Stage 3D background system/Stage 2 background

shaders!
This commit is contained in:
laochailan 2012-01-06 21:52:55 +01:00
parent a2a822eb86
commit 89a019f1fb
24 changed files with 560 additions and 122 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 455 KiB

BIN
gfx/stage1/leaves.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

BIN
gfx/stage1/road.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 958 KiB

20
shader/alpha_depth.sha Normal file
View file

@ -0,0 +1,20 @@
#version 110
void main(void) {
gl_Position = ftransform();
gl_FrontColor = gl_Color;
gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0;
}
%% -- FRAG
#version 110
uniform sampler2D tex;
void main(void) {
vec4 clr = texture2D(tex, vec2(gl_TexCoord[0].xy));
gl_FragColor = vec4(0.1,0.0,0.07,1.0);
gl_FragDepth = 0.5*gl_FragCoord.z/clr.a;
}

37
shader/bloom.sha Normal file
View file

@ -0,0 +1,37 @@
#version 110
void main(void) {
gl_Position = ftransform();
gl_FrontColor = gl_Color;
gl_TexCoord[0] = gl_MultiTexCoord0;
}
%% -- FRAG
#version 110
uniform sampler2D tex;
uniform float intensity;
float pi = 2.0 * asin(1.0);
void main(void) {
vec2 pos = vec2(gl_TexCoord[0]);
float a;
float i = 0.0;
vec4 sum = vec4(0.0), c;
for(a = 0.0; a <= 2.0*pi; a+=0.6) {
c = texture2D(tex, pos + vec2(cos(a),sin(a))*0.01);
if(c != vec4(0.0)) {
sum += c;
i++;
}
}
gl_FragColor = texture2D(tex, pos) + intensity*sum*sum/i;
// gl_FragColor = texture2D(tex, pos);
}

View file

@ -1,7 +1,7 @@
#version 110
void main(void) {
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
gl_Position = ftransform();
gl_FrontColor = gl_Color;
gl_TexCoord[0] = gl_MultiTexCoord0;
}

View file

