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 679:f5ae66677a49
prev669:ab344e42bca9
next736:a02d1475ccfd
author nkeynes
date Sun Jun 01 00:37:27 2008 +0000 (13 years ago)
permissions -rw-r--r--
last change Fix shaders to be disabled until explicitly requested
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
.