Конференция "Игры" » Как создавать Meshes через буфер вершин?
 
  • dr_creigan (13.10.07 13:04) [0]
    Как создавать Meshes через буфер вершин - можно полный исходник.
    подойдут любые среды, кроме Visual C++ MFC - она у меня при переводе не прокатила. - у меня directX 9.0 SDK, если что.
  • Elec3C © (13.10.07 13:17) [1]
    unit DXMGPlayer;

    interface

    uses
    windows,Math,Direct3D8;

    const
    D3DFVF_CUSTOMVERTEX = D3DFVF_XYZ or D3DFVF_DIFFUSE;

    type    //Базовые и общие типы
           //n 004
     D3DFloat = Single;

     PD3DCustomVertex = ^ TD3DCustomVertex;
     TD3DCustomVertex = packed record
       X, Y, Z : D3DFloat;
       Color : DWORD;
     end;

     D3DInt = Integer;
     WRDType = Word;
     D3DBoolean = ByteBool;
     ICustomDirect3D = IDirect3D8;
     ICustomDirect3DDevice = IDirect3DDevice8;
     ICustomDirect3DVertexBuffer = IDirect3DVertexBuffer8;
          //k 004
    type
          //n 005 нужные типы
     PD3D = ^ICustomDirect3D ;
     PD3DDevice= ^ ICustomDirect3DDevice;
     PD3DVertexBuffer = ^ ICustomDirect3DVertexBuffer;

     TD3DVertex=TD3DCustomVertex;
     PD3DVertex=^ TD3DVertex;

     TD3DVector = array[0..2] of D3DFloat;
     PD3DVector = ^TD3DVector;

     TD3DFace = array[0..2] of D3DInt;
     PD3DFace = ^TD3DFace;

     TD3DVertexArray = array[WRDType] of TD3DVertex;
     PD3DVertexArray = ^TD3DVertexArray;

     TD3DFacesArray = array[WRDType] of TD3DFace;
     PD3DFacesArray = ^TD3DFacesArray;
          //k 005
     TD3DMesh = class
       Vertices : PD3DVertexArray; // Массив вершин
       Faces : PD3DFacesArray;   // Массив граней
       FasetNormals : PD3DVertexArray; // Массив фасетных нормалей
       SmoothNormals : PD3DVertexArray; // Массив сглаживающих нормалей
       VertexCount : Integer;  // Число вершин
       FacesCount : Integer;   // Число граней
       FExtent : D3DFloat;      // Масштабный коэффициент
       Extent : D3DBoolean;     // Флаг масштабирования
       D3DVB : ICustomDirect3DVertexBuffer;
      public
       DefaultColor : DWORD;
       D3D : PD3D;
       D3DDevice : PD3DDevice;
       procedure LoadFromFile( const FileName : String );
       procedure CalcNormals;
       procedure Draw(Smooth : Boolean);
       procedure InitVertexBuffer;
       destructor Destroy; override;
     end;

    implementation

    uses Unit1;

    { TD3DMesh }
    var
    x:D3DFloat;

    procedure TD3DMesh.CalcNormals;
    var
     i : Integer;
     wrki, vx1, vy1, vz1, vx2, vy2, vz2 : D3DFloat;
     nx, ny, nz : D3DFloat;
     wrkVector : TD3DVertex;
     wrkVector1, wrkVector2, wrkVector3 : TD3DVertex;
     wrkFace : TD3DFace;
    begin
     For i := 0 to FacesCount - 1 do begin
        wrkFace := Faces[i];
        wrkVector1 := Vertices[wrkFace[0]];
        wrkVector2 := Vertices[wrkFace[1]];
        wrkVector3 := Vertices[wrkFace[2]];

        vx1 := wrkVector1.x - wrkVector2.x;
        vy1 := wrkVector1.y - wrkVector2.y;
        vz1 := wrkVector1.z*fExtent - wrkVector2.z*fExtent;

        vx2 := wrkVector2.x - wrkVector3.x;
        vy2 := wrkVector2.y - wrkVector3.y;
        vz2 := wrkVector2.z - wrkVector3.z;
        // вектор перпендикулярен центру треугольника
        nx := vy1 * vz2 - vz1 * vy2;
        ny := vz1 * vx2 - vx1 * vz2;
        nz := vx1 * vy2 - vy1 * vx2;
        // получаем унитарный вектор единичной длины
        wrki := sqrt (nx * nx + ny * ny + nz * nz);
        If wrki = 0 then wrki := 1; // для предотвращения деления на ноль

        wrkVector.x := nx / wrki;
        wrkVector.y := ny / wrki;
        wrkVector.z := nz / wrki;

        FasetNormals[i] := wrkVector;
     end;
    end;

    destructor TD3DMesh.Destroy;
    begin
     if not (D3DVB = nil) then
      begin
       D3DVB._Release;
       D3DVB:=nil;
      end
                      else
      D3DVB:=nil;
     inherited;
    end;

    procedure TD3DMesh.Draw(Smooth: Boolean);//рисование
    begin  //n 006
      D3DDevice.DrawPrimitive(D3DPT_TRIANGLELIST,0,FacesCount);
    end; //k 006

    procedure TD3DMesh.InitVertexBuffer;
    var
      Face : TD3DFace;
      i : Integer;
      aVerticesArray : PD3DVertexArray;
      VerArr : ^ TD3DCustomVertex;
      h:HRESULT;
    begin
      D3DVB:=nil;
      {GetMem(aVerticesArray,FacesCount*sizeof(TD3DCustomVertex));
      for i:=0 to FacesCount-1 do
       begin
        Face:=Faces[i];
        aVerticesArray[i].X:=vertices[Face[0]].X;
        aVerticesArray[i].Y:=vertices[Face[0]].y;
        aVerticesArray[i].Z:=vertices[Face[0]].z;
        aVerticesArray[i].Color:=DefaultColor;

        aVerticesArray[i].X:=vertices[Face[1]].X;
        aVerticesArray[i].Y:=vertices[Face[1]].y;
        aVerticesArray[i].Z:=vertices[Face[1]].z;
        aVerticesArray[i].Color:=DefaultColor;

        aVerticesArray[i].X:=vertices[Face[2]].X;
        aVerticesArray[i].Y:=vertices[Face[2]].y;
        aVerticesArray[i].Z:=vertices[Face[2]].z;
        aVerticesArray[i].Color:=DefaultColor;
       end;  }
      h:=D3DDevice.CreateVertexBuffer(FacesCount*sizeof(TD3DCustomVertex),D3DUSAGE_WRI TEONLY,
           D3DFVF_CUSTOMVERTEX,D3DPOOL_DEFAULT,D3DVB);
      D3DDevice.SetStreamSource(1,D3DVB,sizeof(TD3DCustomVertex));
      D3DDevice.SetVertexShader(D3DFVF_CUSTOMVERTEX);
      D3DVB.Lock(0,FacesCount*sizeof(TD3DCustomVertex),pbyte(VerArr),0);
      //Move(aVerticesArray,VerArr^,sizeof(aVerticesArray));
      for i:=0 to FacesCount-1 do
       begin
        verArr.X:=-1;
        VerArr.Y:=1;
        VerArr.Z:=0;
        VerArr.Color:=DefaultColor;
        Inc(VerArr);
        {Face:=Faces[i];
        VerArr.X:=vertices[Face[0]].X;
        VerArr.Y:=vertices[Face[0]].y;
        VerArr.Z:=vertices[Face[0]].z;
        VerArr.Color:=DefaultColor;
        Inc(VerArr);

        VerArr.X:=vertices[Face[1]].X;
        VerArr.Y:=vertices[Face[1]].y;
        VerArr.Z:=vertices[Face[1]].z;
        VerArr.Color:=DefaultColor;
        Inc(VerArr);

        VerArr.X:=vertices[Face[1]].X;
        VerArr.Y:=vertices[Face[1]].y;
        VerArr.Z:=vertices[Face[1]].z;
        VerArr.Color:=DefaultColor;
        Inc(VerArr);    }
       end;  
      D3DVB.Unlock;
    end;
  • ElectriC (13.10.07 13:18) [2]
    procedure TD3DMesh.LoadFromFile;
    var
      f : TextFile;
      S : String;
      i : Integer;
      Vertex : TD3DVertex;
      Normal : TD3DVertex;
      SNormal : TD3DVertex;
      Face : TD3DFace;
      MaxVertex : D3DFloat;
    begin        //n 001
      {FacesCount:=1;
      GetMem(Vertices,3*SizeOf(TD3DVertex));
      GetMem(Faces,1*SizeOf(TD3DVector));
      Vertices[0].X:=0;
      Vertices[0].y:=0;
      Vertices[0].z:=1;
      Vertices[0].Color:=DefaultColor;
      Vertices[1].X:=0;
      Vertices[1].y:=0;
      Vertices[1].z:=-1.5;
      Vertices[1].Color:=DefaultColor;
      Vertices[2].X:=0;
      Vertices[2].y:=0;
      Vertices[2].z:=-1.5;
      Vertices[2].Color:=DefaultColor;
      Face[0]:=0;
      Face[1]:=1;
      Face[2]:=2;
      Faces[0]:=Face;
      FExtent:=0.7;      }
      AssignFile(f,FileName);
      Reset(f);
      repeat
        ReadLn(f, S);
      until (S = 'numverts numfaces') or eof(f);
      Readln(f,VertexCount,FacesCount);   // Читаем количество вершин и граней
      GetMem(Vertices,VertexCount*SizeOf(TD3DVertex)); // Выделяем память для хранения сетки
      GetMem(SmoothNormals,VertexCount*SizeOf(TD3DVector));
      GetMem(Faces,FacesCount*SizeOf(TD3DFace));
      GetMem(FasetNormals,FacesCount*SizeOf(TD3DVector));

      ReadLn(f, S); // Пропускаем строку Mesh vertices:
      for i := 0 to VertexCount - 1 do    // Считываем вершины
        begin
          Readln(f,Vertex.x,Vertex.y,Vertex.z);
          Vertices[i] := Vertex;
        end;

      ReadLn(f, S); // Пропустим строку end vertices
      ReadLn(f, S); // Пропустим строку Mesh faces:
      for i := 0 to FacesCount - 1 do     // Считываем грани
        begin
          Readln(f,Face[0],Face[1],Face[2]);
          Face[0] := Face[0] - 1;
          Face[1] := Face[1] - 1;
          Face[2] := Face[2] - 1;
          Faces[i] := Face;
        end;

      ReadLn(f, S); // Пропустим строку end faces
      ReadLn(f, S); // Пропустим строку Faset normals:
      // фасетные нормали
      for i := 0 to FacesCount - 1 do
        begin
          Readln(f,Normal.x,Normal.y,Normal.z);
          FasetNormals[i] := Normal;
        end;

      ReadLn(f, S); // Пропустим строку end faset normals
      ReadLn(f, S); // Пропустим строку Smooth normals:
      // Считываем сглаживающие нормали
      for i := 0 to VertexCount - 1 do
        begin
          Readln(f,SNormal.x,SNormal.y,SNormal.z);
          SmoothNormals[i] := SNormal;
        end;

      CloseFile(f);

      // Рассчитываем масштаб
      MaxVertex := 0;
      for i := 0 to VertexCount - 1 do
        begin
          MaxVertex := Max(MaxVertex,Vertices[i].x);
          MaxVertex := Max(MaxVertex,Vertices[i].y);
          MaxVertex := Max(MaxVertex,Vertices[i].z);
        end;
      fExtent := 1/MaxVertex;  

      //CalcNormals;
    end;   //k 001

    end.

    P.S. Перевод на DX9 не займёт никакой сложности.
  • ElectriC (13.10.07 13:21) [3]
    Пример модели: http://slil.ru/24973625
  • dr_creigan (15.10.07 10:21) [4]
    Всё бы ничего, да только повторю У МЕНЯ DirectX9.0 SDK. И строка
    D3DDevice.SetVertexShader(D3DFVF_CUSTOMVERTEX);
    там по другому. Я пробовал на 8 писать - там всё нормально, а вот на девятом SetVertexShader имеет 2 параметра. первый DWORD, второй - сам Shader, из которого загружать. Так что думайте....
  • Help (15.10.07 19:01) [5]

    >  Так что думайте....

    Я за тебя ещё и думать должен! Думай-ка лучше сам:\ Тебе ж надо!
  • Elec3C © (15.10.07 19:02) [6]
    :\
  • dr_creigan (17.10.07 11:53) [7]
    Нет, ну если не получается, то по-моему лучше посоветоваться со знающими. А то что не получается по переводу из Directx8.0 в DirectX9.0, - это уже не от меня зависит - так уж была оформлена девятая часть директа...
  • Elec3C © (17.10.07 15:23) [8]
    Перевести я могу, но не буду)) Подумай лучше - перевести оч легко.
  • dr_creigan (19.10.07 12:52) [9]
    Удалено модератором
  • Elec3C © (19.10.07 18:13) [10]
    Удалено модератором
  • dr_creigan (27.10.07 08:55) [11]
    Удалено модератором
  • Мистер Т (27.10.07 08:57) [12]
    В DirectX SDK все написано.
    Так что RTFM
  • Elec3C © (28.10.07 02:50) [13]
    Удалено модератором
  • dr_creigan (15.11.07 14:55) [14]
    Удалено модератором
  • @!!ex © (15.11.07 15:42) [15]
    Удалено модератором
  • Игорь Шевченко © (16.11.07 11:34) [16]
    Напоминаю, что бан неизбежен, как кризис империализма.
 
Конференция "Игры" » Как создавать Meshes через буфер вершин?
Есть новые Нет новых   [134431   +10][b:0][p:0.001]