1
0
Fork 0
flightgear/Hints/lights.c
1999-04-05 21:32:32 +00:00

288 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. */
}