diff options
| author | Jack Jamison <jackqjamison@gmail.com> | 2025-10-20 15:10:21 -0400 |
|---|---|---|
| committer | Jack Jamison <jackqjamison@gmail.com> | 2025-10-20 15:10:21 -0400 |
| commit | 93e2d267acbd7dd123d89d214a868f957a0a8bd0 (patch) | |
| tree | 65cdffcdf0d42120275e920293148b568f07b496 | |
| parent | 1bfc17ba8ce16ef8bfc505f2d9747adb55222ae6 (diff) | |
cursor and box shader
| -rw-r--r-- | README.md | 7 | ||||
| -rw-r--r-- | config.h | 3 | ||||
| -rw-r--r-- | graphics.c | 110 | ||||
| -rw-r--r-- | input_field.c | 1 | ||||
| -rw-r--r-- | state.h | 17 |
5 files changed, 95 insertions, 43 deletions
@@ -10,16 +10,11 @@ To build: `make` - [X] special mode if there is no stdin - [x] sort filtering by match % - [ ] cursor +- [ ] page scroll - [ ] fuzzy filter -- [ ] unicode -- [ ] kerning -- [ ] config file -- [ ] emacs keybindings -- [ ] input fluff - [ ] "prompt" - [ ] cursor - [ ] emacs keybindings -- [ ] fuzzy filter - [ ] config file - [ ] input fluff - [ ] unicode @@ -8,9 +8,10 @@ typedef struct { } color_t; static const uint32_t min_width = 500; -static const uint32_t font_size = 14; +static const uint32_t font_size = 20; static const color_t text_color = {0.85, 0.85, 0.85, 1.0}; static const color_t highlight_color = {0.1, 0.3, 0.7, 1.0}; static const color_t background_color = {0.1, 0.1, 0.1, 1.0}; +static const color_t cursor_color = {0.9, 0.9, 0.9, 0.5}; #endif @@ -17,7 +17,7 @@ MessageCallback(GLenum source, type, severity, message ); } -const char* vertexShader = +const char* text_vertex_shader = "#version 330 core\n" "layout (location = 0) in vec2 pos;" "layout (location = 1) in vec2 uv;" @@ -36,7 +36,7 @@ const char* vertexShader = " gl_Position = vec4(project(pos + u_offset), 0.0, 1.0);" "}"; -const char* fragmentShader = +const char* text_fragment_shader = "#version 330 core\n" "uniform sampler2D u_texture;" "uniform vec4 u_color;" @@ -48,6 +48,32 @@ const char* fragmentShader = " frag_color = u_color * vec4(1.0, 1.0, 1.0, texture(u_texture, o_uv).r);" "}"; +const char* box_vertex_shader = + "#version 330 core\n" + "uniform vec2 u_screen_size;" + "uniform vec2 u_start;" + "uniform vec2 u_size;" + "" + "vec2 project(vec2 point) { " + " return (((2.0 * point) / u_screen_size) - vec2(1)); " + "}" + "" + "void main() {" + " uint b = uint(1 << (gl_VertexID % 6));" + " vec2 offset = vec2((uint(0x1C) & b) != uint(0), (uint(0x0E) & b) != uint(0));" + " gl_Position = vec4(project(u_start + offset * u_size), 0.0, 1.0);" + "}"; + +const char* box_fragment_shader = + "#version 330 core\n" + "uniform vec4 u_color;" + "" + "layout (location = 0) out vec4 frag_color;" + "" + "void main() {" + " frag_color = u_color;" + "}"; + bool init_gl(client_state* state) { EGLint attrs[] = { EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT, @@ -126,10 +152,18 @@ bool init_gl(client_state* state) { glEnable(GL_DEBUG_OUTPUT); glDebugMessageCallback(MessageCallback, 0); - state->text_shader = createShader(vertexShader, fragmentShader); - state->screen_size_uniform = glGetUniformLocation(state->text_shader, "u_screen_size"); - state->offset_uniform = glGetUniformLocation(state->text_shader, "u_offset"); - state->color_uniform = glGetUniformLocation(state->text_shader, "u_color"); + // text shader + state->text_shader = createShader(text_vertex_shader, text_fragment_shader); + state->t_screen_size_uniform = glGetUniformLocation(state->text_shader, "u_screen_size"); + state->t_offset_uniform = glGetUniformLocation(state->text_shader, "u_offset"); + state->t_color_uniform = glGetUniformLocation(state->text_shader, "u_color"); + + // box shader + state->box_shader = createShader(box_vertex_shader, box_fragment_shader); + state->b_screen_size_uniform = glGetUniformLocation(state->box_shader, "u_screen_size"); + state->b_start_uniform = glGetUniformLocation(state->box_shader, "u_start"); + state->b_size_uniform = glGetUniformLocation(state->box_shader, "u_size"); + state->b_color_uniform = glGetUniformLocation(state->box_shader, "u_color"); return true; } @@ -143,8 +177,8 @@ void render_frame(client_state *state) { // bind shader and texture glUseProgram(state->text_shader); - glUniform2f(state->screen_size_uniform, state->width, state->height); - glUniform4f(state->color_uniform, text_color.r,text_color.g,text_color.b,text_color.a); + glUniform2f(state->t_screen_size_uniform, state->width, state->height); + glUniform4f(state->t_color_uniform, text_color.r,text_color.g,text_color.b,text_color.a); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, state->atlas.texture); @@ -162,9 +196,17 @@ void render_frame(client_state *state) { glScissor(0, 0, state->width, state->height); } glBindVertexArray(state->input_buffer_grafix.vao); - glUniform2f(state->offset_uniform, state->horizontal_spacing / 2.0f, input_y - state->atlas.vert_shift); + glUniform2f(state->t_offset_uniform, state->horizontal_spacing / 2.0f, input_y - state->atlas.vert_shift); glDrawElements(GL_TRIANGLES, state->input_buffer_grafix.num_elements, GL_UNSIGNED_INT, 0); + // draw cursor box + glUseProgram(state->box_shader); + glUniform4f(state->b_color_uniform, cursor_color.r,cursor_color.g,cursor_color.b,cursor_color.a); + glUniform2f(state->b_screen_size_uniform, state->width, state->height); + glUniform2f(state->b_start_uniform, state->input_buffer_grafix.pixel_len + state->horizontal_spacing / 2.0f, input_y); + glUniform2f(state->b_size_uniform, 10.0f, state->line_height); + glDrawArrays(GL_TRIANGLES, 0, 6); + float start; // set up starting pen and scissor for options if (state->lines > 0) { @@ -207,7 +249,35 @@ void render_frame(client_state *state) { } } + // draw highlighted option box + if (state->selected_filtered_item != -1) { + item_display_t* display = &state->filtered_items[state->selected_filtered_item]; + item_t* item = display->item; + + float x,y; + if (state->lines > 0) { + x = 0; + y = start - display->offset; + } + else { + x = start + display->offset; + y = 0; + } + + glUseProgram(state->box_shader); + glUniform4f(state->b_color_uniform, highlight_color.r,highlight_color.g,highlight_color.b,highlight_color.a); + glUniform2f(state->b_screen_size_uniform, state->width, state->height); + glUniform2f(state->b_start_uniform, x, y); + glUniform2f(state->b_size_uniform, (state->lines > 0) ? state->width : item->pixel_len + state->horizontal_spacing, state->line_height); + glDrawArrays(GL_TRIANGLES, 0, 6); + } + // draw options + glUseProgram(state->text_shader); + glUniform2f(state->t_screen_size_uniform, state->width, state->height); + glUniform4f(state->t_color_uniform, text_color.r,text_color.g,text_color.b,text_color.a); + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, state->atlas.texture); for (uint32_t i = 0; i < array_size(state->filtered_items); ++i) { item_display_t* display = &state->filtered_items[i]; item_t* item = display->item; @@ -223,26 +293,8 @@ void render_frame(client_state *state) { } glBindVertexArray(item->text_buffer.vao); - glUniform2f(state->offset_uniform, x + state->horizontal_spacing / 2.0f, y - state->atlas.vert_shift); - if (i == state->selected_filtered_item) { - // draw box - glScissor(x, y, ((state->lines > 0) ? state->width : item->pixel_len + state->horizontal_spacing), state->line_height); - glClearColor(highlight_color.r,highlight_color.g,highlight_color.b,highlight_color.a); - glClear(GL_COLOR_BUFFER_BIT); - if (state->lines > 0) { - glScissor(0, 0, state->width, input_y); - } - else { - glScissor(input_width, 0, state->width, state->line_height); - } - - // draw text - glDrawElements(GL_TRIANGLES, item->text_buffer.num_elements, GL_UNSIGNED_INT, 0); - } else { - - // draw text - glDrawElements(GL_TRIANGLES, item->text_buffer.num_elements, GL_UNSIGNED_INT, 0); - } + glUniform2f(state->t_offset_uniform, x + state->horizontal_spacing / 2.0f, y - state->atlas.vert_shift); + glDrawElements(GL_TRIANGLES, item->text_buffer.num_elements, GL_UNSIGNED_INT, 0); } // present screen diff --git a/input_field.c b/input_field.c index 9f34120..bb8023a 100644 --- a/input_field.c +++ b/input_field.c @@ -89,7 +89,6 @@ bool type_key(client_state* state, xkb_keysym_t keysym) { // submit line if (keysym == XKB_KEY_Return || keysym == XKB_KEY_KP_Enter) { submit_line(state); - update_text_buffer(state); return false; } @@ -83,9 +83,14 @@ typedef struct { // graphics GLuint text_shader; - GLuint screen_size_uniform; - GLuint offset_uniform; - GLuint color_uniform; + GLuint t_screen_size_uniform; + GLuint t_offset_uniform; + GLuint t_color_uniform; + GLuint box_shader; + GLuint b_screen_size_uniform; + GLuint b_start_uniform; + GLuint b_size_uniform; + GLuint b_color_uniform; text_buffer_t input_buffer_grafix; // fonts @@ -105,12 +110,12 @@ typedef struct { bool verbose; // state - char* input_buffer; - float scroll; - int selected_filtered_item; uint32_t width, height; + char* input_buffer; item_t* items; item_display_t* filtered_items; + int selected_filtered_item; + float scroll; bool running; int exit_code; |
