DirectX 中的光照
来源:互联网 发布:macbook windows快捷键 编辑:程序博客网 时间:2024/05/11 05:19
DirectX 中的光照
给一个场景添加光照的步骤为:
(1)激活光照模型
(2)为每一个物体创建材质,并在渲染前设置相应的材质
(3)创建光源
(4)打开光照状态,如镜面高光等。
源代码:
litPyramid.cpp
- #include "d3dUtility.h"
- //
- // Globals
- //
- IDirect3DDevice9* Device = 0;
- const int Width = 640;
- const int Height = 480;
- IDirect3DVertexBuffer9* Pyramid = 0;
- /*
- Classes and structures
- */
- //定义Vertex 类型
- struct Vertex
- {
- Vertex(){}
- Vertex(float x,float y,float z,
- float nx,float ny,float nz)
- {
- _x = x ; _y = y ;_z= z;
- _nx = nx;_ny = ny; _nz = nz;
- }
- float _x,_y,_z;
- float _nx,_ny,_nz;
- static const DWORD FVF;
- };
- const DWORD Vertex::FVF =D3DFVF_XYZ|D3DFVF_NORMAL;
- //
- // Framework Functions
- //
- bool Setup()
- {
- //开启光照
- Device->SetRenderState(D3DRS_LIGHTING,true);
- //为Pyramid创建vertex buffer
- Device->CreateVertexBuffer(
- 12*sizeof(Vertex),
- D3DUSAGE_WRITEONLY,
- Vertex::FVF,
- D3DPOOL_MANAGED,
- &Pyramid,
- 0);
- //用Pyramid数据填充vertex buffer
- Vertex* v;
- Pyramid->Lock(0,0,(void**)&v,0);
- v[0] = Vertex(-1.0f, 0.0f, -1.0f, 0.0f, 0.707f, -0.707f);
- v[1] = Vertex( 0.0f, 1.0f, 0.0f, 0.0f, 0.707f, -0.707f);
- v[2] = Vertex( 1.0f, 0.0f, -1.0f, 0.0f, 0.707f, -0.707f);
- // left face
- v[3] = Vertex(-1.0f, 0.0f, 1.0f, -0.707f, 0.707f, 0.0f);
- v[4] = Vertex( 0.0f, 1.0f, 0.0f, -0.707f, 0.707f, 0.0f);
- v[5] = Vertex(-1.0f, 0.0f, -1.0f, -0.707f, 0.707f, 0.0f);
- // right face
- v[6] = Vertex( 1.0f, 0.0f, -1.0f, 0.707f, 0.707f, 0.0f);
- v[7] = Vertex( 0.0f, 1.0f, 0.0f, 0.707f, 0.707f, 0.0f);
- v[8] = Vertex( 1.0f, 0.0f, 1.0f, 0.707f, 0.707f, 0.0f);
- // back face
- v[9] = Vertex( 1.0f, 0.0f, 1.0f, 0.0f, 0.707f, 0.707f);
- v[10] = Vertex( 0.0f, 1.0f, 0.0f, 0.0f, 0.707f, 0.707f);
- v[11] = Vertex(-1.0f, 0.0f, 1.0f, 0.0f, 0.707f, 0.707f);
- Pyramid->Unlock();
- // 创建和设置材质
- D3DMATERIAL9 mtrl;
- mtrl.Ambient = d3d::WHITE;
- mtrl.Diffuse = d3d::WHITE;
- mtrl.Specular = d3d::WHITE;
- mtrl.Emissive = d3d::BLACK;
- mtrl.Power = 5.0f;
- Device->SetMaterial(&mtrl);
- //设置一个直线光源
- D3DLIGHT9 dir;
- ::ZeroMemory(&dir,sizeof(dir));
- dir.Type = D3DLIGHT_DIRECTIONAL;
- dir.Diffuse = d3d::WHITE;
- dir.Ambient = d3d::WHITE*0.6f;
- dir.Specular = d3d::WHITE*0.3f;
- dir.Direction = D3DXVECTOR3(1.0f,0,0);
- //设置,开放 灯光,使用灯光
- Device->SetLight(0,&dir);
- Device->LightEnable(0,true);
- //设置渲染状态,重新计算法线方向,打开镜面光
- Device->SetRenderState(D3DRS_NORMALIZENORMALS,true);
- Device->SetRenderState(D3DRS_SPECULARENABLE,true);
- //设置camera 位置
- D3DXVECTOR3 pos(0.0f,1.0f,-3.0f);
- D3DXVECTOR3 target(0.0f,0.0f,0.0f);
- D3DXVECTOR3 up(0.0f,1.0f,0.0f);
- D3DXMATRIX View;
- D3DXMatrixLookAtLH(&View,&pos,&target,&up);
- Device->SetTransform(D3DTS_VIEW,&View);
- //设置投影矩阵
- D3DXMATRIX proj;
- D3DXMatrixPerspectiveFovLH(
- &proj,
- D3DX_PI *0.5f,
- (float)Width/(float)Height,
- 1.0f,
- 1000.0f);
- Device->SetTransform(D3DTS_PROJECTION,&proj);
- return true;
- }
- void Cleanup()
- {
- //清理创建的buffer
- d3d::Release<IDirect3DVertexBuffer9* >(Pyramid);
- }
- bool Display(float timeDelta)
- {
- if (Device)
- {
- D3DXMATRIX yRot;
- static float y = 0.0f;
- D3DXMatrixRotationY(&yRot,y);
- y+= timeDelta;
- if (y>6.28f)
- {
- y = 0.0f;
- }
- Device->SetTransform(D3DTS_WORLD,&yRot);
- // 绘制场景
- Device->Clear(0, 0, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER,
- 0x00000000,1.0f,0);
- Device->BeginScene();
- Device->SetStreamSource(0,Pyramid, 0, sizeof(Vertex));
- Device->SetFVF(Vertex::FVF);
- Device->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 4);
- Device->EndScene();
- Device->Present(0,0,0,0);
- }
- return true;
- }
- //回调函数
- LRESULT CALLBACK d3d::WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
- {
- switch( msg )
- {
- case WM_DESTROY:
- ::PostQuitMessage(0);
- break;
- case WM_KEYDOWN:
- if( wParam == VK_ESCAPE )
- ::DestroyWindow(hwnd);
- break;
- }
- return ::DefWindowProc(hwnd, msg, wParam, lParam);
- }
- //
- // 主函数
- //
- int WINAPI WinMain(HINSTANCE hinstance,
- HINSTANCE prevInstance,
- PSTR cmdLine,
- int showCmd)
- {
- if(!d3d::InitD3D(hinstance,
- Width, Height, true, D3DDEVTYPE_HAL, &Device))
- {
- ::MessageBox(0, _T("InitD3D() - FAILED"), 0, 0);
- return 0;
- }
- if(!Setup())
- {
- ::MessageBox(0, _T("Setup() - FAILED"), 0, 0);
- return 0;
- }
- d3d::EnterMsgLoop( Display );
- Cleanup();
- Device->Release();
- return 0;
- }
d3dUtility.h
- #include "d3dx9.h"
- #include "d3d9.h"
- #include <tchar.h>
- #include <iostream>
- #include <vector>
- #include<Windows.h>
- #pragma comment(lib,"d3dx9.lib")
- #pragma comment(lib,"d3d9.lib")
- #pragma comment(lib,"winmm.lib")
- namespace d3d
- {
- bool InitD3D(
- HINSTANCE hInstance, // [in] Application instance.
- int width, int height, // [in] Backbuffer dimensions.
- bool windowed, // [in] Windowed (true)or full screen (false).
- D3DDEVTYPE deviceType, // [in] HAL or REF
- IDirect3DDevice9** device);// [out]The created device.
- int EnterMsgLoop(
- bool (*ptr_display)(float timeDelta));
- LRESULT CALLBACK WndProc(
- HWND hwnd,
- UINT msg,
- WPARAM wParam,
- LPARAM lParam);
- template<class T> void Release(T t)
- {
- if( t )
- {
- t->Release();
- t = 0;
- }
- }
- template<class T> void Delete(T t)
- {
- if( t )
- {
- delete t;
- t = 0;
- }
- }
- const D3DXCOLOR WHITE( D3DCOLOR_XRGB(255, 255, 255) );
- const D3DXCOLOR BLACK( D3DCOLOR_XRGB( 0, 0, 0) );
- const D3DXCOLOR RED( D3DCOLOR_XRGB(255, 0, 0) );
- const D3DXCOLOR GREEN( D3DCOLOR_XRGB( 0, 255, 0) );
- const D3DXCOLOR BLUE( D3DCOLOR_XRGB( 0, 0, 255) );
- const D3DXCOLOR YELLOW( D3DCOLOR_XRGB(255, 255, 0) );
- const D3DXCOLOR CYAN( D3DCOLOR_XRGB( 0, 255, 255) );
- const D3DXCOLOR MAGENTA( D3DCOLOR_XRGB(255, 0, 255) );
- //
- // Lights
- //
- D3DLIGHT9 InitDirectionalLight(D3DXVECTOR3* direction, D3DXCOLOR* color);
- D3DLIGHT9 InitPointLight(D3DXVECTOR3* position, D3DXCOLOR* color);
- D3DLIGHT9 InitSpotLight(D3DXVECTOR3* position, D3DXVECTOR3* direction, D3DXCOLOR* color);
- //
- // Materials
- //
- D3DMATERIAL9 InitMtrl(D3DXCOLOR a, D3DXCOLOR d, D3DXCOLOR s, D3DXCOLOR e, float p);
- const D3DMATERIAL9 WHITE_MTRL = InitMtrl(WHITE, WHITE, WHITE, BLACK, 2.0f);
- const D3DMATERIAL9 RED_MTRL = InitMtrl(RED, RED, RED, BLACK, 2.0f);
- const D3DMATERIAL9 GREEN_MTRL = InitMtrl(GREEN, GREEN, GREEN, BLACK, 2.0f);
- const D3DMATERIAL9 BLUE_MTRL = InitMtrl(BLUE, BLUE, BLUE, BLACK, 2.0f);
- const D3DMATERIAL9 YELLOW_MTRL = InitMtrl(YELLOW, YELLOW, YELLOW, BLACK, 2.0f);
- }
d3dUtility.cpp
- #include "d3dutility.h"
- bool d3d::InitD3D(HINSTANCE hInstance,
- int width,
- int height,
- bool windowed,
- D3DDEVTYPE deviceType,
- IDirect3DDevice9 ** device)
- {
- //创建应用程序主窗口
- WNDCLASS wc;
- wc.style = CS_HREDRAW | CS_VREDRAW;
- wc.lpfnWndProc = (WNDPROC)d3d::WndProc;
- wc.cbClsExtra = 0;
- wc.cbWndExtra = 0;
- wc.hInstance = hInstance;
- wc.hIcon = LoadIcon(0, IDI_APPLICATION);
- wc.hCursor = LoadCursor(0, IDC_ARROW);
- wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
- wc.lpszMenuName = 0;
- wc.lpszClassName = _T("Direct3D9App");
- if (!RegisterClass(&wc))
- {
- ::MessageBox(0,_T("RegisterClass() ---error"),0,0);
- return false;
- }
- HWND hwnd = 0;
- hwnd = ::CreateWindow(_T("Direct3D9App"), _T("Direct3D9App"),
- WS_EX_TOPMOST,
- 0, 0, width, height,
- 0 /*parent hwnd*/, 0 /* menu */, hInstance, 0 /*extra*/);
- if (!hwnd)
- {
- ::MessageBox(0,_T("CreateWindow()--error"),0,0);
- return false;
- }
- ::ShowWindow(hwnd,SW_SHOW);
- ::UpdateWindow(hwnd);
- //初始化 D3D
- HRESULT hr = 0;
- //创建IDirect3D9 对象
- IDirect3D9 *d3d9 = 0;
- d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
- if (!d3d9)
- {
- ::MessageBox(0,_T("error"),0,0);
- return false;
- }
- // 检测硬件支持
- D3DCAPS9 caps ;
- d3d9->GetDeviceCaps(D3DADAPTER_DEFAULT,deviceType,&caps);
- int vp= 0;
- if (caps.DeviceType & D3DDEVCAPS_HWTRANSFORMANDLIGHT)
- {
- vp = D3DCREATE_SOFTWARE_VERTEXPROCESSING;
- }
- else
- {
- vp = D3DCREATE_SOFTWARE_VERTEXPROCESSING;
- }
- // 填充D3DPRESENT_PARAMETERS struct
- D3DPRESENT_PARAMETERS d3dpp;
- d3dpp.BackBufferWidth = width;
- d3dpp.BackBufferHeight = height;
- d3dpp.BackBufferFormat = D3DFMT_A8R8G8B8;
- d3dpp.BackBufferCount = 1;
- d3dpp.MultiSampleType = D3DMULTISAMPLE_NONE;
- d3dpp.MultiSampleQuality = 0;
- d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
- d3dpp.hDeviceWindow = hwnd;
- d3dpp.Windowed = windowed;
- d3dpp.EnableAutoDepthStencil = true;
- d3dpp.AutoDepthStencilFormat = D3DFMT_D24S8;
- d3dpp.Flags = 0;
- d3dpp.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;
- d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
- //创建设备
- hr = d3d9->CreateDevice(
- D3DADAPTER_DEFAULT, // primary adapter
- deviceType, // device type
- hwnd, // window associated with device
- vp, // vertex processing
- &d3dpp, // present parameters
- device);
- if( FAILED(hr) )
- {
- // try again using a 16-bit depth buffer
- d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
- hr = d3d9->CreateDevice(
- D3DADAPTER_DEFAULT,
- deviceType,
- hwnd,
- vp,
- &d3dpp,
- device);
- if( FAILED(hr) )
- {
- d3d9->Release(); // done with d3d9 object
- ::MessageBox(0, _T("CreateDevice() - FAILED"), 0, 0);
- return false;
- }
- }
- d3d9->Release(); // done with d3d9 object
- return true;
- }
- int d3d::EnterMsgLoop( bool (*ptr_display)(float timeDelta) )
- {
- MSG msg;
- ::ZeroMemory(&msg, sizeof(MSG));
- static float lastTime = (float)timeGetTime();
- while(msg.message != WM_QUIT)
- {
- if(::PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
- {
- ::TranslateMessage(&msg);
- ::DispatchMessage(&msg);
- }
- else
- {
- float currTime = (float)timeGetTime();
- float timeDelta = (currTime - lastTime)*0.001f;
- ptr_display(timeDelta);
- lastTime = currTime;
- }
- }
- return msg.wParam;
- }
- D3DLIGHT9 d3d::InitDirectionalLight(D3DXVECTOR3* direction ,D3DXCOLOR* color)
- {
- D3DLIGHT9 light;
- ::ZeroMemory(&light,sizeof(light));
- light.Type = D3DLIGHT_DIRECTIONAL;
- light.Ambient = *color*0.6f;
- light.Diffuse = *color;
- light.Specular = *color*0.0f;
- light.Direction = *direction;
- return light;
- }
- D3DLIGHT9 d3d::InitPointLight(D3DXVECTOR3* position ,D3DXCOLOR* color)
- {
- D3DLIGHT9 light;
- ::ZeroMemory(&light,sizeof(light));
- light.Type = D3DLIGHT_POINT;
- light.Ambient = *color*0.6f;
- light.Diffuse = *color;
- light.Specular = *color*0.6f;
- light.Position = *position;
- light.Range = 1000.0f;
- light.Falloff = 1.0f;
- light.Attenuation0 =1.0f;
- light.Attenuation1 = 0.0f;
- light.Attenuation2 = 0.0f;
- return light;
- }
- D3DLIGHT9 d3d::InitSpotLight(D3DXVECTOR3* position, D3DXVECTOR3* direction, D3DXCOLOR* color)
- {
- D3DLIGHT9 light;
- ::ZeroMemory(&light, sizeof(light));
- light.Type = D3DLIGHT_SPOT;
- light.Ambient = *color * 0.0f;
- light.Diffuse = *color;
- light.Specular = *color * 0.6f;
- light.Position = *position;
- light.Direction = *direction;
- light.Range = 1000.0f;
- light.Falloff = 1.0f;
- light.Attenuation0 = 1.0f;
- light.Attenuation1 = 0.0f;
- light.Attenuation2 = 0.0f;
- light.Theta = 0.4f;
- light.Phi = 0.9f;
- return light;
- }
- D3DMATERIAL9 d3d::InitMtrl(D3DXCOLOR a, D3DXCOLOR d, D3DXCOLOR s, D3DXCOLOR e, float p)
- {
- D3DMATERIAL9 mtrl;
- mtrl.Ambient = a;
- mtrl.Diffuse = d;
- mtrl.Specular = s;
- mtrl.Emissive = e;
- mtrl.Power = p;
- return mtrl;
- }
- DirectX 中的光照
- DirectX 光源、光照模型
- DirectX实现光照、纹理
- DirectX 9.0 C++ 教程 光照
- 【阅读笔记之七】《DIRECTX.9.0.3D游戏开发编程基础》:Direct3D中的光照
- OpenGL中的光照[光照计算]
- DirectX 入门[04] 创建和使用光照
- DirectX 10 教程6:漫反射光照
- 菜鸟DirectX之光照与材质
- OpenGL中的光照
- D3D中的光照
- cocos2d中的光照效果
- OpenGL中的光照
- MATLAB中的光照处理
- Unity5中的光照简介
- OpenGL中的光照
- Direct3D中的光照
- DirectX 3D_实践之DirectX3D光照的实现
- 这段代码出错在那可以编译不能运行
- Ogitor 绘制地形图(1)
- 关于预编译语句使用的注意事项
- 深度优先—递归方法 求解n皇后问题
- 新手上路
- DirectX 中的光照
- 有的东西忘得好快啊!!!
- 代码中获取资源文件中的string,Array
- 安装 Silverlight
- 很喜欢的10段话,哪段感动了你.......
- 从web到Andorid
- 在网上见到的一个小故事,看完你有什么感受呢?到最后......
- I would like to join Android Developer Group
- java基础知识点汇总 I