architecture for shader & boss shader

I didn't think about it. I just. wrote. and it looked like I wanted it to be. yay.
This commit is contained in:
laochailan 2011-04-25 19:40:21 +02:00
parent d280d8c8ad
commit fbccb951c1
16 changed files with 326 additions and 24 deletions

View file

@ -9,6 +9,7 @@ set(CMAKE_CFLAGS="--std=c99")
set(DATA_DIR "share/taisei")
install(DIRECTORY gfx DESTINATION ${DATA_DIR})
install(DIRECTORY sfx DESTINATION ${DATA_DIR})
install(DIRECTORY shader DESTINATION ${DATA_DIR})
# uninstall target
configure_file(

Binary file not shown.

Before

Width:  |  Height:  |  Size: 697 B

After

Width:  |  Height:  |  Size: 934 B

View file

@ -11,7 +11,7 @@
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="16"
height="8"
height="12"
id="svg2"
version="1.1"
inkscape:version="0.48.1 r9760"
@ -77,10 +77,11 @@
<filter
inkscape:collect="always"
id="filter4412"
x="-0.17254389"
x="-0.17254388"
width="1.3450878"
y="-0.12395158"
height="1.2479032">
height="1.2479032"
color-interpolation-filters="sRGB">
<feGaussianBlur
inkscape:collect="always"
stdDeviation="0.095963993"
@ -88,7 +89,8 @@
</filter>
<filter
inkscape:collect="always"
id="filter3777">
id="filter3777"
color-interpolation-filters="sRGB">
<feGaussianBlur
inkscape:collect="always"
stdDeviation="0.16447804"
@ -97,15 +99,36 @@
<filter
inkscape:collect="always"
id="filter3783"
x="-0.15987741"
x="-0.1598774"
width="1.3197548"
y="-0.16618992"
height="1.3323798">
height="1.3323798"
color-interpolation-filters="sRGB">
<feGaussianBlur
inkscape:collect="always"
stdDeviation="0.52392387"
id="feGaussianBlur3785" />
</filter>
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3755"
id="linearGradient3839"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.9563608,0,0,1.955242,0.06992714,1040.0607)"
x1="1.9379158"
y1="0.34551451"
x2="1.9600886"
y2="3.8887517" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3755"
id="linearGradient3841"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(2.1163858,0,0,2.1163858,0.07564699,1039.0469)"
x1="1.9379158"
y1="0.34551451"
x2="1.9600886"
y2="3.8887517" />
</defs>
<sodipodi:namedview
id="base"
@ -116,7 +139,7 @@
inkscape:pageshadow="2"
inkscape:zoom="39.863145"
inkscape:cx="2.1859308"
inkscape:cy="3.7000826"
inkscape:cy="7.8300027"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
@ -133,7 +156,7 @@
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
@ -141,25 +164,28 @@
inkscape:label="Ebene 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(0,-1044.3622)">
transform="translate(0,-1040.3622)">
<path
style="color:#000000;fill:url(#linearGradient3761);fill-opacity:1;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;"
d="m 0.15077605,1052.2779 c 0.37898665,-8.8342 6.67018235,-11.269 7.86488385,0 -2.7488298,-8.6242 -5.3663146,-8.3433 -7.86488385,0 z"
style="color:#000000;fill:url(#linearGradient3839);fill-opacity:1;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;opacity:0.82677165"
d="m 0.36489949,1047.7169 c 0.35033055,-8.1615 6.16583381,-10.4109 7.27020101,0 -2.5409842,-7.9675 -4.9605546,-7.708 -7.27020101,0 z"
id="path2985"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccc" />
<path
style="color:#000000;fill:#005fff;fill-opacity:1;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;filter:url(#filter3783)"
d="m 0.15077605,1052.2779 c 0.37898665,-8.8342 6.67018235,-11.269 7.86488385,0 -2.7488298,-8.6242 -5.3663146,-8.3433 -7.86488385,0 z"
style="opacity:0.56299213;color:#000000;fill:#659eff;fill-opacity:1;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;filter:url(#filter3783);enable-background:accumulate"
d="m 0.15077605,1052.2779 c 0.0776544,-16.901 6.23081395,-23.0311 7.86488385,0 -2.7886226,-9.0012 -5.4199058,-9.1633 -7.86488385,0 z"
id="path3781"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccc"
transform="matrix(0.7171497,0,0,0.67307029,1.1549394,342.78411)" />
transform="matrix(0.66292428,0,0,0.62182203,1.2931356,397.25073)"
inkscape:export-xdpi="180"
inkscape:export-ydpi="180" />
<path
sodipodi:nodetypes="ccc"
inkscape:connector-curvature="0"
id="path3775"
d="m 0.15077605,1052.2779 c 0.37898665,-8.8342 6.67018235,-11.269 7.86488385,0 -2.7488298,-8.6242 -5.3663146,-8.3433 -7.86488385,0 z"
style="color:#000000;fill:url(#linearGradient3761);fill-opacity:1;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;filter:url(#filter3777)" />
d="m 0.39474728,1047.3341 c 0.37898665,-8.8342 6.67018232,-11.269 7.86488382,0 -2.5560342,-7.0818 -5.2264322,-7.2242 -7.86488382,0 z"
style="color:#000000;fill:url(#linearGradient3841);fill-opacity:1;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;filter:url(#filter3777);enable-background:accumulate;opacity:0.82677165"
transform="matrix(0.92438759,0,0,0.92385898,0,80.127931)" />
</g>
</svg>

