Oolite
Loading...
Searching...
No Matches
OOSkyDrawable.m
Go to the documentation of this file.
1/*
2
3OOSkyDrawable.m
4
5
6Copyright (C) 2007-2013 Jens Ayton
7
8Permission is hereby granted, free of charge, to any person obtaining a copy
9of this software and associated documentation files (the "Software"), to deal
10in the Software without restriction, including without limitation the rights
11to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12copies of the Software, and to permit persons to whom the Software is
13furnished to do so, subject to the following conditions:
14
15The above copyright notice and this permission notice shall be included in all
16copies or substantial portions of the Software.
17
18THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24SOFTWARE.
25
26*/
27
28#import "OOSkyDrawable.h"
29#import "ResourceManager.h"
30#import "OOTexture.h"
31#import "GameController.h"
32#import "OOColor.h"
35#import "Universe.h"
36#import "OOMacroOpenGL.h"
39
40
41#define SKY_ELEMENT_SCALE_FACTOR (BILLBOARD_DEPTH / 500.0f)
42#define NEBULA_SHUFFLE_FACTOR 0.005f
43#define DEBUG_COLORS 0 // If set, rgb = xyz (offset to range from 0.1 to 1.0).
44
45
46/* Min and max coords are 0 and 1 normally, but the default
47 sky-render-inset-coords can be used to modify them slightly as an attempted
48 work-around for artefacts on buggy S3/Via renderers.
49*/
50static float sMinTexCoord = 0.0f, sMaxTexCoord = 1.0f;
51static BOOL sInited = NO;
52
53
54/* Struct used to describe quads initially. This form is optimized for
55 reasoning about.
56*/
63
64
65enum
66{
70};
71
72
73/* Class containing a set of quads with the same texture. This form is
74 optimized for rendering.
75*/
76@interface OOSkyQuadSet: NSObject
77{
78@private
80 unsigned _count;
81 GLfloat *_positions; // 3 entries per vertex, 12 per quad
82 GLfloat *_texCoords; // 2 entries per vertex, 8 per quad
83 GLfloat *_colors; // 4 entries per vertex, 16 per quad
84}
85
86+ (void)addQuads:(OOSkyQuadDesc *)quads count:(unsigned)count toArray:(NSMutableArray *)ioArray;
87
88- (id)initWithQuadsWithTexture:(OOTexture *)texture inArray:(OOSkyQuadDesc *)array count:(unsigned)totalCount;
89
90- (void)render;
91
92#ifndef NDEBUG
93- (size_t) totalSize;
94- (OOTexture *) texture;
95#endif
96
97@end
98
99
100/* Textures are global because there is always a sky, but the sky isn't
101 replaced very often, so the textures are likely to fall out of the cache.
102*/
105
106
107static OOColor *SaturatedColorInRange(OOColor *color1, OOColor *color2, BOOL hueFix);
108
109
110@interface OOSkyDrawable (OOPrivate) <OOGraphicsResetClient>
111
112- (void)setUpStarsWithColor1:(OOColor *)color1 color2:(OOColor *)color2;
113- (void)setUpNebulaeWithColor1:(OOColor *)color1
114 color2:(OOColor *)color2
115 clusterFactor:(float)nebulaClusterFactor
116 nebulaHueFix:(BOOL)nebulaHueFix
117 alpha:(float)nebulaAlpha
118 scale:(float)nebulaScale;
119
120
121- (void)loadStarTextures;
122- (void)loadNebulaTextures;
123
124- (void)addQuads:(OOSkyQuadDesc *)quads count:(unsigned)count;
125
127
128@end
129
130
131@implementation OOSkyDrawable
132
133- (id)initWithColor1:(OOColor *)color1
134 Color2:(OOColor *)color2
135 Color3:(OOColor *)color3
136 Color4:(OOColor *)color4
137 starCount:(unsigned)starCount
138 nebulaCount:(unsigned)nebulaCount
139 nebulaHueFix:(BOOL)nebulaHueFix
140 clusterFactor:(float)nebulaClusterFactor
141 alpha:(float)nebulaAlpha
142 scale:(float)nebulaScale
143{
144 NSAutoreleasePool *pool = nil;
145
146 if (!sInited)
147 {
148 sInited = YES;
149 if ([[NSUserDefaults standardUserDefaults] boolForKey:@"sky-render-inset-coords"])
150 {
151 sMinTexCoord += 1.0f/128.0f;
152 sMaxTexCoord -= 1.0f/128.0f;
153 }
154 }
155
156 self = [super init];
157 if (self == nil) return nil;
158
159 _starCount = starCount;
160 _nebulaCount = nebulaCount;
161
162 pool = [[NSAutoreleasePool alloc] init];
163 [self setUpStarsWithColor1:color1 color2:color2];
164
165 if (![UNIVERSE reducedDetail])
166 {
167 [self setUpNebulaeWithColor1:color3
168 color2:color4
169 clusterFactor:nebulaClusterFactor
170 nebulaHueFix:nebulaHueFix
171 alpha:nebulaAlpha
172 scale:nebulaScale];
173 }
174 [pool release];
175
177
178 return self;
179}
180
181
182- (void)dealloc
183{
185
186 [_quadSets release];
188 if (_displayListName != 0) glDeleteLists(_displayListName, 1);
189
190 [super dealloc];
191}
192
193
194- (void)renderOpaqueParts
195{
196 // While technically translucent, the sky doesn't need to be depth-sorted
197 // since it'll be behind everything else anyway.
198
201
202 OOGL(glDisable(GL_DEPTH_TEST)); // don't read the depth buffer
203 OOGL(glEnable(GL_TEXTURE_2D));
204
205 // Make stars dim in atmosphere. Note: works OK on night side because sky is dark blue, not black.
206 GLfloat fogColor[4] = {0.02, 0.02, 0.02, 1.0};
207 OOGL(glFogfv(GL_FOG_COLOR, fogColor));
208
209 if (_displayListName != 0)
210 {
211 OOGL(glCallList(_displayListName));
212 }
213 else
214 {
215 // Set up display list
216 [self ensureTexturesLoaded];
217 _displayListName = glGenLists(1);
218
219 OOGL(glNewList(_displayListName, GL_COMPILE));
220
221 OOGL(glEnableClientState(GL_TEXTURE_COORD_ARRAY));
222 OOGL(glEnableClientState(GL_COLOR_ARRAY));
223
224 [_quadSets makeObjectsPerformSelector:@selector(render)];
225
226 OOGL(glDisableClientState(GL_TEXTURE_COORD_ARRAY));
227 OOGL(glDisableClientState(GL_COLOR_ARRAY));
228
229 OOGL(glEndList());
230 }
231
232 // Restore state
233 OOGL(glEnable(GL_DEPTH_TEST));
234 OOGL(glDisable(GL_TEXTURE_2D));
235
236 // Resetting fog is draw loop's responsibility.
237
239 OOCheckOpenGLErrors(@"OOSkyDrawable after rendering");
240}
241
242
243- (BOOL)hasOpaqueParts
244{
245 return YES;
246}
247
248
249- (GLfloat)maxDrawDistance
250{
251 return INFINITY;
252}
253
254#ifndef NDEBUG
255- (NSSet *) allTextures
256{
257 NSMutableSet *result = [NSMutableSet setWithCapacity:[_quadSets count]];
258
259 OOSkyQuadSet *quadSet = nil;
260 foreach (quadSet, _quadSets)
261 {
262 [result addObject:[quadSet texture]];
263 }
264
265 return result;
266}
267
268
269- (size_t) totalSize
270{
271 size_t result = [super totalSize];
272
273 OOSkyQuadSet *quadSet = nil;
274 foreach (quadSet, _quadSets)
275 {
276 result += [quadSet totalSize];
277 }
278
279 return result;
280}
281#endif
282
283@end
284
285
286#if DEBUG_COLORS
287static OOColor *DebugColor(Vector orientation)
288{
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];
291}
292#endif
293
294
295@implementation OOSkyDrawable (OOPrivate)
296
297- (void)setUpStarsWithColor1:(OOColor *)color1 color2:(OOColor *)color2
298{
299 OOSkyQuadDesc *quads = NULL, *currQuad = NULL;
300 unsigned i;
301 Quaternion q;
302 Vector vi, vj, vk;
303 float size;
304 Vector middle, offset;
305
306 [self loadStarTextures];
307
308 quads = malloc(sizeof *quads * _starCount);
309 if (quads == NULL) return;
310
311 currQuad = quads;
312 for (i = 0; i != _starCount; ++i)
313 {
314 // Select a direction and rotation.
315 q = OORandomQuaternion();
316 basis_vectors_from_quaternion(q, &vi, &vj, &vk);
317
318 // Select colour and texture.
319#if DEBUG_COLORS
320 currQuad->color = DebugColor(vk);
321#else
322 currQuad->color = [color1 blendedColorWithFraction:randf() ofColor:color2];
323#endif
324 currQuad->texture = [sStarTextures selectTexture]; // Not retained, since sStarTextures is never released.
325
326 // Select scale; calculate centre position and offset to first corner.
327 size = (1 + (ranrot_rand() % 6)) * SKY_ELEMENT_SCALE_FACTOR;
328 middle = vector_multiply_scalar(vk, BILLBOARD_DEPTH);
329 offset = vector_multiply_scalar(vector_add(vi, vj), 0.5f * size);
330
331 // Scale the "side" vectors.
332 Vector vj2 = vector_multiply_scalar(vj, size);
333 Vector vi2 = vector_multiply_scalar(vi, size);
334
335 // Set up corners.
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);
340
341 ++currQuad;
342 }
343
344 [self addQuads:quads count:_starCount];
345 free(quads);
346}
347
348
349- (void)setUpNebulaeWithColor1:(OOColor *)color1
350 color2:(OOColor *)color2
351 clusterFactor:(float)nebulaClusterFactor
352 nebulaHueFix:(BOOL)nebulaHueFix
353 alpha:(float)nebulaAlpha
354 scale:(float)nebulaScale
355{
356 OOSkyQuadDesc *quads = NULL, *currQuad = NULL;
357 unsigned i, actualCount = 0;
358 OOColor *color;
359 Quaternion q;
360 Vector vi, vj, vk;
361 double size, r2;
362 Vector middle, offset;
363 int r1;
364
365 [self loadNebulaTextures];
366
367 quads = malloc(sizeof *quads * _nebulaCount);
368 if (quads == NULL) return;
369
370 currQuad = quads;
371 for (i = 0; i < _nebulaCount; ++i)
372 {
373 color = SaturatedColorInRange(color1, color2, nebulaHueFix);
374
375 // Select a direction and rotation.
376 q = OORandomQuaternion();
377
378 // Create a cluster of nebula quads.
379 while ((i < _nebulaCount) && (randf() < nebulaClusterFactor))
380 {
381 // Select size.
382 r1 = 1 + (ranrot_rand() & 15);
383 size = nebulaScale * r1 * SKY_ELEMENT_SCALE_FACTOR;
384
385 // Calculate centre position and offset to first corner.
386 basis_vectors_from_quaternion(q, &vi, &vj, &vk);
387
388 // Select colour and texture. Smaller nebula quads are dimmer.
389#if DEBUG_COLORS
390 currQuad->color = DebugColor(vk);
391#else
392 currQuad->color = [color colorWithBrightnessFactor:nebulaAlpha * (0.5f + (float)r1 / 32.0f)];
393#endif
394 currQuad->texture = [sNebulaTextures selectTexture]; // Not retained, since sStarTextures is never released.
395
396 middle = vector_multiply_scalar(vk, BILLBOARD_DEPTH);
397 offset = vector_multiply_scalar(vector_add(vi, vj), 0.5f * size);
398
399 // Rotate vi and vj by a random angle
400 r2 = randf() * M_PI * 2.0;
404
405 // Scale the "side" vectors.
406 vj = vector_multiply_scalar(vj, size);
407 vi = vector_multiply_scalar(vi, size);
408
409 // Set up corners.
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);
414
415 // Shuffle direction quat around a bit to spread the cluster out.
417 q.x += size * (randf() - 0.5);
418 q.y += size * (randf() - 0.5);
419 q.z += size * (randf() - 0.5);
420 q.w += size * (randf() - 0.5);
421 quaternion_normalize(&q);
422
423 ++i;
424 ++currQuad;
425 ++actualCount;
426 }
427 }
428
429 /* The above code generates less than _nebulaCount quads, because i is
430 incremented once in the outer loop as well as in the inner loop. To
431 keep skies looking the same, we leave the bug in and fill in the
432 actual generated count here.
433 */
434 _nebulaCount = actualCount;
435
436 [self addQuads:quads count:_nebulaCount];
437 free(quads);
438}
439
440
441- (void)addQuads:(OOSkyQuadDesc *)quads count:(unsigned)count
442{
443 if (_quadSets == nil) _quadSets = [[NSMutableArray alloc] init];
444
445 [OOSkyQuadSet addQuads:quads count:count toArray:_quadSets];
446}
447
448
449- (void)loadStarTextures
450{
451 if (sStarTextures == nil)
452 {
454 initWithPListName:@"startextures.plist"
455 options:kOOTextureMinFilterMipMap | kOOTextureMagFilterLinear | kOOTextureAlphaMask
456 anisotropy:0.0f
457 lodBias:-0.0f];
458 if (sStarTextures == nil)
459 {
460 [NSException raise:OOLITE_EXCEPTION_DATA_NOT_FOUND format:@"No star textures could be loaded."];
461 }
462 }
463
464 [sStarTextures setSeed:RANROTGetFullSeed()];
465
466}
467
468
469- (void)loadNebulaTextures
470{
471 if (sNebulaTextures == nil)
472 {
474 initWithPListName:@"nebulatextures.plist"
475 options:kOOTextureDefaultOptions | kOOTextureAlphaMask
476 anisotropy:0.0f
477 lodBias:0.0f];
478 if (sNebulaTextures == nil)
479 {
480 [NSException raise:OOLITE_EXCEPTION_DATA_NOT_FOUND format:@"No nebula textures could be loaded."];
481 }
482 }
483
484 [sNebulaTextures setSeed:RANROTGetFullSeed()];
485
486}
487
488
490{
491 [sStarTextures ensureTexturesLoaded];
492 [sNebulaTextures ensureTexturesLoaded];
493}
494
495
496- (void)resetGraphicsState
497{
499
500 if (_displayListName != 0)
501 {
502 glDeleteLists(_displayListName, 1);
503 _displayListName = 0;
504 }
505}
506
507@end
508
509
510@implementation OOSkyQuadSet
511
512+ (void)addQuads:(OOSkyQuadDesc *)quads count:(unsigned)count toArray:(NSMutableArray *)ioArray
513{
514 NSMutableSet *seenTextures = nil;
515 OOTexture *texture = nil;
516 OOSkyQuadSet *quadSet = nil;
517 unsigned i;
518
519 // Iterate over all quads.
520 seenTextures = [NSMutableSet set];
521 for (i = 0; i != count; ++i)
522 {
523 texture = quads[i].texture;
524
525 // If we haven't seen this quad's texture before...
526 if (![seenTextures containsObject:texture])
527 {
528 [seenTextures addObject:texture];
529
530 // ...create a quad set for this texture.
531 quadSet = [[self alloc] initWithQuadsWithTexture:texture
532 inArray:quads
533 count:count];
534 if (quadSet != nil)
535 {
536 [ioArray addObject:quadSet];
537 [quadSet release];
538 }
539 }
540 }
541}
542
543
544- (id)initWithQuadsWithTexture:(OOTexture *)texture inArray:(OOSkyQuadDesc *)array count:(unsigned)totalCount
545{
546 BOOL OK = YES;
547 unsigned i, j, vertexCount;
548 GLfloat *pos;
549 GLfloat *tc;
550 GLfloat *col;
551 GLfloat r, g, b, x;
552 size_t posSize, tcSize, colSize;
553 unsigned count = 0;
554 int skyColorCorrection = [[NSUserDefaults standardUserDefaults] oo_integerForKey:@"sky-color-correction" defaultValue:0];
555
556// Hejl / Burgess-Dawson filmic tone mapping
557// this algorithm has gamma correction already embedded
558#define SKYCOLOR_TONEMAP_COMPONENT(skyColorComponent) \
559do { \
560 x = MAX(0.0, skyColorComponent - 0.004); \
561 *col++ = (x * (6.2 * x + 0.5)) / (x * (6.2 * x + 1.7) + 0.06); \
562} while (0)
563
564 self = [super init];
565 if (self == nil) OK = NO;
566
567 if (OK)
568 {
569 // Count the quads in the array using this texture.
570 for (i = 0; i != totalCount; ++i)
571 {
572 if (array[i].texture == texture) ++_count;
573 }
574 if (_count == 0) OK = NO;
575 }
576
577 if (OK)
578 {
579 // Allocate arrays.
580 vertexCount = _count * 4;
581 posSize = sizeof *_positions * vertexCount * kSkyQuadSetPositionEntriesPerVertex;
582 tcSize = sizeof *_texCoords * vertexCount * kSkyQuadSetTexCoordEntriesPerVertex;
583 colSize = sizeof *_colors * vertexCount * kSkyQuadSetColorEntriesPerVertex;
584
585 _positions = malloc(posSize);
586 _texCoords = malloc(tcSize);
587 _colors = malloc(colSize);
588
589 if (_positions == NULL || _texCoords == NULL || _colors == NULL) OK = NO;
590
591 pos = _positions;
592 tc = _texCoords;
593 col = _colors;
594 }
595
596 if (OK)
597 {
598 // Find the matching quads again, and convert them to renderable representation.
599 for (i = 0; i != totalCount; ++i)
600 {
601 if (array[i].texture == texture)
602 {
603 r = [array[i].color redComponent];
604 g = [array[i].color greenComponent];
605 b = [array[i].color blueComponent];
606
607 // Loop over vertices
608 for (j = 0; j != 4; ++j)
609 {
610 *pos++ = array[i].corners[j].x;
611 *pos++ = array[i].corners[j].y;
612 *pos++ = array[i].corners[j].z;
613
614 // Colour is the same for each vertex
615 if (skyColorCorrection == 0) // no color correction
616 {
617 *col++ = r;
618 *col++ = g;
619 *col++ = b;
620 }
621 else if (skyColorCorrection == 1) // gamma correction only
622 {
623 *col++ = pow(r, 1.0/2.2);
624 *col++ = pow(g, 1.0/2.2);
625 *col++ = pow(b, 1.0/2.2);
626 }
627 else // gamma correctioin + filmic tone mapping
628 {
632 }
633 *col++ = 1.0f; // Alpha is unused but needs to be there
634 }
635
636 // Texture co-ordinates are the same for each quad.
637 *tc++ = sMinTexCoord;
638 *tc++ = sMinTexCoord;
639
640 *tc++ = sMaxTexCoord;
641 *tc++ = sMinTexCoord;
642
643 *tc++ = sMaxTexCoord;
644 *tc++ = sMaxTexCoord;
645
646 *tc++ = sMinTexCoord;
647 *tc++ = sMaxTexCoord;
648
649 count++;
650 }
651 }
652
653 _texture = [texture retain];
654 OOLog(@"sky.setup", @"Generated quadset with %u quads for texture %@", count, _texture);
655 }
656
657 if (!OK)
658 {
659 [self release];
660 self = nil;
661 }
662
663 return self;
664}
665
666
667- (void)dealloc
668{
669 [_texture release];
670
671 if (_positions != NULL) free(_positions);
672 if (_texCoords != NULL) free(_texCoords);
673 if (_colors != NULL) free(_colors);
674
675 [super dealloc];
676}
677
678
679- (NSString *)description
680{
681 return [NSString stringWithFormat:@"<%@ %p>{%u quads, texture: %@}", [self class], self, _count, _texture];
682}
683
684
685- (void)render
686{
688
689 [_texture apply];
690
691 OOGL(glVertexPointer(kSkyQuadSetPositionEntriesPerVertex, GL_FLOAT, 0, _positions));
692 OOGL(glTexCoordPointer(kSkyQuadSetTexCoordEntriesPerVertex, GL_FLOAT, 0, _texCoords));
693 OOGL(glColorPointer(kSkyQuadSetColorEntriesPerVertex, GL_FLOAT, 0, _colors));
694
695 OOGL(glDrawArrays(GL_QUADS, 0, 4 * _count));
696}
697
698
699#ifndef NDEBUG
700- (size_t) totalSize
701{
702 return [self oo_objectSize] + _count * 4 * (sizeof *_positions + sizeof *_texCoords + sizeof *_colors);
703}
704
705
706- (OOTexture *) texture
707{
708 return _texture;
709}
710#endif
711
712@end
713
714
715static OOColor *SaturatedColorInRange(OOColor *color1, OOColor *color2, BOOL hueFix)
716{
717 OOColor *color = nil;
718 float hue, saturation, brightness, alpha;
719
720 color = [color1 blendedColorWithFraction:randf() ofColor:color2];
721 [color getHue:&hue saturation:&saturation brightness:&brightness alpha:&alpha];
722
723 saturation = 0.5 * saturation + 0.5; // move saturation up a notch!
724
725 /* NOTE: this changes the hue, because getHue:... produces hue values
726 in [0, 360], but colorWithCalibratedHue:... takes hue values in
727 [0, 1].
728 */
729 if (hueFix)
730 {
731 /* now nebula colours can be independently set, correct the
732 * range so they behave expectedly if they have actually been
733 * set in planetinfo */
734 hue /= 360.0;
735 }
736 /* else keep it how it was before so the nebula hues are clearer */
737
738 return [OOColor colorWithHue:hue saturation:saturation brightness:brightness alpha:alpha];
739}
#define OOLog(class, format,...)
Definition OOLogging.h:88
#define OO_ENTER_OPENGL()
#define M_PI
Definition OOMaths.h:73
@ OPENGL_STATE_ADDITIVE_BLENDING
Definition OOOpenGL.h:125
#define OOVerifyOpenGLState()
Definition OOOpenGL.h:136
BOOL OOCheckOpenGLErrors(NSString *format,...)
Definition OOOpenGL.m:39
#define OOSetOpenGLState(STATE)
Definition OOOpenGL.h:135
#define OOGL(statement)
Definition OOOpenGL.h:251
unsigned count
return nil
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)
float y
float x
static BOOL sInited
static float sMaxTexCoord
#define SKY_ELEMENT_SCALE_FACTOR
static float sMinTexCoord
static OOProbabilisticTextureManager * sNebulaTextures
static BOOL sInited
#define NEBULA_SHUFFLE_FACTOR
#define SKYCOLOR_TONEMAP_COMPONENT(skyColorComponent)
static OOProbabilisticTextureManager * sStarTextures
static OOColor * SaturatedColorInRange(OOColor *color1, OOColor *color2, BOOL hueFix)
@ kSkyQuadSetTexCoordEntriesPerVertex
@ kSkyQuadSetPositionEntriesPerVertex
@ kSkyQuadSetColorEntriesPerVertex
#define UNIVERSE
Definition Universe.h:842
#define BILLBOARD_DEPTH
Definition Universe.h:163
void getHue:saturation:brightness:alpha:(float *hue,[saturation] float *saturation,[brightness] float *brightness,[alpha] float *alpha)
Definition OOColor.m:438
OOColor * colorWithBrightnessFactor:(float factor)
Definition OOColor.m:502
OOColor * colorWithHue:saturation:brightness:alpha:(float hue,[saturation] float saturation,[brightness] float brightness,[alpha] float alpha)
Definition OOColor.m:87
OOColor * blendedColorWithFraction:ofColor:(float fraction,[ofColor] OOColor *color)
Definition OOColor.m:328
void registerClient:(id< OOGraphicsResetClient > client)
void unregisterClient:(id< OOGraphicsResetClient > client)
OOGraphicsResetManager * sharedManager()
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)
OOTexture * texture()
unsigned _count
GLfloat * _positions
void addQuads:count:toArray:(OOSkyQuadDesc *quads,[count] unsigned count,[toArray] NSMutableArray *ioArray)
OOTexture * _texture
GLfloat * _colors
GLfloat * _texCoords
voidpf void uLong size
Definition ioapi.h:134
voidpf uLong offset
Definition ioapi.h:140
float randf(void)
#define ranrot_rand()
OOColor * color
Vector corners[4]
OOTexture * texture