/* orxonox - the future of 3D-vertical-scrollers Copyright (C) 2006 orx This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. ### File Specific: main programmer: Marco Biasini */ #ifndef _BUFFERBROKER_H #define _BUFFERBROKER_H #include "glincl.h" #include "debug.h" /** * @brief Manages the streaming of the vertex buffer objects for the terrain page. */ struct BufferPair { BufferPair( int _i, int _v ) { indexName = _i; vertexName = _v; next = NULL; } BufferPair() { indexName = vertexName = 0; next = NULL; } GLuint indexName; GLuint vertexName; BufferPair *next; }; typedef BufferPair *pBufferPair; class BufferBroker { public: BufferBroker( int _num, int _vbSize, int _ibSize ) { capacity = _num; freeIndexBuffers = new GLuint[capacity]; freeVertexBuffers = new GLuint[capacity]; lastAcquired = 0; vbSize = _vbSize; ibSize = _ibSize; glGenBuffersARB( capacity, freeIndexBuffers ); glGenBuffersARB( capacity, freeVertexBuffers ); for ( int i = 0; i < capacity; ++i ) { glBindBufferARB( GL_ARRAY_BUFFER_ARB, freeVertexBuffers[i] ); glBufferDataARB( GL_ARRAY_BUFFER_ARB, vbSize, NULL, GL_DYNAMIC_DRAW_ARB ); glBindBufferARB( GL_ELEMENT_ARRAY_BUFFER_ARB, freeIndexBuffers[i] ); glBufferDataARB( GL_ELEMENT_ARRAY_BUFFER_ARB, ibSize, NULL, GL_DYNAMIC_DRAW_ARB ); } head = tail = NULL; } inline void acquire( GLuint &_vbName, GLuint &_ibName ); inline void release( const GLuint &_vbName, const GLuint &_ibName ); protected: int capacity; int vbSize, ibSize; int lastAcquired; GLuint *freeIndexBuffers, *freeVertexBuffers; BufferPair *head, *tail; }; inline void BufferBroker::release( const GLuint &_vbName, const GLuint &_ibName ) { pBufferPair bp = head, prev = NULL; bool removed = false; while ( bp ) { if ( bp->indexName == _ibName && bp->vertexName == _vbName ) { if ( prev ) { prev->next = bp->next; } else { head = bp->next; } if ( bp->next == NULL ) tail = prev; int index = capacity-lastAcquired; lastAcquired--; freeIndexBuffers[index] = bp->indexName; freeVertexBuffers[index] = bp->vertexName; delete bp; removed = true; break; } prev = bp; bp = bp->next; } assert( removed ); } inline void BufferBroker::acquire( GLuint &_vbName, GLuint &_ibName ) { int index = capacity-lastAcquired-1; _vbName = freeVertexBuffers[index]; _ibName = freeIndexBuffers[index]; lastAcquired++; if ( tail ) { tail->next = new BufferPair( _ibName, _vbName ); tail = tail->next; } else { tail = head = new BufferPair( _ibName, _vbName ); } } typedef BufferBroker *pBufferBroker; #endif