drawer.cpp 12.6 KB
Newer Older
1
2
3
/*******************************************************************************
* CGoGN: Combinatorial and Geometric modeling with Generic N-dimensional Maps  *
* version 0.1                                                                  *
4
* Copyright (C) 2009-2012, IGG Team, LSIIT, University of Strasbourg           *
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
*                                                                              *
* This library is free software; you can redistribute it and/or modify it      *
* under the terms of the GNU Lesser General Public License as published by the *
* Free Software Foundation; either version 2.1 of the License, or (at your     *
* option) any later version.                                                   *
*                                                                              *
* This library is distributed in the hope that it will be useful, but WITHOUT  *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or        *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License  *
* for more details.                                                            *
*                                                                              *
* You should have received a copy of the GNU Lesser General Public License     *
* along with this library; if not, write to the Free Software Foundation,      *
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.           *
*                                                                              *
20
* Web site: http://cgogn.unistra.fr/                                           *
21
22
23
24
* Contact information: cgogn@unistra.fr                                        *
*                                                                              *
*******************************************************************************/

Sylvain Thery's avatar
Sylvain Thery committed
25
#include "GL/glew.h"
Sylvain Thery's avatar
Sylvain Thery committed
26
27

#define CGoGN_UTILS_DLL_EXPORT 1
28
#include "Utils/drawer.h"
29

Thery Sylvain's avatar
Thery Sylvain committed
30
#include "Utils/vbo_base.h"
Sylvain Thery's avatar
Sylvain Thery committed
31
#include "Utils/svg.h"
32
33
34

