diff --git a/Data/Shaders/Mesh/Mesh.frag b/Data/Shaders/Mesh/Mesh.frag index 183e6756889380be8279b06cbc625a9951444024..72a9daef6d2e5aafedcbfea8edc2e8ca88eabb03 100644 --- a/Data/Shaders/Mesh/Mesh.frag +++ b/Data/Shaders/Mesh/Mesh.frag @@ -1,5 +1,11 @@ #version 420 core +layout(std140, binding = 1) uniform LightData +{ + uint pointLightCount; + vec4 pointLightPos[10]; +} lightData; + in FragData { vec3 wsPosition; @@ -7,11 +13,13 @@ in FragData vec2 uv; } fragData; -vec3 lightPos = vec3(4.0, 5.0, 6.0); - void main() { - vec3 pointToLight = normalize(lightPos - fragData.wsPosition); - float test = max(dot(pointToLight, fragData.wsNormal), 0); + float test = 0.0; + for (int i = 0; i < lightData.pointLightCount; i++) + { + vec3 pointToLight = normalize(lightData.pointLightPos[i].xyz - fragData.wsPosition); + test += max(dot(pointToLight, fragData.wsNormal), 0); + } gl_FragColor = vec4(test, test, test, test); } diff --git a/external/DMath b/external/DMath index 0d9c06d9e19a54a8747147a370d5e73dfe616220..a17ca749764c26300ffaf2d8ffa13da38cc4d630 160000 --- a/external/DMath +++ b/external/DMath @@ -1 +1 @@ -Subproject commit 0d9c06d9e19a54a8747147a370d5e73dfe616220 +Subproject commit a17ca749764c26300ffaf2d8ffa13da38cc4d630 diff --git a/src/Engine/Application.cpp b/src/Engine/Application.cpp index 9663b05cdf649442834d0f3e532c55eb96256ee9..72df58ef66bdbc665017983b5d6eba0ec7e7a694 100644 --- a/src/Engine/Application.cpp +++ b/src/Engine/Application.cpp @@ -53,8 +53,8 @@ namespace Engine data = std::make_unique<Data>(); data->isRunning = true; - glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); - glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); + glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4); + glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2); GLFWwindow* window = glfwCreateWindow(defaultWindowSize.width, defaultWindowSize.height, "My Title", NULL, NULL); if (!window) { @@ -133,6 +133,15 @@ Engine::Input::Raw::Button Engine::Application::Core::APIKeyToButton(int32_t api case GLFW_KEY_LEFT_CONTROL: return Button::LeftCtrl; + case GLFW_KEY_UP: + return Button::Up; + case GLFW_KEY_DOWN: + return Button::Down; + case GLFW_KEY_LEFT: + return Button::Left; + case GLFW_KEY_RIGHT: + return Button::Right; + case GLFW_KEY_A: return Button::A; case GLFW_KEY_B: diff --git a/src/Engine/Engine.cpp b/src/Engine/Engine.cpp index ac5b7a5317e5c9fa81afb2073b6b312c81cdbd00..5b001717dc6a4afcd278b60a39158c63507c6154 100644 --- a/src/Engine/Engine.cpp +++ b/src/Engine/Engine.cpp @@ -69,8 +69,8 @@ void Engine::Core::Run() auto& sceneObject1 = scene1.NewSceneObject(); - auto& sprite1 = sceneObject1.AddComponent<Components::MeshRenderer>().first.get(); - sprite1.SetMesh(Asset::Mesh::Helmet); + auto& mesh1 = sceneObject1.AddComponent<Components::MeshRenderer>().first.get(); + mesh1.SetMesh(Asset::Mesh::Helmet); auto& mesh2 = sceneObject1.AddComponent<Components::MeshRenderer>().first.get(); mesh2.SetMesh(Asset::Mesh::Cube); @@ -80,9 +80,19 @@ void Engine::Core::Run() auto& camera = objCamera.AddComponent<Components::Camera>().first.get(); camera.positionOffset.z = 5.f; - auto& obj3 = scene1.NewSceneObject(); - obj3.transform.localPosition = { 5.f, 5.f, 10.f }; - Components::PointLight& light1 = obj3.AddComponent<Components::PointLight>().first.get(); + auto& lightObj = scene1.NewSceneObject(); + lightObj.transform.localPosition = { 2.5f, 2.5f, 2.5f }; + Components::PointLight& light1 = lightObj.AddComponent<Components::PointLight>().first.get(); + auto& mesh3 = lightObj.AddComponent<Components::MeshRenderer>().first.get(); + mesh3.SetMesh(Asset::Mesh::Cube); + mesh3.scale = { 0.1f, 0.1f, 0.1f }; + + auto& obj4 = scene1.NewSceneObject(); + obj4.transform.localPosition = { 0.f, -7.5f, -10.f }; + Components::PointLight& light3 = obj4.AddComponent<Components::PointLight>().first.get(); + auto& mesh4 = obj4.AddComponent<Components::MeshRenderer>().first.get(); + mesh4.SetMesh(Asset::Mesh::Cube); + mesh4.scale = { 0.1f, 0.1f, 0.1f }; Renderer::RenderGraph graph; @@ -109,6 +119,15 @@ void Engine::Core::Run() camera.positionOffset += Math::Vector3D::Down() * speed * scene1.GetTimeData().GetDeltaTime(); camera.LookAt({ 0, 0, 0 }); + if (Input::Raw::GetValue(Input::Raw::Button::Up)) + lightObj.transform.localPosition.z += speed * scene1.GetTimeData().GetDeltaTime(); + if (Input::Raw::GetValue(Input::Raw::Button::Down)) + lightObj.transform.localPosition.z -= speed * scene1.GetTimeData().GetDeltaTime(); + if (Input::Raw::GetValue(Input::Raw::Button::Left)) + lightObj.transform.localPosition.x -= speed * scene1.GetTimeData().GetDeltaTime(); + if (Input::Raw::GetValue(Input::Raw::Button::Right)) + lightObj.transform.localPosition.x += speed * scene1.GetTimeData().GetDeltaTime(); + if (Input::Raw::GetEventType(Input::Raw::Button::C) == Input::EventType::Pressed) { scene1.Clear(); diff --git a/src/Engine/Renderer/OpenGL.cpp b/src/Engine/Renderer/OpenGL.cpp index 5cd066160f9b28561f7b12b5fa83a92abfbb02fa..065f8be0db7ffad6a4ecfa77090d58f250d0b3ab 100644 --- a/src/Engine/Renderer/OpenGL.cpp +++ b/src/Engine/Renderer/OpenGL.cpp @@ -44,8 +44,11 @@ namespace Engine void Draw_SpritePass(const Data& data, const std::vector<SpriteID>& sprites, const std::vector<Math::Matrix4x4>& transforms); void Draw_MeshPass(const Data& data, const std::vector<MeshID>& meshes, const std::vector<Math::Matrix4x4>& transforms); + void CreateStandardUBOs(Data& data); void LoadSpriteShader(Data& data); void LoadMeshShader(Data& data); + + inline void PrintGLError(const char* string = ""); } } } @@ -58,7 +61,8 @@ struct Engine::Renderer::OpenGL::CameraDataUBO struct Engine::Renderer::OpenGL::LightDataUBO { uint32_t pointLightCount; - std::array<Math::Vector4D, 10> pointLights; + std::array<uint32_t, 3> padding; + std::array<Math::Vector4D, 10> pointLightPos; }; struct Engine::Renderer::OpenGL::VertexBufferObject @@ -96,6 +100,7 @@ struct Engine::Renderer::OpenGL::Data std::unordered_map<SpriteID, IBO> iboDatabase; GLuint cameraDataUBO; + GLuint lightDataUBO; GLuint samplerObject; GLuint spriteProgram; @@ -104,8 +109,6 @@ struct Engine::Renderer::OpenGL::Data GLuint meshProgram; GLint meshModelUniform; - - }; Engine::Renderer::OpenGL::Data& Engine::Renderer::OpenGL::GetData() { return std::any_cast<Data&>(Core::GetAPIData()); } @@ -232,7 +235,44 @@ void Engine::Renderer::OpenGL::LoadMeshShader(Engine::Renderer::OpenGL::Data &da // Grab uniforms data.meshModelUniform = glGetUniformLocation(data.meshProgram, "model"); - glUniformBlockBinding(data.meshProgram, 0, 0); + auto test = glGetUniformBlockIndex(data.meshProgram, "LightData"); + glUniformBlockBinding(data.meshProgram, 1, 1); +} + +inline void Engine::Renderer::OpenGL::PrintGLError(const char* string) +{ + if constexpr (enableDebug) + { + auto errorEnum = glGetError(); + if (errorEnum != 0) + { + auto errorString = glewGetErrorString(errorEnum); + std::cout << string << errorString << std::endl; + } + } +} + +void Engine::Renderer::OpenGL::CreateStandardUBOs(Data& data) +{ + std::array<GLuint, 2> buffers; + glGenBuffers(2, buffers.data()); + + PrintGLError("Making buffers for standard UBOs: "); + + data.cameraDataUBO = buffers[0]; + data.lightDataUBO = buffers[1]; + + // Make camera ubo + glBindBuffer(GL_UNIFORM_BUFFER, data.cameraDataUBO); + glNamedBufferData(data.cameraDataUBO, sizeof(CameraDataUBO), nullptr, GL_DYNAMIC_DRAW); + glBindBufferRange(GL_UNIFORM_BUFFER, 0, data.cameraDataUBO, 0, sizeof(CameraDataUBO)); + PrintGLError("Making Camera UBO: "); + + // Make light ubo + glBindBuffer(GL_UNIFORM_BUFFER, data.lightDataUBO); + glNamedBufferData(data.lightDataUBO, sizeof(LightDataUBO), nullptr, GL_DYNAMIC_DRAW); + glBindBufferRange(GL_UNIFORM_BUFFER, 1, data.lightDataUBO, 0, sizeof(LightDataUBO)); + PrintGLError("Making LightData UBO: "); } void Engine::Renderer::OpenGL::Initialize(std::any& apiData, CreateInfo&& createInfo) @@ -245,11 +285,7 @@ void Engine::Renderer::OpenGL::Initialize(std::any& apiData, CreateInfo&& create data.glSwapBuffers = std::move(createInfo.glSwapBuffers); - // Make camera ubo - glGenBuffers(1, &data.cameraDataUBO); - glBindBuffer(GL_UNIFORM_BUFFER, data.cameraDataUBO); - glBufferData(GL_UNIFORM_BUFFER, sizeof(CameraDataUBO), nullptr, GL_DYNAMIC_DRAW); - glBindBufferRange(GL_UNIFORM_BUFFER, 0, data.cameraDataUBO, 0, sizeof(CameraDataUBO)); + CreateStandardUBOs(data); // Gen sampler glGenSamplers(1, &data.samplerObject); @@ -265,22 +301,16 @@ void Engine::Renderer::OpenGL::Initialize(std::any& apiData, CreateInfo&& create else assert(false); - - glEnable(GL_DEPTH_TEST); glEnable(GL_CULL_FACE); glCullFace(GL_BACK); + //LoadSpriteShader(data); LoadMeshShader(data); - if constexpr (enableDebug) - { - auto errorEnum = glGetError(); - if (errorEnum != 0) - std::cout << glewGetErrorString(errorEnum) << std::endl; - } + PrintGLError("End of GL init: "); } void Engine::Renderer::OpenGL::Terminate(std::any& apiData) @@ -303,43 +333,56 @@ void Engine::Renderer::OpenGL::Terminate(std::any& apiData) void Engine::Renderer::OpenGL::PrepareRenderingEarly(const std::vector<SpriteID>& spriteLoadQueue, const std::vector<MeshID>& meshLoadQueue) { - UpdateIBODatabase(GetData(), spriteLoadQueue); - UpdateVBODatabase(GetData(), meshLoadQueue); -} + Data& data = GetData(); -void Engine::Renderer::OpenGL::PrepareRenderingLate() -{ - // Update lights positions + UpdateIBODatabase(data, spriteLoadQueue); + UpdateVBODatabase(data, meshLoadQueue); + + // Update light count + const auto& renderGraph = Core::GetRenderGraph(); + uint32_t pointLightCount = renderGraph.pointLights.size(); + glNamedBufferSubData(data.lightDataUBO, 0, sizeof(uint32_t), &pointLightCount); } -void Engine::Renderer::OpenGL::Draw() +void Engine::Renderer::OpenGL::PrepareRenderingLate() { Data& data = GetData(); - glClearColor(1.f, 0.f, 0.f, 1.f); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + const auto& renderGraphTransform = Core::GetRenderGraphTransform(); - auto& viewport = Renderer::GetViewport(0); + // Update lights positions + const size_t elements = Math::Min(10, renderGraphTransform.pointLights.size()); + std::array<Math::Vector4D, 10> posData; + for (size_t i = 0; i < elements; i++) + posData[i] = renderGraphTransform.pointLights[i].AsVec4(); + size_t byteLength = sizeof(Math::Vector4D) * elements; + + glNamedBufferSubData(data.lightDataUBO, sizeof(uint32_t) * 4, byteLength, posData.data()); + auto& viewport = Renderer::GetViewport(0); auto& cameraInfo = Renderer::Core::GetCameraInfo(); auto viewMatrix = cameraInfo.GetModel(viewport.GetDimensions().GetAspectRatio()); glNamedBufferSubData(data.cameraDataUBO, 0, sizeof(CameraDataUBO::viewProjection), viewMatrix.data.data()); +} + +void Engine::Renderer::OpenGL::Draw() +{ + Data& data = GetData(); + + glClearColor(0.25f, 0.f, 0.f, 1.f); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); const auto& renderGraph = Core::GetRenderGraph(); const auto& renderGraphTransform = Core::GetRenderGraphTransform(); - Draw_SpritePass(data, renderGraph.sprites, renderGraphTransform.sprites); Draw_MeshPass(data, renderGraph.meshes, renderGraphTransform.meshes); - if constexpr (enableDebug) - { - auto errorEnum = glGetError(); - if (errorEnum != 0) - std::cout << glewGetErrorString(errorEnum) << std::endl; - } + PrintGLError("End of GL tick: "); + + auto& viewport = Renderer::GetViewport(0); data.glSwapBuffers(viewport.GetSurfaceHandle()); } diff --git a/src/Engine/Renderer/Renderer.cpp b/src/Engine/Renderer/Renderer.cpp index ce93f8ad7bfe8b279ec478e56cf1da838924755d..97aef6c8d07ec283d17e2a4b51169a212070c774 100644 --- a/src/Engine/Renderer/Renderer.cpp +++ b/src/Engine/Renderer/Renderer.cpp @@ -109,20 +109,22 @@ void Engine::Renderer::Core::Terminate() void Engine::Renderer::Core::PrepareRenderingEarly(RenderGraph& renderGraphInput) { - auto& renderGraph = data->renderGraph; + Data& data = *Core::data; - UpdateAssetReferences(*data, renderGraph, &renderGraphInput); + auto& renderGraph = data.renderGraph; + + UpdateAssetReferences(data, renderGraph, &renderGraphInput); std::swap(renderGraph, renderGraphInput); - if (!data->loadSpriteQueue.empty() || !data->loadMeshQueue.empty()) + if (!data.loadSpriteQueue.empty() || !data.loadMeshQueue.empty()) std::cout << "Loading sprite/mesh resource(s)..." << std::endl; - data->PrepareRenderingEarly(data->loadSpriteQueue, data->loadMeshQueue); + data.PrepareRenderingEarly(data.loadSpriteQueue, data.loadMeshQueue); - data->loadSpriteQueue.clear(); - data->unloadSpriteQueue.clear(); - data->loadMeshQueue.clear(); - data->unloadMeshQueue.clear(); + data.loadSpriteQueue.clear(); + data.unloadSpriteQueue.clear(); + data.loadMeshQueue.clear(); + data.unloadMeshQueue.clear(); } void Engine::Renderer::Core::PrepareRenderingLate(RenderGraphTransform &input) @@ -133,6 +135,8 @@ void Engine::Renderer::Core::PrepareRenderingLate(RenderGraphTransform &input) assert(IsCompatible(renderGraph, input)); std::swap(renderGraphTransform, input); + + data->PrepareRenderingLate(); } void Engine::Renderer::Core::Draw()