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 1207:f7ca985659c6
prev1206:a9b41bcb8410
next1208:6955202d6408
author nkeynes
date Tue Feb 07 11:20:00 2012 +1000 (12 years ago)
permissions -rw-r--r--
last change Gen helper functions for uniform + attribute variables, along with the main
program use, to provide a more usable interface to the shaders
file annotate diff log raw
nkeynes@635
     1
/**
nkeynes@635
     2
 * $Id$
nkeynes@635
     3
 *
nkeynes@1130
     4
 * GLSL wrapper code to hide the differences between the different gl/sl APIs.
nkeynes@1130
     5
  *
nkeynes@1130
     6
 * Copyright (c) 2007-2010 Nathan Keynes.
nkeynes@635
     7
 *
nkeynes@635
     8
 * This program is free software; you can redistribute it and/or modify
nkeynes@635
     9
 * it under the terms of the GNU General Public License as published by
nkeynes@635
    10
 * the Free Software Foundation; either version 2 of the License, or
nkeynes@635
    11
 * (at your option) any later version.
nkeynes@635
    12
 *
nkeynes@635
    13
 * This program is distributed in the hope that it will be useful,
nkeynes@635
    14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
nkeynes@635
    15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
nkeynes@635
    16
 * GNU General Public License for more details.
nkeynes@635
    17
 */
nkeynes@635
    18
nkeynes@1130
    19
#include <assert.h>
nkeynes@1130
    20
nkeynes@635
    21
#include "lxdream.h"
nkeynes@635
    22
#include "display.h"
nkeynes@635
    23
#include "pvr2/glutil.h"
nkeynes@1207
    24
#include "pvr2/shaders.h"
nkeynes@635
    25
nkeynes@635
    26
#define MAX_ERROR_BUF 4096
nkeynes@1130
    27
#define INVALID_SHADER 0
nkeynes@1130
    28
#define INVALID_PROGRAM 0
nkeynes@1130
    29
nkeynes@1130
    30
#ifdef HAVE_OPENGL_SHADER_ARB
nkeynes@1130
    31
typedef GLhandleARB gl_program_t;
nkeynes@1130
    32
typedef GLhandleARB gl_shader_t;
nkeynes@1130
    33
#else
nkeynes@1130
    34
typedef GLuint gl_program_t;
nkeynes@1130
    35
typedef GLuint gl_shader_t;
nkeynes@1130
    36
#endif
nkeynes@1130
    37
nkeynes@1130
    38
gboolean glsl_is_supported();
nkeynes@1130
    39
gl_shader_t glsl_create_vertex_shader( const char *source );
nkeynes@1130
    40
gl_shader_t glsl_create_fragment_shader( const char *source );
nkeynes@1130
    41
gl_program_t glsl_create_program( gl_shader_t *shaderv );
nkeynes@1130
    42
void glsl_use_program(gl_program_t program);
nkeynes@1130
    43
void glsl_destroy_shader(gl_shader_t shader);
nkeynes@1130
    44
void glsl_destroy_program(gl_program_t program);
nkeynes@1130
    45
nkeynes@1130
    46
#ifdef HAVE_OPENGL_SHADER_ARB
nkeynes@635
    47
nkeynes@635
    48
gboolean glsl_is_supported()
nkeynes@635
    49
{
nkeynes@635
    50
    return isGLExtensionSupported("GL_ARB_fragment_shader") &&
nkeynes@736
    51
    isGLExtensionSupported("GL_ARB_vertex_shader") &&
nkeynes@736
    52
    isGLExtensionSupported("GL_ARB_shading_language_100");
nkeynes@635
    53
}
nkeynes@635
    54
nkeynes@1134
    55
const char *glsl_get_version()
nkeynes@1134
    56
{
nkeynes@1134
    57
    return glGetString(GL_SHADING_LANGUAGE_VERSION_ARB);
nkeynes@1134
    58
}
nkeynes@1134
    59
