Skip to content
This repository has been archived by the owner on Aug 8, 2023. It is now read-only.

Commit

Permalink
[core] Use gl::Program to resolve some rough edges in the GL binding …
Browse files Browse the repository at this point in the history
…types

* Extract `ignore` util to separate header.
* `Segment` now tracks offset and length of indices, rather than primitives. This is more natural.
* Introduce `VertexVector` and `IndexVector` types. These types carry information about the intended draw mode (`Triangles`, `LineStrip`, etc.), and ensure that elements are always appended in a group size appropriate for that draw mode, for both indexed and unindexed rendering.
* `Program`, rather than `Drawable`, is now the unifying object for draw calls. `Program` is the best place to type check the draw call, because it is typed to carry information about the intended primitive, vertex type, attributes, and uniforms.
* Use the debug shaders for debug tile rendering, like gl-js.
* Fix the draw mode for background. It was drawing triangle strips with a triangles array. Surprised this didn’t cause issues. Now it’s type checked.
  • Loading branch information
jfirebaugh committed Nov 3, 2016
1 parent 507f114 commit 8d201ab
Show file tree
Hide file tree
Showing 42 changed files with 472 additions and 359 deletions.
3 changes: 2 additions & 1 deletion cmake/core-files.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -66,14 +66,14 @@ set(MBGL_CORE_FILES
src/mbgl/gl/depth_mode.cpp
src/mbgl/gl/depth_mode.hpp
src/mbgl/gl/draw_mode.hpp
src/mbgl/gl/drawable.hpp
src/mbgl/gl/extension.cpp
src/mbgl/gl/extension.hpp
src/mbgl/gl/framebuffer.hpp
src/mbgl/gl/gl.cpp
src/mbgl/gl/index_buffer.hpp
src/mbgl/gl/object.cpp
src/mbgl/gl/object.hpp
src/mbgl/gl/primitives.hpp
src/mbgl/gl/program.hpp
src/mbgl/gl/renderbuffer.hpp
src/mbgl/gl/segment.hpp
Expand Down Expand Up @@ -155,6 +155,7 @@ set(MBGL_CORE_FILES
src/mbgl/programs/circle_program.hpp
src/mbgl/programs/collision_box_program.cpp
src/mbgl/programs/collision_box_program.hpp
src/mbgl/programs/debug_program.hpp
src/mbgl/programs/fill_program.cpp
src/mbgl/programs/fill_program.hpp
src/mbgl/programs/line_program.cpp
Expand Down
16 changes: 7 additions & 9 deletions src/mbgl/gl/attribute.hpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#pragma once

#include <mbgl/gl/types.hpp>
#include <mbgl/util/ignore.hpp>

#include <cstddef>
#include <functional>
Expand Down Expand Up @@ -157,17 +158,14 @@ class Attributes {
template <std::size_t... Is>
static std::function<void (std::size_t)> binder(const State& state, std::index_sequence<Is...>) {
return [&state] (std::size_t vertexOffset) {
noop((bindAttribute(std::get<Is>(state).location,
std::get<Is>(state).count,
std::get<Is>(state).type,
sizeof(Vertex),
vertexOffset,
Vertex::attributeOffsets[Is]), 0)...);
ignore((bindAttribute(std::get<Is>(state).location,
std::get<Is>(state).count,
std::get<Is>(state).type,
sizeof(Vertex),
vertexOffset,
Vertex::attributeOffsets[Is]), 0)...);
};
}

// This exists only to provide a varags context for unpacking the assignments in `binder`.
template <int...> static void noop(int...) {}
};

} // namespace gl
Expand Down
4 changes: 2 additions & 2 deletions src/mbgl/gl/context.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -492,9 +492,9 @@ void Context::draw(const Drawable& drawable) {
if (drawable.indexBuffer) {
MBGL_CHECK_ERROR(glDrawElements(
static_cast<GLenum>(primitiveType),
static_cast<GLsizei>(drawable.primitiveSize / sizeof(uint16_t) * segment.primitiveLength),
static_cast<GLsizei>(segment.indexLength),
GL_UNSIGNED_SHORT,
reinterpret_cast<GLvoid*>(drawable.primitiveSize * segment.primitiveOffset)));
reinterpret_cast<GLvoid*>(sizeof(uint16_t) * segment.indexOffset)));
} else {
MBGL_CHECK_ERROR(glDrawArrays(
static_cast<GLenum>(primitiveType),
Expand Down
40 changes: 30 additions & 10 deletions src/mbgl/gl/context.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,16 @@
#include <mbgl/gl/framebuffer.hpp>
#include <mbgl/gl/vertex_buffer.hpp>
#include <mbgl/gl/index_buffer.hpp>
#include <mbgl/gl/drawable.hpp>
#include <mbgl/gl/types.hpp>
#include <mbgl/gl/draw_mode.hpp>
#include <mbgl/gl/depth_mode.hpp>
#include <mbgl/gl/stencil_mode.hpp>
#include <mbgl/gl/color_mode.hpp>
#include <mbgl/gl/segment.hpp>
#include <mbgl/util/noncopyable.hpp>


#include <functional>
#include <memory>
#include <vector>
#include <array>
Expand All @@ -33,18 +40,18 @@ class Context : private util::noncopyable {
UniqueProgram createProgram(ShaderID vertexShader, ShaderID fragmentShader);
UniqueTexture createTexture();

template <class V>
VertexBuffer<V> createVertexBuffer(std::vector<V>&& v) {
return VertexBuffer<V> {
v.size(),
createVertexBuffer(v.data(), v.size() * sizeof(V))
template <class Vertex, class DrawMode>
VertexBuffer<Vertex, DrawMode> createVertexBuffer(VertexVector<Vertex, DrawMode>&& v) {
return VertexBuffer<Vertex, DrawMode> {
v.vertexSize(),
createVertexBuffer(v.data(), v.byteSize())
};
}

template <class P>
IndexBuffer<P> createIndexBuffer(std::vector<P>&& v) {
return IndexBuffer<P> {
createIndexBuffer(v.data(), v.size() * sizeof(P))
template <class DrawMode>
IndexBuffer<DrawMode> createIndexBuffer(IndexVector<DrawMode>&& v) {
return IndexBuffer<DrawMode> {
createIndexBuffer(v.data(), v.byteSize())
};
}

Expand Down Expand Up @@ -94,6 +101,19 @@ class Context : private util::noncopyable {
optional<float> depth,
optional<int32_t> stencil);

struct Drawable {
DrawMode drawMode;
DepthMode depthMode;
StencilMode stencilMode;
ColorMode colorMode;
gl::ProgramID program;
gl::BufferID vertexBuffer;
gl::BufferID indexBuffer;
const std::vector<Segment>& segments;
std::function<void ()> bindUniforms;
std::function<void (std::size_t)> bindAttributes;
};

void draw(const Drawable&);

void setDepthMode(const DepthMode&);
Expand Down
34 changes: 32 additions & 2 deletions src/mbgl/gl/draw_mode.hpp
Original file line number Diff line number Diff line change
@@ -1,27 +1,57 @@
#pragma once

#include <mbgl/gl/primitives.hpp>
#include <mbgl/util/variant.hpp>

namespace mbgl {
namespace gl {

class Points {
public:
using Primitive = Point;
static constexpr std::size_t bufferGroupSize = 1;

float pointSize;
};

class Lines {
public:
using Primitive = Line;
static constexpr std::size_t bufferGroupSize = 2;

float lineWidth;
};

class LineStrip {
public:
// LineStrip is a form of "Line" rendering, but the element buffer
// cannot be grouped into logical elements beyond a single Point.
using Primitive = Line;
static constexpr std::size_t bufferGroupSize = 1;

float lineWidth;
};

class Triangles {};
class TriangleStrip {};
class Triangles {
public:
using Primitive = Triangle;
static constexpr std::size_t bufferGroupSize = 3;
};

class TriangleStrip {
public:
// TriangleStrip is a form of "Triangle" rendering, but the element buffer
// cannot be grouped into logical elements beyond a single Point.
using Primitive = Triangle;
static constexpr std::size_t bufferGroupSize = 1;
};

// Special draw mode for use with VertexVector<Indexed, Vertex>, in which
// case the true draw mode is denoted by the IndexVector type.
class Indexed {
public:
static constexpr std::size_t bufferGroupSize = 1;
};

using DrawMode = variant<
Points,
Expand Down
124 changes: 0 additions & 124 deletions src/mbgl/gl/drawable.hpp

This file was deleted.

38 changes: 18 additions & 20 deletions src/mbgl/gl/index_buffer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,39 +2,37 @@

#include <mbgl/gl/object.hpp>
#include <mbgl/gl/draw_mode.hpp>
#include <mbgl/util/ignore.hpp>

#include <vector>

namespace mbgl {
namespace gl {

class Line {
template <class DrawMode>
class IndexVector {
public:
using DrawMode = Lines;

Line(uint16_t a_, uint16_t b_)
: a(a_), b(b_) {}
static constexpr std::size_t groupSize = DrawMode::bufferGroupSize;

uint16_t a;
uint16_t b;
};
template <class... Args>
void emplace_back(Args&&... args) {
static_assert(sizeof...(args) == groupSize, "wrong buffer element count");
ignore({(v.emplace_back(std::forward<Args>(args)), 0)...});
}

class Triangle {
public:
using DrawMode = Triangles;
std::size_t indexSize() const { return v.size(); }
std::size_t byteSize() const { return v.size() * sizeof(uint16_t); }

Triangle(uint16_t a_, uint16_t b_, uint16_t c_)
: a(a_), b(b_), c(c_) {}
bool empty() const { return v.empty(); }
const uint16_t* data() const { return v.data(); }

uint16_t a;
uint16_t b;
uint16_t c;
private:
std::vector<uint16_t> v;
};

template <class Primitive>
template <class DrawMode>
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;
};

Expand Down
22 changes: 22 additions & 0 deletions src/mbgl/gl/primitives.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#pragma once

namespace mbgl {
namespace gl {

class Point {
public:
static constexpr std::size_t vertexCount = 1;
};

class Line {
public:
static constexpr std::size_t vertexCount = 2;
};

class Triangle {
public:
static constexpr std::size_t vertexCount = 3;
};

} // namespace gl
} // namespace mbgl
Loading

0 comments on commit 8d201ab

Please sign in to comment.