Coupure prévue mardi 3 Août au matin pour maintenance du serveur. Nous faisons au mieux pour que celle-ci soit la plus brève possible.

text3d.cpp 9.38 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
25
* Contact information: cgogn@unistra.fr                                        *
*                                                                              *
*******************************************************************************/

#include "Utils/text3d.h"
26
#include "Utils/vbo.h"
Sylvain Thery's avatar
Sylvain Thery committed
27
#include "Utils/svg.h"
28

29
30
namespace CGoGN
{
Pierre Kraemer's avatar
merge..  
Pierre Kraemer committed
31

32
33
namespace Utils
{
34
35
36
#include "text3d.vert"
#include "text3d.frag"

37
38

std::string Strings3D::fragmentShaderText2 =
39
"	gl_FragColor = color*lum;\n"
40
41
"}";

Pierre Kraemer's avatar
merge..  
Pierre Kraemer committed
42

43
Strings3D* Strings3D::m_instance0 = NULL;
44

Pierre Kraemer's avatar
merge..  
Pierre Kraemer committed
45

Sylvain's avatar
Sylvain committed
46
Strings3D::Strings3D(bool withBackground, const Geom::Vec3f& bgc, bool with_plane) : m_nbChars(0),m_scale(1.0f)
47
{
48
	if (m_instance0 == NULL)
49
	{
50
		m_instance0 = this;
Sylvain Thery's avatar
Sylvain Thery committed
51
		std::string font_filename = Utils::GLSLShader::findFile("font_cgogn.gz");
52
53
54
55
		igzstream fs(font_filename.c_str(), std::ios::in|std::ios::binary);
		char* buff = new char[WIDTHTEXTURE*HEIGHTTEXTURE];
		fs.read(reinterpret_cast<char*>(buff), WIDTHTEXTURE*HEIGHTTEXTURE );
		fs.close();
Sylvain Thery's avatar
Sylvain Thery committed
56
		
57
58
		glGenTextures(1, &(*m_idTexture));
		glBindTexture(GL_TEXTURE_2D, *m_idTexture);
59
		glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, WIDTHTEXTURE, HEIGHTTEXTURE, 0, GL_LUMINANCE,  GL_UNSIGNED_BYTE, (GLvoid*)(buff));
60
61
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
62
		delete[] buff;
63
	}
64
65
	else
	{
Sylvain's avatar
Sylvain committed
66
		*m_idTexture = *(m_instance0->m_idTexture);
67
	}
68

69
	std::string glxvert(*GLSLShader::DEFINES_GL);
Sylvain's avatar
Sylvain committed
70
	if (with_plane)
Sylvain Thery's avatar
Sylvain Thery committed
71
		glxvert.append("#define WITH_PLANE 1");
72
73
74
75
76
77
78
	glxvert.append(vertexShaderText);
	std::string glxfrag(*GLSLShader::DEFINES_GL);

	glxfrag.append(fragmentShaderText1);

	std::string background;
	if (!withBackground)
Pierre Kraemer's avatar
merge..  
Pierre Kraemer committed
79
		glxfrag.append("if (lum == 0.0) discard;\n");
80
81
82
83
	else if (bgc*bgc > 0.0)
	{
		std::stringstream ss;
		ss << "	if (lum==0.0) gl_FragColor=vec4(";
84
		ss << bgc[0] << "," << bgc[1] << "," << bgc[2] << ",color[3]);\n		else\n";
85
86
87
88
89
90
		background.append(ss.str());
	}
	glxfrag.append(background);
	glxfrag.append(fragmentShaderText2);

	loadShadersFromMemory(glxvert.c_str(), glxfrag.c_str());
91

92
93
94
95
96
97
	m_vbo1 = new Utils::VBO();
	m_vbo1->setDataSize(4);

	bindVA_VBO("VertexPosition", m_vbo1);

	bind();
98
99
100
101
102
	*m_uniform_position = glGetUniformLocation(program_handler(), "strPos");
	*m_uniform_color = glGetUniformLocation(program_handler(), "color");
	*m_uniform_scale = glGetUniformLocation(program_handler(), "scale");
	*m_uniform_texture = glGetUniformLocation(program_handler(), "FontTexture");
	glUniform1f(*m_uniform_scale, 1.0f);
Sylvain's avatar
Sylvain committed
103
104
105
106
107
	if (with_plane)
	{
		*m_uniform_planeX = glGetUniformLocation(program_handler(), "planeX");
		*m_uniform_planeY = glGetUniformLocation(program_handler(), "planeY");
	}
108
	unbind();
Sylvain Thery's avatar
Sylvain Thery committed
109
110

