现在的位置: 首页 > 综合 > 正文

directx中给多边形的正反面贴上不同的纹理

2011年04月18日 ⁄ 综合 ⁄ 共 6687字 ⁄ 字号 评论关闭
//=============================================================================
// Desc: 最简单的Direct3D程序,
//=============================================================================
#include <d3d9.h>
#pragma comment(lib,"d3d9.lib")
#include <d3dx9.h>
#pragma comment(lib,"d3dx9.lib")
#include <tchar.h>
//-----------------------------------------------------------------------------
// 全局变量
//-----------------------------------------------------------------------------
LPDIRECT3D9             g_pD3D       = NULL;  //Direct3D对象
LPDIRECT3DDEVICE9       g_pd3dDevice = NULL;  //Direct3D设备对象
LPDIRECT3DVERTEXBUFFER9 g_pd3dVerText1 = NULL; //顶点缓冲区
LPDIRECT3DVERTEXBUFFER9 g_pd3dVerText2 = NULL; //顶点缓冲区
LPDIRECT3DTEXTURE9    g_pd3dTexture1 = NULL;
LPDIRECT3DTEXTURE9    g_pd3dTexture2 = NULL;
int g_nRotateY = 0;    //实体的旋转角度
UINT_PTR g_nTimer = 0;
//定义FVF的顶点结构
struct CUSTOMVERTEXT
{
    float x,y,z; //顶点坐标
    float u,v;    //纹理
};
//d定义FVF用到的数据项:坐标,颜色
#define D3DFVF_CUSTOMVERTEXT (D3DFVF_XYZ | D3DFVF_TEX1)
//该函数用于设置旋转矩阵
void SetupMatrices()
{
    float angle = g_nRotateY*D3DX_PI/180; //把旋转角度换算成弧度
    D3DXMATRIX matWorld;
    //计算世界变化矩阵
    D3DXMatrixRotationY(&matWorld,angle);

    //把世界变换矩阵设置到渲染环境
    g_pd3dDevice->SetTransform(D3DTS_WORLD,&matWorld);

    D3DXVECTOR3 eye(0.0f,0.0f,4.0f);    //观察点
    D3DXVECTOR3 lookat(0.0f,0.0f,0.0f); //视线目标点
    D3DXVECTOR3 up(0.0f,1.0f,0.0f);        //上方向
    D3DXMATRIX matView;
    //计算视角变换矩阵
    D3DXMatrixLookAtLH(&matView,&eye,&lookat,&up);
    //把视角变换矩阵设置到渲染环境
    g_pd3dDevice->SetTransform(D3DTS_VIEW,&matView);

    D3DXMATRIXA16 matProj;
    //计算透视投影变换矩阵
    D3DXMatrixPerspectiveFovLH(&matProj,D3DX_PI/4,1.0f,1.0f,100.0f);
    //把投影变换矩阵设置到渲染环境
    g_pd3dDevice->SetTransform(D3DTS_PROJECTION,&matProj);
}
//-----------------------------------------------------------------------------
// Desc: 初始化Direct3D
//-----------------------------------------------------------------------------
HRESULT InitD3D( HWND hWnd )
{
    //创建Direct3D对象, 该对象用来创建Direct3D设备对象
    if( NULL == ( g_pD3D = Direct3DCreate9(D3D_SDK_VERSION)) )
        return E_FAIL;

    //设置D3DPRESENT_PARAMETERS结构, 准备创建Direct3D设备对象
    D3DPRESENT_PARAMETERS d3dpp; 
    ZeroMemory( &d3dpp, sizeof(d3dpp) );
    d3dpp.Windowed = TRUE;
    d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
    d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;
    d3dpp.MultiSampleType = D3DMULTISAMPLE_8_SAMPLES;
    //创建Direct3D设备对象
    if( FAILED( g_pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd,
                                      D3DCREATE_SOFTWARE_VERTEXPROCESSING,
                                      &d3dpp, &g_pd3dDevice ) ) )
    {
        return E_FAIL;
    }
    //因为使用顶点颜色渲染,所以要禁用光照
    g_pd3dDevice->SetRenderState(D3DRS_LIGHTING,FALSE);
    //关闭挑选功能,允许渲染背面
    //g_pd3dDevice->SetRenderState(D3DRS_CULLMODE,D3DCULL_NONE);

    g_pd3dDevice->SetSamplerState(0,D3DSAMP_MAGFILTER,D3DTEXF_ANISOTROPIC);
    g_pd3dDevice->SetSamplerState(0,D3DSAMP_MINFILTER,D3DTEXF_ANISOTROPIC);

    g_pd3dDevice->SetRenderState(D3DRS_MULTISAMPLEANTIALIAS, TRUE);
    return S_OK;
}

