opengl_renderer.cxx 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. //
  2. // opengl_renderer.cxx
  3. // graphics
  4. //
  5. // Created by Sam Jaffe on 5/20/19.
  6. // Copyright © 2019 Sam Jaffe. All rights reserved.
  7. //
  8. #include "opengl_renderer.h"
  9. #ifdef __APPLE__
  10. #include <OpenGL/gl3.h>
  11. #endif
  12. #include "game/graphics/manager.hpp"
  13. #include "game/graphics/material.hpp"
  14. #include "game/graphics/vertex.h"
  15. #include "game/util/env.hpp"
  16. #include "game/util/time.hpp"
  17. #include "matrix.hpp"
  18. #include "matrix/matrix.hpp"
  19. #include "matrix/matrix_helpers.hpp"
  20. using namespace graphics;
  21. opengl_renderer::opengl_renderer()
  22. : mgr(new opengl_manager), active_material(0) {
  23. glGenVertexArrays(1, &vertex_array_object);
  24. glBindVertexArray(vertex_array_object);
  25. glGenBuffers(1, &vertex_buffer_object);
  26. glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer_object);
  27. }
  28. opengl_renderer::~opengl_renderer() {
  29. glDeleteBuffers(1, &vertex_buffer_object);
  30. glDeleteVertexArrays(1, &vertex_array_object);
  31. }
  32. void opengl_renderer::clear() {
  33. world_to_clip = identity;
  34. math::vec2i resolution = env::screen_size();
  35. world_to_clip = graphics::orthogonal_view(0.f, resolution[0], 0.f,
  36. resolution[1], -1.f, 1.f);
  37. glClearDepth(1.f);
  38. glClearColor(0.f, 0.f, 0.0f, 1.f);
  39. glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  40. glEnable(GL_DEPTH_TEST);
  41. current_time = env::clock::current_time<double>();
  42. // TODO (sjaffe): I labeled this as needed before, but I don't know why
  43. // I think it has to do with the resolution being 2x the screen size
  44. // static auto const rescale = make_vector(0.5f, 0.5f, 1.f);
  45. // world_to_clip = world_to_clip * math::matrix::scalar(rescale);
  46. }
  47. void opengl_renderer::flush() { glFlush(); }
  48. void opengl_renderer::draw(::identity<material> material_id,
  49. math::matr4 const & object_to_world,
  50. std::vector<vertex> const & vertices) {
  51. material const & mat = manager()->get(material_id);
  52. activate(mat);
  53. // TODO: Attatch shader-id to material-id
  54. unsigned int const id = mat.program.id;
  55. int objectLocation = glGetUniformLocation(id, "u_objectToWorldMatrix");
  56. // Argument 2: GL_TRUE -> row-major ; GL_FALSE -> column-major
  57. glUniformMatrix4fv(objectLocation, 1, GL_TRUE, &object_to_world(0, 0));
  58. int clipLocation = glGetUniformLocation(id, "u_worldToClipMatrix");
  59. glUniformMatrix4fv(clipLocation, 1, GL_TRUE, &world_to_clip(0, 0));
  60. int timeLocation = glGetUniformLocation(id, "u_time");
  61. glUniform1d(timeLocation, current_time);
  62. // TODO: Cache attribute locations
  63. int positionLocation = glGetAttribLocation(id, "a_position");
  64. int colorLocation = glGetAttribLocation(id, "a_color");
  65. int texCoordsLocation = glGetAttribLocation(id, "a_texCoords");
  66. glEnableVertexAttribArray(positionLocation);
  67. glEnableVertexAttribArray(colorLocation);
  68. glEnableVertexAttribArray(texCoordsLocation);
  69. glVertexAttribPointer(positionLocation, 2, GL_FLOAT, GL_FALSE, sizeof(vertex),
  70. &vertices[0].position);
  71. glVertexAttribPointer(colorLocation, 4, GL_UNSIGNED_BYTE, GL_TRUE,
  72. sizeof(vertex), &vertices[0].color);
  73. glVertexAttribPointer(texCoordsLocation, 2, GL_FLOAT, GL_FALSE,
  74. sizeof(vertex), &vertices[0].texture_coords);
  75. glDrawArrays(GL_TRIANGLES, 0, static_cast<GLsizei>(vertices.size()));
  76. glDisableVertexAttribArray(positionLocation);
  77. glDisableVertexAttribArray(colorLocation);
  78. glDisableVertexAttribArray(texCoordsLocation);
  79. }
  80. void opengl_renderer::activate(material const & mat) {
  81. if (mat.id == active_material) return;
  82. glUseProgram(mat.program.id);
  83. for (unsigned int i = 0; i < mat.uniforms.size(); i++) {
  84. const uniform & uniform = mat.uniforms[i];
  85. glActiveTexture(i + GL_TEXTURE0);
  86. // glEnable(GL_TEXTURE_2D);
  87. glBindTexture(GL_TEXTURE_2D, uniform.texture.id);
  88. glUniform1i(uniform.uniform_id, i);
  89. }
  90. glActiveTexture(GL_TEXTURE0);
  91. }
  92. template <> renderer_impl * graphics::get_renderer_impl<driver::openGL>() {
  93. static opengl_renderer impl;
  94. return &impl;
  95. }