- //
- // 2011/1/20
- // cube.cpp文件:
- // 作者:CYM
- // 渲染组旋转立方体在网格模式。演示了顶点和索引缓存,世界和观点变换
- // *新增功能:按方向键能上下能调整摄像机距离和目标的距离
- // *新增功能:纹理变化
- //
- #include "d3dUtility.h"
- //
- // 全局设置
- //
- IDirect3DDevice9* Device = 0; //dx设备对象
- LPDIRECT3DTEXTURE9 g_Texture1 = NULL; //定义文理1 ugp.tga
- LPDIRECT3DTEXTURE9 g_Texture2 = NULL; //定义文理2 picture.tga
- D3DLIGHT9 g_light; //定义灯光
- D3DMATERIAL9 g_material; //定义材质
- const int Width = 640;
- const int Height = 480;
- IDirect3DVertexBuffer9* VB = 0;
- IDirect3DIndexBuffer9* IB = 0;
- D3DXVECTOR3 position(0.0f, 0.0f, -5.0f); //视角位置
- D3DXVECTOR3 target(0.0f, 0.0f, 0.0f); //目标
- D3DXVECTOR3 up(0.0f, 1.0f, 0.0f); //高度
- D3DXMATRIX V; //矩阵,
- static int texType=0; //纹理类型标识
- //
- // 顶点/类和结构
- //
- struct Vertex
- {
- Vertex(){}
- Vertex(float x, float y, float z, float nx ,float ny , float nz,unsigned long color, float tu, float tv)
- {
- _x = x; _y = y; _z = z;
- _nx=nx;_ny=ny;_nz=nz;
- _color=color;
- _tu=tu;_tv=tv;
- }
- float _x, _y, _z;
- float _nx,_ny,_nz;
- unsigned long _color;
- float _tu, _tv;
- static const DWORD FVF;
- };
- const DWORD Vertex::FVF = (D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_DIFFUSE | D3DFVF_TEX1);
- //
- //框架功能
- //
- bool Setup()
- {
- //
- // 创建顶点和索引缓冲.
- //
- Device->CreateVertexBuffer(
- 24 * sizeof(Vertex),
- D3DUSAGE_WRITEONLY,
- Vertex::FVF,
- D3DPOOL_MANAGED,
- &VB,
- 0);
- Device->CreateIndexBuffer(
- 36 * sizeof(WORD),
- D3DUSAGE_WRITEONLY,
- D3DFMT_INDEX16,
- D3DPOOL_MANAGED,
- &IB,
- 0);
- //
- // 填补缓冲器与立方体数据。
- //
- // 定义独特的顶点。
- Vertex* v;
- VB->Lock(0, 0, (void**)&v, 0);
- // 一个立方体的顶点数据
- // 填充正面顶点数据
- v[0] = Vertex(-1.0f, -1.0f, -1.0f,0.0f,0.0f,1.0f,D3DCOLOR_XRGB(255,255,255),0.0f, 0.0f);
- v[1] = Vertex(-1.0f, 1.0f, -1.0f,0.0f,0.0f,1.0f,D3DCOLOR_XRGB(255,255,255),0.0f, 1.0f);
- v[2] = Vertex( 1.0f, 1.0f, -1.0f,0.0f,0.0f,1.0f,D3DCOLOR_XRGB(255,255,255),1.0f, 1.0f);
- v[3] = Vertex( 1.0f, -1.0f, -1.0f,0.0f,0.0f,1.0f,D3DCOLOR_XRGB(255,255,255),1.0f, 0.0f);
- // 填充背面顶点数据
- v[4] = Vertex(-1.0f, -1.0f, 1.0f,0.0f,0.0f,-1.0f,D3DCOLOR_XRGB(255,255,255),0.0f, 0.0f);
- v[5] = Vertex( 1.0f, -1.0f, 1.0f,0.0f,0.0f,-1.0f,D3DCOLOR_XRGB(255,255,255),0.0f, 1.0f);
- v[6] = Vertex( 1.0f, 1.0f, 1.0f,0.0f,0.0f,-1.0f,D3DCOLOR_XRGB(255,255,255),1.0f, 1.0f);
- v[7] = Vertex(-1.0f, 1.0f, 1.0f,0.0f,0.0f,-1.0f,D3DCOLOR_XRGB(255,255,255),1.0f, 0.0f);
- // 填充顶面顶点数据
- v[8] = Vertex(-1.0f, 1.0f, -1.0f,0.0f,1.0f,0.0f,D3DCOLOR_XRGB(255,255,255),0.0f, 0.0f);
- v[9] = Vertex(-1.0f, 1.0f, 1.0f,0.0f,1.0f,0.0f,D3DCOLOR_XRGB(255,255,255),0.0f, 1.0f);
- v[10] = Vertex( 1.0f, 1.0f, 1.0f,0.0f,1.0f,0.0f,D3DCOLOR_XRGB(255,255,255),1.0f, 1.0f);
- v[11] = Vertex( 1.0f, 1.0f, -1.0f,0.0f,1.0f,0.0f,D3DCOLOR_XRGB(255,255,255),1.0f, 0.0f);
- // 填充底面顶点数据
- v[12] = Vertex(-1.0f, -1.0f, -1.0f,0.0f,-1.0f,0.0f,D3DCOLOR_XRGB(255,255,255),0.0f, 0.0f);
- v[13] = Vertex( 1.0f, -1.0f, -1.0f,0.0f,-1.0f,0.0f,D3DCOLOR_XRGB(255,255,255),0.0f, 1.0f);
- v[14] = Vertex( 1.0f, -1.0f, 1.0f,0.0f,-1.0f,0.0f,D3DCOLOR_XRGB(255,255,255),1.0f, 1.0f);
- v[15] = Vertex(-1.0f, -1.0f, 1.0f,0.0f,-1.0f,0.0f,D3DCOLOR_XRGB(255,255,255),1.0f, 0.0f);
- // 填充左面顶点数据
- v[16] = Vertex(-1.0f, -1.0f, 1.0f,-1.0f,0.0f,0.0f,D3DCOLOR_XRGB(255,255,255),0.0f, 0.0f);
- v[17] = Vertex(-1.0f, 1.0f, 1.0f,-1.0f,0.0f,0.0f,D3DCOLOR_XRGB(255,255,255),0.0f, 1.0f);
- v[18] = Vertex(-1.0f, 1.0f, -1.0f,-1.0f,0.0f,0.0f,D3DCOLOR_XRGB(255,255,255),1.0f, 1.0f);
- v[19] = Vertex(-1.0f, -1.0f, -1.0f,-1.0f,0.0f,0.0f,D3DCOLOR_XRGB(255,255,255),1.0f, 0.0f);
- // 填充右面顶点数据
- v[20] = Vertex( 1.0f, -1.0f, -1.0f,1.0f,0.0f,0.0f,D3DCOLOR_XRGB(255,255,255),0.0f, 0.0f);
- v[21] = Vertex( 1.0f, 1.0f, -1.0f,1.0f,0.0f,0.0f,D3DCOLOR_XRGB(255,255,255),0.0f, 1.0f);
- v[22] = Vertex( 1.0f, 1.0f, 1.0f,1.0f,0.0f,0.0f,D3DCOLOR_XRGB(255,255,255),1.0f, 1.0f);
- v[23] = Vertex( 1.0f, -1.0f, 1.0f,1.0f,0.0f,0.0f,D3DCOLOR_XRGB(255,255,255),1.0f, 0.0f);
- VB->Unlock();
- // 定义三角面的立方体:
- WORD* i = 0;
- IB->Lock(0, 0, (void**)&i, 0);
- // 填充正面顶点索引数据
- i[0] = 0; i[1] = 1; i[2] = 2;
- i[3] = 0; i[4] = 2; i[5] = 3;
- // 填充背面顶点索引数据
- i[6] = 4; i[7] = 5; i[8] = 6;
- i[9] = 4; i[10] = 6; i[11] = 7;
- // 填充顶面顶点索引数据
- i[12] = 8; i[13] = 9; i[14] = 10;
- i[15] = 8; i[16] = 10; i[17] = 11;
- // 填充底面顶点索引数据
- i[18] = 12; i[19] = 13; i[20] = 14;
- i[21] = 12; i[22] = 14; i[23] = 15;
- // 填充左面顶点索引数据
- i[24] = 16; i[25] = 17; i[26] = 18;
- i[27] = 16; i[28] = 18; i[29] = 19;
- // 填充右面顶点索引数据
- i[30] = 20; i[31] = 21; i[32] = 22;
- i[33] = 20; i[34] = 22; i[35] = 23;
- IB->Unlock();
- //加载纹理
- D3DXCreateTextureFromFile(Device,"ugp.tga",&g_Texture1);
- D3DXCreateTextureFromFile(Device,"picture.tga",&g_Texture2);
- //线性过滤
- Device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
- Device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
- Device->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR);
- // 设置纹理g_Texture1的渲染状态,指定纹理颜色与顶点颜色的混合方法
- Device->SetTextureStageState(0, D3DTSS_TEXCOORDINDEX, 0);
- Device->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
- Device->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
- Device->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
- // 设置纹理g_Texture2过滤器
- Device->SetSamplerState(1, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
- Device->SetSamplerState(1, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
- Device->SetSamplerState(1, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR);
- // 设置纹理g_Texture2的渲染状态,指定纹理颜色与顶点颜色的混合方法
- Device->SetTextureStageState(1, D3DTSS_TEXCOORDINDEX, 1);
- Device->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_MODULATE);
- Device->SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
- Device->SetTextureStageState(1, D3DTSS_COLORARG2, D3DTA_CURRENT);
- //初始化灯光
- ::ZeroMemory(&g_light, sizeof(g_light));
- g_light.Type = D3DLIGHT_DIRECTIONAL;
- g_light.Ambient = D3DXCOLOR(0.8f, 0.8f, 0.8f, 1.0f);
- g_light.Diffuse = D3DXCOLOR(1.0f, 1.0f, 1.0f, 1.0f);
- g_light.Specular = D3DXCOLOR(0.2f, 0.2f, 0.2f, 1.0f);
- g_light.Direction = D3DXVECTOR3(1.0f, -1.0f, 0.0f);
- Device->SetLight(0, &g_light); //设置灯光
- Device->LightEnable(0, true); //激活灯光
- //初始化材质
- ZeroMemory(&g_material,sizeof(D3DMATERIAL9));
- g_material.Diffuse.r = 0.4f;
- g_material.Diffuse.g =0.4f;
- g_material.Diffuse.b = 0.4f;
- g_material.Ambient.r = 0.6f;
- g_material.Ambient.g = 0.6f;
- g_material.Ambient.b = 0.7f;
- g_material.Specular.r = 0.4f;
- g_material.Specular.g = 0.4f;
- g_material.Specular.b = 0.4f;
- g_material.Power = 8.0f;
- //
- // 位置和目标照相机。
- //
- D3DXMatrixLookAtLH(&V, &position, &target, &up); //摄像机函数
- Device->SetTransform(D3DTS_VIEW, &V); //转换为试图
- //
- // 投影矩阵的.
- //
- D3DXMATRIX proj;
- D3DXMatrixPerspectiveFovLH(
- &proj,
- D3DX_PI * 0.5f, // 90 - degree
- (float)Width / (float)Height,
- 1.0f,
- 1000.0f);
- Device->SetTransform(D3DTS_PROJECTION, &proj);
- //
- // 设置渲染模式。
- //
- Device->SetRenderState(D3DRS_NORMALIZENORMALS, true); //正常的渲染等级
- Device->SetRenderState(D3DRS_SPECULARENABLE, true); //镜面高光
- Device->SetRenderState(D3DRS_LIGHTING, true); //设置渲染方式
- Device->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE); // 不剔除任何面
- Device->SetRenderState(D3DRS_AMBIENT,D3DCOLOR_COLORVALUE(0.3f, 0.3f, 0.3f, 1.0f)); //设置环境光
- return true;
- }
- void Cleanup()
- {
- d3d::Release<LPDIRECT3DTEXTURE9>(g_Texture2);
- d3d::Release<LPDIRECT3DTEXTURE9>(g_Texture1);
- d3d::Release<IDirect3DVertexBuffer9*>(VB);
- d3d::Release<IDirect3DIndexBuffer9*>(IB);
- }
- void SetMatrixLookAt(D3DXVECTOR3 position,D3DXVECTOR3 target,D3DXVECTOR3 up,D3DXMATRIX V)
- {
- D3DXMatrixLookAtLH(&V, &position, &target, &up); //摄像机函数
- Device->SetTransform(D3DTS_VIEW, &V); //转换为试图
- }
- bool Display(float timeDelta)
- {
- if( Device )
- {
- //
- // 旋转立方体:
- //
- D3DXMATRIX Rx, Ry;
- // 定义x轴要旋转的角度
- static float x = 0.0f;
- D3DXMatrixRotationX(&Rx, x);
- x+=timeDelta;
- // 重置的角度对零当角度达到 2*PI也就是360°
- if(x > 2*D3DX_PI)
- { x = 0.0f; }
- // 定义y轴要旋转的角度
- static float y = 0.0f;
- D3DXMatrixRotationY(&Ry, y);
- y += timeDelta;
- // 重置的角度对零当角度达到 2*PI也就是360°
- if( y >= 2*D3DX_PI )
- y = 0.0f;
- // 结合x -和y维度旋转变换.
- D3DXMATRIX p = Rx * Ry;
- Device->SetTransform(D3DTS_WORLD, &p);
- //
- // 画现场:
- //
- Device->Clear(0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0);
- Device->BeginScene();
- if(texType==0) //设置纹理1
- {
- Device->SetTexture(0, 0);
- Device->SetTexture(1, 0);
- Device->SetTexture(0, g_Texture1);
- }
- else if(texType==1) //设置纹理2
- {
- Device->SetTexture(0, 0);
- Device->SetTexture(1, 0);
- Device->SetTexture(0, g_Texture2);
- }
- else if(texType==2) //设置多重纹理
- {
- Device->SetTexture(0, 0);
- Device->SetTexture(1, 0);
- Device->SetTexture(0, g_Texture1);
- Device->SetTexture(1, g_Texture2);
- }
- Device->SetMaterial(&g_material);
- Device->SetStreamSource(0, VB, 0, sizeof(Vertex));
- Device->SetIndices(IB);
- Device->SetFVF(Vertex::FVF);
- // 画立方体.
- Device->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, 24, 0, 12);
- Device->EndScene();
- Device->Present(0, 0, 0, 0);
- }
- return true;
- }
- //
- // 消息处理
- //
- LRESULT CALLBACK d3d::WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
- {
- switch( msg )
- {
- case WM_DESTROY:
- ::PostQuitMessage(0);
- break;
- case WM_KEYDOWN:
- switch(wParam)
- {
- case VK_ESCAPE:
- ::DestroyWindow(hwnd);break;
- case VK_UP: //摄像机位置靠近目标
- position.z+1<-1.0f?position.z+=1:position.z;
- SetMatrixLookAt(position,target,up,V);
- break;
- case VK_DOWN: //摄像机位置远离目标
- position.z-=1.0f;
- SetMatrixLookAt(position,target,up,V);
- break;
- case VK_LEFT:
- position.x+=0.1f; //摄像机向左移动,同时观察点也相应移动
- target.x+=0.1f;
- SetMatrixLookAt(position,target,up,V);
- break;
- case VK_RIGHT:
- position.x-=0.1f; //摄像机向右移动,同时观察点也相应移动
- target.x-=0.1f;
- SetMatrixLookAt(position,target,up,V);
- break;
- case VK_SPACE:
- texType=(texType==2?0:++texType);
- break;
- }
- }
- return ::DefWindowProc(hwnd, msg, wParam, lParam);
- }
- //
- // 入口函数
- //
- int WINAPI WinMain(HINSTANCE hinstance,
- HINSTANCE prevInstance,
- PSTR cmdLine,
- int showCmd)
- {
- if(!d3d::InitD3D(hinstance,
- Width, Height, true, D3DDEVTYPE_HAL, &Device))
- {
- ::MessageBox(0, "InitD3D() - FAILED", 0, 0);
- return 0;
- }
- if(!Setup())
- {
- ::MessageBox(0, "Setup() - FAILED", 0, 0);
- return 0;
- }
- d3d::EnterMsgLoop( Display );
- Cleanup();
- Device->Release();
- return 0;
- }
按空格键后变换纹理
图:多重纹理
纹理1:
纹理2: