fixed: auto_ptr -> unique_ptr
[opensg.git] / Source / System / NodeCores / Drawables / Geometry / Base / OSGGeometry.cpp
blob27c5a295addcf1d2bf13f5b9e77121bb7823aff1
1 /*---------------------------------------------------------------------------*\
2 * OpenSG *
3 * *
4 * *
5 * Copyright (C) 2000-2002 by the OpenSG Forum *
6 * *
7 * www.opensg.org *
8 * *
9 * contact: dirk@opensg.org, gerrit.voss@vossg.org, jbehr@zgdv.de *
10 * *
11 \*---------------------------------------------------------------------------*/
12 /*---------------------------------------------------------------------------*\
13 * License *
14 * *
15 * This library is free software; you can redistribute it and/or modify it *
16 * under the terms of the GNU Library General Public License as published *
17 * by the Free Software Foundation, version 2. *
18 * *
19 * This library is distributed in the hope that it will be useful, but *
20 * WITHOUT ANY WARRANTY; without even the implied warranty of *
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
22 * Library General Public License for more details. *
23 * *
24 * You should have received a copy of the GNU Library General Public *
25 * License along with this library; if not, write to the Free Software *
26 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
27 * *
28 \*---------------------------------------------------------------------------*/
29 /*---------------------------------------------------------------------------*\
30 * Changes *
31 * *
32 * *
33 * *
34 * *
35 * *
36 * *
37 \*---------------------------------------------------------------------------*/
39 //---------------------------------------------------------------------------
40 // Includes
41 //---------------------------------------------------------------------------
43 #include <cstdlib>
44 #include <cstdio>
45 #include <boost/bind.hpp>
47 #include "OSGConfig.h"
49 #include "OSGGLFuncProtos.h"
51 #include "OSGGeometry.h"
52 #include "OSGGeoPumpGroup.h"
54 #include "OSGAction.h"
55 #include "OSGRenderAction.h"
56 #include "OSGIntersectAction.h"
57 #include "OSGDrawEnv.h"
59 //#include "OSGIntersectActor.h"
61 #include "OSGTriangleIterator.h"
62 #include "OSGPrimitiveIterator.h"
63 #include "OSGFaceIterator.h"
64 #include "OSGLineIterator.h"
65 #include "OSGEdgeIterator.h"
66 #include "OSGPointIterator.h"
67 #include "OSGDrawableStatsAttachment.h"
69 OSG_BEGIN_NAMESPACE
71 // Documentation for this class is emited in the
72 // OSGGeometryBase.cpp file.
73 // To modify it, please change the .fcd file (OSGGeometry.fcd) and
74 // regenerate the base file.
76 /***************************************************************************\
77 * Class variables *
78 \***************************************************************************/
80 Geometry::PumpGroupStorage Geometry::_pumps;
82 UInt32 Geometry::_arbVertexArrayObject = Window::invalidExtensionID;
83 UInt32 Geometry::_arbTessellationShader = Window::invalidExtensionID;
84 UInt32 Geometry::_arbDrawInstanced = Window::invalidExtensionID;
86 UInt32 Geometry::FuncIdBindVertexArray = Window::invalidFunctionID;
87 UInt32 Geometry::FuncIdDeleteVertexArrays = Window::invalidFunctionID;
88 UInt32 Geometry::FuncIdGenVertexArrays = Window::invalidFunctionID;
89 UInt32 Geometry::FuncPatchParameterI = Window::invalidFunctionID;
90 UInt32 Geometry::FuncIdDrawElementsInstanced = Window::invalidFunctionID;
91 UInt32 Geometry::FuncIdDrawArraysInstanced = Window::invalidFunctionID;
93 /***************************************************************************\
94 * Class methods *
95 \***************************************************************************/
97 void Geometry::initMethod(InitPhase ePhase)
99 if(ePhase == TypeObject::SystemPost)
101 IntersectAction::registerEnterDefault(
102 getClassType(),
103 reinterpret_cast<Action::Callback>(&Geometry::intersectEnter));
105 RenderAction::registerEnterDefault(
106 getClassType(),
107 reinterpret_cast<Action::Callback>(
108 &MaterialDrawable::renderEnter));
110 RenderAction::registerLeaveDefault(
111 getClassType(),
112 reinterpret_cast<Action::Callback>(
113 &MaterialDrawable::renderLeave));
116 #ifndef __APPLE__
117 _arbVertexArrayObject =
118 Window::registerExtension("GL_ARB_vertex_array_object");
120 FuncIdBindVertexArray =
121 Window::registerFunction
122 (OSG_DLSYM_UNDERSCORE"glBindVertexArray",
123 _arbVertexArrayObject);
125 FuncIdDeleteVertexArrays =
126 Window::registerFunction
127 (OSG_DLSYM_UNDERSCORE"glDeleteVertexArrays",
128 _arbVertexArrayObject);
130 FuncIdGenVertexArrays =
131 Window::registerFunction
132 (OSG_DLSYM_UNDERSCORE"glGenVertexArrays",
133 _arbVertexArrayObject);
135 #else
136 _arbVertexArrayObject =
137 Window::registerExtension("GL_APPLE_vertex_array_object");
139 FuncIdBindVertexArray =
140 Window::registerFunction
141 (OSG_DLSYM_UNDERSCORE"glBindVertexArrayAPPLE",
142 _arbVertexArrayObject);
144 FuncIdDeleteVertexArrays =
145 Window::registerFunction
146 (OSG_DLSYM_UNDERSCORE"glDeleteVertexArraysAPPLE",
147 _arbVertexArrayObject);
149 FuncIdGenVertexArrays =
150 Window::registerFunction
151 (OSG_DLSYM_UNDERSCORE"glGenVertexArraysAPPLE",
152 _arbVertexArrayObject);
153 #endif
155 _arbTessellationShader =
156 Window::registerExtension("GL_ARB_tessellation_shader");
158 _arbDrawInstanced =
159 Window::registerExtension("GL_ARB_draw_instanced");
161 FuncPatchParameterI =
162 Window::registerFunction
163 (OSG_DLSYM_UNDERSCORE"glPatchParameteri",
164 _arbTessellationShader);
166 FuncIdDrawElementsInstanced =
167 Window::registerFunction
168 (OSG_DLSYM_UNDERSCORE"glDrawElementsInstanced",
169 _arbDrawInstanced);
171 FuncIdDrawArraysInstanced =
172 Window::registerFunction
173 (OSG_DLSYM_UNDERSCORE"glDrawArraysInstanced",
174 _arbDrawInstanced);
179 /*! A little helper function to map the OpenGL primitive type to a name.
181 const char *Geometry::mapType(UInt8 type)
183 switch(type)
185 case GL_POINTS: return "Points";
186 case GL_LINES: return "Lines";
187 case GL_LINE_LOOP: return "LineLoop";
188 case GL_LINE_STRIP: return "LineStrip";
189 case GL_TRIANGLES: return "Triangles";
190 case GL_TRIANGLE_STRIP: return "TriangleStrip";
191 case GL_TRIANGLE_FAN: return "TriangleFan";
192 case GL_QUADS: return "Quads";
193 case GL_QUAD_STRIP: return "QuadStrip";
194 case GL_POLYGON: return "Polygon";
195 case GL_PATCHES: return "Patches";
196 case GL_LINES_ADJACENCY_EXT: return "LinesAdjacency";
197 case GL_LINE_STRIP_ADJACENCY_EXT: return "LineStripAdjacency";
198 case GL_TRIANGLES_ADJACENCY_EXT: return "TrianglesAdjacency";
199 case GL_TRIANGLE_STRIP_ADJACENCY_EXT: return "TriangleStripAdjacency";
202 return "Unknown Primitive";
205 /***************************************************************************\
206 * Instance methods *
207 \***************************************************************************/
209 /*-------------------------------------------------------------------------*\
210 - private -
211 \*-------------------------------------------------------------------------*/
213 /*----------------------- constructors & destructors ----------------------*/
215 Geometry::Geometry(void) :
216 Inherited (),
217 _volumeCache()
221 Geometry::Geometry(const Geometry &source) :
222 Inherited (source ),
223 _volumeCache(source._volumeCache)
227 Geometry::~Geometry(void)
231 void Geometry::onCreate(const Geometry *source)
233 Inherited::onCreate(source);
235 // if we're in startup this is the prototype, which shouldn't have an id
236 if(GlobalSystemState == Startup)
237 return;
239 #if !defined(OSG_OGL_COREONLY)
240 setClassicGLId(
241 Window::registerGLObject(
242 boost::bind(&Geometry::handleClassicGL,
243 GeometryMTUncountedPtr(this),
244 _1, _2, _3, _4),
245 &Geometry::handleClassicDestroyGL));
246 #endif
248 setAttGLId(
249 Window::registerGLObject(
250 boost::bind(&Geometry::handleAttGL,
251 GeometryMTUncountedPtr(this),
252 _1, _2, _3, _4),
253 &Geometry::handleAttDestroyGL));
255 setClassicVaoGLId(
256 Window::registerGLObject(
257 boost::bind(&Geometry::handleVAOGL,
258 GeometryMTUncountedPtr(this),
259 _1, _2, _3, _4),
260 &Geometry::handleVAODestroyGL));
261 setAttribVaoGLId(
262 Window::registerGLObject(
263 boost::bind(&Geometry::handleVAOGL,
264 GeometryMTUncountedPtr(this),
265 _1, _2, _3, _4),
266 &Geometry::handleVAODestroyGL));
269 void Geometry::onDestroy(UInt32 uiContainerId)
271 #if !defined(OSG_OGL_COREONLY)
272 if(getClassicGLId() > 0)
273 Window::destroyGLObject(getClassicGLId(), 1);
274 #endif
276 if(getAttGLId() > 0)
277 Window::destroyGLObject(getAttGLId(), 1);
279 if(getClassicVaoGLId() > 0)
280 Window::destroyGLObject(getClassicVaoGLId(), 1);
282 if(getAttribVaoGLId() > 0)
283 Window::destroyGLObject(getAttribVaoGLId(), 1);
285 Inherited::onDestroy(uiContainerId);
289 /*------------------------------ access -----------------------------------*/
291 void Geometry::adjustVolume(Volume & volume)
293 if(!_volumeCache.isEmpty())
295 // use cached volume.
296 volume.setValid();
297 volume.extendBy(_volumeCache);
299 return;
302 GeoVectorProperty *pos = getPositions();
304 if(pos == NULL)
305 return; // Node has no points, no volume
307 _volumeCache.setValid();
309 PrimitiveIterator it = this->beginPrimitives();
310 PrimitiveIterator end = this->endPrimitives ();
312 for(; it != end; ++it)
314 for(UInt32 v = 0; v < it.getLength(); ++v)
316 _volumeCache.extendBy(it.getPosition(v));
320 volume.extendBy(_volumeCache);
323 /*! OpenGL object handler. Used for DisplayList caching.
326 UInt32 Geometry::handleClassicGL(DrawEnv *pEnv,
327 UInt32 id,
328 Window::GLObjectStatusE mode,
329 UInt64 uiOptions)
331 #if !defined(OSG_OGL_COREONLY) || defined(OSG_CHECK_COREONLY)
332 UInt32 glid;
333 Window *pWin = pEnv->getWindow();
334 GLHandlerOptions glOptions = { uiOptions };
336 #ifdef OSG_DEBUG
337 Geometry *pAspectGeo = Aspect::convertToCurrent<Geometry *>(this);
338 OSG_ASSERT(pAspectGeo == this);
339 #endif
341 if(mode == Window::initialize || mode == Window::needrefresh ||
342 mode == Window::reinitialize)
344 if(mode == Window::initialize)
346 glid = glGenLists(1);
347 pWin->setGLObjectId(id, glid);
349 else
351 glid = pWin->getGLObjectId(id);
354 GeoPumpGroup::PropertyCharacteristics prop = glOptions.s.uiOptions;
356 if(((prop & (GeoPumpGroup::SingleIndexed |
357 GeoPumpGroup::NonIndexed )) == 0x0000))
359 GeoPumpGroup::GeoPump pump = GeoPumpGroup::findGeoPump(pEnv, prop);
361 glNewList(glid, GL_COMPILE);
363 if(pump)
365 pump(pEnv,
366 getLengths(), getTypes(),
367 getMFProperties(), getMFPropIndices(),
368 glOptions.s.uiNumInstances );
370 else
372 SWARNING << "Geometry::handleClassicGL: no Pump found for "
373 << "geometry "
374 << this
375 << std::endl;
378 glEndList();
380 else if(_sfUseVAO.getValue() == false ||
381 !pWin->hasExtension(_arbVertexArrayObject) ||
382 (prop & GeoPumpGroup::AllVAOMask) != GeoPumpGroup::AllVAOMask)
384 GeoPumpGroup::SplitGeoPump pump =
385 GeoPumpGroup::findSplitGeoPump(pEnv,
386 prop);
388 if(pump.drawPump != NULL)
390 glNewList(glid, GL_COMPILE);
392 pump.drawPump(pEnv,
393 getLengths(), getTypes(),
394 getMFProperties(), getMFPropIndices(),
395 glOptions.s.uiNumInstances );
397 glEndList();
399 else
401 SWARNING << "Geometry::handleClassicGL: no Pump found for "
402 << "geometry "
403 << this
404 << std::endl;
407 else
409 Int32 vaoGlid =
410 (glOptions.value &
411 GeoPumpGroup::UsesShader) ? getAttribVaoGLId () :
412 getClassicVaoGLId();
414 pWin->validateGLObject(vaoGlid, pEnv, glOptions.value);
416 UInt32 uiValidVAO = pWin->getGLObjectInfo(vaoGlid) & ValidVAO;
418 if(uiValidVAO != 0)
420 GeoPumpGroup::SplitGeoPump pump =
421 GeoPumpGroup::findSplitGeoPump(pEnv,
422 prop);
424 if(pump.drawPump != NULL)
426 OSGGETGLFUNCBYID_GL3(glBindVertexArray,
427 osgGlBindVertexArray,
428 FuncIdBindVertexArray,
429 pWin);
431 osgGlBindVertexArray(pWin->getGLObjectId(vaoGlid));
433 glNewList(glid, GL_COMPILE);
435 pump.drawPump(pEnv,
436 getLengths(), getTypes(),
437 getMFProperties(), getMFPropIndices(),
438 glOptions.s.uiNumInstances );
440 glEndList();
442 osgGlBindVertexArray(0);
444 else
446 SWARNING << "Geometry::handleClassicGL: no Pump found for "
447 << "geometry "
448 << this
449 << std::endl;
454 else
456 SWARNING << "Geometry(" << this << ")::handleClassicGL: Illegal mode: "
457 << mode << " for id " << id << std::endl;
459 #endif
461 return 0;
464 void Geometry::handleClassicDestroyGL(DrawEnv *pEnv,
465 UInt32 id,
466 Window::GLObjectStatusE mode)
468 #if !defined(OSG_OGL_COREONLY) || defined(OSG_CHECK_COREONLY)
469 UInt32 glid;
470 Window *pWin = pEnv->getWindow();
472 if(mode == Window::destroy)
474 glid = pWin->getGLObjectId(id);
476 glDeleteLists(glid, 1);
478 else if(mode == Window::finaldestroy)
480 //SWARNING << "Last geometry user destroyed" << std::endl;
482 else
484 SWARNING << "Geometry::handleClassicDestroyGL: Illegal mode: "
485 << mode << " for id " << id << std::endl;
487 #endif
490 UInt32 Geometry::handleAttGL(DrawEnv *pEnv,
491 UInt32 id,
492 Window::GLObjectStatusE mode,
493 UInt64 uiOptions)
495 #if !defined(OSG_OGL_COREONLY) || defined(OSG_CHECK_COREONLY)
496 UInt32 glid;
497 Window *pWin = pEnv->getWindow();
498 GLHandlerOptions glOptions = { uiOptions };
500 if(mode == Window::initialize || mode == Window::needrefresh ||
501 mode == Window::reinitialize)
503 if(mode == Window::initialize)
505 glid = glGenLists(1);
506 pWin->setGLObjectId(id, glid);
508 else
510 glid = pWin->getGLObjectId(id);
513 GeoPumpGroup::PropertyCharacteristics prop = glOptions.s.uiOptions;
515 if(((prop & (GeoPumpGroup::SingleIndexed |
516 GeoPumpGroup::NonIndexed )) == 0x0000))
518 GeoPumpGroup::GeoPump pump = GeoPumpGroup::findGeoPump(pEnv,
519 prop);
520 glNewList(glid, GL_COMPILE);
522 if(pump != NULL)
524 pump(pEnv,
525 getLengths(), getTypes(),
526 getMFProperties(), getMFPropIndices(),
527 glOptions.s.uiNumInstances );
529 else
531 SWARNING << "Geometry::handleAttGL: no Pump found for "
532 << "geometry "
533 << this
534 << std::endl;
537 glEndList();
539 else if(_sfUseVAO.getValue() == false ||
540 !pWin->hasExtension(_arbVertexArrayObject) ||
541 (prop & GeoPumpGroup::AllVAOMask) != GeoPumpGroup::AllVAOMask)
543 GeoPumpGroup::SplitGeoPump pump =
544 GeoPumpGroup::findSplitGeoPump(pEnv,
545 prop);
547 if(pump.drawPump != NULL)
549 glNewList(glid, GL_COMPILE);
551 pump.drawPump(pEnv,
552 getLengths(), getTypes(),
553 getMFProperties(), getMFPropIndices(),
554 glOptions.s.uiNumInstances );
556 glEndList();
558 else
560 SWARNING << "Geometry::handleAttGL: no Pump found for "
561 << "geometry "
562 << this
563 << std::endl;
566 else
568 Int32 vaoGlid =
569 (glOptions.value &
570 GeoPumpGroup::UsesShader) ? getAttribVaoGLId () :
571 getClassicVaoGLId();
573 pWin->validateGLObject(vaoGlid, pEnv, glOptions.value);
575 UInt32 uiValidVAO = pWin->getGLObjectInfo(vaoGlid) & ValidVAO;
577 if(uiValidVAO != 0)
579 GeoPumpGroup::SplitGeoPump pump =
580 GeoPumpGroup::findSplitGeoPump(pEnv,
581 prop);
583 if(pump.drawPump != NULL)
585 OSGGETGLFUNCBYID_GL3(glBindVertexArray,
586 osgGlBindVertexArray,
587 FuncIdBindVertexArray,
588 pWin);
590 osgGlBindVertexArray(pWin->getGLObjectId(vaoGlid));
592 glNewList(glid, GL_COMPILE);
594 pump.drawPump(pEnv,
595 getLengths(), getTypes(),
596 getMFProperties(), getMFPropIndices(),
597 glOptions.s.uiNumInstances );
599 glEndList();
601 osgGlBindVertexArray(0);
603 else
605 SWARNING << "Geometry::handleAttGL: no Pump found for "
606 << "geometry "
607 << this
608 << std::endl;
613 else
615 SWARNING << "Geometry(" << this << ")::handleAttGL: Illegal mode: "
616 << mode << " for id " << id << std::endl;
618 #endif
620 return 0;
623 void Geometry::handleAttDestroyGL(DrawEnv *pEnv,
624 UInt32 id,
625 Window::GLObjectStatusE mode)
627 #if !defined(OSG_OGL_COREONLY) || defined(OSG_CHECK_COREONLY)
628 UInt32 glid;
629 Window *pWin = pEnv->getWindow();
631 if(mode == Window::destroy)
633 glid = pWin->getGLObjectId(id);
635 glDeleteLists(glid, 1);
637 else if(mode == Window::finaldestroy)
639 //SWARNING << "Last geometry user destroyed" << std::endl;
641 else
643 SWARNING << "Geometry::handleAttDestroyGL: Illegal mode: "
644 << mode << " for id " << id << std::endl;
646 #endif
649 UInt32 Geometry::handleVAOGL(DrawEnv *pEnv,
650 UInt32 id,
651 Window::GLObjectStatusE mode,
652 UInt64 uiOptions)
654 UInt32 glid;
655 Window *pWin = pEnv->getWindow();
656 GLHandlerOptions glOptions = { uiOptions };
658 if(!pWin->hasExtension(_arbVertexArrayObject))
660 SWARNING << "Geometry::handleVAOGL: Extension "
661 << "'GL_ARB_vertex_array_object' not supported by window "
662 << pWin << std::endl;
663 return 0;
666 if(mode == Window::initialize || mode == Window::needrefresh ||
667 mode == Window::reinitialize)
669 if(mode == Window::initialize)
671 OSGGETGLFUNCBYID_GL3_ES(glGenVertexArrays,
672 osgGlGenVertexArrays,
673 FuncIdGenVertexArrays,
674 pWin);
676 osgGlGenVertexArrays(1, &glid);
678 pWin->setGLObjectId(id, glid);
680 else
682 glid = pWin->getGLObjectId(id);
685 GeoPumpGroup::PropertyCharacteristics prop = glOptions.s.uiOptions;
687 GeoPumpGroup::SplitGeoPump pump = GeoPumpGroup::findSplitGeoPump(pEnv,
688 prop);
689 if(pump.setupPump != NULL)
691 OSGGETGLFUNCBYID_GL3_ES(glBindVertexArray,
692 osgGlBindVertexArray,
693 FuncIdBindVertexArray,
694 pWin);
696 osgGlBindVertexArray(glid);
698 bool rc = pump.setupPump(pEnv,
699 getLengths(), getTypes(),
700 getMFProperties(), getMFPropIndices(),
701 false );
703 UInt32 uiObjInfo = rc ? ValidVAO : 0x00;
705 uiObjInfo |= (prop & GeoPumpGroup::UsesShader);
707 pWin->setGLObjectInfo(id, uiObjInfo);
709 osgGlBindVertexArray(0);
711 else
713 SWARNING << "Geometry::handleVAOGL: no Pump found for geometry "
714 << this
715 << std::endl;
718 else
720 SWARNING << "Geometry(" << this << ")::handleVAOGL: Illegal mode: "
721 << mode << " for id " << id << std::endl;
724 return 0;
727 void Geometry::handleVAODestroyGL(DrawEnv *pEnv,
728 UInt32 id,
729 Window::GLObjectStatusE mode)
731 UInt32 glid;
732 Window *pWin = pEnv->getWindow();
734 if(!pWin->hasExtension(_arbVertexArrayObject))
736 SWARNING << "Geometry::handleVAODestroyGL: Extension "
737 << "'GL_ARB_vertex_array_object' not supported by window "
738 << pWin
739 << std::endl;
740 return;
743 if(mode == Window::destroy)
745 OSGGETGLFUNCBYID_GL3_ES(glDeleteVertexArrays,
746 osgGlDeleteVertexArrays,
747 FuncIdDeleteVertexArrays,
748 pWin);
750 glid = pWin->getGLObjectId(id);
752 osgGlDeleteVertexArrays(1, &glid);
754 else if(mode == Window::finaldestroy)
756 //SWARNING << "Last geometry user destroyed" << std::endl;
758 else
760 SWARNING << "Geometry::handleVAODestroyGL: Illegal mode: "
761 << mode << " for id " << id << std::endl;
765 void Geometry::drawPrimitives(DrawEnv *pEnv)
767 this->drawPrimitives(pEnv, 1);
770 void Geometry::drawPrimitives(DrawEnv *pEnv, UInt32 uiNumInstances)
772 Window *pWin = pEnv->getWindow();
773 bool usesShader = false;
775 if(!pWin->hasExtOrVersion(_arbDrawInstanced, 0x0300, 0x0200))
777 uiNumInstances = 1;
780 // Quick solution must be cleaned up.
781 if(_sfUseAttribCalls.getValue() == true)
783 usesShader = true;
785 else
787 if(pEnv->getActiveShader() != 0)
789 if((pEnv->getRequiredOGLFeature() &
790 HardwareContext::HasAttribAliasing) == 0x0000)
792 usesShader = true;
794 else
796 usesShader = (pEnv->getWindow()->getOGLFeatures() &
797 HardwareContext::HasAttribAliasing ) != 0x0000;
802 GeoPumpGroup::PropertyCharacteristics prop;
804 prop = GeoPumpGroup::characterizeGeometry(this);
806 if(usesShader)
807 prop |= GeoPumpGroup::UsesShader;
809 GLHandlerOptions glOptions;
811 glOptions.s.uiOptions = prop;
812 glOptions.s.uiNumInstances = uiNumInstances;
814 #if !defined(OSG_OGL_COREONLY) || defined(OSG_CHECK_COREONLY)
815 // store glColor.
816 Color4f color;
818 if(getColors() != NULL)
819 glGetFloatv(GL_CURRENT_COLOR, color.getValuesRGBA());
820 #endif
822 if(_sfPatchVertices.getValue() != 0)
824 OSGGETGLFUNCBYID_GL3(glPatchParameteri,
825 osgGlPatchParameteri,
826 Geometry::FuncPatchParameterI,
827 pWin );
829 osgGlPatchParameteri(GL_PATCH_VERTICES, _sfPatchVertices.getValue());
832 if(((prop & (GeoPumpGroup::SingleIndexed |
833 GeoPumpGroup::NonIndexed )) == 0x0000)) // ||
834 // (prop & GeoPumpGroup::AllVAOMask ) != GeoPumpGroup::AllVAOMask)
836 #if !defined(OSG_OGL_COREONLY) || defined(OSG_CHECK_COREONLY)
837 if(getDlistCache() == true)
839 Int32 glid;
841 if(usesShader)
843 glid = getAttGLId();
845 else
847 glid = getClassicGLId();
850 pWin->validateGLObject(glid, pEnv, glOptions.value);
852 glCallList(pEnv->getWindow()->getGLObjectId(glid));
854 else
855 #endif
857 GeoPumpGroup::GeoPump pump = GeoPumpGroup::findGeoPump(pEnv,
858 prop);
859 if(pump != NULL)
861 pump(pEnv,
862 getLengths(), getTypes(),
863 getMFProperties(), getMFPropIndices(),
864 uiNumInstances );
866 else
868 SWARNING << "Geometry::drawPrimitives: no Pump found for "
869 << "geometry "
870 << this
871 << std::endl;
875 else if( _sfUseVAO.getValue() == false ||
876 !pWin->hasExtension(_arbVertexArrayObject) ||
877 (prop & GeoPumpGroup::AllVAOMask) != GeoPumpGroup::AllVAOMask)
879 #if (!defined(OSG_OGL_COREONLY) || defined(OSG_CHECK_COREONLY)) && \
880 !defined(__APPLE__)
881 if(getDlistCache() == true && uiNumInstances == 1)
883 Int32 glid;
885 if(usesShader)
887 glid = getAttGLId();
889 else
891 glid = getClassicGLId();
894 GeoPumpGroup::SplitGeoPump pump =
895 GeoPumpGroup::findSplitGeoPump(pEnv,
896 prop);
898 if(pump.setupPump != NULL)
900 bool rc = pump.setupPump(pEnv,
901 getLengths(),
902 getTypes(),
903 getMFProperties(),
904 getMFPropIndices(),
905 true );
907 if(rc == true)
909 pWin->validateGLObject(glid, pEnv, glOptions.value);
911 glCallList(pEnv->getWindow()->getGLObjectId(glid));
913 pump.shutdownPump(pEnv,
914 getLengths(),
915 getTypes(),
916 getMFProperties(),
917 getMFPropIndices());
919 else // fallback
921 GeoPumpGroup::GeoPump pumpFallback =
922 GeoPumpGroup::findGeoPump(pEnv,
923 prop);
924 if(pumpFallback != NULL)
926 pumpFallback(pEnv,
927 getLengths(), getTypes(),
928 getMFProperties(), getMFPropIndices(),
929 uiNumInstances );
934 else
935 #endif
937 GeoPumpGroup::GeoPump pump = GeoPumpGroup::findGeoPump(pEnv,
938 prop);
939 if(pump != NULL)
941 pump(pEnv,
942 getLengths(), getTypes(),
943 getMFProperties(), getMFPropIndices(),
944 uiNumInstances );
946 else
948 SWARNING << "Geometry::drawPrimitives: no Pump found for "
949 << "geometry "
950 << this
951 << std::endl;
955 else
957 Int32 vaoGlid =
958 (glOptions.value &
959 GeoPumpGroup::UsesShader) ? getAttribVaoGLId () :
960 getClassicVaoGLId();
962 pWin->validateGLObject(vaoGlid, pEnv, glOptions.value);
964 UInt32 uiVAOInfo = pWin->getGLObjectInfo(vaoGlid);
966 #ifdef OSG_DEBUG
967 if((prop & GeoPumpGroup::UsesShader) !=
968 (uiVAOInfo & GeoPumpGroup::UsesShader) )
970 fprintf(stderr, "vao shader settings not equal : %04x | %04x\n",
971 (prop & GeoPumpGroup::UsesShader),
972 (uiVAOInfo & GeoPumpGroup::UsesShader));
974 #endif
976 if((uiVAOInfo & ValidVAO) != 0)
978 GeoPumpGroup::SplitGeoPump pump =
979 GeoPumpGroup::findSplitGeoPump(pEnv,
980 prop);
982 if(pump.drawPump != NULL)
984 OSGGETGLFUNCBYID_GL3(glBindVertexArray,
985 osgGlBindVertexArray,
986 FuncIdBindVertexArray,
987 pWin);
989 #if (!defined(OSG_OGL_COREONLY) || defined(OSG_CHECK_COREONLY)) && \
990 !defined(__APPLE__)
991 if(getDlistCache() == true && uiNumInstances == 1 &&
992 pWin->hasVAODListProblems() == false)
994 Int32 glid;
996 if(usesShader)
998 glid = getAttGLId();
1000 else
1002 glid = getClassicGLId();
1005 pWin->validateGLObject(glid, pEnv, glOptions.value);
1007 osgGlBindVertexArray(
1008 pEnv->getWindow()->getGLObjectId(vaoGlid));
1010 glCallList(pEnv->getWindow()->getGLObjectId(glid));
1012 osgGlBindVertexArray(0);
1014 else
1015 #endif
1017 osgGlBindVertexArray(
1018 pEnv->getWindow()->getGLObjectId(vaoGlid));
1020 pump.drawPump(pEnv,
1021 getLengths(),
1022 getTypes(),
1023 getMFProperties(),
1024 getMFPropIndices(),
1025 uiNumInstances );
1027 osgGlBindVertexArray(0);
1030 else
1032 SWARNING << "Geometry::drawPrimitives: no Pump found "
1033 << "for geometry "
1034 << this
1035 << std::endl;
1041 #if !defined(OSG_OGL_COREONLY) || defined(OSG_CHECK_COREONLY)
1042 // restore glColor.
1043 if(getColors() != NULL)
1044 glColor4fv(color.getValuesRGBA());
1045 #endif
1048 /*! The IntersectAction callback for Geometry. It computes if the ray used in
1049 the IntersectAction \a action hits this object and if that is the case,
1050 which triangle is hit.
1052 \param[in] action IntersectAction performing the intersect test.
1053 \return Action result code, \see OSG::Action.
1055 \note This method is registered with the IntersectAction and automatically
1056 called from there, you probably never have to call it manually.
1059 Action::ResultE Geometry::intersectEnter(Action * action)
1061 IntersectAction *ia = dynamic_cast<IntersectAction*>(action);
1063 ia->getActNode()->updateVolume();
1064 const BoxVolume &bv = ia->getActNode()->getVolume();
1066 if(bv.isValid() && !bv.intersect(ia->getLine()))
1068 return Action::Skip; //bv missed -> can not hit children
1071 UInt32 numTris = 0;
1072 TriangleIterator it = this->beginTriangles();
1073 TriangleIterator end = this->endTriangles ();
1074 Real32 t;
1075 Vec3f norm;
1076 const Line &ia_line = ia->getLine();
1078 for(; it != end; ++it)
1080 ++numTris;
1082 if(ia_line.intersect(it.getPosition(0),
1083 it.getPosition(1),
1084 it.getPosition(2), t, &norm))
1086 ia->setHit(t, ia->getActNode(), it.getIndex(), norm, -1);
1090 // If we need to test lines, iterate over lines and test for
1091 // lines that are within width distance from the line
1092 if(ia->getTestLines())
1094 Real32 range_sq = ia->getTestLineWidth();
1095 range_sq = range_sq * range_sq;
1096 LineIterator lIt = this->beginLines();
1097 LineIterator lEnd = this->endLines ();
1098 Pnt3f pt1, pt2;
1100 // Find closest points and if they are within the range, then add a hit
1101 for(; lIt != lEnd; ++lIt)
1103 Line cur_line(lIt.getPosition(0), lIt.getPosition(1));
1104 ia_line.getClosestPoints(cur_line, pt1, pt2);
1105 Real32 dist_sq( pt1.dist2(pt2) );
1107 if (dist_sq <= range_sq)
1109 t = ia_line.getPosition().dist(pt1);
1110 ia->setHit(t, ia->getActNode(), -1, norm, lIt.getIndex());
1115 ia->getStatCollector()->getElem(IntersectAction::statNTriangles)->add(numTris);
1117 return Action::Continue;
1120 /*----------------------------- class specific ----------------------------*/
1121 void Geometry::changed(ConstFieldMaskArg whichField,
1122 UInt32 origin,
1123 BitVector details)
1125 #if !defined(OSG_OGL_COREONLY)
1126 // Handle change to the display list cache field.
1127 if(whichField & DlistCacheFieldMask)
1129 if(getDlistCache())
1131 // Ensure that we have OpenGL objects for display list.
1132 if(getClassicGLId() == 0)
1134 setClassicGLId(
1135 Window::registerGLObject(
1136 boost::bind(&Geometry::handleClassicGL,
1137 GeometryMTUncountedPtr(this),
1138 _1, _2, _3, _4),
1139 &Geometry::handleClassicDestroyGL));
1141 if(getAttGLId() == 0)
1143 setAttGLId(
1144 Window::registerGLObject(
1145 boost::bind(&Geometry::handleAttGL,
1146 GeometryMTUncountedPtr(this),
1147 _1, _2, _3, _4),
1148 &Geometry::handleAttDestroyGL));
1151 else
1153 // Delete old display list objects.
1154 if(getClassicGLId() != 0)
1156 Window::destroyGLObject(getClassicGLId(), 1);
1158 setClassicGLId(0);
1160 if(getAttGLId() != 0)
1162 Window::destroyGLObject(getAttGLId(), 1);
1164 setAttGLId(0);
1168 #endif
1170 // If something changed inside the geometry fields and we are using
1171 // display lists, refresh them.
1172 if(whichField & (TypesFieldMask | LengthsFieldMask |
1173 PropertiesFieldMask | PropIndicesFieldMask))
1175 if(this->getDlistCache() == true)
1177 #if !defined(OSG_OGL_COREONLY)
1178 Window::refreshGLObject(getClassicGLId());
1179 #endif
1180 Window::refreshGLObject(getAttGLId ());
1183 if(this->getUseVAO() == true)
1185 Window::refreshGLObject(getClassicVaoGLId());
1186 Window::refreshGLObject(getAttribVaoGLId ());
1190 if(whichField & PropertiesFieldMask)
1192 for(UInt32 i = 0; i < _mfParents.size(); i++)
1194 _mfParents[i]->invalidateVolume();
1197 _volumeCache.setValid();
1198 _volumeCache.setEmpty();
1201 Inherited::changed(whichField, origin, details);
1204 void Geometry::dump( UInt32 ,
1205 const BitVector ) const
1207 SLOG << "Dump Geometry NI" << std::endl;
1210 UInt32 Geometry::indexOccurrence(GeoIntegralProperty * const value) const
1212 UInt32 returnValue = 0;
1214 for(UInt32 i = 0; i < _mfPropIndices.size(); ++i)
1216 if(_mfPropIndices[i] != NULL && _mfPropIndices[i] == value)
1218 ++returnValue;
1222 return returnValue;
1225 bool Geometry::isSingleIndex(void) const
1227 bool returnValue = true;
1229 for(UInt32 i = PositionsIndex; i < _mfPropIndices.size(); ++i)
1231 if(_mfPropIndices[i] != NULL &&
1232 _mfPropIndices[i] != _mfPropIndices[PositionsIndex] )
1234 returnValue = false;
1235 break;
1239 return returnValue;
1242 /*! Returns the indices properties of this geometry together with information
1243 for which properties they are used.
1244 Each element of the returned vector holds a pointer to an indices property
1245 and a vector indicating which properties are indexed by it.
1247 Geometry::IndexBag Geometry::getUniqueIndexBag(void) const
1249 typedef IndexBag::value_type IndexBagEntry;
1251 IndexBag returnValue;
1252 UInt32 i;
1254 // Find the first valid prop
1255 for(i = 0; i < _mfPropIndices.size(); ++i)
1257 if(_mfPropIndices[i] != NULL)
1259 break;
1263 if(i == _mfPropIndices.size())
1264 return returnValue;
1266 IndexBagEntry oEntry;
1268 oEntry.first = _mfPropIndices[i];
1269 oEntry.second.push_back(i);
1271 returnValue.push_back(oEntry);
1273 bool bFoundProp;
1275 for(UInt32 j = i + 1; j < _mfPropIndices.size(); ++j)
1277 bFoundProp = false;
1279 for(UInt32 k = 0; k < returnValue.size() && bFoundProp == false; ++k)
1281 if(_mfPropIndices[j] == returnValue[k].first)
1283 returnValue[k].second.push_back(j);
1285 bFoundProp = true;
1289 if(bFoundProp == false && _mfPropIndices[j] != NULL)
1291 IndexBagEntry oEntryProp;
1293 oEntryProp.first = _mfPropIndices[j];
1294 oEntryProp.second.push_back(j);
1296 returnValue.push_back(oEntryProp);
1300 return returnValue;
1303 void Geometry::fill(DrawableStatsAttachment *pStat)
1305 if(pStat == NULL)
1307 FINFO(("Geometry::fill(DrawableStatsAttachment *): "
1308 "No attachment given.\n"));
1310 return;
1313 // Att Bytes
1314 UInt32 storedAttBytes = 0;
1315 UInt32 attBytesPerVertex = 0;
1317 for(UInt16 i = 0; i < Geometry::MaxAttribs; ++i)
1319 if(this->getProperty(i) == NULL)
1320 continue;
1322 attBytesPerVertex += this->getProperty(i)->getFormatSize() *
1323 this->getProperty(i)->getDimension();
1324 storedAttBytes += this->getProperty(i)->getFormatSize() *
1325 this->getProperty(i)->getDimension() *
1326 this->getProperty(i)->size32();
1330 GeoIntegralProperty *geoTypePtr = this->getTypes();
1331 GeoIntegralProperty *lensPtr = this->getLengths();
1333 UInt32 lN, tN, len, type;
1335 lN = (lensPtr == NULL) ? 0 : lensPtr ->size32();
1336 tN = (geoTypePtr == NULL) ? 0 : geoTypePtr->size32();
1338 if((tN == 0) || (lN != 0 && tN != lN) || (lN == 0 && tN != 1))
1340 FINFO(("GeoStatsAttachment::calc: "
1341 "Lengths and Types information mismatch.\n"));
1342 return;
1345 UInt32 triangle = 0, line = 0, point = 0, vertices = 0, patches = 0,
1346 procAttBytes = 0;
1348 for(UInt32 i = 0; i < tN; ++i)
1350 geoTypePtr->getValue(type, i);
1352 if(lN != 0)
1354 lensPtr->getValue(len, i);
1356 else
1358 GeoVectorProperty *pos = this->getPositions();
1360 if(pos == NULL)
1362 FINFO(("GeoStatsAttachment::calc: No Positions!\n"));
1363 return;
1366 len = pos->size32();
1369 vertices += len;
1370 procAttBytes += len * attBytesPerVertex;
1372 switch(type)
1374 case GL_POINTS:
1375 point += len;
1376 break;
1377 case GL_LINES:
1378 line += len / 2;
1379 break;
1380 case GL_LINE_LOOP:
1381 line += len;
1382 break;
1383 case GL_LINE_STRIP:
1384 line += len - 1;
1385 break;
1386 case GL_TRIANGLES:
1387 triangle += len / 3;
1388 break;
1389 case GL_TRIANGLE_STRIP:
1390 triangle += len - 2;
1391 break;
1392 case GL_TRIANGLE_FAN:
1393 triangle += len - 2;
1394 break;
1395 case GL_QUADS:
1396 triangle += len / 2;
1397 break;
1398 case GL_QUAD_STRIP:
1399 triangle += len - 2;
1400 break;
1401 case GL_POLYGON:
1402 triangle += len - 2;
1403 break;
1404 case GL_PATCHES:
1405 patches += 1;
1406 break;
1407 case GL_LINES_ADJACENCY_EXT:
1408 line += len / 4;
1409 break;
1410 case GL_LINE_STRIP_ADJACENCY_EXT:
1411 line += len - 3;
1412 break;
1413 case GL_TRIANGLES_ADJACENCY_EXT:
1414 triangle += len / 6;
1415 break;
1416 case GL_TRIANGLE_STRIP_ADJACENCY_EXT:
1417 triangle += len / 2 - 2;
1418 break;
1419 default:
1420 FWARNING(("GeoStatsAttachment::calc: Invalid geoType: %d\n",
1421 type));
1422 break;
1426 pStat->setVertices(vertices);
1427 pStat->setPoints(point);
1428 pStat->setLines(line);
1429 pStat->setTriangles(triangle);
1430 pStat->setPatches(patches);
1431 pStat->setStoredAttributeBytes(storedAttBytes);
1432 pStat->setProcessedAttributeBytes(procAttBytes);
1433 pStat->setValid(true);
1436 // Iterators
1439 /*-------------------------- Primitive Iterator --------------------------------*/
1441 /*! Return a PrimitiveIterator poiting to the beginning of the Geometry.
1443 PrimitiveIterator Geometry::beginPrimitives(void) const
1445 PrimitiveIterator it(this);
1447 it.setToBegin();
1449 return it;
1452 /*! Return a PrimitiveIterator poiting to the end of the Geometry.
1454 PrimitiveIterator Geometry::endPrimitives(void) const
1456 PrimitiveIterator it(this);
1458 it.setToEnd();
1460 return it;
1463 /*! Return a TriangleIterator poiting to the beginning of the Geometry.
1465 TriangleIterator Geometry::beginTriangles(void) const
1467 TriangleIterator it(this);
1469 it.setToBegin();
1471 return it;
1474 /*! Return a TriangleIterator poiting to the end of the Geometry.
1476 TriangleIterator Geometry::endTriangles(void) const
1478 TriangleIterator it(this);
1480 it.setToEnd();
1482 return it;
1485 /*! Return a FaceIterator poiting to the beginning of the Geometry.
1487 FaceIterator Geometry::beginFaces(void) const
1489 FaceIterator it(this);
1491 it.setToBegin();
1493 return it;
1496 /*! Return a FaceIterator poiting to the end of the Geometry.
1498 FaceIterator Geometry::endFaces(void) const
1500 FaceIterator it(this);
1502 it.setToEnd();
1504 return it;
1507 /*! Return a LineIterator poiting to the beginning of the Geometry.
1509 LineIterator Geometry::beginLines(void) const
1511 LineIterator it(this);
1513 it.setToBegin();
1515 return it;
1518 /*! Return a LineIterator poiting to the end of the Geometry.
1520 LineIterator Geometry::endLines(void) const
1522 LineIterator it(this);
1524 it.setToEnd();
1526 return it;
1529 /*! Return a EdgeIterator poiting to the beginning of the Geometry.
1531 EdgeIterator Geometry::beginEdges(void) const
1533 EdgeIterator it(this);
1535 it.setToBegin();
1537 return it;
1540 /*! Return a EdgeIterator pointing to the end of the Geometry.
1542 EdgeIterator Geometry::endEdges(void) const
1544 EdgeIterator it(this);
1546 it.setToEnd();
1548 return it;
1551 /*! Return a PointIterator pointing to the beginning of the Geometry.
1553 PointIterator Geometry::beginPoints(void) const
1555 PointIterator it(this);
1557 it.setToBegin();
1559 return it;
1562 /*! Return a PointIterator pointing to the end of the Geometry.
1564 PointIterator Geometry::endPoints(void) const
1566 PointIterator it(this);
1568 it.setToEnd();
1570 return it;
1573 OSG_END_NAMESPACE