![]() |
Merkwürdiges Problem mit Z-Buffer...
Liste der Anhänge anzeigen (Anzahl: 2)
Hallo Delphianer.
Ich bin am rum experimentieren mit DirectX (9) und dem Erstellen von 3D Landschaften. DirectX ist übrigens auch ein relativ neues Thema für mich :angel2: ! Zur Zeit kämpfe ich mit einem sehr merkwürdigem Problem des Z-Buffers(?). Obwohl er aktiviert ist, auch vor dem Rendern eines Frames gelöscht wird, kommt es dazu, dass beim rotieren der Kamera der Hintergrund der Landschaft plötzlich vor dem Vordergrund gezeichnet wird :gruebel: ... Dies tritt auch auf, wenn ich die Welt per Matrix-Befehl drehe. Anbei ein Screenshot des Problems, und das Programm. Hier nochmal einige Auszüge aus dem Quellcode: Initialisierung von D3D:
Delphi-Quellcode:
Erstellen der Landschaft aus einer Heightmap:
D3DInit := Direct3DCreate9(D3D_SDK_VERSION);
if (D3DInit = nil) then FatalError(0, 'Fehler beim Erstellen von Direct3D!'); // Setze zunächst alle D3DPRESENT_PARAMETERS auf 0 ZeroMemory(@d3dpp, SizeOf(d3dpp)); with d3dpp do begin SwapEffect := D3DSWAPEFFECT_DISCARD; hDeviceWindow := Handle; // Dies ist unser HWND von TForm // Wir brauche einen Z-Buffer also schalten wir ihn ein EnableAutoDepthStencil := True; AutoDepthStencilFormat := D3DFMT_D16; PresentationInterval := D3DPRESENT_INTERVAL_IMMEDIATE; // Initialisieren des Backbuffers Windowed := True; if not Windowed then begin // Vollbild BackBufferWidth := 800; BackBufferHeight := 600; BackBufferFormat := D3DFind16BitMode; BackBufferCount := 1; // 1 Backbuffer end else begin // Fenster hr := D3DInit.GetAdapterDisplayMode(D3DADAPTER_DEFAULT, d3ddm); if Failed(hr) then FatalError(hr, 'Fehler beim Ermitteln des Dislaymodes'); BackBufferFormat := d3ddm.Format; end; end; // Hardware T&L? hr := D3DInit.GetDeviceCaps(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, FD3dDevCaps); if Failed(hr) then FatalError(hr, 'Fehler beim Abfragen der DevCaps'); FHwVertexProcess := FD3dDevCaps.DevCaps and D3DDEVCAPS_HWTRANSFORMANDLIGHT <> 0; if FHwVertexProcess then vp := D3DCREATE_HARDWARE_VERTEXPROCESSING else vp := D3DCREATE_SOFTWARE_VERTEXPROCESSING; //Erstellen des D3D-Device hr := D3DInit.CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, Handle, vp, @d3dpp, D3DRenderer);
Delphi-Quellcode:
Rendern der Szene/Landschaft:
var
Bitmap: TBitmap; ix, iy, Index: Integer; WorldHeight, WorldWidth: Integer; AvailWorldHeight, AvailWorldWidth: Integer; VertexList: array of TD3DLVertex; IndexList: array of Word; bBuffer: Pointer; idm: ID3DXMesh; begin Bitmap := TBitmap.Create; Bitmap.LoadFromFile(FileName); try with FTargetRenderer do begin WorldWidth := Bitmap.Width; WorldHeight := Bitmap.Height; // // Maps, die größer sind als 100x100 würden mehr als die gültigen 2^16 // Vertices besitzen, also muss demnach die Präzision verändert werden! // if (WorldWidth * WorldHeight > 21845{(2^16)-1 / 3}) then FMapPrecision := Round(Ceil((WorldWidth * WorldHeight) / 21845)); AvailWorldWidth := WorldWidth div FMapPrecision; AvailWorldHeight := WorldHeight div FMapPrecision; FVerticeCount := AvailWorldWidth * AvailWorldHeight; // Buffer erstellen CreateVertexBuffer(FVerticeCount * SizeOf(TD3DLVertex), D3DUSAGE_WRITEONLY or D3DUSAGE_DYNAMIC, D3DFVF_LVertexFormat, D3DPOOL_DEFAULT, FVertexBuffer, nil); CreateIndexBuffer(65536 * SizeOf(Word), D3DUSAGE_WRITEONLY, D3DFMT_INDEX16, D3DPOOL_DEFAULT, FIndexBuffer, nil); // Sicherstellen dass später keine falschen Werte berechnet werden... FBoundingBoxMin := D3DXVector3(MaxSingle, MaxSingle, MaxSingle); FBoundingBoxMax := D3DXVector3(MinSingle, MinSingle, MinSingle); // // Vertices mit Höheninformationen aus HeightMap erstellen... // Index := 0; SetLength(VertexList, FVerticeCount); SetLength(IndexList, 65536); for ix := 0 to AvailWorldWidth - 1 do begin for iy := 0 to AvailWorldHeight - 1 do begin FMap[ix, iy] := Bitmap.Canvas.Pixels[ix, iy] mod 256; VertexList[Index] := D3DLVertex(ix * FMapExpansionFactor / AvailWorldWidth, FMap[ix, iy] * FMapHeightExpFactor / 255, iy * FMapExpansionFactor / AvailWorldHeight, D3DCOLOR_XRGB(200, 100, 50), 0, 0); VertexList[Index].tu := ix / AvailWorldWidth; VertexList[Index].tv := iy / AvailWorldHeight; // Bounding box erstellen... FBoundingBoxMin := MinVertex(FBoundingBoxMin, VertexList[Index]); FBoundingBoxMax := MaxVertex(FBoundingBoxMax, VertexList[Index]); Inc(Index); end; end; // // Vertices mit Höheninformationen miteinander verbinden, damit Polygone // entstehen... // Index := 0; for ix := 0 to AvailWorldWidth - 2 do begin for iy := 0 to AvailWorldHeight - 2 do begin IndexList[Index] := ix + (iy * AvailWorldWidth); IndexList[Index + 1] := ix + 1 + (iy * AvailWorldWidth); IndexList[Index + 2] := ix + ((iy + 1) * AvailWorldWidth); IndexList[Index + 3] := ix + 1 + (iy * AvailWorldWidth); IndexList[Index + 4] := ix + 1 + ((iy + 1) * AvailWorldWidth); IndexList[Index + 5] := ix + ((iy + 1) * AvailWorldWidth); Inc(Index, 6); end; end; FIndexCount := Index; // Vertices in Buffer kopieren //if Failed(FVertexBuffer.Lock(0, 0, bBuffer, 0)) then // raise EFatalException.Create('Buffer lock failed in GenerateTarrainFromHeightMap'); Assert(not Failed(FVertexBuffer.Lock(0, 0, bBuffer, 0)), 'Vertex-Buffer lock failed'); Move(VertexList[0], bBuffer^, SizeOf(TD3DLVertex) * Length(VertexList)); FVertexBuffer.Unlock; // Indices in Buffer kopieren Assert(not Failed(FIndexBuffer.Lock(0, 0, bBuffer, 0)), 'Index-Buffer lock failed'); Move(IndexList[0], bBuffer^, SizeOf(Word) * Length(IndexList)); FIndexBuffer.Unlock; end; // Textur laden... D3DXCreateTextureFromFile(FTargetRenderer, PChar(TextureBaseDir + 'NoTex.dds'), FTexture); finally Bitmap.Free; SetLength(VertexList, 0); SetLength(IndexList, 0); end;
Delphi-Quellcode:
var
ViewMatrix: TD3DXMatrix; i: Integer; n: Integer; //Our translation matrix R: TRect; begin Rotation := Rotation + IncRotationBy; if Assigned(D3DRenderer) then with D3DRenderer do begin Clear(0, nil, D3DCLEAR_TARGET or D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0, 0, 0), 1.0, 0); R := Bounds(1, 1, 0, 0); dxFont.DrawTextA(nil, PChar('FPS: ' + IntToStr(FPS)), -1, @R, DT_NOCLIP, D3DCOLOR_XRGB(255, 255, 255)); if Succeeded(BeginScene) then begin D3DXMatrixLookAtLH(ViewMatrix, D3DXVector3(Sin(PiBy180 * Rotation) * HeightDistance * 1.5, HeightDistance, Cos(PiBy180 * Rotation) * HeightDistance * 1.5), D3DXVector3(0.0, 0.0, 0.0), D3DXVector3(0.0, 1.0, 0.0)); SetTransform(D3DTS_VIEW, ViewMatrix); SetTexture(0, FTexture); // Mit D3DTSS_COLLORP wird festgelegt, wie die Farbe jedes einzelnen Pixels // verarbeitet wird. D3DTOP_SELECTARG1 verweist auf D3DTSS_COLORARG1 SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1); // Mit D3DTSS_COLORARG1 wird festgelegt, daß die Farbe nur von der Textur // genommen wird und von nichts anderem. SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); // Wir benutzen kein Alpha blending, also schalten wir es ab. SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_DISABLE); // MipMapping SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_POINT); SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); SetFVF(D3DFVF_LVertexFormat); SetStreamSource(0, FVertexBuffer, 0, SizeOf(TD3DLVertex)); SetIndices(FIndexBuffer); DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, FVerticeCount, 0, FIndexCount div 3); EndScene; end; // Zeige Resultate auf dem Bildschirm Present(nil, nil, 0, nil); Inc(RenderedFramesCount); end; |
Re: Merkwürdiges Problem mit Z-Buffer...
Huhu :) :firejump: :wink:
|
Re: Merkwürdiges Problem mit Z-Buffer...
"Die Anwendung konnte nicht gestartet werden, weil d3dx9_27.dll nicht gefunden wurde. Neuinstallation der Anwendung könnte das Problem beheben."
Also DirectX 9 hab ich aber installiert.... |
Re: Merkwürdiges Problem mit Z-Buffer...
Liste der Anhänge anzeigen (Anzahl: 1)
Hm, das ist merkwürdig... Die wird normalerweise mit DX 9c mit installiert... :gruebel:
Im Anhang die DLL. |
Re: Merkwürdiges Problem mit Z-Buffer...
Ändere
Delphi-Quellcode:
mal in
AutoDepthStencilFormat := D3DFMT_D16;
Delphi-Quellcode:
und schau, was passiert.
AutoDepthStencilFormat := D3DFMT_D24X8;
|
Re: Merkwürdiges Problem mit Z-Buffer...
Hm, da passiert das gleiche nur noch zusätzlich mit einem komischen "Kriseln"...
Wobei ich auch schon dran gedacht habe, dass es an einem zu kleinen Z-Buffer liegen könnte, nur wollte ich gleich D3DFMT_D32, was aber nicht funktioniert hat. |
Re: Merkwürdiges Problem mit Z-Buffer...
Hm, hab das Problem gelößt...
DX schein damit Probleme zu haben, wenn die Near-Plane 0.0 ist... Komische Geschichte. Trotzdem danke :) |
Alle Zeitangaben in WEZ +1. Es ist jetzt 01:40 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz