[OpenGL] glGetError() verhält sich merkwürdig

Für Fragen zu Grafik APIs wie DirectX und OpenGL sowie Shaderprogrammierung.
Antworten
Andre
Establishment
Beiträge: 186
Registriert: 21.12.2011, 20:33

[OpenGL] glGetError() verhält sich merkwürdig

Beitrag von Andre »

Hi Leute,

ich habe die letzte Zeit damit verbracht unsere App auf Android zu portieren. Einen OpenGL-Renderer habe ich unter Windows schon geschrieben, wobei ich nur die Initialisierung etwas abändern musste um das ganze mit Android kompatibel zu machen.

Nun bin ich allerdings auf folgendes Problem gestoßen, welches für mich einfach keinen Sinn ergibt:

Ich habe 2 Makros, um die OpenGL-aufrufe auf Fehler zu überprüfen:

Code: Alles auswählen

#define GL_CHECK(x) \
        x; glGetError();

#define EGL_CHECK(x) \
	x; eglGetError();
Klar, da passiert nichts, weil ich die Logging-Funktionen nun mal weggelassen habe, aber der Effekt tritt trotzdem auf:
Wenn ich die Makros folgendermaßen abändere:

Code: Alles auswählen

#define GL_CHECK(x) x;
#define EGL_CHECK(x) x;
also noch mehr nichts, so bekomme ich etwas gerendert (nicht alles, aber immerhin ein paar Objekte).
Lasse ich den Aufruf zu glGetError() drin, so tut nur der Clear-Aufruf etwas, aber gerendert wird nichts.

Weiterhin ist komisch, dass mir, wenn die Logging-Funktionen noch drin sind natürlich, merkwürdige Werte für die Errors ausgegeben werden.
Es handelt sich dabei um 2 glGenBuffers-Aufrufe:

Code: Alles auswählen

	GL_CHECK(glGenBuffers(1, &VertexBufferID))
	GL_CHECK(glGenBuffers(1, &IndexBufferID))
Beim 1. Aufruf, wird glGetError() als "1" im Log stehen. Beim 2. Aufruf als "2". Wenn das nächste Objekt geladen wird gehts weiter, 3, 4, dann das nächste: 5, 6, und immer so weiter!
Dazwischen gibt es aber noch andere Funktionen, die auch Fehler liefern, die in der Dokumentation stehen, aber diese beiden Aufrufe zählen immer aufwärts mit ihren Fehlern!

Hat jemand soetwas schonmal gesehen und weiß vielleicht was da los ist? Ich bin für jede Hilfe dankbar :)
DerAlbi
Establishment
Beiträge: 269
Registriert: 20.05.2011, 05:37

Re: [OpenGL] glGetError() verhält sich merkwürdig

Beitrag von DerAlbi »

Code: Alles auswählen

#define GL_CHECK(x) \
x; glGetError();
Gefährlich. :-O Deine Fehlerbeschreibung lässt verlauten, dass umso mehr funktioniert, je weniger Instruktionen im #define stehen...

Code: Alles auswählen

If (boolean) GL_CHECK(...);
//oder
while(abc) GL_CHECK(...);
...wird alles völliger humbug. Kann es daran liegen?
Geschweifte Klammern!
Benutzeravatar
dot
Establishment
Beiträge: 1745
Registriert: 06.03.2004, 18:10
Echter Name: Michael Kenzel
Kontaktdaten:

Re: [OpenGL] glGetError() verhält sich merkwürdig

Beitrag von dot »

Andre hat geschrieben:Weiterhin ist komisch, dass mir, wenn die Logging-Funktionen noch drin sind natürlich, merkwürdige Werte für die Errors ausgegeben werden.
Es handelt sich dabei um 2 glGenBuffers-Aufrufe:

Code: Alles auswählen

	GL_CHECK(glGenBuffers(1, &VertexBufferID))
	GL_CHECK(glGenBuffers(1, &IndexBufferID))
Beim 1. Aufruf, wird glGetError() als "1" im Log stehen. Beim 2. Aufruf als "2". Wenn das nächste Objekt geladen wird gehts weiter, 3, 4, dann das nächste: 5, 6, und immer so weiter!
Klingt mir so, als würdest du da aus irgendeinem Grund die von glGenBuffers() zurückgegebenen Buffer Names als Error Codes ausgeben...
Benutzeravatar
Artificial Mind
Establishment
Beiträge: 802
Registriert: 17.12.2007, 17:51
Wohnort: Aachen

Re: [OpenGL] glGetError() verhält sich merkwürdig

Beitrag von Artificial Mind »

DerAlbi hat geschrieben: Geschweifte Klammern!
Auch nicht ideal, da dann

