aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--font.c4
-rw-r--r--graphics.c226
-rw-r--r--main.c2
-rw-r--r--state.h3
4 files changed, 120 insertions, 115 deletions
diff --git a/font.c b/font.c
index 85e0a24..bbd7d33 100644
--- a/font.c
+++ b/font.c
@@ -30,7 +30,7 @@ char* get_font(const char* font_name) {
FcFontSetSortDestroy(font_patterns);
FcPatternDestroy(pattern);
- if (!fs || !font_patterns->nfont) {
+ if (!fs || !fs->nfont) {
fprintf(stderr, "Could not prepare font set\n");
}
FcObjectSet* os = FcObjectSetBuild(FC_FILE, (char*)0);
@@ -56,7 +56,7 @@ bool freetype_init(client_state* state, const char* file) {
fprintf(stderr, "Failed to create font\n");
return false;
}
- if (FT_Set_Char_Size(state->ft_face, 0, 12 << 6, 0, 0)) {
+ if (FT_Set_Char_Size(state->ft_face, 0, 16 << 6, 0, 0)) {
fprintf(stderr, "Failed to set font size\n");
return false;
}
diff --git a/graphics.c b/graphics.c
index 9aeb41f..5bf1bf1 100644
--- a/graphics.c
+++ b/graphics.c
@@ -2,17 +2,16 @@
#include "shader.h"
void GLAPIENTRY
-MessageCallback( GLenum source,
- GLenum type,
- GLuint id,
- GLenum severity,
- GLsizei length,
- const GLchar* message,
- const void* userParam )
-{
- fprintf( stderr, "GL CALLBACK: %s type = 0x%x, severity = 0x%x, message = %s\n",
- ( type == GL_DEBUG_TYPE_ERROR ? "** GL ERROR **" : "" ),
- type, severity, message );
+MessageCallback(GLenum source,
+ GLenum type,
+ GLuint id,
+ GLenum severity,
+ GLsizei length,
+ const GLchar* message,
+ const void* userParam) {
+ fprintf( stderr, "GL CALLBACK: %s type = 0x%x, severity = 0x%x, message = %s\n",
+ ( type == GL_DEBUG_TYPE_ERROR ? "** GL ERROR **" : "" ),
+ type, severity, message );
}
const char* vertexShader = "#version 330 core\n\
@@ -25,93 +24,96 @@ uniform vec2 u_offset;\n\
out vec2 o_uv;\n\
\n\
void main() {\n\
- o_uv = uv;\n\
- gl_Position = vec4((((pos + u_offset) / u_screen_size) - vec2(0.5, 0.5)) * 2.0, 0.0, 1.0);\n\
+ o_uv = uv;\n\
+ gl_Position = vec4((((2.0 * (pos + u_offset)) / u_screen_size) - vec2(1.0)), 0.0, 1.0);\n\
}";
const char* fragmentShader = "#version 330 core\n\
uniform sampler2D u_texture;\n\
-in vec2 uv;\n\
+in vec2 o_uv;\n\
\n\
layout (location = 0) out vec4 frag_color;\n\
\n\
void main() {\n\
- float d = texture(u_texture, uv).r;\n\
- float aaf = fwidth(d);\n\
- float alpha = smoothstep(0.5 - aaf, 0.5 + aaf, d);\n\
- frag_color = vec4(0.0, 0.0, 0.0, alpha);\n\
+ float d = texture(u_texture, o_uv).r;\n\
+ float aaf = fwidth(d);\n\
+ float alpha = smoothstep(0.5 - aaf, 0.5 + aaf, d);\n\
+ frag_color = vec4(1.0, 1.0, 1.0, alpha);\n\
}";
bool init_gl(client_state* state) {
- EGLint attrs[] = {
- EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT,
- EGL_CONFORMANT, EGL_OPENGL_BIT,
- EGL_RED_SIZE, 8,
- EGL_GREEN_SIZE, 8,
- EGL_BLUE_SIZE, 8,
- EGL_ALPHA_SIZE, 8,
- EGL_DEPTH_SIZE, 24,
- EGL_NONE
- };
-
- state->egl_window = wl_egl_window_create(state->surface, state->width, state->height);
- if (!state->egl_window) {
- fprintf(stderr, "ewindow\n");
+ EGLint attrs[] = {
+ EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT,
+ EGL_CONFORMANT, EGL_OPENGL_BIT,
+ EGL_RED_SIZE, 8,
+ EGL_GREEN_SIZE, 8,
+ EGL_BLUE_SIZE, 8,
+ EGL_ALPHA_SIZE, 8,
+ EGL_DEPTH_SIZE, 24,
+ EGL_NONE
+ };
+
+ state->egl_window = wl_egl_window_create(state->surface, state->width, state->height);
+ if (!state->egl_window) {
+ fprintf(stderr, "ewindow\n");
return false;
- }
+ }
+
+ state->egl_display = eglGetDisplay(state->display);
+ if (state->egl_display == EGL_NO_DISPLAY) {
+ fprintf(stderr, "edisplay\n");
+ return false;
+ }
+ {
+ EGLint major, minor;
+ if (eglInitialize(state->egl_display, &major, &minor) != EGL_TRUE) {
+ fprintf(stderr, "eglinit\n");
+ return false;
+ }
+
+ printf("EGL version %u.%u\n", major, minor);
+ }
+ eglBindAPI(EGL_OPENGL_API);
+
+ EGLint num_configs;
+ if (eglChooseConfig(state->egl_display, attrs, &state->egl_config, 1, &num_configs) != EGL_TRUE) {
+ fprintf(stderr, "econfig: %d\n", eglGetError());
+ return false;
+ }
- state->egl_display = eglGetDisplay(state->display);
- if (state->egl_display == EGL_NO_DISPLAY) {
- fprintf(stderr, "edisplay\n");
+ state->egl_surface = eglCreateWindowSurface(state->egl_display, state->egl_config,
+ (EGLNativeWindowType)state->egl_window, NULL);
+ if (state->egl_surface == EGL_NO_SURFACE) {
+ fprintf(stderr, "esurface\n");
return false;
- }
- {
- EGLint major, minor;
- if (eglInitialize(state->egl_display, &major, &minor) != EGL_TRUE) {
- fprintf(stderr, "eglinit\n");
- return false;
- }
-
- printf("EGL version %u.%u\n", major, minor);
- }
- eglBindAPI(EGL_OPENGL_API);
-
- EGLint num_configs;
- if (eglChooseConfig(state->egl_display, attrs, &state->egl_config, 1, &num_configs) != EGL_TRUE) {
- fprintf(stderr, "econfig: %d\n", eglGetError());
- return false;
- }
-
- state->egl_surface = eglCreateWindowSurface(state->egl_display, state->egl_config,
- (EGLNativeWindowType)state->egl_window, NULL);
- if (state->egl_surface == EGL_NO_SURFACE) {
- fprintf(stderr, "esurface\n");
- return false;
- }
-
- state->egl_context = eglCreateContext(state->egl_display, state->egl_config,
- EGL_NO_CONTEXT, NULL);
- if (state->egl_context == EGL_NO_CONTEXT) {
- fprintf(stderr, "econtext: %x\n", eglGetError());
- return false;
- }
-
- eglMakeCurrent(state->egl_display, state->egl_surface, state->egl_surface, state->egl_context);
-
- if (!gladLoadGL()) {
- fprintf(stderr, "gladLoadGL");
- return false;
- }
-
- {
- GLint major, minor;
- glGetIntegerv(GL_MAJOR_VERSION, &major);
- glGetIntegerv(GL_MINOR_VERSION, &minor);
- printf("GL version %u.%u\n", major, minor);
- }
-
- glEnable ( GL_DEBUG_OUTPUT );
- glDebugMessageCallback( MessageCallback, 0 );
+ }
+
+ state->egl_context = eglCreateContext(state->egl_display, state->egl_config,
+ EGL_NO_CONTEXT, NULL);
+ if (state->egl_context == EGL_NO_CONTEXT) {
+ fprintf(stderr, "econtext: %x\n", eglGetError());
+ return false;
+ }
+
+ eglMakeCurrent(state->egl_display, state->egl_surface, state->egl_surface, state->egl_context);
+
+ if (!gladLoadGL()) {
+ fprintf(stderr, "gladLoadGL");
+ return false;
+ }
+
+ {
+ GLint major, minor;
+ glGetIntegerv(GL_MAJOR_VERSION, &major);
+ glGetIntegerv(GL_MINOR_VERSION, &minor);
+ printf("GL version %u.%u\n", major, minor);
+ }
+
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
+ glEnable(GL_DEBUG_OUTPUT);
+ glDebugMessageCallback(MessageCallback, 0);
state->text_shader = createShader(vertexShader, fragmentShader);
state->screen_size_uniform = glGetUniformLocation(state->text_shader, "u_screen_size");
@@ -121,8 +123,12 @@ bool init_gl(client_state* state) {
}
void render_frame(client_state *state) {
- glClearColor(1.0, 1.0, 1.0, 1.0);
- glClear(GL_COLOR_BUFFER_BIT);
+ glClearColor(0.0, 0.0, 0.0, 1.0);
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ glBindVertexArray(state->input_buffer_text.vao);
+ glBindBuffer(GL_ARRAY_BUFFER, state->input_buffer_text.vbo);
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, state->input_buffer_text.ebo);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, state->atlas.texture);
@@ -130,8 +136,7 @@ void render_frame(client_state *state) {
glUseProgram(state->text_shader);
glUniform2f(state->screen_size_uniform, state->width, state->height);
glUniform2f(state->offset_uniform, 200.0f, 200.0f);
- glBindVertexArray(state->input_buffer_text.vao);
- glDrawElements(GL_TRIANGLES, state->input_buffer_text.numElements, GL_UNSIGNED_INT, 0);
+ glDrawElements(GL_TRIANGLES, state->input_buffer_text.num_elements, GL_UNSIGNED_INT, 0);
eglSwapBuffers(state->egl_display, state->egl_surface);
}
@@ -143,58 +148,57 @@ typedef struct {
void initTextBuffer(client_state* state, text_buffer_t* buffer, char* text, size_t text_len) {
// generate openg bullshit
glGenVertexArrays(1, &buffer->vao);
+ glBindVertexArray(buffer->vao);
glGenBuffers(1, &buffer->vbo);
glGenBuffers(1, &buffer->ebo);
- glBindVertexArray(buffer->vao);
// TODO for unicode - check for missing characters, iterate over "unicode characters" not chars
// TODO for all fonts - possibly kerning
// generate vertices
vert_t vertices[text_len * 4];
uint32_t indices[text_len * 6];
- buffer->numElements = text_len * 6;
+ buffer->num_elements = text_len * 6;
float pen_x = 0;
- for (int n = 0; n < text_len; n++ )
- {
+ for (int n = 0; n < text_len; n++) {
char c = text[n];
metric_t* m = &state->atlas.metrics[(int)c];
float start_x = pen_x + m->bearing_x;
- float start_y = -m->bearing_y;
+ float start_y = m->bearing_y;
uint32_t base_vert = n * 4;
uint32_t base_idx = n * 6;
- // top left vert
- vert_t v = { .x=start_x, .y=start_y, .u=m->texture_x_start, .v=1.0f};
- vertices[base_vert + 0] = v;
// bottom left vert
- v.y += m->bitmap_height;
- v.v = 0.0f;
+ vert_t v = { .x=start_x, .y=start_y, .u=m->texture_x_start, .v=0.0f};
+ vertices[base_vert + 0] = v;
+ // top left vert
+ v.y -= m->bitmap_height;
+ v.v = ((float)m->bitmap_height / state->atlas.height);
vertices[base_vert + 1] = v;
- // bottom right vert
+ // top right vert
v.x += m->bitmap_width;
v.u = m->texture_x_end;
vertices[base_vert + 2] = v;
- // top right vert
+ // bottom right vert
v.y = start_y;
- v.v = 1;
+ v.v = 0.0f;
vertices[base_vert + 3] = v;
// indices
- indices[base_idx + 0] = base_vert + 0;
- indices[base_idx + 1] = base_vert + 1;
- indices[base_idx + 2] = base_vert + 2;
- indices[base_idx + 3] = base_vert + 0;
- indices[base_idx + 4] = base_vert + 2;
- indices[base_idx + 5] = base_vert + 3;
+ indices[base_idx + 0] = base_vert + 0;
+ indices[base_idx + 1] = base_vert + 1;
+ indices[base_idx + 2] = base_vert + 2;
+ indices[base_idx + 3] = base_vert + 0;
+ indices[base_idx + 4] = base_vert + 2;
+ indices[base_idx + 5] = base_vert + 3;
// go forward
pen_x += m->advance_x;
}
- for (int i = 0; i < sizeof(vertices) / sizeof(vert_t); ++i) {
+ for (int i = 0, n = 0; i < sizeof(vertices) / sizeof(vert_t); ++i, !(i % 4) ? n++ : false) {
vert_t v = vertices[i];
- printf("(%f, %f, %f, %f)\n", v.x, v.y, v.u, v.v);
+ printf("%c: (%f, %f, %f, %f)\n", text[n], v.x, v.y, v.u, v.v);
}
// vertex buffer
@@ -206,8 +210,8 @@ void initTextBuffer(client_state* state, text_buffer_t* buffer, char* text, size
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
// vertex attributes
- glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void*)0);
+ glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(vert_t), (void*)0);
glEnableVertexAttribArray(0);
- glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void*)(2 * sizeof(float)));
+ glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(vert_t), (void*)(2 * sizeof(float)));
glEnableVertexAttribArray(1);
}
diff --git a/main.c b/main.c
index 430ae45..acc328d 100644
--- a/main.c
+++ b/main.c
@@ -74,7 +74,7 @@ int main() {
// create font altas textures
atlas_create_texture(&state);
- initTextBuffer(&state, &state.input_buffer_text, "a g dadsd s", 19);
+ initTextBuffer(&state, &state.input_buffer_text, "this is a test", strlen("this is a test"));
// event loop
while (state.running) {
diff --git a/state.h b/state.h
index 4226711..29eac02 100644
--- a/state.h
+++ b/state.h
@@ -17,10 +17,11 @@
#include "./glad/glad.h"
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
+#define MIN(a, b) (((a) < (b)) ? (a) : (b))
typedef struct {
GLuint vbo, ebo, vao;
- uint32_t numElements;
+ uint32_t num_elements;
} text_buffer_t;
typedef struct {