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

@@ -111,6 +111,8 @@ struct ExampleAppConsole
Commands.push_back("r_scene_debug_draw");
Commands.push_back("r_show_stats");
Commands.push_back("r_entity_debug_draw");
Commands.push_back("r_light_debug_draw");
Commands.push_back("noclip");
Commands.push_back("map");
Commands.push_back("quit");
AutoScroll = true;
@@ -290,12 +292,12 @@ struct ExampleAppConsole
void ExecCommand(const char* command_line)
{
AddLog("# %s\n", command_line);
static char extracted[1024];
const char* full_command_line = command_line;
if (const char* arg = strchr(command_line, ' '))
{
static char extracted[1024];
strncpy(extracted, command_line, arg - command_line);
command_line = extracted;
@@ -348,6 +350,15 @@ struct ExampleAppConsole
extern bool g_debugEntityDraw;
g_debugEntityDraw = !g_debugEntityDraw;
}
else if (Stricmp(command_line, "R_LIGHT_DEBUG_DRAW") == 0)
{
extern bool g_debugDrawLights;
g_debugDrawLights = !g_debugDrawLights;
}
else if (Stricmp(command_line, "NOCLIP") == 0)
{
toggleNoclip();
}
else if (Stricmp(command_line, "MAP") == 0)
{
GetEngine()->NewGame(full_command_line + 4);
@@ -363,6 +374,8 @@ struct ExampleAppConsole
// On command input, we scroll to bottom even if AutoScroll==false
ScrollToBottom = true;
extracted[0] = '\0';
}
// In C++11 you'd be better off using lambdas for this sort of forwarding callbacks
@@ -674,6 +687,14 @@ void Engine::Frame()
if (s_showConsole)
UpdateConsole();
// update sound
Camera* camera = g_cameraManager.GetActiveCamera();
if (camera)
{
g_soundSystem.SetListenerPosition(camera->GetPosition().x, camera->GetPosition().y, camera->GetPosition().z);
g_soundSystem.SetListenerDirection(camera->GetFront().x, camera->GetFront().y, camera->GetFront().z);
}
// update physics
if (g_PhysicsWorld)
g_PhysicsWorld->Step(dt);
@@ -766,7 +787,8 @@ void Engine::NewGame(const char* mapname)
g_render->LoadSceneXML(mapname);
CloseConsole();
if (s_showConsole)
CloseConsole();
// after initializing client scene and collision system - we initialize the server game
g_game->InitForNewMap(mapname);

View File

@@ -5,7 +5,8 @@
REGISTER_ENTITY(ActorBase);
ActorBase::ActorBase()
ActorBase::ActorBase() :
m_noclip(false)
{
}
@@ -242,6 +243,40 @@ bool ActorBase::OnGround()
return false;
}
void ActorBase::SetNoclip(bool noclip)
{
static int mask1 = -1, mask2 = -1;
m_noclip = noclip;
if (noclip)
{
if (mask1 == -1)
{
mask1 = m_rigidBody->getBroadphaseHandle()->m_collisionFilterGroup;
mask2 = m_rigidBody->getBroadphaseHandle()->m_collisionFilterMask;
}
m_rigidBody->getBroadphaseHandle()->m_collisionFilterGroup = 0;
m_rigidBody->getBroadphaseHandle()->m_collisionFilterMask = 0;
g_PhysicsWorld->GetWorld()->getPairCache()->cleanProxyFromPairs(m_rigidBody->getBroadphaseHandle(), g_PhysicsWorld->GetWorld()->getDispatcher());
m_rigidBody->setCollisionFlags(m_rigidBody->getCollisionFlags() |/* btCollisionObject::CF_KINEMATIC_OBJECT |*/ btCollisionObject::CF_NO_CONTACT_RESPONSE);
m_rigidBody->setGravity(btVector3(0.0f, 0.f, 0.f));
}
else
{
m_rigidBody->getBroadphaseHandle()->m_collisionFilterGroup = mask1;
m_rigidBody->getBroadphaseHandle()->m_collisionFilterMask = mask2;
// m_rigidBody->setCollisionFlags(m_rigidBody->getCollisionFlags() & ~btCollisionObject::CF_KINEMATIC_OBJECT);
m_rigidBody->setCollisionFlags(m_rigidBody->getCollisionFlags() & ~btCollisionObject::CF_NO_CONTACT_RESPONSE);
m_rigidBody->setGravity(g_PhysicsWorld->GetWorld()->getGravity());
}
}
void ActorBase::RegisterFunctions()
{
m_luaObject.Register("activate_camera", *this, &ActorBase::Lua_ActivateCamera);
@@ -253,6 +288,7 @@ void ActorBase::RegisterFunctions()
m_luaObject.Register("get_action", *this, &ActorBase::Lua_GetAction);
m_luaObject.Register("get_movement", *this, &ActorBase::Lua_GetMovement);
m_luaObject.Register("on_ground", *this, &ActorBase::Lua_OnGround);
m_luaObject.Register("is_noclip", *this, &ActorBase::Lua_IsNoclip);
//m_luaObject.RegisterDirect("activate_camera", &ActorBase_ActivateCamera);
//m_luaObject.RegisterDirect("update_camera_look", &ActorBase_UpdateCameraLook);
@@ -332,6 +368,12 @@ int ActorBase::Lua_OnGround(LuaPlus::LuaState* state)
return 1;
}
int ActorBase::Lua_IsNoclip(LuaPlus::LuaState* state)
{
state->PushBoolean(m_noclip);
return 1;
}
int ActorBase::GenAction()
{
int action = -1;

View File

@@ -37,6 +37,8 @@ public:
bool OnGround();
void SetNoclip(bool noclip);
// Lua bindings
virtual void RegisterFunctions();
@@ -50,6 +52,7 @@ public:
int Lua_GetAction(LuaPlus::LuaState* state);
int Lua_GetMovement(LuaPlus::LuaState* state);
int Lua_OnGround(LuaPlus::LuaState* state);
int Lua_IsNoclip(LuaPlus::LuaState* state);
private:
int GenAction();
@@ -58,7 +61,7 @@ private:
private:
Camera m_camera;
bool m_noclip;
};

