filename | src/pvr2/glutil.c |
changeset | 1248:0ea1904e2b14 |
prev | 1245:01e0020adf88 |
next | 1258:f8a9c0fd2abb |
author | nkeynes |
date | Sat Mar 03 16:11:28 2012 +1000 (12 years ago) |
permissions | -rw-r--r-- |
last change | Support depth component 16 as well as 24 (add capability flag for the available bits) Put remaining TODOs inside HAVE_OPENGL_FIXEDFUNC blocks Add swap-buffer calls for EGL (does not appear to support rendering directly to front-buffer) |
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 gboolean isOpenGLES2()
45 {
46 const char *str = glGetString(GL_VERSION);
47 if( strncmp(str, "OpenGL ES 2.", 12) == 0 ) {
48 return TRUE;
49 }
50 }
52 /**
53 * Check if there's at least 2 texture units
54 */
55 gboolean isGLMultitextureSupported()
56 {
57 if( !isOpenGLES2() && !isGLExtensionSupported("GL_ARB_multitexture") )
58 return FALSE;
59 int units = 0;
61 #if defined(GL_MAX_TEXTURE_UNITS)
62 glGetIntegerv(GL_MAX_TEXTURE_UNITS, &units);
63 #elif defined(GL_MAX_TEXTURE_IMAGE_UNITS)
64 glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &units);
65 #endif
66 return units >= 2;
67 }
69 gboolean isGLVertexRangeSupported()
70 {
71 return isGLExtensionSupported("GL_APPLE_vertex_array_range") ||
72 isGLExtensionSupported("GL_NV_vertex_array_range");
73 }
75 /**
76 * Test if a specific extension is supported. From opengl.org
77 * @param extension extension name to check for
78 * @return TRUE if supported, otherwise FALSE.
79 */
80 gboolean isGLExtensionSupported( const char *extension )
81 {
82 const GLubyte *extensions = NULL;
83 const GLubyte *start;
84 GLubyte *where, *terminator;
86 /* Extension names should not have spaces. */
87 where = (GLubyte *) strchr(extension, ' ');
88 if (where || *extension == '\0')
89 return 0;
90 extensions = glGetString(GL_EXTENSIONS);
91 if( extensions == NULL ) {
92 /* No GL available, so we're pretty sure the extension isn't
93 * available either. */
94 return FALSE;
95 }
96 /* It takes a bit of care to be fool-proof about parsing the
97 OpenGL extensions string. Don't be fooled by sub-strings,
98 etc. */
99 start = extensions;
100 for (;;) {
101 where = (GLubyte *) strstr((const char *) start, extension);
102 if (!where)
103 break;
104 terminator = where + strlen(extension);
105 if (where == start || *(where - 1) == ' ')
106 if (*terminator == ' ' || *terminator == '\0')
107 return TRUE;
108 start = terminator;
109 }
110 return FALSE;
111 }
113 int compare_charp( const void *a, const void *b )
114 {
115 const char **ca = (const char **)a;
116 const char **cb = (const char **)b;
117 return strcmp(*ca, *cb);
118 }
120 #define DEFAULT_TERMINAL_COLUMNS 80
121 #define DEFAULT_COLUMN_WIDTH 34
123 int glGetMaxColourAttachments()
124 {
125 #ifdef GL_MAX_COLOR_ATTACHMENTS
126 GLint result = 0;
127 glGetIntegerv(GL_MAX_COLOR_ATTACHMENTS, &result);
128 return result;
129 #else
130 return 1;
131 #endif
132 }
135 /**
136 * Define an orthographic projection matrix
137 * Note: row-major order
138 */
139 void defineOrthoMatrix( GLfloat *matrix, GLfloat width, GLfloat height, GLfloat znear, GLfloat zfar )
140 {
141 matrix[0] = 2/width;
142 matrix[1] = 0;
143 matrix[2] = 0;
144 matrix[3] = 0;
146 matrix[4] = 0;
147 matrix[5] = -2/height;
148 matrix[6] = 0;
149 matrix[7] = 0;
151 matrix[8] = 0;
152 matrix[9] = 0;
153 matrix[10]= -2/(zfar-znear);
154 matrix[11]= 0;
156 matrix[12]= -1;
157 matrix[13]= 1;
158 matrix[14]= -(zfar+znear)/(zfar-znear);
159 matrix[15]= 1;
160 }
162 /**
163 * Format a GL extension list (or other space-separated string) nicely, and
164 * print to the given output stream.
165 */
167 void fprint_extensions( FILE *out, const char *extensions )
168 {
169 unsigned int i, j, count, maxlen = DEFAULT_COLUMN_WIDTH, columns, per_column, terminal_columns;
170 const char *terminal_columns_str = getenv("COLUMNS");
171 if( terminal_columns_str == NULL || (terminal_columns = strtol(terminal_columns_str,0,10)) == 0 )
172 terminal_columns = DEFAULT_TERMINAL_COLUMNS;
174 if( extensions == NULL || extensions[0] == '\0' )
175 return;
177 gchar *ext_dup = g_strdup(extensions);
178 gchar **ext_split = g_strsplit(g_strstrip(extensions), " ", 0);
179 for( count = 0; ext_split[count] != NULL; count++ ) {
180 unsigned len = strlen(ext_split[count]);
181 if( len > maxlen )
182 maxlen = len;
183 }
185 columns = terminal_columns / (maxlen+2);
186 if( columns == 0 )
187 columns = 1;
188 per_column = (count+columns-1) / columns;
190 qsort(ext_split, count, sizeof(gchar *), compare_charp);
192 for( i=0; i<per_column; i++ ) {
193 for( j=0; j<columns; j++ ) {
194 unsigned idx = i + (j*per_column);
195 if( idx < count )
196 fprintf( out, " %-*s", maxlen, ext_split[idx] );
197 }
198 fprintf( out, "\n" );
199 }
200 g_strfreev(ext_split);
201 g_free(ext_dup);
202 }
204 void glPrintInfo( FILE *out )
205 {
206 fprintf( out, "GL Vendor: %s\n", glGetString(GL_VENDOR) );
207 fprintf( out, "GL Renderer: %s\n", glGetString(GL_RENDERER) );
208 fprintf( out, "GL Version: %s\n", glGetString(GL_VERSION) );
209 if( glsl_is_supported() ) {
210 const char * version = glsl_get_version();
211 fprintf( out, "SL Version: %s\n", version );
212 }
214 fprintf( out, "GL Extensions:\n" );
216 fprint_extensions( out, (const gchar *)glGetString(GL_EXTENSIONS) );
217 if( display_driver && display_driver->print_info ) {
218 fprintf( out, "\n");
219 display_driver->print_info(out);
220 }
221 }
223 gboolean gl_check_error(const char *context)
224 {
225 GLint err = glGetError();
226 if( err != 0 ) {
227 const char *s;
228 switch( err ) {
229 case GL_INVALID_ENUM: s = "Invalid enum"; break;
230 case GL_INVALID_VALUE: s = "Invalid value"; break;
231 case GL_INVALID_OPERATION: s = "Invalid operation"; break;
232 #ifdef GL_STACK_OVERFLOW
233 case GL_STACK_OVERFLOW: s = "Stack overflow"; break;
234 #endif
235 #ifdef GL_STACK_UNDERFLOW
236 case GL_STACK_UNDERFLOW: s = "Stack underflow"; break;
237 #endif
238 case GL_OUT_OF_MEMORY: s = "Out of memory"; break;
239 default: s = "Unknown error"; break;
240 }
241 if( context ) {
242 WARN( "%s: GL error: %x (%s)\n", context, err, s );
243 } else {
244 WARN( "GL error: %x (%s)\n", err, s );
245 }
246 return FALSE;
247 }
248 return TRUE;
249 }
.