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 736:a02d1475ccfd
prev679:f5ae66677a49
next1009:c29795e15cef
author nkeynes
date Sun Oct 19 05:09:31 2008 +0000 (15 years ago)
permissions -rw-r--r--
last change Remove unused fields from vertex_struct
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
#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@635
    26
nkeynes@635
    27
gboolean glsl_is_supported()
nkeynes@635
    28
{
nkeynes@635
    29
    return isGLExtensionSupported("GL_ARB_fragment_shader") &&
nkeynes@736
    30
    isGLExtensionSupported("GL_ARB_vertex_shader") &&
nkeynes@736
    31
    isGLExtensionSupported("GL_ARB_shading_language_100");
nkeynes@635
    32
}
nkeynes@635
    33
nkeynes@635
    34
#ifdef GL_ARB_shader_objects
nkeynes@635
    35
static GLhandleARB glsl_program = 0, glsl_vert_shader = 0, glsl_frag_shader = 0;
nkeynes@635
    36
nkeynes@635
    37
void glsl_print_error( char *msg, GLhandleARB obj )
nkeynes@635
    38
{
nkeynes@635
    39
    char buf[MAX_ERROR_BUF];
nkeynes@635
    40
    GLsizei length;
nkeynes@635
    41
    glGetInfoLogARB( obj, sizeof(buf), &length, buf );
nkeynes@635
    42
    ERROR( "%s: %s", msg, buf );
nkeynes@635
    43
}
nkeynes@635
    44
nkeynes@635
    45
gboolean glsl_check_shader_error( char *msg, GLhandleARB obj )
nkeynes@635
    46
{
nkeynes@635
    47
    GLint value;
nkeynes@635
    48
nkeynes@635
    49
    glGetObjectParameterivARB(obj, GL_OBJECT_COMPILE_STATUS_ARB, &value);
nkeynes@635
    50
    if( value == 0 ) {
nkeynes@736
    51
        glsl_print_error(msg, obj);
nkeynes@736
    52
        return FALSE;
nkeynes@635
    53
    }
nkeynes@635
    54
    return TRUE;
nkeynes@635
    55
}
nkeynes@635
    56
nkeynes@635
    57
gboolean glsl_check_program_error( char *msg, GLhandleARB obj )
nkeynes@635
    58
{
nkeynes@635
    59
    if( glGetError() != GL_NO_ERROR ) {
nkeynes@736
    60
        glsl_print_error(msg, obj);
nkeynes@635
    61
    }
nkeynes@635
    62
    return TRUE;
nkeynes@635
    63
}
nkeynes@635
    64
nkeynes@635
    65
nkeynes@635
    66
gboolean glsl_load_shaders( const char *vertex_src, const char *fragment_src )
nkeynes@635
    67
{
nkeynes@635
    68
    gboolean vsok = TRUE, fsok = TRUE, pok = FALSE;
nkeynes@635
    69
nkeynes@635
    70
    if( vertex_src == NULL && fragment_src == NULL ) {
nkeynes@736
    71
        return TRUE; // nothing to do
nkeynes@635
    72
    }
nkeynes@635
    73
nkeynes@635
    74
    glsl_program = glCreateProgramObjectARB();
nkeynes@635
    75
nkeynes@635
    76
    if( vertex_src != NULL ) {
nkeynes@736
    77
        glsl_vert_shader = glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB);
nkeynes@736
    78
        glShaderSourceARB( glsl_vert_shader, 1, &vertex_src, NULL );
nkeynes@736
    79
        glCompileShaderARB(glsl_vert_shader);
nkeynes@736
    80
        vsok = glsl_check_shader_error("Failed to compile vertex shader", glsl_vert_shader);
nkeynes@635
    81
    }
nkeynes@635
    82
    if( fragment_src != NULL ) {
nkeynes@736
    83
        glsl_frag_shader = glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB);
nkeynes@736
    84
        glShaderSourceARB( glsl_frag_shader, 1, &fragment_src, NULL );
nkeynes@736
    85
        glCompileShaderARB(glsl_frag_shader);
nkeynes@736
    86
        fsok = glsl_check_shader_error("Failed to compile fragment shader", glsl_frag_shader);
nkeynes@635
    87
    }
nkeynes@635
    88
