Création d'un compte pour un collaborateur extérieur au laboratoire depuis l'intranet ICube : https://intranet.icube.unistra.fr/fr/labs/member/profile

drawer.cpp 11 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
30
#include "Utils/Shaders/shaderColorPerVertex.h"

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

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

37
38
39
namespace Utils
{

40
41
42
Drawer::Drawer() :
	m_currentWidth(1.0f),
	m_currentSize(1.0f)
43
44
45
46
47
48
49
50
51
52
53
{
	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);

Pierre Kraemer's avatar
merge..    
Pierre Kraemer committed
54
	Utils::GLSLShader::registerShader(NULL, m_shader);
55

56
57
58
59
60
61
62
63
64
	if (GLSLShader::CURRENT_OGL_VERSION >=3)
	{
		m_shader2 = new Utils::ShaderBoldColorLines();
		m_shader2->setAttributePosition(m_vboPos);
		m_shader2->setAttributeColor(m_vboCol);
		m_shader2->setNoClippingPlane();
		Utils::GLSLShader::registerShader(NULL, m_shader2);
	}

65
66
67
68
69
70
71
72
	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
73
	Utils::GLSLShader::unregisterShader(NULL, m_shader);
74
75
	delete m_vboPos;
	delete m_vboCol;
76
	delete m_shader;
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
	if (m_shader2)
		delete m_shader2;
}

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

std::vector<Utils::GLSLShader*> Drawer::getShaders()
{
	std::vector<Utils::GLSLShader*> shaders;
	shaders.push_back(m_shader);
	if (m_shader2)
		shaders.push_back(m_shader2);
	return shaders;
93
94
}

95
void Drawer::updateMatrices(const glm::mat4& projection, const glm::mat4& modelview)
96
{
97
98
99
	m_shader->updateMatrices(projection,modelview);
	if (m_shader2)
		m_shader2->updateMatrices(projection,modelview);
100
101
}

102

103
104
void Drawer::lineWidth(float lw)
{
Pierre Kraemer's avatar
merge..    
Pierre Kraemer committed
105
	m_currentWidth = lw;
106
107
108
109
}

void Drawer::pointSize(float ps)
{
110
	m_currentSize = ps;
111
112
}

113
int Drawer::begin(GLenum mode)
114
{
115
	int res = int(m_begins.size());
116

117
	if (mode == GL_POINTS)
118
		m_begins.push_back(PrimParam(uint32(m_dataPos.size()), mode, m_currentSize));
119
	else
120
		m_begins.push_back(PrimParam(uint32(m_dataPos.size()), mode, m_currentWidth));
121

122
	return res;
123
124
125
126
}

void Drawer::end()
{
127
	m_begins.back().nb = uint32(m_dataPos.size() - m_begins.back().begin);
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
}

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
143
unsigned int Drawer::vertex(const Geom::Vec3f& v)
144
145
146
147
{
	if (m_dataPos.size() == m_dataCol.size())
	{
		if (m_dataCol.empty())
Pierre Kraemer's avatar
merge..    
Pierre Kraemer committed
148
			m_dataCol.push_back(Geom::Vec3f(1.0f, 1.0f, 1.0f));
149
150
151
152
		else
			m_dataCol.push_back( m_dataCol.back());
	}
	m_dataPos.push_back(v);
153
	return  uint32(m_dataPos.size()-1);
154
155
}

Sylvain Thery's avatar
Sylvain Thery committed
156
unsigned int Drawer::vertex3f(float r, float g, float b)
157
{
Sylvain Thery's avatar
Sylvain Thery committed
158
	return vertex(Geom::Vec3f(r,g,b));
159
160
161
162
163
164
165
166
167
168
169
170
}

void Drawer::newList(GLenum comp)
{
	m_compile = comp;
	m_dataPos.clear();
	m_dataCol.clear();
	m_begins.clear();
}

void Drawer::endList()
{
171
	unsigned int nbElts = uint32(m_dataPos.size());
CGoGN GIT Supervisor's avatar
CGoGN GIT Supervisor committed
172
173
174
	
	if (nbElts == 0)
		return;
175
176

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

	m_vboCol->bind();
Pierre Kraemer's avatar
merge..    
Pierre Kraemer committed
180
	glBufferData(GL_ARRAY_BUFFER, nbElts * sizeof(Geom::Vec3f), &(m_dataCol[0]), GL_STREAM_DRAW);
181
182
183
184
185
186
187
188
189
190
191

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

	if (m_compile != GL_COMPILE)
		callList();
}

Sylvain Thery's avatar
Sylvain Thery committed
192
193
194
195
196
197
198
199
200
201
202
203
204
205

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);
}


