游戏开发论坛

 找回密码
 立即注册
搜索
查看: 1750|回复: 2

显示一个正方体

[复制链接]

27

主题

93

帖子

106

积分

注册会员

Rank: 2

积分
106
发表于 2008-7-27 17:14:00 | 显示全部楼层 |阅读模式
//------------------------------------------------------------------------
// Comment: render a cube with material and texture.
// Created: atyuwen.
// Date: 2008.7.18
//------------------------------------------------------------------------

#include <Windows.h>
#include <d3d9.h>
#include <d3dx9.h>
#pragma comment(lib,"d3d9.lib")
#pragma comment(lib,"d3dx9.lib")


// 全局变量 D3D 对象接口指针
LPDIRECT3D9             g_pD3D        = NULL;
LPDIRECT3DDEVICE9       g_pd3dDevice = NULL;
LPDIRECT3DVERTEXBUFFER9 g_pVertexBuff = NULL;
LPDIRECT3DINDEXBUFFER9 g_pIndexBuff = NULL;
LPDIRECT3DTEXTURE9      g_pTexture    = NULL;

// 变换
float g_RotateAngleY;        // 绕 y 轴旋转
float g_TranslationX;        // x 方向平移
float g_TranslationY;   // y 方向平移
float g_TranslationZ;   // z 方向平移


// 前置声明
BOOL InitInstance(HINSTANCE hInstace, int nCmdShow);
LRESULT CALLBACK WinProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam );

LRESULT InitD3D(HWND hWnd); // 初始化 DirectX
LRESULT InitMatrices();      // 初始化光栅矩阵
LRESULT CreateVertexBuff(); // 创建顶点缓存
LRESULT CreateIndexBuff();   // 创建索引缓存
LRESULT CreateTexture();     // 创建纹理
void SetMaterial();          // 设置材质
void SetLighting();          // 设置光照
void RenderScene();    // 渲染
void TransformScene(WPARAM wParam, LPARAM lParam); // 变换
void Cleanup();              // 释放


//------------------------------------------------------------------------
// D3D 顶点结构
//------------------------------------------------------------------------
const DWORD VertexFomat = D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_TEX1;
struct D3D_VERTEX
{
        FLOAT x,y,z;
        D3DVECTOR normal;
        FLOAT u,v;
};


//------------------------------------------------------------------------
// 主程序入口函数
//------------------------------------------------------------------------
int WINAPI WinMain( HINSTANCE hInstance,
                                    HINSTANCE hPrevInstance,
                                    LPSTR lpCmdLine,
                                    int nShowCmd )
{
        MSG msg;

        // 创建主窗口
        if(!InitInstance(hInstance,nShowCmd))
                return FALSE;

        // 进入消息循环
        ZeroMemory( &msg, sizeof(msg) );
        while( msg.message!=WM_QUIT )
        {
                if( PeekMessage( &msg, NULL, 0U, 0U, PM_REMOVE ) )
                {
                        TranslateMessage( &msg );
                        DispatchMessage( &msg );
                }
                else
                        RenderScene();
        }
        return msg.wParam;
}


//------------------------------------------------------------------------
// 实例化一个窗口
//------------------------------------------------------------------------
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
        HWND hWnd; //窗口句柄

        WNDCLASS wc; //窗口类结构

        // 填充窗口类结构
        wc.style = CS_VREDRAW | CS_HREDRAW;
        wc.lpfnWndProc = (WNDPROC)WinProc;
        wc.cbClsExtra = 0;
        wc.cbWndExtra = 0;
        wc.hInstance = hInstance;
        wc.hIcon = LoadIcon( hInstance, IDI_APPLICATION );
        wc.hCursor = LoadCursor( NULL, IDC_ARROW );
        wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
        wc.lpszMenuName = NULL;
        wc.lpszClassName = "MyWindow";

        // 注册窗口类
        RegisterClass( &wc );

        // 创建窗口
        hWnd = CreateWindow("MyWindow",
                "D3D Sample",
                WS_OVERLAPPEDWINDOW,
                100, 100,
                512, 512,
                NULL, NULL,
                hInstance, NULL);
        if(!hWnd)
                return FALSE;

        if(!SUCCEEDED(InitD3D(hWnd))) // 如果初始化D3D失败
                return FALSE;

        CreateVertexBuff(); // 创建顶点缓存
        CreateIndexBuff(); // 创建索引缓存

        ShowWindow(hWnd, nCmdShow);
        UpdateWindow(hWnd);

        return TRUE;
}


//------------------------------------------------------------------------
// 回调函数
//------------------------------------------------------------------------
LRESULT CALLBACK WinProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam )
{
        switch (message)
        {
        case WM_KEYDOWN: // 按键
                TransformScene(wParam, lParam);
                break;

        case WM_DESTROY: // 退出
                Cleanup();
                PostQuitMessage(0);
                break;
        default:;
        }

        // 调用缺省消息处理过程
        return DefWindowProc(hWnd, message, wParam, lParam);
}


