mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-03 10:22:45 -04:00
add nonlinearImager
This commit is contained in:
parent
4a0b5d3d7e
commit
f030c6333f
@ -10,6 +10,7 @@
|
|||||||
config_distort.cxx config_distort.h \
|
config_distort.cxx config_distort.h \
|
||||||
cylindricalLens.cxx cylindricalLens.h cylindricalLens.I \
|
cylindricalLens.cxx cylindricalLens.h cylindricalLens.I \
|
||||||
fisheyeLens.cxx fisheyeLens.h fisheyeLens.I \
|
fisheyeLens.cxx fisheyeLens.h fisheyeLens.I \
|
||||||
|
nonlinearImager.cxx nonlinearImager.h nonlinearImager.I \
|
||||||
pSphereLens.cxx pSphereLens.h pSphereLens.I \
|
pSphereLens.cxx pSphereLens.h pSphereLens.I \
|
||||||
projectionScreen.cxx projectionScreen.h projectionScreen.I
|
projectionScreen.cxx projectionScreen.h projectionScreen.I
|
||||||
|
|
||||||
|
43
panda/src/distort/nonlinearImager.I
Normal file
43
panda/src/distort/nonlinearImager.I
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
// Filename: nonlinearImager.I
|
||||||
|
// Created by: drose (12Dec01)
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// PANDA 3D SOFTWARE
|
||||||
|
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
|
||||||
|
//
|
||||||
|
// All use of this software is subject to the terms of the Panda 3d
|
||||||
|
// Software license. You should have received a copy of this license
|
||||||
|
// along with this source code; you will also find a current copy of
|
||||||
|
// the license at http://www.panda3d.org/license.txt .
|
||||||
|
//
|
||||||
|
// To contact the maintainers of this program write to
|
||||||
|
// panda3d@yahoogroups.com .
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: NonlinearImager::set_camera
|
||||||
|
// Access: Published
|
||||||
|
// Description: Specifies the virtual camera that will be used to
|
||||||
|
// view the various ProjectionScreens. It should be in
|
||||||
|
// the same scene graph with the ProjectionScreens, to
|
||||||
|
// establish a relative coordinate system with them.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE void NonlinearImager::
|
||||||
|
set_camera(LensNode *camera) {
|
||||||
|
_camera = camera;
|
||||||
|
_stale = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: NonlinearImager::get_camera
|
||||||
|
// Access: Published
|
||||||
|
// Description: Returns the virtual camera that will be used to
|
||||||
|
// view the various ProjectionScreens.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE LensNode *NonlinearImager::
|
||||||
|
get_camera() const {
|
||||||
|
return _camera;
|
||||||
|
}
|
365
panda/src/distort/nonlinearImager.cxx
Normal file
365
panda/src/distort/nonlinearImager.cxx
Normal file
@ -0,0 +1,365 @@
|
|||||||
|
// Filename: nonlinearImager.cxx
|
||||||
|
// Created by: drose (12Dec01)
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// PANDA 3D SOFTWARE
|
||||||
|
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
|
||||||
|
//
|
||||||
|
// All use of this software is subject to the terms of the Panda 3d
|
||||||
|
// Software license. You should have received a copy of this license
|
||||||
|
// along with this source code; you will also find a current copy of
|
||||||
|
// the license at http://www.panda3d.org/license.txt .
|
||||||
|
//
|
||||||
|
// To contact the maintainers of this program write to
|
||||||
|
// panda3d@yahoogroups.com .
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#include "nonlinearImager.h"
|
||||||
|
#include "config_distort.h"
|
||||||
|
|
||||||
|
#include "graphicsStateGuardian.h"
|
||||||
|
#include "textureTransition.h"
|
||||||
|
#include "matrixLens.h"
|
||||||
|
#include "renderRelation.h"
|
||||||
|
#include "graphicsWindow.h"
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: NonlinearImager::Constructor
|
||||||
|
// Access: Published
|
||||||
|
// Description: The NonlinearImager is associated with a particular
|
||||||
|
// DisplayRegion when it is created. It will throw away
|
||||||
|
// whatever camera is currently associated with the
|
||||||
|
// DisplayRegion, and create a speciality camera for
|
||||||
|
// itself.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
NonlinearImager::
|
||||||
|
NonlinearImager(DisplayRegion *dr) {
|
||||||
|
_dr = dr;
|
||||||
|
|
||||||
|
_internal_camera = new Camera("NonlinearImager");
|
||||||
|
_internal_camera->set_lens(new MatrixLens);
|
||||||
|
_internal_scene = new NamedNode("NonlinearImager");
|
||||||
|
_internal_camera->set_scene(_internal_scene);
|
||||||
|
_dr->set_camera(_internal_camera);
|
||||||
|
|
||||||
|
_stale = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: NonlinearImager::Destructor
|
||||||
|
// Access: Published
|
||||||
|
// Description:
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
NonlinearImager::
|
||||||
|
~NonlinearImager() {
|
||||||
|
_internal_camera->set_scene((Node *)NULL);
|
||||||
|
_dr->set_camera((Camera *)NULL);
|
||||||
|
remove_all_screens();
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: NonlinearImager::add_screen
|
||||||
|
// Access: Published
|
||||||
|
// Description: Adds a new ProjectionScreen to the list of screens
|
||||||
|
// that will be processed by the NonlinearImager. Each
|
||||||
|
// ProjectionScreen represents a view into the world.
|
||||||
|
// It must be based on a linear camera (or whatever kind
|
||||||
|
// of camera is respected by the graphics engine).
|
||||||
|
//
|
||||||
|
// width and height indicate the size of the texture
|
||||||
|
// that will be created to render the scene for the
|
||||||
|
// screen. See set_size().
|
||||||
|
//
|
||||||
|
// Each ProjectionScreen object should already have some
|
||||||
|
// screen geometry created.
|
||||||
|
//
|
||||||
|
// When render() is called, the graphics state guardian
|
||||||
|
// will be used to render a scene for each
|
||||||
|
// ProjectionScreen object, and then each resulting
|
||||||
|
// image will be applied to a mesh to be rendered to the
|
||||||
|
// screen.
|
||||||
|
//
|
||||||
|
// The return value is the index number of the new
|
||||||
|
// screen.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
int NonlinearImager::
|
||||||
|
add_screen(ProjectionScreen *screen) {
|
||||||
|
_screens.push_back(Screen());
|
||||||
|
Screen &new_screen = _screens.back();
|
||||||
|
new_screen._screen = screen;
|
||||||
|
new_screen._mesh_arc = (NodeRelation *)NULL;
|
||||||
|
new_screen._texture = (Texture *)NULL;
|
||||||
|
new_screen._tex_width = 256;
|
||||||
|
new_screen._tex_height = 256;
|
||||||
|
|
||||||
|
// If the LensNode associated with the ProjectionScreen is an actual
|
||||||
|
// Camera, then it has a scene associated. Otherwise, the user will
|
||||||
|
// have to specify the scene later.
|
||||||
|
LensNode *projector = screen->get_projector();
|
||||||
|
if (projector->is_of_type(Camera::get_class_type())) {
|
||||||
|
Camera *camera = DCAST(Camera, projector);
|
||||||
|
new_screen._scene = camera->get_scene();
|
||||||
|
}
|
||||||
|
|
||||||
|
_stale = true;
|
||||||
|
return _screens.size() - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: NonlinearImager::find_screen
|
||||||
|
// Access: Published
|
||||||
|
// Description: Returns the index number of the first appearance of
|
||||||
|
// the indicated screen within the imager's list, or -1
|
||||||
|
// if it does not appear.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
int NonlinearImager::
|
||||||
|
find_screen(ProjectionScreen *screen) const {
|
||||||
|
for (size_t i = 0; i < _screens.size(); i++) {
|
||||||
|
if (_screens[i]._screen == screen) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: NonlinearImager::remove_screen
|
||||||
|
// Access: Published
|
||||||
|
// Description: Removes the screen with the indicated index number
|
||||||
|
// from the imager.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void NonlinearImager::
|
||||||
|
remove_screen(int index) {
|
||||||
|
nassertv_always(index >= 0 && index < (int)_screens.size());
|
||||||
|
Screen &screen = _screens[index];
|
||||||
|
if (screen._mesh_arc != (NodeRelation *)NULL) {
|
||||||
|
remove_arc(screen._mesh_arc);
|
||||||
|
}
|
||||||
|
_screens.erase(_screens.begin() + index);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: NonlinearImager::remove_all_screens
|
||||||
|
// Access: Published
|
||||||
|
// Description: Removes all screens from the imager.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void NonlinearImager::
|
||||||
|
remove_all_screens() {
|
||||||
|
Screens::iterator si;
|
||||||
|
for (si = _screens.begin(); si != _screens.end(); ++si) {
|
||||||
|
Screen &screen = (*si);
|
||||||
|
if (screen._mesh_arc != (NodeRelation *)NULL) {
|
||||||
|
remove_arc(screen._mesh_arc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_screens.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: NonlinearImager::get_num_screens
|
||||||
|
// Access: Published
|
||||||
|
// Description: Returns the number of screens that have been added to
|
||||||
|
// the imager.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
int NonlinearImager::
|
||||||
|
get_num_screens() const {
|
||||||
|
return _screens.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: NonlinearImager::get_screen
|
||||||
|
// Access: Published
|
||||||
|
// Description: Returns the nth screen that has been added to the
|
||||||
|
// imager.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
ProjectionScreen *NonlinearImager::
|
||||||
|
get_screen(int index) const {
|
||||||
|
nassertr(index >= 0 && index < (int)_screens.size(), (ProjectionScreen *)NULL);
|
||||||
|
return _screens[index]._screen;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: NonlinearImager::set_size
|
||||||
|
// Access: Published
|
||||||
|
// Description: Sets the width and height of the texture used to
|
||||||
|
// render the scene for the indicated screen. This must
|
||||||
|
// be less than or equal to the window size, and it
|
||||||
|
// should be a power of two.
|
||||||
|
//
|
||||||
|
// In general, the larger the texture, the greater the
|
||||||
|
// detail of the rendered scene.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void NonlinearImager::
|
||||||
|
set_size(int index, int width, int height) {
|
||||||
|
nassertv(index >= 0 && index < (int)_screens.size());
|
||||||
|
_screens[index]._tex_width = width;
|
||||||
|
_screens[index]._tex_height = height;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: NonlinearImager::set_source
|
||||||
|
// Access: Published
|
||||||
|
// Description: Specifies the camera and root of the scene that will
|
||||||
|
// be used to render the image for this particular
|
||||||
|
// screen.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void NonlinearImager::
|
||||||
|
set_source(int index, LensNode *source, Node *scene) {
|
||||||
|
nassertv(index >= 0 && index < (int)_screens.size());
|
||||||
|
_screens[index]._source = source;
|
||||||
|
_screens[index]._scene = scene;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: NonlinearImager::set_source
|
||||||
|
// Access: Published
|
||||||
|
// Description: Specifies the camera and root of the scene that will
|
||||||
|
// be used to render the image for this particular
|
||||||
|
// screen.
|
||||||
|
//
|
||||||
|
// Since this flavor accepts a Camera node, instead of
|
||||||
|
// just a LensNode, the scene is specified within the
|
||||||
|
// Camera itself.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void NonlinearImager::
|
||||||
|
set_source(int index, Camera *source) {
|
||||||
|
nassertv(index >= 0 && index < (int)_screens.size());
|
||||||
|
_screens[index]._source = source;
|
||||||
|
_screens[index]._scene = source->get_scene();
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: NonlinearImager::recompute
|
||||||
|
// Access: Published
|
||||||
|
// Description: Forces a regeneration of all the mesh objects, etc.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void NonlinearImager::
|
||||||
|
recompute() {
|
||||||
|
Screens::iterator si;
|
||||||
|
for (si = _screens.begin(); si != _screens.end(); ++si) {
|
||||||
|
recompute_screen(*si);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_camera != (LensNode *)NULL && _camera->get_lens() != (Lens *)NULL) {
|
||||||
|
_camera_lens_change = _camera->get_lens()->get_last_change();
|
||||||
|
}
|
||||||
|
_stale = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: NonlinearImager::render
|
||||||
|
// Access: Published
|
||||||
|
// Description: Uses the DisplayRegion's GSG to render a scene for
|
||||||
|
// each ProjectionScreen, and makes our DisplayRegion
|
||||||
|
// ready to render the combined results. This will
|
||||||
|
// destroy the contents of the frame buffer; it should
|
||||||
|
// be done before any of the actual frame has started
|
||||||
|
// rendering.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void NonlinearImager::
|
||||||
|
render() {
|
||||||
|
recompute_if_stale();
|
||||||
|
|
||||||
|
Screens::iterator si;
|
||||||
|
for (si = _screens.begin(); si != _screens.end(); ++si) {
|
||||||
|
render_screen(*si);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: NonlinearImager::recompute_if_stale
|
||||||
|
// Access: Private
|
||||||
|
// Description: Calls recompute() if it needs to be called.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void NonlinearImager::
|
||||||
|
recompute_if_stale() {
|
||||||
|
if (_camera != (LensNode *)NULL &&
|
||||||
|
_camera->get_lens() != (Lens *)NULL) {
|
||||||
|
UpdateSeq lens_change = _camera->get_lens()->get_last_change();
|
||||||
|
if (_stale || lens_change != _camera_lens_change) {
|
||||||
|
recompute();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: NonlinearImager::recompute_screen
|
||||||
|
// Access: Private
|
||||||
|
// Description: Regenerates the mesh objects just for the indicated
|
||||||
|
// screen.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void NonlinearImager::
|
||||||
|
recompute_screen(NonlinearImager::Screen &screen) {
|
||||||
|
if (screen._mesh_arc != (NodeRelation *)NULL) {
|
||||||
|
remove_arc(screen._mesh_arc);
|
||||||
|
screen._mesh_arc = (NodeRelation *)NULL;
|
||||||
|
}
|
||||||
|
screen._texture.clear();
|
||||||
|
if (_camera == (LensNode *)NULL) {
|
||||||
|
// Not much we can do without a camera.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
PT_Node mesh = screen._screen->make_flat_mesh(_camera);
|
||||||
|
screen._mesh_arc = new RenderRelation(_internal_scene, mesh);
|
||||||
|
|
||||||
|
PT(Texture) texture = new Texture;
|
||||||
|
texture->set_minfilter(Texture::FT_linear);
|
||||||
|
texture->set_magfilter(Texture::FT_linear);
|
||||||
|
texture->set_wrapu(Texture::WM_clamp);
|
||||||
|
texture->set_wrapv(Texture::WM_clamp);
|
||||||
|
texture->_pbuffer->set_xsize(screen._tex_width);
|
||||||
|
texture->_pbuffer->set_ysize(screen._tex_height);
|
||||||
|
|
||||||
|
screen._texture = texture;
|
||||||
|
screen._mesh_arc->set_transition(new TextureTransition(texture));
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: NonlinearImager::render_screen
|
||||||
|
// Access: Private
|
||||||
|
// Description: Renders the scene just for the indicated screen, into
|
||||||
|
// the screen's own texture.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void NonlinearImager::
|
||||||
|
render_screen(NonlinearImager::Screen &screen) {
|
||||||
|
if (screen._source == (LensNode *)NULL) {
|
||||||
|
distort_cat.error()
|
||||||
|
<< "No source lens specified for screen " << screen._screen->get_name()
|
||||||
|
<< "\n";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (screen._scene == (Node *)NULL) {
|
||||||
|
distort_cat.error()
|
||||||
|
<< "No scene specified for screen " << screen._screen->get_name()
|
||||||
|
<< "\n";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
GraphicsStateGuardian *gsg = _dr->get_window()->get_gsg();
|
||||||
|
|
||||||
|
// Make a display region of the proper size and clear it to prepare for
|
||||||
|
// rendering the scene.
|
||||||
|
PT(DisplayRegion) scratch_region =
|
||||||
|
gsg->get_window()->make_scratch_display_region(screen._tex_width, screen._tex_height);
|
||||||
|
gsg->clear(gsg->get_render_buffer(RenderBuffer::T_back |
|
||||||
|
RenderBuffer::T_depth),
|
||||||
|
scratch_region);
|
||||||
|
|
||||||
|
DisplayRegionStack old_dr = gsg->push_display_region(scratch_region);
|
||||||
|
gsg->prepare_display_region();
|
||||||
|
gsg->render_scene(screen._scene, screen._source);
|
||||||
|
|
||||||
|
// Copy the results of the render from the frame buffer into the
|
||||||
|
// screen's texture.
|
||||||
|
screen._texture->copy(gsg, scratch_region,
|
||||||
|
gsg->get_render_buffer(RenderBuffer::T_back));
|
||||||
|
|
||||||
|
// Restore the original display region.
|
||||||
|
gsg->pop_display_region(old_dr);
|
||||||
|
}
|
101
panda/src/distort/nonlinearImager.h
Normal file
101
panda/src/distort/nonlinearImager.h
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
// Filename: nonlinearImager.h
|
||||||
|
// Created by: drose (12Dec01)
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// PANDA 3D SOFTWARE
|
||||||
|
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
|
||||||
|
//
|
||||||
|
// All use of this software is subject to the terms of the Panda 3d
|
||||||
|
// Software license. You should have received a copy of this license
|
||||||
|
// along with this source code; you will also find a current copy of
|
||||||
|
// the license at http://www.panda3d.org/license.txt .
|
||||||
|
//
|
||||||
|
// To contact the maintainers of this program write to
|
||||||
|
// panda3d@yahoogroups.com .
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#ifndef NONLINEARIMAGER_H
|
||||||
|
#define NONLINEARIMAGER_H
|
||||||
|
|
||||||
|
#include "pandabase.h"
|
||||||
|
|
||||||
|
#include "projectionScreen.h"
|
||||||
|
#include "displayRegion.h"
|
||||||
|
#include "camera.h"
|
||||||
|
#include "texture.h"
|
||||||
|
#include "pvector.h"
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Class : NonlinearImager
|
||||||
|
// Description : This class object combines the rendered output of a
|
||||||
|
// 3-d from one or more linear cameras, as seen through
|
||||||
|
// a single, possibly non-linear camera.
|
||||||
|
//
|
||||||
|
// This can be used to generate real-time imagery of a
|
||||||
|
// 3-d scene using a nonlinear camera, for instance a
|
||||||
|
// fisheye camera, even though the 3-d graphics engine
|
||||||
|
// only supports linear cameras.
|
||||||
|
//
|
||||||
|
// The NonlinearImager collects together a number of
|
||||||
|
// ProjectionScreens, each of which has a standard,
|
||||||
|
// linear Camera. Each frame, the Imager renders each
|
||||||
|
// scene into a texture and then maps that texture onto
|
||||||
|
// a mesh which is presented to the graphics engine for
|
||||||
|
// rendering the final, non-linear output.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
class EXPCL_PANDAFX NonlinearImager {
|
||||||
|
PUBLISHED:
|
||||||
|
NonlinearImager(DisplayRegion *dr);
|
||||||
|
~NonlinearImager();
|
||||||
|
|
||||||
|
int add_screen(ProjectionScreen *screen);
|
||||||
|
int find_screen(ProjectionScreen *screen) const;
|
||||||
|
void remove_screen(int index);
|
||||||
|
void remove_all_screens();
|
||||||
|
|
||||||
|
int get_num_screens() const;
|
||||||
|
ProjectionScreen *get_screen(int index) const;
|
||||||
|
void set_size(int index, int width, int height);
|
||||||
|
void set_source(int index, LensNode *source, Node *scene);
|
||||||
|
void set_source(int index, Camera *source);
|
||||||
|
|
||||||
|
INLINE void set_camera(LensNode *camera);
|
||||||
|
INLINE LensNode *get_camera() const;
|
||||||
|
|
||||||
|
void recompute();
|
||||||
|
void render();
|
||||||
|
|
||||||
|
private:
|
||||||
|
class Screen {
|
||||||
|
public:
|
||||||
|
PT(ProjectionScreen) _screen;
|
||||||
|
NodeRelation *_mesh_arc;
|
||||||
|
PT(Texture) _texture;
|
||||||
|
PT(LensNode) _source;
|
||||||
|
PT_Node _scene;
|
||||||
|
int _tex_width, _tex_height;
|
||||||
|
};
|
||||||
|
|
||||||
|
void recompute_if_stale();
|
||||||
|
void recompute_screen(Screen &screen);
|
||||||
|
void render_screen(Screen &screen);
|
||||||
|
|
||||||
|
PT(DisplayRegion) _dr;
|
||||||
|
|
||||||
|
typedef pvector<Screen> Screens;
|
||||||
|
Screens _screens;
|
||||||
|
|
||||||
|
PT(LensNode) _camera;
|
||||||
|
|
||||||
|
PT(Camera) _internal_camera;
|
||||||
|
PT_Node _internal_scene;
|
||||||
|
|
||||||
|
bool _stale;
|
||||||
|
UpdateSeq _camera_lens_change;
|
||||||
|
};
|
||||||
|
|
||||||
|
#include "nonlinearImager.I"
|
||||||
|
|
||||||
|
#endif
|
@ -610,11 +610,17 @@ render_subgraph(RenderTraverser *traverser,
|
|||||||
|
|
||||||
// activate();
|
// activate();
|
||||||
|
|
||||||
|
Lens *lens = projnode->get_lens();
|
||||||
|
if (!lens->is_linear()) {
|
||||||
|
glgsg_cat.error()
|
||||||
|
<< "Cannot render with a nonlinear lens!\n";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
LensNode *old_camera = _current_camera;
|
LensNode *old_camera = _current_camera;
|
||||||
_current_camera = projnode;
|
_current_camera = projnode;
|
||||||
LMatrix4f old_projection_mat = _current_projection_mat;
|
LMatrix4f old_projection_mat = _current_projection_mat;
|
||||||
|
|
||||||
Lens *lens = projnode->get_lens();
|
|
||||||
const LMatrix4f &projection_mat = lens->get_projection_mat();
|
const LMatrix4f &projection_mat = lens->get_projection_mat();
|
||||||
|
|
||||||
// The projection matrix must always be right-handed Y-up, even if
|
// The projection matrix must always be right-handed Y-up, even if
|
||||||
@ -1998,6 +2004,7 @@ copy_texture(TextureContext *tc, const DisplayRegion *dr) {
|
|||||||
get_internal_image_format(pb->get_format()),
|
get_internal_image_format(pb->get_format()),
|
||||||
pb->get_xorg(), pb->get_yorg(),
|
pb->get_xorg(), pb->get_yorg(),
|
||||||
pb->get_xsize(), pb->get_ysize(), pb->get_border());
|
pb->get_xsize(), pb->get_ysize(), pb->get_border());
|
||||||
|
clear_attribute(TextureTransition::get_class_type());
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
|
@ -78,6 +78,11 @@ sub_render(NodeRelation *arc, const AllTransitionsWrapper &,
|
|||||||
// DisplayRegion instead of the GSG.
|
// DisplayRegion instead of the GSG.
|
||||||
const DisplayRegion *dr = gsg->get_current_display_region();
|
const DisplayRegion *dr = gsg->get_current_display_region();
|
||||||
LensNode *camera = dr->get_cull_frustum();
|
LensNode *camera = dr->get_cull_frustum();
|
||||||
|
if (camera == (LensNode *)NULL) {
|
||||||
|
// Never mind; ask the gsg.
|
||||||
|
camera = gsg->get_current_camera();
|
||||||
|
}
|
||||||
|
|
||||||
nassertr(camera != (LensNode *)NULL, true);
|
nassertr(camera != (LensNode *)NULL, true);
|
||||||
|
|
||||||
// And the relative coordinate space.
|
// And the relative coordinate space.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user