00001 /*------------------------------------------------------------------------- 00002 This source file is a part of OGRE 00003 (Object-oriented Graphics Rendering Engine) 00004 00005 For the latest info, see http://www.ogre3d.org/ 00006 00007 Copyright © 2000-2002 The OGRE Team 00008 Also see acknowledgements in Readme.html 00009 00010 This library is free software; you can redistribute it and/or modify it 00011 under the terms of the GNU Lesser General Public License (LGPL) as 00012 published by the Free Software Foundation; either version 2.1 of the 00013 License, or (at your option) any later version. 00014 00015 This library is distributed in the hope that it will be useful, but 00016 WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 00017 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 00018 License for more details. 00019 00020 You should have received a copy of the GNU Lesser General Public License 00021 along with this library; if not, write to the Free Software Foundation, 00022 Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA or go to 00023 http://www.gnu.org/copyleft/lesser.txt 00024 -------------------------------------------------------------------------*/ 00025 00026 #include "OgreTextAreaGuiElement.h" 00027 #include "OgreRoot.h" 00028 #include "OgreLogManager.h" 00029 #include "OgreOverlayManager.h" 00030 #include "OgreHardwareBufferManager.h" 00031 #include "OgreHardwareVertexBuffer.h" 00032 #include "OgreException.h" 00033 00034 namespace Ogre { 00035 00036 #define DEFAULT_INITIAL_CHARS 12 00037 //--------------------------------------------------------------------- 00038 String TextAreaGuiElement::msTypeName = "TextArea"; 00039 TextAreaGuiElement::CmdCharHeight TextAreaGuiElement::msCmdCharHeight; 00040 TextAreaGuiElement::CmdSpaceWidth TextAreaGuiElement::msCmdSpaceWidth; 00041 TextAreaGuiElement::CmdFontName TextAreaGuiElement::msCmdFontName; 00042 TextAreaGuiElement::CmdColour TextAreaGuiElement::msCmdColour; 00043 TextAreaGuiElement::CmdColourBottom TextAreaGuiElement::msCmdColourBottom; 00044 TextAreaGuiElement::CmdColourTop TextAreaGuiElement::msCmdColourTop; 00045 TextAreaGuiElement::CmdAlignment TextAreaGuiElement::msCmdAlignment; 00046 //--------------------------------------------------------------------- 00047 #define POS_TEX_BINDING 0 00048 #define COLOUR_BINDING 1 00049 //--------------------------------------------------------------------- 00050 TextAreaGuiElement::TextAreaGuiElement(const String& name) 00051 : GuiElement(name) 00052 { 00053 mTransparent = false; 00054 mAlignment = Left; 00055 mpFont = 0; 00056 00057 mColourTop = ColourValue::White; 00058 mColourBottom = ColourValue::White; 00059 mColoursChanged = true; 00060 00061 mAllocSize = 0; 00062 00063 mCharHeight = 0.02; 00064 mPixelCharHeight = 12; 00065 mSpaceWidth = 0; 00066 mPixelSpaceWidth = 0; 00067 00068 if (createParamDictionary("TextAreaGuiElement")) 00069 { 00070 addBaseParameters(); 00071 } 00072 } 00073 00074 void TextAreaGuiElement::initialise(void) 00075 { 00076 // Set up the render op 00077 // Combine positions and texture coords since they tend to change together 00078 // since character sizes are different 00079 mRenderOp.vertexData = new VertexData(); 00080 VertexDeclaration* decl = mRenderOp.vertexData->vertexDeclaration; 00081 size_t offset = 0; 00082 // Positions 00083 decl->addElement(POS_TEX_BINDING, offset, VET_FLOAT3, VES_POSITION); 00084 offset += VertexElement::getTypeSize(VET_FLOAT3); 00085 // Texcoords 00086 decl->addElement(POS_TEX_BINDING, offset, VET_FLOAT2, VES_TEXTURE_COORDINATES, 0); 00087 offset += VertexElement::getTypeSize(VET_FLOAT2); 00088 // Colours - store these in a separate buffer because they change less often 00089 decl->addElement(COLOUR_BINDING, 0, VET_COLOUR, VES_DIFFUSE); 00090 00091 mRenderOp.operationType = RenderOperation::OT_TRIANGLE_LIST; 00092 mRenderOp.useIndexes = false; 00093 mRenderOp.vertexData->vertexStart = 0; 00094 // Vertex buffer will be created in checkMemoryAllocation 00095 00096 checkMemoryAllocation( DEFAULT_INITIAL_CHARS ); 00097 00098 } 00099 00100 void TextAreaGuiElement::checkMemoryAllocation( size_t numChars ) 00101 { 00102 if( mAllocSize < numChars) 00103 { 00104 // Create and bind new buffers 00105 // Note that old buffers will be deleted automatically through reference counting 00106 00107 // 6 verts per char since we're doing tri lists without indexes 00108 // Allocate space for positions & texture coords 00109 VertexDeclaration* decl = mRenderOp.vertexData->vertexDeclaration; 00110 VertexBufferBinding* bind = mRenderOp.vertexData->vertexBufferBinding; 00111 00112 mRenderOp.vertexData->vertexCount = numChars * 6; 00113 00114 // Create dynamic since text tends to change alot 00115 // positions & texcoords 00116 HardwareVertexBufferSharedPtr vbuf = 00117 HardwareBufferManager::getSingleton(). 00118 createVertexBuffer( 00119 decl->getVertexSize(POS_TEX_BINDING), 00120 mRenderOp.vertexData->vertexCount, 00121 HardwareBuffer::HBU_DYNAMIC); 00122 bind->setBinding(POS_TEX_BINDING, vbuf); 00123 00124 // colours 00125 vbuf = HardwareBufferManager::getSingleton(). 00126 createVertexBuffer( 00127 decl->getVertexSize(COLOUR_BINDING), 00128 mRenderOp.vertexData->vertexCount, 00129 HardwareBuffer::HBU_DYNAMIC); 00130 bind->setBinding(COLOUR_BINDING, vbuf); 00131 00132 mAllocSize = numChars; 00133 mColoursChanged = true; // force colour buffer regeneration 00134 } 00135 00136 } 00137 00138 void TextAreaGuiElement::updateGeometry() 00139 { 00140 Real *pVert; 00141 00142 if (!mpFont) 00143 { 00144 // not initialised yet, probably due to the order of creation in a template 00145 return; 00146 } 00147 00148 size_t charlen = mCaption.size(); 00149 checkMemoryAllocation( charlen ); 00150 00151 mRenderOp.vertexData->vertexCount = charlen * 6; 00152 // Get position / texcoord buffer 00153 HardwareVertexBufferSharedPtr vbuf = 00154 mRenderOp.vertexData->vertexBufferBinding->getBuffer(POS_TEX_BINDING); 00155 pVert = static_cast<Real*>( 00156 vbuf->lock(HardwareBuffer::HBL_DISCARD) ); 00157 00158 float largestWidth = 0; 00159 float left = _getDerivedLeft() * 2.0 - 1.0; 00160 float top = -( (_getDerivedTop() * 2.0 ) - 1.0 ); 00161 00162 // Derive space with from a capital A 00163 if (mSpaceWidth == 0) 00164 { 00165 mSpaceWidth = mpFont->getGlyphAspectRatio( 'A' ) * mCharHeight * 2.0; 00166 } 00167 00168 // Use iterator 00169 String::iterator i, iend; 00170 iend = mCaption.end(); 00171 bool newLine = true; 00172 for( i = mCaption.begin(); i != iend; ++i ) 00173 { 00174 if( newLine ) 00175 { 00176 Real len = 0.0f; 00177 for( String::iterator j = i; j != iend && *j != '\n'; j++ ) 00178 { 00179 if (*j == ' ') 00180 { 00181 len += mSpaceWidth; 00182 } 00183 else 00184 { 00185 len += mpFont->getGlyphAspectRatio( *j ) * mCharHeight * 2.0; 00186 } 00187 } 00188 00189 if( mAlignment == Right ) 00190 left -= len; 00191 else if( mAlignment == Center ) 00192 left -= len * 0.5; 00193 00194 newLine = false; 00195 } 00196 00197 if( *i == '\n' ) 00198 { 00199 left = _getDerivedLeft() * 2.0 - 1.0; 00200 top -= mCharHeight * 2.0; 00201 newLine = true; 00202 // Also reduce tri count 00203 mRenderOp.vertexData->vertexCount -= 6; 00204 continue; 00205 } 00206 00207 if ( *i == ' ') 00208 { 00209 // Just leave a gap, no tris 00210 left += mSpaceWidth; 00211 // Also reduce tri count 00212 mRenderOp.vertexData->vertexCount -= 6; 00213 continue; 00214 } 00215 00216 Real horiz_height = mpFont->getGlyphAspectRatio( *i ); 00217 Real u1, u2, v1, v2; 00218 mpFont->getGlyphTexCoords( *i, u1, v1, u2, v2 ); 00219 00220 // each vert is (x, y, z, u, v) 00221 //------------------------------------------------------------------------------------- 00222 // First tri 00223 // 00224 // Upper left 00225 *pVert++ = left; 00226 *pVert++ = top; 00227 *pVert++ = -1.0; 00228 *pVert++ = u1; 00229 *pVert++ = v1; 00230 00231 top -= mCharHeight * 2.0; 00232 00233 // Bottom left 00234 *pVert++ = left; 00235 *pVert++ = top; 00236 *pVert++ = -1.0; 00237 *pVert++ = u1; 00238 *pVert++ = v2; 00239 00240 top += mCharHeight * 2.0; 00241 left += horiz_height * mCharHeight * 2.0; 00242 00243 // Top right 00244 *pVert++ = left; 00245 *pVert++ = top; 00246 *pVert++ = -1.0; 00247 *pVert++ = u2; 00248 *pVert++ = v1; 00249 //------------------------------------------------------------------------------------- 00250 00251 //------------------------------------------------------------------------------------- 00252 // Second tri 00253 // 00254 // Top right (again) 00255 *pVert++ = left; 00256 *pVert++ = top; 00257 *pVert++ = -1.0; 00258 *pVert++ = u2; 00259 *pVert++ = v1; 00260 00261 top -= mCharHeight * 2.0; 00262 left -= horiz_height * mCharHeight * 2.0; 00263 00264 // Bottom left (again) 00265 *pVert++ = left; 00266 *pVert++ = top; 00267 *pVert++ = -1.0; 00268 *pVert++ = u1; 00269 *pVert++ = v2; 00270 00271 left += horiz_height * mCharHeight * 2.0; 00272 00273 // Bottom right 00274 *pVert++ = left; 00275 *pVert++ = top; 00276 *pVert++ = -1.0; 00277 *pVert++ = u2; 00278 *pVert++ = v2; 00279 //------------------------------------------------------------------------------------- 00280 00281 // Go back up with top 00282 top += mCharHeight * 2.0; 00283 00284 float currentWidth = (left + 1)/2 - _getDerivedLeft(); 00285 if (currentWidth > largestWidth) 00286 { 00287 largestWidth = currentWidth; 00288 00289 } 00290 } 00291 // Unlock vertex buffer 00292 vbuf->unlock(); 00293 00294 if (mMetricsMode == GMM_PIXELS) 00295 { 00296 // Derive parametric version of dimensions 00297 Real vpWidth; 00298 vpWidth = (Real) (OverlayManager::getSingleton().getViewportWidth()); 00299 00300 largestWidth *= vpWidth; 00301 }; 00302 00303 if (getWidth() < largestWidth) 00304 setWidth(largestWidth); 00305 updateColours(); 00306 00307 } 00308 00309 void TextAreaGuiElement::updatePositionGeometry() 00310 { 00311 updateGeometry(); 00312 } 00313 00314 void TextAreaGuiElement::setCaption( const String& caption ) 00315 { 00316 mCaption = caption; 00317 updateGeometry(); 00318 00319 } 00320 const String& TextAreaGuiElement::getCaption() const 00321 { 00322 return mCaption; 00323 } 00324 00325 void TextAreaGuiElement::setFontName( const String& font ) 00326 { 00327 mpFont = (Font*)FontManager::getSingleton().getByName( font ); 00328 if (!mpFont) 00329 Except( Exception::ERR_ITEM_NOT_FOUND, "Could not find font " + font, 00330 "TextAreaGuiElement::setFontName" ); 00331 mpFont->load(); 00332 mpMaterial = mpFont->getMaterial(); 00333 mpMaterial->setDepthCheckEnabled(false); 00334 mpMaterial->setLightingEnabled(false); 00335 00336 updateGeometry(); 00337 } 00338 const String& TextAreaGuiElement::getFontName() const 00339 { 00340 return mpFont->getName(); 00341 } 00342 00343 void TextAreaGuiElement::setCharHeight( Real height ) 00344 { 00345 if (mMetricsMode != GMM_RELATIVE) 00346 { 00347 mPixelCharHeight = height; 00348 } 00349 else 00350 { 00351 mCharHeight = height; 00352 } 00353 mGeomPositionsOutOfDate = true; 00354 } 00355 Real TextAreaGuiElement::getCharHeight() const 00356 { 00357 if (mMetricsMode == GMM_PIXELS) 00358 { 00359 return mPixelCharHeight; 00360 } 00361 else 00362 { 00363 return mCharHeight; 00364 } 00365 } 00366 00367 void TextAreaGuiElement::setSpaceWidth( Real width ) 00368 { 00369 if (mMetricsMode != GMM_RELATIVE) 00370 { 00371 mPixelSpaceWidth = width; 00372 } 00373 else 00374 { 00375 mSpaceWidth = width; 00376 } 00377 00378 mGeomPositionsOutOfDate = true; 00379 } 00380 Real TextAreaGuiElement::getSpaceWidth() const 00381 { 00382 if (mMetricsMode == GMM_PIXELS) 00383 { 00384 return mPixelSpaceWidth; 00385 } 00386 else 00387 { 00388 return mSpaceWidth; 00389 } 00390 } 00391 00392 //--------------------------------------------------------------------- 00393 TextAreaGuiElement::~TextAreaGuiElement() 00394 { 00395 delete mRenderOp.vertexData; 00396 } 00397 //--------------------------------------------------------------------- 00398 const String& TextAreaGuiElement::getTypeName(void) const 00399 { 00400 return msTypeName; 00401 } 00402 //--------------------------------------------------------------------- 00403 void TextAreaGuiElement::getRenderOperation(RenderOperation& op) 00404 { 00405 op = mRenderOp; 00406 } 00407 //--------------------------------------------------------------------- 00408 void TextAreaGuiElement::setMaterialName(const String& matName) 00409 { 00410 GuiElement::setMaterialName(matName); 00411 updateGeometry(); 00412 } 00413 //--------------------------------------------------------------------- 00414 void TextAreaGuiElement::addBaseParameters(void) 00415 { 00416 GuiElement::addBaseParameters(); 00417 ParamDictionary* dict = getParamDictionary(); 00418 00419 dict->addParameter(ParameterDef("char_height", 00420 "Sets the height of the characters in relation to the screen." 00421 , PT_REAL), 00422 &msCmdCharHeight); 00423 00424 dict->addParameter(ParameterDef("space_width", 00425 "Sets the width of a space in relation to the screen." 00426 , PT_REAL), 00427 &msCmdSpaceWidth); 00428 00429 dict->addParameter(ParameterDef("font_name", 00430 "Sets the name of the font to use." 00431 , PT_STRING), 00432 &msCmdFontName); 00433 00434 dict->addParameter(ParameterDef("colour", 00435 "Sets the colour of the font (a solid colour)." 00436 , PT_STRING), 00437 &msCmdColour); 00438 00439 dict->addParameter(ParameterDef("colour_bottom", 00440 "Sets the colour of the font at the bottom (a gradient colour)." 00441 , PT_STRING), 00442 &msCmdColourBottom); 00443 00444 dict->addParameter(ParameterDef("colour_top", 00445 "Sets the colour of the font at the top (a gradient colour)." 00446 , PT_STRING), 00447 &msCmdColourTop); 00448 00449 dict->addParameter(ParameterDef("alignment", 00450 "Sets the alignment of the text: 'left', 'center' or 'right'." 00451 , PT_STRING), 00452 &msCmdAlignment); 00453 } 00454 //--------------------------------------------------------------------- 00455 void TextAreaGuiElement::setColour(const ColourValue& col) 00456 { 00457 mColourBottom = mColourTop = col; 00458 mColoursChanged = true; 00459 updateColours(); 00460 } 00461 //--------------------------------------------------------------------- 00462 const ColourValue& TextAreaGuiElement::getColour(void) const 00463 { 00464 // Either one 00465 return mColourTop; 00466 } 00467 //--------------------------------------------------------------------- 00468 void TextAreaGuiElement::setColourBottom(const ColourValue& col) 00469 { 00470 mColourBottom = col; 00471 mColoursChanged = true; 00472 updateColours(); 00473 } 00474 //--------------------------------------------------------------------- 00475 const ColourValue& TextAreaGuiElement::getColourBottom(void) const 00476 { 00477 return mColourBottom; 00478 } 00479 //--------------------------------------------------------------------- 00480 void TextAreaGuiElement::setColourTop(const ColourValue& col) 00481 { 00482 mColourTop = col; 00483 mColoursChanged = true; 00484 updateColours(); 00485 } 00486 //--------------------------------------------------------------------- 00487 const ColourValue& TextAreaGuiElement::getColourTop(void) const 00488 { 00489 return mColourTop; 00490 } 00491 //--------------------------------------------------------------------- 00492 void TextAreaGuiElement::updateColours(void) 00493 { 00494 if (!mColoursChanged) return; // do nothing if colours haven't changed 00495 00496 // Convert to system-specific 00497 RGBA topColour, bottomColour; 00498 Root::getSingleton().convertColourValue(mColourTop, &topColour); 00499 Root::getSingleton().convertColourValue(mColourBottom, &bottomColour); 00500 00501 HardwareVertexBufferSharedPtr vbuf = 00502 mRenderOp.vertexData->vertexBufferBinding->getBuffer(COLOUR_BINDING); 00503 00504 RGBA* pDest = static_cast<RGBA*>( 00505 vbuf->lock(HardwareBuffer::HBL_DISCARD) ); 00506 00507 for (size_t i = 0; i < mAllocSize; ++i) 00508 { 00509 // First tri (top, bottom, top) 00510 *pDest++ = topColour; 00511 *pDest++ = bottomColour; 00512 *pDest++ = topColour; 00513 // Second tri (top, bottom, bottom) 00514 *pDest++ = topColour; 00515 *pDest++ = bottomColour; 00516 *pDest++ = bottomColour; 00517 } 00518 vbuf->unlock(); 00519 00520 mColoursChanged = false; 00521 00522 } 00523 //----------------------------------------------------------------------- 00524 void TextAreaGuiElement::setMetricsMode(GuiMetricsMode gmm) 00525 { 00526 GuiElement::setMetricsMode(gmm); 00527 if (gmm != GMM_RELATIVE) 00528 { 00529 // Set pixel variables based on viewport multipliers 00530 Real vpHeight; 00531 vpHeight = (Real) (OverlayManager::getSingleton().getViewportHeight()); 00532 00533 mPixelCharHeight = mCharHeight * vpHeight; 00534 mPixelSpaceWidth = mSpaceWidth * vpHeight; 00535 } 00536 } 00537 00538 //----------------------------------------------------------------------- 00539 void TextAreaGuiElement::_update(void) 00540 { 00541 if (mMetricsMode != GMM_RELATIVE && 00542 (OverlayManager::getSingleton().hasViewportChanged() || mGeomPositionsOutOfDate)) 00543 { 00544 // Recalc character size 00545 Real vpHeight; 00546 vpHeight = (Real) (OverlayManager::getSingleton().getViewportHeight()); 00547 00548 mCharHeight = (Real) mPixelCharHeight / vpHeight; 00549 mSpaceWidth = (Real) mPixelSpaceWidth / vpHeight; 00550 mGeomPositionsOutOfDate = true; 00551 } 00552 GuiElement::_update(); 00553 } 00554 //--------------------------------------------------------------------------------------------- 00555 // Char height command object 00556 // 00557 String TextAreaGuiElement::CmdCharHeight::doGet( const void* target ) const 00558 { 00559 return StringConverter::toString( 00560 static_cast< const TextAreaGuiElement* >( target )->getCharHeight() ); 00561 } 00562 void TextAreaGuiElement::CmdCharHeight::doSet( void* target, const String& val ) 00563 { 00564 static_cast< TextAreaGuiElement* >( target )->setCharHeight( 00565 StringConverter::parseReal( val ) ); 00566 } 00567 //--------------------------------------------------------------------------------------------- 00568 // Space width command object 00569 // 00570 String TextAreaGuiElement::CmdSpaceWidth::doGet( const void* target ) const 00571 { 00572 return StringConverter::toString( 00573 static_cast< const TextAreaGuiElement* >( target )->getSpaceWidth() ); 00574 } 00575 void TextAreaGuiElement::CmdSpaceWidth::doSet( void* target, const String& val ) 00576 { 00577 static_cast< TextAreaGuiElement* >( target )->setSpaceWidth( 00578 StringConverter::parseReal( val ) ); 00579 } 00580 //--------------------------------------------------------------------------------------------- 00581 00582 //--------------------------------------------------------------------------------------------- 00583 // Font name command object 00584 // 00585 String TextAreaGuiElement::CmdFontName::doGet( const void* target ) const 00586 { 00587 return static_cast< const TextAreaGuiElement* >( target )->getFontName(); 00588 } 00589 void TextAreaGuiElement::CmdFontName::doSet( void* target, const String& val ) 00590 { 00591 static_cast< TextAreaGuiElement* >( target )->setFontName( val ); 00592 } 00593 //--------------------------------------------------------------------------------------------- 00594 //--------------------------------------------------------------------------------------------- 00595 // Colour command object 00596 // 00597 String TextAreaGuiElement::CmdColour::doGet( const void* target ) const 00598 { 00599 return StringConverter::toString ( 00600 static_cast< const TextAreaGuiElement* >( target )->getColour()); 00601 } 00602 void TextAreaGuiElement::CmdColour::doSet( void* target, const String& val ) 00603 { 00604 static_cast< TextAreaGuiElement* >( target )->setColour( 00605 StringConverter::parseColourValue(val) ); 00606 } 00607 //--------------------------------------------------------------------------------------------- 00608 //--------------------------------------------------------------------------------------------- 00609 //--------------------------------------------------------------------------------------------- 00610 // Top colour command object 00611 // 00612 String TextAreaGuiElement::CmdColourTop::doGet( const void* target ) const 00613 { 00614 return StringConverter::toString ( 00615 static_cast< const TextAreaGuiElement* >( target )->getColourTop()); 00616 } 00617 void TextAreaGuiElement::CmdColourTop::doSet( void* target, const String& val ) 00618 { 00619 static_cast< TextAreaGuiElement* >( target )->setColourTop( 00620 StringConverter::parseColourValue(val) ); 00621 } 00622 //--------------------------------------------------------------------------------------------- 00623 //--------------------------------------------------------------------------------------------- 00624 //--------------------------------------------------------------------------------------------- 00625 // Bottom colour command object 00626 // 00627 String TextAreaGuiElement::CmdColourBottom::doGet( const void* target ) const 00628 { 00629 return StringConverter::toString ( 00630 static_cast< const TextAreaGuiElement* >( target )->getColourBottom()); 00631 } 00632 void TextAreaGuiElement::CmdColourBottom::doSet( void* target, const String& val ) 00633 { 00634 static_cast< TextAreaGuiElement* >( target )->setColourBottom( 00635 StringConverter::parseColourValue(val) ); 00636 } 00637 //--------------------------------------------------------------------------------------------- 00638 //--------------------------------------------------------------------------------------------- 00639 //--------------------------------------------------------------------------------------------- 00640 // Alignment command object 00641 // 00642 String TextAreaGuiElement::CmdAlignment::doGet( const void* target ) const 00643 { 00644 Alignment align = static_cast< const TextAreaGuiElement* >( target )->getAlignment(); 00645 switch (align) 00646 { 00647 case Left: 00648 return "left"; 00649 case Center: 00650 return "center"; 00651 case Right: 00652 return "right"; 00653 00654 } 00655 // To keep compiler happy 00656 return "left"; 00657 } 00658 void TextAreaGuiElement::CmdAlignment::doSet( void* target, const String& val ) 00659 { 00660 if (val == "center") 00661 { 00662 static_cast< TextAreaGuiElement* >( target )->setAlignment(Center); 00663 } 00664 else if (val == "right") 00665 { 00666 static_cast< TextAreaGuiElement* >( target )->setAlignment(Right); 00667 } 00668 else 00669 { 00670 static_cast< TextAreaGuiElement* >( target )->setAlignment(Left); 00671 } 00672 } 00673 //--------------------------------------------------------------------------------------------- 00674 }
Copyright © 2002-2003 by The OGRE Team
Last modified Fri May 14 23:22:51 2004