summaryrefslogtreecommitdiff
path: root/src/mbgl/gl
diff options
context:
space:
mode:
authorJohn Firebaugh <john.firebaugh@gmail.com>2016-09-26 12:53:32 -0700
committerJohn Firebaugh <john.firebaugh@gmail.com>2016-10-05 10:52:19 -0700
commit7a3bef091e7390fa57bf33f1a704c893768b5625 (patch)
treeaf798d879923fd45e763f5dc5449b7e8419aa192 /src/mbgl/gl
parentac8a74ebccb85f83c40b9fccfeb11dc2cb3c79e4 (diff)
downloadqtlocation-mapboxgl-7a3bef091e7390fa57bf33f1a704c893768b5625.tar.gz
[core] Refactor Buffer
Diffstat (limited to 'src/mbgl/gl')
-rw-r--r--src/mbgl/gl/context.cpp20
-rw-r--r--src/mbgl/gl/context.hpp21
-rw-r--r--src/mbgl/gl/element_group.hpp25
-rw-r--r--src/mbgl/gl/index_buffer.hpp41
-rw-r--r--src/mbgl/gl/vao.cpp61
-rw-r--r--src/mbgl/gl/vao.hpp80
-rw-r--r--src/mbgl/gl/vertex_buffer.hpp17
7 files changed, 256 insertions, 9 deletions
diff --git a/src/mbgl/gl/context.cpp b/src/mbgl/gl/context.cpp
index ded7936feb..5837aa3399 100644
--- a/src/mbgl/gl/context.cpp
+++ b/src/mbgl/gl/context.cpp
@@ -91,10 +91,22 @@ UniqueShader Context::createFragmentShader() {
return UniqueShader{ MBGL_CHECK_ERROR(glCreateShader(GL_FRAGMENT_SHADER)), { this } };
}
-UniqueBuffer Context::createBuffer() {
+UniqueBuffer Context::createVertexBuffer(const void* data, std::size_t size) {
BufferID id = 0;
MBGL_CHECK_ERROR(glGenBuffers(1, &id));
- return UniqueBuffer{ std::move(id), { this } };
+ UniqueBuffer result { std::move(id), { this } };
+ vertexBuffer = result;
+ MBGL_CHECK_ERROR(glBufferData(GL_ARRAY_BUFFER, size, data, GL_STATIC_DRAW));
+ return result;
+}
+
+UniqueBuffer Context::createIndexBuffer(const void* data, std::size_t size) {
+ BufferID id = 0;
+ MBGL_CHECK_ERROR(glGenBuffers(1, &id));
+ UniqueBuffer result { std::move(id), { this } };
+ elementBuffer = result;
+ MBGL_CHECK_ERROR(glBufferData(GL_ELEMENT_ARRAY_BUFFER, size, data, GL_STATIC_DRAW));
+ return result;
}
UniqueTexture Context::createTexture() {
@@ -120,10 +132,6 @@ UniqueFramebuffer Context::createFramebuffer() {
return UniqueFramebuffer{ std::move(id), { this } };
}
-void Context::uploadBuffer(BufferType type, size_t size, void* data) {
- MBGL_CHECK_ERROR(glBufferData(static_cast<GLenum>(type), size, data, GL_STATIC_DRAW));
-}
-
UniqueTexture
Context::createTexture(uint16_t width, uint16_t height, const void* data, TextureUnit unit) {
auto obj = createTexture();
diff --git a/src/mbgl/gl/context.hpp b/src/mbgl/gl/context.hpp
index 0ec846033a..e26b35e7c0 100644
--- a/src/mbgl/gl/context.hpp
+++ b/src/mbgl/gl/context.hpp
@@ -4,6 +4,8 @@
#include <mbgl/gl/state.hpp>
#include <mbgl/gl/value.hpp>
#include <mbgl/gl/texture.hpp>
+#include <mbgl/gl/vertex_buffer.hpp>
+#include <mbgl/gl/index_buffer.hpp>
#include <mbgl/util/noncopyable.hpp>
#include <memory>
@@ -22,12 +24,24 @@ public:
UniqueProgram createProgram();
UniqueShader createVertexShader();
UniqueShader createFragmentShader();
- UniqueBuffer createBuffer();
UniqueTexture createTexture();
UniqueVertexArray createVertexArray();
UniqueFramebuffer createFramebuffer();
- void uploadBuffer(BufferType, size_t, void*);
+ template <class V>
+ VertexBuffer<V> createVertexBuffer(std::vector<V>&& v) {
+ return VertexBuffer<V> {
+ v.size(),
+ createVertexBuffer(v.data(), v.size() * sizeof(V))
+ };
+ }
+
+ template <class P>
+ IndexBuffer<P> createIndexBuffer(std::vector<P>&& v) {
+ return IndexBuffer<P> {
+ createIndexBuffer(v.data(), v.size() * sizeof(P))
+ };
+ }
// Create a texture from an image with data.
template <typename Image>
@@ -98,9 +112,10 @@ public:
State<value::BindVertexArray> vertexArrayObject;
private:
+ UniqueBuffer createVertexBuffer(const void* data, std::size_t size);
+ UniqueBuffer createIndexBuffer(const void* data, std::size_t size);
UniqueTexture createTexture(uint16_t width, uint16_t height, const void* data, TextureUnit);
-private:
friend detail::ProgramDeleter;
friend detail::ShaderDeleter;
friend detail::BufferDeleter;
diff --git a/src/mbgl/gl/element_group.hpp b/src/mbgl/gl/element_group.hpp
new file mode 100644
index 0000000000..f99a03b679
--- /dev/null
+++ b/src/mbgl/gl/element_group.hpp
@@ -0,0 +1,25 @@
+#pragma once
+
+#include <mbgl/gl/vao.hpp>
+#include <mbgl/util/noncopyable.hpp>
+
+#include <array>
+
+namespace mbgl {
+namespace gl {
+
+template <uint8_t count>
+struct ElementGroup : public util::noncopyable {
+ std::array<VertexArrayObject, count> array;
+ uint32_t vertex_length;
+ uint32_t elements_length;
+
+ ElementGroup(uint32_t vertex_length_ = 0, uint32_t elements_length_ = 0)
+ : vertex_length(vertex_length_)
+ , elements_length(elements_length_)
+ {
+ }
+};
+
+} // namespace gl
+} // namespace mbgl
diff --git a/src/mbgl/gl/index_buffer.hpp b/src/mbgl/gl/index_buffer.hpp
new file mode 100644
index 0000000000..f38d7fd4f5
--- /dev/null
+++ b/src/mbgl/gl/index_buffer.hpp
@@ -0,0 +1,41 @@
+#pragma once
+
+#include <mbgl/gl/object.hpp>
+
+namespace mbgl {
+namespace gl {
+
+class Line {
+public:
+ Line(uint16_t a_, uint16_t b_)
+ : a(a_), b(b_) {}
+
+ uint16_t a;
+ uint16_t b;
+
+ static constexpr std::size_t IndexCount = 2;
+};
+
+class Triangle {
+public:
+ Triangle(uint16_t a_, uint16_t b_, uint16_t c_)
+ : a(a_), b(b_), c(c_) {}
+
+ uint16_t a;
+ uint16_t b;
+ uint16_t c;
+
+ static constexpr std::size_t IndexCount = 3;
+};
+
+template <class Primitive>
+class IndexBuffer {
+public:
+ static_assert(std::is_same<Primitive, Line>::value || std::is_same<Primitive, Triangle>::value,
+ "primitive must be Line or Triangle");
+ static constexpr std::size_t primitiveSize = sizeof(Primitive);
+ UniqueBuffer buffer;
+};
+
+} // namespace gl
+} // namespace mbgl
diff --git a/src/mbgl/gl/vao.cpp b/src/mbgl/gl/vao.cpp
new file mode 100644
index 0000000000..527dd214fb
--- /dev/null
+++ b/src/mbgl/gl/vao.cpp
@@ -0,0 +1,61 @@
+#include <mbgl/gl/vao.hpp>
+#include <mbgl/gl/vertex_array.hpp>
+#include <mbgl/platform/log.hpp>
+#include <mbgl/util/string.hpp>
+#include <mbgl/gl/gl.hpp>
+
+namespace mbgl {
+
+VertexArrayObject::VertexArrayObject() {
+}
+
+VertexArrayObject::~VertexArrayObject() = default;
+
+void VertexArrayObject::bindVertexArrayObject(gl::Context& context) {
+ if (!gl::GenVertexArrays || !gl::BindVertexArray) {
+ static bool reported = false;
+ if (!reported) {
+ Log::Warning(Event::OpenGL, "Not using Vertex Array Objects");
+ reported = true;
+ }
+ return;
+ }
+
+ if (!vertexArray) {
+ vertexArray = context.createVertexArray();
+ context.vertexBuffer.setDirty();
+ context.elementBuffer.setDirty();
+ }
+
+ context.vertexArrayObject = *vertexArray;
+}
+
+void VertexArrayObject::verifyBinding(Shader& shader,
+ gl::BufferID vertexBuffer,
+ gl::BufferID elementsBuffer,
+ int8_t* offset) {
+ if (bound_shader != shader.getID()) {
+ throw std::runtime_error(std::string("trying to rebind VAO to another shader from " +
+ util::toString(bound_shader) + "(" + bound_shader_name + ") to " +
+ util::toString(shader.getID()) + "(" + shader.name + ")" ));
+ } else if (bound_offset != offset) {
+ throw std::runtime_error("trying to bind VAO to another offset");
+ } else if (bound_vertex_buffer != vertexBuffer) {
+ throw std::runtime_error("trying to bind VAO to another vertex buffer");
+ } else if (bound_elements_buffer != elementsBuffer) {
+ throw std::runtime_error("trying to bind VAO to another elements buffer");
+ }
+}
+
+void VertexArrayObject::storeBinding(Shader& shader,
+ gl::BufferID vertexBuffer,
+ gl::BufferID elementsBuffer,
+ int8_t* offset) {
+ bound_shader = shader.getID();
+ bound_shader_name = shader.name;
+ bound_offset = offset;
+ bound_vertex_buffer = vertexBuffer;
+ bound_elements_buffer = elementsBuffer;
+}
+
+} // namespace mbgl
diff --git a/src/mbgl/gl/vao.hpp b/src/mbgl/gl/vao.hpp
new file mode 100644
index 0000000000..c2e3470367
--- /dev/null
+++ b/src/mbgl/gl/vao.hpp
@@ -0,0 +1,80 @@
+#pragma once
+
+#include <mbgl/shader/shader.hpp>
+#include <mbgl/gl/context.hpp>
+#include <mbgl/gl/vertex_buffer.hpp>
+#include <mbgl/util/noncopyable.hpp>
+#include <mbgl/util/optional.hpp>
+
+#include <stdexcept>
+
+namespace mbgl {
+
+class VertexArrayObject : public util::noncopyable {
+public:
+ VertexArrayObject();
+ ~VertexArrayObject();
+
+ template <typename Shader, typename T>
+ void bind(Shader& shader,
+ const gl::VertexBuffer<T>& vertexBuffer,
+ int8_t* offset,
+ gl::Context& context) {
+ bindVertexArrayObject(context);
+ if (bound_shader == 0) {
+ context.vertexBuffer = vertexBuffer.buffer;
+ shader.bind(vertexBuffer, offset);
+ if (vertexArray) {
+ storeBinding(shader, vertexBuffer.buffer, 0, offset);
+ }
+ } else {
+ verifyBinding(shader, vertexBuffer.buffer, 0, offset);
+ }
+ }
+
+ template <typename Shader, typename T, typename P>
+ void bind(Shader& shader,
+ const gl::VertexBuffer<T>& vertexBuffer,
+ const gl::IndexBuffer<P>& indexBuffer,
+ int8_t* offset,
+ gl::Context& context) {
+ bindVertexArrayObject(context);
+ if (bound_shader == 0) {
+ context.vertexBuffer = vertexBuffer.buffer;
+ context.elementBuffer = indexBuffer.buffer;
+ shader.bind(vertexBuffer, offset);
+ if (vertexArray) {
+ storeBinding(shader, vertexBuffer.buffer, indexBuffer.buffer, offset);
+ }
+ } else {
+ verifyBinding(shader, vertexBuffer.buffer, indexBuffer.buffer, offset);
+ }
+ }
+
+ gl::VertexArrayID getID() const {
+ return *vertexArray;
+ }
+
+private:
+ void bindVertexArrayObject(gl::Context&);
+ void storeBinding(Shader& shader,
+ gl::BufferID vertexBuffer,
+ gl::BufferID elementsBuffer,
+ int8_t* offset);
+ void verifyBinding(Shader& shader,
+ gl::BufferID vertexBuffer,
+ gl::BufferID elementsBuffer,
+ int8_t* offset);
+
+ mbgl::optional<gl::UniqueVertexArray> vertexArray;
+
+ // For debug reasons, we're storing the bind information so that we can
+ // detect errors and report
+ gl::ProgramID bound_shader = 0;
+ const char* bound_shader_name = "";
+ gl::BufferID bound_vertex_buffer = 0;
+ gl::BufferID bound_elements_buffer = 0;
+ int8_t *bound_offset = nullptr;
+};
+
+} // namespace mbgl
diff --git a/src/mbgl/gl/vertex_buffer.hpp b/src/mbgl/gl/vertex_buffer.hpp
new file mode 100644
index 0000000000..c77a9a4213
--- /dev/null
+++ b/src/mbgl/gl/vertex_buffer.hpp
@@ -0,0 +1,17 @@
+#pragma once
+
+#include <mbgl/gl/object.hpp>
+
+namespace mbgl {
+namespace gl {
+
+template <class Vertex>
+class VertexBuffer {
+public:
+ static constexpr std::size_t vertexSize = sizeof(Vertex);
+ std::size_t vertexCount;
+ UniqueBuffer buffer;
+};
+
+} // namespace gl
+} // namespace mbgl