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

98 lines
2.1 KiB
C++

#pragma once
#include <vector>
#include <gl/glew.h>
#include <glm/glm.hpp>
#include <glm/ext.hpp>
#include "Shader.h"
class DefaultUniform {
private:
public:
glm::mat4 model;
glm::mat4 view;
glm::mat4 projection;
};
template<class TVertexData, class TUniform = DefaultUniform>
class Mesh
{
private:
TUniform _uniform;
GLuint _uniformModel;
GLuint _uniformView;
GLuint _uniformProjection;
protected:
std::vector<TVertexData> _vertexData;
GLuint _vba;
GLuint _vbo;
Shader* shader;
bool _isVertexDirty;
public:
TUniform& Uniform() { return _uniform; }
public:
Mesh(Shader* shader) : shader(shader), _isVertexDirty(true) {
shader->Initialize();
glCreateVertexArrays(1, &_vba);
glCreateBuffers(1, &_vbo);
_uniformModel = glGetUniformLocation(shader->Reference(), "model");
_uniformView = glGetUniformLocation(shader->Reference(), "view");
_uniformProjection = glGetUniformLocation(shader->Reference(), "projection");
}
~Mesh() {
glDeleteVertexArrays(1, &_vba);
glDeleteBuffers(1, &_vbo);
}
void AddTriangle(const TVertexData& p0, const TVertexData& p1, const TVertexData& p2) {
_vertexData.push_back(p0);
_vertexData.push_back(p1);
_vertexData.push_back(p2);
_isVertexDirty = true;
}
void AddQuad(const TVertexData& p0, const TVertexData& p1, const TVertexData& p2, const TVertexData& p3) {
AddTriangle(p0, p1, p2);
AddTriangle(p1, p2, p3);
}
virtual void Render(const TUniform& uniform) {
shader->Use();
glUniformMatrix4fv(_uniformModel, 1, GL_FALSE, glm::value_ptr(uniform.model));
glUniformMatrix4fv(_uniformView, 1, GL_FALSE, glm::value_ptr(uniform.view));
glUniformMatrix4fv(_uniformProjection, 1, GL_FALSE, glm::value_ptr(uniform.projection));
glBindVertexArray(_vba);
glBindBuffer(GL_ARRAY_BUFFER, _vbo);
if (_isVertexDirty) {
glBufferData(GL_ARRAY_BUFFER, sizeof(TVertexData) * _vertexData.size(), _vertexData.data(), GL_STATIC_DRAW);
_isVertexDirty = false;
}
glDrawArrays(GL_TRIANGLES, 0, _vertexData.size());
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
shader->Disable();
}
};