fixed up a few lighting issues + made modularity boot quicker without taking past 100 MB of ram.
This commit is contained in:
@@ -614,7 +614,7 @@ void Engine::renderViewport() {
|
|||||||
glm::mat4 view = camera.getViewMatrix();
|
glm::mat4 view = camera.getViewMatrix();
|
||||||
|
|
||||||
renderer.beginRender(view, proj, camera.position);
|
renderer.beginRender(view, proj, camera.position);
|
||||||
renderer.renderScene(camera, sceneObjects, selectedObjectId);
|
renderer.renderScene(camera, sceneObjects, selectedObjectId, FOV, NEAR_PLANE, FAR_PLANE, collisionWireframe);
|
||||||
unsigned int tex = renderer.getViewportTexture();
|
unsigned int tex = renderer.getViewportTexture();
|
||||||
|
|
||||||
ImGui::Image((void*)(intptr_t)tex, imageSize, ImVec2(0, 1), ImVec2(1, 0));
|
ImGui::Image((void*)(intptr_t)tex, imageSize, ImVec2(0, 1), ImVec2(1, 0));
|
||||||
|
|||||||
@@ -379,19 +379,9 @@ void Engine::run() {
|
|||||||
if (aspect <= 0.0f) aspect = 1.0f;
|
if (aspect <= 0.0f) aspect = 1.0f;
|
||||||
glm::mat4 proj = glm::perspective(glm::radians(FOV), aspect, NEAR_PLANE, FAR_PLANE);
|
glm::mat4 proj = glm::perspective(glm::radians(FOV), aspect, NEAR_PLANE, FAR_PLANE);
|
||||||
|
|
||||||
#ifdef GL_POLYGON_MODE
|
|
||||||
GLint prevPoly[2] = { GL_FILL, GL_FILL };
|
|
||||||
glGetIntegerv(GL_POLYGON_MODE, prevPoly);
|
|
||||||
glPolygonMode(GL_FRONT_AND_BACK, collisionWireframe ? GL_LINE : GL_FILL);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
renderer.beginRender(view, proj, camera.position);
|
renderer.beginRender(view, proj, camera.position);
|
||||||
renderer.renderScene(camera, sceneObjects, selectedObjectId);
|
renderer.renderScene(camera, sceneObjects, selectedObjectId, FOV, NEAR_PLANE, FAR_PLANE, collisionWireframe);
|
||||||
renderer.endRender();
|
renderer.endRender();
|
||||||
|
|
||||||
#ifdef GL_POLYGON_MODE
|
|
||||||
glPolygonMode(GL_FRONT_AND_BACK, prevPoly[0]);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (firstFrame) {
|
if (firstFrame) {
|
||||||
|
|||||||
@@ -537,6 +537,7 @@ Renderer::~Renderer() {
|
|||||||
if (rbo) glDeleteRenderbuffers(1, &rbo);
|
if (rbo) glDeleteRenderbuffers(1, &rbo);
|
||||||
if (quadVBO) glDeleteBuffers(1, &quadVBO);
|
if (quadVBO) glDeleteBuffers(1, &quadVBO);
|
||||||
if (quadVAO) glDeleteVertexArrays(1, &quadVAO);
|
if (quadVAO) glDeleteVertexArrays(1, &quadVAO);
|
||||||
|
if (debugWhiteTexture) glDeleteTextures(1, &debugWhiteTexture);
|
||||||
}
|
}
|
||||||
|
|
||||||
Texture* Renderer::getTexture(const std::string& path) {
|
Texture* Renderer::getTexture(const std::string& path) {
|
||||||
@@ -619,6 +620,17 @@ void Renderer::initialize() {
|
|||||||
|
|
||||||
texture1 = new Texture("Resources/Textures/container.jpg");
|
texture1 = new Texture("Resources/Textures/container.jpg");
|
||||||
texture2 = new Texture("Resources/Textures/awesomeface.png");
|
texture2 = new Texture("Resources/Textures/awesomeface.png");
|
||||||
|
if (debugWhiteTexture == 0) {
|
||||||
|
unsigned char white[4] = { 255, 255, 255, 255 };
|
||||||
|
glGenTextures(1, &debugWhiteTexture);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, debugWhiteTexture);
|
||||||
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, white);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
|
}
|
||||||
|
|
||||||
cubeMesh = new Mesh(vertices, sizeof(vertices));
|
cubeMesh = new Mesh(vertices, sizeof(vertices));
|
||||||
|
|
||||||
@@ -1449,9 +1461,15 @@ unsigned int Renderer::applyPostProcessing(const std::vector<SceneObject>& scene
|
|||||||
return target.texture;
|
return target.texture;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Renderer::renderScene(const Camera& camera, const std::vector<SceneObject>& sceneObjects, int /*selectedId*/, float fovDeg, float nearPlane, float farPlane) {
|
void Renderer::renderScene(const Camera& camera, const std::vector<SceneObject>& sceneObjects, int /*selectedId*/, float fovDeg, float nearPlane, float farPlane, bool drawColliders) {
|
||||||
updateMirrorTargets(camera, sceneObjects, currentWidth, currentHeight, fovDeg, nearPlane, farPlane);
|
updateMirrorTargets(camera, sceneObjects, currentWidth, currentHeight, fovDeg, nearPlane, farPlane);
|
||||||
renderSceneInternal(camera, sceneObjects, currentWidth, currentHeight, true, fovDeg, nearPlane, farPlane, true);
|
renderSceneInternal(camera, sceneObjects, currentWidth, currentHeight, true, fovDeg, nearPlane, farPlane, true);
|
||||||
|
if (drawColliders) {
|
||||||
|
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
|
||||||
|
glViewport(0, 0, currentWidth, currentHeight);
|
||||||
|
renderCollisionOverlay(camera, sceneObjects, currentWidth, currentHeight, fovDeg, nearPlane, farPlane);
|
||||||
|
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||||
|
}
|
||||||
unsigned int result = applyPostProcessing(sceneObjects, viewportTexture, currentWidth, currentHeight, true);
|
unsigned int result = applyPostProcessing(sceneObjects, viewportTexture, currentWidth, currentHeight, true);
|
||||||
displayTexture = result ? result : viewportTexture;
|
displayTexture = result ? result : viewportTexture;
|
||||||
}
|
}
|
||||||
@@ -1474,6 +1492,119 @@ unsigned int Renderer::renderScenePreview(const Camera& camera, const std::vecto
|
|||||||
return processed ? processed : previewTarget.texture;
|
return processed ? processed : previewTarget.texture;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Renderer::renderCollisionOverlay(const Camera& camera, const std::vector<SceneObject>& sceneObjects, int width, int height, float fovDeg, float nearPlane, float farPlane) {
|
||||||
|
if (!defaultShader || width <= 0 || height <= 0) return;
|
||||||
|
|
||||||
|
GLint prevPoly[2] = { GL_FILL, GL_FILL };
|
||||||
|
glGetIntegerv(GL_POLYGON_MODE, prevPoly);
|
||||||
|
GLboolean depthTest = glIsEnabled(GL_DEPTH_TEST);
|
||||||
|
GLboolean cullFace = glIsEnabled(GL_CULL_FACE);
|
||||||
|
GLboolean polyOffsetLine = glIsEnabled(GL_POLYGON_OFFSET_LINE);
|
||||||
|
|
||||||
|
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
|
||||||
|
glDisable(GL_CULL_FACE);
|
||||||
|
glEnable(GL_POLYGON_OFFSET_LINE);
|
||||||
|
glPolygonOffset(-1.0f, -1.0f);
|
||||||
|
|
||||||
|
Shader* active = defaultShader;
|
||||||
|
active->use();
|
||||||
|
active->setMat4("view", camera.getViewMatrix());
|
||||||
|
active->setMat4("projection", glm::perspective(glm::radians(fovDeg), (float)width / (float)height, nearPlane, farPlane));
|
||||||
|
active->setVec3("viewPos", camera.position);
|
||||||
|
active->setBool("unlit", true);
|
||||||
|
active->setBool("hasOverlay", false);
|
||||||
|
active->setBool("hasNormalMap", false);
|
||||||
|
active->setInt("lightCount", 0);
|
||||||
|
active->setFloat("mixAmount", 0.0f);
|
||||||
|
active->setVec3("materialColor", glm::vec3(0.2f, 1.0f, 0.2f));
|
||||||
|
active->setFloat("ambientStrength", 1.0f);
|
||||||
|
active->setFloat("specularStrength", 0.0f);
|
||||||
|
active->setFloat("shininess", 1.0f);
|
||||||
|
active->setInt("texture1", 0);
|
||||||
|
active->setInt("overlayTex", 1);
|
||||||
|
active->setInt("normalMap", 2);
|
||||||
|
|
||||||
|
glActiveTexture(GL_TEXTURE0);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, debugWhiteTexture ? debugWhiteTexture : (texture1 ? texture1->GetID() : 0));
|
||||||
|
|
||||||
|
for (const auto& obj : sceneObjects) {
|
||||||
|
if (!obj.enabled) continue;
|
||||||
|
if (!(obj.hasCollider && obj.collider.enabled) && !(obj.hasRigidbody && obj.rigidbody.enabled)) continue;
|
||||||
|
|
||||||
|
Mesh* meshToDraw = nullptr;
|
||||||
|
glm::vec3 scale = obj.scale;
|
||||||
|
glm::vec3 position = obj.position;
|
||||||
|
glm::vec3 rotation = obj.rotation;
|
||||||
|
|
||||||
|
if (obj.hasCollider && obj.collider.enabled) {
|
||||||
|
switch (obj.collider.type) {
|
||||||
|
case ColliderType::Box:
|
||||||
|
meshToDraw = cubeMesh;
|
||||||
|
scale = obj.collider.boxSize;
|
||||||
|
break;
|
||||||
|
case ColliderType::Capsule:
|
||||||
|
meshToDraw = capsuleMesh;
|
||||||
|
scale = obj.collider.boxSize;
|
||||||
|
break;
|
||||||
|
case ColliderType::Mesh:
|
||||||
|
case ColliderType::ConvexMesh:
|
||||||
|
if (obj.type == ObjectType::OBJMesh && obj.meshId >= 0) {
|
||||||
|
meshToDraw = g_objLoader.getMesh(obj.meshId);
|
||||||
|
} else if (obj.type == ObjectType::Model && obj.meshId >= 0) {
|
||||||
|
meshToDraw = getModelLoader().getMesh(obj.meshId);
|
||||||
|
} else {
|
||||||
|
meshToDraw = nullptr;
|
||||||
|
}
|
||||||
|
scale = obj.scale;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
switch (obj.type) {
|
||||||
|
case ObjectType::Cube:
|
||||||
|
meshToDraw = cubeMesh;
|
||||||
|
break;
|
||||||
|
case ObjectType::Sphere:
|
||||||
|
meshToDraw = sphereMesh;
|
||||||
|
break;
|
||||||
|
case ObjectType::Capsule:
|
||||||
|
meshToDraw = capsuleMesh;
|
||||||
|
break;
|
||||||
|
case ObjectType::Plane:
|
||||||
|
meshToDraw = planeMesh;
|
||||||
|
break;
|
||||||
|
case ObjectType::Torus:
|
||||||
|
meshToDraw = sphereMesh;
|
||||||
|
break;
|
||||||
|
case ObjectType::OBJMesh:
|
||||||
|
if (obj.meshId >= 0) meshToDraw = g_objLoader.getMesh(obj.meshId);
|
||||||
|
break;
|
||||||
|
case ObjectType::Model:
|
||||||
|
if (obj.meshId >= 0) meshToDraw = getModelLoader().getMesh(obj.meshId);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!meshToDraw) continue;
|
||||||
|
|
||||||
|
glm::mat4 model = glm::mat4(1.0f);
|
||||||
|
model = glm::translate(model, position);
|
||||||
|
model = glm::rotate(model, glm::radians(rotation.x), glm::vec3(1.0f, 0.0f, 0.0f));
|
||||||
|
model = glm::rotate(model, glm::radians(rotation.y), glm::vec3(0.0f, 1.0f, 0.0f));
|
||||||
|
model = glm::rotate(model, glm::radians(rotation.z), glm::vec3(0.0f, 0.0f, 1.0f));
|
||||||
|
model = glm::scale(model, scale);
|
||||||
|
active->setMat4("model", model);
|
||||||
|
|
||||||
|
meshToDraw->draw();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!polyOffsetLine) glDisable(GL_POLYGON_OFFSET_LINE);
|
||||||
|
if (cullFace) glEnable(GL_CULL_FACE);
|
||||||
|
if (depthTest) glEnable(GL_DEPTH_TEST);
|
||||||
|
glPolygonMode(GL_FRONT_AND_BACK, prevPoly[0]);
|
||||||
|
}
|
||||||
|
|
||||||
void Renderer::endRender() {
|
void Renderer::endRender() {
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -84,6 +84,7 @@ private:
|
|||||||
Shader* blurShader = nullptr;
|
Shader* blurShader = nullptr;
|
||||||
Texture* texture1 = nullptr;
|
Texture* texture1 = nullptr;
|
||||||
Texture* texture2 = nullptr;
|
Texture* texture2 = nullptr;
|
||||||
|
unsigned int debugWhiteTexture = 0;
|
||||||
std::unordered_map<std::string, std::unique_ptr<Texture>> textureCache;
|
std::unordered_map<std::string, std::unique_ptr<Texture>> textureCache;
|
||||||
std::unordered_map<std::string, std::unique_ptr<Texture>> previewTextureCacheLinear;
|
std::unordered_map<std::string, std::unique_ptr<Texture>> previewTextureCacheLinear;
|
||||||
std::unordered_map<std::string, std::unique_ptr<Texture>> previewTextureCacheNearest;
|
std::unordered_map<std::string, std::unique_ptr<Texture>> previewTextureCacheNearest;
|
||||||
@@ -145,8 +146,9 @@ public:
|
|||||||
void beginRender(const glm::mat4& view, const glm::mat4& proj, const glm::vec3& cameraPos);
|
void beginRender(const glm::mat4& view, const glm::mat4& proj, const glm::vec3& cameraPos);
|
||||||
void renderSkybox(const glm::mat4& view, const glm::mat4& proj);
|
void renderSkybox(const glm::mat4& view, const glm::mat4& proj);
|
||||||
void renderObject(const SceneObject& obj);
|
void renderObject(const SceneObject& obj);
|
||||||
void renderScene(const Camera& camera, const std::vector<SceneObject>& sceneObjects, int selectedId = -1, float fovDeg = FOV, float nearPlane = NEAR_PLANE, float farPlane = FAR_PLANE);
|
void renderScene(const Camera& camera, const std::vector<SceneObject>& sceneObjects, int selectedId = -1, float fovDeg = FOV, float nearPlane = NEAR_PLANE, float farPlane = FAR_PLANE, bool drawColliders = false);
|
||||||
unsigned int renderScenePreview(const Camera& camera, const std::vector<SceneObject>& sceneObjects, int width, int height, float fovDeg, float nearPlane, float farPlane, bool applyPostFX = false);
|
unsigned int renderScenePreview(const Camera& camera, const std::vector<SceneObject>& sceneObjects, int width, int height, float fovDeg, float nearPlane, float farPlane, bool applyPostFX = false);
|
||||||
|
void renderCollisionOverlay(const Camera& camera, const std::vector<SceneObject>& sceneObjects, int width, int height, float fovDeg, float nearPlane, float farPlane);
|
||||||
void endRender();
|
void endRender();
|
||||||
|
|
||||||
Skybox* getSkybox() { return skybox; }
|
Skybox* getSkybox() { return skybox; }
|
||||||
|
|||||||
@@ -47,12 +47,34 @@ void Shader::compileShaders(const char* vertexSource, const char* fragmentSource
|
|||||||
glCompileShader(fragment);
|
glCompileShader(fragment);
|
||||||
checkCompileErrors(fragment, "FRAGMENT");
|
checkCompileErrors(fragment, "FRAGMENT");
|
||||||
|
|
||||||
|
int success = 0;
|
||||||
|
glGetShaderiv(vertex, GL_COMPILE_STATUS, &success);
|
||||||
|
if (!success) {
|
||||||
|
glDeleteShader(vertex);
|
||||||
|
glDeleteShader(fragment);
|
||||||
|
ID = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
glGetShaderiv(fragment, GL_COMPILE_STATUS, &success);
|
||||||
|
if (!success) {
|
||||||
|
glDeleteShader(vertex);
|
||||||
|
glDeleteShader(fragment);
|
||||||
|
ID = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
ID = glCreateProgram();
|
ID = glCreateProgram();
|
||||||
glAttachShader(ID, vertex);
|
glAttachShader(ID, vertex);
|
||||||
glAttachShader(ID, fragment);
|
glAttachShader(ID, fragment);
|
||||||
glLinkProgram(ID);
|
glLinkProgram(ID);
|
||||||
checkCompileErrors(ID, "PROGRAM");
|
checkCompileErrors(ID, "PROGRAM");
|
||||||
|
|
||||||
|
glGetProgramiv(ID, GL_LINK_STATUS, &success);
|
||||||
|
if (!success) {
|
||||||
|
glDeleteProgram(ID);
|
||||||
|
ID = 0;
|
||||||
|
}
|
||||||
|
|
||||||
glDeleteShader(vertex);
|
glDeleteShader(vertex);
|
||||||
glDeleteShader(fragment);
|
glDeleteShader(fragment);
|
||||||
}
|
}
|
||||||
|
|||||||
48
src/main.cpp
48
src/main.cpp
@@ -1,7 +1,55 @@
|
|||||||
#include "Engine.h"
|
#include "Engine.h"
|
||||||
|
#include <filesystem>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#if defined(_WIN32)
|
||||||
|
#include <windows.h>
|
||||||
|
#elif defined(__APPLE__)
|
||||||
|
#include <mach-o/dyld.h>
|
||||||
|
#else
|
||||||
|
#include <unistd.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static std::filesystem::path getExecutableDir() {
|
||||||
|
#if defined(_WIN32)
|
||||||
|
char pathBuf[MAX_PATH] = {};
|
||||||
|
DWORD len = GetModuleFileNameA(nullptr, pathBuf, MAX_PATH);
|
||||||
|
if (len == 0 || len == MAX_PATH) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
return std::filesystem::path(pathBuf).parent_path();
|
||||||
|
#elif defined(__APPLE__)
|
||||||
|
uint32_t size = 0;
|
||||||
|
if (_NSGetExecutablePath(nullptr, &size) != -1 || size == 0) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
std::string buf(size, '\0');
|
||||||
|
if (_NSGetExecutablePath(buf.data(), &size) != 0) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
return std::filesystem::path(buf).lexically_normal().parent_path();
|
||||||
|
#else
|
||||||
|
std::vector<char> buf(4096, '\0');
|
||||||
|
ssize_t len = readlink("/proc/self/exe", buf.data(), buf.size() - 1);
|
||||||
|
if (len <= 0) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
buf[static_cast<size_t>(len)] = '\0';
|
||||||
|
return std::filesystem::path(buf.data()).parent_path();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
|
if (auto exeDir = getExecutableDir(); !exeDir.empty()) {
|
||||||
|
std::error_code ec;
|
||||||
|
std::filesystem::current_path(exeDir, ec);
|
||||||
|
if (ec) {
|
||||||
|
std::cerr << "[WARN] Failed to set working dir to executable: "
|
||||||
|
<< ec.message() << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
std::cerr << "[DEBUG] Starting engine initialization..." << std::endl;
|
std::cerr << "[DEBUG] Starting engine initialization..." << std::endl;
|
||||||
Engine engine;
|
Engine engine;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user