`
阿尔萨斯
  • 浏览: 4170011 次
社区版块
存档分类
最新评论

Directx9.0 学习教程5 光照

 
阅读更多

光照

1.首先需要定义这样的顶点结构

struct CUSTOMVERTEX
{
    D3DXVECTOR3position; // 顶点
    D3DXVECTOR3normal;   // 法向量
};
// Custom flexible vertex format (FVF).
#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ|D3DFVF_NORMAL)


2.然后创建一个圆柱体顶点模型

// Create the vertex buffer.
   if( FAILED(g_pd3dDevice->CreateVertexBuffer(50 * 2 * sizeof( CUSTOMVERTEX),
                                                 0, D3DFVF_CUSTOMVERTEX,
                                                 D3DPOOL_DEFAULT, &g_pVB, NULL ) ))
   {
       return E_FAIL;
    }
 
   // Fill the vertex buffer. We arealgorithmically generating a cylinder
   // here, including the normals, which are usedfor lighting.
   CUSTOMVERTEX* pVertices;
   if( FAILED(g_pVB->Lock(0, 0, ( void** )&pVertices,0 ) ) )
       return E_FAIL;
   for( DWORDi = 0; i< 50; i++ )
   {
       FLOAT theta= ( 2 * D3DX_PI * i) / ( 50 - 1 );
       pVertices[2 * i + 0].position = D3DXVECTOR3( sinf(theta ), -1.0f, cosf(theta ) );
       pVertices[2 * i + 0].normal = D3DXVECTOR3( sinf(theta ), 0.0f, cosf(theta ) );
       pVertices[2 * i + 1].position = D3DXVECTOR3( sinf(theta ), 1.0f, cosf(theta ) );
       pVertices[2 * i + 1].normal = D3DXVECTOR3( sinf(theta ), 0.0f, cosf(theta ) );
   }
   g_pVB->Unlock();
 


3.创建灯光

// Set up a material. The material here just has thediffuse and ambient
   // colors set to yellow. Note that only onematerial can be used at a time.
   D3DMATERIAL9 mtrl;  //因为有光照,所以需要创建一个材质来接受
   ZeroMemory( &mtrl, sizeof( D3DMATERIAL9 ) );
   mtrl.Diffuse.r = mtrl.Ambient.r =1.0f;
   mtrl.Diffuse.g = mtrl.Ambient.g =1.0f;
   mtrl.Diffuse.b = mtrl.Ambient.b =0.0f;
   mtrl.Diffuse.a = mtrl.Ambient.a =1.0f;
   g_pd3dDevice->SetMaterial( &mtrl);
 
   // Set up a white, directional light, with anoscillating direction.
   // Note that many lights may be active at atime (but each one slows down
   // the rendering of our scene). However, herewe are just using one. Also,
   // we need to set the D3DRS_LIGHTINGrenderstate to enable lighting
   D3DXVECTOR3 vecDir;
   D3DLIGHT9 light;//创建灯光
   ZeroMemory( &light, sizeof( D3DLIGHT9 ) );
   light.Type= D3DLIGHT_DIRECTIONAL; //设置为平行光
   light.Diffuse.r = 1.0f;
   light.Diffuse.g = 1.0f;
   light.Diffuse.b = 1.0f;
   vecDir = D3DXVECTOR3(cosf( timeGetTime()/ 350.0f ), //方向随时间变化
                          1.0f,
                          sinf( timeGetTime()/ 350.0f ) );
   D3DXVec3Normalize( ( D3DXVECTOR3* )&light.Direction, &vecDir); //单位化方向
   light.Range= 1000.0f;//方向光这个参数无效
   g_pd3dDevice->SetLight( 0, &light);
   g_pd3dDevice->LightEnable( 0, TRUE);
   g_pd3dDevice->SetRenderState( D3DRS_LIGHTING,TRUE ); //开启光照
 
   // Finally, turn on some ambient light.
   g_pd3dDevice->SetRenderState( D3DRS_AMBIENT,0x00202020 ); //设置环境光

比较简单,

效果:


全部代码:

//-----------------------------------------------------------------------------
// File: Lights.cpp
//
// Desc: Rendering 3D geometry is much more interesting when dynamic lighting
//       is added to the scene. To use lighting in D3D, you must create one or
//       lights, setup a material, and make sure your geometry contains surface
//       normals. Lights may have a position, a color, and be of a certain type
//       such as directional (light comes from one direction), point (light
//       comes from a specific x,y,z coordinate and radiates in all directions)
//       or spotlight. Materials describe the surface of your geometry,
//       specifically, how it gets lit (diffuse color, ambient color, etc.).
//       Surface normals are part of a vertex, and are needed for the D3D's
//       internal lighting calculations.
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//-----------------------------------------------------------------------------
#include <Windows.h>
#include <mmsystem.h>
#include <d3dx9.h>
#pragma warning( disable : 4996 ) // disable deprecated warning 
#include <strsafe.h>
#pragma warning( default : 4996 )




//-----------------------------------------------------------------------------
// Global variables
//-----------------------------------------------------------------------------
LPDIRECT3D9             g_pD3D = NULL; // Used to create the D3DDevice
LPDIRECT3DDEVICE9       g_pd3dDevice = NULL; // Our rendering device
LPDIRECT3DVERTEXBUFFER9 g_pVB = NULL; // Buffer to hold vertices

// A structure for our custom vertex type. We added a normal, and omitted the
// color (which is provided by the material)
struct CUSTOMVERTEX
{
    D3DXVECTOR3 position; // The 3D position for the vertex
    D3DXVECTOR3 normal;   // The surface normal for the vertex
};

// Our custom FVF, which describes our custom vertex structure
#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ|D3DFVF_NORMAL)




//-----------------------------------------------------------------------------
// Name: InitD3D()
// Desc: Initializes Direct3D
//-----------------------------------------------------------------------------
HRESULT InitD3D( HWND hWnd )
{
    // Create the D3D object.
    if( NULL == ( g_pD3D = Direct3DCreate9( D3D_SDK_VERSION ) ) )
        return E_FAIL;

    // Set up the structure used to create the D3DDevice. Since we are now
    // using more complex geometry, we will create a device with a zbuffer.
    D3DPRESENT_PARAMETERS d3dpp;
    ZeroMemory( &d3dpp, sizeof( d3dpp ) );
    d3dpp.Windowed = TRUE;
    d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
    d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;
    d3dpp.EnableAutoDepthStencil = TRUE;
    d3dpp.AutoDepthStencilFormat = D3DFMT_D16;

    // Create the D3DDevice
    if( FAILED( g_pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd,
                                      D3DCREATE_SOFTWARE_VERTEXPROCESSING,
                                      &d3dpp, &g_pd3dDevice ) ) )
    {
        return E_FAIL;
    }

    // Turn off culling
    g_pd3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE );

    // Turn on the zbuffer
    g_pd3dDevice->SetRenderState( D3DRS_ZENABLE, TRUE );

    return S_OK;
}




//-----------------------------------------------------------------------------
// Name: InitGeometry()
// Desc: Creates the scene geometry
//-----------------------------------------------------------------------------
HRESULT InitGeometry()
{
    // Create the vertex buffer.
    if( FAILED( g_pd3dDevice->CreateVertexBuffer( 50 * 2 * sizeof( CUSTOMVERTEX ),
                                                  0, D3DFVF_CUSTOMVERTEX,
                                                  D3DPOOL_DEFAULT, &g_pVB, NULL ) ) )
    {
        return E_FAIL;
    }

    // Fill the vertex buffer. We are algorithmically generating a cylinder
    // here, including the normals, which are used for lighting.
    CUSTOMVERTEX* pVertices;
    if( FAILED( g_pVB->Lock( 0, 0, ( void** )&pVertices, 0 ) ) )
        return E_FAIL;
    for( DWORD i = 0; i < 50; i++ )
    {
        FLOAT theta = ( 2 * D3DX_PI * i ) / ( 50 - 1 );
        pVertices[2 * i + 0].position = D3DXVECTOR3( sinf( theta ), -1.0f, cosf( theta ) );
        pVertices[2 * i + 0].normal = D3DXVECTOR3( sinf( theta ), 0.0f, cosf( theta ) );
        pVertices[2 * i + 1].position = D3DXVECTOR3( sinf( theta ), 1.0f, cosf( theta ) );
        pVertices[2 * i + 1].normal = D3DXVECTOR3( sinf( theta ), 0.0f, cosf( theta ) );
    }
    g_pVB->Unlock();

    return S_OK;
}




//-----------------------------------------------------------------------------
// Name: Cleanup()
// Desc: Releases all previously initialized objects
//-----------------------------------------------------------------------------
VOID Cleanup()
{
    if( g_pVB != NULL )
        g_pVB->Release();

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

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



//-----------------------------------------------------------------------------
// Name: SetupMatrices()
// Desc: Sets up the world, view, and projection transform matrices.
//-----------------------------------------------------------------------------
VOID SetupMatrices()
{
    // Set up world matrix
    D3DXMATRIXA16 matWorld;
    D3DXMatrixIdentity( &matWorld );
    D3DXMatrixRotationX( &matWorld, D3DX_PI/4);
    g_pd3dDevice->SetTransform( D3DTS_WORLD, &matWorld );

    // Set up our view matrix. A view matrix can be defined given an eye point,
    // a point to lookat, and a direction for which way is up. Here, we set the
    // eye five units back along the z-axis and up three units, look at the
    // origin, and define "up" to be in the y-direction.
    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 );

    // For the projection matrix, we set up a perspective transform (which
    // transforms geometry from 3D view space to 2D viewport space, with
    // a perspective divide making objects smaller in the distance). To build
    // a perpsective transform, we need the field of view (1/4 pi is common),
    // the aspect ratio, and the near and far clipping planes (which define at
    // what distances geometry should be no longer be rendered).
    D3DXMATRIXA16 matProj;
    D3DXMatrixPerspectiveFovLH( &matProj, D3DX_PI / 4, 1.0f, 1.0f, 100.0f );
    g_pd3dDevice->SetTransform( D3DTS_PROJECTION, &matProj );
}




//-----------------------------------------------------------------------------
// Name: SetupLights()
// Desc: Sets up the lights and materials for the scene.
//-----------------------------------------------------------------------------
VOID SetupLights()
{
    // Set up a material. The material here just has the diffuse and ambient
    // colors set to yellow. Note that only one material can be used at a time.
    D3DMATERIAL9 mtrl;
    ZeroMemory( &mtrl, sizeof( D3DMATERIAL9 ) );
    mtrl.Diffuse.r = mtrl.Ambient.r = 1.0f;
    mtrl.Diffuse.g = mtrl.Ambient.g = 1.0f;
    mtrl.Diffuse.b = mtrl.Ambient.b = 0.0f;
    mtrl.Diffuse.a = mtrl.Ambient.a = 1.0f;
    g_pd3dDevice->SetMaterial( &mtrl );

    // Set up a white, directional light, with an oscillating direction.
    // Note that many lights may be active at a time (but each one slows down
    // the rendering of our scene). However, here we are just using one. Also,
    // we need to set the D3DRS_LIGHTING renderstate to enable lighting
    D3DXVECTOR3 vecDir;
    D3DLIGHT9 light;
    ZeroMemory( &light, sizeof( D3DLIGHT9 ) );
    light.Type = D3DLIGHT_DIRECTIONAL;
    light.Diffuse.r = 1.0f;
    light.Diffuse.g = 1.0f;
    light.Diffuse.b = 1.0f;
    vecDir = D3DXVECTOR3( cosf( timeGetTime() / 350.0f ),
                          1.0f,
                          sinf( timeGetTime() / 350.0f ) );
    D3DXVec3Normalize( ( D3DXVECTOR3* )&light.Direction, &vecDir );
    light.Range = 1000.0f;
    g_pd3dDevice->SetLight( 0, &light );
    g_pd3dDevice->LightEnable( 0, TRUE );
    g_pd3dDevice->SetRenderState( D3DRS_LIGHTING, TRUE );

    // Finally, turn on some ambient light.
    g_pd3dDevice->SetRenderState( D3DRS_AMBIENT, 0x00202020 );
}




//-----------------------------------------------------------------------------
// Name: Render()
// Desc: Draws the scene
//-----------------------------------------------------------------------------
VOID Render()
{
    // Clear the backbuffer and the zbuffer
    g_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER,
                         D3DCOLOR_XRGB( 0, 0, 255 ), 1.0f, 0 );

    // Begin the scene
    if( SUCCEEDED( g_pd3dDevice->BeginScene() ) )
    {
        // Setup the lights and materials
        SetupLights();

        // Setup the world, view, and projection matrices
        SetupMatrices();

        // Render the vertex buffer contents
        g_pd3dDevice->SetStreamSource( 0, g_pVB, 0, sizeof( CUSTOMVERTEX ) );
        g_pd3dDevice->SetFVF( D3DFVF_CUSTOMVERTEX );
        g_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, 0, 2 * 50 - 2 );

        // End the scene
        g_pd3dDevice->EndScene();
    }

    // Present the backbuffer contents to the display
    g_pd3dDevice->Present( NULL, NULL, NULL, NULL );
}




//-----------------------------------------------------------------------------
// Name: MsgProc()
// Desc: The window's message handler
//-----------------------------------------------------------------------------
LRESULT WINAPI MsgProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam )
{
    switch( msg )
    {
        case WM_DESTROY:
            Cleanup();
            PostQuitMessage( 0 );
            return 0;
    }

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




//-----------------------------------------------------------------------------
// Name: WinMain()
// Desc: The application's entry point
//-----------------------------------------------------------------------------
INT WINAPI wWinMain( HINSTANCE hInst, HINSTANCE, LPWSTR, INT )
{
    UNREFERENCED_PARAMETER( hInst );

    // Register the window class
    WNDCLASSEX wc =
    {
        sizeof( WNDCLASSEX ), CS_CLASSDC, MsgProc, 0L, 0L,
        GetModuleHandle( NULL ), NULL, NULL, NULL, NULL,
        L"D3D Tutorial", NULL
    };
    RegisterClassEx( &wc );

    // Create the application's window
    HWND hWnd = CreateWindow( L"D3D Tutorial", L"D3D Tutorial 04: Lights",
                              WS_OVERLAPPEDWINDOW, 100, 100, 300, 300,
                              NULL, NULL, wc.hInstance, NULL );

    // Initialize Direct3D
    if( SUCCEEDED( InitD3D( hWnd ) ) )
    {
        // Create the geometry
        if( SUCCEEDED( InitGeometry() ) )
        {
            // Show the window
            ShowWindow( hWnd, SW_SHOWDEFAULT );
            UpdateWindow( hWnd );

            // Enter the message loop
            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"D3D Tutorial", wc.hInstance );
    return 0;
}




分享到:
评论

相关推荐

    DirectX 9.0 3D 游戏开发编程基础

    本书主要介绍如何使用DirectX 9.0开发交互式3D图形程序,重点是游戏开发。全书首先介绍了必要的数学工具,然后讲解了相关的3D概念。其他主题几乎涵盖了Direct3D中的所有基本运算,例如图元的绘制、光照、纹理、Alpha...

    Introduction to 3D Game Programming with DirectX 9.0

    Introduction to 3D Game Programming with DirectX 9.0,中文书名为《DirectX 9.0 3D 游戏开发编程基础》,资源是这本书的英文原版,配有详细的书签目录 最后附上其中文目录 目录 第Ⅰ部分 基础知识 必备的数学...

    DirectX9.0三种灯光效果

    用DirectX画的立方体,设置了材质,纹理。用它来展示灯光效果。

    Directx9.0 3D游戏开发编程基础

    第5章 光照 第6章 纹理映射 第7章 融合技术 第8章 模板 第9章 字体 第10章 网格(一) 第11章 网格(二) 第12章 设计一个灵活的Camera类 第13章 地形绘制基础 第14章 粒子系统 第15章 拾取 第16章 高级着色...

    DIRECTX.9.0.3D游戏开发编程基础.pdf

    第5章 光照 5.1 光照的组成 5.2 材质 5.3 顶点法线 5.4 光源 5.5 例程:光照 5.6 一些附加例程 5.7 小结 第6章 纹理映射 6.1 纹理坐标 6.2 创建并启用纹理 6.3 纹理过滤器 6.4 多级渐进纹理 6.4.1 多级...

    DirectX9 3D游戏设计入门 英文版+中文版+源代码

    本书主要介绍如何使用DirectX 9.0开发交互式3D图形程序,重点是游戏开发。全书首先介绍了必要的数学工具,然后讲解了相关的3D概念。其他主题几乎涵盖了Direct3D中的所有基本运算,例如图元的绘制、光照、纹理、Alpha...

    【C++】3D场景漫游程序源码 by浅墨

    源码的配套博文是 《【Visual C++】游戏开发笔记四十七 浅墨DirectX教程十五 翱翔于三维世界:摄像机的实现》 ,文章地址为http://blog.csdn.net/zhmxy555/article/details/8657656, 点击Debug下的exe文件可以...

    【C++】3D场景漫游2.0版程序源码 by浅墨

    源码的配套博文是 《【Visual C++】游戏开发笔记四十八 浅墨DirectX教程十六 三维地形系统的实现》 ,文章地址为http://blog.csdn.net/zhmxy555/article/details/8685546, 点击Release文件夹下的exe文件可以直接...

    精通DirectX.3D图形与动画程序设计.pdf

    第五部分是附录,包括学习direct3d之前所必须掌握的基础知识和directx sdk提供的各种工具的简要说明。  本书配套光盘提供了书中所有示例程序的可执行文件、工程文件和完整源代码,以方便读者编译、调试示例程序。 ...

    【C++】3D场景漫游3.0版程序源码by浅墨

    源码的配套博文是 《【Visual C++】游戏开发四十九 浅墨DirectX教程十七 三维天空的实现》 ,文章地址为http://blog.csdn.net/zhmxy555/article/details/8715196, 点击Release文件夹下的exe文件可以直接看到运行...

    三维程序设计范例

    这是三维程序设计课程的配套范例,主要学习的是Directx,与《DirectX9.0 3D游戏开发编程基础》清华大学出版社这本书对应。涉及到图形的绘制,立方体,茶壶,环状体,旋转,光照,阴影,拾取,地形,音乐,粒子,网格...

    【C++】3D游戏场景漫游4.0版程序源码by浅墨

    源码的配套博文是 《【Visual C++】游戏开发五十 浅墨DirectX教程十八 雪花飞扬:实现唯美的粒子系统》 ,文章地址为http://blog.csdn.net/zhmxy555/article/details/8744805, 点击Release文件夹下的exe文件可以...

    【C++】3D游戏场景漫游5.0版程序源码by浅墨

    源码的配套博文是 《 【Visual C++】游戏开发五十一 浅墨DirectX教程十九 网格模型进阶之路》 ,文章地址为http://blog.csdn.net/zhmxy555/article/details/8770426, 点击Release文件夹下的exe文件可以直接看到...

Global site tag (gtag.js) - Google Analytics