Merged nfb into default

This commit is contained in:
2014-05-20 23:21:30 -07:00
114 changed files with 6874 additions and 1254 deletions

1
.hgtags Normal file
View File

@@ -0,0 +1 @@
be35d62159788e03c335f8b7f3ddbde8030a3ccf Release 1.0.2

View File

@@ -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<typename T>
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;i++)
{
m_pArray[i]=original.m_pArray[i];
}
}
/*!***************************************************************************
@Function CPVRTArray
@Input pArray an ordinary array
@Input uiSize number of elements passed
@Description constructor from ordinary array.
*****************************************************************************/
CPVRTArray(const T* const pArray, const unsigned int uiSize) : m_uiSize(uiSize),
m_uiCapacity(uiSize)
{
_ASSERT(uiSize != 0);
m_pArray = new T[uiSize];
for(unsigned int i=0;i<m_uiSize;i++)
{
m_pArray[i]=pArray[i];
}
}
/*!***************************************************************************
@Function CPVRTArray
@Input uiSize initial capacity
@Input val value to populate with
@Description constructor from a capacity and initial value.
*****************************************************************************/
CPVRTArray(const unsigned int uiSize, const T& val) : m_uiSize(uiSize),
m_uiCapacity(uiSize)
{
_ASSERT(uiSize != 0);
m_pArray = new T[uiSize];
for(unsigned int uiIndex = 0; uiIndex < m_uiSize; ++uiIndex)
{
m_pArray[uiIndex] = val;
}
}
/*!***************************************************************************
@Function ~CPVRTArray
@Description Destructor.
*****************************************************************************/
virtual ~CPVRTArray()
{
if(m_pArray)
delete [] m_pArray;
}
/*!***************************************************************************
@Function Insert
@Input pos The position to insert the new element at
@Input addT The element to insert
@Return The index of the new item or -1 on failure.
@Description Inserts an element into the array, expanding it
if necessary.
*****************************************************************************/
int Insert(const unsigned int pos, const T& addT)
{
unsigned int uiIndex = pos;
if(pos >= 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<typename T2>
void Copy(const CPVRTArray<T2>& 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<T>& 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<T>& 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<class Pred>
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<typename T>
class CPVRTArrayManagedPointers : public CPVRTArray<T*>
{
public:
virtual ~CPVRTArrayManagedPointers()
{
if(this->m_pArray)
{
for(unsigned int i=0;i<this->m_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)
*****************************************************************************/

View File

@@ -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)
*****************************************************************************/

View File

@@ -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 <android/log.h>
#else
#if defined(_WIN32)
#include <windows.h>
#else
#include <stdio.h>
#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)
*****************************************************************************/

View File

@@ -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 <windows.h>
#include <crtdbg.h>
#include <tchar.h>
#endif
#if defined(UNDER_CE)
#include <windows.h>
#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 <stdlib.h>
#include <string.h>
#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 <stdio.h>
#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 <typename T>
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 <typename T>
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<unsigned char>(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)
*****************************************************************************/

View File

@@ -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 <typename KeyType, typename DataType>
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; ++i)
{
//Check if a key matches.
if (m_Keys[i]==key)
{
//If a matched key is found, return the position.
return i;
}
}
//If not found, return the number of meaningful members.
return m_uiSize;
}
/*!***********************************************************************
@Function GetDataAtIndex
@Input uiIndex
@Return Data type at the specified position.
@Description Returns a pointer to the Data at a particular index.
If the index supplied is not valid, NULL is returned
instead. Deletion of data at this pointer will lead
to undefined behaviour.
*************************************************************************/
const DataType* GetDataAtIndex(const PVRTuint32 uiIndex) const
{
if (uiIndex>=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<KeyType> m_Keys;
//Array of pointers to all the allocated data.
CPVRTArray<DataType> m_Data;
//The number of meaningful members in the map.
PVRTuint32 m_uiSize;
};
#endif // __PVRTMAP_H__
/*****************************************************************************
End of file (PVRTMap.h)
*****************************************************************************/

View File

@@ -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 <stdio.h>
#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<class InputIterator> 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<class InputIterator> 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<class InputIterator> 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<class InputIterator> 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)
*****************************************************************************/

View File

@@ -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<<ePVRTAxisX,
ePVRTOrientRight= 0,
ePVRTOrientUp = 1<<ePVRTAxisY,
ePVRTOrientDown = 0,
ePVRTOrientOut = 1<<ePVRTAxisZ,
ePVRTOrientIn = 0
};
enum EPVRTColourSpace
{
ePVRTCSpacelRGB,
ePVRTCSpacesRGB,
ePVRTCSpaceNumSpaces
};
//Compressed pixel formats
enum EPVRTPixelFormat
{
ePVRTPF_PVRTCI_2bpp_RGB,
ePVRTPF_PVRTCI_2bpp_RGBA,
ePVRTPF_PVRTCI_4bpp_RGB,
ePVRTPF_PVRTCI_4bpp_RGBA,
ePVRTPF_PVRTCII_2bpp,
ePVRTPF_PVRTCII_4bpp,
ePVRTPF_ETC1,
ePVRTPF_DXT1,
ePVRTPF_DXT2,
ePVRTPF_DXT3,
ePVRTPF_DXT4,
ePVRTPF_DXT5,
//These formats are identical to some DXT formats.
ePVRTPF_BC1 = ePVRTPF_DXT1,
ePVRTPF_BC2 = ePVRTPF_DXT3,
ePVRTPF_BC3 = ePVRTPF_DXT5,
//These are currently unsupported:
ePVRTPF_BC4,
ePVRTPF_BC5,
ePVRTPF_BC6,
ePVRTPF_BC7,
//These are supported
ePVRTPF_UYVY,
ePVRTPF_YUY2,
ePVRTPF_BW1bpp,
ePVRTPF_SharedExponentR9G9B9E5,
ePVRTPF_RGBG8888,
ePVRTPF_GRGB8888,
ePVRTPF_ETC2_RGB,
ePVRTPF_ETC2_RGBA,
ePVRTPF_ETC2_RGB_A1,
ePVRTPF_EAC_R11,
ePVRTPF_EAC_RG11,
//Invalid value
ePVRTPF_NumCompressedPFs
};
//Variable Type Names
enum EPVRTVariableType
{
ePVRTVarTypeUnsignedByteNorm,
ePVRTVarTypeSignedByteNorm,
ePVRTVarTypeUnsignedByte,
ePVRTVarTypeSignedByte,
ePVRTVarTypeUnsignedShortNorm,
ePVRTVarTypeSignedShortNorm,
ePVRTVarTypeUnsignedShort,
ePVRTVarTypeSignedShort,
ePVRTVarTypeUnsignedIntegerNorm,
ePVRTVarTypeSignedIntegerNorm,
ePVRTVarTypeUnsignedInteger,
ePVRTVarTypeSignedInteger,
ePVRTVarTypeSignedFloat, ePVRTVarTypeFloat=ePVRTVarTypeSignedFloat, //the name ePVRTVarTypeFloat is now deprecated.
ePVRTVarTypeUnsignedFloat,
ePVRTVarTypeNumVarTypes
};
//A 64 bit pixel format ID & this will give you the high bits of a pixel format to check for a compressed format.
static const PVRTuint64 PVRTEX_PFHIGHMASK=0xffffffff00000000ull;
/*****************************************************************************
* Texture header structures.
*****************************************************************************/
struct MetaDataBlock
{
PVRTuint32 DevFOURCC; //A 4cc descriptor of the data type's creator. Values equating to values between 'P' 'V' 'R' 0 and 'P' 'V' 'R' 255 will be used by our headers.
PVRTuint32 u32Key; //A DWORD (enum value) identifying the data type, and thus how to read it.
PVRTuint32 u32DataSize; //Size of the Data member.
PVRTuint8* Data; //Data array, can be absolutely anything, the loader needs to know how to handle it based on DevFOURCC and Key. Use new operator to assign to it.
/*!***********************************************************************
@Function MetaDataBlock
@Description Meta Data Block Constructor
*************************************************************************/
MetaDataBlock() : DevFOURCC(0), u32Key(0), u32DataSize(0), Data(NULL)
{}
/*!***********************************************************************
@Function MetaDataBlock
@Description Meta Data Block Copy Constructor
*************************************************************************/
MetaDataBlock(const MetaDataBlock& rhs) : DevFOURCC(rhs.DevFOURCC), u32Key(rhs.u32Key), u32DataSize(rhs.u32DataSize)
{
//Copy the data across.
Data = new PVRTuint8[u32DataSize];
for (PVRTuint32 uiDataAmt=0; uiDataAmt<u32DataSize; ++uiDataAmt)
{
Data[uiDataAmt]=rhs.Data[uiDataAmt];
}
}
/*!***********************************************************************
@Function ~MetaDataBlock
@Description Meta Data Block Destructor
*************************************************************************/
~MetaDataBlock()
{
if (Data)
delete [] Data;
Data = NULL;
}
/*!***********************************************************************
@Function SizeOfBlock
@Return size_t Size (in a file) of the block.
@Description Returns the number of extra bytes this will add to any output files.
*************************************************************************/
size_t SizeOfBlock() const
{
return sizeof(DevFOURCC)+sizeof(u32Key)+sizeof(u32DataSize)+u32DataSize;
}
/*!***********************************************************************
@Function operator=
@Return MetaDataBlock This MetaDataBlock after the operation.
@Description Assigns one MetaDataBlock to the other.
*************************************************************************/
MetaDataBlock& operator=(const MetaDataBlock& rhs)
{
if (&rhs==this)
return *this;
//Remove pre-existing data.
if (Data)
delete [] Data;
Data=NULL;
//Copy the basic parameters
DevFOURCC=rhs.DevFOURCC;
u32Key=rhs.u32Key;
u32DataSize=rhs.u32DataSize;
//Copy the data across.
if (rhs.Data)
{
Data = new PVRTuint8[u32DataSize];
for (PVRTuint32 uiDataAmt=0; uiDataAmt<u32DataSize; ++uiDataAmt)
{
Data[uiDataAmt]=rhs.Data[uiDataAmt];
}
}
return *this;
}
/*!***************************************************************************
@Function ReadFromPtr
@Input pDataCursor The data to read
@Description Reads from a pointer of memory in to the meta data block.
*****************************************************************************/
bool ReadFromPtr(const unsigned char** pDataCursor);
};
//The idea behind this is that it stores EVERYTHING that you would ever need to read a texture accurately, and nothing more.
//Extraneous data is stored in meta data. Correct use of the texture may rely on meta data, but accurate data loading can be done through the
//Standard header alone.
#pragma pack(push,4)
struct PVRTextureHeaderV3{
PVRTuint32 u32Version; //Version of the file header, used to identify it.
PVRTuint32 u32Flags; //Various format flags.
PVRTuint64 u64PixelFormat; //The pixel format, 8cc value storing the 4 channel identifiers and their respective sizes.
PVRTuint32 u32ColourSpace; //The Colour Space of the texture, currently either linear RGB or sRGB.
PVRTuint32 u32ChannelType; //Variable type that the channel is stored in. Supports signed/unsigned int/short/byte or float for now.
PVRTuint32 u32Height; //Height of the texture.
PVRTuint32 u32Width; //Width of the texture.
PVRTuint32 u32Depth; //Depth of the texture. (Z-slices)
PVRTuint32 u32NumSurfaces; //Number of members in a Texture Array.
PVRTuint32 u32NumFaces; //Number of faces in a Cube Map. Maybe be a value other than 6.
PVRTuint32 u32MIPMapCount; //Number of MIP Maps in the texture - NB: Includes top level.
PVRTuint32 u32MetaDataSize; //Size of the accompanying meta data.
//Constructor for the header - used to make sure that the header is initialised usefully. The initial pixel format is an invalid one and must be set.
PVRTextureHeaderV3() :
u32Version(PVRTEX3_IDENT),u32Flags(0),
u64PixelFormat(ePVRTPF_NumCompressedPFs),
u32ColourSpace(0),u32ChannelType(0),
u32Height(1),u32Width(1),u32Depth(1),
u32NumSurfaces(1),u32NumFaces(1),
u32MIPMapCount(1),u32MetaDataSize(0)
{}
};
#pragma pack(pop)
#define PVRTEX3_HEADERSIZE 52
/*!***************************************************************************
Describes the Version 2 header of a PVR texture header.
*****************************************************************************/
struct PVR_Texture_Header
{
PVRTuint32 dwHeaderSize; /*!< size of the structure */
PVRTuint32 dwHeight; /*!< height of surface to be created */
PVRTuint32 dwWidth; /*!< width of input surface */
PVRTuint32 dwMipMapCount; /*!< number of mip-map levels requested */
PVRTuint32 dwpfFlags; /*!< pixel format flags */
PVRTuint32 dwTextureDataSize; /*!< Total size in bytes */
PVRTuint32 dwBitCount; /*!< number of bits per pixel */
PVRTuint32 dwRBitMask; /*!< mask for red bit */
PVRTuint32 dwGBitMask; /*!< mask for green bits */
PVRTuint32 dwBBitMask; /*!< mask for blue bits */
PVRTuint32 dwAlphaBitMask; /*!< mask for alpha channel */
PVRTuint32 dwPVR; /*!< magic number identifying pvr file */
PVRTuint32 dwNumSurfs; /*!< the number of surfaces present in the pvr */
} ;
/*****************************************************************************
* Legacy (V2 and V1) ENUMS
*****************************************************************************/
enum PVRTPixelType
{
MGLPT_ARGB_4444 = 0x00,
MGLPT_ARGB_1555,
MGLPT_RGB_565,
MGLPT_RGB_555,
MGLPT_RGB_888,
MGLPT_ARGB_8888,
MGLPT_ARGB_8332,
MGLPT_I_8,
MGLPT_AI_88,
MGLPT_1_BPP,
MGLPT_VY1UY0,
MGLPT_Y1VY0U,
MGLPT_PVRTC2,
MGLPT_PVRTC4,
// OpenGL version of pixel types
OGL_RGBA_4444= 0x10,
OGL_RGBA_5551,
OGL_RGBA_8888,
OGL_RGB_565,
OGL_RGB_555,
OGL_RGB_888,
OGL_I_8,
OGL_AI_88,
OGL_PVRTC2,
OGL_PVRTC4,
OGL_BGRA_8888,
OGL_A_8,
OGL_PVRTCII4, //Not in use
OGL_PVRTCII2, //Not in use
// S3TC Encoding
D3D_DXT1 = 0x20,
D3D_DXT2,
D3D_DXT3,
D3D_DXT4,
D3D_DXT5,
//RGB Formats
D3D_RGB_332,
D3D_AL_44,
D3D_LVU_655,
D3D_XLVU_8888,
D3D_QWVU_8888,
//10 bit integer - 2 bit alpha
D3D_ABGR_2101010,
D3D_ARGB_2101010,
D3D_AWVU_2101010,
//16 bit integers
D3D_GR_1616,
D3D_VU_1616,
D3D_ABGR_16161616,
//Float Formats
D3D_R16F,
D3D_GR_1616F,
D3D_ABGR_16161616F,
//32 bits per channel
D3D_R32F,
D3D_GR_3232F,
D3D_ABGR_32323232F,
// Ericsson
ETC_RGB_4BPP,
ETC_RGBA_EXPLICIT, // unimplemented
ETC_RGBA_INTERPOLATED, // unimplemented
D3D_A8 = 0x40,
D3D_V8U8,
D3D_L16,
D3D_L8,
D3D_AL_88,
//Y'UV Colourspace
D3D_UYVY,
D3D_YUY2,
// DX10
DX10_R32G32B32A32_FLOAT= 0x50,
DX10_R32G32B32A32_UINT ,
DX10_R32G32B32A32_SINT,
DX10_R32G32B32_FLOAT,
DX10_R32G32B32_UINT,
DX10_R32G32B32_SINT,
DX10_R16G16B16A16_FLOAT ,
DX10_R16G16B16A16_UNORM,
DX10_R16G16B16A16_UINT ,
DX10_R16G16B16A16_SNORM ,
DX10_R16G16B16A16_SINT ,
DX10_R32G32_FLOAT ,
DX10_R32G32_UINT ,
DX10_R32G32_SINT ,
DX10_R10G10B10A2_UNORM ,
DX10_R10G10B10A2_UINT ,
DX10_R11G11B10_FLOAT , // unimplemented
DX10_R8G8B8A8_UNORM ,
DX10_R8G8B8A8_UNORM_SRGB ,
DX10_R8G8B8A8_UINT ,
DX10_R8G8B8A8_SNORM ,
DX10_R8G8B8A8_SINT ,
DX10_R16G16_FLOAT ,
DX10_R16G16_UNORM ,
DX10_R16G16_UINT ,
DX10_R16G16_SNORM ,
DX10_R16G16_SINT ,
DX10_R32_FLOAT ,
DX10_R32_UINT ,
DX10_R32_SINT ,
DX10_R8G8_UNORM ,
DX10_R8G8_UINT ,
DX10_R8G8_SNORM ,
DX10_R8G8_SINT ,
DX10_R16_FLOAT ,
DX10_R16_UNORM ,
DX10_R16_UINT ,
DX10_R16_SNORM ,
DX10_R16_SINT ,
DX10_R8_UNORM,
DX10_R8_UINT,
DX10_R8_SNORM,
DX10_R8_SINT,
DX10_A8_UNORM,
DX10_R1_UNORM,
DX10_R9G9B9E5_SHAREDEXP, // unimplemented
DX10_R8G8_B8G8_UNORM, // unimplemented
DX10_G8R8_G8B8_UNORM, // unimplemented
DX10_BC1_UNORM,
DX10_BC1_UNORM_SRGB,
DX10_BC2_UNORM,
DX10_BC2_UNORM_SRGB,
DX10_BC3_UNORM,
DX10_BC3_UNORM_SRGB,
DX10_BC4_UNORM, // unimplemented
DX10_BC4_SNORM, // unimplemented
DX10_BC5_UNORM, // unimplemented
DX10_BC5_SNORM, // unimplemented
// OpenVG
/* RGB{A,X} channel ordering */
ePT_VG_sRGBX_8888 = 0x90,
ePT_VG_sRGBA_8888,
ePT_VG_sRGBA_8888_PRE,
ePT_VG_sRGB_565,
ePT_VG_sRGBA_5551,
ePT_VG_sRGBA_4444,
ePT_VG_sL_8,
ePT_VG_lRGBX_8888,
ePT_VG_lRGBA_8888,
ePT_VG_lRGBA_8888_PRE,
ePT_VG_lL_8,
ePT_VG_A_8,
ePT_VG_BW_1,
/* {A,X}RGB channel ordering */
ePT_VG_sXRGB_8888,
ePT_VG_sARGB_8888,
ePT_VG_sARGB_8888_PRE,
ePT_VG_sARGB_1555,
ePT_VG_sARGB_4444,
ePT_VG_lXRGB_8888,
ePT_VG_lARGB_8888,
ePT_VG_lARGB_8888_PRE,
/* BGR{A,X} channel ordering */
ePT_VG_sBGRX_8888,
ePT_VG_sBGRA_8888,
ePT_VG_sBGRA_8888_PRE,
ePT_VG_sBGR_565,
ePT_VG_sBGRA_5551,
ePT_VG_sBGRA_4444,
ePT_VG_lBGRX_8888,
ePT_VG_lBGRA_8888,
ePT_VG_lBGRA_8888_PRE,
/* {A,X}BGR channel ordering */
ePT_VG_sXBGR_8888,
ePT_VG_sABGR_8888 ,
ePT_VG_sABGR_8888_PRE,
ePT_VG_sABGR_1555,
ePT_VG_sABGR_4444,
ePT_VG_lXBGR_8888,
ePT_VG_lABGR_8888,
ePT_VG_lABGR_8888_PRE,
// max cap for iterating
END_OF_PIXEL_TYPES,
MGLPT_NOTYPE = 0xffffffff
};
/*****************************************************************************
* Legacy constants (V1/V2)
*****************************************************************************/
const PVRTuint32 PVRTEX_MIPMAP = (1<<8); // has mip map levels
const PVRTuint32 PVRTEX_TWIDDLE = (1<<9); // is twiddled
const PVRTuint32 PVRTEX_BUMPMAP = (1<<10); // has normals encoded for a bump map
const PVRTuint32 PVRTEX_TILING = (1<<11); // is bordered for tiled pvr
const PVRTuint32 PVRTEX_CUBEMAP = (1<<12); // is a cubemap/skybox
const PVRTuint32 PVRTEX_FALSEMIPCOL = (1<<13); // are there false coloured MIP levels
const PVRTuint32 PVRTEX_VOLUME = (1<<14); // is this a volume texture
const PVRTuint32 PVRTEX_ALPHA = (1<<15); // v2.1 is there transparency info in the texture
const PVRTuint32 PVRTEX_VERTICAL_FLIP = (1<<16); // v2.1 is the texture vertically flipped
const PVRTuint32 PVRTEX_PIXELTYPE = 0xff; // pixel type is always in the last 16bits of the flags
const PVRTuint32 PVRTEX_IDENTIFIER = 0x21525650; // the pvr identifier is the characters 'P','V','R'
const PVRTuint32 PVRTEX_V1_HEADER_SIZE = 44; // old header size was 44 for identification purposes
const PVRTuint32 PVRTC2_MIN_TEXWIDTH = 16;
const PVRTuint32 PVRTC2_MIN_TEXHEIGHT = 8;
const PVRTuint32 PVRTC4_MIN_TEXWIDTH = 8;
const PVRTuint32 PVRTC4_MIN_TEXHEIGHT = 8;
const PVRTuint32 ETC_MIN_TEXWIDTH = 4;
const PVRTuint32 ETC_MIN_TEXHEIGHT = 4;
const PVRTuint32 DXT_MIN_TEXWIDTH = 4;
const PVRTuint32 DXT_MIN_TEXHEIGHT = 4;
/****************************************************************************
** Functions
****************************************************************************/
/*!***************************************************************************
@Function PVRTTextureCreate
@Input w Size of the texture
@Input h Size of the texture
@Input wMin Minimum size of a texture level
@Input hMin Minimum size of a texture level
@Input nBPP Bits per pixel of the format
@Input bMIPMap Create memory for MIP-map levels also?
@Return Allocated texture memory (must be free()d)
@Description Creates a PVRTextureHeaderV3 structure, including room for
the specified texture, in memory.
*****************************************************************************/
PVRTextureHeaderV3 *PVRTTextureCreate(
unsigned int w,
unsigned int h,
const unsigned int wMin,
const unsigned int hMin,
const unsigned int nBPP,
const bool bMIPMap);
/*!***************************************************************************
@Function PVRTTextureTile
@Modified pOut The tiled texture in system memory
@Input pIn The source texture
@Input nRepeatCnt Number of times to repeat the source texture
@Description Allocates and fills, in system memory, a texture large enough
to repeat the source texture specified number of times.
*****************************************************************************/
void PVRTTextureTile(
PVRTextureHeaderV3 **pOut,
const PVRTextureHeaderV3 * const pIn,
const int nRepeatCnt);
/****************************************************************************
** Internal Functions
****************************************************************************/
//Preprocessor definitions to generate a pixelID for use when consts are needed. For example - switch statements. These should be evaluated by the compiler rather than at run time - assuming that arguments are all constant.
//Generate a 4 channel PixelID.
#define PVRTGENPIXELID4(C1Name, C2Name, C3Name, C4Name, C1Bits, C2Bits, C3Bits, C4Bits) ( ( (PVRTuint64)C1Name) + ( (PVRTuint64)C2Name<<8) + ( (PVRTuint64)C3Name<<16) + ( (PVRTuint64)C4Name<<24) + ( (PVRTuint64)C1Bits<<32) + ( (PVRTuint64)C2Bits<<40) + ( (PVRTuint64)C3Bits<<48) + ( (PVRTuint64)C4Bits<<56) )
//Generate a 1 channel PixelID.
#define PVRTGENPIXELID3(C1Name, C2Name, C3Name, C1Bits, C2Bits, C3Bits)( PVRTGENPIXELID4(C1Name, C2Name, C3Name, 0, C1Bits, C2Bits, C3Bits, 0) )
//Generate a 2 channel PixelID.
#define PVRTGENPIXELID2(C1Name, C2Name, C1Bits, C2Bits) ( PVRTGENPIXELID4(C1Name, C2Name, 0, 0, C1Bits, C2Bits, 0, 0) )
//Generate a 3 channel PixelID.
#define PVRTGENPIXELID1(C1Name, C1Bits) ( PVRTGENPIXELID4(C1Name, 0, 0, 0, C1Bits, 0, 0, 0))
//Forward declaration of CPVRTMap.
template <typename KeyType, typename DataType>
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<PVRTuint32, CPVRTMap<PVRTuint32,MetaDataBlock> >* 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)
*****************************************************************************/

View File

@@ -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

View File

@@ -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 <typename KeyType, typename DataType>
class PVR_DLL CPVRTMap;
template<typename T>
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 <typename KeyType, typename DataType>
class PVR_DLL CPVRTMap;
template<typename T>
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<uint32, CPVRTMap<uint32,MetaDataBlock> > MetaDataMap;
};
#endif //_PVRTEXTURE_DEFINES_H

View File

@@ -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

View File

@@ -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<uint32, CPVRTMap<uint32,MetaDataBlock> > 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

View File

@@ -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

View File

@@ -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

Binary file not shown.

View File

@@ -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 = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.cpp; };
104A335D1672D31C001C8BA6 /* KRCollider.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = KRCollider.h; sourceTree = "<group>"; 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 = "<group>"; };
E404701E18695DD200F01F42 /* KRTextureKTX.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = KRTextureKTX.cpp; sourceTree = "<group>"; };
E404701F18695DD200F01F42 /* KRTextureKTX.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KRTextureKTX.h; sourceTree = "<group>"; };
@@ -419,7 +434,7 @@
E40BA45315EFF79500D7C3DD /* KRAABB.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KRAABB.h; sourceTree = "<group>"; };
E40F982A184A7A2700CFA4D8 /* KRMeshQuad.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = KRMeshQuad.cpp; sourceTree = "<group>"; };
E40F982B184A7A2700CFA4D8 /* KRMeshQuad.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KRMeshQuad.h; sourceTree = "<group>"; };
E40F9830184A7BAC00CFA4D8 /* KRSprite.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = KRSprite.cpp; sourceTree = "<group>"; };
E40F9830184A7BAC00CFA4D8 /* KRSprite.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; path = KRSprite.cpp; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.cpp; };
E40F9831184A7BAC00CFA4D8 /* KRSprite.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KRSprite.h; sourceTree = "<group>"; };
E414BAE11435557300A668C4 /* KRModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = KRModel.h; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
E414BAE41435558800A668C4 /* KRModel.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; path = KRModel.cpp; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.cpp; };
@@ -459,10 +474,8 @@
E43B0AD515DDCA0D00A5CB9F /* KRContextObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KRContextObject.h; sourceTree = "<group>"; };
E43F70DA181B20E300136169 /* KRLODSet.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = KRLODSet.cpp; sourceTree = "<group>"; };
E43F70DB181B20E400136169 /* KRLODSet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KRLODSet.h; sourceTree = "<group>"; };
E43F70E31824D9AB00136169 /* KRTextureStreamer.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = KRTextureStreamer.mm; sourceTree = "<group>"; };
E43F70E41824D9AB00136169 /* KRTextureStreamer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KRTextureStreamer.h; sourceTree = "<group>"; };
E43F70FD1824E73100136169 /* KRMeshStreamer.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = KRMeshStreamer.mm; sourceTree = "<group>"; };
E43F70FE1824E73100136169 /* KRMeshStreamer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KRMeshStreamer.h; sourceTree = "<group>"; };
E43F70E31824D9AB00136169 /* KRStreamer.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; lineEnding = 0; path = KRStreamer.mm; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
E43F70E41824D9AB00136169 /* KRStreamer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = KRStreamer.h; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
E44F38231683B22C00399B5D /* KRRenderSettings.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KRRenderSettings.h; sourceTree = "<group>"; };
E44F38271683B24400399B5D /* KRRenderSettings.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = KRRenderSettings.cpp; sourceTree = "<group>"; };
E450273716E0491D00FDEC5C /* KRReverbZone.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; path = KRReverbZone.cpp; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.cpp; };
@@ -471,6 +484,25 @@
E45134B51746A4A300443C21 /* KRBehavior.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KRBehavior.h; sourceTree = "<group>"; };
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 = "<group>"; };
E45E03A518790DD1006DA23F /* PVRTDecompress.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PVRTDecompress.h; sourceTree = "<group>"; };
E45E03A618790DD1006DA23F /* PVRTError.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PVRTError.h; sourceTree = "<group>"; };
E45E03A718790DD1006DA23F /* PVRTexture.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PVRTexture.h; sourceTree = "<group>"; };
E45E03A818790DD1006DA23F /* PVRTextureDefines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PVRTextureDefines.h; sourceTree = "<group>"; };
E45E03A918790DD1006DA23F /* PVRTextureFormat.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PVRTextureFormat.h; sourceTree = "<group>"; };
E45E03AA18790DD1006DA23F /* PVRTextureHeader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PVRTextureHeader.h; sourceTree = "<group>"; };
E45E03AB18790DD1006DA23F /* PVRTextureUtilities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PVRTextureUtilities.h; sourceTree = "<group>"; };
E45E03AC18790DD1006DA23F /* PVRTextureVersion.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PVRTextureVersion.h; sourceTree = "<group>"; };
E45E03AD18790DD1006DA23F /* PVRTGlobal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PVRTGlobal.h; sourceTree = "<group>"; };
E45E03AE18790DD1006DA23F /* PVRTMap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PVRTMap.h; sourceTree = "<group>"; };
E45E03AF18790DD1006DA23F /* PVRTString.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PVRTString.h; sourceTree = "<group>"; };
E45E03B018790DD1006DA23F /* PVRTTexture.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PVRTTexture.h; sourceTree = "<group>"; };
E45E03BF18790DF5006DA23F /* libPVRTexLib.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libPVRTexLib.a; sourceTree = "<group>"; };
E45E03C318790EC0006DA23F /* tinyxml2_readme.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = tinyxml2_readme.txt; sourceTree = "<group>"; };
E45E03C418790EC0006DA23F /* tinyxml2.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = tinyxml2.cpp; sourceTree = "<group>"; };
E45E03C518790EC0006DA23F /* tinyxml2.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tinyxml2.h; sourceTree = "<group>"; };
E45E03CB18790EFF006DA23F /* forsyth.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = forsyth.cpp; sourceTree = "<group>"; };
E45E03CC18790EFF006DA23F /* forsyth.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = forsyth.h; sourceTree = "<group>"; };
E460292516681CFE00261BB9 /* KRTextureAnimated.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KRTextureAnimated.h; sourceTree = "<group>"; };
E460292716681D1000261BB9 /* KRTextureAnimated.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = KRTextureAnimated.cpp; sourceTree = "<group>"; };
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 = "<group>"; };
E46A6B6C1559E97D000DBD37 /* KRResource+blend.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "KRResource+blend.cpp"; sourceTree = "<group>"; };
E46A6B6F1559EF0A000DBD37 /* KRResource+blend.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "KRResource+blend.h"; sourceTree = "<group>"; };
E46C214115364BC8009CABF3 /* tinyxml2_readme.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = tinyxml2_readme.txt; sourceTree = "<group>"; };
E46C214215364BC8009CABF3 /* tinyxml2.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = tinyxml2.cpp; sourceTree = "<group>"; };
E46C214315364BC8009CABF3 /* tinyxml2.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tinyxml2.h; sourceTree = "<group>"; };
E46C214915364DDB009CABF3 /* KRSceneManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KRSceneManager.h; sourceTree = "<group>"; };
E46C214A15364DEC009CABF3 /* KRSceneManager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = KRSceneManager.cpp; sourceTree = "<group>"; };
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 = "<group>"; 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 = "<group>"; };
E4F89BB318A6DB1200015637 /* KRTriangle3.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KRTriangle3.h; sourceTree = "<group>"; };
E4F975311536220900FD60B2 /* KRNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = KRNode.h; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
E4F975351536221C00FD60B2 /* KRNode.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; path = KRNode.cpp; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.cpp; };
E4FE6AA716B21D660058B8CE /* forsyth.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = forsyth.h; sourceTree = "<group>"; };
E4FE6AAA16B21D7E0058B8CE /* forsyth.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = forsyth.cpp; sourceTree = "<group>"; };
/* 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 = "<group>";
};
E45E03A118790D92006DA23F /* 3rdparty */ = {
isa = PBXGroup;
children = (
E45E03C218790E55006DA23F /* tinyxml2 */,
E45E03C118790E4F006DA23F /* forsyth */,
E45E03A218790DA3006DA23F /* pvrtexlib */,
);
path = 3rdparty;
sourceTree = "<group>";
};
E45E03A218790DA3006DA23F /* pvrtexlib */ = {
isa = PBXGroup;
children = (
E45E03BE18790DDB006DA23F /* static_osx */,
E45E03A318790DB8006DA23F /* include */,
);
path = pvrtexlib;
sourceTree = "<group>";
};
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 = "<group>";
};
E45E03BE18790DDB006DA23F /* static_osx */ = {
isa = PBXGroup;
children = (
E45E03BF18790DF5006DA23F /* libPVRTexLib.a */,
);
path = static_osx;
sourceTree = "<group>";
};
E45E03C118790E4F006DA23F /* forsyth */ = {
isa = PBXGroup;
children = (
E45E03CB18790EFF006DA23F /* forsyth.cpp */,
E45E03CC18790EFF006DA23F /* forsyth.h */,
);
path = forsyth;
sourceTree = "<group>";
};
E45E03C218790E55006DA23F /* tinyxml2 */ = {
isa = PBXGroup;
children = (
E45E03C318790EC0006DA23F /* tinyxml2_readme.txt */,
E45E03C418790EC0006DA23F /* tinyxml2.cpp */,
E45E03C518790EC0006DA23F /* tinyxml2.h */,
);
path = tinyxml2;
sourceTree = "<group>";
};
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 = "<group>";
};
E46C214015364BB8009CABF3 /* tinyxml2 */ = {
isa = PBXGroup;
children = (
E46C214115364BC8009CABF3 /* tinyxml2_readme.txt */,
E46C214215364BC8009CABF3 /* tinyxml2.cpp */,
E46C214315364BC8009CABF3 /* tinyxml2.h */,
);
name = tinyxml2;
sourceTree = "<group>";
};
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 = "<group>";
};
E4F9753815362A5200FD60B2 /* 3rdparty */ = {
isa = PBXGroup;
children = (
E4FE6AA516B21D330058B8CE /* forsyth */,
E46C214015364BB8009CABF3 /* tinyxml2 */,
);
name = 3rdparty;
sourceTree = "<group>";
};
E4FE6AA516B21D330058B8CE /* forsyth */ = {
isa = PBXGroup;
children = (
E4FE6AA716B21D660058B8CE /* forsyth.h */,
E4FE6AAA16B21D7E0058B8CE /* forsyth.cpp */,
);
name = forsyth;
sourceTree = "<group>";
};
/* 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 */,

View File

@@ -1,59 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0500"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "E491016013C99B9E0098455B"
BuildableName = "libkraken.a"
BlueprintName = "Kraken - ios"
ReferencedContainer = "container:Kraken.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES"
buildConfiguration = "Debug">
<Testables>
</Testables>
</TestAction>
<LaunchAction
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
buildConfiguration = "Debug"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
allowLocationSimulation = "YES">
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
buildConfiguration = "Release"
debugDocumentVersioning = "YES">
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>

View File

@@ -1,59 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0500"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "E4BBBB7D1512A40300F43B5B"
BuildableName = "kraken.framework"
BlueprintName = "Kraken - osx"
ReferencedContainer = "container:Kraken.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES"
buildConfiguration = "Debug">
<Testables>
</Testables>
</TestAction>
<LaunchAction
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
buildConfiguration = "Debug"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
allowLocationSimulation = "YES">
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
buildConfiguration = "Release"
debugDocumentVersioning = "YES">
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>

View File

@@ -1,59 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0500"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "E4C8E4F316B9B2E20031DDCB"
BuildableName = "kraken_standard_assets_osx.bundle"
BlueprintName = "Kraken Standard Assets - OSX"
ReferencedContainer = "container:Kraken.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES"
buildConfiguration = "Debug">
<Testables>
</Testables>
</TestAction>
<LaunchAction
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
buildConfiguration = "Debug"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
allowLocationSimulation = "YES">
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
buildConfiguration = "Release"
debugDocumentVersioning = "YES">
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>

