Compare commits

...

7 Commits

  1. 32
      CMakeLists.txt
  2. 4
      assets/glsl/batch-cubemap.vert
  3. 3
      assets/glsl/lightsource.frag
  4. 4
      assets/glsl/post-process.frag
  5. 1
      example/CMakeLists.txt
  6. 1
      src/CMakeLists.txt
  7. 2
      src/inferno/asset/shader.h
  8. 2
      src/inferno/component/cubemap-component.cpp
  9. 2
      src/inferno/component/model-component.cpp
  10. 127
      src/inferno/component/serialize.cpp
  11. 58
      src/inferno/component/serialize.h
  12. 29
      src/inferno/component/spritecomponent.cpp
  13. 7
      src/inferno/component/spritecomponent.h
  14. 51
      src/inferno/component/transformcomponent.cpp
  15. 30
      src/inferno/component/transformcomponent.h
  16. 65
      src/inferno/render/buffer.cpp
  17. 17
      src/inferno/render/buffer.h
  18. 81
      src/inferno/render/renderer.cpp
  19. 44
      src/inferno/render/renderer.h
  20. 195
      src/inferno/render/shader-storage-buffer.cpp
  21. 63
      src/inferno/render/shader-storage-buffer.h
  22. 24
      src/inferno/render/shader-structs.h
  23. 1
      src/inferno/render/uniformbuffer.cpp
  24. 28
      src/inferno/render/uniformbuffer.h
  25. 24
      src/inferno/system/rendersystem.cpp
  26. 2
      src/inferno/system/textareasystem.h
  27. 1
      vendor/CMakeLists.txt
  28. 2
      vendor/ruc

32
CMakeLists.txt

@ -11,6 +11,7 @@ endif()
# Options
option(BUILD_SHARED_LIBS "Build shared libraries" OFF)
option(INFERNO_BUILD_EXAMPLES "Build the Inferno example programs" ${INFERNO_STANDALONE})
option(INFERNO_BUILD_WARNINGS "Build with warnings enabled" ${INFERNO_STANDALONE})
# ------------------------------------------
@ -25,10 +26,15 @@ set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
# Compiler flags used for all build types
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Wpedantic")
# -Wall = All warnings about contructions that are easily avoidable
# -Wextra = Extra warning flags not covered by -Wall
# -Wpedantic = Warnings for compiler extensions not part of the standard
set(COMPILE_FLAGS_DEPS -w)
if(INFERNO_BUILD_WARNINGS)
set(COMPILE_FLAGS_PROJECT -Wall -Wextra -Wpedantic)
# -Wall = All warnings about contructions that are easily avoidable
# -Wextra = Extra warning flags not covered by -Wall
# -Wpedantic = Warnings for compiler extensions not part of the standard
else()
set(COMPILE_FLAGS_PROJECT ${COMPILE_FLAGS_DEPS})
endif()
# Set default build type if not specified
set(DEFAULT_BUILD_TYPE Release)
@ -42,14 +48,20 @@ endif()
# Set build type specific compiler flags
message("--- ${CMAKE_BUILD_TYPE} ---")
if(${CMAKE_BUILD_TYPE} STREQUAL Debug)
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Og -g -pg")
# -Og = Optimizations that do not interfere with debugging
# -g = Produce debugging information in OS's native format
# -pg = Generate profile information for analysis with gprof
# Optimizations that do not interfere with debugging
string(APPEND CMAKE_CXX_FLAGS_DEBUG " -Og")
# Produce debugging information in OS's native format
string(APPEND CMAKE_CXX_FLAGS_DEBUG " -g")
# Generate profile information for analysis with gprof
# $ gprof <PROJECT> gmon.out > profile-data.txt
string(APPEND CMAKE_CXX_FLAGS_DEBUG " -pg")
# Enable ASan (Address Sanitizer) and UBSan (Undefined Behavior Sanitizer)
string(APPEND CMAKE_CXX_FLAGS_DEBUG " -fsanitize=address,undefined")
# Do not omit frame pointer, which helps with debugging.
string(APPEND CMAKE_CXX_FLAGS_DEBUG " -fno-omit-frame-pointer")
elseif(${CMAKE_BUILD_TYPE} STREQUAL Release)
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O3")
# -O3 = Optimizations that increase compilation time and performance
# Optimizations that increase compilation time and performance
string(APPEND CMAKE_CXX_FLAGS_RELEASE " -O3")
endif()
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)

4
assets/glsl/batch-cubemap.vert

@ -8,7 +8,7 @@ out vec4 v_color;
out vec3 v_textureCoordinates;
out flat uint v_textureIndex;
uniform mat4 u_projectionView2;
uniform mat4 u_projectionView;
void main()
{
@ -16,5 +16,5 @@ void main()
v_textureCoordinates = a_position;
v_textureIndex = a_textureIndex;
// Vclip = Camera projection * Camera view * Model transform * Vlocal
gl_Position = u_projectionView2 * vec4(a_position, 1.0f);
gl_Position = u_projectionView * vec4(a_position, 1.0f);
}

3
assets/glsl/lightsource.frag

@ -10,5 +10,8 @@ uniform samplerCube u_textures[32];
void main()
{
// Prevent u_textures variable from getting optimized away
if (texture(u_textures[0], vec3(0.0f)).x > 99999.0f) { discard; }
color = v_color;
}

4
assets/glsl/post-process.frag

