Search
lxdream.org :: lxdream/src/pvr2/gl_sl.c
lxdream 0.9.1
released Jun 29
Download Now
filename src/pvr2/gl_sl.c
changeset 736:a02d1475ccfd
prev679:f5ae66677a49
next1009:c29795e15cef
author nkeynes
date Wed Jul 30 22:50:44 2008 +0000 (15 years ago)
permissions -rw-r--r--
last change Bug #61: OpenBSD support
(Modified) patch from bsdmaniak, thanks!
view annotate diff log raw
     1 /**
     2  * $Id$
     3  *
     4  * GLSL shader loader/unloader. Current version assumes there's exactly
     5  * 1 shader program that's used globally. This may turn out not to be the
     6  * most efficient approach.
     7  *
     8  * Copyright (c) 2007 Nathan Keynes.
     9  *
    10  * This program is free software; you can redistribute it and/or modify
    11  * it under the terms of the GNU General Public License as published by
    12  * the Free Software Foundation; either version 2 of the License, or
    13  * (at your option) any later version.
    14  *
    15  * This program is distributed in the hope that it will be useful,
    16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    18  * GNU General Public License for more details.
    19  */
    21 #include "lxdream.h"
    22 #include "display.h"
    23 #include "pvr2/glutil.h"
    25 #define MAX_ERROR_BUF 4096
    27 gboolean glsl_is_supported()
    28 {
    29     return isGLExtensionSupported("GL_ARB_fragment_shader") &&
    30     isGLExtensionSupported("GL_ARB_vertex_shader") &&
    31     isGLExtensionSupported("GL_ARB_shading_language_100");
    32 }
    34 #ifdef GL_ARB_shader_objects
    35 static GLhandleARB glsl_program = 0, glsl_vert_shader = 0, glsl_frag_shader = 0;
    37 void glsl_print_error( char *msg, GLhandleARB obj )
    38 {
    39     char buf[MAX_ERROR_BUF];
    40     GLsizei length;
    41     glGetInfoLogARB( obj, sizeof(buf), &length, buf );
    42     ERROR( "%s: %s", msg, buf );
    43 }
    45 gboolean glsl_check_shader_error( char *msg, GLhandleARB obj )
    46 {
    47     GLint value;
    49     glGetObjectParameterivARB(obj, GL_OBJECT_COMPILE_STATUS_ARB, &value);
    50     if( value == 0 ) {
    51         glsl_print_error(msg, obj);
    52         return FALSE;
    53     }
    54     return TRUE;
    55 }
    57 gboolean glsl_check_program_error( char *msg, GLhandleARB obj )
    58 {
    59     if( glGetError() != GL_NO_ERROR ) {
    60         glsl_print_error(msg, obj);
    61     }
    62     return TRUE;
    63 }
    66 gboolean glsl_load_shaders( const char *vertex_src, const char *fragment_src )
    67 {
    68     gboolean vsok = TRUE, fsok = TRUE, pok = FALSE;
    70     if( vertex_src == NULL && fragment_src == NULL ) {
    71         return TRUE; // nothing to do
    72     }
    74     glsl_program = glCreateProgramObjectARB();
    76     if( vertex_src != NULL ) {
    77         glsl_vert_shader = glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB);
    78         glShaderSourceARB( glsl_vert_shader, 1, &vertex_src, NULL );
    79         glCompileShaderARB(glsl_vert_shader);
    80         vsok = glsl_check_shader_error("Failed to compile vertex shader", glsl_vert_shader);
    81     }
    82     if( fragment_src != NULL ) {
    83         glsl_frag_shader = glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB);
    84         glShaderSourceARB( glsl_frag_shader, 1, &fragment_src, NULL );
    85         glCompileShaderARB(glsl_frag_shader);
    86         fsok = glsl_check_shader_error("Failed to compile fragment shader", glsl_frag_shader);
    87     }
    89     if( vsok && fsok ) {
    90         if( vertex_src != NULL ) {
    91             glAttachObjectARB(glsl_program, glsl_vert_shader);
    92         }
    93         if( fragment_src != NULL ) {
    94             glAttachObjectARB(glsl_program, glsl_frag_shader);
    95         }
    96         glLinkProgramARB(glsl_program);
    97         pok = glsl_check_program_error( "Failed to link shader program", glsl_program );
    98     }
    99     if( pok ) {
   100         glUseProgramObjectARB(glsl_program);
   101         pok = glsl_check_program_error( "Failed to apply shader program", glsl_program );
   102         glsl_enable_shaders(FALSE); // initially disabled
   103     } else {
   104         glsl_unload_shaders();
   105     }
   106     return pok;
   107 }
   109 void glsl_enable_shaders(gboolean en)
   110 {
   111     if( glsl_program != 0 ) {
   112         if( en ) {
   113             glUseProgramObjectARB(glsl_program);
   114         } else {
   115             glUseProgramObjectARB(0);
   116         }
   117     }
   118 }
   120 void glsl_unload_shaders(void)
   121 {
   122     glUseProgramObjectARB(0);
   123     glDetachObjectARB(glsl_program, glsl_vert_shader);
   124     glDetachObjectARB(glsl_program, glsl_frag_shader);
   125     glDeleteObjectARB(glsl_program);
   126     glDeleteObjectARB(glsl_vert_shader);
   127     glDeleteObjectARB(glsl_frag_shader);
   128 }
   130 #elif HAVE_OPENGL_SHADER
   131 static GLuint glsl_program = 0, glsl_vert_shader = 0, glsl_frag_shader = 0;
   133 gboolean glsl_check_shader_error( char *msg, GLuint shader )
   134 {
   135     GLint value;
   137     glGetShaderiv( shader, GL_COMPILE_STATUS, &value );
   138     if( value == 0 ) {
   139         char buf[MAX_ERROR_BUF];
   140         GLsizei length;
   141         glGetShaderInfoLog( shader, sizeof(buf), &length, buf );
   142         ERROR( "%s: %s", msg, buf );
   143         return FALSE;
   144     }
   145     return TRUE;
   146 }
   147 gboolean glsl_check_program_error( char *msg, GLuint program )
   148 {
   149     if( glGetError() != GL_NO_ERROR ) {
   150         char buf[MAX_ERROR_BUF];
   151         GLsizei length;
   152         glGetProgramInfoLog( program, sizeof(buf), &length, buf );
   153         ERROR( "%s: %s", msg, buf );
   154         return FALSE;
   155     }
   156     return TRUE;
   157 }
   159 gboolean glsl_load_shaders( const char *vertex_src, const char *fragment_src )
   160 {
   161     gboolean vsok = TRUE, fsok = TRUE, pok = FALSE;
   163     if( vertex_src == NULL && fragment_src == NULL ) {
   164         return TRUE;
   165     }
   167     glsl_program = glCreateProgram();
   169     if( vertex_src != NULL ) {
   170         glsl_vert_shader = glCreateShader(GL_VERTEX_SHADER);
   171         glShaderSource( glsl_vert_shader, 1, &vertex_src, NULL );
   172         glCompileShader(glsl_vert_shader);
   173         vsok = glsl_check_shader_error( "Failed to compile vertex shader", glsl_vert_shader );
   174     }
   175     if( fragment_src != NULL ) {
   176         glsl_frag_shader = glCreateShader(GL_FRAGMENT_SHADER);
   177         glShaderSource( glsl_frag_shader, 1, &fragment_src, NULL );
   178         glCompileShader(glsl_frag_shader);
   179         fsok = glsl_check_shader_error( "Failed to compile fragment shader", glsl_frag_shader );
   180     }
   182     if( vsok && fsok ) {
   183         if( vertex_src != NULL ) {
   184             glAttachShader(glsl_program, glsl_vert_shader);
   185         }
   186         if( fragment_src != NULL ) {
   187             glAttachShader(glsl_program, glsl_frag_shader);
   188         }
   189         glLinkProgram(glsl_program);
   190         pok = glsl_check_program_error( "Failed to link shader program", glsl_program );
   191     }
   193     if( pok ) {
   194         glUseProgram(glsl_program);
   195         pok = glsl_check_program_error( "Failed to apply shader program", glsl_program );
   196         glsl_enable_shaders(FALSE); // initially disabled
   197     } else {
   198         glsl_unload_shaders();
   199     }
   200     return pok;
   201 }
   204 void glsl_enable_shaders(gboolean en)
   205 {
   206     if( glsl_program != 0 ) {
   207         if( en ) {
   208             glUseProgram(glsl_program);
   209         } else {
   210             glUseProgram(0);
   211         }
   212     }
   213 }
   215 void glsl_unload_shaders(void)
   216 {
   217     glUseProgram(0);
   218     glDetachShader(glsl_program, glsl_vert_shader);
   219     glDetachShader(glsl_program, glsl_frag_shader);
   220     glDeleteProgram(glsl_program);
   221     glDeleteShader(glsl_vert_shader);
   222     glDeleteShader(glsl_frag_shader);
   223 }
   225 #else
   226 gboolean glsl_load_shaders( const char *vertex_src, const char *fragment_src )
   227 {
   228     return FALSE;
   229 }
   231 void glsl_unload_shaders()
   232 {
   233 }
   235 void glsl_enable_shaders( gboolean enable )
   236 {
   237 }
   238 #endif
.