AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Multimedia Delphi Merkwürdiges Problem mit Z-Buffer...

Merkwürdiges Problem mit Z-Buffer...

Ein Thema von md_mse · begonnen am 24. Okt 2005 · letzter Beitrag vom 30. Okt 2005
Antwort Antwort
Benutzerbild von md_mse
md_mse

Registriert seit: 13. Aug 2003
Ort: Berlin
95 Beiträge
 
#1

Merkwürdiges Problem mit Z-Buffer...

  Alt 24. Okt 2005, 11:05
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:
  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;
Miniaturansicht angehängter Grafiken
terrainerror_m_160.png  
Angehängte Dateien
Dateityp: zip terrainerror_809.zip (930,2 KB, 16x aufgerufen)
  Mit Zitat antworten Zitat
Benutzerbild von md_mse
md_mse

Registriert seit: 13. Aug 2003
Ort: Berlin
95 Beiträge
 
#2

Re: Merkwürdiges Problem mit Z-Buffer...

  Alt 25. Okt 2005, 14:36
Huhu
  Mit Zitat antworten Zitat
Benutzerbild von Neutral General
Neutral General

Registriert seit: 16. Jan 2004
Ort: Bendorf
5.219 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#3

Re: Merkwürdiges Problem mit Z-Buffer...

  Alt 25. Okt 2005, 14:40
"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....
Michael
  Mit Zitat antworten Zitat
Benutzerbild von md_mse
md_mse

Registriert seit: 13. Aug 2003
Ort: Berlin
95 Beiträge
 
#4

Re: Merkwürdiges Problem mit Z-Buffer...

  Alt 25. Okt 2005, 17:16
Hm, das ist merkwürdig... Die wird normalerweise mit DX 9c mit installiert...
Im Anhang die DLL.
Angehängte Dateien
Dateityp: zip d3dx9_27_601.zip (1,02 MB, 6x aufgerufen)
  Mit Zitat antworten Zitat
Oxmyx

Registriert seit: 21. Sep 2004
499 Beiträge
 
#5

Re: Merkwürdiges Problem mit Z-Buffer...

  Alt 25. Okt 2005, 18:16
Ändere
AutoDepthStencilFormat := D3DFMT_D16; mal in
AutoDepthStencilFormat := D3DFMT_D24X8; und schau, was passiert.
  Mit Zitat antworten Zitat
Benutzerbild von md_mse
md_mse

Registriert seit: 13. Aug 2003
Ort: Berlin
95 Beiträge
 
#6

Re: Merkwürdiges Problem mit Z-Buffer...

  Alt 25. Okt 2005, 19:58
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.
  Mit Zitat antworten Zitat
Benutzerbild von md_mse
md_mse

Registriert seit: 13. Aug 2003
Ort: Berlin
95 Beiträge
 
#7

Re: Merkwürdiges Problem mit Z-Buffer...

  Alt 30. Okt 2005, 17:00
Hm, hab das Problem gelößt...

DX schein damit Probleme zu haben, wenn die Near-Plane 0.0 ist...
Komische Geschichte.

Trotzdem danke
  Mit Zitat antworten Zitat
Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

Forumregeln

Es 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

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 15:31 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