• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Krzywe NURBS i OpenGL

Object Storage Arubacloud
0 głosów
63 wizyt
pytanie zadane 8 grudnia 2020 w C i C++ przez Bartosz Pawlak Początkujący (370 p.)

Z pomocą NURBS umiem stworzyć górkę. 

Tablica points[4*4*3]

0.0,0.0,5.0, 0.0,0.0,4.5, 0.0,0.0,0.5, 0.0,0.0,0.0,
0.5,0.0,5.0, 3.0,2.0,2.0, 3.0,2.0,3.0, 0.5,0.0,0.0,
4.5,0.0,5.0, 2.0,2.0,2.0, 2.0,2.0,3.0, 4.5,0.0,0.0,
5.0,0.0,5.0, 5.0,0.0,4.5, 5.0,0.0,0.5, 5.0,0.0,0.0
gluNurbsSurface(nurbs, 8, knots, 8, knots, 4 * 3, 3, points, 4, 4, GL_MAP2_VERTEX_3);

Rysunek:

Problem pojawia się wtedy kiedy chce zmienić ilość punktów, aby mieć większą kontrolę nad powierzchnią.

    0.0,0.0,5.0, 0.0,0.0,4.5, 0.0,0.0,4.0, 0.0,0.0,1.0, 0.0,0.0,0.5, 0.0,0.0,0.0,
    0.5,0.0,5.0, 3.0,2.0,4.0, 3.0,2.0,5.0, 3.0,2.0,1.0, 3.0,2.0,2.0, 0.5,0.0,0.0,
    4.5,0.0,5.0, 2.0,2.0,4.0, 2.0,2.0,5.0, 2.0,2.0,1.0, 2.0,2.0,2.0, 4.5,0.0,0.0,
    5.0,0.0,5.0, 5.0,0.0,4.5, 5.0,0.0,4.0, 5.0,0.0,1.0, 5.0,0.0,0.5, 5.0,0.0,0.0
gluNurbsSurface(nurbs, 8, knots, 8, knots, 4 * 3, 3, points, 4, 4, GL_MAP2_VERTEX_3);

Jak zmienię zestaw punktów to wychodzi coś takiego:

Jak dostosuje do nowej ilość punktów argumenty funkcji gluNurbsSurface

gluNurbsSurface(nurbs, 8, knots, 8, knots, 4*6, 3, points, 4, 6, GL_MAP2_VERTEX_3);

to otrzymuje:

Moim celem są dwa szczyty.

Jakakolwiek zmiana w parametrach funkcji gluNurbsSurface powoduje zniknięcie płaszczyzny. Gdzie i jaki popełniam błąd? Mój kod umieszczam poniżej. Używam OpenGL i freeGLUT.

Pozdrawiam

//Colors
GLfloat WHITE[] = { 1,1,1 };
GLfloat RED[] = { 1,0,0 };
GLfloat GREEN[] = { 0,1,0 };
GLfloat MAGENTA[] = { 1,0,1 };
GLfloat BLACK[] = { 0,0,0 };
GLfloat BLUE[] = { 0,0,1 };

//-----------------

// rozmiary bryły obcinania

const GLdouble left1 = -2.0;
const GLdouble right1 = 2.0;
const GLdouble bottom = -2.0;
const GLdouble top = 2.0;
const GLdouble near1 = 3.0;
const GLdouble far1 = 7.0;

// kąty obrotu obiektu

GLfloat rotatex = 0.0;
GLfloat rotatey = 0.0;

// wskaźnik naciśnięcia lewego przycisku myszki

int button_state = GLUT_UP;

// położenie kursora myszki

int button_x, button_y;

// współczynnik skalowania

GLfloat scale = 1.0;

// współrzędne punktów kontrolnych powierzchni
//4 * 4 * 3

