filename | src/pvr2/glutil.c |
changeset | 1220:34e696c3a56f |
prev | 1219:3966d3e55351 |
next | 1223:61684ca88599 |
author | nkeynes |
date | Wed Feb 15 17:54:51 2012 +1000 (12 years ago) |
permissions | -rw-r--r-- |
last change | Use GL_TEXTURE_2D instead of GL_TEXTURE_RECTANGLE_ARB for frame buffers, for systems that don't provide the latter (and there's not really much difference anyway). Add macro wrangling for GL_DEPTH24_STENCIL8 format |
view | annotate | diff | log | raw |
1 /**
2 * $Id$
3 *
4 * GL-based support functions
5 *
6 * Copyright (c) 2005 Nathan Keynes.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 */
19 #include <string.h>
20 #include <stdlib.h>
21 #include <glib/gstrfuncs.h>
22 #include "pvr2/glutil.h"
24 gboolean isGLSecondaryColorSupported()
25 {
26 return isGLExtensionSupported("GL_EXT_secondary_color");
27 }
29 gboolean isGLVertexBufferSupported()
30 {
31 return isGLExtensionSupported("GL_ARB_vertex_buffer_object");
32 }
34 gboolean isGLPixelBufferSupported()
35 {
36 return isGLExtensionSupported("GL_ARB_pixel_buffer_object");
37 }
39 gboolean isGLMirroredTextureSupported()
40 {
41 return isGLExtensionSupported("GL_ARB_texture_mirrored_repeat");
42 }
44 /**
45 * Check if there's at least 2 texture units
46 */
47 gboolean isGLMultitextureSupported()
48 {
49 if( !isGLExtensionSupported("GL_ARB_multitexture") )
50 return FALSE;
51 int units = 0;
53 #if defined(GL_MAX_TEXTURE_UNITS)
54 glGetIntegerv(GL_MAX_TEXTURE_UNITS, &units);
55 #elif defined(GL_MAX_TEXTURE_IMAGE_UNITS)
56 glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &units);
57 #endif
58 return units >= 2;
59 }
61 gboolean isGLVertexRangeSupported()
62 {
63 return isGLExtensionSupported("GL_APPLE_vertex_array_range") ||
64 isGLExtensionSupported("GL_NV_vertex_array_range");
65 }
67 /**
68 * Test if a specific extension is supported. From opengl.org
69 * @param extension extension name to check for
70 * @return TRUE if supported, otherwise FALSE.
71 */
72 gboolean isGLExtensionSupported( const char *extension )
73 {
74 const GLubyte *extensions = NULL;
75 const GLubyte *start;
76 GLubyte *where, *terminator;
78 /* Extension names should not have spaces. */
79 where = (GLubyte *) strchr(extension, ' ');
80 if (where || *extension == '\0')
81 return 0;
82 extensions = glGetString(GL_EXTENSIONS);
83 if( extensions == NULL ) {
84 /* No GL available, so we're pretty sure the extension isn't
85 * available either. */
86 return FALSE;
87 }
88 /* It takes a bit of care to be fool-proof about parsing the
89 OpenGL extensions string. Don't be fooled by sub-strings,
90 etc. */
91 start = extensions;
92 for (;;) {
93 where = (GLubyte *) strstr((const char *) start, extension);
94 if (!where)
95 break;
96 terminator = where + strlen(extension);
97 if (where == start || *(where - 1) == ' ')
98 if (*terminator == ' ' || *terminator == '\0')
99 return TRUE;
100 start = terminator;
101 }
102 return FALSE;
103 }
105 int compare_charp( const void *a, const void *b )
106 {
107 const char **ca = (const char **)a;
108 const char **cb = (const char **)b;
109 return strcmp(*ca, *cb);
110 }
112 #define DEFAULT_TERMINAL_COLUMNS 80
113 #define DEFAULT_COLUMN_WIDTH 34
115 /**
116 * Format a GL extension list (or other space-separated string) nicely, and
117 * print to the given output stream.
118 */
120 void fprint_extensions( FILE *out, const char *extensions )
121 {
122 unsigned int i, j, count, maxlen = DEFAULT_COLUMN_WIDTH, columns, per_column, terminal_columns;
123 const char *terminal_columns_str = getenv("COLUMNS");
124 if( terminal_columns_str == NULL || (terminal_columns = strtol(terminal_columns_str,0,10)) == 0 )
125 terminal_columns = DEFAULT_TERMINAL_COLUMNS;
127 if( extensions == NULL || extensions[0] == '\0' )
128 return;
130 gchar *ext_dup = g_strdup(extensions);
131 gchar **ext_split = g_strsplit(g_strstrip(extensions), " ", 0);
132 for( count = 0; ext_split[count] != NULL; count++ ) {
133 unsigned len = strlen(ext_split[count]);
134 if( len > maxlen )
135 maxlen = len;
136 }
138 columns = terminal_columns / (maxlen+2);
139 if( columns == 0 )
140 columns = 1;
141 per_column = (count+columns-1) / columns;
143 qsort(ext_split, count, sizeof(gchar *), compare_charp);
145 for( i=0; i<per_column; i++ ) {
146 for( j=0; j<columns; j++ ) {
147 unsigned idx = i + (j*per_column);
148 if( idx < count )
149 fprintf( out, " %-*s", maxlen, ext_split[idx] );
150 }
151 fprintf( out, "\n" );
152 }
153 g_strfreev(ext_split);
154 g_free(ext_dup);
155 }
157 void glPrintInfo( FILE *out )
158 {
159 fprintf( out, "GL Vendor: %s\n", glGetString(GL_VENDOR) );
160 fprintf( out, "GL Renderer: %s\n", glGetString(GL_RENDERER) );
161 fprintf( out, "GL Version: %s\n", glGetString(GL_VERSION) );
162 if( glsl_is_supported() ) {
163 const char * version = glsl_get_version();
164 fprintf( out, "SL Version: %s\n", version );
165 }
167 fprintf( out, "GL Extensions:\n" );
169 fprint_extensions( out, (const gchar *)glGetString(GL_EXTENSIONS) );
170 if( display_driver && display_driver->print_info ) {
171 fprintf( out, "\n");
172 display_driver->print_info(out);
173 }
174 }
176 gboolean gl_check_error(const char *context)
177 {
178 GLint err = glGetError();
179 if( err != 0 ) {
180 const char *s;
181 switch( err ) {
182 case GL_INVALID_ENUM: s = "Invalid enum"; break;
183 case GL_INVALID_VALUE: s = "Invalid value"; break;
184 case GL_INVALID_OPERATION: s = "Invalid operation"; break;
185 #ifdef GL_STACK_OVERFLOW
186 case GL_STACK_OVERFLOW: s = "Stack overflow"; break;
187 #endif
188 #ifdef GL_STACK_UNDERFLOW
189 case GL_STACK_UNDERFLOW: s = "Stack underflow"; break;
190 #endif
191 case GL_OUT_OF_MEMORY: s = "Out of memory"; break;
192 default: s = "Unknown error"; break;
193 }
194 if( context ) {
195 WARN( "%s: GL error: %x (%s)\n", context, err, s );
196 } else {
197 WARN( "GL error: %x (%s)\n", err, s );
198 }
199 return FALSE;
200 }
201 return TRUE;
202 }
.