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 405:570d93abb5b7
next424:421d68e78c46
author nkeynes
date Fri Sep 28 07:24:14 2007 +0000 (12 years ago)
permissions -rw-r--r--
last change Add GLSL loader framework
file annotate diff log raw
nkeynes@405
     1
/**
nkeynes@405
     2
 * $Id: gl_sl.c,v 1.1 2007-09-28 07:24:14 nkeynes Exp $
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@405
    21
nkeynes@405
    22
#include <GL/gl.h>
nkeynes@405
    23
#include <GL/glext.h>
nkeynes@405
    24
#include "drivers/gl_common.h"
nkeynes@405
    25
#include "display.h"
nkeynes@405
    26
nkeynes@405
    27
#define MAX_ERROR_BUF 4096
nkeynes@405
    28
nkeynes@405
    29
static GLuint glsl_program, glsl_vert_shader, glsl_frag_shader;
nkeynes@405
    30
nkeynes@405
    31
gboolean glsl_is_supported()
nkeynes@405
    32
{
nkeynes@405
    33
    return isGLExtensionSupported("GL_ARB_fragment_shader") &&
nkeynes@405
    34
	isGLExtensionSupported("GL_ARB_vertex_shader") &&
nkeynes@405
    35
	isGLExtensionSupported("GL_ARB_shading_language_100");
nkeynes@405
    36
}
nkeynes@405
    37
nkeynes@405
    38
#ifdef GL_ARB_shader_objects
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@405
   108
gboolean glsl_check_shader_error( char *msg, GLuint shader )
nkeynes@405
   109
{
nkeynes@405
   110
    GLint value;
nkeynes@405
   111
nkeynes@405
   112
    glGetShaderiv( shader, GL_COMPILE_STATUS, &value );
nkeynes@405
   113
    if( value == 0 ) {
nkeynes@405
   114
	char buf[MAX_ERROR_BUF];
nkeynes@405
   115
	GLsizei length;
nkeynes@405
   116
	glGetShaderInfoLog( shader, sizeof(buf), &length, buf );
nkeynes@405
   117
	ERROR( "%s: %s", msg, buf );
nkeynes@405
   118
	return FALSE;
nkeynes@405
   119
    }
nkeynes@405
   120
    return TRUE;
nkeynes@405
   121
}
nkeynes@405
   122
gboolean glsl_check_program_error( char *msg, GLuint program )
nkeynes@405
   123
{
nkeynes@405
   124
    if( glGetError() != GL_NO_ERROR ) {
nkeynes@405
   125
	char buf[MAX_ERROR_BUF];
nkeynes@405
   126
	GLsizei length;
nkeynes@405
   127
	glGetProgramInfoLog( program, sizeof(buf), &length, buf );
nkeynes@405
   128
	ERROR( "%s: %s", msg, buf );
nkeynes@405
   129
	return FALSE;
nkeynes@405
   130
    }
nkeynes@405
   131
    return TRUE;
nkeynes@405
   132
}
nkeynes@405
   133
nkeynes@405
   134
gboolean glsl_load_shaders( const char *vertex_src, const char *fragment_src )
nkeynes@405
   135
{
nkeynes@405
   136
    gboolean vsok, fsok, pok = FALSE;
nkeynes@405
   137
    glsl_program = glCreateProgram();
nkeynes@405
   138
    glsl_vert_shader = glCreateShader(GL_VERTEX_SHADER);
nkeynes@405
   139
    glsl_frag_shader = glCreateShader(GL_FRAGMENT_SHADER);
nkeynes@405
   140
    glShaderSource( glsl_vert_shader, 1, &vertex_src, NULL );
nkeynes@405
   141
    glCompileShader(glsl_vert_shader);
nkeynes@405
   142
    vsok = glsl_check_shader_error( "Failed to compile vertex shader", glsl_vert_shader );
nkeynes@405
   143
    glShaderSource( glsl_frag_shader, 1, &fragment_src, NULL );
nkeynes@405
   144
    glCompileShader(glsl_frag_shader);
nkeynes@405
   145
    fsok = glsl_check_shader_error( "Failed to compile fragment shader", glsl_frag_shader );
nkeynes@405
   146
nkeynes@405
   147
    if( vsok && fsok ) {
nkeynes@405
   148
	glAttachShader(glsl_program, glsl_vert_shader);
nkeynes@405
   149
	glAttachShader(glsl_program, glsl_frag_shader);
nkeynes@405
   150
	glLinkProgram(glsl_program);
nkeynes@405
   151
	pok = glsl_check_program_error( "Failed to link shader program", glsl_program );
nkeynes@405
   152
    }
nkeynes@405
   153
nkeynes@405
   154
    if( pok ) {
nkeynes@405
   155
	glUseProgram(glsl_program);
nkeynes@405
   156
    } else {
nkeynes@405
   157
	glsl_unload_shaders();
nkeynes@405
   158
    }
nkeynes@405
   159
    return pok;
nkeynes@405
   160
}
nkeynes@405
   161
nkeynes@405
   162
void glsl_unload_shaders(void)
nkeynes@405
   163
{
nkeynes@405
   164
    glUseProgram(0);
nkeynes@405
   165
    glDetachShader(glsl_program, glsl_vert_shader);
nkeynes@405
   166
    glDetachShader(glsl_program, glsl_frag_shader);
nkeynes@405
   167
    glDeleteProgram(glsl_program);
nkeynes@405
   168
    glDeleteShader(glsl_vert_shader);
nkeynes@405
   169
    glDeleteShader(glsl_frag_shader);
nkeynes@405
   170
}
nkeynes@405
   171
#endif
.