emscripten support
This commit is contained in:
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
*.o
|
||||
/emscripten/main.js
|
||||
/emscripten/main.js.map
|
||||
20
Makefile
20
Makefile
@@ -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
|
||||
|
||||
30
README.md
Normal file
30
README.md
Normal file
@@ -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);
|
||||
```
|
||||
77
bin/build-shaders.js
Executable file
77
bin/build-shaders.js
Executable file
@@ -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();
|
||||
154
emscripten/main.cpp
Normal file
154
emscripten/main.cpp
Normal file
@@ -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;
|
||||
}
|
||||
9
emscripten/main.html
Normal file
9
emscripten/main.html
Normal file
@@ -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>
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
28
include/llmr/shader/shaders.h
Normal file
28
include/llmr/shader/shaders.h
Normal file
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#include <llmr/geometry/linevertexbuffer.hpp>
|
||||
#include <llmr/platform/gl.hpp>
|
||||
|
||||
#include <cstdio>
|
||||
|
||||
|
||||
@@ -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++;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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];
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
|
||||
uniform vec4 u_color;
|
||||
|
||||
void main() {
|
||||
|
||||
13
src/shader/shaders.c
Normal file
13
src/shader/shaders.c
Normal file
@@ -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",
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user