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.
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.
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_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...
bool is_of_type(TypeHandle handle) const
Returns true if the current object is or derives from the indicated type.
void remove_all_viewers()
Removes all viewers from the imager.
PandaNode * node() const
Returns the referenced node of the path.
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_dark_room() const
Returns the NodePath to the root of the dark room scene.
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.
NodePath get_viewer_camera(int index) const
Returns the NodePath to the LensNode that is to serve as nth viewer for this screen.
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.
int find_screen(const NodePath &screen) const
Returns the index number of the first appearance of the indicated screen within the imager's list...
This class object combines the rendered output of a 3-d from one or more linear (e.g.
int get_num_screens() const
Returns the number of screens that have been added to the imager.
GraphicsOutput * get_window() const
Returns the GraphicsOutput that this DisplayRegion is ultimately associated with, or NULL if no windo...
void add(AsyncTask *task)
Adds the indicated task to the active queue.
int add_viewer(DisplayRegion *dr)
Adds the indicated DisplayRegion as a viewer into the NonlinearImager room.
GraphicsEngine * get_graphics_engine() const
Returns the GraphicsEngine that all of the viewers added to the NonlinearImager have in common...
bool get_screen_active(int index) const
Returns the active flag on the indicated screen.
int add_screen(ProjectionScreen *screen)
This version of this method is deprecated and will soon be removed.
GraphicsStateGuardian * get_gsg() const
Returns the GSG that is associated with this window.
Associates a generic C-style function pointer with an AsyncTask object.
A ProjectionScreen implements a simple system for projective texturing.
This is a base class for the various different classes that represent the result of a frame of render...
GraphicsOutput * get_buffer(int index) const
Returns the offscreen buffer that is automatically created for the nth projection screen...
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.
int get_num_viewers() const
Returns the number of viewers that have been added to the imager.
GraphicsOutput * make_texture_buffer(const string &name, int x_size, int y_size, Texture *tex=NULL, bool to_ram=false, FrameBufferProperties *fbp=NULL)
Creates and returns an offscreen buffer for rendering into, the result of which will be a texture sui...
Encapsulates all the communication with a particular instance of a given rendering backend...
bool is_empty() const
Returns true if the NodePath contains no nodes.
void remove_viewer(int index)
Removes the viewer with the indicated index number from the imager.
A rectangular subregion within a window for rendering into.
GraphicsEngine * get_engine() const
Returns the graphics engine that created this GSG.
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 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.
DisplayRegion * get_viewer(int index) const
Returns the nth viewer's DisplayRegion that has been added to the imager.
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 ...
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...
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 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...
NodePath is the fundamental system for disambiguating instances, and also provides a higher-level int...
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...