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 635:76c63aac3590
next656:031d23fa6d0b
author nkeynes
date Thu Mar 06 08:22:00 2008 +0000 (12 years ago)
branchlxdream-render
permissions -rw-r--r--
last change More refactor work in progress - nearly done now
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 #define GL_GLEXT_PROTOTYPES 1
    23 #include "lxdream.h"
    24 #include "display.h"
    25 #include "pvr2/glutil.h"
    27 #define MAX_ERROR_BUF 4096
    29 gboolean glsl_is_supported()
    30 {
    31     return isGLExtensionSupported("GL_ARB_fragment_shader") &&
    32 	isGLExtensionSupported("GL_ARB_vertex_shader") &&
    33 	isGLExtensionSupported("GL_ARB_shading_language_100");
    34 }
    36 #ifdef GL_ARB_shader_objects
    37 static GLhandleARB glsl_program = 0, glsl_vert_shader = 0, glsl_frag_shader = 0;
    39 void glsl_print_error( char *msg, GLhandleARB obj )
    40 {
    41     char buf[MAX_ERROR_BUF];
    42     GLsizei length;
    43     glGetInfoLogARB( obj, sizeof(buf), &length, buf );
    44     ERROR( "%s: %s", msg, buf );
    45 }
    47 gboolean glsl_check_shader_error( char *msg, GLhandleARB obj )
    48 {
    49     GLint value;
    51     glGetObjectParameterivARB(obj, GL_OBJECT_COMPILE_STATUS_ARB, &value);
    52     if( value == 0 ) {
    53 	glsl_print_error(msg, obj);
    54 	return FALSE;
    55     }
    56     return TRUE;
    57 }
    59 gboolean glsl_check_program_error( char *msg, GLhandleARB obj )
    60 {
    61     if( glGetError() != GL_NO_ERROR ) {
    62 	glsl_print_error(msg, obj);
    63     }
    64     return TRUE;
    65 }
    68 gboolean glsl_load_shaders( const char *vertex_src, const char *fragment_src )
    69 {
    70     gboolean vsok = TRUE, fsok = TRUE, pok = FALSE;
    72     if( vertex_src == NULL && fragment_src == NULL ) {
    73 	return TRUE; // nothing to do
    74     }
    76     glsl_program = glCreateProgramObjectARB();
    78     if( vertex_src != NULL ) {
    79 	glsl_vert_shader = glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB);
    80 	glShaderSourceARB( glsl_vert_shader, 1, &vertex_src, NULL );
    81 	glCompileShaderARB(glsl_vert_shader);
    82 	vsok = glsl_check_shader_error("Failed to compile vertex shader", glsl_vert_shader);
    83     }
    84     if( fragment_src != NULL ) {
    85 	glsl_frag_shader = glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB);
    86 	glShaderSourceARB( glsl_frag_shader, 1, &fragment_src, NULL );
    87 	glCompileShaderARB(glsl_frag_shader);
    88 	fsok = glsl_check_shader_error("Failed to compile fragment shader", glsl_frag_shader);
    89     }
    91     if( vsok && fsok ) {
    92 	if( vertex_src != NULL ) {
    93 	    glAttachObjectARB(glsl_program, glsl_vert_shader);
    94 	}
    95 	if( fragment_src != NULL ) {
    96 	    glAttachObjectARB(glsl_program, glsl_frag_shader);
    97 	}
    98 	glLinkProgramARB(glsl_program);
    99 	pok = glsl_check_program_error( "Failed to link shader program", glsl_program );
   100     }
   101     if( pok ) {
   102 	glUseProgramObjectARB(glsl_program);
   103 	pok = glsl_check_program_error( "Failed to apply shader program", glsl_program );
   104     } else {
   105 	glsl_unload_shaders();
   106     }
   107     return pok;
   108 }
   110 void glsl_enable_shader(gboolean en)
   111 {
   112     if( glsl_program != 0 ) {
   113 	if( en ) {
   114 	    glUseProgramObjectARB(glsl_program);
   115 	} else {
   116 	    glUseProgramObjectARB(0);
   117 	}
   118     }
   119 }
   121 void glsl_unload_shaders(void)
   122 {
   123     glUseProgramObjectARB(0);
   124     glDetachObjectARB(glsl_program, glsl_vert_shader);
   125     glDetachObjectARB(glsl_program, glsl_frag_shader);
   126     glDeleteObjectARB(glsl_program);
   127     glDeleteObjectARB(glsl_vert_shader);
   128     glDeleteObjectARB(glsl_frag_shader);
   129 }
   131 #else
   132 static GLuint glsl_program = 0, glsl_vert_shader = 0, glsl_frag_shader = 0;
   134 gboolean glsl_check_shader_error( char *msg, GLuint shader )
   135 {
   136     GLint value;
   138     glGetShaderiv( shader, GL_COMPILE_STATUS, &value );
   139     if( value == 0 ) {
   140 	char buf[MAX_ERROR_BUF];
   141 	GLsizei length;
   142 	glGetShaderInfoLog( shader, sizeof(buf), &length, buf );
   143 	ERROR( "%s: %s", msg, buf );
   144 	return FALSE;
   145     }
   146     return TRUE;
   147 }
   148 gboolean glsl_check_program_error( char *msg, GLuint program )
   149 {
   150     if( glGetError() != GL_NO_ERROR ) {
   151 	char buf[MAX_ERROR_BUF];
   152 	GLsizei length;
   153 	glGetProgramInfoLog( program, sizeof(buf), &length, buf );
   154 	ERROR( "%s: %s", msg, buf );
   155 	return FALSE;
   156     }
   157     return TRUE;
   158 }
   160 gboolean glsl_load_shaders( const char *vertex_src, const char *fragment_src )
   161 {
   162     gboolean vsok = TRUE, fsok = TRUE, pok = FALSE;
   164     if( vertex_src == NULL && fragment_src == NULL ) {
   165 	return TRUE;
   166     }
   168     glsl_program = glCreateProgram();
   170     if( vertex_src != NULL ) {
   171 	glsl_vert_shader = glCreateShader(GL_VERTEX_SHADER);
   172 	glShaderSource( glsl_vert_shader, 1, &vertex_src, NULL );
   173 	glCompileShader(glsl_vert_shader);
   174 	vsok = glsl_check_shader_error( "Failed to compile vertex shader", glsl_vert_shader );
   175     }
   176     if( fragment_src != NULL ) {
   177 	glsl_frag_shader = glCreateShader(GL_FRAGMENT_SHADER);
   178 	glShaderSource( glsl_frag_shader, 1, &fragment_src, NULL );
   179 	glCompileShader(glsl_frag_shader);
   180 	fsok = glsl_check_shader_error( "Failed to compile fragment shader", glsl_frag_shader );
   181     }
   183     if( vsok && fsok ) {
   184 	if( vertex_src != NULL ) {
   185 	    glAttachShader(glsl_program, glsl_vert_shader);
   186 	}
   187 	if( fragment_src != NULL ) {
   188 	    glAttachShader(glsl_program, glsl_frag_shader);
   189 	}
   190 	glLinkProgram(glsl_program);
   191 	pok = glsl_check_program_error( "Failed to link shader program", glsl_program );
   192     }
   194     if( pok ) {
   195 	glUseProgram(glsl_program);
   196     } else {
   197 	glsl_unload_shaders();
   198     }
   199     return pok;
   200 }
   203 void glsl_enable_shader(gboolean en)
   204 {
   205     if( glsl_program != 0 ) {
   206 	if( en ) {
   207 	    glUseProgram(glsl_program);
   208 	} else {
   209 	    glUseProgram(0);
   210 	}
   211     }
   212 }
   214 void glsl_unload_shaders(void)
   215 {
   216     glUseProgram(0);
   217     glDetachShader(glsl_program, glsl_vert_shader);
   218     glDetachShader(glsl_program, glsl_frag_shader);
   219     glDeleteProgram(glsl_program);
   220     glDeleteShader(glsl_vert_shader);
   221     glDeleteShader(glsl_frag_shader);
   222 }
   223 #endif
.