From c852e9991b076aa26da1ae4e1ef31fa19222e11b Mon Sep 17 00:00:00 2001 From: Josh Holtrop Date: Tue, 13 Sep 2016 22:19:47 -0400 Subject: [PATCH] add a rectangle shader --- share/jes/shaders/rect.f.glsl | 11 +++++++++ share/jes/shaders/rect.v.glsl | 25 +++++++++++++++++++ src/gui/Shaders/RectShader.cc | 18 ++++++++++++++ src/gui/Shaders/RectShader.h | 46 +++++++++++++++++++++++++++++++++++ src/gui/Window.cc | 25 +++++++++++++++++++ src/gui/Window.h | 5 ++++ 6 files changed, 130 insertions(+) create mode 100644 share/jes/shaders/rect.f.glsl create mode 100644 share/jes/shaders/rect.v.glsl create mode 100644 src/gui/Shaders/RectShader.cc create mode 100644 src/gui/Shaders/RectShader.h diff --git a/share/jes/shaders/rect.f.glsl b/share/jes/shaders/rect.f.glsl new file mode 100644 index 0000000..f1b3451 --- /dev/null +++ b/share/jes/shaders/rect.f.glsl @@ -0,0 +1,11 @@ +#version 130 + +/* Color */ +uniform vec4 color; + +out vec4 frag_color; + +void main(void) +{ + frag_color = color; +} diff --git a/share/jes/shaders/rect.v.glsl b/share/jes/shaders/rect.v.glsl new file mode 100644 index 0000000..8d40b59 --- /dev/null +++ b/share/jes/shaders/rect.v.glsl @@ -0,0 +1,25 @@ +#version 130 + +/* Viewport width and height */ +uniform ivec2 viewport_size; +/* Position offset */ +uniform ivec2 position; +/* Rectangle size */ +uniform ivec2 size; + +/* Vertex coordinates: x, y */ +in vec2 coords; + +/** + * Map coordinates such that: + * (0 .. viewport_size.[xy]) => (-1.0 .. 1.0) + */ +vec2 map_to_screen(vec2 position) +{ + return 2.0 * position / viewport_size - 1.0; +} + +void main(void) +{ + gl_Position = vec4(map_to_screen(vec2(position) + coords * size), 0, 1); +} diff --git a/src/gui/Shaders/RectShader.cc b/src/gui/Shaders/RectShader.cc new file mode 100644 index 0000000..af9a322 --- /dev/null +++ b/src/gui/Shaders/RectShader.cc @@ -0,0 +1,18 @@ +#include "RectShader.h" +#include "Runtime.h" + +RectShader::RectShader() +{ + std::string v_path = Runtime::find(Runtime::SHADER, "rect.v"); + std::string f_path = Runtime::find(Runtime::SHADER, "rect.f"); + + m_program = glcxx::Program::create( + glcxx::Shader::create_from_file(GL_VERTEX_SHADER, v_path.c_str()), + glcxx::Shader::create_from_file(GL_FRAGMENT_SHADER, f_path.c_str()), + "coords", 0); + + m_uniforms.viewport_size = m_program->get_uniform_location("viewport_size"); + m_uniforms.color = m_program->get_uniform_location("color"); + m_uniforms.position = m_program->get_uniform_location("position"); + m_uniforms.size = m_program->get_uniform_location("size"); +} diff --git a/src/gui/Shaders/RectShader.h b/src/gui/Shaders/RectShader.h new file mode 100644 index 0000000..be9a8aa --- /dev/null +++ b/src/gui/Shaders/RectShader.h @@ -0,0 +1,46 @@ +#ifndef RECTSHADER_H +#define RECTSHADER_H + +#include "glcxx.hpp" +#include + +class RectShader +{ +public: + RectShader(); + + void use() { m_program->use(); } + + void set_viewport_size(int width, int height) + { + glUniform2i(m_uniforms.viewport_size, width, height); + } + + void set_color(float r, float g, float b, float a) + { + glUniform4f(m_uniforms.color, r, g, b, a); + } + + void set_position(int x, int y) + { + glUniform2i(m_uniforms.position, x, y); + } + + void set_size(int x, int y) + { + glUniform2i(m_uniforms.size, x, y); + } + +protected: + std::shared_ptr m_program; + + struct + { + GLint viewport_size; + GLint color; + GLint position; + GLint size; + } m_uniforms; +}; + +#endif diff --git a/src/gui/Window.cc b/src/gui/Window.cc index bc1df57..7fa256f 100644 --- a/src/gui/Window.cc +++ b/src/gui/Window.cc @@ -118,6 +118,7 @@ bool Window::create(std::shared_ptr buffer) m_shaders.text->set_color(1.0, 1.0, 1.0, 1.0); m_shaders.flat = std::make_shared(); + m_shaders.rect = std::make_shared(); GLint cursor_bounds[] = {0, 0, m_font.get_advance(), 0, @@ -130,6 +131,18 @@ bool Window::create(std::shared_ptr buffer) glEnableVertexAttribArray(0); glVertexAttribPointer(0, 2, GL_INT, GL_FALSE, 0, 0); + GLint rect_coords[] = { + 0, 0, + 1, 0, + 1, 1, + 0, 1}; + m_rect_array = glcxx::Array::create(); + m_rect_array->bind(); + m_rect_buffer = glcxx::Buffer::create(GL_ARRAY_BUFFER, GL_STATIC_DRAW, + rect_coords, sizeof(rect_coords)); + glEnableVertexAttribArray(0); + glVertexAttribPointer(0, 2, GL_INT, GL_FALSE, 0, 0); + m_buffer = buffer; m_cursor = m_buffer->piece_table->add_cursor(); m_start_piece = m_buffer->piece_table->start_piece->next; @@ -430,6 +443,8 @@ void Window::resize() m_shaders.text->set_viewport_size(m_width, m_height); m_shaders.flat->use(); m_shaders.flat->set_viewport_size(m_width, m_height); + m_shaders.rect->use(); + m_shaders.rect->set_viewport_size(m_width, m_height); m_columns = m_width / m_font.get_advance(); if (m_columns < 1) m_columns = 1; @@ -474,3 +489,13 @@ void Window::colrow_to_xy(int col, int row, int * x, int * y) *x = col * m_font.get_advance(); *y = m_height - (row + 1) * m_font.get_line_height(); } + +void Window::draw_rect(int x, int y, int width, int height, float r, float g, float b, float a) +{ + m_rect_array->bind(); + m_shaders.rect->use(); + m_shaders.rect->set_color(r, g, b, a); + m_shaders.rect->set_position(x, y); + m_shaders.rect->set_size(width, height); + glDrawArrays(GL_TRIANGLE_FAN, 0, 4); +} diff --git a/src/gui/Window.h b/src/gui/Window.h index 036b543..942bfc6 100644 --- a/src/gui/Window.h +++ b/src/gui/Window.h @@ -5,6 +5,7 @@ #include #include "TextShader.h" #include "FlatShader.h" +#include "RectShader.h" #include "Font.h" #include "Buffer.h" #include "glcxx.hpp" @@ -38,6 +39,7 @@ protected: void draw_text(); void draw_character(int screen_column, int screen_row, uint32_t character); void update_cursor_row(int cursor_row); + void draw_rect(int x, int y, int width, int height, float r, float g, float b, float a); SDL_Window * m_window; bool m_exit_requested; @@ -47,6 +49,7 @@ protected: { std::shared_ptr text; std::shared_ptr flat; + std::shared_ptr rect; } m_shaders; Font m_font; @@ -60,6 +63,8 @@ protected: std::shared_ptr m_cursor_array; std::shared_ptr m_cursor_buffer; + std::shared_ptr m_rect_array; + std::shared_ptr m_rect_buffer; std::shared_ptr m_cursor;