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