PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Würfel rotieren lassen in OpenGL


Lord Nikon
2003-06-22, 13:05:09
Hi ,
hier erstmal die Koordinaten für meinen Würfel:

glBegin(GL_LINES);
glVertex3d(0.0,0.0,0.0);
glVertex3d(1.0,0.0,0.0);


glVertex3d(0.0,0.0,0.0);
glVertex3d(0.0,1.0,0.0);

glVertex3d(1.0,0.0,0.0);
glVertex3d(1.0,1.0,0.0);

glVertex3d(1.0,1.0,0.0);
glVertex3d(0.0,1.0,0.0);


// Ecken in die höhen ziehen
glVertex3d(1.0,0.0,0.0);
glVertex3d(1.0,0.0,1.0);

glVertex3d(0.0,1.0,0.0);
glVertex3d(0.0,1.0,1.0);

glVertex3d(1.0,1.0,0.0);
glVertex3d(1.0,1.0,1.0);


glVertex3d(0.0,0.0,0.0);
glVertex3d(0.0,0.0,1.0);
// Verbindungen zwischen den einzelen Höhen herstellen

glVertex3d(1.0,0.0,1.0);
glVertex3d(1.0,1.0,1.0);

glVertex3d(0.0,0.0,1.0);
glVertex3d(0.0,1.0,1.0);

glVertex3d(1.0,1.0,1.0);
glVertex3d(0.0,1.0,1.0);

glVertex3d(0.0,0.0,1.0);
glVertex3d(1.0,0.0,1.0);
glEnd();

Wie kann ich den Würfel jetzt nach rechts rotieren lassen?

Demirug
2003-06-22, 13:16:08
http://nehe.gamedev.net/data/lessons/lesson.asp?lesson=04

Lord Nikon
2003-06-22, 13:53:25
Ich hab einen Timer eingefügt der jede Sekunde aufgerufen wird. In dieser hab ich die 2 Befehle eingefügt:

glTranslatef(-1.5f,0.0f,-6.0f);
glRotatef(winkel,0.0f,1.0f,0.0f);

, wobei ich am Anfang der Timer Methode den Winkel immer um 20 Grad erhöhe.Dannach ruf ich die Methode auf , die den Würfel zeichnet.Wieso bleibt der Würfel trotzdem an der gleichen Position und rotiert nicht?

Demirug
2003-06-22, 14:01:50
Original geschrieben von Lord Nikon
Ich hab eine Timer eingefügt die sich jede Sekunde aufgerufen wird. In dieser hab ich die 2 Befehle eingefügt:

glTranslatef(-1.5f,0.0f,-6.0f);
glRotatef(winkel,0.0f,1.0f,0.0f);

, wobei ich am Anfang der Timer Methode den Winkel immer um 20 Grad erhöhe.Dannach ruf ich die Methode auf , die den Würfel zeichnet.Wieso bleibt der Würfel trotzdem an der gleichen Position und rotiert nicht?

Und wo benutzt du die Variable mit dem Winkel?

Lord Nikon
2003-06-22, 14:11:32
Original geschrieben von Demirug
Und wo benutzt du die Variable mit dem Winkel?
Die Variable winkel ist global. Ich nutze die Variable beim Aufruf

glRotatef(winkel,0.0f,1.0f,0.0f);

Bevor dieser Aufruf geschieht , wird die Variable winkel um 20 erhöht.Diese beiden Sachen geschehen in der Timer Methode.

Abe Ghiran
2003-06-22, 14:45:22
Du sagst, das du glRotate aufrufst und dann eine Methode, die den Würfel zeichnet..
Kann es sein, das du beim zeichnen des Würfels noch irgendwie den Matrixstack manipulierst (Kamera einrichten, o.ä.), so das der Effekt, den glRotate auf die Matrix hatte wieder überschrieben wird?

Ansonsten kann es auch nicht schaden, regelmäßig (z.b. pro Frame) abzufragen, ob es irgendwelche Fehler gegeben hat, z.b. so:


GLenum error = glGetError();

if(error != GL_NO_ERROR){
Log::log("An error occured rendering this frame.");
Log::log((char*)gluErrorString(error));
}


Grüße, Jan

Lord Nikon
2003-06-22, 15:04:58
@Abe
Hab den Fehler gerade gefunden. In der Methode hab ich am Anfang

glRotated(-65.0,1.0,0.0,0.0); //SZENEN UM X DREHEN
glRotated(-75.0,0.0,0.0,1.0); //SZENEN UM Y DREHEN
glTranslated(-2.5,0.0,-1.4); // SZENE in X,Y Verschieben

