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 669:ab344e42bca9
prev656:031d23fa6d0b
next679:f5ae66677a49
author nkeynes
date Sun May 25 20:59:29 2008 +0000 (15 years ago)
permissions -rw-r--r--
last change Update test again for ftrv change
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     } else {
   103 	glsl_unload_shaders();
   104     }
   105     return pok;
   106 }
   108 void glsl_enable_shaders(gboolean en)
   109 {
   110     if( glsl_program != 0 ) {
   111 	if( en ) {
   112 	    glUseProgramObjectARB(glsl_program);
   113 	} else {
   114 	    glUseProgramObjectARB(0);
   115 	}
   116     }
   117 }
   119 void glsl_unload_shaders(void)
   120 {
   121     glUseProgramObjectARB(0);
   122     glDetachObjectARB(glsl_program, glsl_vert_shader);
   123     glDetachObjectARB(glsl_program, glsl_frag_shader);
   124     glDeleteObjectARB(glsl_program);
   125     glDeleteObjectARB(glsl_vert_shader);
   126     glDeleteObjectARB(glsl_frag_shader);
   127 }
   129 #elif HAVE_OPENGL_SHADER
   130 static GLuint glsl_program = 0, glsl_vert_shader = 0, glsl_frag_shader = 0;
   132 gboolean glsl_check_shader_error( char *msg, GLuint shader )
   133 {
   134     GLint value;
   136     glGetShaderiv( shader, GL_COMPILE_STATUS, &value );
   137     if( value == 0 ) {
   138 	char buf[MAX_ERROR_BUF];
   139 	GLsizei length;
   140 	glGetShaderInfoLog( shader, sizeof(buf), &length, buf );
   141 	ERROR( "%s: %s", msg, buf );
   142 	return FALSE;
   143     }
   144     return TRUE;
   145 }
   146 gboolean glsl_check_program_error( char *msg, GLuint program )
   147 {
   148     if( glGetError() != GL_NO_ERROR ) {
   149 	char buf[MAX_ERROR_BUF];
   150 	GLsizei length;
   151 	glGetProgramInfoLog( program, sizeof(buf), &length, buf );
   152 	ERROR( "%s: %s", msg, buf );
   153 	return FALSE;
   154     }
   155     return TRUE;
   156 }
   158 gboolean glsl_load_shaders( const char *vertex_src, const char *fragment_src )
   159 {
   160     gboolean vsok = TRUE, fsok = TRUE, pok = FALSE;
   162     if( vertex_src == NULL && fragment_src == NULL ) {
   163 	return TRUE;
   164     }
   166     glsl_program = glCreateProgram();
   168     if( vertex_src != NULL ) {
   169 	glsl_vert_shader = glCreateShader(GL_VERTEX_SHADER);
   170 	glShaderSource( glsl_vert_shader, 1, &vertex_src, NULL );
   171 	glCompileShader(glsl_vert_shader);
   172 	vsok = glsl_check_shader_error( "Failed to compile vertex shader", glsl_vert_shader );
   173     }
   174     if( fragment_src != NULL ) {
   175 	glsl_frag_shader = glCreateShader(GL_FRAGMENT_SHADER);
   176 	glShaderSource( glsl_frag_shader, 1, &fragment_src, NULL );
   177 	glCompileShader(glsl_frag_shader);
   178 	fsok = glsl_check_shader_error( "Failed to compile fragment shader", glsl_frag_shader );
   179     }
   181     if( vsok && fsok ) {
   182 	if( vertex_src != NULL ) {
   183 	    glAttachShader(glsl_program, glsl_vert_shader);
   184 	}
   185 	if( fragment_src != NULL ) {
   186 	    glAttachShader(glsl_program, glsl_frag_shader);
   187 	}
   188 	glLinkProgram(glsl_program);
   189 	pok = glsl_check_program_error( "Failed to link shader program", glsl_program );
   190     }
   192     if( pok ) {
   193 	glUseProgram(glsl_program);
   194     } else {
   195 	glsl_unload_shaders();
   196     }
   197     return pok;
   198 }
   201 void glsl_enable_shaders(gboolean en)
   202 {
   203     if( glsl_program != 0 ) {
   204 	if( en ) {
   205 	    glUseProgram(glsl_program);
   206 	} else {
   207 	    glUseProgram(0);
   208 	}
   209     }
   210 }
   212 void glsl_unload_shaders(void)
   213 {
   214     glUseProgram(0);
   215     glDetachShader(glsl_program, glsl_vert_shader);
   216     glDetachShader(glsl_program, glsl_frag_shader);
   217     glDeleteProgram(glsl_program);
   218     glDeleteShader(glsl_vert_shader);
   219     glDeleteShader(glsl_frag_shader);
   220 }
   222 #else
   223 gboolean glsl_load_shaders( const char *vertex_src, const char *fragment_src )
   224 {
   225     return FALSE;
   226 }
   228 void glsl_unload_shaders()
   229 {
   230 }
   232 void glsl_enable_shaders( gboolean enable )
   233 {
   234 }
   235 #endif
.