1 // Created on: 2012-04-09
2 // Created by: Sergey ANIKIN
3 // Copyright (c) 2012 OPEN CASCADE SAS
5 // The content of this file is subject to the Open CASCADE Technology Public
6 // License Version 6.5 (the "License"). You may not use the content of this file
7 // except in compliance with the License. Please obtain a copy of the License
8 // at http://www.opencascade.org and read it completely before using this file.
10 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
11 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
13 // The Original Code and all software distributed under the License is
14 // distributed on an "AS IS" basis, without warranty of any kind, and the
15 // Initial Developer hereby disclaims all such warranties, including without
16 // limitation, any warranties of merchantability, fitness for a particular
17 // purpose or non-infringement. Please see the License for the specific terms
18 // and conditions governing the rights and limitations under the License.
24 #include <ViewerTest.hxx>
26 #include <Aspect_GraphicDevice.hxx>
27 #include <AIS_InteractiveContext.hxx>
28 #include <AIS_InteractiveObject.hxx>
30 #include <Draw_Interpretor.hxx>
31 #include <Graphic3d_Group.hxx>
32 #include <OpenGl_ArbVBO.hxx>
33 #include <OpenGl_AspectFace.hxx>
34 #include <OpenGl_AspectLine.hxx>
35 #include <OpenGl_AspectMarker.hxx>
36 #include <OpenGl_AspectText.hxx>
37 #include <OpenGl_Context.hxx>
38 #include <OpenGl_Element.hxx>
39 #include <OpenGl_ExtFBO.hxx>
40 #include <OpenGl_GlCore20.hxx>
41 #include <OpenGl_GraphicDriver.hxx>
42 #include <OpenGl_Workspace.hxx>
43 #include <Prs3d_Presentation.hxx>
44 #include <Prs3d_Root.hxx>
45 #include <Select3D_SensitiveCurve.hxx>
46 #include <SelectMgr_EntityOwner.hxx>
47 #include <SelectMgr_Selection.hxx>
48 #include <V3d_Viewer.hxx>
49 #include <TCollection_AsciiString.hxx>
50 #include <V3d_View.hxx>
52 extern Standard_Boolean VDisplayAISObject (const TCollection_AsciiString& theName,
53 const Handle(AIS_InteractiveObject)& theAISObj,
54 Standard_Boolean theReplaceIfExists = Standard_True);
56 //=======================================================================
57 //function : VUserDraw
58 //purpose : Checks availability and operation of UserDraw feature
59 //=======================================================================
60 DEFINE_STANDARD_HANDLE(VUserDrawObj, AIS_InteractiveObject)
62 class VUserDrawObj : public AIS_InteractiveObject
66 DEFINE_STANDARD_RTTI(VUserDrawObj);
79 class Element : public OpenGl_Element
82 Handle(VUserDrawObj) myIObj;
85 Element (const Handle(VUserDrawObj)& theIObj,
86 CALL_DEF_BOUNDS* theBounds)
90 myIObj->GetBounds(theBounds);
97 virtual void Render (const Handle(OpenGl_Workspace)& theWorkspace) const
100 myIObj->Render(theWorkspace);
103 virtual void Release (const Handle(OpenGl_Context)& theGlCtx)
109 DEFINE_STANDARD_ALLOC
113 // Virtual methods implementation
114 void Compute (const Handle(PrsMgr_PresentationManager3d)& thePresentationManager,
115 const Handle(Prs3d_Presentation)& thePresentation,
116 const Standard_Integer theMode);
118 void ComputeSelection (const Handle(SelectMgr_Selection)& theSelection,
119 const Standard_Integer theMode);
121 // Called by VUserDrawElement
122 void Render(const Handle(OpenGl_Workspace)& theWorkspace) const;
123 void GetBounds(CALL_DEF_BOUNDS* theBounds);
127 friend class Element;
129 IMPLEMENT_STANDARD_HANDLE(VUserDrawObj, AIS_InteractiveObject)
130 IMPLEMENT_STANDARD_RTTIEXT(VUserDrawObj, AIS_InteractiveObject)
132 void VUserDrawObj::Compute(const Handle(PrsMgr_PresentationManager3d)& thePresentationManager,
133 const Handle(Prs3d_Presentation)& thePresentation,
134 const Standard_Integer theMode)
136 thePresentation->Clear();
138 Handle(Graphic3d_Group) aGrp = Prs3d_Root::CurrentGroup(thePresentation);
139 aGrp->UserDraw(this, Standard_True, Standard_True);
142 void VUserDrawObj::ComputeSelection (const Handle(SelectMgr_Selection)& theSelection,
143 const Standard_Integer theMode)
145 Handle(SelectMgr_EntityOwner) anEntityOwner = new SelectMgr_EntityOwner(this);
146 Handle(TColgp_HArray1OfPnt) aPnts = new TColgp_HArray1OfPnt(1, 5);
147 aPnts->SetValue(1, gp_Pnt(myCoords[0], myCoords[1], myCoords[2]));
148 aPnts->SetValue(2, gp_Pnt(myCoords[3], myCoords[4], myCoords[2]));
149 aPnts->SetValue(3, gp_Pnt(myCoords[3], myCoords[4], myCoords[5]));
150 aPnts->SetValue(4, gp_Pnt(myCoords[0], myCoords[1], myCoords[5]));
151 aPnts->SetValue(5, gp_Pnt(myCoords[0], myCoords[1], myCoords[2]));
152 Handle(Select3D_SensitiveCurve) aSensitive = new Select3D_SensitiveCurve(anEntityOwner, aPnts);
153 theSelection->Add(aSensitive);
156 void VUserDrawObj::GetBounds(CALL_DEF_BOUNDS* theBounds)
160 theBounds->XMin = myCoords[0];
161 theBounds->YMin = myCoords[1];
162 theBounds->ZMin = myCoords[2];
163 theBounds->XMax = myCoords[3];
164 theBounds->YMax = myCoords[4];
165 theBounds->ZMax = myCoords[5];
169 void VUserDrawObj::Render(const Handle(OpenGl_Workspace)& theWorkspace) const
171 // To test linking against OpenGl_Workspace and all aspect classes
172 const OpenGl_AspectLine* aLA = theWorkspace->AspectLine(0);
173 const OpenGl_AspectFace* aFA = theWorkspace->AspectFace(0);
175 const OpenGl_AspectMarker* aMA = theWorkspace->AspectMarker(0);
177 const OpenGl_AspectText* aTA = theWorkspace->AspectText(0);
179 TEL_COLOUR aColor = theWorkspace->NamedStatus & OPENGL_NS_HIGHLIGHT ?
180 *(theWorkspace->HighlightColor) : aLA->Color();
182 // To test OpenGl_Window
183 //Handle(OpenGl_Context) aCtx = theWorkspace->GetGlContext();
185 // Finally draw something to make sure UserDraw really works
186 glPushAttrib(GL_ENABLE_BIT);
187 glDisable(GL_LIGHTING);
188 glColor4fv(aColor.rgb);
189 glBegin(GL_LINE_LOOP);
190 glVertex3f(myCoords[0], myCoords[1], myCoords[2]);
191 glVertex3f(myCoords[3], myCoords[4], myCoords[2]);
192 glVertex3f(myCoords[3], myCoords[4], myCoords[5]);
193 glVertex3f(myCoords[0], myCoords[1], myCoords[5]);
200 OpenGl_Element* VUserDrawCallback(const CALL_DEF_USERDRAW * theUserDraw)
202 Handle(VUserDrawObj) anIObj = (VUserDrawObj*)theUserDraw->Data;
205 std::cout << "VUserDrawCallback error: null object passed, the custom scene element will not be rendered" << std::endl;
208 return new VUserDrawObj::Element(anIObj, theUserDraw->Bounds);
211 static Standard_Integer VUserDraw (Draw_Interpretor& di,
212 Standard_Integer argc,
215 Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
216 if (aContext.IsNull())
218 di << argv[0] << "Call 'vinit' before!\n";
222 Handle(OpenGl_GraphicDriver) aDriver = Handle(OpenGl_GraphicDriver)::DownCast (aContext->CurrentViewer()->Device()->GraphicDriver());
223 if (aDriver.IsNull())
225 std::cerr << "Graphic driver not available.\n";
231 di << argv[0] << "Wrong number of arguments, only the object name expected\n";
235 TCollection_AsciiString aName (argv[1]);
236 VDisplayAISObject(aName, Handle(AIS_InteractiveObject)());
238 // register the custom element factory function
239 aDriver->UserDrawCallback() = VUserDrawCallback;
241 Handle(VUserDrawObj) anIObj = new VUserDrawObj();
242 VDisplayAISObject(aName, anIObj);
247 //==============================================================================
248 //function : VFeedback
250 //==============================================================================
252 static int VFeedback (Draw_Interpretor& theDI,
253 Standard_Integer theArgNb,
254 const char** theArgVec)
256 // get the active view
257 Handle(V3d_View) aView = ViewerTest::CurrentView();
260 std::cerr << "No active view. Please call vinit.\n";
264 unsigned int aBufferSize = 1024 * 1024;
267 size_t aBytes = (size_t )aBufferSize * sizeof(GLfloat);
268 if (aBytes / sizeof(GLfloat) != (size_t )aBufferSize)
270 // finito la commedia
271 std::cerr << "Can not allocate buffer - requested size ("
272 << (double(aBufferSize / (1024 * 1024)) * double(sizeof(GLfloat)))
273 << " MiB) is out of address space\n";
277 GLfloat* aBuffer = (GLfloat* )Standard::Allocate (aBytes);
280 // finito la commedia
281 std::cerr << "Can not allocate buffer with size ("
282 << (double(aBufferSize / (1024 * 1024)) * double(sizeof(GLfloat)))
287 glFeedbackBuffer ((GLsizei )aBufferSize, GL_2D, aBuffer);
288 glRenderMode (GL_FEEDBACK);
292 GLint aResult = glRenderMode (GL_RENDER);
297 void* aPtr = aBuffer;
298 Standard::Free (aPtr);
303 std::cout << "FeedBack result= " << aResult << "\n";
310 GLint aBitmapsNb = 0;
311 GLint aPassThrNb = 0;
312 GLint aUnknownNb = 0;
313 const GLint NODE_VALUES = 2; // GL_2D
314 for (GLint anIter = 0; anIter < aResult;)
316 const GLfloat aPos = aBuffer[anIter];
317 switch ((GLint )aPos)
323 anIter += 1 + NODE_VALUES;
326 case GL_LINE_RESET_TOKEN:
331 anIter += 1 + 2 * NODE_VALUES;
334 case GL_POLYGON_TOKEN:
336 const GLint aCount = (GLint )aBuffer[++anIter];
338 anIter += aCount * NODE_VALUES + 1;
343 else if (aCount == 4)
353 case GL_BITMAP_TOKEN:
354 case GL_DRAW_PIXEL_TOKEN:
355 case GL_COPY_PIXEL_TOKEN:
358 anIter += 1 + NODE_VALUES;
361 case GL_PASS_THROUGH_TOKEN:
364 anIter += 2; // header + value
375 void* aPtr = aBuffer;
376 Standard::Free (aPtr);
379 theDI << "Total nodes: " << aNodesNb << "\n"
380 << "Points: " << aPntNb << "\n"
381 << "Line segments: " << aLinesNb << "\n"
382 << "Triangles: " << aTriNb << "\n"
383 << "Quads: " << aQuadsNb << "\n"
384 << "Polygons: " << aPolyNb << "\n"
385 << "Bitmap tokens: " << aBitmapsNb << "\n"
386 << "Pass through: " << aPassThrNb << "\n"
387 << "UNKNOWN: " << aUnknownNb << "\n";
389 double aLen2D = double(aNodesNb * 2 + aPntNb + aLinesNb * 2 + (aTriNb + aQuadsNb + aPolyNb) * 2 + aBitmapsNb + aPassThrNb);
390 double aLen3D = double(aNodesNb * 3 + aPntNb + aLinesNb * 2 + (aTriNb + aQuadsNb + aPolyNb) * 2 + aBitmapsNb + aPassThrNb);
391 double aLen3D_rgba = double(aNodesNb * 7 + aPntNb + aLinesNb * 2 + (aTriNb + aQuadsNb + aPolyNb) * 2 + aBitmapsNb + aPassThrNb);
392 theDI << "Buffer size GL_2D: " << aLen2D * double(sizeof(GLfloat)) / double(1024 * 1024) << " MiB\n"
393 << "Buffer size GL_3D: " << aLen3D * double(sizeof(GLfloat)) / double(1024 * 1024) << " MiB\n"
394 << "Buffer size GL_3D_COLOR: " << aLen3D_rgba * double(sizeof(GLfloat)) / double(1024 * 1024) << " MiB\n";
399 //=======================================================================
400 //function : OpenGlCommands
402 //=======================================================================
404 void ViewerTest::OpenGlCommands(Draw_Interpretor& theCommands)
406 const char* aGroup ="Commands for low-level TKOpenGl features";
408 theCommands.Add("vuserdraw",
409 "vuserdraw : name - simulates drawing with help of UserDraw",
410 __FILE__, VUserDraw, aGroup);
411 theCommands.Add("vfeedback",
412 "vfeedback : perform test GL feedback rendering",
413 __FILE__, VFeedback, aGroup);