Skip to content

Instantly share code, notes, and snippets.

@tai2
Created May 5, 2013 09:19
Show Gist options
  • Select an option

  • Save tai2/5520256 to your computer and use it in GitHub Desktop.

Select an option

Save tai2/5520256 to your computer and use it in GitHub Desktop.
Old school plasma effect. c.f. http://www.bidouille.org/prog/plasma
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>
#include <GLUT/glut.h>
#define KEY_ESC 27
#define WINDOW_POS_X 100
#define WINDOW_POS_Y 100
#define DEF_SCREEN_WIDTH 640
#define DEF_SCREEN_HEIGHT 360
#define SAMPLES_PER_PERIOD 0x1000
#define INT_COLOR(v) (255 * (0.5 * (v) + 0.5))
#define USE_TABLE
#ifdef USE_TABLE
#define CALC_IDX(x) (((int)(SAMPLES_PER_PERIOD * (x) / (2 * M_PI)) + 10 * SAMPLES_PER_PERIOD)&0xFFF)
#define SIN(x) sin_tbl[CALC_IDX(x)]
#define COS(x) cos_tbl[CALC_IDX(x)]
#else
#define SIN(x) sin(x)
#define COS(x) cos(x)
#endif
static int curr_width = 0;
static int curr_height = 0;
static GLubyte *screen_buf = NULL;
static int fullscreen = 0;
static clock_t c_old = 0;
static double sin_tbl[SAMPLES_PER_PERIOD];
static double cos_tbl[SAMPLES_PER_PERIOD];
static void
make_tables() {
int i;
for (i = 0; i < SAMPLES_PER_PERIOD; i++) {
double t = 2 * M_PI * ((double)i / SAMPLES_PER_PERIOD);
sin_tbl[i] = sin(t);
cos_tbl[i] = cos(t);
}
}
static void
keyboard(unsigned char c, int x, int y)
{
switch (c) {
case KEY_ESC:
exit(0);
break;
case 'f':
if (fullscreen) {
glutReshapeWindow(DEF_SCREEN_WIDTH, DEF_SCREEN_HEIGHT);
glutPositionWindow(WINDOW_POS_X, WINDOW_POS_Y);
fullscreen = 0;
} else {
glutFullScreen();
fullscreen = 1;
}
break;
}
}
void
idle()
{
glutPostRedisplay();
}
static void
reshape(int w, int h)
{
curr_width = w;
curr_height = h;
if (screen_buf) {
free(screen_buf);
}
screen_buf = (GLubyte *)malloc(curr_width * curr_height * 4);
if (!screen_buf) {
abort();
}
}
static void
draw_pixel(int x, int y, GLubyte r, GLubyte g, GLubyte b)
{
int base = 4 * ((curr_height - 1 - y) * curr_width + x);
screen_buf[base + 0] = r;
screen_buf[base + 1] = g;
screen_buf[base + 2] = b;
screen_buf[base + 3] = 255;
}
static void
display()
{
int x, y;
clock_t c_new = clock();
double t = (double)(c_new - c_old) / CLOCKS_PER_SEC;
t *= 2; // two times faster
glClear(GL_COLOR_BUFFER_BIT);
for (y = 0; y < curr_height; y++) {
double ny = ((double)y / curr_height) - 0.5;
double cy = ny + 0.5 * COS(t / 3);
for (x = 0; x < curr_width; x++) {
double nx = ((double)x / curr_width) - 0.5;
double cx = nx + 0.5 * SIN(t / 5);
double a1 = SIN(10 * nx + t);
double a2 = SIN(10 * (nx * SIN(t / 2) + ny * COS(t / 3)) + t);
double a3 = SIN(sqrt(100 * (cx * cx + cy * cy) + 1) + t);
double a = a1 + a2 + a3;
GLubyte r = INT_COLOR(SIN(a * M_PI));
GLubyte g = INT_COLOR(COS(a * M_PI));
GLubyte b = 0;
draw_pixel(x, y, r, g, b);
}
}
glWindowPos2i(0, 0);
glDrawPixels(curr_width, curr_height, GL_RGBA, GL_UNSIGNED_BYTE, screen_buf);
glutSwapBuffers();
}
int
main(int argc, char** argv)
{
srand(0);
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH );
glutInitWindowSize(DEF_SCREEN_WIDTH, DEF_SCREEN_HEIGHT);
glutInitWindowPosition(WINDOW_POS_X, WINDOW_POS_Y);
glutCreateWindow(argv[0]);
glutKeyboardFunc(keyboard);
glutIdleFunc(idle);
glutReshapeFunc(reshape);
glutDisplayFunc(display);
glClearColor(0.0, 0.0, 0.0, 0.0);
glShadeModel(GL_FLAT);
make_tables();
c_old = clock();
glutMainLoop();
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment