Update contrib.
2 * Copyright (c) 2003 Nokia Corporation and/or its subsidiary(-ies).
4 * This component and the accompanying materials are made available
5 * under the terms of the License "Eclipse Public License v1.0"
6 * which accompanies this distribution, and is available
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
9 * Initial Contributors:
10 * Nokia Corporation - initial contribution.
14 * Description: Material implementation
22 * \brief Material implementation
25 #ifndef M3G_CORE_INCLUDE
26 # error included by m3g_core.c; do not compile separately.
29 #include "m3g_material.h"
30 #include "m3g_animationtrack.h"
32 #define ALL_TARGET_MASK (M3G_AMBIENT_BIT | M3G_DIFFUSE_BIT | M3G_EMISSIVE_BIT | M3G_SPECULAR_BIT)
34 /*----------------------------------------------------------------------
36 *--------------------------------------------------------------------*/
40 * \brief Applies default material to OpenGL.
42 static void m3gApplyDefaultMaterial(void)
44 glDisable(GL_COLOR_MATERIAL);
45 glDisable(GL_LIGHTING);
50 * \brief Applies material to OpenGL.
52 * \param material Material object
53 * \param alphaFactor alpha factor as 1.16 fixed point
55 static void m3gApplyMaterial(Material *material, M3Gint alphaFactor)
57 if (material != NULL) {
60 /* NOTE We must set the ColorMaterial state *before* setting
61 * any of the material colors, as they will not change if
62 * tracking is enabled! */
64 if (material->vertexColorTracking) {
65 glEnable(GL_COLOR_MATERIAL);
68 glDisable(GL_COLOR_MATERIAL);
70 /* Ambient and diffuse only need to be set when tracking
73 m3gFloatColor(material->ambientColor, 1.0f, colors);
74 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, colors);
75 m3gFloatColor(material->diffuseColor, 1.0f, colors);
76 if (alphaFactor < 0x10000) {
77 colors[3] = m3gMul(colors[3],
78 m3gMul((M3Gfloat) alphaFactor,
81 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, colors);
83 m3gFloatColor(material->emissiveColor, 1.0f, colors);
84 glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, colors);
85 m3gFloatColor(material->specularColor, 1.0f, colors);
86 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, colors);
87 glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, material->shininess);
89 glEnable(GL_LIGHTING);
92 m3gApplyDefaultMaterial();
99 * \brief Overloaded Object3D method.
101 * \param property animation property
102 * \retval M3G_TRUE property supported
103 * \retval M3G_FALSE property not supported
105 static M3Gbool m3gMaterialIsCompatible(M3Gint property)
109 case M3G_ANIM_AMBIENT_COLOR:
110 case M3G_ANIM_DIFFUSE_COLOR:
111 case M3G_ANIM_EMISSIVE_COLOR:
112 case M3G_ANIM_SHININESS:
113 case M3G_ANIM_SPECULAR_COLOR:
116 return m3gObjectIsCompatible(property);
122 * \brief Overloaded Object3D method.
124 * \param self Material object
125 * \param property animation property
126 * \param valueSize size of value array
127 * \param value value array
129 static void m3gMaterialUpdateProperty(Object *self,
132 const M3Gfloat *value)
134 Material *material = (Material *)self;
135 M3G_VALIDATE_OBJECT(material);
136 M3G_ASSERT_PTR(value);
140 M3G_ASSERT(valueSize >= 1);
141 material->diffuseColor = (material->diffuseColor | M3G_ALPHA_MASK) &
142 m3gAlpha1f(value[0]);
144 case M3G_ANIM_AMBIENT_COLOR:
145 M3G_ASSERT(valueSize >= 3);
146 material->ambientColor = m3gColor3f(value[0], value[1], value[2]);
148 case M3G_ANIM_DIFFUSE_COLOR:
149 M3G_ASSERT(valueSize >= 3);
150 material->diffuseColor = (material->diffuseColor | M3G_RGB_MASK)
151 & m3gColor3f(value[0], value[1], value[2]);
153 case M3G_ANIM_EMISSIVE_COLOR:
154 M3G_ASSERT(valueSize >= 3);
155 material->emissiveColor = m3gColor3f(value[0], value[1], value[2]) & M3G_RGB_MASK;
157 case M3G_ANIM_SHININESS:
158 M3G_ASSERT(valueSize >= 1);
159 material->shininess = m3gClampFloat(value[0], 0.f, 128.f);
161 case M3G_ANIM_SPECULAR_COLOR:
162 M3G_ASSERT(valueSize >= 3);
163 material->specularColor = m3gColor3f(value[0], value[1], value[2]);
166 m3gObjectUpdateProperty(self, property, valueSize, value);
172 * \brief Overloaded Object3D method.
174 * \param originalObj original Material object
175 * \param cloneObj pointer to cloned Material object
176 * \param pairs array for all object-duplicate pairs
177 * \param numPairs number of pairs
179 static M3Gbool m3gMaterialDuplicate(const Object *originalObj,
184 const Material *original = (const Material *)originalObj;
186 /* Create the clone object */
188 Material *clone = (Material *)m3gCreateMaterial(originalObj->interface);
192 *cloneObj = (Object *)clone;
194 /* Duplicate base class and own data */
196 if (m3gObjectDuplicate(originalObj, cloneObj, pairs, numPairs)) {
197 clone->vertexColorTracking = original->vertexColorTracking;
198 clone->ambientColor = original->ambientColor;
199 clone->diffuseColor = original->diffuseColor;
200 clone->emissiveColor = original->emissiveColor;
201 clone->specularColor = original->specularColor;
202 clone->shininess = original->shininess;
210 /*----------------------------------------------------------------------
211 * Virtual function table
212 *--------------------------------------------------------------------*/
214 static const ObjectVFTable m3gvf_Material = {
215 m3gObjectApplyAnimation,
216 m3gMaterialIsCompatible,
217 m3gMaterialUpdateProperty,
218 m3gObjectDoGetReferences,
220 m3gMaterialDuplicate,
225 /*----------------------------------------------------------------------
226 * Public API functions
227 *--------------------------------------------------------------------*/
230 * \brief Creates a Material object.
232 * \param interface M3G interface
233 * \retval Material new Material object
234 * \retval NULL Material creating failed
236 M3G_API M3GMaterial m3gCreateMaterial(M3GInterface interface)
238 Interface *m3g = (Interface *) interface;
239 M3G_VALIDATE_INTERFACE(m3g);
242 Material *material = m3gAllocZ(m3g, sizeof(Material));
244 if (material != NULL) {
245 m3gInitObject(&material->object, m3g, M3G_CLASS_MATERIAL);
246 /* Default values are from the jsr-184 specification */
247 material->vertexColorTracking = GL_FALSE;
248 material->ambientColor = 0x00333333U;
249 material->diffuseColor = 0xFFCCCCCCU;
250 material->emissiveColor = 0x00000000U;
251 material->specularColor = 0x00000000U;
252 material->shininess = 0.0f;
255 return (M3GMaterial)material;
260 * \brief Set material color.
262 * \param hMaterial Material object
263 * \param target color target
264 * \param ARGB ARGB color
266 M3G_API void m3gSetColor(M3GMaterial hMaterial, M3Genum target, M3Guint ARGB)
268 Material *material = (Material *) hMaterial;
269 M3G_VALIDATE_OBJECT(material);
270 /* is invalid target in the mask OR no target */
271 if (((target | ALL_TARGET_MASK) != ALL_TARGET_MASK) || ((target & ALL_TARGET_MASK) == 0)) {
272 m3gRaiseError(M3G_INTERFACE(material), M3G_INVALID_VALUE);
275 if ((target & M3G_AMBIENT_BIT) != 0) {
276 material->ambientColor = ARGB & M3G_RGB_MASK;
278 if ((target & M3G_DIFFUSE_BIT) != 0) {
279 material->diffuseColor = ARGB;
281 if ((target & M3G_EMISSIVE_BIT) != 0) {
282 material->emissiveColor = ARGB & M3G_RGB_MASK;
284 if ((target & M3G_SPECULAR_BIT) != 0) {
285 material->specularColor = ARGB & M3G_RGB_MASK;
290 * \brief Get material color.
292 * \param hMaterial Material object
293 * \param target color target
296 M3G_API M3Guint m3gGetColor(M3GMaterial hMaterial, M3Genum target)
298 Material *material = (Material *) hMaterial;
299 M3G_VALIDATE_OBJECT(material);
302 case M3G_AMBIENT_BIT:
303 return material->ambientColor;
304 case M3G_DIFFUSE_BIT:
305 return material->diffuseColor;
306 case M3G_EMISSIVE_BIT:
307 return material->emissiveColor;
308 case M3G_SPECULAR_BIT:
309 return material->specularColor;
311 m3gRaiseError(M3G_INTERFACE(material), M3G_INVALID_VALUE);
315 return 0; /* Error */
319 * \brief Set material shininess.
321 * \param hMaterial Material object
322 * \param shininess shininess
324 M3G_API void m3gSetShininess(M3GMaterial hMaterial, M3Gfloat shininess)
326 Material *material = (Material *) hMaterial;
327 M3G_VALIDATE_OBJECT(material);
328 if (!m3gInRangef(shininess, 0.0f, 128.f)) {
329 m3gRaiseError(M3G_INTERFACE(material), M3G_INVALID_VALUE);
332 material->shininess = shininess;
336 * \brief Get material shininess.
338 * \param hMaterial Material object
341 M3G_API GLfloat m3gGetShininess(M3GMaterial hMaterial)
343 Material *material = (Material *) hMaterial;
344 M3G_VALIDATE_OBJECT(material);
345 return material->shininess;
349 * \brief Set vertex color tracking enable.
351 * \param hMaterial Material object
352 * \param enable color tracking enable
354 M3G_API void m3gSetVertexColorTrackingEnable(M3GMaterial hMaterial,
357 Material *material = (Material *) hMaterial;
358 M3G_VALIDATE_OBJECT(material);
359 material->vertexColorTracking = (GLboolean) enable;
363 * \brief Get vertex color tracking enable.
365 * \param hMaterial Material object
366 * \retval M3G_TRUE color tracking enabled
367 * \retval M3G_FALSE color tracking disabled
369 M3G_API M3Gbool m3gIsVertexColorTrackingEnabled(M3GMaterial hMaterial)
371 Material *material = (Material *) hMaterial;
372 M3G_VALIDATE_OBJECT(material);
373 return (M3Gbool) material->vertexColorTracking;