nkeynes@635
    89
    if( vsok && fsok ) {
nkeynes@736
    90
        if( vertex_src != NULL ) {
nkeynes@736
    91
            glAttachObjectARB(glsl_program, glsl_vert_shader);
nkeynes@736
    92
        }
nkeynes@736
    93
        if( fragment_src != NULL ) {
nkeynes@736
    94
            glAttachObjectARB(glsl_program, glsl_frag_shader);
nkeynes@736
    95
        }
nkeynes@736
    96
        glLinkProgramARB(glsl_program);
nkeynes@736
    97
        pok = glsl_check_program_error( "Failed to link shader program", glsl_program );
nkeynes@635
    98
    }
nkeynes@635
    99
    if( pok ) {
nkeynes@736
   100
        glUseProgramObjectARB(glsl_program);
nkeynes@736
   101
        pok = glsl_check_program_error( "Failed to apply shader program", glsl_program );
nkeynes@736
   102
        glsl_enable_shaders(FALSE); // initially disabled
nkeynes@635
   103
    } else {
nkeynes@736
   104
        glsl_unload_shaders();
nkeynes@635
   105
    }
nkeynes@635
   106
    return pok;
nkeynes@635
   107
}
nkeynes@635
   108
nkeynes@669
   109
void glsl_enable_shaders(gboolean en)
nkeynes@635
   110
{
nkeynes@635
   111
    if( glsl_program != 0 ) {
nkeynes@736
   112
        if( en ) {
nkeynes@736
   113
            glUseProgramObjectARB(glsl_program);
nkeynes@736
   114
        } else {
nkeynes@736
   115
            glUseProgramObjectARB(0);
nkeynes@736
   116
        }
nkeynes@635
   117
    }
nkeynes@635
   118
}
nkeynes@635
   119
nkeynes@635
   120
void glsl_unload_shaders(void)
nkeynes@635
   121
{
nkeynes@635
   122
    glUseProgramObjectARB(0);
nkeynes@635
   123
    glDetachObjectARB(glsl_program, glsl_vert_shader);
nkeynes@635
   124
    glDetachObjectARB(glsl_program, glsl_frag_shader);
nkeynes@635
   125
    glDeleteObjectARB(glsl_program);
nkeynes@635
   126
    glDeleteObjectARB(glsl_vert_shader);
nkeynes@635
   127
    glDeleteObjectARB(glsl_frag_shader);
nkeynes@635
   128
}
nkeynes@635
   129
nkeynes@656
   130
#elif HAVE_OPENGL_SHADER
nkeynes@635
   131
static GLuint glsl_program = 0, glsl_vert_shader = 0, glsl_frag_shader = 0;
nkeynes@635
   132
nkeynes@635
   133
gboolean glsl_check_shader_error( char *msg, GLuint shader )
nkeynes@635
   134
{
nkeynes@635
   135
    GLint value;
nkeynes@635
   136
nkeynes@635
   137
    glGetShaderiv( shader, GL_COMPILE_STATUS, &value );
nkeynes@635
   138
    if( value == 0 ) {
nkeynes@736
   139
        char buf[MAX_ERROR_BUF];
nkeynes@736
   140
        GLsizei length;
nkeynes@736
   141
        glGetShaderInfoLog( shader, sizeof(buf), &length, buf );
nkeynes@736
   142
        ERROR( "%s: %s", msg, buf );
nkeynes@736
   143
        return FALSE;
nkeynes@635
   144
    }
nkeynes@635
   145
    return TRUE;
nkeynes@635
   146
}
nkeynes@635
   147
gboolean glsl_check_program_error( char *msg, GLuint program )
nkeynes@635
   148
{
nkeynes@635
   149
    if( glGetError() != GL_NO_ERROR ) {
nkeynes@736
   150
        char buf[MAX_ERROR_BUF];
nkeynes@736
   151
        GLsizei length;
nkeynes@736
   152
        glGetProgramInfoLog( program, sizeof(buf), &length, buf );
nkeynes@736
   153
        ERROR( "%s: %s", msg, buf );
nkeynes@736
   154
        return FALSE;
nkeynes@635
   155
    }
nkeynes@635
   156
    return TRUE;
nkeynes@635
   157
}
nkeynes@635
   158
nkeynes@635
   159
