ScreenSaver/src/effects/morphfire.cpp

174 lines
4.8 KiB
C++

#include "effects.h"
#include <num/num.h>
#include "../utilities/fast_trig.h"
#include "../utilities/3Dtransform.h"
#include <cstring>
/********************************\
* MOPRHING EFFECT - MODULE 2 *
* Specific data and structures *
\********************************/
#define NB_POINTS 1024
#define SCALE 80
extern Vertex3D Sphere[NB_POINTS];
extern Vertex3D Torus[NB_POINTS];
extern Vertex3D Cylinder[NB_POINTS];
extern Vertex3D Morph[NB_POINTS];
extern libnum::num32 scale;
extern libnum::num32 eye;
extern libnum::num32 eyescale;
extern int centerx, centery;
static float anglef = 0.0;
static int angle = 0;
static double frame_counter = 0;
void morphfire_init( bopti_image_t *screen )
{
eye = libnum::num32( 250 );
scale = libnum::num32( SCALE );
eyescale = eye*scale;
centerx = (DWIDTH / 2);
centery = (MAXHEIGHT / 2);
// Create Sphere
for (int i = 0; i < NB_POINTS; i++)
{
int theta = rand() % 360;
int phi = rand() % 360 ;
Sphere[i].x = FastCosInt(phi) * FastSinInt(theta);
Sphere[i].y = FastSinInt(phi) * FastSinInt(theta);
Sphere[i].z = FastCosInt(theta);
}
// Create torus
for (int i = 0; i < NB_POINTS; i++)
{
int theta = rand() % 360;
int phi = rand() % 360 ;
Torus[i].x = (libnum::num32(0.8) + libnum::num32(0.4) * FastCosInt(theta)) * FastCosInt(phi);
Torus[i].y = (libnum::num32(0.8) + libnum::num32(0.4) * FastCosInt(theta)) * FastSinInt(phi);
Torus[i].z = libnum::num32(0.4) * FastSinInt(theta);
}
// Create cylinder
for (int i = 0; i < NB_POINTS; i++)
{
int theta = rand() % 360;
int height = rand() % 800;
Cylinder[i].x = libnum::num32(0.75) * FastCosInt(theta);
Cylinder[i].y = libnum::num32(0.75) * FastSinInt(theta);
Cylinder[i].z = libnum::num32( ((float) height - 400.0f) / 500.0f );
}
for(int u = 0; u<64; u++)
{
screen->palette[u] = C_RGB( 0, 0, 0 );
screen->palette[u+64] = C_RGB( 0, 0, u/2 );
screen->palette[u+128] = C_RGB( 0, u/2, 31 );
screen->palette[u+192] = C_RGB( u/2, 31, 31 );
}
image_fill( screen, -128 );
}
void morphfire_update( bopti_image_t *screen, [[Maybe_unused]] float dt )
{
anglef += dt / 10000.0;
angle = (int) anglef;
frame_counter += dt / 10000.0;
int frame = (int)frame_counter % 1536;
// Transform the torus into a sphere
if (frame >= 0 && frame < 256) {
int key = frame;
for (int i = 0; i < NB_POINTS; i++) {
Morph[i].x = (libnum::num32(key) * Sphere[i].x + libnum::num32(256 - key) * Torus[i].x) / libnum::num32(256);
Morph[i].y = (libnum::num32(key) * Sphere[i].y + libnum::num32(256 - key) * Torus[i].y) / libnum::num32(256);
Morph[i].z = (libnum::num32(key) * Sphere[i].z + libnum::num32(256 - key) * Torus[i].z) / libnum::num32(256);
}
}
// Transform the sphere into a torus
if (frame >= 512 && frame <768 ) {
int key = frame - 512;
for (int i = 0; i < NB_POINTS; i++) {
Morph[i].x = (libnum::num32(key) * Cylinder[i].x + libnum::num32(256 - key) * Sphere[i].x) / libnum::num32(256);
Morph[i].y = (libnum::num32(key) * Cylinder[i].y + libnum::num32(256 - key) * Sphere[i].y) / libnum::num32(256);
Morph[i].z = (libnum::num32(key) * Cylinder[i].z + libnum::num32(256 - key) * Sphere[i].z) / libnum::num32(256);
}
}
// Transform the sphere into a torus
if (frame >= 1024 && frame <1280 ) {
int key = frame - 1024;
for (int i = 0; i < NB_POINTS; i++) {
Morph[i].x = (libnum::num32(key) * Torus[i].x + libnum::num32(256 - key) * Cylinder[i].x) / libnum::num32(256);
Morph[i].y = (libnum::num32(key) * Torus[i].y + libnum::num32(256 - key) * Cylinder[i].y) / libnum::num32(256);
Morph[i].z = (libnum::num32(key) * Torus[i].z + libnum::num32(256 - key) * Cylinder[i].z) / libnum::num32(256);
}
}
// Rotate the vertex in world coordinates and then project them on screen
for (int i = 0; i < NB_POINTS; i++)
{
RotateVertex(&Morph[i], 0, angle, angle);
ProjectVertex(&Morph[i]);
}
}
void pixel( bopti_image_t *screen, uint16_t sx, uint16_t sy, int8_t color )
{
if (sx<0 || sx>DWIDTH || sy<0 || sy> MAXHEIGHT ) return;
int8_t *image = (int8_t *)screen->data;
image[ sx + sy * screen->stride ] = color;
}
void morphfire_render( bopti_image_t *screen )
{
//image_fill( screen, -128 );
int8_t *image = (int8_t *)screen->data;
for (int i = 0; i < NB_POINTS; i++)
{
pixel( screen, Morph[i].sx-1, Morph[i].sy, 127 );
pixel( screen, Morph[i].sx, Morph[i].sy, 127 );
pixel( screen, Morph[i].sx+1, Morph[i].sy, 127 );
pixel( screen, Morph[i].sx, Morph[i].sy-1, 127 );
pixel( screen, Morph[i].sx, Morph[i].sy+1, 127 );
}
Blur( screen );
Blur( screen );
dimage( 0, 0, screen );
}
void morphfire_deinit( bopti_image_t *screen )
{
}
char morphfire_TextToRender[100] = "Morphing & Blur > _\0";
char *morphfire_text( void )
{
return morphfire_TextToRender;
}