Search
lxdream.org :: lxdream/src/drivers/gl_sl.c
lxdream 0.9.1
released Jun 29
Download Now
filename src/drivers/gl_sl.c
changeset 561:533f6b478071
prev540:a3767018a96d
author nkeynes
date Tue Jan 01 05:08:38 2008 +0000 (12 years ago)
branchlxdream-mmu
permissions -rw-r--r--
last change Enable Id keyword on all source files
file annotate diff log raw
nkeynes@405
     1
/**
nkeynes@561
     2
 * $Id$
nkeynes@405
     3
 *
nkeynes@405
     4
 * GLSL shader loader/unloader. Current version assumes there's exactly
nkeynes@405
     5
 * 1 shader program that's used globally. This may turn out not to be the
nkeynes@405
     6
 * most efficient approach.
nkeynes@405
     7
 *
nkeynes@405
     8
 * Copyright (c) 2007 Nathan Keynes.
nkeynes@405
     9
 *
nkeynes@405
    10
 * This program is free software; you can redistribute it and/or modify
nkeynes@405
    11
 * it under the terms of the GNU General Public License as published by
nkeynes@405
    12
 * the Free Software Foundation; either version 2 of the License, or
nkeynes@405
    13
 * (at your option) any later version.
nkeynes@405
    14
 *
nkeynes@405
    15
 * This program is distributed in the hope that it will be useful,
nkeynes@405
    16
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
nkeynes@405
    17
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
nkeynes@405
    18
 * GNU General Public License for more details.
nkeynes@405
    19
 */
nkeynes@405
    20
nkeynes@424
    21
#define GL_GLEXT_PROTOTYPES 1
nkeynes@405
    22
nkeynes@477
    23
#include "lxdream.h"
nkeynes@540
    24
#include "display.h"
nkeynes@405
    25
#include "drivers/gl_common.h"
nkeynes@405
    26
nkeynes@405
    27
#define MAX_ERROR_BUF 4096
nkeynes@405
    28
nkeynes@405
    29
gboolean glsl_is_supported()
nkeynes@405
    30
{
nkeynes@405
    31
    return isGLExtensionSupported("GL_ARB_fragment_shader") &&
nkeynes@405
    32
	isGLExtensionSupported("GL_ARB_vertex_shader") &&
nkeynes@405
    33
	isGLExtensionSupported("GL_ARB_shading_language_100");
nkeynes@405
    34
}
nkeynes@405
    35
nkeynes@405
    36
#ifdef GL_ARB_shader_objects
nkeynes@538
    37
static GLhandleARB glsl_program, glsl_vert_shader, glsl_frag_shader;
nkeynes@538
    38
nkeynes@405
    39
void glsl_print_error( char *msg, GLhandleARB obj )
nkeynes@405
    40
{
nkeynes@405
    41
    char buf[MAX_ERROR_BUF];
nkeynes@405
    42
    GLsizei length;
nkeynes@405
    43
    glGetInfoLogARB( obj, sizeof(buf), &length, buf );
nkeynes@405
    44
    ERROR( "%s: %s", msg, buf );
nkeynes@405
    45
}
nkeynes@405
    46
nkeynes@405
    47
gboolean glsl_check_shader_error( char *msg, GLhandleARB obj )
nkeynes@405
    48
{
nkeynes@405
    49
    GLint value;
nkeynes@405
    50
nkeynes@405
    51
    glGetObjectParameterivARB(obj, GL_OBJECT_COMPILE_STATUS_ARB, &value);
nkeynes@405
    52
    if( value == 0 ) {
nkeynes@405
    53
	glsl_print_error(msg, obj);
nkeynes@405
    54
	return FALSE;
nkeynes@405
    55
    }
nkeynes@405
    56
    return TRUE;
nkeynes@405
    57
}
nkeynes@405
    58
nkeynes@405
    59
gboolean glsl_check_program_error( char *msg, GLhandleARB obj )
nkeynes@405
    60
{
nkeynes@405
    61
    if( glGetError() != GL_NO_ERROR ) {
nkeynes@405
    62
	glsl_print_error(msg, obj);
nkeynes@405
    63
    }
nkeynes@405
    64
    return TRUE;
nkeynes@405
    65
}
nkeynes@405
    66
nkeynes@405
    67
nkeynes@405
    68
gboolean glsl_load_shaders( const char *vertex_src, const char *fragment_src )
nkeynes@405
    69
{
nkeynes@405
    70
    gboolean vsok, fsok, pok = FALSE;
nkeynes@405
    71
    glsl_program = glCreateProgramObjectARB();
nkeynes@405
    72
nkeynes@405
    73
    glsl_vert_shader = glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB);
nkeynes@405
    74
    glsl_frag_shader = glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB);
nkeynes@405
    75
    glShaderSourceARB( glsl_vert_shader, 1, &vertex_src, NULL );
nkeynes@405
    76
    glCompileShaderARB(glsl_vert_shader);
nkeynes@405
    77
    vsok = glsl_check_shader_error("Failed to compile vertex shader", glsl_vert_shader);
nkeynes@405
    78
    glShaderSourceARB( glsl_frag_shader, 1, &fragment_src, NULL );
nkeynes@405
    79
    glCompileShaderARB(glsl_frag_shader);
nkeynes@405
    80
    fsok = glsl_check_shader_error("Failed to compile fragment shader", glsl_frag_shader);
nkeynes@405
    81
nkeynes@405
    82
    if( vsok && fsok ) {
nkeynes@405
    83
	glAttachObjectARB(glsl_program, glsl_vert_shader);
nkeynes@405
    84
	glAttachObjectARB(glsl_program, glsl_frag_shader);
nkeynes@405
    85
	glLinkProgramARB(glsl_program);
nkeynes@405
    86
	pok = glsl_check_program_error( "Failed to link shader program", glsl_program );
nkeynes@405
    87
    }
