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