summaryrefslogtreecommitdiff
path: root/src/mbgl/shader/shader.cpp
diff options
context:
space:
mode:
authorBruno de Oliveira Abinader <bruno@mapbox.com>2016-06-21 17:22:51 -0700
committerBruno de Oliveira Abinader <bruno@mapbox.com>2016-07-01 19:47:35 +0300
commita17b0bcd82ebe8628b69588d19773d26596b86da (patch)
tree06e53bf42b059b28780e995020733aaaeb6487b1 /src/mbgl/shader/shader.cpp
parenteb7cfea7eacad8a179fb3167b88508f8f1f7fdd2 (diff)
downloadqtlocation-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.cpp51
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