206
void Drawer::callList(float opacity)
207
208
209
210
{
	if (m_begins.empty())
		return;

211
212
213
214
215
216
217
218
219
220
221
222
223
	if (GLSLShader::CURRENT_OGL_VERSION >=3)
	{
		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();
Sylvain Thery's avatar
Sylvain Thery committed
224

225
226
227
228
229
230
231
232
233
234
235
236
237
238
		m_shader2->setOpacity(opacity);
		m_shader2->enableVertexAttribs();
		for (std::vector<PrimParam>::iterator pp = m_begins.begin(); pp != m_begins.end(); ++pp)
		{
			if (pp->mode != GL_POINTS)
			{
				m_shader2->setLineWidth(pp->width);
				m_shader2->bind();
				glDrawArrays(pp->mode, pp->begin, pp->nb);
			}
		}
		m_shader2->disableVertexAttribs();
	}
	else
239
	{
240
241
242
243
244
245
246
247
248
249
250
		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);
			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();
251
252
253
	}
}

Sylvain Thery's avatar
Sylvain Thery committed
254

255
256
257
258
259
260
void Drawer::callSubList(int index, float opacity)
{
	if (index >= int(m_begins.size()))
		return;
	PrimParam* pp = & (m_begins[index]);

261
262
263
	if (GLSLShader::CURRENT_OGL_VERSION >=3)
	{
		if (pp->mode == GL_POINTS)
264
		{
265
266
267
			m_shader->setOpacity(opacity);
			m_shader->enableVertexAttribs();
			glPointSize(pp->width);
268
			glDrawArrays(pp->mode, pp->begin, pp->nb);
269
			m_shader->disableVertexAttribs();
270
		}
271
		else
272
		{
273
274
275
			m_shader2->setOpacity(opacity);
			m_shader2->enableVertexAttribs();
			m_shader2->setLineWidth(pp->width);
276
			glDrawArrays(pp->mode, pp->begin, pp->nb);
277
			m_shader2->disableVertexAttribs();
278
		}
279
280
281
282
283
284
285
286
287
288
289
290
	}
	else
	{
		m_shader->setOpacity(opacity);
		m_shader->enableVertexAttribs();
		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();
	}
291
292
}

293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
//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
335

Sylvain Thery's avatar
Sylvain Thery committed
336
337
338
339
340
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());

341
342
343
344
	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
345
346
	for (std::vector<PrimParam>::iterator pp = m_begins.begin(); pp != m_begins.end(); ++pp)
	{
347
		svg1->setWidth(pp->width);
Sylvain Thery's avatar
Sylvain Thery committed
348
349
350
		if (pp->mode == GL_POINTS)
		{
			unsigned int end = pp->begin + pp->nb;
351
			svg1->beginPoints();
Sylvain Thery's avatar
Sylvain Thery committed
352
			for (unsigned int i=pp->begin; i<end; ++i)
353
354
				svg1->addPoint(ptrP[i], ptrC[i]);
			svg1->endPoints();
Sylvain Thery's avatar
Sylvain Thery committed
355
356
		}

357
		svg2->setWidth(pp->width);
Sylvain Thery's avatar
Sylvain Thery committed
358
359
360
		if (pp->mode == GL_LINES)
		{
			unsigned int end = pp->begin + pp->nb;
361
			svg2->beginLines();
Sylvain Thery's avatar
Sylvain Thery committed
362
			for (unsigned int i=pp->begin; i<end; i+=2)
363
364
				svg2->addLine(ptrP[i], ptrP[i+1], ptrC[i]);
			svg2->endLines();
Sylvain Thery's avatar
Sylvain Thery committed
365
366
		}

367
		svg3->setWidth(pp->width);
Sylvain Thery's avatar
Sylvain Thery committed
368
369
370
		if ((pp->mode == GL_LINE_LOOP) || (pp->mode == GL_POLYGON))
		{
			unsigned int end = pp->begin + pp->nb-1;
371
			svg3->beginLines();
Sylvain Thery's avatar
Sylvain Thery committed
372
			for (unsigned int i=pp->begin; i<=end; ++i)
373
374
375
				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
376
377
378
379
		}
		if (pp->mode == GL_TRIANGLES)
		{
			unsigned int end = pp->begin + pp->nb;
380
			svg3->beginLines();
Sylvain Thery's avatar
Sylvain Thery committed
381
382
			for (unsigned int i=pp->begin; i<end; i+=3)
			{
383
384
385
				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
386
			}
387
			svg3->endLines();
Sylvain Thery's avatar
Sylvain Thery committed
388
389
390
391
		}
		if (pp->mode == GL_QUADS)
		{
			unsigned int end = pp->begin + pp->nb;
392
			svg3->beginLines();
Sylvain Thery's avatar
Sylvain Thery committed
393
394
			for (unsigned int i=pp->begin; i<end; i+=4)
			{
395
396
397
398
				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
399
			}
400
			svg3->endLines();
Sylvain Thery's avatar
Sylvain Thery committed
401
402
403
		}
	}

404
405
406
407
	svg.addGroup(svg1);
	svg.addGroup(svg2);
	svg.addGroup(svg3);

Sylvain Thery's avatar
Sylvain Thery committed
408
409
410
411
	m_vboPos->releasePtr();
	m_vboCol->releasePtr();
}

Pierre Kraemer's avatar
merge..    
Pierre Kraemer committed
412
} // namespace Utils
413

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