0029084: Visualization, AIS_Manipulator - broken transformation is applied at Rotatio...
[occt.git] / src / ViewerTest / ViewerTest_OpenGlCommands.cxx
CommitLineData
6aca4d39 1// Created on: 2012-04-09
3946774d 2// Created by: Sergey ANIKIN
6aca4d39 3// Copyright (c) 2012-2014 OPEN CASCADE SAS
3946774d 4//
973c2be1 5// This file is part of Open CASCADE Technology software library.
3946774d 6//
d5f74e42 7// This library is free software; you can redistribute it and/or modify it under
8// the terms of the GNU Lesser General Public License version 2.1 as published
973c2be1 9// by the Free Software Foundation, with special exception defined in the file
10// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11// distribution for complete text of the license and disclaimer of any warranty.
3946774d 12//
973c2be1 13// Alternatively, this file may be used under the terms of Open CASCADE
14// commercial license or contractual agreement.
3946774d 15
3946774d 16#include <ViewerTest.hxx>
17
5e27df78 18#include <AIS_InteractiveContext.hxx>
3946774d 19#include <AIS_InteractiveObject.hxx>
20#include <Draw.hxx>
21#include <Draw_Interpretor.hxx>
22#include <Graphic3d_Group.hxx>
392ac980 23#include <Graphic3d_ShaderObject.hxx>
24#include <Graphic3d_ShaderProgram.hxx>
3946774d 25#include <OpenGl_AspectFace.hxx>
26#include <OpenGl_AspectLine.hxx>
27#include <OpenGl_AspectMarker.hxx>
28#include <OpenGl_AspectText.hxx>
3946774d 29#include <OpenGl_Context.hxx>
30#include <OpenGl_Element.hxx>
3946774d 31#include <OpenGl_GlCore20.hxx>
5e27df78 32#include <OpenGl_GraphicDriver.hxx>
8613985b 33#include <OpenGl_ShaderManager.hxx>
3946774d 34#include <OpenGl_Workspace.hxx>
392ac980 35#include <OSD_Environment.hxx>
36#include <OSD_File.hxx>
6262338c 37#include <Prs3d_Drawer.hxx>
3946774d 38#include <Prs3d_Presentation.hxx>
39#include <Prs3d_Root.hxx>
2831708b 40#include <Prs3d_LineAspect.hxx>
392ac980 41#include <Prs3d_ShadingAspect.hxx>
3946774d 42#include <Select3D_SensitiveCurve.hxx>
43#include <SelectMgr_EntityOwner.hxx>
44#include <SelectMgr_Selection.hxx>
45#include <TCollection_AsciiString.hxx>
3c4153af 46#include <V3d_View.hxx>
392ac980 47#include <V3d_Viewer.hxx>
392ac980 48#include <ViewerTest_DoubleMapOfInteractiveAndName.hxx>
49#include <ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName.hxx>
92efcf78 50#include <OpenGl_Group.hxx>
3946774d 51
52extern Standard_Boolean VDisplayAISObject (const TCollection_AsciiString& theName,
53 const Handle(AIS_InteractiveObject)& theAISObj,
54 Standard_Boolean theReplaceIfExists = Standard_True);
392ac980 55extern ViewerTest_DoubleMapOfInteractiveAndName& GetMapOfAIS();
3946774d 56
c04c30b3 57namespace {
58
3946774d 59//=======================================================================
60//function : VUserDraw
61//purpose : Checks availability and operation of UserDraw feature
62//=======================================================================
3946774d 63
64class VUserDrawObj : public AIS_InteractiveObject
65{
66public:
67 // CASCADE RTTI
92efcf78 68 DEFINE_STANDARD_RTTI_INLINE(VUserDrawObj,AIS_InteractiveObject);
3946774d 69
70 VUserDrawObj()
71 {
72 myCoords[0] = -10.;
73 myCoords[1] = -20.;
74 myCoords[2] = -30.;
75 myCoords[3] = 10.;
76 myCoords[4] = 20.;
77 myCoords[5] = 30.;
78 }
79
80public:
81 class Element : public OpenGl_Element
82 {
83 private:
84 Handle(VUserDrawObj) myIObj;
85
86 public:
a521d90d 87 Element (const Handle(VUserDrawObj)& theIObj) : myIObj (theIObj) {}
3946774d 88
a521d90d 89 virtual ~Element() {}
3946774d 90
91 virtual void Render (const Handle(OpenGl_Workspace)& theWorkspace) const
92 {
93 if (!myIObj.IsNull())
94 myIObj->Render(theWorkspace);
95 }
96
10b9c7df 97 virtual void Release (OpenGl_Context*)
5e27df78 98 {
99 //
100 }
101
3946774d 102 public:
103 DEFINE_STANDARD_ALLOC
104 };
105
106private:
107 // Virtual methods implementation
108 void Compute (const Handle(PrsMgr_PresentationManager3d)& thePresentationManager,
109 const Handle(Prs3d_Presentation)& thePresentation,
79104795 110 const Standard_Integer theMode) Standard_OVERRIDE;
3946774d 111
112 void ComputeSelection (const Handle(SelectMgr_Selection)& theSelection,
79104795 113 const Standard_Integer theMode) Standard_OVERRIDE;
3946774d 114
115 // Called by VUserDrawElement
116 void Render(const Handle(OpenGl_Workspace)& theWorkspace) const;
3946774d 117
a521d90d 118private:
3946774d 119 GLfloat myCoords[6];
3946774d 120 friend class Element;
121};
ec357c5c 122
a521d90d 123void VUserDrawObj::Compute(const Handle(PrsMgr_PresentationManager3d)& thePrsMgr,
124 const Handle(Prs3d_Presentation)& thePrs,
35e08fe8 125 const Standard_Integer /*theMode*/)
3946774d 126{
a521d90d 127 thePrs->Clear();
128
129 Graphic3d_Vec4 aBndMin (myCoords[0], myCoords[1], myCoords[2], 1.0f);
130 Graphic3d_Vec4 aBndMax (myCoords[3], myCoords[4], myCoords[5], 1.0f);
131 Handle(OpenGl_Group) aGroup = Handle(OpenGl_Group)::DownCast (thePrs->NewGroup());
132 aGroup->SetMinMaxValues (aBndMin.x(), aBndMin.y(), aBndMin.z(),
133 aBndMax.x(), aBndMax.y(), aBndMax.z());
2831708b 134 aGroup->SetGroupPrimitivesAspect (myDrawer->LineAspect()->Aspect());
a521d90d 135 VUserDrawObj::Element* anElem = new VUserDrawObj::Element (this);
136 aGroup->AddElement(anElem);
137
138 // invalidate bounding box of the scene
cfece3ef 139 thePrsMgr->StructureManager()->Update();
3946774d 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
3946774d 156void VUserDrawObj::Render(const Handle(OpenGl_Workspace)& theWorkspace) const
157{
a521d90d 158 // this sample does not use GLSL programs - make sure it is disabled
159 Handle(OpenGl_Context) aCtx = theWorkspace->GetGlContext();
8613985b 160 aCtx->BindProgram (Handle(OpenGl_ShaderProgram)());
161 aCtx->ShaderManager()->PushState (Handle(OpenGl_ShaderProgram)());
a521d90d 162
3946774d 163 // To test linking against OpenGl_Workspace and all aspect classes
f9ba5c4d 164 const OpenGl_AspectMarker* aMA = theWorkspace->AspectMarker();
b6472664 165 aMA->Aspect()->Type();
f9ba5c4d 166 const OpenGl_AspectText* aTA = theWorkspace->AspectText();
b6472664 167 aTA->Aspect()->Font();
168 OpenGl_Vec4 aColor = theWorkspace->LineColor();
3946774d 169
1ce0716b 170#if !defined(GL_ES_VERSION_2_0)
3946774d 171 // Finally draw something to make sure UserDraw really works
172 glPushAttrib(GL_ENABLE_BIT);
173 glDisable(GL_LIGHTING);
b6472664 174 glColor4fv(aColor.GetData());
3946774d 175 glBegin(GL_LINE_LOOP);
176 glVertex3f(myCoords[0], myCoords[1], myCoords[2]);
177 glVertex3f(myCoords[3], myCoords[4], myCoords[2]);
178 glVertex3f(myCoords[3], myCoords[4], myCoords[5]);
179 glVertex3f(myCoords[0], myCoords[1], myCoords[5]);
180 glEnd();
181 glPopAttrib();
1ce0716b 182#endif
3946774d 183}
184
c04c30b3 185} // end of anonymous namespace
186
3946774d 187static Standard_Integer VUserDraw (Draw_Interpretor& di,
188 Standard_Integer argc,
189 const char ** argv)
190{
191 Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
192 if (aContext.IsNull())
193 {
194 di << argv[0] << "Call 'vinit' before!\n";
195 return 1;
196 }
197
dc3fe572 198 Handle(OpenGl_GraphicDriver) aDriver = Handle(OpenGl_GraphicDriver)::DownCast (aContext->CurrentViewer()->Driver());
5e27df78 199 if (aDriver.IsNull())
200 {
201 std::cerr << "Graphic driver not available.\n";
202 return 1;
203 }
204
3946774d 205 if (argc > 2)
206 {
207 di << argv[0] << "Wrong number of arguments, only the object name expected\n";
208 return 1;
209 }
210
211 TCollection_AsciiString aName (argv[1]);
212 VDisplayAISObject(aName, Handle(AIS_InteractiveObject)());
213
3946774d 214 Handle(VUserDrawObj) anIObj = new VUserDrawObj();
215 VDisplayAISObject(aName, anIObj);
216
217 return 0;
218}
219
3c4153af 220//==============================================================================
221//function : VFeedback
222//purpose :
223//==============================================================================
224
225static int VFeedback (Draw_Interpretor& theDI,
35e08fe8 226 Standard_Integer /*theArgNb*/,
227 const char** /*theArgVec*/)
3c4153af 228{
1ce0716b 229#if !defined(GL_ES_VERSION_2_0)
3c4153af 230 // get the active view
231 Handle(V3d_View) aView = ViewerTest::CurrentView();
232 if (aView.IsNull())
233 {
234 std::cerr << "No active view. Please call vinit.\n";
235 return 1;
236 }
237
238 unsigned int aBufferSize = 1024 * 1024;
239 for (;;)
240 {
241 size_t aBytes = (size_t )aBufferSize * sizeof(GLfloat);
242 if (aBytes / sizeof(GLfloat) != (size_t )aBufferSize)
243 {
244 // finito la commedia
245 std::cerr << "Can not allocate buffer - requested size ("
246 << (double(aBufferSize / (1024 * 1024)) * double(sizeof(GLfloat)))
247 << " MiB) is out of address space\n";
248 return 1;
249 }
250
251 GLfloat* aBuffer = (GLfloat* )Standard::Allocate (aBytes);
252 if (aBuffer == NULL)
253 {
254 // finito la commedia
255 std::cerr << "Can not allocate buffer with size ("
256 << (double(aBufferSize / (1024 * 1024)) * double(sizeof(GLfloat)))
257 << " MiB)\n";
258 return 1;
259 }
260
261 glFeedbackBuffer ((GLsizei )aBufferSize, GL_2D, aBuffer);
262 glRenderMode (GL_FEEDBACK);
263
264 aView->Redraw();
265
266 GLint aResult = glRenderMode (GL_RENDER);
267 if (aResult < 0)
268 {
269 aBufferSize *= 2;
270
271 void* aPtr = aBuffer;
272 Standard::Free (aPtr);
273 aBuffer = NULL;
274 continue;
275 }
276
277 std::cout << "FeedBack result= " << aResult << "\n";
278 GLint aPntNb = 0;
279 GLint aTriNb = 0;
280 GLint aQuadsNb = 0;
281 GLint aPolyNb = 0;
282 GLint aNodesNb = 0;
283 GLint aLinesNb = 0;
284 GLint aBitmapsNb = 0;
285 GLint aPassThrNb = 0;
286 GLint aUnknownNb = 0;
287 const GLint NODE_VALUES = 2; // GL_2D
288 for (GLint anIter = 0; anIter < aResult;)
289 {
290 const GLfloat aPos = aBuffer[anIter];
291 switch ((GLint )aPos)
292 {
293 case GL_POINT_TOKEN:
294 {
295 ++aPntNb;
296 ++aNodesNb;
297 anIter += 1 + NODE_VALUES;
298 break;
299 }
300 case GL_LINE_RESET_TOKEN:
301 case GL_LINE_TOKEN:
302 {
303 ++aLinesNb;
304 aNodesNb += 2;
305 anIter += 1 + 2 * NODE_VALUES;
306 break;
307 }
308 case GL_POLYGON_TOKEN:
309 {
310 const GLint aCount = (GLint )aBuffer[++anIter];
311 aNodesNb += aCount;
312 anIter += aCount * NODE_VALUES + 1;
313 if (aCount == 3)
314 {
315 ++aTriNb;
316 }
317 else if (aCount == 4)
318 {
319 ++aQuadsNb;
320 }
321 else
322 {
323 ++aPolyNb;
324 }
325 break;
326 }
327 case GL_BITMAP_TOKEN:
328 case GL_DRAW_PIXEL_TOKEN:
329 case GL_COPY_PIXEL_TOKEN:
330 {
331 ++aBitmapsNb;
332 anIter += 1 + NODE_VALUES;
333 break;
334 }
335 case GL_PASS_THROUGH_TOKEN:
336 {
337 ++aPassThrNb;
338 anIter += 2; // header + value
339 break;
340 }
341 default:
342 {
343 ++anIter;
344 ++aUnknownNb;
345 break;
346 }
347 }
348 }
349 void* aPtr = aBuffer;
350 Standard::Free (aPtr);
351
352 // return statistics
353 theDI << "Total nodes: " << aNodesNb << "\n"
354 << "Points: " << aPntNb << "\n"
355 << "Line segments: " << aLinesNb << "\n"
356 << "Triangles: " << aTriNb << "\n"
357 << "Quads: " << aQuadsNb << "\n"
358 << "Polygons: " << aPolyNb << "\n"
359 << "Bitmap tokens: " << aBitmapsNb << "\n"
360 << "Pass through: " << aPassThrNb << "\n"
361 << "UNKNOWN: " << aUnknownNb << "\n";
362
363 double aLen2D = double(aNodesNb * 2 + aPntNb + aLinesNb * 2 + (aTriNb + aQuadsNb + aPolyNb) * 2 + aBitmapsNb + aPassThrNb);
364 double aLen3D = double(aNodesNb * 3 + aPntNb + aLinesNb * 2 + (aTriNb + aQuadsNb + aPolyNb) * 2 + aBitmapsNb + aPassThrNb);
365 double aLen3D_rgba = double(aNodesNb * 7 + aPntNb + aLinesNb * 2 + (aTriNb + aQuadsNb + aPolyNb) * 2 + aBitmapsNb + aPassThrNb);
366 theDI << "Buffer size GL_2D: " << aLen2D * double(sizeof(GLfloat)) / double(1024 * 1024) << " MiB\n"
367 << "Buffer size GL_3D: " << aLen3D * double(sizeof(GLfloat)) / double(1024 * 1024) << " MiB\n"
368 << "Buffer size GL_3D_COLOR: " << aLen3D_rgba * double(sizeof(GLfloat)) / double(1024 * 1024) << " MiB\n";
369 return 0;
370 }
1ce0716b 371#else
372 (void )theDI;
373 std::cout << "Command is unsupported on current platform.\n";
374 return 1;
375#endif
3c4153af 376}
377
1981cb22 378//==============================================================================
379//function : VImmediateFront
380//purpose :
381//==============================================================================
382
35e08fe8 383static int VImmediateFront (Draw_Interpretor& /*theDI*/,
1981cb22 384 Standard_Integer theArgNb,
385 const char** theArgVec)
386{
387 // get the context
388 Handle(AIS_InteractiveContext) aContextAIS = ViewerTest::GetAISContext();
389 if (aContextAIS.IsNull())
390 {
391 std::cerr << "No active view. Please call vinit.\n";
392 return 1;
393 }
394
dc3fe572 395 Handle(Graphic3d_GraphicDriver) aDriver = aContextAIS->CurrentViewer()->Driver();
396
1981cb22 397 if (aDriver.IsNull())
398 {
399 std::cerr << "Graphic driver not available.\n";
400 return 1;
401 }
402
403 if (theArgNb < 2)
404 {
1981cb22 405 std::cerr << "Wrong number of arguments.\n";
406 return 1;
407 }
408
c357e426 409 ViewerTest::CurrentView()->View()->SetImmediateModeDrawToFront (atoi(theArgVec[1]) != 0);
410
1981cb22 411 return 0;
412}
413
26d9c835 414//! Search the info from the key.
415inline TCollection_AsciiString searchInfo (const TColStd_IndexedDataMapOfStringString& theDict,
416 const TCollection_AsciiString& theKey)
417{
418 for (TColStd_IndexedDataMapOfStringString::Iterator anIter (theDict); anIter.More(); anIter.Next())
419 {
420 if (TCollection_AsciiString::IsSameString (anIter.Key(), theKey, Standard_False))
421 {
422 return anIter.Value();
423 }
424 }
425 return TCollection_AsciiString();
426}
427
dac04bfa 428//==============================================================================
429//function : VGlInfo
430//purpose :
431//==============================================================================
432
433static int VGlInfo (Draw_Interpretor& theDI,
434 Standard_Integer theArgNb,
435 const char** theArgVec)
436{
437 // get the active view
438 Handle(V3d_View) aView = ViewerTest::CurrentView();
439 if (aView.IsNull())
440 {
441 std::cerr << "No active view. Please call vinit.\n";
442 return 1;
443 }
444
26d9c835 445 Standard_Integer anArgIter = 1;
446 Graphic3d_DiagnosticInfo anInfoLevel = Graphic3d_DiagnosticInfo_Basic;
447 if (theArgNb == 2)
dac04bfa 448 {
26d9c835 449 TCollection_AsciiString aName (theArgVec[1]);
450 aName.LowerCase();
451 if (aName == "-short")
4e1523ef 452 {
26d9c835 453 ++anArgIter;
454 anInfoLevel = Graphic3d_DiagnosticInfo_Short;
455 }
456 else if (aName == "-basic")
457 {
458 ++anArgIter;
459 anInfoLevel = Graphic3d_DiagnosticInfo_Basic;
4e1523ef 460 }
26d9c835 461 else if (aName == "-complete"
462 || aName == "-full")
463 {
464 ++anArgIter;
465 anInfoLevel = Graphic3d_DiagnosticInfo_Complete;
466 }
467 }
468
469 TColStd_IndexedDataMapOfStringString aDict;
470 if (anArgIter >= theArgNb)
471 {
472 aView->DiagnosticInformation (aDict, anInfoLevel);
473 TCollection_AsciiString aText;
474 for (TColStd_IndexedDataMapOfStringString::Iterator aValueIter (aDict); aValueIter.More(); aValueIter.Next())
475 {
476 if (!aText.IsEmpty())
477 {
478 aText += "\n";
479 }
480 aText += TCollection_AsciiString(" ") + aValueIter.Key() + ": " + aValueIter.Value();
481 }
482
dac04bfa 483 theDI << "OpenGL info:\n"
26d9c835 484 << aText;
dac04bfa 485 return 0;
486 }
487
488 const Standard_Boolean isList = theArgNb >= 3;
26d9c835 489 aView->DiagnosticInformation (aDict, Graphic3d_DiagnosticInfo_Complete);
490 for (; anArgIter < theArgNb; ++anArgIter)
dac04bfa 491 {
26d9c835 492 TCollection_AsciiString aName (theArgVec[anArgIter]);
dac04bfa 493 aName.UpperCase();
26d9c835 494 TCollection_AsciiString aValue;
dac04bfa 495 if (aName.Search ("VENDOR") != -1)
496 {
26d9c835 497 aValue = searchInfo (aDict, "GLvendor");
dac04bfa 498 }
499 else if (aName.Search ("RENDERER") != -1)
500 {
26d9c835 501 aValue = searchInfo (aDict, "GLdevice");
dac04bfa 502 }
503 else if (aName.Search ("SHADING_LANGUAGE_VERSION") != -1
504 || aName.Search ("GLSL") != -1)
505 {
26d9c835 506 aValue = searchInfo (aDict, "GLSLversion");
dac04bfa 507 }
508 else if (aName.Search ("VERSION") != -1)
509 {
26d9c835 510 aValue = searchInfo (aDict, "GLversion");
dac04bfa 511 }
512 else if (aName.Search ("EXTENSIONS") != -1)
513 {
26d9c835 514 aValue = searchInfo (aDict, "GLextensions");
dac04bfa 515 }
516 else
517 {
518 std::cerr << "Unknown key '" << aName.ToCString() << "'\n";
519 return 1;
520 }
521
522 if (isList)
523 {
524 theDI << "{" << aValue << "} ";
525 }
526 else
527 {
528 theDI << aValue;
529 }
530 }
531
532 return 0;
533}
534
392ac980 535
536//==============================================================================
537//function : VShaderProg
538//purpose : Sets the pair of vertex and fragment shaders for the object
539//==============================================================================
540static Standard_Integer VShaderProg (Draw_Interpretor& /*theDI*/,
541 Standard_Integer theArgNb,
542 const char** theArgVec)
543{
544 Handle(AIS_InteractiveContext) aCtx = ViewerTest::GetAISContext();
545 if (aCtx.IsNull())
546 {
547 std::cerr << "Use 'vinit' command before " << theArgVec[0] << "\n";
548 return 1;
549 }
550 else if (theArgNb < 2)
551 {
552 std::cerr << theArgVec[0] << " syntax error: lack of arguments\n";
553 return 1;
554 }
555
556 TCollection_AsciiString aLastArg (theArgVec[theArgNb - 1]);
ee5befae 557 aLastArg.LowerCase();
558 const Standard_Boolean toTurnOff = aLastArg == "off";
392ac980 559 Standard_Integer anArgsNb = theArgNb - 1;
560 Handle(Graphic3d_ShaderProgram) aProgram;
561 if (!toTurnOff
ee5befae 562 && aLastArg == "phong")
392ac980 563 {
ee5befae 564 const TCollection_AsciiString& aShadersRoot = Graphic3d_ShaderProgram::ShadersFolder();
565 if (aShadersRoot.IsEmpty())
566 {
567 std::cerr << "Both environment variables CSF_ShadersDirectory and CASROOT are undefined!\n"
568 << "At least one should be defined to load Phong program.\n";
569 return 1;
570 }
571
572 const TCollection_AsciiString aSrcVert = aShadersRoot + "/PhongShading.vs";
573 const TCollection_AsciiString aSrcFrag = aShadersRoot + "/PhongShading.fs";
574
575 if (!aSrcVert.IsEmpty()
576 && !OSD_File (aSrcVert).Exists())
577 {
578 std::cerr << "Error: PhongShading.vs is not found\n";
579 return 1;
580 }
581 if (!aSrcFrag.IsEmpty()
582 && !OSD_File (aSrcFrag).Exists())
583 {
584 std::cerr << "Error: PhongShading.fs is not found\n";
585 return 1;
586 }
587
588 aProgram = new Graphic3d_ShaderProgram();
589 aProgram->AttachShader (Graphic3d_ShaderObject::CreateFromFile (Graphic3d_TOS_VERTEX, aSrcVert));
590 aProgram->AttachShader (Graphic3d_ShaderObject::CreateFromFile (Graphic3d_TOS_FRAGMENT, aSrcFrag));
392ac980 591 }
592 if (!toTurnOff
593 && aProgram.IsNull())
594 {
595 if (theArgNb < 3)
596 {
cc8cbabe 597 std::cout << "Syntax error: lack of arguments\n";
392ac980 598 return 1;
599 }
600
601 const TCollection_AsciiString aSrcVert = theArgVec[theArgNb - 2];
602 const TCollection_AsciiString aSrcFrag = theArgVec[theArgNb - 1];
cc8cbabe 603 if (aSrcVert.IsEmpty() || aSrcFrag.IsEmpty())
392ac980 604 {
cc8cbabe 605 std::cout << "Syntax error: lack of arguments\n";
392ac980 606 return 1;
607 }
cc8cbabe 608
609 const bool isVertFile = OSD_File (aSrcVert).Exists();
610 const bool isFragFile = OSD_File (aSrcFrag).Exists();
611 if (!isVertFile
612 && aSrcVert.Search ("gl_Position") == -1)
392ac980 613 {
cc8cbabe 614 std::cerr << "Error: non-existing or invalid vertex shader source\n";
615 return 1;
616 }
617 if (!isFragFile
618 && aSrcFrag.Search ("occFragColor") == -1)
619 {
620 std::cerr << "Error: non-existing or invalid fragment shader source\n";
392ac980 621 return 1;
622 }
623
624 aProgram = new Graphic3d_ShaderProgram();
cc8cbabe 625 aProgram->AttachShader (isVertFile
626 ? Graphic3d_ShaderObject::CreateFromFile (Graphic3d_TOS_VERTEX, aSrcVert)
627 : Graphic3d_ShaderObject::CreateFromSource(Graphic3d_TOS_VERTEX, aSrcVert));
628 aProgram->AttachShader (isFragFile
629 ? Graphic3d_ShaderObject::CreateFromFile (Graphic3d_TOS_FRAGMENT, aSrcFrag)
630 : Graphic3d_ShaderObject::CreateFromSource(Graphic3d_TOS_FRAGMENT, aSrcFrag));
392ac980 631 anArgsNb = theArgNb - 2;
632 }
633
634 Handle(AIS_InteractiveObject) anIO;
635 if (anArgsNb <= 1
636 || *theArgVec[1] == '*')
637 {
638 for (ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName anIter (GetMapOfAIS());
639 anIter.More(); anIter.Next())
640 {
641 anIO = Handle(AIS_InteractiveObject)::DownCast (anIter.Key1());
fb66bb28 642 if (anIO.IsNull())
392ac980 643 {
fb66bb28 644 continue;
645 }
646
647 if (!anIO->Attributes()->HasOwnShadingAspect())
648 {
649 Handle(Prs3d_ShadingAspect) aNewAspect = new Prs3d_ShadingAspect();
650 *aNewAspect->Aspect() = *anIO->Attributes()->ShadingAspect()->Aspect();
651 aNewAspect->Aspect()->SetShaderProgram (aProgram);
652 anIO->Attributes()->SetShadingAspect (aNewAspect);
392ac980 653 aCtx->Redisplay (anIO, Standard_False);
654 }
fb66bb28 655 else
656 {
657 anIO->Attributes()->SetShaderProgram (aProgram, Graphic3d_ASPECT_FILL_AREA);
658 anIO->SynchronizeAspects();
659 }
392ac980 660 }
661 aCtx->UpdateCurrentViewer();
662 return 0;
663 }
664
665 for (Standard_Integer anArgIter = 1; anArgIter < anArgsNb; ++anArgIter)
666 {
667 const TCollection_AsciiString aName (theArgVec[anArgIter]);
668 if (!GetMapOfAIS().IsBound2 (aName))
669 {
670 std::cerr << "Warning: " << aName.ToCString() << " is not displayed\n";
671 continue;
672 }
673 anIO = Handle(AIS_InteractiveObject)::DownCast (GetMapOfAIS().Find2 (aName));
674 if (anIO.IsNull())
675 {
676 std::cerr << "Warning: " << aName.ToCString() << " is not an AIS object\n";
677 continue;
678 }
fb66bb28 679
680 if (!anIO->Attributes()->HasOwnShadingAspect())
681 {
682 Handle(Prs3d_ShadingAspect) aNewAspect = new Prs3d_ShadingAspect();
683 *aNewAspect->Aspect() = *anIO->Attributes()->ShadingAspect()->Aspect();
684 aNewAspect->Aspect()->SetShaderProgram (aProgram);
685 anIO->Attributes()->SetShadingAspect (aNewAspect);
686 aCtx->Redisplay (anIO, Standard_False);
687 }
688 else
689 {
690 anIO->Attributes()->SetShaderProgram (aProgram, Graphic3d_ASPECT_FILL_AREA);
691 anIO->SynchronizeAspects();
692 }
392ac980 693 }
694
695 aCtx->UpdateCurrentViewer();
696 return 0;
697}
698
3946774d 699//=======================================================================
700//function : OpenGlCommands
701//purpose :
702//=======================================================================
703
704void ViewerTest::OpenGlCommands(Draw_Interpretor& theCommands)
705{
706 const char* aGroup ="Commands for low-level TKOpenGl features";
707
708 theCommands.Add("vuserdraw",
709 "vuserdraw : name - simulates drawing with help of UserDraw",
710 __FILE__, VUserDraw, aGroup);
3c4153af 711 theCommands.Add("vfeedback",
712 "vfeedback : perform test GL feedback rendering",
713 __FILE__, VFeedback, aGroup);
1981cb22 714 theCommands.Add("vimmediatefront",
715 "vimmediatefront : render immediate mode to front buffer or to back buffer",
716 __FILE__, VImmediateFront, aGroup);
dac04bfa 717 theCommands.Add("vglinfo",
26d9c835 718 "vglinfo [-short|-basic|-complete]"
719 "\n\t\t: [GL_VENDOR] [GL_RENDERER] [GL_VERSION]"
720 "\n\t\t: [GL_SHADING_LANGUAGE_VERSION] [GL_EXTENSIONS]"
721 "\n\t\t: print OpenGL info",
dac04bfa 722 __FILE__, VGlInfo, aGroup);
392ac980 723 theCommands.Add("vshaderprog",
724 " 'vshaderprog [name] pathToVertexShader pathToFragmentShader'"
725 "\n\t\t: or 'vshaderprog [name] off' to disable GLSL program"
726 "\n\t\t: or 'vshaderprog [name] phong' to enable per-pixel lighting calculations"
727 "\n\t\t: * might be used to specify all displayed objects",
728 __FILE__, VShaderProg, aGroup);
3946774d 729}