View File

@@ -1,59 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0500"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "E4C8E4E316B9B2D50031DDCB"
BuildableName = "kraken_standard_assets_ios.bundle"
BlueprintName = "Kraken Standard Assets - iOS"
ReferencedContainer = "container:Kraken.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES"
buildConfiguration = "Debug">
<Testables>
</Testables>
</TestAction>
<LaunchAction
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
buildConfiguration = "Debug"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
allowLocationSimulation = "YES">
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
buildConfiguration = "Release"
debugDocumentVersioning = "YES">
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>

View File

@@ -7,30 +7,22 @@
<key>Kraken - ios.xcscheme</key>
<dict>
<key>isShown</key>
<false/>
<key>orderHint</key>
<integer>30</integer>
<true/>
</dict>
<key>Kraken - osx.xcscheme</key>
<dict>
<key>isShown</key>
<false/>
<key>orderHint</key>
<integer>31</integer>
</dict>
<key>Kraken Standard Assets - OSX.xcscheme</key>
<dict>
<key>isShown</key>
<false/>
<key>orderHint</key>
<integer>33</integer>
</dict>
<key>Kraken Standard Assets - iOS.xcscheme</key>
<dict>
<key>isShown</key>
<false/>
<key>orderHint</key>
<integer>32</integer>
<true/>
</dict>
</dict>
<key>SuppressBuildableAutocreation</key>

