From 714c5d08bfcaec8102f12661fc6e335722c114c5 Mon Sep 17 00:00:00 2001 From: nullifiedcat Date: Fri, 10 Nov 2017 09:26:05 +0300 Subject: [PATCH] programs --- ftgl/mat4.c | 245 +++++++++++++++++++++++++++++++ ftgl/mat4.h | 91 ++++++++++++ include/drawglx_internal.h | 48 +++--- include/programs.h | 33 +++++ src/drawglx_internal.c | 14 +- src/program_freetype.c | 47 ++++++ src/program_triangles_plain.c | 37 +++++ src/program_triangles_textured.c | 37 +++++ src/programs.c | 9 ++ 9 files changed, 537 insertions(+), 24 deletions(-) create mode 100644 ftgl/mat4.c create mode 100644 ftgl/mat4.h create mode 100644 include/programs.h create mode 100644 src/program_freetype.c create mode 100644 src/program_triangles_plain.c create mode 100644 src/program_triangles_textured.c create mode 100644 src/programs.c diff --git a/ftgl/mat4.c b/ftgl/mat4.c new file mode 100644 index 0000000..7a986fa --- /dev/null +++ b/ftgl/mat4.c @@ -0,0 +1,245 @@ +/* Freetype GL - A C OpenGL Freetype engine + * + * Distributed under the OSI-approved BSD 2-Clause License. See accompanying + * file `LICENSE` for more details. + */ +#include +#include +#include +#include "mat4.h" + +mat4 * +mat4_new( void ) +{ + mat4 *self = (mat4 *) malloc( sizeof(mat4) ); + return self; + +} + +void +mat4_set_zero( mat4 *self ) +{ + if (!self) + return; + + memset( self, 0, sizeof( mat4 )); +} + +void +mat4_set_identity( mat4 *self ) +{ + if (!self) + return; + + memset( self, 0, sizeof( mat4 )); + self->m00 = 1.0; + self->m11 = 1.0; + self->m22 = 1.0; + self->m33 = 1.0; +} + +void +mat4_multiply( mat4 *self, mat4 *other ) +{ + mat4 m; + size_t i; + + if (!self || !other) + return; + + for( i=0; i<4; ++i ) + { + m.data[i*4+0] = + (self->data[i*4+0] * other->data[0*4+0]) + + (self->data[i*4+1] * other->data[1*4+0]) + + (self->data[i*4+2] * other->data[2*4+0]) + + (self->data[i*4+3] * other->data[3*4+0]) ; + + m.data[i*4+1] = + (self->data[i*4+0] * other->data[0*4+1]) + + (self->data[i*4+1] * other->data[1*4+1]) + + (self->data[i*4+2] * other->data[2*4+1]) + + (self->data[i*4+3] * other->data[3*4+1]) ; + + m.data[i*4+2] = + (self->data[i*4+0] * other->data[0*4+2]) + + (self->data[i*4+1] * other->data[1*4+2]) + + (self->data[i*4+2] * other->data[2*4+2]) + + (self->data[i*4+3] * other->data[3*4+2]) ; + + m.data[i*4+3] = + (self->data[i*4+0] * other->data[0*4+3]) + + (self->data[i*4+1] * other->data[1*4+3]) + + (self->data[i*4+2] * other->data[2*4+3]) + + (self->data[i*4+3] * other->data[3*4+3]) ; + } + memcpy( self, &m, sizeof( mat4 ) ); + +} + + +void +mat4_set_orthographic( mat4 *self, + float left, float right, + float bottom, float top, + float znear, float zfar ) +{ + if (!self) + return; + + if (left == right || bottom == top || znear == zfar) + return; + + mat4_set_zero( self ); + + self->m00 = +2.0f/(right-left); + self->m30 = -(right+left)/(right-left); + self->m11 = +2.0f/(top-bottom); + self->m31 = -(top+bottom)/(top-bottom); + self->m22 = -2.0f/(zfar-znear); + self->m32 = -(zfar+znear)/(zfar-znear); + self->m33 = 1.0f; +} + +void +mat4_set_perspective( mat4 *self, + float fovy, float aspect, + float znear, float zfar) +{ + float h, w; + + if (!self) + return; + + if (znear == zfar) + return; + + h = (float)tan(fovy / 360.0 * M_PI) * znear; + w = h * aspect; + + mat4_set_frustum( self, -w, w, -h, h, znear, zfar ); +} + +void +mat4_set_frustum( mat4 *self, + float left, float right, + float bottom, float top, + float znear, float zfar ) +{ + + if (!self) + return; + + if (left == right || bottom == top || znear == zfar) + return; + + mat4_set_zero( self ); + + self->m00 = (2.0f*znear)/(right-left); + self->m20 = (right+left)/(right-left); + + self->m11 = (2.0f*znear)/(top-bottom); + self->m21 = (top+bottom)/(top-bottom); + + self->m22 = -(zfar+znear)/(zfar-znear); + self->m32 = -(2.0f*zfar*znear)/(zfar-znear); + + self->m23 = -1.0f; +} + +void +mat4_set_rotation( mat4 *self, + float angle, + float x, float y, float z) +{ + float c, s, norm; + + if (!self) + return; + + c = (float)cos( M_PI*angle/180.0 ); + s = (float)sin( M_PI*angle/180.0 ); + norm = (float)sqrt(x*x+y*y+z*z); + + x /= norm; y /= norm; z /= norm; + + mat4_set_identity( self ); + + self->m00 = x*x*(1-c)+c; + self->m10 = y*x*(1-c)-z*s; + self->m20 = z*x*(1-c)+y*s; + + self->m01 = x*y*(1-c)+z*s; + self->m11 = y*y*(1-c)+c; + self->m21 = z*y*(1-c)-x*s; + + self->m02 = x*z*(1-c)-y*s; + self->m12 = y*z*(1-c)+x*s; + self->m22 = z*z*(1-c)+c; +} + +void +mat4_set_translation( mat4 *self, + float x, float y, float z) +{ + if (!self) + return; + + mat4_set_identity( self ); + self-> m30 = x; + self-> m31 = y; + self-> m32 = z; +} + +void +mat4_set_scaling( mat4 *self, + float x, float y, float z) +{ + if (!self) + return; + + mat4_set_identity( self ); + self-> m00 = x; + self-> m11 = y; + self-> m22 = z; +} + +void +mat4_rotate( mat4 *self, + float angle, + float x, float y, float z) +{ + mat4 m; + + if (!self) + return; + + mat4_set_rotation( &m, angle, x, y, z); + mat4_multiply( self, &m ); +} + +void +mat4_translate( mat4 *self, + float x, float y, float z) +{ + mat4 m; + + if (!self) + return; + + mat4_set_translation( &m, x, y, z); + mat4_multiply( self, &m ); +} + +void +mat4_scale( mat4 *self, + float x, float y, float z) +{ + mat4 m; + + if (!self) + return; + + mat4_set_scaling( &m, x, y, z); + mat4_multiply( self, &m ); +} diff --git a/ftgl/mat4.h b/ftgl/mat4.h new file mode 100644 index 0000000..83d6f30 --- /dev/null +++ b/ftgl/mat4.h @@ -0,0 +1,91 @@ +/* Freetype GL - A C OpenGL Freetype engine + * + * Distributed under the OSI-approved BSD 2-Clause License. See accompanying + * file `LICENSE` for more details. + */ +#ifndef __MAT4_H__ +#define __MAT4_H__ + +#ifdef __cplusplus +extern "C" { +namespace ftgl { +#endif + + +/** + * + */ +typedef union +{ + float data[16]; /**< All compoments at once */ + struct { + float m00, m01, m02, m03; + float m10, m11, m12, m13; + float m20, m21, m22, m23; + float m30, m31, m32, m33; + }; +} mat4; + + +mat4 * +mat4_new( void ); + +void +mat4_set_identity( mat4 *self ); + +void +mat4_set_zero( mat4 *self ); + +void +mat4_multiply( mat4 *self, mat4 *other ); + +void +mat4_set_orthographic( mat4 *self, + float left, float right, + float bottom, float top, + float znear, float zfar ); + +void +mat4_set_perspective( mat4 *self, + float fovy, float aspect, + float zNear, float zFar); + +void +mat4_set_frustum( mat4 *self, + float left, float right, + float bottom, float top, + float znear, float zfar ); + +void +mat4_set_rotation( mat4 *self, + float angle, + float x, float y, float z); + +void +mat4_set_translation( mat4 *self, + float x, float y, float z); + +void +mat4_set_scaling( mat4 *self, + float x, float y, float z); + +void +mat4_rotate( mat4 *self, + float angle, + float x, float y, float z); + +void +mat4_translate( mat4 *self, + float x, float y, float z); + +void +mat4_scale( mat4 *self, + float x, float y, float z); + + +#ifdef __cplusplus +} +} +#endif + +#endif /* __MAT4_H__ */ diff --git a/include/drawglx_internal.h b/include/drawglx_internal.h index 7f56ae4..ce4409d 100644 --- a/include/drawglx_internal.h +++ b/include/drawglx_internal.h @@ -11,6 +11,7 @@ #include "vector.h" #include "vec234.h" +#include "mat4.h" enum { @@ -20,25 +21,23 @@ enum PROGRAM_COUNT }; -enum -{ - CMD_VERTEX_BUFFER -}; - typedef void(*program_callback_fn)(struct draw_cmd *); +typedef void(*program_callback_empty_fn)(); struct program_t { - vertex_buffer_t vertex; + vertex_buffer_t *vertex; GLuint shader; - program_callback_fn load; + program_callback_empty_fn init; + program_callback_empty_fn load; program_callback_fn render; - program_callback_fn unload; + program_callback_empty_fn unload; + program_callback_empty_fn destroy; }; void -program_init_inplace(struct program_t *program, const char *vertex_format, const char *shader_frag, const char *shader_vert, program_callback_fn load, program_callback_fn unload); +program_init_inplace(struct program_t *program, const char *vertex_format, const char *shader_frag, const char *shader_vert, program_callback_empty_fn init, program_callback_empty_fn load, program_callback_fn render, program_callback_empty_fn unload, program_callback_empty_fn destroy); struct program_t programs[PROGRAM_COUNT]; @@ -47,9 +46,9 @@ drawglx_internal_init(); struct draw_cmd { - vertex_buffer_t vertex; - int program; - GLuint texture; + vector_t *vertices; + int program; + GLuint texture; }; struct draw_cmd* @@ -57,32 +56,39 @@ draw_cmd_new(); struct draw_state { + mat4 model, view, projection; + int program; + GLuint texture; + GLuint shader; + struct vector_t *commands; struct size_t current_command; }; -struct draw_state* -draw_state_init(size_t vertex_size); +struct draw_state drawstate; void -draw_state_next_command(struct draw_state *state); +draw_state_init(); void -draw_state_free(struct draw_state *state); +draw_state_next_command(); void -draw_state_clear(struct draw_state *state); +draw_state_free(); void -draw_state_render(struct draw_state *state); +draw_state_clear(); void -draw_set_texture(struct draw_state *state, GLuint texture); +draw_state_render(); void -draw_line(struct draw_state *state, float x, float y, float x2, float y2); +draw_set_texture(GLuint texture); void -draw_rect(struct draw_state *state, float x, float y, float w, float h); +draw_line(float x, float y, float x2, float y2); + +void +draw_rect(float x, float y, float w, float h); diff --git a/include/programs.h b/include/programs.h new file mode 100644 index 0000000..c36384e --- /dev/null +++ b/include/programs.h @@ -0,0 +1,33 @@ +/* + * programs.h + * + * Created on: Nov 10, 2017 + * Author: nullifiedcat + */ + +#pragma once + +#define PROGRAM_INIT(name) program_##name##_init +#define PROGRAM_LOAD(name) program_##name##_load +#define PROGRAM_RENDER(name) program_##name##_render +#define PROGRAM_UNLOAD(name) program_##name##_unload +#define PROGRAM_DESTROY(name) program_##name##_destroy + +#define DECL_PROGRAM_INIT(name) void program_##name##_init() +#define DECL_PROGRAM_LOAD(name) void program_##name##_load() +#define DECL_PROGRAM_RENDER(name) void program_##name##_render(struct draw_cmd *cmd) +#define DECL_PROGRAM_UNLOAD(name) void program_##name##_unload() +#define DECL_PROGRAM_DESTROY(name) void program_##name##_destroy() + +#define DECL_PROGRAM(name) \ + DECL_PROGRAM_INIT(name); \ + DECL_PROGRAM_LOAD(name); \ + DECL_PROGRAM_RENDER(name); \ + DECL_PROGRAM_UNLOAD(name); \ + DECL_PROGRAM_DESTROY(name) + +DECL_PROGRAM(triangles_plain); +DECL_PROGRAM(triangles_textured); +DECL_PROGRAM(freetype); + +void program_noop() {}; diff --git a/src/drawglx_internal.c b/src/drawglx_internal.c index b53aa28..fe28671 100644 --- a/src/drawglx_internal.c +++ b/src/drawglx_internal.c @@ -46,18 +46,26 @@ draw_state_render(struct draw_state *state) if (current->texture != state->texture) { glBindTexture(GL_TEXTURE_2D, current->texture); + state->texture = current->texture; } if (current->program != state->program) { if (state->program >= 0) { - programs[state->program].unload(current); + programs[state->program].unload(); } - glUseProgram(programs[current->program].shader); - programs[current->program].load(current); + if (programs[current->program].shader != state->shader) + { + glUseProgram(programs[current->program].shader); + state->shader = programs[current->program].shader; + } + programs[current->program].load(); } programs[current->program].render(current); } + if (state->program >= 0) + programs[state->program].unload(); + state->program = -1; } void diff --git a/src/program_freetype.c b/src/program_freetype.c new file mode 100644 index 0000000..b2281f5 --- /dev/null +++ b/src/program_freetype.c @@ -0,0 +1,47 @@ +/* + * program_freetype.c + * + * Created on: Nov 10, 2017 + * Author: nullifiedcat + */ + +#include + +#include "freetype-gl.h" +#include "programs.h" +#include "texture-atlas.h" + +texture_atlas_t *atlas; +texture_font_t *font; +vec2 pen; + +DECL_PROGRAM_INIT(freetype) +{ + atlas = texture_atlas_new(1024, 1024, 1); + font = texture_font_new_from_file(atlas, 14, "/usr/share/fonts/truetype/freefont/FreeMono.ttf"); + glGenTextures(1, &atlas->id); +} + +DECL_PROGRAM_LOAD(freetype) +{ + vertex_buffer_clear(programs[PROGRAM_FREETYPE].vertex); +} + +DECL_PROGRAM_RENDER(freetype) +{ + if (programs[PROGRAM_FREETYPE].vertex->indices->size == 0) + return; + vertex_buffer_render(programs[PROGRAM_FREETYPE].vertex, GL_TRIANGLES); +} + +DECL_PROGRAM_UNLOAD(freetype) +{ + +} + +DECL_PROGRAM_DESTROY(freetype) +{ + texture_atlas_delete(atlas); + texture_font_delete(font); +} + diff --git a/src/program_triangles_plain.c b/src/program_triangles_plain.c new file mode 100644 index 0000000..584201a --- /dev/null +++ b/src/program_triangles_plain.c @@ -0,0 +1,37 @@ +/* + * program_triangles_plain.c + * + * Created on: Nov 10, 2017 + * Author: nullifiedcat + */ + +#include + +#include "programs.h" + +DECL_PROGRAM_INIT(triangles_plain) +{ + +} + +DECL_PROGRAM_LOAD(triangles_plain) +{ + vertex_buffer_clear(programs[PROGRAM_TRIANGLES_PLAIN].vertex); +} + +DECL_PROGRAM_RENDER(triangles_plain) +{ + if (programs[PROGRAM_TRIANGLES_PLAIN].vertex->indices->size == 0) + return; + vertex_buffer_render(programs[PROGRAM_TRIANGLES_PLAIN], GL_TRIANGLES); +} + +DECL_PROGRAM_UNLOAD(triangles_plain) +{ + +} + +DECL_PROGRAM_DESTROY(triangles_plain) +{ + +} diff --git a/src/program_triangles_textured.c b/src/program_triangles_textured.c new file mode 100644 index 0000000..3e077be --- /dev/null +++ b/src/program_triangles_textured.c @@ -0,0 +1,37 @@ +/* + * program_triangles_textured.c + * + * Created on: Nov 10, 2017 + * Author: nullifiedcat + */ + +#include + +#include "programs.h" + +DECL_PROGRAM_INIT(triangles_textured) +{ + +} + +DECL_PROGRAM_LOAD(triangles_textured) +{ + vertex_buffer_clear(programs[PROGRAM_TRIANGLES_TEXTURED].vertex); +} + +DECL_PROGRAM_RENDER(triangles_textured) +{ + if (programs[PROGRAM_TRIANGLES_TEXTURED].vertex->indices->size == 0) + return; + vertex_buffer_render(programs[PROGRAM_TRIANGLES_TEXTURED], GL_TRIANGLES); +} + +DECL_PROGRAM_UNLOAD(triangles_textured) +{ + +} + +DECL_PROGRAM_DESTROY(triangles_textured) +{ + +} diff --git a/src/programs.c b/src/programs.c new file mode 100644 index 0000000..31f6a4e --- /dev/null +++ b/src/programs.c @@ -0,0 +1,9 @@ +/* + * draw_commands.c + * + * Created on: Nov 10, 2017 + * Author: nullifiedcat + */ + +#include "drawglx_internal.h" +