Registriert: Di Nov 18, 2008 11:10 Beiträge: 23 Wohnort: Hamburg
Okay ich bin grade am erarbeiten der Tutorilas und ich blick nicht mehr durch...
Ich habe das quick start Tutorial hinbekommen ... und kann jetzt so tolle dreiecke und vierecke auf jeglich farbigen Hintergrund zeichen .. ich als Anfänger bin ja jetzt schon total begeistert....
Aber,: ich bin grade beim 3. also ich will es einfach nur hinbekommen das sich eine Form um die andere dreht ^^
Also ich habe bisher das gemacht:
Registriert: Do Sep 25, 2003 15:56 Beiträge: 7810 Wohnort: Sachsen - ERZ / C
Programmiersprache: Java (, Pascal)
Das mit dem Drehen ist für jemand Neues immer recht schwer.
Jedes Objekt solltest du für sich behandeln. Also wenn du ein Dreieck hast welches in der Bildmitte sich um sich selbst drehen soll, dann programmier das. Wenn du jetzt ein anderes Objekt haben möchtest, was sich um das Dreieck dreht, dann mach folgendes:
Vor dem Dreieck-Dreh-Code machst du glPushMatrix(). Nach dem du das Dreieck gezeichnet hast machst du glPopMatrix. Jetzt schreibst du den zweiten Drehcode, so als wäre das Dreieck nicht da. Schon sollte es gehn.
Ansonsten kann ich dir zur Funktionsweise der Matrizen noch das Tutorial_Matrix2 ans Herz legen. Hat viele Bilder.
_________________ Blog: kevin-fleischer.de und fbaingermany.com
Registriert: Di Nov 18, 2008 11:10 Beiträge: 23 Wohnort: Hamburg
okay ich hab grade noch mal was gelesen... ich muss das mit Timebased Movement machen oder ?
also der Rotate code musss mit einer Variablen zusammenhängen die sich stätig ändert?
okay ich hab echt noch gar keine Ahnung aber es wäre klasse wenn ihr mir trozdem Antworten könnten
Registriert: Do Sep 25, 2003 15:56 Beiträge: 7810 Wohnort: Sachsen - ERZ / C
Programmiersprache: Java (, Pascal)
Timebased Movement ist dazu da, unterschiedliche Hardware auszugleichen. Wenn du einen Rechner hast der lange braucht um ein Bild zu erzeugen, dann musst du pro zeiteinheit um einen größeren Winkel rotieren als wenn du einen Rechner hast der sehr schnell ist.
Für deine Zwecke gehts erstmal ohne. Mach das mal mit dem glPush/PopMatrix.
_________________ Blog: kevin-fleischer.de und fbaingermany.com
Du gibst aber nur einen festen Wert beim zu drehenden Winkel an und keinen Wert der angibt um welche Achse sich dein Objekt drehen soll. Um zu bestimmen um welche Achse sich das Objekt drehen soll gibt man eine 1 an. Eine 0 steht dann für das Gegenteil.Möchtest du ein Objekt drehen muss sich der Wert in ZuDrehenderWinkel jedes mal erhöhen. Du brauchst also eine Variable die seinen eigenen aktuellen Wert + Geschwindigkeit rechnet.
Code:
glTranslatef(0,0,-10);
Rotation = Rotation + 0.01; // hier die fehlende Variable
glRotatef(Ratation,0,1,0); // Variable einsetzen und Rotationsachse angeben
glColor3ub(255,255,0);
glBegin(GL_TRIANGLES);
glVertex3f(-1,-1, 0);
glVertex3f( 1, -1, 0);
glVertex3f( 0,1, 0);
glEnd();
Du darfst natürlich nicht vergessen Rotatation zu initialisieren.
Das mit den Timebased Movement lässt sich einfach(hoffentlich ^^) erklären.
In einen Spiel soll ein Objekt einmal in einer Sekunde um sich selbst rotieren. Wenn du wie oben, einfach bei einer Variablen "Rotation = Rotation + 0.01" schreibst, bewegt sich vielleicht auf deinen PC das Objekt in einer Sekunde einmal um sich selber. Wenn aber jemand anderes einen doppelt so schnelleren PC hat, dreht sich bei ihm das Objekt 2 mal in einer Sekunde. Das Spiel würde also doppelt so schnell laufen, weil er ja auf seinen PC auch doppelt so schnell "Rotation = Rotation + 0.01" aufruft.
Um das zu verhindern benutzt man Timebased Movement.
Man misst eine Startzeit am Anfang der Prozedur und am Ende, nachdem du den Buffer leerst, misst du noch einmal die aktuelle Zeit und ziehst davon die Startzeit ab. Damit hast du dann die Zeit die dein Programm gebraucht hat um einmal die Funktion zu durchlaufen. Diesen Wert multiplizierst du mit deiner Geschwindigkeit. Also: "Rotation = Rotation+(0.01*DrawTime)" . DrawTime ist dann sozusagen die Variable die, die Zeitdifferenz enthällt. Ein langsamer Computer braucht nun mehr Zeit für die Berechnung in deiner Renderfunktion. Damit ist dann auch der Wert in DrawTime größer. Es vergeht ja schließlich mehr Zeit zwischen der ersten und zweiten Messung. Also bewegt sich das Objekt auch in größeren Abständen pro Renderdurchlauf. Bei einen schnelleren Computer vergeht weniger Zeit. Dafür kann dieser ja auch mehr Bilder ausgeben. Wenn die Zeit in DrawTime nun kürzer ist, bewegt sich dieser auch pro Renderdurchlauf in nicht so großen Abständen.
Beispiel: PC A durchläuft 100 mal die Renderschleife pro Sekunde. Er braucht also
pro Renderdurchlauf 0.01 Sekunden. Das ist der Wert für DrawTime.
PC B durchläuft 50 mal die Renderschleife pro Sekunde. Er braucht also
pro Renderdurchlauf 0.02 Sekunden. Das ist der Wert für DrawTime.
Wenn man nun "Rotation = Rotation + (0.5 * DrawTime)" rechnet kommen beide nach einer
Sekunde auf die gleichen Wert da ja PC A die Schleife 100 mal durchläuft in 0.01(DrawTime)
Sekunden und PC B nur 50 mal in 0.02(DrawTime) Sekunden. Ob man nun 100 mal 0.01
rechnet oder 50 mal 0.02 ist vollkommen egal, da beide am Ende den gleichen Wert haben.
So alles doppelt erzählt aber hoffe, dass es einleuchtend ist. ^^
Gibt auch sehr gute Erklärungen hier im Wiki.
Registriert: Di Nov 18, 2008 11:10 Beiträge: 23 Wohnort: Hamburg
Okay jetzt funktioniert es und schon stellen sich mir die nächsten Fragen...
das Problem : immoment habe ich die "Rotation" über Key_Press angegeben... wie bekomme ich das hin, dass diese über eine Schleife läuft.?
Vor allem wie soll diese schleife aussehen, da sie ja nie zu ende gehen soll...???
2. Problem : Nach dem ich ein 3dimensionales Dreieck gezeichnet habe, hat das nächste Objekt was ich zeichne auf einmal die Form des vorherigen Dreieckes irgendwie in ausgeschnittener Form noch in sich ( man sieht den Hintergrund durch den Würfel.)...
Hier der Quelltextauszug:
Code:
glTranslatef(0,0,-10);
// sonrot:= sonrot + (0.1*Drawtime); dafür bräucht ich schleife
glTranslatef(0,0,weite);
glRotatef(sonrot,0,1,0);
glRotatef(sonrot2,1,0,0);
glTranslatef(0,0,weite2);
glDisable(GL_CULL_FACE); //hat das hiermit was zu tun???
glColor3ub(255,255,0);
glBegin(GL_TRIANGLES);
glVertex3f(-1,-1, 1);
glVertex3f( 1, -1, 1);
glVertex3f( 0,1, 0);
glEnd();
glColor3ub(255,0,0);
glBegin(GL_TRIANGLES);
glVertex3f(-1,-1, -1);
glVertex3f( 1, -1, -1);
glVertex3f( 0,1, 0);
glEnd();
glColor3ub(0,0,0);
glBegin(GL_TRIANGLES);
glVertex3f(1,-1, -1);
glVertex3f( 1, -1, 1);
glVertex3f( 0,1, 0);
glEnd();
glColor3ub(0,255,0);
glBegin(GL_TRIANGLES);
glVertex3f(-1,-1, -1);
glVertex3f(-1,-1, 1);
glVertex3f( 0,1, 0);
glEnd();
glColor3ub(0,0,255);
glBegin(GL_QUADS);
glVertex3f(-1,-1, -1);
glVertex3f(-1,-1, 1);
glVertex3f( 1,-1, 1);
glVertex3f( 1,-1, -1);
glEnd();
glRotatef(sonrot,0,1,0);
glTranslatef( -5, 3, 0);
glPushMatrix;
glColor3ub(0,0,255);
drawquads; //hier der Problemwürfel!
glPopMatrix;
SwapBuffers(DC);
und so hab ich das Immoment mit der Variablen gemacht:
Registriert: Mo Jan 31, 2005 11:02 Beiträge: 432 Wohnort: Rheinlandpfalz
Hallo,
deine Schleife ist die Render-Procedure, diese wird ja im OnIdle aufgerufen (gehe ich jetzt mal von aus).
Code:
...
glTranslatef(0,0,-10);
sonrot:= sonrot + (0.1*Drawtime);
If (sonrot > 360) then sonrot := sonrot - 360;
glTranslatef(0,0,weite);
glRotatef(sonrot,0,1,0);
...
Was mir noch aufgefallen ist: 1. Du hast in deinem Code 2x glRotatef(sonrot,0,1,0); stehen, also einmal vor dem Zeichnen des dreidim. Dreiecks (=Pyramide?) und einmal vor dem Würfel, d.h. der Würfel dreht sich 2mal so schnell, wie dein erstes Objekt. Aber vllt ist dies ja gewünscht...
2. Du kannst die ersten 4 Triangles in einen einzigen glBegin(GL_TRIANGLES); - glEnd(); Block zusammenfassen:
Code:
glBegin(GL_TRIANGLES);
glColor3ub(255,255,0);
glVertex3f(-1,-1, 1);
glVertex3f( 1, -1, 1);
glVertex3f( 0,1, 0);
glColor3ub(255,0,0);
glVertex3f(-1,-1, -1);
glVertex3f( 1, -1, -1);
glVertex3f( 0,1, 0);
glColor3ub(0,0,0);
glVertex3f(1,-1, -1);
glVertex3f( 1, -1, 1);
glVertex3f( 0,1, 0);
glColor3ub(0,255,0);
glVertex3f(-1,-1, -1);
glVertex3f(-1,-1, 1);
glVertex3f( 0,1, 0);
glEnd();
Das glDisable(GL_CULL_FACE); sagt aus, dass du für alles nachfolgende Hinter- und Vorderseite zeichnen willst, bzw. dass eine Seite (vermutlich die hintere, festgelegt mit glCullFace(...)) nicht weggecullt wird.
Da du aber, soweit ich sehen kann, nirgendwo glEnable(GL_CULL_FACE); aufrufst, bleibt diese Eigenschaft deaktiviert, für alle Objekte, die du danach zeichnen solltest, dies gilt insbesondere für jeden weiteren Durchlauf von deiner Render-Schleife.
Mitglieder in diesem Forum: 0 Mitglieder und 6 Gäste
Du darfst keine neuen Themen in diesem Forum erstellen. Du darfst keine Antworten zu Themen in diesem Forum erstellen. Du darfst deine Beiträge in diesem Forum nicht ändern. Du darfst deine Beiträge in diesem Forum nicht löschen. Du darfst keine Dateianhänge in diesem Forum erstellen.