Code: Alles auswählen

if (boolean) GL_CHECK(...);
else GL_CHECK(...);
kaputt ist.

Deswegen:

Code: Alles auswählen

#define GL_CHECK(x) do { x; glGetError(); } while(0)
Benutzeravatar
dot
Establishment
Beiträge: 1745
Registriert: 06.03.2004, 18:10
Echter Name: Michael Kenzel
Kontaktdaten:

Re: [OpenGL] glGetError() verhält sich merkwürdig

Beitrag von dot »

Oder noch besser: Keine Makros sondern einfach eine GL::checkError() Funktion und fertig... ;)
Benutzeravatar
Artificial Mind
Establishment
Beiträge: 802
Registriert: 17.12.2007, 17:51
Wohnort: Aachen

Re: [OpenGL] glGetError() verhält sich merkwürdig

Beitrag von Artificial Mind »

dot hat geschrieben:Oder noch besser: Keine Makros sondern einfach eine GL::checkError() Funktion und fertig... ;)
Und dann per Template-foo die eigentliche OGL Funktion aufrufen?
Benutzeravatar
dot
Establishment
Beiträge: 1745
Registriert: 06.03.2004, 18:10
Echter Name: Michael Kenzel
Kontaktdaten:

Re: [OpenGL] glGetError() verhält sich merkwürdig

Beitrag von dot »

Nein, einfach nur GL::checkError(). So funktioniert OpenGL halt nunmal...
Benutzeravatar
Artificial Mind
Establishment
Beiträge: 802
Registriert: 17.12.2007, 17:51
Wohnort: Aachen

Re: [OpenGL] glGetError() verhält sich merkwürdig

Beitrag von Artificial Mind »

Die Idee ist doch eindeutig automatisch zu jedem GL-call einen Errorcheck zu haben (ohne viel duplicated Code) um direkt zu prüfen ob irgendwas fehlgeschlagen ist.
GL_ARB_debug_output kann man ja nicht überall annehmen (insbesondere nicht auf Android, oder?)
Und auch der Error Callback von OpenGL ist nicht überall verfügbar.
Benutzeravatar
dot
Establishment
Beiträge: 1745
Registriert: 06.03.2004, 18:10
Echter Name: Michael Kenzel
Kontaktdaten:

Re: [OpenGL] glGetError() verhält sich merkwürdig

Beitrag von dot »

Mir ist schon klar, was die Idee ist. Wo liegt das Problem, hinter jeden GL-call ein GL::checkError() zu schreiben!? Die Alternative ist ja offenbar, um jeden GL-call ein problematisches Makro zu wrappen. Wie geht man in dieser Lösung dann mit Funktionen wie glCreateShader() um, die einen Wert returnen? OpenGL funktioniert halt nunmal so...
Benutzeravatar
Artificial Mind
Establishment
Beiträge: 802
Registriert: 17.12.2007, 17:51
Wohnort: Aachen

Re: [OpenGL] glGetError() verhält sich merkwürdig

Beitrag von Artificial Mind »

Wir können noch gerne andere Meinungen einholen aber für mich "funktioniert OpenGL" nicht so, dass man seinen Code literally verdoppelt mit Errorchecks.
Insbesondere kann man die dann nicht mal eben alle rausnehmen, ganz zu schweigen davon, dass es den Code sehr hässlich werden lässt.

Die Funktionen die tatsächlich einen Wert zurückgeben kann man zwar nicht so einfach wrappen aber in meiner Erfahrung ist das nur ein ganz kleiner Teil des GL-Codes den man schreibt.

EDIT: Und wo ist das do-while Makro problematisch (abgesehen vom return value)?
Spiele Programmierer
Establishment
Beiträge: 426
Registriert: 23.01.2013, 15:55

Re: [OpenGL] glGetError() verhält sich merkwürdig

Beitrag von Spiele Programmierer »

[quote=Artificial Mind ]Insbesondere kann man die dann nicht mal eben alle rausnehmen[/quote]
Was spricht gegen eine Präprozessorverzweigung im einfachsten Fall zb. nach "DEBUG" etc.

Hinter wirklich jeder Zeile ist vielleicht ein bisschen arg viel, aber hinter jedem "Codeblock" sollte meiner Ansicht nach schon ein Check. Ansonsten wird Debugging unmöglich.

Interessant finde ich auch das Debug-Output Feature von OpenGL 4.3 oder der Äquivalenten "KHR_debug"-Extension. (bzw. aus Abwärtskompatibilitätsgründen auch die älteren Extensions dafür)
Damit kann man prinzipiell OpenGL Fehler ohne "glGetError" abfangen.
Andre
Establishment
Beiträge: 186
Registriert: 21.12.2011, 20:33

