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]];
259 NSEnumerator *quadSetEnum =
nil;
261 for (quadSetEnum = [_quadSets objectEnumerator]; (quadSet = [quadSetEnum nextObject]); )
263 [result addObject:[quadSet
texture]];
272 size_t result = [
super totalSize];
274 NSEnumerator *quadSetEnum =
nil;
276 for (quadSetEnum = [_quadSets objectEnumerator]; (quadSet = [quadSetEnum nextObject]); )
278 result += [quadSet totalSize];
289static OOColor *DebugColor(Vector orientation)
291 Vector color = vector_add(make_vector(0.55, 0.55, 0.55), vector_multiply_scalar(vector_normal(orientation), 0.45));
292 return [
OOColor colorWithCalibratedRed:color.x green:color.y blue:color.z alpha:1.0];
297@implementation OOSkyDrawable (OOPrivate)
299- (void)setUpStarsWithColor1:(
OOColor *)color1 color2:(
OOColor *)color2
308 [
self loadStarTextures];
310 quads = malloc(
sizeof *quads * _starCount);
311 if (quads == NULL)
return;
314 for (i = 0; i != _starCount; ++i)
317 q = OORandomQuaternion();
322 currQuad->color = DebugColor(vk);
331 offset = vector_multiply_scalar(vector_add(vi, vj), 0.5f *
size);
334 Vector vj2 = vector_multiply_scalar(vj,
size);
335 Vector vi2 = vector_multiply_scalar(vi,
size);
338 currQuad->corners[0] = vector_subtract(middle,
offset);
339 currQuad->corners[1] = vector_add(currQuad->corners[0], vj2);
340 currQuad->corners[2] = vector_add(currQuad->corners[1], vi2);
341 currQuad->corners[3] = vector_add(currQuad->corners[0], vi2);
346 [
self addQuads:quads count:_starCount];
351- (void)setUpNebulaeWithColor1:(
OOColor *)color1
353 clusterFactor:(
float)nebulaClusterFactor
354 nebulaHueFix:(BOOL)nebulaHueFix
355 alpha:(
float)nebulaAlpha
356 scale:(
float)nebulaScale
359 unsigned i, actualCount = 0, clusters = 0;
367 [
self loadNebulaTextures];
369 quads = malloc(
sizeof *quads * _nebulaCount);
370 if (quads == NULL)
return;
373 for (i = 0; i < _nebulaCount; ++i)
378 q = OORandomQuaternion();
381 while ((i < _nebulaCount) && (
randf() < nebulaClusterFactor))
392 currQuad->color = DebugColor(vk);
399 offset = vector_multiply_scalar(vector_add(vi, vj), 0.5f *
size);
408 vj = vector_multiply_scalar(vj,
size);
409 vi = vector_multiply_scalar(vi,
size);
412 currQuad->corners[0] = vector_subtract(middle,
offset);
413 currQuad->corners[1] = vector_add(currQuad->corners[0], vj);
414 currQuad->corners[2] = vector_add(currQuad->corners[1], vi);
415 currQuad->corners[3] = vector_add(currQuad->corners[0], vi);
423 quaternion_normalize(&q);
437 _nebulaCount = actualCount;
439 [
self addQuads:quads count:_nebulaCount];
446 if (_quadSets ==
nil) _quadSets = [[NSMutableArray alloc] init];
457 initWithPListName:@"startextures.plist"
458 options:kOOTextureMinFilterMipMap | kOOTextureMagFilterLinear | kOOTextureAlphaMask
463 [NSException raise:OOLITE_EXCEPTION_DATA_NOT_FOUND format:@"No star textures could be loaded."];
467 [sStarTextures
setSeed:RANROTGetFullSeed()];
477 initWithPListName:@"nebulatextures.plist"
478 options:kOOTextureDefaultOptions | kOOTextureAlphaMask
483 [NSException raise:OOLITE_EXCEPTION_DATA_NOT_FOUND format:@"No nebula textures could be loaded."];
487 [sNebulaTextures
setSeed:RANROTGetFullSeed()];
503 if (_displayListName != 0)
505 glDeleteLists(_displayListName, 1);
506 _displayListName = 0;
515+ (void)addQuads:(
OOSkyQuadDesc *)quads count:(
unsigned)count toArray:(NSMutableArray *)ioArray
517 NSMutableSet *seenTextures =
nil;
523 seenTextures = [NSMutableSet set];
524 for (i = 0; i !=
count; ++i)
529 if (![seenTextures containsObject:texture])
531 [seenTextures addObject:texture];
534 quadSet = [[
self alloc] initWithQuadsWithTexture:texture
539 [ioArray addObject:quadSet];
547- (id)initWithQuadsWithTexture:(
OOTexture *)texture inArray:(
OOSkyQuadDesc *)array count:(
unsigned)totalCount
550 unsigned i, j, vertexCount;
555 size_t posSize, tcSize, colSize;
557 int skyColorCorrection = [[NSUserDefaults standardUserDefaults] oo_integerForKey:@"sky-color-correction" defaultValue:0];
561#define SKYCOLOR_TONEMAP_COMPONENT(skyColorComponent) \
563 x = MAX(0.0, skyColorComponent - 0.004); \
564 *col++ = (x * (6.2 * x + 0.5)) / (x * (6.2 * x + 1.7) + 0.06); \
568 if (
self ==
nil) OK = NO;
573 for (i = 0; i != totalCount; ++i)
575 if (array[i].texture == texture) ++_count;
577 if (_count == 0) OK = NO;
583 vertexCount = _count * 4;
588 _positions = malloc(posSize);
589 _texCoords = malloc(tcSize);
590 _colors = malloc(colSize);
592 if (_positions == NULL || _texCoords == NULL || _colors == NULL) OK = NO;
602 for (i = 0; i != totalCount; ++i)
604 if (array[i].texture == texture)
606 r = [array[i].color redComponent];
607 g = [array[i].color greenComponent];
608 b = [array[i].color blueComponent];
611 for (j = 0; j != 4; ++j)
613 *pos++ = array[i].corners[j].
x;
614 *pos++ = array[i].corners[j].
y;
615 *pos++ = array[i].corners[j].z;
618 if (skyColorCorrection == 0)
624 else if (skyColorCorrection == 1)
626 *col++ = pow(r, 1.0/2.2);
627 *col++ = pow(g, 1.0/2.2);
628 *col++ = pow(b, 1.0/2.2);
656 _texture = [texture
retain];
657 OOLog(
@"sky.setup",
@"Generated quadset with %u quads for texture %@",
count, _texture);
674 if (_positions != NULL) free(_positions);
675 if (_texCoords != NULL) free(_texCoords);
676 if (_colors != NULL) free(_colors);
682- (NSString *)description
684 return [NSString stringWithFormat:@"<%@ %p>{%u quads, texture: %@}", [
self class], self, _count, _texture];
698 OOGL(glDrawArrays(GL_QUADS, 0, 4 * _count));
705 return [
self oo_objectSize] + _count * 4 * (sizeof *_positions + sizeof *_texCoords + sizeof *_colors);
721 float hue, saturation, brightness, alpha;
726 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)
struct OOSkyQuadDesc OOSkyQuadDesc
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)