| Autor |
Beitrag |
md_mse
Hält's aus hier
Beiträge: 2
|
Verfasst: Mo 24.10.05 18:47
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  ...
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:
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47:
| D3DInit := Direct3DCreate9(D3D_SDK_VERSION); if (D3DInit = nil) then FatalError(0, 'Fehler beim Erstellen von Direct3D!');
ZeroMemory(@d3dpp, SizeOf(d3dpp)); with d3dpp do begin SwapEffect := D3DSWAPEFFECT_DISCARD; hDeviceWindow := Handle; EnableAutoDepthStencil := True; AutoDepthStencilFormat := D3DFMT_D16;
PresentationInterval := D3DPRESENT_INTERVAL_IMMEDIATE;
Windowed := True; if not Windowed then begin BackBufferWidth := 800; BackBufferHeight := 600; BackBufferFormat := D3DFind16BitMode; BackBufferCount := 1; end else begin hr := D3DInit.GetAdapterDisplayMode(D3DADAPTER_DEFAULT, d3ddm); if Failed(hr) then FatalError(hr, 'Fehler beim Ermitteln des Dislaymodes'); BackBufferFormat := d3ddm.Format; end; end;
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;
hr := D3DInit.CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, Handle, vp, @d3dpp, D3DRenderer); |
Erstellen der Landschaft aus einer Heightmap:
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88: 89: 90: 91: 92: 93: 94: 95: 96: 97: 98: 99: 100: 101: 102: 103: 104: 105: 106: 107: 108: 109: 110:
| 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; if (WorldWidth * WorldHeight > 21845) then FMapPrecision := Round(Ceil((WorldWidth * WorldHeight) / 21845));
AvailWorldWidth := WorldWidth div FMapPrecision; AvailWorldHeight := WorldHeight div FMapPrecision;
FVerticeCount := AvailWorldWidth * AvailWorldHeight;
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);
FBoundingBoxMin := D3DXVector3(MaxSingle, MaxSingle, MaxSingle); FBoundingBoxMax := D3DXVector3(MinSingle, MinSingle, MinSingle); 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;
FBoundingBoxMin := MinVertex(FBoundingBoxMin, VertexList[Index]); FBoundingBoxMax := MaxVertex(FBoundingBoxMax, VertexList[Index]);
Inc(Index); end; end;
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;
Assert(not Failed(FVertexBuffer.Lock(0, 0, bBuffer, 0)), 'Vertex-Buffer lock failed'); Move(VertexList[0], bBuffer^, SizeOf(TD3DLVertex) * Length(VertexList)); FVertexBuffer.Unlock;
Assert(not Failed(FIndexBuffer.Lock(0, 0, bBuffer, 0)), 'Index-Buffer lock failed'); Move(IndexList[0], bBuffer^, SizeOf(Word) * Length(IndexList)); FIndexBuffer.Unlock; end;
D3DXCreateTextureFromFile(FTargetRenderer, PChar(TextureBaseDir + 'NoTex.dds'), FTexture);
finally Bitmap.Free; SetLength(VertexList, 0); SetLength(IndexList, 0); end; |
Rendern der Szene/Landschaft:
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53:
| var ViewMatrix: TD3DXMatrix; i: Integer; n: Integer; 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);
SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1); SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_DISABLE); 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;
Present(nil, nil, 0, nil); Inc(RenderedFramesCount); end; |
Einloggen, um Attachments anzusehen!
|
|
NeoInDerMATRIX
      
Beiträge: 245
Win95, Win98(+se), WinNT, Win2000, WinME, WinXP(+pro), VISTA, Linux(SuSe), DOS [MultiMon(3)], Vista
D6 PeE + (FP 2.0l) + D3 Pe + D2005+ D2006 Arch
|
Verfasst: So 30.10.05 17:27
Hi,
ich bin zwar kein Fachman im bereich DX aber es sieht danach aus als ob die Scene nicht nur einmal sondern zweimal gezeichnet wird. Sieht jedenfals so aus. Allerdings wie gesagt bin kein DX mensch. OGL code währe für mich leichter zu verstehen.
Cu
Neo
P.S.: Und bitte tu mal noch die d3dx9_27.dll in dein ZIP mit rein. Nicht jeder hat das DX-SDK auf dem rechner.
|
|
md_mse 
Hält's aus hier
Beiträge: 2
|
Verfasst: So 30.10.05 18:04
Hm, hab das Problem gelößt...
Die Szene wurde nicht zwei mal gerendert.
DX schein damit Probleme zu haben, wenn die Near-Plane 0.0 ist...
Komische Geschichte.
Trotzdem danke 
|
|
|