Basic Image AlgorithmS Library  2.8.0
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
glfVertexFormat.cpp
1 /*
2  This file is part of the BIAS library (Basic ImageAlgorithmS).
3 
4  Copyright (C) 2008, 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 "glfVertexFormat.hh"
26 #include "glfException.hh"
27 
28 using namespace BIAS;
29 
31 {
32  vertexSize_ = 0;
33 }
34 
36 {
37 }
38 
41 {
42  vertexSize_ = v2.vertexSize_;
43  for(unsigned int i=0; i<v2.attribDesc_.size(); i++) {
44  attribDesc_.push_back(v2.attribDesc_[i]);
45  }
46  return *this;
47 }
48 
50  int index, GLenum type,
51  int size, bool normalized)
52 {
53  BIASASSERT(size > 0);
54  BIASASSERT(index >= 0);
55  BIASASSERT(attrib == ATTRIB_TEXCOORD ||
56  attrib == ATTRIB_GENERIC ||
57  index == 0);
58  BIASASSERT(!HasAttribute(attrib, index));
59  BIASASSERT(sizeof(GLubyte) == 1);
60 
61  // check if attribute is supported.
62  std::string reason;
63  if (!IsAttributeSupported(attrib, index, type, size, reason)) {
64  GLF_THROW_EXCEPTION("Vertex attribute is not supported: " << reason);
65  }
66 
67  // create attribute description.
68  AttributeDesc desc;
69  desc.attrib = attrib;
70  desc.index = index;
71  desc.offset = vertexSize_;
72  desc.type = type;
73  desc.size = size;
74  desc.normalized = normalized ? GL_TRUE : GL_FALSE;
75  attribDesc_.push_back(desc);
76 
77  // update vertex size.
78  int typeSize = 0;
79  switch (type) {
80  case GL_BYTE: typeSize = sizeof(GLbyte); break;
81  case GL_UNSIGNED_BYTE: typeSize = sizeof(GLubyte); break;
82  case GL_SHORT: typeSize = sizeof(GLshort); break;
83  case GL_UNSIGNED_SHORT: typeSize = sizeof(GLushort); break;
84  case GL_INT: typeSize = sizeof(GLint); break;
85  case GL_UNSIGNED_INT: typeSize = sizeof(GLuint); break;
86  case GL_FLOAT: typeSize = sizeof(GLfloat); break;
87  case GL_DOUBLE: typeSize = sizeof(GLdouble); break;
88  }
89  vertexSize_ += typeSize * size;
90  BIASASSERT(vertexSize_ > 0);
91 }
92 
94 {
95  return vertexSize_;
96 }
97 
98 bool glfVertexFormat::HasAttribute(Attribute attrib, int index) const
99 {
100  BIASASSERT(attrib == ATTRIB_TEXCOORD || attrib == ATTRIB_GENERIC || index == 0);
101 
102  for (unsigned int i = 0; i < attribDesc_.size(); i++) {
103  if (attribDesc_[i].attrib == attrib && attribDesc_[i].index == index) {
104  return true;
105  }
106  }
107  return false;
108 }
109 
110 bool glfVertexFormat::GetAttributeInfo(Attribute attrib, int index, int& offset, GLenum& type, int& size) const
111 {
112  BIASASSERT(attrib == ATTRIB_TEXCOORD || attrib == ATTRIB_GENERIC || index == 0);
113 
114  for (unsigned int i = 0; i < attribDesc_.size(); i++) {
115  if (attribDesc_[i].attrib == attrib && attribDesc_[i].index == index) {
116  offset = attribDesc_[i].offset;
117  type = attribDesc_[i].type;
118  size = attribDesc_[i].size;
119  return true;
120  }
121  }
122  return false;
123 }
124 
125 bool glfVertexFormat::IsAttributeSupported(Attribute attrib, int index, GLenum type,
126  int size, std::string& reason)
127 {
128  switch (attrib) {
129 
130  case ATTRIB_POSITION:
131  if (type != GL_SHORT &&
132  type != GL_INT &&
133  type != GL_FLOAT &&
134  type != GL_DOUBLE) {
135  reason = "Type of ATTRIBUTE_POSITION must be GL_SHORT, GL_INT, GL_FLOAT, or GL_DOUBLE.";
136  return false;
137  }
138  if (size < 2 || size > 4) {
139  reason = "Size of ATTRIBUTE_POSITION must be 2, 3, or 4.";
140  return false;
141  }
142  break;
143 
144  case ATTRIB_NORMAL:
145  if (type != GL_BYTE &&
146  type != GL_SHORT &&
147  type != GL_INT &&
148  type != GL_FLOAT &&
149  type != GL_DOUBLE) {
150  reason = "Type of ATTRIBUTE_NORMAL must be GL_BYTE, GL_SHORT, GL_INT, GL_FLOAT, or GL_DOUBLE.";
151  return false;
152  }
153  if (size != 3) {
154  reason = "Size of ATTRIBUTE_NORMAL must be 3.";
155  return false;
156  }
157  break;
158 
159  case ATTRIB_COLOR:
160  if (type != GL_BYTE &&
161  type != GL_UNSIGNED_BYTE &&
162  type != GL_SHORT &&
163  type != GL_UNSIGNED_SHORT &&
164  type != GL_INT &&
165  type != GL_UNSIGNED_INT &&
166  type != GL_FLOAT &&
167  type != GL_DOUBLE) {
168  reason = "Type of ATTRIBUTE_COLOR must be GL_BYTE, GL_UNSIGNED_BYTE, GL_SHORT, "
169  "GL_UNSIGNED_SHORT, GL_INT, GL_UNSIGNED_INT, GL_FLOAT, or GL_DOUBLE.";
170  return false;
171  }
172  if (size < 3 || size > 4) {
173  reason = "Size of ATTRIBUTE_COLOR must be 3 or 4.";
174  return false;
175  }
176  break;
177 
178  case ATTRIB_TEXCOORD:
179  if (type != GL_SHORT &&
180  type != GL_INT &&
181  type != GL_FLOAT &&
182  type != GL_DOUBLE) {
183  reason = "Type of ATTRIBUTE_TEXCOORD must be GL_SHORT, GL_INT, GL_FLOAT, or GL_DOUBLE";
184  return false;
185  }
186  if (size < 1 || size > 4) {
187  reason = "Size of ATTRIBUTE_TEXCOORD must be 1, 2, 3, or 4.";
188  return false;
189  }
190  GLint maxTextureCoords;
191  glGetIntegerv(GL_MAX_TEXTURE_COORDS, &maxTextureCoords);
192  if (index >= maxTextureCoords) {
193  std::stringstream s;
194  s << "Index of ATTRIBUTE_TEXCOORD must be < " << maxTextureCoords;
195  reason = s.str();
196  return false;
197  }
198  break;
199 
200  case ATTRIB_GENERIC:
201  if (type != GL_BYTE &&
202  type != GL_UNSIGNED_BYTE &&
203  type != GL_SHORT &&
204  type != GL_UNSIGNED_SHORT &&
205  type != GL_INT &&
206  type != GL_UNSIGNED_INT &&
207  type != GL_FLOAT &&
208  type != GL_DOUBLE) {
209  reason = "Type of ATTRIBUTE_GENERIC must be GL_BYTE, GL_UNSIGNED_BYTE, GL_SHORT, "
210  "GL_UNSIGNED_SHORT, GL_INT, GL_UNSIGNED_INT, GL_FLOAT, or GL_DOUBLE.";
211  return false;
212  }
213  if (size < 1 || size > 4) {
214  reason = "Size of ATTRIBUTE_GENERIC must be 1, 2, 3, or 4.";
215  return false;
216  }
217  GLint maxVertexAttribs;
218  glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &maxVertexAttribs);
219  if (index >= maxVertexAttribs) {
220  std::stringstream s;
221  s << "Index of ATTRIBUTE_GENERIC must be < " << maxVertexAttribs;
222  reason = s.str();
223  return false;
224  }
225  break;
226 
227  default:
228  reason = "Invalid vertex attribute.";
229  return false;
230  break;
231 
232  }
233 
234  return true;
235 }
236 
237 void glfVertexFormat::Bind(const void* data) const
238 {
239  GLint maxTextureCoords;
240  glGetIntegerv(GL_MAX_TEXTURE_COORDS, &maxTextureCoords);
241  GLint maxVertexAttribs;
242  glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &maxVertexAttribs);
243 
244  // first disable all attribute arrays, because it is unknown which are enabled now.
245  glDisableClientState(GL_VERTEX_ARRAY);
246  glDisableClientState(GL_NORMAL_ARRAY);
247  glDisableClientState(GL_COLOR_ARRAY);
248  for (int i = 0; i < maxTextureCoords; i++) {
249  glClientActiveTexture(GL_TEXTURE0 + i);
250  glDisableClientState(GL_TEXTURE_COORD_ARRAY);
251  }
252  for (int i = 0; i < maxVertexAttribs; i++) {
253  glDisableVertexAttribArray(i);
254  }
255 
256  for (unsigned int i = 0; i < attribDesc_.size(); i++) {
257  const AttributeDesc& desc = attribDesc_[i];
258  switch (desc.attrib) {
259  case ATTRIB_POSITION:
260  glEnableClientState(GL_VERTEX_ARRAY);
261  glVertexPointer(desc.size, desc.type, vertexSize_, (GLubyte*)data + desc.offset);
262  break;
263  case ATTRIB_NORMAL:
264  glEnableClientState(GL_NORMAL_ARRAY);
265  glNormalPointer(desc.type, vertexSize_, (GLubyte*)data + desc.offset);
266  break;
267  case ATTRIB_COLOR:
268  glEnableClientState(GL_COLOR_ARRAY);
269  glColorPointer(desc.size, desc.type, vertexSize_, (GLubyte*)data + desc.offset);
270  break;
271  case ATTRIB_TEXCOORD:
272  glClientActiveTexture(GL_TEXTURE0 + desc.index);
273  glEnableClientState(GL_TEXTURE_COORD_ARRAY);
274  glTexCoordPointer(desc.size, desc.type, vertexSize_, (GLubyte*)data + desc.offset);
275  break;
276  case ATTRIB_GENERIC:
277  glEnableVertexAttribArray(desc.index);
278  glVertexAttribPointer(desc.index, desc.size, desc.type, desc.normalized,
279  vertexSize_, (GLubyte*)data + desc.offset);
280  break;
281  }
282  }
283 
284  GLF_THROW_ON_OPENGL_ERROR;
285 }
glfVertexFormat & operator=(const glfVertexFormat &v2)
bool HasAttribute(Attribute attrib, int index=0) const
Returns true iff the given attribute is part of the format.
void AddAttribute(Attribute attrib, int index, GLenum type, int size, bool normalized=false)
Adds a vertex attribute to the format.
int GetVertexSize() const
Returns the size in bytes of a single vertex.
A vertex format describes the attributes of a vertex.
void Bind(const void *data) const
Binds a vertex buffer or vertex array in OpenGL using this vertex format.
Attribute
Possible attributes of a vertex.
bool GetAttributeInfo(Attribute attrib, int index, int &offset, GLenum &type, int &size) const
Retrieves information about a vertex attribute inside the vertex structure.