//----------------------------------------------------------------// void MOAIDraw::DrawGrid ( const USRect& rect, u32 xCells, u32 yCells ) { if ( xCells > 1 ) { float xStep = rect.Width () / ( float )xCells; for ( u32 i = 1; i < xCells; ++i ) { float x = rect.mXMin + (( float )i * xStep ); USVec2D v0 ( x, rect.mYMin ); USVec2D v1 ( x, rect.mYMax ); MOAIDraw::DrawLine ( v0, v1 ); } } if ( yCells > 1 ) { float yStep = rect.Height () / ( float )yCells; for ( u32 i = 1; i < yCells; ++i ) { float y = rect.mYMin + (( float )i * yStep ); USVec2D v0 ( rect.mXMin, y ); USVec2D v1 ( rect.mXMax, y ); MOAIDraw::DrawLine ( v0, v1 ); } } MOAIDraw::DrawRectOutline ( rect ); }
//----------------------------------------------------------------// void MOAIGfxDevice::SetScissorRect ( USRect rect ) { rect.Bless (); USRect& current = this->mScissorRect; if ( ( current.mXMin != rect.mXMin ) || ( current.mYMin != rect.mYMin ) || ( current.mXMax != rect.mXMax ) || ( current.mYMax != rect.mYMax )) { this->Flush (); USRect deviceRect = this->mFrameBuffer->WndRectToDevice ( rect ); GLint x = ( GLint )deviceRect.mXMin; GLint y = ( GLint )deviceRect.mYMin; GLsizei w = ( GLsizei )( deviceRect.Width () + 0.5f ); GLsizei h = ( GLsizei )( deviceRect.Height () + 0.5f ); glScissor ( x, y, w, h ); this->mScissorRect = rect; glEnable ( GL_SCISSOR_TEST ); } }
//----------------------------------------------------------------// void MOAIDraw::DrawGrid ( USRect& rect, u32 xCells, u32 yCells ) { MOAILineBrush glLine; if ( xCells > 1 ) { float xStep = rect.Width () / ( float )xCells; for ( u32 i = 1; i < xCells; ++i ) { float x = rect.mXMin + (( float )i * xStep ); USVec2D v0 ( x, rect.mYMin ); USVec2D v1 ( x, rect.mYMax ); glLine.SetVerts ( v0, v1 ); glLine.Draw (); } } if ( yCells > 1 ) { float yStep = rect.Height () / ( float )yCells; for ( u32 i = 1; i < yCells; ++i ) { float y = rect.mYMin + (( float )i * yStep ); USVec2D v0 ( rect.mXMin, y ); USVec2D v1 ( rect.mXMax, y ); glLine.SetVerts ( v0, v1 ); glLine.Draw (); } } MOAIDraw::DrawRectOutline ( rect ); }
//----------------------------------------------------------------// void MOAIGfxDevice::ResetState () { this->mTop = 0; this->mPrimCount = 0; // turn off texture #if USE_OPENGLES1 glDisable ( GL_TEXTURE_2D ); #endif this->mTextureUnits [ 0 ] = 0; // turn off blending glDisable ( GL_BLEND ); this->mBlendEnabled = false; // disable backface culling glDisable ( GL_CULL_FACE ); this->mCullFunc = 0; // disable depth test glDisable ( GL_DEPTH_TEST ); this->mDepthFunc = 0; // enable depth write glDepthMask ( true ); this->mDepthMask = true; // clear the vertex format this->SetVertexFormat (); // clear the shader this->mShader = 0; // reset the pen width this->mPenWidth = 1.0f; glLineWidth (( GLfloat )this->mPenWidth ); // reset the point size this->mPointSize = 1.0f; // reset the scissor rect MOAIGfxDevice& device = MOAIGfxDevice::Get (); USRect scissorRect = device.GetRect (); glScissor (( int )scissorRect.mXMin, ( int )scissorRect.mYMin, ( int )scissorRect.Width (), ( int )scissorRect.Height ()); this->mScissorRect = scissorRect; #if USE_OPENGLES1 // fixed function reset if ( !this->IsProgrammable ()) { // reset the current vertex color glColor4f ( 1.0f, 1.0f, 1.0f, 1.0f ); // reset the point size glPointSize (( GLfloat )this->mPointSize ); } #endif }
//----------------------------------------------------------------// void MOAIGfxDevice::SetScissorRect ( const USRect& rect ) { USRect& current = this->mScissorRect; if ( ( current.mXMin != rect.mXMin ) || ( current.mYMin != rect.mYMin ) || ( current.mXMax != rect.mXMax ) || ( current.mYMax != rect.mYMax )) { this->Flush (); glScissor (( int )rect.mXMin, ( int )rect.mYMin, ( int )rect.Width (), ( int )rect.Height ()); this->mScissorRect = rect; } }
//----------------------------------------------------------------// void MOAIGfxDevice::SetViewport ( const USRect& viewport ) { // set us up the viewport GLint x = ( GLint )viewport.mXMin; GLint y = ( GLint )viewport.mYMin; GLsizei w = ( GLsizei )( viewport.Width () + 0.5f ); GLsizei h = ( GLsizei )( viewport.Height () + 0.5f ); glViewport ( x, y, w, h ); this->mViewRect = viewport; }
//----------------------------------------------------------------// void MOAIGfxDevice::SetViewRect ( USRect rect ) { USRect deviceRect = rect; deviceRect = this->mFrameBuffer->WndRectToDevice ( rect ); GLint x = ( GLint )deviceRect.mXMin; GLint y = ( GLint )deviceRect.mYMin; GLsizei w = ( GLsizei )( deviceRect.Width () + 0.5f ); GLsizei h = ( GLsizei )( deviceRect.Height () + 0.5f ); glViewport ( x, y, w, h ); this->mViewRect = rect; }
//----------------------------------------------------------------// USMatrix4x4 MOAIGfxDevice::GetWndToNormMtx () const { USRect rect = this->mViewRect; float hWidth = rect.Width () * 0.5f; float hHeight = rect.Height () * 0.5f; // Inv Wnd USMatrix4x4 wndToNorm; wndToNorm.Translate ( -hWidth - rect.mXMin, -hHeight - rect.mYMin, 0.0f ); USMatrix4x4 mtx; mtx.Scale (( 1.0f / hWidth ), -( 1.0f / hHeight ), 1.0f ); wndToNorm.Append ( mtx ); return wndToNorm; }
//----------------------------------------------------------------// USMatrix4x4 MOAIGfxDevice::GetNormToWndMtx () const { USRect rect = this->mViewRect; float hWidth = rect.Width () * 0.5f; float hHeight = rect.Height () * 0.5f; // Wnd USMatrix4x4 normToWnd; normToWnd.Scale ( hWidth, -hHeight, 1.0f ); USMatrix4x4 mtx; mtx.Translate ( hWidth + rect.mXMin, hHeight + rect.mYMin, 0.0f ); normToWnd.Append ( mtx ); return normToWnd; }
//----------------------------------------------------------------// void MOAIGfxDevice::SetViewport ( const USRect& viewport ) { // set us up the viewport GLint x = ( GLint )viewport.mXMin; GLint y = ( GLint )viewport.mYMin; GLsizei w = ( GLsizei )( viewport.Width () + 0.5f ); GLsizei h = ( GLsizei )( viewport.Height () + 0.5f ); glViewport ( ( GLint )( x * this->mDeviceScale ), ( GLint )( y * this->mDeviceScale ), ( GLsizei )( w * this->mDeviceScale ), ( GLsizei )( h * this->mDeviceScale ) ); this->mViewRect = viewport; }
//----------------------------------------------------------------// USMatrix4x4 MOAIGfxDevice::GetWorldToWndMtx ( float xScale, float yScale ) const { USMatrix4x4 worldToWnd; USMatrix4x4 mtx; USRect rect = this->GetViewRect (); float hWidth = rect.Width () * 0.5f; float hHeight = rect.Height () * 0.5f; // viewproj worldToWnd = this->GetViewProjMtx (); // wnd mtx.Scale ( hWidth * xScale, hHeight * yScale, 1.0f ); worldToWnd.Append ( mtx ); mtx.Translate ( hWidth + rect.mXMin, hHeight + rect.mYMin, 0.0f ); worldToWnd.Append ( mtx ); return worldToWnd; }
//----------------------------------------------------------------// USMatrix4x4 MOAIGfxDevice::GetWndToWorldMtx () const { USMatrix4x4 wndToWorld; USMatrix4x4 mtx; USRect rect = this->GetViewRect (); float hWidth = rect.Width () * 0.5f; float hHeight = rect.Height () * 0.5f; // Inv Wnd wndToWorld.Translate ( -hWidth - rect.mXMin, -hHeight - rect.mYMin, 0.0f ); mtx.Scale (( 1.0f / hWidth ), -( 1.0f / hHeight ), 1.0f ); wndToWorld.Append ( mtx ); // inv viewproj mtx = this->GetViewProjMtx (); mtx.Inverse (); wndToWorld.Append ( mtx ); return wndToWorld; }
//----------------------------------------------------------------// void MOAITextDesigner::BuildLayout ( MOAITextBox& textBox ) { if ( !textBox.mStyleMap.GetTop ()) return; this->mStr = textBox.mText; this->mIdx = textBox.mCurrentPageIdx; this->mStyleSpan = 0; this->mStyle = 0; int tokenIdx = this->mIdx; int lineIdx = this->mIdx; float width = textBox.mFrame.Width (); float height = textBox.mFrame.Height (); u32 lineStart = 0; u32 lineSize = 0; u32 tokenStart = 0; u32 tokenSize = 0; USRect lineRect; lineRect.Init ( 0.0f, 0.0f, 0.0f, 0.0f ); USRect tokenRect; tokenRect.Init ( 0.0f, 0.0f, 0.0f, 0.0f ); float tokenAscent = 0.0f; float lineAscent = 0.0f; USVec2D pen; pen.Init ( 0.0f, 0.0f ); MOAIGlyph* glyph = 0; MOAIGlyph* prevGlyph = 0; textBox.mMore = true; bool more = true; while ( more ) { u32 c = this->NextChar ( textBox ); float scale = textBox.mGlyphScale * ( this->mStyle ? this->mStyle->mScale : 1.0f ); bool acceptToken = false; bool acceptLine = false; if ( MOAIFont::IsControl ( c )) { if ( c == '\n' ) { tokenIdx = this->mIdx - 1; tokenStart = textBox.mSprites.GetTop (); acceptToken = true; acceptLine = true; if ( !tokenRect.Height ()) { tokenRect.mYMax += this->mDeck->mHeight * scale; } } else if ( c == 0 ) { textBox.mMore = false; tokenIdx = this->mIdx - 1; tokenStart = textBox.mSprites.GetTop (); acceptToken = true; acceptLine = true; more = false; } } else { glyph = this->mDeck->GetGlyph ( c ); if ( !glyph ) continue; if ( glyph->mAdvanceX == 0.0f ) continue; // apply kerning if ( prevGlyph ) { MOAIKernVec kernVec = prevGlyph->GetKerning ( glyph->mCode ); pen.mX += kernVec.mX * scale; } prevGlyph = glyph; if ( MOAIFont::IsWhitespace ( c )) { if ( tokenSize ) { acceptToken = true; } } else { float glyphBottom = pen.mY + ( this->mDeck->mHeight * scale ); // handle new token if ( !tokenSize ) { tokenIdx = this->mIdx - 1; tokenStart = textBox.mSprites.GetTop (); tokenRect.Init ( pen.mX, pen.mY, pen.mX, glyphBottom ); tokenAscent = this->mDeck->mAscent * scale; } // check for overrun float glyphRight = pen.mX + (( glyph->mBearingX + glyph->mWidth ) * scale ); bool overrun = glyphRight > width; acceptLine = ( lineSize && overrun ); if ( acceptLine || !overrun ) { textBox.PushSprite ( this->mIdx - 1, *glyph, *this->mStyle, pen.mX, pen.mY, scale ); tokenRect.mXMax = glyphRight; tokenSize++; } } pen.mX += glyph->mAdvanceX * scale; } if ( acceptToken ) { lineRect.Grow ( tokenRect ); lineSize += tokenSize; lineAscent = tokenAscent > lineAscent ? tokenAscent : lineAscent; tokenSize = 0; } if ( acceptLine ) { textBox.PushLine ( lineStart, lineSize, lineRect, lineAscent ); // end line pen.mY += lineRect.Height () + textBox.mLineSpacing; lineRect.Init ( 0.0f, pen.mY, 0.0f, pen.mY ); // next line lineIdx = tokenIdx; lineStart = tokenStart; lineSize = 0; lineAscent = 0.0f; prevGlyph = 0; if ( tokenSize ){ // slide the current token (if any) back to the origin for ( u32 i = 0; i < tokenSize; ++i ) { MOAITextSprite& sprite = textBox.mSprites [ tokenStart + i ]; sprite.mX -= tokenRect.mXMin; sprite.mY = pen.mY; } pen.mX -= tokenRect.mXMin; tokenRect.Init ( 0.0f, pen.mY, tokenRect.Width (), pen.mY + tokenRect.Height ()); } else { pen.mX = 0.0f; tokenRect.Init ( 0.0f, pen.mY, 0.0f, pen.mY + this->mDeck->mHeight ); } } // if we overrun height, then back up to the start of the current line if ( tokenRect.mYMax > height ) { textBox.mSprites.SetTop ( lineStart ); textBox.mNextPageIdx = lineIdx; more = false; } } if ( textBox.mSprites.GetTop () == 0 ) { textBox.mMore = false; return; } float yOff = textBox.mFrame.mYMin; float layoutHeight = lineRect.mYMax; switch ( textBox.mVAlign ) { case MOAITextBox::CENTER_JUSTIFY: yOff = ( yOff + ( height * 0.5f )) - ( layoutHeight * 0.5f ); case MOAITextBox::LEFT_JUSTIFY: break; case MOAITextBox::RIGHT_JUSTIFY: yOff = textBox.mFrame.mYMax - layoutHeight; } u32 totalLines = textBox.mLines.GetTop (); for ( u32 i = 0; i < totalLines; ++i ) { MOAITextLine& line = textBox.mLines [ i ]; float xOff = textBox.mFrame.mXMin; float lineWidth = line.mRect.Width (); switch ( textBox.mHAlign ) { case MOAITextBox::CENTER_JUSTIFY: xOff = ( xOff + ( width * 0.5f )) - ( lineWidth * 0.5f ); case MOAITextBox::LEFT_JUSTIFY: break; case MOAITextBox::RIGHT_JUSTIFY: xOff = textBox.mFrame.mXMax - lineWidth; } line.mRect.Offset ( xOff, yOff ); float spriteYOff = yOff + line.mAscent; MOAIAnimCurve* curve = 0; if ( textBox.mCurves ) { curve = textBox.mCurves [ i % textBox.mCurves.Size ()]; } for ( u32 j = 0; j < line.mSize; ++j ) { MOAITextSprite& sprite = textBox.mSprites [ line.mStart + j ]; sprite.mX += xOff; if ( curve ) { sprite.mY += spriteYOff + curve->GetFloatValue (( sprite.mX - textBox.mFrame.mXMin ) / width ); } else { sprite.mY += spriteYOff; } } } }
//----------------------------------------------------------------// void MOAIGfxDevice::ResetState () { for ( u32 i = 0; i < TOTAL_VTX_TRANSFORMS; ++i ) { this->mVertexTransforms [ i ].Ident (); } this->mUVTransform.Ident (); this->mCpuVertexTransformMtx.Ident (); this->mBillboardMtx.Ident (); this->mVertexMtxInput = VTX_STAGE_MODEL; this->mVertexMtxOutput = VTX_STAGE_MODEL; this->mTop = 0; this->mPrimCount = 0; // turn off texture #if USE_OPENGLES1 if ( !this->IsProgrammable ()) { glDisable ( GL_TEXTURE_2D ); } #endif this->mTextureUnits [ 0 ] = 0; // turn off blending glDisable ( GL_BLEND ); this->mBlendEnabled = false; // disable backface culling glDisable ( GL_CULL_FACE ); this->mCullFunc = 0; // disable depth test glDisable ( GL_DEPTH_TEST ); this->mDepthFunc = 0; // enable depth write glDepthMask ( true ); this->mDepthMask = true; // clear the vertex format this->SetVertexFormat (); // clear the shader this->mShader = 0; // reset the pen width this->mPenWidth = 1.0f; glLineWidth (( GLfloat )this->mPenWidth ); // reset the point size this->mPointSize = 1.0f; // reset the scissor rect USRect scissorRect = this->mFrameBuffer->GetBufferRect (); glScissor (( int )scissorRect.mXMin, ( int )scissorRect.mYMin, ( int )scissorRect.Width (), ( int )scissorRect.Height ()); this->mScissorRect = scissorRect; // fixed function reset #if USE_OPENGLES1 if ( !this->IsProgrammable ()) { // load identity matrix glMatrixMode ( GL_MODELVIEW ); glLoadIdentity (); glMatrixMode ( GL_PROJECTION ); glLoadIdentity (); glMatrixMode ( GL_TEXTURE ); glLoadIdentity (); // reset the current vertex color glColor4f ( 1.0f, 1.0f, 1.0f, 1.0f ); // reset the point size glPointSize (( GLfloat )this->mPointSize ); } #endif }