💿🐜 Antkeeper source code https://antkeeper.com
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

169 lines
4.2 KiB

  1. /*
  2. * Copyright (C) 2023 Christopher J. Howard
  3. *
  4. * This file is part of Antkeeper source code.
  5. *
  6. * Antkeeper source code is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation, either version 3 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * Antkeeper source code is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with Antkeeper source code. If not, see <http://www.gnu.org/licenses/>.
  18. */
  19. #include "gl/rasterizer.hpp"
  20. #include "gl/framebuffer.hpp"
  21. #include "gl/shader-program.hpp"
  22. #include "gl/vertex-array.hpp"
  23. #include <glad/glad.h>
  24. namespace gl {
  25. static constexpr GLenum drawing_mode_lut[] =
  26. {
  27. GL_POINTS,
  28. GL_LINE_STRIP,
  29. GL_LINE_LOOP,
  30. GL_LINES,
  31. GL_LINE_STRIP_ADJACENCY,
  32. GL_LINES_ADJACENCY,
  33. GL_TRIANGLE_STRIP,
  34. GL_TRIANGLE_FAN,
  35. GL_TRIANGLES,
  36. GL_TRIANGLE_STRIP_ADJACENCY,
  37. GL_TRIANGLES_ADJACENCY
  38. };
  39. static constexpr GLenum element_array_type_lut[] =
  40. {
  41. GL_UNSIGNED_BYTE,
  42. GL_UNSIGNED_SHORT,
  43. GL_UNSIGNED_INT
  44. };
  45. rasterizer::rasterizer():
  46. bound_vao(nullptr),
  47. bound_shader_program(nullptr)
  48. {
  49. // Determine dimensions of default framebuffer
  50. GLint scissor_box[4] = {0, 0, 0, 0};
  51. glGetIntegerv(GL_SCISSOR_BOX, scissor_box);
  52. // Setup default framebuffer
  53. default_framebuffer = new framebuffer();
  54. default_framebuffer->gl_framebuffer_id = 0;
  55. default_framebuffer->dimensions = {scissor_box[2], scissor_box[3]};
  56. // Bind default framebuffer
  57. bound_framebuffer = default_framebuffer;
  58. }
  59. rasterizer::~rasterizer()
  60. {
  61. delete default_framebuffer;
  62. }
  63. void rasterizer::context_resized(int width, int height)
  64. {
  65. default_framebuffer->dimensions = {width, height};
  66. }
  67. void rasterizer::use_framebuffer(const gl::framebuffer& framebuffer)
  68. {
  69. if (bound_framebuffer != &framebuffer)
  70. {
  71. glBindFramebuffer(GL_FRAMEBUFFER, framebuffer.gl_framebuffer_id);
  72. bound_framebuffer = &framebuffer;
  73. }
  74. }
  75. void rasterizer::set_clear_color(float r, float g, float b, float a)
  76. {
  77. glClearColor(r, g, b, a);
  78. }
  79. void rasterizer::set_clear_depth(float depth)
  80. {
  81. glClearDepth(depth);
  82. }
  83. void rasterizer::set_clear_stencil(int s)
  84. {
  85. glClearStencil(s);
  86. }
  87. void rasterizer::clear_framebuffer(bool color, bool depth, bool stencil)
  88. {
  89. GLbitfield mask = 0;
  90. if (color)
  91. mask |= GL_COLOR_BUFFER_BIT;
  92. if (depth)
  93. mask |= GL_DEPTH_BUFFER_BIT;
  94. if (stencil)
  95. mask |= GL_STENCIL_BUFFER_BIT;
  96. glClear(mask);
  97. }
  98. void rasterizer::set_viewport(int x, int y, int width, int height)
  99. {
  100. glViewport(x, y, static_cast<GLsizei>(width), static_cast<GLsizei>(height));
  101. }
  102. void rasterizer::use_program(const shader_program& program)
  103. {
  104. if (bound_shader_program != &program)
  105. {
  106. glUseProgram(program.gl_program_id);
  107. bound_shader_program = &program;
  108. }
  109. }
  110. void rasterizer::draw_arrays(const vertex_array& vao, drawing_mode mode, std::size_t offset, std::size_t count)
  111. {
  112. GLenum gl_mode = drawing_mode_lut[static_cast<std::size_t>(mode)];
  113. if (bound_vao != &vao)
  114. {
  115. glBindVertexArray(vao.gl_array_id);
  116. bound_vao = &vao;
  117. }
  118. glDrawArrays(gl_mode, static_cast<GLint>(offset), static_cast<GLsizei>(count));
  119. }
  120. void rasterizer::draw_arrays_instanced(const vertex_array& vao, drawing_mode mode, std::size_t offset, std::size_t count, std::size_t instance_count)
  121. {
  122. GLenum gl_mode = drawing_mode_lut[static_cast<std::size_t>(mode)];
  123. if (bound_vao != &vao)
  124. {
  125. glBindVertexArray(vao.gl_array_id);
  126. bound_vao = &vao;
  127. }
  128. glDrawArraysInstanced(gl_mode, static_cast<GLint>(offset), static_cast<GLsizei>(count), static_cast<GLsizei>(instance_count));
  129. }
  130. void rasterizer::draw_elements(const vertex_array& vao, drawing_mode mode, std::size_t offset, std::size_t count, element_array_type type)
  131. {
  132. GLenum gl_mode = drawing_mode_lut[static_cast<std::size_t>(mode)];
  133. GLenum gl_type = element_array_type_lut[static_cast<std::size_t>(type)];
  134. if (bound_vao != &vao)
  135. {
  136. glBindVertexArray(vao.gl_array_id);
  137. bound_vao = &vao;
  138. }
  139. glDrawElements(gl_mode, static_cast<GLsizei>(count), gl_type, (const GLvoid*)offset);
  140. }
  141. } // namespace gl