Oolite 1.91.0.7646-241128-10e222e
Loading...
Searching...
No Matches
OOEnvironmentCubeMap.m
Go to the documentation of this file.
1/*
2
3OOEnvironmentCubeMap.m
4
5
6Copyright (C) 2010-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
29#import "OOTexture.h"
30#import "OOTextureInternal.h"
31#import "MyOpenGLView.h"
32#import "OOPixMap.h"
33#import "OOMacroOpenGL.h"
34
35#import "Universe.h"
36#import "PlayerEntity.h"
37#import "SkyEntity.h"
38#import "OOSunEntity.h"
39#import "OOPlanetEntity.h"
40#import "OODrawable.h"
42
43
44#if OO_USE_FBO && OO_TEXTURE_CUBE_MAP
45
46@interface OOEnvironmentCubeMap (Private)
47
48- (void) setUp;
49
50- (void) renderOnePassWithSky:(OODrawable *)sky sun:(OOSunEntity *)sun planets:(NSArray *)planets;
51
52@end
53
54
55@implementation OOEnvironmentCubeMap
56
57- (id) initWithSideLength:(GLuint)size
58{
59 if (![[OOOpenGLExtensionManager sharedManager] fboSupported] || !OOCubeMapsAvailable())
60 {
61 [self release];
62 return nil;
63 }
64
65 if ((self = [super init]))
66 {
67 _size = size;
68 }
69
70 return self;
71}
72
73
74- (void) dealloc
75{
76 [self forceRebind];
77
78 [super dealloc];
79}
80
81
82- (void) render
83{
84 if (_textureName == 0) [self setUp];
85
87
88 // Save stuff.
89 OOGL(glPushAttrib(GL_VIEWPORT_BIT | GL_ENABLE_BIT));
92
93 OOGL(glViewport(0, 0, _size, _size));
94 OOGLScaleProjection(make_vector(-1.0, 1.0, 1.0)); // flip left and right
95
96 /* TODO: once confirmed working (and rendering everything in the right
97 orientation), replace with glLoadMatrix and the following:
98 1 0 0 0
99 0 1 0 0
100 0 0 -1 -2
101 0 0 -1 0
102
103 ...and appropriate rotations thereof.
104 */
105
107 OOGLPerspective(90.0, 1.0, 1.0, MAX_CLEAR_DEPTH);
108
109 OODrawable *sky = [[UNIVERSE nearestEntityMatchingPredicate:HasClassPredicate parameter:[SkyEntity class] relativeToEntity:nil] drawable];
110 OOSunEntity *sun = [UNIVERSE sun];
111 NSArray *planets = [UNIVERSE planets];
112
113 unsigned i;
114 Vector centers[6] = { { 1, 0, 0 }, { -1, 0, 0 }, { 0, 1, 0 }, { 0, -1, 0 }, { 0, 0, 1 }, { 0, 0, -1 } };
115 Vector ups[6] = { { 0, -1, 0 }, { 0, -1, 0 }, { 0, 0, 1 }, { 0, 0, -1 }, { 0, -1, 0 }, { 0, -1, 0 } };
116
117 for (i = 0; i < 6; i++)
118 {
120 Vector center = centers[i];
121 Vector up = ups[i];
122 OOGLLookAt(kZeroVector, center, up);
123
124 OOGL(glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, _fbos[i]));
125 [self renderOnePassWithSky:sky sun:sun planets:planets];
126
128 }
129
132 OOGL(glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0));
133 OOGL(glPopAttrib());
134}
135
136
137- (void) renderOnePassWithSky:(OODrawable *)sky sun:(OOSunEntity *)sun planets:(NSArray *)planets
138{
140
141 OOGL(glClearColor(0.0f, 0.0f, 0.0f, 1.0f));
142 OOGL(glClearDepth(MAX_CLEAR_DEPTH));
143 OOGL(glClear(_planets ? GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT : GL_COLOR_BUFFER_BIT));
144
145 OOGL(glDepthMask(GL_FALSE));
146 [sky renderOpaqueParts];
147 OOGL(glDepthMask(GL_TRUE));
148
151 OOGLTranslateModelView(vector_flip([PLAYER position]));
152
153 NSEnumerator *planetEnum = nil;
154 OOPlanetEntity *planet = nil;
155 for (planetEnum = [planets objectEnumerator]; (planet = [planetEnum nextObject]); )
156 {
158 OOGLTranslateModelView(planet position]);
159#if NEW_PLANETS
160 [[planet drawable] renderOpaqueParts];
161#else
162 [planet drawUnconditionally];
163#endif
165 }
166
168 OOGLTranslateModelView([sun position]);
169 [sun drawUnconditionally];
172}
173
174- (void) setUp
175{
177
178 if (_textureName != 0) return;
179 _planets = [UNIVERSE reducedDetail];
180
181 OOGL(glGenTextures(1, &_textureName));
182 OOGL(glBindTexture(GL_TEXTURE_CUBE_MAP, _textureName));
183 OOGL(glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
184 OOGL(glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
185 OOGL(glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE));
186 OOGL(glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
187 OOGL(glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
188
189 OOGL(glGenFramebuffersEXT(6, _fbos));
190 OOGL(glGenRenderbuffersEXT(6, _depthBuffers));
191
192 unsigned i;
193 for (i = 0; i < 6; i++)
194 {
195 GLenum textarget = GL_TEXTURE_CUBE_MAP_POSITIVE_X + i;
196
197 OOGL(glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, _fbos[i]));
198
199 OOGL(glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, _depthBuffers[i]));
200 OOGL(glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, _size, _size));
201 OOGL(glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, _depthBuffers[i]));
202
203 OOGL(glTexImage2D(textarget, 0, GL_RGBA8, _size, _size, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL));
204 OOGL(glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, textarget, _textureName, 0));
205 }
206
207#ifndef NDEBUG
208 GLenum status;
209 OOGL(status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT));
210 if (status != GL_FRAMEBUFFER_COMPLETE_EXT)
211 {
212 OOLogERR(@"environmentCube.fbo.setup.failed", @"Failed to set up FBO for environment cube map - status is %u.", status);
213 DESTROY(self);
214 }
215
216 OOCheckOpenGLErrors(@"after setting up environment cube map FBO");
217#endif
218 OOGL(glBindTexture(GL_TEXTURE_CUBE_MAP, 0));
219 OOGL(glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0));
220 OOGL(glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0));
221}
222
223
224// OOTexture stuff.
225
226- (void) apply
227{
229 OOGL(glBindTexture(GL_TEXTURE_CUBE_MAP, _textureName));
230}
231
232
233- (NSSize) dimensions
234{
235 return NSMakeSize(_size, _size);
236}
237
238
239- (void) forceRebind
240{
242 if (_textureName == 0) return;
243
244 OOGL(glDeleteTextures(1, &_textureName));
245 _textureName = 0;
246
247 OOGL(glDeleteFramebuffersEXT(6, _fbos));
248 OOGL(glDeleteRenderbuffersEXT(6, _depthBuffers));
249}
250
251
252- (BOOL) isCubeMap
253{
254 return YES;
255}
256
257
258- (struct OOPixMap) copyPixMapRepresentation
259{
260 OOPixMap pixmap = OOAllocatePixMap(_size, _size * 6, 4, 0, 0);
261 if (!OOIsValidPixMap(pixmap)) return kOONullPixMap;
262
264
265 unsigned i;
266 for (i = 0; i < 6; i++)
267 {
268 OOGL(glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, _fbos[i]));
269 OOGL(glReadBuffer(GL_COLOR_ATTACHMENT0_EXT));
270 uint8_t *target = pixmap.pixels;
271 target += pixmap.rowBytes * _size * i;
272 OOGL(glReadPixels(0, 0, _size, _size, GL_RGBA, GL_UNSIGNED_BYTE, target));
273 }
274
275 OOGL(glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0));
276 return pixmap;
277}
278
279@end
280
281#endif
#define MAX_CLEAR_DEPTH
#define DESTROY(x)
Definition OOCocoa.h:77
#define OOLogERR(class, format,...)
Definition OOLogging.h:112
#define OO_ENTER_OPENGL()
void OOGLLookAt(Vector eye, Vector center, Vector up)
void OOGLScaleProjection(Vector scale)
void OOGLPushModelView(void)
void OOGLPushProjection(void)
void OOGLResetModelView(void)
void OOGLTranslateModelView(Vector vector)
void OOGLPerspective(double fovy, double aspect, double zNear, double zFar)
OOMatrix OOGLPopModelView(void)
void OOGLResetProjection(void)
OOMatrix OOGLPopProjection(void)
BOOL OOCheckOpenGLErrors(NSString *format,...)
Definition OOOpenGL.m:39
#define OOGL(statement)
Definition OOOpenGL.h:251
const OOPixMap kOONullPixMap
Definition OOPixMap.m:31
OOPixMap OOAllocatePixMap(OOPixMapDimension width, OOPixMapDimension height, OOPixMapFormat format, size_t rowBytes, size_t bufferSize)
Definition OOPixMap.m:73
BOOL OOIsValidPixMap(OOPixMap pixMap)
Definition OOPixMap.m:42
return nil
#define GL_CLAMP_TO_EDGE
BOOL OOCubeMapsAvailable(void)
Definition OOTexture.m:688
const Vector kZeroVector
Definition OOVector.m:28
#define PLAYER
void renderOpaqueParts()
Definition OODrawable.m:34
voidpf void uLong size
Definition ioapi.h:134
void * pixels
Definition OOPixMap.h:49