Engine: Implement skybox
This commit is contained in:
Binary file not shown.
|
After Width: | Height: | Size: 77 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 77 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 69 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 88 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 87 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 79 KiB |
@@ -0,0 +1,49 @@
|
|||||||
|
#version 450 core
|
||||||
|
|
||||||
|
layout(location = 0) out vec4 color;
|
||||||
|
|
||||||
|
in vec4 v_color;
|
||||||
|
in vec3 v_textureCoordinates;
|
||||||
|
in flat float v_textureIndex;
|
||||||
|
|
||||||
|
uniform samplerCube u_textures[32];
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
vec4 textureColor = v_color;
|
||||||
|
switch(int(v_textureIndex)) {
|
||||||
|
case 0: break; // Texture unit 0 is reserved for no texture
|
||||||
|
case 1: textureColor *= texture(u_textures[1], v_textureCoordinates); break;
|
||||||
|
case 2: textureColor *= texture(u_textures[2], v_textureCoordinates); break;
|
||||||
|
case 3: textureColor *= texture(u_textures[3], v_textureCoordinates); break;
|
||||||
|
case 4: textureColor *= texture(u_textures[4], v_textureCoordinates); break;
|
||||||
|
case 5: textureColor *= texture(u_textures[5], v_textureCoordinates); break;
|
||||||
|
case 6: textureColor *= texture(u_textures[6], v_textureCoordinates); break;
|
||||||
|
case 7: textureColor *= texture(u_textures[7], v_textureCoordinates); break;
|
||||||
|
case 8: textureColor *= texture(u_textures[8], v_textureCoordinates); break;
|
||||||
|
case 9: textureColor *= texture(u_textures[9], v_textureCoordinates); break;
|
||||||
|
case 10: textureColor *= texture(u_textures[10], v_textureCoordinates); break;
|
||||||
|
case 11: textureColor *= texture(u_textures[11], v_textureCoordinates); break;
|
||||||
|
case 12: textureColor *= texture(u_textures[12], v_textureCoordinates); break;
|
||||||
|
case 13: textureColor *= texture(u_textures[13], v_textureCoordinates); break;
|
||||||
|
case 14: textureColor *= texture(u_textures[14], v_textureCoordinates); break;
|
||||||
|
case 15: textureColor *= texture(u_textures[15], v_textureCoordinates); break;
|
||||||
|
case 16: textureColor *= texture(u_textures[16], v_textureCoordinates); break;
|
||||||
|
case 17: textureColor *= texture(u_textures[17], v_textureCoordinates); break;
|
||||||
|
case 18: textureColor *= texture(u_textures[18], v_textureCoordinates); break;
|
||||||
|
case 19: textureColor *= texture(u_textures[19], v_textureCoordinates); break;
|
||||||
|
case 20: textureColor *= texture(u_textures[20], v_textureCoordinates); break;
|
||||||
|
case 21: textureColor *= texture(u_textures[21], v_textureCoordinates); break;
|
||||||
|
case 22: textureColor *= texture(u_textures[22], v_textureCoordinates); break;
|
||||||
|
case 23: textureColor *= texture(u_textures[23], v_textureCoordinates); break;
|
||||||
|
case 24: textureColor *= texture(u_textures[24], v_textureCoordinates); break;
|
||||||
|
case 25: textureColor *= texture(u_textures[25], v_textureCoordinates); break;
|
||||||
|
case 26: textureColor *= texture(u_textures[26], v_textureCoordinates); break;
|
||||||
|
case 27: textureColor *= texture(u_textures[27], v_textureCoordinates); break;
|
||||||
|
case 28: textureColor *= texture(u_textures[28], v_textureCoordinates); break;
|
||||||
|
case 29: textureColor *= texture(u_textures[29], v_textureCoordinates); break;
|
||||||
|
case 30: textureColor *= texture(u_textures[30], v_textureCoordinates); break;
|
||||||
|
case 31: textureColor *= texture(u_textures[31], v_textureCoordinates); break;
|
||||||
|
}
|
||||||
|
color = textureColor;
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
#version 450 core
|
||||||
|
|
||||||
|
layout(location = 0) in vec3 a_position;
|
||||||
|
layout(location = 1) in vec4 a_color;
|
||||||
|
layout(location = 2) in float a_textureIndex;
|
||||||
|
|
||||||
|
out vec4 v_color;
|
||||||
|
out vec3 v_textureCoordinates;
|
||||||
|
out flat float v_textureIndex;
|
||||||
|
|
||||||
|
uniform mat4 u_projectionView;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
v_color = a_color;
|
||||||
|
v_textureCoordinates = a_position;
|
||||||
|
v_textureIndex = a_textureIndex;
|
||||||
|
// Vclip = Camera projection * Camera view * Model transform * Vlocal
|
||||||
|
gl_Position = u_projectionView * vec4(a_position, 1.0f);
|
||||||
|
}
|
||||||
@@ -14,6 +14,19 @@
|
|||||||
{ "path": "assets/lua/cameracontroller.lua" }
|
{ "path": "assets/lua/cameracontroller.lua" }
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"id": { "id": 212563732 },
|
||||||
|
"tag": { "tag": "Skybox" },
|
||||||
|
"transform" : {
|
||||||
|
"translate": [0.0, 0.0, 0.0],
|
||||||
|
"rotate": [0.0, 0.0, 0.0],
|
||||||
|
"scale": [100.0, 100.0, 100.0]
|
||||||
|
},
|
||||||
|
"cubemap": {
|
||||||
|
"color": [ 1.0, 1.0, 1.0, 1.0 ],
|
||||||
|
"texture": "assets/gfx/skybox.jpg"
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"id": { "id": 564564564 },
|
"id": { "id": 564564564 },
|
||||||
"tag": { "tag": "Quad" },
|
"tag": { "tag": "Quad" },
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2022 Riyyi
|
* Copyright (C) 2022,2024 Riyyi
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: MIT
|
* SPDX-License-Identifier: MIT
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <utility> // std::pair
|
||||||
|
|
||||||
#include "glm/gtc/type_ptr.hpp" // glm::make_mat4
|
#include "glm/gtc/type_ptr.hpp" // glm::make_mat4
|
||||||
#include "ruc/format/log.h"
|
#include "ruc/format/log.h"
|
||||||
#include "ruc/meta/assert.h"
|
#include "ruc/meta/assert.h"
|
||||||
@@ -78,6 +80,7 @@ Application::~Application()
|
|||||||
FontManager::destroy();
|
FontManager::destroy();
|
||||||
RendererCharacter::destroy();
|
RendererCharacter::destroy();
|
||||||
Renderer2D::destroy();
|
Renderer2D::destroy();
|
||||||
|
RendererCubemap::destroy();
|
||||||
RenderCommand::destroy();
|
RenderCommand::destroy();
|
||||||
TextureManager::destroy();
|
TextureManager::destroy();
|
||||||
ShaderManager::destroy();
|
ShaderManager::destroy();
|
||||||
@@ -164,12 +167,15 @@ int Application::run()
|
|||||||
RenderCommand::clearColor({ 0.2f, 0.3f, 0.3f, 1.0f });
|
RenderCommand::clearColor({ 0.2f, 0.3f, 0.3f, 1.0f });
|
||||||
RenderCommand::clear();
|
RenderCommand::clear();
|
||||||
|
|
||||||
Renderer2D::the().beginScene(m_scene->cameraProjectionView()); // camera, lights, environment
|
std::pair<glm::mat4, glm::mat4> projectionView = m_scene->cameraProjectionView();
|
||||||
|
RendererCubemap::the().beginScene(projectionView.first, projectionView.second); // camera, lights, environment
|
||||||
|
Renderer2D::the().beginScene(projectionView.first, projectionView.second); // camera, lights, environment
|
||||||
RendererCharacter::the().beginScene();
|
RendererCharacter::the().beginScene();
|
||||||
|
|
||||||
m_scene->render();
|
m_scene->render();
|
||||||
// RendererCharacter::the().drawCharacter(character, f->texture());
|
// RendererCharacter::the().drawCharacter(character, f->texture());
|
||||||
|
|
||||||
|
RendererCubemap::the().endScene();
|
||||||
Renderer2D::the().endScene();
|
Renderer2D::the().endScene();
|
||||||
RendererCharacter::the().endScene();
|
RendererCharacter::the().endScene();
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,27 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2024 Riyyi
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "ruc/json/json.h"
|
||||||
|
|
||||||
|
#include "inferno/component/cubemap-component.h"
|
||||||
|
#include "inferno/component/spritecomponent.h" // TODO: Move glm::x toJson/fromJson to separate file
|
||||||
|
#include "inferno/render/texture.h"
|
||||||
|
|
||||||
|
namespace Inferno {
|
||||||
|
|
||||||
|
void fromJson(const ruc::Json& json, CubemapComponent& value)
|
||||||
|
{
|
||||||
|
VERIFY(json.type() == ruc::Json::Type::Object);
|
||||||
|
|
||||||
|
if (json.exists("color")) {
|
||||||
|
json.at("color").getTo(value.color);
|
||||||
|
}
|
||||||
|
if (json.exists("texture") && json.at("texture").type() == ruc::Json::Type::String) {
|
||||||
|
value.texture = TextureManager::the().load(json.at("texture").asString(), Texture::Type::Cubemap);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Inferno
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2024 Riyyi
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <memory> // std::shared_ptr
|
||||||
|
|
||||||
|
#include "glm/ext/vector_float4.hpp" // glm::vec4
|
||||||
|
#include "ruc/json/json.h"
|
||||||
|
|
||||||
|
#include "inferno/render/texture.h"
|
||||||
|
|
||||||
|
namespace Inferno {
|
||||||
|
|
||||||
|
struct CubemapComponent {
|
||||||
|
glm::vec4 color { 1.0f };
|
||||||
|
std::shared_ptr<Texture> texture;
|
||||||
|
};
|
||||||
|
|
||||||
|
void fromJson(const ruc::Json& json, CubemapComponent& value);
|
||||||
|
|
||||||
|
} // namespace Inferno
|
||||||
@@ -32,7 +32,7 @@ Font::Font(const std::string& name)
|
|||||||
std::string font = ruc::File(path).data();
|
std::string font = ruc::File(path).data();
|
||||||
parseFont(font);
|
parseFont(font);
|
||||||
|
|
||||||
m_texture = std::make_shared<Texture>(image);
|
m_texture = Texture2D::create(image);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Move this to ruc
|
// TODO: Move this to ruc
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2022 Riyyi
|
* Copyright (C) 2022,2024 Riyyi
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: MIT
|
* SPDX-License-Identifier: MIT
|
||||||
*/
|
*/
|
||||||
@@ -216,10 +216,10 @@ Renderer2D::~Renderer2D()
|
|||||||
Renderer::destroy();
|
Renderer::destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Renderer2D::beginScene(glm::mat4 cameraProjectionView)
|
void Renderer2D::beginScene(glm::mat4 cameraProjection, glm::mat4 cameraView)
|
||||||
{
|
{
|
||||||
m_shader->bind();
|
m_shader->bind();
|
||||||
m_shader->setFloat("u_projectionView", cameraProjectionView);
|
m_shader->setFloat("u_projectionView", cameraProjection * cameraView);
|
||||||
m_shader->unbind();
|
m_shader->unbind();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -311,6 +311,184 @@ void Renderer2D::nextBatch()
|
|||||||
|
|
||||||
// -----------------------------------------
|
// -----------------------------------------
|
||||||
|
|
||||||
|
RendererCubemap::RendererCubemap(s)
|
||||||
|
{
|
||||||
|
Renderer::initialize();
|
||||||
|
|
||||||
|
// CPU
|
||||||
|
// ---------------------------------
|
||||||
|
|
||||||
|
// Create array for storing quads vertices
|
||||||
|
m_vertexBufferBase = std::make_unique<CubemapVertex[]>(vertexCount);
|
||||||
|
m_vertexBufferPtr = m_vertexBufferBase.get();
|
||||||
|
|
||||||
|
// Set default cubemap vertex positions
|
||||||
|
|
||||||
|
// Back face - v
|
||||||
|
m_vertexPositions[0] = { 0.5f, -0.5f, 0.5f, 1.0f };
|
||||||
|
m_vertexPositions[1] = { -0.5f, -0.5f, 0.5f, 1.0f };
|
||||||
|
m_vertexPositions[2] = { -0.5f, 0.5f, 0.5f, 1.0f };
|
||||||
|
m_vertexPositions[3] = { 0.5f, 0.5f, 0.5f, 1.0f };
|
||||||
|
|
||||||
|
// Left face - v
|
||||||
|
m_vertexPositions[7] = { -0.5f, 0.5f, 0.5f, 1.0f };
|
||||||
|
m_vertexPositions[6] = { -0.5f, 0.5f, -0.5f, 1.0f };
|
||||||
|
m_vertexPositions[5] = { -0.5f, -0.5f, -0.5f, 1.0f };
|
||||||
|
m_vertexPositions[4] = { -0.5f, -0.5f, 0.5f, 1.0f };
|
||||||
|
|
||||||
|
// Right face - v
|
||||||
|
m_vertexPositions[8] = { 0.5f, -0.5f, -0.5f, 1.0f };
|
||||||
|
m_vertexPositions[9] = { 0.5f, -0.5f, 0.5f, 1.0f };
|
||||||
|
m_vertexPositions[10] = { 0.5f, 0.5f, 0.5f, 1.0f };
|
||||||
|
m_vertexPositions[11] = { 0.5f, 0.5f, -0.5f, 1.0f };
|
||||||
|
|
||||||
|
// Front face - v
|
||||||
|
m_vertexPositions[12] = { -0.5f, -0.5f, -0.5f, 1.0f };
|
||||||
|
m_vertexPositions[13] = { 0.5f, -0.5f, -0.5f, 1.0f };
|
||||||
|
m_vertexPositions[14] = { 0.5f, 0.5f, -0.5f, 1.0f };
|
||||||
|
m_vertexPositions[15] = { -0.5f, 0.5f, -0.5f, 1.0f };
|
||||||
|
|
||||||
|
// Top face
|
||||||
|
m_vertexPositions[16] = { -0.5f, 0.5f, -0.5f, 1.0f };
|
||||||
|
m_vertexPositions[17] = { 0.5f, 0.5f, -0.5f, 1.0f };
|
||||||
|
m_vertexPositions[18] = { 0.5f, 0.5f, 0.5f, 1.0f };
|
||||||
|
m_vertexPositions[19] = { -0.5f, 0.5f, 0.5f, 1.0f };
|
||||||
|
|
||||||
|
// Bottom face
|
||||||
|
m_vertexPositions[20] = { -0.5f, -0.5f, -0.5f, 1.0f };
|
||||||
|
m_vertexPositions[21] = { -0.5f, -0.5f, 0.5f, 1.0f };
|
||||||
|
m_vertexPositions[22] = { 0.5f, -0.5f, 0.5f, 1.0f };
|
||||||
|
m_vertexPositions[23] = { 0.5f, -0.5f, -0.5f, 1.0f };
|
||||||
|
|
||||||
|
// Generate indices
|
||||||
|
|
||||||
|
uint32_t* indices = new uint32_t[indexCount];
|
||||||
|
|
||||||
|
uint32_t offset = 0;
|
||||||
|
for (uint32_t i = 0; i < indexCount; i += indexPerQuad) {
|
||||||
|
indices[i + 0] = offset + 0;
|
||||||
|
indices[i + 1] = offset + 1;
|
||||||
|
indices[i + 2] = offset + 2;
|
||||||
|
indices[i + 3] = offset + 2;
|
||||||
|
indices[i + 4] = offset + 3;
|
||||||
|
indices[i + 5] = offset + 0;
|
||||||
|
|
||||||
|
offset += vertexPerQuad;
|
||||||
|
}
|
||||||
|
|
||||||
|
// GPU
|
||||||
|
// ---------------------------------
|
||||||
|
|
||||||
|
// Create vertex buffer
|
||||||
|
auto vertexBuffer = std::make_shared<VertexBuffer>(sizeof(CubemapVertex) * vertexCount);
|
||||||
|
vertexBuffer->setLayout({
|
||||||
|
{ BufferElementType::Vec3, "a_position" },
|
||||||
|
{ BufferElementType::Vec4, "a_color" },
|
||||||
|
{ BufferElementType::Float, "a_textureIndex" },
|
||||||
|
});
|
||||||
|
m_vertexArray->addVertexBuffer(vertexBuffer);
|
||||||
|
|
||||||
|
// Create index buffer
|
||||||
|
auto indexBuffer = std::make_shared<IndexBuffer>(indices, sizeof(uint32_t) * indexCount);
|
||||||
|
m_vertexArray->setIndexBuffer(indexBuffer);
|
||||||
|
delete[] indices;
|
||||||
|
|
||||||
|
ruc::info("RendererCubemap initialized");
|
||||||
|
}
|
||||||
|
|
||||||
|
RendererCubemap::~RendererCubemap()
|
||||||
|
{
|
||||||
|
Renderer::destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
void RendererCubemap::beginScene(glm::mat4 cameraProjection, glm::mat4 cameraView)
|
||||||
|
{
|
||||||
|
// We want the skybox fixed in position, so only retain the rotation and scale.
|
||||||
|
// Set the translation of the camera's view matrix to 0, meaning:
|
||||||
|
// x x x 0
|
||||||
|
// x x x 0
|
||||||
|
// x x x 0
|
||||||
|
// 0 0 0 1
|
||||||
|
cameraView = glm::mat4(glm::mat3(cameraView));
|
||||||
|
|
||||||
|
m_shader->bind();
|
||||||
|
m_shader->setFloat("u_projectionView", cameraProjection * cameraView);
|
||||||
|
m_shader->unbind();
|
||||||
|
}
|
||||||
|
|
||||||
|
void RendererCubemap::endScene()
|
||||||
|
{
|
||||||
|
nextBatch();
|
||||||
|
}
|
||||||
|
|
||||||
|
void RendererCubemap::drawCubemap(const TransformComponent& transform, glm::vec4 color, std::shared_ptr<Texture> texture)
|
||||||
|
{
|
||||||
|
drawCubemap(transform, glm::mat4(color, color, color, color), texture);
|
||||||
|
}
|
||||||
|
|
||||||
|
void RendererCubemap::drawCubemap(const TransformComponent& transform, glm::mat4 color, std::shared_ptr<Texture> texture)
|
||||||
|
{
|
||||||
|
// Create a new batch if the quad limit has been reached
|
||||||
|
if (m_quadIndex >= quadCount) {
|
||||||
|
nextBatch();
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t textureUnitIndex = addTextureUnit(texture);
|
||||||
|
|
||||||
|
// Add the quads 4 vertices
|
||||||
|
for (uint32_t i = 0; i < vertexPerQuad * quadPerCube; i++) {
|
||||||
|
m_vertexBufferPtr->position = transform.transform * m_vertexPositions[i];
|
||||||
|
m_vertexBufferPtr->color = color[i % 4];
|
||||||
|
m_vertexBufferPtr->textureIndex = (float)textureUnitIndex;
|
||||||
|
m_vertexBufferPtr++;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_quadIndex += quadPerCube;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RendererCubemap::loadShader()
|
||||||
|
{
|
||||||
|
m_shader = ShaderManager::the().load("assets/glsl/batch-cubemap");
|
||||||
|
}
|
||||||
|
|
||||||
|
void RendererCubemap::flush()
|
||||||
|
{
|
||||||
|
if (m_quadIndex == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Upload vertex data to GPU
|
||||||
|
m_vertexArray->getVertexBuffers().at(0)->uploadData(
|
||||||
|
m_vertexBufferBase.get(),
|
||||||
|
m_quadIndex * vertexPerQuad * sizeof(CubemapVertex));
|
||||||
|
|
||||||
|
bind();
|
||||||
|
|
||||||
|
// Render
|
||||||
|
bool depthTest = RenderCommand::depthTest();
|
||||||
|
RenderCommand::setDepthTest(false);
|
||||||
|
RenderCommand::drawIndexed(*m_vertexArray, m_quadIndex * indexPerQuad);
|
||||||
|
RenderCommand::setDepthTest(depthTest);
|
||||||
|
|
||||||
|
unbind();
|
||||||
|
}
|
||||||
|
|
||||||
|
void RendererCubemap::startBatch()
|
||||||
|
{
|
||||||
|
m_quadIndex = 0;
|
||||||
|
m_vertexBufferPtr = m_vertexBufferBase.get();
|
||||||
|
|
||||||
|
m_textureUnitIndex = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RendererCubemap::nextBatch()
|
||||||
|
{
|
||||||
|
flush();
|
||||||
|
startBatch();
|
||||||
|
}
|
||||||
|
|
||||||
|
// -----------------------------------------
|
||||||
|
|
||||||
RendererCharacter::RendererCharacter(s)
|
RendererCharacter::RendererCharacter(s)
|
||||||
{
|
{
|
||||||
Renderer::initialize();
|
Renderer::initialize();
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2022 Riyyi
|
* Copyright (C) 2022,2024 Riyyi
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: MIT
|
* SPDX-License-Identifier: MIT
|
||||||
*/
|
*/
|
||||||
@@ -27,7 +27,13 @@ struct QuadVertex {
|
|||||||
glm::vec3 position { 0.0f, 0.0f, 0.0f };
|
glm::vec3 position { 0.0f, 0.0f, 0.0f };
|
||||||
glm::vec4 color { 1.0f, 1.0f, 1.0f, 1.0f };
|
glm::vec4 color { 1.0f, 1.0f, 1.0f, 1.0f };
|
||||||
glm::vec2 textureCoordinates { 0.0f, 0.0f };
|
glm::vec2 textureCoordinates { 0.0f, 0.0f };
|
||||||
float textureIndex = 0; // @Todo get int to pass to fragment correctly
|
float textureIndex = 0; // TODO: get int to pass to fragment correctly
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CubemapVertex {
|
||||||
|
glm::vec3 position { 0.0f, 0.0f, 0.0f };
|
||||||
|
glm::vec4 color { 1.0f, 1.0f, 1.0f, 1.0f };
|
||||||
|
float textureIndex = 0; // TODO: get int to pass to fragment correctly
|
||||||
};
|
};
|
||||||
|
|
||||||
struct CharacterVertex {
|
struct CharacterVertex {
|
||||||
@@ -66,9 +72,10 @@ public:
|
|||||||
|
|
||||||
class Renderer {
|
class Renderer {
|
||||||
public:
|
public:
|
||||||
static const uint32_t vertexPerQuad = 4;
|
static constexpr const uint32_t vertexPerQuad = 4;
|
||||||
static const uint32_t indexPerQuad = 6;
|
static constexpr const uint32_t indexPerQuad = 6;
|
||||||
static const uint32_t textureUnitPerBatch = 32;
|
static constexpr const uint32_t quadPerCube = 6;
|
||||||
|
static constexpr const uint32_t textureUnitPerBatch = 32;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Renderer() {}
|
Renderer() {}
|
||||||
@@ -108,11 +115,12 @@ public:
|
|||||||
|
|
||||||
using Singleton<Renderer2D>::destroy;
|
using Singleton<Renderer2D>::destroy;
|
||||||
|
|
||||||
static const uint32_t quadCount = 1000;
|
// When to start a new batch
|
||||||
static const uint32_t vertexCount = quadCount * vertexPerQuad;
|
static constexpr const uint32_t quadCount = 1000;
|
||||||
static const uint32_t indexCount = quadCount * indexPerQuad;
|
static constexpr const uint32_t vertexCount = quadCount * vertexPerQuad;
|
||||||
|
static constexpr const uint32_t indexCount = quadCount * indexPerQuad;
|
||||||
|
|
||||||
void beginScene(glm::mat4 cameraProjectionView);
|
void beginScene(glm::mat4 cameraProjectionView, glm::mat4 cameraView);
|
||||||
void endScene();
|
void endScene();
|
||||||
|
|
||||||
void drawQuad(const TransformComponent& transform, glm::vec4 color);
|
void drawQuad(const TransformComponent& transform, glm::vec4 color);
|
||||||
@@ -133,6 +141,42 @@ private:
|
|||||||
// Default quad vertex positions
|
// Default quad vertex positions
|
||||||
glm::vec4 m_vertexPositions[vertexPerQuad];
|
glm::vec4 m_vertexPositions[vertexPerQuad];
|
||||||
};
|
};
|
||||||
|
// -------------------------------------
|
||||||
|
|
||||||
|
class RendererCubemap final
|
||||||
|
: public Renderer
|
||||||
|
, public ruc::Singleton<RendererCubemap> {
|
||||||
|
public:
|
||||||
|
RendererCubemap(s);
|
||||||
|
virtual ~RendererCubemap();
|
||||||
|
|
||||||
|
using Singleton<RendererCubemap>::destroy;
|
||||||
|
|
||||||
|
// When to start a new batch
|
||||||
|
static constexpr const uint32_t cubemapCount = 166;
|
||||||
|
static constexpr const uint32_t quadCount = cubemapCount * quadPerCube;
|
||||||
|
static constexpr const uint32_t vertexCount = quadCount * vertexPerQuad;
|
||||||
|
static constexpr const uint32_t indexCount = quadCount * indexPerQuad;
|
||||||
|
|
||||||
|
void beginScene(glm::mat4 cameraProjectionView, glm::mat4 cameraView);
|
||||||
|
void endScene();
|
||||||
|
|
||||||
|
void drawCubemap(const TransformComponent& transform, glm::vec4 color, std::shared_ptr<Texture> texture);
|
||||||
|
void drawCubemap(const TransformComponent& transform, glm::mat4 color, std::shared_ptr<Texture> texture);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void loadShader() override;
|
||||||
|
void flush() override;
|
||||||
|
void startBatch() override;
|
||||||
|
void nextBatch() override;
|
||||||
|
|
||||||
|
// CPU quad vertices
|
||||||
|
std::unique_ptr<CubemapVertex[]> m_vertexBufferBase;
|
||||||
|
CubemapVertex* m_vertexBufferPtr { nullptr };
|
||||||
|
|
||||||
|
// Default cubemap vertex positions
|
||||||
|
glm::vec4 m_vertexPositions[vertexPerQuad * quadPerCube];
|
||||||
|
};
|
||||||
|
|
||||||
// -------------------------------------
|
// -------------------------------------
|
||||||
|
|
||||||
|
|||||||
+123
-42
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2022 Riyyi
|
* Copyright (C) 2022,2024 Riyyi
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: MIT
|
* SPDX-License-Identifier: MIT
|
||||||
*/
|
*/
|
||||||
@@ -19,36 +19,47 @@
|
|||||||
|
|
||||||
namespace Inferno {
|
namespace Inferno {
|
||||||
|
|
||||||
Texture::Texture(const std::string& path)
|
Texture::~Texture()
|
||||||
: m_path(std::move(path))
|
|
||||||
{
|
{
|
||||||
unsigned char* data = nullptr;
|
glDeleteTextures(1, &m_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Texture::init(uint32_t width, uint32_t height, uint8_t channels)
|
||||||
|
{
|
||||||
|
m_width = width;
|
||||||
|
m_height = height;
|
||||||
|
|
||||||
|
m_internalFormat = (channels == 3) ? GL_RGB8 : GL_RGBA8;
|
||||||
|
m_dataFormat = (channels == 3) ? GL_RGB : GL_RGBA;
|
||||||
|
}
|
||||||
|
|
||||||
|
// -----------------------------------------
|
||||||
|
|
||||||
|
std::shared_ptr<Texture> Texture2D::create(const std::string& path)
|
||||||
|
{
|
||||||
|
auto result = std::shared_ptr<Texture2D>(new Texture2D);
|
||||||
|
result->m_path = path;
|
||||||
|
|
||||||
int width = 0;
|
int width = 0;
|
||||||
int height = 0;
|
int height = 0;
|
||||||
int channels = 0;
|
int channels = 0;
|
||||||
|
unsigned char* data = nullptr;
|
||||||
|
|
||||||
// Load image data
|
// Load image data
|
||||||
stbi_set_flip_vertically_on_load(1);
|
stbi_set_flip_vertically_on_load(1);
|
||||||
data = stbi_load(path.c_str(), &width, &height, &channels, STBI_default);
|
data = stbi_load(path.c_str(), &width, &height, &channels, STBI_default);
|
||||||
VERIFY(data, "failed to load image: '{}'", path);
|
VERIFY(data, "failed to load image: '{}'", path);
|
||||||
|
|
||||||
init(data, width, height, channels);
|
result->init(width, height, channels);
|
||||||
|
result->create(data);
|
||||||
|
|
||||||
// Clean resources
|
// Clean resources
|
||||||
stbi_image_free(data);
|
stbi_image_free(data);
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
Texture::Texture(unsigned char* data, uint32_t width, uint32_t height, uint8_t channels)
|
void Texture2D::bind(uint32_t unit) const
|
||||||
{
|
|
||||||
init(data, width, height, channels);
|
|
||||||
}
|
|
||||||
|
|
||||||
Texture::~Texture()
|
|
||||||
{
|
|
||||||
glDeleteTextures(1, &m_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Texture::bind(uint32_t unit) const
|
|
||||||
{
|
{
|
||||||
// Set active unit
|
// Set active unit
|
||||||
glActiveTexture(GL_TEXTURE0 + unit);
|
glActiveTexture(GL_TEXTURE0 + unit);
|
||||||
@@ -59,31 +70,12 @@ void Texture::bind(uint32_t unit) const
|
|||||||
glActiveTexture(GL_TEXTURE0);
|
glActiveTexture(GL_TEXTURE0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Texture::unbind() const
|
void Texture2D::unbind() const
|
||||||
{
|
{
|
||||||
glBindTexture(GL_TEXTURE_2D, 0);
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// -----------------------------------------
|
void Texture2D::create(unsigned char* data)
|
||||||
|
|
||||||
void Texture::init(unsigned char* data, uint32_t width, uint32_t height, uint8_t channels)
|
|
||||||
{
|
|
||||||
m_width = width;
|
|
||||||
m_height = height;
|
|
||||||
|
|
||||||
if (channels == 4) {
|
|
||||||
m_internalFormat = GL_RGBA8;
|
|
||||||
m_dataFormat = GL_RGBA;
|
|
||||||
}
|
|
||||||
else if (channels == 3) {
|
|
||||||
m_internalFormat = GL_RGB8;
|
|
||||||
m_dataFormat = GL_RGB;
|
|
||||||
}
|
|
||||||
|
|
||||||
create(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Texture::create(unsigned char* data)
|
|
||||||
{
|
{
|
||||||
m_id = UINT_MAX;
|
m_id = UINT_MAX;
|
||||||
|
|
||||||
@@ -109,10 +101,10 @@ void Texture::create(unsigned char* data)
|
|||||||
data); // Image data
|
data); // Image data
|
||||||
|
|
||||||
// Set the texture wrapping / filtering options
|
// Set the texture wrapping / filtering options
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); // Magnify
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); // Minify
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); // X
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); // X
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); // Y
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); // Y
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); // Minify
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); // Magnify
|
|
||||||
|
|
||||||
// Automatically generate all mipmap levels
|
// Automatically generate all mipmap levels
|
||||||
glGenerateMipmap(GL_TEXTURE_2D);
|
glGenerateMipmap(GL_TEXTURE_2D);
|
||||||
@@ -123,6 +115,94 @@ void Texture::create(unsigned char* data)
|
|||||||
|
|
||||||
// -----------------------------------------
|
// -----------------------------------------
|
||||||
|
|
||||||
|
std::shared_ptr<Texture> TextureCubemap::create(const std::string& path)
|
||||||
|
{
|
||||||
|
auto result = std::shared_ptr<TextureCubemap>(new TextureCubemap);
|
||||||
|
result->m_path = path;
|
||||||
|
|
||||||
|
result->create();
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TextureCubemap::bind(uint32_t unit) const
|
||||||
|
{
|
||||||
|
// Set active unit
|
||||||
|
glActiveTexture(GL_TEXTURE0 + unit);
|
||||||
|
|
||||||
|
glBindTexture(GL_TEXTURE_CUBE_MAP, m_id);
|
||||||
|
|
||||||
|
// Reset unit
|
||||||
|
glActiveTexture(GL_TEXTURE0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TextureCubemap::unbind() const
|
||||||
|
{
|
||||||
|
glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TextureCubemap::create()
|
||||||
|
{
|
||||||
|
m_id = UINT_MAX;
|
||||||
|
|
||||||
|
// Create texture object
|
||||||
|
glGenTextures(1, &m_id);
|
||||||
|
|
||||||
|
// Bind texture object
|
||||||
|
glBindTexture(GL_TEXTURE_CUBE_MAP, m_id);
|
||||||
|
|
||||||
|
// Set unpacking of pixel data to byte-alignment,
|
||||||
|
// this prevents alignment issues when using a single byte for color
|
||||||
|
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||||
|
|
||||||
|
stbi_set_flip_vertically_on_load(0);
|
||||||
|
|
||||||
|
static constexpr const char* cubemapPaths[6] { "-px", "-nx", "-py", "-ny", "-pz", "-nz" };
|
||||||
|
size_t dotIndex = m_path.find_last_of('.');
|
||||||
|
std::string path = m_path.substr(0, dotIndex);
|
||||||
|
std::string extension = m_path.substr(dotIndex);
|
||||||
|
|
||||||
|
int width = 0;
|
||||||
|
int height = 0;
|
||||||
|
int channels = 0;
|
||||||
|
unsigned char* data = nullptr;
|
||||||
|
for (size_t i = 0; i < 6; ++i) {
|
||||||
|
std::string facePath = path + cubemapPaths[i] + extension;
|
||||||
|
|
||||||
|
// Load image data
|
||||||
|
data = stbi_load(facePath.c_str(), &width, &height, &channels, STBI_default);
|
||||||
|
VERIFY(data, "failed to load image: '{}'", facePath.c_str());
|
||||||
|
|
||||||
|
init(width, height, channels);
|
||||||
|
|
||||||
|
// Generate texture face
|
||||||
|
glTexImage2D(
|
||||||
|
GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, // Texture target
|
||||||
|
0, // Midmap level, base starts at level 0
|
||||||
|
m_internalFormat, // Internal format
|
||||||
|
m_width, m_height, // Image width/height
|
||||||
|
0, // Always 0 (legacy)
|
||||||
|
m_dataFormat, // Texture source format
|
||||||
|
GL_UNSIGNED_BYTE, // Texture source datatype
|
||||||
|
data); // Image data
|
||||||
|
|
||||||
|
// Clean resources
|
||||||
|
stbi_image_free(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the texture wrapping / filtering options
|
||||||
|
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // Magnify
|
||||||
|
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR); // Minify
|
||||||
|
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); // X
|
||||||
|
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); // Y
|
||||||
|
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); // Z
|
||||||
|
|
||||||
|
// Unbind texture object
|
||||||
|
glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// -----------------------------------------
|
||||||
|
|
||||||
TextureManager::TextureManager(s)
|
TextureManager::TextureManager(s)
|
||||||
{
|
{
|
||||||
ruc::info("TextureManager initialized");
|
ruc::info("TextureManager initialized");
|
||||||
@@ -138,15 +218,16 @@ void TextureManager::add(const std::string& path, std::shared_ptr<Texture> textu
|
|||||||
m_textureList.emplace(std::move(path), std::move(texture));
|
m_textureList.emplace(std::move(path), std::move(texture));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<Texture> TextureManager::load(const std::string& path)
|
std::shared_ptr<Texture> TextureManager::load(const std::string& path, Texture::Type type)
|
||||||
{
|
{
|
||||||
if (exists(path)) {
|
if (exists(path)) {
|
||||||
return get(path);
|
return get(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<Texture> texture = std::make_shared<Texture>(path);
|
auto texture = (type == Texture::TwoDimensional) ? Texture2D::create(path) : TextureCubemap::create(path);
|
||||||
add(path, texture);
|
add(path, texture);
|
||||||
return get(path);
|
|
||||||
|
return texture;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<Texture> TextureManager::get(const std::string& path)
|
std::shared_ptr<Texture> TextureManager::get(const std::string& path)
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2022 Riyyi
|
* Copyright (C) 2022,2024 Riyyi
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: MIT
|
* SPDX-License-Identifier: MIT
|
||||||
*/
|
*/
|
||||||
@@ -15,33 +15,88 @@
|
|||||||
|
|
||||||
namespace Inferno {
|
namespace Inferno {
|
||||||
|
|
||||||
|
class Texture2D;
|
||||||
|
class TextureCubemap;
|
||||||
|
|
||||||
class Texture {
|
class Texture {
|
||||||
public:
|
public:
|
||||||
Texture(const std::string& path);
|
|
||||||
Texture(unsigned char* data, uint32_t width, uint32_t height, uint8_t channels = 3);
|
|
||||||
virtual ~Texture();
|
virtual ~Texture();
|
||||||
|
|
||||||
void bind(uint32_t unit = 0) const;
|
enum Type : uint8_t {
|
||||||
void unbind() const;
|
TwoDimensional = 0,
|
||||||
|
Cubemap,
|
||||||
|
};
|
||||||
|
|
||||||
inline std::string path() const { return m_path; }
|
void init(uint32_t width, uint32_t height, uint8_t channels);
|
||||||
inline uint32_t width() const { return m_width; }
|
|
||||||
inline uint32_t height() const { return m_height; }
|
virtual void bind(uint32_t unit = 0) const = 0;
|
||||||
inline uint32_t id() const { return m_id; }
|
virtual void unbind() const = 0;
|
||||||
inline uint32_t internalFormat() const { return m_internalFormat; }
|
|
||||||
inline uint32_t dataFormat() const { return m_dataFormat; }
|
std::string path() const { return m_path; }
|
||||||
|
uint32_t width() const { return m_width; }
|
||||||
|
uint32_t height() const { return m_height; }
|
||||||
|
uint32_t id() const { return m_id; }
|
||||||
|
uint32_t internalFormat() const { return m_internalFormat; }
|
||||||
|
uint32_t dataFormat() const { return m_dataFormat; }
|
||||||
|
|
||||||
|
virtual bool is2D() const { return false; }
|
||||||
|
virtual bool isCubeMap() const { return false; }
|
||||||
|
|
||||||
|
friend Texture2D;
|
||||||
|
friend TextureCubemap;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void init(unsigned char* data, uint32_t width, uint32_t height, uint8_t channels);
|
Texture() {}
|
||||||
void create(unsigned char* data);
|
|
||||||
|
protected:
|
||||||
|
std::string m_path;
|
||||||
|
uint32_t m_width { 0 };
|
||||||
|
uint32_t m_height { 0 };
|
||||||
|
uint32_t m_id { 0 };
|
||||||
|
uint32_t m_internalFormat { 0 };
|
||||||
|
uint32_t m_dataFormat { 0 };
|
||||||
|
};
|
||||||
|
|
||||||
|
// -------------------------------------
|
||||||
|
|
||||||
|
class Texture2D final : public Texture {
|
||||||
|
public:
|
||||||
|
virtual ~Texture2D() = default;
|
||||||
|
|
||||||
|
// Factory function
|
||||||
|
static std::shared_ptr<Texture> create(const std::string& path);
|
||||||
|
|
||||||
|
virtual void bind(uint32_t unit = 0) const override;
|
||||||
|
virtual void unbind() const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::string m_path;
|
Texture2D() {}
|
||||||
uint32_t m_width;
|
|
||||||
uint32_t m_height;
|
virtual bool is2D() const override { return true; }
|
||||||
uint32_t m_id;
|
|
||||||
uint32_t m_internalFormat;
|
private:
|
||||||
uint32_t m_dataFormat;
|
void create(unsigned char* data);
|
||||||
|
};
|
||||||
|
|
||||||
|
// -------------------------------------
|
||||||
|
|
||||||
|
class TextureCubemap final : public Texture {
|
||||||
|
public:
|
||||||
|
virtual ~TextureCubemap() = default;
|
||||||
|
|
||||||
|
// Factory function
|
||||||
|
static std::shared_ptr<Texture> create(const std::string& path);
|
||||||
|
|
||||||
|
virtual void bind(uint32_t unit = 0) const override;
|
||||||
|
virtual void unbind() const override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
TextureCubemap() {};
|
||||||
|
|
||||||
|
virtual bool isCubeMap() const override { return true; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
void create();
|
||||||
};
|
};
|
||||||
|
|
||||||
// -------------------------------------
|
// -------------------------------------
|
||||||
@@ -52,7 +107,7 @@ public:
|
|||||||
~TextureManager();
|
~TextureManager();
|
||||||
|
|
||||||
void add(const std::string& path, std::shared_ptr<Texture> texture);
|
void add(const std::string& path, std::shared_ptr<Texture> texture);
|
||||||
std::shared_ptr<Texture> load(const std::string& path);
|
std::shared_ptr<Texture> load(const std::string& path, Texture::Type type = Texture::Type::TwoDimensional);
|
||||||
std::shared_ptr<Texture> get(const std::string& path);
|
std::shared_ptr<Texture> get(const std::string& path);
|
||||||
bool exists(const std::string& path);
|
bool exists(const std::string& path);
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
#include <cstddef> // size_t
|
#include <cstddef> // size_t
|
||||||
#include <cstdint> // uint32_t
|
#include <cstdint> // uint32_t
|
||||||
#include <limits> // std::numeric_limits
|
#include <limits> // std::numeric_limits
|
||||||
|
#include <utility> // std::pair
|
||||||
|
|
||||||
#include "entt/entity/entity.hpp" // ent::entity
|
#include "entt/entity/entity.hpp" // ent::entity
|
||||||
#include "ruc/file.h"
|
#include "ruc/file.h"
|
||||||
@@ -15,6 +16,7 @@
|
|||||||
#include "ruc/meta/assert.h"
|
#include "ruc/meta/assert.h"
|
||||||
|
|
||||||
#include "inferno/component/cameracomponent.h"
|
#include "inferno/component/cameracomponent.h"
|
||||||
|
#include "inferno/component/cubemap-component.h"
|
||||||
#include "inferno/component/id-component.h"
|
#include "inferno/component/id-component.h"
|
||||||
#include "inferno/component/luascriptcomponent.h"
|
#include "inferno/component/luascriptcomponent.h"
|
||||||
#include "inferno/component/nativescriptcomponent.h"
|
#include "inferno/component/nativescriptcomponent.h"
|
||||||
@@ -156,6 +158,10 @@ uint32_t Scene::loadEntity(ruc::Json components, uint32_t parentEntity)
|
|||||||
auto& sprite = addComponent<SpriteComponent>(entity);
|
auto& sprite = addComponent<SpriteComponent>(entity);
|
||||||
components.at("sprite").getTo(sprite);
|
components.at("sprite").getTo(sprite);
|
||||||
}
|
}
|
||||||
|
if (components.exists("cubemap")) {
|
||||||
|
auto& cubemap = addComponent<CubemapComponent>(entity);
|
||||||
|
components.at("cubemap").getTo(cubemap);
|
||||||
|
}
|
||||||
if (components.exists("text")) {
|
if (components.exists("text")) {
|
||||||
auto& text = addComponent<TextAreaComponent>(entity);
|
auto& text = addComponent<TextAreaComponent>(entity);
|
||||||
components.at("text").getTo(text);
|
components.at("text").getTo(text);
|
||||||
@@ -192,7 +198,7 @@ void Scene::destroyEntity(uint32_t entity)
|
|||||||
|
|
||||||
// -----------------------------------------
|
// -----------------------------------------
|
||||||
|
|
||||||
glm::mat4 Scene::cameraProjectionView()
|
std::pair<glm::mat4, glm::mat4> Scene::cameraProjectionView()
|
||||||
{
|
{
|
||||||
return CameraSystem::the().projectionView();
|
return CameraSystem::the().projectionView();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
#include <cstddef> // size_t
|
#include <cstddef> // size_t
|
||||||
#include <cstdint> // uint32_t
|
#include <cstdint> // uint32_t
|
||||||
#include <memory> // std::shared_ptr
|
#include <memory> // std::shared_ptr
|
||||||
|
#include <utility> // std::pair
|
||||||
|
|
||||||
#include "entt/entity/registry.hpp" // entt::entity, entt::registry
|
#include "entt/entity/registry.hpp" // entt::entity, entt::registry
|
||||||
#include "glm/ext/matrix_float4x4.hpp" // glm::mat4
|
#include "glm/ext/matrix_float4x4.hpp" // glm::mat4
|
||||||
@@ -35,7 +36,10 @@ public:
|
|||||||
uint32_t findEntity(std::string_view name);
|
uint32_t findEntity(std::string_view name);
|
||||||
void destroyEntity(uint32_t entity);
|
void destroyEntity(uint32_t entity);
|
||||||
|
|
||||||
glm::mat4 cameraProjectionView();
|
/**
|
||||||
|
* @brief Return a pair from the camera component: { projection, view }
|
||||||
|
*/
|
||||||
|
std::pair<glm::mat4, glm::mat4> cameraProjectionView();
|
||||||
|
|
||||||
void validEntity(uint32_t entity) const;
|
void validEntity(uint32_t entity) const;
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2022 Riyyi
|
* Copyright (C) 2022,2024 Riyyi
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: MIT
|
* SPDX-License-Identifier: MIT
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <utility> // std::pair
|
||||||
|
|
||||||
#include "glm/ext/matrix_clip_space.hpp" // glm::perspective, glm::ortho
|
#include "glm/ext/matrix_clip_space.hpp" // glm::perspective, glm::ortho
|
||||||
#include "glm/ext/matrix_transform.hpp" // glm::radians, glm::lookAt
|
#include "glm/ext/matrix_transform.hpp" // glm::radians, glm::lookAt
|
||||||
#include "ruc/format/log.h"
|
#include "ruc/format/log.h"
|
||||||
@@ -42,17 +44,17 @@ void CameraSystem::update()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
glm::mat4 CameraSystem::projectionView()
|
std::pair<glm::mat4, glm::mat4> CameraSystem::projectionView()
|
||||||
{
|
{
|
||||||
auto view = m_registry->view<TransformComponent, CameraComponent>();
|
auto view = m_registry->view<TransformComponent, CameraComponent>();
|
||||||
|
|
||||||
for (auto [entity, transform, camera] : view.each()) {
|
for (auto [entity, transform, camera] : view.each()) {
|
||||||
return camera.projection * transform.transform;
|
return { camera.projection, transform.transform };
|
||||||
}
|
}
|
||||||
|
|
||||||
VERIFY_NOT_REACHED();
|
VERIFY_NOT_REACHED();
|
||||||
|
|
||||||
return glm::mat4 { 1.0f };
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
void CameraSystem::updateOrthographic(TransformComponent& transform, CameraComponent& camera)
|
void CameraSystem::updateOrthographic(TransformComponent& transform, CameraComponent& camera)
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2022 Riyyi
|
* Copyright (C) 2022,2024 Riyyi
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: MIT
|
* SPDX-License-Identifier: MIT
|
||||||
*/
|
*/
|
||||||
@@ -7,6 +7,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <memory> //std::shared_ptr
|
#include <memory> //std::shared_ptr
|
||||||
|
#include <utility> // std::pair
|
||||||
|
|
||||||
#include "entt/entity/registry.hpp" // entt::entity, entt::registry
|
#include "entt/entity/registry.hpp" // entt::entity, entt::registry
|
||||||
#include "glm/ext/matrix_float4x4.hpp" // glm::mat4
|
#include "glm/ext/matrix_float4x4.hpp" // glm::mat4
|
||||||
@@ -27,7 +28,10 @@ public:
|
|||||||
|
|
||||||
void update();
|
void update();
|
||||||
|
|
||||||
glm::mat4 projectionView();
|
/**
|
||||||
|
* @brief Return a pair from the camera component: { projection, view }
|
||||||
|
*/
|
||||||
|
std::pair<glm::mat4, glm::mat4> projectionView();
|
||||||
|
|
||||||
void setRegistry(std::shared_ptr<entt::registry> registry) { m_registry = registry; };
|
void setRegistry(std::shared_ptr<entt::registry> registry) { m_registry = registry; };
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2022 Riyyi
|
* Copyright (C) 2022,2024 Riyyi
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: MIT
|
* SPDX-License-Identifier: MIT
|
||||||
*/
|
*/
|
||||||
@@ -7,6 +7,7 @@
|
|||||||
#include "glm/ext/matrix_transform.hpp" // glm::translate, glm::rotate, glm::scale, glm::radians
|
#include "glm/ext/matrix_transform.hpp" // glm::translate, glm::rotate, glm::scale, glm::radians
|
||||||
#include "ruc/format/log.h"
|
#include "ruc/format/log.h"
|
||||||
|
|
||||||
|
#include "inferno/component/cubemap-component.h"
|
||||||
#include "inferno/component/spritecomponent.h"
|
#include "inferno/component/spritecomponent.h"
|
||||||
#include "inferno/component/transformcomponent.h"
|
#include "inferno/component/transformcomponent.h"
|
||||||
#include "inferno/render/renderer.h"
|
#include "inferno/render/renderer.h"
|
||||||
@@ -25,11 +26,17 @@ RenderSystem::~RenderSystem()
|
|||||||
|
|
||||||
void RenderSystem::render()
|
void RenderSystem::render()
|
||||||
{
|
{
|
||||||
auto group = m_registry->group<TransformComponent, SpriteComponent>();
|
auto quadView = m_registry->view<TransformComponent, SpriteComponent>();
|
||||||
|
|
||||||
for (auto [entity, transform, sprite] : group.each()) {
|
for (auto [entity, transform, sprite] : quadView.each()) {
|
||||||
Renderer2D::the().drawQuad(transform, sprite.color, sprite.texture);
|
Renderer2D::the().drawQuad(transform, sprite.color, sprite.texture);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto cubemapView = m_registry->view<TransformComponent, CubemapComponent>();
|
||||||
|
|
||||||
|
for (auto [entity, transform, cubemap] : cubemapView.each()) {
|
||||||
|
RendererCubemap::the().drawCubemap(transform, cubemap.color, cubemap.texture);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Inferno
|
} // namespace Inferno
|
||||||
|
|||||||
Reference in New Issue
Block a user