From 507022db7cd82e01d47156aaf0bf4e60984d8c9f Mon Sep 17 00:00:00 2001 From: Lynix Date: Fri, 11 Jan 2013 14:40:02 +0100 Subject: [PATCH] Added light class Former-commit-id: e2969fe35720e1ea2f982a86197237a50bef1389 --- include/Nazara/3D/Enums.hpp | 10 ++ include/Nazara/3D/Light.hpp | 55 ++++++++++ src/Nazara/3D/Light.cpp | 196 ++++++++++++++++++++++++++++++++++++ 3 files changed, 261 insertions(+) create mode 100644 include/Nazara/3D/Light.hpp create mode 100644 src/Nazara/3D/Light.cpp diff --git a/include/Nazara/3D/Enums.hpp b/include/Nazara/3D/Enums.hpp index a42bcb22d..2cae8e416 100644 --- a/include/Nazara/3D/Enums.hpp +++ b/include/Nazara/3D/Enums.hpp @@ -7,8 +7,18 @@ #ifndef NAZARA_ENUMS_3D_HPP #define NAZARA_ENUMS_3D_HPP +enum nzLightType +{ + nzLightType_Directional, + nzLightType_Point, + nzLightType_Spot, + + nzLightType_Max = nzLightType_Spot +}; + enum nzSceneNodeType { + nzSceneNodeType_Light, nzSceneNodeType_Model, nzSceneNodeType_Max = nzSceneNodeType_Model diff --git a/include/Nazara/3D/Light.hpp b/include/Nazara/3D/Light.hpp new file mode 100644 index 000000000..349e846e8 --- /dev/null +++ b/include/Nazara/3D/Light.hpp @@ -0,0 +1,55 @@ +// Copyright (C) 2012 Jérôme Leclercq +// This file is part of the "Nazara Engine - 3D module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#pragma once + +#ifndef NAZARA_LIGHT_HPP +#define NAZARA_LIGHT_HPP + +#include +#include +#include +#include + +class NAZARA_API NzLight : public NzSceneNode +{ + public: + NzLight(nzLightType type); + NzLight(const NzLight& light); + ~NzLight(); + + void Apply(unsigned int i = 0) const; + + const NzAxisAlignedBox& GetAABB() const; + NzColor GetAmbientColor() const; + float GetAttenuation() const; + NzColor GetDiffuseColor() const; + float GetInnerAngle() const; + float GetOuterAngle() const; + float GetRadius() const; + nzSceneNodeType GetSceneNodeType() const; + NzColor GetSpecularColor() const; + + void SetAmbientColor(const NzColor& ambient); + void SetAttenuation(float attenuation); + void SetDiffuseColor(const NzColor& diffuse); + void SetInnerAngle(float innerAngle); + void SetOuterAngle(float outerAngle); + void SetRadius(float radius); + void SetSpecularColor(const NzColor& specular); + + NzLight& operator=(const NzLight& light); + + private: + nzLightType m_type; + NzColor m_ambientColor; + NzColor m_diffuseColor; + NzColor m_specularColor; + float m_attenuation; + float m_innerAngle; + float m_outerAngle; + float m_radius; +}; + +#endif // NAZARA_LIGHT_HPP diff --git a/src/Nazara/3D/Light.cpp b/src/Nazara/3D/Light.cpp new file mode 100644 index 000000000..3c33ca3d9 --- /dev/null +++ b/src/Nazara/3D/Light.cpp @@ -0,0 +1,196 @@ +// Copyright (C) 2012 Jérôme Leclercq +// This file is part of the "Nazara Engine - 3D Module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#include +#include +#include +#include +#include +#include +#include + +NzLight::NzLight(nzLightType type) : +m_type(type), +m_ambientColor((type == nzLightType_Directional) ? NzColor(50, 50, 50) : NzColor::Black), +m_diffuseColor(NzColor::White), +m_specularColor(NzColor::White), +m_attenuation(0.9f), +m_innerAngle(15.f), +m_outerAngle(45.f), +m_radius(500.f) +{ +} + +NzLight::NzLight(const NzLight& light) +{ + std::memcpy(this, &light, sizeof(NzLight)); // Aussi simple que ça +} + +NzLight::~NzLight() = default; + +void NzLight::Apply(unsigned int i) const +{ + /* + struct Light + { + int type; + vec4 ambient; + vec4 diffuse; + vec4 specular; + + vec4 parameters1; + vec4 parameters2; + vec2 parameters3; + }; + + Directional + -P1: vec3 direction + + Point + -P1: vec3 position + float attenuation + -P2: float invRadius + + Spot + -P1: vec3 position + float attenuation + -P2: vec3 direction + float invRadius + -P3: float cosInnerAngle + float cosOuterAngle + */ + const NzShader* shader = NzRenderer::GetShader(); + + int typeLocation = shader->GetUniformLocation("Lights[0].type"); + int ambientLocation = shader->GetUniformLocation("Lights[0].ambient"); + int diffuseLocation = shader->GetUniformLocation("Lights[0].diffuse"); + int specularLocation = shader->GetUniformLocation("Lights[0].specular"); + int parameters1Location = shader->GetUniformLocation("Lights[0].parameters1"); + int parameters2Location = shader->GetUniformLocation("Lights[0].parameters2"); + int parameters3Location = shader->GetUniformLocation("Lights[0].parameters3"); + + if (i > 0) + { + int type2Location = shader->GetUniformLocation("Lights[1].type"); + int offset = i * (type2Location - typeLocation); // type2Location - typeLocation donne la taille de la structure + + // On applique cet offset + typeLocation += offset; + ambientLocation += offset; + diffuseLocation += offset; + specularLocation += offset; + parameters1Location += offset; + parameters2Location += offset; + parameters3Location += offset; + } + + shader->SendInteger(typeLocation, m_type); + shader->SendColor(ambientLocation, m_ambientColor); + shader->SendColor(diffuseLocation, m_diffuseColor); + shader->SendColor(specularLocation, m_specularColor); + + if (!m_derivedUpdated) + UpdateDerived(); + + switch (m_type) + { + case nzLightType_Directional: + shader->SendVector(parameters1Location, NzVector4f(m_derivedRotation * NzVector3f::Forward())); + break; + + case nzLightType_Point: + shader->SendVector(parameters1Location, NzVector4f(m_derivedTranslation, m_attenuation)); + shader->SendVector(parameters2Location, NzVector4f(1.f/m_radius, 0.f, 0.f, 0.f)); + break; + + case nzLightType_Spot: + shader->SendVector(parameters1Location, NzVector4f(m_derivedTranslation, m_attenuation)); + shader->SendVector(parameters2Location, NzVector4f(m_derivedRotation * NzVector3f::Forward(), 1.f/m_radius)); + shader->SendVector(parameters3Location, NzVector2f(std::cos(NzDegreeToRadian(m_innerAngle)), std::cos(NzDegreeToRadian(m_outerAngle)))); + break; + } +} + +const NzAxisAlignedBox& NzLight::GetAABB() const +{ + return NzAxisAlignedBox::Null; +} + +NzColor NzLight::GetAmbientColor() const +{ + return m_ambientColor; +} + +float NzLight::GetAttenuation() const +{ + return m_attenuation; +} + +NzColor NzLight::GetDiffuseColor() const +{ + return m_diffuseColor; +} + +float NzLight::GetInnerAngle() const +{ + return m_innerAngle; +} + +float NzLight::GetOuterAngle() const +{ + return m_outerAngle; +} + +float NzLight::GetRadius() const +{ + return m_radius; +} + +nzSceneNodeType NzLight::GetSceneNodeType() const +{ + return nzSceneNodeType_Light; +} + +NzColor NzLight::GetSpecularColor() const +{ + return m_specularColor; +} + +void NzLight::SetAmbientColor(const NzColor& ambient) +{ + m_ambientColor = ambient; +} + +void NzLight::SetAttenuation(float attenuation) +{ + m_attenuation = attenuation; +} + +void NzLight::SetDiffuseColor(const NzColor& diffuse) +{ + m_diffuseColor = diffuse; +} + +void NzLight::SetInnerAngle(float innerAngle) +{ + m_innerAngle = innerAngle; +} + +void NzLight::SetOuterAngle(float outerAngle) +{ + m_outerAngle = outerAngle; +} + +void NzLight::SetRadius(float radius) +{ + m_radius = radius; +} + +void NzLight::SetSpecularColor(const NzColor& specular) +{ + m_specularColor = specular; +} + +NzLight& NzLight::operator=(const NzLight& light) +{ + std::memcpy(this, &light, sizeof(NzLight)); + + return *this; +}