View File

@@ -11,6 +11,10 @@
#include "world.h"
#include "game_object.h"
#include "soundsystem.h"
#include "animation.h"
#include "scenemanager.h"
#include "game_world_objects.h"
#include "actor_base.h"
#include <pugixml.hpp>
@@ -27,6 +31,7 @@ public:
public:
void PlaySound2D(const std::string& filename);
void PlaySound3D(const std::string& filename, const glm::vec3& pos);
void CacheSound(const std::string& filename);
private:
@@ -57,6 +62,24 @@ void GameSoundSystem::PlaySound2D(const std::string& filename)
g_soundSystem.Play(it->second, false);
}
void GameSoundSystem::PlaySound3D(const std::string& filename, const glm::vec3& pos)
{
auto it = m_sounds.find(filename);
if (it == m_sounds.end())
{
CacheSound(filename);
it = m_sounds.find(filename);
}
SDL_assert(it != m_sounds.end());
// .hack due unimplemented sound sources^
if (g_soundSystem.IsPlaying(it->second))
g_soundSystem.Stop(it->second);
g_soundSystem.Play3D(it->second, pos.x, pos.y, pos.z, true);
}
void GameSoundSystem::CacheSound(const std::string& filename)
{
m_sounds.emplace(filename, g_soundSystem.LoadSound(filename.c_str()));
@@ -82,6 +105,11 @@ void enginePlaySound(const char* filename)
GameSoundSystem::GetInstance().PlaySound2D(filename);
}
void enginePlaySound3D(const char* filename, float x, float y, float z)
{
GameSoundSystem::GetInstance().PlaySound3D(filename, glm::vec3(x, y, z));
}
LuaPlus::LuaObject engineCreateEntity(const char* classname)
{
Entity* entity = static_cast<Entity*>(g_game->Lua_CreateEntity(classname));
@@ -157,6 +185,7 @@ void registerEngine()
engineTable.RegisterDirect("add_entity_to_world", &engineAddEntityToWorld);
engineTable.RegisterDirect("get_entity_from_id", &engineGetEntityFromID);
engineTable.RegisterDirect("play_sound", &enginePlaySound);
engineTable.RegisterDirect("play_sound_3d", &enginePlaySound3D);
engineTable.RegisterDirect("get_delta", &engineGetDelta);
engineTable.RegisterDirect("trace_ray", &engineTraceRay);
@@ -231,6 +260,20 @@ void registerInput()
inputTable.RegisterDirect("get_lock_mouse", &inputGetLock);
}
void toggleNoclip()
{
static bool s_noclip = false;
s_noclip = !s_noclip;
LuaPlus::LuaObject player = GetLuaState().GetGlobal("g_player");
if (player.IsTable())
{
ActorBase* actor = (ActorBase*)player["__object"].GetLightUserdata();
actor->SetNoclip(s_noclip);
}
}
int cameraGetPos(LuaPlus::LuaState* state)
{
glm::vec3 v = glm::vec3(0.0f);
@@ -494,6 +537,16 @@ void Game::LoadLevelXML(const char* mapname)
entity->LoadModel(filename);
}
pugi::xml_node animation = entitynode.child("Animation");
if (animation)
{
const char* name = animation.attribute("name").as_string();
int mode = animation.attribute("mode").as_int();
SkeletonInstance* skeleton = entity->GetSkeletonInstance();
if (skeleton)
skeleton->PlayAnimation(skeleton->FindAnimation(name), mode);
}
pugi::xml_node physics = entitynode.child("Physics");
if (physics)
{
@@ -502,6 +555,10 @@ void Game::LoadLevelXML(const char* mapname)
entity->CreateTestBody();
}
Light* light = dynamic_cast<Light*>(entity); // BAD!!!
if (light)
light->InitFromXML(entitynode);
entity->Init();
//IEntityBase* entity = g_entityManager->CreateEntity(classname.as_string());