namespace CGoGN
{
Pierre Kraemer's avatar
merge..    
Pierre Kraemer committed
35

36
37
38
namespace Utils
{

Sylvain Thery's avatar
Sylvain Thery committed
39
	Drawer::Drawer(int lineMode) :
40
	m_currentWidth(1.0f),
Sylvain Thery's avatar
Sylvain Thery committed
41
42
	m_currentSize(1.0f),
	m_shader(NULL),
Sylvain Thery's avatar
Sylvain Thery committed
43
	m_shaderL(NULL),
Sylvain Thery's avatar
Sylvain Thery committed
44
	m_shaderSF(NULL),
Sylvain Thery's avatar
Sylvain Thery committed
45
46
	//m_shaderCL(NULL),
	//m_shader3DCL(NULL),
Sylvain Thery's avatar
Sylvain Thery committed
47
48
	m_lineMode(lineMode),
	m_withShading(false)
49
50
51
52
53
54
55
56
57
58
59
{
	m_vboPos = new Utils::VBO();
	m_vboPos->setDataSize(3);

	m_vboCol = new Utils::VBO();
	m_vboCol->setDataSize(3);

	m_shader = new Utils::ShaderColorPerVertex();
	m_shader->setAttributePosition(m_vboPos);
	m_shader->setAttributeColor(m_vboCol);

Sylvain Thery's avatar
Sylvain Thery committed
60
	m_shaderL = m_shader;
61

62
63
	if (GLSLShader::CURRENT_OGL_VERSION >=3)
	{
Sylvain Thery's avatar
Sylvain Thery committed
64
65
66
67
68
69
70
		if (lineMode == 1)
			m_shaderL = new Utils::ShaderBoldColorLines();
		if (lineMode == 2)
			m_shaderL = new Utils::ShaderBold3DColorLines();
			m_shaderL->setAttributePosition(m_vboPos);
			m_shaderL->setAttributeColor(m_vboCol);
			m_shaderL->setNoClippingPlane();
71
72
	}

Sylvain Thery's avatar
Sylvain Thery committed
73

Sylvain Thery's avatar
Sylvain Thery committed
74
75
76
77
	m_shaderSF = new Utils::ShaderSimpleFlat();
	m_shaderSF->setAttributePosition(m_vboPos);
	m_shaderSF->setAttributeColor(m_vboCol);

Sylvain Thery's avatar
Sylvain Thery committed
78
79
	Utils::GLSLShader::registerShader(NULL, m_shader);
	Utils::GLSLShader::registerShader(NULL, m_shaderL);
Sylvain Thery's avatar
Sylvain Thery committed
80
	Utils::GLSLShader::registerShader(NULL, m_shaderSF);
Sylvain Thery's avatar
Sylvain Thery committed
81

82
83
84
85
86
87
88
89
	m_dataPos.reserve(128);
	m_dataCol.reserve(128);
	m_begins.reserve(16);
//	m_modes.reserve(16);
}

Drawer::~Drawer()
{
Pierre Kraemer's avatar
merge..    
Pierre Kraemer committed
90
	Utils::GLSLShader::unregisterShader(NULL, m_shader);
Sylvain Thery's avatar
Sylvain Thery committed
91
	Utils::GLSLShader::unregisterShader(NULL, m_shaderL);
Sylvain Thery's avatar
Sylvain Thery committed
92
	Utils::GLSLShader::unregisterShader(NULL, m_shaderSF);
93
94
	delete m_vboPos;
	delete m_vboCol;
Sylvain Thery's avatar
Sylvain Thery committed
95
96
97

	if (m_shaderL != m_shader)
		delete m_shaderL;
98
	delete m_shader;
Sylvain Thery's avatar
Sylvain Thery committed
99
	delete m_shaderSF;
100
101
102
103
104
105
106
107
108
109
110
}

//Utils::ShaderColorPerVertex* Drawer::getShader()
//{
//	return m_shader;
//}

std::vector<Utils::GLSLShader*> Drawer::getShaders()
{
	std::vector<Utils::GLSLShader*> shaders;
	shaders.push_back(m_shader);
Sylvain Thery's avatar
Sylvain Thery committed
111
112
	if (m_shaderL != m_shader)
		shaders.push_back(m_shaderL);
Sylvain Thery's avatar
Sylvain Thery committed
113

Sylvain Thery's avatar
Sylvain Thery committed
114
115
	shaders.push_back(m_shaderSF);

116
	return shaders;
117
118
}

119
void Drawer::updateMatrices(const glm::mat4& projection, const glm::mat4& modelview)
120
{
121
	m_shader->updateMatrices(projection,modelview);
Sylvain Thery's avatar
Sylvain Thery committed
122
123
	if (m_shaderL != m_shader)
		m_shaderL->updateMatrices(projection,modelview);
Sylvain Thery's avatar
Sylvain Thery committed
124
125

	m_shaderSF->updateMatrices(projection, modelview);
126
127
}

128

129
130
void Drawer::lineWidth(float lw)
{
Pierre Kraemer's avatar
merge..    
Pierre Kraemer committed
131
	m_currentWidth = lw;
132
133
134
135
}

void Drawer::pointSize(float ps)
{
136
	m_currentSize = ps;
137
138
}

139
int Drawer::begin(GLenum mode)
140
{
141
	int res = int(m_begins.size());
142

143
	if (mode == GL_POINTS)
144
		m_begins.push_back(PrimParam(uint32(m_dataPos.size()), mode, m_currentSize));
145
	else
146
		m_begins.push_back(PrimParam(uint32(m_dataPos.size()), mode, m_currentWidth));
147

148
	return res;
149
150
151
152
}

void Drawer::end()
{
153
	m_begins.back().nb = uint32(m_dataPos.size() - m_begins.back().begin);
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
}

void Drawer::color(const Geom::Vec3f& col)
{
	if (m_dataPos.size() == m_dataCol.size())
		m_dataCol.push_back(col);
	else
		m_dataCol.back() = col;
}

void Drawer::color3f(float r, float g, float b)
{
	color(Geom::Vec3f(r,g,b));
}

Sylvain Thery's avatar
Sylvain Thery committed
169
unsigned int Drawer::vertex(const Geom::Vec3f& v)
170
171
172
173
{
	if (m_dataPos.size() == m_dataCol.size())
	{
		if (m_dataCol.empty())
Pierre Kraemer's avatar
merge..    
Pierre Kraemer committed
174
			m_dataCol.push_back(Geom::Vec3f(1.0f, 1.0f, 1.0f));
175
176
177
178
		else
			m_dataCol.push_back( m_dataCol.back());
	}
	m_dataPos.push_back(v);
179
	return  uint32(m_dataPos.size()-1);
180
181
}

Sylvain Thery's avatar
Sylvain Thery committed
182
unsigned int Drawer::vertex3f(float r, float g, float b)
183
{
Sylvain Thery's avatar
Sylvain Thery committed
184
	return vertex(Geom::Vec3f(r,g,b));
185
186
187
188
189
190
191
192
}

void Drawer::newList(GLenum comp)
{
	m_compile = comp;
	m_dataPos.clear();
	m_dataCol.clear();
	m_begins.clear();
193
194
195
	m_begins_point.clear();
	m_begins_line.clear();
	m_begins_face.clear();
196
197
198
199
}

void Drawer::endList()
{
200
	unsigned int nbElts = uint32(m_dataPos.size());
CGoGN GIT Supervisor's avatar
CGoGN GIT Supervisor committed
201
202
203
	
	if (nbElts == 0)
		return;
204
205

	m_vboPos->bind();
Pierre Kraemer's avatar
merge..    
Pierre Kraemer committed
206
	glBufferData(GL_ARRAY_BUFFER, nbElts * sizeof(Geom::Vec3f), &(m_dataPos[0]), GL_STREAM_DRAW);
207
208

	m_vboCol->bind();
Pierre Kraemer's avatar
merge..    
Pierre Kraemer committed
209
	glBufferData(GL_ARRAY_BUFFER, nbElts * sizeof(Geom::Vec3f), &(m_dataCol[0]), GL_STREAM_DRAW);
210
211
212
213
214
215
216

	// free memory
	std::vector<Geom::Vec3f> tempo;
	tempo.swap(m_dataPos);
	std::vector<Geom::Vec3f> tempo2;
	tempo2.swap(m_dataCol);

Sylvain Thery's avatar
Sylvain Thery committed
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
	for (auto it = m_begins.begin(); it != m_begins.end(); ++it)
	{
		switch (it->mode)
		{
		case GL_POINTS:
			m_begins_point.push_back(*it);
			break;
		case GL_LINES:
		case GL_LINE_STRIP:
		case GL_LINE_LOOP:
			m_begins_line.push_back(*it);
			break;
		default:
			m_begins_face.push_back(*it);
			break;
		}
	}


236
237
238
239
	if (m_compile != GL_COMPILE)
		callList();
}

Sylvain Thery's avatar
Sylvain Thery committed
240
241
242
243
244
245
246
247
248
249
250
251
252
253

void Drawer::updatePositions(unsigned int first, unsigned int nb, const Geom::Vec3f* P)
{
	m_vboPos->bind();
	glBufferSubData(GL_ARRAY_BUFFER, first * sizeof(Geom::Vec3f), nb * sizeof(Geom::Vec3f), P);
}

void Drawer::updatePositions(unsigned int first, unsigned int nb, const float* P)
{
	m_vboPos->bind();
	glBufferSubData(GL_ARRAY_BUFFER, first * 3 * sizeof(float), nb * 3 * sizeof(float), P);
}


254
void Drawer::callList(float opacity)
255
{
Sylvain Thery's avatar
Sylvain Thery committed
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
	//if (m_begins.empty())
	//	return;

	//m_shader->setOpacity(opacity);
	//m_shader->enableVertexAttribs();
	//for (std::vector<PrimParam>::iterator pp = m_begins.begin(); pp != m_begins.end(); ++pp)
	//{
	//	if (pp->mode == GL_POINTS)
	//	{
	//		glPointSize(pp->width);
	//		glDrawArrays(GL_POINTS, pp->begin, pp->nb);
	//	}
	//}
	//m_shader->disableVertexAttribs();

	//m_shaderL->setOpacity(opacity);
	//m_shaderL->enableVertexAttribs();
	//for (std::vector<PrimParam>::iterator pp = m_begins.begin(); pp != m_begins.end(); ++pp)
	//{
	//	if (pp->mode != GL_POINTS)
	//	{
	//		m_shaderL->setLineWidth(pp->width);
	//		m_shaderL->bind();
	//		glDrawArrays(pp->mode, pp->begin, pp->nb);
	//	}
	//}
	//m_shaderL->disableVertexAttribs();

284
285
286
	if (m_begins.empty())
		return;

Sylvain Thery's avatar
Sylvain Thery committed
287
288
289
290
	// rendering lines
	m_shaderL->setOpacity(opacity);
	m_shaderL->enableVertexAttribs();
	for (std::vector<PrimParam>::iterator pp = m_begins_line.begin(); pp != m_begins_line.end(); ++pp)
291
	{
Sylvain Thery's avatar
Sylvain Thery committed
292
293
294
		m_shaderL->setLineWidth(pp->width);
		m_shaderL->bind();
		glDrawArrays(pp->mode, pp->begin, pp->nb);
295
	}
Sylvain Thery's avatar
Sylvain Thery committed
296
	m_shaderL->disableVertexAttribs();
Sylvain Thery's avatar
Sylvain Thery committed
297

Sylvain Thery's avatar
Sylvain Thery committed
298
299
	
	if (m_withShading)
300
	{
Sylvain Thery's avatar
Sylvain Thery committed
301
302
303
		// rendering faces
		m_shaderSF->enableVertexAttribs();
		for (std::vector<PrimParam>::iterator pp = m_begins_face.begin(); pp != m_begins_face.end(); ++pp)
304
305
306
		{
			glDrawArrays(pp->mode, pp->begin, pp->nb);
		}
Sylvain Thery's avatar
Sylvain Thery committed
307
		m_shaderSF->disableVertexAttribs();
308

Sylvain Thery's avatar
Sylvain Thery committed
309
		// rendering points
310
311
		m_shader->setOpacity(opacity);
		m_shader->enableVertexAttribs();
Sylvain Thery's avatar
Sylvain Thery committed
312
313
314
315
316
		for (std::vector<PrimParam>::iterator pp = m_begins_point.begin(); pp != m_begins_point.end(); ++pp)
		{
			glPointSize(pp->width);
			glDrawArrays(pp->mode, pp->begin, pp->nb);
		}
317
318
		m_shader->disableVertexAttribs();
	}
Sylvain Thery's avatar
Sylvain Thery committed
319
320
	else
	{
Sylvain Thery's avatar
Sylvain Thery committed
321
322
323
324
325
326
327
328
329
330
331
332
333
334
		// rendering faces & points
		m_shader->setOpacity(opacity);
		m_shader->enableVertexAttribs();
		for (std::vector<PrimParam>::iterator pp = m_begins_face.begin(); pp != m_begins_face.end(); ++pp)
		{
			glDrawArrays(pp->mode, pp->begin, pp->nb);
		}
		for (std::vector<PrimParam>::iterator pp = m_begins_point.begin(); pp != m_begins_point.end(); ++pp)
		{
			glPointSize(pp->width);
			glDrawArrays(pp->mode, pp->begin, pp->nb);
		}

		m_shader->disableVertexAttribs();
Sylvain Thery's avatar
Sylvain Thery committed
335
	}
336
337
}

Sylvain Thery's avatar
Sylvain Thery committed
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364


//
//void Drawer::callSubList(int index, float opacity)
//{
//	if (index >= int(m_begins.size()))
//		return;
//	PrimParam* pp = & (m_begins[index]);
//
//	if (pp->mode == GL_POINTS)
//	{
//		m_shader->setOpacity(opacity);
//		m_shader->enableVertexAttribs();
//		glPointSize(pp->width);
//		glDrawArrays(pp->mode, pp->begin, pp->nb);
//		m_shader->disableVertexAttribs();
//	}
//	else
//	{
//		m_shaderL->setOpacity(opacity);
//		m_shaderL->setLineWidth(pp->width);
//		m_shaderL->enableVertexAttribs();
//		glDrawArrays(pp->mode, pp->begin, pp->nb);
//		m_shaderL->disableVertexAttribs();
//	}
//}

365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
//void Drawer::callSubLists(int first, int nb, float opacity)
//{
//	m_shader->setOpacity(opacity);
//	m_shader->enableVertexAttribs();

//	int last = first+nb;
//	for (int i = first; i< last; ++i)
//		if (i < int(m_begins.size()))
//		{
//			PrimParam* pp = & (m_begins[i]);

//			if (pp->mode == GL_POINTS)
//				glPointSize(pp->width);
//			if ((pp->mode == GL_LINES) || (pp->mode == GL_LINE_LOOP) || (pp->mode == GL_LINE_STRIP))
//				glLineWidth(pp->width);
//			glDrawArrays(pp->mode, pp->begin, pp->nb);
//		}

//	m_shader->disableVertexAttribs();
//}

//void Drawer::callSubLists(std::vector<int> indices, float opacity)
//{
//	m_shader->setOpacity(opacity);

//	m_shader->enableVertexAttribs();

//	for (std::vector<int>::iterator it = indices.begin(); it != indices.end(); ++it)
//		if (*it < int(m_begins.size()))
//		{
//			PrimParam* pp = & (m_begins[*it]);

//			if (pp->mode == GL_POINTS)
//				glPointSize(pp->width);
//			if ((pp->mode == GL_LINES) || (pp->mode == GL_LINE_LOOP) || (pp->mode == GL_LINE_STRIP))
//				glLineWidth(pp->width);
//			glDrawArrays(pp->mode, pp->begin, pp->nb);
//		}

//	m_shader->disableVertexAttribs();
//}

Sylvain Thery's avatar
Sylvain Thery committed
407

Sylvain Thery's avatar
Sylvain Thery committed
408
409
410
411
412
void Drawer::toSVG(Utils::SVG::SVGOut& svg)
{
	const Geom::Vec3f* ptrP = reinterpret_cast<Geom::Vec3f*>(m_vboPos->lockPtr());
	const Geom::Vec3f* ptrC = reinterpret_cast<Geom::Vec3f*>(m_vboCol->lockPtr());

413
414
415
416
	Utils::SVG::SvgGroup* svg1 = new Utils::SVG::SvgGroup("points", svg.m_model, svg.m_proj);
	Utils::SVG::SvgGroup* svg2 = new Utils::SVG::SvgGroup("lines", svg.m_model, svg.m_proj);
	Utils::SVG::SvgGroup* svg3 = new Utils::SVG::SvgGroup("faces", svg.m_model, svg.m_proj);

Sylvain Thery's avatar
Sylvain Thery committed
417
418
	for (std::vector<PrimParam>::iterator pp = m_begins.begin(); pp != m_begins.end(); ++pp)
	{
419
		svg1->setWidth(pp->width);
Sylvain Thery's avatar
Sylvain Thery committed
420
421
422
		if (pp->mode == GL_POINTS)
		{
			unsigned int end = pp->begin + pp->nb;
423
			svg1->beginPoints();
Sylvain Thery's avatar
Sylvain Thery committed
424
			for (unsigned int i=pp->begin; i<end; ++i)
425
426
				svg1->addPoint(ptrP[i], ptrC[i]);
			svg1->endPoints();
Sylvain Thery's avatar
Sylvain Thery committed
427
428
		}

429
		svg2->setWidth(pp->width);
Sylvain Thery's avatar
Sylvain Thery committed
430
431
432
		if (pp->mode == GL_LINES)
		{
			unsigned int end = pp->begin + pp->nb;
433
			svg2->beginLines();
Sylvain Thery's avatar
Sylvain Thery committed
434
			for (unsigned int i=pp->begin; i<end; i+=2)
435
436
				svg2->addLine(ptrP[i], ptrP[i+1], ptrC[i]);
			svg2->endLines();
Sylvain Thery's avatar
Sylvain Thery committed
437
438
		}

439
		svg3->setWidth(pp->width);
Sylvain Thery's avatar
Sylvain Thery committed
440
441
442
		if ((pp->mode == GL_LINE_LOOP) || (pp->mode == GL_POLYGON))
		{
			unsigned int end = pp->begin + pp->nb-1;
443
			svg3->beginLines();
Sylvain Thery's avatar
Sylvain Thery committed
444
			for (unsigned int i=pp->begin; i<=end; ++i)
445
446
447
				svg3->addLine(ptrP[i], ptrP[i+1], ptrC[i]);
			svg3->addLine(ptrP[end], ptrP[pp->begin], ptrC[end]);
			svg3->endLines();
Sylvain Thery's avatar
Sylvain Thery committed
448
449
450
451
		}
		if (pp->mode == GL_TRIANGLES)
		{
			unsigned int end = pp->begin + pp->nb;
452
			svg3->beginLines();
Sylvain Thery's avatar
Sylvain Thery committed
453
454
			for (unsigned int i=pp->begin; i<end; i+=3)
			{
455
456
457
				svg3->addLine(ptrP[i],   ptrP[i+1], ptrC[i]);
				svg3->addLine(ptrP[i+1], ptrP[i+2], ptrC[i+1]);
				svg3->addLine(ptrP[i+2], ptrP[i],   ptrC[i+2]);
Sylvain Thery's avatar
Sylvain Thery committed
458
			}
459
			svg3->endLines();
Sylvain Thery's avatar
Sylvain Thery committed
460
461
462
463
		}
		if (pp->mode == GL_QUADS)
		{
			unsigned int end = pp->begin + pp->nb;
464
			svg3->beginLines();
Sylvain Thery's avatar
Sylvain Thery committed
465
466
			for (unsigned int i=pp->begin; i<end; i+=4)
			{
467
468
469
470
				svg3->addLine(ptrP[i],   ptrP[i+1], ptrC[i]);
				svg3->addLine(ptrP[i+1], ptrP[i+2], ptrC[i+1]);
				svg3->addLine(ptrP[i+2], ptrP[i+3], ptrC[i+2]);
				svg3->addLine(ptrP[i+3], ptrP[i],   ptrC[i+3]);
Sylvain Thery's avatar
Sylvain Thery committed
471
			}
472
			svg3->endLines();
Sylvain Thery's avatar
Sylvain Thery committed
473
474
475
		}
	}

476
477
478
479
	svg.addGroup(svg1);
	svg.addGroup(svg2);
	svg.addGroup(svg3);

Sylvain Thery's avatar
Sylvain Thery committed
480
481
482
483
	m_vboPos->releasePtr();
	m_vboCol->releasePtr();
}

Pierre Kraemer's avatar
merge..    
Pierre Kraemer committed
484
} // namespace Utils
485

Pierre Kraemer's avatar
merge..    
Pierre Kraemer committed
486
} // namespace CGoGN