Torque3D Documentation / _generateds / guiOffscreenCanvas.cpp

guiOffscreenCanvas.cpp

Engine/source/gui/core/guiOffscreenCanvas.cpp

More...

Public Functions

Detailed Description

Public Functions

DefineEngineMethod(GuiOffscreenCanvas , markDirty , void , () , "" )

DefineEngineMethod(GuiOffscreenCanvas , resetTarget , void , () , "" )

IMPLEMENT_CONOBJECT(GuiOffscreenCanvas )

  1
  2#include "gui/core/guiOffscreenCanvas.h"
  3#include "gfx/gfxDrawUtil.h"
  4#include "gfx/gfxTextureManager.h"
  5#include "gfx/gfxAPI.h"
  6#include "gfx/gfxDebugEvent.h"
  7
  8#include "console/consoleTypes.h"
  9#include "console/console.h"
 10
 11IMPLEMENT_CONOBJECT(GuiOffscreenCanvas);
 12
 13Vector<GuiOffscreenCanvas*> GuiOffscreenCanvas::sList;
 14
 15GuiOffscreenCanvas::GuiOffscreenCanvas()
 16{
 17   mTargetFormat = GFXFormatR8G8B8A8;
 18   mTargetSize = Point2I(256,256);
 19   mTargetName = "offscreenCanvas";
 20   mTargetDirty = true;
 21   mDynamicTarget = false;
 22   mUseDepth = false;
 23}
 24
 25GuiOffscreenCanvas::~GuiOffscreenCanvas()
 26{
 27}
 28
 29void GuiOffscreenCanvas::initPersistFields()
 30{
 31   addField( "targetSize", TypePoint2I, Offset( mTargetSize, GuiOffscreenCanvas ),"" );
 32   addField( "targetFormat", TypeGFXFormat, Offset( mTargetFormat, GuiOffscreenCanvas ), "");
 33   addField( "targetName", TypeRealString, Offset( mTargetName, GuiOffscreenCanvas ), "");
 34   addField( "dynamicTarget", TypeBool, Offset( mDynamicTarget, GuiOffscreenCanvas ), "");
 35   addField( "useDepth", TypeBool, Offset( mUseDepth, GuiOffscreenCanvas ), "");
 36
 37   Parent::initPersistFields();
 38}
 39
 40bool GuiOffscreenCanvas::onAdd()
 41{
 42   if (GuiControl::onAdd()) // jamesu - skip GuiCanvas onAdd since it sets up GFX which is bad
 43   {
 44      // ensure that we have a cursor
 45      setCursor(dynamic_cast<GuiCursor*>(Sim::findObject("DefaultCursor")));
 46      
 47      mRenderFront = true;
 48      sList.push_back(this);
 49
 50      //Con::printf("Registering target %s...", mTargetName.c_str());
 51      mNamedTarget.registerWithName( mTargetName );
 52
 53      _setupTargets();
 54
 55      GFXTextureManager::addEventDelegate( this, &GuiOffscreenCanvas::_onTextureEvent );
 56
 57      return true;
 58   }
 59   return false;
 60}
 61
 62void GuiOffscreenCanvas::onRemove()
 63{
 64   GFXTextureManager::removeEventDelegate( this, &GuiOffscreenCanvas::_onTextureEvent );
 65
 66   _teardownTargets();
 67
 68   U32 idx = sList.find_next(this);
 69   if (idx != (U32)-1)
 70   {
 71      sList.erase(idx);
 72   }
 73
 74   mTarget = NULL;
 75   mTargetTexture = NULL;
 76   mTargetDepth = NULL;
 77
 78   Parent::onRemove();
 79}
 80
 81void GuiOffscreenCanvas::_setupTargets()
 82{
 83   _teardownTargets();
 84
 85   if (!mTarget.isValid())
 86   {
 87      mTarget = GFX->allocRenderToTextureTarget();
 88   }
 89
 90   // Update color
 91   if (!mTargetTexture.isValid() || mTargetSize != mTargetTexture.getWidthHeight())
 92   {
 93      mTargetTexture.set( mTargetSize.x, mTargetSize.y, mTargetFormat, &GFXRenderTargetSRGBProfile, avar( "%s() - (line %d)", __FUNCTION__, __LINE__ ), 1, 0 );
 94   }
 95
 96   // Update depth if needed
 97   if (mUseDepth && (!mTargetDepth.isValid() || mTargetSize != mTargetDepth.getWidthHeight()))
 98   {
 99      mTargetDepth.set( mTargetSize.x, mTargetSize.y, GFXFormatD24S8, &GFXRenderTargetProfile, avar( "%s() - (line %d)", __FUNCTION__, __LINE__ ), 1, 0 );
100      mTarget->attachTexture( GFXTextureTarget::RenderSlot(GFXTextureTarget::DepthStencil), mTargetDepth );
101   }
102
103   mTarget->attachTexture( GFXTextureTarget::RenderSlot(GFXTextureTarget::Color0), mTargetTexture );
104   mNamedTarget.setTexture(0, mTargetTexture);
105}
106
107void GuiOffscreenCanvas::_teardownTargets()
108{
109   mNamedTarget.release();
110   mTargetTexture = NULL;
111   mTargetDepth = NULL;
112   mTargetDirty = true;
113}
114
115void GuiOffscreenCanvas::renderFrame(bool preRenderOnly, bool bufferSwap /* = true */)
116{
117   if (!mTargetDirty)
118      return;
119   
120#ifdef TORQUE_ENABLE_GFXDEBUGEVENTS
121   char buf[256];
122   dSprintf(buf, sizeof(buf), "OffsceenCanvas %s", getName() ? getName() : getIdString());
123   GFXDEBUGEVENT_SCOPE_EX(GuiOffscreenCanvas_renderFrame, ColorI::GREEN, buf);
124#endif
125   
126   PROFILE_START(OffscreenCanvasPreRender);
127
128#ifdef TORQUE_GFX_STATE_DEBUG
129   GFX->getDebugStateManager()->startFrame();
130#endif
131
132   if (mTarget->getSize() != mTargetSize)
133   {
134      _setupTargets();
135      mNamedTarget.setViewport( RectI( Point2I::Zero, mTargetSize ) );
136   }
137
138   // Make sure the root control is the size of the canvas.
139   Point2I size = mTarget->getSize();
140
141   if(size.x == 0 || size.y == 0)
142   {
143      PROFILE_END();
144      return;
145   }
146
147   RectI screenRect(0, 0, size.x, size.y);
148
149   maintainSizing();
150
151   //preRender (recursive) all controls
152   preRender();
153
154   PROFILE_END();
155
156   // Are we just doing pre-render?
157   if(preRenderOnly)
158   {
159      return;
160   }
161
162   resetUpdateRegions();
163
164   PROFILE_START(OffscreenCanvasRenderControls);
165
166   GuiCursor *mouseCursor = NULL;
167   bool cursorVisible = true;
168
169   Point2I cursorPos((S32)mCursorPt.x, (S32)mCursorPt.y);
170   mouseCursor = mDefaultCursor;
171
172   mLastCursorEnabled = cursorVisible;
173   mLastCursor = mouseCursor;
174   mLastCursorPt = cursorPos;
175
176   // Set active target
177   GFX->pushActiveRenderTarget();
178   GFX->setActiveRenderTarget(mTarget);
179
180   // Clear the current viewport area
181   GFX->setViewport( screenRect );
182   GFX->clear( GFXClearTarget, LinearColorF(0,0,0,0), 1.0f, 0 );
183
184   resetUpdateRegions();
185
186   // Make sure we have a clean matrix state 
187   // before we start rendering anything!   
188   GFX->setWorldMatrix( MatrixF::Identity );
189   GFX->setViewMatrix( MatrixF::Identity );
190   GFX->setProjectionMatrix( MatrixF::Identity );
191   
192   RectI contentRect(Point2I(0,0), mTargetSize);
193   {
194      // Render active GUI Dialogs
195      for(iterator i = begin(); i != end(); i++)
196      {
197         // Get the control
198         GuiControl *contentCtrl = static_cast<GuiControl*>(*i);
199         
200         GFX->setClipRect( contentRect );
201         GFX->setStateBlock(mDefaultGuiSB);
202         
203         contentCtrl->onRender(contentCtrl->getPosition(), contentRect);
204      }
205
206      // Fill Blue if no Dialogs
207      if(this->size() == 0)
208         GFX->clear( GFXClearTarget, LinearColorF(0,0,0,1), 1.0f, 0 );
209
210      GFX->setClipRect( contentRect );
211
212      // Draw cursor
213      // 
214      if (mCursorEnabled && mouseCursor && mShowCursor)
215      {
216         Point2I pos((S32)mCursorPt.x, (S32)mCursorPt.y);
217         Point2I spot = mouseCursor->getHotSpot();
218
219         pos -= spot;
220         mouseCursor->render(pos);
221      }
222
223      GFX->getDrawUtil()->clearBitmapModulation();
224   }
225
226   mTarget->resolve();
227   GFX->popActiveRenderTarget();
228
229   PROFILE_END();
230
231   // Keep track of the last time we rendered.
232   mLastRenderMs = Platform::getRealMilliseconds();
233   mTargetDirty = mDynamicTarget;
234
235   onFrameRendered();
236}
237
238void GuiOffscreenCanvas::onFrameRendered()
239{
240
241}
242
243Point2I GuiOffscreenCanvas::getWindowSize()
244{
245   return mTargetSize;
246}
247
248Point2I GuiOffscreenCanvas::getCursorPos()
249{
250   return Point2I(mCursorPt.x, mCursorPt.y);
251}
252
253void GuiOffscreenCanvas::setCursorPos(const Point2I &pt)
254{
255   mCursorPt.x = F32( pt.x );
256   mCursorPt.y = F32( pt.y );
257}
258
259void GuiOffscreenCanvas::showCursor(bool state)
260{ 
261   mShowCursor = state;
262}
263
264bool GuiOffscreenCanvas::isCursorShown()
265{
266   return mShowCursor;
267}
268
269void GuiOffscreenCanvas::_onTextureEvent( GFXTexCallbackCode code )
270{
271   switch(code)
272   {
273      case GFXZombify:
274         _teardownTargets();
275         break;
276
277      case GFXResurrect:
278         _setupTargets();
279         break;
280   }
281}
282
283DefineEngineMethod(GuiOffscreenCanvas, resetTarget, void, (), , "")
284{
285   object->_setupTargets();
286}
287
288DefineEngineMethod(GuiOffscreenCanvas, markDirty, void, (), , "")
289{
290   object->markDirty();
291}
292
293