纹理贴图案例
vertex.h

1 #ifndef __vertexH__ 2 #define __vertexH__ 3 4 struct Vertex 5 { 6 Vertex(){} 7 Vertex(float x, float y, float z, 8 float nx, float ny, float nz, 9 float u, float v) 10 { 11 _x = x; _y = y; _z = z; 12 _nx = nx; _ny = ny; _nz = nz; 13 _u = u; _v = v; 14 } 15 float _x, _y, _z; 16 float _nx, _ny, _nz; 17 float _u, _v; 18 }; 19 20 #define FVF_VERTEX (D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_TEX1) 21 22 #endif
Cube.h

#ifndef __CubeH__ #define __CubeH__ #include<d3dx9.h> class Cube { public: Cube(void); Cube(IDirect3DDevice9* device); bool draw(D3DXMATRIX* world,D3DMATERIAL9* mtrl,IDirect3DTexture9* tex); ~Cube(void); private: IDirect3DDevice9* _device; IDirect3DVertexBuffer9* _vb; IDirect3DIndexBuffer9* _ib; }; #endif
d3dUtility.h

////////////////////////////////////////////////////////////////////////////////////////////////// // // File: d3dUtility.h // // Author: Frank Luna (C) All Rights Reserved // // System: AMD Athlon 1800+ XP, 512 DDR, Geforce 3, Windows XP, MSVC++ 7.0 // // Desc: Provides utility functions for simplifying common tasks. // ////////////////////////////////////////////////////////////////////////////////////////////////// #ifndef __d3dUtilityH__ #define __d3dUtilityH__ #include <d3dx9.h> #include <string> namespace d3d { bool InitD3D( HINSTANCE hInstance, // [in] Application instance. int width, int height, // [in] Backbuffer dimensions. bool windowed, // [in] Windowed (true)or full screen (false). D3DDEVTYPE deviceType, // [in] HAL or REF IDirect3DDevice9** device);// [out]The created device. int EnterMsgLoop( bool (*ptr_display)(float timeDelta)); LRESULT CALLBACK WndProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam); template<class T> void Release(T t) { if( t ) { t->Release(); t = 0; } } template<class T> void Delete(T t) { if( t ) { delete t; t = 0; } } const D3DXCOLOR RED(D3DCOLOR_XRGB(255,0,0)); const D3DXCOLOR WHITE(D3DCOLOR_XRGB(255,255,255)); const D3DXCOLOR BLACK(D3DCOLOR_XRGB(0,0,0)); const D3DXCOLOR GREEN(D3DCOLOR_XRGB(0,255,0)); const D3DXCOLOR BLUE(D3DCOLOR_XRGB(0,0,255)); const D3DXCOLOR YELLOW(D3DCOLOR_XRGB(255,255,0)); const D3DXCOLOR CYAN(D3DCOLOR_XRGB(0,255,255)); const D3DXCOLOR MAGENTA(D3DCOLOR_XRGB(255,0,255)); D3DMATERIAL9 InitMtrl(D3DXCOLOR a,D3DXCOLOR d,D3DXCOLOR s,D3DXCOLOR e,float p); //5.定义材质常量 const D3DMATERIAL9 RED_MTRL=InitMtrl(d3d::RED,d3d::RED,d3d::RED,d3d::BLACK,2.0f); const D3DMATERIAL9 WHITE_MTRL=InitMtrl(WHITE,WHITE,WHITE,BLACK,2.0f); const D3DMATERIAL9 GREEN_MTRL=InitMtrl(GREEN,GREEN,GREEN,BLACK,2.0f); const D3DMATERIAL9 YELLOW_MTRL=InitMtrl(YELLOW,YELLOW,YELLOW,BLACK,2.0f); const D3DMATERIAL9 BLUE_MTRL=InitMtrl(BLUE,BLUE,BLUE,BLACK,2.0f); D3DLIGHT9 InitSpotLight(D3DXVECTOR3* position,D3DXVECTOR3* direction,D3DXCOLOR* color); D3DLIGHT9 InitDirectionalLight(D3DXVECTOR3* direction,D3DXCOLOR* color); D3DLIGHT9 InitPointLight(D3DXVECTOR3* position,D3DXCOLOR* color); } #endif // __d3dUtilityH__
Cube.cpp

