text3d.cpp 7.75 KB
Newer Older
1
2
3
/*******************************************************************************
* CGoGN: Combinatorial and Geometric modeling with Generic N-dimensional Maps  *
* version 0.1                                                                  *
4
* Copyright (C) 2009-2011, 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.u-strasbg.fr/                                         *
21
22
23
24
25
26
* Contact information: cgogn@unistra.fr                                        *
*                                                                              *
*******************************************************************************/

#include "Utils/text3d.h"

27
28
#include "Utils/vbo.h"

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

32
33
namespace Utils
{
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
#include "text3d.vert"
#include "text3d.frag"

//std::string Strings3D::vertexShaderText =
//"ATTRIBUTE vec4 VertexPosition;\n"
//"uniform mat4 ModelViewMatrix;\n"
//"uniform mat4 ProjectionMatrix;\n"
//"uniform vec3 strPos;\n"
//"uniform float scale;\n"
//"VARYING_VERT vec2 tex_coord;\n"
//"INVARIANT_POS;\n"
//"void main ()\n"
//"{\n"
//"	vec4 pos = ModelViewMatrix * vec4(strPos,1.0) + vec4(VertexPosition[0]*scale,VertexPosition[1]*scale,0.0,0.0);\n"
//"	tex_coord = vec2(VertexPosition[2],VertexPosition[3]);\n"
//"	gl_Position = ProjectionMatrix * pos;\n"
//"}";
//
//
//std::string Strings3D::fragmentShaderText1 =
//"VARYING_FRAG vec2 tex_coord;\n"
//"uniform sampler2D FontTexture;\n"
//"uniform vec3 color;\n"
//"FRAG_OUT_DEF;\n"
//"void main (void)\n"
//"{\n"
//"	float lum = texture2D(FontTexture, tex_coord).s;\n";
61
62
63
64
65

std::string Strings3D::fragmentShaderText2 =
"	gl_FragColor = vec4(color,0.0)*lum;\n"
"}";

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

67
68
69
GLuint Strings3D::m_idTexture = 0xffffffff;
ILuint Strings3D::m_imgName;

Pierre Kraemer's avatar
merge..    
Pierre Kraemer committed
70
71

Strings3D::Strings3D(bool withBackground, const Geom::Vec3f& bgc) : m_nbChars(0)
72
{
73
74
75
76
77
78
79
80
81
82
83
	if (m_idTexture == 0xffffffff)
	{
		std::string font_finename = Utils::GLSLShader::findFile("font_cgogn.png");
		ilInit();
		ilOriginFunc(IL_ORIGIN_UPPER_LEFT);
		ilEnable(IL_ORIGIN_SET);

		ilGenImages(1,&m_imgName);
		ilBindImage(m_imgName);
		ilLoadImage(font_finename.c_str());

Pierre Kraemer's avatar
merge..    
Pierre Kraemer committed
84
		glGenTextures(1, &m_idTexture);
85
86
87
88
89
		glBindTexture(GL_TEXTURE_2D, m_idTexture);
		glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, WIDTHTEXTURE, HEIGHTTEXTURE, 0, GL_LUMINANCE,  GL_UNSIGNED_BYTE, (GLvoid*)(ilGetData()));
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	}
90

91
92
93
94
95
96
97
98
	std::string glxvert(*GLSLShader::DEFINES_GL);
	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
99
		glxfrag.append("if (lum == 0.0) discard;\n");
100
101
102
103
	else if (bgc*bgc > 0.0)
	{
		std::stringstream ss;
		ss << "	if (lum==0.0) gl_FragColor=vec4(";
Pierre Kraemer's avatar
merge..    
Pierre Kraemer committed
104
		ss << bgc[0] << "," << bgc[1] << "," << bgc[2] << ",0.0);\n		else\n";
105
106
107
108
109
110
		background.append(ss.str());
	}
	glxfrag.append(background);
	glxfrag.append(fragmentShaderText2);

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

112
113
114
115
116
117
	m_vbo1 = new Utils::VBO();
	m_vbo1->setDataSize(4);

	bindVA_VBO("VertexPosition", m_vbo1);

	bind();
Pierre Kraemer's avatar
merge..    
Pierre Kraemer committed
118
119
120
121
	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");
122
123
124
	glUniform1f(m_uniform_scale, 1.0f);
	unbind();
}
125
126
127

void Strings3D::setScale(float scale)
{
128
	bind();
129
	glUniform1f(m_uniform_scale, scale);
130
	unbind();
131
132
133
134
}

Strings3D::~Strings3D()
{
Pierre Kraemer's avatar
merge..    
Pierre Kraemer committed
135
	ilDeleteImages(1 ,&m_imgName);
136
	delete m_vbo1;
137
138
139
140
}

unsigned int Strings3D::addString(const std::string& str)
{
Pierre Kraemer's avatar
merge..    
Pierre Kraemer committed
141
	unsigned int id = m_strings.size();
142
143
144
145
146
147
148
	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
149
	unsigned int id = m_strings.size();
150
151
152
153
154
155
156
157
158
159
	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
160
	float x = 0.0f;
161
162
163

	float* buffer = *buffervbo;

Pierre Kraemer's avatar
merge..    
Pierre Kraemer committed
164
	for(unsigned int j = 0; j < nbc; ++j)
165
166
	{
		unsigned int ci = str[j]-32;
Pierre Kraemer's avatar
merge..    
Pierre Kraemer committed
167
168
169
170
		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);
171
172
173
174
175
176

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

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

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

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

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

		x = xf; // + space ?
	}

	*buffervbo = buffer;

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

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

	// alloc buffer
207
	m_vbo1->bind();
Pierre Kraemer's avatar
merge..    
Pierre Kraemer committed
208
209
	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));
210
211

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

221
	glUnmapBuffer(GL_ARRAY_BUFFER);
222
223
224
225
}

void Strings3D::predraw(const Geom::Vec3f& color)
{
226
	bind();
Pierre Kraemer's avatar
merge..    
Pierre Kraemer committed
227
228
	glUniform1i(m_uniform_texture, 0);
	glUniform3fv(m_uniform_color, 1, color.data());
229
230
231
232
233
234
235

	glActiveTextureARB(GL_TEXTURE0_ARB);
	glBindTexture(GL_TEXTURE_2D, m_idTexture);
	glEnable(GL_TEXTURE_2D);

	glDisable(GL_LIGHTING);

236
	enableVertexAttribs();
237
238
239
240
}

void Strings3D::postdraw()
{
241
242
	disableVertexAttribs();
	unbind();
243
244
245
246
247
248
249
250
251
252
253
254
255
}

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

void Strings3D::drawAll(const Geom::Vec3f& color)
{
	predraw(color);
	if (m_strpos.size() != m_strTranslate.size())
	{
256
		CGoGNerr << "Strings3D: for drawAll use exclusively addString with position"<< CGoGNendl;
257
258
259
260
261
262
263
264
265
266
267
268
		return;
	}

	unsigned int nb = m_strpos.size();
	for (unsigned int idSt=0; idSt<nb; ++idSt)
	{
		glUniform3fv(m_uniform_position, 1, m_strTranslate[idSt].data());
		glDrawArrays(GL_QUADS, m_strpos[idSt].first , m_strpos[idSt].second );
	}
	postdraw();
}

Pierre Kraemer's avatar
merge..    
Pierre Kraemer committed
269
} // namespace Utils
270

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