Initial commit
This commit is contained in:
318
Torque/SDK/engine/dgl/gDynamicTexture.cc
Normal file
318
Torque/SDK/engine/dgl/gDynamicTexture.cc
Normal file
@@ -0,0 +1,318 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// Gridwalkers
|
||||
//
|
||||
// Copyright (c) 2003 Pat Wilson and Flaming Duck Studio
|
||||
// Portions Copyright (c) 2001 GarageGames.Com
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
#include "dgl/gDynamicTexture.h"
|
||||
#include "dgl/gBitmap.h"
|
||||
#include "gui/core/guiControl.h"
|
||||
#include "dgl/dgl.h"
|
||||
#include "util/safeDelete.h"
|
||||
|
||||
Vector<DynamicTexture *> DynamicTexture::smRegisteredGuiUpdaters;
|
||||
Vector<DynamicTexture *> DynamicTexture::smRegisteredScreenUpdaters;
|
||||
Vector<DynamicTexture *> DynamicTexture::smUpdateAtEndOfFrame;
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
void dynamicTextureCB(const U32 eventCode, void *userData)
|
||||
{
|
||||
DynamicTexture* ts = reinterpret_cast<DynamicTexture*>(userData);
|
||||
|
||||
if(eventCode==TextureManager::BeginZombification)
|
||||
{
|
||||
SAFE_DELETE(ts->mTextureHandle);
|
||||
}
|
||||
else if(eventCode==TextureManager::CacheResurrected)
|
||||
{
|
||||
GBitmap *bmp = new GBitmap( ts->mSize.x, ts->mSize.y, false, GBitmap::RGBA );
|
||||
ts->mTextureHandle = new TextureHandle( NULL, bmp, BitmapKeepTexture, true );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
DynamicTexture::DynamicTexture()
|
||||
{
|
||||
initDT();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
DynamicTexture::DynamicTexture( GuiControl * control )
|
||||
{
|
||||
initDT();
|
||||
|
||||
registerForGuiUpdates( control );
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
DynamicTexture::DynamicTexture( const RectI &updateRect )
|
||||
{
|
||||
initDT();
|
||||
mUpdateRect = updateRect;
|
||||
|
||||
setUpdateRect( updateRect );
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
DynamicTexture::~DynamicTexture()
|
||||
{
|
||||
TextureManager::unregisterEventCallback(mTexCBHandle);
|
||||
SAFE_DELETE( mTextureHandle );
|
||||
SAFE_DELETE( mTempDynamicTexture );
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
void DynamicTexture::setEnableRTT( bool enable /* = true */ )
|
||||
{
|
||||
mRTT = enable;
|
||||
|
||||
if( enable && mTempDynamicTexture == NULL )
|
||||
mTempDynamicTexture = new DynamicTexture( mUpdateRect );
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
void DynamicTexture::update()
|
||||
{
|
||||
if( !mHasUpdateRect )
|
||||
return;
|
||||
|
||||
RectI *rect = &mUpdateRect;
|
||||
|
||||
// Different-rect updating provided it is the same size
|
||||
if( 0 )
|
||||
{
|
||||
/// rect = something differing
|
||||
AssertFatal( rect->extent.x <= mUpdateRect.extent.x &&
|
||||
rect->extent.y <= mUpdateRect.extent.x, "Cannot update a DynamicTexture with an update area larger than it's allocated area." );
|
||||
}
|
||||
|
||||
|
||||
// Do the screen copy
|
||||
glReadBuffer( GL_BACK );
|
||||
glBindTexture( GL_TEXTURE_2D, mTextureHandle->getGLName() );
|
||||
glCopyTexSubImage2D( GL_TEXTURE_2D, 0, // 0 = no mipmaplevels
|
||||
0, 0, // X and y offsets, see docs
|
||||
rect->point.x, rect->point.y,
|
||||
rect->extent.x, rect->extent.y );
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
void DynamicTexture::setUpdateRect( const RectI &newRect )
|
||||
{
|
||||
mHasUpdateRect = true;
|
||||
|
||||
// Check to see if this is being called as part of the constructor
|
||||
if( mTextureHandle == NULL )
|
||||
{
|
||||
GBitmap *bmp = new GBitmap( newRect.extent.x, newRect.extent.y, false, GBitmap::RGBA );
|
||||
mTextureHandle = new TextureHandle( NULL, bmp, BitmapKeepTexture, true );
|
||||
mSize = newRect.extent;
|
||||
}
|
||||
|
||||
if( mTempDynamicTexture != NULL )
|
||||
mTempDynamicTexture->setUpdateRect( newRect );
|
||||
|
||||
// Flip from upper-left point to lower-left point (for GL)
|
||||
RectI updateRect = newRect;
|
||||
updateRect.point.y = Platform::getWindowSize().y - updateRect.point.y - updateRect.extent.y;
|
||||
|
||||
if( updateRect.extent == mUpdateRect.extent )
|
||||
{
|
||||
if( updateRect.point != mUpdateRect.point )
|
||||
mUpdateRect.point = updateRect.point;
|
||||
}
|
||||
else
|
||||
{
|
||||
TextureObject *to = mTextureHandle->object;
|
||||
mUpdateRect = updateRect;
|
||||
|
||||
// If the new texture size can fit in the existing allocated size,
|
||||
// then we are golden, otherwise we have to re-create or we'll get
|
||||
// hosed.
|
||||
if( mTextureHandle->getDownloadedWidth() >= mUpdateRect.extent.x &&
|
||||
mTextureHandle->getDownloadedHeight() >= mUpdateRect.extent.y )
|
||||
{
|
||||
|
||||
// We don't have to resize the actual memory (yay)
|
||||
to->bitmapWidth = mUpdateRect.extent.x;
|
||||
to->bitmapHeight = mUpdateRect.extent.y;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Damn, we gotta reallocate
|
||||
delete mTextureHandle;
|
||||
mTextureHandle = NULL;
|
||||
|
||||
GBitmap *bmp = new GBitmap( updateRect.extent.x, updateRect.extent.y, false, GBitmap::RGBA );
|
||||
mTextureHandle = new TextureHandle( NULL, bmp, BitmapKeepTexture, true );
|
||||
mSize = updateRect.extent;
|
||||
}
|
||||
}
|
||||
|
||||
// DON'T USE mUpdateRect here
|
||||
// Note that this looks a bit funny, this is because grabbing pixels results in
|
||||
// the rows getting flipped, to adjust for this, the texture coordinates must be flipped
|
||||
TextureObject *obj = (TextureObject *)mTextureHandle;
|
||||
F32 maxX = F32(newRect.extent.x) / F32(obj->texWidth);
|
||||
F32 maxY = F32(newRect.extent.y) / F32(obj->texHeight);
|
||||
mTextureCoords = RectF( (F32)newRect.point.x, maxY, maxX, (F32)newRect.point.y );
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
void DynamicTexture::renderGuiControl( GuiControl *ctrl /* = NULL */, bool rttMode /* = false */ )
|
||||
{
|
||||
if( ctrl == NULL )
|
||||
{
|
||||
if( mGuiControl == NULL )
|
||||
return;
|
||||
else
|
||||
ctrl = mGuiControl;
|
||||
}
|
||||
else
|
||||
mGuiControl = ctrl;
|
||||
|
||||
setUpdateRect( ctrl->mBounds ); // This CHANGES mUpdateRect
|
||||
|
||||
// If we are simulating rendering to offscreen type thing
|
||||
// grab the current contents of the framebuffer and store them
|
||||
if( rttMode )
|
||||
{
|
||||
setEnableRTT( true );
|
||||
storePixels();
|
||||
}
|
||||
|
||||
// Now render the control and grab the pixels
|
||||
dglSetClipRect( ctrl->mBounds );
|
||||
//ctrl->preRender();
|
||||
ctrl->onRender( ctrl->mBounds.point, ctrl->mBounds );
|
||||
|
||||
update();
|
||||
|
||||
// Now restore the contents of the framebuffer so it doesn't look like we did
|
||||
// anything at all (bwahahaha, Trogdor strikes again)
|
||||
if( rttMode )
|
||||
{
|
||||
dglSetClipRect( ctrl->mBounds );
|
||||
restorePixels();
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
void DynamicTexture::storePixels()
|
||||
{
|
||||
mTempDynamicTexture->update();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
void DynamicTexture::restorePixels()
|
||||
{
|
||||
dglClearBitmapModulation();
|
||||
dglDrawBitmapStretch( mTempDynamicTexture->getTextureHandle(), mUpdateRect, GFlip_Y );
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
void DynamicTexture::registerForGuiUpdates( GuiControl *control )
|
||||
{
|
||||
if( control == NULL )
|
||||
return;
|
||||
|
||||
unregisterForGuiUpdates();
|
||||
|
||||
// Sign it up in the vector
|
||||
smRegisteredGuiUpdaters.push_back( this );
|
||||
|
||||
mGuiControl = control;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
bool DynamicTexture::unregisterForGuiUpdates()
|
||||
{
|
||||
for( RegisteredUpdateItr i = smRegisteredGuiUpdaters.begin();
|
||||
i != smRegisteredGuiUpdaters.end(); i++ )
|
||||
{
|
||||
if( (*i) == this )
|
||||
{
|
||||
smRegisteredGuiUpdaters.erase( i );
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
void DynamicTexture::updateGuiTextures()
|
||||
{
|
||||
for( RegisteredUpdateItr i = smRegisteredGuiUpdaters.begin();
|
||||
i != smRegisteredGuiUpdaters.end(); i++ )
|
||||
{
|
||||
(*i)->renderGuiControl( (*i)->mGuiControl );
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
void DynamicTexture::registerForScreenUpdates()
|
||||
{
|
||||
unregisterForScreenUpdates();
|
||||
|
||||
// Sign it up in the vector
|
||||
smRegisteredScreenUpdaters.push_back( this );
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
bool DynamicTexture::unregisterForScreenUpdates()
|
||||
{
|
||||
for( RegisteredUpdateItr i = smRegisteredScreenUpdaters.begin();
|
||||
i != smRegisteredScreenUpdaters.end(); i++ )
|
||||
{
|
||||
if( (*i) == this )
|
||||
{
|
||||
smRegisteredScreenUpdaters.erase( i );
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
void DynamicTexture::updateScreenTextures()
|
||||
{
|
||||
for( RegisteredUpdateItr i = smRegisteredScreenUpdaters.begin();
|
||||
i != smRegisteredScreenUpdaters.end(); i++ )
|
||||
{
|
||||
(*i)->update();
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
void DynamicTexture::updateEndOfFrameTextures()
|
||||
{
|
||||
for( RegisteredUpdateItr i = smUpdateAtEndOfFrame.begin();
|
||||
i != smUpdateAtEndOfFrame.end(); i++ )
|
||||
{
|
||||
(*i)->update();
|
||||
}
|
||||
|
||||
smUpdateAtEndOfFrame.clear();
|
||||
}
|
||||
Reference in New Issue
Block a user