Panda3D
Loading...
Searching...
No Matches
config_display.cxx
Go to the documentation of this file.
1/**
2 * PANDA 3D SOFTWARE
3 * Copyright (c) Carnegie Mellon University. All rights reserved.
4 *
5 * All use of this software is subject to the terms of the revised BSD
6 * license. You should have received a copy of this license along
7 * with this source code in a file named "LICENSE."
8 *
9 * @file config_display.cxx
10 * @author drose
11 * @date 1999-10-06
12 */
13
14#include "config_display.h"
16#include "displayRegion.h"
19#include "standardMunger.h"
21#include "graphicsPipe.h"
22#include "graphicsOutput.h"
23#include "graphicsBuffer.h"
24#include "graphicsDevice.h"
25#include "graphicsWindow.h"
28#include "mouseAndKeyboard.h"
29#include "nativeWindowHandle.h"
30#include "parasiteBuffer.h"
31#include "pandaSystem.h"
32#include "stereoDisplayRegion.h"
33#include "subprocessWindow.h"
34#include "windowHandle.h"
35
36#if !defined(CPPPARSER) && !defined(LINK_ALL_STATIC) && !defined(BUILDING_PANDA_DISPLAY)
37 #error Buildsystem error: BUILDING_PANDA_DISPLAY not defined
38#endif
39
40ConfigureDef(config_display);
41NotifyCategoryDef(display, "");
42NotifyCategoryDef(gsg, display_cat);
43
44ConfigureFn(config_display) {
46}
47
48ConfigVariableBool view_frustum_cull
49("view-frustum-cull", true,
50 PRC_DESC("This is normally true; set it false to disable view-frustum culling "
51 "(primarily useful for debugging)."));
52
53ConfigVariableBool pstats_unused_states
54("pstats-unused-states", false,
55 PRC_DESC("Set this true to show the number of unused states in the pstats "
56 "graph for TransformState and RenderState counts. This adds a bit "
57 "of per-frame overhead to count these things up."));
58
59
60// Warning! The code that uses this is currently experimental and incomplete,
61// and will almost certainly crash! Do not set threading-model to anything
62// other than its default of a single-threaded model unless you are developing
63// Panda's threading system!
64ConfigVariableString threading_model
65("threading-model", "",
66 PRC_DESC("This is the default threading model to use for new windows. Use "
67 "empty string for single-threaded, or something like \"cull/draw\" for "
68 "a 3-stage pipeline. See GraphicsEngine::set_threading_model(). "
69 "EXPERIMENTAL and incomplete, do not use this!"));
70
71ConfigVariableBool allow_nonpipeline_threads
72("allow-nonpipeline-threads", false,
73 PRC_DESC("This variable should only be set true for debugging or development "
74 "purposes. When true, the threading-model variable may specify "
75 "a threaded pipeline mode, even if pipelining is not compiled in. "
76 "This will certainly result in erroneous behavior, and quite likely "
77 "will cause a crash. Do not set this unless you know what you "
78 "are doing."));
79
80ConfigVariableBool auto_flip
81("auto-flip", false,
82 PRC_DESC("This indicates the initial setting of the auto-flip flag. Set it "
83 "true to cause render_frame() to flip all the windows "
84 "before it returns (in single-threaded mode only), or false to wait "
85 "until an explicit call to flip_frame() or the next "
86 "render_frame(). Setting it true gets more immediate response "
87 "time, while setting it false can get a better frame rate as more "
88 "is achieved in parallel with the graphics card."));
89
90ConfigVariableBool sync_flip
91("sync-flip", false,
92 PRC_DESC("Set this true to attempt to flip all windows at the same time, "
93 "or false to flip each window as late as possible. Setting this "
94 "false can improve parallelization. This is a temporary "
95 "variable; it will later be replaced with a more explicit control "
96 "over synchronizing window flip."));
97
98ConfigVariableBool yield_timeslice
99("yield-timeslice", false,
100 PRC_DESC("Set this true to yield the timeslice at the end of the frame to be "
101 "more polite to other applications that are trying to run."));
102
103ConfigVariableDouble subprocess_window_max_wait
104("subprocess-window-max-wait", 0.2,
105 PRC_DESC("This is the amount of time, in seconds, that the SubprocessWindow will "
106 "wait in begin_flip for the parent process to remove the previously-rendered "
107 "frame. When this time is exceeded, the next frame will be rendered without "
108 "having flipped the previous one. This is designed to allow the Python "
109 "process some time to run even when the parent window is offscreen or minimized."));
110
111ConfigVariableString screenshot_filename
112("screenshot-filename", "%~p-%a-%b-%d-%H-%M-%S-%Y-%~f.%~e",
113 PRC_DESC("This specifies the filename pattern to be used to generate "
114 "screenshots captured via save_screenshot_default(). See "
115 "DisplayRegion::save_screenshot()."));
116
117ConfigVariableString screenshot_extension
118("screenshot-extension", "jpg",
119 PRC_DESC("This specifies the default filename extension (and therefore the "
120 "default image type) to be used for saving screenshots."));
121
122ConfigVariableBool prefer_texture_buffer
123("prefer-texture-buffer", true,
124 PRC_DESC("Set this true to make GraphicsOutput::make_texture_buffer() always "
125 "try to create an offscreen buffer supporting render-to-texture, "
126 "if the graphics card claims to be able to support this feature. "
127 "If the graphics card cannot support this feature, this option is "
128 "ignored. This is usually the fastest way to render "
129 "to a texture, and it presumably does not consume any additional "
130 "framebuffer memory over a copy-to-texture operation (since "
131 "the texture and the buffer share the "
132 "same memory)."));
133
134ConfigVariableBool prefer_parasite_buffer
135("prefer-parasite-buffer", false,
136 PRC_DESC("Set this true to make GraphicsOutput::make_texture_buffer() try to "
137 "create a ParasiteBuffer before it tries to create an offscreen "
138 "buffer (assuming it could not create a direct render buffer for "
139 "some reason). This may reduce your graphics card memory "
140 "requirements by sharing memory with the framebuffer, but it can "
141 "cause problems if the user subsequently resizes the window "
142 "smaller than the buffer."));
143
144ConfigVariableBool force_parasite_buffer
145("force-parasite-buffer", false,
146 PRC_DESC("Set this true to make GraphicsOutput::make_texture_buffer() really "
147 "strongly prefer ParasiteBuffers over conventional offscreen buffers. "
148 "With this set, it will create a ParasiteBuffer every time an offscreen "
149 "buffer is requested, even if this means reducing the buffer size to fit "
150 "within the window. The only exceptions are for buffers that, by their "
151 "nature, really cannot use ParasiteBuffers (like depth textures). You might "
152 "set this true if you don't trust your graphics driver's support for "
153 "offscreen buffers."));
154
155ConfigVariableBool prefer_single_buffer
156("prefer-single-buffer", true,
157 PRC_DESC("Set this true to make GraphicsOutput::make_render_texture() first "
158 "try to create a single-buffered offscreen buffer, before falling "
159 "back to a double-buffered one (or whatever kind the source window "
160 "has). This is true by default to reduce waste of framebuffer "
161 "memory, but you might get a performance benefit by setting it to "
162 "false (since in that case the buffer can share a graphics context "
163 "with the window)."));
164
165ConfigVariableInt max_texture_stages
166("max-texture-stages", -1,
167 PRC_DESC("Set this to a positive integer to limit the number of "
168 "texture stages reported by the GSG. This can be used to limit "
169 "the amount of multitexturing Panda will attempt to use. "
170 "If this is zero or less, the GSG will report its honest number "
171 "of texture stages, allowing Panda the full use of the graphics "
172 "card; if it is 1 or more, then Panda will never allow more than "
173 "this number of texture stages simultaneously, regardless of "
174 "what the GSG says it can do."));
175
176ConfigVariableInt max_color_targets
177("max-color-targets", -1,
178 PRC_DESC("Set this to a positive integer to limit the number of "
179 "color targets reported by the GSG. This can be used to limit "
180 "the amount of render targets Panda will attempt to use. "
181 "If this is zero or less, the GSG will report its honest number "
182 "of color targets, allowing Panda the full use of the graphics "
183 "card; if it is 1 or more, then Panda will never allow more than "
184 "this number of color targets simultaneously, regardless of "
185 "what the GSG says it can do."));
186
187ConfigVariableBool support_render_texture
188("support-render-texture", true,
189 PRC_DESC("Set this true allow use of the render-to-a-texture feature, if it "
190 "is supported by your graphics card. Without this enabled, "
191 "offscreen renders will be copied to a texture instead of directly "
192 "rendered there."));
193
194ConfigVariableBool support_rescale_normal
195("support-rescale-normal", true,
196 PRC_DESC("Set this true to allow use of the rescale-normal feature, if it "
197 "is supported by your graphics card. This allows lighting normals "
198 "to be uniformly counter-scaled, instead of re-normalized, "
199 "in the presence of a uniform scale, which should in principle be "
200 "a bit faster. This feature is only supported "
201 "by the OpenGL API."));
202
203ConfigVariableBool support_stencil
204("support-stencil", true,
205 PRC_DESC("Set this true to allow use of the stencil buffer, if it "
206 "is supported by your graphics card. If this is false, stencil "
207 "buffer support will not be enabled, even if it is supported. "
208 "Generally, only very old cards do not support some kind of "
209 "stencil buffer operations; but it is also not supported by "
210 "our tinydisplay renderer. "
211 "The main reason to set this false is to test your code in "
212 "the absence of stencil buffer support."));
213
214ConfigVariableBool copy_texture_inverted
215("copy-texture-inverted", false,
216 PRC_DESC("Set this true to indicate that the GSG in use will invert textures when "
217 "it performs a framebuffer-to-texture copy operation, or false to indicate "
218 "that it does the right thing. If this is not set, the default behavior is "
219 "determined by the GSG's internal logic."));
220
221ConfigVariableBool window_inverted
222("window-inverted", false,
223 PRC_DESC("Set this true to create all windows with the inverted flag set, so that "
224 "they will render upside-down and backwards. Normally this is useful only "
225 "for debugging."));
226
227ConfigVariableBool red_blue_stereo
228("red-blue-stereo", false,
229 PRC_DESC("Set this true to create windows with red-blue stereo mode enabled "
230 "by default, if the framebuffer does not support true stereo "
231 "rendering."));
232
233ConfigVariableString red_blue_stereo_colors
234("red-blue-stereo-colors", "red cyan",
235 PRC_DESC("This defines the color channels that are used for the left and "
236 "right eye, respectively, for red-blue-stereo mode. This should "
237 "be a two-word string, where each word is one of 'red', 'blue', "
238 "'green', 'cyan', 'magenta', 'yellow', or 'alpha', or a union "
239 "of two or more words separated by a vertical pipe (|)."));
240
241ConfigVariableBool side_by_side_stereo
242("side-by-side-stereo", false,
243 PRC_DESC("Set this true to create windows with side-by-side stereo mode enabled "
244 "by default, if the framebuffer does not support true stereo "
245 "rendering."));
246
247ConfigVariableDouble sbs_left_dimensions
248("sbs-left-dimensions", "0.0 0.5 0.0 1.0",
249 PRC_DESC("Defines the default region of the window that is used for the "
250 "left eye, when side-by-side stereo is enabled. This is a set of "
251 "four numbers, in the form left right top bottom, similar to a "
252 "normal DisplayRegion layout."));
253
254ConfigVariableDouble sbs_right_dimensions
255("sbs-right-dimensions", "0.5 1.0 0.0 1.0",
256 PRC_DESC("Defines the default region of the window that is used for the "
257 "right eye, when side-by-side stereo is enabled. This is a set of "
258 "four numbers, in the form left right top bottom, similar to a "
259 "normal DisplayRegion layout."));
260
261ConfigVariableBool swap_eyes
262("swap-eyes", false,
263 PRC_DESC("Set this true to reverse the left and right channel output of "
264 "stereo DisplayRegions."));
265
266ConfigVariableBool default_stereo_camera
267("default-stereo-camera", true,
268 PRC_DESC("When this is true, the default DisplayRegion created for "
269 "a window or buffer with the stereo property will be a "
270 "StereoDisplayRegion, which activates the stereo properties of "
271 "the camera lens, and enables stereo. Set this false to "
272 "require StereoDisplayRegions to be created explicitly."));
273
274ConfigVariableBool color_scale_via_lighting
275("color-scale-via-lighting", true,
276 PRC_DESC("When this is true, Panda will try to implement ColorAttribs and "
277 "ColorScaleAttribs using the lighting interface, by "
278 "creating a default material and/or an ambient light if "
279 "necessary, even if lighting is ostensibly disabled. This "
280 "avoids the need to munge the vertex data to change each vertex's "
281 "color. Set this false to avoid this trickery, so that lighting "
282 "is only enabled when the application specifically enables "
283 "it. See also alpha-scale-via-texture."));
284
285ConfigVariableBool alpha_scale_via_texture
286("alpha-scale-via-texture", true,
287 PRC_DESC("When this is true, Panda will try to implement "
288 "ColorScaleAttribs that affect alpha by "
289 "creating an additional Texture layer over the geometry "
290 "with a uniform alpha scale applied everywhere, if there "
291 "is at least one available Texture slot available on the "
292 "multitexture pipeline. Set this false to avoid this "
293 "trickery, so that texturing is only enabled when the "
294 "application specifically enables it. See also "
295 "color-scale-via-lighting."));
296
297ConfigVariableBool allow_incomplete_render
298("allow-incomplete-render", true,
299 PRC_DESC("When this is true, the frame may be rendered even if some of the "
300 "geometry in the scene has been paged out, or if the textures are "
301 "unavailable. The nonresident geometry and textures will be "
302 "rendered as soon as they can be read from disk, "
303 "which may be several frames in the future. When this is false, "
304 "geometry is always paged in immediately when needed, holding up "
305 "the frame render if necessary."));
306
307ConfigVariableBool old_alpha_blend
308("old-alpha-blend", false,
309 PRC_DESC("Set this to true to enable the old alpha blending behavior from "
310 "Panda 1.9 in which the alpha value written out to the framebuffer "
311 "is squared. The new behavior is more intuitive when compositing "
312 "an semitransparent image produced using render-to-texture. You "
313 "should generally leave this false unless you have an effect that "
314 "relies on the old behavior, or you suspect an implementation bug."));
315
316ConfigVariableInt win_size
317("win-size", "800 600",
318 PRC_DESC("This is the default size at which to open a new window. This "
319 "replaces the deprecated win-width and win-height variables."));
320
321ConfigVariableInt win_origin
322("win-origin", "",
323 PRC_DESC("This is the default position at which to open a new window. This "
324 "replaces the deprecated win-origin-x and win-origin-y variables. "
325 "A window coordinate of -1 means to choose a default value, "
326 "whereas -2 means to center the window on the screen."));
327
328ConfigVariableBool fullscreen
329("fullscreen", false);
330
331ConfigVariableBool undecorated
332("undecorated", false,
333 PRC_DESC("This specifies the default value of the 'undecorated' window "
334 "property. When this is true, the default window is created "
335 "without a title bar or resizable border."));
336
337ConfigVariableBool win_fixed_size
338("win-fixed-size", false,
339 PRC_DESC("This specifies the default value of the 'fixed_size' window "
340 "property. When this is true, the default window is created "
341 "without a resizable border."));
342
343ConfigVariableBool cursor_hidden
344("cursor-hidden", false);
345
346ConfigVariableFilename icon_filename
347("icon-filename", "");
348
349ConfigVariableFilename cursor_filename
350("cursor-filename", "");
351
353("z-order", WindowProperties::Z_normal);
354
355ConfigVariableString window_title
356("window-title", "Panda");
357
358ConfigVariableInt parent_window_handle
359("parent-window-handle", 0,
360 PRC_DESC("The window handle of the parent window to attach the Panda window "
361 "to, for the purposes of creating an embedded window. This is "
362 "an HWND on Windows, or the NSWindow pointer or XWindow pointer "
363 "converted to an integer, on OSX and X11."));
364
365ConfigVariableBool win_unexposed_draw
366("win-unexposed-draw", true,
367 PRC_DESC("Specifies the default setting of GraphicsWindow::set_unexposed_draw(). "
368 "See that method for more information."));
369
370ConfigVariableFilename subprocess_window
371("subprocess-window", "",
372 PRC_DESC("The filename of a SubprocessWindowBuffer's temporary mmap file, "
373 "used for opening a window in a child process and rendering "
374 "to a different window in the parent process. "
375 "This is specifically used for OSX when the plugin is compiled, "
376 "and is not used or needed in other environments. See "
377 "WindowProperties::set_subprocess_window()."));
378
379ConfigVariableString framebuffer_mode
380("framebuffer-mode", "",
381 PRC_DESC("No longer has any effect. Do not use."));
382
383ConfigVariableBool framebuffer_hardware
384("framebuffer-hardware", true,
385 PRC_DESC("True if FM_hardware should be added to the default framebuffer "
386 "properties, which requests a hardware-accelerated display."));
387ConfigVariableBool framebuffer_software
388("framebuffer-software", false,
389 PRC_DESC("True if FM_software should be added to the default framebuffer "
390 "properties, which requests a software-only display."));
391ConfigVariableBool framebuffer_multisample
392("framebuffer-multisample", false,
393 PRC_DESC("True if FM_multisample should be added to the default framebuffer "
394 "properties, which requests a multisample-capable display, if "
395 "possible. This can be used to implement full-screen "
396 "antialiasing."));
397ConfigVariableBool framebuffer_depth
398("framebuffer-depth", true,
399 PRC_DESC("True if FM_depth should be added to the default framebuffer "
400 "properties, which requests a depth buffer."));
401ConfigVariableBool framebuffer_alpha
402("framebuffer-alpha", true,
403 PRC_DESC("True if FM_alpha should be added to the default framebuffer "
404 "properties, which requests an alpha channel if possible."));
405ConfigVariableBool framebuffer_stencil
406("framebuffer-stencil", false,
407 PRC_DESC("True if FM_stencil should be added to the default framebuffer "
408 "properties, which requests an stencil buffer if possible."));
409ConfigVariableBool framebuffer_accum
410("framebuffer-accum", false,
411 PRC_DESC("True if FM_accum should be added to the default framebuffer "
412 "properties, which requests an accumulator buffer if possible."));
413ConfigVariableBool framebuffer_stereo
414("framebuffer-stereo", false,
415 PRC_DESC("True if FM_stereo should be added to the default framebuffer "
416 "properties, which requests a stereo-capable display, if "
417 "supported by the graphics driver."));
418ConfigVariableBool framebuffer_srgb
419("framebuffer-srgb", false,
420 PRC_DESC("Set this to request an sRGB framebuffer, which will "
421 "convert all values to linear space before blending. This "
422 "means that the output will be properly gamma-corrected, as "
423 "long as all the input textures are either converted from "
424 "original sRGB to linear or sRGB textures are used."));
425ConfigVariableBool framebuffer_float
426("framebuffer-float", false,
427 PRC_DESC("Set this to request a framebuffer that uses floating-point "
428 "storage for the color channel."));
429
430ConfigVariableInt depth_bits
431("depth-bits", 0,
432 PRC_DESC("The minimum number of depth buffer bits requested."));
433ConfigVariableInt color_bits
434("color-bits", "",
435 PRC_DESC("The minimum number of total color buffer bits requested. If you "
436 "specify only one value, it will represent the total value for the "
437 "red, green and blue channels, and indicates you don't care how the "
438 "bits are divided up among the red, green and blue channels. If "
439 "you specify three values, it represents three separate red, green "
440 "and blue bit requirements."));
441ConfigVariableInt alpha_bits
442("alpha-bits", 0,
443 PRC_DESC("The minimum number of alpha buffer bits requested."));
444ConfigVariableInt stencil_bits
445("stencil-bits", 0,
446 PRC_DESC("The minimum number of stencil buffer bits requested."));
447ConfigVariableInt accum_bits
448("accum-bits", 0,
449 PRC_DESC("The minimum number of accumulator buffer bits requested."));
450ConfigVariableInt multisamples
451("multisamples", 0,
452 PRC_DESC("The minimum number of samples requested."));
453ConfigVariableInt back_buffers
454("back-buffers", 1,
455 PRC_DESC("The default number of back buffers requested."));
456
457ConfigVariableDouble pixel_zoom
458("pixel-zoom", 1.0,
459 PRC_DESC("The default pixel_zoom factor for new windows."));
460
461ConfigVariableInt shadow_depth_bits
462("shadow-depth-bits", 24,
463 PRC_DESC("The minimum number of depth buffer bits requested when rendering "
464 "shadow maps. Set this to 32 for more depth resolution in shadow "
465 "maps."));
466ConfigVariableBool shadow_cube_map_filter
467("shadow-cube-map-filter", false,
468 PRC_DESC("If true, Panda enables hardware depth map comparison mode for "
469 "point lights, if supported. If false, does not. Keep this set to "
470 "false if you want the shader generator to work correctly for point "
471 "light shadows."));
472
473ConfigVariableColor background_color
474("background-color", "0.41 0.41 0.41 0.0",
475 PRC_DESC("Specifies the rgb(a) value of the default background color for a "
476 "new window or offscreen buffer."));
477
478ConfigVariableBool sync_video
479("sync-video", true,
480 PRC_DESC("Configure this true to request the rendering to sync to the video "
481 "refresh, or false to let your frame rate go as high as it can, "
482 "irrespective of the video refresh. Usually you want this true, "
483 "but it may be useful to set it false during development for a "
484 "cheesy estimate of scene complexity. Some drivers may ignore "
485 "this request."));
486
487ConfigVariableDouble display_zoom
488("display-zoom", 0.0,
489 PRC_DESC("If this is set to a value other than 0.0, it overrides the detected "
490 "system DPI scaling. GraphicsPipe::get_display_zoom() will instead "
491 "return whatever was passed in here. You should generally only "
492 "change this based on a user preference change or to test how the UI "
493 "will look on monitors with different pixel densities."));
494
495/**
496 * Initializes the library. This must be called at least once before any of
497 * the functions or classes in this library can be used. Normally it will be
498 * called by the static initializers and need not be called explicitly, but
499 * special cases exist.
500 */
501void
503 static bool initialized = false;
504 if (initialized) {
505 return;
506 }
507 initialized = true;
508
509 CallbackGraphicsWindow::init_type();
510 DisplayRegion::init_type();
511 DisplayRegionCullCallbackData::init_type();
512 DisplayRegionDrawCallbackData::init_type();
513 DisplayRegionPipelineReader::init_type();
514 GraphicsBuffer::init_type();
515 GraphicsDevice::init_type();
516 GraphicsOutput::init_type();
517 GraphicsPipe::init_type();
518 GraphicsStateGuardian::init_type();
519 GraphicsWindow::init_type();
520 GraphicsWindowInputDevice::init_type();
521 GraphicsWindowProcCallbackData::init_type();
522 MouseAndKeyboard::init_type();
523 NativeWindowHandle::init_type();
524 ParasiteBuffer::init_type();
525 StandardMunger::init_type();
526 StereoDisplayRegion::init_type();
527#ifdef SUPPORT_SUBPROCESS_WINDOW
528 SubprocessWindow::init_type();
529#endif
530 WindowHandle::init_type();
531 WindowHandle::OSHandle::init_type();
532
533#if defined(HAVE_THREADS) && defined(DO_PIPELINING)
535 ps->add_system("pipelining");
536#endif
537}
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
This is a convenience class to specialize ConfigVariable as a boolean type.
This is a convenience class to specialize ConfigVariable as a set of floating-point types representin...
This is a convenience class to specialize ConfigVariable as a floating- point type.
This class specializes ConfigVariable as an enumerated type.
This is a convenience class to specialize ConfigVariable as a Filename type.
This is a convenience class to specialize ConfigVariable as an integer type.
This is a convenience class to specialize ConfigVariable as a string type.
This class is used as a namespace to group several global properties of Panda.
Definition pandaSystem.h:26
static PandaSystem * get_global_ptr()
Returns the global PandaSystem object.
void add_system(const std::string &system)
Intended for use by each subsystem to register itself at startup.
void init_libdisplay()
Initializes the library.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.