2014-07-02 19:08:47 +02:00
# include "graphics/tinygl/zblit.h"
# include "graphics/tinygl/zgl.h"
2014-07-07 18:17:54 +02:00
# include "graphics/pixelbuffer.h"
2014-07-07 21:14:58 +02:00
# include "common/array.h"
2014-08-07 17:54:53 +02:00
# include "graphics/tinygl/zdirtyrect.h"
2014-07-25 15:45:12 +02:00
# include "graphics/tinygl/gl.h"
2014-07-16 02:24:34 +02:00
# include <math.h>
2014-07-07 18:17:54 +02:00
2014-07-12 11:41:55 +02:00
namespace Graphics {
2014-07-13 19:01:23 +02:00
Common : : Point transformPoint ( float x , float y , int rotation ) ;
Common : : Rect rotateRectangle ( int x , int y , int width , int height , int rotation , int originX , int originY ) ;
2014-07-13 18:49:27 +02:00
2014-07-07 21:14:58 +02:00
struct BlitImage {
2014-07-07 18:17:54 +02:00
public :
2014-08-10 19:34:47 +02:00
BlitImage ( ) : _isDisposed ( false ) , _version ( 0 ) , _binaryTransparent ( false ) { }
2014-07-07 18:17:54 +02:00
2014-07-07 21:14:58 +02:00
void loadData ( const Graphics : : Surface & surface , uint32 colorKey , bool applyColorKey ) {
2014-08-13 21:11:35 +02:00
const Graphics : : PixelFormat textureFormat ( 4 , 8 , 8 , 8 , 8 , 0 , 8 , 16 , 24 ) ;
2014-07-07 18:17:54 +02:00
_surface . create ( surface . w , surface . h , textureFormat ) ;
2014-07-16 14:18:01 +02:00
Graphics : : PixelBuffer buffer ( surface . format , ( byte * ) const_cast < void * > ( surface . getPixels ( ) ) ) ;
2014-07-16 16:46:56 +02:00
Graphics : : PixelBuffer dataBuffer ( textureFormat , ( byte * ) const_cast < void * > ( _surface . getPixels ( ) ) ) ;
2014-07-14 18:11:23 +02:00
dataBuffer . copyBuffer ( 0 , 0 , surface . w * surface . h , buffer ) ;
if ( applyColorKey ) {
for ( int x = 0 ; x < surface . w ; x + + ) {
for ( int y = 0 ; y < surface . h ; y + + ) {
uint32 pixel = dataBuffer . getValueAt ( y * surface . w + x ) ;
if ( pixel = = colorKey ) {
2014-08-13 21:11:35 +02:00
// Color keyed pixels become transparent white.
dataBuffer . setPixelAt ( y * surface . w + x , 0 , 255 , 255 , 255 ) ;
2014-07-14 18:11:23 +02:00
}
2014-07-04 19:34:12 +02:00
}
}
2014-07-02 19:08:47 +02:00
}
2014-07-14 18:11:23 +02:00
2014-07-07 18:17:54 +02:00
// Create opaque lines data.
2014-07-13 16:17:17 +02:00
// A line of pixels can not wrap more that one line of the image, since it would break
// blitting of bitmaps with a non-zero x position.
Graphics : : PixelBuffer srcBuf = dataBuffer ;
_lines . clear ( ) ;
2014-07-17 13:22:15 +02:00
_binaryTransparent = true ;
2014-07-13 16:17:17 +02:00
for ( int y = 0 ; y < surface . h ; y + + ) {
int start = - 1 ;
for ( int x = 0 ; x < surface . w ; + + x ) {
// We found a transparent pixel, so save a line from 'start' to the pixel before this.
uint8 r , g , b , a ;
srcBuf . getARGBAt ( x , a , r , g , b ) ;
2014-07-17 13:22:15 +02:00
if ( a ! = 0 & & a ! = 0xFF ) {
_binaryTransparent = false ;
}
2014-07-13 16:17:17 +02:00
if ( a = = 0 & & start > = 0 ) {
_lines . push_back ( Line ( start , y , x - start , srcBuf . getRawBuffer ( start ) ) ) ;
start = - 1 ;
} else if ( a ! = 0 & & start = = - 1 ) {
start = x ;
}
}
// end of the bitmap line. if start is an actual pixel save the line.
if ( start > = 0 ) {
2014-08-07 21:49:13 +02:00
_lines . push_back ( Line ( start , y , surface . w - start , srcBuf . getRawBuffer ( start ) ) ) ;
2014-07-13 16:17:17 +02:00
}
srcBuf . shiftBy ( surface . w ) ;
}
2014-08-03 20:56:38 +02:00
_version + + ;
2014-07-07 18:17:54 +02:00
}
2014-07-02 19:08:47 +02:00
2014-08-02 21:44:23 +02:00
int getVersion ( ) const {
return _version ;
}
2014-07-07 21:14:58 +02:00
~ BlitImage ( ) {
2014-07-07 18:17:54 +02:00
_surface . free ( ) ;
2014-07-02 19:08:47 +02:00
}
2014-07-13 19:01:23 +02:00
struct Line {
2014-07-13 16:17:17 +02:00
int _x ;
int _y ;
int _length ;
byte * _pixels ;
Graphics : : PixelBuffer _buf ; // This is needed for the conversion.
2014-08-13 20:51:53 +02:00
Line ( ) : _x ( 0 ) , _y ( 0 ) , _length ( 0 ) , _pixels ( nullptr ) { }
2014-08-10 19:34:47 +02:00
Line ( int x , int y , int length , byte * pixels ) : _buf ( TinyGL : : gl_get_context ( ) - > fb - > cmode , length * TinyGL : : gl_get_context ( ) - > fb - > cmode . bytesPerPixel , DisposeAfterUse : : NO ) ,
_x ( x ) , _y ( y ) , _length ( length ) {
2014-07-13 16:17:17 +02:00
// Performing texture to screen conversion.
2014-08-13 21:11:35 +02:00
const Graphics : : PixelFormat textureFormat ( 4 , 8 , 8 , 8 , 8 , 0 , 8 , 16 , 24 ) ;
2014-07-13 16:17:17 +02:00
Graphics : : PixelBuffer srcBuf ( textureFormat , pixels ) ;
_buf . copyBuffer ( 0 , 0 , length , srcBuf ) ;
_pixels = _buf . getRawBuffer ( ) ;
}
2014-08-10 19:34:47 +02:00
Line ( const Line & other ) : _buf ( TinyGL : : gl_get_context ( ) - > fb - > cmode , other . _length * TinyGL : : gl_get_context ( ) - > fb - > cmode . bytesPerPixel , DisposeAfterUse : : NO ) ,
_x ( other . _x ) , _y ( other . _y ) , _length ( other . _length ) {
2014-07-13 16:17:17 +02:00
_buf . copyBuffer ( 0 , 0 , _length , other . _buf ) ;
_pixels = _buf . getRawBuffer ( ) ;
}
~ Line ( ) {
_buf . free ( ) ;
}
} ;
2014-08-01 19:27:28 +02:00
FORCEINLINE bool clipBlitImage ( TinyGL : : GLContext * c , int & srcX , int & srcY , int & srcWidth , int & srcHeight , int & width , int & height , int & dstX , int & dstY , int & clampWidth , int & clampHeight ) {
2014-07-15 16:32:14 +02:00
if ( srcWidth = = 0 | | srcHeight = = 0 ) {
srcWidth = _surface . w ;
srcHeight = _surface . h ;
}
if ( width = = 0 & & height = = 0 ) {
width = srcWidth ;
height = srcHeight ;
}
2014-08-13 21:03:42 +02:00
if ( dstX > = c - > _scissorRect . right | | dstY > = c - > _scissorRect . bottom )
2014-07-15 16:32:14 +02:00
return false ;
2014-08-13 21:03:42 +02:00
if ( dstX + width < c - > _scissorRect . left | | dstY + height < c - > _scissorRect . top ) {
2014-08-05 13:20:18 +02:00
return false ;
}
2014-08-13 21:03:42 +02:00
if ( dstX < c - > _scissorRect . left ) {
srcX + = ( c - > _scissorRect . left - dstX ) ;
width - = ( c - > _scissorRect . left - dstX ) ;
dstX = c - > _scissorRect . left ;
2014-08-01 19:27:28 +02:00
}
2014-08-13 21:03:42 +02:00
if ( dstY < c - > _scissorRect . top ) {
srcY + = ( c - > _scissorRect . top - dstY ) ;
height - = ( c - > _scissorRect . top - dstY ) ;
dstY = c - > _scissorRect . top ;
2014-08-01 19:27:28 +02:00
}
2014-08-05 13:20:18 +02:00
if ( width < 0 | | height < 0 ) {
return false ;
}
2014-08-13 21:03:42 +02:00
if ( dstX + width > c - > _scissorRect . right )
clampWidth = c - > _scissorRect . right - dstX ;
2014-07-15 16:32:14 +02:00
else
clampWidth = width ;
2014-08-13 21:03:42 +02:00
if ( dstY + height > c - > _scissorRect . bottom )
clampHeight = c - > _scissorRect . bottom - dstY ;
2014-07-15 16:32:14 +02:00
else
clampHeight = height ;
return true ;
}
2014-08-10 22:02:06 +02:00
// Blits an image to the z buffer.
// The function only supports clipped blitting without any type of transformation or tinting.
2014-07-25 15:45:12 +02:00
void tglBlitZBuffer ( int dstX , int dstY ) {
TinyGL : : GLContext * c = TinyGL : : gl_get_context ( ) ;
int clampWidth , clampHeight ;
int width = _surface . w , height = _surface . h ;
int srcWidth = 0 , srcHeight = 0 ;
2014-08-01 19:27:28 +02:00
int srcX = 0 , srcY = 0 ;
if ( clipBlitImage ( c , srcX , srcY , srcWidth , srcHeight , width , height , dstX , dstY , clampWidth , clampHeight ) = = false )
2014-07-25 15:45:12 +02:00
return ;
2014-08-10 22:02:06 +02:00
Graphics : : PixelBuffer srcBuf ( _surface . format , ( byte * ) const_cast < void * > ( _surface . getPixels ( ) ) ) ; // Blit image buffer
Graphics : : PixelBuffer dstBuf ( _surface . format , ( byte * ) c - > fb - > getZBuffer ( ) ) ; // TinyGL z buffer
2014-07-25 15:45:12 +02:00
2014-08-02 21:46:07 +02:00
srcBuf . shiftBy ( srcY * _surface . w ) ;
2014-08-01 19:27:28 +02:00
dstBuf . shiftBy ( dstY * c - > fb - > xsize ) ;
2014-08-10 19:35:29 +02:00
for ( int y = 0 ; y < clampHeight ; y + + ) {
2014-08-02 21:46:07 +02:00
dstBuf . copyBuffer ( dstX , srcX , clampWidth , srcBuf ) ;
2014-07-25 15:45:12 +02:00
dstBuf . shiftBy ( c - > fb - > xsize ) ;
2014-08-01 19:27:28 +02:00
srcBuf . shiftBy ( _surface . w ) ;
2014-07-25 15:45:12 +02:00
}
}
2014-08-10 20:29:09 +02:00
template < bool kDisableColoring , bool kDisableBlending , bool kEnableAlphaBlending >
2014-07-17 13:38:23 +02:00
FORCEINLINE void tglBlitRLE ( int dstX , int dstY , int srcX , int srcY , int srcWidth , int srcHeight , float aTint , float rTint , float gTint , float bTint ) ;
2014-07-15 16:32:14 +02:00
2014-08-10 20:29:09 +02:00
template < bool kDisableBlending , bool kDisableColoring , bool kFlipVertical , bool kFlipHorizontal >
2014-07-17 13:38:23 +02:00
FORCEINLINE void tglBlitSimple ( int dstX , int dstY , int srcX , int srcY , int srcWidth , int srcHeight , float aTint , float rTint , float gTint , float bTint ) ;
2014-07-15 16:32:14 +02:00
2014-08-10 20:29:09 +02:00
template < bool kDisableBlending , bool kDisableColoring , bool kFlipVertical , bool kFlipHorizontal >
2014-07-17 13:38:23 +02:00
FORCEINLINE void tglBlitScale ( int dstX , int dstY , int width , int height , int srcX , int srcY , int srcWidth , int srcHeight , float aTint , float rTint , float gTint , float bTint ) ;
2014-07-15 16:32:14 +02:00
2014-08-10 20:29:09 +02:00
template < bool kDisableBlending , bool kDisableColoring , bool kFlipVertical , bool kFlipHorizontal >
2014-07-17 13:38:23 +02:00
FORCEINLINE void tglBlitRotoScale ( int dstX , int dstY , int width , int height , int srcX , int srcY , int srcWidth , int srcHeight , int rotation ,
2014-07-15 16:32:14 +02:00
int originX , int originY , float aTint , float rTint , float gTint , float bTint ) ;
2014-08-10 20:17:31 +02:00
//Utility function that calls the correct blitting function.
2014-08-10 20:29:09 +02:00
template < bool kDisableBlending , bool kDisableColoring , bool kDisableTransform , bool kFlipVertical , bool kFlipHorizontal , bool kEnableAlphaBlending >
2014-07-15 16:32:14 +02:00
FORCEINLINE void tglBlitGeneric ( const BlitTransform & transform ) {
2014-08-10 20:29:09 +02:00
if ( kDisableTransform ) {
if ( ( kDisableBlending | | kEnableAlphaBlending ) & & kFlipVertical = = false & & kFlipHorizontal = = false ) {
2014-08-13 21:11:24 +02:00
tglBlitRLE < kDisableColoring , kDisableBlending , kEnableAlphaBlending > ( transform . _destinationRectangle . left ,
transform . _destinationRectangle . top , transform . _sourceRectangle . left , transform . _sourceRectangle . top ,
transform . _sourceRectangle . width ( ) , transform . _sourceRectangle . height ( ) , transform . _aTint ,
transform . _rTint , transform . _gTint , transform . _bTint ) ;
2014-07-15 16:32:14 +02:00
} else {
2014-08-13 21:11:24 +02:00
tglBlitSimple < kDisableBlending , kDisableColoring , kFlipVertical , kFlipHorizontal > ( transform . _destinationRectangle . left ,
transform . _destinationRectangle . top , transform . _sourceRectangle . left , transform . _sourceRectangle . top ,
transform . _sourceRectangle . width ( ) , transform . _sourceRectangle . height ( ) ,
2014-07-15 16:32:14 +02:00
transform . _aTint , transform . _rTint , transform . _gTint , transform . _bTint ) ;
}
} else {
if ( transform . _rotation = = 0 ) {
2014-08-13 21:11:24 +02:00
tglBlitScale < kDisableBlending , kDisableColoring , kFlipVertical , kFlipHorizontal > ( transform . _destinationRectangle . left ,
transform . _destinationRectangle . top , transform . _destinationRectangle . width ( ) , transform . _destinationRectangle . height ( ) ,
transform . _sourceRectangle . left , transform . _sourceRectangle . top , transform . _sourceRectangle . width ( ) , transform . _sourceRectangle . height ( ) ,
transform . _aTint , transform . _rTint , transform . _gTint , transform . _bTint ) ;
2014-07-15 16:32:14 +02:00
} else {
2014-08-13 21:11:24 +02:00
tglBlitRotoScale < kDisableBlending , kDisableColoring , kFlipVertical , kFlipHorizontal > ( transform . _destinationRectangle . left ,
transform . _destinationRectangle . top , transform . _destinationRectangle . width ( ) , transform . _destinationRectangle . height ( ) ,
transform . _sourceRectangle . left , transform . _sourceRectangle . top , transform . _sourceRectangle . width ( ) ,
transform . _sourceRectangle . height ( ) , transform . _rotation , transform . _originX , transform . _originY , transform . _aTint ,
transform . _rTint , transform . _gTint , transform . _bTint ) ;
2014-07-15 16:32:14 +02:00
}
}
}
2014-08-13 21:13:50 +02:00
int getWidth ( ) const { return _surface . w ; }
int getHeight ( ) const { return _surface . h ; }
void dispose ( ) { _isDisposed = true ; }
bool isDisposed ( ) const { return _isDisposed ; }
private :
2014-08-10 19:34:47 +02:00
bool _isDisposed ;
2014-07-17 13:22:15 +02:00
bool _binaryTransparent ;
2014-07-13 16:17:17 +02:00
Common : : Array < Line > _lines ;
2014-07-07 18:17:54 +02:00
Graphics : : Surface _surface ;
2014-08-02 21:44:23 +02:00
int _version ;
2014-07-07 18:17:54 +02:00
} ;
2014-07-27 19:51:16 +02:00
void tglGetBlitImageSize ( BlitImage * blitImage , int & width , int & height ) {
2014-08-13 21:13:50 +02:00
width = blitImage - > getWidth ( ) ;
height = blitImage - > getHeight ( ) ;
2014-07-27 19:51:16 +02:00
}
2014-08-02 21:44:23 +02:00
int tglGetBlitImageVersion ( BlitImage * blitImage ) {
return blitImage - > getVersion ( ) ;
}
2014-07-07 21:14:58 +02:00
BlitImage * tglGenBlitImage ( ) {
2014-07-12 11:51:11 +02:00
TinyGL : : GLContext * c = TinyGL : : gl_get_context ( ) ;
2014-07-07 21:14:58 +02:00
BlitImage * image = new BlitImage ( ) ;
2014-08-09 12:17:40 +02:00
c - > _blitImages . push_back ( image ) ;
2014-07-07 21:14:58 +02:00
return image ;
2014-07-07 18:17:54 +02:00
}
2014-07-07 21:14:58 +02:00
void tglUploadBlitImage ( BlitImage * blitImage , const Graphics : : Surface & surface , uint32 colorKey , bool applyColorKey ) {
if ( blitImage ! = nullptr ) {
blitImage - > loadData ( surface , colorKey , applyColorKey ) ;
}
2014-07-07 18:17:54 +02:00
}
2014-07-07 21:14:58 +02:00
void tglDeleteBlitImage ( BlitImage * blitImage ) {
2014-08-13 15:38:00 +02:00
if ( blitImage ! = nullptr ) {
2014-08-13 21:13:50 +02:00
blitImage - > dispose ( ) ;
2014-08-13 15:38:00 +02:00
}
2014-07-07 18:17:54 +02:00
}
2014-08-10 22:02:06 +02:00
// This function uses RLE encoding to skip transparent bitmap parts
2014-08-13 21:21:09 +02:00
// This blit only supports tinting but it will fall back to simpleBlit
// if flipping is required (or anything more complex than that, including rotationd and scaling).
2014-08-10 20:29:09 +02:00
template < bool kDisableColoring , bool kDisableBlending , bool kEnableAlphaBlending >
2014-07-17 13:38:23 +02:00
FORCEINLINE void BlitImage : : tglBlitRLE ( int dstX , int dstY , int srcX , int srcY , int srcWidth , int srcHeight , float aTint , float rTint , float gTint , float bTint ) {
2014-07-13 18:49:27 +02:00
TinyGL : : GLContext * c = TinyGL : : gl_get_context ( ) ;
2014-07-02 19:08:47 +02:00
2014-07-13 18:49:27 +02:00
int clampWidth , clampHeight ;
int width = srcWidth , height = srcHeight ;
2014-08-01 19:27:28 +02:00
if ( clipBlitImage ( c , srcX , srcY , srcWidth , srcHeight , width , height , dstX , dstY , clampWidth , clampHeight ) = = false )
2014-07-13 18:49:27 +02:00
return ;
2014-07-17 13:22:15 +02:00
if ( aTint < = 0.0f )
return ;
2014-07-15 16:32:14 +02:00
Graphics : : PixelBuffer srcBuf ( _surface . format , ( byte * ) _surface . getPixels ( ) ) ;
srcBuf . shiftBy ( srcX + ( srcY * _surface . w ) ) ;
2014-07-07 18:17:54 +02:00
Graphics : : PixelBuffer dstBuf ( c - > fb - > cmode , c - > fb - > getPixelBuffer ( ) ) ;
2014-07-14 18:11:51 +02:00
dstBuf . shiftBy ( dstY * c - > fb - > xsize + dstX ) ;
2014-07-07 18:17:54 +02:00
2014-07-18 20:06:42 +02:00
int kBytesPerPixel = c - > fb - > cmode . bytesPerPixel ;
2014-07-13 19:00:14 +02:00
2014-07-16 14:18:01 +02:00
uint32 lineIndex = 0 ;
2014-07-13 19:00:14 +02:00
int maxY = srcY + clampHeight ;
int maxX = srcX + clampWidth ;
2014-07-15 16:32:14 +02:00
while ( lineIndex < _lines . size ( ) & & _lines [ lineIndex ] . _y < srcY ) {
2014-07-13 19:00:14 +02:00
lineIndex + + ;
}
2014-07-17 13:22:15 +02:00
2014-08-13 21:21:09 +02:00
if ( _binaryTransparent | | ( kDisableBlending | | ! kEnableAlphaBlending ) ) { // If bitmap is binary transparent or if we need complex forms of blending (not just alpha) we need to use writePixel, which is slower
2014-07-17 13:22:15 +02:00
while ( lineIndex < _lines . size ( ) & & _lines [ lineIndex ] . _y < maxY ) {
const BlitImage : : Line & l = _lines [ lineIndex ] ;
if ( l . _x < maxX & & l . _x + l . _length > srcX ) {
int length = l . _length ;
int skipStart = ( l . _x < srcX ) ? ( srcX - l . _x ) : 0 ;
length - = skipStart ;
int skipEnd = ( l . _x + l . _length > maxX ) ? ( l . _x + l . _length - maxX ) : 0 ;
length - = skipEnd ;
2014-08-10 20:29:09 +02:00
if ( kDisableColoring & & ( kEnableAlphaBlending = = false | | kDisableBlending ) ) {
2014-07-17 13:22:15 +02:00
memcpy ( dstBuf . getRawBuffer ( ( l . _y - srcY ) * c - > fb - > xsize + MAX ( l . _x - srcX , 0 ) ) ,
l . _pixels + skipStart * kBytesPerPixel , length * kBytesPerPixel ) ;
} else {
int xStart = MAX ( l . _x - srcX , 0 ) ;
2014-08-10 20:29:09 +02:00
if ( kDisableColoring ) {
2014-07-18 19:56:26 +02:00
dstBuf . copyBuffer ( xStart + ( l . _y - srcY ) * c - > fb - > xsize , skipStart , length , l . _buf ) ;
} else {
for ( int x = xStart ; x < xStart + length ; x + + ) {
byte aDst , rDst , gDst , bDst ;
srcBuf . getARGBAt ( ( l . _y - srcY ) * _surface . w + x , aDst , rDst , gDst , bDst ) ;
2014-07-17 13:22:15 +02:00
c - > fb - > writePixel ( ( dstX + x ) + ( dstY + ( l . _y - srcY ) ) * c - > fb - > xsize , aDst * aTint , rDst * rTint , gDst * gTint , bDst * bTint ) ;
}
}
2014-07-18 19:56:26 +02:00
2014-07-07 18:17:54 +02:00
}
}
2014-07-17 13:22:15 +02:00
lineIndex + + ;
}
2014-08-10 22:02:06 +02:00
} else { // Otherwise can use setPixel in some cases which speeds up things quite a bit
2014-07-17 13:22:15 +02:00
while ( lineIndex < _lines . size ( ) & & _lines [ lineIndex ] . _y < maxY ) {
const BlitImage : : Line & l = _lines [ lineIndex ] ;
if ( l . _x < maxX & & l . _x + l . _length > srcX ) {
int length = l . _length ;
int skipStart = ( l . _x < srcX ) ? ( srcX - l . _x ) : 0 ;
length - = skipStart ;
int skipEnd = ( l . _x + l . _length > maxX ) ? ( l . _x + l . _length - maxX ) : 0 ;
length - = skipEnd ;
2014-08-10 20:29:09 +02:00
if ( kDisableColoring & & ( kEnableAlphaBlending = = false | | kDisableBlending ) ) {
2014-07-17 13:22:15 +02:00
memcpy ( dstBuf . getRawBuffer ( ( l . _y - srcY ) * c - > fb - > xsize + MAX ( l . _x - srcX , 0 ) ) ,
l . _pixels + skipStart * kBytesPerPixel , length * kBytesPerPixel ) ;
} else {
int xStart = MAX ( l . _x - srcX , 0 ) ;
for ( int x = xStart ; x < xStart + length ; x + + ) {
byte aDst , rDst , gDst , bDst ;
srcBuf . getARGBAt ( ( l . _y - srcY ) * _surface . w + x , aDst , rDst , gDst , bDst ) ;
2014-08-10 20:29:09 +02:00
if ( kDisableColoring ) {
2014-07-17 13:22:15 +02:00
if ( aDst ! = 0xFF ) {
c - > fb - > writePixel ( ( dstX + x ) + ( dstY + ( l . _y - srcY ) ) * c - > fb - > xsize , aDst , rDst , gDst , bDst ) ;
} else {
dstBuf . setPixelAt ( x + ( l . _y - srcY ) * c - > fb - > xsize , aDst , rDst , gDst , bDst ) ;
}
} else {
c - > fb - > writePixel ( ( dstX + x ) + ( dstY + ( l . _y - srcY ) ) * c - > fb - > xsize , aDst * aTint , rDst * rTint , gDst * gTint , bDst * bTint ) ;
}
}
}
}
lineIndex + + ;
2014-07-02 19:08:47 +02:00
}
}
2014-07-07 18:17:54 +02:00
}
2014-08-10 22:02:06 +02:00
// This blit function is called when flipping is needed but transformation isn't.
2014-08-10 20:29:09 +02:00
template < bool kDisableBlending , bool kDisableColoring , bool kFlipVertical , bool kFlipHorizontal >
2014-07-17 13:38:23 +02:00
FORCEINLINE void BlitImage : : tglBlitSimple ( int dstX , int dstY , int srcX , int srcY , int srcWidth , int srcHeight , float aTint , float rTint , float gTint , float bTint ) {
2014-07-12 11:41:55 +02:00
TinyGL : : GLContext * c = TinyGL : : gl_get_context ( ) ;
2014-07-13 18:49:27 +02:00
int clampWidth , clampHeight ;
int width = srcWidth , height = srcHeight ;
2014-08-01 19:27:28 +02:00
if ( clipBlitImage ( c , srcX , srcY , srcWidth , srcHeight , width , height , dstX , dstY , clampWidth , clampHeight ) = = false )
2014-07-13 18:49:27 +02:00
return ;
2014-07-12 11:41:55 +02:00
2014-07-15 16:32:14 +02:00
Graphics : : PixelBuffer srcBuf ( _surface . format , ( byte * ) _surface . getPixels ( ) ) ;
2014-07-12 11:41:55 +02:00
2014-08-10 20:29:09 +02:00
if ( kFlipVertical ) {
2014-08-05 13:19:57 +02:00
srcBuf . shiftBy ( ( ( srcHeight - srcY - 1 ) * _surface . w ) ) ;
2014-07-13 18:49:27 +02:00
} else {
2014-08-05 13:19:57 +02:00
srcBuf . shiftBy ( ( srcY * _surface . w ) ) ;
2014-07-13 18:49:27 +02:00
}
2014-07-12 11:41:55 +02:00
2014-07-13 18:49:27 +02:00
Graphics : : PixelBuffer dstBuf ( c - > fb - > cmode , c - > fb - > getPixelBuffer ( ) ) ;
2014-07-12 11:41:55 +02:00
2014-08-10 19:35:29 +02:00
for ( int y = 0 ; y < clampHeight ; y + + ) {
for ( int x = 0 ; x < clampWidth ; + + x ) {
2014-07-13 18:49:27 +02:00
byte aDst , rDst , gDst , bDst ;
2014-08-10 20:29:09 +02:00
if ( kFlipHorizontal ) {
2014-08-10 19:35:29 +02:00
srcBuf . getARGBAt ( srcX + clampWidth - x , aDst , rDst , gDst , bDst ) ;
2014-07-13 18:49:27 +02:00
} else {
2014-08-10 19:35:29 +02:00
srcBuf . getARGBAt ( srcX + x , aDst , rDst , gDst , bDst ) ;
2014-07-13 18:49:27 +02:00
}
2014-08-10 22:02:06 +02:00
// Those branches are needed to favor speed: avoiding writePixel always yield a huge performance boost when blitting images.
if ( kDisableColoring ) {
2014-08-10 20:29:09 +02:00
if ( kDisableBlending & & aDst ! = 0 ) {
2014-08-10 19:35:29 +02:00
dstBuf . setPixelAt ( ( dstX + x ) + ( dstY + y ) * c - > fb - > xsize , aDst , rDst , gDst , bDst ) ;
2014-07-13 18:49:27 +02:00
} else {
2014-08-10 19:35:29 +02:00
c - > fb - > writePixel ( ( dstX + x ) + ( dstY + y ) * c - > fb - > xsize , aDst , rDst , gDst , bDst ) ;
2014-07-13 18:49:27 +02:00
}
} else {
2014-08-10 20:29:09 +02:00
if ( kDisableBlending & & aDst * aTint ! = 0 ) {
2014-08-10 19:35:29 +02:00
dstBuf . setPixelAt ( ( dstX + x ) + ( dstY + y ) * c - > fb - > xsize , aDst * aTint , rDst * rTint , gDst * gTint , bDst * bTint ) ;
2014-07-13 18:49:27 +02:00
} else {
2014-08-10 19:35:29 +02:00
c - > fb - > writePixel ( ( dstX + x ) + ( dstY + y ) * c - > fb - > xsize , aDst * aTint , rDst * rTint , gDst * gTint , bDst * bTint ) ;
2014-07-13 18:49:27 +02:00
}
}
}
2014-08-10 20:29:09 +02:00
if ( kFlipVertical ) {
2014-07-15 16:32:14 +02:00
srcBuf . shiftBy ( - _surface . w ) ;
2014-07-13 18:49:27 +02:00
} else {
2014-07-15 16:32:14 +02:00
srcBuf . shiftBy ( _surface . w ) ;
2014-07-13 18:49:27 +02:00
}
}
}
2014-07-12 11:41:55 +02:00
2014-08-13 21:21:09 +02:00
// This function is called when scale is needed: it uses a simple nearest
// filter to scale the blit image before copying it to the screen.
2014-08-10 20:29:09 +02:00
template < bool kDisableBlending , bool kDisableColoring , bool kFlipVertical , bool kFlipHorizontal >
2014-07-17 13:38:23 +02:00
FORCEINLINE void BlitImage : : tglBlitScale ( int dstX , int dstY , int width , int height , int srcX , int srcY , int srcWidth , int srcHeight ,
2014-07-13 18:51:33 +02:00
float aTint , float rTint , float gTint , float bTint ) {
2014-07-13 18:49:27 +02:00
TinyGL : : GLContext * c = TinyGL : : gl_get_context ( ) ;
2014-07-12 11:41:55 +02:00
2014-07-13 18:49:27 +02:00
int clampWidth , clampHeight ;
2014-08-01 19:27:28 +02:00
if ( clipBlitImage ( c , srcX , srcY , srcWidth , srcHeight , width , height , dstX , dstY , clampWidth , clampHeight ) = = false )
2014-07-13 18:49:27 +02:00
return ;
2014-07-12 11:41:55 +02:00
2014-07-15 16:32:14 +02:00
Graphics : : PixelBuffer srcBuf ( _surface . format , ( byte * ) _surface . getPixels ( ) ) ;
srcBuf . shiftBy ( srcX + ( srcY * _surface . w ) ) ;
2014-07-12 11:41:55 +02:00
Graphics : : PixelBuffer dstBuf ( c - > fb - > cmode , c - > fb - > getPixelBuffer ( ) ) ;
2014-08-10 19:35:29 +02:00
for ( int y = 0 ; y < clampHeight ; y + + ) {
for ( int x = 0 ; x < clampWidth ; + + x ) {
2014-07-13 18:49:27 +02:00
byte aDst , rDst , gDst , bDst ;
int xSource , ySource ;
2014-08-10 20:29:09 +02:00
if ( kFlipVertical ) {
2014-08-10 19:35:29 +02:00
ySource = clampHeight - y - 1 ;
2014-07-13 18:49:27 +02:00
} else {
2014-08-10 19:35:29 +02:00
ySource = y ;
2014-07-13 18:49:27 +02:00
}
2014-08-10 20:29:09 +02:00
if ( kFlipHorizontal ) {
2014-08-10 19:35:29 +02:00
xSource = clampWidth - x - 1 ;
2014-07-13 18:49:27 +02:00
} else {
2014-08-10 19:35:29 +02:00
xSource = x ;
2014-07-13 18:49:27 +02:00
}
2014-07-15 16:32:14 +02:00
srcBuf . getARGBAt ( ( ( ySource * srcHeight ) / height ) * _surface . w + ( ( xSource * srcWidth ) / width ) , aDst , rDst , gDst , bDst ) ;
2014-07-13 18:49:27 +02:00
2014-08-10 20:29:09 +02:00
if ( kDisableColoring ) {
if ( kDisableBlending & & aDst ! = 0 ) {
2014-08-10 19:35:29 +02:00
dstBuf . setPixelAt ( ( dstX + x ) + ( dstY + y ) * c - > fb - > xsize , aDst , rDst , gDst , bDst ) ;
2014-07-12 11:41:55 +02:00
} else {
2014-08-10 19:35:29 +02:00
c - > fb - > writePixel ( ( dstX + x ) + ( dstY + y ) * c - > fb - > xsize , aDst , rDst , gDst , bDst ) ;
2014-07-12 11:41:55 +02:00
}
2014-07-13 18:49:27 +02:00
} else {
2014-08-10 20:29:09 +02:00
if ( kDisableBlending & & aDst * aTint ! = 0 ) {
2014-08-10 19:35:29 +02:00
dstBuf . setPixelAt ( ( dstX + x ) + ( dstY + y ) * c - > fb - > xsize , aDst * aTint , rDst * rTint , gDst * gTint , bDst * bTint ) ;
2014-07-12 11:41:55 +02:00
} else {
2014-08-10 19:35:29 +02:00
c - > fb - > writePixel ( ( dstX + x ) + ( dstY + y ) * c - > fb - > xsize , aDst * aTint , rDst * rTint , gDst * gTint , bDst * bTint ) ;
2014-07-12 11:41:55 +02:00
}
2014-07-13 18:49:27 +02:00
}
}
}
}
2014-08-10 22:02:06 +02:00
/*
The below two functions are adapted from SDL_rotozoom . c ,
taken from SDL_gfx - 2.0 .18 .
Its copyright notice :
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
SDL_rotozoom . c : rotozoomer , zoomer and shrinker for 32 bit or 8 bit surfaces
Copyright ( C ) 2001 - 2012 Andreas Schiffler
This software is provided ' as - is ' , without any express or implied
warranty . In no event will the authors be held liable for any damages
arising from the use of this software .
Permission is granted to anyone to use this software for any purpose ,
including commercial applications , and to alter it and redistribute it
freely , subject to the following restrictions :
1. The origin of this software must not be misrepresented ; you must not
claim that you wrote the original software . If you use this software
in a product , an acknowledgment in the product documentation would be
appreciated but is not required .
2. Altered source versions must be plainly marked as such , and must not be
misrepresented as being the original software .
3. This notice may not be removed or altered from any source
distribution .
Andreas Schiffler - - aschiffler at ferzkopp dot net
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
The functions have been adapted for different structures and coordinate
systems .
*/
2014-08-10 20:29:09 +02:00
template < bool kDisableBlending , bool kDisableColoring , bool kFlipVertical , bool kFlipHorizontal >
2014-07-17 13:38:23 +02:00
FORCEINLINE void BlitImage : : tglBlitRotoScale ( int dstX , int dstY , int width , int height , int srcX , int srcY , int srcWidth , int srcHeight , int rotation ,
2014-07-13 18:49:27 +02:00
int originX , int originY , float aTint , float rTint , float gTint , float bTint ) {
TinyGL : : GLContext * c = TinyGL : : gl_get_context ( ) ;
2014-07-16 14:00:50 +02:00
2014-07-13 18:49:27 +02:00
int clampWidth , clampHeight ;
2014-08-01 19:27:28 +02:00
if ( clipBlitImage ( c , srcX , srcY , srcWidth , srcHeight , width , height , dstX , dstY , clampWidth , clampHeight ) = = false )
2014-07-13 18:49:27 +02:00
return ;
2014-07-16 14:00:50 +02:00
2014-07-15 16:32:14 +02:00
Graphics : : PixelBuffer srcBuf ( _surface . format , ( byte * ) _surface . getPixels ( ) ) ;
srcBuf . shiftBy ( srcX + ( srcY * _surface . w ) ) ;
2014-07-16 14:00:50 +02:00
2014-07-13 18:49:27 +02:00
Graphics : : PixelBuffer dstBuf ( c - > fb - > cmode , c - > fb - > getPixelBuffer ( ) ) ;
2014-07-16 14:00:50 +02:00
2014-07-13 18:49:27 +02:00
// Transform destination rectangle accordingly.
Common : : Rect destinationRectangle = rotateRectangle ( dstX , dstY , width , height , rotation , originX , originY ) ;
2014-07-16 14:00:50 +02:00
2014-07-13 18:49:27 +02:00
if ( dstX + destinationRectangle . width ( ) > c - > fb - > xsize )
clampWidth = c - > fb - > xsize - dstX ;
else
clampWidth = destinationRectangle . width ( ) ;
if ( dstY + destinationRectangle . height ( ) > c - > fb - > ysize )
clampHeight = c - > fb - > ysize - dstY ;
else
clampHeight = destinationRectangle . height ( ) ;
2014-07-16 14:00:50 +02:00
2014-07-13 18:49:27 +02:00
uint32 invAngle = 360 - ( rotation % 360 ) ;
float invCos = cos ( invAngle * M_PI / 180.0f ) ;
2014-07-16 14:04:14 +02:00
float invSin = sin ( invAngle * M_PI / 180.0f ) ;
2014-07-16 14:00:50 +02:00
2014-07-13 18:49:27 +02:00
int icosx = ( int ) ( invCos * ( 65536.0f * srcWidth / width ) ) ;
int isinx = ( int ) ( invSin * ( 65536.0f * srcWidth / width ) ) ;
int icosy = ( int ) ( invCos * ( 65536.0f * srcHeight / height ) ) ;
int isiny = ( int ) ( invSin * ( 65536.0f * srcHeight / height ) ) ;
2014-07-16 14:00:50 +02:00
2014-07-13 18:49:27 +02:00
int xd = ( srcX + originX ) < < 16 ;
int yd = ( srcY + originY ) < < 16 ;
2014-07-16 01:56:12 +02:00
int cx = originX * ( ( float ) width / srcWidth ) ;
int cy = originY * ( ( float ) height / srcHeight ) ;
2014-07-16 14:00:50 +02:00
2014-07-13 18:49:27 +02:00
int ax = - icosx * cx ;
int ay = - isiny * cx ;
int sw = width - 1 ;
int sh = height - 1 ;
2014-07-16 14:00:50 +02:00
2014-08-10 19:35:29 +02:00
for ( int y = 0 ; y < clampHeight ; y + + ) {
int t = cy - y ;
2014-07-13 18:49:27 +02:00
int sdx = ax + ( isinx * t ) + xd ;
int sdy = ay - ( icosy * t ) + yd ;
2014-08-10 19:35:29 +02:00
for ( int x = 0 ; x < clampWidth ; + + x ) {
2014-07-13 18:49:27 +02:00
byte aDst , rDst , gDst , bDst ;
2014-07-16 14:00:50 +02:00
2014-07-13 18:49:27 +02:00
int dx = ( sdx > > 16 ) ;
int dy = ( sdy > > 16 ) ;
2014-07-16 14:00:50 +02:00
2014-08-13 21:21:09 +02:00
if ( kFlipHorizontal ) {
2014-07-13 18:49:27 +02:00
dx = sw - dx ;
2014-08-13 21:21:09 +02:00
}
if ( kFlipVertical ) {
2014-07-13 18:49:27 +02:00
dy = sh - dy ;
2014-08-13 21:21:09 +02:00
}
2014-07-16 14:00:50 +02:00
2014-07-13 18:49:27 +02:00
if ( ( dx > = 0 ) & & ( dy > = 0 ) & & ( dx < srcWidth ) & & ( dy < srcHeight ) ) {
2014-07-15 16:32:14 +02:00
srcBuf . getARGBAt ( dy * _surface . w + dx , aDst , rDst , gDst , bDst ) ;
2014-08-10 20:29:09 +02:00
if ( kDisableColoring ) {
if ( kDisableBlending & & aDst ! = 0 ) {
2014-08-10 19:35:29 +02:00
dstBuf . setPixelAt ( ( dstX + x ) + ( dstY + y ) * c - > fb - > xsize , aDst , rDst , gDst , bDst ) ;
2014-07-12 11:41:55 +02:00
} else {
2014-08-10 19:35:29 +02:00
c - > fb - > writePixel ( ( dstX + x ) + ( dstY + y ) * c - > fb - > xsize , aDst , rDst , gDst , bDst ) ;
2014-07-12 11:41:55 +02:00
}
} else {
2014-08-10 20:29:09 +02:00
if ( kDisableBlending & & aDst * aTint ! = 0 ) {
2014-08-10 19:35:29 +02:00
dstBuf . setPixelAt ( ( dstX + x ) + ( dstY + y ) * c - > fb - > xsize , aDst * aTint , rDst * rTint , gDst * gTint , bDst * bTint ) ;
2014-07-12 11:41:55 +02:00
} else {
2014-08-10 19:35:29 +02:00
c - > fb - > writePixel ( ( dstX + x ) + ( dstY + y ) * c - > fb - > xsize , aDst * aTint , rDst * rTint , gDst * gTint , bDst * bTint ) ;
2014-07-12 11:41:55 +02:00
}
}
}
2014-07-13 18:49:27 +02:00
sdx + = icosx ;
sdy + = isiny ;
2014-07-12 11:41:55 +02:00
}
}
2014-07-16 02:24:34 +02:00
}
2014-07-23 15:18:57 +02:00
void tglBlit ( BlitImage * blitImage , int x , int y ) {
2014-07-23 21:37:45 +02:00
BlitTransform transform ( x , y ) ;
2014-08-07 17:38:11 +02:00
TinyGL : : tglIssueDrawCall ( new BlittingDrawCall ( blitImage , transform , BlittingDrawCall : : BlitMode_Regular ) ) ;
2014-07-23 15:18:57 +02:00
}
void tglBlit ( BlitImage * blitImage , const BlitTransform & transform ) {
2014-08-07 17:38:11 +02:00
TinyGL : : tglIssueDrawCall ( new BlittingDrawCall ( blitImage , transform , BlittingDrawCall : : BlitMode_Regular ) ) ;
2014-07-23 15:18:57 +02:00
}
void tglBlitNoBlend ( BlitImage * blitImage , const BlitTransform & transform ) {
2014-08-07 17:38:11 +02:00
TinyGL : : tglIssueDrawCall ( new BlittingDrawCall ( blitImage , transform , BlittingDrawCall : : BlitMode_NoBlend ) ) ;
2014-07-23 15:18:57 +02:00
}
void tglBlitFast ( BlitImage * blitImage , int x , int y ) {
2014-07-23 21:37:45 +02:00
BlitTransform transform ( x , y ) ;
2014-08-07 17:38:11 +02:00
TinyGL : : tglIssueDrawCall ( new BlittingDrawCall ( blitImage , transform , BlittingDrawCall : : BlitMode_Fast ) ) ;
2014-07-23 15:18:57 +02:00
}
2014-07-25 15:45:12 +02:00
void tglBlitZBuffer ( BlitImage * blitImage , int x , int y ) {
BlitTransform transform ( x , y ) ;
2014-08-07 17:38:11 +02:00
TinyGL : : tglIssueDrawCall ( new BlittingDrawCall ( blitImage , transform , BlittingDrawCall : : BlitMode_ZBuffer ) ) ;
2014-07-25 15:45:12 +02:00
}
2014-07-23 15:18:57 +02:00
namespace Internal {
2014-08-10 20:18:04 +02:00
template < bool kEnableAlphaBlending , bool kDisableColor , bool kDisableTransform , bool kDisableBlend >
void tglBlit ( BlitImage * blitImage , const BlitTransform & transform ) {
if ( transform . _flipHorizontally ) {
if ( transform . _flipVertically ) {
blitImage - > tglBlitGeneric < kDisableBlend , kDisableColor , kDisableTransform , true , true , kEnableAlphaBlending > ( transform ) ;
} else {
blitImage - > tglBlitGeneric < kDisableBlend , kDisableColor , kDisableTransform , false , true , kEnableAlphaBlending > ( transform ) ;
}
} else if ( transform . _flipVertically ) {
blitImage - > tglBlitGeneric < kDisableBlend , kDisableColor , kDisableTransform , true , false , kEnableAlphaBlending > ( transform ) ;
} else {
blitImage - > tglBlitGeneric < kDisableBlend , kDisableColor , kDisableTransform , false , false , kEnableAlphaBlending > ( transform ) ;
}
}
template < bool kEnableAlphaBlending , bool kDisableColor , bool kDisableTransform >
void tglBlit ( BlitImage * blitImage , const BlitTransform & transform , bool disableBlend ) {
if ( disableBlend ) {
tglBlit < kEnableAlphaBlending , kDisableColor , kDisableTransform , true > ( blitImage , transform ) ;
} else {
tglBlit < kEnableAlphaBlending , kDisableColor , kDisableTransform , false > ( blitImage , transform ) ;
}
}
template < bool kEnableAlphaBlending , bool kDisableColor >
void tglBlit ( BlitImage * blitImage , const BlitTransform & transform , bool disableTransform , bool disableBlend ) {
if ( disableTransform ) {
tglBlit < kEnableAlphaBlending , kDisableColor , true > ( blitImage , transform , disableBlend ) ;
} else {
tglBlit < kEnableAlphaBlending , kDisableColor , false > ( blitImage , transform , disableBlend ) ;
}
}
template < bool kEnableAlphaBlending >
void tglBlit ( BlitImage * blitImage , const BlitTransform & transform , bool disableColor , bool disableTransform , bool disableBlend ) {
if ( disableColor ) {
tglBlit < kEnableAlphaBlending , true > ( blitImage , transform , disableTransform , disableBlend ) ;
} else {
tglBlit < kEnableAlphaBlending , false > ( blitImage , transform , disableTransform , disableBlend ) ;
}
}
2014-07-07 21:14:58 +02:00
void tglBlit ( BlitImage * blitImage , const BlitTransform & transform ) {
2014-07-07 18:17:54 +02:00
TinyGL : : GLContext * c = TinyGL : : gl_get_context ( ) ;
bool disableColor = transform . _aTint = = 1.0f & & transform . _bTint = = 1.0f & & transform . _gTint = = 1.0f & & transform . _rTint = = 1.0f ;
2014-07-07 21:14:58 +02:00
bool disableTransform = transform . _destinationRectangle . width ( ) = = 0 & & transform . _destinationRectangle . height ( ) = = 0 & & transform . _rotation = = 0 ;
2014-07-25 15:23:50 +02:00
bool disableBlend = c - > fb - > isBlendingEnabled ( ) = = false ;
2014-07-17 13:22:15 +02:00
bool enableAlphaBlending = c - > fb - > isAlphaBlendingEnabled ( ) ;
2014-08-10 20:18:04 +02:00
2014-07-17 13:22:15 +02:00
if ( enableAlphaBlending ) {
2014-08-10 20:18:04 +02:00
tglBlit < true > ( blitImage , transform , disableColor , disableTransform , disableBlend ) ;
2014-07-07 18:17:54 +02:00
} else {
2014-08-10 20:18:04 +02:00
tglBlit < false > ( blitImage , transform , disableColor , disableTransform , disableBlend ) ;
2014-07-02 19:08:47 +02:00
}
2014-07-07 18:17:54 +02:00
}
2014-07-02 19:08:47 +02:00
2014-07-07 21:14:58 +02:00
void tglBlitNoBlend ( BlitImage * blitImage , const BlitTransform & transform ) {
2014-07-07 18:17:54 +02:00
if ( transform . _flipHorizontally = = false & & transform . _flipVertically = = false ) {
2014-07-17 13:22:15 +02:00
blitImage - > tglBlitGeneric < true , false , false , false , false , false > ( transform ) ;
2014-07-07 18:17:54 +02:00
} else if ( transform . _flipHorizontally = = false ) {
2014-07-17 13:22:15 +02:00
blitImage - > tglBlitGeneric < true , false , false , true , false , false > ( transform ) ;
2014-07-07 18:17:54 +02:00
} else {
2014-07-17 13:22:15 +02:00
blitImage - > tglBlitGeneric < true , false , false , false , true , false > ( transform ) ;
2014-07-02 19:08:47 +02:00
}
2014-07-07 18:17:54 +02:00
}
2014-07-02 19:08:47 +02:00
2014-07-07 21:14:58 +02:00
void tglBlitFast ( BlitImage * blitImage , int x , int y ) {
2014-07-07 18:17:54 +02:00
BlitTransform transform ( x , y ) ;
2014-07-17 13:22:15 +02:00
blitImage - > tglBlitGeneric < true , true , true , false , false , false > ( transform ) ;
2014-07-07 18:17:54 +02:00
}
2014-07-12 11:41:55 +02:00
2014-07-25 15:45:12 +02:00
void tglBlitZBuffer ( BlitImage * blitImage , int x , int y ) {
blitImage - > tglBlitZBuffer ( x , y ) ;
}
2014-07-23 21:37:45 +02:00
void tglCleanupImages ( ) {
TinyGL : : GLContext * c = TinyGL : : gl_get_context ( ) ;
2014-08-09 12:17:40 +02:00
Common : : List < BlitImage * > : : iterator it = c - > _blitImages . begin ( ) ;
while ( it ! = c - > _blitImages . end ( ) ) {
2014-08-13 21:13:50 +02:00
if ( ( * it ) - > isDisposed ( ) ) {
2014-08-09 12:17:11 +02:00
delete ( * it ) ;
2014-08-09 12:17:40 +02:00
it = c - > _blitImages . erase ( it ) ;
2014-08-09 12:17:11 +02:00
} else {
+ + it ;
2014-07-23 21:37:45 +02:00
}
}
}
2014-08-10 19:38:06 +02:00
void tglBlitSetScissorRect ( int left , int top , int right , int bottom ) {
2014-08-13 21:03:42 +02:00
TinyGL : : GLContext * c = TinyGL : : gl_get_context ( ) ;
c - > _scissorRect . left = left ;
c - > _scissorRect . right = right ;
c - > _scissorRect . top = top ;
c - > _scissorRect . bottom = bottom ;
if ( c - > _scissorRect . right = = 0 | | c - > _scissorRect . bottom = = 0 ) {
c - > _scissorRect . right = c - > fb - > xsize ;
c - > _scissorRect . bottom = c - > fb - > ysize ;
2014-08-03 22:16:18 +02:00
}
2014-08-01 19:27:28 +02:00
}
2014-07-23 15:18:57 +02:00
} // end of namespace Internal
2014-07-13 18:49:27 +02:00
Common : : Point transformPoint ( float x , float y , int rotation ) {
float rotateRad = rotation * M_PI / 180.0f ;
Common : : Point newPoint ;
newPoint . x = x * cos ( rotateRad ) - y * sin ( rotateRad ) ;
newPoint . y = x * sin ( rotateRad ) + y * cos ( rotateRad ) ;
return newPoint ;
}
Common : : Rect rotateRectangle ( int x , int y , int width , int height , int rotation , int originX , int originY ) {
Common : : Point nw , ne , sw , se ;
nw = transformPoint ( x - originX , y - originY , rotation ) ;
ne = transformPoint ( x + width - originX , y - originY , rotation ) ;
2014-07-16 14:00:50 +02:00
sw = transformPoint ( x + width - originX , y + height - originY , rotation ) ;
2014-07-13 18:49:27 +02:00
se = transformPoint ( x - originX , y + height - originY , rotation ) ;
float top = MIN ( nw . y , MIN ( ne . y , MIN ( sw . y , se . y ) ) ) ;
float bottom = MAX ( nw . y , MAX ( ne . y , MAX ( sw . y , se . y ) ) ) ;
float left = MIN ( nw . x , MIN ( ne . x , MIN ( sw . x , se . x ) ) ) ;
float right = MAX ( nw . x , MAX ( ne . x , MAX ( sw . x , se . x ) ) ) ;
Common : : Rect res ;
res . top = ( int32 ) ( floor ( top ) ) + originY ;
res . bottom = ( int32 ) ( ceil ( bottom ) ) + originY ;
res . left = ( int32 ) ( floor ( left ) ) + originX ;
res . right = ( int32 ) ( ceil ( right ) ) + originX ;
return res ;
}
2014-07-12 11:41:55 +02:00
}