1 | /* |
---|
2 | orxonox - the future of 3D-vertical-scrollers |
---|
3 | |
---|
4 | Copyright (C) 2006 orx |
---|
5 | |
---|
6 | This program is free software; you can redistribute it and/or modify |
---|
7 | it under the terms of the GNU General Public License as published by |
---|
8 | the Free Software Foundation; either version 2, or (at your option) |
---|
9 | any later version. |
---|
10 | |
---|
11 | ### File Specific: |
---|
12 | main programmer: Marco Biasini |
---|
13 | |
---|
14 | */ |
---|
15 | |
---|
16 | #ifndef _BUFFERBROKER_H |
---|
17 | #define _BUFFERBROKER_H |
---|
18 | |
---|
19 | #include "glincl.h" |
---|
20 | #include "debug.h" |
---|
21 | #include "types.h" |
---|
22 | /** |
---|
23 | * @brief Manages the streaming of the vertex buffer objects for the terrain page. |
---|
24 | */ |
---|
25 | |
---|
26 | struct BufferPair { |
---|
27 | BufferPair( int _i, int _v ) { indexName = _i; vertexName = _v; next = NULL; } |
---|
28 | BufferPair() { indexName = vertexName = 0; next = NULL; } |
---|
29 | GLuint indexName; |
---|
30 | GLuint vertexName; |
---|
31 | BufferPair *next; |
---|
32 | }; |
---|
33 | |
---|
34 | typedef BufferPair *pBufferPair; |
---|
35 | |
---|
36 | class BufferBroker { |
---|
37 | public: |
---|
38 | |
---|
39 | BufferBroker( int _num, int _vbSize, int _ibSize ) |
---|
40 | { |
---|
41 | capacity = _num; |
---|
42 | freeIndexBuffers = new GLuint[capacity]; |
---|
43 | freeVertexBuffers = new GLuint[capacity]; |
---|
44 | lastAcquired = 0; |
---|
45 | vbSize = _vbSize; ibSize = _ibSize; |
---|
46 | glGenBuffersARB( capacity, freeIndexBuffers ); |
---|
47 | glGenBuffersARB( capacity, freeVertexBuffers ); |
---|
48 | for ( int i = 0; i < capacity; ++i ) { |
---|
49 | glBindBufferARB( GL_ARRAY_BUFFER_ARB, freeVertexBuffers[i] ); |
---|
50 | glBufferDataARB( GL_ARRAY_BUFFER_ARB, vbSize, |
---|
51 | NULL, GL_DYNAMIC_DRAW_ARB ); |
---|
52 | glBindBufferARB( GL_ELEMENT_ARRAY_BUFFER_ARB, freeIndexBuffers[i] ); |
---|
53 | glBufferDataARB( GL_ELEMENT_ARRAY_BUFFER_ARB, ibSize, |
---|
54 | NULL, GL_DYNAMIC_DRAW_ARB ); |
---|
55 | } |
---|
56 | head = tail = NULL; |
---|
57 | } |
---|
58 | ~BufferBroker() |
---|
59 | { |
---|
60 | pBufferPair bp = head; |
---|
61 | while ( bp ) { |
---|
62 | pBufferPair tmp = bp->next; |
---|
63 | release( bp->vertexName, bp->indexName ); |
---|
64 | bp = tmp; |
---|
65 | } |
---|
66 | glDeleteBuffersARB( capacity, freeVertexBuffers ); |
---|
67 | glDeleteBuffersARB( capacity, freeIndexBuffers ); |
---|
68 | SAVE_DELETE_ARRAY( freeIndexBuffers ); |
---|
69 | SAVE_DELETE_ARRAY( freeVertexBuffers ); |
---|
70 | } |
---|
71 | inline int getIBSize() { return ibSize; } |
---|
72 | inline int getVBSize() { return vbSize; } |
---|
73 | inline void acquire( GLuint &_vbName, GLuint &_ibName ); |
---|
74 | |
---|
75 | inline void release( const GLuint &_vbName, const GLuint &_ibName ); |
---|
76 | protected: |
---|
77 | |
---|
78 | int capacity; |
---|
79 | |
---|
80 | int vbSize, |
---|
81 | ibSize; |
---|
82 | int lastAcquired; |
---|
83 | |
---|
84 | GLuint *freeIndexBuffers, |
---|
85 | *freeVertexBuffers; |
---|
86 | |
---|
87 | BufferPair *head, *tail; |
---|
88 | }; |
---|
89 | |
---|
90 | inline void BufferBroker::release( const GLuint &_vbName, const GLuint &_ibName ) |
---|
91 | { |
---|
92 | pBufferPair bp = head, prev = NULL; |
---|
93 | bool removed = false; |
---|
94 | while ( bp ) { |
---|
95 | |
---|
96 | if ( bp->indexName == _ibName && bp->vertexName == _vbName ) { |
---|
97 | if ( prev ) { |
---|
98 | prev->next = bp->next; |
---|
99 | } |
---|
100 | else { |
---|
101 | head = bp->next; |
---|
102 | } |
---|
103 | if ( bp->next == NULL ) |
---|
104 | tail = prev; |
---|
105 | int index = capacity-lastAcquired; |
---|
106 | lastAcquired--; |
---|
107 | freeIndexBuffers[index] = bp->indexName; |
---|
108 | freeVertexBuffers[index] = bp->vertexName; |
---|
109 | delete bp; |
---|
110 | removed = true; |
---|
111 | break; |
---|
112 | } |
---|
113 | prev = bp; |
---|
114 | bp = bp->next; |
---|
115 | } |
---|
116 | assert( removed ); |
---|
117 | } |
---|
118 | |
---|
119 | inline void BufferBroker::acquire( GLuint &_vbName, GLuint &_ibName ) |
---|
120 | { |
---|
121 | assert( capacity > lastAcquired ); |
---|
122 | int index = capacity-lastAcquired-1; |
---|
123 | _vbName = freeVertexBuffers[index]; _ibName = freeIndexBuffers[index]; |
---|
124 | lastAcquired++; |
---|
125 | if ( tail ) { |
---|
126 | tail->next = new BufferPair( _ibName, _vbName ); |
---|
127 | tail = tail->next; |
---|
128 | } |
---|
129 | else { |
---|
130 | tail = head = new BufferPair( _ibName, _vbName ); |
---|
131 | } |
---|
132 | } |
---|
133 | |
---|
134 | typedef BufferBroker *pBufferBroker; |
---|
135 | |
---|
136 | #endif |
---|