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 | |
52 | extern Standard_Boolean VDisplayAISObject (const TCollection_AsciiString& theName, |
53 | const Handle(AIS_InteractiveObject)& theAISObj, |
54 | Standard_Boolean theReplaceIfExists = Standard_True); |
392ac980 |
55 | extern ViewerTest_DoubleMapOfInteractiveAndName& GetMapOfAIS(); |
3946774d |
56 | |
c04c30b3 |
57 | namespace { |
58 | |
3946774d |
59 | //======================================================================= |
60 | //function : VUserDraw |
61 | //purpose : Checks availability and operation of UserDraw feature |
62 | //======================================================================= |
3946774d |
63 | |
64 | class VUserDrawObj : public AIS_InteractiveObject |
65 | { |
66 | public: |
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 | |
80 | public: |
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 | |
106 | private: |
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 |
118 | private: |
3946774d |
119 | GLfloat myCoords[6]; |
3946774d |
120 | friend class Element; |
121 | }; |
ec357c5c |
122 | |
a521d90d |
123 | void 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 | |
142 | void 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 |
156 | void VUserDrawObj::Render(const Handle(OpenGl_Workspace)& theWorkspace) const |
157 | { |
1136702b |
158 | const Handle(OpenGl_Context)& aCtx = theWorkspace->GetGlContext(); |
a521d90d |
159 | |
3946774d |
160 | // To test linking against OpenGl_Workspace and all aspect classes |
f9ba5c4d |
161 | const OpenGl_AspectMarker* aMA = theWorkspace->AspectMarker(); |
b6472664 |
162 | aMA->Aspect()->Type(); |
f9ba5c4d |
163 | const OpenGl_AspectText* aTA = theWorkspace->AspectText(); |
b6472664 |
164 | aTA->Aspect()->Font(); |
165 | OpenGl_Vec4 aColor = theWorkspace->LineColor(); |
3946774d |
166 | |
c40eb6b9 |
167 | aCtx->ShaderManager()->BindLineProgram (Handle(OpenGl_TextureSet)(), Aspect_TOL_SOLID, |
168 | Graphic3d_TOSM_UNLIT, Graphic3d_AlphaMode_Opaque, false, |
169 | Handle(OpenGl_ShaderProgram)()); |
1136702b |
170 | aCtx->SetColor4fv (aColor); |
171 | |
172 | const OpenGl_Vec3 aVertArray[4] = |
173 | { |
174 | OpenGl_Vec3(myCoords[0], myCoords[1], myCoords[2]), |
175 | OpenGl_Vec3(myCoords[3], myCoords[4], myCoords[2]), |
176 | OpenGl_Vec3(myCoords[3], myCoords[4], myCoords[5]), |
177 | OpenGl_Vec3(myCoords[0], myCoords[1], myCoords[5]), |
178 | }; |
179 | Handle(OpenGl_VertexBuffer) aVertBuffer = new OpenGl_VertexBuffer(); |
180 | aVertBuffer->Init (aCtx, 3, 4, aVertArray[0].GetData()); |
181 | |
3946774d |
182 | // Finally draw something to make sure UserDraw really works |
1136702b |
183 | aVertBuffer->BindAttribute (aCtx, Graphic3d_TOA_POS); |
184 | glDrawArrays(GL_LINE_LOOP, 0, aVertBuffer->GetElemsNb()); |
185 | aVertBuffer->UnbindAttribute(aCtx, Graphic3d_TOA_POS); |
186 | aVertBuffer->Release (aCtx.get()); |
3946774d |
187 | } |
188 | |
c04c30b3 |
189 | } // end of anonymous namespace |
190 | |
3946774d |
191 | static Standard_Integer VUserDraw (Draw_Interpretor& di, |
192 | Standard_Integer argc, |
193 | const char ** argv) |
194 | { |
195 | Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext(); |
196 | if (aContext.IsNull()) |
197 | { |
198 | di << argv[0] << "Call 'vinit' before!\n"; |
199 | return 1; |
200 | } |
201 | |
dc3fe572 |
202 | Handle(OpenGl_GraphicDriver) aDriver = Handle(OpenGl_GraphicDriver)::DownCast (aContext->CurrentViewer()->Driver()); |
5e27df78 |
203 | if (aDriver.IsNull()) |
204 | { |
205 | std::cerr << "Graphic driver not available.\n"; |
206 | return 1; |
207 | } |
208 | |
3946774d |
209 | if (argc > 2) |
210 | { |
211 | di << argv[0] << "Wrong number of arguments, only the object name expected\n"; |
212 | return 1; |
213 | } |
214 | |
215 | TCollection_AsciiString aName (argv[1]); |
216 | VDisplayAISObject(aName, Handle(AIS_InteractiveObject)()); |
217 | |
3946774d |
218 | Handle(VUserDrawObj) anIObj = new VUserDrawObj(); |
219 | VDisplayAISObject(aName, anIObj); |
220 | |
221 | return 0; |
222 | } |
223 | |
3c4153af |
224 | //============================================================================== |
225 | //function : VFeedback |
226 | //purpose : |
227 | //============================================================================== |
228 | |
229 | static int VFeedback (Draw_Interpretor& theDI, |
35e08fe8 |
230 | Standard_Integer /*theArgNb*/, |
231 | const char** /*theArgVec*/) |
3c4153af |
232 | { |
1ce0716b |
233 | #if !defined(GL_ES_VERSION_2_0) |
3c4153af |
234 | // get the active view |
235 | Handle(V3d_View) aView = ViewerTest::CurrentView(); |
236 | if (aView.IsNull()) |
237 | { |
238 | std::cerr << "No active view. Please call vinit.\n"; |
239 | return 1; |
240 | } |
241 | |
242 | unsigned int aBufferSize = 1024 * 1024; |
243 | for (;;) |
244 | { |
245 | size_t aBytes = (size_t )aBufferSize * sizeof(GLfloat); |
246 | if (aBytes / sizeof(GLfloat) != (size_t )aBufferSize) |
247 | { |
248 | // finito la commedia |
249 | std::cerr << "Can not allocate buffer - requested size (" |
250 | << (double(aBufferSize / (1024 * 1024)) * double(sizeof(GLfloat))) |
251 | << " MiB) is out of address space\n"; |
252 | return 1; |
253 | } |
254 | |
255 | GLfloat* aBuffer = (GLfloat* )Standard::Allocate (aBytes); |
256 | if (aBuffer == NULL) |
257 | { |
258 | // finito la commedia |
259 | std::cerr << "Can not allocate buffer with size (" |
260 | << (double(aBufferSize / (1024 * 1024)) * double(sizeof(GLfloat))) |
261 | << " MiB)\n"; |
262 | return 1; |
263 | } |
264 | |
265 | glFeedbackBuffer ((GLsizei )aBufferSize, GL_2D, aBuffer); |
266 | glRenderMode (GL_FEEDBACK); |
267 | |
268 | aView->Redraw(); |
269 | |
270 | GLint aResult = glRenderMode (GL_RENDER); |
271 | if (aResult < 0) |
272 | { |
273 | aBufferSize *= 2; |
274 | |
275 | void* aPtr = aBuffer; |
276 | Standard::Free (aPtr); |
277 | aBuffer = NULL; |
278 | continue; |
279 | } |
280 | |
281 | std::cout << "FeedBack result= " << aResult << "\n"; |
282 | GLint aPntNb = 0; |
283 | GLint aTriNb = 0; |
284 | GLint aQuadsNb = 0; |
285 | GLint aPolyNb = 0; |
286 | GLint aNodesNb = 0; |
287 | GLint aLinesNb = 0; |
288 | GLint aBitmapsNb = 0; |
289 | GLint aPassThrNb = 0; |
290 | GLint aUnknownNb = 0; |
291 | const GLint NODE_VALUES = 2; // GL_2D |
292 | for (GLint anIter = 0; anIter < aResult;) |
293 | { |
294 | const GLfloat aPos = aBuffer[anIter]; |
295 | switch ((GLint )aPos) |
296 | { |
297 | case GL_POINT_TOKEN: |
298 | { |
299 | ++aPntNb; |
300 | ++aNodesNb; |
301 | anIter += 1 + NODE_VALUES; |
302 | break; |
303 | } |
304 | case GL_LINE_RESET_TOKEN: |
305 | case GL_LINE_TOKEN: |
306 | { |
307 | ++aLinesNb; |
308 | aNodesNb += 2; |
309 | anIter += 1 + 2 * NODE_VALUES; |
310 | break; |
311 | } |
312 | case GL_POLYGON_TOKEN: |
313 | { |
314 | const GLint aCount = (GLint )aBuffer[++anIter]; |
315 | aNodesNb += aCount; |
316 | anIter += aCount * NODE_VALUES + 1; |
317 | if (aCount == 3) |
318 | { |
319 | ++aTriNb; |
320 | } |
321 | else if (aCount == 4) |
322 | { |
323 | ++aQuadsNb; |
324 | } |
325 | else |
326 | { |
327 | ++aPolyNb; |
328 | } |
329 | break; |
330 | } |
331 | case GL_BITMAP_TOKEN: |
332 | case GL_DRAW_PIXEL_TOKEN: |
333 | case GL_COPY_PIXEL_TOKEN: |
334 | { |
335 | ++aBitmapsNb; |
336 | anIter += 1 + NODE_VALUES; |
337 | break; |
338 | } |
339 | case GL_PASS_THROUGH_TOKEN: |
340 | { |
341 | ++aPassThrNb; |
342 | anIter += 2; // header + value |
343 | break; |
344 | } |
345 | default: |
346 | { |
347 | ++anIter; |
348 | ++aUnknownNb; |
349 | break; |
350 | } |
351 | } |
352 | } |
353 | void* aPtr = aBuffer; |
354 | Standard::Free (aPtr); |
355 | |
356 | // return statistics |
357 | theDI << "Total nodes: " << aNodesNb << "\n" |
358 | << "Points: " << aPntNb << "\n" |
359 | << "Line segments: " << aLinesNb << "\n" |
360 | << "Triangles: " << aTriNb << "\n" |
361 | << "Quads: " << aQuadsNb << "\n" |
362 | << "Polygons: " << aPolyNb << "\n" |
363 | << "Bitmap tokens: " << aBitmapsNb << "\n" |
364 | << "Pass through: " << aPassThrNb << "\n" |
365 | << "UNKNOWN: " << aUnknownNb << "\n"; |
366 | |
367 | double aLen2D = double(aNodesNb * 2 + aPntNb + aLinesNb * 2 + (aTriNb + aQuadsNb + aPolyNb) * 2 + aBitmapsNb + aPassThrNb); |
368 | double aLen3D = double(aNodesNb * 3 + aPntNb + aLinesNb * 2 + (aTriNb + aQuadsNb + aPolyNb) * 2 + aBitmapsNb + aPassThrNb); |
369 | double aLen3D_rgba = double(aNodesNb * 7 + aPntNb + aLinesNb * 2 + (aTriNb + aQuadsNb + aPolyNb) * 2 + aBitmapsNb + aPassThrNb); |
370 | theDI << "Buffer size GL_2D: " << aLen2D * double(sizeof(GLfloat)) / double(1024 * 1024) << " MiB\n" |
371 | << "Buffer size GL_3D: " << aLen3D * double(sizeof(GLfloat)) / double(1024 * 1024) << " MiB\n" |
372 | << "Buffer size GL_3D_COLOR: " << aLen3D_rgba * double(sizeof(GLfloat)) / double(1024 * 1024) << " MiB\n"; |
373 | return 0; |
374 | } |
1ce0716b |
375 | #else |
376 | (void )theDI; |
377 | std::cout << "Command is unsupported on current platform.\n"; |
378 | return 1; |
379 | #endif |
3c4153af |
380 | } |
381 | |
1981cb22 |
382 | //============================================================================== |
383 | //function : VImmediateFront |
384 | //purpose : |
385 | //============================================================================== |
386 | |
35e08fe8 |
387 | static int VImmediateFront (Draw_Interpretor& /*theDI*/, |
1981cb22 |
388 | Standard_Integer theArgNb, |
389 | const char** theArgVec) |
390 | { |
391 | // get the context |
392 | Handle(AIS_InteractiveContext) aContextAIS = ViewerTest::GetAISContext(); |
393 | if (aContextAIS.IsNull()) |
394 | { |
395 | std::cerr << "No active view. Please call vinit.\n"; |
396 | return 1; |
397 | } |
398 | |
dc3fe572 |
399 | Handle(Graphic3d_GraphicDriver) aDriver = aContextAIS->CurrentViewer()->Driver(); |
400 | |
1981cb22 |
401 | if (aDriver.IsNull()) |
402 | { |
403 | std::cerr << "Graphic driver not available.\n"; |
404 | return 1; |
405 | } |
406 | |
407 | if (theArgNb < 2) |
408 | { |
1981cb22 |
409 | std::cerr << "Wrong number of arguments.\n"; |
410 | return 1; |
411 | } |
412 | |
c357e426 |
413 | ViewerTest::CurrentView()->View()->SetImmediateModeDrawToFront (atoi(theArgVec[1]) != 0); |
414 | |
1981cb22 |
415 | return 0; |
416 | } |
417 | |
26d9c835 |
418 | //! Search the info from the key. |
419 | inline TCollection_AsciiString searchInfo (const TColStd_IndexedDataMapOfStringString& theDict, |
420 | const TCollection_AsciiString& theKey) |
421 | { |
422 | for (TColStd_IndexedDataMapOfStringString::Iterator anIter (theDict); anIter.More(); anIter.Next()) |
423 | { |
424 | if (TCollection_AsciiString::IsSameString (anIter.Key(), theKey, Standard_False)) |
425 | { |
426 | return anIter.Value(); |
427 | } |
428 | } |
429 | return TCollection_AsciiString(); |
430 | } |
431 | |
dac04bfa |
432 | //============================================================================== |
433 | //function : VGlInfo |
434 | //purpose : |
435 | //============================================================================== |
436 | |
437 | static int VGlInfo (Draw_Interpretor& theDI, |
438 | Standard_Integer theArgNb, |
439 | const char** theArgVec) |
440 | { |
441 | // get the active view |
442 | Handle(V3d_View) aView = ViewerTest::CurrentView(); |
443 | if (aView.IsNull()) |
444 | { |
445 | std::cerr << "No active view. Please call vinit.\n"; |
446 | return 1; |
447 | } |
448 | |
26d9c835 |
449 | Standard_Integer anArgIter = 1; |
450 | Graphic3d_DiagnosticInfo anInfoLevel = Graphic3d_DiagnosticInfo_Basic; |
451 | if (theArgNb == 2) |
dac04bfa |
452 | { |
26d9c835 |
453 | TCollection_AsciiString aName (theArgVec[1]); |
454 | aName.LowerCase(); |
455 | if (aName == "-short") |
4e1523ef |
456 | { |
26d9c835 |
457 | ++anArgIter; |
458 | anInfoLevel = Graphic3d_DiagnosticInfo_Short; |
459 | } |
460 | else if (aName == "-basic") |
461 | { |
462 | ++anArgIter; |
463 | anInfoLevel = Graphic3d_DiagnosticInfo_Basic; |
4e1523ef |
464 | } |
26d9c835 |
465 | else if (aName == "-complete" |
466 | || aName == "-full") |
467 | { |
468 | ++anArgIter; |
469 | anInfoLevel = Graphic3d_DiagnosticInfo_Complete; |
470 | } |
471 | } |
472 | |
473 | TColStd_IndexedDataMapOfStringString aDict; |
474 | if (anArgIter >= theArgNb) |
475 | { |
476 | aView->DiagnosticInformation (aDict, anInfoLevel); |
477 | TCollection_AsciiString aText; |
478 | for (TColStd_IndexedDataMapOfStringString::Iterator aValueIter (aDict); aValueIter.More(); aValueIter.Next()) |
479 | { |
480 | if (!aText.IsEmpty()) |
481 | { |
482 | aText += "\n"; |
483 | } |
484 | aText += TCollection_AsciiString(" ") + aValueIter.Key() + ": " + aValueIter.Value(); |
485 | } |
486 | |
dac04bfa |
487 | theDI << "OpenGL info:\n" |
26d9c835 |
488 | << aText; |
dac04bfa |
489 | return 0; |
490 | } |
491 | |
492 | const Standard_Boolean isList = theArgNb >= 3; |
26d9c835 |
493 | aView->DiagnosticInformation (aDict, Graphic3d_DiagnosticInfo_Complete); |
494 | for (; anArgIter < theArgNb; ++anArgIter) |
dac04bfa |
495 | { |
26d9c835 |
496 | TCollection_AsciiString aName (theArgVec[anArgIter]); |
dac04bfa |
497 | aName.UpperCase(); |
26d9c835 |
498 | TCollection_AsciiString aValue; |
dac04bfa |
499 | if (aName.Search ("VENDOR") != -1) |
500 | { |
26d9c835 |
501 | aValue = searchInfo (aDict, "GLvendor"); |
dac04bfa |
502 | } |
503 | else if (aName.Search ("RENDERER") != -1) |
504 | { |
26d9c835 |
505 | aValue = searchInfo (aDict, "GLdevice"); |
dac04bfa |
506 | } |
507 | else if (aName.Search ("SHADING_LANGUAGE_VERSION") != -1 |
508 | || aName.Search ("GLSL") != -1) |
509 | { |
26d9c835 |
510 | aValue = searchInfo (aDict, "GLSLversion"); |
dac04bfa |
511 | } |
512 | else if (aName.Search ("VERSION") != -1) |
513 | { |
26d9c835 |
514 | aValue = searchInfo (aDict, "GLversion"); |
dac04bfa |
515 | } |
516 | else if (aName.Search ("EXTENSIONS") != -1) |
517 | { |
26d9c835 |
518 | aValue = searchInfo (aDict, "GLextensions"); |
dac04bfa |
519 | } |
520 | else |
521 | { |
522 | std::cerr << "Unknown key '" << aName.ToCString() << "'\n"; |
523 | return 1; |
524 | } |
525 | |
526 | if (isList) |
527 | { |
528 | theDI << "{" << aValue << "} "; |
529 | } |
530 | else |
531 | { |
532 | theDI << aValue; |
533 | } |
534 | } |
535 | |
536 | return 0; |
537 | } |
538 | |
8e0a2b19 |
539 | //! Parse shader type argument. |
540 | static bool parseShaderTypeArg (Graphic3d_TypeOfShaderObject& theType, |
541 | const TCollection_AsciiString& theArg) |
542 | { |
543 | if (theArg == "-vertex" |
544 | || theArg == "-vert") |
545 | { |
546 | theType = Graphic3d_TOS_VERTEX; |
547 | } |
548 | else if (theArg == "-tessevaluation" |
549 | || theArg == "-tesseval" |
550 | || theArg == "-evaluation" |
551 | || theArg == "-eval") |
552 | { |
553 | theType = Graphic3d_TOS_TESS_EVALUATION; |
554 | } |
555 | else if (theArg == "-tesscontrol" |
556 | || theArg == "-tessctrl" |
557 | || theArg == "-control" |
558 | || theArg == "-ctrl") |
559 | { |
560 | theType = Graphic3d_TOS_TESS_CONTROL; |
561 | } |
562 | else if (theArg == "-geometry" |
563 | || theArg == "-geom") |
564 | { |
565 | theType = Graphic3d_TOS_GEOMETRY; |
566 | } |
567 | else if (theArg == "-fragment" |
568 | || theArg == "-frag") |
569 | { |
570 | theType = Graphic3d_TOS_FRAGMENT; |
571 | } |
572 | else if (theArg == "-compute" |
573 | || theArg == "-comp") |
574 | { |
575 | theType = Graphic3d_TOS_COMPUTE; |
576 | } |
577 | else |
578 | { |
579 | return false; |
580 | } |
581 | return true; |
582 | } |
392ac980 |
583 | |
584 | //============================================================================== |
585 | //function : VShaderProg |
586 | //purpose : Sets the pair of vertex and fragment shaders for the object |
587 | //============================================================================== |
588 | static Standard_Integer VShaderProg (Draw_Interpretor& /*theDI*/, |
589 | Standard_Integer theArgNb, |
590 | const char** theArgVec) |
591 | { |
592 | Handle(AIS_InteractiveContext) aCtx = ViewerTest::GetAISContext(); |
593 | if (aCtx.IsNull()) |
594 | { |
8e0a2b19 |
595 | std::cout << "Error: no active view.\n"; |
392ac980 |
596 | return 1; |
597 | } |
598 | else if (theArgNb < 2) |
599 | { |
8e0a2b19 |
600 | std::cout << "Syntax error: lack of arguments\n"; |
392ac980 |
601 | return 1; |
602 | } |
603 | |
8e0a2b19 |
604 | bool isExplicitShaderType = false; |
605 | Handle(Graphic3d_ShaderProgram) aProgram = new Graphic3d_ShaderProgram(); |
606 | NCollection_Sequence<Handle(AIS_InteractiveObject)> aPrsList; |
607 | Graphic3d_GroupAspect aGroupAspect = Graphic3d_ASPECT_FILL_AREA; |
608 | bool isSetGroupAspect = false; |
609 | for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter) |
392ac980 |
610 | { |
8e0a2b19 |
611 | TCollection_AsciiString anArg (theArgVec[anArgIter]); |
612 | anArg.LowerCase(); |
613 | Graphic3d_TypeOfShaderObject aShaderTypeArg = Graphic3d_TypeOfShaderObject(-1); |
614 | if (!aProgram.IsNull() |
615 | && aProgram->ShaderObjects().IsEmpty() |
616 | && (anArg == "-off" |
617 | || anArg == "off")) |
618 | { |
619 | aProgram.Nullify(); |
620 | } |
621 | else if (!aProgram.IsNull() |
622 | && aProgram->ShaderObjects().IsEmpty() |
623 | && (anArg == "-phong" |
624 | || anArg == "phong")) |
625 | { |
626 | const TCollection_AsciiString& aShadersRoot = Graphic3d_ShaderProgram::ShadersFolder(); |
627 | if (aShadersRoot.IsEmpty()) |
628 | { |
629 | std::cout << "Error: both environment variables CSF_ShadersDirectory and CASROOT are undefined!\n" |
630 | "At least one should be defined to load Phong program.\n"; |
631 | return 1; |
632 | } |
ee5befae |
633 | |
8e0a2b19 |
634 | const TCollection_AsciiString aSrcVert = aShadersRoot + "/PhongShading.vs"; |
635 | const TCollection_AsciiString aSrcFrag = aShadersRoot + "/PhongShading.fs"; |
636 | if (!aSrcVert.IsEmpty() |
637 | && !OSD_File (aSrcVert).Exists()) |
638 | { |
639 | std::cout << "Error: PhongShading.vs is not found\n"; |
640 | return 1; |
641 | } |
642 | if (!aSrcFrag.IsEmpty() |
643 | && !OSD_File (aSrcFrag).Exists()) |
644 | { |
645 | std::cout << "Error: PhongShading.fs is not found\n"; |
646 | return 1; |
647 | } |
ee5befae |
648 | |
8e0a2b19 |
649 | aProgram->AttachShader (Graphic3d_ShaderObject::CreateFromFile (Graphic3d_TOS_VERTEX, aSrcVert)); |
650 | aProgram->AttachShader (Graphic3d_ShaderObject::CreateFromFile (Graphic3d_TOS_FRAGMENT, aSrcFrag)); |
ee5befae |
651 | } |
8e0a2b19 |
652 | else if (aPrsList.IsEmpty() |
653 | && anArg == "*") |
ee5befae |
654 | { |
8e0a2b19 |
655 | // |
392ac980 |
656 | } |
8e0a2b19 |
657 | else if (!isSetGroupAspect |
658 | && anArgIter + 1 < theArgNb |
659 | && (anArg == "-primtype" |
660 | || anArg == "-primitivetype" |
661 | || anArg == "-groupaspect" |
662 | || anArg == "-aspecttype" |
663 | || anArg == "-aspect")) |
664 | { |
665 | isSetGroupAspect = true; |
666 | TCollection_AsciiString aPrimTypeStr (theArgVec[++anArgIter]); |
667 | aPrimTypeStr.LowerCase(); |
668 | if (aPrimTypeStr == "line") |
669 | { |
670 | aGroupAspect = Graphic3d_ASPECT_LINE; |
671 | } |
672 | else if (aPrimTypeStr == "tris" |
673 | || aPrimTypeStr == "triangles" |
674 | || aPrimTypeStr == "fill" |
675 | || aPrimTypeStr == "fillarea" |
676 | || aPrimTypeStr == "shading" |
677 | || aPrimTypeStr == "shade") |
678 | { |
679 | aGroupAspect = Graphic3d_ASPECT_FILL_AREA; |
680 | } |
681 | else if (aPrimTypeStr == "text") |
682 | { |
683 | aGroupAspect = Graphic3d_ASPECT_TEXT; |
684 | } |
685 | else if (aPrimTypeStr == "marker" |
686 | || aPrimTypeStr == "point" |
687 | || aPrimTypeStr == "pnt") |
688 | { |
689 | aGroupAspect = Graphic3d_ASPECT_MARKER; |
690 | } |
691 | else |
692 | { |
693 | std::cerr << "Syntax error at '" << aPrimTypeStr << "'\n"; |
694 | return 1; |
695 | } |
392ac980 |
696 | } |
8e0a2b19 |
697 | else if (anArgIter + 1 < theArgNb |
698 | && !aProgram.IsNull() |
699 | && aProgram->Header().IsEmpty() |
700 | && (anArg == "-version" |
701 | || anArg == "-glslversion" |
702 | || anArg == "-header" |
703 | || anArg == "-glslheader")) |
392ac980 |
704 | { |
8e0a2b19 |
705 | TCollection_AsciiString aHeader (theArgVec[++anArgIter]); |
706 | if (aHeader.IsIntegerValue()) |
707 | { |
708 | aHeader = TCollection_AsciiString ("#version ") + aHeader; |
709 | } |
710 | aProgram->SetHeader (aHeader); |
cc8cbabe |
711 | } |
8e0a2b19 |
712 | else if (!anArg.StartsWith ("-") |
713 | && GetMapOfAIS().IsBound2 (theArgVec[anArgIter])) |
cc8cbabe |
714 | { |
8f521168 |
715 | Handle(AIS_InteractiveObject) anIO = GetMapOfAIS().Find2 (theArgVec[anArgIter]); |
8e0a2b19 |
716 | if (anIO.IsNull()) |
717 | { |
718 | std::cerr << "Syntax error: " << theArgVec[anArgIter] << " is not an AIS object\n"; |
719 | return 1; |
720 | } |
721 | aPrsList.Append (anIO); |
392ac980 |
722 | } |
8e0a2b19 |
723 | else if (!aProgram.IsNull() |
724 | && ((anArgIter + 1 < theArgNb && parseShaderTypeArg (aShaderTypeArg, anArg)) |
725 | || (!isExplicitShaderType && aProgram->ShaderObjects().Size() < 2))) |
392ac980 |
726 | { |
8e0a2b19 |
727 | TCollection_AsciiString aShaderPath (theArgVec[anArgIter]); |
728 | if (aShaderTypeArg != Graphic3d_TypeOfShaderObject(-1)) |
392ac980 |
729 | { |
8e0a2b19 |
730 | aShaderPath = (theArgVec[++anArgIter]); |
731 | isExplicitShaderType = true; |
fb66bb28 |
732 | } |
733 | |
8e0a2b19 |
734 | const bool isSrcFile = OSD_File (aShaderPath).Exists(); |
735 | Handle(Graphic3d_ShaderObject) aShader = isSrcFile |
736 | ? Graphic3d_ShaderObject::CreateFromFile (Graphic3d_TOS_VERTEX, aShaderPath) |
737 | : Graphic3d_ShaderObject::CreateFromSource(Graphic3d_TOS_VERTEX, aShaderPath); |
738 | const TCollection_AsciiString& aShaderSrc = aShader->Source(); |
739 | |
740 | const bool hasVertPos = aShaderSrc.Search ("gl_Position") != -1; |
b17e5bae |
741 | const bool hasFragColor = aShaderSrc.Search ("occSetFragColor") != -1 |
742 | || aShaderSrc.Search ("occFragColor") != -1 |
8e0a2b19 |
743 | || aShaderSrc.Search ("gl_FragColor") != -1 |
744 | || aShaderSrc.Search ("gl_FragData") != -1; |
745 | Graphic3d_TypeOfShaderObject aShaderType = aShaderTypeArg; |
746 | if (aShaderType == Graphic3d_TypeOfShaderObject(-1)) |
fb66bb28 |
747 | { |
8e0a2b19 |
748 | if (hasVertPos |
749 | && !hasFragColor) |
750 | { |
751 | aShaderType = Graphic3d_TOS_VERTEX; |
752 | } |
753 | if (hasFragColor |
754 | && !hasVertPos) |
755 | { |
756 | aShaderType = Graphic3d_TOS_FRAGMENT; |
757 | } |
392ac980 |
758 | } |
8e0a2b19 |
759 | if (aShaderType == Graphic3d_TypeOfShaderObject(-1)) |
fb66bb28 |
760 | { |
8e0a2b19 |
761 | std::cerr << "Error: non-existing or invalid shader source\n"; |
762 | return 1; |
fb66bb28 |
763 | } |
8e0a2b19 |
764 | |
765 | aProgram->AttachShader (Graphic3d_ShaderObject::CreateFromSource (aShaderType, aShaderSrc)); |
766 | } |
767 | else |
768 | { |
769 | std::cerr << "Syntax error at '" << anArg << "'\n"; |
770 | return 1; |
392ac980 |
771 | } |
392ac980 |
772 | } |
773 | |
b17e5bae |
774 | if (!aProgram.IsNull() |
775 | && ViewerTest::CurrentView()->RenderingParams().TransparencyMethod == Graphic3d_RTM_BLEND_OIT) |
776 | { |
777 | aProgram->SetNbFragmentOutputs (2); |
778 | aProgram->SetWeightOitOutput (true); |
779 | } |
780 | |
8e0a2b19 |
781 | ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName aGlobalPrsIter (GetMapOfAIS()); |
782 | NCollection_Sequence<Handle(AIS_InteractiveObject)>::Iterator aPrsIter (aPrsList); |
783 | const bool isGlobalList = aPrsList.IsEmpty(); |
784 | for (;;) |
392ac980 |
785 | { |
8e0a2b19 |
786 | Handle(AIS_InteractiveObject) anIO; |
787 | if (isGlobalList) |
392ac980 |
788 | { |
8e0a2b19 |
789 | if (!aGlobalPrsIter.More()) |
790 | { |
791 | break; |
792 | } |
8f521168 |
793 | anIO = aGlobalPrsIter.Key1(); |
8e0a2b19 |
794 | aGlobalPrsIter.Next(); |
795 | if (anIO.IsNull()) |
796 | { |
797 | continue; |
798 | } |
392ac980 |
799 | } |
8e0a2b19 |
800 | else |
392ac980 |
801 | { |
8e0a2b19 |
802 | if (!aPrsIter.More()) |
803 | { |
804 | break; |
805 | } |
806 | anIO = aPrsIter.Value(); |
807 | aPrsIter.Next(); |
392ac980 |
808 | } |
fb66bb28 |
809 | |
8e0a2b19 |
810 | if (anIO->Attributes()->SetShaderProgram (aProgram, aGroupAspect, true)) |
fb66bb28 |
811 | { |
fb66bb28 |
812 | aCtx->Redisplay (anIO, Standard_False); |
813 | } |
814 | else |
815 | { |
fb66bb28 |
816 | anIO->SynchronizeAspects(); |
817 | } |
392ac980 |
818 | } |
819 | |
820 | aCtx->UpdateCurrentViewer(); |
821 | return 0; |
822 | } |
823 | |
3946774d |
824 | //======================================================================= |
825 | //function : OpenGlCommands |
826 | //purpose : |
827 | //======================================================================= |
828 | |
829 | void ViewerTest::OpenGlCommands(Draw_Interpretor& theCommands) |
830 | { |
831 | const char* aGroup ="Commands for low-level TKOpenGl features"; |
832 | |
833 | theCommands.Add("vuserdraw", |
834 | "vuserdraw : name - simulates drawing with help of UserDraw", |
835 | __FILE__, VUserDraw, aGroup); |
3c4153af |
836 | theCommands.Add("vfeedback", |
837 | "vfeedback : perform test GL feedback rendering", |
838 | __FILE__, VFeedback, aGroup); |
1981cb22 |
839 | theCommands.Add("vimmediatefront", |
840 | "vimmediatefront : render immediate mode to front buffer or to back buffer", |
841 | __FILE__, VImmediateFront, aGroup); |
dac04bfa |
842 | theCommands.Add("vglinfo", |
26d9c835 |
843 | "vglinfo [-short|-basic|-complete]" |
844 | "\n\t\t: [GL_VENDOR] [GL_RENDERER] [GL_VERSION]" |
845 | "\n\t\t: [GL_SHADING_LANGUAGE_VERSION] [GL_EXTENSIONS]" |
846 | "\n\t\t: print OpenGL info", |
dac04bfa |
847 | __FILE__, VGlInfo, aGroup); |
8e0a2b19 |
848 | theCommands.Add("vshader", |
849 | "vshader name -vert VertexShader -frag FragmentShader [-geom GeometryShader]" |
850 | "\n\t\t: [-off] [-phong] [-aspect {shading|line|point|text}=shading]" |
851 | "\n\t\t: [-header VersionHeader]" |
852 | "\n\t\t: [-tessControl TessControlShader -tesseval TessEvaluationShader]" |
853 | "\n\t\t: Assign custom GLSL program to presentation aspects.", |
392ac980 |
854 | __FILE__, VShaderProg, aGroup); |
8e0a2b19 |
855 | theCommands.Add("vshaderprog", "Alias for vshader", __FILE__, VShaderProg, aGroup); |
3946774d |
856 | } |