nkeynes@635
    60
void glsl_print_error( char *msg, GLhandleARB obj )
nkeynes@635
    61
{
nkeynes@635
    62
    char buf[MAX_ERROR_BUF];
nkeynes@635
    63
    GLsizei length;
nkeynes@635
    64
    glGetInfoLogARB( obj, sizeof(buf), &length, buf );
nkeynes@635
    65
    ERROR( "%s: %s", msg, buf );
nkeynes@635
    66
}
nkeynes@635
    67
nkeynes@635
    68
gboolean glsl_check_shader_error( char *msg, GLhandleARB obj )
nkeynes@635
    69
{
nkeynes@635
    70
    GLint value;
nkeynes@635
    71
nkeynes@635
    72
    glGetObjectParameterivARB(obj, GL_OBJECT_COMPILE_STATUS_ARB, &value);
nkeynes@635
    73
    if( value == 0 ) {
nkeynes@736
    74
        glsl_print_error(msg, obj);
nkeynes@736
    75
        return FALSE;
nkeynes@635
    76
    }
nkeynes@635
    77
    return TRUE;
nkeynes@635
    78
}
nkeynes@635
    79
nkeynes@635
    80
gboolean glsl_check_program_error( char *msg, GLhandleARB obj )
nkeynes@635
    81
{
nkeynes@635
    82
    if( glGetError() != GL_NO_ERROR ) {
nkeynes@736
    83
        glsl_print_error(msg, obj);
nkeynes@635
    84
    }
nkeynes@635
    85
    return TRUE;
nkeynes@635
    86
}
nkeynes@635
    87
nkeynes@1130
    88
gl_shader_t glsl_create_vertex_shader( const char *source )
nkeynes@1130
    89
{
nkeynes@1130
    90
    gboolean ok;
nkeynes@1130
    91
    gl_shader_t shader = glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB);
nkeynes@635
    92
nkeynes@1130
    93
    glShaderSourceARB( shader, 1, &source, NULL );
nkeynes@1130
    94
    glCompileShaderARB(shader);
nkeynes@1130
    95
    ok = glsl_check_shader_error("Failed to compile vertex shader", shader);
nkeynes@1130
    96
    if( !ok ) {
nkeynes@1130
    97
        glDeleteObjectARB(shader);
nkeynes@1130
    98
        return INVALID_SHADER;
nkeynes@635
    99
    } else {
nkeynes@1130
   100
        return shader;
nkeynes@635
   101
    }
nkeynes@635
   102
}
nkeynes@635
   103
nkeynes@1130
   104
gl_shader_t glsl_create_fragment_shader( const char *source )
nkeynes@635
   105
{
nkeynes@1130
   106
    gboolean ok;
nkeynes@1130
   107
    gl_shader_t shader = glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB);
nkeynes@1130
   108
nkeynes@1130
   109
    glShaderSourceARB( shader, 1, &source, NULL );
nkeynes@1130
   110
    glCompileShaderARB(shader);
nkeynes@1130
   111
    ok = glsl_check_shader_error("Failed to compile fragment shader", shader);
nkeynes@1130
   112
    if( !ok ) {
nkeynes@1130
   113
        glDeleteObjectARB(shader);
nkeynes@1130
   114
        return INVALID_SHADER;
nkeynes@1130
   115
    } else {
nkeynes@1130
   116
        return shader;
nkeynes@1130
   117
    }
nkeynes@1130
   118
}
nkeynes@1130
   119
nkeynes@1130
   120
