43 if (_recompute_task !=
nullptr) {
45 task_mgr->
remove(_recompute_task);
76 screen.
node()->
is_of_type(ProjectionScreen::get_class_type()), -1);
80 _screens.push_back(Screen());
81 Screen &new_screen = _screens.back();
82 new_screen._screen = screen;
83 new_screen._screen_node = screen_node;
84 new_screen._name = name;
85 new_screen._buffer =
nullptr;
86 new_screen._tex_width = 256;
87 new_screen._tex_height = 256;
88 new_screen._active =
true;
92 for (vi = 0; vi < _viewers.size(); ++vi) {
93 new_screen._meshes.push_back(Mesh());
94 new_screen._meshes[vi]._last_screen = screen_node->get_last_screen();
102 nassertr(_dark_room.
is_same_graph(screen), _screens.size() - 1);
105 return _screens.size() - 1;
114 for (
size_t i = 0; i < _screens.size(); i++) {
115 if (_screens[i]._screen == screen) {
128 nassertv_always(index >= 0 && index < (
int)_screens.size());
129 Screen &screen = _screens[index];
130 for (
size_t vi = 0; vi < screen._meshes.size(); vi++) {
131 screen._meshes[vi]._mesh.remove_node();
133 _screens.erase(_screens.begin() + index);
141 while (!_screens.empty()) {
149 int NonlinearImager::
150 get_num_screens()
const {
151 return _screens.size();
159 nassertr(index >= 0 && index < (
int)_screens.size(),
NodePath());
160 return _screens[index]._screen;
170 nassertr(index >= 0 && index < (
int)_screens.size(),
nullptr);
171 return _screens[index]._buffer;
184 nassertv(index >= 0 && index < (
int)_screens.size());
186 Screen &screen = _screens[index];
188 screen._tex_width = width;
189 screen._tex_height = height;
191 if (screen._buffer !=
nullptr) {
192 bool removed = _engine->remove_window(screen._buffer);
193 screen._buffer =
nullptr;
209 nassertv(index >= 0 && index < (
int)_screens.size());
210 nassertv(!source_camera.
is_empty() &&
212 _screens[index]._source_camera = source_camera;
221 nassertv(index >= 0 && index < (
int)_screens.size());
223 Screen &screen = _screens[index];
224 screen._active = active;
228 for (
size_t vi = 0; vi < screen._meshes.size(); vi++) {
229 screen._meshes[vi]._mesh.remove_node();
233 if (screen._buffer !=
nullptr) {
234 bool removed = _engine->remove_window(screen._buffer);
235 screen._buffer =
nullptr;
242 screen._screen.hide();
248 screen._screen.show();
257 nassertr(index >= 0 && index < (
int)_screens.size(),
false);
258 return _screens[index]._active;
279 nassertr(window !=
nullptr, -1);
282 nassertr(gsg !=
nullptr, -1);
285 nassertr(engine !=
nullptr, -1);
287 nassertr(_viewers.empty() || (engine == _engine), -1);
288 if (_engine ==
nullptr) {
292 if (_recompute_task ==
nullptr) {
296 task_mgr->
add(_recompute_task);
300 if (previous_vi >= 0) {
304 size_t vi = _viewers.size();
305 _viewers.push_back(Viewer());
306 Viewer &viewer = _viewers[vi];
312 if (viewer._viewer.is_empty()) {
313 viewer._viewer_node =
nullptr;
315 viewer._viewer_node = DCAST(
LensNode, viewer._viewer.node());
320 viewer._internal_camera =
new Camera(
"internal_camera");
321 viewer._internal_camera->set_lens(
new MatrixLens);
322 viewer._internal_scene =
NodePath(
"internal_screens");
323 viewer._internal_camera->set_scene(viewer._internal_scene);
326 viewer._dr->set_camera(camera_np);
334 Screens::iterator si;
335 for (si = _screens.begin(); si != _screens.end(); ++si) {
336 Screen &screen = (*si);
337 screen._meshes.push_back(Mesh());
338 nassertr(screen._meshes.size() == _viewers.size(), -1);
344 _dark_room = viewer._viewer.
get_top();
358 for (
size_t vi = 0; vi < _viewers.size(); vi++) {
359 if (_viewers[vi]._dr == dr) {
372 nassertv_always(index >= 0 && index < (
int)_viewers.size());
373 Viewer &viewer = _viewers[index];
374 viewer._internal_camera->set_scene(
NodePath());
375 viewer._dr->set_camera(viewer._viewer);
378 Screens::iterator si;
379 for (si = _screens.begin(); si != _screens.end(); ++si) {
380 Screen &screen = (*si);
381 nassertv(index < (
int)screen._meshes.size());
382 screen._meshes[index]._mesh.remove_node();
383 screen._meshes.erase(screen._meshes.begin() + index);
386 _viewers.erase(_viewers.begin() + index);
394 while (!_viewers.empty()) {
413 nassertv(index >= 0 && index < (
int)_viewers.size());
414 nassertv(!viewer_camera.
is_empty() &&
416 Viewer &viewer = _viewers[index];
417 viewer._viewer = viewer_camera;
418 viewer._viewer_node = DCAST(
LensNode, viewer_camera.
node());
422 _dark_room = viewer._viewer.
get_top();
434 nassertr(index >= 0 && index < (
int)_viewers.size(),
NodePath());
435 return _viewers[index]._viewer;
449 nassertr(index >= 0 && index < (
int)_viewers.size(),
NodePath());
450 return _viewers[index]._internal_scene;
456 int NonlinearImager::
457 get_num_viewers()
const {
458 return _viewers.size();
466 nassertr(index >= 0 && index < (
int)_viewers.size(),
nullptr);
467 return _viewers[index]._dr;
501 for (vi = 0; vi < _viewers.size(); ++vi) {
502 Viewer &viewer = _viewers[vi];
504 Screens::iterator si;
505 for (si = _screens.begin(); si != _screens.end(); ++si) {
506 Screen &screen = (*si);
507 if (screen._active) {
508 recompute_screen(screen, vi);
512 if (viewer._viewer_node !=
nullptr &&
513 viewer._viewer_node->get_lens() !=
nullptr) {
514 viewer._viewer_lens_change =
515 viewer._viewer_node->get_lens()->get_last_change();
528 self->recompute_if_stale();
529 return AsyncTask::DS_cont;
541 for (vi = 0; vi < _viewers.size(); ++vi) {
542 Viewer &viewer = _viewers[vi];
543 if (viewer._viewer_node !=
nullptr) {
545 viewer._viewer_node->get_lens()->get_last_change();
546 if (lens_change != viewer._viewer_lens_change) {
549 Screens::iterator si;
550 for (si = _screens.begin(); si != _screens.end(); ++si) {
551 Screen &screen = (*si);
552 if (screen._active) {
553 recompute_screen(screen, vi);
559 Screens::iterator si;
560 for (si = _screens.begin(); si != _screens.end(); ++si) {
561 Screen &screen = (*si);
562 if (screen._active &&
563 screen._meshes[vi]._last_screen != screen._screen_node->get_last_screen()) {
564 recompute_screen(screen, vi);
566 screen._screen_node->recompute_if_stale(screen._screen);
578 void NonlinearImager::
579 recompute_screen(NonlinearImager::Screen &screen,
size_t vi) {
580 nassertv(vi < screen._meshes.size());
581 screen._meshes[vi]._mesh.remove_node();
582 if (!screen._active) {
586 screen._screen_node->recompute_if_stale(screen._screen);
588 Viewer &viewer = _viewers[vi];
590 screen._screen_node->make_flat_mesh(screen._screen, viewer._viewer);
591 if (mesh !=
nullptr) {
592 screen._meshes[vi]._mesh = viewer._internal_scene.attach_new_node(mesh);
595 if (screen._buffer ==
nullptr) {
598 (screen._name, screen._tex_width, screen._tex_height,
nullptr,
false);
600 if (buffer !=
nullptr) {
601 screen._buffer = buffer;
606 screen._meshes[vi]._mesh.clear_texture();
610 if (screen._buffer !=
nullptr) {
611 screen._meshes[vi]._mesh.set_texture(screen._buffer->get_texture());
617 screen._screen.set_texture(screen._buffer->get_texture());
620 screen._meshes[vi]._last_screen = screen._screen_node->get_last_screen();
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.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
A basic node of the scene graph or data graph.
get_screen
Returns the nth screen that has been added to the imager.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
bool remove(AsyncTask *task)
Removes the indicated task from the active queue.
bool get_screen_active(int index) const
Returns the active flag on the indicated screen.
A completely generic linear lens.
get_viewer
Returns the nth viewer's DisplayRegion that has been added to the imager.
void recompute()
Forces a regeneration of all the mesh objects, etc.
bool is_empty() const
Returns true if the NodePath contains no nodes.
A class to manage a loose queue of isolated tasks, which can be performed either synchronously (in th...
void remove_all_screens()
Removes all screens from the imager.
A node that contains a Lens.
void remove_all_viewers()
Removes all viewers from the imager.
int find_screen(const NodePath &screen) const
Returns the index number of the first appearance of the indicated screen within the imager's list,...
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.
void recompute_if_stale()
Calls recompute() if it needs to be called.
void set_viewer_camera(int index, const NodePath &viewer_camera)
Specifies the LensNode that is to serve as the viewer for this screen.
NodePath get_viewer_camera(int index) const
Returns the NodePath to the LensNode that is to serve as nth viewer for this screen.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
void set_screen_active(int index, bool active)
Sets the active flag on the indicated screen.
DisplayRegion * make_display_region()
Creates a new DisplayRegion that covers the entire window.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
GraphicsEngine * get_engine() const
Returns the graphics engine that created this GSG.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
This class object combines the rendered output of a 3-d from one or more linear (e....
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
void add(AsyncTask *task)
Adds the indicated task to the active queue.
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...
int add_viewer(DisplayRegion *dr)
Adds the indicated DisplayRegion as a viewer into the NonlinearImager room.
get_camera
Returns the camera associated with this DisplayRegion, or an empty NodePath if no camera is associate...
int add_screen(ProjectionScreen *screen)
This version of this method is deprecated and will soon be removed.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
Associates a generic C-style function pointer with an AsyncTask object.
A ProjectionScreen implements a simple system for projective texturing.
int find_viewer(DisplayRegion *dr) const
Returns the index number of the indicated DisplayRegion within the list of viewers,...
NodePath get_viewer_scene(int index) const
Returns a pointer to the root node of the internal scene graph for the nth viewer,...
This is a base class for the various different classes that represent the result of a frame of render...
NodePath get_dark_room() const
Returns the NodePath to the root of the dark room scene.
set_camera
Sets the camera that is associated with this DisplayRegion.
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...
void remove_screen(int index)
Removes the screen with the indicated index number from the imager.
PandaNode * node() const
Returns the referenced node of the path.
get_window
Returns the GraphicsOutput that this DisplayRegion is ultimately associated with, or NULL if no windo...
Encapsulates all the communication with a particular instance of a given rendering backend.
void remove_viewer(int index)
Removes the viewer with the indicated index number from the imager.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
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...
get_buffer
Returns the offscreen buffer that is automatically created for the nth projection screen.
A rectangular subregion within a window for rendering into.
bool is_of_type(TypeHandle handle) const
Returns true if the current object is or derives from the indicated type.
This class is the main interface to controlling the render process.
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.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
This is a sequence number that increments monotonically.
A node that can be positioned around in the scene graph to represent a point of view for rendering a ...
static AsyncTaskManager * get_global_ptr()
Returns a pointer to the global AsyncTaskManager.
void set_two_sided(bool two_sided, int priority=0)
Specifically sets or disables two-sided rendering mode on this particular node.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
get_gsg
Returns the GSG that is associated with this window.
NodePath is the fundamental system for disambiguating instances, and also provides a higher-level int...
GraphicsEngine * get_graphics_engine() const
Returns the GraphicsEngine that all of the viewers added to the NonlinearImager have in common.