From 0b4470af0d619ab40b0267451cbee984700904ed Mon Sep 17 00:00:00 2001 From: David Rose Date: Fri, 24 Apr 2009 19:04:07 +0000 Subject: [PATCH] support window-type offscreen in pview --- panda/src/framework/config_framework.cxx | 2 + panda/src/framework/pandaFramework.cxx | 72 +++++++++++++----------- panda/src/framework/pandaFramework.h | 10 ++-- panda/src/framework/windowFramework.I | 18 +++++- panda/src/framework/windowFramework.cxx | 50 ++++++++-------- panda/src/framework/windowFramework.h | 9 +-- panda/src/testbed/pview.cxx | 26 +++++---- 7 files changed, 109 insertions(+), 78 deletions(-) diff --git a/panda/src/framework/config_framework.cxx b/panda/src/framework/config_framework.cxx index 22a9ca888f..b03c661b56 100644 --- a/panda/src/framework/config_framework.cxx +++ b/panda/src/framework/config_framework.cxx @@ -30,6 +30,8 @@ ConfigVariableDouble aspect_ratio ("aspect-ratio", 0.0); ConfigVariableBool show_frame_rate_meter ("show-frame-rate-meter", false); +ConfigVariableString window_type +("window-type", "onscreen"); ConfigVariableString record_session ("record-session", ""); diff --git a/panda/src/framework/pandaFramework.cxx b/panda/src/framework/pandaFramework.cxx index 97fcdb00be..02d0f6beb2 100644 --- a/panda/src/framework/pandaFramework.cxx +++ b/panda/src/framework/pandaFramework.cxx @@ -233,7 +233,7 @@ get_default_pipe() { // GraphicsWindow to share the same mouse. //////////////////////////////////////////////////////////////////// NodePath PandaFramework:: -get_mouse(GraphicsWindow *window) { +get_mouse(GraphicsOutput *window) { Mouses::iterator mi = _mouses.find(window); if (mi != _mouses.end()) { return (*mi).second; @@ -241,18 +241,21 @@ get_mouse(GraphicsWindow *window) { NodePath mouse; - NodePath data_root = get_data_root(); - MouseAndKeyboard *mouse_node = new MouseAndKeyboard(window, 0, "mouse"); - mouse = data_root.attach_new_node(mouse_node); - - RecorderController *recorder = get_recorder(); - if (recorder != (RecorderController *)NULL) { - // If we're in recording or playback mode, associate a recorder. - MouseRecorder *mouse_recorder = new MouseRecorder("mouse"); - mouse = mouse.attach_new_node(mouse_recorder); - recorder->add_recorder("mouse", mouse_recorder); + if (window->is_of_type(GraphicsWindow::get_class_type())) { + NodePath data_root = get_data_root(); + GraphicsWindow *win = DCAST(GraphicsWindow, window); + MouseAndKeyboard *mouse_node = new MouseAndKeyboard(win, 0, "mouse"); + mouse = data_root.attach_new_node(mouse_node); + + RecorderController *recorder = get_recorder(); + if (recorder != (RecorderController *)NULL) { + // If we're in recording or playback mode, associate a recorder. + MouseRecorder *mouse_recorder = new MouseRecorder("mouse"); + mouse = mouse.attach_new_node(mouse_recorder); + recorder->add_recorder("mouse", mouse_recorder); + } } - + _mouses[window] = mouse; return mouse; @@ -265,7 +268,7 @@ get_mouse(GraphicsWindow *window) { // earlier call to get_mouse(). //////////////////////////////////////////////////////////////////// void PandaFramework:: -remove_mouse(const GraphicsWindow *window) { +remove_mouse(const GraphicsOutput *window) { Mouses::iterator mi = _mouses.find(window); if (mi != _mouses.end()) { (*mi).second.remove_node(); @@ -391,7 +394,12 @@ open_window(GraphicsPipe *pipe, GraphicsStateGuardian *gsg) { WindowProperties props; get_default_window_props(props); - return open_window(props, pipe, gsg); + int flags = GraphicsPipe::BF_require_window; + if (window_type == "offscreen") { + flags = GraphicsPipe::BF_refuse_window; + } + + return open_window(props, flags, pipe, gsg); } //////////////////////////////////////////////////////////////////// @@ -405,8 +413,8 @@ open_window(GraphicsPipe *pipe, GraphicsStateGuardian *gsg) { // NULL if not. //////////////////////////////////////////////////////////////////// WindowFramework *PandaFramework:: -open_window(const WindowProperties &props, GraphicsPipe *pipe, - GraphicsStateGuardian *gsg) { +open_window(const WindowProperties &props, int flags, + GraphicsPipe *pipe, GraphicsStateGuardian *gsg) { if (pipe == (GraphicsPipe *)NULL) { pipe = get_default_pipe(); if (pipe == (GraphicsPipe *)NULL) { @@ -424,18 +432,18 @@ open_window(const WindowProperties &props, GraphicsPipe *pipe, wf->set_perpixel(get_perpixel()); wf->set_background_type(get_background_type()); - GraphicsWindow *win = wf->open_window(props, get_graphics_engine(), + GraphicsOutput *win = wf->open_window(props, flags, get_graphics_engine(), pipe, gsg); _engine->open_windows(); - if (win != (GraphicsWindow *)NULL && !win->is_valid()) { + if (win != (GraphicsOutput *)NULL && !win->is_valid()) { // The window won't open. _engine->remove_window(win); wf->close_window(); win = NULL; } - if (win == (GraphicsWindow *)NULL) { - // Oops, couldn't make an actual window. + if (win == (GraphicsOutput *)NULL) { + // Oops, couldn't make a window or buffer. framework_cat.error() << "Unable to create window.\n"; return NULL; @@ -449,14 +457,14 @@ open_window(const WindowProperties &props, GraphicsPipe *pipe, // Function: PandaFramework::find_window // Access: Public // Description: Returns the index of the first WindowFramework object -// found that references the indicated GraphicsWindow +// found that references the indicated GraphicsOutput // pointer, or -1 if none do. //////////////////////////////////////////////////////////////////// int PandaFramework:: -find_window(const GraphicsWindow *win) const { +find_window(const GraphicsOutput *win) const { int n; for (n = 0; n < (int)_windows.size(); n++) { - if (_windows[n]->get_graphics_window() == win) { + if (_windows[n]->get_graphics_output() == win) { return n; } } @@ -494,8 +502,8 @@ close_window(int n) { nassertv(n >= 0 && n < (int)_windows.size()); WindowFramework *wf = _windows[n]; - GraphicsWindow *win = wf->get_graphics_window(); - if (win != (GraphicsWindow *)NULL) { + GraphicsOutput *win = wf->get_graphics_output(); + if (win != (GraphicsOutput *)NULL) { _engine->remove_window(win); } @@ -515,8 +523,8 @@ close_all_windows() { for (wi = _windows.begin(); wi != _windows.end(); ++wi) { WindowFramework *wf = (*wi); - GraphicsWindow *win = wf->get_graphics_window(); - if (win != (GraphicsWindow *)NULL) { + GraphicsOutput *win = wf->get_graphics_output(); + if (win != (GraphicsOutput *)NULL) { _engine->remove_window(win); } @@ -543,7 +551,7 @@ all_windows_closed() const { Windows::const_iterator wi; for (wi = _windows.begin(); wi != _windows.end(); ++wi) { WindowFramework *wf = (*wi); - if (wf->get_graphics_window()->get_properties().get_open()) { + if (wf->get_graphics_output()->is_valid()) { return false; } } @@ -938,7 +946,7 @@ event_esc(const Event *event, void *data) { WindowFramework *wf; DCAST_INTO_V(wf, param.get_ptr()); - PT(GraphicsWindow) win = wf->get_graphics_window(); + PT(GraphicsOutput) win = wf->get_graphics_output(); PandaFramework *self = (PandaFramework *)data; self->close_window(wf); @@ -1341,7 +1349,7 @@ event_f9(const Event *event, void *data) { self->_engine->render_frame(); } - Filename filename = wf->get_graphics_window()->save_screenshot_default(); + Filename filename = wf->get_graphics_output()->save_screenshot_default(); string text; if (filename.empty()) { text = "Screenshot failed"; @@ -1467,7 +1475,7 @@ event_window_event(const Event *event, void *data) { // than the window framework object (which is the parameter of all // of the keyboard events). EventParameter param = event->get_parameter(0); - const GraphicsWindow *win; + const GraphicsOutput *win; DCAST_INTO_V(win, param.get_ptr()); // Is this a window we've heard about? @@ -1477,7 +1485,7 @@ event_window_event(const Event *event, void *data) { << "Ignoring message from unknown window.\n"; } else { - if (!win->get_properties().get_open()) { + if (!win->is_valid()) { int window_index = self->find_window(win); while (window_index != -1) { self->close_window(window_index); diff --git a/panda/src/framework/pandaFramework.h b/panda/src/framework/pandaFramework.h index ce51d982b8..819bbef241 100644 --- a/panda/src/framework/pandaFramework.h +++ b/panda/src/framework/pandaFramework.h @@ -50,8 +50,8 @@ public: INLINE const NodePath &get_data_root() const; INLINE EventHandler &get_event_handler(); INLINE AsyncTaskManager &get_task_mgr(); - NodePath get_mouse(GraphicsWindow *window); - void remove_mouse(const GraphicsWindow *window); + NodePath get_mouse(GraphicsOutput *window); + void remove_mouse(const GraphicsOutput *window); void define_key(const string &event_name, const string &description, @@ -64,13 +64,13 @@ public: WindowFramework *open_window(); WindowFramework *open_window(GraphicsPipe *pipe, GraphicsStateGuardian *gsg = NULL); - WindowFramework *open_window(const WindowProperties &props, + WindowFramework *open_window(const WindowProperties &props, int flags, GraphicsPipe *pipe = NULL, GraphicsStateGuardian *gsg = NULL); INLINE int get_num_windows() const; INLINE WindowFramework *get_window(int n) const; - int find_window(const GraphicsWindow *win) const; + int find_window(const GraphicsOutput *win) const; int find_window(const WindowFramework *wf) const; void close_window(int n); INLINE void close_window(WindowFramework *wf); @@ -176,7 +176,7 @@ private: typedef pvector< PT(WindowFramework) > Windows; Windows _windows; - typedef pmap< const GraphicsWindow *, NodePath > Mouses; + typedef pmap< const GraphicsOutput *, NodePath > Mouses; Mouses _mouses; NodePath _models; diff --git a/panda/src/framework/windowFramework.I b/panda/src/framework/windowFramework.I index ea7126b3e4..908b7bcaac 100644 --- a/panda/src/framework/windowFramework.I +++ b/panda/src/framework/windowFramework.I @@ -28,10 +28,26 @@ get_panda_framework() const { // Function: WindowFramework::get_graphics_window // Access: Public // Description: Returns a pointer to the underlying GraphicsWindow -// object. +// object, if it is in fact a window; or NULL if it is +// not. //////////////////////////////////////////////////////////////////// INLINE GraphicsWindow *WindowFramework:: get_graphics_window() const { + if (_window != (GraphicsOutput *)NULL && + _window->is_of_type(GraphicsWindow::get_class_type())) { + return DCAST(GraphicsWindow, _window); + } + return NULL; +} + +//////////////////////////////////////////////////////////////////// +// Function: WindowFramework::get_graphics_output +// Access: Public +// Description: Returns a pointer to the underlying GraphicsOutput +// object +//////////////////////////////////////////////////////////////////// +INLINE GraphicsOutput *WindowFramework:: +get_graphics_output() const { return _window; } diff --git a/panda/src/framework/windowFramework.cxx b/panda/src/framework/windowFramework.cxx index 1cdfcc8b0f..41139098fa 100644 --- a/panda/src/framework/windowFramework.cxx +++ b/panda/src/framework/windowFramework.cxx @@ -142,13 +142,13 @@ WindowFramework:: //////////////////////////////////////////////////////////////////// // Function: WindowFramework::open_window // Access: Protected -// Description: Opens the actual window. This is normally called -// only from PandaFramework::open_window(). +// Description: Opens the actual window or buffer. This is normally +// called only from PandaFramework::open_window(). //////////////////////////////////////////////////////////////////// -GraphicsWindow *WindowFramework:: -open_window(const WindowProperties &props, GraphicsEngine *engine, +GraphicsOutput *WindowFramework:: +open_window(const WindowProperties &props, int flags, GraphicsEngine *engine, GraphicsPipe *pipe, GraphicsStateGuardian *gsg) { - nassertr(_window == (GraphicsWindow *)NULL, _window); + nassertr(_window == (GraphicsOutput *)NULL, _window); static int next_window_index = 1; ostringstream stream; @@ -160,11 +160,10 @@ open_window(const WindowProperties &props, GraphicsEngine *engine, GraphicsOutput *winout = engine->make_output(pipe, name, 0, FrameBufferProperties::get_default(), - props, GraphicsPipe::BF_require_window, - gsg, NULL); + props, flags, gsg, NULL); if (winout != (GraphicsOutput *)NULL) { - _window = DCAST(GraphicsWindow, winout); - _window->request_properties(props); + _window = winout; + // _window->request_properties(props); // Create a display region that covers the entire window. _display_region_3d = _window->make_display_region(); @@ -193,7 +192,7 @@ open_window(const WindowProperties &props, GraphicsEngine *engine, //////////////////////////////////////////////////////////////////// // Function: WindowFramework::close_window // Access: Protected -// Description: Closes the window. This is normally called +// Description: Closes the window or buffer. This is normally called // from PandaFramework::close_window(). //////////////////////////////////////////////////////////////////// void WindowFramework:: @@ -328,13 +327,12 @@ get_aspect_2d() { // An aspect ratio of 0.0 means to try to infer it. this_aspect_ratio = 1.0f; - WindowProperties properties = _window->get_properties(); - if (!properties.has_size()) { - properties = _window->get_requested_properties(); - } - if (properties.has_size() && properties.get_y_size() != 0.0f) { - this_aspect_ratio = - (float)properties.get_x_size() / (float)properties.get_y_size(); + if (_window->has_size()) { + int x_size = _window->get_x_size(); + int y_size = _window->get_y_size(); + if (y_size != 0) { + this_aspect_ratio = (float)x_size / (float)y_size; + } } } @@ -382,7 +380,8 @@ enable_keyboard() { return; } - if (_window->get_num_input_devices() > 0) { + if (_window->is_of_type(GraphicsWindow::get_class_type()) && + DCAST(GraphicsWindow, _window)->get_num_input_devices() > 0) { NodePath mouse = get_mouse(); // Create a button thrower to listen for our keyboard events and @@ -412,7 +411,8 @@ setup_trackball() { return; } - if (_window->get_num_input_devices() > 0) { + if (_window->is_of_type(GraphicsWindow::get_class_type()) && + DCAST(GraphicsWindow, _window)->get_num_input_devices() > 0) { NodePath mouse = get_mouse(); NodePath camera = get_camera_group(); @@ -1088,12 +1088,12 @@ make_camera() { } else { // Otherwise, infer the aspect ratio from the window size. This // does assume we have square pixels on our output device. - WindowProperties properties = _window->get_properties(); - if (!properties.has_size()) { - properties = _window->get_requested_properties(); - } - if (properties.has_size()) { - lens->set_film_size(properties.get_x_size(), properties.get_y_size()); + if (_window->has_size()) { + int x_size = _window->get_x_size(); + int y_size = _window->get_y_size(); + if (y_size != 0) { + lens->set_film_size(x_size, y_size); + } } } diff --git a/panda/src/framework/windowFramework.h b/panda/src/framework/windowFramework.h index 9f35581bcb..40b56c224c 100644 --- a/panda/src/framework/windowFramework.h +++ b/panda/src/framework/windowFramework.h @@ -18,6 +18,7 @@ #include "pandabase.h" #include "nodePath.h" #include "camera.h" +#include "graphicsOutput.h" #include "graphicsWindow.h" #include "animControlCollection.h" #include "trackball.h" @@ -27,7 +28,6 @@ #include "partGroup.h" #include "pvector.h" #include "typedWritableReferenceCount.h" -#include "graphicsWindow.h" #include "loaderOptions.h" #include "pgSliderBar.h" #include "textNode.h" @@ -48,7 +48,7 @@ class DisplayRegion; // display region within a window. (In the case where a // window has been subdivided with split_window(), there // may be multiple WindowFrameworks objects that share -// the same GraphicsWindow pointer, but reference +// the same GraphicsOutput pointer, but reference // different display regions within that window). //////////////////////////////////////////////////////////////////// class EXPCL_FRAMEWORK WindowFramework : public TypedWritableReferenceCount { @@ -60,7 +60,7 @@ public: virtual ~WindowFramework(); protected: - GraphicsWindow *open_window(const WindowProperties &props, + GraphicsOutput *open_window(const WindowProperties &props, int flags, GraphicsEngine *engine, GraphicsPipe *pipe, GraphicsStateGuardian *gsg = NULL); void close_window(); @@ -68,6 +68,7 @@ protected: public: INLINE PandaFramework *get_panda_framework() const; INLINE GraphicsWindow *get_graphics_window() const; + INLINE GraphicsOutput *get_graphics_output() const; NodePath get_camera_group(); INLINE int get_num_cameras() const; @@ -156,7 +157,7 @@ private: private: PandaFramework *_panda_framework; - PT(GraphicsWindow) _window; + PT(GraphicsOutput) _window; PT(DisplayRegion) _display_region_2d; PT(DisplayRegion) _display_region_3d; diff --git a/panda/src/testbed/pview.cxx b/panda/src/testbed/pview.cxx index 0c230e2143..bad866c66e 100644 --- a/panda/src/testbed/pview.cxx +++ b/panda/src/testbed/pview.cxx @@ -54,7 +54,7 @@ output_screenshot(Filename &fn) framework.do_frame(current_thread); WindowFramework *wf = framework.get_window(0); - bool ok = wf->get_graphics_window()->save_screenshot(fn, "from pview"); + bool ok = wf->get_graphics_output()->save_screenshot(fn, "from pview"); if (!ok) { cerr << "Could not generate screenshot " << fn << "\n"; } @@ -71,7 +71,7 @@ event_W(const Event *, void *) { if (framework.get_num_windows() > 0) { WindowFramework *old_window = framework.get_window(0); - GraphicsWindow *win = old_window->get_graphics_window(); + GraphicsOutput *win = old_window->get_graphics_output(); pipe = win->get_pipe(); // gsg = win->get_gsg(); } @@ -100,19 +100,23 @@ event_Enter(const Event *, void *) { WindowProperties props; - if (framework.get_num_windows() > 0) { - WindowFramework *old_window = framework.get_window(0); + for (int i = 0; i < framework.get_num_windows(); ++i) { + WindowFramework *old_window = framework.get_window(i); GraphicsWindow *win = old_window->get_graphics_window(); - pipe = win->get_pipe(); - gsg = win->get_gsg(); - props = win->get_properties(); - framework.close_window(old_window); + if (win != (GraphicsWindow *)NULL) { + pipe = win->get_pipe(); + gsg = win->get_gsg(); + props = win->get_properties(); + framework.close_window(old_window); + break; + } } // set the toggle props.set_fullscreen(!props.get_fullscreen()); + int flags = GraphicsPipe::BF_require_window; - WindowFramework *window = framework.open_window(props, pipe, gsg); + WindowFramework *window = framework.open_window(props, flags, pipe, gsg); if (window != (WindowFramework *)NULL) { window->enable_keyboard(); window->setup_trackball(); @@ -144,7 +148,7 @@ event_0(const Event *event, void *) { DCAST_INTO_V(wf, param.get_ptr()); // Create a new offscreen buffer. - GraphicsWindow *win = wf->get_graphics_window(); + GraphicsOutput *win = wf->get_graphics_output(); PT(GraphicsOutput) buffer = win->make_texture_buffer("tex", 256, 256); cerr << buffer->get_type() << "\n"; @@ -339,7 +343,7 @@ main(int argc, char *argv[]) { window->loop_animations(hierarchy_match_flags); // Make sure the textures are preloaded. - framework.get_models().prepare_scene(window->get_graphics_window()->get_gsg()); + framework.get_models().prepare_scene(window->get_graphics_output()->get_gsg()); loading_np.remove_node();