drawer.cpp 10.4 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 44 45
	m_shaderL(NULL),
	//m_shaderCL(NULL),
	//m_shader3DCL(NULL),
Sylvain Thery's avatar
Sylvain Thery committed
46
	m_lineMode(lineMode)
47 48 49 50 51 52 53 54 55 56 57
{
	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
58
	m_shaderL = m_shader;
59

60 61
	if (GLSLShader::CURRENT_OGL_VERSION >=3)
	{
Sylvain Thery's avatar
Sylvain Thery committed
62 63 64 65 66 67 68
		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();
69 70
	}

Sylvain Thery's avatar
Sylvain Thery committed
71 72 73 74

	Utils::GLSLShader::registerShader(NULL, m_shader);
	Utils::GLSLShader::registerShader(NULL, m_shaderL);

75 76 77 78 79 80 81 82
	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
83
	Utils::GLSLShader::unregisterShader(NULL, m_shader);
Sylvain Thery's avatar
Sylvain Thery committed
84
	Utils::GLSLShader::unregisterShader(NULL, m_shaderL);
85 86
	delete m_vboPos;
	delete m_vboCol;
Sylvain Thery's avatar
Sylvain Thery committed
87 88 89

	if (m_shaderL != m_shader)
		delete m_shaderL;
90
	delete m_shader;
91 92 93 94 95 96 97 98 99 100 101
}

//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
102 103
	if (m_shaderL != m_shader)
		shaders.push_back(m_shaderL);
Sylvain Thery's avatar
Sylvain Thery committed
104

105
	return shaders;
106 107
}

108
void Drawer::updateMatrices(const glm::mat4& projection, const glm::mat4& modelview)
109
{
110
	m_shader->updateMatrices(projection,modelview);
Sylvain Thery's avatar
Sylvain Thery committed
111 112
	if (m_shaderL != m_shader)
		m_shaderL->updateMatrices(projection,modelview);
113 114
}

115

116 117
void Drawer::lineWidth(float lw)
{
Pierre Kraemer's avatar
merge..  
Pierre Kraemer committed
118
	m_currentWidth = lw;
119 120 121 122
}

void Drawer::pointSize(float ps)
{
123
	m_currentSize = ps;
124 125
}

126
int Drawer::begin(GLenum mode)
127
{
128
	int res = int(m_begins.size());
129

130
	if (mode == GL_POINTS)
131
		m_begins.push_back(PrimParam(uint32(m_dataPos.size()), mode, m_currentSize));
132
	else
133
		m_begins.push_back(PrimParam(uint32(m_dataPos.size()), mode, m_currentWidth));
134

135
	return res;
136 137 138 139
}

void Drawer::end()
{
140
	m_begins.back().nb = uint32(m_dataPos.size() - m_begins.back().begin);
141 142 143 144 145 146 147 148 149 150 151 152 153 154 155
}

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
156
unsigned int Drawer::vertex(const Geom::Vec3f& v)
157 158 159 160
{
	if (m_dataPos.size() == m_dataCol.size())
	{
		if (m_dataCol.empty())
Pierre Kraemer's avatar
merge..  
Pierre Kraemer committed
161
			m_dataCol.push_back(Geom::Vec3f(1.0f, 1.0f, 1.0f));
162 163 164 165
		else
			m_dataCol.push_back( m_dataCol.back());
	}
	m_dataPos.push_back(v);
166
	return  uint32(m_dataPos.size()-1);
167 168
}

Sylvain Thery's avatar
Sylvain Thery committed
169
unsigned int Drawer::vertex3f(float r, float g, float b)
170
{
Sylvain Thery's avatar
Sylvain Thery committed
171
	return vertex(Geom::Vec3f(r,g,b));
172 173 174 175 176 177 178 179 180 181 182 183
}

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

