以MFC为框架使用D3D绘制一个立方体每个面贴不同的图片
首先需要创建一个MFC项目,然后添加D3D的相关头文件和库文件。
接下来,在应用程序类中添加以下成员变量:
LPDIRECT3D9 m_pD3D; // D3D对象指针
LPDIRECT3DDEVICE9 m_pDevice; // 设备对象指针
LPDIRECT3DVERTEXBUFFER9 m_pVB; // 顶点缓冲区指针
LPDIRECT3DTEXTURE9 m_pTexture[6]; // 纹理对象指针数组
在应用程序类的构造函数中初始化D3D对象和设备对象:
CMyApp::CMyApp() {
m_pD3D = Direct3DCreate9(D3D_SDK_VERSION);
if (m_pD3D == NULL) {
AfxMessageBox(_T("Error creating D3D object!"));
AfxAbort();
}
D3DPRESENT_PARAMETERS d3dpp;
ZeroMemory(&d3dpp, sizeof(d3dpp));
d3dpp.Windowed = TRUE;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;
d3dpp.EnableAutoDepthStencil = TRUE;
d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
HWND hWnd = AfxGetMainWnd()->GetSafeHwnd();
m_pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd,
D3DCREATE_HARDWARE_VERTEXPROCESSING, &d3dpp, &m_pDevice);
}
接下来,需要定义立方体的顶点数据和纹理坐标数据:
struct CUSTOMVERTEX {
FLOAT x, y, z;
DWORD color;
FLOAT u, v;
};
CUSTOMVERTEX g_Vertices[] = {
// Front face
{-1.0f, -1.0f, -1.0f, 0xffffffff, 0.0f, 1.0f},
{-1.0f, 1.0f, -1.0f, 0xffffffff, 0.0f, 0.0f},
{ 1.0f, 1.0f, -1.0f, 0xffffffff, 1.0f, 0.0f},
{ 1.0f, -1.0f, -1.0f, 0xffffffff, 1.0f, 1.0f},
// Back face
{-1.0f, -1.0f, 1.0f, 0xffffffff, 0.0f, 1.0f},
{ 1.0f, -1.0f, 1.0f, 0xffffffff, 1.0f, 1.0f},
{ 1.0f, 1.0f, 1.0f, 0xffffffff, 1.0f, 0.0f},
{-1.0f, 1.0f, 1.0f, 0xffffffff, 0.0f, 0.0f},
// Top face
{-1.0f, 1.0f, -1.0f, 0xffffffff, 0.0f, 1.0f},
{-1.0f, 1.0f, 1.0f, 0xffffffff, 0.0f, 0.0f},
{ 1.0f, 1.0f, 1.0f, 0xffffffff, 1.0f, 0.0f},
{ 1.0f, 1.0f, -1.0f, 0xffffffff, 1.0f, 1.0f},
// Bottom face
{-1.0f, -1.0f, -1.0f, 0xffffffff, 0.0f, 1.0f},
{ 1.0f, -1.0f, -1.0f, 0xffffffff, 1.0f, 1.0f},
{ 1.0f, -1.0f, 1.0f, 0xffffffff, 1.0f, 0.0f},
{-1.0f, -1.0f, 1.0f, 0xffffffff, 0.0f, 0.0f},
// Right face
{ 1.0f, -1.0f, -1.0f, 0xffffffff, 0.0f, 1.0f},
{ 1.0f, 1.0f, -1.0f, 0xffffffff, 0.0f, 0.0f},
{ 1.0f, 1.0f, 1.0f, 0xffffffff, 1.0f, 0.0f},
{ 1.0f, -1.0f, 1.0f, 0xffffffff, 1.0f, 1.0f},
// Left face
{-1.0f, -1.0f, -1.0f, 0xffffffff, 0.0f, 1.0f},
{-1.0f, -1.0f, 1.0f, 0xffffffff, 1.0f, 1.0f},
{-1.0f, 1.0f, 1.0f, 0xffffffff, 1.0f, 0.0f},
{-1.0f, 1.0f, -1.0f, 0xffffffff, 0.0f, 0.0f},
};
WORD g_Indices[] = {
0, 1, 2, 0, 2, 3, // Front face
4, 5, 6, 4, 6, 7, // Back face
8, 9, 10, 8, 10, 11, // Top face
12, 13, 14, 12, 14, 15, // Bottom face
16, 17, 18, 16, 18, 19, // Right face
20, 21, 22, 20, 22, 23, // Left face
};
LPCTSTR g_TextureFiles[] = {
_T("front.bmp"),
_T("back.bmp"),
_T("top.bmp"),
_T("bottom.bmp"),
_T("right.bmp"),
_T("left.bmp"),
};
在应用程序类的InitInstance函数中,需要创建顶点缓冲区和纹理对象:
BOOL CMyApp::InitInstance() {
// ...
// Create vertex buffer
if (FAILED(m_pDevice->CreateVertexBuffer(sizeof(g_Vertices),
D3DUSAGE_WRITEONLY, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1,
D3DPOOL_MANAGED, &m_pVB, NULL))) {
AfxMessageBox(_T("Error creating vertex buffer!"));
AfxAbort();
}
// Copy vertex data into buffer
VOID* pVertices;
if (FAILED(m_pVB->Lock(0, sizeof(g_Vertices), (void**)&pVertices, 0))) {
AfxMessageBox(_T("Error locking vertex buffer!"));
AfxAbort();
}
memcpy(pVertices, g_Vertices, sizeof(g_Vertices));
m_pVB->Unlock();
// Load textures
for (int i = 0; i < 6; i++) {
if (FAILED(D3DXCreateTextureFromFile(m_pDevice, g_TextureFiles[i],
&m_pTexture[i]))) {
AfxMessageBox(_T("Error loading texture!"));
AfxAbort();
}
}
// ...
}
在应用程序类的Render函数中,需要设置渲染状态和绘制立方体:
void CMyApp::Render() {
// Clear the screen and depth buffer
m_pDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER,
D3DCOLOR_XRGB(0, 0, 255), 1.0f, 0);
// Begin the scene
if (SUCCEEDED(m_pDevice->BeginScene())) {
// Set render states
m_pDevice->SetRenderState(D3DRS_LIGHTING, FALSE);
m_pDevice->SetRenderState(D3DRS_ZENABLE, TRUE);
m_pDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
m_pDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
m_pDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
m_pDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
m_pDevice->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
m_pDevice->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
// Set vertex stream
m_pDevice->SetStreamSource(0, m_pVB, 0, sizeof(CUSTOMVERTEX));
m_pDevice->SetFVF(D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1);
// Set texture
for (int i = 0; i < 6; i++) {
m_pDevice->SetTexture(0, m_pTexture[i]);
m_pDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, 24,
g_Indices + i * 6, 2);
}
// End the scene
m_pDevice->EndScene();
}
// Present the backbuffer to the screen
m_pDevice->Present(NULL, NULL, NULL, NULL);
}
最后,在应用程序类的ExitInstance函数中释放资源:
int CMyApp::ExitInstance() {
// Release resources
if (m_pTexture) {
for (int i = 0; i < 6; i++) {
if (m_pTexture[i])
m_pTexture[i]->Release();
}
}
if (m_pVB)
m_pVB->Release();
if (m_pDevice)
m_pDevice->Release();
if (m_pD3D)
m_pD3D->Release();
return CWinApp::ExitInstance();
}
这样,一个使用D3D绘制立方体,并且每个面贴不同图片的MFC应用程序就完成了
原文地址: https://www.cveoy.top/t/topic/eCM4 著作权归作者所有。请勿转载和采集!