15 #include "nonlinearImager.h" 16 #include "config_distort.h" 18 #include "graphicsStateGuardian.h" 19 #include "matrixLens.h" 20 #include "graphicsOutput.h" 21 #include "graphicsEngine.h" 23 #include "cPointerCallbackObject.h" 24 #include "asyncTaskManager.h" 25 #include "genericAsyncTask.h" 48 if (_recompute_task != (
AsyncTask *)NULL) {
50 task_mgr->
remove(_recompute_task);
89 screen.
node()->
is_of_type(ProjectionScreen::get_class_type()), -1);
93 _screens.push_back(Screen());
94 Screen &new_screen = _screens.back();
95 new_screen._screen = screen;
96 new_screen._screen_node = screen_node;
97 new_screen._name = name;
99 new_screen._tex_width = 256;
100 new_screen._tex_height = 256;
101 new_screen._active =
true;
105 for (vi = 0; vi < _viewers.size(); ++vi) {
106 new_screen._meshes.push_back(Mesh());
107 new_screen._meshes[vi]._last_screen = screen_node->get_last_screen();
115 nassertr(_dark_room.
is_same_graph(screen), _screens.size() - 1);
118 return _screens.size() - 1;
130 for (
size_t i = 0; i < _screens.size(); i++) {
131 if (_screens[i]._screen == screen) {
147 nassertv_always(index >= 0 && index < (
int)_screens.size());
148 Screen &screen = _screens[index];
149 for (
size_t vi = 0; vi < screen._meshes.size(); vi++) {
150 screen._meshes[vi]._mesh.remove_node();
152 _screens.erase(_screens.begin() + index);
162 while (!_screens.empty()) {
175 return _screens.size();
186 nassertr(index >= 0 && index < (
int)_screens.size(),
NodePath());
187 return _screens[index]._screen;
200 nassertr(index >= 0 && index < (
int)_screens.size(), (
GraphicsOutput *)NULL);
201 return _screens[index]._buffer;
217 nassertv(index >= 0 && index < (
int)_screens.size());
219 Screen &screen = _screens[index];
221 screen._tex_width = width;
222 screen._tex_height = height;
225 bool removed = _engine->remove_window(screen._buffer);
245 nassertv(index >= 0 && index < (
int)_screens.size());
246 nassertv(!source_camera.
is_empty() &&
248 _screens[index]._source_camera = source_camera;
260 nassertv(index >= 0 && index < (
int)_screens.size());
262 Screen &screen = _screens[index];
263 screen._active = active;
267 for (
size_t vi = 0; vi < screen._meshes.size(); vi++) {
268 screen._meshes[vi]._mesh.remove_node();
273 bool removed = _engine->remove_window(screen._buffer);
281 screen._screen.hide();
287 screen._screen.show();
298 nassertr(index >= 0 && index < (
int)_screens.size(),
false);
299 return _screens[index]._active;
333 nassertr(_viewers.empty() || (engine == _engine), -1);
338 if (_recompute_task == (
AsyncTask *)NULL) {
342 task_mgr->
add(_recompute_task);
346 if (previous_vi >= 0) {
350 size_t vi = _viewers.size();
351 _viewers.push_back(Viewer());
352 Viewer &viewer = _viewers[vi];
358 if (viewer._viewer.is_empty()) {
359 viewer._viewer_node = (
LensNode *)NULL;
361 viewer._viewer_node = DCAST(
LensNode, viewer._viewer.node());
366 viewer._internal_camera =
new Camera(
"internal_camera");
367 viewer._internal_camera->set_lens(
new MatrixLens);
368 viewer._internal_scene =
NodePath(
"internal_screens");
369 viewer._internal_camera->set_scene(viewer._internal_scene);
372 viewer._dr->set_camera(camera_np);
380 Screens::iterator si;
381 for (si = _screens.begin(); si != _screens.end(); ++si) {
382 Screen &screen = (*si);
383 screen._meshes.push_back(Mesh());
384 nassertr(screen._meshes.size() == _viewers.size(), -1);
390 _dark_room = viewer._viewer.
get_top();
407 for (
size_t vi = 0; vi < _viewers.size(); vi++) {
408 if (_viewers[vi]._dr == dr) {
424 nassertv_always(index >= 0 && index < (
int)_viewers.size());
425 Viewer &viewer = _viewers[index];
426 viewer._internal_camera->set_scene(
NodePath());
427 viewer._dr->set_camera(viewer._viewer);
430 Screens::iterator si;
431 for (si = _screens.begin(); si != _screens.end(); ++si) {
432 Screen &screen = (*si);
433 nassertv(index < (
int)screen._meshes.size());
434 screen._meshes[index]._mesh.remove_node();
435 screen._meshes.erase(screen._meshes.begin() + index);
438 _viewers.erase(_viewers.begin() + index);
448 while (!_viewers.empty()) {
472 nassertv(index >= 0 && index < (
int)_viewers.size());
473 nassertv(!viewer_camera.
is_empty() &&
475 Viewer &viewer = _viewers[index];
476 viewer._viewer = viewer_camera;
477 viewer._viewer_node = DCAST(
LensNode, viewer_camera.
node());
481 _dark_room = viewer._viewer.
get_top();
495 nassertr(index >= 0 && index < (
int)_viewers.size(),
NodePath());
496 return _viewers[index]._viewer;
515 nassertr(index >= 0 && index < (
int)_viewers.size(),
NodePath());
516 return _viewers[index]._internal_scene;
527 return _viewers.size();
538 nassertr(index >= 0 && index < (
int)_viewers.size(), (
DisplayRegion *)NULL);
539 return _viewers[index]._dr;
582 for (vi = 0; vi < _viewers.size(); ++vi) {
583 Viewer &viewer = _viewers[vi];
585 Screens::iterator si;
586 for (si = _screens.begin(); si != _screens.end(); ++si) {
587 Screen &screen = (*si);
588 if (screen._active) {
589 recompute_screen(screen, vi);
593 if (viewer._viewer_node != (
LensNode *)NULL &&
594 viewer._viewer_node->get_lens() != (
Lens *)NULL) {
595 viewer._viewer_lens_change =
596 viewer._viewer_node->get_lens()->get_last_change();
613 return AsyncTask::DS_cont;
627 for (vi = 0; vi < _viewers.size(); ++vi) {
628 Viewer &viewer = _viewers[vi];
629 if (viewer._viewer_node != (
LensNode *)NULL) {
631 viewer._viewer_node->get_lens()->get_last_change();
632 if (lens_change != viewer._viewer_lens_change) {
635 Screens::iterator si;
636 for (si = _screens.begin(); si != _screens.end(); ++si) {
637 Screen &screen = (*si);
638 if (screen._active) {
639 recompute_screen(screen, vi);
646 Screens::iterator si;
647 for (si = _screens.begin(); si != _screens.end(); ++si) {
648 Screen &screen = (*si);
649 if (screen._active &&
650 screen._meshes[vi]._last_screen != screen._screen_node->get_last_screen()) {
651 recompute_screen(screen, vi);
653 screen._screen_node->recompute_if_stale(screen._screen);
668 void NonlinearImager::
669 recompute_screen(NonlinearImager::Screen &screen,
size_t vi) {
670 nassertv(vi < screen._meshes.size());
671 screen._meshes[vi]._mesh.remove_node();
672 if (!screen._active) {
676 screen._screen_node->recompute_if_stale(screen._screen);
678 Viewer &viewer = _viewers[vi];
680 screen._screen_node->make_flat_mesh(screen._screen, viewer._viewer);
682 screen._meshes[vi]._mesh = viewer._internal_scene.attach_new_node(mesh);
688 (screen._name, screen._tex_width, screen._tex_height, NULL,
false);
691 screen._buffer = buffer;
696 screen._meshes[vi]._mesh.clear_texture();
701 screen._meshes[vi]._mesh.set_texture(screen._buffer->get_texture());
707 screen._screen.set_texture(screen._buffer->get_texture());
710 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...
NodePath get_screen(int index) const
Returns the nth screen that has been added to the imager.
A basic node of the scene graph or data graph.
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 base class for any number of different kinds of lenses, linear and otherwise.
A completely generic linear lens.
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.
NodePath get_camera(Thread *current_thread=Thread::get_current_thread()) const
Returns the camera associated with this DisplayRegion, or an empty NodePath if no camera is associate...
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...
GraphicsOutput * get_buffer(int index) const
Returns the offscreen buffer that is automatically created for the nth projection screen...
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.
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.
GraphicsOutput * get_window() const
Returns the GraphicsOutput that this DisplayRegion is ultimately associated with, or NULL if no windo...
GraphicsEngine * get_engine() const
Returns the graphics engine that created this GSG.
This class object combines the rendered output of a 3-d from one or more linear (e.g.
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.
DisplayRegion * get_viewer(int index) const
Returns the nth viewer's DisplayRegion that has been added to the imager.
int get_num_screens() const
Returns the number of screens that have been added to the imager.
int add_screen(ProjectionScreen *screen)
This version of this method is deprecated and will soon be removed.
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, or -1 if it is not found.
NodePath get_viewer_scene(int index) const
Returns a pointer to the root node of the internal scene graph for the nth viewer, which is used to render all of the screen meshes for this 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.
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.
This class represents a concrete task performed by an AsyncManager.
virtual void set_camera(const NodePath &camera)
Sets the camera that is associated with this DisplayRegion.
GraphicsStateGuardian * get_gsg() const
Returns the GSG that is associated with this window.
PandaNode * node() const
Returns the referenced node of the path.
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.
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...
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.
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 ...
int get_num_viewers() const
Returns the number of viewers that have been added to the imager.
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.
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...