From 86f7480826870cb4fc0dff562a000e8984fb79d7 Mon Sep 17 00:00:00 2001 From: Allanis Date: Fri, 19 Jul 2013 19:05:01 +0100 Subject: [PATCH] [Add] Animated nebulae ftw!!! --- src/nebulae.c | 109 +++++++++++++++++++++++++++++++++++++++----------- src/perlin.c | 2 +- 2 files changed, 87 insertions(+), 24 deletions(-) diff --git a/src/nebulae.c b/src/nebulae.c index 0985f88..643627b 100644 --- a/src/nebulae.c +++ b/src/nebulae.c @@ -7,8 +7,11 @@ #include "log.h" #include "opengl.h" #include "lfile.h" +#include "rng.h" #include "perlin.h" +#define NEBU_DT_MAX 1. + #define NEBULAE_Z 16 /* Z plane. */ #define NEBULAE_PATH "gen/nebu_%02d.png" @@ -18,6 +21,10 @@ static int nebu_w = 0; static int nebu_h = 0; static int nebu_pw, nebu_ph; +/* Information on rendering. */ +static int cur_nebu[2] = { 0, 1 }; +static unsigned int last_render = 0; + static int nebu_checkCompat(const char* file); static void saveNebulae(float* map, const uint32_t w, const uint32_t h, const char* file); @@ -60,6 +67,7 @@ void nebu_init(void) { WARN("Nebulae raw size doesn't match expected! (%dx%d instead of %dx%d)", nebu_sur->w, nebu_sur->h, nebu_pw, nebu_ph); + /* Prepare to load into OpenGL. */ nebu_sur = gl_prepareSurface(nebu_sur); if((nebu_sur->w != nebu_pw) || (nebu_sur->h != nebu_ph)) WARN("Nebulae size doesn't match expected! (%dx%d instead of %dx%d)", @@ -70,6 +78,7 @@ void nebu_init(void) { glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + /* Store into opengl saving only alpha channel in video memory. */ SDL_LockSurface(nebu_sur); glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, nebu_sur->w, nebu_sur->h, 0, GL_RGBA, GL_UNSIGNED_BYTE, nebu_sur->pixels); @@ -89,40 +98,94 @@ void nebu_exit(void) { /* Render the nebulae. */ void nebu_render(void) { - int n; - double x, y, w, h, tx, ty, tw, th; + unsigned int t; + double dt; + double tw, th; + GLfloat col[4]; + int tmp; - n = 0; + /* Calculate frame to draw. */ + t = SDL_GetTicks(); + dt = (t - last_render) / 1000.; + if(dt > NEBU_DT_MAX) { /* Time to change. */ + tmp = cur_nebu[0]; + cur_nebu[0] += cur_nebu[0] - cur_nebu[1]; + cur_nebu[1] = tmp; + if(cur_nebu[0]+1 > NEBULAE_Z) + cur_nebu[0] = NEBULAE_Z - 2; + else if(cur_nebu[0] < 0) + cur_nebu[0] = 1; - x = -SCREEN_W/2.; - y = -SCREEN_H/2.; + last_render = t; + dt = 0.; + } - w = SCREEN_W; - h = SCREEN_H; - - tx = 0.; - ty = 0.; + col[0] = cPurple.r; + col[1] = cPurple.g; + col[2] = cPurple.b; + col[3] = dt / NEBU_DT_MAX; tw = (double)nebu_w / (double)nebu_pw; th = (double)nebu_h / (double)nebu_ph; + /* Set up the targets. */ + /* Texture 0. */ + glActiveTexture(GL_TEXTURE0); glEnable(GL_TEXTURE_2D); - /*glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);*/ - glBindTexture(GL_TEXTURE_2D, nebu_textures[n]); - COLOUR(cPurple); + glBindTexture(GL_TEXTURE_2D, nebu_textures[cur_nebu[0]]); + + /* Texture 1. */ + glActiveTexture(GL_TEXTURE1); + glEnable(GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D, nebu_textures[cur_nebu[1]]); + + /* Prepare it. */ + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE); + glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_INTERPOLATE); + glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_INTERPOLATE); + /* Colour. */ + glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, col); + + /* Arguments. */ + glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_CONSTANT); + glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, GL_TEXTURE1); + glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR); + glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA); + /* Arg 1. */ + glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE1_RGB, GL_CONSTANT); + glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA, GL_PREVIOUS); + glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR); + glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA, GL_SRC_ALPHA); + /* Arg 2. */ + glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB, GL_CONSTANT); + glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_ALPHA, GL_CONSTANT); + glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB, GL_SRC_ALPHA); + glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB, GL_SRC_ALPHA); + + /* Now render. */ glBegin(GL_QUADS); - glTexCoord2d(tx, ty); - glVertex2d(x, y); + glMultiTexCoord2d(GL_TEXTURE0, 0., 0.); + glMultiTexCoord2d(GL_TEXTURE1, 0., 0.); + glVertex2d(-SCREEN_W/2., -SCREEN_H/2.); - glTexCoord2d(tx+tw, ty); - glVertex2d(x+w, y); - - glTexCoord2d(tx+tw, ty+th); - glVertex2d(x+w, y+h); - - glTexCoord2d(tx, ty+th); - glVertex2d(x, y+h); + glMultiTexCoord2d(GL_TEXTURE0, tw, 0.); + glMultiTexCoord2d(GL_TEXTURE1, tw, 0.); + glVertex2d(SCREEN_W/2., -SCREEN_H/2.); + + glMultiTexCoord2d(GL_TEXTURE0, tw, th); + glMultiTexCoord2d(GL_TEXTURE1, tw, th); + glVertex2d(SCREEN_W/2., SCREEN_H/2.); + + glMultiTexCoord2d(GL_TEXTURE0, 0., th); + glMultiTexCoord2d(GL_TEXTURE1, 0., th); + glVertex2d(-SCREEN_W/2., SCREEN_H/2.); glEnd(); + + /* Clean up. */ + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + glDisable(GL_TEXTURE_2D); + glActiveTexture(GL_TEXTURE0); + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); glDisable(GL_TEXTURE_2D); /* Did anything fail? */ diff --git a/src/perlin.c b/src/perlin.c index b37f389..58cfcf2 100644 --- a/src/perlin.c +++ b/src/perlin.c @@ -183,7 +183,7 @@ float* noise_genNebulaeMap(const int w, const int h, const int n, float rug) { lacunarity = NOISE_DEFAULT_LACUNARITY; zoom = rug * ((float)h/768.)*((float)w/1024.); - /* Create noiuse and data. */ + /* Create noise and data. */ noise = noise_new(hurst, lacunarity); nebulae = malloc(sizeof(float)*w*h*n);