Subversion Repositories gelsvn

Rev

Rev 409 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

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