kmscon_LDADD = libkmscon-core.la
test_console_SOURCES = tests/test_console.c
-test_console_LDADD = \
- libkmscon-core.la \
- $(OPENGL_LIBS)
-test_console_CPPFLAGS = \
- $(AM_CPPFLAGS) \
- $(OPENGL_CFLAGS)
+test_console_LDADD = libkmscon-core.la
test_output_SOURCES = tests/test_output.c
test_output_LDADD = libkmscon-core.la
* to a framebuffer as used by terminals and consoles.
*/
-/*
- * TODO: Avoid using this hack and instead retrieve GL extension
- * pointers dynamically on initialization.
- */
-#define GL_GLEXT_PROTOTYPES
-
#include <errno.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#include <cairo.h>
-#include <GL/gl.h>
-#include <GL/glext.h>
#include "console.h"
#include "font.h"
size_t ref;
struct kmscon_font_factory *ff;
struct kmscon_compositor *comp;
+ struct kmscon_context *ctx;
/* GL texture and font */
- GLuint tex;
+ unsigned int tex;
unsigned int res_x;
unsigned int res_y;
struct kmscon_font *font;
static void kmscon_console_free_res(struct kmscon_console *con)
{
if (con && con->cr) {
- glDeleteTextures(1, &con->tex);
+ kmscon_context_free_tex(con->ctx, con->tex);
cairo_destroy(con->cr);
cairo_surface_destroy(con->surf);
free(con->surf_buf);
con->surf = surface;
con->cr = cr;
- glGenTextures(1, &con->tex);
- glBindTexture(GL_TEXTURE_RECTANGLE, con->tex);
- glTexImage2D(GL_TEXTURE_RECTANGLE, 0, GL_RGBA, con->res_x, con->res_y,
- 0, GL_BGRA, GL_UNSIGNED_BYTE, con->surf_buf);
- glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
+ con->tex = kmscon_context_new_tex(con->ctx);
log_debug("console: new resolution %ux%u\n", con->res_x, con->res_y);
return 0;
con->ref = 1;
con->ff = ff;
con->comp = comp;
+ con->ctx = kmscon_compositor_get_context(comp);
log_debug("console: new console\n");
ret = kmscon_buffer_new(&con->cells, 0, 0);
cairo_restore(con->cr);
/* refresh GL texture contents */
- glBindTexture(GL_TEXTURE_RECTANGLE, con->tex);
- glTexImage2D(GL_TEXTURE_RECTANGLE, 0, GL_RGBA, con->res_x, con->res_y,
- 0, GL_BGRA, GL_UNSIGNED_BYTE, con->surf_buf);
+ kmscon_context_set_tex(con->ctx, con->tex, con->res_x, con->res_y,
+ con->surf_buf);
}
/*
*/
void kmscon_console_map(struct kmscon_console *con)
{
+ static const float vertices[] = { -1, -1, 1, -1, 1, 1, -1, 1 };
+ static const float texpos[] = { 0, 0, 1, 0, 1, 1, 0, 1 };
+
if (!con || !con->cr)
return;
- glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glEnable(GL_TEXTURE_RECTANGLE);
- glBindTexture(GL_TEXTURE_RECTANGLE, con->tex);
-
- glBegin(GL_QUADS);
- glColor4f(0.0f, 0.0f, 0.0f, 0.0f);
-
- glTexCoord2f(0.0f, 0.0f);
- glVertex2f(-1.0f, -1.0f);
-
- glTexCoord2f(con->res_x, 0.0f);
- glVertex2f(1.0f, -1.0f);
-
- glTexCoord2f(con->res_x, con->res_y);
- glVertex2f(1.0f, 1.0f);
-
- glTexCoord2f(0.0f, con->res_y);
- glVertex2f(-1.0f, 1.0f);
- glEnd();
+ kmscon_context_draw_tex(con->ctx, vertices, texpos, 4, con->tex);
}
void kmscon_console_write(struct kmscon_console *con, kmscon_symbol_t ch)
void kmscon_context_clear(struct kmscon_context *ctx);
void kmscon_context_draw_def(struct kmscon_context *ctx, float *vertices,
float *colors, size_t num);
+void kmscon_context_draw_tex(struct kmscon_context *ctx, const float *vertices,
+ const float *texcoords, size_t num, unsigned int tex);
+unsigned int kmscon_context_new_tex(struct kmscon_context *ctx);
+void kmscon_context_free_tex(struct kmscon_context *ctx, unsigned int tex);
+void kmscon_context_set_tex(struct kmscon_context *ctx, unsigned int tex,
+ unsigned int width, unsigned int height, void *buf);
/* compositors */
(GLuint program, const GLchar *name);
typedef void (*PFNGLUNIFORMMATRIX4FVPROC) (GLint location,
GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (*PFNGLUNIFORM1IPROC) (GLint location, GLint v0);
typedef void (*PFNGLVERTEXATTRIBPOINTERPROC)
(GLuint index, GLint size, GLenum type, GLboolean normalized,
GLsizei stride, const GLvoid *pointer);
PFNGLGETPROGRAMINFOLOGPROC proc_get_program_info_log;
PFNGLGETUNIFORMLOCATIONPROC proc_get_uniform_location;
PFNGLUNIFORMMATRIX4FVPROC proc_uniform_matrix_4fv;
+ PFNGLUNIFORM1IPROC proc_uniform_1i;
PFNGLVERTEXATTRIBPOINTERPROC proc_vertex_attrib_pointer;
PFNGLENABLEVERTEXATTRIBARRAYPROC proc_enable_vertex_attrib_array;
PFNGLDRAWARRAYSEXTPROC proc_draw_arrays;
(void*) eglGetProcAddress("glGetUniformLocation");
ctx->proc_uniform_matrix_4fv =
(void*) eglGetProcAddress("glUniformMatrix4fv");
+ ctx->proc_uniform_1i =
+ (void*) eglGetProcAddress("glUniform1i");
ctx->proc_vertex_attrib_pointer =
(void*) eglGetProcAddress("glVertexAttribPointer");
ctx->proc_enable_vertex_attrib_array =
!ctx->proc_get_program_info_log ||
!ctx->proc_get_uniform_location ||
!ctx->proc_uniform_matrix_4fv ||
+ !ctx->proc_uniform_1i ||
!ctx->proc_vertex_attrib_pointer ||
!ctx->proc_enable_vertex_attrib_array ||
!ctx->proc_draw_arrays) {
ctx->proc_draw_arrays(GL_QUADS, 0, num);
}
+void kmscon_context_draw_tex(struct kmscon_context *ctx, const float *vertices,
+ const float *texcoords, size_t num, unsigned int tex)
+{
+ static const float m[16] = { 1, 0, 0, 0,
+ 0, 1, 0, 0,
+ 0, 0, 1, 0,
+ 0, 0, 0, 1 };
+
+ if (!ctx)
+ return;
+
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_2D, tex);
+
+ ctx->proc_use_program(ctx->tex_program);
+ ctx->proc_uniform_matrix_4fv(ctx->tex_uni_projection, 1, GL_FALSE, m);
+ ctx->proc_uniform_1i(ctx->tex_uni_texture, 0);
+
+ ctx->proc_vertex_attrib_pointer(0, 2, GL_FLOAT, GL_FALSE, 0, vertices);
+ ctx->proc_vertex_attrib_pointer(1, 2, GL_FLOAT, GL_FALSE, 0, texcoords);
+ ctx->proc_enable_vertex_attrib_array(0);
+ ctx->proc_enable_vertex_attrib_array(1);
+ ctx->proc_draw_arrays(GL_QUADS, 0, num);
+}
+
+unsigned int kmscon_context_new_tex(struct kmscon_context *ctx)
+{
+ GLuint tex = 0;
+
+ if (!ctx)
+ return tex;
+
+ glGenTextures(1, &tex);
+ glBindTexture(GL_TEXTURE_2D, tex);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+
+ return tex;
+}
+
+void kmscon_context_free_tex(struct kmscon_context *ctx, unsigned int tex)
+{
+ if (!ctx)
+ return;
+
+ glDeleteTextures(1, &tex);
+}
+
+void kmscon_context_set_tex(struct kmscon_context *ctx, unsigned int tex,
+ unsigned int width, unsigned int height, void *buf)
+{
+ if (!ctx || !buf || !width || !height)
+ return;
+
+ glBindTexture(GL_TEXTURE_2D, tex);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_BGRA,
+ GL_UNSIGNED_BYTE, buf);
+}
+
int renderbuffer_new(struct renderbuffer **out, struct kmscon_context *ctx,
void *bo)
{
*/
#define _BSD_SOURCE
-#define GL_GLEXT_PROTOTYPES
#include <errno.h>
#include <inttypes.h>
#include <string.h>
#include <unistd.h>
-#include <GL/gl.h>
-#include <GL/glext.h>
#include "console.h"
#include "eloop.h"
#include "font.h"
{
int ret;
struct kmscon_output *iter;
+ struct kmscon_context *ctx;
if (kmscon_compositor_is_asleep(con->comp))
return;
kmscon_console_draw(con->con);
+ ctx = kmscon_compositor_get_context(con->comp);
iter = kmscon_compositor_get_outputs(con->comp);
for ( ; iter; iter = kmscon_output_next(iter)) {
if (ret)
continue;
- glClearColor(0.0, 0.0, 0.0, 1.0);
- glClear(GL_COLOR_BUFFER_BIT);
-
+ kmscon_context_clear(ctx);
kmscon_console_map(con->con);
ret = kmscon_output_swap(iter);