Before

Width:  |  Height:  |  Size: 5.4 KiB

After

Width:  |  Height:  |  Size: 6.4 KiB

34
shader/boss_zoom.sha Normal file
View file

@ -0,0 +1,34 @@
void main(void)
{
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
gl_FrontColor = gl_Color;
gl_TexCoord[0] = gl_MultiTexCoord0;
}
%% -- FRAG
uniform sampler2D tex;
uniform vec2 blur_orig; // center
uniform vec2 fix_orig;
uniform float rad; // radius of zoom effect
void main(void)
{
vec2 pos = vec2(gl_TexCoord[0]);
pos -= blur_orig;
vec2 pos1 = pos;
pos1.y *= 2.0;
if(length(pos1) < rad)
pos *= length(pos1)/rad;
gl_FragColor = texture2D(tex, pos + blur_orig);
pos1 = vec2(gl_TexCoord[0]) - fix_orig;
pos1.y *= 2.0;
if(length(pos1) < rad)
gl_FragColor *= pow(vec4(0.1,0.2,0.3,1),3.0*(rad - length(pos1)));
}

View file

@ -15,6 +15,7 @@ set(SRCs
boss.c
plrmodes.c
laser.c
shader.c
stages/stage0.c)
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${PROJECT_SOURCE_DIR})
@ -26,7 +27,7 @@ find_package(ALUT REQUIRED)
find_package(SDL_image REQUIRED)
find_package(SDL_ttf REQUIRED)
add_definitions(-DPREFIX="${CMAKE_INSTALL_PREFIX}")
add_definitions(-DPREFIX="${CMAKE_INSTALL_PREFIX}" -DGL_GLEXT_PROTOTYPES)
include_directories(${SDL_INCLUDE_DIRS} ${ALUT_INCLUDE_DIRS})
add_executable(taisei ${SRCs})

View file

