filename | src/pvr2/gl_sl.c |
changeset | 635:76c63aac3590 |
next | 656:031d23fa6d0b |
author | nkeynes |
date | Tue Mar 11 08:50:16 2008 +0000 (16 years ago) |
branch | lxdream-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 +00001.2 +++ b/src/pvr2/gl_sl.c Tue Mar 11 08:50:16 2008 +00001.3 @@ -0,0 +1,223 @@1.4 +/**1.5 + * $Id$1.6 + *1.7 + * GLSL shader loader/unloader. Current version assumes there's exactly1.8 + * 1 shader program that's used globally. This may turn out not to be the1.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 modify1.14 + * it under the terms of the GNU General Public License as published by1.15 + * the Free Software Foundation; either version 2 of the License, or1.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 of1.20 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the1.21 + * GNU General Public License for more details.1.22 + */1.23 +1.24 +#define GL_GLEXT_PROTOTYPES 11.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 40961.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_objects1.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 do1.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 +#else1.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
.