122 lines
3.0 KiB
C++
122 lines
3.0 KiB
C++
#pragma once
|
|
|
|
#include <glad/glad.h>
|
|
#include <GLFW/glfw3.h>
|
|
|
|
#include "types.h"
|
|
|
|
static bool glck(const char* call) {
|
|
int err = glGetError();
|
|
if (err == 0) {
|
|
return true;
|
|
} else {
|
|
switch (err) {
|
|
case GL_INVALID_VALUE:
|
|
printf("GL_INVALID_VALUE: %s\n", call);
|
|
break;
|
|
case GL_INVALID_ENUM:
|
|
printf("GL_INVALID_ENUM: %s\n", call);
|
|
break;
|
|
case GL_INVALID_OPERATION:
|
|
printf("GL_INVALID_OPERATION: %s\n", call);
|
|
break;
|
|
default:
|
|
printf("UNKNOWN Error: %s\n", call);
|
|
}
|
|
return false;
|
|
}
|
|
}
|
|
|
|
#define GLCK(a) {a; assert(glck(#a));}
|
|
|
|
class GLMesh {
|
|
unsigned int vertexArrayId, vPositionId, vTexCoordId, vNormalId,
|
|
indexBufferId;
|
|
unsigned int indexCount;
|
|
|
|
public:
|
|
|
|
GLMesh() :
|
|
vertexArrayId(0), vPositionId(0), vTexCoordId(0), vNormalId(0), indexBufferId(
|
|
0), indexCount(0) {
|
|
|
|
}
|
|
|
|
~GLMesh() {
|
|
GLCK(glDeleteBuffers(1, &vPositionId))
|
|
GLCK(glDeleteBuffers(1, &vTexCoordId))
|
|
GLCK(glDeleteBuffers(1, &vNormalId))
|
|
GLCK(glDeleteBuffers(1, &indexBufferId))
|
|
GLCK(glDeleteVertexArrays(1, &vertexArrayId))
|
|
}
|
|
|
|
void create() {
|
|
GLCK(glGenVertexArrays(1, &vertexArrayId))
|
|
GLCK(glGenBuffers(1, &vPositionId))
|
|
GLCK(glGenBuffers(1, &vTexCoordId))
|
|
GLCK(glGenBuffers(1, &vNormalId))
|
|
GLCK(glGenBuffers(1, &indexBufferId))
|
|
}
|
|
|
|
void upload(const Mesh &mesh) {
|
|
printf("upload mesh\n");
|
|
GLCK(glBindVertexArray(vertexArrayId))
|
|
|
|
GLCK(glBindBuffer(GL_ARRAY_BUFFER, vPositionId))
|
|
GLCK(
|
|
glBufferData(GL_ARRAY_BUFFER, mesh.positions.size() * sizeof(glm::vec3), mesh.positions.data(), GL_STATIC_DRAW))
|
|
|
|
GLCK(glBindBuffer(GL_ARRAY_BUFFER, vTexCoordId))
|
|
GLCK(
|
|
glBufferData(GL_ARRAY_BUFFER, mesh.texcoords.size() * sizeof(glm::vec2), mesh.texcoords.data(), GL_STATIC_DRAW))
|
|
|
|
GLCK(glBindBuffer(GL_ARRAY_BUFFER, vNormalId))
|
|
GLCK(
|
|
glBufferData(GL_ARRAY_BUFFER, mesh.normals.size() * sizeof(glm::vec3), mesh.normals.data(), GL_STATIC_DRAW))
|
|
|
|
GLCK(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBufferId))
|
|
GLCK(
|
|
glBufferData(GL_ELEMENT_ARRAY_BUFFER, mesh.indices.size() * sizeof(glm::uvec3), mesh.indices.data(), GL_STATIC_DRAW))
|
|
|
|
GLCK(glBindVertexArray(0))
|
|
|
|
indexCount = mesh.indices.size() * 3;
|
|
}
|
|
|
|
void render() {
|
|
GLCK(glBindVertexArray(vertexArrayId))
|
|
GLCK(
|
|
glDrawElements(GL_TRIANGLES, indexCount, GL_UNSIGNED_INT, (void* ) 0))
|
|
GLCK(glBindVertexArray(0))
|
|
|
|
}
|
|
|
|
bool bindVertexAttrib(GLuint id, GLint loc, GLuint size) const {
|
|
if (loc < 0) {
|
|
GLCK(glDisableVertexAttribArray(loc))
|
|
} else {
|
|
GLCK(glBindBuffer(GL_ARRAY_BUFFER, id))
|
|
GLCK(glEnableVertexAttribArray(loc))
|
|
GLCK(glVertexAttribPointer(loc, // attribute
|
|
size,// size
|
|
GL_FLOAT,// type
|
|
GL_FALSE,// normalized?
|
|
0,// stride
|
|
(void* ) 0// array buffer offset
|
|
))
|
|
}
|
|
return true;
|
|
}
|
|
|
|
void update(int vPositionLoc, int vNormalLoc, int vTexCoordLoc) const {
|
|
GLCK(glBindVertexArray(vertexArrayId))
|
|
|
|
bindVertexAttrib(vPositionId, vPositionLoc, 3);
|
|
bindVertexAttrib(vNormalId, vNormalLoc, 3);
|
|
bindVertexAttrib(vTexCoordId, vTexCoordLoc, 2);
|
|
|
|
GLCK(glBindVertexArray(0))
|
|
}
|
|
};
|
|
|