697 lines
24 KiB
C++
697 lines
24 KiB
C++
// Filename: graphicsWindow.cxx
|
|
// Created by: mike (09Jan97)
|
|
//
|
|
////////////////////////////////////////////////////////////////////
|
|
//
|
|
// 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 "graphicsWindow.h"
|
|
#include "graphicsPipe.h"
|
|
#include "config_display.h"
|
|
|
|
#include <mouseButton.h>
|
|
#include <keyboardButton.h>
|
|
|
|
#include "pmap.h"
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Static variables
|
|
////////////////////////////////////////////////////////////////////
|
|
TypeHandle GraphicsWindow::_type_handle;
|
|
TypeHandle GraphicsWindow::WindowProps::_type_handle;
|
|
TypeHandle GraphicsWindow::WindowPipe::_type_handle;
|
|
|
|
GraphicsWindow::WindowFactory *GraphicsWindow::_factory = NULL;
|
|
|
|
#ifndef CPPPARSER
|
|
// We must compile these lines, even if DO_PSTATS is not defined,
|
|
// because the symbols for them are declared in the header file.
|
|
// Otherwise they will be undefined symbols at link time. However,
|
|
// there's no runtime overhead to speak of for declaring these, so
|
|
// there's no harm in compiling them all the time.
|
|
PStatCollector GraphicsWindow::_app_pcollector("App");
|
|
PStatCollector GraphicsWindow::_show_code_pcollector("App:Show code");
|
|
PStatCollector GraphicsWindow::_swap_pcollector("Swap buffers");
|
|
PStatCollector GraphicsWindow::_clear_pcollector("Draw:Clear");
|
|
PStatCollector GraphicsWindow::_show_fps_pcollector("Draw:Show fps");
|
|
PStatCollector GraphicsWindow::_make_current_pcollector("Draw:Make current");
|
|
#endif
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: GraphicsWindow::Properties::Constructor
|
|
// Access: Published
|
|
// Description:
|
|
////////////////////////////////////////////////////////////////////
|
|
GraphicsWindow::Properties::
|
|
Properties() {
|
|
_xorg = 0;
|
|
_yorg = 0;
|
|
_xsize = 512;
|
|
_ysize = 512;
|
|
_title = "Panda";
|
|
_border = true;
|
|
_fullscreen = false;
|
|
_mask = W_RGBA | W_DOUBLE | W_DEPTH;
|
|
_want_depth_bits = 1;
|
|
_want_color_bits = 1;
|
|
_bCursorIsVisible=true;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: GraphicsWindow::Callback::draw
|
|
// Access: Public
|
|
// Description:
|
|
////////////////////////////////////////////////////////////////////
|
|
void GraphicsWindow::Callback::
|
|
draw(bool) {
|
|
display_cat.error()
|
|
<< "Callback::draw() - no class defined for this" << endl;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: GraphicsWindow::Callback::idle
|
|
// Access: Public
|
|
// Description:
|
|
////////////////////////////////////////////////////////////////////
|
|
void GraphicsWindow::Callback::
|
|
idle() {
|
|
display_cat.error()
|
|
<< "Callback::idle() - no class defined for this" << endl;
|
|
}
|
|
|
|
GraphicsWindow::WindowProps::~WindowProps(void) {}
|
|
|
|
TypeHandle GraphicsWindow::WindowProps::get_class_type(void) {
|
|
return _type_handle;
|
|
}
|
|
|
|
void GraphicsWindow::WindowProps::init_type(void) {
|
|
WindowParam::init_type();
|
|
register_type(_type_handle, "GraphicsWindow::WindowProps",
|
|
WindowParam::get_class_type());
|
|
}
|
|
|
|
TypeHandle GraphicsWindow::WindowProps::get_type(void) const {
|
|
return get_class_type();
|
|
}
|
|
|
|
TypeHandle GraphicsWindow::WindowProps::force_init_type(void) {
|
|
init_type();
|
|
return get_class_type();
|
|
}
|
|
|
|
GraphicsWindow::WindowPipe::~WindowPipe(void) {}
|
|
|
|
TypeHandle GraphicsWindow::WindowPipe::get_class_type(void) {
|
|
return _type_handle;
|
|
}
|
|
|
|
void GraphicsWindow::WindowPipe::init_type(void) {
|
|
WindowParam::init_type();
|
|
register_type(_type_handle, "GraphicsWindow::WindowPipe",
|
|
WindowParam::get_class_type());
|
|
}
|
|
|
|
TypeHandle GraphicsWindow::WindowPipe::get_type(void) const {
|
|
return get_class_type();
|
|
}
|
|
|
|
TypeHandle GraphicsWindow::WindowPipe::force_init_type(void) {
|
|
init_type();
|
|
return get_class_type();
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: GraphicsWindow::Constructor
|
|
// Access: Public
|
|
// Description:
|
|
////////////////////////////////////////////////////////////////////
|
|
GraphicsWindow::
|
|
GraphicsWindow(GraphicsPipe *pipe) : Configurable() {
|
|
#ifdef DO_MEMORY_USAGE
|
|
MemoryUsage::update_type(this, this);
|
|
#endif
|
|
_pipe = pipe;
|
|
|
|
_draw_callback = NULL;
|
|
_idle_callback = NULL;
|
|
_frame_number = 0;
|
|
_is_synced = false;
|
|
_window_active = true;
|
|
_display_regions_stale = false;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: GraphicsWindow::Constructor
|
|
// Access: Public
|
|
// Description:
|
|
////////////////////////////////////////////////////////////////////
|
|
GraphicsWindow::
|
|
GraphicsWindow(GraphicsPipe *pipe,
|
|
const GraphicsWindow::Properties& props) : Configurable() {
|
|
#ifdef DO_MEMORY_USAGE
|
|
MemoryUsage::update_type(this, this);
|
|
#endif
|
|
_pipe = pipe;
|
|
_props = props;
|
|
|
|
_draw_callback = NULL;
|
|
_idle_callback = NULL;
|
|
_is_synced = false;
|
|
_window_active = true;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: GraphicsWindow::Copy Constructor
|
|
// Access: Public
|
|
// Description:
|
|
////////////////////////////////////////////////////////////////////
|
|
GraphicsWindow::
|
|
GraphicsWindow(const GraphicsWindow&) {
|
|
display_cat.error()
|
|
<< "GraphicsWindows should not be copied" << endl;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: GraphicsWindow::Copy Assignment Operator
|
|
// Access: Public
|
|
// Description:
|
|
////////////////////////////////////////////////////////////////////
|
|
GraphicsWindow& GraphicsWindow::
|
|
operator=(const GraphicsWindow&) {
|
|
display_cat.error()
|
|
<< "GraphicsWindows should not be assigned" << endl;
|
|
return *this;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: GraphicsWindow::Destructor
|
|
// Access: Public, Virtual
|
|
// Description:
|
|
////////////////////////////////////////////////////////////////////
|
|
GraphicsWindow::
|
|
~GraphicsWindow() {
|
|
// First, call close_window(). This tells our GSG to let go of its
|
|
// pointer to us, and also eventually calls do_close_window().
|
|
// However, do_close_window() is a virtual function that might be
|
|
// extended in a derived class, but we don't have any derived
|
|
// virtual functions by the time the destructor is called.
|
|
|
|
// Therefore, if a derived class has redefined do_close_window(), it
|
|
// should also call close_window() in its own destructor.
|
|
close_window();
|
|
|
|
|
|
// We don't have to destruct our child channels explicitly, since
|
|
// they are all reference-counted and will go away when their
|
|
// pointers do. However, we do need to zero out their pointers to
|
|
// us.
|
|
Channels::iterator ci;
|
|
for (ci = _channels.begin(); ci != _channels.end(); ++ci) {
|
|
(*ci)->_window = NULL;
|
|
}
|
|
|
|
// We don't need to remove ourself from the pipe's list of windows.
|
|
// We must have already been removed, or we wouldn't be destructing!
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: GraphicsWindow::get_channel
|
|
// Access: Public
|
|
// Description: Returns a GraphicsChannel pointer that can be used to
|
|
// access the indicated channel number. All windows
|
|
// have at least one channel, channel 0, which
|
|
// corresponds to the entire window. If the hardware
|
|
// supports it, some kinds of windows may also have a
|
|
// number of hardware channels available at indices
|
|
// 1..n, which will correspond to a subregion of the
|
|
// window.
|
|
//
|
|
// This function returns a GraphicsChannel pointer if a
|
|
// channel is available, or NULL if it is not. If
|
|
// called twice with the same index number, it will
|
|
// return the same pointer.
|
|
////////////////////////////////////////////////////////////////////
|
|
GraphicsChannel *GraphicsWindow::
|
|
get_channel(int index) {
|
|
nassertr(index >= 0, NULL);
|
|
|
|
if (index < (int)_channels.size()) {
|
|
if (_channels[index] != (GraphicsChannel *)NULL) {
|
|
return _channels[index];
|
|
}
|
|
}
|
|
|
|
// This channel has never been requested before; define it.
|
|
|
|
PT(GraphicsChannel) chan;
|
|
if (index == 0) {
|
|
// Channel 0 is the default channel: the entire screen.
|
|
chan = new GraphicsChannel(this);
|
|
} else {
|
|
// Any other channel is some hardware-specific channel.
|
|
nassertr(_pipe != NULL, NULL);
|
|
chan = _pipe->get_hw_channel(this, index);
|
|
if (chan == NULL) {
|
|
display_cat.error()
|
|
<< "GraphicsWindow::get_channel() - got a NULL channel" << endl;
|
|
} else {
|
|
if (chan->get_window() != this) {
|
|
chan = NULL;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (chan != (GraphicsChannel *)NULL) {
|
|
declare_channel(index, chan);
|
|
}
|
|
|
|
return chan;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: GraphicsWindow::remove_channel
|
|
// Access: Public
|
|
// Description: Deletes a GraphicsChannel that was previously created
|
|
// via a call to get_channel(). Note that the channel
|
|
// is not actually deleted until all pointers to it are
|
|
// cleared.
|
|
////////////////////////////////////////////////////////////////////
|
|
void GraphicsWindow::
|
|
remove_channel(int index) {
|
|
if (index >= 0 && index < (int)_channels.size()) {
|
|
_channels[index].clear();
|
|
}
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: GraphicsWindow::get_max_channel_index
|
|
// Access: Public
|
|
// Description: Returns the largest channel index number yet created,
|
|
// plus 1. All channels associated with this window
|
|
// will have an index number in the range [0,
|
|
// get_max_channel_index()). This function, in
|
|
// conjunction with is_channel_defined(), below, may be
|
|
// used to determine the complete set of channels
|
|
// associated with the window.
|
|
////////////////////////////////////////////////////////////////////
|
|
int GraphicsWindow::
|
|
get_max_channel_index() const {
|
|
return _channels.size();
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: GraphicsWindow::is_channel_defined
|
|
// Access: Public
|
|
// Description: Returns true if the channel with the given index
|
|
// number has already been defined, false if it hasn't.
|
|
// If this returns true, calling get_channel() on the
|
|
// given index number will return the channel pointer.
|
|
// If it returns false, calling get_channel() will
|
|
// create and return a new channel pointer.
|
|
////////////////////////////////////////////////////////////////////
|
|
bool GraphicsWindow::
|
|
is_channel_defined(int index) const {
|
|
if (index < 0 || index >= (int)_channels.size()) {
|
|
return false;
|
|
}
|
|
return (_channels[index] != (GraphicsChannel *)NULL);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: GraphicsWindow::declare_channel
|
|
// Access: Protected
|
|
// Description: An internal function to add the indicated
|
|
// newly-created channel to the list at the indicated
|
|
// channel number.
|
|
////////////////////////////////////////////////////////////////////
|
|
void GraphicsWindow::
|
|
declare_channel(int index, GraphicsChannel *chan) {
|
|
nassertv(index >= 0);
|
|
if (index >= (int)_channels.size()) {
|
|
_channels.reserve(index);
|
|
while (index >= (int)_channels.size()) {
|
|
_channels.push_back(NULL);
|
|
}
|
|
}
|
|
|
|
nassertv(index < (int)_channels.size());
|
|
_channels[index] = chan;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: GraphicsWindow::do_determine_display_regions
|
|
// Access: Private
|
|
// Description: Recomputes the list of active DisplayRegions within
|
|
// the window.
|
|
////////////////////////////////////////////////////////////////////
|
|
void GraphicsWindow::
|
|
do_determine_display_regions() {
|
|
_display_regions.clear();
|
|
Channels::const_iterator ci;
|
|
for (ci = _channels.begin(); ci != _channels.end(); ++ci) {
|
|
GraphicsChannel *chan = (*ci);
|
|
if (chan->is_active()) {
|
|
GraphicsChannel::GraphicsLayers::const_iterator li;
|
|
for (li = chan->_layers.begin(); li != chan->_layers.end(); ++li) {
|
|
GraphicsLayer *layer = (*li);
|
|
if (layer->is_active()) {
|
|
GraphicsLayer::DisplayRegions::const_iterator dri;
|
|
for (dri = layer->_display_regions.begin();
|
|
dri != layer->_display_regions.end();
|
|
++dri) {
|
|
DisplayRegion *dr = (*dri);
|
|
if (dr->is_active()) {
|
|
_display_regions.push_back(dr);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
_display_regions_stale = false;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: GraphicsWindow::resized
|
|
// Access: Public, Virtual
|
|
// Description: Called whenever the window gets the resize event.
|
|
////////////////////////////////////////////////////////////////////
|
|
void GraphicsWindow::
|
|
resized(const unsigned int x, const unsigned int y) {
|
|
Channels::iterator ci;
|
|
for (ci = _channels.begin(); ci != _channels.end(); ++ci) {
|
|
GraphicsChannel *chan = (*ci);
|
|
chan->window_resized(x, y);
|
|
}
|
|
_props._xsize = x;
|
|
_props._ysize = y;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: GraphicsWindow::make_scratch_display_region
|
|
// Access: Public
|
|
// Description: Allocates and returns a temporary DisplayRegion that
|
|
// may be used to render offscreen into. This
|
|
// DisplayRegion is not associated with any layer.
|
|
//
|
|
// To allocate a normal DisplayRegion for rendering, use
|
|
// the interface provded in GraphicsLayer.
|
|
////////////////////////////////////////////////////////////////////
|
|
PT(DisplayRegion) GraphicsWindow::
|
|
make_scratch_display_region(int xsize, int ysize) const {
|
|
if (xsize > _props._xsize) {
|
|
display_cat.error()
|
|
<< "GraphicsWindow::make_scratch_display_region() - x size is larger "
|
|
<< "than window x size" << endl;
|
|
xsize = _props._xsize;
|
|
}
|
|
if (ysize > _props._ysize) {
|
|
display_cat.error()
|
|
<< "GraphicsWindow::make_scratch_display_region() - y size is larger "
|
|
<< "than window y size" << endl;
|
|
ysize = _props._ysize;
|
|
}
|
|
|
|
return new DisplayRegion(xsize, ysize);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: GraphicsWindow::make_current
|
|
// Access: Public, Virtual
|
|
// Description: Makes the window's graphics context the currently
|
|
// active context that will be next rendered into by the
|
|
// GSG, if this makes sense for the particular type of
|
|
// GraphicsWindow.
|
|
////////////////////////////////////////////////////////////////////
|
|
void GraphicsWindow::
|
|
make_current(void) {
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: GraphicsWindow::unmake_current
|
|
// Access: Public, Virtual
|
|
// Description:
|
|
////////////////////////////////////////////////////////////////////
|
|
void GraphicsWindow::
|
|
unmake_current(void) {
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: GraphicsWindow::flag_redisplay
|
|
// Access: Public, Virtual
|
|
// Description:
|
|
////////////////////////////////////////////////////////////////////
|
|
void GraphicsWindow::
|
|
flag_redisplay() {
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: GraphicsWindow::register_draw_function
|
|
// Access: Public, Virtual
|
|
// Description:
|
|
////////////////////////////////////////////////////////////////////
|
|
void GraphicsWindow::
|
|
register_draw_function(GraphicsWindow::vfn f) {
|
|
_draw_function = f;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: GraphicsWindow::register_idle_function
|
|
// Access: Public, Virtual
|
|
// Description:
|
|
////////////////////////////////////////////////////////////////////
|
|
void GraphicsWindow::
|
|
register_idle_function(GraphicsWindow::vfn f) {
|
|
_idle_function = f;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: GraphicsWindow::begin_frame
|
|
// Access: Public, Virtual
|
|
// Description: This function will be called by the GSG before
|
|
// beginning processing for a given frame. It should do
|
|
// whatever setup is required.
|
|
////////////////////////////////////////////////////////////////////
|
|
void GraphicsWindow::
|
|
begin_frame() {
|
|
_gsg->begin_frame();
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: GraphicsWindow::clear
|
|
// Access: Public
|
|
// Description: Invokes the GSG to clear the entire contents of the
|
|
// window prior to drawing into it. This is normally
|
|
// called only by the draw process at the beginning of
|
|
// the frame.
|
|
////////////////////////////////////////////////////////////////////
|
|
void GraphicsWindow::
|
|
clear() {
|
|
_gsg->clear_framebuffer();
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: GraphicsWindow::end_frame
|
|
// Access: Public, Virtual
|
|
// Description: This function will be called by the GSG after
|
|
// processing is completed for a given frame. It should
|
|
// do whatever finalization is required.
|
|
////////////////////////////////////////////////////////////////////
|
|
void GraphicsWindow::
|
|
end_frame() {
|
|
_gsg->end_frame();
|
|
_frame_number++;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: GraphicsWindow::process_events
|
|
// Access: Public, Virtual
|
|
// Description: Do whatever processing is necessary to ensure that
|
|
// the window responds to user events.
|
|
////////////////////////////////////////////////////////////////////
|
|
void GraphicsWindow::
|
|
process_events() {
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: GraphicsWindow::deactivate_window
|
|
// Access: Public, Virtual
|
|
// Description: Indicates the window should stop rendering
|
|
// temporarily, and does whatever else is associated
|
|
// with that. This is normally called only by the
|
|
// GraphicsWindow itself, or by the GSG.
|
|
////////////////////////////////////////////////////////////////////
|
|
void GraphicsWindow::
|
|
deactivate_window() {
|
|
_window_active = false;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: GraphicsWindow::reactivate_window
|
|
// Access: Public, Virtual
|
|
// Description: Restores the normal window rendering behavior after a
|
|
// previous call to deactivate_window().
|
|
////////////////////////////////////////////////////////////////////
|
|
void GraphicsWindow::
|
|
reactivate_window() {
|
|
_window_active = true;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: GraphicsWindow::make_gsg
|
|
// Access: Protected
|
|
// Description: Creates a new GSG for the window and stores it in the
|
|
// _gsg pointer.
|
|
////////////////////////////////////////////////////////////////////
|
|
void GraphicsWindow::
|
|
make_gsg() {
|
|
FactoryParams params;
|
|
params.add_param(new GraphicsStateGuardian::GsgWindow(this));
|
|
|
|
_gsg = GraphicsStateGuardian::get_factory().
|
|
make_instance(get_gsg_type(), params);
|
|
|
|
nassertv(_gsg != (GraphicsStateGuardian *)NULL);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: GraphicsWindow::release_gsg
|
|
// Access: Protected
|
|
// Description: Releases the current GSG pointer, if it is currently
|
|
// held. This invalidates the window and marks it
|
|
// closed; it should not be called unless the code to
|
|
// close the window is also called.
|
|
////////////////////////////////////////////////////////////////////
|
|
void GraphicsWindow::
|
|
release_gsg() {
|
|
if (_gsg != (GraphicsStateGuardian *)NULL) {
|
|
// First, we save the GSG pointer and then NULL it out. That way,
|
|
// if the GSG happens to call close_window() while it is closing
|
|
// itself, it won't be recursive (because we'll already be marked
|
|
// closed).
|
|
PT(GraphicsStateGuardian) gsg = _gsg;
|
|
_gsg.clear();
|
|
|
|
// Now we tell the GSG it's time to sleep.
|
|
gsg->close_gsg();
|
|
}
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: GraphicsWindow::do_close_window
|
|
// Access: Protected, Virtual
|
|
// Description: An internal function to release whatever system
|
|
// resources are held by the window and actually close
|
|
// it. This is called by close_window().
|
|
//
|
|
// If a derived class redefines this function, it should
|
|
// also arrange to call close_window() (or its
|
|
// equivalent) from its own destructor, since we cannot
|
|
// call a virtual function from this destructor.
|
|
////////////////////////////////////////////////////////////////////
|
|
void GraphicsWindow::
|
|
do_close_window() {
|
|
display_cat.info()
|
|
<< "Closing " << get_type() << "\n";
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: GraphicsWindow::get_factory
|
|
// Access: Public, Static
|
|
// Description: Returns the factory object that can be used to
|
|
// register new kinds of GraphicsWindow objects that may
|
|
// be created.
|
|
////////////////////////////////////////////////////////////////////
|
|
GraphicsWindow::WindowFactory &GraphicsWindow::
|
|
get_factory() {
|
|
if (_factory == (WindowFactory *)NULL) {
|
|
_factory = new WindowFactory;
|
|
}
|
|
return (*_factory);
|
|
}
|
|
|
|
void GraphicsWindow::read_priorities(void) {
|
|
WindowFactory &factory = get_factory();
|
|
if (factory.get_num_preferred() == 0) {
|
|
Config::ConfigTable::Symbol::iterator i;
|
|
for (i = preferred_window_begin(); i != preferred_window_end(); ++i) {
|
|
ConfigString type_name = (*i).Val();
|
|
TypeHandle type = TypeRegistry::ptr()->find_type(type_name);
|
|
if (type == TypeHandle::none()) {
|
|
display_cat.warning()
|
|
<< "Unknown type requested for window preference: " << type_name
|
|
<< "\n";
|
|
} else {
|
|
display_cat.debug()
|
|
<< "Specifying type " << type << " for window preference.\n";
|
|
factory.add_preferred(type);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: GraphicsWindow::swap
|
|
// Access: Public
|
|
// Description: Swaps buffers explicitely as synchronization
|
|
// mechanism.
|
|
////////////////////////////////////////////////////////////////////
|
|
void GraphicsWindow::
|
|
swap() {
|
|
display_cat.warning() << "swap() unimplemented by " << get_type() << endl;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: GraphicsWindow::resize
|
|
// Access: Public
|
|
// Description: Resizes the window to the given size.
|
|
// Should try to preserve current window bitdepths,
|
|
// if possible. If it is not possible to resize window to
|
|
// the given size, return false and maintain current
|
|
// window size.
|
|
////////////////////////////////////////////////////////////////////
|
|
bool GraphicsWindow::
|
|
resize(unsigned int xsize,unsigned int ysize) {
|
|
display_cat.warning() << "resize() unimplemented by " << get_type() << endl;
|
|
return false;
|
|
}
|
|
|
|
unsigned int GraphicsWindow::
|
|
verify_window_sizes(unsigned int numsizes,unsigned int *dimen) {
|
|
// see if window sizes are supported (i.e. in fullscrn mode)
|
|
// dimen is an array containing contiguous x,y pairs specifying
|
|
// possible display sizes, it is numsizes*2 long. fn will zero
|
|
// out any invalid x,y size pairs. return value is number of valid
|
|
// sizes that were found.
|
|
//
|
|
// note: it might be better to implement some sort of query
|
|
// interface that returns an array of supported sizes,
|
|
// but this way is somewhat simpler and will do the job
|
|
// on most cards, assuming they handle the std sizes the app
|
|
// knows about.
|
|
|
|
// Also note this doesnt guarantee resize() will work, you still need to check its return value.
|
|
|
|
display_cat.warning() << "verify_window_sizes() unimplemented by " << get_type() << endl;
|
|
return numsizes;
|
|
}
|
|
|
|
int GraphicsWindow::
|
|
get_depth_bitwidth(void) {
|
|
display_cat.warning() << "get_depth_bitwidth() unimplemented by " << get_type() << endl;
|
|
return -1;
|
|
}
|