View File

@@ -23,8 +23,9 @@ public:
extern Game* g_game;
void registerCamera();
void registerInput();
void toggleNoclip();
#endif
void registerCamera();
void registerInput();

View File

@@ -134,6 +134,11 @@ bool Entity::GetVisible()
return true;
}
SkeletonInstance* Entity::GetSkeletonInstance()
{
return m_skeleton;
}
void Entity::UpdateSkeleton(float dt)
{
if (m_model && m_skeleton)

View File

@@ -77,6 +77,7 @@ public:
void SetVisible(bool visible);
bool GetVisible();
SkeletonInstance* GetSkeletonInstance();
void UpdateSkeleton(float dt);
void Init();

View File

@@ -0,0 +1,51 @@
#include "core.h"
#include "game_world_objects.h"
#include "debugrender.h"
#include "scenemanager.h" // BAD!
bool g_debugDrawLights = false;
REGISTER_ENTITY(Light);
Light::Light()
{
m_dlight = nullptr;
}
Light::~Light()
{
}
void Light::Render()
{
if (!m_dlight)
return;
m_dlight->position = m_position;
if (g_debugDrawLights)
{
g_debugRender->DrawSphere(m_dlight->position, m_dlight->radius, m_dlight->color);
}
}
void Light::InitFromXML(const pugi::xml_node& node)
{
m_dlight = DLightManager::GetInstance()->AllocLight();
SDL_assert_always(m_dlight);
m_dlight->position = m_position;
pugi::xml_node color = node.child("Color");
if (color)
{
m_dlight->color.r = color.attribute("r").as_float();
m_dlight->color.g = color.attribute("g").as_float();
m_dlight->color.b = color.attribute("b").as_float();
}
pugi::xml_node radius = node.child("Radius");
if (radius)
{
m_dlight->radius = radius.attribute("value").as_float();
}
}

View File

@@ -0,0 +1,26 @@
#ifndef GAME_WORLD_OBJECTS_H
#define GAME_WORLD_OBJECTS_H
#include <pugixml.hpp>
#include "game_object.h"
struct DLight;
// #TODO: Inheritance from Entity is needed for expose to lua, but did
// light need to have a animation stuff?
class Light : public Entity
{
public:
Light();
~Light();
void Render() override;
void InitFromXML(const pugi::xml_node& node);
private:
DLight* m_dlight;
};
#endif // !GAME_WORLD_OBJECTS_H

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:

View File

@@ -39,6 +39,9 @@ void SoundSystem::Init()
ma_uint32 uiSampleRate = ma_engine_get_sample_rate(&m_engine);
Msg("Sound sampling rate: %d\n", uiSampleRate);
// Initialize listener
SetListenerPosition(0.0f, 0.0f, 0.0f);
m_inited = true;
}
@@ -91,6 +94,15 @@ void SoundSystem::Play(SoundHandle handle, bool bLoop)
ma_sound_set_looping(&m_sounds[handle], true);
}
void SoundSystem::Play3D(SoundHandle handle, float x, float y, float z, bool bLoop)
{
if ( !m_inited )
return;
Play(handle, bLoop);
ma_sound_set_position(&m_sounds[handle], x, y, z);
}
void SoundSystem::Stop(SoundHandle handle)
{
if ( !m_inited )
@@ -121,4 +133,20 @@ void SoundSystem::SetMasterVolume(float volume)
float SoundSystem::GetMasterVolume()
{
return ma_engine_get_volume(&m_engine);
}
}
void SoundSystem::SetListenerPosition(float _x, float _y, float _z)
{
if ( !m_inited )
return;
ma_engine_listener_set_position(&m_engine, 0, _x, _y, _z);
}
void SoundSystem::SetListenerDirection(float _x, float _y, float _z)
{
if ( !m_inited )
return;
ma_engine_listener_set_direction(&m_engine, 0, _x, _y, _z);
}

View File

@@ -19,6 +19,7 @@ public:
SoundHandle LoadSound(const char* filename);
void Play(SoundHandle handle, bool bLoop);
void Play3D(SoundHandle handle, float x, float y, float z, bool bLoop);
void Stop(SoundHandle handle);
bool IsPlaying(SoundHandle handle);
@@ -26,6 +27,9 @@ public:
void SetMasterVolume(float volume);
float GetMasterVolume();
void SetListenerPosition(float _x, float _y, float _z);
void SetListenerDirection(float _x, float _y, float _z);
private:
ma_sound m_sounds[MAX_SOUNDS];
ma_engine m_engine;