#include "Cube.h" #include "vertex.h" Cube::Cube(void) { } Cube::Cube(IDirect3DDevice9* device) { _device = device; _device->CreateVertexBuffer(24 * sizeof(Vertex),//24个顶点,6个面*4个点 D3DUSAGE_WRITEONLY, FVF_VERTEX, D3DPOOL_MANAGED, &_vb, 0); Vertex* v; _vb->Lock(0,0,(void**)&v,0); // fill in the front face vertex data v[0] = Vertex(-1.0f, -1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f);//顶点坐标,法线坐标,纹理坐标 v[1] = Vertex(-1.0f, 1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 1.0f); v[2] = Vertex( 1.0f, 1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 1.0f, 1.0f); v[3] = Vertex( 1.0f, -1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f); // fill in the back face vertex data v[4] = Vertex(-1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f); v[5] = Vertex( 1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f); v[6] = Vertex( 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f); v[7] = Vertex(-1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f); // fill in the top face vertex data v[8] = Vertex(-1.0f, 1.0f, -1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f); v[9] = Vertex(-1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f); v[10] = Vertex( 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f); v[11] = Vertex( 1.0f, 1.0f, -1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f); // fill in the bottom face vertex data v[12] = Vertex(-1.0f, -1.0f, -1.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f); v[13] = Vertex( 1.0f, -1.0f, -1.0f, 0.0f, -1.0f, 0.0f, 0.0f, 1.0f); v[14] = Vertex( 1.0f, -1.0f, 1.0f, 0.0f, -1.0f, 0.0f, 1.0f, 1.0f); v[15] = Vertex(-1.0f, -1.0f, 1.0f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f); // fill in the left face vertex data v[16] = Vertex(-1.0f, -1.0f, 1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f); v[17] = Vertex(-1.0f, 1.0f, 1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f); v[18] = Vertex(-1.0f, 1.0f, -1.0f, -1.0f, 0.0f, 0.0f, 1.0f, 1.0f); v[19] = Vertex(-1.0f, -1.0f, -1.0f, -1.0f, 0.0f, 0.0f, 1.0f, 0.0f); // fill in the right face vertex data v[20] = Vertex( 1.0f, -1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f); v[21] = Vertex( 1.0f, 1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f); v[22] = Vertex( 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f); v[23] = Vertex( 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f); _vb->Unlock(); //创建索引缓存 _device->CreateIndexBuffer(36*sizeof(WORD),//每个面两个三角形,6个面*2个三角形*3个顶点 D3DUSAGE_WRITEONLY, D3DFMT_INDEX16, D3DPOOL_MANAGED, &_ib, 0); WORD* i=0; _ib->Lock(0,0,(void**)&i,0); // fill in the front face index data i[0] = 0; i[1] = 1; i[2] = 2; i[3] = 0; i[4] = 2; i[5] = 3; // fill in the back face index data i[6] = 4; i[7] = 5; i[8] = 6; i[9] = 4; i[10] = 6; i[11] = 7; // fill in the top face index data i[12] = 8; i[13] = 9; i[14] = 10; i[15] = 8; i[16] = 10; i[17] = 11; // fill in the bottom face index data i[18] = 12; i[19] = 13; i[20] = 14; i[21] = 12; i[22] = 14; i[23] = 15; // fill in the left face index data i[24] = 16; i[25] = 17; i[26] = 18; i[27] = 16; i[28] = 18; i[29] = 19; // fill in the right face index data i[30] = 20; i[31] = 21; i[32] = 22; i[33] = 20; i[34] = 22; i[35] = 23; _ib->Unlock(); } Cube::~Cube(void) { } bool Cube::draw(D3DXMATRIX* world, D3DMATERIAL9* mtrl, IDirect3DTexture9* tex) { if(world) _device->SetTransform(D3DTS_WORLD, world); if(mtrl) _device->SetMaterial(mtrl); if(tex) _device->SetTexture(0,tex); _device->SetStreamSource(0,_vb,0,sizeof(Vertex)); _device->SetIndices(_ib); _device->SetFVF(FVF_VERTEX); _device->DrawIndexedPrimitive(D3DPT_TRIANGLELIST,0,0,24,0,12); return true; }
d3dInit.cpp

////////////////////////////////////////////////////////////////////////////////////////////////// // // File: d3dinit.cpp // // Author: Frank Luna (C) All Rights Reserved // // System: AMD Athlon 1800+ XP, 512 DDR, Geforce 3, Windows XP, MSVC++ 7.0 // // Desc: Demonstrates how to initialize Direct3D, how to use the book's framework // functions, and how to clear the screen to black. Note that the Direct3D // initialization code is in the d3dUtility.h/.cpp files. // ////////////////////////////////////////////////////////////////////////////////////////////////// #include "d3dUtility.h" #pragma comment(lib, "d3d9.lib") #pragma comment(lib, "d3dx9.lib") #pragma comment(lib, "winmm.lib") // // Globals // #include "Cube.h" IDirect3DDevice9* Device = 0; // // Framework Functions // const int Width=640; const int Height=480; float angle=0.0f; Cube* Box = 0; IDirect3DTexture9* Tex = 0; bool Setup() { Box = new Cube(Device); //灯光 D3DLIGHT9 light; ::ZeroMemory(&light,sizeof(light)); light.Type = D3DLIGHT_DIRECTIONAL; light.Ambient = D3DXCOLOR(0.8f, 0.8f, 0.8f, 1.0f); light.Diffuse = D3DXCOLOR(1.0f, 1.0f, 1.0f, 1.0f); light.Specular = D3DXCOLOR(0.2f, 0.2f, 0.2f, 1.0f); light.Direction = D3DXVECTOR3(1.0f,-1.0f,0.0f); Device->SetLight(0,&light); Device->LightEnable(0,true); Device->SetRenderState(D3DRS_NORMALIZENORMALS, true); Device->SetRenderState(D3DRS_SPECULARENABLE, true); D3DXCreateTextureFromFile( Device, L"crate.jpg", &Tex); Device->SetSamplerState(0,D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); Device->SetSamplerState(0,D3DSAMP_MINFILTER, D3DTEXF_LINEAR); Device->SetSamplerState(0,D3DSAMP_MIPFILTER, D3DTEXF_LINEAR); //摄像机的位置和角度 D3DXVECTOR3 position(0.0f,2.0f,-5.0f); D3DXVECTOR3 target(0.0f,0.0f,0.0f); D3DXVECTOR3 up(0.0f,1.0f,0.0f); D3DXMATRIX V; D3DXMatrixLookAtLH(&V,&position,&target,&up); Device->SetTransform(D3DTS_VIEW,&V); //投影 D3DXMATRIX proj; D3DXMatrixPerspectiveFovLH( &proj, D3DX_PI*0.5f, (float)Width/(float)Height, 1.0f, 1000.0f); Device->SetTransform(D3DTS_PROJECTION,&proj); //Device->SetRenderState(D3DRS_FILLMODE,D3DFILL_WIREFRAME); //Device->SetRenderState(D3DRS_FILLMODE,D3DFILL_WIREFRAME); return true; } void Cleanup() { d3d::Delete<Cube*>(Box); d3d::Release<IDirect3DTexture9*>(Tex); } bool Display(float timeDelta) { if( Device ) // Only use Device methods if we have a valid device. { D3DXMATRIX yRot; angle+=0.001f; D3DXMatrixRotationY(&yRot,angle); Device->SetTransform(D3DTS_WORLD, &yRot); Device->Clear(0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0); Device->BeginScene(); Device->SetMaterial(&d3d::WHITE_MTRL); Device->SetTexture(0,Tex); Box->draw(0,0,0); Device->EndScene(); Device->Present(0, 0, 0, 0); } return true; } // // WndProc // LRESULT CALLBACK d3d::WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { switch( msg ) { case WM_DESTROY: ::PostQuitMessage(0); break; case WM_KEYDOWN: if( wParam == VK_ESCAPE ) ::DestroyWindow(hwnd); break; } return ::DefWindowProc(hwnd, msg, wParam, lParam); } // // WinMain // int WINAPI WinMain(HINSTANCE hinstance, HINSTANCE prevInstance, PSTR cmdLine, int showCmd) { if(!d3d::InitD3D(hinstance, 640, 480, true, D3DDEVTYPE_HAL, &Device)) { ::MessageBox(0, L"InitD3D() - FAILED", 0, 0); return 0; } if(!Setup()) { ::MessageBox(0, L"Setup() - FAILED", 0, 0); return 0; } d3d::EnterMsgLoop( Display ); Cleanup(); Device->Release(); return 0; }
d3dUtility.cpp

