1
2 #include <algorithm>
3
4 #include "misc.h"
5 #include "timer.h"
6 #include "gldefs.h"
7 #include "bbox.h"
8 #include "../resources.h"
9
10
11 extern Timer *g_timer;
12
13
FPScounter(float interval)14 FPScounter::FPScounter(float interval) :
15 m_interval(interval),m_frames(0),
16 m_old_t((float)glfwGetTime()),
17 m_fps(0.0f)
18 {
19 }
20
next_frame(void)21 float FPScounter::next_frame(void)
22 {
23 m_frames++;
24 float t = (float) glfwGetTime();
25 if ((t - m_old_t)>m_interval) {
26 m_fps = m_frames / (t - m_old_t);
27 m_frames = 0;
28 m_old_t = (float) t;
29 }
30 return m_fps;
31 }
32
vec2_ary_to_double_ary(vec2_ary_t v2ary)33 double_ary_t vec2_ary_to_double_ary(vec2_ary_t v2ary)
34 {
35 double_ary_t out;
36 out.reserve(v2ary.size()*2);
37 for(vec2_ary_t::const_iterator it=v2ary.begin();it!=v2ary.end();++it) {
38 out.push_back((*it)[0]); // x
39 out.push_back((*it)[1]); // y
40 }
41 return out;
42 }
43
vec2_ary_to_float_ary(vec2_ary_t v2ary)44 float_ary_t vec2_ary_to_float_ary(vec2_ary_t v2ary)
45 {
46 float_ary_t out;
47 out.reserve(v2ary.size()*2);
48 for(vec2_ary_t::const_iterator it=v2ary.begin();it!=v2ary.end();++it) {
49 out.push_back((*it)[0]); // x
50 out.push_back((*it)[1]); // y
51 }
52 return out;
53 }
54
get_time_con(float c)55 float get_time_con(float c)
56 {
57 return get_time_con_time((float)g_timer->now(), c);
58 }
59
get_time_con_time(float t,float c)60 float get_time_con_time(float t, float c)
61 {
62 float tmp;
63 float tc = t / c;
64 float fract = modf(tc,&tmp);
65 return fract * c;
66 }
67
save_texture_as_ppm(GLuint texid,const char * fname)68 void save_texture_as_ppm(GLuint texid,const char *fname)
69 {
70 GLint width=0,height=0;
71 glBindTexture(GL_TEXTURE_2D,texid);
72 glGetTexLevelParameteriv(GL_TEXTURE_2D,0,GL_TEXTURE_WIDTH,&width);
73 glGetTexLevelParameteriv(GL_TEXTURE_2D,0,GL_TEXTURE_HEIGHT,&height);
74
75 unsigned char *data = new unsigned char[width*height*3];
76
77 glGetTexImage(GL_TEXTURE_2D,0,GL_RGB,GL_UNSIGNED_BYTE,data);
78
79 FILE *f = fopen(fname,"wb");
80 if (!f)
81 return;
82 fprintf(f,"P6\n%i %i\n255\n",width,height);
83 fwrite(data, 1,width*height*3,f);
84 fclose(f);
85
86 glBindTexture(GL_TEXTURE_2D,0);
87 }
88
draw_textured_quad(float size,GLuint texture,bool blend)89 void draw_textured_quad(float size, GLuint texture,bool blend)
90 {
91 if (blend) {
92 glEnable(GL_BLEND);
93 glBlendFunc(GL_ONE,GL_ONE_MINUS_SRC_ALPHA);
94 } else {
95 glDisable(GL_BLEND);
96 }
97
98 size /= 2.0;
99
100 if (texture) {
101 glEnable(GL_TEXTURE_2D);
102 glBindTexture(GL_TEXTURE_2D,texture);
103 }
104
105 glBegin(GL_QUADS);
106 glTexCoord2f(0.0,0.0); glVertex2f(-size,-size);
107 glTexCoord2f(0.0,1.0); glVertex2f(-size, size);
108 glTexCoord2f(1.0,1.0); glVertex2f( size, size);
109 glTexCoord2f(1.0,0.0); glVertex2f( size,-size);
110 glEnd();
111 if (blend)
112 glDisable(GL_BLEND);
113 if (texture)
114 glDisable(GL_TEXTURE_2D);
115 }
116
draw_aa_line(Line l,float width,vec4 color,float stipple)117 void draw_aa_line(Line l,float width,vec4 color,float stipple)
118 {
119 // stretch line to quad
120 vec2 linedir = normalized(l.p2 - l.p1); // line direction vector
121 linedir *= 0.001 * width; // scale normalized vector with line width
122 vec2 p1_a = vec2(+linedir[1],-linedir[0]) + l.p1; // rotate vector 90 degrees and add to p1
123 vec2 p1_b = vec2(-linedir[1],+linedir[0]) + l.p1; // rotate vector 270 degrees and add to p1
124 vec2 p2_a = vec2(+linedir[1],-linedir[0]) + l.p2; // rotate vector 90 degrees and add to p2
125 vec2 p2_b = vec2(-linedir[1],+linedir[0]) + l.p2; // rotate vector 270 degrees and add to p2
126
127 float len = length(l.p2 - l.p1);
128
129 glBindTexture(GL_TEXTURE_2D,g_resources.texture_line);
130
131 len *= stipple;
132
133 g_resources.shader_line->use();
134 my_glUniform1f(g_resources.shader_line->get_uni_loc("stipple"),clamp_0_1(stipple));
135
136 glEnable(GL_TEXTURE_2D);
137 glEnable(GL_BLEND);
138 glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
139
140 glColor(color);
141
142 glBegin(GL_QUADS);
143 glTexCoord2f(0.0,0.0); glVertex(p1_a);
144 glTexCoord2f(0.0,1.0); glVertex(p1_b);
145 glTexCoord2f(len,1.0); glVertex(p2_b);
146 glTexCoord2f(len,0.0); glVertex(p2_a);
147 glEnd();
148 g_resources.shader_line->unuse();
149
150 glDisable(GL_TEXTURE_2D);
151 }
152
153
154 // copy RGBA texture's R channel to new 1-component texture, downsamples 2x (uses first mipmap), deletes original texture
155 // - used because some cards doesn't support direct FBO rendering to single-component texture
156 // and sticking with RGBA even when we use only 1 channel (font, models etc.) kills both performance and VRAM
157 // - downsampling is done because we render to FBO at 2x size to supersample
158 // (FBO multisampling is sadly not supported on many configurations, especially with pre-8xxx nvidia cards on Mac OS X)
move_texture_red_component(GLuint texid)159 GLuint move_texture_red_component(GLuint texid)
160 {
161 // TODO: PBO
162 int width,height;
163 glBindTexture(GL_TEXTURE_2D, texid);
164 glGetTexLevelParameteriv(GL_TEXTURE_2D,1,GL_TEXTURE_WIDTH,&width);
165 glGetTexLevelParameteriv(GL_TEXTURE_2D,1,GL_TEXTURE_HEIGHT,&height);
166
167 unsigned char*data = new unsigned char[width*height];
168 glGetTexImage(GL_TEXTURE_2D,1,GL_RED,GL_UNSIGNED_BYTE,data);
169
170 glDeleteTextures(1,&texid);
171
172 //
173 GLuint newtexid = 0;
174 glGenTextures(1,&newtexid);
175
176 glBindTexture(GL_TEXTURE_2D, newtexid);
177 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
178 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
179 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
180 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
181 glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE);
182
183 glTexImage2D(GL_TEXTURE_2D, 0, 1, width, height, 0, GL_RED, GL_UNSIGNED_BYTE, data);
184 my_glGenerateMipmap(GL_TEXTURE_2D);
185
186 delete[] data;
187
188 return newtexid;
189 }
190
191
hsv2rgb(vec3 const & hsv)192 vec3 hsv2rgb(vec3 const& hsv)
193 {
194 float h = hsv[0] * 6.0f;
195 float s = hsv[1];
196 float v = hsv[2];
197 vec3 out;
198
199 int i = floor(h);
200 float f = h - i;
201 if ( !(i&1) ) // if i is even
202 f = 1 - f;
203
204 float m = v * (1 - s);
205 float n = v * (1 - s * f);
206
207 switch (i) {
208 default:
209 case 6:
210 case 0: return vec3(v, n, m);
211 case 1: return vec3(n, v, m);
212 case 2: return vec3(m, v, n);
213 case 3: return vec3(m, n, v);
214 case 4: return vec3(n, m, v);
215 case 5: return vec3(v, m, n);
216 }
217 /* not reached */
218 }
219
220
rgb2hsv(vec3 const & rgb)221 vec3 rgb2hsv(vec3 const& rgb)
222 {
223 float r = rgb[0];
224 float g = rgb[1];
225 float b = rgb[2];
226
227 float x = min(min(r,g),b);
228 float v = max(max(r,g),b);
229
230 if(v == x) // greyscale => undefined hue
231 return vec3(0, 0, v);
232
233 float f = (r == x) ? g - b : ((g == x) ? b - r : r - g);
234 int i = (r == x) ? 3 : ((g == x) ? 5 : 1);
235
236 return vec3((i - f /(v - x))/6.0f, (v - x)/v, v);
237 }
238
__cxa_pure_virtual(void)239 extern "C" void __cxa_pure_virtual (void) {}
240