gboolean glsl_load_shaders( const char *vertex_src, const char *fragment_src )
nkeynes@635
   160
{
nkeynes@635
   161
    gboolean vsok = TRUE, fsok = TRUE, pok = FALSE;
nkeynes@635
   162
nkeynes@635
   163
    if( vertex_src == NULL && fragment_src == NULL ) {
nkeynes@736
   164
        return TRUE;
nkeynes@635
   165
    }
nkeynes@635
   166
nkeynes@635
   167
    glsl_program = glCreateProgram();
nkeynes@635
   168
nkeynes@635
   169
    if( vertex_src != NULL ) {
nkeynes@736
   170
        glsl_vert_shader = glCreateShader(GL_VERTEX_SHADER);
nkeynes@736
   171
        glShaderSource( glsl_vert_shader, 1, &vertex_src, NULL );
nkeynes@736
   172
        glCompileShader(glsl_vert_shader);
nkeynes@736
   173
        vsok = glsl_check_shader_error( "Failed to compile vertex shader", glsl_vert_shader );
nkeynes@635
   174
    }
nkeynes@635
   175
    if( fragment_src != NULL ) {
nkeynes@736
   176
        glsl_frag_shader = glCreateShader(GL_FRAGMENT_SHADER);
nkeynes@736
   177
        glShaderSource( glsl_frag_shader, 1, &fragment_src, NULL );
nkeynes@736
   178
        glCompileShader(glsl_frag_shader);
nkeynes@736
   179
        fsok = glsl_check_shader_error( "Failed to compile fragment shader", glsl_frag_shader );
nkeynes@635
   180
    }
nkeynes@635
   181
nkeynes@635
   182
    if( vsok && fsok ) {
nkeynes@736
   183
        if( vertex_src != NULL ) {
nkeynes@736
   184
            glAttachShader(glsl_program, glsl_vert_shader);
nkeynes@736
   185
        }
nkeynes@736
   186
        if( fragment_src != NULL ) {
nkeynes@736
   187
            glAttachShader(glsl_program, glsl_frag_shader);
nkeynes@736
   188
        }
nkeynes@736
   189
        glLinkProgram(glsl_program);
nkeynes@736
   190
        pok = glsl_check_program_error( "Failed to link shader program", glsl_program );
nkeynes@635
   191
    }
nkeynes@635
   192
nkeynes@635
   193
    if( pok ) {
nkeynes@736
   194
        glUseProgram(glsl_program);
nkeynes@736
   195
        pok = glsl_check_program_error( "Failed to apply shader program", glsl_program );
nkeynes@736
   196
        glsl_enable_shaders(FALSE); // initially disabled
nkeynes@635
   197
    } else {
nkeynes@736
   198
        glsl_unload_shaders();
nkeynes@635
   199
    }
nkeynes@635
   200
    return pok;
nkeynes@635
   201
}
nkeynes@635
   202
nkeynes@635
   203
nkeynes@669
   204
void glsl_enable_shaders(gboolean en)
nkeynes@635
   205
{
nkeynes@635
   206
    if( glsl_program != 0 ) {
nkeynes@736
   207
        if( en ) {
nkeynes@736
   208
            glUseProgram(glsl_program);
nkeynes@736
   209
        } else {
nkeynes@736
   210
            glUseProgram(0);
nkeynes@736
   211
        }
nkeynes@635
   212
    }
nkeynes@635
   213
}
nkeynes@635
   214
nkeynes@635
   215
void glsl_unload_shaders(void)
nkeynes@635
   216
{
nkeynes@635
   217
    glUseProgram(0);
nkeynes@635
   218
    glDetachShader(glsl_program, glsl_vert_shader);
nkeynes@635
   219
    glDetachShader(glsl_program, glsl_frag_shader);
nkeynes@635
   220
    glDeleteProgram(glsl_program);
nkeynes@635
   221
    glDeleteShader(glsl_vert_shader);
nkeynes@635
   222
    glDeleteShader(glsl_frag_shader);
nkeynes@635
   223
}
nkeynes@656
   224
nkeynes@656
   225
#else
nkeynes@656
   226
gboolean glsl_load_shaders( const char *vertex_src, const char *fragment_src )
nkeynes@656
   227
{
nkeynes@656
   228
    return FALSE;
nkeynes@656
   229
}
nkeynes@656
   230
nkeynes@656
   231
void glsl_unload_shaders()
nkeynes@656
   232
{
nkeynes@656
   233
}
nkeynes@656
   234
nkeynes@669
   235
void glsl_enable_shaders( gboolean enable )
nkeynes@669
   236
{
nkeynes@669
   237
}
nkeynes@635
   238
#endif
.