eingefügt, und deshalb hats warscheinlich es nicht geklappt.Ich bin noch ziemlicher Anfänger in OpenGL und daher ist mir nicht aufgefallen.Ich teste das ganze jetzt mal, ob es jetzt geht.
EDIT geht immer noch nicht:

glRotated(winkel,1.0,0.0,0.0);
glRotated(winkel,0.0,0.0,1.0);
glTranslated(-2.5,0.0,-1.4); // SZENE in X,Y Verschieben
glMatrixMode(GL_MODELVIEW); // aktuelle Matrix setzen
glLoadIdentity();
glBegin(GL_LINES);
glVertex3d(0.0,0.0,0.0);
glVertex3d(1.0,0.0,0.0);


glVertex3d(0.0,0.0,0.0);
glVertex3d(0.0,1.0,0.0);

glVertex3d(1.0,0.0,0.0);
glVertex3d(1.0,1.0,0.0);

glVertex3d(1.0,1.0,0.0);
glVertex3d(0.0,1.0,0.0);


// Ecken in die höhen ziehen
glVertex3d(1.0,0.0,0.0);
glVertex3d(1.0,0.0,1.0);

glVertex3d(0.0,1.0,0.0);
glVertex3d(0.0,1.0,1.0);

glVertex3d(1.0,1.0,0.0);
glVertex3d(1.0,1.0,1.0);


glVertex3d(0.0,0.0,0.0);
glVertex3d(0.0,0.0,1.0);

// Verbindungen zwischen den einzelen Höhen
glVertex3d(1.0,0.0,1.0);
glVertex3d(1.0,1.0,1.0);

glVertex3d(0.0,0.0,1.0); //
glVertex3d(0.0,1.0,1.0);

glVertex3d(1.0,1.0,1.0);
glVertex3d(0.0,1.0,1.0);

glVertex3d(0.0,0.0,1.0);
glVertex3d(1.0,0.0,1.0);


glEnd();

Ich erhöhe jetzt noch noch die winkel zahl in der Timer Methode.

Abe Ghiran
2003-06-22, 15:56:22
Original geschrieben von Lord Nikon

glRotated(winkel,1.0,0.0,0.0);
glRotated(winkel,0.0,0.0,1.0);
glTranslated(-2.5,0.0,-1.4); // SZENE in X,Y Verschieben
glMatrixMode(GL_MODELVIEW); // aktuelle Matrix setzen
glLoadIdentity();



Das sitzt das Problem: mit glLoadIdentity lädst du die Einheitsmatrix (diagonale 1, rest 0), dadurch werden alle Effekte von glRotate / glTranslate gelöscht, da ja die manipulierte Matrix überschrieben wird.

Noch etwas anderes: das glMatrixMode(GL_MODELVIEW) muß vor den Operationen stehen, die die Matrix manipulieren (wie glRotate, etc), damit du dir sicher sein kannst, das diese auch wirklich die Modelview Matrix ändern und keine der anderen.

Grüße, Jan

Abe Ghiran
2003-06-22, 16:32:09
Kleiner crashkurs was die Matrixstacks in OpenGl angeht (@demi, zecki, xmas & co: wenn ich was falsches erzähle bitte korrigieren, bin ja auch noch OpenGL Anfänger):

Es gibt 3 Matrizen / + Stacks, die für die Projektion verantwortlich sind:

1. Viewport Matrix, mit der hast du normalerweise nicht viel direkt zu tun, sie mappt ganz zum Schluß das Bild auf den viewport. Sie muß eigentlich nur geändert werden, wenn sich die Größe deines viewports ändert z.B. so:


/* Methode um die viewport groesse zu ändern. */
void Renderer::setSize(int width, int height){
this->width = width;
this->height = height;

if(this->height == 0)
this->height = 1; // no divide by zero please :-)

glViewport(0, 0, this->width, this->height);
}


2. Die projection Matrix, die festlegt wie die 3 dimensionale Szene auf den 2 dimensionalen viewport projeziert wird, nämlich entweder orthogonal oder perspektivisch um die Wahrnehmung des menschlichen Auges nachzuahmen.
Für die projection matrix gibt es einen Stack (GL_PROJECTION).

3. Die modelview Matrix, die sowohl die Kamera umfasst (deswegen ...VIEW) sowie die Verschiebung einzelner models / 3d objekte in der Szene (MODEL...).

