yupplemayham/YuppleMayham/utility/debugdraw.h
2024-06-21 16:59:06 -04:00

181 lines
No EOL
4.5 KiB
C++

#ifndef _H_DEBUGDRAW_H
#define _H_DEBUGDRAW_H
#include <glad/glad.h>
#include <glm/glm.hpp>
#include <glm/gtc/type_ptr.hpp>
#include <iostream>
#include <vector>
struct ShaderSource {
const char* vertexShader;
const char* fragShader;
};
struct ShaderProgram {
unsigned programID;
//uniform locations
unsigned u_MVP, u_Color;
void setup(const ShaderSource& source) {
unsigned vertexID, fragID;
// compile vertex shader
vertexID = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertexID, 1, &source.vertexShader, NULL);
glCompileShader(vertexID);
// compile fragment shader
fragID = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragID, 1, &source.fragShader, NULL);
glCompileShader(fragID);
// link shaders to program
programID = glCreateProgram();
glAttachShader(programID, vertexID);
glAttachShader(programID, fragID);
glLinkProgram(programID);
// delete shaders
glDeleteShader(vertexID);
glDeleteShader(fragID);
// get uniform locations
u_MVP = glGetUniformLocation(programID, "u_MVP");
u_Color = glGetUniformLocation(programID, "u_Color");
}
void use () { if (programID) glUseProgram(programID); }
void setMVP (const float* mvpPointer) { use(); glUniformMatrix4fv(u_MVP, 1, GL_FALSE, mvpPointer); }
void setColor (const float* colorPointer) { use(); glUniform4fv(u_Color, 1, colorPointer); }
void delShader () { glDeleteProgram(programID); }
};
class Circle
{
private:
unsigned VAO, VBO;
glm::mat4 MVP;
glm::vec4 Color;
float radius;
public:
Circle(const glm::vec3& position, float radius);
void setMVP (const glm::mat4& mvp) { MVP = mvp; }
void setColor(const glm::vec4& color) { Color = color; }
const glm::mat4& getMVP () const { return MVP; }
const glm::vec4& getColor() const { return Color; }
void draw();
void updatePosition(const glm::vec3& position);
~Circle();
};
class Line
{
private:
unsigned VAO, VBO;
glm::vec4 color;
public:
Line(glm::vec3 start, glm::vec3 end);
void setColor(glm::vec4 color) { this->color = color; }
const glm::vec4& getColor() const { return color; }
void draw();
void updateVertices(const glm::vec3& origin, const glm::vec3& target);
~Line();
};
class DebugDrawer {
public:
static DebugDrawer& getInstance() {
static DebugDrawer instance;
return instance;
}
DebugDrawer(DebugDrawer const&) = delete;
void operator=(DebugDrawer const&) = delete;
void addLine(const glm::vec3& start, const glm::vec3& end, const glm::vec4& color) {
auto line = std::make_shared<Line>(start, end);
line->setColor(color);
lines.push_back(line);
}
void addCircle(const glm::vec3& position, float radius, const glm::vec4& color) {
auto circle = std::make_shared<Circle>(position, radius);
circle->setColor(color);
circles.push_back(circle);
}
void draw(const glm::mat4& mvp) {
lineProgram.use();
for (auto& line : lines)
{
lineProgram.setMVP(glm::value_ptr(mvp));
lineProgram.setColor(glm::value_ptr(line->getColor()));
line->draw();
}
lines.clear();
circleProgram.use();
for (auto& circle : circles)
{
circleProgram.setMVP(glm::value_ptr(mvp));
circleProgram.setColor(glm::value_ptr(circle->getColor()));
circle->draw();
}
circles.clear();
}
~DebugDrawer() {
lineProgram.delShader();
circleProgram.delShader();
}
private:
std::vector<std::shared_ptr<Line>> lines;
std::vector<std::shared_ptr<Circle>> circles;
DebugDrawer() {
circleProgram.setup(circleSource);
lineProgram.setup(lineSource);
}
ShaderSource circleSource {
// vertex shader program
"#version 330 core\n"
"layout (location = 0) in vec3 aPos;\n"
"layout (location = 1) in float aRadius;\n"
"uniform mat4 u_MVP;\n"
"void main()\n"
"{\n"
"float angle = 2.0 * 3.14159 * float(gl_InstanceID) / 360.0;\n"
"float x = aPos.x + cos(angle) * aRadius;\n"
"float y = aPos.y + sin(angle) * aRadius;\n"
"gl_Position = u_MVP * vec4(x, y, aPos.z, 1.0);\n"
"}\0"
,
// fragment shader program
"#version 330 core\n"
"out vec4 FragColor;\n"
"uniform vec4 u_Color;\n"
"void main()\n"
"{\n"
"FragColor = u_Color;\n"
"}\0"
};
ShaderSource lineSource {
// vertex shader
"#version 330 core\n"
"layout (location = 0) in vec3 aPos;\n"
"uniform mat4 mvp;\n"
"void main()\n"
"{\n"
"gl_Position = mvp * vec4(aPos, 1.0);\n"
"}\0"
,
// fragment shader
"#version 330 core\n"
"out vec4 FragColor;\n"
"uniform vec4 Color;\n"
"void main()\n"
"{\n"
"FragColor = Color;\n"
"}\0"
};
ShaderProgram circleProgram;
ShaderProgram lineProgram;
};
#endif