D3D9 C++ Terrain wird nicht korrekt gezeichnet



  • EDIT: Problem gelöst, lag am Verwechseln von CUSTOMVERTEX und CUSTOMFVF

    Moin,

    vor zwei Tagen habe ich angefangen mich in Direct3D einzuarbeiten.
    Als Grundlage habe ich diese Tutorials verwendet:
    http://directxtutorial.com

    Seit gestern versuche ich ein Terrain zu rendern, wobei mir diese Seite sehr geholfen hat:
    http://www.toymaker.info/Games/html/terrain.html

    Auf dieser Basis habe ich den gleich folgenden Code geschrieben.

    Das Problem: Es wird zwar etwas gezeichnet, aber das scheint komplett wirres Zeug zu sein. Ich habe meinen Vertexbuffer und Indexbuffer überprüft und eine Zeichnung angelegt wie alles sein sollte:
    http://img3.imagebanana.com/view/i8jc8tf/TerrainMesh.png

    Dieser *Müll* kommt bei mir heraus beim Ausführen des Programms:
    http://img3.imagebanana.com/view/j4hmvqw/crapTerrain.png
    (wobei allein schon die Positionierung der Kamera mit den gegebenen Daten keinen Sinn ergibt, siehe Code)

    Ich teste mit einem kleinem 2 * 2 Terrain für den Anfang ohne Höhenwerte. Also y ist immer 0.0f. Ich habe den Vertex- und Indexbuffer vor dem Kopieren in den VideoRAM überprüft und alles ist korrekt. Ich Vermute das ich beim Kopieren oder Zeichnen etwas falsch mache.

    eigenes flexible vertex format und die struct:

    #define CUSTOMFVF (D3DFVF_XYZ|D3DFVF_DIFFUSE)
    struct CUSTOMVERTEX
    {
        FLOAT x, y, z;
        DWORD color;
    };
    

    Funktionen zum Erstellen des Terrainmesh und Renderfunktion:

    bool Cterrain::CreateTerrainMesh(unsigned short numCellsX, unsigned short numCellsZ, float CellSize)
    {
    	this->cellsx    = numCellsX;
    	this->cellsz    = numCellsZ;
    	this->cells     = cellsx * cellsz;
    	this->verticesx = cellsx + 1;
    	this->verticesz = cellsz + 1;
    	this->vertices  = verticesx * verticesz;
    	this->triangles = cellsx * cellsz * 2;
    	this->cellsize  = CellSize;
    	this->minboundx = 0.0f;
    	this->maxboundx = cellsx * cellsize;
    	this->minboundz = 0.0f;
    	this->maxboundz = cellsz * cellsize;
    
    	CUSTOMVERTEX *vertex = new CUSTOMVERTEX[this->vertices];
    	unsigned short *indices = new unsigned short[this->triangles*3];
    
    	// fill temporary vertexbuffer
    	unsigned long count=0;
    	float posx = this->minboundx;
    	float posz = this->minboundz;
    	for (unsigned long z=0; z<this->verticesz; z++)
    	{
    		posx = this->minboundx;
    		for (unsigned long x=0; x<this->verticesx; x++)
    		{
    			vertex[count].x = posx;
    			vertex[count].y = 0.0f;
    			vertex[count].z = posz;
    			vertex[count].color = 0xFFFFFFFF;
    			posx += this->cellsize;
    			count++;
    		}
    		posz += this->cellsize;
    	}
    
    	// fill temporary indexbuffer
    	count=0;
    	unsigned short vIndex=0;
    	for (unsigned long z=0; z<this->cellsz; z++)
    	{
    		for (unsigned long x=0; x<this->cellsz; x++)
    		{
    			// first triangle
    			indices[count++]=vIndex;
    			indices[count++]=vIndex+this->verticesx;
    			indices[count++]=vIndex+this->verticesx+1;
    
    			// second triangle
    			indices[count++]=vIndex;
    			indices[count++]=vIndex+this->verticesx+1;
    			indices[count++]=vIndex+1;
    			vIndex++;
    		 }
    		 vIndex++;
    	}
    
    	d3ddev->CreateVertexBuffer( this->vertices*sizeof(CUSTOMFVF),
    								D3DUSAGE_WRITEONLY,
    								CUSTOMFVF,
                                    D3DPOOL_MANAGED,
    								&vertexbuffer,
    								NULL );
    
    	d3ddev->CreateIndexBuffer(	this->triangles*3*2,// *3=three vertices per triangle; *2=each index 2 bytes
    								D3DUSAGE_WRITEONLY,
    								D3DFMT_INDEX16,
    								D3DPOOL_MANAGED,
    								&indexbuffer,
    								NULL);
    
    	// copy buffers
        VOID* pVoid=0;
    	vertexbuffer->Lock(0, this->vertices*sizeof(CUSTOMFVF), (void**)&pVoid, 0);	// lock the vertex buffer
    	memcpy(pVoid, vertex, sizeof(CUSTOMVERTEX)*this->vertices);			// copy the vertices to the locked buffer
        vertexbuffer->Unlock();							// unlock the vertex buffer
    
    	pVoid=0;
    	indexbuffer->Lock(0, sizeof(unsigned short)*this->triangles*3, (void**)&pVoid, 0);		// lock the indexbuffer
    	memcpy(pVoid, indices, sizeof(unsigned short)*this->triangles*3);		// copy indexbuffer
        indexbuffer->Unlock();							// unlock the indexbuffer
    
    	delete []vertex;
    	delete []indices;
    
    	return true;
    }
    
    void Cterrain::RenderTerrain()
    {
    	d3ddev->SetStreamSource(0,this->vertexbuffer,0,sizeof(CUSTOMFVF));
    	d3ddev->SetFVF(CUSTOMFVF);
    	d3ddev->SetIndices(this->indexbuffer);
    
    	if (d3ddev->DrawIndexedPrimitive(D3DPT_TRIANGLELIST,0,0,this->vertices,0,this->triangles) != D3D_OK)
    	{
    		int SETBPHERE=0;	// something is wrong, damn...
    	}
    }
    

    Funktion zum Rendern eines Frames, hier wird RenderTerrain() gecallt:

    void render_frame()
    {
        d3ddev->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 40, 100), 1.0f, 0);
    	d3ddev->Clear(0, NULL, D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0);
        d3ddev->BeginScene();
    
        // SET UP THE PIPELINE
    
    	D3DXMATRIX matTranslate;
    	D3DXMatrixTranslation(&matTranslate, 0.0f, 0.0f, 0.0f);
        d3ddev->SetTransform(D3DTS_WORLD, &matTranslate);
    
        D3DXMATRIX matView;
        D3DXMatrixLookAtLH(&matView,
                           &D3DXVECTOR3 (0.0f, 50.0f,-200.0f),	// the camera position
                           &D3DXVECTOR3 (-50.0f, 0.0f,-50.0f),	// the look-at position
                           &D3DXVECTOR3 (0.0f, 1.0f, 0.0f));	// the up direction
        d3ddev->SetTransform(D3DTS_VIEW, &matView);
    
        D3DXMATRIX matProjection;
        D3DXMatrixPerspectiveFovLH(&matProjection,
                                   D3DXToRadian(45),    // the horizontal field of view
                                   (FLOAT)SCREEN_WIDTH / (FLOAT)SCREEN_HEIGHT, // aspect ratio
                                   1.0f,    // the near view-plane
                                   1000.0f);    // the far view-plane
    
        d3ddev->SetTransform(D3DTS_PROJECTION, &matProjection);    // set the projection
    
    	terrain.RenderTerrain();
    
        d3ddev->EndScene();
        d3ddev->Present(NULL, NULL, NULL, NULL);   // displays the created frame on the screen
    }
    

Anmelden zum Antworten