//------------------------------------------------------------------------
// DirectX初始化函数
//------------------------------------------------------------------------
LRESULT InitD3D(HWND hWnd)
{
        if( NULL == ( g_pD3D = Direct3DCreate9( D3D_SDK_VERSION ) ) )
                return E_FAIL;

        // 填写像素格式结构,类似于OpenGL中的PIXELFORMATDESCRIPTOR
        D3DPRESENT_PARAMETERS d3dpp;
        ZeroMemory( &d3dpp, sizeof(d3dpp) );
        d3dpp.Windowed = TRUE;
        d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
        d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;

        // 如果支持 设置全屏抗锯齿
        if( SUCCEEDED(g_pD3D->CheckDeviceMultiSampleType( D3DADAPTER_DEFAULT,
                D3DDEVTYPE_HAL , D3DFMT_X8R8G8B8, FALSE,
                D3DMULTISAMPLE_8_SAMPLES, NULL ) ) )
        {
                d3dpp.MultiSampleType = D3DMULTISAMPLE_8_SAMPLES;
        }


        // 创建设备
        if( FAILED( g_pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd,
                D3DCREATE_SOFTWARE_VERTEXPROCESSING,
                &d3dpp, &g_pd3dDevice ) ) )
        {
                return E_FAIL;
        }

        // 打开全屏抗锯齿
        g_pd3dDevice->SetRenderState( D3DRS_MULTISAMPLEANTIALIAS, TRUE);

        // 设置材质
        SetMaterial();

        // 设置光照
        SetLighting();

        // 设置纹理
        CreateTexture();

        return S_OK;
}


//------------------------------------------------------------------------
// DirectX绘制函数
//------------------------------------------------------------------------
void RenderScene()
{
        if( NULL == g_pd3dDevice )
                return;

        // 清屏
        g_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0,0,0), 1.0f, 0 );

        // 开始绘制
        if( SUCCEEDED( g_pd3dDevice->BeginScene()))
        {
                // Rendering of scene objects can happen here
                InitMatrices();
                g_pd3dDevice->SetStreamSource( 0, g_pVertexBuff, 0, sizeof(D3D_VERTEX) );
                g_pd3dDevice->SetFVF( VertexFomat);
                g_pd3dDevice->SetIndices(g_pIndexBuff);
                g_pd3dDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, 8, 0, 12);
                // End the scene
                g_pd3dDevice->EndScene();
        }

        // 换页
        g_pd3dDevice-&gtresent( NULL, NULL, NULL, NULL );
}

//------------------------------------------------------------------------
// 创建顶点缓存并压入数据
//------------------------------------------------------------------------
LRESULT CreateVertexBuff()
{
        D3D_VERTEX vertices[] =    // 顶点数据 正方体 8个顶点
        {
                { 0.0f, 0.0f, 0.0f, { -1.0f, -1.0f, -1.0f}, 0.0f, 0.0f },
                { 1.0f, 0.0f, 0.0f, { 1.0f, -1.0f, -1.0f}, 1.0f, 0.0f },
                { 1.0f, 0.0f, 1.0f, { 1.0f, -1.0f, 1.0f}, 1.0f, 1.0f },
                { 0.0f, 0.0f, 1.0f, { -1.0f, -1.0f, 1.0f}, 0.0f, 1.0f },
                { 0.0f, 1.0f, 0.0f, { -1.0f, 1.0f, -1.0f}, 0.0f, 1.0f },
                { 1.0f, 1.0f, 0.0f, { 1.0f, 1.0f, -1.0f}, 1.0f, 1.0f },
                { 1.0f, 1.0f, 1.0f, { 1.0f, 1.0f, 1.0f}, 1.0f, 0.0f },
                { 0.0f, 1.0f, 1.0f, { -1.0f, 1.0f, 1.0f}, 0.0f, 0.0f },
        };

        if( FAILED( g_pd3dDevice->CreateVertexBuffer( 8*sizeof(D3D_VERTEX),
                0 /*Usage*/,VertexFomat, D3DPOOL_DEFAULT, &g_pVertexBuff, NULL ) ) )
                return E_FAIL;

        VOID* pVertices;           // 锁定缓存
        if( FAILED( g_pVertexBuff->Lock( 0, sizeof(vertices), (void**)&pVertices, 0 ) ) )
                return E_FAIL;

        memcpy( pVertices, vertices, sizeof(vertices) ); // 填充数据
        g_pVertexBuff->Unlock();

        return S_OK;
}


