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 Feb 14 13:54:11 2008 +0000 (13 years ago)
branchlxdream-render
permissions -rw-r--r--
last change Commit render work in progress. Main changes:
* Preliminary OSMesa support
* Move the generic gl code out to pvr2/
* Implement scene data structure + reader
* Remove the 1/z adjustments
file annotate diff log raw
nkeynes@635
     1
/**
nkeynes@635
     2
 * $Id$
nkeynes@635
     3
 *
nkeynes@635
     4
 * GLSL shader loader/unloader. Current version assumes there's exactly
nkeynes@635
     5
 * 1 shader program that's used globally. This may turn out not to be the
nkeynes@635
     6
 * most efficient approach.
nkeynes@635
     7
 *
nkeynes@635
     8
 * Copyright (c) 2007 Nathan Keynes.
nkeynes@635
     9
 *
nkeynes@635
    10
 * This program is free software; you can redistribute it and/or modify
nkeynes@635
    11
 * it under the terms of the GNU General Public License as published by
nkeynes@635
    12
 * the Free Software Foundation; either version 2 of the License, or
nkeynes@635
    13
 * (at your option) any later version.
nkeynes@635
    14
 *
nkeynes@635
    15
 * This program is distributed in the hope that it will be useful,
nkeynes@635
    16
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
nkeynes@635
    17
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
nkeynes@635
    18
 * GNU General Public License for more details.
nkeynes@635
    19
 */
nkeynes@635
    20
nkeynes@635
    21
#define GL_GLEXT_PROTOTYPES 1
nkeynes@635
    22
nkeynes@635
    23
#include "lxdream.h"
nkeynes@635
    24
#include "display.h"
nkeynes@635
    25
#include "pvr2/glutil.h"
nkeynes@635
    26
nkeynes@635
    27
#define MAX_ERROR_BUF 4096
nkeynes@635
    28
nkeynes@635
    29
gboolean glsl_is_supported()
nkeynes@635
    30
{
nkeynes@635
    31
    return isGLExtensionSupported("GL_ARB_fragment_shader") &&
nkeynes@635
    32
	isGLExtensionSupported("GL_ARB_vertex_shader") &&
nkeynes@635
    33
	isGLExtensionSupported("GL_ARB_shading_language_100");
nkeynes@635
    34
}
nkeynes@635
    35
nkeynes@635
    36
#ifdef GL_ARB_shader_objects
nkeynes@635
    37
static GLhandleARB glsl_program = 0, glsl_vert_shader = 0, glsl_frag_shader = 0;
nkeynes@635
    38
nkeynes@635
    39
void glsl_print_error( char *msg, GLhandleARB obj )
nkeynes@635
    40
{
nkeynes@635
    41
    char buf[MAX_ERROR_BUF];
nkeynes@635
    42
    GLsizei length;
nkeynes@635
    43
    glGetInfoLogARB( obj, sizeof(buf), &length, buf );
nkeynes@635
    44
    ERROR( "%s: %s", msg, buf );
nkeynes@635
    45
}
nkeynes@635
    46
nkeynes@635
    47
gboolean glsl_check_shader_error( char *msg, GLhandleARB obj )
nkeynes@635
    48
{
nkeynes@635
    49
    GLint value;
nkeynes@635
    50
nkeynes@635
    51
    glGetObjectParameterivARB(obj, GL_OBJECT_COMPILE_STATUS_ARB, &value);
nkeynes@635
    52
    if( value == 0 ) {
nkeynes@635
    53
	glsl_print_error(msg, obj);
nkeynes@635
    54
	return FALSE;
nkeynes@635
    55
    }
nkeynes@635
    56
    return TRUE;
nkeynes@635
    57
}
nkeynes@635
    58
nkeynes@635
    59
gboolean glsl_check_program_error( char *msg, GLhandleARB obj )
nkeynes@635
    60
{
nkeynes@635
    61
    if( glGetError() != GL_NO_ERROR ) {
nkeynes@635
    62
	glsl_print_error(msg, obj);
nkeynes@635
    63
    }
nkeynes@635
    64
    return TRUE;
nkeynes@635
    65
}
nkeynes@635
    66
nkeynes@635
    67
nkeynes@635
    68
gboolean glsl_load_shaders( const char *vertex_src, const char *fragment_src )
nkeynes@635
    69
{
nkeynes@635
    70
    gboolean vsok = TRUE, fsok = TRUE, pok = FALSE;
nkeynes@635
    71
nkeynes@635
    72
    if( vertex_src == NULL && fragment_src == NULL ) {
nkeynes@635
    73
	return TRUE; // nothing to do
nkeynes@635
    74
    }
nkeynes@635
    75
nkeynes@635
    76
    glsl_program = glCreateProgramObjectARB();
nkeynes@635
    77
nkeynes@635
    78
    if( vertex_src != NULL ) {
nkeynes@635
    79
	glsl_vert_shader = glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB);
nkeynes@635
    80
	glShaderSourceARB( glsl_vert_shader, 1, &vertex_src, NULL );
nkeynes@635
    81
	glCompileShaderARB(glsl_vert_shader);
nkeynes@635
    82
	vsok = glsl_check_shader_error("Failed to compile vertex shader", glsl_vert_shader);
nkeynes@635
    83
    }
nkeynes@635
    84
    if( fragment_src != NULL ) {
nkeynes@635
    85
	glsl_frag_shader = glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB);
nkeynes@635
    86
	glShaderSourceARB( glsl_frag_shader, 1, &fragment_src, NULL );
nkeynes@635
    87
	glCompileShaderARB(glsl_frag_shader);
nkeynes@635
    88
	fsok = glsl_check_shader_error("Failed to compile fragment shader", glsl_frag_shader);
nkeynes@635
    89
    }
nkeynes@635
    90
nkeynes@635
    91
    if( vsok && fsok ) {
nkeynes@635
    92
	if( vertex_src != NULL ) {
nkeynes@635
    93
	    glAttachObjectARB(glsl_program, glsl_vert_shader);
nkeynes@635
    94
	}
nkeynes@635
    95
	if( fragment_src != NULL ) {
nkeynes@635
    96
	    glAttachObjectARB(glsl_program, glsl_frag_shader);
nkeynes@635
    97
	}
nkeynes@635
    98
	glLinkProgramARB(glsl_program);
nkeynes@635
    99
	pok = glsl_check_program_error( "Failed to link shader program", glsl_program );
nkeynes@635
   100
    }
nkeynes@635
   101
    if( pok ) {
nkeynes@635
   102
	glUseProgramObjectARB(glsl_program);
nkeynes@635
   103
	pok = glsl_check_program_error( "Failed to apply shader program", glsl_program );
nkeynes@635
   104
    } else {
nkeynes@635
   105
	glsl_unload_shaders();
nkeynes@635
   106
    }
nkeynes@635
   107
    return pok;
nkeynes@635
   108
}
nkeynes@635
   109
nkeynes@635
   110
void glsl_enable_shader(gboolean en)
nkeynes@635
   111
{
nkeynes@635
   112
    if( glsl_program != 0 ) {
nkeynes@635
   113
	if( en ) {
nkeynes@635
   114
	    glUseProgramObjectARB(glsl_program);
nkeynes@635
   115
	} else {
nkeynes@635
   116
	    glUseProgramObjectARB(0);
nkeynes@635
   117
	}
nkeynes@635
   118
    }
nkeynes@635
   119
}
nkeynes@635
   120
nkeynes@635
   121
void glsl_unload_shaders(void)
nkeynes@635
   122
{
nkeynes@635
   123
    glUseProgramObjectARB(0);
nkeynes@635
   124
    glDetachObjectARB(glsl_program, glsl_vert_shader);
nkeynes@635
   125
    glDetachObjectARB(glsl_program, glsl_frag_shader);
nkeynes@635
   126
    glDeleteObjectARB(glsl_program);
nkeynes@635
   127
    glDeleteObjectARB(glsl_vert_shader);
nkeynes@635
   128
    glDeleteObjectARB(glsl_frag_shader);
nkeynes@635
   129
}
nkeynes@635
   130
nkeynes@635
   131
#else
nkeynes@635
   132
static GLuint glsl_program = 0, glsl_vert_shader = 0, glsl_frag_shader = 0;
nkeynes@635
   133
nkeynes@635
   134
gboolean glsl_check_shader_error( char *msg, GLuint shader )
nkeynes@635
   135
{
nkeynes@635
   136
    GLint value;
nkeynes@635
   137
nkeynes@635
   138
    glGetShaderiv( shader, GL_COMPILE_STATUS, &value );
nkeynes@635
   139
    if( value == 0 ) {
nkeynes@635
   140
	char buf[MAX_ERROR_BUF];
nkeynes@635
   141
	GLsizei length;
nkeynes@635
   142
	glGetShaderInfoLog( shader, sizeof(buf), &length, buf );
nkeynes@635
   143
	ERROR( "%s: %s", msg, buf );
nkeynes@635
   144
	return FALSE;
nkeynes@635
   145
    }
nkeynes@635
   146
    return TRUE;
nkeynes@635
   147
}
nkeynes@635
   148
