diff options
author | Bruno de Oliveira Abinader <bruno@mapbox.com> | 2016-06-21 17:22:51 -0700 |
---|---|---|
committer | Bruno de Oliveira Abinader <bruno@mapbox.com> | 2016-07-01 19:47:35 +0300 |
commit | a17b0bcd82ebe8628b69588d19773d26596b86da (patch) | |
tree | 06e53bf42b059b28780e995020733aaaeb6487b1 /src/mbgl/shader/shader.cpp | |
parent | eb7cfea7eacad8a179fb3167b88508f8f1f7fdd2 (diff) | |
download | qtlocation-mapboxgl-a17b0bcd82ebe8628b69588d19773d26596b86da.tar.gz |
[core] Fix overdraw mode on Linux
- Use glBindAttribLocation for GLSL attributes.
- Create a separate shader for each shader that supports overdraw.
Needed because each uniform location must be known for every program.
- Create a separate VAO for each shader inside buckets.
Needed because we can only bind a VAO to a specific shader.
Fixes #5435.
Diffstat (limited to 'src/mbgl/shader/shader.cpp')
-rw-r--r-- | src/mbgl/shader/shader.cpp | 51 |
1 files changed, 20 insertions, 31 deletions
diff --git a/src/mbgl/shader/shader.cpp b/src/mbgl/shader/shader.cpp index 80c4c33efc..c9a6b89ade 100644 --- a/src/mbgl/shader/shader.cpp +++ b/src/mbgl/shader/shader.cpp @@ -11,10 +11,11 @@ #include <string> #include <fstream> #include <cstdio> +#include <cassert> namespace mbgl { -Shader::Shader(const char* name_, const char* vertexSource, const char* fragmentSource, gl::ObjectStore& store) +Shader::Shader(const char* name_, const char* vertexSource, const char* fragmentSource, gl::ObjectStore& store, bool overdraw) : name(name_) , program(store.createProgram()) , vertexShader(store.createShader(GL_VERTEX_SHADER)) @@ -27,7 +28,13 @@ Shader::Shader(const char* name_, const char* vertexSource, const char* fragment throw util::ShaderException(std::string { "Vertex shader " } + name + " failed to compile"); } - if (!compileShader(fragmentShader, fragmentSource)) { + std::string fragment(fragmentSource); + if (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"); } @@ -36,39 +43,25 @@ Shader::Shader(const char* name_, const char* vertexSource, const char* fragment MBGL_CHECK_ERROR(glAttachShader(program.get(), vertexShader.get())); MBGL_CHECK_ERROR(glAttachShader(program.get(), fragmentShader.get())); - linkProgram(program); - - std::string overdrawSource(fragmentSource); - if (overdrawSource.find("#ifdef OVERDRAW_INSPECTOR") != std::string::npos) { - programOverdraw = store.createProgram(); - overdrawShader = store.createShader(GL_FRAGMENT_SHADER); - - overdrawSource.replace(overdrawSource.find_first_of('\n'), 1, "\n#define OVERDRAW_INSPECTOR\n"); - if (!compileShader(*overdrawShader, overdrawSource.c_str())) { - Log::Error(Event::Shader, "Overdraw shader %s failed to compile: %s", name, overdrawSource.c_str()); - throw util::ShaderException(std::string { "Overdraw shader " } + name + " failed to compile"); - } + // 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_data1, "a_data1")); + MBGL_CHECK_ERROR(glBindAttribLocation(program.get(), a_data2, "a_data2")); - MBGL_CHECK_ERROR(glAttachShader(*programOverdraw, vertexShader.get())); - MBGL_CHECK_ERROR(glAttachShader(*programOverdraw, *overdrawShader)); - linkProgram(*programOverdraw); - } - - a_pos = MBGL_CHECK_ERROR(glGetAttribLocation(program.get(), "a_pos")); -} - -void Shader::linkProgram(gl::UniqueProgram& program_) { // Link program GLint status; - MBGL_CHECK_ERROR(glLinkProgram(program_.get())); + MBGL_CHECK_ERROR(glLinkProgram(program.get())); - MBGL_CHECK_ERROR(glGetProgramiv(program_.get(), GL_LINK_STATUS, &status)); + 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)); + 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())); + 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()); @@ -109,10 +102,6 @@ Shader::~Shader() { MBGL_CHECK_ERROR(glDetachShader(program.get(), vertexShader.get())); MBGL_CHECK_ERROR(glDetachShader(program.get(), fragmentShader.get())); } - if (programOverdraw) { - MBGL_CHECK_ERROR(glDetachShader(*programOverdraw, vertexShader.get())); - MBGL_CHECK_ERROR(glDetachShader(*programOverdraw, *overdrawShader)); - } } } // namespace mbgl |