00001
00002 #include "TextNode.h"
00003 #include "Stateset.h"
00004 #include "Sampler.h"
00005 #include "Program.h"
00006 #include "Rendergroup.h"
00007 #include "PropertyProxy.h"
00008 #include "Error.h"
00009
00010 namespace RenderTools {
00011
00012 using namespace Matrix;
00013
00015
00016 #ifdef RT_FTGL
00017 FTFont * TextNode::s_font = 0;
00018 string TextNode::s_fontname = "Arial.ttf";
00019 #elif RT_GLUT
00020 void * TextNode::s_font = 0;
00021 string TextNode::s_fontname = "GLUT_STROKE_ROMAN";
00022 #endif
00023
00024 TextNode::TextNode( void ):
00025 Rendernode(){
00026
00027 }
00028
00029 TextNode::~TextNode( void ){
00030
00031 }
00032
00033 PropertyPtr TextNode::create( const XMLNodePtr & xml ){
00034 TextNodePtr p( new TextNode() );
00035 p->setName( xml );
00036 p->createProperties();
00037 p->setProperties( xml, false );
00038 return( dynamic_pointer_cast< AbstractProperty, TextNode >( p ) );
00039 }
00040
00041 void TextNode::createProperties( void ){
00042 Rendernode::createProperties();
00043 createProperty( this, "text", & m_text );
00044 }
00045
00046 const string TextNode::getTypeName( bool ofComponent ) const {
00047 return( "TextNode" );
00048 }
00049
00050 void TextNode::onInitialize( void ){
00051 Rendernode::onInitialize();
00052
00053 loadFont();
00054
00055 #ifdef RT_FTGL
00056 setFontSize( 8 );
00057 #endif
00058 }
00059
00060 void TextNode::loadFont( void ){
00061 #ifdef RT_FTGL
00062 s_font = new FTGLPolygonFont( findFile( s_fontname, true ).c_str() );
00063
00064 s_font->FaceSize( 30 );
00065 #elif RT_GLUT
00066 if( s_fontname == "GLUT_BITMAP_9_BY_15" ){
00067 s_font = GLUT_BITMAP_9_BY_15;
00068 }
00069 else if( s_fontname == "GLUT_BITMAP_8_BY_13" ){
00070 s_font = GLUT_BITMAP_8_BY_13;
00071 }
00072 else if( s_fontname == "GLUT_BITMAP_TIMES_ROMAN_10" ){
00073 s_font = GLUT_BITMAP_TIMES_ROMAN_10;
00074 }
00075 else if( s_fontname == "GLUT_BITMAP_TIMES_ROMAN_24" ){
00076 s_font = GLUT_BITMAP_TIMES_ROMAN_24;
00077 }
00078 else if( s_fontname == "GLUT_STROKE_ROMAN" ){
00079 s_font = GLUT_STROKE_ROMAN;
00080 }
00081 else if( s_fontname == "GLUT_STROKE_MONO_ROMAN" ){
00082 s_font = GLUT_STROKE_MONO_ROMAN;
00083 }
00084 # if (GLUT_API_VERSION >= 3)
00085 else if( s_fontname == "GLUT_BITMAP_HELVETICA_10" ){
00086 s_font = GLUT_BITMAP_HELVETICA_10;
00087 }
00088 else if( s_fontname == "GLUT_BITMAP_HELVETICA_12" ){
00089 s_font = GLUT_BITMAP_HELVETICA_12;
00090 }
00091 else if( s_fontname == "GLUT_BITMAP_HELVETICA_18" ){
00092 s_font = GLUT_BITMAP_HELVETICA_18;
00093 }
00094 # endif
00095 #endif
00096 }
00097
00098 void TextNode::setText( const string text ){
00099 m_text = text;
00100 }
00101
00102 const string & TextNode::getText( void ) const {
00103 return( m_text );
00104 }
00105
00106 void TextNode::setFontSize( int height ){
00107 #ifdef RT_FTGL
00108 if( ! s_font ){
00109 Error::error( Error::NULL_POINTER, __FILE__, __LINE__, "TextNode:: requires that you call ::loadFont first!" );
00110 return;
00111 }
00112 s_font->FaceSize( height );
00113 #elif RT_GLUT
00114 Error::warning( Error::WRONG_TYPE, __FILE__, __LINE__, "TextNode:: in GLut, fontsize is set with the font name" );
00115 #endif
00116 }
00117
00118 void TextNode::onRender( void ){
00119
00120
00121
00122
00123
00124
00125
00126 #if defined(RT_FTGL) || defined(RT_GLUT)
00127 if( ! s_font ){
00128 Error::error( Error::NULL_POINTER, __FILE__, __LINE__, "TextNode:: requires that you call ::loadFont first!" );
00129 return;
00130 }
00131 #endif
00132
00133 push( MODELVIEW, get( MODELVIEW ) * getLocal() );
00134 #ifndef RT_AS3
00135 # ifndef RT_GLES1
00136 m_program->bind();
00137 # endif
00138 m_stateset->bind();
00139 #endif
00140
00141 #ifdef RT_FTGL
00142 glColor3fv( * m_color );
00143 s_font->Render( m_text.c_str() );
00144 #elif RT_GLUT
00145 glColor3fv( * m_color );
00146 const char * text = m_text.c_str();
00147 unsigned int len = m_text.size();
00148
00149 if( s_font == GLUT_STROKE_ROMAN || s_font == GLUT_STROKE_MONO_ROMAN ){
00150 for( unsigned int i = 0; i < len; i++ ){
00151 glutStrokeCharacter( s_font, (int)text[ i ] );
00152 }
00153 }
00154 else{
00156
00158 GLint vp[4];
00159 glGetIntegerv( GL_VIEWPORT, vp );
00160
00162
00164 Vec3 view = project( getLocal().translation(), Vec4( (float)vp[0], (float)vp[1], (float)vp[2], (float)vp[3] ) );
00165
00166 Matrix::push( Matrix::PROJECTION, Mat4::fromIdentity() );
00167 Matrix::push( Matrix::MODELVIEW, Mat4::fromIdentity() );
00168
00169 glRasterPos2f( view[ 0 ] / (float)vp[ 2 ], view[ 1 ] / (float)vp[ 3 ] );
00170 for( unsigned int i = 0; i < len; i++ ){
00171 glutBitmapCharacter( s_font, (int)text[ i ] );
00172 }
00173 Matrix::pop( Matrix::PROJECTION );
00174 Matrix::pop( Matrix::MODELVIEW );
00175 }
00176 #endif
00177 Matrix::pop( Matrix::MODELVIEW );
00178 }
00179
00180 NAABB TextNode::getBounds( void ) const {
00181 float lx,ly,lz,ux,uy,uz;
00182 lx = 0.0f; ly = 0.0f; lz = 0.0f; ux = 0.0f; uy = 0.0f; uz = 0.0f;
00183 #ifdef RT_FTGL
00184 if( ! s_font ){
00185 Error::error( Error::NULL_POINTER, __FILE__, __LINE__, "TextNode:: requires that you call ::loadFont first!" );
00186 return( NAABB() );
00187 }
00188
00189 s_font->BBox( ( const char * )( m_text.c_str() ), lx, ly, lz, ux, uy, uz );
00190 FTBBox box( lx, ly, lz, ux, uy, uz );
00191
00192 # if _DEBUG
00193 FTPoint lower = FTPoint( box.lowerX, box.lowerY, box.lowerZ );
00194 FTPoint upper = FTPoint( box.upperX, box.upperY, box.upperZ );
00195 lx = lower.X(); ly = lower.Y();
00196 ux = upper.X(); uy = upper.Y();
00197 # endif
00198
00199 #elif RT_GLUT
00200 unsigned int len = m_text.size();
00201
00202 int w = 0;
00203 int h = 0;
00204 if( s_font == GLUT_STROKE_ROMAN || s_font == GLUT_STROKE_MONO_ROMAN ){
00205 h = 130.0f;
00206 for( unsigned int i = 0; i < len; i++ ){
00207 w += glutStrokeWidth( s_font, (int)m_text[ i ] );
00208 }
00209 }
00210 else{
00211 if( s_fontname == "GLUT_BITMAP_9_BY_15" ){
00212 h = 15;
00213 }
00214 else if( s_fontname == "GLUT_BITMAP_8_BY_13" ){
00215 h = 13;
00216 }
00217 else if( s_fontname == "GLUT_BITMAP_TIMES_ROMAN_10" ){
00218 h = 10;
00219 }
00220 else if( s_fontname == "GLUT_BITMAP_TIMES_ROMAN_24" ){
00221 h = 24;
00222 }
00223 #if (GLUT_API_VERSION >= 3)
00224 else if( s_fontname == "GLUT_BITMAP_HELVETICA_10" ){
00225 h = 10;
00226 }
00227 else if( s_fontname == "GLUT_BITMAP_HELVETICA_12" ){
00228 h = 12;
00229 }
00230 else if( s_fontname == "GLUT_BITMAP_HELVETICA_18" ){
00231 h = 18;
00232 }
00233 #endif
00234 for( unsigned int i = 0; i < len; i++ ){
00235 w += glutBitmapWidth( s_font, (int)m_text[ i ] );
00236 }
00237 }
00238
00239 ux = w;
00240 uy = h;
00241
00242 #endif
00243 lx += getLocal().getCol(3)[0];
00244 ly += getLocal().getCol(3)[1];
00245 ux += getLocal().getCol(3)[0];
00246 uy += getLocal().getCol(3)[1];
00247
00248
00249
00250 return( NAABB( Vec3( lx, ly ) * length( m_local.getCol(0).xyz() ), Vec3( ux, uy ) * length( m_local.getCol(1).xyz() ) ) );
00251 }
00252
00253 };