0024057: Eliminate compiler warning C4100 in MSVC++ with warning level 4
[occt.git] / src / ViewerTest / ViewerTest_OpenGlCommands.cxx
CommitLineData
3946774d 1// Created on: 2012-04-09
2// Created by: Sergey ANIKIN
3// Copyright (c) 2012 OPEN CASCADE SAS
4//
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.
9//
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.
12//
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.
19
20#ifdef HAVE_CONFIG_H
21# include <config.h>
22#endif
23
24#include <ViewerTest.hxx>
25
5e27df78 26#include <AIS_InteractiveContext.hxx>
3946774d 27#include <AIS_InteractiveObject.hxx>
28#include <Draw.hxx>
29#include <Draw_Interpretor.hxx>
30#include <Graphic3d_Group.hxx>
31#include <OpenGl_ArbVBO.hxx>
32#include <OpenGl_AspectFace.hxx>
33#include <OpenGl_AspectLine.hxx>
34#include <OpenGl_AspectMarker.hxx>
35#include <OpenGl_AspectText.hxx>
3946774d 36#include <OpenGl_Context.hxx>
37#include <OpenGl_Element.hxx>
38#include <OpenGl_ExtFBO.hxx>
39#include <OpenGl_GlCore20.hxx>
5e27df78 40#include <OpenGl_GraphicDriver.hxx>
3946774d 41#include <OpenGl_Workspace.hxx>
42#include <Prs3d_Presentation.hxx>
43#include <Prs3d_Root.hxx>
44#include <Select3D_SensitiveCurve.hxx>
45#include <SelectMgr_EntityOwner.hxx>
46#include <SelectMgr_Selection.hxx>
5e27df78 47#include <V3d_Viewer.hxx>
3946774d 48#include <TCollection_AsciiString.hxx>
3c4153af 49#include <V3d_View.hxx>
1981cb22 50#include <Visual3d_View.hxx>
3946774d 51
52extern Standard_Boolean VDisplayAISObject (const TCollection_AsciiString& theName,
53 const Handle(AIS_InteractiveObject)& theAISObj,
54 Standard_Boolean theReplaceIfExists = Standard_True);
55
56//=======================================================================
57//function : VUserDraw
58//purpose : Checks availability and operation of UserDraw feature
59//=======================================================================
60DEFINE_STANDARD_HANDLE(VUserDrawObj, AIS_InteractiveObject)
61
62class VUserDrawObj : public AIS_InteractiveObject
63{
64public:
65 // CASCADE RTTI
66 DEFINE_STANDARD_RTTI(VUserDrawObj);
67
68 VUserDrawObj()
69 {
70 myCoords[0] = -10.;
71 myCoords[1] = -20.;
72 myCoords[2] = -30.;
73 myCoords[3] = 10.;
74 myCoords[4] = 20.;
75 myCoords[5] = 30.;
76 }
77
78public:
79 class Element : public OpenGl_Element
80 {
81 private:
82 Handle(VUserDrawObj) myIObj;
83
84 public:
85 Element (const Handle(VUserDrawObj)& theIObj,
86 CALL_DEF_BOUNDS* theBounds)
87 : myIObj( theIObj )
88 {
89 if (!myIObj.IsNull())
90 myIObj->GetBounds(theBounds);
91 }
92
93 virtual ~Element ()
94 {
95 }
96
97 virtual void Render (const Handle(OpenGl_Workspace)& theWorkspace) const
98 {
99 if (!myIObj.IsNull())
100 myIObj->Render(theWorkspace);
101 }
102
35e08fe8 103 virtual void Release (const Handle(OpenGl_Context)&)
5e27df78 104 {
105 //
106 }
107
3946774d 108 public:
109 DEFINE_STANDARD_ALLOC
110 };
111
112private:
113 // Virtual methods implementation
114 void Compute (const Handle(PrsMgr_PresentationManager3d)& thePresentationManager,
115 const Handle(Prs3d_Presentation)& thePresentation,
116 const Standard_Integer theMode);
117
118 void ComputeSelection (const Handle(SelectMgr_Selection)& theSelection,
119 const Standard_Integer theMode);
120
121 // Called by VUserDrawElement
122 void Render(const Handle(OpenGl_Workspace)& theWorkspace) const;
123 void GetBounds(CALL_DEF_BOUNDS* theBounds);
124
125 GLfloat myCoords[6];
126
127 friend class Element;
128};
129IMPLEMENT_STANDARD_HANDLE(VUserDrawObj, AIS_InteractiveObject)
130IMPLEMENT_STANDARD_RTTIEXT(VUserDrawObj, AIS_InteractiveObject)
131
35e08fe8 132void VUserDrawObj::Compute(const Handle(PrsMgr_PresentationManager3d)& /*thePresentationManager*/,
3946774d 133 const Handle(Prs3d_Presentation)& thePresentation,
35e08fe8 134 const Standard_Integer /*theMode*/)
3946774d 135{
136 thePresentation->Clear();
137
138 Handle(Graphic3d_Group) aGrp = Prs3d_Root::CurrentGroup(thePresentation);
139 aGrp->UserDraw(this, Standard_True, Standard_True);
140}
141
142void VUserDrawObj::ComputeSelection (const Handle(SelectMgr_Selection)& theSelection,
35e08fe8 143 const Standard_Integer /*theMode*/)
3946774d 144{
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);
154}
155
156void VUserDrawObj::GetBounds(CALL_DEF_BOUNDS* theBounds)
157{
158 if (theBounds)
159 {
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];
166 }
167}
168
169void VUserDrawObj::Render(const Handle(OpenGl_Workspace)& theWorkspace) const
170{
171 // To test linking against OpenGl_Workspace and all aspect classes
172 const OpenGl_AspectLine* aLA = theWorkspace->AspectLine(0);
3946774d 173 const OpenGl_AspectMarker* aMA = theWorkspace->AspectMarker(0);
174 aMA->Type();
175 const OpenGl_AspectText* aTA = theWorkspace->AspectText(0);
a174a3c5 176 aTA->FontName();
3946774d 177 TEL_COLOUR aColor = theWorkspace->NamedStatus & OPENGL_NS_HIGHLIGHT ?
178 *(theWorkspace->HighlightColor) : aLA->Color();
179
180 // To test OpenGl_Window
5e27df78 181 //Handle(OpenGl_Context) aCtx = theWorkspace->GetGlContext();
3946774d 182
183 // Finally draw something to make sure UserDraw really works
184 glPushAttrib(GL_ENABLE_BIT);
185 glDisable(GL_LIGHTING);
186 glColor4fv(aColor.rgb);
187 glBegin(GL_LINE_LOOP);
188 glVertex3f(myCoords[0], myCoords[1], myCoords[2]);
189 glVertex3f(myCoords[3], myCoords[4], myCoords[2]);
190 glVertex3f(myCoords[3], myCoords[4], myCoords[5]);
191 glVertex3f(myCoords[0], myCoords[1], myCoords[5]);
192 glEnd();
193 glPopAttrib();
194}
195
3946774d 196OpenGl_Element* VUserDrawCallback(const CALL_DEF_USERDRAW * theUserDraw)
197{
198 Handle(VUserDrawObj) anIObj = (VUserDrawObj*)theUserDraw->Data;
199 if (anIObj.IsNull())
200 {
201 std::cout << "VUserDrawCallback error: null object passed, the custom scene element will not be rendered" << std::endl;
202 }
203
204 return new VUserDrawObj::Element(anIObj, theUserDraw->Bounds);
205}
206
207static Standard_Integer VUserDraw (Draw_Interpretor& di,
208 Standard_Integer argc,
209 const char ** argv)
210{
211 Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
212 if (aContext.IsNull())
213 {
214 di << argv[0] << "Call 'vinit' before!\n";
215 return 1;
216 }
217
dc3fe572 218 Handle(OpenGl_GraphicDriver) aDriver = Handle(OpenGl_GraphicDriver)::DownCast (aContext->CurrentViewer()->Driver());
5e27df78 219 if (aDriver.IsNull())
220 {
221 std::cerr << "Graphic driver not available.\n";
222 return 1;
223 }
224
3946774d 225 if (argc > 2)
226 {
227 di << argv[0] << "Wrong number of arguments, only the object name expected\n";
228 return 1;
229 }
230
231 TCollection_AsciiString aName (argv[1]);
232 VDisplayAISObject(aName, Handle(AIS_InteractiveObject)());
233
234 // register the custom element factory function
5e27df78 235 aDriver->UserDrawCallback() = VUserDrawCallback;
3946774d 236
237 Handle(VUserDrawObj) anIObj = new VUserDrawObj();
238 VDisplayAISObject(aName, anIObj);
239
240 return 0;
241}
242
3c4153af 243//==============================================================================
244//function : VFeedback
245//purpose :
246//==============================================================================
247
248static int VFeedback (Draw_Interpretor& theDI,
35e08fe8 249 Standard_Integer /*theArgNb*/,
250 const char** /*theArgVec*/)
3c4153af 251{
252 // get the active view
253 Handle(V3d_View) aView = ViewerTest::CurrentView();
254 if (aView.IsNull())
255 {
256 std::cerr << "No active view. Please call vinit.\n";
257 return 1;
258 }
259
260 unsigned int aBufferSize = 1024 * 1024;
261 for (;;)
262 {
263 size_t aBytes = (size_t )aBufferSize * sizeof(GLfloat);
264 if (aBytes / sizeof(GLfloat) != (size_t )aBufferSize)
265 {
266 // finito la commedia
267 std::cerr << "Can not allocate buffer - requested size ("
268 << (double(aBufferSize / (1024 * 1024)) * double(sizeof(GLfloat)))
269 << " MiB) is out of address space\n";
270 return 1;
271 }
272
273 GLfloat* aBuffer = (GLfloat* )Standard::Allocate (aBytes);
274 if (aBuffer == NULL)
275 {
276 // finito la commedia
277 std::cerr << "Can not allocate buffer with size ("
278 << (double(aBufferSize / (1024 * 1024)) * double(sizeof(GLfloat)))
279 << " MiB)\n";
280 return 1;
281 }
282
283 glFeedbackBuffer ((GLsizei )aBufferSize, GL_2D, aBuffer);
284 glRenderMode (GL_FEEDBACK);
285
286 aView->Redraw();
287
288 GLint aResult = glRenderMode (GL_RENDER);
289 if (aResult < 0)
290 {
291 aBufferSize *= 2;
292
293 void* aPtr = aBuffer;
294 Standard::Free (aPtr);
295 aBuffer = NULL;
296 continue;
297 }
298
299 std::cout << "FeedBack result= " << aResult << "\n";
300 GLint aPntNb = 0;
301 GLint aTriNb = 0;
302 GLint aQuadsNb = 0;
303 GLint aPolyNb = 0;
304 GLint aNodesNb = 0;
305 GLint aLinesNb = 0;
306 GLint aBitmapsNb = 0;
307 GLint aPassThrNb = 0;
308 GLint aUnknownNb = 0;
309 const GLint NODE_VALUES = 2; // GL_2D
310 for (GLint anIter = 0; anIter < aResult;)
311 {
312 const GLfloat aPos = aBuffer[anIter];
313 switch ((GLint )aPos)
314 {
315 case GL_POINT_TOKEN:
316 {
317 ++aPntNb;
318 ++aNodesNb;
319 anIter += 1 + NODE_VALUES;
320 break;
321 }
322 case GL_LINE_RESET_TOKEN:
323 case GL_LINE_TOKEN:
324 {
325 ++aLinesNb;
326 aNodesNb += 2;
327 anIter += 1 + 2 * NODE_VALUES;
328 break;
329 }
330 case GL_POLYGON_TOKEN:
331 {
332 const GLint aCount = (GLint )aBuffer[++anIter];
333 aNodesNb += aCount;
334 anIter += aCount * NODE_VALUES + 1;
335 if (aCount == 3)
336 {
337 ++aTriNb;
338 }
339 else if (aCount == 4)
340 {
341 ++aQuadsNb;
342 }
343 else
344 {
345 ++aPolyNb;
346 }
347 break;
348 }
349 case GL_BITMAP_TOKEN:
350 case GL_DRAW_PIXEL_TOKEN:
351 case GL_COPY_PIXEL_TOKEN:
352 {
353 ++aBitmapsNb;
354 anIter += 1 + NODE_VALUES;
355 break;
356 }
357 case GL_PASS_THROUGH_TOKEN:
358 {
359 ++aPassThrNb;
360 anIter += 2; // header + value
361 break;
362 }
363 default:
364 {
365 ++anIter;
366 ++aUnknownNb;
367 break;
368 }
369 }
370 }
371 void* aPtr = aBuffer;
372 Standard::Free (aPtr);
373
374 // return statistics
375 theDI << "Total nodes: " << aNodesNb << "\n"
376 << "Points: " << aPntNb << "\n"
377 << "Line segments: " << aLinesNb << "\n"
378 << "Triangles: " << aTriNb << "\n"
379 << "Quads: " << aQuadsNb << "\n"
380 << "Polygons: " << aPolyNb << "\n"
381 << "Bitmap tokens: " << aBitmapsNb << "\n"
382 << "Pass through: " << aPassThrNb << "\n"
383 << "UNKNOWN: " << aUnknownNb << "\n";
384
385 double aLen2D = double(aNodesNb * 2 + aPntNb + aLinesNb * 2 + (aTriNb + aQuadsNb + aPolyNb) * 2 + aBitmapsNb + aPassThrNb);
386 double aLen3D = double(aNodesNb * 3 + aPntNb + aLinesNb * 2 + (aTriNb + aQuadsNb + aPolyNb) * 2 + aBitmapsNb + aPassThrNb);
387 double aLen3D_rgba = double(aNodesNb * 7 + aPntNb + aLinesNb * 2 + (aTriNb + aQuadsNb + aPolyNb) * 2 + aBitmapsNb + aPassThrNb);
388 theDI << "Buffer size GL_2D: " << aLen2D * double(sizeof(GLfloat)) / double(1024 * 1024) << " MiB\n"
389 << "Buffer size GL_3D: " << aLen3D * double(sizeof(GLfloat)) / double(1024 * 1024) << " MiB\n"
390 << "Buffer size GL_3D_COLOR: " << aLen3D_rgba * double(sizeof(GLfloat)) / double(1024 * 1024) << " MiB\n";
391 return 0;
392 }
393}
394
1981cb22 395//==============================================================================
396//function : VImmediateFront
397//purpose :
398//==============================================================================
399
35e08fe8 400static int VImmediateFront (Draw_Interpretor& /*theDI*/,
1981cb22 401 Standard_Integer theArgNb,
402 const char** theArgVec)
403{
404 // get the context
405 Handle(AIS_InteractiveContext) aContextAIS = ViewerTest::GetAISContext();
406 if (aContextAIS.IsNull())
407 {
408 std::cerr << "No active view. Please call vinit.\n";
409 return 1;
410 }
411
dc3fe572 412 Handle(Graphic3d_GraphicDriver) aDriver = aContextAIS->CurrentViewer()->Driver();
413
1981cb22 414 if (aDriver.IsNull())
415 {
416 std::cerr << "Graphic driver not available.\n";
417 return 1;
418 }
419
420 if (theArgNb < 2)
421 {
422 //theDI << "VBO: " << aDriver->ToUseVBO() << "\n";
423 //return 0;
424 std::cerr << "Wrong number of arguments.\n";
425 return 1;
426 }
427
428 Graphic3d_CView* aCView = (Graphic3d_CView* )(ViewerTest::CurrentView()->View()->CView());
429 aDriver->SetImmediateModeDrawToFront (*aCView, atoi(theArgVec[1]) != 0);
430 return 0;
431}
432
dac04bfa 433//==============================================================================
434//function : VGlInfo
435//purpose :
436//==============================================================================
437
438static int VGlInfo (Draw_Interpretor& theDI,
439 Standard_Integer theArgNb,
440 const char** theArgVec)
441{
442 // get the active view
443 Handle(V3d_View) aView = ViewerTest::CurrentView();
444 if (aView.IsNull())
445 {
446 std::cerr << "No active view. Please call vinit.\n";
447 return 1;
448 }
449
450 if (theArgNb <= 1)
451 {
452 theDI << "OpenGL info:\n"
453 << " GLvendor = '" << (const char* )glGetString(GL_VENDOR) << "'\n"
454 << " GLdevice = '" << (const char* )glGetString(GL_RENDERER) << "'\n"
455 << " GLversion = '" << (const char* )glGetString(GL_VERSION) << "'\n"
456 << " GLSLversion = '" << (const char* )glGetString(GL_SHADING_LANGUAGE_VERSION) << "'\n";
457 return 0;
458 }
459
460 const Standard_Boolean isList = theArgNb >= 3;
461 for (Standard_Integer anIter = 1; anIter < theArgNb; ++anIter)
462 {
463 TCollection_AsciiString aName (theArgVec[anIter]);
464 aName.UpperCase();
465 const char* aValue = NULL;
466 if (aName.Search ("VENDOR") != -1)
467 {
468 aValue = (const char* )glGetString (GL_VENDOR);
469 }
470 else if (aName.Search ("RENDERER") != -1)
471 {
472 aValue = (const char* )glGetString (GL_RENDERER);
473 }
474 else if (aName.Search ("SHADING_LANGUAGE_VERSION") != -1
475 || aName.Search ("GLSL") != -1)
476 {
477 aValue = (const char* )glGetString (GL_SHADING_LANGUAGE_VERSION);
478 }
479 else if (aName.Search ("VERSION") != -1)
480 {
481 aValue = (const char* )glGetString (GL_VERSION);
482 }
483 else if (aName.Search ("EXTENSIONS") != -1)
484 {
485 aValue = (const char* )glGetString (GL_EXTENSIONS);
486 }
487 else
488 {
489 std::cerr << "Unknown key '" << aName.ToCString() << "'\n";
490 return 1;
491 }
492
493 if (isList)
494 {
495 theDI << "{" << aValue << "} ";
496 }
497 else
498 {
499 theDI << aValue;
500 }
501 }
502
503 return 0;
504}
505
3946774d 506//=======================================================================
507//function : OpenGlCommands
508//purpose :
509//=======================================================================
510
511void ViewerTest::OpenGlCommands(Draw_Interpretor& theCommands)
512{
513 const char* aGroup ="Commands for low-level TKOpenGl features";
514
515 theCommands.Add("vuserdraw",
516 "vuserdraw : name - simulates drawing with help of UserDraw",
517 __FILE__, VUserDraw, aGroup);
3c4153af 518 theCommands.Add("vfeedback",
519 "vfeedback : perform test GL feedback rendering",
520 __FILE__, VFeedback, aGroup);
1981cb22 521 theCommands.Add("vimmediatefront",
522 "vimmediatefront : render immediate mode to front buffer or to back buffer",
523 __FILE__, VImmediateFront, aGroup);
524
dac04bfa 525 theCommands.Add("vglinfo",
526 "vglinfo [GL_VENDOR] [GL_RENDERER] [GL_VERSION] [GL_SHADING_LANGUAGE_VERSION] [GL_EXTENSIONS]"
527 " : prints GL info",
528 __FILE__, VGlInfo, aGroup);
3946774d 529}