0026885: Visualization - drop redundant aspects from structure level
[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>
3946774d 33#include <OpenGl_Workspace.hxx>
392ac980 34#include <OSD_Environment.hxx>
35#include <OSD_File.hxx>
6262338c 36#include <Prs3d_Drawer.hxx>
3946774d 37#include <Prs3d_Presentation.hxx>
38#include <Prs3d_Root.hxx>
2831708b 39#include <Prs3d_LineAspect.hxx>
392ac980 40#include <Prs3d_ShadingAspect.hxx>
3946774d 41#include <Select3D_SensitiveCurve.hxx>
42#include <SelectMgr_EntityOwner.hxx>
43#include <SelectMgr_Selection.hxx>
44#include <TCollection_AsciiString.hxx>
3c4153af 45#include <V3d_View.hxx>
392ac980 46#include <V3d_Viewer.hxx>
392ac980 47#include <ViewerTest_DoubleMapOfInteractiveAndName.hxx>
48#include <ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName.hxx>
92efcf78 49#include <OpenGl_Group.hxx>
3946774d 50
51extern Standard_Boolean VDisplayAISObject (const TCollection_AsciiString& theName,
52 const Handle(AIS_InteractiveObject)& theAISObj,
53 Standard_Boolean theReplaceIfExists = Standard_True);
392ac980 54extern ViewerTest_DoubleMapOfInteractiveAndName& GetMapOfAIS();
3946774d 55
c04c30b3 56namespace {
57
3946774d 58//=======================================================================
59//function : VUserDraw
60//purpose : Checks availability and operation of UserDraw feature
61//=======================================================================
3946774d 62
63class VUserDrawObj : public AIS_InteractiveObject
64{
65public:
66 // CASCADE RTTI
92efcf78 67 DEFINE_STANDARD_RTTI_INLINE(VUserDrawObj,AIS_InteractiveObject);
3946774d 68
69 VUserDrawObj()
70 {
71 myCoords[0] = -10.;
72 myCoords[1] = -20.;
73 myCoords[2] = -30.;
74 myCoords[3] = 10.;
75 myCoords[4] = 20.;
76 myCoords[5] = 30.;
77 }
78
79public:
80 class Element : public OpenGl_Element
81 {
82 private:
83 Handle(VUserDrawObj) myIObj;
84
85 public:
a521d90d 86 Element (const Handle(VUserDrawObj)& theIObj) : myIObj (theIObj) {}
3946774d 87
a521d90d 88 virtual ~Element() {}
3946774d 89
90 virtual void Render (const Handle(OpenGl_Workspace)& theWorkspace) const
91 {
92 if (!myIObj.IsNull())
93 myIObj->Render(theWorkspace);
94 }
95
10b9c7df 96 virtual void Release (OpenGl_Context*)
5e27df78 97 {
98 //
99 }
100
3946774d 101 public:
102 DEFINE_STANDARD_ALLOC
103 };
104
105private:
106 // Virtual methods implementation
107 void Compute (const Handle(PrsMgr_PresentationManager3d)& thePresentationManager,
108 const Handle(Prs3d_Presentation)& thePresentation,
79104795 109 const Standard_Integer theMode) Standard_OVERRIDE;
3946774d 110
111 void ComputeSelection (const Handle(SelectMgr_Selection)& theSelection,
79104795 112 const Standard_Integer theMode) Standard_OVERRIDE;
3946774d 113
114 // Called by VUserDrawElement
115 void Render(const Handle(OpenGl_Workspace)& theWorkspace) const;
3946774d 116
a521d90d 117private:
3946774d 118 GLfloat myCoords[6];
3946774d 119 friend class Element;
120};
ec357c5c 121
a521d90d 122void VUserDrawObj::Compute(const Handle(PrsMgr_PresentationManager3d)& thePrsMgr,
123 const Handle(Prs3d_Presentation)& thePrs,
35e08fe8 124 const Standard_Integer /*theMode*/)
3946774d 125{
a521d90d 126 thePrs->Clear();
127
128 Graphic3d_Vec4 aBndMin (myCoords[0], myCoords[1], myCoords[2], 1.0f);
129 Graphic3d_Vec4 aBndMax (myCoords[3], myCoords[4], myCoords[5], 1.0f);
130 Handle(OpenGl_Group) aGroup = Handle(OpenGl_Group)::DownCast (thePrs->NewGroup());
131 aGroup->SetMinMaxValues (aBndMin.x(), aBndMin.y(), aBndMin.z(),
132 aBndMax.x(), aBndMax.y(), aBndMax.z());
2831708b 133 aGroup->SetGroupPrimitivesAspect (myDrawer->LineAspect()->Aspect());
a521d90d 134 VUserDrawObj::Element* anElem = new VUserDrawObj::Element (this);
135 aGroup->AddElement(anElem);
136
137 // invalidate bounding box of the scene
138 thePrsMgr->StructureManager()->Update (thePrsMgr->StructureManager()->UpdateMode());
3946774d 139}
140
141void VUserDrawObj::ComputeSelection (const Handle(SelectMgr_Selection)& theSelection,
35e08fe8 142 const Standard_Integer /*theMode*/)
3946774d 143{
144 Handle(SelectMgr_EntityOwner) anEntityOwner = new SelectMgr_EntityOwner(this);
145 Handle(TColgp_HArray1OfPnt) aPnts = new TColgp_HArray1OfPnt(1, 5);
146 aPnts->SetValue(1, gp_Pnt(myCoords[0], myCoords[1], myCoords[2]));
147 aPnts->SetValue(2, gp_Pnt(myCoords[3], myCoords[4], myCoords[2]));
148 aPnts->SetValue(3, gp_Pnt(myCoords[3], myCoords[4], myCoords[5]));
149 aPnts->SetValue(4, gp_Pnt(myCoords[0], myCoords[1], myCoords[5]));
150 aPnts->SetValue(5, gp_Pnt(myCoords[0], myCoords[1], myCoords[2]));
151 Handle(Select3D_SensitiveCurve) aSensitive = new Select3D_SensitiveCurve(anEntityOwner, aPnts);
152 theSelection->Add(aSensitive);
153}
154
3946774d 155void VUserDrawObj::Render(const Handle(OpenGl_Workspace)& theWorkspace) const
156{
a521d90d 157 // this sample does not use GLSL programs - make sure it is disabled
158 Handle(OpenGl_Context) aCtx = theWorkspace->GetGlContext();
159 aCtx->BindProgram (NULL);
160
3946774d 161 // To test linking against OpenGl_Workspace and all aspect classes
162 const OpenGl_AspectLine* aLA = theWorkspace->AspectLine(0);
3946774d 163 const OpenGl_AspectMarker* aMA = theWorkspace->AspectMarker(0);
164 aMA->Type();
165 const OpenGl_AspectText* aTA = theWorkspace->AspectText(0);
a174a3c5 166 aTA->FontName();
3946774d 167 TEL_COLOUR aColor = theWorkspace->NamedStatus & OPENGL_NS_HIGHLIGHT ?
168 *(theWorkspace->HighlightColor) : aLA->Color();
169
3946774d 170 // Finally draw something to make sure UserDraw really works
171 glPushAttrib(GL_ENABLE_BIT);
172 glDisable(GL_LIGHTING);
173 glColor4fv(aColor.rgb);
174 glBegin(GL_LINE_LOOP);
175 glVertex3f(myCoords[0], myCoords[1], myCoords[2]);
176 glVertex3f(myCoords[3], myCoords[4], myCoords[2]);
177 glVertex3f(myCoords[3], myCoords[4], myCoords[5]);
178 glVertex3f(myCoords[0], myCoords[1], myCoords[5]);
179 glEnd();
180 glPopAttrib();
181}
182
c04c30b3 183} // end of anonymous namespace
184
3946774d 185static Standard_Integer VUserDraw (Draw_Interpretor& di,
186 Standard_Integer argc,
187 const char ** argv)
188{
189 Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
190 if (aContext.IsNull())
191 {
192 di << argv[0] << "Call 'vinit' before!\n";
193 return 1;
194 }
195
dc3fe572 196 Handle(OpenGl_GraphicDriver) aDriver = Handle(OpenGl_GraphicDriver)::DownCast (aContext->CurrentViewer()->Driver());
5e27df78 197 if (aDriver.IsNull())
198 {
199 std::cerr << "Graphic driver not available.\n";
200 return 1;
201 }
202
3946774d 203 if (argc > 2)
204 {
205 di << argv[0] << "Wrong number of arguments, only the object name expected\n";
206 return 1;
207 }
208
209 TCollection_AsciiString aName (argv[1]);
210 VDisplayAISObject(aName, Handle(AIS_InteractiveObject)());
211
3946774d 212 Handle(VUserDrawObj) anIObj = new VUserDrawObj();
213 VDisplayAISObject(aName, anIObj);
214
215 return 0;
216}
217
3c4153af 218//==============================================================================
219//function : VFeedback
220//purpose :
221//==============================================================================
222
223static int VFeedback (Draw_Interpretor& theDI,
35e08fe8 224 Standard_Integer /*theArgNb*/,
225 const char** /*theArgVec*/)
3c4153af 226{
227 // get the active view
228 Handle(V3d_View) aView = ViewerTest::CurrentView();
229 if (aView.IsNull())
230 {
231 std::cerr << "No active view. Please call vinit.\n";
232 return 1;
233 }
234
235 unsigned int aBufferSize = 1024 * 1024;
236 for (;;)
237 {
238 size_t aBytes = (size_t )aBufferSize * sizeof(GLfloat);
239 if (aBytes / sizeof(GLfloat) != (size_t )aBufferSize)
240 {
241 // finito la commedia
242 std::cerr << "Can not allocate buffer - requested size ("
243 << (double(aBufferSize / (1024 * 1024)) * double(sizeof(GLfloat)))
244 << " MiB) is out of address space\n";
245 return 1;
246 }
247
248 GLfloat* aBuffer = (GLfloat* )Standard::Allocate (aBytes);
249 if (aBuffer == NULL)
250 {
251 // finito la commedia
252 std::cerr << "Can not allocate buffer with size ("
253 << (double(aBufferSize / (1024 * 1024)) * double(sizeof(GLfloat)))
254 << " MiB)\n";
255 return 1;
256 }
257
258 glFeedbackBuffer ((GLsizei )aBufferSize, GL_2D, aBuffer);
259 glRenderMode (GL_FEEDBACK);
260
261 aView->Redraw();
262
263 GLint aResult = glRenderMode (GL_RENDER);
264 if (aResult < 0)
265 {
266 aBufferSize *= 2;
267
268 void* aPtr = aBuffer;
269 Standard::Free (aPtr);
270 aBuffer = NULL;
271 continue;
272 }
273
274 std::cout << "FeedBack result= " << aResult << "\n";
275 GLint aPntNb = 0;
276 GLint aTriNb = 0;
277 GLint aQuadsNb = 0;
278 GLint aPolyNb = 0;
279 GLint aNodesNb = 0;
280 GLint aLinesNb = 0;
281 GLint aBitmapsNb = 0;
282 GLint aPassThrNb = 0;
283 GLint aUnknownNb = 0;
284 const GLint NODE_VALUES = 2; // GL_2D
285 for (GLint anIter = 0; anIter < aResult;)
286 {
287 const GLfloat aPos = aBuffer[anIter];
288 switch ((GLint )aPos)
289 {
290 case GL_POINT_TOKEN:
291 {
292 ++aPntNb;
293 ++aNodesNb;
294 anIter += 1 + NODE_VALUES;
295 break;
296 }
297 case GL_LINE_RESET_TOKEN:
298 case GL_LINE_TOKEN:
299 {
300 ++aLinesNb;
301 aNodesNb += 2;
302 anIter += 1 + 2 * NODE_VALUES;
303 break;
304 }
305 case GL_POLYGON_TOKEN:
306 {
307 const GLint aCount = (GLint )aBuffer[++anIter];
308 aNodesNb += aCount;
309 anIter += aCount * NODE_VALUES + 1;
310 if (aCount == 3)
311 {
312 ++aTriNb;
313 }
314 else if (aCount == 4)
315 {
316 ++aQuadsNb;
317 }
318 else
319 {
320 ++aPolyNb;
321 }
322 break;
323 }
324 case GL_BITMAP_TOKEN:
325 case GL_DRAW_PIXEL_TOKEN:
326 case GL_COPY_PIXEL_TOKEN:
327 {
328 ++aBitmapsNb;
329 anIter += 1 + NODE_VALUES;
330 break;
331 }
332 case GL_PASS_THROUGH_TOKEN:
333 {
334 ++aPassThrNb;
335 anIter += 2; // header + value
336 break;
337 }
338 default:
339 {
340 ++anIter;
341 ++aUnknownNb;
342 break;
343 }
344 }
345 }
346 void* aPtr = aBuffer;
347 Standard::Free (aPtr);
348
349 // return statistics
350 theDI << "Total nodes: " << aNodesNb << "\n"
351 << "Points: " << aPntNb << "\n"
352 << "Line segments: " << aLinesNb << "\n"
353 << "Triangles: " << aTriNb << "\n"
354 << "Quads: " << aQuadsNb << "\n"
355 << "Polygons: " << aPolyNb << "\n"
356 << "Bitmap tokens: " << aBitmapsNb << "\n"
357 << "Pass through: " << aPassThrNb << "\n"
358 << "UNKNOWN: " << aUnknownNb << "\n";
359
360 double aLen2D = double(aNodesNb * 2 + aPntNb + aLinesNb * 2 + (aTriNb + aQuadsNb + aPolyNb) * 2 + aBitmapsNb + aPassThrNb);
361 double aLen3D = double(aNodesNb * 3 + aPntNb + aLinesNb * 2 + (aTriNb + aQuadsNb + aPolyNb) * 2 + aBitmapsNb + aPassThrNb);
362 double aLen3D_rgba = double(aNodesNb * 7 + aPntNb + aLinesNb * 2 + (aTriNb + aQuadsNb + aPolyNb) * 2 + aBitmapsNb + aPassThrNb);
363 theDI << "Buffer size GL_2D: " << aLen2D * double(sizeof(GLfloat)) / double(1024 * 1024) << " MiB\n"
364 << "Buffer size GL_3D: " << aLen3D * double(sizeof(GLfloat)) / double(1024 * 1024) << " MiB\n"
365 << "Buffer size GL_3D_COLOR: " << aLen3D_rgba * double(sizeof(GLfloat)) / double(1024 * 1024) << " MiB\n";
366 return 0;
367 }
368}
369
1981cb22 370//==============================================================================
371//function : VImmediateFront
372//purpose :
373//==============================================================================
374
35e08fe8 375static int VImmediateFront (Draw_Interpretor& /*theDI*/,
1981cb22 376 Standard_Integer theArgNb,
377 const char** theArgVec)
378{
379 // get the context
380 Handle(AIS_InteractiveContext) aContextAIS = ViewerTest::GetAISContext();
381 if (aContextAIS.IsNull())
382 {
383 std::cerr << "No active view. Please call vinit.\n";
384 return 1;
385 }
386
dc3fe572 387 Handle(Graphic3d_GraphicDriver) aDriver = aContextAIS->CurrentViewer()->Driver();
388
1981cb22 389 if (aDriver.IsNull())
390 {
391 std::cerr << "Graphic driver not available.\n";
392 return 1;
393 }
394
395 if (theArgNb < 2)
396 {
1981cb22 397 std::cerr << "Wrong number of arguments.\n";
398 return 1;
399 }
400
c357e426 401 ViewerTest::CurrentView()->View()->SetImmediateModeDrawToFront (atoi(theArgVec[1]) != 0);
402
1981cb22 403 return 0;
404}
405
dac04bfa 406//==============================================================================
407//function : VGlInfo
408//purpose :
409//==============================================================================
410
411static int VGlInfo (Draw_Interpretor& theDI,
412 Standard_Integer theArgNb,
413 const char** theArgVec)
414{
415 // get the active view
416 Handle(V3d_View) aView = ViewerTest::CurrentView();
417 if (aView.IsNull())
418 {
419 std::cerr << "No active view. Please call vinit.\n";
420 return 1;
421 }
422
423 if (theArgNb <= 1)
424 {
c357e426 425 Handle(OpenGl_GraphicDriver) aDriver = Handle(OpenGl_GraphicDriver)::DownCast (aView->Viewer()->Driver());
4e1523ef 426 if (aDriver.IsNull())
427 {
428 std::cerr << "Error: view does not use OpenGL.\n";
429 return 1;
430 }
431 Handle(OpenGl_Context) aCtx = aDriver->GetSharedContext();
432 Standard_CString aDebugInfo = !aCtx.IsNull() && aCtx->IsDebugContext()
433 ? " GLdebug = ON\n"
434 : "";
dac04bfa 435 theDI << "OpenGL info:\n"
436 << " GLvendor = '" << (const char* )glGetString(GL_VENDOR) << "'\n"
437 << " GLdevice = '" << (const char* )glGetString(GL_RENDERER) << "'\n"
438 << " GLversion = '" << (const char* )glGetString(GL_VERSION) << "'\n"
58655684 439 << " GLSLversion = '" << (const char* )glGetString(GL_SHADING_LANGUAGE_VERSION) << "'\n"
440 << aDebugInfo;
dac04bfa 441 return 0;
442 }
443
444 const Standard_Boolean isList = theArgNb >= 3;
445 for (Standard_Integer anIter = 1; anIter < theArgNb; ++anIter)
446 {
447 TCollection_AsciiString aName (theArgVec[anIter]);
448 aName.UpperCase();
449 const char* aValue = NULL;
450 if (aName.Search ("VENDOR") != -1)
451 {
452 aValue = (const char* )glGetString (GL_VENDOR);
453 }
454 else if (aName.Search ("RENDERER") != -1)
455 {
456 aValue = (const char* )glGetString (GL_RENDERER);
457 }
458 else if (aName.Search ("SHADING_LANGUAGE_VERSION") != -1
459 || aName.Search ("GLSL") != -1)
460 {
461 aValue = (const char* )glGetString (GL_SHADING_LANGUAGE_VERSION);
462 }
463 else if (aName.Search ("VERSION") != -1)
464 {
465 aValue = (const char* )glGetString (GL_VERSION);
466 }
467 else if (aName.Search ("EXTENSIONS") != -1)
468 {
469 aValue = (const char* )glGetString (GL_EXTENSIONS);
470 }
471 else
472 {
473 std::cerr << "Unknown key '" << aName.ToCString() << "'\n";
474 return 1;
475 }
476
477 if (isList)
478 {
479 theDI << "{" << aValue << "} ";
480 }
481 else
482 {
483 theDI << aValue;
484 }
485 }
486
487 return 0;
488}
489
392ac980 490
491//==============================================================================
492//function : VShaderProg
493//purpose : Sets the pair of vertex and fragment shaders for the object
494//==============================================================================
495static Standard_Integer VShaderProg (Draw_Interpretor& /*theDI*/,
496 Standard_Integer theArgNb,
497 const char** theArgVec)
498{
499 Handle(AIS_InteractiveContext) aCtx = ViewerTest::GetAISContext();
500 if (aCtx.IsNull())
501 {
502 std::cerr << "Use 'vinit' command before " << theArgVec[0] << "\n";
503 return 1;
504 }
505 else if (theArgNb < 2)
506 {
507 std::cerr << theArgVec[0] << " syntax error: lack of arguments\n";
508 return 1;
509 }
510
511 TCollection_AsciiString aLastArg (theArgVec[theArgNb - 1]);
512 aLastArg.UpperCase();
513 const Standard_Boolean toTurnOff = aLastArg == "OFF";
514 Standard_Integer anArgsNb = theArgNb - 1;
515 Handle(Graphic3d_ShaderProgram) aProgram;
516 if (!toTurnOff
517 && aLastArg == "PHONG")
518 {
519 aProgram = new Graphic3d_ShaderProgram (Graphic3d_ShaderProgram::ShaderName_Phong);
520 }
521 if (!toTurnOff
522 && aProgram.IsNull())
523 {
524 if (theArgNb < 3)
525 {
526 std::cerr << theArgVec[0] << " syntax error: lack of arguments\n";
527 return 1;
528 }
529
530 const TCollection_AsciiString aSrcVert = theArgVec[theArgNb - 2];
531 const TCollection_AsciiString aSrcFrag = theArgVec[theArgNb - 1];
532 if (!aSrcVert.IsEmpty()
533 && !OSD_File (aSrcVert).Exists())
534 {
535 std::cerr << "Non-existing vertex shader source\n";
536 return 1;
537 }
538 if (!aSrcFrag.IsEmpty()
539 && !OSD_File (aSrcFrag).Exists())
540 {
541 std::cerr << "Non-existing fragment shader source\n";
542 return 1;
543 }
544
545 aProgram = new Graphic3d_ShaderProgram();
546 aProgram->AttachShader (Graphic3d_ShaderObject::CreateFromFile (Graphic3d_TOS_VERTEX, aSrcVert));
547 aProgram->AttachShader (Graphic3d_ShaderObject::CreateFromFile (Graphic3d_TOS_FRAGMENT, aSrcFrag));
548 anArgsNb = theArgNb - 2;
549 }
550
551 Handle(AIS_InteractiveObject) anIO;
552 if (anArgsNb <= 1
553 || *theArgVec[1] == '*')
554 {
555 for (ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName anIter (GetMapOfAIS());
556 anIter.More(); anIter.Next())
557 {
558 anIO = Handle(AIS_InteractiveObject)::DownCast (anIter.Key1());
559 if (!anIO.IsNull())
560 {
561 anIO->Attributes()->ShadingAspect()->Aspect()->SetShaderProgram (aProgram);
562 aCtx->Redisplay (anIO, Standard_False);
563 }
564 }
565 aCtx->UpdateCurrentViewer();
566 return 0;
567 }
568
569 for (Standard_Integer anArgIter = 1; anArgIter < anArgsNb; ++anArgIter)
570 {
571 const TCollection_AsciiString aName (theArgVec[anArgIter]);
572 if (!GetMapOfAIS().IsBound2 (aName))
573 {
574 std::cerr << "Warning: " << aName.ToCString() << " is not displayed\n";
575 continue;
576 }
577 anIO = Handle(AIS_InteractiveObject)::DownCast (GetMapOfAIS().Find2 (aName));
578 if (anIO.IsNull())
579 {
580 std::cerr << "Warning: " << aName.ToCString() << " is not an AIS object\n";
581 continue;
582 }
583 anIO->Attributes()->ShadingAspect()->Aspect()->SetShaderProgram (aProgram);
584 aCtx->Redisplay (anIO, Standard_False);
585 }
586
587 aCtx->UpdateCurrentViewer();
588 return 0;
589}
590
3946774d 591//=======================================================================
592//function : OpenGlCommands
593//purpose :
594//=======================================================================
595
596void ViewerTest::OpenGlCommands(Draw_Interpretor& theCommands)
597{
598 const char* aGroup ="Commands for low-level TKOpenGl features";
599
600 theCommands.Add("vuserdraw",
601 "vuserdraw : name - simulates drawing with help of UserDraw",
602 __FILE__, VUserDraw, aGroup);
3c4153af 603 theCommands.Add("vfeedback",
604 "vfeedback : perform test GL feedback rendering",
605 __FILE__, VFeedback, aGroup);
1981cb22 606 theCommands.Add("vimmediatefront",
607 "vimmediatefront : render immediate mode to front buffer or to back buffer",
608 __FILE__, VImmediateFront, aGroup);
dac04bfa 609 theCommands.Add("vglinfo",
610 "vglinfo [GL_VENDOR] [GL_RENDERER] [GL_VERSION] [GL_SHADING_LANGUAGE_VERSION] [GL_EXTENSIONS]"
611 " : prints GL info",
612 __FILE__, VGlInfo, aGroup);
392ac980 613 theCommands.Add("vshaderprog",
614 " 'vshaderprog [name] pathToVertexShader pathToFragmentShader'"
615 "\n\t\t: or 'vshaderprog [name] off' to disable GLSL program"
616 "\n\t\t: or 'vshaderprog [name] phong' to enable per-pixel lighting calculations"
617 "\n\t\t: * might be used to specify all displayed objects",
618 __FILE__, VShaderProg, aGroup);
3946774d 619}