[gelöst] glGetError gibt keinen Fehler und sehen tu ich auch nichts...
-
Hallo,
ich arbeite gerade wieder an meiner eigenen kleinen 3D-Engine.
Ich verwende derzeit wxWidgets 2.8.11 und OpenGL 2.1Da ich mich ja der Versionen unabhängig machen will, habe ich in meinem Visual Studio-Projekt in 4 Bereiche gegliedert.
1. Bereich: OpenGL-Api
2. Bereich: wxWidgets-GUI
3. Bereich: Meine Engine mit alles was dazu gehärt
4. Hauptprogramm.Ich linke dann die OpenGL-Lib, die wxWidgets-Lib und die Engine-Lib im Hauptprogramm zusammen und nat+ürlich noch die opengl32.lib glu32.lib und alles was wxWidgets als abhängigkeiten vorgibt.
Meine OpenGL-Klasse hat zwei Funktionne (also hat mehr, aber heir sind nur 2 wichtig):
/* Formen */ // Dreieck void Stefan3dApiOpenGL::DrawTriangle() { glTranslatef(0,0,-6); glBegin(GL_TRIANGLES); glColor3f(1, 0, 0); glVertex3f(-1,-1, 0); glColor3f(0, 0, 1); glVertex3f( 1,-1, 0); glEnd(); glColor3f(0, 1, 0); glVertex3f( 0, 1, 0); } /* Fehler */ // Fehlernummer abfragen Stefan3dErrorNumber Stefan3dApiOpenGL::ErrorNumberGet() const { GLenum MyError = glGetError(); if (MyError!=GL_NO_ERROR) { if (MyError==Stefan3dErrorNoError) { return MyError+1000; } return MyError; } return Stefan3dErrorNoError; }
Wie man hier erkennen kann erzeuge ich absichtlich einen Fehler. Das mache ich, weil ich in meinem Hauptprogramm leider keine Ausgabe bekomme. Ich hab den Hintergrund auf rot gestellt (damit ich auch schwarze Zeichnungen sehe) und lasse dann das Dreieck zeichenen, aber ich sehe nicht. Also habe ich einen Error-Abfrage geschrieben (nicht schön, aber zu optimierung komme ich wenn alles klappt).
Leider bekomme ich als Rückgabe der glGetError() immer ein GL_NO_ERROR zurück, obwohl ich ja in der DrawTriangle() einen Fehler eingebaut habe. Also müsste ich eigentlich einen Fehlercode != GL_NO_ERROR haben.
Im Debugger bin ich bereits alles durchgegangen. Die Funktionen werden aufgerufen in der richtigen Reihenfolge. Also erst zeichnen, dann Fehlerabfrage.
In der ApiOpenGl.lib habe ich natürlich keine wxWidgets-Libs eingebunden, da die Libs ja erst ins Hauptprogramm gehören. Kann es sein, dass die OpenGL-Befehle nicht genau wissen, wo sie hinzeichen sollen und deswegen einfach die Ausführung ignorieren? Aber dann müsste doch ein Fehlercode kommen ähnlich wie "Kein Ausgabefenster zum zeichnen da..."
/* wxWidgets-Events */ // Paint void wxStefan3d::OnPaint(wxPaintEvent& WXUNUSED(event)) { if ((EngineUse!=0) && (IsShownOnScreen())) { // Das aktuelle OpenGL-Fenster auswählen SetCurrent(); // DC öffnen wxPaintDC dc(this); // Init? if (InitMustGet()) { EngineUse->ApiInit(WidthGet(), HeightGet(), PerspectiveNearGet(), PerspectiveFarGet(), PerspectiveFovYGet()); InitMust=false; } // Zeichnen EngineUse->Draw(); // Auf den Bildschirm SwapBuffers(); } }
Ich hab also brav mein SetCurrent() und mein wxPaintDC dc(this); gesetzt. Außerdem iritiert es mich, dass wenn ich die Hintergrundfarbe ändere mit glClearColor() und glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT), dann funktioniert das schon. Die Hintergrundfarbe ändert sich.
Ich hab dann versucht noch mit
glMatrixMode(GL_MODELVIEW); glLoadIdentity();
und
glFlush();
die Ausgabe mehr "zu erzwingen", aber erfolglos.
Jetzt weiß ich nicht mehr weiter. Ich bekomme keine Ausgabe, wenn ich es richtig mache (von den OpenGL befehlen) und wenn ich absichtlich einen Fehler einbaue, dann bekomme ich nicht mal einen Fehlerreport. Der Debugger geht über alle Befehle drüber und ich sehe, dass alle Werte (in meiner Engine) richtig verarbeitet werden, aber außer die Hintergrundfarbe bekomme ich nichts gezeichnet.
HILFE!!!! Leit mir euere Gedanken. Danke!
Grüße,
Stefan
-
Würd mich wundern wenn glEnd() einen Fehler erzeugt nur weil einfach zu wenig Vertices angegeben wurden und glVertex() außerhalb von glBegin()/glEnd() führt nur zu undefinierem Verhalten aber eben nicht notwendigerweise zu einem Fehler. Mach das glTranslatef() mal weg, damit verschiebst du dein Dreieck hinter die Near-Plane
-
Hallo,
in meinem schlauen Buch über OpenGL steht, dass ein glVertex() außerhalb von glBegin()/glEnd() zu einem Fehler führt, der mit glGetError() abgefangen werden kann. Tja, mein Buch ist wohl doch nichtso schlau.Ich hab nun meine Funktion mal folgt geschrieben:
/* Formen */ // Dreieck void Stefan3dApiOpenGL::DrawTriangle() { glBegin(GL_TRIANGLES); glColor3f(1, 0, 0); glVertex3f(-1,-1, -1); glColor3f(0, 0, 1); glVertex3f( 1,-1, -1); glColor3f(0, 1, 0); glVertex3f( 0, 1, -1); glEnd(); glBegin(GL_TRIANGLES); glColor3f(0, 1, 0); glVertex3f( 0, 1, -1); glColor3f(0, 0, 1); glVertex3f( 1,-1, -1); glColor3f(1, 0, 0); glVertex3f(-1,-1, -1); glEnd(); glBegin(GL_TRIANGLES); glColor3f(1, 0, 0); glVertex3f(-1,-1, 1); glColor3f(0, 0, 1); glVertex3f( 1,-1, 1); glColor3f(0, 1, 0); glVertex3f( 0, 1, 1); glEnd(); glBegin(GL_TRIANGLES); glColor3f(0, 1, 0); glVertex3f( 0, 1, 1); glColor3f(0, 0, 1); glVertex3f( 1,-1, 1); glColor3f(1, 0, 0); glVertex3f(-1,-1, 1); glEnd(); }
Leider sehe ich immer noch nichts. Auch den Near unf Far-Wert habe ich gesetzt mit 0 bis 1000.
gluPerspective(45, aspect, 0, 1000);
Ich hab auch einmal absichtlich einen Stack-Overflow erzeugt (mit Hilfe von glPushMatrix) und somit festgestellt, dass ich schon Fehler mit glGetError() zurück bekomme (was dann Fehler 1283). Also spricht OpenGL schon mit meinem wxGLCanvas. Dann muss es doch was mit meiner Ausgabe-Funktion DrawTriangle() zu tun haben.
-
stefanjann schrieb:
Tja, mein Buch ist wohl doch nichtso schlau.
OpenGL Doku schrieb:
Invoking glVertex outside of a glBegin/glEnd pair results in undefined behavior.
Ein Wert für die near-plane von 0 ist eine sehr schlechte Idee. Lass die Projection einfach mal auf Identity und pack dein Dreieck an z = 0...
Und ein glBegin()/glEnd() reicht, es heißt nicht umsonst GL_TRIANGLES
-
DGL Wiki gluPerspective schrieb:
Die Genauigkeit des Tiefenpuffer wird von den in zNear und zFar angegebenen Werten beeinflusst. Je größer das Verhältnis von zFar zu zNear, je ineffektiver kann der Tiefenpuffer zwischen nah beieinander liegenden Oberflächen unterscheiden. Wenn r = zFar / zNear, dann gehen ungefähr log(2)r Bits an Tiefenpuffergenauigkeit verloren. Da r gegen Unendlich strebt wenn zNear gegen 0 strebt, darf zNear niemals gleich 0 gesetzt werden.
Ah jetzt ja. Ich mag mein schlaues Buch nicht mehr, denn sort wird near eigentlich immer = 0 gesetzt! Ich hab jetzt mal den Bereich von gluPerspective() auskommentiert - und siehe da, ein Dreieck steht auf meinem Bildschirm.
Man man man, ich muss noch soooo viel lernen mit OpenGL. Aber der Weg ist das Ziel und das Ergebnis zeigt ja doch schon ein paar Fortschritte.
Ich schaff das schon noch mit meiner kleinen einfachen Engine.
Vielen Dank,
Stefan
-
glBegin, glVertex und glEnd sind auch hoffnungslos veraltet. Man sollte mindestens Vertex Arrays verwenden, sprich OpenGL 2.x.
-
Das stimmt natürlich für mehr als schnell ein paar Dreiecke malen ist glBegin()/glEnd() nicht wirklich brauchbar. Aber Vertex Arrays gibts auch schon seit OpenGL 1.1. In OpenGL 2.0 würde man VBOs und Shader verwenden. Für den Fall dass dein Buch das nicht behandelt sei auf dieses Tutorial verwiesen: http://duriansoftware.com/joe/An-intro-to-modern-OpenGL.-Table-of-Contents.html
-
Dsa von Dot is a bissl kurz:
http://www.arcsynthesis.org/gltut/
-
Hallo,
na das man mit glBegin()/glEnd() nicht mehr "UpToDate" ist hab ich auch schon festgestellt, aber ich dachte wenn mein Buch (Auflage 2010!?!) das noch verwendet, dann kann es gar nicht soooooo schlimm sein.Aber wieder einmal lehrt mich die Praxis eines besseren. Ich hab auch schon nach passenden Anleitungen für Open GL 4.1 etc gesucht, aber nicht wirklich gutes leicht verständliches gefunden. Daher danke ich euch für die zwei Tuts. Die versteh ich sehr gut (und das obwohl mein Fachenglisch für diesen Programmierbereich noch nicht so gut ist).
Ich seh mein Buch mal als praktische Grundlage und ersten Einstieg. Aber das Buch schimpft sich als "Praxisbuch" und so wie ich das sehe, war es das auch schon 2010 nicht mehr!
Grüße,
Stefan
-
Wenn das ein Fachbuch ist in der Auflage von 2010 und immer noch glBegin/glEnd lehrt, dann würde ich mein Geld zurückverlangen.
Das Problem ist halt, dass mit OpenGL 3 das ganze fixed Function Zeug rausfällt und man sich nur schwer umgewöhnen kann.
Mit OpenGL2 hat man das auch noch und ist nicht auf Shader angewiesen.
OpenGL 3 geht nur noch mit Shadern.
-
Naja wenn das Buch glBegin()/glEnd() für die ersten kurzen Beispiele verwendet oder einfach der Vollständigkeit halber erwähnt ist das OK, immerhin bekommt man damit schnell was auf den Bildschirm. Wenn das allerdings alles ist kannst du das Buch in die Tonne treten. Das ist nämlich nicht erst neulich veraltet sondern schon seit 10 Jahren oder so
-
Naja, ein weiteres Problem ist auch, dass 90% der Leute auf Nehe verwiesen werden wenn die OpenGL lernen wollen. Das ist ja leider auch nicht mehr so ganz aktuell.
-
Hallo,
danke für euere Hinweise. Ich habe nun sehr viel gelesen und festestellt, dass es zwar im ersten Moment eine große Denkumstellung ist auf OpenGL 4(.x), aber dass es eigentlich schon sinnvoll ist, was die Jungs sich überlegt haben.Ich will natürlich weiter gehen und weiter lernen. Aber mein letztes Buch war ein Flop und mit ein paar einfachen Tuts kommt man nicht weit, besonders, weil die meisten Tuts halt einfach "nur" einen Einblick geben; was fehlt ist ein "Best Practice".
Da ich aber immer noch nach dem Prinzip handle: Erst denken, dann fragen;
Ich habe mir folgendes Buch angeschaut und überlegt:Shader mit GLSL: Eine Einführung in die OpenGL Shading Language [Taschenbuch] # Taschenbuch: 162 Seiten # Verlag: Diplomica Verlag; Auflage: 1 (1. September 2009) # Sprache: Deutsch # ISBN-10: 3836679272 # ISBN-13: 978-3836679275 # http://www.amazon.de/Shader-mit-GLSL-Einf%C3%BChrung-Language/dp/3836679272/
Gut? Zu Empfehlen?
Leider habe ich keinen guten Einstieg gefunden zur "Best Practice".
Mein Ziel ist es immer noch eine 3D-Engine für mich zu schreiben, die meine einfachen Spiele (Niveau "Bomberman" oder "Pac-Man 3D") und Arbeiten (Niveau "Noteneditor für Musik") darstellen kann.Gerne auch Englisch, aber Deutsch ist mir lieber (wobei mir klar ist, dass ein Englisches Original meist am Besten ist).
Danke,
Stefan