Subversion Repositories gelsvn

Rev

Rev 630 | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 630 Rev 657
1
/* ----------------------------------------------------------------------- *
1
/* ----------------------------------------------------------------------- *
2
 * This file is part of GEL, http://www.imm.dtu.dk/GEL
2
 * This file is part of GEL, http://www.imm.dtu.dk/GEL
3
 * Copyright (C) the authors and DTU Informatics
3
 * Copyright (C) the authors and DTU Informatics
4
 * For license and list of authors, see ../../doc/intro.pdf
4
 * For license and list of authors, see ../../doc/intro.pdf
5
 * ----------------------------------------------------------------------- */
5
 * ----------------------------------------------------------------------- */
6
 
6
 
7
#include "IDBufferWireFrameRenderer.h"
7
#include "IDBufferWireFrameRenderer.h"
8
 
8
 
9
#include "../CGLA/Vec4f.h"
9
#include "../CGLA/Vec4f.h"
10
#include "../CGLA/Vec2f.h"
10
#include "../CGLA/Vec2f.h"
11
#include "../CGLA/Vec3f.h"
11
#include "../CGLA/Vec3f.h"
12
#include "../HMesh/Manifold.h"
12
#include "../HMesh/Manifold.h"
13
#include "../HMesh/AttributeVector.h"
13
#include "../HMesh/AttributeVector.h"
14
 
14
 
15
#include "../GLGraphics/draw.h"
15
#include "../GLGraphics/draw.h"
16
 
16
 
17
#include "glsl_shader.h"
17
#include "glsl_shader.h"
18
 
18
 
19
using namespace std;
19
using namespace std;
20
using namespace CGLA;
20
using namespace CGLA;
21
using namespace GLGraphics;
21
using namespace GLGraphics;
22
using namespace HMesh;
22
using namespace HMesh;
23
 
23
 
