Add YCbCr input. Required a bit of reworking of the sRGB extension stuff, but seems...
[movit] / widgets.cpp
1 #define GL_GLEXT_PROTOTYPES 1
2
3 #include <math.h>
4 #include <GL/gl.h>
5 #include <GL/glext.h>
6
7 #include "widgets.h"
8 #include "util.h"
9
10 #define HSV_WHEEL_SIZE 128
11
12 GLuint hsv_wheel_num;
13
14 void draw_hsv_wheel(float y, float rad, float theta, float value)
15 {
16         glUseProgram(0);
17         check_error();
18         glActiveTexture(GL_TEXTURE0);
19         check_error();
20         glEnable(GL_TEXTURE_2D);
21         check_error();
22         glBindTexture(GL_TEXTURE_2D, hsv_wheel_num);
23         check_error();
24         glActiveTexture(GL_TEXTURE1);
25         check_error();
26         glBindTexture(GL_TEXTURE_2D, 0);
27         check_error();
28         glActiveTexture(GL_TEXTURE0);
29         glEnable(GL_BLEND);
30         check_error();
31         glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
32         check_error();
33
34         // wheel
35         glBegin(GL_QUADS);
36
37         glTexCoord2f(0.0f, 1.0f);
38         glVertex2f(0.0f, y);
39
40         glTexCoord2f(1.0f, 1.0f);
41         glVertex2f(0.2f * 9.0f / 16.0f, y);
42
43         glTexCoord2f(1.0f, 0.0f);
44         glVertex2f(0.2f * 9.0f / 16.0f, y + 0.2f);
45
46         glTexCoord2f(0.0f, 0.0f);
47         glVertex2f(0.0f, y + 0.2f);
48
49         glEnd();
50
51         // wheel selector
52         glDisable(GL_TEXTURE_2D);
53         glColor3f(0.0f, 0.0f, 0.0f);
54         glPointSize(5.0f);
55         glBegin(GL_POINTS);
56         glVertex2f((0.1f + rad * cos(theta) * 0.1f) * 9.0f / 16.0f, y + 0.1f - rad * sin(theta) * 0.1f);
57         glEnd();
58         
59         // value slider
60         glDisable(GL_TEXTURE_2D);
61         glBegin(GL_QUADS);
62
63         glColor3f(0.0f, 0.0f, 0.0f);
64         glVertex2f(0.22f * 9.0f / 16.0f, y);
65         glVertex2f(0.24f * 9.0f / 16.0f, y);
66
67         glColor3f(1.0f, 1.0f, 1.0f);
68         glVertex2f(0.24f * 9.0f / 16.0f, y + 0.2f);
69         glVertex2f(0.22f * 9.0f / 16.0f, y + 0.2f);
70
71         glEnd();
72
73         // value selector
74         glColor3f(0.0f, 0.0f, 0.0f);
75         glPointSize(5.0f);
76         glBegin(GL_POINTS);
77         glVertex2f(0.23f * 9.0f / 16.0f, y + value * 0.2f);
78         glEnd();
79
80         glColor3f(1.0f, 1.0f, 1.0f);
81 }
82
83 void draw_saturation_bar(float y, float saturation)
84 {
85         glUseProgram(0);
86         check_error();
87
88         // value slider
89         glDisable(GL_TEXTURE_2D);
90         glBegin(GL_QUADS);
91
92         glColor3f(0.0f, 0.0f, 0.0f);
93         glVertex2f(0.0f * 9.0f / 16.0f, y + 0.02f);
94         glVertex2f(0.0f * 9.0f / 16.0f, y);
95
96         glColor3f(1.0f, 1.0f, 1.0f);
97         glVertex2f(0.2f * 9.0f / 16.0f, y);
98         glVertex2f(0.2f * 9.0f / 16.0f, y + 0.02f);
99
100         glEnd();
101
102         // value selector
103         glColor3f(0.0f, 0.0f, 0.0f);
104         glPointSize(5.0f);
105         glBegin(GL_POINTS);
106         glVertex2f(0.2f * saturation * 9.0f / 16.0f, y + 0.01f);
107         glEnd();
108
109         glColor3f(1.0f, 1.0f, 1.0f);
110 }
111
112 void make_hsv_wheel_texture()
113 {
114         glGenTextures(1, &hsv_wheel_num);
115
116         static unsigned char hsv_pix[HSV_WHEEL_SIZE * HSV_WHEEL_SIZE * 4];
117         for (int y = 0; y < HSV_WHEEL_SIZE; ++y) {
118                 for (int x = 0; x < HSV_WHEEL_SIZE; ++x) {
119                         float yf = 2.0f * y / (float)(HSV_WHEEL_SIZE) - 1.0f;
120                         float xf = 2.0f * x / (float)(HSV_WHEEL_SIZE) - 1.0f;
121                         float rad = hypot(xf, yf);
122                         float theta = atan2(yf, xf);
123
124                         float r, g, b;
125                         hsv2rgb(theta, rad, 1.0f, &r, &g, &b);
126                         hsv_pix[(y * HSV_WHEEL_SIZE + x) * 4 + 0] = lrintf(r * 255.0f);
127                         hsv_pix[(y * HSV_WHEEL_SIZE + x) * 4 + 1] = lrintf(g * 255.0f);
128                         hsv_pix[(y * HSV_WHEEL_SIZE + x) * 4 + 2] = lrintf(b * 255.0f);
129
130                         if (rad > 1.0f) {
131                                 hsv_pix[(y * HSV_WHEEL_SIZE + x) * 4 + 3] = 0;
132                         } else {
133                                 hsv_pix[(y * HSV_WHEEL_SIZE + x) * 4 + 3] = 255;
134                         }
135                 }
136                 printf("\n");
137         }
138
139         glBindTexture(GL_TEXTURE_2D, hsv_wheel_num);
140         check_error();
141         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
142         check_error();
143         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, HSV_WHEEL_SIZE, HSV_WHEEL_SIZE, 0, GL_RGBA, GL_UNSIGNED_BYTE, hsv_pix);
144         check_error();
145 }
146
147 void read_colorwheel(float xf, float yf, float *rad, float *theta, float *value)
148 {
149         if (xf < 0.2f && yf < 0.2f) {
150                 float xp = 2.0f * xf / 0.2f - 1.0f;
151                 float yp = -(2.0f * yf / 0.2f - 1.0f);
152                 *rad = hypot(xp, yp);
153                 *theta = atan2(yp, xp);
154                 if (*rad > 1.0) {
155                         *rad = 1.0;
156                 }
157         } else if (xf >= 0.22f && xf <= 0.24f) {
158                 *value = yf / 0.2f;
159         }
160 }
161