Search
lxdream.org :: lxdream/src/pvr2/glutil.c
lxdream 0.9.1
released Jun 29
Download Now
filename src/pvr2/glutil.c
changeset 1275:83b15705cdde
prev1258:f8a9c0fd2abb
next1276: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 }
.