gl_program_t glsl_create_program( gl_shader_t *shaderv )
nkeynes@1130
   121
{
nkeynes@1130
   122
    gboolean ok;
nkeynes@1130
   123
    unsigned i;
nkeynes@1130
   124
    gl_program_t program = glCreateProgramObjectARB();
nkeynes@1130
   125
nkeynes@1130
   126
    for( i=0; shaderv[i] != INVALID_SHADER; i++ ) {
nkeynes@1130
   127
        glAttachObjectARB(program, shaderv[i]);
nkeynes@1130
   128
    }
nkeynes@1130
   129
nkeynes@1130
   130
    glLinkProgramARB(program);
nkeynes@1130
   131
    ok = glsl_check_program_error( "Failed to link shader program", program );
nkeynes@1130
   132
    if( !ok ) {
nkeynes@1130
   133
        glDeleteObjectARB(program);
nkeynes@1130
   134
        return INVALID_PROGRAM;
nkeynes@1130
   135
    } else {
nkeynes@1130
   136
        return program;
nkeynes@1130
   137
    }
nkeynes@1130
   138
}
nkeynes@1130
   139
nkeynes@1130
   140
void glsl_use_program(gl_program_t program)
nkeynes@1130
   141
{
nkeynes@1130
   142
    glUseProgramObjectARB(program);
nkeynes@1130
   143
}
nkeynes@1130
   144
nkeynes@1130
   145
void glsl_destroy_shader(gl_shader_t shader)
nkeynes@1130
   146
{
nkeynes@1130
   147
    glDeleteObjectARB(shader);
nkeynes@1130
   148
}
nkeynes@1130
   149
nkeynes@1130
   150
void glsl_destroy_program(gl_program_t program)
nkeynes@1130
   151
{
nkeynes@1130
   152
    glDeleteObjectARB(program);
nkeynes@635
   153
}
nkeynes@635
   154
nkeynes@1207
   155
static inline GLint glsl_get_uniform_location(gl_program_t program, const char *name)
nkeynes@1140
   156
{
nkeynes@1140
   157
    return glGetUniformLocationARB(program, name);
nkeynes@1140
   158
}
nkeynes@1140
   159
nkeynes@1207
   160
static inline GLint glsl_get_attrib_location(gl_program_t program, const char *name)
nkeynes@1206
   161
{
nkeynes@1206
   162
    return glGetAttribLocationARB(program, name);
nkeynes@1206
   163
}
nkeynes@1206
   164
nkeynes@1207
   165
#define glsl_set_uniform_sampler1D(id,v) glUniform1iARB(id,v)
nkeynes@1207
   166
#define glsl_set_uniform_sampler2D(id,v) glUniform1iARB(id,v)
nkeynes@1207
   167
#define glsl_set_uniform_vec4(id,v) glUniform4fvARB(id,1,v)
nkeynes@1207
   168
#define glsl_set_uniform_mat4(id,v) glUniformMatrix4fvARB(id,1,GL_FALSE,v)
nkeynes@1207
   169
#define glsl_set_attrib_vec3(id,stride,v) glVertexAttribPointerARB(id, 3, GL_FLOAT, GL_FALSE, stride, v)
nkeynes@1207
   170
#define glsl_set_attrib_vec4(id,stride,v) glVertexAttribPointerARB(id, 4, GL_FLOAT, GL_FALSE, stride, v)
nkeynes@1206
   171
nkeynes@656
   172
#elif HAVE_OPENGL_SHADER
nkeynes@1130
   173
nkeynes@1130
   174
gboolean glsl_is_supported()
nkeynes@1130
   175
{
nkeynes@1130
   176
    return isGLExtensionSupported("GL_ARB_fragment_shader") &&
nkeynes@1130
   177
    isGLExtensionSupported("GL_ARB_vertex_shader") &&
nkeynes@1130
   178
    isGLExtensionSupported("GL_ARB_shading_language_100");
nkeynes@1130
   179
}
nkeynes@635
   180
nkeynes@1134
   181
const char *glsl_get_version()
nkeynes@1134
   182
{
nkeynes@1134
   183
    return glGetString(GL_SHADING_LANGUAGE_VERSION);
nkeynes@1134
   184
}
nkeynes@1134
   185
