Developer Documentation
MaterialNode.cc
1 /*===========================================================================*\
2  * *
3  * OpenFlipper *
4  * Copyright (c) 2001-2015, RWTH-Aachen University *
5  * Department of Computer Graphics and Multimedia *
6  * All rights reserved. *
7  * www.openflipper.org *
8  * *
9  *---------------------------------------------------------------------------*
10  * This file is part of OpenFlipper. *
11  *---------------------------------------------------------------------------*
12  * *
13  * Redistribution and use in source and binary forms, with or without *
14  * modification, are permitted provided that the following conditions *
15  * are met: *
16  * *
17  * 1. Redistributions of source code must retain the above copyright notice, *
18  * this list of conditions and the following disclaimer. *
19  * *
20  * 2. Redistributions in binary form must reproduce the above copyright *
21  * notice, this list of conditions and the following disclaimer in the *
22  * documentation and/or other materials provided with the distribution. *
23  * *
24  * 3. Neither the name of the copyright holder nor the names of its *
25  * contributors may be used to endorse or promote products derived from *
26  * this software without specific prior written permission. *
27  * *
28  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
29  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
30  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
31  * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
32  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, *
33  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *
34  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR *
35  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
36  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *
37  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
38  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
39  * *
40 \*===========================================================================*/
41 
42 
43 
44 
45 
46 
47 //=============================================================================
48 //
49 // CLASS MaterialNode - IMPLEMENTATION
50 //
51 //=============================================================================
52 
53 
54 //== INCLUDES =================================================================
55 
56 
57 #include "MaterialNode.hh"
58 
59 #include <cstdio>
60 #include <sstream>
61 
62 #if QT_VERSION >= 0x050000
63 #include <QJsonDocument>
64 #include <QJsonObject>
65 #elif defined(ENABLE_QJSON)
66 #include <QJson/Serializer>
67 #include <QJson/Parser>
68 #endif
69 
70 #if defined(ENABLE_QJSON) || QT_VERSION >= 0x050000
71 #define JSON_SERIALIZABLE 1
72 #else
73 #define JSON_SERIALIZABLE 0
74 #endif
75 
76 //== NAMESPACES ===============================================================
77 
78 namespace {
79 
80 enum ClassProperties {
81 #if JSON_SERIALIZABLE
82  CP_JSON_SERIALIZABLE = 1
83 #else
84  CP_JSON_SERIALIZABLE = 0
85 #endif
86 };
87 
88 inline QVariantList col2vl(const ACG::Vec4f &col) {
89  return QVariantList() << col[0] << col[1] << col[2] << col[3];
90 }
91 
92 inline ACG::Vec4f vl2col(const QVariantList &vl) {
93  if (vl.size() < 4) return ACG::Vec4f();
94  return ACG::Vec4f(vl[0].toFloat(), vl[1].toFloat(), vl[2].toFloat(), vl[3].toFloat());
95 }
96 
97 } /* anonymous namespace */
98 
99 namespace ACG {
100 
101 QVariantMap json_to_variant_map(QString json) {
102 #ifdef ENABLE_QJSON
103  QJson::Parser parser;
104  bool ok;
105  QVariantMap matMap = parser.parse(json.toUtf8(), &ok).toMap();
106  if (!ok) return QVariantMap();
107  return matMap;
108 #elif QT_VERSION >= 0x050000
109  QJsonParseError error;
110  QJsonDocument jsonDoc = QJsonDocument::fromJson(json.toUtf8(), &error);
111  if (error.error != QJsonParseError::NoError || !jsonDoc.isObject())
112  return QVariantMap();
113  return jsonDoc.object().toVariantMap();
114 #else
115  return QVariantMap();
116 #endif
117 }
118 
119 namespace SceneGraph {
120 
121 
122 //== IMPLEMENTATION ==========================================================
123 
124 bool Material::support_json_serialization() {
125  return CP_JSON_SERIALIZABLE;
126 }
127 
128 QString Material::serializeToJson() const {
129 #if JSON_SERIALIZABLE
130  QVariantMap matMap;
131 
132  matMap["baseColor"] = col2vl(baseColor_);
133  matMap["ambientColor"] = col2vl(ambientColor_);
134  matMap["diffuseColor"] = col2vl(diffuseColor_);
135  matMap["specularColor"] = col2vl(specularColor_);
136  matMap["overlayColor"] = col2vl(overlayColor_);
137  matMap["shininess"] = shininess_;
138  matMap["reflectance"] = reflectance_;
139  matMap["indexOfRefraction"] = indexOfRefraction_;
140  matMap["isRefractive"] = isRefractive_;
141  matMap["pointSize"] = pointSize_;
142  matMap["lineWidth"] = lineWidth_;
143  matMap["roundPoints"] = roundPoints_;
144  matMap["linesSmooth"] = linesSmooth_;
145  matMap["alphaTest"] = alphaTest_;
146  matMap["alphaClip"] = alphaClip_;
147  matMap["blending"] = blending_;
148  matMap["blendParam1"] = blendParam1_;
149  matMap["blendParam2"] = blendParam2_;
150  matMap["colorMaterial"] = colorMaterial_;
151  matMap["backfaceCulling"] = backfaceCulling_;
152  matMap["multiSampling"] = multiSampling_;
153 
154 #ifdef ENABLE_QJSON
155  QJson::Serializer serializer;
156  QByteArray bytes = serializer.serialize(matMap);
157  return QString::fromUtf8(bytes.constData(), bytes.size());
158 #elif QT_VERSION >= 0x050000
159  const QJsonDocument json_doc(QJsonObject::fromVariantMap(matMap));
160  return QString::fromUtf8(
161  json_doc.toJson(QJsonDocument::Indented));
162 #endif
163 
164 #else
165  return QString("<No suitable serializer at the moment. Sorry.>");
166 #endif
167 }
168 
169 void Material::deserializeFromVariantMap(const QVariantMap &matMap) {
170  if (matMap.contains("baseColor")) baseColor_ = vl2col(matMap["baseColor"].toList());
171  if (matMap.contains("ambientColor")) ambientColor_ = vl2col(matMap["ambientColor"].toList());
172  if (matMap.contains("diffuseColor")) diffuseColor_ = vl2col(matMap["diffuseColor"].toList());
173  if (matMap.contains("specularColor")) specularColor_ = vl2col(matMap["specularColor"].toList());
174  if (matMap.contains("overlayColor")) overlayColor_ = vl2col(matMap["overlayColor"].toList());
175  if (matMap.contains("shininess")) shininess_ = matMap["shininess"].toFloat();
176  if (matMap.contains("reflectance")) reflectance_ = matMap["reflectance"].toDouble();
177  if (matMap.contains("indexOfRefraction")) indexOfRefraction_ = matMap["indexOfRefraction"].toDouble();
178  if (matMap.contains("isRefractive")) isRefractive_ = matMap["isRefractive"].toBool();
179  if (matMap.contains("pointSize")) pointSize_ = matMap["pointSize"].toFloat();
180  if (matMap.contains("lineWidth")) lineWidth_ = matMap["lineWidth"].toFloat();
181  if (matMap.contains("roundPoints")) roundPoints_ = matMap["roundPoints"].toBool();
182  if (matMap.contains("linesSmooth")) linesSmooth_ = matMap["linesSmooth"].toBool();
183  if (matMap.contains("alphaTest")) alphaTest_ = matMap["alphaTest"].toBool();
184  if (matMap.contains("alphaClip")) alphaClip_ = matMap["alphaClip"].toFloat();
185  if (matMap.contains("blending")) blending_ = matMap["blending"].toBool();
186  if (matMap.contains("blendParam1")) blendParam1_ = matMap["blendParam1"].toUInt();
187  if (matMap.contains("blendParam2")) blendParam2_ = matMap["blendParam2"].toUInt();
188  if (matMap.contains("colorMaterial")) colorMaterial_ = matMap["colorMaterial"].toBool();
189  if (matMap.contains("backfaceCulling")) backfaceCulling_ = matMap["backfaceCulling"].toBool();
190  if (matMap.contains("multiSampling")) multiSampling_ = matMap["multiSampling"].toBool();
191 }
192 
193 void Material::deserializeFromJson(const QString &json) {
194  deserializeFromVariantMap(ACG::json_to_variant_map(json));
195 }
196 
198  const std::string& _name,
199  unsigned int _applyProperties )
200  : BaseNode(_parent, _name),
201  applyProperties_(_applyProperties)
202 {}
203 
204 
205 //----------------------------------------------------------------------------
206 
207 
208 void MaterialNode::enter(GLState& _state, const DrawModes::DrawMode& _drawmode )
209 {
211  {
212  materialBackup_.baseColor_ = _state.base_color();
213  _state.set_base_color(material_.baseColor_);
214  }
215 
217  {
218  materialBackup_.ambientColor_ = _state.ambient_color();
219  materialBackup_.diffuseColor_ = _state.diffuse_color();
220  materialBackup_.specularColor_ = _state.specular_color();
221  materialBackup_.overlayColor_ = _state.overlay_color();
222  materialBackup_.shininess_ = _state.shininess();
223 
224  _state.set_ambient_color(material_.ambientColor_);
225  _state.set_diffuse_color(material_.diffuseColor_);
226  _state.set_specular_color(material_.specularColor_);
227  _state.set_overlay_color(material_.overlayColor_);
228  _state.set_shininess(material_.shininess_);
229  }
230 
232  {
233  materialBackup_.pointSize_ = _state.point_size();
234  _state.set_point_size(material_.pointSize_);
235  }
236 
238  {
239  materialBackup_.lineWidth_ = _state.line_width();
240  _state.set_line_width(material_.lineWidth_);
241  }
242 
243  if (_state.compatibilityProfile())
244  {
245  // deprecated opengl caps
246 
248  {
249  materialBackup_.roundPoints_ = glIsEnabled(GL_POINT_SMOOTH) &&
250  glIsEnabled(GL_ALPHA_TEST);
251 
252  if (material_.roundPoints_) {
253  glHint(GL_POINT_SMOOTH_HINT, GL_NICEST);
254  ACG::GLState::enable(GL_POINT_SMOOTH);
255  }
256  else
257  ACG::GLState::disable(GL_POINT_SMOOTH);
258  }
259 
261  {
262  materialBackup_.linesSmooth_ = glIsEnabled(GL_LINE_SMOOTH) &&
263  glIsEnabled(GL_ALPHA_TEST);
264 
265  if (material_.linesSmooth_) {
266  glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
267  ACG::GLState::enable(GL_LINE_SMOOTH);
268  }
269  else
270  ACG::GLState::disable(GL_LINE_SMOOTH);
271  }
272 
274  {
275  materialBackup_.alphaTest_ = glIsEnabled(GL_ALPHA_TEST);
276  glGetFloatv(GL_ALPHA_TEST_REF, &materialBackup_.alphaClip_);
277 
278  if (material_.alphaTest_)
279  {
280  ACG::GLState::alphaFunc(GL_GREATER, material_.alphaClip_);
281  ACG::GLState::enable(GL_ALPHA_TEST);
282  }
283  else
284  {
285  ACG::GLState::disable(GL_ALPHA_TEST);
286  }
287  }
288 
289  }
290 
292  {
293  materialBackup_.multiSampling_ = _state.multisampling();
294  _state.set_multisampling( material_.multiSampling_ );
295  }
296 
297 
299  {
300  materialBackup_.blending_ = _state.blending();
301  glGetIntegerv( GL_BLEND_SRC, (GLint*) &materialBackup_.blendParam1_);
302  glGetIntegerv( GL_BLEND_DST, (GLint*) &materialBackup_.blendParam2_);
303 
304  _state.set_blending(material_.blending_);
305 
306  if (material_.blending_)
307  {
308  _state.set_depthFunc(GL_LEQUAL);
309  ACG::GLState::blendFunc(material_.blendingParam1(), material_.blendingParam2());
310  ACG::GLState::enable(GL_BLEND);
311  }
312  else
313  {
314  _state.set_depthFunc(GL_LESS);
315  ACG::GLState::disable(GL_BLEND);
316  }
317  }
318 
319 
321  {
322  materialBackup_.backfaceCulling_ = glIsEnabled(GL_CULL_FACE);
323 
324  if ( material_.backfaceCulling_ )
325  ACG::GLState::enable( GL_CULL_FACE );
326  else
327  ACG::GLState::disable( GL_CULL_FACE );
328 
329  }
330 
332  {
333  materialBackup_.colorMaterial_ = glIsEnabled(GL_COLOR_MATERIAL);
334 
335  if(_state.compatibilityProfile())
336  {
337  if (material_.colorMaterial_ ) {
338  ACG::GLState::disable( GL_COLOR_MATERIAL );
339  glColorMaterial( GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE );
340  ACG::GLState::enable( GL_COLOR_MATERIAL );
341  } else
342  ACG::GLState::disable( GL_COLOR_MATERIAL );
343  }
344  }
345 
346 }
347 
348 //----------------------------------------------------------------------------
349 
350 void MaterialNode::enterPick(GLState& _state , PickTarget /*_target*/, const DrawModes::DrawMode& /*_drawMode*/ ) {
351 
353  {
354  materialBackup_.pointSize_ = _state.point_size();
355  _state.set_point_size(material_.pointSize_);
356  }
357 
359  {
360  materialBackup_.lineWidth_ = _state.line_width();
361  _state.set_line_width(material_.lineWidth_);
362  }
363 }
364 
365 void MaterialNode::leavePick(GLState& _state, PickTarget /*_target*/, const DrawModes::DrawMode& /*_drawMode*/ ) {
366 
368  {
369  _state.set_point_size(materialBackup_.pointSize_);
370  }
371 
372 
374  {
375  _state.set_line_width(materialBackup_.lineWidth_);
376  }
377 }
378 
379 
380 //----------------------------------------------------------------------------
381 
382 
383 void MaterialNode::leave(GLState& _state, const DrawModes::DrawMode& _drawmode )
384 {
386  {
387  _state.set_base_color(materialBackup_.baseColor_);
388  }
389 
390 
392  {
393  _state.set_ambient_color(materialBackup_.ambientColor_);
394  _state.set_diffuse_color(materialBackup_.diffuseColor_);
395  _state.set_specular_color(materialBackup_.specularColor_);
396  _state.set_overlay_color(materialBackup_.overlayColor_);
397  _state.set_shininess(materialBackup_.shininess_);
398  }
399 
400 
402  {
403  _state.set_point_size(materialBackup_.pointSize_);
404  }
405 
406 
408  {
409  _state.set_line_width(materialBackup_.lineWidth_);
410  }
411 
412 
413  if ((applyProperties_ & RoundPoints) && _state.compatibilityProfile())
414  {
415  if( materialBackup_.roundPoints_)
416  ACG::GLState::enable(GL_POINT_SMOOTH);
417  else
418  ACG::GLState::disable(GL_POINT_SMOOTH);
419  }
420 
421  if ((applyProperties_ & LineSmooth) && _state.compatibilityProfile())
422  {
423  if( materialBackup_.linesSmooth_)
424  ACG::GLState::enable(GL_LINE_SMOOTH);
425  else
426  ACG::GLState::disable(GL_LINE_SMOOTH);
427  }
428 
430  _state.set_multisampling( materialBackup_.multiSampling_ );
431 
432  if ((applyProperties_ & AlphaTest) && _state.compatibilityProfile())
433  {
434  if (materialBackup_.alphaTest_)
435  {
436  ACG::GLState::alphaFunc(GL_GREATER, materialBackup_.alphaClip_);
437  ACG::GLState::enable(GL_ALPHA_TEST);
438  }
439  else
440  {
441  ACG::GLState::disable(GL_ALPHA_TEST);
442  }
443  }
444 
445 
447  {
448  _state.set_blending(materialBackup_.blending_);
449 
450  if (materialBackup_.blending_)
451  {
452  _state.set_depthFunc(GL_LEQUAL);
453  ACG::GLState::blendFunc(materialBackup_.blendParam1_, materialBackup_.blendParam2_);
454  ACG::GLState::enable(GL_BLEND);
455  }
456  else
457  {
458  _state.set_depthFunc(GL_LESS);
459  ACG::GLState::disable(GL_BLEND);
460  }
461  }
462 
463 
465  {
466  if (materialBackup_.backfaceCulling_)
467  ACG::GLState::enable( GL_CULL_FACE );
468  else
469  ACG::GLState::disable( GL_CULL_FACE );
470  }
471 
473  {
474  if(_state.compatibilityProfile())
475  {
476  if (materialBackup_.colorMaterial_ ) {
477  ACG::GLState::enable( GL_COLOR_MATERIAL );
478  } else
479  ACG::GLState::disable( GL_COLOR_MATERIAL );
480  }
481  }
482 
483 }
484 
485 
486 //----------------------------------------------------------------------------
487 
488 
489 void
490 MaterialNode::read(std::istream& _is)
491 {
492 
493  char s[200];
494  float x, y, z, u;
495  bool b;
496 
497  while (_is && (!_is.eof()) && _is.getline(s,200) ) {
498  std::istringstream buffer(s);
499 
500  // comment or empty
501  if ( s[0] == '#')
502  continue;
503 
504  std::string specifier = "";
505 
506  // Read specifier from buffer
507  buffer >> specifier;
508 
509  // BaseColor
510  if (specifier == "BaseColor") {
511  buffer >> x >> y >> z >> u;
512 
513  if (buffer.good()) {
514  material_.baseColor(Vec4f(x, y, z, u));
515  }
516  }
517  // AmbientColor
518  else if (specifier == "AmbientColor") {
519  buffer >> x >> y >> z >> u;
520 
521  if (buffer.good()) {
522  material_.ambientColor(Vec4f(x, y, z, u));
523  }
524  }
525  // DiffuseColor
526  else if (specifier == "DiffuseColor") {
527  buffer >> x >> y >> z >> u;
528 
529  if (buffer.good()) {
530  material_.diffuseColor(Vec4f(x, y, z, u));
531  }
532  }
533  // SpecularColor
534  else if (specifier == "SpecularColor") {
535  buffer >> x >> y >> z >> u;
536 
537  if (buffer.good()) {
538  material_.specularColor(Vec4f(x, y, z, u));
539  }
540  }
541  // OverlayColor
542  else if (specifier == "OverlayColor") {
543  buffer >> x >> y >> z >> u;
544 
545  if (buffer.good()) {
546  material_.overlayColor(Vec4f(x, y, z, u));
547  }
548  }
549  // Shininess
550  else if (specifier == "Shininess") {
551  buffer >> x;
552 
553  if (buffer.good()) {
554  material_.shininess(x);
555  }
556  }
557  // Refractive
558  else if (specifier == "isRefractive") {
559  buffer >> b;
560 
561  if (buffer.good()) {
563  }
564  }
565  // Refraction Index
566  else if (specifier == "indexOfRefraction") {
567  buffer >> x;
568 
569  if (buffer.good()) {
571  }
572  }
573  // PointSize
574  else if (specifier == "PointSize") {
575  buffer >> x;
576 
577  if (buffer.good()) {
578  material_.pointSize(x);
579  }
580  }
581  // LineWidth
582  else if (specifier == "LineWidth") {
583  buffer >> x;
584 
585  if (buffer.good()) {
586  material_.lineWidth(x);
587  }
588  }
589 
590  if (!buffer.good())
591  std::cerr << "MaterialNode parse error while reading string : " << s << std::endl;
592 
593  }
594 }
595 
596 //=============================================================================
597 } // namespace SceneGraph
598 } // namespace ACG
599 //=============================================================================
const Vec4f & specular_color() const
get specular color
Definition: GLState.hh:941
void set_blending(bool _b)
set whether transparent or solid objects should be drawn
Definition: GLState.hh:1033
Namespace providing different geometric functions concerning angles.
MaterialNode(BaseNode *_parent=0, const std::string &_name="<MaterialNode>", unsigned int _applyProperties=(All &~BackFaceCulling))
Default constructor. Applies all properties.
void lineWidth(float _sz)
set line width (default: 1.0)
void indexOfRefraction(double _m)
set index of refraction
void set_shininess(float _shininess)
set specular shininess (must be in [0, 128])
Definition: GLState.cc:761
void set_specular_color(const Vec4f &_col)
set specular color
Definition: GLState.cc:737
int applyProperties_
OR&#39;ed ApplyProperties.
void ambientColor(const Vec4f &_a)
set the ambient color.
void set_ambient_color(const Vec4f &_col)
set ambient color
Definition: GLState.cc:707
bool multisampling()
Get current multisampling state.
Definition: GLState.hh:1048
void set_diffuse_color(const Vec4f &_col)
set diffuse color
Definition: GLState.cc:722
DrawMode SOLID_FACES_COLORED_SMOOTH_SHADED
draw smooth shaded and colored faces (requires vertex normals and face colors)
Definition: DrawModes.cc:95
void read(std::istream &_is)
read MaterialFile
static void enable(GLenum _cap, bool _warnRemoved=true)
replaces glEnable, but supports locking
void pointSize(float _sz)
set point size (default: 1.0)
void leave(GLState &_state, const DrawModes::DrawMode &_drawmode)
restores original GL-color and GL-material
VectorT< float, 4 > Vec4f
Definition: VectorT.hh:138
ACG::SceneGraph::Material materialBackup_
Material Backup.
void enter(GLState &_state, const DrawModes::DrawMode &_drawmode)
set current GL-color and GL-material
float point_size() const
get point size
Definition: GLState.hh:970
float line_width() const
get line width
Definition: GLState.hh:975
void set_overlay_color(const Vec4f &_col)
set overlay color
Definition: GLState.cc:752
void specularColor(const Vec4f &_s)
set the specular color
static void disable(GLenum _cap, bool _warnRemoved=true)
replaces glDisable, but supports locking
void set_depthFunc(const GLenum &_depth_func)
Call glDepthFunc() to actually change the depth comparison function, and store the new value in this ...
Definition: GLState.cc:948
void leavePick(GLState &_state, PickTarget _target, const DrawModes::DrawMode &_drawMode)
Do nothing in picking.
void diffuseColor(const Vec4f &_d)
set the diffuse color.
const Vec4f & overlay_color() const
Get overlay color.
Definition: GLState.hh:955
static void blendFunc(GLenum _sfactor, GLenum _dfactor)
replaces glBlendFunc, supports locking
void overlayColor(const Vec4f &_s)
set the overlay color (This can be used to render overlays e.g. additional wireframes in a different ...
draw smooth lines using glLine()
Color Material ( Only when a drawmode using shading and lighting is enabled )
bool blending()
get whether transparenet or solid objects should be drawn
Definition: GLState.hh:1035
static void alphaFunc(GLenum _func, GLclampf _ref)
replaces glAlphaFunc, supports locking
void set_multisampling(bool _b)
Enable or disable multisampling.
Definition: GLState.cc:839
ACG::SceneGraph::Material material_
Local material class that actually stores the properties.
void baseColor(const Vec4f &_c)
set the base color (Sets the baseColor which is the same as the emission(const Vec4f& _c) ) ...
void set_point_size(float _f)
set point size
Definition: GLState.cc:776
void set_line_width(float _f)
set line width
Definition: GLState.cc:791
const Vec4f & base_color() const
get base color (used when lighting is off)
Definition: GLState.hh:926
float shininess() const
get specular shininess (must be in [0, 128])
Definition: GLState.hh:960
void enterPick(GLState &_state, PickTarget _target, const DrawModes::DrawMode &_drawMode)
Do nothing in picking.
PickTarget
What target to use for picking.
Definition: PickTarget.hh:73
void setRefractive(bool _r)
set refractive flag
draw smooth (round) points using glPoint()
const Vec4f & diffuse_color() const
get diffuse color
Definition: GLState.hh:936
void set_base_color(const Vec4f &_col)
set base color (used when lighting is off)
Definition: GLState.cc:677
void shininess(float _s)
set shininess
const Vec4f & ambient_color() const
get ambient color
Definition: GLState.hh:931
DrawMode SOLID_FACES_COLORED_FLAT_SHADED
draw flat shaded and colored faces (requires face normals and colors)
Definition: DrawModes.cc:94