Wichtig sind also in dem Moment wo du einen Frame renderst 2. und 3. Ich mache das bei mir so:
Immer am Anfang eines Frames setze ich die 3. Projektion, in dem ich die folgende Hilfsmethode aufrufe:

void Renderer::set3DProjection(){
// projektion einstellen
glMatrixMode(GL_PROJECTION);

// aktuelle matrix loeschen
glLoadIdentity();

// perspektivische projektion
gluPerspective(70.0f, (GLfloat)width / (GLfloat)height, 0.1f, 100.0f);


// kamera einrichten -> modelview matrix auswählen
glMatrixMode(GL_MODELVIEW);

// aktuelle matrix löschen
glLoadIdentity();

// kamera positionieren
gluLookAt(ep_posx, ep_posy, ep_posz, // eye point
vp_posx, vp_posy, vp_posz, // view point
0, 1.0f, 0); // up vector

// error checking
checkGLError("An error occured setting the 3d projection:");
}


Ich hoffe, das sich das bißchen code zusammen mit dem Text oben soweit erst mal selbst erklärt.

Wenn ich dann so Kamera und Projektion gesetzt habe, render ich meine 3d Objekte und zwar so (pseudocode):

for(alle 3d objekte){
// sicherstellen, das ich wirklich die modelview matrix manipuliere
glMatrixMode(GL_MODELVIEW);

// bisher aktuelle matrix sichern, in dem eine Kopie davon auf den Stack gelegt wird
glPushMatrix();

// diese kopie manipulieren, um das aktuelle objekt in der szene zu positionieren
glRotate()...
glTranslate()....

// das objekt rendern...

// alte matrix wiederherstellen, in dem die aktuelle vom stack geworfen wird
glPopMatrix();
}


Man kann den Matrixstack auch schön dazu benutzen, um Objekthierarchien abzubilden, dazu gibt es auf beim gamedev.net ein gutes Tutorial (http://www.gamedev.net/reference/articles/article1267.asp).

Das steht zwar alles auch lang und breit im red book, bzw. in den diversen Tutorials auf gamedev.net aber ich hoffe, das dir das wenigstens eine kleine Hilfe ist, was ich hier von mir gegeben habe :).

Grüße, Jan

Lord Nikon
2003-06-22, 16:39:25
thx ich gucks mir gleich an. Ich weiss jetzt , warum der nicht rotiert. Die Variable winkel wirkt , r nur lokal und deshalb hat sie immer den gleichen Wert , nämlich den Ausgangswert den ich gegeben habe.

Xmas
2003-06-22, 17:18:41
Abe Ghiran,
es gibt noch einen vierten Stack, GL_TEXTURE. Damit lassen sich die Texturkoordinaten entsprechend verändern.

Genauer gesagt, dritter Stack, vierte Matrix, weil die Viewport-Transformation ja keinen Stack braucht.

Abe Ghiran
2003-06-22, 17:29:50
Yup, das weiß ich wohl ;).
Hatte den jetzt nur mal außen vor gelassen, weil es Lord Nikon ja erst mal um sein Problem mit der Projektion ging.

Grüße, Jan

Lord Nikon
2003-06-22, 20:01:21
Ein big thx an alle die mir geholfen haben. Der Würfel rotiert jetzt.

Lord Nikon
2003-06-23, 17:05:37
Wie kann ich jetzt rausfinden wieviel FPS ich hab ?

Xmas
2003-06-23, 17:42:57
Original geschrieben von Lord Nikon
Wie kann ich jetzt rausfinden wieviel FPS ich hab ?
Indem du immer an derselben Stelle in deiner Renderfunktion die Zeit misst und die Differenz zur Zeit des vorherigen Frames bildest. Natürlich muss die Timerfunktion entsprechend hochauflösend sein, z.B. QueryPerformanceCounter()

Lord Nikon
2003-06-23, 20:41:17
Ist folgender Code für die FPS Anzeige richtig ?

if (zahler==0)
{
QueryPerformanceCounter(&zeit2);
}
if (zahler==1)
{
QueryPerformanceCounter(&zeit1);
elapsedTime = 0.0f;
elapsedTime = static_cast<float>(zeit1.QuadPart -zeit2.QuadPart);
elapsedTime =elapsedTime/1000.0;
zahler=-1;
}

zahler beim jedem durchrendern um eins erhört , damit ich weiss wann der die Methode einmal komplet Ausgeführt hat. Am Anfang wird im Konstruktor zahler der Wert -1 inizialisiert.