@ -1,11 +1,9 @@
#version 110
#extension GL_EXT_draw_instanced : enable
varying vec4 TexCoord0;
void main(void) {
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
gl_Position = ftransform();
gl_FrontColor = gl_Color;
TexCoord0 = gl_TextureMatrix[0] * gl_MultiTexCoord0;

View file

@ -1,7 +1,7 @@
#version 110
void main(void) {
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
gl_Position = ftransform();
gl_FrontColor = gl_Color;
gl_TexCoord[0] = gl_MultiTexCoord0;
}

30
shader/zbuf_fog.sha Normal file
View file

@ -0,0 +1,30 @@
#version 110
void main(void) {
gl_Position = ftransform();
gl_FrontColor = gl_Color;
gl_TexCoord[0] = gl_MultiTexCoord0;
}
%% -- FRAG
#version 110
uniform sampler2D tex;
uniform sampler2D depth;
uniform float start;
uniform float end;
uniform vec4 fog_color;
void main(void) {
vec2 pos = vec2(gl_TexCoord[0]);
float z = pow(texture2D(depth, pos).x,6.0);
float f = clamp((end - z)/(end-start),0.0,1.0);
gl_FragColor = f*texture2D(tex, pos) + (1.0-f)*fog_color;
// gl_FragColor = vec4(z);
}

View file

@ -31,6 +31,7 @@ set(SRCs
dialog.c
fbo.c
vbo.c
stageutils.c
matrix.c
menu/menu.c
menu/mainmenu.c
@ -40,6 +41,7 @@ set(SRCs
menu/difficulty.c
menu/charselect.c
stages/stage0.c
stages/stage1.c
resource/resource.c
resource/texture.c
resource/animation.c

View file

@ -32,23 +32,29 @@ void init_fbo(FBO *fbo) {
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, fbo->nw, fbo->nh, 0, GL_BGR, GL_UNSIGNED_BYTE, NULL);
glGenFramebuffersEXT(1,&fbo->fbo);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo->fbo);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, fbo->tex, 0);
glGenFramebuffers(1,&fbo->fbo);
glBindFramebuffer(GL_FRAMEBUFFER, fbo->fbo);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fbo->tex, 0);
glEnable(GL_BLEND);
glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE);
glGenRenderbuffersEXT(1, &fbo->depth);
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, fbo->depth);
glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT24, fbo->nw, fbo->nh);
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, fbo->depth);
glGenTextures(1, &fbo->depth);
glBindTexture(GL_TEXTURE_2D, fbo->depth);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
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_DEPTH_COMPONENT16, fbo->nw, fbo->nh, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D,fbo->depth, 0);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
void draw_fbo_viewport(FBO *fbo) {
void draw_fbo_viewport(FBO *fbo) {
glPushMatrix();
glTranslatef(-VIEWPORT_X,VIEWPORT_H+VIEWPORT_Y-fbo->nh,0);

View file

@ -61,6 +61,7 @@ enum {
FPS = 60,
GAMEOVER_DEFEAT = 1,
GAMEOVER_WIN,
GAMEOVER_ABORT
};

View file

@ -40,7 +40,7 @@ void draw_ingame_menu(MenuData *menu) {
rad = IMENU_BLUR * (1.0-menu->fade);
if(!tconfig.intval[NO_SHADER]) {
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
GLenum shader = get_shader("ingame_menu");
glUseProgram(shader);

View file

@ -14,6 +14,7 @@
#include "global.h"
#include "stages/stage0.h"
#include "stages/stage1.h"
void quit_menu(void *arg) {
MenuData *m = arg;
@ -35,10 +36,12 @@ troll:
goto troll;
stage0_loop();
stage1_loop();
global.game_over = 0;
}
void enter_options(void *arg)
{
void enter_options(void *arg) {
MenuData m;
create_options_menu(&m);
options_menu_loop(&m);

View file

@ -91,7 +91,7 @@ void draw_animation_p(float x, float y, int row, Animation *ani) {
glPushMatrix();
glTranslatef(x,y,0);
glScalef(ani->w/2,ani->h/2, 1);
glScalef(ani->w,ani->h, 1);
glMatrixMode(GL_TEXTURE);
glPushMatrix();
@ -99,12 +99,7 @@ void draw_animation_p(float x, float y, int row, Animation *ani) {
glTranslatef(global.frames/ani->speed % ani->cols, row, 0);
glMatrixMode(GL_MODELVIEW);
glBegin(GL_QUADS);
glTexCoord2f(0,0); glVertex3f(-1, -1, 0);
glTexCoord2f(0,1); glVertex3f(-1, 1, 0);
glTexCoord2f(1,1); glVertex3f(1, 1, 0);
glTexCoord2f(1,0); glVertex3f(1, -1, 0);
glEnd();
draw_quad();
glMatrixMode(GL_TEXTURE);
glPopMatrix();

View file

@ -81,7 +81,8 @@ void load_resources() {
recurse_dir(path);
printf("init_fbo():\n");
init_fbo(&resources.fbg);
init_fbo(&resources.fbg[0]);
init_fbo(&resources.fbg[1]);
init_fbo(&resources.fsec);
printf("-- finished\n");

View file

@ -38,7 +38,7 @@ struct Resources {
ALuint sndsrc[SNDSRC_COUNT];
FBO fbg;
FBO fbg[2];
FBO fsec;
};

View file

@ -122,7 +122,20 @@ void draw_hud() {
draw_texture(VIEWPORT_X+creal(global.boss->pos), 590, "boss_indicator");
}
void stage_draw() {
void stage_draw(StageRule bgdraw, ShaderRule *shaderrules, int time) {
if(!tconfig.intval[NO_SHADER])
glBindFramebuffer(GL_FRAMEBUFFER, resources.fbg[0].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);
glEnable(GL_DEPTH_TEST);
if(!global.menu)
bgdraw();
glPopMatrix();
glBindFramebuffer(GL_FRAMEBUFFER, 0);
set_ortho();
glPushMatrix();
@ -130,7 +143,7 @@ void stage_draw() {
if(!global.menu) {
if(!tconfig.intval[NO_SHADER])
apply_bg_shaders();
apply_bg_shaders(shaderrules);
if(global.boss) {
glPushMatrix();
@ -183,18 +196,25 @@ void stage_draw() {
glPopMatrix();
draw_hud();
if(global.frames < FADE_TIME)
fade_out(1.0 - global.frames/(float)FADE_TIME);
if(global.menu && global.menu->selected == 1) {
fade_out(global.menu->fade);
if(global.frames < 4*FADE_TIME)
fade_out(1.0 - global.frames/(float)(4*FADE_TIME));
if(global.timer > time - 4*FADE_TIME) {
fade_out((global.timer - time + 4*FADE_TIME)/(float)(4*FADE_TIME));
}
draw_hud();
if(global.menu && global.menu->selected == 1)
fade_out(global.menu->fade);
}
void apply_bg_shaders() {
void apply_bg_shaders(ShaderRule *shaderrules) {
int fbonum = 0;
int i;
if(global.boss && global.boss->current && global.boss->current->draw_rule) {
glBindFramebuffer(GL_FRAMEBUFFER, resources.fbg.fbo);
glBindFramebuffer(GL_FRAMEBUFFER, resources.fbg[0].fbo);
global.boss->current->draw_rule(global.boss, global.frames - global.boss->current->starttime);
glPushMatrix();
@ -211,6 +231,13 @@ void apply_bg_shaders() {
glPopMatrix();
glBindFramebuffer(GL_FRAMEBUFFER, 0);
} else {
for(i = 0; shaderrules != NULL && shaderrules[i] != NULL; i++) {
glBindFramebuffer(GL_FRAMEBUFFER, resources.fbg[!fbonum].fbo);
shaderrules[i](fbonum);
fbonum = !fbonum;
}
}
glBindFramebuffer(GL_FRAMEBUFFER, resources.fsec.fbo);
@ -223,15 +250,15 @@ void apply_bg_shaders() {
complex pos = fpos + 15*cexp(I*global.frames/4.5);
glUniform2f(glGetUniformLocation(shader, "blur_orig"),
creal(pos)/resources.fbg.nw, cimag(pos)/resources.fbg.nh);
creal(pos)/resources.fbg[fbonum].nw, cimag(pos)/resources.fbg[fbonum].nh);
glUniform2f(glGetUniformLocation(shader, "fix_orig"),
creal(fpos)/resources.fbg.nw, cimag(fpos)/resources.fbg.nh);
creal(fpos)/resources.fbg[fbonum].nw, cimag(fpos)/resources.fbg[fbonum].nh);
glUniform1f(glGetUniformLocation(shader, "blur_rad"), 0.2+0.025*sin(global.frames/15.0));
glUniform1f(glGetUniformLocation(shader, "rad"), 0.24);
glUniform1f(glGetUniformLocation(shader, "ratio"), (float)resources.fbg.nh/resources.fbg.nw);
glUniform1f(glGetUniformLocation(shader, "ratio"), (float)resources.fbg[fbonum].nh/resources.fbg[fbonum].nw);
}
draw_fbo_viewport(&resources.fbg);
draw_fbo_viewport(&resources.fbg[fbonum]);
glUseProgram(0);
@ -252,7 +279,7 @@ void apply_bg_shaders() {
}
}
void stage_logic() {
void stage_logic(int time) {
if(global.menu) {
ingame_menu_logic(&global.menu);
return;
@ -279,6 +306,9 @@ void stage_logic() {
calc_fps(&global.fps);
if(global.timer >= time)
global.game_over = GAMEOVER_WIN;
}
void stage_end() {
@ -304,7 +334,13 @@ void stage_end() {
}
}
void stage_loop(StageRule start, StageRule end, StageRule draw, StageRule event) {
void stage_loop(StageRule start, StageRule end, StageRule draw, StageRule event, ShaderRule *shaderrules, int endtime) {
if(global.game_over == GAMEOVER_WIN) {
global.game_over = 0;
} else if(global.game_over) {
return;
}
stage_start();
start();
@ -312,13 +348,9 @@ void stage_loop(StageRule start, StageRule end, StageRule draw, StageRule event)
if(!global.boss && !global.dialog)
event();
stage_input();
stage_logic();
if(!tconfig.intval[NO_SHADER])
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, resources.fbg.fbo);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
draw();
stage_draw();
stage_logic(endtime);
stage_draw(draw, shaderrules, endtime);
SDL_GL_SwapBuffers();
frame_rate(&global.lasttime);

View file

@ -28,17 +28,10 @@
#define GO_TO(obj, p, f) (obj)->pos += (f)*((p) - (obj)->pos);
typedef void (*StageRule)(void);
typedef void (*ShaderRule)(int);
void stage_loop(StageRule start, StageRule end, StageRule draw, StageRule event);
void stage_loop(StageRule start, StageRule end, StageRule draw, StageRule event, ShaderRule *shaderrules, int endtime);
void stage_start();
void stage_logic();
void stage_draw();
void stage_input();
void stage_end();
void apply_bg_shaders();
void apply_bg_shaders(ShaderRule *shaderrules);
void draw_stage_title(int t, int dur, char *stage, char *subtitle);
#endif

View file

@ -9,6 +9,9 @@
#include "stage.h"
#include "global.h"
#include "stageutils.h"
static Stage3D bgcontext;
Dialog *stage0_dialog() {
Dialog *d = create_dialog(global.plr.cha == Marisa ? "dialog/marisa" : "dialog/youmu", "masterspark");
@ -23,59 +26,50 @@ Dialog *stage0_dialog() {
return d;
}
void stage0_draw() {
void stage0_bg_draw(Vector pos) {
glPushMatrix();
glTranslatef(-(VIEWPORT_X+VIEWPORT_W/2.0), -(VIEWPORT_Y+VIEWPORT_H/2.0),0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glTranslatef(-(VIEWPORT_X+VIEWPORT_W/2.0)/SCREEN_W, -(VIEWPORT_Y+VIEWPORT_H/2.0)/SCREEN_H,0);
gluPerspective(45, 5.0/6.0, 500, 5000);
glTranslatef(0,0,-500);
glMatrixMode(GL_MODELVIEW);
glEnable(GL_DEPTH_TEST);
glBegin(GL_QUADS);
glVertex3f(-1000,0,-3000);
glVertex3f(1500,-0,-3000);
glVertex3f(1500,2500,-3000);
glVertex3f(-1000,2500,-3000);
glEnd();
glPushMatrix();
glRotatef(60, -1, 0, 0);
Texture *water = get_tex("stage0/water");
glTranslatef(pos[0]+330,pos[1],pos[0]);
glRotatef(180,1,0,0);
glScalef(1200,3000,1);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, water->gltex);
glBindTexture(GL_TEXTURE_2D, get_tex("stage0/water")->gltex);
glMatrixMode(GL_TEXTURE);
glLoadIdentity();
glTranslatef(0,global.frames/(float)water->h, 0);
glScalef(2,2,2);
glMatrixMode(GL_MODELVIEW);
glBegin(GL_QUADS);
glTexCoord2i(0,0);
glVertex3f(-500,0,0);
glTexCoord2i(1,0);
glVertex3f(1000,0,0);
glTexCoord2i(1,1);
glVertex3f(1000,3000,0);
glTexCoord2i(0,1);
glVertex3f(-500,3000,0);
glEnd();
glPopMatrix();
glMatrixMode(GL_TEXTURE);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
draw_quad();
glDisable(GL_TEXTURE_2D);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
glPopMatrix();
}
Vector **stage0_bg_pos(Vector p, float maxrange) {
Vector q = {0,0,0};
Vector r = {0,3000,0};
return linear3dpos(p, maxrange, q, r);
}
void stage0_fog(int fbonum) {
GLuint shader = get_shader("zbuf_fog");
glUseProgram(shader);
glUniform1i(glGetUniformLocation(shader, "depth"),2);
glUniform4f(glGetUniformLocation(shader, "fog_color"),0.1, 0.1, 0.1, 1.0);
glUniform1f(glGetUniformLocation(shader, "start"),0.0);
glUniform1f(glGetUniformLocation(shader, "end"),0.4);
glActiveTexture(GL_TEXTURE0 + 2);
glBindTexture(GL_TEXTURE_2D, resources.fbg[fbonum].depth);
glActiveTexture(GL_TEXTURE0);
draw_fbo_viewport(&resources.fbg[fbonum]);
glUseProgram(0);
}
void stage0_draw() {
set_perspective(&bgcontext, 500, 5000);
draw_stage3d(&bgcontext, 7000);
}
@ -568,27 +562,22 @@ void stage0_events() {
AT(5000)
global.boss = create_cirno();
AT(5200) {
global.game_over = 1;
printf("You won! for now.\n");
}
}
void stage0_start() {
stage_start();
glEnable(GL_FOG);
GLfloat clr[] = { 0.1, 0.1, 0.1, 0 };
glFogfv(GL_FOG_COLOR, clr);
glFogf(GL_FOG_MODE, GL_LINEAR);
glFogf(GL_FOG_START, 0);
glFogf(GL_FOG_END, 1500);
init_stage3d(&bgcontext);
add_model(&bgcontext, stage0_bg_draw, stage0_bg_pos);
bgcontext.crot[0] = -60;
bgcontext.cx[2] = -700;
bgcontext.cv[1] = -7;
}
void stage0_end() {
glDisable(GL_FOG);
free_stage3d(&bgcontext);
}
void stage0_loop() {
stage_loop(stage0_start, stage0_end, stage0_draw, stage0_events);
void stage0_loop() {
ShaderRule list[] = { stage0_fog, NULL };
stage_loop(stage0_start, stage0_end, stage0_draw, stage0_events, list, 5200);
}

166
src/stages/stage1.c Normal file
View file

@ -0,0 +1,166 @@
/*
* 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 "stage1.h"
#include "global.h"
#include "stage.h"
#include "stageutils.h"
static Stage3D bgcontext;
void stage1_bg_leaves_draw(Vector pos) {
glEnable(GL_TEXTURE_2D);
if(!tconfig.intval[NO_SHADER])
glUseProgram(get_shader("alpha_depth"));
glMatrixMode(GL_TEXTURE);
glLoadIdentity();
glScalef(-1,1,1);
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
Texture *leaves = get_tex("stage1/leaves");
glBindTexture(GL_TEXTURE_2D, leaves->gltex);
glTranslatef(pos[0]-100,pos[1],pos[2]+500);
glRotatef(-160,0,1,0);
glTranslatef(-150,0,0);
glScalef(1000,3000,1);
draw_quad();
glPopMatrix();
if(!tconfig.intval[NO_SHADER])
glUseProgram(0);
glDisable(GL_TEXTURE_2D);
glMatrixMode(GL_TEXTURE);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
}
void stage1_bg_ground_draw(Vector pos) {
glEnable(GL_TEXTURE_2D);
glPushMatrix();
glTranslatef(pos[0]+400,pos[1],pos[2]);
glScalef(1500,3000,1000);
Texture *road = get_tex("stage1/road");
glBindTexture(GL_TEXTURE_2D, road->gltex);
glMatrixMode(GL_TEXTURE);
glLoadIdentity();
glScalef(1,2,1);
glMatrixMode(GL_MODELVIEW);
glRotatef(-180,1,0,0);
draw_quad();
glMatrixMode(GL_TEXTURE);
glLoadIdentity();
glTranslatef(global.frames/100.0,1*sin(global.frames/100.0),0);
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
glPushMatrix();
Texture *border = get_tex("stage1/border");
glBindTexture(GL_TEXTURE_2D, border->gltex);
glTranslatef(pos[0]+780,pos[1],pos[2]+600);
glRotatef(90,0,1,0);
glScalef(1200,3000,1);
draw_quad();
glPopMatrix();
glDisable(GL_TEXTURE_2D);
glMatrixMode(GL_TEXTURE);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
}
Vector **stage1_bg_pos(Vector pos, float maxrange) {
Vector p = {0, 0, 0};
Vector r = {0, 3000, 0};
return linear3dpos(pos, maxrange, p, r);
}
void stage1_fog(int fbonum) {
GLuint shader = get_shader("zbuf_fog");
glUseProgram(shader);
glUniform1i(glGetUniformLocation(shader, "depth"),2);
glUniform4f(glGetUniformLocation(shader, "fog_color"),0.05,0.0,0.03,1.0);
glUniform1f(glGetUniformLocation(shader, "start"),0.2);
glUniform1f(glGetUniformLocation(shader, "end"),0.8);
glActiveTexture(GL_TEXTURE0 + 2);
glBindTexture(GL_TEXTURE_2D, resources.fbg[fbonum].depth);
glActiveTexture(GL_TEXTURE0);
draw_fbo_viewport(&resources.fbg[fbonum]);
glUseProgram(0);
}
void stage1_bloom(int fbonum) {
GLuint shader = get_shader("bloom");
glUseProgram(shader);
glUniform1f(glGetUniformLocation(shader, "intensity"),0.05);
draw_fbo_viewport(&resources.fbg[fbonum]);
glUseProgram(0);
}
void stage1_start() {
init_stage3d(&bgcontext);
bgcontext.cx[2] = -1000;
bgcontext.cx[0] = 850;
bgcontext.crot[0] = -50;
bgcontext.crot[2] = 90;
bgcontext.cv[0] = -9;
add_model(&bgcontext, stage1_bg_ground_draw, stage1_bg_pos);
add_model(&bgcontext, stage1_bg_leaves_draw, stage1_bg_pos);
}
void stage1_end() {
free_stage3d(&bgcontext);
}
void stage1_draw() {
TIMER(&global.frames);
set_perspective(&bgcontext, 500, 5000);
FROM_TO(0,180,1) {
bgcontext.cv[0] += 0.05;
bgcontext.cv[1] -= 0.1;
bgcontext.crot[2] -= 0.5;
}
// bgcontext.cv[1] -= 0.5;
draw_stage3d(&bgcontext, 7000);
}
void stage1_events() {
}
void stage1_loop() {
ShaderRule shaderrules[] = { stage1_fog, stage1_bloom, NULL };
stage_loop(stage1_start, stage1_end, stage1_draw, stage1_events, shaderrules, 5000);
}

13
src/stages/stage1.h Normal file
View file

@ -0,0 +1,13 @@
/*
* 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 STAGE1_H
#define STAGE1_H
void stage1_loop();
#endif

105
src/stageutils.c Normal file
View file

@ -0,0 +1,105 @@
/*
* 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 "stageutils.h"
#include <string.h>
#include <stdlib.h>
#include <GL/glew.h>
#include "global.h"
void init_stage3d(Stage3D *s) {
memset(s, 0, sizeof(Stage3D));
s->projangle = 45;
}
void add_model(Stage3D *s, ModelDrawRule draw, ModelPositionRule pos) {
s->models = realloc(s->models, (++s->msize)*sizeof(Model));
s->models[s->msize - 1].draw = draw;
s->models[s->msize - 1].pos = pos;
}
void set_perspective(Stage3D *s, float near, float far) {
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glTranslatef(-(VIEWPORT_X+VIEWPORT_W/2.0)/SCREEN_W, -(VIEWPORT_Y+VIEWPORT_H/2.0)/SCREEN_H,0);
gluPerspective(s->projangle, 1, near, far);
glRotatef(s->crot[0], 1, 0, 0);
glRotatef(s->crot[1], 0, 1, 0);
glRotatef(s->crot[2], 0, 0, 1);
glTranslatef(s->cx[0],s->cx[1],s->cx[2]);
glMatrixMode(GL_MODELVIEW);
}
void draw_stage3d(Stage3D *s, float maxrange) {
int i,j;
for(i = 0; i < 3;i++)
s->cx[i] += s->cv[i];
for(i = 0; i < s->msize; i++) {
Vector **list;
list = s->models[i].pos(s->cx, maxrange);
for(j = 0; list[j] != NULL; j++) {
s->models[i].draw(*list[j]);
free(list[j]);
}
free(list);
}
}
void free_stage3d(Stage3D *s) {
if(s->models != NULL)
free(s->models);
}
Vector **linear3dpos(Vector q, float maxrange, Vector p, Vector r) {
int i;
float n = 0, z = 0;
for(i = 0; i < 3; i++) {
n += q[i]*r[i] - p[i]*r[i];
z += r[i]*r[i];
}
float t = n/z;
Vector **list = NULL;
int size = 0;
int mod = 1;
int num = t;
while(1) {
Vector dif;
for(i = 0; i < 3; i++)
dif[i] = q[i] - p[i] - r[i]*num;
if(length(dif) < maxrange) {
list = realloc(list, (++size)*sizeof(Vector*));
list[size-1] = malloc(sizeof(Vector));
for(i = 0; i < 3; i++)
(*list[size-1])[i] = - p[i] - r[i]*num;
} else if(mod == 1) {
mod = -1;
num = t;
} else {
break;
}
num += mod;
}
list = realloc(list, (++size)*sizeof(Vector));
list[size-1] = NULL;
return list;
}

47
src/stageutils.h Normal file
View file

@ -0,0 +1,47 @@
/*
* 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 STAGEUITLS_H
#define STAGEUTILS_H
#include "matrix.h"
typedef struct Model Model;
typedef void (*ModelDrawRule)(Vector pos);
typedef Vector **(*ModelPositionRule)(Vector q, float maxrange); // returns NULL-terminated array
struct Model {
ModelDrawRule draw;
ModelPositionRule pos;
};
typedef struct Stage3D Stage3D;
struct Stage3D {
Model *models;
int msize;
// Camera
Vector cx; // x
Vector cv; // x'
Vector crot;
float projangle;
};
void init_stage3d(Stage3D *s);
void add_model(Stage3D *s, ModelDrawRule draw, ModelPositionRule pos);
void set_perspective(Stage3D *s, float near, float far);
void draw_stage3d(Stage3D *s, float maxrange);
void free_stage3d(Stage3D *s);
Vector **linear3dpos(Vector q, float maxrange, Vector p, Vector r);
#endif