关于Mesh的一个简单问题,请人指教
帮我看看这段代码为什么运行不出任何图像?我是先建一个Mesh然后填充数据,再渲染出来。已经把Mesh的数据简化了,可就不出任何图像,请高手指教!
struct TerrainVertex
{
TerrainVertex(){}
TerrainVertex(float x,float y,float z,float u,float v)
{
_x=x;_y=y;_z=z;
_u=u;_v=v;
}
float _x,_y,_z;
float _u,_v;
};
#define FVF D3DFVF_XYZ | D3DFVF_TEX1
// 全局变量:
HINSTANCE hInst; // 当前实例
TCHAR szTitle[MAX_LOADSTRING]; // 标题栏文本
TCHAR szWindowClass[MAX_LOADSTRING]; // 主窗口类名
LPDIRECT3D9 g_pD3D=NULL; //创建D3D设备的D3D对象参数
LPDIRECT3DDEVICE9 g_pd3dDevice=NULL;//渲染中使用的D3D设备
HWND hwnd;
ID3DXMesh *Mesh=0;
IDirect3DTexture9 *tex=0;
int numVertsPerRow,numVertsPerCol;
int cellSpacing;
int numCellsPerRow,numCellsPerCol;
int width,depth;
int numVertices,numTriangles;
float herightScale;
// 此代码模块中包含的函数的前向声明:
ATOM MyRegisterClass(HINSTANCE hInstance);
BOOL InitInstance(HINSTANCE, int);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM);
bool computeVertices();
bool computeIndices();
bool loadTexture(LPCWSTR fileName);
bool computeAttributeBuffer();
void SetupMatrices();
int d3d::EnterMsgLooop(bool (*ptr_display)(float timeDelete))
{
MSG msg;
ZeroMemory(&msg,sizeof(msg));
float lastTime=(float)timeGetTime();
while(msg.message !=WM_QUIT)
{
//消息队列中有消息时,调用相应的处理过程
if(PeekMessage(&msg,NULL,0U,0U,PM_REMOVE))
{
TranslateMessage( &msg );
DispatchMessage( &msg );
}
else
{
float currTime=(float)timeGetTime();
float timeDelta=(currTime-lastTime)*0.001f;
ptr_display(timeDelta);
lastTime=currTime;
}
}
return msg.wParam;
}
//初始化Mesh用到的数据,并填充Mesh
bool Setup()
{
width=WIIDTH;
depth=DEPTH;
cellSpacing=1;
numVertsPerRow=(width/cellSpacing)+1;
numVertsPerCol=(depth/cellSpacing)+1;
numCellsPerRow=numVertsPerRow-1;
numCellsPerCol=numVertsPerCol-1;
numVertices=numVertsPerCol*numVertsPerRow;
numTriangles=numCellsPerRow*numVertsPerCol*2;
herightScale=0.0f;
HRESULT hr=0;
hr=D3DXCreateMeshFVF(numTriangles,numVertices,D3DXMESH_MANAGED,FVF,g_pd3dDevice,&Mesh);
if(FAILED(hr))
{
MessageBox(0,L"Error",L"创建Mesh失败",MB_OK);
}
computeVertices();
computeIndices();
computeAttributeBuffer();
std::vector<DWORD> adjacencyBuffer(Mesh->GetNumFaces() * 3);
Mesh->GenerateAdjacency(0.0f, &adjacencyBuffer[0]);
hr = Mesh->OptimizeInplace(
D3DXMESHOPT_ATTRSORT |
D3DXMESHOPT_COMPACT |
D3DXMESHOPT_VERTEXCACHE,
&adjacencyBuffer[0],
0, 0, 0);
if(FAILED(hr))
{
MessageBox(0,L"Error",L"优化Mesh失败",MB_OK);
}
if(!loadTexture(L"rock.jpg"))
MessageBox(0,L"Error",L"创建纹理失败",MB_OK);
g_pd3dDevice->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
g_pd3dDevice->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
g_pd3dDevice->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
//
// Disable lighting.
//
g_pd3dDevice->SetRenderState(D3DRS_LIGHTING, false);
SetupMatrices();
return true;
}
void Cleanup()
{
}
bool Display(float timeDelta)
{
D3DXMATRIXA16 matWorld;
D3DXMatrixIdentity(&matWorld);
g_pd3dDevice->SetTransform( D3DTS_WORLD, &matWorld );
if(g_pd3dDevice)
{
g_pd3dDevice->Clear(0,NULL,D3DCLEAR_TARGET,D3DCOLOR_XRGB(80,60,120),1.0f,0);
if(SUCCEEDED(g_pd3dDevice->BeginScene()))
{
g_pd3dDevice->SetTexture(0,tex);
Mesh->DrawSubset(0);
g_pd3dDevice->EndScene();
}
else
{
MessageBox(0,L"Error",L"绘制开始失败",MB_OK);
}
g_pd3dDevice->Present(NULL,NULL,NULL,NULL);
}
return true;
}
LRESULT CALLBACK d3d::WndProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam)
{
switch (msg)
{
case WM_KEYDOWN:
if(wParam==VK_ESCAPE)
DestroyWindow(hwnd);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd, msg, wParam, lParam);
}
return 0;
}
bool d3d::InitD3D(HWND hWnd)
{
//创建一个用来创建设备的D3D对象
if(NULL==(g_pD3D=Direct3DCreate9(D3D_SDK_VERSION)))
return E_FAIL;
D3DPRESENT_PARAMETERS d3dpp;//创建设备的结构体
ZeroMemory(&d3dpp,sizeof(d3dpp));//必须调用此函数将结构体清0
d3dpp.Windowed=TRUE;//创建窗口模式
d3dpp.hDeviceWindow = hWnd;
d3dpp.SwapEffect=D3DSWAPEFFECT_DISCARD;//最有效的Swap效果
d3dpp.BackBufferFormat=D3DFMT_UNKNOWN;//建立一个与当前显示模式相匹配的后置缓冲
if(FAILED(g_pD3D->CreateDevice(D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL,hWnd,D3DCREATE_SOFTWARE_VERTEXPROCESSING,&d3dpp,&g_pd3dDevice)))
{
return E_FAIL;
}
return true;
}
int APIENTRY _tWinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
{
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
// TODO: 在此放置代码。
MSG msg;
HACCEL hAccelTable;
// 初始化全局字符串
LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
LoadString(hInstance, IDC_TERRAIN, szWindowClass, MAX_LOADSTRING);
MyRegisterClass(hInstance);
// 执行应用程序初始化:
if (!InitInstance (hInstance, nCmdShow))
{
return FALSE;
}
if(!d3d::InitD3D (hwnd))
{
MessageBox(hwnd,L"InitD3D() failed",0,0);
return FALSE;
}
if(!Setup())
{
MessageBox(hwnd,L"Setup() failed",0,0);
return FALSE;
}
//显示窗口
ShowWindow(hwnd, nCmdShow);
UpdateWindow(hwnd);
d3d::EnterMsgLooop (Display);
Cleanup();
}
// 目的: 注册窗口类
ATOM MyRegisterClass(HINSTANCE hInstance)
{
WNDCLASSEX wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = d3d::WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_TERRAIN));
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
//把系统自动生成的菜单给去掉,以后用的时候再填上。游戏中一般都没有菜单的!
wcex.lpszMenuName = NULL;//MAKEINTRESOURCE(IDC_MYCOMMON);
wcex.lpszClassName = szWindowClass;
wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));
return RegisterClassEx(&wcex);
}