GLfloat points[4 * 6 * 3] =
{ 
/*
0.0,0.0,5.0, 0.0,0.0,4.5, 0.0,0.0,0.5, 0.0,0.0,0.0,
0.5,0.0,5.0, 3.0,2.0,2.0, 3.0,2.0,3.0, 0.5,0.0,0.0,
4.5,0.0,5.0, 2.0,2.0,2.0, 2.0,2.0,3.0, 4.5,0.0,0.0,
5.0,0.0,5.0, 5.0,0.0,4.5, 5.0,0.0,0.5, 5.0,0.0,0.0

*/
    0.0,0.0,5.0, 0.0,0.0,4.5, 0.0,0.0,4.0, 0.0,0.0,1.0, 0.0,0.0,0.5, 0.0,0.0,0.0,
    0.5,0.0,5.0, 3.0,2.0,4.0, 3.0,2.0,5.0, 3.0,2.0,1.0, 3.0,2.0,2.0, 0.5,0.0,0.0,
    4.5,0.0,5.0, 2.0,2.0,4.0, 2.0,2.0,5.0, 2.0,2.0,1.0, 2.0,2.0,2.0, 4.5,0.0,0.0,
    5.0,0.0,5.0, 5.0,0.0,4.5, 5.0,0.0,4.0, 5.0,0.0,1.0, 5.0,0.0,0.5, 5.0,0.0,0.0
};

// węzły

GLfloat knots[4 * 2] =
{
    0.0, 0.0,
    0.0, 0.0,
    1.0, 1.0,
    1.0, 1.0
};

//A chekerboard
class Checkerboard {
    int displayListId;

public:
    int width;
    int depth;
    Checkerboard(int width, int depth) : width(width), depth(depth) {}
    double centerx() { return width / 2; }
    double centery() { return depth / 2; }
    int returnx() { return width; }
    int returny() { return depth; }
    void create() {
        displayListId = glGenLists(1);
        glNewList(displayListId, GL_COMPILE);
        glBegin(GL_QUADS);
        glNormal3d(0, 1, 0);
        for (int x = 0; x < width - 1; x++) {
            for (int z = 0; z < depth - 1; z++) {
                glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE,
                    (x + z) % 2 == 0 ? RED : WHITE);
                glVertex3d(x, 0, z);
                glVertex3d(x + 1, 0, z);
                glVertex3d(x + 1, 0, z + 1);
                glVertex3d(x, 0, z + 1);
            }
        }
        glEnd();
        glEndList();
    }
    void draw() {
        glCallList(displayListId);
    }
    void rotate()
    {
        glRotatef(rotatex, 1.0, 0, 0);
        glRotatef(rotatey, 0, 1.0, 0);
    }
};

Vector3d v(0, 0, 0), f(0, 0, 0);
int checkerboardSize = 6;
Checkerboard checkerboard(checkerboardSize, checkerboardSize);

void Update(void)
{
    glutPostRedisplay();
}

void init(void)
{
    glEnable(GL_DEPTH_TEST);
    glLightfv(GL_LIGHT0, GL_DIFFUSE, WHITE);
    glLightfv(GL_LIGHT0, GL_SPECULAR, WHITE);
    glMaterialfv(GL_FRONT, GL_SPECULAR, WHITE);
    glMaterialf(GL_FRONT, GL_SHININESS, 30);
    glEnable(GL_LIGHTING);
    glEnable(GL_LIGHT0);
    checkerboard.create();
}

void update() {
    Update();
}

