+ -
当前位置:首页 → 问答吧 → 为什么显示不出图片,,D3D

为什么显示不出图片,,D3D

时间:2011-08-29

来源:互联网

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, Direct3D9, StdCtrls;

type
  TVertex = packed record
  X, Y, Z, RHW: Single;
  Color : D3DCOLOR;
  U, V : Single;
  end;

  T2DPanel = array [0..3] of TVertex;

  TForm1 = class(TForm)
  procedure FormCreate(Sender: TObject);
  procedure FormPaint(Sender: TObject);
  private
  FD3D : IDirect3D9;
  FDevice : IDirect3DDevice9;
  FD3dpp : D3DPRESENT_PARAMETERS;
  FImageTexture : IDirect3DTexture9;
  ImgWidth : Single;
  ImgHeight : Single;
  function InitD3D():Boolean;
  procedure SetDeviceRenderState();
  procedure SetDeviceSamplerState();
  procedure LoadTexture(sFileName:String);
  procedure Render();
  procedure RenderImage();
  { Private declarations }
  public
  { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
  if not InitD3D() then exit;
end;

function TForm1.InitD3D: Boolean;
begin
  Result := False;
  FD3D := Direct3DCreate9(D3D_SDK_VERSION);
  if FD3D = nil then
  Exit;
  FillChar(FD3dpp, sizeof(D3DPRESENT_PARAMETERS), 0);
  FD3dpp.BackBufferWidth := form1.Width;
  FD3dpp.BackBufferHeight := form1.Height;
  FD3dpp.BackBufferFormat := D3DFMT_UNKNOWN;
  FD3dpp.SwapEffect := D3DSWAPEFFECT_DISCARD;
  FD3dpp.Windowed := True;
  if FAILED(FD3D.CreateDevice(D3DADAPTER_DEFAULT,
  D3DDEVTYPE_HAL,
  form1.Handle,
  D3DCREATE_SOFTWARE_VERTEXPROCESSING,
  @FD3Dpp,
  FDevice)) then
  Exit;
  SetDeviceRenderState();
  LoadTexture('r.bmp');
  Result := True;
end;

procedure TForm1.LoadTexture(sFileName:String);
var
  Bmp:TBitmap;
begin
  Bmp:=TBitmap.Create;
  Bmp.LoadFromFile(sFileName);
  ImgWidth:=Bmp.Width;
  ImgHeight:=Bmp.Height;
  form1.Width := Bmp.Width;
  form1.Height:= Bmp.Height;
  if FAILED(FDevice.CreateTexture( Bmp.Width,
  Bmp.Height,
  1, 0,
  D3DFMT_A8R8G8B8,
  D3DPOOL_MANAGED,
  FImageTexture,
  nil)) then
  Raise Exception.Create('创建位图纹理失败!');
end;

procedure TForm1.SetDeviceRenderState;
begin
  with FDevice do
  begin
  SetRenderState(D3DRS_LIGHTING, 0);
  SetRenderState(D3DRS_ZENABLE, D3DZB_FALSE);
  SetRenderState(D3DRS_ALPHABLENDENABLE, 1);
  SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
  SetRenderState(D3DRS_DESTBLEND,D3DBLEND_INVSRCALPHA);
  SetFVF(D3DFVF_XYZRHW or D3DFVF_DIFFUSE or D3DFVF_TEX1);
  end;
  SetDeviceSamplerState();
end;

procedure TForm1.SetDeviceSamplerState;
begin
  FDevice.SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
  FDevice.SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
end;

procedure TForm1.FormPaint(Sender: TObject);
begin
  Render();
end;

procedure TForm1.Render;
begin
  if FDevice = nil then
  Exit;
  FDevice.Clear(0, nil, D3DCLEAR_TARGET, $FF000000, 1.0, 0);
  if SUCCEEDED(FDevice.BeginScene()) then
  begin
  RenderImage();
  end;
  FDevice.EndScene();
  FDevice.Present(nil, nil, 0, nil);
end;

procedure TForm1.RenderImage;
  function Make2DVertex(const _X, _Y, _U, _V: Single; const col: D3DCOLOR):TVertex;
  begin
  with Result do
  begin
  X := _X;
  Y := _Y;
  Z := 0;
  RHW := 1.0;
  Color := col;
  U := _U;
  V := _V;
  end;
  end;
  function Make2DPanel(const X, Y, AWidth, AHeight: Single; const col: D3DCOLOR):T2DPanel;
  begin
  Result[0] := Make2DVertex(X, Y + AHeight, 0, 1, col);//左下
  Result[1] := Make2DVertex(X, Y, 0, 0, col);//左上
  Result[2] := Make2DVertex(X + AWidth, Y + AHeight, 1, 1, col);//右下
  Result[3] := Make2DVertex(X + AWidth, Y, 1, 0, col);//右上
  end;
var
  Vertices: T2DPanel;
begin
  if FImageTexture = nil then
  Exit;
  Vertices := Make2DPanel(0, 0, ImgWidth, ImgHeight , $FFFFFFFF);
  FDevice.SetTexture(0, FImageTexture);
  FDevice.DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, Vertices, sizeof(TVertex));
