]> git.sesse.net Git - movit/blobdiff - widgets.cpp
Explicitly bind fragment shader outputs in order.
[movit] / widgets.cpp
index 87260215e2b1b4bb3f2e916c98e9e1d4adb37a37..66ec7c5c9ab932c6dbeaf7e02fb007e7fad87489 100644 (file)
 #include <epoxy/gl.h>
 #include <math.h>
 
+#include <string>
+#include <vector>
+
+#include "resource_pool.h"
 #include "widgets.h"
 #include "util.h"
 
 #define HSV_WHEEL_SIZE 128
 
+using namespace std;
+
 namespace movit {
 
-GLuint hsv_wheel_num;
+GLuint hsv_wheel_texnum = 0;
+GLuint textured_program_num = 0, colored_program_num = 0, hsv_vao = 0;
+ResourcePool resource_pool;
 
-void draw_hsv_wheel(float y, float rad, float theta, float value)
+void draw_black_point(float x, float y, float point_size)
 {
-       glUseProgram(0);
-       check_error();
-       glActiveTexture(GL_TEXTURE0);
+       glUseProgram(colored_program_num);
        check_error();
-       glEnable(GL_TEXTURE_2D);
+
+       float vertices[] = { x, y };
+       float colors[] = { 0.0f, 0.0f, 0.0f };
+
+       glPointSize(point_size);
        check_error();
-       glBindTexture(GL_TEXTURE_2D, hsv_wheel_num);
+       GLuint position_vbo = fill_vertex_attribute(colored_program_num, "position", 2, GL_FLOAT, sizeof(vertices), vertices);
+       GLuint color_vbo = fill_vertex_attribute(colored_program_num, "color", 3, GL_FLOAT, sizeof(colors), colors);
        check_error();
-       glActiveTexture(GL_TEXTURE1);
+       glDrawArrays(GL_POINTS, 0, 1);
        check_error();
-       glBindTexture(GL_TEXTURE_2D, 0);
+       cleanup_vertex_attribute(colored_program_num, "position", position_vbo);
+       cleanup_vertex_attribute(colored_program_num, "color", color_vbo);
+}
+
+void draw_hsv_wheel(float y, float rad, float theta, float value)
+{
+       glUseProgram(textured_program_num);
        check_error();
        glActiveTexture(GL_TEXTURE0);
+       check_error();
+       glBindTexture(GL_TEXTURE_2D, hsv_wheel_texnum);
+       check_error();
+       glUniform1i(glGetUniformLocation(textured_program_num, "tex"), 0);  // Bind the 2D sampler.
+       check_error();
        glEnable(GL_BLEND);
        check_error();
        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
        check_error();
 
-       // wheel
-       glBegin(GL_QUADS);
-
-       glTexCoord2f(0.0f, 1.0f);
-       glVertex2f(0.0f, y);
-
-       glTexCoord2f(1.0f, 1.0f);
-       glVertex2f(0.2f * 9.0f / 16.0f, y);
+       GLuint vao;
+       glGenVertexArrays(1, &vao);
+       check_error();
+       glBindVertexArray(vao);
+       check_error();
 
-       glTexCoord2f(1.0f, 0.0f);
-       glVertex2f(0.2f * 9.0f / 16.0f, y + 0.2f);
+       // wheel
+       float wheel_vertices[] = {
+               0.0f, y,
+               0.0f, y + 0.2f,
+               0.2f * 9.0f / 16.0f, y,
+               0.2f * 9.0f / 16.0f, y + 0.2f,
+       };
+       float wheel_texcoords[] = {
+               0.0f, 1.0f,
+               0.0f, 0.0f,
+               1.0f, 1.0f,
+               1.0f, 0.0f,
+       };
+       GLuint position_vbo = fill_vertex_attribute(textured_program_num, "position", 2, GL_FLOAT, sizeof(wheel_vertices), wheel_vertices);
+       GLuint texcoord_vbo = fill_vertex_attribute(textured_program_num, "texcoord", 2, GL_FLOAT, sizeof(wheel_texcoords), wheel_texcoords);
+       check_error();
 
-       glTexCoord2f(0.0f, 0.0f);
-       glVertex2f(0.0f, y + 0.2f);
+       glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
+       check_error();
 
-       glEnd();
+       cleanup_vertex_attribute(textured_program_num, "position", position_vbo);
+       cleanup_vertex_attribute(textured_program_num, "texcoord", texcoord_vbo);
 
        // wheel selector
-       glDisable(GL_TEXTURE_2D);
-       glColor3f(0.0f, 0.0f, 0.0f);
-       glPointSize(5.0f);
-       glBegin(GL_POINTS);
-       glVertex2f((0.1f + rad * cos(theta) * 0.1f) * 9.0f / 16.0f, y + 0.1f - rad * sin(theta) * 0.1f);
-       glEnd();
-       
-       // value slider
-       glDisable(GL_TEXTURE_2D);
-       glBegin(GL_QUADS);
+       draw_black_point(
+           (0.1f + rad * cos(theta) * 0.1f) * 9.0f / 16.0f,
+           y + 0.1f - rad * sin(theta) * 0.1f,
+           5.0f);
 
-       glColor3f(0.0f, 0.0f, 0.0f);
-       glVertex2f(0.22f * 9.0f / 16.0f, y);
-       glVertex2f(0.24f * 9.0f / 16.0f, y);
-
-       glColor3f(1.0f, 1.0f, 1.0f);
-       glVertex2f(0.24f * 9.0f / 16.0f, y + 0.2f);
-       glVertex2f(0.22f * 9.0f / 16.0f, y + 0.2f);
-
-       glEnd();
+       // value slider
+       glUseProgram(colored_program_num);
+       float value_vertices[] = {
+               0.22f * 9.0f / 16.0f, y,
+               0.22f * 9.0f / 16.0f, y + 0.2f,
+               0.24f * 9.0f / 16.0f, y,
+               0.24f * 9.0f / 16.0f, y + 0.2f,
+       };
+       float value_colors[] = {
+               0.0f, 0.0f, 0.0f,
+               1.0f, 1.0f, 1.0f,
+               0.0f, 0.0f, 0.0f,
+               1.0f, 1.0f, 1.0f,
+       };
+       position_vbo = fill_vertex_attribute(colored_program_num, "position", 2, GL_FLOAT, sizeof(value_vertices), value_vertices);
+       GLuint color_vbo = fill_vertex_attribute(colored_program_num, "color", 3, GL_FLOAT, sizeof(value_colors), value_colors);
+       check_error();
+       glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
+       check_error();
+       cleanup_vertex_attribute(colored_program_num, "position", position_vbo);
+       cleanup_vertex_attribute(colored_program_num, "color", color_vbo);
 
        // value selector
-       glColor3f(0.0f, 0.0f, 0.0f);
-       glPointSize(5.0f);
-       glBegin(GL_POINTS);
-       glVertex2f(0.23f * 9.0f / 16.0f, y + value * 0.2f);
-       glEnd();
+       draw_black_point(0.23f * 9.0f / 16.0f, y + value * 0.2f, 5.0f);
 
-       glColor3f(1.0f, 1.0f, 1.0f);
+       glDeleteVertexArrays(1, &vao);
+       check_error();
+       glUseProgram(0);
+       check_error();
 }
 
 void draw_saturation_bar(float y, float saturation)
 {
-       glUseProgram(0);
+       GLuint vao;
+       glGenVertexArrays(1, &vao);
+       check_error();
+       glBindVertexArray(vao);
        check_error();
 
        // value slider
-       glDisable(GL_TEXTURE_2D);
-       glBegin(GL_QUADS);
-
-       glColor3f(0.0f, 0.0f, 0.0f);
-       glVertex2f(0.0f * 9.0f / 16.0f, y + 0.02f);
-       glVertex2f(0.0f * 9.0f / 16.0f, y);
-
-       glColor3f(1.0f, 1.0f, 1.0f);
-       glVertex2f(0.2f * 9.0f / 16.0f, y);
-       glVertex2f(0.2f * 9.0f / 16.0f, y + 0.02f);
-
-       glEnd();
+       glUseProgram(colored_program_num);
+       float value_vertices[] = {
+               0.0f * 9.0f / 16.0f, y + 0.02f,
+               0.2f * 9.0f / 16.0f, y + 0.02f,
+               0.0f * 9.0f / 16.0f, y,
+               0.2f * 9.0f / 16.0f, y,
+       };
+       float value_colors[] = {
+               0.0f, 0.0f, 0.0f,
+               1.0f, 1.0f, 1.0f,
+               0.0f, 0.0f, 0.0f,
+               1.0f, 1.0f, 1.0f,
+       };
+       GLuint position_vbo = fill_vertex_attribute(colored_program_num, "position", 2, GL_FLOAT, sizeof(value_vertices), value_vertices);
+       GLuint color_vbo = fill_vertex_attribute(colored_program_num, "color", 3, GL_FLOAT, sizeof(value_colors), value_colors);
+       check_error();
+       glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
+       check_error();
+       cleanup_vertex_attribute(colored_program_num, "position", position_vbo);
+       cleanup_vertex_attribute(colored_program_num, "color", color_vbo);
 
        // value selector
-       glColor3f(0.0f, 0.0f, 0.0f);
-       glPointSize(5.0f);
-       glBegin(GL_POINTS);
-       glVertex2f(0.2f * saturation * 9.0f / 16.0f, y + 0.01f);
-       glEnd();
+       draw_black_point(0.2f * saturation * 9.0f / 16.0f, y + 0.01f, 5.0f);
 
-       glColor3f(1.0f, 1.0f, 1.0f);
+       glDeleteVertexArrays(1, &vao);
+       check_error();
+       glUseProgram(0);
+       check_error();
 }
 
 void make_hsv_wheel_texture()
 {
-       glGenTextures(1, &hsv_wheel_num);
+       glGenTextures(1, &hsv_wheel_texnum);
 
        static unsigned char hsv_pix[HSV_WHEEL_SIZE * HSV_WHEEL_SIZE * 4];
        for (int y = 0; y < HSV_WHEEL_SIZE; ++y) {
@@ -134,7 +183,7 @@ void make_hsv_wheel_texture()
                }
        }
 
-       glBindTexture(GL_TEXTURE_2D, hsv_wheel_num);
+       glBindTexture(GL_TEXTURE_2D, hsv_wheel_texnum);
        check_error();
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        check_error();
@@ -142,6 +191,26 @@ void make_hsv_wheel_texture()
        check_error();
 }
 
+void init_hsv_resources()
+{
+       vector<string> frag_shader_outputs;
+       textured_program_num = resource_pool.compile_glsl_program(
+               read_version_dependent_file("vs", "vert"),
+               read_version_dependent_file("texture1d", "frag"),
+               frag_shader_outputs);
+       colored_program_num = resource_pool.compile_glsl_program(
+               read_version_dependent_file("vs-color", "vert"),
+               read_version_dependent_file("color", "frag"),
+               frag_shader_outputs);
+       make_hsv_wheel_texture();
+}
+
+void cleanup_hsv_resources()
+{
+       resource_pool.release_glsl_program(textured_program_num);
+       resource_pool.release_glsl_program(colored_program_num);
+}
+
 void read_colorwheel(float xf, float yf, float *rad, float *theta, float *value)
 {
        if (xf < 0.2f && yf < 0.2f) {