--- /dev/null
+/**
+ * \file texture.cxx
+ * Texture manipulation routines
+ *
+ * Copyright (c) Mark J. Kilgard, 1997.
+ * Code added in april 2003 by Erik Hofman
+ *
+ * This program is freely distributable without licensing fees
+ * and is provided without guarantee or warrantee expressed or
+ * implied. This program is -not- in the public domain.
+ *
+ * $Id$
+ */
+
+#include <GL/glu.h>
+
+#include <stdlib.h> // malloc()
+
+#include "texture.hxx"
+#include "colours.h"
+
+SGTexture::SGTexture()
+{
+ texture_data = NULL;
+}
+
+SGTexture::~SGTexture()
+{
+ if (texture_data)
+ free(texture_data);
+}
+
+void
+SGTexture::bind()
+{
+ if (!texture_data) {
+#ifdef GL_VERSION_1_1
+ glGenTextures(1, &texture_id);
+
+#elif GL_EXT_texture_object
+ glGenTexturesEXT(1, &texture_id);
+#endif
+ }
+
+#ifdef GL_VERSION_1_1
+ glBindTexture(GL_TEXTURE_2D, texture_id);
+
+#elif GL_EXT_texture_object
+ glBindTextureEXT(GL_TEXTURE_2D, texture_id);
+#endif
+
+ if (!texture_data) {
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ }
+}
+
+/**
+ * A function to resize the OpenGL window which will be used by
+ * the dynamic texture generating routines.
+ *
+ * @param width The width of the new window
+ * @param height The height of the new window
+ */
+void
+SGTexture::resize(unsigned int width, unsigned int height)
+{
+ GLfloat aspect;
+
+ // Make sure that we don't get a divide by zero exception
+ if (height == 0)
+ height = 1;
+
+ // Set the viewport for the OpenGL window
+ glViewport(0, 0, width, height);
+
+ // Calculate the aspect ratio of the window
+ aspect = width/height;
+
+ // Go to the projection matrix, this gets modified by the perspective
+ // calulations
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+
+ // Do the perspective calculations
+ gluPerspective(45.0, aspect, 1.0, 400.0);
+
+ // Return to the modelview matrix
+ glMatrixMode(GL_MODELVIEW);
+}
+
+/**
+ * A function to prepare the OpenGL state machine for dynamic
+ * texture generation.
+ *
+ * @param width The width of the texture
+ * @param height The height of the texture
+ */
+void
+SGTexture::prepare(unsigned int width, unsigned int height) {
+
+ texture_width = width;
+ texture_height = height;
+
+ // Resize the OpenGL window to the size of our dynamic texture
+ resize(texture_width, texture_height);
+
+ // Clear the contents of the screen buffer to blue
+ glClearColor(0.0, 0.0, 1.0, 1.0);
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ // Turn off texturing (don't want the torus to be texture);
+ glDisable(GL_TEXTURE_2D);
+}
+
+/**
+ * A function to generate the dynamic texture.
+ *
+ * The actual texture can be accessed by calling get_texture()
+ *
+ * @param width The width of the previous OpenGL window
+ * @param height The height of the previous OpenGL window
+ */
+void
+SGTexture::finish(unsigned int width, unsigned int height) {
+ // If a texture hasn't been created then it gets created, and the contents
+ // of the frame buffer gets copied into it. If the texture has already been
+ // created then its contents just get updated.
+ bind();
+ if (!texture_data)
+ {
+ // Copies the contents of the frame buffer into the texture
+ glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 0, 0,
+ texture_width, texture_height, 0);
+
+ } else {
+ // Copies the contents of the frame buffer into the texture
+ glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0,
+ texture_width, texture_height);
+ }
+
+ // Set the OpenGL window back to its previous size
+ resize(width, height);
+
+ // Clear the window back to black
+ glClearColor(0.0, 0.0, 0.0, 1.0);
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+}
+
+
+void
+SGTexture::read_alpha_texture(const char *name)
+{
+ GLubyte *lptr;
+ SGTexture::ImageRec *image;
+ int y;
+
+ if (texture_data)
+ free(texture_data);
+
+ image = ImageOpen(name);
+ if(!image) {
+ return;
+ }
+
+ texture_width = image->xsize;
+ texture_height = image->ysize;
+
+ // printf("image->zsize = %d\n", image->zsize);
+
+ if (image->zsize != 1) {
+ ImageClose(image);
+ return;
+ }
+
+ texture_data = (GLubyte *)
+ malloc(image->xsize*image->ysize*sizeof(GLubyte));
+
+ if (!texture_data)
+ return;
+
+ lptr = texture_data;
+ for(y=0; y<image->ysize; y++) {
+ ImageGetRow(image,lptr,y,0);
+ lptr += image->xsize;
+ }
+ ImageClose(image);
+}
+
+void
+SGTexture::read_rgb_texture(const char *name)
+{
+ GLubyte *ptr;
+ GLubyte *rbuf, *gbuf, *bbuf, *abuf;
+ SGTexture::ImageRec *image;
+ int y;
+
+ if (texture_data)
+ free(texture_data);
+
+ image = ImageOpen(name);
+ if(!image)
+ return;
+
+ texture_width = image->xsize;
+ texture_height = image->ysize;
+ if (image->zsize != 3 && image->zsize != 4) {
+ ImageClose(image);
+ return;
+ }
+
+ texture_data = (GLubyte *)malloc(image->xsize*image->ysize*sizeof(GLubyte)*3);
+ rbuf = (GLubyte *)malloc(image->xsize*sizeof(GLubyte));
+ gbuf = (GLubyte *)malloc(image->xsize*sizeof(GLubyte));
+ bbuf = (GLubyte *)malloc(image->xsize*sizeof(GLubyte));
+ abuf = (GLubyte *)malloc(image->xsize*sizeof(GLubyte));
+ if(!texture_data || !rbuf || !gbuf || !bbuf || !abuf) {
+ if (texture_data) free(texture_data);
+ if (rbuf) free(rbuf);
+ if (gbuf) free(gbuf);
+ if (bbuf) free(bbuf);
+ if (abuf) free(abuf);
+ return;
+ }
+
+ ptr = texture_data;
+ for(y=0; y<image->ysize; y++) {
+ if(image->zsize == 4) {
+ ImageGetRow(image,rbuf,y,0);
+ ImageGetRow(image,gbuf,y,1);
+ ImageGetRow(image,bbuf,y,2);
+ ImageGetRow(image,abuf,y,3); /* Discard. */
+ rgbtorgb(rbuf,gbuf,bbuf,ptr,image->xsize);
+ ptr += (image->xsize * 3);
+ } else {
+ ImageGetRow(image,rbuf,y,0);
+ ImageGetRow(image,gbuf,y,1);
+ ImageGetRow(image,bbuf,y,2);
+ rgbtorgb(rbuf,gbuf,bbuf,ptr,image->xsize);
+ ptr += (image->xsize * 3);
+ }
+ }
+
+ ImageClose(image);
+ free(rbuf);
+ free(gbuf);
+ free(bbuf);
+ free(abuf);
+}
+
+void
+SGTexture::read_raw_texture(const char *name)
+{
+ GLubyte *ptr;
+ SGTexture::ImageRec *image;
+ int y;
+
+ if (texture_data)
+ free(texture_data);
+
+ image = RawImageOpen(name);
+
+ if(!image)
+ return;
+
+ texture_width = 256;
+ texture_height = 256;
+
+ texture_data = (GLubyte *)malloc(256*256*sizeof(GLubyte)*3);
+ if(!texture_data)
+ return;
+
+ ptr = texture_data;
+ for(y=0; y<256; y++) {
+ sgread(image->file, ptr, 256*3);
+ ptr+=256*3;
+ }
+ ImageClose(image);
+}
+
+void
+SGTexture::read_r8_texture(const char *name)
+{
+ unsigned char c[1];
+ GLubyte *ptr;
+ SGTexture::ImageRec *image;
+ int xy;
+
+ if (texture_data)
+ free(texture_data);
+
+ //it wouldn't make sense to write a new function ...
+ image = RawImageOpen(name);
+
+ if(!image)
+ return;
+
+ texture_width = 256;
+ texture_height = 256;
+
+ texture_data = (GLubyte *)malloc(256*256*sizeof(GLubyte)*3);
+ if(!texture_data)
+ return;
+
+ ptr = texture_data;
+ for(xy=0; xy<(256*256); xy++) {
+ sgread(image->file,c,1);
+
+ //look in the table for the right colours
+ ptr[0]=msfs_colour[c[0]][0];
+ ptr[1]=msfs_colour[c[0]][1];
+ ptr[2]=msfs_colour[c[0]][2];
+
+ ptr+=3;
+ }
+ ImageClose(image);
+}
+
+
+SGTexture::ImageRec *
+SGTexture::ImageOpen(const char *fileName)
+{
+ union {
+ int testWord;
+ char testByte[4];
+ } endianTest;
+
+ SGTexture::ImageRec *image;
+ int swapFlag;
+ int x;
+
+ endianTest.testWord = 1;
+ if (endianTest.testByte[0] == 1) {
+ swapFlag = 1;
+ } else {
+ swapFlag = 0;
+ }
+
+ image = (SGTexture::ImageRec *)malloc(sizeof(SGTexture::ImageRec));
+ if (image == NULL) {
+ // fprintf(stderr, "Out of memory!\n");
+ exit(1);
+ }
+ if ((image->file = sgopen(fileName, "rb")) == NULL) {
+ return NULL;
+ }
+
+ // fread(image, 1, 12, image->file);
+ sgread(image->file, image, 12);
+
+ if (swapFlag) {
+ ConvertShort(&image->imagic, 6);
+ }
+
+ image->tmp = (GLubyte *)malloc(image->xsize*256);
+ if (image->tmp == NULL) {
+ // fprintf(stderr, "\nOut of memory!\n");
+ exit(1);
+ }
+
+ if ((image->type & 0xFF00) == 0x0100) {
+ x = image->ysize * image->zsize * (int) sizeof(unsigned);
+ image->rowStart = (unsigned *)malloc(x);
+ image->rowSize = (int *)malloc(x);
+ if (image->rowStart == NULL || image->rowSize == NULL) {
+ // fprintf(stderr, "\nOut of memory!\n");
+ exit(1);
+ }
+ image->rleEnd = 512 + (2 * x);
+ sgseek(image->file, 512, SEEK_SET);
+ // fread(image->rowStart, 1, x, image->file);
+ sgread(image->file, image->rowStart, x);
+ // fread(image->rowSize, 1, x, image->file);
+ sgread(image->file, image->rowSize, x);
+ if (swapFlag) {
+ ConvertUint(image->rowStart, x/(int) sizeof(unsigned));
+ ConvertUint((unsigned *)image->rowSize, x/(int) sizeof(int));
+ }
+ }
+ return image;
+}
+
+
+void
+SGTexture::ImageClose(SGTexture::ImageRec *image) {
+ sgclose(image->file);
+ free(image->tmp);
+ free(image);
+}
+
+
+SGTexture::ImageRec *
+SGTexture::RawImageOpen(const char *fileName)
+{
+ union {
+ int testWord;
+ char testByte[4];
+ } endianTest;
+
+ SGTexture::ImageRec *image;
+ int swapFlag;
+
+ endianTest.testWord = 1;
+ if (endianTest.testByte[0] == 1) {
+ swapFlag = 1;
+ } else {
+ swapFlag = 0;
+ }
+
+ image = (SGTexture::ImageRec *)malloc(sizeof(SGTexture::ImageRec));
+ if (image == NULL) {
+ // fprintf(stderr, "Out of memory!\n");
+ exit(1);
+ }
+ if ((image->file = sgopen(fileName, "rb")) == NULL) {
+ return NULL;
+ }
+
+ sgread(image->file, image, 12);
+
+ if (swapFlag) {
+ ConvertShort(&image->imagic, 6);
+ }
+
+
+ //just allocate a pseudo value as I'm too lazy to change ImageClose()...
+ image->tmp = (GLubyte *)malloc(1);
+
+ if (image->tmp == NULL) {
+ // fprintf(stderr, "\nOut of memory!\n");
+ exit(1);
+ }
+
+ return image;
+}
+
+void
+SGTexture::ImageGetRow(SGTexture::ImageRec *image, GLubyte *buf, int y, int z) {
+ GLubyte *iPtr, *oPtr, pixel;
+ int count;
+
+ if ((image->type & 0xFF00) == 0x0100) {
+ sgseek(image->file, (long) image->rowStart[y+z*image->ysize], SEEK_SET); // fread(image->tmp, 1, (unsigned int)image->rowSize[y+z*image->ysize],
+ // image->file);
+ sgread(image->file, image->tmp,
+ (unsigned int)image->rowSize[y+z*image->ysize]);
+
+ iPtr = image->tmp;
+ oPtr = buf;
+ for (;;) {
+ pixel = *iPtr++;
+ count = (int)(pixel & 0x7F);
+ if (!count) {
+ return;
+ }
+ if (pixel & 0x80) {
+ while (count--) {
+ *oPtr++ = *iPtr++;
+ }
+ } else {
+ pixel = *iPtr++;
+ while (count--) {
+ *oPtr++ = pixel;
+ }
+ }
+ }
+ } else {
+ sgseek(image->file, 512+(y*image->xsize)+(z*image->xsize*image->ysize),
+ SEEK_SET);
+ // fread(buf, 1, image->xsize, image->file);
+ sgread(image->file, buf, image->xsize);
+ }
+}
+
+void
+SGTexture::rgbtorgb(GLubyte *r, GLubyte *g, GLubyte *b, GLubyte *l, int n) {
+ while(n--) {
+ l[0] = r[0];
+ l[1] = g[0];
+ l[2] = b[0];
+ l += 3; r++; g++; b++;
+ }
+}
+
+void
+SGTexture::ConvertShort(unsigned short *array, unsigned int length) {
+ unsigned short b1, b2;
+ unsigned char *ptr;
+
+ ptr = (unsigned char *)array;
+ while (length--) {
+ b1 = *ptr++;
+ b2 = *ptr++;
+ *array++ = (b1 << 8) | (b2);
+ }
+}
+
+void
+SGTexture::ConvertUint(unsigned *array, unsigned int length) {
+ unsigned int b1, b2, b3, b4;
+ unsigned char *ptr;
+
+ ptr = (unsigned char *)array;
+ while (length--) {
+ b1 = *ptr++;
+ b2 = *ptr++;
+ b3 = *ptr++;
+ b4 = *ptr++;
+ *array++ = (b1 << 24) | (b2 << 16) | (b3 << 8) | (b4);
+ }
+}
+
#include <plib/sg.h>
#include <simgear/debug/logstream.hxx>
+#include <simgear/sky/sunsky/sunsky.hxx>
#include "dome.hxx"
// Set up dome rendering callbacks
static int sgSkyDomePreDraw( ssgEntity *e ) {
/* cout << endl << "Dome Pre Draw" << endl << "----------------"
- << endl << endl; */
+ << endl << endl; */
ssgLeaf *f = (ssgLeaf *)e;
if ( f -> hasState () ) f->getState()->apply() ;
static int sgSkyDomePostDraw( ssgEntity *e ) {
/* cout << endl << "Dome Post Draw" << endl << "----------------"
- << endl << endl; */
+ << endl << endl; */
glPopAttrib();
// cout << "pop error = " << glGetError() << endl;
// initialize the sky object and connect it into our scene graph
ssgBranch * SGSkyDome::build( double hscale, double vscale ) {
- sgVec4 color;
+// sgVec4 color;
float theta;
int i;
dome_state->setShadeModel( GL_SMOOTH );
dome_state->disable( GL_LIGHTING );
dome_state->disable( GL_CULL_FACE );
- dome_state->disable( GL_TEXTURE_2D );
- dome_state->enable( GL_COLOR_MATERIAL );
+ dome_state->enable( GL_TEXTURE_2D );
+ dome_state->disable( GL_COLOR_MATERIAL );
dome_state->setColourMaterial( GL_AMBIENT_AND_DIFFUSE );
dome_state->setMaterial( GL_EMISSION, 0, 0, 0, 1 );
dome_state->setMaterial( GL_SPECULAR, 0, 0, 0, 1 );
// initialize arrays
center_disk_vl = new ssgVertexArray( 14 );
center_disk_cl = new ssgColourArray( 14 );
-
+
upper_ring_vl = new ssgVertexArray( 26 );
upper_ring_cl = new ssgColourArray( 26 );
lower_ring_cl = new ssgColourArray( 26 );
// initially seed to all blue
- sgSetVec4( color, 0.0, 0.0, 1.0, 1.0 );
+// sgSetVec4( color, 0.0, 0.0, 1.0, 1.0 );
// generate the raw vertex data
sgVec3 center_vertex;
sgSetVec3( center_vertex, 0.0, 0.0, center_elev * vscale );
for ( i = 0; i < 12; i++ ) {
- theta = (i * 30.0) * SGD_DEGREES_TO_RADIANS;
-
- sgSetVec3( upper_vertex[i],
- cos(theta) * upper_radius * hscale,
- sin(theta) * upper_radius * hscale,
- upper_elev * vscale );
-
- sgSetVec3( middle_vertex[i],
- cos((double)theta) * middle_radius * hscale,
- sin((double)theta) * middle_radius * hscale,
- middle_elev * vscale );
-
- sgSetVec3( lower_vertex[i],
- cos((double)theta) * lower_radius * hscale,
- sin((double)theta) * lower_radius * hscale,
- lower_elev * vscale );
-
- sgSetVec3( bottom_vertex[i],
- cos((double)theta) * bottom_radius * hscale,
- sin((double)theta) * bottom_radius * hscale,
- bottom_elev * vscale );
+ theta = (i * 30.0) * SGD_DEGREES_TO_RADIANS;
+
+ sgSetVec3( upper_vertex[i],
+ cos(theta) * upper_radius * hscale,
+ sin(theta) * upper_radius * hscale,
+ upper_elev * vscale );
+
+ sgSetVec3( middle_vertex[i],
+ cos((double)theta) * middle_radius * hscale,
+ sin((double)theta) * middle_radius * hscale,
+ middle_elev * vscale );
+
+ sgSetVec3( lower_vertex[i],
+ cos((double)theta) * lower_radius * hscale,
+ sin((double)theta) * lower_radius * hscale,
+ lower_elev * vscale );
+
+ sgSetVec3( bottom_vertex[i],
+ cos((double)theta) * bottom_radius * hscale,
+ sin((double)theta) * bottom_radius * hscale,
+ bottom_elev * vscale );
}
// generate the center disk vertex/color arrays
center_disk_vl->add( center_vertex );
- center_disk_cl->add( color );
+// center_disk_cl->add( color );
for ( i = 11; i >= 0; i-- ) {
- center_disk_vl->add( upper_vertex[i] );
- center_disk_cl->add( color );
+ center_disk_vl->add( upper_vertex[i] );
+// center_disk_cl->add( color );
}
center_disk_vl->add( upper_vertex[11] );
- center_disk_cl->add( color );
+// center_disk_cl->add( color );
// generate the upper ring
for ( i = 0; i < 12; i++ ) {
- upper_ring_vl->add( middle_vertex[i] );
- upper_ring_cl->add( color );
+ upper_ring_vl->add( middle_vertex[i] );
+// upper_ring_cl->add( color );
- upper_ring_vl->add( upper_vertex[i] );
- upper_ring_cl->add( color );
+ upper_ring_vl->add( upper_vertex[i] );
+// upper_ring_cl->add( color );
}
upper_ring_vl->add( middle_vertex[0] );
- upper_ring_cl->add( color );
+// upper_ring_cl->add( color );
upper_ring_vl->add( upper_vertex[0] );
- upper_ring_cl->add( color );
+// upper_ring_cl->add( color );
// generate middle ring
for ( i = 0; i < 12; i++ ) {
- middle_ring_vl->add( lower_vertex[i] );
- middle_ring_cl->add( color );
+ middle_ring_vl->add( lower_vertex[i] );
+// middle_ring_cl->add( color );
- middle_ring_vl->add( middle_vertex[i] );
- middle_ring_cl->add( color );
+ middle_ring_vl->add( middle_vertex[i] );
+// middle_ring_cl->add( color );
}
middle_ring_vl->add( lower_vertex[0] );
- middle_ring_cl->add( color );
+// middle_ring_cl->add( color );
middle_ring_vl->add( middle_vertex[0] );
- middle_ring_cl->add( color );
+// middle_ring_cl->add( color );
// generate lower ring
for ( i = 0; i < 12; i++ ) {
- lower_ring_vl->add( bottom_vertex[i] );
- lower_ring_cl->add( color );
+ lower_ring_vl->add( bottom_vertex[i] );
+// lower_ring_cl->add( color );
- lower_ring_vl->add( lower_vertex[i] );
- lower_ring_cl->add( color );
+ lower_ring_vl->add( lower_vertex[i] );
+// lower_ring_cl->add( color );
}
lower_ring_vl->add( bottom_vertex[0] );
- lower_ring_cl->add( color );
+// lower_ring_cl->add( color );
lower_ring_vl->add( lower_vertex[0] );
- lower_ring_cl->add( color );
+// lower_ring_cl->add( color );
// force a repaint of the sky colors with ugly defaults
- sgVec4 fog_color;
- sgSetVec4( fog_color, 1.0, 1.0, 1.0, 1.0 );
- repaint( color, fog_color, 0.0, 5000.0 );
+// sgVec4 fog_color;
+// sgSetVec4( fog_color, 1.0, 1.0, 1.0, 1.0 );
+// repaint( color, fog_color, 0.0, 5000.0 );
// build the ssg scene graph sub tree for the sky and connected
// into the provide scene graph branch
ssgVtxTable *center_disk, *upper_ring, *middle_ring, *lower_ring;
center_disk = new ssgVtxTable( GL_TRIANGLE_FAN,
- center_disk_vl, NULL, NULL, center_disk_cl );
+ center_disk_vl, NULL, NULL, center_disk_cl );
upper_ring = new ssgVtxTable( GL_TRIANGLE_STRIP,
- upper_ring_vl, NULL, NULL, upper_ring_cl );
+ upper_ring_vl, NULL, NULL, upper_ring_cl );
middle_ring = new ssgVtxTable( GL_TRIANGLE_STRIP,
- middle_ring_vl, NULL, NULL, middle_ring_cl );
+ middle_ring_vl, NULL, NULL, middle_ring_cl );
lower_ring = new ssgVtxTable( GL_TRIANGLE_STRIP,
- lower_ring_vl, NULL, NULL, lower_ring_cl );
+ lower_ring_vl, NULL, NULL, lower_ring_cl );
center_disk->setState( dome_state );
upper_ring->setState( dome_state );
}
+/**
+ * regenerate the sky texture based on the current position and time
+ *
+ * lat: the current latitude (0 ... 360)
+ * lon: the current longitude (-90 ... 90) south to north
+ * zone: standard meredian
+ * julianDay: julian day (1 ... 365)
+ * time: time of day (0.0 ... 23.99 - 14.25 = 2:15pm)
+ * turbidity: (1.0 ... 30+) 2-6 are most useful for clear days.
+ * atmEffects: if atm effects are not initialized, bad things will
+ * happen if you try to use them....
+ */
+#define SG_SKYTEXTURE_WIDTH 128
+#define SG_SKYTEXTURE_HEIGHT 128
+
+// produce theta-distorted map suitable for texture mapping
+static const bool thetaMap = false;
+
+bool SGSkyDome::repaint( float lat, float lon, int zone, int julianDay,
+ int time, float turbidity, bool atmEffects )
+{
+ SGSunSky sunSky(lat, lon, zone, julianDay, time, turbidity, atmEffects);
+
+ float sunAngle = sqrt(sunSky.GetSunSolidAngle() / SG_PI);
+ sgVec3 *sunColour = sunSky.GetSunSpectralRadiance().To_XYZ();
+ sgVec3 *sunDir = sunSky.GetSunPosition();
+
+ for (unsigned int i = 0; i < 128; i++ ) {
+ for (unsigned int j = 0; j < 128; j++ ) {
+
+ sgVec2 hemiPos, normVec2;
+ sgVec3 hemiDir;
+ sgVec3 *hemiColour;
+
+ sgSetVec2( normVec2, 1.0, 1.0 );
+ sgSetVec2( hemiPos, (j + 0.5)/SG_SKYTEXTURE_WIDTH,
+ (i + 0.5)/SG_SKYTEXTURE_WIDTH );
+
+ sgScaleVec2(hemiPos, 2.0);
+ sgAddVec2(hemiPos, normVec2);
+
+ if (sgDistanceSquaredVec2(hemiPos, normVec2) <= 1.0)
+ {
+ // North = Up, East = left, so hemisphere is 'above' viewer:
+ // imagine lying on your back looking up at the sky,
+ // head oriented towards north
+
+ if (thetaMap)
+ {
+ // remap to theta-based coords
+ float r = sgLengthVec2(hemiPos);
+ sgScaleVec2(hemiPos, cos(SG_PI * (1 - r) / 2.0) / r);
+ }
+
+ sgSetVec3( hemiDir, -hemiPos[1], -hemiPos[0],
+ sqrt(1.0-sgDistanceSquaredVec2(hemiPos, normVec2)) );
+
+ if (acos(sgScalarProductVec2(hemiDir, *sunDir)) < sunAngle)
+ {
+ // this is actually a little beside the point: as
+ // the sun subtends about 0.5 degrees, at an image
+ // size of 400x400 pixels, the sun will only cover a
+ // pixel or so.
+ hemiColour = sunColour;
+ }
+ else
+ {
+ hemiColour = sunSky.GetSkyXYZRadiance(&hemiDir);
+ // hemiColour = csDisplay.ToGamut(hemiColour);
+ }
+
+ radImage.SetPixel(j, i, hemiColour);
+ }
+ else
+ radImage.SetPixel(j, i, cBlack);
+ }
+ }
+}
+
+
// repaint the sky colors based on current value of sun_angle, sky,
// and fog colors. This updates the color arrays for ssgVtxTable.
// sun angle in degrees relative to verticle
// 90 degrees = sun rise/set
// 180 degrees = darkest midnight
bool SGSkyDome::repaint( sgVec4 sky_color, sgVec4 fog_color, double sun_angle,
- double vis )
+ double vis )
{
+#if 0
double diff;
sgVec3 outer_param, outer_amt, outer_diff;
sgVec3 middle_param, middle_amt, middle_diff;
// Check for sunrise/sunset condition
if ( (sun_angle > 80.0) && (sun_angle < 100.0) ) {
- // 0.0 - 0.4
- sgSetVec3( outer_param,
- (10.0 - fabs(90.0 - sun_angle)) / 20.0,
- (10.0 - fabs(90.0 - sun_angle)) / 40.0,
- -(10.0 - fabs(90.0 - sun_angle)) / 30.0 );
+ // 0.0 - 0.4
+ sgSetVec3( outer_param,
+ (10.0 - fabs(90.0 - sun_angle)) / 20.0,
+ (10.0 - fabs(90.0 - sun_angle)) / 40.0,
+ -(10.0 - fabs(90.0 - sun_angle)) / 30.0 );
- sgSetVec3( middle_param,
- (10.0 - fabs(90.0 - sun_angle)) / 40.0,
- (10.0 - fabs(90.0 - sun_angle)) / 80.0,
- 0.0 );
+ sgSetVec3( middle_param,
+ (10.0 - fabs(90.0 - sun_angle)) / 40.0,
+ (10.0 - fabs(90.0 - sun_angle)) / 80.0,
+ 0.0 );
- sgScaleVec3( outer_diff, outer_param, 1.0 / 6.0 );
+ sgScaleVec3( outer_diff, outer_param, 1.0 / 6.0 );
- sgScaleVec3( middle_diff, middle_param, 1.0 / 6.0 );
+ sgScaleVec3( middle_diff, middle_param, 1.0 / 6.0 );
} else {
- sgSetVec3( outer_param, 0.0, 0.0, 0.0 );
- sgSetVec3( middle_param, 0.0, 0.0, 0.0 );
+ sgSetVec3( outer_param, 0.0, 0.0, 0.0 );
+ sgSetVec3( middle_param, 0.0, 0.0, 0.0 );
- sgSetVec3( outer_diff, 0.0, 0.0, 0.0 );
- sgSetVec3( middle_diff, 0.0, 0.0, 0.0 );
+ sgSetVec3( outer_diff, 0.0, 0.0, 0.0 );
+ sgSetVec3( middle_diff, 0.0, 0.0, 0.0 );
}
// printf(" outer_red_param = %.2f outer_red_diff = %.2f\n",
// outer_red_param, outer_red_diff);
double vis_factor;
if ( vis < 3000.0 ) {
- vis_factor = (vis - 1000.0) / 2000.0;
- if ( vis_factor < 0.0 ) {
- vis_factor = 0.0;
- }
+ vis_factor = (vis - 1000.0) / 2000.0;
+ if ( vis_factor < 0.0 ) {
+ vis_factor = 0.0;
+ }
} else {
- vis_factor = 1.0;
+ vis_factor = 1.0;
}
for ( j = 0; j < 3; j++ ) {
- diff = sky_color[j] - fog_color[j];
- center_color[j] = sky_color[j] - diff * ( 1.0 - vis_factor );
+ diff = sky_color[j] - fog_color[j];
+ center_color[j] = sky_color[j] - diff * ( 1.0 - vis_factor );
}
center_color[3] = 1.0;
for ( i = 0; i < 6; i++ ) {
- for ( j = 0; j < 3; j++ ) {
- diff = sky_color[j] - fog_color[j];
-
- // printf("sky = %.2f fog = %.2f diff = %.2f\n",
- // l->sky_color[j], l->fog_color[j], diff);
-
- upper_color[i][j] = sky_color[j] - diff * ( 1.0 - vis_factor * 0.7);
- middle_color[i][j] = sky_color[j] - diff * ( 1.0 - vis_factor * 0.1)
- + middle_amt[j];
- lower_color[i][j] = fog_color[j] + outer_amt[j];
-
- if ( upper_color[i][j] > 1.0 ) { upper_color[i][j] = 1.0; }
- if ( upper_color[i][j] < 0.0 ) { upper_color[i][j] = 0.0; }
- if ( middle_color[i][j] > 1.0 ) { middle_color[i][j] = 1.0; }
- if ( middle_color[i][j] < 0.0 ) { middle_color[i][j] = 0.0; }
- if ( lower_color[i][j] > 1.0 ) { lower_color[i][j] = 1.0; }
- if ( lower_color[i][j] < 0.0 ) { lower_color[i][j] = 0.0; }
- }
- upper_color[i][3] = middle_color[i][3] = lower_color[i][3] = 1.0;
-
- for ( j = 0; j < 3; j++ ) {
- outer_amt[j] -= outer_diff[j];
- middle_amt[j] -= middle_diff[j];
- }
-
- /*
- printf("upper_color[%d] = %.2f %.2f %.2f %.2f\n", i, upper_color[i][0],
- upper_color[i][1], upper_color[i][2], upper_color[i][3]);
- printf("middle_color[%d] = %.2f %.2f %.2f %.2f\n", i,
- middle_color[i][0], middle_color[i][1], middle_color[i][2],
- middle_color[i][3]);
- printf("lower_color[%d] = %.2f %.2f %.2f %.2f\n", i,
- lower_color[i][0], lower_color[i][1], lower_color[i][2],
- lower_color[i][3]);
- */
+ for ( j = 0; j < 3; j++ ) {
+ diff = sky_color[j] - fog_color[j];
+
+ // printf("sky = %.2f fog = %.2f diff = %.2f\n",
+ // l->sky_color[j], l->fog_color[j], diff);
+
+ upper_color[i][j] = sky_color[j] - diff * ( 1.0 - vis_factor * 0.7);
+ middle_color[i][j] = sky_color[j] - diff * ( 1.0 - vis_factor * 0.1)
+ + middle_amt[j];
+ lower_color[i][j] = fog_color[j] + outer_amt[j];
+
+ if ( upper_color[i][j] > 1.0 ) { upper_color[i][j] = 1.0; }
+ if ( upper_color[i][j] < 0.0 ) { upper_color[i][j] = 0.0; }
+ if ( middle_color[i][j] > 1.0 ) { middle_color[i][j] = 1.0; }
+ if ( middle_color[i][j] < 0.0 ) { middle_color[i][j] = 0.0; }
+ if ( lower_color[i][j] > 1.0 ) { lower_color[i][j] = 1.0; }
+ if ( lower_color[i][j] < 0.0 ) { lower_color[i][j] = 0.0; }
+ }
+ upper_color[i][3] = middle_color[i][3] = lower_color[i][3] = 1.0;
+
+ for ( j = 0; j < 3; j++ ) {
+ outer_amt[j] -= outer_diff[j];
+ middle_amt[j] -= middle_diff[j];
+ }
+
+ /*
+ printf("upper_color[%d] = %.2f %.2f %.2f %.2f\n", i, upper_color[i][0],
+ upper_color[i][1], upper_color[i][2], upper_color[i][3]);
+ printf("middle_color[%d] = %.2f %.2f %.2f %.2f\n", i,
+ middle_color[i][0], middle_color[i][1], middle_color[i][2],
+ middle_color[i][3]);
+ printf("lower_color[%d] = %.2f %.2f %.2f %.2f\n", i,
+ lower_color[i][0], lower_color[i][1], lower_color[i][2],
+ lower_color[i][3]);
+ */
}
sgSetVec3( outer_amt, 0.0, 0.0, 0.0 );
sgSetVec3( middle_amt, 0.0, 0.0, 0.0 );
for ( i = 6; i < 12; i++ ) {
- for ( j = 0; j < 3; j++ ) {
- diff = sky_color[j] - fog_color[j];
-
- // printf("sky = %.2f fog = %.2f diff = %.2f\n",
- // sky_color[j], fog_color[j], diff);
-
- upper_color[i][j] = sky_color[j] - diff * ( 1.0 - vis_factor * 0.7);
- middle_color[i][j] = sky_color[j] - diff * ( 1.0 - vis_factor * 0.1)
- + middle_amt[j];
- lower_color[i][j] = fog_color[j] + outer_amt[j];
-
- if ( upper_color[i][j] > 1.0 ) { upper_color[i][j] = 1.0; }
- if ( upper_color[i][j] < 0.0 ) { upper_color[i][j] = 0.0; }
- if ( middle_color[i][j] > 1.0 ) { middle_color[i][j] = 1.0; }
- if ( middle_color[i][j] < 0.0 ) { middle_color[i][j] = 0.0; }
- if ( lower_color[i][j] > 1.0 ) { lower_color[i][j] = 1.0; }
- if ( lower_color[i][j] < 0.0 ) { lower_color[i][j] = 0.0; }
- }
- upper_color[i][3] = middle_color[i][3] = lower_color[i][3] = 1.0;
-
- for ( j = 0; j < 3; j++ ) {
- outer_amt[j] += outer_diff[j];
- middle_amt[j] += middle_diff[j];
- }
-
- /*
- printf("upper_color[%d] = %.2f %.2f %.2f %.2f\n", i, upper_color[i][0],
- upper_color[i][1], upper_color[i][2], upper_color[i][3]);
- printf("middle_color[%d] = %.2f %.2f %.2f %.2f\n", i,
- middle_color[i][0], middle_color[i][1], middle_color[i][2],
- middle_color[i][3]);
- printf("lower_color[%d] = %.2f %.2f %.2f %.2f\n", i,
- lower_color[i][0], lower_color[i][1], lower_color[i][2],
- lower_color[i][3]);
+ for ( j = 0; j < 3; j++ ) {
+ diff = sky_color[j] - fog_color[j];
+
+ // printf("sky = %.2f fog = %.2f diff = %.2f\n",
+ // sky_color[j], fog_color[j], diff);
+
+ upper_color[i][j] = sky_color[j] - diff * ( 1.0 - vis_factor * 0.7);
+ middle_color[i][j] = sky_color[j] - diff * ( 1.0 - vis_factor * 0.1)
+ + middle_amt[j];
+ lower_color[i][j] = fog_color[j] + outer_amt[j];
+
+ if ( upper_color[i][j] > 1.0 ) { upper_color[i][j] = 1.0; }
+ if ( upper_color[i][j] < 0.0 ) { upper_color[i][j] = 0.0; }
+ if ( middle_color[i][j] > 1.0 ) { middle_color[i][j] = 1.0; }
+ if ( middle_color[i][j] < 0.0 ) { middle_color[i][j] = 0.0; }
+ if ( lower_color[i][j] > 1.0 ) { lower_color[i][j] = 1.0; }
+ if ( lower_color[i][j] < 0.0 ) { lower_color[i][j] = 0.0; }
+ }
+ upper_color[i][3] = middle_color[i][3] = lower_color[i][3] = 1.0;
+
+ for ( j = 0; j < 3; j++ ) {
+ outer_amt[j] += outer_diff[j];
+ middle_amt[j] += middle_diff[j];
+ }
+
+ /*
+ printf("upper_color[%d] = %.2f %.2f %.2f %.2f\n", i, upper_color[i][0],
+ upper_color[i][1], upper_color[i][2], upper_color[i][3]);
+ printf("middle_color[%d] = %.2f %.2f %.2f %.2f\n", i,
+ middle_color[i][0], middle_color[i][1], middle_color[i][2],
+ middle_color[i][3]);
+ printf("lower_color[%d] = %.2f %.2f %.2f %.2f\n", i,
+ lower_color[i][0], lower_color[i][1], lower_color[i][2],
+ lower_color[i][3]);
*/
}
for ( i = 0; i < 12; i++ ) {
- sgCopyVec4( bottom_color[i], fog_color );
+ sgCopyVec4( bottom_color[i], fog_color );
}
//
// sgSetVec4( red, 1.0, 0.0, 0.0, 1.0 );
sgCopyVec4( slot, center_color );
for ( i = 11; i >= 0; i-- ) {
- slot = center_disk_cl->get( counter++ );
- sgCopyVec4( slot, upper_color[i] );
+ slot = center_disk_cl->get( counter++ );
+ sgCopyVec4( slot, upper_color[i] );
}
slot = center_disk_cl->get( counter++ );
sgCopyVec4( slot, upper_color[11] );
// generate the upper ring
counter = 0;
for ( i = 0; i < 12; i++ ) {
- slot = upper_ring_cl->get( counter++ );
- sgCopyVec4( slot, middle_color[i] );
+ slot = upper_ring_cl->get( counter++ );
+ sgCopyVec4( slot, middle_color[i] );
- slot = upper_ring_cl->get( counter++ );
- sgCopyVec4( slot, upper_color[i] );
+ slot = upper_ring_cl->get( counter++ );
+ sgCopyVec4( slot, upper_color[i] );
}
slot = upper_ring_cl->get( counter++ );
sgCopyVec4( slot, middle_color[0] );
// generate middle ring
counter = 0;
for ( i = 0; i < 12; i++ ) {
- slot = middle_ring_cl->get( counter++ );
- sgCopyVec4( slot, lower_color[i] );
+ slot = middle_ring_cl->get( counter++ );
+ sgCopyVec4( slot, lower_color[i] );
- slot = middle_ring_cl->get( counter++ );
- sgCopyVec4( slot, middle_color[i] );
+ slot = middle_ring_cl->get( counter++ );
+ sgCopyVec4( slot, middle_color[i] );
}
slot = middle_ring_cl->get( counter++ );
sgCopyVec4( slot, lower_color[0] );
// generate lower ring
counter = 0;
for ( i = 0; i < 12; i++ ) {
- slot = lower_ring_cl->get( counter++ );
- sgCopyVec4( slot, bottom_color[i] );
+ slot = lower_ring_cl->get( counter++ );
+ sgCopyVec4( slot, bottom_color[i] );
- slot = lower_ring_cl->get( counter++ );
- sgCopyVec4( slot, lower_color[i] );
+ slot = lower_ring_cl->get( counter++ );
+ sgCopyVec4( slot, lower_color[i] );
}
slot = lower_ring_cl->get( counter++ );
sgCopyVec4( slot, bottom_color[0] );
slot = lower_ring_cl->get( counter++ );
sgCopyVec4( slot, lower_color[0] );
-
+#endif
return true;
}
// spin specifies a rotation about the new Z axis (and orients the
// sunrise/set effects
bool SGSkyDome::reposition( sgVec3 p, double lon, double lat, double spin ) {
+#if 0
sgMat4 T, LON, LAT, SPIN;
sgVec3 axis;
sgSetCoord( &skypos, TRANSFORM );
dome_transform->setTransform( &skypos );
-
+#endif
return true;
}