]> git.mxchange.org Git - simgear.git/commitdiff
Add out own texture object
authorehofman <ehofman>
Wed, 9 Apr 2003 20:24:52 +0000 (20:24 +0000)
committerehofman <ehofman>
Wed, 9 Apr 2003 20:24:52 +0000 (20:24 +0000)
configure.ac
simgear/misc/Makefile.am
simgear/misc/colours.h [new file with mode: 0644]
simgear/misc/texture.cxx [new file with mode: 0644]
simgear/misc/texture.hxx [new file with mode: 0644]
simgear/scene/sky/Makefile.am
simgear/scene/sky/dome.cxx
simgear/scene/sky/dome.hxx
simgear/sg_zlib.h

index 7d0e53540979a431b005ca78824804b17a43dc0b..c7342f1d7d4795437d3e030fc5194d8cb1a5b6cf 100644 (file)
@@ -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 \
index d691930dc1906d827a3787fc0be10d19d9580b81..d961b03c45eb77c6b1a947a392b35ecf5b70daa5 100644 (file)
@@ -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 (file)
index 0000000..ba3b891
--- /dev/null
@@ -0,0 +1,289 @@
+// colours.h -- This header file contains colour definitions in the
+//              same way as MS FS5 does
+//
+// Contributed by "Christian Mayer" <Vader@t-online.de>, 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 (file)
index 0000000..0d2328e
--- /dev/null
@@ -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 <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);
+    }
+}
+
diff --git a/simgear/misc/texture.hxx b/simgear/misc/texture.hxx
new file mode 100644 (file)
index 0000000..ef739a9
--- /dev/null
@@ -0,0 +1,80 @@
+
+#ifndef __SG_TEXTURE_HXX
+#define __SG_TEXTURE_HXX 1
+
+#include <GL/gl.h>
+
+#include <simgear/sg_zlib.h>
+
+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
+
index c2364339ea7eb581a0a3176f711053de24ae6d06..929689ee3665f87c3258a254dc7b4d478c2fcbd8 100644 (file)
@@ -1,6 +1,7 @@
 includedir = @includedir@/sky
 
-# SUBDIRS = clouds3d
+SUBDIRS = sunsky
+# SUBDIRS += clouds3d
 
 lib_LIBRARIES = libsgsky.a
 
index 17fc03f4225ced7e6b508c7e519f8433d20baff3..e6535091d5aa73e23a71ad154477eda3b5b508a7 100644 (file)
@@ -38,6 +38,7 @@
 #include <plib/sg.h>
 
 #include <simgear/debug/logstream.hxx>
+#include <simgear/sky/sunsky/sunsky.hxx>
 
 #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;
 }
index cb81a543926df92ceac4e15635a18a348c5c9781..ecd8994c12b99eb2175364b15dcecaa6c71c75c3 100644 (file)
@@ -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
index 3119167b23b9e2cafb7a2ae9ea3ef221f3479a5d..f39d5593ed8028444e94cbf07962f7cc810bf5ae 100644 (file)
@@ -35,7 +35,7 @@
 
 
 #ifdef HAVE_CONFIG_H
-#  include <config.h>
+#  include <simgear_config.h>
 #endif