gboolean glsl_check_program_error( char *msg, GLuint program )
nkeynes@635
   149
{
nkeynes@635
   150
    if( glGetError() != GL_NO_ERROR ) {
nkeynes@635
   151
	char buf[MAX_ERROR_BUF];
nkeynes@635
   152
	GLsizei length;
nkeynes@635
   153
	glGetProgramInfoLog( program, sizeof(buf), &length, buf );
nkeynes@635
   154
	ERROR( "%s: %s", msg, buf );
nkeynes@635
   155
	return FALSE;
nkeynes@635
   156
    }
nkeynes@635
   157
    return TRUE;
nkeynes@635
   158
}
nkeynes@635
   159
nkeynes@635
   160
gboolean glsl_load_shaders( const char *vertex_src, const char *fragment_src )
nkeynes@635
   161
{
nkeynes@635
   162
    gboolean vsok = TRUE, fsok = TRUE, pok = FALSE;
nkeynes@635
   163
nkeynes@635
   164
    if( vertex_src == NULL && fragment_src == NULL ) {
nkeynes@635
   165
	return TRUE;
nkeynes@635
   166
    }
nkeynes@635
   167
nkeynes@635
   168
    glsl_program = glCreateProgram();
nkeynes@635
   169
nkeynes@635
   170
    if( vertex_src != NULL ) {
nkeynes@635
   171
	glsl_vert_shader = glCreateShader(GL_VERTEX_SHADER);
nkeynes@635
   172
	glShaderSource( glsl_vert_shader, 1, &vertex_src, NULL );
nkeynes@635
   173
	glCompileShader(glsl_vert_shader);
nkeynes@635
   174
	vsok = glsl_check_shader_error( "Failed to compile vertex shader", glsl_vert_shader );
nkeynes@635
   175
    }
nkeynes@635
   176
    if( fragment_src != NULL ) {
nkeynes@635
   177
	glsl_frag_shader = glCreateShader(GL_FRAGMENT_SHADER);
nkeynes@635
   178
	glShaderSource( glsl_frag_shader, 1, &fragment_src, NULL );
nkeynes@635
   179
	glCompileShader(glsl_frag_shader);
nkeynes@635
   180
	fsok = glsl_check_shader_error( "Failed to compile fragment shader", glsl_frag_shader );
nkeynes@635
   181
    }
nkeynes@635
   182
nkeynes@635
   183
    if( vsok && fsok ) {
nkeynes@635
   184
	if( vertex_src != NULL ) {
nkeynes@635
   185
	    glAttachShader(glsl_program, glsl_vert_shader);
nkeynes@635
   186
	}
nkeynes@635
   187
	if( fragment_src != NULL ) {
nkeynes@635
   188
	    glAttachShader(glsl_program, glsl_frag_shader);
nkeynes@635
   189
	}
nkeynes@635
   190
	glLinkProgram(glsl_program);
nkeynes@635
   191
	pok = glsl_check_program_error( "Failed to link shader program", glsl_program );
nkeynes@635
   192
    }
nkeynes@635
   193
nkeynes@635
   194
    if( pok ) {
nkeynes@635
   195
	glUseProgram(glsl_program);
nkeynes@635
   196
    } else {
nkeynes@635
   197
	glsl_unload_shaders();
nkeynes@635
   198
    }
nkeynes@635
   199
    return pok;
nkeynes@635
   200
}
nkeynes@635
   201
nkeynes@635
   202
nkeynes@635
   203
void glsl_enable_shader(gboolean en)
nkeynes@635
   204
{
nkeynes@635
   205
    if( glsl_program != 0 ) {
nkeynes@635
   206
	if( en ) {
nkeynes@635
   207
	    glUseProgram(glsl_program);
nkeynes@635
   208
	} else {
nkeynes@635
   209
	    glUseProgram(0);
nkeynes@635
   210
	}
nkeynes@635
   211
    }
nkeynes@635
   212
}
nkeynes@635
   213
nkeynes@635
   214
void glsl_unload_shaders(void)
nkeynes@635
   215
{
nkeynes@635
   216
    glUseProgram(0);
nkeynes@635
   217
    glDetachShader(glsl_program, glsl_vert_shader);
nkeynes@635
   218
    glDetachShader(glsl_program, glsl_frag_shader);
nkeynes@635
   219
    glDeleteProgram(glsl_program);
nkeynes@635
   220
    glDeleteShader(glsl_vert_shader);
nkeynes@635
   221
    glDeleteShader(glsl_frag_shader);
nkeynes@635
   222
}
nkeynes@635
   223
#endif
.