3D游戏编程(五)

光照和材质已经使三维图形具有较强的立体感, 如果给三维网格填充上二维图形 (纹理, 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(00, (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.25f0.00f0.00f0.00f,
                            
0.00f-0.25f0.00f0.00f
,
                            
0.00f0.00f1.00f0.00f
,
                            
0.50f0.50f0.00f1.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, 0sizeof(CUSTOMVERTEX));

        
// 指定顶点着色信息(FVF)

        g_pD3DDevice->SetFVF(D3DFVF_CUSTOMVERTEX);

        
// 输出

        g_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, 02 * MAX_TRIANGLES - 2);
        
// 结束渲染

        g_pD3DDevice->EndScene();
    }


    
// 显示后置缓冲的画面
    g_pD3DDevice->Present(NULL, NULL, NULL, NULL);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值