144 lines
No EOL
3.2 KiB
C++
144 lines
No EOL
3.2 KiB
C++
#ifndef _H_LINE_H
|
|
#define _H_LINE_H
|
|
|
|
#include <glad/glad.h>
|
|
#include <glm/glm.hpp>
|
|
#include <glm/gtc/type_ptr.hpp>
|
|
|
|
#include <iostream>
|
|
#include <vector>
|
|
|
|
class Line
|
|
{
|
|
private:
|
|
unsigned VAO, VBO;
|
|
glm::vec4 color;
|
|
public:
|
|
Line(glm::vec3 start, glm::vec3 end)
|
|
{
|
|
float vertices[] = {
|
|
start.x, start.y, start.z,
|
|
end.x, end.y, end.z
|
|
};
|
|
|
|
glGenVertexArrays(1, &VAO);
|
|
glGenBuffers(1, &VBO);
|
|
|
|
glBindVertexArray(VAO);
|
|
glBindBuffer(GL_ARRAY_BUFFER, VBO);
|
|
|
|
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), &vertices, GL_DYNAMIC_DRAW);
|
|
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
|
|
glEnableVertexAttribArray(0);
|
|
|
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
|
glBindVertexArray(0);
|
|
color = glm::vec4(1.0f, 0.0f, 0.0f, 1.0f);
|
|
}
|
|
|
|
void updateVertices(const glm::vec3& origin, const glm::vec3& target)
|
|
{
|
|
float vertices[] = {
|
|
origin.x, origin.y, origin.z,
|
|
target.x, target.y, target.z
|
|
};
|
|
glBindBuffer(GL_ARRAY_BUFFER, VBO);
|
|
float* ptr = (float*)glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);
|
|
if (ptr)
|
|
{
|
|
for (int i = 0; i < sizeof(vertices) / sizeof(vertices[0]); i++)
|
|
{
|
|
ptr[i] = vertices[i];
|
|
}
|
|
glUnmapBuffer(GL_ARRAY_BUFFER);
|
|
}
|
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
|
}
|
|
|
|
void setColor(glm::vec4 color) { this->color = color; }
|
|
|
|
const glm::vec4& getColor() const { return color; }
|
|
|
|
void draw()
|
|
{
|
|
glBindVertexArray(VAO);
|
|
glLineWidth(10.0f);
|
|
glDrawArrays(GL_LINES, 0, 2);
|
|
glBindVertexArray(0);
|
|
}
|
|
~Line()
|
|
{
|
|
glDeleteVertexArrays(1, &VAO);
|
|
glDeleteBuffers(1, &VBO);
|
|
}
|
|
};
|
|
|
|
class LineDrawer {
|
|
public:
|
|
static LineDrawer& getInstance() {
|
|
static LineDrawer instance;
|
|
return instance;
|
|
}
|
|
LineDrawer(LineDrawer const&) = delete;
|
|
void operator=(LineDrawer 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 draw(const glm::mat4& mvp) {
|
|
glUseProgram(programID);
|
|
for (auto& line : lines)
|
|
{
|
|
glUniform4fv(glGetUniformLocation(programID, "Color"), 1, glm::value_ptr(line->getColor()));
|
|
glUniformMatrix4fv(glGetUniformLocation(programID, "mvp"), 1, GL_FALSE, glm::value_ptr(mvp));
|
|
line->draw();
|
|
}
|
|
lines.clear();
|
|
}
|
|
~LineDrawer() {
|
|
glDeleteProgram(programID);
|
|
}
|
|
|
|
private:
|
|
unsigned programID;
|
|
LineDrawer() {
|
|
const char* vertexShader = "#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";
|
|
const char* fragmentShader = "#version 330 core\n"
|
|
"out vec4 FragColor;\n"
|
|
"uniform vec4 Color;\n"
|
|
"void main()\n"
|
|
"{\n"
|
|
"FragColor = Color;\n"
|
|
"}\0";
|
|
unsigned vertexID, fragmentID;
|
|
|
|
vertexID = glCreateShader(GL_VERTEX_SHADER);
|
|
glShaderSource(vertexID, 1, &vertexShader, NULL);
|
|
glCompileShader(vertexID);
|
|
|
|
fragmentID = glCreateShader(GL_FRAGMENT_SHADER);
|
|
glShaderSource(fragmentID, 1, &fragmentShader, NULL);
|
|
glCompileShader(fragmentID);
|
|
|
|
programID = glCreateProgram();
|
|
glAttachShader(programID, vertexID);
|
|
glAttachShader(programID, fragmentID);
|
|
glLinkProgram(programID);
|
|
|
|
glDeleteShader(vertexID);
|
|
glDeleteShader(fragmentID);
|
|
}
|
|
|
|
std::vector<std::shared_ptr<Line>> lines;
|
|
};
|
|
|
|
#endif |