Search
lxdream.org :: lxdream/src/pvr2/gl_sl.c :: diff
lxdream 0.9.1
released Jun 29
Download Now
filename src/pvr2/gl_sl.c
changeset 635:76c63aac3590
next656:031d23fa6d0b
author nkeynes
date Tue Mar 11 08:50:16 2008 +0000 (16 years ago)
branchlxdream-render
permissions -rw-r--r--
last change Use maxz rather than minz for tri sorting (better results atm)
Change depth-test-disable to depth-mask (more correct)
Implement alpha test for punchthru polys
file annotate diff log raw
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/src/pvr2/gl_sl.c Tue Mar 11 08:50:16 2008 +0000
1.3 @@ -0,0 +1,223 @@
1.4 +/**
1.5 + * $Id$
1.6 + *
1.7 + * GLSL shader loader/unloader. Current version assumes there's exactly
1.8 + * 1 shader program that's used globally. This may turn out not to be the
1.9 + * most efficient approach.
1.10 + *
1.11 + * Copyright (c) 2007 Nathan Keynes.
1.12 + *
1.13 + * This program is free software; you can redistribute it and/or modify
1.14 + * it under the terms of the GNU General Public License as published by
1.15 + * the Free Software Foundation; either version 2 of the License, or
1.16 + * (at your option) any later version.
1.17 + *
1.18 + * This program is distributed in the hope that it will be useful,
1.19 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
1.20 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1.21 + * GNU General Public License for more details.
1.22 + */
1.23 +
1.24 +#define GL_GLEXT_PROTOTYPES 1
1.25 +
1.26 +#include "lxdream.h"
1.27 +#include "display.h"
1.28 +#include "pvr2/glutil.h"
1.29 +
1.30 +#define MAX_ERROR_BUF 4096
1.31 +
1.32 +gboolean glsl_is_supported()
1.33 +{
1.34 + return isGLExtensionSupported("GL_ARB_fragment_shader") &&
1.35 + isGLExtensionSupported("GL_ARB_vertex_shader") &&
1.36 + isGLExtensionSupported("GL_ARB_shading_language_100");
1.37 +}
1.38 +
1.39 +#ifdef GL_ARB_shader_objects
1.40 +static GLhandleARB glsl_program = 0, glsl_vert_shader = 0, glsl_frag_shader = 0;
1.41 +
1.42 +void glsl_print_error( char *msg, GLhandleARB obj )
1.43 +{
1.44 + char buf[MAX_ERROR_BUF];
1.45 + GLsizei length;
1.46 + glGetInfoLogARB( obj, sizeof(buf), &length, buf );
1.47 + ERROR( "%s: %s", msg, buf );
1.48 +}
1.49 +
1.50 +gboolean glsl_check_shader_error( char *msg, GLhandleARB obj )
1.51 +{
1.52 + GLint value;
1.53 +
1.54 + glGetObjectParameterivARB(obj, GL_OBJECT_COMPILE_STATUS_ARB, &value);
1.55 + if( value == 0 ) {
1.56 + glsl_print_error(msg, obj);
1.57 + return FALSE;
1.58 + }
1.59 + return TRUE;
1.60 +}
1.61 +
1.62 +gboolean glsl_check_program_error( char *msg, GLhandleARB obj )
1.63 +{
1.64 + if( glGetError() != GL_NO_ERROR ) {
1.65 + glsl_print_error(msg, obj);
1.66 + }
1.67 + return TRUE;
1.68 +}
1.69 +
1.70 +
1.71 +gboolean glsl_load_shaders( const char *vertex_src, const char *fragment_src )
1.72 +{
1.73 + gboolean vsok = TRUE, fsok = TRUE, pok = FALSE;
1.74 +
1.75 + if( vertex_src == NULL && fragment_src == NULL ) {
1.76 + return TRUE; // nothing to do
1.77 + }
1.78 +
1.79 + glsl_program = glCreateProgramObjectARB();
1.80 +
1.81 + if( vertex_src != NULL ) {
1.82 + glsl_vert_shader = glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB);
1.83 + glShaderSourceARB( glsl_vert_shader, 1, &vertex_src, NULL );
1.84 + glCompileShaderARB(glsl_vert_shader);
1.85 + vsok = glsl_check_shader_error("Failed to compile vertex shader", glsl_vert_shader);
1.86 + }
1.87 + if( fragment_src != NULL ) {
1.88 + glsl_frag_shader = glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB);
1.89 + glShaderSourceARB( glsl_frag_shader, 1, &fragment_src, NULL );
1.90 + glCompileShaderARB(glsl_frag_shader);
1.91 + fsok = glsl_check_shader_error("Failed to compile fragment shader", glsl_frag_shader);
1.92 + }
1.93 +
1.94 + if( vsok && fsok ) {
1.95 + if( vertex_src != NULL ) {
1.96 + glAttachObjectARB(glsl_program, glsl_vert_shader);
1.97 + }
1.98 + if( fragment_src != NULL ) {
1.99 + glAttachObjectARB(glsl_program, glsl_frag_shader);
1.100 + }
1.101 + glLinkProgramARB(glsl_program);
1.102 + pok = glsl_check_program_error( "Failed to link shader program", glsl_program );
1.103 + }
1.104 + if( pok ) {
1.105 + glUseProgramObjectARB(glsl_program);
1.106 + pok = glsl_check_program_error( "Failed to apply shader program", glsl_program );
1.107 + } else {
1.108 + glsl_unload_shaders();
1.109 + }
1.110 + return pok;
1.111 +}
1.112 +
1.113 +void glsl_enable_shader(gboolean en)
1.114 +{
1.115 + if( glsl_program != 0 ) {
1.116 + if( en ) {
1.117 + glUseProgramObjectARB(glsl_program);
1.118 + } else {
1.119 + glUseProgramObjectARB(0);
1.120 + }
1.121 + }
1.122 +}
1.123 +
1.124 +void glsl_unload_shaders(void)
1.125 +{
1.126 + glUseProgramObjectARB(0);
1.127 + glDetachObjectARB(glsl_program, glsl_vert_shader);
1.128 + glDetachObjectARB(glsl_program, glsl_frag_shader);
1.129 + glDeleteObjectARB(glsl_program);
1.130 + glDeleteObjectARB(glsl_vert_shader);
1.131 + glDeleteObjectARB(glsl_frag_shader);
1.132 +}
1.133 +
1.134 +#else
1.135 +static GLuint glsl_program = 0, glsl_vert_shader = 0, glsl_frag_shader = 0;
1.136 +
1.137 +gboolean glsl_check_shader_error( char *msg, GLuint shader )
1.138 +{
1.139 + GLint value;
1.140 +
1.141 + glGetShaderiv( shader, GL_COMPILE_STATUS, &value );
1.142 + if( value == 0 ) {
1.143 + char buf[MAX_ERROR_BUF];
1.144 + GLsizei length;
1.145 + glGetShaderInfoLog( shader, sizeof(buf), &length, buf );
1.146 + ERROR( "%s: %s", msg, buf );
1.147 + return FALSE;
1.148 + }
1.149 + return TRUE;
1.150 +}
1.151 +gboolean glsl_check_program_error( char *msg, GLuint program )
1.152 +{
1.153 + if( glGetError() != GL_NO_ERROR ) {
1.154 + char buf[MAX_ERROR_BUF];
1.155 + GLsizei length;
1.156 + glGetProgramInfoLog( program, sizeof(buf), &length, buf );
1.157 + ERROR( "%s: %s", msg, buf );
1.158 + return FALSE;
1.159 + }
1.160 + return TRUE;
1.161 +}
1.162 +
1.163 +gboolean glsl_load_shaders( const char *vertex_src, const char *fragment_src )
1.164 +{
1.165 + gboolean vsok = TRUE, fsok = TRUE, pok = FALSE;
1.166 +
1.167 + if( vertex_src == NULL && fragment_src == NULL ) {
1.168 + return TRUE;
1.169 + }
1.170 +
1.171 + glsl_program = glCreateProgram();
1.172 +
1.173 + if( vertex_src != NULL ) {
1.174 + glsl_vert_shader = glCreateShader(GL_VERTEX_SHADER);
1.175 + glShaderSource( glsl_vert_shader, 1, &vertex_src, NULL );
1.176 + glCompileShader(glsl_vert_shader);
1.177 + vsok = glsl_check_shader_error( "Failed to compile vertex shader", glsl_vert_shader );
1.178 + }
1.179 + if( fragment_src != NULL ) {
1.180 + glsl_frag_shader = glCreateShader(GL_FRAGMENT_SHADER);
1.181 + glShaderSource( glsl_frag_shader, 1, &fragment_src, NULL );
1.182 + glCompileShader(glsl_frag_shader);
1.183 + fsok = glsl_check_shader_error( "Failed to compile fragment shader", glsl_frag_shader );
1.184 + }
1.185 +
1.186 + if( vsok && fsok ) {
1.187 + if( vertex_src != NULL ) {
1.188 + glAttachShader(glsl_program, glsl_vert_shader);
1.189 + }
1.190 + if( fragment_src != NULL ) {
1.191 + glAttachShader(glsl_program, glsl_frag_shader);
1.192 + }
1.193 + glLinkProgram(glsl_program);
1.194 + pok = glsl_check_program_error( "Failed to link shader program", glsl_program );
1.195 + }
1.196 +
1.197 + if( pok ) {
1.198 + glUseProgram(glsl_program);
1.199 + } else {
1.200 + glsl_unload_shaders();
1.201 + }
1.202 + return pok;
1.203 +}
1.204 +
1.205 +
1.206 +void glsl_enable_shader(gboolean en)
1.207 +{
1.208 + if( glsl_program != 0 ) {
1.209 + if( en ) {
1.210 + glUseProgram(glsl_program);
1.211 + } else {
1.212 + glUseProgram(0);
1.213 + }
1.214 + }
1.215 +}
1.216 +
1.217 +void glsl_unload_shaders(void)
1.218 +{
1.219 + glUseProgram(0);
1.220 + glDetachShader(glsl_program, glsl_vert_shader);
1.221 + glDetachShader(glsl_program, glsl_frag_shader);
1.222 + glDeleteProgram(glsl_program);
1.223 + glDeleteShader(glsl_vert_shader);
1.224 + glDeleteShader(glsl_frag_shader);
1.225 +}
1.226 +#endif
.