Merge branch 'development' into Fix_Issue_#1951_TCPObject_is_broken_3.10

This commit is contained in:
Areloch 2017-04-17 20:19:20 -05:00 committed by GitHub
commit 6cee446926
2553 changed files with 166354 additions and 22543 deletions

View file

@ -1,52 +0,0 @@
1.10
* Iterative cluster fit is now considered to be a new compression mode
* The core cluster fit is now 4x faster using contributions by Ignacio
Castano from NVIDIA
* The single colour lookup table has been halved by exploiting symmetry
1.9
* Added contributed SSE1 truncate implementation
* Changed use of SQUISH_USE_SSE to be 1 for SSE and 2 for SSE2 instructions
* Cluster fit is now iterative to further reduce image error
1.8
* Switched from using floor to trunc for much better SSE performance (again)
* Xcode build now expects libpng in /usr/local for extra/squishpng
1.7
* Fixed floating-point equality issue in clusterfit sort (x86 affected only)
* Implemented proper SSE(2) floor function for 50% speedup on SSE builds
* The range fit implementation now uses the correct colour metric
1.6
* Fixed bug in CompressImage where masked pixels were not skipped over
* DXT3 and DXT5 alpha compression now properly use the mask to ignore pixels
* Fixed major DXT1 bug that can generate unexpected transparent pixels
1.5
* Added CompressMasked function to handle incomplete DXT blocks more cleanly
* Added kWeightColourByAlpha flag for better quality images when alpha blending
1.4
* Fixed stack overflow in rangefit
1.3
* Worked around SSE floor implementation bug, proper fix needed!
* This release has visual studio and makefile builds that work
1.2
* Added provably optimal single colour compressor
* Added extra/squishgen.cpp that generates single colour lookup tables
1.1
* Fixed a DXT1 colour output bug
* Changed argument order for Decompress function to match Compress
* Added GetStorageRequirements function
* Added CompressImage function
* Added DecompressImage function
* Moved squishtool.cpp to extra/squishpng.cpp
* Added extra/squishtest.cpp
1.0
* Initial release

20
Engine/lib/squish/LICENSE Normal file
View file

@ -0,0 +1,20 @@
Copyright (c) 2006 Simon Brown si@sjbrown.co.uk
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View file