nkeynes@635
   186
gboolean glsl_check_shader_error( char *msg, GLuint shader )
nkeynes@635
   187
{
nkeynes@635
   188
    GLint value;
nkeynes@635
   189
nkeynes@635
   190
    glGetShaderiv( shader, GL_COMPILE_STATUS, &value );
nkeynes@635
   191
    if( value == 0 ) {
nkeynes@736
   192
        char buf[MAX_ERROR_BUF];
nkeynes@736
   193
        GLsizei length;
nkeynes@736
   194
        glGetShaderInfoLog( shader, sizeof(buf), &length, buf );
nkeynes@736
   195
        ERROR( "%s: %s", msg, buf );
nkeynes@736
   196
        return FALSE;
nkeynes@635
   197
    }
nkeynes@635
   198
    return TRUE;
nkeynes@635
   199
}
nkeynes@1130
   200
nkeynes@635
   201
gboolean glsl_check_program_error( char *msg, GLuint program )
nkeynes@635
   202
{
nkeynes@635
   203
    if( glGetError() != GL_NO_ERROR ) {
nkeynes@736
   204
        char buf[MAX_ERROR_BUF];
nkeynes@736
   205
        GLsizei length;
nkeynes@736
   206
        glGetProgramInfoLog( program, sizeof(buf), &length, buf );
nkeynes@736
   207
        ERROR( "%s: %s", msg, buf );
nkeynes@736
   208
        return FALSE;
nkeynes@635
   209
    }
nkeynes@635
   210
    return TRUE;
nkeynes@635
   211
}
nkeynes@635
   212
nkeynes@1130
   213
gl_shader_t glsl_create_vertex_shader( const char *source )
nkeynes@635
   214
{
nkeynes@1130
   215
    gboolean ok;
nkeynes@1130
   216
    gl_shader_t shader = glCreateShader(GL_VERTEX_SHADER);
nkeynes@635
   217
nkeynes@1130
   218
    glShaderSource( shader, 1, &source, NULL );
nkeynes@1130
   219
    glCompileShader(shader);
nkeynes@1203
   220
    ok = glsl_check_shader_error( "Failed to compile vertex shader", shader );
nkeynes@1130
   221
    if( !ok ) {
nkeynes@1130
   222
        glDeleteShader(shader);
nkeynes@1130
   223
        return INVALID_SHADER;
nkeynes@1130
   224
    } else {
nkeynes@1130
   225
        return shader;
nkeynes@635
   226
    }
nkeynes@635
   227
nkeynes@1130
   228
}
nkeynes@635
   229
nkeynes@1130
   230
gl_shader_t glsl_create_fragment_shader( const char *source )
nkeynes@1130
   231
{
nkeynes@1130
   232
    gboolean ok;
nkeynes@1130
   233
    gl_shader_t shader = glCreateShader(GL_FRAGMENT_SHADER);
nkeynes@1130
   234
nkeynes@1130
   235
    glShaderSource( shader, 1, &source, NULL );
nkeynes@1130
   236
    glCompileShader(shader);
nkeynes@1203
   237
    ok = glsl_check_shader_error( "Failed to compile fragment shader", shader );
nkeynes@1130
   238
    if( !ok ) {
nkeynes@1130
   239
        glDeleteShader(shader);
nkeynes@1130
   240
        return INVALID_SHADER;
nkeynes@1130
   241
    } else {
nkeynes@1130
   242
        return shader;
nkeynes@635
   243
    }
nkeynes@1130
   244
}
nkeynes@1130
   245
nkeynes@1130
   246
