1 |
#include <iostream> |
2 |
#include <GL/glut.h> |
3 |
#include <unistd.h> |
4 |
#include <stdlib.h> |
5 |
#include <math.h> |
6 |
|
7 |
#include "shader.hxx" |
8 |
#include "shaders.hxx" |
9 |
|
10 |
#define GLERR { int er = glGetError(); if(er != GL_NO_ERROR) {\ |
11 |
cout << "ERROR "<<__FILE__<<" "<<__LINE__ \ |
12 |
<<gluErrorString(er)<<"\n"; \ |
13 |
abort();\ |
14 |
} \ |
15 |
} |
16 |
namespace Shader { |
17 |
|
18 |
#include "../buildmipmaps.cxx" |
19 |
|
20 |
using std::cout; |
21 |
|
22 |
|
23 |
void Frame2::genTextures() { |
24 |
if (tex[0]) return; |
25 |
glGenTextures(3, tex); |
26 |
GLERR; |
27 |
|
28 |
ShaderParam param; |
29 |
Shader *shad = Shader::getShader("TubeFrame"); |
30 |
|
31 |
float *data = new float[512 * 512 * 2]; |
32 |
|
33 |
cout << "generating ambient and shadow\n"; |
34 |
|
35 |
param.setParam("light", "ambient"); |
36 |
shad->render(¶m, 512, 512, 1, 2, data); |
37 |
glBindTexture(GL_TEXTURE_2D, tex[0]); |
38 |
glPixelStorei(GL_UNPACK_ALIGNMENT, 1); |
39 |
buildmipmaps(GL_TEXTURE_2D, GL_LUMINANCE_ALPHA, 512, 512, |
40 |
GL_LUMINANCE_ALPHA, GL_FLOAT, data); |
41 |
|
42 |
cout << "generating diffuse\n"; |
43 |
|
44 |
param.setParam("light", "diffuse"); |
45 |
shad->render(¶m, 512, 512, 1, 1, data); |
46 |
glBindTexture(GL_TEXTURE_2D, tex[1]); |
47 |
glPixelStorei(GL_UNPACK_ALIGNMENT, 1); |
48 |
buildmipmaps(GL_TEXTURE_2D, GL_LUMINANCE, 512, 512, |
49 |
GL_LUMINANCE, GL_FLOAT, data); |
50 |
|
51 |
cout << "generating specular\n"; |
52 |
|
53 |
param.setParam("light", "specular"); |
54 |
param.setParam("power", "16"); |
55 |
shad->render(¶m, 512, 512, 1, 1, data); |
56 |
glBindTexture(GL_TEXTURE_2D, tex[2]); |
57 |
glPixelStorei(GL_UNPACK_ALIGNMENT, 1); |
58 |
buildmipmaps(GL_TEXTURE_2D, GL_LUMINANCE, 512, 512, |
59 |
GL_LUMINANCE, GL_FLOAT, data); |
60 |
|
61 |
delete[] data; |
62 |
delete shad; |
63 |
} |
64 |
|
65 |
Frame2::Frame2() { |
66 |
cout << "constructing Frame2\n"; |
67 |
genTextures(); |
68 |
lights[0][0] = 0.1; lights[0][1] = 0.1; lights[0][2] = 0.3; // ambient |
69 |
lights[1][0] = 0.6; lights[1][1] = 0.0; lights[1][2] = 0.0; // diffuse |
70 |
lights[2][0] = 1.0; lights[2][1] = 1.0; lights[2][2] = 1.0; // specular |
71 |
cout << "done\n"; |
72 |
} |
73 |
|
74 |
/* Render a rectangle with all the required passes using |
75 |
the given texture slice */ |
76 |
void Frame2::renderquad(float x0, float y0, float x1, float y1, |
77 |
float s0, float t0, float s1, float t1) { |
78 |
glEnable(GL_BLEND); |
79 |
glEnable(GL_TEXTURE_2D); |
80 |
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); |
81 |
for (int i = 0; i <= 2; i++) { |
82 |
if (i == 1) |
83 |
glBlendFunc(GL_ONE, GL_ONE); |
84 |
|
85 |
glColor3fv(lights[i]); |
86 |
|
87 |
glBindTexture(GL_TEXTURE_2D, tex[i]); |
88 |
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); |
89 |
glBegin(GL_QUAD_STRIP); |
90 |
glTexCoord2f(s0, t0); glVertex2f(x0, y0); |
91 |
glTexCoord2f(s0, t1); glVertex2f(x0, y1); |
92 |
glTexCoord2f(s1, t0); glVertex2f(x1, y0); |
93 |
glTexCoord2f(s1, t1); glVertex2f(x1, y1); |
94 |
glEnd(); |
95 |
} |
96 |
} |
97 |
|
98 |
#define lerp(t, a, b) ( a + (t) * (b - a) ) |
99 |
|
100 |
/* Render a rectangle using renderquad and |
101 |
repeating the texture region (s0,t0)-(s1,t1) |
102 |
horizontally for each block of width w starting from the x0-side |
103 |
*/ |
104 |
void Frame2::rendertube_h(float x0, float y0, float x1, float y1, float w, |
105 |
float s0, float t0, float s1, float t1, float s) { |
106 |
int n = (int)((x1 - x0) / w); |
107 |
|
108 |
for (int i = 0; i < n; i++) { |
109 |
renderquad(x0, y0, x0 + w, y1, |
110 |
s0, t0, s1, t1); |
111 |
x0 += w; |
112 |
} |
113 |
|
114 |
float f = (x1 - x0) / w; |
115 |
|
116 |
if (f > 0) { |
117 |
renderquad(x0, y0, x1, y1, |
118 |
s0, t0, lerp(f, s0, s1), t1); |
119 |
} |
120 |
} |
121 |
|
122 |
/* Analogous to rendertube_h */ |
123 |
void Frame2::rendertube_v(float x0, float y0, float x1, float y1, float w, |
124 |
float s0, float t0, float s1, float t1, float s) { |
125 |
int n = (int)((y1 - y0) / w); |
126 |
|
127 |
for (int i = 0; i < n; i++) { |
128 |
renderquad(x0, y0, x1, y0 + w, |
129 |
s0, t0, s1, t1); |
130 |
y0 += w; |
131 |
} |
132 |
|
133 |
float f = (y1 - y0) / w; |
134 |
|
135 |
if (f > 0) { |
136 |
renderquad(x0, y0, x1, y1, |
137 |
s0, t0, s1, lerp(f, t0, t1)); |
138 |
} |
139 |
} |
140 |
|
141 |
/* Render the quadrant of the frame starting from the corner (x0,y0) |
142 |
* and continuing to the middle point (x1,y1) of the frame. |
143 |
* |
144 |
* (s0,t0)-(s1,t1) is the corresponding texture quadrant, |
145 |
* w is the size of the corner block in object coordinates and |
146 |
* c is the size of the corner block in the texture |
147 |
*/ |
148 |
void Frame2::rendercorner(float x0, float y0, float x1, float y1, float w, |
149 |
float s0, float t0, float s1, float t1, float c) { |
150 |
float dx = s1 > s0 ? 1 : -1; |
151 |
float dy = t1 > t0 ? 1 : -1; |
152 |
|
153 |
float side = 1 - 2 * c; |
154 |
|
155 |
renderquad(x0, y0, x0 + w * dx, y0 + w * dy, |
156 |
s0, t0, s0 + c * dx, t0 + c * dy); |
157 |
|
158 |
rendertube_h(x0 + w * dx, y0, x1, y0 + w * dy, side / c * w * dx, |
159 |
s0 + c * dx, t0, 2*s1-s0-c*dx, t0 + c * dy, side * dx); |
160 |
|
161 |
rendertube_v(x0, y0 + w * dy, x0 + w * dx, y1, side / c * w * dy, |
162 |
s0, t0 + c * dy, s0 + c * dx, 2*t1-t0-c*dy, side * dy); |
163 |
} |
164 |
|
165 |
void Frame2::render(float x0, float y0, float x1, float y1, float w) { |
166 |
glPushAttrib(GL_COLOR_BUFFER_BIT | GL_CURRENT_BIT | GL_TEXTURE_BIT); |
167 |
|
168 |
float fac = .2; |
169 |
|
170 |
glDisable(GL_TEXTURE_2D); |
171 |
glColor3f(0.9, 0.9, 0.8); |
172 |
glBegin(GL_QUAD_STRIP); |
173 |
glVertex2f(x0 + w * fac, y0 + w * fac); |
174 |
glVertex2f(x0 + w * fac, y1 - w * fac); |
175 |
glVertex2f(x1 - w * fac, y0 + w * fac); |
176 |
glVertex2f(x1 - w * fac, y1 - w * fac); |
177 |
glEnd(); |
178 |
|
179 |
float corner = .25; |
180 |
|
181 |
rendercorner(x0, y0, .5 * (x0 + x1), .5 * (y0 + y1), w, |
182 |
0, 0, .5, .5, corner); |
183 |
|
184 |
rendercorner(x1, y0, .5 * (x0 + x1), .5 * (y0 + y1), w, |
185 |
1, 0, .5, .5, corner); |
186 |
|
187 |
rendercorner(x0, y1, .5 * (x0 + x1), .5 * (y0 + y1), w, |
188 |
0, 1, .5, .5, corner); |
189 |
|
190 |
rendercorner(x1, y1, .5 * (x0 + x1), .5 * (y0 + y1), w, |
191 |
1, 1, .5, .5, corner); |
192 |
|
193 |
glPopAttrib(); |
194 |
} |
195 |
|
196 |
GLuint Frame2::tex[3] = {0,0,0}; |
197 |
|
198 |
|
199 |
void Connector::genTextures() { |
200 |
if (tex[0]) return; |
201 |
glGenTextures(4, tex); |
202 |
GLERR; |
203 |
|
204 |
ShaderParam param; |
205 |
Shader *shad = Shader::getShader("TubeConnector"); |
206 |
|
207 |
float *data = new float[512 * 128 * 2]; |
208 |
|
209 |
cout << "generating ambient\n"; |
210 |
|
211 |
param.setParam("light", "ambient"); |
212 |
shad->render(¶m, 512, 128, 1, 2, data); |
213 |
glBindTexture(GL_TEXTURE_2D, tex[0]); |
214 |
glPixelStorei(GL_UNPACK_ALIGNMENT, 1); |
215 |
buildmipmaps(GL_TEXTURE_2D, GL_LUMINANCE_ALPHA, 512, 128, |
216 |
GL_LUMINANCE_ALPHA, GL_FLOAT, data); |
217 |
|
218 |
cout << "generating diffuse\n"; |
219 |
|
220 |
param.setParam("light", "diffuse"); |
221 |
shad->render(¶m, 512, 128, 1, 1, data); |
222 |
glBindTexture(GL_TEXTURE_2D, tex[1]); |
223 |
glPixelStorei(GL_UNPACK_ALIGNMENT, 1); |
224 |
buildmipmaps(GL_TEXTURE_2D, GL_LUMINANCE, 512, 128, |
225 |
GL_LUMINANCE, GL_FLOAT, data); |
226 |
|
227 |
cout << "generating specular\n"; |
228 |
|
229 |
param.setParam("light", "specular"); |
230 |
param.setParam("power", "16"); |
231 |
shad->render(¶m, 512, 128, 1, 1, data); |
232 |
glBindTexture(GL_TEXTURE_2D, tex[2]); |
233 |
glPixelStorei(GL_UNPACK_ALIGNMENT, 1); |
234 |
buildmipmaps(GL_TEXTURE_2D, GL_LUMINANCE, 512, 128, |
235 |
GL_LUMINANCE, GL_FLOAT, data); |
236 |
|
237 |
|
238 |
cout << "generating shadow\n"; |
239 |
|
240 |
param.setParam("light", "shadow"); |
241 |
shad->render(¶m, 512, 128, 1, 1, data); |
242 |
glBindTexture(GL_TEXTURE_2D, tex[3]); |
243 |
glPixelStorei(GL_UNPACK_ALIGNMENT, 1); |
244 |
buildmipmaps(GL_TEXTURE_2D, GL_ALPHA, 512, 128, |
245 |
GL_ALPHA, GL_FLOAT, data); |
246 |
|
247 |
delete[] data; |
248 |
delete shad; |
249 |
} |
250 |
|
251 |
Connector::Connector() { |
252 |
genTextures(); |
253 |
lights[0][0] = 0.1; lights[0][1] = 0.1; lights[0][2] = 0.3; // ambient |
254 |
lights[1][0] = 0.6; lights[1][1] = 0.0; lights[1][2] = 0.0; // diffuse |
255 |
lights[2][0] = 1.0; lights[2][1] = 1.0; lights[2][2] = 1.0; // specular |
256 |
} |
257 |
|
258 |
void Connector::render(float x0, float y0, float w0, float x1, float y1, float w1) { |
259 |
float vx = x1 - x0, vy = y1 - y0; |
260 |
float m = 1 / sqrt(vx * vx + vy * vy); |
261 |
vx *= m; vy *= m; |
262 |
|
263 |
float x[4] = { x0 + w0 * vy, x0 - w0 * vy, x1 + w1 * vy, x1 - w1 * vy }; |
264 |
float y[4] = { y0 - w0 * vx, y0 + w0 * vx, y1 - w1 * vx, y1 + w1 * vx }; |
265 |
|
266 |
glPushAttrib(GL_COLOR_BUFFER_BIT | GL_CURRENT_BIT | GL_TEXTURE_BIT); |
267 |
|
268 |
glEnable(GL_BLEND); |
269 |
glEnable(GL_TEXTURE_2D); |
270 |
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); |
271 |
|
272 |
// Shadow |
273 |
glColor3f(0,0,0); |
274 |
glBindTexture(GL_TEXTURE_2D, tex[3]); |
275 |
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); |
276 |
glBegin(GL_QUAD_STRIP); |
277 |
float dx0 = .2*w0, dx1 = .2*w1; |
278 |
float dy0 = -.2*w0, dy1 = -.2*w1; |
279 |
glTexCoord4f(0, 0, 0, w0); glVertex2f(x[0]+dx0, y[0]+dy0); |
280 |
glTexCoord4f(0, w0, 0, w0); glVertex2f(x[1]+dx0, y[1]+dy0); |
281 |
glTexCoord4f(w1, 0, 0, w1); glVertex2f(x[2]+dx1, y[2]+dy1); |
282 |
glTexCoord4f(w1, w1, 0, w1); glVertex2f(x[3]+dx1, y[3]+dy1); |
283 |
glEnd(); |
284 |
|
285 |
|
286 |
for (int i = 0; i <= 2; i++) { |
287 |
if (i == 1) |
288 |
glBlendFunc(GL_ONE, GL_ONE); |
289 |
glColor3fv(lights[i]); |
290 |
|
291 |
glBindTexture(GL_TEXTURE_2D, tex[i]); |
292 |
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); |
293 |
glBegin(GL_QUAD_STRIP); |
294 |
glTexCoord4f(0, 0, 0, w0); glVertex2f(x[0], y[0]); |
295 |
glTexCoord4f(0, w0, 0, w0); glVertex2f(x[1], y[1]); |
296 |
|
297 |
for (float t = 0; t < 1; t += .25) { |
298 |
float a = (5+t)*(1./6); |
299 |
float w = lerp(a, w0, w1); |
300 |
|
301 |
glTexCoord4f(a*w, 0, 0, w); |
302 |
glVertex2f(lerp(a,x[0],x[2])+lerp(a,dx0,dx1)*(t*t), lerp(a,y[0],y[2])+lerp(a,dy0,dy1)*(t*t)); |
303 |
|
304 |
glTexCoord4f(a*w, w, 0, w); |
305 |
glVertex2f(lerp(a,x[1],x[3])+lerp(a,dx0,dx1)*(t*t), lerp(a,y[1],y[3])+lerp(a,dy0,dy1)*(t*t)); |
306 |
} |
307 |
|
308 |
|
309 |
glTexCoord4f(w1, 0, 0, w1); glVertex2f(x[2]+dx1, y[2]+dy1); |
310 |
glTexCoord4f(w1, w1, 0, w1); glVertex2f(x[3]+dx1, y[3]+dy1); |
311 |
glEnd(); |
312 |
} |
313 |
|
314 |
glPopAttrib(); |
315 |
GLERR |
316 |
} |
317 |
|
318 |
GLuint Connector::tex[4] = {0,0,0,0}; |
319 |
|
320 |
#define BGTEXSIZE 256 |
321 |
void Bg::genTextures() { |
322 |
if(tex[0]) return; |
323 |
cout << "Bg:: genTextures\n"; |
324 |
glGenTextures(NUM_BG_TEX, tex); |
325 |
GLERR; |
326 |
|
327 |
for(int i=0; i<NUM_BG_TEX; i++) { |
328 |
ShaderParam param; |
329 |
Shader *shad; |
330 |
float *data = new float[BGTEXSIZE*BGTEXSIZE*4]; |
331 |
|
332 |
float color[3]; |
333 |
|
334 |
int components = 4; |
335 |
GLint intformat = GL_RGB; |
336 |
GLenum format = GL_RGBA; |
337 |
|
338 |
switch(i) { |
339 |
case 0: |
340 |
shad = Shader::getShader("ppbg1"); |
341 |
param.setParam("r", "0"); |
342 |
param.setParam("g", "0.53"); |
343 |
param.setParam("b", "0.73"); |
344 |
break; |
345 |
case 1: |
346 |
shad = Shader::getShader("ppbg1"); |
347 |
param.setParam("r", "0.91"); |
348 |
param.setParam("g", "0.88"); |
349 |
param.setParam("b", "0.51"); |
350 |
break; |
351 |
case 2: |
352 |
shad = Shader::getShader("bgnoise"); |
353 |
components = 1; |
354 |
intformat = format = GL_LUMINANCE; |
355 |
break; |
356 |
} |
357 |
|
358 |
shad->render(¶m, BGTEXSIZE, BGTEXSIZE, 1, components, data); |
359 |
cout << "Bg:: shadrendered end\n"; |
360 |
glBindTexture(GL_TEXTURE_2D, tex[i]); |
361 |
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); |
362 |
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); |
363 |
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); |
364 |
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); |
365 |
buildmipmaps(GL_TEXTURE_2D, intformat, BGTEXSIZE, BGTEXSIZE, |
366 |
format, GL_FLOAT, data); |
367 |
delete[] data; |
368 |
delete shad; |
369 |
} |
370 |
cout << "Bg:: genTextures end\n"; |
371 |
} |
372 |
|
373 |
Bg::Bg(int ind) { |
374 |
genTextures(); |
375 |
this->ind = ind; |
376 |
} |
377 |
|
378 |
void Bg::render(float x0, float y0, float x1, float y1) { |
379 |
glPushAttrib(GL_TEXTURE_BIT | GL_ENABLE_BIT); |
380 |
glEnable(GL_TEXTURE_2D); |
381 |
glBindTexture(GL_TEXTURE_2D, tex[ind]); |
382 |
glColor3f(1,1,1); |
383 |
glBegin(GL_QUAD_STRIP); |
384 |
glTexCoord2f(0, 0); |
385 |
glVertex2f(x0, y0); |
386 |
glTexCoord2f((x1-x0)/BGTEXSIZE, 0); |
387 |
glVertex2f(x1, y0); |
388 |
glTexCoord2f(0, (y1-y0)/BGTEXSIZE); |
389 |
glVertex2f(x0, y1); |
390 |
glTexCoord2f((x1-x0)/BGTEXSIZE, (y1-y0)/BGTEXSIZE); |
391 |
glVertex2f(x1, y1); |
392 |
glEnd(); |
393 |
glPopAttrib(); |
394 |
GLERR |
395 |
} |
396 |
GLuint Bg::tex[NUM_BG_TEX]; |
397 |
|
398 |
} |