Line data Source code
1 0 : /*
2 :
3 : OOBasicMaterial.m
4 :
5 :
6 : Copyright (C) 2007-2013 Jens Ayton
7 :
8 : Permission is hereby granted, free of charge, to any person obtaining a copy
9 : of this software and associated documentation files (the "Software"), to deal
10 : in the Software without restriction, including without limitation the rights
11 : to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 : copies of the Software, and to permit persons to whom the Software is
13 : furnished to do so, subject to the following conditions:
14 :
15 : The above copyright notice and this permission notice shall be included in all
16 : copies or substantial portions of the Software.
17 :
18 : THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 : IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 : FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 : AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 : LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 : OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24 : SOFTWARE.
25 :
26 : */
27 :
28 : #import "OOBasicMaterial.h"
29 : #import "OOCollectionExtractors.h"
30 : #import "OOFunctionAttributes.h"
31 : #import "Universe.h"
32 : #import "OOMaterialSpecifier.h"
33 : #import "OOTexture.h"
34 :
35 :
36 0 : static OOBasicMaterial *sDefaultMaterial = nil;
37 :
38 :
39 0 : #define FACE GL_FRONT_AND_BACK
40 :
41 :
42 : @implementation OOBasicMaterial
43 :
44 : - (id)initWithName:(NSString *)name
45 : {
46 : self = [super init];
47 : if (EXPECT_NOT(self == nil)) return nil;
48 :
49 : materialName = [name copy];
50 :
51 : [self setDiffuseRed:1.0f green:1.0f blue:1.0f alpha:1.0f];
52 : [self setAmbientRed:1.0f green:1.0f blue:1.0f alpha:1.0f];
53 : specular[3] = 1.0;
54 : emission[3] = 1.0;
55 :
56 : return self;
57 : }
58 :
59 :
60 : - (id)initWithName:(NSString *)name configuration:(NSDictionary *)configuration
61 : {
62 : id colorDesc = nil;
63 : int specularExponent;
64 :
65 : self = [self initWithName:name];
66 : if (EXPECT_NOT(self == nil)) return nil;
67 :
68 : if (configuration == nil) configuration = [NSDictionary dictionary];
69 :
70 : colorDesc = [configuration oo_diffuseColor];
71 : if (colorDesc != nil) [self setDiffuseColor:[OOColor colorWithDescription:colorDesc]];
72 :
73 : colorDesc = [configuration oo_ambientColor];
74 : if (colorDesc != nil) [self setAmbientColor:[OOColor colorWithDescription:colorDesc]];
75 : else [self setAmbientColor:[self diffuseColor]];
76 :
77 : colorDesc = [configuration oo_emissionColor];
78 : if (colorDesc != nil) [self setEmissionColor:[OOColor colorWithDescription:colorDesc]];
79 :
80 : specularExponent = [configuration oo_specularExponent];
81 : if (specularExponent != 0 && [self permitSpecular])
82 : {
83 : colorDesc = [configuration oo_specularColor];
84 : [self setShininess:specularExponent];
85 : if (colorDesc != nil) [self setSpecularColor:[OOColor colorWithDescription:colorDesc]];
86 : }
87 :
88 : return self;
89 : }
90 :
91 :
92 0 : - (void)dealloc
93 : {
94 : [super willDealloc];
95 : [materialName release];
96 :
97 : [super dealloc];
98 : }
99 :
100 :
101 0 : - (NSString *)name
102 : {
103 : return materialName;
104 : }
105 :
106 :
107 0 : - (BOOL)doApply
108 : {
109 : OOGL(glMaterialfv(FACE, GL_DIFFUSE, diffuse));
110 : OOGL(glMaterialfv(FACE, GL_SPECULAR, specular));
111 : OOGL(glMaterialfv(FACE, GL_AMBIENT, ambient));
112 : OOGL(glMaterialfv(FACE, GL_EMISSION, emission));
113 : OOGL(glMateriali(FACE, GL_SHININESS, shininess));
114 : if ([self isMemberOfClass:[OOBasicMaterial class]])
115 : {
116 : [OOTexture applyNone];
117 : }
118 :
119 : return YES;
120 : }
121 :
122 :
123 0 : - (void)unapplyWithNext:(OOMaterial *)next
124 : {
125 : if (![next isKindOfClass:[OOBasicMaterial class]])
126 : {
127 : if (EXPECT_NOT(sDefaultMaterial == nil)) sDefaultMaterial = [[OOBasicMaterial alloc] initWithName:@"<default material>"];
128 : [sDefaultMaterial doApply];
129 : }
130 : }
131 :
132 :
133 : - (OOColor *)diffuseColor
134 : {
135 : return [OOColor colorWithRed:diffuse[0]
136 : green:diffuse[1]
137 : blue:diffuse[2]
138 : alpha:diffuse[3]];
139 : }
140 :
141 :
142 : - (void)setDiffuseColor:(OOColor *)color
143 : {
144 : if (color != nil)
145 : {
146 : [self setDiffuseRed:[color redComponent]
147 : green:[color greenComponent]
148 : blue:[color blueComponent]
149 : alpha:[color alphaComponent]];
150 : }
151 : }
152 :
153 :
154 : - (void)setAmbientAndDiffuseColor:(OOColor *)color
155 : {
156 : [self setAmbientColor:color];
157 : [self setDiffuseColor:color];
158 : }
159 :
160 :
161 : - (OOColor *)specularColor
162 : {
163 : return [OOColor colorWithRed:specular[0]
164 : green:specular[1]
165 : blue:specular[2]
166 : alpha:specular[3]];
167 : }
168 :
169 :
170 : - (void)setSpecularColor:(OOColor *)color
171 : {
172 : if (color != nil)
173 : {
174 : [self setSpecularRed:[color redComponent]
175 : green:[color greenComponent]
176 : blue:[color blueComponent]
177 : alpha:[color alphaComponent]];
178 : }
179 : }
180 :
181 :
182 : - (OOColor *)ambientColor
183 : {
184 : return [OOColor colorWithRed:ambient[0]
185 : green:ambient[1]
186 : blue:ambient[2]
187 : alpha:ambient[3]];
188 : }
189 :
190 :
191 : - (void)setAmbientColor:(OOColor *)color
192 : {
193 : if (color != nil)
194 : {
195 : [self setAmbientRed:[color redComponent]
196 : green:[color greenComponent]
197 : blue:[color blueComponent]
198 : alpha:[color alphaComponent]];
199 : }
200 : }
201 :
202 :
203 : - (OOColor *)emmisionColor
204 : {
205 : return [OOColor colorWithRed:emission[0]
206 : green:emission[1]
207 : blue:emission[2]
208 : alpha:emission[3]];
209 : }
210 :
211 :
212 : - (void)setEmissionColor:(OOColor *)color
213 : {
214 : if (color != nil)
215 : {
216 : [self setEmissionRed:[color redComponent]
217 : green:[color greenComponent]
218 : blue:[color blueComponent]
219 : alpha:[color alphaComponent]];
220 : }
221 : }
222 :
223 :
224 : - (void)getDiffuseComponents:(GLfloat[4])outComponents
225 : {
226 : memcpy(outComponents, diffuse, 4 * sizeof *outComponents);
227 : }
228 :
229 :
230 : - (void)setDiffuseComponents:(const GLfloat[4])components
231 : {
232 : memcpy(diffuse, components, 4 * sizeof *components);
233 : }
234 :
235 :
236 : - (void)setAmbientAndDiffuseComponents:(const GLfloat[4])components
237 : {
238 : [self setAmbientComponents:components];
239 : [self setDiffuseComponents:components];
240 : }
241 :
242 :
243 : - (void)getSpecularComponents:(GLfloat[4])outComponents
244 : {
245 : memcpy(outComponents, specular, 4 * sizeof *outComponents);
246 : }
247 :
248 :
249 : - (void)setSpecularComponents:(const GLfloat[4])components
250 : {
251 : memcpy(specular, components, 4 * sizeof *components);
252 : }
253 :
254 :
255 : - (void)getAmbientComponents:(GLfloat[4])outComponents
256 : {
257 : memcpy(outComponents, ambient, 4 * sizeof *outComponents);
258 : }
259 :
260 :
261 : - (void)setAmbientComponents:(const GLfloat[4])components
262 : {
263 : memcpy(ambient, components, 4 * sizeof *components);
264 : }
265 :
266 :
267 : - (void)getEmissionComponents:(GLfloat[4])outComponents
268 : {
269 : memcpy(outComponents, emission, 4 * sizeof *outComponents);
270 : }
271 :
272 :
273 : - (void)setEmissionComponents:(const GLfloat[4])components
274 : {
275 : memcpy(emission, components, 4 * sizeof *components);
276 : }
277 :
278 :
279 : - (void)setDiffuseRed:(GLfloat)r green:(GLfloat)g blue:(GLfloat)b alpha:(GLfloat)a
280 : {
281 : diffuse[0] = r;
282 : diffuse[1] = g;
283 : diffuse[2] = b;
284 : diffuse[3] = a;
285 : }
286 :
287 :
288 : - (void)setAmbientAndDiffuseRed:(GLfloat)r green:(GLfloat)g blue:(GLfloat)b alpha:(GLfloat)a
289 : {
290 : [self setAmbientRed:r green:g blue:b alpha:a];
291 : [self setDiffuseRed:r green:g blue:b alpha:a];
292 : }
293 :
294 :
295 : - (void)setSpecularRed:(GLfloat)r green:(GLfloat)g blue:(GLfloat)b alpha:(GLfloat)a
296 : {
297 : specular[0] = r;
298 : specular[1] = g;
299 : specular[2] = b;
300 : specular[3] = a;
301 : }
302 :
303 :
304 : - (void)setAmbientRed:(GLfloat)r green:(GLfloat)g blue:(GLfloat)b alpha:(GLfloat)a
305 : {
306 : ambient[0] = r;
307 : ambient[1] = g;
308 : ambient[2] = b;
309 : ambient[3] = a;
310 : }
311 :
312 :
313 : - (void)setEmissionRed:(GLfloat)r green:(GLfloat)g blue:(GLfloat)b alpha:(GLfloat)a
314 : {
315 : emission[0] = r;
316 : emission[1] = g;
317 : emission[2] = b;
318 : emission[3] = a;
319 : }
320 :
321 :
322 :
323 : - (uint8_t)shininess
324 : {
325 : return shininess;
326 : }
327 :
328 :
329 : - (void)setShininess:(uint8_t)value
330 : {
331 : shininess = MIN(value, 128);
332 : }
333 :
334 :
335 : - (BOOL) permitSpecular
336 : {
337 : return ![UNIVERSE reducedDetail];
338 : }
339 :
340 :
341 : #ifndef NDEBUG
342 0 : - (NSSet *) allTextures
343 : {
344 : return [NSSet set];
345 : }
346 : #endif
347 :
348 : @end
|