1 //
2 // Copyright 2016 Pixar
3 //
4 // Licensed under the Apache License, Version 2.0 (the "Apache License")
5 // with the following modification; you may not use this file except in
6 // compliance with the Apache License and the following modification to it:
7 // Section 6. Trademarks. is deleted and replaced with:
8 //
9 // 6. Trademarks. This License does not grant permission to use the trade
10 // names, trademarks, service marks, or product names of the Licensor
11 // and its affiliates, except as required to comply with Section 4(c) of
12 // the License and to reproduce the content of the NOTICE file.
13 //
14 // You may obtain a copy of the Apache License at
15 //
16 // http://www.apache.org/licenses/LICENSE-2.0
17 //
18 // Unless required by applicable law or agreed to in writing, software
19 // distributed under the Apache License with the above modification is
20 // distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
21 // KIND, either express or implied. See the Apache License for the specific
22 // language governing permissions and limitations under the Apache License.
23 //
24 #include "pxr/pxr.h"
25
26 #include "pxr/imaging/garch/glApi.h"
27
28 #include "pxr/usdImaging/usdImagingGL/unitTestGLDrawing.h"
29 #include "pxr/imaging/glf/contextCaps.h"
30 #include "pxr/imaging/glf/diagnostic.h"
31 #include "pxr/imaging/glf/drawTarget.h"
32 #include "pxr/imaging/garch/glDebugWindow.h"
33
34 #include "pxr/base/arch/attributes.h"
35 #include "pxr/base/gf/vec2i.h"
36 #include "pxr/base/trace/collector.h"
37 #include "pxr/base/trace/reporter.h"
38
39 #include "pxr/base/plug/registry.h"
40 #include "pxr/base/arch/systemInfo.h"
41
42 #include <stdio.h>
43 #include <stdarg.h>
44
45 #include <fstream>
46
47 PXR_NAMESPACE_OPEN_SCOPE
48
49
UsdImagingGL_UnitTestHelper_InitPlugins()50 static void UsdImagingGL_UnitTestHelper_InitPlugins()
51 {
52 // Unfortunately, in order to properly find plugins in our test setup, we
53 // need to know where the test is running.
54 std::string testDir = TfGetPathName(ArchGetExecutablePath());
55 std::string pluginDir = TfStringCatPaths(testDir,
56 "UsdImagingPlugins/lib/UsdImagingTest.framework/Resources");
57 printf("registering plugins in: %s\n", pluginDir.c_str());
58
59 PlugRegistry::GetInstance().RegisterPlugins(pluginDir);
60 }
61
62 ////////////////////////////////////////////////////////////
63
64 class UsdImagingGL_UnitTestWindow : public GarchGLDebugWindow {
65 public:
66 typedef UsdImagingGL_UnitTestWindow This;
67
68 public:
69 UsdImagingGL_UnitTestWindow(UsdImagingGL_UnitTestGLDrawing * unitTest,
70 int w, int h);
71 virtual ~UsdImagingGL_UnitTestWindow();
72
73 void DrawOffscreen();
74
75 bool WriteToFile(std::string const & attachment,
76 std::string const & filename);
77
78 // GarchGLDebugWIndow overrides;
79 virtual void OnInitializeGL();
80 virtual void OnUninitializeGL();
81 virtual void OnPaintGL();
82 virtual void OnKeyRelease(int key);
83 virtual void OnMousePress(int button, int x, int y, int modKeys);
84 virtual void OnMouseRelease(int button, int x, int y, int modKeys);
85 virtual void OnMouseMove(int x, int y, int modKeys);
86
87 private:
88 UsdImagingGL_UnitTestGLDrawing *_unitTest;
89 GlfDrawTargetRefPtr _drawTarget;
90 };
91
UsdImagingGL_UnitTestWindow(UsdImagingGL_UnitTestGLDrawing * unitTest,int w,int h)92 UsdImagingGL_UnitTestWindow::UsdImagingGL_UnitTestWindow(
93 UsdImagingGL_UnitTestGLDrawing * unitTest, int w, int h)
94 : GarchGLDebugWindow("UsdImagingGL Test", w, h)
95 , _unitTest(unitTest)
96 {
97 }
98
~UsdImagingGL_UnitTestWindow()99 UsdImagingGL_UnitTestWindow::~UsdImagingGL_UnitTestWindow()
100 {
101 }
102
103 /* virtual */
104 void
OnInitializeGL()105 UsdImagingGL_UnitTestWindow::OnInitializeGL()
106 {
107 GarchGLApiLoad();
108 GlfRegisterDefaultDebugOutputMessageCallback();
109 GlfContextCaps::InitInstance();
110
111
112 //
113 // Create an offscreen draw target which is the same size as this
114 // widget and initialize the unit test with the draw target bound.
115 //
116 _drawTarget = GlfDrawTarget::New(GfVec2i(GetWidth(), GetHeight()));
117 _drawTarget->Bind();
118 _drawTarget->AddAttachment("color", GL_RGBA, GL_FLOAT, GL_RGBA);
119 _drawTarget->AddAttachment("depth", GL_DEPTH_COMPONENT, GL_FLOAT,
120 GL_DEPTH_COMPONENT);
121
122 _unitTest->InitTest();
123
124 _drawTarget->Unbind();
125 }
126
127 /* virtual */
128 void
OnUninitializeGL()129 UsdImagingGL_UnitTestWindow::OnUninitializeGL()
130 {
131 _drawTarget = GlfDrawTargetRefPtr();
132
133 _unitTest->ShutdownTest();
134 }
135
136 /* virtual */
137 void
OnPaintGL()138 UsdImagingGL_UnitTestWindow::OnPaintGL()
139 {
140 //
141 // Update the draw target's size and execute the unit test with
142 // the draw target bound.
143 //
144 int width = GetWidth();
145 int height = GetHeight();
146 _drawTarget->Bind();
147 _drawTarget->SetSize(GfVec2i(width, height));
148
149 _unitTest->DrawTest(false);
150
151 _drawTarget->Unbind();
152
153 //
154 // Blit the resulting color buffer to the window (this is a noop
155 // if we're drawing offscreen).
156 //
157 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
158 glBindFramebuffer(GL_READ_FRAMEBUFFER, _drawTarget->GetFramebufferId());
159
160 glBlitFramebuffer(0, 0, width, height,
161 0, 0, width, height,
162 GL_COLOR_BUFFER_BIT,
163 GL_NEAREST);
164
165 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
166 glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
167 }
168
169 void
DrawOffscreen()170 UsdImagingGL_UnitTestWindow::DrawOffscreen()
171 {
172 _drawTarget->Bind();
173 _drawTarget->SetSize(GfVec2i(GetWidth(), GetHeight()));
174
175 _unitTest->DrawTest(true);
176
177 _drawTarget->Unbind();
178 }
179
180 bool
WriteToFile(std::string const & attachment,std::string const & filename)181 UsdImagingGL_UnitTestWindow::WriteToFile(std::string const & attachment,
182 std::string const & filename)
183 {
184 // We need to unbind the draw target before writing to file to be sure the
185 // attachment is in a good state.
186 bool isBound = _drawTarget->IsBound();
187 if (isBound)
188 _drawTarget->Unbind();
189
190 bool result = _drawTarget->WriteToFile(attachment, filename);
191
192 if (isBound)
193 _drawTarget->Bind();
194 return result;
195 }
196
197 /* virtual */
198 void
OnKeyRelease(int key)199 UsdImagingGL_UnitTestWindow::OnKeyRelease(int key)
200 {
201 switch (key) {
202 case 'q':
203 ExitApp();
204 return;
205 }
206 _unitTest->KeyRelease(key);
207 }
208
209 /* virtual */
210 void
OnMousePress(int button,int x,int y,int modKeys)211 UsdImagingGL_UnitTestWindow::OnMousePress(int button,
212 int x, int y, int modKeys)
213 {
214 _unitTest->MousePress(button, x, y, modKeys);
215 }
216
217 /* virtual */
218 void
OnMouseRelease(int button,int x,int y,int modKeys)219 UsdImagingGL_UnitTestWindow::OnMouseRelease(int button,
220 int x, int y, int modKeys)
221 {
222 _unitTest->MouseRelease(button, x, y, modKeys);
223 }
224
225 /* virtual */
226 void
OnMouseMove(int x,int y,int modKeys)227 UsdImagingGL_UnitTestWindow::OnMouseMove(int x, int y, int modKeys)
228 {
229 _unitTest->MouseMove(x, y, modKeys);
230 }
231
232 ////////////////////////////////////////////////////////////
233
UsdImagingGL_UnitTestGLDrawing()234 UsdImagingGL_UnitTestGLDrawing::UsdImagingGL_UnitTestGLDrawing()
235 : _widget(NULL)
236 , _testLighting(false)
237 , _sceneLights(false)
238 , _cameraLight(false)
239 , _testIdRender(false)
240 , _enableSceneMaterials(true)
241 , _complexity(1.0f)
242 , _drawMode(UsdImagingGLDrawMode::DRAW_SHADED_SMOOTH)
243 , _shouldFrameAll(false)
244 , _cullStyle(UsdImagingGLCullStyle::CULL_STYLE_NOTHING)
245 , _showGuides(UsdImagingGLRenderParams().showGuides)
246 , _showRender(UsdImagingGLRenderParams().showRender)
247 , _showProxy(UsdImagingGLRenderParams().showProxy)
248 , _clearOnce(false)
249 , _presentDisabled(false)
250 {
251 }
252
~UsdImagingGL_UnitTestGLDrawing()253 UsdImagingGL_UnitTestGLDrawing::~UsdImagingGL_UnitTestGLDrawing()
254 {
255 }
256
257 int
GetWidth() const258 UsdImagingGL_UnitTestGLDrawing::GetWidth() const
259 {
260 return _widget->GetWidth();
261 }
262
263 int
GetHeight() const264 UsdImagingGL_UnitTestGLDrawing::GetHeight() const
265 {
266 return _widget->GetHeight();
267 }
268
269 bool
WriteToFile(std::string const & attachment,std::string const & filename) const270 UsdImagingGL_UnitTestGLDrawing::WriteToFile(std::string const & attachment,
271 std::string const & filename) const
272 {
273 return _widget->WriteToFile(attachment, filename);
274 }
275
276 struct UsdImagingGL_UnitTestGLDrawing::_Args {
_ArgsUsdImagingGL_UnitTestGLDrawing::_Args277 _Args()
278 : offscreen(false)
279 , clearColor{1.0f, 0.5f, 0.1f, 1.0f}
280 , translate{0.0f, -1000.0f, -2500.0f}
281 , widgetSize{640, 480}
282 , pixelAspectRatio(1.0f)
283 , dataWindow{0, 0, 0, 0}
284 , displayWindow{0.0f, 0.0f, 0.0f, 0.0f}
285 {
286 }
287
288 std::string unresolvedStageFilePath;
289 bool offscreen;
290 std::string shading;
291 std::string cullStyle;
292 std::vector<double> clipPlaneCoords;
293 std::vector<double> complexities;
294 float clearColor[4];
295 float translate[3];
296 int widgetSize[2];
297 float pixelAspectRatio;
298 int dataWindow[4];
299 float displayWindow[4];
300 };
301
302 static void Die(const char* fmt, ...) ARCH_PRINTF_FUNCTION(1, 2);
Die(const char * fmt,...)303 static void Die(const char* fmt, ...)
304 {
305 va_list ap;
306 va_start(ap, fmt);
307 vfprintf(stderr, fmt, ap);
308 va_end(ap);
309 fflush(stderr);
310 exit(1);
311 }
312
313 static void
314 ParseError(const char* pname, const char* fmt, ...) ARCH_PRINTF_FUNCTION(2, 3);
315 static void
ParseError(const char * pname,const char * fmt,...)316 ParseError(const char* pname, const char* fmt, ...)
317 {
318 fprintf(stderr, "%s: ", TfGetBaseName(pname).c_str());
319 va_list ap;
320 va_start(ap, fmt);
321 vfprintf(stderr, fmt, ap);
322 va_end(ap);
323 fprintf(stderr, ". Try '%s -' for help.\n", TfGetBaseName(pname).c_str());
324 fflush(stderr);
325 exit(1);
326 }
327
Usage(int argc,char * argv[])328 static void Usage(int argc, char *argv[])
329 {
330 static const char usage[] =
331 "%s [-stage filePath] [-write filePath]\n"
332 " [-offscreen] [-lighting] [-idRender]\n"
333 " [-disableSceneMaterials]\n"
334 " [-camera pathToCamera]\n"
335 " [-complexity complexity]\n"
336 " [-renderer rendererName]\n"
337 " [-shading [flat|smooth|wire|wireOnSurface|points]]\n"
338 " [-frameAll]\n"
339 " [-clipPlane clipPlane1 ... clipPlane4]\n"
340 " [-complexities complexities1 complexities2 ...]\n"
341 " [-times times1 times2 ...] [-cullStyle cullStyle]\n"
342 " [-clear r g b a] [-clearOnce] [-translate x y z]\n"
343 " [-renderSetting name type value]\n"
344 " [-rendererAov name]\n"
345 " [-perfStatsFile path]\n"
346 " [-traceFile path] [...]\n"
347 "\n"
348 " usdImaging basic drawing test\n"
349 "\n"
350 "options:\n"
351 " -stage filePath name of usd stage to open []\n"
352 " -write filePath name of image file to write (suffix determines type) []\n"
353 " -offscreen execute without mapping a window\n"
354 " -lighting use simple lighting override shader\n"
355 " -sceneLights use in combination with -lighting to utilize the lights \n"
356 " defined in the scene\n"
357 " -camLight use a single camera light\n"
358 " -idRender ID rendering\n"
359 " -disableSceneMaterials\n"
360 " Disable scene materials\n"
361 " -complexity complexity\n"
362 " Set the fallback complexity [1]\n"
363 " -renderer rendererName\n"
364 " use the specified renderer plugin []\n"
365 " -shading [flat|smooth|wire|wireOnSurface]\n"
366 " force specific type of shading\n"
367 " [flat|smooth|wire|wireOnSurface|points] []\n"
368 " -frameAll set the view to frame all root prims on the stage\n"
369 " -clipPlane clipPlane1 ... clipPlane4\n"
370 " set an additional camera clipping plane [()]\n"
371 " -complexities complexities1 complexities2 ...\n"
372 " One or more complexities, each complexity will\n"
373 " produce an image [()]\n"
374 " -times times1 times2 ...\n"
375 " One or more time samples, each time will produce\n"
376 " an image [()]\n"
377 " -cullStyle Set face cull style\n"
378 " -clear r g b a clear color\n"
379 " -clearOnce Clear the framebuffer only once at the start \n"
380 " instead of before each render.\n"
381 " -translate x y z default camera translation\n"
382 " -rendererAov name Name of AOV to display or write out\n"
383 " -perfStatsFile path Path to file performance stats are written to\n"
384 " -traceFile path Path to trace file to write\n"
385 " -renderSetting name type value\n"
386 " Specifies a setting with given name, type (such as\n"
387 " float) and value passed to renderer. -renderSetting\n"
388 " can be given multiple times to specify different\n"
389 " settings\n"
390 " -guidesPurpose [show|hide]\n"
391 " force prims of purpose 'guide' to be shown or hidden\n"
392 " -renderPurpose [show|hide]\n"
393 " force prims of purpose 'render' to be shown or hidden\n"
394 " -proxyPurpose [show|hide]\n"
395 " force prims of purpose 'proxy' to be shown or hidden\n"
396 " -widgetSize w h width and height of widget and render buffers\n"
397 " -pixelAspectRatio a\n"
398 " width of pixel divided by height of pixel\n"
399 " -dataWindow x y width height\n"
400 " Specifies data window for rendering\n"
401 " -displayWindow x y width height\n"
402 " Specifies display window for rendering\n"
403 ;
404
405 Die(usage, TfGetBaseName(argv[0]).c_str());
406 }
407
CheckForMissingArguments(int i,int n,int argc,char * argv[])408 static void CheckForMissingArguments(int i, int n, int argc, char *argv[])
409 {
410 if (i + n >= argc) {
411 if (n == 1) {
412 ParseError(argv[0], "missing parameter for '%s'", argv[i]);
413 }
414 else {
415 ParseError(argv[0], "argument '%s' requires %d values", argv[i], n);
416 }
417 }
418 }
419
ParseDouble(int & i,int argc,char * argv[],bool * invalid=nullptr)420 static double ParseDouble(int& i, int argc, char *argv[],
421 bool* invalid = nullptr)
422 {
423 if (i + 1 == argc) {
424 if (invalid) {
425 *invalid = true;
426 return 0.0;
427 }
428 ParseError(argv[0], "missing parameter for '%s'", argv[i]);
429 }
430 char* end;
431 double result = strtod(argv[i + 1], &end);
432 if (end == argv[i + 1] || *end != '\0') {
433 if (invalid) {
434 *invalid = true;
435 return 0.0;
436 }
437 ParseError(argv[0], "invalid parameter for '%s': %s",
438 argv[i], argv[i + 1]);
439 }
440 ++i;
441 if (invalid) {
442 *invalid = false;
443 }
444 return result;
445 }
446
ParseShowHide(int & i,int argc,char * argv[],bool * result)447 static bool ParseShowHide(int& i, int argc, char *argv[],
448 bool* result)
449 {
450 if (i + 1 == argc) {
451 ParseError(argv[0], "missing parameter for '%s'", argv[i]);
452 return false;
453 }
454 if (strcmp(argv[i + 1], "show") == 0) {
455 *result = true;
456 } else if (strcmp(argv[i + 1], "hide") == 0) {
457 *result = false;
458 } else {
459 ParseError(argv[0], "invalid parameter for '%s': %s. Must be either "
460 "'show' or 'hide'",
461 argv[i], argv[i + 1]);
462 return false;
463 }
464
465 ++i;
466 return true;
467 }
468
ParseString(int & i,int argc,char * argv[],bool * invalid=nullptr)469 static const char * ParseString(int &i, int argc, char *argv[],
470 bool* invalid = nullptr)
471 {
472 if (i + 1 == argc) {
473 if (invalid) {
474 *invalid = true;
475 return nullptr;
476 }
477 ParseError(argv[0], "missing parameter for '%s'", argv[i]);
478 }
479 const char * const result = argv[i + 1];
480 ++i;
481 if (invalid) {
482 *invalid = false;
483 }
484 return result;
485 }
486
487 static void
ParseDoubleVector(int & i,int argc,char * argv[],std::vector<double> * result)488 ParseDoubleVector(
489 int& i, int argc, char *argv[],
490 std::vector<double>* result)
491 {
492 bool invalid = false;
493 while (i != argc) {
494 const double value = ParseDouble(i, argc, argv, &invalid);
495 if (invalid) {
496 break;
497 }
498 result->push_back(value);
499 }
500 }
501
ParseVtValue(int & i,int argc,char * argv[])502 static VtValue ParseVtValue(int &i, int argc, char *argv[])
503 {
504 const char * const typeString = ParseString(i, argc, argv);
505
506 if (strcmp(typeString, "float") == 0) {
507 CheckForMissingArguments(i, 1, argc, argv);
508 return VtValue(float(ParseDouble(i, argc, argv)));
509 } else {
510 ParseError(argv[0], "unknown type '%s'", typeString);
511 return VtValue();
512 }
513 }
514
515 void
_Parse(int argc,char * argv[],_Args * args)516 UsdImagingGL_UnitTestGLDrawing::_Parse(int argc, char *argv[], _Args* args)
517 {
518 for (int i = 1; i != argc; ++i) {
519 if (strcmp(argv[i], "-") == 0) {
520 Usage(argc, argv);
521 }
522 else if (strcmp(argv[i], "-frameAll") == 0) {
523 _shouldFrameAll = true;
524 }
525 else if (strcmp(argv[i], "-cullStyle") == 0) {
526 CheckForMissingArguments(i, 1, argc, argv);
527 args->cullStyle = argv[++i];
528 }
529 else if (strcmp(argv[i], "-offscreen") == 0) {
530 args->offscreen = true;
531 }
532 else if (strcmp(argv[i], "-lighting") == 0) {
533 _testLighting = true;
534 }
535 else if (strcmp(argv[i], "-sceneLights") == 0) {
536 _sceneLights = true;
537 }
538 else if (strcmp(argv[i], "-camlight") == 0) {
539 _cameraLight = true;
540 }
541 else if (strcmp(argv[i], "-camera") == 0) {
542 CheckForMissingArguments(i, 1, argc, argv);
543 _cameraPath = argv[++i];
544 }
545 else if (strcmp(argv[i], "-idRender") == 0) {
546 _testIdRender = true;
547 }
548 else if (strcmp(argv[i], "-disableSceneMaterials") == 0) {
549 _enableSceneMaterials = false;
550 }
551 else if (strcmp(argv[i], "-stage") == 0) {
552 CheckForMissingArguments(i, 1, argc, argv);
553 args->unresolvedStageFilePath = argv[++i];
554 }
555 else if (strcmp(argv[i], "-write") == 0) {
556 CheckForMissingArguments(i, 1, argc, argv);
557 _outputFilePath = argv[++i];
558 }
559 else if (strcmp(argv[i], "-shading") == 0) {
560 CheckForMissingArguments(i, 1, argc, argv);
561 args->shading = argv[++i];
562 }
563 else if (strcmp(argv[i], "-complexity") == 0) {
564 CheckForMissingArguments(i, 1, argc, argv);
565 _complexity = ParseDouble(i, argc, argv);
566 }
567 else if (strcmp(argv[i], "-renderer") == 0) {
568 CheckForMissingArguments(i, 1, argc, argv);
569 _renderer = TfToken(argv[++i]);
570 }
571 else if (strcmp(argv[i], "-rendererAov") == 0) {
572 CheckForMissingArguments(i, 1, argc, argv);
573 _rendererAov = TfToken(argv[++i]);
574 }
575 else if (strcmp(argv[i], "-perfStatsFile") == 0) {
576 CheckForMissingArguments(i, 1, argc, argv);
577 _perfStatsFile = argv[++i];
578 }
579 else if (strcmp(argv[i], "-traceFile") == 0) {
580 CheckForMissingArguments(i, 1, argc, argv);
581 _traceFile = argv[++i];
582 }
583 else if (strcmp(argv[i], "-clipPlane") == 0) {
584 CheckForMissingArguments(i, 4, argc, argv);
585 args->clipPlaneCoords.push_back(ParseDouble(i, argc, argv));
586 args->clipPlaneCoords.push_back(ParseDouble(i, argc, argv));
587 args->clipPlaneCoords.push_back(ParseDouble(i, argc, argv));
588 args->clipPlaneCoords.push_back(ParseDouble(i, argc, argv));
589 }
590 else if (strcmp(argv[i], "-complexities") == 0) {
591 ParseDoubleVector(i, argc, argv, &args->complexities);
592 }
593 else if (strcmp(argv[i], "-times") == 0) {
594 ParseDoubleVector(i, argc, argv, &_times);
595 }
596 else if (strcmp(argv[i], "-clear") == 0) {
597 CheckForMissingArguments(i, 4, argc, argv);
598 args->clearColor[0] = (float)ParseDouble(i, argc, argv);
599 args->clearColor[1] = (float)ParseDouble(i, argc, argv);
600 args->clearColor[2] = (float)ParseDouble(i, argc, argv);
601 args->clearColor[3] = (float)ParseDouble(i, argc, argv);
602 }
603 else if (strcmp(argv[i], "-translate") == 0) {
604 CheckForMissingArguments(i, 3, argc, argv);
605 args->translate[0] = (float)ParseDouble(i, argc, argv);
606 args->translate[1] = (float)ParseDouble(i, argc, argv);
607 args->translate[2] = (float)ParseDouble(i, argc, argv);
608 }
609 else if (strcmp(argv[i], "-widgetSize") == 0) {
610 CheckForMissingArguments(i, 2, argc, argv);
611 args->widgetSize[0] = (int)ParseDouble(i, argc, argv);
612 args->widgetSize[1] = (int)ParseDouble(i, argc, argv);
613 }
614 else if (strcmp(argv[i], "-pixelAspectRatio") == 0) {
615 CheckForMissingArguments(i, 1, argc, argv);
616 args->pixelAspectRatio = (float)ParseDouble(i, argc, argv);
617 }
618 else if (strcmp(argv[i], "-dataWindow") == 0) {
619 CheckForMissingArguments(i, 4, argc, argv);
620 args->dataWindow[0] = (int)ParseDouble(i, argc, argv);
621 args->dataWindow[1] = (int)ParseDouble(i, argc, argv);
622 args->dataWindow[2] = (int)ParseDouble(i, argc, argv);
623 args->dataWindow[3] = (int)ParseDouble(i, argc, argv);
624 }
625 else if (strcmp(argv[i], "-displayWindow") == 0) {
626 CheckForMissingArguments(i, 4, argc, argv);
627 args->displayWindow[0] = (float)ParseDouble(i, argc, argv);
628 args->displayWindow[1] = (float)ParseDouble(i, argc, argv);
629 args->displayWindow[2] = (float)ParseDouble(i, argc, argv);
630 args->displayWindow[3] = (float)ParseDouble(i, argc, argv);
631 }
632 else if (strcmp(argv[i], "-renderSetting") == 0) {
633 CheckForMissingArguments(i, 2, argc, argv);
634 const char * const key = ParseString(i, argc, argv);
635 _renderSettings[key] = ParseVtValue(i, argc, argv);
636 }
637 else if (strcmp(argv[i], "-guidesPurpose") == 0) {
638 ParseShowHide(i, argc, argv, &_showGuides);
639 }
640 else if (strcmp(argv[i], "-renderPurpose") == 0) {
641 ParseShowHide(i, argc, argv, &_showRender);
642 }
643 else if (strcmp(argv[i], "-proxyPurpose") == 0) {
644 ParseShowHide(i, argc, argv, &_showProxy);
645 }
646 else if (strcmp(argv[i], "-clearOnce") == 0) {
647 _clearOnce = true;
648 }
649 else if (strcmp(argv[i], "-presentDisabled") == 0) {
650 _presentDisabled = true;
651 }
652 else {
653 ParseError(argv[0], "unknown argument %s", argv[i]);
654 }
655 }
656 }
657
658 /* virtual */
659 void
MousePress(int button,int x,int y,int modKeys)660 UsdImagingGL_UnitTestGLDrawing::MousePress(int button, int x, int y,
661 int modKeys)
662 {
663 }
664 /* virtual */
665 void
MouseRelease(int button,int x,int y,int modKeys)666 UsdImagingGL_UnitTestGLDrawing::MouseRelease(int button, int x, int y,
667 int modKeys)
668 {
669 }
670 /* virtual */
671 void
MouseMove(int x,int y,int modKeys)672 UsdImagingGL_UnitTestGLDrawing::MouseMove(int x, int y, int modKeys)
673 {
674 }
675 /* virtual */
676 void
KeyRelease(int key)677 UsdImagingGL_UnitTestGLDrawing::KeyRelease(int key)
678 {
679 }
680
681 void
RunTest(int argc,char * argv[])682 UsdImagingGL_UnitTestGLDrawing::RunTest(int argc, char *argv[])
683 {
684 _Args args;
685 _Parse(argc, argv, &args);
686
687 if (!_traceFile.empty()) {
688 TraceCollector::GetInstance().SetEnabled(true);
689 }
690
691 UsdImagingGL_UnitTestHelper_InitPlugins();
692
693 for (size_t i=0; i<args.clipPlaneCoords.size()/4; ++i) {
694 _clipPlanes.push_back(GfVec4d(&args.clipPlaneCoords[i*4]));
695 }
696 _clearColor = GfVec4f(args.clearColor);
697 _translate = GfVec3f(args.translate);
698 _pixelAspectRatio = args.pixelAspectRatio;
699 _displayWindow = GfRange2f(
700 GfVec2f(args.displayWindow[0],
701 args.displayWindow[1]),
702 GfVec2f(args.displayWindow[0] + args.displayWindow[2],
703 args.displayWindow[1] + args.displayWindow[3]));
704 _dataWindow = GfRect2i(
705 GfVec2i(args.dataWindow[0], args.dataWindow[1]),
706 args.dataWindow[2], args.dataWindow[3]);
707
708 _drawMode = UsdImagingGLDrawMode::DRAW_SHADED_SMOOTH;
709
710 if (args.shading.compare("wireOnSurface") == 0) {
711 _drawMode = UsdImagingGLDrawMode::DRAW_WIREFRAME_ON_SURFACE;
712 } else if (args.shading.compare("flat") == 0 ) {
713 _drawMode = UsdImagingGLDrawMode::DRAW_SHADED_FLAT;
714 } else if (args.shading.compare("wire") == 0 ) {
715 _drawMode = UsdImagingGLDrawMode::DRAW_WIREFRAME;
716 } else if (args.shading.compare("points") == 0 ) {
717 _drawMode = UsdImagingGLDrawMode::DRAW_POINTS;
718 } else {
719 TF_WARN("Draw mode %s not supported!", args.shading.c_str());
720 }
721
722 _cullStyle = UsdImagingGLCullStyle::CULL_STYLE_NOTHING;
723
724 if (args.cullStyle.compare("back") == 0) {
725 _cullStyle = UsdImagingGLCullStyle::CULL_STYLE_BACK;
726 } else if (args.cullStyle.compare("backUnlessDoubleSided") == 0 ) {
727 _cullStyle = UsdImagingGLCullStyle::CULL_STYLE_BACK_UNLESS_DOUBLE_SIDED;
728 } else if (args.cullStyle.compare("front") == 0 ) {
729 _cullStyle = UsdImagingGLCullStyle::CULL_STYLE_FRONT;
730 } else {
731 TF_WARN("Cull style %s not supported!", args.cullStyle.c_str());
732 }
733
734 if (!args.unresolvedStageFilePath.empty()) {
735 _stageFilePath = args.unresolvedStageFilePath;
736 }
737
738 _widget = new UsdImagingGL_UnitTestWindow(
739 this, args.widgetSize[0], args.widgetSize[1]);
740 _widget->Init();
741
742 if (_times.empty()) {
743 _times.push_back(-999);
744 }
745
746 if (args.complexities.size() > 0) {
747 std::string imageFilePath = GetOutputFilePath();
748
749 TF_FOR_ALL(compIt, args.complexities) {
750 _complexity = *compIt;
751 if (!imageFilePath.empty()) {
752 std::stringstream suffix;
753 suffix << "_" << _complexity << ".png";
754 _outputFilePath = TfStringReplace(imageFilePath, ".png", suffix.str());
755 }
756
757 _widget->DrawOffscreen();
758 }
759
760 } else if (args.offscreen) {
761 _widget->DrawOffscreen();
762 } else {
763 _widget->Run();
764 }
765
766 if(!_traceFile.empty()) {
767 TraceCollector::GetInstance().SetEnabled(false);
768
769 {
770 std::ofstream traceOutFile(_traceFile);
771 if (TF_VERIFY(traceOutFile)) {
772 TraceReporter::GetGlobalReporter()->Report(traceOutFile);
773 }
774 }
775
776 TraceCollector::GetInstance().Clear();
777 TraceReporter::GetGlobalReporter()->ClearTree();
778 }
779 }
780
781 PXR_NAMESPACE_CLOSE_SCOPE
782
783