JLI Spieleprogrammierung Foren-Übersicht JLI Spieleprogrammierung

 
 FAQFAQ   SuchenSuchen   MitgliederlisteMitgliederliste   BenutzergruppenBenutzergruppen 
 medals.php?sid=278981d40eda8eb884ffbc15169fed8eMedaillen   RegistrierenRegistrieren   ProfilProfil   Einloggen, um private Nachrichten zu lesenEinloggen, um private Nachrichten zu lesen   LoginLogin 

FVF: Vertexstruktur automatisieren

 
Neues Thema eröffnen   Neue Antwort erstellen    JLI Spieleprogrammierung Foren-Übersicht -> DirectX, OpenGL
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen  
Autor Nachricht
gombolo
Mini JLI'ler



Anmeldedatum: 25.11.2006
Beiträge: 8

Medaillen: Keine

BeitragVerfasst am: 19.10.2007, 20:08    Titel: FVF: Vertexstruktur automatisieren Antworten mit Zitat

-Habt ihr euch schon mal Gedanken gemacht wie man die Wahl der Struktur welche die Vertexinformationen speichert automatisieren kann?

-Braucht man eigentlich noch diese Strukturen wenn man doch Vertexshader hat?

API: DirectX
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Dr. Best
Senior JLI'ler


Alter: 34
Anmeldedatum: 17.06.2004
Beiträge: 269
Wohnort: Köln
Medaillen: Keine

BeitragVerfasst am: 19.10.2007, 22:13    Titel: Antworten mit Zitat

Gedanken? Ja. Und noch einiges mehr Very Happy . In meiner Engine habe ich eine Struktur für Vertexformate. Allerdings nicht mit FVF sondern mit DWORD Declarations. Für FVF lohnt es nicht, die sind einfach so simpel, dass man das mit einigen if-statements oder Schleifen schnell geregelt hat. Meine Struktur hat viele verschiedene Konstruktoren, um komfortabel Vertexformate verschiedener Komplexität zu generieren. Außerdem hat sie als Membervariablen ein Feld von DWORDs in die das generierte Vertexformat gespeichert wird und ein paar Membervariablen mit Zusatzinformationen. Hier ist einfach mal der Code dazu. Denn ich kann noch so viel reden, der Code sagt mehr Laughing .
CPP:
// This structure saves a vertex shader declaration. It has several constructors for
// commonly used vertex shader declarations.
struct SVSDeclaration{
   // The default constructor creates a declaration with position, normal and one
   // 2D texture coordinate set, all of them in stream 0
   inline SVSDeclaration(){
      pDwordDeclaration[0]=D3DVSD_STREAM(0);
      pDwordDeclaration[1]=D3DVSD_REG(D3DVSDE_POSITION,D3DVSDT_FLOAT3);
      pDwordDeclaration[2]=D3DVSD_REG(D3DVSDE_NORMAL,D3DVSDT_FLOAT3);
      pDwordDeclaration[3]=D3DVSD_REG(D3DVSDE_TEXCOORD0,D3DVSDT_FLOAT2);
      pDwordDeclaration[4]=D3DVSD_END();
      ContainsWeights=false;
      SoftwareVP=false;
   }

   // This constructor creates a declaration with position, possibly a normal and a
   // 2D texture coordinate set
   SVSDeclaration(bool Normal){
      pDwordDeclaration[0]=D3DVSD_STREAM(0);
      pDwordDeclaration[1]=D3DVSD_REG(D3DVSDE_POSITION,D3DVSDT_FLOAT3);
      pDwordDeclaration[2]=D3DVSD_REG(D3DVSDE_NORMAL,D3DVSDT_FLOAT3);
      pDwordDeclaration[2+Normal]=D3DVSD_REG(D3DVSDE_TEXCOORD0,D3DVSDT_FLOAT2);
      pDwordDeclaration[3+Normal]=D3DVSD_END();
      ContainsWeights=false;
      SoftwareVP=false;
   }