View File

@@ -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 &center, 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;

View File

@@ -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 &center, float radius) const;
void encapsulate(const KRAABB & b);
KRAABB& operator =(const KRAABB& b);

View File

@@ -87,6 +87,7 @@ void KRAmbientZone::setZone(const std::string &zone)
void KRAmbientZone::render(KRCamera *pCamera, std::vector<KRPointLight *> &point_lights, std::vector<KRDirectionalLight *> &directional_lights, std::vector<KRSpotLight *>&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<KRPointLight *> &point
GLDEBUG(glEnable(GL_DEPTH_TEST));
GLDEBUG(glDepthFunc(GL_LEQUAL));
GLDEBUG(glDepthRangef(0.0, 1.0));
std::vector<KRMesh *> sphereModels = getContext().getModelManager()->getModel("__sphere");
std::vector<KRMesh *> 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");

View File

@@ -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,13 +257,35 @@ KRAnimation *KRAnimation::split(const std::string &name, float start_time, float
new_animation->m_layers[new_layer->getName()] = new_layer;
for(std::vector<KRAnimationAttribute *>::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) {

View File

@@ -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<KRAudioSample *> 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();
@@ -1929,3 +1964,126 @@ void KRAudioManager::renderITD()
*/
}
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();
}

View File

@@ -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
// 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<KRAudioSource *> m_activeAudioSources;
std::set<KRAudioSample *> m_openAudioSamples;
void initAudio();
void initOpenAL();
void initSiren();
@@ -176,7 +199,6 @@ private:
void cleanupSiren();
audio_engine_t m_audio_engine;
// OpenAL Handles
@@ -215,6 +237,7 @@ private:
void renderHRTF();
void renderITD();
void renderReverbImpulseResponse(int impulse_response_offset, int frame_count_log2);
void renderLimiter();
std::vector<KRVector2> m_hrtf_sample_locations;
float *m_hrtf_data;

View File

@@ -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;
@@ -232,6 +238,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();
}
}

View File

@@ -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,

View File

@@ -200,6 +200,8 @@ void KRAudioSource::queueBuffer()
void KRAudioSource::render(KRCamera *pCamera, std::vector<KRPointLight *> &point_lights, std::vector<KRDirectionalLight *> &directional_lights, std::vector<KRSpotLight *>&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<KRPointLight *> &point
GLDEBUG(glEnable(GL_DEPTH_TEST));
GLDEBUG(glDepthFunc(GL_LEQUAL));
GLDEBUG(glDepthRangef(0.0, 1.0));
std::vector<KRMesh *> sphereModels = getContext().getModelManager()->getModel("__sphere");
std::vector<KRMesh *> 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");

View File

@@ -41,6 +41,7 @@ KRAABB KRBone::getBounds() {
void KRBone::render(KRCamera *pCamera, std::vector<KRPointLight *> &point_lights, std::vector<KRDirectionalLight *> &directional_lights, std::vector<KRSpotLight *>&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<KRPointLight *> &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<KRMesh *> sphereModels = getContext().getModelManager()->getModel("__sphere");
std::vector<KRMesh *> 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");

View File

@@ -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,6 +78,11 @@ 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 ----====----
@@ -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<KRPointLight *>(), std::vector<KRDirectionalLight *>(), std::vector<KRSpotLight *>(), 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));
}
@@ -331,6 +341,10 @@ 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<KRPointLight *>(), std::vector<KRDirectionalLight *>(), std::vector<KRSpotLight *>(), 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<KRAABB, int>::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<KRPointLight *>(), std::vector<KRDirectionalLight *>(), std::vector<KRSpotLight *>(), 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<KRPointLight *>(), std::vector<KRDirectionalLight *>(), std::vector<KRSpotLight *>(), 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<KRPointLight *>(), std::vector<KRDirectionalLight *>(), std::vector<KRSpotLight *>(), 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<KRMeshManager::draw_call_info> draw_calls = m_pContext->getModelManager()->getDrawCalls();
std::vector<KRMeshManager::draw_call_info> 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;
}

View File

@@ -59,7 +59,7 @@ public:
KRRenderSettings settings;
const KRViewport &getViewport();
const KRViewport &getViewport() const;
virtual std::string getElementName();
@@ -68,10 +68,14 @@ public:
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;

View File

@@ -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<KRPointLight *> &point_lights, std::vector<KRDirectionalLight *> &directional_lights, std::vector<KRSpotLight *>&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);

View File

@@ -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);

View File

@@ -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<KRResource *> KRContext::getResources()
for(unordered_map<std::string, KRMaterial *>::iterator itr = m_pMaterialManager->getMaterials().begin(); itr != m_pMaterialManager->getMaterials().end(); itr++) {
resources.push_back((*itr).second);
}
for(unordered_multimap<std::string, KRMesh *>::iterator itr = m_pModelManager->getModels().begin(); itr != m_pModelManager->getModels().end(); itr++) {
for(unordered_multimap<std::string, KRMesh *>::iterator itr = m_pMeshManager->getModels().begin(); itr != m_pMeshManager->getModels().end(); itr++) {
resources.push_back((*itr).second);
}
for(unordered_map<std::string, KRAnimation *>::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);
}
}

View File

@@ -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

View File

@@ -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<KRPointLight *> &point_lights, std::vector<KRDirectionalLight *> &directional_lights, std::vector<KRSpotLight *>&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<KRPointLight *> &
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));
}
}

View File

@@ -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"

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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();
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 {
if(!m_lod_visible) {
getScene().notify_sceneGraphCreate(this);
m_lod_visible = true;
}
for(std::set<KRNode *>::iterator itr=m_childNodes.begin(); itr != m_childNodes.end(); ++itr) {
(*itr)->updateLODVisibility(viewport);
return LOD_VISIBILITY_HIDDEN;
}
}
}

View File

@@ -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

View File

@@ -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<KRNode *>::iterator itr=m_childNodes.begin(); itr != m_childNodes.end(); ++itr) {
KRLODGroup *lod_group = dynamic_cast<KRLODGroup *>(*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<KRNode *>::iterator itr=m_childNodes.begin(); itr != m_childNodes.end(); ++itr) {
KRLODGroup *lod_group = dynamic_cast<KRLODGroup *>(*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<KRNode *>::iterator itr=m_childNodes.begin(); itr != m_childNodes.end(); ++itr) {
KRLODGroup *lod_group = dynamic_cast<KRLODGroup *>(*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;
}
}

View File

@@ -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);
};

View File

@@ -176,6 +176,8 @@ float KRLight::getDecayStart() {
void KRLight::render(KRCamera *pCamera, std::vector<KRPointLight *> &point_lights, std::vector<KRDirectionalLight *> &directional_lights, std::vector<KRSpotLight *>&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<KRPointLight *> &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<KRPointLight *> &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<KRPointLight *> &point_light
GLDEBUG(glBeginQuery(GL_SAMPLES_PASSED, m_occlusionQuery));
#endif
std::vector<KRMesh *> sphereModels = getContext().getModelManager()->getModel("__sphere");
std::vector<KRMesh *> 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<KRPointLight *> &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));
}
}

View File

@@ -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<KRPointLight *> &point_lights, std::vector<KRDirectionalLight *> &directional_lights, std::vector<KRSpotLight *>&spot_lights, const std::vector<KRBone *> &bones, const std::vector<KRMat4> &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<KRPointLight *> &point_ligh
if(!m_pReflectionCube && m_reflectionCube.size()) {
m_pReflectionCube = getContext().getTextureManager()->getTextureCube(m_reflectionCube.c_str());
}
}
bool KRMaterial::bind(KRCamera *pCamera, std::vector<KRPointLight *> &point_lights, std::vector<KRDirectionalLight *> &directional_lights, std::vector<KRSpotLight *>&spot_lights, const std::vector<KRBone *> &bones, const std::vector<KRMat4> &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<KRPointLight *> &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);
}

View File

@@ -84,10 +84,13 @@ public:
bool isTransparent();
const std::string &getName() const;
bool bind(KRCamera *pCamera, std::vector<KRPointLight *> &point_lights, std::vector<KRDirectionalLight *> &directional_lights, std::vector<KRSpotLight *>&spot_lights, const std::vector<KRBone *> &bones, const std::vector<KRMat4> &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<KRPointLight *> &point_lights, std::vector<KRDirectionalLight *> &directional_lights, std::vector<KRSpotLight *>&spot_lights, const std::vector<KRBone *> &bones, const std::vector<KRMat4> &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

View File

@@ -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);
}

View File

@@ -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,12 +161,8 @@ void KRMesh::loadPack(KRDataBlock *data) {
updateAttributeOffsets();
}
void KRMesh::render(const std::string &object_name, KRCamera *pCamera, std::vector<KRPointLight *> &point_lights, std::vector<KRDirectionalLight *> &directional_lights, std::vector<KRSpotLight *>&spot_lights, const KRViewport &viewport, const KRMat4 &matModel, KRTexture *pLightMap, KRNode::RenderPass renderPass, const std::vector<KRBone *> &bones, const KRVector3 &rim_color, float rim_power) {
//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();
void KRMesh::getMaterials()
{
if(m_materials.size() == 0) {
for(std::vector<KRMesh::Submesh *>::iterator itr = m_submeshes.begin(); itr != m_submeshes.end(); itr++) {
@@ -187,6 +184,37 @@ void KRMesh::render(const std::string &object_name, KRCamera *pCamera, std::vect
}
}
}
}
void KRMesh::preStream(float lodCoverage)
{
getSubmeshes();
getMaterials();
for(std::set<KRMaterial *>::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<KRMaterial *>::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<KRPointLight *> &point_lights, std::vector<KRDirectionalLight *> &directional_lights, std::vector<KRSpotLight *>&spot_lights, const KRViewport &viewport, const KRMat4 &matModel, KRTexture *pLightMap, KRNode::RenderPass renderPass, const std::vector<KRBone *> &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();
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;
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);
KRMeshManager::KRVBOData *vbo_data_block = NULL;
if(m_submeshes[iSubmesh]->vertex_data_blocks.size() <= vbo_index) {
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
}
}
// 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();
KRVector3 hit_point;
if(tri.rayCast(start, dir, hit_point)) {
// ---===--- hit_point is in triangle ---===---
if(new_hit_distance_sqr < prev_hit_distance_sqr || !hitinfo.didHit()) {
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_v0 - hit_point).magnitude();
float distance_v1 = (tri_v1 - hit_point).magnitude();
float distance_v2 = (tri_v2 - hit_point).magnitude();
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);
hitinfo = KRHitInfo(hit_point, normal, new_hit_distance);
return true;
} else {
return false; // Either no hit, or the hit was farther than an existing hit
}
return false; // The hit was farther than an existing hit
}
/*
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);
} else {
// Dit not hit the triangle
return false;
}
*/
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();

View File

@@ -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<std::vector<float> > bone_weights;
} mesh_info;
void render(const std::string &object_name, KRCamera *pCamera, std::vector<KRPointLight *> &point_lights, std::vector<KRDirectionalLight *> &directional_lights, std::vector<KRSpotLight *>&spot_lights, const KRViewport &viewport, const KRMat4 &matModel, KRTexture *pLightMap, KRNode::RenderPass renderPass, const std::vector<KRBone *> &bones, const KRVector3 &rim_color, float rim_power);
void render(const std::string &object_name, KRCamera *pCamera, std::vector<KRPointLight *> &point_lights, std::vector<KRDirectionalLight *> &directional_lights, std::vector<KRSpotLight *>&spot_lights, const KRViewport &viewport, const KRMat4 &matModel, KRTexture *pLightMap, KRNode::RenderPass renderPass, const std::vector<KRBone *> &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<std::pair<int, int> > vertex_index_bases, std::vector<KRVector3> vertices, std::vector<KRVector2> uva, std::vector<KRVector2> uvb, std::vector<KRVector3> normals, std::vector<KRVector3> tangents, std::vector<int> submesh_starts, std::vector<int> submesh_lengths, std::vector<std::string> material_names, std::vector<std::string> bone_names, std::vector<KRMat4> bone_bind_poses, std::vector<std::vector<int> > bone_indexes, std::vector<std::vector<float> > 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<KRDataBlock *>::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<KRDataBlock *>::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<KRDataBlock *> vertex_data_blocks;
vector<KRDataBlock *> index_data_blocks;
vector<KRMeshManager::KRVBOData *> 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<KRMaterial *> m_materials;

View File

@@ -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<std::string, KRMesh *> &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) {
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(vbo_to_release) {
m_vboMemUsed -= vbo_to_release->getSize();
#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));
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) {
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));
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;
}
#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
bool used_vbo_data = false;
if(vbo_changed) {
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<KRDataBlock *, vbo_info_type>::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<KRDataBlock *, KRVBOData *>::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
m_currentVBO->load();
m_memoryTransferredThisFrame += m_currentVBO->getSize();
m_vboMemUsed += m_currentVBO->getSize();
GLDEBUG(glBindBuffer(GL_ARRAY_BUFFER, m_currentVBO.vbo_handle));
#if GL_OES_mapbuffer
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<KRDataBlock *, vbo_info_type>::iterator itr = m_vbosActive.begin(); itr != m_vbosActive.end(); itr++) {
mem_active += (*itr).second.size;
for(unordered_map<KRDataBlock *, KRVBOData *>::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::draw_call_info> 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
}

View File

@@ -37,8 +37,6 @@
#include "KRDataBlock.h"
#include "KRNode.h"
#include "KRMeshStreamer.h"
class KRContext;
class KRMesh;
@@ -61,13 +59,49 @@ public:
std::vector<std::string> getModelNames();
unordered_multimap<std::string, KRMesh *> &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<draw_call_info> 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<std::string, KRMesh *> 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<KRDataBlock *, vbo_info_type> m_vbosActive;
unordered_map<KRDataBlock *, vbo_info_type> m_vbosPool;
unordered_map<KRDataBlock *, KRVBOData *> m_vbosActive;
unordered_map<KRDataBlock *, KRVBOData *> m_vbosPool;
KRDataBlock m_randomParticleVertexData;
KRDataBlock m_volumetricLightingVertexData;
@@ -142,8 +173,6 @@ private:
bool m_draw_call_logging_enabled;
bool m_draw_call_log_used;
KRMeshStreamer m_streamer;
};
#endif

View File

