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 424:421d68e78c46
prev405:570d93abb5b7
next477:9a373f2ff009
author nkeynes
date Sun Oct 07 05:42:25 2007 +0000 (12 years ago)
permissions -rw-r--r--
last change Fix compilation warnings
file annotate diff log raw
nkeynes@405
     1
/**
nkeynes@424
     2
 * $Id: gl_sl.c,v 1.2 2007-10-07 05:42:25 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@424
    21
#define GL_GLEXT_PROTOTYPES 1
nkeynes@405
    22
nkeynes@405
    23
#include <GL/gl.h>
nkeynes@405
    24
#include <GL/glext.h>
nkeynes@405
    25
#include "drivers/gl_common.h"
nkeynes@405
    26
#include "display.h"
nkeynes@405
    27
nkeynes@405
    28
#define MAX_ERROR_BUF 4096
nkeynes@405
    29
nkeynes@405
    30
static GLuint glsl_program, glsl_vert_shader, glsl_frag_shader;
nkeynes@405
    31
nkeynes@405
    32
gboolean glsl_is_supported()
nkeynes@405
    33
{
nkeynes@405
    34
    return isGLExtensionSupported("GL_ARB_fragment_shader") &&
nkeynes@405
    35
	isGLExtensionSupported("GL_ARB_vertex_shader") &&
nkeynes@405
    36
	isGLExtensionSupported("GL_ARB_shading_language_100");
nkeynes@405
    37
}
nkeynes@405
    38
nkeynes@405
    39
#ifdef GL_ARB_shader_objects
nkeynes@405
    40
void glsl_print_error( char *msg, GLhandleARB obj )
nkeynes@405
    41
{
nkeynes@405
    42
    char buf[MAX_ERROR_BUF];
nkeynes@405
    43
    GLsizei length;
nkeynes@405
    44
    glGetInfoLogARB( obj, sizeof(buf), &length, buf );
nkeynes@405
    45
    ERROR( "%s: %s", msg, buf );
nkeynes@405
    46
}
nkeynes@405
    47
nkeynes@405
    48
gboolean glsl_check_shader_error( char *msg, GLhandleARB obj )
nkeynes@405
    49
{
nkeynes@405
    50
    GLint value;
nkeynes@405
    51
nkeynes@405
    52
    glGetObjectParameterivARB(obj, GL_OBJECT_COMPILE_STATUS_ARB, &value);
nkeynes@405
    53
    if( value == 0 ) {
nkeynes@405
    54
	glsl_print_error(msg, obj);
nkeynes@405
    55
	return FALSE;
nkeynes@405
    56
    }
nkeynes@405
    57
    return TRUE;
nkeynes@405
    58
}
nkeynes@405
    59
nkeynes@405
    60
gboolean glsl_check_program_error( char *msg, GLhandleARB obj )
nkeynes@405
    61
{
nkeynes@405
    62
    if( glGetError() != GL_NO_ERROR ) {
nkeynes@405
    63
	glsl_print_error(msg, obj);
nkeynes@405
    64
    }
nkeynes@405
    65
    return TRUE;
nkeynes@405
    66
}
nkeynes@405
    67
nkeynes@405
    68
nkeynes@405
    69
gboolean glsl_load_shaders( const char *vertex_src, const char *fragment_src )
nkeynes@405
    70
{
nkeynes@405
    71
    gboolean vsok, fsok, pok = FALSE;
nkeynes@405
    72
    glsl_program = glCreateProgramObjectARB();
nkeynes@405
    73
nkeynes@405
    74
    glsl_vert_shader = glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB);
nkeynes@405
    75
    glsl_frag_shader = glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB);
nkeynes@405
    76
    glShaderSourceARB( glsl_vert_shader, 1, &vertex_src, NULL );
nkeynes@405
    77
    glCompileShaderARB(glsl_vert_shader);
nkeynes@405
    78
    vsok = glsl_check_shader_error("Failed to compile vertex shader", glsl_vert_shader);
nkeynes@405
    79
    glShaderSourceARB( glsl_frag_shader, 1, &fragment_src, NULL );
nkeynes@405
    80
    glCompileShaderARB(glsl_frag_shader);
nkeynes@405
    81
    fsok = glsl_check_shader_error("Failed to compile fragment shader", glsl_frag_shader);
nkeynes@405
    82
nkeynes@405
    83
    if( vsok && fsok ) {
nkeynes@405
    84
	glAttachObjectARB(glsl_program, glsl_vert_shader);
nkeynes@405
    85
	glAttachObjectARB(glsl_program, glsl_frag_shader);
nkeynes@405
    86
	glLinkProgramARB(glsl_program);
nkeynes@405
    87
	pok = glsl_check_program_error( "Failed to link shader program", glsl_program );
nkeynes@405
    88
    }
nkeynes@405
    89
    if( pok ) {
nkeynes@405
    90
	glUseProgramObjectARB(glsl_program);
nkeynes@405
    91
	pok = glsl_check_program_error( "Failed to apply shader program", glsl_program );
nkeynes@405
    92
    } else {
nkeynes@405
    93
	glsl_unload_shaders();
nkeynes@405
    94
    }
nkeynes@405
    95
    return pok;
nkeynes@405
    96
}
nkeynes@405
    97
nkeynes@405
    98
void glsl_unload_shaders(void)
nkeynes@405
    99
{
nkeynes@405
   100
    glUseProgramObjectARB(0);
nkeynes@405
   101
    glDetachObjectARB(glsl_program, glsl_vert_shader);
nkeynes@405
   102
    glDetachObjectARB(glsl_program, glsl_frag_shader);
nkeynes@405
   103
    glDeleteObjectARB(glsl_program);
nkeynes@405
   104
    glDeleteObjectARB(glsl_vert_shader);
nkeynes@405
   105
    glDeleteObjectARB(glsl_frag_shader);
nkeynes@405
   106
}
nkeynes@405
   107
nkeynes@405
   108
#else
nkeynes@405
   109
gboolean glsl_check_shader_error( char *msg, GLuint shader )
nkeynes@405
   110
{
nkeynes@405
   111
    GLint value;
nkeynes@405
   112
nkeynes@405
   113
    glGetShaderiv( shader, GL_COMPILE_STATUS, &value );
nkeynes@405
   114
    if( value == 0 ) {
nkeynes@405
   115
	char buf[MAX_ERROR_BUF];
nkeynes@405
   116
	GLsizei length;
nkeynes@405
   117
	glGetShaderInfoLog( shader, sizeof(buf), &length, buf );
nkeynes@405
   118
	ERROR( "%s: %s", msg, buf );
nkeynes@405
   119
	return FALSE;
nkeynes@405
   120
    }
nkeynes@405
   121
    return TRUE;
nkeynes@405
   122
}
nkeynes@405
   123
gboolean glsl_check_program_error( char *msg, GLuint program )
nkeynes@405
   124
{
nkeynes@405
   125
    if( glGetError() != GL_NO_ERROR ) {
nkeynes@405
   126
	char buf[MAX_ERROR_BUF];
nkeynes@405
   127
	GLsizei length;
nkeynes@405
   128
	glGetProgramInfoLog( program, sizeof(buf), &length, buf );
nkeynes@405
   129
	ERROR( "%s: %s", msg, buf );
nkeynes@405
   130
	return FALSE;
nkeynes@405
   131
    }
nkeynes@405
   132
    return TRUE;
nkeynes@405
   133
}
nkeynes@405
   134
nkeynes@405
   135
gboolean glsl_load_shaders( const char *vertex_src, const char *fragment_src )
nkeynes@405
   136
{
nkeynes@405
   137
    gboolean vsok, fsok, pok = FALSE;
nkeynes@405
   138
    glsl_program = glCreateProgram();
nkeynes@405
   139
    glsl_vert_shader = glCreateShader(GL_VERTEX_SHADER);
nkeynes@405
   140
    glsl_frag_shader = glCreateShader(GL_FRAGMENT_SHADER);
nkeynes@405
   141
    glShaderSource( glsl_vert_shader, 1, &vertex_src, NULL );
nkeynes@405
   142
    glCompileShader(glsl_vert_shader);
nkeynes@405
   143
    vsok = glsl_check_shader_error( "Failed to compile vertex shader", glsl_vert_shader );
nkeynes@405
   144
    glShaderSource( glsl_frag_shader, 1, &fragment_src, NULL );
nkeynes@405
   145
    glCompileShader(glsl_frag_shader);
nkeynes@405
   146
    fsok = glsl_check_shader_error( "Failed to compile fragment shader", glsl_frag_shader );
nkeynes@405
   147
nkeynes@405
   148
    if( vsok && fsok ) {
nkeynes@405
   149
	glAttachShader(glsl_program, glsl_vert_shader);
nkeynes@405
   150
	glAttachShader(glsl_program, glsl_frag_shader);
nkeynes@405
   151
	glLinkProgram(glsl_program);
nkeynes@405
   152
	pok = glsl_check_program_error( "Failed to link shader program", glsl_program );
nkeynes@405
   153
    }
nkeynes@405
   154
nkeynes@405
   155
    if( pok ) {
nkeynes@405
   156
	glUseProgram(glsl_program);
nkeynes@405
   157
    } else {
nkeynes@405
   158
	glsl_unload_shaders();
nkeynes@405
   159
    }
nkeynes@405
   160
    return pok;
nkeynes@405
   161
}
nkeynes@405
   162
nkeynes@405
   163
void glsl_unload_shaders(void)
nkeynes@405
   164
{
nkeynes@405
   165
    glUseProgram(0);
nkeynes@405
   166
    glDetachShader(glsl_program, glsl_vert_shader);
nkeynes@405
   167
    glDetachShader(glsl_program, glsl_frag_shader);
nkeynes@405
   168
    glDeleteProgram(glsl_program);
nkeynes@405
   169
    glDeleteShader(glsl_vert_shader);
nkeynes@405
   170
    glDeleteShader(glsl_frag_shader);
nkeynes@405
   171
}
nkeynes@405
   172
#endif
.