24
namespace
24
namespace
25
{
25
{
26
    string line_atten_frag = 
26
    string line_atten_frag = 
27
        "uniform int ATTEN_MODE;\n"
27
        "uniform int ATTEN_MODE;\n"
28
        "uniform float THICKNESS;\n"
28
        "uniform float THICKNESS;\n"
29
        "uniform sampler2DRect IDMAP;\n"
29
        "uniform sampler2DRect IDMAP;\n"
30
        "uniform float TRANSITION;\n"
30
        "uniform float TRANSITION;\n"
31
        "\n"
31
        "\n"
32
        "varying vec3 _id;\n"
32
        "varying vec3 _id;\n"
33
        "varying vec2 p_2d_0;\n"
33
        "varying vec2 p_2d_0;\n"
34
        "varying vec2 p_2d_1;\n"
34
        "varying vec2 p_2d_1;\n"
35
        "\n"
35
        "\n"
36
        "const int LINEAR_ATTENUATION = 1;\n"
36
        "const int LINEAR_ATTENUATION = 1;\n"
37
        "const int HERMITE_ATTENUATION = 2;\n"
37
        "const int HERMITE_ATTENUATION = 2;\n"
38
        "\n"
38
        "\n"
39
        "const float HERMITE_COL_ATTEN_BIAS = 0.25;\n"
39
        "const float HERMITE_COL_ATTEN_BIAS = 0.25;\n"
40
        "const float LINEAR_COL_ATTEN_BIAS = 0.4;\n"
40
        "const float LINEAR_COL_ATTEN_BIAS = 0.4;\n"
41
        "const float HERMITE_ATTEN_BEGIN = 0.75;\n"
41
        "const float HERMITE_ATTEN_BEGIN = 0.75;\n"
42
        "const float HERMITE_ATTEN_END = 1.0;\n"
42
        "const float HERMITE_ATTEN_END = 1.0;\n"
43
        "\n"
43
        "\n"
44
        "void main(void)\n"
44
        "void main(void)\n"
45
        "{\n"
45
        "{\n"
46
        "	vec2 dir = (p_2d_1-p_2d_0);\n"
46
        "	vec2 dir = (p_2d_1-p_2d_0);\n"
47
        "	float sq_len01 = dot(dir,dir);\n"
47
        "	float sq_len01 = dot(dir,dir);\n"
48
        "	vec2 v0 = (gl_FragCoord.xy)-p_2d_0;\n"
48
        "	vec2 v0 = (gl_FragCoord.xy)-p_2d_0;\n"
49
        "	vec2 v1 = (gl_FragCoord.xy)-p_2d_1;\n"
49
        "	vec2 v1 = (gl_FragCoord.xy)-p_2d_1;\n"
50
        "	float t = dot(dir, v0);\n"
50
        "	float t = dot(dir, v0);\n"
51
        "	float d;\n"
51
        "	float d;\n"
52
        "	\n"
52
        "	\n"
53
        "	if(t<=0.0)\n"
53
        "	if(t<=0.0)\n"
54
        "			d = length(v0);\n"
54
        "			d = length(v0);\n"
55
        "	else if(t>= sq_len01)\n"
55
        "	else if(t>= sq_len01)\n"
56
        "			d = length(v1);\n"
56
        "			d = length(v1);\n"
57
        "	else\n"
57
        "	else\n"
58
        "			d = length(dir * t / sq_len01 - v0);\n"
58
        "			d = length(dir * t / sq_len01 - v0);\n"
59
        "	\n"
59
        "	\n"
60
        "	vec3 iddiff = texture2DRect(IDMAP,gl_FragCoord.xy).xyz - _id;\n"
60
        "	vec3 iddiff = texture2DRect(IDMAP,gl_FragCoord.xy).xyz - _id;\n"
61
        " 	if(dot(iddiff, iddiff)<1e-6)\n"
61
        " 	if(dot(iddiff, iddiff)<1e-6)\n"
62
        "		gl_FragDepth = 0.0;\n"
62
        "		gl_FragDepth = 0.0;\n"
63
        "	else	\n"
63
        "	else	\n"
64
        "		gl_FragDepth = gl_FragCoord.z;\n"
64
        "		gl_FragDepth = gl_FragCoord.z;\n"
65
        "	\n"
65
        "	\n"
66
        "	\n"
66
        "	\n"
67
        "	float t1 = THICKNESS;\n"
67
        "	float t1 = THICKNESS;\n"
68
        "	if(ATTEN_MODE == HERMITE_ATTENUATION)\n"
68
        "	if(ATTEN_MODE == HERMITE_ATTENUATION)\n"
69
        "		{\n"
69
        "		{\n"
70
        "			float width_atten = smoothstep(HERMITE_ATTEN_END,HERMITE_ATTEN_BEGIN,\n"
70
        "			float width_atten = smoothstep(HERMITE_ATTEN_END,HERMITE_ATTEN_BEGIN,\n"
71
        "																		 gl_FragCoord.z);\n"
71
        "																		 gl_FragCoord.z);\n"
72
        "			t1 *= width_atten;\n"
72
        "			t1 *= width_atten;\n"
73
        "		}\n"
73
        "		}\n"
74
        "	else if(ATTEN_MODE == LINEAR_ATTENUATION)\n"
74
        "	else if(ATTEN_MODE == LINEAR_ATTENUATION)\n"
75
        "		{\n"
75
        "		{\n"
76
        "			float width_atten = 1.0-gl_FragCoord.z;\n"
76
        "			float width_atten = 1.0-gl_FragCoord.z;\n"
77
        "			t1 *= width_atten;\n"
77
        "			t1 *= width_atten;\n"
78
        "		}			\n"
78
        "		}			\n"
79
        "	float t2 = t1+TRANSITION;\n"
79
        "	float t2 = t1+TRANSITION;\n"
80
        "\n"
80
        "\n"
81
        "	float I;\n"
81
        "	float I;\n"
82
        "	if(d<t1) \n"
82
        "	if(d<t1) \n"
83
        "			I = 1.0;\n"
83
        "			I = 1.0;\n"
84
        "	else\n"
84
        "	else\n"
85
        "	{\n"
85
        "	{\n"
86
        "			float x = (d-t1);\n"
86
        "			float x = (d-t1);\n"
87
        "			I = exp2(-x*x*2);\n"
87
        "			I = exp2(-x*x*2);\n"
88
        "	}\n"
88
        "	}\n"
89
        " 	gl_FragColor.rgb = gl_Color.rgb;\n"
89
        " 	gl_FragColor.rgb = gl_Color.rgb;\n"
90
        "	gl_FragColor.a = I;\n"
90
        "	gl_FragColor.a = I;\n"
91
        "}\n";
91
        "}\n";
92
 
92
 
93
    string line_frag = 
93
    string line_frag = 
94
        "uniform sampler2DRect IDMAP;\n"
94
        "uniform sampler2DRect IDMAP;\n"
95
        "uniform float TRANSITION;\n"
95
        "uniform float TRANSITION;\n"
96
        "	\n"
96
        "	\n"
97
        "varying vec3 _id;\n"
97
        "varying vec3 _id;\n"
98
        "varying vec2 p_2d_0;\n"
98
        "varying vec2 p_2d_0;\n"
99
        "varying vec2 p_2d_1;\n"
99
        "varying vec2 p_2d_1;\n"
100
        "\n"
100
        "\n"
101
        "void main(void)\n"
101
        "void main(void)\n"
102
        "{\n"
102
        "{\n"
103
        "	vec2 dir = (p_2d_1-p_2d_0);\n"
103
        "	vec2 dir = (p_2d_1-p_2d_0);\n"
104
        "	float sq_len01 = dot(dir,dir);\n"
104
        "	float sq_len01 = dot(dir,dir);\n"
105
        "	vec2 v0 = gl_FragCoord.xy-p_2d_0;\n"
105
        "	vec2 v0 = gl_FragCoord.xy-p_2d_0;\n"
106
        "	vec2 v1 = gl_FragCoord.xy-p_2d_1;\n"
106
        "	vec2 v1 = gl_FragCoord.xy-p_2d_1;\n"
107
        "	float t = dot(dir, v0);\n"
107
        "	float t = dot(dir, v0);\n"
108
        "	float sq_d;\n"
108
        "	float sq_d;\n"
109
        "	\n"
109
        "	\n"
110
        "	if(t<=0.0)\n"
110
        "	if(t<=0.0)\n"
111
        "		sq_d = dot(v0,v0);\n"
111
        "		sq_d = dot(v0,v0);\n"
112
        "	else if(t>= sq_len01)\n"
112
        "	else if(t>= sq_len01)\n"
113
        "		sq_d = dot(v1,v1);\n"
113
        "		sq_d = dot(v1,v1);\n"
114
        "	else\n"
114
        "	else\n"
115
        "		{\n"
115
        "		{\n"
116
        "			float area = (v0.x*v1.y - v0.y * v1.x);\n"
116
        "			float area = (v0.x*v1.y - v0.y * v1.x);\n"
117
        "			sq_d = area*area/sq_len01;\n"
117
        "			sq_d = area*area/sq_len01;\n"
118
        "		}\n"
118
        "		}\n"
119
        "\n"
119
        "\n"
120
        "	vec3 iddiff = texture2DRect(IDMAP,gl_FragCoord.xy).xyz -_id;\n"
120
        "	vec3 iddiff = texture2DRect(IDMAP,gl_FragCoord.xy).xyz -_id;\n"
121
        "	if(dot(iddiff, iddiff)<1e-6)\n"
121
        "	if(dot(iddiff, iddiff)<1e-6)\n"
122
        "		gl_FragDepth = 0.0;\n"
122
        "		gl_FragDepth = 0.0;\n"
123
        " 	else	\n"
123
        " 	else	\n"
124
        " 		gl_FragDepth = gl_FragCoord.z;\n"
124
        " 		gl_FragDepth = gl_FragCoord.z;\n"
125
        "	\n"
125
        "	\n"
126
        "	gl_FragColor.a = exp2(-sq_d*2.0);\n"
126
        "	gl_FragColor.a = exp2(-sq_d*2.0);\n"
127
        "	gl_FragColor.rgb = gl_Color.rgb;\n"
127
        "	gl_FragColor.rgb = vec3(1,0,0);\n"
128
        "}\n";
128
        "}\n";
129
 
129
 
130
    string line_vert = 
130
    string line_vert = 
131
        "uniform float THICKNESS;\n"
131
        "uniform float THICKNESS;\n"
132
        "uniform vec2 WIN_SCALE;\n"
132
        "uniform vec2 WIN_SCALE;\n"
133
        "uniform vec2 INV_WIN_SCALE;\n"
133
        "uniform vec2 INV_WIN_SCALE;\n"
134
        "uniform float TRANSITION;\n"
134
        "uniform float TRANSITION;\n"
135
        "\n"
135
        "\n"
136
        "attribute vec4 id;\n"
136
        "attribute vec4 id;\n"
137
        "attribute vec4 opp_vertex;\n"
137
        "attribute vec4 opp_vertex;\n"
138
        "attribute vec2 displace;\n"
138
        "attribute vec2 displace;\n"
139
        "\n"
139
        "\n"
140
        "varying vec3 _id;\n"
140
        "varying vec3 _id;\n"
141
        "varying vec2 p_2d_0;\n"
141
        "varying vec2 p_2d_0;\n"
142
        "varying vec2 p_2d_1;\n"
142
        "varying vec2 p_2d_1;\n"
143
        "\n"
143
        "\n"
144
        "\n"
144
        "\n"
145
        "void main(void)\n"
145
        "void main(void)\n"
146
        "{\n"
146
        "{\n"
147
        "	vec4 p0 = gl_ModelViewProjectionMatrix * opp_vertex;\n"
147
        "	vec4 p0 = gl_ModelViewProjectionMatrix * opp_vertex;\n"
148
        "	float w0 = p0.w; \n"
148
        "	float w0 = p0.w; \n"
149
        "\n"
149
        "\n"
150
        "	vec4 p1 = gl_ModelViewProjectionMatrix * gl_Vertex;\n"
150
        "	vec4 p1 = gl_ModelViewProjectionMatrix * gl_Vertex;\n"
151
        "	float w1 = p1.w;\n"
151
        "	float w1 = p1.w;\n"
152
        "		\n"
152
        "		\n"
153
        "	p_2d_0 = (p0.xy/w0+vec2(1,1)) * WIN_SCALE;\n"
153
        "	p_2d_0 = (p0.xy/w0+vec2(1,1)) * WIN_SCALE;\n"
154
        "	p_2d_1 = (p1.xy/w1+vec2(1,1)) * WIN_SCALE;\n"
154
        "	p_2d_1 = (p1.xy/w1+vec2(1,1)) * WIN_SCALE;\n"
155
        "	\n"
155
        "	\n"
156
        "	vec2 a = normalize(p_2d_1 - p_2d_0);\n"
156
        "	vec2 a = normalize(p_2d_1 - p_2d_0);\n"
157
        "	vec2 a_h = vec2(-a.y, a.x);\n"
157
        "	vec2 a_h = vec2(-a.y, a.x);\n"
158
        "	vec2 scale = (TRANSITION+THICKNESS)*INV_WIN_SCALE;\n"
158
        "	vec2 scale = (TRANSITION+THICKNESS)*INV_WIN_SCALE;\n"
159
        "\n"
159
        "\n"
160
        "	gl_Position = (displace.x>0.0) ? p1 : p0;\n"
160
        "	gl_Position = (displace.x>0.0) ? p1 : p0;\n"
161
        "	vec2 offset = a * displace.x + a_h * displace.y;\n"
161
        "	vec2 offset = a * displace.x + a_h * displace.y;\n"
162
        "	gl_Position.xy += scale * gl_Position.w * offset;\n"
162
        "	gl_Position.xy += scale * gl_Position.w * offset;\n"
163
        "\n"
163
        "\n"
164
        "	_id = id.rgb;\n"
164
        "	_id = id.rgb;\n"
165
        "	gl_FrontColor = gl_Color;\n"
-
 
166
        "	gl_FrontSecondaryColor = gl_SecondaryColor;\n"
-
 
167
        "}\n";
165
        "}\n";
168
 
166
 
169
}
167
}
170
 
