// // opengl_renderer.cxx // graphics // // Created by Sam Jaffe on 5/20/19. // Copyright © 2019 Sam Jaffe. All rights reserved. // #include "renderer_impl.hpp" #ifdef __APPLE__ #include #endif #include "game/graphics/material.hpp" #include "game/graphics/vertex.h" #include "matrix/matrix.hpp" #include "matrix/matrix_helpers.hpp" using namespace graphics; class opengl_renderer : public renderer_impl { public: opengl_renderer(); ~opengl_renderer(); void draw(flyweight, math::matr4 const &, std::vector const &) override; void clear() override; void flush() override; private: const math::matr4 identity{math::matrix::identity()}; math::matr4 world_to_clip{identity}; double current_time{0.0}; unsigned int vertex_array_object{0}, vertex_buffer_object{0}; }; opengl_renderer::opengl_renderer() { glGenVertexArrays(1, &vertex_array_object); glBindVertexArray(vertex_array_object); glGenBuffers(1, &vertex_buffer_object); glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer_object); } opengl_renderer::~opengl_renderer() { glDeleteBuffers(1, &vertex_buffer_object); glDeleteVertexArrays(1, &vertex_array_object); } void opengl_renderer::clear() { world_to_clip = identity; // vec2i resolution = env::resolution(); // orthogonal_view(0.0, resolution[0], 0.0, resolution[1], -1.0, 1.0); glClearDepth(1.f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glClearColor(0.f, 0.f, 0.0f, 1.f); glEnable(GL_DEPTH_TEST); // TODO: Use a unified time calculation current_time = time(NULL); // TODO: ??? // scale(0.5, 0.5, 1); // Don't know why I need to do this } void opengl_renderer::flush() { glFlush(); } void opengl_renderer::draw(flyweight material, math::matr4 const & object_to_world, std::vector const & vertices) { // TODO: Don't activate here? auto const & mat = material.actual(); // TODO: Attatch shader-id to material-id unsigned int const id = mat.shaders.id; mat.activate(); int objectLocation = glGetUniformLocation(id, "u_objectToWorldMatrix"); glUniformMatrix4fv(objectLocation, 1, false, &object_to_world(0, 0)); int clipLocation = glGetUniformLocation(id, "u_worldToClipMatrix"); glUniformMatrix4fv(clipLocation, 1, false, &world_to_clip(0, 0)); int timeLocation = glGetUniformLocation(id, "u_time"); glUniform1d(timeLocation, current_time); // TODO: Cache attribute locations int positionLocation = glGetAttribLocation(id, "a_position"); int colorLocation = glGetAttribLocation(id, "a_color"); int texCoordsLocation = glGetAttribLocation(id, "a_texCoords"); glEnableVertexAttribArray(positionLocation); glEnableVertexAttribArray(colorLocation); glEnableVertexAttribArray(texCoordsLocation); glVertexAttribPointer(positionLocation, 2, GL_FLOAT, GL_FALSE, sizeof(vertex), &vertices[0].position); glVertexAttribPointer(colorLocation, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(vertex), &vertices[0].color); glVertexAttribPointer(texCoordsLocation, 2, GL_FLOAT, GL_FALSE, sizeof(vertex), &vertices[0].texture_coords); glDrawArrays(GL_TRIANGLES, 0, static_cast(vertices.size())); glDisableVertexAttribArray(positionLocation); glDisableVertexAttribArray(colorLocation); glDisableVertexAttribArray(texCoordsLocation); } template <> renderer_impl * graphics::get_renderer_impl() { static opengl_renderer impl; return &impl; }