switch renderer submission from macros to lambdas

This commit is contained in:
2025-11-30 15:55:23 +08:00
parent 3f1515bb63
commit 4cdd405ba9
15 changed files with 370 additions and 272 deletions

View File

@ -54,7 +54,7 @@ namespace Prism
for (Layer* layer : m_LayerStack) for (Layer* layer : m_LayerStack)
layer->OnUpdate(m_TimeStep); layer->OnUpdate(m_TimeStep);
PM_RENDER_S({ self->RenderImGui(); }); Renderer::Submit([this](){ this->RenderImGui(); });
Renderer::Get().WaitAndRender(); Renderer::Get().WaitAndRender();
@ -189,7 +189,7 @@ namespace Prism
} }
m_Minimized = false; m_Minimized = false;
PM_RENDER_2(width, height, { glViewport(0, 0, width, height); }); Renderer::Submit([=]() { glViewport(0, 0, width, height); });
auto& fbs = FrameBufferPool::GetGlobal()->GetAll(); auto& fbs = FrameBufferPool::GetGlobal()->GetAll();
for (auto& fb : fbs) for (auto& fb : fbs)
{ {

View File

@ -28,26 +28,26 @@ namespace Prism
{ {
m_LocalData = Buffer::Copy(data, size); m_LocalData = Buffer::Copy(data, size);
PM_RENDER_S({ Renderer::Submit([=](){
glCreateBuffers(1, &self->m_RendererID); glCreateBuffers(1, &m_RendererID);
glNamedBufferData(self->m_RendererID, self->m_Size, self->m_LocalData.Data, OpenGLUsage(self->m_Usage)); glNamedBufferData(m_RendererID, m_Size, m_LocalData.Data, OpenGLUsage(m_Usage));
}); });
} }
OpenGLVertexBuffer::OpenGLVertexBuffer(const uint32_t size, const VertexBufferUsage usage) OpenGLVertexBuffer::OpenGLVertexBuffer(const uint32_t size, const VertexBufferUsage usage)
: m_Size(size), m_Usage(usage) : m_Size(size), m_Usage(usage)
{ {
PM_RENDER_S({ Renderer::Submit([this](){
glCreateBuffers(1, &self->m_RendererID); glCreateBuffers(1, &m_RendererID);
glNamedBufferData(self->m_RendererID, self->m_Size, nullptr, OpenGLUsage(self->m_Usage)); glNamedBufferData(m_RendererID, m_Size, nullptr, OpenGLUsage(m_Usage));
}); });
} }
OpenGLVertexBuffer::~OpenGLVertexBuffer() OpenGLVertexBuffer::~OpenGLVertexBuffer()
{ {
PM_RENDER_S({ Renderer::Submit([this](){
glDeleteBuffers(1, &self->m_RendererID); glDeleteBuffers(1, &m_RendererID);
}); });
} }
@ -55,15 +55,15 @@ namespace Prism
{ {
m_LocalData = Buffer::Copy(buffer, size); m_LocalData = Buffer::Copy(buffer, size);
m_Size = size; m_Size = size;
PM_RENDER_S1(offset, { Renderer::Submit([this, offset]() {
glNamedBufferSubData(self->m_RendererID, offset, self->m_Size, self->m_LocalData.Data); glNamedBufferSubData(m_RendererID, offset, m_Size, m_LocalData.Data);
}); });
} }
void OpenGLVertexBuffer::Bind() const void OpenGLVertexBuffer::Bind() const
{ {
PM_RENDER_S({ Renderer::Submit([this](){
glBindBuffer(GL_ARRAY_BUFFER, self->m_RendererID); glBindBuffer(GL_ARRAY_BUFFER, m_RendererID);
glEnableVertexAttribArray(0); glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(float) * 5, 0); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(float) * 5, 0);
@ -81,16 +81,16 @@ namespace Prism
{ {
m_LocalData = Buffer::Copy(data, size); m_LocalData = Buffer::Copy(data, size);
PM_RENDER_S({ Renderer::Submit([this](){
glCreateBuffers(1, &self->m_RendererID); glCreateBuffers(1, &m_RendererID);
glNamedBufferData(self->m_RendererID, self->m_Size, self->m_LocalData.Data, GL_STATIC_DRAW); glNamedBufferData(m_RendererID, m_Size, m_LocalData.Data, GL_STATIC_DRAW);
}); });
} }
OpenGLIndexBuffer::~OpenGLIndexBuffer() OpenGLIndexBuffer::~OpenGLIndexBuffer()
{ {
PM_RENDER_S({ Renderer::Submit([this](){
glDeleteBuffers(1, &self->m_RendererID); glDeleteBuffers(1, &m_RendererID);
}); });
} }
@ -98,15 +98,15 @@ namespace Prism
{ {
m_LocalData = Buffer::Copy(data, size); m_LocalData = Buffer::Copy(data, size);
m_Size = size; m_Size = size;
PM_RENDER_S1(offset, { Renderer::Submit([this, offset](){
glNamedBufferSubData(self->m_RendererID, offset, self->m_Size, self->m_LocalData.Data); glNamedBufferSubData(m_RendererID, offset, m_Size, m_LocalData.Data);
}); });
} }
void OpenGLIndexBuffer::Bind() const void OpenGLIndexBuffer::Bind() const
{ {
PM_RENDER_S({ Renderer::Submit([this](){
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, self->m_RendererID); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_RendererID);
}); });
} }
} }

View File

@ -19,22 +19,22 @@ namespace Prism
OpenGLFrameBuffer::~OpenGLFrameBuffer() OpenGLFrameBuffer::~OpenGLFrameBuffer()
{ {
PM_RENDER_S({ Renderer::Submit([this](){
glDeleteFramebuffers(1, &self->m_RendererID); glDeleteFramebuffers(1, &m_RendererID);
}); });
} }
void OpenGLFrameBuffer::Bind() const void OpenGLFrameBuffer::Bind() const
{ {
PM_RENDER_S({ Renderer::Submit([this](){
glBindFramebuffer(GL_FRAMEBUFFER, self->m_RendererID); glBindFramebuffer(GL_FRAMEBUFFER, m_RendererID);
glViewport(0, 0, self->m_Specification.Width, self->m_Specification.Height); glViewport(0, 0, m_Specification.Width, m_Specification.Height);
}); });
} }
void OpenGLFrameBuffer::Unbind() const void OpenGLFrameBuffer::Unbind() const
{ {
PM_RENDER_S({ Renderer::Submit([this](){
glBindFramebuffer(GL_FRAMEBUFFER, 0); glBindFramebuffer(GL_FRAMEBUFFER, 0);
}); });
} }
@ -46,41 +46,41 @@ namespace Prism
m_Specification.Width = width; m_Specification.Width = width;
m_Specification.Height = height; m_Specification.Height = height;
PM_RENDER_S({ Renderer::Submit([this](){
if (self->m_RendererID) if (m_RendererID)
{ {
glDeleteFramebuffers(1, &self->m_RendererID); glDeleteFramebuffers(1, &m_RendererID);
glDeleteTextures(1, &self->m_ColorAttachment); glDeleteTextures(1, &m_ColorAttachment);
glDeleteTextures(1, &self->m_DepthAttachment); glDeleteTextures(1, &m_DepthAttachment);
} }
glGenFramebuffers(1, &self->m_RendererID); glGenFramebuffers(1, &m_RendererID);
glBindFramebuffer(GL_FRAMEBUFFER, self->m_RendererID); glBindFramebuffer(GL_FRAMEBUFFER, m_RendererID);
glGenTextures(1, &self->m_ColorAttachment); glGenTextures(1, &m_ColorAttachment);
glBindTexture(GL_TEXTURE_2D, self->m_ColorAttachment); glBindTexture(GL_TEXTURE_2D, m_ColorAttachment);
// TODO: Create Hazel texture object based on format here // TODO: Create Hazel texture object based on format here
if (self->m_Specification.Format == FramebufferFormat::RGBA16F) if (m_Specification.Format == FramebufferFormat::RGBA16F)
{ {
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, self->m_Specification.Width, self->m_Specification.Height, 0, GL_RGBA, GL_FLOAT, nullptr); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, m_Specification.Width, m_Specification.Height, 0, GL_RGBA, GL_FLOAT, nullptr);
} }
else if (self->m_Specification.Format == FramebufferFormat::RGBA8) else if (m_Specification.Format == FramebufferFormat::RGBA8)
{ {
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, self->m_Specification.Width, self->m_Specification.Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_Specification.Width, m_Specification.Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
} }
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, self->m_ColorAttachment, 0); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_ColorAttachment, 0);
glGenTextures(1, &self->m_DepthAttachment); glGenTextures(1, &m_DepthAttachment);
glBindTexture(GL_TEXTURE_2D, self->m_DepthAttachment); glBindTexture(GL_TEXTURE_2D, m_DepthAttachment);
glTexImage2D( glTexImage2D(
GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8, self->m_Specification.Width, self->m_Specification.Height, 0, GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8, m_Specification.Width, m_Specification.Height, 0,
GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, NULL GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, NULL
); );
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, self->m_DepthAttachment, 0); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, m_DepthAttachment, 0);
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
PM_CORE_ERROR("Framebuffer is incomplete!"); PM_CORE_ERROR("Framebuffer is incomplete!");
@ -91,9 +91,9 @@ namespace Prism
void OpenGLFrameBuffer::BindTexture(uint32_t slot) const void OpenGLFrameBuffer::BindTexture(uint32_t slot) const
{ {
PM_RENDER_S1(slot, { Renderer::Submit([this, slot](){
glActiveTexture(GL_TEXTURE0 + slot); glActiveTexture(GL_TEXTURE0 + slot);
glBindTexture(GL_TEXTURE_2D, self->m_ColorAttachment); glBindTexture(GL_TEXTURE_2D, m_ColorAttachment);
}); });
} }
} }

