@ -30,6 +30,7 @@ namespace olc {
olc : : Decal * decal ,
const olc : : vf2d & scale = { 1.0f , 1.0f } ,
const olc : : Pixel & tint = olc : : WHITE ) const ;
void DrawRectDecal ( const olc : : vf2d & pos , const olc : : vf2d & size , const olc : : Pixel col = olc : : WHITE ) const ;
void DrawPartialDecal ( const olc : : vf2d & pos ,
olc : : Decal * decal ,
const olc : : vf2d & source_pos ,
@ -46,6 +47,7 @@ namespace olc {
const olc : : vf2d * pos ,
const olc : : vf2d * uv ,
const olc : : Pixel * col ,
const float * ws ,
uint32_t elements = 4 ) const ;
void DrawWarpedDecal ( Decal * decal ,
const vf2d ( & pos ) [ 4 ] ,
@ -124,6 +126,7 @@ namespace olc {
const vf2d * points ,
const vf2d * uvs ,
const Pixel * col ,
const float * ws ,
uint32_t elements = 0 ) const ;
static float lineSegmentIntersect ( vf2d lineA ,
@ -226,8 +229,9 @@ void olc::ViewPort::DrawExplicitDecal(olc::Decal *decal,
const olc : : vf2d * pos ,
const olc : : vf2d * uv ,
const olc : : Pixel * col ,
const float * ws ,
uint32_t elements ) const {
drawClippedDecal ( decal , pos , uv , col , elements ) ;
drawClippedDecal ( decal , pos , uv , col , ws , elements ) ;
}
void olc : : ViewPort : : DrawWarpedDecal ( Decal * decal ,
@ -238,6 +242,9 @@ void olc::ViewPort::DrawWarpedDecal(Decal *decal,
void olc : : ViewPort : : DrawWarpedDecal ( Decal * decal ,
const vf2d * pos ,
const Pixel & tint ) const {
std : : vector < float > w { 1 , 1 , 1 , 1 } ;
std : : vector < olc : : vf2d > newPos ;
newPos . resize ( 4 ) ;
std : : vector < vf2d > uvs {
{ 0 , 0 } ,
{ 0 , 1 } ,
@ -251,7 +258,26 @@ void olc::ViewPort::DrawWarpedDecal(Decal *decal,
tint ,
} ;
drawClippedDecal ( decal , pos , uvs . data ( ) , cols . data ( ) , 4 ) ;
olc : : vf2d vInvScreenSize = { 1.0f / pge - > GetScreenSize ( ) . x , 1.0f / pge - > GetScreenSize ( ) . y } ;
olc : : vf2d center ;
float rd = ( ( pos [ 2 ] . x - pos [ 0 ] . x ) * ( pos [ 3 ] . y - pos [ 1 ] . y ) - ( pos [ 3 ] . x - pos [ 1 ] . x ) * ( pos [ 2 ] . y - pos [ 0 ] . y ) ) ;
if ( rd ! = 0 )
{
rd = 1.0f / rd ;
float rn = ( ( pos [ 3 ] . x - pos [ 1 ] . x ) * ( pos [ 0 ] . y - pos [ 1 ] . y ) - ( pos [ 3 ] . y - pos [ 1 ] . y ) * ( pos [ 0 ] . x - pos [ 1 ] . x ) ) * rd ;
float sn = ( ( pos [ 2 ] . x - pos [ 0 ] . x ) * ( pos [ 0 ] . y - pos [ 1 ] . y ) - ( pos [ 2 ] . y - pos [ 0 ] . y ) * ( pos [ 0 ] . x - pos [ 1 ] . x ) ) * rd ;
if ( ! ( rn < 0.f | | rn > 1.f | | sn < 0.f | | sn > 1.f ) ) center = pos [ 0 ] + rn * ( pos [ 2 ] - pos [ 0 ] ) ;
float d [ 4 ] ; for ( int i = 0 ; i < 4 ; i + + ) d [ i ] = ( pos [ i ] - center ) . mag ( ) ;
for ( int i = 0 ; i < 4 ; i + + )
{
float q = d [ i ] = = 0.0f ? 1.0f : ( d [ i ] + d [ ( i + 2 ) & 3 ] ) / d [ ( i + 2 ) & 3 ] ;
uvs [ i ] * = q ; w [ i ] * = q ;
}
drawClippedDecal ( decal , pos , uvs . data ( ) , cols . data ( ) , w . data ( ) , 4 ) ;
}
}
void olc : : ViewPort : : DrawWarpedDecal ( Decal * decal ,
const std : : array < vf2d , 4 > & pos ,
@ -297,7 +323,25 @@ void olc::ViewPort::DrawPartialWarpedDecal(Decal *decal,
tint ,
} ;
drawClippedDecal ( decal , pos , uvs . data ( ) , cols . data ( ) , 4 ) ;
std : : vector < float > ws { 1 , 1 , 1 , 1 } ;
olc : : vf2d center ;
float rd = ( ( pos [ 2 ] . x - pos [ 0 ] . x ) * ( pos [ 3 ] . y - pos [ 1 ] . y ) - ( pos [ 3 ] . x - pos [ 1 ] . x ) * ( pos [ 2 ] . y - pos [ 0 ] . y ) ) ;
if ( rd ! = 0 )
{
rd = 1.0f / rd ;
float rn = ( ( pos [ 3 ] . x - pos [ 1 ] . x ) * ( pos [ 0 ] . y - pos [ 1 ] . y ) - ( pos [ 3 ] . y - pos [ 1 ] . y ) * ( pos [ 0 ] . x - pos [ 1 ] . x ) ) * rd ;
float sn = ( ( pos [ 2 ] . x - pos [ 0 ] . x ) * ( pos [ 0 ] . y - pos [ 1 ] . y ) - ( pos [ 2 ] . y - pos [ 0 ] . y ) * ( pos [ 0 ] . x - pos [ 1 ] . x ) ) * rd ;
if ( ! ( rn < 0.f | | rn > 1.f | | sn < 0.f | | sn > 1.f ) ) center = pos [ 0 ] + rn * ( pos [ 2 ] - pos [ 0 ] ) ;
float d [ 4 ] ; for ( int i = 0 ; i < 4 ; i + + ) d [ i ] = ( pos [ i ] - center ) . mag ( ) ;
for ( int i = 0 ; i < 4 ; i + + )
{
float q = d [ i ] = = 0.0f ? 1.0f : ( d [ i ] + d [ ( i + 2 ) & 3 ] ) / d [ ( i + 2 ) & 3 ] ;
uvs [ i ] * = q ; ws [ i ] * = q ;
}
drawClippedDecal ( decal , pos , uvs . data ( ) , cols . data ( ) , ws . data ( ) , 4 ) ;
}
}
void olc : : ViewPort : : DrawPartialWarpedDecal ( Decal * decal ,
@ -369,7 +413,7 @@ void olc::ViewPort::FillRectDecal(const vf2d &pos,
pos ,
{ pos . x , pos . y + size . y } ,
pos + size ,
{ pos . x + size . y , pos . y } ,
{ pos . x + size . x , pos . y } ,
} ;
std : : vector < vf2d > uvs {
{ 0 , 0 } ,
@ -391,7 +435,7 @@ void olc::ViewPort::GradientFillRectDecal(const vf2d &pos,
pos ,
{ pos . x , pos . y + size . y } ,
pos + size ,
{ pos . x + size . y , pos . y } ,
{ pos . x + size . x , pos . y } ,
} ;
std : : vector < vf2d > uvs {
@ -408,7 +452,9 @@ void olc::ViewPort::GradientFillRectDecal(const vf2d &pos,
colTR ,
} ;
drawClippedDecal ( nullptr , points . data ( ) , uvs . data ( ) , colors . data ( ) , points . size ( ) ) ;
std : : vector < float > w { 1 , 1 , 1 , 1 } ;
drawClippedDecal ( nullptr , points . data ( ) , uvs . data ( ) , colors . data ( ) , w . data ( ) , points . size ( ) ) ;
}
void olc : : ViewPort : : DrawPolygonDecal ( Decal * decal ,
@ -421,7 +467,9 @@ void olc::ViewPort::DrawPolygonDecal(Decal *decal,
colors [ i ] = tint ;
}
drawClippedDecal ( decal , pos . data ( ) , uv . data ( ) , colors . data ( ) , pos . size ( ) ) ;
std : : vector < float > w { 1 , 1 , 1 , 1 } ;
drawClippedDecal ( decal , pos . data ( ) , uv . data ( ) , colors . data ( ) , w . data ( ) , pos . size ( ) ) ;
}
void olc : : ViewPort : : DrawPolygonDecal ( Decal * decal ,
@ -436,7 +484,8 @@ void olc::ViewPort::DrawPolygonDecal(Decal *decal,
const std : : vector < vf2d > & pos ,
const std : : vector < vf2d > & uv ,
const std : : vector < Pixel > & tint ) const {
drawClippedDecal ( decal , pos . data ( ) , uv . data ( ) , tint . data ( ) , pos . size ( ) ) ;
std : : vector < float > w { 1 , 1 , 1 , 1 } ;
drawClippedDecal ( decal , pos . data ( ) , uv . data ( ) , tint . data ( ) , w . data ( ) , pos . size ( ) ) ;
}
void olc : : ViewPort : : DrawLineDecal ( const vf2d & pos1 ,
@ -471,9 +520,11 @@ void olc::ViewPort::drawClippedDecal(Decal *decal,
const vf2d * points ,
const vf2d * uvs ,
const Pixel * col ,
const float * ws ,
uint32_t elements ) const {
std : : vector < vf2d > outputList { points , points + elements } ;
std : : vector < vf2d > outputUvs { uvs , uvs + elements } ;
std : : vector < float > outputWs { ws , ws + elements } ;
std : : vector < Pixel > outputCols { col , col + elements } ;
for ( auto i = 0u ; i < clipVertices . size ( ) ; i + + ) {
@ -482,9 +533,11 @@ void olc::ViewPort::drawClippedDecal(Decal *decal,
auto inputList { outputList } ;
auto inputUvs { outputUvs } ;
auto inputWs { outputWs } ;
auto inputCols { outputCols } ;
outputList . clear ( ) ;
outputUvs . clear ( ) ;
outputWs . clear ( ) ;
outputCols . clear ( ) ;
for ( auto i = 0u ; i < inputList . size ( ) ; i + + ) {
@ -492,6 +545,8 @@ void olc::ViewPort::drawClippedDecal(Decal *decal,
auto polygonB = inputList [ ( i + 1 ) % inputList . size ( ) ] ;
auto uvA = inputUvs [ i ] ;
auto uvB = inputUvs [ ( i + 1 ) % inputList . size ( ) ] ;
auto Wa = inputWs [ i ] ;
auto Wb = inputWs [ ( i + 1 ) % inputList . size ( ) ] ;
auto colA = inputCols [ i ] ;
auto colB = inputCols [ ( i + 1 ) % inputList . size ( ) ] ;
@ -500,6 +555,7 @@ void olc::ViewPort::drawClippedDecal(Decal *decal,
auto intersectionPoint =
polygonA + ( polygonB - polygonA ) * intersection ;
auto intersectionUv = uvA + ( uvB - uvA ) * intersection ;
auto intersectionW = Wa + ( Wb - Wa ) * intersection ;
auto intersectionCol = PixelLerp ( colA , colB , intersection ) ;
float aDirection = directionFromLine ( clipA , clipB , polygonA ) ;
@ -509,14 +565,17 @@ void olc::ViewPort::drawClippedDecal(Decal *decal,
if ( aDirection > 0 ) {
outputList . push_back ( intersectionPoint ) ;
outputUvs . push_back ( intersectionUv ) ;
outputWs . push_back ( intersectionW ) ;
outputCols . push_back ( intersectionCol ) ;
}
outputList . push_back ( polygonB ) ;
outputUvs . push_back ( uvB ) ;
outputWs . push_back ( Wb ) ;
outputCols . push_back ( colB ) ;
} else if ( aDirection < = 0 ) {
outputList . push_back ( intersectionPoint ) ;
outputUvs . push_back ( intersectionUv ) ;
outputWs . push_back ( intersectionW ) ;
outputCols . push_back ( intersectionCol ) ;
}
}
@ -534,6 +593,7 @@ void olc::ViewPort::drawClippedDecal(Decal *decal,
outputList . data ( ) ,
outputUvs . data ( ) ,
outputCols . data ( ) ,
outputWs . data ( ) ,
outputList . size ( ) ) ;
}
@ -772,4 +832,11 @@ void olc::ViewPort::DrawDropShadowStringDecal(Font&font, const olc::vf2d& pos, c
DrawDecal ( pos , garbageCollector [ key ] . decal , scale / 4 , col ) ;
}
void olc : : ViewPort : : DrawRectDecal ( const olc : : vf2d & pos , const olc : : vf2d & size , const olc : : Pixel col ) const {
FillRectDecal ( pos , { size . x , float ( pge - > GetPixelSize ( ) . y ) } , col ) ;
FillRectDecal ( pos + vf2d { 0 , size . y - float ( pge - > GetPixelSize ( ) . y ) } , { size . x , float ( pge - > GetPixelSize ( ) . y ) } , col ) ;
FillRectDecal ( pos + vf2d { 0 , float ( pge - > GetPixelSize ( ) . y ) } , { float ( pge - > GetPixelSize ( ) . x ) , size . y - float ( pge - > GetPixelSize ( ) . y ) * 2 } , col ) ;
FillRectDecal ( pos + vf2d { size . x - float ( pge - > GetPixelSize ( ) . x ) , float ( pge - > GetPixelSize ( ) . y ) } , { float ( pge - > GetPixelSize ( ) . x ) , size . y - float ( pge - > GetPixelSize ( ) . y ) * 2 } , col ) ;
}
# endif