Engine update

This commit is contained in:
2026-02-26 14:46:29 +03:00
parent fcba7d9035
commit 2539ceee03
33 changed files with 1677 additions and 180 deletions

View File

@@ -21,7 +21,7 @@ static InputLayoutDesc_t g_debugRenderLayout[] =
bool g_drawDebug = true;
DebugRender* g_pDebugRender;
DebugRender* g_debugRender;
DebugRender::DebugRender()
{
@@ -38,11 +38,11 @@ DebugRender::~DebugRender()
void DebugRender::Initialize()
{
//float points[12];
//m_verticesBuffer = g_pRenderDevice->CreateVertexBuffer(points, sizeof(points), true);
//m_verticesBuffer = g_renderDevice->CreateVertexBuffer(points, sizeof(points), true);
m_verticesBuffer = g_pRenderDevice->CreateVertexBuffer(NULL, kMaxDebugVBSize, true);
m_verticesBuffer = g_renderDevice->CreateVertexBuffer(NULL, kMaxDebugVBSize, true);
m_shader = g_pShaderSystem->CreateShader("debug_draw",
m_shader = g_shaderSystem->CreateShader("debug_draw",
"data/shaders/debug_draw.vs",
"data/shaders/debug_draw.ps",
g_debugRenderLayout,
@@ -120,26 +120,26 @@ void DebugRender::DrawLinesInternal()
if (m_lines.empty())
return;
g_pRenderDevice->SetDepthTest(true);
g_pRenderDevice->SetDepthWrite(true);
g_renderDevice->SetDepthTest(true);
g_renderDevice->SetDepthWrite(true);
g_pRenderDevice->SetVerticesBuffer(m_verticesBuffer);
g_renderDevice->SetVerticesBuffer(m_verticesBuffer);
m_verticesBuffer->UpdateBuffer(m_lines.data(), m_lines.size() * sizeof(Line));
// Bind our shader
g_pShaderSystem->SetShader(m_shader);
g_shaderSystem->SetShader(m_shader);
// #TODO: Fix stupid bug, when we get very far from wireframe and lines can start cliping
glm::mat4 proj = g_pRender->GetProjectionMatrix();
glm::mat4 view = g_pRender->GetViewMatrix();
glm::mat4 proj = g_render->GetProjectionMatrix();
glm::mat4 view = g_render->GetViewMatrix();
proj[2][3] -= 0.0001f;
glm::mat4 mv = glm::mat4(1.0f);
mv = proj * view;
g_pShaderSystem->SetUniformMatrix(m_shader, UNIFORM_MVP_MATRIX, &mv[0]);
g_shaderSystem->SetUniformMatrix(m_shader, UNIFORM_MVP_MATRIX, &mv[0]);
// draw stuff
g_pRenderDevice->DrawArrays(PT_LINES, 0, m_lines.size() * 2);
g_renderDevice->DrawArrays(PT_LINES, 0, m_lines.size() * 2);
}

View File

@@ -48,7 +48,7 @@ private:
Shader* m_shader;
};
extern DebugRender* g_pDebugRender;
extern DebugRender* g_debugRender;
extern bool g_drawDebug;

View File

@@ -17,7 +17,7 @@ void ImGuiManager::Init()
// Initialize backend
ImGui_ImplSDL3_InitForOpenGL(GetEngine()->GetWindow(), g_pRender->GetGLContext());
ImGui_ImplSDL3_InitForOpenGL(GetEngine()->GetWindow(), g_render->GetGLContext());
ImGui_ImplOpenGL3_Init();

View File

@@ -11,7 +11,7 @@
#include "modelsystem.h"
#include "texturesmanager.h"
ModelSystem* g_pModelSystem = nullptr;
ModelSystem* g_modelSystem = nullptr;
static InputLayoutDesc_t g_staticVertexLayout[] = {
{ VERTEXATTR_VEC3, SHADERSEMANTIC_POSITION },
@@ -45,6 +45,13 @@ ModelSystem::~ModelSystem()
{
}
void ModelSystem::Init()
{
// Load model generic shader
g_litShader = g_shaderSystem->CreateShader("lit_generic", "data/shaders/lit_generic.vs", "data/shaders/lit_generic.ps",
g_staticVertexLayout, sizeof(g_staticVertexLayout) / sizeof(g_staticVertexLayout[0]));
}
void ModelSystem::Shutdown()
{
for (int i = 0; i < m_models.size(); i++)
@@ -255,7 +262,7 @@ void Model::LoadObj(const char* filename)
m_Vertices = vertices;
m_data.vb = g_pRenderDevice->CreateVertexBuffer(vertices.data(), (int)sizeof(StaticMeshVertex) * (int)vertices.size());
m_data.vb = g_renderDevice->CreateVertexBuffer(vertices.data(), (int)sizeof(StaticMeshVertex) * (int)vertices.size());
m_data.vbcount = vertices.size();
std::string mtlfilename = getFileNameWithoutExtension(filename);
@@ -286,7 +293,7 @@ void Model::LoadMtl(const char* filename)
fgets(stupidBuffer, 1000, file);
const char* textureFilename = stupidBuffer + 1;
m_AlbedoTexture = g_pTexturesManager->LoadTexture2D(textureFilename, true);
m_AlbedoTexture = g_texturesManager->LoadTexture2D(textureFilename, true);
}
//if (strcmp(lineHeader, "v") == 0) {
@@ -307,40 +314,36 @@ void Model::LoadMtl(const char* filename)
void Model::Draw(const glm::mat4& model, bool isTransparent /*= false*/)
{
if (!g_litShader)
{
g_litShader = g_pShaderSystem->CreateShader("lit_generic", "data/shaders/lit_generic.vs", "data/shaders/lit_generic.ps",
g_staticVertexLayout, sizeof(g_staticVertexLayout) / sizeof(g_staticVertexLayout[0]));
}
SDL_assert(g_litShader);
glFrontFace(GL_CCW);
glDepthFunc(GL_LESS);
g_pRenderDevice->SetCullFace(true);
g_pRenderDevice->SetDepthTest(true);
g_pRenderDevice->SetDepthWrite(true);
g_renderDevice->SetCullFace(true);
g_renderDevice->SetDepthTest(true);
g_renderDevice->SetDepthWrite(true);
if (isTransparent)
{
// Enable blending
g_pRenderDevice->SetBlending(true);
g_pRenderDevice->SetBlendingFunction(BF_SRC_ALPHA, BF_ONE_MINUS_SRC_ALPHA);
g_renderDevice->SetBlending(true);
g_renderDevice->SetBlendingFunction(BF_SRC_ALPHA, BF_ONE_MINUS_SRC_ALPHA);
glm::vec4 color = glm::vec4(1.f, 1.f, 1.f, .5f);
g_pShaderSystem->SetUniformFloat4(g_litShader, UNIFORM_CUSTOM_COLOR, glm::value_ptr(color));
g_shaderSystem->SetUniformFloat4(g_litShader, UNIFORM_CUSTOM_COLOR, glm::value_ptr(color));
}
else
{
g_pRenderDevice->SetBlending(false);
g_renderDevice->SetBlending(false);
//glm::vec4 color = glm::vec4(1.f, 1.f, 1.f, 1.f);
//g_pShaderSystem->SetUniformFloat4(g_litShader, UNIFORM_CUSTOM_COLOR, glm::value_ptr(color));
//g_shaderSystem->SetUniformFloat4(g_litShader, UNIFORM_CUSTOM_COLOR, glm::value_ptr(color));
}
g_pRenderDevice->SetVerticesBuffer(m_data.vb);
g_renderDevice->SetVerticesBuffer(m_data.vb);
g_pShaderSystem->SetShader(g_litShader);
g_pShaderSystem->SetUniformMatrix(g_litShader, UNIFORM_MODEL_MATRIX, &model[0]);
g_shaderSystem->SetShader(g_litShader);
g_shaderSystem->SetUniformMatrix(g_litShader, UNIFORM_MODEL_MATRIX, &model[0]);
//static float test = 0.0f;
//test += g_systemTimer->GetDelta() * 6.0f;
@@ -367,27 +370,27 @@ void Model::Draw(const glm::mat4& model, bool isTransparent /*= false*/)
//model = glm::translate(model, pos);
glm::mat4 mvp = glm::identity<glm::mat4>();
mvp = g_pRender->GetProjectionMatrix() * g_pRender->GetViewMatrix() * model;
g_pShaderSystem->SetUniformMatrix(g_litShader, UNIFORM_MVP_MATRIX, &mvp[0]);
mvp = g_render->GetProjectionMatrix() * g_render->GetViewMatrix() * model;
g_shaderSystem->SetUniformMatrix(g_litShader, UNIFORM_MVP_MATRIX, &mvp[0]);
g_pTexturesManager->SetTexture(0, m_AlbedoTexture);
g_pShaderSystem->SetUniformSampler(g_litShader, SAMPLER_ALBEDO, 0);
g_texturesManager->SetTexture(0, m_AlbedoTexture);
g_shaderSystem->SetUniformSampler(g_litShader, SAMPLER_ALBEDO, 0);
g_pRenderDevice->DrawArrays(PT_TRIANGLES, 0, m_data.vbcount);
g_renderDevice->DrawArrays(PT_TRIANGLES, 0, m_data.vbcount);
#if 0
glm::mat4 mvp = glm::identity<glm::mat4>();
mvp = g_renderView.proj * g_renderView.view * model;
g_shaderSystem->SetUniformMatrix(g_litShader, UNIFORM_MVP_MATRIX, &mvp[0]);
g_pTexturesManager->SetTexture(0, m_AlbedoTexture);
g_texturesManager->SetTexture(0, m_AlbedoTexture);
g_shaderSystem->SetUniformSampler(g_litShader, SAMPLER_ALBEDO, 0);
g_renderDevice->DrawArrays(PT_TRIANGLES, 0, m_data.vbcount);
BoundingBox bbox = m_boundingBox;
TransformBoundingBox(bbox, model);
g_pDebugRender->DrawBoundingBox(bbox, glm::vec3(1.0f));
g_debugRender->DrawBoundingBox(bbox, glm::vec3(1.0f));
#endif
}

View File

@@ -51,6 +51,7 @@ public:
ModelSystem();
~ModelSystem();
void Init();
void Shutdown();
Model* LoadModel(const char* filename);
@@ -66,6 +67,6 @@ private:
};
extern ModelSystem* g_pModelSystem;
extern ModelSystem* g_modelSystem;
#endif // !MODELMANAGER_H

View File

@@ -9,8 +9,7 @@
#include "ifilesystem.h"
#include "camera.h"
#include "imguimanager.h"
#include <pugixml.hpp>
#include "scenemanager.h"
static GLuint g_VAO = 0;
@@ -66,17 +65,16 @@ void APIENTRY GL_DebugOutput(GLenum source,
}
}
Render* g_pRender = nullptr;
Render* g_render = nullptr;
Render::Render() :
m_pWindow(nullptr),
m_pGLContext(nullptr),
m_pStretchedPicVBuf(nullptr),
m_sceneModel(nullptr),
m_bUsingVAO(false)
m_usingVAO(false)
{
m_ViewMatrix = glm::identity<glm::mat4>();
m_ProjectionMatrix = glm::identity<glm::mat4>();
m_viewMatrix = glm::identity<glm::mat4>();
m_projectionMatrix = glm::identity<glm::mat4>();
}
Render::~Render()
@@ -101,7 +99,7 @@ void Render::Init(SDL_Window* pWindow)
// Core profile probably, should use VAO
if (GLVersion.major >= 3 && GLVersion.minor >= 1)
m_bUsingVAO = true;
m_usingVAO = true;
Msg("%s", (const char*)glGetString(GL_VENDOR));
Msg("%s", (const char*)glGetString(GL_RENDERER));
@@ -126,31 +124,35 @@ void Render::Init(SDL_Window* pWindow)
// Create render device
g_pRenderDevice = new RenderDevice();
g_renderDevice = new RenderDevice();
// Create texture manager
g_pTexturesManager = new TexturesManager();
g_pTexturesManager->Init();
g_texturesManager = new TexturesManager();
g_texturesManager->Init();
// Create shader system
g_pShaderSystem = new ShaderSystem();
g_pShaderSystem->Init();
g_shaderSystem = new ShaderSystem();
g_shaderSystem->Init();
// Create model system
g_pModelSystem = new ModelSystem();
g_modelSystem = new ModelSystem();
g_modelSystem->Init();
// Create scene manager
g_sceneManager = new SceneManager();
// Create debug render
g_pDebugRender = new DebugRender();
g_pDebugRender->Initialize();
g_debugRender = new DebugRender();
g_debugRender->Initialize();
// Create imgui manager
g_ImGuiManager.Init();
// Create stretched picture filenameBuffer
m_pStretchedPicVBuf = g_pRenderDevice->CreateVertexBuffer(nullptr, MAX_STRETCH_VX, true);
m_pStretchedPicVBuf = g_renderDevice->CreateVertexBuffer(nullptr, MAX_STRETCH_VX, true);
// Core profile require Vertex Array Object to render
if (m_bUsingVAO)
if (m_usingVAO)
{
// Create global vertex array
glGenVertexArrays(1, &g_VAO);
@@ -160,7 +162,7 @@ void Render::Init(SDL_Window* pWindow)
void Render::Shutdown()
{
if (m_bUsingVAO)
if (m_usingVAO)
{
glBindVertexArray(0);
glDeleteVertexArrays(1, &g_VAO);
@@ -171,24 +173,27 @@ void Render::Shutdown()
g_ImGuiManager.Shutdown();
g_pDebugRender->Shutdown();
delete g_pDebugRender;
g_pDebugRender = nullptr;
g_debugRender->Shutdown();
delete g_debugRender;
g_debugRender = nullptr;
g_pModelSystem->Shutdown();
delete g_pModelSystem;
g_pModelSystem = nullptr;
delete g_sceneManager;
g_sceneManager = nullptr;
g_pShaderSystem->Shutdown();
delete g_pShaderSystem;
g_pShaderSystem = nullptr;
g_modelSystem->Shutdown();
delete g_modelSystem;
g_modelSystem = nullptr;
g_pTexturesManager->Shutdown();
delete g_pTexturesManager;
g_pTexturesManager = nullptr;
g_shaderSystem->Shutdown();
delete g_shaderSystem;
g_shaderSystem = nullptr;
delete g_pRenderDevice;
g_pRenderDevice = nullptr;
g_texturesManager->Shutdown();
delete g_texturesManager;
g_texturesManager = nullptr;
delete g_renderDevice;
g_renderDevice = nullptr;
// Destroy OpenGL context
SDL_GL_MakeCurrent(nullptr, nullptr);
@@ -197,35 +202,40 @@ void Render::Shutdown()
}
void Render::RenderScene() {
if (m_sceneModel) {
Camera* camera = g_cameraManager.GetActiveCamera();
if (camera) {
glm::mat4 viewProj = m_ProjectionMatrix * m_ViewMatrix;
viewProj = glm::transpose(viewProj);
//if (m_sceneModel) {
// Camera* camera = g_cameraManager.GetActiveCamera();
// if (camera) {
// glm::mat4 viewProj = m_projectionMatrix * m_viewMatrix;
// viewProj = glm::transpose(viewProj);
camera->GetFrustum().Build(viewProj);
// camera->GetFrustum().Build(viewProj);
if (camera->GetFrustum().CullBoundingBox(m_sceneModel->GetBoundingBox()))
return;
}
// if (camera->GetFrustum().CullBoundingBox(m_sceneModel->GetBoundingBox()))
// return;
// }
static glm::mat4 s_identity = glm::mat4(1.0f);
m_sceneModel->Draw(s_identity);
// static glm::mat4 s_identity = glm::mat4(1.0f);
// m_sceneModel->Draw(s_identity);
g_NumModels++;
g_pDebugRender->DrawBoundingBox(m_sceneModel->GetBoundingBox(), glm::vec3(1.0f));
}
// g_NumModels++;
//
// g_debugRender->DrawBoundingBox(m_sceneModel->GetBoundingBox(), glm::vec3(1.0f));
//}
g_pDebugRender->RenderFrame();
static glm::mat4 s_identity = glm::mat4(1.0f);
if (g_sceneManager->isSceneLoaded())
g_sceneManager->renderScene(s_identity);
g_debugRender->RenderFrame();
}
void Render::RenderStats()
{
char buffer[256];
snprintf(buffer, sizeof(buffer), "Scene: %s", m_sceneName.c_str());
snprintf(buffer, sizeof(buffer), "Scene: %s", g_sceneManager->getSceneName());
ImGui::GetForegroundDrawList()->AddText(ImVec2(0.0f, 0.0f), 0xffffffff, buffer);
snprintf(buffer, sizeof(buffer), "numModels: %d", g_NumModels);
ImGui::GetForegroundDrawList()->AddText(ImVec2(0.0f, 15.0f), 0xffffffff, buffer);
}
@@ -240,65 +250,30 @@ void Render::Present(bool vsync)
void Render::ResetStates()
{
g_pRenderDevice->SetDepthTest(true);
g_pRenderDevice->SetDepthWrite(true);
g_pRenderDevice->SetStencilTest(false);
g_pRenderDevice->SetScissorTest(false);
g_pRenderDevice->SetCullFace(false);
g_pRenderDevice->SetBlending(false);
g_renderDevice->SetDepthTest(true);
g_renderDevice->SetDepthWrite(true);
g_renderDevice->SetStencilTest(false);
g_renderDevice->SetScissorTest(false);
g_renderDevice->SetCullFace(false);
g_renderDevice->SetBlending(false);
}
void Render::SetViewMatrix(const glm::mat4& matView)
{
m_ViewMatrix = matView;
m_viewMatrix = matView;
}
void Render::SetProjectionMatrix(const glm::mat4& matProjection)
{
m_ProjectionMatrix = matProjection;
m_projectionMatrix = matProjection;
}
void Render::LoadSceneXML(const char* filename)
{
char filenameBuffer[kMaxPathLength];
snprintf(filenameBuffer, kMaxPathLength, "data/levels/%s/%s.xml", filename, filename);
FileHandle_t file = GetFileSystem()->OpenFile(filenameBuffer, "rb");
SDL_assert_always(file != kInvalidFileHandleValue);
size_t length = GetFileSystem()->GetFileLength(file);
char* filedata = new char[length + 1];
GetFileSystem()->ReadFile(file, filedata, length);
filedata[length] = '\0';
GetFileSystem()->CloseFile(file);
pugi::xml_document doc;
pugi::xml_parse_result result = doc.load_buffer(filedata, length);
delete[] filedata;
if (!result) {
Core::Error("SceneManager::LoadScene: Error while reading level description file '%s'\nError: %s:%i",
filenameBuffer, result.description(), result.offset);
}
pugi::xml_node root = doc.document_element();
const char* scenefilename = root.child("SceneFile").attribute("filename").value();
m_sceneName = scenefilename;
sprintf(filenameBuffer, "data/levels/%s/%s", filename, scenefilename);
if (!GetFileSystem()->IsExist(filenameBuffer)) {
Core::Error("SceneManager::LoadScene: scene file '%s' doesnt exist", scenefilename);
}
m_sceneFilename = filenameBuffer;
m_sceneModel = g_pModelSystem->LoadModel(m_sceneFilename.c_str());
g_sceneManager->loadScene(filename);
}
//IRender* GetRender()
//{
// return g_pRender;
// return g_render;
//}

View File

@@ -28,31 +28,26 @@ public:
void SetViewMatrix(const glm::mat4& matView);
void SetProjectionMatrix(const glm::mat4& matProjection);
inline const glm::mat4& GetViewMatrix() { return m_ViewMatrix; }
inline const glm::mat4& GetProjectionMatrix() { return m_ProjectionMatrix; }
inline const glm::mat4& GetViewMatrix() { return m_viewMatrix; }
inline const glm::mat4& GetProjectionMatrix() { return m_projectionMatrix; }
void LoadSceneXML(const char* filename);
SDL_GLContext GetGLContext() { return m_pGLContext; }
private:
glm::mat4 m_ViewMatrix;
glm::mat4 m_ProjectionMatrix;
glm::mat4 m_viewMatrix;
glm::mat4 m_projectionMatrix;
SDL_Window* m_pWindow;
SDL_GLContext m_pGLContext;
GPUBuffer* m_pStretchedPicVBuf;
std::string m_sceneFilename;
std::string m_sceneName;
Model* m_sceneModel;
bool m_bUsingVAO;
bool m_usingVAO;
};
extern Render* g_pRender;
extern Render* g_render;
// TEMP
extern glm::vec3 g_viewOrigin;

View File

@@ -14,7 +14,7 @@ static GLenum g_glPrimitiveMode[PT_TRIANGLES + 1] = {
};
// The render device instance.
RenderDevice* g_pRenderDevice = nullptr;
RenderDevice* g_renderDevice = nullptr;
RenderDevice::RenderDevice()
{

View File

@@ -54,6 +54,6 @@ private:
BlendFactor m_destBlendFactor;
};
extern RenderDevice* g_pRenderDevice;
extern RenderDevice* g_renderDevice;
#endif // !RENDERDEVICE_H

676
src/render/scenemanager.cpp Normal file
View File

@@ -0,0 +1,676 @@
#include "engine/core.h"
#include "engine/log.h"
#include "engine/ifilesystem.h"
#include "engine/camera.h"
#include "render/texturesmanager.h"
#include "render/modelsystem.h"
#include "render/scenemanager.h"
#include "render/renderdevice.h"
#include "render/gl_shared.h"
#include "render/texture2d.h"
#include "render/shader.h"
#include "render/shadersystem.h"
#include "render/render.h"
#include "render/debugrender.h"
#include <pugixml.hpp>
static std::string getFileExtension(const std::string& filename)
{
size_t whereIsDot = filename.find_last_of('.');
if (whereIsDot != std::string::npos) {
return filename.substr(whereIsDot);
}
return "";
}
static std::string getFileNameWithoutExtension(const std::string& filename)
{
size_t lastindex = filename.find_last_of(".");
if (lastindex != std::string::npos) {
return filename.substr(0, lastindex);
}
return filename;
}
static std::string getFilenameWithoutPathAndExtension(const std::string& filename)
{
size_t whereIsDot = filename.find_last_of('.');
size_t whereIsSlash = filename.find_last_of('/');
if (whereIsSlash == std::string::npos) {
whereIsSlash = filename.find_last_of('\\');
}
if (whereIsDot == std::string::npos && whereIsSlash == std::string::npos) {
return filename;
}
std::string string = filename.substr(whereIsSlash + 1);
whereIsDot = string.find_last_of('.');
string = string.substr(0, whereIsDot);
return string;
}
//#ifdef NDEBUG
//#pragma comment(lib, "assimp-vc141-mt.lib")
//#else
//#pragma comment(lib, "assimp-vc141-mtd.lib")
//#endif // NDEBUG
//
//inline static glm::mat4 Assimp2Glm(const aiMatrix4x4& from)
//{
// return glm::mat4(
// (double)from.a1, (double)from.b1, (double)from.c1, (double)from.d1,
// (double)from.a2, (double)from.b2, (double)from.c2, (double)from.d2,
// (double)from.a3, (double)from.b3, (double)from.c3, (double)from.d3,
// (double)from.a4, (double)from.b4, (double)from.c4, (double)from.d4
// );
//}
//
//SceneStaticMesh* createSceneStaticMesh(const aiScene* scene, aiMesh* mesh)
//{
// assert(scene);
// assert(mesh);
// //assert(mesh->mPrimitiveTypes == aiPrimitiveType_TRIANGLE);
//
// std::vector<SceneStaticMeshVertex> vertices;
// std::vector<uint32_t> indices;
//
// // reserve 1024 vertices and indices
// vertices.reserve(1024);
// indices.reserve(1024);
//
// for (uint32_t i = 0; i < mesh->mNumVertices; i++) {
// SceneStaticMeshVertex vertex;
//
// // position
// aiVector3D position = mesh->mVertices[i];
// vertex.m_position.x = position.x;
// vertex.m_position.y = position.y;
// vertex.m_position.z = position.z;
//
// // normal
// aiVector3D normal = mesh->mNormals[i];
// vertex.m_normal.x = normal.x;
// vertex.m_normal.y = normal.y;
// vertex.m_normal.z = normal.z;
//
// static bool inverseTexCoords = true;
//
// if (inverseTexCoords) {
// // texture coord 0 ( DIFFUSE )
// if (mesh->mTextureCoords[0]) {
// vertex.m_texcoord1.x = mesh->mTextureCoords[0][i].x;
// vertex.m_texcoord1.y = mesh->mTextureCoords[0][i].y;
// }
// else {
// vertex.m_texcoord1 = glm::vec2(0.0f, 0.0f);
// }
//
// // texture coord 1 ( LIGHTMAP )
// if (mesh->mTextureCoords[1]) {
// vertex.m_texcoord0.x = mesh->mTextureCoords[1][i].x;
// vertex.m_texcoord0.y = mesh->mTextureCoords[1][i].y;
// }
// else {
// vertex.m_texcoord0 = glm::vec2(0.0f, 0.0f);
// }
// }
// else {
// // texture coord 0 ( DIFFUSE )
// if (mesh->mTextureCoords[0]) {
// vertex.m_texcoord0.x = mesh->mTextureCoords[0][i].x;
// vertex.m_texcoord0.y = mesh->mTextureCoords[0][i].y;
// }
// else {
// vertex.m_texcoord0 = glm::vec2(0.0f, 0.0f);
// }
//
// // texture coord 0 ( LIGHTMAP )
// if (mesh->mTextureCoords[1]) {
// vertex.m_texcoord1.x = mesh->mTextureCoords[1][i].x;
// vertex.m_texcoord1.y = mesh->mTextureCoords[1][i].y;
// }
// else {
// vertex.m_texcoord1 = glm::vec2(0.0f, 0.0f);
// }
// }
//
// vertices.push_back(vertex);
// }
//
// for (uint32_t i = 0; i < mesh->mNumFaces; i++) {
// aiFace face = mesh->mFaces[i];
// for (uint32_t j = 0; j < face.mNumIndices; j++)
// indices.push_back(face.mIndices[j]);
// }
//
// aiMaterial* assImpMaterial = scene->mMaterials[mesh->mMaterialIndex];
// aiString diffusePath;
// assImpMaterial->GetTexture(aiTextureType_DIFFUSE, 0, &diffusePath);
//
// if (strlen(diffusePath.C_Str()) == 0) {
// Logger::msg("Scene mesh '%s' has assImpMaterial, but diffuse texture is not specified.", mesh->mName.C_Str());
// }
//
// Material* material = g_materialsManager->createMaterial("default_lightmap", diffusePath.C_Str());
//
// glm::mat4 transform = glm::identity<glm::mat4>();
//
// return new SceneStaticMesh(vertices, indices, material, transform);
//}
SceneManager* g_sceneManager;
SceneManager::SceneManager()
{
m_sceneLoaded = false;
}
SceneManager::~SceneManager()
{
m_sceneLoaded = false;
}
void SceneManager::loadScene(const char* filename)
{
char filenameBuffer[kMaxPathLength];
snprintf(filenameBuffer, kMaxPathLength, "data/levels/%s/%s.xml", filename, filename);
FileHandle_t file = GetFileSystem()->OpenFile(filenameBuffer, "rb");
SDL_assert_always(file != kInvalidFileHandleValue);
size_t length = GetFileSystem()->GetFileLength(file);
char* filedata = new char[length + 1];
GetFileSystem()->ReadFile(file, filedata, length);
filedata[length] = '\0';
GetFileSystem()->CloseFile(file);
pugi::xml_document doc;
pugi::xml_parse_result result = doc.load_buffer(filedata, length);
delete[] filedata;
if (!result) {
Core::Error("SceneManager::LoadScene: Error while reading level description file '%s'\nError: %s:%i",
filenameBuffer, result.description(), result.offset);
}
pugi::xml_node root = doc.document_element();
const char* scenefilename = root.child("SceneFile").attribute("filename").value();
m_sceneName = getFileNameWithoutExtension(scenefilename);
sprintf(filenameBuffer, "data/levels/%s/%s", filename, scenefilename);
if (!GetFileSystem()->IsExist(filenameBuffer)) {
Core::Error("SceneManager::LoadScene: scene file '%s' doesnt exist", scenefilename);
}
m_sceneFilename = filenameBuffer;
if (getFileExtension(m_sceneFilename) == ".scene") {
LoadSceneXML(m_sceneFilename.c_str());
}
Logger::Msg("loaded %u meshes", m_sceneMeshes.size());
m_sceneLoaded = true;
}
void SceneManager::LoadSceneXML(const char* filename)
{
FileHandle_t file = GetFileSystem()->OpenFile(filename, "rb");
SDL_assert_always(file != kInvalidFileHandleValue);
size_t length = GetFileSystem()->GetFileLength(file);
char* filedata = new char[length + 1];
GetFileSystem()->ReadFile(file, filedata, length);
filedata[length] = '\0';
GetFileSystem()->CloseFile(file);
pugi::xml_document doc;
pugi::xml_parse_result result = doc.load_buffer(filedata, length);
delete[] filedata;
if (!result) {
Core::Error("SceneManager::LoadSceneXML: Error while reading level description file '%s'\nError: %s:%i",
filename, result.description(), result.offset);
}
for (pugi::xml_node staticMesh : doc.child("Scene").children("StaticMesh")) {
const char* meshfilename = staticMesh.attribute("filename").as_string();
if (meshfilename)
loadStaticMesh(meshfilename);
}
}
//void SceneManager::loadScene(const char* sceneName)
//{
// if (sceneName)
// m_sceneName = getFileNameWithoutExtension(sceneName);
//
// if (!m_sceneName.size())
// Core::Error("Scene::loadScene: Scene file is empty, check the 'SceneFile' attribute in level description.");
//
// m_sceneFilename = "data/levels/" + std::string(sceneName) + "/" + std::string(sceneName) + ".scene.xml";
//
// if (!GetFileSystem()->IsExist(m_sceneFilename.c_str()))
// Core::Error("Scene::loadScene: scene file '%s' doesnt exist", m_sceneFilename.c_str());
//
// Logger::Msg("loading scene %s", m_sceneFilename.c_str());
//
// loadStaticMeshes();
//
// // Load lightmap
//// m_lightmap = g_texturesManager->createTexture2D("**");
//
// //if (!scene->HasTextures()) {
// // Core::error("Scene::loadScene: scene '%s' doesnt have textures. Please check assImpMaterial parameters!", scenefilename);
// //}
//
// m_sceneLoaded = true;
//}
void SceneManager::loadSkybox(const char* skybox)
{
if (skybox && *skybox && strcmp(skybox, "none"))
m_pSkybox = g_modelSystem->LoadModel(skybox);
}
void SceneManager::loadStaticMeshes()
{
//File* file = g_fileManager->openFile(m_sceneFilename.c_str(), FileAccess::Read);
//file->seek(SeekDir::End, 0);
//size_t length = file->tell();
//file->seek(SeekDir::Begin, 0);
//char* filedata = new char[length + 1];
//file->read(filedata, length);
//filedata[length] = '\0';
//g_fileManager->closeFile(file);
//Assimp::Importer importer;
//const aiScene* scene = importer.ReadFileFromMemory(filedata, length,
// aiProcessPreset_TargetRealtime_Quality | // some optimizations and safety checks
// aiProcess_OptimizeMeshes | // minimize number of meshes
// aiProcess_PreTransformVertices | // apply node matrices
// // aiProcess_Triangulate |
// aiProcess_SplitLargeMeshes |
// aiProcess_TransformUVCoords /*|*/ // apply UV transformations
///*aiProcess_FlipUVs*/);
//delete[] filedata;
//if (!scene || scene->mFlags & AI_SCENE_FLAGS_INCOMPLETE || !scene->mRootNode) {
// Core::error("Scene::loadScene: failed to load scene '%s'.\n%s", m_sceneName, importer.GetErrorString());
//}
//if (scene && !scene->HasMaterials()) {
// Core::error("Scene::loadScene: scene '%s' doesnt have materials. Please check export parameters!", m_sceneName);
//}
//Logger::msg("loaded %u meshes", scene->mNumMeshes);
//for (unsigned int i = 0; i < scene->mNumMeshes; i++) {
// m_sceneMeshes.push_back(createSceneStaticMesh(scene, scene->mMeshes[i]));
//}
}
void SceneManager::loadStaticMesh(const char* filename)
{
char filenamebuf[kMaxPathLength];
snprintf(filenamebuf, kMaxPathLength, "data/levels/%s/%s", m_sceneName.c_str(), filename);
if (GetFileSystem()->IsExist(filenamebuf)) {
SceneStaticMesh* staticMesh = new SceneStaticMesh();
staticMesh->LoadObj(filenamebuf);
m_sceneMeshes.push_back(staticMesh);
}
}
bool SceneManager::isSceneLoaded()
{
return m_sceneLoaded;
}
void SceneManager::renderScene(const glm::mat4& cameraTranslation)
{
if (!isSceneLoaded())
return;
Camera* camera = g_cameraManager.GetActiveCamera();
if (!camera)
return;
Frustum& frustum = camera->GetFrustum();
for (std::list<SceneStaticMesh*>::iterator it = m_sceneMeshes.begin(); it != m_sceneMeshes.end(); ++it) {
if (*it) {
// cull mesh
if (frustum.CullBoundingBox((*it)->GetBoundingBox()))
continue;
(*it)->RenderObjects();
g_debugRender->DrawBoundingBox((*it)->GetBoundingBox(), glm::vec3(1.0f));
}
}
// draw skybox
//if (m_pSkybox)
// m_pSkybox->renderObjects(cameraTranslation);
//glActiveTexture(GL_TEXTURE1);
//m_lightmap->bind();
//if (g_lmTexFilter.getValueB()) {
// //m_lightmap->setMin
//}
//m_lightmap->setWrapS(TextureWrap::ClampToEdge);
//m_lightmap->setWrapT(TextureWrap::ClampToEdge);
//for (std::list<SceneStaticMesh*>::iterator it = m_sceneMeshes.begin(); it != m_sceneMeshes.end(); ++it) {
// if (*it) {
// (*it)->renderObjects();
// }
//}
//glActiveTexture(GL_TEXTURE1);
//glBindTexture(GL_TEXTURE_2D, 0);
}
void SceneManager::unloadIfScenePresent()
{
if (!isSceneLoaded())
return;
unloadScene();
}
void SceneManager::replaceMaterial(const char* oldMaterialname, const char* newMaterialName)
{
}
void SceneManager::replaceAllMaterialsWithBruteForce(const char* materialname)
{
/*for (std::list<SceneStaticMesh*>::iterator it = m_sceneMeshes.begin();
it != m_sceneMeshes.end();
++it)
{
SceneStaticMesh* mesh = (*it);
assert(mesh);
assert(mesh->m_material && "scene mesh has nullptr assImpMaterial");
mesh->m_material = g_materialsManager->createMaterial(materialname,
mesh->m_material->getTemplateMaterial()->m_diffuseTextures[0].c_str());
}*/
}
void SceneManager::unloadScene()
{
Logger::Msg("deleting scene ...");
if (m_sceneMeshes.empty())
return;
for (std::list<SceneStaticMesh*>::iterator it = m_sceneMeshes.begin();
it != m_sceneMeshes.end();
++it)
{
if (*it) {
delete* it;
*it = nullptr;
}
}
m_sceneMeshes.clear();
m_sceneLoaded = false;
}
const char* SceneManager::getSceneName()
{
return m_sceneName.c_str();
}
// SceneStaticMesh
SceneStaticMesh::SceneStaticMesh() :
m_vb(nullptr),
m_ib(nullptr),
m_albedoTexture(nullptr),
m_vbcount(0),
m_ibcount(0)
{
}
SceneStaticMesh::~SceneStaticMesh()
{
if (m_ib) {
delete m_ib;
m_ib = nullptr;
}
if (m_vb) {
delete m_vb;
m_vb = nullptr;
}
}
void SceneStaticMesh::LoadObj(const char* filename)
{
std::vector<unsigned int> vertexIndices, uvIndices, normalIndices;
std::vector<glm::vec3> temp_vertices;
std::vector<glm::vec2> temp_uvs;
std::vector<glm::vec3> temp_normals;
std::vector<glm::vec3> out_vertices;
std::vector<glm::vec2> out_uvs;
std::vector<glm::vec3> out_normals;
FILE* file = fopen(filename, "r");
if (file == NULL) {
Msg("SceneStaticMesh::LoadObj: Impossible to open the file !");
return;
}
while (1) {
char lineHeader[128];
// read the first word of the line
int res = fscanf(file, "%s", lineHeader);
if (res == EOF)
break; // EOF = End Of File. Quit the loop.
// else : parse lineHeader
if (strcmp(lineHeader, "v") == 0) {
glm::vec3 vertex;
fscanf(file, "%f %f %f\n", &vertex.x, &vertex.y, &vertex.z);
temp_vertices.push_back(vertex);
}
else if (strcmp(lineHeader, "vt") == 0) {
glm::vec2 uv;
fscanf(file, "%f %f\n", &uv.x, &uv.y);
uv.y = -uv.y; // Invert V coordinate since we will only use DDS texture, which are inverted. Remove if you want to use TGA or BMP loaders.
temp_uvs.push_back(uv);
}
else if (strcmp(lineHeader, "vn") == 0) {
glm::vec3 normal;
fscanf(file, "%f %f %f\n", &normal.x, &normal.y, &normal.z);
temp_normals.push_back(normal);
}
else if (strcmp(lineHeader, "f") == 0) {
std::string vertex1, vertex2, vertex3;
unsigned int vertexIndex[3], uvIndex[3], normalIndex[3];
int matches = fscanf(file, "%d/%d/%d %d/%d/%d %d/%d/%d\n", &vertexIndex[0], &uvIndex[0], &normalIndex[0], &vertexIndex[1], &uvIndex[1], &normalIndex[1], &vertexIndex[2], &uvIndex[2], &normalIndex[2]);
if (matches != 9) {
Msg("SceneStaticMesh::LoadObj: File can't be read by our simple parser :-( Try exporting with other options");
fclose(file);
return;
}
vertexIndices.push_back(vertexIndex[0]);
vertexIndices.push_back(vertexIndex[1]);
vertexIndices.push_back(vertexIndex[2]);
uvIndices.push_back(uvIndex[0]);
uvIndices.push_back(uvIndex[1]);
uvIndices.push_back(uvIndex[2]);
normalIndices.push_back(normalIndex[0]);
normalIndices.push_back(normalIndex[1]);
normalIndices.push_back(normalIndex[2]);
}
else {
// Probably a comment, eat up the rest of the line
char stupidBuffer[1000];
fgets(stupidBuffer, 1000, file);
}
}
// For each vertex of each triangle
for (unsigned int i = 0; i < vertexIndices.size(); i++) {
// Get the indices of its attributes
unsigned int vertexIndex = vertexIndices[i];
unsigned int uvIndex = uvIndices[i];
unsigned int normalIndex = normalIndices[i];
// Get the attributes thanks to the index
glm::vec3 vertex = temp_vertices[vertexIndex - 1];
glm::vec2 uv = temp_uvs[uvIndex - 1];
glm::vec3 normal = temp_normals[normalIndex - 1];
// Put the attributes in buffers
out_vertices.push_back(vertex);
out_uvs.push_back(uv);
out_normals.push_back(normal);
}
fclose(file);
m_boundingBox.m_min = glm::vec3(FLT_MAX);
m_boundingBox.m_max = glm::vec3(FLT_MIN);
// Combine in to the one array
std::vector<StaticMeshVertex> vertices;
for (unsigned int i = 0; i < vertexIndices.size(); i++)
{
// Get the indices of its attributes
unsigned int vertexIndex = vertexIndices[i];
unsigned int uvIndex = uvIndices[i];
unsigned int normalIndex = normalIndices[i];
// Get the attributes thanks to the index
glm::vec3 vertex = temp_vertices[vertexIndex - 1];
glm::vec2 uv = temp_uvs[uvIndex - 1];
glm::vec3 normal = temp_normals[normalIndex - 1];
StaticMeshVertex vtx = {};
vtx.position = vertex;
vtx.normal = normal;
vtx.texcoord = uv;
vertices.push_back(vtx);
if (i == 0)
{
m_boundingBox.m_min = vertex;
m_boundingBox.m_max = vertex;
}
else
{
m_boundingBox.m_min = glm::min(m_boundingBox.m_min, vertex);
m_boundingBox.m_max = glm::max(m_boundingBox.m_max, vertex);
}
}
// m_Vertices = vertices;
m_vb = g_renderDevice->CreateVertexBuffer(vertices.data(), (int)sizeof(StaticMeshVertex) * (int)vertices.size());
m_vbcount = vertices.size();
std::string mtlfilename = getFileNameWithoutExtension(filename);
mtlfilename += ".mtl";
LoadMtl(mtlfilename.c_str());
}
void SceneStaticMesh::LoadMtl(const char* filename)
{
FILE* file = fopen(filename, "r");
if (file == NULL) {
Msg("SceneStaticMesh::LoadObj: Impossible to open the file !");
return;
}
while (1) {
char lineHeader[128];
// read the first word of the line
int res = fscanf(file, "%s", lineHeader);
if (res == EOF)
break; // EOF = End Of File. Quit the loop.
if (strcmp(lineHeader, "map_Kd") == 0) {
char stupidBuffer[1000];
fgets(stupidBuffer, 1000, file);
const char* textureFilename = stupidBuffer + 1;
m_albedoTexture = g_texturesManager->LoadTexture2D(textureFilename, true);
}
//if (strcmp(lineHeader, "v") == 0) {
// glm::vec3 vertex;
// fscanf(file, "%f %f %f\n", &vertex.x, &vertex.y, &vertex.z);
// temp_vertices.push_back(vertex);
//}
//else {
// // Probably a comment, eat up the rest of the line
// char stupidBuffer[1000];
// fgets(stupidBuffer, 1000, file);
//}
}
fclose(file);
}
void SceneStaticMesh::RenderObjects()
{
extern Shader* g_litShader;
SDL_assert(g_litShader);
glFrontFace(GL_CCW);
glDepthFunc(GL_LESS);
g_renderDevice->SetCullFace(true);
g_renderDevice->SetDepthTest(true);
g_renderDevice->SetDepthWrite(true);
g_renderDevice->SetBlending(false);
g_renderDevice->SetVerticesBuffer(m_vb);
g_shaderSystem->SetShader(g_litShader);
static glm::mat4 s_identity = glm::mat4(1.0f);
g_shaderSystem->SetUniformMatrix(g_litShader, UNIFORM_MODEL_MATRIX, &s_identity[0]);
glm::mat4 mvp = glm::identity<glm::mat4>();
mvp = g_render->GetProjectionMatrix() * g_render->GetViewMatrix();
g_shaderSystem->SetUniformMatrix(g_litShader, UNIFORM_MVP_MATRIX, &mvp[0]);
g_texturesManager->SetTexture(0, m_albedoTexture);
g_shaderSystem->SetUniformSampler(g_litShader, SAMPLER_ALBEDO, 0);
g_renderDevice->DrawArrays(PT_TRIANGLES, 0, m_vbcount);
}

73
src/render/scenemanager.h Normal file
View File

@@ -0,0 +1,73 @@
#ifndef SCENEMANAGER_H
#define SCENEMANAGER_H
#include <list>
#include <string>
class Texture2D;
class GPUBuffer;
class Model;
class SceneStaticMesh
{
public:
SceneStaticMesh();
~SceneStaticMesh();
void LoadObj(const char* filename);
void LoadMtl(const char* filename);
const BoundingBox& GetBoundingBox() { return m_boundingBox; }
void RenderObjects();
private:
GPUBuffer* m_vb;
GPUBuffer* m_ib;
uint32_t m_vbcount;
uint32_t m_ibcount;
BoundingBox m_boundingBox;
Texture2D* m_albedoTexture;
};
class SceneManager
{
public:
SceneManager();
~SceneManager();
// \brief Load an static scene.
void loadScene(const char*);
// \brief Get current scene name.
const char* getSceneName();
private:
void LoadSceneXML(const char* filename);
void loadSkybox(const char*);
void loadStaticMeshes();
void loadStaticMesh(const char* filename);
public:
bool isSceneLoaded();
void renderScene(const glm::mat4& cameraTranslation);
void unloadScene();
void unloadIfScenePresent();
void replaceMaterial(const char* oldMaterialname, const char* newMaterialName);
void replaceAllMaterialsWithBruteForce(const char* materialname);
private:
Model* m_pSkybox;
std::list<SceneStaticMesh*> m_sceneMeshes;
std::string m_sceneFilename;
std::string m_sceneName;
Texture2D* m_lightmap;
bool m_sceneLoaded;
};
extern SceneManager* g_sceneManager;
#endif // !SCENEMANAGER_H

View File

@@ -59,7 +59,7 @@ size_t g_vertexAttribsRealSizeTable[VERTEXATTR_MAX] =
4, // VERTEXATTR_UINT
};
ShaderSystem* g_pShaderSystem = nullptr;
ShaderSystem* g_shaderSystem = nullptr;
ShaderSystem::ShaderSystem()
{

View File

@@ -27,6 +27,6 @@ private:
std::vector<Shader*> m_shaders;
};
extern ShaderSystem* g_pShaderSystem;
extern ShaderSystem* g_shaderSystem;
#endif // !SHADERSYSTEM_H

View File

@@ -11,7 +11,7 @@
static const char* g_texFileExtensions[] = { ".png", ".jpeg", ".jpg", ".tga", ".bmp" };
const int kTexFileExtensionsSize = sizeof(g_texFileExtensions) / sizeof(g_texFileExtensions[0]);
TexturesManager* g_pTexturesManager = nullptr;
TexturesManager* g_texturesManager = nullptr;
static std::string getFileExtension(const std::string& filename)
{

View File

@@ -35,6 +35,6 @@ private:
Texture2D* m_notex;
};
extern TexturesManager* g_pTexturesManager;
extern TexturesManager* g_texturesManager;
#endif // !TEXTURESMANAGER_H