View File

@ -12,6 +12,7 @@ namespace Prism
{ {
static void OpenGLLogMessage(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar* message, const void* userParam) static void OpenGLLogMessage(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar* message, const void* userParam)
{ {
/*
if (severity != GL_DEBUG_SEVERITY_NOTIFICATION) if (severity != GL_DEBUG_SEVERITY_NOTIFICATION)
{ {
@ -21,7 +22,98 @@ namespace Prism
{ {
PM_CORE_TRACE("{0}", message); PM_CORE_TRACE("{0}", message);
} }
PM_CORE_ASSERT(0); */
if (severity == GL_DEBUG_SEVERITY_NOTIFICATION)
{
if (id == 131185 || id == 131218)
{
return;
}
PM_CORE_TRACE("[OpenGL Notification] {0}", message);
return;
}
std::string sourceStr;
switch (source)
{
case GL_DEBUG_SOURCE_API: sourceStr = "API";
break;
case GL_DEBUG_SOURCE_WINDOW_SYSTEM: sourceStr = "Window System";
break;
case GL_DEBUG_SOURCE_SHADER_COMPILER: sourceStr = "Shader Compiler";
break;
case GL_DEBUG_SOURCE_THIRD_PARTY: sourceStr = "Third Party";
break;
case GL_DEBUG_SOURCE_APPLICATION: sourceStr = "Application";
break;
case GL_DEBUG_SOURCE_OTHER: sourceStr = "Other";
break;
default: sourceStr = "Unknown";
break;
}
std::string typeStr;
switch (type)
{
case GL_DEBUG_TYPE_ERROR: typeStr = "Error";
break;
case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR: typeStr = "Deprecated Behavior";
break;
case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR: typeStr = "Undefined Behavior";
break;
case GL_DEBUG_TYPE_PORTABILITY: typeStr = "Portability";
break;
case GL_DEBUG_TYPE_PERFORMANCE: typeStr = "Performance";
break;
case GL_DEBUG_TYPE_MARKER: typeStr = "Marker";
break;
case GL_DEBUG_TYPE_PUSH_GROUP: typeStr = "Push Group";
break;
case GL_DEBUG_TYPE_POP_GROUP: typeStr = "Pop Group";
break;
case GL_DEBUG_TYPE_OTHER: typeStr = "Other";
break;
default: typeStr = "Unknown";
break;
}
switch (severity)
{
case GL_DEBUG_SEVERITY_HIGH:
PM_CORE_ERROR("[OpenGL HIGH] Source: {0}, Type: {1}, ID: {2}\nMessage: {3}",
sourceStr, typeStr, id, message);
if (type == GL_DEBUG_TYPE_ERROR)
{
PM_CORE_ASSERT(false, "OpenGL严重错误");
}
break;
case GL_DEBUG_SEVERITY_MEDIUM:
PM_CORE_WARN("[OpenGL MEDIUM] Source: {0}, Type: {1}, ID: {2}\nMessage: {3}", sourceStr, typeStr, id, message);
break;
case GL_DEBUG_SEVERITY_LOW:
PM_CORE_INFO("[OpenGL LOW] Source: {0}, Type: {1}, ID: {2}\nMessage: {3}", sourceStr, typeStr, id, message);
break;
}
if (type == GL_DEBUG_TYPE_PERFORMANCE)
{
PM_CORE_DEBUG("[Performance Tip] {0}", message);
}
if (type == GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR)
{
PM_CORE_ERROR("[Undefined behavior] This may cause rendering errors!");
GLint program;
glGetIntegerv(GL_CURRENT_PROGRAM, &program);
if (program != 0)
{
PM_CORE_DEBUG("Current Shader Program: {0}", program);
}
}
} }
void RendererAPI::Init() void RendererAPI::Init()

View File

@ -39,28 +39,29 @@ namespace Prism
m_ShaderSource = PreProcess(source); m_ShaderSource = PreProcess(source);
Parse(); Parse();
PM_RENDER_S({ Renderer::Submit([this](){
if (self->m_RendererID) auto &a = m_RendererID;
glDeleteProgram(self->m_RendererID); if (m_RendererID)
glDeleteProgram(m_RendererID);
self->CompileAndUploadShader(); CompileAndUploadShader();
self->ResolveUniforms(); ResolveUniforms();
self->ValidateUniforms(); ValidateUniforms();
if (self->m_Loaded) if (m_Loaded)
{ {
for (auto& callback : self->m_ShaderReloadedCallbacks) for (auto& callback : m_ShaderReloadedCallbacks)
callback(); callback();
} }
self->m_Loaded = true; m_Loaded = true;
}); });
} }
void OpenGLShader::Bind() void OpenGLShader::Bind()
{ {
PM_RENDER_S({ Renderer::Submit([this](){
glUseProgram(self->m_RendererID); glUseProgram(m_RendererID);
}); });
} }
@ -75,32 +76,32 @@ namespace Prism
{ {
const std::string& name = decl.Name; const std::string& name = decl.Name;
float value = *(float*)(uniformBuffer.GetBuffer() + decl.Offset); float value = *(float*)(uniformBuffer.GetBuffer() + decl.Offset);
PM_RENDER_S2(name, value, { Renderer::Submit([=]() {
self->UploadUniformFloat(name, value); UploadUniformFloat(name, value);
}); });
} }
case UniformType::Float3: case UniformType::Float3:
{ {
const std::string& name = decl.Name; const std::string& name = decl.Name;
glm::vec3& values = *(glm::vec3*)(uniformBuffer.GetBuffer() + decl.Offset); glm::vec3& values = *(glm::vec3*)(uniformBuffer.GetBuffer() + decl.Offset);
PM_RENDER_S2(name, values, { Renderer::Submit([=]() {
self->UploadUniformFloat3(name, values); UploadUniformFloat3(name, values);
}); });
} }
case UniformType::Float4: case UniformType::Float4:
{ {
const std::string& name = decl.Name; const std::string& name = decl.Name;
glm::vec4& values = *(glm::vec4*)(uniformBuffer.GetBuffer() + decl.Offset); glm::vec4& values = *(glm::vec4*)(uniformBuffer.GetBuffer() + decl.Offset);
PM_RENDER_S2(name, values, { Renderer::Submit([=]() {
self->UploadUniformFloat4(name, values); UploadUniformFloat4(name, values);
}); });
} }
case UniformType::Mat4: case UniformType::Mat4:
{ {
const std::string& name = decl.Name; const std::string& name = decl.Name;
glm::mat4& values = *(glm::mat4*)(uniformBuffer.GetBuffer() + decl.Offset); glm::mat4& values = *(glm::mat4*)(uniformBuffer.GetBuffer() + decl.Offset);
PM_RENDER_S2(name, values, { Renderer::Submit([=](){
self->UploadUniformMat4(name, values); UploadUniformMat4(name, values);
}); });
} }
@ -115,37 +116,46 @@ namespace Prism
void OpenGLShader::SetFloat(const std::string& name, float value) void OpenGLShader::SetFloat(const std::string& name, float value)
{ {
PM_RENDER_S2(name, value, { Renderer::Submit([=]() {
self->UploadUniformFloat(name, value); UploadUniformFloat(name, value);
}); });
} }
void OpenGLShader::SetMat4(const std::string& name, const glm::mat4& value) void OpenGLShader::SetMat4(const std::string& name, const glm::mat4& value)
{ {
PM_RENDER_S2(name, value, { Renderer::Submit([=]() {
self->UploadUniformMat4(name, value); UploadUniformMat4(name, value);
}); });
} }
void OpenGLShader::SetVSMaterialUniformBuffer(Buffer buffer) void OpenGLShader::SetVSMaterialUniformBuffer(Buffer buffer)
{ {
PM_RENDER_S1(buffer, { Renderer::Submit([this, buffer]() {
glUseProgram(self->m_RendererID); glUseProgram(m_RendererID);
self->ResolveAndSetUniforms(self->m_VSMaterialUniformBuffer, buffer); ResolveAndSetUniforms(m_VSMaterialUniformBuffer, buffer);
}); });
} }
void OpenGLShader::SetPSMaterialUniformBuffer(Buffer buffer) void OpenGLShader::SetPSMaterialUniformBuffer(Buffer buffer)
{ {
PM_RENDER_S1(buffer, { Renderer::Submit([this, buffer]() {
glUseProgram(self->m_RendererID); glUseProgram(m_RendererID);
self->ResolveAndSetUniforms(self->m_PSMaterialUniformBuffer, buffer); ResolveAndSetUniforms(m_PSMaterialUniformBuffer, buffer);
}); });
} }
void OpenGLShader::SetMat4FromRenderThread(const std::string& name, const glm::mat4& value) void OpenGLShader::SetMat4FromRenderThread(const std::string& name, const glm::mat4& value, const bool bind)
{ {
UploadUniformMat4(name, value); if (bind)
{
UploadUniformMat4(name, value);
}
else
{
const int location = glGetUniformLocation(m_RendererID, name.c_str());
if (location != -1)
UploadUniformMat4(location, value);
}
} }
const std::string& OpenGLShader::GetName() const const std::string& OpenGLShader::GetName() const
@ -656,7 +666,7 @@ namespace Prism
// Always detach shaders after a successful link. // Always detach shaders after a successful link.
for (auto id : shaderRendererIDs) for (const auto id : shaderRendererIDs)
glDetachShader(program, id); glDetachShader(program, id);
m_RendererID = program; m_RendererID = program;
@ -850,64 +860,64 @@ namespace Prism
} }
} }
void OpenGLShader::UploadUniformInt(uint32_t location, int32_t value) void OpenGLShader::UploadUniformInt(const uint32_t location, const int32_t value)
{ {
glUniform1i(location, value); glUniform1i(location, value);
} }
void OpenGLShader::UploadUniformIntArray(uint32_t location, int32_t* values, int32_t count) void OpenGLShader::UploadUniformIntArray(const uint32_t location, const int32_t* values, const int32_t count)
{ {
glUniform1iv(location, count, values); glUniform1iv(location, count, values);
} }
void OpenGLShader::UploadUniformFloat(uint32_t location, float value) void OpenGLShader::UploadUniformFloat(const uint32_t location, const float value)
{ {
glUniform1f(location, value); glUniform1f(location, value);
} }
void OpenGLShader::UploadUniformFloat2(uint32_t location, const glm::vec2& value) void OpenGLShader::UploadUniformFloat2(const uint32_t location, const glm::vec2& value)
{ {
glUniform2f(location, value.x, value.y); glUniform2f(location, value.x, value.y);
} }
void OpenGLShader::UploadUniformFloat3(uint32_t location, const glm::vec3& value) void OpenGLShader::UploadUniformFloat3(const uint32_t location, const glm::vec3& value)
{ {
glUniform3f(location, value.x, value.y, value.z); glUniform3f(location, value.x, value.y, value.z);
} }
void OpenGLShader::UploadUniformFloat4(uint32_t location, const glm::vec4& value) void OpenGLShader::UploadUniformFloat4(const uint32_t location, const glm::vec4& value)
{ {
glUniform4f(location, value.x, value.y, value.z, value.w); glUniform4f(location, value.x, value.y, value.z, value.w);
} }
void OpenGLShader::UploadUniformMat3(uint32_t location, const glm::mat3& values) void OpenGLShader::UploadUniformMat3(const uint32_t location, const glm::mat3& values)
{ {
glUniformMatrix3fv(location, 1, GL_FALSE, glm::value_ptr(values)); glUniformMatrix3fv(location, 1, GL_FALSE, glm::value_ptr(values));
} }
void OpenGLShader::UploadUniformMat4(uint32_t location, const glm::mat4& values) void OpenGLShader::UploadUniformMat4(const uint32_t location, const glm::mat4& values)
{ {
glUniformMatrix4fv(location, 1, GL_FALSE, glm::value_ptr(values)); glUniformMatrix4fv(location, 1, GL_FALSE, glm::value_ptr(values));
} }
void OpenGLShader::UploadUniformMat4Array(uint32_t location, const glm::mat4& values, uint32_t count) void OpenGLShader::UploadUniformMat4Array(const uint32_t location, const glm::mat4& values, const uint32_t count)
{ {
glUniformMatrix4fv(location, count, GL_FALSE, glm::value_ptr(values)); glUniformMatrix4fv(location, count, GL_FALSE, glm::value_ptr(values));
} }
void OpenGLShader::UploadUniformStruct(OpenGLShaderUniformDeclaration* uniform, byte* buffer, uint32_t offset) void OpenGLShader::UploadUniformStruct(const OpenGLShaderUniformDeclaration* uniform, byte* buffer, uint32_t offset)
{ {
const ShaderStruct& s = uniform->GetShaderUniformStruct(); const ShaderStruct& s = uniform->GetShaderUniformStruct();
const auto& fields = s.GetFields(); const auto& fields = s.GetFields();
for (size_t k = 0; k < fields.size(); k++) for (size_t k = 0; k < fields.size(); k++)
{ {
OpenGLShaderUniformDeclaration* field = (OpenGLShaderUniformDeclaration*)fields[k]; const OpenGLShaderUniformDeclaration* field = (OpenGLShaderUniformDeclaration*)fields[k];
ResolveAndSetUniformField(*field, buffer, offset); ResolveAndSetUniformField(*field, buffer, offset);
offset += field->m_Size; offset += field->m_Size;
} }
} }
void OpenGLShader::UploadUniformIntArray(const std::string& name, int32_t* values, int32_t count) void OpenGLShader::UploadUniformIntArray(const std::string& name, const int32_t* values, const int32_t count) const
{ {
int32_t location = GetUniformLocation(name); int32_t location = GetUniformLocation(name);
glUniform1iv(location, count, values); glUniform1iv(location, count, values);

View File

@ -31,7 +31,7 @@ namespace Prism
virtual void SetVSMaterialUniformBuffer(Buffer buffer) override; virtual void SetVSMaterialUniformBuffer(Buffer buffer) override;
virtual void SetPSMaterialUniformBuffer(Buffer buffer) override; virtual void SetPSMaterialUniformBuffer(Buffer buffer) override;
virtual void SetMat4FromRenderThread(const std::string& name, const glm::mat4& value) override; virtual void SetMat4FromRenderThread(const std::string& name, const glm::mat4& value, bool bind = true) override;
const std::string& GetName() const override; const std::string& GetName() const override;
@ -69,7 +69,7 @@ namespace Prism
void ResolveAndSetUniformField(const OpenGLShaderUniformDeclaration& field, byte* data, int32_t offset); void ResolveAndSetUniformField(const OpenGLShaderUniformDeclaration& field, byte* data, int32_t offset);
void UploadUniformInt(uint32_t location, int32_t value); void UploadUniformInt(uint32_t location, int32_t value);
void UploadUniformIntArray(uint32_t location, int32_t* values, int32_t count); void UploadUniformIntArray(uint32_t location, const int32_t* values, int32_t count);
void UploadUniformFloat(uint32_t location, float value); void UploadUniformFloat(uint32_t location, float value);
void UploadUniformFloat2(uint32_t location, const glm::vec2& value); void UploadUniformFloat2(uint32_t location, const glm::vec2& value);
void UploadUniformFloat3(uint32_t location, const glm::vec3& value); void UploadUniformFloat3(uint32_t location, const glm::vec3& value);
@ -78,8 +78,8 @@ namespace Prism
void UploadUniformMat4(uint32_t location, const glm::mat4& values); void UploadUniformMat4(uint32_t location, const glm::mat4& values);
void UploadUniformMat4Array(uint32_t location, const glm::mat4& values, uint32_t count); void UploadUniformMat4Array(uint32_t location, const glm::mat4& values, uint32_t count);
void UploadUniformStruct(OpenGLShaderUniformDeclaration* uniform, byte* buffer, uint32_t offset); void UploadUniformStruct(const OpenGLShaderUniformDeclaration* uniform, byte* buffer, uint32_t offset);
void UploadUniformIntArray(const std::string& name, int32_t* values, int32_t count); void UploadUniformIntArray(const std::string& name, const int32_t* values, int32_t count) const;
inline const ShaderUniformBufferList& GetVSRendererUniforms() const override { return m_VSRendererUniformBuffers; } inline const ShaderUniformBufferList& GetVSRendererUniforms() const override { return m_VSRendererUniformBuffers; }
inline const ShaderUniformBufferList& GetPSRendererUniforms() const override { return m_PSRendererUniformBuffers; } inline const ShaderUniformBufferList& GetPSRendererUniforms() const override { return m_PSRendererUniformBuffers; }

View File

@ -36,19 +36,18 @@ namespace Prism
OpenGLTexture2D::OpenGLTexture2D(TextureFormat format, unsigned int width, unsigned int height, TextureWrap wrap) OpenGLTexture2D::OpenGLTexture2D(TextureFormat format, unsigned int width, unsigned int height, TextureWrap wrap)
: m_Format(format), m_Width(width), m_Height(height), m_Wrap(wrap) : m_Format(format), m_Width(width), m_Height(height), m_Wrap(wrap)
{ {
auto self = this; Renderer::Submit([this]() {
PM_RENDER_1(self, { glGenTextures(1, &m_RendererID);
glGenTextures(1, &self->m_RendererID); glBindTexture(GL_TEXTURE_2D, m_RendererID);
glBindTexture(GL_TEXTURE_2D, self->m_RendererID);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
GLenum wrap = self->m_Wrap == TextureWrap::Clamp ? GL_CLAMP_TO_EDGE : GL_REPEAT; GLenum wrap = m_Wrap == TextureWrap::Clamp ? GL_CLAMP_TO_EDGE : GL_REPEAT;
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrap); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrap);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrap); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrap);
glTextureParameterf(self->m_RendererID, GL_TEXTURE_MAX_ANISOTROPY, RendererAPI::GetCapabilities().MaxAnisotropy); glTextureParameterf(m_RendererID, GL_TEXTURE_MAX_ANISOTROPY, RendererAPI::GetCapabilities().MaxAnisotropy);
glTexImage2D(GL_TEXTURE_2D, 0, PrismToOpenGLTextureFormat(self->m_Format), self->m_Width, self->m_Height, 0, PrismToOpenGLTextureFormat(self->m_Format), GL_UNSIGNED_BYTE, nullptr); glTexImage2D(GL_TEXTURE_2D, 0, Prism::PrismToOpenGLTextureFormat(m_Format), m_Width, m_Height, 0, Prism::PrismToOpenGLTextureFormat(m_Format), GL_UNSIGNED_BYTE, nullptr);
glGenerateMipmap(GL_TEXTURE_2D); glGenerateMipmap(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, 0); glBindTexture(GL_TEXTURE_2D, 0);
@ -68,50 +67,50 @@ namespace Prism
m_Height = height; m_Height = height;
m_Format = TextureFormat::RGBA; m_Format = TextureFormat::RGBA;
PM_RENDER_S1(srgb, { Renderer::Submit([this, srgb]() {
// TODO: Consolidate properly // TODO: Consolidate properly
if (srgb) if (srgb)
{ {
glCreateTextures(GL_TEXTURE_2D, 1, &self->m_RendererID); glCreateTextures(GL_TEXTURE_2D, 1, &m_RendererID);
int levels = CalculateMipMapCount(self->m_Width, self->m_Height); int levels = CalculateMipMapCount(m_Width, m_Height);
PM_CORE_INFO("Creating srgb texture width {0} mips", levels); PM_CORE_INFO("Creating srgb texture width {0} mips", levels);
glTextureStorage2D(self->m_RendererID, levels, GL_SRGB8, self->m_Width, self->m_Height); glTextureStorage2D(m_RendererID, levels, GL_SRGB8, m_Width, m_Height);
glTextureParameteri(self->m_RendererID, GL_TEXTURE_MIN_FILTER, levels > 1 ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR); glTextureParameteri(m_RendererID, GL_TEXTURE_MIN_FILTER, levels > 1 ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR);
glTextureParameteri(self->m_RendererID, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTextureParameteri(m_RendererID, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTextureSubImage2D(self->m_RendererID, 0, 0, 0, self->m_Width, self->m_Height, GL_RGB, GL_UNSIGNED_BYTE, self->m_ImageData.Data); glTextureSubImage2D(m_RendererID, 0, 0, 0, m_Width, m_Height, GL_RGB, GL_UNSIGNED_BYTE, m_ImageData.Data);
glGenerateTextureMipmap(self->m_RendererID); glGenerateTextureMipmap(m_RendererID);
} }
else else
{ {
glGenTextures(1, &self->m_RendererID); glGenTextures(1, &m_RendererID);
glBindTexture(GL_TEXTURE_2D, self->m_RendererID); glBindTexture(GL_TEXTURE_2D, m_RendererID);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexImage2D(GL_TEXTURE_2D, 0, PrismToOpenGLTextureFormat(self->m_Format), self->m_Width, self->m_Height, 0, srgb ? GL_SRGB8 : PrismToOpenGLTextureFormat(self->m_Format), GL_UNSIGNED_BYTE, self->m_ImageData.Data); glTexImage2D(GL_TEXTURE_2D, 0, PrismToOpenGLTextureFormat(m_Format), m_Width, m_Height, 0, srgb ? GL_SRGB8 : PrismToOpenGLTextureFormat(m_Format), GL_UNSIGNED_BYTE, m_ImageData.Data);
glGenerateMipmap(GL_TEXTURE_2D); glGenerateMipmap(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, 0); glBindTexture(GL_TEXTURE_2D, 0);
} }
stbi_image_free(self->m_ImageData.Data); stbi_image_free(m_ImageData.Data);
}); });
} }
OpenGLTexture2D::~OpenGLTexture2D() OpenGLTexture2D::~OpenGLTexture2D()
{ {
PM_RENDER_S({ Renderer::Submit([this](){
glDeleteTextures(1, &self->m_RendererID); glDeleteTextures(1, &m_RendererID);
}); });
} }
void OpenGLTexture2D::Bind(uint32_t slot) const void OpenGLTexture2D::Bind(uint32_t slot) const
{ {
PM_RENDER_S1(slot, { Renderer::Submit([this, slot]() {
glBindTextureUnit(slot, self->m_RendererID); glBindTextureUnit(slot, m_RendererID);
}); });
} }
@ -123,8 +122,8 @@ namespace Prism
void OpenGLTexture2D::Unlock() void OpenGLTexture2D::Unlock()
{ {
m_Locked = false; m_Locked = false;
PM_RENDER_S({ Renderer::Submit([this](){
glTextureSubImage2D(self->m_RendererID, 0, 0, 0, self->m_Width, self->m_Height, PrismToOpenGLTextureFormat(self->m_Format), GL_UNSIGNED_BYTE, self->m_ImageData.Data); glTextureSubImage2D(m_RendererID, 0, 0, 0, m_Width, m_Height, PrismToOpenGLTextureFormat(m_Format), GL_UNSIGNED_BYTE, m_ImageData.Data);
}); });
} }
@ -205,17 +204,17 @@ namespace Prism
} }
faceIndex++; faceIndex++;
} }
PM_RENDER_S3(faces, faceWidth, faceHeight, { Renderer::Submit([=]() {
glGenTextures(1, &self->m_RendererID); glGenTextures(1, &m_RendererID);
glBindTexture(GL_TEXTURE_CUBE_MAP, self->m_RendererID); glBindTexture(GL_TEXTURE_CUBE_MAP, m_RendererID);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTextureParameterf(self->m_RendererID, GL_TEXTURE_MAX_ANISOTROPY, RendererAPI::GetCapabilities().MaxAnisotropy); glTextureParameterf(m_RendererID, GL_TEXTURE_MAX_ANISOTROPY, RendererAPI::GetCapabilities().MaxAnisotropy);
auto format = PrismToOpenGLTextureFormat(self->m_Format); auto format = PrismToOpenGLTextureFormat(m_Format);
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, format, faceWidth, faceHeight, 0, format, GL_UNSIGNED_BYTE, faces[2]); glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, format, faceWidth, faceHeight, 0, format, GL_UNSIGNED_BYTE, faces[2]);
glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, format, faceWidth, faceHeight, 0, format, GL_UNSIGNED_BYTE, faces[0]); glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, format, faceWidth, faceHeight, 0, format, GL_UNSIGNED_BYTE, faces[0]);
@ -232,22 +231,21 @@ namespace Prism
for (size_t i = 0; i < faces.size(); i++) for (size_t i = 0; i < faces.size(); i++)
delete[] faces[i]; delete[] faces[i];
stbi_image_free(self->m_ImageData); stbi_image_free(m_ImageData);
}); });
} }
OpenGLTextureCube::~OpenGLTextureCube() OpenGLTextureCube::~OpenGLTextureCube()
{ {
auto self = this; Renderer::Submit([this]() {
PM_RENDER_1(self, { glDeleteTextures(1, &m_RendererID);
glDeleteTextures(1, &self->m_RendererID);
}); });
} }
void OpenGLTextureCube::Bind(uint32_t slot) const void OpenGLTextureCube::Bind(uint32_t slot) const
{ {
PM_RENDER_S1(slot, { Renderer::Submit([this, slot]() {
glBindTextureUnit(slot, self->m_RendererID); glBindTextureUnit(slot, m_RendererID);
}); });
} }

