光照和材质已经使三维图形具有较强的立体感, 如果给三维网格填充上二维图形 (纹理, Texture), 则可表现出更为逼真的场景效果.
第六步: 纹理
(一) 使用方法
1. 声明IDirect3DTecture对象;
2. 声明纹理坐标顶点;
3. 创建纹理 (文件导入或光影贴图);
4. 设置纹理层 (texture stage);
5. 指定绘制纹理;
6. 绘制网格.
#define SHOW_HOW_TO_USE_TCI
#define MAX_TRIANGLES 100
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
struct
CUSTOMVERTEX
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
...
{
D3DXVECTOR3 position; // 顶点三维坐标
D3DCOLOR color; // 顶点颜色
#ifdef SHOW_HOW_TO_USE_TCI
FLOAT tu,tv; // 纹理坐标
#endif
}
;
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
struct
CUSTOMVERTEX
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
...
{
D3DXVECTOR3 position; // 顶点三维坐标
D3DCOLOR color; // 顶点颜色
#ifdef SHOW_HOW_TO_USE_TCI
FLOAT tu,tv; // 纹理坐标
#endif
}
;
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
HRESULT InitGeometry()
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
...
{
// 由文件创建纹理
if(FAILED(D3DXCreateTextureFromFile(g_pD3DDevice, _T("yulefox.jpg"), &g_pTexture)))
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
MessageBox(NULL, _T("找不到文件:-("), _T("Tetris2007.exe"), MB_OK);
return E_FAIL;
}
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
// 创建顶点缓冲
if(FAILED(g_pD3DDevice->CreateVertexBuffer(2 * MAX_TRIANGLES * sizeof(CUSTOMVERTEX),
0, D3DFVF_CUSTOMVERTEX, D3DPOOL_DEFAULT, &g_pVB, NULL)))
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
return E_FAIL;
}
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
// 写入缓冲
// 将纹理的u, v坐标值设置在0.0~1.0之间
CUSTOMVERTEX *pVertices;
if(FAILED(g_pVB->Lock(0, 0, (void **)&pVertices, 0)))
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
return E_FAIL;
}
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
for(DWORD i=0; i<MAX_TRIANGLES; i++)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
FLOAT theta = (2 * D3DX_PI * i) / (MAX_TRIANGLES - 1);
pVertices[2*i+0].position = D3DXVECTOR3(sinf(theta), -1.0f, cosf(theta)); // 气缸上方圆
pVertices[2*i+0].color = 0xffffffff;
#ifndef SHOW_HOW_TO_USE_TCI
pVertices[2*i+0].tu = ((FLOAT)i) / (MAX_TRIANGLES - 1);
pVertices[2*i+0].tv = 1.0f;
#endif
pVertices[2*i+1].position = D3DXVECTOR3(sinf(theta), 1.0f, cosf(theta)); // 气缸下方圆
pVertices[2*i+1].color = 0xff808080;
#ifndef SHOW_HOW_TO_USE_TCI
pVertices[2*i+1].tu = ((FLOAT)i) / (MAX_TRIANGLES - 1);
pVertices[2*i+1].tv = 0.0f;
#endif
}
g_pVB->Unlock();
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
return S_OK;
}
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
void
Render()
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
...
{
......
// 开始渲染
if(SUCCEEDED(g_pD3DDevice->BeginScene()))
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
// 创建矩阵
SetupMatrices();
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
// 创建纹理层
g_pD3DDevice->SetTexture(0, g_pTexture);
g_pD3DDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
g_pD3DDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
g_pD3DDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
g_pD3DDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
#ifdef SHOW_HOW_TO_USE_TCI
// 使用摄像机坐标系的顶点信息创建纹理坐标
// 将x, y, z, TCI坐标变换为u, v坐标
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
// 将(-1.0~1.0)值变换为(0.0~1.0)值的矩阵
// tu = 0.5 * x + 0.5
// tv = -0.5 * y + 0.5
D3DXMATRIXA16 mat(0.25f, 0.00f, 0.00f, 0.00f,
0.00f, -0.25f, 0.00f, 0.00f,
0.00f, 0.00f, 1.00f, 0.00f,
0.50f, 0.50f, 0.00f, 1.00f);
g_pD3DDevice->SetTransform(D3DTS_TEXTURE0, &mat); // 纹理变换矩阵
g_pD3DDevice->SetTextureStageState(0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2); // 使用二维纹理
g_pD3DDevice->SetTextureStageState(0, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEPOSITION); // 变换摄像机坐标系
#endif
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
// 绘制顶点缓冲
// 绑定设备数据流
g_pD3DDevice->SetStreamSource(0, g_pVB, 0, sizeof(CUSTOMVERTEX));
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
// 指定顶点着色信息(FVF)
g_pD3DDevice->SetFVF(D3DFVF_CUSTOMVERTEX);
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
// 输出
g_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2 * MAX_TRIANGLES - 2);
// 结束渲染
g_pD3DDevice->EndScene();
}
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
// 显示后置缓冲的画面
g_pD3DDevice->Present(NULL, NULL, NULL, NULL);
}