Merge branch 'master' of git://github.com/BTAxis/naev into testmission
[naev.git] / src / opengl_vbo.c
blob5b636d4178672269fb1a95d4bf417f8e74fd251c
1 /*
2 * See Licensing and Copyright notice in naev.h
3 */
5 /**
6 * @file opengl_vbo.c
8 * @brief Handles OpenGL vbos.
9 */
12 #include "opengl.h"
14 #include "naev.h"
16 #include "log.h"
19 #define BUFFER_OFFSET(i) ((char *)NULL + (i)) /**< Taken from OpengL spec. */
22 /**
23 * @brief VBO types.
25 typedef enum gl_vboType_e {
26 NGL_VBO_NULL, /**< No VBO type. */
27 NGL_VBO_STREAM, /**< VBO streaming type. */
28 NGL_VBO_STATIC /**< VBO static type. */
29 } gl_vboType;
32 /**
33 * @brief Contains the VBO.
35 struct gl_vbo_s {
36 GLuint id; /**< VBO ID. */
37 gl_vboType type; /**< VBO type. */
38 GLsizei size; /**< VBO size. */
39 char* data; /**< VBO data. */
43 static int has_vbo = 0; /**< Whether or not has VBO. */
46 /**
47 * Prototypes.
49 static gl_vbo* gl_vboCreate( GLenum target, GLsizei size, void* data, GLenum usage );
52 /**
53 * @brief Initializes the OpenGL VBO subsystem.
55 * @return 0 on success.
57 int gl_initVBO (void)
59 if (nglGenBuffers != NULL)
60 has_vbo = 1;
62 return 0;
66 /**
67 * @brief Exits the OpenGL VBO subsystem.
69 void gl_exitVBO (void)
71 has_vbo = 0;
75 /**
76 * @brief Creates a VBO.
78 * @param target Target to create to (usually GL_ARRAY_BUFFER).
79 * @param size Size of the buffer (in bytes).
80 * @param data The actual datat to use.
81 * @param usage Usage to use.
82 * @return ID of the vbo.
84 static gl_vbo* gl_vboCreate( GLenum target, GLsizei size, void* data, GLenum usage )
86 gl_vbo *vbo;
88 /* Allocate. */
89 vbo = malloc( sizeof(gl_vbo) );
90 memset( vbo, 0, sizeof(gl_vbo) );
92 /* General stuff. */
93 vbo->size = size;
95 if (has_vbo) {
96 /* Create the buffer. */
97 nglGenBuffers( 1, &vbo->id );
99 /* Upload the data. */
100 nglBindBuffer( target, vbo->id );
101 nglBufferData( target, size, data, usage );
102 nglBindBuffer( target, 0 );
104 else {
105 vbo->size = size;
106 vbo->data = malloc(size);
107 if (data == NULL)
108 memset( vbo->data, 0, size );
109 else
110 memcpy( vbo->data, data, size );
113 /* Check for errors. */
114 gl_checkErr();
116 return vbo;
121 * @brief Reloads new data or grows the size of the vbo.
123 * @param vbo VBO to get new data of.
124 * @param size Size of new data.
125 * @param data New data.
127 void gl_vboData( gl_vbo *vbo, GLsizei size, void* data )
129 GLenum usage;
131 vbo->size = size;
133 if (has_vbo) {
134 /* Get usage. */
135 if (vbo->type == NGL_VBO_STREAM)
136 usage = GL_STREAM_DRAW;
137 else if (vbo->type == NGL_VBO_STATIC)
138 usage = GL_STATIC_DRAW;
139 else
140 usage = GL_STREAM_DRAW;
142 /* Get new data. */
143 nglBindBuffer( GL_ARRAY_BUFFER, vbo->id );
144 nglBufferData( GL_ARRAY_BUFFER, size, data, usage );
146 else {
147 /* Grow memory. */
148 vbo->data = realloc( vbo->data, size );
149 if (data == NULL)
150 memset( vbo->data, 0, size );
151 else
152 memcpy( vbo->data, data, size );
155 /* Check for errors. */
156 gl_checkErr();
161 * @brief Loads some data into the VBO.
163 * @param vbo VBO to load data into.
164 * @param offset Offset location of the data (in bytes).
165 * @param size Size of the data (in bytes).
166 * @param data Pointer to the data.
168 void gl_vboSubData( gl_vbo *vbo, GLint offset, GLsizei size, void* data )
170 if (has_vbo) {
171 nglBindBuffer( GL_ARRAY_BUFFER, vbo->id );
172 nglBufferSubData( GL_ARRAY_BUFFER, offset, size, data );
174 else {
175 memcpy( &vbo->data[offset], data, size );
178 /* Check for errors. */
179 gl_checkErr();
184 * @brief Creates a stream vbo.
186 * @param size Size of the stream vbo (multiply by sizeof(type)).
187 * @param data Data for the VBO.
189 gl_vbo* gl_vboCreateStream( GLsizei size, void* data )
191 gl_vbo *vbo;
193 vbo = gl_vboCreate( GL_ARRAY_BUFFER, size, data, GL_STREAM_DRAW );
194 vbo->type = NGL_VBO_STREAM;
196 /* Check for errors. */
197 gl_checkErr();
199 return vbo;
204 * @brief Creates a stream vbo.
206 * @param size Size of the stream vbo (multiply by sizeof(type)).
207 * @param data Data for the VBO.
209 gl_vbo* gl_vboCreateStatic( GLsizei size, void* data )
211 gl_vbo *vbo;
213 vbo = gl_vboCreate( GL_ARRAY_BUFFER, size, data, GL_STATIC_DRAW );
214 vbo->type = NGL_VBO_STATIC;
216 /* Check for errors. */
217 gl_checkErr();
219 return vbo;
224 * @brief Maps a buffer.
226 * @param vbo VBO to map.
227 * @return The data contained in the vbo.
229 void* gl_vboMap( gl_vbo *vbo )
231 if (has_vbo) {
232 nglBindBuffer( GL_ARRAY_BUFFER, vbo->id );
233 return nglMapBuffer( GL_ARRAY_BUFFER, GL_WRITE_ONLY );
235 else
236 return vbo->data;
241 * @brief Unmaps a buffer.
243 * @param vbo VBO to unmap.
245 void gl_vboUnmap( gl_vbo *vbo )
247 (void) vbo;
248 if (has_vbo)
249 nglUnmapBuffer( GL_ARRAY_BUFFER );
251 /* Check for errors. */
252 gl_checkErr();
257 * @brief Activates a VBO.
259 * @param vbo VBO to activate.
260 * @param Should be one of GL_COLOR_ARRAY, GL_VERTEX_ARRAY, or GL_TEXTURE_COORD_ARRAY.
261 * @param size Specifies components per point.
262 * @param type Type of data (usually GL_FLOAT).
263 * @param stride Offset between consecutive points.
265 void gl_vboActivate( gl_vbo *vbo, GLuint class, GLint size, GLenum type, GLsizei stride )
267 gl_vboActivateOffset( vbo, class, 0, size, type, stride );
272 * @brief Activates a VBO's offset.
274 * @param vbo VBO to activate.
275 * @param class Should be one of GL_COLOR_ARRAY, GL_VERTEX_ARRAY,
276 * GL_TEXTURE_COORD_ARRAY, GL_TEXTURE0 or GL_TEXTURE1.
277 * @param offset Offset (in bytes).
278 * @param size Specifies components per point.
279 * @param type Type of data (usually GL_FLOAT).
280 * @param stride Offset between consecutive points.
282 void gl_vboActivateOffset( gl_vbo *vbo, GLuint class, GLuint offset,
283 GLint size, GLenum type, GLsizei stride )
285 const GLvoid *pointer;
287 /* Set up. */
288 if (has_vbo) {
289 nglBindBuffer( GL_ARRAY_BUFFER, vbo->id );
290 pointer = BUFFER_OFFSET(offset);
292 else
293 pointer = &vbo->data[offset];
295 /* Class specific. */
296 switch (class) {
297 case GL_COLOR_ARRAY:
298 glEnableClientState(class);
299 glColorPointer( size, type, stride, pointer );
300 break;
302 case GL_VERTEX_ARRAY:
303 glEnableClientState(class);
304 glVertexPointer( size, type, stride, pointer );
305 break;
307 case GL_TEXTURE_COORD_ARRAY:
308 glEnableClientState(class);
309 glTexCoordPointer( size, type, stride, pointer );
310 break;
312 case GL_TEXTURE0:
313 nglClientActiveTexture( GL_TEXTURE0 );
314 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
315 glTexCoordPointer( size, type, stride, pointer );
316 break;
318 case GL_TEXTURE1:
319 nglClientActiveTexture( GL_TEXTURE1 );
320 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
321 glTexCoordPointer( size, type, stride, pointer );
322 break;
324 default:
325 WARN("Unknown VBO class.");
326 break;
329 /* Check for errors. */
330 gl_checkErr();
335 * @brief Deactivates the vbo stuff.
337 void gl_vboDeactivate (void)
339 if (has_vbo)
340 nglBindBuffer(GL_ARRAY_BUFFER, 0);
341 glDisableClientState(GL_VERTEX_ARRAY);
342 glDisableClientState(GL_COLOR_ARRAY);
343 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
344 if (nglClientActiveTexture != NULL) {
345 nglClientActiveTexture( GL_TEXTURE1 );
346 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
347 nglClientActiveTexture( GL_TEXTURE0 );
348 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
351 /* Check for errors. */
352 gl_checkErr();
357 * @brief Destroys a VBO.
359 * @param vbo VBO to destroy.
361 void gl_vboDestroy( gl_vbo *vbo )
363 if (has_vbo)
364 /* Destroy VBO. */
365 nglDeleteBuffers( 1, &vbo->id );
366 else
367 free(vbo->data);
369 /* Check for errors. */
370 gl_checkErr();
372 /* Free memory. */
373 free(vbo);
378 * @brief Checks to see if the VBOs are supported by HW.
380 * @return 1 if VBOs are enabled and supported by HW.
382 int gl_vboIsHW (void)
384 return has_vbo;