1 /**************************************************************************\
2 * Copyright (c) Kongsberg Oil & Gas Technologies AS
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met:
8 *
9 * Redistributions of source code must retain the above copyright notice,
10 * this list of conditions and the following disclaimer.
11 *
12 * Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * Neither the name of the copyright holder nor the names of its
17 * contributors may be used to endorse or promote products derived from
18 * this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 \**************************************************************************/
32
33 /*!
34 \class SoMultiTextureImageElement Inventor/elements/SoMultiTextureImageElement.h
35 \brief The SoMultiTextureImageElement class is yet to be documented.
36
37 \ingroup elements
38
39 FIXME: write doc.
40
41 \COIN_CLASS_EXTENSION
42
43 \since Coin 2.2
44 */
45
46 #include "coindefs.h"
47 #include "SbBasicP.h"
48
49 #include <Inventor/elements/SoMultiTextureImageElement.h>
50 #include <Inventor/elements/SoGLMultiTextureImageElement.h>
51 #include <Inventor/nodes/SoNode.h>
52 #include <Inventor/misc/SoGLImage.h>
53 #include <Inventor/SbImage.h>
54 #include <Inventor/lists/SbList.h>
55 #include <cassert>
56
57 class SoMultiTextureImageElementP {
58 public:
ensureCapacity(int unit) const59 void ensureCapacity(int unit) const {
60 while (unit >= this->unitdata.getLength()) {
61 this->unitdata.append(SoMultiTextureImageElement::UnitData());
62 }
63 }
64 mutable SbList<SoMultiTextureImageElement::UnitData> unitdata;
65 };
66
67 SO_ELEMENT_CUSTOM_CONSTRUCTOR_SOURCE(SoMultiTextureImageElement);
68
69 #define PRIVATE(obj) obj->pimpl
70
SoMultiTextureImageElement(void)71 SoMultiTextureImageElement::SoMultiTextureImageElement(void)
72 {
73 PRIVATE(this) = new SoMultiTextureImageElementP;
74
75 this->setTypeId(SoMultiTextureImageElement::classTypeId);
76 this->setStackIndex(SoMultiTextureImageElement::classStackIndex);
77 }
78
79 /*!
80 This static method initializes static data for the
81 SoMultiTextureImageElement class.
82 */
83
84 void
initClass(void)85 SoMultiTextureImageElement::initClass(void)
86 {
87 SO_ELEMENT_INIT_CLASS(SoMultiTextureImageElement, inherited);
88 }
89
90 /*!
91 The destructor.
92 */
93
~SoMultiTextureImageElement()94 SoMultiTextureImageElement::~SoMultiTextureImageElement()
95 {
96 delete PRIVATE(this);
97 }
98
99 //! FIXME: write doc.
100
101 void
init(SoState * state)102 SoMultiTextureImageElement::init(SoState * state)
103 {
104 inherited::init(state);
105 }
106
107 /*!
108 Resets this element to its original values.
109 */
110 void
setDefault(SoState * const state,SoNode * const COIN_UNUSED_ARG (node),const int unit)111 SoMultiTextureImageElement::setDefault(SoState * const state, SoNode * const COIN_UNUSED_ARG(node), const int unit)
112 {
113 SoMultiTextureImageElement * elem =
114 coin_safe_cast<SoMultiTextureImageElement *>
115 (state->getElement(classStackIndex));
116 PRIVATE(elem)->ensureCapacity(unit);
117 PRIVATE(elem)->unitdata[unit] = UnitData();
118 }
119
120 //! FIXME: write doc.
121 void
set(SoState * const state,SoNode * const node,const int unit,const SbVec2s & size,const int numComponents,const unsigned char * bytes,const Wrap wrapS,const Wrap wrapT,const Model model,const SbColor & blendColor)122 SoMultiTextureImageElement::set(SoState * const state, SoNode * const node,
123 const int unit,
124 const SbVec2s & size, const int numComponents,
125 const unsigned char * bytes,
126 const Wrap wrapS,
127 const Wrap wrapT,
128 const Model model,
129 const SbColor & blendColor)
130 {
131 SoMultiTextureImageElement * elem =
132 coin_safe_cast<SoMultiTextureImageElement *>
133 (state->getElement(classStackIndex));
134
135 PRIVATE(elem)->ensureCapacity(unit);
136 elem->setElt(unit, node->getNodeId(), size, numComponents, bytes, wrapS, wrapT,
137 model, blendColor);
138 }
139
140 /*!
141 FIXME: write doc.
142
143 \COIN_FUNCTION_EXTENSION
144 */
145 void
set(SoState * const state,SoNode * const node,const int unit,const SbVec3s & size,const int numComponents,const unsigned char * bytes,const Wrap wrapS,const Wrap wrapT,const Wrap wrapR,const Model model,const SbColor & blendColor)146 SoMultiTextureImageElement::set(SoState * const state, SoNode * const node,
147 const int unit,
148 const SbVec3s & size, const int numComponents,
149 const unsigned char * bytes,
150 const Wrap wrapS,
151 const Wrap wrapT,
152 const Wrap wrapR,
153 const Model model,
154 const SbColor & blendColor)
155 {
156 SoMultiTextureImageElement * elem = coin_safe_cast<SoMultiTextureImageElement *>
157 (state->getElement(classStackIndex));
158
159 PRIVATE(elem)->ensureCapacity(unit);
160 elem->setElt(unit, node->getNodeId(), size, numComponents, bytes, wrapS, wrapT, wrapR,
161 model, blendColor);
162 }
163
164 //! FIXME: write doc.
165
166 const unsigned char *
get(SoState * const state,const int unit,SbVec2s & size,int & numComponents,Wrap & wrapS,Wrap & wrapT,Model & model,SbColor & blendColor)167 SoMultiTextureImageElement::get(SoState * const state,
168 const int unit,
169 SbVec2s & size,
170 int & numComponents,
171 Wrap & wrapS,
172 Wrap & wrapT,
173 Model & model,
174 SbColor &blendColor)
175 {
176 const SoMultiTextureImageElement * elem =
177 coin_assert_cast<const SoMultiTextureImageElement *>
178 (getConstElement(state, classStackIndex));
179
180 PRIVATE(elem)->ensureCapacity(unit);
181 const UnitData & ud = PRIVATE(elem)->unitdata[unit];
182
183 wrapS = ud.wrapS;
184 wrapT = ud.wrapT;
185 model = ud.model;
186 blendColor = ud.blendColor;
187
188 return getImage(state, unit, size, numComponents);
189 }
190
191 /*!
192 FIXME: write doc.
193
194 \COIN_FUNCTION_EXTENSION
195
196 */
197 const unsigned char *
get(SoState * const state,const int unit,SbVec3s & size,int & numComponents,Wrap & wrapS,Wrap & wrapT,Wrap & wrapR,Model & model,SbColor & blendColor)198 SoMultiTextureImageElement::get(SoState * const state,
199 const int unit,
200 SbVec3s & size,
201 int & numComponents,
202 Wrap & wrapS,
203 Wrap & wrapT,
204 Wrap & wrapR,
205 Model & model,
206 SbColor &blendColor)
207 {
208 const SoMultiTextureImageElement * elem =
209 coin_assert_cast<const SoMultiTextureImageElement *>
210 (getConstElement(state, classStackIndex));
211
212 PRIVATE(elem)->ensureCapacity(unit);
213 const UnitData & ud = PRIVATE(elem)->unitdata[unit];
214
215 wrapS = ud.wrapS;
216 wrapT = ud.wrapT;
217 wrapR = ud.wrapR;
218 model = ud.model;
219 blendColor = ud.blendColor;
220
221 return getImage(state, unit, size, numComponents);
222 }
223
224 /*!
225 FIXME: write doc
226 */
227 const unsigned char *
getImage(SoState * const state,const int unit,SbVec2s & size,int & numComponents)228 SoMultiTextureImageElement::getImage(SoState * const state,
229 const int unit,
230 SbVec2s &size,
231 int & numComponents)
232 {
233 const SoMultiTextureImageElement * elem =
234 coin_assert_cast<const SoMultiTextureImageElement *>
235 (getConstElement(state, classStackIndex));
236
237 PRIVATE(elem)->ensureCapacity(unit);
238 const UnitData & ud = PRIVATE(elem)->unitdata[unit];
239
240 size.setValue(ud.size[0], ud.size[1]);
241 numComponents = ud.numComponents;
242 return ud.bytes;
243 }
244
245 /*!
246 FIXME: write doc
247 */
248 const unsigned char *
getImage(SoState * const state,const int unit,SbVec3s & size,int & numComponents)249 SoMultiTextureImageElement::getImage(SoState * const state,
250 const int unit,
251 SbVec3s & size,
252 int & numComponents)
253 {
254 const SoMultiTextureImageElement * elem =
255 coin_assert_cast<const SoMultiTextureImageElement *>
256 (getConstElement(state, classStackIndex));
257
258 PRIVATE(elem)->ensureCapacity(unit);
259 const UnitData & ud = PRIVATE(elem)->unitdata[unit];
260
261 size = ud.size;
262 numComponents = ud.numComponents;
263 return ud.bytes;
264 }
265
266
267 //! FIXME: write doc.
268
269 SbBool
containsTransparency(SoState * const state)270 SoMultiTextureImageElement::containsTransparency(SoState * const state)
271 {
272 const SoMultiTextureImageElement * elem =
273 coin_assert_cast<const SoMultiTextureImageElement *>
274 (getConstElement(state, classStackIndex));
275
276 for (int i = 0; i < PRIVATE(elem)->unitdata.getLength(); i++) {
277 if (elem->hasTransparency(i)) return TRUE;
278 }
279 return FALSE;
280 }
281
282 /*!
283 Called by containsTransparency(). Returns \e TRUE if image data has
284 transparency. Default method does a very poor job of detecting this,
285 since it returns \e TRUE when the number of components are 2 or
286 4. Override whenever it is important to know this
287 (SoGLTextureImageElement overrides it to avoid transparency handling
288 where possible).
289 */
290 SbBool
hasTransparency(const int unit) const291 SoMultiTextureImageElement::hasTransparency(const int unit) const
292 {
293 if (unit < PRIVATE(this)->unitdata.getLength()) {
294 const UnitData & ud = PRIVATE(this)->unitdata[unit];
295 return (ud.numComponents==2 || ud.numComponents==4);
296 }
297 return FALSE;
298 }
299
300 const SoMultiTextureImageElement::UnitData &
getUnitData(const int unit) const301 SoMultiTextureImageElement::getUnitData(const int unit) const
302 {
303 assert(unit < PRIVATE(this)->unitdata.getLength());
304 return PRIVATE(this)->unitdata[unit];
305 }
306
307 /*!
308 Get the number of units with image data set.
309 */
310 int
getNumUnits() const311 SoMultiTextureImageElement::getNumUnits() const
312 {
313 return PRIVATE(this)->unitdata.getLength();
314 }
315
316 //! FIXME: write doc.
317
318 const unsigned char *
getDefault(SbVec2s & size,int & numComponents)319 SoMultiTextureImageElement::getDefault(SbVec2s & size, int & numComponents)
320 {
321 size.setValue(0,0);
322 numComponents = 0;
323 return NULL;
324 }
325
326 /*!
327 FIXME: write doc.
328
329 */
330 const unsigned char *
getDefault(SbVec3s & size,int & numComponents)331 SoMultiTextureImageElement::getDefault(SbVec3s & size, int & numComponents)
332 {
333 size.setValue(0,0,0);
334 numComponents = 0;
335 return NULL;
336 }
337
338 void
push(SoState * COIN_UNUSED_ARG (state))339 SoMultiTextureImageElement::push(SoState * COIN_UNUSED_ARG(state))
340 {
341 const SoMultiTextureImageElement * prev =
342 coin_assert_cast<SoMultiTextureImageElement *>
343 (this->getNextInStack());
344
345 PRIVATE(this)->unitdata = PRIVATE(prev)->unitdata;
346 }
347
348 SbBool
matches(const SoElement * elem) const349 SoMultiTextureImageElement::matches(const SoElement * elem) const
350 {
351 const SoMultiTextureImageElement * e =
352 coin_assert_cast<const SoMultiTextureImageElement *>
353 (elem);
354 const int n = PRIVATE(e)->unitdata.getLength();
355 if (n != PRIVATE(this)->unitdata.getLength()) return FALSE;
356
357 for (int i = 0; i < n; i++) {
358 if (PRIVATE(e)->unitdata[i].nodeid != PRIVATE(this)->unitdata[i].nodeid) {
359 return FALSE;
360 }
361 }
362 return TRUE;
363 }
364
365 SoElement *
copyMatchInfo(void) const366 SoMultiTextureImageElement::copyMatchInfo(void) const
367 {
368 SoMultiTextureImageElement * elem = static_cast<SoMultiTextureImageElement *>
369 (getTypeId().createInstance());
370 PRIVATE(elem)->unitdata = PRIVATE(this)->unitdata;
371 return elem;
372 }
373
374
375 //! FIXME: write doc.
376
377 void
setElt(const int unit,const SbUniqueId nodeid,const SbVec2s & size,const int numComponents,const unsigned char * bytes,const Wrap wrapS,const Wrap wrapT,const Model model,const SbColor & blendColor)378 SoMultiTextureImageElement::setElt(const int unit,
379 const SbUniqueId nodeid,
380 const SbVec2s &size, const int numComponents,
381 const unsigned char * bytes,
382 const Wrap wrapS,
383 const Wrap wrapT,
384 const Model model,
385 const SbColor &blendColor)
386 {
387 assert(unit < PRIVATE(this)->unitdata.getLength());
388 UnitData & ud = PRIVATE(this)->unitdata[unit];
389
390 ud.nodeid = nodeid;
391 ud.size.setValue(size[0],size[1],1);
392 ud.numComponents = numComponents;
393 ud.bytes = bytes;
394 ud.wrapS = wrapS;
395 ud.wrapT = wrapT;
396 ud.wrapR = REPEAT;
397 ud.model = model;
398 ud.blendColor = blendColor;
399 }
400
401 /*!
402 FIXME: write doc.
403 */
404 void
setElt(const int unit,const SbUniqueId nodeid,const SbVec3s & size,const int numComponents,const unsigned char * bytes,const Wrap wrapS,const Wrap wrapT,const Wrap wrapR,const Model model,const SbColor & blendColor)405 SoMultiTextureImageElement::setElt(const int unit,
406 const SbUniqueId nodeid,
407 const SbVec3s & size, const int numComponents,
408 const unsigned char * bytes,
409 const Wrap wrapS,
410 const Wrap wrapT,
411 const Wrap wrapR,
412 const Model model,
413 const SbColor &blendColor)
414 {
415 assert(unit < PRIVATE(this)->unitdata.getLength());
416 UnitData & ud = PRIVATE(this)->unitdata[unit];
417
418 ud.nodeid = nodeid;
419 ud.size = size;
420 ud.numComponents = numComponents;
421 ud.bytes = bytes;
422 ud.wrapS = wrapS;
423 ud.wrapT = wrapT;
424 ud.wrapR = wrapR;
425 ud.model = model;
426 ud.blendColor = blendColor;
427 }
428
429 /*!
430 FIXME: write doc.
431 */
432 const SbColor &
getBlendColor(SoState * const state,const int unit)433 SoMultiTextureImageElement::getBlendColor(SoState * const state, const int unit)
434 {
435 const SoMultiTextureImageElement * elem =
436 coin_assert_cast<const SoMultiTextureImageElement *>
437 (getConstElement(state, classStackIndex));
438
439 PRIVATE(elem)->ensureCapacity(unit);
440 return PRIVATE(elem)->unitdata[unit].blendColor;
441 }
442
443 /*!
444 FIXME: write doc.
445 */
446 SoMultiTextureImageElement::Wrap
getWrapS(SoState * const state,const int unit)447 SoMultiTextureImageElement::getWrapS(SoState * const state, const int unit)
448 {
449 const SoMultiTextureImageElement * elem =
450 coin_assert_cast<const SoMultiTextureImageElement *>
451 (getConstElement(state, classStackIndex));
452
453 PRIVATE(elem)->ensureCapacity(unit);
454 return PRIVATE(elem)->unitdata[unit].wrapT;
455 }
456
457 /*!
458 FIXME: write doc.
459 */
460 SoMultiTextureImageElement::Wrap
getWrapT(SoState * const state,const int unit)461 SoMultiTextureImageElement::getWrapT(SoState * const state, const int unit)
462 {
463 const SoMultiTextureImageElement * elem =
464 coin_assert_cast<const SoMultiTextureImageElement *>
465 (getConstElement(state, classStackIndex));
466
467 PRIVATE(elem)->ensureCapacity(unit);
468 return PRIVATE(elem)->unitdata[unit].wrapS;
469 }
470
471 /*!
472 FIXME: write doc.
473 */
474 SoMultiTextureImageElement::Wrap
getWrapR(SoState * const state,const int unit)475 SoMultiTextureImageElement::getWrapR(SoState * const state, const int unit)
476 {
477 const SoMultiTextureImageElement * elem =
478 coin_assert_cast<const SoMultiTextureImageElement *>
479 (getConstElement(state, classStackIndex));
480
481 PRIVATE(elem)->ensureCapacity(unit);
482 return PRIVATE(elem)->unitdata[unit].wrapR;
483 }
484
485 /*!
486 FIXME: write doc.
487 */
488 SoMultiTextureImageElement::Model
getModel(SoState * const state,const int unit)489 SoMultiTextureImageElement::getModel(SoState * const state, const int unit)
490 {
491 const SoMultiTextureImageElement * elem =
492 coin_assert_cast<const SoMultiTextureImageElement *>
493 (getConstElement(state, classStackIndex));
494
495 PRIVATE(elem)->ensureCapacity(unit);
496 return PRIVATE(elem)->unitdata[unit].model;
497 }
498
UnitData()499 SoMultiTextureImageElement::UnitData::UnitData()
500 : nodeid(0),
501 size(0,0,0),
502 numComponents(0),
503 bytes(0),
504 wrapS(SoMultiTextureImageElement::REPEAT),
505 wrapT(SoMultiTextureImageElement::REPEAT),
506 wrapR(SoMultiTextureImageElement::REPEAT),
507 model(SoMultiTextureImageElement::MODULATE),
508 blendColor(0.0f, 0.0f, 0.0f)
509 {
510 }
511
UnitData(const UnitData & org)512 SoMultiTextureImageElement::UnitData::UnitData(const UnitData & org)
513 : nodeid(org.nodeid),
514 size(org.size),
515 numComponents(org.numComponents),
516 bytes(org.bytes),
517 wrapS(org.wrapS),
518 wrapT(org.wrapT),
519 wrapR(org.wrapR),
520 model(org.model),
521 blendColor(org.blendColor)
522 {
523 }
524
525 #undef PRIVATE
526