我正在尝试使用索引基元创建地形...我已经编写了一个类来处理图形,但是,我无法让纹理地形出现在屏幕上......以下是源代码和此进程关联的头文件...请忽略天空盒功能......
graphics.h中:
#pragma once
#include <d3d9.h>
#include <d3dx9.h>
#include <d3dx9tex.h>
#include <string>
#include "Camera.h"
class CGraphics
{
public:
CGraphics(IDirect3DDevice9 *device);
~CGraphics(void);
IDirect3DDevice9 *m_d3ddev;
LPDIRECT3DVERTEXBUFFER9 m_vertexBuffer;
LPDIRECT3DVERTEXBUFFER9 m_terrainVertexBuffer;
LPDIRECT3DINDEXBUFFER9 m_terrainIndexBuffer;
LPDIRECT3DTEXTURE9 m_textures[6];
LPDIRECT3DTEXTURE9 m_terrainTexture;
int m_numVertices;
int m_numFaces;
bool SkyBox(void);
void UpdateSkyBox(void);
bool Terrain(D3DXVECTOR3 minB, D3DXVECTOR3 maxB, int numCellsW, int numCellsL);
void RenderTerrain(void);
private:
void RenderSkyBox(void);
};
graphics.cpp:
#include "Graphics.h"
#include "3D Shapes.h"
#include "assert.h"
CGraphics::CGraphics(IDirect3DDevice9 *device) : m_d3ddev(device), m_vertexBuffer(0)
{
for(unsigned int i = 0; i < sizeof(LPDIRECT3DTEXTURE9)/sizeof(m_textures); i++)
{
m_textures[i] = 0;
m_terrainVertexBuffer = NULL;
m_terrainIndexBuffer = NULL;
}
}
CGraphics::~CGraphics(void)
{
if(m_vertexBuffer)
{
delete m_vertexBuffer;
m_vertexBuffer=0;
}
if(m_d3ddev)
{
m_d3ddev->Release();
m_d3ddev=0;
}
if(m_terrainVertexBuffer){
m_terrainVertexBuffer->Release();
m_terrainVertexBuffer=0;
}
if(m_terrainIndexBuffer){
m_terrainIndexBuffer->Release();
m_terrainIndexBuffer=0;
}
}
bool CGraphics::SkyBox(void)
{
HRESULT hr;
hr = m_d3ddev->CreateVertexBuffer(sizeof(TEXTUREVERTEX) * 24, 0, CUSTOMFVF, D3DPOOL_MANAGED,
&m_vertexBuffer, NULL);
if(FAILED(hr))
{
MessageBox(NULL, L"Failed to 'Create Vertex Buffer for SkyBox'", L"ERROR", MB_OK);
return false;
}
void* pVertices = NULL;
m_vertexBuffer->Lock(0, sizeof(TEXTUREVERTEX)*24, (void**)&pVertices, 0);
memcpy(pVertices, skyBox, sizeof(TEXTUREVERTEX)*24);
m_vertexBuffer->Unlock();
hr = D3DXCreateTextureFromFileA(m_d3ddev, fileF.c_str(), &m_textures[0]);
hr |= D3DXCreateTextureFromFileA(m_d3ddev, fileB.c_str(), &m_textures[1]);
hr |= D3DXCreateTextureFromFileA(m_d3ddev, fileL.c_str(), &m_textures[2]);
hr |= D3DXCreateTextureFromFileA(m_d3ddev, fileR.c_str(), &m_textures[3]);
hr |= D3DXCreateTextureFromFileA(m_d3ddev, fileTop.c_str(), &m_textures[4]);
hr |= D3DXCreateTextureFromFileA(m_d3ddev, fileBottom.c_str(), &m_textures[5]);
if ( FAILED(hr) )
{
MessageBox(NULL, L"Failed to open 1 or more images files!", L"Error Opening Texture Files", MB_OK);
return false;
}
return true;
}
void CGraphics::UpdateSkyBox(void)
{
D3DXMATRIX matView, matSave, matWorld;
m_d3ddev->GetTransform(D3DTS_VIEW, &matSave);
matView = matSave;
matView._41 = 0.0f; matView._42 = -0.4f; matView._43 = 0.0f;
m_d3ddev->SetTransform(D3DTS_VIEW, &matView);
D3DXMatrixIdentity(&matWorld);
m_d3ddev->SetTransform(D3DTS_WORLD, &matWorld);
RenderSkyBox();
m_d3ddev->SetTransform(D3DTS_VIEW, &matSave);
}
void CGraphics::RenderSkyBox(void)
{
m_d3ddev->SetRenderState(D3DRS_ZENABLE, false);
m_d3ddev->SetRenderState(D3DRS_ZWRITEENABLE, false);
m_d3ddev->SetRenderState(D3DRS_LIGHTING, false);
m_d3ddev->SetSamplerState( 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP );
m_d3ddev->SetSamplerState( 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP );
m_d3ddev->SetFVF(CUSTOMFVF);
m_d3ddev->SetStreamSource(0, m_vertexBuffer, 0, sizeof(TEXTUREVERTEX));
for(unsigned int i = 0; i < 6; i ++)
{
m_d3ddev->SetTexture(0, m_textures[i]);
m_d3ddev->DrawPrimitive(D3DPT_TRIANGLESTRIP, i*4, 2);
}
m_d3ddev->SetRenderState(D3DRS_ZENABLE, true);
m_d3ddev->SetRenderState(D3DRS_ZWRITEENABLE, true);
m_d3ddev->SetRenderState(D3DRS_LIGHTING, true);
}
bool CGraphics::Terrain(D3DXVECTOR3 minB, D3DXVECTOR3 maxB, int numCellsW, int numCellsL)
{
HRESULT hr = D3DXCreateTextureFromFileA(m_d3ddev, (LPCSTR)texFileTerrain.c_str(), &m_terrainTexture);
if(FAILED(hr))
{
MessageBox(NULL, L"Could not 'Load Texture(Terrain)'", L"ERROR", MB_OK);
return false;
}
TERRAIN terra = {minB,maxB,numCellsW,numCellsL,numCellsW+1,numCellsL+1,(maxB.x - minB.x)/numCellsW,
(maxB.z - minB.z)/numCellsL,
terra.vertices = new VERTEXARRAY[terra.numVertsX*terra.numVertsZ],
};
m_numVertices = terra.numVertsX*terra.numVertsZ;
m_numFaces = terra.numCellsX*terra.numCellsZ*2;
DWORD *indices = new DWORD[terra.numCellsX*terra.numCellsZ*6];
for(int i = 0; i < sizeof(indices); i++)
{
indices[i] = 0;
}
D3DXVECTOR3 pos(minB.x, 0, minB.z);
int vIter = 0;
for(int z = 0; z < terra.numVertsZ; z++)
{
for(int x = 0; x < terra.numVertsX; x++)
{
terra.vertices[vIter].x = 0;
terra.vertices[vIter].y = 0;
terra.vertices[vIter].z = 0;
terra.vertices[vIter].tu = 0;
terra.vertices[vIter].tv = 0;
vIter++;
}
}
double curTexPosZ = 1.0;
vIter=0;
for(double z = 0; z < (double)terra.numVertsZ; z++)
{
pos.x = minB.x;
curTexPosZ = (double)((double)terra.numCellsZ - z) / (double)(terra.numCellsZ);
for(double x = 0; x < terra.numVertsX; x++)
{
terra.vertices[vIter].x = pos.x;
terra.vertices[vIter].y = pos.y;
terra.vertices[vIter].z = pos.z;
//terra.vertices[vIter].color = D3DCOLOR_ARGB(0,255,255,255);
terra.vertices[vIter].tu = (float)(x / (double)terra.numCellsX);
terra.vertices[vIter].tv = (float)curTexPosZ;
pos.x += terra.stepX;
vIter++;
}
pos.z += terra.stepZ;
}
assert(vIter <= terra.numVertsX*terra.numVertsZ);
vIter = 0;
int iPos =0;
for(int z =0; z< terra.numCellsZ; z++)
{
for(int x = 0; x< terra.numCellsX; x++)
{
indices[iPos] = vIter; iPos++;
indices[iPos] = vIter+terra.numVertsX; iPos++;
indices[iPos] = vIter+terra.numVertsX+1; iPos++;
indices[iPos] = vIter; iPos++;
indices[iPos] = vIter+terra.numVertsX+1; iPos++;
indices[iPos] = vIter+1; iPos++;
vIter++;
}
vIter++;
}
assert(vIter <= terra.numCellsX*terra.numCellsZ*6);
void* pVoid;
hr = m_d3ddev->CreateVertexBuffer(sizeof(VERTEXARRAY)*terra.numVertsX*terra.numVertsZ,0,
CUSTOMFVF,D3DPOOL_MANAGED,&m_terrainVertexBuffer,NULL);
if(FAILED(hr)){
MessageBox(NULL, L"Could not Create Vertex Buffer", L"ERROR", MB_OK);
return false;
}
hr = m_terrainVertexBuffer->Lock(0, 0, (void**)&pVoid, NULL);
if(FAILED(hr)){
MessageBox(NULL, L"Could not Lock Vertex Buffer", L"ERROR", MB_OK);
return false;
}
memcpy(pVoid, terra.vertices, sizeof(terra.vertices));
m_terrainVertexBuffer->Unlock();
hr = m_d3ddev->CreateIndexBuffer(sizeof(DWORD)*sizeof(indices),0,
D3DFMT_INDEX16, D3DPOOL_MANAGED, &m_terrainIndexBuffer, NULL);
if(FAILED(hr)){
MessageBox(NULL, L"Could not Create Index Buffer", L"ERROR", MB_OK);
return false;
}
hr = m_terrainIndexBuffer->Lock(0, 0, (void**)&pVoid, 0);
if(FAILED(hr)){
MessageBox(NULL, L"Could not Create Vertex Buffer", L"ERROR", MB_OK);
return false;
}
memcpy(pVoid, indices, sizeof(indices));
if(FAILED(hr)){
MessageBox(NULL, L"Could not Create Vertex Buffer", L"ERROR", MB_OK);
return false;
}
m_terrainIndexBuffer->Unlock();
return true;
}
void CGraphics::RenderTerrain(void)
{
m_d3ddev->SetFVF(CUSTOMFVF);
m_d3ddev->SetTexture(0, m_terrainTexture);
m_d3ddev->SetStreamSource(0, m_terrainVertexBuffer, 0, sizeof(VERTEXARRAY));
m_d3ddev->SetIndices(m_terrainIndexBuffer);
m_d3ddev->DrawIndexedPrimitive(D3DPT_TRIANGLESTRIP, 0, 0, m_numVertices, 0, m_numFaces);
}
3D形状:
#pragma once
#define CUSTOMFVF (D3DFVF_XYZ | D3DFVF_TEX1)
struct TEXTUREVERTEX {
float x, y, z, tu, tv;
};
TEXTUREVERTEX skyBox[] = {
// Front quad, NOTE: All quads face inward
{-10.0f, -10.0f, 10.0f, 0.0f, 1.0f }, {-10.0f, 10.0f, 10.0f, 0.0f, 0.0f }, { 10.0f, -10.0f, 10.0f, 1.0f, 1.0f }, { 10.0f, 10.0f, 10.0f, 1.0f, 0.0f },
// Back quad
{ 10.0f, -10.0f, -10.0f, 0.0f, 1.0f }, { 10.0f, 10.0f, -10.0f, 0.0f, 0.0f }, {-10.0f, -10.0f, -10.0f, 1.0f, 1.0f },{-10.0f, 10.0f, -10.0f, 1.0f, 0.0f },
// Left quad
{-10.0f, -10.0f, -10.0f, 0.0f, 1.0f }, {-10.0f, 10.0f, -10.0f, 0.0f, 0.0f }, {-10.0f, -10.0f, 10.0f, 1.0f, 1.0f }, {-10.0f, 10.0f, 10.0f, 1.0f, 0.0f },
// Right quad
{ 10.0f, -10.0f, 10.0f, 0.0f, 1.0f }, { 10.0f, 10.0f, 10.0f, 0.0f, 0.0f }, { 10.0f, -10.0f, -10.0f, 1.0f, 1.0f }, { 10.0f, 10.0f, -10.0f, 1.0f, 0.0f },
// Top quad
{-10.0f, 10.0f, 10.0f, 0.0f, 1.0f }, {-10.0f, 10.0f, -10.0f, 0.0f, 0.0f }, { 10.0f, 10.0f, 10.0f, 1.0f, 1.0f }, { 10.0f, 10.0f, -10.0f, 1.0f, 0.0f },
// Bottom quad
{-10.0f, -10.0f, -10.0f, 0.0f, 1.0f }, {-10.0f, -10.0f, 10.0f, 0.0f, 0.0f }, { 10.0f, -10.0f, -10.0f, 1.0f, 1.0f },{ 10.0f, -10.0f, 10.0f, 1.0f, 0.0f }
};
std::string fileF("skybox_front.jpg");
std::string fileB("skybox_back.jpg");
std::string fileL("skybox_left.jpg");
std::string fileR("skybox_right.jpg");
std::string fileTop("skybox_top.jpg");
std::string fileBottom("skybox_bottom.jpg");
struct VERTEXARRAY {
float x, y, z, tu, tv;
};
struct TERRAIN {
D3DXVECTOR3 minBounds; // minimum bounds (x, y, z)
D3DXVECTOR3 maxBounds; // maximum bounds (x, y, z)
int numCellsX; // # of cells in the x direction
int numCellsZ; // # of cells in the z direction
int numVertsX; // # of vertices in the x direction
int numVertsZ; // # of vertices in the z direction
float stepX; // space between vertices in the x direction
float stepZ; // space between vertices in the z direction
VERTEXARRAY *vertices; // vertex array pointer (stores the position for each vertex
};
std::string texFileTerrain("sunset.jpg");
我在线查看了无数的教程和样本,但没有找到解决方案。我想我遇到的问题与设置有关,我必须忽略一些事情......任何想法都会受到赞赏......提前谢谢!