View File

@ -12,17 +12,17 @@ namespace Prism
{ {
switch (type) switch (type)
{ {
case Prism::ShaderDataType::Float: return GL_FLOAT; case ShaderDataType::Float: return GL_FLOAT;
case Prism::ShaderDataType::Float2: return GL_FLOAT; case ShaderDataType::Float2: return GL_FLOAT;
case Prism::ShaderDataType::Float3: return GL_FLOAT; case ShaderDataType::Float3: return GL_FLOAT;
case Prism::ShaderDataType::Float4: return GL_FLOAT; case ShaderDataType::Float4: return GL_FLOAT;
case Prism::ShaderDataType::Mat3: return GL_FLOAT; case ShaderDataType::Mat3: return GL_FLOAT;
case Prism::ShaderDataType::Mat4: return GL_FLOAT; case ShaderDataType::Mat4: return GL_FLOAT;
case Prism::ShaderDataType::Int: return GL_INT; case ShaderDataType::Int: return GL_INT;
case Prism::ShaderDataType::Int2: return GL_INT; case ShaderDataType::Int2: return GL_INT;
case Prism::ShaderDataType::Int3: return GL_INT; case ShaderDataType::Int3: return GL_INT;
case Prism::ShaderDataType::Int4: return GL_INT; case ShaderDataType::Int4: return GL_INT;
case Prism::ShaderDataType::Bool: return GL_BOOL; case ShaderDataType::Bool: return GL_BOOL;
} }
PM_CORE_ASSERT(false, "Unknown ShaderDataType!"); PM_CORE_ASSERT(false, "Unknown ShaderDataType!");
@ -31,28 +31,28 @@ namespace Prism
OpenGLVertexArray::OpenGLVertexArray() OpenGLVertexArray::OpenGLVertexArray()
{ {
PM_RENDER_S({ Renderer::Submit([this](){
glCreateVertexArrays(1, &self->m_RendererID); glCreateVertexArrays(1, &m_RendererID);
}); });
} }
OpenGLVertexArray::~OpenGLVertexArray() OpenGLVertexArray::~OpenGLVertexArray()
{ {
PM_RENDER_S({ Renderer::Submit([this](){
glDeleteVertexArrays(1, &self->m_RendererID); glDeleteVertexArrays(1, &m_RendererID);
}); });
} }
void OpenGLVertexArray::Bind() const void OpenGLVertexArray::Bind() const
{ {
PM_RENDER_S({ Renderer::Submit([this](){
glBindVertexArray(self->m_RendererID); glBindVertexArray(m_RendererID);
}); });
} }
void OpenGLVertexArray::Unbind() const void OpenGLVertexArray::Unbind() const
{ {
PM_RENDER_S({ Renderer::Submit([this](){
glBindVertexArray(0); glBindVertexArray(0);
}); });
} }
@ -64,15 +64,15 @@ namespace Prism
Bind(); Bind();
vertexBuffer->Bind(); vertexBuffer->Bind();
PM_RENDER_S1(vertexBuffer, { Renderer::Submit([this, vertexBuffer](){
const auto& layout = vertexBuffer->GetLayout(); const auto& layout = vertexBuffer->GetLayout();
for (const auto& element : layout) for (const auto& element : layout)
{ {
auto glBaseType = ShaderDataTypeToOpenGLBaseType(element.Type); auto glBaseType = ShaderDataTypeToOpenGLBaseType(element.Type);
glEnableVertexAttribArray(self->m_VertexBufferIndex); glEnableVertexAttribArray(m_VertexBufferIndex);
if (glBaseType == GL_INT) if (glBaseType == GL_INT)
{ {
glVertexAttribIPointer(self->m_VertexBufferIndex, glVertexAttribIPointer(m_VertexBufferIndex,
element.GetComponentCount(), element.GetComponentCount(),
glBaseType, glBaseType,
layout.GetStride(), layout.GetStride(),
@ -80,14 +80,14 @@ namespace Prism
} }
else else
{ {
glVertexAttribPointer(self->m_VertexBufferIndex, glVertexAttribPointer(m_VertexBufferIndex,
element.GetComponentCount(), element.GetComponentCount(),
glBaseType, glBaseType,
element.Normalized ? GL_TRUE : GL_FALSE, element.Normalized ? GL_TRUE : GL_FALSE,
layout.GetStride(), layout.GetStride(),
(const void*)(intptr_t)element.Offset); (const void*)(intptr_t)element.Offset);
} }
self->m_VertexBufferIndex++; m_VertexBufferIndex++;
} }
}); });
m_VertexBuffers.push_back(vertexBuffer); m_VertexBuffers.push_back(vertexBuffer);

View File

@ -73,7 +73,7 @@ namespace Prism
PM_CORE_WARN("Vertex has more than four bones/weights affecting it, extra data will be discarded (BoneID={0}, Weight={1})", BoneID, Weight); PM_CORE_WARN("Vertex has more than four bones/weights affecting it, extra data will be discarded (BoneID={0}, Weight={1})", BoneID, Weight);
} }
void VertexBoneData::AddBoneData(uint32_t BoneID, float Weight) void VertexBoneData::AddBoneData(const uint32_t BoneID, const float Weight)
{ {
for (size_t i = 0; i < 4; i++) for (size_t i = 0; i < 4; i++)
{ {
@ -177,11 +177,7 @@ namespace Prism
} }
} }
PM_CORE_TRACE("NODES:");
PM_CORE_TRACE("-----------------------------");
TraverseNodes(scene->mRootNode); TraverseNodes(scene->mRootNode);
PM_CORE_TRACE("-----------------------------");
// Bones // Bones
if (m_IsAnimated) if (m_IsAnimated)
@ -195,7 +191,7 @@ namespace Prism
{ {
aiBone* bone = mesh->mBones[i]; aiBone* bone = mesh->mBones[i];
std::string boneName(bone->mName.data); std::string boneName(bone->mName.data);
int boneIndex = 0; uint32_t boneIndex = 0;
if (m_BoneMapping.find(boneName) == m_BoneMapping.end()) if (m_BoneMapping.find(boneName) == m_BoneMapping.end())
{ {
@ -215,7 +211,7 @@ namespace Prism
for (size_t j = 0; j < bone->mNumWeights; j++) for (size_t j = 0; j < bone->mNumWeights; j++)
{ {
int VertexID = submesh.BaseVertex + bone->mWeights[j].mVertexId; uint32_t VertexID = submesh.BaseVertex + bone->mWeights[j].mVertexId;
float Weight = bone->mWeights[j].mWeight; float Weight = bone->mWeights[j].mWeight;
m_AnimatedVertices[VertexID].AddBoneData(boneIndex, Weight); m_AnimatedVertices[VertexID].AddBoneData(boneIndex, Weight);
} }
@ -267,11 +263,9 @@ namespace Prism
m_Scene = scene; m_Scene = scene;
} }
Mesh::~Mesh() Mesh::~Mesh() = default;
{
}
void Mesh::Render(TimeStep deltaTime, const Ref<MaterialInstance>& materialInstance) void Mesh::Render(const TimeStep deltaTime, const Ref<MaterialInstance>& materialInstance)
{ {
Render(deltaTime, glm::mat4(1.0f), materialInstance); Render(deltaTime, glm::mat4(1.0f), materialInstance);
} }
@ -305,15 +299,15 @@ namespace Prism
bool materialOverride = !!materialInstance; bool materialOverride = !!materialInstance;
// TODO: replace with render API calls // TODO: replace with render API calls
PM_RENDER_S2(transform, materialOverride,{ Renderer::Submit([=](){
for (Submesh& submesh : self->m_Submeshes) for (const Submesh& submesh : m_Submeshes)
{ {
if (self->m_IsAnimated) if (m_IsAnimated)
{ {
for (size_t i = 0; i < self->m_BoneTransforms.size(); i++) for (size_t i = 0; i < m_BoneTransforms.size(); i++)
{ {
std::string uniformName = std::string("u_BoneTransforms[") + std::to_string(i) + std::string("]"); std::string uniformName = std::string("u_BoneTransforms[") + std::to_string(i) + std::string("]");
self->m_MeshShader->SetMat4FromRenderThread(uniformName, self->m_BoneTransforms[i]); m_MeshShader->SetMat4FromRenderThread(uniformName, m_BoneTransforms[i]);
} }
} }
@ -321,65 +315,6 @@ namespace Prism
// self->m_MeshShader->SetMat4FromRenderThread("u_ModelMatrix", transform * submesh.Transform); // self->m_MeshShader->SetMat4FromRenderThread("u_ModelMatrix", transform * submesh.Transform);
glDrawElementsBaseVertex(GL_TRIANGLES, submesh.IndexCount, GL_UNSIGNED_INT, (void*)(sizeof(uint32_t) * submesh.BaseIndex), submesh.BaseVertex); glDrawElementsBaseVertex(GL_TRIANGLES, submesh.IndexCount, GL_UNSIGNED_INT, (void*)(sizeof(uint32_t) * submesh.BaseIndex), submesh.BaseVertex);
} }
/*
for (const Submesh& submesh : self->m_Submeshes)
{
if (self->m_IsAnimated)
{
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(AnimatedVertex), (const void*)offsetof(AnimatedVertex, Position));
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(AnimatedVertex), (const void*)offsetof(AnimatedVertex, Normal));
glEnableVertexAttribArray(2);
glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, sizeof(AnimatedVertex), (const void*)offsetof(AnimatedVertex, Tangent));
glEnableVertexAttribArray(3);
glVertexAttribPointer(3, 3, GL_FLOAT, GL_FALSE, sizeof(AnimatedVertex), (const void*)offsetof(AnimatedVertex, Binormal));
glEnableVertexAttribArray(4);
glVertexAttribPointer(4, 2, GL_FLOAT, GL_FALSE, sizeof(AnimatedVertex), (const void*)offsetof(AnimatedVertex, Texcoord));
glEnableVertexAttribArray(5);
glVertexAttribIPointer(5, 4, GL_INT, sizeof(AnimatedVertex), (const void*)offsetof(AnimatedVertex, IDs));
glEnableVertexAttribArray(6);
glVertexAttribPointer(6, 4, GL_FLOAT, GL_FALSE, sizeof(AnimatedVertex), (const void*)offsetof(AnimatedVertex, Weights));
#1#
if (self->m_Scene->mAnimations)
{
for (size_t i = 0; i < self->m_BoneTransforms.size(); i++)
{
std::string uniformName = std::string("u_BoneTransforms[") + std::to_string(i) + std::string("]");
self->m_MeshShader->SetMat4FromRenderThread(uniformName, self->m_BoneTransforms[i]);
}
}
glDrawElementsBaseVertex(GL_TRIANGLES, submesh.IndexCount, GL_UNSIGNED_INT, (void*)(sizeof(uint32_t) * submesh.BaseIndex), submesh.BaseVertex);
}else
{
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (const void*)offsetof(Vertex, Position));
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (const void*)offsetof(Vertex, Normal));
glEnableVertexAttribArray(2);
glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (const void*)offsetof(Vertex, Tangent));
glEnableVertexAttribArray(3);
glVertexAttribPointer(3, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (const void*)offsetof(Vertex, Binormal));
glEnableVertexAttribArray(4);
glVertexAttribPointer(4, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (const void*)offsetof(Vertex, Texcoord));
}
if (!materialOverride)
self->m_MeshShader->SetMat4FromRenderThread("u_ModelMatrix", transform * submesh.Transform);
glDrawElementsBaseVertex(GL_TRIANGLES, submesh.IndexCount, GL_UNSIGNED_INT, (void*)(sizeof(uint32_t) * submesh.BaseIndex), submesh.BaseVertex);
}
*/
}); });
} }
@ -448,32 +383,32 @@ namespace Prism
m_BoneTransforms[i] = m_BoneInfo[i].FinalTransformation; m_BoneTransforms[i] = m_BoneInfo[i].FinalTransformation;
} }
void Mesh::ReadNodeHierarchy(float AnimationTime, const aiNode* pNode, const glm::mat4& ParentTransform) void Mesh::ReadNodeHierarchy(const float AnimationTime, const aiNode* pNode, const glm::mat4& ParentTransform)
{ {
std::string name(pNode->mName.data); const std::string name(pNode->mName.data);
const aiAnimation* animation = m_Scene->mAnimations[0]; const aiAnimation* animation = m_Scene->mAnimations[0];
glm::mat4 nodeTransform(aiMatrix4x4ToGlm(pNode->mTransformation)); glm::mat4 nodeTransform(aiMatrix4x4ToGlm(pNode->mTransformation));
const aiNodeAnim* nodeAnim = FindNodeAnim(animation, name); const aiNodeAnim* nodeAnim = FindNodeAnim(animation, name);
if (nodeAnim) if (nodeAnim)
{ {
glm::vec3 translation = InterpolateTranslation(AnimationTime, nodeAnim); const glm::vec3 translation = InterpolateTranslation(AnimationTime, nodeAnim);
glm::mat4 translationMatrix = glm::translate(glm::mat4(1.0f), glm::vec3(translation.x, translation.y, translation.z)); const glm::mat4 translationMatrix = glm::translate(glm::mat4(1.0f), glm::vec3(translation.x, translation.y, translation.z));
glm::quat rotation = InterpolateRotation(AnimationTime, nodeAnim); const glm::quat rotation = InterpolateRotation(AnimationTime, nodeAnim);
glm::mat4 rotationMatrix = glm::toMat4(rotation); const glm::mat4 rotationMatrix = glm::toMat4(rotation);
glm::vec3 scale = InterpolateScale(AnimationTime, nodeAnim); const glm::vec3 scale = InterpolateScale(AnimationTime, nodeAnim);
glm::mat4 scaleMatrix = glm::scale(glm::mat4(1.0f), glm::vec3(scale.x, scale.y, scale.z)); const glm::mat4 scaleMatrix = glm::scale(glm::mat4(1.0f), glm::vec3(scale.x, scale.y, scale.z));
nodeTransform = translationMatrix * rotationMatrix * scaleMatrix; nodeTransform = translationMatrix * rotationMatrix * scaleMatrix;
} }
glm::mat4 transform = ParentTransform * nodeTransform; const glm::mat4 transform = ParentTransform * nodeTransform;
if (m_BoneMapping.find(name) != m_BoneMapping.end()) if (m_BoneMapping.find(name) != m_BoneMapping.end())
{ {
uint32_t BoneIndex = m_BoneMapping[name]; const uint32_t BoneIndex = m_BoneMapping[name];
m_BoneInfo[BoneIndex].FinalTransformation = m_InverseTransform * transform * m_BoneInfo[BoneIndex].BoneOffset; m_BoneInfo[BoneIndex].FinalTransformation = m_InverseTransform * transform * m_BoneInfo[BoneIndex].BoneOffset;
} }
@ -481,12 +416,14 @@ namespace Prism
ReadNodeHierarchy(AnimationTime, pNode->mChildren[i], transform); ReadNodeHierarchy(AnimationTime, pNode->mChildren[i], transform);
} }
void Mesh::TraverseNodes(aiNode* node, int level) void Mesh::TraverseNodes(const aiNode* node)
{ {
/*
std::string levelText; std::string levelText;
for (int i = 0; i < level; i++) for (int i = 0; i < level; i++)
levelText += "-"; levelText += "-";
PM_CORE_TRACE("{0}Node name: {1}", levelText, std::string(node->mName.data)); PM_CORE_TRACE("{0}Node name: {1}", levelText, std::string(node->mName.data));
*/
for (uint32_t i = 0; i < node->mNumMeshes; i++) for (uint32_t i = 0; i < node->mNumMeshes; i++)
{ {
uint32_t mesh = node->mMeshes[i]; uint32_t mesh = node->mMeshes[i];
@ -495,8 +432,7 @@ namespace Prism
for (uint32_t i = 0; i < node->mNumChildren; i++) for (uint32_t i = 0; i < node->mNumChildren; i++)
{ {
aiNode* child = node->mChildren[i]; TraverseNodes(node->mChildren[i]);
TraverseNodes(child, level + 1);
} }
} }
@ -511,7 +447,7 @@ namespace Prism
return nullptr; return nullptr;
} }
uint32_t Mesh::FindPosition(float AnimationTime, const aiNodeAnim* pNodeAnim) uint32_t Mesh::FindPosition(const float AnimationTime, const aiNodeAnim* pNodeAnim)
{ {
for (uint32_t i = 0; i < pNodeAnim->mNumPositionKeys - 1; i++) for (uint32_t i = 0; i < pNodeAnim->mNumPositionKeys - 1; i++)
{ {
@ -522,7 +458,7 @@ namespace Prism
return 0; return 0;
} }
uint32_t Mesh::FindRotation(float AnimationTime, const aiNodeAnim* pNodeAnim) uint32_t Mesh::FindRotation(const float AnimationTime, const aiNodeAnim* pNodeAnim)
{ {
PM_CORE_ASSERT(pNodeAnim->mNumRotationKeys > 0); PM_CORE_ASSERT(pNodeAnim->mNumRotationKeys > 0);
@ -535,7 +471,7 @@ namespace Prism
return 0; return 0;
} }
uint32_t Mesh::FindScaling(float AnimationTime, const aiNodeAnim* pNodeAnim) uint32_t Mesh::FindScaling(const float AnimationTime, const aiNodeAnim* pNodeAnim)
{ {
PM_CORE_ASSERT(pNodeAnim->mNumScalingKeys > 0); PM_CORE_ASSERT(pNodeAnim->mNumScalingKeys > 0);
@ -548,7 +484,7 @@ namespace Prism
return 0; return 0;
} }
glm::vec3 Mesh::InterpolateTranslation(float animationTime, const aiNodeAnim* nodeAnim) glm::vec3 Mesh::InterpolateTranslation(const float animationTime, const aiNodeAnim* nodeAnim)
{ {
if (nodeAnim->mNumPositionKeys == 1) if (nodeAnim->mNumPositionKeys == 1)
{ {
@ -572,7 +508,7 @@ namespace Prism
return { aiVec.x, aiVec.y, aiVec.z }; return { aiVec.x, aiVec.y, aiVec.z };
} }
glm::quat Mesh::InterpolateRotation(float animationTime, const aiNodeAnim* nodeAnim) glm::quat Mesh::InterpolateRotation(const float animationTime, const aiNodeAnim* nodeAnim)
{ {
if (nodeAnim->mNumRotationKeys == 1) if (nodeAnim->mNumRotationKeys == 1)
{ {
@ -597,7 +533,7 @@ namespace Prism
return glm::quat(q.w, q.x, q.y, q.z); return glm::quat(q.w, q.x, q.y, q.z);
} }
glm::vec3 Mesh::InterpolateScale(float animationTime, const aiNodeAnim* nodeAnim) glm::vec3 Mesh::InterpolateScale(const float animationTime, const aiNodeAnim* nodeAnim)
{ {
if (nodeAnim->mNumScalingKeys == 1) if (nodeAnim->mNumScalingKeys == 1)
{ {

View File

@ -60,6 +60,8 @@ namespace Prism
{ {
glm::mat4 BoneOffset; glm::mat4 BoneOffset;
glm::mat4 FinalTransformation; glm::mat4 FinalTransformation;
BoneInfo() : BoneOffset(glm::mat4(1.0f)), FinalTransformation(glm::mat4(1.0f)) {}
}; };
struct VertexBoneData struct VertexBoneData
@ -106,7 +108,7 @@ namespace Prism
private: private:
void BoneTransform(float time); void BoneTransform(float time);
void ReadNodeHierarchy(float AnimationTime, const aiNode* pNode, const glm::mat4& ParentTransform); void ReadNodeHierarchy(float AnimationTime, const aiNode* pNode, const glm::mat4& ParentTransform);
void TraverseNodes(aiNode* node, int level = 0); void TraverseNodes(const aiNode* node);
const aiNodeAnim* FindNodeAnim(const aiAnimation* animation, const std::string& nodeName); const aiNodeAnim* FindNodeAnim(const aiAnimation* animation, const std::string& nodeName);
uint32_t FindPosition(float AnimationTime, const aiNodeAnim* pNodeAnim); uint32_t FindPosition(float AnimationTime, const aiNodeAnim* pNodeAnim);
@ -153,6 +155,8 @@ namespace Prism
bool m_AnimationPlaying = true; bool m_AnimationPlaying = true;
std::string m_FilePath; std::string m_FilePath;
private:
friend class Renderer;
}; };
} }

View File

@ -13,7 +13,7 @@ namespace Prism
{ {
RenderCommandQueue::RenderCommandQueue() RenderCommandQueue::RenderCommandQueue()
{ {
m_CommandBuffer = new unsigned char[10 * 1024 * 1024]; // 10mb buffer m_CommandBuffer = new uint8_t[10 * 1024 * 1024]; // 10mb buffer
m_CommandBufferPtr = m_CommandBuffer; m_CommandBufferPtr = m_CommandBuffer;
memset(m_CommandBuffer, 0, 10 * 1024 * 1024); memset(m_CommandBuffer, 0, 10 * 1024 * 1024);
} }
@ -23,13 +23,13 @@ namespace Prism
delete[] m_CommandBuffer; delete[] m_CommandBuffer;
} }
void* RenderCommandQueue::Allocate(RenderCommandFn func, unsigned int size) void* RenderCommandQueue::Allocate(RenderCommandFn func, uint32_t size)
{ {
*(RenderCommandFn*)m_CommandBufferPtr = func; *(RenderCommandFn*)m_CommandBufferPtr = func;
m_CommandBufferPtr += sizeof(RenderCommandFn); m_CommandBufferPtr += sizeof(RenderCommandFn);
*(int*)m_CommandBufferPtr = size; *(uint32_t*)m_CommandBufferPtr = size;
m_CommandBufferPtr += sizeof(unsigned int); m_CommandBufferPtr += sizeof(uint32_t);
void* memory = m_CommandBufferPtr; void* memory = m_CommandBufferPtr;
m_CommandBufferPtr += size; m_CommandBufferPtr += size;
@ -44,13 +44,13 @@ namespace Prism
byte* buffer = m_CommandBuffer; byte* buffer = m_CommandBuffer;
for (unsigned i = 0 ; i < m_CommandCount ; i++) for (uint32_t i = 0 ; i < m_CommandCount ; i++)
{ {
RenderCommandFn function = *(RenderCommandFn*)(buffer); RenderCommandFn function = *(RenderCommandFn*)(buffer);
buffer += sizeof(RenderCommandFn); buffer += sizeof(RenderCommandFn);
unsigned int size = *(unsigned int*)buffer; uint32_t size = *(uint32_t*)buffer;
buffer += sizeof(unsigned int); buffer += sizeof(uint32_t);
function(buffer); function(buffer);
buffer += size; buffer += size;
} }

View File

@ -16,13 +16,13 @@ namespace Prism
RenderCommandQueue(); RenderCommandQueue();
~RenderCommandQueue(); ~RenderCommandQueue();
void* Allocate(RenderCommandFn func, unsigned int size); void* Allocate(RenderCommandFn func, uint32_t size);
void Execute(); void Execute();
private: private:
unsigned char* m_CommandBuffer = nullptr; uint8_t* m_CommandBuffer = nullptr;
unsigned char* m_CommandBufferPtr = nullptr; uint8_t* m_CommandBufferPtr = nullptr;
unsigned int m_CommandCount = 0; uint32_t m_CommandCount = 0;
}; };
} }

View File

@ -5,6 +5,7 @@
#include "Renderer.h" #include "Renderer.h"
#include "RendererAPI.h" #include "RendererAPI.h"
#include "glad/glad.h"
namespace Prism namespace Prism
@ -14,11 +15,15 @@ namespace Prism
void Renderer::Clear() void Renderer::Clear()
{ {
Submit([]()
{
RendererAPI::Clear(0.0f, 0.0f, 0.0f, 1.0f);
});
} }
void Renderer::Clear(float r, float g, float b, float a) void Renderer::Clear(float r, float g, float b, float a)
{ {
PM_RENDER_4(r, g, b, a, { Submit([=](){
RendererAPI::Clear(r, g, b, a); RendererAPI::Clear(r, g, b, a);
}); });
} }
@ -29,7 +34,7 @@ namespace Prism
void Renderer::DrawIndexed(uint32_t count, bool depthTest) void Renderer::DrawIndexed(uint32_t count, bool depthTest)
{ {
PM_RENDER_2(count, depthTest, { Submit([=]() {
RendererAPI::DrawIndexed(count, depthTest); RendererAPI::DrawIndexed(count, depthTest);
}); });
} }
@ -42,7 +47,7 @@ namespace Prism
void Renderer::Init() void Renderer::Init()
{ {
s_Instance->m_ShaderLibrary = std::make_unique<ShaderLibrary>(); s_Instance->m_ShaderLibrary = std::make_unique<ShaderLibrary>();
PM_RENDER({ RendererAPI::Init(); }); Submit([](){ RendererAPI::Init(); });
GetShaderLibrary()->Load("assets/shaders/simplepbr_Static.glsl"); GetShaderLibrary()->Load("assets/shaders/simplepbr_Static.glsl");
GetShaderLibrary()->Load("assets/shaders/simplepbr_Anim.glsl"); GetShaderLibrary()->Load("assets/shaders/simplepbr_Anim.glsl");
@ -63,9 +68,10 @@ namespace Prism
s_Instance->IEndRenderPass(); s_Instance->IEndRenderPass();
} }
void Renderer::SubmitMesh(const Ref<Mesh>& mesh) void Renderer::SubmitMesh(const Ref<Mesh>& mesh, const glm::mat4& transform,
const Ref<MaterialInstance>& overrideMaterial)
{ {
s_Instance->SubmitMeshI(mesh); s_Instance->SubmitMeshI(mesh, transform, overrideMaterial);
} }
void Renderer::IBeginRenderPass(const Ref<RenderPass>& renderPass) void Renderer::IBeginRenderPass(const Ref<RenderPass>& renderPass)
@ -74,6 +80,11 @@ namespace Prism
m_ActiveRenderPass = renderPass; m_ActiveRenderPass = renderPass;
renderPass->GetSpecification().TargetFramebuffer->Bind(); renderPass->GetSpecification().TargetFramebuffer->Bind();
const glm::vec4& clearColor = renderPass->GetSpecification().TargetFramebuffer->GetSpecification().ClearColor;
Submit([=]() {
RendererAPI::Clear(clearColor.r, clearColor.g, clearColor.b, clearColor.a);
});
} }
void Renderer::IEndRenderPass() void Renderer::IEndRenderPass()
@ -83,7 +94,35 @@ namespace Prism
m_ActiveRenderPass = nullptr; m_ActiveRenderPass = nullptr;
} }
void Renderer::SubmitMeshI(const Ref<Mesh>& mesh) void Renderer::SubmitMeshI(const Ref<Mesh>& mesh, const glm::mat4& transform,
const Ref<MaterialInstance>& overrideMaterial)
{ {
if (overrideMaterial)
{
overrideMaterial->Bind();
}else
{
// bind mesh material here
}
mesh->m_VertexArray->Bind();
// TODO: temp test , use RenderAPI replace this
Submit([=]()
{
for (const Submesh& submesh : mesh->m_Submeshes)
{
if (mesh->m_IsAnimated)
{
for (size_t i = 0; i < mesh->m_BoneTransforms.size(); i++)
{
std::string uniformName = std::string("u_BoneTransforms[") + std::to_string(i) + std::string("]");
mesh->m_MeshShader->SetMat4FromRenderThread(uniformName, mesh->m_BoneTransforms[i]);
}
}
glDrawElementsBaseVertex(GL_TRIANGLES, submesh.IndexCount, GL_UNSIGNED_INT, (void*)(sizeof(uint32_t) * submesh.BaseIndex), submesh.BaseVertex);
}
});
} }
} }

