1 /*---------------------------------------------------------------------------*\
5 * Copyright (C) 2000-2002 by the OpenSG Forum *
9 * contact: dirk@opensg.org, gerrit.voss@vossg.org, jbehr@zgdv.de *
11 \*---------------------------------------------------------------------------*/
12 /*---------------------------------------------------------------------------*\
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. *
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. *
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. *
28 \*---------------------------------------------------------------------------*/
29 /*---------------------------------------------------------------------------*\
37 \*---------------------------------------------------------------------------*/
39 //---------------------------------------------------------------------------
41 //---------------------------------------------------------------------------
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"
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 /***************************************************************************\
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 /***************************************************************************\
95 \***************************************************************************/
97 void Geometry::initMethod(InitPhase ePhase
)
99 if(ePhase
== TypeObject::SystemPost
)
101 IntersectAction::registerEnterDefault(
103 reinterpret_cast<Action::Callback
>(&Geometry::intersectEnter
));
105 RenderAction::registerEnterDefault(
107 reinterpret_cast<Action::Callback
>(
108 &MaterialDrawable::renderEnter
));
110 RenderAction::registerLeaveDefault(
112 reinterpret_cast<Action::Callback
>(
113 &MaterialDrawable::renderLeave
));
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
);
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
);
155 _arbTessellationShader
=
156 Window::registerExtension("GL_ARB_tessellation_shader");
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",
171 FuncIdDrawArraysInstanced
=
172 Window::registerFunction
173 (OSG_DLSYM_UNDERSCORE
"glDrawArraysInstanced",
179 /*! A little helper function to map the OpenGL primitive type to a name.
181 const char *Geometry::mapType(UInt8 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 /***************************************************************************\
207 \***************************************************************************/
209 /*-------------------------------------------------------------------------*\
211 \*-------------------------------------------------------------------------*/
213 /*----------------------- constructors & destructors ----------------------*/
215 Geometry::Geometry(void) :
221 Geometry::Geometry(const Geometry
&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
)
239 #if !defined(OSG_OGL_COREONLY)
241 Window::registerGLObject(
242 boost::bind(&Geometry::handleClassicGL
,
243 GeometryMTUncountedPtr(this),
245 &Geometry::handleClassicDestroyGL
));
249 Window::registerGLObject(
250 boost::bind(&Geometry::handleAttGL
,
251 GeometryMTUncountedPtr(this),
253 &Geometry::handleAttDestroyGL
));
256 Window::registerGLObject(
257 boost::bind(&Geometry::handleVAOGL
,
258 GeometryMTUncountedPtr(this),
260 &Geometry::handleVAODestroyGL
));
262 Window::registerGLObject(
263 boost::bind(&Geometry::handleVAOGL
,
264 GeometryMTUncountedPtr(this),
266 &Geometry::handleVAODestroyGL
));
269 void Geometry::onDestroy(UInt32 uiContainerId
)
271 #if !defined(OSG_OGL_COREONLY)
272 if(getClassicGLId() > 0)
273 Window::destroyGLObject(getClassicGLId(), 1);
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.
297 volume
.extendBy(_volumeCache
);
302 GeoVectorProperty
*pos
= getPositions();
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
,
328 Window::GLObjectStatusE mode
,
331 #if !defined(OSG_OGL_COREONLY) || defined(OSG_CHECK_COREONLY)
333 Window
*pWin
= pEnv
->getWindow();
334 GLHandlerOptions glOptions
= { uiOptions
};
337 Geometry
*pAspectGeo
= Aspect::convertToCurrent
<Geometry
*>(this);
338 OSG_ASSERT(pAspectGeo
== this);
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
);
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
);
366 getLengths(), getTypes(),
367 getMFProperties(), getMFPropIndices(),
368 glOptions
.s
.uiNumInstances
);
372 SWARNING
<< "Geometry::handleClassicGL: no Pump found for "
380 else if(_sfUseVAO
.getValue() == false ||
381 !pWin
->hasExtension(_arbVertexArrayObject
) ||
382 (prop
& GeoPumpGroup::AllVAOMask
) != GeoPumpGroup::AllVAOMask
)
384 GeoPumpGroup::SplitGeoPump pump
=
385 GeoPumpGroup::findSplitGeoPump(pEnv
,
388 if(pump
.drawPump
!= NULL
)
390 glNewList(glid
, GL_COMPILE
);
393 getLengths(), getTypes(),
394 getMFProperties(), getMFPropIndices(),
395 glOptions
.s
.uiNumInstances
);
401 SWARNING
<< "Geometry::handleClassicGL: no Pump found for "
411 GeoPumpGroup::UsesShader
) ? getAttribVaoGLId () :
414 pWin
->validateGLObject(vaoGlid
, pEnv
, glOptions
.value
);
416 UInt32 uiValidVAO
= pWin
->getGLObjectInfo(vaoGlid
) & ValidVAO
;
420 GeoPumpGroup::SplitGeoPump pump
=
421 GeoPumpGroup::findSplitGeoPump(pEnv
,
424 if(pump
.drawPump
!= NULL
)
426 OSGGETGLFUNCBYID_GL3(glBindVertexArray
,
427 osgGlBindVertexArray
,
428 FuncIdBindVertexArray
,
431 osgGlBindVertexArray(pWin
->getGLObjectId(vaoGlid
));
433 glNewList(glid
, GL_COMPILE
);
436 getLengths(), getTypes(),
437 getMFProperties(), getMFPropIndices(),
438 glOptions
.s
.uiNumInstances
);
442 osgGlBindVertexArray(0);
446 SWARNING
<< "Geometry::handleClassicGL: no Pump found for "
456 SWARNING
<< "Geometry(" << this << ")::handleClassicGL: Illegal mode: "
457 << mode
<< " for id " << id
<< std::endl
;
464 void Geometry::handleClassicDestroyGL(DrawEnv
*pEnv
,
466 Window::GLObjectStatusE mode
)
468 #if !defined(OSG_OGL_COREONLY) || defined(OSG_CHECK_COREONLY)
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;
484 SWARNING
<< "Geometry::handleClassicDestroyGL: Illegal mode: "
485 << mode
<< " for id " << id
<< std::endl
;
490 UInt32
Geometry::handleAttGL(DrawEnv
*pEnv
,
492 Window::GLObjectStatusE mode
,
495 #if !defined(OSG_OGL_COREONLY) || defined(OSG_CHECK_COREONLY)
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
);
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
,
520 glNewList(glid
, GL_COMPILE
);
525 getLengths(), getTypes(),
526 getMFProperties(), getMFPropIndices(),
527 glOptions
.s
.uiNumInstances
);
531 SWARNING
<< "Geometry::handleAttGL: no Pump found for "
539 else if(_sfUseVAO
.getValue() == false ||
540 !pWin
->hasExtension(_arbVertexArrayObject
) ||
541 (prop
& GeoPumpGroup::AllVAOMask
) != GeoPumpGroup::AllVAOMask
)
543 GeoPumpGroup::SplitGeoPump pump
=
544 GeoPumpGroup::findSplitGeoPump(pEnv
,
547 if(pump
.drawPump
!= NULL
)
549 glNewList(glid
, GL_COMPILE
);
552 getLengths(), getTypes(),
553 getMFProperties(), getMFPropIndices(),
554 glOptions
.s
.uiNumInstances
);
560 SWARNING
<< "Geometry::handleAttGL: no Pump found for "
570 GeoPumpGroup::UsesShader
) ? getAttribVaoGLId () :
573 pWin
->validateGLObject(vaoGlid
, pEnv
, glOptions
.value
);
575 UInt32 uiValidVAO
= pWin
->getGLObjectInfo(vaoGlid
) & ValidVAO
;
579 GeoPumpGroup::SplitGeoPump pump
=
580 GeoPumpGroup::findSplitGeoPump(pEnv
,
583 if(pump
.drawPump
!= NULL
)
585 OSGGETGLFUNCBYID_GL3(glBindVertexArray
,
586 osgGlBindVertexArray
,
587 FuncIdBindVertexArray
,
590 osgGlBindVertexArray(pWin
->getGLObjectId(vaoGlid
));
592 glNewList(glid
, GL_COMPILE
);
595 getLengths(), getTypes(),
596 getMFProperties(), getMFPropIndices(),
597 glOptions
.s
.uiNumInstances
);
601 osgGlBindVertexArray(0);
605 SWARNING
<< "Geometry::handleAttGL: no Pump found for "
615 SWARNING
<< "Geometry(" << this << ")::handleAttGL: Illegal mode: "
616 << mode
<< " for id " << id
<< std::endl
;
623 void Geometry::handleAttDestroyGL(DrawEnv
*pEnv
,
625 Window::GLObjectStatusE mode
)
627 #if !defined(OSG_OGL_COREONLY) || defined(OSG_CHECK_COREONLY)
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;
643 SWARNING
<< "Geometry::handleAttDestroyGL: Illegal mode: "
644 << mode
<< " for id " << id
<< std::endl
;
649 UInt32
Geometry::handleVAOGL(DrawEnv
*pEnv
,
651 Window::GLObjectStatusE mode
,
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
;
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
,
676 osgGlGenVertexArrays(1, &glid
);
678 pWin
->setGLObjectId(id
, glid
);
682 glid
= pWin
->getGLObjectId(id
);
685 GeoPumpGroup::PropertyCharacteristics prop
= glOptions
.s
.uiOptions
;
687 GeoPumpGroup::SplitGeoPump pump
= GeoPumpGroup::findSplitGeoPump(pEnv
,
689 if(pump
.setupPump
!= NULL
)
691 OSGGETGLFUNCBYID_GL3_ES(glBindVertexArray
,
692 osgGlBindVertexArray
,
693 FuncIdBindVertexArray
,
696 osgGlBindVertexArray(glid
);
698 bool rc
= pump
.setupPump(pEnv
,
699 getLengths(), getTypes(),
700 getMFProperties(), getMFPropIndices(),
703 UInt32 uiObjInfo
= rc
? ValidVAO
: 0x00;
705 uiObjInfo
|= (prop
& GeoPumpGroup::UsesShader
);
707 pWin
->setGLObjectInfo(id
, uiObjInfo
);
709 osgGlBindVertexArray(0);
713 SWARNING
<< "Geometry::handleVAOGL: no Pump found for geometry "
720 SWARNING
<< "Geometry(" << this << ")::handleVAOGL: Illegal mode: "
721 << mode
<< " for id " << id
<< std::endl
;
727 void Geometry::handleVAODestroyGL(DrawEnv
*pEnv
,
729 Window::GLObjectStatusE mode
)
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 "
743 if(mode
== Window::destroy
)
745 OSGGETGLFUNCBYID_GL3_ES(glDeleteVertexArrays
,
746 osgGlDeleteVertexArrays
,
747 FuncIdDeleteVertexArrays
,
750 glid
= pWin
->getGLObjectId(id
);
752 osgGlDeleteVertexArrays(1, &glid
);
754 else if(mode
== Window::finaldestroy
)
756 //SWARNING << "Last geometry user destroyed" << std::endl;
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))
780 // Quick solution must be cleaned up.
781 if(_sfUseAttribCalls
.getValue() == true)
787 if(pEnv
->getActiveShader() != 0)
789 if((pEnv
->getRequiredOGLFeature() &
790 HardwareContext::HasAttribAliasing
) == 0x0000)
796 usesShader
= (pEnv
->getWindow()->getOGLFeatures() &
797 HardwareContext::HasAttribAliasing
) != 0x0000;
802 GeoPumpGroup::PropertyCharacteristics prop
;
804 prop
= GeoPumpGroup::characterizeGeometry(this);
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)
818 if(getColors() != NULL
)
819 glGetFloatv(GL_CURRENT_COLOR
, color
.getValuesRGBA());
822 if(_sfPatchVertices
.getValue() != 0)
824 OSGGETGLFUNCBYID_GL3(glPatchParameteri
,
825 osgGlPatchParameteri
,
826 Geometry::FuncPatchParameterI
,
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)
847 glid
= getClassicGLId();
850 pWin
->validateGLObject(glid
, pEnv
, glOptions
.value
);
852 glCallList(pEnv
->getWindow()->getGLObjectId(glid
));
857 GeoPumpGroup::GeoPump pump
= GeoPumpGroup::findGeoPump(pEnv
,
862 getLengths(), getTypes(),
863 getMFProperties(), getMFPropIndices(),
868 SWARNING
<< "Geometry::drawPrimitives: no Pump found for "
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)) && \
881 if(getDlistCache() == true && uiNumInstances
== 1)
891 glid
= getClassicGLId();
894 GeoPumpGroup::SplitGeoPump pump
=
895 GeoPumpGroup::findSplitGeoPump(pEnv
,
898 if(pump
.setupPump
!= NULL
)
900 bool rc
= pump
.setupPump(pEnv
,
909 pWin
->validateGLObject(glid
, pEnv
, glOptions
.value
);
911 glCallList(pEnv
->getWindow()->getGLObjectId(glid
));
913 pump
.shutdownPump(pEnv
,
921 GeoPumpGroup::GeoPump pumpFallback
=
922 GeoPumpGroup::findGeoPump(pEnv
,
924 if(pumpFallback
!= NULL
)
927 getLengths(), getTypes(),
928 getMFProperties(), getMFPropIndices(),
937 GeoPumpGroup::GeoPump pump
= GeoPumpGroup::findGeoPump(pEnv
,
942 getLengths(), getTypes(),
943 getMFProperties(), getMFPropIndices(),
948 SWARNING
<< "Geometry::drawPrimitives: no Pump found for "
959 GeoPumpGroup::UsesShader
) ? getAttribVaoGLId () :
962 pWin
->validateGLObject(vaoGlid
, pEnv
, glOptions
.value
);
964 UInt32 uiVAOInfo
= pWin
->getGLObjectInfo(vaoGlid
);
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
));
976 if((uiVAOInfo
& ValidVAO
) != 0)
978 GeoPumpGroup::SplitGeoPump pump
=
979 GeoPumpGroup::findSplitGeoPump(pEnv
,
982 if(pump
.drawPump
!= NULL
)
984 OSGGETGLFUNCBYID_GL3(glBindVertexArray
,
985 osgGlBindVertexArray
,
986 FuncIdBindVertexArray
,
989 #if (!defined(OSG_OGL_COREONLY) || defined(OSG_CHECK_COREONLY)) && \
991 if(getDlistCache() == true && uiNumInstances
== 1 &&
992 pWin
->hasVAODListProblems() == false)
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);
1017 osgGlBindVertexArray(
1018 pEnv
->getWindow()->getGLObjectId(vaoGlid
));
1027 osgGlBindVertexArray(0);
1032 SWARNING
<< "Geometry::drawPrimitives: no Pump found "
1041 #if !defined(OSG_OGL_COREONLY) || defined(OSG_CHECK_COREONLY)
1043 if(getColors() != NULL
)
1044 glColor4fv(color
.getValuesRGBA());
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
1072 TriangleIterator it
= this->beginTriangles();
1073 TriangleIterator end
= this->endTriangles ();
1076 const Line
&ia_line
= ia
->getLine();
1078 for(; it
!= end
; ++it
)
1082 if(ia_line
.intersect(it
.getPosition(0),
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 ();
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
,
1125 #if !defined(OSG_OGL_COREONLY)
1126 // Handle change to the display list cache field.
1127 if(whichField
& DlistCacheFieldMask
)
1131 // Ensure that we have OpenGL objects for display list.
1132 if(getClassicGLId() == 0)
1135 Window::registerGLObject(
1136 boost::bind(&Geometry::handleClassicGL
,
1137 GeometryMTUncountedPtr(this),
1139 &Geometry::handleClassicDestroyGL
));
1141 if(getAttGLId() == 0)
1144 Window::registerGLObject(
1145 boost::bind(&Geometry::handleAttGL
,
1146 GeometryMTUncountedPtr(this),
1148 &Geometry::handleAttDestroyGL
));
1153 // Delete old display list objects.
1154 if(getClassicGLId() != 0)
1156 Window::destroyGLObject(getClassicGLId(), 1);
1160 if(getAttGLId() != 0)
1162 Window::destroyGLObject(getAttGLId(), 1);
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());
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
)
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;
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
;
1254 // Find the first valid prop
1255 for(i
= 0; i
< _mfPropIndices
.size(); ++i
)
1257 if(_mfPropIndices
[i
] != NULL
)
1263 if(i
== _mfPropIndices
.size())
1266 IndexBagEntry oEntry
;
1268 oEntry
.first
= _mfPropIndices
[i
];
1269 oEntry
.second
.push_back(i
);
1271 returnValue
.push_back(oEntry
);
1275 for(UInt32 j
= i
+ 1; j
< _mfPropIndices
.size(); ++j
)
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
);
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
);
1303 void Geometry::fill(DrawableStatsAttachment
*pStat
)
1307 FINFO(("Geometry::fill(DrawableStatsAttachment *): "
1308 "No attachment given.\n"));
1314 UInt32 storedAttBytes
= 0;
1315 UInt32 attBytesPerVertex
= 0;
1317 for(UInt16 i
= 0; i
< Geometry::MaxAttribs
; ++i
)
1319 if(this->getProperty(i
) == NULL
)
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"));
1345 UInt32 triangle
= 0, line
= 0, point
= 0, vertices
= 0, patches
= 0,
1348 for(UInt32 i
= 0; i
< tN
; ++i
)
1350 geoTypePtr
->getValue(type
, i
);
1354 lensPtr
->getValue(len
, i
);
1358 GeoVectorProperty
*pos
= this->getPositions();
1362 FINFO(("GeoStatsAttachment::calc: No Positions!\n"));
1366 len
= pos
->size32();
1370 procAttBytes
+= len
* attBytesPerVertex
;
1387 triangle
+= len
/ 3;
1389 case GL_TRIANGLE_STRIP
:
1390 triangle
+= len
- 2;
1392 case GL_TRIANGLE_FAN
:
1393 triangle
+= len
- 2;
1396 triangle
+= len
/ 2;
1399 triangle
+= len
- 2;
1402 triangle
+= len
- 2;
1407 case GL_LINES_ADJACENCY_EXT
:
1410 case GL_LINE_STRIP_ADJACENCY_EXT
:
1413 case GL_TRIANGLES_ADJACENCY_EXT
:
1414 triangle
+= len
/ 6;
1416 case GL_TRIANGLE_STRIP_ADJACENCY_EXT
:
1417 triangle
+= len
/ 2 - 2;
1420 FWARNING(("GeoStatsAttachment::calc: Invalid geoType: %d\n",
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);
1439 /*-------------------------- Primitive Iterator --------------------------------*/
1441 /*! Return a PrimitiveIterator poiting to the beginning of the Geometry.
1443 PrimitiveIterator
Geometry::beginPrimitives(void) const
1445 PrimitiveIterator
it(this);
1452 /*! Return a PrimitiveIterator poiting to the end of the Geometry.
1454 PrimitiveIterator
Geometry::endPrimitives(void) const
1456 PrimitiveIterator
it(this);
1463 /*! Return a TriangleIterator poiting to the beginning of the Geometry.
1465 TriangleIterator
Geometry::beginTriangles(void) const
1467 TriangleIterator
it(this);
1474 /*! Return a TriangleIterator poiting to the end of the Geometry.
1476 TriangleIterator
Geometry::endTriangles(void) const
1478 TriangleIterator
it(this);
1485 /*! Return a FaceIterator poiting to the beginning of the Geometry.
1487 FaceIterator
Geometry::beginFaces(void) const
1489 FaceIterator
it(this);
1496 /*! Return a FaceIterator poiting to the end of the Geometry.
1498 FaceIterator
Geometry::endFaces(void) const
1500 FaceIterator
it(this);
1507 /*! Return a LineIterator poiting to the beginning of the Geometry.
1509 LineIterator
Geometry::beginLines(void) const
1511 LineIterator
it(this);
1518 /*! Return a LineIterator poiting to the end of the Geometry.
1520 LineIterator
Geometry::endLines(void) const
1522 LineIterator
it(this);
1529 /*! Return a EdgeIterator poiting to the beginning of the Geometry.
1531 EdgeIterator
Geometry::beginEdges(void) const
1533 EdgeIterator
it(this);
1540 /*! Return a EdgeIterator pointing to the end of the Geometry.
1542 EdgeIterator
Geometry::endEdges(void) const
1544 EdgeIterator
it(this);
1551 /*! Return a PointIterator pointing to the beginning of the Geometry.
1553 PointIterator
Geometry::beginPoints(void) const
1555 PointIterator
it(this);
1562 /*! Return a PointIterator pointing to the end of the Geometry.
1564 PointIterator
Geometry::endPoints(void) const
1566 PointIterator
it(this);