Basic Image AlgorithmS Library  2.8.0
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
glfBatch.cpp
1 /*
2  This file is part of the BIAS library (Basic ImageAlgorithmS).
3 
4  Copyright (C) 2003-2009 (see file CONTACT for details)
5  Multimediale Systeme der Informationsverarbeitung
6  Institut fuer Informatik
7  Christian-Albrechts-Universitaet Kiel
8 
9 
10  BIAS is free software; you can redistribute it and/or modify
11  it under the terms of the GNU Lesser General Public License as published by
12  the Free Software Foundation; either version 2.1 of the License, or
13  (at your option) any later version.
14 
15  BIAS is distributed in the hope that it will be useful,
16  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18  GNU Lesser General Public License for more details.
19 
20  You should have received a copy of the GNU Lesser General Public License
21  along with BIAS; if not, write to the Free Software
22  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23  */
24 
25 #include "glfBatch.hh"
26 #include "glfScreen.hh"
27 #include "glfException.hh"
28 
29 using namespace BIAS;
30 
31 const GLenum INVALID_PRIMITIVE_TYPE = 0xffffffff;
32 
34  MAX_TEXTURE_UNITS_(-1),
35  MAX_TEXTURE_COORDS_(-1),
36  initialized_(false),
37  maxUsedTextureIndex_(-1),
38  maxUsedTextureMatrixIndex_(-1)
39 {
40  viewport_ = NULL;
41  depthBufferMode_ = &glfDepthBufferMode::DEFAULT;
42  stencilBufferMode_ = &glfStencilBufferMode::DEFAULT;
43  blendMode_ = &glfBlendMode::DEFAULT;
44  shaderProgram_ = NULL;
45  renderTarget_ = &glfScreen::GetInstance();
46  vertexBuffer_ = NULL;
47  elementBuffer_ = NULL;
48  primitiveType_ = INVALID_PRIMITIVE_TYPE;
49  first_ = 0;
50  count_ = -1;
51  modelViewMatrix_ = &glfMatrix::IDENTITY;
52  projectionMatrix_ = &glfMatrix::IDENTITY;
53 }
54 
56 {
57 }
58 
59 void glfBatch::SetRenderTarget(const glfRenderTarget* renderTarget)
60 {
61  BIASASSERT(renderTarget != NULL);
62  renderTarget_ = renderTarget;
63 }
64 
65 void glfBatch::SetViewport(const glfViewport* viewport)
66 {
67  BIASASSERT(viewport != NULL);
68  viewport_ = viewport;
69 }
70 
71 void glfBatch::SetTexture(const glfTexture* texture, int textureUnit)
72 {
73  //BIASASSERT(textureUnit >= 0 && textureUnit < MAX_TEXTURE_UNITS);
74  if(initialized_) {
75  BIASASSERT(textureUnit >= 0 && textureUnit < MAX_TEXTURE_UNITS_);
76  }
77  if((int)textures_.size() <= textureUnit) {
78  textures_.resize(textureUnit+1, NULL);
79  }
80  if(maxUsedTextureIndex_<textureUnit && texture!= NULL)
81  maxUsedTextureIndex_=textureUnit;
82 
83  if(textureUnit == maxUsedTextureIndex_-1 && texture == NULL) {
84  maxUsedTextureIndex_--;
85  }
86 
87  textures_[textureUnit] = texture;
88 }
89 
90 void glfBatch::ReleaseTextures(unsigned int fromIndex)
91 {
92  for(int i=maxUsedTextureIndex_;
93  i>=static_cast<int>(fromIndex); i--){
94  SetTexture(NULL, i);
95  }
96  maxUsedTextureIndex_ = fromIndex-1;
97 }
98 
99 
101 {
102  return maxUsedTextureIndex_;
103 }
104 
105 
107 {
108  BIASASSERT(depthBufferMode != NULL);
109  depthBufferMode_ = depthBufferMode;
110 }
111 
113 {
114  BIASASSERT(stencilBufferMode != NULL);
115  stencilBufferMode_ = stencilBufferMode;
116 }
117 
118 void glfBatch::SetBlendMode(const glfBlendMode* blendMode)
119 {
120  BIASASSERT(blendMode != NULL);
121  blendMode_ = blendMode;
122 }
123 
125 {
126  shaderProgram_ = shaderProgram;
127 }
128 
130 {
131  vertexBuffer_ = vertexBuffer;
132 }
133 
135 {
136  elementBuffer_ = elementBuffer;
137 }
138 
139 void glfBatch::SetPrimitiveType(GLenum primitiveType)
140 {
141  primitiveType_ = primitiveType;
142 }
143 
144 void glfBatch::SetRange(int first, int count)
145 {
146  first_ = first;
147  count_ = count;
148 }
149 
151 {
152  BIASASSERT(matrix != NULL);
153  modelViewMatrix_ = matrix;
154 }
155 
157 {
158  BIASASSERT(matrix != NULL);
159  projectionMatrix_ = matrix;
160 }
161 
162 void glfBatch::SetTextureMatrix(const glfMatrix* matrix, int index)
163 {
164  if(initialized_) {
165  BIASASSERT(index >= 0 && index < MAX_TEXTURE_COORDS_);
166  } else {
167  if((int)textureMatrix_.size() <= index) {
168  textureMatrix_.resize(index+1, NULL);
169  }
170  }
171 
172  if(maxUsedTextureMatrixIndex_<index && matrix != NULL)
173  maxUsedTextureMatrixIndex_=index;
174 
175  textureMatrix_[index] = matrix;
176 
177  if(index == maxUsedTextureMatrixIndex_-1 && matrix == NULL) {
178  maxUsedTextureMatrixIndex_--;
179  }
180 }
181 
182 void glfBatch::ReleaseTextureMatrices(unsigned int fromIndex)
183 {
184  for(int i=maxUsedTextureMatrixIndex_;
185  i>=static_cast<int>(fromIndex); i--){
186 
187  SetTextureMatrix(NULL, i);
188  }
189  maxUsedTextureMatrixIndex_ = fromIndex-1;
190 
191 }
192 
194 {
195  return maxUsedTextureMatrixIndex_;
196 }
197 
199 {
200  //std::cout<<"Batch init:"<<std::endl;
201  MAX_TEXTURE_UNITS_ = GetMaxSupportedTextureUnits();
202  MAX_TEXTURE_COORDS_ = GetMaxSupportedTextureMatrices();
203 
204  if(static_cast<int>(textureMatrix_.size())>MAX_TEXTURE_COORDS_)
205  GLF_THROW_EXCEPTION("Too many texture matrices assigned!");
206  if(static_cast<int>(textures_.size())>MAX_TEXTURE_UNITS_)
207  GLF_THROW_EXCEPTION("Too many textures assigned!");
208 
209  if(static_cast<int>(textureMatrix_.size())<MAX_TEXTURE_COORDS_) {
210  textureMatrix_.resize(MAX_TEXTURE_COORDS_, NULL);
211  }
212  if(static_cast<int>(textures_.size())<MAX_TEXTURE_UNITS_) {
213  textures_.resize(MAX_TEXTURE_UNITS_, NULL);
214  }
215  initialized_ = true;
216 }
217 
219 {
220  BindRenderStates();
221 
222  if (elementBuffer_ != NULL) {
223  // draw from element buffer
224  elementBuffer_->Draw(first_, count_);
225  } else {
226  // draw straight from vertex buffer
227  int count = count_;
228  if (count == -1) {
229  count = vertexBuffer_->GetNumVertices();
230  }
231  BIASASSERT(primitiveType_ != INVALID_PRIMITIVE_TYPE);
232  glDrawArrays(primitiveType_, first_, count);
233  }
234 
235  glFinish();
236 
237  GLF_THROW_ON_OPENGL_ERROR;
238 }
239 
240 
241 void glfBatch::BindRenderStates()
242 {
243  if(!initialized_) {
244  Init();
245  }
246 
247  // bind render target
248  if(renderTarget_ != NULL)
249  renderTarget_->Bind();
250 
251  // bind viewport
252  if(viewport_ != NULL)
253  viewport_->Bind();
254 
255  // bind textures
256  for (int i = 0; i <= maxUsedTextureIndex_; i++) {
257  if (textures_[i] != NULL) {
258  glActiveTexture(GL_TEXTURE0 + i);
259  textures_[i]->Bind();
260  }
261  }
262 
263  // bind depth buffer mode
264  if(depthBufferMode_ != NULL)
265  depthBufferMode_->Bind();
266 
267  if(stencilBufferMode_ != NULL)
268  stencilBufferMode_->Bind();
269 
270  // bind blend mode
271  if(blendMode_ != NULL)
272  blendMode_->Bind();
273 
274  // bind shader program
275  if (shaderProgram_ != NULL) {
276  shaderProgram_->Bind();
277  } else {
278  /** Is this code incomplete ?? **/
279  glUseProgram(0); // use fixed-function pipeline
280  if (textures_[0] != NULL) {
281  glActiveTexture(GL_TEXTURE0);
282  glEnable(textures_[0]->GetTextureTarget());
283  } else {
284  glActiveTexture(GL_TEXTURE0);
285  glDisable(GL_TEXTURE_1D);
286  glDisable(GL_TEXTURE_2D);
287  glDisable(GL_TEXTURE_3D);
288  }
289  }
290 
291  // bind vertex buffer
292  if(vertexBuffer_ != NULL)
293  vertexBuffer_->Bind();
294 
295  // load modelview matrix
296  if (modelViewMatrix_ != NULL) {
297  glMatrixMode(GL_MODELVIEW);
298  modelViewMatrix_->Load();
299  }
300 
301  // load projection matrix
302  if (projectionMatrix_ != NULL) {
303  glMatrixMode(GL_PROJECTION);
304  projectionMatrix_->Load();
305  }
306 
307  // load texture matrices
308  // for (int i = 0; i <= maxUsedTextureMatrixIndex_; i++) {
309  for (int i = 0; i < MAX_TEXTURE_COORDS_; i++) {
310  if (textureMatrix_[i] != NULL) {
311  glActiveTexture(GL_TEXTURE0 + i);
312  glMatrixMode(GL_TEXTURE);
313  textureMatrix_[i]->Load();
314  } else {
315  //why should I want to do this ? -> fixed function ?
316  glActiveTexture(GL_TEXTURE0 + i);
317  glMatrixMode(GL_TEXTURE);
318  glLoadIdentity();
319  }
320  }
321 }
322 
324 {
325  GLint TUs = 0;
326  glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &TUs);\
327  return static_cast<int>(TUs);
328 }
329 
331 {
332  GLint matrices = 0;
333  glGetIntegerv(GL_MAX_TEXTURE_COORDS, &matrices);
334  return static_cast<int>(matrices);
335 }
336 
338 {
339  int MAX_TEXTURE_UNITS = GetMaxSupportedTextureUnits();
340  int MAX_TEXTURE_COORDS = GetMaxSupportedTextureMatrices();
341 
342  // reset render target
344  GLF_THROW_ON_OPENGL_ERROR
345 
346  // reset textures
347  for (int i = 0; i < MAX_TEXTURE_UNITS; i++) {
348  glActiveTexture(GL_TEXTURE0 + i);
349  glBindTexture(GL_TEXTURE_1D, 0);
350  glBindTexture(GL_TEXTURE_2D, 0);
351  glBindTexture(GL_TEXTURE_3D, 0);
352  }
353 
354  // reset depth buffer mode
356 
357  // reset blend mode
359 
360  //reset stencil
362 
363  // reset shader program
364  glUseProgram(0);
365 
366  // reset vertex buffer
367  glBindBuffer(GL_ARRAY_BUFFER, 0);
368  GLint maxTextureCoords;
369  glGetIntegerv(GL_MAX_TEXTURE_COORDS, &maxTextureCoords);
370  GLint maxVertexAttribs;
371  glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &maxVertexAttribs);
372  glDisableClientState(GL_VERTEX_ARRAY);
373  glDisableClientState(GL_NORMAL_ARRAY);
374  glDisableClientState(GL_COLOR_ARRAY);
375 
376  /// todo: this loop made problems with open scene graph for SIGGRAPH09, fkellner
377  // for (int i = 0; i < maxTextureCoords; i++) {
378  // glClientActiveTexture(GL_TEXTURE0 + i);
379  // glDisableClientState(GL_TEXTURE_COORD_ARRAY);
380  // }
381  for (int i = 0; i < maxVertexAttribs; i++) {
382  glDisableVertexAttribArray(i);
383  }
384 
385  // reset modelview matrix
386  glMatrixMode(GL_MODELVIEW);
387  glLoadIdentity();
388 
389  // reset projection matrix
390  glMatrixMode(GL_PROJECTION);
391  glLoadIdentity();
392 
393  // reset texture matrices
394  for (int i = 0; i < MAX_TEXTURE_COORDS; i++) {
395  glActiveTexture(GL_TEXTURE0 + i);
396  glMatrixMode(GL_TEXTURE);
397  glLoadIdentity();
398  }
399 
400  // reset active texture
401  glActiveTexture(GL_TEXTURE0);
402 
403  // reset element buffer
404  glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
405  GLF_THROW_ON_OPENGL_ERROR
406 }
An element buffer contains vertex indices that form primitives.
void SetVertexBuffer(const glfVertexBuffer *vertexBuffer)
Sets the vertex buffer.
Definition: glfBatch.cpp:129
Defines the usage of the stencil buffer.
void SetModelViewMatrix(const glfMatrix *matrix)
Sets the modelview matrix.
Definition: glfBatch.cpp:150
Defines the usage of the depth buffer.
int GetNumVertices() const
Returns the number of vertices in the vertex buffer.
static const glfMatrix IDENTITY
The identity matrix.
Definition: glfMatrix.hh:158
void SetPrimitiveType(GLenum primitiveType)
Sets the primitive type to rendering.
Definition: glfBatch.cpp:139
virtual void Bind() const
Binds the viewport.
Definition: glfViewport.cpp:57
static int GetMaxSupportedTextureUnits()
Definition: glfBatch.cpp:323
void SetDepthBufferMode(const glfDepthBufferMode *depthBufferMode)
Sets the depth buffer mode.
Definition: glfBatch.cpp:106
void Draw()
Draws the batch.
Definition: glfBatch.cpp:218
void ReleaseTextureMatrices(unsigned int fromIndex)
Releases texture matrices including the matrix associated with the argument index.
Definition: glfBatch.cpp:182
static const glfBlendMode DEFAULT
The default blend mode.
Definition: glfBlendMode.hh:70
A vertex buffer contains an array of vertices that can be used for rendering.
unsigned int GetMaxUsedTextureIndex()
Definition: glfBatch.cpp:100
void Bind() const
Binds the shader program.
A shader program composed of several shaders.
void SetViewport(const glfViewport *viewport)
Sets the viewport.
Definition: glfBatch.cpp:65
static const glfDepthBufferMode DEFAULT
The default depth buffer mode.
Defines the function that blends rendered geometry with its background.
Definition: glfBlendMode.hh:37
static glfScreen & GetInstance()
Returns the global screen instance.
Definition: glfScreen.cpp:30
virtual void Bind() const =0
Makes this render target the currently used render target.
void SetTexture(const glfTexture *texture, int textureUnit)
Sets the texture of a texture unit.
Definition: glfBatch.cpp:71
unsigned int GetMaxUsedTextureMatrixIndex() const
Definition: glfBatch.cpp:193
class for setting viewports
Definition: glfViewport.hh:37
void Bind() const
Binds the vertex buffer in OpenGL.
void SetRenderTarget(const glfRenderTarget *renderTarget)
Sets the render target.
Definition: glfBatch.cpp:59
virtual void Bind() const
Makes this render target the currently used render target.
Definition: glfScreen.cpp:36
void SetShaderProgram(const glfShaderProgram *shaderProgram)
Sets the shader program.
Definition: glfBatch.cpp:124
A 4x4 matrix in native OpenGL format.
Definition: glfMatrix.hh:41
void Draw(int first=0, int count=-1) const
Draw elements from the buffer.
void Bind() const
Binds the stencil buffer mode.
Base class for textures.
Definition: glfTexture.hh:42
void SetProjectionMatrix(const glfMatrix *matrix)
Sets the projection matrix.
Definition: glfBatch.cpp:156
void ReleaseTextures(unsigned int fromIndex)
Releases texture including the matrix associated with the argument index.
Definition: glfBatch.cpp:90
void SetElementBuffer(const glfElementBuffer *elementBuffer)
Sets the element buffer.
Definition: glfBatch.cpp:134
static int GetMaxSupportedTextureMatrices()
Definition: glfBatch.cpp:330
void SetStencilBufferMode(const glfStencilBufferMode *stencilBufferMode)
Sets the stencil buffer mode.
Definition: glfBatch.cpp:112
Interface for render targets.
virtual void Load() const
Loads the matrix in OpenGL.
Definition: glfMatrix.cpp:540
static const glfStencilBufferMode DEFAULT
The default stencil buffer mode.
void Bind() const
Binds the depth buffer mode.
static void SetDefaultRenderStates()
Sets all render states possibly modified by Batch to the OpenGL defaults.
Definition: glfBatch.cpp:337
void Bind() const
Binds the blend mode.
void SetRange(int first, int count)
Sets the range of vertices to be rendered if no element buffer is set, or the range of vertex indices...
Definition: glfBatch.cpp:144
void SetTextureMatrix(const glfMatrix *matrix, int index)
Sets a texture matrix.
Definition: glfBatch.cpp:162
void SetBlendMode(const glfBlendMode *blendMode)
Sets the blend mode.
Definition: glfBatch.cpp:118