diff --git a/librtt/Display/Rtt_ClosedPath.cpp b/librtt/Display/Rtt_ClosedPath.cpp index cd3c9e508..ad3033eaa 100644 --- a/librtt/Display/Rtt_ClosedPath.cpp +++ b/librtt/Display/Rtt_ClosedPath.cpp @@ -16,6 +16,8 @@ #include "Display/Rtt_Shader.h" #include "Renderer/Rtt_Program.h" +#include "Display/Rtt_CompositePaint.h" + // ---------------------------------------------------------------------------- namespace Rtt @@ -79,12 +81,37 @@ ClosedPath::SetSelfBounds( Real width, Real height ) return false; } +static bool +ComesFromImageSheet( const Paint* paint ) +{ + if ( paint->IsType( Paint::kImageSheet ) ) + { + return true; + } + + if ( !paint->IsType( Paint::kMultitexture ) ) + { + return false; + } + + const CompositePaint* composite = static_cast< const CompositePaint* >( paint ); + + if ( composite->GetPaint0() && composite->GetPaint0()->IsType( Paint::kImageSheet ) ) + { + return true; + } + + return false; +} + void ClosedPath::UpdatePaint( RenderData& data ) { if ( HasFill() ) { fFill->UpdatePaint( data ); + + data.fFromImageSheet = ComesFromImageSheet( fFill ); } if ( HasStroke() && fStrokeData ) diff --git a/librtt/Display/Rtt_CompositePaint.h b/librtt/Display/Rtt_CompositePaint.h index f03489bbd..b924a7118 100755 --- a/librtt/Display/Rtt_CompositePaint.h +++ b/librtt/Display/Rtt_CompositePaint.h @@ -36,6 +36,8 @@ class CompositePaint : public Paint public: virtual const Paint* AsPaint( Type t ) const; virtual void ApplyPaintUVTransformations( ArrayVertex2& vertices ) const override; + + const Paint* GetPaint0() const { return fPaint0; } // virtual const MLuaUserdataAdapter& GetAdapter() const; diff --git a/librtt/Display/Rtt_DisplayDefaults.cpp b/librtt/Display/Rtt_DisplayDefaults.cpp index 68d01bf3b..882e3b494 100644 --- a/librtt/Display/Rtt_DisplayDefaults.cpp +++ b/librtt/Display/Rtt_DisplayDefaults.cpp @@ -52,6 +52,7 @@ DisplayDefaults::DisplayDefaults() fIsImageSheetSampledInsideFrame( false ), fIsImageSheetFrameTrimCorrected( false ), fIsExternalTextureRetina( true ), + fIsUnitRegionWantedForBuiltinEffects( false ), fSkipsCull( false ), fSkipsHitTest( false ), fEnableDepthInScene( false ), diff --git a/librtt/Display/Rtt_DisplayDefaults.h b/librtt/Display/Rtt_DisplayDefaults.h index 5542efb38..220c3f42e 100644 --- a/librtt/Display/Rtt_DisplayDefaults.h +++ b/librtt/Display/Rtt_DisplayDefaults.h @@ -63,15 +63,18 @@ class DisplayDefaults U8 GetEmitterMapping() const { return fEmitterMapping; } void SetEmitterMapping( U8 newValue ) { fEmitterMapping = newValue; } - bool IsImageSheetSampledInsideFrame() const { return fIsImageSheetSampledInsideFrame;} + bool IsImageSheetSampledInsideFrame() const { return fIsImageSheetSampledInsideFrame; } void SetImageSheetSampledInsideFrame( bool newValue ) { fIsImageSheetSampledInsideFrame = newValue; } - bool IsImageSheetFrameTrimCorrected() const { return fIsImageSheetFrameTrimCorrected;} + bool IsImageSheetFrameTrimCorrected() const { return fIsImageSheetFrameTrimCorrected; } void SetImageSheetFrameTrimCorrected( bool newValue ) { fIsImageSheetFrameTrimCorrected = newValue; } - bool IsExternalTextureRetina() const { return fIsExternalTextureRetina;} + bool IsExternalTextureRetina() const { return fIsExternalTextureRetina; } void SetExternalTextureRetina( bool newValue ) { fIsExternalTextureRetina = newValue; } + bool IsUnitRegionWantedForBuiltinEffects() const { return fIsUnitRegionWantedForBuiltinEffects; } + void SetIsUnitRegionWantedForBuiltinEffects( bool newValue ) { fIsUnitRegionWantedForBuiltinEffects = newValue; } + public: bool IsV1Compatibility() const { return fV1Compatibility; } void SetV1Compatibility( bool newValue ) { fV1Compatibility = newValue; } @@ -144,6 +147,7 @@ class DisplayDefaults bool fIsImageSheetSampledInsideFrame; bool fIsImageSheetFrameTrimCorrected; bool fIsExternalTextureRetina; + bool fIsUnitRegionWantedForBuiltinEffects; bool fSkipsCull; bool fSkipsHitTest; bool fEnableDepthInScene; diff --git a/librtt/Display/Rtt_DisplayObject.cpp b/librtt/Display/Rtt_DisplayObject.cpp index 1dd4cc820..18716eafc 100644 --- a/librtt/Display/Rtt_DisplayObject.cpp +++ b/librtt/Display/Rtt_DisplayObject.cpp @@ -225,6 +225,9 @@ DisplayObject::DidChangePaint( RenderData& data ) data.fUserUniform1 = NULL; data.fUserUniform2 = NULL; data.fUserUniform3 = NULL; + + data.fFromImageSheet = false; + data.fWantsUnitRegion = false; } // ---------------------------------------------------------------------------- diff --git a/librtt/Display/Rtt_LuaLibDisplay.cpp b/librtt/Display/Rtt_LuaLibDisplay.cpp index e188edac6..cc1ec4624 100644 --- a/librtt/Display/Rtt_LuaLibDisplay.cpp +++ b/librtt/Display/Rtt_LuaLibDisplay.cpp @@ -1977,6 +1977,11 @@ DisplayLibrary::getDefault( lua_State *L ) bool value = defaults.IsExternalTextureRetina(); lua_pushboolean( L, value ? 1 : 0 ); } + else if ( ( Rtt_StringCompare( key, "isUnitRegionWantedForBuiltinEffects" ) == 0 ) ) + { + bool value = defaults.IsUnitRegionWantedForBuiltinEffects(); + lua_pushboolean( L, value ? 1 : 0 ); + } else if ( ( Rtt_StringCompare( key, "timeTransform" ) == 0 ) ) { const TimeTransform* transform = defaults.GetTimeTransform(); @@ -2169,6 +2174,11 @@ DisplayLibrary::setDefault( lua_State *L ) bool value = lua_toboolean( L, index ) ? true : false; defaults.SetExternalTextureRetina( value ); } + else if ( ( Rtt_StringCompare( key, "isUnitRegionWantedForBuiltinEffects" ) == 0 ) ) + { + bool value = lua_toboolean( L, index ) ? true : false; + defaults.SetIsUnitRegionWantedForBuiltinEffects( value ); + } else if ( ( Rtt_StringCompare( key, "timeTransform" ) == 0 ) ) { if ( lua_isstring( L, index ) ) diff --git a/librtt/Display/Rtt_Scene.cpp b/librtt/Display/Rtt_Scene.cpp index 0f280647a..2c3008eb5 100644 --- a/librtt/Display/Rtt_Scene.cpp +++ b/librtt/Display/Rtt_Scene.cpp @@ -210,6 +210,8 @@ Scene::Render( Renderer& renderer, PlatformSurface& rTarget, ProfilingEntryRAII* if ( ! IsValid() ) { + renderer.SetOptInToUnitRegionEncoding( GetDisplay().GetDefaults().IsUnitRegionWantedForBuiltinEffects() ); + const Rtt::Real kMillisecondsPerSecond = 1000.0f; Rtt_AbsoluteTime elapsedTime = fOwner.GetElapsedTime(); Rtt::Real totalTime = Rtt_AbsoluteToMilliseconds( elapsedTime ) / kMillisecondsPerSecond; @@ -318,6 +320,8 @@ Scene::Render( Renderer& renderer, PlatformSurface& rTarget, DisplayObject& obje const StageObject* stage = object.GetStage(); if ( Rtt_VERIFY( stage == fCurrentStage ) ) { + renderer.SetOptInToUnitRegionEncoding( GetDisplay().GetDefaults().IsUnitRegionWantedForBuiltinEffects() ); + Clear( renderer ); // This function is used to render a specific object in a scene. diff --git a/librtt/Display/Rtt_Shader.cpp b/librtt/Display/Rtt_Shader.cpp index dc1670098..b1594dfd1 100644 --- a/librtt/Display/Rtt_Shader.cpp +++ b/librtt/Display/Rtt_Shader.cpp @@ -255,6 +255,14 @@ Shader::Prepare( RenderData& objectData, int w, int h, ShaderResource::ProgramMo objectData.fProgram = program; + ShaderResource::UnitRegionPolicy policy = fResource->GetUnitRegionPolicy(); + if ( objectData.fFromImageSheet && ShaderResource::kNone != policy ) + { + objectData.fWantsUnitRegion = true; + objectData.fAlwaysUseUnitRegion = ShaderResource::kAlways == policy; + objectData.fHasDistortion = ShaderResource::k25D == mod; + } + const CoronaEffectCallbacks * callbacks = fResource->GetEffectCallbacks(); if (callbacks && callbacks->prepare) @@ -275,7 +283,9 @@ Shader::Draw( Renderer& renderer, const RenderData& objectData, const GeometryWr { if ( !renderer.CanAddGeometryWriters() ) // ignore during raw draws { - renderer.SetGeometryWriters( writers, n ); + bool encodeUnitRegion = objectData.fWantsUnitRegion && + ( objectData.fAlwaysUseUnitRegion || renderer.GetOptInToUnitRegionEncoding() ); + renderer.SetGeometryWriters( writers, n, encodeUnitRegion, objectData.fHasDistortion ); } DrawState state( fResource->GetEffectCallbacks(), fIsDrawing ); diff --git a/librtt/Display/Rtt_ShaderComposite.cpp b/librtt/Display/Rtt_ShaderComposite.cpp index 0a764f0c4..14cd78be1 100755 --- a/librtt/Display/Rtt_ShaderComposite.cpp +++ b/librtt/Display/Rtt_ShaderComposite.cpp @@ -305,7 +305,9 @@ ShaderComposite::Draw( Renderer& renderer, const RenderData& objectData, const G { if ( !renderer.CanAddGeometryWriters() ) // ignore during raw draws { - renderer.SetGeometryWriters( writers, n ); + bool encodeUnitRegion = objectData.fWantsUnitRegion && + ( objectData.fAlwaysUseUnitRegion || renderer.GetOptInToUnitRegionEncoding() ); + renderer.SetGeometryWriters( writers, n, encodeUnitRegion, objectData.fHasDistortion ); } DrawState state( fResource->GetEffectCallbacks(), fIsDrawing ); diff --git a/librtt/Display/Rtt_ShaderFactory.cpp b/librtt/Display/Rtt_ShaderFactory.cpp index cfd4a22c7..192fc10b2 100644 --- a/librtt/Display/Rtt_ShaderFactory.cpp +++ b/librtt/Display/Rtt_ShaderFactory.cpp @@ -768,6 +768,22 @@ ShaderFactory::InitializeBindings( lua_State *L, int shaderIndex, const SharedPt BindTimeTransform( L, shaderIndex, resource ); } + lua_getfield( L, shaderIndex, "wantUnitRegion" ); + + bool forBuiltins = LUA_TSTRING == lua_type( L, -1 ) && Rtt_StringCompare( lua_tostring( L, -1 ), "builtin" ) == 0; + + if (forBuiltins) + { + resource->SetUnitRegionPolicy( ShaderResource::kOptIn ); + } + + else if ( LUA_TBOOLEAN == lua_type( L, -1 ) && lua_toboolean( L, -1 ) ) + { + resource->SetUnitRegionPolicy( ShaderResource::kAlways ); + } + + lua_pop( L, 1 ); + bool has_vertex_data = BindVertexDataMap( L, shaderIndex, resource ); if( has_vertex_data ) { diff --git a/librtt/Display/Rtt_ShaderResource.cpp b/librtt/Display/Rtt_ShaderResource.cpp index 4669a51f8..34b35b8a3 100755 --- a/librtt/Display/Rtt_ShaderResource.cpp +++ b/librtt/Display/Rtt_ShaderResource.cpp @@ -268,6 +268,7 @@ ShaderResource::ShaderResource( Program *program, ShaderTypes::Category category fDetailsCount( 0U ), fShellTransform( NULL ), fTimeTransform( NULL ), + fUnitRegionPolicy( kNone ), fUsesUniforms( false ), fUsesTime( false ) { @@ -286,6 +287,7 @@ ShaderResource::ShaderResource( Program *program, ShaderTypes::Category category fDetailsCount( 0U ), fShellTransform( NULL ), fTimeTransform( NULL ), + fUnitRegionPolicy( kNone ), fUsesUniforms( false ), fUsesTime( false ) { diff --git a/librtt/Display/Rtt_ShaderResource.h b/librtt/Display/Rtt_ShaderResource.h index 0567f1061..bfc08e6eb 100644 --- a/librtt/Display/Rtt_ShaderResource.h +++ b/librtt/Display/Rtt_ShaderResource.h @@ -68,6 +68,15 @@ class ShaderResource } ProgramMod; + typedef enum UnitRegionPolicy + { + kNone = 0, + kAlways = 1, + kOptIn = 2, + kNumUnitRegionPolicies + } + UnitRegionPolicy; + typedef std::map< std::string, int > VertexDataMap; struct UniformData @@ -98,6 +107,9 @@ class ShaderResource bool UsesTime() const { return fUsesTime; } void SetUsesTime( bool newValue ) { fUsesTime = newValue; } + UnitRegionPolicy GetUnitRegionPolicy() const { return fUnitRegionPolicy; } + void SetUnitRegionPolicy( UnitRegionPolicy policy ) { fUnitRegionPolicy = policy; } + const CoronaEffectCallbacks * GetEffectCallbacks() const { return fEffectCallbacks; } void SetEffectCallbacks( CoronaEffectCallbacks * callbacks ); const CoronaShellTransform * GetShellTransform() const { return fShellTransform; } @@ -157,6 +169,7 @@ class ShaderResource std::vector< std::string > fDetailValues; U32 fDetailsCount; TimeTransform *fTimeTransform; + UnitRegionPolicy fUnitRegionPolicy; bool fUsesUniforms; bool fUsesTime; diff --git a/librtt/Display/Shader/shell_default_gl.lua b/librtt/Display/Shader/shell_default_gl.lua index cd28a7cbb..62496761a 100644 --- a/librtt/Display/Shader/shell_default_gl.lua +++ b/librtt/Display/Shader/shell_default_gl.lua @@ -21,7 +21,18 @@ uniform P_POSITION vec2 u_ContentScale; uniform P_POSITION mat4 u_ViewProjectionMatrix; #define CoronaVertexUserData a_UserData -#define CoronaTexCoord a_TexCoord.xy + +#if WANT_UNIT_REGION + // want decoded attributes, but varyings aren't readable in general, + // as elaborated below in main() + P_UV vec4 g_DecodedCoords; // (x, y) = texcoord, (z, w) = unit coords + + #define CoronaTexCoord g_DecodedCoords.xy + #define CoronaLocalTexCoord g_DecodedCoords.zw +#else + #define CoronaTexCoord a_TexCoord.xy + #define CoronaLocalTexCoord CoronaTexCoord +#endif #define CoronaTotalTime u_TotalTime #define CoronaDeltaTime u_DeltaTime @@ -67,6 +78,42 @@ varying P_DEFAULT vec4 v_UserData; P_POSITION vec2 VertexKernel( P_POSITION vec2 position ); #endif +#if WANT_UNIT_REGION + varying P_UV vec2 v_UnitCoords; + + P_UV vec2 CoronaAuxDecodeTexCoord( P_UV vec2 texCoord ) + { + P_UV vec2 isEncoded = step( vec2( .5 ), abs( texCoord - .5 ) ); // outside [0, 1]? + P_UV vec2 whichSide = sign( texCoord ); // if so, -1 (< 0) or +1 (> 1) + + g_DecodedCoords.zw = mix( texCoord, max( whichSide, 0. ), isEncoded ); // if decoded, 0 or 1 + + v_UnitCoords = g_DecodedCoords.zw; + + // "encoded" points interpret the texcoords like a + // (limited) mirrored repeat, so: + // < 0: -x + // from 0 to 1: just x (normal, not encoded) + // > 1: = 2 - x + + g_DecodedCoords.xy = mix( texCoord, ( whichSide + 1. ) - texCoord, isEncoded ); + + return g_DecodedCoords.xy; + } + + #ifdef TEX_COORD_Z + P_UV vec2 CoronaDecodeTexCoord( P_UV vec3 texCoord ) + { + return CoronaAuxDecodeTexCoord( texCoord.xy / texCoord.z ) * texCoord.z; + } + #else + #define CoronaDecodeTexCoord( texCoord ) CoronaAuxDecodeTexCoord( texCoord.xy ) + #endif + +#else + #define CoronaDecodeTexCoord( texCoord ) texCoord.xy +#endif + void main() { // "varying" are only meant as OUTPUT variables. ie: Write-only variables @@ -76,7 +123,7 @@ void main() // Certain devices, like the "Samsung Galaxy Tab 2", DON'T allow you to // use "varying" variable like any other local variables. - v_TexCoord = a_TexCoord.xy; + v_TexCoord = CoronaDecodeTexCoord( a_TexCoord ); #ifdef TEX_COORD_Z v_TexCoordZ = a_TexCoord.z; #endif @@ -122,6 +169,13 @@ varying P_DEFAULT vec4 v_UserData; #define CoronaColorScale( color ) (v_ColorScale*(color)) #define CoronaVertexUserData v_UserData +#if WANT_UNIT_REGION + varying P_UV vec2 v_UnitCoords; + #define CoronaLocalTexCoord( _ ) v_UnitCoords +#else + #define CoronaLocalTexCoord( texCoord ) texCoord +#endif + #define CoronaTotalTime u_TotalTime #define CoronaDeltaTime u_DeltaTime #define CoronaTexelSize u_TexelSize diff --git a/librtt/Renderer/Rtt_GLProgram.cpp b/librtt/Renderer/Rtt_GLProgram.cpp index 437697979..85c9e96da 100644 --- a/librtt/Renderer/Rtt_GLProgram.cpp +++ b/librtt/Renderer/Rtt_GLProgram.cpp @@ -363,8 +363,10 @@ GLProgram::UpdateShaderSource( Program* program, Program::Version version, Versi char highp_support[] = "#define FRAGMENT_SHADER_SUPPORTS_HIGHP 0\n"; highp_support[ sizeof( highp_support ) - 3 ] = ( CommandBuffer::GetGpuSupportsHighPrecisionFragmentShaders() ? '1' : '0' ); - //! \TODO Make the definition of "TEX_COORD_Z" conditional. - char texCoordZBuffer[] = "";//#define TEX_COORD_Z 1\n"; + ShaderResource * shaderResource = program->GetShaderResource(); + + char wantUnitRegionBuffer[] = "#define WANT_UNIT_REGION 0\n"; + wantUnitRegionBuffer[ sizeof( wantUnitRegionBuffer ) - 3] = ( shaderResource->GetUnitRegionPolicy() != ShaderResource::kNone ? '1' : '0' ); const char *program_header_source = program->GetHeaderSource(); const char *header = ( program_header_source ? program_header_source : "" ); @@ -374,7 +376,7 @@ GLProgram::UpdateShaderSource( Program* program, Program::Version version, Versi shader_source[0] = header; shader_source[1] = highp_support; shader_source[2] = maskBuffer; - shader_source[3] = texCoordZBuffer; + shader_source[3] = wantUnitRegionBuffer; if ( program->IsCompilerVerbose() ) { @@ -383,10 +385,9 @@ GLProgram::UpdateShaderSource( Program* program, Program::Version version, Versi data.fHeaderNumLines = CountLines( shader_source, numSegments ); } - ShaderResource * shaderResource = program->GetShaderResource(); const CoronaShellTransform * shellTransform = shaderResource->GetShellTransform(); CoronaShellTransformParams params = {}; - const char * hints[] = { "header", "highpSupport", "mask", "texCoordZ", NULL }; + const char * hints[] = { "header", "highpSupport", "mask", "wantUnitRegion", NULL }; void * shellTransformKey = &fCleanupShellTransform; // n.b. done to make cleanup robust std::vector< CoronaEffectDetail > details; diff --git a/librtt/Renderer/Rtt_Geometry_Renderer.cpp b/librtt/Renderer/Rtt_Geometry_Renderer.cpp index 96e292d0f..779bde8d5 100644 --- a/librtt/Renderer/Rtt_Geometry_Renderer.cpp +++ b/librtt/Renderer/Rtt_Geometry_Renderer.cpp @@ -53,6 +53,127 @@ GeometryWriter::CopyGeometryWriter() return sCopyGeometry; } +static float GetFloat( const void* bytes ) +{ + return *static_cast< const float* >( bytes ); +} + +static float GetFloatMappedTo0( const void* bytes ) +{ + float f = GetFloat( bytes ); + + return f > 0.f ? -f : 0.f; +} + +static float GetFloatMappedTo1( const void* bytes ) +{ + float f = GetFloat( bytes ); + + return f < 1.f ? 2. - f : 1.f; +} + +static void CopyFloat( void* dst, const float f ) +{ + memcpy( dst, &f, sizeof(float) ); +} + +void +GeometryWriter::UnitRegionEncode( void* dst, const void* src, const CoronaGeometryMappingLayout* layout, U32, U32 n ) +{ + Rtt_ASSERT( 4 == n ); // specialization for image sheet rects + + unsigned char * bytes = static_cast( dst ); + + // Bottom-left + float leftX = GetFloatMappedTo0( bytes ); + float bottomY = GetFloatMappedTo0( bytes + sizeof(float) ); + + CopyFloat( bytes, leftX ); + CopyFloat( bytes + sizeof(float), bottomY ); + + bytes += layout->outStride; + + // Upper-left + float topY = GetFloatMappedTo1( bytes + sizeof(float) ); + + CopyFloat( bytes, leftX ); + CopyFloat( bytes + sizeof(float), topY ); + + bytes += layout->outStride; + + // Bottom-right + float rightX = GetFloatMappedTo1( bytes ); + + CopyFloat( bytes, rightX ); + CopyFloat( bytes + sizeof(float), bottomY ); + + bytes += layout->outStride; + + // Upper-right + CopyFloat( bytes, rightX ); + CopyFloat( bytes + sizeof(float), topY ); +} + +static float MapDistortedFloatTo0( float f, float z ) +{ +/* + float raw = f / z, encoded = -raw; + + return encoded * z; +*/ + return -f; +} + +static float MapDistortedFloatTo1( float f, float z ) +{ +/* + float raw = f / z, encoded = 2.f - raw; + + return encoded * z; +*/ + return 2.f * z - f; +} + +static void GetFloatTriple( unsigned char* bytes, float xyz[] ) +{ + memcpy( xyz, bytes, 3 * sizeof(float) ); +} + +void +GeometryWriter::UnitRegionEncodeWithDistortion( void* dst, const void* src, const CoronaGeometryMappingLayout* layout, U32, U32 n ) +{ + Rtt_ASSERT( 4 == n ); // specialization for image sheet rects + + unsigned char * bytes = static_cast( dst ); + float xyz[3]; + + // Bottom-left + GetFloatTriple( bytes, xyz ); + CopyFloat( bytes, MapDistortedFloatTo0( xyz[0], xyz[2] ) ); + CopyFloat( bytes + sizeof(float), MapDistortedFloatTo0( xyz[1], xyz[2] ) ); + + bytes += layout->outStride; + + // Upper-left + GetFloatTriple( bytes, xyz ); + CopyFloat( bytes, MapDistortedFloatTo0( xyz[0], xyz[2] ) ); + CopyFloat( bytes + sizeof(float), MapDistortedFloatTo1( xyz[1], xyz[2] ) ); + + bytes += layout->outStride; + + // Bottom-right + GetFloatTriple( bytes, xyz ); + CopyFloat( bytes, MapDistortedFloatTo1( xyz[0], xyz[2] ) ); + CopyFloat( bytes + sizeof(float), MapDistortedFloatTo0( xyz[1], xyz[2] ) ); + + bytes += layout->outStride; + + // Upper-right + GetFloatTriple( bytes, xyz ); + CopyFloat( bytes, MapDistortedFloatTo1( xyz[0], xyz[2] ) ); + CopyFloat( bytes + sizeof(float), MapDistortedFloatTo1( xyz[1], xyz[2] ) ); +} + void Geometry::Vertex::Zero() { memset(this, 0, sizeof(*this)); diff --git a/librtt/Renderer/Rtt_Geometry_Renderer.h b/librtt/Renderer/Rtt_Geometry_Renderer.h index 0663992d6..662ab8441 100644 --- a/librtt/Renderer/Rtt_Geometry_Renderer.h +++ b/librtt/Renderer/Rtt_Geometry_Renderer.h @@ -71,6 +71,9 @@ struct GeometryWriter { Rtt_STATIC_ASSERT( ( kExtra == kMain + 1 ) && ( kIsUpdate == kAll + 1 ) ); static const GeometryWriter& CopyGeometryWriter(); + + static void UnitRegionEncode( void* dst, const void* src, const CoronaGeometryMappingLayout* layout, U32, U32 n ); + static void UnitRegionEncodeWithDistortion( void* dst, const void* src, const CoronaGeometryMappingLayout* layout, U32, U32 n ); const void* fContext; void (*fWriter)( void*, const void*, const CoronaGeometryMappingLayout*, U32, U32 ); diff --git a/librtt/Renderer/Rtt_RenderData.cpp b/librtt/Renderer/Rtt_RenderData.cpp index 800e43b71..a30903bcd 100644 --- a/librtt/Renderer/Rtt_RenderData.cpp +++ b/librtt/Renderer/Rtt_RenderData.cpp @@ -36,7 +36,11 @@ RenderData::RenderData() // fMinDepthRange( 0.0 ), // fMaxDepthRange( 1.0 ), fBlendMode(), - fBlendEquation( RenderTypes::kAddEquation ) + fBlendEquation( RenderTypes::kAddEquation ), + fFromImageSheet( false ), + fWantsUnitRegion( false ), + fAlwaysUseUnitRegion( false ), + fHasDistortion( false ) { } diff --git a/librtt/Renderer/Rtt_RenderData.h b/librtt/Renderer/Rtt_RenderData.h index 00bd30134..8211f0dcd 100644 --- a/librtt/Renderer/Rtt_RenderData.h +++ b/librtt/Renderer/Rtt_RenderData.h @@ -50,6 +50,12 @@ struct RenderData // Real fMaxDepthRange; BlendMode fBlendMode; RenderTypes::BlendEquation fBlendEquation; + + // for unit region mechanics: + bool fFromImageSheet; + bool fWantsUnitRegion; + bool fAlwaysUseUnitRegion; + bool fHasDistortion; }; // ---------------------------------------------------------------------------- diff --git a/librtt/Renderer/Rtt_Renderer.cpp b/librtt/Renderer/Rtt_Renderer.cpp index 419d78150..58de9d0e5 100644 --- a/librtt/Renderer/Rtt_Renderer.cpp +++ b/librtt/Renderer/Rtt_Renderer.cpp @@ -1281,12 +1281,12 @@ Renderer::IssueCaptures( Texture * fill0 ) } void -Renderer::SetGeometryWriters( const GeometryWriter* list, U32 n ) +Renderer::SetGeometryWriters( const GeometryWriter* list, U32 n, bool wantUnitRegion, bool hasDistortion ) { if ( 0 == n || list != fCurrentGeometryWriterList ) { fGeometryWriters.Clear(); - + if ( NULL == list ) { list = &GeometryWriter::CopyGeometryWriter(); @@ -1308,6 +1308,27 @@ Renderer::SetGeometryWriters( const GeometryWriter* list, U32 n ) Rtt_ASSERT( GeometryWriter::kAll == mask ); + if (wantUnitRegion) + { + GeometryWriter encode = {}; + + encode.fOffset = offsetof(Geometry::Vertex, u); + + if (hasDistortion) + { + encode.fWriter = GeometryWriter::UnitRegionEncodeWithDistortion; + } + + else + { + encode.fWriter = GeometryWriter::UnitRegionEncode; + } + + encode.fMask = GeometryWriter::kTexcoord; + + fGeometryWriters.Append( encode ); + } + fCurrentGeometryWriterList = list; } } diff --git a/librtt/Renderer/Rtt_Renderer.h b/librtt/Renderer/Rtt_Renderer.h index dc34e4beb..b21d13d22 100644 --- a/librtt/Renderer/Rtt_Renderer.h +++ b/librtt/Renderer/Rtt_Renderer.h @@ -259,7 +259,7 @@ class Renderer void IssueCaptures( Texture * fill0 ); public: - void SetGeometryWriters( const GeometryWriter* list, U32 n = 1 ); + void SetGeometryWriters( const GeometryWriter* list, U32 n = 1, bool wantUnitRegion = false, bool hasDistortion = false ); bool AddGeometryWriter( const GeometryWriter& writer, bool isUpdate ); bool CanAddGeometryWriters() const { return fCanAddGeometryWriters; } @@ -270,6 +270,10 @@ class Renderer Renderer& fRenderer; }; + public: + bool GetOptInToUnitRegionEncoding() const { return fOptInToUnitRegionEncoding; } + void SetOptInToUnitRegionEncoding( bool newValue ) { fOptInToUnitRegionEncoding = newValue; } + protected: void WriteGeometry ( void * dstGeomComp, const void* srcGeom, U32 stride, U32 index, U32 count = 1, GeometryWriter::MaskBits validBits = GeometryWriter::kMain ); @@ -411,6 +415,7 @@ class Renderer Array< GeometryWriter > fGeometryWriters; const GeometryWriter* fCurrentGeometryWriterList; // to detect change in writer; assumed to be stable object, i.e. either NULL (default) or some static array bool fCanAddGeometryWriters; + bool fOptInToUnitRegionEncoding; }; // ----------------------------------------------------------------------------