Search
lxdream.org :: lxdream/src/drivers/gl_sl.c :: diff
lxdream 0.9.1
released Jun 29
Download Now
filename src/drivers/gl_sl.c
changeset 405:570d93abb5b7
next424:421d68e78c46
author nkeynes
date Fri Sep 28 07:24:14 2007 +0000 (12 years ago)
permissions -rw-r--r--
last change Add GLSL loader framework
file annotate diff log raw
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/src/drivers/gl_sl.c Fri Sep 28 07:24:14 2007 +0000
1.3 @@ -0,0 +1,171 @@
1.4 +/**
1.5 + * $Id: gl_sl.c,v 1.1 2007-09-28 07:24:14 nkeynes Exp $
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 +
1.25 +#include <GL/gl.h>
1.26 +#include <GL/glext.h>
1.27 +#include "drivers/gl_common.h"
1.28 +#include "display.h"
1.29 +
1.30 +#define MAX_ERROR_BUF 4096
1.31 +
1.32 +static GLuint glsl_program, glsl_vert_shader, glsl_frag_shader;
1.33 +
1.34 +gboolean glsl_is_supported()
1.35 +{
1.36 + return isGLExtensionSupported("GL_ARB_fragment_shader") &&
1.37 + isGLExtensionSupported("GL_ARB_vertex_shader") &&
1.38 + isGLExtensionSupported("GL_ARB_shading_language_100");
1.39 +}
1.40 +
1.41 +#ifdef GL_ARB_shader_objects
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, fsok, pok = FALSE;
1.74 + glsl_program = glCreateProgramObjectARB();
1.75 +
1.76 + glsl_vert_shader = glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB);
1.77 + glsl_frag_shader = glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB);
1.78 + glShaderSourceARB( glsl_vert_shader, 1, &vertex_src, NULL );
1.79 + glCompileShaderARB(glsl_vert_shader);
1.80 + vsok = glsl_check_shader_error("Failed to compile vertex shader", glsl_vert_shader);
1.81 + glShaderSourceARB( glsl_frag_shader, 1, &fragment_src, NULL );
1.82 + glCompileShaderARB(glsl_frag_shader);
1.83 + fsok = glsl_check_shader_error("Failed to compile fragment shader", glsl_frag_shader);
1.84 +
1.85 + if( vsok && fsok ) {
1.86 + glAttachObjectARB(glsl_program, glsl_vert_shader);
1.87 + glAttachObjectARB(glsl_program, glsl_frag_shader);
1.88 + glLinkProgramARB(glsl_program);
1.89 + pok = glsl_check_program_error( "Failed to link shader program", glsl_program );
1.90 + }
1.91 + if( pok ) {
1.92 + glUseProgramObjectARB(glsl_program);
1.93 + pok = glsl_check_program_error( "Failed to apply shader program", glsl_program );
1.94 + } else {
1.95 + glsl_unload_shaders();
1.96 + }
1.97 + return pok;
1.98 +}
1.99 +
1.100 +void glsl_unload_shaders(void)
1.101 +{
1.102 + glUseProgramObjectARB(0);
1.103 + glDetachObjectARB(glsl_program, glsl_vert_shader);
1.104 + glDetachObjectARB(glsl_program, glsl_frag_shader);
1.105 + glDeleteObjectARB(glsl_program);
1.106 + glDeleteObjectARB(glsl_vert_shader);
1.107 + glDeleteObjectARB(glsl_frag_shader);
1.108 +}
1.109 +
1.110 +#else
1.111 +gboolean glsl_check_shader_error( char *msg, GLuint shader )
1.112 +{
1.113 + GLint value;
1.114 +
1.115 + glGetShaderiv( shader, GL_COMPILE_STATUS, &value );
1.116 + if( value == 0 ) {
1.117 + char buf[MAX_ERROR_BUF];
1.118 + GLsizei length;
1.119 + glGetShaderInfoLog( shader, sizeof(buf), &length, buf );
1.120 + ERROR( "%s: %s", msg, buf );
1.121 + return FALSE;
1.122 + }
1.123 + return TRUE;
1.124 +}
1.125 +gboolean glsl_check_program_error( char *msg, GLuint program )
1.126 +{
1.127 + if( glGetError() != GL_NO_ERROR ) {
1.128 + char buf[MAX_ERROR_BUF];
1.129 + GLsizei length;
1.130 + glGetProgramInfoLog( program, sizeof(buf), &length, buf );
1.131 + ERROR( "%s: %s", msg, buf );
1.132 + return FALSE;
1.133 + }
1.134 + return TRUE;
1.135 +}
1.136 +
1.137 +gboolean glsl_load_shaders( const char *vertex_src, const char *fragment_src )
1.138 +{
1.139 + gboolean vsok, fsok, pok = FALSE;
1.140 + glsl_program = glCreateProgram();
1.141 + glsl_vert_shader = glCreateShader(GL_VERTEX_SHADER);
1.142 + glsl_frag_shader = glCreateShader(GL_FRAGMENT_SHADER);
1.143 + glShaderSource( glsl_vert_shader, 1, &vertex_src, NULL );
1.144 + glCompileShader(glsl_vert_shader);
1.145 + vsok = glsl_check_shader_error( "Failed to compile vertex shader", glsl_vert_shader );
1.146 + glShaderSource( glsl_frag_shader, 1, &fragment_src, NULL );
1.147 + glCompileShader(glsl_frag_shader);
1.148 + fsok = glsl_check_shader_error( "Failed to compile fragment shader", glsl_frag_shader );
1.149 +
1.150 + if( vsok && fsok ) {
1.151 + glAttachShader(glsl_program, glsl_vert_shader);
1.152 + glAttachShader(glsl_program, glsl_frag_shader);
1.153 + glLinkProgram(glsl_program);
1.154 + pok = glsl_check_program_error( "Failed to link shader program", glsl_program );
1.155 + }
1.156 +
1.157 + if( pok ) {
1.158 + glUseProgram(glsl_program);
1.159 + } else {
1.160 + glsl_unload_shaders();
1.161 + }
1.162 + return pok;
1.163 +}
1.164 +
1.165 +void glsl_unload_shaders(void)
1.166 +{
1.167 + glUseProgram(0);
1.168 + glDetachShader(glsl_program, glsl_vert_shader);
1.169 + glDetachShader(glsl_program, glsl_frag_shader);
1.170 + glDeleteProgram(glsl_program);
1.171 + glDeleteShader(glsl_vert_shader);
1.172 + glDeleteShader(glsl_frag_shader);
1.173 +}
1.174 +#endif
.