168
 
171
namespace GLGraphics
169
namespace GLGraphics
172
{
170
{
173
    IDBufferWireframeRenderer::~IDBufferWireframeRenderer()
171
    IDBufferWireframeRenderer::~IDBufferWireframeRenderer()
174
    {
172
    {
175
        glDeleteShader(vs);	
173
        glDeleteShader(vs);	
176
        glDeleteShader(fs);
174
        glDeleteShader(fs);
177
        glDeleteProgram(line_prog);
175
        glDeleteProgram(line_prog);
178
        glDeleteTextures(1, &idmap);
176
        glDeleteTextures(1, &idmap);
179
        glDeleteBuffers(1, &vertex_buffername);
177
        glDeleteBuffers(1, &vertex_buffername);
180
        glDeleteBuffers(1, &colors_buffername);
178
        glDeleteBuffers(1, &colors_buffername);
181
 
179
 
182
        glDeleteBuffers(1, &line_id_attrib);
180
        glDeleteBuffers(1, &line_id_attrib);
183
        glDeleteBuffers(1, &line_vertex_pos);
181
        glDeleteBuffers(1, &line_vertex_pos);
184
        glDeleteBuffers(1, &line_disp_attrib);			
182
        glDeleteBuffers(1, &line_disp_attrib);			
185
        glDeleteBuffers(1, &line_opp_attrib);
183
        glDeleteBuffers(1, &line_opp_attrib);
186
    }
184
    }
187
 
185
 
188
    IDBufferWireframeRenderer::IDBufferWireframeRenderer(int _XSZ, int _YSZ,
186
    IDBufferWireframeRenderer::IDBufferWireframeRenderer(int _XSZ, int _YSZ,
189
        HMesh::Manifold& _mesh, 
187
        HMesh::Manifold& _mesh, 
190
        float _thickness, 
188
        float _thickness, 
191
        float _transition, 
189
        float _transition, 
192
        int atten_mode): 
190
        int atten_mode): 
193
    mesh(&_mesh), XSZ(_XSZ), YSZ(_YSZ), thickness(_thickness), transition(_transition)
191
    mesh(&_mesh), XSZ(_XSZ), YSZ(_YSZ), thickness(_thickness), transition(_transition)
194
    {
192
    {
195
 
193
 
196
        if(atten_mode == 0 && thickness == 0.0)
194
        if(atten_mode == 0 && thickness == 0.0)
197
        {
195
        {
198
            vs = create_glsl_shader(GL_VERTEX_SHADER, line_vert);
196
            vs = create_glsl_shader(GL_VERTEX_SHADER, line_vert);
199
            fs = create_glsl_shader(GL_FRAGMENT_SHADER, line_frag);
197
            fs = create_glsl_shader(GL_FRAGMENT_SHADER, line_frag);
200
        }
198
        }
201
        else
199
        else
202
        {
200
        {
203
            vs = create_glsl_shader(GL_VERTEX_SHADER, line_vert);
201
            vs = create_glsl_shader(GL_VERTEX_SHADER, line_vert);
204
            fs = create_glsl_shader(GL_FRAGMENT_SHADER, line_atten_frag);
202
            fs = create_glsl_shader(GL_FRAGMENT_SHADER, line_atten_frag);
205
        }
203
        }
206
 
204
 
207
        line_prog = glCreateProgram();
205
        line_prog = glCreateProgram();
208
        glAttachShader(line_prog, vs);
206
        glAttachShader(line_prog, vs);
209
        glAttachShader(line_prog, fs);
207
        glAttachShader(line_prog, fs);
210
        glLinkProgram(line_prog);
208
        glLinkProgram(line_prog);
211
        glUseProgram(line_prog);
209
        glUseProgram(line_prog);
212
 
210
 
213
        glUniform1f(glGetUniformLocation(line_prog,"THICKNESS"), 
211
        glUniform1f(glGetUniformLocation(line_prog,"THICKNESS"), 
214
            thickness);
212
            thickness);
215
        glUniform1f(glGetUniformLocation(line_prog,"TRANSITION"), 
213
        glUniform1f(glGetUniformLocation(line_prog,"TRANSITION"), 
216
            transition);
214
            transition);
217
        glUniform1i(glGetUniformLocation(line_prog,"ATTEN_MODE"),
215
        glUniform1i(glGetUniformLocation(line_prog,"ATTEN_MODE"),
218
            atten_mode);
216
            atten_mode);
219
        glUniform2f(glGetUniformLocation(line_prog,"WIN_SCALE"), 
217
        glUniform2f(glGetUniformLocation(line_prog,"WIN_SCALE"), 
220
            XSZ/2.0, YSZ/2.0);
218
            XSZ/2.0, YSZ/2.0);
221
        glUniform2f(glGetUniformLocation(line_prog,"INV_WIN_SCALE"), 
219
        glUniform2f(glGetUniformLocation(line_prog,"INV_WIN_SCALE"), 
222
            2.0/XSZ, 2.0/YSZ);
220
            2.0/XSZ, 2.0/YSZ);
223
        glUniform1i(glGetUniformLocation(line_prog,"IDMAP"), 0);
221
        glUniform1i(glGetUniformLocation(line_prog,"IDMAP"), 0);
224
 
222
 
225
        id_attrib = glGetAttribLocation(line_prog, "id");
223
        id_attrib = glGetAttribLocation(line_prog, "id");
226
        popp_attrib = glGetAttribLocation(line_prog, "opp_vertex");
224
        popp_attrib = glGetAttribLocation(line_prog, "opp_vertex");
227
        disp_attrib = glGetAttribLocation(line_prog, "displace");
225
        disp_attrib = glGetAttribLocation(line_prog, "displace");
228
        glUseProgram(0);
226
        glUseProgram(0);
229
 
227
 
230
        glGenTextures(1, &idmap);
228
        glGenTextures(1, &idmap);
231
        glBindTexture(GL_TEXTURE_RECTANGLE_ARB, idmap);
229
        glBindTexture(GL_TEXTURE_RECTANGLE_ARB, idmap);
232
        glTexParameteri(GL_TEXTURE_RECTANGLE_ARB,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
230
        glTexParameteri(GL_TEXTURE_RECTANGLE_ARB,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
233
        glTexParameteri(GL_TEXTURE_RECTANGLE_ARB,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
231
        glTexParameteri(GL_TEXTURE_RECTANGLE_ARB,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
234
        glTexParameteri(GL_TEXTURE_RECTANGLE_ARB,GL_TEXTURE_WRAP_S,GL_CLAMP);
232
        glTexParameteri(GL_TEXTURE_RECTANGLE_ARB,GL_TEXTURE_WRAP_S,GL_CLAMP);
235
        glTexParameteri(GL_TEXTURE_RECTANGLE_ARB,GL_TEXTURE_WRAP_T,GL_CLAMP);
233
        glTexParameteri(GL_TEXTURE_RECTANGLE_ARB,GL_TEXTURE_WRAP_T,GL_CLAMP);
236
 
234
 
237
        //create the texture
235
        //create the texture
238
        glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA8, XSZ, YSZ,
236
        glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA8, XSZ, YSZ,
239
            0, GL_RGB, GL_FLOAT, 0);
237
            0, GL_RGB, GL_FLOAT, 0);
240
 
238
 
241
 
239
 
242
        glGenBuffers(1, &vertex_buffername);
240
        glGenBuffers(1, &vertex_buffername);
243
        glGenBuffers(1, &colors_buffername);
241
        glGenBuffers(1, &colors_buffername);
244
 
242
 
245
        glGenBuffers(1, &line_id_attrib);
243
        glGenBuffers(1, &line_id_attrib);
246
        glGenBuffers(1, &line_vertex_pos);
244
        glGenBuffers(1, &line_vertex_pos);
247
        glGenBuffers(1, &line_disp_attrib);
245
        glGenBuffers(1, &line_disp_attrib);
248
        glGenBuffers(1, &line_opp_attrib);
246
        glGenBuffers(1, &line_opp_attrib);
249
 
247
 
250
        triangles = static_cast<int>(mesh->no_faces());
248
        triangles = static_cast<int>(mesh->no_faces());
251
        vector<Vec3f> verts;
249
        vector<Vec3f> verts;
252
        vector<Vec3f> cols;
250
        vector<Vec3f> cols;
253
 
251
 
254
        unsigned int k = 0;
252
        unsigned int k = 0;
255
        for(FaceIDIterator f = mesh->faces_begin(); f != mesh->faces_end(); ++f, ++k){
253
        for(FaceIDIterator f = mesh->faces_begin(); f != mesh->faces_end(); ++f, ++k){
256
            Vec3uc idv(id_get(k));
254
            Vec3uc idv(id_get(k));
257
            Vec3f idvec(idv[0]/255.0, idv[1]/255.0, idv[2]/255.0);
255
            Vec3f idvec(idv[0]/255.0, idv[1]/255.0, idv[2]/255.0);
258
            for(Walker w = mesh->walker(*f); !w.full_circle(); w = w.circulate_face_ccw()){
256
            for(Walker w = mesh->walker(*f); !w.full_circle(); w = w.circulate_face_ccw()){
259
                cols.push_back(idvec);
257
                cols.push_back(idvec);
260
                verts.push_back(Vec3f(mesh->pos(w.vertex())));
258
                verts.push_back(Vec3f(mesh->pos(w.vertex())));
261
            }
259
            }
262
        }
260
        }
263
        glBindBuffer(GL_ARRAY_BUFFER, vertex_buffername);
261
        glBindBuffer(GL_ARRAY_BUFFER, vertex_buffername);
264
        glBufferData(GL_ARRAY_BUFFER, sizeof(float)*3*verts.size(),
262
        glBufferData(GL_ARRAY_BUFFER, sizeof(float)*3*verts.size(),
265
            (float*)&verts[0],GL_STATIC_DRAW);
263
            (float*)&verts[0],GL_STATIC_DRAW);
266
 
264
 
267
 
265
 
268
 
266
 
269
        glBindBuffer(GL_ARRAY_BUFFER, colors_buffername);
267
        glBindBuffer(GL_ARRAY_BUFFER, colors_buffername);
270
        glBufferData(GL_ARRAY_BUFFER, sizeof(float)*3*cols.size(),
268
        glBufferData(GL_ARRAY_BUFFER, sizeof(float)*3*cols.size(),
271
            (float*)&cols[0],GL_STATIC_DRAW);
269
            (float*)&cols[0],GL_STATIC_DRAW);
272
 
270
 
273
 
271
 
274
        vector<Vec3f> line_ids;
272
        vector<Vec3f> line_ids;
275
        vector<Vec3f> vertex_positions;
273
        vector<Vec3f> vertex_positions;
276
        vector<Vec2f> displacements;
274
        vector<Vec2f> displacements;
277
        vector<Vec3f> opposite_positions;
275
        vector<Vec3f> opposite_positions;
278
 
276
 
279
 
277
 
280
        quads = 0;
278
        quads = 0;
281
        unsigned int i = 0;
279
        unsigned int i = 0;
282
        for(FaceIDIterator f = mesh->faces_begin(); f != mesh->faces_end(); ++f,++i){
280
        for(FaceIDIterator f = mesh->faces_begin(); f != mesh->faces_end(); ++f,++i){
283
            for(Walker w = mesh->walker(*f); !w.full_circle(); w = w.circulate_face_ccw()){
281
            for(Walker w = mesh->walker(*f); !w.full_circle(); w = w.circulate_face_ccw()){
284
                ++quads;
282
                ++quads;
285
                Vec3uc idv(id_get(i));
283
                Vec3uc idv(id_get(i));
286
                Vec3f v0(mesh->pos(w.next().vertex()));
284
                Vec3f v0(mesh->pos(w.next().vertex()));
287
                Vec3f v1(mesh->pos(w.next().opp().vertex()));
285
                Vec3f v1(mesh->pos(w.next().opp().vertex()));
288
                Vec3f idvec(idv[0]/255.0, idv[1]/255.0, idv[2]/255.0);
286
                Vec3f idvec(idv[0]/255.0, idv[1]/255.0, idv[2]/255.0);
289
 
287
 
290
                line_ids.push_back(idvec);
288
                line_ids.push_back(idvec);
291
                opposite_positions.push_back(v0);
289
                opposite_positions.push_back(v0);
292
                displacements.push_back(Vec2f(1,-1));
290
                displacements.push_back(Vec2f(1,-1));
293
                vertex_positions.push_back(v1);
291
                vertex_positions.push_back(v1);
294
 
292
 
295
 
293
 
296
                line_ids.push_back(idvec);
294
                line_ids.push_back(idvec);
297
                opposite_positions.push_back(v0);
295
                opposite_positions.push_back(v0);
298
                displacements.push_back(Vec2f(1, 1));
296
                displacements.push_back(Vec2f(1, 1));
299
                vertex_positions.push_back(v1);
297
                vertex_positions.push_back(v1);
300
 
298
 
301
 
299
 
302
                line_ids.push_back(idvec);
300
                line_ids.push_back(idvec);
303
                opposite_positions.push_back(v0);
301
                opposite_positions.push_back(v0);
304
                displacements.push_back(Vec2f(-1,1));
302
                displacements.push_back(Vec2f(-1,1));
305
                vertex_positions.push_back(v1);
303
                vertex_positions.push_back(v1);
306
 
304
 
307
 
305
 
308
                line_ids.push_back(idvec);
306
                line_ids.push_back(idvec);
309
                opposite_positions.push_back(v0);
307
                opposite_positions.push_back(v0);
310
                displacements.push_back(Vec2f(-1,-1));
308
                displacements.push_back(Vec2f(-1,-1));
311
                vertex_positions.push_back(v1);
309
                vertex_positions.push_back(v1);
312
            }
310
            }
313
        }
311
        }
314
 
312
 
315
        glBindBuffer(GL_ARRAY_BUFFER, line_id_attrib);
313
        glBindBuffer(GL_ARRAY_BUFFER, line_id_attrib);
316
 
314
 
317
        glBufferData(GL_ARRAY_BUFFER, sizeof(float)*3*line_ids.size(),
315
        glBufferData(GL_ARRAY_BUFFER, sizeof(float)*3*line_ids.size(),
318
            (float*)&line_ids[0],GL_STATIC_DRAW);
316
            (float*)&line_ids[0],GL_STATIC_DRAW);
319
 
317
 
320
        glBindBuffer(GL_ARRAY_BUFFER, line_opp_attrib);
318
        glBindBuffer(GL_ARRAY_BUFFER, line_opp_attrib);
321
        glBufferData(GL_ARRAY_BUFFER, sizeof(float)*3*opposite_positions.size(),
319
        glBufferData(GL_ARRAY_BUFFER, sizeof(float)*3*opposite_positions.size(),
322
            (float*)&opposite_positions[0],GL_STATIC_DRAW);
320
            (float*)&opposite_positions[0],GL_STATIC_DRAW);
323
 
321
 
324
        glBindBuffer(GL_ARRAY_BUFFER, line_disp_attrib);
322
        glBindBuffer(GL_ARRAY_BUFFER, line_disp_attrib);
325
        glBufferData(GL_ARRAY_BUFFER, sizeof(float)*2*displacements.size(),
323
        glBufferData(GL_ARRAY_BUFFER, sizeof(float)*2*displacements.size(),
326
            (float*)&displacements[0],GL_STATIC_DRAW);
324
            (float*)&displacements[0],GL_STATIC_DRAW);
327
 
325
 
328
        glBindBuffer(GL_ARRAY_BUFFER, line_vertex_pos);
326
        glBindBuffer(GL_ARRAY_BUFFER, line_vertex_pos);
329
        glBufferData(GL_ARRAY_BUFFER, sizeof(float)*3*vertex_positions.size(),
327
        glBufferData(GL_ARRAY_BUFFER, sizeof(float)*3*vertex_positions.size(),
330
            (float*)&vertex_positions[0],GL_STATIC_DRAW);
328
            (float*)&vertex_positions[0],GL_STATIC_DRAW);
331
 
329
 
332
 
330
 
333
 
331
 
334
    }
332
    }
335
 
333
 
336
 
334
 
337
    void IDBufferWireframeRenderer::draw(const Vec3f& color, const Vec3f& clear_color)
335
    void IDBufferWireframeRenderer::draw(const Vec3f& color, const Vec3f& clear_color)
338
    {
336
    {
339
        // push those attributes we change.
337
        // push those attributes we change.
340
        glPushAttrib(GL_COLOR_BUFFER_BIT|
338
        glPushAttrib(GL_COLOR_BUFFER_BIT|
341
            GL_CURRENT_BIT|
339
            GL_CURRENT_BIT|
342
            GL_TRANSFORM_BIT|
340
            GL_TRANSFORM_BIT|
343
            GL_DEPTH_BUFFER_BIT);
341
            GL_DEPTH_BUFFER_BIT);
344
 
342
 
345
        // Store information about whether we use lighting
343
        // Store information about whether we use lighting
346
        GLboolean lights_on;
344
        GLboolean lights_on;
347
        glGetBooleanv(GL_LIGHTING, &lights_on);
345
        glGetBooleanv(GL_LIGHTING, &lights_on);
348
 
346
 
349
        // Store color information
347
        // Store color information
350
        Vec4f current_color;
348
        Vec4f current_color;
351
        glGetFloatv(GL_CURRENT_COLOR, &current_color[0]);
349
        glGetFloatv(GL_CURRENT_COLOR, &current_color[0]);
352
 
350
 
353
        // Store the current draw buffer 
351
        // Store the current draw buffer 
354
        GLint _currentDrawbuf;
352
        GLint _currentDrawbuf;
355
        glGetIntegerv(GL_DRAW_BUFFER, &_currentDrawbuf); 
353
        glGetIntegerv(GL_DRAW_BUFFER, &_currentDrawbuf); 
356
 
354
 
357
        // Enable depth testing
355
        // Enable depth testing
358
        glEnable(GL_DEPTH_TEST);
356
        glEnable(GL_DEPTH_TEST);
359
 
357
 
360
        // ------------------------------
358
        // ------------------------------
361
        // Pass 1: Draw the ID map
359
        // Pass 1: Draw the ID map
362
        // Each polygon has a unique ID which is coded as a colour and drawn
360
        // Each polygon has a unique ID which is coded as a colour and drawn
363
        // into the ID buffer
361
        // into the ID buffer
364
        glDisable(GL_LIGHTING);
362
        glDisable(GL_LIGHTING);
365
        glClearColor(0,0,0,0);
363
        glClearColor(0,0,0,0);
366
        glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
364
        glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
367
 
365
 
368
        glBindBuffer(GL_ARRAY_BUFFER, vertex_buffername);
366
        glBindBuffer(GL_ARRAY_BUFFER, vertex_buffername);
369
        glVertexPointer(3,GL_FLOAT,0,static_cast<char*>(0));
367
        glVertexPointer(3,GL_FLOAT,0,static_cast<char*>(0));
370
        glEnableClientState(GL_VERTEX_ARRAY);
368
        glEnableClientState(GL_VERTEX_ARRAY);
371
 
369
 
372
        glBindBuffer(GL_ARRAY_BUFFER, colors_buffername);
370
        glBindBuffer(GL_ARRAY_BUFFER, colors_buffername);
373
        glColorPointer(3,GL_FLOAT,0,static_cast<char*>(0));
371
        glColorPointer(3,GL_FLOAT,0,static_cast<char*>(0));
374
        glEnableClientState(GL_COLOR_ARRAY);
372
        glEnableClientState(GL_COLOR_ARRAY);
375
 
373
 
376
        int vertex_idx = 0;
374
        int vertex_idx = 0;
377
        for(FaceIDIterator f = mesh->faces_begin(); f != mesh->faces_end(); ++f){
375
        for(FaceIDIterator f = mesh->faces_begin(); f != mesh->faces_end(); ++f){
378
            glBegin(GL_POLYGON);
376
            glBegin(GL_POLYGON);
379
            for(Walker w = mesh->walker(*f); !w.full_circle(); w = w.circulate_face_ccw())
377
            for(Walker w = mesh->walker(*f); !w.full_circle(); w = w.circulate_face_ccw())
380
                 glArrayElement(vertex_idx++);
378
                 glArrayElement(vertex_idx++);
381
            glEnd();
379
            glEnd();
382
        }
380
        }
383
        glFinish();
381
        glFinish();
384
        glDisableClientState(GL_COLOR_ARRAY);
382
        glDisableClientState(GL_COLOR_ARRAY);
385
        glDisableClientState(GL_VERTEX_ARRAY);
383
        glDisableClientState(GL_VERTEX_ARRAY);
386
 
384
 
387
        glBindTexture(GL_TEXTURE_RECTANGLE_ARB, idmap);
385
        glBindTexture(GL_TEXTURE_RECTANGLE_ARB, idmap);
388
        glCopyTexSubImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, 0,0,0,0,XSZ, YSZ);
386
        glCopyTexSubImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, 0,0,0,0,XSZ, YSZ);
389
 
387
 
390
        // Clear color buffer but retain depth buffer.
388
        // Clear color buffer but retain depth buffer.
391
        glClear(GL_COLOR_BUFFER_BIT);
389
        glClear(GL_COLOR_BUFFER_BIT);
392
 
390
 
393
        // Enable blending for all subsequent passes
391
        // Enable blending for all subsequent passes
394
        glEnable(GL_BLEND);
392
        glEnable(GL_BLEND);
395
 
393
 
396
        // ------------------------------
394
        // ------------------------------
397
        // PASS 3: Draw lines using ID map texture.
395
        // PASS 3: Draw lines using ID map texture.
398
        // For each polygon, all edges are drawn as prefiltered
396
        // For each polygon, all edges are drawn as prefiltered
399
        // lines. A given fragment belonging to a line will be written
397
        // lines. A given fragment belonging to a line will be written
400
        // to the framebuffer if either of the following three conditions are met
398
        // to the framebuffer if either of the following three conditions are met
401
        // - its ID matches the contents of the ID  buffer for the corresponding 
399
        // - its ID matches the contents of the ID  buffer for the corresponding 
402
        // pixel (in the ID buffer)
400
        // pixel (in the ID buffer)
403
        // - The ID of the corresponding pixel is 0 - meaning we are outside.
401
        // - The ID of the corresponding pixel is 0 - meaning we are outside.
404
        // - The depth test is passed.
402
        // - The depth test is passed.
405
        // The final condition ensures that line pixels which are on an interior
403
        // The final condition ensures that line pixels which are on an interior
406
        // contour will be drawn.
404
        // contour will be drawn.
407
        //
405
        //
408
        // If the line fragment is written into the framebuffer - two values are
406
        // If the line fragment is written into the framebuffer - two values are
409
        // actually written: The colour of the line and an alpha value which
407
        // actually written: The colour of the line and an alpha value which
410
        // corresponds to the value of the filter function.
408
        // corresponds to the value of the filter function.
411
        //
409
        //
412
        // During this pass, blending is enabled and the blending equation is set
410
        // During this pass, blending is enabled and the blending equation is set
413
        // to max. Since the alpha values are the values of the filter (large if 
411
        // to max. Since the alpha values are the values of the filter (large if 
414
        // close to line) this means that we replace a pixel value with an 
412
        // close to line) this means that we replace a pixel value with an 
415
        // incoming fragment if the incoming fragment is closer to a line
413
        // incoming fragment if the incoming fragment is closer to a line
416
        // than the pixel value.
414
        // than the pixel value.
417
        //
415
        //
418
        // The depth values are not changed during this pass.
416
        // The depth values are not changed during this pass.
419
        glEnable(GL_TEXTURE_RECTANGLE_ARB);
417
        glEnable(GL_TEXTURE_RECTANGLE_ARB);
420
        glBindTexture(GL_TEXTURE_RECTANGLE_ARB, idmap);
418
        glBindTexture(GL_TEXTURE_RECTANGLE_ARB, idmap);
421
        glDepthMask(GL_FALSE);
419
        glDepthMask(GL_FALSE);
422
        glBlendEquation(GL_MAX);
420
        glBlendEquation(GL_MAX);
423
        glUseProgram(line_prog);
421
        glUseProgram(line_prog);
424
        glColor3fv(color.get());
-
 
425
        glSecondaryColor3fv(clear_color.get());
-
 
426
 
422
 
427
        float lw;
423
        float lw;
428
        glGetFloatv(GL_LINE_WIDTH, &lw);
424
        glGetFloatv(GL_LINE_WIDTH, &lw);
429
        glLineWidth(ceil(2.0*(thickness+transition)));
425
        glLineWidth(ceil(2.0*(thickness+transition)));
430
 
426
 
431
 
427
 
432
        glBindBuffer(GL_ARRAY_BUFFER, line_id_attrib);
428
        glBindBuffer(GL_ARRAY_BUFFER, line_id_attrib);
433
        glVertexAttribPointer(id_attrib, 3,GL_FLOAT,GL_FALSE,0,static_cast<char*>(0));
429
        glVertexAttribPointer(id_attrib, 3,GL_FLOAT,GL_FALSE,0,static_cast<char*>(0));
434
        glEnableVertexAttribArray(id_attrib);
430
        glEnableVertexAttribArray(id_attrib);
435
 
431
 
436
 
432
 
437
        glBindBuffer(GL_ARRAY_BUFFER, line_disp_attrib);
433
        glBindBuffer(GL_ARRAY_BUFFER, line_disp_attrib);
438
        glVertexAttribPointer(disp_attrib, 2,GL_FLOAT,GL_FALSE,0,static_cast<char*>(0));
434
        glVertexAttribPointer(disp_attrib, 2,GL_FLOAT,GL_FALSE,0,static_cast<char*>(0));
439
        glEnableVertexAttribArray(disp_attrib);
435
        glEnableVertexAttribArray(disp_attrib);
440
 
436
 
441
 
437
 
442
        glBindBuffer(GL_ARRAY_BUFFER, line_opp_attrib);
438
        glBindBuffer(GL_ARRAY_BUFFER, line_opp_attrib);
443
        glVertexAttribPointer(popp_attrib, 3,GL_FLOAT,GL_FALSE,0,static_cast<char*>(0));
439
        glVertexAttribPointer(popp_attrib, 3,GL_FLOAT,GL_FALSE,0,static_cast<char*>(0));
444
        glEnableVertexAttribArray(popp_attrib);
440
        glEnableVertexAttribArray(popp_attrib);
445
 
441
 
446
 
442
 
447
        glBindBuffer(GL_ARRAY_BUFFER, line_vertex_pos);
443
        glBindBuffer(GL_ARRAY_BUFFER, line_vertex_pos);
448
        glVertexPointer(3,GL_FLOAT,0,static_cast<char*>(0));
444
        glVertexPointer(3,GL_FLOAT,0,static_cast<char*>(0));
449
        glEnableClientState(GL_VERTEX_ARRAY);
445
        glEnableClientState(GL_VERTEX_ARRAY);
450
 
446
 
451
        glDrawArrays(GL_QUADS, 0, quads*4);
447
        glDrawArrays(GL_QUADS, 0, quads*4);
452
 
448
 
453
        glDisableVertexAttribArray(id_attrib);
449
        glDisableVertexAttribArray(id_attrib);
454
        glDisableVertexAttribArray(disp_attrib);
450
        glDisableVertexAttribArray(disp_attrib);
455
        glDisableVertexAttribArray(popp_attrib);
451
        glDisableVertexAttribArray(popp_attrib);
456
        glDisableClientState(GL_VERTEX_ARRAY);
452
        glDisableClientState(GL_VERTEX_ARRAY);
457
 
453
 
458
 
454
 
459
        glLineWidth(lw);
455
        glLineWidth(lw);
460
 
456
 
461
        glUseProgram(0);
457
        glUseProgram(0);
462
        glDisable(GL_TEXTURE_RECTANGLE_ARB);
458
        glDisable(GL_TEXTURE_RECTANGLE_ARB);
463
        glDepthMask(GL_TRUE);
459
        glDepthMask(GL_TRUE);
464
 
460
 
465
        // ------------------------------
461
        // ------------------------------
466
        // Pass 4: Draw with shading
462
        // Pass 4: Draw with shading
467
        // In this pass we draw the shaded model. At this point, the framebuffer
463
        // In this pass we draw the shaded model. At this point, the framebuffer
468
        // contains alpha values and line colours and also depth values.
464
        // contains alpha values and line colours and also depth values.
469
        //
465
        //
470
        // The depth test is set to `equal' and the shaded fragments from the 
466
        // The depth test is set to `equal' and the shaded fragments from the 
471
        // filled polygons are combined with the line colours using the alpha 
467
        // filled polygons are combined with the line colours using the alpha 
472
        // values already stored in the frame buffer.
468
        // values already stored in the frame buffer.
473
        //
469
        //
474
        // The framebuffer lines along the contour also need to be blended. 
470
        // The framebuffer lines along the contour also need to be blended. 
475
        // Hence, a screen filling quad is drawn. 
471
        // Hence, a screen filling quad is drawn. 
476
        glDepthFunc(GL_LEQUAL);
472
        glDepthFunc(GL_LEQUAL);
477
        glBlendEquation(GL_FUNC_ADD);
473
        glBlendEquation(GL_FUNC_ADD);
478
        glBlendFuncSeparate(GL_ONE_MINUS_DST_ALPHA, GL_DST_ALPHA, 
474
        glBlendFuncSeparate(GL_ONE_MINUS_DST_ALPHA, GL_DST_ALPHA, 
479
            GL_ZERO, GL_ONE);
475
            GL_ZERO, GL_ONE);
480
        if(lights_on)
476
        if(lights_on)
481
        {
477
        {
482
            glEnable(GL_LIGHTING);
478
            glEnable(GL_LIGHTING);
483
            glEnable(GL_LIGHT0);
479
            glEnable(GL_LIGHT0);
484
        }else
480
        }else
485
            glColor4fv(current_color.get());
481
            glColor4fv(current_color.get());
486
 
482
 
487
        glBindBuffer(GL_ARRAY_BUFFER, vertex_buffername);
483
        glBindBuffer(GL_ARRAY_BUFFER, vertex_buffername);
488
        glVertexPointer(3,GL_FLOAT,0,static_cast<char*>(0));
484
        glVertexPointer(3,GL_FLOAT,0,static_cast<char*>(0));
489
        glEnableClientState(GL_VERTEX_ARRAY);
485
        glEnableClientState(GL_VERTEX_ARRAY);
490
 
486
 
491
        vertex_idx = 0;
487
        vertex_idx = 0;
492
        for(FaceIDIterator f = mesh->faces_begin(); f != mesh->faces_end(); ++f){
488
        for(FaceIDIterator f = mesh->faces_begin(); f != mesh->faces_end(); ++f){
493
			Vec3f n(normal(*mesh, *f));
489
			Vec3f n(normal(*mesh, *f));
494
            glNormal3fv(n.get());
490
            glNormal3fv(n.get());
495
            glBegin(GL_POLYGON);
491
            glBegin(GL_POLYGON);
496
            for(Walker w = mesh->walker(*f); !w.full_circle(); w = w.circulate_face_ccw())
492
            for(Walker w = mesh->walker(*f); !w.full_circle(); w = w.circulate_face_ccw())
497
                 glArrayElement(vertex_idx++);
493
                 glArrayElement(vertex_idx++);
498
            glEnd();
494
            glEnd();
499
        }
495
        }
500
        glDisableClientState(GL_VERTEX_ARRAY);
496
        glDisableClientState(GL_VERTEX_ARRAY);
501
 
497
 
502
 
498
 
503
        glDisable(GL_LIGHTING);
499
        glDisable(GL_LIGHTING);
504
 
500
 
505
 
501
 
506
        double mvmat[16];
502
        double mvmat[16];
507
        glGetDoublev(GL_MODELVIEW_MATRIX, mvmat);
503
        glGetDoublev(GL_MODELVIEW_MATRIX, mvmat);
508
        double prjmat[16];
504
        double prjmat[16];
509
        glGetDoublev(GL_PROJECTION_MATRIX, prjmat);
505
        glGetDoublev(GL_PROJECTION_MATRIX, prjmat);
510
        glMatrixMode(GL_PROJECTION);
506
        glMatrixMode(GL_PROJECTION);
511
        glLoadIdentity();
507
        glLoadIdentity();
512
        glMatrixMode(GL_MODELVIEW);
508
        glMatrixMode(GL_MODELVIEW);
513
        glLoadIdentity();
509
        glLoadIdentity();
514
        glColor3fv(clear_color.get());
510
        glColor3fv(clear_color.get());
515
        glBegin(GL_QUADS);
511
        glBegin(GL_QUADS);
516
        glVertex3f(-1,-1,1);
512
        glVertex3f(-1,-1,1);
517
        glVertex3f( 1,-1,1);
513
        glVertex3f( 1,-1,1);
518
        glVertex3f( 1, 1,1);
514
        glVertex3f( 1, 1,1);
519
        glVertex3f(-1, 1,1);
515
        glVertex3f(-1, 1,1);
520
        glEnd();
516
        glEnd();
521
 
517
 
522
 
518
 
523
 
519
 
524
        glMatrixMode(GL_PROJECTION);
520
        glMatrixMode(GL_PROJECTION);
525
        glLoadMatrixd(prjmat);
521
        glLoadMatrixd(prjmat);
526
        glMatrixMode(GL_MODELVIEW);
522
        glMatrixMode(GL_MODELVIEW);
527
        glLoadMatrixd(mvmat);
523
        glLoadMatrixd(mvmat);
528
 
524
 
529
        glPopAttrib();
525
        glPopAttrib();
530
        if(lights_on)
526
        if(lights_on)
531
            glEnable(GL_LIGHTING);
527
            glEnable(GL_LIGHTING);
532
 
528
 
533
        //			cout << gluErrorString(glGetError()) << endl;
529
        //			cout << gluErrorString(glGetError()) << endl;
534
    }
530
    }
535
}
531
}
536
 
532