Skip to content
Snippets Groups Projects
Commit 4a866fdc authored by Nils Petter Skålerud's avatar Nils Petter Skålerud
Browse files

Added support for colored point lights.

Updated RenderSystem, shaders and components for colored light support.
Tried working on the Utility::Color struct, still WIP.

Signed-off-by: default avatarNils Petter Skålerud <np_skalerud@hotmail.com>
parent 4c0d7376
No related branches found
No related tags found
No related merge requests found
......@@ -2,13 +2,15 @@
layout(std140, binding = 0) uniform CameraData
{
vec4 wsPosition;
vec3 wsPosition;
mat4 viewProjection;
} cameraData;
layout(std140, binding = 1) uniform LightData
{
vec4 ambientLight;
uint pointLightCount;
vec4 pointLightIntensity[10];
vec4 pointLightPos[10];
} lightData;
......@@ -23,26 +25,25 @@ layout(location = 0) out vec4 frag_color;
void main()
{
vec3 pointToCamera = cameraData.wsPosition.xyz - fragData.wsPosition;
vec3 pointToCamera = cameraData.wsPosition - fragData.wsPosition;
vec3 pointToCameraDir = normalize(pointToCamera);
float test = 0.0;
vec3 diffuse;
vec3 specular;
for (int i = 0; i < lightData.pointLightCount; i++)
{
vec3 pointToLight = lightData.pointLightPos[i].xyz - fragData.wsPosition;
vec3 pointToLightDir = normalize(pointToLight);
float diff = max(0, dot(pointToLightDir, fragData.wsNormal));
test += diff;
diffuse += max(0, dot(pointToLightDir, fragData.wsNormal)) * vec3(lightData.pointLightIntensity[i]);
vec3 lightToPointDir = -pointToLightDir;
vec3 reflectDir = reflect(lightToPointDir, fragData.wsNormal);
float spec = pow(max(dot(pointToCameraDir, reflectDir), 0.0), 50);
test += spec;
const float coefficient = 50;
specular += pow(max(dot(pointToCameraDir, reflectDir), 0.0), coefficient) * vec3(1);
}
frag_color = vec4(test);
frag_color = vec4(vec3(lightData.ambientLight) + diffuse + specular, 1.0);
}
......@@ -6,7 +6,7 @@ layout(location = 2) in vec3 vtxNormal;
layout(std140, binding = 0) uniform CameraData
{
vec4 wsPosition;
vec3 wsPosition;
mat4 viewProjection;
} cameraData;
......
......@@ -23,8 +23,6 @@ namespace Engine
Application::API3D activeAPI;
void* windowHandle = nullptr;
};
static std::unique_ptr<Data> data;
......
......@@ -11,7 +11,8 @@ namespace Engine
PointLight::PointLight(SceneObject& owningObject) :
ParentType(owningObject),
positionOffset(),
intensity(1)
intensity(1),
color{1.f, 1.f, 1.f}
{
}
......
......@@ -6,6 +6,7 @@
#include "DMath/Vector/Vector.hpp"
#include "DMath/Matrix/Matrix.hpp"
#include "../Utility/Color.hpp"
namespace Engine
{
......@@ -20,6 +21,7 @@ namespace Engine
~PointLight();
float intensity;
Math::Vector3D color;
Math::Vector3D positionOffset;
[[nodiscard]] Math::Matrix<4, 3> GetModel_Reduced(Space space) const;
......
......@@ -56,11 +56,14 @@ void Engine::Core::Run()
Input::Core::Initialize();
Physics2D::Core::Initialize();
Renderer::CreateInfo rendererCreateInfo;
rendererCreateInfo.preferredAPI = Renderer::API::OpenGL;
rendererCreateInfo.surfaceDimensions = Application::GetWindowSize();
rendererCreateInfo.surfaceHandle = Application::Core::GetMainWindowHandle();
rendererCreateInfo.openGLCreateInfo.glSwapBuffers = Application::Core::GL_SwapWindow;
Renderer::Core::Initialize(std::move(rendererCreateInfo));
// Create scene and make viewport 0 point to scene 0.
......@@ -89,6 +92,7 @@ void Engine::Core::Run()
auto& lightObj = scene1.NewSceneObject();
lightObj.transform.localPosition = { 2.5f, 2.5f, 2.5f };
Components::PointLight& light1 = lightObj.AddComponent<Components::PointLight>().first.get();
light1.color = { 1.f, 0.5f, 0.f };
auto& mesh3 = lightObj.AddComponent<Components::MeshRenderer>().first.get();
mesh3.SetMesh(Asset::Mesh::Cube);
mesh3.scale = { 0.1f, 0.1f, 0.1f };
......
......@@ -55,14 +55,17 @@ namespace Engine
struct Engine::Renderer::OpenGL::CameraDataUBO
{
Math::Vector4D wsPosition;
Math::Vector3D wsPosition;
float padding1;
Math::Matrix<4, 4, float> viewProjection;
};
struct Engine::Renderer::OpenGL::LightDataUBO
{
Math::Vector4D ambientLight;
uint32_t pointLightCount;
std::array<uint32_t, 3> padding1;
std::array<Math::Vector4D, 10> pointLightIntensity;
std::array<Math::Vector4D, 10> pointLightPos;
};
......@@ -306,6 +309,9 @@ void Engine::Renderer::OpenGL::Initialize(std::any& apiData, CreateInfo&& create
glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);
//glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
//LoadSpriteShader(data);
LoadMeshShader(data);
......@@ -338,11 +344,25 @@ void Engine::Renderer::OpenGL::PrepareRenderingEarly(const std::vector<SpriteID>
UpdateIBODatabase(data, spriteLoadQueue);
UpdateVBODatabase(data, meshLoadQueue);
// Update light count
const auto& renderGraph = Core::GetRenderGraph();
// Update ambient light
constexpr GLintptr ambientLightOffset = offsetof(LightDataUBO, LightDataUBO::ambientLight);
glNamedBufferSubData(data.lightDataUBO, ambientLightOffset, sizeof(renderGraph.ambientLight), renderGraph.ambientLight.Data());
// Update light count
auto pointLightCount = static_cast<uint32_t>(renderGraph.pointLights.size());
constexpr GLintptr pointLightCountDataOffset = offsetof(LightDataUBO, LightDataUBO::pointLightCount);
glNamedBufferSubData(data.lightDataUBO, pointLightCountDataOffset, sizeof(pointLightCount), &pointLightCount);
// Update intensities
const size_t elements = Math::Min(10, renderGraph.pointLights.size());
std::array<Math::Vector4D, 10> intensityData;
for (size_t i = 0; i < elements; i++)
intensityData[i] = renderGraph.pointLights[i].AsVec4();
size_t byteLength = sizeof(Math::Vector4D) * elements;
constexpr GLintptr pointLightIntensityOffset = offsetof(LightDataUBO, LightDataUBO::pointLightIntensity);
glNamedBufferSubData(data.lightDataUBO, pointLightIntensityOffset, byteLength, intensityData.data());
}
bool testing = false;
......@@ -365,7 +385,7 @@ void Engine::Renderer::OpenGL::PrepareRenderingLate()
// Update camera UBO
auto& cameraInfo = Renderer::Core::GetCameraInfo();
const Math::Vector4D& cameraWSPosition = cameraInfo.worldSpacePos.AsVec4();
const Math::Vector3D& cameraWSPosition = cameraInfo.worldSpacePos;
constexpr GLintptr cameraWSPositionDataOffset = offsetof(CameraDataUBO, CameraDataUBO::wsPosition);
glBindBuffer(GL_UNIFORM_BUFFER, data.cameraDataUBO);
glBufferSubData(GL_UNIFORM_BUFFER, cameraWSPositionDataOffset, sizeof(cameraWSPosition), cameraWSPosition.Data());
......
......@@ -5,10 +5,9 @@
#include "OpenGLCreateInfo.hpp"
#include "../Utility/ImgDim.hpp"
#include "../Utility/Color.hpp"
#include "DMath/Vector/Vector.hpp"
#include "DMath/UnitQuaternion.hpp"
#include "DMath/Matrix/Matrix.hpp"
#include <memory>
#include <vector>
......@@ -59,19 +58,17 @@ namespace Engine
API preferredAPI = API::None;
Utility::ImgDim surfaceDimensions{};
void* surfaceHandle = nullptr;
std::function<void(std::string_view)> errorMessageCallback;
OpenGL::CreateInfo openGLCreateInfo{};
};
struct Renderer::PointLight
{
float intensity;
};
struct Renderer::RenderGraph
{
std::vector<SpriteID> sprites;
std::vector<MeshID> meshes;
std::vector<PointLight> pointLights;
Math::Vector3D ambientLight;
std::vector<Math::Vector<3, float>> pointLights;
};
struct Renderer::RenderGraphTransform
......
......@@ -42,7 +42,12 @@ namespace Engine
const auto& pointLightComponents = *pointLightComponentsPtr;
graph.pointLights.resize(pointLightComponents.size());
for (size_t i = 0; i < pointLightComponents.size(); i++)
graph.pointLights[i] = Renderer::PointLight{ pointLightComponents[i].intensity };
{
Math::Vector3D color = pointLightComponents[i].color;
for (auto& element : color)
element = Math::Clamp(element, 0.f, 1.f) * pointLightComponents[i].intensity;
graph.pointLights[i] = color;
}
}
}
......
#pragma once
#include <cstdint>
#include <cassert>
namespace Utility
{
struct Color
{
static constexpr unsigned char length = 4;
public:
static constexpr uint8_t length = 4;
using ValueType = float;
ValueType r;
ValueType g;
ValueType b;
ValueType a;
constexpr void Clamp();
constexpr Color GetClamped() const;
float r;
float g;
float y;
float x;
constexpr void Normalize();
constexpr Color GetNormalized() const;
constexpr ValueType& At(size_t i);
constexpr const ValueType& At(size_t i) const;
constexpr ValueType& operator[](size_t i);
constexpr const ValueType& operator[](size_t i) const;
static constexpr Color Black();
static constexpr Color White();
......@@ -19,6 +37,59 @@ namespace Utility
static constexpr Color Blue();
};
constexpr void Color::Clamp()
{
for (size_t i = 0; i < length; i++)
{
ValueType& element = At(i);
if (element < 0)
element = 0;
else if (element > 1)
element = 1;
}
}
constexpr Color Color::GetClamped() const
{
Color newColor = *this;
newColor.Clamp();
return newColor;
}
constexpr Color::ValueType& Color::At(size_t i)
{
return const_cast<ValueType&>(std::as_const(*this).At(i));
}
constexpr const Color::ValueType& Color::At(size_t i) const
{
assert(0 <= i && i < length);
switch (i)
{
case 0:
return r;
case 1:
return g;
case 2:
return b;
case 3:
return a;
default:
assert(false);
return r;
}
}
constexpr Color::ValueType& Color::operator[](size_t i)
{
return At(i);
}
constexpr const Color::ValueType& Color::operator[](size_t i) const
{
return At(i);
}
constexpr Color Color::Black() { return { 0, 0, 0, 1 }; }
constexpr Color Color::White() { return { 1, 1, 1, 1 }; }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment