opengl obracajacy sie szescian

0

witam napisałem program za pomocą biblioteki opengl, jest to sześcian który powinien być przesunięty o 5 wzdłuż osi x i obracać się wokół osi z. kwadrat nie wiem czemu się nie przesuwa i nie obraca, mógłbym prosić o zerknięcie i o ewentualne uwagi?? wstawiam kod programu

#include <GL/glut.h>

const int w = 800;
const int h = 600;
const float delta_alfa=0.5;
float alfa=0.0;

void uklad(){
   glBegin(GL_LINES);
    glColor3f(0.0, 1.0, 0.0); //zielona os X
      glVertex3f(-5.0, 0.0, 0.0);
      glVertex3f(5.0, 0.0, 0.0);
      glColor3f(0.0, 0.0, 1.0); // niebieska os Y
      glVertex3f(0.0, -5.0, 0.0);
      glVertex3f(0.0, 5.0, 0.0);
      glColor3f(1.0, 1.0, 1.0); // biala os Z
      glVertex3f(0.0, 0.0, -5.0);
      glVertex3f(0.0, 0.0, 5.0);
    glEnd();
}

void sciana(){
    glBegin(GL_QUADS);
      glVertex3f(-0.5, 0.0, -0.5);
      glVertex3f (-0.5, 0.0, 0.5);
      glVertex3f(0.5, 0.0, 0.5);
      glVertex3f(0.5, 0.0, -0.5);
    glEnd();
}

void szescian(){

   //dolna podstawa
   glPushMatrix();
   glLoadIdentity();
     glTranslatef(0.0, -0.5, 0.0);
     glColor3f(0.0, 0.0, 1.0);
     sciana();
   glPopMatrix();

   //gorna podstawa
   glPushMatrix();
   glLoadIdentity();
     glTranslatef(0.0, 0.5, 0.0);
     glColor3f(0.0, 1.0, 0.0);
     sciana();
   glPopMatrix();

   //lewa sciana
   glPushMatrix();
   glLoadIdentity();
     glColor3f(1.0, 0.0, 0.0);
     glTranslatef(-0.5, 0.0, 0.0);
     glRotatef(90.0, 0.0, 1.0, 0.0);
     glRotatef(90.0, 1.0, 0.0, 0.0);
     sciana();
   glPopMatrix();

   //prawa sciana
   glPushMatrix();
   glLoadIdentity();
     glColor3f(0.0, 1.0, 1.0);
     glTranslatef(0.5, 0.0, 0.0);
     glRotatef(90.0, 0.0, 1.0, 0.0);
     glRotatef(90.0, 1.0, 0.0, 0.0);
     sciana();
   glPopMatrix();

   //tylna sciana
   glPushMatrix();
   glLoadIdentity();
     glColor3f(1.0, 1.0, 0.0);
     glTranslatef(0.0, 0.0, -0.5);
     glRotatef(90.0, 1.0, 0.0, 0.0);
     sciana();
   glPopMatrix();

   //przednia sciana
   glPushMatrix();
   glLoadIdentity();
     glColor3f(1.0, 1.0, 1.0);
     glTranslatef(0.0, 0.0, 0.5);
     glRotatef(90.0, 1.0, 0.0, 0.0);
     sciana();
   glPopMatrix();

}

void anim(){
   alfa+=delta_alfa;
    glutPostRedisplay();
}

void init(){
    glClearColor(0.0, 0.0, 0.0, 1.0);
   glEnable(GL_DEPTH_TEST);
   glMatrixMode(GL_PROJECTION);
   gluPerspective(60.0,1.0,1.0,20.0);
   gluLookAt(7.0,7.0,5.0, 0.0,0.0,0.0, 0.0,0.0,1.0);
   glMatrixMode(GL_MODELVIEW);
}

void drawScene(void) {
   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
   glLoadIdentity();
     uklad();
     glRotatef(alfa, 1.0, 0.0, 0.0);
     glTranslatef(5.0, 0.0, 0.0);
     szescian();
    glFlush();
    glutSwapBuffers();
}

