void Trigger::renderObject( ObjectRenderInst *ri, SceneRenderState *state, BaseMatInstance *overrideMat ) { if(overrideMat) return; GFXStateBlockDesc desc; desc.setZReadWrite( true, false ); desc.setBlend( true ); // Trigger polyhedrons are set up with outward facing normals and CCW ordering // so can't enable backface culling. desc.setCullMode( GFXCullNone ); GFXTransformSaver saver; MatrixF mat = getRenderTransform(); mat.scale( getScale() ); GFX->multWorld( mat ); GFXDrawUtil *drawer = GFX->getDrawUtil(); drawer->drawPolyhedron( desc, mTriggerPolyhedron, ColorI( 255, 192, 0, 45 ) ); // Render wireframe. desc.setFillModeWireframe(); drawer->drawPolyhedron( desc, mTriggerPolyhedron, ColorI::BLACK ); }
void ForestWindEmitter::_renderEmitterInfo( ObjectRenderInst *ri, SceneRenderState *state, BaseMatInstance *overrideMat ) { if ( overrideMat ) return; GFXTransformSaver saver; GFXDrawUtil *drawer = GFX->getDrawUtil(); AssertFatal( drawer, "Got NULL GFXDrawUtil!" ); const Point3F &pos = getPosition(); const VectorF &windVec = mWind->getDirection(); GFXStateBlockDesc desc; desc.setBlend( true ); desc.setZReadWrite( true, false ); // Draw an arrow pointing // in the wind direction. drawer->drawArrow( desc, pos, pos + (windVec * mWindStrength), ColorI( 0, 0, 255, 255 ) );//Point3F( -235.214, 219.589, 34.0991 ), Point3F( -218.814, 244.731, 37.5587 ), ColorI( 255, 255, 0, 255 ) );// drawer->drawArrow( desc, pos, pos + (mWind->getTarget() * mWindStrength ), ColorI( 255, 0, 0, 85 ) ); // Draw a 2D circle for the wind radius. if ( isRadialEmitter() ) drawer->drawSphere( desc, mWindRadius, pos, ColorI( 255, 0, 0, 80 ) ); }
void SceneSpace::_renderObject( ObjectRenderInst* ri, SceneRenderState* state, BaseMatInstance* overrideMat ) { if( overrideMat ) return; if( !mEditorRenderMaterial ) { // We have no material for rendering so just render // a plain box. GFXTransformSaver saver; MatrixF mat = getRenderTransform(); mat.scale( getScale() ); GFX->multWorld( mat ); GFXStateBlockDesc desc; desc.setZReadWrite( true, false ); desc.setBlend( true ); desc.setCullMode( GFXCullNone ); GFXDrawUtil *drawer = GFX->getDrawUtil(); drawer->drawCube( desc, mObjBox, _getDefaultEditorSolidColor() ); // Render black wireframe. desc.setFillModeWireframe(); drawer->drawCube( desc, mObjBox, _getDefaultEditorWireframeColor() ); } else { //RDTODO } }
void GuiRiverEditorCtrl::_drawRiverControlNodes( River *river, const ColorI &color ) { if ( !River::smShowSpline ) return; RectI bounds = getBounds(); GFXDrawUtil *drawer = GFX->getDrawUtil(); bool isSelected = ( river == mSelRiver ); bool isHighlighted = ( river == mHoverRiver ); for ( U32 i = 0; i < river->mNodes.size(); i++ ) { if ( false && isSelected && mSelNode == i ) continue; const Point3F &wpos = river->mNodes[i].point; Point3F spos; project( wpos, &spos ); if ( spos.z > 1.0f ) continue; Point2I posi; posi.x = spos.x; posi.y = spos.y; if ( !bounds.pointInRect( posi ) ) continue; ColorI theColor = color; Point2I nodeHalfSize = mNodeHalfSize; if ( isHighlighted && mHoverNode == i ) { //theColor = mHoverNodeColor; nodeHalfSize += Point2I(2,2); } if ( isSelected ) { if ( mSelNode == i ) { theColor.set(0,0,255); } else if ( i == 0 ) { theColor.set(0,255,0); } else if ( i == river->mNodes.size() - 1 ) { theColor.set(255,0,0); } } drawer->drawRectFill( posi - nodeHalfSize, posi + nodeHalfSize, theColor ); } }
void Forest::_renderCellBounds( ObjectRenderInst *ri, SceneRenderState *state, BaseMatInstance *overrideMat ) { PROFILE_SCOPE( Forest_RenderCellBounds ); if ( overrideMat ) return; GFXTransformSaver saver; MatrixF projBias(true); const Frustum frustum = GFX->getFrustum(); MathUtils::getZBiasProjectionMatrix( 0.001f, frustum, &projBias ); GFX->setProjectionMatrix( projBias ); VectorF extents; Point3F pos; // Get top level cells Vector<ForestCell*> cellStack; mData->getCells( &cellStack ); // Holds child cells we need to render as we encounter them. Vector<ForestCell*> frontier; GFXDrawUtil *drawer = GFX->getDrawUtil(); GFXStateBlockDesc desc; desc.setZReadWrite( true, false ); desc.setBlend( true ); desc.setFillModeWireframe(); while ( !cellStack.empty() ) { while ( !cellStack.empty() ) { const ForestCell *cell = cellStack.last(); cellStack.pop_back(); Box3F box = cell->getBounds(); drawer->drawCube( desc, box, ColorI( 0, 255, 0 ) ); RectF rect = cell->getRect(); box.minExtents.set( rect.point.x, rect.point.y, box.minExtents.z ); box.maxExtents.set( rect.point.x + rect.extent.x, rect.point.y + rect.extent.y, box.minExtents.z ); drawer->drawCube( desc, box, ColorI::RED ); // If this cell has children, add them to the frontier. if ( !cell->isLeaf() ) cell->getChildren( &frontier ); } // Now the frontier becomes the cellStack and we empty the frontier. cellStack = frontier; frontier.clear(); } }
void NavPath::renderSimple(ObjectRenderInst *ri, SceneRenderState *state, BaseMatInstance *overrideMat) { if(overrideMat) return; if(state->isReflectPass() || !(isSelected() || mAlwaysRender)) return; GFXDrawUtil *drawer = GFX->getDrawUtil(); GFXStateBlockDesc desc; desc.setZReadWrite(true, false); desc.setBlend(true); desc.setCullMode(GFXCullNone); if(isSelected()) { drawer->drawCube(desc, getWorldBox(), ColorI(136, 255, 228, 5)); desc.setFillModeWireframe(); drawer->drawCube(desc, getWorldBox(), ColorI::BLACK); } desc.setZReadWrite(!mXray, false); ColorI pathColour(255, 0, 255); if(!mIsLooping) { desc.setFillModeSolid(); if(mFromSet) drawer->drawCube(desc, Point3F(0.2f, 0.2f, 0.2f), mFrom, pathColour); if(mToSet) drawer->drawCube(desc, Point3F(0.2f, 0.2f, 0.2f), mTo, pathColour); } GFXStateBlockRef sb = GFX->createStateBlock(desc); GFX->setStateBlock(sb); PrimBuild::color3i(pathColour.red, pathColour.green, pathColour.blue); PrimBuild::begin(GFXLineStrip, mPoints.size()); for (U32 i = 0; i < mPoints.size(); i++) PrimBuild::vertex3fv(mPoints[i]); PrimBuild::end(); if(mRenderSearch && getServerObject()) { NavPath *np = static_cast<NavPath*>(getServerObject()); if(np->mQuery && !dtStatusSucceed(np->mStatus)) { duDebugDrawTorque dd; dd.overrideColor(duRGBA(250, 20, 20, 255)); duDebugDrawNavMeshNodes(&dd, *np->mQuery); dd.render(); } } }
void renderSlightlyRaisedBox( const RectI &bounds, GuiControlProfile *profile ) { S32 l = bounds.point.x + 1, r = bounds.point.x + bounds.extent.x - 1; S32 t = bounds.point.y + 1, b = bounds.point.y + bounds.extent.y - 1; GFXDrawUtil *drawer = GFX->getDrawUtil(); drawer->drawRectFill( bounds, profile->mFillColor); drawer->drawLine(l, t, l, b, profile->mBorderColor); drawer->drawLine(l, t, r, t, profile->mBorderColor); drawer->drawLine(l + 1, b, r, b, profile->mBorderColor); drawer->drawLine(r, t + 1, r, b - 1, profile->mBorderColor); }
void TSShapeInstance::renderDebugNodes() { GFXDrawUtil *drawUtil = GFX->getDrawUtil(); ColorI color( 255, 0, 0, 255 ); GFXStateBlockDesc desc; desc.setBlend( false ); desc.setZReadWrite( false, false ); for ( U32 i = 0; i < mNodeTransforms.size(); i++ ) drawUtil->drawTransform( desc, mNodeTransforms[i], NULL, NULL ); }
void GuiDecalEditorCtrl::renderScene(const RectI & updateRect) { PROFILE_SCOPE( GuiDecalEditorCtrl_renderScene ); GFXTransformSaver saver; RectI bounds = getBounds(); ColorI hlColor(0,255,0,255); ColorI regColor(255,0,0,255); ColorI selColor(0,0,255,255); ColorI color; GFXDrawUtil *drawUtil = GFX->getDrawUtil(); GFXStateBlockDesc desc; desc.setBlend( true ); desc.setZReadWrite( true, false ); // Draw 3D stuff here. if ( mSELDecal ) { mGizmo->renderGizmo( mLastCameraQuery.cameraMatrix, mLastCameraQuery.fov ); mSELEdgeVerts.clear(); if ( gDecalManager->clipDecal( mSELDecal, &mSELEdgeVerts ) ) _renderDecalEdge( mSELEdgeVerts, ColorI( 255, 255, 255, 255 ) ); const F32 &decalSize = mSELDecal->mSize; Point3F boxSize( decalSize, decalSize, decalSize ); MatrixF worldMat( true ); mSELDecal->getWorldMatrix( &worldMat, true ); drawUtil->drawObjectBox( desc, boxSize, mSELDecal->mPosition, worldMat, ColorI( 255, 255, 255, 255 ) ); } if ( mHLDecal ) { mHLEdgeVerts.clear(); if ( gDecalManager->clipDecal( mHLDecal, &mHLEdgeVerts ) ) _renderDecalEdge( mHLEdgeVerts, ColorI( 255, 255, 255, 255 ) ); const F32 &decalSize = mHLDecal->mSize; Point3F boxSize( decalSize, decalSize, decalSize ); MatrixF worldMat( true ); mHLDecal->getWorldMatrix( &worldMat, true ); drawUtil->drawObjectBox( desc, boxSize, mHLDecal->mPosition, worldMat, ColorI( 255, 255, 255, 255 ) ); } }
void NavMesh::render(ObjectRenderInst *ri, SceneRenderState *state, BaseMatInstance *overrideMat) { if(overrideMat) return; if(state->isReflectPass()) return; PROFILE_SCOPE(NavMesh_Render); GFXDrawUtil *drawer = GFX->getDrawUtil(); GFXStateBlockDesc desc; desc.setZReadWrite(true, false); desc.setBlend(true); desc.setCullMode(GFXCullNone); drawer->drawCube(desc, getWorldBox(), ColorI(136, 255, 228, 45)); desc.setFillModeWireframe(); drawer->drawCube(desc, getWorldBox(), ColorI::BLACK); // Recast debug draw duDebugDrawTorque dd; NetObject *no = getServerObject(); if(no && isSelected()) { NavMesh *n = static_cast<NavMesh*>(no); RenderMode mode = mRenderMode; bool build = n->mBuilding; if(build) { mode = RENDER_NAVMESH; dd.overrideColour(duRGBA(255, 0, 0, 80)); } n->mNavMeshLock.lock(); switch(mode) { case RENDER_NAVMESH: if(n->nm) duDebugDrawNavMesh (&dd, *n->nm, 0); break; case RENDER_CONTOURS: if(n->cs) duDebugDrawContours (&dd, *n->cs); break; case RENDER_POLYMESH: if(n->pm) duDebugDrawPolyMesh (&dd, *n->pm); break; case RENDER_DETAILMESH: if(n->pmd) duDebugDrawPolyMeshDetail (&dd, *n->pmd); break; case RENDER_PORTALS: if(n->nm) duDebugDrawNavMeshPortals (&dd, *n->nm); break; } if(n->cs && mRenderConnections && !build) duDebugDrawRegionConnections(&dd, *n->cs); if(n->mInPolys && mRenderInput && !build) n->mInPolys->render(); n->mNavMeshLock.unlock(); } }
void GuiDecalEditorCtrl::renderGui( Point2I offset, const RectI &updateRect ) { Parent::renderGui( offset, updateRect ); PROFILE_SCOPE( GuiDecalEditorCtrl_renderGui ); // Show the pixelSize of the selected decal as a text overlay. if ( smRenderDecalPixelSize && mSELDecal != NULL ) { const F32 pixelSize = mSELDecal->calcPixelSize( mSaveViewport.extent.y, mLastCameraQuery.cameraMatrix.getPosition(), mSaveWorldToScreenScale.y ); // Find position onscreen to render the text. Point3F screenPos; bool onScreen = project( mSELDecal->mPosition, &screenPos ); if ( onScreen ) { // It is extremely annoying to require the GuiProfile to have a font // or to create one within the decal editor for only this single use, // so we instead rely on the fact that we already have a Gizmo, that // all Gizmo's have a GizmoProfile, and that GizmoProfile has a font. GFont *font = mGizmo->getProfile()->font; // Might as well use some colors defined in GizmoProfile too instead // of just hardcoding it here. const ColorI bgColor = mGizmo->getProfile()->inActiveColor; const ColorI textColor = mGizmo->getProfile()->activeColor; // Note: This mostly mirrors the way WorldEditor renders popupText for // the gizmo during a drag operation, consider unifying this into a utility method. char buf[256]; dSprintf( buf, 256, "%0.3f", pixelSize ); const U32 width = font->getStrWidth((const UTF8 *)buf);; const Point2I posi( (U32)screenPos.x, (U32)screenPos.y + 12 ); const Point2I minPt(posi.x - width / 2 - 2, posi.y - 1); const Point2I maxPt(posi.x + width / 2 + 2, posi.y + font->getHeight() + 1); GFXDrawUtil *drawer = GFX->getDrawUtil(); drawer->drawRectFill( minPt, maxPt, bgColor ); GFX->getDrawUtil()->setBitmapModulation( textColor ); GFX->getDrawUtil()->drawText( mProfile->mFont, Point2I( posi.x - width / 2, posi.y ), buf ); } } }
void ForestWindEmitter::_renderEmitterInfo( ObjectRenderInst *ri, SceneRenderState *state, BaseMatInstance *overrideMat ) { if ( overrideMat ) return; GFXTransformSaver saver; GFXDrawUtil *drawer = GFX->getDrawUtil(); AssertFatal( drawer, "Got NULL GFXDrawUtil!" ); const Point3F &pos = getPosition(); const VectorF &windVec = mWind->getDirection(); GFXStateBlockDesc desc; desc.setBlend( true ); desc.setZReadWrite( true, false ); // Draw an arrow pointing // in the wind direction. drawer->drawArrow( desc, pos, pos + (windVec * mWindStrength), ColorI( 0, 0, 255, 255 ) );//Point3F( -235.214, 219.589, 34.0991 ), Point3F( -218.814, 244.731, 37.5587 ), ColorI( 255, 255, 0, 255 ) );// drawer->drawArrow( desc, pos, pos + (mWind->getTarget() * mWindStrength ), ColorI( 255, 0, 0, 85 ) ); S32 useRadius = mWindRadius; // Draw a 2D circle for the wind radius. if ( isRadialEmitter() ) { //WLE - Vince //So the problem is that when your inside the sphere it won't render so it might make someone //think that it's not working right. So what I did was determine if the camera is inside the sphere. //If the camera is inside the sphere, then I find the distance from the center of the sphere to the camera //Round down and use that as the radius to draw the sphere. //That way if someone zooms in or out, their screen is still showing the sphere. GameConnection * gc = GameConnection::getConnectionToServer(); GameBase* gb = gc->getCameraObject(); if (gb) { Point3F camPos = gb->getPosition(); if ( getPosition().isInsideSphere( camPos, mWindRadius ) ) useRadius = getPosition().distanceTo(camPos); } drawer->drawSphere( desc, useRadius, pos, ColorI( 255, 0, 0, 80 ) ); } }
void EditTSCtrl::renderMissionArea() { MissionArea* obj = MissionArea::getServerObject(); if ( !obj ) return; if ( !mRenderMissionArea && !obj->isSelected() ) return; GFXDEBUGEVENT_SCOPE( Editor_renderMissionArea, ColorI::WHITE ); F32 minHeight = 0.0f; F32 maxHeight = 0.0f; TerrainBlock* terrain = getActiveTerrain(); if ( terrain ) { terrain->getMinMaxHeight( &minHeight, &maxHeight ); Point3F pos = terrain->getPosition(); maxHeight += pos.z + mMissionAreaHeightAdjust; minHeight += pos.z - mMissionAreaHeightAdjust; } const RectI& area = obj->getArea(); Box3F areaBox( area.point.x, area.point.y, minHeight, area.point.x + area.extent.x, area.point.y + area.extent.y, maxHeight ); GFXDrawUtil* drawer = GFX->getDrawUtil(); GFXStateBlockDesc desc; desc.setCullMode( GFXCullNone ); desc.setBlend( true ); desc.setZReadWrite( false, false ); desc.setFillModeSolid(); drawer->drawCube( desc, areaBox, mMissionAreaFillColor ); desc.setFillModeWireframe(); drawer->drawCube( desc, areaBox, mMissionAreaFrameColor ); }
// Render out the fixed bitmap borders based on a multiplier into the bitmap array // It renders left and right caps, with a sizable fill area in the middle to reach // the x extent. It does not stretch in the y direction. void renderFixedBitmapBordersFilled( const RectI &bounds, S32 baseMultiplier, GuiControlProfile *profile ) { // Indices into the bitmap array S32 numBitmaps = 3; S32 borderLeft = numBitmaps * baseMultiplier - numBitmaps; S32 fill = 1 + borderLeft; S32 borderRight = 2 + borderLeft; GFXDrawUtil *drawer = GFX->getDrawUtil(); drawer->clearBitmapModulation(); if(profile->mBitmapArrayRects.size() >= (numBitmaps * baseMultiplier)) { RectI destRect; RectI stretchRect; RectI* mBitmapBounds = profile->mBitmapArrayRects.address(); // Draw all corners first. //left border drawer->drawBitmapSR(profile->mTextureObject,Point2I(bounds.point.x,bounds.point.y),mBitmapBounds[borderLeft]); //right border drawer->drawBitmapSR(profile->mTextureObject,Point2I(bounds.point.x + bounds.extent.x - mBitmapBounds[borderRight].extent.x,bounds.point.y),mBitmapBounds[borderRight]); // End drawing corners // Begin drawing fill //fill stretch destRect.point.x = bounds.point.x + mBitmapBounds[borderLeft].extent.x; destRect.extent.x = (bounds.extent.x) - mBitmapBounds[borderLeft].extent.x - mBitmapBounds[borderRight].extent.x; destRect.extent.y = mBitmapBounds[fill].extent.y; destRect.point.y = bounds.point.y; //stretch it stretchRect = mBitmapBounds[fill]; stretchRect.inset(1,0); //draw it drawer->drawBitmapStretchSR(profile->mTextureObject,destRect,stretchRect); // End drawing fill } }
void GuiTheoraCtrl::onRender(Point2I offset, const RectI &updateRect) { if( mDone && mIsLooping ) mTheoraTexture.play(); const RectI rect(offset, getBounds().extent); if( mTheoraTexture.isReady() ) { mTheoraTexture.refresh(); if( mTheoraTexture.isPlaying() || mTheoraTexture.isPaused() ) { // Draw the frame. GFXDrawUtil* drawUtil = GFX->getDrawUtil(); drawUtil->clearBitmapModulation(); drawUtil->drawBitmapStretch( mTheoraTexture.getTexture(), rect ); // Draw frame info, if requested. if( mRenderDebugInfo ) { String info = String::ToString( "Frame Number: %i | Frame Time: %.2fs | Playback Time: %.2fs | Dropped: %i", mTheoraTexture.getFrameNumber(), mTheoraTexture.getFrameTime(), F32( mTheoraTexture.getPosition() ) / 1000.f, mTheoraTexture.getNumDroppedFrames() ); drawUtil->setBitmapModulation( mProfile->mFontColors[ 0 ] ); drawUtil->drawText( mProfile->mFont, localToGlobalCoord( Point2I( 0, 0 ) ), info, mProfile->mFontColors ); } } else mDone = true; } else GFX->getDrawUtil()->drawRectFill(rect, mBackgroundColor); // black rect renderChildControls(offset, updateRect); }
void GuiSwatchButtonCtrl::onRender( Point2I offset, const RectI &updateRect ) { bool highlight = mMouseOver; ColorI borderColor = mActive ? ( highlight ? mProfile->mBorderColorHL : mProfile->mBorderColor ) : mProfile->mBorderColorNA; RectI renderRect( offset, getExtent() ); if ( !highlight ) renderRect.inset( 1, 1 ); GFXDrawUtil *drawer = GFX->getDrawUtil(); drawer->clearBitmapModulation(); // Draw background transparency grid texture... if ( mGrid.isValid() ) drawer->drawBitmapStretch( mGrid, renderRect ); // Draw swatch color as fill... if (!mUseSRGB) drawer->drawRectFill( renderRect, mSwatchColor.toGamma() ); else drawer->drawRectFill(renderRect, mSwatchColor); // Draw any borders... drawer->drawRect( renderRect, borderColor ); }
void ForestWindEmitter::_renderEmitterInfo( ObjectRenderInst *ri, SceneRenderState *state, BaseMatInstance *overrideMat ) { if ( overrideMat ) return; GFXTransformSaver saver; GFXDrawUtil *drawer = GFX->getDrawUtil(); AssertFatal( drawer, "Got NULL GFXDrawUtil!" ); const Point3F &pos = getPosition(); const VectorF &windVec = mWind->getDirection(); GFXStateBlockDesc desc; desc.setBlend( true ); desc.setZReadWrite( true, false ); // Draw an arrow pointing // in the wind direction. drawer->drawArrow( desc, pos, pos + (windVec * mWindStrength), ColorI( 0, 0, 255, 255 ) );//Point3F( -235.214, 219.589, 34.0991 ), Point3F( -218.814, 244.731, 37.5587 ), ColorI( 255, 255, 0, 255 ) );// drawer->drawArrow( desc, pos, pos + (mWind->getTarget() * mWindStrength ), ColorI( 255, 0, 0, 85 ) ); S32 useRadius = mWindRadius; // Draw a 2D circle for the wind radius. if ( isRadialEmitter() ) { // If the camera is close to the sphere, shrink the sphere so it remains visible. GameConnection* gc = GameConnection::getConnectionToServer(); GameBase* gb; if ( gc && (gb = gc->getCameraObject()) ) { F32 camDist = (gb->getPosition() - getPosition()).len(); if ( camDist < mWindRadius ) useRadius = camDist; } drawer->drawSphere( desc, useRadius, pos, ColorI( 255, 0, 0, 80 ) ); } }
void DecalManager::renderDecalSpheres() { if ( mData && Con::getBoolVariable( "$renderSpheres" ) ) { PROFILE_SCOPE( DecalManager_renderDecalSpheres ); const Vector<DecalSphere*> &grid = mData->getGrid(); GFXDrawUtil *drawUtil = GFX->getDrawUtil(); ColorI sphereLineColor( 0, 255, 0, 25 ); ColorI sphereColor( 0, 0, 255, 30 ); GFXStateBlockDesc desc; desc.setBlend( true ); desc.setZReadWrite( true, false ); for ( U32 i = 0; i < grid.size(); i++ ) { DecalSphere *decalSphere = grid[i]; const SphereF &worldSphere = decalSphere->mWorldSphere; drawUtil->drawSphere( desc, worldSphere.radius, worldSphere.center, sphereColor ); } } }
void SFXEmitter::_renderObject( ObjectRenderInst* ri, SceneRenderState* state, BaseMatInstance* overrideMat ) { // Check to see if the emitter is in range and playing // and assign a proper color depending on this. ColorI color; if( _getPlaybackStatus() == SFXStatusPlaying ) { if( isInRange() ) color = smRenderColorPlayingInRange; else color = smRenderColorPlayingOutOfRange; } else { if( isInRange() ) color = smRenderColorStoppedInRange; else color = smRenderColorStoppedOutOfRange; } // Draw the cube. GFXStateBlockDesc desc; desc.setZReadWrite( true, false ); desc.setBlend( true ); desc.setCullMode( GFXCullNone ); GFXDrawUtil *drawer = GFX->getDrawUtil(); drawer->drawCube( desc, Point3F( 0.5f, 0.5f, 0.5f ), getBoxCenter(), color ); // Render visual feedback for 3D sounds. if( ( smRenderEmitters || isSelected() ) && is3D() ) _render3DVisualFeedback(); }
void renderLoweredBox( const RectI &bounds, GuiControlProfile *profile ) { S32 l = bounds.point.x, r = bounds.point.x + bounds.extent.x - 1; S32 t = bounds.point.y, b = bounds.point.y + bounds.extent.y - 1; GFXDrawUtil* drawUtil = GFX->getDrawUtil(); drawUtil->drawRectFill( bounds, profile->mFillColor); drawUtil->drawLine(l, b, r, b, colorWhite); drawUtil->drawLine(r, b - 1, r, t, colorWhite); drawUtil->drawLine(l, t, r - 1, t, colorBlack); drawUtil->drawLine(l, t + 1, l, b - 1, colorBlack); drawUtil->drawLine(l + 1, t + 1, r - 2, t + 1, profile->mBorderColor); drawUtil->drawLine(l + 1, t + 2, l + 1, b - 2, profile->mBorderColor); }
void GuiInspectorField::onRender( Point2I offset, const RectI &updateRect ) { RectI ctrlRect(offset, getExtent()); // Render fillcolor... if ( mProfile->mOpaque ) GFX->getDrawUtil()->drawRectFill(ctrlRect, mProfile->mFillColor); // Render caption... if ( mCaption && mCaption[0] ) { // Backup current ClipRect RectI clipBackup = GFX->getClipRect(); RectI clipRect = updateRect; // The rect within this control in which our caption must fit. RectI rect( offset + mCaptionRect.point + mProfile->mTextOffset, mCaptionRect.extent + Point2I(1,1) - Point2I(5,0) ); // Now clipRect is the amount of our caption rect that is actually visible. bool hit = clipRect.intersect( rect ); if ( hit ) { GFX->setClipRect( clipRect ); GFXDrawUtil *drawer = GFX->getDrawUtil(); // Backup modulation color ColorI currColor; drawer->getBitmapModulation( &currColor ); // Draw caption background... if( !isActive() ) GFX->getDrawUtil()->drawRectFill( clipRect, mProfile->mFillColorNA ); else if ( mHighlighted ) GFX->getDrawUtil()->drawRectFill( clipRect, mProfile->mFillColorHL ); // Draw caption text... drawer->setBitmapModulation( !isActive() ? mProfile->mFontColorNA : mHighlighted ? mProfile->mFontColorHL : mProfile->mFontColor ); // Clip text with '...' if too long to fit String clippedText( mCaption ); clipText( clippedText, clipRect.extent.x ); renderJustifiedText( offset + mProfile->mTextOffset, getExtent(), clippedText ); // Restore modulation color drawer->setBitmapModulation( currColor ); // Restore previous ClipRect GFX->setClipRect( clipBackup ); } } // Render Children... renderChildControls(offset, updateRect); // Render border... if ( mProfile->mBorder ) renderBorder(ctrlRect, mProfile); // Render divider... Point2I worldPnt = mEditCtrlRect.point + offset; GFX->getDrawUtil()->drawLine( worldPnt.x - 5, worldPnt.y, worldPnt.x - 5, worldPnt.y + getHeight(), !isActive() ? mProfile->mBorderColorNA : mHighlighted ? mProfile->mBorderColorHL : mProfile->mBorderColor ); }
void Forest::prepRenderImage( SceneRenderState *state ) { PROFILE_SCOPE(Forest_RenderCells); // TODO: Fix stats. /* ForestCellVector &theCells = mData->getCells(); smTotalCells += theCells.size(); // Don't render if we don't have a grid! if ( theCells.empty() ) return false; */ // Prepare to render. GFXTransformSaver saver; // Figure out the grid range in the viewing area. const bool isReflectPass = state->isReflectPass(); const F32 cullScale = isReflectPass ? mReflectionLodScalar : 1.0f; // If we need to update our cached // zone state then do it now. if ( mZoningDirty ) { mZoningDirty = false; Vector<ForestCell*> cells; mData->getCells( &cells ); for ( U32 i=0; i < cells.size(); i++ ) cells[i]->_updateZoning( getSceneManager()->getZoneManager() ); } // TODO: Move these into the TSForestItemData as something we // setup once and don't do per-instance. // Set up the TS render state. TSRenderState rdata; rdata.setSceneState( state ); // Use origin sort on all forest elements as // its alot cheaper than the bounds sort. rdata.setOriginSort( true ); // We may have some forward lit materials in // the forest, so pass down a LightQuery for it. LightQuery lightQuery; rdata.setLightQuery( &lightQuery ); Frustum culler = state->getFrustum(); // Adjust the far distance if the cull scale has changed. if ( !mIsEqual( cullScale, 1.0f ) ) { const F32 visFarDist = culler.getFarDist() * cullScale; culler.setFarDist( visFarDist ); } Box3F worldBox; // Used for debug drawing. GFXDrawUtil* drawer = GFX->getDrawUtil(); drawer->clearBitmapModulation(); // Go thru the visible cells. const Box3F &cullerBounds = culler.getBounds(); const Point3F &camPos = state->getDiffuseCameraPosition(); U32 clipMask; smAverageItemsPerCell = 0.0f; U32 cellsProcessed = 0; ForestCell *cell; // First get all the top level cells which // intersect the frustum. Vector<ForestCell*> cellStack; mData->getCells( culler, &cellStack ); // Get the culling zone state. const BitVector &zoneState = state->getCullingState().getZoneVisibilityFlags(); // Now loop till we run out of cells. while ( !cellStack.empty() ) { // Pop off the next cell. cell = cellStack.last(); cellStack.pop_back(); const Box3F &cellBounds = cell->getBounds(); // If the cell is empty or its bounds is outside the frustum // bounds then we have nothing nothing more to do. if ( cell->isEmpty() || !cullerBounds.isOverlapped( cellBounds ) ) continue; // Can we cull this cell entirely? clipMask = culler.testPlanes( cellBounds, Frustum::PlaneMaskAll ); if ( clipMask == -1 ) continue; // Test cell visibility for interior zones. const bool visibleInside = !cell->getZoneOverlap().empty() ? zoneState.testAny( cell->getZoneOverlap() ) : false; // Test cell visibility for outdoor zone, but only // if we need to. bool visibleOutside = false; if( !cell->mIsInteriorOnly && !visibleInside ) { U32 outdoorZone = SceneZoneSpaceManager::RootZoneId; visibleOutside = !state->getCullingState().isCulled( cellBounds, &outdoorZone, 1 ); } // Skip cell if neither visible indoors nor outdoors. if( !visibleInside && !visibleOutside ) continue; // Update the stats. smAverageItemsPerCell += cell->getItems().size(); ++cellsProcessed; //if ( cell->isLeaf() ) //++leafCellsProcessed; // Get the distance from the camera to the cell bounds. F32 dist = cellBounds.getDistanceToPoint( camPos ); // If the largest item in the cell can be billboarded // at the cell distance to the camera... then the whole // cell can be billboarded. // if ( smForceImposters || ( dist > 0.0f && cell->getLargestItem().canBillboard( state, dist ) ) ) { // If imposters are disabled then skip out. if ( smDisableImposters ) continue; PROFILE_SCOPE(Forest_RenderBatches); // Keep track of how many cells were batched. ++smCellsBatched; // Ok... everything in this cell should be batched. First // create the batches if we don't have any. if ( !cell->hasBatches() ) cell->buildBatches(); //if ( drawCells ) //mCellRenderFlag[ cellIter - theCells.begin() ] = 1; // TODO: Light queries for batches? // Now render the batches... we pass the culler if the // cell wasn't fully visible so that each batch can be culled. smCellItemsBatched += cell->renderBatches( state, clipMask != 0 ? &culler : NULL ); continue; } // If this isn't a leaf then recurse. if ( !cell->isLeaf() ) { cell->getChildren( &cellStack ); continue; } // This cell has mixed billboards and mesh based items. ++smCellsRendered; PROFILE_SCOPE(Forest_RenderItems); //if ( drawCells ) //mCellRenderFlag[ cellIter - theCells.begin() ] = 2; // Use the cell bounds as the light query volume. // // This means all forward lit items in this cell will // get the same lights, but it performs much better. lightQuery.init( cellBounds ); // This cell is visible... have it render its items. smCellItemsRendered += cell->render( &rdata, clipMask != 0 ? &culler : NULL ); } // Keep track of the average items per cell. if ( cellsProcessed > 0 ) smAverageItemsPerCell /= (F32)cellsProcessed; // Got debug drawing to do? if ( smDrawCells && state->isDiffusePass() ) { ObjectRenderInst *ri = state->getRenderPass()->allocInst<ObjectRenderInst>(); ri->renderDelegate.bind( this, &Forest::_renderCellBounds ); ri->type = RenderPassManager::RIT_Editor; state->getRenderPass()->addInst( ri ); } }
void ConvexShape::_renderDebug( ObjectRenderInst *ri, SceneRenderState *state, BaseMatInstance *mat ) { GFXDrawUtil *drawer = GFX->getDrawUtil(); GFX->setTexture( 0, NULL ); // Render world box. if ( false ) { Box3F wbox( mWorldBox ); //if ( getServerObject() ) // Box3F wbox = static_cast<ConvexShape*>( getServerObject() )->mWorldBox; GFXStateBlockDesc desc; desc.setCullMode( GFXCullNone ); desc.setFillModeWireframe(); drawer->drawCube( desc, wbox, ColorI::RED ); } const Vector< Point3F > &pointList = mGeometry.points; const Vector< ConvexShape::Face > &faceList = mGeometry.faces; // Render Edges. if ( false ) { GFXTransformSaver saver; //GFXFrustumSaver fsaver; MatrixF xfm( getRenderTransform() ); xfm.scale( getScale() ); GFX->multWorld( xfm ); GFXStateBlockDesc desc; desc.setZReadWrite( true, false ); desc.setBlend( true ); GFX->setStateBlockByDesc( desc ); //MathUtils::getZBiasProjectionMatrix( 0.01f, state->getFrustum(), ) const Point3F &camFvec = state->getCameraTransform().getForwardVector(); for ( S32 i = 0; i < faceList.size(); i++ ) { const ConvexShape::Face &face = faceList[i]; const Vector< ConvexShape::Edge > &edgeList = face.edges; const Vector< U32 > &facePntList = face.points; PrimBuild::begin( GFXLineList, edgeList.size() * 2 ); PrimBuild::color( ColorI::WHITE * 0.8f ); for ( S32 j = 0; j < edgeList.size(); j++ ) { PrimBuild::vertex3fv( pointList[ facePntList[ edgeList[j].p0 ] ] - camFvec * 0.001f ); PrimBuild::vertex3fv( pointList[ facePntList[ edgeList[j].p1 ] ] - camFvec * 0.001f ); } PrimBuild::end(); } } ColorI faceColorsx[4] = { ColorI( 255, 0, 0 ), ColorI( 0, 255, 0 ), ColorI( 0, 0, 255 ), ColorI( 255, 0, 255 ) }; MatrixF objToWorld( mObjToWorld ); objToWorld.scale( mObjScale ); // Render faces centers/colors. if ( false ) { GFXStateBlockDesc desc; desc.setCullMode( GFXCullNone ); Point3F size( 0.1f ); for ( S32 i = 0; i < faceList.size(); i++ ) { ColorI color = faceColorsx[ i % 4 ]; S32 div = ( i / 4 ) * 4; if ( div > 0 ) color /= div; color.alpha = 255; Point3F pnt; objToWorld.mulP( faceList[i].centroid, &pnt ); drawer->drawCube( desc, size, pnt, color, NULL ); } } // Render winding order. if ( false ) { GFXStateBlockDesc desc; desc.setCullMode( GFXCullNone ); desc.setZReadWrite( true, false ); GFX->setStateBlockByDesc( desc ); U32 pointCount = 0; for ( S32 i = 0; i < faceList.size(); i++ ) pointCount += faceList[i].winding.size(); PrimBuild::begin( GFXLineList, pointCount * 2 ); for ( S32 i = 0; i < faceList.size(); i++ ) { for ( S32 j = 0; j < faceList[i].winding.size(); j++ ) { Point3F p0 = pointList[ faceList[i].points[ faceList[i].winding[j] ] ]; Point3F p1 = p0 + mSurfaces[ faceList[i].id ].getUpVector() * 0.75f * ( Point3F::One / mObjScale ); objToWorld.mulP( p0 ); objToWorld.mulP( p1 ); ColorI color = faceColorsx[ j % 4 ]; S32 div = ( j / 4 ) * 4; if ( div > 0 ) color /= div; color.alpha = 255; PrimBuild::color( color ); PrimBuild::vertex3fv( p0 ); PrimBuild::color( color ); PrimBuild::vertex3fv( p1 ); } } PrimBuild::end(); } // Render Points. if ( false ) { /* GFXTransformSaver saver; MatrixF xfm( getRenderTransform() ); xfm.scale( getScale() ); GFX->multWorld( xfm ); GFXStateBlockDesc desc; Point3F size( 0.05f ); */ } // Render surface transforms. if ( false ) { GFXStateBlockDesc desc; desc.setBlend( false ); desc.setZReadWrite( true, true ); Point3F scale(mNormalLength); for ( S32 i = 0; i < mSurfaces.size(); i++ ) { MatrixF objToWorld( mObjToWorld ); objToWorld.scale( mObjScale ); MatrixF renderMat; renderMat.mul( objToWorld, mSurfaces[i] ); renderMat.setPosition( renderMat.getPosition() + renderMat.getUpVector() * 0.001f ); drawer->drawTransform( desc, renderMat, &scale, NULL ); } } }
// Render out the sizable bitmap borders based on a multiplier into the bitmap array // Based on the 'Skinnable GUI Controls in TGE' resource by Justin DuJardin void renderSizableBitmapBordersFilledIndex( const RectI &bounds, S32 startIndex, GuiControlProfile *profile ) { // Indices into the bitmap array S32 numBitmaps = 9; S32 borderTopLeft = startIndex; S32 borderTop = 1 + borderTopLeft; S32 borderTopRight = 2 + borderTopLeft; S32 borderLeft = 3 + borderTopLeft; S32 fill = 4 + borderTopLeft; S32 borderRight = 5 + borderTopLeft; S32 borderBottomLeft = 6 + borderTopLeft; S32 borderBottom = 7 + borderTopLeft; S32 borderBottomRight = 8 + borderTopLeft; GFXDrawUtil *drawer = GFX->getDrawUtil(); drawer->clearBitmapModulation(); if(profile->mBitmapArrayRects.size() >= (startIndex + numBitmaps)) { RectI destRect; RectI stretchRect; RectI* mBitmapBounds = profile->mBitmapArrayRects.address(); // Draw all corners first. //top left border drawer->drawBitmapSR(profile->mTextureObject,Point2I(bounds.point.x,bounds.point.y),mBitmapBounds[borderTopLeft]); //top right border drawer->drawBitmapSR(profile->mTextureObject,Point2I(bounds.point.x + bounds.extent.x - mBitmapBounds[borderTopRight].extent.x,bounds.point.y),mBitmapBounds[borderTopRight]); //bottom left border drawer->drawBitmapSR(profile->mTextureObject,Point2I(bounds.point.x,bounds.point.y + bounds.extent.y - mBitmapBounds[borderBottomLeft].extent.y),mBitmapBounds[borderBottomLeft]); //bottom right border drawer->drawBitmapSR(profile->mTextureObject,Point2I( bounds.point.x + bounds.extent.x - mBitmapBounds[borderBottomRight].extent.x, bounds.point.y + bounds.extent.y - mBitmapBounds[borderBottomRight].extent.y), mBitmapBounds[borderBottomRight]); // End drawing corners // Begin drawing sides and top stretched borders //start with top line stretch destRect.point.x = bounds.point.x + mBitmapBounds[borderTopLeft].extent.x; destRect.extent.x = bounds.extent.x - mBitmapBounds[borderTopRight].extent.x - mBitmapBounds[borderTopLeft].extent.x; destRect.extent.y = mBitmapBounds[borderTop].extent.y; destRect.point.y = bounds.point.y; //stretch it stretchRect = mBitmapBounds[borderTop]; stretchRect.inset(1,0); //draw it drawer->drawBitmapStretchSR(profile->mTextureObject,destRect,stretchRect); //bottom line stretch destRect.point.x = bounds.point.x + mBitmapBounds[borderBottomLeft].extent.x; destRect.extent.x = bounds.extent.x - mBitmapBounds[borderBottomRight].extent.x - mBitmapBounds[borderBottomLeft].extent.x; destRect.extent.y = mBitmapBounds[borderBottom].extent.y; destRect.point.y = bounds.point.y + bounds.extent.y - mBitmapBounds[borderBottom].extent.y; //stretch it stretchRect = mBitmapBounds[borderBottom]; stretchRect.inset(1,0); //draw it drawer->drawBitmapStretchSR(profile->mTextureObject,destRect,stretchRect); //left line stretch destRect.point.x = bounds.point.x; destRect.extent.x = mBitmapBounds[borderLeft].extent.x; destRect.extent.y = bounds.extent.y - mBitmapBounds[borderTopLeft].extent.y - mBitmapBounds[borderBottomLeft].extent.y; destRect.point.y = bounds.point.y + mBitmapBounds[borderTopLeft].extent.y; //stretch it stretchRect = mBitmapBounds[borderLeft]; stretchRect.inset(0,1); //draw it drawer->drawBitmapStretchSR(profile->mTextureObject,destRect,stretchRect); //left line stretch destRect.point.x = bounds.point.x + bounds.extent.x - mBitmapBounds[borderRight].extent.x; destRect.extent.x = mBitmapBounds[borderRight].extent.x; destRect.extent.y = bounds.extent.y - mBitmapBounds[borderTopRight].extent.y - mBitmapBounds[borderBottomRight].extent.y; destRect.point.y = bounds.point.y + mBitmapBounds[borderTopRight].extent.y; //stretch it stretchRect = mBitmapBounds[borderRight]; stretchRect.inset(0,1); //draw it drawer->drawBitmapStretchSR(profile->mTextureObject,destRect,stretchRect); //fill stretch destRect.point.x = bounds.point.x + mBitmapBounds[borderLeft].extent.x; destRect.extent.x = (bounds.extent.x) - mBitmapBounds[borderLeft].extent.x - mBitmapBounds[borderRight].extent.x; destRect.extent.y = bounds.extent.y - mBitmapBounds[borderTop].extent.y - mBitmapBounds[borderBottom].extent.y; destRect.point.y = bounds.point.y + mBitmapBounds[borderTop].extent.y; //stretch it stretchRect = mBitmapBounds[fill]; stretchRect.inset(1,1); //draw it drawer->drawBitmapStretchSR(profile->mTextureObject,destRect,stretchRect); // End drawing sides and top stretched borders } }
void drawActor( NxActor *inActor ) { GFXDrawUtil *drawer = GFX->getDrawUtil(); //drawer->setZRead( false ); // Determine alpha we render shapes with. const U8 enabledAlpha = 255; const U8 disabledAlpha = 100; U8 renderAlpha = inActor->readActorFlag( NX_AF_DISABLE_COLLISION ) ? disabledAlpha : enabledAlpha; // Determine color we render actors and shapes with. ColorI actorColor( 0, 0, 255, 200 ); ColorI shapeColor = ( inActor->isSleeping() ? ColorI( 0, 0, 255, renderAlpha ) : ColorI( 255, 0, 255, renderAlpha ) ); MatrixF actorMat(true); inActor->getGlobalPose().getRowMajor44( actorMat ); GFXStateBlockDesc desc; desc.setBlend( true ); desc.setZReadWrite( true, false ); desc.setCullMode( GFXCullNone ); // Draw an xfm gizmo for the actor's globalPose... //drawer->drawTransform( desc, actorMat, Point3F::One, actorColor ); // Loop through and render all the actor's shapes.... NxShape *const*pShapeArray = inActor->getShapes(); U32 numShapes = inActor->getNbShapes(); for ( U32 i = 0; i < numShapes; i++ ) { const NxShape *shape = pShapeArray[i]; Point3F shapePos = pxCast<Point3F>( shape->getGlobalPosition() ); MatrixF shapeMat(true); shape->getGlobalPose().getRowMajor44(shapeMat); shapeMat.setPosition( Point3F::Zero ); switch ( shape->getType() ) { case NX_SHAPE_SPHERE: { NxSphereShape *sphere = (NxSphereShape*)shape; drawer->drawSphere( desc, sphere->getRadius(), shapePos, shapeColor ); break; } case NX_SHAPE_BOX: { NxBoxShape *box = (NxBoxShape*)shape; Point3F size = pxCast<Point3F>( box->getDimensions() ); drawer->drawCube( desc, size*2, shapePos, shapeColor, &shapeMat ); break; } case NX_SHAPE_CAPSULE: { shapeMat.mul( MatrixF( EulerF( mDegToRad(90.0f), mDegToRad(90.0f), 0 ) ) ); NxCapsuleShape *capsule = (NxCapsuleShape*)shape; drawer->drawCapsule( desc, shapePos, capsule->getRadius(), capsule->getHeight(), shapeColor, &shapeMat ); break; } default: { break; } } } //drawer->clearZDefined(); }
void GuiProgressBitmapCtrl::onRender(Point2I offset, const RectI &updateRect) { RectI ctrlRect(offset, getExtent()); //grab lowest dimension if(getHeight() <= getWidth()) mDim = getHeight(); else mDim = getWidth(); GFXDrawUtil* drawUtil = GFX->getDrawUtil(); drawUtil->clearBitmapModulation(); if(mNumberOfBitmaps == 1) { //draw the progress with image S32 width = (S32)((F32)(getWidth()) * mProgress); if (width > 0) { //drawing stretch bitmap RectI progressRect = ctrlRect; progressRect.extent.x = width; drawUtil->drawBitmapStretchSR(mProfile->mTextureObject, progressRect, mProfile->mBitmapArrayRects[0]); } } else if(mNumberOfBitmaps >= 3) { //drawing left-end bitmap RectI progressRectLeft(ctrlRect.point.x, ctrlRect.point.y, mDim, mDim); drawUtil->drawBitmapStretchSR(mProfile->mTextureObject, progressRectLeft, mProfile->mBitmapArrayRects[0]); //draw the progress with image S32 width = (S32)((F32)(getWidth()) * mProgress); if (width > mDim) { //drawing stretch bitmap RectI progressRect = ctrlRect; progressRect.point.x += mDim; progressRect.extent.x = (width - mDim - mDim); if (progressRect.extent.x < 0) progressRect.extent.x = 0; drawUtil->drawBitmapStretchSR(mProfile->mTextureObject, progressRect, mProfile->mBitmapArrayRects[1]); //drawing right-end bitmap RectI progressRectRight(progressRect.point.x + progressRect.extent.x, ctrlRect.point.y, mDim, mDim ); drawUtil->drawBitmapStretchSR(mProfile->mTextureObject, progressRectRight, mProfile->mBitmapArrayRects[2]); } } else Con::warnf("guiProgressBitmapCtrl only processes an array of bitmaps == 1 or >= 3"); //if there's a border, draw it if (mProfile->mBorder) drawUtil->drawRect(ctrlRect, mProfile->mBorderColor); Parent::onRender( offset, updateRect ); //render the children renderChildControls(offset, updateRect); }
void renderBorder( const RectI &bounds, GuiControlProfile *profile ) { S32 l = bounds.point.x, r = bounds.point.x + bounds.extent.x - 1; S32 t = bounds.point.y, b = bounds.point.y + bounds.extent.y - 1; GFXDrawUtil *drawer = GFX->getDrawUtil(); switch(profile->mBorder) { case 1: drawer->drawRect(bounds, profile->mBorderColor); break; case 2: drawer->drawLine(l + 1, t + 1, l + 1, b - 2, profile->mBevelColorHL); drawer->drawLine(l + 2, t + 1, r - 2, t + 1, profile->mBevelColorHL); drawer->drawLine(r, t, r, b, profile->mBevelColorHL); drawer->drawLine(l, b, r - 1, b, profile->mBevelColorHL); drawer->drawLine(l, t, r - 1, t, profile->mBorderColorNA); drawer->drawLine(l, t + 1, l, b - 1, profile->mBorderColorNA); drawer->drawLine(l + 1, b - 1, r - 1, b - 1, profile->mBorderColorNA); drawer->drawLine(r - 1, t + 1, r - 1, b - 2, profile->mBorderColorNA); break; case 3: drawer->drawLine(l, b, r, b, profile->mBevelColorHL); drawer->drawLine(r, t, r, b - 1, profile->mBevelColorHL); drawer->drawLine(l + 1, b - 1, r - 1, b - 1, profile->mFillColor); drawer->drawLine(r - 1, t + 1, r - 1, b - 2, profile->mFillColor); drawer->drawLine(l, t, l, b - 1, profile->mBorderColorNA); drawer->drawLine(l + 1, t, r - 1, t, profile->mBorderColorNA); drawer->drawLine(l + 1, t + 1, l + 1, b - 2, profile->mBevelColorLL); drawer->drawLine(l + 2, t + 1, r - 2, t + 1, profile->mBevelColorLL); break; case 4: drawer->drawLine(l, t, l, b - 1, profile->mBevelColorHL); drawer->drawLine(l + 1, t, r, t, profile->mBevelColorHL); drawer->drawLine(l, b, r, b, profile->mBevelColorLL); drawer->drawLine(r, t + 1, r, b - 1, profile->mBevelColorLL); drawer->drawLine(l + 1, b - 1, r - 1, b - 1, profile->mBorderColor); drawer->drawLine(r - 1, t + 1, r - 1, b - 2, profile->mBorderColor); break; case 5: renderFilledBorder( bounds, profile ); break; // case -1: // Draw a simple sizable border with corners // Taken from the 'Skinnable GUI Controls in TGE' resource by Justin DuJardin if(profile->mBitmapArrayRects.size() >= 8) { drawer->clearBitmapModulation(); RectI destRect; RectI stretchRect; RectI* mBitmapBounds = profile->mBitmapArrayRects.address(); // Indices into the bitmap array enum { BorderTopLeft = 0, BorderTop, BorderTopRight, BorderLeft, //Fill, BorderRight, BorderBottomLeft, BorderBottom, BorderBottomRight, NumBitmaps }; // Draw all corners first. //top left border drawer->drawBitmapSR(profile->mTextureObject,Point2I(bounds.point.x,bounds.point.y),mBitmapBounds[BorderTopLeft]); //top right border drawer->drawBitmapSR(profile->mTextureObject,Point2I(bounds.point.x + bounds.extent.x - mBitmapBounds[BorderTopRight].extent.x,bounds.point.y),mBitmapBounds[BorderTopRight]); //bottom left border drawer->drawBitmapSR(profile->mTextureObject,Point2I(bounds.point.x,bounds.point.y + bounds.extent.y - mBitmapBounds[BorderBottomLeft].extent.y),mBitmapBounds[BorderBottomLeft]); //bottom right border drawer->drawBitmapSR(profile->mTextureObject,Point2I( bounds.point.x + bounds.extent.x - mBitmapBounds[BorderBottomRight].extent.x, bounds.point.y + bounds.extent.y - mBitmapBounds[BorderBottomRight].extent.y), mBitmapBounds[BorderBottomRight]); // End drawing corners // Begin drawing sides and top stretched borders //start with top line stretch destRect.point.x = bounds.point.x + mBitmapBounds[BorderTopLeft].extent.x; destRect.extent.x = bounds.extent.x - mBitmapBounds[BorderTopRight].extent.x - mBitmapBounds[BorderTopLeft].extent.x; destRect.extent.y = mBitmapBounds[BorderTop].extent.y; destRect.point.y = bounds.point.y; //stretch it stretchRect = mBitmapBounds[BorderTop]; stretchRect.inset(1,0); //draw it drawer->drawBitmapStretchSR(profile->mTextureObject,destRect,stretchRect); //bottom line stretch destRect.point.x = bounds.point.x + mBitmapBounds[BorderBottomLeft].extent.x; destRect.extent.x = bounds.extent.x - mBitmapBounds[BorderBottomRight].extent.x - mBitmapBounds[BorderBottomLeft].extent.x; destRect.extent.y = mBitmapBounds[BorderBottom].extent.y; destRect.point.y = bounds.point.y + bounds.extent.y - mBitmapBounds[BorderBottom].extent.y; //stretch it stretchRect = mBitmapBounds[BorderBottom]; stretchRect.inset(1,0); //draw it drawer->drawBitmapStretchSR(profile->mTextureObject,destRect,stretchRect); //left line stretch destRect.point.x = bounds.point.x; destRect.extent.x = mBitmapBounds[BorderLeft].extent.x; destRect.extent.y = bounds.extent.y - mBitmapBounds[BorderTopLeft].extent.y - mBitmapBounds[BorderBottomLeft].extent.y; destRect.point.y = bounds.point.y + mBitmapBounds[BorderTopLeft].extent.y; //stretch it stretchRect = mBitmapBounds[BorderLeft]; stretchRect.inset(0,1); //draw it drawer->drawBitmapStretchSR(profile->mTextureObject,destRect,stretchRect); //right line stretch destRect.point.x = bounds.point.x + bounds.extent.x - mBitmapBounds[BorderRight].extent.x; destRect.extent.x = mBitmapBounds[BorderRight].extent.x; destRect.extent.y = bounds.extent.y - mBitmapBounds[BorderTopRight].extent.y - mBitmapBounds[BorderBottomRight].extent.y; destRect.point.y = bounds.point.y + mBitmapBounds[BorderTopRight].extent.y; //stretch it stretchRect = mBitmapBounds[BorderRight]; stretchRect.inset(0,1); //draw it drawer->drawBitmapStretchSR(profile->mTextureObject,destRect,stretchRect); // End drawing sides and top stretched borders break; } case -2: // Draw a simple sizable border with corners that is filled in renderSizableBitmapBordersFilled(bounds, 1, profile); break; case -3: // Draw a simple fixed height border with center fill horizontally. renderFixedBitmapBordersFilled( bounds, 1, profile ); break; } }
void GuiGameListMenuCtrl::onRender(Point2I offset, const RectI &updateRect) { GuiGameListMenuProfile * profile = (GuiGameListMenuProfile *) mProfile; GFXDrawUtil* drawUtil = GFX->getDrawUtil(); F32 xScale = (float) getWidth() / profile->getRowWidth(); bool profileHasIcons = profile->hasArrows(); S32 rowHeight = profile->getRowHeight(); Point2I currentOffset = offset; Point2I extent = getExtent(); Point2I rowExtent(extent.x, rowHeight); Point2I textOffset(profile->mTextOffset.x * xScale, profile->mTextOffset.y); Point2I textExtent(extent.x - textOffset.x, rowHeight); Point2I iconExtent, iconOffset(0.0f, 0.0f); if (profileHasIcons) { iconExtent = profile->getIconExtent(); // icon is centered vertically plus any specified offset S32 iconOffsetY = (rowHeight - iconExtent.y) >> 1; iconOffsetY += profile->mIconOffset.y; iconOffset = Point2I(profile->mIconOffset.x * xScale, iconOffsetY); } for (Vector<Row *>::iterator row = mRows.begin(); row < mRows.end(); ++row) { if (row != mRows.begin()) { // rows other than the first can have padding above them currentOffset.y += (*row)->mHeightPad; currentOffset.y += rowHeight; } // select appropriate colors and textures ColorI fontColor; U32 buttonTextureIndex; S32 iconIndex = (*row)->mIconIndex; bool useHighlightIcon = (*row)->mUseHighlightIcon; if (! (*row)->mEnabled) { buttonTextureIndex = Profile::TEX_DISABLED; fontColor = profile->mFontColorNA; } else if (row == &mRows[mSelected]) { if (iconIndex != NO_ICON) { iconIndex++; } buttonTextureIndex = Profile::TEX_SELECTED; fontColor = profile->mFontColorSEL; } else if ((mHighlighted != NO_ROW) && (row == &mRows[mHighlighted])) { if (iconIndex != NO_ICON && useHighlightIcon) { iconIndex++; } buttonTextureIndex = Profile::TEX_HIGHLIGHT; fontColor = profile->mFontColorHL; } else { buttonTextureIndex = Profile::TEX_NORMAL; fontColor = profile->mFontColor; } // render the row bitmap drawUtil->clearBitmapModulation(); drawUtil->drawBitmapStretchSR(profile->mTextureObject, RectI(currentOffset, rowExtent), profile->getBitmapArrayRect(buttonTextureIndex)); // render the row icon if it has one if ((iconIndex != NO_ICON) && profileHasIcons && (! profile->getBitmapArrayRect((U32)iconIndex).extent.isZero())) { iconIndex += Profile::TEX_FIRST_ICON; drawUtil->clearBitmapModulation(); drawUtil->drawBitmapStretchSR(profile->mTextureObject, RectI(currentOffset + iconOffset, iconExtent), profile->getBitmapArrayRect(iconIndex)); } // render the row text drawUtil->setBitmapModulation(fontColor); renderJustifiedText(currentOffset + textOffset, textExtent, (*row)->mLabel); } if (mDebugRender) { onDebugRender(offset); } renderChildControls(offset, updateRect); }