gl_program_t glsl_create_program( gl_shader_t *shaderv )
nkeynes@1130
   247
{
nkeynes@1130
   248
    gboolean ok;
nkeynes@1130
   249
    unsigned i;
nkeynes@1130
   250
    gl_program_t program = glCreateProgram();
nkeynes@1130
   251
nkeynes@1130
   252
    for( i=0; shaderv[i] != INVALID_SHADER; i++ ) {
nkeynes@1130
   253
        glAttachShader(program, shaderv[i]);
nkeynes@1130
   254
    }
nkeynes@1130
   255
    glLinkProgram(program);
nkeynes@1130
   256
    ok = glsl_check_program_error( "Failed to link shader program", program );
nkeynes@1130
   257
    if( !ok ) {
nkeynes@1130
   258
        glDeleteProgram(program);
nkeynes@1130
   259
        return INVALID_PROGRAM;
nkeynes@1130
   260
    } else {
nkeynes@1130
   261
        return program;
nkeynes@1130
   262
    }
nkeynes@1130
   263
}
nkeynes@1130
   264
nkeynes@1130
   265
void glsl_use_program(gl_program_t program)
nkeynes@1130
   266
{
nkeynes@1130
   267
    glUseProgram(program);
nkeynes@1130
   268
}
nkeynes@1130
   269
nkeynes@1130
   270
void glsl_destroy_shader(gl_shader_t shader)
nkeynes@1130
   271
{
nkeynes@1130
   272
    glDeleteShader(shader);
nkeynes@1130
   273
}
nkeynes@1130
   274
nkeynes@1130
   275
void glsl_destroy_program(gl_program_t program)
nkeynes@1130
   276
{
nkeynes@1130
   277
    glDeleteProgram(program);
nkeynes@1130
   278
}
nkeynes@1130
   279
nkeynes@1207
   280
static inline GLint glsl_get_uniform_location(gl_program_t program, const char *name)
nkeynes@1140
   281
{
nkeynes@1140
   282
    return glGetUniformLocation(program, name);
nkeynes@1140
   283
}
nkeynes@1207
   284
static inline GLint glsl_get_attrib_location(gl_program_t program, const char *name)
nkeynes@1206
   285
{
nkeynes@1206
   286
    return glGetAttribLocation(program, name);
nkeynes@1206
   287
}
nkeynes@1207
   288
nkeynes@1207
   289
#define glsl_set_uniform_sampler1D(id,v) glUniform1i(id,v)
nkeynes@1207
   290
#define glsl_set_uniform_sampler2D(id,v) glUniform1i(id,v)
nkeynes@1207
   291
#define glsl_set_uniform_vec4(id,v) glUniform4fv(id,1,v)
nkeynes@1207
   292
#define glsl_set_uniform_mat4(id,v) glUniformMatrix4fv(id,1,GL_FALSE,v)
nkeynes@1207
   293
#define glsl_set_attrib_vec3(id,stride,v) glVertexAttribPointer(id, 3, GL_FLOAT, GL_FALSE, stride, v)
nkeynes@1207
   294
#define glsl_set_attrib_vec4(id,stride,v) glVertexAttribPointer(id, 4, GL_FLOAT, GL_FALSE, stride, v)
nkeynes@1207
   295
nkeynes@1207
   296
nkeynes@1130
   297
#else
nkeynes@1130
   298
gboolean glsl_is_supported()
nkeynes@1130
   299
{
nkeynes@1130
   300
    return FALSE;
nkeynes@1130
   301
}
nkeynes@1130
   302
nkeynes@1203
   303
const char *glsl_get_version()
nkeynes@1134
   304
{
nkeynes@1134
   305
    return 0;
nkeynes@1134
   306
}
nkeynes@1134
   307
nkeynes@1130
   308
gl_shader_t glsl_create_vertex_shader( const char *source )
nkeynes@1130
   309
{
nkeynes@1130
   310
    return 0;
nkeynes@1130
   311
}
nkeynes@1130
   312
nkeynes@1130
   313
gl_shader_t glsl_create_fragment_shader( const char *source )
nkeynes@1130
   314
{
nkeynes@1130
   315
    return 0;
nkeynes@1130
   316
}
nkeynes@1130
   317
