void GuiBitmapCtrl::onRender(Point2I offset, const RectI &updateRect) { GFXDEBUGEVENT_SCOPE_EX( GuiBitmapCtrl_onRender, ColorI::GREEN, avar("GuiBitmapCtrl: %s", mBitmapName.c_str()) ); if (mTextureObject) { GFX->getDrawUtil()->clearBitmapModulation(); if(mWrap) { // We manually draw each repeat because non power of two textures will // not tile correctly when rendered with GFX->drawBitmapTile(). The non POT // bitmap will be padded by the hardware, and we'll see lots of slack // in the texture. So... lets do what we must: draw each repeat by itself: GFXTextureObject* texture = mTextureObject; RectI srcRegion; RectI dstRegion; float xdone = ((float)getExtent().x/(float)texture->mBitmapSize.x)+1; float ydone = ((float)getExtent().y/(float)texture->mBitmapSize.y)+1; int xshift = mStartPoint.x%texture->mBitmapSize.x; int yshift = mStartPoint.y%texture->mBitmapSize.y; for(int y = 0; y < ydone; ++y) for(int x = 0; x < xdone; ++x) { srcRegion.set(0,0,texture->mBitmapSize.x,texture->mBitmapSize.y); dstRegion.set( ((texture->mBitmapSize.x*x)+offset.x)-xshift, ((texture->mBitmapSize.y*y)+offset.y)-yshift, texture->mBitmapSize.x, texture->mBitmapSize.y); GFX->getDrawUtil()->drawBitmapStretchSR(texture,dstRegion, srcRegion, GFXBitmapFlip_None, GFXTextureFilterLinear); } } else { RectI rect(offset, getExtent()); GFX->getDrawUtil()->drawBitmapStretch(mTextureObject, rect, GFXBitmapFlip_None, GFXTextureFilterLinear, false); } } if (mProfile->mBorder || !mTextureObject) { RectI rect(offset.x, offset.y, getExtent().x, getExtent().y); GFX->getDrawUtil()->drawRect(rect, mProfile->mBorderColor); } renderChildControls(offset, updateRect); }
void RenderFormatToken::process(SceneState *state, RenderPassStateBin *callingBin) { switch(mFCState) { case FTSWaiting: { GFXDEBUGEVENT_SCOPE_EX(RFT_Waiting, ColorI::BLUE, avar("[%s Activate] (%s)", getName(), GFXStringTextureFormat[mColorFormat])); mFCState = FTSActive; mViewportRect = GFX->getViewport(); // Update targets _updateTargets(); // If we have a copy PostEffect then get the active backbuffer copy // now before we swap the render targets. GFXTexHandle curBackBuffer; if(mCopyPostEffect.isValid()) curBackBuffer = PFXMGR->getBackBufferTex(); // Push target GFX->pushActiveRenderTarget(); GFX->setActiveRenderTarget(mTargetChain[mTargetChainIdx]); // Set viewport GFX->setViewport(mViewportRect); // Clear GFX->clear(GFXClearTarget | GFXClearZBuffer | GFXClearStencil, gCanvasClearColor, 1.0f, 0); // Set active z target on render pass if(mTargetDepthStencilTexture[mTargetChainIdx].isValid()) { if(callingBin->getParentManager()->getDepthTargetTexture() != GFXTextureTarget::sDefaultDepthStencil) mStoredPassZTarget = callingBin->getParentManager()->getDepthTargetTexture(); else mStoredPassZTarget = NULL; callingBin->getParentManager()->setDepthTargetTexture(mTargetDepthStencilTexture[mTargetChainIdx]); } // Run the PostEffect which copies data into the new target. if ( mCopyPostEffect.isValid() ) mCopyPostEffect->process( state, curBackBuffer, &mViewportRect ); } break; case FTSActive: { GFXDEBUGEVENT_SCOPE_EX(RFT_Active, ColorI::BLUE, avar("[%s Deactivate]", getName())); mFCState = FTSComplete; // Pop target AssertFatal(GFX->getActiveRenderTarget() == mTargetChain[mTargetChainIdx], "Render target stack went wrong somewhere"); mTargetChain[mTargetChainIdx]->resolve(); GFX->popActiveRenderTarget(); // This is the GFX viewport when we were first processed. GFX->setViewport(mViewportRect); // Restore active z-target if(mTargetDepthStencilTexture[mTargetChainIdx].isValid()) { callingBin->getParentManager()->setDepthTargetTexture(mStoredPassZTarget.getPointer()); mStoredPassZTarget = NULL; } // Run the PostEffect which copies data to the backbuffer if(mResolvePostEffect.isValid()) { // Need to create a texhandle here, since inOutTex gets assigned during process() GFXTexHandle inOutTex = mTargetColorTexture[mTargetChainIdx]; mResolvePostEffect->process( state, inOutTex, &mViewportRect ); } } break; case FTSComplete: AssertFatal(false, "process() called on a RenderFormatToken which was already complete."); // fall through case FTSDisabled: break; } }
void GuiOffscreenCanvas::renderFrame(bool preRenderOnly, bool bufferSwap /* = true */) { if (!mTargetDirty) return; #ifdef TORQUE_ENABLE_GFXDEBUGEVENTS char buf[256]; dSprintf(buf, sizeof(buf), "OffsceenCanvas %s", getName() ? getName() : getIdString()); GFXDEBUGEVENT_SCOPE_EX(GuiOffscreenCanvas_renderFrame, ColorI::GREEN, buf); #endif PROFILE_START(OffscreenCanvasPreRender); #ifdef TORQUE_GFX_STATE_DEBUG GFX->getDebugStateManager()->startFrame(); #endif if (mTarget->getSize() != mTargetSize) { _setupTargets(); mNamedTarget.setViewport( RectI( Point2I::Zero, mTargetSize ) ); } // Make sure the root control is the size of the canvas. Point2I size = mTarget->getSize(); if(size.x == 0 || size.y == 0) { PROFILE_END(); return; } RectI screenRect(0, 0, size.x, size.y); maintainSizing(); //preRender (recursive) all controls preRender(); PROFILE_END(); // Are we just doing pre-render? if(preRenderOnly) { return; } resetUpdateRegions(); PROFILE_START(OffscreenCanvasRenderControls); GuiCursor *mouseCursor = NULL; bool cursorVisible = true; Point2I cursorPos((S32)mCursorPt.x, (S32)mCursorPt.y); mouseCursor = mDefaultCursor; mLastCursorEnabled = cursorVisible; mLastCursor = mouseCursor; mLastCursorPt = cursorPos; // Set active target GFX->pushActiveRenderTarget(); GFX->setActiveRenderTarget(mTarget); // Clear the current viewport area GFX->setViewport( screenRect ); GFX->clear( GFXClearTarget, ColorF(0,0,0,0), 1.0f, 0 ); resetUpdateRegions(); // Make sure we have a clean matrix state // before we start rendering anything! GFX->setWorldMatrix( MatrixF::Identity ); GFX->setViewMatrix( MatrixF::Identity ); GFX->setProjectionMatrix( MatrixF::Identity ); RectI contentRect(Point2I(0,0), mTargetSize); { // Render active GUI Dialogs for(iterator i = begin(); i != end(); i++) { // Get the control GuiControl *contentCtrl = static_cast<GuiControl*>(*i); GFX->setClipRect( contentRect ); GFX->setStateBlock(mDefaultGuiSB); contentCtrl->onRender(contentCtrl->getPosition(), contentRect); } // Fill Blue if no Dialogs if(this->size() == 0) GFX->clear( GFXClearTarget, ColorF(0,0,0,1), 1.0f, 0 ); GFX->setClipRect( contentRect ); // Draw cursor // if (mCursorEnabled && mouseCursor && mShowCursor) { Point2I pos((S32)mCursorPt.x, (S32)mCursorPt.y); Point2I spot = mouseCursor->getHotSpot(); pos -= spot; mouseCursor->render(pos); } GFX->getDrawUtil()->clearBitmapModulation(); } mTarget->resolve(); GFX->popActiveRenderTarget(); PROFILE_END(); // Keep track of the last time we rendered. mLastRenderMs = Platform::getRealMilliseconds(); mTargetDirty = mDynamicTarget; onFrameRendered(); }