First public contribution.
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: Fog implementation
22 * \brief Fog implementation
25 #ifndef M3G_CORE_INCLUDE
26 # error included by m3g_core.c; do not compile separately.
30 #include "m3g_animationtrack.h"
32 /*----------------------------------------------------------------------
34 *--------------------------------------------------------------------*/
38 * \brief Destroys this Fog object.
40 * \param obj Fog object
42 static void m3gDestroyFog(Object *obj)
44 Fog *fog = (Fog *) obj;
45 M3G_VALIDATE_OBJECT(fog);
47 m3gDestroyObject(&fog->object);
52 * \brief Overloaded Object3D method.
54 * \param property animation property
55 * \retval M3G_TRUE property supported
56 * \retval M3G_FALSE property not supported
58 static M3Gbool m3gFogIsCompatible(M3Gint property)
62 case M3G_ANIM_DENSITY:
63 case M3G_ANIM_FAR_DISTANCE:
64 case M3G_ANIM_NEAR_DISTANCE:
67 return m3gObjectIsCompatible(property);
73 * \brief Overloaded Object3D method.
75 * \param self Fog object
76 * \param property animation property
77 * \param valueSize size of value array
78 * \param value value array
80 static void m3gFogUpdateProperty(Object *self,
83 const M3Gfloat *value)
85 Fog *fog = (Fog *)self;
86 M3G_VALIDATE_OBJECT(fog);
87 M3G_ASSERT_PTR(value);
91 M3G_ASSERT(valueSize >= 3);
92 fog->color = m3gColor3f(value[0], value[1], value[2]) & M3G_RGB_MASK;
94 case M3G_ANIM_DENSITY:
95 M3G_ASSERT(valueSize >= 1);
96 fog->density = (value[0] < 0.f) ? 0.f : value[0];
98 case M3G_ANIM_FAR_DISTANCE:
99 M3G_ASSERT(valueSize >= 1);
102 case M3G_ANIM_NEAR_DISTANCE:
103 M3G_ASSERT(valueSize >= 1);
104 fog->start = value[0];
107 m3gObjectUpdateProperty(self, property, valueSize, value);
113 * \brief Overloaded Object3D method.
115 * \param originalObj original Fog object
116 * \param cloneObj pointer to cloned Fog object
117 * \param pairs array for all object-duplicate pairs
118 * \param numPairs number of pairs
120 static M3Gbool m3gFogDuplicate(const Object *originalObj,
125 Fog *original = (Fog *)originalObj;
126 Fog *clone = (Fog *)m3gCreateFog(originalObj->interface);
127 *cloneObj = (Object *)clone;
128 if (*cloneObj == NULL) {
132 if(m3gObjectDuplicate(originalObj, cloneObj, pairs, numPairs)) {
133 clone->color = original->color;
134 clone->density = original->density;
135 clone->start = original->start;
136 clone->end = original->end;
137 clone->mode = original->mode;
147 * \brief Initializes a Fog object. See specification
148 * for default values.
150 * \param m3g M3G interface
151 * \param fog Fog object
153 static void m3gInitFog(Interface *m3g, Fog *fog)
155 /* Fog is derived from object */
156 m3gInitObject(&fog->object, m3g, M3G_CLASS_FOG);
161 fog->mode = M3G_LINEAR_FOG;
166 * \brief Applies fog to OpenGL. This is used for
169 * \param self Fog object
171 static void m3gApplyFog(const Fog *self)
176 m3gGLColor(self->color, temp);
178 switch (self->mode) {
181 glFogf(GL_FOG_MODE, GL_LINEAR);
182 glFogf(GL_FOG_START, self->start);
183 glFogf(GL_FOG_END, self->end);
184 glFogxv(GL_FOG_COLOR, temp);
186 case M3G_EXPONENTIAL_FOG:
188 glFogf(GL_FOG_MODE, GL_EXP);
189 glFogf(GL_FOG_DENSITY, self->density);
190 glFogxv(GL_FOG_COLOR, temp);
200 #ifdef M3G_USE_NGL_API
203 * \brief Applies fog to NGL. This is used for
204 * Sprite3D objects only.
206 * \param self Fog object
207 * \param eyeZ Eye space Z (e.g. after modelview)
208 * \param finalZ Final Z (e.g. after modelview and projection)
210 static void m3gApplySpriteFog(const Fog *self, M3Gfloat eyeZ, M3Gfloat finalZ)
214 M3Gfloat fogValue = 1;
216 /* Calculate fog value and use OpenGL linear fog
217 * to result in same value. Sprites are drawn with
218 * identity MV and P and therefore the fog has to
219 * be adjusted like this */
220 switch (self->mode) {
222 fogValue = m3gDiv(m3gAdd(self->end, eyeZ), m3gSub(self->end, self->start));
224 case M3G_EXPONENTIAL_FOG:
225 fogValue = m3gExp(m3gMul(self->density, eyeZ));
228 M3G_ASSERT(M3G_FALSE);
232 m3gGLColor(self->color, temp);
235 glFogf(GL_FOG_MODE, GL_LINEAR);
237 /* NGL works differently in fog calculation */
238 glFogf(GL_FOG_START, -m3gDiv(finalZ, fogValue));
239 glFogf(GL_FOG_END, 0.f);
240 glFogxv(GL_FOG_COLOR, temp);
247 /*----------------------------------------------------------------------
248 * Virtual function table
249 *--------------------------------------------------------------------*/
251 static const ObjectVFTable m3gvf_Fog = {
252 m3gObjectApplyAnimation,
254 m3gFogUpdateProperty,
255 m3gObjectDoGetReferences,
262 /*----------------------------------------------------------------------
263 * Public API functions
264 *--------------------------------------------------------------------*/
267 * \brief Creates a Fog object.
269 * \param interface M3G interface
270 * \retval Fog new Fog object
271 * \retval NULL Fog creating failed
273 M3G_API M3GFog m3gCreateFog(M3GInterface interface)
275 Interface *m3g = (Interface *) interface;
276 M3G_VALIDATE_INTERFACE(m3g);
279 Fog *fog = m3gAllocZ(m3g, sizeof(Fog));
282 m3gInitFog(m3g, fog);
290 * \brief Sets fog mode.
292 * \param handle Fog object
293 * \param mode fog mode
295 M3G_API void m3gSetFogMode(M3GFog handle, M3Gint mode)
297 Fog *fog = (Fog *) handle;
298 M3G_VALIDATE_OBJECT(fog);
300 /* Check for errors */
301 if(mode < M3G_EXPONENTIAL_FOG || mode > M3G_LINEAR_FOG) {
302 m3gRaiseError(M3G_INTERFACE(fog), M3G_INVALID_VALUE);
310 * \brief Gets fog mode.
312 * \param handle Fog object
315 M3G_API M3Gint m3gGetFogMode(M3GFog handle)
317 Fog *fog = (Fog *) handle;
318 M3G_VALIDATE_OBJECT(fog);
324 * \brief Sets linear fog parameters.
326 * \param handle Fog object
327 * \param fogNear near distance
328 * \param fogFar far distance
330 M3G_API void m3gSetFogLinear(M3GFog handle, M3Gfloat fogNear, M3Gfloat fogFar)
332 Fog *fog = (Fog *) handle;
333 M3G_VALIDATE_OBJECT(fog);
335 fog->start = fogNear;
340 * \brief Gets linear fog parameters.
342 * \param handle Fog object
343 * \param which which parameter to return
346 * \return near or far distance
348 M3G_API M3Gfloat m3gGetFogDistance(M3GFog handle, M3Gint which)
350 Fog *fog = (Fog *) handle;
351 M3G_VALIDATE_OBJECT(fog);
363 * \brief Sets exponential fog density.
365 * \param handle Fog object
366 * \param density fog density
368 M3G_API void m3gSetFogDensity(M3GFog handle, M3Gfloat density)
370 Fog *fog = (Fog *) handle;
371 M3G_VALIDATE_OBJECT(fog);
374 m3gRaiseError(M3G_INTERFACE(fog), M3G_INVALID_VALUE);
378 fog->density = density;
382 * \brief Gets exponential fog density.
384 * \param handle Fog object
385 * \return fog density
387 M3G_API M3Gfloat m3gGetFogDensity(M3GFog handle)
389 Fog *fog = (Fog *) handle;
390 M3G_VALIDATE_OBJECT(fog);
396 * \brief Sets fog color as RGB.
398 * \param handle Fog object
399 * \param rgb fog color as RGB
401 M3G_API void m3gSetFogColor(M3GFog handle, M3Guint rgb)
403 Fog *fog = (Fog *) handle;
404 M3G_VALIDATE_OBJECT(fog);
406 fog->color = rgb & M3G_RGB_MASK;
410 * \brief Gets fog color as RGB.
412 * \param handle Fog object
413 * \return fog color as RGB
415 M3G_API M3Guint m3gGetFogColor(M3GFog handle)
417 Fog *fog = (Fog *) handle;
418 M3G_VALIDATE_OBJECT(fog);