nkeynes@1203
   318
gl_program_t glsl_create_program( gl_shader_t *shaderv )
nkeynes@1130
   319
{
nkeynes@1130
   320
    return 0;
nkeynes@1130
   321
}
nkeynes@1130
   322
nkeynes@1130
   323
void glsl_use_program(gl_program_t program)
nkeynes@1130
   324
{
nkeynes@1130
   325
}
nkeynes@1130
   326
nkeynes@1130
   327
void glsl_destroy_shader(gl_shader_t shader)
nkeynes@1130
   328
{
nkeynes@1130
   329
}
nkeynes@1130
   330
nkeynes@1130
   331
void glsl_destroy_program(gl_program_t program)
nkeynes@1130
   332
{
nkeynes@1130
   333
}
nkeynes@1140
   334
nkeynes@1207
   335
static inline GLint glsl_get_uniform_location(gl_program_t program, const char *name)
nkeynes@1140
   336
{
nkeynes@1140
   337
    return 0;
nkeynes@1140
   338
}
nkeynes@1140
   339
nkeynes@1207
   340
static inline GLint glsl_get_attrib_location(gl_program_t program, const char *name)
nkeynes@1206
   341
{
nkeynes@1206
   342
    return 0;
nkeynes@1206
   343
}
nkeynes@1207
   344
nkeynes@1207
   345
#define glsl_set_uniform_sampler2D(id,v)
nkeynes@1207
   346
#define glsl_set_uniform_vec4(id,v)
nkeynes@1207
   347
#define glsl_set_uniform_mat4(id,v)
nkeynes@1207
   348
#define glsl_set_attrib_vec3(id,stride,v)
nkeynes@1207
   349
#define glsl_set_attrib_vec4(id,stride,v)
nkeynes@1207
   350
nkeynes@1207
   351
nkeynes@1130
   352
#endif
nkeynes@1130
   353
nkeynes@1130
   354
/****************************************************************************/
nkeynes@1130
   355
nkeynes@1130
   356
/* Pull in the auto-generated shader definitions */
nkeynes@1130
   357
nkeynes@1130
   358
#include "pvr2/shaders.def"
nkeynes@1130
   359
nkeynes@1130
   360
static gl_program_t program_array[GLSL_NUM_PROGRAMS];
nkeynes@1130
   361
nkeynes@1130
   362