Re: [OpenGL] glGetError() verhält sich merkwürdig

Beitrag von Andre »

Das zeigt doch mal wieder wunderbar, dass man einem Makro niemals einfach so trauen sollte, besonders nicht wenn es aus irgendeinem Sample kommt ;)

Naja, aber das Makro ist leider nicht Schuld am Problem. Hier das ganze mal Komplett ohne Makros und mit Standard Android-Log-Funktion:

Code: Alles auswählen

/** Create API specific resources here */
HRESULT GLMesh::CreateMeshResources()
{
	// Generate the buffers
	glGenBuffers(1, &VertexBufferID);
	__android_log_print(ANDROID_LOG_INFO, "JustHotAir", "glGenBuffers(vx) - glGetError(): %d", glGetError());

	glGenBuffers(1, &IndexBufferID);
	__android_log_print(ANDROID_LOG_INFO, "JustHotAir", "glGenBuffers(ix) - glGetError(): %d", glGetError());

	// Bind the vertexbuffer
	glBindBuffer(GL_ARRAY_BUFFER, VertexBufferID);

	// Fill it with our data
	glBufferData(GL_ARRAY_BUFFER, NumVertices * sizeof(WorldVertexStruct), WorldVertices, GL_STATIC_DRAW);
		

	// Bind the indexbuffer
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IndexBufferID);

	// Fill it with our data
	glBufferData(GL_ELEMENT_ARRAY_BUFFER, NumIndices * sizeof(unsigned short), Indices, GL_STATIC_DRAW);

	glBindBuffer(GL_ARRAY_BUFFER, 0);
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);

	return S_OK;
}

Tut immernoch das selbe, nämlich hochzählen und nichts rendern (ohne glGetError() wird aber gerendert!). Hier mal ein Auszug aus dem Log:

Code: Alles auswählen