//建模
HRESULT BuildModel1()
{
    //三角形尸体的数值模型
    CUSTOMVERTEXT vertices[] = 
    {
        //正面
        { -1.0f, -1.0f, 0.0f, 0.0f,1.0f},  // 点A,红色 
        { -1.0f, 1.0f, 0.0f, 0.0f,0.0f}, //点B ,绿色 
        {  1.0f, 1.0f, 0.0f, 1.0f,0.0f},
        {  1.0f, -1.0f, 0.0f, 1.0f,1.0f}
    };//点C,浅蓝

    //创建顶点缓冲区
    if (FAILED(    g_pd3dDevice->CreateVertexBuffer(
        sizeof(vertices), //缓冲区尺寸
0,D3DFVF_CUSTOMVERTEXT,D3DPOOL_DEFAULT,&g_pd3dVerText1,NULL)))
    {
        return E_FAIL;
    }
    //将顶点数据填入顶点缓冲区
    void* pVertices;
    if (FAILED(g_pd3dVerText1->Lock(0,sizeof(vertices),(void**)&pVertices,0)))
    {
        return E_FAIL;
    }
    memcpy(pVertices,vertices,sizeof(vertices));
    g_pd3dVerText1->Unlock();

    if (FAILED(D3DXCreateTextureFromFile(g_pd3dDevice,_T("z.png"),&g_pd3dTexture1)))
    {
        return E_FAIL;
    }
    return S_OK;
}

HRESULT BuildModel2()
{
    //三角形尸体的数值模型
    CUSTOMVERTEXT vertices[] = 
    {
        //正面
        { -1.0f, -1.0f, 0.0f,1.0f,1.0f},  // 点A,红色 
        { 1.0f, -1.0f, 0.0f,0.0f,1.0f},   //点B ,绿色 
        {  1.0f, 1.0f, 0.0f,0.0f,0.0f},
        {  -1.0f, 1.0f, 0.0f,1.0f,0.0f}
    };//点C,浅蓝

    //创建顶点缓冲区
    if (FAILED(    g_pd3dDevice->CreateVertexBuffer(
        sizeof(vertices), //缓冲区尺寸
0,D3DFVF_CUSTOMVERTEXT,
        D3DPOOL_DEFAULT,
        &g_pd3dVerText2,NULL)))
    {
        return E_FAIL;
    }
    //将顶点数据填入顶点缓冲区
    void* pVertices;
    if (FAILED(g_pd3dVerText2->Lock(0,sizeof(vertices),(void**)&pVertices,0)))
    {
        return E_FAIL;
    }
    memcpy(pVertices,vertices,sizeof(vertices));
    g_pd3dVerText2->Unlock();
    if (FAILED(D3DXCreateTextureFromFile(g_pd3dDevice,_T("f.png"),&g_pd3dTexture2)))
    {
        return E_FAIL;
    }
    return S_OK;
}


//-----------------------------------------------------------------------------
// Desc: 释放创建对象
//-----------------------------------------------------------------------------
VOID Cleanup()
{
    if (g_pd3dTexture1 != NULL)
        g_pd3dTexture1->Release();

    if (g_pd3dTexture2 != NULL)
        g_pd3dTexture2->Release();

    if (g_pd3dVerText1 != NULL)
        g_pd3dVerText1->Release();

    if (g_pd3dVerText2 != NULL)
        g_pd3dVerText2->Release();

    //释放Direct3D设备对象
    if( g_pd3dDevice != NULL) 
        g_pd3dDevice->Release();

    //释放Direct3D对象
    if( g_pD3D != NULL)
        g_pD3D->Release();
}


