From 27e16bc568228d5ed3233d21888e5741e179fca1 Mon Sep 17 00:00:00 2001 From: Josh Holtrop Date: Tue, 23 Jan 2018 14:49:36 -0500 Subject: [PATCH] remove rotating cube demo; add TextShader class --- cube.f.glsl | 36 ------------- cube.v.glsl | 19 ------- src/TextShader.cc | 14 +++++ src/TextShader.h | 46 ++++++++++++++++ src/main.cc | 134 +++------------------------------------------- text.f.glsl | 15 ++++++ text.v.glsl | 27 ++++++++++ 7 files changed, 109 insertions(+), 182 deletions(-) delete mode 100644 cube.f.glsl delete mode 100644 cube.v.glsl create mode 100644 src/TextShader.cc create mode 100644 src/TextShader.h create mode 100644 text.f.glsl create mode 100644 text.v.glsl diff --git a/cube.f.glsl b/cube.f.glsl deleted file mode 100644 index eefeafb..0000000 --- a/cube.f.glsl +++ /dev/null @@ -1,36 +0,0 @@ - -uniform vec4 ambient, specular; -uniform float shininess; -uniform sampler2D tex; - -varying vec3 pos_i; -varying vec3 normal_i; -varying vec2 tex_coord_i; - -void main(void) -{ - vec3 n, lightDir; - vec4 color; - float NdotL, RdotEye; - - lightDir = normalize(vec3(-0.1, 0, -0.9)); - vec4 texture_color = texture2D(tex, tex_coord_i); - color = texture_color * ambient; /* ambient light */ - n = normalize(normal_i); - - NdotL = dot(n, -lightDir); - - if (NdotL > 0.0) - { - /* diffuse component */ - color += texture_color * NdotL; - /* specular component */ - RdotEye = dot(normalize(-pos_i), normalize(reflect(-lightDir, n))); - if (RdotEye > 0.0) - { - color += clamp(specular * pow(RdotEye, shininess), 0.0, 1.0); - } - } - - gl_FragColor = color; -} diff --git a/cube.v.glsl b/cube.v.glsl deleted file mode 100644 index 9780d82..0000000 --- a/cube.v.glsl +++ /dev/null @@ -1,19 +0,0 @@ - -uniform mat4 projection; -uniform mat4 modelview; - -attribute vec3 pos; -attribute vec3 normal; -attribute vec2 tex_coord; - -varying vec3 pos_i; -varying vec3 normal_i; -varying vec2 tex_coord_i; - -void main(void) -{ - gl_Position = projection * modelview * vec4(pos, 1); - pos_i = gl_Position.xyz; - tex_coord_i = tex_coord; - normal_i = (modelview * vec4(normal, 0)).xyz; -} diff --git a/src/TextShader.cc b/src/TextShader.cc new file mode 100644 index 0000000..fab57e8 --- /dev/null +++ b/src/TextShader.cc @@ -0,0 +1,14 @@ +#include "TextShader.h" + +TextShader::TextShader() +{ + m_program = glcxx::Program::create( + glcxx::Shader::create_from_file(GL_VERTEX_SHADER, "text.v.glsl"), + glcxx::Shader::create_from_file(GL_FRAGMENT_SHADER, "text.f.glsl"), + "coords", 0); + + m_uniforms.viewport_size = m_program->get_uniform_location("viewport_size"); + m_uniforms.texture = m_program->get_uniform_location("texture"); + m_uniforms.color = m_program->get_uniform_location("color"); + m_uniforms.position = m_program->get_uniform_location("position"); +} diff --git a/src/TextShader.h b/src/TextShader.h new file mode 100644 index 0000000..1f542fd --- /dev/null +++ b/src/TextShader.h @@ -0,0 +1,46 @@ +#ifndef TEXTSHADER_H +#define TEXTSHADER_H + +#include "glcxx.hpp" +#include + +class TextShader +{ +public: + TextShader(); + + void use() { m_program->use(); } + + void set_viewport_size(int width, int height) + { + glUniform2i(m_uniforms.viewport_size, width, height); + } + + void set_texture(int texture) + { + glUniform1i(m_uniforms.texture, texture); + } + + 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); + } + +protected: + std::shared_ptr m_program; + + struct + { + GLint viewport_size; + GLint texture; + GLint color; + GLint position; + } m_uniforms; +}; + +#endif diff --git a/src/main.cc b/src/main.cc index e71c095..fdb7ee9 100644 --- a/src/main.cc +++ b/src/main.cc @@ -3,27 +3,11 @@ #include "glcxx.hpp" #include "GL3/gl3w.h" #include -#include "glm/glm.hpp" -#include "glm/gtc/matrix_transform.hpp" +#include "TextShader.h" using namespace std; -std::shared_ptr program; -std::shared_ptr cube_buffer; -std::shared_ptr cube_array; -static struct -{ - GLint ambient; - GLint specular; - GLint shininess; - GLint tex; - GLint projection; - GLint modelview; -} uniforms; -glm::mat4 modelview; -glm::mat4 projection; -std::shared_ptr texture; -GLubyte texture_data[16][16][4]; +std::shared_ptr text_shader; #define WIDTH 800 #define HEIGHT 800 @@ -31,7 +15,6 @@ GLubyte texture_data[16][16][4]; bool init(void) { glClearColor (0.0, 0.0, 0.0, 0.0); - glEnable(GL_DEPTH_TEST); glEnable(GL_CULL_FACE); #if 0 glEnable(GL_BLEND); @@ -40,63 +23,10 @@ bool init(void) glViewport(0, 0, WIDTH, HEIGHT); try { - program = glcxx::Program::create( - glcxx::Shader::create_from_file(GL_VERTEX_SHADER, "cube.v.glsl"), - glcxx::Shader::create_from_file(GL_FRAGMENT_SHADER, "cube.f.glsl"), - "position", 0, - "normal", 1, - "tex_coord", 2); - uniforms.ambient = program->get_uniform_location("ambient"); - uniforms.specular = program->get_uniform_location("specular"); - uniforms.shininess = program->get_uniform_location("shininess"); - uniforms.tex = program->get_uniform_location("tex"); - uniforms.projection = program->get_uniform_location("projection"); - uniforms.modelview = program->get_uniform_location("modelview"); - - cube_buffer = glcxx::Buffer::create(GL_ARRAY_BUFFER, GL_STATIC_DRAW, - {-1, -1, 1, 0, 0, 1, 0, 0, - 1, -1, 1, 0, 0, 1, 1, 0, - 1, 1, 1, 0, 0, 1, 1, 1, - -1, 1, 1, 0, 0, 1, 0, 1}); - cube_array = glcxx::Array::create(); - cube_array->bind(); - cube_buffer->bind(); - glEnableVertexAttribArray(0); - glEnableVertexAttribArray(1); - glEnableVertexAttribArray(2); - glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), NULL); - glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (void *)(3 * sizeof(GLfloat))); - glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (void *)(6 * sizeof(GLfloat))); - - projection = glm::perspective((float)(60.0 * M_PI / 180.0), (float)WIDTH / (float)HEIGHT, 0.1f, 1000.0f); - - for (int i = 0; i < 16; i++) - { - for (int j = 0; j < 16; j++) - { - if (((j / 2) & 1) == ((i / 2) & 1)) - { - texture_data[i][j][0] = 255; - texture_data[i][j][1] = 255; - texture_data[i][j][2] = 255; - texture_data[i][j][3] = 255; - } - else - { - texture_data[i][j][0] = 100; - texture_data[i][j][1] = 100; - texture_data[i][j][2] = 100; - texture_data[i][j][3] = 100; - } - } - } - - texture = glcxx::Texture::create(); - glActiveTexture(GL_TEXTURE0); - texture->bind(GL_TEXTURE_2D); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, &texture_data[0][0][0]); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + text_shader = std::make_shared(); + text_shader->use(); + text_shader->set_texture(0); + text_shader->set_viewport_size(WIDTH, HEIGHT); } catch (glcxx::Error & e) { @@ -106,59 +36,9 @@ bool init(void) return true; } -static void draw_cube() -{ - static const struct - { - int counts; - float axis[3]; - } rotations[] = { - {0, {0, 0, 0}}, - {1, {1, 0, 0}}, - {2, {1, 0, 0}}, - {3, {1, 0, 0}}, - {1, {0, 1, 0}}, - {3, {0, 1, 0}}, - }; - - glm::mat4 modelview_backup = modelview; - - program->use(); - cube_array->bind(); - - glUniform4f(uniforms.ambient, 0.2, 0.2, 0.2, 0.2); - glUniform4f(uniforms.specular, 1.0, 1.0, 1.0, 1.0); - glUniform1f(uniforms.shininess, 150.0); - glUniform1i(uniforms.tex, 0); - glUniformMatrix4fv(uniforms.projection, 1, GL_FALSE, &projection[0][0]); - - for (unsigned int i = 0; i < sizeof(rotations) / sizeof(rotations[0]); i++) - { - if (rotations[i].counts > 0) - { - modelview = glm::rotate(modelview_backup, - (float)(M_PI / 2.0 * rotations[i].counts), - glm::vec3(rotations[i].axis[0], - rotations[i].axis[1], - rotations[i].axis[2])); - } - glUniformMatrix4fv(uniforms.modelview, 1, GL_FALSE, &modelview[0][0]); - glDrawArrays(GL_TRIANGLE_FAN, 0, 4); - } - - modelview = modelview_backup; -} - void display(SDL_Window * window) { - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - modelview = glm::lookAt(glm::vec3(-1, -8, 7), - glm::vec3(0, 0, 0), - glm::vec3(0, 0, 1)); - modelview = glm::rotate(modelview, (float)(SDL_GetTicks() / 1000.0), glm::vec3(0, 0, 1)); - modelview = glm::translate(modelview, glm::vec3(3, 0, 0)); - - draw_cube(); + glClear(GL_COLOR_BUFFER_BIT); SDL_GL_SwapWindow(window); } diff --git a/text.f.glsl b/text.f.glsl new file mode 100644 index 0000000..1b1ed9e --- /dev/null +++ b/text.f.glsl @@ -0,0 +1,15 @@ +#version 130 + +/* Texture coordinate: s, t */ +in vec2 texture_coord_v; + +/* Texture unit */ +uniform sampler2D texture; +uniform vec4 color; + +out vec4 frag_color; + +void main(void) +{ + frag_color = vec4(1, 1, 1, texture2D(texture, texture_coord_v).a) * color; +} diff --git a/text.v.glsl b/text.v.glsl new file mode 100644 index 0000000..33aedae --- /dev/null +++ b/text.v.glsl @@ -0,0 +1,27 @@ +#version 130 + +/* Viewport width and height */ +uniform ivec2 viewport_size; +/* Position of lower left corner of glyph */ +uniform ivec2 position; + +/* Vertex coordinates: x, y, s, t */ +in vec4 coords; + +/* Output texture coordinate: s, t */ +out vec2 texture_coord_v; + +/** + * 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.xy), 0, 1); + texture_coord_v = coords.zw; +}