diff options
Diffstat (limited to 'src/gl/vertex_array.h')
-rw-r--r-- | src/gl/vertex_array.h | 108 |
1 files changed, 108 insertions, 0 deletions
diff --git a/src/gl/vertex_array.h b/src/gl/vertex_array.h new file mode 100644 index 0000000..5799c60 --- /dev/null +++ b/src/gl/vertex_array.h @@ -0,0 +1,108 @@ +// Copyright 2021 Benjamin Barenblat +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may not +// use this file except in compliance with the License. You may obtain a copy of +// the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +// License for the specific language governing permissions and limitations under +// the License. + +// Vertex array objects. + +#ifndef GLPLANET_SRC_GL_VERTEX_ARRAY_H_ +#define GLPLANET_SRC_GL_VERTEX_ARRAY_H_ + +#include <stdint.h> + +#include <utility> + +#include "src/gl/buffer.h" +#include "src/gl/error.h" +#include "third_party/abseil/absl/types/optional.h" +#include "third_party/glew/include/GL/glew.h" + +namespace gl { + +enum class VertexAttributeType : GLenum { + kByte = GL_BYTE, + kShort = GL_SHORT, + kInt = GL_INT, + kFixed = GL_FIXED, + kFloat = GL_FLOAT, + kHalfFloat = GL_HALF_FLOAT, + kDouble = GL_DOUBLE, + kUnsignedByte = GL_UNSIGNED_BYTE, + kUnsignedShort = GL_UNSIGNED_SHORT, + kUnsignedInt = GL_UNSIGNED_INT, + kInt2x10x10x10Rev = GL_INT_2_10_10_10_REV, + kUnsignedInt2x10x10x10Rev = GL_UNSIGNED_INT_2_10_10_10_REV, + kUnsignedInt10f11f11fRev = GL_UNSIGNED_INT_10F_11F_11F_REV, +}; + +// A VAO. +class VertexArray final { + public: + explicit VertexArray() noexcept(!(gl_internal::kThreadSafetyChecks || + gl_internal::kAggressiveErrorChecking)) { + gl_internal::CheckThreadSafety(); + glCreateVertexArrays(1, &array_); + gl_internal::UnnecessaryErrorCheck(); + } + + VertexArray(VertexArray&&) noexcept = default; + VertexArray& operator=(VertexArray&&) noexcept = default; + + ~VertexArray() noexcept(!(gl_internal::kThreadSafetyChecks || + gl_internal::kAggressiveErrorChecking)) { + gl_internal::CheckThreadSafety(); + glDeleteVertexArrays(1, &array_); + gl_internal::UnnecessaryErrorCheck(); + } + + // Attaches the specified vertex buffer to the VAO. + void SetVertexBuffer(VertexBuffer vertices) { + gl_internal::CheckThreadSafety(); + glVertexArrayVertexBuffer(array_, /*bindingindex=*/0, vertices.id(), + /*offset=*/0, vertices.element_size()); + // This error check is necessary because the elements of the VBO might be + // too large for the implementation to handle. + gl_internal::ErrorCheck(); + vertices_ = std::move(vertices); + } + + // Specifies the organization of data in the attached VAO. + void SetVertexAttributeFormat(int index, int size, VertexAttributeType type, + int offset, bool normalized = false); + + // Attaches the specified element buffer to the VAO. The element buffer must + // outlive this VAO. + void SetElementBuffer(ElementBuffer elements) noexcept( + !(gl_internal::kThreadSafetyChecks || + gl_internal::kAggressiveErrorChecking)) { + gl_internal::CheckThreadSafety(); + glVertexArrayElementBuffer(array_, elements.id()); + gl_internal::UnnecessaryErrorCheck(); + elements_ = std::move(elements); + } + + // Returns the element buffer attached to this VAO. + const ElementBuffer& element_buffer() const noexcept { return elements_; } + + // The GL identifier for this VAO. + unsigned int id() const noexcept { return array_; } + + private: + GLuint array_; + + VertexBuffer vertices_; + ElementBuffer elements_; +}; + +} // namespace gl + +#endif // GLPLANET_SRC_GL_VERTEX_ARRAY_H_ |