   // This constructor creates a declaration with position, a normal if requested and
   // the given multi dimensional texture coordinate sets
   SVSDeclaration(bool Normal,WORD nDimensionTex0,WORD nDimensionTex1,WORD nDimensionTex2,WORD nDimensionTex3,WORD nDimensionTex4,WORD nDimensionTex5,WORD nDimensionTex6,WORD nDimensionTex7){
      WORD pTexCoordDimension[8]={nDimensionTex0,nDimensionTex1,nDimensionTex2,nDimensionTex3,nDimensionTex4,nDimensionTex5,nDimensionTex6,nDimensionTex7};
      pDwordDeclaration[0]=D3DVSD_STREAM(0);
      pDwordDeclaration[1]=D3DVSD_REG(D3DVSDE_POSITION,D3DVSDT_FLOAT3);
      pDwordDeclaration[2]=D3DVSD_REG(D3DVSDE_NORMAL,D3DVSDT_FLOAT3);
      WORD iDestinationRegister=2+Normal;
      for(UINT i=0;i<8;i++){
         if(pTexCoordDimension[i]){
            pDwordDeclaration[iDestinationRegister]=D3DVSD_REG(D3DVSDE_TEXCOORD0+i,pTexCoordDimension[i]-1);
            iDestinationRegister++;
         }
      }
      pDwordDeclaration[iDestinationRegister]=D3DVSD_END();
      ContainsWeights=false;
      SoftwareVP=false;
   }

   // This constructor creates a declaration with position, a normal if requested and
   // the given multi dimensional texture coordinate sets
   SVSDeclaration(bool Normal,const WORD* pTexCoordDimension){
      pDwordDeclaration[0]=D3DVSD_STREAM(0);
      pDwordDeclaration[1]=D3DVSD_REG(D3DVSDE_POSITION,D3DVSDT_FLOAT3);
      pDwordDeclaration[2]=D3DVSD_REG(D3DVSDE_NORMAL,D3DVSDT_FLOAT3);
      WORD iDestinationRegister=2+Normal;
      for(UINT i=0;i<8;i++){
         if(pTexCoordDimension[i]){
            pDwordDeclaration[iDestinationRegister]=D3DVSD_REG(D3DVSDE_TEXCOORD0+i,pTexCoordDimension[i]-1);
            iDestinationRegister++;
         }
      }
      pDwordDeclaration[iDestinationRegister]=D3DVSD_END();
      ContainsWeights=false;
      SoftwareVP=false;
   }

   // This constructor creates a declaration with position, the given number of indexed
   // weights, a normal if requested and the given multi dimensional texture coordinates
   SVSDeclaration(bool Normal,WORD nSkinWeight,bool UseSoftwareVPForWeights,const WORD* pTexCoordDimension){
      pDwordDeclaration[0]=D3DVSD_STREAM(0);
      pDwordDeclaration[1]=D3DVSD_REG(D3DVSDE_POSITION,D3DVSDT_FLOAT3);
      if(nSkinWeight){
         pDwordDeclaration[2]=D3DVSD_REG(D3DVSDE_BLENDWEIGHT,nSkinWeight-1);
         pDwordDeclaration[3]=D3DVSD_REG(D3DVSDE_BLENDINDICES,D3DVSDT_UBYTE4);
      }
      pDwordDeclaration[2+(nSkinWeight!=0)*2]=D3DVSD_REG(D3DVSDE_NORMAL,D3DVSDT_FLOAT3);
      WORD iDestinationRegister=2+Normal+2*(nSkinWeight!=0);
      for(UINT i=0;i<8;i++){
         if(pTexCoordDimension[i]){
            pDwordDeclaration[iDestinationRegister]=D3DVSD_REG(D3DVSDE_TEXCOORD0+i,pTexCoordDimension[i]-1);
            iDestinationRegister++;
         }
      }
      pDwordDeclaration[iDestinationRegister]=D3DVSD_END();
      ContainsWeights=nSkinWeight!=0;
      SoftwareVP=ContainsWeights && UseSoftwareVPForWeights;
   }

   // This constructor creates a declaration for a tweening shader with positions and
   // normals in stream 0 and 1 and multi dimensional texture coordiantes in the given
   // stage
   SVSDeclaration(const WORD* pTexCoordDimension,WORD TextureCoordinateStage){
      WORD nTextureCoordinate=0;
      for(UINT i=0;i<8;i++){
         nTextureCoordinate+=pTexCoordDimension[i]!=0;
      }
      pDwordDeclaration[0]=D3DVSD_STREAM(0);
      pDwordDeclaration[1]=D3DVSD_REG(D3DVSDE_POSITION,D3DVSDT_FLOAT3);
      pDwordDeclaration[2]=D3DVSD_REG(D3DVSDE_NORMAL,D3DVSDT_FLOAT3);
      WORD iDestinationRegister=3;
      WORD iTexCoordDestination=0;
      if(TextureCoordinateStage==0){
         iTexCoordDestination=iDestinationRegister;
         iDestinationRegister+=nTextureCoordinate;
      }
      pDwordDeclaration[iDestinationRegister+0]=D3DVSD_STREAM(1);
      pDwordDeclaration[iDestinationRegister+1]=D3DVSD_REG(D3DVSDE_BLENDWEIGHT,D3DVSDT_FLOAT3);
      pDwordDeclaration[iDestinationRegister+2]=D3DVSD_REG(D3DVSDE_BLENDINDICES,D3DVSDT_FLOAT3);
      iDestinationRegister+=3;
      if(TextureCoordinateStage==1){
         iTexCoordDestination=iDestinationRegister;
         iDestinationRegister+=nTextureCoordinate;
      }
      if(iTexCoordDestination==0){
         pDwordDeclaration[iDestinationRegister]=D3DVSD_STREAM(TextureCoordinateStage);
         iDestinationRegister+=1;
         iTexCoordDestination=iDestinationRegister;
         iDestinationRegister+=nTextureCoordinate;
      }
      pDwordDeclaration[iDestinationRegister]=D3DVSD_END();
      iDestinationRegister=iTexCoordDestination;
      for(UINT i=0;i<8;i++){
         if(pTexCoordDimension[i]){
            pDwordDeclaration[iDestinationRegister]=D3DVSD_REG(D3DVSDE_TEXCOORD0+i,pTexCoordDimension[i]-1);
            iDestinationRegister++;
         }
      }
      ContainsWeights=false;
      SoftwareVP=false;
   }

