//////////////////////////////////////////////////////////////////////////////// // render //virtual void GaMainGameState::render() { // NEILO HACK: REMOVE. OsClient* pClient = OsCore::pImpl()->getClient( 0 ); RsViewport Viewport( 0, 0, pClient->getWidth(), pClient->getHeight() ); // Render background. Projection_.perspProjectionHorizontal( BcPIDIV4, (BcReal)pClient->getWidth() / (BcReal)pClient->getHeight(), 1.0f, 1024.0f ); WorldView_.lookAt( BcVec3d( 0.0f, 350.0f, 270.0f ), BcVec3d( 0.0f, 0.0f, 0.0f ), BcVec3d( 0.0f, 0.0f, 1.0f ) ); if( SsCore::pImpl() != NULL ) { SsCore::pImpl()->setListener( BcVec3d( 0.0f, 350.0f, 270.0f ), BcVec3d( 0.0f, -4.0f, -2.0f ).normal(), BcVec3d( 0.0f, 0.0f, 1.0f ) ); } setMaterialComponentParams( BackgroundMaterialComponent_, BcMat4d() ); Canvas_->setMaterialComponent( BackgroundMaterialComponent_ ); Canvas_->drawSpriteCentered3D( BcVec3d( 0.0f, 0.0f, 0.0f ), WorldHalfSize_ * 4.0f, 0, RsColour::WHITE, 0 ); // Render entities. for( BcU32 Idx = 0; Idx < Entities_.size(); ++Idx ) { GaGameComponent* pEntity = Entities_[ Idx ]; pEntity->render( Canvas_ ); } // Draw foreground. BcMat4d Ortho; Ortho.orthoProjection( -WorldHalfSize_.x(), WorldHalfSize_.x(), -WorldHalfSize_.y(), WorldHalfSize_.y(), -1.0f, 0.0f ); Canvas_->pushMatrix( Ortho ); Canvas_->setMaterialComponent( ForegroundMaterialComponent_ ); Canvas_->drawSpriteCentered( BcVec2d( 0.0f, 0.0f ), BcVec2d( WorldHalfSize_.x() * 2.2f, WorldHalfSize_.y() * -2.0f ), 0, RsColour::WHITE, 20 ); BcReal Width = BcMax( 0.0f, FoodHealth_ - 0.5f ) * 2.0f; RsColour Colour; Colour.lerp( RsColour::RED, RsColour::GREEN, Width ); Canvas_->setMaterialComponent( BarMaterialComponent_ ); Canvas_->drawSpriteCentered( BcVec2d( 0.0f, WorldHalfSize_.y() - ( WorldHalfSize_.y() * 0.05f ) ), BcVec2d( WorldHalfSize_.x() * 1.5f * Width, WorldHalfSize_.y() * 0.05f ), 0, Colour, 20 ); Canvas_->popMatrix(); // Base render. GaBaseGameState::render(); }
////////////////////////////////////////////////////////////////////////// // drawLines void ScnCanvasComponent::drawLines( const MaVec2d* pPoints, BcU32 NoofLines, const RsColour& Colour, BcU32 Layer ) { BcU32 NoofVertices = 2 * NoofLines; ScnCanvasComponentVertex* pVertices = allocVertices( NoofVertices ); ScnCanvasComponentVertex* pFirstVertex = pVertices; // Only draw if we can allocate vertices. if( pVertices != NULL ) { // Now copy in data. BcU32 ABGR = Colour.asABGR(); for( BcU32 Idx = 0; Idx < NoofVertices; ++Idx ) { pVertices->X_ = pPoints[ Idx ].x(); pVertices->Y_ = pPoints[ Idx ].y(); pVertices->Z_ = 0.0f; pVertices->W_ = 1.0f; pVertices->ABGR_ = ABGR; ++pVertices; } // Add primitive. addPrimitive( RsTopologyType::LINE_LIST, pFirstVertex, NoofVertices, Layer, BcTrue ); } }
////////////////////////////////////////////////////////////////////////// // drawLines void ScnDebugRenderComponent::drawLines( const MaVec3d* pPoints, BcU32 NoofLines, const RsColour& Colour, BcU32 Layer ) { BcU32 NoofVertices = 2 * NoofLines; ScnDebugRenderComponentVertex* pVertices = allocVertices( NoofVertices ); ScnDebugRenderComponentVertex* pFirstVertex = pVertices; // Only draw if we can allocate vertices. if( pVertices != NULL ) { // Now copy in data. BcU32 ABGR = Colour.asABGR(); for( BcU32 Idx = 0; Idx < NoofVertices; ++Idx ) { pVertices->X_ = pPoints[ Idx ].x(); pVertices->Y_ = pPoints[ Idx ].y(); pVertices->Z_ = pPoints[ Idx ].z(); pVertices->ABGR_ = ABGR; ++pVertices; } // Add primitive. addPrimitive( rsPT_LINESTRIP, pFirstVertex, NoofVertices, Layer, BcTrue ); } }
////////////////////////////////////////////////////////////////////////// // drawLine3d void ScnCanvasComponent::drawLine3d( const MaVec3d& PointA, const MaVec3d& PointB, const RsColour& Colour, BcU32 Layer ) { ScnCanvasComponentVertex* pVertices = allocVertices( 2 ); ScnCanvasComponentVertex* pFirstVertex = pVertices; // Only draw if we can allocate vertices. if( pVertices != NULL ) { // Now copy in data. BcU32 ABGR = Colour.asABGR(); pVertices->X_ = PointA.x(); pVertices->Y_ = PointA.y(); pVertices->Z_ = PointA.z(); pVertices->ABGR_ = ABGR; ++pVertices; pVertices->X_ = PointB.x(); pVertices->Y_ = PointB.y(); pVertices->Z_ = PointB.z(); pVertices->ABGR_ = ABGR; // Add primitive. addPrimitive( rsPT_LINELIST, pFirstVertex, 2, Layer, BcTrue ); } }
////////////////////////////////////////////////////////////////////////// // drawBox void ScnCanvasComponent::drawBox( const MaVec2d& CornerA, const MaVec2d& CornerB, const RsColour& Colour, BcU32 Layer ) { ScnCanvasComponentVertex* pVertices = allocVertices( 4 ); ScnCanvasComponentVertex* pFirstVertex = pVertices; // Only draw if we can allocate vertices. if( pVertices != NULL ) { // Now copy in data. BcU32 ABGR = Colour.asABGR(); pVertices->X_ = CornerA.x(); pVertices->Y_ = CornerA.y(); pVertices->Z_ = 0.0f; pVertices->W_ = 1.0f; pVertices->U_ = 0.0f; pVertices->V_ = 0.0f; pVertices->ABGR_ = ABGR; ++pVertices; pVertices->X_ = CornerB.x(); pVertices->Y_ = CornerA.y(); pVertices->Z_ = 0.0f; pVertices->W_ = 1.0f; pVertices->U_ = 1.0f; pVertices->V_ = 0.0f; pVertices->ABGR_ = ABGR; ++pVertices; pVertices->X_ = CornerA.x(); pVertices->Y_ = CornerB.y(); pVertices->Z_ = 0.0f; pVertices->W_ = 1.0f; pVertices->U_ = 0.0f; pVertices->V_ = 1.0f; pVertices->ABGR_ = ABGR; ++pVertices; pVertices->X_ = CornerB.x(); pVertices->Y_ = CornerB.y(); pVertices->Z_ = 0.0f; pVertices->W_ = 1.0f; pVertices->U_ = 1.0f; pVertices->V_ = 1.0f; pVertices->ABGR_ = ABGR; // Add primitive. addPrimitive( RsTopologyType::TRIANGLE_STRIP, pFirstVertex, 4, Layer, BcTrue ); } }
////////////////////////////////////////////////////////////////////////// // drawLine void ScnDebugRenderComponent::drawLine( const MaVec3d& PointA, const MaVec3d& PointB, const RsColour& Colour, BcU32 Layer ) { ScnDebugRenderComponentVertex* pVertices = allocVertices( 2 ); ScnDebugRenderComponentVertex* pFirstVertex = pVertices; // Only draw if we can allocate vertices. if( pVertices != NULL ) { // Now copy in data. BcU32 ABGR = Colour.asABGR(); pVertices->X_ = PointA.x(); pVertices->Y_ = PointA.y(); pVertices->Z_ = PointA.z(); pVertices->ABGR_ = ABGR; ++pVertices; pVertices->X_ = PointB.x(); pVertices->Y_ = PointB.y(); pVertices->Z_ = PointB.z(); pVertices->ABGR_ = ABGR; // Quickly check last primitive. BcBool AddNewPrimitive = BcTrue; if( LastPrimitiveSection_ != BcErrorCode ) { ScnDebugRenderComponentPrimitiveSection& PrimitiveSection = PrimitiveSectionList_[ LastPrimitiveSection_ ]; // If the last primitive was the same type as ours we can append to it. // NOTE: Need more checks here later. if( PrimitiveSection.Type_ == rsPT_LINELIST && PrimitiveSection.Layer_ == Layer && PrimitiveSection.MaterialComponent_ == MaterialComponent_ ) { PrimitiveSection.NoofVertices_ += 2; AddNewPrimitive = BcFalse; } } // Add primitive. if( AddNewPrimitive == BcTrue ) { addPrimitive( rsPT_LINELIST, pFirstVertex, 2, Layer, BcTrue ); } } }
////////////////////////////////////////////////////////////////////////// // drawSprite void ScnCanvasComponent::drawSprite( const MaVec2d& Position, const MaVec2d& Size, BcU32 TextureIdx, const RsColour& Colour, BcU32 Layer ) { ScnCanvasComponentVertex* pVertices = allocVertices( 6 ); ScnCanvasComponentVertex* pFirstVertex = pVertices; const MaVec2d CornerA = Position; const MaVec2d CornerB = Position + Size; const ScnRect Rect = DiffuseTexture_.isValid() ? DiffuseTexture_->getRect( TextureIdx ) : ScnRect(); // Only draw if we can allocate vertices. if( pVertices != NULL ) { // Now copy in data. BcU32 ABGR = Colour.asABGR(); pVertices->X_ = CornerA.x(); pVertices->Y_ = CornerA.y(); pVertices->Z_ = 0.0f; pVertices->W_ = 1.0f; pVertices->U_ = Rect.X_; pVertices->V_ = Rect.Y_; pVertices->ABGR_ = ABGR; ++pVertices; pVertices->X_ = CornerB.x(); pVertices->Y_ = CornerA.y(); pVertices->Z_ = 0.0f; pVertices->W_ = 1.0f; pVertices->U_ = Rect.X_ + Rect.W_; pVertices->V_ = Rect.Y_; pVertices->ABGR_ = ABGR; ++pVertices; pVertices->X_ = CornerA.x(); pVertices->Y_ = CornerB.y(); pVertices->Z_ = 0.0f; pVertices->W_ = 1.0f; pVertices->U_ = Rect.X_; pVertices->V_ = Rect.Y_ + Rect.H_; pVertices->ABGR_ = ABGR; ++pVertices; pVertices->X_ = CornerA.x(); pVertices->Y_ = CornerB.y(); pVertices->Z_ = 0.0f; pVertices->W_ = 1.0f; pVertices->U_ = Rect.X_; pVertices->V_ = Rect.Y_ + Rect.H_; pVertices->ABGR_ = ABGR; ++pVertices; pVertices->X_ = CornerB.x(); pVertices->Y_ = CornerA.y(); pVertices->Z_ = 0.0f; pVertices->W_ = 1.0f; pVertices->U_ = Rect.X_ + Rect.W_; pVertices->V_ = Rect.Y_; pVertices->ABGR_ = ABGR; ++pVertices; pVertices->X_ = CornerB.x(); pVertices->Y_ = CornerB.y(); pVertices->Z_ = 0.0f; pVertices->W_ = 1.0f; pVertices->U_ = Rect.X_ + Rect.W_; pVertices->V_ = Rect.Y_ + Rect.H_; pVertices->ABGR_ = ABGR; // Quickly check last primitive. BcBool AddNewPrimitive = BcTrue; if( LastPrimitiveSection_ != BcErrorCode ) { ScnCanvasComponentPrimitiveSection& PrimitiveSection = PrimitiveSectionList_[ LastPrimitiveSection_ ]; // If the last primitive was the same type as ours we can append to it. // NOTE: Need more checks here later. if( PrimitiveSection.Type_ == RsTopologyType::TRIANGLE_LIST && PrimitiveSection.Layer_ == Layer && PrimitiveSection.MaterialComponent_ == MaterialComponent_ ) { PrimitiveSection.NoofVertices_ += 6; // Matrix stack. // TODO: Factor into a seperate function. if( IsIdentity_ == BcFalse ) { MaMat4d Matrix = getMatrix(); for( BcU32 Idx = 0; Idx < 6; ++Idx ) { ScnCanvasComponentVertex* pVertex = &pFirstVertex[ Idx ]; MaVec3d Vertex = MaVec3d( pVertex->X_, pVertex->Y_, pVertex->Z_ ) * Matrix; pVertex->X_ = Vertex.x(); pVertex->Y_ = Vertex.y(); pVertex->Z_ = Vertex.z(); pVertex->W_ = 1.0f; } } AddNewPrimitive = BcFalse; } } // Add primitive. if( AddNewPrimitive == BcTrue ) { addPrimitive( RsTopologyType::TRIANGLE_LIST, pFirstVertex, 6, Layer, BcTrue ); } } }
////////////////////////////////////////////////////////////////////////// // drawLine void ScnCanvasComponent::drawLine( const MaVec2d& PointA, const MaVec2d& PointB, const RsColour& Colour, BcU32 Layer ) { ScnCanvasComponentVertex* pVertices = allocVertices( 2 ); ScnCanvasComponentVertex* pFirstVertex = pVertices; // Only draw if we can allocate vertices. if( pVertices != NULL ) { // Now copy in data. BcU32 ABGR = Colour.asABGR(); pVertices->X_ = PointA.x(); pVertices->Y_ = PointA.y(); pVertices->Z_ = 0.0f; pVertices->W_ = 1.0f; pVertices->ABGR_ = ABGR; ++pVertices; pVertices->X_ = PointB.x(); pVertices->Y_ = PointB.y(); pVertices->Z_ = 0.0f; pVertices->W_ = 1.0f; pVertices->ABGR_ = ABGR; // Quickly check last primitive. BcBool AddNewPrimitive = BcTrue; if( LastPrimitiveSection_ != BcErrorCode ) { ScnCanvasComponentPrimitiveSection& PrimitiveSection = PrimitiveSectionList_[ LastPrimitiveSection_ ]; // If the last primitive was the same type as ours we can append to it. // NOTE: Need more checks here later. if( PrimitiveSection.Type_ == RsTopologyType::LINE_LIST && PrimitiveSection.Layer_ == Layer && PrimitiveSection.MaterialComponent_ == MaterialComponent_ ) { PrimitiveSection.NoofVertices_ += 2; // Matrix stack. // TODO: Factor into a seperate function. if( IsIdentity_ == BcFalse ) { MaMat4d Matrix = getMatrix(); for( BcU32 Idx = 0; Idx < 2; ++Idx ) { ScnCanvasComponentVertex* pVertex = &pFirstVertex[ Idx ]; MaVec3d Vertex = MaVec3d( pVertex->X_, pVertex->Y_, pVertex->Z_ ) * Matrix; pVertex->X_ = Vertex.x(); pVertex->Y_ = Vertex.y(); pVertex->Z_ = Vertex.z(); pVertices->W_ = 1.0f; } } AddNewPrimitive = BcFalse; } } // Add primitive. if( AddNewPrimitive == BcTrue ) { addPrimitive( RsTopologyType::LINE_LIST, pFirstVertex, 2, Layer, BcTrue ); } } }
void RsTextureWinGL::Render( const MtVector2& v2Position, const MtVector2& v2Dimension, RsColour colour, BtU32 sortOrder ) { // Cache the impl RsImplWinGL *pImpl = (RsImplWinGL*)RsImpl::pInstance(); // Cache the render target RsRenderTarget *pRenderTarget = RsRenderTarget::GetCurrent(); // Cache the camera RsCamera camera = pRenderTarget->GetCamera(); // Cache the display width and height BtFloat Width = (BtFloat)camera.GetViewport().m_width; BtFloat Height = (BtFloat)camera.GetViewport().m_height; // Cache the display width and height BtFloat fScaleWidth = 1.0f / Width; BtFloat fScaleHeight = 1.0f / Height; // Allocate vertex RsVertex3 *pStartVertex = pImpl->StartVertex(); // Set the start vertex RsVertex3 *pVertex = pStartVertex; // Cache the texture width and height BtFloat fTextureWidth = m_pMipmaps[0].m_nWidth; BtFloat fTextureHeight = m_pMipmaps[0].m_nHeight; // Calculate the texture scalars BtFloat fScalarX = 1.0f / fTextureWidth; BtFloat fScalarY = 1.0f / fTextureHeight; BtFloat minU = fScalarX / 2; BtFloat minV = fScalarY / 2; BtFloat maxU = ( m_pMipmaps[0].m_originalWidth * fScalarX ) - minU; BtFloat maxV = ( m_pMipmaps[0].m_originalHeight * fScalarY ) - minV; // Calculate the positions BtFloat xmin = v2Position.x; BtFloat xmax = v2Position.x + v2Dimension.x; BtFloat ymin = v2Position.y; BtFloat ymax = v2Position.y + v2Dimension.y; RsVertex3 *pQuad = pVertex; // Copy these into vertex pVertex->m_v3Position = MtVector3(xmin, ymin, 0.1f ); pVertex->m_v2UV = MtVector2( minU, minV ); ++pVertex; pVertex->m_v3Position = MtVector3(xmin, ymax, 0.1f ); pVertex->m_v2UV = MtVector2( minU, maxV ); ++pVertex; pVertex->m_v3Position = MtVector3(xmax, ymin, 0.1f ); pVertex->m_v2UV = MtVector2( maxU, minV ); ++pVertex; pVertex->m_v3Position = MtVector3(xmax, ymax, 0.1f ); pVertex->m_v2UV = MtVector2( maxU, maxV ); ++pVertex; // Scale the position to local screen space -1 to 1 for( BtU32 i=0; i<4; i++ ) { // Set the colour pQuad[ i ].m_colour = colour.asARGB(); // Flip the y pQuad[ i ].m_v3Position.y = Height - pQuad[ i ].m_v3Position.y; // Scale from 0..width to 0..1 pQuad[ i ].m_v3Position.x *= fScaleWidth; pQuad[ i ].m_v3Position.y *= fScaleHeight; // Scale from 0..1 to 0..2 pQuad[ i ].m_v3Position.x *= 2.0f; pQuad[ i ].m_v3Position.y *= 2.0f; // Translate from 0..2 to -1..1 pQuad[ i ].m_v3Position.x -= 1.0f; pQuad[ i ].m_v3Position.y -= 1.0f; } // Setup the primitive RsPrimitiveWinGL *pPrimitive = pImpl->AddPrimitive(); pPrimitive->m_primitiveType = GL_TRIANGLE_STRIP; pPrimitive->m_numVertex = 4; pPrimitive->m_nStartVertex = pImpl->GetCurrentVertex(); // End the current vertex pImpl->EndVertex( 4 ); // Make a new font renderable RsTextureRenderable *pTextureRenderable = pImpl->AddTexture(); pTextureRenderable->m_pTexture = this; pTextureRenderable->m_pVertex = pStartVertex; pTextureRenderable->m_primitive = pPrimitive; // Validate the shader BtAssert( pTextureRenderable->m_pShader != BtNull ); // Add the font to the renderable list RsRenderTargetWinGL *pCurrentRenderTarget = (RsRenderTargetWinGL*)RsRenderTarget::GetCurrent(); pCurrentRenderTarget->Add( sortOrder, pTextureRenderable ); }
// virtual MtVector2 RsFontWin32GL::Render( const MtVector2& v2StartPosition, const MtVector2& v2Scale, const RsColour &colour, const BtChar* szText, BtU32 sortOrder ) { const BtU32 MaxFontLength = 256; MtVector2 v2LastPosition = MtVector2( 0, 0 ); // Cache the impl RsImplWinGL *pImpl = (RsImplWinGL*)RsImpl::pInstance(); // Cache the render target RsRenderTarget *pRenderTarget = RsRenderTarget::GetCurrent(); // Cache the camera RsCamera camera = pRenderTarget->GetCamera(); // Cache the display width and height BtFloat Width = (BtFloat)camera.GetViewport().m_width; BtFloat Height = (BtFloat)camera.GetViewport().m_height; // Cache the display width and height BtFloat fScaleWidth = 1.0f / Width; BtFloat fScaleHeight = 1.0f / Height; // Allocate vertex RsVertex3 *pStartVertex = pImpl->StartVertex(); // Set the start vertex RsVertex3 *pVertex = pStartVertex; // Cache the texture RsTextureWinGL* pTexture = (RsTextureWinGL*) m_pTextures[ 0 ]; // Set the start position MtVector2 v2Position = v2StartPosition; // Cache the string length BtU32 length = strlen(szText); // Cache the texture width and height BtFloat TextureWidth = 1.0f / (BtFloat) pTexture->GetWidth(); BtFloat TextureHeight = 1.0f / (BtFloat) pTexture->GetHeight(); BtU32 currentVertex = 0; // Loop through the string for( BtU32 nCharacterIndex=0; nCharacterIndex<length; nCharacterIndex++ ) { // Cache each character BtUChar Character = szText[nCharacterIndex]; if( Character == '\n' ) { // Cache the font character LBaFontChar& fontChar = m_pFileData->m_characters['A']; v2Position.x = v2StartPosition.x; v2Position.y += fontChar.m_fHeight * 1.50f * v2Scale.y; continue; } // Cache the font character LBaFontChar& fontChar = m_pFileData->m_characters[Character]; // Set the dimension from the width and height of the texture MtVector2 v2Dimension = MtVector2( fontChar.m_fWidth, fontChar.m_fHeight ); // Calculate the positions BtFloat fX0 = v2Position.x; BtFloat fX1 = fX0 + ( v2Dimension.x * v2Scale.x ); BtFloat fY0 = v2Position.y + ( fontChar.m_nYOffset * v2Scale.y ); BtFloat fY1 = fY0 + ( v2Dimension.y * v2Scale.y ); RsVertex3 *pQuad = pVertex; // Copy these into vertex pVertex->m_v3Position = MtVector3(fX0, fY0, 0.1f ); pVertex->m_v2UV = MtVector2( fontChar.m_U0 , fontChar.m_V0 ); ++pVertex; pVertex->m_v3Position = MtVector3(fX0, fY1, 0.1f ); pVertex->m_v2UV = MtVector2( fontChar.m_U0, fontChar.m_V1 + 1 ); ++pVertex; pVertex->m_v3Position = MtVector3(fX1, fY0, 0.1f ); pVertex->m_v2UV = MtVector2( fontChar.m_U1 + 1, fontChar.m_V0 ); ++pVertex; pVertex->m_v3Position = MtVector3(fX0, fY1, 0.1f ); pVertex->m_v2UV = MtVector2( fontChar.m_U0 , fontChar.m_V1 + 1 ); ++pVertex; pVertex->m_v3Position = MtVector3(fX1, fY1, 0.1f ); pVertex->m_v2UV = MtVector2( fontChar.m_U1 + 1, fontChar.m_V1 + 1 ); ++pVertex; pVertex->m_v3Position = MtVector3(fX1, fY0, 0.1f ); pVertex->m_v2UV = MtVector2( fontChar.m_U1 + 1, fontChar.m_V0 ); ++pVertex; // Scale the position to local screen space -1 to 1 for( BtU32 i=0; i<6; i++ ) { // Set the colour pQuad[ i ].m_colour = colour.asWord(); // Scale the uvs pQuad[ i ].m_v2UV.x *= TextureWidth; pQuad[ i ].m_v2UV.y *= TextureHeight; // Flip the y pQuad[ i ].m_v3Position.y = Height - pQuad[ i ].m_v3Position.y; pQuad[ i ].m_v3Position.x -= 0.5f; pQuad[ i ].m_v3Position.y -= 0.5f; // Scale from 0..width to 0..1 pQuad[ i ].m_v3Position.x *= fScaleWidth; pQuad[ i ].m_v3Position.y *= fScaleHeight; // Scale from 0..1 to 0..2 pQuad[ i ].m_v3Position.x *= 2.0f; pQuad[ i ].m_v3Position.y *= 2.0f; // Translate from 0..2 to -1..1 pQuad[ i ].m_v3Position.x -= 1.0f; pQuad[ i ].m_v3Position.y -= 1.0f; } // Render the 6 new vertex // Increment the last position v2LastPosition.x = MtMax( v2LastPosition.x, v2Position.x + v2Dimension.x ); v2LastPosition.y = MtMax( v2LastPosition.y, v2Position.y + v2Dimension.y ); // Increment the position v2Position.x += ( fontChar.m_nXAdvance * v2Scale.x ); currentVertex += 6; } // Setup the primitive RsPrimitiveWinGL *pPrimitive = pImpl->AddPrimitive(); pPrimitive->m_primitiveType = GL_TRIANGLES; pPrimitive->m_numVertex = currentVertex; pPrimitive->m_nStartVertex = pImpl->GetCurrentVertex(); // End the current vertex pImpl->EndVertex( currentVertex ); // Make a new font renderable RsFontRenderable *pFontRenderable = pImpl->AddFont(); pFontRenderable->m_pFont = this; pFontRenderable->m_pVertex = pStartVertex; pFontRenderable->m_primitive = pPrimitive; // Validate the shader BtAssert( pFontRenderable->m_pShader != BtNull ); // Add the font to the renderable list RsRenderTargetWinGL *pCurrentRenderTarget = (RsRenderTargetWinGL*)RsRenderTarget::GetCurrent(); pCurrentRenderTarget->Add( sortOrder, pFontRenderable ); // Calculate the dimension MtVector2 v2Dimension = v2LastPosition - v2StartPosition; // Return the dimension return v2Dimension; }