diff options
author | John Firebaugh <john.firebaugh@gmail.com> | 2016-09-30 12:20:29 -0700 |
---|---|---|
committer | John Firebaugh <john.firebaugh@gmail.com> | 2016-10-05 10:52:19 -0700 |
commit | 73334ac8fa330af05dd91906a4e5d1bbda7d5c34 (patch) | |
tree | aeba3681352926e5837d2d68b70a08f52d6ed026 /src/mbgl/gl | |
parent | 7a3bef091e7390fa57bf33f1a704c893768b5625 (diff) | |
download | qtlocation-mapboxgl-73334ac8fa330af05dd91906a4e5d1bbda7d5c34.tar.gz |
[core] Move shader and uniform to gl directory
Diffstat (limited to 'src/mbgl/gl')
-rw-r--r-- | src/mbgl/gl/shader.cpp | 116 | ||||
-rw-r--r-- | src/mbgl/gl/shader.hpp | 51 | ||||
-rw-r--r-- | src/mbgl/gl/uniform.cpp | 57 | ||||
-rw-r--r-- | src/mbgl/gl/uniform.hpp | 61 | ||||
-rw-r--r-- | src/mbgl/gl/vao.cpp | 4 | ||||
-rw-r--r-- | src/mbgl/gl/vao.hpp | 6 |
6 files changed, 290 insertions, 5 deletions
diff --git a/src/mbgl/gl/shader.cpp b/src/mbgl/gl/shader.cpp new file mode 100644 index 0000000000..5b3712e80d --- /dev/null +++ b/src/mbgl/gl/shader.cpp @@ -0,0 +1,116 @@ +#include <mbgl/gl/shader.hpp> +#include <mbgl/gl/gl.hpp> +#include <mbgl/gl/context.hpp> +#include <mbgl/util/stopwatch.hpp> +#include <mbgl/util/exception.hpp> +#include <mbgl/platform/log.hpp> +#include <mbgl/platform/platform.hpp> + +#include <cstring> +#include <cassert> +#include <iostream> +#include <string> +#include <fstream> +#include <cstdio> +#include <cassert> + +namespace mbgl { +namespace gl { + +Shader::Shader(const char* name_, + const char* vertexSource, + const char* fragmentSource, + Context& context, + Defines defines) + : name(name_), + program(context.createProgram()), + vertexShader(context.createVertexShader()), + fragmentShader(context.createFragmentShader()) { + util::stopwatch stopwatch("shader compilation", Event::Shader); + + if (!compileShader(vertexShader, vertexSource)) { + Log::Error(Event::Shader, "Vertex shader %s failed to compile: %s", name, vertexSource); + throw util::ShaderException(std::string { "Vertex shader " } + name + " failed to compile"); + } + + std::string fragment(fragmentSource); + if (defines & Defines::Overdraw) { + assert(fragment.find("#ifdef OVERDRAW_INSPECTOR") != std::string::npos); + fragment.replace(fragment.find_first_of('\n'), 1, "\n#define OVERDRAW_INSPECTOR\n"); + } + + if (!compileShader(fragmentShader, fragment.c_str())) { + Log::Error(Event::Shader, "Fragment shader %s failed to compile: %s", name, fragmentSource); + throw util::ShaderException(std::string { "Fragment shader " } + name + " failed to compile"); + } + + // Attach shaders + MBGL_CHECK_ERROR(glAttachShader(program.get(), vertexShader.get())); + MBGL_CHECK_ERROR(glAttachShader(program.get(), fragmentShader.get())); + + // Bind attribute variables + MBGL_CHECK_ERROR(glBindAttribLocation(program.get(), a_pos, "a_pos")); + MBGL_CHECK_ERROR(glBindAttribLocation(program.get(), a_extrude, "a_extrude")); + MBGL_CHECK_ERROR(glBindAttribLocation(program.get(), a_offset, "a_offset")); + MBGL_CHECK_ERROR(glBindAttribLocation(program.get(), a_data, "a_data")); + MBGL_CHECK_ERROR(glBindAttribLocation(program.get(), a_texture_pos, "a_texture_pos")); + + // Link program + GLint status; + MBGL_CHECK_ERROR(glLinkProgram(program.get())); + + MBGL_CHECK_ERROR(glGetProgramiv(program.get(), GL_LINK_STATUS, &status)); + if (status == 0) { + GLint logLength; + MBGL_CHECK_ERROR(glGetProgramiv(program.get(), GL_INFO_LOG_LENGTH, &logLength)); + const auto log = std::make_unique<GLchar[]>(logLength); + if (logLength > 0) { + MBGL_CHECK_ERROR(glGetProgramInfoLog(program.get(), logLength, &logLength, log.get())); + Log::Error(Event::Shader, "Program failed to link: %s", log.get()); + } + throw util::ShaderException(std::string { "Program " } + name + " failed to link: " + log.get()); + } +} + +bool Shader::compileShader(UniqueShader& shader, const GLchar *source) { + GLint status = 0; + + const GLsizei lengths = static_cast<GLsizei>(std::strlen(source)); + MBGL_CHECK_ERROR(glShaderSource(shader.get(), 1, &source, &lengths)); + + MBGL_CHECK_ERROR(glCompileShader(shader.get())); + + MBGL_CHECK_ERROR(glGetShaderiv(shader.get(), GL_COMPILE_STATUS, &status)); + if (status == 0) { + GLint logLength; + MBGL_CHECK_ERROR(glGetShaderiv(shader.get(), GL_INFO_LOG_LENGTH, &logLength)); + if (logLength > 0) { + const auto log = std::make_unique<GLchar[]>(logLength); + MBGL_CHECK_ERROR(glGetShaderInfoLog(shader.get(), logLength, &logLength, log.get())); + Log::Error(Event::Shader, "Shader failed to compile: %s", log.get()); + } + return false; + } + + MBGL_CHECK_ERROR(glGetShaderiv(shader.get(), GL_COMPILE_STATUS, &status)); + if (status == GL_FALSE) { + Log::Error(Event::Shader, "Shader %s failed to compile.", name); + return false; + } + + return true; +} + +Shader::~Shader() { + if (program.get()) { + MBGL_CHECK_ERROR(glDetachShader(program.get(), vertexShader.get())); + MBGL_CHECK_ERROR(glDetachShader(program.get(), fragmentShader.get())); + } +} + +UniformLocation Shader::getUniformLocation(const char* uniform) const { + return MBGL_CHECK_ERROR(glGetUniformLocation(program.get(), uniform)); +} + +} // namespace gl +} // namespace mbgl diff --git a/src/mbgl/gl/shader.hpp b/src/mbgl/gl/shader.hpp new file mode 100644 index 0000000000..f73400bc15 --- /dev/null +++ b/src/mbgl/gl/shader.hpp @@ -0,0 +1,51 @@ +#pragma once + +#include <mbgl/gl/types.hpp> +#include <mbgl/gl/object.hpp> +#include <mbgl/util/noncopyable.hpp> + +namespace mbgl { +namespace gl { + +class Context; + +class Shader : private util::noncopyable { +public: + ~Shader(); + const char* name; + + ProgramID getID() const { + return program.get(); + } + + UniformLocation getUniformLocation(const char* uniform) const; + + enum Defines : bool { + None = false, + Overdraw = true, + }; + +protected: + Shader(const char* name_, + const char* vertex, + const char* fragment, + Context&, + Defines defines = Defines::None); + +public: + static constexpr AttributeLocation a_pos = 0; + static constexpr AttributeLocation a_extrude = 1; + static constexpr AttributeLocation a_offset = 2; + static constexpr AttributeLocation a_data = 3; + static constexpr AttributeLocation a_texture_pos = 4; + +private: + bool compileShader(UniqueShader&, const char *source); + + UniqueProgram program; + UniqueShader vertexShader; + UniqueShader fragmentShader; +}; + +} // namespace gl +} // namespace mbgl diff --git a/src/mbgl/gl/uniform.cpp b/src/mbgl/gl/uniform.cpp new file mode 100644 index 0000000000..07a27963d9 --- /dev/null +++ b/src/mbgl/gl/uniform.cpp @@ -0,0 +1,57 @@ +#include <mbgl/gl/uniform.hpp> +#include <mbgl/gl/gl.hpp> +#include <mbgl/util/color.hpp> + +namespace mbgl { +namespace gl { + +template <> +void Uniform<float>::bind(const float& t) { + MBGL_CHECK_ERROR(glUniform1f(location, t)); +} + +template <> +void Uniform<int32_t>::bind(const int32_t& t) { + MBGL_CHECK_ERROR(glUniform1i(location, t)); +} + +template <> +void Uniform<std::array<float, 2>>::bind(const std::array<float, 2>& t) { + MBGL_CHECK_ERROR(glUniform2fv(location, 1, t.data())); +} + +template <> +void Uniform<std::array<float, 3>>::bind(const std::array<float, 3>& t) { + MBGL_CHECK_ERROR(glUniform3fv(location, 1, t.data())); +} + +template <> +void Uniform<std::array<float, 4>>::bind(const std::array<float, 4>& t) { + MBGL_CHECK_ERROR(glUniform4fv(location, 1, t.data())); +} + +template <> +void Uniform<Color>::bind(const Color& t) { + std::array<float, 4> a = {{ t.r, t.g, t.b, t.a }}; + MBGL_CHECK_ERROR(glUniform4fv(location, 1, a.data())); +} + +template <> +void UniformMatrix<2>::bind(const std::array<float, 4>& t) { + MBGL_CHECK_ERROR(glUniformMatrix2fv(location, 1, GL_FALSE, t.data())); +} + +template <> +void UniformMatrix<3>::bind(const std::array<float, 9>& t) { + MBGL_CHECK_ERROR(glUniformMatrix3fv(location, 1, GL_FALSE, t.data())); +} + +template <> +void UniformMatrix<4>::bind(const std::array<float, 16>& t) { + MBGL_CHECK_ERROR(glUniformMatrix4fv(location, 1, GL_FALSE, t.data())); +} + +// Add more as needed. + +} // namespace gl +} // namespace mbgl diff --git a/src/mbgl/gl/uniform.hpp b/src/mbgl/gl/uniform.hpp new file mode 100644 index 0000000000..5af781043d --- /dev/null +++ b/src/mbgl/gl/uniform.hpp @@ -0,0 +1,61 @@ +#pragma once + +#include <mbgl/gl/shader.hpp> + +#include <array> + +namespace mbgl { +namespace gl { + +template <typename T> +class Uniform { +public: + Uniform(const char* name, const Shader& shader) + : current(), location(shader.getUniformLocation(name)) { + } + + void operator=(const T& t) { + if (current != t) { + current = t; + bind(t); + } + } + +private: + void bind(const T&); + + T current; + UniformLocation location; +}; + +template <size_t C, size_t R = C> +class UniformMatrix { +public: + typedef std::array<float, C*R> T; + + UniformMatrix(const char* name, const Shader& shader) + : current(), location(shader.getUniformLocation(name)) { + } + + void operator=(const std::array<double, C*R>& t) { + bool dirty = false; + for (unsigned int i = 0; i < C*R; i++) { + if (current[i] != t[i]) { + current[i] = t[i]; + dirty = true; + } + } + if (dirty) { + bind(current); + } + } + +private: + void bind(const T&); + + T current; + UniformLocation location; +}; + +} // namespace gl +} // namespace mbgl diff --git a/src/mbgl/gl/vao.cpp b/src/mbgl/gl/vao.cpp index 527dd214fb..26a03a8a16 100644 --- a/src/mbgl/gl/vao.cpp +++ b/src/mbgl/gl/vao.cpp @@ -30,7 +30,7 @@ void VertexArrayObject::bindVertexArrayObject(gl::Context& context) { context.vertexArrayObject = *vertexArray; } -void VertexArrayObject::verifyBinding(Shader& shader, +void VertexArrayObject::verifyBinding(gl::Shader& shader, gl::BufferID vertexBuffer, gl::BufferID elementsBuffer, int8_t* offset) { @@ -47,7 +47,7 @@ void VertexArrayObject::verifyBinding(Shader& shader, } } -void VertexArrayObject::storeBinding(Shader& shader, +void VertexArrayObject::storeBinding(gl::Shader& shader, gl::BufferID vertexBuffer, gl::BufferID elementsBuffer, int8_t* offset) { diff --git a/src/mbgl/gl/vao.hpp b/src/mbgl/gl/vao.hpp index c2e3470367..bedc3abbc7 100644 --- a/src/mbgl/gl/vao.hpp +++ b/src/mbgl/gl/vao.hpp @@ -1,6 +1,6 @@ #pragma once -#include <mbgl/shader/shader.hpp> +#include <mbgl/gl/shader.hpp> #include <mbgl/gl/context.hpp> #include <mbgl/gl/vertex_buffer.hpp> #include <mbgl/util/noncopyable.hpp> @@ -57,11 +57,11 @@ public: private: void bindVertexArrayObject(gl::Context&); - void storeBinding(Shader& shader, + void storeBinding(gl::Shader& shader, gl::BufferID vertexBuffer, gl::BufferID elementsBuffer, int8_t* offset); - void verifyBinding(Shader& shader, + void verifyBinding(gl::Shader& shader, gl::BufferID vertexBuffer, gl::BufferID elementsBuffer, int8_t* offset); |