181 lines
No EOL
4.5 KiB
C++
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 |