289 lines
7.4 KiB
C
289 lines
7.4 KiB
C
|
From curt@infoplane.com Fri Nov 13 06:10:29 1998
|
||
|
X-VM-v5-Data: ([nil nil nil nil nil nil nil nil nil]
|
||
|
["6615" "Fri" "13" "November" "1998" "06:10:23" "-0600" "curt@infoplane.com" "curt@infoplane.com" nil "271" "fuzzy-light-effect" "^From:" nil nil "11" nil nil nil nil nil]
|
||
|
nil)
|
||
|
Received: from dorthy.state.net (dorthy.state.net [209.234.62.254])
|
||
|
by meserv.me.umn.edu (8.9.1a/8.9.1) with ESMTP id GAA15847
|
||
|
for <curt@me.umn.edu>; Fri, 13 Nov 1998 06:10:28 -0600 (CST)
|
||
|
Received: from sledge.infoplane.com (curt@sledge.infoplane.com [204.120.151.21]) by dorthy.state.net (8.8.8/8.7.2) with ESMTP id GAA25998 for <curt@me.umn.edu>; Fri, 13 Nov 1998 06:10:08 -0600 (CST)
|
||
|
Received: (from curt@localhost)
|
||
|
by sledge.infoplane.com (8.8.8/8.8.8/Debian/GNU) id GAA24798
|
||
|
for curt@me.umn.edu; Fri, 13 Nov 1998 06:10:23 -0600
|
||
|
Message-Id: <199811131210.GAA24798@sledge.infoplane.com>
|
||
|
From: curt@infoplane.com
|
||
|
To: curt@me.umn.edu
|
||
|
Subject: fuzzy-light-effect
|
||
|
Date: Fri, 13 Nov 1998 06:10:23 -0600
|
||
|
|
||
|
/* stars - draws a twisting sphere of eerie lights
|
||
|
Copyright (C) 1998 James Bowman
|
||
|
|
||
|
stars is free software; you can redistribute it and/or modify
|
||
|
it under the terms of the GNU General Public License as published by
|
||
|
the Free Software Foundation; either version 2, or (at your option)
|
||
|
any later version.
|
||
|
|
||
|
gpasm is distributed in the hope that it will be useful,
|
||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
|
GNU General Public License for more details.
|
||
|
|
||
|
You should have received a copy of the GNU General Public License
|
||
|
along with gpasm; see the file COPYING. If not, write to
|
||
|
the Free Software Foundation, 59 Temple Place - Suite 330,
|
||
|
Boston, MA 02111-1307, USA. */
|
||
|
|
||
|
|
||
|
#include <stdio.h>
|
||
|
#include <stdlib.h>
|
||
|
#include <string.h>
|
||
|
#include <math.h> /* for cos(), sin(), and sqrt() */
|
||
|
#include <assert.h>
|
||
|
#ifdef WIN32
|
||
|
#include <time.h>
|
||
|
#else
|
||
|
#include <sys/time.h>
|
||
|
#endif
|
||
|
#include <GL/glut.h>
|
||
|
|
||
|
static int phi; /* Global clock */
|
||
|
static int texWidth = 64; /* 64x64 is plenty */
|
||
|
|
||
|
/************************************************************************/
|
||
|
|
||
|
/* Generate a pleasing, light-shaped texture. */
|
||
|
|
||
|
static void
|
||
|
setTexture(void)
|
||
|
{
|
||
|
int texSize;
|
||
|
void *textureBuf;
|
||
|
GLubyte *p;
|
||
|
int i,j;
|
||
|
double radius;
|
||
|
|
||
|
texSize = texWidth*texWidth;
|
||
|
|
||
|
textureBuf = malloc(texSize);
|
||
|
if (NULL == textureBuf) return;
|
||
|
|
||
|
p = (GLubyte *)textureBuf;
|
||
|
|
||
|
radius = (double)(texWidth / 2);
|
||
|
|
||
|
for (i=0; i < texWidth; i++) {
|
||
|
for (j=0; j < texWidth; j++) {
|
||
|
double x, y, d;
|
||
|
|
||
|
x = fabs((double)(i - (texWidth / 2)));
|
||
|
y = fabs((double)(j - (texWidth / 2)));
|
||
|
|
||
|
d = sqrt((x * x) + (y * y));
|
||
|
if (d < radius) {
|
||
|
double t = 1.0 - (d / radius); /* t is 1.0 at center,
|
||
|
0.0 at edge */
|
||
|
|
||
|
/* inverse square looks nice */
|
||
|
*p = (int)((double)0xff * (t * t));
|
||
|
} else
|
||
|
*p = 0x00;
|
||
|
p++;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
gluBuild2DMipmaps(GL_TEXTURE_2D, 1, texWidth, texWidth,
|
||
|
GL_LUMINANCE,
|
||
|
GL_UNSIGNED_BYTE, textureBuf);
|
||
|
free(textureBuf);
|
||
|
}
|
||
|
|
||
|
/************************************************************************/
|
||
|
|
||
|
static int W, H;
|
||
|
|
||
|
#define NUM_STARS 100
|
||
|
|
||
|
#define frand() ((float)(rand() & 0xfff) / (float)0x1000) /* 0.0 - 1.0 */
|
||
|
#define frand2() (1.0f - (2.0f * frand())) /* -1 - +1 */
|
||
|
|
||
|
/* Normalise the input vector */
|
||
|
static void vecNormalise(float *vv)
|
||
|
{
|
||
|
double mag;
|
||
|
|
||
|
mag = sqrt((vv[0] * vv[0]) + (vv[1] * vv[1]) + (vv[2] * vv[2]));
|
||
|
vv[0] /= mag;
|
||
|
vv[1] /= mag;
|
||
|
vv[2] /= mag;
|
||
|
}
|
||
|
|
||
|
void
|
||
|
redraw_viewing(void)
|
||
|
{
|
||
|
static int cold = 1;
|
||
|
static float stars[NUM_STARS * 3];
|
||
|
GLfloat fb_buffer[NUM_STARS * 4];
|
||
|
int i;
|
||
|
|
||
|
if (cold) {
|
||
|
/* Position all the stars more-or-less randomly on the surface
|
||
|
* of a unit sphere. */
|
||
|
for (i = 0; i < NUM_STARS; i++) {
|
||
|
stars[3 * i + 0] = frand2();
|
||
|
stars[3 * i + 1] = frand2();
|
||
|
stars[3 * i + 2] = frand2();
|
||
|
vecNormalise(&stars[3 * i]);
|
||
|
}
|
||
|
cold = 0;
|
||
|
}
|
||
|
|
||
|
glClear(GL_COLOR_BUFFER_BIT);
|
||
|
|
||
|
/* First use feedback to determine the screen positions of the
|
||
|
stars. */
|
||
|
glFeedbackBuffer(NUM_STARS * 4, GL_3D, fb_buffer);
|
||
|
glRenderMode(GL_FEEDBACK);
|
||
|
|
||
|
glMatrixMode(GL_MODELVIEW);
|
||
|
glPushMatrix();
|
||
|
glRotatef(phi % 360, 0.0f, 1.0f, 0.0f); /* Constant spin */
|
||
|
glRotatef(sin((double)phi / 300.0) * 150.0, /* Periodic twist */
|
||
|
0.1f, 0.6f, -0.5f);
|
||
|
glBegin(GL_POINTS);
|
||
|
for (i = 0; i < NUM_STARS; i++)
|
||
|
glVertex3fv(&stars[3 * i]);
|
||
|
glEnd();
|
||
|
glPopMatrix();
|
||
|
glRenderMode(GL_RENDER); /* No more feedback */
|
||
|
|
||
|
/* Now draw the stars as sprites. */
|
||
|
glEnable(GL_TEXTURE_2D);
|
||
|
glEnable(GL_BLEND); /* Simple additive blend is fine */
|
||
|
glBlendFunc(GL_ONE, GL_ONE);
|
||
|
|
||
|
/* Choose a color triple like this so that when the sprites overlap
|
||
|
* and the color saturates, red will clamp first, then green, then
|
||
|
* blue. */
|
||
|
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
|
||
|
glColor3f(1.0f, 0.75f, 0.5f);
|
||
|
|
||
|
/* Set up projection and modelview matrix that gives us a 1:1
|
||
|
* mapping to screen coordinates. */
|
||
|
glMatrixMode(GL_PROJECTION);
|
||
|
glPushMatrix();
|
||
|
glLoadIdentity();
|
||
|
glMatrixMode(GL_MODELVIEW);
|
||
|
glPushMatrix();
|
||
|
glLoadIdentity();
|
||
|
glScalef(2.0f / (GLfloat)W, 2.0f / (GLfloat)H, 1.0f);
|
||
|
glTranslatef(0.5f * -(GLfloat)W, 0.5f * -(GLfloat)H, 0.0f);
|
||
|
|
||
|
{
|
||
|
float width;
|
||
|
float x, y, z;
|
||
|
int i;
|
||
|
|
||
|
glBegin(GL_QUADS);
|
||
|
|
||
|
for (i = 0; i < NUM_STARS; i++) {
|
||
|
/* Skip the GL_POINT_TOKEN */
|
||
|
x = fb_buffer[4 * i + 1];
|
||
|
y = fb_buffer[4 * i + 2];
|
||
|
z = fb_buffer[4 * i + 3];
|
||
|
|
||
|
width = 10.0 * (2.0 - z); /* Arbitrary distance attenuation */
|
||
|
|
||
|
glTexCoord2f(0.0f, 0.0f);
|
||
|
glVertex2f(x - width, y - width);
|
||
|
|
||
|
glTexCoord2f(1.0f, 0.0f);
|
||
|
glVertex2f(x + width, y - width);
|
||
|
|
||
|
glTexCoord2f(1.0f, 1.0f);
|
||
|
glVertex2f(x + width, y + width);
|
||
|
|
||
|
glTexCoord2f(0.0f, 1.0f);
|
||
|
glVertex2f(x - width, y + width);
|
||
|
}
|
||
|
|
||
|
glEnd();
|
||
|
}
|
||
|
|
||
|
glMatrixMode(GL_MODELVIEW);
|
||
|
glPopMatrix();
|
||
|
glMatrixMode(GL_PROJECTION);
|
||
|
glPopMatrix();
|
||
|
|
||
|
glutSwapBuffers();
|
||
|
}
|
||
|
|
||
|
void
|
||
|
reshape_viewing(int w, int h)
|
||
|
{
|
||
|
glViewport(0, 0, w, h);
|
||
|
W = w;
|
||
|
H = h;
|
||
|
}
|
||
|
|
||
|
/************************************************************************/
|
||
|
|
||
|
void
|
||
|
animate(void)
|
||
|
{
|
||
|
phi++;
|
||
|
redraw_viewing();
|
||
|
}
|
||
|
|
||
|
void
|
||
|
key(unsigned char key, int x, int y)
|
||
|
{
|
||
|
switch (key) {
|
||
|
case 27:
|
||
|
case 'q':
|
||
|
exit(0);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
int
|
||
|
main(int argc, char **argv)
|
||
|
{
|
||
|
glutInit(&argc, argv);
|
||
|
|
||
|
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
|
||
|
glutInitWindowSize(640, 480);
|
||
|
|
||
|
glutCreateWindow("stars");
|
||
|
glutReshapeFunc(reshape_viewing);
|
||
|
glutDisplayFunc(redraw_viewing);
|
||
|
|
||
|
glutIdleFunc(animate);
|
||
|
glutKeyboardFunc(key);
|
||
|
|
||
|
glDisable(GL_DEPTH_TEST);
|
||
|
glDisable(GL_LIGHTING);
|
||
|
|
||
|
glMatrixMode(GL_MODELVIEW);
|
||
|
|
||
|
setTexture();
|
||
|
glTexParameteri(GL_TEXTURE_2D,
|
||
|
GL_TEXTURE_MIN_FILTER,
|
||
|
GL_LINEAR_MIPMAP_NEAREST);
|
||
|
glTexParameteri(GL_TEXTURE_2D,
|
||
|
GL_TEXTURE_MAG_FILTER,
|
||
|
GL_LINEAR);
|
||
|
|
||
|
glMatrixMode(GL_PROJECTION);
|
||
|
gluPerspective( /* field of view in degree */ 40.0f,
|
||
|
/* aspect ratio */ 1.0f,
|
||
|
/* Z near */ 3.0f,
|
||
|
/* Z far */ 5.0f);
|
||
|
glMatrixMode(GL_MODELVIEW);
|
||
|
gluLookAt(0.0f, 0.0f, 4.0f, /* eye position */
|
||
|
0.0f, 0.0f, 0.0f, /* looking at */
|
||
|
0.0f, 1.0f, 0.0f); /* up vector */
|
||
|
|
||
|
glutMainLoop();
|
||
|
return 0; /* ANSI C requires main to return int. */
|
||
|
}
|
||
|
|