Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

DDS loader fixed, ALBuffer/ALSource++

- ozCore
  * alignment calculation++: (size + align - 1) / align
  * some variable renames, cleanups
- ozEngine
  * ALBuffer::createSource(), creating buffers/sources without data/buffer
    atttached
  * DDS loader fixed for non-square, non-power-of-two and uncompressed images
    and GL ES
  • Loading branch information...
commit 75f6ba99c6c82f86bf0d07b7b8a06fc56ae63e1c 1 parent 535c74d
Davorin Učakar authored
4 src/ozCore/Alloc.hh
View
@@ -163,7 +163,7 @@ class Alloc
OZ_ALWAYS_INLINE
static size_t alignUp( size_t size )
{
- return ( ( size - 1 ) & ~( ALIGNMENT - 1 ) ) + ALIGNMENT;
+ return ( size + ALIGNMENT - 1 ) & ~( ALIGNMENT - 1 );
}
/**
@@ -183,7 +183,7 @@ class Alloc
OZ_ALWAYS_INLINE
static Type* alignUp( Type* p )
{
- return reinterpret_cast<Type*>( ( size_t( p - 1 ) & ~( ALIGNMENT - 1 ) ) + ALIGNMENT );
+ return reinterpret_cast<Type*>( size_t( p + ALIGNMENT - 1 ) & ~( ALIGNMENT - 1 ) );
}
};
2  src/ozCore/Array.hh
View
@@ -156,7 +156,7 @@ class Array
}
/**
- * Always false since static array cannot have zero size.
+ * Always false since static array cannot have zero elements.
*/
OZ_ALWAYS_INLINE
bool isEmpty() const
4 src/ozCore/Bitset.hh
View
@@ -66,7 +66,7 @@ class Bitset
size = 0;
}
else {
- size = ( nBits - 1 ) / ULONG_BITSIZE + 1;
+ size = ( nBits + ULONG_BITSIZE - 1 ) / ULONG_BITSIZE;
data = new ulong[size];
}
}
@@ -461,7 +461,7 @@ class Bitset
{
hard_assert( size == 0 && nBits > 0 );
- int nUnits = ( nBits - 1 ) / ULONG_BITSIZE + 1;
+ int nUnits = ( nBits + ULONG_BITSIZE - 1 ) / ULONG_BITSIZE;
data = new ulong[nUnits];
size = nUnits;
10 src/ozCore/Buffer.cc
View
@@ -40,7 +40,7 @@ Buffer::Buffer( const char* data_, int size_ ) :
}
Buffer::Buffer( const String& s ) :
- data( s.length() == 0 ? nullptr : new char[s.length()] ), size( s.length() )
+ data( s.length() == 0 ? nullptr : new char[ s.length() ] ), size( s.length() )
{
mCopy( data, s.cstr(), size_t( size ) );
}
@@ -119,12 +119,12 @@ void Buffer::resize( int newSize )
size = newSize;
}
-void Buffer::allocate( int size_ )
+void Buffer::allocate( int newSize )
{
- hard_assert( size == 0 && size_ > 0 );
+ hard_assert( size == 0 && newSize > 0 );
- data = new char[size_];
- size = size_;
+ data = new char[newSize];
+ size = newSize;
}
void Buffer::deallocate()
4 src/ozCore/Buffer.hh
View
@@ -176,9 +176,9 @@ class Buffer
void resize( int newSize );
/**
- * For an empty buffer, allocate new storage of `size` bytes.
+ * For an empty buffer, allocate new storage of `newSize` bytes.
*/
- void allocate( int size );
+ void allocate( int newSize );
/**
* Deallocate storage.
20 src/ozCore/List.hh
View
@@ -76,11 +76,11 @@ class List
* Capacity is doubled, if it doesn't suffice, it is set to the least multiple of `GRANULARITY`
* able to hold the requested number of elements.
*/
- void ensureCapacity( int desiredSize )
+ void ensureCapacity( int capacity )
{
- if( size < desiredSize ) {
+ if( size < capacity ) {
size *= 2;
- size = size < desiredSize ? ( ( desiredSize - 1 ) / GRANULARITY + 1 ) * GRANULARITY : size;
+ size = size < capacity ? ( capacity + GRANULARITY - 1 ) / GRANULARITY * GRANULARITY : size;
data = aReallocate<Elem>( data, count, size );
}
}
@@ -90,8 +90,8 @@ class List
/**
* Create an empty list with the given initial capacity.
*/
- explicit List( int size_ = 0 ) :
- data( size_ == 0 ? nullptr : new Elem[size_] ), count( 0 ), size( size_ )
+ explicit List( int capacity = 0 ) :
+ data( capacity == 0 ? nullptr : new Elem[capacity] ), count( 0 ), size( capacity )
{}
/**
@@ -631,14 +631,14 @@ class List
}
/**
- * For an empty list with no allocated storage, allocate capacity for `size_` elements.
+ * For an empty list with no allocated storage, allocate capacity for `capacity` elements.
*/
- void allocate( int size_ )
+ void allocate( int capacity )
{
- hard_assert( size == 0 && size_ > 0 );
+ hard_assert( size == 0 && capacity > 0 );
- data = new Elem[size_];
- size = size_;
+ data = new Elem[capacity];
+ size = capacity;
}
/**
20 src/ozCore/Map.hh
View
@@ -102,11 +102,11 @@ class Map
* Capacity is doubled, if it doesn't suffice, it is set to the least multiple of `GRANULARITY`
* able to hold the requested number of elements.
*/
- void ensureCapacity( int desiredSize )
+ void ensureCapacity( int capacity )
{
- if( size < desiredSize ) {
+ if( size < capacity ) {
size *= 2;
- size = size < desiredSize ? ( ( desiredSize - 1 ) / GRANULARITY + 1 ) * GRANULARITY : size;
+ size = size < capacity ? ( capacity + GRANULARITY - 1 ) / GRANULARITY * GRANULARITY : size;
data = aReallocate<Elem>( data, count, size );
}
}
@@ -116,8 +116,8 @@ class Map
/**
* Create an empty map with the given initial capacity.
*/
- explicit Map( int size_ = 0 ) :
- data( size_ == 0 ? nullptr : new Elem[size_] ), count( 0 ), size( size_ )
+ explicit Map( int capacity = 0 ) :
+ data( capacity == 0 ? nullptr : new Elem[capacity] ), count( 0 ), size( capacity )
{}
/**
@@ -541,14 +541,14 @@ class Map
}
/**
- * For an empty map with no allocated storage, allocate capacity for `size_` elements.
+ * For an empty map with no allocated storage, allocate capacity for `capacity` elements.
*/
- void allocate( int size_ )
+ void allocate( int capacity )
{
- hard_assert( size == 0 && size_ > 0 );
+ hard_assert( size == 0 && capacity > 0 );
- data = new Elem[size_];
- size = size_;
+ data = new Elem[capacity];
+ size = capacity;
}
/**
20 src/ozCore/Pool.hh
View
@@ -132,8 +132,8 @@ class Pool
Block* firstBlock; ///< Linked list of the allocated blocks.
Slot* freeSlot; ///< Linked list of free slots or `nullptr` if none.
- int size; ///< Capacity.
int count; ///< Number of occupied slots in the pool.
+ int size; ///< Capacity.
public:
@@ -141,7 +141,7 @@ class Pool
* Create an empty pool, storage is allocated when the first allocation is made.
*/
explicit Pool() :
- firstBlock( nullptr ), freeSlot( nullptr ), size( 0 ), count( 0 )
+ firstBlock( nullptr ), freeSlot( nullptr ), count( 0 ), size( 0 )
{}
/**
@@ -156,12 +156,12 @@ class Pool
* Move constructor, moves storage.
*/
Pool( Pool&& p ) :
- firstBlock( p.firstBlock ), freeSlot( p.freeSlot ), size( p.size ), count( p.count )
+ firstBlock( p.firstBlock ), freeSlot( p.freeSlot ), count( p.count ), size( p.size )
{
p.firstBlock = nullptr;
p.freeSlot = nullptr;
- p.size = 0;
p.count = 0;
+ p.size = 0;
}
/**
@@ -179,13 +179,13 @@ class Pool
firstBlock = p.firstBlock;
freeSlot = p.freeSlot;
- size = p.size;
count = p.count;
+ size = p.size;
p.firstBlock = nullptr;
p.freeSlot = nullptr;
- p.size = 0;
p.count = 0;
+ p.size = 0;
return *this;
}
@@ -199,12 +199,14 @@ class Pool
if( freeSlot == nullptr ) {
firstBlock = new Block( firstBlock );
- freeSlot = &firstBlock->data[1];
- size += BLOCK_SIZE;
+ freeSlot = &firstBlock->data[1];
+ size += BLOCK_SIZE;
+
return firstBlock->data[0].content;
}
else {
Slot* slot = freeSlot;
+
freeSlot = slot->nextSlot;
return slot;
}
@@ -283,8 +285,8 @@ class Pool
firstBlock = nullptr;
freeSlot = nullptr;
- size = 0;
count = 0;
+ size = 0;
}
};
2  src/ozCore/SBitset.hh
View
@@ -52,7 +52,7 @@ class SBitset
static const int ULONG_BITSIZE = int( sizeof( ulong ) * 8 );
/// Number of units.
- static const int SIZE = ( BITSIZE - 1 ) / ULONG_BITSIZE + 1;
+ static const int SIZE = ( BITSIZE + ULONG_BITSIZE - 1 ) / ULONG_BITSIZE;
ulong data[SIZE]; ///< Pointer to array of units that holds the data.
20 src/ozCore/Set.hh
View
@@ -79,11 +79,11 @@ class Set
* Capacity is doubled, if it doesn't suffice, it is set to the least multiple of `GRANULARITY`
* able to hold the requested number of elements.
*/
- void ensureCapacity( int desiredSize )
+ void ensureCapacity( int capacity )
{
- if( size < desiredSize ) {
+ if( size < capacity ) {
size *= 2;
- size = size < desiredSize ? ( ( desiredSize - 1 ) / GRANULARITY + 1 ) * GRANULARITY : size;
+ size = size < capacity ? ( capacity + GRANULARITY - 1 ) / GRANULARITY * GRANULARITY : size;
data = aReallocate<Elem>( data, count, size );
}
}
@@ -93,8 +93,8 @@ class Set
/**
* Create an empty set with the given initial capacity.
*/
- explicit Set( int size_ = 0 ) :
- data( size_ == 0 ? nullptr : new Elem[size_] ), count( 0 ), size( size_ )
+ explicit Set( int capacity = 0 ) :
+ data( capacity == 0 ? nullptr : new Elem[capacity] ), count( 0 ), size( capacity )
{}
/**
@@ -498,14 +498,14 @@ class Set
}
/**
- * For an empty set with no allocated storage, allocate capacity for `size_` elements.
+ * For an empty set with no allocated storage, allocate capacity for `capacity` elements.
*/
- void allocate( int size_ )
+ void allocate( int capacity )
{
- hard_assert( size == 0 && size_ > 0 );
+ hard_assert( size == 0 && capacity > 0 );
- data = new Elem[size_];
- size = size_;
+ data = new Elem[capacity];
+ size = capacity;
}
/**
2  src/ozCore/Thread.cc
View
@@ -237,7 +237,7 @@ void Thread::start( const char* name, Type type, Main* main, void* data )
}
}
else {
- pthread_attr_t attrib;
+ pthread_attr_t attrib;
pthread_attr_init( &attrib );
pthread_attr_setdetachstate( &attrib, PTHREAD_CREATE_DETACHED );
106 src/ozCore/arrays.hh
View
@@ -223,10 +223,10 @@ inline int aLength( const Elem ( & )[COUNT] )
* Copy array elements from the first to the last.
*/
template <typename Elem>
-inline void aCopy( Elem* aDest, const Elem* aSrc, int count )
+inline void aCopy( Elem* destArray, const Elem* srcArray, int count )
{
for( int i = 0; i < count; ++i ) {
- aDest[i] = aSrc[i];
+ destArray[i] = srcArray[i];
}
}
@@ -234,10 +234,10 @@ inline void aCopy( Elem* aDest, const Elem* aSrc, int count )
* Move array elements from the last to the first.
*/
template <typename Elem>
-inline void aCopyBackward( Elem* aDest, const Elem* aSrc, int count )
+inline void aCopyBackward( Elem* destArray, const Elem* srcArray, int count )
{
for( int i = count - 1; i >= 0; --i ) {
- aDest[i] = aSrc[i];
+ destArray[i] = srcArray[i];
}
}
@@ -245,10 +245,10 @@ inline void aCopyBackward( Elem* aDest, const Elem* aSrc, int count )
* Move array elements from the first to the last.
*/
template <typename Elem>
-inline void aMove( Elem* aDest, Elem* aSrc, int count )
+inline void aMove( Elem* destArray, Elem* srcArray, int count )
{
for( int i = 0; i < count; ++i ) {
- aDest[i] = static_cast<Elem&&>( aSrc[i] );
+ destArray[i] = static_cast<Elem&&>( srcArray[i] );
}
}
@@ -256,10 +256,10 @@ inline void aMove( Elem* aDest, Elem* aSrc, int count )
* Move array elements from the last to the first.
*/
template <typename Elem>
-inline void aMoveBackward( Elem* aDest, Elem* aSrc, int count )
+inline void aMoveBackward( Elem* destArray, Elem* srcArray, int count )
{
for( int i = count - 1; i >= 0; --i ) {
- aDest[i] = static_cast<Elem&&>( aSrc[i] );
+ destArray[i] = static_cast<Elem&&>( srcArray[i] );
}
}
@@ -267,10 +267,10 @@ inline void aMoveBackward( Elem* aDest, Elem* aSrc, int count )
* %Set array elements to the given value.
*/
template <typename Elem, typename Value = Elem>
-inline void aFill( Elem* aDest, const Value& value, int count )
+inline void aFill( Elem* array, const Value& value, int count )
{
for( int i = 0; i < count; ++i ) {
- aDest[i] = value;
+ array[i] = value;
}
}
@@ -278,25 +278,25 @@ inline void aFill( Elem* aDest, const Value& value, int count )
* Swap array elements.
*/
template <typename Elem>
-inline void aSwap( Elem* aDestA, Elem* aDestB, int count )
+inline void aSwap( Elem* arrayA, Elem* arrayB, int count )
{
for( int i = 0; i < count; ++i ) {
- Elem t = static_cast<Elem&&>( aDestA[i] );
- aDestA[i] = static_cast<Elem&&>( aDestB[i] );
- aDestB[i] = static_cast<Elem&&>( t );
+ Elem t = static_cast<Elem&&>( arrayA[i] );
+ arrayA[i] = static_cast<Elem&&>( arrayB[i] );
+ arrayB[i] = static_cast<Elem&&>( t );
}
}
/**
- * Swap elements of two same-size static arrays.
+ * Swap elements of two same-length static arrays.
*/
template <typename Elem, int COUNT>
-inline void aSwap( Elem ( & aDestA )[COUNT], Elem ( & aDestB )[COUNT] )
+inline void aSwap( Elem ( & arrayA )[COUNT], Elem ( & arrayB )[COUNT] )
{
for( int i = 0; i < COUNT; ++i ) {
- Elem t = static_cast<Elem&&>( aDestA[i] );
- aDestA[i] = static_cast<Elem&&>( aDestB[i] );
- aDestB[i] = static_cast<Elem&&>( t );
+ Elem t = static_cast<Elem&&>( arrayA[i] );
+ arrayA[i] = static_cast<Elem&&>( arrayB[i] );
+ arrayB[i] = static_cast<Elem&&>( t );
}
}
@@ -304,10 +304,10 @@ inline void aSwap( Elem ( & aDestA )[COUNT], Elem ( & aDestB )[COUNT] )
* True iff respective elements are equal.
*/
template <typename Elem>
-inline bool aEquals( const Elem* aSrcA, const Elem* aSrcB, int count )
+inline bool aEquals( const Elem* arrayA, const Elem* arrayB, int count )
{
for( int i = 0; i < count; ++i ) {
- if( !( aSrcA[i] == aSrcB[i] ) ) {
+ if( !( arrayA[i] == arrayB[i] ) ) {
return false;
}
}
@@ -318,10 +318,10 @@ inline bool aEquals( const Elem* aSrcA, const Elem* aSrcB, int count )
* True iff the given value is found in the array.
*/
template <typename Elem, typename Value = Elem>
-inline bool aContains( const Elem* aSrc, const Value& value, int count )
+inline bool aContains( const Elem* array, const Value& value, int count )
{
for( int i = 0; i < count; ++i ) {
- if( aSrc[i] == value ) {
+ if( array[i] == value ) {
return true;
}
}
@@ -332,11 +332,11 @@ inline bool aContains( const Elem* aSrc, const Value& value, int count )
* Pointer to the first occurrence or `nullptr` if not found.
*/
template <typename Elem, typename Value = Elem>
-inline Elem* aFind( Elem* aSrc, const Value& value, int count )
+inline Elem* aFind( Elem* array, const Value& value, int count )
{
for( int i = 0; i < count; ++i ) {
- if( aSrc[i] == value ) {
- return &aSrc[i];
+ if( array[i] == value ) {
+ return &array[i];
}
}
return nullptr;
@@ -346,11 +346,11 @@ inline Elem* aFind( Elem* aSrc, const Value& value, int count )
* Pointer to the last occurrence or `nullptr` if not found.
*/
template <typename Elem, typename Value = Elem>
-inline Elem* aFindLast( Elem* aSrc, const Value& value, int count )
+inline Elem* aFindLast( Elem* array, const Value& value, int count )
{
for( int i = count - 1; i >= 0; --i ) {
- if( aSrc[i] == value ) {
- return &aSrc[i];
+ if( array[i] == value ) {
+ return &array[i];
}
}
return nullptr;
@@ -360,10 +360,10 @@ inline Elem* aFindLast( Elem* aSrc, const Value& value, int count )
* Index of the first occurrence of the value or -1 if not found.
*/
template <typename Elem, typename Value = Elem>
-inline int aIndex( const Elem* aSrc, const Value& value, int count )
+inline int aIndex( const Elem* array, const Value& value, int count )
{
for( int i = 0; i < count; ++i ) {
- if( aSrc[i] == value ) {
+ if( array[i] == value ) {
return i;
}
}
@@ -374,10 +374,10 @@ inline int aIndex( const Elem* aSrc, const Value& value, int count )
* Index of the last occurrence of the value or -1 if not found.
*/
template <typename Elem, typename Value = Elem>
-inline int aLastIndex( const Elem* aSrc, const Value& value, int count )
+inline int aLastIndex( const Elem* array, const Value& value, int count )
{
for( int i = count - 1; i >= 0; --i ) {
- if( aSrc[i] == value ) {
+ if( array[i] == value ) {
return i;
}
}
@@ -388,50 +388,50 @@ inline int aLastIndex( const Elem* aSrc, const Value& value, int count )
* Delete objects referenced by elements and set all elements to `nullptr`.
*/
template <typename Elem>
-inline void aFree( Elem* aDest, int count )
+inline void aFree( Elem* array, int count )
{
for( int i = 0; i < count; ++i ) {
- delete aDest[i];
- aDest[i] = nullptr;
+ delete array[i];
+ array[i] = nullptr;
}
}
/**
* Reallocate array.
*
- * Allocate new array of `newCount` elements, copy first `count` elements of the source array `aSrc`
- * to the newly created one and delete the source array.
+ * Allocate new array of `length` elements, copy first `count` elements of the source array to the
+ * newly created one and delete the source array.
*
* @return Newly allocated array.
*/
template <typename Elem>
-inline Elem* aReallocate( Elem* aSrc, int count, int newCount )
+inline Elem* aReallocate( Elem* array, int count, int length )
{
- Elem* aNew = nullptr;
+ Elem* newArray = nullptr;
- if( newCount != 0 ) {
- aNew = new Elem[newCount];
+ if( length != 0 ) {
+ newArray = new Elem[length];
for( int i = 0; i < count; ++i ) {
- aNew[i] = static_cast<Elem&&>( aSrc[i] );
+ newArray[i] = static_cast<Elem&&>( array[i] );
}
}
- delete[] aSrc;
+ delete[] array;
- return aNew;
+ return newArray;
}
/**
* Reverse the order of array elements.
*/
template <typename Elem>
-inline void aReverse( Elem* aDest, int count )
+inline void aReverse( Elem* array, int count )
{
int bottom = 0;
int top = count - 1;
while( bottom < top ) {
- swap<Elem>( aDest[bottom], aDest[top] );
+ swap<Elem>( array[bottom], array[top] );
++bottom;
--top;
}
@@ -503,12 +503,12 @@ static void quicksort( Elem* first, Elem* last )
* Sort array using quicksort algorithm.
*/
template <typename Elem>
-inline void aSort( Elem* aSrc, int count )
+inline void aSort( Elem* array, int count )
{
int last = count - 1;
if( last > 0 ) {
- quicksort<Elem>( aSrc, &aSrc[last] );
+ quicksort<Elem>( array, &array[last] );
}
}
@@ -520,23 +520,23 @@ inline void aSort( Elem* aSrc, int count )
*
* If all elements are lesser return `count - 1` and if all elements are greater return -1.
*
- * @param aSrc array.
+ * @param array array of elements.
* @param key the key we are looking for.
* @param count number of elements.
* @return Index of the last element not greater than `key`, -1 otherwise.
*/
template <typename Elem, typename Key = Elem>
-inline int aBisection( Elem* aSrc, const Key& key, int count )
+inline int aBisection( Elem* array, const Key& key, int count )
{
int a = -1;
int b = count;
- // The algorithm ensures that (a == -1 or aSrc[a] <= key) and (b == count or key < aSrc[b]),
+ // The algorithm ensures that (a == -1 or array[a] <= key) and (b == count or key < array[b]),
// so the key may only lie on position a or nowhere.
while( b - a > 1 ) {
int c = ( a + b ) / 2;
- if( key < aSrc[c] ) {
+ if( key < array[c] ) {
b = c;
}
else {
17 src/ozCore/common.hh
View
@@ -117,8 +117,23 @@ namespace oz
{
using std::nullptr_t;
-using std::ptrdiff_t;
using std::size_t;
+using std::ptrdiff_t;
+
+/**
+ * Null pointer type.
+ */
+typedef std::nullptr_t nullptr_t;
+
+/**
+ * Platform-dependent unsigned integer type for memory offsets and sizes.
+ */
+typedef std::size_t size_t;
+
+/**
+ * Platform-dependent signed integer type for memory offsets and pointer differences.
+ */
+typedef std::ptrdiff_t ptrdiff_t;
/**
* Signed byte.
131 src/ozCore/iterables.hh
View
@@ -178,36 +178,51 @@ inline typename Container::Iterator iter( Container& container )
}
/**
- * Copy all elements from `iSrc` to `iDest`.
+ * Count elements.
+ */
+template <class CIterator>
+inline int iLength( CIterator iter )
+{
+ int count = 0;
+
+ while( iter.isValid() ) {
+ ++count;
+ ++iter;
+ }
+ return count;
+}
+
+/**
+ * Copy all elements from `srcIter` to `destIter`.
*/
template <class IteratorA, class CIteratorB>
-inline void iCopy( IteratorA iDest, CIteratorB iSrc )
+inline void iCopy( IteratorA destIter, CIteratorB srcIter )
{
- while( iSrc.isValid() ) {
- hard_assert( iDest.isValid() );
+ while( srcIter.isValid() ) {
+ hard_assert( destIter.isValid() );
- *iDest = *iSrc;
+ *destIter = *srcIter;
- ++iDest;
- ++iSrc;
+ ++destIter;
+ ++srcIter;
}
}
/**
- * Move all elements from `iSrc` to `iDest`.
+ * Move all elements from `srcIter` to `destIter`.
*/
template <class IteratorA, class IteratorB>
-inline void iMove( IteratorA iDest, IteratorB iSrc )
+inline void iMove( IteratorA destIter, IteratorB srcIter )
{
typedef typename IteratorB::ElemType ElemB;
- while( iSrc.isValid() ) {
- hard_assert( iDest.isValid() );
+ while( srcIter.isValid() ) {
+ hard_assert( destIter.isValid() );
- *iDest = static_cast<ElemB&&>( *iSrc );
+ *destIter = static_cast<ElemB&&>( *srcIter );
- ++iDest;
- ++iSrc;
+ ++destIter;
+ ++srcIter;
}
}
@@ -215,12 +230,12 @@ inline void iMove( IteratorA iDest, IteratorB iSrc )
* %Set elements to the given value.
*/
template <class Iterator, typename Value = typename Iterator::ElemType>
-inline void iFill( Iterator iDest, const Value& value )
+inline void iFill( Iterator iter, const Value& value )
{
- while( iDest.isValid() ) {
- *iDest = value;
+ while( iter.isValid() ) {
+ *iter = value;
- ++iDest;
+ ++iter;
}
}
@@ -228,78 +243,78 @@ inline void iFill( Iterator iDest, const Value& value )
* Swap element of two same-length containers.
*/
template <class IteratorA, class IteratorB>
-inline void iSwap( IteratorA iDestA, IteratorB iDestB )
+inline void iSwap( IteratorA iterA, IteratorB iterB )
{
typedef typename IteratorA::ElemType ElemA;
typedef typename IteratorB::ElemType ElemB;
- while( iDestA.isValid() ) {
- hard_assert( iDestB.isValid() );
+ while( iterA.isValid() ) {
+ hard_assert( iterB.isValid() );
- ElemA t = static_cast<ElemA&&>( *iDestA );
- *iDestA = static_cast<ElemB&&>( *iDestB );
- *iDestB = static_cast<ElemA&&>( t );
+ ElemA t = static_cast<ElemA&&>( *iterA );
+ *iterA = static_cast<ElemB&&>( *iterB );
+ *iterB = static_cast<ElemA&&>( t );
- ++iDestA;
- ++iDestB;
+ ++iterA;
+ ++iterB;
}
- hard_assert( !iDestB.isValid() );
+ hard_assert( !iterB.isValid() );
}
/**
* True iff same length and respective elements are equal.
*/
template <class CIteratorA, class CIteratorB>
-inline bool iEquals( CIteratorA iSrcA, CIteratorB iSrcB )
+inline bool iEquals( CIteratorA iterA, CIteratorB iterB )
{
- hard_assert( static_cast<void*>( &iSrcA ) != static_cast<void*>( &iSrcB ) );
+ hard_assert( static_cast<void*>( &iterA ) != static_cast<void*>( &iterB ) );
- while( iSrcA.isValid() && iSrcB.isValid() && *iSrcA == *iSrcB ) {
- ++iSrcA;
- ++iSrcB;
+ while( iterA.isValid() && iterB.isValid() && *iterA == *iterB ) {
+ ++iterA;
+ ++iterB;
}
- return !iSrcA.isValid() && !iSrcB.isValid();
+ return !iterA.isValid() && !iterB.isValid();
}
/**
* True iff the given value is found in the container.
*/
template <class CIterator, typename Value = typename CIterator::ElemType>
-inline bool iContains( CIterator iSrc, const Value& value )
+inline bool iContains( CIterator iter, const Value& value )
{
- while( iSrc.isValid() && !( *iSrc == value ) ) {
- ++iSrc;
+ while( iter.isValid() && !( *iter == value ) ) {
+ ++iter;
}
- return iSrc.isValid();
+ return iter.isValid();
}
/**
* %Iterator for the first occurrence or an invalid iterator if not found.
*/
template <class Iterator, typename Value = typename Iterator::ElemType>
-inline Iterator iFind( Iterator iSrc, const Value& value )
+inline Iterator iFind( Iterator iter, const Value& value )
{
- while( iSrc.isValid() && !( *iSrc == value ) ) {
- ++iSrc;
+ while( iter.isValid() && !( *iter == value ) ) {
+ ++iter;
}
- return iSrc;
+ return iter;
}
/**
* %Iterator for the last occurrence or an invalid iterator if not found.
*/
template <class Iterator, typename Value = typename Iterator::ElemType>
-inline Iterator iFindLast( Iterator iSrc, const Value& value )
+inline Iterator iFindLast( Iterator iter, const Value& value )
{
Iterator lastOccurence;
- while( iSrc.isValid() ) {
- if( *iSrc == value ) {
- lastOccurence = iSrc;
+ while( iter.isValid() ) {
+ if( *iter == value ) {
+ lastOccurence = iter;
}
- ++iSrc;
+ ++iter;
}
return lastOccurence;
}
@@ -308,32 +323,32 @@ inline Iterator iFindLast( Iterator iSrc, const Value& value )
* Index of the first occurrence of the value or -1 if not found.
*/
template <class CIterator, typename Value = typename CIterator::ElemType>
-inline int iIndex( CIterator iSrc, const Value& value )
+inline int iIndex( CIterator iter, const Value& value )
{
int index = 0;
- while( iSrc.isValid() && !( *iSrc == value ) ) {
- ++iSrc;
+ while( iter.isValid() && !( *iter == value ) ) {
+ ++iter;
++index;
}
- return !iSrc.isValid() ? -1 : index;
+ return !iter.isValid() ? -1 : index;
}
/**
* Index of the last occurrence of the value or -1 if not found.
*/
template <class CIterator, typename Value = typename CIterator::ElemType>
-inline int iLastIndex( CIterator iSrc, const Value& value )
+inline int iLastIndex( CIterator iter, const Value& value )
{
int index = 0;
int lastIndex = -1;
- while( iSrc.isValid() ) {
- if( *iSrc == value ) {
+ while( iter.isValid() ) {
+ if( *iter == value ) {
lastIndex = index;
}
- ++iSrc;
+ ++iter;
++index;
}
return lastIndex;
@@ -343,13 +358,13 @@ inline int iLastIndex( CIterator iSrc, const Value& value )
* Delete objects referenced by elements and set all elements to `nullptr`.
*/
template <class Iterator>
-inline void iFree( Iterator iDest )
+inline void iFree( Iterator iter )
{
typedef typename Iterator::ElemType Elem;
- while( iDest.isValid() ) {
- Elem& elem = *iDest;
- ++iDest;
+ while( iter.isValid() ) {
+ Elem& elem = *iter;
+ ++iter;
delete elem;
elem = nullptr;
40 src/ozEngine/ALBuffer.cc
View
@@ -81,12 +81,44 @@ ALBuffer::~ALBuffer()
destroy();
}
+ALSource ALBuffer::createSource() const
+{
+ ALSource source;
+
+ if( bufferId == 0 ) {
+ return source;
+ }
+
+ source.create();
+
+ if( source.isCreated() ) {
+ alSourcei( source.id(), AL_BUFFER, int( bufferId ) );
+ }
+ return source;
+}
+
+bool ALBuffer::create()
+{
+ destroy();
+
+ alGenBuffers( 1, &bufferId );
+ return bufferId != 0;
+}
+
bool ALBuffer::load( const File& file )
{
destroy();
- Buffer buffer = file.read();
- InputStream istream = buffer.inputStream();
+ Buffer buffer;
+ InputStream istream;
+
+ if( file.isMapped() ) {
+ istream = file.inputStream();
+ }
+ else {
+ buffer = file.read();
+ istream = buffer.inputStream();
+ }
if( !istream.isAvailable() ) {
return false;
@@ -184,7 +216,7 @@ bool ALBuffer::load( const File& file )
ov_clear( &ovStream );
OZ_AL_CHECK_ERROR();
- return true;
+ return bufferId != 0;
}
}
@@ -193,8 +225,6 @@ void ALBuffer::destroy()
if( bufferId != 0 ) {
alDeleteBuffers( 1, &bufferId );
bufferId = 0;
-
- OZ_AL_CHECK_ERROR();
}
}
12 src/ozEngine/ALBuffer.hh
View
@@ -26,7 +26,7 @@
#pragma once
-#include "common.hh"
+#include "ALSource.hh"
namespace oz
{
@@ -98,6 +98,16 @@ class ALBuffer
}
/**
+ * Create a new OpenAL source for this buffer.
+ */
+ ALSource createSource() const;
+
+ /**
+ * Create a new uninitialised OpenAL buffer.
+ */
+ bool create();
+
+ /**
* Create a new OpenAL buffer from the given WAVE or Ogg Vorbis file.
*/
bool load( const File& file );
30 src/ozEngine/ALSource.cc
View
@@ -35,33 +35,23 @@ ALSource::ALSource() :
sourceId( 0 )
{}
-ALSource::ALSource( const ALBuffer& buffer ) :
- sourceId( 0 )
-{
- create( buffer );
-}
-
ALSource::~ALSource()
{
destroy();
}
-bool ALSource::create( const ALBuffer& buffer )
+bool ALSource::create()
{
- destroy();
-
- if( !buffer.isLoaded() ) {
- return false;
- }
-
alGenSources( 1, &sourceId );
- alSourcei( sourceId, AL_BUFFER, int( buffer.id() ) );
-
- // This is not necessary by specification but it seems it's always the case with openalsoft.
- hard_assert( sourceId != 0 );
- OZ_AL_CHECK_ERROR();
- return true;
+ if( alGetError() != AL_NO_ERROR ) {
+ sourceId = 0;
+ }
+ else {
+ // This is not necessary by specification but it seems it's always the case with openalsoft.
+ hard_assert( sourceId != 0 );
+ }
+ return sourceId != 0;
}
void ALSource::destroy()
@@ -69,8 +59,6 @@ void ALSource::destroy()
if( sourceId != 0 ) {
alDeleteSources( 1, &sourceId );
sourceId = 0;
-
- OZ_AL_CHECK_ERROR();
}
}
13 src/ozEngine/ALSource.hh
View
@@ -26,7 +26,7 @@
#pragma once
-#include "ALBuffer.hh"
+#include "common.hh"
namespace oz
{
@@ -48,11 +48,6 @@ class ALSource
explicit ALSource();
/**
- * Create a new source for the given buffer. Same as the default constructor plus `create()`.
- */
- explicit ALSource( const ALBuffer& buffer );
-
- /**
* Destructor, destroys OpenAL source if created.
*/
~ALSource();
@@ -75,6 +70,8 @@ class ALSource
return *this;
}
+ destroy();
+
sourceId = s.sourceId;
s.sourceId = 0;
@@ -98,9 +95,9 @@ class ALSource
}
/**
- * Create a new OpenAL source for the given OpenAL buffer.
+ * Create a new uninitialised OpenAL source.
*/
- bool create( const ALBuffer& buffer );
+ bool create();
/**
* Destroy OpenAL source if created.
141 src/ozEngine/ALStreamingBuffer.cc
View
@@ -0,0 +1,141 @@
+/*
+ * ozEngine - OpenZone Engine Library.
+ *
+ * Copyright © 2002-2013 Davorin Učakar
+ *
+ * This software is provided 'as-is', without any express or implied warranty.
+ * In no event will the authors be held liable for any damages arising from
+ * the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ * claim that you wrote the original software. If you use this software in
+ * a product, an acknowledgement in the product documentation would be
+ * appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ * misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ */
+
+/**
+ * @file ozEngine/ALStreamingBuffer.cc
+ */
+
+#include "ALStreamingBuffer.hh"
+
+#include "OpenAL.hh"
+
+// We don't use those callbacks anywhere and they don't compile on MinGW.
+#define OV_EXCLUDE_STATIC_CALLBACKS
+#include <vorbis/vorbisfile.h>
+
+namespace oz
+{
+
+static size_t vorbisRead( void* buffer, size_t size, size_t n, void* handle )
+{
+ InputStream* istream = static_cast<InputStream*>( handle );
+
+ int blockSize = int( size );
+ int nBlocks = min( int( n ), istream->available() / blockSize );
+
+ istream->readChars( static_cast<char*>( buffer ), nBlocks * blockSize );
+ return size_t( nBlocks );
+}
+
+static int vorbisSeek( void* handle, ogg_int64_t offset, int whence )
+{
+ InputStream* istream = static_cast<InputStream*>( handle );
+
+ const char* origin = whence == SEEK_CUR ? istream->pos() :
+ whence == SEEK_END ? istream->end() : istream->begin();
+
+ istream->set( origin + offset );
+ return 0;
+}
+
+static long vorbisTell( void* handle )
+{
+ InputStream* istream = static_cast<InputStream*>( handle );
+
+ return long( istream->tell() );
+}
+
+static ov_callbacks VORBIS_CALLBACKS = { vorbisRead, vorbisSeek, nullptr, vorbisTell };
+
+ALStreamingBuffer::ALStreamingBuffer()
+{
+ bufferIds[0] = 0;
+ bufferIds[1] = 0;
+ sourceId = 0;
+}
+
+ALStreamingBuffer::ALStreamingBuffer( const File& file )
+{
+ bufferIds[0] = 0;
+ bufferIds[1] = 0;
+ sourceId = 0;
+
+ load( file );
+}
+
+ALStreamingBuffer::~ALStreamingBuffer()
+{
+ destroy();
+}
+
+ALSource ALStreamingBuffer::createSource()
+{
+ ALSource source;
+
+ if( bufferIds[0] == 0 ) {
+ return source;
+ }
+
+ source.create();
+
+ if( source.isCreated() ) {
+ sourceId = source.id();
+ alSourceQueueBuffers( source.id(), 2, bufferIds );
+ }
+ return source;
+}
+
+void ALStreamingBuffer::detachSource()
+{
+ if( sourceId == 0 ) {
+ return;
+ }
+
+ alSourceStop( sourceId );
+ alSourceUnqueueBuffers( sourceId, 2, bufferIds );
+ sourceId = 0;
+}
+
+void ALStreamingBuffer::update()
+{
+
+}
+
+bool ALStreamingBuffer::load( const File& file )
+{
+ destroy();
+
+ return true;
+}
+
+void ALStreamingBuffer::destroy()
+{
+ if( bufferIds[0] != 0 ) {
+ detachSource();
+
+ alDeleteBuffers( 2, bufferIds );
+ bufferIds[0] = 0;
+ bufferIds[1] = 0;
+ }
+}
+
+}
155 src/ozEngine/ALStreamingBuffer.hh
View
@@ -0,0 +1,155 @@
+/*
+ * ozEngine - OpenZone Engine Library.
+ *
+ * Copyright © 2002-2013 Davorin Učakar
+ *
+ * This software is provided 'as-is', without any express or implied warranty.
+ * In no event will the authors be held liable for any damages arising from
+ * the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ * claim that you wrote the original software. If you use this software in
+ * a product, an acknowledgement in the product documentation would be
+ * appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ * misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ */
+
+/**
+ * @file ozEngine/ALStreamingBuffer.hh
+ */
+
+#pragma once
+
+#include "ALSource.hh"
+
+namespace oz
+{
+
+/**
+ * Wrapper for a queue of two OpenAL buffers for streaming an Ogg Vorbis file.
+ */
+class ALStreamingBuffer
+{
+ private:
+
+ Buffer fileBuffer; ///< Contents of the streamed Ogg Vorbis file.
+ uint bufferIds[2]; ///< OpenAL buffer ids, both 0 if not loaded.
+ uint sourceId; ///< Target OpenAL source for which buffers are queued.
+
+ public:
+
+ /**
+ * Create an empty instance (no OpenAL buffers are created).
+ */
+ explicit ALStreamingBuffer();
+
+ /**
+ * Create a new buffer from the given file. Same as the default constructor plus `load()`.
+ */
+ explicit ALStreamingBuffer( const File& file );
+
+ /**
+ * Destructor, destroys OpenAL buffers if created.
+ */
+ ~ALStreamingBuffer();
+
+ /**
+ * Move constructor.
+ */
+ ALStreamingBuffer( ALStreamingBuffer&& b )
+ {
+ fileBuffer = static_cast<Buffer&&>( b.fileBuffer );
+ bufferIds[0] = b.bufferIds[0];
+ bufferIds[1] = b.bufferIds[1];
+ sourceId = b.sourceId;
+
+ b.bufferIds[0] = 0;
+ b.bufferIds[1] = 0;
+ b.sourceId = 0;
+ }
+
+ /**
+ * Move operator.
+ */
+ ALStreamingBuffer& operator = ( ALStreamingBuffer&& b )
+ {
+ if( &b == this ) {
+ return *this;
+ }
+
+ fileBuffer = static_cast<Buffer&&>( b.fileBuffer );
+ bufferIds[0] = b.bufferIds[0];
+ bufferIds[1] = b.bufferIds[1];
+ sourceId = b.sourceId;
+
+ b.bufferIds[0] = 0;
+ b.bufferIds[1] = 0;
+ b.sourceId = 0;
+
+ return *this;
+ }
+
+ /**
+ * Get OpenAL buffer id.
+ */
+ uint id( int i ) const
+ {
+ hard_assert( 0 <= i && i < 2 );
+
+ return bufferIds[i];
+ }
+
+ /**
+ * True iff loaded.
+ */
+ bool isLoaded() const
+ {
+ return bufferIds[0] != 0;
+ }
+
+ /**
+ * Create a new source and attach it to this buffer queue.
+ *
+ * Streaming only works for the attached source (the last source created by this function).
+ */
+ ALSource createSource();
+
+ /**
+ * Detach last created source.
+ *
+ * Forgets the last created source and stops queuing buffers for it.
+ */
+ void detachSource();
+
+ /**
+ * Update buffers and queue for the attached source.
+ *
+ * If a buffer has been processed, unqueues it, fills it with new data and puts it back into
+ * the queue. This is a NOP if no source is attached.
+ */
+ void update();
+
+ /**
+ * Create a new uninitialised OpenAL buffers for queuing.
+ */
+ bool create();
+
+ /**
+ * Create a new buffer queue from the given Ogg Vorbis file.
+ */
+ bool load( const File& file );
+
+ /**
+ * Destroy OpenAL buffers if created and detach the source if attached.
+ */
+ void destroy();
+
+};
+
+}
2  src/ozEngine/CMakeLists.txt
View
@@ -6,6 +6,7 @@ add_library( ozEngine
#BEGIN SOURCES
ALBuffer.hh
ALSource.hh
+ ALStreamingBuffer.hh
common.hh
GLTexture.hh
OpenAL.hh
@@ -16,6 +17,7 @@ add_library( ozEngine
Window.hh
ALBuffer.cc
ALSource.cc
+ ALStreamingBuffer.cc
common.cc
GLTexture.cc
OpenAL.cc
78 src/ozEngine/GLTexture.cc
View
@@ -36,6 +36,7 @@ static const int DDSD_MIPMAPCOUNT_BIT = 0x00020000;
static const int DDSD_LINEARSIZE_BIT = 0x00080000;
static const int DDPF_ALPHAPIXELS = 0x00000001;
static const int DDPF_FOURCC = 0x00000004;
+static const int DDPF_RGB = 0x00000040;
#if 0
bool GLTexture::build( const File& file, int options, OutputStream* ostream )
@@ -242,8 +243,16 @@ bool GLTexture::load( const File& file )
{
destroy();
- Buffer buffer = file.read();
- InputStream istream = buffer.inputStream();
+ Buffer buffer;
+ InputStream istream;
+
+ if( file.isMapped() ) {
+ istream = file.inputStream();
+ }
+ else {
+ buffer = file.read();
+ istream = buffer.inputStream();
+ }
// Implementation is based on specifications from
// http://msdn.microsoft.com/en-us/library/windows/desktop/bb943991%28v=vs.85%29.aspx.
@@ -255,8 +264,8 @@ bool GLTexture::load( const File& file )
istream.readInt();
int flags = istream.readInt();
- int width = istream.readInt();
int height = istream.readInt();
+ int width = istream.readInt();
int pitch = istream.readInt();
istream.readInt();
@@ -284,6 +293,10 @@ bool GLTexture::load( const File& file )
textureFormat = GL_COMPRESSED_RGB_S3TC_DXT1_EXT;
baseBlock = 8;
}
+ else if( String::beginsWith( format, "DXT3" ) ) {
+ textureFormat = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
+ baseBlock = 16;
+ }
else if( String::beginsWith( format, "DXT5" ) ) {
textureFormat = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
baseBlock = 16;
@@ -293,36 +306,75 @@ bool GLTexture::load( const File& file )
return false;
}
}
- else {
+ else if( pixelFlags & DDPF_RGB ) {
textureFormat = pixelFlags & DDPF_ALPHAPIXELS ? GL_RGBA : GL_RGB;
baseBlock = 1;
}
+ else {
+ textureMipmaps = 0;
+ return false;
+ }
istream.seek( 4 + 124 );
+ int mipmapWidth = width;
+ int mipmapHeight = height;
+ int mipmapPitch = pitch;
+ int mipmapSize = pixelFlags & DDPF_FOURCC ? pitch : height * pitch;
+ char* mipmapData = pixelFlags & DDPF_FOURCC ? nullptr : new char[mipmapSize];
+
glGenTextures( 1, &textureId );
glBindTexture( GL_TEXTURE_2D, textureId );
- int mipmapWidth = width;
- int mipmapHeight = height;
- int mipmapSize = pixelFlags & DDPF_FOURCC ? pitch : width * height * ( bpp / 8 );
+ // Default minification filter in OpenGL is crappy GL_NEAREST_MIPMAP_LINEAR not regarding whether
+ // texture actually has mipmaps.
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
+ textureMipmaps == 1 ? GL_LINEAR : GL_LINEAR_MIPMAP_LINEAR );
for( int i = 0; i < textureMipmaps; ++i ) {
if( pixelFlags & DDPF_FOURCC ) {
glCompressedTexImage2D( GL_TEXTURE_2D, i, textureFormat, mipmapWidth, mipmapHeight, 0,
mipmapSize, istream.forward( mipmapSize ) );
+
+ mipmapWidth /= 2;
+ mipmapHeight /= 2;
+ mipmapSize /= 4;
+ mipmapSize = max( mipmapSize, baseBlock );
}
else {
+ char* data = mipmapData;
+ const char* source = istream.forward( mipmapSize );
+ int pixelSize = bpp / 8;
+
+ for( int j = 0; j < mipmapHeight; ++j ) {
+ for( int k = 0; k < mipmapWidth; ++k ) {
+ data[0] = source[2];
+ data[1] = source[1];
+ data[2] = source[0];
+
+ if( bpp == 32 ) {
+ data[3] = source[3];
+ }
+
+ data += pixelSize;
+ source += pixelSize;
+ }
+
+ source += mipmapPitch - mipmapWidth * pixelSize;
+ }
+
glTexImage2D( GL_TEXTURE_2D, i, int( textureFormat ), mipmapWidth, mipmapHeight, 0,
- textureFormat, GL_UNSIGNED_BYTE, istream.forward( mipmapSize ) );
- }
+ textureFormat, GL_UNSIGNED_BYTE, mipmapData );
- mipmapWidth /= 2;
- mipmapHeight /= 2;
- mipmapSize /= 4;
- mipmapSize = max( mipmapSize, baseBlock );
+ mipmapWidth /= 2;
+ mipmapHeight /= 2;
+ mipmapPitch = ( mipmapWidth * bpp + 7 ) / 8;
+ mipmapSize = mipmapPitch * mipmapHeight;
+ }
}
+ delete[] mipmapData;
+
OZ_GL_CHECK_ERROR();
return true;
}
2  src/ozEngine/Window.cc
View
@@ -322,7 +322,7 @@ bool Window::create( const char* title, int width_, int height_, bool fullscreen
#endif
- Log::printEnd( " %dx%d ... OK", width, height );
+ Log::printEnd( "%dx%d ... OK", width, height );
glViewport( 0, 0, width, height );
glClearColor( 0.0f, 0.0f, 0.0f, 1.0f );
1  src/ozEngine/ozEngine.hh
View
@@ -36,6 +36,7 @@
#include "GLTexture.hh"
#include "ALBuffer.hh"
+#include "ALStreamingBuffer.hh"
#include "ALSource.hh"
#include "Window.hh"
32 src/tests/test.cc
View
@@ -24,6 +24,8 @@
#include <ozCore/ozCore.hh>
#include <ozEngine/ozEngine.hh>
#include <SDL.h>
+#include <AL/alc.h>
+#include <vector>
using namespace oz;
@@ -33,20 +35,25 @@ int main( int argc, char** argv )
SDL_Init( SDL_INIT_VIDEO );
Window::create( "Test", 1024, 768, false );
- File dds( argc < 2 ? "skin.dds" : argv[1] );
- GLTexture texture( dds );
+ ALCdevice* device = alcOpenDevice( nullptr );
+ ALCcontext* context = alcCreateContext( device, nullptr );
+ alcMakeContextCurrent( context );
+
+ ALBuffer buffer( "/usr/share/sounds/Kopete_Received.ogg" );
+ ALSource source = buffer.createSource();
- glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
- glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
+ hard_assert( source.id() != 0 );
+ alSourcePlay( source.id() );
- Log() << texture.id() << "\n";
+ File dds( argc < 2 ? "mail.dds" : argv[1] );
+ GLTexture texture( dds );
bool isAlive = true;
while( isAlive ) {
SDL_Event event;
SDL_PollEvent( &event );
- if( event.type == SDL_QUIT ) {
+ if( event.type == SDL_QUIT || event.type == SDL_KEYDOWN ) {
isAlive = false;
}
@@ -57,16 +64,21 @@ int main( int argc, char** argv )
glBindTexture( GL_TEXTURE_2D, texture.id() );
glBegin( GL_QUADS );
- glTexCoord2i( 0, 1 ); glVertex2d( -0.5, -0.5 );
- glTexCoord2i( 1, 1 ); glVertex2d( +0.5, -0.5 );
- glTexCoord2i( 1, 0 ); glVertex2d( +0.5, +0.5 );
- glTexCoord2i( 0, 0 ); glVertex2d( -0.5, +0.5 );
+ glTexCoord2i( 0, 1 ); glVertex2d( -1, -1 );
+ glTexCoord2i( 1, 1 ); glVertex2d( +1, -1 );
+ glTexCoord2i( 1, 0 ); glVertex2d( +1, +1 );
+ glTexCoord2i( 0, 0 ); glVertex2d( -1, +1 );
glEnd();
Window::swapBuffers();
Time::sleep( 10 );
}
+ source.destroy();
+ buffer.destroy();
+
+ alcDestroyContext( context );
+ alcCloseDevice( device );
Window::destroy();
SDL_Quit();
return 0;
Please sign in to comment.
Something went wrong with that request. Please try again.