|
Registriert seit: 13. Aug 2003 Ort: Berlin 95 Beiträge |
#1
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 ![]() 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:
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; |
![]() |
Ansicht |
![]() |
![]() |
![]() |
ForumregelnEs ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.
BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus. Trackbacks are an
Pingbacks are an
Refbacks are aus
|
|
Nützliche Links |
Heutige Beiträge |
Sitemap |
Suchen |
Code-Library |
Wer ist online |
Alle Foren als gelesen markieren |
Gehe zu... |
LinkBack |
![]() |
![]() |