I/JustHotAir( 1433): Info:Switching to level 1
I/JustHotAir( 1433): Info:Loading level: Beach-01
I/JustHotAir( 1433): glGenBuffers(vx) - glGetError(): 1
I/JustHotAir( 1433): glGenBuffers(ix) - glGetError(): 2
E/emuglGLESv2_enc( 1433): device/androVM/common/opengl/system/GLESv2_enc/GL2Encoder.cpp:s_glBufferData:184 GL error 0x502
I/JustHotAir( 1433): glGenBuffers(vx) - glGetError(): 1282
I/JustHotAir( 1433): glGenBuffers(ix) - glGetError(): 4
E/emuglGLESv2_enc( 1433): device/androVM/common/opengl/system/GLESv2_enc/GL2Encoder.cpp:s_glBufferData:184 GL error 0x502
I/JustHotAir( 1433): glGenBuffers(vx) - glGetError(): 1282
I/JustHotAir( 1433): glGenBuffers(ix) - glGetError(): 6
E/emuglGLESv2_enc( 1433): device/androVM/common/opengl/system/GLESv2_enc/GL2Encoder.cpp:s_glBufferData:184 GL error 0x502
[...]
E/emuglGLESv2_enc( 1433): device/androVM/common/opengl/system/GLESv2_enc/GL2Encoder.cpp:s_glBufferData:184 GL error 0x502
[...]
I/JustHotAir( 1433): glGenBuffers(vx) - glGetError(): 1282
I/JustHotAir( 1433): glGenBuffers(ix) - glGetError(): 11
I/JustHotAir( 1433): glGenBuffers(vx) - glGetError(): 12
I/JustHotAir( 1433): glGenBuffers(ix) - glGetError(): 13
E/emuglGLESv2_enc( 1433): device/androVM/common/opengl/system/GLESv2_enc/GL2Encoder.cpp:s_glBufferData:184 GL error 0x502
E/emuglGLESv2_enc( 1433): device/androVM/common/opengl/system/GLESv2_enc/GL2Encoder.cpp:s_glBufferData:184 GL error 0x502
I/JustHotAir( 1433): glGenBuffers(vx) - glGetError(): 1282
I/JustHotAir( 1433): glGenBuffers(ix) - glGetError(): 15
E/emuglGLESv2_enc( 1433): device/androVM/common/opengl/system/GLESv2_enc/GL2Encoder.cpp:s_glBufferData:184 GL error 0x502
I/JustHotAir( 1433): glGenBuffers(vx) - glGetError(): 1282
I/JustHotAir( 1433): glGenBuffers(ix) - glGetError(): 17
E/emuglGLESv2_enc( 1433): device/androVM/common/opengl/system/GLESv2_enc/GL2Encoder.cpp:s_glBufferData:184 GL error 0x502
I/JustHotAir( 1433): glGenBuffers(vx) - glGetError(): 1282
I/JustHotAir( 1433): glGenBuffers(ix) - glGetError(): 19
E/emuglGLESv2_enc( 1433): device/androVM/common/opengl/system/GLESv2_enc/GL2Encoder.cpp:s_glBufferData:184 GL error 0x502
I/JustHotAir( 1433): glGenBuffers(vx) - glGetError(): 1282
I/JustHotAir( 1433): glGenBuffers(ix) - glGetError(): 21
E/emuglGLESv2_enc( 1433): device/androVM/common/opengl/system/GLESv2_enc/GL2Encoder.cpp:s_glBufferData:184 GL error 0x502
I/JustHotAir( 1433): glGenBuffers(vx) - glGetError(): 1282
I/JustHotAir( 1433): glGenBuffers(ix) - glGetError(): 23
E/emuglGLESv2_enc( 1433): device/androVM/common/opengl/system/GLESv2_enc/GL2Encoder.cpp:s_glBufferData:184 GL error 0x502
I/JustHotAir( 1433): glGenBuffers(vx) - glGetError(): 1282
I/JustHotAir( 1433): glGenBuffers(ix) - glGetError(): 25
E/emuglGLESv2_enc( 1433): device/androVM/common/opengl/system/GLESv2_enc/GL2Encoder.cpp:s_glBufferData:184 GL error 0x502
I/JustHotAir( 1433): glGenBuffers(vx) - glGetError(): 1282
I/JustHotAir( 1433): glGenBuffers(ix) - glGetError(): 27
E/emuglGLESv2_enc( 1433): device/androVM/common/opengl/system/GLESv2_enc/GL2Encoder.cpp:s_glBufferData:184 GL error 0x502
I/JustHotAir( 1433): glGenBuffers(vx) - glGetError(): 1282
I/JustHotAir( 1433): glGenBuffers(ix) - glGetError(): 29
E/emuglGLESv2_enc( 1433): device/androVM/common/opengl/system/GLESv2_enc/GL2Encoder.cpp:s_glBufferData:184 GL error 0x502
I/JustHotAir( 1433): glGenBuffers(vx) - glGetError(): 1282
I/JustHotAir( 1433): glGenBuffers(ix) - glGetError(): 31
E/emuglGLESv2_enc( 1433): device/androVM/common/opengl/system/GLESv2_enc/GL2Encoder.cpp:s_glBufferData:184 GL error 0x502
I/JustHotAir( 1433): glGenBuffers(vx) - glGetError(): 1282
I/JustHotAir( 1433): glGenBuffers(ix) - glGetError(): 33
E/emuglGLESv2_enc( 1433): device/androVM/common/opengl/system/GLESv2_enc/GL2Encoder.cpp:s_glBufferData:184 GL error 0x502
I/JustHotAir( 1433): glGenBuffers(vx) - glGetError(): 1282
I/JustHotAir( 1433): glGenBuffers(ix) - glGetError(): 35
E/emuglGLESv2_enc( 1433): device/androVM/common/opengl/system/GLESv2_enc/GL2Encoder.cpp:s_glBufferData:184 GL error 0x502
I/JustHotAir( 1433): glGenBuffers(vx) - glGetError(): 1282
I/JustHotAir( 1433): glGenBuffers(ix) - glGetError(): 37
E/emuglGLESv2_enc( 1433): device/androVM/common/opengl/system/GLESv2_enc/GL2Encoder.cpp:s_glBufferData:184 GL error 0x502
I/JustHotAir( 1433): glGenBuffers(vx) - glGetError(): 1282
I/JustHotAir( 1433): glGenBuffers(ix) - glGetError(): 39
Da sind so einige GL_INVALID_OPERATIONs, aber die sollten nur kommen, weil eben glGenBuffers schon nicht will. Außerdem gibt es nicht einen einzigen Aufruf zu "glBegin" in meinem Code, was der einzige Grund für diesen Fehler sein soll, laut Dokumentation... (glGenBuffers zwischen glBegin und glEnd)

Die Zahlen die glGetError() ausspuckt haben übrigens nichts mit den IDs der Buffer zu tun. Diese sind anders, und manchmal auch 0.
Andre
Establishment
Beiträge: 186
Registriert: 21.12.2011, 20:33

Re: [OpenGL] glGetError() verhält sich merkwürdig

Beitrag von Andre »

Problem hat sich gelöst! (Jedenfalls so halb)

Es war wohl irgendein Speicherproblem mit dem Code, der die Shader auf Fehler prüft, oder was weiß ich was da falsch gelaufen ist (Code kam nicht von mir, Sample...) und wieso glGetError() dann sowas produziert hat...
Aber danke trotzdem für die Hilfe :)
Antworten