void Drawer::endList()
{
184
	unsigned int nbElts = uint32(m_dataPos.size());
CGoGN GIT Supervisor's avatar
CGoGN GIT Supervisor committed
185 186 187
	
	if (nbElts == 0)
		return;
188 189

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

	m_vboCol->bind();
Pierre Kraemer's avatar
merge..  
Pierre Kraemer committed
193
	glBufferData(GL_ARRAY_BUFFER, nbElts * sizeof(Geom::Vec3f), &(m_dataCol[0]), GL_STREAM_DRAW);
194 195 196 197 198 199 200 201 202 203 204

	// 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
205 206 207 208 209 210 211 212 213 214 215 216 217 218

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


219
void Drawer::callList(float opacity)
220 221 222 223
{
	if (m_begins.empty())
		return;

Sylvain Thery's avatar
Sylvain Thery committed
224 225 226
	m_shader->setOpacity(opacity);
	m_shader->enableVertexAttribs();
	for (std::vector<PrimParam>::iterator pp = m_begins.begin(); pp != m_begins.end(); ++pp)
227
	{
Sylvain Thery's avatar
Sylvain Thery committed
228
		if (pp->mode == GL_POINTS)
229
		{
Sylvain Thery's avatar
Sylvain Thery committed
230 231
			glPointSize(pp->width);
			glDrawArrays(GL_POINTS, pp->begin, pp->nb);
232 233
		}
	}
Sylvain Thery's avatar
Sylvain Thery committed
234 235 236 237 238
	m_shader->disableVertexAttribs();

	m_shaderL->setOpacity(opacity);
	m_shaderL->enableVertexAttribs();
	for (std::vector<PrimParam>::iterator pp = m_begins.begin(); pp != m_begins.end(); ++pp)
239
	{
Sylvain Thery's avatar
Sylvain Thery committed
240
		if (pp->mode != GL_POINTS)
241
		{
Sylvain Thery's avatar
Sylvain Thery committed
242 243
			m_shaderL->setLineWidth(pp->width);
			m_shaderL->bind();
244 245
			glDrawArrays(pp->mode, pp->begin, pp->nb);
		}
246
	}
Sylvain Thery's avatar
Sylvain Thery committed
247
	m_shaderL->disableVertexAttribs();
248 249
}

Sylvain Thery's avatar
Sylvain Thery committed
250

251 252 253 254 255 256
void Drawer::callSubList(int index, float opacity)
{
	if (index >= int(m_begins.size()))
		return;
	PrimParam* pp = & (m_begins[index]);

Sylvain Thery's avatar
Sylvain Thery committed
257
	if (pp->mode == GL_POINTS)
258 259 260
	{
		m_shader->setOpacity(opacity);
		m_shader->enableVertexAttribs();
Sylvain Thery's avatar
Sylvain Thery committed
261
		glPointSize(pp->width);
262 263 264
		glDrawArrays(pp->mode, pp->begin, pp->nb);
		m_shader->disableVertexAttribs();
	}
Sylvain Thery's avatar
Sylvain Thery committed
265 266 267 268 269 270 271 272
	else
	{
		m_shaderL->setOpacity(opacity);
		m_shaderL->setLineWidth(pp->width);
		m_shaderL->enableVertexAttribs();
		glDrawArrays(pp->mode, pp->begin, pp->nb);
		m_shaderL->disableVertexAttribs();
	}
273 274
}

275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 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
//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
317

Sylvain Thery's avatar
Sylvain Thery committed
318 319 320 321 322
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());

323 324 325 326
	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
327 328
	for (std::vector<PrimParam>::iterator pp = m_begins.begin(); pp != m_begins.end(); ++pp)
	{
329
		svg1->setWidth(pp->width);
Sylvain Thery's avatar
Sylvain Thery committed
330 331 332
		if (pp->mode == GL_POINTS)
		{
			unsigned int end = pp->begin + pp->nb;
333
			svg1->beginPoints();
Sylvain Thery's avatar
Sylvain Thery committed
334
			for (unsigned int i=pp->begin; i<end; ++i)
335 336
				svg1->addPoint(ptrP[i], ptrC[i]);
			svg1->endPoints();
Sylvain Thery's avatar
Sylvain Thery committed
337 338
		}

339
		svg2->setWidth(pp->width);
Sylvain Thery's avatar
Sylvain Thery committed
340 341 342
		if (pp->mode == GL_LINES)
		{
			unsigned int end = pp->begin + pp->nb;
343
			svg2->beginLines();
Sylvain Thery's avatar
Sylvain Thery committed
344
			for (unsigned int i=pp->begin; i<end; i+=2)
345 346
				svg2->addLine(ptrP[i], ptrP[i+1], ptrC[i]);
			svg2->endLines();
Sylvain Thery's avatar
Sylvain Thery committed
347 348
		}

349
		svg3->setWidth(pp->width);
Sylvain Thery's avatar
Sylvain Thery committed
350 351 352
		if ((pp->mode == GL_LINE_LOOP) || (pp->mode == GL_POLYGON))
		{
			unsigned int end = pp->begin + pp->nb-1;
353
			svg3->beginLines();
Sylvain Thery's avatar
Sylvain Thery committed
354
			for (unsigned int i=pp->begin; i<=end; ++i)
355 356 357
				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
358 359 360 361
		}
		if (pp->mode == GL_TRIANGLES)
		{
			unsigned int end = pp->begin + pp->nb;
362
			svg3->beginLines();
Sylvain Thery's avatar
Sylvain Thery committed
363 364
			for (unsigned int i=pp->begin; i<end; i+=3)
			{
365 366 367
				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
368
			}
369
			svg3->endLines();
Sylvain Thery's avatar
Sylvain Thery committed
370 371 372 373
		}
		if (pp->mode == GL_QUADS)
		{
			unsigned int end = pp->begin + pp->nb;
374
			svg3->beginLines();
Sylvain Thery's avatar
Sylvain Thery committed
375 376
			for (unsigned int i=pp->begin; i<end; i+=4)
			{
377 378 379 380
				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
381
			}
382
			svg3->endLines();
Sylvain Thery's avatar
Sylvain Thery committed
383 384 385
		}
	}

386 387 388 389
	svg.addGroup(svg1);
	svg.addGroup(svg2);
	svg.addGroup(svg3);

Sylvain Thery's avatar
Sylvain Thery committed
390 391 392 393
	m_vboPos->releasePtr();
	m_vboCol->releasePtr();
}

Pierre Kraemer's avatar
merge..  
Pierre Kraemer committed
394
} // namespace Utils
395

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