gboolean glsl_load_shaders()
nkeynes@1130
   363
{
nkeynes@1130
   364
    gl_shader_t shader_array[GLSL_NUM_SHADERS];
nkeynes@1130
   365
    gboolean ok = TRUE;
nkeynes@1130
   366
    unsigned i, j;
nkeynes@1130
   367
    for( i=0; i<GLSL_NUM_SHADERS; i++ )
nkeynes@1130
   368
        shader_array[i] = INVALID_SHADER;
nkeynes@1130
   369
    for( i=0; i<GLSL_NUM_PROGRAMS; i++ )
nkeynes@1130
   370
        program_array[i] = INVALID_PROGRAM;
nkeynes@1130
   371
nkeynes@1130
   372
    /* Compile the shader fragments */
nkeynes@1130
   373
    for( i=0; shader_source[i].type != GLSL_NO_SHADER; i++ ) {
nkeynes@1130
   374
        gl_shader_t shader = INVALID_SHADER;
nkeynes@1130
   375
        switch(shader_source[i].type) {
nkeynes@1130
   376
        case GLSL_VERTEX_SHADER:
nkeynes@1130
   377
            shader = glsl_create_vertex_shader(shader_source[i].source);
nkeynes@1130
   378
            break;
nkeynes@1130
   379
        case GLSL_FRAGMENT_SHADER:
nkeynes@1130
   380
            shader = glsl_create_fragment_shader(shader_source[i].source);
nkeynes@1130
   381
            break;
nkeynes@1130
   382
        }
nkeynes@1130
   383
        if( shader == INVALID_SHADER ) {
nkeynes@1130
   384
            ok = FALSE;
nkeynes@1130
   385
            break;
nkeynes@1130
   386
        } else {
nkeynes@1130
   387
            shader_array[i] = shader;
nkeynes@1130
   388
        }
nkeynes@635
   389
    }
nkeynes@635
   390
nkeynes@1130
   391
    /* Link the programs */
nkeynes@1130
   392
    if(ok) for( i=0; program_list[i][0] != GLSL_NO_SHADER; i++ ) {
nkeynes@1130
   393
        gl_shader_t shaderv[GLSL_NUM_SHADERS+1];
nkeynes@1130
   394
        for( j=0; program_list[i][j] != GLSL_NO_SHADER; j++ ) {
nkeynes@1130
   395
            shaderv[j] = shader_array[program_list[i][j]];
nkeynes@736
   396
        }
nkeynes@1130
   397
        shaderv[j] = INVALID_SHADER;
nkeynes@1130
   398
        gl_program_t program = glsl_create_program(shaderv);
nkeynes@1130
   399
        if( program == INVALID_PROGRAM ) {
nkeynes@1130
   400
            ok = FALSE;
nkeynes@1130
   401
            break;
nkeynes@1130
   402
        } else {
nkeynes@1166
   403
            /* Check that we can actually use the program (can this really fail?) */
nkeynes@1166
   404
            glsl_use_program(program);
nkeynes@1166
   405
            if( !glsl_check_program_error( "Failed to activate shader program", program ) ) {
nkeynes@1166
   406
                ok = FALSE;
nkeynes@1166
   407
            }
nkeynes@1130
   408
            program_array[i] = program;
nkeynes@736
   409
        }
nkeynes@635
   410
    }
nkeynes@635
   411
nkeynes@1130
   412
    /**
nkeynes@1130
   413
     * Destroy the compiled fragments (the linked programs don't need them
nkeynes@1130
   414
     * anymore)
nkeynes@1130
   415
     */
nkeynes@1130
   416
    for( i=0; i<GLSL_NUM_SHADERS; i++ ) {
nkeynes@1130
   417
        if( shader_array[i] != INVALID_SHADER )
nkeynes@1130
   418
            glsl_destroy_shader(shader_array[i]);
nkeynes@1130
   419
    }
nkeynes@1130
   420
nkeynes@1130
   421
    /**
nkeynes@1130
   422
     * If we errored, delete the programs. It's all or nothing.
nkeynes@1130
   423
     */
nkeynes@1130
   424
    if( !ok ) {
nkeynes@736
   425
        glsl_unload_shaders();
nkeynes@1130
   426
        return FALSE;
nkeynes@635
   427
    }
nkeynes@1166
   428
    
nkeynes@1207
   429
    glsl_init_programs(program_array);
nkeynes@1166
   430
    glsl_use_program(0);
nkeynes@1130
   431
    return TRUE;
nkeynes@635
   432
}
nkeynes@635
   433
nkeynes@1130
   434
void glsl_unload_shaders()
nkeynes@635
   435
{
nkeynes@1130
   436
    unsigned i;
nkeynes@1130
   437
    for( i=0; i<GLSL_NUM_PROGRAMS; i++ ) {
nkeynes@1130
   438
        if( program_array[i] != INVALID_PROGRAM ) {
nkeynes@1130
   439
            glsl_destroy_program(program_array[i]);
nkeynes@1130
   440
            program_array[i] = INVALID_PROGRAM;
nkeynes@736
   441
        }
nkeynes@635
   442
    }
nkeynes@635
   443
}
nkeynes@635
   444
nkeynes@1130
   445
void glsl_clear_shader()
nkeynes@656
   446
{
nkeynes@1130
   447
    glsl_use_program(0);
nkeynes@656
   448
}
.