end;

end.

作者: gongliangjie_1985   发布时间: 2011-08-29

对delphi的d3d不是太熟,下面都是基于c++的,应该能看明白,不知道c++中的所有d3d函数和常量delphi是不是都能用。
把纹理绑定到纹理通道以后,就是这句FDevice.SetTexture(0, FImageTexture);,应该设置一下纹理通道状态,如下
g_pd3dDevice->SetTextureStageState(0,D3DTSS_COLORARG1,D3DTA_TEXTURE);
g_pd3dDevice->SetTextureStageState(0,D3DTSS_COLOROP,D3DTOP_SELECTARG1);
这里g_pd3dDevice应该就是等同于你那个FDevice,看能不能显示纹理了。
还有就是背面裁剪方式是不是和你的定点顺序一致,一般都是逆时针序裁剪,那么顶点顺序就要是顺时针,否则就看不到了。
还有你那个LoadTexture函数问题很多,首先你那个bmp对象根本就没有释放,而且那个bmp对象除了取得宽高外根本没用,CreateTexture最后一个参数是个对象句柄指针,应该指向那个bmp对象,而且这时不能使用托管池而要使用系统池D3DPOOL_SYSTEMMEM,在c++中可以使用D3DX库直接从文件载入纹理,不知你那里有没有转换sdk的D3DX库,如果有的话直接使用D3DXCreateTextureFromFile函数。

作者: bluekitty   发布时间: 2011-08-29

楼主参考一下,这是我自己写的一个控件中的代码:

function TD3DWindow.InitD3dWindow: HRESULT;
var
  d3dpp: TD3DPresentParameters;
  rc: TRect;
begin
  if p_pD3D <> nil then p_pD3D := nil;
  if p_pD3DDevice <> nil then p_pD3DDevice := nil;
  Result := E_FAIL;
  p_pD3D := Direct3DCreate9(D3D_SDK_VERSION);
  if (p_pD3D = nil) then Exit;
  FillChar(d3dpp, SizeOf(d3dpp), 0);
  d3dpp.BackBufferWidth := Width;
  d3dpp.BackBufferHeight := Height;
  d3dpp.Windowed := True;
  d3dpp.SwapEffect := D3DSWAPEFFECT_DISCARD;
  d3dpp.BackBufferFormat := D3DFMT_A8R8G8B8;
  d3dpp.Flags := D3DPRESENTFLAG_LOCKABLE_BACKBUFFER;
  Result := p_pD3D.CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, Handle, D3DCREATE_SOFTWARE_VERTEXPROCESSING, @d3dpp, p_pd3dDevice);
  if FAILED(Result) then
  begin
  Result := E_FAIL;
  Exit;
  end;
  p_pD3DDevice.SetRenderState(D3DRS_ALPHABLENDENABLE, 1);
  p_pd3dDevice.SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); //D3DCULL_NONE
  p_pd3dDevice.SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
  p_pd3dDevice.SetRenderState(D3DRS_LIGHTING, 0);
  p_pd3dDevice.SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
  Result := S_OK;
end;

