Oolite 1.91.0.7646-241128-10e222e
Loading...
Searching...
No Matches
OOMultiTextureMaterial.m
Go to the documentation of this file.
1/*
2
3OOMultiTextureMaterial.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
31#import "OOTexture.h"
32#import "OOMacroOpenGL.h"
35
36#if OO_MULTITEXTURE
37
38
39@implementation OOMultiTextureMaterial
40
41- (id)initWithName:(NSString *)name configuration:(NSDictionary *)configuration
42{
43 if (![[OOOpenGLExtensionManager sharedManager] textureCombinersSupported])
44 {
45 [self release];
46 return nil;
47 }
48
49 NSDictionary *diffuseSpec = [configuration oo_diffuseMapSpecifierWithDefaultName:name];
50 NSDictionary *emissionSpec = [configuration oo_emissionMapSpecifier];
51 NSDictionary *illuminationSpec = [configuration oo_illuminationMapSpecifier];
52 NSDictionary *emissionAndIlluminationSpec = [configuration oo_emissionAndIlluminationMapSpecifier];
53 OOColor *diffuseColor = [configuration oo_diffuseColor];
54 OOColor *emissionColor = nil;
55 OOColor *illuminationColor = [configuration oo_illuminationModulateColor];
56
57 NSMutableDictionary *mutableConfiguration = [NSMutableDictionary dictionaryWithDictionary:configuration];
58
59 if (emissionSpec != nil || emissionAndIlluminationSpec != nil)
60 {
61 emissionColor = [configuration oo_emissionModulateColor];
62
63 /* If an emission map and an emission colour are both specified, stop
64 the superclass (OOBasicMaterial) from applying the emission colour.
65 */
66 [mutableConfiguration removeObjectForKey:kOOMaterialEmissionColorName];
67 [mutableConfiguration removeObjectForKey:kOOMaterialEmissionColorLegacyName];
68 }
69
70 if ((self = [super initWithName:name configuration:mutableConfiguration]))
71 {
72 if (diffuseSpec != nil)
73 {
74 _diffuseMap = [[OOTexture textureWithConfiguration:diffuseSpec] retain];
75 if (_diffuseMap != nil) _unitsUsed++;
76 }
77
78 // Check for simplest cases, where we don't need to bake a derived emission map.
79 if (emissionSpec != nil && illuminationSpec == nil && emissionAndIlluminationSpec == nil && emissionColor == nil)
80 {
81 _emissionMap = [[OOTexture textureWithConfiguration:emissionSpec extraOptions:kOOTextureExtraShrink] retain];
82 if (_emissionMap != nil) _unitsUsed++;
83 }
84 else
85 {
87
88 if (emissionAndIlluminationSpec != nil)
89 {
90 generator = [[OOCombinedEmissionMapGenerator alloc] initWithEmissionAndIlluminationMapSpec:emissionAndIlluminationSpec
91 diffuseMap:_diffuseMap
92 diffuseColor:diffuseColor
93 emissionColor:emissionColor
94 illuminationColor:illuminationColor
95 optionsSpecifier:emissionAndIlluminationSpec];
96 }
97 else
98 {
99 generator = [[OOCombinedEmissionMapGenerator alloc] initWithEmissionMapSpec:emissionSpec
100 emissionColor:emissionColor
101 diffuseMap:_diffuseMap
102 diffuseColor:diffuseColor
103 illuminationMapSpec:illuminationSpec
104 illuminationColor:illuminationColor
105 optionsSpecifier:emissionSpec ?: illuminationSpec];
106 }
107
108 _emissionMap = [[OOTexture textureWithGenerator:[generator autorelease]] retain];
109 if (_emissionMap != nil) _unitsUsed++;
110 }
111 }
112
113 return self;
114}
115
116
117- (void) dealloc
118{
119 [self willDealloc];
120
121 DESTROY(_diffuseMap);
122 DESTROY(_emissionMap);
123
124 [super dealloc];
125}
126
127
128- (NSString *) descriptionComponents
129{
130 NSMutableArray *bits = [NSMutableArray array];
131 if (_diffuseMap) [bits addObject:[NSString stringWithFormat:@"diffuse map: %@", [_diffuseMap shortDescription]]];
132 if (_emissionMap) [bits addObject:[NSString stringWithFormat:@"emission map: %@", [_emissionMap shortDescription]]];
133
134 NSString *result = [super descriptionComponents];
135 if ([bits count] > 0) result = [result stringByAppendingFormat:@" - %@", [bits componentsJoinedByString:@","]];
136 return result;
137}
138
139
140- (NSUInteger) textureUnitCount
141{
142 return _unitsUsed;
143}
144
145
146- (NSUInteger) countOfTextureUnitsWithBaseCoordinates
147{
148 return _unitsUsed;
149}
150
151
152- (void) ensureFinishedLoading
153{
154 [_diffuseMap ensureFinishedLoading];
155 [_emissionMap ensureFinishedLoading];
156}
157
158
159- (void) apply
160{
162
163 [super apply];
164
165 GLenum textureUnit = GL_TEXTURE0_ARB;
166
167 if (_diffuseMap != nil)
168 {
169 OOGL(glActiveTextureARB(textureUnit++));
170 OOGL(glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB));
171 OOGL(glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE));
172 [_diffuseMap apply];
173 }
174
175 if (_emissionMap != nil)
176 {
177 OOGL(glActiveTextureARB(textureUnit++));
178 OOGL(glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB));
179 OOGL(glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_ADD));
180 [_emissionMap apply];
181 }
182
183 NSAssert2(textureUnit - GL_TEXTURE0_ARB == _unitsUsed, @"OOMultiTextureMaterial texture unit count invalid (expected %lu, actually using %u)", _unitsUsed, textureUnit - GL_TEXTURE0_ARB);
184
185 if (textureUnit > GL_TEXTURE1_ARB)
186 {
187 OOGL(glActiveTextureARB(GL_TEXTURE0_ARB));
188 }
189}
190
191
192- (void) unapplyWithNext:(OOMaterial *)next
193{
195
196 [super unapplyWithNext:next];
197
198 NSUInteger i;
199 i = [next isKindOfClass:[OOMultiTextureMaterial class]] ? [(OOMultiTextureMaterial *)next textureUnitCount] : 0;
200 for (; i != _unitsUsed; ++i)
201 {
202 OOGL(glActiveTextureARB(GL_TEXTURE0_ARB + i));
204 OOGL(glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE));
205 }
206 OOGL(glActiveTextureARB(GL_TEXTURE0_ARB));
207}
208
209
210#ifndef NDEBUG
211- (NSSet *) allTextures
212{
213 if (_diffuseMap == nil) return [NSSet setWithObject:_emissionMap];
214 return [NSSet setWithObjects:_diffuseMap, _emissionMap, nil];
215}
216#endif
217
218@end
219
220#endif /* OO_MULTITEXTURE */
#define DESTROY(x)
Definition OOCocoa.h:77
#define OO_ENTER_OPENGL()
#define OOGL(statement)
Definition OOOpenGL.h:251
unsigned count
return nil
id textureWithGenerator:(OOTextureGenerator *generator)
Definition OOTexture.m:217
id textureWithConfiguration:extraOptions:(id configuration,[extraOptions] OOTextureFlags extraOptions)
Definition OOTexture.m:198
void applyNone()
Definition OOTexture.m:275
id textureWithConfiguration:(id configuration)
Definition OOTexture.m:192