topoRender.cpp 8.78 KB
Newer Older
Sylvain Thery's avatar
Sylvain Thery committed
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           *
Sylvain Thery's avatar
Sylvain Thery committed
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/                                           *
Sylvain Thery's avatar
Sylvain Thery committed
21 22 23 24 25
* Contact information: cgogn@unistra.fr                                        *
*                                                                              *
*******************************************************************************/

#include "Algo/Render/GL2/topoRender.h"
26 27 28
#include "Utils/Shaders/shaderSimpleColor.h"
#include "Utils/Shaders/shaderColorPerVertex.h"

Sylvain Thery's avatar
Sylvain Thery committed
29 30 31 32 33 34 35 36 37 38 39 40
namespace CGoGN
{

namespace Algo
{

namespace Render
{

namespace GL2
{

41
TopoRender::TopoRender():
Pierre Kraemer's avatar
Pierre Kraemer committed
42 43 44 45
	m_nbDarts(0),
	m_nbRel2(0),
	m_topo_dart_width(2.0f),
	m_topo_relation_width(3.0f),
46
	m_normalShift(0.0f),
47 48
	m_dartsColor(1.0f,1.0f,1.0f),
	m_bufferDartPosition(NULL)
Sylvain Thery's avatar
Sylvain Thery committed
49
{
50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69
	m_vbo0 = new Utils::VBO();
	m_vbo1 = new Utils::VBO();
	m_vbo2 = new Utils::VBO();
	m_vbo3 = new Utils::VBO();

	m_vbo0->setDataSize(3);
	m_vbo1->setDataSize(3);
	m_vbo2->setDataSize(3);
	m_vbo3->setDataSize(3);

	m_shader1 = new Utils::ShaderSimpleColor();
	m_shader2 = new Utils::ShaderColorPerVertex();

	// binding VBO - VA
	m_vaId = m_shader1->setAttributePosition(m_vbo1);

	m_shader2->setAttributePosition(m_vbo0);
	m_shader2->setAttributeColor(m_vbo3);

	// registering for auto matrices update
Pierre Kraemer's avatar
merge..  
Pierre Kraemer committed
70 71
	Utils::GLSLShader::registerShader(NULL, m_shader1);
	Utils::GLSLShader::registerShader(NULL, m_shader2);
Sylvain Thery's avatar
Sylvain Thery committed
72 73
}

74
TopoRender::~TopoRender()
Sylvain Thery's avatar
Sylvain Thery committed
75
{
Pierre Kraemer's avatar
merge..  
Pierre Kraemer committed
76 77
	Utils::GLSLShader::unregisterShader(NULL, m_shader2);
	Utils::GLSLShader::unregisterShader(NULL, m_shader1);
78 79 80 81 82 83 84 85

	delete m_shader2;
	delete m_shader1;
	delete m_vbo3;
	delete m_vbo2;
	delete m_vbo1;
	delete m_vbo0;

Sylvain Thery's avatar
Sylvain Thery committed
86 87
	if (m_attIndex.map() != NULL)
		static_cast<AttribMap*>(m_attIndex.map())->removeAttribute(m_attIndex);
88 89 90

	if (m_bufferDartPosition!=NULL)
		delete[] m_bufferDartPosition;
Sylvain Thery's avatar
Sylvain Thery committed
91 92
}

93
void TopoRender::setDartWidth(float dw)
Sylvain Thery's avatar
Sylvain Thery committed
94 95 96 97
{
	m_topo_dart_width = dw;
}

98
void TopoRender::setRelationWidth(float pw)
Sylvain Thery's avatar
Sylvain Thery committed
99 100 101 102
{
	m_topo_relation_width = pw;
}

103
void TopoRender::setDartColor(Dart d, float r, float g, float b)
Sylvain Thery's avatar
Sylvain Thery committed
104 105 106 107
{
	float RGB[6];
	RGB[0]=r; RGB[1]=g; RGB[2]=b;
	RGB[3]=r; RGB[4]=g; RGB[5]=b;
108
	m_vbo3->bind();
Sylvain Thery's avatar
Sylvain Thery committed
109 110 111
	glBufferSubData(GL_ARRAY_BUFFER, m_attIndex[d]*3*sizeof(float), 6*sizeof(float),RGB);
}

112
void TopoRender::setAllDartsColor(float r, float g, float b)
Sylvain Thery's avatar
Sylvain Thery committed
113
{
114 115
	m_vbo3->bind();
	GLvoid* ColorDartsBuffer = glMapBuffer(GL_ARRAY_BUFFER, GL_READ_WRITE);
Sylvain Thery's avatar
Sylvain Thery committed
116 117 118 119 120 121 122 123
	float* colorDartBuf = reinterpret_cast<float*>(ColorDartsBuffer);
	for (unsigned int i=0; i < 2*m_nbDarts; ++i)
	{
		*colorDartBuf++ = r;
		*colorDartBuf++ = g;
		*colorDartBuf++ = b;
	}

124 125
	m_vbo3->bind();
	glUnmapBuffer(GL_ARRAY_BUFFER);
Sylvain Thery's avatar
Sylvain Thery committed
126 127
}

128 129 130 131 132
void TopoRender::setInitialDartsColor(float r, float g, float b)
{
	m_dartsColor = Geom::Vec3f(r,g,b);
}

133
void TopoRender::drawDarts()
Sylvain Thery's avatar
Sylvain Thery committed
134
{
135 136 137
	if (m_nbDarts==0)
		return;

138
	m_shader2->enableVertexAttribs();
Sylvain Thery's avatar
Sylvain Thery committed
139

140
	glLineWidth(m_topo_dart_width);
Sylvain Thery's avatar
Sylvain Thery committed
141 142
	glDrawArrays(GL_LINES, 0, m_nbDarts*2);

143 144
	// change the stride to take 1/2 vertices
	m_shader2->enableVertexAttribs(6*sizeof(GL_FLOAT));
Sylvain Thery's avatar
Sylvain Thery committed
145

146
	glPointSize(2.0f*m_topo_dart_width);
Sylvain Thery's avatar
Sylvain Thery committed
147
 	glDrawArrays(GL_POINTS, 0, m_nbDarts);
148 149

 	m_shader2->disableVertexAttribs();
Sylvain Thery's avatar
Sylvain Thery committed
150 151
}

152
void TopoRender::drawRelation1()
Sylvain Thery's avatar
Sylvain Thery committed
153
{
154 155 156
	if (m_nbDarts==0)
		return;

Sylvain Thery's avatar
Sylvain Thery committed
157 158
	glLineWidth(m_topo_relation_width);

159 160 161 162
	m_shader1->changeVA_VBO(m_vaId, m_vbo1);
	m_shader1->setColor(Geom::Vec4f(0.0f,1.0f,1.0f,0.0f));
	m_shader1->enableVertexAttribs();

Sylvain Thery's avatar
Sylvain Thery committed
163
	glDrawArrays(GL_LINES, 0, m_nbDarts*2);
164 165

	m_shader1->disableVertexAttribs();
Sylvain Thery's avatar
Sylvain Thery committed
166 167
}

168
void TopoRender::drawRelation2()
Sylvain Thery's avatar
Sylvain Thery committed
169
{
170 171 172
	if (m_nbRel2==0)
		return;

Sylvain Thery's avatar
Sylvain Thery committed
173 174
	glLineWidth(m_topo_relation_width);

175 176 177 178
	m_shader1->changeVA_VBO(m_vaId, m_vbo2);
	m_shader1->setColor(Geom::Vec4f(1.0f,0.0f,0.0f,0.0f));
	m_shader1->enableVertexAttribs();

179
	glDrawArrays(GL_LINES, 0, m_nbRel2*2);
180 181

	m_shader1->disableVertexAttribs();
Sylvain Thery's avatar
Sylvain Thery committed
182 183
}

184
void TopoRender::drawTopo()
Sylvain Thery's avatar
Sylvain Thery committed
185 186 187 188 189 190
{
	drawDarts();
	drawRelation1();
	drawRelation2();
}

191
void TopoRender::overdrawDart(Dart d, float width, float r, float g, float b)
Sylvain Thery's avatar
Sylvain Thery committed
192
{
Pierre Kraemer's avatar
Pierre Kraemer committed
193
	unsigned int indexDart = m_attIndex[d];
Sylvain Thery's avatar
Sylvain Thery committed
194

195 196 197 198
	m_shader1->changeVA_VBO(m_vaId, m_vbo0);
	m_shader1->setColor(Geom::Vec4f(r,g,b,0.0f));
	m_shader1->enableVertexAttribs();

Sylvain Thery's avatar
Sylvain Thery committed
199
	glLineWidth(width);
200 201
	glDrawArrays(GL_LINES, indexDart, 2);

Sylvain Thery's avatar
Sylvain Thery committed
202
	glPointSize(2.0f*width);
203
 	glDrawArrays(GL_POINTS, indexDart, 1);
Sylvain Thery's avatar
Sylvain Thery committed
204

205 206
 	m_shader2->disableVertexAttribs();
}
Sylvain Thery's avatar
Sylvain Thery committed
207

208 209 210 211 212 213 214 215
Dart TopoRender::colToDart(float* color)
{
	unsigned int r = (unsigned int)(color[0]*255.0f);
	unsigned int g = (unsigned int)(color[1]*255.0f);
	unsigned int b = (unsigned int)(color[2]*255.0f);

	unsigned int id = r + 255*g +255*255*b;

216 217 218
	if (id == 0)
		return NIL;
	return Dart(id-1);
219 220 221

}

222 223 224 225 226 227 228 229 230 231 232 233 234
void TopoRender::dartToCol(Dart d, float& r, float& g, float& b)
{
	// here use d.index beacause it is what we want (and not map.dartIndex(d) !!)
	unsigned int lab = d.index + 1; // add one to avoid picking the black of screen

	r = float(lab%255) / 255.0f; lab = lab/255;
	g = float(lab%255) / 255.0f; lab = lab/255;
	b = float(lab%255) / 255.0f; lab = lab/255;
	if (lab!=0)
		CGoGNerr << "Error picking color, too many darts"<< CGoGNendl;
}


Sylvain Thery's avatar
Sylvain Thery committed
235

Sylvain Thery's avatar
Sylvain Thery committed
236
Dart TopoRender::pickColor(unsigned int x, unsigned int y)
237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252
{
	//more easy picking for
	unsigned int dw = m_topo_dart_width;
	m_topo_dart_width+=2;

	// save clear color and set to zero
	float cc[4];
	glGetFloatv(GL_COLOR_CLEAR_VALUE,cc);

	glClearColor(0.0f,0.0f,0.0f,0.0f);
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	glDisable(GL_LIGHTING);
	// draw in back buffer (not shown on screen)
	drawDarts();

Thomas's avatar
Thomas committed
253
	// restore dart width
254 255 256 257 258 259 260 261 262 263 264 265
	m_topo_dart_width = dw;

	// read the pixel under the mouse in back buffer
	glReadBuffer(GL_BACK);
	float color[3];
	glReadPixels(x,y,1,1,GL_RGB,GL_FLOAT,color);

	glClearColor(cc[0], cc[1], cc[2], cc[3]);

	return colToDart(color);
}

Sylvain Thery's avatar
Sylvain Thery committed
266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286
void TopoRender::pushColors()
{
	m_color_save = new float[6*m_nbDarts];
	m_vbo3->bind();
	void* colorBuffer = glMapBufferARB(GL_ARRAY_BUFFER, GL_READ_WRITE);

	memcpy(m_color_save, colorBuffer, 6*m_nbDarts*sizeof(float));
	glUnmapBuffer(GL_ARRAY_BUFFER);
}

void TopoRender::popColors()
{
	m_vbo3->bind();
	void* colorBuffer = glMapBufferARB(GL_ARRAY_BUFFER, GL_READ_WRITE);

	memcpy(colorBuffer, m_color_save, 6*m_nbDarts*sizeof(float));
	glUnmapBuffer(GL_ARRAY_BUFFER);

	delete[] m_color_save;
	m_color_save=NULL;
}
287

288 289 290
void TopoRender::svgout2D(const std::string& filename, const glm::mat4& model, const glm::mat4& proj)
{
	Utils::SVG::SVGOut svg(filename,model,proj);
Sylvain Thery's avatar
Sylvain Thery committed
291 292
	toSVG(svg);
}
293

Sylvain Thery's avatar
Sylvain Thery committed
294 295
void TopoRender::toSVG(Utils::SVG::SVGOut& svg)
{
296 297 298 299 300 301 302 303
	svg.setWidth(m_topo_relation_width);

	// PHI2 / beta2

	const Geom::Vec3f* ptr = reinterpret_cast<Geom::Vec3f*>(m_vbo2->lockPtr());

	svg.beginLines();
	for (unsigned int i=0; i<m_nbRel2; ++i)
Sylvain Thery's avatar
Sylvain Thery committed
304
		svg.addLine(ptr[2*i], ptr[2*i+1],Geom::Vec3f(0.8f,0.0f,0.0f));
305 306 307 308 309 310 311 312 313
	svg.endLines();

	m_vbo2->releasePtr();

	//PHI1 /beta1
	ptr = reinterpret_cast<Geom::Vec3f*>(m_vbo1->lockPtr());

	svg.beginLines();
	for (unsigned int i=0; i<m_nbRel1; ++i)
Sylvain Thery's avatar
Sylvain Thery committed
314
		svg.addLine(ptr[2*i], ptr[2*i+1],Geom::Vec3f(0.0f,0.7f,0.7f));
315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339
	svg.endLines();

	m_vbo1->releasePtr();


	const Geom::Vec3f* colorsPtr = reinterpret_cast<const Geom::Vec3f*>(m_vbo3->lockPtr());
	ptr= reinterpret_cast<Geom::Vec3f*>(m_vbo0->lockPtr());

	svg.setWidth(m_topo_dart_width);

	svg.beginLines();
	for (unsigned int i=0; i<m_nbDarts; ++i)
		svg.addLine(ptr[2*i], ptr[2*i+1], colorsPtr[2*i]);
	svg.endLines();

	svg.beginPoints();
	for (unsigned int i=0; i<m_nbDarts; ++i)
			svg.addPoint(ptr[2*i], colorsPtr[2*i]);
	svg.endPoints();

	m_vbo0->releasePtr();
	m_vbo3->releasePtr();
}


Sylvain Thery's avatar
Sylvain Thery committed
340

Sylvain Thery's avatar
Sylvain Thery committed
341 342 343 344 345 346 347
}//end namespace GL2

}//end namespace Render

}//end namespace Algo

}//end namespace CGoGN