17. 增加对硬件光照的支持
2011-08-21 22:55
260 查看
该游戏项目一开始先创建名为light.h、material.h的两个文件。
light.h头文件用于创建灯源结构,该结构用于创建Direct3D中的灯源对象。以某种方式实现该结构,这样也可将其用于OpenGL或其他渲染系统。光源结构模仿了Direct3D中的D3DLIGHT结构,所以它们是完全兼容的。
light.h
material.h
Direct3D渲染系统需要一种创建光源和材质的方法。这可以通过为渲染系统添加三个新函数来实现。第一个函数是SetMaterial(),它的参数包括材质(stMaterial)对象,并将其施加到渲染设备上。第二个新函数是SetLight(),它的参数包括灯源对象、灯源索引(因为Direct3D和OpenGL由多达8个的硬件光源,所以索引值可以是0~7),并且调用必须的Direct3D函数用于在硬件中创建和注册光源。最后一个新函数是DisalbeLight(),它以想要关闭灯源的索引为参数。给出了新增加的CD3DRenderer和CRenderInterface类。
D3DRenderer.cpp源文件实现了三个和Direct3D打交道的函数。SetMaterial()函数使用材质结构中的信息创建Direct3D材质对象,并调用Direct3D设备函数SetMaterial()将该对象直接发送给Direct3D。这同样使用于SetLight()函数。SetLight()函数的参数包括光源结构,该函数使用该参数设置D3DLIGHT9对象,并将其直接发送给Direct3D。DisableLight()函数的参数包括光源索引,它将关闭注册在该索引上的所有光源。给出了这些函数的源代码。
还需要在“defines.h”头文件里加入这几行代码:
light.h头文件用于创建灯源结构,该结构用于创建Direct3D中的灯源对象。以某种方式实现该结构,这样也可将其用于OpenGL或其他渲染系统。光源结构模仿了Direct3D中的D3DLIGHT结构,所以它们是完全兼容的。
light.h
#ifndef _UGP_LIGHT_H_ #define _UGP_LIGHT_H_ struct stLight { stLight() { type = 0; posX = 0, posY = 0, posZ = 0; dirX = 0, dirY = 0, dirZ = 0; ambientR = ambientG = ambientB = ambientA = 1; diffuseR = diffuseG = diffuseB = diffuseA = 1; specularR = specularG = specularB = specularA = 0; range = 0; falloff = 0; attenuation0 = 0; attenuation1 = 0; attenuation2 = 0; theta = 0; phi = 0; } int type; float posX, posY, posZ; float dirX, dirY, dirZ; float ambientR, ambientG, ambientB, ambientA; float diffuseR, diffuseG, diffuseB, diffuseA; float specularR, specularG, specularB, specularA; float range; float falloff; float attenuation0; float attenuation1; float attenuation2; float theta; float phi; }; #endif
material.h
// ======================================================================== //§ material.h 文件 //§ //§ 【描述】:定义材质结构:stMaterial //§ // ======================================================================== #ifndef _UGP_MATERIAL_H_ #define _UGP_MATERIAL_H_ struct stMaterial { stMaterial() { emissiveR = emissiveG = emissiveB = emissiveA = 0; ambientR = ambientG = ambientB = ambientA = 1; diffuseR = diffuseG = diffuseB = diffuseA = 1; specularR = specularG = specularB = specularA = 0; power = 0; } float emissiveR, emissiveG, emissiveB, emissiveA; float ambientR, ambientG, ambientB, ambientA; float diffuseR, diffuseG, diffuseB, diffuseA; float specularR, specularG, specularB, specularA; float power; }; #endif
Direct3D渲染系统需要一种创建光源和材质的方法。这可以通过为渲染系统添加三个新函数来实现。第一个函数是SetMaterial(),它的参数包括材质(stMaterial)对象,并将其施加到渲染设备上。第二个新函数是SetLight(),它的参数包括灯源对象、灯源索引(因为Direct3D和OpenGL由多达8个的硬件光源,所以索引值可以是0~7),并且调用必须的Direct3D函数用于在硬件中创建和注册光源。最后一个新函数是DisalbeLight(),它以想要关闭灯源的索引为参数。给出了新增加的CD3DRenderer和CRenderInterface类。
class CRenderInterface { // ...The beginning of the class functions... // 设置材质 virtual void SetMaterial(stMaterial *mat) = 0; // 设置并启用光源 virtual void SetLight(stLight *light, int index) = 0; // 关闭光源 virtual void DisableLight(int index) = 0; // ...The rest of the class's functions... }; class CD3DRenderer : public CRenderInterface { // ...The beginning of the class functions... // 设置材质 void SetMaterial(stMaterial *mat); // 设置并启用光源 void SetLight(stLight *light, int index); // 关闭光源 void DisableLight(int index); // ...The rest of the class's functions... };
D3DRenderer.cpp源文件实现了三个和Direct3D打交道的函数。SetMaterial()函数使用材质结构中的信息创建Direct3D材质对象,并调用Direct3D设备函数SetMaterial()将该对象直接发送给Direct3D。这同样使用于SetLight()函数。SetLight()函数的参数包括光源结构,该函数使用该参数设置D3DLIGHT9对象,并将其直接发送给Direct3D。DisableLight()函数的参数包括光源索引,它将关闭注册在该索引上的所有光源。给出了这些函数的源代码。
// 设置材质 void CD3DRenderer::SetMaterial(stMaterial *mat) { if(!mat || !m_Device) return; D3DMATERIAL9 m = { mat->diffuseR, mat->diffuseG, mat->diffuseB, mat->diffuseA, mat->ambientR, mat->ambientG, mat->ambientB, mat->ambientA, mat->specularR, mat->specularG, mat->specularB, mat->specularA, mat->emissiveR, mat->emissiveG, mat->emissiveB, mat->emissiveA, mat->power }; m_Device->SetMaterial(&m); } // 设置并启用光源 void CD3DRenderer::SetLight(stLight *light, int index) { if(!light || !m_Device || index < 0) return; D3DLIGHT9 l; l.Ambient.a = light->ambientA; l.Ambient.r = light->ambientR; l.Ambient.g = light->ambientG; l.Ambient.b = light->ambientB; l.Attenuation0 = light->attenuation0; l.Attenuation1 = light->attenuation1; l.Attenuation2 = light->attenuation2; l.Diffuse.a = light->diffuseA; l.Diffuse.r = light->diffuseR; l.Diffuse.g = light->diffuseG; l.Diffuse.b = light->diffuseB; l.Direction.x = light->dirX; l.Direction.y = light->dirY; l.Direction.z = light->dirZ; l.Falloff = light->falloff; l.Phi = light->phi; l.Position.x = light->posX; l.Position.y = light->posY; l.Position.z = light->posZ; l.Range = light->range; l.Specular.a = light->specularA; l.Specular.r = light->specularR; l.Specular.g = light->specularG; l.Specular.b = light->specularB; l.Theta = light->theta; if(light->type == LIGHT_POINT) l.Type = D3DLIGHT_POINT; else if (light->type == LIGHT_SPOT) l.Type = D3DLIGHT_SPOT; else l.Type = D3DLIGHT_DIRECTIONAL; m_Device->SetLight(index, &l); m_Device->LightEnable(index, TRUE); } // 关闭光源 void CD3DRenderer::DisableLight(int index) { if(!m_Device) return; m_Device->LightEnable(index, FALSE); }
还需要在“defines.h”头文件里加入这几行代码:
// Light type defines. // 光源类型 #define LIGHT_POINT 1 // 点光源 #define LIGHT_DIRECTIONAL 2 // 方向光 #define LIGHT_SPOT 3 // 聚光灯
相关文章推荐
- 首页增加沉浸式状态栏,仅支持android4.4及以上
- HTTP实现长连接(TTP1.1和HTTP1.0相比较而言,最大的区别就是增加了持久连接支持Connection: keep-alive)
- 全功能智能车之CCD增加自适应光照能力(第十三篇)
- 在Android 系统中增加C 可执行程序来访问硬件驱动程序
- myeclise maven导入现成的web项目时出现的问题 增加web支持
- 在Ubuntu上为Android系统的Application Frameworks层增加硬件访问服务
- Java压缩辅助类(支持文件夹压缩,加密,增加描述)
- Chrome对第三方安全硬件Key支持注意问题
- 计算机 锁 的cpu硬件级别支持原理
- 验证 .NET 4.6 的 SIMD 硬件加速支持的重要性
- ARM学习笔记002之gcc-4.3.2编译器不支持硬件除法运算的解决方法
- 在Frameworks层增加硬件访问服务
- Mesosphere在其数据中心操作系统中增加了对Kubernetes的支持
- Android4.2 MediaScanner增加其他格式的支持
- VS2008增加AJAX Control Toolkit3.5支持
- 为 SELECT.options 对象增加或删除选项的方法在各浏览器中的支持情况不同
- Android平台Stagefright中增加flv/f4v支持及相关原理介绍
- 在Ubuntu上为Android系统的Application Frameworks层增加硬件访问服务
- 在WAMPSERVER下增加多版本的PHP(PHP5.3,PHP5.4,PHP5.5)完美支持。