filename | src/pvr2/glutil.c |
changeset | 1275:83b15705cdde |
prev | 1258:f8a9c0fd2abb |
next | 1276:e20a69167093 |
author | nkeynes |
date | Tue Mar 20 08:29:38 2012 +1000 (10 years ago) |
permissions | -rw-r--r-- |
last change | More android WIP - Implement onPause/onResume (although resume is not actually working yet) - Implement BGRA => RGBA texture conversion (BGRA doesn't seem to work on the TFP) Boot swirl is now displayed, albeit depth buffering seems to be broken. |
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 isOpenGLES2()
25 {
26 const char *str = glGetString(GL_VERSION);
27 if( strncmp(str, "OpenGL ES 2.", 12) == 0 ) {
28 return TRUE;
29 }
30 }
32 gboolean isGLSecondaryColorSupported()
33 {
34 return isGLExtensionSupported("GL_EXT_secondary_color");
35 }
37 gboolean isGLVertexBufferSupported()
38 {
39 return isGLExtensionSupported("GL_ARB_vertex_buffer_object");
40 }
42 gboolean isGLPixelBufferSupported()
43 {
44 return isGLExtensionSupported("GL_ARB_pixel_buffer_object");
45 }
47 gboolean isGLMirroredTextureSupported()
48 {
49 return isGLExtensionSupported("GL_ARB_texture_mirrored_repeat");
50 }
52 gboolean isGLBGRATextureSupported()
53 {
54 /* Note: e.g. Tegra 3 reports GL_EXT_bgra, but it doesn't actually work.
55 * Need to check this with NVIDIA, in meantime assume GLES2 doesn't have
56 * BGRA support */
57 return !isOpenGLES2() && isGLExtensionSupported("GL_EXT_bgra");
58 }
61 gboolean isGLShaderSupported()
62 {
63 return isOpenGLES2() || (isGLExtensionSupported("GL_ARB_fragment_shader") &&
64 isGLExtensionSupported("GL_ARB_vertex_shader") &&
65 isGLExtensionSupported("GL_ARB_shading_language_100"));
66 }
68 /**
69 * Check if there's at least 2 texture units
70 */
71 gboolean isGLMultitextureSupported()
72 {
73 if( !isOpenGLES2() && !isGLExtensionSupported("GL_ARB_multitexture") )
74 return FALSE;
75 int units = 0;
77 #if defined(GL_MAX_TEXTURE_UNITS)
78 glGetIntegerv(GL_MAX_TEXTURE_UNITS, &units);
79 #elif defined(GL_MAX_TEXTURE_IMAGE_UNITS)
80 glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &units);
81 #endif
82 return units >= 2;
83 }
85 gboolean isGLVertexRangeSupported()
86 {
87 return isGLExtensionSupported("GL_APPLE_vertex_array_range") ||
88 isGLExtensionSupported("GL_NV_vertex_array_range");
89 }
91 /**
92 * Test if a specific extension is supported. From opengl.org
93 * @param extension extension name to check for
94 * @return TRUE if supported, otherwise FALSE.
95 */
96 gboolean isGLExtensionSupported( const char *extension )
97 {
98 const GLubyte *extensions = NULL;
99 const GLubyte *start;
100 GLubyte *where, *terminator;
102 /* Extension names should not have spaces. */
103 where = (GLubyte *) strchr(extension, ' ');
104 if (where || *extension == '\0')
105 return 0;
106 extensions = glGetString(GL_EXTENSIONS);
107 if( extensions == NULL ) {
108 /* No GL available, so we're pretty sure the extension isn't
109 * available either. */
110 return FALSE;
111 }
112 /* It takes a bit of care to be fool-proof about parsing the
113 OpenGL extensions string. Don't be fooled by sub-strings,
114 etc. */
115 start = extensions;
116 for (;;) {
117 where = (GLubyte *) strstr((const char *) start, extension);
118 if (!where)
119 break;
120 terminator = where + strlen(extension);
121 if (where == start || *(where - 1) == ' ')
122 if (*terminator == ' ' || *terminator == '\0')
123 return TRUE;
124 start = terminator;
125 }
126 return FALSE;
127 }
129 int compare_charp( const void *a, const void *b )
130 {
131 const char **ca = (const char **)a;
132 const char **cb = (const char **)b;
133 return strcmp(*ca, *cb);
134 }
136 #define DEFAULT_TERMINAL_COLUMNS 80
137 #define DEFAULT_COLUMN_WIDTH 34
139 int glGetMaxColourAttachments()
140 {
141 #ifdef GL_MAX_COLOR_ATTACHMENTS
142 GLint result = 0;
143 glGetIntegerv(GL_MAX_COLOR_ATTACHMENTS, &result);
144 return result;
145 #else
146 return 1;
147 #endif
148 }
151 /**
152 * Define an orthographic projection matrix
153 * Note: row-major order
154 */
155 void defineOrthoMatrix( GLfloat *matrix, GLfloat width, GLfloat height, GLfloat znear, GLfloat zfar )
156 {
157 matrix[0] = 2/width;
158 matrix[1] = 0;
159 matrix[2] = 0;
160 matrix[3] = 0;
162 matrix[4] = 0;
163 matrix[5] = -2/height;
164 matrix[6] = 0;
165 matrix[7] = 0;
167 matrix[8] = 0;
168 matrix[9] = 0;
169 matrix[10]= -2/(zfar-znear);
170 matrix[11]= 0;
172 matrix[12]= -1;
173 matrix[13]= 1;
174 matrix[14]= -(zfar+znear)/(zfar-znear);
175 matrix[15]= 1;
176 }
178 /**
179 * Format a GL extension list (or other space-separated string) nicely, and
180 * print to the given output stream.
181 */
183 void fprint_extensions( FILE *out, const char *extensions )
184 {
185 unsigned int i, j, count, maxlen = DEFAULT_COLUMN_WIDTH, columns, per_column, terminal_columns;
186 const char *terminal_columns_str = getenv("COLUMNS");
187 if( terminal_columns_str == NULL || (terminal_columns = strtol(terminal_columns_str,0,10)) == 0 )
188 terminal_columns = DEFAULT_TERMINAL_COLUMNS;
190 if( extensions == NULL || extensions[0] == '\0' )
191 return;
193 gchar *ext_dup = g_strdup(extensions);
194 gchar **ext_split = g_strsplit(g_strstrip(extensions), " ", 0);
195 for( count = 0; ext_split[count] != NULL; count++ ) {
196 unsigned len = strlen(ext_split[count]);
197 if( len > maxlen )
198 maxlen = len;
199 }
201 columns = terminal_columns / (maxlen+2);
202 if( columns == 0 )
203 columns = 1;
204 per_column = (count+columns-1) / columns;
206 qsort(ext_split, count, sizeof(gchar *), compare_charp);
208 for( i=0; i<per_column; i++ ) {
209 for( j=0; j<columns; j++ ) {
210 unsigned idx = i + (j*per_column);
211 if( idx < count )
212 fprintf( out, " %-*s", maxlen, ext_split[idx] );
213 }
214 fprintf( out, "\n" );
215 }
216 g_strfreev(ext_split);
217 g_free(ext_dup);
218 }
220 void glPrintInfo( FILE *out )
221 {
222 fprintf( out, "GL Vendor: %s\n", glGetString(GL_VENDOR) );
223 fprintf( out, "GL Renderer: %s\n", glGetString(GL_RENDERER) );
224 fprintf( out, "GL Version: %s\n", glGetString(GL_VERSION) );
225 if( isGLShaderSupported() ) {
226 fprintf( out, "SL Version: %s\n", glGetString(GL_SHADING_LANGUAGE_VERSION) );
227 }
229 fprintf( out, "GL Extensions:\n" );
231 fprint_extensions( out, (const gchar *)glGetString(GL_EXTENSIONS) );
232 if( display_driver && display_driver->print_info ) {
233 fprintf( out, "\n");
234 display_driver->print_info(out);
235 }
236 }
238 gboolean gl_check_error(const char *context)
239 {
240 GLint err = glGetError();
241 if( err != 0 ) {
242 const char *s;
243 switch( err ) {
244 case GL_INVALID_ENUM: s = "Invalid enum"; break;
245 case GL_INVALID_VALUE: s = "Invalid value"; break;
246 case GL_INVALID_OPERATION: s = "Invalid operation"; break;
247 #ifdef GL_STACK_OVERFLOW
248 case GL_STACK_OVERFLOW: s = "Stack overflow"; break;
249 #endif
250 #ifdef GL_STACK_UNDERFLOW
251 case GL_STACK_UNDERFLOW: s = "Stack underflow"; break;
252 #endif
253 case GL_OUT_OF_MEMORY: s = "Out of memory"; break;
254 default: s = "Unknown error"; break;
255 }
256 if( context ) {
257 WARN( "%s: GL error: %x (%s)\n", context, err, s );
258 } else {
259 WARN( "GL error: %x (%s)\n", err, s );
260 }
261 return FALSE;
262 }
263 return TRUE;
264 }
.