diff options
author | John Firebaugh <john.firebaugh@gmail.com> | 2016-10-28 18:17:33 -0700 |
---|---|---|
committer | John Firebaugh <john.firebaugh@gmail.com> | 2016-11-08 08:09:29 -0800 |
commit | 66bdbc3b969083b9d647abdf72784be64a125949 (patch) | |
tree | 9f2f1c6eb3d0569926420459c2c9afda50c66fd0 /src/mbgl/gl/context.cpp | |
parent | 36210fe4e9c68a52dedc90548d90e77cf39a2228 (diff) | |
download | qtlocation-mapboxgl-66bdbc3b969083b9d647abdf72784be64a125949.tar.gz |
[core] Introduce gl::Program template
Diffstat (limited to 'src/mbgl/gl/context.cpp')
-rw-r--r-- | src/mbgl/gl/context.cpp | 55 |
1 files changed, 48 insertions, 7 deletions
diff --git a/src/mbgl/gl/context.cpp b/src/mbgl/gl/context.cpp index f23dfe3dbe..b12c77c1a1 100644 --- a/src/mbgl/gl/context.cpp +++ b/src/mbgl/gl/context.cpp @@ -4,12 +4,16 @@ #include <mbgl/gl/vertex_array.hpp> #include <mbgl/util/traits.hpp> #include <mbgl/util/std.hpp> +#include <mbgl/platform/log.hpp> #include <boost/functional/hash.hpp> namespace mbgl { namespace gl { +static_assert(underlying_type(ShaderType::Vertex) == GL_VERTEX_SHADER, "OpenGL type mismatch"); +static_assert(underlying_type(ShaderType::Fragment) == GL_FRAGMENT_SHADER, "OpenGL type mismatch"); + static_assert(underlying_type(PrimitiveType::Points) == GL_POINTS, "OpenGL type mismatch"); static_assert(underlying_type(PrimitiveType::Lines) == GL_LINES, "OpenGL type mismatch"); static_assert(underlying_type(PrimitiveType::LineLoop) == GL_LINE_LOOP, "OpenGL type mismatch"); @@ -34,16 +38,53 @@ Context::~Context() { reset(); } -UniqueProgram Context::createProgram() { - return UniqueProgram{ MBGL_CHECK_ERROR(glCreateProgram()), { this } }; -} +UniqueShader Context::createShader(ShaderType type, const std::string& source) { + UniqueShader result { MBGL_CHECK_ERROR(glCreateShader(static_cast<GLenum>(type))), { this } }; + + const GLchar* sources = source.data(); + const GLsizei lengths = static_cast<GLsizei>(source.length()); + MBGL_CHECK_ERROR(glShaderSource(result, 1, &sources, &lengths)); + MBGL_CHECK_ERROR(glCompileShader(result)); + + GLint status = 0; + MBGL_CHECK_ERROR(glGetShaderiv(result, GL_COMPILE_STATUS, &status)); + if (status != 0) { + return result; + } + + GLint logLength; + MBGL_CHECK_ERROR(glGetShaderiv(result, GL_INFO_LOG_LENGTH, &logLength)); + if (logLength > 0) { + const auto log = std::make_unique<GLchar[]>(logLength); + MBGL_CHECK_ERROR(glGetShaderInfoLog(result, logLength, &logLength, log.get())); + Log::Error(Event::Shader, "Shader failed to compile: %s", log.get()); + } -UniqueShader Context::createVertexShader() { - return UniqueShader{ MBGL_CHECK_ERROR(glCreateShader(GL_VERTEX_SHADER)), { this } }; + throw std::runtime_error("shader failed to compile"); } -UniqueShader Context::createFragmentShader() { - return UniqueShader{ MBGL_CHECK_ERROR(glCreateShader(GL_FRAGMENT_SHADER)), { this } }; +UniqueProgram Context::createProgram(ShaderID vertexShader, ShaderID fragmentShader) { + UniqueProgram result { MBGL_CHECK_ERROR(glCreateProgram()), { this } }; + + MBGL_CHECK_ERROR(glAttachShader(result, vertexShader)); + MBGL_CHECK_ERROR(glAttachShader(result, fragmentShader)); + MBGL_CHECK_ERROR(glLinkProgram(result)); + + GLint status; + MBGL_CHECK_ERROR(glGetProgramiv(result, GL_LINK_STATUS, &status)); + if (status != 0) { + return result; + } + + GLint logLength; + MBGL_CHECK_ERROR(glGetProgramiv(result, GL_INFO_LOG_LENGTH, &logLength)); + const auto log = std::make_unique<GLchar[]>(logLength); + if (logLength > 0) { + MBGL_CHECK_ERROR(glGetProgramInfoLog(result, logLength, &logLength, log.get())); + Log::Error(Event::Shader, "Program failed to link: %s", log.get()); + } + + throw std::runtime_error("program failed to link"); } UniqueBuffer Context::createVertexBuffer(const void* data, std::size_t size) { |