//-----------------------------------------------------------------------------
// Desc: 渲染图形
//-----------------------------------------------------------------------------
VOID Render()
{
    //清空后台缓冲区
    g_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(255,255,255), 1.0f, 0 );
    
    //开始在后台缓冲区绘制图形
    if( SUCCEEDED( g_pd3dDevice->BeginScene() ) )
    {
        //在此在后台缓冲区绘制图形
        SetupMatrices(); 
        //设置自定义的FVF
        g_pd3dDevice->SetFVF(D3DFVF_CUSTOMVERTEXT);

        g_pd3dDevice->SetStreamSource(0,g_pd3dVerText2,0,sizeof(CUSTOMVERTEXT));
        g_pd3dDevice->SetTexture(0,g_pd3dTexture2);
        g_pd3dDevice->DrawPrimitive(D3DPT_TRIANGLEFAN,0,2);        
        
        g_pd3dDevice->SetStreamSource(0,g_pd3dVerText1,0,sizeof(CUSTOMVERTEXT));
        g_pd3dDevice->SetTexture(0,g_pd3dTexture1);
        g_pd3dDevice->DrawPrimitive(D3DPT_TRIANGLEFAN,0,2);


        //结束在后台缓冲区渲染图形
        g_pd3dDevice->EndScene();
    }

    //将在后台缓冲区绘制的图形提交到前台缓冲区显示
    g_pd3dDevice->Present( NULL, NULL, NULL, NULL );
}

//

//-----------------------------------------------------------------------------
// Desc: 消息处理
//-----------------------------------------------------------------------------
LRESULT WINAPI MsgProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam )
{
    switch( msg )
    {
        case WM_DESTROY:
            {
                KillTimer(hWnd,g_nTimer);
                Cleanup();
                PostQuitMessage( 0 );
                return 0;
            }

        case WM_PAINT:
            {
                Render();
                ValidateRect( hWnd, NULL );
                return 0;
            }
        case WM_CREATE:
            {
                g_nTimer = SetTimer(hWnd,1,40,NULL);
            }break;
        case WM_TIMER:
            {
                g_nRotateY += 2; //每次旋转2度
                InvalidateRect(hWnd,NULL,TRUE);
                UpdateWindow(hWnd);
            }break;
    }

    return DefWindowProc( hWnd, msg, wParam, lParam );
}


//-----------------------------------------------------------------------------
// Desc: 程序入口
//-----------------------------------------------------------------------------
INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR, INT )
{
    //注册窗口类
    WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, MsgProc, 0L, 0L, 
                      GetModuleHandle(NULL), NULL, NULL, NULL, NULL,
                      L"ClassName", NULL };
    RegisterClassEx( &wc );

    //创建窗口
    HWND hWnd = CreateWindow( L"ClassName", L"最简单的Direct3D程序", 
                              WS_OVERLAPPEDWINDOW, 200, 100, 600, 500,
                              NULL, NULL, wc.hInstance, NULL );

    //初始化Direct3D
    if( SUCCEEDED( InitD3D( hWnd ) ) && SUCCEEDED(BuildModel1()) && SUCCEEDED(BuildModel2()))
    { 
        //显示主窗口
        ShowWindow( hWnd, SW_SHOWDEFAULT );
        UpdateWindow( hWnd );

        //进入消息循环
        MSG msg;
        ZeroMemory( &msg, sizeof(msg) );
        while( msg.message!=WM_QUIT )
        {
            if( PeekMessage( &msg, NULL, 0U, 0U, PM_REMOVE ) )
            {
                TranslateMessage( &msg );
                DispatchMessage( &msg );
            }
            else
            {
                Render();  //渲染图形
            }
        }
    }

    UnregisterClass( L"ClassName", wc.hInstance );
    return 0;
}

 

效果图:

【上篇】
【下篇】

抱歉!评论已关闭.