Developer Documentation
Loading...
Searching...
No Matches
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#include <QJsonDocument>
63#include <QJsonObject>
64
65
66//== NAMESPACES ===============================================================
67
68namespace {
69
70enum ClassProperties {
71 CP_JSON_SERIALIZABLE = 1
72};
73
74inline QVariantList col2vl(const ACG::Vec4f &col) {
75 return QVariantList() << col[0] << col[1] << col[2] << col[3];
76}
77
78inline ACG::Vec4f vl2col(const QVariantList &vl) {
79 if (vl.size() < 4) return ACG::Vec4f();
80 return ACG::Vec4f(vl[0].toFloat(), vl[1].toFloat(), vl[2].toFloat(), vl[3].toFloat());
81}
82
83} /* anonymous namespace */
84
85namespace ACG {
86
87QVariantMap json_to_variant_map(QString json) {
88 QJsonParseError error;
89 QJsonDocument jsonDoc = QJsonDocument::fromJson(json.toUtf8(), &error);
90 if (error.error != QJsonParseError::NoError || !jsonDoc.isObject())
91 return QVariantMap();
92 return jsonDoc.object().toVariantMap();
93}
94
95namespace SceneGraph {
96
97
98//== IMPLEMENTATION ==========================================================
99
100bool Material::support_json_serialization() {
101 return CP_JSON_SERIALIZABLE;
102}
103
104QString Material::serializeToJson() const {
105 QVariantMap matMap;
106
107 matMap["baseColor"] = col2vl(baseColor_);
108 matMap["ambientColor"] = col2vl(ambientColor_);
109 matMap["diffuseColor"] = col2vl(diffuseColor_);
110 matMap["specularColor"] = col2vl(specularColor_);
111 matMap["overlayColor"] = col2vl(overlayColor_);
112 matMap["shininess"] = shininess_;
113 matMap["reflectance"] = reflectance_;
114 matMap["indexOfRefraction"] = indexOfRefraction_;
115 matMap["isRefractive"] = isRefractive_;
116 matMap["pointSize"] = pointSize_;
117 matMap["lineWidth"] = lineWidth_;
118 matMap["roundPoints"] = roundPoints_;
119 matMap["linesSmooth"] = linesSmooth_;
120 matMap["alphaTest"] = alphaTest_;
121 matMap["alphaClip"] = alphaClip_;
122 matMap["blending"] = blending_;
123 matMap["blendParam1"] = blendParam1_;
124 matMap["blendParam2"] = blendParam2_;
125 matMap["colorMaterial"] = colorMaterial_;
126 matMap["backfaceCulling"] = backfaceCulling_;
127 matMap["multiSampling"] = multiSampling_;
128
129 const QJsonDocument json_doc(QJsonObject::fromVariantMap(matMap));
130 return QString::fromUtf8(
131 json_doc.toJson(QJsonDocument::Indented));
132}
133
134void Material::deserializeFromVariantMap(const QVariantMap &matMap) {
135 if (matMap.contains("baseColor")) baseColor_ = vl2col(matMap["baseColor"].toList());
136 if (matMap.contains("ambientColor")) ambientColor_ = vl2col(matMap["ambientColor"].toList());
137 if (matMap.contains("diffuseColor")) diffuseColor_ = vl2col(matMap["diffuseColor"].toList());
138 if (matMap.contains("specularColor")) specularColor_ = vl2col(matMap["specularColor"].toList());
139 if (matMap.contains("overlayColor")) overlayColor_ = vl2col(matMap["overlayColor"].toList());
140 if (matMap.contains("shininess")) shininess_ = matMap["shininess"].toFloat();
141 if (matMap.contains("reflectance")) reflectance_ = matMap["reflectance"].toDouble();
142 if (matMap.contains("indexOfRefraction")) indexOfRefraction_ = matMap["indexOfRefraction"].toDouble();
143 if (matMap.contains("isRefractive")) isRefractive_ = matMap["isRefractive"].toBool();
144 if (matMap.contains("pointSize")) pointSize_ = matMap["pointSize"].toFloat();
145 if (matMap.contains("lineWidth")) lineWidth_ = matMap["lineWidth"].toFloat();
146 if (matMap.contains("roundPoints")) roundPoints_ = matMap["roundPoints"].toBool();
147 if (matMap.contains("linesSmooth")) linesSmooth_ = matMap["linesSmooth"].toBool();
148 if (matMap.contains("alphaTest")) alphaTest_ = matMap["alphaTest"].toBool();
149 if (matMap.contains("alphaClip")) alphaClip_ = matMap["alphaClip"].toFloat();
150 if (matMap.contains("blending")) blending_ = matMap["blending"].toBool();
151 if (matMap.contains("blendParam1")) blendParam1_ = matMap["blendParam1"].toUInt();
152 if (matMap.contains("blendParam2")) blendParam2_ = matMap["blendParam2"].toUInt();
153 if (matMap.contains("colorMaterial")) colorMaterial_ = matMap["colorMaterial"].toBool();
154 if (matMap.contains("backfaceCulling")) backfaceCulling_ = matMap["backfaceCulling"].toBool();
155 if (matMap.contains("multiSampling")) multiSampling_ = matMap["multiSampling"].toBool();
156}
157
158void Material::deserializeFromJson(const QString &json) {
159 deserializeFromVariantMap(ACG::json_to_variant_map(json));
160}
161
163 const std::string& _name,
164 unsigned int _applyProperties )
165 : BaseNode(_parent, _name),
166 applyProperties_(_applyProperties)
167{}
168
169
170//----------------------------------------------------------------------------
171
172
173void MaterialNode::enter(GLState& _state, const DrawModes::DrawMode& _drawmode )
174{
176 {
177 materialBackup_.baseColor_ = _state.base_color();
178 _state.set_base_color(material_.baseColor_);
179 }
180
182 {
183 materialBackup_.ambientColor_ = _state.ambient_color();
184 materialBackup_.diffuseColor_ = _state.diffuse_color();
185 materialBackup_.specularColor_ = _state.specular_color();
186 materialBackup_.overlayColor_ = _state.overlay_color();
187 materialBackup_.shininess_ = _state.shininess();
188
189 _state.set_ambient_color(material_.ambientColor_);
190 _state.set_diffuse_color(material_.diffuseColor_);
191 _state.set_specular_color(material_.specularColor_);
192 _state.set_overlay_color(material_.overlayColor_);
193 _state.set_shininess(material_.shininess_);
194 }
195
197 {
198 materialBackup_.pointSize_ = _state.point_size();
199 _state.set_point_size(material_.pointSize_);
200 }
201
203 {
204 materialBackup_.lineWidth_ = _state.line_width();
205 _state.set_line_width(material_.lineWidth_);
206 }
207
208 if (_state.compatibilityProfile())
209 {
210 // deprecated opengl caps
211
213 {
214 materialBackup_.roundPoints_ = glIsEnabled(GL_POINT_SMOOTH) &&
215 glIsEnabled(GL_ALPHA_TEST);
216
217 if (material_.roundPoints_) {
218 glHint(GL_POINT_SMOOTH_HINT, GL_NICEST);
219 ACG::GLState::enable(GL_POINT_SMOOTH);
220 }
221 else
222 ACG::GLState::disable(GL_POINT_SMOOTH);
223 }
224
226 {
227 materialBackup_.linesSmooth_ = glIsEnabled(GL_LINE_SMOOTH) &&
228 glIsEnabled(GL_ALPHA_TEST);
229
230 if (material_.linesSmooth_) {
231 glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
232 ACG::GLState::enable(GL_LINE_SMOOTH);
233 }
234 else
235 ACG::GLState::disable(GL_LINE_SMOOTH);
236 }
237
239 {
240 materialBackup_.alphaTest_ = glIsEnabled(GL_ALPHA_TEST);
241 glGetFloatv(GL_ALPHA_TEST_REF, &materialBackup_.alphaClip_);
242
243 if (material_.alphaTest_)
244 {
245 ACG::GLState::alphaFunc(GL_GREATER, material_.alphaClip_);
246 ACG::GLState::enable(GL_ALPHA_TEST);
247 }
248 else
249 {
250 ACG::GLState::disable(GL_ALPHA_TEST);
251 }
252 }
253
254 }
255
257 {
258 materialBackup_.multiSampling_ = _state.multisampling();
259 _state.set_multisampling( material_.multiSampling_ );
260 }
261
262
264 {
265 materialBackup_.blending_ = _state.blending();
266 glGetIntegerv( GL_BLEND_SRC, (GLint*) &materialBackup_.blendParam1_);
267 glGetIntegerv( GL_BLEND_DST, (GLint*) &materialBackup_.blendParam2_);
268
269 _state.set_blending(material_.blending_);
270
271 if (material_.blending_)
272 {
273 _state.set_depthFunc(GL_LEQUAL);
274 ACG::GLState::blendFunc(material_.blendingParam1(), material_.blendingParam2());
275 ACG::GLState::enable(GL_BLEND);
276 }
277 else
278 {
279 _state.set_depthFunc(GL_LESS);
280 ACG::GLState::disable(GL_BLEND);
281 }
282 }
283
284
286 {
287 materialBackup_.backfaceCulling_ = glIsEnabled(GL_CULL_FACE);
288
289 if ( material_.backfaceCulling_ )
290 ACG::GLState::enable( GL_CULL_FACE );
291 else
292 ACG::GLState::disable( GL_CULL_FACE );
293
294 }
295
297 {
298 materialBackup_.colorMaterial_ = glIsEnabled(GL_COLOR_MATERIAL);
299
300 if(_state.compatibilityProfile())
301 {
302 if (material_.colorMaterial_ ) {
303 ACG::GLState::disable( GL_COLOR_MATERIAL );
304 glColorMaterial( GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE );
305 ACG::GLState::enable( GL_COLOR_MATERIAL );
306 } else
307 ACG::GLState::disable( GL_COLOR_MATERIAL );
308 }
309 }
310
311}
312
313//----------------------------------------------------------------------------
314
315void MaterialNode::enterPick(GLState& _state , PickTarget /*_target*/, const DrawModes::DrawMode& /*_drawMode*/ ) {
316
318 {
319 materialBackup_.pointSize_ = _state.point_size();
320 _state.set_point_size(material_.pointSize_);
321 }
322
324 {
325 materialBackup_.lineWidth_ = _state.line_width();
326 _state.set_line_width(material_.lineWidth_);
327 }
328}
329
330void MaterialNode::leavePick(GLState& _state, PickTarget /*_target*/, const DrawModes::DrawMode& /*_drawMode*/ ) {
331
333 {
334 _state.set_point_size(materialBackup_.pointSize_);
335 }
336
337
339 {
340 _state.set_line_width(materialBackup_.lineWidth_);
341 }
342}
343
344
345//----------------------------------------------------------------------------
346
347
348void MaterialNode::leave(GLState& _state, const DrawModes::DrawMode& _drawmode )
349{
351 {
352 _state.set_base_color(materialBackup_.baseColor_);
353 }
354
355
357 {
358 _state.set_ambient_color(materialBackup_.ambientColor_);
359 _state.set_diffuse_color(materialBackup_.diffuseColor_);
360 _state.set_specular_color(materialBackup_.specularColor_);
361 _state.set_overlay_color(materialBackup_.overlayColor_);
362 _state.set_shininess(materialBackup_.shininess_);
363 }
364
365
367 {
368 _state.set_point_size(materialBackup_.pointSize_);
369 }
370
371
373 {
374 _state.set_line_width(materialBackup_.lineWidth_);
375 }
376
377
378 if ((applyProperties_ & RoundPoints) && _state.compatibilityProfile())
379 {
380 if( materialBackup_.roundPoints_)
381 ACG::GLState::enable(GL_POINT_SMOOTH);
382 else
383 ACG::GLState::disable(GL_POINT_SMOOTH);
384 }
385
386 if ((applyProperties_ & LineSmooth) && _state.compatibilityProfile())
387 {
388 if( materialBackup_.linesSmooth_)
389 ACG::GLState::enable(GL_LINE_SMOOTH);
390 else
391 ACG::GLState::disable(GL_LINE_SMOOTH);
392 }
393
395 _state.set_multisampling( materialBackup_.multiSampling_ );
396
397 if ((applyProperties_ & AlphaTest) && _state.compatibilityProfile())
398 {
399 if (materialBackup_.alphaTest_)
400 {
401 ACG::GLState::alphaFunc(GL_GREATER, materialBackup_.alphaClip_);
402 ACG::GLState::enable(GL_ALPHA_TEST);
403 }
404 else
405 {
406 ACG::GLState::disable(GL_ALPHA_TEST);
407 }
408 }
409
410
412 {
413 _state.set_blending(materialBackup_.blending_);
414
415 if (materialBackup_.blending_)
416 {
417 _state.set_depthFunc(GL_LEQUAL);
418 ACG::GLState::blendFunc(materialBackup_.blendParam1_, materialBackup_.blendParam2_);
419 ACG::GLState::enable(GL_BLEND);
420 }
421 else
422 {
423 _state.set_depthFunc(GL_LESS);
424 ACG::GLState::disable(GL_BLEND);
425 }
426 }
427
428
430 {
431 if (materialBackup_.backfaceCulling_)
432 ACG::GLState::enable( GL_CULL_FACE );
433 else
434 ACG::GLState::disable( GL_CULL_FACE );
435 }
436
438 {
439 if(_state.compatibilityProfile())
440 {
441 if (materialBackup_.colorMaterial_ ) {
442 ACG::GLState::enable( GL_COLOR_MATERIAL );
443 } else
444 ACG::GLState::disable( GL_COLOR_MATERIAL );
445 }
446 }
447
448}
449
450
451//----------------------------------------------------------------------------
452
453
454void
455MaterialNode::read(std::istream& _is)
456{
457
458 char s[200];
459 float x, y, z, u;
460 bool b;
461
462 while (_is && (!_is.eof()) && _is.getline(s,200) ) {
463 std::istringstream buffer(s);
464
465 // comment or empty
466 if ( s[0] == '#')
467 continue;
468
469 std::string specifier = "";
470
471 // Read specifier from buffer
472 buffer >> specifier;
473
474 // BaseColor
475 if (specifier == "BaseColor") {
476 buffer >> x >> y >> z >> u;
477
478 if (buffer.good()) {
479 material_.baseColor(Vec4f(x, y, z, u));
480 }
481 }
482 // AmbientColor
483 else if (specifier == "AmbientColor") {
484 buffer >> x >> y >> z >> u;
485
486 if (buffer.good()) {
487 material_.ambientColor(Vec4f(x, y, z, u));
488 }
489 }
490 // DiffuseColor
491 else if (specifier == "DiffuseColor") {
492 buffer >> x >> y >> z >> u;
493
494 if (buffer.good()) {
495 material_.diffuseColor(Vec4f(x, y, z, u));
496 }
497 }
498 // SpecularColor
499 else if (specifier == "SpecularColor") {
500 buffer >> x >> y >> z >> u;
501
502 if (buffer.good()) {
503 material_.specularColor(Vec4f(x, y, z, u));
504 }
505 }
506 // OverlayColor
507 else if (specifier == "OverlayColor") {
508 buffer >> x >> y >> z >> u;
509
510 if (buffer.good()) {
511 material_.overlayColor(Vec4f(x, y, z, u));
512 }
513 }
514 // Shininess
515 else if (specifier == "Shininess") {
516 buffer >> x;
517
518 if (buffer.good()) {
520 }
521 }
522 // Refractive
523 else if (specifier == "isRefractive") {
524 buffer >> b;
525
526 if (buffer.good()) {
528 }
529 }
530 // Refraction Index
531 else if (specifier == "indexOfRefraction") {
532 buffer >> x;
533
534 if (buffer.good()) {
536 }
537 }
538 // PointSize
539 else if (specifier == "PointSize") {
540 buffer >> x;
541
542 if (buffer.good()) {
544 }
545 }
546 // LineWidth
547 else if (specifier == "LineWidth") {
548 buffer >> x;
549
550 if (buffer.good()) {
552 }
553 }
554
555 if (!buffer.good())
556 std::cerr << "MaterialNode parse error while reading string : " << s << std::endl;
557
558 }
559}
560
561//=============================================================================
562} // namespace SceneGraph
563} // namespace ACG
564//=============================================================================
void set_specular_color(const Vec4f &_col)
set specular color
Definition GLState.cc:737
void set_ambient_color(const Vec4f &_col)
set ambient color
Definition GLState.cc:707
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 set_multisampling(bool _b)
Enable or disable multisampling.
Definition GLState.cc:839
static void enable(GLenum _cap, bool _warnRemoved=true)
replaces glEnable, but supports locking
Definition GLState.cc:1507
const Vec4f & specular_color() const
get specular color
Definition GLState.hh:966
void set_blending(bool _b)
set whether transparent or solid objects should be drawn
Definition GLState.hh:1058
const Vec4f & base_color() const
get base color (used when lighting is off)
Definition GLState.hh:951
const Vec4f & overlay_color() const
Get overlay color.
Definition GLState.hh:980
void set_overlay_color(const Vec4f &_col)
set overlay color
Definition GLState.cc:752
bool blending()
get whether transparenet or solid objects should be drawn
Definition GLState.hh:1060
void set_shininess(float _shininess)
set specular shininess (must be in [0, 128])
Definition GLState.cc:761
static void blendFunc(GLenum _sfactor, GLenum _dfactor)
replaces glBlendFunc, supports locking
Definition GLState.hh:307
static void alphaFunc(GLenum _func, GLclampf _ref)
replaces glAlphaFunc, supports locking
Definition GLState.cc:1708
static void disable(GLenum _cap, bool _warnRemoved=true)
replaces glDisable, but supports locking
Definition GLState.cc:1527
void set_line_width(float _f)
set line width
Definition GLState.cc:791
const Vec4f & ambient_color() const
get ambient color
Definition GLState.hh:956
void set_point_size(float _f)
set point size
Definition GLState.cc:776
void set_base_color(const Vec4f &_col)
set base color (used when lighting is off)
Definition GLState.cc:677
bool multisampling()
Get current multisampling state.
Definition GLState.hh:1073
float line_width() const
get line width
Definition GLState.hh:1000
const Vec4f & diffuse_color() const
get diffuse color
Definition GLState.hh:961
void set_diffuse_color(const Vec4f &_col)
set diffuse color
Definition GLState.cc:722
float shininess() const
get specular shininess (must be in [0, 128])
Definition GLState.hh:985
float point_size() const
get point size
Definition GLState.hh:995
MaterialNode(BaseNode *_parent=0, const std::string &_name="<MaterialNode>", unsigned int _applyProperties=(All &~BackFaceCulling))
Default constructor. Applies all properties.
int applyProperties_
OR'ed ApplyProperties.
ACG::SceneGraph::Material materialBackup_
Material Backup.
void read(std::istream &_is)
read MaterialFile
void enter(GLState &_state, const DrawModes::DrawMode &_drawmode) override
set current GL-color and GL-material
ACG::SceneGraph::Material material_
Local material class that actually stores the properties.
@ BackFaceCulling
backface culling
@ RoundPoints
draw smooth (round) points using glPoint()
@ LineSmooth
draw smooth lines using glLine()
@ ColorMaterial
Color Material ( Only when a drawmode using shading and lighting is enabled )
void enterPick(GLState &_state, PickTarget _target, const DrawModes::DrawMode &_drawMode) override
Do nothing in picking.
void leave(GLState &_state, const DrawModes::DrawMode &_drawmode) override
restores original GL-color and GL-material
void leavePick(GLState &_state, PickTarget _target, const DrawModes::DrawMode &_drawMode) override
Do nothing in picking.
void setRefractive(bool _r)
set refractive flag
void lineWidth(float _sz)
set line width (default: 1.0)
void indexOfRefraction(double _m)
set index of refraction
void shininess(float _s)
set shininess
void baseColor(const Vec4f &_c)
set the base color (Sets the baseColor which is the same as the emission(const Vec4f& _c) )
void specularColor(const Vec4f &_s)
set the specular color
void pointSize(float _sz)
set point size (default: 1.0)
void ambientColor(const Vec4f &_a)
set the ambient color.
void overlayColor(const Vec4f &_s)
set the overlay color (This can be used to render overlays e.g. additional wireframes in a different ...
void diffuseColor(const Vec4f &_d)
set the diffuse color.
DrawMode SOLID_FACES_COLORED_SMOOTH_SHADED
draw smooth shaded and colored faces (requires vertex normals and face colors)
Definition DrawModes.cc:95
DrawMode SOLID_FACES_COLORED_FLAT_SHADED
draw flat shaded and colored faces (requires face normals and colors)
Definition DrawModes.cc:94
PickTarget
What target to use for picking.
Definition PickTarget.hh:74
Namespace providing different geometric functions concerning angles.
VectorT< float, 4 > Vec4f
Definition VectorT.hh:138