   // This constructor initializes this vertex shader declaration from a complete DWORD
   // declaration
   SVSDeclaration(const DWORD* pDwDeclaration,bool UseSoftwareVPForWeights){
      ContainsWeights=false;
      // Search for the end of the declaration, copy it and determine whether it
      // contains weights
      WORD oDwDeclaration=0;
      do{
         ContainsWeights=ContainsWeights || pDwDeclaration[oDwDeclaration]==D3DVSD_REG(D3DVSDE_BLENDINDICES,D3DVSDT_UBYTE4);
         pDwordDeclaration[oDwDeclaration]=pDwDeclaration[oDwDeclaration];
         oDwDeclaration++;
      } while(pDwDeclaration[oDwDeclaration-1]!=D3DVSD_END() && oDwDeclaration<32);
      if(oDwDeclaration>=32){
         Error("Too long DWORD declaration passed to a constructor of SVSDeclaration.");
      }
      SoftwareVP=ContainsWeights && UseSoftwareVPForWeights;
   }

   // The comparsion operator returns true if the DWORD declarations are equal until
   // the end and the boolean values are the same
   bool operator== (const SVSDeclaration& rRHS) const{
      WORD oDwDeclaration=0;
      bool Equal=true;
      do{
         if(rRHS.pDwordDeclaration[oDwDeclaration]!=pDwordDeclaration[oDwDeclaration]){
            Equal=false;
            break;
         }
         oDwDeclaration++;
      } while(rRHS.pDwordDeclaration[oDwDeclaration-1]!=D3DVSD_END() && pDwordDeclaration[oDwDeclaration-1]!=D3DVSD_END() && oDwDeclaration<32);
      return ContainsWeights==rRHS.ContainsWeights && SoftwareVP==rRHS.SoftwareVP && Equal;
   }

   DWORD pDwordDeclaration[32];
   bool ContainsWeights;
   bool SoftwareVP;
};

_________________

Ich bin da, wer noch?
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen AIM-Name MSN Messenger
Fallen
JLI MVP
JLI MVP


Alter: 40
Anmeldedatum: 08.03.2003
Beiträge: 2860
Wohnort: Münster
Medaillen: 1 (mehr...)

BeitragVerfasst am: 19.10.2007, 22:15    Titel: Antworten mit Zitat

FVF sind die alte Variante vertexstrukturen zu beschreiben die neuere sind VertesDeclarations:

Zitat:
A FVF code describes the contents of vertices stored interleaved in a single data stream. It generally specifies data to be processed by the fixed function vertex processing pipeline. This is an older-style vertex declaration; to see the current vertex declaration style, see D3DVERTEXELEMENT9.


http://msdn2.microsoft.com/en-us/library/bb206335.aspx

Und der vertexshader braucht diese Informationen um zu wissen was ein Positionswert, Texturkoordinate, Farbe, etc. ist.

Habt ihr euch schon mal Gedanken gemacht wie man die Wahl der Struktur welche die Vertexinformationen speichert automatisieren kann?

Ja dies ist sogar recht einfach:

Zuerst erstelle ich mir eine InfoStruktur für das vertexformat, dies sieht ungefähr so aus:

Zu beachten ist hier das die einzelnen Werte bestimmt geordnet sein sollte da es sonst bei bestimmten Rechnerkonfigurationen zu Problemen kommen könnte, näheres dazu kannst du den FVF Spezifikationen entnehmen (Position, Normal, PrimaryColor, SecondaryColor, Texturecoordinates, sollte AFAIk die grundlegende Ordnung sein).

