refactor rendering
This commit is contained in:
@@ -1,36 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <algorithm>
|
|
||||||
#include <functional>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
namespace td {
|
|
||||||
namespace utils {
|
|
||||||
|
|
||||||
template <typename Listener>
|
|
||||||
class ObjectNotifier {
|
|
||||||
protected:
|
|
||||||
std::vector<Listener*> m_Listeners;
|
|
||||||
|
|
||||||
public:
|
|
||||||
void BindListener(Listener* listener) {
|
|
||||||
m_Listeners.push_back(listener);
|
|
||||||
}
|
|
||||||
|
|
||||||
void UnbindListener(Listener* listener) {
|
|
||||||
auto iter = std::find(m_Listeners.begin(), m_Listeners.end(), listener);
|
|
||||||
|
|
||||||
if (iter == m_Listeners.end()) return;
|
|
||||||
|
|
||||||
m_Listeners.erase(iter);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename Func, typename... Args>
|
|
||||||
void NotifyListeners(Func function, Args... args) {
|
|
||||||
for (Listener* listener : m_Listeners)
|
|
||||||
std::bind(function, listener, args...)();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace utils
|
|
||||||
} // namespace td
|
|
||||||
31
include/td/misc/Signal.h
Normal file
31
include/td/misc/Signal.h
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <functional>
|
||||||
|
#include <td/common/NonCopyable.h>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace td {
|
||||||
|
namespace utils {
|
||||||
|
|
||||||
|
template <typename... Args>
|
||||||
|
class Signal : private NonCopyable {
|
||||||
|
private:
|
||||||
|
using CallBack = std::function<void(Args...)>;
|
||||||
|
|
||||||
|
std::vector<CallBack> m_Callbacks;
|
||||||
|
|
||||||
|
public:
|
||||||
|
void Connect(CallBack&& a_Callback) {
|
||||||
|
m_Callbacks.push_back(std::move(a_Callback));
|
||||||
|
}
|
||||||
|
|
||||||
|
void operator()(Args... args) const {
|
||||||
|
for (const CallBack& callback : m_Callbacks) {
|
||||||
|
callback(args...);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace utils
|
||||||
|
} // namespace td
|
||||||
@@ -1,20 +1,12 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <td/Maths.h>
|
#include <td/Maths.h>
|
||||||
#include <td/misc/ObjectNotifier.h>
|
#include <td/misc/Signal.h>
|
||||||
|
|
||||||
namespace td {
|
namespace td {
|
||||||
namespace render {
|
namespace render {
|
||||||
|
|
||||||
class ICameraListener {
|
class Camera {
|
||||||
public:
|
|
||||||
virtual void OnPerspectiveChange() {}
|
|
||||||
virtual void OnViewChange() {}
|
|
||||||
};
|
|
||||||
|
|
||||||
using CameraNotifier = utils::ObjectNotifier<ICameraListener>;
|
|
||||||
|
|
||||||
class Camera : public CameraNotifier {
|
|
||||||
private:
|
private:
|
||||||
Mat4f m_ViewMatrix;
|
Mat4f m_ViewMatrix;
|
||||||
Mat4f m_ProjectionMatrix;
|
Mat4f m_ProjectionMatrix;
|
||||||
@@ -29,6 +21,9 @@ class Camera : public CameraNotifier {
|
|||||||
float m_Pitch = -PI / 2.0f + 0.0000001f;
|
float m_Pitch = -PI / 2.0f + 0.0000001f;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
utils::Signal<> OnPerspectiveChange;
|
||||||
|
utils::Signal<> OnViewChange;
|
||||||
|
|
||||||
const Mat4f& GetViewMatrix() const {
|
const Mat4f& GetViewMatrix() const {
|
||||||
return m_ViewMatrix;
|
return m_ViewMatrix;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,35 +1,42 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
#include <td/render/Camera.h>
|
#include <td/render/Camera.h>
|
||||||
#include <td/render/loader/GLLoader.h>
|
#include <td/render/loader/GLLoader.h>
|
||||||
#include <memory>
|
#include <td/render/shader/CameraShaderProgram.h>
|
||||||
|
|
||||||
namespace td {
|
namespace td {
|
||||||
namespace render {
|
namespace render {
|
||||||
|
|
||||||
class Renderer {
|
class BasicRenderer {
|
||||||
protected:
|
|
||||||
Camera& m_Camera;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Renderer(Camera& a_Camera) : m_Camera(a_Camera) {}
|
|
||||||
virtual ~Renderer() {}
|
|
||||||
|
|
||||||
virtual void Render() = 0;
|
virtual void Render() = 0;
|
||||||
|
|
||||||
void Render(const GL::VertexArray& a_Vao);
|
void Render(const GL::VertexArray& a_Vao);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class Renderer : public BasicRenderer {
|
||||||
|
protected:
|
||||||
|
std::unique_ptr<shader::CameraShaderProgram> m_Shader;
|
||||||
|
Camera& m_Camera;
|
||||||
|
|
||||||
|
public:
|
||||||
|
Renderer(std::unique_ptr<shader::CameraShaderProgram>&& a_Shader, Camera& a_Camera);
|
||||||
|
|
||||||
|
virtual ~Renderer() {}
|
||||||
|
};
|
||||||
|
|
||||||
class RenderPipeline {
|
class RenderPipeline {
|
||||||
private:
|
private:
|
||||||
std::vector<std::unique_ptr<Renderer>> m_Renderers;
|
std::vector<std::unique_ptr<BasicRenderer>> m_Renderers;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
RenderPipeline();
|
RenderPipeline();
|
||||||
~RenderPipeline() = default;
|
~RenderPipeline() = default;
|
||||||
|
|
||||||
void AddRenderer(std::unique_ptr<Renderer>&& a_Renderer) {
|
template<typename T, typename... Args>
|
||||||
m_Renderers.push_back(std::move(a_Renderer));
|
void AddRenderer(Args&&... args) {
|
||||||
|
m_Renderers.push_back(std::make_unique<T>(args ...));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Clear() {
|
void Clear() {
|
||||||
|
|||||||
@@ -2,16 +2,15 @@
|
|||||||
|
|
||||||
#include <td/game/World.h>
|
#include <td/game/World.h>
|
||||||
#include <td/render/Renderer.h>
|
#include <td/render/Renderer.h>
|
||||||
#include <td/render/shader/WorldShader.h>
|
|
||||||
#include <td/render/loader/GLLoader.h>
|
#include <td/render/loader/GLLoader.h>
|
||||||
|
#include <td/render/shader/WorldShader.h>
|
||||||
|
|
||||||
namespace td {
|
namespace td {
|
||||||
namespace render {
|
namespace render {
|
||||||
|
|
||||||
class WorldRenderer : public Renderer, public ICameraListener {
|
class WorldRenderer : public Renderer {
|
||||||
private:
|
private:
|
||||||
const game::World& m_World;
|
const game::World& m_World;
|
||||||
shader::WorldShader m_Shader;
|
|
||||||
std::unique_ptr<GL::VertexArray> m_WorldVao;
|
std::unique_ptr<GL::VertexArray> m_WorldVao;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@@ -19,9 +18,6 @@ class WorldRenderer : public Renderer, public ICameraListener {
|
|||||||
virtual ~WorldRenderer();
|
virtual ~WorldRenderer();
|
||||||
|
|
||||||
virtual void Render() override;
|
virtual void Render() override;
|
||||||
|
|
||||||
virtual void OnPerspectiveChange() override;
|
|
||||||
virtual void OnViewChange() override;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace render
|
} // namespace render
|
||||||
|
|||||||
23
include/td/render/shader/CameraShaderProgram.h
Normal file
23
include/td/render/shader/CameraShaderProgram.h
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <td/render/shader/ShaderProgram.h>
|
||||||
|
|
||||||
|
namespace td {
|
||||||
|
namespace shader {
|
||||||
|
|
||||||
|
class CameraShaderProgram : public ShaderProgram {
|
||||||
|
private:
|
||||||
|
unsigned int m_LocationProjection = 0, m_LocationView = 0;
|
||||||
|
|
||||||
|
public:
|
||||||
|
CameraShaderProgram() {}
|
||||||
|
|
||||||
|
void SetProjectionMatrix(const Mat4f& proj) const;
|
||||||
|
void SetViewMatrix(const Mat4f& view) const;
|
||||||
|
|
||||||
|
virtual void GetAllUniformLocation();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace shader
|
||||||
|
} // namespace td
|
||||||
@@ -1,10 +1,15 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <string>
|
||||||
#include <td/Maths.h>
|
#include <td/Maths.h>
|
||||||
#include <td/render/OpenGL.h>
|
#include <td/render/OpenGL.h>
|
||||||
#include <string>
|
|
||||||
|
|
||||||
namespace td {
|
namespace td {
|
||||||
|
|
||||||
|
namespace render {
|
||||||
|
class Renderer;
|
||||||
|
} // namespace render
|
||||||
|
|
||||||
namespace shader {
|
namespace shader {
|
||||||
|
|
||||||
class ShaderProgram {
|
class ShaderProgram {
|
||||||
@@ -15,10 +20,10 @@ class ShaderProgram {
|
|||||||
void Start() const;
|
void Start() const;
|
||||||
void Stop() const;
|
void Stop() const;
|
||||||
|
|
||||||
|
protected:
|
||||||
void LoadProgramFile(const std::string& vertexFile, const std::string& fragmentFile);
|
void LoadProgramFile(const std::string& vertexFile, const std::string& fragmentFile);
|
||||||
void LoadProgram(const std::string& vertexSource, const std::string& fragmentSource);
|
void LoadProgram(const std::string& vertexSource, const std::string& fragmentSource);
|
||||||
|
|
||||||
protected:
|
|
||||||
virtual void GetAllUniformLocation() = 0;
|
virtual void GetAllUniformLocation() = 0;
|
||||||
int GetUniformLocation(const std::string& uniformName) const;
|
int GetUniformLocation(const std::string& uniformName) const;
|
||||||
|
|
||||||
|
|||||||
@@ -1,20 +1,13 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <td/render/shader/ShaderProgram.h>
|
#include <td/render/shader/CameraShaderProgram.h>
|
||||||
|
|
||||||
namespace td {
|
namespace td {
|
||||||
namespace shader {
|
namespace shader {
|
||||||
|
|
||||||
class WorldShader : public ShaderProgram {
|
class WorldShader : public CameraShaderProgram {
|
||||||
private:
|
|
||||||
unsigned int m_LocationProjection = 0, m_LocationView = 0;
|
|
||||||
protected:
|
|
||||||
void GetAllUniformLocation();
|
|
||||||
public:
|
public:
|
||||||
WorldShader();
|
WorldShader();
|
||||||
|
|
||||||
void SetProjectionMatrix(const Mat4f& proj) const;
|
|
||||||
void SetViewMatrix(const Mat4f& view) const;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace shader
|
} // namespace shader
|
||||||
|
|||||||
@@ -196,7 +196,7 @@ int main(int argc, char** argv) {
|
|||||||
td::render::Camera cam;
|
td::render::Camera cam;
|
||||||
|
|
||||||
td::render::RenderPipeline renderer;
|
td::render::RenderPipeline renderer;
|
||||||
renderer.AddRenderer(std::make_unique<td::render::WorldRenderer>(cam, w));
|
renderer.AddRenderer<td::render::WorldRenderer>(cam, w);
|
||||||
|
|
||||||
cam.SetCamPos({77, 25, 13});
|
cam.SetCamPos({77, 25, 13});
|
||||||
cam.UpdatePerspective(display.GetAspectRatio());
|
cam.UpdatePerspective(display.GetAspectRatio());
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ namespace render {
|
|||||||
void Camera::UpdatePerspective(float a_AspectRatio) {
|
void Camera::UpdatePerspective(float a_AspectRatio) {
|
||||||
m_ProjectionMatrix = maths::Perspective(80.0f / 180.0f * PI, a_AspectRatio, 0.1f, 160.0f);
|
m_ProjectionMatrix = maths::Perspective(80.0f / 180.0f * PI, a_AspectRatio, 0.1f, 160.0f);
|
||||||
m_InvProjectionMatrix = maths::Inverse(m_ProjectionMatrix);
|
m_InvProjectionMatrix = maths::Inverse(m_ProjectionMatrix);
|
||||||
NotifyListeners(&ICameraListener::OnPerspectiveChange);
|
OnPerspectiveChange();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Camera::SetCamPos(const Vec3f& a_NewPos) {
|
void Camera::SetCamPos(const Vec3f& a_NewPos) {
|
||||||
@@ -21,7 +21,7 @@ void Camera::SetCamPos(const Vec3f& a_NewPos) {
|
|||||||
m_CamPos = a_NewPos;
|
m_CamPos = a_NewPos;
|
||||||
m_ViewMatrix = maths::Look(m_CamPos, front, { 0, 1, 0 });
|
m_ViewMatrix = maths::Look(m_CamPos, front, { 0, 1, 0 });
|
||||||
m_InvViewMatrix = maths::Transpose(maths::Inverse(m_ViewMatrix)); // why transpose ? I don't know
|
m_InvViewMatrix = maths::Transpose(maths::Inverse(m_ViewMatrix)); // why transpose ? I don't know
|
||||||
NotifyListeners(&ICameraListener::OnViewChange);
|
OnViewChange();
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace render
|
} // namespace render
|
||||||
|
|||||||
@@ -5,13 +5,27 @@
|
|||||||
namespace td {
|
namespace td {
|
||||||
namespace render {
|
namespace render {
|
||||||
|
|
||||||
void Renderer::Render(const GL::VertexArray& a_Vao) {
|
void BasicRenderer::Render(const GL::VertexArray& a_Vao) {
|
||||||
a_Vao.Bind();
|
a_Vao.Bind();
|
||||||
glDrawArrays(GL_TRIANGLES, 0, a_Vao.GetVertexCount());
|
glDrawArrays(GL_TRIANGLES, 0, a_Vao.GetVertexCount());
|
||||||
// glDrawElements(GL_TRIANGLES, a_Vao.GetVertexCount(), GL_UNSIGNED_INT, nullptr);
|
// glDrawElements(GL_TRIANGLES, a_Vao.GetVertexCount(), GL_UNSIGNED_INT, nullptr);
|
||||||
a_Vao.Unbind();
|
a_Vao.Unbind();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Renderer::Renderer(std::unique_ptr<shader::CameraShaderProgram>&& a_Shader, Camera& a_Camera) :
|
||||||
|
m_Shader(std::move(a_Shader)), m_Camera(a_Camera) {
|
||||||
|
a_Camera.OnPerspectiveChange.Connect([this]() {
|
||||||
|
m_Shader->Start();
|
||||||
|
m_Shader->SetProjectionMatrix(m_Camera.GetProjectionMatrix());
|
||||||
|
});
|
||||||
|
|
||||||
|
a_Camera.OnViewChange.Connect([this]() {
|
||||||
|
m_Shader->Start();
|
||||||
|
m_Shader->SetViewMatrix(m_Camera.GetViewMatrix());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
RenderPipeline::RenderPipeline() {
|
RenderPipeline::RenderPipeline() {
|
||||||
glEnable(GL_TEXTURE_2D);
|
glEnable(GL_TEXTURE_2D);
|
||||||
glEnable(GL_BLEND);
|
glEnable(GL_BLEND);
|
||||||
|
|||||||
@@ -7,28 +7,17 @@
|
|||||||
namespace td {
|
namespace td {
|
||||||
namespace render {
|
namespace render {
|
||||||
|
|
||||||
WorldRenderer::WorldRenderer(Camera& a_Camera, const game::World& a_World) : Renderer(a_Camera), m_World(a_World) {
|
WorldRenderer::WorldRenderer(Camera& a_Camera, const game::World& a_World) : Renderer(std::make_unique<shader::WorldShader>(), a_Camera), m_World(a_World) {
|
||||||
m_WorldVao = std::make_unique<GL::VertexArray>(std::move(WorldLoader::LoadWorldModel(&a_World)));
|
m_WorldVao = std::make_unique<GL::VertexArray>(std::move(WorldLoader::LoadWorldModel(&a_World)));
|
||||||
a_Camera.BindListener(this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
WorldRenderer::~WorldRenderer() {}
|
WorldRenderer::~WorldRenderer() {}
|
||||||
|
|
||||||
void WorldRenderer::Render() {
|
void WorldRenderer::Render() {
|
||||||
m_Shader.Start();
|
m_Shader->Start();
|
||||||
Renderer::Render(*m_WorldVao);
|
Renderer::Render(*m_WorldVao);
|
||||||
ImGui::ShowDemoWindow();
|
ImGui::ShowDemoWindow();
|
||||||
}
|
}
|
||||||
|
|
||||||
void WorldRenderer::OnPerspectiveChange() {
|
|
||||||
m_Shader.Start();
|
|
||||||
m_Shader.SetProjectionMatrix(m_Camera.GetProjectionMatrix());
|
|
||||||
}
|
|
||||||
|
|
||||||
void WorldRenderer::OnViewChange() {
|
|
||||||
m_Shader.Start();
|
|
||||||
m_Shader.SetViewMatrix(m_Camera.GetViewMatrix());
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace render
|
} // namespace render
|
||||||
} // namespace td
|
} // namespace td
|
||||||
|
|||||||
21
src/td/render/shader/CameraShaderProgram.cpp
Normal file
21
src/td/render/shader/CameraShaderProgram.cpp
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
#include <td/render/shader/CameraShaderProgram.h>
|
||||||
|
|
||||||
|
namespace td {
|
||||||
|
namespace shader {
|
||||||
|
|
||||||
|
void CameraShaderProgram::SetProjectionMatrix(const Mat4f& proj) const {
|
||||||
|
LoadMat4(m_LocationProjection, proj);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CameraShaderProgram::SetViewMatrix(const Mat4f& view) const {
|
||||||
|
LoadMat4(m_LocationView, view);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CameraShaderProgram::GetAllUniformLocation() {
|
||||||
|
m_LocationProjection = static_cast<unsigned int>(GetUniformLocation("projectionMatrix"));
|
||||||
|
m_LocationView = static_cast<unsigned int>(GetUniformLocation("viewMatrix"));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace shader
|
||||||
|
} // namespace td
|
||||||
@@ -81,22 +81,9 @@ void main(void){
|
|||||||
)";
|
)";
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
WorldShader::WorldShader() : ShaderProgram() {
|
WorldShader::WorldShader() : CameraShaderProgram() {
|
||||||
ShaderProgram::LoadProgram(vertexSource, fragmentSource);
|
ShaderProgram::LoadProgram(vertexSource, fragmentSource);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WorldShader::GetAllUniformLocation() {
|
|
||||||
m_LocationProjection = static_cast<unsigned int>(GetUniformLocation("projectionMatrix"));
|
|
||||||
m_LocationView = static_cast<unsigned int>(GetUniformLocation("viewMatrix"));
|
|
||||||
}
|
|
||||||
|
|
||||||
void WorldShader::SetProjectionMatrix(const Mat4f& proj) const {
|
|
||||||
LoadMat4(m_LocationProjection, proj);
|
|
||||||
}
|
|
||||||
|
|
||||||
void WorldShader::SetViewMatrix(const Mat4f& view) const {
|
|
||||||
LoadMat4(m_LocationView, view);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace shader
|
} // namespace shader
|
||||||
} // namespace td
|
} // namespace td
|
||||||
Reference in New Issue
Block a user