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 !
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 ...
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:
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;
// Initialisieren des Backbuffers
Windowed := True; ifnot Windowed then begin // Vollbild
BackBufferWidth := 800;
BackBufferHeight := 600;
BackBufferFormat := D3DFind16BitMode;
BackBufferCount := 1; // 1 Backbuffer endelse 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;
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;
// // 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);
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);
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.