41#define SKY_ELEMENT_SCALE_FACTOR (BILLBOARD_DEPTH / 500.0f)
42#define NEBULA_SHUFFLE_FACTOR 0.005f
86+ (void)addQuads:(
OOSkyQuadDesc *)quads count:(
unsigned)count toArray:(NSMutableArray *)ioArray;
88- (id)initWithQuadsWithTexture:(
OOTexture *)texture inArray:(
OOSkyQuadDesc *)array count:(
unsigned)totalCount;
110@interface OOSkyDrawable (OOPrivate) <OOGraphicsResetClient>
112- (void)setUpStarsWithColor1:(
OOColor *)color1 color2:(
OOColor *)color2;
113- (void)setUpNebulaeWithColor1:(
OOColor *)color1
115 clusterFactor:(
float)nebulaClusterFactor
116 nebulaHueFix:(BOOL)nebulaHueFix
117 alpha:(
float)nebulaAlpha
118 scale:(
float)nebulaScale;
124- (void)addQuads:(
OOSkyQuadDesc *)quads count:(
unsigned)count;
133- (id)initWithColor1:(
OOColor *)color1
137 starCount:(
unsigned)starCount
138 nebulaCount:(
unsigned)nebulaCount
139 nebulaHueFix:(BOOL)nebulaHueFix
140 clusterFactor:(
float)nebulaClusterFactor
141 alpha:(
float)nebulaAlpha
142 scale:(
float)nebulaScale
144 NSAutoreleasePool *pool =
nil;
149 if ([[NSUserDefaults standardUserDefaults] boolForKey:
@"sky-render-inset-coords"])
157 if (
self ==
nil)
return nil;
159 _starCount = starCount;
160 _nebulaCount = nebulaCount;
162 pool = [[NSAutoreleasePool alloc] init];
188 if (_displayListName != 0) glDeleteLists(_displayListName, 1);
194- (void)renderOpaqueParts
202 OOGL(glDisable(GL_DEPTH_TEST));
203 OOGL(glEnable(GL_TEXTURE_2D));
206 GLfloat fogColor[4] = {0.02, 0.02, 0.02, 1.0};
207 OOGL(glFogfv(GL_FOG_COLOR, fogColor));
209 if (_displayListName != 0)
211 OOGL(glCallList(_displayListName));
216 [
self ensureTexturesLoaded];
217 _displayListName = glGenLists(1);
219 OOGL(glNewList(_displayListName, GL_COMPILE));
221 OOGL(glEnableClientState(GL_TEXTURE_COORD_ARRAY));
222 OOGL(glEnableClientState(GL_COLOR_ARRAY));
224 [_quadSets makeObjectsPerformSelector:@selector(render)];
226 OOGL(glDisableClientState(GL_TEXTURE_COORD_ARRAY));
227 OOGL(glDisableClientState(GL_COLOR_ARRAY));
233 OOGL(glEnable(GL_DEPTH_TEST));
234 OOGL(glDisable(GL_TEXTURE_2D));
243- (BOOL)hasOpaqueParts
249- (GLfloat)maxDrawDistance
255- (NSSet *) allTextures
257 NSMutableSet *result = [NSMutableSet setWithCapacity:[_quadSets count]];
260 foreach (quadSet, _quadSets)
262 [result addObject:[quadSet
texture]];
271 size_t result = [
super totalSize];
274 foreach (quadSet, _quadSets)
276 result += [quadSet totalSize];
287static OOColor *DebugColor(Vector orientation)
289 Vector color = vector_add(make_vector(0.55, 0.55, 0.55), vector_multiply_scalar(vector_normal(orientation), 0.45));
290 return [
OOColor colorWithCalibratedRed:color.x green:color.y blue:color.z alpha:1.0];
295@implementation OOSkyDrawable (OOPrivate)
297- (void)setUpStarsWithColor1:(
OOColor *)color1 color2:(
OOColor *)color2
306 [
self loadStarTextures];
308 quads = malloc(
sizeof *quads * _starCount);
309 if (quads == NULL)
return;
312 for (i = 0; i != _starCount; ++i)
315 q = OORandomQuaternion();
320 currQuad->color = DebugColor(vk);
329 offset = vector_multiply_scalar(vector_add(vi, vj), 0.5f *
size);
332 Vector vj2 = vector_multiply_scalar(vj,
size);
333 Vector vi2 = vector_multiply_scalar(vi,
size);
336 currQuad->corners[0] = vector_subtract(middle,
offset);
337 currQuad->corners[1] = vector_add(currQuad->corners[0], vj2);
338 currQuad->corners[2] = vector_add(currQuad->corners[1], vi2);
339 currQuad->corners[3] = vector_add(currQuad->corners[0], vi2);
344 [
self addQuads:quads count:_starCount];
349- (void)setUpNebulaeWithColor1:(
OOColor *)color1
351 clusterFactor:(
float)nebulaClusterFactor
352 nebulaHueFix:(BOOL)nebulaHueFix
353 alpha:(
float)nebulaAlpha
354 scale:(
float)nebulaScale
357 unsigned i, actualCount = 0;
365 [
self loadNebulaTextures];
367 quads = malloc(
sizeof *quads * _nebulaCount);
368 if (quads == NULL)
return;
371 for (i = 0; i < _nebulaCount; ++i)
376 q = OORandomQuaternion();
379 while ((i < _nebulaCount) && (
randf() < nebulaClusterFactor))
390 currQuad->color = DebugColor(vk);
397 offset = vector_multiply_scalar(vector_add(vi, vj), 0.5f *
size);
406 vj = vector_multiply_scalar(vj,
size);
407 vi = vector_multiply_scalar(vi,
size);
410 currQuad->corners[0] = vector_subtract(middle,
offset);
411 currQuad->corners[1] = vector_add(currQuad->corners[0], vj);
412 currQuad->corners[2] = vector_add(currQuad->corners[1], vi);
413 currQuad->corners[3] = vector_add(currQuad->corners[0], vi);
421 quaternion_normalize(&q);
434 _nebulaCount = actualCount;
436 [
self addQuads:quads count:_nebulaCount];
443 if (_quadSets ==
nil) _quadSets = [[NSMutableArray alloc] init];
454 initWithPListName:@"startextures.plist"
455 options:kOOTextureMinFilterMipMap | kOOTextureMagFilterLinear | kOOTextureAlphaMask
460 [NSException raise:OOLITE_EXCEPTION_DATA_NOT_FOUND format:@"No star textures could be loaded."];
464 [sStarTextures
setSeed:RANROTGetFullSeed()];
474 initWithPListName:@"nebulatextures.plist"
475 options:kOOTextureDefaultOptions | kOOTextureAlphaMask
480 [NSException raise:OOLITE_EXCEPTION_DATA_NOT_FOUND format:@"No nebula textures could be loaded."];
484 [sNebulaTextures
setSeed:RANROTGetFullSeed()];
500 if (_displayListName != 0)
502 glDeleteLists(_displayListName, 1);
503 _displayListName = 0;
512+ (void)addQuads:(
OOSkyQuadDesc *)quads count:(
unsigned)count toArray:(NSMutableArray *)ioArray
514 NSMutableSet *seenTextures =
nil;
520 seenTextures = [NSMutableSet set];
521 for (i = 0; i !=
count; ++i)
526 if (![seenTextures containsObject:texture])
528 [seenTextures addObject:texture];
531 quadSet = [[
self alloc] initWithQuadsWithTexture:texture
536 [ioArray addObject:quadSet];
544- (id)initWithQuadsWithTexture:(
OOTexture *)texture inArray:(
OOSkyQuadDesc *)array count:(
unsigned)totalCount
547 unsigned i, j, vertexCount;
552 size_t posSize, tcSize, colSize;
554 int skyColorCorrection = [[NSUserDefaults standardUserDefaults] oo_integerForKey:@"sky-color-correction" defaultValue:0];
558#define SKYCOLOR_TONEMAP_COMPONENT(skyColorComponent) \
560 x = MAX(0.0, skyColorComponent - 0.004); \
561 *col++ = (x * (6.2 * x + 0.5)) / (x * (6.2 * x + 1.7) + 0.06); \
565 if (
self ==
nil) OK = NO;
570 for (i = 0; i != totalCount; ++i)
572 if (array[i].texture == texture) ++_count;
574 if (_count == 0) OK = NO;
580 vertexCount = _count * 4;
585 _positions = malloc(posSize);
586 _texCoords = malloc(tcSize);
587 _colors = malloc(colSize);
589 if (_positions == NULL || _texCoords == NULL || _colors == NULL) OK = NO;
599 for (i = 0; i != totalCount; ++i)
601 if (array[i].texture == texture)
603 r = [array[i].color redComponent];
604 g = [array[i].color greenComponent];
605 b = [array[i].color blueComponent];
608 for (j = 0; j != 4; ++j)
610 *pos++ = array[i].corners[j].
x;
611 *pos++ = array[i].corners[j].
y;
612 *pos++ = array[i].corners[j].z;
615 if (skyColorCorrection == 0)
621 else if (skyColorCorrection == 1)
623 *col++ = pow(r, 1.0/2.2);
624 *col++ = pow(g, 1.0/2.2);
625 *col++ = pow(b, 1.0/2.2);
653 _texture = [texture
retain];
654 OOLog(
@"sky.setup",
@"Generated quadset with %u quads for texture %@",
count, _texture);
671 if (_positions != NULL) free(_positions);
672 if (_texCoords != NULL) free(_texCoords);
673 if (_colors != NULL) free(_colors);
679- (NSString *)description
681 return [NSString stringWithFormat:@"<%@ %p>{%u quads, texture: %@}", [
self class], self, _count, _texture];
695 OOGL(glDrawArrays(GL_QUADS, 0, 4 * _count));
702 return [
self oo_objectSize] + _count * 4 * (sizeof *_positions + sizeof *_texCoords + sizeof *_colors);
718 float hue, saturation, brightness, alpha;
723 saturation = 0.5 * saturation + 0.5;
#define OOLog(class, format,...)
#define OO_ENTER_OPENGL()
@ OPENGL_STATE_ADDITIVE_BLENDING
#define OOVerifyOpenGLState()
BOOL OOCheckOpenGLErrors(NSString *format,...)
#define OOSetOpenGLState(STATE)
Vector vector_up_from_quaternion(Quaternion quat)
Vector vector_right_from_quaternion(Quaternion quat)
void basis_vectors_from_quaternion(Quaternion quat, Vector *outRight, Vector *outUp, Vector *outForward)
void quaternion_rotate_about_axis(Quaternion *quat, Vector axis, OOScalar angle)
static float sMaxTexCoord
#define SKY_ELEMENT_SCALE_FACTOR
static float sMinTexCoord
static OOProbabilisticTextureManager * sNebulaTextures
#define NEBULA_SHUFFLE_FACTOR
#define SKYCOLOR_TONEMAP_COMPONENT(skyColorComponent)
static OOProbabilisticTextureManager * sStarTextures
static OOColor * SaturatedColorInRange(OOColor *color1, OOColor *color2, BOOL hueFix)
@ kSkyQuadSetTexCoordEntriesPerVertex
@ kSkyQuadSetPositionEntriesPerVertex
@ kSkyQuadSetColorEntriesPerVertex
void resetGraphicsState()
void loadNebulaTextures()
void ensureTexturesLoaded()
void getHue:saturation:brightness:alpha:(float *hue,[saturation] float *saturation,[brightness] float *brightness,[alpha] float *alpha)
OOColor * colorWithBrightnessFactor:(float factor)
OOColor * colorWithHue:saturation:brightness:alpha:(float hue,[saturation] float saturation,[brightness] float brightness,[alpha] float alpha)
OOColor * blendedColorWithFraction:ofColor:(float fraction,[ofColor] OOColor *color)
void registerClient:(id< OOGraphicsResetClient > client)
void unregisterClient:(id< OOGraphicsResetClient > client)
OOGraphicsResetManager * sharedManager()
void ensureTexturesLoaded()
void setSeed:(RANROTSeed seed)
OOTexture * selectTexture()
void setUpStarsWithColor1:color2:(OOColor *color1,[color2] OOColor *color2)
void setUpNebulaeWithColor1:color2:clusterFactor:nebulaHueFix:alpha:scale:(OOColor *color1,[color2] OOColor *color2,[clusterFactor] float nebulaClusterFactor,[nebulaHueFix] BOOL nebulaHueFix,[alpha] float nebulaAlpha,[scale] float nebulaScale)
void addQuads:count:toArray:(OOSkyQuadDesc *quads,[count] unsigned count,[toArray] NSMutableArray *ioArray)