#pragma once #include "Color.h" #include "ShaderUtil.h" #include "Mesh.h" #include "Entity.h" #include #include #include #include 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 _lines; std::vector _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); } } };