This commit is contained in:
2026-03-07 07:48:16 +03:00
parent a998771486
commit 95daf12fc5
48 changed files with 4613 additions and 66 deletions

View File

@@ -95,6 +95,51 @@ void DebugRender::DrawBoundingBox(const BoundingBox& box, const glm::vec3& color
DrawLine(p5, p7, color);
}
void DebugRender::DrawSphere(const glm::vec3& origin, float radius, const glm::vec3& color)
{
#ifndef M_PI
#define M_PI 3.14159265358979323846 // pi
#endif // !M_PI
const int kSegments = 16;
const float kStep = 2.0f * M_PI / (float)kSegments;
#undef M_PI
// XY
for (int i = 0; i < kSegments; i++)
{
float theta = i * kStep;
float theta2 = (i + 1) * kStep;
glm::vec3 p1 = origin + glm::vec3(cos(theta) * radius, sin(theta) * radius, 0.0f);
glm::vec3 p2 = origin + glm::vec3(cos(theta2) * radius, sin(theta2) * radius, 0.0f);
DrawLine(p1, p2, color);
}
// XZ
for (int i = 0; i < kSegments; i++)
{
float theta = i * kStep;
float theta2 = (i + 1) * kStep;
glm::vec3 p1 = origin + glm::vec3(cos(theta) * radius, 0.0f, sin(theta) * radius);
glm::vec3 p2 = origin + glm::vec3(cos(theta2) * radius, 0.0f, sin(theta2) * radius);
DrawLine(p1, p2, color);
}
// YZ
for (int i = 0; i < kSegments; i++)
{
float theta = i * kStep;
float theta2 = (i + 1) * kStep;
glm::vec3 p1 = origin + glm::vec3(0.0f, cos(theta) * radius, sin(theta) * radius);
glm::vec3 p2 = origin + glm::vec3(0.0f, cos(theta2) * radius, sin(theta2) * radius);
DrawLine(p1, p2, color);
}
}
void DebugRender::RenderFrame()
{
if (!g_drawDebug)

View File

@@ -23,6 +23,7 @@ public:
void DrawAxis(const glm::vec3& vec);
void DrawLine(const glm::vec3& from, const glm::vec3& to, const glm::vec3& color);
void DrawBoundingBox(const BoundingBox& box, const glm::vec3& color);
void DrawSphere(const glm::vec3& origin, float radius, const glm::vec3& color);
void RenderFrame();

View File

@@ -14,9 +14,13 @@
#include "texturesmanager.h"
#include "iqm.h"
#include "debugrender.h"
#include "scenemanager.h"
#include "camera.h"
extern Shader* g_unlitShader;
extern Shader* g_unlitSkinnedShader;
extern Shader* g_litShader;
extern Shader* g_litSkinnedShader;
static std::string getFileNameWithoutExtension(const std::string& filename)
{
@@ -285,7 +289,7 @@ void Model::LoadIqm(const char* filename)
//mesh.m_indices = indices;
mesh.vb = g_renderDevice->CreateVertexBuffer(vertices.data(), pMesh->num_vertexes * sizeof(SkinnedMeshVertex), true);
mesh.vbcount = pMesh->num_vertexes;
mesh.ib = g_renderDevice->CreateIndexBuffer(indices.data(), pMesh->num_triangles * sizeof(iqmtriangle), false);
mesh.ib = g_renderDevice->CreateIndexBuffer(indices.data(), pMesh->num_triangles * 3 * sizeof(uint), false);
mesh.ibcount = pMesh->num_triangles * 3;
@@ -611,8 +615,28 @@ void Model::Draw(const glm::mat4& model, SkeletonInstance* instance /*= nullptr*
{
SDL_assert(g_unlitShader);
glm::vec3 pos = model[3];
Shader* shader = instance ? g_unlitSkinnedShader : g_unlitShader;
DLight* light = nullptr;
float lastDistSq = FLT_MAX;
for (int i = 0; i < DLightManager::GetInstance()->GetNumLights(); i++)
{
float distSq = glm::length2(pos - DLightManager::GetInstance()->GetDLight(i)->position );
if (distSq <= lastDistSq)
{
lastDistSq = distSq;
light = DLightManager::GetInstance()->GetDLight(i);
}
}
if (light)
shader = instance ? g_litSkinnedShader : g_litShader;
for (int i = 0; i < m_meshes.size(); i++)
{
ModelData_t& m_data = m_meshes[i];
@@ -624,23 +648,7 @@ void Model::Draw(const glm::mat4& model, SkeletonInstance* instance /*= nullptr*
g_renderDevice->SetDepthTest(true);
g_renderDevice->SetDepthWrite(true);
bool isTransparent = false;
if (isTransparent)
{
// Enable blending
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_shaderSystem->SetUniformFloat4(shader, UNIFORM_CUSTOM_COLOR, glm::value_ptr(color));
}
else
{
g_renderDevice->SetBlending(false);
//glm::vec4 color = glm::vec4(1.f, 1.f, 1.f, 1.f);
//g_shaderSystem->SetUniformFloat4(shader, UNIFORM_CUSTOM_COLOR, glm::value_ptr(color));
}
g_renderDevice->SetBlending(false);
g_renderDevice->SetVerticesBuffer(m_data.vb);
if (m_data.ib)
@@ -657,6 +665,37 @@ void Model::Draw(const glm::mat4& model, SkeletonInstance* instance /*= nullptr*
g_shaderSystem->SetUniformMatrix(shader, UNIFORM_MVP_MATRIX, &mvp[0]);
Camera* camera = g_cameraManager.GetActiveCamera();
if (camera && shader->HasUniform(UNIFORM_CAMERA_POS))
{
glm::vec4 campos = glm::vec4(camera->GetPosition(), 1.0f);
g_shaderSystem->SetUniformFloat4(shader, UNIFORM_CAMERA_POS, &campos);
}
if (shader->HasUniform(UNIFORM_SUN_DIRECTION))
{
glm::vec4 lightPos = glm::vec4(0.0f, 0.0f, 0.0f, 0.0f);
if (light)
lightPos = glm::vec4(light->position, light->radius);
g_shaderSystem->SetUniformFloat4(shader, UNIFORM_SUN_DIRECTION, &lightPos);
}
if (shader->HasUniform(UNIFORM_SUN_COLOR))
{
glm::vec4 lightColor = glm::vec4(0.0f, 0.0f, 0.0f, 0.0f);
if (light)
lightColor = glm::vec4(light->color, 1.0f);
g_shaderSystem->SetUniformFloat4(shader, UNIFORM_SUN_COLOR, &lightColor);
}
if (shader->HasUniform(UNIFORM_SUN_AMBIENT))
{
glm::vec4 lightColor = glm::vec4(0.1f);
g_shaderSystem->SetUniformFloat4(shader, UNIFORM_SUN_AMBIENT, &lightColor);
}
if (!m_data.m_AlbedoTexture)
m_data.m_AlbedoTexture = g_texturesManager->LoadTexture2D("MustBeEvilHackButDontCare");

View File

@@ -64,6 +64,11 @@ void ModelSystem::Init()
// Load unlighted skinned model generic shader
g_unlitSkinnedShader = g_shaderSystem->CreateShader("unlit_generic_skin", "data/shaders/unlit_generic_skin.vs", "data/shaders/unlit_generic.ps",
g_skinnedVertexLayout, sizeof(g_skinnedVertexLayout) / sizeof(g_skinnedVertexLayout[0]));
// Load lighted skinned model generic shader
g_litSkinnedShader = g_shaderSystem->CreateShader("lit_generic_skin", "data/shaders/lit_generic_skin.vs", "data/shaders/lit_generic.ps",
g_skinnedVertexLayout, sizeof(g_skinnedVertexLayout) / sizeof(g_skinnedVertexLayout[0]));
}
void ModelSystem::Shutdown()

View File

@@ -67,7 +67,7 @@ void APIENTRY GL_DebugOutput(GLenum source,
if (type == GL_DEBUG_TYPE_ERROR_ARB)
{
bool debug = true;
__debugbreak();
//__debugbreak();
}
}
@@ -78,7 +78,7 @@ Render::Render() :
m_pGLContext(nullptr),
m_pStretchedPicVBuf(nullptr),
m_usingVAO(false),
m_showStats(true)
m_showStats(false)
{
m_viewMatrix = glm::identity<glm::mat4>();
m_projectionMatrix = glm::identity<glm::mat4>();
@@ -310,6 +310,13 @@ void Render::RenderStats()
snprintf(buffer, sizeof(buffer), "numModels: %d", g_NumModels);
ImGui::GetForegroundDrawList()->AddText(ImVec2(0.0f, 30.0f), 0xffffffff, buffer);
Camera* camera = g_cameraManager.GetActiveCamera();
if (camera)
{
snprintf(buffer, sizeof(buffer), "cam pos: %.2f %.2f %.2f", camera->GetPosition().x, camera->GetPosition().y, camera->GetPosition().z);
ImGui::GetForegroundDrawList()->AddText(ImVec2(0.0f, 45.0f), 0xffffffff, buffer);
}
}
void Render::Present(bool vsync)
@@ -319,6 +326,8 @@ void Render::Present(bool vsync)
SDL_GL_SwapWindow(m_pWindow);
// reset stats
ResetStates();
g_NumModels = 0;
}

View File

@@ -250,4 +250,11 @@ struct SkinnedMeshVertex
glm::vec4 weights;
};
struct DLight
{
glm::vec3 position;
glm::vec3 color;
float radius;
};
#endif

View File

@@ -205,6 +205,8 @@ SceneManager* g_sceneManager;
SceneManager::SceneManager()
{
m_sceneLoaded = false;
DLightManager::GetInstance()->Clear();
}
SceneManager::~SceneManager()
@@ -214,6 +216,8 @@ SceneManager::~SceneManager()
void SceneManager::loadScene(const char* filename)
{
unloadIfScenePresent();
char filenameBuffer[kMaxPathLength];
snprintf(filenameBuffer, kMaxPathLength, "data/levels/%s/%s.xml", filename, filename);
@@ -478,6 +482,8 @@ void SceneManager::unloadScene()
m_sceneMeshes.clear();
DLightManager::GetInstance()->Clear();
m_sceneLoaded = false;
}
@@ -777,7 +783,14 @@ void SceneStaticMesh::LoadMtl(const char* filename)
char stupidBuffer[1000];
fgets(stupidBuffer, 1000, file);
const char* textureFilename = stupidBuffer + 1;
char* textureFilename = stupidBuffer + 1;
int str_len = strlen(textureFilename);
if (textureFilename[str_len - 1] == '\n')
textureFilename[str_len - 1] = '\0';
m_albedoTexture = g_texturesManager->LoadTexture2D(textureFilename, true);
}
@@ -799,7 +812,7 @@ void SceneStaticMesh::LoadMtl(const char* filename)
static glm::mat4 s_identity = glm::mat4(1.0f);
void R_SceneStaticMesh_BindShader(const glm::mat4& worldMatrix, Texture2D* albedoTexture)
void R_SceneStaticMesh_BindShader(const glm::mat4& worldMatrix, Texture2D* albedoTexture, DLight* light)
{
extern Shader* g_unlitShader;
extern Shader* g_litShader;
@@ -807,7 +820,7 @@ void R_SceneStaticMesh_BindShader(const glm::mat4& worldMatrix, Texture2D* albed
SDL_assert(g_unlitShader);
SDL_assert(g_litShader);
Shader* shader = g_litShader;
Shader* shader = light ? g_litShader : g_unlitShader;
g_shaderSystem->SetShader(shader);
@@ -825,17 +838,22 @@ void R_SceneStaticMesh_BindShader(const glm::mat4& worldMatrix, Texture2D* albed
if (shader->HasUniform(UNIFORM_SUN_DIRECTION))
{
glm::vec4 lightPos = glm::vec4(1.0f, 1.0f, 1.0f, 0.0f);
// g_debugRender->DrawAxis(glm::vec3(lightPos));
Camera* camera = g_cameraManager.GetActiveCamera();
if (camera)
lightPos = glm::vec4(camera->GetPosition(), 1.0f);
glm::vec4 lightPos = glm::vec4(0.0f, 0.0f, 0.0f, 0.0f);
if (light)
lightPos = glm::vec4(light->position, light->radius);
g_shaderSystem->SetUniformFloat4(shader, UNIFORM_SUN_DIRECTION, &lightPos);
}
if (shader->HasUniform(UNIFORM_SUN_COLOR))
{
glm::vec4 lightColor = glm::vec4(0.0f, 0.0f, 0.0f, 0.0f);
if (light)
lightColor = glm::vec4(light->color, 1.0f);
g_shaderSystem->SetUniformFloat4(shader, UNIFORM_SUN_COLOR, &lightColor);
}
if (shader->HasUniform(UNIFORM_SUN_AMBIENT))
{
glm::vec4 lightColor = glm::vec4(0.1f);
@@ -854,14 +872,149 @@ void SceneStaticMesh::RenderObjects()
g_renderDevice->SetCullFace(true);
g_renderDevice->SetDepthTest(true);
g_renderDevice->SetDepthWrite(true);
g_renderDevice->SetBlending(false);
g_renderDevice->SetVerticesBuffer(m_vb);
int numlights = DLightManager::GetInstance()->GetNumLights();
if (!numlights)
{
g_renderDevice->SetVerticesBuffer(m_vb);
R_SceneStaticMesh_BindShader(s_identity, m_albedoTexture);
R_SceneStaticMesh_BindShader(s_identity, m_albedoTexture, nullptr);
g_renderDevice->DrawArrays(PT_TRIANGLES, 0, m_vbcount);
g_renderDevice->DrawArrays(PT_TRIANGLES, 0, m_vbcount);
g_NumModels++;
g_NumModels++;
}
else
{
// first pass
g_renderDevice->SetVerticesBuffer(m_vb);
R_SceneStaticMesh_BindShader(s_identity, m_albedoTexture, DLightManager::GetInstance()->GetDLight(0));
g_renderDevice->DrawArrays(PT_TRIANGLES, 0, m_vbcount);
g_NumModels++; // overdraw YAAAY
if (numlights > 1)
{
// fragment passed, can turn off depth write
g_renderDevice->SetDepthWrite(false);
// testing only written fragments
glDepthFunc(GL_EQUAL);
// additive blending
g_renderDevice->SetBlending(true);
g_renderDevice->SetBlendingFunction(BF_ONE, BF_ONE);
glBlendFunc(GL_ONE, GL_ONE);
for (int i = 1; i < numlights; i++)
{
g_renderDevice->SetVerticesBuffer(m_vb);
R_SceneStaticMesh_BindShader(s_identity, m_albedoTexture, DLightManager::GetInstance()->GetDLight(i));
g_renderDevice->DrawArrays(PT_TRIANGLES, 0, m_vbcount);
g_NumModels++; // overdraw YAAAY
}
g_renderDevice->SetBlending(false);
glDepthFunc(GL_LESS);
}
}
}
DLightManager* DLightManager::GetInstance()
{
static DLightManager instance;
return &instance;
}
DLight* DLightManager::AllocLight()
{
return &m_dlights[m_numdlights++];
}
void DLightManager::Clear()
{
memset(m_dlights, 0, sizeof(m_dlights));
m_numdlights = 0;
}
DLight* DLightManager::GetDLight(int index)
{
if (index >= m_numdlights)
Core::Error("DLightManager::GetDLight: index is out of range");
return &m_dlights[index];
}
int DLightManager::GetNumLights()
{
return m_numdlights;
}
//void R_SceneStaticMesh_BindShader(const glm::mat4& worldMatrix, Texture2D* albedoTexture)
//{
// extern Shader* g_unlitShader;
// extern Shader* g_litShader;
//
// SDL_assert(g_unlitShader);
// SDL_assert(g_litShader);
//
// Shader* shader = g_litShader;
//
// g_shaderSystem->SetShader(shader);
//
// g_shaderSystem->SetUniformMatrix(shader, UNIFORM_MODEL_MATRIX, &worldMatrix[0]);
//
// glm::mat4 mvp = g_render->GetProjectionMatrix() * g_render->GetViewMatrix() * worldMatrix;
// g_shaderSystem->SetUniformMatrix(shader, UNIFORM_MVP_MATRIX, &mvp[0]);
//
// Camera* camera = g_cameraManager.GetActiveCamera();
// if (camera && shader->HasUniform(UNIFORM_CAMERA_POS))
// {
// glm::vec4 campos = glm::vec4(camera->GetPosition(), 1.0f);
// g_shaderSystem->SetUniformFloat4(shader, UNIFORM_CAMERA_POS, &campos);
// }
//
// if (shader->HasUniform(UNIFORM_SUN_DIRECTION))
// {
// glm::vec4 lightPos = glm::vec4(1.0f, 1.0f, 1.0f, 0.0f);
//
// // g_debugRender->DrawAxis(glm::vec3(lightPos));
//
// Camera* camera = g_cameraManager.GetActiveCamera();
// if (camera)
// lightPos = glm::vec4(camera->GetPosition(), 1.0f);
//
// g_shaderSystem->SetUniformFloat4(shader, UNIFORM_SUN_DIRECTION, &lightPos);
// }
//
// if (shader->HasUniform(UNIFORM_SUN_AMBIENT))
// {
// glm::vec4 lightColor = glm::vec4(0.1f);
// g_shaderSystem->SetUniformFloat4(shader, UNIFORM_SUN_AMBIENT, &lightColor);
// }
//
// g_texturesManager->SetTexture(0, albedoTexture);
// g_shaderSystem->SetUniformSampler(shader, SAMPLER_ALBEDO, 0);
//}
//
//void SceneStaticMesh::RenderObjects()
//{
// 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);
//
// R_SceneStaticMesh_BindShader(s_identity, m_albedoTexture);
//
// g_renderDevice->DrawArrays(PT_TRIANGLES, 0, m_vbcount);
//
// g_NumModels++;
//}

View File

@@ -31,6 +31,25 @@ private:
Texture2D* m_albedoTexture;
};
const int kMaxDLight = 1024;
class DLightManager
{
public:
static DLightManager* GetInstance();
public:
DLight* AllocLight();
void Clear();
DLight* GetDLight(int index);
int GetNumLights();
private:
DLight m_dlights[kMaxDLight];
int m_numdlights;
};
class SceneManager
{
public: