Subversion Repositories gelsvn

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
688 khor 1
/* ----------------------------------------------------------------------- *
2
 * This file is part of GEL, http://www.imm.dtu.dk/GEL
3
 * Copyright (C) the authors and DTU Informatics
4
 * For license and list of authors, see ../../doc/intro.pdf
5
 * ----------------------------------------------------------------------- */
6
 
7
#include "ManifoldRenderer.h"
8
 
9
#if !defined (WIN32)
10
  #include <GLUT/GLUT.h>
11
#else
12
  #include <GL/GLUT.h>
13
#endif
14
 
15
 
16
#include <algorithm>
17
#include <string>
18
#include <cstdlib>
19
#include "../Geometry/TriMesh.h"
20
#include "../CGLA/Mat3x3d.h"
21
#include "../GLGraphics/glsl_shader.h"
22
#include "../GLGraphics/draw.h"
23
#include "../HMesh/Manifold.h"
24
#include "../HMesh/AttributeVector.h"
25
#include "../HMesh/curvature.h"
26
 
27
using namespace CGLA;
28
using namespace HMesh;
29
using namespace std;
30
using namespace Geometry;
31
namespace GLGraphics
32
{    
33
    GLuint get_noise_texture_id()
34
    {
35
        static GLuint texname=0;
36
        static bool was_here = false;
37
 
38
        if(!was_here)
39
        {
40
            was_here = true;
41
            int width = 32;
42
            int height = 32;
43
            int depth = 32;
44
            vector<unsigned char> texels(width*height*depth);
45
            for (int i = 0; i < width*height*depth; ++i)
46
            {
47
                int intensity = 255.0 * (float(gel_rand()) / GEL_RAND_MAX);
48
                texels[i] = (unsigned char) intensity;
49
            }
50
 
51
            glGenTextures(1, &texname);	
52
            glBindTexture(GL_TEXTURE_3D, texname);
53
            glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
54
            glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
55
            glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_REPEAT);
56
            glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_REPEAT);
57
            glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_REPEAT);
58
            glTexImage3D(GL_TEXTURE_3D, 0, GL_INTENSITY8, width, height, depth, 0, GL_RED, GL_UNSIGNED_BYTE, &texels[0]);
59
        }
60
 
61
        return texname;
62
    }
63
 
64
 
65
    int WireframeRenderer::maximum_face_valency(const Manifold& m)
66
    {
67
        int max_val = 0;
68
        for(FaceIDIterator f = m.faces_begin(); f != m.faces_end(); ++f)
69
            max_val = max(max_val, no_edges(m, *f));
70
        return max_val;
71
    }
72
 
73
    WireframeRenderer::WireframeRenderer(HMesh::Manifold& m, bool smooth): idbuff_renderer(0)
74
    {
75
        if(GLEW_EXT_geometry_shader4 && maximum_face_valency(m) > 3)
76
        {
77
            GLint viewp[4];
78
            glGetIntegerv(GL_VIEWPORT,viewp);
79
            idbuff_renderer = new IDBufferWireframeRenderer(viewp[2], viewp[3], m);
80
        }
81
        else
82
        {
83
            glNewList(display_list,GL_COMPILE);
84
            if(GLEW_EXT_geometry_shader4)
85
                draw_triangles_in_wireframe(m,smooth, Vec3f(1,0,0));				
86
            else
87
                draw_wireframe_oldfashioned(m,smooth, Vec3f(1,0,0));
88
            glEndList();
89
        }
90
    }
91
 
92
    void WireframeRenderer::draw()
93
    {
94
        if(idbuff_renderer)
95
        {
96
            glEnable(GL_LIGHTING);
97
            idbuff_renderer->draw(Vec3f(1,0,0),Vec3f(1));
98
            glDisable(GL_LIGHTING);
99
        }
100
        else
101
            glCallList(display_list);
102
    }
103
 
104
    void SimpleShaderRenderer::init_shaders(const std::string& vss, 
105
                                            const std::string& fss)
106
    {
107
        vs = create_glsl_shader(GL_VERTEX_SHADER, vss);
108
        print_glsl_program_log(vs);
109
 
110
        fs = create_glsl_shader(GL_FRAGMENT_SHADER, fss);
111
        print_glsl_program_log(fs);
112
 
113
        prog = glCreateProgram();
114
 
115
        if(vs) glAttachShader(prog, vs);
116
        if(fs) glAttachShader(prog, fs);
117
 
118
        glLinkProgram(prog);
119
        print_glsl_program_log(prog);
120
 
121
    }
122
 
123
    void SimpleShaderRenderer::compile_display_list(const Manifold& m, bool smooth)
124
    {
125
        GLint old_prog;
126
        glGetIntegerv(GL_CURRENT_PROGRAM, &old_prog);
127
        glUseProgram(prog);
128
        glNewList(display_list,GL_COMPILE);
129
        GLGraphics::draw(m, smooth);
130
        glEndList();	
131
        glUseProgram(old_prog);
132
    }
133
 
134
    void SimpleShaderRenderer::draw()
135
    {
136
        GLint old_prog;
137
        glGetIntegerv(GL_CURRENT_PROGRAM, &old_prog);
138
        glUseProgram(prog);
139
        glCallList(display_list);
140
        glUseProgram(old_prog);
141
    }
142
 
143
    const string NormalRenderer::vss =
144
    "varying vec3 _n;\n"
145
    "varying vec3 v;\n"
146
    "\n"
147
    "void main(void)\n"
148
    "{\n"
149
    "	gl_Position = ftransform();\n"
150
    "	v = vec3(gl_ModelViewMatrix * gl_Vertex);\n"
151
    "	_n = normalize(gl_NormalMatrix * gl_Normal);\n"
152
    "}\n";
153
 
154
    const string NormalRenderer::fss =
155
    "varying vec3 _n;\n"
156
    "varying vec3 v;\n"
157
    "\n"
158
    "void main(void)\n"
159
    "{\n"
160
    "   vec3 n = normalize(_n);\n"
161
    "	vec3 l = normalize(-v);\n"
162
    "	vec3 e = l;\n"
163
    "	vec3 r = normalize(2.0*dot(l, n)*n - l);\n"
164
    "	\n"
165
    "	vec4 a = vec4(0.0,0.1,.3,1.0);\n"
166
    "   float dot_ln = abs(dot(l, n));\n"
167
    "	vec4 d = vec4(0.7) * dot_ln;\n"
168
    "	vec4 s = vec4(0.3)*smoothstep(0.98,0.9999,dot(r, e));\n"
169
    "	\n"
170
    "	gl_FragColor =  d+s;\n"
171
    "}\n";
172
 
173
    const string DebugRenderer::vss =
174
    "varying vec3 _n;\n"
175
    "varying vec3 v;\n"
176
    "varying vec3 c;\n"
177
    "\n"
178
    "void main(void)\n"
179
    "{\n"
180
    "	gl_Position = ftransform();\n"
181
    "	v = vec3(gl_ModelViewMatrix * gl_Vertex);\n"
182
    "	_n = normalize(gl_NormalMatrix * gl_Normal);\n"
183
    "   c = gl_Color.rgb;\n"
184
    "}\n";
185
 
186
    const string DebugRenderer::fss =
187
    "varying vec3 _n;\n"
188
    "varying vec3 v;\n"
189
    "varying vec3 c;\n"
190
    "\n"
191
    "void main(void)\n"
192
    "{\n"
193
    "   vec3 n = normalize(_n);\n"
194
    "	vec3 l = normalize(-v);\n"
195
    "	vec3 e = l;\n"
196
    "	vec3 r = normalize(2.0*dot(l, n)*n - l);\n"
197
    "	\n"
198
    "	vec4 a = vec4(0.0,0.1,.3,1.0);\n"
199
    "   float dot_ln = abs(dot(l, n));\n"
200
    "	vec4 d = vec4(c,1) * 0.7 * dot_ln;\n"
201
    "	vec4 s = vec4(c,1) * 0.3 * smoothstep(0.98,0.9999,dot(r, e));\n"
202
    "	\n"
203
    "	gl_FragColor =  vec4(c,1);\n"
204
    "}\n";
205
 
206
    HMesh::VertexAttributeVector<CGLA::Vec3f> DebugRenderer::vertex_colors;
207
    HMesh::HalfEdgeAttributeVector<CGLA::Vec3f> DebugRenderer::edge_colors;
208
    HMesh::FaceAttributeVector<CGLA::Vec3f> DebugRenderer::face_colors;
209
 
210
 
211
    void DebugRenderer::compile_display_list(const HMesh::Manifold& m, bool smooth, float rad)
212
    {
213
        GLint old_prog;
214
        glGetIntegerv(GL_CURRENT_PROGRAM, &old_prog);
215
        glUseProgram(prog);
216
        glNewList(display_list,GL_COMPILE);
217
        glEnable(GL_POLYGON_OFFSET_FILL);
218
        glPolygonOffset(1,1);
219
        for(FaceID f: m.faces()){
220
            Vec3f c = face_colors[f];
221
            glColor3f(c[0], c[1], c[2]);
222
            if(!smooth)
223
                glNormal3dv(normal(m, f).get());
224
            if(no_edges(m, f)== 3)
225
                glBegin(GL_TRIANGLES);
226
            else
227
                glBegin(GL_POLYGON);
228
 
229
            for(Walker w = m.walker(f); !w.full_circle(); w = w.circulate_face_ccw()){
230
                Vec3d n = normal(m, w.vertex());
231
                if(smooth)
232
                    glNormal3dv(n.get());
233
                glVertex3dv(m.pos(w.vertex()).get());
234
            }
235
            glEnd();
236
        }
237
        glLineWidth(2);
238
        glDisable(GL_POLYGON_OFFSET_FILL);
239
        glBegin(GL_LINES);
240
        for(auto hid: m.halfedges())
241
        {
242
            Walker w = m.walker(hid);
243
            Vec3f c = edge_colors[hid];
244
            glColor3fv(c.get());
245
            glNormal3dv(normal(m, w.opp().vertex()).get());
246
            glVertex3dv(m.pos(w.opp().vertex()).get());
247
            glNormal3dv(normal(m, w.vertex()).get());
248
            glVertex3dv(m.pos(w.vertex()).get());
249
        }
250
        glEnd();
251
        glLineWidth(1);
252
        Vec3d c;
253
        float r;
254
        bsphere(m, c, r);
255
        r *= rad;
256
        for(auto vid : m.vertices())
257
        {
258
            Vec3d p = m.pos(vid);
259
            Vec3f c = vertex_colors[vid];
260
            glColor3f(c[0], c[1], c[2]);
261
            glPushMatrix();
262
            glTranslated(p[0], p[1], p[2]);
263
            glScalef(r, r, r);
264
            draw_ball();
265
            glPopMatrix();
266
        }
267
        glEnd();
268
        glEndList();
269
        glUseProgram(old_prog);
270
    }
271
 
272
    const string ReflectionLineRenderer::vss = 
273
    "varying vec3 _n;\n"
274
    "varying vec3 v;\n"
275
    "\n"
276
    "void main(void)\n"
277
    "{\n"
278
    "	gl_Position = ftransform();\n"
279
    "	v = vec3(gl_ModelViewMatrix * gl_Vertex);\n"
280
    "	_n = normalize(gl_NormalMatrix * gl_Normal);\n"
281
    "}\n";
282
 
283
 
284
    const string ReflectionLineRenderer::fss = 
285
    "uniform float detail;\n"
286
    "\n"
287
    "varying vec3 _n;\n"
288
    "varying vec3 v;\n"
289
    "\n"
290
    "void main(void)\n"
291
    "{\n"
292
    "   vec3 n = normalize(_n);\n"
293
    "	// calculate the reflection\n"
294
    "	vec3 r = normalize(2.0*dot(-v, n)*n + v);\n"
295
    "	vec3 viewer_lightdir = vec3(0, 0, 1.0);\n"
296
    "   float diff  = dot(n,viewer_lightdir);\n"
297
    "	\n"
298
    "	vec2 r2 = normalize(vec2(r[0], r[2]));\n"
299
    "	vec2 x = vec2(1, 0);\n"
300
    "	float angle = acos(dot(r2, x));\n"
301
    "	\n"
302
    "	// decide if we hit a white or black ring, based on y value\n"
303
    "	gl_FragColor = diff * vec4(1.0) + smoothstep(0.8, 1.0,cos(13.0*angle)) * vec4(-1.0);\n"
304
    "}\n";
305
 
306
    const string IsophoteLineRenderer::vss = 
307
    "varying vec3 _n;\n"
308
    "varying vec3 v;\n"
309
    "\n"
310
    "void main(void)\n"
311
    "{\n"
312
    "	gl_Position = ftransform();\n"
313
    "	v = vec3(gl_ModelViewMatrix * gl_Vertex);\n"
314
    "	_n = normalize(gl_NormalMatrix * gl_Normal);\n"
315
    "}\n";
316
 
317
 
318
    const string IsophoteLineRenderer::fss = 
319
    "uniform float detail;\n"
320
    "\n"
321
    "varying vec3 _n;\n"
322
    "varying vec3 v;\n"
323
    "\n"
324
    "void main(void)\n"
325
    "{\n"
326
    "   vec3 n = normalize(_n);\n"
327
    "	vec3 viewer_lightdir = vec3(0, 0, 1.0);\n"
328
    "	vec3 isophote_lightdir = viewer_lightdir;\n"
329
    "	float angle = acos(dot(n, isophote_lightdir));\n"
330
    "   float diff  = dot(n,viewer_lightdir);\n"
331
    "	\n"
332
    "	// decide if we hit a white or black ring, based on y value\n"
333
    "	gl_FragColor = diff * vec4(1.0) + smoothstep(0.8, 1.0,cos(20.0*angle)) * vec4(-1.0);\n"
334
    "}\n";
335
 
336
    const string ToonRenderer::vss = 
337
    "varying vec3 _n;\n"
338
    "varying vec3 v;\n"
339
    "\n"
340
    "void main(void)\n"
341
    "{\n"
342
    "	gl_Position = ftransform();\n"
343
    "	v = vec3(gl_ModelViewMatrix * gl_Vertex);\n"
344
    "	_n = normalize(gl_NormalMatrix * gl_Normal);\n"
345
    "}\n";
346
 
347
    const string ToonRenderer::fss = 
348
    "varying vec3 _n;\n"
349
    "varying vec3 v;\n"
350
    "\n"
351
    "void main(void)\n"
352
    "{\n"
353
    "   vec3 n = normalize(_n);\n"
354
    "	vec3 l = normalize(-v);\n"
355
    "	vec3 e = l;\n"
356
    "	vec3 r = normalize(2.0*dot(l, n)*n - l);\n"
357
    "	\n"
358
    "	vec4 a = vec4(0.0,0.1,.3,1.0);\n"
359
    "   float dot_ln = abs(dot(l, n));\n"
360
    "	vec4 d = vec4(0.7,0.7,0.0,1.0) * 0.25 * (smoothstep(0.23,0.25,dot_ln)+smoothstep(0.45,0.47,dot_ln)+smoothstep(0.7,0.72,dot_ln)+smoothstep(0.9,0.92,dot_ln));\n"
361
    "	vec4 s = vec4(0.5,0.3,0.4,1.0)*smoothstep(0.96,0.98,dot(r, e));\n"
362
    "	\n"
363
    "	gl_FragColor =  d+s;\n"
364
    "}\n";
365
 
366
 
367
    void GlazedRenderer::compile_display_list(const HMesh::Manifold& m, bool smooth)
368
    {
369
        GLint old_prog;
370
        glGetIntegerv(GL_CURRENT_PROGRAM, &old_prog);
371
        glUseProgram(prog);
372
        glNewList(display_list,GL_COMPILE);
373
        glBindTexture(GL_TEXTURE_3D, get_noise_texture_id());
374
        glUniform1iARB(glGetUniformLocationARB(prog, "noise_tex"),0);
375
        float r;
376
        Vec3d c;
377
        bsphere(m, c, r);
378
        glUniform1fARB(glGetUniformLocationARB(prog, "noise_scale"),12.0/r);
379
        GLGraphics::draw(m, smooth);
380
        glEndList();
381
        glUseProgram(old_prog);
382
 
383
    }
384
 
385
 
386
    const string GlazedRenderer::vss = 
387
    "varying vec3 _n;\n"
388
    "varying vec3 v;\n"
389
    "varying vec3 v_obj;\n"
390
    "\n"
391
    "void main(void)\n"
392
    "{\n"
393
    "	gl_Position = ftransform();\n"
394
    "   v_obj = gl_Vertex.xyz;\n"
395
    "	v = vec3(gl_ModelViewMatrix * gl_Vertex);\n"
396
    "	_n = normalize(gl_NormalMatrix * gl_Normal);\n"
397
    "}\n"
398
    "\n";
399
 
400
    const string GlazedRenderer::fss =
401
    "uniform sampler3D noise_tex;\n"
402
    "uniform float noise_scale;\n"
403
    "varying vec3 _n;\n"
404
    "varying vec3 v;\n"
405
    "varying vec3 v_obj;\n"
406
    "\n"
407
    "vec4 glazed_shader(vec4 mat_col,  vec4 light_col, vec3 light_dir)\n"
408
    "{\n"
409
    "   vec3 n = normalize(_n);\n"
410
    "	vec3 e = normalize(-v);\n"
411
    "	vec3 r = normalize(2.0*dot(e, n)*n - e);\n"
412
    "	float d = max(0.05,dot(light_dir, n));\n"
413
    "	vec4 diff = mat_col * light_col *d; 	\n"
414
    "	vec4 refl = smoothstep(0.7,0.75,dot(r,light_dir)) * light_col;\n"
415
    "	return 0.15*refl + diff;\n"
416
    "}\n"
417
    "\n"
418
    "void main(void)\n"
419
    "{\n"
420
    "	vec4 mat_col = vec4(0.9,1.0,0.4,1.0) +  vec4(-0.1,-0.1,0.12,0.0) * texture3D(noise_tex, noise_scale*v_obj).x\n"
421
    " + vec4(0.05) * texture3D(noise_tex, 500.0*v_obj).x;\n"
422
    "	\n"
423
    "	vec3 light0_dir = vec3(0.0,1.0,0.0);\n"
424
    "	vec4 light0_col = vec4(0.7,0.9,1.0,1.0);\n"
425
    "	\n"
426
    "	vec3 light1_dir = vec3(0.0,0.0,1.0);\n"
427
    "	vec4 light1_col = vec4(1.0,1.0,0.7,1.0);\n"
428
    "	\n"
429
    "	gl_FragColor = \n"
430
    "	0.5*glazed_shader(mat_col, light0_col, light0_dir)+\n"
431
    "	0.5*glazed_shader(mat_col, light1_col, light1_dir);\n"
432
    "	\n"
433
    "	gl_FragColor.a = 1.0;\n"
434
    "}\n";
435
 
436
 
437
    const string ScalarFieldRenderer::vss =
438
    "	attribute float scalar;\n"
439
    "	varying vec3 _normal;\n"
440
    "	varying float s;\n"
441
    "	\n"
442
    "	void main(void)\n"
443
    "	{\n"
444
    "		gl_Position =  ftransform();\n"
445
    "		_normal = normalize(gl_NormalMatrix * gl_Normal);\n"
446
    "		s=scalar;\n"
447
    "	}\n";
448
 
449
    const string ScalarFieldRenderer::fss =
450
    "	varying vec3 _normal;\n"
451
    "	varying float s;\n"
452
    "	uniform float scalar_max;\n"
453
    "   uniform float gamma;\n"
454
    "	const vec3 light_dir = vec3(0,0,1);\n"
455
    "	\n"
456
    "	void main()\n"
457
    "	{\n"
458
    "       vec3 normal = normalize(_normal);\n"
459
    "		float dot_ln = max(0.0,dot(light_dir, normal));\n"
460
    "		\n"
461
    "		float s_norm = s/scalar_max;\n"
462
    "		float stripe_signal = 50.0 * s_norm;\n"
463
    "		vec4 stripe_col = vec4(.9,.9,.9,0);\n"
464
    "		\n"
465
    "		gl_FragColor = max(vec4(0), s_norm * vec4(-1,0,1,0));\n"
466
    "       gl_FragColor *= dot_ln;\n"
467
    "       gl_FragColor.r = pow(gl_FragColor.r, 1.0/gamma);\n"
468
    "       gl_FragColor.g = pow(gl_FragColor.g, 1.0/gamma);\n"
469
    "       gl_FragColor.b = pow(gl_FragColor.b, 1.0/gamma);\n"
470
    "		gl_FragColor += 0.2*stripe_col * pow(cos(stripe_signal),70.0);\n"
471
    "	}\n";
472
 
473
    void ScalarFieldRenderer::compile_display_list(const HMesh::Manifold& m, bool smooth,
474
                                                   HMesh::VertexAttributeVector<double>& field, double max_val, float gamma)
475
    {
476
 
477
        GLint old_prog;
478
        glGetIntegerv(GL_CURRENT_PROGRAM, &old_prog);
479
        glUseProgram(prog);
480
 
481
        GLuint scalar_attrib = glGetAttribLocation(prog, "scalar");
482
        glUniform1fARB(glGetUniformLocationARB(prog, "scalar_max"), max_val);
483
 
484
        //    static float& gamma = CreateCVar("display.scalar_field_renderer.gamma",2.2f);
485
        glUniform1fARB(glGetUniformLocationARB(prog, "gamma"), gamma);
486
        glNewList(display_list,GL_COMPILE);
487
 
488
        for(FaceIDIterator f = m.faces_begin(); f != m.faces_end(); ++f){
489
            if(!smooth)
490
                glNormal3dv(normal(m, *f).get());
491
            if(no_edges(m, *f)== 3)
492
                glBegin(GL_TRIANGLES);
493
            else
494
                glBegin(GL_POLYGON);
495
 
496
 
497
            for(Walker w = m.walker(*f); !w.full_circle(); w = w.circulate_face_ccw()){
498
                Vec3d n(normal(m, w.vertex()));
499
                if(smooth)
500
                    glNormal3dv(n.get());
501
                glVertexAttrib1d(scalar_attrib, field[w.vertex()]);
502
                glVertex3dv(m.pos(w.vertex()).get());
503
            }
504
            glEnd();
505
        }
506
        glEndList();
507
        glUseProgram(old_prog);
508
 
509
    }
510
 
511
    HMesh::VertexAttributeVector<CGLA::Vec2f> CheckerBoardRenderer::param;
512
 
513
    const string CheckerBoardRenderer::vss =
514
    "	attribute vec2 param;\n"
515
    "	varying vec3 _normal;\n"
516
    "	varying vec2 uv;\n"
517
    "	\n"
518
    "	void main(void)\n"
519
    "	{\n"
520
    "		gl_Position =  ftransform();\n"
521
    "		_normal = normalize(gl_NormalMatrix * gl_Normal);\n"
522
    "		uv=param;\n"
523
    "	}\n";
524
 
525
    const string CheckerBoardRenderer::fss =
526
    "	varying vec3 _normal;\n"
527
    "	varying vec2 uv;\n"
528
    "   const float pi = 3.14159265359;\n"
529
    "	const vec3 light_dir = vec3(0,0,1);\n"
530
    "	\n"
531
    "	void main()\n"
532
    "	{\n"
533
    "       vec3 normal = normalize(_normal);\n"
534
    "		float dot_ln = max(0.0,dot(light_dir, normal));\n"
535
    "		vec2 rt = uv;//vec2(length(uv),atan(uv.y, uv.x));\n"
536
    "		float stripe_signal = smoothstep(-0.001,0.001,sin(2.0*pi*rt.x)*sin(10.0*rt.y));\n"
537
    "		\n"
538
    "		gl_FragColor = dot_ln * vec4(0.35,0.25,0.5,0);\n"
539
   "		gl_FragColor.rgb += 0.7*stripe_signal;\n"
540
    "	}\n";
541
 
542
    void CheckerBoardRenderer::compile_display_list(const HMesh::Manifold& m, bool smooth)
543
    {
544
 
545
        GLint old_prog;
546
        glGetIntegerv(GL_CURRENT_PROGRAM, &old_prog);
547
        glUseProgram(prog);
548
 
549
        GLuint param_attrib = glGetAttribLocation(prog, "param");
550
        glNewList(display_list,GL_COMPILE);
551
 
552
        for(FaceIDIterator f = m.faces_begin(); f != m.faces_end(); ++f){
553
            if(!smooth)
554
                glNormal3dv(normal(m, *f).get());
555
            if(no_edges(m, *f)== 3)
556
                glBegin(GL_TRIANGLES);
557
            else
558
                glBegin(GL_POLYGON);
559
 
560
 
561
            for(Walker w = m.walker(*f); !w.full_circle(); w = w.circulate_face_ccw()){
562
                Vec3d n(normal(m, w.vertex()));
563
                if(smooth)
564
                    glNormal3dv(n.get());
565
                glVertexAttrib2fv(param_attrib, param[w.vertex()].get());
566
                glVertex3dv(m.pos(w.vertex()).get());
567
            }
568
            glEnd();
569
        }
570
        glEndList();
571
        glUseProgram(old_prog);
572
 
573
    }
574
 
575
 
576
 
577
    const string AmbientOcclusionRenderer::vss =
578
    "	attribute float scalar;\n"
579
    "	varying vec3 _normal;\n"
580
    "	varying float s;\n"
581
    "	\n"
582
    "	void main(void)\n"
583
    "	{\n"
584
    "		gl_Position =  ftransform();\n"
585
    "		_normal = normalize(gl_NormalMatrix * gl_Normal);\n"
586
    "		s=scalar;\n"
587
    "	}\n";
588
 
589
    const string AmbientOcclusionRenderer::fss = 	
590
    "	varying vec3 _normal;\n"
591
    "	varying float s;\n"
592
    "	uniform float scalar_max;\n"
593
    "	const vec3 light_dir = vec3(0,0,1);\n"
594
    "	\n"
595
    "	void main()\n"
596
    "	{\n"
597
    "   vec3 normal = normalize(_normal);\n"
598
    "		float dot_ln = max(0.0,dot(light_dir, normal));\n"
599
    "		\n"
600
    "		float s_norm = min(1.0,s/scalar_max+1.0);\n"
601
    "		\n"
602
    "		gl_FragColor = s_norm * vec4(1.0);\n"
603
    "       gl_FragColor *= dot_ln;\n"
604
    "       gl_FragColor.r = pow(gl_FragColor.r, 1.0);\n"
605
    "       gl_FragColor.g = pow(gl_FragColor.g, 1.0);\n"
606
    "       gl_FragColor.b = pow(gl_FragColor.b, 1.0);\n"
607
    "	}\n";
608
 
609
    void AmbientOcclusionRenderer::compile_display_list(const HMesh::Manifold& m, HMesh::VertexAttributeVector<double>& field, double max_val)
610
    {	
611
        GLint old_prog;
612
        glGetIntegerv(GL_CURRENT_PROGRAM, &old_prog);
613
        glUseProgram(prog);
614
 
615
        GLuint scalar_attrib = glGetAttribLocation(prog, "scalar");
616
        glUniform1fARB(glGetUniformLocationARB(prog, "scalar_max"), max_val);
617
 
618
        glNewList(display_list,GL_COMPILE);
619
 
620
        for(FaceIDIterator f = m.faces_begin(); f != m.faces_end(); ++f){
621
 
622
            if(no_edges(m, *f)== 3)
623
                glBegin(GL_TRIANGLES);
624
            else 
625
                glBegin(GL_POLYGON);
626
 
627
            for(Walker w = m.walker(*f); !w.full_circle(); w = w.circulate_face_ccw())
628
            {
629
                Vec3d n(normal(m, w.vertex()));
630
                glNormal3dv(n.get());
631
                glVertexAttrib1d(scalar_attrib, field[w.vertex()]);
632
                glVertex3dv(m.pos(w.vertex()).get());
633
            }
634
            glEnd();
635
        }
636
        glEndList();	
637
        glUseProgram(old_prog);
638
 
639
    }
640
 
641
 
642
    void LineFieldRenderer::compile_display_list(const HMesh::Manifold& m,HMesh::VertexAttributeVector<CGLA::Vec3d>& lines)
643
    {
644
        float r;
645
        Vec3d c;
646
        bsphere(m, c, r);
647
        float noise_scale = 10.0f/r;
648
        float line_scale = 0.02f;
649
 
650
        GLint old_prog;
651
        glGetIntegerv(GL_CURRENT_PROGRAM, &old_prog);
652
        glUseProgram(prog);
653
        glNewList(display_list,GL_COMPILE);
654
        glUniform1fARB(glGetUniformLocationARB(prog, "line_scale"),line_scale);
655
        glUniform1fARB(glGetUniformLocationARB(prog, "noise_scale"),noise_scale);
656
        glUniform1iARB(glGetUniformLocationARB(prog, "noise_tex"),0);
657
        GLuint direction = glGetAttribLocation(prog, "direction");	
658
        glBindTexture(GL_TEXTURE_3D, get_noise_texture_id());
659
 
660
 
661
        for(FaceIDIterator f = m.faces_begin(); f != m.faces_end(); ++f){
662
            if(no_edges(m, *f) == 3)
663
                glBegin(GL_TRIANGLES);
664
            else 
665
                glBegin(GL_POLYGON);
666
 
667
            Vec3d n(normal(m, *f));
668
            Vec3d d0 = lines[m.walker(*f).vertex()];
669
            d0 = normalize(d0-n*dot(n,d0));
670
            for(Walker w = m.walker(*f); !w.full_circle(); w = w.circulate_face_ccw()){
671
                Vec3d n(normal(m, w.vertex()));
672
                glNormal3dv(n.get());
673
 
674
                Vec3d d = lines[w.vertex()];
675
                d = normalize(d-n*dot(n,d));
676
                if(dot(d,d0)<0) d=-d;
677
                glVertexAttrib3dv(direction, d.get());
678
                glVertex3dv(m.pos(w.vertex()).get());
679
            }
680
            glEnd();
681
        }
682
 
683
        glBindTexture(GL_TEXTURE_3D, 0);
684
        glEndList();	
685
        glUseProgram(old_prog);
686
 
687
    }
688
 
689
 
690
    const string LineFieldRenderer::vss = 
691
    "attribute vec3 direction;\n"
692
    "varying vec3 _n;\n"
693
    "varying vec3 dir_obj;\n"
694
    "varying vec3 v_obj;\n"
695
    "\n"
696
    "void main(void)\n"
697
    "{\n"
698
    "	gl_Position = ftransform();\n"
699
    "   v_obj = gl_Vertex.xyz;\n"
700
    "	dir_obj = direction;\n"
701
    "	_n = normalize(gl_NormalMatrix * gl_Normal);\n"
702
    "}\n";
703
 
704
    const string LineFieldRenderer::fss =
705
    "uniform sampler3D noise_tex;\n"
706
    "uniform float line_scale;\n"
707
    "uniform float noise_scale;\n"
708
    "varying vec3 _n;\n"
709
    "varying vec3 dir_obj;\n"
710
    "varying vec3 v_obj;\n"
711
    "\n"
712
    "float tex(vec3 p) {return smoothstep(0.2,0.4,texture3D(noise_tex, p).x);}\n"
713
    "void main(void)\n"
714
    "{\n"
715
    "   vec3 n = normalize(_n);\n"
716
    "   vec3 d = normalize(dir_obj);\n"
717
    "   float I = "
718
    "             tex(noise_scale*v_obj + 6.0*line_scale*d) + \n"
719
    "             tex(noise_scale*v_obj - 6.0*line_scale*d) + \n"
720
    "             tex(noise_scale*v_obj + 5.0*line_scale*d) + \n"
721
    "             tex(noise_scale*v_obj - 5.0*line_scale*d) + \n"
722
    "             tex(noise_scale*v_obj + 4.0*line_scale*d) + \n"
723
    "             tex(noise_scale*v_obj - 4.0*line_scale*d) + \n"
724
    "             tex(noise_scale*v_obj + 3.0*line_scale*d) + \n"
725
    "             tex(noise_scale*v_obj - 3.0*line_scale*d) + \n"
726
    "             tex(noise_scale*v_obj + 2.0*line_scale*d) + \n"
727
    "             tex(noise_scale*v_obj - 2.0*line_scale*d) + \n"
728
    "             tex(noise_scale*v_obj + 1.0*line_scale*d) + \n"
729
    "             tex(noise_scale*v_obj - 1.0*line_scale*d) + \n"
730
    "			  tex(noise_scale*v_obj); \n"
731
    "	\n"
732
    "   float diff = max(0.0,dot(n,vec3(0.0, 0.0, 1.0)));\n"
733
    "	gl_FragColor.rgb = vec3(diff*I/13.0);\n"
734
    "	gl_FragColor.a = 1.0;\n"
735
    "}\n";
736
 
737
    GLuint HarmonicsRenderer::prog_P0 = 0;
738
    GLGraphics::Console::variable<float> HarmonicsRenderer::display_harmonics_time;
739
    GLGraphics::Console::variable<int> HarmonicsRenderer::display_harmonics_diffuse;
740
    GLGraphics::Console::variable<int> HarmonicsRenderer::display_harmonics_highlight;
741
 
742
    GLGraphics::Console::variable<int> HarmonicsRenderer::display_harmonics_e0;
743
    GLGraphics::Console::variable<int> HarmonicsRenderer::display_harmonics_e1;
744
 
745
    string vss =
746
	"#version 120\n"
747
	"#extension GL_EXT_gpu_shader4 : enable\n"
748
	"	\n"
749
	"	\n"
750
	"	attribute float eigenvalue;\n"
751
	"	attribute float eigenvalue2;\n"
752
	"	varying vec3 normal;\n"
753
	"	varying float eig;\n"
754
	"	varying float eig2;\n"
755
	"	\n"
756
	"	void main(void)\n"
757
	"	{\n"
758
	"		gl_Position =  ftransform();\n"
759
	"		normal = normalize(gl_NormalMatrix * gl_Normal);\n"
760
	"		eig = eigenvalue;\n"
761
	"		eig2 = eigenvalue2;\n"
762
	"	}\n";
763
 
764
	string fss =
765
	"#version 120\n"
766
	"#extension GL_EXT_gpu_shader4 : enable\n"
767
	"	\n"
768
	"	varying vec3 normal;\n"
769
	"	varying float eig;\n"
770
	"	varying float eig2;\n"
771
	"	uniform float eig_max;\n"
772
	"	uniform float eig_max2;\n"
773
	"	uniform bool do_highlight;\n"
774
	"	uniform bool do_diffuse;\n"
775
	"	const vec3 light_dir = vec3(0,0,1);\n"
776
	"	\n"
777
	" float basef(float x) {return max(0.0,min(1.0,2.0-4.0*abs(x)));\n}"
778
	"	void main()\n"
779
	"	{\n"
780
	"		float dot_ln = max(0.0,dot(light_dir, normal));\n"
781
	"		\n"
782
	"		float eig_norm = eig/eig_max;\n"
783
	"		float stripe_signal = 250 * eig_norm;\n"
784
	//"		vec4 stripe_col = abs(stripe_signal) < 3.14 ? vec4(1,1,0,0) : vec4(.4,.4,.4,0);\n"
785
	"		vec4 stripe_col = -vec4(.4,.4,.4,0);\n"
786
	"		\n"
787
	"       float alpha = (1.0-eig_norm) * 2.0 * 3.1415926;\n"
788
	"       float offs = 2.0*3.1415/3.0;\n"
789
	"		gl_FragColor = vec4(0,0,1,0)*basef(eig_norm)+vec4(0,1,0,0)*basef(eig_norm-0.5)+vec4(1,0,0,0)* basef(eig_norm-1.0);\n"
790
	"		if(do_diffuse)   gl_FragColor *= dot_ln;\n"
791
	"		if(do_highlight) gl_FragColor += dot_ln*dot_ln*dot_ln*dot_ln*dot_ln*dot_ln*dot_ln*vec4(.5,.5,.5,0);\n"
