Cocos2d-x architecture game light material
Lighting and material are implemented as follows:
1. Lighting
#pragma once//=========================================================================// Lights.h - implements a simple light class for the scene graph//=========================================================================#include "D3DRenderer.h"#include "Geometry.h"#include "Scene.h"#include "SceneNodes.h"// 光的颜色刚好反映在材质上面// Note: Light color is stored in the Material structure, which is already present in all SceneNodes.//// struct LightProperties//struct LightProperties{floatm_Attenuation[3]; /* Attenuation coefficients 衰减系数 */floatm_Range; /* 光照范围 */floatm_Falloff; floatm_Theta;floatm_Phi;};//// class LightNode//// Note: In the book this class implements the LightNode in D3D11, but here it is a base// class. The derived classes make it possible to run the engine in D3D9 or D3D11.//typedef unsigned int ActorId;typedef unsigned int GameViewId;typedef D3DXCOLOR Color;typedef unsigned int DWORD;typedef unsigned char BYTE;#define GCC_NEW newenum HRESULT { E_INVALIDARG, E_FAIL, S_OK,};class LightNode : public SceneNode{protected:LightProperties m_LightProps;public:LightNode(const ActorId actorId, WeakBaseRenderComponentPtr renderComponent, const LightProperties &props, const Mat4x4 *t);};class D3DLightNode9 : public LightNode{public:D3DLightNode9(const ActorId actorId, WeakBaseRenderComponentPtr renderComponent, const LightProperties &lightProps, const Mat4x4 *t): LightNode(actorId, renderComponent, lightProps, t) { }D3DLIGHT9m_d3dLight9;virtual HRESULT VOnRestore(Scene *pScene);virtual HRESULT VOnUpdate(Scene *, DWORD const elapsedMs);};class D3DLightNode11 : public LightNode{public:D3DLightNode11(const ActorId actorId, WeakBaseRenderComponentPtr renderComponent, const LightProperties &lightProps, const Mat4x4 *t): LightNode(actorId, renderComponent, lightProps, t) { }virtual HRESULT VOnRestore() { return S_OK; };virtual HRESULT VOnUpdate(Scene *, DWORD const elapsedMs);};struct ConstantBuffer_Lighting;//// class LightManager//class LightManager{friend class Scene;protected:Lightsm_Lights;Vec4m_vLightDir[MAXIMUM_LIGHTS_SUPPORTED]; Colorm_vLightDiffuse[MAXIMUM_LIGHTS_SUPPORTED];Vec4m_vLightAmbient;public:void CalcLighting(Scene *pScene);void CalcLighting(ConstantBuffer_Lighting* pLighting, SceneNode *pNode);int GetLightCount(const SceneNode *node) { return m_Lights.size(); }const Vec4 *GetLightAmbient(const SceneNode *node) { return &m_vLightAmbient; }const Vec4 *GetLightDirection(const SceneNode *node) { return m_vLightDir; }const Color *GetLightDiffuse(const SceneNode *node) { return m_vLightDiffuse; }};
//=========================================================================// Lights.h - implements a simple light class for the GameCode4 scene graph//=========================================================================#include "GameCodeStd.h"#include "GameCode.h"#include "RenderComponent.h"#include "Lights.h"LightNode::LightNode(const ActorId actorId, WeakBaseRenderComponentPtr renderComponent, const LightProperties &props, const Mat4x4 *t) : SceneNode(actorId, renderComponent, RenderPass_NotRendered, t) {m_LightProps = props;}HRESULT D3DLightNode9::VOnRestore(Scene *pScene){ZeroMemory( &m_d3dLight9, sizeof(D3DLIGHT9) ); m_d3dLight9.Type = D3DLIGHT_DIRECTIONAL;// These parameters are constant for the list after the scene is loadedm_d3dLight9.Range = m_LightProps.m_Range; m_d3dLight9.Falloff= m_LightProps.m_Falloff;m_d3dLight9.Attenuation0= m_LightProps.m_Attenuation[0]; m_d3dLight9.Attenuation1= m_LightProps.m_Attenuation[0]; m_d3dLight9.Attenuation2= m_LightProps.m_Attenuation[0]; m_d3dLight9.Theta= m_LightProps.m_Theta; m_d3dLight9.Phi= m_LightProps.m_Phi;return S_OK;}HRESULT D3DLightNode9::VOnUpdate(Scene *, DWORD const elapsedMs){// light color can change anytime! Check the BaseRenderComponent!LightRenderComponent* lrc = static_cast<LightRenderComponent*>(m_RenderComponent);m_Props.GetMaterial().SetDiffuse(lrc->GetColor());m_d3dLight9.Diffuse = m_Props.GetMaterial().GetDiffuse();float power;Color spec; m_Props.GetMaterial().GetSpecular(spec, power);m_d3dLight9.Specular = spec; m_d3dLight9.Ambient = m_Props.GetMaterial().GetAmbient();m_d3dLight9.Position = GetPosition();m_d3dLight9.Direction = GetDirection();return S_OK;}HRESULT D3DLightNode11::VOnUpdate(Scene *, DWORD const elapsedMs){ // light color can change anytime! Check the BaseRenderComponent!LightRenderComponent* lrc = static_cast<LightRenderComponent*>(m_RenderComponent);m_Props.GetMaterial().SetDiffuse(lrc->GetColor());return S_OK; }//// LightManager::CalcLighting//void LightManager::CalcLighting(Scene *pScene){// FUTURE WORK: There might be all kinds of things you'd want to do here for optimization, especially turning off lights on actors that can't be seen, etc.pScene->GetRenderer()->VCalcLighting(&m_Lights, MAXIMUM_LIGHTS_SUPPORTED);int count = 0;GCC_ASSERT(m_Lights.size() < MAXIMUM_LIGHTS_SUPPORTED);for(Lights::iterator i=m_Lights.begin(); i!=m_Lights.end(); ++i, ++count){shared_ptr<LightNode> light = *i;if (count==0){// Light 0 is the only one we use for ambient lighting. The rest are ignored in the simple shaders used for GameCode4.Color ambient = light->VGet()->GetMaterial().GetAmbient();m_vLightAmbient = D3DXVECTOR4(ambient.r, ambient.g, ambient.b, 1.0f); }Vec3 lightDir = light->GetDirection();m_vLightDir[count] = D3DXVECTOR4(lightDir.x, lightDir.y, lightDir.z, 1.0f);m_vLightDiffuse[count] = light->VGet()->GetMaterial().GetDiffuse();}}void LightManager::CalcLighting(ConstantBuffer_Lighting* pLighting, SceneNode *pNode){int count = GetLightCount(pNode);if (count){pLighting->m_vLightAmbient = *GetLightAmbient(pNode);memcpy(pLighting->m_vLightDir, GetLightDirection(pNode), sizeof( Vec4 ) * count );memcpy(pLighting->m_vLightDiffuse, GetLightDiffuse(pNode), sizeof( Vec4 ) * count);pLighting->m_nNumLights = count;}}
2. Material
#pragma once//==============================================================================// File: Material.h - stores texture and material information for D3D9 and D3D11//==============================================================================// class Material#include "Geometry.h"#include "ResCache.h"class Material{D3DMATERIAL9 m_D3DMaterial;// This structure stores diffuse,ambient,specular,emissive,power.public:Material();void SetAmbient(const Color &color);const Color GetAmbient() { return m_D3DMaterial.Ambient; }void SetDiffuse(const Color &color);const Color GetDiffuse() { return m_D3DMaterial.Diffuse; }void SetSpecular(const Color &color, const float power);void GetSpecular(Color &_color, float &_power) { _color = m_D3DMaterial.Specular; _power = m_D3DMaterial.Power; }void SetEmissive(const Color &color);const Color GetEmissive() { return m_D3DMaterial.Emissive; }void SetAlpha(const float alpha);bool HasAlpha() const { return GetAlpha() != fOPAQUE; }float GetAlpha() const { return m_D3DMaterial.Diffuse.a; }void D3DUse9();};// // class D3DTextureResourceExtraData9, also see D3DTextureResourceExtraData11//class D3DTextureResourceExtraData9 : public IResourceExtraData{friend class TextureResourceLoader;public:D3DTextureResourceExtraData9();virtual ~D3DTextureResourceExtraData9() { SAFE_RELEASE(m_pTexture); }virtual std::string VToString() { return "D3DTextureResourceExtraData9"; }LPDIRECT3DTEXTURE9 const GetTexture() { return m_pTexture; }protected:LPDIRECT3DTEXTURE9m_pTexture;};// // class D3DTextureResourceExtraData11//class D3DTextureResourceExtraData11 : public IResourceExtraData{friend class TextureResourceLoader;public:D3DTextureResourceExtraData11();virtual ~D3DTextureResourceExtraData11() { SAFE_RELEASE(m_pTexture); SAFE_RELEASE(m_pSamplerLinear); }virtual std::string VToString() { return "D3DTextureResourceExtraData11"; }ID3D11ShaderResourceView * const *GetTexture() { return &m_pTexture; }ID3D11SamplerState * const *GetSampler() { return &m_pSamplerLinear; }protected:ID3D11ShaderResourceView *m_pTexture;ID3D11SamplerState* m_pSamplerLinear;};// // class TextureResourceLoader//class TextureResourceLoader : public IResourceLoader{public:virtual bool VUseRawFile() { return false; }virtual bool VDiscardRawBufferAfterLoad() { return true; }virtual unsigned int VGetLoadedResourceSize(char *rawBuffer, unsigned int rawSize);virtual bool VLoadResource(char *rawBuffer, unsigned int rawSize, shared_ptr<ResHandle> handle);};
//================================================================================// File: Material.cpp - stores texture and material information for D3D9 and D3D11//================================================================================#include "GameCodeStd.h"#include "GameCode.h"#include "ResCache.h"#include "SceneNodes.h"////////////////////////////////////////////////////// class Material////////////////////////////////////////////////////Material::Material(){ZeroMemory( &m_D3DMaterial, sizeof( D3DMATERIAL9 ) );m_D3DMaterial.Diffuse = g_White;m_D3DMaterial.Ambient = Color(0.10f, 0.10f, 0.10f, 1.0f);m_D3DMaterial.Specular = g_White;m_D3DMaterial.Emissive = g_Black;}void Material::SetAmbient(const Color &color){m_D3DMaterial.Ambient = color;}void Material::SetDiffuse(const Color &color){m_D3DMaterial.Diffuse = color;}void Material::SetSpecular(const Color &color, const float power){m_D3DMaterial.Specular = color;m_D3DMaterial.Power = power;}void Material::SetEmissive(const Color &color){m_D3DMaterial.Emissive = color;}void Material::SetAlpha(float alpha){m_D3DMaterial.Diffuse.a = alpha;}void Material::D3DUse9(){DXUTGetD3D9Device()->SetMaterial( &m_D3DMaterial );}//// class DdsResourceLoader- creates an interface with the Resource cache to load DDS files//class DdsResourceLoader : public TextureResourceLoader{public:virtual std::string VGetPattern() { return "*.dds"; }};shared_ptr<IResourceLoader> CreateDDSResourceLoader(){return shared_ptr<IResourceLoader>(GCC_NEW DdsResourceLoader());}//// class JpgResourceLoader - creates an interface with the Resource cache to load JPG files//class JpgResourceLoader : public TextureResourceLoader{public:virtual std::string VGetPattern() { return "*.jpg"; }};shared_ptr<IResourceLoader> CreateJPGResourceLoader(){return shared_ptr<IResourceLoader>(GCC_NEW JpgResourceLoader());}D3DTextureResourceExtraData9::D3DTextureResourceExtraData9(): m_pTexture(NULL) {}D3DTextureResourceExtraData11::D3DTextureResourceExtraData11(): m_pTexture(NULL), m_pSamplerLinear(NULL){}unsigned int TextureResourceLoader::VGetLoadedResourceSize(char *rawBuffer, unsigned int rawSize){// This will keep the resource cache from allocating memory for the texture, so DirectX can manage it on it's own.return 0;}//// TextureResourceLoader::VLoadResource//bool TextureResourceLoader::VLoadResource(char *rawBuffer, unsigned int rawSize, shared_ptr<ResHandle> handle){GameCodeApp::Renderer renderer = GameCodeApp::GetRendererImpl();if (renderer == GameCodeApp::Renderer_D3D9){shared_ptr<D3DTextureResourceExtraData9> extra = shared_ptr<D3DTextureResourceExtraData9>(GCC_NEW D3DTextureResourceExtraData9());if ( FAILED ( D3DXCreateTextureFromFileInMemory( DXUTGetD3D9Device(), rawBuffer, rawSize, &extra->m_pTexture ) ) )return false;else {handle->SetExtra(shared_ptr<D3DTextureResourceExtraData9>(extra));return true;}}else if (renderer == GameCodeApp::Renderer_D3D11){shared_ptr<D3DTextureResourceExtraData11> extra = shared_ptr<D3DTextureResourceExtraData11>(GCC_NEW D3DTextureResourceExtraData11());// Load the Textureif ( FAILED ( D3DX11CreateShaderResourceViewFromMemory( DXUTGetD3D11Device(), rawBuffer, rawSize, NULL, NULL, &extra->m_pTexture, NULL ) ) )return false;// Create the sample stateD3D11_SAMPLER_DESC sampDesc;ZeroMemory( &sampDesc, sizeof(sampDesc) );sampDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;sampDesc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP;sampDesc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP;sampDesc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP;sampDesc.ComparisonFunc = D3D11_COMPARISON_NEVER;sampDesc.MinLOD = 0;sampDesc.MaxLOD = D3D11_FLOAT32_MAX;if( FAILED( DXUTGetD3D11Device()->CreateSamplerState( &sampDesc, &extra->m_pSamplerLinear ) ) ) return false;handle->SetExtra(shared_ptr<D3DTextureResourceExtraData11>(extra));return true;}GCC_ASSERT(0 && "Unsupported Renderer in TextureResourceLoader::VLoadResource");return false;}
Next is the mesh and shader ~~~
Game framework 9: Lights and material)