@@ -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<KRMesh *> 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<KRMesh *> 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<KRMesh *, std::vector<KRBone *> > 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<KRPointLight *> &point_lights, std::vector<KRDirectionalLight *> &directional_lights, std::vector<KRSpotLight *>&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<KRPointLight *> &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<KRPointLight *> &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) {

View File

@@ -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<KRMesh *> m_models;
unordered_map<KRMesh *, std::vector<KRBone *> > m_bones; // Outer std::map connects model to set of bones
KRTexture *m_pLightMap;

View File

@@ -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<KRNode *>::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<KRPointLight *> &point_lights, std::vector<KRDirectionalLight *> &directional_lights, std::vector<KRSpotLight *>&spot_lights, const KRViewport &viewport, RenderPass renderPass)
{
if(m_lod_visible <= LOD_VISIBILITY_PRESTREAM) return;
m_lastRenderFrame = getContext().getCurrentFrame();
}
@@ -472,6 +475,7 @@ KRScene &KRNode::getScene() {
}
KRAABB KRNode::getBounds() {
if(!m_boundsValid) {
KRAABB bounds = KRAABB::Zero();
bool first_child = true;
@@ -487,7 +491,10 @@ KRAABB KRNode::getBounds() {
}
}
return bounds;
m_bounds = bounds;
m_boundsValid = true;
}
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<KRNode *>::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) {
if(m_lod_visible != lod_visibility) {
if(m_lod_visible == LOD_VISIBILITY_HIDDEN && lod_visibility >= LOD_VISIBILITY_PRESTREAM) {
getScene().notify_sceneGraphCreate(this);
m_lod_visible = true;
} 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<KRNode *>::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<KRBehavior *> &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<KRNode *>::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();
}
}

View File

@@ -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<KRNode *> 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;

View File

@@ -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<KRCollider *> outer_colliders;
for(std::set<KRNode *>::iterator outer_nodes_itr=m_outerSceneNodes.begin(); outer_nodes_itr != m_outerSceneNodes.end(); outer_nodes_itr++) {
KRCollider *collider = dynamic_cast<KRCollider *>(*outer_nodes_itr);
if(collider) {
outer_colliders.push_back(collider);
}
}
for(std::vector<KRCollider *>::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;
}

View File

@@ -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;

View File

@@ -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<KRNode *>::iterator nodes_itr=m_sceneNodes.begin(); nodes_itr != m_sceneNodes.end(); nodes_itr++) {
KRCollider *collider = dynamic_cast<KRCollider *>(*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;
}

View File

@@ -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;

View File

@@ -56,6 +56,7 @@ bool KRParticleSystemNewtonian::hasPhysics()
void KRParticleSystemNewtonian::render(KRCamera *pCamera, std::vector<KRPointLight *> &point_lights, std::vector<KRDirectionalLight *> &directional_lights, std::vector<KRSpotLight *>&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::vector<KRPointLig
GLDEBUG(glDepthRangef(0.0, 1.0));
KRTexture *pParticleTexture = m_pContext->getTextureManager()->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::vector<KRPointLig
if(getContext().getShaderManager()->selectShader(*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));
// }
//// }
//// }
//// }

View File

@@ -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<KRPointLight *> &point_lights, std::vector<KRDirectionalLight *> &directional_lights, std::vector<KRSpotLight *>&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<KRPointLight *> &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<KRPointLight *> &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();

View File

@@ -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;

View File

@@ -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<FbxAnimStack>();
for(int i = 0; i < animation_count; i++) {
@@ -626,6 +639,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_X);
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);
}
@@ -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);
}
@@ -868,6 +899,22 @@ void LoadNode(FbxScene* pFbxScene, KRNode *parent_node, FbxGeometryConverter *pG
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;
KRVector3 node_scale = KRVector3(local_scale[0], local_scale[1], local_scale[2]);
@@ -880,6 +927,7 @@ void LoadNode(FbxScene* pFbxScene, KRNode *parent_node, FbxGeometryConverter *pG
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;
//&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;
}
}
}
@@ -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,8 +1489,11 @@ 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 ----====----
if(need_tangents) {
for(int l = 0; l < tangent_count; ++l)
{
FbxVector4 new_tangent;
@@ -1475,9 +1519,8 @@ void LoadMesh(KRContext &context, FbxScene* pFbxScene, FbxGeometryConverter *pGe
}
}
}
*/
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;
}

View File

@@ -86,6 +86,7 @@ void KRReverbZone::setZone(const std::string &zone)
void KRReverbZone::render(KRCamera *pCamera, std::vector<KRPointLight *> &point_lights, std::vector<KRDirectionalLight *> &directional_lights, std::vector<KRSpotLight *>&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<KRPointLight *> &point_
GLDEBUG(glEnable(GL_DEPTH_TEST));
GLDEBUG(glDepthFunc(GL_LEQUAL));
GLDEBUG(glDepthRangef(0.0, 1.0));
std::vector<KRMesh *> sphereModels = getContext().getModelManager()->getModel("__sphere");
std::vector<KRMesh *> 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");

View File

@@ -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<KRLocator *> &KRScene::getLocators()
return m_locatorNodes;
}
std::set<KRLight *> &KRScene::getLights()
{
return m_lights;
}
void KRScene::render(KRCamera *pCamera, unordered_map<KRAABB, int> &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<KRAABB, int> &visibleBound
std::vector<KRDirectionalLight *>directional_lights;
std::vector<KRSpotLight *>spot_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<KRNode *> outerNodes = std::set<KRNode *>(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<KRAABB, int> &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<KRAABB, int> &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<KRLight *>(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<KRNode *> newNodes = m_newNodes;
std::set<KRNode *> modifiedNodes = m_modifiedNodes;
std::set<KRNode *> newNodes = std::move(m_newNodes);
std::set<KRNode *> 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<KRLight *>(node);
if(light) {
m_lights.insert(light);
}
}
for(std::set<KRNode *>::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<KRNode *> newNodes = std::move(m_newNodes);
m_newNodes.clear();
for(std::set<KRNode *>::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<KRAmbientZone *>(node);
if(ambientZoneNode) {
m_ambientZoneNodes.insert(ambientZoneNode);
}
KRReverbZone *reverbZoneNode = dynamic_cast<KRReverbZone *>(node);
if(reverbZoneNode) {
m_reverbZoneNodes.insert(reverbZoneNode);
}
KRLocator *locatorNode = dynamic_cast<KRLocator *>(node);
if(locatorNode) {
m_locatorNodes.insert(locatorNode);
}
KRLight *light = dynamic_cast<KRLight *>(node);
if(light) {
m_lights.insert(light);
}
}
}
void KRScene::physicsUpdate(float deltaTime)
{
for(std::set<KRNode *>::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;
}

View File

@@ -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<KRAABB, int> &visibleBounds, const KRViewport &viewport, KRNode::RenderPass renderPass, bool new_frame);
@@ -73,6 +76,7 @@ public:
void render(KROctreeNode *pOctreeNode, unordered_map<KRAABB, int> &visibleBounds, KRCamera *pCamera, std::vector<KRPointLight *> &point_lights, std::vector<KRDirectionalLight *> &directional_lights, std::vector<KRSpotLight *>&spot_lights, const KRViewport &viewport, KRNode::RenderPass renderPass, std::vector<KROctreeNode *> &remainingOctrees, std::vector<KROctreeNode *> &remainingOctreesTestResults, std::vector<KROctreeNode *> &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<KRAmbientZone *> &getAmbientZones();
std::set<KRReverbZone *> &getReverbZones();
std::set<KRLocator *> &getLocators();
std::set<KRLight *> &getLights();
private:
@@ -101,6 +106,7 @@ private:
std::set<KRAmbientZone *> m_ambientZoneNodes;
std::set<KRReverbZone *> m_reverbZoneNodes;
std::set<KRLocator *> m_locatorNodes;
std::set<KRLight *> m_lights;
KROctree m_nodeTree;

View File

@@ -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]));
@@ -510,6 +511,10 @@ bool KRShader::bind(KRCamera &camera, const KRViewport &viewport, const KRMat4 &
);
}
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);

View File

@@ -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,

View File

@@ -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());
}

View File

@@ -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();

View File

@@ -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<KRPointLight *> &point_lights, std::vector<KRDirectionalLight *> &directional_lights, std::vector<KRSpotLight *>&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<KRPointLight *> &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));
}
}

View File

@@ -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;
};

View File

@@ -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) */

View File

@@ -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 <chrono>
#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 );
}
}

View File

@@ -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<texture_usage_t>(static_cast<int>(m_last_frame_usage) | static_cast<int>(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();
}

View File

@@ -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<long> m_textureMemUsed;

View File

@@ -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
int prev_lod_max_dim = m_new_lod_max_dim;
if(m_iHandle != 0) {
prev_lod_max_dim = m_current_lod_max_dim;
}
#endif
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;
}
}

View File

