38 #include FT_FREETYPE_H 76 GLboolean depth_mask=0;
77 glGetBooleanv(GL_DEPTH_WRITEMASK, &depth_mask);
78 glDepthMask(GL_FALSE);
108 glDepthMask(depth_mask);
113 GLboolean color_mask[4];
114 glGetBooleanv(GL_COLOR_WRITEMASK, color_mask);
115 glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
118 int stencil_front_mask=0;
119 glGetIntegerv(GL_STENCIL_WRITEMASK, &stencil_front_mask);
120 int stencil_back_mask=0;
122 glGetIntegerv(GL_STENCIL_BACK_WRITEMASK, &stencil_back_mask);
132 glColorMask(color_mask[0],color_mask[1],color_mask[2],color_mask[3]);
135 glStencilMask(stencil_front_mask);
137 glStencilMaskSeparate(GL_BACK, stencil_back_mask);
141 glColor4fv( gl_context->
color().
ptr() );
142 glNormal3fv( gl_context->
normal().
ptr() );
149 Log::error(
"Text::renderText() error: no Font assigned to the Text object.\n");
154 if (!
font()->mFT_Face)
156 Log::error(
"Text::renderText() error: invalid FT_Face: probably you tried to load an unsupported font format.\n");
163 if (viewport[2] < 1) viewport[2] = 1;
164 if (viewport[3] < 1) viewport[3] = 1;
170 glMatrixMode(GL_MODELVIEW);
175 glMatrixMode(GL_PROJECTION);
184 glLoadMatrixf(mat.
ptr());
194 bbox.setMaxCorner( bbox.maxCorner() +
vec3(2.0f*applied_margin,2.0f*applied_margin,0) );
202 float texc[] = { 0,0, 0,0, 0,0, 0,0 };
203 VL_glActiveTexture( GL_TEXTURE0 );
204 glEnable(GL_TEXTURE_2D);
205 VL_glClientActiveTexture( GL_TEXTURE0 );
206 glEnableClientState( GL_TEXTURE_COORD_ARRAY );
207 glTexCoordPointer(2, GL_FLOAT, 0, texc);
210 glColor4f( color.
r(), color.
g(), color.
b(), color.
a() );
213 glNormal3f( 0, 0, 1 );
216 glEnableClientState( GL_VERTEX_ARRAY );
217 glVertexPointer(3, GL_FLOAT, 0, vect[0].ptr());
219 FT_Long has_kerning = FT_HAS_KERNING(
font()->mFT_Face );
220 FT_UInt previous = 0;
238 m.
translate( (
float)
int((w-1.0f) / 2.0f), 0, 0);
262 m.
translate( 0, (
float)
int((h-1.0f) / 2.0f), 0);
270 std::vector< String > lines;
271 lines.push_back(
String() );
274 if (
text()[i] ==
'\n')
277 lines.push_back(
String() );
280 lines.back() +=
text()[i];
283 for(
unsigned iline=0; iline<lines.size(); iline++)
292 int just_remained_space = 0;
294 for(
int c=0; c<(int)lines[iline].
length(); c++)
295 if ( lines[iline][c] ==
' ' )
300 just_space = int(rbbox.
width() - linebox.
width()) / space_count;
301 just_remained_space = int(rbbox.
width() - linebox.
width()) % space_count;
310 displace = -
int(rbbox.
width() - linebox.
width());
313 displace = -
int((rbbox.
width() - linebox.
width()) / 2.0f);
318 displace =
int(rbbox.
width() - linebox.
width());
324 displace = +
int((rbbox.
width() - linebox.
width()) / 2.0f);
330 if (iline != 0 && !lines[iline].
length())
332 pen.y() -=
mFont->mHeight;
336 for(
int c=0; c<(int)lines[iline].
length(); c++)
338 if (c == 0 && iline != 0)
340 pen.y() -=
mFont->mHeight;
344 const Glyph* glyph =
mFont->glyph( lines[iline][c] );
351 FT_Vector delta; delta.y = 0;
354 FT_Get_Kerning(
font()->mFT_Face, previous, glyph->
glyphIndex(), FT_KERNING_DEFAULT, &delta );
355 pen.x() += delta.x / 64.0f;
360 FT_Get_Kerning(
font()->mFT_Face, glyph->
glyphIndex(), previous, FT_KERNING_DEFAULT, &delta );
361 pen.x() -= delta.x / 64.0f;
363 pen.y() += delta.y / 64.0f;
371 texc[0] = glyph->
s0();
372 texc[1] = glyph->
t1();
374 texc[2] = glyph->
s1();
375 texc[3] = glyph->
t1();
377 texc[4] = glyph->
s1();
378 texc[5] = glyph->
t0();
380 texc[6] = glyph->
s0();
381 texc[7] = glyph->
t0();
387 vect[0].
x() = pen.x() + glyph->
width()*0 + left -1;
388 vect[0].
y() = pen.y() + glyph->
height()*0 + glyph->
top() - glyph->
height() -1;
390 vect[1].
x() = pen.x() + glyph->
width()*1 + left +1;
391 vect[1].
y() = pen.y() + glyph->
height()*0 + glyph->
top() - glyph->
height() -1;
393 vect[2].
x() = pen.x() + glyph->
width()*1 + left +1;
394 vect[2].
y() = pen.y() + glyph->
height()*1 + glyph->
top() - glyph->
height() +1;
396 vect[3].
x() = pen.x() + glyph->
width()*0 + left -1;
397 vect[3].
y() = pen.y() + glyph->
height()*1 + glyph->
top() - glyph->
height() +1;
402 vect[0].
x() -= glyph->
width()-1 +2;
403 vect[1].
x() -= glyph->
width()-1 +2;
404 vect[2].
x() -= glyph->
width()-1 +2;
405 vect[3].
x() -= glyph->
width()-1 +2;
409 vect[0].
y() -=
mFont->mHeight;
410 vect[1].
y() -=
mFont->mHeight;
411 vect[2].
y() -=
mFont->mHeight;
412 vect[3].
y() -=
mFont->mHeight;
416 vect[0] -= (
fvec3)bbox.minCorner();
417 vect[1] -= (
fvec3)bbox.minCorner();
418 vect[2] -= (
fvec3)bbox.minCorner();
419 vect[3] -= (
fvec3)bbox.minCorner();
423 vect[0].
x() += applied_margin + displace;
424 vect[1].
x() += applied_margin + displace;
425 vect[2].
x() += applied_margin + displace;
426 vect[3].
x() += applied_margin + displace;
428 vect[0].
y() += applied_margin;
429 vect[1].
y() += applied_margin;
430 vect[2].
y() += applied_margin;
431 vect[3].
y() += applied_margin;
435 vect[0].
x() += offset.
x();
436 vect[0].
y() += offset.
y();
437 vect[1].
x() += offset.
x();
438 vect[1].
y() += offset.
y();
439 vect[2].
x() += offset.
x();
440 vect[2].
y() += offset.
y();
441 vect[3].
x() += offset.
x();
442 vect[3].
y() += offset.
y();
445 for(
int i=0; i<4; ++i)
451 vect[i].
x() -= (int)(bbox.width() / 2.0f);
458 vect[i].
x() -= (int)bbox.width();
465 vect[i].
y() -= (int)bbox.height();
472 vect[i].
y() -= int(bbox.height() / 2.0);
477 vect[0] = m * vect[0];
478 vect[1] = m * vect[1];
479 vect[2] = m * vect[2];
480 vect[3] = m * vect[3];
491 v.
x() -= viewport[0];
492 v.
y() -= viewport[1];
494 v.
x() = (float)
int(v.
x());
495 v.
y() = (float)
int(v.
y());
497 vect[0].x() += (float)v.
x();
498 vect[0].y() += (float)v.
y();
499 vect[1].x() += (float)v.
x();
500 vect[1].y() += (float)v.
y();
501 vect[2].x() += (float)v.
x();
502 vect[2].y() += (float)v.
y();
503 vect[3].x() += (float)v.
x();
504 vect[3].y() += (float)v.
y();
510 vect[3].z() = float((v.
z() - 0.5f) / 0.5f);
516 glDisable(GL_TEXTURE_2D);
517 glColor3fv(
vec3(1,0,0).ptr());
518 glDrawArrays(GL_LINE_LOOP, 0, 4);
519 glColor4fv(color.
ptr());
520 glEnable(GL_TEXTURE_2D);
524 if (just_space && lines[iline][c] ==
' ' && iline != lines.size()-1)
528 pen.x() += just_space + (just_remained_space?1:0);
534 pen.x() -= just_space + (just_remained_space?1:0);
537 if(just_remained_space)
538 just_remained_space--;
556 glDisableClientState( GL_VERTEX_ARRAY );
VL_CHECK_OGL();
557 glDisableClientState( GL_TEXTURE_COORD_ARRAY );
VL_CHECK_OGL();
563 glMatrixMode(GL_MODELVIEW);
566 glMatrixMode(GL_PROJECTION);
570 glDisable(GL_TEXTURE_2D);
571 glBindTexture(GL_TEXTURE_2D,0);
581 Log::error(
"Text::rawboundingRect() error: no Font assigned to the Text object.\n");
586 if (!
font()->mFT_Face)
588 Log::error(
"Text::rawboundingRect() error: invalid FT_Face: probably you tried to load an unsupported font format.\n");
596 FT_Long has_kerning = FT_HAS_KERNING(
font()->mFT_Face );
597 FT_UInt previous = 0;
599 for(
int c=0; c<(int)text.
length(); c++)
616 FT_Vector delta; delta.y = 0;
619 FT_Get_Kerning(
font()->mFT_Face, previous, glyph->
glyphIndex(), FT_KERNING_DEFAULT, &delta );
620 pen.
x() += delta.x / 64.0f;
625 FT_Get_Kerning(
font()->mFT_Face, glyph->
glyphIndex(), previous, FT_KERNING_DEFAULT, &delta );
626 pen.
x() -= delta.x / 64.0f;
628 pen.
y() += delta.y / 64.0f;
636 vect[0].
x() = pen.
x() + glyph->
width()*0 + left -1;
639 vect[1].
x() = pen.
x() + glyph->
width()*1 + left +1;
642 vect[2].
x() = pen.
x() + glyph->
width()*1 + left +1;
645 vect[3].
x() = pen.
x() + glyph->
width()*0 + left -1;
651 vect[0].
x() -= glyph->
width()-1 +2;
652 vect[1].
x() -= glyph->
width()-1 +2;
653 vect[2].
x() -= glyph->
width()-1 +2;
654 vect[3].
x() -= glyph->
width()-1 +2;
658 vect[0].
y() -=
mFont->mHeight;
659 vect[1].
y() -=
mFont->mHeight;
660 vect[2].
y() -=
mFont->mHeight;
661 vect[3].
y() -=
mFont->mHeight;
708 if (viewport[2] < 1) viewport[2] = 1;
709 if (viewport[3] < 1) viewport[3] = 1;
713 glMatrixMode(GL_MODELVIEW);
718 glMatrixMode(GL_PROJECTION);
727 glLoadMatrixf(mat.
ptr());
749 glMatrixMode(GL_MODELVIEW);
752 glMatrixMode(GL_PROJECTION);
761 if (viewport[2] < 1) viewport[2] = 1;
762 if (viewport[3] < 1) viewport[3] = 1;
766 glMatrixMode(GL_MODELVIEW);
771 glMatrixMode(GL_PROJECTION);
780 glLoadMatrixf(mat.
ptr());
788 glNormal3f( 0, 0, 1 );
793 glEnableClientState( GL_VERTEX_ARRAY );
794 glVertexPointer(3, GL_FLOAT, 0, vect);
796 glDrawArrays(GL_LINE_LOOP, 0, 4);
798 glDisableClientState( GL_VERTEX_ARRAY );
802 glMatrixMode(GL_MODELVIEW);
805 glMatrixMode(GL_PROJECTION);
835 min.
x() -= int(bbox.
width() / 2.0);
836 max.
x() -= int(bbox.
width() / 2.0);
843 min.
x() -= (int)bbox.
width();
844 max.
x() -= (int)bbox.
width();
859 min.
y() -= int(bbox.
height() / 2.0);
860 max.
y() -= int(bbox.
height() / 2.0);
905 a.
z() = b.
z() = c.
z() = d.
z() = 0;
923 m.
translate( (
float)
int((w-1.0f) / 2.0f), 0, 0);
947 m.
translate( 0, (
float)
int((h-1.0f) / 2.0f), 0);
980 v.
x() -= viewport[0];
981 v.
y() -= viewport[1];
983 v.
x() = (float)
int(v.
x());
984 v.
y() = (float)
int(v.
y());
995 d.
z() = (v.
z() - 0.5f) / 0.5f;
const fvec4 & color() const
Associates a Renderable object to an Effect and Transform.
const T_Scalar & z() const
AABB rawboundingRect(const String &text) const
Matrix4 & rotate(T_Scalar degrees, const Vector3< T_Scalar > &v)
const T_Scalar & e(int i, int j) const
const T_Scalar & x() const
Vector3< float > fvec3
A 3 components vector with float precision.
Transform * transform()
Returns the Transform bound tho an Actor.
bool borderEnabled() const
const fvec2 & shadowVector() const
The String class implements an advanced UTF16 (Unicode BMP) string manipulation engine.
const T_Scalar & z() const
Matrix4 & translate(T_Scalar x, T_Scalar y, T_Scalar z)
const T_Scalar & r() const
bool kerningEnabled() const
Represents an OpenGL context, possibly a widget or a pbuffer, which can also respond to keyboard...
The Glyph associated to a character of a given Font.
static void error(const String &message)
Use this function to provide information about run-time errors: file not found, out of memory...
Vector3< T_Scalar > xyz() const
static Matrix4 getOrtho(float pleft, float pright, float pbottom, float ptop, float pnear, float pfar)
unsigned int textureHandle() const
bool outlineEnabled() const
void setNull()
Sets ths AABB as null, that is, empty.
int viewportAlignment() const
void renderBorder(const Actor *actor, const Camera *camera) const
const fvec3 & normal() const
Viewport * viewport()
The viewport bound to a camera.
const fvec4 & color() const
Visualization Library main namespace.
int length() const
Returns the length of the string.
bool project(const vec4 &in_world, vec4 &out_viewp) const
Projects a vector from world coordinates to viewport coordinates.
Vector2< float > fvec2
A 2 components vector with float precision.
const fvec2 & advance() const
virtual void render_Implementation(const Actor *actor, const Shader *shader, const Camera *camera, OpenGLContext *gl_context) const
const T_Scalar & g() const
The AABB class implements an axis-aligned bounding box using vl::real precision.
real width() const
Returns the width of the AABB computed as max.x - min.x.
const vec3 & maxCorner() const
Returns the corner of the AABB with the maximum x y z coordinates.
float max(float a, float b)
float min(float a, float b)
void setMinCorner(real x, real y, real z)
Sets the corner of the AABB with the minimum x y z coordinates.
bool backgroundEnabled() const
void rotate(float degrees, float x, float y, float z)
void renderText(const Actor *, const Camera *camera, const fvec4 &color, const fvec2 &offset) const
AABB boundingRect() const
Returns the plain 2D bounding box of the text, without taking into consideration the Text's matrix tr...
void setMaxCorner(real x, real y, real z)
Sets the corner of the AABB with the maximum x y z coordinates.
void addPoint(const vec3 &p, real radius)
Updates the AABB to contain the given point.
const T_Scalar & y() const
const T_Scalar & y() const
bool shadowEnabled() const
const T_Scalar & b() const
unsigned int glyphIndex() const
Manages most of the OpenGL rendering states responsible of the final aspect of the rendered objects...
const fvec4 & outlineColor() const
const vec3 & minCorner() const
Returns the corner of the AABB with the minimum x y z coordinates.
void bindVAS(const IVertexAttribSet *vas, bool use_vbo, bool force)
Activates the specified vertex attribute set - For internal use only.
fvec3 vec3
Defined as: 'typedef fvec3 vec3'. See also VL_PIPELINE_PRECISION.
void translate(float x, float y, float z)
fmat4 mat4
Defined as: 'typedef fmat4 mat4'. See also VL_PIPELINE_PRECISION.
const fvec4 & shadowColor() const
const T_Scalar & x() const
The ref<> class is used to reference-count an Object.
const String & text() const
ETextAlign textAlignment() const
const T_Scalar & x() const
const Font * font() const
Represents a virtual camera defining, among other things, the point of view from which scenes can be ...
ETextLayout layout() const
AABB boundingRectTransformed(vec3 &a, vec3 &b, vec3 &c, vec3 &d, const Camera *camera, const Actor *actor=NULL) const
void renderBackground(const Actor *actor, const Camera *camera) const
const T_Scalar & y() const
const T_Scalar & a() const
real height() const
Returns the height of the AABB computed as max.y - min.y.