C++ Directx 9带顶点的基本地形创建
我正在尝试使用索引原语创建地形…我编写了一个类来处理图形,但是,我无法使纹理地形显示在屏幕上…以下是与此过程相关的源文件和头文件…请忽略skybox函数 图h:C++ Directx 9带顶点的基本地形创建,c++,winapi,directx,C++,Winapi,Directx,我正在尝试使用索引原语创建地形…我编写了一个类来处理图形,但是,我无法使纹理地形显示在屏幕上…以下是与此过程相关的源文件和头文件…请忽略skybox函数 图h: #pragma once #include <d3d9.h> #include <d3dx9.h> #include <d3dx9tex.h> #include <string> #include "Camera.h" class CGraphics { public: CG
#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);
};
我在网上查阅了无数的教程和示例,但没有找到解决方案。我想我遇到的问题与设置有关,我一定是忽略了一些东西…任何想法都将不胜感激…提前感谢 您尚未正确设置视图矩阵。摄像机可能位于地形内或地形下。首先使用D3DXMatrixLookAtLH,而不是尝试立即渲染地形,而是从单个四边形/三角形开始。当你能够直观地看到一个四边形时,就开始把事情弄得更复杂。此外,您不需要“删除”顶点缓冲区。视图矩阵是在程序的另一部分中设置的…我有一个可以用键盘和鼠标在三维空间中移动的相机…我需要设置任何变换才能将地形放置在屏幕上吗?D3D中是否有任何设置会阻止或启用查看索引原语?有几个地方可能会出错。为了弄清楚发生了什么,我需要调试你的程序,坦率地说,我没有心情。要调试地形,请禁用背面消隐(SetRenderState(D3DRS_CULLMODE,D3DCULL_NONE)),然后尝试渲染没有纹理的单个四边形。当你得到正确的四边形时,开始将其转换为地形。你看到天空盒子了吗?比较地形渲染代码和skybox渲染代码,看看有什么问题。我在屏幕上看到一个三角形,它是静止的…当我移动相机时,三角形保持在屏幕上的相同位置…如何将三角形包括在视图变换中?
#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);
}
#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");