CPP:
// ganz simpel
struct r_VertexInfo
{
  r_VertexInfo()
    : mi_Size(0)
    , mi_PositionOffset(-1)
    , mi_NormalOffset(-1)
    , mi_ColorOffset(-1)
  {
    for (int i=0; i<max_texturecoordinates; ++i)
      mi_TextureCoordinateOffset[i] = -1;
  }

  int mi_Size;
  int mi_PositionOffset;
  int mi_NormalOffset;
  int mi_ColorOffset;
  int mi_TextureCoordinateOffset[max_texturecoordinates];
};


Bei dir im Code kannst du dann die Struktur ganz einfach füllen und die Offsetdaten relativ einfach bei dem auffüllen der Vertexdclarations benutzen:

CPP:
#define OffsetOf(type, element) (size_t)(unsigned long)&(((type *)0)->element)

...

struct r_Vertex
{
  float mf_Position[3]; //x,y,z
  float mf_Normal[3]; //x,y,z
  float mf_Texcoordinate[2]; //u,v
};

...

r_VertexInfo lr_VertexInfo;
lr_VertexInfo.mi_size = sizeof(r_Vertex);
lr_VertexInfo.mi_PositionOffset = OffsetOf(r_Vertex, mf_Position);
lr_VertexInfo.mi_NormalOffset = OffsetOf(r_Vertex, mf_Normal);
lr_VertexInfo.mi_TextureCoordinateOffset[0] = OffsetOf(r_Vertex, mf_Texcoordinate);


Das auffüllen der VertexDeclaration müsstest du anschliessend noch selbst übernehmen:

http://msdn2.microsoft.com/en-us/library/bb147299.aspx

(Habe dazu grade den Code nicht parat, aber komplex war er nicht.)

Edit: Hier mal fix zusammen gebastelt, vermutlich gehts nicht aber so ungefähr könnte es aussehen:

CPP:
LPDIRECT3DVERTEXDECLARATION9 CreateVertexDeclaration(r_VertexInfo& ar_Info)
{
  std::vector<D3DVERTEXELEMENT9> lk_Elements;
  if (ar_Info.mi_PositionOffset >= 0)
  {
    D3DVERTEXELEMENT9 lr_Element = {0, ar_Info.mi_PositionOffset, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0};
    lk_Elements.push_back(lr_Element);
  }
  if (ar_Info.mi_NormalOffset >= 0)
  {
    D3DVERTEXELEMENT9 lr_Element = {0, ar_Info.mi_NormalOffset, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0};
    lk_Elements.push_back(lr_Element);
  }
  ...

  lk_Elements.push_back(D3DDECL_END());

  D3DVERTEXELEMENT9 lr_Decl_ = new D3DVERTEXELEMENT9[lk_Elements.size()];
  for (unsigned int i=0; i<lk_Elements.size(); ++i)
    lr_Decl_[i] = lk_Elements[i];

  LPDIRECT3DVERTEXDECLARATION9 lr_VertexDeclaration_;
  lr_D3DDevice_->CreateVertexDeclaration(lr_Decl_ , lr_VertexDeclaration_);

  delete [] lr_Decl_;

  return lr_VertexDeclaration_;
}

_________________
"I have a Core2Quad at 3.2GHz, 4GB of RAM at 1066 and an Nvidia 8800 GTS 512 on Vista64 and this game runs like ass whereas everything else I own runs like melted butter over a smokin' hot 18 year old catholic schoolgirl's arse."
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen
gombolo
Mini JLI'ler



Anmeldedatum: 25.11.2006
Beiträge: 8

Medaillen: Keine

BeitragVerfasst am: 20.10.2007, 09:10    Titel: Antworten mit Zitat

Oh toll. Das muss ich mir jetzt genauer durchlesen. Danke für die Informationen.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Beiträge der letzten Zeit anzeigen:   
Neues Thema eröffnen   Neue Antwort erstellen    JLI Spieleprogrammierung Foren-Übersicht -> DirectX, OpenGL Alle Zeiten sind GMT
Seite 1 von 1

 
Gehe zu:  
Du kannst keine Beiträge in dieses Forum schreiben.
Du kannst auf Beiträge in diesem Forum nicht antworten.
Du kannst deine Beiträge in diesem Forum nicht bearbeiten.
Du kannst deine Beiträge in diesem Forum nicht löschen.
Du kannst an Umfragen in diesem Forum nicht mitmachen.


Powered by phpBB © 2001, 2005 phpBB Group
Deutsche Übersetzung von phpBB.de

Impressum