rendered paste body#ifndef _SHADER_H_#define _SHADER_H_// Shader Platform Definitions.#define NONE 0#define GLSL 1#define CG 2#define HLSL 3#define IMPL GLSL#if (IMPL == NONE)#define USE_NONE#elif (IMPL == GLSL)#define USE_GLSL#else#error Unsupported in Allegro 5.1#endif /* //(IMPL == GLSL) */#ifdef USE_NONE#define IMPL_ID "none"#define PLATFORM#endif /* //USE_NONE */#ifdef USE_GLSL#include "allegro5/allegro_opengl.h"#include "allegro5/allegro_shader_glsl.h"#define IMPL_ID "glsl"#define PLATFORM ALLEGRO_SHADER_GLSL#endif /* //USE_GLSL */// Shader Definitions.#define SHADER_PIXEL 0#define SHADER_VERTEX 1#define SHADER_FRAGMENT SHADER_PIXEL#define SHADER_TYPES 2#define SHADER_PARAM_USE_SRC_MATRIX "use_tex_matrix"#define SHADER_PARAM_SRC_MATRIX "tex_matrix"#define SHADER_PARAM_USE_SRC "use_tex"#define SHADER_PARAM_SRC "tex"#define SHADER_PARAM_DEST "dest"#define SHADER_PARAM_AUX "aux"#define SHADER_PARAM_VARYINGCOLOR "varying_color"#define SHADER_PARAM_VARYINGCOORD "varying_texcoord"#define SHADER_PARAM_TIME "time"#ifdef USE_NONEtypedef void *shaderhandle;#elsetypedef ALLEGRO_SHADER * shaderhandle;#endif /* //USE_NONE */typedef struct _shader { shaderhandle shaders;} shader;//Initialize Shader System.int init_shaders();//Destroy Shader System.void quit_shaders();//Destroy a Shadervoid destroy_shader(shader * shade);//Create an Identity Shadershader * identity_shader();//Create a Shadershader * create_shader(char *shadername);#endif /* //_SHADER_H_ */#include <header.h>#include <gameglobal.h>#include <log.h>#include <util.h>#include <shader.h>char shader_type_id[SHADER_TYPES][MAXSTR] = {"pixel", "vertex"};char shader_suffix[MAXSTR] = {".shader"};//Needed if not Fixed Function. static shader *identity = NULL;#ifndef USE_NONEchar identityshadercode[SHADER_TYPES][MAXSTR] = { //Pixel "uniform bool " SHADER_PARAM_USE_SRC ";\n" "uniform sampler2D " SHADER_PARAM_SRC ";\n" "uniform bool " SHADER_PARAM_USE_SRC_MATRIX ";\n" "uniform mat4 " SHADER_PARAM_SRC_MATRIX ";\n" "varying vec2 " SHADER_PARAM_VARYINGCOORD ";\n" "varying vec4 " SHADER_PARAM_VARYINGCOLOR ";\n" "void main(){\n" " vec4 tmp = " SHADER_PARAM_VARYINGCOLOR ";\n" " vec4 coord = vec4(" SHADER_PARAM_VARYINGCOORD ", 0.0, 1.0);\n" " if (" SHADER_PARAM_USE_SRC ") {\n" " vec4 sample = texture2D(" SHADER_PARAM_SRC ", coord.st);\n" " tmp *= sample;\n" " } else if (" SHADER_PARAM_USE_SRC_MATRIX ") {\n" " vec4 sample;\n" " coord = coord * " SHADER_PARAM_SRC_MATRIX ";\n" " sample = texture2D(" SHADER_PARAM_SRC ", coord.st);\n" " tmp *= sample;\n" " }\n" " gl_FragColor = tmp;\n" "}\n" , //Vertex "attribute vec4 pos;\n" "attribute vec4 color;\n" "attribute vec2 texcoord;\n" "uniform mat4 projview_matrix;\n" "varying vec4 " SHADER_PARAM_VARYINGCOLOR ";\n" "varying vec2 " SHADER_PARAM_VARYINGCOORD ";\n" "void main(){\n" "" SHADER_PARAM_VARYINGCOLOR " = color;\n" "" SHADER_PARAM_VARYINGCOORD " = texcoord;\n"#ifndef LINUX "gl_PointSize = 1.0;\n"#endif /* //LINUX */ "gl_Position = projview_matrix * pos;\n" "}\n"};#endif /* //USE_NONE *///Initialize Shader System.int init_shaders(){ log_printf("Initializing Shader System");#ifdef USE_GLSL al_set_new_display_flags(ALLEGRO_USE_PROGRAMMABLE_PIPELINE | ALLEGRO_OPENGL);#endif /* //USE_GLSL */ return 0;}//Destroy Shader System.void quit_shaders(){ if (identity) { destroy_shader(identity); identity = NULL; } log_printf("Uninitializing Shader System");}//Destroy a Shadervoid destroy_shader(shader * shade){ if (shade) { if (shade->shaders) {#ifndef USE_NONE al_destroy_shader(shade->shaders); shade->shaders = NULL;#endif /* //USE_NONE */ } free(shade); shade = NULL; log_printf("Destroyed Shader."); }}#ifndef USE_NONE//Compile a Shader from a String.static int shaderhandle_compile_string(shaderhandle shade, char *string, int type){#ifndef USE_NONE ALLEGRO_SHADER_TYPE atype; if (type == SHADER_PIXEL) { atype = ALLEGRO_PIXEL_SHADER; } else if (type == SHADER_VERTEX) { atype = ALLEGRO_VERTEX_SHADER; } else { return -1; } if (shade == NULL) { return -1; } if (!al_attach_shader_source(shade, atype, string)) { log_printf("Error Compiling Shader of Type: %s %s\n", shader_type_id[type], al_get_shader_log(shade)); return -1; }#endif return 0;}//Compile a Shader from a File.static int shaderhandle_compile_file(shaderhandle shade, char *shader_path, int type){ char *str = get_file_contents(shader_path, NULL); int retval = -1; if (str) { retval = shaderhandle_compile_string(shade, str, type); free(str); str = NULL; } return retval;}#endif /* //USE_NONE *///Create a Shader.shader * create_shader(char *shadername){ shader *s = malloc(sizeof(shader)); if (s) { int loaded; s->shaders = NULL; loaded = 0;#ifndef USE_NONE s->shaders = al_create_shader(PLATFORM); if (s->shaders) { char shaderfilename[MAXSTR]; int t; for (t = 0; t < SHADER_TYPES; ++t) { int retval = 0; *shaderfilename = 0; sprintf(shaderfilename, "%s%c%s%c%s%c%s%c%s%s", DATADIR, PATHSEP, "Shaders", PATHSEP, shadername, PATHSEP, shader_type_id[t], '_', IMPL_ID, ".shader"); if (file_exists(shaderfilename)) retval = shaderhandle_compile_file(s->shaders, shaderfilename, t); else retval = shaderhandle_compile_string(s->shaders, identityshadercode[t], t); if (retval == -1) { log_printf("Unable to Load Shader: %s", shadername); } else { ++loaded; } } if (!loaded || !al_link_shader(s->shaders)) { log_printf("Error Linking Shader: %s %s", shadername, al_get_shader_log(s->shaders)); destroy_shader(s); s = NULL; } else {#ifdef USE_GLSL al_set_opengl_program_object(screen, al_get_opengl_program_object(s->shaders));#endif /* //USE_GLSL */ log_printf("Successfully Loaded Shader: %s", shadername); } }#endif /* //USE_NONE */ } return s;}//Create an Identity Shadershader * identity_shader(){ if (identity) return identity; identity = create_shader("identity"); return identity;}//Source file for miscellaneous functions and utilities.#include <util.h>#include <shader.h> // Truncates a string off trailing newlines and carriage returns char *strip_crlfs(char *str) { char *tmp = str; if (str) while (*str) { if (*str == '\r' || *str == '\n') *str = 0; else str++; } return tmp; } //Skips data from current line onto next line void *skip_line(FILE * flevel) { int c = EOF; char data[MAXSTR], *retval; *data = 0; //Ignore a Line retval = fgets(data, MAXSTR, flevel); //Clean Up c = fgetc(flevel); while (c != EOF && !isprint(c)) c = fgetc(flevel); if (c != EOF && isprint(c)) ungetc(c, flevel); return NULL; } //File Exists. int file_exists(char *file) { FILE *rfile = NULL; rfile = fopen(file, "rb"); if (rfile) { fclose(rfile); rfile = NULL; return 1; } return 0; } //Get File Length. static long get_file_length(FILE * file) { long fcur, flength; fcur = ftell(file); fseek(file, 0, SEEK_END); flength = ftell(file); fseek(file, fcur, SEEK_SET); return flength; } //Get File Contents. char *get_file_contents(char *file, long *length) { FILE *rfile = NULL; long flength = 0; char *array = NULL; if (file) rfile = fopen(file, "rb"); if (rfile) { flength = get_file_length(rfile); array = malloc(sizeof(char) * (flength + 1)); if (array) { fread(array, sizeof(char), flength, rfile); array[flength] = 0; } fclose(rfile); rfile = NULL; } if (length) *length = flength; return array; }#ifdef USE_NONE#define set_shader_params(...)#define unset_shader_params(...) //Sets Current Shader for Draw . void set_shader(shader * s) { } //Unsets Shader. void unset_shader() { }#else static shader *current = NULL; static void set_shader_params(ALLEGRO_BITMAP * src, ALLEGRO_BITMAP * dest, ALLEGRO_BITMAP * aux) { if (current == NULL) current = identity_shader(); if (current) { if (src) { al_set_shader_bool(current->shaders, SHADER_PARAM_USE_SRC, true); al_set_shader_sampler(current->shaders, SHADER_PARAM_SRC, src, 0); } if (!dest) dest = al_get_target_bitmap(); if (dest) al_set_shader_sampler(current->shaders, SHADER_PARAM_DEST, dest, 1); if (aux) al_set_shader_sampler(current->shaders, SHADER_PARAM_AUX, aux, 2); al_use_shader(current->shaders, true); } } static void unset_shader_params() { if (current == NULL) current = identity_shader(); if (current) { al_use_shader(current->shaders, false); } } //Sets Current Shader for Draw . void set_shader(shader * s) { if (s) current = s; } //Unsets Shader. void unset_shader() { current = NULL; }#endif /* //USE_NONE */ //Loads a ALLEGRO_BITMAP ALLEGRO_BITMAP * load_bitmap_ex(char *file, ALLEGRO_COLOR * pal) { ALLEGRO_BITMAP *lbmp = NULL; lbmp = al_load_bitmap(file); if (lbmp) { //Set magenta to transparent al_convert_mask_to_alpha(lbmp, al_map_rgb(255, 0, 255)); } return lbmp; } //Blits a Bitmap to Screen void blit(ALLEGRO_BITMAP * src, float sx, float sy, float dx, float dy, float sw, float sh) { set_shader_params(src, NULL, NULL); al_draw_bitmap_region(src, sx, sy, sw, sh, dx, dy, 0); unset_shader_params(); } //Rotates a Bitmap and Blits to Screen void rotated_blit(ALLEGRO_BITMAP * src, float sx, float sy, float dx, float dy, float sw, float sh, float angle) { ALLEGRO_TRANSFORM old, T; al_copy_transform(&old, al_get_current_transform()); al_build_transform(&T, dx, dy, 1.0f, 1.0f, angle); al_use_transform(&T); set_shader_params(src, NULL, NULL); blit(src, sx, sy, -0.5f * sw, -0.5f * sh, sw, sh); unset_shader_params(); al_use_transform(&old); } //Stretches a Bitmap and Draws to Screen void stretch_blit(ALLEGRO_BITMAP * src, float sx, float sy, float sw, float sh, float dx, float dy, float dw, float dh) { set_shader_params(src, NULL, NULL); al_draw_scaled_bitmap(src, sx, sy, sw, sh, dx, dy, dw, dh, 0); unset_shader_params(); }