💿🐜 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.

99 lines
2.6 KiB

  1. /*
  2. * Copyright (C) 2021 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/vertex-array.hpp"
  20. #include "gl/vertex-buffer.hpp"
  21. #include <glad/glad.h>
  22. #include <stdexcept>
  23. #include <string>
  24. namespace gl {
  25. static constexpr GLenum vertex_attribute_type_lut[] =
  26. {
  27. GL_BYTE,
  28. GL_UNSIGNED_BYTE,
  29. GL_SHORT,
  30. GL_UNSIGNED_SHORT,
  31. GL_INT,
  32. GL_UNSIGNED_INT,
  33. GL_HALF_FLOAT,
  34. GL_FLOAT,
  35. GL_DOUBLE
  36. };
  37. vertex_array::vertex_array():
  38. gl_array_id(0)
  39. {
  40. glGenVertexArrays(1, &gl_array_id);
  41. }
  42. vertex_array::~vertex_array()
  43. {
  44. glDeleteVertexArrays(1, &gl_array_id);
  45. }
  46. void vertex_array::bind(attribute_location_type location, const vertex_attribute& attribute)
  47. {
  48. if (attribute.buffer == nullptr)
  49. {
  50. throw std::invalid_argument("Cannot bind vertex attribute that has a null vertex buffer.");
  51. }
  52. if (attribute.components < 1 || attribute.components > 4)
  53. {
  54. throw std::invalid_argument("Cannot bind vertex attribute that has an unsupported number of components (" + std::to_string(attribute.components) + ")");
  55. }
  56. attributes[location] = attribute;
  57. GLenum gl_type = vertex_attribute_type_lut[static_cast<std::size_t>(attribute.type)];
  58. glBindVertexArray(gl_array_id);
  59. glBindBuffer(GL_ARRAY_BUFFER, attribute.buffer->gl_buffer_id);
  60. glVertexAttribPointer(
  61. static_cast<GLuint>(location),
  62. static_cast<GLint>(attribute.components),
  63. gl_type,
  64. GL_FALSE,
  65. static_cast<GLsizei>(attribute.stride),
  66. (const GLvoid*)attribute.offset);
  67. glEnableVertexAttribArray(static_cast<GLuint>(location));
  68. }
  69. void vertex_array::unbind(attribute_location_type location)
  70. {
  71. if (auto it = attributes.find(location); it != attributes.end())
  72. {
  73. glBindVertexArray(gl_array_id);
  74. glDisableVertexAttribArray(static_cast<GLuint>(location));
  75. attributes.erase(it);
  76. }
  77. else
  78. {
  79. throw std::invalid_argument("Non-existent vertex attribute cannot be unbound.");
  80. }
  81. }
  82. const typename vertex_array::attribute_map_type& vertex_array::get_attributes() const
  83. {
  84. return attributes;
  85. }
  86. } // namespace gl