792
	"		gl_FragColor -= vec4(.4,.4,.4,.4)*smoothstep(0.2,0.6,cos(stripe_signal));\n"
793
	"	}\n";
794
 
795
 
796
    HarmonicsRenderer::HarmonicsRenderer(HMesh::Manifold& _m, HMesh::Harmonics* _h, GLGraphics::Console& cs): m(&_m), h(_h)
797
    {
798
        if (prog_P0 == 0) {
799
            string shader_path = "/Users/jab/GEL/apps/MeshEdit/";
800
            GLuint vs = create_glsl_shader(GL_VERTEX_SHADER, vss);
801
            GLuint fs = create_glsl_shader(GL_FRAGMENT_SHADER, fss);
802
 
803
            // Create the program
804
            prog_P0 = glCreateProgram();
805
 
806
            // Attach all shaders
807
            if(vs) glAttachShader(prog_P0, vs);
808
            if(fs) glAttachShader(prog_P0, fs);
809
 
810
            // Link the program object and print out the info log
811
            glLinkProgram(prog_P0);
812
            print_glsl_program_log(prog_P0);
813
 
814
            // Install program object as part of current state
815
            glUseProgram(0);
816
 
817
 
818
            display_harmonics_diffuse.reg(cs, "display.harmonics.diffuse", "");
819
            display_harmonics_time.reg(cs, "display.harmonics.time", "");
820
            display_harmonics_highlight.reg(cs, "display.harmonics.highlight", "");
821
            display_harmonics_e0.reg(cs,"display.harmonics.e0","");
822
            display_harmonics_e1.reg(cs,"display.harmonics.e1","");
823
        }
824
        draw_esum();
825
    }
826
 
827
 
828
    void HarmonicsRenderer::parse_key(unsigned char key)
829
    {
830
        switch(key) {
831
            case '+':
832
                display_harmonics_time = display_harmonics_time+0.001;
833
                break;
834
            case '-':
835
                display_harmonics_time = display_harmonics_time-0.001;
836
                break;
837
            case 'd':
838
                display_harmonics_diffuse = !display_harmonics_diffuse;
839
                break;
840
            case 'h':
841
                display_harmonics_highlight = !display_harmonics_highlight;
842
                break;
843
        }
844
 
845
    }
846
 
847
 
848
 
849
 
850
    void HarmonicsRenderer::draw_adf()
851
    {
852
        VertexAttributeVector<double> F;
853
        double F_max = h->compute_adf(F, display_harmonics_time);
854
        cout << "F max" <<  F_max << endl;
855
 
856
        glNewList(display_list, GL_COMPILE);
857
        glUseProgram(prog_P0);
858
        glUniform1f(glGetUniformLocation(prog_P0,"eig_max"),F_max);//2*M_PI);
859
        glUniform1i(glGetUniformLocation(prog_P0,"do_diffuse"),display_harmonics_diffuse);
860
        glUniform1i(glGetUniformLocation(prog_P0,"do_highlight"),display_harmonics_highlight);
861
        GLuint attrib = glGetAttribLocationARB(prog_P0, "eigenvalue");
862
 
863
        glFrontFace(GL_CW);
864
        for(FaceIDIterator f = m->faces_begin(); f != m->faces_end(); ++f){
865
            glBegin(GL_TRIANGLES);
866
            for(Walker w = m->walker(*f); !w.full_circle(); w = w.circulate_face_cw()){
867
                glVertexAttrib1f(attrib,F[w.vertex()]);
868
                glNormal3dv(normal(*m, w.vertex()).get());
869
                glVertex3dv(m->pos(w.vertex()).get());
870
            }
871
            glEnd();
872
        }
873
        glFrontFace(GL_CCW);
874
        glUseProgram(0);
875
        glEndList();
876
    }
877
 
878
    void HarmonicsRenderer::draw_esum()
879
    {
880
        VertexAttributeVector<double> F;
881
        double F_max = h->compute_esum(F, display_harmonics_e0, display_harmonics_e1);
882
        cout << "F max" <<  F_max << endl;
883
 
884
        glNewList(display_list, GL_COMPILE);
885
        glUseProgram(prog_P0);
886
        glUniform1f(glGetUniformLocation(prog_P0,"eig_max"),F_max);//2*M_PI);
887
        glUniform1i(glGetUniformLocation(prog_P0,"do_diffuse"),display_harmonics_diffuse);
888
        glUniform1i(glGetUniformLocation(prog_P0,"do_highlight"),display_harmonics_highlight);
889
        GLuint attrib = glGetAttribLocationARB(prog_P0, "eigenvalue");
890
 
891
        glFrontFace(GL_CW);
892
        for(FaceIDIterator f = m->faces_begin(); f != m->faces_end(); ++f){
893
            glBegin(GL_TRIANGLES);
894
            for(Walker w = m->walker(*f); !w.full_circle(); w = w.circulate_face_cw()){
895
                glVertexAttrib1f(attrib,F[w.vertex()]);
896
                glNormal3dv(normal(*m, w.vertex()).get());
897
                glVertex3dv(m->pos(w.vertex()).get());
898
            }
899
            glEnd();
900
        }
901
        glFrontFace(GL_CCW);
902
        glUseProgram(0);
903
        glEndList();
904
    }
905
 
906
 
907
 
908
}
909
 
910