@@ -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 &current_lod_max_dim, int prev_lod_max_dim, bool compress = false) = 0;
virtual bool uploadTexture(GLenum target, int lod_max_dim, int &current_lod_max_dim, bool compress = false, bool premultiply_alpha = false) = 0;
virtual void bind(GLuint texture_unit);
protected:

View File

@@ -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; i<m_frame_count; i++) {
KRTexture2D *frame_texture = textureForFrame(i);
if(frame_texture) {
frame_texture->resetPoolExpiry(); // 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);

View File

@@ -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();

View File

@@ -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)
{

View File

@@ -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];
};

View File

@@ -153,7 +153,7 @@ long KRTextureKTX::getMemRequiredForSize(int max_dim)
return memoryRequired;
}
bool KRTextureKTX::uploadTexture(GLenum target, int lod_max_dim, int &current_lod_max_dim, int prev_lod_max_dim, bool compress)
bool KRTextureKTX::uploadTexture(GLenum target, int lod_max_dim, int &current_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 &current_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 &current_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++;
}

View File

@@ -19,7 +19,7 @@ public:
virtual ~KRTextureKTX();
virtual std::string getExtension();
bool uploadTexture(GLenum target, int lod_max_dim, int &current_lod_max_dim, int prev_lod_max_dim, bool compress = false);
bool uploadTexture(GLenum target, int lod_max_dim, int &current_lod_max_dim, bool compress = false, bool premultiply_alpha = false);
virtual long getMemRequiredForSize(int max_dim);

View File

@@ -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<KRENGINE_MAX_TEXTURE_UNITS; iTexture++) {
m_boundTextures[iTexture] = NULL;
}
m_memoryTransferredThisFrame = 0;
m_streamerComplete = true;
_clearGLState();
}
@@ -64,7 +64,7 @@ void KRTextureManager::_clearGLState()
m_wrapModeS[i] = 0;
m_wrapModeT[i] = 0;
m_maxAnisotropy[i] = -1.0f;
selectTexture(i, NULL);
selectTexture(i, NULL, 0.0f, KRTexture::TEXTURE_USAGE_NONE);
}
m_iActiveTexture = -1;
@@ -145,10 +145,42 @@ KRTexture *KRTextureManager::getTextureCube(const char *szName) {
unordered_map<std::string, KRTexture *>::iterator itr = m_textures.find(lowerName);
if(itr == m_textures.end()) {
// 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<KRTexture2D *>(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<KRTexture *>::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<KRTexture *> expiredTextures;
for(std::set<KRTexture *>::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<float, KRTexture *>(priority, activeTexture));
}
}
for(std::set<KRTexture *>::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<KRTexture *>::iterator itr=m_activeTextures_streamer.begin(); itr != m_activeTextures_streamer.end(); itr++) {
KRTexture *activeTexture = *itr;
/*
NEW ALGORITHM:
wantedTextureMem = activeTexture->getMemRequiredForSize(getContext().KRENGINE_MAX_TEXTURE_DIM) - activeTexture->getMemSize();
}
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
// Determine how much memory we need to free up
long memoryDeficit = wantedTextureMem - (getContext().KRENGINE_TARGET_TEXTURE_MEM_MAX - getMemUsed());
*/
// ---------------
// 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;
//long MAX_STREAM_TIME = 66;
//long startTime = getContext().getAbsoluteTimeMilliseconds();
for(std::set<KRTexture *>::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::sort(m_activeTextures_streamer.begin(), m_activeTextures_streamer.end(), std::greater<std::pair<float, KRTexture *>>());
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;
if(memoryRemainingThisFrame > minLodMem && texture->getNewLodMaxDim() < min_mip_level) {
memoryRemainingThisFrame -= minLodMem;
texture->resize(min_mip_level);
}
}
// Strip off mipmap levels of inactive textures to free up memory
long inactive_texture_mem_used_target = 0;
for(std::set<KRTexture *>::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);
}
}
inactive_texture_mem_used_target += mem_required;
//long minMipTime = getContext().getAbsoluteTimeMilliseconds() - startTime;
std::vector<int> 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 {
inactive_texture_mem_used_target += poolTexture->getMemSize();
memoryRemainingThisMip = memoryRemaining / 100L * (long)(*mip_itr);
mip_drop++;
mip_itr++;
}
}
// 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<KRTexture *>::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
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);
}
}
// Resize active textures to balance the memory usage and mipmap levels
for(std::set<KRTexture *>::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);
}
}
//if(getContext().getAbsoluteTimeMilliseconds() - startTime > MAX_STREAM_TIME) {
// return; // Bail out early if we spend too long
//}
}
//fprintf(stderr, "Active mipmap size: %i Inactive mapmap size: %i\n", (int)maxDimActive, (int)maxDimInactive);
glFlush();
//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<KRTexture *> expiredTextures;
for(std::set<KRTexture *>::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<KRTexture *>::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<std::string, KRTexture *> &KRTextureManager::getTextures()
return m_textures;
}
void KRTextureManager::compress()
void KRTextureManager::compress(bool premultiply_alpha)
{
std::vector<KRTexture *> textures_to_remove;
std::vector<KRTexture *> textures_to_add;
for(unordered_map<std::string, KRTexture *>::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<KRTexture *> &KRTextureManager::getActiveTextures()
return m_activeTextures;
}
std::set<KRTexture *> &KRTextureManager::getPoolTextures()
void KRTextureManager::primeTexture(KRTexture *texture)
{
return m_poolTextures;
if(m_activeTextures.find(texture) == m_activeTextures.end()) {
m_activeTextures.insert(texture);
}
}

View File

@@ -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<std::string, KRTexture *> &getTextures();
void compress();
void compress(bool premultiply_alpha = false);
std::set<KRTexture *> &getActiveTextures();
std::set<KRTexture *> &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<KRTexture *> m_activeTextures;
std::set<KRTexture *> m_poolTextures;
std::set<KRTexture *> m_activeTextures_streamer;
std::set<KRTexture *> m_poolTextures_streamer;
std::set<KRTexture *> m_activeTextures_streamer_copy;
std::set<KRTexture *> m_poolTextures_streamer_copy;
std::vector<std::pair<float, KRTexture *> > m_activeTextures_streamer;
std::vector<std::pair<float, KRTexture *> > m_activeTextures_streamer_copy;
bool m_streamerComplete;
std::atomic<long> m_textureMemUsed;
void rotateBuffers();
void balanceTextureMemory();
KRTextureStreamer m_streamer;
void balanceTextureMemory(long &memoryRemaining, long &memoryRemainingThisFrame);
std::mutex m_streamerFenceMutex;
};

View File

@@ -173,7 +173,7 @@ long KRTexturePVR::getMemRequiredForSize(int max_dim)
return memoryRequired;
}
bool KRTexturePVR::uploadTexture(GLenum target, int lod_max_dim, int &current_lod_max_dim, int prev_lod_max_dim, bool compress)
bool KRTexturePVR::uploadTexture(GLenum target, int lod_max_dim, int &current_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 &current_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 &current_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++;
}

View File

@@ -18,7 +18,7 @@ public:
virtual ~KRTexturePVR();
virtual std::string getExtension();
bool uploadTexture(GLenum target, int lod_max_dim, int &current_lod_max_dim, int prev_lod_max_dim, bool compress = false);
bool uploadTexture(GLenum target, int lod_max_dim, int &current_lod_max_dim, bool compress = false, bool premultiply_alpha = false);
virtual long getMemRequiredForSize(int max_dim);

View File

@@ -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,20 +71,25 @@ KRTextureTGA::~KRTextureTGA()
}
bool KRTextureTGA::uploadTexture(GLenum target, int lod_max_dim, int &current_lod_max_dim, int prev_lod_max_dim, bool compress)
bool KRTextureTGA::uploadTexture(GLenum target, int lod_max_dim, int &current_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();
@@ -113,25 +119,152 @@ bool KRTextureTGA::uploadTexture(GLenum target, int lod_max_dim, int &current_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;
default:
m_pData->unlock();
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;
@@ -149,7 +282,9 @@ bool KRTextureTGA::uploadTexture(GLenum target, int lod_max_dim, int &current_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:
@@ -187,14 +329,12 @@ KRTexture *KRTextureTGA::compress()
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) {
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();
@@ -204,21 +344,14 @@ KRTexture *KRTextureTGA::compress()
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)
{

View File

@@ -18,8 +18,11 @@ public:
virtual ~KRTextureTGA();
virtual std::string getExtension();
bool uploadTexture(GLenum target, int lod_max_dim, int &current_lod_max_dim, int prev_lod_max_dim, bool compress = false);
virtual KRTexture *compress();
bool uploadTexture(GLenum target, int lod_max_dim, int &current_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:

View File

@@ -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);
}

View File

@@ -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 <thread>
#include <atomic>
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<bool> m_stop;
std::atomic<bool> m_running;
void run();
KRVector3 m_c[3];
};
#endif /* defined(KRMESHSTREAMER_H) */
#endif // KRTRIANGLE3_H

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