aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDrew DeVault <sir@cmpwn.com>2017-06-15 15:31:13 -0400
committerDrew DeVault <sir@cmpwn.com>2017-06-15 15:31:13 -0400
commit2443a070e75e33285b6d5ed0ce89c989956b9065 (patch)
tree1ae59cb449eb6e1dc212e60dbb9d33545735cd6f
parent4a9966b1a47d497ccc9473a24ba56b3d0eef72d2 (diff)
Add colored quad and ellipse rendering primitives
-rw-r--r--example/CMakeLists.txt12
-rw-r--r--example/tablet.c63
-rw-r--r--include/render/gles3.h3
-rw-r--r--include/wlr/render.h10
-rw-r--r--include/wlr/render/interface.h4
-rw-r--r--render/gles3/renderer.c35
-rw-r--r--render/gles3/shaders.c75
-rw-r--r--render/wlr_renderer.c10
8 files changed, 192 insertions, 20 deletions
diff --git a/example/CMakeLists.txt b/example/CMakeLists.txt
index a6085392..fff2e49b 100644
--- a/example/CMakeLists.txt
+++ b/example/CMakeLists.txt
@@ -53,3 +53,15 @@ target_link_libraries(touch
wlr-render
${XKBCOMMON_LIBRARIES}
)
+
+add_executable(tablet
+ tablet.c
+ shared.c
+)
+
+target_link_libraries(tablet
+ wlr-backend
+ wlr-session
+ wlr-render
+ ${XKBCOMMON_LIBRARIES}
+)
diff --git a/example/tablet.c b/example/tablet.c
new file mode 100644
index 00000000..9a498438
--- /dev/null
+++ b/example/tablet.c
@@ -0,0 +1,63 @@
+#define _POSIX_C_SOURCE 199309L
+#define _XOPEN_SOURCE 500
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include <string.h>
+#include <unistd.h>
+#include <wayland-server.h>
+#include <wayland-server-protocol.h>
+#include <xkbcommon/xkbcommon.h>
+#include <GLES3/gl3.h>
+#include <wlr/render/matrix.h>
+#include <wlr/render/gles3.h>
+#include <wlr/render.h>
+#include <wlr/backend.h>
+#include <wlr/session.h>
+#include <wlr/types.h>
+#include <math.h>
+#include "shared.h"
+#include "cat.h"
+
+struct sample_state {
+ struct wlr_renderer *renderer;
+};
+
+static void handle_output_frame(struct output_state *output, struct timespec *ts) {
+ struct compositor_state *state = output->compositor;
+ struct sample_state *sample = state->data;
+ struct wlr_output *wlr_output = output->output;
+
+ wlr_renderer_begin(sample->renderer, wlr_output);
+
+ float matrix[16];
+ float color[4] = { 0, 1.0, 0, 1.0 };
+ wlr_matrix_scale(&matrix, 128, 128, 1);
+ wlr_matrix_mul(&wlr_output->transform_matrix, &matrix, &matrix);
+ wlr_render_colored_ellipse(sample->renderer, &color, &matrix);
+
+ wlr_renderer_end(sample->renderer);
+}
+
+static void handle_keyboard_key(struct keyboard_state *kbstate,
+ xkb_keysym_t sym, enum wlr_key_state key_state) {
+ if (sym == XKB_KEY_Escape) {
+ kbstate->compositor->exit = true;
+ }
+}
+
+int main(int argc, char *argv[]) {
+ struct sample_state state = { 0 };
+ struct compositor_state compositor;
+
+ compositor_init(&compositor);
+ compositor.output_frame_cb = handle_output_frame;
+ compositor.keyboard_key_cb = handle_keyboard_key;
+
+ state.renderer = wlr_gles3_renderer_init();
+
+ compositor.data = &state;
+ compositor_run(&compositor);
+
+ wlr_renderer_destroy(state.renderer);
+}
diff --git a/include/render/gles3.h b/include/render/gles3.h
index 5efb197e..9acc1088 100644
--- a/include/render/gles3.h
+++ b/include/render/gles3.h
@@ -13,6 +13,9 @@ struct wlr_surface_state {
struct wlr_surface *gles3_surface_init();
+extern const GLchar quad_vertex_src[];
+extern const GLchar quad_fragment_src[];
+extern const GLchar ellipse_fragment_src[];
extern const GLchar vertex_src[];
extern const GLchar fragment_src_RGB[];
extern const GLchar fragment_src_RGBA[];
diff --git a/include/wlr/render.h b/include/wlr/render.h
index 88aa615e..3c0bd04b 100644
--- a/include/wlr/render.h
+++ b/include/wlr/render.h
@@ -29,6 +29,16 @@ struct wlr_surface *wlr_render_surface_init(struct wlr_renderer *r);
bool wlr_render_with_matrix(struct wlr_renderer *r,
struct wlr_surface *surface, const float (*matrix)[16]);
/**
+ * Renders a solid quad in the specified color.
+ */
+void wlr_render_colored_quad(struct wlr_renderer *r,
+ const float (*color)[4], const float (*matrix)[16]);
+/**
+ * Renders a solid ellipse in the specified color.
+ */
+void wlr_render_colored_ellipse(struct wlr_renderer *r,
+ const float (*color)[4], const float (*matrix)[16]);
+/**
* Destroys this wlr_renderer. Surfaces must be destroyed separately.
*/
void wlr_renderer_destroy(struct wlr_renderer *renderer);
diff --git a/include/wlr/render/interface.h b/include/wlr/render/interface.h
index 80471ac8..a934f49e 100644
--- a/include/wlr/render/interface.h
+++ b/include/wlr/render/interface.h
@@ -19,6 +19,10 @@ struct wlr_renderer_impl {
struct wlr_surface *(*surface_init)(struct wlr_renderer_state *state);
bool (*render_with_matrix)(struct wlr_renderer_state *state,
struct wlr_surface *surface, const float (*matrix)[16]);
+ void (*render_quad)(struct wlr_renderer_state *state,
+ const float (*color)[4], const float (*matrix)[16]);
+ void (*render_ellipse)(struct wlr_renderer_state *state,
+ const float (*color)[4], const float (*matrix)[16]);
void (*destroy)(struct wlr_renderer_state *state);
};
diff --git a/render/gles3/renderer.c b/render/gles3/renderer.c
index 74754d1b..b0056193 100644
--- a/render/gles3/renderer.c
+++ b/render/gles3/renderer.c
@@ -13,6 +13,8 @@
static struct {
bool initialized;
GLuint rgb, rgba;
+ GLuint quad;
+ GLuint ellipse;
} shaders;
static GLuint vao, vbo, ebo;
@@ -28,6 +30,9 @@ static bool compile_shader(GLuint type, const GLchar *src, GLuint *shader) {
GL_CALL(glGetShaderiv(*shader, GL_INFO_LOG_LENGTH, &loglen));
GLchar msg[loglen];
GL_CALL(glGetShaderInfoLog(*shader, loglen, &loglen, msg));
+ wlr_log(L_ERROR, "Shader compilation failed");
+ wlr_log(L_ERROR, "%s", msg);
+ exit(1);
return false;
}
return true;
@@ -60,6 +65,12 @@ static void init_default_shaders() {
if (!compile_program(vertex_src, fragment_src_RGBA, &shaders.rgba)) {
goto error;
}
+ if (!compile_program(quad_vertex_src, quad_fragment_src, &shaders.quad)) {
+ goto error;
+ }
+ if (!compile_program(quad_vertex_src, ellipse_fragment_src, &shaders.ellipse)) {
+ goto error;
+ }
return;
error:
wlr_log(L_ERROR, "Failed to set up default shaders!");
@@ -141,6 +152,28 @@ static bool wlr_gles3_render_surface(struct wlr_renderer_state *state,
return true;
}
+static void wlr_gles3_render_quad(struct wlr_renderer_state *state,
+ const float (*color)[4], const float (*matrix)[16]) {
+ GL_CALL(glUseProgram(shaders.quad));
+ GL_CALL(glBindVertexArray(vao));
+ GL_CALL(glBindBuffer(GL_ARRAY_BUFFER, vbo));
+ GL_CALL(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo));
+ GL_CALL(glUniformMatrix4fv(0, 1, GL_TRUE, *matrix));
+ GL_CALL(glUniform4f(1, (*color)[0], (*color)[1], (*color)[2], (*color)[3]));
+ GL_CALL(glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0));
+}
+
+static void wlr_gles3_render_ellipse(struct wlr_renderer_state *state,
+ const float (*color)[4], const float (*matrix)[16]) {
+ GL_CALL(glUseProgram(shaders.ellipse));
+ GL_CALL(glBindVertexArray(vao));
+ GL_CALL(glBindBuffer(GL_ARRAY_BUFFER, vbo));
+ GL_CALL(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo));
+ GL_CALL(glUniformMatrix4fv(0, 1, GL_TRUE, *matrix));
+ GL_CALL(glUniform4f(1, (*color)[0], (*color)[1], (*color)[2], (*color)[3]));
+ GL_CALL(glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0));
+}
+
static void wlr_gles3_destroy(struct wlr_renderer_state *state) {
// no-op
}
@@ -150,6 +183,8 @@ static struct wlr_renderer_impl wlr_renderer_impl = {
.end = wlr_gles3_end,
.surface_init = wlr_gles3_surface_init,
.render_with_matrix = wlr_gles3_render_surface,
+ .render_quad = wlr_gles3_render_quad,
+ .render_ellipse = wlr_gles3_render_ellipse,
.destroy = wlr_gles3_destroy
};
diff --git a/render/gles3/shaders.c b/render/gles3/shaders.c
index f53ef385..dd7f790f 100644
--- a/render/gles3/shaders.c
+++ b/render/gles3/shaders.c
@@ -1,28 +1,63 @@
#include "render/gles3.h"
#include <GLES3/gl3.h>
+// Colored quads
+const GLchar quad_vertex_src[] =
+"uniform mat4 proj;"
+"uniform vec4 color;"
+"attribute vec2 pos;"
+"attribute vec2 texcoord;"
+"varying vec4 v_color;"
+"varying vec2 v_texcoord;"
+"void main() {"
+" gl_Position = proj * vec4(pos, 0.0, 1.0);"
+" v_color = color;"
+" v_texcoord = texcoord;"
+"}";
+
+const GLchar quad_fragment_src[] =
+"precision mediump float;"
+"varying vec4 v_color;"
+"varying vec2 v_texcoord;"
+"void main() {"
+" gl_FragColor = v_color;"
+"}";
+
+// Colored ellipses (TODO)
+
+const GLchar ellipse_fragment_src[] =
+"precision mediump float;"
+"varying vec4 v_color;"
+"varying vec2 v_texcoord;"
+"void main() {"
+" float l = length(v_texcoord - vec2(0.5, 0.5));"
+" if (l > 0.5) discard;"
+" gl_FragColor = v_color;"
+"}";
+
+// Textured quads
const GLchar vertex_src[] =
-"uniform mat4 proj;\n"
-"attribute vec2 pos;\n"
-"attribute vec2 texcoord;\n"
-"varying vec2 v_texcoord;\n"
-"void main() {\n"
-" gl_Position = proj * vec4(pos, 0.0, 1.0);\n"
-" v_texcoord = texcoord;\n"
-"}\n";
+"uniform mat4 proj;"
+"attribute vec2 pos;"
+"attribute vec2 texcoord;"
+"varying vec2 v_texcoord;"
+"void main() {"
+" gl_Position = proj * vec4(pos, 0.0, 1.0);"
+" v_texcoord = texcoord;"
+"}";
const GLchar fragment_src_RGB[] =
-"precision mediump float;\n"
-"varying vec2 v_texcoord;\n"
-"uniform sampler2D tex;\n"
-"void main() {\n"
-" gl_FragColor = vec4(texture2D(tex, v_texcoord).rgb, 1.0);\n"
-"}\n";
+"precision mediump float;"
+"varying vec2 v_texcoord;"
+"uniform sampler2D tex;"
+"void main() {"
+" gl_FragColor = vec4(texture2D(tex, v_texcoord).rgb, 1.0);"
+"}";
const GLchar fragment_src_RGBA[] =
-"precision mediump float;\n"
-"varying vec2 v_texcoord;\n"
-"uniform sampler2D tex;\n"
-"void main() {\n"
-" gl_FragColor = texture2D(tex, v_texcoord);\n"
-"}\n";
+"precision mediump float;"
+"varying vec2 v_texcoord;"
+"uniform sampler2D tex;"
+"void main() {"
+" gl_FragColor = texture2D(tex, v_texcoord);"
+"}";
diff --git a/render/wlr_renderer.c b/render/wlr_renderer.c
index 2fd2fd31..f48bb3eb 100644
--- a/render/wlr_renderer.c
+++ b/render/wlr_renderer.c
@@ -31,3 +31,13 @@ bool wlr_render_with_matrix(struct wlr_renderer *r,
struct wlr_surface *surface, const float (*matrix)[16]) {
return r->impl->render_with_matrix(r->state, surface, matrix);
}
+
+void wlr_render_colored_quad(struct wlr_renderer *r,
+ const float (*color)[4], const float (*matrix)[16]) {
+ r->impl->render_quad(r->state, color, matrix);
+}
+
+void wlr_render_colored_ellipse(struct wlr_renderer *r,
+ const float (*color)[4], const float (*matrix)[16]) {
+ r->impl->render_ellipse(r->state, color, matrix);
+}