@ -24,8 +24,9 @@
-------------------------------------------------------------------------- */ -------------------------------------------------------------------------- */
#include "alpha.h" #include "alpha.h"
#include <climits>
#include <algorithm> #include <algorithm>
#include <limits.h>
namespace squish { namespace squish {

View file

@ -26,7 +26,7 @@
#ifndef SQUISH_ALPHA_H #ifndef SQUISH_ALPHA_H
#define SQUISH_ALPHA_H #define SQUISH_ALPHA_H
#include <squish.h> #include "squish.h"
namespace squish { namespace squish {

View file

@ -31,22 +31,21 @@
namespace squish { namespace squish {
ClusterFit::ClusterFit( ColourSet const* colours, int flags ) ClusterFit::ClusterFit( ColourSet const* colours, int flags, float* metric )
: ColourFit( colours, flags ) : ColourFit( colours, flags )
{ {
// set the iteration count // set the iteration count
m_iterationCount = ( m_flags & kColourIterativeClusterFit ) ? kMaxIterations : 1; m_iterationCount = ( m_flags & kColourIterativeClusterFit ) ? kMaxIterations : 1;
// initialise the best error // initialise the metric (old perceptual = 0.2126f, 0.7152f, 0.0722f)
m_besterror = VEC4_CONST( FLT_MAX ); if( metric )
m_metric = Vec4( metric[0], metric[1], metric[2], 1.0f );
// initialise the metric
bool perceptual = ( ( m_flags & kColourMetricPerceptual ) != 0 );
if( perceptual )
m_metric = Vec4( 0.2126f, 0.7152f, 0.0722f, 0.0f );
else else
m_metric = VEC4_CONST( 1.0f ); m_metric = VEC4_CONST( 1.0f );
// initialise the best error
m_besterror = VEC4_CONST( FLT_MAX );
// cache some values // cache some values
int const count = m_colours->GetCount(); int const count = m_colours->GetCount();
Vec3 const* values = m_colours->GetPoints(); Vec3 const* values = m_colours->GetPoints();

View file

@ -27,7 +27,7 @@
#ifndef SQUISH_CLUSTERFIT_H #ifndef SQUISH_CLUSTERFIT_H
#define SQUISH_CLUSTERFIT_H #define SQUISH_CLUSTERFIT_H
#include <squish.h> #include "squish.h"
#include "maths.h" #include "maths.h"
#include "simd.h" #include "simd.h"
#include "colourfit.h" #include "colourfit.h"
@ -37,7 +37,7 @@ namespace squish {
class ClusterFit : public ColourFit class ClusterFit : public ColourFit
{ {
public: public:
ClusterFit( ColourSet const* colours, int flags ); ClusterFit( ColourSet const* colours, int flags, float* metric );
private: private:
bool ConstructOrdering( Vec3 const& axis, int iteration ); bool ConstructOrdering( Vec3 const& axis, int iteration );

View file

@ -26,7 +26,7 @@
#ifndef SQUISH_COLOURBLOCK_H #ifndef SQUISH_COLOURBLOCK_H
#define SQUISH_COLOURBLOCK_H #define SQUISH_COLOURBLOCK_H
#include <squish.h> #include "squish.h"
#include "maths.h" #include "maths.h"
namespace squish { namespace squish {

View file

@ -34,6 +34,10 @@ ColourFit::ColourFit( ColourSet const* colours, int flags )
{ {
} }
ColourFit::~ColourFit()
{
}
void ColourFit::Compress( void* block ) void ColourFit::Compress( void* block )
{ {
bool isDxt1 = ( ( m_flags & kDxt1 ) != 0 ); bool isDxt1 = ( ( m_flags & kDxt1 ) != 0 );

View file

@ -26,9 +26,11 @@
#ifndef SQUISH_COLOURFIT_H #ifndef SQUISH_COLOURFIT_H
#define SQUISH_COLOURFIT_H #define SQUISH_COLOURFIT_H
#include <squish.h> #include "squish.h"
#include "maths.h" #include "maths.h"
#include <climits>
namespace squish { namespace squish {
class ColourSet; class ColourSet;
@ -37,6 +39,7 @@ class ColourFit
{ {
public: public:
ColourFit( ColourSet const* colours, int flags ); ColourFit( ColourSet const* colours, int flags );
virtual ~ColourFit();
void Compress( void* block ); void Compress( void* block );

View file

@ -26,7 +26,7 @@
#ifndef SQUISH_COLOURSET_H #ifndef SQUISH_COLOURSET_H
#define SQUISH_COLOURSET_H #define SQUISH_COLOURSET_H
#include <squish.h> #include "squish.h"
#include "maths.h" #include "maths.h"
namespace squish { namespace squish {

View file

@ -36,7 +36,7 @@
#define SQUISH_USE_SSE 0 #define SQUISH_USE_SSE 0
#endif #endif
// Internally et SQUISH_USE_SIMD when either Altivec or SSE is available. // Internally set SQUISH_USE_SIMD when either Altivec or SSE is available.
#if SQUISH_USE_ALTIVEC && SQUISH_USE_SSE #if SQUISH_USE_ALTIVEC && SQUISH_USE_SSE
#error "Cannot enable both Altivec and SSE!" #error "Cannot enable both Altivec and SSE!"
#endif #endif
@ -46,10 +46,4 @@
#define SQUISH_USE_SIMD 0 #define SQUISH_USE_SIMD 0
#endif #endif
// TORQUE MODIFICATIONS
#ifdef TORQUE_DEBUG
# undef SQUISH_USE_SSE
# define SQUISH_USE_SSE 0
#endif
#endif // ndef SQUISH_CONFIG_H #endif // ndef SQUISH_CONFIG_H

View file

@ -30,6 +30,7 @@
*/ */
#include "maths.h" #include "maths.h"
#include "simd.h"
#include <cfloat> #include <cfloat>
namespace squish { namespace squish {
@ -44,6 +45,7 @@ Sym3x3 ComputeWeightedCovariance( int n, Vec3 const* points, float const* weight
total += weights[i]; total += weights[i];
centroid += weights[i]*points[i]; centroid += weights[i]*points[i];
} }
if( total > FLT_EPSILON )
centroid /= total; centroid /= total;
// accumulate the covariance matrix // accumulate the covariance matrix
@ -65,6 +67,8 @@ Sym3x3 ComputeWeightedCovariance( int n, Vec3 const* points, float const* weight
return covariance; return covariance;
} }
#if 0
static Vec3 GetMultiplicity1Evector( Sym3x3 const& matrix, float evalue ) static Vec3 GetMultiplicity1Evector( Sym3x3 const& matrix, float evalue )
{ {
// compute M // compute M
@ -224,4 +228,32 @@ Vec3 ComputePrincipleComponent( Sym3x3 const& matrix )
} }
} }
#else
#define POWER_ITERATION_COUNT 8
Vec3 ComputePrincipleComponent( Sym3x3 const& matrix )
{
Vec4 const row0( matrix[0], matrix[1], matrix[2], 0.0f );
Vec4 const row1( matrix[1], matrix[3], matrix[4], 0.0f );
Vec4 const row2( matrix[2], matrix[4], matrix[5], 0.0f );
Vec4 v = VEC4_CONST( 1.0f );
for( int i = 0; i < POWER_ITERATION_COUNT; ++i )
{
// matrix multiply
Vec4 w = row0*v.SplatX();
w = MultiplyAdd(row1, v.SplatY(), w);
w = MultiplyAdd(row2, v.SplatZ(), w);
// get max component from xyz in all channels
Vec4 a = Max(w.SplatX(), Max(w.SplatY(), w.SplatZ()));
// divide through and advance
v = w*Reciprocal(a);
}
return v.GetVec3();
}
#endif
} // namespace squish } // namespace squish

View file

@ -30,13 +30,12 @@
namespace squish { namespace squish {
RangeFit::RangeFit( ColourSet const* colours, int flags ) RangeFit::RangeFit( ColourSet const* colours, int flags, float* metric )
: ColourFit( colours, flags ) : ColourFit( colours, flags )
{ {
// initialise the metric // initialise the metric (old perceptual = 0.2126f, 0.7152f, 0.0722f)
bool perceptual = ( ( m_flags & kColourMetricPerceptual ) != 0 ); if( metric )
if( perceptual ) m_metric = Vec3( metric[0], metric[1], metric[2] );
m_metric = Vec3( 0.2126f, 0.7152f, 0.0722f );
else else
m_metric = Vec3( 1.0f ); m_metric = Vec3( 1.0f );

View file

@ -26,7 +26,7 @@
#ifndef SQUISH_RANGEFIT_H #ifndef SQUISH_RANGEFIT_H
#define SQUISH_RANGEFIT_H #define SQUISH_RANGEFIT_H
#include <squish.h> #include "squish.h"
#include "colourfit.h" #include "colourfit.h"
#include "maths.h" #include "maths.h"
@ -37,7 +37,7 @@ class ColourSet;
class RangeFit : public ColourFit class RangeFit : public ColourFit
{ {
public: public:
RangeFit( ColourSet const* colours, int flags ); RangeFit( ColourSet const* colours, int flags, float* metric );
private: private:
virtual void Compress3( void* block ); virtual void Compress3( void* block );

View file

@ -27,14 +27,6 @@
#define SQUISH_SIMD_H #define SQUISH_SIMD_H
#include "maths.h" #include "maths.h"
#if SQUISH_USE_ALTIVEC
#include "simd_ve.h"
#elif SQUISH_USE_SSE
#include "simd_sse.h"
#else
#include "simd_float.h" #include "simd_float.h"
#endif
#endif // ndef SQUISH_SIMD_H #endif // ndef SQUISH_SIMD_H

View file

@ -1,180 +0,0 @@
/* -----------------------------------------------------------------------------
Copyright (c) 2006 Simon Brown si@sjbrown.co.uk
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-------------------------------------------------------------------------- */
#ifndef SQUISH_SIMD_SSE_H
#define SQUISH_SIMD_SSE_H
#include <xmmintrin.h>
#if ( SQUISH_USE_SSE > 1 )
#include <emmintrin.h>
#endif
#define SQUISH_SSE_SPLAT( a ) \
( ( a ) | ( ( a ) << 2 ) | ( ( a ) << 4 ) | ( ( a ) << 6 ) )
#define SQUISH_SSE_SHUF( x, y, z, w ) \
( ( x ) | ( ( y ) << 2 ) | ( ( z ) << 4 ) | ( ( w ) << 6 ) )
namespace squish {
#define VEC4_CONST( X ) Vec4( X )
class Vec4
{
public:
typedef Vec4 const& Arg;
Vec4() {}
explicit Vec4( __m128 v ) : m_v( v ) {}
Vec4( Vec4 const& arg ) : m_v( arg.m_v ) {}
Vec4& operator=( Vec4 const& arg )
{
m_v = arg.m_v;
return *this;
}
explicit Vec4( float s ) : m_v( _mm_set1_ps( s ) ) {}
Vec4( float x, float y, float z, float w ) : m_v( _mm_setr_ps( x, y, z, w ) ) {}
Vec3 GetVec3() const
{
#ifdef __GNUC__
__attribute__ ((__aligned__ (16))) float c[4];
#else
__declspec(align(16)) float c[4];
#endif
_mm_store_ps( c, m_v );
return Vec3( c[0], c[1], c[2] );
}
Vec4 SplatX() const { return Vec4( _mm_shuffle_ps( m_v, m_v, SQUISH_SSE_SPLAT( 0 ) ) ); }
Vec4 SplatY() const { return Vec4( _mm_shuffle_ps( m_v, m_v, SQUISH_SSE_SPLAT( 1 ) ) ); }
Vec4 SplatZ() const { return Vec4( _mm_shuffle_ps( m_v, m_v, SQUISH_SSE_SPLAT( 2 ) ) ); }
Vec4 SplatW() const { return Vec4( _mm_shuffle_ps( m_v, m_v, SQUISH_SSE_SPLAT( 3 ) ) ); }
Vec4& operator+=( Arg v )
{
m_v = _mm_add_ps( m_v, v.m_v );
return *this;
}
Vec4& operator-=( Arg v )
{
m_v = _mm_sub_ps( m_v, v.m_v );
return *this;
}
Vec4& operator*=( Arg v )
{
m_v = _mm_mul_ps( m_v, v.m_v );
return *this;
}
friend Vec4 operator+( Vec4::Arg left, Vec4::Arg right )
{
return Vec4( _mm_add_ps( left.m_v, right.m_v ) );
}
friend Vec4 operator-( Vec4::Arg left, Vec4::Arg right )
{
return Vec4( _mm_sub_ps( left.m_v, right.m_v ) );
}
friend Vec4 operator*( Vec4::Arg left, Vec4::Arg right )
{
return Vec4( _mm_mul_ps( left.m_v, right.m_v ) );
}
//! Returns a*b + c
friend Vec4 MultiplyAdd( Vec4::Arg a, Vec4::Arg b, Vec4::Arg c )
{
return Vec4( _mm_add_ps( _mm_mul_ps( a.m_v, b.m_v ), c.m_v ) );
}
//! Returns -( a*b - c )
friend Vec4 NegativeMultiplySubtract( Vec4::Arg a, Vec4::Arg b, Vec4::Arg c )
{
return Vec4( _mm_sub_ps( c.m_v, _mm_mul_ps( a.m_v, b.m_v ) ) );
}
friend Vec4 Reciprocal( Vec4::Arg v )
{
// get the reciprocal estimate
__m128 estimate = _mm_rcp_ps( v.m_v );
// one round of Newton-Rhaphson refinement
__m128 diff = _mm_sub_ps( _mm_set1_ps( 1.0f ), _mm_mul_ps( estimate, v.m_v ) );
return Vec4( _mm_add_ps( _mm_mul_ps( diff, estimate ), estimate ) );
}
friend Vec4 Min( Vec4::Arg left, Vec4::Arg right )
{
return Vec4( _mm_min_ps( left.m_v, right.m_v ) );
}
friend Vec4 Max( Vec4::Arg left, Vec4::Arg right )
{
return Vec4( _mm_max_ps( left.m_v, right.m_v ) );
}
friend Vec4 Truncate( Vec4::Arg v )
{
#if ( SQUISH_USE_SSE == 1 )
// convert to ints
__m128 input = v.m_v;
__m64 lo = _mm_cvttps_pi32( input );
__m64 hi = _mm_cvttps_pi32( _mm_movehl_ps( input, input ) );
// convert to floats
__m128 part = _mm_movelh_ps( input, _mm_cvtpi32_ps( input, hi ) );
__m128 truncated = _mm_cvtpi32_ps( part, lo );
// clear out the MMX multimedia state to allow FP calls later
_mm_empty();
return Vec4( truncated );
#else
// use SSE2 instructions
return Vec4( _mm_cvtepi32_ps( _mm_cvttps_epi32( v.m_v ) ) );
#endif
}
friend bool CompareAnyLessThan( Vec4::Arg left, Vec4::Arg right )
{
__m128 bits = _mm_cmplt_ps( left.m_v, right.m_v );
int value = _mm_movemask_ps( bits );
return value != 0;
}
private:
__m128 m_v;
};
} // namespace squish
#endif // ndef SQUISH_SIMD_SSE_H

View file

@ -1,166 +0,0 @@
/* -----------------------------------------------------------------------------
Copyright (c) 2006 Simon Brown si@sjbrown.co.uk
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-------------------------------------------------------------------------- */
#ifndef SQUISH_SIMD_VE_H
#define SQUISH_SIMD_VE_H
#include <altivec.h>
#undef bool
namespace squish {
#define VEC4_CONST( X ) Vec4( ( vector float )( X ) )
class Vec4
{
public:
typedef Vec4 Arg;
Vec4() {}
explicit Vec4( vector float v ) : m_v( v ) {}
Vec4( Vec4 const& arg ) : m_v( arg.m_v ) {}
Vec4& operator=( Vec4 const& arg )
{
m_v = arg.m_v;
return *this;
}
explicit Vec4( float s )
{
union { vector float v; float c[4]; } u;
u.c[0] = s;
u.c[1] = s;
u.c[2] = s;
u.c[3] = s;
m_v = u.v;
}
Vec4( float x, float y, float z, float w )
{
union { vector float v; float c[4]; } u;
u.c[0] = x;
u.c[1] = y;
u.c[2] = z;
u.c[3] = w;
m_v = u.v;
}
Vec3 GetVec3() const
{
union { vector float v; float c[4]; } u;
u.v = m_v;
return Vec3( u.c[0], u.c[1], u.c[2] );
}
Vec4 SplatX() const { return Vec4( vec_splat( m_v, 0 ) ); }
Vec4 SplatY() const { return Vec4( vec_splat( m_v, 1 ) ); }
Vec4 SplatZ() const { return Vec4( vec_splat( m_v, 2 ) ); }
Vec4 SplatW() const { return Vec4( vec_splat( m_v, 3 ) ); }
Vec4& operator+=( Arg v )
{
m_v = vec_add( m_v, v.m_v );
return *this;
}
Vec4& operator-=( Arg v )
{
m_v = vec_sub( m_v, v.m_v );
return *this;
}
Vec4& operator*=( Arg v )
{
m_v = vec_madd( m_v, v.m_v, ( vector float )( -0.0f ) );
return *this;
}
friend Vec4 operator+( Vec4::Arg left, Vec4::Arg right )
{
return Vec4( vec_add( left.m_v, right.m_v ) );
}
friend Vec4 operator-( Vec4::Arg left, Vec4::Arg right )
{
return Vec4( vec_sub( left.m_v, right.m_v ) );
}
friend Vec4 operator*( Vec4::Arg left, Vec4::Arg right )
{
return Vec4( vec_madd( left.m_v, right.m_v, ( vector float )( -0.0f ) ) );
}
//! Returns a*b + c
friend Vec4 MultiplyAdd( Vec4::Arg a, Vec4::Arg b, Vec4::Arg c )
{
return Vec4( vec_madd( a.m_v, b.m_v, c.m_v ) );
}
//! Returns -( a*b - c )
friend Vec4 NegativeMultiplySubtract( Vec4::Arg a, Vec4::Arg b, Vec4::Arg c )
{
return Vec4( vec_nmsub( a.m_v, b.m_v, c.m_v ) );
}
friend Vec4 Reciprocal( Vec4::Arg v )
{
// get the reciprocal estimate
vector float estimate = vec_re( v.m_v );
// one round of Newton-Rhaphson refinement
vector float diff = vec_nmsub( estimate, v.m_v, ( vector float )( 1.0f ) );
return Vec4( vec_madd( diff, estimate, estimate ) );
}
friend Vec4 Min( Vec4::Arg left, Vec4::Arg right )
{
return Vec4( vec_min( left.m_v, right.m_v ) );
}
friend Vec4 Max( Vec4::Arg left, Vec4::Arg right )
{
return Vec4( vec_max( left.m_v, right.m_v ) );
}
friend Vec4 Truncate( Vec4::Arg v )
{
return Vec4( vec_trunc( v.m_v ) );
}
friend bool CompareAnyLessThan( Vec4::Arg left, Vec4::Arg right )
{
return vec_any_lt( left.m_v, right.m_v ) != 0;
}
private:
vector float m_v;
};
} // namespace squish
#endif // ndef SQUISH_SIMD_VE_H

View file

@ -26,7 +26,6 @@
#include "singlecolourfit.h" #include "singlecolourfit.h"
#include "colourset.h" #include "colourset.h"
#include "colourblock.h" #include "colourblock.h"
#include <limits.h>
namespace squish { namespace squish {

View file

@ -26,7 +26,7 @@
#ifndef SQUISH_SINGLECOLOURFIT_H #ifndef SQUISH_SINGLECOLOURFIT_H
#define SQUISH_SINGLECOLOURFIT_H #define SQUISH_SINGLECOLOURFIT_H
#include <squish.h> #include "squish.h"
#include "colourfit.h" #include "colourfit.h"
namespace squish { namespace squish {

View file

@ -1,3 +1,27 @@
/* -----------------------------------------------------------------------------
Copyright (c) 2006 Simon Brown si@sjbrown.co.uk
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-------------------------------------------------------------------------- */
static SingleColourLookup const lookup_5_3[] = static SingleColourLookup const lookup_5_3[] =
{ {

View file

@ -1,20 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleExecutable</key>
<string>${EXECUTABLE_NAME}</string>
<key>CFBundleIdentifier</key>
<string>com.sjbrown.squish</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1.0</string>
</dict>
</plist>

View file

@ -23,7 +23,7 @@
-------------------------------------------------------------------------- */ -------------------------------------------------------------------------- */
#include <squish.h> #include "squish.h"
#include "colourset.h" #include "colourset.h"
#include "maths.h" #include "maths.h"
#include "rangefit.h" #include "rangefit.h"
@ -37,37 +37,58 @@ namespace squish {
static int FixFlags( int flags ) static int FixFlags( int flags )
{ {
// grab the flag bits // grab the flag bits
int method = flags & ( kDxt1 | kDxt3 | kDxt5 ); int method = flags & ( kDxt1 | kDxt3 | kDxt5 | kBc4 | kBc5 );
int fit = flags & ( kColourIterativeClusterFit | kColourClusterFit | kColourRangeFit ); int fit = flags & ( kColourIterativeClusterFit | kColourClusterFit | kColourRangeFit );
int metric = flags & ( kColourMetricPerceptual | kColourMetricUniform );
int extra = flags & kWeightColourByAlpha; int extra = flags & kWeightColourByAlpha;
// set defaults // set defaults
if( method != kDxt3 && method != kDxt5 ) if ( method != kDxt3
&& method != kDxt5
&& method != kBc4
&& method != kBc5 )
{
method = kDxt1; method = kDxt1;
if( fit != kColourRangeFit ) }
if( fit != kColourRangeFit && fit != kColourIterativeClusterFit )
fit = kColourClusterFit; fit = kColourClusterFit;
if( metric != kColourMetricUniform )
metric = kColourMetricPerceptual;
// done // done
return method | fit | metric | extra; return method | fit | extra;
} }
void Compress( u8 const* rgba, void* block, int flags ) void CompressMasked( u8 const* rgba, int mask, void* block, int flags, float* metric )
{
// compress with full mask
CompressMasked( rgba, 0xffff, block, flags );
}
void CompressMasked( u8 const* rgba, int mask, void* block, int flags )
{ {
// fix any bad flags // fix any bad flags
flags = FixFlags( flags ); flags = FixFlags( flags );
if ( ( flags & ( kBc4 | kBc5 ) ) != 0 )
{
u8 alpha[16*4];
for( int i = 0; i < 16; ++i )
{
alpha[i*4 + 3] = rgba[i*4 + 0]; // copy R to A
}
u8* rBlock = reinterpret_cast< u8* >( block );
CompressAlphaDxt5( alpha, mask, rBlock );
if ( ( flags & ( kBc5 ) ) != 0 )
{
for( int i = 0; i < 16; ++i )
{
alpha[i*4 + 3] = rgba[i*4 + 1]; // copy G to A
}
u8* gBlock = reinterpret_cast< u8* >( block ) + 8;
CompressAlphaDxt5( alpha, mask, gBlock );
}
return;
}
// get the block locations // get the block locations
void* colourBlock = block; void* colourBlock = block;
void* alphaBock = block; void* alphaBlock = block;
if( ( flags & ( kDxt3 | kDxt5 ) ) != 0 ) if( ( flags & ( kDxt3 | kDxt5 ) ) != 0 )
colourBlock = reinterpret_cast< u8* >( block ) + 8; colourBlock = reinterpret_cast< u8* >( block ) + 8;
@ -84,21 +105,21 @@ void CompressMasked( u8 const* rgba, int mask, void* block, int flags )
else if( ( flags & kColourRangeFit ) != 0 || colours.GetCount() == 0 ) else if( ( flags & kColourRangeFit ) != 0 || colours.GetCount() == 0 )
{ {
// do a range fit // do a range fit
RangeFit fit( &colours, flags ); RangeFit fit( &colours, flags, metric );
fit.Compress( colourBlock ); fit.Compress( colourBlock );
} }
else else
{ {
// default to a cluster fit (could be iterative or not) // default to a cluster fit (could be iterative or not)
ClusterFit fit( &colours, flags ); ClusterFit fit( &colours, flags, metric );
fit.Compress( colourBlock ); fit.Compress( colourBlock );
} }
// compress alpha separately if necessary // compress alpha separately if necessary
if( ( flags & kDxt3 ) != 0 ) if( ( flags & kDxt3 ) != 0 )
CompressAlphaDxt3( rgba, mask, alphaBock ); CompressAlphaDxt3( rgba, mask, alphaBlock );
else if( ( flags & kDxt5 ) != 0 ) else if( ( flags & kDxt5 ) != 0 )
CompressAlphaDxt5( rgba, mask, alphaBock ); CompressAlphaDxt5( rgba, mask, alphaBlock );
} }
void Decompress( u8* rgba, void const* block, int flags ) void Decompress( u8* rgba, void const* block, int flags )
@ -129,18 +150,18 @@ int GetStorageRequirements( int width, int height, int flags )
// compute the storage requirements // compute the storage requirements
int blockcount = ( ( width + 3 )/4 ) * ( ( height + 3 )/4 ); int blockcount = ( ( width + 3 )/4 ) * ( ( height + 3 )/4 );
int blocksize = ( ( flags & kDxt1 ) != 0 ) ? 8 : 16; int blocksize = ( ( flags & ( kDxt1 | kBc4 ) ) != 0 ) ? 8 : 16;
return blockcount*blocksize; return blockcount*blocksize;
} }
void CompressImage( u8 const* rgba, int width, int height, void* blocks, int flags ) void CompressImage( u8 const* rgba, int width, int height, void* blocks, int flags, float* metric )
{ {
// fix any bad flags // fix any bad flags
flags = FixFlags( flags ); flags = FixFlags( flags );
// initialise the block output // initialise the block output
u8* targetBlock = reinterpret_cast< u8* >( blocks ); u8* targetBlock = reinterpret_cast< u8* >( blocks );
int bytesPerBlock = ( ( flags & kDxt1 ) != 0 ) ? 8 : 16; int bytesPerBlock = ( ( flags & ( kDxt1 | kBc4 ) ) != 0 ) ? 8 : 16;
// loop over blocks // loop over blocks
for( int y = 0; y < height; y += 4 ) for( int y = 0; y < height; y += 4 )
@ -179,7 +200,7 @@ void CompressImage( u8 const* rgba, int width, int height, void* blocks, int fla
} }
// compress it into the output // compress it into the output
CompressMasked( sourceRgba, mask, targetBlock, flags ); CompressMasked( sourceRgba, mask, targetBlock, flags, metric );
// advance // advance
targetBlock += bytesPerBlock; targetBlock += bytesPerBlock;
@ -194,7 +215,7 @@ void DecompressImage( u8* rgba, int width, int height, void const* blocks, int f
// initialise the block input // initialise the block input
u8 const* sourceBlock = reinterpret_cast< u8 const* >( blocks ); u8 const* sourceBlock = reinterpret_cast< u8 const* >( blocks );
int bytesPerBlock = ( ( flags & kDxt1 ) != 0 ) ? 8 : 16; int bytesPerBlock = ( ( flags & ( kDxt1 | kBc4 ) ) != 0 ) ? 8 : 16;
// loop over blocks // loop over blocks
for( int y = 0; y < height; y += 4 ) for( int y = 0; y < height; y += 4 )

View file

@ -47,66 +47,34 @@ enum
//! Use DXT5 compression. //! Use DXT5 compression.
kDxt5 = ( 1 << 2 ), kDxt5 = ( 1 << 2 ),
//! Use a very slow but very high quality colour compressor. //! Use BC4 compression.
kColourIterativeClusterFit = ( 1 << 8 ), kBc4 = ( 1 << 3 ),
//! Use BC5 compression.
kBc5 = ( 1 << 4 ),
//! Use a slow but high quality colour compressor (the default). //! Use a slow but high quality colour compressor (the default).
kColourClusterFit = ( 1 << 3 ), kColourClusterFit = ( 1 << 5 ),
//! Use a fast but low quality colour compressor. //! Use a fast but low quality colour compressor.
kColourRangeFit = ( 1 << 4 ), kColourRangeFit = ( 1 << 6 ),
//! Use a perceptual metric for colour error (the default).
kColourMetricPerceptual = ( 1 << 5 ),
//! Use a uniform metric for colour error.
kColourMetricUniform = ( 1 << 6 ),
//! Weight the colour by alpha during cluster fit (disabled by default). //! Weight the colour by alpha during cluster fit (disabled by default).
kWeightColourByAlpha = ( 1 << 7 ) kWeightColourByAlpha = ( 1 << 7 ),
//! Use a very slow but very high quality colour compressor.
kColourIterativeClusterFit = ( 1 << 8 ),
}; };
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
/*! @brief Compresses a 4x4 block of pixels.
@param rgba The rgba values of the 16 source pixels.
@param block Storage for the compressed DXT block.
@param flags Compression flags.
The source pixels should be presented as a contiguous array of 16 rgba
values, with each component as 1 byte each. In memory this should be:
{ r1, g1, b1, a1, .... , r16, g16, b16, a16 }
The flags parameter should specify either kDxt1, kDxt3 or kDxt5 compression,
however, DXT1 will be used by default if none is specified. When using DXT1
compression, 8 bytes of storage are required for the compressed DXT block.
DXT3 and DXT5 compression require 16 bytes of storage per block.
The flags parameter can also specify a preferred colour compressor and
colour error metric to use when fitting the RGB components of the data.
Possible colour compressors are: kColourClusterFit (the default),
kColourRangeFit or kColourIterativeClusterFit. Possible colour error metrics
are: kColourMetricPerceptual (the default) or kColourMetricUniform. If no
flags are specified in any particular category then the default will be
used. Unknown flags are ignored.
When using kColourClusterFit, an additional flag can be specified to
weight the colour of each pixel by its alpha value. For images that are
rendered using alpha blending, this can significantly increase the
perceived quality.
*/
void Compress( u8 const* rgba, void* block, int flags );
// -----------------------------------------------------------------------------
/*! @brief Compresses a 4x4 block of pixels. /*! @brief Compresses a 4x4 block of pixels.
@param rgba The rgba values of the 16 source pixels. @param rgba The rgba values of the 16 source pixels.
@param mask The valid pixel mask. @param mask The valid pixel mask.
@param block Storage for the compressed DXT block. @param block Storage for the compressed DXT block.
@param flags Compression flags. @param flags Compression flags.
@param metric An optional perceptual metric.
The source pixels should be presented as a contiguous array of 16 rgba The source pixels should be presented as a contiguous array of 16 rgba
values, with each component as 1 byte each. In memory this should be: values, with each component as 1 byte each. In memory this should be:
@ -125,20 +93,68 @@ void Compress( u8 const* rgba, void* block, int flags );
compression, 8 bytes of storage are required for the compressed DXT block. compression, 8 bytes of storage are required for the compressed DXT block.
DXT3 and DXT5 compression require 16 bytes of storage per block. DXT3 and DXT5 compression require 16 bytes of storage per block.
The flags parameter can also specify a preferred colour compressor and The flags parameter can also specify a preferred colour compressor to use
colour error metric to use when fitting the RGB components of the data. when fitting the RGB components of the data. Possible colour compressors
Possible colour compressors are: kColourClusterFit (the default), are: kColourClusterFit (the default), kColourRangeFit (very fast, low
kColourRangeFit or kColourIterativeClusterFit. Possible colour error metrics quality) or kColourIterativeClusterFit (slowest, best quality).
are: kColourMetricPerceptual (the default) or kColourMetricUniform. If no
flags are specified in any particular category then the default will be
used. Unknown flags are ignored.
When using kColourClusterFit, an additional flag can be specified to When using kColourClusterFit or kColourIterativeClusterFit, an additional
weight the colour of each pixel by its alpha value. For images that are flag can be specified to weight the importance of each pixel by its alpha
rendered using alpha blending, this can significantly increase the value. For images that are rendered using alpha blending, this can
perceived quality. significantly increase the perceived quality.
The metric parameter can be used to weight the relative importance of each
colour channel, or pass NULL to use the default uniform weight of
{ 1.0f, 1.0f, 1.0f }. This replaces the previous flag-based control that
allowed either uniform or "perceptual" weights with the fixed values
{ 0.2126f, 0.7152f, 0.0722f }. If non-NULL, the metric should point to a
contiguous array of 3 floats.
*/ */
void CompressMasked( u8 const* rgba, int mask, void* block, int flags ); void CompressMasked( u8 const* rgba, int mask, void* block, int flags, float* metric = 0 );
// -----------------------------------------------------------------------------
/*! @brief Compresses a 4x4 block of pixels.
@param rgba The rgba values of the 16 source pixels.
@param block Storage for the compressed DXT block.
@param flags Compression flags.
@param metric An optional perceptual metric.
The source pixels should be presented as a contiguous array of 16 rgba
values, with each component as 1 byte each. In memory this should be:
{ r1, g1, b1, a1, .... , r16, g16, b16, a16 }
The flags parameter should specify either kDxt1, kDxt3 or kDxt5 compression,
however, DXT1 will be used by default if none is specified. When using DXT1
compression, 8 bytes of storage are required for the compressed DXT block.
DXT3 and DXT5 compression require 16 bytes of storage per block.
The flags parameter can also specify a preferred colour compressor to use
when fitting the RGB components of the data. Possible colour compressors
are: kColourClusterFit (the default), kColourRangeFit (very fast, low
quality) or kColourIterativeClusterFit (slowest, best quality).
When using kColourClusterFit or kColourIterativeClusterFit, an additional
flag can be specified to weight the importance of each pixel by its alpha
value. For images that are rendered using alpha blending, this can
significantly increase the perceived quality.
The metric parameter can be used to weight the relative importance of each
colour channel, or pass NULL to use the default uniform weight of
{ 1.0f, 1.0f, 1.0f }. This replaces the previous flag-based control that
allowed either uniform or "perceptual" weights with the fixed values
{ 0.2126f, 0.7152f, 0.0722f }. If non-NULL, the metric should point to a
contiguous array of 3 floats.
This method is an inline that calls CompressMasked with a mask of 0xffff,
provided for compatibility with older versions of squish.
*/
inline void Compress( u8 const* rgba, void* block, int flags, float* metric = 0 )
{
CompressMasked( rgba, 0xffff, block, flags, metric );
}
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
@ -186,6 +202,7 @@ int GetStorageRequirements( int width, int height, int flags );
@param height The height of the source image. @param height The height of the source image.
@param blocks Storage for the compressed output. @param blocks Storage for the compressed output.
@param flags Compression flags. @param flags Compression flags.
@param metric An optional perceptual metric.
The source pixels should be presented as a contiguous array of width*height The source pixels should be presented as a contiguous array of width*height
rgba values, with each component as 1 byte each. In memory this should be: rgba values, with each component as 1 byte each. In memory this should be:
@ -197,24 +214,29 @@ int GetStorageRequirements( int width, int height, int flags );
compression, 8 bytes of storage are required for each compressed DXT block. compression, 8 bytes of storage are required for each compressed DXT block.
DXT3 and DXT5 compression require 16 bytes of storage per block. DXT3 and DXT5 compression require 16 bytes of storage per block.
The flags parameter can also specify a preferred colour compressor and The flags parameter can also specify a preferred colour compressor to use
colour error metric to use when fitting the RGB components of the data. when fitting the RGB components of the data. Possible colour compressors
Possible colour compressors are: kColourClusterFit (the default), are: kColourClusterFit (the default), kColourRangeFit (very fast, low
kColourRangeFit or kColourIterativeClusterFit. Possible colour error metrics quality) or kColourIterativeClusterFit (slowest, best quality).
are: kColourMetricPerceptual (the default) or kColourMetricUniform. If no
flags are specified in any particular category then the default will be
used. Unknown flags are ignored.
When using kColourClusterFit, an additional flag can be specified to When using kColourClusterFit or kColourIterativeClusterFit, an additional
weight the colour of each pixel by its alpha value. For images that are flag can be specified to weight the importance of each pixel by its alpha
rendered using alpha blending, this can significantly increase the value. For images that are rendered using alpha blending, this can
perceived quality. significantly increase the perceived quality.
Internally this function calls squish::Compress for each block. To see how The metric parameter can be used to weight the relative importance of each
much memory is required in the compressed image, use colour channel, or pass NULL to use the default uniform weight of
squish::GetStorageRequirements. { 1.0f, 1.0f, 1.0f }. This replaces the previous flag-based control that
allowed either uniform or "perceptual" weights with the fixed values
{ 0.2126f, 0.7152f, 0.0722f }. If non-NULL, the metric should point to a
contiguous array of 3 floats.
Internally this function calls squish::CompressMasked for each block, which
allows for pixels outside the image to take arbitrary values. The function
squish::GetStorageRequirements can be called to compute the amount of memory
to allocate for the compressed output.
*/ */
void CompressImage( u8 const* rgba, int width, int height, void* blocks, int flags ); void CompressImage( u8 const* rgba, int width, int height, void* blocks, int flags, float* metric = 0 );
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------

View file

@ -1,508 +0,0 @@
Name
EXT_texture_compression_s3tc
Name Strings
GL_EXT_texture_compression_s3tc
Contact
Pat Brown, NVIDIA Corporation (pbrown 'at' nvidia.com)
Status
FINAL
Version
1.1, 16 November 2001 (containing only clarifications relative to
version 1.0, dated 7 July 2000)
Number
198
Dependencies
OpenGL 1.1 is required.
GL_ARB_texture_compression is required.
This extension is written against the OpenGL 1.2.1 Specification.
Overview
This extension provides additional texture compression functionality
specific to S3's S3TC format (called DXTC in Microsoft's DirectX API),
subject to all the requirements and limitations described by the extension
GL_ARB_texture_compression.
This extension supports DXT1, DXT3, and DXT5 texture compression formats.
For the DXT1 image format, this specification supports an RGB-only mode
and a special RGBA mode with single-bit "transparent" alpha.
IP Status
Contact S3 Incorporated (http://www.s3.com) regarding any intellectual
property issues associated with implementing this extension.
WARNING: Vendors able to support S3TC texture compression in Direct3D
drivers do not necessarily have the right to use the same functionality in
OpenGL.
Issues
(1) Should DXT2 and DXT4 (premultiplied alpha) formats be supported?
RESOLVED: No -- insufficient interest. Supporting DXT2 and DXT4
would require some rework to the TexEnv definition (maybe add a new
base internal format RGBA_PREMULTIPLIED_ALPHA) for these formats.
Note that the EXT_texture_env_combine extension (which extends normal
TexEnv modes) can be used to support textures with premultipled alpha.
(2) Should generic "RGB_S3TC_EXT" and "RGBA_S3TC_EXT" enums be supported
or should we use only the DXT<n> enums?
RESOLVED: No. A generic RGBA_S3TC_EXT is problematic because DXT3
and DXT5 are both nominally RGBA (and DXT1 with the 1-bit alpha is
also) yet one format must be chosen up front.
(3) Should TexSubImage support all block-aligned edits or just the minimal
functionality required by the ARB_texture_compression extension?
RESOLVED: Allow all valid block-aligned edits.
(4) A pre-compressed image with a DXT1 format can be used as either an
RGB_S3TC_DXT1 or an RGBA_S3TC_DXT1 image. If the image has
transparent texels, how are they treated in each format?
RESOLVED: The renderer has to make sure that an RGB_S3TC_DXT1 format
is decoded as RGB (where alpha is effectively one for all texels),
while RGBA_S3TC_DXT1 is decoded as RGBA (where alpha is zero for all
texels with "transparent" encodings). Otherwise, the formats are
identical.
(5) Is the encoding of the RGB components for DXT1 formats correct in this
spec? MSDN documentation does not specify an RGB color for the
"transparent" encoding. Is it really black?
RESOLVED: Yes. The specification for the DXT1 format initially
required black, but later changed that requirement to a
recommendation. All vendors involved in the definition of this
specification support black. In addition, specifying black has a
useful behavior.
When blending multiple texels (GL_LINEAR filtering), mixing opaque and
transparent samples is problematic. Defining a black color on
transparent texels achieves a sensible result that works like a
texture with premultiplied alpha. For example, if three opaque white
and one transparent sample is being averaged, the result would be a
75% intensity gray (with an alpha of 75%). This is the same result on
the color channels as would be obtained using a white color, 75%
alpha, and a SRC_ALPHA blend factor.
(6) Is the encoding of the RGB components for DXT3 and DXT5 formats
correct in this spec? MSDN documentation suggests that the RGB blocks
for DXT3 and DXT5 are decoded as described by the DXT1 format.
RESOLVED: Yes -- this appears to be a bug in the MSDN documentation.
The specification for the DXT2-DXT5 formats require decoding using the
opaque block encoding, regardless of the relative values of "color0"
and "color1".
New Procedures and Functions
None.
New Tokens
Accepted by the <internalformat> parameter of TexImage2D, CopyTexImage2D,
and CompressedTexImage2DARB and the <format> parameter of
CompressedTexSubImage2DARB:
COMPRESSED_RGB_S3TC_DXT1_EXT 0x83F0
COMPRESSED_RGBA_S3TC_DXT1_EXT 0x83F1
COMPRESSED_RGBA_S3TC_DXT3_EXT 0x83F2
COMPRESSED_RGBA_S3TC_DXT5_EXT 0x83F3
Additions to Chapter 2 of the OpenGL 1.2.1 Specification (OpenGL Operation)
None.
Additions to Chapter 3 of the OpenGL 1.2.1 Specification (Rasterization)
Add to Table 3.16.1: Specific Compressed Internal Formats
Compressed Internal Format Base Internal Format
========================== ====================
COMPRESSED_RGB_S3TC_DXT1_EXT RGB
COMPRESSED_RGBA_S3TC_DXT1_EXT RGBA
COMPRESSED_RGBA_S3TC_DXT3_EXT RGBA
COMPRESSED_RGBA_S3TC_DXT5_EXT RGBA
Modify Section 3.8.2, Alternate Image Specification
(add to end of TexSubImage discussion, p.123 -- after edit from the
ARB_texture_compression spec)
If the internal format of the texture image being modified is
COMPRESSED_RGB_S3TC_DXT1_EXT, COMPRESSED_RGBA_S3TC_DXT1_EXT,
COMPRESSED_RGBA_S3TC_DXT3_EXT, or COMPRESSED_RGBA_S3TC_DXT5_EXT, the
texture is stored using one of the several S3TC compressed texture image
formats. Such images are easily edited along 4x4 texel boundaries, so the
limitations on TexSubImage2D or CopyTexSubImage2D parameters are relaxed.
TexSubImage2D and CopyTexSubImage2D will result in an INVALID_OPERATION
error only if one of the following conditions occurs:
* <width> is not a multiple of four or equal to TEXTURE_WIDTH,
unless <xoffset> and <yoffset> are both zero.
* <height> is not a multiple of four or equal to TEXTURE_HEIGHT,
unless <xoffset> and <yoffset> are both zero.
* <xoffset> or <yoffset> is not a multiple of four.
The contents of any 4x4 block of texels of an S3TC compressed texture
image that does not intersect the area being modified are preserved during
valid TexSubImage2D and CopyTexSubImage2D calls.
Add to Section 3.8.2, Alternate Image Specification (adding to the end of
the CompressedTexImage section introduced by the ARB_texture_compression
spec)
If <internalformat> is COMPRESSED_RGB_S3TC_DXT1_EXT,
COMPRESSED_RGBA_S3TC_DXT1_EXT, COMPRESSED_RGBA_S3TC_DXT3_EXT, or
COMPRESSED_RGBA_S3TC_DXT5_EXT, the compressed texture is stored using one
of several S3TC compressed texture image formats. The S3TC texture
compression algorithm supports only 2D images without borders.
CompressedTexImage1DARB and CompressedTexImage3DARB produce an
INVALID_ENUM error if <internalformat> is an S3TC format.
CompressedTexImage2DARB will produce an INVALID_OPERATION error if
<border> is non-zero.
Add to Section 3.8.2, Alternate Image Specification (adding to the end of
the CompressedTexSubImage section introduced by the
ARB_texture_compression spec)
If the internal format of the texture image being modified is
COMPRESSED_RGB_S3TC_DXT1_EXT, COMPRESSED_RGBA_S3TC_DXT1_EXT,
COMPRESSED_RGBA_S3TC_DXT3_EXT, or COMPRESSED_RGBA_S3TC_DXT5_EXT, the
texture is stored using one of the several S3TC compressed texture image
formats. Since the S3TC texture compression algorithm supports only 2D
images, CompressedTexSubImage1DARB and CompressedTexSubImage3DARB produce
an INVALID_ENUM error if <format> is an S3TC format. Since S3TC images
are easily edited along 4x4 texel boundaries, the limitations on
CompressedTexSubImage2D are relaxed. CompressedTexSubImage2D will result
in an INVALID_OPERATION error only if one of the following conditions
occurs:
* <width> is not a multiple of four or equal to TEXTURE_WIDTH.
* <height> is not a multiple of four or equal to TEXTURE_HEIGHT.
* <xoffset> or <yoffset> is not a multiple of four.
The contents of any 4x4 block of texels of an S3TC compressed texture
image that does not intersect the area being modified are preserved during
valid TexSubImage2D and CopyTexSubImage2D calls.
Additions to Chapter 4 of the OpenGL 1.2.1 Specification (Per-Fragment
Operations and the Frame Buffer)
None.
Additions to Chapter 5 of the OpenGL 1.2.1 Specification (Special Functions)
None.
Additions to Chapter 6 of the OpenGL 1.2.1 Specification (State and
State Requests)
None.
Additions to Appendix A of the OpenGL 1.2.1 Specification (Invariance)
None.
Additions to the AGL/GLX/WGL Specifications
None.
GLX Protocol
None.
Errors
INVALID_ENUM is generated by CompressedTexImage1DARB or
CompressedTexImage3DARB if <internalformat> is
COMPRESSED_RGB_S3TC_DXT1_EXT, COMPRESSED_RGBA_S3TC_DXT1_EXT,
COMPRESSED_RGBA_S3TC_DXT3_EXT, or COMPRESSED_RGBA_S3TC_DXT5_EXT.
INVALID_OPERATION is generated by CompressedTexImage2DARB if
<internalformat> is COMPRESSED_RGB_S3TC_DXT1_EXT,
COMPRESSED_RGBA_S3TC_DXT1_EXT, COMPRESSED_RGBA_S3TC_DXT3_EXT, or
COMPRESSED_RGBA_S3TC_DXT5_EXT and <border> is not equal to zero.
INVALID_ENUM is generated by CompressedTexSubImage1DARB or
CompressedTexSubImage3DARB if <format> is COMPRESSED_RGB_S3TC_DXT1_EXT,
COMPRESSED_RGBA_S3TC_DXT1_EXT, COMPRESSED_RGBA_S3TC_DXT3_EXT, or
COMPRESSED_RGBA_S3TC_DXT5_EXT.
INVALID_OPERATION is generated by TexSubImage2D CopyTexSubImage2D, or
CompressedTexSubImage2D if TEXTURE_INTERNAL_FORMAT is
COMPRESSED_RGB_S3TC_DXT1_EXT, COMPRESSED_RGBA_S3TC_DXT1_EXT,
COMPRESSED_RGBA_S3TC_DXT3_EXT, or COMPRESSED_RGBA_S3TC_DXT5_EXT and any of
the following apply: <width> is not a multiple of four or equal to
TEXTURE_WIDTH; <height> is not a multiple of four or equal to
TEXTURE_HEIGHT; <xoffset> or <yoffset> is not a multiple of four.
The following restrictions from the ARB_texture_compression specification
do not apply to S3TC texture formats, since subimage modification is
straightforward as long as the subimage is properly aligned.
DELETE: INVALID_OPERATION is generated by TexSubImage1D, TexSubImage2D,
DELETE: TexSubImage3D, CopyTexSubImage1D, CopyTexSubImage2D, or
DELETE: CopyTexSubImage3D if the internal format of the texture image is
DELETE: compressed and <xoffset>, <yoffset>, or <zoffset> does not equal
DELETE: -b, where b is value of TEXTURE_BORDER.
DELETE: INVALID_VALUE is generated by CompressedTexSubImage1DARB,
DELETE: CompressedTexSubImage2DARB, or CompressedTexSubImage3DARB if the
DELETE: entire texture image is not being edited: if <xoffset>,
DELETE: <yoffset>, or <zoffset> is greater than -b, <xoffset> + <width> is
DELETE: less than w+b, <yoffset> + <height> is less than h+b, or <zoffset>
DELETE: + <depth> is less than d+b, where b is the value of
DELETE: TEXTURE_BORDER, w is the value of TEXTURE_WIDTH, h is the value of
DELETE: TEXTURE_HEIGHT, and d is the value of TEXTURE_DEPTH.
See also errors in the GL_ARB_texture_compression specification.
New State
In the "Textures" state table, increment the TEXTURE_INTERNAL_FORMAT
subscript for Z by 4 in the "Type" row.
New Implementation Dependent State
None
Appendix
S3TC Compressed Texture Image Formats
Compressed texture images stored using the S3TC compressed image formats
are represented as a collection of 4x4 texel blocks, where each block
contains 64 or 128 bits of texel data. The image is encoded as a normal
2D raster image in which each 4x4 block is treated as a single pixel. If
an S3TC image has a width or height less than four, the data corresponding
to texels outside the image are irrelevant and undefined.
When an S3TC image with a width of <w>, height of <h>, and block size of
<blocksize> (8 or 16 bytes) is decoded, the corresponding image size (in
bytes) is:
ceil(<w>/4) * ceil(<h>/4) * blocksize.
When decoding an S3TC image, the block containing the texel at offset
(<x>, <y>) begins at an offset (in bytes) relative to the base of the
image of:
blocksize * (ceil(<w>/4) * floor(<y>/4) + floor(<x>/4)).
The data corresponding to a specific texel (<x>, <y>) are extracted from a
4x4 texel block using a relative (x,y) value of
(<x> modulo 4, <y> modulo 4).
There are four distinct S3TC image formats:
COMPRESSED_RGB_S3TC_DXT1_EXT: Each 4x4 block of texels consists of 64
bits of RGB image data.
Each RGB image data block is encoded as a sequence of 8 bytes, called (in
order of increasing address):
c0_lo, c0_hi, c1_lo, c1_hi, bits_0, bits_1, bits_2, bits_3
The 8 bytes of the block are decoded into three quantities:
color0 = c0_lo + c0_hi * 256
color1 = c1_lo + c1_hi * 256
bits = bits_0 + 256 * (bits_1 + 256 * (bits_2 + 256 * bits_3))
color0 and color1 are 16-bit unsigned integers that are unpacked to
RGB colors RGB0 and RGB1 as though they were 16-bit packed pixels with
a <format> of RGB and a type of UNSIGNED_SHORT_5_6_5.
bits is a 32-bit unsigned integer, from which a two-bit control code
is extracted for a texel at location (x,y) in the block using:
code(x,y) = bits[2*(4*y+x)+1..2*(4*y+x)+0]
where bit 31 is the most significant and bit 0 is the least
significant bit.
The RGB color for a texel at location (x,y) in the block is given by:
RGB0, if color0 > color1 and code(x,y) == 0
RGB1, if color0 > color1 and code(x,y) == 1
(2*RGB0+RGB1)/3, if color0 > color1 and code(x,y) == 2
(RGB0+2*RGB1)/3, if color0 > color1 and code(x,y) == 3
RGB0, if color0 <= color1 and code(x,y) == 0
RGB1, if color0 <= color1 and code(x,y) == 1
(RGB0+RGB1)/2, if color0 <= color1 and code(x,y) == 2
BLACK, if color0 <= color1 and code(x,y) == 3
Arithmetic operations are done per component, and BLACK refers to an
RGB color where red, green, and blue are all zero.
Since this image has an RGB format, there is no alpha component and the
image is considered fully opaque.
COMPRESSED_RGBA_S3TC_DXT1_EXT: Each 4x4 block of texels consists of 64
bits of RGB image data and minimal alpha information. The RGB components
of a texel are extracted in the same way as COMPRESSED_RGB_S3TC_DXT1_EXT.
The alpha component for a texel at location (x,y) in the block is
given by:
0.0, if color0 <= color1 and code(x,y) == 3
1.0, otherwise
IMPORTANT: When encoding an RGBA image into a format using 1-bit
alpha, any texels with an alpha component less than 0.5 end up with an
alpha of 0.0 and any texels with an alpha component greater than or
equal to 0.5 end up with an alpha of 1.0. When encoding an RGBA image
into the COMPRESSED_RGBA_S3TC_DXT1_EXT format, the resulting red,
green, and blue components of any texels with a final alpha of 0.0
will automatically be zero (black). If this behavior is not desired
by an application, it should not use COMPRESSED_RGBA_S3TC_DXT1_EXT.
This format will never be used when a generic compressed internal
format (Table 3.16.2) is specified, although the nearly identical
format COMPRESSED_RGB_S3TC_DXT1_EXT (above) may be.
COMPRESSED_RGBA_S3TC_DXT3_EXT: Each 4x4 block of texels consists of 64
bits of uncompressed alpha image data followed by 64 bits of RGB image
data.
Each RGB image data block is encoded according to the
COMPRESSED_RGB_S3TC_DXT1_EXT format, with the exception that the two code
bits always use the non-transparent encodings. In other words, they are
treated as though color0 > color1, regardless of the actual values of
color0 and color1.
Each alpha image data block is encoded as a sequence of 8 bytes, called
(in order of increasing address):
a0, a1, a2, a3, a4, a5, a6, a7
The 8 bytes of the block are decoded into one 64-bit integer:
alpha = a0 + 256 * (a1 + 256 * (a2 + 256 * (a3 + 256 * (a4 +
256 * (a5 + 256 * (a6 + 256 * a7))))))
alpha is a 64-bit unsigned integer, from which a four-bit alpha value
is extracted for a texel at location (x,y) in the block using:
alpha(x,y) = bits[4*(4*y+x)+3..4*(4*y+x)+0]
where bit 63 is the most significant and bit 0 is the least
significant bit.
The alpha component for a texel at location (x,y) in the block is
given by alpha(x,y) / 15.
COMPRESSED_RGBA_S3TC_DXT5_EXT: Each 4x4 block of texels consists of 64
bits of compressed alpha image data followed by 64 bits of RGB image data.
Each RGB image data block is encoded according to the
COMPRESSED_RGB_S3TC_DXT1_EXT format, with the exception that the two code
bits always use the non-transparent encodings. In other words, they are
treated as though color0 > color1, regardless of the actual values of
color0 and color1.
Each alpha image data block is encoded as a sequence of 8 bytes, called
(in order of increasing address):
alpha0, alpha1, bits_0, bits_1, bits_2, bits_3, bits_4, bits_5
The alpha0 and alpha1 are 8-bit unsigned bytes converted to alpha
components by multiplying by 1/255.
The 6 "bits" bytes of the block are decoded into one 48-bit integer:
bits = bits_0 + 256 * (bits_1 + 256 * (bits_2 + 256 * (bits_3 +
256 * (bits_4 + 256 * bits_5))))
bits is a 48-bit unsigned integer, from which a three-bit control code
is extracted for a texel at location (x,y) in the block using:
code(x,y) = bits[3*(4*y+x)+1..3*(4*y+x)+0]
where bit 47 is the most significant and bit 0 is the least
significant bit.
The alpha component for a texel at location (x,y) in the block is
given by:
alpha0, code(x,y) == 0
alpha1, code(x,y) == 1
(6*alpha0 + 1*alpha1)/7, alpha0 > alpha1 and code(x,y) == 2
(5*alpha0 + 2*alpha1)/7, alpha0 > alpha1 and code(x,y) == 3
(4*alpha0 + 3*alpha1)/7, alpha0 > alpha1 and code(x,y) == 4
(3*alpha0 + 4*alpha1)/7, alpha0 > alpha1 and code(x,y) == 5
(2*alpha0 + 5*alpha1)/7, alpha0 > alpha1 and code(x,y) == 6
(1*alpha0 + 6*alpha1)/7, alpha0 > alpha1 and code(x,y) == 7
(4*alpha0 + 1*alpha1)/5, alpha0 <= alpha1 and code(x,y) == 2
(3*alpha0 + 2*alpha1)/5, alpha0 <= alpha1 and code(x,y) == 3
(2*alpha0 + 3*alpha1)/5, alpha0 <= alpha1 and code(x,y) == 4
(1*alpha0 + 4*alpha1)/5, alpha0 <= alpha1 and code(x,y) == 5
0.0, alpha0 <= alpha1 and code(x,y) == 6
1.0, alpha0 <= alpha1 and code(x,y) == 7
Revision History
1.1, 11/16/01 pbrown: Updated contact info, clarified where texels
fall within a single block.
1.0, 07/07/00 prbrown1: Published final version agreed to by working
group members.
0.9, 06/24/00 prbrown1: Documented that block-aligned TexSubImage calls
do not modify existing texels outside the
modified blocks. Added caveat to allow for a
(0,0)-anchored TexSubImage operation of
arbitrary size.
0.7, 04/11/00 prbrown1: Added issues on DXT1, DXT3, and DXT5 encodings
where the MSDN documentation doesn't match what
is really done. Added enum values from the
extension registry.
0.4, 03/28/00 prbrown1: Updated to reflect final version of the
ARB_texture_compression extension. Allowed
block-aligned TexSubImage calls.
0.3, 03/07/00 prbrown1: Resolved issues pertaining to the format of RGB
blocks in the DXT3 and DXT5 formats (they don't
ever use the "transparent" encoding). Fixed
decoding of DXT1 blocks. Pointed out issue of
"transparent" texels in DXT1 encodings having
different behaviors for RGB and RGBA internal
formats.
0.2, 02/23/00 prbrown1: Minor revisions; added several issues.
0.11, 02/17/00 prbrown1: Slight modification to error semantics
(INVALID_ENUM instead of INVALID_OPERATION).
0.1, 02/15/00 prbrown1: Initial revision.

5
Engine/source/.gitattributes vendored Normal file
View file

@ -0,0 +1,5 @@
*.cpp filter=tabspace
*.h filter=tabspace
*.l filter=tabspace
*.y filter=tabspace
*.mm filter=tabspace

File diff suppressed because it is too large Load diff

View file

@ -99,7 +99,7 @@ U32 postEvent(SimObject *destObject, SimEvent* event,U32 time)
Mutex::lockMutex(gEventQueueMutex); Mutex::lockMutex(gEventQueueMutex);
if( time == -1 ) if( time == -1 ) // FIXME: a smart compiler will remove this check. - see http://garagegames.com/community/resources/view/19785 for a fix
time = gCurrentTime; time = gCurrentTime;
event->time = time; event->time = time;

View file

@ -60,7 +60,7 @@ MODULE_END;
WindDeformationGLSL::WindDeformationGLSL() WindDeformationGLSL::WindDeformationGLSL()
: mDep( "shaders/common/gl/wind.glsl" ) : mDep(String(Con::getVariable("$Core::CommonShaderPath")) + String("/gl/wind.glsl" ))
{ {
addDependency( &mDep ); addDependency( &mDep );
} }

View file

@ -60,7 +60,7 @@ MODULE_END;
WindDeformationHLSL::WindDeformationHLSL() WindDeformationHLSL::WindDeformationHLSL()
: mDep( "shaders/common/wind.hlsl" ) : mDep(String(Con::getVariable("$Core::CommonShaderPath")) + String("/wind.hlsl" ))
{ {
addDependency( &mDep ); addDependency( &mDep );
} }

View file

@ -670,8 +670,8 @@ void GFXD3D11Device::setupGenericShaders(GenericShaderType type)
//shader model 4.0 is enough for the generic shaders //shader model 4.0 is enough for the generic shaders
const char* shaderModel = "4.0"; const char* shaderModel = "4.0";
shaderData = new ShaderData(); shaderData = new ShaderData();
shaderData->setField("DXVertexShaderFile", "shaders/common/fixedFunction/colorV.hlsl"); shaderData->setField("DXVertexShaderFile", String(Con::getVariable("$Core::CommonShaderPath")) + String("/fixedFunction/colorV.hlsl"));
shaderData->setField("DXPixelShaderFile", "shaders/common/fixedFunction/colorP.hlsl"); shaderData->setField("DXPixelShaderFile", String(Con::getVariable("$Core::CommonShaderPath")) + String("/fixedFunction/colorP.hlsl"));
shaderData->setField("pixVersion", shaderModel); shaderData->setField("pixVersion", shaderModel);
shaderData->registerObject(); shaderData->registerObject();
mGenericShader[GSColor] = shaderData->getShader(); mGenericShader[GSColor] = shaderData->getShader();
@ -680,8 +680,8 @@ void GFXD3D11Device::setupGenericShaders(GenericShaderType type)
Sim::getRootGroup()->addObject(shaderData); Sim::getRootGroup()->addObject(shaderData);
shaderData = new ShaderData(); shaderData = new ShaderData();
shaderData->setField("DXVertexShaderFile", "shaders/common/fixedFunction/modColorTextureV.hlsl"); shaderData->setField("DXVertexShaderFile", String(Con::getVariable("$Core::CommonShaderPath")) + String("/fixedFunction/modColorTextureV.hlsl"));
shaderData->setField("DXPixelShaderFile", "shaders/common/fixedFunction/modColorTextureP.hlsl"); shaderData->setField("DXPixelShaderFile", String(Con::getVariable("$Core::CommonShaderPath")) + String("/fixedFunction/modColorTextureP.hlsl"));
shaderData->setField("pixVersion", shaderModel); shaderData->setField("pixVersion", shaderModel);
shaderData->registerObject(); shaderData->registerObject();
mGenericShader[GSModColorTexture] = shaderData->getShader(); mGenericShader[GSModColorTexture] = shaderData->getShader();
@ -690,8 +690,8 @@ void GFXD3D11Device::setupGenericShaders(GenericShaderType type)
Sim::getRootGroup()->addObject(shaderData); Sim::getRootGroup()->addObject(shaderData);
shaderData = new ShaderData(); shaderData = new ShaderData();
shaderData->setField("DXVertexShaderFile", "shaders/common/fixedFunction/addColorTextureV.hlsl"); shaderData->setField("DXVertexShaderFile", String(Con::getVariable("$Core::CommonShaderPath")) + String("/fixedFunction/addColorTextureV.hlsl"));
shaderData->setField("DXPixelShaderFile", "shaders/common/fixedFunction/addColorTextureP.hlsl"); shaderData->setField("DXPixelShaderFile", String(Con::getVariable("$Core::CommonShaderPath")) + String("/fixedFunction/addColorTextureP.hlsl"));
shaderData->setField("pixVersion", shaderModel); shaderData->setField("pixVersion", shaderModel);
shaderData->registerObject(); shaderData->registerObject();
mGenericShader[GSAddColorTexture] = shaderData->getShader(); mGenericShader[GSAddColorTexture] = shaderData->getShader();
@ -700,8 +700,8 @@ void GFXD3D11Device::setupGenericShaders(GenericShaderType type)
Sim::getRootGroup()->addObject(shaderData); Sim::getRootGroup()->addObject(shaderData);
shaderData = new ShaderData(); shaderData = new ShaderData();
shaderData->setField("DXVertexShaderFile", "shaders/common/fixedFunction/textureV.hlsl"); shaderData->setField("DXVertexShaderFile", String(Con::getVariable("$Core::CommonShaderPath")) + String("/fixedFunction/textureV.hlsl"));
shaderData->setField("DXPixelShaderFile", "shaders/common/fixedFunction/textureP.hlsl"); shaderData->setField("DXPixelShaderFile", String(Con::getVariable("$Core::CommonShaderPath")) + String("/fixedFunction/textureP.hlsl"));
shaderData->setField("pixVersion", shaderModel); shaderData->setField("pixVersion", shaderModel);
shaderData->registerObject(); shaderData->registerObject();
mGenericShader[GSTexture] = shaderData->getShader(); mGenericShader[GSTexture] = shaderData->getShader();

View file

@ -154,8 +154,8 @@ inline void GFXD3D9Device::setupGenericShaders( GenericShaderType type /* = GSCo
ShaderData *shaderData; ShaderData *shaderData;
shaderData = new ShaderData(); shaderData = new ShaderData();
shaderData->setField("DXVertexShaderFile", "shaders/common/fixedFunction/colorV.hlsl"); shaderData->setField("DXVertexShaderFile", String(Con::getVariable("$Core::CommonShaderPath")) + String("/fixedFunction/colorV.hlsl"));
shaderData->setField("DXPixelShaderFile", "shaders/common/fixedFunction/colorP.hlsl"); shaderData->setField("DXPixelShaderFile", String(Con::getVariable("$Core::CommonShaderPath")) + String("/fixedFunction/colorP.hlsl"));
shaderData->setField("pixVersion", "3.0"); shaderData->setField("pixVersion", "3.0");
shaderData->registerObject(); shaderData->registerObject();
mGenericShader[GSColor] = shaderData->getShader(); mGenericShader[GSColor] = shaderData->getShader();
@ -164,8 +164,8 @@ inline void GFXD3D9Device::setupGenericShaders( GenericShaderType type /* = GSCo
Sim::getRootGroup()->addObject(shaderData); Sim::getRootGroup()->addObject(shaderData);
shaderData = new ShaderData(); shaderData = new ShaderData();
shaderData->setField("DXVertexShaderFile", "shaders/common/fixedFunction/modColorTextureV.hlsl"); shaderData->setField("DXVertexShaderFile", String(Con::getVariable("$Core::CommonShaderPath")) + String("/fixedFunction/modColorTextureV.hlsl"));
shaderData->setField("DXPixelShaderFile", "shaders/common/fixedFunction/modColorTextureP.hlsl"); shaderData->setField("DXPixelShaderFile", String(Con::getVariable("$Core::CommonShaderPath")) + String("/fixedFunction/modColorTextureP.hlsl"));
shaderData->setSamplerName("$diffuseMap", 0); shaderData->setSamplerName("$diffuseMap", 0);
shaderData->setField("pixVersion", "3.0"); shaderData->setField("pixVersion", "3.0");
shaderData->registerObject(); shaderData->registerObject();
@ -175,8 +175,8 @@ inline void GFXD3D9Device::setupGenericShaders( GenericShaderType type /* = GSCo
Sim::getRootGroup()->addObject(shaderData); Sim::getRootGroup()->addObject(shaderData);
shaderData = new ShaderData(); shaderData = new ShaderData();
shaderData->setField("DXVertexShaderFile", "shaders/common/fixedFunction/addColorTextureV.hlsl"); shaderData->setField("DXVertexShaderFile", String(Con::getVariable("$Core::CommonShaderPath")) + String("/fixedFunction/addColorTextureV.hlsl"));
shaderData->setField("DXPixelShaderFile", "shaders/common/fixedFunction/addColorTextureP.hlsl"); shaderData->setField("DXPixelShaderFile", String(Con::getVariable("$Core::CommonShaderPath")) + String("/fixedFunction/addColorTextureP.hlsl"));
shaderData->setSamplerName("$diffuseMap", 0); shaderData->setSamplerName("$diffuseMap", 0);
shaderData->setField("pixVersion", "3.0"); shaderData->setField("pixVersion", "3.0");
shaderData->registerObject(); shaderData->registerObject();
@ -186,8 +186,8 @@ inline void GFXD3D9Device::setupGenericShaders( GenericShaderType type /* = GSCo
Sim::getRootGroup()->addObject(shaderData); Sim::getRootGroup()->addObject(shaderData);
shaderData = new ShaderData(); shaderData = new ShaderData();
shaderData->setField("DXVertexShaderFile", "shaders/common/fixedFunction/textureV.hlsl"); shaderData->setField("DXVertexShaderFile", String(Con::getVariable("$Core::CommonShaderPath")) + String("/fixedFunction/textureV.hlsl"));
shaderData->setField("DXPixelShaderFile", "shaders/common/fixedFunction/textureP.hlsl"); shaderData->setField("DXPixelShaderFile", String(Con::getVariable("$Core::CommonShaderPath")) + String("/fixedFunction/textureP.hlsl"));
shaderData->setSamplerName("$diffuseMap", 0); shaderData->setSamplerName("$diffuseMap", 0);
shaderData->setField("pixVersion", "3.0"); shaderData->setField("pixVersion", "3.0");
shaderData->registerObject(); shaderData->registerObject();

View file

@ -42,9 +42,9 @@ using namespace Torque;
S32 GFXTextureManager::smTextureReductionLevel = 0; S32 GFXTextureManager::smTextureReductionLevel = 0;
String GFXTextureManager::smMissingTexturePath("core/art/missingTexture"); String GFXTextureManager::smMissingTexturePath(Con::getVariable("$Core::MissingTexturePath"));
String GFXTextureManager::smUnavailableTexturePath("core/art/unavailable"); String GFXTextureManager::smUnavailableTexturePath(Con::getVariable("$Core::UnAvailableTexturePath"));
String GFXTextureManager::smWarningTexturePath("core/art/warnmat"); String GFXTextureManager::smWarningTexturePath(Con::getVariable("$Core::WarningTexturePath"));
GFXTextureManager::EventSignal GFXTextureManager::smEventSignal; GFXTextureManager::EventSignal GFXTextureManager::smEventSignal;

View file

@ -780,8 +780,8 @@ void GFXGLDevice::setupGenericShaders( GenericShaderType type )
ShaderData *shaderData; ShaderData *shaderData;
shaderData = new ShaderData(); shaderData = new ShaderData();
shaderData->setField("OGLVertexShaderFile", "shaders/common/fixedFunction/gl/colorV.glsl"); shaderData->setField("OGLVertexShaderFile", String(Con::getVariable("$Core::CommonShaderPath")) + String("/fixedFunction/gl/colorV.glsl"));
shaderData->setField("OGLPixelShaderFile", "shaders/common/fixedFunction/gl/colorP.glsl"); shaderData->setField("OGLPixelShaderFile", String(Con::getVariable("$Core::CommonShaderPath")) + String("/fixedFunction/gl/colorP.glsl"));
shaderData->setField("pixVersion", "2.0"); shaderData->setField("pixVersion", "2.0");
shaderData->registerObject(); shaderData->registerObject();
mGenericShader[GSColor] = shaderData->getShader(); mGenericShader[GSColor] = shaderData->getShader();
@ -790,8 +790,8 @@ void GFXGLDevice::setupGenericShaders( GenericShaderType type )
Sim::getRootGroup()->addObject(shaderData); Sim::getRootGroup()->addObject(shaderData);
shaderData = new ShaderData(); shaderData = new ShaderData();
shaderData->setField("OGLVertexShaderFile", "shaders/common/fixedFunction/gl/modColorTextureV.glsl"); shaderData->setField("OGLVertexShaderFile", String(Con::getVariable("$Core::CommonShaderPath")) + String("/fixedFunction/gl/modColorTextureV.glsl"));
shaderData->setField("OGLPixelShaderFile", "shaders/common/fixedFunction/gl/modColorTextureP.glsl"); shaderData->setField("OGLPixelShaderFile", String(Con::getVariable("$Core::CommonShaderPath")) + String("/fixedFunction/gl/modColorTextureP.glsl"));
shaderData->setSamplerName("$diffuseMap", 0); shaderData->setSamplerName("$diffuseMap", 0);
shaderData->setField("pixVersion", "2.0"); shaderData->setField("pixVersion", "2.0");
shaderData->registerObject(); shaderData->registerObject();
@ -801,8 +801,8 @@ void GFXGLDevice::setupGenericShaders( GenericShaderType type )
Sim::getRootGroup()->addObject(shaderData); Sim::getRootGroup()->addObject(shaderData);
shaderData = new ShaderData(); shaderData = new ShaderData();
shaderData->setField("OGLVertexShaderFile", "shaders/common/fixedFunction/gl/addColorTextureV.glsl"); shaderData->setField("OGLVertexShaderFile", String(Con::getVariable("$Core::CommonShaderPath")) + String("/fixedFunction/gl/addColorTextureV.glsl"));
shaderData->setField("OGLPixelShaderFile", "shaders/common/fixedFunction/gl/addColorTextureP.glsl"); shaderData->setField("OGLPixelShaderFile", String(Con::getVariable("$Core::CommonShaderPath")) + String("/fixedFunction/gl/addColorTextureP.glsl"));
shaderData->setSamplerName("$diffuseMap", 0); shaderData->setSamplerName("$diffuseMap", 0);
shaderData->setField("pixVersion", "2.0"); shaderData->setField("pixVersion", "2.0");
shaderData->registerObject(); shaderData->registerObject();
@ -812,8 +812,8 @@ void GFXGLDevice::setupGenericShaders( GenericShaderType type )
Sim::getRootGroup()->addObject(shaderData); Sim::getRootGroup()->addObject(shaderData);
shaderData = new ShaderData(); shaderData = new ShaderData();
shaderData->setField("OGLVertexShaderFile", "shaders/common/fixedFunction/gl/textureV.glsl"); shaderData->setField("OGLVertexShaderFile", String(Con::getVariable("$Core::CommonShaderPath")) + String("/fixedFunction/gl/textureV.glsl"));
shaderData->setField("OGLPixelShaderFile", "shaders/common/fixedFunction/gl/textureP.glsl"); shaderData->setField("OGLPixelShaderFile", String(Con::getVariable("$Core::CommonShaderPath")) + String("/fixedFunction/gl/textureP.glsl"));
shaderData->setSamplerName("$diffuseMap", 0); shaderData->setSamplerName("$diffuseMap", 0);
shaderData->setField("pixVersion", "2.0"); shaderData->setField("pixVersion", "2.0");
shaderData->registerObject(); shaderData->registerObject();

View file

@ -68,7 +68,8 @@ ImplementEnumType( WorldEditorDropType,
{ WorldEditor::DropAtScreenCenter, "screenCenter", "Places at a position projected outwards from the screen's center.\n" }, { WorldEditor::DropAtScreenCenter, "screenCenter", "Places at a position projected outwards from the screen's center.\n" },
{ WorldEditor::DropAtCentroid, "atCentroid", "Places at the center position of the current centroid.\n" }, { WorldEditor::DropAtCentroid, "atCentroid", "Places at the center position of the current centroid.\n" },
{ WorldEditor::DropToTerrain, "toTerrain", "Places on the terrain.\n" }, { WorldEditor::DropToTerrain, "toTerrain", "Places on the terrain.\n" },
{ WorldEditor::DropBelowSelection, "belowSelection", "Places at a position below the selected object.\n" } { WorldEditor::DropBelowSelection, "belowSelection", "Places at a position below the selected object.\n" },
{ WorldEditor::DropAtGizmo, "atGizmo", "Places at the gizmo point.\n" }
EndImplementEnumType; EndImplementEnumType;
ImplementEnumType( WorldEditorAlignmentType, ImplementEnumType( WorldEditorAlignmentType,
@ -643,10 +644,10 @@ void WorldEditor::dropSelection(Selection* sel)
Point3F offset = -boxCenter; Point3F offset = -boxCenter;
offset.z += bounds.len_z() * 0.5f; offset.z += bounds.len_z() * 0.5f;
sel->offset( offset, mGridSnap ? mGridPlaneSize : 0.f ); sel->offset(offset, (!mUseGroupCenter && mGridSnap) ? mGridPlaneSize : 0.f);
} }
else else
sel->offset( Point3F( -centroid ), mGridSnap ? mGridPlaneSize : 0.f ); sel->offset(Point3F(-centroid), (!mUseGroupCenter && mGridSnap) ? mGridPlaneSize : 0.f);
break; break;
} }
@ -657,7 +658,7 @@ void WorldEditor::dropSelection(Selection* sel)
if(mDropAtBounds && !sel->containsGlobalBounds()) if(mDropAtBounds && !sel->containsGlobalBounds())
center = sel->getBoxBottomCenter(); center = sel->getBoxBottomCenter();
sel->offset( Point3F( smCamPos - center ), mGridSnap ? mGridPlaneSize : 0.f ); sel->offset(Point3F(smCamPos - center), (!mUseGroupCenter && mGridSnap) ? mGridPlaneSize : 0.f);
sel->orient(smCamMatrix, center); sel->orient(smCamMatrix, center);
break; break;
} }
@ -668,7 +669,7 @@ void WorldEditor::dropSelection(Selection* sel)
if(mDropAtBounds && !sel->containsGlobalBounds()) if(mDropAtBounds && !sel->containsGlobalBounds())
sel->getBoxBottomCenter(); sel->getBoxBottomCenter();
sel->offset( Point3F( smCamPos - center ), mGridSnap ? mGridPlaneSize : 0.f ); sel->offset(Point3F(smCamPos - center), (!mUseGroupCenter && mGridSnap) ? mGridPlaneSize : 0.f);
break; break;
} }
@ -680,7 +681,7 @@ void WorldEditor::dropSelection(Selection* sel)
Point3F offset = smCamPos - center; Point3F offset = smCamPos - center;
offset.z -= mDropBelowCameraOffset; offset.z -= mDropBelowCameraOffset;
sel->offset( offset, mGridSnap ? mGridPlaneSize : 0.f ); sel->offset(offset, (!mUseGroupCenter && mGridSnap) ? mGridPlaneSize : 0.f);
break; break;
} }
@ -712,7 +713,7 @@ void WorldEditor::dropSelection(Selection* sel)
event.vec = wp - smCamPos; event.vec = wp - smCamPos;
event.vec.normalizeSafe(); event.vec.normalizeSafe();
event.vec *= viewdist; event.vec *= viewdist;
sel->offset( Point3F( event.pos - center ) += event.vec, mGridSnap ? mGridPlaneSize : 0.f ); sel->offset(Point3F(event.pos - center) += event.vec, (!mUseGroupCenter && mGridSnap) ? mGridPlaneSize : 0.f);
break; break;
} }
@ -728,12 +729,26 @@ void WorldEditor::dropSelection(Selection* sel)
dropBelowSelection(sel, centroid, mDropAtBounds); dropBelowSelection(sel, centroid, mDropAtBounds);
break; break;
} }
case DropAtGizmo:
{
dropAtGizmo(sel, mGizmo->getPosition()-centroid);
break;
}
} }
// //
updateClientTransforms(sel); updateClientTransforms(sel);
} }
void WorldEditor::dropAtGizmo(Selection* sel, const Point3F & gizmoPos)
{
if (!sel->size())
return;
sel->offset(gizmoPos, (!mUseGroupCenter && mGridSnap) ? mGridPlaneSize : 0.f);
}
void WorldEditor::dropBelowSelection(Selection* sel, const Point3F & centroid, bool useBottomBounds) void WorldEditor::dropBelowSelection(Selection* sel, const Point3F & centroid, bool useBottomBounds)
{ {
if(!sel->size()) if(!sel->size())
@ -756,7 +771,7 @@ void WorldEditor::dropBelowSelection(Selection* sel, const Point3F & centroid,
sel->enableCollision(); sel->enableCollision();
if( hit ) if( hit )
sel->offset( ri.point - start, mGridSnap ? mGridPlaneSize : 0.f ); sel->offset(ri.point - start, (!mUseGroupCenter && mGridSnap) ? mGridPlaneSize : 0.f);
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
@ -800,7 +815,7 @@ void WorldEditor::terrainSnapSelection(Selection* sel, U8 modifier, Point3F gizm
{ {
mStuckToGround = true; mStuckToGround = true;
sel->offset( ri.point - centroid, mGridSnap ? mGridPlaneSize : 0.f ); sel->offset(ri.point - centroid, (!mUseGroupCenter && mGridSnap) ? mGridPlaneSize : 0.f);
if(mTerrainSnapAlignment != AlignNone) if(mTerrainSnapAlignment != AlignNone)
{ {
@ -1026,7 +1041,7 @@ void WorldEditor::softSnapSelection(Selection* sel, U8 modifier, Point3F gizmoPo
if ( minT <= 1.0f ) if ( minT <= 1.0f )
foundPoint += ( end - start ) * (0.5f - minT); foundPoint += ( end - start ) * (0.5f - minT);
sel->offset( foundPoint - sel->getCentroid(), mGridSnap ? mGridPlaneSize : 0.f ); sel->offset(foundPoint - sel->getCentroid(), (!mUseGroupCenter && mGridSnap) ? mGridPlaneSize : 0.f);
} }
mSoftSnapIsStuck = found; mSoftSnapIsStuck = found;
@ -1805,7 +1820,7 @@ WorldEditor::WorldEditor()
mSoftSnapDebugPoint.set(0.0f, 0.0f, 0.0f); mSoftSnapDebugPoint.set(0.0f, 0.0f, 0.0f);
mGridSnap = false; mGridSnap = false;
mUseGroupCenter = true;
mFadeIcons = true; mFadeIcons = true;
mFadeIconsDist = 8.f; mFadeIconsDist = 8.f;
} }
@ -2254,7 +2269,7 @@ void WorldEditor::on3DMouseDragged(const Gui3DMouseEvent & event)
mGizmo->getProfile()->snapToGrid = snapToGrid; mGizmo->getProfile()->snapToGrid = snapToGrid;
} }
mSelected->offset( mGizmo->getOffset() ); mSelected->offset(mGizmo->getOffset(), (!mUseGroupCenter && mGridSnap) ? mGridPlaneSize : 0.f);
// Handle various sticking // Handle various sticking
terrainSnapSelection( mSelected, event.modifier, mGizmo->getPosition() ); terrainSnapSelection( mSelected, event.modifier, mGizmo->getPosition() );
@ -2686,7 +2701,8 @@ void WorldEditor::initPersistFields()
addGroup( "Grid" ); addGroup( "Grid" );
addField( "gridSnap", TypeBool, Offset( mGridSnap, WorldEditor ), addField( "gridSnap", TypeBool, Offset( mGridSnap, WorldEditor ),
"If true, transform operations will snap to the grid." ); "If true, transform operations will snap to the grid.");
addField("useGroupCenter", TypeBool, Offset(mUseGroupCenter, WorldEditor));
endGroup( "Grid" ); endGroup( "Grid" );
@ -3035,7 +3051,7 @@ void WorldEditor::transformSelection(bool position, Point3F& p, bool relativePos
{ {
if( relativePos ) if( relativePos )
{ {
mSelected->offset( p, mGridSnap ? mGridPlaneSize : 0.f ); mSelected->offset(p, (!mUseGroupCenter && mGridSnap) ? mGridPlaneSize : 0.f);
} }
else else
{ {
@ -3641,7 +3657,7 @@ void WorldEditor::makeSelectionPrefab( const char *filename )
else else
{ {
//Only push the cleanup of the group if it's ONLY a SimGroup. //Only push the cleanup of the group if it's ONLY a SimGroup.
cleanup.push_back(grp); cleanup.push_back( grp );
} }
} }
else else

View file

@ -164,7 +164,8 @@ class WorldEditor : public EditTSCtrl
bool copySelection(Selection* sel); bool copySelection(Selection* sel);
bool pasteSelection(bool dropSel=true); bool pasteSelection(bool dropSel=true);
void dropSelection(Selection* sel); void dropSelection(Selection* sel);
void dropBelowSelection(Selection* sel, const Point3F & centroid, bool useBottomBounds=false); void dropBelowSelection(Selection* sel, const Point3F & centroid, bool useBottomBounds = false);
void dropAtGizmo(Selection* sel, const Point3F & gizmoPos);
void terrainSnapSelection(Selection* sel, U8 modifier, Point3F gizmoPos, bool forceStick=false); void terrainSnapSelection(Selection* sel, U8 modifier, Point3F gizmoPos, bool forceStick=false);
void softSnapSelection(Selection* sel, U8 modifier, Point3F gizmoPos); void softSnapSelection(Selection* sel, U8 modifier, Point3F gizmoPos);
@ -296,7 +297,8 @@ class WorldEditor : public EditTSCtrl
DropAtScreenCenter, DropAtScreenCenter,
DropAtCentroid, DropAtCentroid,
DropToTerrain, DropToTerrain,
DropBelowSelection DropBelowSelection,
DropAtGizmo
}; };
// Snapping alignment mode // Snapping alignment mode
@ -349,6 +351,7 @@ class WorldEditor : public EditTSCtrl
F32 mDropAtScreenCenterMax; F32 mDropAtScreenCenterMax;
bool mGridSnap; bool mGridSnap;
bool mUseGroupCenter;
bool mStickToGround; bool mStickToGround;
bool mStuckToGround; ///< Selection is stuck to the ground bool mStuckToGround; ///< Selection is stuck to the ground
AlignmentType mTerrainSnapAlignment; ///< How does the stickied object align to the terrain AlignmentType mTerrainSnapAlignment; ///< How does the stickied object align to the terrain

View file

@ -306,9 +306,9 @@ void WorldEditorSelection::offset( const Point3F& offset, F32 gridSnap )
if( gridSnap != 0.f ) if( gridSnap != 0.f )
{ {
wPos.x -= mFmod( wPos.x, gridSnap ); wPos.x = _snapFloat(wPos.x, gridSnap);
wPos.y -= mFmod( wPos.y, gridSnap ); wPos.y = _snapFloat(wPos.y, gridSnap);
wPos.z -= mFmod( wPos.z, gridSnap ); wPos.z = _snapFloat(wPos.z, gridSnap);
} }
mat.setColumn(3, wPos); mat.setColumn(3, wPos);
@ -318,6 +318,22 @@ void WorldEditorSelection::offset( const Point3F& offset, F32 gridSnap )
mCentroidValid = false; mCentroidValid = false;
} }
F32 WorldEditorSelection::_snapFloat(const F32 &val, const F32 &snap) const
{
if (snap == 0.0f)
return val;
F32 a = mFmod(val, snap);
F32 temp = val;
if (mFabs(a) > (snap / 2))
val < 0.0f ? temp -= snap : temp += snap;
return(temp - a);
}
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void WorldEditorSelection::setPosition(const Point3F & pos) void WorldEditorSelection::setPosition(const Point3F & pos)

View file

@ -108,6 +108,7 @@ class WorldEditorSelection : public SimPersistSet
// //
void offset(const Point3F& delta, F32 gridSnap = 0.f ); void offset(const Point3F& delta, F32 gridSnap = 0.f );
void setPosition(const Point3F & pos); void setPosition(const Point3F & pos);
F32 _snapFloat(const F32 &val, const F32 &snap) const;
void setCentroidPosition(bool useBoxCenter, const Point3F & pos); void setCentroidPosition(bool useBoxCenter, const Point3F & pos);
void orient(const MatrixF &, const Point3F &); void orient(const MatrixF &, const Point3F &);

View file

@ -48,10 +48,10 @@ ConsoleDocClass( ShaderData,
"// Used for the procedural clould system\n" "// Used for the procedural clould system\n"
"singleton ShaderData( CloudLayerShader )\n" "singleton ShaderData( CloudLayerShader )\n"
"{\n" "{\n"
" DXVertexShaderFile = \"shaders/common/cloudLayerV.hlsl\";\n" " DXVertexShaderFile = $Core::CommonShaderPath @ \"/cloudLayerV.hlsl\";\n"
" DXPixelShaderFile = \"shaders/common/cloudLayerP.hlsl\";\n" " DXPixelShaderFile = $Core::CommonShaderPath @ \"/cloudLayerP.hlsl\";\n"
" OGLVertexShaderFile = \"shaders/common/gl/cloudLayerV.glsl\";\n" " OGLVertexShaderFile = $Core::CommonShaderPath @ \"/gl/cloudLayerV.glsl\";\n"
" OGLPixelShaderFile = \"shaders/common/gl/cloudLayerP.glsl\";\n" " OGLPixelShaderFile = $Core::CommonShaderPath @ \"/gl/cloudLayerP.glsl\";\n"
" pixVersion = 2.0;\n" " pixVersion = 2.0;\n"
"};\n" "};\n"
"@endtsexample\n\n" "@endtsexample\n\n"
@ -109,8 +109,8 @@ void ShaderData::initPersistFields()
"@tsexample\n" "@tsexample\n"
"singleton ShaderData( FlashShader )\n" "singleton ShaderData( FlashShader )\n"
"{\n" "{\n"
"DXVertexShaderFile = \"shaders/common/postFx/flashV.hlsl\";\n" "DXVertexShaderFile = $shaderGen::cachePath @ \"/postFx/flashV.hlsl\";\n"
"DXPixelShaderFile = \"shaders/common/postFx/flashP.hlsl\";\n\n" "DXPixelShaderFile = $shaderGen::cachePath @ \"/postFx/flashP.hlsl\";\n\n"
" //Define setting the color of WHITE_COLOR.\n" " //Define setting the color of WHITE_COLOR.\n"
"defines = \"WHITE_COLOR=float4(1.0,1.0,1.0,0.0)\";\n\n" "defines = \"WHITE_COLOR=float4(1.0,1.0,1.0,0.0)\";\n\n"
"pixVersion = 2.0\n" "pixVersion = 2.0\n"

View file

@ -373,3 +373,20 @@ DefineConsoleFunction( mGetAngleBetweenVectors, F32, (VectorF vecA, VectorF vecB
{ {
return MathUtils::getAngleBetweenVectors(vecA, vecB); return MathUtils::getAngleBetweenVectors(vecA, vecB);
} }
DefineConsoleFunction(mGetSignedAngleBetweenVectors, F32, (VectorF vecA, VectorF vecB, VectorF norm), (VectorF::Zero, VectorF::Zero, VectorF::Zero),
"Returns signed angle between two vectors, using a normal for orientation.\n"
"@param vecA First input vector."
"@param vecB Second input vector."
"@param norm Normal/Cross Product vector."
"@returns Angle between both vectors in radians."
"@ingroup Math")
{
if (vecA.isZero() || vecB.isZero() || norm.isZero())
{
Con::errorf("mGetSignedAngleBetweenVectors - Error! Requires all 3 vectors used to be non-zero!");
return 0;
}
return MathUtils::getSignedAngleBetweenVectors(vecA, vecB, norm);
}

View file

@ -371,6 +371,18 @@ F32 getAngleBetweenVectors(VectorF vecA, VectorF vecB)
return angle; return angle;
} }
F32 getSignedAngleBetweenVectors(VectorF vecA, VectorF vecB, VectorF norm)
{
// angle in 0-180
F32 angle = getAngleBetweenVectors(vecA, vecB);
F32 sign = mSign(mDot(norm, mCross(vecA, vecB)));
// angle in -179-180
F32 signed_angle = angle * sign;
return signed_angle;
}
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void transformBoundingBox(const Box3F &sbox, const MatrixF &mat, const Point3F scale, Box3F &dbox) void transformBoundingBox(const Box3F &sbox, const MatrixF &mat, const Point3F scale, Box3F &dbox)

View file

@ -161,6 +161,11 @@ namespace MathUtils
/// ///
F32 getAngleBetweenVectors(VectorF vecA, VectorF vecB); F32 getAngleBetweenVectors(VectorF vecA, VectorF vecB);
/// Returns the angle between two given vectors, utilizing a normal vector to discertain the angle's sign
///
/// Angles is in RADIANS
///
F32 getSignedAngleBetweenVectors(VectorF vecA, VectorF vecB, VectorF norm);
/// Simple reflection equation - pass in a vector and a normal to reflect off of /// Simple reflection equation - pass in a vector and a normal to reflect off of
inline Point3F reflect( Point3F &inVec, Point3F &norm ) inline Point3F reflect( Point3F &inVec, Point3F &norm )

View file

@ -51,6 +51,7 @@ mModuleId(StringTable->EmptyString()),
mSynchronized( false ), mSynchronized( false ),
mDeprecated( false ), mDeprecated( false ),
mCriticalMerge( false ), mCriticalMerge( false ),
mOverrideExistingObjects(false),
mModuleDescription( StringTable->EmptyString() ), mModuleDescription( StringTable->EmptyString() ),
mAuthor(StringTable->EmptyString()), mAuthor(StringTable->EmptyString()),
mModuleGroup(StringTable->EmptyString()), mModuleGroup(StringTable->EmptyString()),
@ -91,6 +92,7 @@ void ModuleDefinition::initPersistFields()
addProtectedField( "Synchronized", TypeBool, Offset(mSynchronized, ModuleDefinition), &setSynchronized, &defaultProtectedGetFn, &writeSynchronized, "Whether the module should be synchronized or not. Optional: If not specified then the module is not synchronized." ); addProtectedField( "Synchronized", TypeBool, Offset(mSynchronized, ModuleDefinition), &setSynchronized, &defaultProtectedGetFn, &writeSynchronized, "Whether the module should be synchronized or not. Optional: If not specified then the module is not synchronized." );
addProtectedField( "Deprecated", TypeBool, Offset(mDeprecated, ModuleDefinition), &setDeprecated, &defaultProtectedGetFn, &writeDeprecated, "Whether the module is deprecated or not. Optional: If not specified then the module is not deprecated." ); addProtectedField( "Deprecated", TypeBool, Offset(mDeprecated, ModuleDefinition), &setDeprecated, &defaultProtectedGetFn, &writeDeprecated, "Whether the module is deprecated or not. Optional: If not specified then the module is not deprecated." );
addProtectedField( "CriticalMerge", TypeBool, Offset(mCriticalMerge, ModuleDefinition), &setDeprecated, &defaultProtectedGetFn, &writeCriticalMerge, "Whether the merging of a module prior to a restart is critical or not. Optional: If not specified then the module is not merge critical." ); addProtectedField( "CriticalMerge", TypeBool, Offset(mCriticalMerge, ModuleDefinition), &setDeprecated, &defaultProtectedGetFn, &writeCriticalMerge, "Whether the merging of a module prior to a restart is critical or not. Optional: If not specified then the module is not merge critical." );
addProtectedField( "OverrideExistingObjects", TypeBool, Offset(mOverrideExistingObjects, ModuleDefinition), &setOverrideExistingObjects, &defaultProtectedGetFn, &writeOverrideExistingObjects, "Controls if when this module is loaded and the create function is executed, it will replace existing objects that share names or not.");
addProtectedField( "Description", TypeString, Offset(mModuleDescription, ModuleDefinition), &setModuleDescription, &defaultProtectedGetFn, &writeModuleDescription, "The description typically used for debugging purposes but can be used for anything." ); addProtectedField( "Description", TypeString, Offset(mModuleDescription, ModuleDefinition), &setModuleDescription, &defaultProtectedGetFn, &writeModuleDescription, "The description typically used for debugging purposes but can be used for anything." );
addProtectedField( "Author", TypeString, Offset(mAuthor, ModuleDefinition), &setAuthor, &defaultProtectedGetFn, &writeAuthor, "The author of the module." ); addProtectedField( "Author", TypeString, Offset(mAuthor, ModuleDefinition), &setAuthor, &defaultProtectedGetFn, &writeAuthor, "The author of the module." );
addProtectedField( "Group", TypeString, Offset(mModuleGroup, ModuleDefinition), &setModuleGroup, &defaultProtectedGetFn, "The module group used typically when loading modules as a group." ); addProtectedField( "Group", TypeString, Offset(mModuleGroup, ModuleDefinition), &setModuleGroup, &defaultProtectedGetFn, "The module group used typically when loading modules as a group." );

View file

@ -89,6 +89,7 @@ private:
bool mSynchronized; bool mSynchronized;
bool mDeprecated; bool mDeprecated;
bool mCriticalMerge; bool mCriticalMerge;
bool mOverrideExistingObjects;
StringTableEntry mModuleDescription; StringTableEntry mModuleDescription;
StringTableEntry mAuthor;; StringTableEntry mAuthor;;
StringTableEntry mModuleGroup; StringTableEntry mModuleGroup;
@ -141,6 +142,8 @@ public:
inline bool getDeprecated( void ) const { return mDeprecated; } inline bool getDeprecated( void ) const { return mDeprecated; }
inline void setCriticalMerge( const bool mergeCritical ) { if ( checkUnlocked() ) { mCriticalMerge = mergeCritical; } } inline void setCriticalMerge( const bool mergeCritical ) { if ( checkUnlocked() ) { mCriticalMerge = mergeCritical; } }
inline bool getCriticalMerge( void ) const { return mCriticalMerge; } inline bool getCriticalMerge( void ) const { return mCriticalMerge; }
inline void setOverrideExistingObjects(const bool overrideExistingObj) { if (checkUnlocked()) { mOverrideExistingObjects = overrideExistingObj; } }
inline bool getOverrideExistingObjects(void) const { return mOverrideExistingObjects; }
inline void setModuleDescription( const char* pModuleDescription ) { if ( checkUnlocked() ) { mModuleDescription = StringTable->insert(pModuleDescription); } } inline void setModuleDescription( const char* pModuleDescription ) { if ( checkUnlocked() ) { mModuleDescription = StringTable->insert(pModuleDescription); } }
inline StringTableEntry getModuleDescription( void ) const { return mModuleDescription; } inline StringTableEntry getModuleDescription( void ) const { return mModuleDescription; }
inline void setAuthor( const char* pAuthor ) { if ( checkUnlocked() ) { mAuthor = StringTable->insert(pAuthor); } } inline void setAuthor( const char* pAuthor ) { if ( checkUnlocked() ) { mAuthor = StringTable->insert(pAuthor); } }
@ -206,6 +209,8 @@ protected:
static bool setDeprecated(void* obj, const char* index, const char* data) { static_cast<ModuleDefinition*>(obj)->setDeprecated(dAtob(data)); return false; } static bool setDeprecated(void* obj, const char* index, const char* data) { static_cast<ModuleDefinition*>(obj)->setDeprecated(dAtob(data)); return false; }
static bool writeDeprecated( void* obj, StringTableEntry pFieldName ) { return static_cast<ModuleDefinition*>(obj)->getDeprecated() == true; } static bool writeDeprecated( void* obj, StringTableEntry pFieldName ) { return static_cast<ModuleDefinition*>(obj)->getDeprecated() == true; }
static bool writeCriticalMerge( void* obj, StringTableEntry pFieldName ){ return static_cast<ModuleDefinition*>(obj)->getCriticalMerge() == true; } static bool writeCriticalMerge( void* obj, StringTableEntry pFieldName ){ return static_cast<ModuleDefinition*>(obj)->getCriticalMerge() == true; }
static bool setOverrideExistingObjects(void* obj, const char* index, const char* data) { static_cast<ModuleDefinition*>(obj)->setOverrideExistingObjects(dAtob(data)); return false; }
static bool writeOverrideExistingObjects(void* obj, StringTableEntry pFieldName) { return static_cast<ModuleDefinition*>(obj)->getOverrideExistingObjects() == true; }
static bool setModuleDescription(void* obj, const char* index, const char* data) { static_cast<ModuleDefinition*>(obj)->setModuleDescription(data); return false; } static bool setModuleDescription(void* obj, const char* index, const char* data) { static_cast<ModuleDefinition*>(obj)->setModuleDescription(data); return false; }
static bool writeModuleDescription( void* obj, StringTableEntry pFieldName ) { return static_cast<ModuleDefinition*>(obj)->getModuleDescription() != StringTable->EmptyString(); } static bool writeModuleDescription( void* obj, StringTableEntry pFieldName ) { return static_cast<ModuleDefinition*>(obj)->getModuleDescription() != StringTable->EmptyString(); }
static bool setAuthor(void* obj, const char* index, const char* data) { static_cast<ModuleDefinition*>(obj)->setAuthor(data); return false; } static bool setAuthor(void* obj, const char* index, const char* data) { static_cast<ModuleDefinition*>(obj)->setAuthor(data); return false; }

View file

@ -429,7 +429,22 @@ bool ModuleManager::loadModuleGroup( const char* pModuleGroup )
if ( pScopeSet->isMethod( pLoadReadyModuleDefinition->getCreateFunction() ) ) if ( pScopeSet->isMethod( pLoadReadyModuleDefinition->getCreateFunction() ) )
{ {
// Yes, so call the create method. // Yes, so call the create method.
Con::executef( pScopeSet, pLoadReadyModuleDefinition->getCreateFunction() );
//But first, check if we're overriding objects, and if so, set our console var to make that happen while we exec our create function
if (pLoadReadyModuleDefinition->getOverrideExistingObjects())
{
String redefineBehaviorPrev = Con::getVariable("$Con::redefineBehavior");
Con::setVariable("$Con::redefineBehavior", "replaceExisting");
Con::executef(pScopeSet, pLoadReadyModuleDefinition->getCreateFunction());
//And now that we've executed, switch back to the prior behavior
Con::setVariable("$Con::redefineBehavior", redefineBehaviorPrev.c_str());
}
else
{
//Nothing to do, just run the create function
Con::executef(pScopeSet, pLoadReadyModuleDefinition->getCreateFunction());
}
} }
} }
else else

View file

@ -739,6 +739,7 @@ Box3F NavMesh::getTileBox(U32 id)
void NavMesh::updateTiles(bool dirty) void NavMesh::updateTiles(bool dirty)
{ {
PROFILE_SCOPE(NavMesh_updateTiles);
if(!isProperlyAdded()) if(!isProperlyAdded())
return; return;
@ -793,6 +794,7 @@ void NavMesh::processTick(const Move *move)
void NavMesh::buildNextTile() void NavMesh::buildNextTile()
{ {
PROFILE_SCOPE(NavMesh_buildNextTile);
if(!mDirtyTiles.empty()) if(!mDirtyTiles.empty())
{ {
// Pop a single dirty tile and process it. // Pop a single dirty tile and process it.
@ -1099,6 +1101,7 @@ unsigned char *NavMesh::buildTileData(const Tile &tile, TileData &data, U32 &dat
/// this NavMesh object. /// this NavMesh object.
void NavMesh::buildTiles(const Box3F &box) void NavMesh::buildTiles(const Box3F &box)
{ {
PROFILE_SCOPE(NavMesh_buildTiles);
// Make sure we've already built or loaded. // Make sure we've already built or loaded.
if(!nm) if(!nm)
return; return;
@ -1124,6 +1127,7 @@ DefineEngineMethod(NavMesh, buildTiles, void, (Box3F box),,
void NavMesh::buildTile(const U32 &tile) void NavMesh::buildTile(const U32 &tile)
{ {
PROFILE_SCOPE(NavMesh_buildTile);
if(tile < mTiles.size()) if(tile < mTiles.size())
{ {
mDirtyTiles.push_back_unique(tile); mDirtyTiles.push_back_unique(tile);

View file

@ -369,6 +369,7 @@ void NavPath::resize()
bool NavPath::plan() bool NavPath::plan()
{ {
PROFILE_SCOPE(NavPath_plan);
// Initialise filter. // Initialise filter.
mFilter.setIncludeFlags(mLinkTypes.getFlags()); mFilter.setIncludeFlags(mLinkTypes.getFlags());
@ -430,15 +431,15 @@ bool NavPath::visitNext()
if(dtStatusFailed(mQuery->findNearestPoly(from, extents, &mFilter, &startRef, NULL)) || !startRef) if(dtStatusFailed(mQuery->findNearestPoly(from, extents, &mFilter, &startRef, NULL)) || !startRef)
{ {
Con::errorf("No NavMesh polygon near visit point (%g, %g, %g) of NavPath %s", //Con::errorf("No NavMesh polygon near visit point (%g, %g, %g) of NavPath %s",
start.x, start.y, start.z, getIdString()); //start.x, start.y, start.z, getIdString());
return false; return false;
} }
if(dtStatusFailed(mQuery->findNearestPoly(to, extents, &mFilter, &endRef, NULL)) || !endRef) if(dtStatusFailed(mQuery->findNearestPoly(to, extents, &mFilter, &endRef, NULL)) || !endRef)
{ {
Con::errorf("No NavMesh polygon near visit point (%g, %g, %g) of NavPath %s", //Con::errorf("No NavMesh polygon near visit point (%g, %g, %g) of NavPath %s",
end.x, end.y, end.z, getIdString()); //end.x, end.y, end.z, getIdString());
return false; return false;
} }
@ -452,6 +453,7 @@ bool NavPath::visitNext()
bool NavPath::update() bool NavPath::update()
{ {
PROFILE_SCOPE(NavPath_update);
if(dtStatusInProgress(mStatus)) if(dtStatusInProgress(mStatus))
mStatus = mQuery->updateSlicedFindPath(mMaxIterations, NULL); mStatus = mQuery->updateSlicedFindPath(mMaxIterations, NULL);
if(dtStatusSucceed(mStatus)) if(dtStatusSucceed(mStatus))
@ -527,6 +529,7 @@ bool NavPath::finalise()
void NavPath::processTick(const Move *move) void NavPath::processTick(const Move *move)
{ {
PROFILE_SCOPE(NavPath_processTick);
if(!mMesh) if(!mMesh)
if(Sim::findObject(mMeshName.c_str(), mMesh)) if(Sim::findObject(mMeshName.c_str(), mMesh))
plan(); plan();

View file

@ -492,10 +492,10 @@ template<class T> T ReservedSocketList<T>::resolve(NetSocket socketToResolve)
return entry.used ? entry.value : -1; return entry.used ? entry.value : -1;
} }
static ConnectionNotifyEvent* smConnectionNotify = NULL; ConnectionNotifyEvent* Net::smConnectionNotify = NULL;
static ConnectionAcceptedEvent* smConnectionAccept = NULL; ConnectionAcceptedEvent* Net::smConnectionAccept = NULL;
static ConnectionReceiveEvent* smConnectionReceive = NULL; ConnectionReceiveEvent* Net::smConnectionReceive = NULL;
static PacketReceiveEvent* smPacketReceive = NULL; PacketReceiveEvent* Net::smPacketReceive = NULL;
ConnectionNotifyEvent& Net::getConnectionNotifyEvent() ConnectionNotifyEvent& Net::getConnectionNotifyEvent()
{ {
@ -809,6 +809,7 @@ NetSocket Net::openConnectTo(const char *addressString)
error = Net::WrongProtocolType; error = Net::WrongProtocolType;
} }
// Open socket
if (error == NoError || error == NeedHostLookup) if (error == NoError || error == NeedHostLookup)
{ {
handleFd = openSocket(); handleFd = openSocket();

View file

@ -215,6 +215,12 @@ struct Net
static bool smIpv4Enabled; static bool smIpv4Enabled;
static bool smIpv6Enabled; static bool smIpv6Enabled;
static ConnectionNotifyEvent* smConnectionNotify;
static ConnectionAcceptedEvent* smConnectionAccept;
static ConnectionReceiveEvent* smConnectionReceive;
static PacketReceiveEvent* smPacketReceive;
static bool init(); static bool init();
static void shutdown(); static void shutdown();

View file

@ -54,9 +54,9 @@ Profiler *gProfiler = NULL;
Vector<StringTableEntry> gProfilerNodeStack; Vector<StringTableEntry> gProfilerNodeStack;
#define TORQUE_PROFILE_AT_ENGINE_START true #define TORQUE_PROFILE_AT_ENGINE_START true
#define PROFILER_DEBUG_PUSH_NODE( nodename ) \ #define PROFILER_DEBUG_PUSH_NODE( nodename ) \
gProfilerNodeStack.push_back( nodename ); gProfilerNodeStack.push_back( nodename );
#define PROFILER_DEBUG_POP_NODE() \ #define PROFILER_DEBUG_POP_NODE() \
gProfilerNodeStack.pop_back(); gProfilerNodeStack.pop_back();
#else #else
#define TORQUE_PROFILE_AT_ENGINE_START false #define TORQUE_PROFILE_AT_ENGINE_START false
#define PROFILER_DEBUG_PUSH_NODE( nodename ) ; #define PROFILER_DEBUG_PUSH_NODE( nodename ) ;

View file

@ -76,8 +76,8 @@ TEST(Net, TCPRequest)
handler.mDataReceived = 0; handler.mDataReceived = 0;
// Hook into the signals. // Hook into the signals.
Net::smConnectionNotify .notify(&handler, &TcpHandle::notify); Net::smConnectionNotify ->notify(&handler, &TcpHandle::notify);
Net::smConnectionReceive.notify(&handler, &TcpHandle::receive); Net::smConnectionReceive->notify(&handler, &TcpHandle::receive);
// Open a TCP connection to garagegames.com // Open a TCP connection to garagegames.com
handler.mSocket = Net::openConnectTo("72.246.107.193:80"); handler.mSocket = Net::openConnectTo("72.246.107.193:80");
@ -85,8 +85,8 @@ TEST(Net, TCPRequest)
while(Process::processEvents() && (Platform::getRealMilliseconds() < limit) ) {} while(Process::processEvents() && (Platform::getRealMilliseconds() < limit) ) {}
// Unhook from the signals. // Unhook from the signals.
Net::smConnectionNotify .remove(&handler, &TcpHandle::notify); Net::smConnectionNotify ->remove(&handler, &TcpHandle::notify);
Net::smConnectionReceive.remove(&handler, &TcpHandle::receive); Net::smConnectionReceive->remove(&handler, &TcpHandle::receive);
EXPECT_GT(handler.mDataReceived, 0) EXPECT_GT(handler.mDataReceived, 0)
<< "Didn't get any data back!"; << "Didn't get any data back!";
@ -139,8 +139,8 @@ struct JournalHandle
mDataReceived = 0; mDataReceived = 0;
// Hook into the signals. // Hook into the signals.
Net::smConnectionNotify .notify(this, &JournalHandle::notify); Net::smConnectionNotify ->notify(this, &JournalHandle::notify);
Net::smConnectionReceive.notify(this, &JournalHandle::receive); Net::smConnectionReceive->notify(this, &JournalHandle::receive);
// Open a TCP connection to garagegames.com // Open a TCP connection to garagegames.com
mSocket = Net::openConnectTo("72.246.107.193:80"); mSocket = Net::openConnectTo("72.246.107.193:80");
@ -149,8 +149,8 @@ struct JournalHandle
while(Process::processEvents()) {} while(Process::processEvents()) {}
// Unhook from the signals. // Unhook from the signals.
Net::smConnectionNotify .remove(this, &JournalHandle::notify); Net::smConnectionNotify ->remove(this, &JournalHandle::notify);
Net::smConnectionReceive.remove(this, &JournalHandle::receive); Net::smConnectionReceive->remove(this, &JournalHandle::receive);
EXPECT_GT(mDataReceived, 0) EXPECT_GT(mDataReceived, 0)
<< "Didn't get any data back!"; << "Didn't get any data back!";

View file

@ -411,10 +411,6 @@ bool PostEffect::onAdd()
texFilename[0] == '#' ) texFilename[0] == '#' )
continue; continue;
// If '/', then path is specified, open normally
if ( texFilename[0] != '/' )
texFilename = scriptPath.getFullPath() + '/' + texFilename;
// Try to load the texture. // Try to load the texture.
bool success = mTextures[i].set( texFilename, &PostFxTextureProfile, avar( "%s() - (line %d)", __FUNCTION__, __LINE__ ) ); bool success = mTextures[i].set( texFilename, &PostFxTextureProfile, avar( "%s() - (line %d)", __FUNCTION__, __LINE__ ) );
if (!success) if (!success)

View file

@ -236,7 +236,7 @@ void BumpFeatGLSL::setTexData( Material::StageData &stageDat,
ParallaxFeatGLSL::ParallaxFeatGLSL() ParallaxFeatGLSL::ParallaxFeatGLSL()
: mIncludeDep( "shaders/common/gl/torque.glsl" ) : mIncludeDep(String(Con::getVariable("$Core::CommonShaderPath")) + String("/gl/torque.glsl" ))
{ {
addDependency( &mIncludeDep ); addDependency( &mIncludeDep );
} }

View file

@ -30,7 +30,7 @@
PixelSpecularGLSL::PixelSpecularGLSL() PixelSpecularGLSL::PixelSpecularGLSL()
: mDep( "shaders/common/gl/lighting.glsl" ) : mDep(String(Con::getVariable("$Core::CommonShaderPath")) + String("/gl/lighting.glsl" ))
{ {
addDependency( &mDep ); addDependency( &mDep );
} }

View file

@ -830,7 +830,7 @@ Var* ShaderFeatureGLSL::addOutDetailTexCoord( Vector<ShaderComponent*> &compon
//**************************************************************************** //****************************************************************************
DiffuseMapFeatGLSL::DiffuseMapFeatGLSL() DiffuseMapFeatGLSL::DiffuseMapFeatGLSL()
: mTorqueDep("shaders/common/gl/torque.glsl") : mTorqueDep(String(Con::getVariable("$Core::CommonShaderPath")) + String("/gl/torque.glsl"))
{ {
addDependency(&mTorqueDep); addDependency(&mTorqueDep);
} }
@ -1975,7 +1975,7 @@ void ReflectCubeFeatGLSL::setTexData( Material::StageData &stageDat,
//**************************************************************************** //****************************************************************************
RTLightingFeatGLSL::RTLightingFeatGLSL() RTLightingFeatGLSL::RTLightingFeatGLSL()
: mDep( "shaders/common/gl/lighting.glsl" ) : mDep(String(Con::getVariable("$Core::CommonShaderPath")) + String("/gl/lighting.glsl" ))
{ {
addDependency( &mDep ); addDependency( &mDep );
} }
@ -2190,7 +2190,7 @@ ShaderFeature::Resources RTLightingFeatGLSL::getResources( const MaterialFeature
//**************************************************************************** //****************************************************************************
FogFeatGLSL::FogFeatGLSL() FogFeatGLSL::FogFeatGLSL()
: mFogDep( "shaders/common/gl/torque.glsl" ) : mFogDep(String(Con::getVariable("$Core::CommonShaderPath")) + String("/gl/torque.glsl" ))
{ {
addDependency( &mFogDep ); addDependency( &mFogDep );
} }
@ -2321,7 +2321,7 @@ ShaderFeature::Resources FogFeatGLSL::getResources( const MaterialFeatureData &f
//**************************************************************************** //****************************************************************************
VisibilityFeatGLSL::VisibilityFeatGLSL() VisibilityFeatGLSL::VisibilityFeatGLSL()
: mTorqueDep( "shaders/common/gl/torque.glsl" ) : mTorqueDep(String(Con::getVariable("$Core::CommonShaderPath")) + String("/gl/torque.glsl" ))
{ {
addDependency( &mTorqueDep ); addDependency( &mTorqueDep );
} }
@ -2487,7 +2487,7 @@ void RenderTargetZeroGLSL::processPix( Vector<ShaderComponent*> &componentList,
//**************************************************************************** //****************************************************************************
HDROutGLSL::HDROutGLSL() HDROutGLSL::HDROutGLSL()
: mTorqueDep( "shaders/common/gl/torque.glsl" ) : mTorqueDep(String(Con::getVariable("$Core::CommonShaderPath")) + String("/gl/torque.glsl" ))
{ {
addDependency( &mTorqueDep ); addDependency( &mTorqueDep );
} }
@ -2508,7 +2508,7 @@ void HDROutGLSL::processPix( Vector<ShaderComponent*> &componentList,
#include "T3D/fx/groundCover.h" #include "T3D/fx/groundCover.h"
FoliageFeatureGLSL::FoliageFeatureGLSL() FoliageFeatureGLSL::FoliageFeatureGLSL()
: mDep( "shaders/common/gl/foliage.glsl" ) : mDep(String(Con::getVariable("$Core::CommonShaderPath")) + String("/gl/foliage.glsl" ))
{ {
addDependency( &mDep ); addDependency( &mDep );
} }
@ -2654,7 +2654,7 @@ void ParticleNormalFeatureGLSL::processVert(Vector<ShaderComponent*> &componentL
//**************************************************************************** //****************************************************************************
ImposterVertFeatureGLSL::ImposterVertFeatureGLSL() ImposterVertFeatureGLSL::ImposterVertFeatureGLSL()
: mDep( "shaders/common/gl/imposter.glsl" ) : mDep(String(Con::getVariable("$Core::CommonShaderPath")) + String("/gl/imposter.glsl" ))
{ {
addDependency( &mDep ); addDependency( &mDep );
} }

View file

@ -37,8 +37,8 @@ void ShaderGenPrinterGLSL::printShaderHeader( Stream& stream )
stream.write( dStrlen(header1), header1 ); stream.write( dStrlen(header1), header1 );
// Cheap HLSL compatibility. // Cheap HLSL compatibility.
const char* header3 = "#include \"shaders/common/gl/hlslCompat.glsl\"\r\n"; String header3 = String("#include \"") + String(Con::getVariable("$Core::CommonShaderPath")) + String("/gl/hlslCompat.glsl\"\r\n");
stream.write( dStrlen(header3), header3 ); stream.write(dStrlen(header3), header3.c_str());
const char* header4 = "\r\n"; const char* header4 = "\r\n";
stream.write( dStrlen(header4), header4 ); stream.write( dStrlen(header4), header4 );

View file

@ -268,7 +268,7 @@ void BumpFeatHLSL::setTexData( Material::StageData &stageDat,
ParallaxFeatHLSL::ParallaxFeatHLSL() ParallaxFeatHLSL::ParallaxFeatHLSL()
: mIncludeDep( "shaders/common/torque.hlsl" ) : mIncludeDep(String(Con::getVariable("$Core::CommonShaderPath")) + String("/torque.hlsl" ))
{ {
addDependency( &mIncludeDep ); addDependency( &mIncludeDep );
} }

View file

@ -30,7 +30,7 @@
PixelSpecularHLSL::PixelSpecularHLSL() PixelSpecularHLSL::PixelSpecularHLSL()
: mDep( "shaders/common/lighting.hlsl" ) : mDep(String(Con::getVariable("$Core::CommonShaderPath")) + String("/lighting.hlsl" ))
{ {
addDependency( &mDep ); addDependency( &mDep );
} }

View file

@ -853,7 +853,7 @@ Var* ShaderFeatureHLSL::addOutDetailTexCoord( Vector<ShaderComponent*> &compon
//**************************************************************************** //****************************************************************************
DiffuseMapFeatHLSL::DiffuseMapFeatHLSL() DiffuseMapFeatHLSL::DiffuseMapFeatHLSL()
: mTorqueDep("shaders/common/torque.hlsl") : mTorqueDep(String(Con::getVariable("$Core::CommonShaderPath")) + String("/torque.hlsl"))
{ {
addDependency(&mTorqueDep); addDependency(&mTorqueDep);
} }
@ -2168,7 +2168,7 @@ void ReflectCubeFeatHLSL::setTexData( Material::StageData &stageDat,
//**************************************************************************** //****************************************************************************
RTLightingFeatHLSL::RTLightingFeatHLSL() RTLightingFeatHLSL::RTLightingFeatHLSL()
: mDep( "shaders/common/lighting.hlsl" ) : mDep(String(Con::getVariable("$Core::CommonShaderPath")) + String("/lighting.hlsl" ))
{ {
addDependency( &mDep ); addDependency( &mDep );
} }
@ -2383,7 +2383,7 @@ ShaderFeature::Resources RTLightingFeatHLSL::getResources( const MaterialFeature
//**************************************************************************** //****************************************************************************
FogFeatHLSL::FogFeatHLSL() FogFeatHLSL::FogFeatHLSL()
: mFogDep( "shaders/common/torque.hlsl" ) : mFogDep(String(Con::getVariable("$Core::CommonShaderPath")) + String("/torque.hlsl" ))
{ {
addDependency( &mFogDep ); addDependency( &mFogDep );
} }
@ -2514,7 +2514,7 @@ ShaderFeature::Resources FogFeatHLSL::getResources( const MaterialFeatureData &f
//**************************************************************************** //****************************************************************************
VisibilityFeatHLSL::VisibilityFeatHLSL() VisibilityFeatHLSL::VisibilityFeatHLSL()
: mTorqueDep( "shaders/common/torque.hlsl" ) : mTorqueDep(String(Con::getVariable("$Core::CommonShaderPath")) + String("/torque.hlsl" ))
{ {
addDependency( &mTorqueDep ); addDependency( &mTorqueDep );
} }
@ -2681,7 +2681,7 @@ void RenderTargetZeroHLSL::processPix( Vector<ShaderComponent*> &componentList,
//**************************************************************************** //****************************************************************************
HDROutHLSL::HDROutHLSL() HDROutHLSL::HDROutHLSL()
: mTorqueDep( "shaders/common/torque.hlsl" ) : mTorqueDep(String(Con::getVariable("$Core::CommonShaderPath")) + String("/torque.hlsl" ))
{ {
addDependency( &mTorqueDep ); addDependency( &mTorqueDep );
} }
@ -2702,7 +2702,7 @@ void HDROutHLSL::processPix( Vector<ShaderComponent*> &componentList,
#include "T3D/fx/groundCover.h" #include "T3D/fx/groundCover.h"
FoliageFeatureHLSL::FoliageFeatureHLSL() FoliageFeatureHLSL::FoliageFeatureHLSL()
: mDep( "shaders/common/foliage.hlsl" ) : mDep(String(Con::getVariable("$Core::CommonShaderPath")) + String("/foliage.hlsl" ))
{ {
addDependency( &mDep ); addDependency( &mDep );
} }
@ -2848,7 +2848,7 @@ void ParticleNormalFeatureHLSL::processVert(Vector<ShaderComponent*> &componentL
//**************************************************************************** //****************************************************************************
ImposterVertFeatureHLSL::ImposterVertFeatureHLSL() ImposterVertFeatureHLSL::ImposterVertFeatureHLSL()
: mDep( "shaders/common/imposter.hlsl" ) : mDep(String(Con::getVariable("$Core::CommonShaderPath")) + String("/imposter.hlsl" ))
{ {
addDependency( &mDep ); addDependency( &mDep );
} }

View file

@ -70,7 +70,7 @@ MODULE_END;
TerrainFeatGLSL::TerrainFeatGLSL() TerrainFeatGLSL::TerrainFeatGLSL()
: mTorqueDep( "shaders/common/gl/torque.glsl" ) : mTorqueDep(String(Con::getVariable("$Core::CommonShaderPath")) + String("/gl/torque.glsl" ))
{ {
addDependency( &mTorqueDep ); addDependency( &mTorqueDep );
} }
@ -297,8 +297,8 @@ U32 TerrainBaseMapFeatGLSL::getOutputTargets( const MaterialFeatureData &fd ) co
} }
TerrainDetailMapFeatGLSL::TerrainDetailMapFeatGLSL() TerrainDetailMapFeatGLSL::TerrainDetailMapFeatGLSL()
: mTorqueDep( "shaders/common/gl/torque.glsl" ), : mTorqueDep(String(Con::getVariable("$Core::CommonShaderPath")) + String("/gl/torque.glsl" )),
mTerrainDep( "shaders/common/terrain/terrain.glsl" ) mTerrainDep(String(Con::getVariable("$Core::CommonShaderPath")) + String("/terrain/terrain.glsl" ))
{ {
addDependency( &mTorqueDep ); addDependency( &mTorqueDep );
@ -667,8 +667,8 @@ U32 TerrainDetailMapFeatGLSL::getOutputTargets( const MaterialFeatureData &fd )
TerrainMacroMapFeatGLSL::TerrainMacroMapFeatGLSL() TerrainMacroMapFeatGLSL::TerrainMacroMapFeatGLSL()
: mTorqueDep( "shaders/common/gl/torque.glsl" ), : mTorqueDep(String(Con::getVariable("$Core::CommonShaderPath")) + String("/gl/torque.glsl" )),
mTerrainDep( "shaders/common/terrain/terrain.glsl" ) mTerrainDep(String(Con::getVariable("$Core::CommonShaderPath")) + String("/terrain/terrain.glsl" ))
{ {
addDependency( &mTorqueDep ); addDependency( &mTorqueDep );

View file

@ -69,7 +69,7 @@ MODULE_END;
TerrainFeatHLSL::TerrainFeatHLSL() TerrainFeatHLSL::TerrainFeatHLSL()
: mTorqueDep( "shaders/common/torque.hlsl" ) : mTorqueDep(String(Con::getVariable("$Core::CommonShaderPath")) + String("/torque.hlsl" ))
{ {
addDependency( &mTorqueDep ); addDependency( &mTorqueDep );
} }
@ -315,8 +315,8 @@ U32 TerrainBaseMapFeatHLSL::getOutputTargets( const MaterialFeatureData &fd ) co
} }
TerrainDetailMapFeatHLSL::TerrainDetailMapFeatHLSL() TerrainDetailMapFeatHLSL::TerrainDetailMapFeatHLSL()
: mTorqueDep( "shaders/common/torque.hlsl" ), : mTorqueDep(String(Con::getVariable("$Core::CommonShaderPath")) + String("/torque.hlsl" )),
mTerrainDep( "shaders/common/terrain/terrain.hlsl" ) mTerrainDep(String(Con::getVariable("$Core::CommonShaderPath")) + String("/terrain/terrain.hlsl" ))
{ {
addDependency( &mTorqueDep ); addDependency( &mTorqueDep );
@ -692,8 +692,8 @@ U32 TerrainDetailMapFeatHLSL::getOutputTargets( const MaterialFeatureData &fd )
TerrainMacroMapFeatHLSL::TerrainMacroMapFeatHLSL() TerrainMacroMapFeatHLSL::TerrainMacroMapFeatHLSL()
: mTorqueDep( "shaders/common/torque.hlsl" ), : mTorqueDep(String(Con::getVariable("$Core::CommonShaderPath")) + String("/torque.hlsl" )),
mTerrainDep( "shaders/common/terrain/terrain.hlsl" ) mTerrainDep(String(Con::getVariable("$Core::CommonShaderPath")) + String("/terrain/terrain.hlsl" ))
{ {
addDependency( &mTorqueDep ); addDependency( &mTorqueDep );

View file

@ -103,10 +103,26 @@ bool Platform::displaySplashWindow( String path )
bool Platform::closeSplashWindow() bool Platform::closeSplashWindow()
{ {
if (gSplashTexture != nullptr)
{
SDL_DestroyTexture(gSplashTexture); SDL_DestroyTexture(gSplashTexture);
gSplashTexture = nullptr;
}
if (gSplashImage != nullptr)
{
SDL_FreeSurface(gSplashImage); SDL_FreeSurface(gSplashImage);
gSplashImage = nullptr;
}
if (gSplashRenderer != nullptr)
{
SDL_DestroyRenderer(gSplashRenderer); SDL_DestroyRenderer(gSplashRenderer);
gSplashRenderer = nullptr;
}
if (gSplashWindow != nullptr)
{
SDL_DestroyWindow(gSplashWindow); SDL_DestroyWindow(gSplashWindow);
gSplashWindow = nullptr;
}
return true; return true;
} }

View file

@ -0,0 +1 @@
# Project-specific Cmake configurations go here

View file

@ -0,0 +1 @@
<exports/>

View file

@ -108,27 +108,7 @@ singleton SFXDescription( AudioMusic )
/// the defaults in the $pref::SFX:: globals. /// the defaults in the $pref::SFX:: globals.
function sfxStartup() function sfxStartup()
{ {
// The console builds should re-detect, by default, so that it plays nicely echo( "\nsfxStartup..." );
// along side a PC build in the same script directory.
if( $platform $= "xenon" )
{
if( $pref::SFX::provider $= "DirectSound" ||
$pref::SFX::provider $= "OpenAL" )
{
$pref::SFX::provider = "";
}
if( $pref::SFX::provider $= "" )
{
$pref::SFX::autoDetect = 1;
warn( "Xbox360 is auto-detecting available sound providers..." );
warn( " - You may wish to alter this functionality before release (core/scripts/client/audio.cs)" );
}
}
echo( "sfxStartup..." );
// If we have a provider set, try initialize a device now. // If we have a provider set, try initialize a device now.
@ -186,7 +166,8 @@ function sfxInit()
echo( " Provider: " @ $pref::SFX::provider ); echo( " Provider: " @ $pref::SFX::provider );
echo( " Device: " @ $pref::SFX::device ); echo( " Device: " @ $pref::SFX::device );
echo( " Hardware: " @ %useHardware ); echo( " Hardware: " @ %useHardware );
echo( " Buffers: " @ %maxBuffers ); echo( " Max Buffers: " @ %maxBuffers );
echo( " " );
if( isDefined( "$pref::SFX::distanceModel" ) ) if( isDefined( "$pref::SFX::distanceModel" ) )
sfxSetDistanceModel( $pref::SFX::distanceModel ); sfxSetDistanceModel( $pref::SFX::distanceModel );
@ -396,7 +377,7 @@ function sfxSetChannelVolume( %channel, %volume )
%obj.setVolume( %volume ); %obj.setVolume( %volume );
} }
singleton SimSet( SFXPausedSet ); /*singleton SimSet( SFXPausedSet );
/// Pauses the playback of active sound sources. /// Pauses the playback of active sound sources.
@ -452,4 +433,4 @@ function sfxResume( %pauseSet )
// Clear our pause set... the caller is left // Clear our pause set... the caller is left
// to clear his own if he passed one. // to clear his own if he passed one.
%pauseSet.clear(); %pauseSet.clear();
} }*/

View file

@ -20,24 +20,61 @@
// IN THE SOFTWARE. // IN THE SOFTWARE.
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------- function createCanvas(%windowTitle)
// initializeCanvas {
// Constructs and initializes the default canvas window. if ($isDedicated)
//--------------------------------------------------------------------------------------------- {
$canvasCreated = false; GFXInit::createNullDevice();
return true;
}
// Create the Canvas
$GameCanvas = new GuiCanvas(Canvas)
{
displayWindow = $platform !$= "windows";
};
// Set the window title
if (isObject(Canvas))
{
Canvas.setWindowTitle(%windowTitle @ " - " @ $pref::Video::displayDevice);
configureCanvas();
}
else
{
error("Canvas creation failed. Shutting down.");
quit();
}
}
// Constants for referencing video resolution preferences
$WORD::RES_X = 0;
$WORD::RES_Y = 1;
$WORD::FULLSCREEN = 2;
$WORD::BITDEPTH = 3;
$WORD::REFRESH = 4;
$WORD::AA = 5;
function configureCanvas() function configureCanvas()
{ {
// Setup a good default if we don't have one already. // Setup a good default if we don't have one already.
if ($pref::Video::mode $= "") if ($pref::Video::Resolution $= "")
$pref::Video::mode = "800 600 false 32 60 0"; $pref::Video::Resolution = "800 600";
if ($pref::Video::FullScreen $= "")
$pref::Video::FullScreen = false;
if ($pref::Video::BitDepth $= "")
$pref::Video::BitDepth = "32";
if ($pref::Video::RefreshRate $= "")
$pref::Video::RefreshRate = "60";
if ($pref::Video::AA $= "")
$pref::Video::AA = "4";
%resX = getWord($pref::Video::mode, $WORD::RES_X); %resX = $pref::Video::Resolution.x;
%resY = getWord($pref::Video::mode, $WORD::RES_Y); %resY = $pref::Video::Resolution.y;
%fs = getWord($pref::Video::mode, $WORD::FULLSCREEN); %fs = $pref::Video::FullScreen;
%bpp = getWord($pref::Video::mode, $WORD::BITDEPTH); %bpp = $pref::Video::BitDepth;
%rate = getWord($pref::Video::mode, $WORD::REFRESH); %rate = $pref::Video::RefreshRate;
%fsaa = getWord($pref::Video::mode, $WORD::AA); %aa = $pref::Video::AA;
if($cliFullscreen !$= "") { if($cliFullscreen !$= "") {
%fs = $cliFullscreen; %fs = $cliFullscreen;
@ -45,7 +82,7 @@ function configureCanvas()
} }
echo("--------------"); echo("--------------");
echo("Attempting to set resolution to \"" @ %resX SPC %resY SPC %fs SPC %bpp SPC %rate SPC %fsaa @ "\""); echo("Attempting to set resolution to \"" @ %resX SPC %resY SPC %fs SPC %bpp SPC %rate SPC %aa @ "\"");
%deskRes = getDesktopResolution(); %deskRes = getDesktopResolution();
%deskResX = getWord(%deskRes, $WORD::RES_X); %deskResX = getWord(%deskRes, $WORD::RES_X);
@ -92,7 +129,11 @@ function configureCanvas()
} }
} }
$pref::Video::mode = %resX SPC %resY SPC %fs SPC %bpp SPC %rate SPC %fsaa; $pref::Video::Resolution = %resX SPC %resY;
$pref::Video::FullScreen = %fs;
$pref::Video::BitDepth = %bpp;
$pref::Video::RefreshRate = %rate;
$pref::Video::AA = %aa;
if (%fs == 1 || %fs $= "true") if (%fs == 1 || %fs $= "true")
%fsLabel = "Yes"; %fsLabel = "Yes";
@ -104,90 +145,18 @@ function configureCanvas()
"--Full Screen : " @ %fsLabel NL "--Full Screen : " @ %fsLabel NL
"--Bits Per Pixel : " @ %bpp NL "--Bits Per Pixel : " @ %bpp NL
"--Refresh Rate : " @ %rate NL "--Refresh Rate : " @ %rate NL
"--FSAA Level : " @ %fsaa NL "--AA TypeXLevel : " @ %aa NL
"--------------"); "--------------");
// Actually set the new video mode // Actually set the new video mode
Canvas.setVideoMode(%resX, %resY, %fs, %bpp, %rate, %fsaa); Canvas.setVideoMode(%resX, %resY, %fs, %bpp, %rate, %aa);
// FXAA piggybacks on the FSAA setting in $pref::Video::mode. commandToServer('setClientAspectRatio', %resX, %resY);
// AA piggybacks on the AA setting in $pref::Video::mode.
// We need to parse the setting between AA modes, and then it's level
// It's formatted as AATypexAALevel
// So, FXAAx4 or MLAAx2
if ( isObject( FXAA_PostEffect ) ) if ( isObject( FXAA_PostEffect ) )
FXAA_PostEffect.isEnabled = ( %fsaa > 0 ) ? true : false; FXAA_PostEffect.isEnabled = ( %aa > 0 ) ? true : false;
//if ( $pref::Video::autoDetect )
// GraphicsQualityAutodetect();
}
function initializeCanvas()
{
// Don't duplicate the canvas.
if($canvasCreated)
{
error("Cannot instantiate more than one canvas!");
return;
}
if (!createCanvas())
{
error("Canvas creation failed. Shutting down.");
quit();
}
$canvasCreated = true;
}
//---------------------------------------------------------------------------------------------
// resetCanvas
// Forces the canvas to redraw itself.
//---------------------------------------------------------------------------------------------
function resetCanvas()
{
if (isObject(Canvas))
Canvas.repaint();
}
//---------------------------------------------------------------------------------------------
// Callbacks for window events.
//---------------------------------------------------------------------------------------------
function GuiCanvas::onLoseFocus(%this)
{
}
//---------------------------------------------------------------------------------------------
// Full screen handling
//---------------------------------------------------------------------------------------------
function GuiCanvas::attemptFullscreenToggle(%this)
{
// If the Editor is running then we cannot enter full screen mode
if ( EditorIsActive() && !%this.isFullscreen() )
{
MessageBoxOK("Windowed Mode Required", "Please exit the Mission Editor to switch to full screen.");
return;
}
// If the GUI Editor is running then we cannot enter full screen mode
if ( GuiEditorIsActive() && !%this.isFullscreen() )
{
MessageBoxOK("Windowed Mode Required", "Please exit the GUI Editor to switch to full screen.");
return;
}
%this.toggleFullscreen();
}
//---------------------------------------------------------------------------------------------
// Editor Checking
// Needs to be outside of the tools directory so these work in non-tools builds
//---------------------------------------------------------------------------------------------
function EditorIsActive()
{
return ( isObject(EditorGui) && Canvas.getContent() == EditorGui.getId() );
}
function GuiEditorIsActive()
{
return ( isObject(GuiEditorGui) && Canvas.getContent() == GuiEditorGui.getId() );
} }

View file

@ -0,0 +1,51 @@
new GuiControl(ConsoleDlg) {
profile = "GuiDefaultProfile";
horizSizing = "right";
vertSizing = "bottom";
position = "0 0";
extent = "640 480";
minExtent = "8 8";
visible = "1";
helpTag = "0";
new GuiConsoleEditCtrl(ConsoleEntry) {
profile = "ConsoleTextEditProfile";
horizSizing = "width";
vertSizing = "top";
position = "0 462";
extent = "640 18";
minExtent = "8 8";
visible = "1";
altCommand = "ConsoleEntry::eval();";
helpTag = "0";
maxLength = "255";
historySize = "40";
password = "0";
tabComplete = "0";
sinkAllKeyEvents = "1";
useSiblingScroller = "1";
};
new GuiScrollCtrl() {
internalName = "Scroll";
profile = "ConsoleScrollProfile";
horizSizing = "width";
vertSizing = "height";
position = "0 0";
extent = "640 462";
minExtent = "8 8";
visible = "1";
helpTag = "0";
willFirstRespond = "1";
hScrollBar = "alwaysOn";
vScrollBar = "alwaysOn";
lockHorizScroll = "false";
lockVertScroll = "false";
constantThumbHeight = "0";
childMargin = "0 0";
new GuiConsole( ConsoleMessageLogView ) {
profile = "GuiConsoleProfile";
position = "0 0";
};
};
};

View file

@ -0,0 +1,108 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
exec("./profiles.cs");
exec("./console.gui");
GlobalActionMap.bind("keyboard", "tilde", "toggleConsole");
function ConsoleEntry::eval()
{
%text = trim(ConsoleEntry.getValue());
if(%text $= "")
return;
// If it's missing a trailing () and it's not a variable,
// append the parentheses.
if(strpos(%text, "(") == -1 && !isDefined(%text)) {
if(strpos(%text, "=") == -1 && strpos(%text, " ") == -1) {
if(strpos(%text, "{") == -1 && strpos(%text, "}") == -1) {
%text = %text @ "()";
}
}
}
// Append a semicolon if need be.
%pos = strlen(%text) - 1;
if(strpos(%text, ";", %pos) == -1 && strpos(%text, "}") == -1) {
%text = %text @ ";";
}
// Turn off warnings for assigning from void
// and evaluate the snippet.
if(!isDefined("$Con::warnVoidAssignment"))
%oldWarnVoidAssignment = true;
else
%oldWarnVoidAssignment = $Con::warnVoidAssignment;
$Con::warnVoidAssignment = false;
echo("==>" @ %text);
if( !startsWith(%text, "function ")
&& !startsWith(%text, "datablock ")
&& !startsWith(%text, "foreach(")
&& !startsWith(%text, "foreach$(")
&& !startsWith(%text, "if(")
&& !startsWith(%text, "while(")
&& !startsWith(%text, "for(")
&& !startsWith(%text, "switch(")
&& !startsWith(%text, "switch$("))
eval("%result = " @ %text);
else
eval(%text);
$Con::warnVoidAssignment = %oldWarnVoidAssignment;
ConsoleEntry.setValue("");
// Echo result.
if(%result !$= "")
echo(%result);
}
function ToggleConsole(%make)
{
if (%make) {
if (ConsoleDlg.isAwake()) {
// Deactivate the console.
Canvas.popDialog(ConsoleDlg);
} else {
Canvas.pushDialog(ConsoleDlg, 99);
}
}
}
function ConsoleDlg::hideWindow(%this)
{
%this-->Scroll.setVisible(false);
}
function ConsoleDlg::showWindow(%this)
{
%this-->Scroll.setVisible(true);
}
function ConsoleDlg::setAlpha( %this, %alpha)
{
if (%alpha $= "")
ConsoleScrollProfile.fillColor = $ConsoleDefaultFillColor;
else
ConsoleScrollProfile.fillColor = getWords($ConsoleDefaultFillColor, 0, 2) SPC %alpha * 255.0;
}

View file

@ -0,0 +1,70 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
if(!isObject(GuiConsoleProfile))
new GuiControlProfile(GuiConsoleProfile)
{
fontType = ($platform $= "macos") ? "Monaco" : "Lucida Console";
fontSize = ($platform $= "macos") ? 13 : 12;
fontColor = "255 255 255";
fontColorHL = "0 255 255";
fontColorNA = "255 0 0";
fontColors[6] = "100 100 100";
fontColors[7] = "100 100 0";
fontColors[8] = "0 0 100";
fontColors[9] = "0 100 0";
category = "Core";
};
if(!isObject(GuiConsoleTextProfile))
new GuiControlProfile(GuiConsoleTextProfile)
{
fontColor = "0 0 0";
autoSizeWidth = true;
autoSizeHeight = true;
textOffset = "2 2";
opaque = true;
fillColor = "255 255 255";
border = true;
borderThickness = 1;
borderColor = "0 0 0";
category = "Core";
};
if(!isObject(ConsoleScrollProfile))
new GuiControlProfile(ConsoleScrollProfile : GuiScrollProfile)
{
opaque = true;
fillColor = "0 0 0 175";
border = 1;
//borderThickness = 0;
borderColor = "0 0 0";
category = "Core";
};
if(!isObject(ConsoleTextEditProfile))
new GuiControlProfile(ConsoleTextEditProfile : GuiTextEditProfile)
{
fillColor = "242 241 240 255";
fillColorHL = "255 255 255";
category = "Core";
};

View file

@ -62,12 +62,11 @@ function GuiCanvas::checkCursor(%this)
if ((%control.noCursor $= "") || !%control.noCursor) if ((%control.noCursor $= "") || !%control.noCursor)
{ {
showCursor(); showCursor();
return true; return;
} }
} }
// If we get here, every control requested a hidden cursor, so we oblige. // If we get here, every control requested a hidden cursor, so we oblige.
hideCursor(); hideCursor();
return false;
} }
//--------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -26,11 +26,11 @@
singleton ShaderData( CloudLayerShader ) singleton ShaderData( CloudLayerShader )
{ {
DXVertexShaderFile = "shaders/common/cloudLayerV.hlsl"; DXVertexShaderFile = $Core::CommonShaderPath @ "/cloudLayerV.hlsl";
DXPixelShaderFile = "shaders/common/cloudLayerP.hlsl"; DXPixelShaderFile = $Core::CommonShaderPath @ "/cloudLayerP.hlsl";
OGLVertexShaderFile = "shaders/common/gl/cloudLayerV.glsl"; OGLVertexShaderFile = $Core::CommonShaderPath @ "/gl/cloudLayerV.glsl";
OGLPixelShaderFile = "shaders/common/gl/cloudLayerP.glsl"; OGLPixelShaderFile = $Core::CommonShaderPath @ "/gl/cloudLayerP.glsl";
samplerNames[0] = "$normalHeightMap"; samplerNames[0] = "$normalHeightMap";
@ -43,11 +43,11 @@ singleton ShaderData( CloudLayerShader )
singleton ShaderData( BasicCloudsShader ) singleton ShaderData( BasicCloudsShader )
{ {
DXVertexShaderFile = "shaders/common/basicCloudsV.hlsl"; DXVertexShaderFile = $Core::CommonShaderPath @ "/basicCloudsV.hlsl";
DXPixelShaderFile = "shaders/common/basicCloudsP.hlsl"; DXPixelShaderFile = $Core::CommonShaderPath @ "/basicCloudsP.hlsl";
OGLVertexShaderFile = "shaders/common/gl/basicCloudsV.glsl"; OGLVertexShaderFile = $Core::CommonShaderPath @ "/gl/basicCloudsV.glsl";
OGLPixelShaderFile = "shaders/common/gl/basicCloudsP.glsl"; OGLPixelShaderFile = $Core::CommonShaderPath @ "/gl/basicCloudsP.glsl";
samplerNames[0] = "$diffuseMap"; samplerNames[0] = "$diffuseMap";

View file

@ -22,13 +22,11 @@
new GFXStateBlockData( ScatterSkySBData ) new GFXStateBlockData( ScatterSkySBData )
{ {
//cullDefined = true;
cullMode = "GFXCullNone"; cullMode = "GFXCullNone";
zDefined = true; zDefined = true;
zEnable = true; zEnable = true;
zWriteEnable = false; zWriteEnable = false;
//zFunc = "GFXCmpLessEqual";
samplersDefined = true; samplersDefined = true;
samplerStates[0] = SamplerClampLinear; samplerStates[0] = SamplerClampLinear;
@ -38,11 +36,11 @@ new GFXStateBlockData( ScatterSkySBData )
singleton ShaderData( ScatterSkyShaderData ) singleton ShaderData( ScatterSkyShaderData )
{ {
DXVertexShaderFile = "shaders/common/scatterSkyV.hlsl"; DXVertexShaderFile = $Core::CommonShaderPath @ "/scatterSkyV.hlsl";
DXPixelShaderFile = "shaders/common/scatterSkyP.hlsl"; DXPixelShaderFile = $Core::CommonShaderPath @ "/scatterSkyP.hlsl";
OGLVertexShaderFile = "shaders/common/gl/scatterSkyV.glsl"; OGLVertexShaderFile = $Core::CommonShaderPath @ "/gl/scatterSkyV.glsl";
OGLPixelShaderFile = "shaders/common/gl/scatterSkyP.glsl"; OGLPixelShaderFile = $Core::CommonShaderPath @ "/gl/scatterSkyP.glsl";
samplerNames[0] = "$nightSky"; samplerNames[0] = "$nightSky";

View file

@ -27,11 +27,11 @@
singleton ShaderData( ParticlesShaderData ) singleton ShaderData( ParticlesShaderData )
{ {
DXVertexShaderFile = "shaders/common/particlesV.hlsl"; DXVertexShaderFile = $Core::CommonShaderPath @ "/particlesV.hlsl";
DXPixelShaderFile = "shaders/common/particlesP.hlsl"; DXPixelShaderFile = $Core::CommonShaderPath @ "/particlesP.hlsl";
OGLVertexShaderFile = "shaders/common/gl/particlesV.glsl"; OGLVertexShaderFile = $Core::CommonShaderPath @ "/gl/particlesV.glsl";
OGLPixelShaderFile = "shaders/common/gl/particlesP.glsl"; OGLPixelShaderFile = $Core::CommonShaderPath @ "/gl/particlesP.glsl";
samplerNames[0] = "$diffuseMap"; samplerNames[0] = "$diffuseMap";
samplerNames[1] = "$prepassTex"; samplerNames[1] = "$prepassTex";
@ -42,11 +42,11 @@ singleton ShaderData( ParticlesShaderData )
singleton ShaderData( OffscreenParticleCompositeShaderData ) singleton ShaderData( OffscreenParticleCompositeShaderData )
{ {
DXVertexShaderFile = "shaders/common/particleCompositeV.hlsl"; DXVertexShaderFile = $Core::CommonShaderPath @ "/particleCompositeV.hlsl";
DXPixelShaderFile = "shaders/common/particleCompositeP.hlsl"; DXPixelShaderFile = $Core::CommonShaderPath @ "/particleCompositeP.hlsl";
OGLVertexShaderFile = "shaders/common/gl/particleCompositeV.glsl"; OGLVertexShaderFile = $Core::CommonShaderPath @ "/gl/particleCompositeV.glsl";
OGLPixelShaderFile = "shaders/common/gl/particleCompositeP.glsl"; OGLPixelShaderFile = $Core::CommonShaderPath @ "/gl/particleCompositeP.glsl";
samplerNames[0] = "$colorSource"; samplerNames[0] = "$colorSource";
samplerNames[1] = "$edgeSource"; samplerNames[1] = "$edgeSource";
@ -59,11 +59,11 @@ singleton ShaderData( OffscreenParticleCompositeShaderData )
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
new ShaderData( ReflectBump ) new ShaderData( ReflectBump )
{ {
DXVertexShaderFile = "shaders/common/planarReflectBumpV.hlsl"; DXVertexShaderFile = $Core::CommonShaderPath @ "/planarReflectBumpV.hlsl";
DXPixelShaderFile = "shaders/common/planarReflectBumpP.hlsl"; DXPixelShaderFile = $Core::CommonShaderPath @ "/planarReflectBumpP.hlsl";
OGLVertexShaderFile = "shaders/common/gl/planarReflectBumpV.glsl"; OGLVertexShaderFile = $Core::CommonShaderPath @ "/gl/planarReflectBumpV.glsl";
OGLPixelShaderFile = "shaders/common/gl/planarReflectBumpP.glsl"; OGLPixelShaderFile = $Core::CommonShaderPath @ "/gl/planarReflectBumpP.glsl";
samplerNames[0] = "$diffuseMap"; samplerNames[0] = "$diffuseMap";
samplerNames[1] = "$refractMap"; samplerNames[1] = "$refractMap";
@ -74,11 +74,11 @@ new ShaderData( ReflectBump )
new ShaderData( Reflect ) new ShaderData( Reflect )
{ {
DXVertexShaderFile = "shaders/common/planarReflectV.hlsl"; DXVertexShaderFile = $Core::CommonShaderPath @ "/planarReflectV.hlsl";
DXPixelShaderFile = "shaders/common/planarReflectP.hlsl"; DXPixelShaderFile = $Core::CommonShaderPath @ "/planarReflectP.hlsl";
OGLVertexShaderFile = "shaders/common/gl/planarReflectV.glsl"; OGLVertexShaderFile = $Core::CommonShaderPath @ "/gl/planarReflectV.glsl";
OGLPixelShaderFile = "shaders/common/gl/planarReflectP.glsl"; OGLPixelShaderFile = $Core::CommonShaderPath @ "/gl/planarReflectP.glsl";
samplerNames[0] = "$diffuseMap"; samplerNames[0] = "$diffuseMap";
samplerNames[1] = "$refractMap"; samplerNames[1] = "$refractMap";
@ -91,11 +91,11 @@ new ShaderData( Reflect )
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
new ShaderData( fxFoliageReplicatorShader ) new ShaderData( fxFoliageReplicatorShader )
{ {
DXVertexShaderFile = "shaders/common/fxFoliageReplicatorV.hlsl"; DXVertexShaderFile = $Core::CommonShaderPath @ "/fxFoliageReplicatorV.hlsl";
DXPixelShaderFile = "shaders/common/fxFoliageReplicatorP.hlsl"; DXPixelShaderFile = $Core::CommonShaderPath @ "/fxFoliageReplicatorP.hlsl";
OGLVertexShaderFile = "shaders/common/gl/fxFoliageReplicatorV.glsl"; OGLVertexShaderFile = $Core::CommonShaderPath @ "/gl/fxFoliageReplicatorV.glsl";
OGLPixelShaderFile = "shaders/common/gl/fxFoliageReplicatorP.glsl"; OGLPixelShaderFile = $Core::CommonShaderPath @ "/gl/fxFoliageReplicatorP.glsl";
samplerNames[0] = "$diffuseMap"; samplerNames[0] = "$diffuseMap";
samplerNames[1] = "$alphaMap"; samplerNames[1] = "$alphaMap";
@ -105,21 +105,21 @@ new ShaderData( fxFoliageReplicatorShader )
singleton ShaderData( VolumetricFogPrePassShader ) singleton ShaderData( VolumetricFogPrePassShader )
{ {
DXVertexShaderFile = "shaders/common/VolumetricFog/VFogPreV.hlsl"; DXVertexShaderFile = $Core::CommonShaderPath @ "/VolumetricFog/VFogPreV.hlsl";
DXPixelShaderFile = "shaders/common/VolumetricFog/VFogPreP.hlsl"; DXPixelShaderFile = $Core::CommonShaderPath @ "/VolumetricFog/VFogPreP.hlsl";
OGLVertexShaderFile = "shaders/common/VolumetricFog/gl/VFogPreV.glsl"; OGLVertexShaderFile = $Core::CommonShaderPath @ "/VolumetricFog/gl/VFogPreV.glsl";
OGLPixelShaderFile = "shaders/common/VolumetricFog/gl/VFogPreP.glsl"; OGLPixelShaderFile = $Core::CommonShaderPath @ "/VolumetricFog/gl/VFogPreP.glsl";
pixVersion = 3.0; pixVersion = 3.0;
}; };
singleton ShaderData( VolumetricFogShader ) singleton ShaderData( VolumetricFogShader )
{ {
DXVertexShaderFile = "shaders/common/VolumetricFog/VFogV.hlsl"; DXVertexShaderFile = $Core::CommonShaderPath @ "/VolumetricFog/VFogV.hlsl";
DXPixelShaderFile = "shaders/common/VolumetricFog/VFogP.hlsl"; DXPixelShaderFile = $Core::CommonShaderPath @ "/VolumetricFog/VFogP.hlsl";
OGLVertexShaderFile = "shaders/common/VolumetricFog/gl/VFogV.glsl"; OGLVertexShaderFile = $Core::CommonShaderPath @ "/VolumetricFog/gl/VFogV.glsl";
OGLPixelShaderFile = "shaders/common/VolumetricFog/gl/VFogP.glsl"; OGLPixelShaderFile = $Core::CommonShaderPath @ "/VolumetricFog/gl/VFogP.glsl";
samplerNames[0] = "$prepassTex"; samplerNames[0] = "$prepassTex";
samplerNames[1] = "$depthBuffer"; samplerNames[1] = "$depthBuffer";
@ -130,11 +130,23 @@ singleton ShaderData( VolumetricFogShader )
}; };
singleton ShaderData( VolumetricFogReflectionShader ) singleton ShaderData( VolumetricFogReflectionShader )
{ {
DXVertexShaderFile = "shaders/common/VolumetricFog/VFogPreV.hlsl"; DXVertexShaderFile = $Core::CommonShaderPath @ "/VolumetricFog/VFogPreV.hlsl";
DXPixelShaderFile = "shaders/common/VolumetricFog/VFogRefl.hlsl"; DXPixelShaderFile = $Core::CommonShaderPath @ "/VolumetricFog/VFogRefl.hlsl";
OGLVertexShaderFile = "shaders/common/VolumetricFog/gl/VFogPreV.glsl"; OGLVertexShaderFile = $Core::CommonShaderPath @ "/VolumetricFog/gl/VFogPreV.glsl";
OGLPixelShaderFile = "shaders/common/VolumetricFog/gl/VFogRefl.glsl"; OGLPixelShaderFile = $Core::CommonShaderPath @ "/VolumetricFog/gl/VFogRefl.glsl";
pixVersion = 3.0;
};
singleton ShaderData( CubemapSaveShader )
{
DXVertexShaderFile = "shaders/common/cubemapSaveV.hlsl";
DXPixelShaderFile = "shaders/common/cubemapSaveP.hlsl";
OGLVertexShaderFile = "shaders/common/gl/cubemapSaveV.glsl";
OGLPixelShaderFile = "shaders/common/gl/cubemapSaveP.glsl";
samplerNames[0] = "$cubemapTex";
pixVersion = 3.0; pixVersion = 3.0;
}; };

View file

@ -23,11 +23,11 @@
/// Used when generating the blended base texture. /// Used when generating the blended base texture.
singleton ShaderData( TerrainBlendShader ) singleton ShaderData( TerrainBlendShader )
{ {
DXVertexShaderFile = "shaders/common/terrain/blendV.hlsl"; DXVertexShaderFile = $Core::CommonShaderPath @ "/terrain/blendV.hlsl";
DXPixelShaderFile = "shaders/common/terrain/blendP.hlsl"; DXPixelShaderFile = $Core::CommonShaderPath @ "/terrain/blendP.hlsl";
OGLVertexShaderFile = "shaders/common/terrain/gl/blendV.glsl"; OGLVertexShaderFile = $Core::CommonShaderPath @ "/terrain/gl/blendV.glsl";
OGLPixelShaderFile = "shaders/common/terrain/gl/blendP.glsl"; OGLPixelShaderFile = $Core::CommonShaderPath @ "/terrain/gl/blendP.glsl";
samplerNames[0] = "layerTex"; samplerNames[0] = "layerTex";
samplerNames[1] = "textureMap"; samplerNames[1] = "textureMap";

View file

@ -28,11 +28,11 @@
singleton ShaderData( WaterShader ) singleton ShaderData( WaterShader )
{ {
DXVertexShaderFile = "shaders/common/water/waterV.hlsl"; DXVertexShaderFile = $Core::CommonShaderPath @ "/water/waterV.hlsl";
DXPixelShaderFile = "shaders/common/water/waterP.hlsl"; DXPixelShaderFile = $Core::CommonShaderPath @ "/water/waterP.hlsl";
OGLVertexShaderFile = "shaders/common/water/gl/waterV.glsl"; OGLVertexShaderFile = $Core::CommonShaderPath @ "/water/gl/waterV.glsl";
OGLPixelShaderFile = "shaders/common/water/gl/waterP.glsl"; OGLPixelShaderFile = $Core::CommonShaderPath @ "/water/gl/waterP.glsl";
samplerNames[0] = "$bumpMap"; // noise samplerNames[0] = "$bumpMap"; // noise
samplerNames[1] = "$prepassTex"; // #prepass samplerNames[1] = "$prepassTex"; // #prepass
@ -131,11 +131,11 @@ singleton CustomMaterial( UnderwaterMat )
singleton ShaderData( WaterBasicShader ) singleton ShaderData( WaterBasicShader )
{ {
DXVertexShaderFile = "shaders/common/water/waterBasicV.hlsl"; DXVertexShaderFile = $Core::CommonShaderPath @ "/water/waterBasicV.hlsl";
DXPixelShaderFile = "shaders/common/water/waterBasicP.hlsl"; DXPixelShaderFile = $Core::CommonShaderPath @ "/water/waterBasicP.hlsl";
OGLVertexShaderFile = "shaders/common/water/gl/waterBasicV.glsl"; OGLVertexShaderFile = $Core::CommonShaderPath @ "/water/gl/waterBasicV.glsl";
OGLPixelShaderFile = "shaders/common/water/gl/waterBasicP.glsl"; OGLPixelShaderFile = $Core::CommonShaderPath @ "/water/gl/waterBasicP.glsl";
samplerNames[0] = "$bumpMap"; samplerNames[0] = "$bumpMap";
samplerNames[2] = "$reflectMap"; samplerNames[2] = "$reflectMap";

View file

@ -0,0 +1,102 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
// DInput keyboard, mouse, and joystick prefs
// ----------------------------------------------------------------------------
$pref::Input::MouseEnabled = 1;
$pref::Input::LinkMouseSensitivity = 1;
$pref::Input::KeyboardEnabled = 1;
$pref::Input::KeyboardTurnSpeed = 0.1;
$pref::Input::JoystickEnabled = 0;
// ----------------------------------------------------------------------------
// Video Preferences
// ----------------------------------------------------------------------------
// Set directory paths for various data or default images.
$pref::Video::ProfilePath = "core/gfxprofile";
$pref::Video::missingTexturePath = "core/images/missingTexture.png";
$pref::Video::unavailableTexturePath = "core/images/unavailable.png";
$pref::Video::warningTexturePath = "core/images/warnMat.dds";
$pref::Video::disableVerticalSync = 1;
$pref::Video::mode = "800 600 false 32 60 4";
$pref::Video::defaultFenceCount = 0;
// This disables the hardware FSAA/MSAA so that we depend completely on the FXAA
// post effect which works on all cards and in deferred mode. Note that the new
// Intel Hybrid graphics on laptops will fail to initialize when hardware AA is
// enabled... so you've been warned.
$pref::Video::disableHardwareAA = true;
$pref::Video::disableNormalmapping = false;
$pref::Video::disablePixSpecular = false;
$pref::Video::disableCubemapping = false;
$pref::Video::disableParallaxMapping = false;
// The number of mipmap levels to drop on loaded textures to reduce video memory
// usage. It will skip any textures that have been defined as not allowing down
// scaling.
$pref::Video::textureReductionLevel = 0;
$pref::Video::defaultAnisotropy = 1;
//$pref::Video::Gamma = 1.0;
/// AutoDetect graphics quality levels the next startup.
$pref::Video::autoDetect = 1;
// ----------------------------------------------------------------------------
// Shader stuff
// ----------------------------------------------------------------------------
// This is the path used by ShaderGen to cache procedural shaders. If left
// blank ShaderGen will only cache shaders to memory and not to disk.
$shaderGen::cachePath = "data/shaderCache";
// Uncomment to disable ShaderGen, useful when debugging
//$ShaderGen::GenNewShaders = false;
// Uncomment to dump disassembly for any shader that is compiled to disk. These
// will appear as shadername_dis.txt in the same path as the shader file.
//$gfx::disassembleAllShaders = true;
// ----------------------------------------------------------------------------
// Lighting and shadowing
// ----------------------------------------------------------------------------
// Uncomment to enable AdvancedLighting on the Mac (T3D 2009 Beta 3)
//$pref::machax::enableAdvancedLighting = true;
$sceneLighting::cacheSize = 20000;
$sceneLighting::purgeMethod = "lastCreated";
$sceneLighting::cacheLighting = 1;
$pref::Shadows::textureScalar = 1.0;
$pref::Shadows::disable = false;
// Sets the shadow filtering mode.
// None - Disables filtering.
// SoftShadow - Does a simple soft shadow
// SoftShadowHighQuality
$pref::Shadows::filterMode = "SoftShadow";

Some files were not shown because too many files have changed in this diff Show more