Directx9.0 学习教程5 光照
来源:互联网 发布:中国制造 知乎 编辑:程序博客网 时间:2024/05/22 01:00
光照
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 D3DDeviceLPDIRECT3DDEVICE9 g_pd3dDevice = NULL; // Our rendering deviceLPDIRECT3DVERTEXBUFFER9 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;}
0 0
- Directx9.0 学习教程5 光照
- Directx9.0 学习教程1 - 第一个程序
- Directx9.0 学习教程2 - 使用DXUT框架
- Directx9.0 学习教程4 - 坐标系以及变换知识小记
- DirectX9.0学习笔记
- Directx9.0学习笔记二
- DirectX9.0教程之ID3DXSprite篇
- DirectX9.0教程之ID3DXSprite篇[转载]
- DirectX9.0教程之ID3DXSprite篇[转载]
- DirectX9.0教程之ID3DXSprite篇
- DirectX9.0教程之ID3DXSprite篇[转载]
- DirectX9.0教程之ID3DXSprite篇[转载]
- Directx9.0 学习教程3 -图形学之创建点 线 三角形 等
- DirectX9.0 入门手册(5)
- DirectX9.0 入门手册(5)
- DirectX9.0学习(二):Direct3D基础
- DirectX9 学习(1)
- DirectX9学习(一)
- Android中Matrix的set、pre、post的区别
- windows内核编程--头文件包含的奇葩的问题
- SVN - 主干/分支
- Android Volley完全解析(二),使用Volley加载网络图片
- 微信公众平台开发(100) 2048游戏
- Directx9.0 学习教程5 光照
- niginx
- Android编译中涉及到Ant构建工具小结
- javascript中构造函数的返回值问题和new对象的过程
- Android Volley完全解析(三),定制自己的Request
- leetcode 虐我篇之(十九)Same Tree
- hdu 1081 dp
- 文章为什么不被百度收录的原因分析
- Android Volley完全解析(四),带你从源码的角度理解Volley