void display(void)
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    // wybór macierzy modelowania
    glMatrixMode(GL_MODELVIEW);

    glLoadIdentity();

    // włączenie testu bufora głębokości
    glEnable(GL_DEPTH_TEST);

    gluLookAt(12.0, 3.0, 0.0, checkerboard.centerx(), 0.0, checkerboard.centery(), 0.0, 1.0, 0.0);
    checkerboard.rotate(); checkerboard.draw();

    // obroty obiektu
    glRotatef(rotatex, 1.0, 0, 0);
    glRotatef(rotatey, 0, 1.0, 0);



    // kolor krawędzi
    glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, BLUE);

    // utworzenie obiektu NURBS
    GLUnurbsObj* nurbs = gluNewNurbsRenderer();

    // początek definicji powierzchni NURBS
    gluBeginSurface(nurbs);

    // sposób renderowania powierzchni NURBS
    gluNurbsProperty(nurbs, GLU_DISPLAY_MODE, GLU_FILL);

    // metoda podziału powierzchni NURBS na wielokąty
    gluNurbsProperty(nurbs, GLU_SAMPLING_METHOD, GLU_PATH_LENGTH);
    //gluNurbsProperty(nurbs, GLU_SAMPLING_TOLERANCE, 25.0);
    //gluNurbsProperty(nurbs, GLU_DISPLAY_MODE, GLU_FILL);

    // narysowanie powierzchni
    gluNurbsSurface(nurbs, 8, knots, 8, knots, 4*6, 3, points, 4, 6, GL_MAP2_VERTEX_3);
    //gluNurbsSurface(nurbs, 8, knots, 8, knots, 4 * 3, 3, points, 4, 4, GL_MAP2_VERTEX_3);


    // koniec definicji powierzchni
    gluEndSurface(nurbs);

    // usunięcie obiektu NURBS
    gluDeleteNurbsRenderer(nurbs);

    // kolor punktów
    //glColor3fv(WHITE);
    glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, WHITE);

    // rozxmiar punktów
    glPointSize(6.0);
    //int arrSize = sizeof(points) / sizeof(points[0]);
    // narysowanie punktów kontrolnych
    //cout << arrSize << endl;
    glBegin(GL_POINTS);
    for (int i = 0; i < 24; i++)
        glVertex3fv(points + i * 3);

    glEnd();

    update();
    glFlush();
    glutSwapBuffers();
}

void reshape(int w, int h)
{
    glViewport(0, 0, w, h);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(50.0, w / (GLfloat)h, 1.0, 150.0);
    glMatrixMode(GL_MODELVIEW);
}

void timer(int v)
{
    glutPostRedisplay();
    glutTimerFunc(1000 / 60, timer, v);
}

//--------------------------------------------------



// obsługa przycisków myszki

void MouseButton(int button, int state, int x, int y)
{
    if (button == GLUT_LEFT_BUTTON)
    {
        // zapamiętanie stanu lewego przycisku myszki
        button_state = state;

        // zapamiętanie położenia kursora myszki
        if (state == GLUT_DOWN)
        {
            button_x = x;
            button_y = y;
        }
    }
}

// obsługa ruchu kursora myszki

void MouseMotion(int x, int y)
{
    if (button_state == GLUT_DOWN)
    {
        rotatey += 30 * (right1 - left1) / glutGet(GLUT_WINDOW_WIDTH) * (x - button_x);
        button_x = x;
        rotatex -= 30 * (top - bottom) / glutGet(GLUT_WINDOW_HEIGHT) * (button_y - y);
        button_y = y;
        glutPostRedisplay();
    }
}

int main(int argc, char* argv[])
{
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
    glutInitWindowSize(800, 600);
    glutInitWindowPosition(10, 10);
    glutCreateWindow("SPH Implementation");
    glutDisplayFunc(display);
    glutReshapeFunc(reshape);

    // dołączenie funkcji obsługi klawiatury
    //glutKeyboardFunc(Keyboard);

    // obsługa przycisków myszki
    glutMouseFunc(MouseButton);

    // obsługa ruchu kursora myszki
    glutMotionFunc(MouseMotion);

    glutIdleFunc(Update);
    glutTimerFunc(1, timer, 0);

    init();
    glutMainLoop();
    return 0;
}

 

Zaloguj lub zarejestruj się, aby odpowiedzieć na to pytanie.

Podobne pytania

0 głosów
1 odpowiedź 478 wizyt
0 głosów
0 odpowiedzi 240 wizyt
0 głosów
1 odpowiedź 321 wizyt
pytanie zadane 6 lipca 2020 w OpenGL, Unity przez tonn204 Mądrala (7,440 p.)

92,576 zapytań

141,426 odpowiedzi

319,652 komentarzy

61,961 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...