nkeynes@405
    88
    if( pok ) {
nkeynes@405
    89
	glUseProgramObjectARB(glsl_program);
nkeynes@405
    90
	pok = glsl_check_program_error( "Failed to apply shader program", glsl_program );
nkeynes@405
    91
    } else {
nkeynes@405
    92
	glsl_unload_shaders();
nkeynes@405
    93
    }
nkeynes@405
    94
    return pok;
nkeynes@405
    95
}
nkeynes@405
    96
nkeynes@405
    97
void glsl_unload_shaders(void)
nkeynes@405
    98
{
nkeynes@405
    99
    glUseProgramObjectARB(0);
nkeynes@405
   100
    glDetachObjectARB(glsl_program, glsl_vert_shader);
nkeynes@405
   101
    glDetachObjectARB(glsl_program, glsl_frag_shader);
nkeynes@405
   102
    glDeleteObjectARB(glsl_program);
nkeynes@405
   103
    glDeleteObjectARB(glsl_vert_shader);
nkeynes@405
   104
    glDeleteObjectARB(glsl_frag_shader);
nkeynes@405
   105
}
nkeynes@405
   106
nkeynes@405
   107
#else
nkeynes@538
   108
static GLuint glsl_program, glsl_vert_shader, glsl_frag_shader;
nkeynes@538
   109
nkeynes@405
   110
gboolean glsl_check_shader_error( char *msg, GLuint shader )
nkeynes@405
   111
{
nkeynes@405
   112
    GLint value;
nkeynes@405
   113
nkeynes@405
   114
    glGetShaderiv( shader, GL_COMPILE_STATUS, &value );
nkeynes@405
   115
    if( value == 0 ) {
nkeynes@405
   116
	char buf[MAX_ERROR_BUF];
nkeynes@405
   117
	GLsizei length;
nkeynes@405
   118
	glGetShaderInfoLog( shader, sizeof(buf), &length, buf );
nkeynes@405
   119
	ERROR( "%s: %s", msg, buf );
nkeynes@405
   120
	return FALSE;
nkeynes@405
   121
    }
nkeynes@405
   122
    return TRUE;
nkeynes@405
   123
}
nkeynes@405
   124
gboolean glsl_check_program_error( char *msg, GLuint program )
nkeynes@405
   125
{
nkeynes@405
   126
    if( glGetError() != GL_NO_ERROR ) {
nkeynes@405
   127
	char buf[MAX_ERROR_BUF];
nkeynes@405
   128
	GLsizei length;
nkeynes@405
   129
	glGetProgramInfoLog( program, sizeof(buf), &length, buf );
nkeynes@405
   130
	ERROR( "%s: %s", msg, buf );
nkeynes@405
   131
	return FALSE;
nkeynes@405
   132
    }
nkeynes@405
   133
    return TRUE;
nkeynes@405
   134
}
nkeynes@405
   135
nkeynes@405
   136
gboolean glsl_load_shaders( const char *vertex_src, const char *fragment_src )
nkeynes@405
   137
{
nkeynes@405
   138
    gboolean vsok, fsok, pok = FALSE;
nkeynes@405
   139
    glsl_program = glCreateProgram();
nkeynes@405
   140
    glsl_vert_shader = glCreateShader(GL_VERTEX_SHADER);
nkeynes@405
   141
    glsl_frag_shader = glCreateShader(GL_FRAGMENT_SHADER);
nkeynes@405
   142
    glShaderSource( glsl_vert_shader, 1, &vertex_src, NULL );
nkeynes@405
   143
    glCompileShader(glsl_vert_shader);
nkeynes@405
   144
    vsok = glsl_check_shader_error( "Failed to compile vertex shader", glsl_vert_shader );
nkeynes@405
   145
    glShaderSource( glsl_frag_shader, 1, &fragment_src, NULL );
nkeynes@405
   146
    glCompileShader(glsl_frag_shader);
nkeynes@405
   147
    fsok = glsl_check_shader_error( "Failed to compile fragment shader", glsl_frag_shader );
nkeynes@405
   148
nkeynes@405
   149
    if( vsok && fsok ) {
nkeynes@405
   150
	glAttachShader(glsl_program, glsl_vert_shader);
nkeynes@405
   151
	glAttachShader(glsl_program, glsl_frag_shader);
nkeynes@405
   152
	glLinkProgram(glsl_program);
nkeynes@405
   153
	pok = glsl_check_program_error( "Failed to link shader program", glsl_program );
nkeynes@405
   154
    }
nkeynes@405
   155
nkeynes@405
   156
    if( pok ) {
nkeynes@405
   157
	glUseProgram(glsl_program);
nkeynes@405
   158
    } else {
nkeynes@405
   159
	glsl_unload_shaders();
nkeynes@405
   160
    }
nkeynes@405
   161
    return pok;
nkeynes@405
   162
}
nkeynes@405
   163
nkeynes@405
   164
void glsl_unload_shaders(void)
nkeynes@405
   165
{
nkeynes@405
   166
    glUseProgram(0);
nkeynes@405
   167
    glDetachShader(glsl_program, glsl_vert_shader);
nkeynes@405
   168
    glDetachShader(glsl_program, glsl_frag_shader);
nkeynes@405
   169
    glDeleteProgram(glsl_program);
nkeynes@405
   170
    glDeleteShader(glsl_vert_shader);
nkeynes@405
   171
    glDeleteShader(glsl_frag_shader);
nkeynes@405
   172
}
nkeynes@405
   173
#endif
.