Panda3D
nonlinearImager.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 nonlinearImager.cxx
10  * @author drose
11  * @date 2001-12-12
12  */
13 
14 #include "nonlinearImager.h"
15 #include "config_distort.h"
16 
17 #include "graphicsStateGuardian.h"
18 #include "matrixLens.h"
19 #include "graphicsOutput.h"
20 #include "graphicsEngine.h"
21 #include "dcast.h"
22 #include "cPointerCallbackObject.h"
23 #include "asyncTaskManager.h"
24 #include "genericAsyncTask.h"
25 
26 /**
27  *
28  */
29 NonlinearImager::
30 NonlinearImager() {
31  _engine = nullptr;
32  _stale = true;
33 }
34 
35 /**
36  *
37  */
38 NonlinearImager::
39 ~NonlinearImager() {
42 
43  if (_recompute_task != nullptr) {
45  task_mgr->remove(_recompute_task);
46  }
47 }
48 
49 /**
50  * This version of this method is deprecated and will soon be removed. Use
51  * the version that takes two parameters instead.
52  *
53  * @deprecated Use the version that takes two parameters instead.
54  */
57  return add_screen(NodePath(screen), screen->get_name());
58 }
59 
60 /**
61  * Adds a new ProjectionScreen to the list of screens that will be processed
62  * by the NonlinearImager. Each ProjectionScreen represents a view into the
63  * world. It must be based on a linear camera (or whatever kind of camera is
64  * respected by the graphics engine).
65  *
66  * Each ProjectionScreen object should already have some screen geometry
67  * created.
68  *
69  * As each frame is rendered, an offscreen image will be rendered from the
70  * source camera associated with each ProjectionScreen, and the resulting
71  * image will be applied to the screen geometry.
72  *
73  * The return value is the index number of the new screen.
74  */
76 add_screen(const NodePath &screen, const std::string &name) {
77  nassertr(!screen.is_empty() &&
78  screen.node()->is_of_type(ProjectionScreen::get_class_type()), -1);
79 
80  ProjectionScreen *screen_node = DCAST(ProjectionScreen, screen.node());
81 
82  _screens.push_back(Screen());
83  Screen &new_screen = _screens.back();
84  new_screen._screen = screen;
85  new_screen._screen_node = screen_node;
86  new_screen._name = name;
87  new_screen._buffer = nullptr;
88  new_screen._tex_width = 256;
89  new_screen._tex_height = 256;
90  new_screen._active = true;
91 
92  // Slot a mesh for each viewer.
93  size_t vi;
94  for (vi = 0; vi < _viewers.size(); ++vi) {
95  new_screen._meshes.push_back(Mesh());
96  new_screen._meshes[vi]._last_screen = screen_node->get_last_screen();
97  }
98 
99  _stale = true;
100 
101  if (_dark_room.is_empty()) {
102  _dark_room = screen.get_top();
103  } else {
104  nassertr(_dark_room.is_same_graph(screen), _screens.size() - 1);
105  }
106 
107  return _screens.size() - 1;
108 }
109 
110 /**
111  * Returns the index number of the first appearance of the indicated screen
112  * within the imager's list, or -1 if it does not appear.
113  */
115 find_screen(const NodePath &screen) const {
116  for (size_t i = 0; i < _screens.size(); i++) {
117  if (_screens[i]._screen == screen) {
118  return i;
119  }
120  }
121 
122  return -1;
123 }
124 
125 /**
126  * Removes the screen with the indicated index number from the imager.
127  */
129 remove_screen(int index) {
130  nassertv_always(index >= 0 && index < (int)_screens.size());
131  Screen &screen = _screens[index];
132  for (size_t vi = 0; vi < screen._meshes.size(); vi++) {
133  screen._meshes[vi]._mesh.remove_node();
134  }
135  _screens.erase(_screens.begin() + index);
136 }
137 
138 /**
139  * Removes all screens from the imager.
140  */
143  while (!_screens.empty()) {
144  remove_screen(_screens.size() - 1);
145  }
146 }
147 
148 /**
149  * Returns the number of screens that have been added to the imager.
150  */
152 get_num_screens() const {
153  return _screens.size();
154 }
155 
156 /**
157  * Returns the nth screen that has been added to the imager.
158  */
160 get_screen(int index) const {
161  nassertr(index >= 0 && index < (int)_screens.size(), NodePath());
162  return _screens[index]._screen;
163 }
164 
165 /**
166  * Returns the offscreen buffer that is automatically created for the nth
167  * projection screen. This may return NULL if the screen is inactive or if it
168  * has not been rendered yet.
169  */
171 get_buffer(int index) const {
172  nassertr(index >= 0 && index < (int)_screens.size(), nullptr);
173  return _screens[index]._buffer;
174 }
175 
176 /**
177  * Sets the width and height of the texture used to render the scene for the
178  * indicated screen. This must be less than or equal to the window size, and
179  * it should be a power of two.
180  *
181  * In general, the larger the texture, the greater the detail of the rendered
182  * scene.
183  */
185 set_texture_size(int index, int width, int height) {
186  nassertv(index >= 0 && index < (int)_screens.size());
187 
188  Screen &screen = _screens[index];
189 
190  screen._tex_width = width;
191  screen._tex_height = height;
192 
193  if (screen._buffer != nullptr) {
194  bool removed = _engine->remove_window(screen._buffer);
195  screen._buffer = nullptr;
196  nassertv(removed);
197  }
198 
199  _stale = true;
200 }
201 
202 /**
203  * Specifies the camera that will be used to render the image for this
204  * particular screen.
205  *
206  * The parameter must be a NodePath whose node is a Camera. The camera itself
207  * indicates the scene that is to be rendered.
208  */
210 set_source_camera(int index, const NodePath &source_camera) {
211  nassertv(index >= 0 && index < (int)_screens.size());
212  nassertv(!source_camera.is_empty() &&
213  source_camera.node()->is_of_type(Camera::get_class_type()));
214  _screens[index]._source_camera = source_camera;
215 }
216 
217 /**
218  * Sets the active flag on the indicated screen. If the active flag is true,
219  * the screen will be used; otherwise, it will not appear.
220  */
222 set_screen_active(int index, bool active) {
223  nassertv(index >= 0 && index < (int)_screens.size());
224 
225  Screen &screen = _screens[index];
226  screen._active = active;
227 
228  if (!active) {
229  // If we've just made this screen inactive, remove its meshes.
230  for (size_t vi = 0; vi < screen._meshes.size(); vi++) {
231  screen._meshes[vi]._mesh.remove_node();
232  }
233 
234  // Also remove its buffer.
235  if (screen._buffer != nullptr) {
236  bool removed = _engine->remove_window(screen._buffer);
237  screen._buffer = nullptr;
238  nassertv(removed);
239  }
240 
241  // Hide the screen in the dark room. This doesn't really matter, since
242  // the dark room isn't normally rendered, but hide it anyway in case the
243  // user stuck a camera in there for fun.
244  screen._screen.hide();
245 
246  } else {
247  // If we've just made it active, it needs to be recomputed.
248  _stale = true;
249 
250  screen._screen.show();
251  }
252 }
253 
254 /**
255  * Returns the active flag on the indicated screen.
256  */
258 get_screen_active(int index) const {
259  nassertr(index >= 0 && index < (int)_screens.size(), false);
260  return _screens[index]._active;
261 }
262 
263 
264 /**
265  * Adds the indicated DisplayRegion as a viewer into the NonlinearImager room.
266  * The camera associated with the DisplayRegion at the time add_viewer() is
267  * called is used as the initial viewer camera; it may have a nonlinear lens,
268  * like a fisheye or cylindrical lens.
269  *
270  * This sets up a special scene graph for this DisplayRegion alone and sets up
271  * the DisplayRegion with a specialty camera. If future changes to the camera
272  * are desired, you should use the set_viewer_camera() interface.
273  *
274  * All viewers must share the same GraphicsEngine.
275  *
276  * The return value is the index of the new viewer.
277  */
280  GraphicsOutput *window = dr->get_window();
281  nassertr(window != nullptr, -1);
282 
283  GraphicsStateGuardian *gsg = window->get_gsg();
284  nassertr(gsg != nullptr, -1);
285 
286  GraphicsEngine *engine = gsg->get_engine();
287  nassertr(engine != nullptr, -1);
288 
289  nassertr(_viewers.empty() || (engine == _engine), -1);
290  if (_engine == nullptr) {
291  _engine = engine;
292  }
293 
294  if (_recompute_task == nullptr) {
295  _recompute_task =
296  new GenericAsyncTask("nli_recompute", recompute_callback, (void *)this);
298  task_mgr->add(_recompute_task);
299  }
300 
301  int previous_vi = find_viewer(dr);
302  if (previous_vi >= 0) {
303  return previous_vi;
304  }
305 
306  size_t vi = _viewers.size();
307  _viewers.push_back(Viewer());
308  Viewer &viewer = _viewers[vi];
309 
310  viewer._dr = dr;
311 
312  // Get the current camera off of the DisplayRegion, if any.
313  viewer._viewer = dr->get_camera();
314  if (viewer._viewer.is_empty()) {
315  viewer._viewer_node = nullptr;
316  } else {
317  viewer._viewer_node = DCAST(LensNode, viewer._viewer.node());
318  }
319 
320  // The internal camera is an identity-matrix camera that simply views the
321  // meshes that represent the user's specified camera.
322  viewer._internal_camera = new Camera("internal_camera");
323  viewer._internal_camera->set_lens(new MatrixLens);
324  viewer._internal_scene = NodePath("internal_screens");
325  viewer._internal_camera->set_scene(viewer._internal_scene);
326 
327  NodePath camera_np = viewer._internal_scene.attach_new_node(viewer._internal_camera);
328  viewer._dr->set_camera(camera_np);
329 
330  // Enable face culling on the wireframe mesh. This will help us to cull out
331  // invalid polygons that result from vertices crossing a singularity (for
332  // instance, at the back of a fisheye lens).
333  viewer._internal_scene.set_two_sided(0);
334 
335  // Finally, slot a new mesh for each screen.
336  Screens::iterator si;
337  for (si = _screens.begin(); si != _screens.end(); ++si) {
338  Screen &screen = (*si);
339  screen._meshes.push_back(Mesh());
340  nassertr(screen._meshes.size() == _viewers.size(), -1);
341  }
342 
343  _stale = true;
344 
345  if (_dark_room.is_empty()) {
346  _dark_room = viewer._viewer.get_top();
347  } else {
348  nassertr(_dark_room.is_same_graph(viewer._viewer), vi);
349  }
350 
351  return vi;
352 }
353 
354 /**
355  * Returns the index number of the indicated DisplayRegion within the list of
356  * viewers, or -1 if it is not found.
357  */
359 find_viewer(DisplayRegion *dr) const {
360  for (size_t vi = 0; vi < _viewers.size(); vi++) {
361  if (_viewers[vi]._dr == dr) {
362  return vi;
363  }
364  }
365 
366  return -1;
367 }
368 
369 /**
370  * Removes the viewer with the indicated index number from the imager.
371  */
373 remove_viewer(int index) {
374  nassertv_always(index >= 0 && index < (int)_viewers.size());
375  Viewer &viewer = _viewers[index];
376  viewer._internal_camera->set_scene(NodePath());
377  viewer._dr->set_camera(viewer._viewer);
378 
379  // Also remove the corresponding mesh from each screen.
380  Screens::iterator si;
381  for (si = _screens.begin(); si != _screens.end(); ++si) {
382  Screen &screen = (*si);
383  nassertv(index < (int)screen._meshes.size());
384  screen._meshes[index]._mesh.remove_node();
385  screen._meshes.erase(screen._meshes.begin() + index);
386  }
387 
388  _viewers.erase(_viewers.begin() + index);
389 }
390 
391 /**
392  * Removes all viewers from the imager.
393  */
396  while (!_viewers.empty()) {
397  remove_viewer(_viewers.size() - 1);
398  }
399 }
400 
401 /**
402  * Specifies the LensNode that is to serve as the viewer for this screen. The
403  * relative position of the LensNode to the NonlinearImager, as well as the
404  * properties of the lens associated with the LensNode, determines the UV's
405  * that will be assigned to the geometry within the NonlinearImager.
406  *
407  * It is not necessary to call this except to change the camera after a viewer
408  * has been added, since the default is to use whatever camera is associated
409  * with the DisplayRegion at the time the viewer is added.
410  *
411  * The NodePath must refer to a LensNode (or a Camera).
412  */
414 set_viewer_camera(int index, const NodePath &viewer_camera) {
415  nassertv(index >= 0 && index < (int)_viewers.size());
416  nassertv(!viewer_camera.is_empty() &&
417  viewer_camera.node()->is_of_type(LensNode::get_class_type()));
418  Viewer &viewer = _viewers[index];
419  viewer._viewer = viewer_camera;
420  viewer._viewer_node = DCAST(LensNode, viewer_camera.node());
421  _stale = true;
422 
423  if (_dark_room.is_empty()) {
424  _dark_room = viewer._viewer.get_top();
425  } else {
426  nassertv(_dark_room.is_same_graph(viewer._viewer));
427  }
428 }
429 
430 /**
431  * Returns the NodePath to the LensNode that is to serve as nth viewer for
432  * this screen.
433  */
435 get_viewer_camera(int index) const {
436  nassertr(index >= 0 && index < (int)_viewers.size(), NodePath());
437  return _viewers[index]._viewer;
438 }
439 
440 /**
441  * Returns a pointer to the root node of the internal scene graph for the nth
442  * viewer, which is used to render all of the screen meshes for this viewer.
443  *
444  * This is the scene graph in which the screen meshes within the dark room
445  * have been flattened into the appropriate transformation according to the
446  * viewer's lens properties (and position relative to the screens). It is
447  * this scene graph that is finally rendered to the window.
448  */
450 get_viewer_scene(int index) const {
451  nassertr(index >= 0 && index < (int)_viewers.size(), NodePath());
452  return _viewers[index]._internal_scene;
453 }
454 
455 /**
456  * Returns the number of viewers that have been added to the imager.
457  */
459 get_num_viewers() const {
460  return _viewers.size();
461 }
462 
463 /**
464  * Returns the nth viewer's DisplayRegion that has been added to the imager.
465  */
467 get_viewer(int index) const {
468  nassertr(index >= 0 && index < (int)_viewers.size(), nullptr);
469  return _viewers[index]._dr;
470 }
471 
472 /**
473  * Returns the NodePath to the root of the dark room scene. This is the scene
474  * in which all of the ProjectionScreens and the viewer cameras reside. It's
475  * a standalone scene with a few projection screens arranged artfully around
476  * one or more viewers; it's so named because it's a little virtual theater.
477  *
478  * Normally this scene is not rendered directly; it only exists as an abstract
479  * concept, and to define the relation between the ProjectionScreens and the
480  * viewers. But it may be rendered to help visualize the NonlinearImager's
481  * behavior.
482  */
484 get_dark_room() const {
485  return _dark_room;
486 }
487 
488 /**
489  * Returns the GraphicsEngine that all of the viewers added to the
490  * NonlinearImager have in common.
491  */
493 get_graphics_engine() const {
494  return _engine;
495 }
496 
497 /**
498  * Forces a regeneration of all the mesh objects, etc.
499  */
501 recompute() {
502  size_t vi;
503  for (vi = 0; vi < _viewers.size(); ++vi) {
504  Viewer &viewer = _viewers[vi];
505 
506  Screens::iterator si;
507  for (si = _screens.begin(); si != _screens.end(); ++si) {
508  Screen &screen = (*si);
509  if (screen._active) {
510  recompute_screen(screen, vi);
511  }
512  }
513 
514  if (viewer._viewer_node != nullptr &&
515  viewer._viewer_node->get_lens() != nullptr) {
516  viewer._viewer_lens_change =
517  viewer._viewer_node->get_lens()->get_last_change();
518  }
519  }
520 
521  _stale = false;
522 }
523 
524 /**
525  * This function is added as a task, to ensure that all frames are up-to-date.
526  */
527 AsyncTask::DoneStatus NonlinearImager::
528 recompute_callback(GenericAsyncTask *, void *data) {
529  NonlinearImager *self = (NonlinearImager *)data;
530  self->recompute_if_stale();
531  return AsyncTask::DS_cont;
532 }
533 
534 /**
535  * Calls recompute() if it needs to be called.
536  */
539  if (_stale) {
540  recompute();
541  } else {
542  size_t vi;
543  for (vi = 0; vi < _viewers.size(); ++vi) {
544  Viewer &viewer = _viewers[vi];
545  if (viewer._viewer_node != nullptr) {
546  UpdateSeq lens_change =
547  viewer._viewer_node->get_lens()->get_last_change();
548  if (lens_change != viewer._viewer_lens_change) {
549  // The viewer has changed, so we need to recompute all screens on
550  // this viewer.
551  Screens::iterator si;
552  for (si = _screens.begin(); si != _screens.end(); ++si) {
553  Screen &screen = (*si);
554  if (screen._active) {
555  recompute_screen(screen, vi);
556  }
557  }
558 
559  } else {
560  // We may not need to recompute all screens, but maybe some of them.
561  Screens::iterator si;
562  for (si = _screens.begin(); si != _screens.end(); ++si) {
563  Screen &screen = (*si);
564  if (screen._active &&
565  screen._meshes[vi]._last_screen != screen._screen_node->get_last_screen()) {
566  recompute_screen(screen, vi);
567  } else {
568  screen._screen_node->recompute_if_stale(screen._screen);
569  }
570  }
571  }
572  }
573  }
574  }
575 }
576 
577 /**
578  * Regenerates the mesh objects just for the indicated screen.
579  */
580 void NonlinearImager::
581 recompute_screen(NonlinearImager::Screen &screen, size_t vi) {
582  nassertv(vi < screen._meshes.size());
583  screen._meshes[vi]._mesh.remove_node();
584  if (!screen._active) {
585  return;
586  }
587 
588  screen._screen_node->recompute_if_stale(screen._screen);
589 
590  Viewer &viewer = _viewers[vi];
591  PT(PandaNode) mesh =
592  screen._screen_node->make_flat_mesh(screen._screen, viewer._viewer);
593  if (mesh != nullptr) {
594  screen._meshes[vi]._mesh = viewer._internal_scene.attach_new_node(mesh);
595  }
596 
597  if (screen._buffer == nullptr) {
598  GraphicsOutput *win = viewer._dr->get_window();
599  GraphicsOutput *buffer = win->make_texture_buffer
600  (screen._name, screen._tex_width, screen._tex_height, nullptr, false);
601 
602  if (buffer != nullptr) {
603  screen._buffer = buffer;
604  DisplayRegion *dr = buffer->make_display_region();
605  dr->set_camera(screen._source_camera);
606 
607  } else {
608  screen._meshes[vi]._mesh.clear_texture();
609  }
610  }
611 
612  if (screen._buffer != nullptr) {
613  screen._meshes[vi]._mesh.set_texture(screen._buffer->get_texture());
614 
615  // We don't really need to set the texture on the dark room screen, since
616  // that's normally not rendered, but we do anyway just for debugging
617  // purposes (in case the user does try to render it, to see what's going
618  // on).
619  screen._screen.set_texture(screen._buffer->get_texture());
620  }
621 
622  screen._meshes[vi]._last_screen = screen._screen_node->get_last_screen();
623 }
MatrixLens
A completely generic linear lens.
Definition: matrixLens.h:28
NonlinearImager::set_viewer_camera
void set_viewer_camera(int index, const NodePath &viewer_camera)
Specifies the LensNode that is to serve as the viewer for this screen.
Definition: nonlinearImager.cxx:414
NonlinearImager::remove_screen
void remove_screen(int index)
Removes the screen with the indicated index number from the imager.
Definition: nonlinearImager.cxx:129
NonlinearImager::recompute
void recompute()
Forces a regeneration of all the mesh objects, etc.
Definition: nonlinearImager.cxx:501
UpdateSeq
This is a sequence number that increments monotonically.
Definition: updateSeq.h:37
asyncTaskManager.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
AsyncTaskManager::get_global_ptr
static AsyncTaskManager * get_global_ptr()
Returns a pointer to the global AsyncTaskManager.
Definition: asyncTaskManager.I:50
NonlinearImager::remove_all_screens
void remove_all_screens()
Removes all screens from the imager.
Definition: nonlinearImager.cxx:142
NonlinearImager::remove_viewer
void remove_viewer(int index)
Removes the viewer with the indicated index number from the imager.
Definition: nonlinearImager.cxx:373
NonlinearImager::get_num_screens
get_num_screens
Returns the number of screens that have been added to the imager.
Definition: nonlinearImager.h:94
ProjectionScreen
A ProjectionScreen implements a simple system for projective texturing.
Definition: projectionScreen.h:48
Camera
A node that can be positioned around in the scene graph to represent a point of view for rendering a ...
Definition: camera.h:35
NonlinearImager::get_viewer_scene
NodePath get_viewer_scene(int index) const
Returns a pointer to the root node of the internal scene graph for the nth viewer,...
Definition: nonlinearImager.cxx:450
GenericAsyncTask
Associates a generic C-style function pointer with an AsyncTask object.
Definition: genericAsyncTask.h:26
dcast.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
NonlinearImager::get_screen_active
bool get_screen_active(int index) const
Returns the active flag on the indicated screen.
Definition: nonlinearImager.cxx:258
GraphicsStateGuardian::get_engine
GraphicsEngine * get_engine() const
Returns the graphics engine that created this GSG.
Definition: graphicsStateGuardian.cxx:318
graphicsEngine.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
DisplayRegion
A rectangular subregion within a window for rendering into.
Definition: displayRegion.h:57
NonlinearImager::find_viewer
int find_viewer(DisplayRegion *dr) const
Returns the index number of the indicated DisplayRegion within the list of viewers,...
Definition: nonlinearImager.cxx:359
GraphicsOutput::make_display_region
DisplayRegion * make_display_region()
Creates a new DisplayRegion that covers the entire window.
Definition: graphicsOutput.I:513
NonlinearImager::add_screen
int add_screen(ProjectionScreen *screen)
This version of this method is deprecated and will soon be removed.
Definition: nonlinearImager.cxx:56
nonlinearImager.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
GraphicsEngine
This class is the main interface to controlling the render process.
Definition: graphicsEngine.h:53
NonlinearImager::find_screen
int find_screen(const NodePath &screen) const
Returns the index number of the first appearance of the indicated screen within the imager's list,...
Definition: nonlinearImager.cxx:115
GraphicsOutput::get_gsg
get_gsg
Returns the GSG that is associated with this window.
Definition: graphicsOutput.h:117
ProjectionScreen::get_last_screen
const UpdateSeq & get_last_screen() const
Returns an UpdateSeq corresponding to the last time a screen mesh was generated for the ProjectionScr...
Definition: projectionScreen.I:229
NonlinearImager::set_screen_active
void set_screen_active(int index, bool active)
Sets the active flag on the indicated screen.
Definition: nonlinearImager.cxx:222
matrixLens.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
GraphicsOutput
This is a base class for the various different classes that represent the result of a frame of render...
Definition: graphicsOutput.h:63
NodePath::is_same_graph
bool is_same_graph(const NodePath &other, Thread *current_thread=Thread::get_current_thread()) const
Returns true if the node represented by this NodePath is parented within the same graph as that of th...
Definition: nodePath.I:275
AsyncTaskManager
A class to manage a loose queue of isolated tasks, which can be performed either synchronously (in th...
Definition: asyncTaskManager.h:48
AsyncTaskManager::add
void add(AsyncTask *task)
Adds the indicated task to the active queue.
Definition: asyncTaskManager.cxx:181
NodePath
NodePath is the fundamental system for disambiguating instances, and also provides a higher-level int...
Definition: nodePath.h:159
NodePath::get_top
NodePath get_top(Thread *current_thread=Thread::get_current_thread()) const
Returns a singleton NodePath that represents the top of the path, or empty NodePath if this path is e...
Definition: nodePath.cxx:209
LensNode
A node that contains a Lens.
Definition: lensNode.h:29
cPointerCallbackObject.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
NonlinearImager
This class object combines the rendered output of a 3-d from one or more linear (e....
Definition: nonlinearImager.h:81
DisplayRegion::set_camera
set_camera
Sets the camera that is associated with this DisplayRegion.
Definition: displayRegion.h:94
config_distort.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
NodePath::set_two_sided
void set_two_sided(bool two_sided, int priority=0)
Specifically sets or disables two-sided rendering mode on this particular node.
Definition: nodePath.cxx:4445
NonlinearImager::add_viewer
int add_viewer(DisplayRegion *dr)
Adds the indicated DisplayRegion as a viewer into the NonlinearImager room.
Definition: nonlinearImager.cxx:279
NonlinearImager::set_source_camera
void set_source_camera(int index, const NodePath &source_camera)
Specifies the camera that will be used to render the image for this particular screen.
Definition: nonlinearImager.cxx:210
DisplayRegion::get_camera
get_camera
Returns the camera associated with this DisplayRegion, or an empty NodePath if no camera is associate...
Definition: displayRegion.h:94
NodePath::attach_new_node
NodePath attach_new_node(PandaNode *node, int sort=0, Thread *current_thread=Thread::get_current_thread()) const
Attaches a new node, with or without existing parents, to the scene graph below the referenced node o...
Definition: nodePath.cxx:563
DisplayRegion::get_window
get_window
Returns the GraphicsOutput that this DisplayRegion is ultimately associated with, or NULL if no windo...
Definition: displayRegion.h:88
NonlinearImager::get_viewer
get_viewer
Returns the nth viewer's DisplayRegion that has been added to the imager.
Definition: nonlinearImager.h:115
GraphicsStateGuardian
Encapsulates all the communication with a particular instance of a given rendering backend.
Definition: graphicsStateGuardian.h:65
NonlinearImager::get_num_viewers
get_num_viewers
Returns the number of viewers that have been added to the imager.
Definition: nonlinearImager.h:115
PandaNode
A basic node of the scene graph or data graph.
Definition: pandaNode.h:65
genericAsyncTask.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
NodePath::node
PandaNode * node() const
Returns the referenced node of the path.
Definition: nodePath.I:227
AsyncTaskManager::remove
bool remove(AsyncTask *task)
Removes the indicated task from the active queue.
Definition: asyncTaskManager.cxx:311
NonlinearImager::get_graphics_engine
GraphicsEngine * get_graphics_engine() const
Returns the GraphicsEngine that all of the viewers added to the NonlinearImager have in common.
Definition: nonlinearImager.cxx:493
NonlinearImager::recompute_callback
static AsyncTask::DoneStatus recompute_callback(GenericAsyncTask *task, void *data)
This function is added as a task, to ensure that all frames are up-to-date.
Definition: nonlinearImager.cxx:528
NonlinearImager::get_buffer
get_buffer
Returns the offscreen buffer that is automatically created for the nth projection screen.
Definition: nonlinearImager.h:96
graphicsStateGuardian.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
graphicsOutput.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
NonlinearImager::get_viewer_camera
NodePath get_viewer_camera(int index) const
Returns the NodePath to the LensNode that is to serve as nth viewer for this screen.
Definition: nonlinearImager.cxx:435
TypedObject::is_of_type
bool is_of_type(TypeHandle handle) const
Returns true if the current object is or derives from the indicated type.
Definition: typedObject.I:28
NonlinearImager::get_dark_room
NodePath get_dark_room() const
Returns the NodePath to the root of the dark room scene.
Definition: nonlinearImager.cxx:484
NonlinearImager::set_texture_size
void set_texture_size(int index, int width, int height)
Sets the width and height of the texture used to render the scene for the indicated screen.
Definition: nonlinearImager.cxx:185
NonlinearImager::get_screen
get_screen
Returns the nth screen that has been added to the imager.
Definition: nonlinearImager.h:94
NodePath::is_empty
bool is_empty() const
Returns true if the NodePath contains no nodes.
Definition: nodePath.I:188
NonlinearImager::recompute_if_stale
void recompute_if_stale()
Calls recompute() if it needs to be called.
Definition: nonlinearImager.cxx:538
NonlinearImager::remove_all_viewers
void remove_all_viewers()
Removes all viewers from the imager.
Definition: nonlinearImager.cxx:395