asteroidgen/src/gl.h

129 lines
3.2 KiB
C++

#pragma once
#include <glad/glad.h>
#include <GLFW/glfw3.h>
#include "Mesh.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) {
return false;
} 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 programId) const {
int vPositionLoc, vNormalLoc, vTexCoordLoc;
GLCK(vPositionLoc = glGetAttribLocation(programId, "vPosition"))
GLCK(vTexCoordLoc = glGetAttribLocation(programId, "vTexCoord"))
GLCK(vNormalLoc = glGetAttribLocation(programId, "vNormal"))
GLCK(glBindVertexArray(vertexArrayId))
bindVertexAttrib(vPositionId, vPositionLoc, 3);
bindVertexAttrib(vNormalId, vNormalLoc, 3);
bindVertexAttrib(vTexCoordId, vTexCoordLoc, 2);
GLCK(glBindVertexArray(0))
}
};