//------------------------------------------------------------------------
// 创建索引缓存并压入数据
//------------------------------------------------------------------------
LRESULT CreateIndexBuff()
{
        // 正方体 6个面 12个三角形
        WORD indexBuff[] = { 0, 1, 2, 0, 2, 3,
                0, 4, 5, 0, 5, 1,
                4, 7, 6, 4, 6, 5,
                7, 3, 2, 7, 2, 6,
                4, 0, 3, 4, 3, 7,
                6, 2, 1, 6, 1, 5};

        if( FAILED( g_pd3dDevice->CreateIndexBuffer( 36*sizeof(WORD),
                0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &g_pIndexBuff, NULL )))
                return E_FAIL;

        VOID * pIndices;
        if( FAILED( g_pIndexBuff->Lock( 0, sizeof(indexBuff), (void**)&pIndices, 0)))
                return E_FAIL;

        memcpy( pIndices, indexBuff, sizeof(indexBuff));
        g_pIndexBuff->Unlock();

        return S_OK;
}


//------------------------------------------------------------------------
// 初始化光栅矩阵
//------------------------------------------------------------------------
LRESULT InitMatrices()
{
        // 世界矩阵
        D3DXMATRIXA16 matWorld, matRotation;
        D3DXMatrixTranslation( &matWorld, g_TranslationX , g_TranslationY, g_TranslationZ);
        D3DXMatrixRotationY(&matRotation, g_RotateAngleY);
        D3DXMatrixMultiply(&matWorld, &matWorld, &matRotation);

        g_pd3dDevice->SetTransform( D3DTS_WORLD, &matWorld );

        // 视图矩阵
        D3DXVECTOR3 vEyePt( 0.0f, 3.0f,-5.0f );
        D3DXVECTOR3 vLookatPt( 0.0f, 0.0f, 0.0f );
        D3DXVECTOR3 vUpVec( 0.0f, 1.0f, 0.0f );
        D3DXMATRIXA16 matView;
        D3DXMatrixLookAtLH( &matView, &vEyePt, &vLookatPt, &vUpVec );
        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 );

        return S_OK;
}


//------------------------------------------------------------------------
// 场景变换
//------------------------------------------------------------------------
void TransformScene(WPARAM wParam, LPARAM lParam)
{
        switch (wParam)
        {
        case VK_SPACE:   // Rotate
                g_RotateAngleY += D3DX_PI/60.0f;
                break;

        case VK_UP:      // Zoom out
                g_TranslationZ += 0.01f;
                break;
        case VK_DOWN:    // Zoom in
                g_TranslationZ -= 0.01f;
                break;
        default: break;
        }
}

//------------------------------------------------------------------------
// 设置材质
//------------------------------------------------------------------------
void SetMaterial()
{
        D3DMATERIAL9 material;
        ZeroMemory(&material, sizeof(D3DMATERIAL9));
        material.Diffuse.r = 0.8f;
        material.Diffuse.g = 0.8f;
        material.Diffuse.b = 0.8f;
        g_pd3dDevice->SetMaterial(&material);
}

//------------------------------------------------------------------------
// 设置光照
//------------------------------------------------------------------------
void SetLighting()
{
        D3DXVECTOR3 lightDir( 0, 0, 1);
        D3DLIGHT9 light;
        ZeroMemory(&light, sizeof(light));
        light.Type = D3DLIGHT_DIRECTIONAL;
        light.Ambient.r = 0.1f;
        light.Ambient.g = 0.1f;
        light.Ambient.b = 0.1f;
        light.Diffuse.r = 0.8f;
        light.Diffuse.g = 0.8f;
        light.Diffuse.b = 0.8f;
        D3DXVec3Normalize((D3DXVECTOR3*)&light.Direction, &lightDir);

        g_pd3dDevice->SetLight( 0, &light);
        g_pd3dDevice->LightEnable( 0, TRUE);
        g_pd3dDevice->SetRenderState(D3DRS_LIGHTING, TRUE);
}

//------------------------------------------------------------------------
// 创建纹理
//------------------------------------------------------------------------
LRESULT CreateTexture()
{
        if( !SUCCEEDED( D3DXCreateTextureFromFile( g_pd3dDevice, "cube.jpg" , &g_pTexture ) ) )
        {
                return E_FAIL;
        }

        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 );
        g_pd3dDevice->SetSamplerState( 0, D3DSAMP_MAXMIPLEVEL, 4);

        return S_OK;
}

//------------------------------------------------------------------------
// 释放资源
//------------------------------------------------------------------------
void Cleanup()
{
        if( g_pTexture != NULL)
                g_pTexture->Release();

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

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

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

        if( g_pD3D != NULL)
                g_pD3D->Release();
}

5

主题

755

帖子

757

积分

高级会员

Rank: 4

积分
757
发表于 2008-7-27 18:31:00 | 显示全部楼层

Re:显示一个正方体

..这个有必要贴吗??

35

主题

1735

帖子

1739

积分

金牌会员

Rank: 6Rank: 6

积分
1739
QQ
发表于 2008-7-28 08:36:00 | 显示全部楼层

Re:显示一个正方体

是啊,贴这干啥?再说有这么麻烦吗?D3DXCreateBox不就OK了?
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

作品发布|文章投稿|广告合作|关于本站|游戏开发论坛 ( 闽ICP备17032699号-3 )

GMT+8, 2026-1-21 21:03

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表