Subversion Repositories gelsvn

Rev

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

Rev 594 Rev 601
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 = gl_Color.rgb;\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"
165
        "	gl_FrontColor = gl_Color;\n"
166
        "	gl_FrontSecondaryColor = gl_SecondaryColor;\n"
166
        "	gl_FrontSecondaryColor = gl_SecondaryColor;\n"
167
        "}\n";
167
        "}\n";
168
 
168
 
169
}
169
}
170
 
170
 
171
namespace GLGraphics
171
namespace GLGraphics
172
{
172
{
173
    IDBufferWireframeRenderer::~IDBufferWireframeRenderer()
173
    IDBufferWireframeRenderer::~IDBufferWireframeRenderer()
174
    {
174
    {
175
        glDeleteShader(vs);	
175
        glDeleteShader(vs);	
176
        glDeleteShader(fs);
176
        glDeleteShader(fs);
177
        glDeleteProgram(line_prog);
177
        glDeleteProgram(line_prog);
178
        glDeleteTextures(1, &idmap);
178
        glDeleteTextures(1, &idmap);
179
        glDeleteBuffers(1, &vertex_buffername);
179
        glDeleteBuffers(1, &vertex_buffername);
180
        glDeleteBuffers(1, &colors_buffername);
180
        glDeleteBuffers(1, &colors_buffername);
181
 
181
 
182
        glDeleteBuffers(1, &line_id_attrib);
182
        glDeleteBuffers(1, &line_id_attrib);
183
        glDeleteBuffers(1, &line_vertex_pos);
183
        glDeleteBuffers(1, &line_vertex_pos);
184
        glDeleteBuffers(1, &line_disp_attrib);			
184
        glDeleteBuffers(1, &line_disp_attrib);			
185
        glDeleteBuffers(1, &line_opp_attrib);
185
        glDeleteBuffers(1, &line_opp_attrib);
186
    }
186
    }
187
 
187
 
188
    IDBufferWireframeRenderer::IDBufferWireframeRenderer(int _XSZ, int _YSZ,
188
    IDBufferWireframeRenderer::IDBufferWireframeRenderer(int _XSZ, int _YSZ,
189
        HMesh::Manifold& _mesh, 
189
        HMesh::Manifold& _mesh, 
190
        float _thickness, 
190
        float _thickness, 
191
        float _transition, 
191
        float _transition, 
192
        int atten_mode): 
192
        int atten_mode): 
193
    mesh(&_mesh), XSZ(_XSZ), YSZ(_YSZ), thickness(_thickness), transition(_transition)
193
    mesh(&_mesh), XSZ(_XSZ), YSZ(_YSZ), thickness(_thickness), transition(_transition)
194
    {
194
    {
195
 
195
 
196
        if(atten_mode == 0 && thickness == 0.0)
196
        if(atten_mode == 0 && thickness == 0.0)
197
        {
197
        {
198
            vs = create_glsl_shader(GL_VERTEX_SHADER, line_vert);
198
            vs = create_glsl_shader(GL_VERTEX_SHADER, line_vert);
199
            fs = create_glsl_shader(GL_FRAGMENT_SHADER, line_frag);
199
            fs = create_glsl_shader(GL_FRAGMENT_SHADER, line_frag);
200
        }
200
        }
201
        else
201
        else
202
        {
202
        {
203
            vs = create_glsl_shader(GL_VERTEX_SHADER, line_vert);
203
            vs = create_glsl_shader(GL_VERTEX_SHADER, line_vert);
204
            fs = create_glsl_shader(GL_FRAGMENT_SHADER, line_atten_frag);
204
            fs = create_glsl_shader(GL_FRAGMENT_SHADER, line_atten_frag);
205
        }
205
        }
206
 
206
 
207
        line_prog = glCreateProgram();
207
        line_prog = glCreateProgram();
208
        glAttachShader(line_prog, vs);
208
        glAttachShader(line_prog, vs);
209
        glAttachShader(line_prog, fs);
209
        glAttachShader(line_prog, fs);
210
        glLinkProgram(line_prog);
210
        glLinkProgram(line_prog);
211
        glUseProgram(line_prog);
211
        glUseProgram(line_prog);
212
 
212
 
213
        glUniform1f(glGetUniformLocation(line_prog,"THICKNESS"), 
213
        glUniform1f(glGetUniformLocation(line_prog,"THICKNESS"), 
214
            thickness);
214
            thickness);
215
        glUniform1f(glGetUniformLocation(line_prog,"TRANSITION"), 
215
        glUniform1f(glGetUniformLocation(line_prog,"TRANSITION"), 
216
            transition);
216
            transition);
217
        glUniform1i(glGetUniformLocation(line_prog,"ATTEN_MODE"),
217
        glUniform1i(glGetUniformLocation(line_prog,"ATTEN_MODE"),
218
            atten_mode);
218
            atten_mode);
219
        glUniform2f(glGetUniformLocation(line_prog,"WIN_SCALE"), 
219
        glUniform2f(glGetUniformLocation(line_prog,"WIN_SCALE"), 
220
            XSZ/2.0, YSZ/2.0);
220
            XSZ/2.0, YSZ/2.0);
221
        glUniform2f(glGetUniformLocation(line_prog,"INV_WIN_SCALE"), 
221
        glUniform2f(glGetUniformLocation(line_prog,"INV_WIN_SCALE"), 
222
            2.0/XSZ, 2.0/YSZ);
222
            2.0/XSZ, 2.0/YSZ);
223
        glUniform1i(glGetUniformLocation(line_prog,"IDMAP"), 0);
223
        glUniform1i(glGetUniformLocation(line_prog,"IDMAP"), 0);
224
 
224
 
225
        id_attrib = glGetAttribLocation(line_prog, "id");
225
        id_attrib = glGetAttribLocation(line_prog, "id");
226
        popp_attrib = glGetAttribLocation(line_prog, "opp_vertex");
226
        popp_attrib = glGetAttribLocation(line_prog, "opp_vertex");
227
        disp_attrib = glGetAttribLocation(line_prog, "displace");
227
        disp_attrib = glGetAttribLocation(line_prog, "displace");
228
        glUseProgram(0);
228
        glUseProgram(0);
229
 
229
 
230
        glGenTextures(1, &idmap);
230
        glGenTextures(1, &idmap);
231
        glBindTexture(GL_TEXTURE_RECTANGLE_ARB, idmap);
231
        glBindTexture(GL_TEXTURE_RECTANGLE_ARB, idmap);
232
        glTexParameteri(GL_TEXTURE_RECTANGLE_ARB,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
232
        glTexParameteri(GL_TEXTURE_RECTANGLE_ARB,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
233
        glTexParameteri(GL_TEXTURE_RECTANGLE_ARB,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
233
        glTexParameteri(GL_TEXTURE_RECTANGLE_ARB,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
234
        glTexParameteri(GL_TEXTURE_RECTANGLE_ARB,GL_TEXTURE_WRAP_S,GL_CLAMP);
234
        glTexParameteri(GL_TEXTURE_RECTANGLE_ARB,GL_TEXTURE_WRAP_S,GL_CLAMP);
235
        glTexParameteri(GL_TEXTURE_RECTANGLE_ARB,GL_TEXTURE_WRAP_T,GL_CLAMP);
235
        glTexParameteri(GL_TEXTURE_RECTANGLE_ARB,GL_TEXTURE_WRAP_T,GL_CLAMP);
236
 
236
 
237
        //create the texture
237
        //create the texture
238
        glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA8, XSZ, YSZ,
238
        glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA8, XSZ, YSZ,
239
            0, GL_RGB, GL_FLOAT, 0);
239
            0, GL_RGB, GL_FLOAT, 0);
240
 
240
 
241
 
241
 
242
        glGenBuffers(1, &vertex_buffername);
242
        glGenBuffers(1, &vertex_buffername);
243
        glGenBuffers(1, &colors_buffername);
243
        glGenBuffers(1, &colors_buffername);
244
 
244
 
245
        glGenBuffers(1, &line_id_attrib);
245
        glGenBuffers(1, &line_id_attrib);
246
        glGenBuffers(1, &line_vertex_pos);
246
        glGenBuffers(1, &line_vertex_pos);
247
        glGenBuffers(1, &line_disp_attrib);
247
        glGenBuffers(1, &line_disp_attrib);
248
        glGenBuffers(1, &line_opp_attrib);
248
        glGenBuffers(1, &line_opp_attrib);
249
 
249
 
250
        triangles = static_cast<int>(mesh->no_faces());
250
        triangles = static_cast<int>(mesh->no_faces());
251
        vector<Vec3f> verts;
251
        vector<Vec3f> verts;
252
        vector<Vec3f> cols;
252
        vector<Vec3f> cols;
253
 
253
 
254
        unsigned int k = 0;
254
        unsigned int k = 0;
255
        for(FaceIDIterator f = mesh->faces_begin(); f != mesh->faces_end(); ++f, ++k){
255
        for(FaceIDIterator f = mesh->faces_begin(); f != mesh->faces_end(); ++f, ++k){
256
            Vec3uc idv(id_get(k));
256
            Vec3uc idv(id_get(k));
257
            Vec3f idvec(idv[0]/255.0, idv[1]/255.0, idv[2]/255.0);
257
            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()){
258
            for(Walker w = mesh->walker(*f); !w.full_circle(); w = w.circulate_face_ccw()){
259
                cols.push_back(idvec);
259
                cols.push_back(idvec);
260
                verts.push_back(Vec3f(mesh->pos(w.vertex())));
260
                verts.push_back(Vec3f(mesh->pos(w.vertex())));
261
            }
261
            }
262
        }
262
        }
263
        glBindBuffer(GL_ARRAY_BUFFER, vertex_buffername);
263
        glBindBuffer(GL_ARRAY_BUFFER, vertex_buffername);
264
        glBufferData(GL_ARRAY_BUFFER, sizeof(float)*3*verts.size(),
264
        glBufferData(GL_ARRAY_BUFFER, sizeof(float)*3*verts.size(),
265
            (float*)&verts[0],GL_STATIC_DRAW);
265
            (float*)&verts[0],GL_STATIC_DRAW);
266
 
266
 
267
 
267
 
268
 
268
 
269
        glBindBuffer(GL_ARRAY_BUFFER, colors_buffername);
269
        glBindBuffer(GL_ARRAY_BUFFER, colors_buffername);
270
        glBufferData(GL_ARRAY_BUFFER, sizeof(float)*3*cols.size(),
270
        glBufferData(GL_ARRAY_BUFFER, sizeof(float)*3*cols.size(),
271
            (float*)&cols[0],GL_STATIC_DRAW);
271
            (float*)&cols[0],GL_STATIC_DRAW);
272
 
272
 
273
 
273
 
274
        vector<Vec3f> line_ids;
274
        vector<Vec3f> line_ids;
275
        vector<Vec3f> vertex_positions;
275
        vector<Vec3f> vertex_positions;
276
        vector<Vec2f> displacements;
276
        vector<Vec2f> displacements;
277
        vector<Vec3f> opposite_positions;
277
        vector<Vec3f> opposite_positions;
278
 
278
 
279
 
279
 
280
        quads = 0;
280
        quads = 0;
281
        unsigned int i = 0;
281
        unsigned int i = 0;
282
        for(FaceIDIterator f = mesh->faces_begin(); f != mesh->faces_end(); ++f,++i){
282
        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()){
283
            for(Walker w = mesh->walker(*f); !w.full_circle(); w = w.circulate_face_ccw()){
284
                ++quads;
284
                ++quads;
285
                Vec3uc idv(id_get(i));
285
                Vec3uc idv(id_get(i));
286
                Vec3f v0(mesh->pos(w.next().vertex()));
286
                Vec3f v0(mesh->pos(w.next().vertex()));
287
                Vec3f v1(mesh->pos(w.next().opp().vertex()));
287
                Vec3f v1(mesh->pos(w.next().opp().vertex()));
288
                Vec3f idvec(idv[0]/255.0, idv[1]/255.0, idv[2]/255.0);
288
                Vec3f idvec(idv[0]/255.0, idv[1]/255.0, idv[2]/255.0);
289
 
289
 
290
                line_ids.push_back(idvec);
290
                line_ids.push_back(idvec);
291
                opposite_positions.push_back(v0);
291
                opposite_positions.push_back(v0);
292
                displacements.push_back(Vec2f(1,-1));
292
                displacements.push_back(Vec2f(1,-1));
293
                vertex_positions.push_back(v1);
293
                vertex_positions.push_back(v1);
294
 
294
 
295
 
295
 
296
                line_ids.push_back(idvec);
296
                line_ids.push_back(idvec);
297
                opposite_positions.push_back(v0);
297
                opposite_positions.push_back(v0);
298
                displacements.push_back(Vec2f(1, 1));
298
                displacements.push_back(Vec2f(1, 1));
299
                vertex_positions.push_back(v1);
299
                vertex_positions.push_back(v1);
300
 
300
 
301
 
301
 
302
                line_ids.push_back(idvec);
302
                line_ids.push_back(idvec);
303
                opposite_positions.push_back(v0);
303
                opposite_positions.push_back(v0);
304
                displacements.push_back(Vec2f(-1,1));
304
                displacements.push_back(Vec2f(-1,1));
305
                vertex_positions.push_back(v1);
305
                vertex_positions.push_back(v1);
306
 
306
 
307
 
307
 
308
                line_ids.push_back(idvec);
308
                line_ids.push_back(idvec);
309
                opposite_positions.push_back(v0);
309
                opposite_positions.push_back(v0);
310
                displacements.push_back(Vec2f(-1,-1));
310
                displacements.push_back(Vec2f(-1,-1));
311
                vertex_positions.push_back(v1);
311
                vertex_positions.push_back(v1);
312
            }
312
            }
313
        }
313
        }
314
 
314
 
315
        glBindBuffer(GL_ARRAY_BUFFER, line_id_attrib);
315
        glBindBuffer(GL_ARRAY_BUFFER, line_id_attrib);
316
 
316
 
317
        glBufferData(GL_ARRAY_BUFFER, sizeof(float)*3*line_ids.size(),
317
        glBufferData(GL_ARRAY_BUFFER, sizeof(float)*3*line_ids.size(),
318
            (float*)&line_ids[0],GL_STATIC_DRAW);
318
            (float*)&line_ids[0],GL_STATIC_DRAW);
319
 
319
 
320
        glBindBuffer(GL_ARRAY_BUFFER, line_opp_attrib);
320
        glBindBuffer(GL_ARRAY_BUFFER, line_opp_attrib);
321
        glBufferData(GL_ARRAY_BUFFER, sizeof(float)*3*opposite_positions.size(),
321
        glBufferData(GL_ARRAY_BUFFER, sizeof(float)*3*opposite_positions.size(),
322
            (float*)&opposite_positions[0],GL_STATIC_DRAW);
322
            (float*)&opposite_positions[0],GL_STATIC_DRAW);
323
 
323
 
324
        glBindBuffer(GL_ARRAY_BUFFER, line_disp_attrib);
324
        glBindBuffer(GL_ARRAY_BUFFER, line_disp_attrib);
325
        glBufferData(GL_ARRAY_BUFFER, sizeof(float)*2*displacements.size(),
325
        glBufferData(GL_ARRAY_BUFFER, sizeof(float)*2*displacements.size(),
326
            (float*)&displacements[0],GL_STATIC_DRAW);
326
            (float*)&displacements[0],GL_STATIC_DRAW);
327
 
327
 
328
        glBindBuffer(GL_ARRAY_BUFFER, line_vertex_pos);
328
        glBindBuffer(GL_ARRAY_BUFFER, line_vertex_pos);
329
        glBufferData(GL_ARRAY_BUFFER, sizeof(float)*3*vertex_positions.size(),
329
        glBufferData(GL_ARRAY_BUFFER, sizeof(float)*3*vertex_positions.size(),
330
            (float*)&vertex_positions[0],GL_STATIC_DRAW);
330
            (float*)&vertex_positions[0],GL_STATIC_DRAW);
331
 
331
 
332
 
332
 
333
 
333
 
334
    }
334
    }
335
 
335
 
336
 
336
 
337
    void IDBufferWireframeRenderer::draw(const Vec3f& color, const Vec3f& clear_color)
337
    void IDBufferWireframeRenderer::draw(const Vec3f& color, const Vec3f& clear_color)
338
    {
338
    {
339
        // push those attributes we change.
339
        // push those attributes we change.
340
        glPushAttrib(GL_COLOR_BUFFER_BIT|
340
        glPushAttrib(GL_COLOR_BUFFER_BIT|
341
            GL_CURRENT_BIT|
341
            GL_CURRENT_BIT|
342
            GL_TRANSFORM_BIT|
342
            GL_TRANSFORM_BIT|
343
            GL_DEPTH_BUFFER_BIT);
343
            GL_DEPTH_BUFFER_BIT);
344
 
344
 
345
        // Store information about whether we use lighting
345
        // Store information about whether we use lighting
346
        GLboolean lights_on;
346
        GLboolean lights_on;
347
        glGetBooleanv(GL_LIGHTING, &lights_on);
347
        glGetBooleanv(GL_LIGHTING, &lights_on);
348
 
348
 
349
        // Store color information
349
        // Store color information
350
        Vec4f current_color;
350
        Vec4f current_color;
351
        glGetFloatv(GL_CURRENT_COLOR, &current_color[0]);
351
        glGetFloatv(GL_CURRENT_COLOR, &current_color[0]);
352
 
352
 
353
        // Store the current draw buffer 
353
        // Store the current draw buffer 
354
        GLint _currentDrawbuf;
354
        GLint _currentDrawbuf;
355
        glGetIntegerv(GL_DRAW_BUFFER, &_currentDrawbuf); 
355
        glGetIntegerv(GL_DRAW_BUFFER, &_currentDrawbuf); 
356
 
356
 
357
        // Enable depth testing
357
        // Enable depth testing
358
        glEnable(GL_DEPTH_TEST);
358
        glEnable(GL_DEPTH_TEST);
359
 
359
 
360
        // ------------------------------
360
        // ------------------------------
361
        // Pass 1: Draw the ID map
361
        // Pass 1: Draw the ID map
362
        // Each polygon has a unique ID which is coded as a colour and drawn
362
        // Each polygon has a unique ID which is coded as a colour and drawn
363
        // into the ID buffer
363
        // into the ID buffer
364
        glDisable(GL_LIGHTING);
364
        glDisable(GL_LIGHTING);
365
        glClearColor(0,0,0,0);
365
        glClearColor(0,0,0,0);
366
        glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
366
        glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
367
 
367
 
368
        glBindBuffer(GL_ARRAY_BUFFER, vertex_buffername);
368
        glBindBuffer(GL_ARRAY_BUFFER, vertex_buffername);
369
        glVertexPointer(3,GL_FLOAT,0,static_cast<char*>(0));
369
        glVertexPointer(3,GL_FLOAT,0,static_cast<char*>(0));
370
        glEnableClientState(GL_VERTEX_ARRAY);
370
        glEnableClientState(GL_VERTEX_ARRAY);
371
 
371
 
372
        glBindBuffer(GL_ARRAY_BUFFER, colors_buffername);
372
        glBindBuffer(GL_ARRAY_BUFFER, colors_buffername);
373
        glColorPointer(3,GL_FLOAT,0,static_cast<char*>(0));
373
        glColorPointer(3,GL_FLOAT,0,static_cast<char*>(0));
374
        glEnableClientState(GL_COLOR_ARRAY);
374
        glEnableClientState(GL_COLOR_ARRAY);
375
 
375
 
376
        int vertex_idx = 0;
376
        int vertex_idx = 0;
377
        for(FaceIDIterator f = mesh->faces_begin(); f != mesh->faces_end(); ++f){
377
        for(FaceIDIterator f = mesh->faces_begin(); f != mesh->faces_end(); ++f){
378
            glBegin(GL_POLYGON);
378
            glBegin(GL_POLYGON);
379
            for(Walker w = mesh->walker(*f); !w.full_circle(); w = w.circulate_face_ccw())
379
            for(Walker w = mesh->walker(*f); !w.full_circle(); w = w.circulate_face_ccw())
380
                 glArrayElement(vertex_idx++);
380
                 glArrayElement(vertex_idx++);
381
            glEnd();
381
            glEnd();
382
        }
382
        }
383
        glFinish();
383
        glFinish();
384
        glDisableClientState(GL_COLOR_ARRAY);
384
        glDisableClientState(GL_COLOR_ARRAY);
385
        glDisableClientState(GL_VERTEX_ARRAY);
385
        glDisableClientState(GL_VERTEX_ARRAY);
386
 
386
 
387
        glBindTexture(GL_TEXTURE_RECTANGLE_ARB, idmap);
387
        glBindTexture(GL_TEXTURE_RECTANGLE_ARB, idmap);
388
        glCopyTexSubImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, 0,0,0,0,XSZ, YSZ);
388
        glCopyTexSubImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, 0,0,0,0,XSZ, YSZ);
389
 
389
 
390
        // Clear color buffer but retain depth buffer.
390
        // Clear color buffer but retain depth buffer.
391
        glClear(GL_COLOR_BUFFER_BIT);
391
        glClear(GL_COLOR_BUFFER_BIT);
392
 
392
 
393
        // Enable blending for all subsequent passes
393
        // Enable blending for all subsequent passes
394
        glEnable(GL_BLEND);
394
        glEnable(GL_BLEND);
395
 
395
 
396
        // ------------------------------
396
        // ------------------------------
397
        // PASS 3: Draw lines using ID map texture.
397
        // PASS 3: Draw lines using ID map texture.
398
        // For each polygon, all edges are drawn as prefiltered
398
        // For each polygon, all edges are drawn as prefiltered
399
        // lines. A given fragment belonging to a line will be written
399
        // lines. A given fragment belonging to a line will be written
400
        // to the framebuffer if either of the following three conditions are met
400
        // 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 
401
        // - its ID matches the contents of the ID  buffer for the corresponding 
402
        // pixel (in the ID buffer)
402
        // pixel (in the ID buffer)
403
        // - The ID of the corresponding pixel is 0 - meaning we are outside.
403
        // - The ID of the corresponding pixel is 0 - meaning we are outside.
404
        // - The depth test is passed.
404
        // - The depth test is passed.
405
        // The final condition ensures that line pixels which are on an interior
405
        // The final condition ensures that line pixels which are on an interior
406
        // contour will be drawn.
406
        // contour will be drawn.
407
        //
407
        //
408
        // If the line fragment is written into the framebuffer - two values are
408
        // 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
409
        // actually written: The colour of the line and an alpha value which
410
        // corresponds to the value of the filter function.
410
        // corresponds to the value of the filter function.
411
        //
411
        //
412
        // During this pass, blending is enabled and the blending equation is set
412
        // 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 
413
        // 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 
414
        // 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
415
        // incoming fragment if the incoming fragment is closer to a line
416
        // than the pixel value.
416
        // than the pixel value.
417
        //
417
        //
418
        // The depth values are not changed during this pass.
418
        // The depth values are not changed during this pass.
419
        glEnable(GL_TEXTURE_RECTANGLE_ARB);
419
        glEnable(GL_TEXTURE_RECTANGLE_ARB);
420
        glBindTexture(GL_TEXTURE_RECTANGLE_ARB, idmap);
420
        glBindTexture(GL_TEXTURE_RECTANGLE_ARB, idmap);
421
        glDepthMask(GL_FALSE);
421
        glDepthMask(GL_FALSE);
422
        glBlendEquation(GL_MAX);
422
        glBlendEquation(GL_MAX);
423
        glUseProgram(line_prog);
423
        glUseProgram(line_prog);
424
        glColor3fv(color.get());
424
        glColor3fv(color.get());
425
        glSecondaryColor3fv(clear_color.get());
425
        glSecondaryColor3fv(clear_color.get());
426
 
426
 
427
        float lw;
427
        float lw;
428
        glGetFloatv(GL_LINE_WIDTH, &lw);
428
        glGetFloatv(GL_LINE_WIDTH, &lw);
429
        glLineWidth(ceil(2.0*(thickness+transition)));
429
        glLineWidth(ceil(2.0*(thickness+transition)));
430
 
430
 
431
 
431
 
432
        glBindBuffer(GL_ARRAY_BUFFER, line_id_attrib);
432
        glBindBuffer(GL_ARRAY_BUFFER, line_id_attrib);
433
        glVertexAttribPointer(id_attrib, 3,GL_FLOAT,GL_FALSE,0,static_cast<char*>(0));
433
        glVertexAttribPointer(id_attrib, 3,GL_FLOAT,GL_FALSE,0,static_cast<char*>(0));
434
        glEnableVertexAttribArray(id_attrib);
434
        glEnableVertexAttribArray(id_attrib);
435
 
435
 
436
 
436
 
437
        glBindBuffer(GL_ARRAY_BUFFER, line_disp_attrib);
437
        glBindBuffer(GL_ARRAY_BUFFER, line_disp_attrib);
438
        glVertexAttribPointer(disp_attrib, 2,GL_FLOAT,GL_FALSE,0,static_cast<char*>(0));
438
        glVertexAttribPointer(disp_attrib, 2,GL_FLOAT,GL_FALSE,0,static_cast<char*>(0));
439
        glEnableVertexAttribArray(disp_attrib);
439
        glEnableVertexAttribArray(disp_attrib);
440
 
440
 
441
 
441
 
442
        glBindBuffer(GL_ARRAY_BUFFER, line_opp_attrib);
442
        glBindBuffer(GL_ARRAY_BUFFER, line_opp_attrib);
443
        glVertexAttribPointer(popp_attrib, 3,GL_FLOAT,GL_FALSE,0,static_cast<char*>(0));
443
        glVertexAttribPointer(popp_attrib, 3,GL_FLOAT,GL_FALSE,0,static_cast<char*>(0));
444
        glEnableVertexAttribArray(popp_attrib);
444
        glEnableVertexAttribArray(popp_attrib);
445
 
445
 
446
 
446
 
447
        glBindBuffer(GL_ARRAY_BUFFER, line_vertex_pos);
447
        glBindBuffer(GL_ARRAY_BUFFER, line_vertex_pos);
448
        glVertexPointer(3,GL_FLOAT,0,static_cast<char*>(0));
448
        glVertexPointer(3,GL_FLOAT,0,static_cast<char*>(0));
449
        glEnableClientState(GL_VERTEX_ARRAY);
449
        glEnableClientState(GL_VERTEX_ARRAY);
450
 
450
 
451
        glDrawArrays(GL_QUADS, 0, quads*4);
451
        glDrawArrays(GL_QUADS, 0, quads*4);
452
 
452
 
453
        glDisableVertexAttribArray(id_attrib);
453
        glDisableVertexAttribArray(id_attrib);
454
        glDisableVertexAttribArray(disp_attrib);
454
        glDisableVertexAttribArray(disp_attrib);
455
        glDisableVertexAttribArray(popp_attrib);
455
        glDisableVertexAttribArray(popp_attrib);
456
        glDisableClientState(GL_VERTEX_ARRAY);
456
        glDisableClientState(GL_VERTEX_ARRAY);
457
 
457
 
458
 
458
 
459
        glLineWidth(lw);
459
        glLineWidth(lw);
460
 
460
 
461
        glUseProgram(0);
461
        glUseProgram(0);
462
        glDisable(GL_TEXTURE_RECTANGLE_ARB);
462
        glDisable(GL_TEXTURE_RECTANGLE_ARB);
463
        glDepthMask(GL_TRUE);
463
        glDepthMask(GL_TRUE);
464
 
464
 
465
        // ------------------------------
465
        // ------------------------------
466
        // Pass 4: Draw with shading
466
        // Pass 4: Draw with shading
467
        // In this pass we draw the shaded model. At this point, the framebuffer
467
        // In this pass we draw the shaded model. At this point, the framebuffer
468
        // contains alpha values and line colours and also depth values.
468
        // contains alpha values and line colours and also depth values.
469
        //
469
        //
470
        // The depth test is set to `equal' and the shaded fragments from the 
470
        // 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 
471
        // filled polygons are combined with the line colours using the alpha 
472
        // values already stored in the frame buffer.
472
        // values already stored in the frame buffer.
473
        //
473
        //
474
        // The framebuffer lines along the contour also need to be blended. 
474
        // The framebuffer lines along the contour also need to be blended. 
475
        // Hence, a screen filling quad is drawn. 
475
        // Hence, a screen filling quad is drawn. 
476
        glDepthFunc(GL_LEQUAL);
476
        glDepthFunc(GL_LEQUAL);
477
        glBlendEquation(GL_FUNC_ADD);
477
        glBlendEquation(GL_FUNC_ADD);
478
        glBlendFuncSeparate(GL_ONE_MINUS_DST_ALPHA, GL_DST_ALPHA, 
478
        glBlendFuncSeparate(GL_ONE_MINUS_DST_ALPHA, GL_DST_ALPHA, 
479
            GL_ZERO, GL_ONE);
479
            GL_ZERO, GL_ONE);
480
        if(lights_on)
480
        if(lights_on)
481
        {
481
        {
482
            glEnable(GL_LIGHTING);
482
            glEnable(GL_LIGHTING);
483
            glEnable(GL_LIGHT0);
483
            glEnable(GL_LIGHT0);
484
        }else
484
        }else
485
            glColor4fv(current_color.get());
485
            glColor4fv(current_color.get());
486
 
486
 
487
        glBindBuffer(GL_ARRAY_BUFFER, vertex_buffername);
487
        glBindBuffer(GL_ARRAY_BUFFER, vertex_buffername);
488
        glVertexPointer(3,GL_FLOAT,0,static_cast<char*>(0));
488
        glVertexPointer(3,GL_FLOAT,0,static_cast<char*>(0));
489
        glEnableClientState(GL_VERTEX_ARRAY);
489
        glEnableClientState(GL_VERTEX_ARRAY);
490
 
490
 
491
        vertex_idx = 0;
491
        vertex_idx = 0;
492
        for(FaceIDIterator f = mesh->faces_begin(); f != mesh->faces_end(); ++f){
492
        for(FaceIDIterator f = mesh->faces_begin(); f != mesh->faces_end(); ++f){
493
			Vec3f n(normal(*mesh, *f));
493
			Vec3f n(normal(*mesh, *f));
494
            glNormal3fv(n.get());
494
            glNormal3fv(n.get());
495
            glBegin(GL_POLYGON);
495
            glBegin(GL_POLYGON);
496
            for(Walker w = mesh->walker(*f); !w.full_circle(); w = w.circulate_face_ccw())
496
            for(Walker w = mesh->walker(*f); !w.full_circle(); w = w.circulate_face_ccw())
497
                 glArrayElement(vertex_idx++);
497
                 glArrayElement(vertex_idx++);
498
            glEnd();
498
            glEnd();
499
        }
499
        }
500
        glDisableClientState(GL_VERTEX_ARRAY);
500
        glDisableClientState(GL_VERTEX_ARRAY);
501
 
501
 
502
 
502
 
503
        glDisable(GL_LIGHTING);
503
        glDisable(GL_LIGHTING);
504
 
504
 
505
 
505
 
506
        double mvmat[16];
506
        double mvmat[16];
507
        glGetDoublev(GL_MODELVIEW_MATRIX, mvmat);
507
        glGetDoublev(GL_MODELVIEW_MATRIX, mvmat);
508
        double prjmat[16];
508
        double prjmat[16];
509
        glGetDoublev(GL_PROJECTION_MATRIX, prjmat);
509
        glGetDoublev(GL_PROJECTION_MATRIX, prjmat);
510
        glMatrixMode(GL_PROJECTION);
510
        glMatrixMode(GL_PROJECTION);
511
        glLoadIdentity();
511
        glLoadIdentity();
512
        glMatrixMode(GL_MODELVIEW);
512
        glMatrixMode(GL_MODELVIEW);
513
        glLoadIdentity();
513
        glLoadIdentity();
514
        glColor3fv(clear_color.get());
514
        glColor3fv(clear_color.get());
515
        glBegin(GL_QUADS);
515
        glBegin(GL_QUADS);
516
        glVertex3f(-1,-1,1);
516
        glVertex3f(-1,-1,1);
517
        glVertex3f( 1,-1,1);
517
        glVertex3f( 1,-1,1);
518
        glVertex3f( 1, 1,1);
518
        glVertex3f( 1, 1,1);
519
        glVertex3f(-1, 1,1);
519
        glVertex3f(-1, 1,1);
520
        glEnd();
520
        glEnd();
521
 
521
 
522
 
522
 
523
 
523
 
524
        glMatrixMode(GL_PROJECTION);
524
        glMatrixMode(GL_PROJECTION);
525
        glLoadMatrixd(prjmat);
525
        glLoadMatrixd(prjmat);
526
        glMatrixMode(GL_MODELVIEW);
526
        glMatrixMode(GL_MODELVIEW);
527
        glLoadMatrixd(mvmat);
527
        glLoadMatrixd(mvmat);
528
 
528
 
529
        glPopAttrib();
529
        glPopAttrib();
530
        if(lights_on)
530
        if(lights_on)
531
            glEnable(GL_LIGHTING);
531
            glEnable(GL_LIGHTING);
532
 
532
 
533
        //			cout << gluErrorString(glGetError()) << endl;
533
        //			cout << gluErrorString(glGetError()) << endl;
534
    }
534
    }
535
}
535
}
536
 
536