All pastes #2115461 Raw Edit

Guilt

public c v1 · immutable
#2115461 ·published 2012-02-09 19:42 UTC
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();		}