View Full Version : [Frage] farZ Schranke / NV Treiberbug?
Wolfibolfi
04-04-2004, 13:56
Hallöchen, ich bin über ein komisches Problem gestolpert, wenn ich den Level rendern lasse, und die farZ Schranke groß (10000) ist, gibts bei nivida-Karten Darstellungsfehler. Wenn ich den Level um den Faktor 10 kleiner mache, und auch die farZ Schranke runtersetze (was aber eigentlich wurscht is, weil ich dann eh nicht bis zur Schranke rendern tu), dann gehts.
Falls es sich wer ansehn will:
NV-Bug (http://stud3.tuwien.ac.at/~e0026034/video/bug.avi)
Bei ATi-Karten gibts das Problem nicht, bei mir (GF4Ti4200, neuer Treiber von der nv Seite) schon.
wieviel bit verwendest du für den depth buffer (bzw welches pixel format hat dein rendering context...). es ist zwar in dem video nicht ganz genau zu erkennen, aber das was du da siehst könnte z-fighting sein, das dadurch entsteht, falls die genauigkeit des z-puffers nicht hoch genug ist um dinge, die sehr weit weg sind korrekt darzustellen (also zu entscheiden welche fragmente weiter vorne und sichtbar sind, bzw weiter hinten und unsichtbar. deshalb sieht es eben teilweise so aus, als ob der hintere teil des hügels gezeichnet wird und der vordere nicht).
im endeffekt ist wohl das beste workaround einfach wirklich das level so zu skalieren, dass es mit der genauigkeit in der entfernung keine probleme gibt, oder zu versuchen einen rendering context mit einem genaueren zbuffer zu erzeugen (maximal sind 32 bit... das gibt man für gewöhnlich bei der wahl des pixel formats an)
versuch mal die near clipping plane (nearZ) weiter vom aug wegzuschieben und schau, ob's dann geht - wenns dann funktioniert, ist es wirklich z-fighting. du musst nearZ und farZ so dimensionieren, dass die genauigkeit des zbuffers ausreicht - und check wie schon geschrieben auch noch mal, wieviel bit du für den z-buffer zur verfügung hast. wenn du den stencil-buffer nämlich nicht benötigst, kannst du diese bits auch dem depth buffer zuweisen.
Uebungsleitung
14-04-2004, 17:11
Als weitere Info:
Die nearplane weiter wegzuschieben ist nämlich deswegen sinnvoll, weil die Genauigkeit des z-buffers in der Nähe höher ist als in der Ferne (das ganze geht in einer ungefähr hyperbolischen Kurve, weil es proportional zu A+B/z ist, wobei A und B Konstanten sind). Der Grund dafür ist, daß nur 1/z-Werte perspektivisch korrekt im Bildraum interpoliert werden können...
Michael Wimmer
Wolfibolfi
01-05-2004, 18:50
Also, ich hab jetzt nochmal herumgespielt, und frag mich, wie ich denn die 32 Bit einstelle, unter DirectX is das ja kein Problem. Aber unter GL - keine Ahnung, ich kanns höchstens mit glutGet abfragen, dann weiß ich halt, dass ich 16 hab.
Irgendwie bin ich beim Doku-Lesen anscheinend blind, aber dem Glut kann ich nur angeben, ob ich einen Depth-Buffer will, aber wie ich die Größe setze, weiß ich nicht. Jetzt google ich schon ewig herum, und find nur abertausende seiten, die mir erklären können, wie ich die Größe abfrage.
Also, ich hab jetzt nochmal herumgespielt, und frag mich, wie ich denn die 32 Bit einstelle, unter DirectX is das ja kein Problem. Aber unter GL - keine Ahnung, ich kanns höchstens mit glutGet abfragen, dann weiß ich halt, dass ich 16 hab.
du setzt ja irgendwo das pixelformat für dein renderwindow, da musst du opengl ein pixelformat vorschlagen und bekommst dann ein möglichst ähnliches zurück, funktioniert ca. so:
int PixelFormat;
PIXELFORMATDESCRIPTOR pfd;
[... pfd setzen ...]
PixelFormat = ChoosePixelFormat(hDC, &pfd); // pixelformat vorschlagen
SetPixelFormat(hDC, PixelFormat, &pfd); // pixelformat setzen
der pixelformatdescriptor schaut folgendermassen aus, da findest du auch die depth buffer bits, und die setzt du einfach auf 32 (stencil dementsprechend auf 0, weil depth und stencil teilen sich 32 bits - standard ist normalerweise 24 / 8).
typedef struct tagPIXELFORMATDESCRIPTOR { // pfd
WORD nSize;
WORD nVersion;
DWORD dwFlags;
BYTE iPixelType;
BYTE cColorBits;
BYTE cRedBits;
BYTE cRedShift;
BYTE cGreenBits;
BYTE cGreenShift;
BYTE cBlueBits;
BYTE cBlueShift;
BYTE cAlphaBits;
BYTE cAlphaShift;
BYTE cAccumBits;
BYTE cAccumRedBits;
BYTE cAccumGreenBits;
BYTE cAccumBlueBits;
BYTE cAccumAlphaBits;
BYTE cDepthBits;
BYTE cStencilBits;
BYTE cAuxBuffers;
BYTE iLayerType;
BYTE bReserved;
DWORD dwLayerMask;
DWORD dwVisibleMask;
DWORD dwDamageMask;
} PIXELFORMATDESCRIPTOR;
Wolfibolfi
02-05-2004, 00:38
Super, danke!
Wir haben kein Pixelformat gesetzt, sondern nur mit dem glutDisplayirgendwas grob festgelegt, was wir wollen. Dass ich das mit einer non-gl Funktion einstellen muss, hätt ich nicht gedacht. :)
ChrisChiu
02-05-2004, 01:00
du setzt ja irgendwo das pixelformat für dein renderwindow, da musst du opengl ein pixelformat vorschlagen und bekommst dann ein möglichst ähnliches zurück, funktioniert ca. so:
int PixelFormat;
PIXELFORMATDESCRIPTOR pfd;
[... pfd setzen ...]
PixelFormat = ChoosePixelFormat(hDC, &pfd); // pixelformat vorschlagen
SetPixelFormat(hDC, PixelFormat, &pfd); // pixelformat setzen
der pixelformatdescriptor schaut folgendermassen aus, da findest du auch die depth buffer bits, und die setzt du einfach auf 32 (stencil dementsprechend auf 0, weil depth und stencil teilen sich 32 bits - standard ist normalerweise 24 / 8).
typedef struct tagPIXELFORMATDESCRIPTOR { // pfd
WORD nSize;
WORD nVersion;
DWORD dwFlags;
BYTE iPixelType;
BYTE cColorBits;
BYTE cRedBits;
BYTE cRedShift;
BYTE cGreenBits;
BYTE cGreenShift;
BYTE cBlueBits;
BYTE cBlueShift;
BYTE cAlphaBits;
BYTE cAlphaShift;
BYTE cAccumBits;
BYTE cAccumRedBits;
BYTE cAccumGreenBits;
BYTE cAccumBlueBits;
BYTE cAccumAlphaBits;
BYTE cDepthBits;
BYTE cStencilBits;
BYTE cAuxBuffers;
BYTE iLayerType;
BYTE bReserved;
DWORD dwLayerMask;
DWORD dwVisibleMask;
DWORD dwDamageMask;
} PIXELFORMATDESCRIPTOR;
Funktioniert das so unter GLUT überhaupt? Der Code hier baut ja quasi auf Windows-API-Funktionen auf (ChoosePixelFormat() usw.).
Ich wüsst zumindest nicht wie man unter GLUT den GDI Device Context Handle (HDC) des Render-Fensters (oder wenigstens dessen HWND Window Handle) bekommt.
Aber da GLUT das intern sicher irgendwo auch so macht für den Win32-Zweig, könnte man eventuell den GLUT-Source-Code diesbezüglich modifizieren.
Funktioniert das so unter GLUT überhaupt? Der Code hier baut ja quasi auf Windows-API-Funktionen auf (ChoosePixelFormat() usw.).
gute frage, ich hab glut noch nie zum erstellen des windows verwendet, sondern höchstens für objekte, camera etc. sollte aber eigentlich auch klappen, man muss ja auch über glut irgendwie das window-handle bekommen ...
und wenn nicht, dann erstelle man das renderwindow halt selbst - dann hat man zumindest die genaue kontrolle über alles, und wahnsinnig aufwändig ist es ja auch nicht :). (vor allem hab ich den ganzen code dafür eh schon hingeschrieben :)
Uebungsleitung
03-05-2004, 10:43
also bei Glut sollte das mit glutinitdisplaystring("depth=32") oder so gehen...
Michael Wimmer
also bei Glut sollte das mit glutinitdisplaystring("depth=32") oder so gehen...
yup, nachgelesen ... mit glutInitDisplayString ("depth=32") geht's. der befehl kann noch einiges mehr, nachlesen lohnt z.B. unter
http://www.fifi.org/cgi-bin/man2html/usr/X11R6/man/man3/glutInitDisplayString.3xglut.gz
wieder was gelernt ...
Wolfibolfi
04-05-2004, 01:32
Ja, funktioniert super! Komischerweise wird dadurch das Double-Buffering ausgeschalten, obwohls im glutIinitDisplay eingeschalten wurde. Muss man halt in der String Methode nochmal einschalten, dann gehts toll!
Danke! :thumb:
vBulletin® v3.7.1, Copyright ©2000-2009, Jelsoft Enterprises Ltd.