	m_color = Geom::Vec4f(0.0f,0.0f,0.0f,1.0f);
111
}
112
113
114

void Strings3D::setScale(float scale)
{
115
	bind();
116
	glUniform1f(*m_uniform_scale, scale);
Sylvain Thery's avatar
Sylvain Thery committed
117
	m_scale = scale;
118
	unbind();
119
120
}

Sylvain Thery's avatar
Sylvain Thery committed
121
void Strings3D::setPlane(const Geom::Vec3f& ox, const Geom::Vec3f& oy)
Sylvain's avatar
Sylvain committed
122
123
{
	bind();
Sylvain Thery's avatar
Sylvain Thery committed
124
125
	glUniform3fv(*m_uniform_planeX, 1, ox.data());
	glUniform3fv(*m_uniform_planeY, 1, oy.data());
Sylvain's avatar
Sylvain committed
126
127
128
	unbind();
}

129
130
131
132
Strings3D::~Strings3D()
{
}

Sylvain Thery's avatar
Sylvain Thery committed
133
134
135
136
137
138
139
140
void Strings3D::clear()
{
	m_nbChars=0;
	m_strings.clear();
	m_strTranslate.clear();
	m_strpos.clear();
}

141
142
unsigned int Strings3D::addString(const std::string& str)
{
Pierre Kraemer's avatar
merge..  
Pierre Kraemer committed
143
	unsigned int id = m_strings.size();
144
145
146
147
148
149
150
	m_strings.push_back(str);
	m_nbChars += str.length();
	return id;
}

unsigned int Strings3D::addString(const std::string& str, const Geom::Vec3f& pos)
{
Pierre Kraemer's avatar
merge..  
Pierre Kraemer committed
151
	unsigned int id = m_strings.size();
152
153
154
155
156
157
158
159
160
161
	m_strings.push_back(str);
	m_nbChars += str.length();
	m_strTranslate.push_back(pos);
	return id;
}

unsigned int Strings3D::sendOneStringToVBO(const std::string& str, float **buffervbo)
{
	unsigned int nbc = str.length();

Pierre Kraemer's avatar
merge..  
Pierre Kraemer committed
162
	float x = 0.0f;
163
164
165

	float* buffer = *buffervbo;

Pierre Kraemer's avatar
merge..  
Pierre Kraemer committed
166
	for(unsigned int j = 0; j < nbc; ++j)
167
168
	{
		unsigned int ci = str[j]-32;
Pierre Kraemer's avatar
merge..  
Pierre Kraemer committed
169
170
171
172
		float u  = float(ci % CHARSPERLINE) / float(CHARSPERLINE);
		float v  = float(ci / CHARSPERLINE) / float(CHARSPERCOL) + 1.0f / HEIGHTTEXTURE;
		float u2 = u + float(REALWIDTHFONT) / float(WIDTHTEXTURE);
		float v2 = v + float(WIDTHFONT - 1) / float(HEIGHTTEXTURE);
173
174
175
176
177
178

		*buffer++ = x;
		*buffer++ = 0;
		*buffer++ = u;
		*buffer++ = v2;

Pierre Kraemer's avatar
merge..  
Pierre Kraemer committed
179
		float xf = x + float(REALWIDTHFONT) / 25.f;
180
181
182
183
184
185
186

		*buffer++ = xf;
		*buffer++ = 0;
		*buffer++ = u2;
		*buffer++ = v2;

		*buffer++ = xf;
Pierre Kraemer's avatar
merge..  
Pierre Kraemer committed
187
		*buffer++ = float(WIDTHFONT) / 25.f;
188
189
190
191
		*buffer++ = u2;
		*buffer++ = v;

		*buffer++ = x;
Pierre Kraemer's avatar
merge..  
Pierre Kraemer committed
192
		*buffer++ = float(WIDTHFONT) / 25.f;
193
194
195
196
197
198
199
200
		*buffer++ = u;
		*buffer++ = v;

		x = xf; // + space ?
	}

	*buffervbo = buffer;

Pierre Kraemer's avatar
merge..  
Pierre Kraemer committed
201
	return 4 * nbc;
202
203
204
205
206
207
208
}

void Strings3D::sendToVBO()
{
	// send coord / texcoord of strings

	// alloc buffer
209
	m_vbo1->bind();
Pierre Kraemer's avatar
merge..  
Pierre Kraemer committed
210
211
	glBufferData(GL_ARRAY_BUFFER, m_nbChars * 16 * sizeof(float), 0, GL_STREAM_DRAW);
	float* buffer = reinterpret_cast<float*>(glMapBuffer(GL_ARRAY_BUFFER, GL_READ_WRITE));
212
213

	// fill buffer
Pierre Kraemer's avatar
merge..  
Pierre Kraemer committed
214
	unsigned int pos = 0; // pos of first index in vbo for current string
215
	unsigned int nbw = m_strings.size();
Pierre Kraemer's avatar
merge..  
Pierre Kraemer committed
216
	for (unsigned int i = 0; i < nbw; ++i)
217
218
	{
		unsigned int nb = sendOneStringToVBO(m_strings[i], &buffer);
Pierre Kraemer's avatar
merge..  
Pierre Kraemer committed
219
		m_strpos.push_back(std::pair<unsigned int, unsigned int>(pos, nb));
220
221
222
		pos += nb;
	}

223
	glUnmapBuffer(GL_ARRAY_BUFFER);
224
225
}

226
void Strings3D::predraw(const Geom::Vec4f& color)
227
{
228
	m_color = color;
229
	bind();
230
	glUniform1i(*m_uniform_texture, 0);
231
	glUniform4fv(*m_uniform_color, 1, color.data());
232
233

	glActiveTextureARB(GL_TEXTURE0_ARB);
234
	glBindTexture(GL_TEXTURE_2D, *m_idTexture);
235
236
237
238
	glEnable(GL_TEXTURE_2D);

	glDisable(GL_LIGHTING);

239
	enableVertexAttribs();
240
241
}

242
void Strings3D::changeColor(const Geom::Vec4f& color)
243
{
244
	m_color = color;
245
	bind();
246
247
248
249
250
251
252
253
	glUniform4fv(*m_uniform_color, 1, color.data());
}

void Strings3D::changeOpacity(float op)
{
	m_color[3] = op;
	bind();
	glUniform4fv(*m_uniform_color, 1, m_color.data());
254
255
}

256
257
void Strings3D::postdraw()
{
258
259
	disableVertexAttribs();
	unbind();
260
261
262
263
}

void Strings3D::draw(unsigned int idSt, const Geom::Vec3f& pos)
{
264
	glUniform3fv(*m_uniform_position, 1, pos.data());
265
266
267
	glDrawArrays(GL_QUADS, m_strpos[idSt].first , m_strpos[idSt].second );
}

268
void Strings3D::drawAll(const Geom::Vec4f& color)
269
{
270
	m_color = color;
Sylvain's avatar
Sylvain committed
271
272
273
274
275
	unsigned int nb = m_strpos.size();
	//  nothing to do if no string !
	if (nb == 0)
		return;

276
277
278
	predraw(color);
	if (m_strpos.size() != m_strTranslate.size())
	{
279
		CGoGNerr << "Strings3D: for drawAll use exclusively addString with position"<< CGoGNendl;
280
281
		return;
	}
Sylvain's avatar
Sylvain committed
282
		
283
284
	for (unsigned int idSt=0; idSt<nb; ++idSt)
	{
285
		glUniform3fv(*m_uniform_position, 1, m_strTranslate[idSt].data());
286
287
288
289
290
		glDrawArrays(GL_QUADS, m_strpos[idSt].first , m_strpos[idSt].second );
	}
	postdraw();
}

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
335
336
337
338
339
340
void Strings3D::updateString(unsigned int idSt, const std::string& str)
{
	unsigned int firstIndex = m_strpos[idSt].first;
	unsigned int nbIndices = m_strpos[idSt].second;

	unsigned int nbc = std::min((unsigned int)(str.length()), nbIndices/4);


	m_vbo1->bind();
	float* buffer = reinterpret_cast<float*>(glMapBuffer(GL_ARRAY_BUFFER, GL_READ_WRITE));

	buffer += firstIndex*4;
	float x = 0.0f;
	for(unsigned int j = 0; j < nbc; ++j)
	{
		unsigned int ci = str[j]-32;
		float u  = float(ci % CHARSPERLINE) / float(CHARSPERLINE);
		float v  = float(ci / CHARSPERLINE) / float(CHARSPERCOL) + 1.0f / HEIGHTTEXTURE;
		float u2 = u + float(REALWIDTHFONT) / float(WIDTHTEXTURE);
		float v2 = v + float(WIDTHFONT - 1) / float(HEIGHTTEXTURE);

		*buffer++ = x;
		*buffer++ = 0;
		*buffer++ = u;
		*buffer++ = v2;

		float xf = x + float(REALWIDTHFONT) / 25.f;

		*buffer++ = xf;
		*buffer++ = 0;
		*buffer++ = u2;
		*buffer++ = v2;

		*buffer++ = xf;
		*buffer++ = float(WIDTHFONT) / 25.f;
		*buffer++ = u2;
		*buffer++ = v;

		*buffer++ = x;
		*buffer++ = float(WIDTHFONT) / 25.f;
		*buffer++ = u;
		*buffer++ = v;

		x = xf; // + space ?
	}
	glUnmapBuffer(GL_ARRAY_BUFFER);
}



Sylvain Thery's avatar
Sylvain Thery committed
341
342
343
344
345
346
347
348
349
void Strings3D::toSVG(Utils::SVG::SVGOut& svg)
{
	svg.beginStrings(m_scale);
	unsigned int nb = m_strings.size();
	for(unsigned int i=0; i<nb; ++i)
		svg.addString(m_strTranslate[i],m_strings[i]);
	svg.endStrings();
}

Pierre Kraemer's avatar
merge..  
Pierre Kraemer committed
350
} // namespace Utils
351

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