1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  */
16 
17 #pragma once
18 
19 /** \file
20  * \ingroup freestyle
21  * \brief Class used to handle materials.
22  */
23 
24 #include "../system/FreestyleConfig.h"
25 
26 #ifdef WITH_CXX_GUARDEDALLOC
27 #  include "MEM_guardedalloc.h"
28 #endif
29 
30 namespace Freestyle {
31 
32 /*! Class defining a material */
33 class FrsMaterial {
34  public:
35   /*! Default constructor */
36   inline FrsMaterial();
37 
38   /*! Builds a Material from its line, diffuse, ambient, specular, emissive
39    *  colors, a shininess coefficient and line color priority.
40    *    \param iLine:
41    *      A 4 element float-array containing the line color.
42    *    \param iDiffuse:
43    *      A 4 element float-array containing the diffuse color.
44    *    \param iAmbiant:
45    *      A 4 element float-array containing the ambient color.
46    *    \param iSpecular:
47    *      A 4 element float-array containing the specular color.
48    *    \param iEmission:
49    *      A 4 element float-array containing the emissive color.
50    *    \param iShininess:
51    *      The shininess coefficient.
52    *    \param iPriority:
53    *      The line color priority.
54    */
55   inline FrsMaterial(const float *iLine,
56                      const float *iDiffuse,
57                      const float *iAmbiant,
58                      const float *iSpecular,
59                      const float *iEmission,
60                      const float iShininess,
61                      const int iPriority);
62 
63   /*! Copy constructor */
64   inline FrsMaterial(const FrsMaterial &m);
65 
66   /*! Destructor */
~FrsMaterial()67   virtual ~FrsMaterial()
68   {
69   }
70 
71   /*! Returns the line color as a 4 float array */
line()72   inline const float *line() const
73   {
74     return Line;
75   }
76 
77   /*! Returns the red component of the line color */
lineR()78   inline const float lineR() const
79   {
80     return Line[0];
81   }
82 
83   /*! Returns the green component of the line color */
lineG()84   inline const float lineG() const
85   {
86     return Line[1];
87   }
88 
89   /*! Returns the blue component of the line color */
lineB()90   inline const float lineB() const
91   {
92     return Line[2];
93   }
94 
95   /*! Returns the alpha component of the line color */
lineA()96   inline const float lineA() const
97   {
98     return Line[3];
99   }
100 
101   /*! Returns the diffuse color as a 4 float array */
diffuse()102   inline const float *diffuse() const
103   {
104     return Diffuse;
105   }
106 
107   /*! Returns the red component of the diffuse color */
diffuseR()108   inline const float diffuseR() const
109   {
110     return Diffuse[0];
111   }
112 
113   /*! Returns the green component of the diffuse color */
diffuseG()114   inline const float diffuseG() const
115   {
116     return Diffuse[1];
117   }
118 
119   /*! Returns the blue component of the diffuse color */
diffuseB()120   inline const float diffuseB() const
121   {
122     return Diffuse[2];
123   }
124 
125   /*! Returns the alpha component of the diffuse color */
diffuseA()126   inline const float diffuseA() const
127   {
128     return Diffuse[3];
129   }
130 
131   /*! Returns the specular color as a 4 float array */
specular()132   inline const float *specular() const
133   {
134     return Specular;
135   }
136 
137   /*! Returns the red component of the specular color */
specularR()138   inline const float specularR() const
139   {
140     return Specular[0];
141   }
142 
143   /*! Returns the green component of the specular color */
specularG()144   inline const float specularG() const
145   {
146     return Specular[1];
147   }
148 
149   /*! Returns the blue component of the specular color */
specularB()150   inline const float specularB() const
151   {
152     return Specular[2];
153   }
154 
155   /*! Returns the alpha component of the specular color */
specularA()156   inline const float specularA() const
157   {
158     return Specular[3];
159   }
160 
161   /*! Returns the ambient color as a 4 float array */
ambient()162   inline const float *ambient() const
163   {
164     return Ambient;
165   }
166 
167   /*! Returns the red component of the ambient color */
ambientR()168   inline const float ambientR() const
169   {
170     return Ambient[0];
171   }
172 
173   /*! Returns the green component of the ambient color */
ambientG()174   inline const float ambientG() const
175   {
176     return Ambient[1];
177   }
178 
179   /*! Returns the blue component of the ambient color */
ambientB()180   inline const float ambientB() const
181   {
182     return Ambient[2];
183   }
184 
185   /*! Returns the alpha component of the ambient color */
ambientA()186   inline const float ambientA() const
187   {
188     return Ambient[3];
189   }
190 
191   /*! Returns the emissive color as a 4 float array */
emission()192   inline const float *emission() const
193   {
194     return Emission;
195   }
196 
197   /*! Returns the red component of the emissive color */
emissionR()198   inline const float emissionR() const
199   {
200     return Emission[0];
201   }
202 
203   /*! Returns the green component of the emissive color */
emissionG()204   inline const float emissionG() const
205   {
206     return Emission[1];
207   }
208 
209   /*! Returns the blue component of the emissive color */
emissionB()210   inline const float emissionB() const
211   {
212     return Emission[2];
213   }
214 
215   /*! Returns the alpha component of the emissive color */
emissionA()216   inline const float emissionA() const
217   {
218     return Emission[3];
219   }
220 
221   /*! Returns the shininess coefficient */
shininess()222   inline const float shininess() const
223   {
224     return Shininess;
225   }
226 
227   /*! Returns the line color priority */
priority()228   inline const int priority() const
229   {
230     return Priority;
231   }
232 
233   /*! Sets the line color.
234    *    \param r:
235    *      Red component
236    *    \param g:
237    *      Green component
238    *    \param b:
239    *     Blue component
240    *    \param a:
241    *      Alpha component
242    */
243   inline void setLine(const float r, const float g, const float b, const float a);
244 
245   /*! Sets the diffuse color.
246    *    \param r:
247    *      Red component
248    *    \param g:
249    *      Green component
250    *    \param b:
251    *     Blue component
252    *    \param a:
253    *      Alpha component
254    */
255   inline void setDiffuse(const float r, const float g, const float b, const float a);
256 
257   /*! Sets the specular color.
258    *    \param r:
259    *      Red component
260    *    \param g:
261    *      Green component
262    *    \param b:
263    *     Blue component
264    *    \param a:
265    *      Alpha component
266    */
267   inline void setSpecular(const float r, const float g, const float b, const float a);
268 
269   /*! Sets the ambient color.
270    *    \param r:
271    *      Red component
272    *    \param g:
273    *      Green component
274    *    \param b:
275    *     Blue component
276    *    \param a:
277    *      Alpha component
278    */
279   inline void setAmbient(const float r, const float g, const float b, const float a);
280 
281   /*! Sets the emissive color.
282    *    \param r:
283    *      Red component
284    *    \param g:
285    *      Green component
286    *    \param b:
287    *     Blue component
288    *    \param a:
289    *      Alpha component
290    */
291   inline void setEmission(const float r, const float g, const float b, const float a);
292 
293   /*! Sets the shininess.
294    *    \param s:
295    *      Shininess
296    */
297   inline void setShininess(const float s);
298 
299   /*! Sets the line color priority.
300    *    \param priority:
301    *      Priority
302    */
303   inline void setPriority(const int priority);
304 
305   /* operators */
306   inline FrsMaterial &operator=(const FrsMaterial &m);
307   inline bool operator!=(const FrsMaterial &m) const;
308   inline bool operator==(const FrsMaterial &m) const;
309 
310  private:
311   /*! Material properties */
312   float Line[4];
313   float Diffuse[4];
314   float Specular[4];
315   float Ambient[4];
316   float Emission[4];
317   float Shininess;
318   int Priority;
319 
320 #ifdef WITH_CXX_GUARDEDALLOC
321   MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:FrsMaterial")
322 #endif
323 };
324 
FrsMaterial()325 FrsMaterial::FrsMaterial()
326 {
327   Line[0] = Line[1] = Line[2] = 0.0f;
328   Line[3] = 1.0f;
329 
330   Ambient[0] = Ambient[1] = Ambient[2] = 0.2f;
331   Ambient[3] = 1.0f;
332 
333   Diffuse[0] = Diffuse[1] = Diffuse[2] = 0.8f;
334   Diffuse[3] = 1.0f;
335 
336   Emission[0] = Emission[1] = Emission[2] = 0.0f;
337   Emission[3] = 1.0f;
338 
339   Specular[0] = Specular[1] = Specular[2] = 0.0f;
340   Specular[3] = 1.0f;
341 
342   Shininess = 0.0f;
343   Priority = 0;
344 }
345 
FrsMaterial(const float * iLine,const float * iDiffuse,const float * iAmbiant,const float * iSpecular,const float * iEmission,const float iShininess,const int iPriority)346 FrsMaterial::FrsMaterial(const float *iLine,
347                          const float *iDiffuse,
348                          const float *iAmbiant,
349                          const float *iSpecular,
350                          const float *iEmission,
351                          const float iShininess,
352                          const int iPriority)
353 {
354   for (int i = 0; i < 4; i++) {
355     Line[i] = iLine[i];
356     Diffuse[i] = iDiffuse[i];
357     Specular[i] = iSpecular[i];
358     Ambient[i] = iAmbiant[i];
359     Emission[i] = iEmission[i];
360   }
361 
362   Shininess = iShininess;
363   Priority = iPriority;
364 }
365 
FrsMaterial(const FrsMaterial & m)366 FrsMaterial::FrsMaterial(const FrsMaterial &m)
367 {
368   for (int i = 0; i < 4; i++) {
369     Line[i] = m.line()[i];
370     Diffuse[i] = m.diffuse()[i];
371     Specular[i] = m.specular()[i];
372     Ambient[i] = m.ambient()[i];
373     Emission[i] = m.emission()[i];
374   }
375 
376   Shininess = m.shininess();
377   Priority = m.priority();
378 }
379 
setLine(const float r,const float g,const float b,const float a)380 void FrsMaterial::setLine(const float r, const float g, const float b, const float a)
381 {
382   Line[0] = r;
383   Line[1] = g;
384   Line[2] = b;
385   Line[3] = a;
386 }
387 
setDiffuse(const float r,const float g,const float b,const float a)388 void FrsMaterial::setDiffuse(const float r, const float g, const float b, const float a)
389 {
390   Diffuse[0] = r;
391   Diffuse[1] = g;
392   Diffuse[2] = b;
393   Diffuse[3] = a;
394 }
395 
setSpecular(const float r,const float g,const float b,const float a)396 void FrsMaterial::setSpecular(const float r, const float g, const float b, const float a)
397 {
398   Specular[0] = r;
399   Specular[1] = g;
400   Specular[2] = b;
401   Specular[3] = a;
402 }
403 
setAmbient(const float r,const float g,const float b,const float a)404 void FrsMaterial::setAmbient(const float r, const float g, const float b, const float a)
405 {
406   Ambient[0] = r;
407   Ambient[1] = g;
408   Ambient[2] = b;
409   Ambient[3] = a;
410 }
411 
setEmission(const float r,const float g,const float b,const float a)412 void FrsMaterial::setEmission(const float r, const float g, const float b, const float a)
413 {
414   Emission[0] = r;
415   Emission[1] = g;
416   Emission[2] = b;
417   Emission[3] = a;
418 }
419 
setShininess(const float s)420 void FrsMaterial::setShininess(const float s)
421 {
422   Shininess = s;
423 }
424 
setPriority(const int priority)425 void FrsMaterial::setPriority(const int priority)
426 {
427   Priority = priority;
428 }
429 
430 FrsMaterial &FrsMaterial::operator=(const FrsMaterial &m)
431 {
432   for (int i = 0; i < 4; i++) {
433     Line[i] = m.line()[i];
434     Diffuse[i] = m.diffuse()[i];
435     Specular[i] = m.specular()[i];
436     Ambient[i] = m.ambient()[i];
437     Emission[i] = m.emission()[i];
438   }
439 
440   Shininess = m.shininess();
441   Priority = m.priority();
442   return *this;
443 }
444 
445 bool FrsMaterial::operator!=(const FrsMaterial &m) const
446 {
447   if (Shininess != m.shininess()) {
448     return true;
449   }
450   if (Priority != m.priority()) {
451     return true;
452   }
453 
454   for (int i = 0; i < 4; i++) {
455     if (Line[i] != m.line()[i]) {
456       return true;
457     }
458     if (Diffuse[i] != m.diffuse()[i]) {
459       return true;
460     }
461     if (Specular[i] != m.specular()[i]) {
462       return true;
463     }
464     if (Ambient[i] != m.ambient()[i]) {
465       return true;
466     }
467     if (Emission[i] != m.emission()[i]) {
468       return true;
469     }
470   }
471 
472   return false;
473 }
474 
475 bool FrsMaterial::operator==(const FrsMaterial &m) const
476 {
477   return (!((*this) != m));
478 }
479 
480 } /* namespace Freestyle */
481