很早实现的了,也就是针对CAMERA的运动做出相应的运动而已,难度不大,代码如下:

Type

  PVRBillBoardVertexInfo = ^TVRBillBoardVertexInfo;

  TVRBillBoard = class( TInterfacedObject,IVRBillBoard )
  private
    Model : IVRModelObject;
    VertexInfo :array[0..3] of  TVRBillBoardVertexInfo;
    Width,Height : Single;
    Position : TPoint3;//位置
    Camera : IVRCamera;
    N : TD3DVector;
    Matrix : TD3DMatrix;
    procedure InitVertex; //初步是对于Y轴垂直,并且以Z轴负方向为N坐标
    procedure Update;//根据CAMERA来判断方向,是否要对应
  public
    function Init(const Info : TVRBillBoardInfo;const Camera : IVRCamera) : Boolean;
    procedure UnInit;
    function GetTexture(): IVRTexture;
    procedure Render;
   
    Constructor Create;
    Destructor Destroy();override;
  end;

implementation

{ TVRBillBoard }

constructor TVRBillBoard.Create;
begin

end;

destructor TVRBillBoard.Destroy;
begin
  UnInit;
  inherited;
end;

function TVRBillBoard.GetTexture: IVRTexture;
begin
  Result := Model.GetTexture(0); 
end;

function TVRBillBoard.Init(const Info: TVRBillBoardInfo;const Camera : IVRCamera): Boolean;
var
  Buf : Pchar;
  Material : IVRMaterial;
  Texture : IVRTexture; //暂时只支持一重纹理
begin
   result := false;
   if Camera = nil then exit;
   Model := TVRModelObject.Create;
   Texture := TVRTexture.Create;

   //模型文件初始化
   if Model.Init(2,4,BillBoardFVF) = false then exit;

   if Texture.Init( Info.TextureInfo ) = false then exit;

   Position:=Info.Position;
   Width := Info.Width;
   Height := Info.Height;
   Self.Camera := Camera;
  
  
   InitVertex;  //初始化各顶点


   Buf := Model.LockVertexBuffer;
   if Buf = nil then exit;
   PVRBillBoardVertexInfo(buf)^:= VertexInfo[0];
   PVRBillBoardVertexInfo(buf+sizeof(TVRBillBoardVertexInfo))^:=VertexInfo[1];
   PVRBillBoardVertexInfo(buf+sizeof(TVRBillBoardVertexInfo)*2)^:=VertexInfo[2];
   PVRBillBoardVertexInfo(buf+sizeof(TVRBillBoardVertexInfo)*3)^:=VertexInfo[3];
   Model.UnLockVertexBuffer;

   Buf := Pchar( Model.LockIndexBuffer );
   if Buf = nil then exit;
   PWord(Buf)^:=0;
   PWord(Buf + sizeof(Word))^:=3;
   PWord(Buf+ sizeof(Word)*2)^:=1;
   PWord(Buf+ sizeof(Word)*3)^:=3;
   PWord(Buf+ sizeof(Word)*4)^:=2;
   PWord(Buf+ sizeof(Word)*5)^:=1;
   Model.UnLockIndexBuffer;

   buf:=Pchar( Model.LockAttriBuffer );
   if buf = nil then exit;
   PDWord(Buf)^:=0;
   PDWord(Buf + sizeof(DWORD))^:=0;
   Model.UnLockAttriBuffer;

   Model.optimizeInPlace;

   Material := TVRMaterial.Create;
   Model.AddMaterial(0,Material);//肯定就一个纹理
 
   Material := nil;
   //======================================
  
   Model.AddTexture(0,Texture);
   Texture := nil;

   Result := true;


end;

 

procedure TVRBillBoard.InitVertex;
var
  L,T : Single;
begin
 // D3DX9.D3DXPlaneFromPointNormal( )
  L := Width / 2;
  T := Height / 2 ;
  VertexInfo[0].Vertex := Point3( Position.x - L, Position.y + T,Position.z );
  VertexInfo[1].Vertex := Point3( Position.x - L, Position.y - T,Position.z );
  VertexInfo[2].Vertex := Point3( Position.x + L, Position.y - T,Position.z );
  VertexInfo[3].Vertex := Point3( Position.x + L, Position.y + T,Position.z );

  VertexInfo[0].Texture := Point2( 0.0,0.0 );
  VertexInfo[1].Texture := Point2(0.0,1.0);
  VertexInfo[2].Texture := Point2(1.0,1.0);
  VertexInfo[3].Texture := Point2(1.0,0.0);

  N:=D3DX9.D3DXVector3(0,0,-1);//暂时这样
end;

procedure TVRBillBoard.Render;
begin
  if Model <> nil then
  begin
    Update;
    Model.Render;
  end;
end;

procedure TVRBillBoard.UnInit;
begin
  Model := nil;
  Camera := nil;
end;

procedure TVRBillBoard.Update;
var
  Cross,Default : TD3DVector;
  Angle : Single;
  m : TD3DMatrix;
begin
  if Camera = nil then exit;
  if Model = nil then exit;

  Cross := Camera.GetUpRightCross;
  N.x := -Cross.x;
  N.y := -Cross.y;
  N.z := -Cross.z;
  Default := D3DX9.D3DXVector3(0,0,-1); //暂时这样
  D3DX9.D3DXMatrixIdentity(Matrix);

  Angle:=D3DX9.D3DXVec3Dot(N,Default);


  //if Angle <= 0 then exit;

  Angle:=Math.ArcCos(Angle);
  D3DX9.D3DXVec3Cross(Cross,Default,N);
  if (Cross.x*Camera.getUp.x>=0) and (Cross.y*Camera.getUp.y>=0) and (Cross.z*Camera.getUp.z>=0) then
  begin
    D3DX9.D3DXMatrixRotationAxis( Matrix,VRCommon.Point3ToVector(Camera.getUp),Angle);
  end
  else
  begin
    D3DX9.D3DXMatrixRotationAxis( Matrix,VRCommon.Point3ToVector(Camera.getUp),-Angle);
  end;
  D3DX9.D3DXMatrixTranslation(m,Position.x,Position.y,Position.z);
  D3DX9.D3DXMatrixMultiply(Matrix,Matrix,m);
  Model.SetMatrix(Matrix);
end;