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

Commit

Permalink
[core] Introduce gl::Program template
Browse files Browse the repository at this point in the history
  • Loading branch information
jfirebaugh committed Nov 3, 2016
1 parent 964d701 commit 507f114
Show file tree
Hide file tree
Showing 90 changed files with 984 additions and 1,451 deletions.
65 changes: 19 additions & 46 deletions cmake/core-files.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -74,10 +74,9 @@ set(MBGL_CORE_FILES
src/mbgl/gl/index_buffer.hpp
src/mbgl/gl/object.cpp
src/mbgl/gl/object.hpp
src/mbgl/gl/program.hpp
src/mbgl/gl/renderbuffer.hpp
src/mbgl/gl/segment.hpp
src/mbgl/gl/shader.cpp
src/mbgl/gl/shader.hpp
src/mbgl/gl/state.hpp
src/mbgl/gl/stencil_mode.cpp
src/mbgl/gl/stencil_mode.hpp
Expand Down Expand Up @@ -150,6 +149,24 @@ set(MBGL_CORE_FILES
include/mbgl/platform/default/settings_json.hpp
include/mbgl/platform/default/thread_pool.hpp

# programs
src/mbgl/programs/attributes.hpp
src/mbgl/programs/circle_program.cpp
src/mbgl/programs/circle_program.hpp
src/mbgl/programs/collision_box_program.cpp
src/mbgl/programs/collision_box_program.hpp
src/mbgl/programs/fill_program.cpp
src/mbgl/programs/fill_program.hpp
src/mbgl/programs/line_program.cpp
src/mbgl/programs/line_program.hpp
src/mbgl/programs/program.hpp
src/mbgl/programs/programs.hpp
src/mbgl/programs/raster_program.cpp
src/mbgl/programs/raster_program.hpp
src/mbgl/programs/symbol_program.cpp
src/mbgl/programs/symbol_program.hpp
src/mbgl/programs/uniforms.hpp

# renderer
src/mbgl/renderer/bucket.hpp
src/mbgl/renderer/circle_bucket.cpp
Expand Down Expand Up @@ -182,50 +199,6 @@ set(MBGL_CORE_FILES
src/mbgl/renderer/symbol_bucket.cpp
src/mbgl/renderer/symbol_bucket.hpp

# shader
src/mbgl/shader/attributes.hpp
src/mbgl/shader/circle_attributes.hpp
src/mbgl/shader/circle_shader.cpp
src/mbgl/shader/circle_shader.hpp
src/mbgl/shader/circle_uniforms.hpp
src/mbgl/shader/collision_box_attributes.hpp
src/mbgl/shader/collision_box_shader.cpp
src/mbgl/shader/collision_box_shader.hpp
src/mbgl/shader/collision_box_uniforms.hpp
src/mbgl/shader/fill_attributes.hpp
src/mbgl/shader/fill_outline_pattern_shader.cpp
src/mbgl/shader/fill_outline_pattern_shader.hpp
src/mbgl/shader/fill_outline_shader.cpp
src/mbgl/shader/fill_outline_shader.hpp
src/mbgl/shader/fill_pattern_shader.cpp
src/mbgl/shader/fill_pattern_shader.hpp
src/mbgl/shader/fill_shader.cpp
src/mbgl/shader/fill_shader.hpp
src/mbgl/shader/fill_uniforms.cpp
src/mbgl/shader/fill_uniforms.hpp
src/mbgl/shader/line_attributes.hpp
src/mbgl/shader/line_pattern_shader.cpp
src/mbgl/shader/line_pattern_shader.hpp
src/mbgl/shader/line_sdf_shader.cpp
src/mbgl/shader/line_sdf_shader.hpp
src/mbgl/shader/line_shader.cpp
src/mbgl/shader/line_shader.hpp
src/mbgl/shader/line_uniforms.cpp
src/mbgl/shader/line_uniforms.hpp
src/mbgl/shader/raster_attributes.hpp
src/mbgl/shader/raster_shader.cpp
src/mbgl/shader/raster_shader.hpp
src/mbgl/shader/raster_uniforms.hpp
src/mbgl/shader/shaders.hpp
src/mbgl/shader/symbol_attributes.hpp
src/mbgl/shader/symbol_icon_shader.cpp
src/mbgl/shader/symbol_icon_shader.hpp
src/mbgl/shader/symbol_sdf_shader.cpp
src/mbgl/shader/symbol_sdf_shader.hpp
src/mbgl/shader/symbol_uniforms.cpp
src/mbgl/shader/symbol_uniforms.hpp
src/mbgl/shader/uniforms.hpp

# sprite
include/mbgl/sprite/sprite_image.hpp
src/mbgl/sprite/sprite_atlas.cpp
Expand Down
7 changes: 3 additions & 4 deletions cmake/shaders.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,13 @@ function(add_shader VAR name)
set(shader_source_prefix ${MBGL_GENERATED}/include/mbgl/shader)

add_custom_command(
OUTPUT ${shader_source_prefix}/${name}.vertex.hpp ${shader_source_prefix}/${name}.fragment.hpp
COMMAND ${shader_build_cmd} ${shader_file_prefix}/${name}.vertex.glsl ${shader_source_prefix}/${name}.vertex.hpp
COMMAND ${shader_build_cmd} ${shader_file_prefix}/${name}.fragment.glsl ${shader_source_prefix}/${name}.fragment.hpp
OUTPUT ${shader_source_prefix}/${name}.hpp
COMMAND ${shader_build_cmd} ${shader_file_prefix}/${name}.vertex.glsl ${shader_file_prefix}/${name}.fragment.glsl ${shader_source_prefix}/${name}.hpp
DEPENDS ${shader_file_prefix}/${name}.vertex.glsl
DEPENDS ${shader_file_prefix}/${name}.fragment.glsl
VERBATIM
)
set(${VAR} ${${VAR}} ${shader_source_prefix}/${name}.vertex.hpp ${shader_source_prefix}/${name}.fragment.hpp PARENT_SCOPE)
set(${VAR} ${${VAR}} ${shader_source_prefix}/${name}.hpp PARENT_SCOPE)
endfunction()

add_shader(MBGL_SHADER_FILES circle)
Expand Down
1 change: 1 addition & 0 deletions cmake/test.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ target_include_directories(mbgl-test
PRIVATE test/include
PRIVATE test/src
PRIVATE platform/default
PRIVATE ${MBGL_GENERATED}/include
)

if(DEFINED ENV{CI})
Expand Down
5 changes: 0 additions & 5 deletions include/mbgl/util/exception.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,5 @@ struct MisuseException : Exception {
MisuseException(const std::string &msg) : Exception(msg) {}
};

struct ShaderException : Exception {
ShaderException(const char *msg) : Exception(msg) {}
ShaderException(const std::string &msg) : Exception(msg) {}
};

} // namespace util
} // namespace mbgl
86 changes: 36 additions & 50 deletions scripts/build-shaders.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,68 +4,54 @@ var path = require('path');
var fs = require('fs');
var mkdirp = require('mkdirp');

var input_file = process.argv[2]
var output_file = process.argv[3];
var vertex_file = process.argv[2];
var fragment_file = process.argv[3];
var output_file = process.argv[4];

if (!input_file || !output_file) {
if (!vertex_file || !fragment_file || !output_file) {
console.warn('No input or output file given.');
console.warn('Usage: %s [input.vertex.glsl] [output.vertex.hpp]', path.basename(process.argv[1]));
console.warn('Usage: %s input.vertex.glsl input.fragment.glsl output.hpp', path.basename(process.argv[1]));
process.exit(1);
}

var components = path.basename(input_file).split('.');

var components = path.basename(vertex_file).split('.');
var shader_name = components[0];
var shader_type = components[1];
var extension = components[2];

var data = fs.readFileSync(input_file, 'utf8');

// Replace uniform pragmas

var pragma_mapbox_regex = /(\s*)#pragma\s+mapbox\s*:\s+(define|initialize)\s+(low|medium|high)p\s+(float|vec(?:2|3|4))\s+(.*)/;

var data = data.split('\n').map(function(line) {
var params = line.match(pragma_mapbox_regex);
if (params) {
if (params[2] === 'define') {
return params[1] + 'uniform ' + params[3] + 'p ' + params[4] + ' u_' + params[5] + ';';
function source(file) {
return '\n' + fs.readFileSync(file, 'utf8').split('\n').map(function(line) {
var params = line.match(pragma_mapbox_regex);
if (params) {
if (params[2] === 'define') {
return params[1] + 'uniform ' + params[3] + 'p ' + params[4] + ' u_' + params[5] + ';';
} else {
return params[1] + params[3] + 'p ' + params[4] + ' ' + params[5] + ' = u_' + params[5] + ';';
}
} else {
return params[1] + params[3] + 'p ' + params[4] + ' ' + params[5] + ' = u_' + params[5] + ';';
return line;
}
} else {
return line;
}
}).join('\n');

}).join('\n');
}

var content =
'#pragma once\n' +
'\n' +
'// NOTE: DO NOT CHANGE THIS FILE. IT IS AUTOMATICALLY GENERATED.\n' +
'\n' +
'#include <mbgl/gl/gl.hpp>\n' +
'\n' +
'namespace mbgl {\n' +
'namespace shaders {\n' +
'namespace ' + shader_name + ' {\n' +
'\n' +
'#ifndef MBGL_SHADER_NAME_' + shader_name.toUpperCase() + '\n' +
'#define MBGL_SHADER_NAME_' + shader_name.toUpperCase() + '\n' +
'constexpr const char* name = "' + shader_name + '";\n' +
'#endif // MBGL_SHADER_NAME_' + shader_name.toUpperCase() + '\n' +
'\n' +
'constexpr const char* ' + shader_type + ' =\n' +
'#ifdef GL_ES_VERSION_2_0\n' +
' "precision highp float;"\n' +
'#else\n' +
' "#version 120"\n' +
'#endif\n' +
' R"MBGL_SHADER(\n' + data + ')MBGL_SHADER";\n' +
'\n' +
'} // namespace ' + shader_name + '\n' +
'} // namespace shaders\n' +
'} // namespace mbgl\n';
var content = "#pragma once\n" +
"\n" +
"// NOTE: DO NOT CHANGE THIS FILE. IT IS AUTOMATICALLY GENERATED.\n" +
"\n" +
"#include <mbgl/gl/gl.hpp>\n" +
"\n" +
"namespace mbgl {\n" +
"namespace shaders {\n" +
"\n" +
"class " + shader_name + " {\n" +
"public:\n" +
" static constexpr const char* name = \"" + shader_name + "\";" +
" static constexpr const char* vertexSource = R\"MBGL_SHADER(" + source(vertex_file) + ")MBGL_SHADER\";\n" +
" static constexpr const char* fragmentSource = R\"MBGL_SHADER(" + source(fragment_file) + ")MBGL_SHADER\";\n" +
"};\n" +
"\n" +
"} // namespace shaders\n" +
"} // namespace mbgl\n";

mkdirp.sync(path.dirname(output_file));
fs.writeFileSync(output_file, content);
4 changes: 4 additions & 0 deletions src/mbgl/gl/attribute.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@
namespace mbgl {
namespace gl {

AttributeLocation attributeLocation(ProgramID id, const char* name) {
return MBGL_CHECK_ERROR(glGetAttribLocation(id, name));
}

void bindAttribute(AttributeLocation location,
std::size_t count,
DataType type,
Expand Down
10 changes: 4 additions & 6 deletions src/mbgl/gl/attribute.hpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
#pragma once

#include <mbgl/gl/types.hpp>
#include <mbgl/gl/shader.hpp>

#include <cstddef>
#include <functional>
Expand All @@ -18,9 +17,6 @@ class Attribute {

class State {
public:
State(const char* name, const Shader& shader)
: location(shader.getAttributeLocation(name)) {}

AttributeLocation location;
static constexpr std::size_t count = N;
static constexpr DataType type = DataTypeOf<T>::value;
Expand Down Expand Up @@ -134,6 +130,8 @@ const std::size_t Vertex<A1, A2, A3, A4, A5>::attributeOffsets[5] = {

} // namespace detail

AttributeLocation attributeLocation(ProgramID, const char * name);

void bindAttribute(AttributeLocation location,
std::size_t count,
DataType type,
Expand All @@ -147,8 +145,8 @@ class Attributes {
using State = std::tuple<typename As::State...>;
using Vertex = detail::Vertex<As...>;

static State state(const Shader& shader) {
return State { { As::name, shader }... };
static State state(const ProgramID& id) {
return State { { attributeLocation(id, As::name) }... };
}

static std::function<void (std::size_t)> binder(const State& state) {
Expand Down
55 changes: 48 additions & 7 deletions src/mbgl/gl/context.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand All @@ -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) {
Expand Down
6 changes: 3 additions & 3 deletions src/mbgl/gl/context.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include <memory>
#include <vector>
#include <array>
#include <string>
#include <unordered_map>

namespace mbgl {
Expand All @@ -28,9 +29,8 @@ class Context : private util::noncopyable {
public:
~Context();

UniqueProgram createProgram();
UniqueShader createVertexShader();
UniqueShader createFragmentShader();
UniqueShader createShader(ShaderType type, const std::string& source);
UniqueProgram createProgram(ShaderID vertexShader, ShaderID fragmentShader);
UniqueTexture createTexture();

template <class V>
Expand Down
Loading

0 comments on commit 507f114

Please sign in to comment.