@ -25,8 +25,8 @@ struct DirectionalLight {
vec3 specular;
};
const int MAX_DIRECTIONAL_LIGHTS = 32;
layout(std140, binding = 1) uniform DirectionalLights {
const int MAX_DIRECTIONAL_LIGHTS = 4;
layout(std430, binding = 0) buffer DirectionalLights {
DirectionalLight u_directionalLight[MAX_DIRECTIONAL_LIGHTS];
};

1
example/CMakeLists.txt

@ -15,6 +15,7 @@ add_executable(${GAME} ${GAME_SOURCES})
target_include_directories(${GAME} PRIVATE
"src")
target_link_libraries(${GAME} ${ENGINE})
target_compile_options(${GAME} PRIVATE ${COMPILE_FLAGS_PROJECT})
target_precompile_headers(${GAME} REUSE_FROM ${ENGINE})

1
src/CMakeLists.txt

@ -10,6 +10,7 @@ target_include_directories(${ENGINE} PUBLIC
"../vendor/sol2/include"
"../vendor/stb")
target_link_libraries(${ENGINE} ${ENGINE}-dependencies)
target_compile_options(${ENGINE} PRIVATE ${COMPILE_FLAGS_PROJECT})
# ------------------------------------------

2
src/inferno/asset/shader.h

@ -4,6 +4,8 @@
* SPDX-License-Identifier: MIT
*/
#pragma once
#include <cstdint> // int32_t, uint32_t
#include <string_view>
#include <unordered_map>

2
src/inferno/component/cubemap-component.cpp

@ -8,7 +8,7 @@
#include "inferno/asset/texture.h"
#include "inferno/component/cubemap-component.h"
#include "inferno/component/spritecomponent.h" // TODO: Move glm::x toJson/fromJson to separate file
#include "inferno/component/serialize.h" // not detected as used by clang-tidy
namespace Inferno {

2
src/inferno/component/model-component.cpp

@ -8,7 +8,7 @@
#include "inferno/asset/asset-manager.h"
#include "inferno/asset/model.h"
#include "inferno/asset/texture.h"
#include "inferno/component/spritecomponent.h" // TODO: Move glm::x toJson/fromJson to separate file
#include "inferno/component/serialize.h" // not detected as used by clang-tidy
namespace Inferno {

127
src/inferno/component/serialize.cpp

@ -0,0 +1,127 @@
/*
* Copyright (C) 2024 Riyyi
*
* SPDX-License-Identifier: MIT
*/
#include "glm/ext/matrix_float2x2.hpp"
#include "glm/ext/matrix_float3x3.hpp"
#include "glm/ext/matrix_float4x4.hpp"
#include "glm/ext/vector_float2.hpp"
#include "glm/ext/vector_float3.hpp"
#include "glm/ext/vector_float4.hpp"
#include "ruc/json/json.h"
#include "inferno/component/serialize.h"
namespace glm {
void toJson(ruc::Json& json, const vec2& value)
{
json = ruc::Json {
{ value.x, value.y },
};
}
void fromJson(const ruc::Json& json, vec2& value)
{
VERIFY(json.type() == ruc::Json::Type::Array);
auto& values = json.asArray();
VERIFY(values.size() == 2, "glm::vec2 expected 2 values, got: {}", values.size());
value.x = values.at(0).get<float>();
value.y = values.at(1).get<float>();
}
// -----------------------------------------
void toJson(ruc::Json& json, const vec3& value)
{
json = ruc::Json {
{ value.x, value.y, value.z },
};
}
void fromJson(const ruc::Json& json, vec3& value)
{
VERIFY(json.type() == ruc::Json::Type::Array);
auto& values = json.asArray();
VERIFY(values.size() == 3, "glm::vec3 expected 3 values, got: {}", values.size());
value.x = values.at(0).get<float>();
value.y = values.at(1).get<float>();
value.z = values.at(2).get<float>();
}
// -----------------------------------------
void toJson(ruc::Json& json, const vec4& value)
{
json = ruc::Json {
{ value.r, value.g, value.b, value.a },
};
}
void fromJson(const ruc::Json& json, vec4& value)
{
VERIFY(json.type() == ruc::Json::Type::Array);
auto& values = json.asArray();
VERIFY(values.size() == 4, "glm::vec4 expected 4 values, got: {}", values.size());
value.r = values.at(0).get<float>();
value.g = values.at(1).get<float>();
value.b = values.at(2).get<float>();
value.a = values.at(3).get<float>();
}
} // namespace glm
// -----------------------------------------
void ruc::format::Formatter<glm::vec2>::format(Builder& builder, glm::vec2 value) const
{
return Formatter<std::vector<float>>::format(builder, { value.x, value.y });
}
void ruc::format::Formatter<glm::vec3>::format(Builder& builder, glm::vec3 value) const
{
return Formatter<std::vector<float>>::format(builder, { value.x, value.y, value.z });
}
void ruc::format::Formatter<glm::vec4>::format(Builder& builder, glm::vec4 value) const
{
return Formatter<std::vector<float>>::format(builder, { value.x, value.y, value.z, value.w });
}
void ruc::format::Formatter<glm::mat2>::format(Builder& builder, glm::mat2 value) const
{
builder.putString("mat2 ");
Formatter<glm::vec2>::format(builder, value[0]);
builder.putString("\n ");
return Formatter<glm::vec2>::format(builder, value[1]);
}
void ruc::format::Formatter<glm::mat3>::format(Builder& builder, glm::mat3 value) const
{
builder.putString("mat3 ");
Formatter<glm::vec3>::format(builder, value[0]);
builder.putString("\n ");
Formatter<glm::vec3>::format(builder, value[1]);
builder.putString("\n ");
return Formatter<glm::vec3>::format(builder, value[2]);
}
void ruc::format::Formatter<glm::mat4>::format(Builder& builder, glm::mat4 value) const
{
builder.putString("mat4 ");
Formatter<glm::vec4>::format(builder, value[0]);
builder.putString("\n ");
Formatter<glm::vec4>::format(builder, value[1]);
builder.putString("\n ");
Formatter<glm::vec4>::format(builder, value[2]);
builder.putString("\n ");
return Formatter<glm::vec4>::format(builder, value[3]);
}

58
src/inferno/component/serialize.h

@ -0,0 +1,58 @@
/*
* Copyright (C) 2024 Riyyi
*
* SPDX-License-Identifier: MIT
*/
#pragma once
#include "glm/ext/matrix_float2x2.hpp"
#include "glm/ext/matrix_float3x3.hpp"
#include "glm/ext/matrix_float4x4.hpp"
#include "glm/ext/vector_float2.hpp"
#include "glm/ext/vector_float3.hpp"
#include "glm/ext/vector_float4.hpp"
#include "ruc/json/json.h"
namespace glm {
void toJson(ruc::Json& json, const vec2& value);
void fromJson(const ruc::Json& json, vec2& value);
void toJson(ruc::Json& json, const vec3& value);
void fromJson(const ruc::Json& json, vec3& value);
void toJson(ruc::Json& json, const vec4& value);
void fromJson(const ruc::Json& json, vec4& value);
} // namespace glm
template<>
struct ruc::format::Formatter<glm::vec2> : Formatter<std::vector<float>> {
void format(Builder& builder, glm::vec2 value) const;
};
template<>
struct ruc::format::Formatter<glm::vec3> : Formatter<std::vector<float>> {
void format(Builder& builder, glm::vec3 value) const;
};
template<>
struct ruc::format::Formatter<glm::vec4> : Formatter<std::vector<float>> {
void format(Builder& builder, glm::vec4 value) const;
};
template<>
struct ruc::format::Formatter<glm::mat2> : Formatter<glm::vec2> {
void format(Builder& builder, glm::mat2 value) const;
};
template<>
struct ruc::format::Formatter<glm::mat3> : Formatter<glm::vec3> {
void format(Builder& builder, glm::mat3 value) const;
};
template<>
struct ruc::format::Formatter<glm::mat4> : Formatter<glm::vec4> {
void format(Builder& builder, glm::mat4 value) const;
};

29
src/inferno/component/spritecomponent.cpp

@ -4,9 +4,12 @@
* SPDX-License-Identifier: MIT
*/
#include "inferno/component/spritecomponent.h"
#include "ruc/json/json.h"
#include "inferno/asset/asset-manager.h"
#include "inferno/asset/texture.h"
#include "inferno/component/serialize.h" // not detected as used by clang-tidy
#include "inferno/component/spritecomponent.h"
namespace Inferno {
@ -23,27 +26,3 @@ void fromJson(const ruc::Json& json, SpriteComponent& value)
}
} // namespace Inferno
namespace glm {
void toJson(ruc::Json& json, const vec4& value)
{
json = ruc::Json {
{ value.r, value.g, value.b, value.a },
};
}
void fromJson(const ruc::Json& json, vec4& value)
{
VERIFY(json.type() == ruc::Json::Type::Array);
auto& values = json.asArray();
VERIFY(values.size() == 4, "glm::vec4 expects 4 values, not {}", values.size());
value.r = values.at(0).get<float>();
value.g = values.at(1).get<float>();
value.b = values.at(2).get<float>();
value.a = values.at(3).get<float>();
}
} // namespace glm

7
src/inferno/component/spritecomponent.h

@ -23,10 +23,3 @@ struct SpriteComponent {
void fromJson(const ruc::Json& json, SpriteComponent& value);
} // namespace Inferno
namespace glm {
void toJson(ruc::Json& json, const vec4& value);
void fromJson(const ruc::Json& json, vec4& value);
} // namespace glm

51
src/inferno/component/transformcomponent.cpp

@ -7,6 +7,7 @@
#include "ruc/format/format.h"
#include "ruc/json/json.h"
#include "inferno/component/serialize.h"
#include "inferno/component/transformcomponent.h"
namespace Inferno {
@ -28,56 +29,6 @@ void fromJson(const ruc::Json& json, TransformComponent& value)
} // namespace Inferno
namespace glm {
void toJson(ruc::Json& json, const vec3& value)
{
json = ruc::Json {
{ value.x, value.y, value.z },
};
}
void fromJson(const ruc::Json& json, vec3& value)
{
VERIFY(json.type() == ruc::Json::Type::Array);
auto& values = json.asArray();
VERIFY(values.size() == 3, "glm::vec3 expects 3 values, not {}", values.size());
value.x = values.at(0).get<float>();
value.y = values.at(1).get<float>();
value.z = values.at(2).get<float>();
}
} // namespace glm
void ruc::format::Formatter<glm::vec2>::format(Builder& builder, glm::vec2 value) const
{
return Formatter<std::vector<float>>::format(builder, { value.x, value.y });
}
void ruc::format::Formatter<glm::vec3>::format(Builder& builder, glm::vec3 value) const
{
return Formatter<std::vector<float>>::format(builder, { value.x, value.y, value.z });
}
void ruc::format::Formatter<glm::vec4>::format(Builder& builder, glm::vec4 value) const
{
return Formatter<std::vector<float>>::format(builder, { value.x, value.y, value.z, value.w });
}
void ruc::format::Formatter<glm::mat4>::format(Builder& builder, glm::mat4 value) const
{
builder.putString("mat4 ");
Formatter<glm::vec4>::format(builder, value[0]);
builder.putString("\n ");
Formatter<glm::vec4>::format(builder, value[1]);
builder.putString("\n ");
Formatter<glm::vec4>::format(builder, value[2]);
builder.putString("\n ");
return Formatter<glm::vec4>::format(builder, value[3]);
}
void ruc::format::Formatter<Inferno::TransformComponent>::format(Builder& builder, Inferno::TransformComponent value) const
{
builder.putString("transform ");

30
src/inferno/component/transformcomponent.h

@ -6,9 +6,6 @@
#pragma once
#include <cstdint> // uint32_t
#include <optional>
#include "entt/entity/entity.hpp" // entt::null
#include "entt/entity/fwd.hpp" // entt::entity
#include "glm/ext/matrix_float4x4.hpp" // glm::mat4
@ -31,33 +28,6 @@ void fromJson(const ruc::Json& json, TransformComponent& value);
} // namespace Inferno
namespace glm {
void toJson(ruc::Json& json, const vec3& value);
void fromJson(const ruc::Json& json, vec3& value);
} // namespace glm
template<>
struct ruc::format::Formatter<glm::vec2> : Formatter<std::vector<float>> {
void format(Builder& builder, glm::vec2 value) const;
};
template<>
struct ruc::format::Formatter<glm::vec3> : Formatter<std::vector<float>> {
void format(Builder& builder, glm::vec3 value) const;
};
template<>
struct ruc::format::Formatter<glm::vec4> : Formatter<std::vector<float>> {
void format(Builder& builder, glm::vec4 value) const;
};
template<>
struct ruc::format::Formatter<glm::mat4> : Formatter<glm::vec4> {
void format(Builder& builder, glm::mat4 value) const;
};
template<>
struct ruc::format::Formatter<Inferno::TransformComponent> : Formatter<glm::vec3> {
void format(Builder& builder, Inferno::TransformComponent value) const;

65
src/inferno/render/buffer.cpp

@ -42,7 +42,7 @@ uint32_t BufferElement::getTypeGL() const
return BufferElement::getTypeGL(m_type);
}
uint32_t BufferElement::getTypeSize(const BufferElementType type)
uint32_t BufferElement::getTypeSize(BufferElementType type)
{
switch (type) {
case BufferElementType::None:
@ -86,7 +86,7 @@ uint32_t BufferElement::getTypeSize(const BufferElementType type)
return 0;
}
uint32_t BufferElement::getTypeCount(const BufferElementType type)
uint32_t BufferElement::getTypeCount(BufferElementType type)
{
switch (type) {
case BufferElementType::None:
@ -133,7 +133,7 @@ uint32_t BufferElement::getTypeCount(const BufferElementType type)
return 0;
}
uint32_t BufferElement::getTypeGL(const BufferElementType type)
uint32_t BufferElement::getTypeGL(BufferElementType type)
{
switch (type) {
case BufferElementType::None:
@ -177,6 +177,58 @@ uint32_t BufferElement::getTypeGL(const BufferElementType type)
return 0;
}
uint32_t BufferElement::getGLTypeSize(uint32_t type)
{
switch (type) {
case GL_BOOL:
case GL_INT:
case GL_UNSIGNED_INT:
case GL_FLOAT:
return 4;
case GL_BOOL_VEC2:
case GL_INT_VEC2:
case GL_UNSIGNED_INT_VEC2:
case GL_FLOAT_VEC2:
return 4 * 2;
case GL_BOOL_VEC3:
case GL_INT_VEC3:
case GL_UNSIGNED_INT_VEC3:
case GL_FLOAT_VEC3:
return 4 * 3;
case GL_BOOL_VEC4:
case GL_INT_VEC4:
case GL_UNSIGNED_INT_VEC4:
case GL_FLOAT_VEC4:
return 4 * 4;
case GL_FLOAT_MAT2:
return 4 * 2 * 2;
case GL_FLOAT_MAT3:
return 4 * 3 * 3;
case GL_FLOAT_MAT4:
return 4 * 4 * 4;
case GL_DOUBLE:
return 8;
case GL_DOUBLE_VEC2:
return 8 * 2;
case GL_DOUBLE_VEC3:
return 8 * 3;
case GL_DOUBLE_VEC4:
return 8 * 4;
case GL_DOUBLE_MAT2:
return 8 * 2 * 2;
case GL_DOUBLE_MAT3:
return 8 * 3 * 3;
case GL_DOUBLE_MAT4:
return 8 * 4 * 4;
default:
VERIFY_NOT_REACHED();
};
return 0;
}
// -----------------------------------------
BufferLayout::BufferLayout(const std::initializer_list<BufferElement>& elements)
@ -372,10 +424,11 @@ void VertexArray::addVertexBuffer(std::shared_ptr<VertexBuffer> vertexBuffer)
index++;
}
m_vertexBuffers.push_back(std::move(vertexBuffer));
unbind();
vertexBuffer->unbind();
m_vertexBuffers.push_back(std::move(vertexBuffer));
}
void VertexArray::setIndexBuffer(std::shared_ptr<IndexBuffer> indexBuffer)
@ -383,10 +436,10 @@ void VertexArray::setIndexBuffer(std::shared_ptr<IndexBuffer> indexBuffer)
bind();
indexBuffer->bind();
m_indexBuffer = std::move(indexBuffer);
unbind();
indexBuffer->unbind();
m_indexBuffer = std::move(indexBuffer);
}
} // namespace Inferno

17
src/inferno/render/buffer.h

@ -16,7 +16,7 @@ namespace Inferno {
// clang-format off
// https://www.khronos.org/opengl/wiki/Data_Type_(GLSL)
enum class BufferElementType {
enum class BufferElementType : uint8_t {
None = 0,
Bool, Bool2, Bool3, Bool4, // bvec
Int, Int2, Int3, Int4, // ivec
@ -39,9 +39,10 @@ public:
uint32_t getTypeSize() const;
uint32_t getTypeCount() const;
uint32_t getTypeGL() const;
static uint32_t getTypeSize(const BufferElementType type);
static uint32_t getTypeCount(const BufferElementType type);
static uint32_t getTypeGL(const BufferElementType type);
static uint32_t getTypeSize(BufferElementType type);
static uint32_t getTypeCount(BufferElementType type);
static uint32_t getTypeGL(BufferElementType type);
static uint32_t getGLTypeSize(uint32_t type);
BufferElementType type() const { return m_type; }
std::string name() const { return m_name; }
@ -49,11 +50,11 @@ public:
uint32_t offset() const { return m_offset; }
bool normalized() const { return m_normalized; }
void setType(const BufferElementType& type) { m_type = type; }
void setType(BufferElementType type) { m_type = type; }
void setName(const std::string& name) { m_name = name; }
void setSize(const uint32_t& size) { m_size = size; }
void setOffset(const uint32_t& offset) { m_offset = offset; }
void setNormalized(const bool& normalized) { m_normalized = normalized; }
void setSize(uint32_t size) { m_size = size; }
void setOffset(uint32_t offset) { m_offset = offset; }
void setNormalized(bool normalized) { m_normalized = normalized; }
private:
BufferElementType m_type;

81
src/inferno/render/renderer.cpp

@ -34,9 +34,6 @@ void Renderer<T>::endScene()
// -----------------------------------------
template<typename T>
uint32_t Renderer<T>::m_maxSupportedTextureSlots = 0;
template<typename T>
void Renderer<T>::initialize()
{
@ -68,7 +65,6 @@ void Renderer<T>::initialize()
template<typename T>
void Renderer<T>::destroy()
{
delete[] m_vertexBufferBase;
}
template<typename T>
@ -164,7 +160,7 @@ void Renderer<T>::flush()
uploadElementBuffer();
// Upload vertex data to GPU
m_vertexArray->at(0)->uploadData(m_vertexBufferBase, m_vertexIndex * sizeof(T));
m_vertexArray->at(0)->uploadData(m_vertexBufferBase.get(), m_vertexIndex * sizeof(T));
bind();
@ -183,7 +179,7 @@ void Renderer<T>::startBatch()
{
m_vertexIndex = 0;
m_elementIndex = 0;
m_vertexBufferPtr = m_vertexBufferBase;
m_vertexBufferPtr = m_vertexBufferBase.get();
m_textureSlotIndex = 1;
}
@ -202,6 +198,10 @@ Renderer2D::Renderer2D(s)
Renderer2D::initialize();
}
Renderer2D::~Renderer2D()
{
}
void Renderer2D::initialize()
{
Renderer::initialize();
@ -210,8 +210,8 @@ void Renderer2D::initialize()
// CPU
// Create array for storing quads vertices
m_vertexBufferBase = new QuadVertex[maxVertices];
m_vertexBufferPtr = m_vertexBufferBase;
m_vertexBufferBase = std::make_unique<QuadVertex[]>(maxVertices);
m_vertexBufferPtr = m_vertexBufferBase.get();
// Set default quad vertex positions
m_vertexPositions[0] = { -1.0f, -1.0f, 0.0f, 1.0f };
@ -283,7 +283,7 @@ void Renderer2D::drawQuad(const TransformComponent& transform, glm::mat4 color,
void Renderer2D::loadShader()
{
m_shader = AssetManager::the().load<Shader>("assets/glsl/post-process");
m_shader = AssetManager::the().load<Shader>("assets/glsl/batch-2d");
}
// -----------------------------------------
@ -293,6 +293,10 @@ RendererCubemap::RendererCubemap(s)
RendererCubemap::initialize();
}
RendererCubemap::~RendererCubemap()
{
}
void RendererCubemap::initialize()
{
Renderer::initialize();
@ -301,8 +305,8 @@ void RendererCubemap::initialize()
// CPU
// Create array for storing quads vertices
m_vertexBufferBase = new CubemapVertex[maxVertices];
m_vertexBufferPtr = m_vertexBufferBase;
m_vertexBufferBase = std::make_unique<CubemapVertex[]>(maxVertices);
m_vertexBufferPtr = m_vertexBufferBase.get();
// Set default cubemap vertex positions
@ -367,10 +371,10 @@ void RendererCubemap::beginScene(glm::mat4 cameraProjection, glm::mat4 cameraVie
// x x x 0
// x x x 0
// 0 0 0 1
// cameraView = glm::mat4(glm::mat3(cameraView));
cameraView = glm::mat4(glm::mat3(cameraView));
m_shader->bind();
m_shader->setFloat("u_projectionView2", cameraProjection * cameraView);
m_shader->setFloat("u_projectionView", cameraProjection * cameraView);
m_shader->unbind();
}
@ -416,8 +420,8 @@ RendererFont::RendererFont(s)
// CPU
// Create array for storing quads vertices
m_vertexBufferBase = new SymbolVertex[maxVertices];
m_vertexBufferPtr = m_vertexBufferBase;
m_vertexBufferBase = std::make_unique<SymbolVertex[]>(maxVertices);
m_vertexBufferPtr = m_vertexBufferBase.get();
// ---------------------------------
// GPU
@ -443,6 +447,10 @@ RendererFont::RendererFont(s)
ruc::info("RendererFont initialized");
}
RendererFont::~RendererFont()
{
}
void RendererFont::drawSymbol(std::array<SymbolVertex, vertexPerQuad>& symbolQuad, std::shared_ptr<Texture> texture)
{
// Create a new batch if the quad limit has been reached
@ -488,8 +496,8 @@ Renderer3D::Renderer3D(s)
// CPU
// Create array for storing quads vertices
m_vertexBufferBase = new Vertex[maxVertices];
m_vertexBufferPtr = m_vertexBufferBase;
m_vertexBufferBase = std::make_unique<Vertex[]>(maxVertices);
m_vertexBufferPtr = m_vertexBufferBase.get();
// ---------------------------------
// GPU
@ -511,6 +519,10 @@ Renderer3D::Renderer3D(s)
ruc::info("Renderer3D initialized");
}
Renderer3D::~Renderer3D()
{
}
void Renderer3D::drawModel(std::span<const Vertex> vertices, std::span<const uint32_t> elements, const TransformComponent& transform, glm::vec4 color, std::shared_ptr<Texture> texture)
{
// ruc::error("drawModel");
@ -553,20 +565,20 @@ void Renderer3D::createElementBuffer()
// CPU
// Create array for storing quads vertices
m_elementBufferBase = new uint32_t[maxElements];
m_elementBufferPtr = m_elementBufferBase;
m_elementBufferBase = std::make_unique<uint32_t[]>(maxElements);
m_elementBufferPtr = m_elementBufferBase.get();
// ---------------------------------
// GPU
// Create index buffer
auto indexBuffer = std::make_shared<IndexBuffer>(m_elementBufferBase, sizeof(uint32_t) * maxElements);
auto indexBuffer = std::make_shared<IndexBuffer>(m_elementBufferBase.get(), sizeof(uint32_t) * maxElements);
m_vertexArray->setIndexBuffer(indexBuffer);
}
void Renderer3D::uploadElementBuffer()
{
m_vertexArray->indexBuffer()->uploadData(m_elementBufferBase, m_elementIndex * sizeof(uint32_t));
m_vertexArray->indexBuffer()->uploadData(m_elementBufferBase.get(), m_elementIndex * sizeof(uint32_t));
}
void Renderer3D::loadShader()
@ -577,11 +589,22 @@ void Renderer3D::loadShader()
void Renderer3D::startBatch()
{
Renderer<Vertex>::startBatch();
m_elementBufferPtr = m_elementBufferBase;
m_elementBufferPtr = m_elementBufferBase.get();
}
// -----------------------------------------
RendererPostProcess::RendererPostProcess(s)
{
Renderer2D::initialize();
ruc::info("RendererPostProcess initialized");
}
RendererPostProcess::~RendererPostProcess()
{
}
void RendererPostProcess::drawQuad(const TransformComponent& transform, std::shared_ptr<Texture> albedo, std::shared_ptr<Texture> position, std::shared_ptr<Texture> normal)
{
nextBatch();
@ -611,12 +634,24 @@ void RendererPostProcess::drawQuad(const TransformComponent& transform, std::sha
void RendererPostProcess::loadShader()
{
ruc::error("POSTPROCESSING!");
m_shader = AssetManager::the().load<Shader>("assets/glsl/post-process");
}
// -----------------------------------------
RendererLightCube::RendererLightCube(s)
{
RendererCubemap::initialize();
m_enableDepthBuffer = true;
ruc::info("RendererLightCube initialized");
}
RendererLightCube::~RendererLightCube()
{
}
void RendererLightCube::loadShader()
{
m_shader = AssetManager::the().load<Shader>("assets/glsl/lightsource");

44
src/inferno/render/renderer.h

@ -16,9 +16,10 @@
#include "glm/ext/vector_float4.hpp" // glm::vec4
#include "ruc/singleton.h"
#include "inferno/asset/shader.h"
namespace Inferno {
class Shader;
class Texture;
class TransformComponent;
class VertexArray;
@ -79,6 +80,8 @@ public:
void setEnableDepthBuffer(bool state) { m_enableDepthBuffer = state; }
uint32_t shaderID() const { return m_shader->id(); }
protected:
Renderer() {}
virtual ~Renderer() { destroy(); };
@ -102,11 +105,11 @@ protected:
// CPU quad vertices
uint32_t m_vertexIndex { 0 };
uint32_t m_elementIndex { 0 };
T* m_vertexBufferBase { nullptr };
std::unique_ptr<T[]> m_vertexBufferBase { nullptr };
T* m_vertexBufferPtr { nullptr };
// Texture units
static uint32_t m_maxSupportedTextureSlots;
static inline uint32_t m_maxSupportedTextureSlots { 0 };
uint32_t m_textureSlotIndex { 1 };
std::array<std::shared_ptr<Texture>, maxTextureSlots> m_textureSlots;
@ -130,7 +133,7 @@ class Renderer2D
, public ruc::Singleton<Renderer2D> {
public:
Renderer2D(s);
virtual ~Renderer2D() = default;
virtual ~Renderer2D();
using Singleton<Renderer2D>::destroy;
@ -140,7 +143,7 @@ public:
void drawQuad(const TransformComponent& transform, glm::mat4 color, std::shared_ptr<Texture> texture);
protected:
Renderer2D() { Renderer2D::initialize(); } // Needed for derived classes
Renderer2D() {} // Needed for derived classes
void initialize();
@ -160,7 +163,7 @@ public:
public:
RendererCubemap(s);
virtual ~RendererCubemap() = default;
virtual ~RendererCubemap();
using Singleton<RendererCubemap>::destroy;
@ -170,7 +173,7 @@ public:
void drawCubemap(const TransformComponent& transform, glm::mat4 color, std::shared_ptr<Texture> texture);
protected:
RendererCubemap() { RendererCubemap::initialize(); } // Needed for derived classes
RendererCubemap() {} // Needed for derived classes
void initialize();
@ -188,7 +191,7 @@ class RendererFont final
, public ruc::Singleton<RendererFont> {
public:
RendererFont(s);
virtual ~RendererFont() = default;
virtual ~RendererFont();
using Singleton<RendererFont>::destroy;
@ -205,7 +208,7 @@ class Renderer3D final
, public ruc::Singleton<Renderer3D> {
public:
Renderer3D(s);
virtual ~Renderer3D() = default;
virtual ~Renderer3D();
using Singleton<Renderer3D>::destroy;
@ -219,7 +222,7 @@ private:
private:
// CPU element vertices
uint32_t* m_elementBufferBase { nullptr };
std::unique_ptr<uint32_t[]> m_elementBufferBase { nullptr };
uint32_t* m_elementBufferPtr { nullptr };
};
@ -229,15 +232,13 @@ class RendererPostProcess final
: public Renderer2D
, public ruc::Singleton<RendererPostProcess> {
public:
RendererPostProcess(ruc::Singleton<RendererPostProcess>::s)
: Renderer2D()
{
}
virtual ~RendererPostProcess() = default;
using Singleton<RendererPostProcess>::s;
using Singleton<RendererPostProcess>::the;
using Singleton<RendererPostProcess>::destroy;
RendererPostProcess(s);
virtual ~RendererPostProcess();
void drawQuad(const TransformComponent& transform, std::shared_ptr<Texture> albedo, std::shared_ptr<Texture> position, std::shared_ptr<Texture> normal);
private:
@ -250,16 +251,13 @@ class RendererLightCube final
: public RendererCubemap
, public ruc::Singleton<RendererLightCube> {
public:
RendererLightCube(ruc::Singleton<RendererLightCube>::s)
: RendererCubemap()
{
m_enableDepthBuffer = true;
}
virtual ~RendererLightCube() = default;
using Singleton<RendererLightCube>::s;
using Singleton<RendererLightCube>::the;
using Singleton<RendererLightCube>::destroy;
RendererLightCube(s);
virtual ~RendererLightCube();
void beginScene(glm::mat4, glm::mat4) override {}
private:

195
src/inferno/render/shader-storage-buffer.cpp

@ -0,0 +1,195 @@
/*
* Copyright (C) 2024 Riyyi
*
* SPDX-License-Identifier: MIT
*/
#include <cstdint> // int32_t, uint8_t, uintt32_t
#include "glad/glad.h"
#include "glm/ext/matrix_float2x2.hpp" // glm::mat2
#include "glm/ext/matrix_float3x3.hpp" // glm::mat3
#include "glm/ext/vector_float4.hpp" // glm::vec4
#include "inferno/render/buffer.h"
#include "inferno/render/shader-storage-buffer.h"
namespace Inferno {
ShaderStorageBuffer::ShaderStorageBuffer(s)
{
// Get maximum uniformbuffer bindings the GPU supports
int32_t maxBindingPoints = 0;
glGetIntegerv(GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS, &maxBindingPoints);
m_maxBindingPoints = static_cast<uint8_t>(maxBindingPoints);
}
ShaderStorageBuffer::~ShaderStorageBuffer()
{
}
// -----------------------------------------
// https://stackoverflow.com/questions/56512216#answer-56513136
void ShaderStorageBuffer::setLayout(std::string_view blockName, uint8_t bindingPoint, uint32_t shaderID)
{
VERIFY(bindingPoint < m_maxBindingPoints,
"shader storage buffer exceeded binding points: {}/{}", bindingPoint, m_maxBindingPoints);
if (!exists(blockName)) {
m_blocks[blockName.data()] = {};
}
BufferBlock& block = m_blocks[blockName.data()];
block.bindingPoint = bindingPoint;
block.memberOffsets.clear();
glBindBuffer(GL_SHADER_STORAGE_BUFFER, block.id);
// Get the shader block index
uint32_t resourceIndex = glGetProgramResourceIndex(shaderID, GL_SHADER_STORAGE_BLOCK, blockName.data());
VERIFY(resourceIndex != GL_INVALID_INDEX, "block doesnt exist in shader: {}::{}", blockName, shaderID);
// Get the amount of member variables
uint32_t prop = GL_NUM_ACTIVE_VARIABLES;
int32_t memberCount;
glGetProgramResourceiv(shaderID, GL_SHADER_STORAGE_BLOCK, resourceIndex, 1, &prop, 1, nullptr, &memberCount);
// Get the indices of the members
prop = GL_ACTIVE_VARIABLES;
std::vector<int32_t> members(memberCount);
glGetProgramResourceiv(shaderID, GL_SHADER_STORAGE_BLOCK, resourceIndex, 1, &prop, (int32_t)members.size(), nullptr, members.data());
// Reserve memory for the names of the members
int32_t memberNameSize;
glGetProgramInterfaceiv(shaderID, GL_BUFFER_VARIABLE, GL_MAX_NAME_LENGTH, &memberNameSize);
std::vector<char> memberNameBuffer(memberNameSize);
int32_t lastOffset = 0;
int32_t lastType = 0;
for (int32_t i = 0; i < memberCount; i++) {
// Get name of buffer variable
int32_t stringLength;
glGetProgramResourceName(shaderID, GL_BUFFER_VARIABLE, members[i], memberNameSize, &stringLength, memberNameBuffer.data());
std::string memberName = std::string(memberNameBuffer.begin(), memberNameBuffer.begin() + stringLength);
// Get the other data needed for computing
uint32_t props[7] = {
GL_OFFSET, // 0
GL_TYPE, // 1
GL_ARRAY_SIZE, // 2
GL_ARRAY_STRIDE, // 3
GL_MATRIX_STRIDE, // 4
GL_TOP_LEVEL_ARRAY_SIZE, // 5
GL_TOP_LEVEL_ARRAY_STRIDE, // 6
};
int32_t params[7];
glGetProgramResourceiv(shaderID, GL_BUFFER_VARIABLE, members[i], 7, props, 7, nullptr, params);
// ruc::error("{}", memberName);
// ruc::error("\n Offset: {}, type: {:#x}, arraySize: {}, arrayStride: {},\n matrixStride: {}, top level size: {}, top level stride: {}\n",
// params[0], params[1], params[2], params[3], params[4], params[5], params[6]);
// Array of structs
if (params[5] != 1 && params[6 != 0]) {
size_t bracketOpen = memberName.find_first_of('[');
size_t bracketClose = memberName.find_first_of(']');
std::string memberNameBegin = memberName.substr(0, bracketOpen); // name: myArray[0].member -> myArray
std::string memberNameMember = memberName.substr(bracketClose + 1); // name: myArray[0].member -> .member
for (int32_t j = 0; j < params[5]; ++j) {
lastOffset = params[0] + (j * params[6]); // calc offset
lastType = params[1];
// Only add the member variant the first time its encountered
if (j == 0 && block.memberOffsets.find(memberNameBegin) == block.memberOffsets.end()) {
block.memberOffsets.emplace(memberNameBegin, lastOffset); // name: myArray
}
// Only add the index variant the first time its encountered
std::string memberNameIndex = memberNameBegin + "[" + std::to_string(j) + "]"; // name: myArray -> myArray[i]
if (block.memberOffsets.find(memberNameIndex) == block.memberOffsets.end()) {
block.memberOffsets.emplace(memberNameIndex, lastOffset);
}
block.memberOffsets.emplace(memberNameIndex + memberNameMember, // name: myArray -> myArray[i].member
lastOffset);
}
}
// Array of primitives
else if (params[2] != 1 && params[3] != 0) {
std::string memberNameBegin = memberName.substr(0, memberName.find_first_of('[')); // name: myArray[0] -> myArray
for (int32_t j = 0; j < params[2]; ++j) {
lastOffset = params[0] + (j * params[3]); // calc offset
lastType = params[1];
// Only add the member variant the first time its encountered
if (j == 0) {
block.memberOffsets.emplace(memberNameBegin, lastOffset); // name: myArray
}
block.memberOffsets.emplace(memberNameBegin + "[" + std::to_string(j) + "]", // name: myArray -> myArray[i]
lastOffset);
}
}
// Matrix case
else if (params[4] != 0) {
lastType = params[1];
lastOffset = params[0];
block.memberOffsets.emplace(memberName, params[0]);
}
else {
lastType = params[1];
lastOffset = params[0];
block.memberOffsets.emplace(memberName, params[0]);
}
}
block.size = lastOffset + BufferElement::getGLTypeSize(lastType);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
// Results
// for (auto [k, v] : block.memberOffsets) {
// ruc::error("{}:{}", k, v);
// }
}
void ShaderStorageBuffer::create(std::string_view blockName)
{
VERIFY(exists(blockName), "shader storage buffer block doesnt exist");
BufferBlock& block = m_blocks[blockName.data()];
if (block.id != 0) {
glDeleteBuffers(1, &block.id);
}
// Allocate buffer
block.id = UINT_MAX;
glGenBuffers(1, &block.id);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, block.id);
glBufferData(GL_SHADER_STORAGE_BUFFER, block.size, NULL, GL_DYNAMIC_DRAW);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
// Bind buffer to binding point
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, block.bindingPoint, block.id);
}
void ShaderStorageBuffer::setValue(std::string_view blockName, std::string_view member, bool value)
{
setValue(blockName, member, static_cast<uint32_t>(value), sizeof(uint32_t));
}
void ShaderStorageBuffer::setValue(std::string_view blockName, std::string_view member, glm::mat2 value)
{
setValue(blockName, member, static_cast<glm::mat4>(value), sizeof(glm::vec4) * 2);
}
void ShaderStorageBuffer::setValue(std::string_view blockName, std::string_view member, glm::mat3 value)
{
setValue(blockName, member, static_cast<glm::mat4>(value), sizeof(glm::vec4) * 3);
}
} // namespace Inferno

63
src/inferno/render/shader-storage-buffer.h

@ -0,0 +1,63 @@
/*
* Copyright (C) 2024 Riyyi
*
* SPDX-License-Identifier: MIT
*/
#pragma once
#include <cstddef> // size_t
#include <cstdint> // uint8_t, uint32_t
#include <string_view>
#include <unordered_map>
#include "glad/glad.h"
#include "glm/ext/matrix_float2x2.hpp" // glm::mat2
#include "glm/ext/matrix_float3x3.hpp" // glm::mat3
#include "ruc/singleton.h"
#define CHECK_SET_CALL(blockName, member) \
VERIFY(exists(blockName), "shader storage buffer block doesnt exist: {}", blockName); \
const BufferBlock& block = m_blocks[blockName.data()]; \
VERIFY(block.memberOffsets.find(member.data()) != block.memberOffsets.end(), \
"shader storage buffer member doesnt exist: {}", member);
namespace Inferno {
struct BufferBlock {
uint32_t id { 0 };
uint32_t size { 0 };
uint8_t bindingPoint { 0 };
std::unordered_map<std::string, uint32_t> memberOffsets {};
};
class ShaderStorageBuffer final : public ruc::Singleton<ShaderStorageBuffer> { // Shader Storage Buffer Object, SSBO
public:
ShaderStorageBuffer(s);
virtual ~ShaderStorageBuffer();
void setLayout(std::string_view blockName, uint8_t bindingPoint, uint32_t shaderID);
void create(std::string_view blockName);
bool exists(std::string_view blockName) const { return m_blocks.find(blockName.data()) != m_blocks.end(); }
template<typename T> // Capture value by reference, instead of decaying to pointer
void setValue(std::string_view blockName, std::string_view member, T&& value, size_t size = 0)
{
CHECK_SET_CALL(blockName, member);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, block.id);
glBufferSubData(GL_SHADER_STORAGE_BUFFER, block.memberOffsets.at(member.data()), (size) ? size : sizeof(T), &value);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
}
// Exceptions:
void setValue(std::string_view blockName, std::string_view member, bool value);
void setValue(std::string_view blockName, std::string_view member, glm::mat2 value);
void setValue(std::string_view blockName, std::string_view member, glm::mat3 value);
private:
uint8_t m_maxBindingPoints { 0 };
std::unordered_map<std::string, BufferBlock> m_blocks;
};
} // namespace Inferno

24
src/inferno/render/shader-structs.h

@ -0,0 +1,24 @@
/*
* Copyright (C) 2024 Riyyi
*
* SPDX-License-Identifier: MIT
*/
#pragma once
#include "glm/ext/vector_float3.hpp" // glm::vec3
namespace Inferno {
// Shader storage block layouts, using std430 memory layout rules
#define MAX_DIRECTIONAL_LIGHTS 4
struct alignas(16) DirectionalLightBlock {
alignas(16) glm::vec3 direction { 0 };
alignas(16) glm::vec3 ambient { 0 };
alignas(16) glm::vec3 diffuse { 0 };
alignas(16) glm::vec3 specular { 0 };
};
} // namespace Inferno

1
src/inferno/render/uniformbuffer.cpp

@ -59,6 +59,7 @@ void Uniformbuffer::setLayout(std::string_view blockName, uint8_t bindingPoint,
UniformbufferBlock& block = m_blocks[blockName];
block.bindingPoint = bindingPoint;
block.uniformLocations.clear();
// Example block layout:
// - mat3

28
src/inferno/render/uniformbuffer.h

@ -4,6 +4,8 @@
* SPDX-License-Identifier: MIT
*/
#pragma once
#include <cstddef> // size_t
#include <cstdint> // uint8_t, uint32_t
#include <string>
@ -13,36 +15,18 @@
#include "glad/glad.h"
#include "glm/ext/matrix_float2x2.hpp" // glm::mat2
#include "glm/ext/matrix_float3x3.hpp" // glm::mat3
#include "glm/ext/vector_float3.hpp" // glm::vec3
#include "ruc/singleton.h"
#include "inferno/render/buffer.h"
#define CHECK_SET_CALL(blockName, member) \
VERIFY(exists(blockName), "uniformbuffer block doesnt exist"); \
#define CHECK_UNIFORM_SET_CALL(blockName, member) \
VERIFY(exists(blockName), "uniformbuffer block doesnt exist: {}", blockName); \
const UniformbufferBlock& block = m_blocks[blockName]; \
VERIFY(block.uniformLocations.find(member.data()) != block.uniformLocations.end(), \
"uniformbuffer block member doesnt exist");
"uniformbuffer member doesnt exist: {}", member);
namespace Inferno {
// Uniform block layouts, using std140 memory layout rules
#define MAX_DIRECTIONAL_LIGHTS 32
struct UniformDirectionalLight {
glm::vec3 direction { 0 };
float __padding0 { 0 };
glm::vec3 ambient { 0 };
float __padding1 { 0 };
glm::vec3 diffuse { 0 };
float __padding2 { 0 };
glm::vec3 specular { 0 };
float __padding3 { 0 };
};
// -----------------------------------------
struct UniformbufferBlock {
uint32_t id { 0 };
uint32_t size { 0 };
@ -62,7 +46,7 @@ public:
template<typename T> // Capture value by reference, instead of decaying to pointer
void setValue(std::string_view blockName, std::string_view member, T&& value, size_t size = 0)
{
CHECK_SET_CALL(blockName, member);
CHECK_UNIFORM_SET_CALL(blockName, member);
glBindBuffer(GL_UNIFORM_BUFFER, block.id);
glBufferSubData(GL_UNIFORM_BUFFER, block.uniformLocations.at(member.data()), (size) ? size : sizeof(T), &value);

24
src/inferno/system/rendersystem.cpp

@ -16,6 +16,8 @@
#include "inferno/render/framebuffer.h"
#include "inferno/render/render-command.h"
#include "inferno/render/renderer.h"
#include "inferno/render/shader-storage-buffer.h"
#include "inferno/render/shader-structs.h"
#include "inferno/render/uniformbuffer.h"
#include "inferno/system/camerasystem.h"
#include "inferno/system/rendersystem.h"
@ -57,16 +59,8 @@ void RenderSystem::initialize(uint32_t width, uint32_t height)
});
Uniformbuffer::the().create("Camera");
Uniformbuffer::the().setLayout(
"DirectionalLights",
{
.size = sizeof(UniformDirectionalLight) * MAX_DIRECTIONAL_LIGHTS,
.bindingPoint = 1,
.uniformLocations = {
{ "u_directionalLight", 0 },
},
});
Uniformbuffer::the().create("DirectionalLights");
ShaderStorageBuffer::the().setLayout("DirectionalLights", 0, RendererPostProcess::the().shaderID());
ShaderStorageBuffer::the().create("DirectionalLights");
ruc::info("RenderSystem initialized");
}
@ -137,15 +131,21 @@ void RenderSystem::renderGeometry()
Uniformbuffer::the().setValue("Camera", "u_projectionView", projection * view);
Uniformbuffer::the().setValue("Camera", "u_position", translate);
static UniformDirectionalLight directionalLights[1] = {
static DirectionalLightBlock directionalLights[2] = {
{
.direction = { -8.0f, -8.0f, -8.0f },
.ambient = { 0.1f, 0.1f, 0.1f },
.diffuse = { 1.0f, 1.0f, 1.0f },
.specular = { 1.0f, 1.0f, 1.0f },
},
{
.direction = { 8.0f, 8.0f, 8.0f },
.ambient = { 0.1f, 0.1f, 0.1f },
.diffuse = { 1.0f, 1.0f, 1.0f },
.specular = { 1.0f, 0.0f, 0.0f },
},
};
Uniformbuffer::the().setValue("DirectionalLights", "u_directionalLight", directionalLights);
ShaderStorageBuffer::the().setValue("DirectionalLights", "u_directionalLight", directionalLights);
auto modelView = m_registry->view<TransformComponent, ModelComponent>();

2
src/inferno/system/textareasystem.h

@ -18,7 +18,7 @@
namespace Inferno {
using Symbols = std::vector<std::shared_ptr<Symbol>>;
using SymbolQuad = std::array<SymbolVertex, Renderer<void>::vertexPerQuad>;
using SymbolQuad = std::array<SymbolVertex, RendererFont::vertexPerQuad>;
class Scene;
class TextAreaComponent;

1
vendor/CMakeLists.txt vendored

@ -33,3 +33,4 @@ target_include_directories(${ENGINE}-dependencies PUBLIC
"glad/include"
"lua")
target_link_libraries(${ENGINE}-dependencies glfw ruc ruc-test assimp)
target_compile_options(${ENGINE}-dependencies PRIVATE ${COMPILE_FLAGS_DEPS})

2
vendor/ruc vendored

@ -1 +1 @@
Subproject commit 85209522358c83dc28df2499b4d70c754121e74d
Subproject commit d5bf50715e0a95d56f86cac260d0c0d4205b779e
Loading…
Cancel
Save