Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Multimedia (https://www.delphipraxis.net/16-multimedia/)
-   -   Delphi Merkwürdiges Problem mit Z-Buffer... (https://www.delphipraxis.net/55614-merkwuerdiges-problem-mit-z-buffer.html)

md_mse 24. Okt 2005 11:05


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:
  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);
Erstellen der Landschaft aus einer Heightmap:
Delphi-Quellcode:
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;
Rendern der Szene/Landschaft:
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;

md_mse 25. Okt 2005 14:36

Re: Merkwürdiges Problem mit Z-Buffer...
 
Huhu :) :firejump: :wink:

Neutral General 25. Okt 2005 14:40

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....

md_mse 25. Okt 2005 17:16

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.

Oxmyx 25. Okt 2005 18:16

Re: Merkwürdiges Problem mit Z-Buffer...
 
Ändere
Delphi-Quellcode:
AutoDepthStencilFormat := D3DFMT_D16;
mal in
Delphi-Quellcode:
AutoDepthStencilFormat := D3DFMT_D24X8;
und schau, was passiert.

md_mse 25. Okt 2005 19:58

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.

md_mse 30. Okt 2005 17:00

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 20:46 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz