ROAM Algo. in Klasse einbauen???
-
Wie kann ich den ROAM Algorhytus in diese C++ Klasse einbauen (entnommen aus dem Buch: 3D-Spiele mit DirectX und C++ von Alexander Rudolph):
//----------------------------------------------------------------------------- // Klasse für das Handling einer Bodentile //----------------------------------------------------------------------------- class CGroundTile { public: // Nummern der verwendeten Texturen: long TexturNummer; long DetailTexturNummer; long HeightMapTexturNummer; // Variablen, die für die Beschreibung des Tiles benötigt // werden: float RangeX; // Tile-Ausdehnung float Half_RangeX; // halbe Tile-Ausdehnung float DifferenzX; // ... zweier Vertices float Differenz_normiertX; // ... zweier Vertices bezogen auf eine Tile-Ausdehnung von 1 float RangeZ; // Tile-Ausdehnung float Half_RangeZ; // halbe Tile-Ausdehnung float DifferenzZ; // ... zweier Vertices float Differenz_normiertZ; // ... zweier Vertices bezogen auf eine Tile-Ausdehnung von 1 float x_min, x_max; // Koordinaten der float z_min, z_max; // Tile-Eckpunkte BOOL Player_above_Tile; // Variablen für den BOOL visible; // Sichtbarkeitstest // Variablen, die für die Erstellung von Vertex- und Indexbuffer // benötigt werden: long AnzVerticesZeile; long AnzVerticesSpalte; long AnzVertices; long AnzTriangles; long AnzQuads; long AnzIndices; // Variablen, die für die Bestimmung der Terrainhöhe benötigt // werden: long IndexX; //Indices desjenigen Quads auf long IndexZ; //dem sich der Spieler befindet long Triangle1Nr; // Nummern der zum Quad long Triangle2Nr; // gehörigen Dreiecke long QuadNr; // Nummer des Quads // Ortsvektoren des Tiles: D3DXVECTOR3 TilePosition; D3DXVECTOR3 TilePositionUpperLeft; D3DXVECTOR3 TilePositionLowerLeft; D3DXVECTOR3 TilePositionUpperRight; D3DXVECTOR3 TilePositionLowerRight; // Array zum Speichern der Tile-Dreiecke; wird für die Berechnung // der Terrainhöhe benötigt: CTriangle* TileTriangle; WORD* IndexArray; INDEXBUFFER TileIB; VERTEXBUFFER TileVB; CGroundTile() { TileTriangle = NULL; IndexArray = NULL; TileVB = NULL; TileIB = NULL; } ~CGroundTile() { SAFE_DELETE_ARRAY(TileTriangle) SAFE_DELETE_ARRAY(IndexArray) SAFE_RELEASE(TileVB) SAFE_RELEASE(TileIB) } void Init_Tile(D3DXVECTOR3* pPosition, long anzVerticesZeile, long anzVerticesSpalte, float DetailFactorX, float DetailFactorZ, float rangeX, float rangeZ, float heightscale, long texturNummer, long detailTexturNummer, long heightMapTexturNummer) { long i; TilePosition = *pPosition; TexturNummer = texturNummer; DetailTexturNummer = detailTexturNummer; HeightMapTexturNummer = heightMapTexturNummer; AnzVerticesZeile = anzVerticesZeile; AnzVerticesSpalte = anzVerticesSpalte; RangeX = rangeX; Half_RangeX = 0.5f*RangeX; DifferenzX = RangeX/(AnzVerticesZeile-1); Differenz_normiertX = 1.0f/(AnzVerticesZeile-1); RangeZ = rangeZ; Half_RangeZ = 0.5f*RangeZ; DifferenzZ = RangeZ/(AnzVerticesSpalte-1); Differenz_normiertZ = 1.0f/(AnzVerticesSpalte-1); x_min = TilePosition.x - Half_RangeX; x_max = TilePosition.x + Half_RangeX; z_min = TilePosition.z - Half_RangeZ; z_max = TilePosition.z + Half_RangeZ; TilePositionUpperLeft = D3DXVECTOR3(x_min, 0.0f, z_max); TilePositionLowerLeft = D3DXVECTOR3(x_min, 0.0f, z_min); TilePositionUpperRight = D3DXVECTOR3(x_max, 0.0f, z_max); TilePositionLowerRight = D3DXVECTOR3(x_max, 0.0f, z_min); AnzVertices = AnzVerticesZeile*AnzVerticesSpalte; AnzQuads = (AnzVerticesZeile-1)*(AnzVerticesSpalte-1); AnzTriangles = 2*AnzQuads; AnzIndices = 3*AnzTriangles; TileTriangle = new CTriangle[AnzTriangles]; D3DXVECTOR3* TileVertices = new D3DXVECTOR3[AnzVertices]; IndexArray = new WORD[AnzIndices]; long zeile = 1; long spalte = 1; // Indexarray für eine geometrische Grundform erzeugen: for(i = 0; i < AnzQuads; i++) { IndexArray[6*i] = AnzVerticesZeile*zeile + spalte - 1; IndexArray[6*i+1] = AnzVerticesZeile*(zeile-1) + spalte - 1; IndexArray[6*i+2] = AnzVerticesZeile*(zeile-1) +1 + spalte - 1; IndexArray[6*i+3] = AnzVerticesZeile*zeile + spalte - 1; IndexArray[6*i+4] = AnzVerticesZeile*(zeile-1) +1 + spalte - 1; IndexArray[6*i+5] = AnzVerticesZeile*zeile +1 + spalte - 1; spalte++; if(spalte == AnzVerticesZeile) { spalte = 1; zeile++; } } // Indexbuffer erzeugen g_pd3dDevice->CreateIndexBuffer(AnzIndices*sizeof(WORD), D3DUSAGE_WRITEONLY, D3DFMT_INDEX16, D3DPOOL_MANAGED, &TileIB, NULL ); WORD* var = NULL; TileIB->Lock( 0, 0, (VOID**)&var, 0 ); memcpy( var, IndexArray, AnzIndices*sizeof(WORD) ); TileIB->Unlock(); long zeilenNr; long spaltenNr; g_pd3dDevice->CreateVertexBuffer(AnzVertices*sizeof(SPACEOBJEKT3DVERTEX_EX), D3DUSAGE_WRITEONLY, D3DFVF_SPACEOBJEKT3DVERTEX_EX, D3DPOOL_MANAGED, &TileVB, NULL ); SPACEOBJEKT3DVERTEX_EX* pVertices; TileVB->Lock( 0, 0, (VOID**)&pVertices, 0 ); // Eine flache Tile erzeugen: for( zeilenNr = 0; zeilenNr < AnzVerticesSpalte; zeilenNr++) { for( spaltenNr = 0; spaltenNr < AnzVerticesZeile; spaltenNr++) { // Vorläufige Vertexkoordinaten berechnen: pVertices[zeilenNr*AnzVerticesZeile+spaltenNr].position = D3DXVECTOR3(-Half_RangeX + spaltenNr*DifferenzX, 0.0f, Half_RangeZ - zeilenNr*DifferenzZ); pVertices[zeilenNr*AnzVerticesZeile+spaltenNr].position += TilePosition; // Vorläufige Vertexkoordinaten für die Bestimmung der // Gouraudnormalen zwischenspeichern: TileVertices[zeilenNr*AnzVerticesZeile+spaltenNr] = pVertices[zeilenNr*AnzVerticesZeile+spaltenNr].position; // Vorläufigen Normalenvektor festlegen: pVertices[zeilenNr*AnzVerticesZeile+spaltenNr].normal = D3DXVECTOR3(0.0f, 1.0f, 0.0f); // Texturkoordinaten der Tile-Textur festlegen: pVertices[zeilenNr*AnzVerticesZeile+spaltenNr].tu1 = spaltenNr*Differenz_normiertX; pVertices[zeilenNr*AnzVerticesZeile+spaltenNr].tv1 = zeilenNr*Differenz_normiertZ; // Texturkoordinaten der Detailtextur festlegen: pVertices[zeilenNr*AnzVerticesZeile+spaltenNr].tu2 = DetailFactorX*spaltenNr*Differenz_normiertX; pVertices[zeilenNr*AnzVerticesZeile+spaltenNr].tv2 = DetailFactorZ*zeilenNr*Differenz_normiertZ; } } // Höhenwerte hinzufügen (Verwendung einer 1024*1024*24Bit-Heightmap-Textur): D3DLOCKED_RECT d3dlr; TerrainTextures->TileHeightMap[HeightMapTexturNummer].pTexture->LockRect(0, &d3dlr, 0, 0 ); long* pCol = (long*)d3dlr.pBits; long color; unsigned char colorRed; unsigned char colorGreen; unsigned char colorBlue; temp2Long = 1024/(AnzVerticesZeile-2); temp1Long = 1024/(AnzVerticesSpalte-2); //FILE* file; //if((file = fopen("heightmap.txt","w")) == NULL) // Game_Shutdown(); for( zeilenNr = 1; zeilenNr < AnzVerticesSpalte-1; zeilenNr++) { for( spaltenNr = 1; spaltenNr < AnzVerticesZeile-1; spaltenNr++) { color = pCol[zeilenNr*temp1Long*1024+spaltenNr*temp2Long]; colorBlue = (unsigned char)color; colorGreen = (unsigned char)(color >> 8); colorRed = (unsigned char)(color >> 16); //fprintf(file,"%03d, %03d, %03d,\n ", (long)colorRed, (long)colorGreen, (long)colorBlue ); // Endgültige Vertexkoordinaten berechnen: pVertices[zeilenNr*AnzVerticesZeile+spaltenNr].position.y += heightscale*(colorRed+colorGreen+colorBlue); // Endgültige Vertexkoordinaten für die Bestimmung der // Gouraudnormalen zwischenspeichern: TileVertices[zeilenNr*AnzVerticesZeile+spaltenNr] = pVertices[zeilenNr*AnzVerticesZeile+spaltenNr].position; } } //fclose(file); TerrainTextures->TileHeightMap[HeightMapTexturNummer].pTexture->UnlockRect(0); // Berechnung der Gouraudormalen; hierbei werden die 8 benachbarten Vertices // eines jeden Vertex (mit Ausnahme der Randvertices) berücksichtigt. D3DXVECTOR3* tempNormal = new D3DXVECTOR3[8]; D3DXVECTOR3* tempDiffVektor = new D3DXVECTOR3[8]; for( zeilenNr = 1; zeilenNr < AnzVerticesSpalte-1; zeilenNr++) { for( spaltenNr = 1; spaltenNr < AnzVerticesZeile-1; spaltenNr++) { // Berechnung der Differenzvektoren zu den benachbarten Vertices: tempDiffVektor[0] = TileVertices[(zeilenNr-1)*AnzVerticesZeile+spaltenNr-1] - TileVertices[zeilenNr*AnzVerticesZeile+spaltenNr]; tempDiffVektor[1] = TileVertices[(zeilenNr-1)*AnzVerticesZeile+spaltenNr] - TileVertices[zeilenNr*AnzVerticesZeile+spaltenNr]; tempDiffVektor[2] = TileVertices[(zeilenNr-1)*AnzVerticesZeile+spaltenNr+1] - TileVertices[zeilenNr*AnzVerticesZeile+spaltenNr]; tempDiffVektor[3] = TileVertices[zeilenNr*AnzVerticesZeile+spaltenNr-1] - TileVertices[zeilenNr*AnzVerticesZeile+spaltenNr]; tempDiffVektor[4] = TileVertices[zeilenNr*AnzVerticesZeile+spaltenNr+1] - TileVertices[zeilenNr*AnzVerticesZeile+spaltenNr]; tempDiffVektor[5] = TileVertices[(zeilenNr+1)*AnzVerticesZeile+spaltenNr-1] - TileVertices[zeilenNr*AnzVerticesZeile+spaltenNr]; tempDiffVektor[6] = TileVertices[(zeilenNr+1)*AnzVerticesZeile+spaltenNr] - TileVertices[zeilenNr*AnzVerticesZeile+spaltenNr]; tempDiffVektor[7] = TileVertices[(zeilenNr+1)*AnzVerticesZeile+spaltenNr+1] - TileVertices[zeilenNr*AnzVerticesZeile+spaltenNr]; // Berechnung der Vektorprodukte zwischen je 2 benachbarten // Differenzvektoren und Normalisieren der Produktvektoren D3DXVec3Cross(&tempNormal[0], &tempDiffVektor[0], &tempDiffVektor[3]); D3DXVec3Normalize(&tempNormal[0], &tempNormal[0]); D3DXVec3Cross(&tempNormal[1], &tempDiffVektor[3], &tempDiffVektor[5]); D3DXVec3Normalize(&tempNormal[1], &tempNormal[1]); D3DXVec3Cross(&tempNormal[2], &tempDiffVektor[5], &tempDiffVektor[6]); D3DXVec3Normalize(&tempNormal[2], &tempNormal[2]); D3DXVec3Cross(&tempNormal[3], &tempDiffVektor[6], &tempDiffVektor[7]); D3DXVec3Normalize(&tempNormal[3], &tempNormal[3]); D3DXVec3Cross(&tempNormal[4], &tempDiffVektor[7], &tempDiffVektor[4]); D3DXVec3Normalize(&tempNormal[4], &tempNormal[4]); D3DXVec3Cross(&tempNormal[5], &tempDiffVektor[4], &tempDiffVektor[2]); D3DXVec3Normalize(&tempNormal[5], &tempNormal[5]); D3DXVec3Cross(&tempNormal[6], &tempDiffVektor[2], &tempDiffVektor[1]); D3DXVec3Normalize(&tempNormal[6], &tempNormal[6]); D3DXVec3Cross(&tempNormal[7], &tempDiffVektor[1], &tempDiffVektor[0]); D3DXVec3Normalize(&tempNormal[7], &tempNormal[7]); // Mittelwertbildung: pVertices[zeilenNr*AnzVerticesZeile+spaltenNr].normal = -1.0f/8.0f*(tempNormal[0] +tempNormal[1]+tempNormal[2]+tempNormal[3]+tempNormal[4]+tempNormal[5]+tempNormal[6] +tempNormal[7]); } } SAFE_DELETE_ARRAY(tempNormal) SAFE_DELETE_ARRAY(tempDiffVektor) TileVB->Unlock(); // Koordinaten der Tile-Dreiecke für die Höhenbestimmung // in einem CTriangle-Array speichern: for(i = 0; i < AnzTriangles; i++) { TileTriangle[i].Init_Triangle(TileVertices[IndexArray[3*i+0]], TileVertices[IndexArray[3*i+1]], TileVertices[IndexArray[3*i+2]], 1.0f, 1.0f, 1.0f, i); } SAFE_DELETE_ARRAY(IndexArray) SAFE_DELETE_ARRAY(TileVertices) } float Calculate_TileHeight(D3DXVECTOR3* pPosition) { temp1Vektor3 = -TilePosition + *pPosition; // Berechnung der Quad-Indices: IndexX = (long)((temp1Vektor3.x+Half_RangeX)/DifferenzX); IndexZ = (long)((Half_RangeZ-temp1Vektor3.z)/DifferenzZ); // Berechnung der Quad- und Triangle-Nummern: QuadNr = IndexX+IndexZ*(AnzVerticesZeile-1); Triangle1Nr = 2*QuadNr; Triangle2Nr = 2*QuadNr+1; // Berechnung der Terrain-Höhe: if(TileTriangle[Triangle1Nr].Test_for_Ray_Intersection_Terrain(pPosition, &tempFloat) == TRUE) return (pPosition->y-tempFloat); else if(TileTriangle[Triangle2Nr].Test_for_Ray_Intersection_Terrain(pPosition, &tempFloat) == TRUE) return (pPosition->y-tempFloat); else return OldGroundTileHeight; } BOOL Test_if_Player_is_above_Tile(D3DXVECTOR3* pPosition) { if(pPosition->x > x_max || pPosition->x < x_min) { Player_above_Tile = FALSE; return FALSE; } if(pPosition->z > z_max || pPosition->z < z_min) { Player_above_Tile = FALSE; return FALSE; } Player_above_Tile = TRUE; return TRUE; } void Test_Visibility(void) { if(Player_above_Tile == TRUE) // Die Tile unter dem Spieler ist natürlich sichtbar { visible = TRUE; return; } tempVektor3.x = PlayerVerschiebungsvektor.x; tempVektor3.y = 0.0f; tempVektor3.z = PlayerVerschiebungsvektor.z; temp1Vektor3 = TilePosition; temp1Vektor3.y = 0.0f; temp1Vektor3 -= tempVektor3; // Abstandsvektor zum Spieler temp2Float = D3DXVec3Dot(&temp1Vektor3, &PlayerFlugrichtung); if(temp2Float > 0.0f) // Tile vor dem Spieler { temp1Float = D3DXVec3LengthSq(&temp1Vektor3); temp3Float = temp2Float*temp2Float; if(temp3Float > temp1Float*0.35f && temp1Float < SizeOfUniverseSq) { visible = TRUE; return; } } temp1Vektor3 = TilePositionUpperLeft; temp1Vektor3 -= tempVektor3; // Abstandsvektor zum Spieler temp2Float = D3DXVec3Dot(&temp1Vektor3, &PlayerFlugrichtung); if(temp2Float > 0.0f) // Tile vor dem Spieler { temp1Float = D3DXVec3LengthSq(&temp1Vektor3); temp3Float = temp2Float*temp2Float; if(temp3Float > temp1Float*0.35f && temp1Float < SizeOfUniverseSq) { visible = TRUE; return; } } temp1Vektor3 = TilePositionUpperRight; temp1Vektor3 -= tempVektor3; // Abstandsvektor zum Spieler temp2Float = D3DXVec3Dot(&temp1Vektor3, &PlayerFlugrichtung); if(temp2Float > 0.0f) // Tile vor dem Spieler { temp1Float = D3DXVec3LengthSq(&temp1Vektor3); temp3Float = temp2Float*temp2Float; if(temp3Float > temp1Float*0.35f && temp1Float < SizeOfUniverseSq) { visible = TRUE; return; } } temp1Vektor3 = TilePositionLowerLeft; temp1Vektor3 -= tempVektor3; // Abstandsvektor zum Spieler temp2Float = D3DXVec3Dot(&temp1Vektor3, &PlayerFlugrichtung); if(temp2Float > 0.0f) // Tile vor dem Spieler { temp1Float = D3DXVec3LengthSq(&temp1Vektor3); temp3Float = temp2Float*temp2Float; if(temp3Float > temp1Float*0.35f && temp1Float < SizeOfUniverseSq) { visible = TRUE; return; } } temp1Vektor3 = TilePositionLowerRight; temp1Vektor3 -= tempVektor3; // Abstandsvektor zum Spieler temp2Float = D3DXVec3Dot(&temp1Vektor3, &PlayerFlugrichtung); if(temp2Float > 0.0f) // Tile vor dem Spieler { temp1Float = D3DXVec3LengthSq(&temp1Vektor3); temp3Float = temp2Float*temp2Float; if(temp3Float > temp1Float*0.35f && temp1Float < SizeOfUniverseSq) { visible = TRUE; return; } } visible = FALSE; } void Render_Tile(void) { if(visible == FALSE) { Player_above_Tile = FALSE; return; } Player_above_Tile = FALSE; ZeroMemory( &mtrl, sizeof(MATERIAL) ); mtrl.Diffuse.r = 5.0f; mtrl.Diffuse.g = 5.0f; mtrl.Diffuse.b = 5.0f; g_pd3dDevice->SetMaterial( &mtrl ); if( FilteringOption == 1 ) { // normales bilineares filtern mit einfachem Mipmap-Wechsel "abruptes Überblenden" g_pd3dDevice->SetSamplerState( 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT ); g_pd3dDevice->SetSamplerState( 1, D3DSAMP_MIPFILTER, D3DTEXF_POINT ); } else if( FilteringOption == 2 ) { // trilineares filtern (bilineare Filterung zwischen verschiedenen Mipmaps "sanftes Überblenden") g_pd3dDevice->SetSamplerState( 0, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR ); g_pd3dDevice->SetSamplerState( 1, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR ); } g_pd3dDevice->SetTexture(0, TerrainTextures->TileTextur[TexturNummer].pTexture); if(DetailMapping == TRUE) { g_pd3dDevice->SetTextureStageState(1, D3DTSS_TEXCOORDINDEX, 1); g_pd3dDevice->SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_TEXTURE ); g_pd3dDevice->SetTextureStageState(1, D3DTSS_COLORARG2, D3DTA_CURRENT ); g_pd3dDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_ADDSIGNED); g_pd3dDevice->SetTexture(1, TerrainTextures->DetailTextur[DetailTexturNummer].pTexture); } g_pd3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_CCW ); g_pd3dDevice->SetStreamSource( 0, TileVB, 0, sizeof(SPACEOBJEKT3DVERTEX_EX) ); g_pd3dDevice->SetFVF( D3DFVF_SPACEOBJEKT3DVERTEX_EX); g_pd3dDevice->SetIndices( TileIB); g_pd3dDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, AnzVertices, 0, AnzTriangles ); g_pd3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_CW ); g_pd3dDevice->SetTextureStageState(0, D3DTSS_TEXCOORDINDEX, 0); g_pd3dDevice->SetTextureStageState(1, D3DTSS_TEXCOORDINDEX, 0); g_pd3dDevice->SetSamplerState( 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE); g_pd3dDevice->SetSamplerState( 1, D3DSAMP_MIPFILTER, D3DTEXF_NONE); g_pd3dDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE); g_pd3dDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE); g_pd3dDevice->SetTexture(0, NULL); g_pd3dDevice->SetTexture(1, NULL); } };
Ich hab schon den ganzen Morgen in der Schule dran gearbeitet, bin aber auf kein richtiges Ergebnis gekommen (ich weiß, dass nicht alle Funktionen der Klasse hier her gehören, aber der Vollständigkeit halber sind sie eben da).
Ich arbeite auch dran weiter, wäre aber sehr sehr sehr glücklich über evtl. Lösungen
.
MfG WirrWar2850.
-
g_pd3dDevice->UseROAMGeneration();
*SCNR*
-
WirrWar2850 schrieb:
ROAM Algorhytus
*scnr 2
-
Schön wärs, wenns so einfach ginge, dann müsste ich mir nicht den Kopf darüber zerbrechen
...
MfG WirrWar2850.
-
WirrWar2850 schrieb:
Wie kann ich den ROAM Algorhytus in diese C++ Klasse einbauen
Mit Hirn und Tastatur.
Bye, TGGC (Der Held lebt!)
-
Du benutzt eine fertige Klasse und willst sie von anderen erweitern lassen?
Glaub mir, da hast du nichts von (abgesehen davon, dass das keiner macht)
-
Ich benutze nicht diese Klasse, meine Klasse ist um einiges gewachsen und die will ich hier nicht rein hauen, da sie vom Allgemeinen her auf dem obrigen Quelltext basiert und die, die ich geschrieben hab viel zu groß und unübersichtlich ist (wenn man sie nicht kennt)...
MfG WirrWar2850.