概述
光照和材质已经使三维图形具有较强的立体感, 如果给三维网格填充上二维图形 (纹理, Texture), 则可表现出更为逼真的场景效果.
第六步: 纹理
(一) 使用方法
1. 声明IDirect3DTecture对象;
2. 声明纹理坐标顶点;
3. 创建纹理 (文件导入或光影贴图);
4. 设置纹理层 (texture stage);
5. 指定绘制纹理;
6. 绘制网格.
#define SHOW_HOW_TO_USE_TCI
#define MAX_TRIANGLES 100
struct CUSTOMVERTEX
... {
D3DXVECTOR3 position; // 顶点三维坐标
D3DCOLOR color; // 顶点颜色
#ifdef SHOW_HOW_TO_USE_TCI
FLOAT tu,tv; // 纹理坐标
#endif
} ;
struct CUSTOMVERTEX
... {
D3DXVECTOR3 position; // 顶点三维坐标
D3DCOLOR color; // 顶点颜色
#ifdef SHOW_HOW_TO_USE_TCI
FLOAT tu,tv; // 纹理坐标
#endif
} ;
HRESULT InitGeometry()
... {
// 由文件创建纹理
if(FAILED(D3DXCreateTextureFromFile(g_pD3DDevice, _T("yulefox.jpg"), &g_pTexture)))
...{
MessageBox(NULL, _T("找不到文件:-("), _T("Tetris2007.exe"), MB_OK);
return E_FAIL;
}
// 创建顶点缓冲
if(FAILED(g_pD3DDevice->CreateVertexBuffer(2 * MAX_TRIANGLES * sizeof(CUSTOMVERTEX),
0, D3DFVF_CUSTOMVERTEX, D3DPOOL_DEFAULT, &g_pVB, NULL)))
...{
return E_FAIL;
}
// 写入缓冲
// 将纹理的u, v坐标值设置在0.0~1.0之间
CUSTOMVERTEX *pVertices;
if(FAILED(g_pVB->Lock(0, 0, (void **)&pVertices, 0)))
...{
return E_FAIL;
}
for(DWORD i=0; i<MAX_TRIANGLES; i++)
...{
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();
return S_OK;
}
void Render()
... {
......
// 开始渲染
if(SUCCEEDED(g_pD3DDevice->BeginScene()))
...{
// 创建矩阵
SetupMatrices();
// 创建纹理层
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);
#ifdef SHOW_HOW_TO_USE_TCI
// 使用摄像机坐标系的顶点信息创建纹理坐标
// 将x, y, z, TCI坐标变换为u, v坐标
// 将(-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
// 绘制顶点缓冲
// 绑定设备数据流
g_pD3DDevice->SetStreamSource(0, g_pVB, 0, sizeof(CUSTOMVERTEX));
// 指定顶点着色信息(FVF)
g_pD3DDevice->SetFVF(D3DFVF_CUSTOMVERTEX);
// 输出
g_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2 * MAX_TRIANGLES - 2);
// 结束渲染
g_pD3DDevice->EndScene();
}
// 显示后置缓冲的画面
g_pD3DDevice->Present(NULL, NULL, NULL, NULL);
}
#define MAX_TRIANGLES 100
struct CUSTOMVERTEX
... {
D3DXVECTOR3 position; // 顶点三维坐标
D3DCOLOR color; // 顶点颜色
#ifdef SHOW_HOW_TO_USE_TCI
FLOAT tu,tv; // 纹理坐标
#endif
} ;
struct CUSTOMVERTEX
... {
D3DXVECTOR3 position; // 顶点三维坐标
D3DCOLOR color; // 顶点颜色
#ifdef SHOW_HOW_TO_USE_TCI
FLOAT tu,tv; // 纹理坐标
#endif
} ;
HRESULT InitGeometry()
... {
// 由文件创建纹理
if(FAILED(D3DXCreateTextureFromFile(g_pD3DDevice, _T("yulefox.jpg"), &g_pTexture)))
...{
MessageBox(NULL, _T("找不到文件:-("), _T("Tetris2007.exe"), MB_OK);
return E_FAIL;
}
// 创建顶点缓冲
if(FAILED(g_pD3DDevice->CreateVertexBuffer(2 * MAX_TRIANGLES * sizeof(CUSTOMVERTEX),
0, D3DFVF_CUSTOMVERTEX, D3DPOOL_DEFAULT, &g_pVB, NULL)))
...{
return E_FAIL;
}
// 写入缓冲
// 将纹理的u, v坐标值设置在0.0~1.0之间
CUSTOMVERTEX *pVertices;
if(FAILED(g_pVB->Lock(0, 0, (void **)&pVertices, 0)))
...{
return E_FAIL;
}
for(DWORD i=0; i<MAX_TRIANGLES; i++)
...{
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();
return S_OK;
}
void Render()
... {
......
// 开始渲染
if(SUCCEEDED(g_pD3DDevice->BeginScene()))
...{
// 创建矩阵
SetupMatrices();
// 创建纹理层
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);
#ifdef SHOW_HOW_TO_USE_TCI
// 使用摄像机坐标系的顶点信息创建纹理坐标
// 将x, y, z, TCI坐标变换为u, v坐标
// 将(-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
// 绘制顶点缓冲
// 绑定设备数据流
g_pD3DDevice->SetStreamSource(0, g_pVB, 0, sizeof(CUSTOMVERTEX));
// 指定顶点着色信息(FVF)
g_pD3DDevice->SetFVF(D3DFVF_CUSTOMVERTEX);
// 输出
g_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2 * MAX_TRIANGLES - 2);
// 结束渲染
g_pD3DDevice->EndScene();
}
// 显示后置缓冲的画面
g_pD3DDevice->Present(NULL, NULL, NULL, NULL);
}
最后
以上就是包容冷风为你收集整理的3D游戏编程(五) 的全部内容,希望文章能够帮你解决3D游戏编程(五) 所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复