2025-01-19 14:17:36 +01:00

147 lines
3.5 KiB
C++

#pragma once
#include "Color.h"
#include "ShaderUtil.h"
#include "Mesh.h"
#include "Entity.h"
#include <gl/glew.h>
#include <glm/glm.hpp>
#include <glm/ext.hpp>
#include <vector>
struct GLFWwindow;
struct DebugLine {
glm::vec3 positionFirst;
glm::vec3 positionLast;
float lineWidth;
Color color;
};
struct DebugPoint {
glm::vec3 position;
Color color;
};
struct DebugDirection {
glm::vec3 origin;
glm::vec3 direction;
float lineWidth;
Color color;
};
struct DebugVertexData {
glm::vec3 v;
glm::vec3 tangent;
Color color;
float lineWidth;
};
class Debug : public Entity
{
private:
std::vector<DebugLine> _lines;
std::vector<DebugPoint> _points;
GLFWwindow* _window;
GLuint _vba;
GLuint _vbo;
GLuint _shader;
GLuint _uniformViewportRes;
GLuint _uniformModel;
GLuint _uniformView;
GLuint _uniformProjection;
public:
Debug() : Entity(nullptr) { }
Debug(GLFWwindow* window) : Entity(nullptr) {
_window = window;
glGenBuffers(1, &_vbo);
glGenVertexArrays(1, &_vba);
glBindVertexArray(_vba);
glBindBuffer(GL_ARRAY_BUFFER, _vbo);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(DebugVertexData), (void*)offsetof(DebugVertexData, v));
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(DebugVertexData), (void*)offsetof(DebugVertexData, tangent));
glVertexAttribPointer(2, 4, GL_FLOAT, GL_FALSE, sizeof(DebugVertexData), (void*)offsetof(DebugVertexData, color));
glVertexAttribPointer(3, 1, GL_FLOAT, GL_FALSE, sizeof(DebugVertexData), (void*)offsetof(DebugVertexData, lineWidth));
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glEnableVertexAttribArray(2);
glEnableVertexAttribArray(3);
_shader = ShaderUtil::CreateShaderProgram("line.vert", "line.frag");
_uniformViewportRes = glGetUniformLocation(_shader, "uViewportRes");
_uniformModel = glGetUniformLocation(_shader, "model");
_uniformView = glGetUniformLocation(_shader, "view");
_uniformProjection = glGetUniformLocation(_shader, "projection");
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
Instance = this;
}
~Debug() {
glDeleteVertexArrays(1, &_vba);
glDeleteBuffers(1, &_vbo);
glDeleteProgram(_shader);
}
void Render(DefaultUniform& uniform) override;
void RenderLines(DefaultUniform& uniform) const;
static inline Debug* Instance;
void Line(const glm::vec3& positionFirst, const glm::vec3& positionLast, const Color& color) {
_lines.push_back(DebugLine { positionFirst, positionLast, 1.0f, color });
}
void Direction(const glm::vec3& origin, const glm::vec3& direction, const Color& color) {
glm::vec4 capWorldPos = glm::vec4(origin + direction * 1.0f, 1.0f);
_lines.push_back(DebugLine { origin, capWorldPos, 8.0f, color });
glm::vec3 up = glm::vec3(direction[1], direction[2], direction[0]);
glm::vec3 capOffsets[4] = {
glm::vec3( 1.0f, 1.0f, -1.0f),
glm::vec3(-1.0f, 1.0f, -1.0f),
glm::vec3( 1.0f, -1.0f, -1.0f),
glm::vec3(-1.0f, -1.0f, -1.0f)
};
glm::mat4 capLocalTf = glm::lookAt(glm::vec3(capWorldPos), origin, up);
capLocalTf = glm::inverse(capLocalTf);
float extends = 0.05f;
for(const glm::vec3& offset : capOffsets) {
Line(capWorldPos, capLocalTf * glm::vec4(extends * offset, 1.0f), color);
}
}
void Point(const glm::vec3& position, const Color& color) {
for(int axis=0;axis<3;axis++) {
glm::vec3 forward = glm::vec3(0.0f);
forward[axis] = 1.0f;
glm::vec3 lineOrigin = position - forward;
glm::vec3 lineDestinatio = position + forward;
Line(lineOrigin, lineDestinatio, color);
}
}
};