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