777 lines
17 KiB
C++
777 lines
17 KiB
C++
#include <windows.h>
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
|
|
#include <GL/glu.h>
|
|
|
|
/*
|
|
#ifdef X11
|
|
#include <GL/glx.h>
|
|
extern "C" {
|
|
#include <tk.h>
|
|
};
|
|
#endif
|
|
*/
|
|
|
|
#ifdef WIN32
|
|
#include "stonehen.h"
|
|
#endif
|
|
|
|
#include "Point.h"
|
|
#include "Ring.h"
|
|
#include "Roundwal.h"
|
|
#include "Ellipse.h"
|
|
#include "Telescop.h"
|
|
|
|
#define SCENE_EXTERN
|
|
#include "scene.h"
|
|
|
|
GLfloat mat_view[16];
|
|
GLfloat view_rotx = 0;
|
|
GLfloat fov = 45.0, aspect = 1.0;
|
|
static Point eyep = {0, 0, .5};
|
|
static Point lookp = {0.05, 1, .25};
|
|
|
|
TimeDate current_time;
|
|
|
|
static int list_ground;
|
|
static int list_texture_ground;
|
|
static int list_trees;
|
|
static int list_texture_trees;
|
|
static int list_ring;
|
|
static int list_ellipse;
|
|
static int list_texture_stones;
|
|
static int list_shadows;
|
|
static int list_telescope;
|
|
static int list_texture_telescope;
|
|
int draw_ground = 1;
|
|
int draw_trees = 0;
|
|
int draw_ring = 1;
|
|
int draw_ellipse = 1;
|
|
int draw_shadows = 0;
|
|
|
|
int use_lighting = 1;
|
|
int use_textures = 0;
|
|
int texture_hack = 0; //HACK HACK HACK - only texture map the stone
|
|
int use_normal_fog = 0;
|
|
int use_fancy_fog = 0;
|
|
int use_telescope = 0;
|
|
int use_antialias = 0;
|
|
|
|
static void scene_identity();
|
|
static void scene_project(GLfloat f = fov, float dx = 0, float dy = 0);
|
|
static void scene_draw(int rend = 1);
|
|
static void scene_render_telescope();
|
|
|
|
static void draw_background();
|
|
|
|
Point sun_position = {0., .707, .707, 0.};
|
|
Color ambient(.25, .25, .25, 1.);
|
|
static void lights_init();
|
|
|
|
static void lists_init();
|
|
|
|
static void ground_list_init();
|
|
static void ground_draw();
|
|
|
|
Roundwall trees;
|
|
static void trees_list_init();
|
|
static void trees_draw();
|
|
|
|
Ring ring;
|
|
static void ring_list_init();
|
|
static void ring_draw();
|
|
|
|
EllipseSt ellipse;
|
|
static void ellipse_list_init();
|
|
static void ellipse_draw();
|
|
|
|
static void shadows_list_init();
|
|
static void shadows_draw();
|
|
|
|
Weather weather;
|
|
|
|
Telescope telescope;
|
|
GLfloat magnif = .5;
|
|
static void telescope_list_init();
|
|
static void telescope_draw();
|
|
|
|
/* Read the back buffer into the accum buffer, adding in the appropriate
|
|
* alpha values */
|
|
static void fog_read_image();
|
|
/* Add the accum buffer to the back buffer */
|
|
static void fog_write_image();
|
|
|
|
|
|
inline float clamp(float x, float min, float max)
|
|
{
|
|
if (x < min) return min;
|
|
else if (x > max) return max;
|
|
else return x;
|
|
}
|
|
|
|
void scene_init()
|
|
{
|
|
|
|
scene_identity();
|
|
scene_viewer_center();
|
|
|
|
glEnable(GL_CULL_FACE);
|
|
glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
|
|
|
|
|
|
glEnable(GL_NORMALIZE);
|
|
|
|
/* Initial time will be four in the afternoon */
|
|
scene_set_time(TimeDate(16, 0));
|
|
scene_set_weather(weathers[def_weather_index]);
|
|
|
|
lights_init();
|
|
lists_init();
|
|
}
|
|
|
|
|
|
inline double time_minutes(int hour, int minute, int second)
|
|
{
|
|
return (double)hour*60.0 + (double)minute + (double)second / 60.0;
|
|
}
|
|
|
|
static void scene_time_changed()
|
|
{
|
|
sun_position = current_time.sun_direction();
|
|
|
|
weather.apply(sun_position);
|
|
|
|
lights_init();
|
|
shadows_list_init();
|
|
}
|
|
|
|
void scene_set_time(TimeDate t)
|
|
{
|
|
current_time = t;
|
|
scene_time_changed();
|
|
}
|
|
|
|
void scene_inc_time(TimeDate t)
|
|
{
|
|
current_time += t;
|
|
scene_time_changed();
|
|
}
|
|
|
|
/* This is a hack -- has to be called several times to get the antialiasing
|
|
* to work */
|
|
static void scene_inner_render(GLfloat dx = 0, GLfloat dy = 0)
|
|
{
|
|
/* This draws layered fog if the use_fancy_fog flag is on --
|
|
* it's going to be slow on anything but high-end stuff */
|
|
if (use_fancy_fog && weather.fog_density != 0.) {
|
|
glMatrixMode(GL_PROJECTION);
|
|
glLoadIdentity();
|
|
glMatrixMode(GL_MODELVIEW);
|
|
glLoadIdentity();
|
|
|
|
glEnable(GL_FOG);
|
|
draw_background();
|
|
scene_project(fov, dx, dy);
|
|
glClear(GL_DEPTH_BUFFER_BIT);
|
|
if (use_lighting) glEnable(GL_LIGHTING);
|
|
scene_draw();
|
|
if (use_lighting) glDisable(GL_LIGHTING);
|
|
fog_read_image();
|
|
glDisable(GL_FOG);
|
|
} else
|
|
if (use_normal_fog && weather.fog_density != 0.) glEnable(GL_FOG);
|
|
else glDisable(GL_FOG);
|
|
|
|
glMatrixMode(GL_PROJECTION);
|
|
glLoadIdentity();
|
|
glMatrixMode(GL_MODELVIEW);
|
|
glLoadIdentity();
|
|
|
|
/* This is the part where we actually draw the image */
|
|
glClear(GL_DEPTH_BUFFER_BIT);
|
|
draw_background();
|
|
scene_project(fov, dx, dy);
|
|
glClear(GL_DEPTH_BUFFER_BIT);
|
|
if (use_lighting) glEnable(GL_LIGHTING);
|
|
scene_draw();
|
|
if (use_lighting) glDisable(GL_LIGHTING);
|
|
|
|
if (use_fancy_fog && weather.fog_density != 0.) {
|
|
fog_write_image();
|
|
}
|
|
|
|
if (use_telescope) scene_render_telescope();
|
|
}
|
|
|
|
void scene_render()
|
|
{
|
|
GLint vp[4];
|
|
|
|
scene_inner_render();
|
|
|
|
if (!use_antialias) return;
|
|
|
|
if (use_fancy_fog) {
|
|
fprintf(stderr, "Cannot antialias while using fancy fog.\n");
|
|
return;
|
|
}
|
|
|
|
|
|
glGetIntegerv(GL_VIEWPORT, vp);
|
|
glAccum(GL_LOAD, .5);
|
|
|
|
scene_inner_render(2. / (float)vp[2], 2. / (float)vp[3]);
|
|
glAccum(GL_ACCUM, .5);
|
|
|
|
/*
|
|
scene_inner_render(-2. / (float)vp[2], -2. / (float)vp[3]);
|
|
glAccum(GL_ACCUM, .25);
|
|
*/
|
|
glAccum(GL_RETURN, 1);
|
|
/*
|
|
glDrawBuffer(GL_BACK);
|
|
glFlush();
|
|
*/
|
|
}
|
|
|
|
static void scene_render_telescope()
|
|
{
|
|
telescope.draw_setup(fov, aspect);
|
|
|
|
/* Don't fog the telescope - moisture makes it rust.
|
|
* Seriously, it's in a strange coordinate system and fog will look
|
|
* bad on it. */
|
|
glPushAttrib(GL_ENABLE_BIT);
|
|
glDisable(GL_FOG);
|
|
if (use_textures) {
|
|
glCallList(list_texture_telescope);
|
|
glEnable(GL_TEXTURE_2D);
|
|
}
|
|
glCallList(list_telescope);
|
|
glPopAttrib();
|
|
|
|
if (use_lighting) glEnable(GL_LIGHTING);
|
|
glEnable(GL_STENCIL_TEST);
|
|
glClearStencil(0);
|
|
glClear(GL_STENCIL_BUFFER_BIT);
|
|
glStencilFunc(GL_ALWAYS, 0x1, 0x1);
|
|
glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
|
|
|
|
glDisable(GL_CULL_FACE);
|
|
telescope.draw_lens();
|
|
glEnable(GL_CULL_FACE);
|
|
|
|
telescope.draw_takedown();
|
|
|
|
if (use_lighting) glDisable(GL_LIGHTING);
|
|
|
|
glStencilFunc(GL_NOTEQUAL, 0x0, 0xffffffff);
|
|
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
|
|
|
|
scene_identity();
|
|
|
|
draw_background();
|
|
|
|
glMatrixMode(GL_PROJECTION);
|
|
glTranslatef(telescope.xpos / magnif, -telescope.ypos / magnif, 0);
|
|
scene_project(fov * magnif);
|
|
|
|
glClear(GL_DEPTH_BUFFER_BIT);
|
|
|
|
/* Pushing the lighting bit used to do really bad things, but
|
|
* hopefully they've all gone away */
|
|
glPushAttrib(GL_LIGHTING_BIT);
|
|
lights_init();
|
|
if (use_lighting) glEnable(GL_LIGHTING);
|
|
scene_draw();
|
|
if (use_lighting) glDisable(GL_LIGHTING);
|
|
glPopAttrib();
|
|
|
|
glDisable(GL_STENCIL_TEST);
|
|
}
|
|
|
|
static void scene_identity()
|
|
{
|
|
glMatrixMode(GL_PROJECTION);
|
|
glLoadIdentity();
|
|
glMatrixMode(GL_MODELVIEW);
|
|
glLoadIdentity();
|
|
}
|
|
|
|
static void scene_project(GLfloat f, float dx, float dy)
|
|
{
|
|
glMatrixMode(GL_PROJECTION);
|
|
glOrtho(-1 - dx, 1, -1 - dy, 1, 0, -1);
|
|
gluPerspective(f, aspect, 0.01, 40.0);
|
|
glMatrixMode(GL_MODELVIEW);
|
|
glRotatef(view_rotx, 1, 0, 0);
|
|
gluLookAt(eyep.pt[0], eyep.pt[1], eyep.pt[2],
|
|
lookp.pt[0], lookp.pt[1], lookp.pt[2],
|
|
0, 0, 1);
|
|
glMultMatrixf(mat_view);
|
|
lights_init();
|
|
}
|
|
|
|
/* scene_draw() just draws the geometry - it's used for rendering and
|
|
* picking. */
|
|
static void scene_draw(int rend)
|
|
{
|
|
if (draw_ground) {
|
|
if (rend) {
|
|
if (use_textures) {
|
|
glCallList(list_texture_ground);
|
|
glEnable(GL_TEXTURE_2D);
|
|
} else glEnable(GL_COLOR_MATERIAL);
|
|
}
|
|
glCallList(list_ground);
|
|
|
|
if (rend) {
|
|
glDisable(GL_TEXTURE_2D);
|
|
glDisable(GL_COLOR_MATERIAL);
|
|
}
|
|
}
|
|
|
|
if (draw_shadows) {
|
|
if (use_textures && rend && !draw_ground) {
|
|
glCallList(list_texture_ground);
|
|
glEnable(GL_TEXTURE_2D);
|
|
}
|
|
glCallList(list_shadows);
|
|
if (use_textures && rend) glDisable(GL_TEXTURE_2D);
|
|
}
|
|
|
|
if (draw_trees) {
|
|
if (use_textures && rend) {
|
|
glCallList(list_texture_trees);
|
|
glEnable(GL_TEXTURE_2D);
|
|
}
|
|
glCallList(list_trees);
|
|
if (use_textures && rend) glDisable(GL_TEXTURE_2D);
|
|
}
|
|
|
|
glClear(GL_DEPTH_BUFFER_BIT);
|
|
|
|
if (draw_ring) {
|
|
if (rend) {
|
|
if (use_textures || texture_hack) {
|
|
glCallList(list_texture_stones);
|
|
glEnable(GL_TEXTURE_2D);
|
|
}
|
|
glEnable(GL_COLOR_MATERIAL);
|
|
glColor3f(.5, .5, .5);
|
|
}
|
|
glCallList(list_ring);
|
|
if (rend) {
|
|
if (use_textures || texture_hack) glDisable(GL_TEXTURE_2D);
|
|
glDisable(GL_COLOR_MATERIAL);
|
|
}
|
|
}
|
|
|
|
if (draw_ellipse) {
|
|
if (use_textures && rend) {
|
|
// Hack to avoid doing something expensive twice in a row
|
|
if (!draw_ring) glCallList(list_texture_stones);
|
|
glEnable(GL_TEXTURE_2D);
|
|
}
|
|
glCallList(list_ellipse);
|
|
if (use_textures && rend) glDisable(GL_TEXTURE_2D);
|
|
}
|
|
}
|
|
|
|
static void draw_background()
|
|
{
|
|
weather.draw_sky(sun_position);
|
|
}
|
|
|
|
void scene_viewer_center()
|
|
{
|
|
glPushMatrix();
|
|
glLoadIdentity();
|
|
glGetFloatv(GL_MODELVIEW_MATRIX, mat_view);
|
|
glPopMatrix();
|
|
view_rotx = 0;
|
|
}
|
|
|
|
void scene_viewer_rotate_worldz(GLfloat degrees)
|
|
{
|
|
glMatrixMode(GL_MODELVIEW);
|
|
glPushMatrix();
|
|
glLoadIdentity();
|
|
glRotatef(degrees, 0, 0, 1);
|
|
glMultMatrixf(mat_view);
|
|
glGetFloatv(GL_MODELVIEW_MATRIX, mat_view);
|
|
glPopMatrix();
|
|
glMatrixMode(GL_MODELVIEW);
|
|
}
|
|
|
|
void scene_viewer_rotatez(GLfloat degrees)
|
|
{
|
|
glMatrixMode(GL_PROJECTION);
|
|
glPushMatrix();
|
|
glLoadIdentity();
|
|
glRotatef(degrees, 0, 0, 1);
|
|
glMultMatrixf(mat_view);
|
|
glGetFloatv(GL_PROJECTION_MATRIX, mat_view);
|
|
glPopMatrix();
|
|
glMatrixMode(GL_MODELVIEW);
|
|
}
|
|
|
|
void scene_viewer_rotatex(GLfloat degrees)
|
|
{
|
|
view_rotx += degrees;
|
|
view_rotx = clamp(view_rotx, -60, 60);
|
|
scene_identity();
|
|
scene_project();
|
|
lights_init();
|
|
}
|
|
|
|
void scene_viewer_translate(GLfloat dist)
|
|
{
|
|
glMatrixMode(GL_PROJECTION);
|
|
glPushMatrix();
|
|
glLoadIdentity();
|
|
glTranslatef(0, dist, 0);
|
|
glMultMatrixf(mat_view);
|
|
glGetFloatv(GL_PROJECTION_MATRIX, mat_view);
|
|
glPopMatrix();
|
|
glMatrixMode(GL_MODELVIEW);
|
|
scene_identity();
|
|
scene_project();
|
|
lights_init();
|
|
}
|
|
|
|
void scene_position_telescope(GLfloat x, GLfloat y)
|
|
{
|
|
telescope.xpos = x;
|
|
telescope.ypos = y;
|
|
}
|
|
|
|
void scene_get_position_telescope(GLfloat *x, GLfloat *y)
|
|
{
|
|
*x = telescope.xpos;
|
|
*y = telescope.ypos;
|
|
}
|
|
|
|
void scene_get_radius_telescope(GLfloat *r)
|
|
{
|
|
*r = telescope.get_radius();
|
|
}
|
|
|
|
void scene_set_weather(Weather w)
|
|
{
|
|
weather = w;
|
|
weather.apply(sun_position);
|
|
shadows_list_init();
|
|
}
|
|
|
|
static int get_lists(int size)
|
|
{
|
|
int i;
|
|
i = glGenLists(size);
|
|
if (size && !i) {
|
|
fprintf(stderr, "Unable to allocate %d display lists.\n");
|
|
exit(1);
|
|
}
|
|
return i;
|
|
}
|
|
|
|
static void lights_init()
|
|
{
|
|
glLightfv(GL_LIGHT0, GL_POSITION, sun_position.pt);
|
|
|
|
/* This light gives a diffuse coefficient when the sun is off -
|
|
* it's used for drawing shadows */
|
|
glLightfv(GL_LIGHT1, GL_AMBIENT, black.c);
|
|
glLightfv(GL_LIGHT1, GL_DIFFUSE, black.c);
|
|
glLightfv(GL_LIGHT1, GL_SPECULAR, black.c);
|
|
}
|
|
|
|
#ifdef TEXTURE
|
|
static void textures_list_init()
|
|
{
|
|
TK_RGBImageRec *teximage = NULL;
|
|
|
|
teximage = tkRGBImageLoad((char *)texfile_stones);
|
|
glNewList(list_texture_stones, GL_COMPILE);
|
|
gluBuild2DMipmaps(GL_TEXTURE_2D, 3, teximage->sizeX, teximage->sizeY,
|
|
GL_RGB, GL_UNSIGNED_BYTE, teximage->data);
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
|
|
GL_NEAREST_MIPMAP_NEAREST);
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
|
|
GL_LINEAR);
|
|
glMatrixMode(GL_TEXTURE);
|
|
glLoadIdentity();
|
|
glMatrixMode(GL_MODELVIEW);
|
|
glDisable(GL_TEXTURE_GEN_S);
|
|
glDisable(GL_TEXTURE_GEN_T);
|
|
glEndList();
|
|
|
|
/* tk is obnoxious and doesn't seem to provide any mechanism for this */
|
|
free(teximage->data);
|
|
free(teximage);
|
|
|
|
teximage = tkRGBImageLoad((char *)texfile_ground);
|
|
glNewList(list_texture_ground, GL_COMPILE);
|
|
gluBuild2DMipmaps(GL_TEXTURE_2D, 3, teximage->sizeX, teximage->sizeY,
|
|
GL_RGB, GL_UNSIGNED_BYTE, teximage->data);
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
|
|
GL_NEAREST_MIPMAP_NEAREST);
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
|
|
GL_LINEAR);
|
|
glMatrixMode(GL_TEXTURE);
|
|
glLoadIdentity();
|
|
glScalef(100, 100, 1);
|
|
glMatrixMode(GL_MODELVIEW);
|
|
glDisable(GL_TEXTURE_GEN_S);
|
|
glDisable(GL_TEXTURE_GEN_T);
|
|
glEndList();
|
|
|
|
free(teximage->data);
|
|
free(teximage);
|
|
|
|
/* Figure out some way to get an alpha component out of the tk --
|
|
* otherwise we're really hosed */
|
|
teximage = tkRGBImageLoad((char *)texfile_trees);
|
|
glNewList(list_texture_trees, GL_COMPILE);
|
|
/* In the final scenerio we probably won't want to mipmap this, but it's
|
|
* not square and I don't feel like bothering to scale it */
|
|
gluBuild2DMipmaps(GL_TEXTURE_2D, 3, teximage->sizeX, teximage->sizeY,
|
|
GL_RGB, GL_UNSIGNED_BYTE, teximage->data);
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
|
|
GL_NEAREST_MIPMAP_NEAREST);
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
|
|
GL_LINEAR);
|
|
glMatrixMode(GL_TEXTURE);
|
|
glLoadIdentity();
|
|
glMatrixMode(GL_MODELVIEW);
|
|
glDisable(GL_TEXTURE_GEN_S);
|
|
glDisable(GL_TEXTURE_GEN_T);
|
|
glEndList();
|
|
|
|
free(teximage->data);
|
|
free(teximage);
|
|
|
|
teximage = tkRGBImageLoad((char *)texfile_telescope);
|
|
glNewList(list_texture_telescope, GL_COMPILE);
|
|
glTexImage2D(GL_TEXTURE_2D, 0, 3, teximage->sizeX, teximage->sizeY,
|
|
0, GL_RGB, GL_UNSIGNED_BYTE, teximage->data);
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
|
glMatrixMode(GL_TEXTURE);
|
|
glLoadIdentity();
|
|
glMatrixMode(GL_MODELVIEW);
|
|
glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
|
|
glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
|
|
glEnable(GL_TEXTURE_GEN_S);
|
|
glEnable(GL_TEXTURE_GEN_T);
|
|
glEndList();
|
|
|
|
free(teximage->data);
|
|
free(teximage);
|
|
}
|
|
#endif
|
|
|
|
static void lists_init()
|
|
{
|
|
list_ground = get_lists(1);
|
|
list_texture_ground = get_lists(1);
|
|
list_trees = get_lists(1);
|
|
list_texture_trees = get_lists(1);
|
|
list_ring = get_lists(1);
|
|
list_ellipse = get_lists(1);
|
|
list_texture_stones = get_lists(1);
|
|
list_shadows = get_lists(1);
|
|
list_telescope = get_lists(1);
|
|
list_texture_telescope = get_lists(1);
|
|
|
|
ground_list_init();
|
|
trees_list_init();
|
|
shadows_list_init();
|
|
ring_list_init();
|
|
ellipse_list_init();
|
|
#ifdef TEXTURE
|
|
textures_list_init();
|
|
#endif
|
|
telescope_list_init();
|
|
}
|
|
|
|
static void ground_list_init()
|
|
{
|
|
glNewList(list_ground, GL_COMPILE);
|
|
ground_draw();
|
|
glEndList();
|
|
}
|
|
|
|
static void ground_draw()
|
|
{
|
|
glColor3f(0, .75, 0);
|
|
|
|
glLoadName(name_ground);
|
|
|
|
glNormal3f(0, 0, 1);
|
|
|
|
glPushMatrix();
|
|
/* Making something this big would confuse the zbuffer, but we're
|
|
* clearing that AFTER drawing this, so it's ok */
|
|
glScalef(100, 100, 1);
|
|
glBegin(GL_QUADS);
|
|
glTexCoord2f(0, 0);
|
|
glVertex2f(-1, -1);
|
|
glTexCoord2f(1, 0);
|
|
glVertex2f(1, -1);
|
|
glTexCoord2f(1, 1);
|
|
glVertex2f(1, 1);
|
|
glTexCoord2f(0, 1);
|
|
glVertex2f(-1, 1);
|
|
glEnd();
|
|
glPopMatrix();
|
|
}
|
|
|
|
static void trees_list_init()
|
|
{
|
|
glNewList(list_trees, GL_COMPILE);
|
|
trees_draw();
|
|
glEndList();
|
|
}
|
|
|
|
static void trees_draw()
|
|
{
|
|
glEnable(GL_COLOR_MATERIAL);
|
|
glColor3f(0, .5, 0);
|
|
|
|
glLoadName(name_trees);
|
|
|
|
glEnable(GL_BLEND);
|
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
|
trees.draw();
|
|
glDisable(GL_BLEND);
|
|
|
|
glDisable(GL_COLOR_MATERIAL);
|
|
}
|
|
|
|
static void ring_list_init()
|
|
{
|
|
glNewList(list_ring, GL_COMPILE);
|
|
ring_draw();
|
|
glEndList();
|
|
}
|
|
|
|
static void ring_draw()
|
|
{
|
|
glLoadName(name_ring);
|
|
|
|
glEnable(GL_DEPTH_TEST);
|
|
ring.erode(.1);
|
|
ring.draw();
|
|
glDisable(GL_DEPTH_TEST);
|
|
}
|
|
|
|
static void ellipse_list_init()
|
|
{
|
|
glNewList(list_ellipse, GL_COMPILE);
|
|
ellipse_draw();
|
|
glEndList();
|
|
}
|
|
|
|
static void ellipse_draw()
|
|
{
|
|
glEnable(GL_COLOR_MATERIAL);
|
|
glColor3f(.5, .5, .5);
|
|
|
|
glEnable(GL_DEPTH_TEST);
|
|
|
|
glLoadName(name_ellipse);
|
|
|
|
ellipse.erode(.1);
|
|
ellipse.draw();
|
|
|
|
glDisable(GL_DEPTH_TEST);
|
|
|
|
glDisable(GL_COLOR_MATERIAL);
|
|
}
|
|
|
|
static void shadows_list_init()
|
|
{
|
|
glNewList(list_shadows, GL_COMPILE);
|
|
shadows_draw();
|
|
glEndList();
|
|
}
|
|
|
|
static void shadows_draw()
|
|
{
|
|
Color grass(0, .75, 0);
|
|
|
|
glPushAttrib(GL_ENABLE_BIT);
|
|
|
|
/* Turn the sun off */
|
|
glDisable(GL_LIGHT0);
|
|
glEnable(GL_LIGHT1);
|
|
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, grass.c);
|
|
glColor3fv((grass * .5).c);
|
|
|
|
glDisable(GL_CULL_FACE);
|
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
|
glEnable(GL_BLEND);
|
|
ring.draw_shadow(sun_position, weather.shadow_blur(),
|
|
grass * .5, grass);
|
|
ellipse.draw_shadow(sun_position, weather.shadow_blur(),
|
|
grass * .5, grass);
|
|
glPopAttrib();
|
|
}
|
|
|
|
static void telescope_list_init()
|
|
{
|
|
glNewList(list_telescope, GL_COMPILE);
|
|
telescope_draw();
|
|
glEndList();
|
|
}
|
|
|
|
static void telescope_draw()
|
|
{
|
|
glLoadName(name_telescope);
|
|
glEnable(GL_COLOR_MATERIAL);
|
|
glDisable(GL_CULL_FACE);
|
|
glClear(GL_DEPTH_BUFFER_BIT);
|
|
glEnable(GL_DEPTH_TEST);
|
|
telescope.draw_body();
|
|
glDisable(GL_DEPTH_TEST);
|
|
glEnable(GL_CULL_FACE);
|
|
glDisable(GL_COLOR_MATERIAL);
|
|
}
|
|
|
|
static void fog_read_image()
|
|
{
|
|
glPushMatrix();
|
|
glLoadIdentity();
|
|
|
|
/* This creates an alpha gradient across the image */
|
|
/* glColorMask(0, 0, 0, 1);
|
|
glBegin(GL_QUADS);
|
|
glColor4f(1, 1, 1, 1);
|
|
glVertex2f(-1, -1);
|
|
glVertex2f(1, -1);
|
|
glColor4f(1, 1, 1, 0);
|
|
glVertex2f(1, 1);
|
|
glVertex2f(-1, 1);
|
|
glEnd();
|
|
glColorMask(1, 1, 1, 1);
|
|
*/
|
|
glDrawBuffer(GL_BACK);
|
|
glReadBuffer(GL_BACK);
|
|
glAccum(GL_LOAD, 1);
|
|
|
|
glPopMatrix();
|
|
}
|
|
|
|
static void fog_write_image()
|
|
{
|
|
glDrawBuffer(GL_BACK);
|
|
|
|
/* Put this back in once we're done testing */
|
|
// glEnable(GL_BLEND);
|
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
|
glAccum(GL_RETURN, 1);
|
|
glDisable(GL_BLEND);
|
|
}
|