#pragma once #include #include #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)) } };