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 477:9a373f2ff009
prev424:421d68e78c46
next538:7f176617a968
author nkeynes
date Wed Oct 31 09:10:23 2007 +0000 (12 years ago)
permissions -rw-r--r--
last change Add save/restore of render buffers in save states
Gzip memory blocks in save states
Move front-buffer management back to pvr2
Add screenshot preview when loading save states
Various minor fixes and cleanups
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
static GLuint glsl_program, glsl_vert_shader, glsl_frag_shader;
nkeynes@405
    32
nkeynes@405
    33
gboolean glsl_is_supported()
nkeynes@405
    34
{
nkeynes@405
    35
    return isGLExtensionSupported("GL_ARB_fragment_shader") &&
nkeynes@405
    36
	isGLExtensionSupported("GL_ARB_vertex_shader") &&
nkeynes@405
    37
	isGLExtensionSupported("GL_ARB_shading_language_100");
nkeynes@405
    38
}
nkeynes@405
    39
nkeynes@405
    40
#ifdef GL_ARB_shader_objects
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@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
.