diff --git a/.hgtags b/.hgtags new file mode 100644 index 0000000..07cc9f0 --- /dev/null +++ b/.hgtags @@ -0,0 +1 @@ +be35d62159788e03c335f8b7f3ddbde8030a3ccf Release 1.0.2 diff --git a/KREngine/kraken/forsyth.cpp b/KREngine/3rdparty/forsyth/forsyth.cpp similarity index 100% rename from KREngine/kraken/forsyth.cpp rename to KREngine/3rdparty/forsyth/forsyth.cpp diff --git a/KREngine/kraken/forsyth.h b/KREngine/3rdparty/forsyth/forsyth.h similarity index 100% rename from KREngine/kraken/forsyth.h rename to KREngine/3rdparty/forsyth/forsyth.h diff --git a/KREngine/3rdparty/pvrtexlib/include/PVRTArray.h b/KREngine/3rdparty/pvrtexlib/include/PVRTArray.h new file mode 100644 index 0000000..ad58f87 --- /dev/null +++ b/KREngine/3rdparty/pvrtexlib/include/PVRTArray.h @@ -0,0 +1,565 @@ +/****************************************************************************** + + @File PVRTArray.h + + @Title PVRTArray + + @Version + + @Copyright Copyright (c) Imagination Technologies Limited. + + @Platform ANSI compatible + + @Description Expanding array template class. Allows appending and direct + access. Mixing access methods should be approached with caution. + +******************************************************************************/ +#ifndef __PVRTARRAY_H__ +#define __PVRTARRAY_H__ + +#include "PVRTGlobal.h" +#include "PVRTError.h" + +/*!**************************************************************************** +Class +******************************************************************************/ + +/*!*************************************************************************** +* @Class CPVRTArray +* @Brief Expanding array template class. +* @Description Expanding array template class. +*****************************************************************************/ +template +class CPVRTArray +{ +public: + /*!*************************************************************************** + @Function CPVRTArray + @Description Blank constructor. Makes a default sized array. + *****************************************************************************/ + CPVRTArray() : m_uiSize(0), m_uiCapacity(GetDefaultSize()) + { + m_pArray = new T[m_uiCapacity]; + } + + /*!*************************************************************************** + @Function CPVRTArray + @Input uiSize intial size of array + @Description Constructor taking initial size of array in elements. + *****************************************************************************/ + CPVRTArray(const unsigned int uiSize) : m_uiSize(0), m_uiCapacity(uiSize) + { + _ASSERT(uiSize != 0); + m_pArray = new T[uiSize]; + } + + /*!*************************************************************************** + @Function CPVRTArray + @Input original the other dynamic array + @Description Copy constructor. + *****************************************************************************/ + CPVRTArray(const CPVRTArray& original) : m_uiSize(original.m_uiSize), + m_uiCapacity(original.m_uiCapacity) + { + m_pArray = new T[m_uiCapacity]; + for(unsigned int i=0;i= m_uiSize) // Are we adding to the end + uiIndex = Append(addT); + else + { + unsigned int uiNewCapacity = 0; + T* pArray = m_pArray; + + if(m_uiSize > m_uiCapacity) + { + uiNewCapacity = m_uiCapacity + 10; // Expand the array by 10. + + pArray = new T[uiNewCapacity]; // New Array + + if(!pArray) + return -1; // Failed to allocate memory! + + // Copy the first half to the new array + for(unsigned int i = 0; i < pos; ++i) + { + pArray[i] = m_pArray[i]; + } + } + + // Copy last half to the new array + for(unsigned int i = m_uiSize; i > pos; --i) + { + pArray[i] = m_pArray[i - 1]; + } + + // Insert our new element + pArray[pos] = addT; + uiIndex = pos; + + // Increase our size + ++m_uiSize; + + // Switch pointers and free memory if needed + if(pArray != m_pArray) + { + m_uiCapacity = uiNewCapacity; + delete[] m_pArray; + m_pArray = pArray; + } + } + + return uiIndex; + } + + /*!*************************************************************************** + @Function Append + @Input addT The element to append + @Return The index of the new item. + @Description Appends an element to the end of the array, expanding it + if necessary. + *****************************************************************************/ + unsigned int Append(const T& addT) + { + unsigned int uiIndex = Append(); + m_pArray[uiIndex] = addT; + return uiIndex; + } + + /*!*************************************************************************** + @Function Append + @Return The index of the new item. + @Description Creates space for a new item, but doesn't add. Instead + returns the index of the new item. + *****************************************************************************/ + unsigned int Append() + { + unsigned int uiIndex = m_uiSize; + SetCapacity(m_uiSize+1); + m_uiSize++; + + return uiIndex; + } + + /*!*************************************************************************** + @Function Clear + @Description Clears the array. + *****************************************************************************/ + void Clear() + { + m_uiSize = 0U; + } + + /*!*************************************************************************** + @Function Resize + @Input uiSize New size of array + @Description Changes the array to the new size + *****************************************************************************/ + EPVRTError Resize(const unsigned int uiSize) + { + EPVRTError err = SetCapacity(uiSize); + + if(err != PVR_SUCCESS) + return err; + + m_uiSize = uiSize; + return PVR_SUCCESS; + } + + /*!*************************************************************************** + @Function SetCapacity + @Input uiSize New capacity of array + @Description Expands array to new capacity + *****************************************************************************/ + EPVRTError SetCapacity(const unsigned int uiSize) + { + if(uiSize <= m_uiCapacity) + return PVR_SUCCESS; // nothing to be done + + unsigned int uiNewCapacity; + if(uiSize < m_uiCapacity*2) + { + uiNewCapacity = m_uiCapacity*2; // Ignore the new size. Expand to twice the previous size. + } + else + { + uiNewCapacity = uiSize; + } + + T* pNewArray = new T[uiNewCapacity]; // New Array + if(!pNewArray) + return PVR_FAIL; // Failed to allocate memory! + + // Copy source data to new array + for(unsigned int i = 0; i < m_uiSize; ++i) + { + pNewArray[i] = m_pArray[i]; + } + + // Switch pointers and free memory + m_uiCapacity = uiNewCapacity; + T* pOldArray = m_pArray; + m_pArray = pNewArray; + delete [] pOldArray; + return PVR_SUCCESS; + } + + /*!*************************************************************************** + @Function Copy + @Input other The CPVRTArray needing copied + @Description A copy function. Will attempt to copy from other CPVRTArrays + if this is possible. + *****************************************************************************/ + template + void Copy(const CPVRTArray& other) + { + T* pNewArray = new T[other.GetCapacity()]; + if(pNewArray) + { + // Copy data + for(unsigned int i = 0; i < other.GetSize(); i++) + { + pNewArray[i] = other[i]; + } + + // Free current array + if(m_pArray) + delete [] m_pArray; + + // Swap pointers + m_pArray = pNewArray; + + m_uiCapacity = other.GetCapacity(); + m_uiSize = other.GetSize(); + } + } + + /*!*************************************************************************** + @Function = + @Input other The CPVRTArray needing copied + @Description assignment operator. + *****************************************************************************/ + CPVRTArray& operator=(const CPVRTArray& other) + { + if(&other != this) + Copy(other); + + return *this; + } + + /*!*************************************************************************** + @Function operator+= + @Input other the array to append. + @Description appends an existing CPVRTArray on to this one. + *****************************************************************************/ + CPVRTArray& operator+=(const CPVRTArray& other) + { + if(&other != this) + { + for(unsigned int uiIndex = 0; uiIndex < other.GetSize(); ++uiIndex) + { + Append(other[uiIndex]); + } + } + + return *this; + } + + /*!*************************************************************************** + @Function [] + @Input uiIndex index of element in array + @Return the element indexed + @Description indexed access into array. Note that this has no error + checking whatsoever + *****************************************************************************/ + T& operator[](const unsigned int uiIndex) + { + _ASSERT(uiIndex < m_uiCapacity); + return m_pArray[uiIndex]; + } + + /*!*************************************************************************** + @Function [] + @Input uiIndex index of element in array + @Return The element indexed + @Description Indexed access into array. Note that this has no error + checking whatsoever + *****************************************************************************/ + const T& operator[](const unsigned int uiIndex) const + { + _ASSERT(uiIndex < m_uiCapacity); + return m_pArray[uiIndex]; + } + + /*!*************************************************************************** + @Function GetSize + @Return Size of array + @Description Gives current size of array/number of elements + *****************************************************************************/ + unsigned int GetSize() const + { + return m_uiSize; + } + + /*!*************************************************************************** + @Function GetDefaultSize + @Return Default size of array + @Description Gives the default size of array/number of elements + *****************************************************************************/ + static unsigned int GetDefaultSize() + { + return 16U; + } + + /*!*************************************************************************** + @Function GetCapacity + @Return Capacity of array + @Description Gives current allocated size of array/number of elements + *****************************************************************************/ + unsigned int GetCapacity() const + { + return m_uiCapacity; + } + + /*!*************************************************************************** + @Function Contains + @Input object The object to check in the array + @Return true if object is contained in this array. + @Description Indicates whether the given object resides inside the + array. + *****************************************************************************/ + bool Contains(const T& object) const + { + for(unsigned int uiIndex = 0; uiIndex < m_uiSize; ++uiIndex) + { + if(m_pArray[uiIndex] == object) + return true; + } + return false; + } + + /*!*************************************************************************** + @Function Find + @Input object The object to check in the array + @Return pointer to the found object or NULL. + @Description Attempts to find the object in the array and returns a + pointer if it is found, or NULL if not found. The time + taken is O(N). + *****************************************************************************/ + T* Find(const T& object) const + { + for(unsigned int uiIndex = 0; uiIndex < m_uiSize; ++uiIndex) + { + if(m_pArray[uiIndex] == object) + return &m_pArray[uiIndex]; + } + return NULL; + } + + /*!*************************************************************************** + @Function Sort + @Input predicate The object which defines "bool operator()" + @Description Simple bubble-sort of the array. Pred should be an object that + defines a bool operator(). + *****************************************************************************/ + template + void Sort(Pred predicate) + { + bool bSwap; + for(unsigned int i=0; i < m_uiSize; ++i) + { + bSwap = false; + for(unsigned int j=0; j < m_uiSize-1; ++j) + { + if(predicate(m_pArray[j], m_pArray[j+1])) + { + PVRTswap(m_pArray[j], m_pArray[j+1]); + bSwap = true; + } + } + + if(!bSwap) + return; + } + } + + /*!*************************************************************************** + @Function Remove + @Input uiIndex The index to remove + @Return success or failure + @Description Removes an element from the array. + *****************************************************************************/ + virtual EPVRTError Remove(unsigned int uiIndex) + { + _ASSERT(uiIndex < m_uiSize); + if(m_uiSize == 0) + return PVR_FAIL; + + if(uiIndex == m_uiSize-1) + { + return RemoveLast(); + } + + m_uiSize--; + // Copy the data. memmove will only work for built-in types. + for(unsigned int uiNewIdx = uiIndex; uiNewIdx < m_uiSize; ++uiNewIdx) + { + m_pArray[uiNewIdx] = m_pArray[uiNewIdx+1]; + } + + return PVR_SUCCESS; + } + + /*!*************************************************************************** + @Function RemoveLast + @Return success or failure + @Description Removes the last element. Simply decrements the size value + *****************************************************************************/ + virtual EPVRTError RemoveLast() + { + if(m_uiSize > 0) + { + m_uiSize--; + return PVR_SUCCESS; + } + else + { + return PVR_FAIL; + } + } + +protected: + unsigned int m_uiSize; /*! current size of contents of array */ + unsigned int m_uiCapacity; /*! currently allocated size of array */ + T *m_pArray; /*! the actual array itself */ +}; + +// note "this" is required for ISO standard C++ and gcc complains otherwise +// http://lists.apple.com/archives/Xcode-users//2005/Dec/msg00644.html +template +class CPVRTArrayManagedPointers : public CPVRTArray +{ +public: + virtual ~CPVRTArrayManagedPointers() + { + if(this->m_pArray) + { + for(unsigned int i=0;im_uiSize;i++) + { + delete(this->m_pArray[i]); + } + } + } + + /*!*************************************************************************** + @Function Remove + @Input uiIndex The index to remove + @Return success or failure + @Description Removes an element from the array. + *****************************************************************************/ + virtual EPVRTError Remove(unsigned int uiIndex) + { + _ASSERT(uiIndex < this->m_uiSize); + if(this->m_uiSize == 0) + return PVR_FAIL; + + if(uiIndex == this->m_uiSize-1) + { + return this->RemoveLast(); + } + + unsigned int uiSize = (this->m_uiSize - (uiIndex+1)) * sizeof(T*); + + delete this->m_pArray[uiIndex]; + memmove(this->m_pArray + uiIndex, this->m_pArray + (uiIndex+1), uiSize); + + this->m_uiSize--; + return PVR_SUCCESS; + } + + /*!*************************************************************************** + @Function RemoveLast + @Return success or failure + @Description Removes the last element. Simply decrements the size value + *****************************************************************************/ + virtual EPVRTError RemoveLast() + { + if(this->m_uiSize > 0 && this->m_pArray) + { + delete this->m_pArray[this->m_uiSize-1]; + this->m_uiSize--; + return PVR_SUCCESS; + } + else + { + return PVR_FAIL; + } + } +}; + +#endif // __PVRTARRAY_H__ + +/***************************************************************************** +End of file (PVRTArray.h) +*****************************************************************************/ + diff --git a/KREngine/3rdparty/pvrtexlib/include/PVRTDecompress.h b/KREngine/3rdparty/pvrtexlib/include/PVRTDecompress.h new file mode 100644 index 0000000..71a008b --- /dev/null +++ b/KREngine/3rdparty/pvrtexlib/include/PVRTDecompress.h @@ -0,0 +1,58 @@ +/****************************************************************************** + + @File PVRTDecompress.h + + @Title PVRTDecompress + + @Version + + @Copyright Copyright (c) Imagination Technologies Limited. + + @Platform ANSI compatible + + @Description PVRTC and ETC Texture Decompression. + +******************************************************************************/ + +#ifndef _PVRTDECOMPRESS_H_ +#define _PVRTDECOMPRESS_H_ + +/*!*********************************************************************** + @Function PVRTDecompressPVRTC + @Input pCompressedData The PVRTC texture data to decompress + @Input Do2bitMode Signifies whether the data is PVRTC2 or PVRTC4 + @Input XDim X dimension of the texture + @Input YDim Y dimension of the texture + @Return Returns the amount of data that was decompressed. + @Modified pResultImage The decompressed texture data + @Description Decompresses PVRTC to RGBA 8888 +*************************************************************************/ +int PVRTDecompressPVRTC(const void *pCompressedData, + const int Do2bitMode, + const int XDim, + const int YDim, + unsigned char* pResultImage); + +/*!*********************************************************************** +@Function PVRTDecompressETC +@Input pSrcData The ETC texture data to decompress +@Input x X dimension of the texture +@Input y Y dimension of the texture +@Modified pDestData The decompressed texture data +@Input nMode The format of the data +@Returns The number of bytes of ETC data decompressed +@Description Decompresses ETC to RGBA 8888 +*************************************************************************/ +int PVRTDecompressETC(const void * const pSrcData, + const unsigned int &x, + const unsigned int &y, + void *pDestData, + const int &nMode); + + +#endif /* _PVRTDECOMPRESS_H_ */ + +/***************************************************************************** + End of file (PVRTBoneBatch.h) +*****************************************************************************/ + diff --git a/KREngine/3rdparty/pvrtexlib/include/PVRTError.h b/KREngine/3rdparty/pvrtexlib/include/PVRTError.h new file mode 100644 index 0000000..357a1ab --- /dev/null +++ b/KREngine/3rdparty/pvrtexlib/include/PVRTError.h @@ -0,0 +1,71 @@ +/****************************************************************************** + + @File PVRTError.h + + @Title PVRTError + + @Version + + @Copyright Copyright (c) Imagination Technologies Limited. + + @Platform ANSI compatible + + @Description + +******************************************************************************/ +#ifndef _PVRTERROR_H_ +#define _PVRTERROR_H_ + +#if defined(ANDROID) + #include +#else + #if defined(_WIN32) + #include + #else + #include + #endif +#endif +/*!*************************************************************************** + Macros +*****************************************************************************/ + +/*! Outputs a string to the standard error if built for debugging. */ +#if !defined(PVRTERROR_OUTPUT_DEBUG) + #if defined(_DEBUG) || defined(DEBUG) + #if defined(ANDROID) + #define PVRTERROR_OUTPUT_DEBUG(A) __android_log_print(ANDROID_LOG_INFO, "PVRTools", A); + #elif defined(_WIN32) && !defined(UNDER_CE) + #define PVRTERROR_OUTPUT_DEBUG(A) OutputDebugStringA(A); + #else + #define PVRTERROR_OUTPUT_DEBUG(A) fprintf(stderr,A); + #endif + #else + #define PVRTERROR_OUTPUT_DEBUG(A) + #endif +#endif + + +/*!*************************************************************************** + Enums +*****************************************************************************/ +/*! Enum error codes */ +enum EPVRTError +{ + PVR_SUCCESS = 0, + PVR_FAIL = 1, + PVR_OVERFLOW = 2 +}; + +/*!*************************************************************************** + @Function PVRTErrorOutputDebug + @Input format printf style format followed by arguments it requires + @Description Outputs a string to the standard error. +*****************************************************************************/ +void PVRTErrorOutputDebug(char const * const format, ...); + +#endif // _PVRTERROR_H_ + +/***************************************************************************** +End of file (PVRTError.h) +*****************************************************************************/ + diff --git a/KREngine/3rdparty/pvrtexlib/include/PVRTGlobal.h b/KREngine/3rdparty/pvrtexlib/include/PVRTGlobal.h new file mode 100644 index 0000000..b7f64a5 --- /dev/null +++ b/KREngine/3rdparty/pvrtexlib/include/PVRTGlobal.h @@ -0,0 +1,296 @@ +/****************************************************************************** + + @File PVRTGlobal.h + + @Title PVRTGlobal + + @Version + + @Copyright Copyright (c) Imagination Technologies Limited. + + @Platform ANSI compatible + + @Description Global defines and typedefs for PVRTools + +******************************************************************************/ +#ifndef _PVRTGLOBAL_H_ +#define _PVRTGLOBAL_H_ + +/*!*************************************************************************** + Macros +*****************************************************************************/ +#define PVRT_MIN(a,b) (((a) < (b)) ? (a) : (b)) +#define PVRT_MAX(a,b) (((a) > (b)) ? (a) : (b)) +#define PVRT_CLAMP(x, l, h) (PVRT_MIN((h), PVRT_MAX((x), (l)))) + +// avoid warning about unused parameter +#define PVRT_UNREFERENCED_PARAMETER(x) ((void) x) + +#if defined(_WIN32) && !defined(__QT__) && !defined(UNDER_CE) /* Windows desktop */ +#if !defined(_CRTDBG_MAP_ALLOC) + #define _CRTDBG_MAP_ALLOC +#endif + #include + #include + #include +#endif + +#if defined(UNDER_CE) + #include + +#ifndef _ASSERT + #ifdef _DEBUG + #define _ASSERT(X) { (X) ? 0 : DebugBreak(); } + #else + #define _ASSERT(X) + #endif +#endif + +#ifndef _ASSERTE + #ifdef _DEBUG + #define _ASSERTE _ASSERT + #else + #define _ASSERTE(X) + #endif +#endif + #define _RPT0(a,b) + #define _RPT1(a,b,c) + #define _RPT2(a,b,c,d) + #define _RPT3(a,b,c,d,e) + #define _RPT4(a,b,c,d,e,f) +#else + +#if defined(_WIN32) && !defined(__QT__) + +#else +#if defined(__linux__) || defined(__APPLE__) + #define _ASSERT(a)((void)0) + #define _ASSERTE(a)((void)0) + #ifdef _DEBUG + #ifndef _RPT0 + #define _RPT0(a,b) printf(b) + #endif + #ifndef _RPT1 + #define _RPT1(a,b,c) printf(b,c) + #endif + #else + #ifndef _RPT0 + #define _RPT0(a,b)((void)0) + #endif + #ifndef _RPT1 + #define _RPT1(a,b,c)((void)0) + #endif + #endif + #define _RPT2(a,b,c,d)((void)0) + #define _RPT3(a,b,c,d,e)((void)0) + #define _RPT4(a,b,c,d,e,f)((void)0) + #include + #include + #define BYTE unsigned char + #define WORD unsigned short + #define DWORD unsigned int + typedef struct tagRGBQUAD { + BYTE rgbBlue; + BYTE rgbGreen; + BYTE rgbRed; + BYTE rgbReserved; + } RGBQUAD; + #define BOOL int +#if !defined(TRUE) + #define TRUE 1 +#endif +#if !defined(FALSE) + #define FALSE 0 +#endif +#else + #define _CRT_WARN 0 + #define _RPT0(a,b) + #define _RPT1(a,b,c) + #define _RPT2(a,b,c,d) + #define _RPT3(a,b,c,d,e) + #define _RPT4(a,b,c,d,e,f) + #define _ASSERT(X) + #define _ASSERTE(X) +#endif +#endif +#endif + +#include + +#define FREE(X) { if(X) { free(X); (X) = 0; } } + +// This macro is used to check at compile time that types are of a certain size +// If the size does not equal the expected size, this typedefs an array of size 0 +// which causes a compile error +#define PVRTSIZEASSERT(T, size) typedef int (sizeof_##T)[sizeof(T) == (size)] +#define PVRTCOMPILEASSERT(T, expr) typedef int (assert_##T)[expr] + + +/**************************************************************************** +** Integer types +****************************************************************************/ + +typedef char PVRTchar8; +typedef signed char PVRTint8; +typedef signed short PVRTint16; +typedef signed int PVRTint32; +typedef unsigned char PVRTuint8; +typedef unsigned short PVRTuint16; +typedef unsigned int PVRTuint32; + +typedef float PVRTfloat32; + +#if (defined(__int64) || defined(_WIN32)) +typedef signed __int64 PVRTint64; +typedef unsigned __int64 PVRTuint64; +#elif defined(TInt64) +typedef TInt64 PVRTint64; +typedef TUInt64 PVRTuint64; +#else +typedef signed long long PVRTint64; +typedef unsigned long long PVRTuint64; +#endif + +#if __SIZEOF_WCHAR_T__ == 4 || __WCHAR_MAX__ > 0x10000 + #define PVRTSIZEOFWCHAR 4 +#else + #define PVRTSIZEOFWCHAR 2 +#endif + +PVRTSIZEASSERT(PVRTchar8, 1); +PVRTSIZEASSERT(PVRTint8, 1); +PVRTSIZEASSERT(PVRTuint8, 1); +PVRTSIZEASSERT(PVRTint16, 2); +PVRTSIZEASSERT(PVRTuint16, 2); +PVRTSIZEASSERT(PVRTint32, 4); +PVRTSIZEASSERT(PVRTuint32, 4); +PVRTSIZEASSERT(PVRTint64, 8); +PVRTSIZEASSERT(PVRTuint64, 8); +PVRTSIZEASSERT(PVRTfloat32, 4); + +/*!************************************************************************** +@Enum ETextureFilter +@Brief Enum values for defining texture filtering +****************************************************************************/ +enum ETextureFilter +{ + eFilter_Nearest, + eFilter_Linear, + eFilter_None, + + eFilter_Size, + eFilter_Default = eFilter_Linear, + eFilter_MipDefault = eFilter_None +}; + +/*!************************************************************************** +@Enum ETextureWrap +@Brief Enum values for defining texture wrapping +****************************************************************************/ +enum ETextureWrap +{ + eWrap_Clamp, + eWrap_Repeat, + + eWrap_Size, + eWrap_Default = eWrap_Repeat +}; + +/**************************************************************************** +** swap template function +****************************************************************************/ +/*!*************************************************************************** + @Function PVRTswap + @Input a Type a + @Input b Type b + @Description A swap template function that swaps a and b +*****************************************************************************/ + +template +inline void PVRTswap(T& a, T& b) +{ + T temp = a; + a = b; + b = temp; +} + +/*!*************************************************************************** + @Function PVRTClamp + @Input val Value to clamp + @Input min Minimum legal value + @Input max Maximum legal value + @Description A clamp template function that clamps val between min and max. +*****************************************************************************/ +template +inline T PVRTClamp(const T& val, const T& min, const T& max) +{ + if(val > max) + return max; + if(val < min) + return min; + return val; +} + +/*!*************************************************************************** + @Function PVRTByteSwap + @Input pBytes A number + @Input i32ByteNo Number of bytes in pBytes + @Description Swaps the endianness of pBytes in place +*****************************************************************************/ +inline void PVRTByteSwap(unsigned char* pBytes, int i32ByteNo) +{ + int i = 0, j = i32ByteNo - 1; + + while(i < j) + PVRTswap(pBytes[i++], pBytes[j--]); +} + +/*!*************************************************************************** + @Function PVRTByteSwap32 + @Input ui32Long A number + @Returns ui32Long with its endianness changed + @Description Converts the endianness of an unsigned int +*****************************************************************************/ +inline unsigned int PVRTByteSwap32(unsigned int ui32Long) +{ + return ((ui32Long&0x000000FF)<<24) + ((ui32Long&0x0000FF00)<<8) + ((ui32Long&0x00FF0000)>>8) + ((ui32Long&0xFF000000) >> 24); +} + +/*!*************************************************************************** + @Function PVRTByteSwap16 + @Input ui16Short A number + @Returns ui16Short with its endianness changed + @Description Converts the endianness of a unsigned short +*****************************************************************************/ +inline unsigned short PVRTByteSwap16(unsigned short ui16Short) +{ + return (ui16Short>>8) | (ui16Short<<8); +} + +/*!*************************************************************************** + @Function PVRTIsLittleEndian + @Returns True if the platform the code is ran on is little endian + @Description Returns true if the platform the code is ran on is little endian +*****************************************************************************/ +inline bool PVRTIsLittleEndian() +{ + static bool bLittleEndian; + static bool bIsInit = false; + + if(!bIsInit) + { + short int word = 0x0001; + char *byte = (char*) &word; + bLittleEndian = byte[0] ? true : false; + bIsInit = true; + } + + return bLittleEndian; +} + +#endif // _PVRTGLOBAL_H_ + +/***************************************************************************** + End of file (Tools.h) +*****************************************************************************/ + diff --git a/KREngine/3rdparty/pvrtexlib/include/PVRTMap.h b/KREngine/3rdparty/pvrtexlib/include/PVRTMap.h new file mode 100644 index 0000000..fff8252 --- /dev/null +++ b/KREngine/3rdparty/pvrtexlib/include/PVRTMap.h @@ -0,0 +1,225 @@ +/****************************************************************************** + + @File PVRTMap.h + + @Title PVRTArray + + @Version + + @Copyright Copyright (c) Imagination Technologies Limited. + + @Platform ANSI compatible + + @Description A simple and easy to use implementation of a map. + +******************************************************************************/ +#ifndef __PVRTMAP_H__ +#define __PVRTMAP_H__ + +#include "PVRTArray.h" + +/*!**************************************************************************** +Class +******************************************************************************/ + +/*!*************************************************************************** +* @Class CPVRTMap +* @Brief Expanding map template class. +* @Description A simple and easy to use implementation of a map. +*****************************************************************************/ +template +class CPVRTMap +{ +public: + + /*!*********************************************************************** + @Function CPVRTMap + @Return A new CPVRTMap. + @Description Constructor for a CPVRTMap. + *************************************************************************/ + CPVRTMap() : m_Keys(), m_Data(), m_uiSize(0) + {} + + /*!*********************************************************************** + @Function ~CPVRTMap + @Description Destructor for a CPVRTMap. + *************************************************************************/ + ~CPVRTMap() + { + //Clear the map, that's enough - the CPVRTArray members will tidy everything else up. + Clear(); + } + + EPVRTError Reserve(const PVRTuint32 uiSize) + { + //Sets the capacity of each member array to the requested size. The array used will only expand. + //Returns the most serious error from either method. + return PVRT_MAX(m_Keys.SetCapacity(uiSize),m_Data.SetCapacity(uiSize)); + } + + /*!*********************************************************************** + @Function GetSize + @Return Number of meaningful members in the map. + @Description Returns the number of meaningful members in the map. + *************************************************************************/ + PVRTuint32 GetSize() const + { + //Return the size. + return m_uiSize; + } + + /*!*********************************************************************** + @Function GetIndexOf + @Input key + @Return The index value for a mapped item. + @Description Gets the position of a particular key/data within the map. + If the return value is exactly equal to the value of + GetSize() then the item has not been found. + *************************************************************************/ + PVRTuint32 GetIndexOf(const KeyType key) const + { + //Loop through all the valid keys. + for (PVRTuint32 i=0; i=m_uiSize) + return NULL; + + return &(m_Data[uiIndex]); + } + + /*!*********************************************************************** + @Function operator[] + @Input key + @Return Data that is mapped to 'key'. + @Description If a mapping already exists for 'key' then it will return + the associated data. If no mapping currently exists, a new + element is created in place. + *************************************************************************/ + DataType& operator[] (const KeyType key) + { + //Get the index of the key. + PVRTuint32 uiIndex = GetIndexOf(key); + + //Check the index is valid + if (uiIndex != m_uiSize) + { + //Return mapped data if the index is valid. + return m_Data[uiIndex]; + } + else + { + //Append the key to the Keys array. + m_Keys.Append(key); + + //Create a new DataType. + DataType sNewData; + + //Append the new pointer to the Data array. + m_Data.Append(sNewData); + + //Increment the size of meaningful data. + ++m_uiSize; + + //Return the contents of pNewData. + return m_Data[m_Keys.GetSize()-1]; + } + } + + /*!*********************************************************************** + @Function Remove + @Input key + @Return Returns PVR_FAIL if item doesn't exist. + Otherwise returns PVR_SUCCESS. + @Description Removes an element from the map if it exists. + *************************************************************************/ + EPVRTError Remove(const KeyType key) + { + //Finds the index of the key. + PVRTuint32 uiIndex=GetIndexOf(key); + + //If the key is invalid, fail. + if (uiIndex==m_uiSize) + { + //Return failure. + return PVR_FAIL; + } + + //Decrement the size of the map to ignore the last element in each array. + m_uiSize--; + + //Copy the last key over the deleted key. There are now two copies of one element, + //but the one at the end of the array is ignored. + m_Keys[uiIndex]=m_Keys[m_uiSize-1]; + + //Copy the last data over the deleted data in the same way as the keys. + m_Data[uiIndex]=m_Data[m_uiSize-1]; + + //Return success. + return PVR_SUCCESS; + } + + /*!*********************************************************************** + @Function Clear + @Description Clears the Map of all data values. + *************************************************************************/ + void Clear() + { + //Set the size to 0. + m_uiSize=0; + m_Keys.Clear(); + m_Data.Clear(); + } + + /*!*********************************************************************** + @Function Exists + @Input key + @Return Whether data exists for the specified key or not. + @Description Checks whether or not data exists for the specified key. + *************************************************************************/ + bool Exists(const KeyType key) const + { + //Checks for a valid index for key, if not, returns false. + return (GetIndexOf(key) != m_uiSize); + } + +private: + + //Array of all the keys. Indices match m_Data. + CPVRTArray m_Keys; + + //Array of pointers to all the allocated data. + CPVRTArray m_Data; + + //The number of meaningful members in the map. + PVRTuint32 m_uiSize; +}; + +#endif // __PVRTMAP_H__ + +/***************************************************************************** +End of file (PVRTMap.h) +*****************************************************************************/ + diff --git a/KREngine/3rdparty/pvrtexlib/include/PVRTString.h b/KREngine/3rdparty/pvrtexlib/include/PVRTString.h new file mode 100644 index 0000000..759aa8b --- /dev/null +++ b/KREngine/3rdparty/pvrtexlib/include/PVRTString.h @@ -0,0 +1,982 @@ +/****************************************************************************** + + @File PVRTString.h + + @Title PVRTString + + @Version + + @Copyright Copyright (c) Imagination Technologies Limited. + + @Platform ANSI compatible + + @Description A string class that can be used as drop-in replacement for + std::string on platforms/compilers that don't provide a full C++ + standard library. + +******************************************************************************/ +#ifndef _PVRTSTRING_H_ +#define _PVRTSTRING_H_ + +#include +#define _USING_PVRTSTRING_ + +/*!*************************************************************************** +@Class CPVRTString +@Brief A string class +*****************************************************************************/ +class CPVRTString +{ + +private: + + // Checking printf and scanf format strings +#if defined(_CC_GNU_) || defined(__GNUG__) || defined(__GNUC__) +#define FX_PRINTF(fmt,arg) __attribute__((format(printf,fmt,arg))) +#define FX_SCANF(fmt,arg) __attribute__((format(scanf,fmt,arg))) +#else +#define FX_PRINTF(fmt,arg) +#define FX_SCANF(fmt,arg) +#endif + +public: + typedef size_t size_type; + typedef char value_type; + typedef char& reference; + typedef const char& const_reference; + + static const size_type npos; + + + + + /*!*********************************************************************** + @Function CPVRTString + @Input _Ptr A string + @Input _Count Length of _Ptr + @Description Constructor + ************************************************************************/ + CPVRTString(const char* _Ptr, size_t _Count = npos); + + /*!*********************************************************************** + @Function CPVRTString + @Input _Right A string + @Input _Roff Offset into _Right + @Input _Count Number of chars from _Right to assign to the new string + @Description Constructor + ************************************************************************/ + CPVRTString(const CPVRTString& _Right, size_t _Roff = 0, size_t _Count = npos); + + /*!*********************************************************************** + @Function CPVRTString + @Input _Count Length of new string + @Input _Ch A char to fill it with + @Description Constructor + *************************************************************************/ + CPVRTString(size_t _Count, const char _Ch); + + /*!*********************************************************************** + @Function CPVRTString + @Input _Ch A char + @Description Constructor + *************************************************************************/ + CPVRTString(const char _Ch); + + /*!*********************************************************************** + @Function CPVRTString + @Description Constructor + ************************************************************************/ + CPVRTString(); + + /*!*********************************************************************** + @Function ~CPVRTString + @Description Destructor + ************************************************************************/ + virtual ~CPVRTString(); + + /*!*********************************************************************** + @Function append + @Input _Ptr A string + @Returns Updated string + @Description Appends a string + *************************************************************************/ + CPVRTString& append(const char* _Ptr); + + /*!*********************************************************************** + @Function append + @Input _Ptr A string + @Input _Count String length + @Returns Updated string + @Description Appends a string of length _Count + *************************************************************************/ + CPVRTString& append(const char* _Ptr, size_t _Count); + + /*!*********************************************************************** + @Function append + @Input _Str A string + @Returns Updated string + @Description Appends a string + *************************************************************************/ + CPVRTString& append(const CPVRTString& _Str); + + /*!*********************************************************************** + @Function append + @Input _Str A string + @Input _Off A position in string + @Input _Count Number of letters to append + @Returns Updated string + @Description Appends _Count letters of _Str from _Off in _Str + *************************************************************************/ + CPVRTString& append(const CPVRTString& _Str, size_t _Off, size_t _Count); + + /*!*********************************************************************** + @Function append + @Input _Ch A char + @Input _Count Number of times to append _Ch + @Returns Updated string + @Description Appends _Ch _Count times + *************************************************************************/ + CPVRTString& append(size_t _Count, const char _Ch); + + //template CPVRTString& append(InputIterator _First, InputIterator _Last); + + /*!*********************************************************************** + @Function assign + @Input _Ptr A string + @Returns Updated string + @Description Assigns the string to the string _Ptr + *************************************************************************/ + CPVRTString& assign(const char* _Ptr); + + /*!*********************************************************************** + @Function assign + @Input _Ptr A string + @Input _Count Length of _Ptr + @Returns Updated string + @Description Assigns the string to the string _Ptr + *************************************************************************/ + CPVRTString& assign(const char* _Ptr, size_t _Count); + + /*!*********************************************************************** + @Function assign + @Input _Str A string + @Returns Updated string + @Description Assigns the string to the string _Str + *************************************************************************/ + CPVRTString& assign(const CPVRTString& _Str); + + /*!*********************************************************************** + @Function assign + @Input _Str A string + @Input _Off First char to start assignment from + @Input _Count Length of _Str + @Returns Updated string + @Description Assigns the string to _Count characters in string _Str starting at _Off + *************************************************************************/ + CPVRTString& assign(const CPVRTString& _Str, size_t _Off, size_t _Count=npos); + + /*!*********************************************************************** + @Function assign + @Input _Ch A string + @Input _Count Number of times to repeat _Ch + @Returns Updated string + @Description Assigns the string to _Count copies of _Ch + *************************************************************************/ + CPVRTString& assign(size_t _Count, char _Ch); + + //template CPVRTString& assign(InputIterator _First, InputIterator _Last); + + //const_reference at(size_t _Off) const; + //reference at(size_t _Off); + + // const_iterator begin() const; + // iterator begin(); + + /*!*********************************************************************** + @Function c_str + @Returns const char* pointer of the string + @Description Returns a const char* pointer of the string + *************************************************************************/ + const char* c_str() const; + + /*!*********************************************************************** + @Function capacity + @Returns The size of the character array reserved + @Description Returns the size of the character array reserved + *************************************************************************/ + size_t capacity() const; + + /*!*********************************************************************** + @Function clear + @Description Clears the string + *************************************************************************/ + void clear(); + + /*!*********************************************************************** + @Function compare + @Input _Str A string to compare with + @Returns 0 if the strings match + @Description Compares the string with _Str + *************************************************************************/ + int compare(const CPVRTString& _Str) const; + + /*!*********************************************************************** + @Function compare + @Input _Pos1 Position to start comparing from + @Input _Num1 Number of chars to compare + @Input _Str A string to compare with + @Returns 0 if the strings match + @Description Compares the string with _Str + *************************************************************************/ + int compare(size_t _Pos1, size_t _Num1, const CPVRTString& _Str) const; + + /*!*********************************************************************** + @Function compare + @Input _Pos1 Position to start comparing from + @Input _Num1 Number of chars to compare + @Input _Str A string to compare with + @Input _Off Position in _Str to compare from + @Input _Count Number of chars in _Str to compare with + @Returns 0 if the strings match + @Description Compares the string with _Str + *************************************************************************/ + int compare(size_t _Pos1, size_t _Num1, const CPVRTString& _Str, size_t _Off, size_t _Count) const; + + /*!*********************************************************************** + @Function compare + @Input _Ptr A string to compare with + @Returns 0 if the strings match + @Description Compares the string with _Ptr + *************************************************************************/ + int compare(const char* _Ptr) const; + + /*!*********************************************************************** + @Function compare + @Input _Pos1 Position to start comparing from + @Input _Num1 Number of chars to compare + @Input _Ptr A string to compare with + @Returns 0 if the strings match + @Description Compares the string with _Ptr + *************************************************************************/ + int compare(size_t _Pos1, size_t _Num1, const char* _Ptr) const; + + /*!*********************************************************************** + @Function compare + @Input _Pos1 Position to start comparing from + @Input _Num1 Number of chars to compare + @Input _Ptr A string to compare with + @Input _Count Number of chars to compare + @Returns 0 if the strings match + @Description Compares the string with _Str + *************************************************************************/ + int compare(size_t _Pos1, size_t _Num1, const char* _Ptr, size_t _Count) const; + + /*!*********************************************************************** + @Function < + @Input _Str A string to compare with + @Returns True on success + @Description Less than operator + *************************************************************************/ + bool operator<(const CPVRTString & _Str) const; + + /*!*********************************************************************** + @Function == + @Input _Str A string to compare with + @Returns True if they match + @Description == Operator + *************************************************************************/ + bool operator==(const CPVRTString& _Str) const; + + /*!*********************************************************************** + @Function == + @Input _Ptr A string to compare with + @Returns True if they match + @Description == Operator + *************************************************************************/ + bool operator==(const char* const _Ptr) const; + + /*!*********************************************************************** + @Function != + @Input _Str A string to compare with + @Returns True if they don't match + @Description != Operator + *************************************************************************/ + bool operator!=(const CPVRTString& _Str) const; + + /*!*********************************************************************** + @Function != + @Input _Ptr A string to compare with + @Returns True if they don't match + @Description != Operator + *************************************************************************/ + bool operator!=(const char* const _Ptr) const; + + /*!*********************************************************************** + @Function copy + @Modified _Ptr A string to copy to + @Input _Count Size of _Ptr + @Input _Off Position to start copying from + @Returns Number of bytes copied + @Description Copies the string to _Ptr + *************************************************************************/ + size_t copy(char* _Ptr, size_t _Count, size_t _Off = 0) const; + + /*!*********************************************************************** + @Function data + @Returns A const char* version of the string + @Description Returns a const char* version of the string + *************************************************************************/ + const char* data( ) const; + + /*!*********************************************************************** + @Function empty + @Returns True if the string is empty + @Description Returns true if the string is empty + *************************************************************************/ + bool empty() const; + + // const_iterator end() const; + // iterator end(); + + //iterator erase(iterator _First, iterator _Last); + //iterator erase(iterator _It); + + /*!*********************************************************************** + @Function erase + @Input _Pos The position to start erasing from + @Input _Count Number of chars to erase + @Returns An updated string + @Description Erases a portion of the string + *************************************************************************/ + CPVRTString& erase(size_t _Pos = 0, size_t _Count = npos); + + /*!*********************************************************************** + @Function substitute + @Input _src Character to search + @Input _subDes Character to substitute for + @Input _all Substitute all + @Returns An updated string + @Description Erases a portion of the string + *************************************************************************/ + CPVRTString& substitute(char _src,char _subDes, bool _all = true); + + /*!*********************************************************************** + @Function substitute + @Input _src Character to search + @Input _subDes Character to substitute for + @Input _all Substitute all + @Returns An updated string + @Description Erases a portion of the string + *************************************************************************/ + CPVRTString& substitute(const char* _src, const char* _subDes, bool _all = true); + + //size_t find(char _Ch, size_t _Off = 0) const; + //size_t find(const char* _Ptr, size_t _Off = 0) const; + + /*!*********************************************************************** + @Function find + @Input _Ptr String to search. + @Input _Off Offset to search from. + @Input _Count Number of characters in this string. + @Returns Position of the first matched string. + @Description Finds a substring within this string. + *************************************************************************/ + size_t find(const char* _Ptr, size_t _Off, size_t _Count) const; + + /*!*********************************************************************** + @Function find + @Input _Str String to search. + @Input _Off Offset to search from. + @Returns Position of the first matched string. + @Description Finds a substring within this string. + *************************************************************************/ + size_t find(const CPVRTString& _Str, size_t _Off = 0) const; + + /*!*********************************************************************** + @Function find_first_not_of + @Input _Ch A char + @Input _Off Start position of the find + @Returns Position of the first char that is not _Ch + @Description Returns the position of the first char that is not _Ch + *************************************************************************/ + size_t find_first_not_of(char _Ch, size_t _Off = 0) const; + + /*!*********************************************************************** + @Function find_first_not_of + @Input _Ptr A string + @Input _Off Start position of the find + @Returns Position of the first char that is not in _Ptr + @Description Returns the position of the first char that is not in _Ptr + *************************************************************************/ + size_t find_first_not_of(const char* _Ptr, size_t _Off = 0) const; + + /*!*********************************************************************** + @Function find_first_not_of + @Input _Ptr A string + @Input _Off Start position of the find + @Input _Count Number of chars in _Ptr + @Returns Position of the first char that is not in _Ptr + @Description Returns the position of the first char that is not in _Ptr + *************************************************************************/ + size_t find_first_not_of(const char* _Ptr, size_t _Off, size_t _Count) const; + + /*!*********************************************************************** + @Function find_first_not_of + @Input _Str A string + @Input _Off Start position of the find + @Returns Position of the first char that is not in _Str + @Description Returns the position of the first char that is not in _Str + *************************************************************************/ + size_t find_first_not_of(const CPVRTString& _Str, size_t _Off = 0) const; + + /*!*********************************************************************** + @Function find_first_of + @Input _Ch A char + @Input _Off Start position of the find + @Returns Position of the first char that is _Ch + @Description Returns the position of the first char that is _Ch + *************************************************************************/ + size_t find_first_of(char _Ch, size_t _Off = 0) const; + + /*!*********************************************************************** + @Function find_first_of + @Input _Ptr A string + @Input _Off Start position of the find + @Returns Position of the first char that matches a char in _Ptr + @Description Returns the position of the first char that matches a char in _Ptr + *************************************************************************/ + size_t find_first_of(const char* _Ptr, size_t _Off = 0) const; + + /*!*********************************************************************** + @Function find_first_of + @Input _Ptr A string + @Input _Off Start position of the find + @Input _Count Size of _Ptr + @Returns Position of the first char that matches a char in _Ptr + @Description Returns the position of the first char that matches a char in _Ptr + *************************************************************************/ + size_t find_first_of(const char* _Ptr, size_t _Off, size_t _Count) const; + + /*!*********************************************************************** + @Function find_first_ofn + @Input _Ptr A string + @Input _Off Start position of the find + @Input _Count Size of _Ptr + @Returns Position of the first char that matches a char in _Ptr + @Description Returns the position of the first char that matches all chars in _Ptr + *************************************************************************/ + size_t find_first_ofn(const char* _Ptr, size_t _Off, size_t _Count) const; + + + /*!*********************************************************************** + @Function find_first_of + @Input _Str A string + @Input _Off Start position of the find + @Returns Position of the first char that matches a char in _Str + @Description Returns the position of the first char that matches a char in _Str + *************************************************************************/ + size_t find_first_of(const CPVRTString& _Str, size_t _Off = 0) const; + + /*!*********************************************************************** + @Function find_last_not_of + @Input _Ch A char + @Input _Off Start position of the find + @Returns Position of the last char that is not _Ch + @Description Returns the position of the last char that is not _Ch + *************************************************************************/ + size_t find_last_not_of(char _Ch, size_t _Off = 0) const; + + /*!*********************************************************************** + @Function find_last_not_of + @Input _Ptr A string + @Input _Off Start position of the find + @Returns Position of the last char that is not in _Ptr + @Description Returns the position of the last char that is not in _Ptr + *************************************************************************/ + size_t find_last_not_of(const char* _Ptr, size_t _Off = 0) const; + + /*!*********************************************************************** + @Function find_last_not_of + @Input _Ptr A string + @Input _Off Start position of the find + @Input _Count Length of _Ptr + @Returns Position of the last char that is not in _Ptr + @Description Returns the position of the last char that is not in _Ptr + *************************************************************************/ + size_t find_last_not_of(const char* _Ptr, size_t _Off, size_t _Count) const; + + /*!*********************************************************************** + @Function find_last_not_of + @Input _Str A string + @Input _Off Start position of the find + @Returns Position of the last char that is not in _Str + @Description Returns the position of the last char that is not in _Str + *************************************************************************/ + size_t find_last_not_of(const CPVRTString& _Str, size_t _Off = 0) const; + + /*!*********************************************************************** + @Function find_last_of + @Input _Ch A char + @Input _Off Start position of the find + @Returns Position of the last char that is _Ch + @Description Returns the position of the last char that is _Ch + *************************************************************************/ + size_t find_last_of(char _Ch, size_t _Off = 0) const; + + /*!*********************************************************************** + @Function find_last_of + @Input _Ptr A string + @Input _Off Start position of the find + @Returns Position of the last char that is in _Ptr + @Description Returns the position of the last char that is in _Ptr + *************************************************************************/ + size_t find_last_of(const char* _Ptr, size_t _Off = 0) const; + + /*!*********************************************************************** + @Function find_last_of + @Input _Ptr A string + @Input _Off Start position of the find + @Input _Count Length of _Ptr + @Returns Position of the last char that is in _Ptr + @Description Returns the position of the last char that is in _Ptr + *************************************************************************/ + size_t find_last_of(const char* _Ptr, size_t _Off, size_t _Count) const; + + /*!*********************************************************************** + @Function find_last_of + @Input _Str A string + @Input _Off Start position of the find + @Returns Position of the last char that is in _Str + @Description Returns the position of the last char that is in _Str + *************************************************************************/ + size_t find_last_of(const CPVRTString& _Str, size_t _Off = 0) const; + + /*!*********************************************************************** + @Function find_number_of + @Input _Ch A char + @Input _Off Start position of the find + @Returns Number of occurances of _Ch in the parent string. + @Description Returns the number of occurances of _Ch in the parent string. + *************************************************************************/ + size_t find_number_of(char _Ch, size_t _Off = 0) const; + + /*!*********************************************************************** + @Function find_number_of + @Input _Ptr A string + @Input _Off Start position of the find + @Returns Number of occurances of _Ptr in the parent string. + @Description Returns the number of occurances of _Ptr in the parent string. + *************************************************************************/ + size_t find_number_of(const char* _Ptr, size_t _Off = 0) const; + + /*!*********************************************************************** + @Function find_number_of + @Input _Ptr A string + @Input _Off Start position of the find + @Input _Count Size of _Ptr + @Returns Number of occurances of _Ptr in the parent string. + @Description Returns the number of occurances of _Ptr in the parent string. + *************************************************************************/ + size_t find_number_of(const char* _Ptr, size_t _Off, size_t _Count) const; + + /*!*********************************************************************** + @Function find_number_of + @Input _Str A string + @Input _Off Start position of the find + @Returns Number of occurances of _Str in the parent string. + @Description Returns the number of occurances of _Str in the parent string. + *************************************************************************/ + size_t find_number_of(const CPVRTString& _Str, size_t _Off = 0) const; + + /*!*********************************************************************** + @Function find_next_occurance_of + @Input _Ch A char + @Input _Off Start position of the find + @Returns Next occurance of _Ch in the parent string. + @Description Returns the next occurance of _Ch in the parent string + after or at _Off. If not found, returns the length of the string. + *************************************************************************/ + int find_next_occurance_of(char _Ch, size_t _Off = 0) const; + + /*!*********************************************************************** + @Function find_next_occurance_of + @Input _Ptr A string + @Input _Off Start position of the find + @Returns Next occurance of _Ptr in the parent string. + @Description Returns the next occurance of _Ptr in the parent string + after or at _Off. If not found, returns the length of the string. + *************************************************************************/ + int find_next_occurance_of(const char* _Ptr, size_t _Off = 0) const; + + /*!*********************************************************************** + @Function find_next_occurance_of + @Input _Ptr A string + @Input _Off Start position of the find + @Input _Count Size of _Ptr + @Returns Next occurance of _Ptr in the parent string. + @Description Returns the next occurance of _Ptr in the parent string + after or at _Off. If not found, returns the length of the string. + *************************************************************************/ + int find_next_occurance_of(const char* _Ptr, size_t _Off, size_t _Count) const; + + /*!*********************************************************************** + @Function find_next_occurance_of + @Input _Str A string + @Input _Off Start position of the find + @Returns Next occurance of _Str in the parent string. + @Description Returns the next occurance of _Str in the parent string + after or at _Off. If not found, returns the length of the string. + *************************************************************************/ + int find_next_occurance_of(const CPVRTString& _Str, size_t _Off = 0) const; + + /*!*********************************************************************** + @Function find_previous_occurance_of + @Input _Ch A char + @Input _Off Start position of the find + @Returns Previous occurance of _Ch in the parent string. + @Description Returns the previous occurance of _Ch in the parent string + before _Off. If not found, returns -1. + *************************************************************************/ + int find_previous_occurance_of(char _Ch, size_t _Off = 0) const; + + /*!*********************************************************************** + @Function find_previous_occurance_of + @Input _Ptr A string + @Input _Off Start position of the find + @Returns Previous occurance of _Ptr in the parent string. + @Description Returns the previous occurance of _Ptr in the parent string + before _Off. If not found, returns -1. + *************************************************************************/ + int find_previous_occurance_of(const char* _Ptr, size_t _Off = 0) const; + + /*!*********************************************************************** + @Function find_previous_occurance_of + @Input _Ptr A string + @Input _Off Start position of the find + @Input _Count Size of _Ptr + @Returns Previous occurance of _Ptr in the parent string. + @Description Returns the previous occurance of _Ptr in the parent string + before _Off. If not found, returns -1. + *************************************************************************/ + int find_previous_occurance_of(const char* _Ptr, size_t _Off, size_t _Count) const; + + /*!*********************************************************************** + @Function find_previous_occurance_of + @Input _Str A string + @Input _Off Start position of the find + @Returns Previous occurance of _Str in the parent string. + @Description Returns the previous occurance of _Str in the parent string + before _Off. If not found, returns -1. + *************************************************************************/ + int find_previous_occurance_of(const CPVRTString& _Str, size_t _Off = 0) const; + + /*!*********************************************************************** + @Function left + @Input iSize number of characters to return (excluding null character) + @Returns The leftmost 'iSize' characters of the string. + @Description Returns the leftmost characters of the string (excluding + the null character) in a new CPVRTString. If iSize is + larger than the string, a copy of the original string is returned. + *************************************************************************/ + CPVRTString left(size_t iSize) const; + + /*!*********************************************************************** + @Function right + @Input iSize number of characters to return (excluding null character) + @Returns The rightmost 'iSize' characters of the string. + @Description Returns the rightmost characters of the string (excluding + the null character) in a new CPVRTString. If iSize is + larger than the string, a copy of the original string is returned. + *************************************************************************/ + CPVRTString right(size_t iSize) const; + + //allocator_type get_allocator( ) const; + + //CPVRTString& insert(size_t _P0, const char* _Ptr); + //CPVRTString& insert(size_t _P0, const char* _Ptr, size_t _Count); + //CPVRTString& insert(size_t _P0, const CPVRTString& _Str); + //CPVRTString& insert(size_t _P0, const CPVRTString& _Str, size_t _Off, size_t _Count); + //CPVRTString& insert(size_t _P0, size_t _Count, char _Ch); + //iterator insert(iterator _It, char _Ch = char()); + //template void insert(iterator _It, InputIterator _First, InputIterator _Last); + //void insert(iterator _It, size_t _Count, char _Ch); + + /*!*********************************************************************** + @Function length + @Returns Length of the string + @Description Returns the length of the string + *************************************************************************/ + size_t length() const; + + /*!*********************************************************************** + @Function max_size + @Returns The maximum number of chars that the string can contain + @Description Returns the maximum number of chars that the string can contain + *************************************************************************/ + size_t max_size() const; + + /*!*********************************************************************** + @Function push_back + @Input _Ch A char to append + @Description Appends _Ch to the string + *************************************************************************/ + void push_back(char _Ch); + + // const_reverse_iterator rbegin() const; + // reverse_iterator rbegin(); + + // const_reverse_iterator rend() const; + // reverse_iterator rend(); + + //CPVRTString& replace(size_t _Pos1, size_t _Num1, const char* _Ptr); + //CPVRTString& replace(size_t _Pos1, size_t _Num1, const CPVRTString& _Str); + //CPVRTString& replace(size_t _Pos1, size_t _Num1, const char* _Ptr, size_t _Num2); + //CPVRTString& replace(size_t _Pos1, size_t _Num1, const CPVRTString& _Str, size_t _Pos2, size_t _Num2); + //CPVRTString& replace(size_t _Pos1, size_t _Num1, size_t _Count, char _Ch); + + //CPVRTString& replace(iterator _First0, iterator _Last0, const char* _Ptr); + //CPVRTString& replace(iterator _First0, iterator _Last0, const CPVRTString& _Str); + //CPVRTString& replace(iterator _First0, iterator _Last0, const char* _Ptr, size_t _Num2); + //CPVRTString& replace(iterator _First0, iterator _Last0, size_t _Num2, char _Ch); + //template CPVRTString& replace(iterator _First0, iterator _Last0, InputIterator _First, InputIterator _Last); + + /*!*********************************************************************** + @Function reserve + @Input _Count Size of string to reserve + @Description Reserves space for _Count number of chars + *************************************************************************/ + void reserve(size_t _Count = 0); + + /*!*********************************************************************** + @Function resize + @Input _Count Size of string to resize to + @Input _Ch Character to use to fill any additional space + @Description Resizes the string to _Count in length + *************************************************************************/ + void resize(size_t _Count, char _Ch = char()); + + //size_t rfind(char _Ch, size_t _Off = npos) const; + //size_t rfind(const char* _Ptr, size_t _Off = npos) const; + //size_t rfind(const char* _Ptr, size_t _Off = npos, size_t _Count) const; + //size_t rfind(const CPVRTString& _Str, size_t _Off = npos) const; + + /*!*********************************************************************** + @Function size + @Returns Size of the string + @Description Returns the size of the string + *************************************************************************/ + size_t size() const; + + /*!*********************************************************************** + @Function substr + @Input _Off Start of the substring + @Input _Count Length of the substring + @Returns A substring of the string + @Description Returns the size of the string + *************************************************************************/ + CPVRTString substr(size_t _Off = 0, size_t _Count = npos) const; + + /*!*********************************************************************** + @Function swap + @Input _Str A string to swap with + @Description Swaps the contents of the string with _Str + *************************************************************************/ + void swap(CPVRTString& _Str); + + /*!*********************************************************************** + @Function toLower + @Returns An updated string + @Description Converts the string to lower case + *************************************************************************/ + CPVRTString& toLower(); + + /*!*********************************************************************** + @Function toUpper + @Returns An updated string + @Description Converts the string to upper case + *************************************************************************/ + CPVRTString& toUpper(); + + /*!*********************************************************************** + @Function format + @Input pFormat A string containing the formating + @Returns A formatted string + @Description return the formatted string + ************************************************************************/ + CPVRTString format(const char *pFormat, ...); + + /*!*********************************************************************** + @Function += + @Input _Ch A char + @Returns An updated string + @Description += Operator + *************************************************************************/ + CPVRTString& operator+=(char _Ch); + + /*!*********************************************************************** + @Function += + @Input _Ptr A string + @Returns An updated string + @Description += Operator + *************************************************************************/ + CPVRTString& operator+=(const char* _Ptr); + + /*!*********************************************************************** + @Function += + @Input _Right A string + @Returns An updated string + @Description += Operator + *************************************************************************/ + CPVRTString& operator+=(const CPVRTString& _Right); + + /*!*********************************************************************** + @Function = + @Input _Ch A char + @Returns An updated string + @Description = Operator + *************************************************************************/ + CPVRTString& operator=(char _Ch); + + /*!*********************************************************************** + @Function = + @Input _Ptr A string + @Returns An updated string + @Description = Operator + *************************************************************************/ + CPVRTString& operator=(const char* _Ptr); + + /*!*********************************************************************** + @Function = + @Input _Right A string + @Returns An updated string + @Description = Operator + *************************************************************************/ + CPVRTString& operator=(const CPVRTString& _Right); + + /*!*********************************************************************** + @Function [] + @Input _Off An index into the string + @Returns A character + @Description [] Operator + *************************************************************************/ + const_reference operator[](size_t _Off) const; + + /*!*********************************************************************** + @Function [] + @Input _Off An index into the string + @Returns A character + @Description [] Operator + *************************************************************************/ + reference operator[](size_t _Off); + + /*!*********************************************************************** + @Function + + @Input _Left A string + @Input _Right A string + @Returns An updated string + @Description + Operator + *************************************************************************/ + friend CPVRTString operator+ (const CPVRTString& _Left, const CPVRTString& _Right); + + /*!*********************************************************************** + @Function + + @Input _Left A string + @Input _Right A string + @Returns An updated string + @Description + Operator + *************************************************************************/ + friend CPVRTString operator+ (const CPVRTString& _Left, const char* _Right); + + /*!*********************************************************************** + @Function + + @Input _Left A string + @Input _Right A string + @Returns An updated string + @Description + Operator + *************************************************************************/ + friend CPVRTString operator+ (const CPVRTString& _Left, const char _Right); + + /*!*********************************************************************** + @Function + + @Input _Left A string + @Input _Right A string + @Returns An updated string + @Description + Operator + *************************************************************************/ + friend CPVRTString operator+ (const char* _Left, const CPVRTString& _Right); + + + /*!*********************************************************************** + @Function + + @Input _Left A string + @Input _Right A string + @Returns An updated string + @Description + Operator + *************************************************************************/ + friend CPVRTString operator+ (const char _Left, const CPVRTString& _Right); + +protected: + char* m_pString; + size_t m_Size; + size_t m_Capacity; +}; + +/************************************************************************* +* MISCELLANEOUS UTILITY FUNCTIONS +*************************************************************************/ +/*!*********************************************************************** +@Function PVRTStringGetFileExtension +@Input strFilePath A string +@Returns Extension +@Description Extracts the file extension from a file path. +Returns an empty CPVRTString if no extension is found. +************************************************************************/ +CPVRTString PVRTStringGetFileExtension(const CPVRTString& strFilePath); + +/*!*********************************************************************** +@Function PVRTStringGetContainingDirectoryPath +@Input strFilePath A string +@Returns Directory +@Description Extracts the directory portion from a file path. +************************************************************************/ +CPVRTString PVRTStringGetContainingDirectoryPath(const CPVRTString& strFilePath); + +/*!*********************************************************************** +@Function PVRTStringGetFileName +@Input strFilePath A string +@Returns FileName +@Description Extracts the name and extension portion from a file path. +************************************************************************/ +CPVRTString PVRTStringGetFileName(const CPVRTString& strFilePath); + +/*!*********************************************************************** +@Function PVRTStringStripWhiteSpaceFromStartOf +@Input strLine A string +@Returns Result of the white space stripping +@Description strips white space characters from the beginning of a CPVRTString. +************************************************************************/ +CPVRTString PVRTStringStripWhiteSpaceFromStartOf(const CPVRTString& strLine); + +/*!*********************************************************************** +@Function PVRTStringStripWhiteSpaceFromEndOf +@Input strLine A string +@Returns Result of the white space stripping +@Description strips white space characters from the end of a CPVRTString. +************************************************************************/ +CPVRTString PVRTStringStripWhiteSpaceFromEndOf(const CPVRTString& strLine); + +/*!*********************************************************************** +@Function PVRTStringFromFormattedStr +@Input pFormat A string containing the formating +@Returns A formatted string +@Description Creates a formatted string +************************************************************************/ +CPVRTString PVRTStringFromFormattedStr(const char *pFormat, ...); + +#endif // _PVRTSTRING_H_ + + +/***************************************************************************** +End of file (PVRTString.h) +*****************************************************************************/ + diff --git a/KREngine/3rdparty/pvrtexlib/include/PVRTTexture.h b/KREngine/3rdparty/pvrtexlib/include/PVRTTexture.h new file mode 100644 index 0000000..114549f --- /dev/null +++ b/KREngine/3rdparty/pvrtexlib/include/PVRTTexture.h @@ -0,0 +1,700 @@ +/****************************************************************************** + + @File PVRTTexture.h + + @Title PVRTTexture + + @Version + + @Copyright Copyright (c) Imagination Technologies Limited. + + @Platform ANSI compatible + + @Description Texture loading. + +******************************************************************************/ +#ifndef _PVRTTEXTURE_H_ +#define _PVRTTEXTURE_H_ + +#include "PVRTGlobal.h" + +/***************************************************************************** +* Texture related constants and enumerations. +*****************************************************************************/ +// V3 Header Identifiers. +const PVRTuint32 PVRTEX3_IDENT = 0x03525650; // 'P''V''R'3 +const PVRTuint32 PVRTEX3_IDENT_REV = 0x50565203; +// If endianness is backwards then PVR3 will read as 3RVP, hence why it is written as an int. + +//Current version texture identifiers +const PVRTuint32 PVRTEX_CURR_IDENT = PVRTEX3_IDENT; +const PVRTuint32 PVRTEX_CURR_IDENT_REV = PVRTEX3_IDENT_REV; + +// PVR Header file flags. Condition if true. If false, opposite is true unless specified. +const PVRTuint32 PVRTEX3_FILE_COMPRESSED = (1<<0); // Texture has been file compressed using PVRTexLib (currently unused) +const PVRTuint32 PVRTEX3_PREMULTIPLIED = (1<<1); // Texture has been premultiplied by alpha value. + +// Mip Map level specifier constants. Other levels are specified by 1,2...n +const PVRTint32 PVRTEX_TOPMIPLEVEL = 0; +const PVRTint32 PVRTEX_ALLMIPLEVELS = -1; //This is a special number used simply to return a total of all MIP levels when dealing with data sizes. + +//values for each meta data type that we know about. Texture arrays hinge on each surface being identical in all but content, including meta data. +//If the meta data varies even slightly then a new texture should be used. It is possible to write your own extension to get around this however. +enum EPVRTMetaData +{ + ePVRTMetaDataTextureAtlasCoords=0, + ePVRTMetaDataBumpData, + ePVRTMetaDataCubeMapOrder, + ePVRTMetaDataTextureOrientation, + ePVRTMetaDataBorderData, + ePVRTMetaDataPadding, + ePVRTMetaDataNumMetaDataTypes +}; + +enum EPVRTAxis +{ + ePVRTAxisX = 0, + ePVRTAxisY = 1, + ePVRTAxisZ = 2 +}; + +enum EPVRTOrientation +{ + ePVRTOrientLeft = 1< +class CPVRTMap; + + +/*!*********************************************************************** + @Function PVRTGetBitsPerPixel + @Input u64PixelFormat A PVR Pixel Format ID. + @Return const PVRTuint32 Number of bits per pixel. + @Description Returns the number of bits per pixel in a PVR Pixel Format + identifier. +*************************************************************************/ +PVRTuint32 PVRTGetBitsPerPixel(PVRTuint64 u64PixelFormat); + +/*!*********************************************************************** + @Function PVRTGetFormatMinDims + @Input u64PixelFormat A PVR Pixel Format ID. + @Modified minX Returns the minimum width. + @Modified minY Returns the minimum height. + @Modified minZ Returns the minimum depth. + @Description Gets the minimum dimensions (x,y,z) for a given pixel format. +*************************************************************************/ +void PVRTGetFormatMinDims(PVRTuint64 u64PixelFormat, PVRTuint32 &minX, PVRTuint32 &minY, PVRTuint32 &minZ); + +/*!*********************************************************************** + @Function PVRTConvertOldTextureHeaderToV3 + @Input LegacyHeader Legacy header for conversion. + @Modified NewHeader New header to output into. + @Modified pMetaData MetaData Map to output into. + @Description Converts a legacy texture header (V1 or V2) to a current + generation header (V3) +*************************************************************************/ +void PVRTConvertOldTextureHeaderToV3(const PVR_Texture_Header* LegacyHeader, PVRTextureHeaderV3& NewHeader, CPVRTMap >* pMetaData); + +/*!*********************************************************************** + @Function PVRTMapLegacyTextureEnumToNewFormat + @Input OldFormat Legacy Enumeration Value + @Modified newType New PixelType identifier. + @Modified newCSpace New ColourSpace + @Modified newChanType New Channel Type + @Modified isPreMult Whether format is pre-multiplied + @Description Maps a legacy enumeration value to the new PVR3 style format. +*************************************************************************/ +void PVRTMapLegacyTextureEnumToNewFormat(PVRTPixelType OldFormat, PVRTuint64& newType, EPVRTColourSpace& newCSpace, EPVRTVariableType& newChanType, bool& isPreMult); + +/*!*************************************************************************** +@Function PVRTTextureLoadTiled +@Modified pDst Texture to place the tiled data +@Input nWidthDst Width of destination texture +@Input nHeightDst Height of destination texture +@Input pSrc Texture to tile +@Input nWidthSrc Width of source texture +@Input nHeightSrc Height of source texture +@Input nElementSize Bytes per pixel +@Input bTwiddled True if the data is twiddled +@Description Needed by PVRTTextureTile() in the various PVRTTextureAPIs +*****************************************************************************/ +void PVRTTextureLoadTiled( + PVRTuint8 * const pDst, + const unsigned int nWidthDst, + const unsigned int nHeightDst, + const PVRTuint8 * const pSrc, + const unsigned int nWidthSrc, + const unsigned int nHeightSrc, + const unsigned int nElementSize, + const bool bTwiddled); + + +/*!*************************************************************************** +@Function PVRTTextureTwiddle +@Output a Twiddled value +@Input u Coordinate axis 0 +@Input v Coordinate axis 1 +@Description Combine a 2D coordinate into a twiddled value +*****************************************************************************/ +void PVRTTextureTwiddle(unsigned int &a, const unsigned int u, const unsigned int v); + +/*!*************************************************************************** +@Function PVRTTextureDeTwiddle +@Output u Coordinate axis 0 +@Output v Coordinate axis 1 +@Input a Twiddled value +@Description Extract 2D coordinates from a twiddled value. +*****************************************************************************/ +void PVRTTextureDeTwiddle(unsigned int &u, unsigned int &v, const unsigned int a); + +/*!*********************************************************************** +@Function PVRTGetTextureDataSize +@Input sTextureHeader Specifies the texture header. +@Input iMipLevel Specifies a mip level to check, 'PVRTEX_ALLMIPLEVELS' + can be passed to get the size of all MIP levels. +@Input bAllSurfaces Size of all surfaces is calculated if true, + only a single surface if false. +@Input bAllFaces Size of all faces is calculated if true, + only a single face if false. +@Return PVRTuint32 Size in BYTES of the specified texture area. +@Description Gets the size in BYTES of the texture, given various input + parameters. User can retrieve the size of either all + surfaces or a single surface, all faces or a single face and + all MIP-Maps or a single specified MIP level. +*************************************************************************/ +PVRTuint32 PVRTGetTextureDataSize(PVRTextureHeaderV3 sTextureHeader, PVRTint32 iMipLevel=PVRTEX_ALLMIPLEVELS, bool bAllSurfaces = true, bool bAllFaces = true); + +#endif /* _PVRTTEXTURE_H_ */ + +/***************************************************************************** +End of file (PVRTTexture.h) +*****************************************************************************/ + diff --git a/KREngine/3rdparty/pvrtexlib/include/PVRTexture.h b/KREngine/3rdparty/pvrtexlib/include/PVRTexture.h new file mode 100644 index 0000000..a03043b --- /dev/null +++ b/KREngine/3rdparty/pvrtexlib/include/PVRTexture.h @@ -0,0 +1,208 @@ +#ifndef _PVRTEXTURE_H +#define _PVRTEXTURE_H + +#include "PVRTextureDefines.h" +#include "PVRTextureHeader.h" +#include "PVRTString.h" + +namespace pvrtexture +{ + class PVR_DLL CPVRTexture : public CPVRTextureHeader + { + public: + /******************************************************************************* + * Construction methods for a texture. + *******************************************************************************/ + /*!*********************************************************************** + @Function CPVRTexture + @Return CPVRTexture A new texture. + @Description Creates a new empty texture + *************************************************************************/ + CPVRTexture(); + /*!*********************************************************************** + @Function CPVRTexture + @Input sHeader + @Input pData + @Return CPVRTexture A new texture. + @Description Creates a new texture based on a texture header, + pre-allocating the correct amount of memory. If data is + supplied, it will be copied into memory. + *************************************************************************/ + CPVRTexture(const CPVRTextureHeader& sHeader, const void* pData=NULL); + + /*!*********************************************************************** + @Function CPVRTexture + @Input szFilePath + @Return CPVRTexture A new texture. + @Description Creates a new texture from a filepath. + *************************************************************************/ + CPVRTexture(const char* szFilePath); + + /*!*********************************************************************** + @Function CPVRTexture + @Input pTexture + @Return CPVRTexture A new texture. + @Description Creates a new texture from a pointer that includes a header + structure, meta data and texture data as laid out in a file. + This functionality is primarily for user defined file loading. + Header may be any version of pvr. + *************************************************************************/ + CPVRTexture( const void* pTexture ); + + /*!*********************************************************************** + @Function CPVRTexture + @Input texture + @Return CPVRTexture A new texture + @Description Creates a new texture as a copy of another. + *************************************************************************/ + CPVRTexture(const CPVRTexture& texture); + + /*!*********************************************************************** + @Function ~CPVRTexture + @Description Deconstructor for CPVRTextures. + *************************************************************************/ + ~CPVRTexture(); + + /*!*********************************************************************** + @Function operator= + @Input rhs + @Return CPVRTexture& This texture. + @Description Will copy the contents and information of another texture into this one. + *************************************************************************/ + CPVRTexture& operator=(const CPVRTexture& rhs); + + /******************************************************************************* + * Texture accessor functions - others are inherited from CPVRTextureHeader. + *******************************************************************************/ + /*!*********************************************************************** + @Function getDataPtr + @Input uiMIPLevel + @Input uiArrayMember + @Input uiFaceNumber + @Return void* Pointer to a location in the texture. + @Description Returns a pointer into the texture's data. + It is possible to specify an offset to specific array members, + faces and MIP Map levels. + *************************************************************************/ + void* getDataPtr(uint32 uiMIPLevel = 0, uint32 uiArrayMember = 0, uint32 uiFaceNumber = 0) const; + + /*!*********************************************************************** + @Function getHeader + @Return const CPVRTextureHeader& Returns the header only for this texture. + @Description Gets the header for this texture, allowing you to create a new + texture based on this one with some changes. Useful for passing + information about a texture without passing all of its data. + *************************************************************************/ + const CPVRTextureHeader& getHeader() const; + + /******************************************************************************* + * File io. + *******************************************************************************/ + + /*!*********************************************************************** + @Function setPaddedMetaData + @Input uiPadding + @Description When writing the texture out to a PVR file, it is often + desirable to pad the meta data so that the start of the + texture data aligns to a given boundary. + This function pads to a boundary value equal to "uiPadding". + For example setting uiPadding=8 will align the start of the + texture data to an 8 byte boundary. + Note - this should be called immediately before saving as + the value is worked out based on the current meta data size. + *************************************************************************/ + void addPaddingMetaData( uint32 uiPadding ); + + /*!*********************************************************************** + @Function saveFile + @Input filepath + @Return bool Whether the method succeeds or not. + @Description Writes out to a file, given a filename and path. + File type will be determined by the extension present in the string. + If no extension is present, PVR format will be selected. + Unsupported formats will result in failure. + *************************************************************************/ + bool saveFile(const CPVRTString& filepath) const; + + /*!*********************************************************************** + @Function saveFileLegacyPVR + @Input filepath + @Input eApi + @Return bool Whether the method succeeds or not. + @Description Writes out to a file, stripping any extensions specified + and appending .pvr. This function is for legacy support only + and saves out to PVR Version 2 file. The target api must be + specified in order to save to this format. + *************************************************************************/ + bool saveFileLegacyPVR(const CPVRTString& filepath, ELegacyApi eApi) const; + + private: + size_t m_stDataSize; // Size of the texture data. + uint8* m_pTextureData; // Pointer to texture data. + + /******************************************************************************* + * Private IO functions + *******************************************************************************/ + /*!*********************************************************************** + @Function loadPVRFile + @Input pTextureFile + @Description Loads a PVR file. + *************************************************************************/ + bool privateLoadPVRFile(FILE* pTextureFile); + + /*!*********************************************************************** + @Function privateSavePVRFile + @Input pTextureFile + @Description Saves a PVR File. + *************************************************************************/ + bool privateSavePVRFile(FILE* pTextureFile) const; + + /*!*********************************************************************** + @Function loadKTXFile + @Input pTextureFile + @Description Loads a KTX file. + *************************************************************************/ + bool privateLoadKTXFile(FILE* pTextureFile); + + /*!*********************************************************************** + @Function privateSaveKTXFile + @Input pTextureFile + @Description Saves a KTX File. + *************************************************************************/ + bool privateSaveKTXFile(FILE* pTextureFile) const; + + /*!*********************************************************************** + @Function loadDDSFile + @Input pTextureFile + @Description Loads a DDS file. + *************************************************************************/ + bool privateLoadDDSFile(FILE* pTextureFile); + + /*!*********************************************************************** + @Function privateSaveDDSFile + @Input pTextureFile + @Description Saves a DDS File. + *************************************************************************/ + bool privateSaveDDSFile(FILE* pTextureFile) const; + + //Legacy IO + /*!*********************************************************************** + @Function privateSavePVRFile + @Input pTextureFile + @Input filename + @Description Saves a .h File. + *************************************************************************/ + bool privateSaveCHeaderFile(FILE* pTextureFile, CPVRTString filename) const; + + /*!*********************************************************************** + @Function privateSaveLegacyPVRFile + @Input pTextureFile + @Input eApi + @Description Saves a legacy PVR File - Uses version 2 file format. + *************************************************************************/ + bool privateSaveLegacyPVRFile(FILE* pTextureFile, ELegacyApi eApi) const; + }; +}; + +#endif //_PVRTEXTURE_H + diff --git a/KREngine/3rdparty/pvrtexlib/include/PVRTextureDefines.h b/KREngine/3rdparty/pvrtexlib/include/PVRTextureDefines.h new file mode 100644 index 0000000..cadbd25 --- /dev/null +++ b/KREngine/3rdparty/pvrtexlib/include/PVRTextureDefines.h @@ -0,0 +1,98 @@ +#ifndef _PVRTEXTURE_DEFINES_H +#define _PVRTEXTURE_DEFINES_H + +//To use the PVRTexLib .dll on Windows, you need to define _WINDLL_IMPORT +#ifndef PVR_DLL +#if defined(_WINDLL_EXPORT) +#define PVR_DLL __declspec(dllexport) +//Forward declaration of various classes/structs used by this library. This exports their interfaces for DLLs. +struct PVR_DLL PVRTextureHeaderV3; +struct PVR_DLL MetaDataBlock; +template +class PVR_DLL CPVRTMap; +template +class PVR_DLL CPVRTArray; +class PVR_DLL CPVRTString; +#elif defined(_WINDLL_IMPORT) +#define PVR_DLL __declspec(dllimport) +//Forward declaration of various classes/structs used by this library. This imports their interfaces for DLLs. +struct PVR_DLL PVRTextureHeaderV3; +struct PVR_DLL MetaDataBlock; +template +class PVR_DLL CPVRTMap; +template +class PVR_DLL CPVRTArray; +class PVR_DLL CPVRTString; +#else +#define PVR_DLL +#endif +#endif + + +#include "PVRTTexture.h" + +namespace pvrtexture +{ + /***************************************************************************** + * Type defines for standard variable sizes. + *****************************************************************************/ + typedef signed char int8; + typedef signed short int16; + typedef signed int int32; + typedef signed long long int64; + typedef unsigned char uint8; + typedef unsigned short uint16; + typedef unsigned int uint32; + typedef unsigned long long uint64; + + /***************************************************************************** + * Texture related constants and enumerations. + *****************************************************************************/ + enum ECompressorQuality + { + ePVRTCFast=0, + ePVRTCNormal, + ePVRTCHigh, + ePVRTCBest, + eNumPVRTCModes, + + eETCFast=0, + eETCFastPerceptual, + eETCSlow, + eETCSlowPerceptual, + eNumETCModes + }; + + enum EResizeMode + { + eResizeNearest, + eResizeLinear, + eResizeCubic, + eNumResizeModes + }; + + // Legacy - API enums. + enum ELegacyApi + { + eOGLES=1, + eOGLES2, + eD3DM, + eOGL, + eDX9, + eDX10, + eOVG, + eMGL, + }; + + /***************************************************************************** + * Useful macros. + *****************************************************************************/ + #define TEXOFFSET2D(x,y,width) ( ((x)+(y)*(width)) ) + #define TEXOFFSET3D(x,y,z,width,height) ( ((x)+(y)*(width)+(z)*(width)*(height)) ) + + /***************************************************************************** + * Useful typedef for Meta Data Maps + *****************************************************************************/ + typedef CPVRTMap > MetaDataMap; +}; +#endif //_PVRTEXTURE_DEFINES_H diff --git a/KREngine/3rdparty/pvrtexlib/include/PVRTextureFormat.h b/KREngine/3rdparty/pvrtexlib/include/PVRTextureFormat.h new file mode 100644 index 0000000..48627ec --- /dev/null +++ b/KREngine/3rdparty/pvrtexlib/include/PVRTextureFormat.h @@ -0,0 +1,73 @@ +#ifndef _PVRT_PIXEL_FORMAT_H +#define _PVRT_PIXEL_FORMAT_H + +#include "PVRTextureDefines.h" +#include "PVRTString.h" + +namespace pvrtexture +{ + //Channel Names + enum EChannelName + { + eNoChannel, + eRed, + eGreen, + eBlue, + eAlpha, + eLuminance, + eIntensity, + eUnspecified, + eNumChannels + }; + + //PixelType union + union PVR_DLL PixelType + { + /*!*********************************************************************** + @Function PixelType + @Return A new PixelType + @Description Creates an empty pixeltype. + *************************************************************************/ + PixelType(); + + /*!*********************************************************************** + @Function PixelType + @Input Type + @Return A new PixelType + @Description Initialises a new pixel type from a 64 bit integer value. + *************************************************************************/ + PixelType(uint64 Type); + + /*!*********************************************************************** + @Function PixelType + @Input C1Name + @Input C2Name + @Input C3Name + @Input C4Name + @Input C1Bits + @Input C2Bits + @Input C3Bits + @Input C4Bits + @Return A new PixelType + @Description Takes up to 4 characters (CnName) and 4 values (CnBits) + to create a new PixelType. Any unused channels should be set to 0. + For example: PixelType('r','g','b',0,8,8,8,0); + *************************************************************************/ + PixelType(uint8 C1Name, uint8 C2Name, uint8 C3Name, uint8 C4Name, uint8 C1Bits, uint8 C2Bits, uint8 C3Bits, uint8 C4Bits); + + struct PVR_DLL LowHigh + { + uint32 Low; + uint32 High; + } Part; + + uint64 PixelTypeID; + uint8 PixelTypeChar[8]; + }; + + static const PixelType PVRStandard8PixelType = PixelType('r','g','b','a',8,8,8,8); + static const PixelType PVRStandard16PixelType = PixelType('r','g','b','a',16,16,16,16); + static const PixelType PVRStandard32PixelType = PixelType('r','g','b','a',32,32,32,32); +} + +#endif diff --git a/KREngine/3rdparty/pvrtexlib/include/PVRTextureHeader.h b/KREngine/3rdparty/pvrtexlib/include/PVRTextureHeader.h new file mode 100644 index 0000000..52e318c --- /dev/null +++ b/KREngine/3rdparty/pvrtexlib/include/PVRTextureHeader.h @@ -0,0 +1,586 @@ +#ifndef _PVRTEXTURE_HEADER_H +#define _PVRTEXTURE_HEADER_H + +#include "PVRTextureDefines.h" +#include "PVRTextureFormat.h" +#include "PVRTString.h" +#include "PVRTMap.h" + +namespace pvrtexture +{ + //Wrapper class for PVRTextureHeaderV3, adds 'smart' accessor functions. + class PVR_DLL CPVRTextureHeader + { + protected: + PVRTextureHeaderV3 m_sHeader; //Texture header as laid out in a file. + CPVRTMap > m_MetaData; //Map of all the meta data stored for a texture. + + public: + /******************************************************************************* + * Construction methods for a texture header. + *******************************************************************************/ + /*!*********************************************************************** + @Function CPVRTextureHeader + @Return CPVRTextureHeader A new texture header. + @Description Default constructor for a CPVRTextureHeader. Returns an empty header. + *************************************************************************/ + CPVRTextureHeader(); + + /*!*********************************************************************** + @Function CPVRTextureHeader + @Input fileHeader + @Input metaDataCount + @Input metaData + @Return CPVRTextureHeader A new texture header. + @Description Creates a new texture header from a PVRTextureHeaderV3, + and appends Meta data if any is supplied. + *************************************************************************/ + CPVRTextureHeader( PVRTextureHeaderV3 fileHeader, + uint32 metaDataCount=0, + MetaDataBlock* metaData=NULL); + + /*!*********************************************************************** + @Function CPVRTextureHeader + @Input u64PixelFormat + @Input u32Height + @Input u32Width + @Input u32Depth + @Input u32NumMipMaps + @Input u32NumArrayMembers + @Input u32NumFaces + @Input eColourSpace + @Input eChannelType + @Input bPreMultiplied + @Return CPVRTextureHeader A new texture header. + @Description Creates a new texture header based on individual header + variables. + *************************************************************************/ + CPVRTextureHeader( uint64 u64PixelFormat, + uint32 u32Height=1, + uint32 u32Width=1, + uint32 u32Depth=1, + uint32 u32NumMipMaps=1, + uint32 u32NumArrayMembers=1, + uint32 u32NumFaces=1, + EPVRTColourSpace eColourSpace=ePVRTCSpacelRGB, + EPVRTVariableType eChannelType=ePVRTVarTypeUnsignedByteNorm, + bool bPreMultiplied=false); + + /*!*********************************************************************** + @Function operator= + @Input rhs + @Return CPVRTextureHeader& This header. + @Description Will copy the contents and information of another header into this one. + *************************************************************************/ + CPVRTextureHeader& operator=(const CPVRTextureHeader& rhs); + + /******************************************************************************* + * Accessor Methods for a texture's properties - getters. + *******************************************************************************/ + + /*!*********************************************************************** + @Function getFileHeader + @Return PVRTextureHeaderV3 The file header. + @Description Gets the file header structure. + *************************************************************************/ + const PVRTextureHeaderV3 getFileHeader() const; + + /*!*********************************************************************** + @Function getPixelType + @Return PixelType 64-bit pixel type ID. + @Description Gets the 64-bit pixel type ID of the texture. + *************************************************************************/ + const PixelType getPixelType() const; + + /*!*********************************************************************** + @Function getBitsPerPixel + @Return uint32 Number of bits per pixel + @Description Gets the bits per pixel of the texture format. + *************************************************************************/ + const uint32 getBitsPerPixel() const; + + /*!*********************************************************************** + @Function getColourSpace + @Return EPVRTColourSpace enum representing colour space. + @Description Returns the colour space of the texture. + *************************************************************************/ + const EPVRTColourSpace getColourSpace() const; + + /*!*********************************************************************** + @Function getChannelType + @Return EPVRTVariableType enum representing the type of the texture. + @Description Returns the variable type that the texture's data is stored in. + *************************************************************************/ + const EPVRTVariableType getChannelType() const; + + /*!*********************************************************************** + @Function getWidth + @Input uiMipLevel MIP level that user is interested in. + @Return uint32 Width of the specified MIP-Map level. + @Description Gets the width of the user specified MIP-Map + level for the texture + *************************************************************************/ + const uint32 getWidth(uint32 uiMipLevel=PVRTEX_TOPMIPLEVEL) const; + + /*!*********************************************************************** + @Function getHeight + @Input uiMipLevel MIP level that user is interested in. + @Return uint32 Height of the specified MIP-Map level. + @Description Gets the height of the user specified MIP-Map + level for the texture + *************************************************************************/ + const uint32 getHeight(uint32 uiMipLevel=PVRTEX_TOPMIPLEVEL) const; + + /*!*********************************************************************** + @Function getDepth + @Input uiMipLevel MIP level that user is interested in. + @Return Depth of the specified MIP-Map level. + @Description Gets the depth of the user specified MIP-Map + level for the texture + *************************************************************************/ + const uint32 getDepth(uint32 uiMipLevel=PVRTEX_TOPMIPLEVEL) const; + + /*!*********************************************************************** + @Function getTextureSize + @Input iMipLevel Specifies a MIP level to check, + 'PVRTEX_ALLMIPLEVELS' can be passed to get + the size of all MIP levels. + @Input bAllSurfaces Size of all surfaces is calculated if true, + only a single surface if false. + @Input bAllFaces Size of all faces is calculated if true, + only a single face if false. + @Return uint32 Size in PIXELS of the specified texture area. + @Description Gets the size in PIXELS of the texture, given various input + parameters. User can retrieve the total size of either all + surfaces or a single surface, all faces or a single face and + all MIP-Maps or a single specified MIP level. All of these + *************************************************************************/ + const uint32 getTextureSize(int32 iMipLevel=PVRTEX_ALLMIPLEVELS, bool bAllSurfaces = true, bool bAllFaces = true) const; + + /*!*********************************************************************** + @Function getDataSize + @Input iMipLevel Specifies a mip level to check, + 'PVRTEX_ALLMIPLEVELS' can be passed to get + the size of all MIP levels. + @Input bAllSurfaces Size of all surfaces is calculated if true, + only a single surface if false. + @Input bAllFaces Size of all faces is calculated if true, + only a single face if false. + @Return uint32 Size in BYTES of the specified texture area. + @Description Gets the size in BYTES of the texture, given various input + parameters. User can retrieve the size of either all + surfaces or a single surface, all faces or a single face + and all MIP-Maps or a single specified MIP level. + *************************************************************************/ + const uint32 getDataSize(int32 iMipLevel=PVRTEX_ALLMIPLEVELS, bool bAllSurfaces = true, bool bAllFaces = true) const; + + /*!*********************************************************************** + @Function getNumArrayMembers + @Return uint32 Number of array members in this texture. + @Description Gets the number of array members stored in this texture. + *************************************************************************/ + const uint32 getNumArrayMembers() const; + + /*!*********************************************************************** + @Function getNumMIPLevels + @Return uint32 Number of MIP-Map levels in this texture. + @Description Gets the number of MIP-Map levels stored in this texture. + *************************************************************************/ + const uint32 getNumMIPLevels() const; + + /*!*********************************************************************** + @Function getNumFaces + @Return uint32 Number of faces in this texture. + @Description Gets the number of faces stored in this texture. + *************************************************************************/ + const uint32 getNumFaces() const; + + /*!*********************************************************************** + @Function getOrientation + @Input axis EPVRTAxis type specifying the axis to examine. + @Return EPVRTOrientation Enum orientation of the axis. + @Description Gets the data orientation for this texture. + *************************************************************************/ + const EPVRTOrientation getOrientation(EPVRTAxis axis) const; + + /*!*********************************************************************** + @Function isFileCompressed + @Return bool True if it is file compressed. + @Description Returns whether or not the texture is compressed using + PVRTexLib's FILE compression - this is independent of + any texture compression. + *************************************************************************/ + const bool isFileCompressed() const; + + /*!*********************************************************************** + @Function isPreMultiplied + @Return bool True if texture is premultiplied. + @Description Returns whether or not the texture's colour has been + pre-multiplied by the alpha values. + *************************************************************************/ + const bool isPreMultiplied() const; + + /*!*********************************************************************** + @Function getMetaDataSize + @Return const uint32 Size, in bytes, of the meta data stored in the header. + @Description Returns the total size of the meta data stored in the header. + This includes the size of all information stored in all MetaDataBlocks. + *************************************************************************/ + const uint32 getMetaDataSize() const; + + /*!*********************************************************************** + @Function getOGLFormat + @Modified internalformat + @Modified format + @Modified type + @Description Gets the OpenGL equivalent values of internal format, format + and type for this texture. This will return any supported + OpenGL texture values, it is up to the user to decide if + these are valid for their current platform. + *************************************************************************/ + const void getOGLFormat(uint32& internalformat, uint32& format, uint32& type) const; + + /*!*********************************************************************** + @Function getOGLESFormat + @Modified internalformat + @Modified format + @Modified type + @Description Gets the OpenGLES equivalent values of internal format, + format and type for this texture. This will return any + supported OpenGLES texture values, it is up to the user + to decide if these are valid for their current platform. + *************************************************************************/ + const void getOGLESFormat(uint32& internalformat, uint32& format, uint32& type) const; + + /*!*********************************************************************** + @Function getD3DFormat + @Return const uint32 + @Description Gets the D3DFormat (up to DirectX 9 and Direct 3D Mobile) + equivalent values for this texture. This will return any + supported D3D texture formats, it is up to the user to + decide if this is valid for their current platform. + *************************************************************************/ + const uint32 getD3DFormat() const; + + /*!*********************************************************************** + @Function getDXGIFormat + @Return const uint32 + @Description Gets the DXGIFormat (DirectX 10 onward) equivalent values + for this texture. This will return any supported DX texture + formats, it is up to the user to decide if this is valid + for their current platform. + *************************************************************************/ + const uint32 getDXGIFormat() const; + + /*!*********************************************************************** + * Accessor Methods for a texture's properties - setters. + *************************************************************************/ + + /*!*********************************************************************** + @Function setPixelFormat + @Input uPixelFormat The format of the pixel. + @Description Sets the pixel format for this texture. + *************************************************************************/ + void setPixelFormat(PixelType uPixelFormat); + + /*!*********************************************************************** + @Function setColourSpace + @Input eColourSpace A colour space enum. + @Description Sets the colour space for this texture. Default is lRGB. + *************************************************************************/ + void setColourSpace(EPVRTColourSpace eColourSpace); + + /*!*********************************************************************** + @Function setChannelType + @Input eVarType A variable type enum. + @Description Sets the variable type for the channels in this texture. + *************************************************************************/ + void setChannelType(EPVRTVariableType eVarType); + + /*!*********************************************************************** + @Function setOGLFormat + @Input internalformat + @Input format + @Input type + @Return bool Whether the format is valid or not. + @Description Sets the format of the texture to PVRTexLib's internal + representation of the OGL format. + *************************************************************************/ + bool setOGLFormat(const uint32& internalformat, const uint32& format, const uint32& type); + + /*!*********************************************************************** + @Function setOGLESFormat + @Input internalformat + @Input format + @Input type + @Return bool Whether the format is valid or not. + @Description Sets the format of the texture to PVRTexLib's internal + representation of the OGLES format. + *************************************************************************/ + bool setOGLESFormat(const uint32& internalformat, const uint32& format, const uint32& type); + + /*!*********************************************************************** + @Function setD3DFormat + @Return bool Whether the format is valid or not. + @Description Sets the format of the texture to PVRTexLib's internal + representation of the D3D format. + *************************************************************************/ + bool setD3DFormat(const uint32& DWORD_D3D_FORMAT); + + /*!*********************************************************************** + @Function setDXGIFormat + @Return bool Whether the format is valid or not. + @Description Sets the format of the texture to PVRTexLib's internal + representation of the DXGI format. + *************************************************************************/ + bool setDXGIFormat(const uint32& DWORD_DXGI_FORMAT); + + /*!*********************************************************************** + @Function setWidth + @Input newWidth The new width. + @Description Sets the width. + *************************************************************************/ + void setWidth(uint32 newWidth); + + /*!*********************************************************************** + @Function setHeight + @Input newHeight The new height. + @Description Sets the height. + *************************************************************************/ + void setHeight(uint32 newHeight); + + /*!*********************************************************************** + @Function setDepth + @Input newDepth The new depth. + @Description Sets the depth. + *************************************************************************/ + void setDepth(uint32 newDepth); + + /*!*********************************************************************** + @Function setNumArrayMembers + @Input newNumMembers The new number of members in this array. + @Description Sets the depth. + *************************************************************************/ + void setNumArrayMembers(uint32 newNumMembers); + + /*!*********************************************************************** + @Function setNumMIPLevels + @Input newNumMIPLevels New number of MIP-Map levels. + @Description Sets the number of MIP-Map levels in this texture. + *************************************************************************/ + void setNumMIPLevels(uint32 newNumMIPLevels); + + /*!*********************************************************************** + @Function setNumFaces + @Input newNumFaces New number of faces for this texture. + @Description Sets the number of faces stored in this texture. + *************************************************************************/ + void setNumFaces(uint32 newNumFaces); + + /*!*********************************************************************** + @Function setOrientation + @Input eAxisOrientation Enum specifying axis and orientation. + @Description Sets the data orientation for a given axis in this texture. + *************************************************************************/ + void setOrientation(EPVRTOrientation eAxisOrientation); + + /*!*********************************************************************** + @Function setIsFileCompressed + @Input isFileCompressed Sets file compression to true/false. + @Description Sets whether or not the texture is compressed using + PVRTexLib's FILE compression - this is independent of + any texture compression. Currently unsupported. + *************************************************************************/ + void setIsFileCompressed(bool isFileCompressed); + + /*!*********************************************************************** + @Function isPreMultiplied + @Return isPreMultiplied Sets if texture is premultiplied. + @Description Sets whether or not the texture's colour has been + pre-multiplied by the alpha values. + *************************************************************************/ + void setIsPreMultiplied(bool isPreMultiplied); + + /*!*********************************************************************** + Meta Data functions - Getters. + *************************************************************************/ + + /*!*********************************************************************** + @Function isBumpMap + @Return bool True if it is a bump map. + @Description Returns whether the texture is a bump map or not. + *************************************************************************/ + const bool isBumpMap() const; + + /*!*********************************************************************** + @Function getBumpMapScale + @Return float Returns the bump map scale. + @Description Gets the bump map scaling value for this texture. If the + texture is not a bump map, 0.0f is returned. If the + texture is a bump map but no meta data is stored to + specify its scale, then 1.0f is returned. + *************************************************************************/ + const float getBumpMapScale() const; + + /*!*********************************************************************** + @Function getBumpMapOrder + @Return CPVRTString Returns bump map order relative to rgba. + @Description Gets the bump map channel order relative to rgba. For + example, an RGB texture with bumps mapped to XYZ returns + 'xyz'. A BGR texture with bumps in the order ZYX will also + return 'xyz' as the mapping is the same: R=X, G=Y, B=Z. + If the letter 'h' is present in the string, it means that + the height map has been stored here. + Other characters are possible if the bump map was created + manually, but PVRTexLib will ignore these characters. They + are returned simply for completeness. + *************************************************************************/ + const CPVRTString getBumpMapOrder() const; + + /*!*********************************************************************** + @Function getNumTextureAtlasMembers + @Return int Returns number of sub textures defined by meta data. + @Description Works out the number of possible texture atlas members in + the texture based on the w/h/d and the data size. + *************************************************************************/ + const int getNumTextureAtlasMembers() const; + + /*!*********************************************************************** + @Function getTextureAtlasData + @Return float* Returns a pointer directly to the texture atlas data. + @Description Returns a pointer to the texture atlas data. + *************************************************************************/ + const float* getTextureAtlasData() const; + + /*!*********************************************************************** + @Function getCubeMapOrder + @Return CPVRTString Returns cube map order. + @Description Gets the cube map face order. Returned string will be in + the form "ZzXxYy" with capitals representing positive and + small letters representing negative. I.e. Z=Z-Positive, + z=Z-Negative. + *************************************************************************/ + const CPVRTString getCubeMapOrder() const; + + /*!*********************************************************************** + @Function getBorder + @Input uiBorderWidth + @Input uiBorderHeight + @Input uiBorderDepth + @Description Obtains the border size in each dimension for this texture. + *************************************************************************/ + void getBorder(uint32& uiBorderWidth, uint32& uiBorderHeight, uint32& uiBorderDepth) const; + + /*!*********************************************************************** + @Function getMetaData + @Input DevFOURCC + @Input u32Key + @Return pvrtexture::MetaDataBlock A copy of the meta data from the texture. + @Description Returns a block of meta data from the texture. If the meta data doesn't exist, a block with data size 0 will be returned. + *************************************************************************/ + const MetaDataBlock getMetaData(uint32 DevFOURCC, uint32 u32Key) const; + + /*!*********************************************************************** + @Function hasMetaData + @Input DevFOURCC + @Input u32Key + @Return bool Whether or not the meta data bock specified exists + @Description Returns whether or not the specified meta data exists as + part of this texture header. + *************************************************************************/ + bool hasMetaData(uint32 DevFOURCC, uint32 u32Key) const; + + /*!*********************************************************************** + @Function getMetaDataMap + @Return MetaDataMap* A direct pointer to the MetaData map. + @Description A pointer directly to the Meta Data Map, to allow users to read out data. + *************************************************************************/ + const MetaDataMap* const getMetaDataMap() const; + + /*!*********************************************************************** + Meta Data functions - Setters. + *************************************************************************/ + + /*!*********************************************************************** + @Function setBumpMap + @Input bumpScale Floating point "height" value to scale the bump map. + @Input bumpOrder Up to 4 character string, with values x,y,z,h in + some combination. Not all values need to be present. + Denotes channel order; x,y,z refer to the + corresponding axes, h indicates presence of the + original height map. It is possible to have only some + of these values rather than all. For example if 'h' + is present alone it will be considered a height map. + The values should be presented in RGBA order, regardless + of the texture format, so a zyxh order in a bgra texture + should still be passed as 'xyzh'. Capitals are allowed. + Any character stored here that is not one of x,y,z,h + or a NULL character will be ignored when PVRTexLib + reads the data, but will be preserved. This is useful + if you wish to define a custom data channel for instance. + In these instances PVRTexLib will assume it is simply + colour data. + @Description Sets a texture's bump map data. + *************************************************************************/ + void setBumpMap(float bumpScale, CPVRTString bumpOrder="xyz"); + + /*!*********************************************************************** + @Function setTextureAtlas + @Input pAtlasData Pointer to an array of atlas data. + @Input dataSize Number of floats that the data pointer contains. + @Description Sets the texture atlas coordinate meta data for later display. + It is up to the user to make sure that this texture atlas + data actually makes sense in the context of the header. It is + suggested that the "generateTextureAtlas" method in the tools + is used to create a texture atlas, manually setting one up is + possible but should be done with care. + *************************************************************************/ + void setTextureAtlas(float* pAtlasData, uint32 dataSize); + + /*!*********************************************************************** + @Function setCubeMapOrder + @Input cubeMapOrder Up to 6 character string, with values + x,X,y,Y,z,Z in some combination. Not all + values need to be present. Denotes face + order; Capitals refer to positive axis + positions and small letters refer to + negative axis positions. E.g. x=X-Negative, + X=X-Positive. It is possible to have only + some of these values rather than all, as + long as they are NULL terminated. + NB: Values past the 6th character are not read. + @Description Sets a texture's bump map data. + *************************************************************************/ + void setCubeMapOrder(CPVRTString cubeMapOrder="XxYyZz"); + + /*!*********************************************************************** + @Function setBorder + @Input uiBorderWidth + @Input uiBorderHeight + @Input uiBorderDepth + @Return void + @Description Sets a texture's border size data. This value is subtracted + from the current texture height/width/depth to get the valid + texture data. + *************************************************************************/ + void setBorder(uint32 uiBorderWidth, uint32 uiBorderHeight, uint32 uiBorderDepth); + + /*!*********************************************************************** + @Function addMetaData + @Input MetaBlock Meta data block to be added. + @Description Adds an arbitrary piece of meta data. + *************************************************************************/ + void addMetaData(const MetaDataBlock& MetaBlock); + + /*!*********************************************************************** + @Function removeMetaData + @Input DevFourCC + @Input u32Key + @Return void + @Description Removes a specified piece of meta data, if it exists. + *************************************************************************/ + void removeMetaData(const uint32& DevFourCC, const uint32& u32Key); + }; +}; + +#endif diff --git a/KREngine/3rdparty/pvrtexlib/include/PVRTextureUtilities.h b/KREngine/3rdparty/pvrtexlib/include/PVRTextureUtilities.h new file mode 100644 index 0000000..20da6db --- /dev/null +++ b/KREngine/3rdparty/pvrtexlib/include/PVRTextureUtilities.h @@ -0,0 +1,157 @@ +#ifndef _PVRTEXTURE_UTILITIES_H +#define _PVRTEXTURE_UTILITIES_H + +#include "PVRTextureFormat.h" +#include "PVRTexture.h" + +namespace pvrtexture +{ + /*!*********************************************************************** + @Function Resize + @Input sTexture + @Input u32NewWidth + @Input u32NewHeight + @Input u32NewDepth + @Input eResizeMode + @Return bool Whether the method succeeds or not. + @Description Resizes the texture to new specified dimensions. Filtering + mode is specified with "eResizeMode". + *************************************************************************/ + bool PVR_DLL Resize(CPVRTexture& sTexture, const uint32& u32NewWidth, const uint32& u32NewHeight, const uint32& u32NewDepth, const EResizeMode eResizeMode); + + /*!*********************************************************************** + @Function Rotate90 + @Input sTexture + @Input eRotationAxis + @Input bForward + @Return bool Whether the method succeeds or not. + @Description Rotates a texture by 90 degrees around the given axis. bForward controls direction of rotation. + *************************************************************************/ + bool PVR_DLL Rotate90(CPVRTexture& sTexture, const EPVRTAxis eRotationAxis, const bool bForward); + + /*!*********************************************************************** + @Function Flip + @Input sTexture + @Input eFlipDirection + @Return bool Whether the method succeeds or not. + @Description Flips a texture in a given direction. + *************************************************************************/ + bool PVR_DLL Flip(CPVRTexture& sTexture, const EPVRTAxis eFlipDirection); + + /*!*********************************************************************** + @Function Border + @Input sTexture + @Input uiBorderX + @Input uiBorderY + @Input uiBorderZ + @Return bool Whether the method succeeds or not. + @Description Adds a user specified border to the texture. + *************************************************************************/ + bool PVR_DLL Border(CPVRTexture& sTexture, uint32 uiBorderX, uint32 uiBorderY, uint32 uiBorderZ); + + /*!*********************************************************************** + @Function PreMultiplyAlpha + @Input sTexture + @Return bool Whether the method succeeds or not. + @Description Pre-multiplies a texture's colours by its alpha values. + *************************************************************************/ + bool PVR_DLL PreMultiplyAlpha(CPVRTexture& sTexture); + + /*!*********************************************************************** + @Function Bleed + @Input sTexture + @Return bool Whether the method succeeds or not. + @Description Allows a texture's colours to run into any fully transparent areas. + *************************************************************************/ + bool PVR_DLL Bleed(CPVRTexture& sTexture); + + /*!*********************************************************************** + @Function SetChannels + @Input sTexture + @Input uiNumChannelSets + @Input eChannels + @Input pValues + @Return bool Whether the method succeeds or not. + @Description Sets the specified number of channels to values specified in pValues. + *************************************************************************/ + bool PVR_DLL SetChannels(CPVRTexture& sTexture, uint32 uiNumChannelSets, EChannelName *eChannels, uint32 *pValues); + bool PVR_DLL SetChannelsFloat(CPVRTexture& sTexture, uint32 uiNumChannelSets, EChannelName *eChannels, float *pValues); + + /*!*********************************************************************** + @Function CopyChannels + @Input sTexture + @Input sTextureSource + @Input uiNumChannelCopies + @Input eChannels + @Input eChannelsSource + @Return bool Whether the method succeeds or not. + @Description Copies the specified channels from sTextureSource into sTexture. + sTextureSource is not modified so it is possible to use the + same texture as both input and output. When using the same + texture as source and destination, channels are preserved + between swaps (e.g. copying Red to Green and then Green to Red + will result in the two channels trading places correctly). + Channels in eChannels are set to the value of the channels + in eChannelSource. + *************************************************************************/ + bool PVR_DLL CopyChannels(CPVRTexture& sTexture, const CPVRTexture& sTextureSource, uint32 uiNumChannelCopies, EChannelName *eChannels, EChannelName *eChannelsSource); + + /*!*********************************************************************** + @Function GenerateNormalMap + @Input sTexture + @Input fScale + @Input sChannelOrder + @Return bool Whether the method succeeds or not. + @Description Generates a Normal Map from a given height map. + Assumes the red channel has the height values. + By default outputs to red/green/blue = x/y/z, + this can be overridden by specifying a channel + order in sChannelOrder. The channels specified + will output to red/green/blue/alpha in that order. + So "xyzh" maps x to red, y to green, z to blue + and h to alpha. 'h' is used to specify that the + original height map data should be preserved in + the given channel. + *************************************************************************/ + bool PVR_DLL GenerateNormalMap(CPVRTexture& sTexture, const float fScale, CPVRTString sChannelOrder); + + /*!*********************************************************************** + @Function GenerateMIPMaps + @Input sTexture + @Input eFilterMode + @Input uiMIPMapsToDo + @Return bool Whether the method succeeds or not. + @Description Generates MIPMaps for a source texture. Default is to + create a complete MIPMap chain, however this can be + overridden with uiMIPMapsToDo. + *************************************************************************/ + bool PVR_DLL GenerateMIPMaps(CPVRTexture& sTexture, const EResizeMode eFilterMode, const uint32 uiMIPMapsToDo=PVRTEX_ALLMIPLEVELS); + + /*!*********************************************************************** + @Function ColourMIPMaps + @Input sTexture + @Return bool Whether the method succeeds or not. + @Description Colours a texture's MIPMap levels with artificial colours + for debugging. MIP levels are coloured in the order: + Red, Green, Blue, Cyan, Magenta and Yellow + in a repeating pattern. + *************************************************************************/ + bool PVR_DLL ColourMIPMaps(CPVRTexture& sTexture); + + /*!*********************************************************************** + @Function Transcode + @Input sTexture + @Input ptFormat + @Input eChannelType + @Input eColourspace + @Input eQuality + @Input bDoDither + @Return bool Whether the method succeeds or not. + @Description Transcodes a texture from its original format into a newly specified format. + Will either quantise or dither to lower precisions based on bDoDither. + uiQuality specifies the quality for PVRTC and ETC compression. + *************************************************************************/ + bool PVR_DLL Transcode(CPVRTexture& sTexture, const PixelType ptFormat, const EPVRTVariableType eChannelType, const EPVRTColourSpace eColourspace, const ECompressorQuality eQuality=ePVRTCNormal, const bool bDoDither=false); +}; +#endif //_PVRTEXTURE_UTILTIES_H + diff --git a/KREngine/3rdparty/pvrtexlib/include/PVRTextureVersion.h b/KREngine/3rdparty/pvrtexlib/include/PVRTextureVersion.h new file mode 100644 index 0000000..38ca378 --- /dev/null +++ b/KREngine/3rdparty/pvrtexlib/include/PVRTextureVersion.h @@ -0,0 +1,7 @@ +#ifndef PVRTEXLIBVERSION_H +#define PVRTEXLIBVERSION_H +#define PVRTLMAJORVERSION 4 +#define PVRTLMINORVERSION 6 +#define PVRTLSTRINGVERSION "4.6" +#define PVRTLVERSIONDESCRIPTOR "" //"BETA" //"ALPHA" //"ENGINEERING DROP" +#endif diff --git a/KREngine/3rdparty/pvrtexlib/static_osx/libPVRTexLib.a b/KREngine/3rdparty/pvrtexlib/static_osx/libPVRTexLib.a new file mode 100644 index 0000000..2615b1f Binary files /dev/null and b/KREngine/3rdparty/pvrtexlib/static_osx/libPVRTexLib.a differ diff --git a/KREngine/kraken/tinyxml2.cpp b/KREngine/3rdparty/tinyxml2/tinyxml2.cpp similarity index 100% rename from KREngine/kraken/tinyxml2.cpp rename to KREngine/3rdparty/tinyxml2/tinyxml2.cpp diff --git a/KREngine/kraken/tinyxml2.h b/KREngine/3rdparty/tinyxml2/tinyxml2.h similarity index 100% rename from KREngine/kraken/tinyxml2.h rename to KREngine/3rdparty/tinyxml2/tinyxml2.h diff --git a/KREngine/kraken/tinyxml2_readme.txt b/KREngine/3rdparty/tinyxml2/tinyxml2_readme.txt similarity index 100% rename from KREngine/kraken/tinyxml2_readme.txt rename to KREngine/3rdparty/tinyxml2/tinyxml2_readme.txt diff --git a/KREngine/Kraken.xcodeproj/project.pbxproj b/KREngine/Kraken.xcodeproj/project.pbxproj index 18e49e4..314545c 100644 --- a/KREngine/Kraken.xcodeproj/project.pbxproj +++ b/KREngine/Kraken.xcodeproj/project.pbxproj @@ -10,12 +10,14 @@ 104A335E1672D31C001C8BA6 /* KRCollider.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 104A335C1672D31B001C8BA6 /* KRCollider.cpp */; }; 104A335F1672D31C001C8BA6 /* KRCollider.h in Headers */ = {isa = PBXBuildFile; fileRef = 104A335D1672D31C001C8BA6 /* KRCollider.h */; settings = {ATTRIBUTES = (); }; }; 10CC33A5168534F000BB9846 /* KRCamera.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E48B3CBF14393E2F000C50E2 /* KRCamera.cpp */; }; + 5035BF3E18D2BBDD00252924 /* flare.fsh in Resources */ = {isa = PBXBuildFile; fileRef = E42559AA184DD4490081BB20 /* flare.fsh */; }; + 5035BF3F18D2BBDD00252924 /* flare.vsh in Resources */ = {isa = PBXBuildFile; fileRef = E42559AC184DD45A0081BB20 /* flare.vsh */; }; E4030E4C160A3CF000592648 /* KRStockGeometry.h in Headers */ = {isa = PBXBuildFile; fileRef = E4030E4B160A3CF000592648 /* KRStockGeometry.h */; settings = {ATTRIBUTES = (); }; }; E4030E4D160A3CF000592648 /* KRStockGeometry.h in Headers */ = {isa = PBXBuildFile; fileRef = E4030E4B160A3CF000592648 /* KRStockGeometry.h */; settings = {ATTRIBUTES = (Public, ); }; }; E404702018695DD200F01F42 /* KRTextureKTX.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E404701E18695DD200F01F42 /* KRTextureKTX.cpp */; }; E404702118695DD200F01F42 /* KRTextureKTX.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E404701E18695DD200F01F42 /* KRTextureKTX.cpp */; }; E404702218695DD200F01F42 /* KRTextureKTX.h in Headers */ = {isa = PBXBuildFile; fileRef = E404701F18695DD200F01F42 /* KRTextureKTX.h */; }; - E404702318695DD200F01F42 /* KRTextureKTX.h in Headers */ = {isa = PBXBuildFile; fileRef = E404701F18695DD200F01F42 /* KRTextureKTX.h */; }; + E404702318695DD200F01F42 /* KRTextureKTX.h in Headers */ = {isa = PBXBuildFile; fileRef = E404701F18695DD200F01F42 /* KRTextureKTX.h */; settings = {ATTRIBUTES = (Public, ); }; }; E40BA45415EFF79500D7C3DD /* KRAABB.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E40BA45215EFF79500D7C3DD /* KRAABB.cpp */; }; E40BA45515EFF79500D7C3DD /* KRAABB.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E40BA45215EFF79500D7C3DD /* KRAABB.cpp */; }; E40BA45615EFF79500D7C3DD /* KRAABB.h in Headers */ = {isa = PBXBuildFile; fileRef = E40BA45315EFF79500D7C3DD /* KRAABB.h */; settings = {ATTRIBUTES = (); }; }; @@ -89,14 +91,10 @@ E43F70DD181B20E400136169 /* KRLODSet.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E43F70DA181B20E300136169 /* KRLODSet.cpp */; }; E43F70DE181B20E400136169 /* KRLODSet.h in Headers */ = {isa = PBXBuildFile; fileRef = E43F70DB181B20E400136169 /* KRLODSet.h */; }; E43F70DF181B20E400136169 /* KRLODSet.h in Headers */ = {isa = PBXBuildFile; fileRef = E43F70DB181B20E400136169 /* KRLODSet.h */; settings = {ATTRIBUTES = (Public, ); }; }; - E43F70E51824D9AB00136169 /* KRTextureStreamer.mm in Sources */ = {isa = PBXBuildFile; fileRef = E43F70E31824D9AB00136169 /* KRTextureStreamer.mm */; }; - E43F70E61824D9AB00136169 /* KRTextureStreamer.mm in Sources */ = {isa = PBXBuildFile; fileRef = E43F70E31824D9AB00136169 /* KRTextureStreamer.mm */; }; - E43F70E71824D9AB00136169 /* KRTextureStreamer.h in Headers */ = {isa = PBXBuildFile; fileRef = E43F70E41824D9AB00136169 /* KRTextureStreamer.h */; }; - E43F70E81824D9AB00136169 /* KRTextureStreamer.h in Headers */ = {isa = PBXBuildFile; fileRef = E43F70E41824D9AB00136169 /* KRTextureStreamer.h */; settings = {ATTRIBUTES = (Public, ); }; }; - E43F70FF1824E73100136169 /* KRMeshStreamer.mm in Sources */ = {isa = PBXBuildFile; fileRef = E43F70FD1824E73100136169 /* KRMeshStreamer.mm */; }; - E43F71001824E73100136169 /* KRMeshStreamer.mm in Sources */ = {isa = PBXBuildFile; fileRef = E43F70FD1824E73100136169 /* KRMeshStreamer.mm */; }; - E43F71011824E73100136169 /* KRMeshStreamer.h in Headers */ = {isa = PBXBuildFile; fileRef = E43F70FE1824E73100136169 /* KRMeshStreamer.h */; }; - E43F71021824E73100136169 /* KRMeshStreamer.h in Headers */ = {isa = PBXBuildFile; fileRef = E43F70FE1824E73100136169 /* KRMeshStreamer.h */; settings = {ATTRIBUTES = (Public, ); }; }; + E43F70E51824D9AB00136169 /* KRStreamer.mm in Sources */ = {isa = PBXBuildFile; fileRef = E43F70E31824D9AB00136169 /* KRStreamer.mm */; }; + E43F70E61824D9AB00136169 /* KRStreamer.mm in Sources */ = {isa = PBXBuildFile; fileRef = E43F70E31824D9AB00136169 /* KRStreamer.mm */; }; + E43F70E71824D9AB00136169 /* KRStreamer.h in Headers */ = {isa = PBXBuildFile; fileRef = E43F70E41824D9AB00136169 /* KRStreamer.h */; }; + E43F70E81824D9AB00136169 /* KRStreamer.h in Headers */ = {isa = PBXBuildFile; fileRef = E43F70E41824D9AB00136169 /* KRStreamer.h */; settings = {ATTRIBUTES = (Public, ); }; }; E4409D2916FA748700310F76 /* font.tga in Resources */ = {isa = PBXBuildFile; fileRef = E41AE1DD16B124CA00980428 /* font.tga */; }; E44F38241683B23000399B5D /* KRRenderSettings.h in Headers */ = {isa = PBXBuildFile; fileRef = E44F38231683B22C00399B5D /* KRRenderSettings.h */; settings = {ATTRIBUTES = (); }; }; E44F38251683B23000399B5D /* KRRenderSettings.h in Headers */ = {isa = PBXBuildFile; fileRef = E44F38231683B22C00399B5D /* KRRenderSettings.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -112,6 +110,28 @@ E45134B91746A4A300443C21 /* KRBehavior.h in Headers */ = {isa = PBXBuildFile; fileRef = E45134B51746A4A300443C21 /* KRBehavior.h */; settings = {ATTRIBUTES = (Public, ); }; }; E459040416C30CC5002B00A0 /* AudioUnit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E459040316C30CC5002B00A0 /* AudioUnit.framework */; }; E459040616C30CD9002B00A0 /* AudioUnit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E459040516C30CD9002B00A0 /* AudioUnit.framework */; }; + E45E03B118790DD1006DA23F /* PVRTArray.h in Headers */ = {isa = PBXBuildFile; fileRef = E45E03A418790DD1006DA23F /* PVRTArray.h */; settings = {ATTRIBUTES = (Public, ); }; }; + E45E03B218790DD1006DA23F /* PVRTDecompress.h in Headers */ = {isa = PBXBuildFile; fileRef = E45E03A518790DD1006DA23F /* PVRTDecompress.h */; settings = {ATTRIBUTES = (Public, ); }; }; + E45E03B318790DD1006DA23F /* PVRTError.h in Headers */ = {isa = PBXBuildFile; fileRef = E45E03A618790DD1006DA23F /* PVRTError.h */; settings = {ATTRIBUTES = (Public, ); }; }; + E45E03B418790DD1006DA23F /* PVRTexture.h in Headers */ = {isa = PBXBuildFile; fileRef = E45E03A718790DD1006DA23F /* PVRTexture.h */; settings = {ATTRIBUTES = (Public, ); }; }; + E45E03B518790DD1006DA23F /* PVRTextureDefines.h in Headers */ = {isa = PBXBuildFile; fileRef = E45E03A818790DD1006DA23F /* PVRTextureDefines.h */; settings = {ATTRIBUTES = (Public, ); }; }; + E45E03B618790DD1006DA23F /* PVRTextureFormat.h in Headers */ = {isa = PBXBuildFile; fileRef = E45E03A918790DD1006DA23F /* PVRTextureFormat.h */; settings = {ATTRIBUTES = (Public, ); }; }; + E45E03B718790DD1006DA23F /* PVRTextureHeader.h in Headers */ = {isa = PBXBuildFile; fileRef = E45E03AA18790DD1006DA23F /* PVRTextureHeader.h */; settings = {ATTRIBUTES = (Public, ); }; }; + E45E03B818790DD1006DA23F /* PVRTextureUtilities.h in Headers */ = {isa = PBXBuildFile; fileRef = E45E03AB18790DD1006DA23F /* PVRTextureUtilities.h */; settings = {ATTRIBUTES = (Public, ); }; }; + E45E03B918790DD1006DA23F /* PVRTextureVersion.h in Headers */ = {isa = PBXBuildFile; fileRef = E45E03AC18790DD1006DA23F /* PVRTextureVersion.h */; settings = {ATTRIBUTES = (Public, ); }; }; + E45E03BA18790DD1006DA23F /* PVRTGlobal.h in Headers */ = {isa = PBXBuildFile; fileRef = E45E03AD18790DD1006DA23F /* PVRTGlobal.h */; settings = {ATTRIBUTES = (Public, ); }; }; + E45E03BB18790DD1006DA23F /* PVRTMap.h in Headers */ = {isa = PBXBuildFile; fileRef = E45E03AE18790DD1006DA23F /* PVRTMap.h */; settings = {ATTRIBUTES = (Public, ); }; }; + E45E03BC18790DD1006DA23F /* PVRTString.h in Headers */ = {isa = PBXBuildFile; fileRef = E45E03AF18790DD1006DA23F /* PVRTString.h */; settings = {ATTRIBUTES = (Public, ); }; }; + E45E03BD18790DD1006DA23F /* PVRTTexture.h in Headers */ = {isa = PBXBuildFile; fileRef = E45E03B018790DD1006DA23F /* PVRTTexture.h */; settings = {ATTRIBUTES = (Public, ); }; }; + E45E03C018790DF5006DA23F /* libPVRTexLib.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E45E03BF18790DF5006DA23F /* libPVRTexLib.a */; }; + E45E03C718790EC0006DA23F /* tinyxml2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E45E03C418790EC0006DA23F /* tinyxml2.cpp */; }; + E45E03C818790EC0006DA23F /* tinyxml2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E45E03C418790EC0006DA23F /* tinyxml2.cpp */; }; + E45E03C918790EC0006DA23F /* tinyxml2.h in Headers */ = {isa = PBXBuildFile; fileRef = E45E03C518790EC0006DA23F /* tinyxml2.h */; }; + E45E03CA18790EC0006DA23F /* tinyxml2.h in Headers */ = {isa = PBXBuildFile; fileRef = E45E03C518790EC0006DA23F /* tinyxml2.h */; settings = {ATTRIBUTES = (Public, ); }; }; + E45E03CD18790EFF006DA23F /* forsyth.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E45E03CB18790EFF006DA23F /* forsyth.cpp */; }; + E45E03CE18790EFF006DA23F /* forsyth.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E45E03CB18790EFF006DA23F /* forsyth.cpp */; }; + E45E03CF18790EFF006DA23F /* forsyth.h in Headers */ = {isa = PBXBuildFile; fileRef = E45E03CC18790EFF006DA23F /* forsyth.h */; }; + E45E03D018790EFF006DA23F /* forsyth.h in Headers */ = {isa = PBXBuildFile; fileRef = E45E03CC18790EFF006DA23F /* forsyth.h */; settings = {ATTRIBUTES = (Public, ); }; }; E460292616681CFF00261BB9 /* KRTextureAnimated.h in Headers */ = {isa = PBXBuildFile; fileRef = E460292516681CFE00261BB9 /* KRTextureAnimated.h */; settings = {ATTRIBUTES = (); }; }; E460292816681D1000261BB9 /* KRTextureAnimated.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E460292716681D1000261BB9 /* KRTextureAnimated.cpp */; }; E460292B16682BF700261BB9 /* libfbxsdk.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E460292916682BD900261BB9 /* libfbxsdk.a */; }; @@ -139,10 +159,6 @@ E468448217FFDF51001F1FA1 /* KRLocator.h in Headers */ = {isa = PBXBuildFile; fileRef = E468447E17FFDF51001F1FA1 /* KRLocator.h */; settings = {ATTRIBUTES = (Public, ); }; }; E46A6B6D1559E97D000DBD37 /* KRResource+blend.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E46A6B6C1559E97D000DBD37 /* KRResource+blend.cpp */; }; E46A6B701559EF0A000DBD37 /* KRResource+blend.h in Headers */ = {isa = PBXBuildFile; fileRef = E46A6B6F1559EF0A000DBD37 /* KRResource+blend.h */; settings = {ATTRIBUTES = (Public, ); }; }; - E46C214515364BC8009CABF3 /* tinyxml2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E46C214215364BC8009CABF3 /* tinyxml2.cpp */; }; - E46C214615364BC8009CABF3 /* tinyxml2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E46C214215364BC8009CABF3 /* tinyxml2.cpp */; }; - E46C214715364BC8009CABF3 /* tinyxml2.h in Headers */ = {isa = PBXBuildFile; fileRef = E46C214315364BC8009CABF3 /* tinyxml2.h */; settings = {ATTRIBUTES = (); }; }; - E46C214815364BC8009CABF3 /* tinyxml2.h in Headers */ = {isa = PBXBuildFile; fileRef = E46C214315364BC8009CABF3 /* tinyxml2.h */; settings = {ATTRIBUTES = (Public, ); }; }; E46C214B15364DEC009CABF3 /* KRSceneManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E46C214A15364DEC009CABF3 /* KRSceneManager.cpp */; }; E46C214C15364DEC009CABF3 /* KRSceneManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E46C214A15364DEC009CABF3 /* KRSceneManager.cpp */; }; E46DBE7F1512AF0200D59F86 /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E46DBE7D1512AD4900D59F86 /* OpenGL.framework */; }; @@ -350,7 +366,6 @@ E4E6F6BE16BA5E0A00E410F8 /* volumetric_fog_downsampled_osx.vsh in Resources */ = {isa = PBXBuildFile; fileRef = E4E6F62816BA5D8300E410F8 /* volumetric_fog_downsampled_osx.vsh */; }; E4E6F6BF16BA5E0A00E410F8 /* volumetric_fog_osx.fsh in Resources */ = {isa = PBXBuildFile; fileRef = E4E6F62916BA5D8300E410F8 /* volumetric_fog_osx.fsh */; }; E4E6F6C016BA5E0A00E410F8 /* volumetric_fog_osx.vsh in Resources */ = {isa = PBXBuildFile; fileRef = E4E6F62A16BA5D8300E410F8 /* volumetric_fog_osx.vsh */; }; - E4EC73B8171F32780065299F /* forsyth.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E4FE6AAA16B21D7E0058B8CE /* forsyth.cpp */; }; E4EC73C11720B1FF0065299F /* KRVector4.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E4EC73BF1720B1FF0065299F /* KRVector4.cpp */; }; E4EC73C21720B1FF0065299F /* KRVector4.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E4EC73BF1720B1FF0065299F /* KRVector4.cpp */; }; E4EC73C31720B1FF0065299F /* KRVector4.h in Headers */ = {isa = PBXBuildFile; fileRef = E4EC73C01720B1FF0065299F /* KRVector4.h */; }; @@ -371,6 +386,10 @@ E4F027E11697BFFF00D4427D /* KRAudioBuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = E4F027DD1697BFFF00D4427D /* KRAudioBuffer.h */; settings = {ATTRIBUTES = (Public, ); }; }; E4F027F71698115600D4427D /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E4F027F61698115600D4427D /* AudioToolbox.framework */; }; E4F027FA1698116000D4427D /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E4F027F91698116000D4427D /* AudioToolbox.framework */; }; + E4F89BB418A6DB1200015637 /* KRTriangle3.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E4F89BB218A6DB1200015637 /* KRTriangle3.cpp */; }; + E4F89BB518A6DB1200015637 /* KRTriangle3.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E4F89BB218A6DB1200015637 /* KRTriangle3.cpp */; }; + E4F89BB618A6DB1200015637 /* KRTriangle3.h in Headers */ = {isa = PBXBuildFile; fileRef = E4F89BB318A6DB1200015637 /* KRTriangle3.h */; }; + E4F89BB718A6DB1200015637 /* KRTriangle3.h in Headers */ = {isa = PBXBuildFile; fileRef = E4F89BB318A6DB1200015637 /* KRTriangle3.h */; }; E4F975321536220900FD60B2 /* KRNode.h in Headers */ = {isa = PBXBuildFile; fileRef = E4F975311536220900FD60B2 /* KRNode.h */; settings = {ATTRIBUTES = (); }; }; E4F975331536220900FD60B2 /* KRNode.h in Headers */ = {isa = PBXBuildFile; fileRef = E4F975311536220900FD60B2 /* KRNode.h */; settings = {ATTRIBUTES = (Public, ); }; }; E4F975361536221C00FD60B2 /* KRNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E4F975351536221C00FD60B2 /* KRNode.cpp */; }; @@ -391,9 +410,6 @@ E4F97552153633EF00FD60B2 /* KRMaterialManager.h in Headers */ = {isa = PBXBuildFile; fileRef = E491018413C99BDC0098455B /* KRMaterialManager.h */; settings = {ATTRIBUTES = (Public, ); }; }; E4F975531536340000FD60B2 /* KRTexture2D.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E491018113C99BDC0098455B /* KRTexture2D.cpp */; }; E4F975541536340400FD60B2 /* KRTexture2D.h in Headers */ = {isa = PBXBuildFile; fileRef = E491018613C99BDC0098455B /* KRTexture2D.h */; settings = {ATTRIBUTES = (Public, ); }; }; - E4FE6AA816B21D660058B8CE /* forsyth.h in Headers */ = {isa = PBXBuildFile; fileRef = E4FE6AA716B21D660058B8CE /* forsyth.h */; settings = {ATTRIBUTES = (); }; }; - E4FE6AA916B21D660058B8CE /* forsyth.h in Headers */ = {isa = PBXBuildFile; fileRef = E4FE6AA716B21D660058B8CE /* forsyth.h */; settings = {ATTRIBUTES = (Public, ); }; }; - E4FE6AAB16B21D7E0058B8CE /* forsyth.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E4FE6AAA16B21D7E0058B8CE /* forsyth.cpp */; }; /* End PBXBuildFile section */ /* Begin PBXBuildRule section */ @@ -411,7 +427,6 @@ /* Begin PBXFileReference section */ 104A335C1672D31B001C8BA6 /* KRCollider.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; path = KRCollider.cpp; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.cpp; }; 104A335D1672D31C001C8BA6 /* KRCollider.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = KRCollider.h; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; - 10CC33A3168530A300BB9846 /* libPVRTexLib.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libPVRTexLib.a; path = Utilities/PVRTexLib/MacOS/libPVRTexLib.a; sourceTree = PVRSDK; }; E4030E4B160A3CF000592648 /* KRStockGeometry.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KRStockGeometry.h; sourceTree = ""; }; E404701E18695DD200F01F42 /* KRTextureKTX.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = KRTextureKTX.cpp; sourceTree = ""; }; E404701F18695DD200F01F42 /* KRTextureKTX.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KRTextureKTX.h; sourceTree = ""; }; @@ -419,7 +434,7 @@ E40BA45315EFF79500D7C3DD /* KRAABB.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KRAABB.h; sourceTree = ""; }; E40F982A184A7A2700CFA4D8 /* KRMeshQuad.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = KRMeshQuad.cpp; sourceTree = ""; }; E40F982B184A7A2700CFA4D8 /* KRMeshQuad.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KRMeshQuad.h; sourceTree = ""; }; - E40F9830184A7BAC00CFA4D8 /* KRSprite.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = KRSprite.cpp; sourceTree = ""; }; + E40F9830184A7BAC00CFA4D8 /* KRSprite.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; path = KRSprite.cpp; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.cpp; }; E40F9831184A7BAC00CFA4D8 /* KRSprite.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KRSprite.h; sourceTree = ""; }; E414BAE11435557300A668C4 /* KRModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = KRModel.h; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; E414BAE41435558800A668C4 /* KRModel.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; path = KRModel.cpp; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.cpp; }; @@ -459,10 +474,8 @@ E43B0AD515DDCA0D00A5CB9F /* KRContextObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KRContextObject.h; sourceTree = ""; }; E43F70DA181B20E300136169 /* KRLODSet.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = KRLODSet.cpp; sourceTree = ""; }; E43F70DB181B20E400136169 /* KRLODSet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KRLODSet.h; sourceTree = ""; }; - E43F70E31824D9AB00136169 /* KRTextureStreamer.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = KRTextureStreamer.mm; sourceTree = ""; }; - E43F70E41824D9AB00136169 /* KRTextureStreamer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KRTextureStreamer.h; sourceTree = ""; }; - E43F70FD1824E73100136169 /* KRMeshStreamer.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = KRMeshStreamer.mm; sourceTree = ""; }; - E43F70FE1824E73100136169 /* KRMeshStreamer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KRMeshStreamer.h; sourceTree = ""; }; + E43F70E31824D9AB00136169 /* KRStreamer.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; lineEnding = 0; path = KRStreamer.mm; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; + E43F70E41824D9AB00136169 /* KRStreamer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = KRStreamer.h; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; E44F38231683B22C00399B5D /* KRRenderSettings.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KRRenderSettings.h; sourceTree = ""; }; E44F38271683B24400399B5D /* KRRenderSettings.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = KRRenderSettings.cpp; sourceTree = ""; }; E450273716E0491D00FDEC5C /* KRReverbZone.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; path = KRReverbZone.cpp; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.cpp; }; @@ -471,6 +484,25 @@ E45134B51746A4A300443C21 /* KRBehavior.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KRBehavior.h; sourceTree = ""; }; E459040316C30CC5002B00A0 /* AudioUnit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioUnit.framework; path = Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.8.sdk/System/Library/Frameworks/AudioUnit.framework; sourceTree = DEVELOPER_DIR; }; E459040516C30CD9002B00A0 /* AudioUnit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioUnit.framework; path = System/Library/Frameworks/AudioUnit.framework; sourceTree = SDKROOT; }; + E45E03A418790DD1006DA23F /* PVRTArray.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PVRTArray.h; sourceTree = ""; }; + E45E03A518790DD1006DA23F /* PVRTDecompress.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PVRTDecompress.h; sourceTree = ""; }; + E45E03A618790DD1006DA23F /* PVRTError.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PVRTError.h; sourceTree = ""; }; + E45E03A718790DD1006DA23F /* PVRTexture.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PVRTexture.h; sourceTree = ""; }; + E45E03A818790DD1006DA23F /* PVRTextureDefines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PVRTextureDefines.h; sourceTree = ""; }; + E45E03A918790DD1006DA23F /* PVRTextureFormat.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PVRTextureFormat.h; sourceTree = ""; }; + E45E03AA18790DD1006DA23F /* PVRTextureHeader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PVRTextureHeader.h; sourceTree = ""; }; + E45E03AB18790DD1006DA23F /* PVRTextureUtilities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PVRTextureUtilities.h; sourceTree = ""; }; + E45E03AC18790DD1006DA23F /* PVRTextureVersion.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PVRTextureVersion.h; sourceTree = ""; }; + E45E03AD18790DD1006DA23F /* PVRTGlobal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PVRTGlobal.h; sourceTree = ""; }; + E45E03AE18790DD1006DA23F /* PVRTMap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PVRTMap.h; sourceTree = ""; }; + E45E03AF18790DD1006DA23F /* PVRTString.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PVRTString.h; sourceTree = ""; }; + E45E03B018790DD1006DA23F /* PVRTTexture.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PVRTTexture.h; sourceTree = ""; }; + E45E03BF18790DF5006DA23F /* libPVRTexLib.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libPVRTexLib.a; sourceTree = ""; }; + E45E03C318790EC0006DA23F /* tinyxml2_readme.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = tinyxml2_readme.txt; sourceTree = ""; }; + E45E03C418790EC0006DA23F /* tinyxml2.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = tinyxml2.cpp; sourceTree = ""; }; + E45E03C518790EC0006DA23F /* tinyxml2.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tinyxml2.h; sourceTree = ""; }; + E45E03CB18790EFF006DA23F /* forsyth.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = forsyth.cpp; sourceTree = ""; }; + E45E03CC18790EFF006DA23F /* forsyth.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = forsyth.h; sourceTree = ""; }; E460292516681CFE00261BB9 /* KRTextureAnimated.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KRTextureAnimated.h; sourceTree = ""; }; E460292716681D1000261BB9 /* KRTextureAnimated.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = KRTextureAnimated.cpp; sourceTree = ""; }; E460292916682BD900261BB9 /* libfbxsdk.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libfbxsdk.a; path = "../../FBX SDK/2014.2/lib/ios-i386/release/libfbxsdk.a"; sourceTree = FBXSDK; }; @@ -486,9 +518,6 @@ E468447E17FFDF51001F1FA1 /* KRLocator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KRLocator.h; sourceTree = ""; }; E46A6B6C1559E97D000DBD37 /* KRResource+blend.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "KRResource+blend.cpp"; sourceTree = ""; }; E46A6B6F1559EF0A000DBD37 /* KRResource+blend.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "KRResource+blend.h"; sourceTree = ""; }; - E46C214115364BC8009CABF3 /* tinyxml2_readme.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = tinyxml2_readme.txt; sourceTree = ""; }; - E46C214215364BC8009CABF3 /* tinyxml2.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = tinyxml2.cpp; sourceTree = ""; }; - E46C214315364BC8009CABF3 /* tinyxml2.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tinyxml2.h; sourceTree = ""; }; E46C214915364DDB009CABF3 /* KRSceneManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KRSceneManager.h; sourceTree = ""; }; E46C214A15364DEC009CABF3 /* KRSceneManager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = KRSceneManager.cpp; sourceTree = ""; }; E46DBE7D1512AD4900D59F86 /* OpenGL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGL.framework; path = ../../../../MacOSX.platform/Developer/SDKs/MacOSX10.7.sdk/System/Library/Frameworks/OpenGL.framework; sourceTree = SDKROOT; }; @@ -656,10 +685,10 @@ E4F027DD1697BFFF00D4427D /* KRAudioBuffer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = KRAudioBuffer.h; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; E4F027F61698115600D4427D /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.7.sdk/System/Library/Frameworks/AudioToolbox.framework; sourceTree = DEVELOPER_DIR; }; E4F027F91698116000D4427D /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = System/Library/Frameworks/AudioToolbox.framework; sourceTree = SDKROOT; }; + E4F89BB218A6DB1200015637 /* KRTriangle3.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = KRTriangle3.cpp; sourceTree = ""; }; + E4F89BB318A6DB1200015637 /* KRTriangle3.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KRTriangle3.h; sourceTree = ""; }; E4F975311536220900FD60B2 /* KRNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = KRNode.h; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; E4F975351536221C00FD60B2 /* KRNode.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; path = KRNode.cpp; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.cpp; }; - E4FE6AA716B21D660058B8CE /* forsyth.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = forsyth.h; sourceTree = ""; }; - E4FE6AAA16B21D7E0058B8CE /* forsyth.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = forsyth.cpp; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -681,6 +710,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + E45E03C018790DF5006DA23F /* libPVRTexLib.a in Frameworks */, E459040416C30CC5002B00A0 /* AudioUnit.framework in Frameworks */, E41B6BAA16BE437800B510EB /* CoreAudio.framework in Frameworks */, E4F027F71698115600D4427D /* AudioToolbox.framework in Frameworks */, @@ -809,6 +839,72 @@ path = kraken_standard_assets; sourceTree = ""; }; + E45E03A118790D92006DA23F /* 3rdparty */ = { + isa = PBXGroup; + children = ( + E45E03C218790E55006DA23F /* tinyxml2 */, + E45E03C118790E4F006DA23F /* forsyth */, + E45E03A218790DA3006DA23F /* pvrtexlib */, + ); + path = 3rdparty; + sourceTree = ""; + }; + E45E03A218790DA3006DA23F /* pvrtexlib */ = { + isa = PBXGroup; + children = ( + E45E03BE18790DDB006DA23F /* static_osx */, + E45E03A318790DB8006DA23F /* include */, + ); + path = pvrtexlib; + sourceTree = ""; + }; + E45E03A318790DB8006DA23F /* include */ = { + isa = PBXGroup; + children = ( + E45E03A418790DD1006DA23F /* PVRTArray.h */, + E45E03A518790DD1006DA23F /* PVRTDecompress.h */, + E45E03A618790DD1006DA23F /* PVRTError.h */, + E45E03A718790DD1006DA23F /* PVRTexture.h */, + E45E03A818790DD1006DA23F /* PVRTextureDefines.h */, + E45E03A918790DD1006DA23F /* PVRTextureFormat.h */, + E45E03AA18790DD1006DA23F /* PVRTextureHeader.h */, + E45E03AB18790DD1006DA23F /* PVRTextureUtilities.h */, + E45E03AC18790DD1006DA23F /* PVRTextureVersion.h */, + E45E03AD18790DD1006DA23F /* PVRTGlobal.h */, + E45E03AE18790DD1006DA23F /* PVRTMap.h */, + E45E03AF18790DD1006DA23F /* PVRTString.h */, + E45E03B018790DD1006DA23F /* PVRTTexture.h */, + ); + path = include; + sourceTree = ""; + }; + E45E03BE18790DDB006DA23F /* static_osx */ = { + isa = PBXGroup; + children = ( + E45E03BF18790DF5006DA23F /* libPVRTexLib.a */, + ); + path = static_osx; + sourceTree = ""; + }; + E45E03C118790E4F006DA23F /* forsyth */ = { + isa = PBXGroup; + children = ( + E45E03CB18790EFF006DA23F /* forsyth.cpp */, + E45E03CC18790EFF006DA23F /* forsyth.h */, + ); + path = forsyth; + sourceTree = ""; + }; + E45E03C218790E55006DA23F /* tinyxml2 */ = { + isa = PBXGroup; + children = ( + E45E03C318790EC0006DA23F /* tinyxml2_readme.txt */, + E45E03C418790EC0006DA23F /* tinyxml2.cpp */, + E45E03C518790EC0006DA23F /* tinyxml2.h */, + ); + path = tinyxml2; + sourceTree = ""; + }; E461A170152E598200F2044A /* Resources */ = { isa = PBXGroup; children = ( @@ -854,20 +950,12 @@ E4EC73C01720B1FF0065299F /* KRVector4.h */, E48CF940173453990005EBBB /* KRFloat.cpp */, E48CF941173453990005EBBB /* KRFloat.h */, + E4F89BB218A6DB1200015637 /* KRTriangle3.cpp */, + E4F89BB318A6DB1200015637 /* KRTriangle3.h */, ); name = Math; sourceTree = ""; }; - E46C214015364BB8009CABF3 /* tinyxml2 */ = { - isa = PBXGroup; - children = ( - E46C214115364BC8009CABF3 /* tinyxml2_readme.txt */, - E46C214215364BC8009CABF3 /* tinyxml2.cpp */, - E46C214315364BC8009CABF3 /* tinyxml2.h */, - ); - name = tinyxml2; - sourceTree = ""; - }; E488399915F92BA300BD66D5 /* Managers */ = { isa = PBXGroup; children = ( @@ -926,8 +1014,6 @@ E4CA10EE1637BD58005D9400 /* KRTextureTGA.cpp */, E460292516681CFE00261BB9 /* KRTextureAnimated.h */, E460292716681D1000261BB9 /* KRTextureAnimated.cpp */, - E43F70E31824D9AB00136169 /* KRTextureStreamer.mm */, - E43F70E41824D9AB00136169 /* KRTextureStreamer.h */, E404701E18695DD200F01F42 /* KRTextureKTX.cpp */, E404701F18695DD200F01F42 /* KRTextureKTX.h */, ); @@ -945,8 +1031,6 @@ E4C454AE167BB8FC003586CD /* KRMeshCube.cpp */, E4C454B1167BC04B003586CD /* KRMeshSphere.h */, E4C454B4167BC05C003586CD /* KRMeshSphere.cpp */, - E43F70FD1824E73100136169 /* KRMeshStreamer.mm */, - E43F70FE1824E73100136169 /* KRMeshStreamer.h */, E40F982A184A7A2700CFA4D8 /* KRMeshQuad.cpp */, E40F982B184A7A2700CFA4D8 /* KRMeshQuad.h */, ); @@ -1040,6 +1124,7 @@ E491015613C99B9D0098455B = { isa = PBXGroup; children = ( + E45E03A118790D92006DA23F /* 3rdparty */, E437849616C4881A0037FD43 /* kraken_standard_assets */, E491016613C99B9E0098455B /* kraken */, E4C8E50C16B9B5ED0031DDCB /* kraken_ios */, @@ -1064,7 +1149,8 @@ E491016613C99B9E0098455B /* kraken */ = { isa = PBXGroup; children = ( - E4F9753815362A5200FD60B2 /* 3rdparty */, + E43F70E31824D9AB00136169 /* KRStreamer.mm */, + E43F70E41824D9AB00136169 /* KRStreamer.h */, E488399915F92BA300BD66D5 /* Managers */, E461A173152E59DF00F2044A /* Math */, E461A170152E598200F2044A /* Resources */, @@ -1120,7 +1206,6 @@ children = ( E459040316C30CC5002B00A0 /* AudioUnit.framework */, E41B6BA916BE437800B510EB /* CoreAudio.framework */, - 10CC33A3168530A300BB9846 /* libPVRTexLib.a */, E460292916682BD900261BB9 /* libfbxsdk.a */, E4BBBB9A1512A48200F43B5B /* Foundation.framework */, E46DBE7D1512AD4900D59F86 /* OpenGL.framework */, @@ -1219,24 +1304,6 @@ name = Frameworks; sourceTree = ""; }; - E4F9753815362A5200FD60B2 /* 3rdparty */ = { - isa = PBXGroup; - children = ( - E4FE6AA516B21D330058B8CE /* forsyth */, - E46C214015364BB8009CABF3 /* tinyxml2 */, - ); - name = 3rdparty; - sourceTree = ""; - }; - E4FE6AA516B21D330058B8CE /* forsyth */ = { - isa = PBXGroup; - children = ( - E4FE6AA716B21D660058B8CE /* forsyth.h */, - E4FE6AAA16B21D7E0058B8CE /* forsyth.cpp */, - ); - name = forsyth; - sourceTree = ""; - }; /* End PBXGroup section */ /* Begin PBXHeadersBuildPhase section */ @@ -1260,14 +1327,14 @@ E414BAE7143557D200A668C4 /* KRScene.h in Headers */, E48B3CBD14393DF5000C50E2 /* KRCamera.h in Headers */, E40F982E184A7A2700CFA4D8 /* KRMeshQuad.h in Headers */, + E45E03CF18790EFF006DA23F /* forsyth.h in Headers */, E497B94A151BCEE900D3DC67 /* KRResource.h in Headers */, E461A152152E54B500F2044A /* KRLight.h in Headers */, E461A15C152E563100F2044A /* KRDirectionalLight.h in Headers */, E461A168152E570700F2044A /* KRSpotLight.h in Headers */, E468448117FFDF51001F1FA1 /* KRLocator.h in Headers */, - E43F70E71824D9AB00136169 /* KRTextureStreamer.h in Headers */, + E43F70E71824D9AB00136169 /* KRStreamer.h in Headers */, E4F975321536220900FD60B2 /* KRNode.h in Headers */, - E46C214715364BC8009CABF3 /* tinyxml2.h in Headers */, E48C696F15374F5B00232E28 /* KRContext.h in Headers */, E46F4A0B155E002100CCF8B8 /* KRDataBlock.h in Headers */, E42CB1EC158446940066E0D8 /* KRQuaternion.h in Headers */, @@ -1304,19 +1371,19 @@ E48B68171697794F00D99917 /* KRAudioSource.h in Headers */, E4F027C916979CCD00D4427D /* KRAudioManager.h in Headers */, E4F027E01697BFFF00D4427D /* KRAudioBuffer.h in Headers */, + E4F89BB618A6DB1200015637 /* KRTriangle3.h in Headers */, E4943233169E08D200BCB891 /* KRAmbientZone.h in Headers */, E499BF1B16AE747C007FCDBE /* KRVector2.h in Headers */, E499BF1E16AE751E007FCDBE /* KRSceneManager.h in Headers */, E499BF2016AE755B007FCDBE /* KRPointLight.h in Headers */, E499BF2116AE75A7007FCDBE /* KREngine-common.h in Headers */, E404702218695DD200F01F42 /* KRTextureKTX.h in Headers */, + E45E03C918790EC0006DA23F /* tinyxml2.h in Headers */, E4F027D016979CE200D4427D /* KRAudioSample.h in Headers */, E450273B16E0491D00FDEC5C /* KRReverbZone.h in Headers */, - E4FE6AA816B21D660058B8CE /* forsyth.h in Headers */, E4AE635F1704FB0A00B460CD /* KRLODGroup.h in Headers */, E4EC73C31720B1FF0065299F /* KRVector4.h in Headers */, E48CF944173453990005EBBB /* KRFloat.h in Headers */, - E43F71011824E73100136169 /* KRMeshStreamer.h in Headers */, E45134B81746A4A300443C21 /* KRBehavior.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; @@ -1354,7 +1421,6 @@ E428C3051669627900A16EDF /* KRAnimationCurve.h in Headers */, E48C697015374F5B00232E28 /* KRContext.h in Headers */, E46F4A10155E004100CCF8B8 /* KRDataBlock.cpp in Headers */, - E46C214815364BC8009CABF3 /* tinyxml2.h in Headers */, E4D13365153767FF0070068C /* KRShaderManager.h in Headers */, E40BA45715EFF79500D7C3DD /* KRAABB.h in Headers */, E428C312166971FF00A16EDF /* KRAnimationLayer.h in Headers */, @@ -1378,16 +1444,31 @@ E4324BA516444C0D0043185B /* KRParticleSystem.h in Headers */, E4324BAC16444DEF0043185B /* KRParticleSystemNewtonian.h in Headers */, E4C454AD167BB8EC003586CD /* KRMeshCube.h in Headers */, - E404702318695DD200F01F42 /* KRTextureKTX.h in Headers */, E414F9A91694D977000B3D58 /* KRUnknownManager.h in Headers */, E48B68181697794F00D99917 /* KRAudioSource.h in Headers */, E4F027CA16979CCD00D4427D /* KRAudioManager.h in Headers */, E4F027D116979CE200D4427D /* KRAudioSample.h in Headers */, E4F027E11697BFFF00D4427D /* KRAudioBuffer.h in Headers */, + E4F89BB718A6DB1200015637 /* KRTriangle3.h in Headers */, E4943234169E08D200BCB891 /* KRAmbientZone.h in Headers */, E414F9AF1694DA37000B3D58 /* KRUnknown.h in Headers */, + E45E03BD18790DD1006DA23F /* PVRTTexture.h in Headers */, + E45E03B618790DD1006DA23F /* PVRTextureFormat.h in Headers */, + E45E03B318790DD1006DA23F /* PVRTError.h in Headers */, + E45E03BA18790DD1006DA23F /* PVRTGlobal.h in Headers */, + E45E03B418790DD1006DA23F /* PVRTexture.h in Headers */, + E45E03B818790DD1006DA23F /* PVRTextureUtilities.h in Headers */, + E45E03B918790DD1006DA23F /* PVRTextureVersion.h in Headers */, + E45E03B118790DD1006DA23F /* PVRTArray.h in Headers */, + E45E03CA18790EC0006DA23F /* tinyxml2.h in Headers */, + E45E03D018790EFF006DA23F /* forsyth.h in Headers */, + E45E03B218790DD1006DA23F /* PVRTDecompress.h in Headers */, + E45E03B518790DD1006DA23F /* PVRTextureDefines.h in Headers */, + E404702318695DD200F01F42 /* KRTextureKTX.h in Headers */, + E45E03B718790DD1006DA23F /* PVRTextureHeader.h in Headers */, + E45E03BB18790DD1006DA23F /* PVRTMap.h in Headers */, + E45E03BC18790DD1006DA23F /* PVRTString.h in Headers */, E499BF2216AE760F007FCDBE /* krengine_osx.h in Headers */, - E4FE6AA916B21D660058B8CE /* forsyth.h in Headers */, E4C454B3167BC04C003586CD /* KRMeshSphere.h in Headers */, E450273C16E0491D00FDEC5C /* KRReverbZone.h in Headers */, E44F38251683B23000399B5D /* KRRenderSettings.h in Headers */, @@ -1397,8 +1478,7 @@ E43F70DF181B20E400136169 /* KRLODSet.h in Headers */, E4AE63601704FB0A00B460CD /* KRLODGroup.h in Headers */, E45134B91746A4A300443C21 /* KRBehavior.h in Headers */, - E43F71021824E73100136169 /* KRMeshStreamer.h in Headers */, - E43F70E81824D9AB00136169 /* KRTextureStreamer.h in Headers */, + E43F70E81824D9AB00136169 /* KRStreamer.h in Headers */, E40F982F184A7A2700CFA4D8 /* KRMeshQuad.h in Headers */, E40F9835184A7BAC00CFA4D8 /* KRSprite.h in Headers */, E48CF945173453990005EBBB /* KRFloat.h in Headers */, @@ -1522,6 +1602,8 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + 5035BF3E18D2BBDD00252924 /* flare.fsh in Resources */, + 5035BF3F18D2BBDD00252924 /* flare.vsh in Resources */, E4409D2916FA748700310F76 /* font.tga in Resources */, E437849816C4884F0037FD43 /* hrtf_kemar.krbundle in Resources */, E4E6F68516BA5DF700E410F8 /* sky_box.fsh in Resources */, @@ -1612,6 +1694,8 @@ E491019813C99BDC0098455B /* KRTextureManager.cpp in Sources */, E491019913C99BDC0098455B /* KRTexture2D.cpp in Sources */, E491019A13C99BDC0098455B /* KRMeshManager.cpp in Sources */, + E45E03C718790EC0006DA23F /* tinyxml2.cpp in Sources */, + E45E03CD18790EFF006DA23F /* forsyth.cpp in Sources */, E47C25A713F4F6AB00FF4370 /* KRShaderManager.cpp in Sources */, E47C25A913F4F6DD00FF4370 /* KRShader.cpp in Sources */, E43F70DC181B20E400136169 /* KRLODSet.cpp in Sources */, @@ -1621,14 +1705,12 @@ E497B946151BA99500D3DC67 /* KRVector2.cpp in Sources */, E497B94D151BCF2500D3DC67 /* KRResource.cpp in Sources */, E497B950151BD2CE00D3DC67 /* KRResource+obj.cpp in Sources */, - E43F70FF1824E73100136169 /* KRMeshStreamer.mm in Sources */, E461A156152E54F800F2044A /* KRLight.cpp in Sources */, E461A159152E557E00F2044A /* KRPointLight.cpp in Sources */, E468447F17FFDF51001F1FA1 /* KRLocator.cpp in Sources */, E461A15F152E565700F2044A /* KRDirectionalLight.cpp in Sources */, E461A165152E56C000F2044A /* KRSpotLight.cpp in Sources */, E4F975361536221C00FD60B2 /* KRNode.cpp in Sources */, - E46C214515364BC8009CABF3 /* tinyxml2.cpp in Sources */, E46C214B15364DEC009CABF3 /* KRSceneManager.cpp in Sources */, E48C697215374F7E00232E28 /* KRContext.cpp in Sources */, E46F4A0E155E003000CCF8B8 /* KRDataBlock.cpp in Sources */, @@ -1638,6 +1720,7 @@ E4924C2B15EE96AB00B965C6 /* KROctreeNode.cpp in Sources */, E404702018695DD200F01F42 /* KRTextureKTX.cpp in Sources */, E40BA45415EFF79500D7C3DD /* KRAABB.cpp in Sources */, + E4F89BB418A6DB1200015637 /* KRTriangle3.cpp in Sources */, E488399415F928CA00BD66D5 /* KRBundle.cpp in Sources */, E488399C15F92BE000BD66D5 /* KRBundleManager.cpp in Sources */, E4B175AC161F5A1000B8FB80 /* KRTexture.cpp in Sources */, @@ -1648,7 +1731,7 @@ E4324BA816444C230043185B /* KRParticleSystem.cpp in Sources */, E4324BAE16444E120043185B /* KRParticleSystemNewtonian.cpp in Sources */, E460292816681D1000261BB9 /* KRTextureAnimated.cpp in Sources */, - E43F70E51824D9AB00136169 /* KRTextureStreamer.mm in Sources */, + E43F70E51824D9AB00136169 /* KRStreamer.mm in Sources */, E428C2F51669611600A16EDF /* KRAnimationManager.cpp in Sources */, E428C2FB1669613200A16EDF /* KRAnimation.cpp in Sources */, E428C3071669628A00A16EDF /* KRAnimationCurve.cpp in Sources */, @@ -1670,7 +1753,6 @@ E4F027CE16979CE200D4427D /* KRAudioSample.cpp in Sources */, E4F027DE1697BFFF00D4427D /* KRAudioBuffer.cpp in Sources */, E4943231169E08D200BCB891 /* KRAmbientZone.cpp in Sources */, - E4FE6AAB16B21D7E0058B8CE /* forsyth.cpp in Sources */, E450273916E0491D00FDEC5C /* KRReverbZone.cpp in Sources */, E4AE635D1704FB0A00B460CD /* KRLODGroup.cpp in Sources */, E4EC73C11720B1FF0065299F /* KRVector4.cpp in Sources */, @@ -1683,7 +1765,6 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - E4EC73B8171F32780065299F /* forsyth.cpp in Sources */, E499BF2516AE8C20007FCDBE /* KREngine.mm in Sources */, 10CC33A5168534F000BB9846 /* KRCamera.cpp in Sources */, E460292C166834AB00261BB9 /* KRTextureAnimated.cpp in Sources */, @@ -1699,6 +1780,7 @@ E497B954151BEDA600D3DC67 /* KRResource+fbx.cpp in Sources */, E4F97551153633E200FD60B2 /* KRMaterialManager.cpp in Sources */, E461A15A152E557E00F2044A /* KRPointLight.cpp in Sources */, + E45E03C818790EC0006DA23F /* tinyxml2.cpp in Sources */, E4F9754F1536333200FD60B2 /* KRMesh.cpp in Sources */, E4F9754B153632D800FD60B2 /* KRMeshManager.cpp in Sources */, E461A160152E565700F2044A /* KRDirectionalLight.cpp in Sources */, @@ -1706,10 +1788,10 @@ E4F9754015362CD400FD60B2 /* KRScene.cpp in Sources */, E461A166152E56C000F2044A /* KRSpotLight.cpp in Sources */, E4F9754315362D0F00FD60B2 /* KRModel.cpp in Sources */, + E45E03CE18790EFF006DA23F /* forsyth.cpp in Sources */, E4F975371536221C00FD60B2 /* KRNode.cpp in Sources */, E4F9754E1536331D00FD60B2 /* KRTextureManager.cpp in Sources */, E4D13367153768610070068C /* KRShader.cpp in Sources */, - E46C214615364BC8009CABF3 /* tinyxml2.cpp in Sources */, E4D13364153767ED0070068C /* KRShaderManager.cpp in Sources */, E4AFC6B915F7C7B200DDB4C8 /* KROctree.cpp in Sources */, E46C214C15364DEC009CABF3 /* KRSceneManager.cpp in Sources */, @@ -1724,12 +1806,12 @@ E488399515F928CA00BD66D5 /* KRBundle.cpp in Sources */, E488399D15F92BE000BD66D5 /* KRBundleManager.cpp in Sources */, E43F70DD181B20E400136169 /* KRLODSet.cpp in Sources */, - E43F71001824E73100136169 /* KRMeshStreamer.mm in Sources */, E4B175AD161F5A1000B8FB80 /* KRTexture.cpp in Sources */, E4B175B3161F5FAF00B8FB80 /* KRTextureCube.cpp in Sources */, E40F9833184A7BAC00CFA4D8 /* KRSprite.cpp in Sources */, E4CA10EA1637BD2B005D9400 /* KRTexturePVR.cpp in Sources */, E4CA10F01637BD58005D9400 /* KRTextureTGA.cpp in Sources */, + E4F89BB518A6DB1200015637 /* KRTriangle3.cpp in Sources */, E4CA11791639CC90005D9400 /* KRViewport.cpp in Sources */, E41843921678704000DBD6CF /* KRCollider.cpp in Sources */, E4324BAF16444E120043185B /* KRParticleSystemNewtonian.cpp in Sources */, @@ -1741,7 +1823,7 @@ E428C31A1669A25D00A16EDF /* KRAnimationAttribute.cpp in Sources */, E416AA9D1671375C000F6786 /* KRAnimationCurveManager.cpp in Sources */, E480BE6D1671C653004EC8AD /* KRBone.cpp in Sources */, - E43F70E61824D9AB00136169 /* KRTextureStreamer.mm in Sources */, + E43F70E61824D9AB00136169 /* KRStreamer.mm in Sources */, E4C454B0167BB8FC003586CD /* KRMeshCube.cpp in Sources */, E4C454B6167BC05C003586CD /* KRMeshSphere.cpp in Sources */, E4C454BC167BD248003586CD /* KRHitInfo.cpp in Sources */, diff --git a/KREngine/Kraken.xcodeproj/xcuserdata/admin8onf.xcuserdatad/xcschemes/Kraken - ios.xcscheme b/KREngine/Kraken.xcodeproj/xcuserdata/admin8onf.xcuserdatad/xcschemes/Kraken - ios.xcscheme deleted file mode 100644 index 832c872..0000000 --- a/KREngine/Kraken.xcodeproj/xcuserdata/admin8onf.xcuserdatad/xcschemes/Kraken - ios.xcscheme +++ /dev/null @@ -1,59 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/KREngine/Kraken.xcodeproj/xcuserdata/admin8onf.xcuserdatad/xcschemes/Kraken - osx.xcscheme b/KREngine/Kraken.xcodeproj/xcuserdata/admin8onf.xcuserdatad/xcschemes/Kraken - osx.xcscheme deleted file mode 100644 index 03db38e..0000000 --- a/KREngine/Kraken.xcodeproj/xcuserdata/admin8onf.xcuserdatad/xcschemes/Kraken - osx.xcscheme +++ /dev/null @@ -1,59 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/KREngine/Kraken.xcodeproj/xcuserdata/admin8onf.xcuserdatad/xcschemes/Kraken Standard Assets - OSX.xcscheme b/KREngine/Kraken.xcodeproj/xcuserdata/admin8onf.xcuserdatad/xcschemes/Kraken Standard Assets - OSX.xcscheme deleted file mode 100644 index a5f6a90..0000000 --- a/KREngine/Kraken.xcodeproj/xcuserdata/admin8onf.xcuserdatad/xcschemes/Kraken Standard Assets - OSX.xcscheme +++ /dev/null @@ -1,59 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/KREngine/Kraken.xcodeproj/xcuserdata/admin8onf.xcuserdatad/xcschemes/Kraken Standard Assets - iOS.xcscheme b/KREngine/Kraken.xcodeproj/xcuserdata/admin8onf.xcuserdatad/xcschemes/Kraken Standard Assets - iOS.xcscheme deleted file mode 100644 index b95caa0..0000000 --- a/KREngine/Kraken.xcodeproj/xcuserdata/admin8onf.xcuserdatad/xcschemes/Kraken Standard Assets - iOS.xcscheme +++ /dev/null @@ -1,59 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/KREngine/Kraken.xcodeproj/xcuserdata/admin8onf.xcuserdatad/xcschemes/xcschememanagement.plist b/KREngine/Kraken.xcodeproj/xcuserdata/admin8onf.xcuserdatad/xcschemes/xcschememanagement.plist index 46ad7fe..300bfdd 100644 --- a/KREngine/Kraken.xcodeproj/xcuserdata/admin8onf.xcuserdatad/xcschemes/xcschememanagement.plist +++ b/KREngine/Kraken.xcodeproj/xcuserdata/admin8onf.xcuserdatad/xcschemes/xcschememanagement.plist @@ -7,30 +7,22 @@ Kraken - ios.xcscheme isShown - - orderHint - 30 + Kraken - osx.xcscheme isShown - orderHint - 31 Kraken Standard Assets - OSX.xcscheme isShown - orderHint - 33 Kraken Standard Assets - iOS.xcscheme isShown - - orderHint - 32 + SuppressBuildableAutocreation diff --git a/KREngine/kraken/KRAABB.cpp b/KREngine/kraken/KRAABB.cpp index 2532d26..1144dd2 100644 --- a/KREngine/kraken/KRAABB.cpp +++ b/KREngine/kraken/KRAABB.cpp @@ -131,7 +131,7 @@ bool KRAABB::operator <(const KRAABB& b) const bool KRAABB::intersects(const KRAABB& b) const { // Return true if the two volumes intersect - return min.x <= b.max.x && min.y <= b.max.y && min.z <= b.max.z && max.x >= b.min.x && max.y >= b.min.y && max.z >= b.max.z; + return min.x <= b.max.x && min.y <= b.max.y && min.z <= b.max.z && max.x >= b.min.x && max.y >= b.min.y && max.z >= b.min.z; } bool KRAABB::contains(const KRAABB &b) const @@ -279,6 +279,42 @@ bool KRAABB::intersectsRay(const KRVector3 &v1, const KRVector3 &dir) const return true; /* ray hits box */ } +bool KRAABB::intersectsSphere(const KRVector3 ¢er, float radius) const +{ + // Arvo's Algorithm + + float squaredDistance = 0; + + // process X + if (center.x < min.x) { + float diff = center.x - min.x; + squaredDistance += diff * diff; + } else if (center.x > max.x) { + float diff = center.x - max.x; + squaredDistance += diff * diff; + } + + // process Y + if (center.y < min.y) { + float diff = center.y - min.y; + squaredDistance += diff * diff; + } else if (center.y > max.y) { + float diff = center.y - max.y; + squaredDistance += diff * diff; + } + + // process Z + if (center.z < min.z) { + float diff = center.z - min.z; + squaredDistance += diff * diff; + } else if (center.z > max.z) { + float diff = center.z - max.z; + squaredDistance += diff * diff; + } + + return squaredDistance <= radius; +} + void KRAABB::encapsulate(const KRAABB & b) { if(b.min.x < min.x) min.x = b.min.x; diff --git a/KREngine/kraken/KRAABB.h b/KREngine/kraken/KRAABB.h index a0fbbfd..6a03c07 100644 --- a/KREngine/kraken/KRAABB.h +++ b/KREngine/kraken/KRAABB.h @@ -35,6 +35,7 @@ public: bool intersectsLine(const KRVector3 &v1, const KRVector3 &v2) const; bool intersectsRay(const KRVector3 &v1, const KRVector3 &dir) const; + bool intersectsSphere(const KRVector3 ¢er, float radius) const; void encapsulate(const KRAABB & b); KRAABB& operator =(const KRAABB& b); diff --git a/KREngine/kraken/KRAmbientZone.cpp b/KREngine/kraken/KRAmbientZone.cpp index 927caa5..cc7675a 100644 --- a/KREngine/kraken/KRAmbientZone.cpp +++ b/KREngine/kraken/KRAmbientZone.cpp @@ -87,6 +87,7 @@ void KRAmbientZone::setZone(const std::string &zone) void KRAmbientZone::render(KRCamera *pCamera, std::vector &point_lights, std::vector &directional_lights, std::vector&spot_lights, const KRViewport &viewport, KRNode::RenderPass renderPass) { + if(m_lod_visible <= LOD_VISIBILITY_PRESTREAM) return; KRNode::render(pCamera, point_lights, directional_lights, spot_lights, viewport, renderPass); @@ -112,7 +113,7 @@ void KRAmbientZone::render(KRCamera *pCamera, std::vector &point GLDEBUG(glEnable(GL_DEPTH_TEST)); GLDEBUG(glDepthFunc(GL_LEQUAL)); GLDEBUG(glDepthRangef(0.0, 1.0)); - std::vector sphereModels = getContext().getModelManager()->getModel("__sphere"); + std::vector sphereModels = getContext().getMeshManager()->getModel("__sphere"); if(sphereModels.size()) { for(int i=0; i < sphereModels[0]->getSubmeshCount(); i++) { sphereModels[0]->renderSubmesh(i, renderPass, getName(), "visualize_overlay"); diff --git a/KREngine/kraken/KRAnimation.cpp b/KREngine/kraken/KRAnimation.cpp index 7db4273..2624ce4 100644 --- a/KREngine/kraken/KRAnimation.cpp +++ b/KREngine/kraken/KRAnimation.cpp @@ -237,6 +237,8 @@ void KRAnimation::setLooping(bool looping) m_loop = looping; } + + KRAnimation *KRAnimation::split(const std::string &name, float start_time, float duration, bool strip_unchanging_attributes, bool clone_curves) { KRAnimation *new_animation = new KRAnimation(getContext(), name); @@ -255,15 +257,37 @@ KRAnimation *KRAnimation::split(const std::string &name, float start_time, float new_animation->m_layers[new_layer->getName()] = new_layer; for(std::vector::iterator attribute_itr = layer->getAttributes().begin(); attribute_itr != layer->getAttributes().end(); attribute_itr++) { KRAnimationAttribute *attribute = *attribute_itr; - KRAnimationCurve *curve = attribute->getCurve(); - if(curve != NULL) { + + // Updated Dec 9, 2013 by Peter to change the way that attributes are stripped. + // + // If we have been asked to strip_unchanging_attributes then we only want to strip those attributes that don't havechanges + // in any of their components (x, y, z). This means that we have to group the attributes before we check for valueChanges(). + // The attributes won't come through in order, but they do come through in group order (each group of 3 arrives as x, y, z) + // + // Since this method isn't designed to handle groups, this is a bit of a hack. We simply take whatever channel is coming + // through and then check the other associated curves. + // + int targetAttribute = attribute->getTargetAttribute(); + if (targetAttribute > 0) { // we have a valid target that fits within a group of 3 + targetAttribute--; // this is now group relative 0,1,2 is the first group .. 3,4,5 is the second group, etc. + + KRAnimationCurve *curve = attribute->getCurve(); // this is the curve we are currently handling + + int placeInGroup = targetAttribute % 3; // this will be 0, 1 or 2 + static long placeLookup[] = { 1, 2, -1, 1, -2, -1 }; + + KRAnimationAttribute *attribute2 = *(attribute_itr + placeLookup[placeInGroup*2]); + KRAnimationAttribute *attribute3 = *(attribute_itr + placeLookup[placeInGroup*2+1]); + KRAnimationCurve *curve2 = attribute2->getCurve(); + KRAnimationCurve *curve3 = attribute3->getCurve(); + bool include_attribute = true; if(strip_unchanging_attributes) { - if(!curve->valueChanges(start_time, duration)) { - include_attribute = false; + include_attribute = curve->valueChanges(start_time, duration) | + curve2->valueChanges(start_time, duration) | + curve3->valueChanges(start_time, duration); } - } - + if(include_attribute) { KRAnimationAttribute *new_attribute = new KRAnimationAttribute(getContext()); KRAnimationCurve *new_curve = curve; diff --git a/KREngine/kraken/KRAudioManager.cpp b/KREngine/kraken/KRAudioManager.cpp index 4d8158f..5295c4a 100644 --- a/KREngine/kraken/KRAudioManager.cpp +++ b/KREngine/kraken/KRAudioManager.cpp @@ -215,8 +215,11 @@ void KRAudioManager::renderAudio(UInt32 inNumberFrames, AudioBufferList *ioData) uint64_t end_time = mach_absolute_time(); // uint64_t duration = (end_time - start_time) * m_timebase_info.numer / m_timebase_info.denom; // Nanoseconds +// double ms = duration; +// ms = ms / 1000000.0; // uint64_t max_duration = (uint64_t)inNumberFrames * 1000000000 / 44100; // fprintf(stderr, "audio load: %5.1f%% hrtf channels: %li\n", (float)(duration * 1000 / max_duration) / 10.0f, m_mapped_sources.size()); +// printf("ms %2.3f frames %ld audio load: %5.1f%% hrtf channels: %li\n", ms, (unsigned long) inNumberFrames, (float)(duration * 1000 / max_duration) / 10.0f, m_mapped_sources.size()); } float *KRAudioManager::getBlockAddress(int block_offset) @@ -403,11 +406,21 @@ void KRAudioManager::renderBlock() // ----====---- Render Ambient Sound ----====---- renderAmbient(); + + // ----====---- Render Ambient Sound ----====---- + renderLimiter(); } // ----====---- Advance audio sources ----====---- m_audio_frame += KRENGINE_AUDIO_BLOCK_LENGTH; + std::set open_samples = m_openAudioSamples; + + for(auto itr=open_samples.begin(); itr != open_samples.end(); itr++) { + KRAudioSample *sample = *itr; + sample->_endFrame(); + } + m_anticlick_block = false; m_mutex.unlock(); } @@ -1423,6 +1436,16 @@ void KRAudioManager::deactivateAudioSource(KRAudioSource *audioSource) m_activeAudioSources.erase(audioSource); } +void KRAudioManager::_registerOpenAudioSample(KRAudioSample *audioSample) +{ + m_openAudioSamples.insert(audioSample); +} + +void KRAudioManager::_registerCloseAudioSample(KRAudioSample *audioSample) +{ + m_openAudioSamples.erase(audioSample); +} + __int64_t KRAudioManager::getAudioFrame() { return m_audio_frame; @@ -1485,7 +1508,19 @@ void KRAudioManager::setGlobalAmbientGain(float gain) void KRAudioManager::startFrame(float deltaTime) { - m_mutex.lock(); + static unsigned long trackCount = 0; + static unsigned long trackMissed = 0; + trackCount++; + if (trackCount > 200) { +// printf("Missed %ld out of 200 try_lock attempts on audio startFrame\n", trackMissed); + trackCount = 0; + trackMissed = 0; + } + + if (!m_mutex.try_lock()) { + trackMissed++; + return; // if we are rendering audio don't update audio state + } // NOTE: this misses anywhere from 0 to to 30 times out of 200 on the iPad2 // ----====---- Determine Ambient Zone Contributions ----====---- m_ambient_zone_weights.clear(); @@ -1928,4 +1963,127 @@ void KRAudioManager::renderITD() */ -} \ No newline at end of file +} + +static bool audioIsMuted = false; +static bool audioShouldBecomeMuted = false; +static bool audioShouldBecomeUnmuted = false; + +void audioLimit_Mute(bool onNotOff) { + if (onNotOff) { + if (audioIsMuted) { + audioShouldBecomeMuted = false; + audioShouldBecomeUnmuted = false; + return; + } + audioShouldBecomeMuted = true; + audioShouldBecomeUnmuted = false; + } + else { + if (!audioIsMuted) { + audioShouldBecomeMuted = false; + audioShouldBecomeUnmuted = false; + return; + } + audioShouldBecomeMuted = false; + audioShouldBecomeUnmuted = true; + } +} + +float audioGetLimitParameters_Stereo(float *buffer, unsigned long framesize, + unsigned long *attack_sample_position, float *peak) +{ + float limitvol = 1.0; + long attack_position = -1; + *peak = 0.0; + float max = 0.0; + float amplitude = 0.0; + + float *src = buffer; + for (unsigned long i = 0; i < framesize * 2; i++) { + amplitude = fabs(*src); src++; + if (amplitude > max) max = amplitude; + if (amplitude > 0.995) if (attack_position < 0) attack_position = (i+1) / 2; + } + if (max > 0.995) limitvol = 0.995 / max; + *peak = max; + + if (attack_position < 0) attack_position = framesize; + *attack_sample_position = (unsigned long) attack_position; + return limitvol; +} // returns the new limit volume, *attack_sample_position tells how fast we need to reach the new limit + +void audioLimit_Stereo(float *stereo_buffer, unsigned long framesize) +{ + static float limit_value = 1.0; + + // (1) get the limiting parameters for the incoming audio data + float previouslimitvol = limit_value; + float peak; + unsigned long attack_sample_position = framesize; + + // (1a) check for a mute or unmute state then get the next limit volume + float nextlimitvol = 0.0; + if (audioIsMuted && audioShouldBecomeUnmuted) { audioIsMuted = false; audioShouldBecomeUnmuted = false; } + if (audioShouldBecomeMuted) { audioIsMuted = true; audioShouldBecomeMuted = false; } + if (!audioIsMuted) nextlimitvol = audioGetLimitParameters_Stereo(stereo_buffer, framesize, &attack_sample_position, &peak); + + // (1b) if no limiting is needed then return + if ((1.0 == nextlimitvol) && (1.0 == previouslimitvol)) { return; } // no limiting necessary + + // (2) calculate limiting factors + float deltavol = 0.0; + if (previouslimitvol != nextlimitvol) { + deltavol = (nextlimitvol - previouslimitvol) / (float) attack_sample_position; + } + + // (3) do the limiting + float *src = stereo_buffer; + + if (0.0 == deltavol) { // fixed volume + for (unsigned long i=0; i < framesize; i++) { + *src = *src * nextlimitvol; + src++; + *src = *src * nextlimitvol; + src++; + } + } + else { + for (unsigned long i=0; i < attack_sample_position; i++) { // attack phase + *src = *src * previouslimitvol; + src++; + *src = *src * previouslimitvol; + src++; + previouslimitvol += deltavol; + } + if (nextlimitvol < 1.0) { // plateau phase + for (unsigned long i = attack_sample_position; i < framesize; i++) { + *src = *src * nextlimitvol; + src++; + *src = *src * nextlimitvol; + src++; + } + } + } + + // (4) save our limit level for next time + limit_value = nextlimitvol; +} + +void KRAudioManager::mute(bool onNotOff) +{ + audioLimit_Mute(onNotOff); +} + +void KRAudioManager::renderLimiter() +{ + int output_offset = (m_output_accumulation_block_start) % (KRENGINE_REVERB_MAX_SAMPLES * KRENGINE_MAX_OUTPUT_CHANNELS); + float *output = m_output_accumulation + output_offset; + unsigned long numframes = KRENGINE_AUDIO_BLOCK_LENGTH; + audioLimit_Stereo(output, numframes); +} + +void KRAudioManager::goToSleep() +{ + cleanupAudio(); +} diff --git a/KREngine/kraken/KRAudioManager.h b/KREngine/kraken/KRAudioManager.h index e3d0474..7b67b97 100644 --- a/KREngine/kraken/KRAudioManager.h +++ b/KREngine/kraken/KRAudioManager.h @@ -40,23 +40,39 @@ #include "KRMat4.h" #include "KRAudioSource.h" -const int KRENGINE_AUDIO_MAX_POOL_SIZE = 32; -const int KRENGINE_AUDIO_MAX_BUFFER_SIZE = 64*1024; +const int KRENGINE_AUDIO_MAX_POOL_SIZE = 60; //32; + // for Circa we play a maximum of 11 mono audio streams at once + cross fading with ambient + // so we could safely say a maximum of 12 or 13 streams, which would be 39 buffers + // do the WAV files for the reverb use the same buffer pool ??? + +const int KRENGINE_AUDIO_MAX_BUFFER_SIZE = 5120; // in bytes + // this is the buffer for our decoded audio (not the source file data) + // it should be greater then 1152 samples (the size of an mp3 frame in samples) + // so it should be greater then 2304 bytes and also a multiple of 128 samples (to make + // the data flow efficient) but it shouldn't be too large or it will cause + // the render loop to stall out decoding large chunks of mp3 data. + // 2560 bytes would be the smallest size for mono sources, and 5120 would be smallest for stereo. + const int KRENGINE_AUDIO_BUFFERS_PER_SOURCE = 3; -const int KRENGINE_AUDIO_BLOCK_LENGTH = 128; // Length of one block to process. Determines the latency of the audio system and sets size for FFT's used in HRTF convolution -const int KRENGINE_AUDIO_BLOCK_LOG2N = 7; // 2 ^ KRENGINE_AUDIO_BLOCK_LOG2N = KRENGINE_AUDIO_BLOCK_LENGTH +const int KRENGINE_AUDIO_BLOCK_LOG2N = 7; // 2 ^ KRENGINE_AUDIO_BLOCK_LOG2N = KRENGINE_AUDIO_BLOCK_LENGTH + // 7 is 128 .. NOTE: the hrtf code uses magic numbers everywhere and is hardcoded to 128 samples per frame + +const int KRENGINE_AUDIO_BLOCK_LENGTH = 1 << KRENGINE_AUDIO_BLOCK_LOG2N; + // Length of one block to process. Determines the latency of the audio system and sets size for FFT's used in HRTF convolution + // the AUGraph works in 1024 sample chunks. At 128 we are making 8 consecutive calls to the renderBlock method for each + // render initiated by the AUGraph. const int KRENGINE_REVERB_MAX_FFT_LOG2 = 15; const int KRENGINE_REVERB_WORKSPACE_SIZE = 1 << KRENGINE_REVERB_MAX_FFT_LOG2; const float KRENGINE_AUDIO_CUTOFF = 0.02f; // Cutoff gain level, to cull out processing of very quiet sounds -const int KRENGINE_REVERB_MAX_SAMPLES = 435200; // At least 10s reverb impulse response length, divisible by KRENGINE_AUDIO_BLOCK_LENGTH -const int KRENGINE_MAX_REVERB_IMPULSE_MIX = 16; // Maximum number of impulse response filters that can be mixed simultaneously +const int KRENGINE_REVERB_MAX_SAMPLES = 128000; // 2.9 seconds //435200; // At least 10s reverb impulse response length, divisible by KRENGINE_AUDIO_BLOCK_LENGTH +const int KRENGINE_MAX_REVERB_IMPULSE_MIX = 8; // Maximum number of impulse response filters that can be mixed simultaneously const int KRENGINE_MAX_OUTPUT_CHANNELS = 2; -const int KRENGINE_MAX_ACTIVE_SOURCES = 24; +const int KRENGINE_MAX_ACTIVE_SOURCES = 16; const int KRENGINE_AUDIO_ANTICLICK_SAMPLES = 64; @@ -127,6 +143,8 @@ public: KRAudioBuffer *getBuffer(KRAudioSample &audio_sample, int buffer_index); + static void mute(bool onNotOff); + void goToSleep(); void startFrame(float deltaTime); @@ -142,6 +160,9 @@ public: float getReverbMaxLength(); void setReverbMaxLength(float max_length); + void _registerOpenAudioSample(KRAudioSample *audioSample); + void _registerCloseAudioSample(KRAudioSample *audioSample); + private: bool m_enable_audio; bool m_enable_hrtf; @@ -166,6 +187,8 @@ private: std::set m_activeAudioSources; + std::set m_openAudioSamples; + void initAudio(); void initOpenAL(); void initSiren(); @@ -174,7 +197,6 @@ private: void cleanupAudio(); void cleanupOpenAL(); void cleanupSiren(); - audio_engine_t m_audio_engine; @@ -215,6 +237,7 @@ private: void renderHRTF(); void renderITD(); void renderReverbImpulseResponse(int impulse_response_offset, int frame_count_log2); + void renderLimiter(); std::vector m_hrtf_sample_locations; float *m_hrtf_data; diff --git a/KREngine/kraken/KRAudioSample.cpp b/KREngine/kraken/KRAudioSample.cpp index b115711..a45fa6f 100644 --- a/KREngine/kraken/KRAudioSample.cpp +++ b/KREngine/kraken/KRAudioSample.cpp @@ -49,7 +49,7 @@ KRAudioSample::KRAudioSample(KRContext &context, std::string name, std::string e m_frameRate = 0; m_bufferCount = 0; - openFile(); + m_last_frame_used = 0; } KRAudioSample::KRAudioSample(KRContext &context, std::string name, std::string extension, KRDataBlock *data) : KRResource(context, name) @@ -64,8 +64,7 @@ KRAudioSample::KRAudioSample(KRContext &context, std::string name, std::string e m_frameRate = 0; m_bufferCount = 0; - openFile(); - + m_last_frame_used = 0; } KRAudioSample::~KRAudioSample() @@ -76,18 +75,21 @@ KRAudioSample::~KRAudioSample() int KRAudioSample::getChannelCount() { - openFile(); + loadInfo(); return m_channelsPerFrame; } int KRAudioSample::getFrameCount() { + loadInfo(); //return (int)((__int64_t)m_totalFrames * (__int64_t)frame_rate / (__int64_t)m_frameRate); return m_totalFrames; } float KRAudioSample::sample(int frame_offset, int frame_rate, int channel) { + loadInfo(); + int c = KRMIN(channel, m_channelsPerFrame - 1); if(frame_offset < 0) { @@ -123,6 +125,10 @@ float KRAudioSample::sample(int frame_offset, int frame_rate, int channel) void KRAudioSample::sample(__int64_t frame_offset, int frame_count, int channel, float *buffer, float amplitude, bool loop) { + loadInfo(); + + m_last_frame_used = getContext().getAudioManager()->getAudioFrame(); + if(loop) { int buffer_offset = 0; int frames_left = frame_count; @@ -231,6 +237,11 @@ void KRAudioSample::openFile() { // AudioFileInitializeWithCallbacks if(m_fileRef == NULL) { + +// printf("Call to KRAudioSample::openFile() with extension: %s\n", m_extension.c_str()); +// The m_extension is valid (it's either wav or mp3 for the files in Circa project) +// so we can key off the extension and use a different data handler for mp3 files if we want to +// // Temp variables UInt32 propertySize; @@ -270,6 +281,8 @@ void KRAudioSample::openFile() m_dataFormat = (outputFormat.mChannelsPerFrame > 1) ? AL_FORMAT_STEREO16 : AL_FORMAT_MONO16; m_channelsPerFrame = outputFormat.mChannelsPerFrame; + + getContext().getAudioManager()->_registerOpenAudioSample(this); } } @@ -284,6 +297,16 @@ void KRAudioSample::closeFile() AudioFileClose(m_audio_file_id); m_audio_file_id = 0; } + + getContext().getAudioManager()->_registerCloseAudioSample(this); +} + +void KRAudioSample::loadInfo() +{ + if(m_frameRate == 0) { + openFile(); + closeFile(); + } } std::string KRAudioSample::getExtension() @@ -299,13 +322,13 @@ bool KRAudioSample::save(KRDataBlock &data) float KRAudioSample::getDuration() { - openFile(); + loadInfo(); return (float)m_totalFrames / (float)m_frameRate; } int KRAudioSample::getBufferCount() { - openFile(); + loadInfo(); return m_bufferCount; } @@ -343,3 +366,11 @@ KRAudioBuffer *KRAudioSample::getBuffer(int index) return buffer; } +void KRAudioSample::_endFrame() +{ + const __int64_t AUDIO_SAMPLE_EXPIRY_FRAMES = 500; + long current_frame = getContext().getAudioManager()->getAudioFrame(); + if(current_frame > m_last_frame_used + AUDIO_SAMPLE_EXPIRY_FRAMES) { + closeFile(); + } +} diff --git a/KREngine/kraken/KRAudioSample.h b/KREngine/kraken/KRAudioSample.h index ab7093b..e348401 100644 --- a/KREngine/kraken/KRAudioSample.h +++ b/KREngine/kraken/KRAudioSample.h @@ -60,8 +60,11 @@ public: float sample(int frame_offset, int frame_rate, int channel); void sample(__int64_t frame_offset, int frame_count, int channel, float *buffer, float amplitude, bool loop); + void _endFrame(); private: + long m_last_frame_used; + std::string m_extension; KRDataBlock *m_pData; @@ -78,6 +81,7 @@ private: void openFile(); void closeFile(); + void loadInfo(); static OSStatus ReadProc( // AudioFile_ReadProc void * inClientData, diff --git a/KREngine/kraken/KRAudioSource.cpp b/KREngine/kraken/KRAudioSource.cpp index dd1668a..874ad22 100644 --- a/KREngine/kraken/KRAudioSource.cpp +++ b/KREngine/kraken/KRAudioSource.cpp @@ -200,6 +200,8 @@ void KRAudioSource::queueBuffer() void KRAudioSource::render(KRCamera *pCamera, std::vector &point_lights, std::vector &directional_lights, std::vector&spot_lights, const KRViewport &viewport, KRNode::RenderPass renderPass) { + if(m_lod_visible <= LOD_VISIBILITY_PRESTREAM) return; + KRNode::render(pCamera, point_lights, directional_lights, spot_lights, viewport, renderPass); bool bVisualize = false; @@ -224,7 +226,7 @@ void KRAudioSource::render(KRCamera *pCamera, std::vector &point GLDEBUG(glEnable(GL_DEPTH_TEST)); GLDEBUG(glDepthFunc(GL_LEQUAL)); GLDEBUG(glDepthRangef(0.0, 1.0)); - std::vector sphereModels = getContext().getModelManager()->getModel("__sphere"); + std::vector sphereModels = getContext().getMeshManager()->getModel("__sphere"); if(sphereModels.size()) { for(int i=0; i < sphereModels[0]->getSubmeshCount(); i++) { sphereModels[0]->renderSubmesh(i, renderPass, getName(), "visualize_overlay"); diff --git a/KREngine/kraken/KRBone.cpp b/KREngine/kraken/KRBone.cpp index 18b4a87..1fdbb62 100644 --- a/KREngine/kraken/KRBone.cpp +++ b/KREngine/kraken/KRBone.cpp @@ -41,6 +41,7 @@ KRAABB KRBone::getBounds() { void KRBone::render(KRCamera *pCamera, std::vector &point_lights, std::vector &directional_lights, std::vector&spot_lights, const KRViewport &viewport, KRNode::RenderPass renderPass) { + if(m_lod_visible <= LOD_VISIBILITY_PRESTREAM) return; KRNode::render(pCamera, point_lights, directional_lights, spot_lights, viewport, renderPass); @@ -64,7 +65,7 @@ void KRBone::render(KRCamera *pCamera, std::vector &point_lights KRVector3 rim_color; if(getContext().getShaderManager()->selectShader(*pCamera, pShader, viewport, sphereModelMatrix, point_lights, directional_lights, spot_lights, 0, renderPass, rim_color, 0.0f)) { - std::vector sphereModels = getContext().getModelManager()->getModel("__sphere"); + std::vector sphereModels = getContext().getMeshManager()->getModel("__sphere"); if(sphereModels.size()) { for(int i=0; i < sphereModels[0]->getSubmeshCount(); i++) { sphereModels[0]->renderSubmesh(i, renderPass, getName(), "visualize_overlay"); diff --git a/KREngine/kraken/KRCamera.cpp b/KREngine/kraken/KRCamera.cpp index 03c0845..d7d5cc6 100644 --- a/KREngine/kraken/KRCamera.cpp +++ b/KREngine/kraken/KRCamera.cpp @@ -39,8 +39,8 @@ KRCamera::KRCamera(KRScene &scene, std::string name) : KRNode(scene, name) { m_last_frame_start = 0; m_particlesAbsoluteTime = 0.0f; - backingWidth = 0; - backingHeight = 0; + m_backingWidth = 0; + m_backingHeight = 0; volumetricBufferWidth = 0; volumetricBufferHeight = 0; m_pSkyBoxTexture = NULL; @@ -54,6 +54,7 @@ KRCamera::KRCamera(KRScene &scene, std::string name) : KRNode(scene, name) { volumetricLightAccumulationBuffer = 0; volumetricLightAccumulationTexture = 0; m_frame_times_filled = 0; + m_downsample = KRVector2::One(); } KRCamera::~KRCamera() { @@ -77,8 +78,13 @@ void KRCamera::loadXML(tinyxml2::XMLElement *e) KRNode::loadXML(e); } +void KRCamera::flushSkybox() +{ + m_pSkyBoxTexture = NULL; // NOTE: the texture manager manages the loading and unloading of the skybox textures +} + void KRCamera::renderFrame(float deltaTime, GLint renderBufferWidth, GLint renderBufferHeight) -{ +{ // ----====---- Record timing information for measuring FPS ----====---- uint64_t current_time = m_pContext->getAbsoluteTimeMilliseconds(); if(m_last_frame_start != 0) { @@ -99,7 +105,7 @@ void KRCamera::renderFrame(float deltaTime, GLint renderBufferWidth, GLint rende //KRMat4 viewMatrix = KRMat4::Invert(getModelMatrix()); - settings.setViewportSize(KRVector2(backingWidth, backingHeight)); + settings.setViewportSize(KRVector2(m_backingWidth, m_backingHeight)); KRMat4 projectionMatrix; projectionMatrix.perspective(settings.perspective_fov, settings.m_viewportSize.x / settings.m_viewportSize.y, settings.perspective_nearz, settings.perspective_farz); m_viewport = KRViewport(settings.getViewportSize(), viewMatrix, projectionMatrix); @@ -110,11 +116,14 @@ void KRCamera::renderFrame(float deltaTime, GLint renderBufferWidth, GLint rende scene.updateOctree(m_viewport); + // ----====---- Pre-stream resources ----====---- + scene.render(this, m_viewport.getVisibleBounds(), m_viewport, KRNode::RENDER_PASS_PRESTREAM, true); + // ----====---- Generate Shadowmaps for Lights ----====---- if(settings.m_cShadowBuffers > 0) { GL_PUSH_GROUP_MARKER("Generate Shadowmaps"); - scene.render(this, m_viewport.getVisibleBounds(), m_viewport, KRNode::RENDER_PASS_GENERATE_SHADOWMAPS, settings.bEnableDeferredLighting); + scene.render(this, m_viewport.getVisibleBounds(), m_viewport, KRNode::RENDER_PASS_GENERATE_SHADOWMAPS, false /*settings.bEnableDeferredLighting*/); GLDEBUG(glViewport(0, 0, m_viewport.getSize().x, m_viewport.getSize().y)); GL_POP_GROUP_MARKER; } @@ -153,7 +162,7 @@ void KRCamera::renderFrame(float deltaTime, GLint renderBufferWidth, GLint rende GLDEBUG(glDisable(GL_BLEND)); // Render the geometry - scene.render(this, m_viewport.getVisibleBounds(), m_viewport, KRNode::RENDER_PASS_DEFERRED_GBUFFER, true); + scene.render(this, m_viewport.getVisibleBounds(), m_viewport, KRNode::RENDER_PASS_DEFERRED_GBUFFER, false); GL_POP_GROUP_MARKER; @@ -167,6 +176,7 @@ void KRCamera::renderFrame(float deltaTime, GLint renderBufferWidth, GLint rende // Set render target GLDEBUG(glBindFramebuffer(GL_FRAMEBUFFER, lightAccumulationBuffer)); GLDEBUG(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, compositeDepthTexture, 0)); + GLDEBUG(glViewport(0, 0, m_viewport.getSize().x * m_downsample.x, m_viewport.getSize().y * m_downsample.y)); GLDEBUG(glClearColor(0.0f, 0.0f, 0.0f, 0.0f)); GLDEBUG(glClear(GL_COLOR_BUFFER_BIT)); @@ -178,10 +188,10 @@ void KRCamera::renderFrame(float deltaTime, GLint renderBufferWidth, GLint rende GLDEBUG(glDepthMask(GL_FALSE)); // Set source to buffers from pass 1 - m_pContext->getTextureManager()->selectTexture(6, NULL); + m_pContext->getTextureManager()->selectTexture(6, NULL, 0.0f, KRTexture::TEXTURE_USAGE_NONE); m_pContext->getTextureManager()->_setActiveTexture(6); GLDEBUG(glBindTexture(GL_TEXTURE_2D, compositeColorTexture)); - m_pContext->getTextureManager()->selectTexture(7, NULL); + m_pContext->getTextureManager()->selectTexture(7, NULL, 0.0f, KRTexture::TEXTURE_USAGE_NONE); m_pContext->getTextureManager()->_setActiveTexture(7); GLDEBUG(glBindTexture(GL_TEXTURE_2D, compositeDepthTexture)); @@ -206,7 +216,7 @@ void KRCamera::renderFrame(float deltaTime, GLint renderBufferWidth, GLint rende GLDEBUG(glClear(GL_COLOR_BUFFER_BIT)); // Set source to buffers from pass 2 - m_pContext->getTextureManager()->selectTexture(6, NULL); + m_pContext->getTextureManager()->selectTexture(6, NULL, 0.0f, KRTexture::TEXTURE_USAGE_NONE); m_pContext->getTextureManager()->_setActiveTexture(6); GLDEBUG(glBindTexture(GL_TEXTURE_2D, lightAccumulationTexture)); @@ -227,10 +237,10 @@ void KRCamera::renderFrame(float deltaTime, GLint renderBufferWidth, GLint rende scene.render(this, m_viewport.getVisibleBounds(), m_viewport, KRNode::RENDER_PASS_DEFERRED_OPAQUE, false); // Deactivate source buffer texture units - m_pContext->getTextureManager()->selectTexture(6, NULL); + m_pContext->getTextureManager()->selectTexture(6, NULL, 0.0f, KRTexture::TEXTURE_USAGE_NONE); m_pContext->getTextureManager()->_setActiveTexture(6); GLDEBUG(glBindTexture(GL_TEXTURE_2D, 0)); - m_pContext->getTextureManager()->selectTexture(7, NULL); + m_pContext->getTextureManager()->selectTexture(7, NULL, 0.0f, KRTexture::TEXTURE_USAGE_NONE); m_pContext->getTextureManager()->_setActiveTexture(7); GLDEBUG(glBindTexture(GL_TEXTURE_2D, 0)); @@ -243,7 +253,7 @@ void KRCamera::renderFrame(float deltaTime, GLint renderBufferWidth, GLint rende // Set render target GLDEBUG(glBindFramebuffer(GL_FRAMEBUFFER, compositeFramebuffer)); GLDEBUG(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, compositeDepthTexture, 0)); - GLDEBUG(glViewport(0, 0, m_viewport.getSize().x, m_viewport.getSize().y)); + GLDEBUG(glViewport(0, 0, m_viewport.getSize().x * m_downsample.x, m_viewport.getSize().y * m_downsample.y)); // Disable alpha blending GLDEBUG(glDisable(GL_BLEND)); @@ -275,7 +285,7 @@ void KRCamera::renderFrame(float deltaTime, GLint renderBufferWidth, GLint rende // Render the geometry - scene.render(this, m_viewport.getVisibleBounds(), m_viewport, KRNode::RENDER_PASS_FORWARD_OPAQUE, true); + scene.render(this, m_viewport.getVisibleBounds(), m_viewport, KRNode::RENDER_PASS_FORWARD_OPAQUE, false); GL_POP_GROUP_MARKER; } @@ -308,10 +318,10 @@ void KRCamera::renderFrame(float deltaTime, GLint renderBufferWidth, GLint rende KRVector3 rim_color; getContext().getShaderManager()->selectShader("sky_box", *this, std::vector(), std::vector(), std::vector(), 0, m_viewport, KRMat4(), false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, KRNode::RENDER_PASS_FORWARD_OPAQUE, rim_color, 0.0f); - getContext().getTextureManager()->selectTexture(0, m_pSkyBoxTexture); + getContext().getTextureManager()->selectTexture(0, m_pSkyBoxTexture, 0.0f, KRTexture::TEXTURE_USAGE_SKY_CUBE); // Render a full screen quad - m_pContext->getModelManager()->bindVBO(getContext().getModelManager()->KRENGINE_VBO_2D_SQUARE_VERTICES, getContext().getModelManager()->KRENGINE_VBO_2D_SQUARE_INDEXES, getContext().getModelManager()->KRENGINE_VBO_2D_SQUARE_ATTRIBS, true); + m_pContext->getMeshManager()->bindVBO(&getContext().getMeshManager()->KRENGINE_VBO_DATA_2D_SQUARE_VERTICES); GLDEBUG(glDrawArrays(GL_TRIANGLE_STRIP, 0, 4)); } @@ -330,7 +340,11 @@ void KRCamera::renderFrame(float deltaTime, GLint renderBufferWidth, GLint rende // // // Disable backface culling // GLDEBUG(glDisable(GL_CULL_FACE)); -// +// + // Enable backface culling + GLDEBUG(glCullFace(GL_BACK)); + GLDEBUG(glEnable(GL_CULL_FACE)); + // Disable z-buffer write GLDEBUG(glDepthMask(GL_FALSE)); // @@ -420,7 +434,7 @@ void KRCamera::renderFrame(float deltaTime, GLint renderBufferWidth, GLint rende // Disable z-buffer test GLDEBUG(glDisable(GL_DEPTH_TEST)); - m_pContext->getTextureManager()->selectTexture(0, NULL); + m_pContext->getTextureManager()->selectTexture(0, NULL, 0.0f, KRTexture::TEXTURE_USAGE_NONE); m_pContext->getTextureManager()->_setActiveTexture(0); GLDEBUG(glBindTexture(GL_TEXTURE_2D, compositeDepthTexture)); @@ -468,7 +482,7 @@ void KRCamera::renderFrame(float deltaTime, GLint renderBufferWidth, GLint rende KRShader *pVisShader = getContext().getShaderManager()->getShader("visualize_overlay", this, std::vector(), std::vector(), std::vector(), 0, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, KRNode::RENDER_PASS_FORWARD_TRANSPARENT); - m_pContext->getModelManager()->bindVBO(getContext().getModelManager()->KRENGINE_VBO_3D_CUBE_VERTICES, getContext().getModelManager()->KRENGINE_VBO_3D_CUBE_INDEXES, getContext().getModelManager()->KRENGINE_VBO_3D_CUBE_ATTRIBS, true); + m_pContext->getMeshManager()->bindVBO(&getContext().getMeshManager()->KRENGINE_VBO_DATA_3D_CUBE_VERTICES); for(unordered_map::iterator itr=m_viewport.getVisibleBounds().begin(); itr != m_viewport.getVisibleBounds().end(); itr++) { KRMat4 matModel = KRMat4(); matModel.scale((*itr).first.size() * 0.5f); @@ -486,12 +500,12 @@ void KRCamera::renderFrame(float deltaTime, GLint renderBufferWidth, GLint rende GL_POP_GROUP_MARKER; -// fprintf(stderr, "VBO Mem: %i Kbyte Texture Mem: %i/%i Kbyte (active/total) Shader Handles: %i Visible Bounds: %i Max Texture LOD: %i\n", (int)m_pContext->getModelManager()->getMemUsed() / 1024, (int)m_pContext->getTextureManager()->getActiveMemUsed() / 1024, (int)m_pContext->getTextureManager()->getMemUsed() / 1024, (int)m_pContext->getShaderManager()->getShaderHandlesUsed(), (int)m_visibleBounds.size(), m_pContext->getTextureManager()->getLODDimCap()); +// fprintf(stderr, "VBO Mem: %i Kbyte Texture Mem: %i/%i Kbyte (active/total) Shader Handles: %i Visible Bounds: %i Max Texture LOD: %i\n", (int)m_pContext->getMeshManager()->getMemUsed() / 1024, (int)m_pContext->getTextureManager()->getActiveMemUsed() / 1024, (int)m_pContext->getTextureManager()->getMemUsed() / 1024, (int)m_pContext->getShaderManager()->getShaderHandlesUsed(), (int)m_visibleBounds.size(), m_pContext->getTextureManager()->getLODDimCap()); GL_PUSH_GROUP_MARKER("Post Processing"); GLDEBUG(glBindFramebuffer(GL_FRAMEBUFFER, defaultFBO)); renderPost(); - m_pContext->getModelManager()->unbindVBO(); + m_pContext->getMeshManager()->unbindVBO(); GL_POP_GROUP_MARKER; @@ -505,9 +519,9 @@ void KRCamera::renderFrame(float deltaTime, GLint renderBufferWidth, GLint rende void KRCamera::createBuffers(GLint renderBufferWidth, GLint renderBufferHeight) { - if(renderBufferWidth != backingWidth || renderBufferHeight != backingHeight) { - backingWidth = renderBufferWidth; - backingHeight = renderBufferHeight; + if(renderBufferWidth != m_backingWidth || renderBufferHeight != m_backingHeight) { + m_backingWidth = renderBufferWidth; + m_backingHeight = renderBufferHeight; if (compositeDepthTexture) { GLDEBUG(glDeleteTextures(1, &compositeDepthTexture)); @@ -546,7 +560,7 @@ void KRCamera::createBuffers(GLint renderBufferWidth, GLint renderBufferHeight) GLDEBUG(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)); GLDEBUG(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE)); // This is necessary for non-power-of-two textures GLDEBUG(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE)); // This is necessary for non-power-of-two textures - GLDEBUG(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, backingWidth, backingHeight, 0, GL_BGRA, GL_UNSIGNED_BYTE, NULL)); + GLDEBUG(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_backingWidth, m_backingHeight, 0, GL_BGRA, GL_UNSIGNED_BYTE, NULL)); GLDEBUG(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, compositeColorTexture, 0)); // ----- Create Depth Texture for compositeFramebuffer ----- @@ -556,9 +570,9 @@ void KRCamera::createBuffers(GLint renderBufferWidth, GLint renderBufferHeight) GLDEBUG(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)); GLDEBUG(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE)); // This is necessary for non-power-of-two textures GLDEBUG(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE)); // This is necessary for non-power-of-two textures - GLDEBUG(glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, backingWidth, backingHeight, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NULL)); - //GLDEBUG(glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT16, backingWidth, backingHeight, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NULL)); - //GLDEBUG(glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24_OES, backingWidth, backingHeight)); + GLDEBUG(glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, m_backingWidth, m_backingHeight, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NULL)); + //GLDEBUG(glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT16, m_backingWidth, m_backingHeight, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NULL)); + //GLDEBUG(glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24_OES, m_backingWidth, m_backingHeight)); GLDEBUG(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, compositeDepthTexture, 0)); // ===== Create offscreen compositing framebuffer object ===== @@ -572,7 +586,7 @@ void KRCamera::createBuffers(GLint renderBufferWidth, GLint renderBufferHeight) GLDEBUG(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)); GLDEBUG(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE)); // This is necessary for non-power-of-two textures GLDEBUG(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE)); // This is necessary for non-power-of-two textures - GLDEBUG(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, backingWidth, backingHeight, 0, GL_BGRA, GL_UNSIGNED_BYTE, NULL)); + GLDEBUG(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_backingWidth, m_backingHeight, 0, GL_BGRA, GL_UNSIGNED_BYTE, NULL)); GLDEBUG(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, lightAccumulationTexture, 0)); } @@ -680,37 +694,37 @@ void KRCamera::renderPost() }}; - + GLDEBUG(glViewport(0, 0, m_viewport.getSize().x, m_viewport.getSize().y)); GLDEBUG(glDisable(GL_DEPTH_TEST)); KRShader *postShader = m_pContext->getShaderManager()->getShader("PostShader", this, std::vector(), std::vector(), std::vector(), 0, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, KRNode::RENDER_PASS_FORWARD_TRANSPARENT); KRVector3 rim_color; getContext().getShaderManager()->selectShader(*this, postShader, m_viewport, KRMat4(), std::vector(), std::vector(), std::vector(), 0, KRNode::RENDER_PASS_FORWARD_TRANSPARENT, rim_color, 0.0f); - m_pContext->getTextureManager()->selectTexture(0, NULL); + m_pContext->getTextureManager()->selectTexture(0, NULL, 0.0f, KRTexture::TEXTURE_USAGE_NONE); m_pContext->getTextureManager()->_setActiveTexture(0); GLDEBUG(glBindTexture(GL_TEXTURE_2D, compositeDepthTexture)); - m_pContext->getTextureManager()->selectTexture(1, NULL); + m_pContext->getTextureManager()->selectTexture(1, NULL, 0.0f, KRTexture::TEXTURE_USAGE_NONE); m_pContext->getTextureManager()->_setActiveTexture(1); GLDEBUG(glBindTexture(GL_TEXTURE_2D, compositeColorTexture)); if(settings.volumetric_environment_enable) { - m_pContext->getTextureManager()->selectTexture(2, NULL); + m_pContext->getTextureManager()->selectTexture(2, NULL, 0.0f, KRTexture::TEXTURE_USAGE_NONE); m_pContext->getTextureManager()->_setActiveTexture(2); GLDEBUG(glBindTexture(GL_TEXTURE_2D, volumetricLightAccumulationTexture)); } // Update attribute values. - m_pContext->getModelManager()->bindVBO(getContext().getModelManager()->KRENGINE_VBO_2D_SQUARE_VERTICES, getContext().getModelManager()->KRENGINE_VBO_2D_SQUARE_INDEXES, getContext().getModelManager()->KRENGINE_VBO_2D_SQUARE_ATTRIBS, true); + m_pContext->getMeshManager()->bindVBO(&getContext().getMeshManager()->KRENGINE_VBO_DATA_2D_SQUARE_VERTICES); GLDEBUG(glDrawArrays(GL_TRIANGLE_STRIP, 0, 4)); - m_pContext->getTextureManager()->selectTexture(0, NULL); + m_pContext->getTextureManager()->selectTexture(0, NULL, 0.0f, KRTexture::TEXTURE_USAGE_NONE); m_pContext->getTextureManager()->_setActiveTexture(0); GLDEBUG(glBindTexture(GL_TEXTURE_2D, 0)); - m_pContext->getTextureManager()->selectTexture(1, NULL); + m_pContext->getTextureManager()->selectTexture(1, NULL, 0.0f, KRTexture::TEXTURE_USAGE_NONE); m_pContext->getTextureManager()->_setActiveTexture(1); GLDEBUG(glBindTexture(GL_TEXTURE_2D, 0)); @@ -724,7 +738,7 @@ void KRCamera::renderPost() // viewMatrix.translate(-0.70, 0.70 - 0.45 * iShadow, 0.0); // getContext().getShaderManager()->selectShader(blitShader, KRViewport(getViewportSize(), viewMatrix, KRMat4()), shadowViewports, KRMat4(), KRVector3(), NULL, 0, KRNode::RENDER_PASS_FORWARD_TRANSPARENT); // m_pContext->getTextureManager()->selectTexture(1, NULL); -// m_pContext->getModelManager()->bindVBO(KRENGINE_VBO_2D_SQUARE_INDICES, KRENGINE_VBO_2D_SQUARE_VERTEXES, KRENGINE_VBO_2D_SQUARE_ATTRIBS, true); +// m_pContext->getMeshManager()->bindVBO(&getContext().getMeshManager()->KRENGINE_VBO_DATA_2D_SQUARE_VERTICES); // m_pContext->getTextureManager()->_setActiveTexture(0); // GLDEBUG(glBindTexture(GL_TEXTURE_2D, shadowDepthTexture[iShadow])); //#if GL_EXT_shadow_samplers @@ -744,7 +758,7 @@ void KRCamera::renderPost() if(m_debug_text_vertices.getSize()) { - m_pContext->getModelManager()->releaseVBO(m_debug_text_vertices); + m_pContext->getMeshManager()->releaseVBO(m_debug_text_vertices); } const char *szText = settings.m_debug_text.c_str(); @@ -890,11 +904,10 @@ void KRCamera::renderPost() KRVector3 rim_color; getContext().getShaderManager()->selectShader(*this, fontShader, m_viewport, KRMat4(), std::vector(), std::vector(), std::vector(), 0, KRNode::RENDER_PASS_FORWARD_TRANSPARENT, rim_color, 0.0f); - m_pContext->getTextureManager()->selectTexture(0, m_pContext->getTextureManager()->getTexture("font")); + m_pContext->getTextureManager()->selectTexture(0, m_pContext->getTextureManager()->getTexture("font"), 0.0f, KRTexture::TEXTURE_USAGE_UI); KRDataBlock index_data; - //m_pContext->getModelManager()->bindVBO((void *)m_debug_text_vertices, vertex_count * sizeof(DebugTextVertexData), NULL, 0, (1 << KRMesh::KRENGINE_ATTRIB_VERTEX) | (1 << KRMesh::KRENGINE_ATTRIB_TEXUVA), true); - m_pContext->getModelManager()->bindVBO(m_debug_text_vertices, index_data, (1 << KRMesh::KRENGINE_ATTRIB_VERTEX) | (1 << KRMesh::KRENGINE_ATTRIB_TEXUVA), true); + m_pContext->getMeshManager()->bindVBO(m_debug_text_vertices, index_data, (1 << KRMesh::KRENGINE_ATTRIB_VERTEX) | (1 << KRMesh::KRENGINE_ATTRIB_TEXUVA), true); GLDEBUG(glDrawArrays(GL_TRIANGLES, 0, vertex_count)); @@ -978,17 +991,16 @@ std::string KRCamera::getDebugText() // ---- GPU Memory ---- int texture_count_active = m_pContext->getTextureManager()->getActiveTextures().size(); - int texture_count_pooled = m_pContext->getTextureManager()->getPoolTextures().size(); - int texture_count = texture_count_active + texture_count_pooled; + int texture_count = texture_count_active; long texture_mem_active = m_pContext->getTextureManager()->getMemActive(); long texture_mem_used = m_pContext->getTextureManager()->getMemUsed(); long texture_mem_throughput = m_pContext->getTextureManager()->getMemoryTransferedThisFrame(); - int vbo_count_active = m_pContext->getModelManager()->getActiveVBOCount(); - int vbo_count_pooled = m_pContext->getModelManager()->getPoolVBOCount(); - long vbo_mem_active = m_pContext->getModelManager()->getMemActive(); - long vbo_mem_used = m_pContext->getModelManager()->getMemUsed(); - long vbo_mem_throughput = m_pContext->getModelManager()->getMemoryTransferedThisFrame(); + int vbo_count_active = m_pContext->getMeshManager()->getActiveVBOCount(); + int vbo_count_pooled = m_pContext->getMeshManager()->getPoolVBOCount(); + long vbo_mem_active = m_pContext->getMeshManager()->getMemActive(); + long vbo_mem_used = m_pContext->getMeshManager()->getMemUsed(); + long vbo_mem_throughput = m_pContext->getMeshManager()->getMemoryTransferedThisFrame(); long total_mem_active = texture_mem_active + vbo_mem_active; long total_mem_used = texture_mem_used + vbo_mem_used; @@ -1037,7 +1049,7 @@ std::string KRCamera::getDebugText() case KRRenderSettings::KRENGINE_DEBUG_DISPLAY_DRAW_CALLS: // ----====---- List Draw Calls ----====---- { - std::vector draw_calls = m_pContext->getModelManager()->getDrawCalls(); + std::vector draw_calls = m_pContext->getMeshManager()->getDrawCalls(); long draw_call_count = 0; long vertex_count = 0; @@ -1102,7 +1114,18 @@ std::string KRCamera::getDebugText() } -const KRViewport &KRCamera::getViewport() +const KRViewport &KRCamera::getViewport() const { return m_viewport; } + + +KRVector2 KRCamera::getDownsample() +{ + return m_downsample; +} + +void KRCamera::setDownsample(float v) +{ + m_downsample = v; +} diff --git a/KREngine/kraken/KRCamera.h b/KREngine/kraken/KRCamera.h index 560dd4e..b1d2070 100644 --- a/KREngine/kraken/KRCamera.h +++ b/KREngine/kraken/KRCamera.h @@ -59,7 +59,7 @@ public: KRRenderSettings settings; - const KRViewport &getViewport(); + const KRViewport &getViewport() const; virtual std::string getElementName(); @@ -67,11 +67,15 @@ public: virtual void loadXML(tinyxml2::XMLElement *e); std::string getDebugText(); + + void flushSkybox(); // this will delete the skybox and cause the camera to reload a new skybox based on the settings + KRVector2 getDownsample(); + void setDownsample(float v); private: void createBuffers(GLint renderBufferWidth, GLint renderBufferHeight); - GLint backingWidth, backingHeight; + GLint m_backingWidth, m_backingHeight; GLint volumetricBufferWidth, volumetricBufferHeight; GLuint compositeFramebuffer, compositeDepthTexture, compositeColorTexture; @@ -89,7 +93,7 @@ private: float m_particlesAbsoluteTime; - + KRVector2 m_downsample; typedef struct { GLfloat x; diff --git a/KREngine/kraken/KRCollider.cpp b/KREngine/kraken/KRCollider.cpp index ad7eba5..3367423 100644 --- a/KREngine/kraken/KRCollider.cpp +++ b/KREngine/kraken/KRCollider.cpp @@ -77,7 +77,7 @@ void KRCollider::loadXML(tinyxml2::XMLElement *e) { void KRCollider::loadModel() { if(m_models.size() == 0) { - m_models = m_pContext->getModelManager()->getModel(m_model_name.c_str()); // The model manager returns the LOD levels in sorted order, with the highest detail first + m_models = m_pContext->getMeshManager()->getModel(m_model_name.c_str()); // The model manager returns the LOD levels in sorted order, with the highest detail first if(m_models.size() > 0) { getScene().notify_sceneGraphModify(this); } @@ -99,14 +99,17 @@ bool KRCollider::lineCast(const KRVector3 &v0, const KRVector3 &v1, KRHitInfo &h loadModel(); if(m_models.size()) { if(getBounds().intersectsLine(v0, v1)) { - KRHitInfo hitinfo_model_space; - if(hitinfo.didHit()) { - hitinfo_model_space = KRHitInfo(KRMat4::Dot(getInverseModelMatrix(), hitinfo.getPosition()), KRMat4::DotNoTranslate(getInverseModelMatrix(), hitinfo.getNormal()), hitinfo.getNode()); - } KRVector3 v0_model_space = KRMat4::Dot(getInverseModelMatrix(), v0); KRVector3 v1_model_space = KRMat4::Dot(getInverseModelMatrix(), v1); + KRHitInfo hitinfo_model_space; + if(hitinfo.didHit()) { + KRVector3 hit_position_model_space = KRMat4::Dot(getInverseModelMatrix(), hitinfo.getPosition()); + hitinfo_model_space = KRHitInfo(hit_position_model_space, KRMat4::DotNoTranslate(getInverseModelMatrix(), hitinfo.getNormal()), (hit_position_model_space - v0_model_space).magnitude(), hitinfo.getNode()); + } + if(m_models[0]->lineCast(v0_model_space, v1_model_space, hitinfo_model_space)) { - hitinfo = KRHitInfo(KRMat4::Dot(getModelMatrix(), hitinfo_model_space.getPosition()), KRVector3::Normalize(KRMat4::DotNoTranslate(getModelMatrix(), hitinfo_model_space.getNormal())), this); + KRVector3 hit_position_world_space = KRMat4::Dot(getModelMatrix(), hitinfo_model_space.getPosition()); + hitinfo = KRHitInfo(hit_position_world_space, KRVector3::Normalize(KRMat4::DotNoTranslate(getModelMatrix(), hitinfo_model_space.getNormal())), (hit_position_world_space - v0).magnitude(), this); return true; } } @@ -121,14 +124,38 @@ bool KRCollider::rayCast(const KRVector3 &v0, const KRVector3 &dir, KRHitInfo &h loadModel(); if(m_models.size()) { if(getBounds().intersectsRay(v0, dir)) { - KRHitInfo hitinfo_model_space; - if(hitinfo.didHit()) { - hitinfo_model_space = KRHitInfo(KRMat4::Dot(getInverseModelMatrix(), hitinfo.getPosition()), KRVector3::Normalize(KRMat4::DotNoTranslate(getInverseModelMatrix(), hitinfo.getNormal())), hitinfo.getNode()); - } KRVector3 v0_model_space = KRMat4::Dot(getInverseModelMatrix(), v0); KRVector3 dir_model_space = KRVector3::Normalize(KRMat4::DotNoTranslate(getInverseModelMatrix(), dir)); + KRHitInfo hitinfo_model_space; + if(hitinfo.didHit()) { + KRVector3 hit_position_model_space = KRMat4::Dot(getInverseModelMatrix(), hitinfo.getPosition()); + hitinfo_model_space = KRHitInfo(hit_position_model_space, KRVector3::Normalize(KRMat4::DotNoTranslate(getInverseModelMatrix(), hitinfo.getNormal())), (hit_position_model_space - v0_model_space).magnitude(), hitinfo.getNode()); + } + if(m_models[0]->rayCast(v0_model_space, dir_model_space, hitinfo_model_space)) { - hitinfo = KRHitInfo(KRMat4::Dot(getModelMatrix(), hitinfo_model_space.getPosition()), KRVector3::Normalize(KRMat4::DotNoTranslate(getModelMatrix(), hitinfo_model_space.getNormal())), this); + KRVector3 hit_position_world_space = KRMat4::Dot(getModelMatrix(), hitinfo_model_space.getPosition()); + hitinfo = KRHitInfo(hit_position_world_space, KRVector3::Normalize(KRMat4::DotNoTranslate(getModelMatrix(), hitinfo_model_space.getNormal())), (hit_position_world_space - v0).magnitude(), this); + return true; + } + } + } + } + return false; +} + +bool KRCollider::sphereCast(const KRVector3 &v0, const KRVector3 &v1, float radius, KRHitInfo &hitinfo, unsigned int layer_mask) +{ + if(layer_mask & m_layer_mask) { // Only test if layer masks have a common bit set + loadModel(); + if(m_models.size()) { + KRAABB sphereCastBounds = KRAABB( // TODO - Need to cache this; perhaps encasulate within a "spherecast" class to be passed through these functions + KRVector3(KRMIN(v0.x, v1.x) - radius, KRMIN(v0.y, v1.y) - radius, KRMIN(v0.z, v1.z) - radius), + KRVector3(KRMAX(v0.x, v1.x) + radius, KRMAX(v0.y, v1.y) + radius, KRMAX(v0.z, v1.z) + radius) + ); + + if(getBounds().intersects(sphereCastBounds)) { + if(m_models[0]->sphereCast(getModelMatrix(), v0, v1, radius, hitinfo)) { + hitinfo = KRHitInfo(hitinfo.getPosition(), hitinfo.getNormal(), hitinfo.getDistance(), this); return true; } } @@ -160,6 +187,7 @@ void KRCollider::setAudioOcclusion(float audio_occlusion) void KRCollider::render(KRCamera *pCamera, std::vector &point_lights, std::vector &directional_lights, std::vector&spot_lights, const KRViewport &viewport, KRNode::RenderPass renderPass) { + if(m_lod_visible <= LOD_VISIBILITY_PRESTREAM) return; KRNode::render(pCamera, point_lights, directional_lights, spot_lights, viewport, renderPass); diff --git a/KREngine/kraken/KRCollider.h b/KREngine/kraken/KRCollider.h index cabf368..cbf106b 100644 --- a/KREngine/kraken/KRCollider.h +++ b/KREngine/kraken/KRCollider.h @@ -61,6 +61,7 @@ public: bool lineCast(const KRVector3 &v0, const KRVector3 &v1, KRHitInfo &hitinfo, unsigned int layer_mask); bool rayCast(const KRVector3 &v0, const KRVector3 &v1, KRHitInfo &hitinfo, unsigned int layer_mask); + bool sphereCast(const KRVector3 &v0, const KRVector3 &v1, float radius, KRHitInfo &hitinfo, unsigned int layer_mask); unsigned int getLayerMask(); void setLayerMask(unsigned int layer_mask); diff --git a/KREngine/kraken/KRContext.cpp b/KREngine/kraken/KRContext.cpp index 60a4dff..db735b8 100644 --- a/KREngine/kraken/KRContext.cpp +++ b/KREngine/kraken/KRContext.cpp @@ -19,7 +19,7 @@ int KRContext::KRENGINE_MAX_TEXTURE_MEM; int KRContext::KRENGINE_TARGET_TEXTURE_MEM_MAX; int KRContext::KRENGINE_MAX_TEXTURE_DIM; int KRContext::KRENGINE_MIN_TEXTURE_DIM; -int KRContext::KRENGINE_MAX_TEXTURE_THROUGHPUT; +int KRContext::KRENGINE_PRESTREAM_DISTANCE; const char *KRContext::extension_names[KRENGINE_NUM_EXTENSIONS] = { "GL_EXT_texture_storage" @@ -28,7 +28,8 @@ const char *KRContext::extension_names[KRENGINE_NUM_EXTENSIONS] = { KRContext::log_callback *KRContext::s_log_callback = NULL; void *KRContext::s_log_callback_user_data = NULL; -KRContext::KRContext() { +KRContext::KRContext() : m_streamer(*this) +{ m_streamingEnabled = false; mach_timebase_info(&m_timebase_info); @@ -40,7 +41,7 @@ KRContext::KRContext() { m_pShaderManager = new KRShaderManager(*this); m_pTextureManager = new KRTextureManager(*this); m_pMaterialManager = new KRMaterialManager(*this, m_pTextureManager, m_pShaderManager); - m_pModelManager = new KRMeshManager(*this); + m_pMeshManager = new KRMeshManager(*this); m_pSceneManager = new KRSceneManager(*this); m_pAnimationManager = new KRAnimationManager(*this); m_pAnimationCurveManager = new KRAnimationCurveManager(*this); @@ -58,9 +59,9 @@ KRContext::~KRContext() { m_pSceneManager = NULL; } - if(m_pModelManager) { - delete m_pModelManager; - m_pModelManager = NULL; + if(m_pMeshManager) { + delete m_pMeshManager; + m_pMeshManager = NULL; } if(m_pTextureManager) { @@ -146,8 +147,8 @@ KRMaterialManager *KRContext::getMaterialManager() { KRShaderManager *KRContext::getShaderManager() { return m_pShaderManager; } -KRMeshManager *KRContext::getModelManager() { - return m_pModelManager; +KRMeshManager *KRContext::getMeshManager() { + return m_pMeshManager; } KRAnimationManager *KRContext::getAnimationManager() { return m_pAnimationManager; @@ -176,7 +177,7 @@ std::vector KRContext::getResources() for(unordered_map::iterator itr = m_pMaterialManager->getMaterials().begin(); itr != m_pMaterialManager->getMaterials().end(); itr++) { resources.push_back((*itr).second); } - for(unordered_multimap::iterator itr = m_pModelManager->getModels().begin(); itr != m_pModelManager->getModels().end(); itr++) { + for(unordered_multimap::iterator itr = m_pMeshManager->getModels().begin(); itr != m_pMeshManager->getModels().end(); itr++) { resources.push_back((*itr).second); } for(unordered_map::iterator itr = m_pAnimationManager->getAnimations().begin(); itr != m_pAnimationManager->getAnimations().end(); itr++) { @@ -210,7 +211,7 @@ void KRContext::loadResource(const std::string &file_name, KRDataBlock *data) { if(extension.compare("krbundle") == 0) { m_pBundleManager->loadBundle(name.c_str(), data); } else if(extension.compare("krmesh") == 0) { - m_pModelManager->loadModel(name.c_str(), data); + m_pMeshManager->loadModel(name.c_str(), data); } else if(extension.compare("krscene") == 0) { m_pSceneManager->loadScene(name.c_str(), data); } else if(extension.compare("kranimation") == 0) { @@ -262,7 +263,7 @@ void KRContext::rotateBuffers(bool new_frame) { //fprintf(stderr, "Rotating Buffers...\n"); if(!new_frame) GLDEBUG(glFinish()); - m_pModelManager->rotateBuffers(new_frame); + m_pMeshManager->rotateBuffers(new_frame); } void KRContext::detectExtensions() { @@ -272,17 +273,18 @@ void KRContext::detectExtensions() { void KRContext::startFrame(float deltaTime) { + m_streamer.startStreamer(); m_pTextureManager->startFrame(deltaTime); m_pAnimationManager->startFrame(deltaTime); m_pSoundManager->startFrame(deltaTime); - m_pModelManager->startFrame(deltaTime); + m_pMeshManager->startFrame(deltaTime); } void KRContext::endFrame(float deltaTime) { m_pTextureManager->endFrame(deltaTime); m_pAnimationManager->endFrame(deltaTime); - m_pModelManager->endFrame(deltaTime); + m_pMeshManager->endFrame(deltaTime); rotateBuffers(true); m_current_frame++; m_absolute_time += deltaTime; @@ -336,3 +338,13 @@ void KRContext::getMemoryStats(long &free_memory) #error Unsupported Platform #endif } + +void KRContext::doStreaming() +{ + if(m_streamingEnabled) { + long memoryRemaining = KRENGINE_TARGET_TEXTURE_MEM_MAX; + long memoryRemainingThisFrame = KRENGINE_MAX_TEXTURE_MEM - m_pTextureManager->getMemUsed(); + m_pMeshManager->doStreaming(memoryRemaining, memoryRemainingThisFrame); + m_pTextureManager->doStreaming(memoryRemaining, memoryRemainingThisFrame); + } +} diff --git a/KREngine/kraken/KRContext.h b/KREngine/kraken/KRContext.h index 4f91d40..147df98 100644 --- a/KREngine/kraken/KRContext.h +++ b/KREngine/kraken/KRContext.h @@ -20,6 +20,7 @@ #include "KRAnimationCurveManager.h" #include "KRAudioManager.h" #include "KRUnknownManager.h" +#include "KRStreamer.h" class KRContext { public: @@ -31,7 +32,7 @@ public: static int KRENGINE_TARGET_TEXTURE_MEM_MAX; static int KRENGINE_MAX_TEXTURE_DIM; static int KRENGINE_MIN_TEXTURE_DIM; - static int KRENGINE_MAX_TEXTURE_THROUGHPUT; + static int KRENGINE_PRESTREAM_DISTANCE; KRContext(); @@ -45,7 +46,7 @@ public: KRTextureManager *getTextureManager(); KRMaterialManager *getMaterialManager(); KRShaderManager *getShaderManager(); - KRMeshManager *getModelManager(); + KRMeshManager *getMeshManager(); KRAnimationManager *getAnimationManager(); KRAnimationCurveManager *getAnimationCurveManager(); KRAudioManager *getAudioManager(); @@ -88,6 +89,7 @@ public: static void SetLogCallback(log_callback *log_callback, void *user_data); static void Log(log_level level, const std::string &message_format, ...); + void doStreaming(); private: KRBundleManager *m_pBundleManager; @@ -95,7 +97,7 @@ private: KRTextureManager *m_pTextureManager; KRMaterialManager *m_pMaterialManager; KRShaderManager *m_pShaderManager; - KRMeshManager *m_pModelManager; + KRMeshManager *m_pMeshManager; KRAnimationManager *m_pAnimationManager; KRAnimationCurveManager *m_pAnimationCurveManager; KRAudioManager *m_pSoundManager; @@ -114,6 +116,8 @@ private: static log_callback *s_log_callback; static void *s_log_callback_user_data; + + KRStreamer m_streamer; }; #endif diff --git a/KREngine/kraken/KRDirectionalLight.cpp b/KREngine/kraken/KRDirectionalLight.cpp index 8e2e01b..94b86b9 100644 --- a/KREngine/kraken/KRDirectionalLight.cpp +++ b/KREngine/kraken/KRDirectionalLight.cpp @@ -35,7 +35,7 @@ KRVector3 KRDirectionalLight::getWorldLightDirection() { } KRVector3 KRDirectionalLight::getLocalLightDirection() { - return KRVector3::Forward(); + return KRVector3::Up(); //&KRF HACK changed from KRVector3::Forward(); - to compensate for the way Maya handles post rotation. } @@ -89,6 +89,8 @@ int KRDirectionalLight::configureShadowBufferViewports(const KRViewport &viewpor void KRDirectionalLight::render(KRCamera *pCamera, std::vector &point_lights, std::vector &directional_lights, std::vector&spot_lights, const KRViewport &viewport, KRNode::RenderPass renderPass) { + if(m_lod_visible <= LOD_VISIBILITY_PRESTREAM) return; + KRLight::render(pCamera, point_lights, directional_lights, spot_lights, viewport, renderPass); if(renderPass == KRNode::RENDER_PASS_DEFERRED_LIGHTS) { @@ -121,7 +123,7 @@ void KRDirectionalLight::render(KRCamera *pCamera, std::vector & GLDEBUG(glDisable(GL_DEPTH_TEST)); // Render a full screen quad - m_pContext->getModelManager()->bindVBO(getContext().getModelManager()->KRENGINE_VBO_2D_SQUARE_VERTICES, getContext().getModelManager()->KRENGINE_VBO_2D_SQUARE_INDEXES, getContext().getModelManager()->KRENGINE_VBO_2D_SQUARE_ATTRIBS, true); + m_pContext->getMeshManager()->bindVBO(&getContext().getMeshManager()->KRENGINE_VBO_DATA_2D_SQUARE_VERTICES); GLDEBUG(glDrawArrays(GL_TRIANGLE_STRIP, 0, 4)); } } diff --git a/KREngine/kraken/KREngine-common.h b/KREngine/kraken/KREngine-common.h index 5dcf36b..c02b537 100644 --- a/KREngine/kraken/KREngine-common.h +++ b/KREngine/kraken/KREngine-common.h @@ -183,6 +183,12 @@ fprintf(stderr, "Error at line number %d, in file %s. Returned %d for call %s\n" #define KRCLAMP(x, min, max) (KRMAX(KRMIN(x, max), min)) #define KRALIGN(x) ((x + 3) & ~0x03) +typedef enum { + STREAM_LEVEL_OUT, + STREAM_LEVEL_IN_LQ, + STREAM_LEVEL_IN_HQ +} kraken_stream_level; + #include "KRVector4.h" #include "KRVector3.h" #include "KRVector2.h" diff --git a/KREngine/kraken/KREngine.mm b/KREngine/kraken/KREngine.mm index 991fba0..f8c2540 100644 --- a/KREngine/kraken/KREngine.mm +++ b/KREngine/kraken/KREngine.mm @@ -94,8 +94,7 @@ void kraken::set_debug_text(const std::string &print_text) KRContext::KRENGINE_MAX_TEXTURE_HANDLES = 10000; KRContext::KRENGINE_MAX_TEXTURE_DIM = 2048; KRContext::KRENGINE_MIN_TEXTURE_DIM = 64; - - KRContext::KRENGINE_MAX_TEXTURE_THROUGHPUT = 4000000; + KRContext::KRENGINE_PRESTREAM_DISTANCE = 1000.0f; KRContext::KRENGINE_MAX_VBO_MEM = total_ram * 2 / 4; @@ -116,7 +115,6 @@ void kraken::set_debug_text(const std::string &print_text) KRContext::KRENGINE_TARGET_TEXTURE_MEM_MAX = 48000000 * 2; KRContext::KRENGINE_MAX_TEXTURE_DIM = 2048; KRContext::KRENGINE_MIN_TEXTURE_DIM = 64; - KRContext::KRENGINE_MAX_TEXTURE_THROUGHPUT = 32000000; } else { KRContext::KRENGINE_MAX_VBO_HANDLES = 10000; KRContext::KRENGINE_MAX_VBO_MEM = 128000000; @@ -126,7 +124,6 @@ void kraken::set_debug_text(const std::string &print_text) KRContext::KRENGINE_TARGET_TEXTURE_MEM_MAX = 48000000; KRContext::KRENGINE_MAX_TEXTURE_DIM = 2048; KRContext::KRENGINE_MIN_TEXTURE_DIM = 64; - KRContext::KRENGINE_MAX_TEXTURE_THROUGHPUT = 32000000; } */ #else @@ -138,7 +135,7 @@ void kraken::set_debug_text(const std::string &print_text) KRContext::KRENGINE_TARGET_TEXTURE_MEM_MAX = 192000000; KRContext::KRENGINE_MAX_TEXTURE_DIM = 8192; KRContext::KRENGINE_MIN_TEXTURE_DIM = 64; - KRContext::KRENGINE_MAX_TEXTURE_THROUGHPUT = 128000000; + KRContext::KRENGINE_PRESTREAM_DISTANCE = 1000.0f; #endif _context = NULL; @@ -237,14 +234,14 @@ void kraken::set_debug_text(const std::string &print_text) NSString *bundlePath = [[NSBundle mainBundle] pathForResource:bundleName ofType:@"bundle"]; NSBundle *bundle = [NSBundle bundleWithPath:bundlePath]; if(bundle == nil) { - NSLog(@"ERROR - Standard asset bundle could not be found."); + KRContext::Log(KRContext::LOG_LEVEL_ERROR, "%s", "ERROR - Standard asset bundle could not be found."); } else { NSEnumerator *bundleEnumerator = [[bundle pathsForResourcesOfType: nil inDirectory: nil] objectEnumerator]; NSString * p = nil; while (p = [bundleEnumerator nextObject]) { NSString *file_name = [p lastPathComponent]; if([file_name hasSuffix: @".vsh"] || [file_name hasSuffix: @".fsh"] || [file_name hasSuffix: @".krbundle"] ||[file_name hasPrefix:@"font."]) { - NSLog(@" %@\n", file_name); + KRContext::Log(KRContext::LOG_LEVEL_INFORMATION, "%s", [file_name UTF8String]); [self loadResource:p]; } } @@ -689,8 +686,8 @@ void kraken::set_debug_text(const std::string &print_text) -(float)getParameterMaxWithIndex: (int)i { float maxValues[54] = { - PI, 3.0f, 1.0f, 1.0, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 10.0f, - 1.0f, 10.0f, 2.0f, 1.0f, 1.0f, 1.0f, 5.0f, 1.0f, 0.5f, 1.0f, + PI, 3.0f, 1.0f, 1.0, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 2.0f, + 1.0f, 5.0f, 2.0f, 1.0f, 1.0f, 1.0f, 5.0f, 1.0f, 0.5f, 1.0f, 2.0f, 2.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 10.0f, 1000.0f, 1.0f, 5.0f, 1000.0f, 1.0f, 5.0f, 3.0f, 1000.0f, 1000.0f, 0.01f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 10.0f, 1.0f, (float)(KRRenderSettings::KRENGINE_DEBUG_DISPLAY_NUMBER - 1), @@ -760,6 +757,9 @@ void kraken::set_debug_text(const std::string &print_text) (t < 0.5f ? t * 2.0f : (1.0f - t) * 2.0f) * i, (t < 0.5f ? 1.0f : (1.0f - t) * 2.0f) * i ); +#ifdef TEST4REL + printf("Sun Intensity = %f \n", i); +#endif } -(float) getSunIntensity @@ -803,6 +803,9 @@ void kraken::set_debug_text(const std::string &print_text) (t < 0.5f ? t * 2.0f : (1.0f - t) * 2.0f) * i, (t < 0.5f ? 1.0f : (1.0f - t) * 2.0f) * i ); +#ifdef TEST4REL + printf("ambient Intensity = %f \n", i); +#endif } -(float) getAmbientIntensity diff --git a/KREngine/kraken/KRHitInfo.cpp b/KREngine/kraken/KRHitInfo.cpp index 724dfb0..b0b376e 100644 --- a/KREngine/kraken/KRHitInfo.cpp +++ b/KREngine/kraken/KRHitInfo.cpp @@ -36,23 +36,23 @@ KRHitInfo::KRHitInfo() { m_position = KRVector3::Zero(); m_normal = KRVector3::Zero(); + m_distance = 0.0f; m_node = NULL; } -KRHitInfo::KRHitInfo(const KRVector3 &position, const KRVector3 &normal, KRNode *node) +KRHitInfo::KRHitInfo(const KRVector3 &position, const KRVector3 &normal, const float distance, KRNode *node) { m_position = position; - if(m_position == KRVector3::Zero()) { - KRContext::Log(KRContext::LOG_LEVEL_ERROR, "Zero position hitinfo"); - } m_normal = normal; + m_distance = distance; m_node = node; } -KRHitInfo::KRHitInfo(const KRVector3 &position, const KRVector3 &normal) +KRHitInfo::KRHitInfo(const KRVector3 &position, const KRVector3 &normal, const float distance) { m_position = position; m_normal = normal; + m_distance = distance; m_node = NULL; } @@ -76,6 +76,11 @@ KRVector3 KRHitInfo::getNormal() const return m_normal; } +float KRHitInfo::getDistance() const +{ + return m_distance; +} + KRNode *KRHitInfo::getNode() const { return m_node; @@ -85,6 +90,7 @@ KRHitInfo& KRHitInfo::operator =(const KRHitInfo& b) { m_position = b.m_position; m_normal = b.m_normal; + m_distance = b.m_distance; m_node = b.m_node; return *this; } diff --git a/KREngine/kraken/KRHitInfo.h b/KREngine/kraken/KRHitInfo.h index ecadc52..e02feed 100644 --- a/KREngine/kraken/KRHitInfo.h +++ b/KREngine/kraken/KRHitInfo.h @@ -39,12 +39,13 @@ class KRNode; class KRHitInfo { public: KRHitInfo(); - KRHitInfo(const KRVector3 &position, const KRVector3 &normal); - KRHitInfo(const KRVector3 &position, const KRVector3 &normal, KRNode *node); + KRHitInfo(const KRVector3 &position, const KRVector3 &normal, const float distance); + KRHitInfo(const KRVector3 &position, const KRVector3 &normal, const float distance, KRNode *node); ~KRHitInfo(); KRVector3 getPosition() const; KRVector3 getNormal() const; + float getDistance() const; KRNode *getNode() const; bool didHit() const; @@ -55,6 +56,7 @@ private: KRNode *m_node; KRVector3 m_position; KRVector3 m_normal; + float m_distance; }; #endif diff --git a/KREngine/kraken/KRLODGroup.cpp b/KREngine/kraken/KRLODGroup.cpp index 9df0a4f..e3cbe52 100644 --- a/KREngine/kraken/KRLODGroup.cpp +++ b/KREngine/kraken/KRLODGroup.cpp @@ -7,6 +7,7 @@ // #include "KRLODGroup.h" +#include "KRLODSet.h" #include "KRContext.h" KRLODGroup::KRLODGroup(KRScene &scene, std::string name) : KRNode(scene, name) @@ -101,15 +102,17 @@ void KRLODGroup::setReference(const KRAABB &reference) m_reference = reference; } -bool KRLODGroup::getLODVisibility(const KRViewport &viewport) +KRNode::LodVisibility KRLODGroup::calcLODVisibility(const KRViewport &viewport) { if(m_min_distance == 0 && m_max_distance == 0) { - return true; + return LOD_VISIBILITY_VISIBLE; } else { float lod_bias = viewport.getLODBias(); lod_bias = pow(2.0f, -lod_bias); - float sqr_distance; // Compare using squared distances as sqrt is expensive + // Compare using squared distances as sqrt is expensive + float sqr_distance; + float sqr_prestream_distance; KRVector3 world_camera_position = viewport.getCameraPosition(); KRVector3 local_camera_position = worldToLocal(world_camera_position); @@ -118,28 +121,23 @@ bool KRLODGroup::getLODVisibility(const KRViewport &viewport) if(m_use_world_units) { KRVector3 world_reference_point = localToWorld(local_reference_point); sqr_distance = (world_camera_position - world_reference_point).sqrMagnitude() * (lod_bias * lod_bias); + sqr_prestream_distance = getContext().KRENGINE_PRESTREAM_DISTANCE * getContext().KRENGINE_PRESTREAM_DISTANCE; } else { sqr_distance = (local_camera_position - local_reference_point).sqrMagnitude() * (lod_bias * lod_bias); + + KRVector3 world_reference_point = localToWorld(local_reference_point); + sqr_prestream_distance = worldToLocal(KRVector3::Normalize(world_reference_point - world_camera_position) * getContext().KRENGINE_PRESTREAM_DISTANCE).sqrMagnitude(); // TODO, FINDME - Optimize with precalc? + } - float sqr_min_distance = m_min_distance * m_min_distance; - float sqr_max_distance = m_max_distance * m_max_distance; - return ((sqr_distance >= sqr_min_distance || m_min_distance == 0) && (sqr_distance < sqr_max_distance || m_max_distance == 0)); - } -} - -void KRLODGroup::updateLODVisibility(const KRViewport &viewport) -{ - bool new_visibility = getLODVisibility(viewport); - if(!new_visibility) { - hideLOD(); - } else { - if(!m_lod_visible) { - getScene().notify_sceneGraphCreate(this); - m_lod_visible = true; - } - for(std::set::iterator itr=m_childNodes.begin(); itr != m_childNodes.end(); ++itr) { - (*itr)->updateLODVisibility(viewport); + float sqr_min_visible_distance = m_min_distance * m_min_distance; + float sqr_max_visible_distance = m_max_distance * m_max_distance; + if((sqr_distance >= sqr_min_visible_distance || m_min_distance == 0) && (sqr_distance < sqr_max_visible_distance || m_max_distance == 0)) { + return LOD_VISIBILITY_VISIBLE; + } else if((sqr_distance >= sqr_min_visible_distance - sqr_prestream_distance || m_min_distance == 0) && (sqr_distance < sqr_max_visible_distance + sqr_prestream_distance || m_max_distance == 0)) { + return LOD_VISIBILITY_PRESTREAM; + } else { + return LOD_VISIBILITY_HIDDEN; } } } diff --git a/KREngine/kraken/KRLODGroup.h b/KREngine/kraken/KRLODGroup.h index c394fb4..f16929a 100644 --- a/KREngine/kraken/KRLODGroup.h +++ b/KREngine/kraken/KRLODGroup.h @@ -20,8 +20,6 @@ public: virtual tinyxml2::XMLElement *saveXML( tinyxml2::XMLNode *parent); virtual void loadXML(tinyxml2::XMLElement *e); - virtual void updateLODVisibility(const KRViewport &viewport); - float getMinDistance(); float getMaxDistance(); void setMinDistance(float min_distance); @@ -32,8 +30,9 @@ public: void setUseWorldUnits(bool use_world_units); bool getUseWorldUnits() const; + LodVisibility calcLODVisibility(const KRViewport &viewport); + private: - bool getLODVisibility(const KRViewport &viewport); float m_min_distance; float m_max_distance; KRAABB m_reference; // Point of reference, used for distance calculation. Usually set to the bounding box center diff --git a/KREngine/kraken/KRLODSet.cpp b/KREngine/kraken/KRLODSet.cpp index 93fe90d..bb1f144 100644 --- a/KREngine/kraken/KRLODSet.cpp +++ b/KREngine/kraken/KRLODSet.cpp @@ -7,6 +7,7 @@ // #include "KRLODSet.h" +#include "KRLODGroup.h" #include "KRContext.h" KRLODSet::KRLODSet(KRScene &scene, std::string name) : KRNode(scene, name) @@ -33,3 +34,79 @@ void KRLODSet::loadXML(tinyxml2::XMLElement *e) { KRNode::loadXML(e); } + + +void KRLODSet::updateLODVisibility(const KRViewport &viewport) +{ + if(m_lod_visible >= LOD_VISIBILITY_PRESTREAM) { + KRLODGroup *new_active_lod_group = NULL; + + // Upgrade and downgrade LOD groups as needed + for(std::set::iterator itr=m_childNodes.begin(); itr != m_childNodes.end(); ++itr) { + KRLODGroup *lod_group = dynamic_cast(*itr); + assert(lod_group != NULL); + LodVisibility group_lod_visibility = KRMIN(lod_group->calcLODVisibility(viewport), m_lod_visible); + if(group_lod_visibility == LOD_VISIBILITY_VISIBLE) { + new_active_lod_group = lod_group; + } + lod_group->setLODVisibility(group_lod_visibility); + } + + /* + // FINDME, TODO, HACK - Disabled streamer delayed LOD load due to performance issues: + bool streamer_ready = false; + if(new_active_lod_group == NULL) { + streamer_ready = true; + } else if(new_active_lod_group->getStreamLevel(viewport) >= kraken_stream_level::STREAM_LEVEL_IN_LQ) { + streamer_ready = true; + } + */ + bool streamer_ready = true; + + if(streamer_ready) { + // Upgrade and downgrade LOD groups as needed + for(std::set::iterator itr=m_childNodes.begin(); itr != m_childNodes.end(); ++itr) { + KRLODGroup *lod_group = dynamic_cast(*itr); + assert(lod_group != NULL); + LodVisibility group_lod_visibility = KRMIN(lod_group->calcLODVisibility(viewport), m_lod_visible); + lod_group->setLODVisibility(group_lod_visibility); + } + } + + KRNode::updateLODVisibility(viewport); + } +} + +void KRLODSet::setLODVisibility(KRNode::LodVisibility lod_visibility) +{ + if(lod_visibility == LOD_VISIBILITY_HIDDEN) { + KRNode::setLODVisibility(lod_visibility); + } else if(m_lod_visible != lod_visibility) { + // Don't automatically recurse into our children, as only one of those will be activated, by updateLODVisibility + if(m_lod_visible == LOD_VISIBILITY_HIDDEN && lod_visibility >= LOD_VISIBILITY_PRESTREAM) { + getScene().notify_sceneGraphCreate(this); + } + m_lod_visible = lod_visibility; + } +} + +kraken_stream_level KRLODSet::getStreamLevel(const KRViewport &viewport) +{ + KRLODGroup *new_active_lod_group = NULL; + + // Upgrade and downgrade LOD groups as needed + for(std::set::iterator itr=m_childNodes.begin(); itr != m_childNodes.end(); ++itr) { + KRLODGroup *lod_group = dynamic_cast(*itr); + assert(lod_group != NULL); + if(lod_group->calcLODVisibility(viewport) == LOD_VISIBILITY_VISIBLE) { + new_active_lod_group = lod_group; + } + } + + if(new_active_lod_group) { + return new_active_lod_group->getStreamLevel(viewport); + } else { + return kraken_stream_level::STREAM_LEVEL_IN_HQ; + } +} + diff --git a/KREngine/kraken/KRLODSet.h b/KREngine/kraken/KRLODSet.h index cbb5337..2e8034b 100644 --- a/KREngine/kraken/KRLODSet.h +++ b/KREngine/kraken/KRLODSet.h @@ -12,6 +12,8 @@ #include "KRResource.h" #include "KRNode.h" +class KRLODGroup; + class KRLODSet : public KRNode { public: KRLODSet(KRScene &scene, std::string name); @@ -20,6 +22,11 @@ public: virtual tinyxml2::XMLElement *saveXML( tinyxml2::XMLNode *parent); virtual void loadXML(tinyxml2::XMLElement *e); + virtual void updateLODVisibility(const KRViewport &viewport); + + virtual void setLODVisibility(LodVisibility lod_visibility); + + virtual kraken_stream_level getStreamLevel(const KRViewport &viewport); }; diff --git a/KREngine/kraken/KRLight.cpp b/KREngine/kraken/KRLight.cpp index 79a303e..5f4b026 100644 --- a/KREngine/kraken/KRLight.cpp +++ b/KREngine/kraken/KRLight.cpp @@ -176,6 +176,8 @@ float KRLight::getDecayStart() { void KRLight::render(KRCamera *pCamera, std::vector &point_lights, std::vector &directional_lights, std::vector&spot_lights, const KRViewport &viewport, KRNode::RenderPass renderPass) { + if(m_lod_visible <= LOD_VISIBILITY_PRESTREAM) return; + KRNode::render(pCamera, point_lights, directional_lights, spot_lights, viewport, renderPass); if(renderPass == KRNode::RENDER_PASS_GENERATE_SHADOWMAPS && (pCamera->settings.volumetric_environment_enable || pCamera->settings.dust_particle_enable || (pCamera->settings.m_cShadowBuffers > 0 && m_casts_shadow))) { @@ -228,7 +230,7 @@ void KRLight::render(KRCamera *pCamera, std::vector &point_light pParticleShader->setUniform(KRShader::KRENGINE_UNIFORM_FLARE_SIZE, m_dust_particle_size); KRDataBlock particle_index_data; - m_pContext->getModelManager()->bindVBO(m_pContext->getModelManager()->getRandomParticles(), particle_index_data, (1 << KRMesh::KRENGINE_ATTRIB_VERTEX) | (1 << KRMesh::KRENGINE_ATTRIB_TEXUVA), true); + m_pContext->getMeshManager()->bindVBO(m_pContext->getMeshManager()->getRandomParticles(), particle_index_data, (1 << KRMesh::KRENGINE_ATTRIB_VERTEX) | (1 << KRMesh::KRENGINE_ATTRIB_TEXUVA), true); GLDEBUG(glDrawArrays(GL_TRIANGLES, 0, particle_count*3)); } } @@ -269,7 +271,7 @@ void KRLight::render(KRCamera *pCamera, std::vector &point_light pFogShader->setUniform(KRShader::KRENGINE_UNIFORM_LIGHT_COLOR, (m_color * pCamera->settings.volumetric_environment_intensity * m_intensity * -slice_spacing / 1000.0f)); KRDataBlock index_data; - m_pContext->getModelManager()->bindVBO(m_pContext->getModelManager()->getVolumetricLightingVertexes(), index_data, (1 << KRMesh::KRENGINE_ATTRIB_VERTEX), true); + m_pContext->getMeshManager()->bindVBO(m_pContext->getMeshManager()->getVolumetricLightingVertexes(), index_data, (1 << KRMesh::KRENGINE_ATTRIB_VERTEX), true); GLDEBUG(glDrawArrays(GL_TRIANGLES, 0, slice_count*6)); } @@ -296,7 +298,7 @@ void KRLight::render(KRCamera *pCamera, std::vector &point_light GLDEBUG(glBeginQuery(GL_SAMPLES_PASSED, m_occlusionQuery)); #endif - std::vector sphereModels = getContext().getModelManager()->getModel("__sphere"); + std::vector sphereModels = getContext().getMeshManager()->getModel("__sphere"); if(sphereModels.size()) { for(int i=0; i < sphereModels[0]->getSubmeshCount(); i++) { sphereModels[0]->renderSubmesh(i, renderPass, getName(), "occlusion_test"); @@ -338,8 +340,8 @@ void KRLight::render(KRCamera *pCamera, std::vector &point_light if(getContext().getShaderManager()->selectShader(*pCamera, pShader, viewport, getModelMatrix(), point_lights, directional_lights, spot_lights, 0, renderPass, rim_light, 0.0f)) { pShader->setUniform(KRShader::KRENGINE_UNIFORM_MATERIAL_ALPHA, 1.0f); pShader->setUniform(KRShader::KRENGINE_UNIFORM_FLARE_SIZE, m_flareSize); - m_pContext->getTextureManager()->selectTexture(0, m_pFlareTexture); - m_pContext->getModelManager()->bindVBO(getContext().getModelManager()->KRENGINE_VBO_2D_SQUARE_VERTICES, getContext().getModelManager()->KRENGINE_VBO_2D_SQUARE_INDEXES, getContext().getModelManager()->KRENGINE_VBO_2D_SQUARE_ATTRIBS, true); + m_pContext->getTextureManager()->selectTexture(0, m_pFlareTexture, 0.0f, KRTexture::TEXTURE_USAGE_LIGHT_FLARE); + m_pContext->getMeshManager()->bindVBO(&getContext().getMeshManager()->KRENGINE_VBO_DATA_2D_SQUARE_VERTICES); GLDEBUG(glDrawArrays(GL_TRIANGLE_STRIP, 0, 4)); } } diff --git a/KREngine/kraken/KRMaterial.cpp b/KREngine/kraken/KRMaterial.cpp index 141f648..fa91451 100644 --- a/KREngine/kraken/KRMaterial.cpp +++ b/KREngine/kraken/KRMaterial.cpp @@ -118,7 +118,7 @@ bool KRMaterial::save(KRDataBlock &data) { stream << "\n# map_Reflection filename.pvr -s 1.0 1.0 -o 0.0 0.0"; } if(m_reflectionCube.size()) { - stream << "map_ReflectionCube " << m_reflectionCube << ".pvr"; + stream << "\nmap_ReflectionCube " << m_reflectionCube << ".pvr"; } else { stream << "\n# map_ReflectionCube cubemapname"; } @@ -217,9 +217,71 @@ bool KRMaterial::isTransparent() { return m_tr < 1.0 || m_alpha_mode == KRMATERIAL_ALPHA_MODE_BLENDONESIDE || m_alpha_mode == KRMATERIAL_ALPHA_MODE_BLENDTWOSIDE; } -bool KRMaterial::bind(KRCamera *pCamera, std::vector &point_lights, std::vector &directional_lights, std::vector&spot_lights, const std::vector &bones, const std::vector &bind_poses, const KRViewport &viewport, const KRMat4 &matModel, KRTexture *pLightMap, KRNode::RenderPass renderPass, const KRVector3 &rim_color, float rim_power) { - bool bLightMap = pLightMap && pCamera->settings.bEnableLightMap; +void KRMaterial::preStream(float lodCoverage) +{ + getTextures(); + if(m_pAmbientMap) { + m_pAmbientMap->resetPoolExpiry(lodCoverage, KRTexture::TEXTURE_USAGE_AMBIENT_MAP); + } + + if(m_pDiffuseMap) { + m_pDiffuseMap->resetPoolExpiry(lodCoverage, KRTexture::TEXTURE_USAGE_DIFFUSE_MAP); + } + + if(m_pNormalMap) { + m_pNormalMap->resetPoolExpiry(lodCoverage, KRTexture::TEXTURE_USAGE_NORMAL_MAP); + } + + if(m_pSpecularMap) { + m_pSpecularMap->resetPoolExpiry(lodCoverage, KRTexture::TEXTURE_USAGE_SPECULAR_MAP); + } + + if(m_pReflectionMap) { + m_pReflectionMap->resetPoolExpiry(lodCoverage, KRTexture::TEXTURE_USAGE_REFLECTION_MAP); + } + + if(m_pReflectionCube) { + m_pReflectionCube->resetPoolExpiry(lodCoverage, KRTexture::TEXTURE_USAGE_REFECTION_CUBE); + } +} + + +kraken_stream_level KRMaterial::getStreamLevel() +{ + kraken_stream_level stream_level = kraken_stream_level::STREAM_LEVEL_IN_HQ; + + getTextures(); + + if(m_pAmbientMap) { + stream_level = KRMIN(stream_level, m_pAmbientMap->getStreamLevel(KRTexture::TEXTURE_USAGE_AMBIENT_MAP)); + } + + if(m_pDiffuseMap) { + stream_level = KRMIN(stream_level, m_pDiffuseMap->getStreamLevel(KRTexture::TEXTURE_USAGE_DIFFUSE_MAP)); + } + + if(m_pNormalMap) { + stream_level = KRMIN(stream_level, m_pNormalMap->getStreamLevel(KRTexture::TEXTURE_USAGE_NORMAL_MAP)); + } + + if(m_pSpecularMap) { + stream_level = KRMIN(stream_level, m_pSpecularMap->getStreamLevel(KRTexture::TEXTURE_USAGE_SPECULAR_MAP)); + } + + if(m_pReflectionMap) { + stream_level = KRMIN(stream_level, m_pReflectionMap->getStreamLevel(KRTexture::TEXTURE_USAGE_REFLECTION_MAP)); + } + + if(m_pReflectionCube) { + stream_level = KRMIN(stream_level, m_pReflectionCube->getStreamLevel(KRTexture::TEXTURE_USAGE_REFECTION_CUBE)); + } + + return stream_level; +} + +void KRMaterial::getTextures() +{ if(!m_pAmbientMap && m_ambientMap.size()) { m_pAmbientMap = getContext().getTextureManager()->getTexture(m_ambientMap); } @@ -238,6 +300,12 @@ bool KRMaterial::bind(KRCamera *pCamera, std::vector &point_ligh if(!m_pReflectionCube && m_reflectionCube.size()) { m_pReflectionCube = getContext().getTextureManager()->getTextureCube(m_reflectionCube.c_str()); } +} + +bool KRMaterial::bind(KRCamera *pCamera, std::vector &point_lights, std::vector &directional_lights, std::vector&spot_lights, const std::vector &bones, const std::vector &bind_poses, const KRViewport &viewport, const KRMat4 &matModel, KRTexture *pLightMap, KRNode::RenderPass renderPass, const KRVector3 &rim_color, float rim_power, float lod_coverage) { + bool bLightMap = pLightMap && pCamera->settings.bEnableLightMap; + + getTextures(); KRVector2 default_scale = KRVector2::One(); KRVector2 default_offset = KRVector2::Zero(); @@ -321,24 +389,24 @@ bool KRMaterial::bind(KRCamera *pCamera, std::vector &point_ligh pShader->setUniform(KRShader::KRENGINE_UNIFORM_MATERIAL_ALPHA, m_tr); if(bDiffuseMap) { - m_pContext->getTextureManager()->selectTexture(0, m_pDiffuseMap); + m_pContext->getTextureManager()->selectTexture(0, m_pDiffuseMap, lod_coverage, KRTexture::TEXTURE_USAGE_DIFFUSE_MAP); } if(bSpecMap) { - m_pContext->getTextureManager()->selectTexture(1, m_pSpecularMap); + m_pContext->getTextureManager()->selectTexture(1, m_pSpecularMap, lod_coverage, KRTexture::TEXTURE_USAGE_SPECULAR_MAP); } if(bNormalMap) { - m_pContext->getTextureManager()->selectTexture(2, m_pNormalMap); + m_pContext->getTextureManager()->selectTexture(2, m_pNormalMap, lod_coverage, KRTexture::TEXTURE_USAGE_NORMAL_MAP); } - if(bReflectionCubeMap && (renderPass == KRNode::RENDER_PASS_FORWARD_OPAQUE || renderPass == KRNode::RENDER_PASS_DEFERRED_OPAQUE)) { - m_pContext->getTextureManager()->selectTexture(4, m_pReflectionCube); + if(bReflectionCubeMap && (renderPass == KRNode::RENDER_PASS_FORWARD_OPAQUE || renderPass == KRNode::RENDER_PASS_FORWARD_TRANSPARENT || renderPass == KRNode::RENDER_PASS_DEFERRED_OPAQUE)) { + m_pContext->getTextureManager()->selectTexture(4, m_pReflectionCube, lod_coverage, KRTexture::TEXTURE_USAGE_REFECTION_CUBE); } - if(bReflectionMap && (renderPass == KRNode::RENDER_PASS_FORWARD_OPAQUE || renderPass == KRNode::RENDER_PASS_DEFERRED_OPAQUE)) { + if(bReflectionMap && (renderPass == KRNode::RENDER_PASS_FORWARD_OPAQUE || renderPass == KRNode::RENDER_PASS_FORWARD_TRANSPARENT || renderPass == KRNode::RENDER_PASS_DEFERRED_OPAQUE)) { // GL_TEXTURE7 is used for reading the depth buffer in gBuffer pass 2 and re-used for the reflection map in gBuffer Pass 3 and in forward rendering - m_pContext->getTextureManager()->selectTexture(7, m_pReflectionMap); + m_pContext->getTextureManager()->selectTexture(7, m_pReflectionMap, lod_coverage, KRTexture::TEXTURE_USAGE_REFLECTION_MAP); } diff --git a/KREngine/kraken/KRMaterial.h b/KREngine/kraken/KRMaterial.h index ef6d9ee..d15a2a6 100644 --- a/KREngine/kraken/KRMaterial.h +++ b/KREngine/kraken/KRMaterial.h @@ -84,10 +84,13 @@ public: bool isTransparent(); const std::string &getName() const; - bool bind(KRCamera *pCamera, std::vector &point_lights, std::vector &directional_lights, std::vector&spot_lights, const std::vector &bones, const std::vector &bind_poses, const KRViewport &viewport, const KRMat4 &matModel, KRTexture *pLightMap, KRNode::RenderPass renderPass, const KRVector3 &rim_color, float rim_power); + bool bind(KRCamera *pCamera, std::vector &point_lights, std::vector &directional_lights, std::vector&spot_lights, const std::vector &bones, const std::vector &bind_poses, const KRViewport &viewport, const KRMat4 &matModel, KRTexture *pLightMap, KRNode::RenderPass renderPass, const KRVector3 &rim_color, float rim_power, float lod_coverage = 0.0f); bool needsVertexTangents(); + kraken_stream_level getStreamLevel(); + void preStream(float lodCoverage); + private: std::string m_name; @@ -129,6 +132,8 @@ private: GLfloat m_ns; // Shininess alpha_mode_type m_alpha_mode; + + void getTextures(); }; #endif diff --git a/KREngine/kraken/KRMaterialManager.cpp b/KREngine/kraken/KRMaterialManager.cpp index cab3a97..f311873 100644 --- a/KREngine/kraken/KRMaterialManager.cpp +++ b/KREngine/kraken/KRMaterialManager.cpp @@ -153,7 +153,7 @@ bool KRMaterialManager::load(const char *szName, KRDataBlock *data) { } else if(strcmp(szSymbol[1], "blendoneside") == 0) { pMaterial->setAlphaMode(KRMaterial::KRMATERIAL_ALPHA_MODE_BLENDONESIDE); } else if(strcmp(szSymbol[1], "blendtwoside") == 0) { - pMaterial->setAlphaMode(KRMaterial::KRMATERIAL_ALPHA_MODE_BLENDONESIDE); + pMaterial->setAlphaMode(KRMaterial::KRMATERIAL_ALPHA_MODE_BLENDTWOSIDE); } else { pMaterial->setAlphaMode(KRMaterial::KRMATERIAL_ALPHA_MODE_OPAQUE); } diff --git a/KREngine/kraken/KRMesh.cpp b/KREngine/kraken/KRMesh.cpp index f379f27..82f57d5 100644 --- a/KREngine/kraken/KRMesh.cpp +++ b/KREngine/kraken/KRMesh.cpp @@ -35,6 +35,7 @@ #include "KRMesh.h" #include "KRVector3.h" +#include "KRTriangle3.h" #include "KRShader.h" #include "KRShaderManager.h" #include "KRContext.h" @@ -70,7 +71,7 @@ void KRMesh::setName(const std::string name) { if(last_underscore_pos != std::string::npos) { // Found an underscore std::string suffix = name.substr(last_underscore_pos + 1); - if(suffix.find_first_of("lod") == 0) { + if(suffix.find("lod") == 0) { std::string lod_level_string = suffix.substr(3); char *end = NULL; int c = (int)strtol(lod_level_string.c_str(), &end, 10); @@ -90,7 +91,7 @@ int KRMesh::GetLODCoverage(const std::string &name) if(last_underscore_pos != std::string::npos) { // Found an underscore std::string suffix = name.substr(last_underscore_pos + 1); - if(suffix.find_first_of("lod") == 0) { + if(suffix.find("lod") == 0) { std::string lod_level_string = suffix.substr(3); char *end = NULL; int c = (int)strtol(lod_level_string.c_str(), &end, 10); @@ -160,33 +161,60 @@ void KRMesh::loadPack(KRDataBlock *data) { updateAttributeOffsets(); } -void KRMesh::render(const std::string &object_name, KRCamera *pCamera, std::vector &point_lights, std::vector &directional_lights, std::vector&spot_lights, const KRViewport &viewport, const KRMat4 &matModel, KRTexture *pLightMap, KRNode::RenderPass renderPass, const std::vector &bones, const KRVector3 &rim_color, float rim_power) { +void KRMesh::getMaterials() +{ + if(m_materials.size() == 0) { + + for(std::vector::iterator itr = m_submeshes.begin(); itr != m_submeshes.end(); itr++) { + const char *szMaterialName = (*itr)->szMaterialName; + KRMaterial *pMaterial = getContext().getMaterialManager()->getMaterial(szMaterialName); + m_materials.push_back(pMaterial); + if(pMaterial) { + m_uniqueMaterials.insert(pMaterial); + } else { + KRContext::Log(KRContext::LOG_LEVEL_WARNING, "Missing material: %s", szMaterialName); + } + } + + m_hasTransparency = false; + for(std::set::iterator mat_itr = m_uniqueMaterials.begin(); mat_itr != m_uniqueMaterials.end(); mat_itr++) { + if((*mat_itr)->isTransparent()) { + m_hasTransparency = true; + break; + } + } + } +} + +void KRMesh::preStream(float lodCoverage) +{ + getSubmeshes(); + getMaterials(); + for(std::set::iterator mat_itr = m_uniqueMaterials.begin(); mat_itr != m_uniqueMaterials.end(); mat_itr++) { + (*mat_itr)->preStream(lodCoverage); + } +} + +kraken_stream_level KRMesh::getStreamLevel() +{ + kraken_stream_level stream_level = kraken_stream_level::STREAM_LEVEL_IN_HQ; + getSubmeshes(); + getMaterials(); + + for(std::set::iterator mat_itr = m_uniqueMaterials.begin(); mat_itr != m_uniqueMaterials.end(); mat_itr++) { + stream_level = KRMIN(stream_level, (*mat_itr)->getStreamLevel()); + } + + return stream_level; +} + +void KRMesh::render(const std::string &object_name, KRCamera *pCamera, std::vector &point_lights, std::vector &directional_lights, std::vector&spot_lights, const KRViewport &viewport, const KRMat4 &matModel, KRTexture *pLightMap, KRNode::RenderPass renderPass, const std::vector &bones, const KRVector3 &rim_color, float rim_power, float lod_coverage) { //fprintf(stderr, "Rendering model: %s\n", m_name.c_str()); if(renderPass != KRNode::RENDER_PASS_ADDITIVE_PARTICLES && renderPass != KRNode::RENDER_PASS_PARTICLE_OCCLUSION && renderPass != KRNode::RENDER_PASS_VOLUMETRIC_EFFECTS_ADDITIVE) { getSubmeshes(); - if(m_materials.size() == 0) { - - for(std::vector::iterator itr = m_submeshes.begin(); itr != m_submeshes.end(); itr++) { - const char *szMaterialName = (*itr)->szMaterialName; - KRMaterial *pMaterial = getContext().getMaterialManager()->getMaterial(szMaterialName); - m_materials.push_back(pMaterial); - if(pMaterial) { - m_uniqueMaterials.insert(pMaterial); - } else { - KRContext::Log(KRContext::LOG_LEVEL_WARNING, "Missing material: %s", szMaterialName); - } - } - - m_hasTransparency = false; - for(std::set::iterator mat_itr = m_uniqueMaterials.begin(); mat_itr != m_uniqueMaterials.end(); mat_itr++) { - if((*mat_itr)->isTransparent()) { - m_hasTransparency = true; - break; - } - } - } + getMaterials(); int cSubmeshes = m_submeshes.size(); if(renderPass == KRNode::RENDER_PASS_SHADOWMAP) { @@ -214,7 +242,7 @@ void KRMesh::render(const std::string &object_name, KRCamera *pCamera, std::vect for(int i=0; i < bones.size(); i++) { bone_bind_poses.push_back(getBoneBindPose(i)); } - if(pMaterial->bind(pCamera, point_lights, directional_lights, spot_lights, bones, bone_bind_poses, viewport, matModel, pLightMap, renderPass, rim_color, rim_power)) { + if(pMaterial->bind(pCamera, point_lights, directional_lights, spot_lights, bones, bone_bind_poses, viewport, matModel, pLightMap, renderPass, rim_color, rim_power, lod_coverage)) { switch(pMaterial->getAlphaMode()) { case KRMaterial::KRMATERIAL_ALPHA_MODE_OPAQUE: // Non-transparent materials @@ -301,28 +329,27 @@ void KRMesh::renderSubmesh(int iSubmesh, KRNode::RenderPass renderPass, const st int start_index_offset, start_vertex_offset, index_count, vertex_count; getIndexedRange(index_group++, start_index_offset, start_vertex_offset, index_count, vertex_count); - KRDataBlock *vertex_data_block = NULL; - KRDataBlock *index_data_block = NULL; + KRMeshManager::KRVBOData *vbo_data_block = NULL; if(m_submeshes[iSubmesh]->vertex_data_blocks.size() <= vbo_index) { - vertex_data_block = m_pData->getSubBlock(vertex_data_offset + start_vertex_offset * m_vertex_size, vertex_count * m_vertex_size); - index_data_block = m_pData->getSubBlock(index_data_offset + start_index_offset * 2, index_count * 2); + KRDataBlock *vertex_data_block = m_pData->getSubBlock(vertex_data_offset + start_vertex_offset * m_vertex_size, vertex_count * m_vertex_size); + KRDataBlock *index_data_block = m_pData->getSubBlock(index_data_offset + start_index_offset * 2, index_count * 2); + vbo_data_block = new KRMeshManager::KRVBOData(*vertex_data_block, *index_data_block, vertex_attrib_flags, true, false); m_submeshes[iSubmesh]->vertex_data_blocks.push_back(vertex_data_block); m_submeshes[iSubmesh]->index_data_blocks.push_back(index_data_block); + m_submeshes[iSubmesh]->vbo_data_blocks.push_back(vbo_data_block); } else { - vertex_data_block = m_submeshes[iSubmesh]->vertex_data_blocks[vbo_index]; - index_data_block = m_submeshes[iSubmesh]->index_data_blocks[vbo_index]; + vbo_data_block = m_submeshes[iSubmesh]->vbo_data_blocks[vbo_index]; } vbo_index++; - //m_pContext->getModelManager()->bindVBO((unsigned char *)pVertexData + start_vertex_offset * m_vertex_size, vertex_count * m_vertex_size, index_data + start_index_offset, index_count * 2, vertex_attrib_flags, true); - m_pContext->getModelManager()->bindVBO(*vertex_data_block, *index_data_block, vertex_attrib_flags, true); + m_pContext->getMeshManager()->bindVBO(vbo_data_block); int vertex_draw_count = cVertexes; if(vertex_draw_count > index_count - index_group_offset) vertex_draw_count = index_count - index_group_offset; glDrawElements(GL_TRIANGLES, vertex_draw_count, GL_UNSIGNED_SHORT, BUFFER_OFFSET(index_group_offset * 2)); - m_pContext->getModelManager()->log_draw_call(renderPass, object_name, material_name, vertex_draw_count); + m_pContext->getMeshManager()->log_draw_call(renderPass, object_name, material_name, vertex_draw_count); cVertexes -= vertex_draw_count; index_group_offset = 0; } @@ -336,19 +363,20 @@ void KRMesh::renderSubmesh(int iSubmesh, KRNode::RenderPass renderPass, const st GLsizei cBufferVertexes = iBuffer < cBuffers - 1 ? MAX_VBO_SIZE : vertex_count % MAX_VBO_SIZE; int vertex_size = m_vertex_size; - KRDataBlock *vertex_data_block = NULL; - KRDataBlock *index_data_block = NULL; + + KRMeshManager::KRVBOData *vbo_data_block = NULL; if(m_submeshes[iSubmesh]->vertex_data_blocks.size() <= vbo_index) { - vertex_data_block = m_pData->getSubBlock(vertex_data_offset + iBuffer * MAX_VBO_SIZE * vertex_size, vertex_size * cBufferVertexes); - + KRDataBlock *index_data_block = NULL; + KRDataBlock *vertex_data_block = m_pData->getSubBlock(vertex_data_offset + iBuffer * MAX_VBO_SIZE * vertex_size, vertex_size * cBufferVertexes); + vbo_data_block = new KRMeshManager::KRVBOData(*vertex_data_block, *index_data_block, vertex_attrib_flags, true, false); m_submeshes[iSubmesh]->vertex_data_blocks.push_back(vertex_data_block); + m_submeshes[iSubmesh]->vbo_data_blocks.push_back(vbo_data_block); } else { - vertex_data_block = m_submeshes[iSubmesh]->vertex_data_blocks[vbo_index]; + vbo_data_block = m_submeshes[iSubmesh]->vbo_data_blocks[vbo_index]; } vbo_index++; - //m_pContext->getModelManager()->bindVBO((unsigned char *)pVertexData + iBuffer * MAX_VBO_SIZE * vertex_size, vertex_size * cBufferVertexes, NULL, 0, vertex_attrib_flags, true); - m_pContext->getModelManager()->bindVBO(*vertex_data_block, *index_data_block, vertex_attrib_flags, true); + m_pContext->getMeshManager()->bindVBO(vbo_data_block); if(iVertex + cVertexes >= MAX_VBO_SIZE) { @@ -369,7 +397,7 @@ void KRMesh::renderSubmesh(int iSubmesh, KRNode::RenderPass renderPass, const st default: break; } - m_pContext->getModelManager()->log_draw_call(renderPass, object_name, material_name, (MAX_VBO_SIZE - iVertex)); + m_pContext->getMeshManager()->log_draw_call(renderPass, object_name, material_name, (MAX_VBO_SIZE - iVertex)); cVertexes -= (MAX_VBO_SIZE - iVertex); iVertex = 0; @@ -387,7 +415,7 @@ void KRMesh::renderSubmesh(int iSubmesh, KRNode::RenderPass renderPass, const st default: break; } - m_pContext->getModelManager()->log_draw_call(renderPass, object_name, material_name, cVertexes); + m_pContext->getMeshManager()->log_draw_call(renderPass, object_name, material_name, cVertexes); cVertexes = 0; } @@ -981,94 +1009,41 @@ KRMesh::model_format_t KRMesh::getModelFormat() const return f; } -bool KRMesh::rayCast(const KRVector3 &line_v0, const KRVector3 &dir, const KRVector3 &tri_v0, const KRVector3 &tri_v1, const KRVector3 &tri_v2, const KRVector3 &tri_n0, const KRVector3 &tri_n1, const KRVector3 &tri_n2, KRHitInfo &hitinfo) +bool KRMesh::rayCast(const KRVector3 &start, const KRVector3 &dir, const KRTriangle3 &tri, const KRVector3 &tri_n0, const KRVector3 &tri_n1, const KRVector3 &tri_n2, KRHitInfo &hitinfo) { - // algorithm based on Dan Sunday's implementation at http://geomalgorithms.com/a06-_intersect-2.html - const float SMALL_NUM = 0.00000001; // anything that avoids division overflow - KRVector3 u, v, n; // triangle vectors - KRVector3 w0, w; // ray vectors - float r, a, b; // params to calc ray-plane intersect - - // get triangle edge vectors and plane normal - u = tri_v1 - tri_v0; - v = tri_v2 - tri_v0; - n = KRVector3::Cross(u, v); // cross product - if (n == KRVector3::Zero()) // triangle is degenerate - return false; // do not deal with this case - - w0 = line_v0 - tri_v0; - a = -KRVector3::Dot(n, w0); - b = KRVector3::Dot(n,dir); - if (fabs(b) < SMALL_NUM) { // ray is parallel to triangle plane - if (a == 0) - return false; // ray lies in triangle plane - else { - return false; // ray disjoint from plane + KRVector3 hit_point; + if(tri.rayCast(start, dir, hit_point)) { + // ---===--- hit_point is in triangle ---===--- + + float new_hit_distance = (hit_point - start).magnitude(); + if(new_hit_distance < hitinfo.getDistance() || !hitinfo.didHit()) { + // Update the hitinfo object if this hit is closer than the prior hit + + // Interpolate between the three vertex normals, performing a 3-way lerp of tri_n0, tri_n1, and tri_n2 + float distance_v0 = (tri[0] - hit_point).magnitude(); + float distance_v1 = (tri[1] - hit_point).magnitude(); + float distance_v2 = (tri[2] - hit_point).magnitude(); + float distance_total = distance_v0 + distance_v1 + distance_v2; + distance_v0 /= distance_total; + distance_v1 /= distance_total; + distance_v2 /= distance_total; + KRVector3 normal = KRVector3::Normalize(tri_n0 * (1.0 - distance_v0) + tri_n1 * (1.0 - distance_v1) + tri_n2 * (1.0 - distance_v2)); + + hitinfo = KRHitInfo(hit_point, normal, new_hit_distance); + return true; + } else { + return false; // The hit was farther than an existing hit } - } - - // get intersect point of ray with triangle plane - r = a / b; - if (r < 0.0) // ray goes away from triangle - return false; // => no intersect - // for a segment, also test if (r > 1.0) => no intersect - - - KRVector3 hit_point = line_v0 + dir * r; // intersect point of ray and plane - - // is hit_point inside triangle? - float uu, uv, vv, wu, wv, D; - uu = KRVector3::Dot(u,u); - uv = KRVector3::Dot(u,v); - vv = KRVector3::Dot(v,v); - w = hit_point - tri_v0; - wu = KRVector3::Dot(w,u); - wv = KRVector3::Dot(w,v); - D = uv * uv - uu * vv; - - // get and test parametric coords - float s, t; - s = (uv * wv - vv * wu) / D; - if (s < 0.0 || s > 1.0) // hit_point is outside triangle - return false; - t = (uv * wu - uu * wv) / D; - if (t < 0.0 || (s + t) > 1.0) // hit_point is outside triangle - return false; - - float new_hit_distance_sqr = (hit_point - line_v0).sqrMagnitude(); - float prev_hit_distance_sqr = (hitinfo.getPosition() - line_v0).sqrMagnitude(); - // ---===--- hit_point is in triangle ---===--- - - - if(new_hit_distance_sqr < prev_hit_distance_sqr || !hitinfo.didHit()) { - // Update the hitinfo object if this hit is closer than the prior hit - - // Interpolate between the three vertex normals, performing a 3-way lerp of tri_n0, tri_n1, and tri_n2 - float distance_v0 = (tri_v0 - hit_point).magnitude(); - float distance_v1 = (tri_v1 - hit_point).magnitude(); - float distance_v2 = (tri_v2 - hit_point).magnitude(); - float distance_total = distance_v0 + distance_v1 + distance_v2; - distance_v0 /= distance_total; - distance_v1 /= distance_total; - distance_v2 /= distance_total; - KRVector3 normal = KRVector3::Normalize(tri_n0 * (1.0 - distance_v0) + tri_n1 * (1.0 - distance_v1) + tri_n2 * (1.0 - distance_v2)); - - hitinfo = KRHitInfo(hit_point, normal); - return true; } else { - return false; // Either no hit, or the hit was farther than an existing hit + // Dit not hit the triangle + return false; } + } -/* -bool KRMesh::rayCast(const KRVector3 &line_v0, const KRVector3 &dir, int tri_index0, int tri_index1, int tri_index2, KRHitInfo &hitinfo) const -{ - return rayCast(line_v0, dir, getVertexPosition(tri_index0), getVertexPosition(tri_index1), getVertexPosition(tri_index2), getVertexNormal(tri_index0), getVertexNormal(tri_index1), getVertexNormal(tri_index2), hitinfo); -} - */ -bool KRMesh::rayCast(const KRVector3 &v0, const KRVector3 &dir, KRHitInfo &hitinfo) const +bool KRMesh::rayCast(const KRVector3 &start, const KRVector3 &dir, KRHitInfo &hitinfo) const { m_pData->lock(); bool hit_found = false; @@ -1084,7 +1059,9 @@ bool KRMesh::rayCast(const KRVector3 &v0, const KRVector3 &dir, KRHitInfo &hitin tri_vert_index[1] = getTriangleVertexIndex(submesh_index, triangle_index*3 + 1); tri_vert_index[2] = getTriangleVertexIndex(submesh_index, triangle_index*3 + 2); - if(rayCast(v0, dir, getVertexPosition(tri_vert_index[0]), getVertexPosition(tri_vert_index[1]), getVertexPosition(tri_vert_index[2]), getVertexNormal(tri_vert_index[0]), getVertexNormal(tri_vert_index[1]), getVertexNormal(tri_vert_index[2]), hitinfo)) hit_found = true; + KRTriangle3 tri = KRTriangle3(getVertexPosition(tri_vert_index[0]), getVertexPosition(tri_vert_index[1]), getVertexPosition(tri_vert_index[2])); + + if(rayCast(start, dir, tri, getVertexNormal(tri_vert_index[0]), getVertexNormal(tri_vert_index[1]), getVertexNormal(tri_vert_index[2]), hitinfo)) hit_found = true; } break; /* @@ -1111,6 +1088,92 @@ bool KRMesh::rayCast(const KRVector3 &v0, const KRVector3 &dir, KRHitInfo &hitin return hit_found; } + +bool KRMesh::sphereCast(const KRMat4 &model_to_world, const KRVector3 &v0, const KRVector3 &v1, float radius, KRHitInfo &hitinfo) const +{ + m_pData->lock(); + + bool hit_found = false; + for(int submesh_index=0; submesh_index < getSubmeshCount(); submesh_index++) { + int vertex_count = getVertexCount(submesh_index); + switch(getModelFormat()) { + case KRENGINE_MODEL_FORMAT_TRIANGLES: + case KRENGINE_MODEL_FORMAT_INDEXED_TRIANGLES: + for(int triangle_index=0; triangle_index < vertex_count / 3; triangle_index++) { + int tri_vert_index[3]; // FINDME, HACK! This is not very efficient for indexed collider meshes... + tri_vert_index[0] = getTriangleVertexIndex(submesh_index, triangle_index*3); + tri_vert_index[1] = getTriangleVertexIndex(submesh_index, triangle_index*3 + 1); + tri_vert_index[2] = getTriangleVertexIndex(submesh_index, triangle_index*3 + 2); + + KRTriangle3 tri = KRTriangle3(getVertexPosition(tri_vert_index[0]), getVertexPosition(tri_vert_index[1]), getVertexPosition(tri_vert_index[2])); + + if(sphereCast(model_to_world, v0, v1, radius, tri, hitinfo)) hit_found = true; + + /* + KRTriangle3 tri2 = KRTriangle3(getVertexPosition(tri_vert_index[1]), getVertexPosition(tri_vert_index[0]), getVertexPosition(tri_vert_index[2])); + + if(sphereCast(model_to_world, v0, v1, radius, tri2, new_hitinfo)) hit_found = true; + */ + } + break; + /* + + NOTE: Not yet supported: + + case KRENGINE_MODEL_FORMAT_STRIP: + case KRENGINE_MODEL_FORMAT_INDEXED_STRIP: + for(int triangle_index=0; triangle_index < vertex_count - 2; triangle_index++) { + int tri_vert_index[3]; + tri_vert_index[0] = getTriangleVertexIndex(submesh_index, vertex_start + triangle_index*3); + tri_vert_index[1] = getTriangleVertexIndex(submesh_index, vertex_start + triangle_index*3 + 1); + tri_vert_index[2] = getTriangleVertexIndex(submesh_index, vertex_start + triangle_index*3 + 2); + + if(sphereCast(model_to_world, v0, v1, getVertexPosition(vertex_start + triangle_index), getVertexPosition(vertex_start + triangle_index+1), getVertexPosition(vertex_start + triangle_index+2), getVertexNormal(vertex_start + triangle_index), getVertexNormal(vertex_start + triangle_index+1), getVertexNormal(vertex_start + triangle_index+2), new_hitinfo)) hit_found = true; + } + break; + */ + default: + break; + } + } + m_pData->unlock(); + + return hit_found; +} + +bool KRMesh::sphereCast(const KRMat4 &model_to_world, const KRVector3 &v0, const KRVector3 &v1, float radius, const KRTriangle3 &tri, KRHitInfo &hitinfo) +{ + + KRVector3 dir = KRVector3::Normalize(v1 - v0); + KRVector3 start = v0; + + KRVector3 new_hit_point; + float new_hit_distance; + + KRTriangle3 world_tri = KRTriangle3(KRMat4::Dot(model_to_world, tri[0]), KRMat4::Dot(model_to_world, tri[1]), KRMat4::Dot(model_to_world, tri[2])); + + if(world_tri.sphereCast(start, dir, radius, new_hit_point, new_hit_distance)) { + if((!hitinfo.didHit() || hitinfo.getDistance() > new_hit_distance) && new_hit_distance <= (v1 - v0).magnitude()) { + + /* + // Interpolate between the three vertex normals, performing a 3-way lerp of tri_n0, tri_n1, and tri_n2 + float distance_v0 = (tri[0] - new_hit_point).magnitude(); + float distance_v1 = (tri[1] - new_hit_point).magnitude(); + float distance_v2 = (tri[2] - new_hit_point).magnitude(); + float distance_total = distance_v0 + distance_v1 + distance_v2; + distance_v0 /= distance_total; + distance_v1 /= distance_total; + distance_v2 /= distance_total; + KRVector3 normal = KRVector3::Normalize(KRMat4::DotNoTranslate(model_to_world, (tri_n0 * (1.0 - distance_v0) + tri_n1 * (1.0 - distance_v1) + tri_n2 * (1.0 - distance_v2)))); + */ + hitinfo = KRHitInfo(new_hit_point, world_tri.calculateNormal(), new_hit_distance); + return true; + } + } + + return false; +} + bool KRMesh::lineCast(const KRVector3 &v0, const KRVector3 &v1, KRHitInfo &hitinfo) const { m_pData->lock(); diff --git a/KREngine/kraken/KRMesh.h b/KREngine/kraken/KRMesh.h index 92e2162..d62b215 100644 --- a/KREngine/kraken/KRMesh.h +++ b/KREngine/kraken/KRMesh.h @@ -34,6 +34,7 @@ #include "KRMat4.h" #include "KRContext.h" #include "KRBone.h" +#include "KRMeshManager.h" #include "KREngine-common.h" @@ -54,6 +55,7 @@ class KRMaterial; class KRNode; +class KRTriangle3; class KRMesh : public KRResource { @@ -66,6 +68,9 @@ public: KRMesh(KRContext &context, std::string name); virtual ~KRMesh(); + kraken_stream_level getStreamLevel(); + void preStream(float lodCoverage); + bool hasTransparency(); typedef enum { @@ -109,7 +114,7 @@ public: std::vector > bone_weights; } mesh_info; - void render(const std::string &object_name, KRCamera *pCamera, std::vector &point_lights, std::vector &directional_lights, std::vector&spot_lights, const KRViewport &viewport, const KRMat4 &matModel, KRTexture *pLightMap, KRNode::RenderPass renderPass, const std::vector &bones, const KRVector3 &rim_color, float rim_power); + void render(const std::string &object_name, KRCamera *pCamera, std::vector &point_lights, std::vector &directional_lights, std::vector&spot_lights, const KRViewport &viewport, const KRMat4 &matModel, KRTexture *pLightMap, KRNode::RenderPass renderPass, const std::vector &bones, const KRVector3 &rim_color, float rim_power, float lod_coverage = 0.0f); std::string m_lodBaseName; @@ -117,7 +122,7 @@ public: virtual bool save(const std::string& path); virtual bool save(KRDataBlock &data); - void LoadData(/*std::vector<__uint16_t> vertex_indexes, std::vector > vertex_index_bases, std::vector vertices, std::vector uva, std::vector uvb, std::vector normals, std::vector tangents, std::vector submesh_starts, std::vector submesh_lengths, std::vector material_names, std::vector bone_names, std::vector bone_bind_poses, std::vector > bone_indexes, std::vector > bone_weights, model_format_t model_format, */const mesh_info &mi, bool calculate_normals, bool calculate_tangents); + void LoadData(const mesh_info &mi, bool calculate_normals, bool calculate_tangents); void loadPack(KRDataBlock *data); void convertToIndexed(); @@ -137,10 +142,13 @@ public: public: Submesh() {}; ~Submesh() { - for(std::vector::iterator itr = vertex_data_blocks.begin(); itr != vertex_data_blocks.end(); itr++) { + for(auto itr = vbo_data_blocks.begin(); itr != vbo_data_blocks.end(); itr++) { delete (*itr); } - for(std::vector::iterator itr = index_data_blocks.begin(); itr != index_data_blocks.end(); itr++) { + for(auto itr = vertex_data_blocks.begin(); itr != vertex_data_blocks.end(); itr++) { + delete (*itr); + } + for(auto itr = index_data_blocks.begin(); itr != index_data_blocks.end(); itr++) { delete (*itr); } }; @@ -150,6 +158,7 @@ public: char szMaterialName[KRENGINE_MAX_NAME_LENGTH]; vector vertex_data_blocks; vector index_data_blocks; + vector vbo_data_blocks; }; typedef struct { @@ -208,6 +217,7 @@ public: bool lineCast(const KRVector3 &v0, const KRVector3 &v1, KRHitInfo &hitinfo) const; bool rayCast(const KRVector3 &v0, const KRVector3 &dir, KRHitInfo &hitinfo) const; + bool sphereCast(const KRMat4 &model_to_world, const KRVector3 &v0, const KRVector3 &v1, float radius, KRHitInfo &hitinfo) const; static int GetLODCoverage(const std::string &name); private: @@ -216,9 +226,10 @@ private: KRDataBlock *m_pIndexBaseData; void getSubmeshes(); + void getMaterials(); -// bool rayCast(const KRVector3 &line_v0, const KRVector3 &dir, int tri_index0, int tri_index1, int tri_index2, KRHitInfo &hitinfo) const; - static bool rayCast(const KRVector3 &line_v0, const KRVector3 &dir, const KRVector3 &tri_v0, const KRVector3 &tri_v1, const KRVector3 &tri_v2, const KRVector3 &tri_n0, const KRVector3 &tri_n1, const KRVector3 &tri_n2, KRHitInfo &hitinfo); + static bool rayCast(const KRVector3 &start, const KRVector3 &dir, const KRTriangle3 &tri, const KRVector3 &tri_n0, const KRVector3 &tri_n1, const KRVector3 &tri_n2, KRHitInfo &hitinfo); + static bool sphereCast(const KRMat4 &model_to_world, const KRVector3 &v0, const KRVector3 &v1, float radius, const KRTriangle3 &tri, KRHitInfo &hitinfo); int m_lodCoverage; // This LOD level is activated when the bounding box of the model will cover less than this percent of the screen (100 = highest detail model) vector m_materials; diff --git a/KREngine/kraken/KRMeshManager.cpp b/KREngine/kraken/KRMeshManager.cpp index 3ef7422..8a039d9 100644 --- a/KREngine/kraken/KRMeshManager.cpp +++ b/KREngine/kraken/KRMeshManager.cpp @@ -38,11 +38,8 @@ #include "KRMeshQuad.h" #include "KRMeshSphere.h" -KRMeshManager::KRMeshManager(KRContext &context) : KRContextObject(context), m_streamer(context) { - m_currentVBO.vbo_handle = -1; - m_currentVBO.vbo_handle_indexes = -1; - m_currentVBO.vao_handle = -1; - m_currentVBO.data = NULL; +KRMeshManager::KRMeshManager(KRContext &context) : KRContextObject(context) { + m_currentVBO = NULL; m_vboMemUsed = 0; m_memoryTransferredThisFrame = 0; @@ -79,6 +76,10 @@ KRMeshManager::KRMeshManager(KRContext &context) : KRContextObject(context), m_s memcpy(KRENGINE_VBO_3D_CUBE_VERTICES.getStart(), _KRENGINE_VBO_3D_CUBE_VERTEX_DATA, sizeof(GLfloat) * 3 * 14); KRENGINE_VBO_3D_CUBE_VERTICES.unlock(); + KRENGINE_VBO_DATA_3D_CUBE_VERTICES.init(KRENGINE_VBO_3D_CUBE_VERTICES, KRENGINE_VBO_3D_CUBE_INDEXES, KRENGINE_VBO_3D_CUBE_ATTRIBS, false, false); + + + static const GLfloat _KRENGINE_VBO_2D_SQUARE_VERTEX_DATA[] = { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 0.0f, 1.0f, 0.0f, @@ -90,6 +91,9 @@ KRMeshManager::KRMeshManager(KRContext &context) : KRContextObject(context), m_s KRENGINE_VBO_2D_SQUARE_VERTICES.lock(); memcpy(KRENGINE_VBO_2D_SQUARE_VERTICES.getStart(), _KRENGINE_VBO_2D_SQUARE_VERTEX_DATA, sizeof(GLfloat) * 5 * 4); KRENGINE_VBO_2D_SQUARE_VERTICES.unlock(); + + KRENGINE_VBO_DATA_2D_SQUARE_VERTICES.init(KRENGINE_VBO_2D_SQUARE_VERTICES, KRENGINE_VBO_2D_SQUARE_INDEXES, KRENGINE_VBO_2D_SQUARE_ATTRIBS, false, false); + } KRMeshManager::~KRMeshManager() { @@ -140,24 +144,22 @@ unordered_multimap &KRMeshManager::getModels() { } void KRMeshManager::unbindVBO() { - if(m_currentVBO.data != NULL) { + if(m_currentVBO != NULL) { GLDEBUG(glBindBuffer(GL_ARRAY_BUFFER, 0)); GLDEBUG(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)); - m_currentVBO.size = 0; - m_currentVBO.data = NULL; - m_currentVBO.vbo_handle = -1; - m_currentVBO.vbo_handle_indexes = -1; - m_currentVBO.vao_handle = -1; + m_currentVBO = NULL; } } void KRMeshManager::releaseVBO(KRDataBlock &data) { - if(m_currentVBO.data == &data) { - unbindVBO(); + if(m_currentVBO) { + if(m_currentVBO->m_data == &data) { + unbindVBO(); + } } - vbo_info_type vbo_to_release; + KRVBOData *vbo_to_release = NULL; if(m_vbosActive.find(&data) != m_vbosActive.end()) { KRContext::Log(KRContext::LOG_LEVEL_WARNING, "glFinish called due to releasing a VBO that is active in the current frame."); GLDEBUG(glFinish()); @@ -171,133 +173,82 @@ void KRMeshManager::releaseVBO(KRDataBlock &data) m_vbosPool.erase(&data); } - m_vboMemUsed -= vbo_to_release.size; - -#if GL_OES_vertex_array_object - GLDEBUG(glDeleteVertexArraysOES(1, &vbo_to_release.vao_handle)); -#endif - GLDEBUG(glDeleteBuffers(1, &vbo_to_release.vbo_handle)); - if(vbo_to_release.vbo_handle_indexes != -1) { - GLDEBUG(glDeleteBuffers(1, &vbo_to_release.vbo_handle_indexes)); + if(vbo_to_release) { + m_vboMemUsed -= vbo_to_release->getSize(); + + vbo_to_release->unload(); + if(vbo_to_release->isTemporary()) { + delete vbo_to_release; + } } } -void KRMeshManager::bindVBO(KRDataBlock &data, KRDataBlock &index_data, int vertex_attrib_flags, bool static_vbo) { - - if(m_currentVBO.data != &data) { +void KRMeshManager::bindVBO(KRVBOData *vbo_data) +{ + bool vbo_changed = false; + if(m_currentVBO == NULL) { + vbo_changed = true; + } else if(m_currentVBO->m_data != vbo_data->m_data) { + vbo_changed = true; + } + + bool used_vbo_data = false; + + if(vbo_changed) { - if(m_vbosActive.find(&data) != m_vbosActive.end()) { - m_currentVBO = m_vbosActive[&data]; -#if GL_OES_vertex_array_object - GLDEBUG(glBindVertexArrayOES(m_currentVBO.vao_handle)); -#else - GLDEBUG(glBindBuffer(GL_ARRAY_BUFFER, m_currentVBO.vbo_handle)); - configureAttribs(vertex_attrib_flags); - if(m_currentVBO.vbo_handle_indexes == -1) { - GLDEBUG(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)); - } else { - GLDEBUG(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_currentVBO.vbo_handle_indexes)); - } -#endif - } else if(m_vbosPool.find(&data) != m_vbosPool.end()) { - m_currentVBO = m_vbosPool[&data]; - m_vbosPool.erase(&data); - m_vbosActive[&data] = m_currentVBO; -#if GL_OES_vertex_array_object - GLDEBUG(glBindVertexArrayOES(m_currentVBO.vao_handle)); -#else - GLDEBUG(glBindBuffer(GL_ARRAY_BUFFER, m_currentVBO.vbo_handle)); - configureAttribs(vertex_attrib_flags); - if(m_currentVBO.vbo_handle_indexes == -1) { - GLDEBUG(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)); - } else { - GLDEBUG(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_currentVBO.vbo_handle_indexes)); - } -#endif + if(m_vbosActive.find(vbo_data->m_data) != m_vbosActive.end()) { + m_currentVBO = m_vbosActive[vbo_data->m_data]; + + m_currentVBO->bind(); + + } else if(m_vbosPool.find(vbo_data->m_data) != m_vbosPool.end()) { + m_currentVBO = m_vbosPool[vbo_data->m_data]; + m_vbosPool.erase(vbo_data->m_data); + m_vbosActive[vbo_data->m_data] = m_currentVBO; + + m_currentVBO->bind(); + + } else { - while(m_vbosPool.size() + m_vbosActive.size() + 1 >= KRContext::KRENGINE_MAX_VBO_HANDLES || m_vboMemUsed + data.getSize() + index_data.getSize() >= KRContext::KRENGINE_MAX_VBO_MEM) { + while(m_vbosPool.size() + m_vbosActive.size() + 1 >= KRContext::KRENGINE_MAX_VBO_HANDLES || m_vboMemUsed + vbo_data->getSize() >= KRContext::KRENGINE_MAX_VBO_MEM) { if(m_vbosPool.empty()) { KRContext::Log(KRContext::LOG_LEVEL_WARNING, "flushBuffers due to VBO exhaustion..."); m_pContext->rotateBuffers(false); } - unordered_map::iterator first_itr = m_vbosPool.begin(); - vbo_info_type firstVBO = first_itr->second; -#if GL_OES_vertex_array_object - GLDEBUG(glDeleteVertexArraysOES(1, &firstVBO.vao_handle)); -#endif - GLDEBUG(glDeleteBuffers(1, &firstVBO.vbo_handle)); - if(firstVBO.vbo_handle_indexes != -1) { - GLDEBUG(glDeleteBuffers(1, &firstVBO.vbo_handle_indexes)); - } - m_vboMemUsed -= firstVBO.size; + unordered_map::iterator first_itr = m_vbosPool.begin(); + KRVBOData *firstVBO = first_itr->second; m_vbosPool.erase(first_itr); -#if defined(DEBUG) - // If you receive this message multiple times per frame, then there are too many vertices. Consider using LOD models or optimizing for occlusion culling. - fprintf(stderr, "VBO Swapping...\n"); -#endif + + m_vboMemUsed -= firstVBO->getSize(); + firstVBO->unload(); + if(firstVBO->isTemporary()) { + delete firstVBO; + } + // fprintf(stderr, "VBO Swapping...\n"); } - m_currentVBO.vao_handle = -1; - m_currentVBO.vbo_handle = -1; - m_currentVBO.vbo_handle_indexes = -1; - GLDEBUG(glGenBuffers(1, &m_currentVBO.vbo_handle)); - if(index_data.getSize() > 0) { - GLDEBUG(glGenBuffers(1, &m_currentVBO.vbo_handle_indexes)); - } + used_vbo_data = true; + m_currentVBO = vbo_data; -#if GL_OES_vertex_array_object - GLDEBUG(glGenVertexArraysOES(1, &m_currentVBO.vao_handle)); - GLDEBUG(glBindVertexArrayOES(m_currentVBO.vao_handle)); -#endif - - GLDEBUG(glBindBuffer(GL_ARRAY_BUFFER, m_currentVBO.vbo_handle)); -#if GL_OES_mapbuffer + m_currentVBO->load(); + m_memoryTransferredThisFrame += m_currentVBO->getSize(); + m_vboMemUsed += m_currentVBO->getSize(); - GLDEBUG(glBufferData(GL_ARRAY_BUFFER, data.getSize(), NULL, static_vbo ? GL_STATIC_DRAW : GL_DYNAMIC_DRAW)); - GLDEBUG(void *map_ptr = glMapBufferOES(GL_ARRAY_BUFFER, GL_WRITE_ONLY_OES)); - data.copy(map_ptr); - //memcpy(map_ptr, data, size); - GLDEBUG(glUnmapBufferOES(GL_ARRAY_BUFFER)); -#else - data.lock(); - GLDEBUG(glBufferData(GL_ARRAY_BUFFER, data.getSize(), data.getStart(), static_vbo ? GL_STATIC_DRAW : GL_DYNAMIC_DRAW)); - data.unlock(); -#endif - m_memoryTransferredThisFrame += data.getSize(); - m_vboMemUsed += data.getSize(); - configureAttribs(vertex_attrib_flags); - - m_currentVBO.size = data.getSize(); - m_currentVBO.data = &data; - - if(index_data.getSize() == 0) { - GLDEBUG(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)); - } else { - GLDEBUG(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_currentVBO.vbo_handle_indexes)); - -#if GL_OES_mapbuffer - - GLDEBUG(glBufferData(GL_ELEMENT_ARRAY_BUFFER, index_data.getSize(), NULL, static_vbo ? GL_STATIC_DRAW : GL_DYNAMIC_DRAW)); - GLDEBUG(void *map_ptr = glMapBufferOES(GL_ELEMENT_ARRAY_BUFFER, GL_WRITE_ONLY_OES)); - index_data.copy(map_ptr); - //memcpy(map_ptr, index_data, index_data.getSize()); - GLDEBUG(glUnmapBufferOES(GL_ELEMENT_ARRAY_BUFFER)); -#else - index_data.lock(); - GLDEBUG(glBufferData(GL_ELEMENT_ARRAY_BUFFER, index_data.getSize(), index_data.getStart(), static_vbo ? GL_STATIC_DRAW : GL_DYNAMIC_DRAW)); - index_data.unlock(); -#endif - - m_memoryTransferredThisFrame += index_data.getSize(); - m_vboMemUsed += index_data.getSize(); - m_currentVBO.size += index_data.getSize(); - } - - m_vbosActive[&data] = m_currentVBO; + m_vbosActive[vbo_data->m_data] = m_currentVBO; } } + + if(!used_vbo_data && vbo_data->isTemporary()) { + delete vbo_data; + } +} + +void KRMeshManager::bindVBO(KRDataBlock &data, KRDataBlock &index_data, int vertex_attrib_flags, bool static_vbo) +{ + KRVBOData *vbo_data = new KRVBOData(data, index_data, vertex_attrib_flags, static_vbo, true); + bindVBO(vbo_data); } void KRMeshManager::configureAttribs(__int32_t attributes) @@ -377,8 +328,8 @@ long KRMeshManager::getMemUsed() long KRMeshManager::getMemActive() { long mem_active = 0; - for(unordered_map::iterator itr = m_vbosActive.begin(); itr != m_vbosActive.end(); itr++) { - mem_active += (*itr).second.size; + for(unordered_map::iterator itr = m_vbosActive.begin(); itr != m_vbosActive.end(); itr++) { + mem_active += (*itr).second->getSize(); } return mem_active; } @@ -387,12 +338,11 @@ void KRMeshManager::rotateBuffers(bool new_frame) { m_vbosPool.insert(m_vbosActive.begin(), m_vbosActive.end()); m_vbosActive.clear(); - if(m_currentVBO.data != NULL) { + if(m_currentVBO != NULL) { // Ensure that the currently active VBO does not get flushed to free memory - m_vbosPool.erase(m_currentVBO.data); - m_vbosActive[m_currentVBO.data] = m_currentVBO; + m_vbosPool.erase(m_currentVBO->m_data); + m_vbosActive[m_currentVBO->m_data] = m_currentVBO; } - } KRDataBlock &KRMeshManager::getVolumetricLightingVertexes() @@ -529,3 +479,140 @@ std::vector KRMeshManager::getDrawCalls() m_draw_call_log_used = true; return m_draw_calls; } + +void KRMeshManager::doStreaming(long &memoryRemaining, long &memoryRemainingThisFrame) +{ + +} + +KRMeshManager::KRVBOData::KRVBOData() +{ + m_temp_vbo = false; + m_static_vbo = false; + m_data = NULL; + m_index_data = NULL; + m_vertex_attrib_flags = 0; + m_vbo_handle = -1; + m_vbo_handle_indexes = -1; + m_vao_handle = -1; + m_size = 0; +} + +KRMeshManager::KRVBOData::KRVBOData(KRDataBlock &data, KRDataBlock &index_data, int vertex_attrib_flags, bool static_vbo, bool temp_vbo) +{ + init(data,index_data,vertex_attrib_flags, static_vbo, temp_vbo); +} + +void KRMeshManager::KRVBOData::init(KRDataBlock &data, KRDataBlock &index_data, int vertex_attrib_flags, bool static_vbo, bool temp_vbo) +{ + m_temp_vbo = temp_vbo; + m_static_vbo = static_vbo; + m_data = &data; + m_index_data = &index_data; + m_vertex_attrib_flags = vertex_attrib_flags; + + m_vbo_handle = -1; + m_vbo_handle_indexes = -1; + m_vao_handle = -1; + + m_size = m_data->getSize(); + if(m_index_data != NULL) { + m_size += m_index_data->getSize(); + } +} + +KRMeshManager::KRVBOData::~KRVBOData() +{ + +} + + + +void KRMeshManager::KRVBOData::load() +{ + if(isLoaded()) { + return; + } + m_vao_handle = -1; + m_vbo_handle = -1; + m_vbo_handle_indexes = -1; + + GLDEBUG(glGenBuffers(1, &m_vbo_handle)); + if(m_index_data->getSize() > 0) { + GLDEBUG(glGenBuffers(1, &m_vbo_handle_indexes)); + } + + + +#if GL_OES_vertex_array_object + GLDEBUG(glGenVertexArraysOES(1, &m_vao_handle)); + GLDEBUG(glBindVertexArrayOES(m_vao_handle)); +#endif + + GLDEBUG(glBindBuffer(GL_ARRAY_BUFFER, m_vbo_handle)); +#if GL_OES_mapbuffer + + GLDEBUG(glBufferData(GL_ARRAY_BUFFER, m_data->getSize(), NULL, m_static_vbo ? GL_STATIC_DRAW : GL_DYNAMIC_DRAW)); + GLDEBUG(void *map_ptr = glMapBufferOES(GL_ARRAY_BUFFER, GL_WRITE_ONLY_OES)); + m_data->copy(map_ptr); + GLDEBUG(glUnmapBufferOES(GL_ARRAY_BUFFER)); +#else + m_data->lock(); + GLDEBUG(glBufferData(GL_ARRAY_BUFFER, m_data->getSize(), m_data->getStart(), m_static_vbo ? GL_STATIC_DRAW : GL_DYNAMIC_DRAW)); + m_data->unlock(); +#endif + + configureAttribs(m_vertex_attrib_flags); + + if(m_index_data->getSize() == 0) { + GLDEBUG(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)); + } else { + GLDEBUG(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_vbo_handle_indexes)); + +#if GL_OES_mapbuffer + + GLDEBUG(glBufferData(GL_ELEMENT_ARRAY_BUFFER, m_index_data->getSize(), NULL, m_static_vbo ? GL_STATIC_DRAW : GL_DYNAMIC_DRAW)); + GLDEBUG(void *map_ptr = glMapBufferOES(GL_ELEMENT_ARRAY_BUFFER, GL_WRITE_ONLY_OES)); + m_index_data->copy(map_ptr); + GLDEBUG(glUnmapBufferOES(GL_ELEMENT_ARRAY_BUFFER)); +#else + m_index_data->lock(); + GLDEBUG(glBufferData(GL_ELEMENT_ARRAY_BUFFER, m_index_data->getSize(), m_index_data->getStart(), m_static_vbo ? GL_STATIC_DRAW : GL_DYNAMIC_DRAW)); + m_index_data->unlock(); +#endif + } +} + +void KRMeshManager::KRVBOData::unload() +{ +#if GL_OES_vertex_array_object + if(m_vao_handle != -1) { + GLDEBUG(glDeleteVertexArraysOES(1, &m_vao_handle)); + m_vao_handle = -1; + } +#endif + if(m_vbo_handle != -1) { + GLDEBUG(glDeleteBuffers(1, &m_vbo_handle)); + m_vbo_handle = -1; + } + + if(m_vbo_handle_indexes != -1) { + GLDEBUG(glDeleteBuffers(1, &m_vbo_handle_indexes)); + m_vbo_handle_indexes = -1; + } +} + +void KRMeshManager::KRVBOData::bind() +{ +#if GL_OES_vertex_array_object + GLDEBUG(glBindVertexArrayOES(m_vao_handle)); +#else + GLDEBUG(glBindBuffer(GL_ARRAY_BUFFER, m_vbo_handle)); + KRMeshManager::configureAttribs(m_vertex_attrib_flags); + if(m_vbo_handle_indexes == -1) { + GLDEBUG(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)); + } else { + GLDEBUG(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_vbo_handle_indexes)); + } +#endif +} \ No newline at end of file diff --git a/KREngine/kraken/KRMeshManager.h b/KREngine/kraken/KRMeshManager.h index 2783617..dcbd584 100644 --- a/KREngine/kraken/KRMeshManager.h +++ b/KREngine/kraken/KRMeshManager.h @@ -37,8 +37,6 @@ #include "KRDataBlock.h" #include "KRNode.h" -#include "KRMeshStreamer.h" - class KRContext; class KRMesh; @@ -61,13 +59,49 @@ public: std::vector getModelNames(); unordered_multimap &getModels(); + class KRVBOData { + + public: + + KRVBOData(); + KRVBOData(KRDataBlock &data, KRDataBlock &index_data, int vertex_attrib_flags, bool static_vbo, bool temp_vbo); + void init(KRDataBlock &data, KRDataBlock &index_data, int vertex_attrib_flags, bool static_vbo, bool temp_vbo); + ~KRVBOData(); + + + KRDataBlock *m_data; + KRDataBlock *m_index_data; + + bool isLoaded() { return m_vbo_handle != -1; } + void load(); + void unload(); + void bind(); + + // Disable copy constructors + KRVBOData(const KRVBOData& o) = delete; + KRVBOData(KRVBOData& o) = delete; + + bool isTemporary() { return m_temp_vbo; } + bool getSize() { return m_size; } + + private: + int m_vertex_attrib_flags; + GLuint m_vbo_handle; + GLuint m_vbo_handle_indexes; + GLuint m_vao_handle; + bool m_static_vbo; + bool m_temp_vbo; + GLsizeiptr m_size; + }; + + void bindVBO(KRVBOData *vbo_data); void bindVBO(KRDataBlock &data, KRDataBlock &index_data, int vertex_attrib_flags, bool static_vbo); void releaseVBO(KRDataBlock &data); void unbindVBO(); long getMemUsed(); long getMemActive(); - void configureAttribs(__int32_t attributes); + static void configureAttribs(__int32_t attributes); typedef struct { GLfloat x; @@ -110,28 +144,25 @@ public: std::vector getDrawCalls(); + + KRVBOData KRENGINE_VBO_DATA_3D_CUBE_VERTICES; + KRVBOData KRENGINE_VBO_DATA_2D_SQUARE_VERTICES; + + void doStreaming(long &memoryRemaining, long &memoryRemainingThisFrame); + +private: KRDataBlock KRENGINE_VBO_3D_CUBE_VERTICES, KRENGINE_VBO_3D_CUBE_INDEXES; __int32_t KRENGINE_VBO_3D_CUBE_ATTRIBS; - KRDataBlock KRENGINE_VBO_2D_SQUARE_VERTICES, KRENGINE_VBO_2D_SQUARE_INDEXES; __int32_t KRENGINE_VBO_2D_SQUARE_ATTRIBS; -private: unordered_multimap m_models; // Multiple models with the same name/key may be inserted, representing multiple LOD levels of the model - typedef struct vbo_info { - GLuint vbo_handle; - GLuint vbo_handle_indexes; - GLuint vao_handle; - GLsizeiptr size; - KRDataBlock *data; - } vbo_info_type; - long m_vboMemUsed; - vbo_info_type m_currentVBO; + KRVBOData *m_currentVBO; - unordered_map m_vbosActive; - unordered_map m_vbosPool; + unordered_map m_vbosActive; + unordered_map m_vbosPool; KRDataBlock m_randomParticleVertexData; KRDataBlock m_volumetricLightingVertexData; @@ -141,8 +172,6 @@ private: std::vector m_draw_calls; bool m_draw_call_logging_enabled; bool m_draw_call_log_used; - - KRMeshStreamer m_streamer; }; diff --git a/KREngine/kraken/KRModel.cpp b/KREngine/kraken/KRModel.cpp index f337aba..421b83f 100644 --- a/KREngine/kraken/KRModel.cpp +++ b/KREngine/kraken/KRModel.cpp @@ -80,7 +80,7 @@ tinyxml2::XMLElement *KRModel::saveXML( tinyxml2::XMLNode *parent) e->SetAttribute("lod_min_coverage", m_min_lod_coverage); e->SetAttribute("receives_shadow", m_receivesShadow ? "true" : "false"); e->SetAttribute("faces_camera", m_faces_camera ? "true" : "false"); - m_rim_color.setXMLAttribute("rim_color", e); + m_rim_color.setXMLAttribute("rim_color", e, KRVector3::Zero()); e->SetAttribute("rim_power", m_rim_power); return e; } @@ -118,7 +118,7 @@ std::string KRModel::getLightMap() void KRModel::loadModel() { if(m_models.size() == 0) { - std::vector models = m_pContext->getModelManager()->getModel(m_model_name.c_str()); // The model manager returns the LOD levels in sorted order, with the highest detail first + std::vector models = m_pContext->getMeshManager()->getModel(m_model_name.c_str()); // The model manager returns the LOD levels in sorted order, with the highest detail first unordered_map > bones; if(models.size() > 0) { bool all_bones_found = true; @@ -141,27 +141,38 @@ void KRModel::loadModel() { m_bones = bones; getScene().notify_sceneGraphModify(this); } + + invalidateBounds(); } } } void KRModel::render(KRCamera *pCamera, std::vector &point_lights, std::vector &directional_lights, std::vector&spot_lights, const KRViewport &viewport, KRNode::RenderPass renderPass) { + if(m_lod_visible == LOD_VISIBILITY_PRESTREAM && renderPass == KRNode::RENDER_PASS_PRESTREAM) { + preStream(viewport); + } + + if(m_lod_visible <= LOD_VISIBILITY_PRESTREAM) return; KRNode::render(pCamera, point_lights, directional_lights, spot_lights, viewport, renderPass); - if(renderPass != KRNode::RENDER_PASS_DEFERRED_LIGHTS && renderPass != KRNode::RENDER_PASS_ADDITIVE_PARTICLES && renderPass != KRNode::RENDER_PASS_PARTICLE_OCCLUSION && renderPass != KRNode::RENDER_PASS_VOLUMETRIC_EFFECTS_ADDITIVE && renderPass != KRNode::RENDER_PASS_GENERATE_SHADOWMAPS) { + if(renderPass != KRNode::RENDER_PASS_DEFERRED_LIGHTS && renderPass != KRNode::RENDER_PASS_ADDITIVE_PARTICLES && renderPass != KRNode::RENDER_PASS_PARTICLE_OCCLUSION && renderPass != KRNode::RENDER_PASS_VOLUMETRIC_EFFECTS_ADDITIVE && renderPass != KRNode::RENDER_PASS_GENERATE_SHADOWMAPS && renderPass != KRNode::RENDER_PASS_PRESTREAM) { loadModel(); if(m_models.size() > 0) { // Don't render meshes on second pass of the deferred lighting renderer, as only lights will be applied - + + /* float lod_coverage = 0.0f; if(m_models.size() > 1) { lod_coverage = viewport.coverage(getBounds()); // This also checks the view frustrum culling } else if(viewport.visible(getBounds())) { lod_coverage = 1.0f; } + */ + + float lod_coverage = viewport.coverage(getBounds()); // This also checks the view frustrum culling if(lod_coverage > m_min_lod_coverage) { @@ -183,7 +194,7 @@ void KRModel::render(KRCamera *pCamera, std::vector &point_light } if(m_pLightMap && pCamera->settings.bEnableLightMap && renderPass != RENDER_PASS_SHADOWMAP && renderPass != RENDER_PASS_GENERATE_SHADOWMAPS) { - m_pContext->getTextureManager()->selectTexture(5, m_pLightMap); + m_pContext->getTextureManager()->selectTexture(5, m_pLightMap, lod_coverage, KRTexture::TEXTURE_USAGE_LIGHT_MAP); } KRMat4 matModel = getModelMatrix(); @@ -193,12 +204,44 @@ void KRModel::render(KRCamera *pCamera, std::vector &point_light matModel = KRQuaternion(KRVector3::Forward(), KRVector3::Normalize(camera_pos - model_center)).rotationMatrix() * matModel; } - pModel->render(getName(), pCamera, point_lights, directional_lights, spot_lights, viewport, matModel, m_pLightMap, renderPass, m_bones[pModel], m_rim_color, m_rim_power); + pModel->render(getName(), pCamera, point_lights, directional_lights, spot_lights, viewport, matModel, m_pLightMap, renderPass, m_bones[pModel], m_rim_color, m_rim_power, lod_coverage); } } } } +void KRModel::preStream(const KRViewport &viewport) +{ + loadModel(); + float lod_coverage = viewport.coverage(getBounds()); + + for(auto itr = m_models.begin(); itr != m_models.end(); itr++) { + (*itr)->preStream(lod_coverage); + } + + if(m_pLightMap == NULL && m_lightMap.size()) { + m_pLightMap = getContext().getTextureManager()->getTexture(m_lightMap); + } + + if(m_pLightMap) { + m_pLightMap->resetPoolExpiry(lod_coverage, KRTexture::TEXTURE_USAGE_LIGHT_MAP); + } +} + + +kraken_stream_level KRModel::getStreamLevel(const KRViewport &viewport) +{ + kraken_stream_level stream_level = KRNode::getStreamLevel(viewport); + + loadModel(); + + for(auto itr = m_models.begin(); itr != m_models.end(); itr++) { + stream_level = KRMIN(stream_level, (*itr)->getStreamLevel()); + } + + return stream_level; +} + KRAABB KRModel::getBounds() { loadModel(); if(m_models.size() > 0) { diff --git a/KREngine/kraken/KRModel.h b/KREngine/kraken/KRModel.h index 3f8df27..95e1ee3 100644 --- a/KREngine/kraken/KRModel.h +++ b/KREngine/kraken/KRModel.h @@ -61,7 +61,7 @@ public: virtual KRAABB getBounds(); - void setRimColor(const const KRVector3 &rim_color); + void setRimColor(const KRVector3 &rim_color); void setRimPower(float rim_power); KRVector3 getRimColor(); float getRimPower(); @@ -69,7 +69,11 @@ public: void setLightMap(const std::string &name); std::string getLightMap(); + virtual kraken_stream_level getStreamLevel(const KRViewport &viewport); + private: + void preStream(const KRViewport &viewport); + std::vector m_models; unordered_map > m_bones; // Outer std::map connects model to set of bones KRTexture *m_pLightMap; diff --git a/KREngine/kraken/KRNode.cpp b/KREngine/kraken/KRNode.cpp index ebbbeb2..90b35de 100644 --- a/KREngine/kraken/KRNode.cpp +++ b/KREngine/kraken/KRNode.cpp @@ -10,6 +10,7 @@ #include "KRNode.h" #include "KRLODGroup.h" +#include "KRLODSet.h" #include "KRPointLight.h" #include "KRSpotLight.h" #include "KRDirectionalLight.h" @@ -62,8 +63,9 @@ KRNode::KRNode(KRScene &scene, std::string name) : KRContextObject(scene.getCont m_modelMatrix = KRMat4(); m_bindPoseMatrix = KRMat4(); m_activePoseMatrix = KRMat4(); - m_lod_visible = false; + m_lod_visible = LOD_VISIBILITY_HIDDEN; m_scale_compensation = false; + m_boundsValid = false; m_lastRenderFrame = -1000; for(int i=0; i < KRENGINE_NODE_ATTRIBUTE_COUNT; i++) { @@ -107,7 +109,7 @@ bool KRNode::getScaleCompensation() void KRNode::childDeleted(KRNode *child_node) { m_childNodes.erase(child_node); - // InvalidateBounds(); + invalidateBounds(); getScene().notify_sceneGraphModify(this); } @@ -115,10 +117,7 @@ void KRNode::addChild(KRNode *child) { assert(child->m_parentNode == NULL); child->m_parentNode = this; m_childNodes.insert(child); - if(m_lod_visible) { - // Child node inherits LOD visibility status from parent - child->showLOD(); - } + child->setLODVisibility(m_lod_visible); // Child node inherits LOD visibility status from parent } tinyxml2::XMLElement *KRNode::saveXML(tinyxml2::XMLNode *parent) { @@ -126,17 +125,17 @@ tinyxml2::XMLElement *KRNode::saveXML(tinyxml2::XMLNode *parent) { tinyxml2::XMLElement *e = doc->NewElement(getElementName().c_str()); tinyxml2::XMLNode *n = parent->InsertEndChild(e); e->SetAttribute("name", m_name.c_str()); - m_localTranslation.setXMLAttribute("translate", e); - m_localScale.setXMLAttribute("scale", e); - (m_localRotation * (180.0f / M_PI)).setXMLAttribute("rotate", e); + m_localTranslation.setXMLAttribute("translate", e, KRVector3::Zero()); + m_localScale.setXMLAttribute("scale", e, KRVector3::One()); + (m_localRotation * (180.0f / M_PI)).setXMLAttribute("rotate", e, KRVector3::Zero()); - m_rotationOffset.setXMLAttribute("rotate_offset", e); - m_scalingOffset.setXMLAttribute("scale_offset", e); - m_rotationPivot.setXMLAttribute("rotate_pivot", e); - m_scalingPivot.setXMLAttribute("scale_pivot", e); - (m_preRotation * (180.0f / M_PI)).setXMLAttribute("pre_rotate", e); - (m_postRotation * (180.0f / M_PI)).setXMLAttribute("post_rotate", e); + m_rotationOffset.setXMLAttribute("rotate_offset", e, KRVector3::Zero()); + m_scalingOffset.setXMLAttribute("scale_offset", e, KRVector3::Zero()); + m_rotationPivot.setXMLAttribute("rotate_pivot", e, KRVector3::Zero()); + m_scalingPivot.setXMLAttribute("scale_pivot", e, KRVector3::Zero()); + (m_preRotation * (180.0f / M_PI)).setXMLAttribute("pre_rotate", e, KRVector3::Zero()); + (m_postRotation * (180.0f / M_PI)).setXMLAttribute("post_rotate", e, KRVector3::Zero()); for(std::set::iterator itr=m_childNodes.begin(); itr != m_childNodes.end(); ++itr) { KRNode *child = (*itr); @@ -395,6 +394,8 @@ KRNode *KRNode::LoadXML(KRScene &scene, tinyxml2::XMLElement *e) { const char *szName = e->Attribute("name"); if(strcmp(szElementName, "node") == 0) { new_node = new KRNode(scene, szName); + } if(strcmp(szElementName, "lod_set") == 0) { + new_node = new KRLODSet(scene, szName); } if(strcmp(szElementName, "lod_group") == 0) { new_node = new KRLODGroup(scene, szName); } else if(strcmp(szElementName, "point_light") == 0) { @@ -452,6 +453,8 @@ KRNode *KRNode::LoadXML(KRScene &scene, tinyxml2::XMLElement *e) { void KRNode::render(KRCamera *pCamera, std::vector &point_lights, std::vector &directional_lights, std::vector&spot_lights, const KRViewport &viewport, RenderPass renderPass) { + if(m_lod_visible <= LOD_VISIBILITY_PRESTREAM) return; + m_lastRenderFrame = getContext().getCurrentFrame(); } @@ -472,22 +475,26 @@ KRScene &KRNode::getScene() { } KRAABB KRNode::getBounds() { - KRAABB bounds = KRAABB::Zero(); + if(!m_boundsValid) { + KRAABB bounds = KRAABB::Zero(); - bool first_child = true; - for(std::set::iterator itr=m_childNodes.begin(); itr != m_childNodes.end(); ++itr) { - KRNode *child = (*itr); - if(child->getBounds() != KRAABB::Zero()) { - if(first_child) { - first_child = false; - bounds = child->getBounds(); - } else { - bounds.encapsulate(child->getBounds()); + bool first_child = true; + for(std::set::iterator itr=m_childNodes.begin(); itr != m_childNodes.end(); ++itr) { + KRNode *child = (*itr); + if(child->getBounds() != KRAABB::Zero()) { + if(first_child) { + first_child = false; + bounds = child->getBounds(); + } else { + bounds.encapsulate(child->getBounds()); + } } } + + m_bounds = bounds; + m_boundsValid = true; } - - return bounds; + return m_bounds; } void KRNode::invalidateModelMatrix() @@ -500,7 +507,7 @@ void KRNode::invalidateModelMatrix() child->invalidateModelMatrix(); } - // InvalidateBounds + invalidateBounds(); getScene().notify_sceneGraphModify(this); } @@ -879,34 +886,31 @@ void KRNode::addToOctreeNode(KROctreeNode *octree_node) void KRNode::updateLODVisibility(const KRViewport &viewport) { - // If we aren't an LOD group node, then we just add ourselves and all our children to the octree - showLOD(); -} - -void KRNode::hideLOD() -{ - if(m_lod_visible) { - m_lod_visible = false; - getScene().notify_sceneGraphDelete(this); + if(m_lod_visible >= LOD_VISIBILITY_PRESTREAM) { for(std::set::iterator itr=m_childNodes.begin(); itr != m_childNodes.end(); ++itr) { - (*itr)->hideLOD(); + (*itr)->updateLODVisibility(viewport); } } } -void KRNode::showLOD() +void KRNode::setLODVisibility(KRNode::LodVisibility lod_visibility) { - if(!m_lod_visible) { - getScene().notify_sceneGraphCreate(this); - m_lod_visible = true; + if(m_lod_visible != lod_visibility) { + if(m_lod_visible == LOD_VISIBILITY_HIDDEN && lod_visibility >= LOD_VISIBILITY_PRESTREAM) { + getScene().notify_sceneGraphCreate(this); + } else if(m_lod_visible >= LOD_VISIBILITY_PRESTREAM && lod_visibility == LOD_VISIBILITY_HIDDEN) { + getScene().notify_sceneGraphDelete(this); + } + + m_lod_visible = lod_visibility; + for(std::set::iterator itr=m_childNodes.begin(); itr != m_childNodes.end(); ++itr) { - (*itr)->showLOD(); + (*itr)->setLODVisibility(lod_visibility); } } } - -bool KRNode::lodIsVisible() +KRNode::LodVisibility KRNode::getLODVisibility() { return m_lod_visible; } @@ -932,3 +936,22 @@ std::set &KRNode::getBehaviors() { return m_behaviors; } + +kraken_stream_level KRNode::getStreamLevel(const KRViewport &viewport) +{ + kraken_stream_level stream_level = kraken_stream_level::STREAM_LEVEL_IN_HQ; + + for(std::set::iterator itr=m_childNodes.begin(); itr != m_childNodes.end(); ++itr) { + stream_level = KRMIN(stream_level, (*itr)->getStreamLevel(viewport)); + } + + return stream_level; +} + +void KRNode::invalidateBounds() const +{ + m_boundsValid = false; + if(m_parentNode) { + m_parentNode->invalidateBounds(); + } +} diff --git a/KREngine/kraken/KRNode.h b/KREngine/kraken/KRNode.h index eb074fa..937f6bf 100644 --- a/KREngine/kraken/KRNode.h +++ b/KREngine/kraken/KRNode.h @@ -43,7 +43,14 @@ public: RENDER_PASS_ADDITIVE_PARTICLES, RENDER_PASS_VOLUMETRIC_EFFECTS_ADDITIVE, RENDER_PASS_GENERATE_SHADOWMAPS, - RENDER_PASS_SHADOWMAP + RENDER_PASS_SHADOWMAP, + RENDER_PASS_PRESTREAM + }; + + enum LodVisibility { + LOD_VISIBILITY_HIDDEN, + LOD_VISIBILITY_PRESTREAM, + LOD_VISIBILITY_VISIBLE }; KRNode(KRScene &scene, std::string name); @@ -110,6 +117,7 @@ public: void setWorldRotation(const KRVector3 &v); virtual KRAABB getBounds(); + void invalidateBounds() const; const KRMat4 &getModelMatrix(); const KRMat4 &getInverseModelMatrix(); const KRMat4 &getBindPoseMatrix(); @@ -158,13 +166,18 @@ public: virtual bool hasPhysics(); virtual void updateLODVisibility(const KRViewport &viewport); - bool lodIsVisible(); + LodVisibility getLODVisibility(); void setScaleCompensation(bool scale_compensation); bool getScaleCompensation(); void setAnimationEnabled(node_attribute_type attrib, bool enable); bool getAnimationEnabled(node_attribute_type attrib) const; + + virtual kraken_stream_level getStreamLevel(const KRViewport &viewport); + + virtual void setLODVisibility(LodVisibility lod_visibility); + protected: KRVector3 m_localTranslation; KRVector3 m_localScale; @@ -188,11 +201,7 @@ protected: KRVector3 m_initialPreRotation; KRVector3 m_initialPostRotation; - bool m_lod_visible; - void hideLOD(); - void showLOD(); - float m_lod_min_coverage; - float m_lod_max_coverage; + LodVisibility m_lod_visible; KRNode *m_parentNode; std::set m_childNodes; @@ -214,6 +223,9 @@ private: bool m_activePoseMatrixValid; bool m_inverseBindPoseMatrixValid; + mutable KRAABB m_bounds; + mutable bool m_boundsValid; + std::string m_name; diff --git a/KREngine/kraken/KROctree.cpp b/KREngine/kraken/KROctree.cpp index df006e5..641407f 100644 --- a/KREngine/kraken/KROctree.cpp +++ b/KREngine/kraken/KROctree.cpp @@ -132,3 +132,25 @@ bool KROctree::rayCast(const KRVector3 &v0, const KRVector3 &dir, KRHitInfo &hit } return hit_found; } + +bool KROctree::sphereCast(const KRVector3 &v0, const KRVector3 &v1, float radius, KRHitInfo &hitinfo, unsigned int layer_mask) +{ + bool hit_found = false; + std::vector outer_colliders; + + for(std::set::iterator outer_nodes_itr=m_outerSceneNodes.begin(); outer_nodes_itr != m_outerSceneNodes.end(); outer_nodes_itr++) { + KRCollider *collider = dynamic_cast(*outer_nodes_itr); + if(collider) { + outer_colliders.push_back(collider); + } + } + for(std::vector::iterator itr=outer_colliders.begin(); itr != outer_colliders.end(); itr++) { + if((*itr)->sphereCast(v0, v1, radius, hitinfo, layer_mask)) hit_found = true; + } + + if(m_pRootNode) { + if(m_pRootNode->sphereCast(v0, v1, radius, hitinfo, layer_mask)) hit_found = true; + } + return hit_found; +} + diff --git a/KREngine/kraken/KROctree.h b/KREngine/kraken/KROctree.h index 7f0cd12..7e7edff 100644 --- a/KREngine/kraken/KROctree.h +++ b/KREngine/kraken/KROctree.h @@ -30,6 +30,7 @@ public: bool lineCast(const KRVector3 &v0, const KRVector3 &v1, KRHitInfo &hitinfo, unsigned int layer_mask); bool rayCast(const KRVector3 &v0, const KRVector3 &dir, KRHitInfo &hitinfo, unsigned int layer_mask); + bool sphereCast(const KRVector3 &v0, const KRVector3 &v1, float radius, KRHitInfo &hitinfo, unsigned int layer_mask); private: KROctreeNode *m_pRootNode; diff --git a/KREngine/kraken/KROctreeNode.cpp b/KREngine/kraken/KROctreeNode.cpp index 7332275..2b62c8a 100644 --- a/KREngine/kraken/KROctreeNode.cpp +++ b/KREngine/kraken/KROctreeNode.cpp @@ -251,3 +251,40 @@ bool KROctreeNode::rayCast(const KRVector3 &v0, const KRVector3 &dir, KRHitInfo return hit_found; } + +bool KROctreeNode::sphereCast(const KRVector3 &v0, const KRVector3 &v1, float radius, KRHitInfo &hitinfo, unsigned int layer_mask) +{ + bool hit_found = false; + /* + // FINDME, TODO - Adapt this optimization to work with sphereCasts + + if(hitinfo.didHit() && v1 != hitinfo.getPosition()) { + // Optimization: If we already have a hit, only search for hits that are closer + hit_found = sphereCast(v0, hitinfo.getPosition(), radius, hitinfo, layer_mask); + } else { + */ + + KRAABB swept_bounds = KRAABB(KRVector3(KRMIN(v0.x, v1.x) - radius, KRMIN(v0.y, v1.y) - radius, KRMIN(v0.z, v1.z) - radius), KRVector3(KRMAX(v0.x, v1.x) + radius, KRMAX(v0.y, v1.y) + radius, KRMAX(v0.z, v1.z) + radius)); + // FINDME, TODO - Investigate AABB - swept sphere intersections or OBB - AABB intersections: "if(getBounds().intersectsSweptSphere(v0, v1, radius)) {" + if(getBounds().intersects(swept_bounds)) { + + for(std::set::iterator nodes_itr=m_sceneNodes.begin(); nodes_itr != m_sceneNodes.end(); nodes_itr++) { + KRCollider *collider = dynamic_cast(*nodes_itr); + if(collider) { + if(collider->sphereCast(v0, v1, radius, hitinfo, layer_mask)) hit_found = true; + } + } + + for(int i=0; i<8; i++) { + if(m_children[i]) { + if(m_children[i]->sphereCast(v0, v1, radius, hitinfo, layer_mask)) { + hit_found = true; + } + } + } + } + // } + + return hit_found; +} + diff --git a/KREngine/kraken/KROctreeNode.h b/KREngine/kraken/KROctreeNode.h index c1bb7cf..84eb549 100644 --- a/KREngine/kraken/KROctreeNode.h +++ b/KREngine/kraken/KROctreeNode.h @@ -51,6 +51,8 @@ public: bool lineCast(const KRVector3 &v0, const KRVector3 &v1, KRHitInfo &hitinfo, unsigned int layer_mask); bool rayCast(const KRVector3 &v0, const KRVector3 &dir, KRHitInfo &hitinfo, unsigned int layer_mask); + bool sphereCast(const KRVector3 &v0, const KRVector3 &v1, float radius, KRHitInfo &hitinfo, unsigned int layer_mask); + private: KRAABB m_bounds; diff --git a/KREngine/kraken/KRParticleSystemNewtonian.cpp b/KREngine/kraken/KRParticleSystemNewtonian.cpp index 89e9dc5..4df6832 100644 --- a/KREngine/kraken/KRParticleSystemNewtonian.cpp +++ b/KREngine/kraken/KRParticleSystemNewtonian.cpp @@ -56,6 +56,7 @@ bool KRParticleSystemNewtonian::hasPhysics() void KRParticleSystemNewtonian::render(KRCamera *pCamera, std::vector &point_lights, std::vector &directional_lights, std::vector&spot_lights, const KRViewport &viewport, KRNode::RenderPass renderPass) { + if(m_lod_visible <= LOD_VISIBILITY_PRESTREAM) return; KRNode::render(pCamera, point_lights, directional_lights, spot_lights, viewport, renderPass); @@ -68,7 +69,7 @@ void KRParticleSystemNewtonian::render(KRCamera *pCamera, std::vectorgetTextureManager()->getTexture("flare"); - m_pContext->getTextureManager()->selectTexture(0, pParticleTexture); + m_pContext->getTextureManager()->selectTexture(0, pParticleTexture, 0.0f, KRTexture::TEXTURE_USAGE_PARTICLE); int particle_count = 10000; @@ -78,39 +79,10 @@ void KRParticleSystemNewtonian::render(KRCamera *pCamera, std::vectorselectShader(*pCamera, pParticleShader, viewport, getModelMatrix(), point_lights, directional_lights, spot_lights, 0, renderPass, rim_color, 0.0f)) { pParticleShader->setUniform(KRShader::KRENGINE_UNIFORM_FLARE_SIZE, 1.0f); - //m_pContext->getModelManager()->bindVBO((void *)m_pContext->getModelManager()->getRandomParticles(), particle_count * 3 * sizeof(KRMeshManager::RandomParticleVertexData), NULL, 0, (1 << KRMesh::KRENGINE_ATTRIB_VERTEX) | (1 << KRMesh::KRENGINE_ATTRIB_TEXUVA), false); KRDataBlock index_data; - m_pContext->getModelManager()->bindVBO(m_pContext->getModelManager()->getRandomParticles(), index_data, (1 << KRMesh::KRENGINE_ATTRIB_VERTEX) | (1 << KRMesh::KRENGINE_ATTRIB_TEXUVA), false); + m_pContext->getMeshManager()->bindVBO(m_pContext->getMeshManager()->getRandomParticles(), index_data, (1 << KRMesh::KRENGINE_ATTRIB_VERTEX) | (1 << KRMesh::KRENGINE_ATTRIB_TEXUVA), false); GLDEBUG(glDrawArrays(GL_TRIANGLES, 0, particle_count*3)); } } } } - -// - -// - -// -// KRMat4 particleModelMatrix = KRMat4(); -//// particleModelMatrix.scale(particleBlockScale); -//// -//// KRVector3 particleBlockOrigin = KRVector3(m_viewport.getCameraPosition().x - fmod(m_viewport.getCameraPosition().x + x * particleBlockScale, particleBlockScale), m_viewport.getCameraPosition().y - fmod(m_viewport.getCameraPosition().y + y * particleBlockScale, particleBlockScale),m_viewport.getCameraPosition().z - fmod(m_viewport.getCameraPosition().z + z * particleBlockScale, particleBlockScale)); -//// -//// particleModelMatrix.translate(particleBlockOrigin); -//// particleModelMatrix.translate(sin(m_particlesAbsoluteTime * 0.0523f) * 10.0f, sin(m_particlesAbsoluteTime * 0.0553f) * 10.0f, sin(m_particlesAbsoluteTime * 0.0521f) * 10.0f); -// -// int particle_count = 10000; -// -// if(getContext().getShaderManager()->selectShader(pParticleShader, m_viewport, particleModelMatrix, lightDirection, shadowmvpmatrix, shadowDepthTexture, m_cShadowBuffers, KRNode::RENDER_PASS_ADDITIVE_PARTICLES)) { -// GLDEBUG(glUniform1f( -// pParticleShader->m_uniforms[KRShader::KRENGINE_UNIFORM_FLARE_SIZE], -// 1.0f -// )); -// -// m_pContext->getModelManager()->bindVBO((void *)m_pContext->getModelManager()->getRandomParticles(), particle_count * 3 * sizeof(KRMeshManager::RandomParticleVertexData), NULL, 0, (1 << KRMesh::KRENGINE_ATTRIB_VERTEX) | (1 << KRMesh::KRENGINE_ATTRIB_TEXUVA), false); -// GLDEBUG(glDrawArrays(GL_TRIANGLES, 0, particle_count*3)); -// } -//// } -//// } -//// } \ No newline at end of file diff --git a/KREngine/kraken/KRPointLight.cpp b/KREngine/kraken/KRPointLight.cpp index fd7cbce..21883a8 100644 --- a/KREngine/kraken/KRPointLight.cpp +++ b/KREngine/kraken/KRPointLight.cpp @@ -34,7 +34,7 @@ std::string KRPointLight::getElementName() { } KRAABB KRPointLight::getBounds() { - float influence_radius = sqrt((m_intensity / 100.0) / KRLIGHT_MIN_INFLUENCE - 1.0) + m_decayStart; + float influence_radius = m_decayStart - sqrt(m_intensity * 0.01f) / sqrt(KRLIGHT_MIN_INFLUENCE); if(influence_radius < m_flareOcclusionSize) { influence_radius = m_flareOcclusionSize; } @@ -43,6 +43,7 @@ KRAABB KRPointLight::getBounds() { void KRPointLight::render(KRCamera *pCamera, std::vector &point_lights, std::vector &directional_lights, std::vector&spot_lights, const KRViewport &viewport, KRNode::RenderPass renderPass) { + if(m_lod_visible <= LOD_VISIBILITY_PRESTREAM) return; KRLight::render(pCamera, point_lights, directional_lights, spot_lights, viewport, renderPass); @@ -56,7 +57,7 @@ void KRPointLight::render(KRCamera *pCamera, std::vector &point_ KRVector3 light_position = getLocalTranslation(); - float influence_radius = sqrt((m_intensity / 100.0) / KRLIGHT_MIN_INFLUENCE - 1.0) + m_decayStart; + float influence_radius = m_decayStart - sqrt(m_intensity * 0.01f) / sqrt(KRLIGHT_MIN_INFLUENCE); KRMat4 sphereModelMatrix = KRMat4(); sphereModelMatrix.scale(influence_radius); @@ -96,13 +97,13 @@ void KRPointLight::render(KRCamera *pCamera, std::vector &point_ GLDEBUG(glDisable(GL_DEPTH_TEST)); // Render a full screen quad - m_pContext->getModelManager()->bindVBO(getContext().getModelManager()->KRENGINE_VBO_2D_SQUARE_VERTICES, getContext().getModelManager()->KRENGINE_VBO_2D_SQUARE_INDEXES, getContext().getModelManager()->KRENGINE_VBO_2D_SQUARE_ATTRIBS, true); + m_pContext->getMeshManager()->bindVBO(&m_pContext->getMeshManager()->KRENGINE_VBO_DATA_2D_SQUARE_VERTICES); GLDEBUG(glDrawArrays(GL_TRIANGLE_STRIP, 0, 4)); } else { #if GL_OES_vertex_array_object GLDEBUG(glBindVertexArrayOES(0)); #endif - m_pContext->getModelManager()->configureAttribs(1 << KRMesh::KRENGINE_ATTRIB_VERTEX); + m_pContext->getMeshManager()->configureAttribs(1 << KRMesh::KRENGINE_ATTRIB_VERTEX); // Render sphere of light's influence generateMesh(); diff --git a/KREngine/kraken/KRRenderSettings.cpp b/KREngine/kraken/KRRenderSettings.cpp index 6c9efe8..86bfaed 100644 --- a/KREngine/kraken/KRRenderSettings.cpp +++ b/KREngine/kraken/KRRenderSettings.cpp @@ -37,7 +37,7 @@ KRRenderSettings::KRRenderSettings() light_intensity = KRVector3::One(); perspective_fov = 45.0 * D2R; - perspective_nearz = 0.05f; + perspective_nearz = 0.3f; // was 0.05f perspective_farz = 1000.0f; dof_quality = 0; diff --git a/KREngine/kraken/KRResource+fbx.cpp b/KREngine/kraken/KRResource+fbx.cpp index 4b1a7fd..9b34901 100644 --- a/KREngine/kraken/KRResource+fbx.cpp +++ b/KREngine/kraken/KRResource+fbx.cpp @@ -28,6 +28,7 @@ #include "KRBundle.h" #include "KRModel.h" #include "KRLODGroup.h" +#include "KRLODSet.h" #include "KRCollider.h" #ifdef IOS_REF @@ -392,6 +393,8 @@ KRAnimationCurve *LoadAnimationCurve(KRContext &context, FbxAnimCurve* pAnimCurv int frame_start = time_span.GetStart().GetSecondDouble() * dest_frame_rate; int frame_count = (time_span.GetStop().GetSecondDouble() * dest_frame_rate) - frame_start; + KRContext::Log(KRContext::LOG_LEVEL_INFORMATION, " animation start %d and frame count %d", frame_start, frame_count); + KRAnimationCurve *new_curve = new KRAnimationCurve(context, name); new_curve->setFrameRate(dest_frame_rate); new_curve->setFrameStart(frame_start); @@ -404,7 +407,11 @@ KRAnimationCurve *LoadAnimationCurve(KRContext &context, FbxAnimCurve* pAnimCurv FbxTime frame_time; frame_time.SetSecondDouble(frame_seconds); float frame_value = pAnimCurve->Evaluate(frame_time, &last_frame); +// printf(" Frame %i / %i: %.6f\n", frame_number, frame_count, frame_value); + if (0 == frame_number) KRContext::Log(KRContext::LOG_LEVEL_INFORMATION, "Value at starting key frame = %3.3f", frame_value); new_curve->setValue(frame_number+frame_start, frame_value); + // BUG FIX Dec 2, 2013 .. changed frame_number to frame_number+frame_start + // setValue(frame_number, frame_value) clamps the frame_number range between frame_start : frame_start+frame_count } return new_curve; @@ -580,6 +587,12 @@ void LoadNode(FbxScene* pFbxScene, KRNode *parent_node, FbxGeometryConverter *pG // Transform = T * Roff * Rp * Rpre * R * Rpost * inverse(Rp) * Soff * Sp * S * inverse(Sp) + int node_has_n_points = 0; // this will be 3 if the node_frame_key_position is complete after the import animated properties loop + KRVector3 node_key_frame_position = KRVector3(0.0, 0.0, 0.0); + // ADDED 3, 2013 by Peter to store the key frame (start location) of an animation + // the x, y, z translation position of the animation will be extracted from the curves + // as they are added to the animation layer in the loop below .. + // Import animated properties int animation_count = pFbxScene->GetSrcObjectCount(); for(int i = 0; i < animation_count; i++) { @@ -626,7 +639,13 @@ void LoadNode(FbxScene* pFbxScene, KRNode *parent_node, FbxGeometryConverter *pG new_attribute->setCurveName(GetFbxObjectName(pAnimCurve)); new_attribute->setTargetName(GetFbxObjectName(pNode)); new_attribute->setTargetAttribute(KRNode::KRENGINE_NODE_ATTRIBUTE_TRANSLATE_X); - pAnimationLayer->addAttribute(new_attribute); + + KRAnimationCurve *curve = new_attribute->getCurve(); + node_key_frame_position.x = curve->getValue(curve->getFrameStart()); + node_has_n_points++; + // ADDED Dec 3, 2013 by Peter to extract start location key frame + + pAnimationLayer->addAttribute(new_attribute); } pAnimCurve = pNode->LclTranslation.GetCurve(pFbxAnimLayer, FBXSDK_CURVENODE_COMPONENT_Y); @@ -635,6 +654,12 @@ void LoadNode(FbxScene* pFbxScene, KRNode *parent_node, FbxGeometryConverter *pG new_attribute->setCurveName(GetFbxObjectName(pAnimCurve)); new_attribute->setTargetName(GetFbxObjectName(pNode)); new_attribute->setTargetAttribute(KRNode::KRENGINE_NODE_ATTRIBUTE_TRANSLATE_Y); + + KRAnimationCurve *curve = new_attribute->getCurve(); + node_key_frame_position.y = curve->getValue(curve->getFrameStart()); + node_has_n_points++; + // ADDED Dec 3, 2013 by Peter to extract start location key frame + pAnimationLayer->addAttribute(new_attribute); } @@ -644,6 +669,12 @@ void LoadNode(FbxScene* pFbxScene, KRNode *parent_node, FbxGeometryConverter *pG new_attribute->setCurveName(GetFbxObjectName(pAnimCurve)); new_attribute->setTargetName(GetFbxObjectName(pNode)); new_attribute->setTargetAttribute(KRNode::KRENGINE_NODE_ATTRIBUTE_TRANSLATE_Z); + + KRAnimationCurve *curve = new_attribute->getCurve(); + node_key_frame_position.z = curve->getValue(curve->getFrameStart()); + node_has_n_points++; + // ADDED Dec 3, 2013 by Peter to extract start location key frame + pAnimationLayer->addAttribute(new_attribute); } @@ -867,6 +898,22 @@ void LoadNode(FbxScene* pFbxScene, KRNode *parent_node, FbxGeometryConverter *pG warning((geometric_translation == lZero), "Geometric Rotation not supported .. 3DSMax file??"); warning((geometric_scaling == lOne), "Geometric Rotation not supported .. 3DSMax file??"); warning((rotation_order == eEulerXYZ), "Geometric Rotation not supported .. 3DSMax file??"); + + // FINDME - node_key_frame_position contains the key frame (start location) for an animation node + // node_has_n_points + // node_key_frame_position + if (3 == node_has_n_points) + KRContext::Log(KRContext::LOG_LEVEL_INFORMATION, "key frame at %2.3f, %2.3f, %2.3f", + node_key_frame_position.x, + node_key_frame_position.y, + node_key_frame_position.z); + // + // The animation curve data is output to the KRNode::KRENGINE_NODE_ATTRIBUTE_TRANSLATE_ X, Y, Z attribute targets + // The actor scripts 'move' command modifies the node's world translations using setWorldTranslation() + // + // QUESTION - where should we store the key frame within the node to make sure it is output into the KRBundle ?? + // do we store it as node_local or store it as the world translation? or somewhere else ?? + // KRVector3 node_translation = KRVector3(local_translation[0], local_translation[1], local_translation[2]); // T * Roff * Rp KRVector3 node_rotation = KRVector3(local_rotation[0], local_rotation[1], local_rotation[2]) / 180.0 * M_PI; @@ -879,7 +926,8 @@ void LoadNode(FbxScene* pFbxScene, KRNode *parent_node, FbxGeometryConverter *pG KRVector3 node_pre_rotation, node_post_rotation; if(rotation_active) { node_pre_rotation = KRVector3(pre_rotation[0], pre_rotation[1], pre_rotation[2]) / 180.0 * M_PI; - node_post_rotation = KRVector3(post_rotation[0], post_rotation[1], post_rotation[2]) / 180.0 * M_PI; + node_post_rotation = KRVector3(post_rotation[0], post_rotation[1], post_rotation[2]) / 180.0 * M_PI; + //&KRF HACK removing this line (above) to prevent the post rotation from corrupting the default light values; the FBX is importing a post rotation and setting it to -90 degrees } else { node_pre_rotation = KRVector3::Zero(); node_post_rotation = KRVector3::Zero(); @@ -898,9 +946,12 @@ void LoadNode(FbxScene* pFbxScene, KRNode *parent_node, FbxGeometryConverter *pG float group_max_distance = 0.0f; if(fbx_lod_group->MinMaxDistance.Get()) { group_min_distance = fbx_lod_group->MinDistance.Get(); - group_max_distance = fbx_lod_group->MinDistance.Get(); + group_max_distance = fbx_lod_group->MaxDistance.Get(); } + KRLODSet *lod_set = new KRLODSet(parent_node->getScene(), name); + parent_node->addChild(lod_set); + KRAABB reference_bounds; // Create a lod_group node for each fbx child node int child_count = pNode->GetChildCount(); @@ -960,7 +1011,7 @@ void LoadNode(FbxScene* pFbxScene, KRNode *parent_node, FbxGeometryConverter *pG new_node->setPostRotation(node_post_rotation); new_node->setUseWorldUnits(use_world_space_units); - parent_node->addChild(new_node); + lod_set->addChild(new_node); LoadNode(pFbxScene, new_node, pGeometryConverter, pNode->GetChild(i)); @@ -1003,19 +1054,7 @@ void LoadNode(FbxScene* pFbxScene, KRNode *parent_node, FbxGeometryConverter *pG if(pNode->GetChildCount() > 0) { // Create an empty node, for inheritence of transforms std::string name = GetFbxObjectName(pNode); - - - /* - if(min_distance == 0.0f && max_distance == 0.0f) { - // Regular node for grouping children together under one transform - new_node = new KRNode(parent_node->getScene(), name); - } else { - */ - // LOD Enabled group node - KRLODGroup *lod_group = new KRLODGroup(parent_node->getScene(), name); - lod_group->setMinDistance(0.0f); - lod_group->setMaxDistance(0.0f); - new_node = lod_group; + new_node = new KRNode(parent_node->getScene(), name); } } } @@ -1111,10 +1150,10 @@ void LoadMaterial(KRContext &context, FbxSurfaceMaterial *pMaterial) { lKFbxDouble1 =((FbxSurfacePhong *) pMaterial)->ReflectionFactor; // Reflection color - lKFbxDouble3 =((FbxSurfacePhong *) pMaterial)->Reflection; + //lKFbxDouble3 =((FbxSurfacePhong *) pMaterial)->Reflection; // We modulate Relection color by reflection factor, as we only have one "reflection color" variable in Kraken - new_material->setReflection(KRVector3(lKFbxDouble3.Get()[0] * lKFbxDouble1.Get(), lKFbxDouble3.Get()[1] * lKFbxDouble1.Get(), lKFbxDouble3.Get()[2] * lKFbxDouble1.Get())); + new_material->setReflection(KRVector3(/*lKFbxDouble3.Get()[0] * */lKFbxDouble1.Get(), /*lKFbxDouble3.Get()[1] * */lKFbxDouble1.Get(), /*lKFbxDouble3.Get()[2] * */lKFbxDouble1.Get())); } else if(pMaterial->GetClassId().Is(FbxSurfaceLambert::ClassId) ) { // We found a Lambert material. @@ -1332,6 +1371,8 @@ void LoadMesh(KRContext &context, FbxScene* pFbxScene, FbxGeometryConverter *pGe } } + pMesh->GenerateTangentsDataForAllUVSets(true); + int polygon_count = pMesh->GetPolygonCount(); int uv_count = pMesh->GetElementUVCount(); int normal_count = pMesh->GetElementNormalCount(); @@ -1448,36 +1489,38 @@ void LoadMesh(KRContext &context, FbxScene* pFbxScene, FbxGeometryConverter *pGe mi.normals.push_back(KRVector3(new_normal[0], new_normal[1], new_normal[2])); } - + /* + TODO - Tangent vectors imported from maya appear incorrectly... Only calculating them in Kraken for now + // ----====---- Read Tangents ----====---- - for(int l = 0; l < tangent_count; ++l) - { - FbxVector4 new_tangent; - FbxGeometryElementTangent* leTangent = pMesh->GetElementTangent(l); - - if(leTangent->GetMappingMode() == FbxGeometryElement::eByPolygonVertex) { - switch (leTangent->GetReferenceMode()) { - case FbxGeometryElement::eDirect: - new_tangent = leTangent->GetDirectArray().GetAt(lControlPointIndex); - break; - case FbxGeometryElement::eIndexToDirect: - { - int id = leTangent->GetIndexArray().GetAt(lControlPointIndex); - new_tangent = leTangent->GetDirectArray().GetAt(id); + if(need_tangents) { + for(int l = 0; l < tangent_count; ++l) + { + FbxVector4 new_tangent; + FbxGeometryElementTangent* leTangent = pMesh->GetElementTangent(l); + + if(leTangent->GetMappingMode() == FbxGeometryElement::eByPolygonVertex) { + switch (leTangent->GetReferenceMode()) { + case FbxGeometryElement::eDirect: + new_tangent = leTangent->GetDirectArray().GetAt(lControlPointIndex); + break; + case FbxGeometryElement::eIndexToDirect: + { + int id = leTangent->GetIndexArray().GetAt(lControlPointIndex); + new_tangent = leTangent->GetDirectArray().GetAt(id); + } + break; + default: + break; // other reference modes not shown here! } - break; - default: - break; // other reference modes not shown here! } + if(l == 0) { + mi.tangents.push_back(KRVector3(new_tangent[0], new_tangent[1], new_tangent[2])); + } + } - if(l == 0) { - mi.tangents.push_back(KRVector3(new_tangent[0], new_tangent[1], new_tangent[2])); - } - } - - - + */ source_vertex_id++; dest_vertex_id++; @@ -1501,7 +1544,7 @@ void LoadMesh(KRContext &context, FbxScene* pFbxScene, FbxGeometryConverter *pGe KRMesh *new_mesh = new KRMesh(context, pSourceMesh->GetNode()->GetName()); new_mesh->LoadData(mi, true, need_tangents); - context.getModelManager()->addModel(new_mesh); + context.getMeshManager()->addModel(new_mesh); } KRNode *LoadMesh(KRNode *parent_node, FbxScene* pFbxScene, FbxGeometryConverter *pGeometryConverter, FbxNode* pNode) { @@ -1596,9 +1639,7 @@ KRNode *LoadLocator(KRNode *parent_node, FbxScene* pFbxScene, FbxNode* pNode) { break; default: { -#if defined( DEBUG ) - fprintf(stderr, "FBX property not imported due to unsupported data type: %s.%s\n", name.c_str(), property_name.c_str()); -#endif + // fprintf(stderr, "FBX property not imported due to unsupported data type: %s.%s\n", name.c_str(), property_name.c_str()); } break; } diff --git a/KREngine/kraken/KRReverbZone.cpp b/KREngine/kraken/KRReverbZone.cpp index 322dfea..2a64ee6 100644 --- a/KREngine/kraken/KRReverbZone.cpp +++ b/KREngine/kraken/KRReverbZone.cpp @@ -86,6 +86,7 @@ void KRReverbZone::setZone(const std::string &zone) void KRReverbZone::render(KRCamera *pCamera, std::vector &point_lights, std::vector &directional_lights, std::vector&spot_lights, const KRViewport &viewport, KRNode::RenderPass renderPass) { + if(m_lod_visible <= LOD_VISIBILITY_PRESTREAM) return; KRNode::render(pCamera, point_lights, directional_lights, spot_lights, viewport, renderPass); @@ -111,7 +112,7 @@ void KRReverbZone::render(KRCamera *pCamera, std::vector &point_ GLDEBUG(glEnable(GL_DEPTH_TEST)); GLDEBUG(glDepthFunc(GL_LEQUAL)); GLDEBUG(glDepthRangef(0.0, 1.0)); - std::vector sphereModels = getContext().getModelManager()->getModel("__sphere"); + std::vector sphereModels = getContext().getMeshManager()->getModel("__sphere"); if(sphereModels.size()) { for(int i=0; i < sphereModels[0]->getSubmeshCount(); i++) { sphereModels[0]->renderSubmesh(i, renderPass, getName(), "visualize_overlay"); diff --git a/KREngine/kraken/KRScene.cpp b/KREngine/kraken/KRScene.cpp index 5e31dce..5c7a199 100644 --- a/KREngine/kraken/KRScene.cpp +++ b/KREngine/kraken/KRScene.cpp @@ -38,7 +38,6 @@ #include "KRScene.h" #include "KRNode.h" -#include "KRLODGroup.h" #include "KRStockGeometry.h" #include "KRDirectionalLight.h" #include "KRSpotLight.h" @@ -49,7 +48,7 @@ const long KRENGINE_OCCLUSION_TEST_EXPIRY = 10; KRScene::KRScene(KRContext &context, std::string name) : KRResource(context, name) { m_pFirstLight = NULL; - m_pRootNode = new KRLODGroup(*this, "scene_root"); + m_pRootNode = new KRNode(*this, "scene_root"); notify_sceneGraphCreate(m_pRootNode); m_skyBoxName = name + "_skybox"; @@ -98,6 +97,11 @@ std::set &KRScene::getLocators() return m_locatorNodes; } +std::set &KRScene::getLights() +{ + return m_lights; +} + void KRScene::render(KRCamera *pCamera, unordered_map &visibleBounds, const KRViewport &viewport, KRNode::RenderPass renderPass, bool new_frame) { if(new_frame) { // Expire cached occlusion test results. @@ -122,8 +126,8 @@ void KRScene::render(KRCamera *pCamera, unordered_map &visibleBound std::vectordirectional_lights; std::vectorspot_lights; - pCamera->settings.setSkyBox(m_skyBoxName); // This is temporary until the camera is moved into the scene graph - +// pCamera->settings.setSkyBox(m_skyBoxName); // This is temporary until the camera is moved into the scene graph +// NOTE: the skybox is now selected in the CircaViewController std::set outerNodes = std::set(m_nodeTree.getOuterSceneNodes()); // HACK - Copying the std::set as it is potentially modified as KRNode's update their bounds during the iteration. This is very expensive and will be eliminated in the future. @@ -277,7 +281,7 @@ void KRScene::render(KROctreeNode *pOctreeNode, unordered_map &visi KRMat4 mvpmatrix = matModel * viewport.getViewProjectionMatrix(); - getContext().getModelManager()->bindVBO(getContext().getModelManager()->KRENGINE_VBO_3D_CUBE_VERTICES, getContext().getModelManager()->KRENGINE_VBO_3D_CUBE_INDEXES, getContext().getModelManager()->KRENGINE_VBO_3D_CUBE_ATTRIBS, true); + getContext().getMeshManager()->bindVBO(&getContext().getMeshManager()->KRENGINE_VBO_DATA_3D_CUBE_VERTICES); // Enable additive blending if(renderPass != KRNode::RENDER_PASS_FORWARD_TRANSPARENT && renderPass != KRNode::RENDER_PASS_ADDITIVE_PARTICLES && renderPass != KRNode::RENDER_PASS_VOLUMETRIC_EFFECTS_ADDITIVE) { @@ -297,7 +301,7 @@ void KRScene::render(KROctreeNode *pOctreeNode, unordered_map &visi if(getContext().getShaderManager()->selectShader("occlusion_test", *pCamera, point_lights, directional_lights, spot_lights, 0, viewport, matModel, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, KRNode::RENDER_PASS_FORWARD_TRANSPARENT, KRVector3::Zero(), 0.0f)) { GLDEBUG(glDrawArrays(GL_TRIANGLE_STRIP, 0, 14)); - m_pContext->getModelManager()->log_draw_call(renderPass, "octree", "occlusion_test", 14); + m_pContext->getMeshManager()->log_draw_call(renderPass, "octree", "occlusion_test", 14); } if(renderPass == KRNode::RENDER_PASS_FORWARD_OPAQUE || @@ -469,6 +473,10 @@ void KRScene::notify_sceneGraphDelete(KRNode *pNode) if(locator) { m_locatorNodes.erase(locator); } + KRLight *light = dynamic_cast(pNode); + if(light) { + m_lights.erase(light); + } m_modifiedNodes.erase(pNode); if(!m_newNodes.erase(pNode)) { m_nodeTree.remove(pNode); @@ -477,10 +485,11 @@ void KRScene::notify_sceneGraphDelete(KRNode *pNode) void KRScene::updateOctree(const KRViewport &viewport) { + m_pRootNode->setLODVisibility(KRNode::LOD_VISIBILITY_VISIBLE); m_pRootNode->updateLODVisibility(viewport); - std::set newNodes = m_newNodes; - std::set modifiedNodes = m_modifiedNodes; + std::set newNodes = std::move(m_newNodes); + std::set modifiedNodes = std::move(m_modifiedNodes); m_newNodes.clear(); m_modifiedNodes.clear(); @@ -502,11 +511,14 @@ void KRScene::updateOctree(const KRViewport &viewport) if(locatorNode) { m_locatorNodes.insert(locatorNode); } - + KRLight *light = dynamic_cast(node); + if(light) { + m_lights.insert(light); + } } for(std::set::iterator itr=modifiedNodes.begin(); itr != modifiedNodes.end(); itr++) { KRNode *node = *itr; - if(node->lodIsVisible()) { + if(node->getLODVisibility() >= KRNode::LOD_VISIBILITY_PRESTREAM) { m_nodeTree.update(node); } if(node->hasPhysics()) { @@ -517,6 +529,35 @@ void KRScene::updateOctree(const KRViewport &viewport) } } +void KRScene::buildOctreeForTheFirstTime() +{ + std::set newNodes = std::move(m_newNodes); + m_newNodes.clear(); + for(std::set::iterator itr=newNodes.begin(); itr != newNodes.end(); itr++) { + KRNode *node = *itr; + m_nodeTree.add(node); + if(node->hasPhysics()) { + m_physicsNodes.insert(node); + } + KRAmbientZone *ambientZoneNode = dynamic_cast(node); + if(ambientZoneNode) { + m_ambientZoneNodes.insert(ambientZoneNode); + } + KRReverbZone *reverbZoneNode = dynamic_cast(node); + if(reverbZoneNode) { + m_reverbZoneNodes.insert(reverbZoneNode); + } + KRLocator *locatorNode = dynamic_cast(node); + if(locatorNode) { + m_locatorNodes.insert(locatorNode); + } + KRLight *light = dynamic_cast(node); + if(light) { + m_lights.insert(light); + } + } +} + void KRScene::physicsUpdate(float deltaTime) { for(std::set::iterator itr=m_physicsNodes.begin(); itr != m_physicsNodes.end(); itr++) { @@ -552,3 +593,20 @@ bool KRScene::rayCast(const KRVector3 &v0, const KRVector3 &dir, KRHitInfo &hiti return m_nodeTree.rayCast(v0, dir, hitinfo, layer_mask); } +bool KRScene::sphereCast(const KRVector3 &v0, const KRVector3 &v1, float radius, KRHitInfo &hitinfo, unsigned int layer_mask) +{ + return m_nodeTree.sphereCast(v0, v1, radius, hitinfo, layer_mask); +} + + +kraken_stream_level KRScene::getStreamLevel() +{ + kraken_stream_level stream_level = kraken_stream_level::STREAM_LEVEL_IN_HQ; + + if(m_pRootNode) { + KRViewport viewport; // This isn't used when prime is false + stream_level = KRMIN(stream_level, m_pRootNode->getStreamLevel(viewport)); + } + + return stream_level; +} diff --git a/KREngine/kraken/KRScene.h b/KREngine/kraken/KRScene.h index 9242a03..0ba470c 100644 --- a/KREngine/kraken/KRScene.h +++ b/KREngine/kraken/KRScene.h @@ -64,8 +64,11 @@ public: KRNode *getRootNode(); KRLight *getFirstLight(); + kraken_stream_level getStreamLevel(); + bool lineCast(const KRVector3 &v0, const KRVector3 &v1, KRHitInfo &hitinfo, unsigned int layer_mask); bool rayCast(const KRVector3 &v0, const KRVector3 &dir, KRHitInfo &hitinfo, unsigned int layer_mask); + bool sphereCast(const KRVector3 &v0, const KRVector3 &v1, float radius, KRHitInfo &hitinfo, unsigned int layer_mask); void renderFrame(float deltaTime, int width, int height); void render(KRCamera *pCamera, unordered_map &visibleBounds, const KRViewport &viewport, KRNode::RenderPass renderPass, bool new_frame); @@ -73,6 +76,7 @@ public: void render(KROctreeNode *pOctreeNode, unordered_map &visibleBounds, KRCamera *pCamera, std::vector &point_lights, std::vector &directional_lights, std::vector&spot_lights, const KRViewport &viewport, KRNode::RenderPass renderPass, std::vector &remainingOctrees, std::vector &remainingOctreesTestResults, std::vector &remainingOctreesTestResultsOnly, bool bOcclusionResultsPass, bool bOcclusionTestResultsOnly); void updateOctree(const KRViewport &viewport); + void buildOctreeForTheFirstTime(); void notify_sceneGraphCreate(KRNode *pNode); void notify_sceneGraphDelete(KRNode *pNode); @@ -86,6 +90,7 @@ public: std::set &getAmbientZones(); std::set &getReverbZones(); std::set &getLocators(); + std::set &getLights(); private: @@ -101,6 +106,7 @@ private: std::set m_ambientZoneNodes; std::set m_reverbZoneNodes; std::set m_locatorNodes; + std::set m_lights; KROctree m_nodeTree; diff --git a/KREngine/kraken/KRShader.cpp b/KREngine/kraken/KRShader.cpp index b1423e0..ff74cf5 100644 --- a/KREngine/kraken/KRShader.cpp +++ b/KREngine/kraken/KRShader.cpp @@ -64,6 +64,7 @@ const char *KRShader::KRENGINE_UNIFORM_NAMES[] = { "projection_matrix", // KRENGINE_UNIFORM_PROJECTION_MATRIX "camera_position_model_space", // KRENGINE_UNIFORM_CAMERAPOS_MODEL_SPACE "viewport", // KRENGINE_UNIFORM_VIEWPORT + "viewport_downsample", // KRENGINE_UNIFORM_VIEWPORT_DOWNSAMPLE "diffuseTexture", // KRENGINE_UNIFORM_DIFFUSETEXTURE "specularTexture", // KRENGINE_UNIFORM_SPECULARTEXTURE "reflectionCubeTexture", // KRENGINE_UNIFORM_REFLECTIONCUBETEXTURE @@ -372,7 +373,7 @@ bool KRShader::bind(KRCamera &camera, const KRViewport &viewport, const KRMat4 & if(light_directional_count == 0) { int cShadowBuffers = directional_light->getShadowBufferCount(); if(m_uniforms[KRENGINE_UNIFORM_SHADOWTEXTURE1] != -1 && cShadowBuffers > 0) { - m_pContext->getTextureManager()->selectTexture(3, NULL); + m_pContext->getTextureManager()->selectTexture(3, NULL, 0.0f, KRTexture::TEXTURE_USAGE_SHADOW_DEPTH); m_pContext->getTextureManager()->_setActiveTexture(3); GLDEBUG(glBindTexture(GL_TEXTURE_2D, directional_light->getShadowTextures()[0])); GLDEBUG(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)); @@ -383,7 +384,7 @@ bool KRShader::bind(KRCamera &camera, const KRViewport &viewport, const KRMat4 & } if(m_uniforms[KRENGINE_UNIFORM_SHADOWTEXTURE2] != -1 && cShadowBuffers > 1 && camera.settings.m_cShadowBuffers > 1) { - m_pContext->getTextureManager()->selectTexture(4, NULL); + m_pContext->getTextureManager()->selectTexture(4, NULL, 0.0f, KRTexture::TEXTURE_USAGE_SHADOW_DEPTH); m_pContext->getTextureManager()->_setActiveTexture(4); GLDEBUG(glBindTexture(GL_TEXTURE_2D, directional_light->getShadowTextures()[1])); GLDEBUG(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)); @@ -393,7 +394,7 @@ bool KRShader::bind(KRCamera &camera, const KRViewport &viewport, const KRMat4 & } if(m_uniforms[KRENGINE_UNIFORM_SHADOWTEXTURE3] != -1 && cShadowBuffers > 2 && camera.settings.m_cShadowBuffers > 2) { - m_pContext->getTextureManager()->selectTexture(5, NULL); + m_pContext->getTextureManager()->selectTexture(5, NULL, 0.0f, KRTexture::TEXTURE_USAGE_SHADOW_DEPTH); m_pContext->getTextureManager()->_setActiveTexture(5); GLDEBUG(glActiveTexture(GL_TEXTURE5)); GLDEBUG(glBindTexture(GL_TEXTURE_2D, directional_light->getShadowTextures()[2])); @@ -502,14 +503,18 @@ bool KRShader::bind(KRCamera &camera, const KRViewport &viewport, const KRMat4 & if(m_uniforms[KRENGINE_UNIFORM_VIEWPORT] != -1) { setUniform(KRENGINE_UNIFORM_VIEWPORT, KRVector4( - (GLfloat)0.0, - (GLfloat)0.0, - (GLfloat)viewport.getSize().x, - (GLfloat)viewport.getSize().y + (GLfloat)0.0, + (GLfloat)0.0, + (GLfloat)viewport.getSize().x, + (GLfloat)viewport.getSize().y ) ); } + if(m_uniforms[KRENGINE_UNIFORM_VIEWPORT_DOWNSAMPLE] != -1) { + setUniform(KRENGINE_UNIFORM_VIEWPORT_DOWNSAMPLE, camera.getDownsample()); + } + // Rim highlighting parameters setUniform(KRENGINE_UNIFORM_RIM_COLOR, rim_color); setUniform(KRENGINE_UNIFORM_RIM_POWER, rim_power); diff --git a/KREngine/kraken/KRShader.h b/KREngine/kraken/KRShader.h index f0cdccc..c198ce6 100644 --- a/KREngine/kraken/KRShader.h +++ b/KREngine/kraken/KRShader.h @@ -76,6 +76,7 @@ public: KRENGINE_UNIFORM_PROJECTION_MATRIX, KRENGINE_UNIFORM_CAMERAPOS_MODEL_SPACE, KRENGINE_UNIFORM_VIEWPORT, + KRENGINE_UNIFORM_VIEWPORT_DOWNSAMPLE, KRENGINE_UNIFORM_DIFFUSETEXTURE, KRENGINE_UNIFORM_SPECULARTEXTURE, KRENGINE_UNIFORM_REFLECTIONCUBETEXTURE, diff --git a/KREngine/kraken/KRSpotLight.cpp b/KREngine/kraken/KRSpotLight.cpp index 0ca149c..f8018c5 100644 --- a/KREngine/kraken/KRSpotLight.cpp +++ b/KREngine/kraken/KRSpotLight.cpp @@ -49,3 +49,13 @@ void KRSpotLight::setInnerAngle(float innerAngle) { void KRSpotLight::setOuterAngle(float outerAngle) { m_outerAngle = outerAngle; } + +KRAABB KRSpotLight::getBounds() { + float influence_radius = m_decayStart - sqrt(m_intensity * 0.01f) / sqrt(KRLIGHT_MIN_INFLUENCE); + if(influence_radius < m_flareOcclusionSize) { + influence_radius = m_flareOcclusionSize; + } + return KRAABB(KRVector3(-influence_radius), KRVector3(influence_radius), getModelMatrix()); +} + + diff --git a/KREngine/kraken/KRSpotLight.h b/KREngine/kraken/KRSpotLight.h index 6ea1b60..7ab2772 100644 --- a/KREngine/kraken/KRSpotLight.h +++ b/KREngine/kraken/KRSpotLight.h @@ -19,7 +19,7 @@ public: virtual std::string getElementName(); virtual tinyxml2::XMLElement *saveXML( tinyxml2::XMLNode *parent); virtual void loadXML(tinyxml2::XMLElement *e); - + virtual KRAABB getBounds(); float getInnerAngle(); float getOuterAngle(); diff --git a/KREngine/kraken/KRSprite.cpp b/KREngine/kraken/KRSprite.cpp index 3ee9d93..b35d028 100644 --- a/KREngine/kraken/KRSprite.cpp +++ b/KREngine/kraken/KRSprite.cpp @@ -28,7 +28,6 @@ KRSprite::KRSprite(KRScene &scene, std::string name) : KRNode(scene, name) { m_spriteTexture = ""; m_pSpriteTexture = NULL; - m_spriteSize = 0.0f; m_spriteAlpha = 1.0f; } @@ -43,7 +42,6 @@ std::string KRSprite::getElementName() { tinyxml2::XMLElement *KRSprite::saveXML( tinyxml2::XMLNode *parent) { tinyxml2::XMLElement *e = KRNode::saveXML(parent); - e->SetAttribute("sprite_size", m_spriteSize); e->SetAttribute("sprite_texture", m_spriteTexture.c_str()); e->SetAttribute("sprite_alpha", m_spriteAlpha); return e; @@ -52,9 +50,6 @@ tinyxml2::XMLElement *KRSprite::saveXML( tinyxml2::XMLNode *parent) void KRSprite::loadXML(tinyxml2::XMLElement *e) { KRNode::loadXML(e); - if(e->QueryFloatAttribute("sprite_size", &m_spriteSize) != tinyxml2::XML_SUCCESS) { - m_spriteSize = 0.0f; - } if(e->QueryFloatAttribute("sprite_alpha", &m_spriteAlpha) != tinyxml2::XML_SUCCESS) { m_spriteAlpha = 1.0f; } @@ -73,11 +68,6 @@ void KRSprite::setSpriteTexture(std::string sprite_texture) { m_pSpriteTexture = NULL; } -void KRSprite::setSpriteSize(float sprite_size) { - // TODO - Deprecated - This should come from the localScale - m_spriteSize = sprite_size; -} - void KRSprite::setSpriteAlpha(float alpha) { m_spriteAlpha = alpha; @@ -89,17 +79,19 @@ float KRSprite::getSpriteAlpha() const } KRAABB KRSprite::getBounds() { - return KRAABB(KRVector3(-m_spriteSize), KRVector3(m_spriteSize), getModelMatrix()); + return KRAABB(-KRVector3::One() * 0.5f, KRVector3::One() * 0.5f, getModelMatrix()); } void KRSprite::render(KRCamera *pCamera, std::vector &point_lights, std::vector &directional_lights, std::vector&spot_lights, const KRViewport &viewport, KRNode::RenderPass renderPass) { + if(m_lod_visible <= LOD_VISIBILITY_PRESTREAM) return; + KRNode::render(pCamera, point_lights, directional_lights, spot_lights, viewport, renderPass); if(renderPass == KRNode::RENDER_PASS_ADDITIVE_PARTICLES) { - if(m_spriteTexture.size() && m_spriteSize > 0.0f && m_spriteAlpha > 0.0f) { + if(m_spriteTexture.size() && m_spriteAlpha > 0.0f) { if(!m_pSpriteTexture && m_spriteTexture.size()) { @@ -128,9 +120,8 @@ void KRSprite::render(KRCamera *pCamera, std::vector &point_ligh KRVector3 rim_color; if(getContext().getShaderManager()->selectShader(*pCamera, pShader, viewport, getModelMatrix(), point_lights, directional_lights, spot_lights, 0, renderPass, rim_color, 0.0f)) { pShader->setUniform(KRShader::KRENGINE_UNIFORM_MATERIAL_ALPHA, m_spriteAlpha); - pShader->setUniform(KRShader::KRENGINE_UNIFORM_FLARE_SIZE, m_spriteSize); - m_pContext->getTextureManager()->selectTexture(0, m_pSpriteTexture); - m_pContext->getModelManager()->bindVBO(getContext().getModelManager()->KRENGINE_VBO_2D_SQUARE_VERTICES, getContext().getModelManager()->KRENGINE_VBO_2D_SQUARE_INDEXES, getContext().getModelManager()->KRENGINE_VBO_2D_SQUARE_ATTRIBS, true); + m_pContext->getTextureManager()->selectTexture(0, m_pSpriteTexture, 0.0f, KRTexture::TEXTURE_USAGE_SPRITE); + m_pContext->getMeshManager()->bindVBO(&m_pContext->getMeshManager()->KRENGINE_VBO_DATA_2D_SQUARE_VERTICES); GLDEBUG(glDrawArrays(GL_TRIANGLE_STRIP, 0, 4)); } } diff --git a/KREngine/kraken/KRSprite.h b/KREngine/kraken/KRSprite.h index e64be0f..9ddc84e 100644 --- a/KREngine/kraken/KRSprite.h +++ b/KREngine/kraken/KRSprite.h @@ -23,7 +23,6 @@ public: virtual void loadXML(tinyxml2::XMLElement *e); void setSpriteTexture(std::string sprite_texture); - void setSpriteSize(float sprite_size); void setSpriteAlpha(float alpha); float getSpriteAlpha() const; @@ -35,7 +34,6 @@ protected: std::string m_spriteTexture; KRTexture *m_pSpriteTexture; - float m_spriteSize; float m_spriteAlpha; }; diff --git a/KREngine/kraken/KRTextureStreamer.h b/KREngine/kraken/KRStreamer.h similarity index 90% rename from KREngine/kraken/KRTextureStreamer.h rename to KREngine/kraken/KRStreamer.h index 39f3705..af6d545 100644 --- a/KREngine/kraken/KRTextureStreamer.h +++ b/KREngine/kraken/KRStreamer.h @@ -29,8 +29,8 @@ // or implied, of Kearwood Gilbert. // -#ifndef KRTEXTURESTREAMER_H -#define KRTEXTURESTREAMER_H +#ifndef KRSTREAMER_H +#define KRSTREAMER_H #include "KREngine-common.h" @@ -39,11 +39,11 @@ class KRContext; -class KRTextureStreamer +class KRStreamer { public: - KRTextureStreamer(KRContext &context); - ~KRTextureStreamer(); + KRStreamer(KRContext &context); + ~KRStreamer(); void startStreamer(); @@ -57,4 +57,4 @@ private: void run(); }; -#endif /* defined(KRTEXTURESTREAMER_H) */ +#endif /* defined(KRSTREAMER_H) */ diff --git a/KREngine/kraken/KRStreamer.mm b/KREngine/kraken/KRStreamer.mm new file mode 100644 index 0000000..a7a79f0 --- /dev/null +++ b/KREngine/kraken/KRStreamer.mm @@ -0,0 +1,98 @@ +// +// KRStreamer.cpp +// Kraken +// +// Created by Kearwood Gilbert on 11/1/2013. +// Copyright (c) 2013 Kearwood Software. All rights reserved. +// + +#include "KREngine-common.h" + +#include "KRStreamer.h" +#include "KRContext.h" + +#include + + +#if TARGET_OS_IPHONE + +EAGLContext *gTextureStreamerContext = nil; + +#elif TARGET_OS_MAC + +NSOpenGLContext *gTextureStreamerContext = nil; + +#else + +#error Unsupported Platform +#endif + +KRStreamer::KRStreamer(KRContext &context) : m_context(context) +{ + m_running = false; + m_stop = false; +} + +void KRStreamer::startStreamer() +{ + if(!m_running) { + m_running = true; + +#if TARGET_OS_IPHONE + + gTextureStreamerContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2 sharegroup: [EAGLContext currentContext].sharegroup]; + // FIXME: need to add code check for iOS 7 and also this appears to cause crashing + + //gTextureStreamerContext.multiThreaded = TRUE; + + +#elif TARGET_OS_MAC + + NSOpenGLPixelFormatAttribute pixelFormatAttributes[] = + { +// NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersionLegacy, + 0 + }; + NSOpenGLPixelFormat *pixelFormat = [[[NSOpenGLPixelFormat alloc] initWithAttributes:pixelFormatAttributes] autorelease]; + gTextureStreamerContext = [[NSOpenGLContext alloc] initWithFormat: pixelFormat shareContext: [NSOpenGLContext currentContext] ]; + +#else + + #error Unsupported Platform +#endif + + m_thread = std::thread(&KRStreamer::run, this); + } +} + +KRStreamer::~KRStreamer() +{ + if(m_running) { + m_stop = true; + m_thread.join(); + m_running = false; + } + + [gTextureStreamerContext release]; +} + +void KRStreamer::run() +{ + pthread_setname_np("Kraken - Streamer"); + + std::chrono::microseconds sleep_duration( 100 ); + +#if TARGET_OS_IPHONE + [EAGLContext setCurrentContext: gTextureStreamerContext]; +#elif TARGET_OS_MAC + [gTextureStreamerContext makeCurrentContext]; +#else +#error Unsupported Platform +#endif + + while(!m_stop) + { + m_context.doStreaming(); + std::this_thread::sleep_for( sleep_duration ); + } +} diff --git a/KREngine/kraken/KRTexture.cpp b/KREngine/kraken/KRTexture.cpp index af9f351..c6e1e6f 100644 --- a/KREngine/kraken/KRTexture.cpp +++ b/KREngine/kraken/KRTexture.cpp @@ -14,12 +14,15 @@ KRTexture::KRTexture(KRContext &context, std::string name) : KRResource(context, name) { + m_current_lod_max_dim = 0; + m_new_lod_max_dim = 0; m_iHandle = 0; m_iNewHandle = 0; m_textureMemUsed = 0; m_newTextureMemUsed = 0; m_last_frame_used = 0; - m_last_frame_bound = 0; + m_last_frame_max_lod_coverage = 0.0f; + m_last_frame_usage = TEXTURE_USAGE_NONE; m_handle_lock.clear(); } @@ -43,6 +46,8 @@ void KRTexture::releaseHandles() { m_iHandle = 0; m_textureMemUsed = 0; } + m_current_lod_max_dim = 0; + m_new_lod_max_dim = 0; m_handle_lock.clear(); @@ -60,7 +65,7 @@ long KRTexture::getReferencedMemSize() { void KRTexture::resize(int max_dim) { - if(!m_handle_lock.test_and_set()) + while(m_handle_lock.test_and_set()); // Spin lock { if(m_iHandle == m_iNewHandle) { if(max_dim == 0) { @@ -69,7 +74,7 @@ void KRTexture::resize(int max_dim) int target_dim = max_dim; if(target_dim < m_min_lod_max_dim) target_dim = m_min_lod_max_dim; - if(m_current_lod_max_dim != target_dim || (m_iHandle == 0 && m_iNewHandle == 0)) { + if(m_new_lod_max_dim != target_dim || (m_iHandle == 0 && m_iNewHandle == 0)) { assert(m_newTextureMemUsed == 0); m_newTextureMemUsed = getMemRequiredForSize(target_dim); @@ -79,7 +84,7 @@ void KRTexture::resize(int max_dim) if(!createGLTexture(target_dim)) { getContext().getTextureManager()->memoryChanged(-m_newTextureMemUsed); m_newTextureMemUsed = 0; - assert(false); + assert(false); // Failed to create the texture } } } @@ -90,26 +95,79 @@ void KRTexture::resize(int max_dim) } GLuint KRTexture::getHandle() { - resetPoolExpiry(); + resetPoolExpiry(0.0f, KRTexture::TEXTURE_USAGE_NONE); // TODO - Pass through getHandle() arguements to replace extraneous resetPoolExpiry calls? return m_iHandle; } -void KRTexture::resetPoolExpiry() +void KRTexture::resetPoolExpiry(float lodCoverage, KRTexture::texture_usage_t textureUsage) { - m_last_frame_used = getContext().getCurrentFrame(); + long current_frame = getContext().getCurrentFrame(); + if(current_frame != m_last_frame_used) { + m_last_frame_used = current_frame; + m_last_frame_max_lod_coverage = 0.0f; + m_last_frame_usage = TEXTURE_USAGE_NONE; + + getContext().getTextureManager()->primeTexture(this); + } + m_last_frame_max_lod_coverage = KRMAX(lodCoverage, m_last_frame_max_lod_coverage); + m_last_frame_usage = static_cast(static_cast(m_last_frame_usage) | static_cast(textureUsage)); +} + +kraken_stream_level KRTexture::getStreamLevel(KRTexture::texture_usage_t textureUsage) +{ + if(m_current_lod_max_dim == 0) { + return kraken_stream_level::STREAM_LEVEL_OUT; + } else if(m_current_lod_max_dim == KRMIN(getContext().KRENGINE_MAX_TEXTURE_DIM, m_max_lod_max_dim)) { + return kraken_stream_level::STREAM_LEVEL_IN_HQ; + } else if(m_current_lod_max_dim >= KRMAX(getContext().KRENGINE_MIN_TEXTURE_DIM, m_min_lod_max_dim)) { + return kraken_stream_level::STREAM_LEVEL_IN_LQ; + } else { + return kraken_stream_level::STREAM_LEVEL_OUT; + } +} + +float KRTexture::getStreamPriority() +{ + long current_frame = getContext().getCurrentFrame(); + if(current_frame > m_last_frame_used + 5) { + return 1.0f - KRCLAMP((float)(current_frame - m_last_frame_used) / 60.0f, 0.0f, 1.0f); + } else { + float priority = 100.0f; + if(m_last_frame_usage & (TEXTURE_USAGE_UI | TEXTURE_USAGE_SHADOW_DEPTH)) { + priority += 10000000.0f; + } + if(m_last_frame_usage & (TEXTURE_USAGE_SKY_CUBE | TEXTURE_USAGE_PARTICLE | TEXTURE_USAGE_SPRITE | TEXTURE_USAGE_LIGHT_FLARE)) { + priority += 1000000.0f; + } + if(m_last_frame_usage & (TEXTURE_USAGE_DIFFUSE_MAP | TEXTURE_USAGE_AMBIENT_MAP | TEXTURE_USAGE_SPECULAR_MAP | TEXTURE_USAGE_NORMAL_MAP | TEXTURE_USAGE_REFLECTION_MAP)) { + priority += 100000.0f; + } + if(m_last_frame_usage & (TEXTURE_USAGE_LIGHT_MAP)) { + priority += 100000.0f; + } + if(m_last_frame_usage & (TEXTURE_USAGE_REFECTION_CUBE)) { + priority += 100000.0f; + } + priority += m_last_frame_max_lod_coverage * 10.0f; + return priority; + } +} + +float KRTexture::getLastFrameLodCoverage() const +{ + return m_last_frame_max_lod_coverage; } long KRTexture::getLastFrameUsed() { return m_last_frame_used; } - bool KRTexture::isAnimated() { return false; } -KRTexture *KRTexture::compress() +KRTexture *KRTexture::compress(bool premultiply_alpha) { return NULL; } @@ -118,6 +176,10 @@ int KRTexture::getCurrentLodMaxDim() { return m_current_lod_max_dim; } +int KRTexture::getNewLodMaxDim() { + return m_new_lod_max_dim; +} + int KRTexture::getMaxMipMap() { return m_max_lod_max_dim; } @@ -131,15 +193,12 @@ bool KRTexture::hasMipmaps() { } void KRTexture::bind(GLuint texture_unit) { - m_last_frame_bound = getContext().getCurrentFrame(); -} - -bool KRTexture::canStreamOut() const { - return (m_last_frame_bound + 2 > getContext().getCurrentFrame()); + } void KRTexture::_swapHandles() { + //while(m_handle_lock.test_and_set()); // Spin lock if(!m_handle_lock.test_and_set()) { if(m_iHandle != m_iNewHandle) { if(m_iHandle != 0) { @@ -149,6 +208,7 @@ void KRTexture::_swapHandles() m_textureMemUsed = (long)m_newTextureMemUsed; m_newTextureMemUsed = 0; m_iHandle = m_iNewHandle; + m_current_lod_max_dim = m_new_lod_max_dim; } m_handle_lock.clear(); } diff --git a/KREngine/kraken/KRTexture.h b/KREngine/kraken/KRTexture.h index defc431..75284f6 100644 --- a/KREngine/kraken/KRTexture.h +++ b/KREngine/kraken/KRTexture.h @@ -38,8 +38,8 @@ #include "KRContextObject.h" #include "KRResource.h" - class KRDataBlock; +class KRCamera; class KRTexture : public KRResource { public: @@ -56,18 +56,40 @@ public: long getLastFrameUsed(); - virtual void resetPoolExpiry(); + typedef enum { + TEXTURE_USAGE_NONE = 0x00, + TEXTURE_USAGE_UI = 0x01, + TEXTURE_USAGE_SKY_CUBE = 0x02, + TEXTURE_USAGE_LIGHT_MAP = 0x04, + TEXTURE_USAGE_DIFFUSE_MAP = 0x08, + TEXTURE_USAGE_AMBIENT_MAP = 0x10, + TEXTURE_USAGE_SPECULAR_MAP = 0x20, + TEXTURE_USAGE_NORMAL_MAP = 0x40, + TEXTURE_USAGE_REFLECTION_MAP = 0x80, + TEXTURE_USAGE_REFECTION_CUBE = 0x100, + TEXTURE_USAGE_LIGHT_FLARE = 0x200, + TEXTURE_USAGE_SHADOW_DEPTH = 0x400, + TEXTURE_USAGE_PARTICLE = 0x800, + TEXTURE_USAGE_SPRITE = 0x1000 + } texture_usage_t; + + float getStreamPriority(); + + virtual void resetPoolExpiry(float lodCoverage, texture_usage_t textureUsage); virtual bool isAnimated(); - virtual KRTexture *compress(); + virtual KRTexture *compress(bool premultiply_alpha = false); int getCurrentLodMaxDim(); + int getNewLodMaxDim(); // For use by streamer only int getMaxMipMap(); int getMinMipMap(); bool hasMipmaps(); - bool canStreamOut() const; + kraken_stream_level getStreamLevel(KRTexture::texture_usage_t textureUsage); + float getLastFrameLodCoverage() const; void _swapHandles(); + protected: virtual bool createGLTexture(int lod_max_dim) = 0; GLuint getHandle(); @@ -78,12 +100,14 @@ protected: std::atomic_flag m_handle_lock; int m_current_lod_max_dim; + int m_new_lod_max_dim; uint32_t m_max_lod_max_dim; uint32_t m_min_lod_max_dim; long m_last_frame_used; - long m_last_frame_bound; + float m_last_frame_max_lod_coverage; + texture_usage_t m_last_frame_usage; private: std::atomic m_textureMemUsed; diff --git a/KREngine/kraken/KRTexture2D.cpp b/KREngine/kraken/KRTexture2D.cpp index 11918d9..25a7a7e 100644 --- a/KREngine/kraken/KRTexture2D.cpp +++ b/KREngine/kraken/KRTexture2D.cpp @@ -34,7 +34,6 @@ #include "KRTextureManager.h" KRTexture2D::KRTexture2D(KRContext &context, KRDataBlock *data, std::string name) : KRTexture(context, name) { - m_current_lod_max_dim = 0; m_pData = data; } @@ -48,16 +47,11 @@ bool KRTexture2D::createGLTexture(int lod_max_dim) { } bool success = true; - int prev_lod_max_dim = 0; -#if GL_APPLE_copy_texture_levels && GL_EXT_texture_storage - - if(m_iHandle != 0) { - prev_lod_max_dim = m_current_lod_max_dim; - } -#endif + int prev_lod_max_dim = m_new_lod_max_dim; + m_iNewHandle = 0; - m_current_lod_max_dim = 0; + m_new_lod_max_dim = 0; GLDEBUG(glGenTextures(1, &m_iNewHandle)); if(m_iNewHandle == 0) { @@ -71,10 +65,10 @@ bool KRTexture2D::createGLTexture(int lod_max_dim) { GLDEBUG(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)); } - if(!uploadTexture(GL_TEXTURE_2D, lod_max_dim, m_current_lod_max_dim, prev_lod_max_dim)) { + if(!uploadTexture(GL_TEXTURE_2D, lod_max_dim, m_new_lod_max_dim)) { GLDEBUG(glDeleteTextures(1, &m_iNewHandle)); m_iNewHandle = m_iHandle; - m_current_lod_max_dim = prev_lod_max_dim; + m_new_lod_max_dim = prev_lod_max_dim; success = false; } } diff --git a/KREngine/kraken/KRTexture2D.h b/KREngine/kraken/KRTexture2D.h index f7f4303..8b32bdd 100644 --- a/KREngine/kraken/KRTexture2D.h +++ b/KREngine/kraken/KRTexture2D.h @@ -46,7 +46,7 @@ public: virtual bool save(const std::string& path); virtual bool save(KRDataBlock &data); - virtual bool uploadTexture(GLenum target, int lod_max_dim, int ¤t_lod_max_dim, int prev_lod_max_dim, bool compress = false) = 0; + virtual bool uploadTexture(GLenum target, int lod_max_dim, int ¤t_lod_max_dim, bool compress = false, bool premultiply_alpha = false) = 0; virtual void bind(GLuint texture_unit); protected: diff --git a/KREngine/kraken/KRTextureAnimated.cpp b/KREngine/kraken/KRTextureAnimated.cpp index c25028a..f3e80c8 100644 --- a/KREngine/kraken/KRTextureAnimated.cpp +++ b/KREngine/kraken/KRTextureAnimated.cpp @@ -91,21 +91,20 @@ long KRTextureAnimated::getMemRequiredForSize(int max_dim) } -void KRTextureAnimated::resetPoolExpiry() +void KRTextureAnimated::resetPoolExpiry(float lodCoverage, texture_usage_t textureUsage) { - KRTexture::resetPoolExpiry(); + KRTexture::resetPoolExpiry(lodCoverage, textureUsage); for(int i=0; iresetPoolExpiry(); // Ensure that frames of animated textures do not expire from the texture pool prematurely, as they are referenced indirectly - getContext().getTextureManager()->primeTexture(frame_texture); + frame_texture->resetPoolExpiry(lodCoverage, textureUsage); // Ensure that frames of animated textures do not expire from the texture pool prematurely, as they are referenced indirectly } } } void KRTextureAnimated::bind(GLuint texture_unit) { - resetPoolExpiry(); + resetPoolExpiry(0.0f, TEXTURE_USAGE_NONE); // TODO - Need to set parameters here for streaming priority? KRTexture::bind(texture_unit); int frame_number = (int)floor(fmodf(getContext().getAbsoluteTime() * m_frame_rate,m_frame_count)); KRTexture2D *frame_texture = textureForFrame(frame_number); diff --git a/KREngine/kraken/KRTextureAnimated.h b/KREngine/kraken/KRTextureAnimated.h index 9e685b6..94ae16c 100644 --- a/KREngine/kraken/KRTextureAnimated.h +++ b/KREngine/kraken/KRTextureAnimated.h @@ -45,7 +45,7 @@ public: virtual void bind(GLuint texture_unit); virtual long getMemRequiredForSize(int max_dim); - virtual void resetPoolExpiry(); + virtual void resetPoolExpiry(float lodCoverage, texture_usage_t textureUsage); virtual long getReferencedMemSize(); diff --git a/KREngine/kraken/KRTextureCube.cpp b/KREngine/kraken/KRTextureCube.cpp index dcf8e0f..57a7bef 100644 --- a/KREngine/kraken/KRTextureCube.cpp +++ b/KREngine/kraken/KRTextureCube.cpp @@ -40,11 +40,14 @@ KRTextureCube::KRTextureCube(KRContext &context, std::string name) : KRTexture(c m_min_lod_max_dim = 64; for(int i=0; i<6; i++) { + m_textures[i] = NULL; std::string faceName = getName() + SUFFIXES[i]; - KRTexture2D *faceTexture = (KRTexture2D *)getContext().getTextureManager()->getTexture(faceName); - if(faceTexture) { - if(faceTexture->getMaxMipMap() < m_max_lod_max_dim) m_max_lod_max_dim = faceTexture->getMaxMipMap(); - if(faceTexture->getMinMipMap() > m_min_lod_max_dim) m_min_lod_max_dim = faceTexture->getMinMipMap(); + m_textures[i] = (KRTexture2D *)getContext().getTextureManager()->getTexture(faceName); + if(m_textures[i]) { + if(m_textures[i]->getMaxMipMap() < m_max_lod_max_dim) m_max_lod_max_dim = m_textures[i]->getMaxMipMap(); + if(m_textures[i]->getMinMipMap() > m_min_lod_max_dim) m_min_lod_max_dim = m_textures[i]->getMinMipMap(); + } else { + assert(false); } } } @@ -58,40 +61,30 @@ bool KRTextureCube::createGLTexture(int lod_max_dim) assert(m_iNewHandle == m_iHandle); // Only allow one resize per frame bool success = true; - int prev_lod_max_dim = 0; -#if GL_APPLE_copy_texture_levels && GL_EXT_texture_storage - - if(m_iHandle != 0) { - prev_lod_max_dim = m_current_lod_max_dim; - } - - -#endif m_iNewHandle = 0; GLDEBUG(glGenTextures(1, &m_iNewHandle)); assert(m_iNewHandle != 0); - m_current_lod_max_dim = 0; + m_new_lod_max_dim = 0; GLDEBUG(glBindTexture(GL_TEXTURE_CUBE_MAP, m_iNewHandle)); bool bMipMaps = false; for(int i=0; i<6; i++) { std::string faceName = getName() + SUFFIXES[i]; - KRTexture2D *faceTexture = (KRTexture2D *)getContext().getTextureManager()->getTexture(faceName); - if(faceTexture) { - if(faceTexture->hasMipmaps()) bMipMaps = true; - faceTexture->uploadTexture(TARGETS[i], lod_max_dim, m_current_lod_max_dim, prev_lod_max_dim); + if(m_textures[i]) { + if(m_textures[i]->hasMipmaps()) bMipMaps = true; + m_textures[i]->uploadTexture(TARGETS[i], lod_max_dim, m_new_lod_max_dim); } } if(bMipMaps) { GLDEBUG(glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR)); } else { - // GLDEBUG(glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR)); - GLDEBUG(glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR)); - GLDEBUG(glGenerateMipmap(GL_TEXTURE_CUBE_MAP)); + GLDEBUG(glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR)); + // GLDEBUG(glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR)); + // GLDEBUG(glGenerateMipmap(GL_TEXTURE_CUBE_MAP)); } @@ -105,27 +98,24 @@ long KRTextureCube::getMemRequiredForSize(int max_dim) long memoryRequired = 0; for(int i=0; i<6; i++) { - std::string faceName = getName() + SUFFIXES[i]; - KRTexture2D *faceTexture = (KRTexture2D *)getContext().getTextureManager()->getTexture(faceName); - if(faceTexture) { - memoryRequired += faceTexture->getMemRequiredForSize(target_dim); + if(m_textures[i]) { + memoryRequired += m_textures[i]->getMemRequiredForSize(target_dim); } } return memoryRequired; } - -void KRTextureCube::resetPoolExpiry() +/* +void KRTextureCube::resetPoolExpiry(float lodCoverage, texture_usage_t textureUsage) { - KRTexture::resetPoolExpiry(); + KRTexture::resetPoolExpiry(lodCoverage, textureUsage); for(int i=0; i<6; i++) { - std::string faceName = getName() + SUFFIXES[i]; - KRTexture2D *faceTexture = (KRTexture2D *)getContext().getTextureManager()->getTexture(faceName); - if(faceTexture) { - faceTexture->resetPoolExpiry(); // Ensure that side of cube maps do not expire from the texture pool prematurely, as they are referenced indirectly + if(m_textures[i]) { + m_textures[i]->resetPoolExpiry(lodCoverage, textureUsage); // Ensure that side of cube maps do not expire from the texture pool prematurely, as they are referenced indirectly } } } +*/ void KRTextureCube::bind(GLuint texture_unit) { diff --git a/KREngine/kraken/KRTextureCube.h b/KREngine/kraken/KRTextureCube.h index e242147..c643e2b 100644 --- a/KREngine/kraken/KRTextureCube.h +++ b/KREngine/kraken/KRTextureCube.h @@ -34,6 +34,8 @@ #include "KRTexture.h" +class KRTexture2D; + class KRTextureCube : public KRTexture { public: KRTextureCube(KRContext &context, std::string name); @@ -44,7 +46,7 @@ public: virtual void bind(GLuint texture_unit); virtual long getMemRequiredForSize(int max_dim); - virtual void resetPoolExpiry(); +// virtual void resetPoolExpiry(float lodCoverage, texture_usage_t textureUsage); private: virtual bool createGLTexture(int lod_max_dim); @@ -66,6 +68,8 @@ private: "_positive_z", "_negative_z" }; + + KRTexture2D *m_textures[6]; }; diff --git a/KREngine/kraken/KRTextureKTX.cpp b/KREngine/kraken/KRTextureKTX.cpp index 0550554..a1bb5bd 100644 --- a/KREngine/kraken/KRTextureKTX.cpp +++ b/KREngine/kraken/KRTextureKTX.cpp @@ -153,7 +153,7 @@ long KRTextureKTX::getMemRequiredForSize(int max_dim) return memoryRequired; } -bool KRTextureKTX::uploadTexture(GLenum target, int lod_max_dim, int ¤t_lod_max_dim, int prev_lod_max_dim, bool compress) +bool KRTextureKTX::uploadTexture(GLenum target, int lod_max_dim, int ¤t_lod_max_dim, bool compress, bool premultiply_alpha) { int target_dim = lod_max_dim; if(target_dim < m_min_lod_max_dim) target_dim = m_min_lod_max_dim; @@ -220,7 +220,7 @@ bool KRTextureKTX::uploadTexture(GLenum target, int lod_max_dim, int ¤t_lo current_lod_max_dim = height; } #if GL_APPLE_copy_texture_levels && GL_EXT_texture_storage - if(target == GL_TEXTURE_2D && width <= prev_lod_max_dim && height <= prev_lod_max_dim) { + if(target == GL_TEXTURE_2D && width <= m_current_lod_max_dim && height <= m_current_lod_max_dim) { //GLDEBUG(glCompressedTexImage2D(target, i, (GLenum)m_header.glInternalFormat, width, height, 0, block.length, NULL)); // Allocate, but don't copy // GLDEBUG(glTexImage2D(target, 0, GL_RGBA, width, height, 0, GL_BGRA, GL_UNSIGNED_BYTE, NULL)); GLDEBUG(glCopyTextureLevelsAPPLE(m_iNewHandle, m_iHandle, source_level, 1)); @@ -253,7 +253,7 @@ bool KRTextureKTX::uploadTexture(GLenum target, int lod_max_dim, int ¤t_lo destination_level++; } - if(width <= prev_lod_max_dim && height <= prev_lod_max_dim) { + if(width <= m_current_lod_max_dim && height <= m_current_lod_max_dim) { source_level++; } diff --git a/KREngine/kraken/KRTextureKTX.h b/KREngine/kraken/KRTextureKTX.h index 13308b8..4f1279e 100644 --- a/KREngine/kraken/KRTextureKTX.h +++ b/KREngine/kraken/KRTextureKTX.h @@ -19,7 +19,7 @@ public: virtual ~KRTextureKTX(); virtual std::string getExtension(); - bool uploadTexture(GLenum target, int lod_max_dim, int ¤t_lod_max_dim, int prev_lod_max_dim, bool compress = false); + bool uploadTexture(GLenum target, int lod_max_dim, int ¤t_lod_max_dim, bool compress = false, bool premultiply_alpha = false); virtual long getMemRequiredForSize(int max_dim); diff --git a/KREngine/kraken/KRTextureManager.cpp b/KREngine/kraken/KRTextureManager.cpp index 2f554c8..c9fdcc7 100644 --- a/KREngine/kraken/KRTextureManager.cpp +++ b/KREngine/kraken/KRTextureManager.cpp @@ -40,14 +40,14 @@ #include "KRTextureAnimated.h" #include "KRContext.h" -KRTextureManager::KRTextureManager(KRContext &context) : KRContextObject(context), m_streamer(context) { +KRTextureManager::KRTextureManager(KRContext &context) : KRContextObject(context) { m_textureMemUsed = 0; for(int iTexture=0; iTexture::iterator itr = m_textures.find(lowerName); if(itr == m_textures.end()) { - KRTextureCube *pTexture = new KRTextureCube(getContext(), lowerName); - m_textures[lowerName] = pTexture; - return pTexture; + // Defer resolving the texture cube until its referenced textures are ready + const GLenum TARGETS[6] = { + GL_TEXTURE_CUBE_MAP_POSITIVE_X, + GL_TEXTURE_CUBE_MAP_NEGATIVE_X, + GL_TEXTURE_CUBE_MAP_POSITIVE_Y, + GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, + GL_TEXTURE_CUBE_MAP_POSITIVE_Z, + GL_TEXTURE_CUBE_MAP_NEGATIVE_Z + }; + + const char *SUFFIXES[6] = { + "_positive_x", + "_negative_x", + "_positive_y", + "_negative_y", + "_positive_z", + "_negative_z" + }; + bool found_all = true; + for(int i=0; i<6; i++) { + std::string faceName = lowerName + SUFFIXES[i]; + KRTexture *faceTexture = dynamic_cast(getContext().getTextureManager()->getTexture(faceName)); + if(faceTexture == NULL) { + found_all = false; + } + } + + if(found_all) { + KRTextureCube *pTexture = new KRTextureCube(getContext(), lowerName); + + m_textures[lowerName] = pTexture; + return pTexture; + } else { + return NULL; + } } else { return (*itr).second; } @@ -171,7 +203,7 @@ KRTexture *KRTextureManager::getTexture(const std::string &name) { return pTexture; } else { // Not found - //fprintf(stderr, "ERROR: Texture not found: %s\n", szName); + // fprintf(stderr, "ERROR: Texture not found: %s\n", name.c_str()); return NULL; } } else { @@ -179,19 +211,17 @@ KRTexture *KRTextureManager::getTexture(const std::string &name) { } } -void KRTextureManager::selectTexture(int iTextureUnit, KRTexture *pTexture) { +void KRTextureManager::selectTexture(int iTextureUnit, KRTexture *pTexture, float lod_coverage, KRTexture::texture_usage_t textureUsage) { bool is_animated = false; if(pTexture) { + pTexture->resetPoolExpiry(lod_coverage, textureUsage); if(pTexture->isAnimated()) is_animated = true; } if(m_boundTextures[iTextureUnit] != pTexture || is_animated) { _setActiveTexture(iTextureUnit); if(pTexture != NULL) { - primeTexture(pTexture); - pTexture->bind(iTextureUnit); - } else { GLDEBUG(glBindTexture(GL_TEXTURE_2D, 0)); } @@ -200,14 +230,6 @@ void KRTextureManager::selectTexture(int iTextureUnit, KRTexture *pTexture) { } -void KRTextureManager::primeTexture(KRTexture *pTexture) -{ - m_poolTextures.erase(pTexture); - if(m_activeTextures.find(pTexture) == m_activeTextures.end()) { - m_activeTextures.insert(pTexture); - } -} - long KRTextureManager::getMemUsed() { return m_textureMemUsed; } @@ -224,17 +246,39 @@ long KRTextureManager::getMemActive() { void KRTextureManager::startFrame(float deltaTime) { - m_streamer.startStreamer(); _clearGLState(); - for(std::set::iterator itr=m_activeTextures.begin(); itr != m_activeTextures.end(); itr++) { - KRTexture *activeTexture = *itr; - activeTexture->_swapHandles(); - } // TODO - Implement proper double-buffering to reduce copy operations m_streamerFenceMutex.lock(); - m_activeTextures_streamer_copy = m_activeTextures; - m_poolTextures_streamer_copy = m_poolTextures; + + if(m_streamerComplete) { + assert(m_activeTextures_streamer_copy.size() == 0); // The streamer should have emptied this if it really did complete + + const long KRENGINE_TEXTURE_EXPIRY_FRAMES = 10; + + + std::set expiredTextures; + for(std::set::iterator itr=m_activeTextures.begin(); itr != m_activeTextures.end(); itr++) { + KRTexture *activeTexture = *itr; + activeTexture->_swapHandles(); + if(activeTexture->getLastFrameUsed() + KRENGINE_TEXTURE_EXPIRY_FRAMES < getContext().getCurrentFrame()) { + // Expire textures that haven't been used in a long time + expiredTextures.insert(activeTexture); + activeTexture->releaseHandles(); + } else { + float priority = activeTexture->getStreamPriority(); + m_activeTextures_streamer_copy.push_back(std::pair(priority, activeTexture)); + } + } + for(std::set::iterator itr=expiredTextures.begin(); itr != expiredTextures.end(); itr++) { + m_activeTextures.erase(*itr); + } + + if(m_activeTextures_streamer_copy.size() > 0) { + m_streamerComplete = false; + } + } + m_streamerFenceMutex.unlock(); m_memoryTransferredThisFrame = 0; @@ -245,127 +289,120 @@ void KRTextureManager::endFrame(float deltaTime) { for(int iTexture=0; iTexture < KRENGINE_MAX_TEXTURE_UNITS; iTexture++) { if(m_boundTextures[iTexture]) { - m_boundTextures[iTexture]->resetPoolExpiry(); // Even if the same texture is bound, ensure that they don't expire from the texture pool while in use + m_boundTextures[iTexture]->resetPoolExpiry(0.0f, KRTexture::TEXTURE_USAGE_NONE); // Even if the same texture is bound, ensure that they don't expire from the texture pool while in use } } } -void KRTextureManager::doStreaming() +void KRTextureManager::doStreaming(long &memoryRemaining, long &memoryRemainingThisFrame) { + // TODO - Implement proper double-buffering to reduce copy operations m_streamerFenceMutex.lock(); - m_activeTextures_streamer = m_activeTextures_streamer_copy; - m_poolTextures_streamer = m_poolTextures_streamer_copy; + m_activeTextures_streamer = std::move(m_activeTextures_streamer_copy); m_streamerFenceMutex.unlock(); - balanceTextureMemory(); + if(m_activeTextures_streamer.size() > 0) { + balanceTextureMemory(memoryRemaining, memoryRemainingThisFrame); + + m_streamerFenceMutex.lock(); + m_streamerComplete = true; + m_streamerFenceMutex.unlock(); + } } -void KRTextureManager::balanceTextureMemory() +void KRTextureManager::balanceTextureMemory(long &memoryRemaining, long &memoryRemainingThisFrame) { // Balance texture memory by reducing and increasing the maximum mip-map level of both active and inactive textures // Favour performance over maximum texture resolution when memory is insufficient for textures at full resolution. - // Determine the additional amount of memory required in order to resize all active textures to the maximum size - long wantedTextureMem = 0; - for(std::set::iterator itr=m_activeTextures_streamer.begin(); itr != m_activeTextures_streamer.end(); itr++) { - KRTexture *activeTexture = *itr; + /* + NEW ALGORITHM: + + Textures are assigned a “weight” by tuneable criteria: + - Area of screen coverage taken by objects containing material (more accurate and generic than distance) + - Type of texture (separate weight for normal, diffuse, spec maps) + - Last used time (to keep textures loaded for recently seen objects that are outside of the view frustum) + Those factors combine together to give a “weight”, which represents a proportion relative to all other textures weights + Mipmap levels are stripped off of each texture until they occupy the amount of memory they should proportionally have + This is in contrast to the global ceiling of texture resolution that slowly drops until the textures fit + + */ + + // --------------- + + //long MAX_STREAM_TIME = 66; + //long startTime = getContext().getAbsoluteTimeMilliseconds(); + + std::sort(m_activeTextures_streamer.begin(), m_activeTextures_streamer.end(), std::greater>()); + + for(auto itr=m_activeTextures_streamer.begin(); itr != m_activeTextures_streamer.end(); itr++) { + KRTexture *texture = (*itr).second; + int min_mip_level = KRMAX(getContext().KRENGINE_MIN_TEXTURE_DIM, texture->getMinMipMap()); + long minLodMem = texture->getMemRequiredForSize(min_mip_level); + memoryRemaining -= minLodMem; - wantedTextureMem = activeTexture->getMemRequiredForSize(getContext().KRENGINE_MAX_TEXTURE_DIM) - activeTexture->getMemSize(); + if(memoryRemainingThisFrame > minLodMem && texture->getNewLodMaxDim() < min_mip_level) { + memoryRemainingThisFrame -= minLodMem; + texture->resize(min_mip_level); + } } - // Determine how much memory we need to free up - long memoryDeficit = wantedTextureMem - (getContext().KRENGINE_TARGET_TEXTURE_MEM_MAX - getMemUsed()); + //long minMipTime = getContext().getAbsoluteTimeMilliseconds() - startTime; - - // Determine how many mip map levels we need to strip off of inactive textures to free the memory we need - long maxDimInactive = getContext().KRENGINE_MAX_TEXTURE_DIM; - long potentialMemorySaving = 0; - while(potentialMemorySaving < memoryDeficit && maxDimInactive > getContext().KRENGINE_MIN_TEXTURE_DIM) { - maxDimInactive = maxDimInactive >> 1; - potentialMemorySaving = 0; - - for(std::set::iterator itr=m_poolTextures_streamer.begin(); itr != m_poolTextures_streamer.end(); itr++) { - KRTexture *poolTexture = *itr; - long potentialMemoryDelta = poolTexture->getMemRequiredForSize(maxDimInactive) - poolTexture->getMemSize(); - if(potentialMemoryDelta < 0) { - potentialMemorySaving += -potentialMemoryDelta; + std::vector mipPercents = {75, 75, 50, 50, 50}; + int mip_drop = -1; + auto mip_itr = mipPercents.begin(); + long memoryRemainingThisMip = 0; + + for(auto itr=m_activeTextures_streamer.begin(); itr != m_activeTextures_streamer.end(); itr++) { + if(memoryRemainingThisMip <= 0) { + if(mip_itr == mipPercents.end()) { + break; + } else { + memoryRemainingThisMip = memoryRemaining / 100L * (long)(*mip_itr); + mip_drop++; + mip_itr++; } } - } - - // Strip off mipmap levels of inactive textures to free up memory - long inactive_texture_mem_used_target = 0; - for(std::set::iterator itr=m_poolTextures_streamer.begin(); itr != m_poolTextures_streamer.end(); itr++) { - KRTexture *poolTexture = *itr; - long mem_required = poolTexture->getMemRequiredForSize(maxDimInactive); - long potentialMemoryDelta = mem_required - poolTexture->getMemSize(); - if(potentialMemoryDelta < 0) { - if(mem_required * 2 + getMemUsed() < KRContext::KRENGINE_MAX_TEXTURE_MEM) { - long mem_free; - m_pContext->getMemoryStats(mem_free); - if(mem_required * 2 < mem_free - 10000000) { - poolTexture->resize(maxDimInactive); - } + + KRTexture *texture = (*itr).second; + int min_mip_level = KRMAX(getContext().KRENGINE_MIN_TEXTURE_DIM, texture->getMinMipMap()); + int max_mip_level = KRMIN(getContext().KRENGINE_MAX_TEXTURE_DIM, texture->getMaxMipMap()); + int target_mip_level = (max_mip_level >> mip_drop); + long targetMem = texture->getMemRequiredForSize(target_mip_level); + long additionalMemRequired = targetMem - texture->getMemRequiredForSize(min_mip_level); + memoryRemainingThisMip -= additionalMemRequired; + memoryRemaining -= additionalMemRequired; + if(memoryRemainingThisMip > 0 && memoryRemainingThisFrame > targetMem) { + int current_mip_level = texture->getNewLodMaxDim(); + if(current_mip_level == (target_mip_level >> 1) || target_mip_level < current_mip_level) { + memoryRemainingThisFrame -= targetMem; + texture->resize(target_mip_level); + } else if(current_mip_level == (target_mip_level >> 2)) { + memoryRemainingThisFrame -= texture->getMemRequiredForSize(target_mip_level >> 1); + texture->resize(target_mip_level >> 1); + } else if(current_mip_level < (target_mip_level >> 2)) { + memoryRemainingThisFrame -= texture->getMemRequiredForSize(target_mip_level >> 2); + texture->resize(target_mip_level >> 2); } - inactive_texture_mem_used_target += mem_required; - } else { - inactive_texture_mem_used_target += poolTexture->getMemSize(); - } - } - - // Determine the maximum mipmap level for the active textures we can achieve with the memory that is available - long memory_available = 0; - long maxDimActive = getContext().KRENGINE_MAX_TEXTURE_DIM; - while(memory_available <= 0 && maxDimActive >= getContext().KRENGINE_MIN_TEXTURE_DIM) { - memory_available = getContext().KRENGINE_TARGET_TEXTURE_MEM_MAX - inactive_texture_mem_used_target; - for(std::set::iterator itr=m_activeTextures_streamer.begin(); itr != m_activeTextures_streamer.end() && memory_available > 0; itr++) { - KRTexture *activeTexture = *itr; - memory_available -= activeTexture->getMemRequiredForSize(maxDimActive); } - if(memory_available <= 0) { - maxDimActive = maxDimActive >> 1; // Try the next smaller mipmap size - } + //if(getContext().getAbsoluteTimeMilliseconds() - startTime > MAX_STREAM_TIME) { + // return; // Bail out early if we spend too long + //} } - // Resize active textures to balance the memory usage and mipmap levels - for(std::set::iterator itr=m_activeTextures_streamer.begin(); itr != m_activeTextures_streamer.end() && memory_available > 0; itr++) { - KRTexture *activeTexture = *itr; - long mem_required = activeTexture->getMemRequiredForSize(maxDimActive); - if(mem_required * 2 + getMemUsed() < KRContext::KRENGINE_MAX_TEXTURE_MEM) { - long mem_free; - m_pContext->getMemoryStats(mem_free); - if(mem_required * 2 < mem_free - 10000000) { - activeTexture->resize(maxDimActive); - } - } - } + glFlush(); - //fprintf(stderr, "Active mipmap size: %i Inactive mapmap size: %i\n", (int)maxDimActive, (int)maxDimInactive); + //long streamerTime = getContext().getAbsoluteTimeMilliseconds() - startTime; + //fprintf(stderr, "%i / %i\n", (int)minMipTime, (int)streamerTime); + } void KRTextureManager::rotateBuffers() { - const long KRENGINE_TEXTURE_EXPIRY_FRAMES = 120; - - // ----====---- Expire textures that haven't been used in a long time ----====---- - std::set expiredTextures; - for(std::set::iterator itr=m_poolTextures.begin(); itr != m_poolTextures.end(); itr++) { - KRTexture *poolTexture = *itr; - if(poolTexture->getLastFrameUsed() + KRENGINE_TEXTURE_EXPIRY_FRAMES < getContext().getCurrentFrame()) { - expiredTextures.insert(poolTexture); - poolTexture->releaseHandles(); - } - } - for(std::set::iterator itr=expiredTextures.begin(); itr != expiredTextures.end(); itr++) { - m_poolTextures.erase(*itr); - } - - // ----====---- Swap the buffers ----====---- - m_poolTextures.insert(m_activeTextures.begin(), m_activeTextures.end()); - m_activeTextures.clear(); } long KRTextureManager::getMemoryTransferedThisFrame() @@ -389,17 +426,19 @@ unordered_map &KRTextureManager::getTextures() return m_textures; } -void KRTextureManager::compress() +void KRTextureManager::compress(bool premultiply_alpha) { std::vector textures_to_remove; std::vector textures_to_add; for(unordered_map::iterator itr=m_textures.begin(); itr != m_textures.end(); itr++) { KRTexture *texture = (*itr).second; - KRTexture *compressed_texture = texture->compress(); + KRTexture *compressed_texture = texture->compress(premultiply_alpha); if(compressed_texture) { textures_to_remove.push_back(texture); textures_to_add.push_back(compressed_texture); + } else { + assert(false); } } @@ -427,8 +466,10 @@ std::set &KRTextureManager::getActiveTextures() return m_activeTextures; } -std::set &KRTextureManager::getPoolTextures() +void KRTextureManager::primeTexture(KRTexture *texture) { - return m_poolTextures; + if(m_activeTextures.find(texture) == m_activeTextures.end()) { + m_activeTextures.insert(texture); + } } diff --git a/KREngine/kraken/KRTextureManager.h b/KREngine/kraken/KRTextureManager.h index cdf8b99..fdc81db 100644 --- a/KREngine/kraken/KRTextureManager.h +++ b/KREngine/kraken/KRTextureManager.h @@ -39,15 +39,14 @@ #include "KREngine-common.h" #include "KRDataBlock.h" #include "KRContext.h" -#include "KRTextureStreamer.h" +#include "KRStreamer.h" class KRTextureManager : public KRContextObject { public: KRTextureManager(KRContext &context); virtual ~KRTextureManager(); - void primeTexture(KRTexture *pTexture); - void selectTexture(int iTextureUnit, KRTexture *pTexture); + void selectTexture(int iTextureUnit, KRTexture *pTexture, float lod_coverage, KRTexture::texture_usage_t textureUsage); KRTexture *loadTexture(const char *szName, const char *szExtension, KRDataBlock *data); KRTexture *getTextureCube(const char *szName); @@ -66,10 +65,9 @@ public: unordered_map &getTextures(); - void compress(); + void compress(bool premultiply_alpha = false); std::set &getActiveTextures(); - std::set &getPoolTextures(); void _setActiveTexture(int i); void _setWrapModeS(GLuint i, GLuint wrap_mode); @@ -79,7 +77,8 @@ public: void _clearGLState(); void setMaxAnisotropy(float max_anisotropy); - void doStreaming(); + void doStreaming(long &memoryRemaining, long &memoryRemainingThisFrame); + void primeTexture(KRTexture *texture); private: int m_iActiveTexture; @@ -95,19 +94,15 @@ private: std::set m_activeTextures; - std::set m_poolTextures; - std::set m_activeTextures_streamer; - std::set m_poolTextures_streamer; - std::set m_activeTextures_streamer_copy; - std::set m_poolTextures_streamer_copy; + std::vector > m_activeTextures_streamer; + std::vector > m_activeTextures_streamer_copy; + bool m_streamerComplete; std::atomic m_textureMemUsed; void rotateBuffers(); - void balanceTextureMemory(); - - KRTextureStreamer m_streamer; + void balanceTextureMemory(long &memoryRemaining, long &memoryRemainingThisFrame); std::mutex m_streamerFenceMutex; }; diff --git a/KREngine/kraken/KRTexturePVR.cpp b/KREngine/kraken/KRTexturePVR.cpp index 419ccbe..24de4b4 100644 --- a/KREngine/kraken/KRTexturePVR.cpp +++ b/KREngine/kraken/KRTexturePVR.cpp @@ -173,7 +173,7 @@ long KRTexturePVR::getMemRequiredForSize(int max_dim) return memoryRequired; } -bool KRTexturePVR::uploadTexture(GLenum target, int lod_max_dim, int ¤t_lod_max_dim, int prev_lod_max_dim, bool compress) +bool KRTexturePVR::uploadTexture(GLenum target, int lod_max_dim, int ¤t_lod_max_dim, bool compress, bool premultiply_alpha) { int target_dim = lod_max_dim; if(target_dim < m_min_lod_max_dim) target_dim = m_min_lod_max_dim; @@ -240,7 +240,7 @@ bool KRTexturePVR::uploadTexture(GLenum target, int lod_max_dim, int ¤t_lo current_lod_max_dim = height; } #if GL_APPLE_copy_texture_levels && GL_EXT_texture_storage - if(target == GL_TEXTURE_2D && width <= prev_lod_max_dim && height <= prev_lod_max_dim) { + if(target == GL_TEXTURE_2D && width <= m_current_lod_max_dim && height <= m_current_lod_max_dim) { //GLDEBUG(glCompressedTexImage2D(target, i, m_internalFormat, width, height, 0, block.length, NULL)); // Allocate, but don't copy // GLDEBUG(glTexImage2D(target, 0, GL_RGBA, width, height, 0, GL_BGRA, GL_UNSIGNED_BYTE, NULL)); GLDEBUG(glCopyTextureLevelsAPPLE(m_iNewHandle, m_iHandle, source_level, 1)); @@ -273,7 +273,7 @@ bool KRTexturePVR::uploadTexture(GLenum target, int lod_max_dim, int ¤t_lo destination_level++; } - if(width <= prev_lod_max_dim && height <= prev_lod_max_dim) { + if(width <= m_current_lod_max_dim && height <= m_current_lod_max_dim) { source_level++; } diff --git a/KREngine/kraken/KRTexturePVR.h b/KREngine/kraken/KRTexturePVR.h index ea15878..0914960 100644 --- a/KREngine/kraken/KRTexturePVR.h +++ b/KREngine/kraken/KRTexturePVR.h @@ -18,7 +18,7 @@ public: virtual ~KRTexturePVR(); virtual std::string getExtension(); - bool uploadTexture(GLenum target, int lod_max_dim, int ¤t_lod_max_dim, int prev_lod_max_dim, bool compress = false); + bool uploadTexture(GLenum target, int lod_max_dim, int ¤t_lod_max_dim, bool compress = false, bool premultiply_alpha = false); virtual long getMemRequiredForSize(int max_dim); diff --git a/KREngine/kraken/KRTextureTGA.cpp b/KREngine/kraken/KRTextureTGA.cpp index 3451117..e7f1d3c 100644 --- a/KREngine/kraken/KRTextureTGA.cpp +++ b/KREngine/kraken/KRTextureTGA.cpp @@ -36,6 +36,7 @@ KRTextureTGA::KRTextureTGA(KRContext &context, KRDataBlock *data, std::string na m_min_lod_max_dim = m_max_lod_max_dim; // Mipmaps not yet supported for TGA images switch(pHeader->imagetype) { case 2: // rgb + case 10: // rgb + rle switch(pHeader->bitsperpixel) { case 24: { @@ -70,21 +71,26 @@ KRTextureTGA::~KRTextureTGA() } -bool KRTextureTGA::uploadTexture(GLenum target, int lod_max_dim, int ¤t_lod_max_dim, int prev_lod_max_dim, bool compress) +bool KRTextureTGA::uploadTexture(GLenum target, int lod_max_dim, int ¤t_lod_max_dim, bool compress, bool premultiply_alpha) { m_pData->lock(); TGA_HEADER *pHeader = (TGA_HEADER *)m_pData->getStart(); unsigned char *pData = (unsigned char *)pHeader + (long)pHeader->idlength + (long)pHeader->colourmaplength * (long)pHeader->colourmaptype + sizeof(TGA_HEADER); - - + +#if TARGET_OS_IPHONE + GLenum base_internal_format = GL_BGRA; +#else GLenum base_internal_format = pHeader->bitsperpixel == 24 ? GL_BGR : GL_BGRA; +#endif - GLenum internal_format = 0; + GLenum internal_format = GL_RGBA; + +#if !TARGET_OS_IPHONE if(compress) { internal_format = pHeader->bitsperpixel == 24 ? GL_COMPRESSED_RGB_S3TC_DXT1_EXT : GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; } +#endif - if(pHeader->colourmaptype != 0) { m_pData->unlock(); return false; // Mapped colors not supported @@ -113,25 +119,40 @@ bool KRTextureTGA::uploadTexture(GLenum target, int lod_max_dim, int ¤t_lo *pDest++ = 0xff; pSource += 3; } + assert(pSource <= m_pData->getEnd()); //#endif - glTexImage2D(target, 0, internal_format, pHeader->width, pHeader->height, 0, GL_BGRA, GL_UNSIGNED_BYTE, (GLvoid *)converted_image); + GLDEBUG(glTexImage2D(target, 0, internal_format, pHeader->width, pHeader->height, 0, GL_BGRA, GL_UNSIGNED_BYTE, (GLvoid *)converted_image)); + GLDEBUG(glFinish()); free(converted_image); - err = glGetError(); - if (err != GL_NO_ERROR) { - m_pData->unlock(); - return false; - } + current_lod_max_dim = m_max_lod_max_dim; } break; case 32: { - glTexImage2D(target, 0, internal_format, pHeader->width, pHeader->height, 0, GL_BGRA, GL_UNSIGNED_BYTE, (GLvoid *)pData); - err = glGetError(); - if (err != GL_NO_ERROR) { - m_pData->unlock(); - return false; + if(premultiply_alpha) { + unsigned char *converted_image = (unsigned char *)malloc(pHeader->width * pHeader->height * 4); + + unsigned char *pSource = pData; + unsigned char *pDest = converted_image; + unsigned char *pEnd = pData + pHeader->height * pHeader->width * 3; + while(pSource < pEnd) { + *pDest++ = (__uint32_t)pSource[0] * (__uint32_t)pSource[3] / 0xff; + *pDest++ = (__uint32_t)pSource[1] * (__uint32_t)pSource[3] / 0xff; + *pDest++ = (__uint32_t)pSource[2] * (__uint32_t)pSource[3] / 0xff; + *pDest++ = pSource[3]; + pSource += 4; + } + assert(pSource <= m_pData->getEnd()); + + GLDEBUG(glTexImage2D(target, 0, internal_format, pHeader->width, pHeader->height, 0, GL_BGRA, GL_UNSIGNED_BYTE, (GLvoid *)converted_image)); + GLDEBUG(glFinish()); + free(converted_image); + } else { + GLDEBUG(glTexImage2D(target, 0, internal_format, pHeader->width, pHeader->height, 0, GL_BGRA, GL_UNSIGNED_BYTE, (GLvoid *)pData)); + GLDEBUG(glFinish()); } + current_lod_max_dim = m_max_lod_max_dim; } break; @@ -140,6 +161,118 @@ bool KRTextureTGA::uploadTexture(GLenum target, int lod_max_dim, int ¤t_lo return false; // 16-bit images not yet supported } break; + case 10: // rgb + rle + switch(pHeader->bitsperpixel) { + case 32: + { + unsigned char *converted_image = (unsigned char *)malloc(pHeader->width * pHeader->height * 4); + unsigned char *pSource = pData; + unsigned char *pDest = converted_image; + unsigned char *pEnd = converted_image + pHeader->height * pHeader->width * 4; + if(premultiply_alpha) { + while(pDest < pEnd) { + int count = (*pSource & 0x7f) + 1; + if(*pSource & 0x80) { + // RLE Packet + pSource++; + while(count--) { + *pDest++ = (__uint32_t)pSource[0] * (__uint32_t)pSource[3] / 0xff; + *pDest++ = (__uint32_t)pSource[1] * (__uint32_t)pSource[3] / 0xff; + *pDest++ = (__uint32_t)pSource[2] * (__uint32_t)pSource[3] / 0xff; + *pDest++ = pSource[3]; + } + pSource += 4; + } else { + // RAW Packet + pSource++; + while(count--) { + *pDest++ = (__uint32_t)pSource[0] * (__uint32_t)pSource[3] / 0xff; + *pDest++ = (__uint32_t)pSource[1] * (__uint32_t)pSource[3] / 0xff; + *pDest++ = (__uint32_t)pSource[2] * (__uint32_t)pSource[3] / 0xff; + *pDest++ = pSource[3]; + pSource += 4; + } + } + } + assert(pSource <= m_pData->getEnd()); + assert(pDest == pEnd); + } else { + while(pDest < pEnd) { + int count = (*pSource & 0x7f) + 1; + if(*pSource & 0x80) { + // RLE Packet + pSource++; + while(count--) { + *pDest++ = pSource[0]; + *pDest++ = pSource[1]; + *pDest++ = pSource[2]; + *pDest++ = pSource[3]; + } + pSource += 4; + } else { + // RAW Packet + pSource++; + while(count--) { + *pDest++ = pSource[0]; + *pDest++ = pSource[1]; + *pDest++ = pSource[2]; + *pDest++ = pSource[3]; + pSource += 4; + } + } + } + assert(pSource <= m_pData->getEnd()); + assert(pDest == pEnd); + } + GLDEBUG(glTexImage2D(target, 0, internal_format, pHeader->width, pHeader->height, 0, GL_BGRA, GL_UNSIGNED_BYTE, (GLvoid *)converted_image)); + GLDEBUG(glFinish()); + free(converted_image); + current_lod_max_dim = m_max_lod_max_dim; + } + break; + case 24: + { + unsigned char *converted_image = (unsigned char *)malloc(pHeader->width * pHeader->height * 4); + unsigned char *pSource = pData; + unsigned char *pDest = converted_image; + unsigned char *pEnd = converted_image + pHeader->height * pHeader->width * 4; + while(pDest < pEnd) { + int count = (*pSource & 0x7f) + 1; + if(*pSource & 0x80) { + // RLE Packet + pSource++; + while(count--) { + *pDest++ = pSource[0]; + *pDest++ = pSource[1]; + *pDest++ = pSource[2]; + *pDest++ = 0xff; + } + pSource += 3; + } else { + // RAW Packet + pSource++; + while(count--) { + *pDest++ = pSource[0]; + *pDest++ = pSource[1]; + *pDest++ = pSource[2]; + *pDest++ = 0xff; + pSource += 3; + } + } + } + assert(pSource <= m_pData->getEnd()); + assert(pDest == pEnd); + GLDEBUG(glTexImage2D(target, 0, internal_format, pHeader->width, pHeader->height, 0, GL_BGRA, GL_UNSIGNED_BYTE, (GLvoid *)converted_image)); + GLDEBUG(glFinish()); + free(converted_image); + current_lod_max_dim = m_max_lod_max_dim; + } + break; + default: + m_pData->unlock(); + return false; // 16-bit images not yet supported + } + break; default: m_pData->unlock(); return false; // Image type not yet supported @@ -149,7 +282,9 @@ bool KRTextureTGA::uploadTexture(GLenum target, int lod_max_dim, int ¤t_lo return true; } -KRTexture *KRTextureTGA::compress() +#if !TARGET_OS_IPHONE + +KRTexture *KRTextureTGA::compress(bool premultiply_alpha) { m_pData->lock(); @@ -163,17 +298,24 @@ KRTexture *KRTextureTGA::compress() GLDEBUG(glBindTexture(GL_TEXTURE_2D, compressed_handle)); int current_max_dim = 0; - if(!uploadTexture(GL_TEXTURE_2D, m_max_lod_max_dim, current_max_dim, 0, true)) { + if(!uploadTexture(GL_TEXTURE_2D, m_max_lod_max_dim, current_max_dim, true, premultiply_alpha)) { assert(false); // Failed to upload the texture } GLDEBUG(glGenerateMipmap(GL_TEXTURE_2D)); GLint width = 0, height = 0, internal_format, base_internal_format; - + + GLDEBUG(glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &width)); GLDEBUG(glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &height)); GLDEBUG(glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_INTERNAL_FORMAT, &internal_format)); + /* + int texture_base_level = 0; + int texture_max_level = 0; + GLDEBUG(glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_MIN_LOD, &texture_base_level)); + GLDEBUG(glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD, &texture_max_level)); + */ switch(internal_format) { case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: @@ -186,39 +328,30 @@ KRTexture *KRTextureTGA::compress() assert(false); // Not yet supported break; } - GLuint lod_level = 0; GLint compressed_size = 0; - GLenum err = GL_NO_ERROR; - while(err == GL_NO_ERROR) { - glGetTexLevelParameteriv(GL_TEXTURE_2D, lod_level, GL_TEXTURE_COMPRESSED_IMAGE_SIZE, &compressed_size); - err = glGetError(); - if(err == GL_NO_ERROR) { - KRDataBlock *new_block = new KRDataBlock(); - new_block->expand(compressed_size); - new_block->lock(); - GLDEBUG(glGetCompressedTexImage(GL_TEXTURE_2D, lod_level, new_block->getStart())); - new_block->unlock(); - blocks.push_back(new_block); - - lod_level++; - } + int lod_width = width; + while(lod_width > 1) { + GLDEBUG(glGetTexLevelParameteriv(GL_TEXTURE_2D, lod_level, GL_TEXTURE_WIDTH, &lod_width)); + GLDEBUG(glGetTexLevelParameteriv(GL_TEXTURE_2D, lod_level, GL_TEXTURE_COMPRESSED_IMAGE_SIZE, &compressed_size)); + KRDataBlock *new_block = new KRDataBlock(); + new_block->expand(compressed_size); + new_block->lock(); + GLDEBUG(glGetCompressedTexImage(GL_TEXTURE_2D, lod_level, new_block->getStart())); + new_block->unlock(); + blocks.push_back(new_block); + + lod_level++; } - if(err != GL_INVALID_VALUE) { - // err will equal GL_INVALID_VALUE when - // assert(false); // Unexpected error - } - + assert(lod_width == 1); GLDEBUG(glBindTexture(GL_TEXTURE_2D, 0)); - getContext().getTextureManager()->selectTexture(0, NULL); + getContext().getTextureManager()->selectTexture(0, NULL, 0.0f, KRTexture::TEXTURE_USAGE_NONE); GLDEBUG(glDeleteTextures(1, &compressed_handle)); KRTextureKTX *new_texture = new KRTextureKTX(getContext(), getName(), internal_format, base_internal_format, width, height, blocks); - KRResource *test_resource = new_texture; - m_pData->unlock(); for(auto block_itr = blocks.begin(); block_itr != blocks.end(); block_itr++) { @@ -228,6 +361,7 @@ KRTexture *KRTextureTGA::compress() return new_texture; } +#endif long KRTextureTGA::getMemRequiredForSize(int max_dim) { diff --git a/KREngine/kraken/KRTextureTGA.h b/KREngine/kraken/KRTextureTGA.h index 34edb9d..18e992a 100644 --- a/KREngine/kraken/KRTextureTGA.h +++ b/KREngine/kraken/KRTextureTGA.h @@ -18,8 +18,11 @@ public: virtual ~KRTextureTGA(); virtual std::string getExtension(); - bool uploadTexture(GLenum target, int lod_max_dim, int ¤t_lod_max_dim, int prev_lod_max_dim, bool compress = false); - virtual KRTexture *compress(); + bool uploadTexture(GLenum target, int lod_max_dim, int ¤t_lod_max_dim, bool compress = false, bool premultiply_alpha = false); + +#if !TARGET_OS_IPHONE + virtual KRTexture *compress(bool premultiply_alpha = false); +#endif virtual long getMemRequiredForSize(int max_dim); private: diff --git a/KREngine/kraken/KRTriangle3.cpp b/KREngine/kraken/KRTriangle3.cpp new file mode 100644 index 0000000..c60c764 --- /dev/null +++ b/KREngine/kraken/KRTriangle3.cpp @@ -0,0 +1,327 @@ +// +// KRTriangle.cpp +// Kraken +// +// Created by Kearwood Gilbert on 2/8/2014. +// Copyright (c) 2014 Kearwood Software. All rights reserved. +// + +#include "KRTriangle3.h" +#include "KRVector3.h" + +KRTriangle3::KRTriangle3(const KRVector3 &v1, const KRVector3 &v2, const KRVector3 &v3) +{ + m_c[0] = v1; + m_c[1] = v2; + m_c[2] = v3; +} + +KRTriangle3::KRTriangle3(const KRTriangle3 &tri) +{ + m_c[0] = tri[0]; + m_c[1] = tri[1]; + m_c[3] = tri[3]; +} + + +KRTriangle3::~KRTriangle3() +{ + +} + +bool KRTriangle3::operator ==(const KRTriangle3& b) const +{ + return m_c[0] == b[0] && m_c[1] == b[1] && m_c[2] == b[2]; +} + +bool KRTriangle3::operator !=(const KRTriangle3& b) const +{ + return m_c[0] != b[0] || m_c[1] != b[1] || m_c[2] != b[2]; +} + +KRTriangle3& KRTriangle3::operator =(const KRTriangle3& b) +{ + + m_c[0] = b[0]; + m_c[1] = b[1]; + m_c[3] = b[3]; + return *this; +} + +KRVector3& KRTriangle3::operator[](unsigned i) +{ + return m_c[i]; +} + +KRVector3 KRTriangle3::operator[](unsigned i) const +{ + return m_c[i]; +} + + +bool KRTriangle3::rayCast(const KRVector3 &start, const KRVector3 &dir, KRVector3 &hit_point) const +{ + // algorithm based on Dan Sunday's implementation at http://geomalgorithms.com/a06-_intersect-2.html + const float SMALL_NUM = 0.00000001; // anything that avoids division overflow + KRVector3 u, v, n; // triangle vectors + KRVector3 w0, w; // ray vectors + float r, a, b; // params to calc ray-plane intersect + + // get triangle edge vectors and plane normal + u = m_c[1] - m_c[0]; + v = m_c[2] - m_c[0]; + n = KRVector3::Cross(u, v); // cross product + if (n == KRVector3::Zero()) // triangle is degenerate + return false; // do not deal with this case + + w0 = start - m_c[0]; + a = -KRVector3::Dot(n, w0); + b = KRVector3::Dot(n,dir); + if (fabs(b) < SMALL_NUM) { // ray is parallel to triangle plane + if (a == 0) + return false; // ray lies in triangle plane + else { + return false; // ray disjoint from plane + } + } + + // get intersect point of ray with triangle plane + r = a / b; + if (r < 0.0) // ray goes away from triangle + return false; // => no intersect + // for a segment, also test if (r > 1.0) => no intersect + + + KRVector3 plane_hit_point = start + dir * r; // intersect point of ray and plane + + // is plane_hit_point inside triangle? + float uu, uv, vv, wu, wv, D; + uu = KRVector3::Dot(u,u); + uv = KRVector3::Dot(u,v); + vv = KRVector3::Dot(v,v); + w = plane_hit_point - m_c[0]; + wu = KRVector3::Dot(w,u); + wv = KRVector3::Dot(w,v); + D = uv * uv - uu * vv; + + // get and test parametric coords + float s, t; + s = (uv * wv - vv * wu) / D; + if (s < 0.0 || s > 1.0) // plane_hit_point is outside triangle + return false; + t = (uv * wu - uu * wv) / D; + if (t < 0.0 || (s + t) > 1.0) // plane_hit_point is outside triangle + return false; + + // plane_hit_point is inside the triangle + hit_point = plane_hit_point; + return true; +} + +KRVector3 KRTriangle3::calculateNormal() const +{ + KRVector3 v1 = m_c[1] - m_c[0]; + KRVector3 v2 = m_c[2] - m_c[0]; + + return KRVector3::Normalize(KRVector3::Cross(v1, v2)); +} + +bool _intersectSphere(const KRVector3 &start, const KRVector3 &dir, const KRVector3 &sphere_center, float sphere_radius, float &distance) +{ + // dir must be normalized + + // From: http://archive.gamedev.net/archive/reference/articles/article1026.html + + // TODO - Move to another class? + KRVector3 Q = sphere_center - start; + float c = Q.magnitude(); + float v = KRVector3::Dot(Q, dir); + float d = sphere_radius * sphere_radius - (c * c - v * v); + + + + if(d < 0.0) { + // No intersection + return false; + } + + // Return the distance to the [first] intersecting point + + distance = v - sqrt(d); + if(distance < 0.0f) { + return false; + } + return true; + +} + +bool _sameSide(const KRVector3 &p1, const KRVector3 &p2, const KRVector3 &a, const KRVector3 &b) +{ + // TODO - Move to KRVector3 class? + // From: http://stackoverflow.com/questions/995445/determine-if-a-3d-point-is-within-a-triangle + + KRVector3 cp1 = KRVector3::Cross(b - a, p1 - a); + KRVector3 cp2 = KRVector3::Cross(b - a, p2 - a); + if(KRVector3::Dot(cp1, cp2) >= 0) return true; + return false; +} + +KRVector3 _closestPointOnLine(const KRVector3 &a, const KRVector3 &b, const KRVector3 &p) +{ + // From: http://stackoverflow.com/questions/995445/determine-if-a-3d-point-is-within-a-triangle + + // Determine t (the length of the vector from ‘a’ to ‘p’) + + KRVector3 c = p - a; + KRVector3 V = KRVector3::Normalize(b - a); + float d = (a - b).magnitude(); + float t = KRVector3::Dot(V, c); + + // Check to see if ‘t’ is beyond the extents of the line segment + + if (t < 0) return a; + if (t > d) return b; + + // Return the point between ‘a’ and ‘b’ + + return a + V * t; +} + +KRVector3 KRTriangle3::closestPointOnTriangle(const KRVector3 &p) const +{ + KRVector3 a = m_c[0]; + KRVector3 b = m_c[1]; + KRVector3 c = m_c[2]; + + KRVector3 Rab = _closestPointOnLine(a, b, p); + KRVector3 Rbc = _closestPointOnLine(b, c, p); + KRVector3 Rca = _closestPointOnLine(c, a, p); + + // return closest [Rab, Rbc, Rca] to p; + float sd_Rab = (p - Rab).sqrMagnitude(); + float sd_Rbc = (p - Rbc).sqrMagnitude(); + float sd_Rca = (p - Rca).sqrMagnitude(); + + if(sd_Rab < sd_Rbc && sd_Rab < sd_Rca) { + return Rab; + } else if(sd_Rbc < sd_Rab && sd_Rbc < sd_Rca) { + return Rbc; + } else { + return Rca; + } +} + +bool KRTriangle3::sphereCast(const KRVector3 &start, const KRVector3 &dir, float radius, KRVector3 &hit_point, float &hit_distance) const +{ + // Dir must be normalized + const float SMALL_NUM = 0.001f; // anything that avoids division overflow + + KRVector3 tri_normal = calculateNormal(); + + float d = KRVector3::Dot(tri_normal, m_c[0]); + float e = KRVector3::Dot(tri_normal, start) - radius; + float cotangent_distance = e - d; + + KRVector3 plane_intersect; + float plane_intersect_distance; + + float denom = KRVector3::Dot(tri_normal, dir); + + if(denom > -SMALL_NUM) { + return false; // dir is co-planar with the triangle or going in the direction of the normal; no intersection + } + + // Detect an embedded plane, caused by a sphere that is already intersecting the plane. + if(cotangent_distance <= 0 && cotangent_distance >= -radius * 2.0f) { + // Embedded plane - Sphere is already intersecting the plane. + // Use the point closest to the origin of the sphere as the intersection + plane_intersect = start - tri_normal * (cotangent_distance + radius); + plane_intersect_distance = 0.0f; + } else { + // Sphere is not intersecting the plane + // Determine the first point hit by the swept sphere on the triangle's plane + + plane_intersect_distance = -(cotangent_distance / denom); + plane_intersect = start + dir * plane_intersect_distance - tri_normal * radius; + } + + if(plane_intersect_distance < 0.0f) { + return false; + } + + if(containsPoint(plane_intersect)) { + // Triangle contains point + hit_point = plane_intersect; + hit_distance = plane_intersect_distance; + return true; + } else { + // Triangle does not contain point, cast ray back to sphere from closest point on triangle edge or vertice + KRVector3 closest_point = closestPointOnTriangle(plane_intersect); + float reverse_hit_distance; + if(_intersectSphere(closest_point, -dir, start, radius, reverse_hit_distance)) { + // Reverse cast hit sphere + hit_distance = reverse_hit_distance; + hit_point = closest_point; + return true; + } else { + // Reverse cast did not hit sphere + return false; + } + } +} + + +bool KRTriangle3::containsPoint(const KRVector3 &p) const +{ + /* + // From: http://stackoverflow.com/questions/995445/determine-if-a-3d-point-is-within-a-triangle + + const float SMALL_NUM = 0.00000001f; // anything that avoids division overflow + // KRVector3 A = m_c[0], B = m_c[1], C = m_c[2]; + if (_sameSide(p, m_c[0], m_c[1], m_c[2]) && _sameSide(p, m_c[1], m_c[0], m_c[2]) && _sameSide(p, m_c[2], m_c[0], m_c[1])) { + KRVector3 vc1 = KRVector3::Cross(m_c[0] - m_c[1], m_c[0] - m_c[2]); + if(fabs(KRVector3::Dot(m_c[0] - p, vc1)) <= SMALL_NUM) { + return true; + } + } + + return false; + */ + + // From: http://blogs.msdn.com/b/rezanour/archive/2011/08/07/barycentric-coordinates-and-point-in-triangle-tests.aspx + + KRVector3 A = m_c[0]; + KRVector3 B = m_c[1]; + KRVector3 C = m_c[2]; + KRVector3 P = p; + + // Prepare our barycentric variables + KRVector3 u = B - A; + KRVector3 v = C - A; + KRVector3 w = P - A; + + KRVector3 vCrossW = KRVector3::Cross(v, w); + KRVector3 vCrossU = KRVector3::Cross(v, u); + + // Test sign of r + if (KRVector3::Dot(vCrossW, vCrossU) < 0) + return false; + + KRVector3 uCrossW = KRVector3::Cross(u, w); + KRVector3 uCrossV = KRVector3::Cross(u, v); + + // Test sign of t + if (KRVector3::Dot(uCrossW, uCrossV) < 0) + return false; + + // At this point, we know that r and t and both > 0. + // Therefore, as long as their sum is <= 1, each must be less <= 1 + float denom = uCrossV.magnitude(); + float r = vCrossW.magnitude() / denom; + float t = uCrossW.magnitude() / denom; + + return (r + t <= 1); +} + + + diff --git a/KREngine/kraken/KRMeshStreamer.h b/KREngine/kraken/KRTriangle3.h similarity index 64% rename from KREngine/kraken/KRMeshStreamer.h rename to KREngine/kraken/KRTriangle3.h index beb3666..25ade3e 100644 --- a/KREngine/kraken/KRMeshStreamer.h +++ b/KREngine/kraken/KRTriangle3.h @@ -1,5 +1,5 @@ // -// KRMeshManager.h +// KRTriangle.h // KREngine // // Copyright 2012 Kearwood Gilbert. All rights reserved. @@ -29,32 +29,35 @@ // or implied, of Kearwood Gilbert. // -#ifndef KRMESHSTREAMER_H -#define KRMESHSTREAMER_H +#ifndef KRTRIANGLE3_H +#define KRTRIANGLE3_H -#include "KREngine-common.h" +#include "KRVector3.h" -#include -#include - -class KRContext; - -class KRMeshStreamer +class KRTriangle3 { public: - KRMeshStreamer(KRContext &context); - ~KRMeshStreamer(); + KRTriangle3(const KRTriangle3 &tri); + KRTriangle3(const KRVector3 &v1, const KRVector3 &v2, const KRVector3 &v3); + ~KRTriangle3(); - void startStreamer(); + KRVector3 calculateNormal() const; + bool operator ==(const KRTriangle3& b) const; + bool operator !=(const KRTriangle3& b) const; + KRTriangle3& operator =(const KRTriangle3& b); + KRVector3& operator[](unsigned i); + KRVector3 operator[](unsigned i) const; + + + bool rayCast(const KRVector3 &start, const KRVector3 &dir, KRVector3 &hit_point) const; + bool sphereCast(const KRVector3 &start, const KRVector3 &dir, float radius, KRVector3 &hit_point, float &hit_distance) const; + + bool containsPoint(const KRVector3 &p) const; + KRVector3 closestPointOnTriangle(const KRVector3 &p) const; private: - KRContext &m_context; - std::thread m_thread; - std::atomic m_stop; - std::atomic m_running; - - void run(); + KRVector3 m_c[3]; }; -#endif /* defined(KRMESHSTREAMER_H) */ +#endif // KRTRIANGLE3_H diff --git a/KREngine/kraken/KRVector2.cpp b/KREngine/kraken/KRVector2.cpp index 27f675e..6219db4 100644 --- a/KREngine/kraken/KRVector2.cpp +++ b/KREngine/kraken/KRVector2.cpp @@ -35,6 +35,20 @@ KRVector2::KRVector2(const KRVector2 &v) { y = v.y; } + +// KRVector2 swizzle getters +KRVector2 KRVector2::yx() const +{ + return KRVector2(y,x); +} + +// KRVector2 swizzle setters +void KRVector2::yx(const KRVector2 &v) +{ + y = v.x; + x = v.y; +} + KRVector2 KRVector2::Min() { return KRVector2(-std::numeric_limits::max()); } diff --git a/KREngine/kraken/KRVector2.h b/KREngine/kraken/KRVector2.h index ded1071..397833e 100644 --- a/KREngine/kraken/KRVector2.h +++ b/KREngine/kraken/KRVector2.h @@ -51,6 +51,12 @@ public: KRVector2(const KRVector2 &v); ~KRVector2(); + // KRVector2 swizzle getters + KRVector2 yx() const; + + // KRVector2 swizzle setters + void yx(const KRVector2 &v); + KRVector2& operator =(const KRVector2& b); KRVector2 operator +(const KRVector2& b) const; KRVector2 operator -(const KRVector2& b) const; diff --git a/KREngine/kraken/KRVector3.cpp b/KREngine/kraken/KRVector3.cpp index 6505716..9074b68 100644 --- a/KREngine/kraken/KRVector3.cpp +++ b/KREngine/kraken/KRVector3.cpp @@ -65,6 +65,87 @@ KRVector3::KRVector3(double *v) { z = (float)v[2]; } +KRVector2 KRVector3::xx() const +{ + return KRVector2(x,x); +} + +KRVector2 KRVector3::xy() const +{ + return KRVector2(x,y); +} + +KRVector2 KRVector3::xz() const +{ + return KRVector2(x,z); +} + +KRVector2 KRVector3::yx() const +{ + return KRVector2(y,x); +} + +KRVector2 KRVector3::yy() const +{ + return KRVector2(y,y); +} + +KRVector2 KRVector3::yz() const +{ + return KRVector2(y,z); +} + +KRVector2 KRVector3::zx() const +{ + return KRVector2(z,x); +} + +KRVector2 KRVector3::zy() const +{ + return KRVector2(z,y); +} + +KRVector2 KRVector3::zz() const +{ + return KRVector2(z,z); +} + +void KRVector3::xy(const KRVector2 &v) +{ + x = v.x; + y = v.y; +} + +void KRVector3::xz(const KRVector2 &v) +{ + x = v.x; + z = v.y; +} + +void KRVector3::yx(const KRVector2 &v) +{ + y = v.x; + x = v.y; +} + +void KRVector3::yz(const KRVector2 &v) +{ + y = v.x; + z = v.y; +} + +void KRVector3::zx(const KRVector2 &v) +{ + z = v.x; + x = v.y; +} + +void KRVector3::zy(const KRVector2 &v) +{ + z = v.x; + y = v.y; +} + KRVector3 KRVector3::Min() { return KRVector3(-std::numeric_limits::max()); } @@ -336,13 +417,15 @@ void KRVector3::setUniform(GLint location) const if(location != -1) GLDEBUG(glUniform3f(location, x, y, z)); } -void KRVector3::setXMLAttribute(const std::string &base_name, tinyxml2::XMLElement *e) +void KRVector3::setXMLAttribute(const std::string &base_name, tinyxml2::XMLElement *e, const KRVector3 &default_value) { // TODO - Increase number of digits after the decimal in floating point format (6 -> 12?) // FINDME, TODO - This needs optimization... - e->SetAttribute((base_name + "_x").c_str(), x); - e->SetAttribute((base_name + "_y").c_str(), y); - e->SetAttribute((base_name + "_z").c_str(), z); + if(*this != default_value) { + e->SetAttribute((base_name + "_x").c_str(), x); + e->SetAttribute((base_name + "_y").c_str(), y); + e->SetAttribute((base_name + "_z").c_str(), z); + } } void KRVector3::getXMLAttribute(const std::string &base_name, tinyxml2::XMLElement *e, const KRVector3 &default_value) diff --git a/KREngine/kraken/KRVector3.h b/KREngine/kraken/KRVector3.h index dc14294..072843e 100644 --- a/KREngine/kraken/KRVector3.h +++ b/KREngine/kraken/KRVector3.h @@ -34,7 +34,7 @@ #include "KREngine-common.h" - +class KRVector2; class KRVector4; class KRVector3 { @@ -56,6 +56,24 @@ public: KRVector3(const KRVector4 &v); ~KRVector3(); + // KRVector2 swizzle getters + KRVector2 xx() const; + KRVector2 xy() const; + KRVector2 xz() const; + KRVector2 yx() const; + KRVector2 yy() const; + KRVector2 yz() const; + KRVector2 zx() const; + KRVector2 zy() const; + KRVector2 zz() const; + + // KRVector2 swizzle setters + void xy(const KRVector2 &v); + void xz(const KRVector2 &v); + void yx(const KRVector2 &v); + void yz(const KRVector2 &v); + void zx(const KRVector2 &v); + void zy(const KRVector2 &v); KRVector3& operator =(const KRVector3& b); KRVector3& operator =(const KRVector4& b); @@ -108,7 +126,7 @@ public: void setUniform(GLint location) const; - void setXMLAttribute(const std::string &base_name, tinyxml2::XMLElement *e); + void setXMLAttribute(const std::string &base_name, tinyxml2::XMLElement *e, const KRVector3 &default_value); void getXMLAttribute(const std::string &base_name, tinyxml2::XMLElement *e, const KRVector3 &default_value); }; diff --git a/KREngine/kraken/KRViewport.cpp b/KREngine/kraken/KRViewport.cpp index 6dbd0e9..4a98772 100644 --- a/KREngine/kraken/KRViewport.cpp +++ b/KREngine/kraken/KRViewport.cpp @@ -176,16 +176,25 @@ float KRViewport::coverage(const KRAABB &b) const if(!visible(b)) { return 0.0f; // Culled out by view frustrum } else { + KRVector3 nearest_point = b.nearestPoint(getCameraPosition()); + float distance = (nearest_point - getCameraPosition()).magnitude(); + + KRVector3 v = KRMat4::DotWDiv(m_matProjection, getCameraPosition() + getCameraDirection() * distance); + + float screen_depth = distance / 1000.0f; + + return KRCLAMP(1.0f - screen_depth, 0.01f, 1.0f); + + /* + KRVector2 screen_min; KRVector2 screen_max; // Loop through all corners and transform them to screen space for(int i=0; i<8; i++) { KRVector3 screen_pos = KRMat4::DotWDiv(m_matViewProjection, KRVector3(i & 1 ? b.min.x : b.max.x, i & 2 ? b.min.y : b.max.y, i & 4 ? b.min.z : b.max.z)); if(i==0) { - screen_min.x = screen_pos.x; - screen_min.y = screen_pos.y; - screen_max.x = screen_pos.x; - screen_max.y = screen_pos.y; + screen_min = screen_pos.xy(); + screen_max = screen_pos.xy(); } else { if(screen_pos.x < screen_min.x) screen_min.x = screen_pos.x; if(screen_pos.y < screen_min.y) screen_min.y = screen_pos.y; @@ -194,7 +203,14 @@ float KRViewport::coverage(const KRAABB &b) const } } - return (screen_max.x - screen_min.x) * (screen_max.y - screen_min.y); + screen_min.x = KRCLAMP(screen_min.x, 0.0f, 1.0f); + screen_min.y = KRCLAMP(screen_min.y, 0.0f, 1.0f); + screen_max.x = KRCLAMP(screen_max.x, 0.0f, 1.0f); + screen_max.y = KRCLAMP(screen_max.y, 0.0f, 1.0f); + + float c = (screen_max.x - screen_min.x) * (screen_max.y - screen_min.y); + return KRCLAMP(c, 0.01f, 1.0f); + */ } } diff --git a/KREngine/kraken_standard_assets_ios/Shaders/ObjectShader.fsh b/KREngine/kraken_standard_assets_ios/Shaders/ObjectShader.fsh index 625f602..62edf5a 100644 --- a/KREngine/kraken_standard_assets_ios/Shaders/ObjectShader.fsh +++ b/KREngine/kraken_standard_assets_ios/Shaders/ObjectShader.fsh @@ -372,9 +372,9 @@ void main() mediump vec3 reflectionVec = mat3(model_matrix) * (incidenceVec - 2.0 * dot(world_space_normal, incidenceVec) * world_space_normal); #endif #if HAS_REFLECTION_MAP == 1 - gl_FragColor += vec4(material_reflection, 0.0) * texture2D(reflectionTexture, reflection_uv) * textureCube(reflectionCubeTexture, reflectionVec); + gl_FragColor += vec4(material_reflection, 0.0) * texture2D(reflectionTexture, reflection_uv) * vec4(textureCube(reflectionCubeTexture, reflectionVec).rgb, 1.0); #else - gl_FragColor += vec4(material_reflection, 0.0) * textureCube(reflectionCubeTexture, reflectionVec); + gl_FragColor += vec4(material_reflection, 0.0) * vec4(textureCube(reflectionCubeTexture, reflectionVec).rgb, 1.0); #endif #endif diff --git a/KREngine/kraken_standard_assets_ios/Shaders/PostShader.vsh b/KREngine/kraken_standard_assets_ios/Shaders/PostShader.vsh index 58b3827..c147629 100644 --- a/KREngine/kraken_standard_assets_ios/Shaders/PostShader.vsh +++ b/KREngine/kraken_standard_assets_ios/Shaders/PostShader.vsh @@ -25,6 +25,7 @@ // or implied, of Kearwood Gilbert. // +uniform mediump vec2 viewport_downsample; attribute vec4 vertex_position; attribute lowp vec4 vertex_uv; @@ -33,5 +34,5 @@ varying mediump vec2 textureCoordinate; void main() { gl_Position = vertex_position; - textureCoordinate = vertex_uv.xy; + textureCoordinate = vertex_uv.xy * viewport_downsample.xy; } \ No newline at end of file diff --git a/KREngine/kraken_standard_assets_ios/Shaders/flare.vsh b/KREngine/kraken_standard_assets_ios/Shaders/flare.vsh index fc0c4d4..b52bc75 100644 --- a/KREngine/kraken_standard_assets_ios/Shaders/flare.vsh +++ b/KREngine/kraken_standard_assets_ios/Shaders/flare.vsh @@ -38,5 +38,5 @@ varying mediump vec2 texCoord; void main() { texCoord = vertex_uv; - gl_Position = mvp_matrix * vec4(0.0, 0.0, 0.0, 1.0) + vec4(vertex_uv.x * viewport.w / viewport.z * 2.0 - 1.0, vertex_uv.y * 2.0 - 1.0, 0.0, 0.0) * flare_size; + gl_Position = mvp_matrix * vec4(0.0, 0.0, 0.0, 1.0) + vec4(vertex_uv.x * viewport.w / viewport.z * 2.0 - 0.75, vertex_uv.y * 2.0 - 1.0, 0.0, 0.0) * flare_size; } diff --git a/KREngine/kraken_standard_assets_ios/Shaders/sprite.vsh b/KREngine/kraken_standard_assets_ios/Shaders/sprite.vsh index 347191e..1e8682a 100644 --- a/KREngine/kraken_standard_assets_ios/Shaders/sprite.vsh +++ b/KREngine/kraken_standard_assets_ios/Shaders/sprite.vsh @@ -32,11 +32,10 @@ attribute mediump vec2 vertex_uv; uniform highp mat4 mvp_matrix; // mvp_matrix is the result of multiplying the model, view, and projection matrices uniform mediump vec4 viewport; -uniform mediump float flare_size; varying mediump vec2 texCoord; void main() { texCoord = vertex_uv; - gl_Position = mvp_matrix * vec4(0.0, 0.0, 0.0, 1.0) + vec4(vertex_uv.x * viewport.w / viewport.z * 2.0 - 1.0, vertex_uv.y * 2.0 - 1.0, 0.0, 0.0) * flare_size; + gl_Position = mvp_matrix * vec4(vertex_uv.x * 2.0 - 1.0, vertex_uv.y * 2.0 - 1.0, 0.0, 1.0); } diff --git a/KREngine/kraken_standard_assets_osx/Shaders/ObjectShader_osx.fsh b/KREngine/kraken_standard_assets_osx/Shaders/ObjectShader_osx.fsh index 7160dbb..6c5fd23 100644 --- a/KREngine/kraken_standard_assets_osx/Shaders/ObjectShader_osx.fsh +++ b/KREngine/kraken_standard_assets_osx/Shaders/ObjectShader_osx.fsh @@ -372,9 +372,9 @@ void main() mediump vec3 reflectionVec = mat3(model_matrix) * (incidenceVec - 2.0 * dot(world_space_normal, incidenceVec) * world_space_normal); #endif #if HAS_REFLECTION_MAP == 1 - gl_FragColor += vec4(material_reflection, 0.0) * texture2D(reflectionTexture, reflection_uv) * textureCube(reflectionCubeTexture, reflectionVec); + gl_FragColor += vec4(material_reflection, 0.0) * texture2D(reflectionTexture, reflection_uv) * vec4(textureCube(reflectionCubeTexture, reflectionVec).rgb, 1.0); #else - gl_FragColor += vec4(material_reflection, 0.0) * textureCube(reflectionCubeTexture, reflectionVec); + gl_FragColor += vec4(material_reflection, 0.0) * vec4(textureCube(reflectionCubeTexture, reflectionVec).rgb, 1.0); #endif #endif diff --git a/KREngine/kraken_standard_assets_osx/Shaders/PostShader_osx.vsh b/KREngine/kraken_standard_assets_osx/Shaders/PostShader_osx.vsh index 7a4719f..c147629 100644 --- a/KREngine/kraken_standard_assets_osx/Shaders/PostShader_osx.vsh +++ b/KREngine/kraken_standard_assets_osx/Shaders/PostShader_osx.vsh @@ -25,6 +25,7 @@ // or implied, of Kearwood Gilbert. // +uniform mediump vec2 viewport_downsample; attribute vec4 vertex_position; attribute lowp vec4 vertex_uv; @@ -33,5 +34,5 @@ varying mediump vec2 textureCoordinate; void main() { gl_Position = vertex_position; - textureCoordinate = vertex_uv.xy; -} + textureCoordinate = vertex_uv.xy * viewport_downsample.xy; +} \ No newline at end of file diff --git a/KREngine/kraken_standard_assets_osx/Shaders/sky_box_osx.vsh b/KREngine/kraken_standard_assets_osx/Shaders/sky_box_osx.vsh index bccc0b9..3540e26 100644 --- a/KREngine/kraken_standard_assets_osx/Shaders/sky_box_osx.vsh +++ b/KREngine/kraken_standard_assets_osx/Shaders/sky_box_osx.vsh @@ -42,8 +42,8 @@ uniform mediump vec4 viewport; void main() { gl_Position = vec4(vertex_position.xy, 1.0, 1.0); - + vec4 t = inv_mvp_matrix_no_translate * vec4(vertex_position.xy, 1.0, 1.0); - t /= t.w; + t *= 1.0 / t.w; texCoord = vec3(t); } diff --git a/KREngine/kraken_standard_assets_osx/Shaders/sprite_osx.vsh b/KREngine/kraken_standard_assets_osx/Shaders/sprite_osx.vsh index 347191e..1e8682a 100644 --- a/KREngine/kraken_standard_assets_osx/Shaders/sprite_osx.vsh +++ b/KREngine/kraken_standard_assets_osx/Shaders/sprite_osx.vsh @@ -32,11 +32,10 @@ attribute mediump vec2 vertex_uv; uniform highp mat4 mvp_matrix; // mvp_matrix is the result of multiplying the model, view, and projection matrices uniform mediump vec4 viewport; -uniform mediump float flare_size; varying mediump vec2 texCoord; void main() { texCoord = vertex_uv; - gl_Position = mvp_matrix * vec4(0.0, 0.0, 0.0, 1.0) + vec4(vertex_uv.x * viewport.w / viewport.z * 2.0 - 1.0, vertex_uv.y * 2.0 - 1.0, 0.0, 0.0) * flare_size; + gl_Position = mvp_matrix * vec4(vertex_uv.x * 2.0 - 1.0, vertex_uv.y * 2.0 - 1.0, 0.0, 1.0); } diff --git a/krengine.xcworkspace/contents.xcworkspacedata b/krengine.xcworkspace/contents.xcworkspacedata index af61294..2fbca5d 100644 --- a/krengine.xcworkspace/contents.xcworkspacedata +++ b/krengine.xcworkspace/contents.xcworkspacedata @@ -1,9 +1,6 @@ - - @@ -13,4 +10,7 @@ + +