From 11d2bca8a7885e83c2cc85859da4fccfa4e419e3 Mon Sep 17 00:00:00 2001 From: ehofman Date: Wed, 9 Apr 2003 20:24:52 +0000 Subject: [PATCH] Add out own texture object --- configure.ac | 1 + simgear/misc/Makefile.am | 7 +- simgear/misc/colours.h | 289 +++++++++++++++++++ simgear/misc/texture.cxx | 514 ++++++++++++++++++++++++++++++++++ simgear/misc/texture.hxx | 80 ++++++ simgear/scene/sky/Makefile.am | 3 +- simgear/scene/sky/dome.cxx | 415 ++++++++++++++++----------- simgear/scene/sky/dome.hxx | 5 + simgear/sg_zlib.h | 2 +- 9 files changed, 1147 insertions(+), 169 deletions(-) create mode 100644 simgear/misc/colours.h create mode 100644 simgear/misc/texture.cxx create mode 100644 simgear/misc/texture.hxx diff --git a/configure.ac b/configure.ac index 7d0e5354..c7342f1d 100644 --- a/configure.ac +++ b/configure.ac @@ -420,6 +420,7 @@ AC_CONFIG_FILES([ \ simgear/serial/Makefile \ simgear/sky/Makefile \ simgear/sky/clouds3d/Makefile \ + simgear/sky/sunsky/Makefile \ simgear/threads/Makefile \ simgear/timing/Makefile \ simgear/xgl/Makefile \ diff --git a/simgear/misc/Makefile.am b/simgear/misc/Makefile.am index d691930d..d961b03c 100644 --- a/simgear/misc/Makefile.am +++ b/simgear/misc/Makefile.am @@ -2,16 +2,20 @@ includedir = @includedir@/misc lib_LIBRARIES = libsgmisc.a +noinst_HEADERS = \ + colours.h + include_HEADERS = \ commands.hxx \ exception.hxx \ props.hxx \ - props_io.hxx \ + props_io.hxx \ sg_path.hxx \ sgstream.hxx \ stopwatch.hxx \ strutils.hxx \ tabbed_values.hxx \ + texture.hxx \ texcoord.hxx \ zfstream.hxx @@ -24,6 +28,7 @@ libsgmisc_a_SOURCES = \ sgstream.cxx \ strutils.cxx \ tabbed_values.cxx \ + texture.cxx \ texcoord.cxx \ zfstream.cxx diff --git a/simgear/misc/colours.h b/simgear/misc/colours.h new file mode 100644 index 00000000..ba3b8914 --- /dev/null +++ b/simgear/misc/colours.h @@ -0,0 +1,289 @@ +// colours.h -- This header file contains colour definitions in the +// same way as MS FS5 does +// +// Contributed by "Christian Mayer" , started April 1999. +// +// Copyright (C) 1998 Christian Mayer - Vader@t-online.de +// +// This program 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 of the +// License, or (at your option) any later version. +// +// This program 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 this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +// +// $Id$ + + +#ifndef COLOURS_H +#define COLOURS_H + +unsigned char msfs_colour[256][3]= +{ + { 0, 0, 0}, + { 8, 8, 8}, + { 16, 16, 16}, + { 24, 24, 24}, + { 32, 32, 32}, + { 40, 40, 40}, + { 48, 48, 48}, + { 56, 56, 56}, + { 65, 65, 65}, + { 73, 73, 73}, + { 81, 81, 81}, + { 89, 89, 89}, + { 97, 97, 97}, + {105, 105, 105}, + {113, 113, 113}, + {121, 121, 121}, + {130, 130, 130}, + {138, 138, 138}, + {146, 146, 146}, + {154, 154, 154}, + {162, 162, 162}, + {170, 170, 170}, + {178, 178, 178}, + {186, 186, 186}, + {195, 195, 195}, + {203, 203, 203}, + {211, 211, 211}, + {219, 219, 219}, + {227, 227, 227}, + {235, 235, 235}, + {247, 247, 247}, + {255, 255, 255}, + { 21, 5, 5}, + { 42, 10, 10}, + { 63, 15, 15}, + { 84, 20, 20}, + {105, 25, 25}, + {126, 30, 30}, + {147, 35, 35}, + {168, 40, 40}, + {189, 45, 45}, + {210, 50, 50}, + {231, 55, 55}, + {252, 60, 60}, + { 5, 21, 5}, + { 10, 42, 10}, + { 15, 63, 15}, + { 20, 84, 20}, + { 25, 105, 25}, + { 30, 126, 30}, + { 35, 147, 35}, + { 40, 168, 40}, + { 45, 189, 45}, + { 50, 210, 50}, + { 55, 231, 55}, + { 60, 252, 60}, + { 0, 7, 23}, + { 0, 15, 40}, + { 0, 23, 58}, + { 0, 40, 84}, + { 0, 64, 104}, + { 0, 71, 122}, + { 0, 87, 143}, + { 0, 99, 156}, + { 0, 112, 179}, + { 0, 128, 199}, + { 0, 143, 215}, + { 0, 153, 230}, + { 28, 14, 0}, + { 56, 28, 0}, + { 84, 42, 0}, + {112, 56, 0}, + {140, 70, 0}, + {168, 84, 0}, + {196, 98, 0}, + {224, 112, 0}, + {252, 126, 0}, + { 28, 28, 0}, + { 56, 56, 0}, + { 84, 84, 0}, + {112, 112, 0}, + {140, 140, 0}, + {168, 168, 0}, + {196, 196, 0}, + {224, 224, 0}, + {252, 252, 0}, + { 25, 21, 16}, + { 50, 42, 32}, + { 75, 63, 48}, + {100, 84, 64}, + {125, 105, 80}, + {150, 126, 96}, + {175, 147, 112}, + {200, 168, 128}, + {225, 189, 144}, + { 28, 11, 7}, + { 56, 22, 14}, + { 84, 33, 21}, + {112, 44, 28}, + {140, 55, 35}, + {168, 66, 42}, + {196, 77, 49}, + {224, 88, 56}, + {252, 99, 63}, + { 17, 22, 9}, + { 34, 44, 18}, + { 51, 66, 27}, + { 68, 88, 36}, + { 85, 110, 45}, + {102, 132, 54}, + {119, 154, 63}, + {136, 176, 72}, + {153, 198, 81}, + { 0, 58, 104}, + { 0, 87, 112}, + { 43, 112, 128}, + {255, 0, 0}, + { 64, 255, 64}, + { 0, 0, 192}, + { 0, 105, 105}, + {255, 128, 0}, + {255, 255, 0}, + { 81, 81, 81}, + {121, 121, 121}, + {146, 146, 146}, + {170, 170, 170}, + {195, 195, 195}, + {227, 227, 227}, + { 0, 0, 0}, + { 0, 0, 0}, + { 0, 0, 0}, + { 0, 0, 0}, + { 0, 0, 0}, + { 0, 0, 0}, + { 0, 0, 0}, + { 0, 0, 0}, + { 0, 0, 0}, + { 0, 0, 0}, + { 0, 0, 0}, + { 0, 0, 0}, + { 0, 0, 0}, + { 0, 0, 0}, + { 0, 0, 0}, + { 0, 0, 0}, + { 0, 0, 0}, + { 0, 0, 0}, + { 0, 0, 0}, + { 0, 0, 0}, + { 0, 0, 0}, + { 0, 0, 0}, + { 0, 0, 0}, + { 0, 0, 0}, + { 0, 0, 0}, + { 0, 0, 0}, + { 0, 0, 0}, + { 0, 0, 0}, + { 0, 0, 0}, + { 0, 0, 0}, + { 0, 0, 0}, + { 0, 0, 0}, + {192, 192, 255}, + {200, 200, 255}, + {208, 208, 255}, + {216, 216, 255}, + {224, 224, 255}, + {232, 232, 255}, + {240, 240, 255}, + {248, 248, 255}, + {255, 255, 255}, + {255, 255, 255}, + {255, 255, 255}, + {255, 255, 255}, + {255, 255, 255}, + {255, 255, 255}, + {255, 255, 255}, + {255, 255, 255}, + { 16, 72, 16}, + { 32, 80, 32}, + { 48, 88, 48}, + { 64, 96, 64}, + { 80, 104, 80}, + { 96, 112, 96}, + {112, 120, 112}, + {120, 124, 120}, + {128, 128, 128}, + {128, 128, 128}, + {128, 128, 128}, + {128, 128, 128}, + {128, 128, 128}, + {128, 128, 128}, + {128, 128, 128}, + {128, 128, 128}, + { 33, 140, 189}, + { 57, 132, 165}, + {189, 66, 66}, + {156, 66, 66}, + {132, 74, 74}, + { 33, 82, 107}, + {214, 90, 82}, + {189, 90, 82}, + {165, 90, 82}, + {123, 57, 49}, + { 99, 57, 49}, + {107, 74, 66}, + {123, 90, 82}, + {181, 90, 66}, + { 74, 49, 41}, + {189, 115, 90}, + {140, 90, 49}, + { 33, 49, 74}, + {181, 115, 49}, + { 99, 66, 33}, + {165, 115, 66}, + { 49, 41, 33}, + {165, 140, 115}, + {189, 165, 140}, + { 57, 99, 123}, + {181, 107, 24}, + {206, 123, 33}, + {156, 99, 33}, + {148, 107, 49}, + {107, 82, 49}, + { 33, 33, 57}, + { 33, 115, 165}, + {214, 214, 33}, + {173, 173, 33}, + {198, 198, 41}, + {140, 140, 33}, + {115, 115, 33}, + {189, 189, 57}, + {156, 156, 49}, + {173, 173, 57}, + {123, 123, 49}, + {123, 123, 66}, + { 74, 74, 49}, + {123, 123, 90}, + { 41, 41, 33}, + { 90, 99, 57}, + {107, 115, 74}, + {123, 148, 82}, + {140, 173, 99}, + {132, 156, 99}, + { 49, 66, 41}, + { 99, 165, 90}, + { 74, 214, 74}, + { 57, 140, 57}, + { 74, 181, 74}, + { 90, 198, 90}, + { 57, 123, 57}, + { 49, 99, 49}, + { 90, 165, 90}, + { 82, 148, 82}, + { 74, 99, 74}, + { 57, 115, 132}, + { 33, 99, 123}, + { 74, 115, 132} +}; + + +#endif diff --git a/simgear/misc/texture.cxx b/simgear/misc/texture.cxx new file mode 100644 index 00000000..0d2328e5 --- /dev/null +++ b/simgear/misc/texture.cxx @@ -0,0 +1,514 @@ +/** + * \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 + +#include // 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; yysize; 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; yysize; 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); + } +} + diff --git a/simgear/misc/texture.hxx b/simgear/misc/texture.hxx new file mode 100644 index 00000000..ef739a90 --- /dev/null +++ b/simgear/misc/texture.hxx @@ -0,0 +1,80 @@ + +#ifndef __SG_TEXTURE_HXX +#define __SG_TEXTURE_HXX 1 + +#include + +#include + +class SGTexture { + +private: + + GLuint texture_id; + GLubyte *texture_data; + + GLsizei texture_width; + GLsizei texture_height; + + void resize(unsigned int width = 256, unsigned int height = 256); + +protected: + + typedef struct _ImageRec { + unsigned short imagic; + unsigned short type; + unsigned short dim; + unsigned short xsize, ysize, zsize; + unsigned int min, max; + unsigned int wasteBytes; + char name[80]; + unsigned long colorMap; + sgFile file; + GLubyte *tmp; + unsigned long rleEnd; + unsigned int *rowStart; + int *rowSize; + } ImageRec; + + void ConvertUint(unsigned *array, unsigned int length); + void ConvertShort(unsigned short *array, unsigned int length); + void rgbtorgb(GLubyte *r, GLubyte *g, GLubyte *b, GLubyte *l, int n); + + ImageRec *ImageOpen(const char *fileName); + ImageRec *RawImageOpen(const char *fileName); + void ImageClose(ImageRec *image); + void ImageGetRow(ImageRec *image, GLubyte *buf, int y, int z); + +public: + + SGTexture(); + ~SGTexture(); + + /* Copyright (c) Mark J. Kilgard, 1997. */ + void read_alpha_texture(const char *name); + void read_rgb_texture(const char *name); + void read_raw_texture(const char *name); + void read_r8_texture(const char *name); + + inline bool usable() { return texture_data ? true : false; } + + inline GLuint id() { return texture_id; } + inline GLubyte *texture() { return texture_data; } + + inline int width() { return texture_width; } + inline int height() { return texture_height; } + + void prepare(unsigned int width = 256, unsigned int height = 256); + void finish(unsigned int width, unsigned int height); + + void bind(); + inline void select() { + // if (texture_data) + glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, + texture_width, texture_height, 0, + GL_RGB, GL_UNSIGNED_BYTE, texture_data ); + } +}; + +#endif + diff --git a/simgear/scene/sky/Makefile.am b/simgear/scene/sky/Makefile.am index c2364339..929689ee 100644 --- a/simgear/scene/sky/Makefile.am +++ b/simgear/scene/sky/Makefile.am @@ -1,6 +1,7 @@ includedir = @includedir@/sky -# SUBDIRS = clouds3d +SUBDIRS = sunsky +# SUBDIRS += clouds3d lib_LIBRARIES = libsgsky.a diff --git a/simgear/scene/sky/dome.cxx b/simgear/scene/sky/dome.cxx index 17fc03f4..e6535091 100644 --- a/simgear/scene/sky/dome.cxx +++ b/simgear/scene/sky/dome.cxx @@ -38,6 +38,7 @@ #include #include +#include #include "dome.hxx" @@ -66,7 +67,7 @@ static const float bottom_elev = -0.0250; // 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() ; @@ -82,7 +83,7 @@ static int sgSkyDomePreDraw( ssgEntity *e ) { static int sgSkyDomePostDraw( ssgEntity *e ) { /* cout << endl << "Dome Post Draw" << endl << "----------------" - << endl << endl; */ + << endl << endl; */ glPopAttrib(); // cout << "pop error = " << glGetError() << endl; @@ -103,7 +104,7 @@ SGSkyDome::~SGSkyDome( void ) { // 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; @@ -113,8 +114,8 @@ ssgBranch * SGSkyDome::build( double hscale, double vscale ) { 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 ); @@ -124,7 +125,7 @@ ssgBranch * SGSkyDome::build( double hscale, double vscale ) { // 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 ); @@ -135,7 +136,7 @@ ssgBranch * SGSkyDome::build( double hscale, double vscale ) { 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; @@ -147,101 +148,101 @@ ssgBranch * SGSkyDome::build( double hscale, double vscale ) { 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 ); @@ -272,6 +273,86 @@ ssgBranch * SGSkyDome::build( double hscale, double vscale ) { } +/** + * 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 @@ -279,8 +360,9 @@ ssgBranch * SGSkyDome::build( double hscale, double vscale ) { // 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; @@ -288,26 +370,26 @@ bool SGSkyDome::repaint( sgVec4 sky_color, sgVec4 fog_color, double sun_angle, // 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); @@ -329,101 +411,101 @@ bool SGSkyDome::repaint( sgVec4 sky_color, sgVec4 fog_color, double sun_angle, 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 ); } // @@ -440,8 +522,8 @@ bool SGSkyDome::repaint( sgVec4 sky_color, sgVec4 fog_color, double sun_angle, // 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] ); @@ -449,11 +531,11 @@ bool SGSkyDome::repaint( sgVec4 sky_color, sgVec4 fog_color, double sun_angle, // 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] ); @@ -464,11 +546,11 @@ bool SGSkyDome::repaint( sgVec4 sky_color, sgVec4 fog_color, double sun_angle, // 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] ); @@ -479,18 +561,18 @@ bool SGSkyDome::repaint( sgVec4 sky_color, sgVec4 fog_color, double sun_angle, // 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; } @@ -501,6 +583,7 @@ bool SGSkyDome::repaint( sgVec4 sky_color, sgVec4 fog_color, double sun_angle, // 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; @@ -540,6 +623,6 @@ bool SGSkyDome::reposition( sgVec3 p, double lon, double lat, double spin ) { sgSetCoord( &skypos, TRANSFORM ); dome_transform->setTransform( &skypos ); - +#endif return true; } diff --git a/simgear/scene/sky/dome.hxx b/simgear/scene/sky/dome.hxx index cb81a543..ecd8994c 100644 --- a/simgear/scene/sky/dome.hxx +++ b/simgear/scene/sky/dome.hxx @@ -73,6 +73,11 @@ public: bool repaint( sgVec3 sky_color, sgVec3 fog_color, double sun_angle, double vis ); + // regenerate the sky texture based on the current position and time + // + bool repaint( float lat, float lon, int zone, int julianDay, + int time, float turb, bool atmEffects = false ); + // reposition the sky at the specified origin and orientation // lon specifies a rotation about the Z axis // lat specifies a rotation about the new Y axis diff --git a/simgear/sg_zlib.h b/simgear/sg_zlib.h index 3119167b..f39d5593 100644 --- a/simgear/sg_zlib.h +++ b/simgear/sg_zlib.h @@ -35,7 +35,7 @@ #ifdef HAVE_CONFIG_H -# include +# include #endif -- 2.39.5