LCOV - code coverage report
Current view: top level - Core - TextureStore.m (source / functions) Hit Total Coverage
Test: coverxygen.info Lines: 0 14 0.0 %
Date: 2025-05-28 07:50:54 Functions: 0 0 -

          Line data    Source code
       1           0 : /*
       2             : 
       3             : TextureStore.m
       4             : 
       5             : Oolite
       6             : Copyright (C) 2004-2013 Giles C Williams and contributors
       7             : 
       8             : This program is free software; you can redistribute it and/or
       9             : modify it under the terms of the GNU General Public License
      10             : as published by the Free Software Foundation; either version 2
      11             : of the License, or (at your option) any later version.
      12             : 
      13             : This program is distributed in the hope that it will be useful,
      14             : but WITHOUT ANY WARRANTY; without even the implied warranty of
      15             : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      16             : GNU General Public License for more details.
      17             : 
      18             : You should have received a copy of the GNU General Public License
      19             : along with this program; if not, write to the Free Software
      20             : Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
      21             : MA 02110-1301, USA.
      22             : 
      23             : */
      24             : 
      25             : #import "OOCocoa.h"
      26             : #import "TextureStore.h"
      27             : #if !NEW_PLANETS
      28             : 
      29             : #import "OOMaths.h"
      30             : 
      31             : #ifndef NDEBUG
      32             : #import "Universe.h"
      33             : #import "MyOpenGLView.h"
      34             : #else
      35             : #import "OOColor.h"
      36             : #endif
      37             : 
      38             : #import "OOCollectionExtractors.h"
      39             : 
      40           0 : #define DEBUG_DUMP                      (       0       && OOLITE_DEBUG)
      41             : 
      42             : 
      43           0 : static NSString * const kOOLogPlanetTextureGen                  = @"texture.planet.generate";
      44             : 
      45             : 
      46             : #import "OOTextureGenerator.h"        // For FloatRGB
      47             : 
      48             : 
      49           0 : static FloatRGB FloatRGBFromDictColor(NSDictionary *dictionary, NSString *key)
      50             : {
      51             :         OOColor *color = [dictionary objectForKey:key];
      52             :         if (color == nil)
      53             :         {
      54             :                 // could not get a color from the dicitionary, return white color instead of hitting the assert below
      55             :                 color = [OOColor colorWithDescription:@"whiteColor"];
      56             :                 OOLog(@"textureStore.FloatRGBFromDictColor.nilColor", @"Expected color for key \"%@\" in dictionary %@, got nil. Setting color to %@", key, dictionary, [color rgbaDescription]);
      57             :         }
      58             :         NSCAssert1([color isKindOfClass:[OOColor class]], @"Expected OOColor, got %@", [color class]);
      59             :         
      60             :         return (FloatRGB){ [color redComponent], [color greenComponent], [color blueComponent] };
      61             : }
      62             : 
      63             : 
      64           0 : static FloatRGB Blend(float fraction, FloatRGB a, FloatRGB b)
      65             : {
      66             :         return (FloatRGB)
      67             :         {
      68             :                 OOLerp(a.r, b.r, fraction),
      69             :                 OOLerp(a.g, b.g, fraction),
      70             :                 OOLerp(a.b, b.b, fraction)
      71             :         };
      72             : }
      73             : 
      74             : 
      75           0 : static FloatRGB PlanetTextureColor(float q, float impress, float bias, FloatRGB seaColor, FloatRGB paleSeaColor, FloatRGB landColor, FloatRGB paleLandColor)
      76             : {
      77             :         const FloatRGB kWhite = { 1.0, 1.0, 1.0 };
      78             :         float maxq = impress + bias;
      79             :         
      80             :         float hi = 0.66667 * maxq;
      81             :         float oh = 1.0 / hi;
      82             :         float ih = 1.0 / (1.0 - hi);
      83             :         
      84             :         if (q <= 0.0)
      85             :         {
      86             :                 return seaColor;
      87             :         }
      88             :         if (q > 1.0)
      89             :         {
      90             :                 return (FloatRGB){ 1.0f, 1.0f, 1.0f };
      91             :         }
      92             :         if (q < 0.01)
      93             :         {
      94             :                 return Blend(q * 100.0f, paleSeaColor, landColor);
      95             :         }
      96             :         if (q > hi)
      97             :         {
      98             :                 return Blend((q - hi) * ih, paleLandColor, kWhite);     // snow capped peaks
      99             :         }
     100             :         
     101             :         return Blend((hi - q) * oh, paleLandColor, landColor);
     102             : }
     103             : 
     104             : 
     105             : static void fillSquareImageDataWithCloudTexture(unsigned char * imageBuffer, int width, OOColor* cloudcolor, float impress, float bias);
     106             : static void fillSquareImageWithPlanetTex(unsigned char * imageBuffer, int width, float impress, float bias, FloatRGB seaColor, FloatRGB paleSeaColor, FloatRGB landColor, FloatRGB paleLandColor);
     107             : 
     108             : 
     109             : @implementation TextureStore
     110             : 
     111             : 
     112           0 : #define PROC_TEXTURE_SIZE       512
     113             : 
     114             : + (BOOL) getPlanetTextureNameFor:(NSDictionary *)planetInfo intoData:(unsigned char **)textureData width:(GLuint *)textureWidth height:(GLuint *)textureHeight
     115             : {
     116             :         int                                     texture_h = PROC_TEXTURE_SIZE;
     117             :         int                                     texture_w = PROC_TEXTURE_SIZE;
     118             : 
     119             :         int                                     tex_bytes = texture_w * texture_h * 4;
     120             :         
     121             :         NSParameterAssert(textureData != NULL && textureWidth != NULL && textureHeight != NULL);
     122             :         
     123             :         unsigned char *imageBuffer = malloc(tex_bytes);
     124             :         if (imageBuffer == NULL)  return NO;
     125             :         
     126             :         *textureData = imageBuffer;
     127             :         *textureWidth = texture_w;
     128             :         *textureHeight = texture_h;
     129             :         
     130             :         float land_fraction = [[planetInfo objectForKey:@"land_fraction"] floatValue];
     131             :         float sea_bias = land_fraction - 1.0;
     132             :         
     133             :         OOLog(kOOLogPlanetTextureGen, @"genning texture for land_fraction %.5f", land_fraction);
     134             :         
     135             :         FloatRGB land_color = FloatRGBFromDictColor(planetInfo, @"land_color");
     136             :         FloatRGB sea_color = FloatRGBFromDictColor(planetInfo, @"sea_color");
     137             :         FloatRGB polar_land_color = FloatRGBFromDictColor(planetInfo, @"polar_land_color");
     138             :         FloatRGB polar_sea_color = FloatRGBFromDictColor(planetInfo, @"polar_sea_color");
     139             :         
     140             :         // Pale sea colour gives a better transition between land and sea., Backported from the new planets code.
     141             :         FloatRGB pale_sea_color = Blend(0.45, polar_sea_color, Blend(0.7, sea_color, land_color));
     142             :         
     143             :         fillSquareImageWithPlanetTex(imageBuffer, texture_w, 1.0, sea_bias,
     144             :                 sea_color,
     145             :                 pale_sea_color,
     146             :                 land_color,
     147             :                 polar_land_color);
     148             :         
     149             :         return YES;
     150             : }
     151             : 
     152             : 
     153             : + (BOOL) getCloudTextureNameFor:(OOColor*)color :(GLfloat)impress :(GLfloat)bias intoData:(unsigned char **)textureData width:(GLuint *)textureWidth height:(GLuint *)textureHeight
     154             : {
     155             :         int                                     texture_h = PROC_TEXTURE_SIZE;
     156             :         int                                     texture_w = PROC_TEXTURE_SIZE;
     157             :         int                                     tex_bytes;
     158             :         
     159             :         tex_bytes = texture_w * texture_h * 4;
     160             :         
     161             :         NSParameterAssert(textureData != NULL && textureWidth != NULL && textureHeight != NULL);
     162             :         
     163             :         unsigned char *imageBuffer = malloc(tex_bytes);
     164             :         if (imageBuffer == NULL)  return NO;
     165             :         
     166             :         *textureData = imageBuffer;
     167             :         *textureWidth = texture_w;
     168             :         *textureHeight = texture_h;
     169             :         
     170             :         fillSquareImageDataWithCloudTexture( imageBuffer, texture_w, color, impress, bias);
     171             :         
     172             :         return YES;
     173             : }
     174             : 
     175             : @end
     176             : 
     177             : 
     178           0 : static RANROTSeed sNoiseSeed;
     179           0 : static float ranNoiseBuffer[128 * 128];
     180             : 
     181           0 : void fillRanNoiseBuffer()
     182             : {
     183             :         sNoiseSeed = RANROTGetFullSeed();
     184             :         
     185             :         int i;
     186             :         for (i = 0; i < 16384; i++)
     187             :                 ranNoiseBuffer[i] = randf();
     188             : }
     189             : 
     190             : 
     191           0 : static void addNoise(float * buffer, int p, int n, float scale)
     192             : {
     193             :         int x, y;
     194             :         
     195             :         float r = (float)p / (float)n;
     196             :         for (y = 0; y < p; y++) for (x = 0; x < p; x++)
     197             :         {
     198             :                 int ix = floor( (float)x / r);
     199             :                 int jx = (ix + 1) % n;
     200             :                 int iy = floor( (float)y / r);
     201             :                 int jy = (iy + 1) % n;
     202             :                 float qx = x / r - ix;
     203             :                 float qy = y / r - iy;
     204             :                 ix &= 127;
     205             :                 iy &= 127;
     206             :                 jx &= 127;
     207             :                 jy &= 127;
     208             :                 float rix = OOLerp(ranNoiseBuffer[iy * 128 + ix], ranNoiseBuffer[iy * 128 + jx], qx);
     209             :                 float rjx = OOLerp(ranNoiseBuffer[jy * 128 + ix], ranNoiseBuffer[jy * 128 + jx], qx);
     210             :                 float rfinal = scale * OOLerp(rix, rjx, qy);
     211             :                 
     212             :                 buffer[y * p + x] += rfinal;
     213             :         }
     214             : }
     215             : 
     216             : 
     217           0 : static float q_factor(float* accbuffer, int x, int y, int width, BOOL polar_y_smooth, float polar_y_value, BOOL polar_x_smooth, float polar_x_value, float impress, float bias)
     218             : {
     219             :         while ( x < 0 ) x+= width;
     220             :         while ( y < 0 ) y+= width;
     221             :         while ( x >= width ) x-= width;
     222             :         while ( y >= width ) y-= width;
     223             : 
     224             :         float q = accbuffer[ y * width + x];    // 0.0 -> 1.0
     225             : 
     226             :         q *= impress;   // impress
     227             :         q += bias;              // + bias
     228             : 
     229             :         float polar_y = (2.0f * y - width) / (float) width;
     230             :         float polar_x = (2.0f * x - width) / (float) width;
     231             :         
     232             :         polar_x *= polar_x;
     233             :         polar_y *= polar_y;
     234             :         
     235             :         if (polar_x_smooth)
     236             :                 q = q * (1.0 - polar_x) + polar_x * polar_x_value;
     237             :         if (polar_y_smooth)
     238             :                 q = q * (1.0 - polar_y) + polar_y * polar_y_value;
     239             : 
     240             :         if (q > 1.0) q = 1.0;
     241             :         if (q < 0.0) q = 0.0;
     242             :         
     243             :         return q;
     244             : }
     245             : 
     246             : 
     247           0 : static void fillSquareImageDataWithCloudTexture(unsigned char * imageBuffer, int width, OOColor* cloudcolor, float impress, float bias)
     248             : {
     249             :         NSCParameterAssert(width > 0);
     250             :         
     251             :         float accbuffer[width * width];
     252             :         memset(accbuffer, 0, sizeof accbuffer);
     253             :         int x, y;
     254             : 
     255             :         GLfloat rgba[4];
     256             :         rgba[0] = [cloudcolor redComponent];
     257             :         rgba[1] = [cloudcolor greenComponent];
     258             :         rgba[2] = [cloudcolor blueComponent];
     259             :         rgba[3] = [cloudcolor alphaComponent];
     260             : 
     261             :         int octave = 8;
     262             :         float scale = 0.5;
     263             :         while (octave < width)
     264             :         {
     265             :                 addNoise(accbuffer, width, octave, scale);
     266             :                 octave *= 2;
     267             :                 scale *= 0.5;
     268             :         }
     269             :         
     270             :         float pole_value = (impress * accbuffer[0] - bias < 0.0)? 0.0: 1.0;
     271             :         
     272             :         for (y = 0; y < width; y++) for (x = 0; x < width; x++)
     273             :         {
     274             :                 float q = q_factor(accbuffer, x, y, width, YES, pole_value, NO, 0.0, impress, bias);
     275             :                 
     276             :                 imageBuffer[0 + 4 * (y * width + x) ] = 255 * rgba[0];
     277             :                 imageBuffer[1 + 4 * (y * width + x) ] = 255 * rgba[1];
     278             :                 imageBuffer[2 + 4 * (y * width + x) ] = 255 * rgba[2];
     279             :                 imageBuffer[3 + 4 * (y * width + x) ] = 255 * rgba[3] * q;
     280             :         }
     281             : #if DEBUG_DUMP
     282             :         NSString *name = [NSString stringWithFormat:@"atmosphere-%u-%u-old", sNoiseSeed.high, sNoiseSeed.low];
     283             :         OOLog(@"planetTex.dump", [NSString stringWithFormat:@"Saving generated texture to file %@.", name]);
     284             :         
     285             :         [[UNIVERSE gameView] dumpRGBAToFileNamed:name
     286             :                                                                            bytes:imageBuffer
     287             :                                                                            width:width
     288             :                                                                           height:width
     289             :                                                                         rowBytes:width * 4];
     290             : #endif
     291             : }
     292             : 
     293           0 : static void fillSquareImageWithPlanetTex(unsigned char * imageBuffer, int width, float impress, float bias,
     294             :         FloatRGB seaColor,
     295             :         FloatRGB paleSeaColor,
     296             :         FloatRGB landColor,
     297             :         FloatRGB paleLandColor)
     298             : {
     299             :         float accbuffer[width * width];
     300             :         memset(accbuffer, 0, sizeof accbuffer);
     301             :         
     302             :         int octave = 8;
     303             :         float scale = 0.5;
     304             :         while (octave < width)
     305             :         {
     306             :                 addNoise(accbuffer, width, octave, scale);
     307             :                 octave *= 2;
     308             :                 scale *= 0.5;
     309             :         }
     310             :         
     311             :         float pole_value = (impress + bias > 0.5)? 0.5 * (impress + bias) : 0.0;
     312             :         
     313             :         int x, y;
     314             :         for (y = 0; y < width; y++) for (x = 0; x < width; x++)
     315             :         {
     316             :                 float q = q_factor(accbuffer, x, y, width, YES, pole_value, NO, 0.0, impress, bias);
     317             : 
     318             :                 float yN = q_factor(accbuffer, x, y - 1, width, YES, pole_value, NO, 0.0, impress, bias);
     319             :                 float yS = q_factor(accbuffer, x, y + 1, width, YES, pole_value, NO, 0.0, impress, bias);
     320             :                 float yW = q_factor(accbuffer, x - 1, y, width, YES, pole_value, NO, 0.0, impress, bias);
     321             :                 float yE = q_factor(accbuffer, x + 1, y, width, YES, pole_value, NO, 0.0, impress, bias);
     322             : 
     323             :                 Vector norm = make_vector( 24.0 * (yW - yE), 24.0 * (yS - yN), 2.0);
     324             :                 
     325             :                 norm = vector_normal(norm);
     326             :                 
     327             :                 GLfloat shade = pow(norm.z, 3.2);
     328             :                 
     329             :                 FloatRGB color = PlanetTextureColor(q, impress, bias, seaColor, paleSeaColor, landColor, paleLandColor);
     330             :                 
     331             :                 color.r *= shade;
     332             :                 color.g *= shade;
     333             :                 color.b *= shade;
     334             :                 
     335             :                 imageBuffer[0 + 4 * (y * width + x)] = 255 * color.r;
     336             :                 imageBuffer[1 + 4 * (y * width + x)] = 255 * color.g;
     337             :                 imageBuffer[2 + 4 * (y * width + x)] = 255 * color.b;
     338             :                 imageBuffer[3 + 4 * (y * width + x)] = 255;
     339             :         }
     340             : #if DEBUG_DUMP
     341             :         OOLog(@"planetTex.dump", [NSString stringWithFormat:@"Saving generated texture to file planet-%u-%u-old.", sNoiseSeed.high, sNoiseSeed.low]);
     342             :         
     343             :         [[UNIVERSE gameView] dumpRGBAToFileNamed:[NSString stringWithFormat:@"planet-%u-%u-old", sNoiseSeed.high, sNoiseSeed.low]
     344             :                                                                            bytes:imageBuffer
     345             :                                                                            width:width
     346             :                                                                           height:width
     347             :                                                                         rowBytes:width * 4];
     348             : #endif
     349             : }
     350             : 
     351             : #endif  // !NEW_PLANETS

Generated by: LCOV version 1.14