OpenGL Depth
-
In dem folgenden Programm wird das Rechteck nur angezeigt, wenn ich glEnable(GL_DEPTH_TEST); auskommentiere. Sieht einer warum?
extern "C" { #include <X11/Xlib.h> #include <GL/glut.h> } void init() { glMatrixMode(GL_MODELVIEW); glLoadIdentity(); gluLookAt(2000000.0, 2000000.0, 10000000.0, 2000000.0, 2000000.0, 0.0, 0.0, 1.0, 0.0); glClearColor(0.0, 0.0, 0.0, 0.0); glShadeModel(GL_SMOOTH); glDepthFunc(GL_LESS); glEnable(GL_DEPTH_TEST); } void display(void) { glClearDepth(1.0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glColor3f(1.0, 0.0, 0.0); glNormal3f(0.0f, 0.0f, 1.0f); glBegin(GL_QUADS); glVertex3i(0, 0, -500000); glVertex3i(2000000, 0, -500000); glVertex3i(2000000, 2000000, -500000); glVertex3i(0, 2000000, -500000); glEnd(); glutSwapBuffers(); } void reshape(int w, int h) { glViewport(0, 0, (GLsizei) w, (GLsizei) h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(60.0, (GLfloat) w / (GLfloat) h, 1.0, 20000000.0); } int main(int argc, char ** argv) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); glutInitWindowSize(500, 500); glutInitWindowPosition(0, 0); glutCreateWindow("hello"); init(); glutDisplayFunc(display); glutReshapeFunc(reshape); glutMainLoop(); }
-
hi,
vllt musst du die hier rausnehmen...
glcleardepth(1.0);
-
Oermel schrieb:
hi,
vllt musst du die hier rausnehmen...
glcleardepth(1.0);Das hilft leider nicht. Ich habe das auch nur drin, weil mir jemand anderes das vorgeschlagen hat.
-
gluPerspective(60.0, (GLfloat) w / (GLfloat) h, 1.0, 20000000.0);20000000.0 erscheint mir etwas sehr hoch gegriffen, mach da mal was kleineres
-
Pellaeon schrieb:
gluPerspective(60.0, (GLfloat) w / (GLfloat) h, 1.0, 20000000.0);20000000.0 erscheint mir etwas sehr hoch gegriffen, mach da mal was kleineres
Die Objekte, die ich darstellen möchte haben Koordinaten im Bereich 0 bis 20 Mio. Dafür sind alle mindestens 100000 Einheiten groß. Es sollte also eigentlich keine Genauigkeitsprobleme geben, da von den 20 Mio vier Stellen zur Bestimmung der Tiefe reichen.
-
Versuch dein Programm mal wenn du alle Einheiten der Objekte und die Werte im Viewport (außer das 60.0f) durch 100.000 dividierst. Wozu auch soviele Nullen, das Ergebnis ohne ist das selbe.
lg, bloodycross
-
Jo mein reden;
@ponto: je größer die zahl vorm Komma desto ungenauer wirds dahinter, in deinem Code seh ich keinen Fehler. Es kann durchaus sein, dass das ganze ein Genauigkeitsproblem ist wegen deiner Riesenzahlen
-
Aber genau das soll der Vorteil von float sein. Ob ich nun 100000.0 oder 0.1 habe, ist egal. Die Genauigkeit ist die gleiche. 4-5 Stellen hinter der führenden Ziffer.
Aber ich versuche es mal mit euren Tipps.
Wie funktioniert eigentlich der Depth Buffer? Wird die entfernung zwischen Near und Far Plane äquidistant aufgeteilt oder anders?
-
Ah. In der OpenGL FAQ habe ich die Lösung gefunden. Mein zFar/zNear Faktor ist zu groß. Wusste nicht, dass man diesen Faktor so klein wie möglich halten sollte
-
Liegt daran dass er nur 16 Bit ist => größte mögliche Zahl ist 65535. Besser wäre es wenn das mal ein bischen modernisiert wird und alles auf min. 32 Bit float umgestellt wird.
K. A. obs in OpenGL 3.0 schon so ist, weiß das wer?lg, bloodycross
PS: Es ist eigentlich immer besser die Zahlen klein zu halten, vor allem wenn du dahinter eh nur Nullen hast. So passiert es nicht so leicht dass du die Variablengrenzen überschreitest, also die Variable umbricht und von Vorne zu zählen beginnt.
Edit: Mir fällt gerade ein dass man evt. die Größe des Depthbuffer selbst einstellen kann, sowie auch die anderen Buffer. Ich glaube aber dass das bei mir nicht funktioniert hat. (mit SDL war das glaub ich)
-
nur mal so zur information: der source funktioniert problemlos unter win32.
ich weiss zwar nicht genau, was (unter linux?) anders ist, aber viele der bisherigen behauptungen und spekulationen sind haarstraeubend.
-
Ich habe jetzt folgendes beobachtet:
Auf meinem Rechner mit Hardwareunterstützung funktioniert der Code einwandfrei.
Auf meinem Rechner ohne Hardwareunterstützung (nur Mesa) gibt es den oben beschriebenen Fehler. Wenn ich die near plane auf 100000 setze, was für meine Anwendung in Ordnung ist. Klappt es auch auf der Maschine.
Die FAQ http://www.opengl.org/resources/faq/technical/depthbuffer.htm#0040 beantwortet auch warum das so ist.
-
nicht so ganz...
damit das einzelne polygon nicht gezeichnet wird muss der z-test fehlschlagen.
bei "glDepthFunc(GL_LESS)" hiesse das, dass die z-koordinate des polygons (-500,000) und die maximal moegliche (-20,000,000.0) auf den gleichen zbuffer-index abgebildet werden.
auch bei deutlich geringerer zbuffer-praezision ist das nicht moeglich und deutet auf einen fehler in der mesa-implementierung hin.
-
hellihjb schrieb:
nicht so ganz...
damit das einzelne polygon nicht gezeichnet wird muss der z-test fehlschlagen.
bei "glDepthFunc(GL_LESS)" hiesse das, dass die z-koordinate des polygons (-500,000) und die maximal moegliche (-20,000,000.0) auf den gleichen zbuffer-index abgebildet werden.
auch bei deutlich geringerer zbuffer-praezision ist das nicht moeglich und deutet auf einen fehler in der mesa-implementierung hin.Naja. Ich hab mal die Werte eingesetzt. Die Mesa Implementierung hat 16 bits im depth buffer:
n = 1.0
f = 20000000.0
s = 65535Das Ergebnis ist, dass alle z-Werte von -65321 bis -20000000 sich auf 65534 und 65535 verteilen. Da die Kamera bei 10000000.0 liegt, ist das Rechteck bei einer z Koordinate von -9999500.0 und das ist weit im ungenauen Bereich.
Meine beschleunigte Implementierung hat eine Buffertiefe von 24 bits. Damit ist s = 16777215
Die werte 1677214 und 16777215 teilen sich den z-Bereich von -9123700 bis -20000000. Hier ist es viel wahrscheinlicher, dass die Koordinate -9999500.0 den Depth-Wert 1677214 zugewiesen bekommt und damit vor dem Hintergrund liegt.
-
Ponto schrieb:
Aber genau das soll der Vorteil von float sein. Ob ich nun 100000.0 oder 0.1 habe, ist egal. Die Genauigkeit ist die gleiche. 4-5 Stellen hinter der führenden Ziffer.
Stimmt so nicht. Hängt mit der Darstellung der Zahl zusammen(Mantisse, Exponent, usw.) Die Mantisse ist nunmal begrenzt und enthält die Infos für den Vor- und Nachkommteil und der Exponent bestimmt, wo das Komma hinegschoben wird(stark vereinfacht ausgedrückt!) Je mehr Stellen vor dem Komma stehen, umso weniger sind für dahinter da.
-
Pellaeon schrieb:
Ponto schrieb:
Aber genau das soll der Vorteil von float sein. Ob ich nun 100000.0 oder 0.1 habe, ist egal. Die Genauigkeit ist die gleiche. 4-5 Stellen hinter der führenden Ziffer.
Stimmt so nicht. Hängt mit der Darstellung der Zahl zusammen(Mantisse, Exponent, usw.) Die Mantisse ist nunmal begrenzt und enthält die Infos für den Vor- und Nachkommteil und der Exponent bestimmt, wo das Komma hinegschoben wird(stark vereinfacht ausgedrückt!) Je mehr Stellen vor dem Komma stehen, umso weniger sind für dahinter da.
Wir meinen eigentlich dasselbe. Mit Genauigkeit meine ich die Stellen hinter der ersten nicht 0. Wo das Komma liegt ist da egal.
Bei 100000.0 hat man bis zu 10 eine gute Genauigkeit und bei 0.1 hat man bis zu 0.00001 eine gute Genauigkeit.