procedure TD3DWindow.SetupMatrices(g_nAppWidth, g_nAppHeight: Single);
var matProj, matScal: TD3DXMatrixA16;
begin
  D3DXMatrixOrthoOffCenterLH(matProj, 0.0, g_nAppWidth, 0, g_nAppHeight, 0.0, 1.0);
  D3DXMatrixScaling(matScal, 1, -1, 1.0); //第3个参数为-1时,倒转图片

  D3DXMatrixMultiply(matProj, matProj, matScal);
  p_pd3dDevice.SetTransform(D3DTS_PROJECTION, matProj);
end;

procedure render;
var matRot, matMove, matWorld: TD3DXMatrix;
  ix,iy ,Angle : single;
  dwcolor : DWORD;
begin
  SetupMatrices(width,height);
  D3DXMatrixIdentity(matRot); //旋转矩阵
  D3DXMatrixIdentity(matMove); //平移矩阵
  D3DXMatrixIdentity(matWorld); //世界矩阵
  dwcolor := $FFFFFFFF;
  if Alpha < 255 then //alpha 透明度
  begin
  dwcolor := $00FFFFFF;
  dwcolor := dwcolor or (Alpha shl 24);
  end;
  //顶点数据这样改一下
  FillChar(g_Vertices[0], SizeOf(TCustomVERTEX) * 4, 0);
  g_Vertices[0].x := -Width * 0.5;
  g_Vertices[0].y := -Height * 0.5;
  g_Vertices[0].z := 0;
  g_Vertices[0].color := dwcolor;
  g_Vertices[0].u := 0;
  g_Vertices[0].v := 0;
  g_Vertices[1].x := -Width * 0.5;
  g_Vertices[1].y := Height * 0.5;
  g_Vertices[1].z := 0;
  g_Vertices[1].color := dwcolor;
  g_Vertices[1].u := 0;
  g_Vertices[1].v := 1.0;
  g_Vertices[2].x := Width * 0.5;
  g_Vertices[2].y := -Height * 0.5;
  g_Vertices[2].z := 0;
  g_Vertices[2].color := dwcolor;
  g_Vertices[2].u := 1.0;
  g_Vertices[2].v := 0.0;
  g_Vertices[3].x := Width * 0.5;
  g_Vertices[3].y := Height * 0.5;
  g_Vertices[3].z := 0;
  g_Vertices[3].color := dwcolor;
  g_Vertices[3].u := 1.0;
  g_Vertices[3].v := 1.0;
  Angle := fangle * (D3DX_PI / 180.0); //fangle 为平面坐标系旋转角度
  ix := X + (Width * 0.5); //中心点偏移,x,y为平面坐标系坐标点,(GDI+)坐标系
  iy := Y + (Height * 0.5); //中心点偏移
  D3DXMatrixRotationZ(matRot, angle);

  D3DXMatrixTranslation(matMove, ix, iy, 0.0);
  D3DXMatrixMultiply(matWorld, matRot, matMove);
  p_pd3dDevice.SetTextureStageState(0,D3DTSS_ALPHAARG1,D3DTA_DIFFUSE);  
  p_pd3dDevice.SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_TEXTURE);
  p_pd3dDevice.SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
  p_pd3dDevice.SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
  p_pd3dDevice.SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
  pd3dDevice.SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_ANISOTROPIC);
  p_pd3dDevice.SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_ANISOTROPIC);
  p_pd3dDevice.SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_ANISOTROPIC);
  p_pd3dDevice.SetTransform(D3DTS_WORLD, matWorld); //设置世界矩阵
  p_pd3dDevice.SetTexture(0, p_texture); // 设置纹理
  p_pd3dDevice.SetFVF(D3DFVF_XYZ or D3DFVF_DIFFUSE or D3DFVF_TEX1);
  p_pd3dDevice.DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, g_Vertices, sizeof(TCustomVERTEX));
end;

作者: mdejtod   发布时间: 2011-08-29

D3DXCreateTextureFromFileEx(p_pD3DDevice, PAnsiChar(fname), D3DX_DEFAULT, D3DX_DEFAULT, 1, 0, D3DFMT_UNKNOWN,
  D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT, 0, @info, nil, p_texture);
创建纹理

作者: mdejtod   发布时间: 2011-08-29

热门下载

更多