int main (int argc , char **argv) {
   glutInit(&argc , argv);
    glutInitDisplayMode (GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
    glutInitWindowSize(w, h);
    glutCreateWindow ("szescian animacja w GLUT");
    glutIdleFunc(anim);
    glutDisplayFunc(drawScene);
    init();
    glutMainLoop();
    return 0;
} 
0

Zakomentuj wszystkie glLoadIdentity() w procedurze szescian a zacznie się kręcić.

0

teraz działa ale możesz mi to wyjaśnić?? czemu mam nie ładować macierzy jednostkowej???

0

No to spójrz na to z perspektywy wierzchołków znajdujących się w pierwszym wywołaniu procedury ściana() w procedurze sześcian(). To co chcesz zrobić z tymi wierzchołkami to przesunąć w y-ku o -0.5, a następnie w x-ie o 5.0, no i na końcu obrócić o alfa stopni. Tak powinna wyglądać twoja macierz modelowania przed wywołaniem pierwszego ściana(). Jednak ty ją po drodze "zerujesz" przez glLoadIdentity() zatem wcześniejsze wywołania glRotatef(alfa, 1.0, 0.0, 0.0); i glTranslatef(5.0, 0.0, 0.0); giną.
Jak zakomentujesz glLoadIdentity() to nie bedzie zerowania po drodze i sześcian zacznie się obracać.

0

ja używałem tej funkcji glLoadIdentity() miedzy glPushMatrix() a glPopMatrix() aby zerować poprzednie przesunięcia i obroty ściany. tak to przynajmniej rozumiałem że przy następnych przesunięciach i obrotach poprzednie trzeba zerować poprzez glLoadIdentity().

0

kiedy wrzucasz macierz na stos to automatycznie obiekty ktore tworzysz i ustawiasz miedzy wywolaniami pushmatrix i popmatrix znajduja sie w punkcie 0,0,0 i z tego punktu sa transformowane. LoadIndentity zeruje ci caly widok i przesuniecia sceny. Nie zeruj nigdy widoku w trakcie rysowania figury bo cala transformacja z glownej funkcji rysowania nie bedzie dzialac. Przesuniecia robisz sobie w funkcji paint a obiekty rysuje sie w punkcie 0,0,0

Ja np. mam takie cus i dziala poprawnie.

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glLoadIdentity();
    glTranslatef(0.0, 0.0,zoom);
    gluLookAt(7,5,7,0,0,0,0,1,0);
    glRotatef(y,0,1,0);

    for(int i=0;i<triangles.size();i++)
    {
        paintPyramid(triangles[i]);
    }
    renderText(5, 20, "Piramida sierpinskiego", *qfont);
0

rozumiem, dziekuje za pomoc ;)

0

Przyjmij po prostu, że macierz zerujesz przed każdą nowo tworzoną sesją, np. Ładujesz macierz jednostkową, dokonujesz rysowania mapy, nierówności, drzewa, krzaki, stawy itd. Potem chcesz wrócić do początku ( czyli do punktu 0, 0, 0 o skali 1, 1, 1 i obrocie 0 rad. ). Rysujesz postać, szaty, broń itd. Ładujesz kolejny raz macierz jednostkową obracasz się, przesuwasz do innego miejsca ( nie odwrotnie, bo to jest różnica, w DirectX jest inaczej ), rysujesz inną postać, szaty, broń, itd. Kolejny raz ładujesz macierz jednostkową, znowu obracasz się, przesuwasz do innego miejsca i rysujesz potwora. Na początku trudno to ogarnąć, ale po kilku przykładach załapiesz
Zaczynając rysowanie w funkcji Render zaczynasz znowu od czystej kartki glClear, więc dobrze byłoby także wyczyścić macierz.

0

rozumiem, dziękuje za informacje

1 użytkowników online, w tym zalogowanych: 0, gości: 1