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