////////////////////////////////////////////////////////////////////////////////////////////////// // // File: d3dUtility.cpp // // Author: Frank Luna (C) All Rights Reserved // // System: AMD Athlon 1800+ XP, 512 DDR, Geforce 3, Windows XP, MSVC++ 7.0 // // Desc: Provides utility functions for simplifying common tasks. // ////////////////////////////////////////////////////////////////////////////////////////////////// #include "d3dUtility.h" bool d3d::InitD3D( HINSTANCE hInstance, int width, int height, bool windowed, D3DDEVTYPE deviceType, IDirect3DDevice9** device) { // // Create the main application window. // WNDCLASS wc; wc.style = CS_HREDRAW | CS_VREDRAW; wc.lpfnWndProc = (WNDPROC)d3d::WndProc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = hInstance; wc.hIcon = LoadIcon(0, IDI_APPLICATION); wc.hCursor = LoadCursor(0, IDC_ARROW); wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); wc.lpszMenuName = 0; wc.lpszClassName = L"Direct3D9App"; if( !RegisterClass(&wc) ) { ::MessageBox(0, L"RegisterClass() - FAILED", 0, 0); return false; } HWND hwnd = 0; hwnd = ::CreateWindow(L"Direct3D9App", L"Direct3D9App", WS_EX_TOPMOST, 0, 0, width, height, 0 /*parent hwnd*/, 0 /* menu */, hInstance, 0 /*extra*/); if( !hwnd ) { ::MessageBox(0, L"CreateWindow() - FAILED", 0, 0); return false; } ::MoveWindow(hwnd,2250,80,640, 480,true); ::ShowWindow(hwnd, SW_SHOW); ::UpdateWindow(hwnd); // // Init D3D: // HRESULT hr = 0; // Step 1: Create the IDirect3D9 object. IDirect3D9* d3d9 = 0; d3d9 = Direct3DCreate9(D3D_SDK_VERSION); if( !d3d9 ) { ::MessageBox(0, L"Direct3DCreate9() - FAILED", 0, 0); return false; } // Step 2: Check for hardware vp. D3DCAPS9 caps; d3d9->GetDeviceCaps(D3DADAPTER_DEFAULT, deviceType, &caps); int vp = 0; if( caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT ) vp = D3DCREATE_HARDWARE_VERTEXPROCESSING; else vp = D3DCREATE_SOFTWARE_VERTEXPROCESSING; // Step 3: Fill out the D3DPRESENT_PARAMETERS structure. D3DPRESENT_PARAMETERS d3dpp; d3dpp.BackBufferWidth = width; d3dpp.BackBufferHeight = height; d3dpp.BackBufferFormat = D3DFMT_A8R8G8B8; d3dpp.BackBufferCount = 1; d3dpp.MultiSampleType = D3DMULTISAMPLE_NONE; d3dpp.MultiSampleQuality = 0; d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; d3dpp.hDeviceWindow = hwnd; d3dpp.Windowed = windowed; d3dpp.EnableAutoDepthStencil = true; d3dpp.AutoDepthStencilFormat = D3DFMT_D24S8; d3dpp.Flags = 0; d3dpp.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT; d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; // Step 4: Create the device. hr = d3d9->CreateDevice( D3DADAPTER_DEFAULT, // primary adapter deviceType, // device type hwnd, // window associated with device vp, // vertex processing &d3dpp, // present parameters device); // return created device if( FAILED(hr) ) { // try again using a 16-bit depth buffer d3dpp.AutoDepthStencilFormat = D3DFMT_D16; hr = d3d9->CreateDevice( D3DADAPTER_DEFAULT, deviceType, hwnd, vp, &d3dpp, device); if( FAILED(hr) ) { d3d9->Release(); // done with d3d9 object ::MessageBox(0, L"CreateDevice() - FAILED", 0, 0); return false; } } d3d9->Release(); // done with d3d9 object return true; } int d3d::EnterMsgLoop( bool (*ptr_display)(float timeDelta) ) { MSG msg; ::ZeroMemory(&msg, sizeof(MSG)); static float lastTime = (float)timeGetTime(); while(msg.message != WM_QUIT) { if(::PeekMessage(&msg, 0, 0, 0, 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; } //4.定义材质函数,具体的函数实现在d3dUtility.cpp源文件中 D3DMATERIAL9 d3d::InitMtrl(D3DXCOLOR a,D3DXCOLOR d,D3DXCOLOR s,D3DXCOLOR e,float p) { D3DMATERIAL9 mtrl; //剪切聚光灯.cpp文件的相应材质定义语句 /*Mtrls[0].Ambient=d3d::RED; Mtrls[0].Diffuse=d3d::RED; Mtrls[0].Specular=d3d::RED; Mtrls[0].Power=2.0f; Mtrls[0].Emissive=d3d::BLACK;*/ //要做相应修改,数组改成局部变量,后面的符号常量,在这里改成参数 mtrl.Ambient=a; mtrl.Diffuse=d; mtrl.Specular=s; mtrl.Power=p; mtrl.Emissive=e; return mtrl; } D3DLIGHT9 d3d::InitSpotLight(D3DXVECTOR3* position,D3DXVECTOR3* direction,D3DXCOLOR *color) { D3DLIGHT9 light; ::ZeroMemory(&light,sizeof(light)); light.Type=D3DLIGHT_SPOT; light.Ambient=*color*0.0f; light.Diffuse=*color; light.Specular=*color*0.6f; light.Position=*position; light.Direction=*direction; light.Range=1000.0f; light.Falloff=1.0f; light.Attenuation0=1.0f; light.Attenuation1=0.0f; light.Attenuation2=0.0f; light.Theta=0.4f; light.Phi=0.9f; return light; } D3DLIGHT9 d3d::InitDirectionalLight(D3DXVECTOR3* direction,D3DXCOLOR *color) { D3DLIGHT9 light; ::ZeroMemory(&light,sizeof(light));//用Windows函数先清零 light.Type=D3DLIGHT_DIRECTIONAL; light.Ambient=*color*0.6f;//环境光,就使用方法给它乘以0.6 light.Diffuse=*color;//漫射光 light.Specular=*color*0.6f;//镜面光,高亮度数是0.6倍 light.Direction=*direction; return light; } D3DLIGHT9 d3d::InitPointLight(D3DXVECTOR3* position,D3DXCOLOR *color) { D3DLIGHT9 light; ::ZeroMemory(&light,sizeof(light));//用Windows函数先清零 light.Type=D3DLIGHT_POINT; light.Ambient=*color*0.6f;//没有环境光,就使用方法给它乘以0.6 light.Diffuse=*color;//漫射光 light.Specular=*color*0.6f;//镜面光,高亮度数是0.6倍 light.Position=*position; light.Range=1000.0f; light.Falloff=1.0f;//衰减率 light.Attenuation0=1.0f; light.Attenuation1=0.0f; light.Attenuation2=0.0f; return light; }
扩展:实现三个箱子在空中旋转
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了