@ -43,6 +43,7 @@ void spell_opening(Boss *b, int time) {
draw_text(b->current->name, VIEWPORT_W-strlen(b->current->name)*5, y, _fonts.biolinum);
}
void draw_boss(Boss *boss) {
draw_animation_p(creal(boss->pos), cimag(boss->pos), boss->anirow, boss->ani);

View file

@ -18,6 +18,46 @@ void init_global() {
load_resources();
init_fonts();
init_rtt();
}
void init_rtt() {
glEnable(GL_BLEND);
glGenTextures(1, &global.rtt.tex);
glBindTexture(GL_TEXTURE_2D, global.rtt.tex);
global.rtt.nw = 2;
global.rtt.nh = 2;
while(global.rtt.nw < VIEWPORT_W) global.rtt.nw *= 2;
while(global.rtt.nh < VIEWPORT_H) global.rtt.nh *= 2;
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, global.rtt.nw, global.rtt.nh, 0, GL_BGR, GL_UNSIGNED_BYTE, NULL);
glGenFramebuffersEXT(1,&global.rtt.fbo);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, global.rtt.fbo);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, global.rtt.tex, 0);
glEnable(GL_BLEND);
glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE);
glGenRenderbuffersEXT(1, &global.rtt.depth);
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, global.rtt.depth);
glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT24, global.rtt.nw, global.rtt.nh);
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, global.rtt.depth);
GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
if(status != GL_FRAMEBUFFER_COMPLETE_EXT)
warnx("!- GPU seems not to support Framebuffer Objects");
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
}
void game_over() {

View file

@ -16,11 +16,9 @@
#include "audio.h"
#include "boss.h"
#include "laser.h"
#include "shader.h"
enum {
RESX = 800,
RESY = 600,
enum {
SCREEN_W = 800,
SCREEN_H = 600,
@ -50,6 +48,15 @@ typedef struct {
Texture *textures;
Animation *animations;
Sound *sounds;
Shader *shaders;
struct {
GLuint fbo;
GLuint tex;
GLuint depth;
int nw,nh;
} rtt;
Boss *boss;
@ -67,6 +74,7 @@ typedef struct {
extern Global global;
void init_global();
void init_rtt();
void game_over();
void frame_rate();

View file

@ -19,8 +19,8 @@ void init_gl() {
glShadeModel(GL_SMOOTH);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_LINE_SMOOTH);
glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
@ -42,6 +42,8 @@ void init_gl() {
void shutdown() {
delete_textures();
delete_animations();
delete_sounds();
delete_shaders();
alutExit();
SDL_FreeSurface(display);
@ -54,10 +56,11 @@ int main(int argc, char** argv) {
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL, 0);
if((display = SDL_SetVideoMode(RESX, RESY, 32, SDL_OPENGL)) == NULL)
if((display = SDL_SetVideoMode(SCREEN_W, SCREEN_H, 32, SDL_OPENGL)) == NULL)
errx(-1, "Error opening screen: %s", SDL_GetError());
init_gl();
if(!alutInit(&argc, argv))
errx(-1, "Error initializing audio: %s", alutGetErrorString(alutGetError()));
init_global();

106
src/shader.c Normal file
View file

@ -0,0 +1,106 @@
/*
* This software is licensed under the terms of the MIT-License
* See COPYING for further information.
* ---
* Copyright (C) 2011, Lukas Weber <laochailan@web.de>
*/
#include "shader.h"
#include "global.h"
#include "list.h"
#include <stdio.h>
void print_info_log(GLuint shader) {
int len, alen;
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &len);
if(len > 1) {
char *log = malloc(len);
memset(log, 0, len);
glGetShaderInfoLog(shader, len, &alen, log);
printf("%s\n", log);
free(log);
}
}
void load_shader(const char *filename) {
FILE *file = fopen(filename,"r");
if(file == NULL)
err(-1, "Error opening '%s'", filename);
fseek(file, 0, SEEK_END);
int size = ftell(file);
fseek(file, 0, SEEK_SET);
if(size == 0)
errx(-1, "File empty!");
char *text = malloc(size+1);
fread(text, size, 1, file);
text[size] = 0;
char *vtext = text;
char *delim = strstr(text, DELIM);
if(delim == NULL)
errx(-1, "Expected '%s' delimiter.", DELIM);
*delim = 0;
char *ftext = delim + DELIM_SIZE;
Shader *sha = create_element((void **)&global.shaders, sizeof(Shader));
GLuint vshaderobj;
GLuint fshaderobj;
sha->prog = glCreateProgram();
vshaderobj = glCreateShader(GL_VERTEX_SHADER);
fshaderobj = glCreateShader(GL_FRAGMENT_SHADER);
int s = -1;
glShaderSource(vshaderobj, 1, (const GLchar **)&vtext, &s);
glShaderSource(fshaderobj, 1, (const GLchar **)&ftext, &s);
glCompileShader(vshaderobj);
glCompileShader(fshaderobj);
print_info_log(vshaderobj);
print_info_log(fshaderobj);
glAttachShader(sha->prog, vshaderobj);
glAttachShader(sha->prog, fshaderobj);
glDeleteShader(vshaderobj);
glDeleteShader(fshaderobj);
glLinkProgram(sha->prog);
print_info_log(sha->prog);
free(text);
char *beg = strstr(filename, "shader/") + 7;
char *end = strrchr(filename, '.');
sha->name = malloc(end - beg + 1);
memset(sha->name, 0, end-beg + 1);
strncpy(sha->name, beg, end-beg);
printf("-- loaded '%s' as '%s'\n", filename, sha->name);
}
GLuint get_shader(const char *name) {
Shader *s, *res = NULL;
for(s = global.shaders; s; s = s->next) {
if(strcmp(s->name, name) == 0)
res = s;
}
if(res == NULL)
errx(-1,"get_shader():\n!- cannot load shader '%s'", name);
return res->prog;
}
void delete_shaders() {
delete_all_elements((void **)&global.shaders);
}

30
src/shader.h Normal file
View file

@ -0,0 +1,30 @@
/*
* This software is licensed under the terms of the MIT-License
* See COPYING for further information.
* ---
* Copyright (C) 2011, Lukas Weber <laochailan@web.de>
*/
#ifndef SHADER_H
#define SHADER_H
#include <SDL/SDL_opengl.h>
#define DELIM "%% -- FRAG"
#define DELIM_SIZE 10
struct Shader;
typedef struct Shader {
struct Shader *next;
struct Shader *prev;
char *name;
GLuint prog;
} Shader;
void load_shader(const char *filename);
GLuint get_shader(const char *name);
void delete_shaders();
#endif

View file

@ -86,6 +86,7 @@ void stage_draw() {
glPushMatrix();
glTranslatef(VIEWPORT_X,VIEWPORT_Y,0);
apply_bg_shaders();
player_draw(&global.plr);
draw_projectiles();
@ -122,6 +123,40 @@ void stage_draw() {
glPopMatrix();
}
void apply_bg_shaders() {
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
if(global.boss) { // Boss background shader
GLuint shader = get_shader("boss_zoom");
glUseProgram(shader);
complex pos = global.boss->pos + 10*cexp(I*global.frames/5.0);
complex fpos = global.boss->pos;
glUniform2f(glGetUniformLocation(shader, "blur_orig"),
(creal(pos)+VIEWPORT_X)/global.rtt.nw, (VIEWPORT_H - cimag(pos) - VIEWPORT_Y/2)/global.rtt.nh);
glUniform2f(glGetUniformLocation(shader, "fix_orig"),
(creal(fpos)+VIEWPORT_X)/global.rtt.nw, (VIEWPORT_H - cimag(fpos) - VIEWPORT_Y/2)/global.rtt.nh);
glUniform1f(glGetUniformLocation(shader, "rad"), 0.3);
}
glPushMatrix();
glTranslatef(-global.rtt.nw+VIEWPORT_W,-global.rtt.nh+VIEWPORT_H,0);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, global.rtt.tex);
glBegin(GL_QUADS);
glTexCoord2f(0,1); glVertex3f(0, 0, 0);
glTexCoord2f(0,0); glVertex3f(0, global.rtt.nh, 0);
glTexCoord2f(1,0); glVertex3f(global.rtt.nw, global.rtt.nh, 0);
glTexCoord2f(1,1); glVertex3f(global.rtt.nw, 0, 0);
glEnd();
glDisable(GL_TEXTURE_2D);
glUseProgramObjectARB(0);
glPopMatrix();
}
void stage_logic() {
player_logic(&global.plr);

View file

@ -16,4 +16,5 @@ void stage_input();
void stage_end();
void apply_bg_shaders();
#endif

View file

@ -23,6 +23,8 @@ void simpleFairy(Fairy *f) {
}
void stage0_draw() {
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, global.rtt.fbo);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushMatrix();
glTranslatef(-(VIEWPORT_X+VIEWPORT_W/2.0), -(VIEWPORT_Y+VIEWPORT_H/2.0),0);
@ -90,6 +92,8 @@ void stage0_draw() {
glPopMatrix();
glDisable(GL_TEXTURE_2D);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
glViewport(0,0,SCREEN_W,SCREEN_H);
}
void cirno_intro(Boss *c, int time) {

View file

@ -11,10 +11,13 @@
#include <sys/types.h>
#include <sys/stat.h>
#include "audio.h"
#include "shader.h"
#include "list.h"
void recurse_dir(char *path) {
DIR *dir = opendir(path);
if(dir == NULL)
err(-1, "Couldn't open directory '%s'", path);
struct dirent *dp;
char buf[512];
@ -36,6 +39,8 @@ void recurse_dir(char *path) {
load_texture(buf);
} else if(strcmp(dp->d_name + strlen(dp->d_name)-4, ".wav") == 0) {
load_sound(buf);
} else if(strcmp(dp->d_name + strlen(dp->d_name)-4, ".sha") == 0) {
load_shader(buf);
}
}
}
@ -53,6 +58,11 @@ void load_resources() {
strcpy(path, FILE_PREFIX);
strncat(path, "sfx", sizeof(FILE_PREFIX)+4);
recurse_dir(path);
printf("- shader:\n");
strcpy(path, FILE_PREFIX);
strncat(path, "shader", sizeof(FILE_PREFIX)+4);
recurse_dir(path);
}
Texture *get_tex(char *name) {

View file

@ -28,6 +28,7 @@ typedef struct Texture {
Texture *get_tex(char *name);
void load_textures();
void load_resources();
void delete_textures();
Texture *load_texture(const char *filename);
@ -36,4 +37,5 @@ void free_texture(Texture *tex);
void draw_texture(int x, int y, char *name);
void draw_texture_p(int x, int y, Texture *tex);
#endif