]> git.sesse.net Git - movit/blob - util.cpp
c6517c90fbe8af07733463fa9d41d0831a0a73f0
[movit] / util.cpp
1 #include <stdio.h>
2 #include <string.h>
3 #include <assert.h>
4
5 #include <math.h>
6 #include "util.h"
7 #include "opengl.h"
8
9 void hsv2rgb(float h, float s, float v, float *r, float *g, float *b)
10 {
11         if (h < 0.0f) {
12                 h += 2.0f * M_PI;
13         }
14         float c = v * s;
15         float hp = (h * 180.0 / M_PI) / 60.0;
16         float x = c * (1 - fabs(fmod(hp, 2.0f) - 1.0f));
17
18         if (hp >= 0 && hp < 1) {
19                 *r = c;
20                 *g = x;
21                 *b = 0.0f;
22         } else if (hp >= 1 && hp < 2) {
23                 *r = x;
24                 *g = c;
25                 *b = 0.0f;
26         } else if (hp >= 2 && hp < 3) {
27                 *r = 0.0f;
28                 *g = c;
29                 *b = x;
30         } else if (hp >= 3 && hp < 4) {
31                 *r = 0.0f;
32                 *g = x;
33                 *b = c;
34         } else if (hp >= 4 && hp < 5) {
35                 *r = x;
36                 *g = 0.0f;
37                 *b = c;
38         } else {
39                 *r = c;
40                 *g = 0.0f;
41                 *b = x;
42         }
43
44         float m = v - c;
45         *r += m;
46         *g += m;
47         *b += m;
48 }
49
50 void hsv2rgb_normalized(float h, float s, float v, float *r, float *g, float *b)
51 {
52         float ref_r, ref_g, ref_b;
53         hsv2rgb(h, s, v, r, g, b);
54         hsv2rgb(h, 0.0f, v, &ref_r, &ref_g, &ref_b);
55         float lum = 0.2126 * *r + 0.7152 * *g + 0.0722 * *b;
56         float ref_lum = 0.2126 * ref_r + 0.7152 * ref_g + 0.0722 * ref_b;
57         if (lum > 1e-3) {
58                 float fac = ref_lum / lum;
59                 *r *= fac;
60                 *g *= fac;
61                 *b *= fac;
62         }
63 }
64
65 std::string read_file(const std::string &filename)
66 {
67         static char buf[131072];
68         FILE *fp = fopen(filename.c_str(), "r");
69         if (fp == NULL) {
70                 perror(filename.c_str());
71                 exit(1);
72         }
73
74         int len = fread(buf, 1, sizeof(buf), fp);
75         fclose(fp);
76
77         return std::string(buf, len);
78 }
79
80 GLuint compile_shader(const std::string &shader_src, GLenum type)
81 {
82         GLuint obj = glCreateShader(type);
83         const GLchar* source[] = { shader_src.data() };
84         const GLint length[] = { (GLint)shader_src.size() };
85         glShaderSource(obj, 1, source, length);
86         glCompileShader(obj);
87
88         GLchar info_log[4096];
89         GLsizei log_length = sizeof(info_log) - 1;
90         glGetShaderInfoLog(obj, log_length, &log_length, info_log);
91         info_log[log_length] = 0; 
92         if (strlen(info_log) > 0) {
93                 printf("shader compile log: %s\n", info_log);
94         }
95
96         GLint status;
97         glGetShaderiv(obj, GL_COMPILE_STATUS, &status);
98         if (status == GL_FALSE) {
99                 exit(1);
100         }
101
102         return obj;
103 }
104
105 void print_3x3_matrix(const Eigen::Matrix3d& m)
106 {
107         printf("%6.4f %6.4f %6.4f\n", m(0,0), m(0,1), m(0,2));
108         printf("%6.4f %6.4f %6.4f\n", m(1,0), m(1,1), m(1,2));
109         printf("%6.4f %6.4f %6.4f\n", m(2,0), m(2,1), m(2,2));
110         printf("\n");
111 }
112
113 std::string output_glsl_mat3(const std::string &name, const Eigen::Matrix3d &m)
114 {
115         char buf[1024];
116         sprintf(buf,
117                 "const mat3 %s = mat3(\n"
118                 "    %.8f, %.8f, %.8f,\n"
119                 "    %.8f, %.8f, %.8f,\n"
120                 "    %.8f, %.8f, %.8f);\n\n",
121                 name.c_str(),
122                 m(0,0), m(1,0), m(2,0),
123                 m(0,1), m(1,1), m(2,1),
124                 m(0,2), m(1,2), m(2,2));
125         return buf;
126 }
127
128 void combine_two_samples(float w1, float w2, float *offset, float *total_weight)
129 {
130         assert(w1 * w2 >= 0.0f);  // Should not have differing signs.
131         if (fabs(w1 + w2) < 1e-6) {
132                 *offset = 0.5f;
133                 *total_weight = 0.0f;
134         } else {
135                 *offset = w2 / (w1 + w2);
136                 *total_weight = w1 + w2;
137         }
138         assert(*offset >= 0.0f);
139         assert(*offset <= 1.0f);
140 }