View File

@ -30,10 +30,27 @@ namespace Prism
static const Scope<ShaderLibrary>& GetShaderLibrary() { return Get().m_ShaderLibrary; } static const Scope<ShaderLibrary>& GetShaderLibrary() { return Get().m_ShaderLibrary; }
template<typename FuncT>
static void Submit(FuncT&& func)
{
auto renderCmd = [](void* ptr) {
auto pFunc = static_cast<FuncT*>(ptr);
(*pFunc)();
// NOTE: Instead of destroying we could try and enforce all items to be trivally destructible
// however some items like uniforms which contain std::strings still exist for now
// static_assert(std::is_trivially_destructible_v<FuncT>, "FuncT must be trivially destructible");
pFunc->~FuncT();
};
auto storageBuffer = s_Instance->m_CommandQueue.Allocate(renderCmd, sizeof(func));
new (storageBuffer) FuncT(std::forward<FuncT>(func));
}
/*
static void* Submit(const RenderCommandFn func, const unsigned int size) static void* Submit(const RenderCommandFn func, const unsigned int size)
{ {
return s_Instance->m_CommandQueue.Allocate(func, size); return s_Instance->m_CommandQueue.Allocate(func, size);
} }
*/
void WaitAndRender(); void WaitAndRender();
inline static Renderer& Get() { return *s_Instance; } inline static Renderer& Get() { return *s_Instance; }
@ -43,13 +60,13 @@ namespace Prism
static void BeginRenderPass(const Ref<RenderPass>& renderPass); static void BeginRenderPass(const Ref<RenderPass>& renderPass);
static void EndRenderPass(); static void EndRenderPass();
static void SubmitMesh(const Ref<Mesh>& mesh); static void SubmitMesh(const Ref<Mesh>& mesh, const glm::mat4& transform, const Ref<MaterialInstance>& overrideMaterial = nullptr);
private: private:
void IBeginRenderPass(const Ref<RenderPass>& renderPass); void IBeginRenderPass(const Ref<RenderPass>& renderPass);
void IEndRenderPass(); void IEndRenderPass();
void SubmitMeshI(const Ref<Mesh>& mesh); void SubmitMeshI(const Ref<Mesh>& mesh, const glm::mat4& transform, const Ref<MaterialInstance>& overrideMaterial = nullptr);
private: private:
@ -60,6 +77,7 @@ namespace Prism
RenderCommandQueue m_CommandQueue; RenderCommandQueue m_CommandQueue;
}; };
#if 0
#define PM_RENDER_PASTE2(a, b) a ## b #define PM_RENDER_PASTE2(a, b) a ## b
#define PM_RENDER_PASTE(a, b) PM_RENDER_PASTE2(a, b) #define PM_RENDER_PASTE(a, b) PM_RENDER_PASTE2(a, b)
#define PM_RENDER_UNIQUE(x) PM_RENDER_PASTE(x, __LINE__) #define PM_RENDER_UNIQUE(x) PM_RENDER_PASTE(x, __LINE__)
@ -183,6 +201,7 @@ PM_RENDER_3(self, arg0, arg1, code)
#define PM_RENDER_S3(arg0, arg1, arg2, code) auto self = this;\ #define PM_RENDER_S3(arg0, arg1, arg2, code) auto self = this;\
PM_RENDER_4(self, arg0, arg1, arg2, code) PM_RENDER_4(self, arg0, arg1, arg2, code)
#endif
} }
#endif //RENDERER_H #endif //RENDERER_H

View File

@ -108,7 +108,7 @@ namespace Prism
virtual void SetFloat(const std::string& name, float value) = 0; virtual void SetFloat(const std::string& name, float value) = 0;
virtual void SetMat4(const std::string& name, const glm::mat4& value) = 0; virtual void SetMat4(const std::string& name, const glm::mat4& value) = 0;
virtual void SetMat4FromRenderThread(const std::string& name, const glm::mat4& value) = 0; virtual void SetMat4FromRenderThread(const std::string& name, const glm::mat4& value, bool bind = true) = 0;
virtual const std::string& GetName() const = 0; virtual const std::string& GetName() const = 0;