diff options
-rw-r--r-- | .gitignore | 3 | ||||
-rw-r--r-- | Makefile | 20 | ||||
-rw-r--r-- | README.md | 30 | ||||
-rwxr-xr-x | bin/build-shaders.js | 77 | ||||
-rw-r--r-- | emscripten/main.cpp | 154 | ||||
-rw-r--r-- | emscripten/main.html | 9 | ||||
-rw-r--r-- | include/llmr/geometry/linevertexbuffer.hpp | 4 | ||||
-rw-r--r-- | include/llmr/platform/gl.hpp | 4 | ||||
-rw-r--r-- | include/llmr/platform/platform.hpp | 2 | ||||
-rw-r--r-- | include/llmr/renderer/painter.hpp | 14 | ||||
-rw-r--r-- | include/llmr/renderer/shader-fill.hpp | 8 | ||||
-rw-r--r-- | include/llmr/renderer/shader-line.hpp | 8 | ||||
-rw-r--r-- | include/llmr/renderer/shader.hpp | 9 | ||||
-rw-r--r-- | include/llmr/shader/shaders.h | 28 | ||||
-rw-r--r-- | macosx/main.mm | 33 | ||||
-rw-r--r-- | src/geometry/linevertexbuffer.cpp | 1 | ||||
-rw-r--r-- | src/map/pbf.hpp | 9 | ||||
-rw-r--r-- | src/map/tile.cpp | 8 | ||||
-rw-r--r-- | src/renderer/painter.cpp | 20 | ||||
-rw-r--r-- | src/renderer/shader-fill.cpp | 9 | ||||
-rw-r--r-- | src/renderer/shader-line.cpp | 20 | ||||
-rw-r--r-- | src/renderer/shader.cpp | 16 | ||||
-rw-r--r-- | src/shader/line.fragment.glsl | 1 | ||||
-rw-r--r-- | src/shader/shaders.c | 13 |
24 files changed, 406 insertions, 94 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000000..6bc0b9d208 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +*.o +/emscripten/main.js +/emscripten/main.js.map
\ No newline at end of file @@ -12,17 +12,17 @@ SRCS += src/renderer/painter.cpp SRCS += src/renderer/shader.cpp SRCS += src/renderer/shader-fill.cpp SRCS += src/renderer/shader-line.cpp +SRCS += src/shader/shaders.c SRCS += src/util/mat4.c -OBJS = $(patsubst %.mm,%.o,$(patsubst %.cpp,%.o,$(patsubst %.c,%.o,$(SRCS)))) +# OBJS = $(patsubst %.mm,%.o,$(patsubst %.cpp,%.o,$(patsubst %.c,%.o,$(SRCS)))) main: macosx -library: $(OBJS) - macosx: SRCS += macosx/main.mm -macosx: library - $(CXX) $(OBJS) $(INCLUDE) -lglfw3 -framework OpenGL -framework Foundation -o macosx/main +emscripten: SRCS += emscripten/main.cpp + +macosx emscripten: OBJS = $(patsubst %.mm,%.o,$(patsubst %.cpp,%.o,$(patsubst %.c,%.o,$(SRCS)))) %.o: %.cpp $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(INCLUDE) -c -o $@ $^ @@ -33,8 +33,16 @@ macosx: library %.o: %.c $(CC) $(CPPFLAGS) $(INCLUDE) -c -o $@ $^ + +.SECONDEXPANSION: +macosx: $$(OBJS) + $(CXX) $(OBJS) $(INCLUDE) -lglfw3 -framework OpenGL -framework Foundation -o macosx/main + +emscripten: $$(OBJS) + $(CXX) $(OBJS) $(INCLUDE) -o emscripten/main.js + clean: rm -rf src/*/*.o rm -rf macosx/main -.PHONY: macosx +.PHONY: macosx emscripten diff --git a/README.md b/README.md new file mode 100644 index 0000000000..47db97996c --- /dev/null +++ b/README.md @@ -0,0 +1,30 @@ + + +# Build instructions + +## Mac OS X + +``` +make +``` + + +## Emscripten + +``` +emmake make emscripten +``` + +Note that mousewheel support requires a hacked emscripten: + +In `src/library_glfw.js`, replace the first part of the mousewheel function with + +```js + GLFW.wheelPos = (event.detail || -event.deltaY); +``` + +In `system/include/GL/glfw.h`, replace the wheel callback typedef with + +```c +typedef void (GLFWCALL * GLFWmousewheelfun)(float); +``` diff --git a/bin/build-shaders.js b/bin/build-shaders.js new file mode 100755 index 0000000000..d8d7a46bbb --- /dev/null +++ b/bin/build-shaders.js @@ -0,0 +1,77 @@ +#!/usr/bin/env node +'use strict'; + +var fs = require('fs'); +var path = require('path'); + +module.exports = function() { + var name; + var shaders = {}; + + var shaderFiles = fs.readdirSync('src/shader'); + + for (var i = 0; i < shaderFiles.length; i++) { + var parts = shaderFiles[i].match(/^(.+)\.(vertex|fragment)\.glsl$/); + if (parts) { + name = parts[1]; + var type = parts[2]; + if (!(name in shaders)) { + shaders[name] = {}; + } + shaders[name][type] = fs.readFileSync(path.join('src/shader', shaderFiles[i]), 'utf8'); + } + } + + var lines = []; + var consts = []; + for (var name in shaders) { + consts.push(name.toUpperCase() + '_SHADER'); + + var line = ''; + line += ' [' + name.toUpperCase() + '_SHADER] = {\n'; + line += ' .vertex = ' + JSON.stringify(shaders[name].vertex) + ',\n'; + line += ' .fragment = ' + JSON.stringify(shaders[name].fragment) + ',\n'; + line += ' }'; + lines.push(line); + } + + var header = '// NOTE: DO NOT CHANGE THIS FILE. IT IS AUTOMATICALLY GENERATED.\n\n'; + header += '#ifndef LLMR_SHADER_SHADERS\n'; + header += '#define LLMR_SHADER_SHADERS\n'; + header += '\n'; + header += '#ifdef __cplusplus\n'; + header += 'extern "C" {\n'; + header += '#endif\n'; + header += '\n'; + header += 'struct llmr_shader {\n'; + header += ' const char *vertex;\n'; + header += ' const char *fragment;\n'; + header += '};\n'; + header += 'typedef struct llmr_shader llmr_shader_t;\n' + header += '\n'; + header += 'enum {\n'; + consts.push('SHADER_COUNT'); + header += ' ' + consts.join(',\n ') + '\n'; + header += '};\n'; + header += '\n'; + header += 'extern const llmr_shader_t llmr_shaders[SHADER_COUNT];\n'; + header += '\n'; + header += '#ifdef __cplusplus\n'; + header += '}\n'; + header += '#endif\n'; + header += '\n'; + header += '#endif\n'; + fs.writeFileSync('include/llmr/shader/shaders.h', header); + + + var code = '// NOTE: DO NOT CHANGE THIS FILE. IT IS AUTOMATICALLY GENERATED.\n'; + code += '#include <llmr/shader/shaders.h>\n'; + code += '\n'; + code += 'const llmr_shader_t llmr_shaders[SHADER_COUNT] = {\n'; + code += lines.join(',\n'); + code += '\n};\n'; + + fs.writeFileSync('src/shader/shaders.c', code); +}; + +module.exports(); diff --git a/emscripten/main.cpp b/emscripten/main.cpp new file mode 100644 index 0000000000..20e9212baf --- /dev/null +++ b/emscripten/main.cpp @@ -0,0 +1,154 @@ +#include <emscripten/emscripten.h> +#include <GL/glfw.h> +#include <cstdio> +#include <cstdlib> +#include <cmath> + +#include <llmr/llmr.hpp> +#include <llmr/map/tile.hpp> + +bool dirty = true; + +class MapView; + +static MapView *view; + +class MapView { +public: + MapView() : + dirty(true), + platform(new llmr::platform(this)), + painter(new llmr::painter(platform)), + map(new llmr::map(platform, painter)) { + + // Initialize GLFW + if (!glfwInit()) { + fprintf(stderr, "Failed to initialize GLFW\n"); + exit(1); + } + + int width, height; + emscripten_get_canvas_size(&width, &height, NULL); + + glfwSetMousePosCallback(mousemove); + glfwSetMouseButtonCallback(mouseclick); + glfwSetMouseWheelCallback(scroll); + + // Open a window and create its OpenGL context + if (!glfwOpenWindow(width, height, 8, 8, 8, 8, 16, 8, GLFW_WINDOW)) { + fprintf(stderr, "Failed to open GLFW window\n"); + + glfwTerminate(); + exit(1); + } + + painter->setup(); + painter->resize(width, height); + + } + + ~MapView() { + delete map; + delete painter; + delete platform; + glfwTerminate(); + } + + static void mousemove(int x, int y) { + if (view->tracking) { + view->map->moveBy(x - view->last_x, y - view->last_y); + } + view->last_x = x; + view->last_y = y; + } + + static void scroll(float pos) { + double delta = pos; + + bool is_wheel = delta != 0 && fmod(delta, 4.000244140625) == 0; + + double absdelta = delta < 0 ? -delta : delta; + double scale = 2.0 / (1.0 + exp(-absdelta / 100.0)); + + // Make the scroll wheel a bit slower. + // if (!is_wheel) { + // scale = (scale - 1.0) / 2.0 + 1.0; + // } + + // Zooming out. + if (delta < 0 && scale != 0) { + scale = 1.0 / scale; + } + + view->map->scaleBy(scale, view->last_x, view->last_y); + } + + static void mouseclick(int button, int action) { + if (button == GLFW_MOUSE_BUTTON_1) { + view->tracking = action == GLFW_PRESS; + } + } + + int run() { + emscripten_set_main_loop(render, 60, 1); + return 0; + } + + static void render() { + if (view->dirty) { + view->map->render(); + // glClearColor(1, 1, 0, 1); + // glClear(GL_COLOR_BUFFER_BIT); + + view->dirty = false; + } + } + + bool dirty; + double last_x, last_y; + bool tracking; + + + llmr::platform *platform; + llmr::painter *painter; + llmr::map *map; + +}; + + +void llmr::platform::restart() { + view->dirty = true; +} + +void ontileload(void* custom, void* bytes, int length) { + fprintf(stderr, "data loaded successfully: length: %d\n", length); + llmr::tile *tile = (llmr::tile *)custom; + tile->setData((uint8_t *)bytes, length); + if (tile->parse()) { + view->map->tileLoaded(tile); + return; + } +} + +void ontileerror(void* custom) { + fprintf(stderr, "data load error\n"); + llmr::tile *tile = (llmr::tile *)custom; + view->map->tileFailed(tile); +} + +void llmr::platform::request(tile *tile) { + const char *urlTemplate = "http://api.tiles.mapbox.com/v3/mapbox.mapbox-streets-v4/%d/%d/%d.vector.pbf"; + char urlString[255]; + snprintf(urlString, 255, urlTemplate, tile->z, tile->x, tile->y); + fprintf(stderr, "requesting %s\n", urlString); + + emscripten_async_wget_data(urlString, tile, ontileload, ontileerror); +} + + +int main() { + view = new MapView(); + int ret = view->run(); + delete view; + return ret; +} diff --git a/emscripten/main.html b/emscripten/main.html new file mode 100644 index 0000000000..9676130527 --- /dev/null +++ b/emscripten/main.html @@ -0,0 +1,9 @@ +<body> +<script> +var canvas = document.createElement('canvas'); +canvas.width = 600; +canvas.height = 400; +document.body.appendChild(canvas); +Module = { canvas: canvas }; +</script> +<script src="main.js"></script> diff --git a/include/llmr/geometry/linevertexbuffer.hpp b/include/llmr/geometry/linevertexbuffer.hpp index 8d5c6b335c..4d23de9154 100644 --- a/include/llmr/geometry/linevertexbuffer.hpp +++ b/include/llmr/geometry/linevertexbuffer.hpp @@ -1,8 +1,6 @@ #ifndef LLMR_GEOMETRY_LINEVERTEXBUFFER #define LLMR_GEOMETRY_LINEVERTEXBUFFER -#include "../platform/gl.hpp" - #include <vector> namespace llmr { @@ -18,7 +16,7 @@ public: void bind(); private: std::vector<uint16_t> array; - GLuint buffer; + uint32_t buffer; }; } diff --git a/include/llmr/platform/gl.hpp b/include/llmr/platform/gl.hpp index 4fa0cf4775..58d9099c70 100644 --- a/include/llmr/platform/gl.hpp +++ b/include/llmr/platform/gl.hpp @@ -1,7 +1,9 @@ #ifndef LLMR_RENDERER_GL #define LLMR_RENDERER_GL -#ifdef __APPLE__ +#ifdef EMSCRIPTEN + #include <GLES2/gl2.h> +#elif __APPLE__ #include "TargetConditionals.h" #if TARGET_OS_IPHONE #include <OpenGLES/ES2/gl.h> diff --git a/include/llmr/platform/platform.hpp b/include/llmr/platform/platform.hpp index 46a1383c42..e8aa972d7b 100644 --- a/include/llmr/platform/platform.hpp +++ b/include/llmr/platform/platform.hpp @@ -8,8 +8,6 @@ class tile; class platform { public: platform(void *obj) : obj(obj) {} - - const char *shaderSource(const char *name, const char *extension); void restart(); void request(tile *tile); diff --git a/include/llmr/renderer/painter.hpp b/include/llmr/renderer/painter.hpp index ac6012b0d0..6c75171846 100644 --- a/include/llmr/renderer/painter.hpp +++ b/include/llmr/renderer/painter.hpp @@ -1,8 +1,6 @@ #ifndef LLMR_RENDERER_PAINTER #define LLMR_RENDERER_PAINTER -#include "../platform/gl.hpp" - #include "shader-fill.hpp" #include "shader-line.hpp" @@ -19,7 +17,7 @@ public: void setup(); void teardown(); - void resize(GLuint new_width, GLuint new_height); + void resize(uint32_t new_width, uint32_t new_height); void viewport(); @@ -38,16 +36,16 @@ public: private: platform *platform; transform *transform; - GLuint width, height; - GLfloat matrix[16]; + uint32_t width, height; + float matrix[16]; Shader *currentShader; FillShader *fillShader; LineShader *lineShader; - GLuint vertexArray; - GLuint triangleVertexBuffer; - GLuint fillVertexBuffer; + uint32_t vertexArray; + uint32_t triangleVertexBuffer; + uint32_t fillVertexBuffer; }; } diff --git a/include/llmr/renderer/shader-fill.hpp b/include/llmr/renderer/shader-fill.hpp index 165266e4b5..440f3011c6 100644 --- a/include/llmr/renderer/shader-fill.hpp +++ b/include/llmr/renderer/shader-fill.hpp @@ -7,11 +7,11 @@ namespace llmr { class FillShader : public Shader { public: - FillShader(const GLchar *vertex, const GLchar *fragment); + FillShader(); - GLint a_pos; - GLint u_matrix; - GLint u_color; + int32_t a_pos; + int32_t u_matrix; + int32_t u_color; }; } diff --git a/include/llmr/renderer/shader-line.hpp b/include/llmr/renderer/shader-line.hpp index 60e27146f9..b40ca0e0a7 100644 --- a/include/llmr/renderer/shader-line.hpp +++ b/include/llmr/renderer/shader-line.hpp @@ -7,11 +7,11 @@ namespace llmr { class LineShader : public Shader { public: - LineShader(const GLchar *vertex, const GLchar *fragment); + LineShader(); - GLint a_pos; - GLint u_matrix; - GLint u_color; + int32_t a_pos; + int32_t u_matrix; + int32_t u_color; }; } diff --git a/include/llmr/renderer/shader.hpp b/include/llmr/renderer/shader.hpp index d178a1d9c8..2968ad59fe 100644 --- a/include/llmr/renderer/shader.hpp +++ b/include/llmr/renderer/shader.hpp @@ -1,21 +1,20 @@ #ifndef LLMR_RENDERER_SHADER #define LLMR_RENDERER_SHADER -#include "../platform/gl.hpp" #include <vector> namespace llmr { class Shader { public: - Shader(const GLchar *vertex, const GLchar *fragment); + Shader(const char *vertex, const char *fragment); ~Shader(); bool valid; - GLuint program; - std::vector<GLuint> attributes; + uint32_t program; + std::vector<uint32_t> attributes; private: - bool compileShader(GLuint *shader, GLenum type, const GLchar *source); + bool compileShader(uint32_t *shader, uint32_t type, const char *source); }; } diff --git a/include/llmr/shader/shaders.h b/include/llmr/shader/shaders.h new file mode 100644 index 0000000000..038f07a2e9 --- /dev/null +++ b/include/llmr/shader/shaders.h @@ -0,0 +1,28 @@ +// NOTE: DO NOT CHANGE THIS FILE. IT IS AUTOMATICALLY GENERATED. + +#ifndef LLMR_SHADER_SHADERS +#define LLMR_SHADER_SHADERS + +#ifdef __cplusplus +extern "C" { +#endif + +struct llmr_shader { + const char *vertex; + const char *fragment; +}; +typedef struct llmr_shader llmr_shader_t; + +enum { + FILL_SHADER, + LINE_SHADER, + SHADER_COUNT +}; + +extern const llmr_shader_t llmr_shaders[SHADER_COUNT]; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/macosx/main.mm b/macosx/main.mm index 2462d2e34e..caa56d999e 100644 --- a/macosx/main.mm +++ b/macosx/main.mm @@ -1,8 +1,6 @@ #include <llmr/llmr.hpp> #include <GLFW/glfw3.h> -#include <cstdlib> #import <Foundation/Foundation.h> - #include <llmr/platform/platform.hpp> #include <llmr/map/tile.hpp> @@ -143,37 +141,6 @@ public: llmr::map *map; }; - - - - - -const char *llmr::platform::shaderSource(const char *name, const char *type) { - char filename[80]; - snprintf(filename, 80, "src/shader/%s.%s", name, type); - - FILE *file = fopen(filename, "rb"); - if (!file) { - fprintf(stderr, "Could not open file %s", filename); - return NULL; - } - - fseek(file, 0, SEEK_END); - long size = ftell(file); - fseek(file, 0, SEEK_SET); - char *shader = (char *)malloc(size + 1); - if (!fread(shader, size, 1, file)) { - fclose(file); - free(shader); - shader = 0; - fprintf(stderr, "Failed to read file %s\n", filename); - return NULL; - } - fclose(file); - shader[size] = 0; - return shader; -} - void llmr::platform::restart() { ((MapView *)obj)->dirty = true; } diff --git a/src/geometry/linevertexbuffer.cpp b/src/geometry/linevertexbuffer.cpp index 7d48f79604..04fd1c6c23 100644 --- a/src/geometry/linevertexbuffer.cpp +++ b/src/geometry/linevertexbuffer.cpp @@ -1,4 +1,5 @@ #include <llmr/geometry/linevertexbuffer.hpp> +#include <llmr/platform/gl.hpp> #include <cstdio> diff --git a/src/map/pbf.hpp b/src/map/pbf.hpp index faf0aadf91..29c252e115 100644 --- a/src/map/pbf.hpp +++ b/src/map/pbf.hpp @@ -21,7 +21,7 @@ struct pbf { // inline pbf(const std::string& buffer); inline bool next(); - inline uint64_t varint(); + template <typename T = uint32_t> inline T varint(); inline int64_t svarint(); inline std::string string(); inline float float32(); @@ -68,17 +68,18 @@ bool pbf::next() } -uint64_t pbf::varint() +template <typename T> +T pbf::varint() { uint8_t byte = 0x80; - uint64_t result = 0; + T result = 0; int bitpos; for (bitpos = 0; bitpos < 70 && (byte & 0x80); bitpos += 7) { if (data >= end) { fprintf(stderr, "unterminated varint, unexpected end of buffer"); exit(1); } - result |= ((uint64_t)(byte = *data) & 0x7F) << bitpos; + result |= ((T)(byte = *data) & 0x7F) << bitpos; data++; } diff --git a/src/map/tile.cpp b/src/map/tile.cpp index a27f6e5ba8..ce56cd6134 100644 --- a/src/map/tile.cpp +++ b/src/map/tile.cpp @@ -69,15 +69,15 @@ void tile::parseFeature(const uint8_t *data, uint32_t bytes) { pbf feature(data, bytes); while (feature.next()) { if (feature.tag == 1) { - uint64_t id = feature.varint(); + uint32_t id = feature.varint(); } else if (feature.tag == 2) { const uint8_t *tag_end = feature.data + feature.varint(); while (feature.data < tag_end) { - uint32_t key = (uint32_t)feature.varint(); - uint32_t value = (uint32_t)feature.varint(); + uint32_t key = feature.varint(); + uint32_t value = feature.varint(); } } else if (feature.tag == 3) { - uint32_t type = (uint32_t)feature.varint(); + uint32_t type = feature.varint(); } else if (feature.tag == 4) { uint32_t bytes = (uint32_t)feature.varint(); loadGeometry(feature.data, bytes); diff --git a/src/renderer/painter.cpp b/src/renderer/painter.cpp index b43e92d5ea..1a3fde50ab 100644 --- a/src/renderer/painter.cpp +++ b/src/renderer/painter.cpp @@ -5,6 +5,7 @@ #include <llmr/platform/platform.hpp> #include <llmr/map/transform.hpp> #include <llmr/map/tile.hpp> +#include <llmr/platform/gl.hpp> using namespace llmr; @@ -44,6 +45,7 @@ void painter::setup() { assert(fillShader); + assert(lineShader); @@ -62,20 +64,8 @@ void painter::setup() { } void painter::setupShaders() { - const GLchar *vertexSource, *fragmentSource; - - vertexSource = platform->shaderSource("fill", "vertex.glsl"); - assert((vertexSource, "Missing fill vertex shader source")); - fragmentSource = platform->shaderSource("fill", "fragment.glsl"); - assert((fragmentSource, "Missing fill fragment shader source")); - - fillShader = new FillShader(vertexSource, fragmentSource); - - vertexSource = platform->shaderSource("line", "vertex.glsl"); - assert((vertexSource, "Missing line vertex shader source")); - fragmentSource = platform->shaderSource("line", "fragment.glsl"); - assert((fragmentSource, "Missing line fragment shader source")); - lineShader = new LineShader(vertexSource, fragmentSource); + fillShader = new FillShader(); + lineShader = new LineShader(); } void painter::teardown() { @@ -108,6 +98,8 @@ void painter::resize(GLuint new_width, GLuint new_height) { void painter::changeMatrix() { assert(transform); + assert(width); + assert(height); // Initialize projection matrix float projMatrix[16]; diff --git a/src/renderer/shader-fill.cpp b/src/renderer/shader-fill.cpp index 763c7e2fcf..e1380bfad8 100644 --- a/src/renderer/shader-fill.cpp +++ b/src/renderer/shader-fill.cpp @@ -1,9 +1,14 @@ #include <llmr/renderer/shader-fill.hpp> +#include <llmr/shader/shaders.h> +#include <llmr/platform/gl.hpp> using namespace llmr; -FillShader::FillShader(const GLchar *vertSource, const GLchar *fragSource) - : Shader(vertSource, fragSource) { +FillShader::FillShader() + : Shader( + llmr_shaders[FILL_SHADER].vertex, + llmr_shaders[FILL_SHADER].fragment + ) { if (!valid) return; a_pos = glGetAttribLocation(program, "a_pos"); diff --git a/src/renderer/shader-line.cpp b/src/renderer/shader-line.cpp index 2f3381bf5b..658e244d56 100644 --- a/src/renderer/shader-line.cpp +++ b/src/renderer/shader-line.cpp @@ -1,10 +1,24 @@ #include <llmr/renderer/shader-line.hpp> +#include <llmr/shader/shaders.h> +#include <llmr/platform/gl.hpp> + +#include <cstdio> using namespace llmr; -LineShader::LineShader(const GLchar *vertSource, const GLchar *fragSource) - : Shader(vertSource, fragSource) { - if (!valid) return; +LineShader::LineShader() + : Shader( + llmr_shaders[LINE_SHADER].vertex, + llmr_shaders[LINE_SHADER].fragment + ), + a_pos(42) { + if (!valid) { + fprintf(stderr, "invalid line shader\n"); + return; + } + + GLint pos = glGetAttribLocation(program, "a_pos"); + fprintf(stderr, "a_pos: %d\n", pos); a_pos = glGetAttribLocation(program, "a_pos"); attributes.push_back(a_pos); diff --git a/src/renderer/shader.cpp b/src/renderer/shader.cpp index 00af17e607..d9614c0ad9 100644 --- a/src/renderer/shader.cpp +++ b/src/renderer/shader.cpp @@ -1,4 +1,5 @@ - #include <llmr/renderer/shader.hpp> +#include <llmr/renderer/shader.hpp> +#include <llmr/platform/gl.hpp> #include <cstdlib> #include <cstdio> @@ -102,7 +103,20 @@ bool Shader::compileShader(GLuint *shader, GLenum type, const GLchar *source) { GLint status; *shader = glCreateShader(type); + +#ifdef EMSCRIPTEN + // Add WebGL GSLSL precision premable + const char *preamble = "precision mediump float;\n\n"; + int preamble_length = strlen(preamble); + int source_length = strlen(source); + char *modified_source = (char *)malloc(preamble_length + source_length); + strncpy(&modified_source[0], preamble, preamble_length); + strncpy(&modified_source[preamble_length], source, source_length); + glShaderSource(*shader, 1, (const GLchar **)(&modified_source), NULL); +#else glShaderSource(*shader, 1, &source, NULL); +#endif + glCompileShader(*shader); #if defined(DEBUG) diff --git a/src/shader/line.fragment.glsl b/src/shader/line.fragment.glsl index 8df552c171..0656051313 100644 --- a/src/shader/line.fragment.glsl +++ b/src/shader/line.fragment.glsl @@ -1,3 +1,4 @@ + uniform vec4 u_color; void main() { diff --git a/src/shader/shaders.c b/src/shader/shaders.c new file mode 100644 index 0000000000..e505fac3f0 --- /dev/null +++ b/src/shader/shaders.c @@ -0,0 +1,13 @@ +// NOTE: DO NOT CHANGE THIS FILE. IT IS AUTOMATICALLY GENERATED. +#include <llmr/shader/shaders.h> + +const llmr_shader_t llmr_shaders[SHADER_COUNT] = { + [FILL_SHADER] = { + .vertex = "attribute vec2 a_pos;\n\nuniform mat4 u_matrix;\n\nvoid main() {\n gl_Position = u_matrix * vec4(a_pos, 0, 1);\n}\n", + .fragment = "uniform vec4 u_color;\n\nvoid main() {\n gl_FragColor = u_color;\n}\n", + }, + [LINE_SHADER] = { + .vertex = "attribute vec2 a_pos;\n\nuniform mat4 u_matrix;\n\nvoid main() {\n float z = step(32767.0, a_pos.x) * 2.0;\n gl_Position = u_matrix * vec4(a_pos, z, 1);\n }\n", + .fragment = "uniform vec4 u_color;\n\nvoid main() {\n gl_FragColor = u_color;\n}\n", + } +}; |