diff --git a/direct/src/showbase/showBase.cxx b/direct/src/showbase/showBase.cxx index 634cd1599e..ce26c599d6 100644 --- a/direct/src/showbase/showBase.cxx +++ b/direct/src/showbase/showBase.cxx @@ -25,10 +25,12 @@ #include "get_config_path.h" #include "camera.h" -// Don't define this unless you have drose's new GraphicsWindow code, -// which is currently a work in progress. You probably won't have it -// unless you are drose. -//#define NEW_WINDOW_CODE 1 +// You should define this unless you don't have the new GraphicsWindow +// code yet. drose checked this in to Panda at around 12:30pm on +// Thursday, Jan 9; if you haven't updated your Panda since then you +// should either go update it (and prepare for a long build) or just +// comment this out to run for the short term with the old code. +#define NEW_WINDOW_CODE 1 #ifdef NEW_WINDOW_CODE #include "graphicsPipeSelection.h" diff --git a/dtool/src/dtoolbase/dllbase.txt b/dtool/src/dtoolbase/dllbase.txt index 9e2ee146f7..677f552cc6 100644 --- a/dtool/src/dtoolbase/dllbase.txt +++ b/dtool/src/dtoolbase/dllbase.txt @@ -7,7 +7,7 @@ ; release dlls libpanda 0x0000000060000000 0x004b0000 -libpandadx 0x0000000061000000 0x00090000 +libpandadx8 0x0000000061000000 0x00090000 libpandadx7 0x0000000061000000 0x00050000 libpandagl 0x0000000061000000 0x00040000 libpandaexpress 0x00000000605d0000 0x00140000 @@ -25,7 +25,7 @@ libframework 0x0000000060a50000 0x00020000 ; debug dlls libpanda_d 0x0000000060000000 0x007c0000 -libpandadx_d 0x00000000607c0000 0x000f0000 +libpandadx8_d 0x00000000607c0000 0x000f0000 libpandadx7_d 0x00000000608b0000 0x00070000 libpandagl_d 0x0000000060920000 0x00050000 libpandaexpress_d 0x0000000060970000 0x00210000 diff --git a/panda/metalibs/pandadx/Sources.pp b/panda/metalibs/pandadx/Sources.pp deleted file mode 100644 index 484da72f6e..0000000000 --- a/panda/metalibs/pandadx/Sources.pp +++ /dev/null @@ -1,23 +0,0 @@ -#define BUILD_DIRECTORY $[HAVE_DX] - -// DIR_TYPE "metalib" indicates we are building a shared library that -// consists mostly of references to other shared libraries. Under -// Windows, this directly produces a DLL (as opposed to the regular -// src libraries, which don't produce anything but a pile of OBJ files -// under Windows). - -#define DIR_TYPE metalib -#define BUILDING_DLL BUILDING_PANDADX - -#define COMPONENT_LIBS \ - dxgsg wdxdisplay -#define LOCAL_LIBS gsgbase display express -#define OTHER_LIBS dtoolconfig dtool - -#begin metalib_target - #define TARGET pandadx7 - #define SOURCES pandadx.cxx - #define WIN_SYS_LIBS \ - ddraw.lib dxguid.lib winmm.lib \ - kernel32.lib gdi32.lib user32.lib $[WIN_SYS_LIBS] -#end metalib_target diff --git a/panda/metalibs/pandadx/pandadx.cxx b/panda/metalibs/pandadx/pandadx.cxx deleted file mode 100644 index dc28e1c017..0000000000 --- a/panda/metalibs/pandadx/pandadx.cxx +++ /dev/null @@ -1,23 +0,0 @@ -// Filename: pandadx.cxx -// Created by: drose (15May00) -// -//////////////////////////////////////////////////////////////////// - -#include "pandadx.h" - -#include -#include - -//////////////////////////////////////////////////////////////////// -// Function: init_libpandadx -// Description: Initializes the library. This must be called at -// least once before any of the functions or classes in -// this library can be used. Normally it will be -// called by the static initializers and need not be -// called explicitly, but special cases exist. -//////////////////////////////////////////////////////////////////// -void -init_libpandadx() { - init_libdxgsg(); - init_libwdxdisplay(); -} diff --git a/panda/metalibs/pandadx/pandadx.h b/panda/metalibs/pandadx/pandadx.h deleted file mode 100644 index d9ffe6377a..0000000000 --- a/panda/metalibs/pandadx/pandadx.h +++ /dev/null @@ -1,13 +0,0 @@ -// Filename: pandadx.h -// Created by: drose (2Jan01) -// -//////////////////////////////////////////////////////////////////// - -#ifndef PANDADX_H -#define PANDADX_H - -#include - -EXPCL_PANDADX void init_libpandadx(); - -#endif diff --git a/panda/metalibs/pandadx8/Sources.pp b/panda/metalibs/pandadx8/Sources.pp index 6078a9dbd2..67af53a187 100644 --- a/panda/metalibs/pandadx8/Sources.pp +++ b/panda/metalibs/pandadx8/Sources.pp @@ -10,12 +10,12 @@ #define BUILDING_DLL BUILDING_PANDADX #define COMPONENT_LIBS \ - dxgsg8 wdxdisplay8 + dxgsg8 #define LOCAL_LIBS gsgbase display express gobj #define OTHER_LIBS dtoolconfig dtool #begin metalib_target - #define TARGET pandadx + #define TARGET pandadx8 #define SOURCES pandadx8.cxx #define WIN_SYS_LIBS \ ddraw.lib dxguid.lib winmm.lib \ diff --git a/panda/metalibs/pandadx8/pandadx8.cxx b/panda/metalibs/pandadx8/pandadx8.cxx index 7110dd62b0..2f728b569f 100644 --- a/panda/metalibs/pandadx8/pandadx8.cxx +++ b/panda/metalibs/pandadx8/pandadx8.cxx @@ -5,8 +5,7 @@ #include "pandadx8.h" -#include -#include +#include "config_dxgsg8.h" //////////////////////////////////////////////////////////////////// // Function: init_libpandadx @@ -19,5 +18,4 @@ void init_libpandadx8() { init_libdxgsg8(); - init_libwdxdisplay8(); } diff --git a/panda/metalibs/pandagl/Sources.pp b/panda/metalibs/pandagl/Sources.pp index 9a807c6ec9..88d5cd9792 100644 --- a/panda/metalibs/pandagl/Sources.pp +++ b/panda/metalibs/pandagl/Sources.pp @@ -12,8 +12,9 @@ // We don't have any components if we're linking the GL library // directly into Panda. #define COMPONENT_LIBS \ - glgsg glxdisplay wgldisplay glutdisplay \ - sgidisplay sgiglxdisplay sgiglutdisplay + glgsg glxdisplay \ + sgidisplay sgiglxdisplay \ + wgldisplay #endif #define LOCAL_LIBS gsgbase display express diff --git a/panda/metalibs/pandagl/pandagl.cxx b/panda/metalibs/pandagl/pandagl.cxx index f5b49349f4..8f6653192d 100644 --- a/panda/metalibs/pandagl/pandagl.cxx +++ b/panda/metalibs/pandagl/pandagl.cxx @@ -7,9 +7,12 @@ #ifndef LINK_IN_GL #include +// Temporarily commented out for development on wgldisplay +/* #ifdef HAVE_WGL #include #endif +*/ #endif //////////////////////////////////////////////////////////////////// @@ -24,8 +27,11 @@ void init_libpandagl() { #ifndef LINK_IN_GL init_libglgsg(); +// Temporarily commented out for development on wgldisplay + /* #ifdef HAVE_WGL init_libwgldisplay(); #endif + */ #endif } diff --git a/panda/src/chancfg/chancfg.cxx b/panda/src/chancfg/chancfg.cxx index 3d5e9f72df..382fd3100e 100644 --- a/panda/src/chancfg/chancfg.cxx +++ b/panda/src/chancfg/chancfg.cxx @@ -19,6 +19,8 @@ #include "chancfg.h" #include "notify.h" #include "displayRegion.h" +#include "graphicsPipe.h" +#include "graphicsEngine.h" #include "graphicsChannel.h" #include "hardwareChannel.h" #include "camera.h" @@ -335,7 +337,8 @@ void ChanConfig::chan_eval(GraphicsWindow* win, WindowItem& W, LayoutItem& L, return; } -ChanConfig::ChanConfig(GraphicsPipe* pipe, std::string cfg, const NodePath &render, +ChanConfig::ChanConfig(GraphicsEngine *engine, GraphicsPipe* pipe, + std::string cfg, const NodePath &render, ChanCfgOverrides& overrides) { ReadChanConfigData(); // check to make sure we know everything we need to @@ -400,9 +403,9 @@ ChanConfig::ChanConfig(GraphicsPipe* pipe, std::string cfg, const NodePath &rend origY = overrides.defined(ChanCfgOverrides::OrigY) ? overrides.getInt(ChanCfgOverrides::OrigY) : origY; - bool border = !chanconfig.GetBool("no-border", !W.getBorder()); + bool undecorated = chanconfig.GetBool("undecorated", !W.getBorder()); bool fullscreen = chanconfig.GetBool("fullscreen", false); - bool use_cursor = chanconfig.GetBool("cursor-visible", W.getCursor()); + bool use_cursor = !chanconfig.GetBool("cursor-hidden", !W.getCursor()); int want_depth_bits = chanconfig.GetInt("want-depth-bits", 1); int want_color_bits = chanconfig.GetInt("want-color-bits", 1); @@ -411,28 +414,27 @@ ChanConfig::ChanConfig(GraphicsPipe* pipe, std::string cfg, const NodePath &rend float win_background_b = chanconfig.GetFloat("win-background-b", 0.41); // visual? nope, that's handled with the mode. - uint mask = 0x0; // ?! this really should come from the win config - mask = overrides.defined(ChanCfgOverrides::Mask) ? - overrides.getUInt(ChanCfgOverrides::Mask) : mask; + int framebuffer_mode = + WindowProperties::FM_rgba | + WindowProperties::FM_double_buffer | + WindowProperties::FM_depth; + framebuffer_mode = overrides.defined(ChanCfgOverrides::Mask) ? + overrides.getUInt(ChanCfgOverrides::Mask) : framebuffer_mode; std::string title = cfg; title = overrides.defined(ChanCfgOverrides::Title) ? overrides.getString(ChanCfgOverrides::Title) : title; - GraphicsWindow::Properties props; - props._xorg = origX; - props._yorg = origY; - props._xsize = sizeX; - props._ysize = sizeY; - props._title = title; - props._mask = mask; - props._border = border; - props._fullscreen = fullscreen; - props._want_depth_bits = want_depth_bits; - props._want_color_bits = want_color_bits; - props._bCursorIsVisible = use_cursor; - - props.set_clear_color(Colorf(win_background_r, win_background_g, - win_background_b, 1.0f)); + WindowProperties props; + props.set_open(true); + props.set_origin(origX, origY); + props.set_size(sizeX, sizeY); + props.set_title(title); + props.set_framebuffer_mode(framebuffer_mode); + props.set_undecorated(undecorated); + props.set_fullscreen(fullscreen); + props.set_depth_bits(want_depth_bits); + props.set_color_bits(want_color_bits); + props.set_cursor_hidden(!use_cursor); // stereo prep? @@ -442,13 +444,17 @@ ChanConfig::ChanConfig(GraphicsPipe* pipe, std::string cfg, const NodePath &rend overrides.getBool(ChanCfgOverrides::Cameras) : true; // open that sucker - PT(GraphicsWindow) win = pipe->make_window(props); + PT(GraphicsWindow) win = engine->make_window(pipe); if(win == (GraphicsWindow *)NULL) { chancfg_cat.error() << "Could not create window" << endl; _graphics_window = (GraphicsWindow *)NULL; return; } + win->request_properties(props); + win->set_clear_color(Colorf(win_background_r, win_background_g, + win_background_b, 1.0f)); + // make channels and display regions ChanViewport V(0.0f, 1.0f, 0.0f, 1.0f); chan_eval(win, W, L, S, V, W.getChanOffset()+1, sizeX, sizeY, @@ -459,9 +465,7 @@ ChanConfig::ChanConfig(GraphicsPipe* pipe, std::string cfg, const NodePath &rend // sanity check if (config_sanity_check) { nout << "ChanConfig Sanity check:" << endl - << "window - " << (void*)win << endl - << " width = " << win->get_width() << " height = " << win->get_height() << endl - << " xorig = " << win->get_xorg() << " yorig = " << win->get_yorg()<< endl; + << "window - " << (void*)win << endl; int max_channel_index = win->get_max_channel_index(); for (int c = 0; c < max_channel_index; c++) { diff --git a/panda/src/chancfg/chancfg.h b/panda/src/chancfg/chancfg.h index c85d04bcc1..f9e9a7054f 100644 --- a/panda/src/chancfg/chancfg.h +++ b/panda/src/chancfg/chancfg.h @@ -26,13 +26,15 @@ #include "chanwindow.h" #include "chanshare.h" -#include "graphicsPipe.h" #include "graphicsWindow.h" #include "pandaNode.h" #include "nodePath.h" #include "pmap.h" +class GraphicsEngine; +class GraphicsPipe; + class EXPCL_PANDA ChanCfgOverrides { public: enum Field { OrigX, OrigY, SizeX, SizeY, Title, Mask, Cameras }; @@ -114,8 +116,9 @@ private: SVec& S, ChanViewport& V, int hw_offset, int xsize, int ysize, const NodePath &render, bool want_cameras); PUBLISHED: - ChanConfig(GraphicsPipe*, std::string, const NodePath &render, - ChanCfgOverrides& = ChanOverrideNone); + ChanConfig(GraphicsEngine *engine, GraphicsPipe *pipe, + std::string cfg, const NodePath &render, + ChanCfgOverrides& = ChanOverrideNone); INLINE PandaNode *get_group_node(const int node_index) const; INLINE int get_group_membership(const int dr_index) const; INLINE int get_num_groups(void) const; diff --git a/panda/src/device/mouseAndKeyboard.cxx b/panda/src/device/mouseAndKeyboard.cxx index e46299eefc..1acafc710c 100644 --- a/panda/src/device/mouseAndKeyboard.cxx +++ b/panda/src/device/mouseAndKeyboard.cxx @@ -78,8 +78,9 @@ do_transmit_data(const DataNodeTransmit &, DataNodeTransmit &output) { _pixel_xy->set_value(LPoint2f(mdata._xpos, mdata._ypos)); output.set_data(_pixel_xy_output, EventParameter(_pixel_xy)); - int w = _window->get_width(); - int h = _window->get_height(); + WindowProperties properties = _window->get_properties(); + int w = properties.get_x_size(); + int h = properties.get_y_size(); // Normalize pixel motion to range [-1,1]. float xf = (float)(2 * mdata._xpos) / (float)w - 1.0f; diff --git a/panda/src/display/Sources.pp b/panda/src/display/Sources.pp index 3185f2a7bd..1169fa4385 100644 --- a/panda/src/display/Sources.pp +++ b/panda/src/display/Sources.pp @@ -10,39 +10,41 @@ #define COMBINED_SOURCES $[TARGET]_composite1.cxx $[TARGET]_composite2.cxx #define SOURCES \ - config_display.h \ - clearableRegion.I clearableRegion.h \ - displayRegion.I displayRegion.h \ - displayRegionStack.I \ - displayRegionStack.h \ - frameBufferStack.I frameBufferStack.h \ - geomContext.I geomContext.h geomNodeContext.I geomNodeContext.h \ - graphicsChannel.I graphicsChannel.h \ - graphicsEngine.I graphicsEngine.h \ - graphicsLayer.I \ - graphicsLayer.h graphicsPipe.I graphicsPipe.N graphicsPipe.h \ - graphicsStateGuardian.I graphicsStateGuardian.N \ - graphicsStateGuardian.h graphicsWindow.I graphicsWindow.N \ - graphicsWindow.h graphicsWindowInputDevice.I \ - graphicsWindowInputDevice.h hardwareChannel.I \ - hardwareChannel.h interactiveGraphicsPipe.I \ - interactiveGraphicsPipe.h \ - lensStack.I lensStack.h \ - noninteractiveGraphicsPipe.I \ - noninteractiveGraphicsPipe.h pipeSpec.I pipeSpec.h \ - savedFrameBuffer.I savedFrameBuffer.h - + config_display.h \ + clearableRegion.I clearableRegion.h \ + displayRegion.I displayRegion.h \ + displayRegionStack.I \ + displayRegionStack.h \ + frameBufferStack.I frameBufferStack.h \ + geomContext.I geomContext.h geomNodeContext.I geomNodeContext.h \ + graphicsChannel.I graphicsChannel.h \ + graphicsEngine.I graphicsEngine.h \ + graphicsLayer.I \ + graphicsLayer.h graphicsPipe.I graphicsPipe.h \ + graphicsPipeSelection.I graphicsPipeSelection.h \ + graphicsStateGuardian.I \ + graphicsStateGuardian.h graphicsWindow.I \ + graphicsWindow.h graphicsWindowInputDevice.I \ + graphicsWindowInputDevice.h \ + windowProperties.I windowProperties.h \ + hardwareChannel.I \ + hardwareChannel.h \ + lensStack.I lensStack.h \ + savedFrameBuffer.I savedFrameBuffer.h + #define INCLUDED_SOURCES \ - config_display.cxx \ - clearableRegion.cxx \ - displayRegion.cxx \ - geomContext.cxx geomNodeContext.cxx graphicsChannel.cxx \ - graphicsEngine.cxx \ - graphicsLayer.cxx graphicsPipe.cxx graphicsStateGuardian.cxx \ - graphicsWindow.cxx graphicsWindowInputDevice.cxx \ - hardwareChannel.cxx interactiveGraphicsPipe.cxx \ - noninteractiveGraphicsPipe.cxx pipeSpec.cxx \ - savedFrameBuffer.cxx + config_display.cxx \ + clearableRegion.cxx \ + displayRegion.cxx \ + geomContext.cxx geomNodeContext.cxx graphicsChannel.cxx \ + graphicsEngine.cxx \ + graphicsLayer.cxx graphicsPipe.cxx \ + graphicsPipeSelection.cxx \ + graphicsStateGuardian.cxx \ + graphicsWindow.cxx graphicsWindowInputDevice.cxx \ + windowProperties.cxx \ + hardwareChannel.cxx \ + savedFrameBuffer.cxx #define INSTALL_HEADERS \ config_display.h \ @@ -54,14 +56,15 @@ graphicsChannel.I graphicsChannel.h \ graphicsEngine.I graphicsEngine.h \ graphicsLayer.I graphicsLayer.h \ - graphicsPipe.I graphicsPipe.h graphicsStateGuardian.I \ + graphicsPipe.I graphicsPipe.h \ + graphicsPipeSelection.I graphicsPipeSelection.h \ + graphicsStateGuardian.I \ graphicsStateGuardian.h graphicsWindow.I graphicsWindow.h \ graphicsWindowInputDevice.I graphicsWindowInputDevice.h \ - hardwareChannel.I hardwareChannel.h interactiveGraphicsPipe.I \ - interactiveGraphicsPipe.h \ + windowProperties.I windowProperties.h \ + hardwareChannel.I hardwareChannel.h \ lensStack.I lensStack.h \ - noninteractiveGraphicsPipe.I \ - noninteractiveGraphicsPipe.h pipeSpec.I pipeSpec.h renderBuffer.h \ + renderBuffer.h \ savedFrameBuffer.I savedFrameBuffer.h #define IGATESCAN all diff --git a/panda/src/display/clearableRegion.h b/panda/src/display/clearableRegion.h index f2204a7e3b..688a16dfe8 100644 --- a/panda/src/display/clearableRegion.h +++ b/panda/src/display/clearableRegion.h @@ -53,6 +53,7 @@ PUBLISHED: INLINE bool is_any_clear_active() const; private: + // This data needs to be cycled. enum Flags { F_clear_color_active = 0x0001, F_clear_depth_active = 0x0002, diff --git a/panda/src/display/config_display.cxx b/panda/src/display/config_display.cxx index 56d9e3da1e..12cc61da8e 100644 --- a/panda/src/display/config_display.cxx +++ b/panda/src/display/config_display.cxx @@ -21,8 +21,6 @@ #include "graphicsStateGuardian.h" #include "savedFrameBuffer.h" #include "graphicsPipe.h" -#include "interactiveGraphicsPipe.h" -#include "noninteractiveGraphicsPipe.h" #include "graphicsWindow.h" #include "graphicsChannel.h" #include "graphicsLayer.h" @@ -36,28 +34,11 @@ NotifyCategoryDef(display, ""); NotifyCategoryDef(gsg, display_cat); static Config::ConfigTable::Symbol *disp; -static Config::ConfigTable::Symbol *guard; -static Config::ConfigTable::Symbol *preferred_pipe; -static Config::ConfigTable::Symbol *preferred_window; -static Config::ConfigTable::Symbol *preferred_gsg; ConfigureFn(config_display) { init_libdisplay(); } -const string pipe_spec_machine = config_display.GetString("pipe-machine", ""); -const string pipe_spec_filename = config_display.GetString("pipe-filename", - "outfile-%03f.rib"); -const int pipe_spec_pipe_number = config_display.GetInt("pipe-number", -1); -const bool pipe_spec_is_file = config_display.Defined("pipe-filename") - || config_display.GetBool("pipe-file", false); -const bool pipe_spec_is_remote = config_display.Defined("pipe-machine") - || config_display.GetBool("pipe-remote", - false); - -const bool compare_state_by_pointer = -config_display.GetBool("compare-state-by-pointer", true); - // This is normally true; set it false to disable view-frustum culling // (primarily useful for debugging). const bool view_frustum_cull = config_display.GetBool("view-frustum-cull", true); @@ -67,59 +48,32 @@ const bool view_frustum_cull = config_display.GetBool("view-frustum-cull", true) // of per-frame overhead to count these things up. const bool pstats_unused_states = config_display.GetBool("pstats-unused-states", false); -// This is the default threading model to use when the GraphicsEngine -// is created, e.g. app-cull-draw or appculldraw or some such. (See -// GraphicsEngine::set_threading_model()). +// This is the default threading model to use for new windows. Use +// empty string for single-threaded, or something like "cull/draw" for +// a 3-stage pipeline. See GraphicsEngine::set_threading_model(). // Warning! The code that uses this is currently experimental and // incomplete, and will almost certainly crash! Do not set // threading-model to anything other than its default of a // single-threaded model unless you are developing Panda's threading // system! -const string threading_model = config_display.GetString("threading-model", "appculldraw"); +const string threading_model = config_display.GetString("threading-model", ""); + +// Use this to specify a particular pipe you prefer to use, when more +// than one GraphicsPipe is available (for instance, if both GL and DX +// are linked in). This should be the name of the type preferred, or +// a substring unique to the type name. +const string preferred_pipe = config_display.GetString("preferred-pipe", ""); -Config::ConfigTable::Symbol::iterator pipe_modules_begin(void) { +Config::ConfigTable::Symbol::iterator display_modules_begin(void) { return disp->begin(); } -Config::ConfigTable::Symbol::iterator pipe_modules_end(void) { +Config::ConfigTable::Symbol::iterator display_modules_end(void) { return disp->end(); } -Config::ConfigTable::Symbol::iterator gsg_modules_begin(void) { - return guard->begin(); -} - -Config::ConfigTable::Symbol::iterator gsg_modules_end(void) { - return guard->end(); -} - - -Config::ConfigTable::Symbol::iterator preferred_pipe_begin(void) { - return preferred_pipe->begin(); -} - -Config::ConfigTable::Symbol::iterator preferred_pipe_end(void) { - return preferred_pipe->end(); -} - -Config::ConfigTable::Symbol::iterator preferred_window_begin(void) { - return preferred_window->begin(); -} - -Config::ConfigTable::Symbol::iterator preferred_window_end(void) { - return preferred_window->end(); -} - -Config::ConfigTable::Symbol::iterator preferred_gsg_begin(void) { - return preferred_gsg->begin(); -} - -Config::ConfigTable::Symbol::iterator preferred_gsg_end(void) { - return preferred_gsg->end(); -} - //////////////////////////////////////////////////////////////////// // Function: init_libdisplay // Description: Initializes the library. This must be called at @@ -141,14 +95,7 @@ init_libdisplay() { GraphicsStateGuardian::GsgWindow::init_type(); SavedFrameBuffer::init_type(); GraphicsPipe::init_type(); - GraphicsPipe::PipeParam::init_type(); - GraphicsPipe::PipeSpec::init_type(); - InteractiveGraphicsPipe::init_type(); - NoninteractiveGraphicsPipe::init_type(); GraphicsWindow::init_type(); - GraphicsWindow::WindowParam::init_type(); - GraphicsWindow::WindowProps::init_type(); - GraphicsWindow::WindowPipe::init_type(); GraphicsChannel::init_type(); GraphicsLayer::init_type(); HardwareChannel::init_type(); @@ -157,15 +104,5 @@ init_libdisplay() { GeomContext::init_type(); disp = new Config::ConfigTable::Symbol; - guard = new Config::ConfigTable::Symbol; - preferred_pipe = new Config::ConfigTable::Symbol; - preferred_window = new Config::ConfigTable::Symbol; - preferred_gsg = new Config::ConfigTable::Symbol; - config_display.GetAll("load-display", *disp); - config_display.GetAll("load-gsg", *guard); - - config_display.GetAll("preferred-pipe", *preferred_pipe); - config_display.GetAll("preferred-window", *preferred_window); - config_display.GetAll("preferred-gsg", *preferred_gsg); } diff --git a/panda/src/display/config_display.h b/panda/src/display/config_display.h index cd789ce9e9..14cb2f2c72 100644 --- a/panda/src/display/config_display.h +++ b/panda/src/display/config_display.h @@ -29,29 +29,14 @@ NotifyCategoryDecl(display, EXPCL_PANDA, EXPTP_PANDA); NotifyCategoryDecl(gsg, EXPCL_PANDA, EXPTP_PANDA); -extern const string pipe_spec_machine; -extern const string pipe_spec_filename; -extern const int pipe_spec_pipe_number; -extern const bool pipe_spec_is_file; -extern const bool pipe_spec_is_remote; - -extern const bool compare_state_by_pointer; extern const bool view_frustum_cull; extern const bool pstats_unused_states; extern const string threading_model; +extern const string preferred_pipe; -extern Config::ConfigTable::Symbol::iterator pipe_modules_begin(void); -extern Config::ConfigTable::Symbol::iterator pipe_modules_end(void); -extern Config::ConfigTable::Symbol::iterator gsg_modules_begin(void); -extern Config::ConfigTable::Symbol::iterator gsg_modules_end(void); - -extern Config::ConfigTable::Symbol::iterator preferred_pipe_begin(); -extern Config::ConfigTable::Symbol::iterator preferred_pipe_end(); -extern Config::ConfigTable::Symbol::iterator preferred_window_begin(); -extern Config::ConfigTable::Symbol::iterator preferred_window_end(); -extern Config::ConfigTable::Symbol::iterator preferred_gsg_begin(); -extern Config::ConfigTable::Symbol::iterator preferred_gsg_end(); +extern Config::ConfigTable::Symbol::iterator display_modules_begin(void); +extern Config::ConfigTable::Symbol::iterator display_modules_end(void); extern EXPCL_PANDA void init_libdisplay(); diff --git a/panda/src/display/displayRegion.I b/panda/src/display/displayRegion.I index 3973366ee3..cb11cfd6f2 100644 --- a/panda/src/display/displayRegion.I +++ b/panda/src/display/displayRegion.I @@ -16,110 +16,10 @@ // //////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////// -// Function: DisplayRegion::get_dimensions -// Access: Public -// Description: Retrieves the coordinates of the DisplayRegion's -// rectangle within its GraphicsLayer. These numbers -// will be in the range [0..1]. -//////////////////////////////////////////////////////////////////// -INLINE void DisplayRegion:: -get_dimensions(float &l, float &r, float &b, float &t) const { - l = _l; - r = _r; - b = _b; - t = _t; -} - -//////////////////////////////////////////////////////////////////// -// Function: DisplayRegion::get_left -// Access: Public -// Description: Retrieves the x coordinate of the left edge of the -// rectangle within its GraphicsLayer. This number -// will be in the range [0..1]. -//////////////////////////////////////////////////////////////////// -INLINE float DisplayRegion:: -get_left() const { - return _l; -} - -//////////////////////////////////////////////////////////////////// -// Function: DisplayRegion::get_right -// Access: Public -// Description: Retrieves the x coordinate of the right edge of the -// rectangle within its GraphicsLayer. This number -// will be in the range [0..1]. -//////////////////////////////////////////////////////////////////// -INLINE float DisplayRegion:: -get_right() const { - return _r; -} - -//////////////////////////////////////////////////////////////////// -// Function: DisplayRegion::get_bottom -// Access: Public -// Description: Retrieves the y coordinate of the bottom edge of -// the rectangle within its GraphicsLayer. This -// number will be in the range [0..1]. -//////////////////////////////////////////////////////////////////// -INLINE float DisplayRegion:: -get_bottom() const { - return _b; -} - -//////////////////////////////////////////////////////////////////// -// Function: DisplayRegion::get_top -// Access: Public -// Description: Retrieves the y coordinate of the top edge of the -// rectangle within its GraphicsLayer. This number -// will be in the range [0..1]. -//////////////////////////////////////////////////////////////////// -INLINE float DisplayRegion:: -get_top() const { - return _t; -} - -//////////////////////////////////////////////////////////////////// -// Function: DisplayRegion::get_layer -// Access: Public -// Description: Returns the layer associated with this particular -// DisplayRegion, or NULL if no layer is associated -// (or if the layer was deleted). -//////////////////////////////////////////////////////////////////// -INLINE GraphicsLayer *DisplayRegion:: -get_layer() const { - return _layer; -} - -//////////////////////////////////////////////////////////////////// -// Function: DisplayRegion::get_camera -// Access: Public -// Description: Returns the camera associated with this -// DisplayRegion, or NULL if no camera is associated. -//////////////////////////////////////////////////////////////////// -INLINE const NodePath &DisplayRegion:: -get_camera() const { - return _camera; -} - -//////////////////////////////////////////////////////////////////// -// Function: DisplayRegion::set_active -// Access: Public -// Description: Sets the active flag associated with the -// DisplayRegion. If the DisplayRegion is marked -// inactive, nothing is rendered. -//////////////////////////////////////////////////////////////////// -INLINE void DisplayRegion:: -set_active(bool active) { - if (active != _active) { - _active = active; - win_display_regions_changed(); - } -} //////////////////////////////////////////////////////////////////// // Function: DisplayRegion::is_active -// Access: Public +// Access: Published // Description: Returns the active flag associated with the // DisplayRegion. //////////////////////////////////////////////////////////////////// @@ -129,67 +29,17 @@ is_active() const { } //////////////////////////////////////////////////////////////////// -// Function: DisplayRegion::compute_pixels -// Access: Public -// Description: Computes the pixel locations of the DisplayRegion -// within its layer, given the size of the layer in -// pixels. +// Function: DisplayRegion::do_compute_pixels +// Access: Private +// Description: The private implementation of compute_pixels, this +// assumes that we already have the lock. //////////////////////////////////////////////////////////////////// INLINE void DisplayRegion:: -compute_pixels(const int x, const int y) { - _pl = int((_l * x) + 0.5); - _pr = int((_r * x) + 0.5); - _pb = int((_b * y) + 0.5); - _pt = int((_t * y) + 0.5); -} - -//////////////////////////////////////////////////////////////////// -// Function: DisplayRegion::get_pixels -// Access: Public -// Description: Retrieves the coordinates of the DisplayRegion within -// its layer, in pixels. -//////////////////////////////////////////////////////////////////// -INLINE void DisplayRegion:: -get_pixels(int &pl, int &pr, int &pb, int &pt) const { - pl = _pl; - pr = _pr; - pb = _pb; - pt = _pt; -} - -//////////////////////////////////////////////////////////////////// -// Function: DisplayRegion::get_region_pixels -// Access: Public -// Description: Retrieves the coordinates of the DisplayRegion within -// its layer, as the pixel location of its bottom-left -// corner, along with a pixel width and height. -//////////////////////////////////////////////////////////////////// -INLINE void DisplayRegion:: -get_region_pixels(int &xo, int &yo, int &w, int &h) const { - xo = _pl; - yo = _pb; - w = _pr - _pl; - h = _pt - _pb; -} - -//////////////////////////////////////////////////////////////////// -// Function: DisplayRegion::get_pixel_width -// Access: Public -// Description: Returns the width of the DisplayRegion in pixels. -//////////////////////////////////////////////////////////////////// -INLINE int DisplayRegion:: -get_pixel_width() const { - return _pr - _pl; -} - -//////////////////////////////////////////////////////////////////// -// Function: DisplayRegion::get_pixel_height -// Access: Public -// Description: Returns the height of the DisplayRegion in pixels. -//////////////////////////////////////////////////////////////////// -INLINE int DisplayRegion:: -get_pixel_height() const { - return _pt - _pb; +do_compute_pixels(int x_size, int y_size) { + _pl = int((_l * x_size) + 0.5); + _pr = int((_r * x_size) + 0.5); + _pb = int((_b * y_size) + 0.5); + _pt = int((_t * y_size) + 0.5); } diff --git a/panda/src/display/displayRegion.cxx b/panda/src/display/displayRegion.cxx index 8af8944c16..9631315611 100644 --- a/panda/src/display/displayRegion.cxx +++ b/panda/src/display/displayRegion.cxx @@ -24,6 +24,7 @@ #include "displayRegion.h" #include "camera.h" #include "dcast.h" +#include "mutexHolder.h" //////////////////////////////////////////////////////////////////// @@ -38,6 +39,7 @@ DisplayRegion(GraphicsLayer *layer) : _camera_node((Camera *)NULL), _active(true) { + compute_pixels(); } //////////////////////////////////////////////////////////////////// @@ -53,6 +55,7 @@ DisplayRegion(GraphicsLayer *layer, const float l, _camera_node((Camera *)NULL), _active(true) { + compute_pixels(); } //////////////////////////////////////////////////////////////////// @@ -102,9 +105,77 @@ DisplayRegion:: set_camera(NodePath()); } +//////////////////////////////////////////////////////////////////// +// Function: DisplayRegion::get_dimensions +// Access: Published +// Description: Retrieves the coordinates of the DisplayRegion's +// rectangle within its GraphicsLayer. These numbers +// will be in the range [0..1]. +//////////////////////////////////////////////////////////////////// +void DisplayRegion:: +get_dimensions(float &l, float &r, float &b, float &t) const { + MutexHolder holder(_lock); + l = _l; + r = _r; + b = _b; + t = _t; +} + +//////////////////////////////////////////////////////////////////// +// Function: DisplayRegion::get_left +// Access: Published +// Description: Retrieves the x coordinate of the left edge of the +// rectangle within its GraphicsLayer. This number +// will be in the range [0..1]. +//////////////////////////////////////////////////////////////////// +float DisplayRegion:: +get_left() const { + MutexHolder holder(_lock); + return _l; +} + +//////////////////////////////////////////////////////////////////// +// Function: DisplayRegion::get_right +// Access: Published +// Description: Retrieves the x coordinate of the right edge of the +// rectangle within its GraphicsLayer. This number +// will be in the range [0..1]. +//////////////////////////////////////////////////////////////////// +float DisplayRegion:: +get_right() const { + MutexHolder holder(_lock); + return _r; +} + +//////////////////////////////////////////////////////////////////// +// Function: DisplayRegion::get_bottom +// Access: Published +// Description: Retrieves the y coordinate of the bottom edge of +// the rectangle within its GraphicsLayer. This +// number will be in the range [0..1]. +//////////////////////////////////////////////////////////////////// +float DisplayRegion:: +get_bottom() const { + MutexHolder holder(_lock); + return _b; +} + +//////////////////////////////////////////////////////////////////// +// Function: DisplayRegion::get_top +// Access: Published +// Description: Retrieves the y coordinate of the top edge of the +// rectangle within its GraphicsLayer. This number +// will be in the range [0..1]. +//////////////////////////////////////////////////////////////////// +float DisplayRegion:: +get_top() const { + MutexHolder holder(_lock); + return _t; +} + //////////////////////////////////////////////////////////////////// // Function: DisplayRegion::set_dimensions -// Access: Public +// Access: Published // Description: Changes the portion of the framebuffer this // DisplayRegion corresponds to. The parameters range // from 0 to 1, where 0,0 is the lower left corner and @@ -113,6 +184,7 @@ DisplayRegion:: //////////////////////////////////////////////////////////////////// void DisplayRegion:: set_dimensions(float l, float r, float b, float t) { + MutexHolder holder(_lock); _l = l; _r = r; _b = b; @@ -120,49 +192,68 @@ set_dimensions(float l, float r, float b, float t) { const GraphicsWindow *win = get_window(); if (win != (GraphicsWindow *)NULL) { - compute_pixels(win->get_width(), win->get_height()); + WindowProperties properties = win->get_properties(); + if (properties.has_size()) { + do_compute_pixels(properties.get_x_size(), properties.get_y_size()); + } } } +//////////////////////////////////////////////////////////////////// +// Function: DisplayRegion::get_layer +// Access: Published +// Description: Returns the layer associated with this particular +// DisplayRegion, or NULL if no layer is associated +// (or if the layer was deleted). +//////////////////////////////////////////////////////////////////// +GraphicsLayer *DisplayRegion:: +get_layer() const { + MutexHolder holder(_lock); + return _layer; +} + //////////////////////////////////////////////////////////////////// // Function: DisplayRegion::get_channel -// Access: Public +// Access: Published // Description: Returns the GraphicsChannel that this DisplayRegion is // ultimately associated with, or NULL if no channel is // associated. //////////////////////////////////////////////////////////////////// GraphicsChannel *DisplayRegion:: get_channel() const { + MutexHolder holder(_lock); return (_layer != (GraphicsLayer *)NULL) ? _layer->get_channel() : NULL; } //////////////////////////////////////////////////////////////////// // Function: DisplayRegion::get_window -// Access: Public +// Access: Published // Description: Returns the GraphicsWindow that this DisplayRegion is // ultimately associated with, or NULL if no window is // associated. //////////////////////////////////////////////////////////////////// GraphicsWindow *DisplayRegion:: get_window() const { + MutexHolder holder(_lock); return (_layer != (GraphicsLayer *)NULL) ? _layer->get_window() : NULL; } //////////////////////////////////////////////////////////////////// // Function: DisplayRegion::get_pipe -// Access: Public +// Access: Published // Description: Returns the GraphicsPipe that this DisplayRegion is // ultimately associated with, or NULL if no pipe is // associated. //////////////////////////////////////////////////////////////////// GraphicsPipe *DisplayRegion:: get_pipe() const { + MutexHolder holder(_lock); return (_layer != (GraphicsLayer *)NULL) ? _layer->get_pipe() : NULL; } //////////////////////////////////////////////////////////////////// // Function: DisplayRegion::set_camera -// Access: Public +// Access: Published // Description: Sets the camera that is associated with this // DisplayRegion. There is a one-to-one association // between cameras and DisplayRegions; if this camera @@ -175,6 +266,7 @@ get_pipe() const { //////////////////////////////////////////////////////////////////// void DisplayRegion:: set_camera(const NodePath &camera) { + MutexHolder holder(_lock); Camera *camera_node = (Camera *)NULL; if (!camera.is_empty()) { DCAST_INTO_V(camera_node, camera.node()); @@ -195,13 +287,135 @@ set_camera(const NodePath &camera) { _camera = camera; } +//////////////////////////////////////////////////////////////////// +// Function: DisplayRegion::get_camera +// Access: Published +// Description: Returns the camera associated with this +// DisplayRegion, or NULL if no camera is associated. +//////////////////////////////////////////////////////////////////// +const NodePath &DisplayRegion:: +get_camera() const { + MutexHolder holder(_lock); + return _camera; +} + +//////////////////////////////////////////////////////////////////// +// Function: DisplayRegion::set_active +// Access: Published +// Description: Sets the active flag associated with the +// DisplayRegion. If the DisplayRegion is marked +// inactive, nothing is rendered. +//////////////////////////////////////////////////////////////////// +void DisplayRegion:: +set_active(bool active) { + MutexHolder holder(_lock); + if (active != _active) { + _active = active; + win_display_regions_changed(); + } +} + +//////////////////////////////////////////////////////////////////// +// Function: DisplayRegion::compute_pixels +// Access: Published +// Description: Computes the pixel locations of the DisplayRegion +// within its layer. The DisplayRegion will request the +// size from the window. +//////////////////////////////////////////////////////////////////// +void DisplayRegion:: +compute_pixels() { + const GraphicsWindow *win = get_window(); + if (win != (GraphicsWindow *)NULL) { + MutexHolder holder(_lock); + WindowProperties properties = win->get_properties(); + if (!properties.has_size()) { + // If the window doesn't know its size yet, maybe it will + // eventually be given the size it's requesting. + properties = win->get_requested_properties(); + } + + if (properties.has_size()) { + do_compute_pixels(properties.get_x_size(), properties.get_y_size()); + } else { + do_compute_pixels(0, 0); + } + } +} + +//////////////////////////////////////////////////////////////////// +// Function: DisplayRegion::compute_pixels +// Access: Published +// Description: Computes the pixel locations of the DisplayRegion +// within its layer, given the size of the layer in +// pixels. +//////////////////////////////////////////////////////////////////// +void DisplayRegion:: +compute_pixels(int x_size, int y_size) { + MutexHolder holder(_lock); + do_compute_pixels(x_size, y_size); +} + +//////////////////////////////////////////////////////////////////// +// Function: DisplayRegion::get_pixels +// Access: Published +// Description: Retrieves the coordinates of the DisplayRegion within +// its layer, in pixels. +//////////////////////////////////////////////////////////////////// +void DisplayRegion:: +get_pixels(int &pl, int &pr, int &pb, int &pt) const { + MutexHolder holder(_lock); + pl = _pl; + pr = _pr; + pb = _pb; + pt = _pt; +} + +//////////////////////////////////////////////////////////////////// +// Function: DisplayRegion::get_region_pixels +// Access: Published +// Description: Retrieves the coordinates of the DisplayRegion within +// its layer, as the pixel location of its bottom-left +// corner, along with a pixel width and height. +//////////////////////////////////////////////////////////////////// +void DisplayRegion:: +get_region_pixels(int &xo, int &yo, int &w, int &h) const { + MutexHolder holder(_lock); + xo = _pl; + yo = _pb; + w = _pr - _pl; + h = _pt - _pb; +} + +//////////////////////////////////////////////////////////////////// +// Function: DisplayRegion::get_pixel_width +// Access: Published +// Description: Returns the width of the DisplayRegion in pixels. +//////////////////////////////////////////////////////////////////// +int DisplayRegion:: +get_pixel_width() const { + MutexHolder holder(_lock); + return _pr - _pl; +} + +//////////////////////////////////////////////////////////////////// +// Function: DisplayRegion::get_pixel_height +// Access: Published +// Description: Returns the height of the DisplayRegion in pixels. +//////////////////////////////////////////////////////////////////// +int DisplayRegion:: +get_pixel_height() const { + MutexHolder holder(_lock); + return _pt - _pb; +} + //////////////////////////////////////////////////////////////////// // Function: DisplayRegion::output -// Access: Public +// Access: Published // Description: //////////////////////////////////////////////////////////////////// void DisplayRegion:: output(ostream &out) const { + MutexHolder holder(_lock); out << "DisplayRegion(" << _l << " " << _r << " " << _b << " " << _t << ")=pixels(" << _pl << " " << _pr << " " << _pb << " " << _pt << ")"; @@ -209,11 +423,12 @@ output(ostream &out) const { //////////////////////////////////////////////////////////////////// // Function: DisplayRegion::win_display_regions_changed -// Access: Public +// Access: Private // Description: Intended to be called when the active state on a // nested channel or layer or display region changes, // forcing the window to recompute its list of active -// display regions. +// display regions. It is assumed the lock is already +// held. //////////////////////////////////////////////////////////////////// void DisplayRegion:: win_display_regions_changed() { diff --git a/panda/src/display/displayRegion.h b/panda/src/display/displayRegion.h index 56b5f455dd..0757e65aa7 100644 --- a/panda/src/display/displayRegion.h +++ b/panda/src/display/displayRegion.h @@ -25,6 +25,7 @@ #include "nodePath.h" #include "cullResult.h" #include "pointerTo.h" +#include "mutex.h" #include "plist.h" @@ -41,50 +42,51 @@ class Camera; //////////////////////////////////////////////////////////////////// class EXPCL_PANDA DisplayRegion : public ReferenceCount, public ClearableRegion { public: - DisplayRegion(GraphicsLayer *); - DisplayRegion(GraphicsLayer *, + DisplayRegion(GraphicsLayer *layer); + DisplayRegion(GraphicsLayer *layer, const float l, const float r, const float b, const float t); DisplayRegion(int xsize, int ysize); private: - DisplayRegion(const DisplayRegion &); - void operator = (const DisplayRegion &); + DisplayRegion(const DisplayRegion ©); + void operator = (const DisplayRegion ©); public: ~DisplayRegion(); PUBLISHED: - INLINE void get_dimensions(float &l, float &r, float &b, float &t) const; - INLINE float get_left() const; - INLINE float get_right() const; - INLINE float get_bottom() const; - INLINE float get_top() const; + void get_dimensions(float &l, float &r, float &b, float &t) const; + float get_left() const; + float get_right() const; + float get_bottom() const; + float get_top() const; void set_dimensions(float l, float r, float b, float t); - INLINE GraphicsLayer *get_layer() const; + GraphicsLayer *get_layer() const; GraphicsChannel *get_channel() const; GraphicsWindow *get_window() const; GraphicsPipe *get_pipe() const; void set_camera(const NodePath &camera); - INLINE const NodePath &get_camera() const; + const NodePath &get_camera() const; - INLINE void set_active(bool active); + void set_active(bool active); INLINE bool is_active() const; - INLINE void compute_pixels(const int x, const int y); - INLINE void get_pixels(int &pl, int &pr, int &pb, int &pt) const; - INLINE void get_region_pixels(int &xo, int &yo, int &w, int &h) const; + void compute_pixels(); + void compute_pixels(int x_size, int y_size); + void get_pixels(int &pl, int &pr, int &pb, int &pt) const; + void get_region_pixels(int &xo, int &yo, int &w, int &h) const; - INLINE int get_pixel_width() const; - INLINE int get_pixel_height() const; + int get_pixel_width() const; + int get_pixel_height() const; void output(ostream &out) const; -public: +private: void win_display_regions_changed(); - -protected: + INLINE void do_compute_pixels(int x_size, int y_size); + Mutex _lock; float _l; float _r; diff --git a/panda/src/display/display_composite2.cxx b/panda/src/display/display_composite2.cxx index c7699fd783..ca3133cd3d 100644 --- a/panda/src/display/display_composite2.cxx +++ b/panda/src/display/display_composite2.cxx @@ -1,6 +1,5 @@ #include "config_display.cxx" +#include "graphicsPipeSelection.cxx" #include "hardwareChannel.cxx" -#include "interactiveGraphicsPipe.cxx" -#include "noninteractiveGraphicsPipe.cxx" -#include "pipeSpec.cxx" #include "savedFrameBuffer.cxx" +#include "windowProperties.cxx" diff --git a/panda/src/display/graphicsChannel.I b/panda/src/display/graphicsChannel.I index 80388afc36..60f8625e97 100644 --- a/panda/src/display/graphicsChannel.I +++ b/panda/src/display/graphicsChannel.I @@ -17,20 +17,6 @@ //////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////// -// Function: GraphicsChannel::set_active -// Access: Public -// Description: Sets the active flag on the channel. If the channel -// is marked as inactive, nothing will be rendered. -//////////////////////////////////////////////////////////////////// -INLINE void GraphicsChannel:: -set_active(bool active) { - if (active != _is_active) { - _is_active = active; - win_display_regions_changed(); - } -} - //////////////////////////////////////////////////////////////////// // Function: GraphicsChannel::is_active // Access: Public diff --git a/panda/src/display/graphicsChannel.cxx b/panda/src/display/graphicsChannel.cxx index c866f2856a..5b87d231ad 100644 --- a/panda/src/display/graphicsChannel.cxx +++ b/panda/src/display/graphicsChannel.cxx @@ -18,18 +18,17 @@ #include "graphicsChannel.h" #include "graphicsWindow.h" +#include "graphicsLayer.h" #include "config_display.h" +#include "mutexHolder.h" #include "pmap.h" -//////////////////////////////////////////////////////////////////// -// Static variables -//////////////////////////////////////////////////////////////////// TypeHandle GraphicsChannel::_type_handle; //////////////////////////////////////////////////////////////////// // Function: GraphicsChannel::Constructor -// Access: Public +// Access: Protected // Description: //////////////////////////////////////////////////////////////////// GraphicsChannel:: @@ -41,7 +40,9 @@ GraphicsChannel() { //////////////////////////////////////////////////////////////////// // Function: GraphicsChannel::Constructor // Access: Public -// Description: +// Description: This is public just so derived window types can +// easily call it. Don't call it directly; instead, use +// GraphicsWindow::get_channel() to get a channel. //////////////////////////////////////////////////////////////////// GraphicsChannel:: GraphicsChannel(GraphicsWindow *window) @@ -56,9 +57,8 @@ GraphicsChannel(GraphicsWindow *window) // Description: //////////////////////////////////////////////////////////////////// INLINE GraphicsChannel:: -GraphicsChannel(const GraphicsChannel&) { - display_cat.error() - << "GraphicsChannels should never be copied" << endl; +GraphicsChannel(const GraphicsChannel &) { + nassertv(false); } //////////////////////////////////////////////////////////////////// @@ -66,16 +66,14 @@ GraphicsChannel(const GraphicsChannel&) { // Access: Private // Description: //////////////////////////////////////////////////////////////////// -INLINE GraphicsChannel &GraphicsChannel:: -operator=(const GraphicsChannel&) { - display_cat.error() - << "GraphicsChannels should never be assigned" << endl; - return *this; +INLINE void GraphicsChannel:: +operator = (const GraphicsChannel &) { + nassertv(false); } //////////////////////////////////////////////////////////////////// // Function: GraphicsChannel::Destructor -// Access: Public +// Access: Published // Description: //////////////////////////////////////////////////////////////////// GraphicsChannel:: @@ -88,7 +86,9 @@ GraphicsChannel:: for (li = _layers.begin(); li != _layers.end(); ++li) { - (*li)->_channel = NULL; + GraphicsLayer *layer = (*li); + MutexHolder holder(layer->_lock); + layer->_channel = NULL; } // We don't need to remove ourself from the windows's list of @@ -98,7 +98,7 @@ GraphicsChannel:: //////////////////////////////////////////////////////////////////// // Function: GraphicsChannel::make_layer -// Access: Public +// Access: Published // Description: Creates a new GraphicsLayer, associated with the // window, at the indicated index position. If the // index position negative or past the end of the array, @@ -108,6 +108,7 @@ GraphicsChannel:: //////////////////////////////////////////////////////////////////// GraphicsLayer *GraphicsChannel:: make_layer(int index) { + MutexHolder holder(_lock); PT(GraphicsLayer) layer = new GraphicsLayer(this); if (index < 0 || index >= (int)_layers.size()) { _layers.push_back(layer); @@ -119,29 +120,33 @@ make_layer(int index) { //////////////////////////////////////////////////////////////////// // Function: GraphicsChannel::get_num_layers -// Access: Public +// Access: Published // Description: Returns the number of layers currently associated // with the channel. //////////////////////////////////////////////////////////////////// int GraphicsChannel:: get_num_layers() const { + MutexHolder holder(_lock); return _layers.size(); } //////////////////////////////////////////////////////////////////// // Function: GraphicsChannel::get_layer -// Access: Public +// Access: Published // Description: Returns the nth layer associated with the channel. //////////////////////////////////////////////////////////////////// GraphicsLayer *GraphicsChannel:: get_layer(int index) const { - nassertr(index >= 0 && index < (int)_layers.size(), NULL); - return _layers[index]; + MutexHolder holder(_lock); + if (index >= 0 && index < (int)_layers.size()) { + return _layers[index]; + } + return NULL; } //////////////////////////////////////////////////////////////////// // Function: GraphicsChannel::move_layer -// Access: Public +// Access: Published // Description: Changes the ordering of the layers so that the // indicated layer will move to the indicated position. // If to_index is negative or past the end of the array, @@ -149,6 +154,7 @@ get_layer(int index) const { //////////////////////////////////////////////////////////////////// void GraphicsChannel:: move_layer(int from_index, int to_index) { + MutexHolder holder(_lock); nassertv(from_index >= 0 && from_index < (int)_layers.size()); PT(GraphicsLayer) layer = _layers[from_index]; @@ -170,19 +176,20 @@ move_layer(int from_index, int to_index) { //////////////////////////////////////////////////////////////////// // Function: GraphicsChannel::remove_layer -// Access: Public +// Access: Published // Description: Removes the nth layer. This changes the numbers of // all subsequent layers. //////////////////////////////////////////////////////////////////// void GraphicsChannel:: remove_layer(int index) { + MutexHolder holder(_lock); nassertv(index >= 0 && index < (int)_layers.size()); _layers.erase(_layers.begin() + index); } //////////////////////////////////////////////////////////////////// // Function: GraphicsChannel::get_window -// Access: Public +// Access: Published // Description: Returns the GraphicsWindow that this channel is // associated with. It is possible that the // GraphicsWindow might have been deleted while an @@ -192,21 +199,38 @@ remove_layer(int index) { //////////////////////////////////////////////////////////////////// GraphicsWindow *GraphicsChannel:: get_window() const { + MutexHolder holder(_lock); return _window; } //////////////////////////////////////////////////////////////////// // Function: GraphicsChannel::get_pipe -// Access: Public +// Access: Published // Description: Returns the GraphicsPipe that this channel is // ultimately associated with, or NULL if no pipe is // associated. //////////////////////////////////////////////////////////////////// GraphicsPipe *GraphicsChannel:: get_pipe() const { + MutexHolder holder(_lock); return (_window != (GraphicsWindow *)NULL) ? _window->get_pipe() : NULL; } +//////////////////////////////////////////////////////////////////// +// Function: GraphicsChannel::set_active +// Access: Published +// Description: Sets the active flag on the channel. If the channel +// is marked as inactive, nothing will be rendered. +//////////////////////////////////////////////////////////////////// +void GraphicsChannel:: +set_active(bool active) { + MutexHolder holder(_lock); + if (active != _is_active) { + _is_active = active; + win_display_regions_changed(); + } +} + //////////////////////////////////////////////////////////////////// // Function: GraphicsChannel::window_resized // Access: Public, Virtual @@ -215,25 +239,27 @@ get_pipe() const { // adjust the channel to account for it. //////////////////////////////////////////////////////////////////// void GraphicsChannel:: -window_resized(int x, int y) { +window_resized(int x_size, int y_size) { // By default, a normal GraphicsChannel fills the whole window, and // so when the window resizes so does the channel, by the same // amount. + MutexHolder holder(_lock); GraphicsLayers::iterator li; for (li = _layers.begin(); li != _layers.end(); ++li) { - (*li)->channel_resized(x, y); + (*li)->channel_resized(x_size, y_size); } } //////////////////////////////////////////////////////////////////// // Function: GraphicsChannel::win_display_regions_changed -// Access: Public +// Access: Private // Description: Intended to be called when the active state on a // nested channel or layer or display region changes, // forcing the window to recompute its list of active -// display regions. +// display regions. It is assumed the lock is already +// held. //////////////////////////////////////////////////////////////////// void GraphicsChannel:: win_display_regions_changed() { diff --git a/panda/src/display/graphicsChannel.h b/panda/src/display/graphicsChannel.h index a14a61229c..b024d1936c 100644 --- a/panda/src/display/graphicsChannel.h +++ b/panda/src/display/graphicsChannel.h @@ -17,22 +17,14 @@ //////////////////////////////////////////////////////////////////// #ifndef GRAPHICSCHANNEL_H #define GRAPHICSCHANNEL_H -// -//////////////////////////////////////////////////////////////////// -// Includes -//////////////////////////////////////////////////////////////////// -#include +#include "pandabase.h" #include "graphicsLayer.h" - -#include -#include - +#include "typedReferenceCount.h" +#include "pointerTo.h" +#include "mutex.h" #include "pvector.h" -//////////////////////////////////////////////////////////////////// -// Defines -//////////////////////////////////////////////////////////////////// class GraphicsChannel; class GraphicsPipe; class GraphicsWindow; @@ -48,14 +40,17 @@ class CullHandler; //////////////////////////////////////////////////////////////////// class EXPCL_PANDA GraphicsChannel : public TypedReferenceCount { protected: - GraphicsChannel(); public: - GraphicsChannel(GraphicsWindow *); - virtual ~GraphicsChannel(); + GraphicsChannel(GraphicsWindow *window); + +private: + GraphicsChannel(const GraphicsChannel ©); + void operator = (const GraphicsChannel ©); PUBLISHED: + virtual ~GraphicsChannel(); GraphicsLayer *make_layer(int index = -1); int get_num_layers() const; GraphicsLayer *get_layer(int index) const; @@ -65,28 +60,23 @@ PUBLISHED: GraphicsWindow *get_window() const; GraphicsPipe *get_pipe() const; -public: - virtual void window_resized(int x, int y); - - void win_display_regions_changed(); - -PUBLISHED: - INLINE void set_active(bool active); + void set_active(bool active); INLINE bool is_active() const; +public: + virtual void window_resized(int x_size, int y_size); + private: + void win_display_regions_changed(); + +protected: + Mutex _lock; GraphicsWindow *_window; bool _is_active; typedef pvector< PT(GraphicsLayer) > GraphicsLayers; GraphicsLayers _layers; -private: - - GraphicsChannel(const GraphicsChannel&); - GraphicsChannel& operator=(const GraphicsChannel&); - - public: static TypeHandle get_class_type() { return _type_handle; @@ -105,6 +95,7 @@ private: static TypeHandle _type_handle; friend class GraphicsWindow; + friend class GraphicsLayer; }; #include "graphicsChannel.I" diff --git a/panda/src/display/graphicsEngine.I b/panda/src/display/graphicsEngine.I index 1d538fbbb0..f314a4d9c3 100644 --- a/panda/src/display/graphicsEngine.I +++ b/panda/src/display/graphicsEngine.I @@ -18,28 +18,17 @@ //////////////////////////////////////////////////////////////////// -// Function: GraphicsEngine::get_threading_model +// Function: GraphicsEngine::make_window // Access: Published -// Description: Returns the current threading model in use; see -// set_threading_model(). +// Description: Creates a new window using the indicated GraphicsPipe +// and returns it. The GraphicsEngine becomes the owner +// of the window; it will persist at least until +// remove_window() is called later. +// +// This flavor of make_window() uses the default +// threading model, specified via set_threading_model(). //////////////////////////////////////////////////////////////////// -INLINE GraphicsEngine::ThreadingModel GraphicsEngine:: -get_threading_model() const { - return _threading_model; -} - -//////////////////////////////////////////////////////////////////// -// Function: GraphicsEngine::start_cull -// Access: Private -// Description: Starts the cull stage for the current frame. This -// may or may not execute within a sub-thread, according -// to the current threading model. -//////////////////////////////////////////////////////////////////// -INLINE void GraphicsEngine:: -start_cull() { - if (_cull_sorting) { - cull_bin_draw(); - } else { - cull_and_draw_together(); - } +INLINE GraphicsWindow *GraphicsEngine:: +make_window(GraphicsPipe *pipe) { + return make_window(pipe, get_threading_model()); } diff --git a/panda/src/display/graphicsEngine.cxx b/panda/src/display/graphicsEngine.cxx index 8e89e39b0f..27e0a6fb4d 100644 --- a/panda/src/display/graphicsEngine.cxx +++ b/panda/src/display/graphicsEngine.cxx @@ -17,6 +17,7 @@ //////////////////////////////////////////////////////////////////// #include "graphicsEngine.h" +#include "graphicsPipe.h" #include "config_display.h" #include "pipeline.h" #include "drawCullHandler.h" @@ -49,19 +50,10 @@ GraphicsEngine(Pipeline *pipeline) : if (_pipeline == (Pipeline *)NULL) { _pipeline = Pipeline::get_render_pipeline(); } - - ThreadingModel tm = string_threading_model(threading_model); - if (tm == TM_invalid) { - display_cat.warning() - << "Invalid threading model: " << threading_model << "\n"; - set_threading_model(TM_appculldraw); - } else { - set_threading_model(tm); - } - - if (tm != TM_appculldraw) { + set_threading_model(threading_model); + if (!_threading_model.empty()) { display_cat.info() - << "Using threading model " << get_threading_model() << "\n"; + << "Using threading model " << _threading_model << "\n"; } } @@ -69,24 +61,144 @@ GraphicsEngine(Pipeline *pipeline) : // Function: GraphicsEngine::Destructor // Access: Published // Description: Gracefully cleans up the graphics engine and its -// related threads. Does not delete the associated -// windows. +// related threads and windows. //////////////////////////////////////////////////////////////////// GraphicsEngine:: ~GraphicsEngine() { - terminate_threads(); + remove_all_windows(); } //////////////////////////////////////////////////////////////////// -// Function: GraphicsEngine::add_window +// Function: GraphicsEngine::set_threading_model // Access: Published -// Description: Adds a new window to the set of windows that will be -// processed when render_frame() is called. This also -// increments the reference count to the window. +// Description: Specifies how windows created using future calls to +// the one-parameter version of make_window() will be +// threaded. (The two-parameter flavor of make_window() +// allows this to be specified on a per-window basis.) +// +// The threading model is a string representing the +// names of the two threads that will process cull and +// draw for the given window, separated by a slash. The +// names are completely arbitrary and are used only to +// differentiate threads. The two names may be the +// same, meaning the same thread, or each may be the +// empty string, which represents the previous thread. +// +// Thus, for example, "cull/draw" indicates that the +// window will be culled in a thread called "cull", and +// drawn in a separate thread called "draw". +// "draw/draw" or simply "draw/" indicates the window +// will be culled and drawn in the same thread, "draw". +// On the other hand, "/draw" indicates the thread will +// be culled in the main, or app thread, and drawn in a +// separate thread named "draw". The empty string, "" +// or "/", indicates the thread will be culled and drawn +// in the main thread; that is to say, a single-process +// model. +// +// Finally, if the threading model begins with a "-" +// character, then cull and draw are run simultaneously, +// in the same thread, with no binning or state sorting. +// It simplifies the cull process but it forces the +// scene to render in scene graph order; state sorting +// and alpha sorting is lost. +// +// You can create as many different threads as you like; +// each thread is uniquified based on its name, so +// multiple windows may easily be handled by the same or +// different threads. //////////////////////////////////////////////////////////////////// void GraphicsEngine:: -add_window(GraphicsWindow *window) { - _windows.insert(window); +set_threading_model(const string &threading_model) { + if (!threading_model.empty() && !Thread::is_threading_supported()) { + display_cat.warning() + << "Threading model " << threading_model + << " requested but threading not supported.\n"; + return; + } + MutexHolder holder(_lock); + _threading_model = threading_model; +} + +//////////////////////////////////////////////////////////////////// +// Function: GraphicsEngine::get_threading_model +// Access: Published +// Description: Returns the current default threading model. See +// set_threading_model(). +//////////////////////////////////////////////////////////////////// +string GraphicsEngine:: +get_threading_model() const { + string result; + { + MutexHolder holder(_lock); + result = _threading_model; + } + return result; +} + +//////////////////////////////////////////////////////////////////// +// Function: GraphicsEngine::make_window +// Access: Published +// Description: Creates a new window using the indicated GraphicsPipe +// and returns it. The GraphicsEngine becomes the owner +// of the window; it will persist at least until +// remove_window() is called later. +//////////////////////////////////////////////////////////////////// +GraphicsWindow *GraphicsEngine:: +make_window(GraphicsPipe *pipe, const string &threading_model) { + PT(GraphicsWindow) window = pipe->make_window(); + if (window != (GraphicsWindow *)NULL) { + MutexHolder holder(_lock); + _windows.insert(window); + + // Now figure out the threading model. + string cull_name; + string draw_name; + bool cull_sorting = true; + size_t start = 0; + if (!threading_model.empty() && threading_model[0] == '-') { + start = 1; + cull_sorting = false; + } + + size_t slash = threading_model.find('/', start); + if (slash == string::npos) { + cull_name = threading_model; + } else { + cull_name = threading_model.substr(start, slash - start); + draw_name = threading_model.substr(slash + 1); + } + if (!cull_sorting || draw_name.empty()) { + draw_name = cull_name; + } + + /* + cerr << "cull_name = " << cull_name << " draw_name = " << draw_name + << " cull_sorting = " << cull_sorting << "\n"; + */ + + WindowRenderer *cull = get_window_renderer(cull_name); + WindowRenderer *draw = get_window_renderer(draw_name); + + if (cull_sorting) { + cull->add_window(cull->_cull, window); + draw->add_window(draw->_draw, window); + } else { + cull->add_window(cull->_cdraw, window); + } + + // We should ask the pipe which thread it prefers to run its + // windowing commands in (the "window thread"). This is the + // thread that handles the commands to open, resize, etc. the + // window. X requires this to be done in the app thread, but some + // pipes might prefer this to be done in draw, for instance. For + // now, we assume this is the app thread. + _app.add_window(_app._window, window); + + display_cat.info() + << "Created " << window->get_type() << "\n"; + } + return window; } //////////////////////////////////////////////////////////////////// @@ -94,17 +206,63 @@ add_window(GraphicsWindow *window) { // Access: Published // Description: Removes the indicated window from the set of windows // that will be processed when render_frame() is called. -// This also decrements the reference count to the -// window, allowing the window to be destructed if there -// are no other references to it. +// This also closes the window if it is open, and +// removes the window from its GraphicsPipe, allowing +// the window to be destructed if there are no other +// references to it. (However, the window may not be +// actually closed until next frame, if it is controlled +// by a sub-thread.) // // The return value is true if the window was removed, // false if it was not found. +// +// Unlike remove_all_windows(), this function does not +// terminate any of the threads that may have been +// started to service this window; they are left running +// (since you might open a new window later on these +// threads). If your intention is to clean up before +// shutting down, it is better to call +// remove_all_windows() then to call remove_window() one +// at a time. //////////////////////////////////////////////////////////////////// bool GraphicsEngine:: remove_window(GraphicsWindow *window) { - size_t count = _windows.erase(window); - return (count != 0); + // First, make sure we know what this window is. + PT(GraphicsWindow) ptwin = window; + size_t count; + { + MutexHolder holder(_lock); + count = _windows.erase(ptwin); + } + if (count == 0) { + // Never heard of this window. Do nothing. + return false; + } + + do_remove_window(window); + return true; +} + +//////////////////////////////////////////////////////////////////// +// Function: GraphicsEngine::remove_all_windows +// Access: Published +// Description: Removes and closes all windows from the engine. This +// also cleans up and terminates any threads that have +// been started to service those windows. +//////////////////////////////////////////////////////////////////// +void GraphicsEngine:: +remove_all_windows() { + Windows::iterator wi; + for (wi = _windows.begin(); wi != _windows.end(); ++wi) { + GraphicsWindow *win = (*wi); + do_remove_window(win); + } + + _windows.clear(); + + _app.do_release(this); + _app.do_close(this); + terminate_threads(); } //////////////////////////////////////////////////////////////////// @@ -115,27 +273,52 @@ remove_window(GraphicsWindow *window) { //////////////////////////////////////////////////////////////////// void GraphicsEngine:: render_frame() { - if (_cull_thread == (Thread *)NULL) { - // Nonthreaded cull: perform cull within the app thread. This - // corresponds to either TM_appculldraw, TM_appcull_draw, or - // TM_appcdraw. - start_cull(); - - } else { - // Threaded cull: perform cull within its own thread. Here we - // simply signal the thread and then let it go about its business - // while we return. - MutexHolder holder(_cull_thread->_cv_mutex); - if (_cull_thread->_thread_state == TS_wait) { - _cull_thread->_thread_state = TS_do_frame; - _cull_thread->_cv.signal(); - } + // We hold the GraphicsEngine mutex while we wait for all of the + // threads. Doing this puts us at risk for deadlock if any of the + // threads tries to call any methods on the GraphicsEngine. So + // don't do that. + MutexHolder holder(_lock); + + // First, wait for all the threads to finish their current frame. + // Grabbing the mutex should achieve that. + Threads::const_iterator ti; + for (ti = _threads.begin(); ti != _threads.end(); ++ti) { + RenderThread *thread = (*ti).second; + thread->_cv_mutex.lock(); } - - // **** This doesn't belong here; it really belongs in the Pipeline, - // but here it is for now. + + // Now signal all of our threads to flip the windows. + _app.do_flip(this); + for (ti = _threads.begin(); ti != _threads.end(); ++ti) { + RenderThread *thread = (*ti).second; + if (thread->_thread_state == TS_wait) { + thread->_thread_state = TS_do_flip; + thread->_cv.signal(); + } + thread->_cv_mutex.release(); + } + + // Grab the mutex again after all windows have flipped. + for (ti = _threads.begin(); ti != _threads.end(); ++ti) { + RenderThread *thread = (*ti).second; + thread->_cv_mutex.lock(); + } + + // Now cycle the pipeline and officially begin the next frame. + _pipeline->cycle(); ClockObject::get_global_clock()->tick(); PStatClient::main_tick(); + + // Now signal all of our threads to begin their next frame. + _app.do_frame(this); + for (ti = _threads.begin(); ti != _threads.end(); ++ti) { + RenderThread *thread = (*ti).second; + if (thread->_thread_state == TS_wait) { + thread->_thread_state = TS_do_frame; + thread->_cv.signal(); + } + thread->_cv_mutex.release(); + } } //////////////////////////////////////////////////////////////////// @@ -149,221 +332,53 @@ render_frame() { // // This always executes completely within the calling // thread, regardless of the threading model in use. -// Thus, it may be an error to call this from the app -// thread if the threading model is not TM_appculldraw; -// similarly, it is an error to call it from cull if the -// threading model is TM_appcull_draw or -// TM_app_cull_draw. +// Thus, it must always be called from the draw thread, +// whichever thread that may be. //////////////////////////////////////////////////////////////////// void GraphicsEngine:: -render_subframe(GraphicsStateGuardian *gsg, DisplayRegion *dr) { - if (_cull_sorting) { +render_subframe(GraphicsStateGuardian *gsg, DisplayRegion *dr, + bool cull_sorting) { + if (cull_sorting) { cull_bin_draw(gsg, dr); } else { cull_and_draw_together(gsg, dr); } } -//////////////////////////////////////////////////////////////////// -// Function: GraphicsEngine::set_threading_model -// Access: Published -// Description: Changes the way the app, cull, and draw steps are -// divided among threads. The allowable settings are: -// -// TM_appculldraw: single-threaded. All steps are -// performed by the calling thread; render_frame() -// does not return until the frame has been fully -// rendered. -// -// TM_appcull_draw: app and cull are performed -// together, while draw is performed in a separate -// thread. render_frame() will return after cull has -// been completed; draw will have started in the -// sub-thread. -// -// TM_app_culldraw: app is separate, while cull and -// draw are performed in sequence within a separate -// thread. render_frame() will return almost -// immediately (after waiting for cull to start in -// the sub-thread). -// -// TM_app_cull_draw: all stages of the pipeline are in -// separate threads. render_frame() returns almost -// immediately, after waiting for cull to start in -// its sub-thread; when cull finishes, it passes the -// frame off to a separate thread for draw and then -// begins working on culling the next frame. -// -// TM_appcdraw: single-threaded, like TM_appculldraw, -// but cull and draw are performed simultaneously, -// rather than sequentially. This means that the -// scene will always be rendered in scene graph -// order; binning, state-sorting and back-to-front -// sorting cannot be achieved. -// -// TM_app_cdraw: similar to TM_appcdraw, but the -// cull&draw step is performed in a separate thread. -//////////////////////////////////////////////////////////////////// -void GraphicsEngine:: -set_threading_model(ThreadingModel threading_model) { - bool spawn_cull_thread; - bool spawn_draw_thread; - bool cull_sorting; - - switch (threading_model) { - case TM_appculldraw: - spawn_cull_thread = false; - spawn_draw_thread = false; - cull_sorting = true; - break; - - case TM_appcull_draw: - spawn_cull_thread = false; - spawn_draw_thread = true; - cull_sorting = true; - break; - - case TM_app_culldraw: - spawn_cull_thread = true; - spawn_draw_thread = false; - cull_sorting = true; - break; - - case TM_app_cull_draw: - spawn_cull_thread = true; - spawn_draw_thread = true; - cull_sorting = true; - break; - - case TM_appcdraw: - spawn_cull_thread = false; - spawn_draw_thread = false; - cull_sorting = false; - break; - - case TM_app_cdraw: - spawn_cull_thread = true; - spawn_draw_thread = false; - cull_sorting = false; - break; - - default: - display_cat.error() - << "Invalid threading model: " << (int)threading_model << "\n"; - return; - } - - if ((spawn_cull_thread || spawn_draw_thread) && - !Thread::is_threading_supported()) { - display_cat.warning() - << "Threading model " << threading_model - << " requested but threading not supported.\n"; - threading_model = (cull_sorting) ? TM_appculldraw : TM_appcdraw; - spawn_cull_thread = false; - spawn_draw_thread = false; - } - - if (_threading_model != threading_model || _cull_sorting != cull_sorting) { - terminate_threads(); - - _threading_model = threading_model; - _cull_sorting = cull_sorting; - - if (spawn_cull_thread) { - const char *thread_name; - if (spawn_draw_thread) { - thread_name = "cull"; - } else if (cull_sorting) { - thread_name = "culldraw"; - } else { - thread_name = "cdraw"; - } - _cull_thread = new CullThread(thread_name, this); - MutexHolder holder(_cull_thread->_cv_mutex); - if (!_cull_thread->start(TP_normal, false, true)) { - display_cat.error() - << "Unable to start cull thread.\n"; - _cull_thread = (CullThread *)NULL; - } - } - - if (spawn_draw_thread) { - _draw_thread = new DrawThread("draw", this); - MutexHolder holder(_draw_thread->_cv_mutex); - if (!_draw_thread->start(TP_normal, true, true)) { - display_cat.error() - << "Unable to start draw thread.\n"; - _draw_thread = (DrawThread *)NULL; - } - } - } -} - -//////////////////////////////////////////////////////////////////// -// Function: GraphicsEngine::string_threading_model -// Access: Public, Static -// Description: Returns the ThreadingModel value corresponding to the -// indicated string, or TM_invalid if the threading -// model is invalid. -//////////////////////////////////////////////////////////////////// -GraphicsEngine::ThreadingModel GraphicsEngine:: -string_threading_model(const string &string) { - if (cmp_nocase_uh(string, "appculldraw") == 0) { - return TM_appculldraw; - - } else if (cmp_nocase_uh(string, "appcull_draw") == 0) { - return TM_appcull_draw; - - } else if (cmp_nocase_uh(string, "app_culldraw") == 0) { - return TM_app_culldraw; - - } else if (cmp_nocase_uh(string, "app_cull_draw") == 0) { - return TM_app_cull_draw; - - } else if (cmp_nocase_uh(string, "appcdraw") == 0) { - return TM_appcdraw; - - } else if (cmp_nocase_uh(string, "app_cdraw") == 0) { - return TM_app_cdraw; - - } else { - return TM_invalid; - } -} - //////////////////////////////////////////////////////////////////// // Function: GraphicsEngine::cull_and_draw_together // Access: Private -// Description: An implementation of render_frame() that renders the -// frame with a DrawCullHandler, to cull and draw all -// windows in the same pass. +// Description: This is called in the cull+draw thread by individual +// RenderThread objects during the frame rendering. It +// culls the geometry and immediately draws it, without +// first collecting it into bins. This is used when the +// threading model begins with the "-" character. //////////////////////////////////////////////////////////////////// void GraphicsEngine:: -cull_and_draw_together() { - Windows::iterator wi; - for (wi = _windows.begin(); wi != _windows.end(); ++wi) { +cull_and_draw_together(const GraphicsEngine::Windows &wlist) { + Windows::const_iterator wi; + for (wi = wlist.begin(); wi != wlist.end(); ++wi) { GraphicsWindow *win = (*wi); - if (win->get_window_active()) { - win->begin_frame(); - win->clear(); + if (win->is_active()) { + if (win->begin_frame()) { + win->clear(); - int num_display_regions = win->get_num_display_regions(); - for (int i = 0; i < num_display_regions; i++) { - DisplayRegion *dr = win->get_display_region(i); - cull_and_draw_together(win->get_gsg(), dr); + int num_display_regions = win->get_num_display_regions(); + for (int i = 0; i < num_display_regions; i++) { + DisplayRegion *dr = win->get_display_region(i); + cull_and_draw_together(win->get_gsg(), dr); + } + win->end_frame(); } - win->end_frame(); } - win->process_events(); } } //////////////////////////////////////////////////////////////////// // Function: GraphicsEngine::cull_and_draw_together // Access: Private -// Description: An implementation of render_frame() that renders the -// frame with a DrawCullHandler, to cull and draw all -// windows in the same pass. +// Description: This variant of cull_and_draw_together() is called +// only by render_subframe(). //////////////////////////////////////////////////////////////////// void GraphicsEngine:: cull_and_draw_together(GraphicsStateGuardian *gsg, DisplayRegion *dr) { @@ -376,9 +391,12 @@ cull_and_draw_together(GraphicsStateGuardian *gsg, DisplayRegion *dr) { if (dr->is_any_clear_active()) { gsg->clear(dr); } - + DrawCullHandler cull_handler(gsg); - do_cull(&cull_handler, scene_setup, gsg); + if (gsg->begin_scene()) { + do_cull(&cull_handler, scene_setup, gsg); + gsg->end_scene(); + } gsg->pop_display_region(old_dr); } @@ -387,44 +405,48 @@ cull_and_draw_together(GraphicsStateGuardian *gsg, DisplayRegion *dr) { //////////////////////////////////////////////////////////////////// // Function: GraphicsEngine::cull_bin_draw // Access: Private -// Description: An implementation of render_frame() that renders the -// frame with a BinCullHandler, to cull into bins and -// then draw the bins. This is the normal method. +// Description: This is called in the cull thread by individual +// RenderThread objects during the frame rendering. It +// collects the geometry into bins in preparation for +// drawing. //////////////////////////////////////////////////////////////////// void GraphicsEngine:: -cull_bin_draw() { - Windows::iterator wi; - for (wi = _windows.begin(); wi != _windows.end(); ++wi) { +cull_bin_draw(const GraphicsEngine::Windows &wlist) { + Windows::const_iterator wi; + for (wi = wlist.begin(); wi != wlist.end(); ++wi) { GraphicsWindow *win = (*wi); - if (win->get_window_active()) { - win->begin_frame(); - win->clear(); + if (win->is_active()) { + // This should be done in the draw thread, not here. + if (win->begin_frame()) { + win->clear(); - int num_display_regions = win->get_num_display_regions(); - for (int i = 0; i < num_display_regions; i++) { - DisplayRegion *dr = win->get_display_region(i); - cull_bin_draw(win->get_gsg(), dr); - } + int num_display_regions = win->get_num_display_regions(); + for (int i = 0; i < num_display_regions; i++) { + DisplayRegion *dr = win->get_display_region(i); + cull_bin_draw(win->get_gsg(), dr); + } - win->end_frame(); + win->end_frame(); + } } - win->process_events(); } } //////////////////////////////////////////////////////////////////// // Function: GraphicsEngine::cull_bin_draw // Access: Private -// Description: An implementation of render_frame() that renders the -// frame with a BinCullHandler, to cull into bins and -// then draw the bins. This is the normal method. +// Description: This variant of cull_bin_draw() is called +// by render_subframe(), as well as within the +// implementation of cull_bin_draw(), above. //////////////////////////////////////////////////////////////////// void GraphicsEngine:: cull_bin_draw(GraphicsStateGuardian *gsg, DisplayRegion *dr) { nassertv(gsg != (GraphicsStateGuardian *)NULL); PT(CullResult) cull_result = dr->_cull_result; - if (cull_result == (CullResult *)NULL) { + if (cull_result != (CullResult *)NULL) { + cull_result = cull_result->make_next(); + } else { cull_result = new CullResult(gsg); } @@ -436,13 +458,50 @@ cull_bin_draw(GraphicsStateGuardian *gsg, DisplayRegion *dr) { cull_result->finish_cull(); // Save the results for next frame. - dr->_cull_result = cull_result->make_next(); + dr->_cull_result = cull_result; // Now draw. + // This should get deferred into the next pipeline stage. do_draw(cull_result, scene_setup, gsg, dr); } } +//////////////////////////////////////////////////////////////////// +// Function: GraphicsEngine::process_events +// Access: Private +// Description: This is called by the RenderThread object to process +// all the windows events (resize, etc.) for the given +// list of windows. This is run in the window thread. +//////////////////////////////////////////////////////////////////// +void GraphicsEngine:: +process_events(const GraphicsEngine::Windows &wlist) { + Windows::const_iterator wi; + for (wi = wlist.begin(); wi != wlist.end(); ++wi) { + GraphicsWindow *win = (*wi); + win->process_events(); + } +} + +//////////////////////////////////////////////////////////////////// +// Function: GraphicsEngine::flip_windows +// Access: Private +// Description: This is called by the RenderThread object to flip the +// buffers (resize, etc.) for the given list of windows. +// This is run in the draw thread. +//////////////////////////////////////////////////////////////////// +void GraphicsEngine:: +flip_windows(const GraphicsEngine::Windows &wlist) { + Windows::const_iterator wi; + for (wi = wlist.begin(); wi != wlist.end(); ++wi) { + GraphicsWindow *win = (*wi); + win->begin_flip(); + } + for (wi = wlist.begin(); wi != wlist.end(); ++wi) { + GraphicsWindow *win = (*wi); + win->end_flip(); + } +} + //////////////////////////////////////////////////////////////////// // Function: GraphicsEngine::setup_scene // Access: Private @@ -565,7 +624,10 @@ do_draw(CullResult *cull_result, SceneSetup *scene_setup, if (dr->is_any_clear_active()) { gsg->clear(dr); } - cull_result->draw(); + if (gsg->begin_scene()) { + cull_result->draw(); + gsg->end_scene(); + } gsg->pop_display_region(old_dr); } } @@ -603,6 +665,35 @@ setup_gsg(GraphicsStateGuardian *gsg, SceneSetup *scene_setup) { return true; } +//////////////////////////////////////////////////////////////////// +// Function: GraphicsEngine::do_remove_window +// Access: Private +// Description: An internal function called by remove_window() and +// remove_all_windows() to actually remove the indicated +// window from all relevant structures, except the +// _windows list itself. +//////////////////////////////////////////////////////////////////// +void GraphicsEngine:: +do_remove_window(GraphicsWindow *window) { + PT(GraphicsPipe) pipe = window->get_pipe(); + if (pipe != (GraphicsPipe *)NULL) { + pipe->remove_window(window); + window->_pipe = (GraphicsPipe *)NULL; + } + + // Now remove the window from all threads that know about it. + _app.remove_window(window); + Threads::const_iterator ti; + for (ti = _threads.begin(); ti != _threads.end(); ++ti) { + RenderThread *thread = (*ti).second; + thread->remove_window(window); + } + + // If the window happened to be controlled by the app thread, we + // might as well close it now rather than waiting for next frame. + _app.do_pending(this); +} + //////////////////////////////////////////////////////////////////// // Function: GraphicsEngine::terminate_threads // Access: Private @@ -611,115 +702,307 @@ setup_gsg(GraphicsStateGuardian *gsg, SceneSetup *scene_setup) { //////////////////////////////////////////////////////////////////// void GraphicsEngine:: terminate_threads() { - if (_cull_thread != (Thread *)NULL) { - MutexHolder holder(_cull_thread->_cv_mutex); - _cull_thread->_thread_state = TS_terminate; - _cull_thread->_cv.signal(); - } - if (_draw_thread != (Thread *)NULL) { - MutexHolder holder(_draw_thread->_cv_mutex); - _draw_thread->_thread_state = TS_terminate; - _draw_thread->_cv.signal(); - } - - if (_cull_thread != (Thread *)NULL) { - _cull_thread->join(); - _cull_thread = (CullThread *)NULL; - } - if (_draw_thread != (Thread *)NULL) { - _draw_thread->join(); - _draw_thread = (DrawThread *)NULL; - } -} - -//////////////////////////////////////////////////////////////////// -// Function: GraphicsEngine::CullThread::Constructor -// Access: Public -// Description: -//////////////////////////////////////////////////////////////////// -GraphicsEngine::CullThread:: -CullThread(const string &name, GraphicsEngine *engine) : - Thread(name), - _engine(engine), - _cv(_cv_mutex) -{ - _thread_state = TS_wait; -} - -//////////////////////////////////////////////////////////////////// -// Function: GraphicsEngine::CullThread::thread_main -// Access: Public, Virtual -// Description: Runs the cull thread. -//////////////////////////////////////////////////////////////////// -void GraphicsEngine::CullThread:: -thread_main() { - MutexHolder holder(_cv_mutex); - while (_thread_state != TS_terminate) { - _cv.wait(); - if (_thread_state == TS_do_frame) { - _engine->start_cull(); - _thread_state = TS_wait; - } - } -} - -//////////////////////////////////////////////////////////////////// -// Function: GraphicsEngine::DrawThread::Constructor -// Access: Public -// Description: -//////////////////////////////////////////////////////////////////// -GraphicsEngine::DrawThread:: -DrawThread(const string &name, GraphicsEngine *engine) : - Thread(name), - _engine(engine), - _cv(_cv_mutex) -{ - _thread_state = TS_wait; -} - -//////////////////////////////////////////////////////////////////// -// Function: GraphicsEngine::DrawThread::thread_main -// Access: Public, Virtual -// Description: Runs the draw thread. -//////////////////////////////////////////////////////////////////// -void GraphicsEngine::DrawThread:: -thread_main() { - MutexHolder holder(_cv_mutex); - while (_thread_state != TS_terminate) { - _cv.wait(); - if (_thread_state == TS_do_frame) { - // _engine->start_draw(); - _thread_state = TS_wait; - } - } -} - -ostream & -operator << (ostream &out, GraphicsEngine::ThreadingModel threading_model) { - switch (threading_model) { - case GraphicsEngine::TM_invalid: - return out << "invalid"; - - case GraphicsEngine::TM_appculldraw: - return out << "appculldraw"; - - case GraphicsEngine::TM_appcull_draw: - return out << "appcull_draw"; - - case GraphicsEngine::TM_app_culldraw: - return out << "app_culldraw"; - - case GraphicsEngine::TM_app_cull_draw: - return out << "app_cull_draw"; - - case GraphicsEngine::TM_appcdraw: - return out << "appcdraw"; - - case GraphicsEngine::TM_app_cdraw: - return out << "app_cdraw"; + MutexHolder holder(_lock); - default: - return out << "**invalid threading model (" << (int)threading_model - << ")**"; + // First, wait for all the threads to finish their current frame. + // Grabbing the mutex should achieve that. + Threads::const_iterator ti; + for (ti = _threads.begin(); ti != _threads.end(); ++ti) { + RenderThread *thread = (*ti).second; + thread->_cv_mutex.lock(); + } + + // Now tell them to release their windows' graphics contexts. + for (ti = _threads.begin(); ti != _threads.end(); ++ti) { + RenderThread *thread = (*ti).second; + if (thread->_thread_state == TS_wait) { + thread->_thread_state = TS_do_release; + thread->_cv.signal(); + } + thread->_cv_mutex.release(); + } + + // Grab the mutex again to wait for the above to complete. + for (ti = _threads.begin(); ti != _threads.end(); ++ti) { + RenderThread *thread = (*ti).second; + thread->_cv_mutex.lock(); + } + + // Now tell them to close their windows and terminate. + for (ti = _threads.begin(); ti != _threads.end(); ++ti) { + RenderThread *thread = (*ti).second; + MutexHolder cv_holder(thread->_cv_mutex); + thread->_thread_state = TS_terminate; + thread->_cv.signal(); + thread->_cv_mutex.release(); + } + + // Finally, wait for them all to finish cleaning up. + for (ti = _threads.begin(); ti != _threads.end(); ++ti) { + RenderThread *thread = (*ti).second; + thread->join(); + } + + _threads.clear(); +} + +//////////////////////////////////////////////////////////////////// +// Function: GraphicsEngine::get_window_renderer +// Access: Private +// Description: Returns the WindowRenderer with the given name. +// Creates a new RenderThread if there is no such thread +// already. +//////////////////////////////////////////////////////////////////// +GraphicsEngine::WindowRenderer *GraphicsEngine:: +get_window_renderer(const string &name) { + if (name.empty()) { + return &_app; + } + + MutexHolder holder(_lock); + Threads::iterator ti = _threads.find(name); + if (ti != _threads.end()) { + return (*ti).second.p(); + } + + PT(RenderThread) thread = new RenderThread(name, this); + thread->start(TP_normal, true, true); + _threads[name] = thread; + + return thread.p(); +} + +//////////////////////////////////////////////////////////////////// +// Function: GraphicsEngine::WindowRenderer::add_window +// Access: Public +// Description: Adds a new window to the indicated list, which should +// be a member of the WindowRenderer. +//////////////////////////////////////////////////////////////////// +void GraphicsEngine::WindowRenderer:: +add_window(Windows &wlist, GraphicsWindow *window) { + MutexHolder holder(_wl_lock); + wlist.insert(window); +} + +//////////////////////////////////////////////////////////////////// +// Function: GraphicsEngine::WindowRenderer::remove_window_now +// Access: Public +// Description: Immediately removes the indicated window from all +// lists. If the window is currently open and is +// already on the _window list, moves it to the _pending_close +// list for later closure. +//////////////////////////////////////////////////////////////////// +void GraphicsEngine::WindowRenderer:: +remove_window(GraphicsWindow *window) { + MutexHolder holder(_wl_lock); + PT(GraphicsWindow) ptwin = window; + + _cull.erase(ptwin); + + Windows::iterator wi; + + wi = _cdraw.find(ptwin); + if (wi != _cdraw.end()) { + // The window is on our _cdraw list, meaning its GSG operations are + // serviced by this thread (cull and draw in the same operation). + + // Move it to the pending release thread so we can release the GSG + // when the thread next runs. We can't do this immediately, + // because we might not have been called from the subthread. + _pending_release.insert(ptwin); + _cdraw.erase(wi); + } + + wi = _draw.find(ptwin); + if (wi != _draw.end()) { + // The window is on our _draw list, meaning its GSG operations are + // serviced by this thread (draw performed on this thread). + + // Move it to the pending release thread so we can release the GSG + // when the thread next runs. We can't do this immediately, + // because we might not have been called from the subthread. + _pending_release.insert(ptwin); + _draw.erase(wi); + } + + wi = _window.find(ptwin); + if (wi != _window.end()) { + // The window is on our _window list, meaning its open/close + // operations (among other window ops) are serviced by this + // thread. + + // Make sure the window isn't about to request itself open. + WindowProperties close_properties; + close_properties.set_open(false); + ptwin->request_properties(close_properties); + + // If the window is already open, move it to the _pending_close list so + // it can be closed later. We can't close it immediately, because + // we might not have been called from the subthread. + if (!ptwin->is_closed()) { + _pending_close.insert(ptwin); + } + + _window.erase(wi); + } +} + +//////////////////////////////////////////////////////////////////// +// Function: GraphicsEngine::WindowRenderer::do_frame +// Access: Public +// Description: Executes one stage of the pipeline for the current +// thread: calls cull on all windows that are on the +// cull list for this thread, draw on all the windows on +// the draw list, etc. +//////////////////////////////////////////////////////////////////// +void GraphicsEngine::WindowRenderer:: +do_frame(GraphicsEngine *engine) { + MutexHolder holder(_wl_lock); + engine->cull_bin_draw(_cull); + engine->cull_and_draw_together(_cdraw); + engine->process_events(_window); +} + +//////////////////////////////////////////////////////////////////// +// Function: GraphicsEngine::WindowRenderer::do_flip +// Access: Public +// Description: Flips the windows as appropriate for the current +// thread. +//////////////////////////////////////////////////////////////////// +void GraphicsEngine::WindowRenderer:: +do_flip(GraphicsEngine *engine) { + MutexHolder holder(_wl_lock); + engine->flip_windows(_cdraw); + engine->flip_windows(_draw); +} + +//////////////////////////////////////////////////////////////////// +// Function: GraphicsEngine::WindowRenderer::do_release +// Access: Public +// Description: Releases the rendering contexts for all windows on +// the _draw list. +//////////////////////////////////////////////////////////////////// +void GraphicsEngine::WindowRenderer:: +do_release(GraphicsEngine *) { + MutexHolder holder(_wl_lock); + Windows::iterator wi; + for (wi = _draw.begin(); wi != _draw.end(); ++wi) { + GraphicsWindow *win = (*wi); + win->release_gsg(); + } +} + +//////////////////////////////////////////////////////////////////// +// Function: GraphicsEngine::WindowRenderer::do_close +// Access: Public +// Description: Closes all the windows on the _window list. +//////////////////////////////////////////////////////////////////// +void GraphicsEngine::WindowRenderer:: +do_close(GraphicsEngine *) { + WindowProperties close_properties; + close_properties.set_open(false); + + MutexHolder holder(_wl_lock); + Windows::iterator wi; + for (wi = _window.begin(); wi != _window.end(); ++wi) { + GraphicsWindow *win = (*wi); + win->set_properties_now(close_properties); + } +} + +//////////////////////////////////////////////////////////////////// +// Function: GraphicsEngine::WindowRenderer::do_pending +// Access: Public +// Description: Actually closes any windows that were recently +// removed from the WindowRenderer. +//////////////////////////////////////////////////////////////////// +void GraphicsEngine::WindowRenderer:: +do_pending(GraphicsEngine *engine) { + MutexHolder holder(_wl_lock); + + if (!_pending_release.empty()) { + // Release any GSG's that were waiting. + Windows::iterator wi; + for (wi = _pending_release.begin(); wi != _pending_release.end(); ++wi) { + GraphicsWindow *win = (*wi); + win->release_gsg(); + } + _pending_release.clear(); + } + + if (!_pending_close.empty()) { + WindowProperties close_properties; + close_properties.set_open(false); + + // Close any windows that were pending closure, but only if their + // associated GSG has already been released. + Windows new_pending_close; + Windows::iterator wi; + for (wi = _pending_close.begin(); wi != _pending_close.end(); ++wi) { + GraphicsWindow *win = (*wi); + if (win->get_gsg() == (GraphicsStateGuardian *)NULL) { + win->set_properties_now(close_properties); + } else { + // If the GSG hasn't been released yet, we have to save the + // close operation for next frame. + new_pending_close.insert(win); + } + } + _pending_close.swap(new_pending_close); + } +} + +//////////////////////////////////////////////////////////////////// +// Function: GraphicsEngine::RenderThread::Constructor +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +GraphicsEngine::RenderThread:: +RenderThread(const string &name, GraphicsEngine *engine) : + Thread(name), + _engine(engine), + _cv(_cv_mutex) +{ + _thread_state = TS_wait; +} + +//////////////////////////////////////////////////////////////////// +// Function: GraphicsEngine::RenderThread::thread_main +// Access: Public, Virtual +// Description: The main loop for a particular render thread. The +// thread will process whatever cull or draw windows it +// has assigned to it. +//////////////////////////////////////////////////////////////////// +void GraphicsEngine::RenderThread:: +thread_main() { + MutexHolder holder(_cv_mutex); + while (true) { + _cv.wait(); + switch (_thread_state) { + case TS_wait: + break; + + case TS_do_frame: + do_pending(_engine); + do_frame(_engine); + _thread_state = TS_wait; + break; + + case TS_do_flip: + do_flip(_engine); + _thread_state = TS_wait; + break; + + case TS_do_release: + do_pending(_engine); + do_release(_engine); + _thread_state = TS_wait; + break; + + case TS_terminate: + do_pending(_engine); + do_close(_engine); + return; + } } } diff --git a/panda/src/display/graphicsEngine.h b/panda/src/display/graphicsEngine.h index 027cc653ec..47d079ecf5 100644 --- a/panda/src/display/graphicsEngine.h +++ b/panda/src/display/graphicsEngine.h @@ -31,6 +31,7 @@ class Pipeline; class DisplayRegion; +class GraphicsPipe; //////////////////////////////////////////////////////////////////// // Class : GraphicsEngine @@ -43,44 +44,40 @@ class DisplayRegion; // required. // // The GraphicsEngine is responsible for managing the -// cull and draw processes. The application simply -// calls engine->render_frame() and considers it done. +// various cull and draw threads. The application +// simply calls engine->render_frame() and considers it +// done. //////////////////////////////////////////////////////////////////// -class EXPCL_PANDA GraphicsEngine : public Namable { +class EXPCL_PANDA GraphicsEngine { PUBLISHED: GraphicsEngine(Pipeline *pipeline = NULL); ~GraphicsEngine(); - void add_window(GraphicsWindow *window); + void set_threading_model(const string &threading_model); + string get_threading_model() const; + + INLINE GraphicsWindow *make_window(GraphicsPipe *pipe); + GraphicsWindow *make_window(GraphicsPipe *pipe, + const string &threading_model); bool remove_window(GraphicsWindow *window); + void remove_all_windows(); void render_frame(); - void render_subframe(GraphicsStateGuardian *gsg, DisplayRegion *dr); - - enum ThreadingModel { - TM_invalid, - TM_appculldraw, - TM_appcull_draw, - TM_app_culldraw, - TM_app_cull_draw, - TM_appcdraw, - TM_app_cdraw, - }; - - void set_threading_model(ThreadingModel threading_model); - INLINE ThreadingModel get_threading_model() const; - -public: - static ThreadingModel string_threading_model(const string &string); + void render_subframe(GraphicsStateGuardian *gsg, DisplayRegion *dr, + bool cull_sorting); private: - INLINE void start_cull(); - void cull_and_draw_together(); + typedef pset< PT(GraphicsWindow) > Windows; + + void cull_and_draw_together(const Windows &wlist); void cull_and_draw_together(GraphicsStateGuardian *gsg, DisplayRegion *dr); - void cull_bin_draw(); + void cull_bin_draw(const Windows &wlist); void cull_bin_draw(GraphicsStateGuardian *gsg, DisplayRegion *dr); + void process_events(const GraphicsEngine::Windows &wlist); + void flip_windows(const GraphicsEngine::Windows &wlist); + PT(SceneSetup) setup_scene(const NodePath &camera, GraphicsStateGuardian *gsg); void do_cull(CullHandler *cull_handler, SceneSetup *scene_setup, @@ -90,17 +87,42 @@ private: bool setup_gsg(GraphicsStateGuardian *gsg, SceneSetup *scene_setup); + void do_remove_window(GraphicsWindow *window); void terminate_threads(); + // The WindowRenderer class records the stages of the pipeline that + // each thread (including the main thread, a.k.a. "app") should + // process, and the list of windows for each stage. + class WindowRenderer { + public: + void add_window(Windows &wlist, GraphicsWindow *window); + void remove_window(GraphicsWindow *window); + void do_frame(GraphicsEngine *engine); + void do_flip(GraphicsEngine *engine); + void do_release(GraphicsEngine *engine); + void do_close(GraphicsEngine *engine); + void do_pending(GraphicsEngine *engine); + + Windows _cull; // cull stage + Windows _cdraw; // cull-and-draw-together stage + Windows _draw; // draw stage + Windows _window; // window stage, i.e. process windowing events + Windows _pending_release; // moved from _draw, pending release_gsg. + Windows _pending_close; // moved from _window, pending close. + Mutex _wl_lock; + }; + enum ThreadState { TS_wait, TS_do_frame, + TS_do_flip, + TS_do_release, TS_terminate }; - class CullThread : public Thread { + class RenderThread : public Thread, public WindowRenderer { public: - CullThread(const string &name, GraphicsEngine *engine); + RenderThread(const string &name, GraphicsEngine *engine); virtual void thread_main(); GraphicsEngine *_engine; @@ -109,37 +131,23 @@ private: ThreadState _thread_state; }; - class DrawThread : public Thread { - public: - DrawThread(const string &name, GraphicsEngine *engine); - virtual void thread_main(); - - GraphicsEngine *_engine; - Mutex _cv_mutex; - ConditionVar _cv; - ThreadState _thread_state; - }; + WindowRenderer *get_window_renderer(const string &name); Pipeline *_pipeline; - - typedef pset Windows; Windows _windows; - ThreadingModel _threading_model; - bool _cull_sorting; + WindowRenderer _app; + typedef pmap Threads; + Threads _threads; + string _threading_model; - PT(CullThread) _cull_thread; - PT(DrawThread) _draw_thread; + Mutex _lock; static PStatCollector _cull_pcollector; static PStatCollector _draw_pcollector; - - friend class CullThread; + friend class WindowRenderer; }; -ostream & -operator << (ostream &out, GraphicsEngine::ThreadingModel threading_model); - #include "graphicsEngine.I" #endif diff --git a/panda/src/display/graphicsLayer.I b/panda/src/display/graphicsLayer.I index db655058ee..cac2714f0a 100644 --- a/panda/src/display/graphicsLayer.I +++ b/panda/src/display/graphicsLayer.I @@ -16,34 +16,6 @@ // //////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////// -// Function: GraphicsLayer::get_channel -// Access: Published -// Description: Returns the GraphicsChannel that this layer is -// associated with. It is possible that the -// GraphicsChannel might have been deleted while an -// outstanding PT(GraphicsLayer) prevented all of its -// children layers from also being deleted; in this -// unlikely case, get_channel() may return NULL. -//////////////////////////////////////////////////////////////////// -INLINE GraphicsChannel *GraphicsLayer:: -get_channel() const { - return _channel; -} - -//////////////////////////////////////////////////////////////////// -// Function: GraphicsLayer::set_active -// Access: Published -// Description: Sets the active flag on the layer. If the layer -// is marked as inactive, nothing will be rendered. -//////////////////////////////////////////////////////////////////// -INLINE void GraphicsLayer:: -set_active(bool active) { - if (active != _is_active) { - _is_active = active; - win_display_regions_changed(); - } -} //////////////////////////////////////////////////////////////////// // Function: GraphicsLayer::is_active @@ -54,4 +26,3 @@ INLINE bool GraphicsLayer:: is_active() const { return _is_active; } - diff --git a/panda/src/display/graphicsLayer.cxx b/panda/src/display/graphicsLayer.cxx index abf9b94e97..6c2c010c2d 100644 --- a/panda/src/display/graphicsLayer.cxx +++ b/panda/src/display/graphicsLayer.cxx @@ -20,20 +20,19 @@ #include "graphicsChannel.h" #include "graphicsWindow.h" #include "config_display.h" +#include "notify.h" +#include "mutexHolder.h" #include -#include -//////////////////////////////////////////////////////////////////// -// Static variables -//////////////////////////////////////////////////////////////////// TypeHandle GraphicsLayer::_type_handle; //////////////////////////////////////////////////////////////////// // Function: GraphicsLayer::Constructor -// Access: Public -// Description: +// Access: Private +// Description: Use GraphicsChannel::make_layer() to make a new +// layer. //////////////////////////////////////////////////////////////////// GraphicsLayer:: GraphicsLayer() { @@ -44,7 +43,8 @@ GraphicsLayer() { //////////////////////////////////////////////////////////////////// // Function: GraphicsLayer::Constructor // Access: Public -// Description: +// Description: Use GraphicsChannel::make_layer() to make a new +// layer. //////////////////////////////////////////////////////////////////// GraphicsLayer:: GraphicsLayer(GraphicsChannel *channel) @@ -58,10 +58,9 @@ GraphicsLayer(GraphicsChannel *channel) // Access: Private // Description: //////////////////////////////////////////////////////////////////// -INLINE GraphicsLayer:: -GraphicsLayer(const GraphicsLayer&) { - display_cat.error() - << "GraphicsLayers should never be copied" << endl; +GraphicsLayer:: +GraphicsLayer(const GraphicsLayer &) { + nassertv(false); } //////////////////////////////////////////////////////////////////// @@ -69,16 +68,14 @@ GraphicsLayer(const GraphicsLayer&) { // Access: Private // Description: //////////////////////////////////////////////////////////////////// -INLINE GraphicsLayer &GraphicsLayer:: -operator=(const GraphicsLayer&) { - display_cat.error() - << "GraphicsLayers should never be assigned" << endl; - return *this; +void GraphicsLayer:: +operator = (const GraphicsLayer &) { + nassertv(false); } //////////////////////////////////////////////////////////////////// // Function: GraphicsLayer::Destructor -// Access: Public +// Access: Published // Description: //////////////////////////////////////////////////////////////////// GraphicsLayer:: @@ -91,7 +88,9 @@ GraphicsLayer:: for (dri = _display_regions.begin(); dri != _display_regions.end(); ++dri) { - (*dri)->_layer = NULL; + DisplayRegion *dr = (*dri); + MutexHolder holder(dr->_lock); + dr->_layer = NULL; } win_display_regions_changed(); @@ -102,17 +101,15 @@ GraphicsLayer:: //////////////////////////////////////////////////////////////////// // Function: GraphicsLayer::make_display_region -// Access: Public +// Access: Published // Description: Creates a new DisplayRegion that covers the entire // layer. //////////////////////////////////////////////////////////////////// DisplayRegion *GraphicsLayer:: make_display_region() { PT(DisplayRegion) dr = new DisplayRegion(this); - const GraphicsWindow *win = get_window(); - if (win != (GraphicsWindow *)NULL) { - dr->compute_pixels(win->get_width(), win->get_height()); - } + + MutexHolder holder(_lock); _display_regions.push_back(dr); win_display_regions_changed(); return dr; @@ -120,7 +117,7 @@ make_display_region() { //////////////////////////////////////////////////////////////////// // Function: GraphicsLayer::make_display_region -// Access: Public +// Access: Published // Description: Creates a new DisplayRegion that covers the indicated // sub-rectangle within the layer. //////////////////////////////////////////////////////////////////// @@ -128,10 +125,8 @@ DisplayRegion *GraphicsLayer:: make_display_region(float l, float r, float b, float t) { nassertr(this != (GraphicsLayer *)NULL, NULL); PT(DisplayRegion) dr = new DisplayRegion(this, l, r, b, t); - const GraphicsWindow *win = get_window(); - if (win != (GraphicsWindow *)NULL) { - dr->compute_pixels(win->get_width(), win->get_height()); - } + + MutexHolder holder(_lock); _display_regions.push_back(dr); win_display_regions_changed(); return dr; @@ -139,36 +134,43 @@ make_display_region(float l, float r, float b, float t) { //////////////////////////////////////////////////////////////////// // Function: GraphicsLayer::get_num_drs -// Access: Public +// Access: Published // Description: Returns the number of DisplayRegions associated with // the layer. //////////////////////////////////////////////////////////////////// int GraphicsLayer:: get_num_drs() const { + MutexHolder holder(_lock); return _display_regions.size(); } //////////////////////////////////////////////////////////////////// // Function: GraphicsLayer::get_dr -// Access: Public +// Access: Published // Description: Returns the nth DisplayRegion associated with the -// layer. +// layer. This might return NULL if another thread has +// recently removed a DisplayRegion. //////////////////////////////////////////////////////////////////// DisplayRegion *GraphicsLayer:: get_dr(int index) const { - nassertr(index >= 0 && index < (int)_display_regions.size(), NULL); - return _display_regions[index]; + MutexHolder holder(_lock); + if (index >= 0 && index < (int)_display_regions.size()) { + return _display_regions[index]; + } else { + return NULL; + } } //////////////////////////////////////////////////////////////////// // Function: GraphicsLayer::remove_dr -// Access: Public +// Access: Published // Description: Removes (and possibly deletes) the nth DisplayRegion // associated with the layer. All subsequent index // numbers will shift down one. //////////////////////////////////////////////////////////////////// void GraphicsLayer:: remove_dr(int index) { + MutexHolder holder(_lock); nassertv(index >= 0 && index < (int)_display_regions.size()); _display_regions[index]->_layer = NULL; _display_regions.erase(_display_regions.begin() + index); @@ -177,7 +179,7 @@ remove_dr(int index) { //////////////////////////////////////////////////////////////////// // Function: GraphicsLayer::remove_dr -// Access: Public +// Access: Published // Description: Removes (and possibly deletes) the indicated // DisplayRegion associated with the layer. All // subsequent index numbers will shift down one. @@ -186,8 +188,7 @@ remove_dr(int index) { //////////////////////////////////////////////////////////////////// bool GraphicsLayer:: remove_dr(DisplayRegion *display_region) { - // For whatever reason, VC++ considers == ambiguous unless we - // compare it to a PT(DisplayRegion) instead of a DisplayRegion*. + MutexHolder holder(_lock); PT(DisplayRegion) ptdr = display_region; DisplayRegions::iterator dri = find(_display_regions.begin(), _display_regions.end(), ptdr); @@ -200,40 +201,73 @@ remove_dr(DisplayRegion *display_region) { return false; } +//////////////////////////////////////////////////////////////////// +// Function: GraphicsLayer::get_channel +// Access: Published +// Description: Returns the GraphicsChannel that this layer is +// associated with. It is possible that the +// GraphicsChannel might have been deleted while an +// outstanding PT(GraphicsLayer) prevented all of its +// children layers from also being deleted; in this +// unlikely case, get_channel() may return NULL. +//////////////////////////////////////////////////////////////////// +GraphicsChannel *GraphicsLayer:: +get_channel() const { + MutexHolder holder(_lock); + return _channel; +} + //////////////////////////////////////////////////////////////////// // Function: GraphicsLayer::get_window -// Access: Public +// Access: Published // Description: Returns the GraphicsWindow that this layer is // ultimately associated with, or NULL if no window is // associated. //////////////////////////////////////////////////////////////////// GraphicsWindow *GraphicsLayer:: get_window() const { - nassertr(this != (GraphicsLayer *)NULL, NULL); + MutexHolder holder(_lock); return (_channel != (GraphicsChannel *)NULL) ? _channel->get_window() : NULL; } //////////////////////////////////////////////////////////////////// // Function: GraphicsLayer::get_pipe -// Access: Public +// Access: Published // Description: Returns the GraphicsPipe that this layer is // ultimately associated with, or NULL if no pipe is // associated. //////////////////////////////////////////////////////////////////// GraphicsPipe *GraphicsLayer:: get_pipe() const { + MutexHolder holder(_lock); return (_channel != (GraphicsChannel *)NULL) ? _channel->get_pipe() : NULL; } +//////////////////////////////////////////////////////////////////// +// Function: GraphicsLayer::set_active +// Access: Published +// Description: Sets the active flag on the layer. If the layer +// is marked as inactive, nothing will be rendered. +//////////////////////////////////////////////////////////////////// +void GraphicsLayer:: +set_active(bool active) { + MutexHolder holder(_lock); + if (active != _is_active) { + _is_active = active; + win_display_regions_changed(); + } +} + //////////////////////////////////////////////////////////////////// // Function: GraphicsLayer::channel_resized -// Access: Public, Virtual +// Access: Public // Description: This is called whenever the parent channel has been // resized; it should do whatever needs to be done to // adjust the layer to account for it. //////////////////////////////////////////////////////////////////// void GraphicsLayer:: channel_resized(int x, int y) { + MutexHolder holder(_lock); // Since a layer always fills the whole channel, when the channel // resizes so does the layer, by the same amount. DisplayRegions::iterator dri; @@ -246,11 +280,12 @@ channel_resized(int x, int y) { //////////////////////////////////////////////////////////////////// // Function: GraphicsLayer::win_display_regions_changed -// Access: Public +// Access: Private // Description: Intended to be called when the active state on a // nested channel or layer or display region changes, // forcing the window to recompute its list of active -// display regions. +// display regions. It is assumed the lock is already +// held. //////////////////////////////////////////////////////////////////// void GraphicsLayer:: win_display_regions_changed() { diff --git a/panda/src/display/graphicsLayer.h b/panda/src/display/graphicsLayer.h index fdd8916c3f..023593a357 100644 --- a/panda/src/display/graphicsLayer.h +++ b/panda/src/display/graphicsLayer.h @@ -19,21 +19,14 @@ #ifndef GRAPHICSLAYER_H #define GRAPHICSLAYER_H -//////////////////////////////////////////////////////////////////// -// Includes -//////////////////////////////////////////////////////////////////// -#include +#include "pandabase.h" #include "displayRegion.h" - -#include -#include - +#include "typedReferenceCount.h" +#include "pointerTo.h" +#include "mutex.h" #include "pvector.h" -//////////////////////////////////////////////////////////////////// -// Defines -//////////////////////////////////////////////////////////////////// class GraphicsChannel; class GraphicsWindow; class GraphicsPipe; @@ -50,15 +43,17 @@ class CullHandler; // without clearing the framebuffer between layers. //////////////////////////////////////////////////////////////////// class EXPCL_PANDA GraphicsLayer : public TypedReferenceCount { -protected: - +private: GraphicsLayer(); - GraphicsLayer(GraphicsChannel *); + GraphicsLayer(GraphicsChannel *channel); -public: - virtual ~GraphicsLayer(); +private: + GraphicsLayer(const GraphicsLayer ©); + void operator = (const GraphicsLayer ©); PUBLISHED: + virtual ~GraphicsLayer(); + DisplayRegion *make_display_region(); DisplayRegion *make_display_region(float l, float r, float b, float t); @@ -68,31 +63,26 @@ PUBLISHED: void remove_dr(int index); bool remove_dr(DisplayRegion *display_region); - INLINE GraphicsChannel *get_channel() const; + GraphicsChannel *get_channel() const; GraphicsWindow *get_window() const; GraphicsPipe *get_pipe() const; + void set_active(bool active); + INLINE bool is_active() const; + public: void channel_resized(int x, int y); +private: void win_display_regions_changed(); -PUBLISHED: - INLINE void set_active(bool active); - INLINE bool is_active() const; - -private: + Mutex _lock; GraphicsChannel *_channel; bool _is_active; typedef pvector< PT(DisplayRegion) > DisplayRegions; DisplayRegions _display_regions; -private: - - GraphicsLayer(const GraphicsLayer&); - GraphicsLayer& operator=(const GraphicsLayer&); - public: static TypeHandle get_class_type() { @@ -113,6 +103,7 @@ private: friend class GraphicsChannel; friend class GraphicsWindow; + friend class DisplayRegion; }; #include "graphicsLayer.I" diff --git a/panda/src/display/graphicsPipe.I b/panda/src/display/graphicsPipe.I index 8838b67b6e..a6d4aae8f3 100644 --- a/panda/src/display/graphicsPipe.I +++ b/panda/src/display/graphicsPipe.I @@ -16,21 +16,3 @@ // //////////////////////////////////////////////////////////////////// - - - -//////////////////////////////////////////////////////////////////// -// Function: GraphicsPipe::get_all_pipes -// Access: Private, Static -// Description: Returns a reference to the static _all_pipes -// container. This wrapper function allows us to -// guarantee creation of the container before we attempt -// to reference it. -//////////////////////////////////////////////////////////////////// -INLINE GraphicsPipe::Pipes &GraphicsPipe:: -get_all_pipes() { - if (_all_pipes == NULL) { - _all_pipes = new Pipes; - } - return *_all_pipes; -} diff --git a/panda/src/display/graphicsPipe.cxx b/panda/src/display/graphicsPipe.cxx index 0730ef76cd..e763cd1943 100644 --- a/panda/src/display/graphicsPipe.cxx +++ b/panda/src/display/graphicsPipe.cxx @@ -18,251 +18,93 @@ #include "graphicsPipe.h" #include "config_display.h" +#include "mutexHolder.h" -#include "load_dso.h" -#include "filename.h" -#include "pset.h" - -#include - -// Static variables -//////////////////////////////////////////////////////////////////// TypeHandle GraphicsPipe::_type_handle; -TypeHandle GraphicsPipe::PipeSpec::_type_handle; - -// These static members are pointers rather than concrete objects so -// we can guarantee order of creation at static init time. -GraphicsPipe::PipeFactory *GraphicsPipe::_factory = NULL; -GraphicsPipe::Pipes *GraphicsPipe::_all_pipes = NULL; - -GraphicsPipe::PipeSpec::~PipeSpec(void) {} - -TypeHandle GraphicsPipe::PipeSpec::get_class_type(void) { - return _type_handle; -} - -void GraphicsPipe::PipeSpec::init_type(void) { - PipeParam::init_type(); - register_type(_type_handle, "GraphicsPipe::PipeSpec", - PipeParam::get_class_type()); -} - -TypeHandle GraphicsPipe::PipeSpec::get_type(void) const { - return get_class_type(); -} - -TypeHandle GraphicsPipe::PipeSpec::force_init_type(void) { - init_type(); - return get_class_type(); -} //////////////////////////////////////////////////////////////////// // Function: GraphicsPipe::Constructor -// Access: Public -// Description: -//////////////////////////////////////////////////////////////////// -GraphicsPipe:: -GraphicsPipe(const PipeSpecifier &spec) : - Namable(spec.get_name()) -{ - // Add ourself to the global list of pipes. - get_all_pipes().push_back(this); -} - -//////////////////////////////////////////////////////////////////// -// Function: GraphicsPipe::Default Constructor -// Access: Private +// Access: Protected // Description: //////////////////////////////////////////////////////////////////// GraphicsPipe:: GraphicsPipe() { - display_cat.error() - << "GraphicsPipes should not be called with default constructor" << endl; } //////////////////////////////////////////////////////////////////// // Function: GraphicsPipe::Copy Constructor // Access: Private -// Description: +// Description: Don't try to copy GraphicsPipes. //////////////////////////////////////////////////////////////////// GraphicsPipe:: -GraphicsPipe(const GraphicsPipe&) { - display_cat.error() - << "GraphicsPipes should not be copied" << endl; +GraphicsPipe(const GraphicsPipe &) { + nassertv(false); } //////////////////////////////////////////////////////////////////// // Function: GraphicsPipe::Copy Assignment Operator // Access: Private -// Description: +// Description: Don't try to copy GraphicsPipes. //////////////////////////////////////////////////////////////////// -GraphicsPipe &GraphicsPipe:: -operator=(const GraphicsPipe&) { - display_cat.error() - << "GraphicsPipes should not be assigned" << endl; - return *this; +void GraphicsPipe:: +operator = (const GraphicsPipe &) { + nassertv(false); } - //////////////////////////////////////////////////////////////////// // Function: GraphicsPipe::Destructor -// Access: Public +// Access: Published // Description: //////////////////////////////////////////////////////////////////// GraphicsPipe:: ~GraphicsPipe() { - // We don't have to destruct our child windows 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. - Windows::const_iterator wi; + // On destruction, we need to clean up our references to all of the + // windows. + Windows::iterator wi; for (wi = _windows.begin(); wi != _windows.end(); ++wi) { - (*wi)->_pipe = NULL; - } - - // Remove ourself from the global list. - Pipes &all_pipes = get_all_pipes(); - Pipes::iterator pi = - find(all_pipes.begin(), all_pipes.end(), this); - if (pi != all_pipes.end()) { - all_pipes.erase(pi); - } -} - - -//////////////////////////////////////////////////////////////////// -// Function: GraphicsPipe::make_window -// Access: Public -// Description: Creates and returns a new window on the pipe. The -// window will automatically be added to the pipe's -// reference-countling list of windows; it must later be -// explicitly removed to destroy it (you should not -// attempt to delete it). -//////////////////////////////////////////////////////////////////// -GraphicsWindow *GraphicsPipe:: -make_window() { - FactoryParams params; - params.add_param(new GraphicsWindow::WindowPipe(this)); - - GraphicsWindow *win = GraphicsWindow::get_factory(). - make_instance(get_window_type(), params); - nassertr(win != (GraphicsWindow *)NULL, NULL); - - add_window(win); - return win; -} - -//////////////////////////////////////////////////////////////////// -// Function: GraphicsPipe::make_window -// Access: Public -// Description: Creates and returns a new window on the pipe. The -// window will automatically be added to the pipe's -// reference-countling list of windows; it must later be -// explicitly removed to destroy it (you should not -// attempt to delete it). -//////////////////////////////////////////////////////////////////// -GraphicsWindow *GraphicsPipe:: -make_window(const GraphicsWindow::Properties &props) { - FactoryParams params; - params.add_param(new GraphicsWindow::WindowPipe(this)); - params.add_param(new GraphicsWindow::WindowProps(props)); - - GraphicsWindow *win = GraphicsWindow::get_factory(). - make_instance(get_window_type(), params); - nassertr(win != (GraphicsWindow *)NULL, NULL); - - add_window(win); - return win; -} - -//////////////////////////////////////////////////////////////////// -// Function: GraphicsPipe::remove_window -// Access: Public -// Description: Deletes a previously-created window by removing it -// from the reference-counting list of windows owned by -// the pipe. Note that the window will not actually be -// deleted until all pointers to it (for instance, on -// mouse objects, etc.) are cleared. -//////////////////////////////////////////////////////////////////// -void GraphicsPipe:: -remove_window(GraphicsWindow *window) { - // For whatever reason, VC++ considers == ambiguous unless we - // compare it to a PT(GraphicsWindow) instead of a GraphicsWindow*. - PT(GraphicsWindow) ptwin = window; - Windows::iterator wi = - find(_windows.begin(), _windows.end(), ptwin); - if (wi != _windows.end()) { - _windows.erase(wi); + GraphicsWindow *window = (*wi); + window->_pipe = NULL; } } //////////////////////////////////////////////////////////////////// // Function: GraphicsPipe::get_num_windows -// Access: Public +// Access: Published // Description: Returns the number of windows that have been created // on this pipe. //////////////////////////////////////////////////////////////////// int GraphicsPipe:: get_num_windows() const { - return _windows.size(); + int result; + { + MutexHolder holder(_lock); + result = _windows.size(); + } + return result; } //////////////////////////////////////////////////////////////////// // Function: GraphicsPipe::get_window -// Access: Public -// Description: Returns the nth window associated with this pipe. n -// must be between 0 and get_num_windows(). +// Access: Published +// Description: Returns the nth window that has been created +// on this pipe. It is possible for this to return NULL +// due to a window being removed in another thread. //////////////////////////////////////////////////////////////////// -GraphicsWindow *GraphicsPipe:: +PT(GraphicsWindow) GraphicsPipe:: get_window(int n) const { - nassertr(n >= 0 && n < get_num_windows(), NULL); - return _windows[n]; + PT(GraphicsWindow) result; + { + MutexHolder holder(_lock); + if (n >= 0 && n < (int)_windows.size()) { + result = _windows[n]; + } + } + return result; } -//////////////////////////////////////////////////////////////////// -// Function: GraphicsPipe::get_num_pipes -// Access: Public, Static -// Description: Returns the total number of pipes in the universe. -//////////////////////////////////////////////////////////////////// -int GraphicsPipe:: -get_num_pipes() { - return get_all_pipes().size(); -} - -//////////////////////////////////////////////////////////////////// -// Function: GraphicsPipe::get_pipe -// Access: Public, Static -// Description: Returns the nth pipe in the universe. n must be -// between 0 and get_num_pipes(). -//////////////////////////////////////////////////////////////////// -GraphicsPipe *GraphicsPipe:: -get_pipe(int n) { - nassertr(n >= 0 && n < get_num_pipes(), NULL); - return get_all_pipes()[n]; -} - -//////////////////////////////////////////////////////////////////// -// Function: GraphicsPipe::get_glx_display -// Access: Public, Virtual -// Description: Returns the glxDisplay information associated with -// this pipe, if any. This allows us to define several -// kinds of GraphicsPipe objects that manage some -// glx-specific stuff, without having them all inherit -// from a common glx base class. This allows the -// glxGraphicsWindow to ask questions about the -// glx-specific stuff without knowing what kind of -// glxGraphicsPipe it has. Non-glx pipes will simply -// return NULL for this function. -//////////////////////////////////////////////////////////////////// -glxDisplay *GraphicsPipe:: -get_glx_display() { - return (glxDisplay *)NULL; -} - - //////////////////////////////////////////////////////////////////// // Function: GraphicsPipe::get_num_hw_channels -// Access: Protected, Virtual +// Access: Public, Virtual // Description: Returns the number of hardware channels available for // pipes of this type. See get_hw_channel(). //////////////////////////////////////////////////////////////////// @@ -271,7 +113,6 @@ get_num_hw_channels() { return 0; } - //////////////////////////////////////////////////////////////////// // Function: GraphicsPipe::get_hw_channel // Access: Public, Virtual @@ -287,92 +128,44 @@ get_num_hw_channels() { // always return NULL. //////////////////////////////////////////////////////////////////// HardwareChannel *GraphicsPipe:: -get_hw_channel(GraphicsWindow*, int) { +get_hw_channel(GraphicsWindow *, int) { return (HardwareChannel*)0L; } //////////////////////////////////////////////////////////////////// // Function: GraphicsPipe::add_window // Access: Protected -// Description: Adds a newly-created window to the set of windows -// owned by the pipe. This function is intended to be -// called from a derived class' make_window() function. +// Description: This is intended to be called by the derived +// make_window() function to add the newly-created +// window to the list of windows owned by this pipe. //////////////////////////////////////////////////////////////////// void GraphicsPipe:: -add_window(GraphicsWindow *win) { - _windows.push_back(win); -} - -void GraphicsPipe::read_priorities(void) { - PipeFactory &factory = get_factory(); - if (factory.get_num_preferred() == 0) { - Config::ConfigTable::Symbol::iterator i; - for (i = preferred_pipe_begin(); i != preferred_pipe_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 pipe preference: " << type_name - << "\n"; - } else { - display_cat.debug() - << "Specifying type " << type << " for pipe preference.\n"; - factory.add_preferred(type); - } - } - } +add_window(GraphicsWindow *window) { + nassertv(window->_pipe == this); + MutexHolder holder(_lock); + _windows.push_back(window); } //////////////////////////////////////////////////////////////////// -// Function: GraphicsPipe::get_factory -// Access: Public, Static -// Description: Returns the factory object that can be used to -// register new kinds of GraphicsPipe objects that may -// be created. +// Function: GraphicsPipe::remove_window +// Access: Protected +// Description: This is intended to be called by the GraphicsEngine +// when a window is to be removed. It returns true if +// the window is removed, or false if it was not found. //////////////////////////////////////////////////////////////////// -GraphicsPipe::PipeFactory &GraphicsPipe:: -get_factory() { - if (_factory == (PipeFactory *)NULL) { - _factory = new PipeFactory; - } - return (*_factory); -} - -void GraphicsPipe::resolve_modules(void) { - Config::ConfigTable::Symbol::iterator i; - - // Build up a set of the modules we've already loaded as we go, so - // we don't attempt to load a given module more than once. - pset already_loaded; - - for (i=pipe_modules_begin(); i!=pipe_modules_end(); ++i) { - string name = (*i).Val(); - if (already_loaded.insert(name).second) { - Filename dlname = Filename::dso_filename("lib" + name + ".so"); - display_cat.info() - << "loading display module: " << dlname.to_os_specific() << endl; - void *tmp = load_dso(dlname); - if (tmp == (void*)0L) { - display_cat.info() - << "Unable to load: " << load_dso_error() << endl; - } - } - } - for (i=gsg_modules_begin(); i!=gsg_modules_end(); ++i) { - string name = (*i).Val(); - if (already_loaded.insert(name).second) { - Filename dlname = Filename::dso_filename("lib" + name + ".so"); - display_cat.info() - << "loading GSG module: " << dlname.to_os_specific() << endl; - void *tmp = load_dso(dlname); - if (tmp == (void*)0L) { - display_cat.info() - << "Unable to load: " << load_dso_error() << endl; - } +bool GraphicsPipe:: +remove_window(GraphicsWindow *window) { + bool removed = false; + { + MutexHolder holder(_lock); + PT(GraphicsWindow) ptwin = window; + window->_pipe = NULL; + Windows::iterator wi = find(_windows.begin(), _windows.end(), ptwin); + if (wi != _windows.end()) { + _windows.erase(wi); + removed = true; } } - read_priorities(); - GraphicsWindow::read_priorities(); - GraphicsPipe::read_priorities(); + return removed; } diff --git a/panda/src/display/graphicsPipe.h b/panda/src/display/graphicsPipe.h index b713215082..11c4dc9e18 100644 --- a/panda/src/display/graphicsPipe.h +++ b/panda/src/display/graphicsPipe.h @@ -15,114 +15,64 @@ // panda3d@yahoogroups.com . // //////////////////////////////////////////////////////////////////// + #ifndef GRAPHICSPIPE_H #define GRAPHICSPIPE_H -// -//////////////////////////////////////////////////////////////////// -// Includes -//////////////////////////////////////////////////////////////////// -#include -#include "graphicsWindow.h" -#include "hardwareChannel.h" -#include "pipeSpec.h" +#include "pandabase.h" -#include -#include -#include -#include - -#include +#include "typedReferenceCount.h" +#include "pointerTo.h" +#include "mutex.h" #include "pvector.h" -//////////////////////////////////////////////////////////////////// -// Defines -//////////////////////////////////////////////////////////////////// -class GraphicsPipe; -class glxDisplay; +class HardwareChannel; +class GraphicsWindow; //////////////////////////////////////////////////////////////////// // Class : GraphicsPipe -// Description : +// Description : An object to create GraphicsWindows that share a +// particular 3-D API. Normally, there will only be one +// GraphicsPipe in an application, although it is +// possible to have multiple of these at once if there +// are multiple different API's available in the same +// machine. +// +// Often, the GraphicsPipe corresponds to a physical +// output device, hence the term "pipe", but this is not +// necessarily the case. +// +// The GraphicsPipe is used by the GraphicsEngine object +// to create and destroy windows; it keeps ownership of +// the windows it creates. //////////////////////////////////////////////////////////////////// -class EXPCL_PANDA GraphicsPipe : public TypedReferenceCount, public Namable { +class EXPCL_PANDA GraphicsPipe : public TypedReferenceCount { +protected: + GraphicsPipe(); +private: + GraphicsPipe(const GraphicsPipe ©); + void operator = (const GraphicsPipe ©); + PUBLISHED: - GraphicsPipe(const PipeSpecifier &spec); virtual ~GraphicsPipe(); - GraphicsWindow *make_window(); - GraphicsWindow *make_window(const GraphicsWindow::Properties&); - - void remove_window(GraphicsWindow *window); - - virtual TypeHandle get_window_type() const=0; - - // Functions for obtaining the set of windows associated with this - // pipe, and the set of all GraphicsPipes in the world. - int get_num_windows() const; - GraphicsWindow *get_window(int n) const; - - static int get_num_pipes(); - static GraphicsPipe *get_pipe(int n); + PT(GraphicsWindow) get_window(int n) const; public: - // This function's interface must be defined here even though we - // know nothing about glx displays at this point. - virtual glxDisplay *get_glx_display(); - -protected: virtual int get_num_hw_channels(); - virtual HardwareChannel *get_hw_channel(GraphicsWindow *, int); - - void add_window(GraphicsWindow *win); - -public: - // Factory stuff - typedef Factory PipeFactory; - typedef FactoryParam PipeParam; - - // Make a factory parameter type for the pipe specifier - class EXPCL_PANDA PipeSpec : public PipeParam { - public: - INLINE PipeSpec(void) : PipeParam() {} - INLINE PipeSpec(PipeSpecifier& p) : PipeParam(), _p(p) {} - virtual ~PipeSpec(void); - INLINE const PipeSpecifier &get_specifier(void) { return _p; } - public: - static TypeHandle get_class_type(void); - static void init_type(void); - virtual TypeHandle get_type(void) const; - virtual TypeHandle force_init_type(void); - private: - PipeSpecifier _p; - - static TypeHandle _type_handle; - }; - - static PipeFactory &get_factory(); - static void resolve_modules(void); - -private: - static void read_priorities(void); + virtual HardwareChannel *get_hw_channel(GraphicsWindow *window, int index); protected: + virtual PT(GraphicsWindow) make_window()=0; - GraphicsPipe(); - GraphicsPipe(const GraphicsPipe ©); - GraphicsPipe &operator = (const GraphicsPipe ©); + void add_window(GraphicsWindow *window); + bool remove_window(GraphicsWindow *window); -private: - // Some private type declarations. These must be declared here so - // we can declare the public iterator types, below. typedef pvector< PT(GraphicsWindow) > Windows; - typedef pvector Pipes; - Windows _windows; + Mutex _lock; - static PipeFactory *_factory; - static Pipes *_all_pipes; - INLINE static Pipes &get_all_pipes(); public: static TypeHandle get_class_type() { @@ -130,10 +80,8 @@ public: } static void init_type() { TypedReferenceCount::init_type(); - Namable::init_type(); register_type(_type_handle, "GraphicsPipe", - TypedReferenceCount::get_class_type(), - Namable::get_class_type()); + TypedReferenceCount::get_class_type()); } virtual TypeHandle get_type() const { return get_class_type(); @@ -142,9 +90,7 @@ public: private: static TypeHandle _type_handle; - - // this is so it can call get_hw_channel - friend class GraphicsWindow; + friend class GraphicsEngine; }; #include "graphicsPipe.I" diff --git a/panda/src/display/graphicsPipeSelection.I b/panda/src/display/graphicsPipeSelection.I new file mode 100644 index 0000000000..e02bf68e4d --- /dev/null +++ b/panda/src/display/graphicsPipeSelection.I @@ -0,0 +1,57 @@ +// Filename: graphicsPipeSelection.I +// Created by: drose (15Aug02) +// +//////////////////////////////////////////////////////////////////// +// +// 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: GraphicsPipeSelection::resolve_modules +// Access: Published +// Description: Conditionally calls do_resolve_modules(), if it has +// not been called before. +//////////////////////////////////////////////////////////////////// +INLINE void GraphicsPipeSelection:: +resolve_modules() const { + if (!_resolved_modules) { + ((GraphicsPipeSelection *)this)->do_resolve_modules(); + } +} + +//////////////////////////////////////////////////////////////////// +// Function: GraphicsPipeSelection::get_global_ptr +// Access: Published, Static +// Description: Returns a pointer to the one global +// GraphicsPipeSelection object. +//////////////////////////////////////////////////////////////////// +INLINE GraphicsPipeSelection *GraphicsPipeSelection:: +get_global_ptr() { + if (_global_ptr == (GraphicsPipeSelection *)NULL) { + _global_ptr = new GraphicsPipeSelection; + } + return _global_ptr; +} + +//////////////////////////////////////////////////////////////////// +// Function: GraphicsPipeSelection::PipeType::Constructor +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +INLINE GraphicsPipeSelection::PipeType:: +PipeType(TypeHandle type, PipeConstructorFunc *constructor) : + _type(type), + _constructor(constructor) +{ +} diff --git a/panda/src/display/graphicsPipeSelection.cxx b/panda/src/display/graphicsPipeSelection.cxx new file mode 100644 index 0000000000..591b351532 --- /dev/null +++ b/panda/src/display/graphicsPipeSelection.cxx @@ -0,0 +1,251 @@ +// Filename: graphicsPipeSelection.cxx +// Created by: drose (15Aug02) +// +//////////////////////////////////////////////////////////////////// +// +// 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 "graphicsPipeSelection.h" +#include "mutexHolder.h" +#include "string_utils.h" +#include "filename.h" +#include "load_dso.h" +#include "config_display.h" + +GraphicsPipeSelection *GraphicsPipeSelection::_global_ptr = NULL; + +//////////////////////////////////////////////////////////////////// +// Function: GraphicsPipeSelection::Constructor +// Access: Protected +// Description: +//////////////////////////////////////////////////////////////////// +GraphicsPipeSelection:: +GraphicsPipeSelection() { + _resolved_modules = false; +} + +//////////////////////////////////////////////////////////////////// +// Function: GraphicsPipeSelection::Destructor +// Access: Protected +// Description: +//////////////////////////////////////////////////////////////////// +GraphicsPipeSelection:: +~GraphicsPipeSelection() { +} + +//////////////////////////////////////////////////////////////////// +// Function: GraphicsPipeSelection::get_num_pipe_types +// Access: Published +// Description: Returns the number of different types of +// GraphicsPipes that are available to create through +// this interface. +//////////////////////////////////////////////////////////////////// +int GraphicsPipeSelection:: +get_num_pipe_types() const { + resolve_modules(); + + int result; + { + MutexHolder holder(_lock); + result = _pipe_types.size(); + } + return result; +} + +//////////////////////////////////////////////////////////////////// +// Function: GraphicsPipeSelection::get_pipe_type +// Access: Published +// Description: Returns the nth type of GraphicsPipe available +// through this interface. +//////////////////////////////////////////////////////////////////// +TypeHandle GraphicsPipeSelection:: +get_pipe_type(int n) const { + resolve_modules(); + + TypeHandle result; + { + MutexHolder holder(_lock); + if (n >= 0 && n < (int)_pipe_types.size()) { + result = _pipe_types[n]._type; + } + } + return result; +} + +//////////////////////////////////////////////////////////////////// +// Function: GraphicsPipeSelection::make_pipe +// Access: Published +// Description: Creates a new GraphicsPipe of the indicated type (or +// a type more specific than the indicated type, if +// necessary) and returns it. Returns NULL if the type +// cannot be matched. +//////////////////////////////////////////////////////////////////// +PT(GraphicsPipe) GraphicsPipeSelection:: +make_pipe(TypeHandle type) { + resolve_modules(); + + MutexHolder holder(_lock); + PipeTypes::const_iterator ti; + + // First, look for an exact match of the requested type. + for (ti = _pipe_types.begin(); ti != _pipe_types.end(); ++ti) { + const PipeType &ptype = (*ti); + if (ptype._type == type) { + // Here's an exact match. + PT(GraphicsPipe) pipe = (*ptype._constructor)(); + if (pipe != (GraphicsPipe *)NULL) { + return pipe; + } + } + } + + // Now look for a more-specific type. + for (ti = _pipe_types.begin(); ti != _pipe_types.end(); ++ti) { + const PipeType &ptype = (*ti); + if (ptype._type.is_derived_from(type)) { + // Here's an approximate match. + PT(GraphicsPipe) pipe = (*ptype._constructor)(); + if (pipe != (GraphicsPipe *)NULL) { + return pipe; + } + } + } + + // Couldn't find a matching pipe type. + return NULL; +} + +//////////////////////////////////////////////////////////////////// +// Function: GraphicsPipeSelection::make_default_pipe +// Access: Published +// Description: Creates a new GraphicsPipe of some arbitrary type. +// The user may specify a preference using the Configrc +// file; otherwise, one will be chosen arbitrarily. +//////////////////////////////////////////////////////////////////// +PT(GraphicsPipe) GraphicsPipeSelection:: +make_default_pipe() { + resolve_modules(); + + MutexHolder holder(_lock); + PipeTypes::const_iterator ti; + + // First, look for an exact match of the requested type (excepting + // case and hyphen/underscore). + for (ti = _pipe_types.begin(); ti != _pipe_types.end(); ++ti) { + const PipeType &ptype = (*ti); + if (cmp_nocase_uh(ptype._type.get_name(), preferred_pipe) == 0) { + // Here's an exact match. + PT(GraphicsPipe) pipe = (*ptype._constructor)(); + if (pipe != (GraphicsPipe *)NULL) { + return pipe; + } + } + } + + // No match; look for a substring match. + string preferred_name = downcase(preferred_pipe); + for (ti = _pipe_types.begin(); ti != _pipe_types.end(); ++ti) { + const PipeType &ptype = (*ti); + string ptype_name = downcase(ptype._type.get_name()); + if (ptype_name.find(preferred_name) != string::npos) { + // Here's a substring match. + PT(GraphicsPipe) pipe = (*ptype._constructor)(); + if (pipe != (GraphicsPipe *)NULL) { + return pipe; + } + } + } + + // Couldn't find a matching pipe type; choose one arbitrarily. + for (ti = _pipe_types.begin(); ti != _pipe_types.end(); ++ti) { + const PipeType &ptype = (*ti); + PT(GraphicsPipe) pipe = (*ptype._constructor)(); + if (pipe != (GraphicsPipe *)NULL) { + return pipe; + } + } + + // Nothing. Probably the list was empty. + return NULL; +} + +//////////////////////////////////////////////////////////////////// +// Function: GraphicsPipeSelection::add_pipe_type +// Access: Public +// Description: Adds a new kind of GraphicsPipe to the list of +// available pipes for creation. Normally, this is +// called at static init type by the various shared +// libraries as they are linked in. Returns true on +// success, false on failure. +//////////////////////////////////////////////////////////////////// +bool GraphicsPipeSelection:: +add_pipe_type(TypeHandle type, PipeConstructorFunc *func) { + if (!type.is_derived_from(GraphicsPipe::get_class_type())) { + display_cat.warning() + << "Attempt to register " << type << " as a GraphicsPipe type.\n"; + return false; + } + + // First, make sure we don't already have a GraphicsPipe of this + // type. + MutexHolder holder(_lock); + PipeTypes::const_iterator ti; + for (ti = _pipe_types.begin(); ti != _pipe_types.end(); ++ti) { + const PipeType &ptype = (*ti); + if (ptype._type == type) { + display_cat.warning() + << "Attempt to register GraphicsPipe type " << type + << " more than once.\n"; + return false; + } + } + + // Ok, now add a new entry. + _pipe_types.push_back(PipeType(type, func)); + + return true; +} + +//////////////////////////////////////////////////////////////////// +// Function: GraphicsPipeSelection::do_resolve_modules +// Access: Private +// Description: Loads the shared objects listed in the load-display +// Configrc variable, which should make all of the +// dynamic GraphicsPipes available. +//////////////////////////////////////////////////////////////////// +void GraphicsPipeSelection:: +do_resolve_modules() { + Config::ConfigTable::Symbol::iterator ci; + + // Build up a set of the modules we've already loaded as we go, so + // we don't attempt to load a given module more than once. + pset already_loaded; + + for (ci = display_modules_begin(); ci != display_modules_end(); ++ci) { + string name = (*ci).Val(); + if (already_loaded.insert(name).second) { + Filename dlname = Filename::dso_filename("lib" + name + ".so"); + display_cat.info() + << "loading display module: " << dlname.to_os_specific() << endl; + void *tmp = load_dso(dlname); + if (tmp == (void *)NULL) { + display_cat.info() + << "Unable to load: " << load_dso_error() << endl; + } + } + } + + _resolved_modules = true; +} + diff --git a/panda/src/display/graphicsPipeSelection.h b/panda/src/display/graphicsPipeSelection.h new file mode 100644 index 0000000000..05b8d6d6b9 --- /dev/null +++ b/panda/src/display/graphicsPipeSelection.h @@ -0,0 +1,86 @@ +// Filename: graphicsPipeSelection.h +// Created by: drose (15Aug02) +// +//////////////////////////////////////////////////////////////////// +// +// 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 GRAPHICSPIPESELECTION_H +#define GRAPHICSPIPESELECTION_H + +#include "pandabase.h" + +#include "graphicsPipe.h" +#include "pointerTo.h" +#include "typeHandle.h" +#include "mutex.h" + +class HardwareChannel; +class GraphicsWindow; + +//////////////////////////////////////////////////////////////////// +// Class : GraphicsPipeSelection +// Description : This maintains a list of GraphicsPipes by type that +// are available for creation. Normally there is one +// default interactive GraphicsPipe, and possibly other +// types available as well. +// +// This is used to manage creation of a GraphicsPipe +// when you don't particularly care what kind of pipe +// you create; you just want to render to the screen. +// If your application does have a preference, you can +// of course invoke the appropriate GraphicsPipe +// constructor yourself. +//////////////////////////////////////////////////////////////////// +class EXPCL_PANDA GraphicsPipeSelection { +protected: + GraphicsPipeSelection(); + ~GraphicsPipeSelection(); + +PUBLISHED: + int get_num_pipe_types() const; + TypeHandle get_pipe_type(int n) const; + + PT(GraphicsPipe) make_pipe(TypeHandle type); + PT(GraphicsPipe) make_default_pipe(); + + INLINE void resolve_modules() const; + + INLINE static GraphicsPipeSelection *get_global_ptr(); + +public: + typedef PT(GraphicsPipe) PipeConstructorFunc(); + bool add_pipe_type(TypeHandle type, PipeConstructorFunc *func); + +private: + void do_resolve_modules(); + + class PipeType { + public: + INLINE PipeType(TypeHandle type, PipeConstructorFunc *constructor); + TypeHandle _type; + PipeConstructorFunc *_constructor; + }; + typedef pvector PipeTypes; + PipeTypes _pipe_types; + bool _resolved_modules; + Mutex _lock; + + static GraphicsPipeSelection *_global_ptr; +}; + +#include "graphicsPipeSelection.I" + +#endif + diff --git a/panda/src/display/graphicsStateGuardian.cxx b/panda/src/display/graphicsStateGuardian.cxx index 3221e37a96..2c68908194 100644 --- a/panda/src/display/graphicsStateGuardian.cxx +++ b/panda/src/display/graphicsStateGuardian.cxx @@ -417,8 +417,14 @@ prepare_lens() { // Description: Called before each frame is rendered, to allow the // GSG a chance to do any internal cleanup before // beginning the frame. +// +// The return value is true if successful (in which case +// the frame will be drawn and end_frame() will be +// called later), or false if unsuccessful (in which +// case nothing will be drawn and end_frame() will not +// be called). //////////////////////////////////////////////////////////////////// -void GraphicsStateGuardian:: +bool GraphicsStateGuardian:: begin_frame() { // Undo any lighting we had enabled last frame, to force the lights // to be reissued, in case their parameters or positions have @@ -466,6 +472,40 @@ begin_frame() { // measurably expensive. modify_state(get_untextured_state()); #endif + return true; +} + +//////////////////////////////////////////////////////////////////// +// Function: GraphicsStateGuardian::begin_scene +// Access: Public, Virtual +// Description: Called between begin_frame() and end_frame() to mark +// the beginning of drawing commands for a "scene" +// (usually a particular DisplayRegion) within a frame. +// All 3-D drawing commands, except the clear operation, +// must be enclosed within begin_scene() .. end_scene(). +// +// The return value is true if successful (in which case +// the scene will be drawn and end_scene() will be +// called later), or false if unsuccessful (in which +// case nothing will be drawn and end_scene() will not +// be called). +//////////////////////////////////////////////////////////////////// +bool GraphicsStateGuardian:: +begin_scene() { + return true; +} + +//////////////////////////////////////////////////////////////////// +// Function: GraphicsStateGuardian::end_scene +// Access: Public, Virtual +// Description: Called between begin_frame() and end_frame() to mark +// the end of drawing commands for a "scene" (usually a +// particular DisplayRegion) within a frame. All 3-D +// drawing commands, except the clear operation, must be +// enclosed within begin_scene() .. end_scene(). +//////////////////////////////////////////////////////////////////// +void GraphicsStateGuardian:: +end_scene() { } //////////////////////////////////////////////////////////////////// @@ -1338,6 +1378,16 @@ unmark_prepared_geom_node(GeomNodeContext *gnc) { return removed; } +//////////////////////////////////////////////////////////////////// +// Function: GraphicsStateGuardian::free_pointers +// Access: Protected, Virtual +// Description: Frees some memory that was explicitly allocated +// within the glgsg. +//////////////////////////////////////////////////////////////////// +void GraphicsStateGuardian:: +free_pointers() { +} + //////////////////////////////////////////////////////////////////// // Function: GraphicsStateGuardian::close_gsg // Access: Protected, Virtual @@ -1348,6 +1398,10 @@ unmark_prepared_geom_node(GeomNodeContext *gnc) { //////////////////////////////////////////////////////////////////// void GraphicsStateGuardian:: close_gsg() { + free_pointers(); + release_all_textures(); + release_all_geoms(); + _win = (GraphicsWindow *)NULL; } @@ -1535,31 +1589,3 @@ get_factory() { } return (*_factory); } - -void GraphicsStateGuardian:: -read_priorities(void) { - GsgFactory &factory = get_factory(); - if (factory.get_num_preferred() == 0) { - Config::ConfigTable::Symbol::iterator i; - for (i = preferred_gsg_begin(); i != preferred_gsg_end(); ++i) { - ConfigString type_name = (*i).Val(); - TypeHandle type = TypeRegistry::ptr()->find_type(type_name); - if (type == TypeHandle::none()) { - gsg_cat.warning() - << "Unknown type requested for GSG preference: " << type_name - << "\n"; - } else { - gsg_cat.debug() - << "Specifying type " << type << " for GSG preference.\n"; - factory.add_preferred(type); - } - } - } -} - -void GraphicsStateGuardian::start_rendering(void) { -} - -void GraphicsStateGuardian::finish_rendering(void) { -} - diff --git a/panda/src/display/graphicsStateGuardian.h b/panda/src/display/graphicsStateGuardian.h index 8bee8d14e4..93fb935f4b 100644 --- a/panda/src/display/graphicsStateGuardian.h +++ b/panda/src/display/graphicsStateGuardian.h @@ -101,12 +101,11 @@ public: INLINE void enable_normals(bool val) { _normals_enabled = val; } - virtual void begin_frame(); + virtual bool begin_frame(); + virtual bool begin_scene(); + virtual void end_scene(); virtual void end_frame(); - virtual void start_rendering(void); - virtual void finish_rendering(void); - // These functions will be queried by the GeomIssuer to determine if // it should issue normals, texcoords, and/or colors, based on the // GSG's current state. @@ -190,6 +189,7 @@ protected: bool mark_prepared_geom_node(GeomNodeContext *gnc); bool unmark_prepared_geom_node(GeomNodeContext *gnc); + virtual void free_pointers(); virtual void close_gsg(); #ifdef DO_PSTATS @@ -353,7 +353,6 @@ public: static GsgFactory &get_factory(); private: - static void read_priorities(void); static GsgFactory *_factory; public: diff --git a/panda/src/display/graphicsWindow.I b/panda/src/display/graphicsWindow.I index 65955cd556..a3f05f9556 100644 --- a/panda/src/display/graphicsWindow.I +++ b/panda/src/display/graphicsWindow.I @@ -16,190 +16,44 @@ // //////////////////////////////////////////////////////////////////// -#include //////////////////////////////////////////////////////////////////// -// Function: GraphicsWindow::Properties::Copy Constructor +// Function: GraphicsWindow::is_closed // Access: Published -// Description: +// Description: Returns true if the window has not yet been opened, +// or has been fully closed, false if it is open. The +// window is not opened immediately after +// GraphicsEngine::make_window() is called; nor is it +// closed immediately after +// GraphicsEngine::remove_window() is called. Either +// operation may take a frame or two. //////////////////////////////////////////////////////////////////// -INLINE GraphicsWindow::Properties:: -Properties(const Properties ©) { - (*this) = copy; +INLINE bool GraphicsWindow:: +is_closed() const { + return !_properties.get_open(); } //////////////////////////////////////////////////////////////////// -// Function: GraphicsWindow::Properties::Copy Assignment Operator +// Function: GraphicsWindow::is_active // Access: Published -// Description: +// Description: Returns true if the window is ready to be rendered +// into, false otherwise. //////////////////////////////////////////////////////////////////// -INLINE void GraphicsWindow::Properties:: -operator = (const Properties ©) { - ClearableRegion::operator = (copy); - _xorg = copy._xorg; - _yorg = copy._yorg; - _xsize = copy._xsize; - _ysize = copy._ysize; - _title = copy._title; - _border = copy._border; - _fullscreen = copy._fullscreen; - _mask = copy._mask; - _want_depth_bits = copy._want_depth_bits; - _want_color_bits = copy._want_color_bits; - _bCursorIsVisible = copy._bCursorIsVisible; +INLINE bool GraphicsWindow:: +is_active() const { + // Make this smarter? + return _properties.get_open() && !_properties.get_minimized(); } //////////////////////////////////////////////////////////////////// -// Function: GraphicsWindow::Properties::Destructor +// Function: GraphicsWindow::is_fullscreen // Access: Published -// Description: +// Description: Returns true if the window has been opened as a +// fullscreen window, false otherwise. //////////////////////////////////////////////////////////////////// -INLINE GraphicsWindow::Properties:: -~Properties() { -} - -//////////////////////////////////////////////////////////////////// -// Function: GraphicsWindow::Properties::set_origin -// Access: Published -// Description: Specifies the origin on the screen (in pixels, -// relative to the top-left corner) at which the window -// should appear. This is the origin of the top-left -// corner of the useful part of the window, not -// including decorations. -//////////////////////////////////////////////////////////////////// -INLINE void GraphicsWindow::Properties:: -set_origin(int xorg, int yorg) { - _xorg = xorg; - _yorg = yorg; -} - -//////////////////////////////////////////////////////////////////// -// Function: GraphicsWindow::Properties::set_size -// Access: Published -// Description: Specifies the requested size of the window, in -// pixels. This is the size of the useful part of the -// window, not including decorations. -//////////////////////////////////////////////////////////////////// -INLINE void GraphicsWindow::Properties:: -set_size(int xsize, int ysize) { - _xsize = xsize; - _ysize = ysize; -} - -//////////////////////////////////////////////////////////////////// -// Function: GraphicsWindow::Properties::set_title -// Access: Published -// Description: Specifies the title that should be assigned to the -// window. -//////////////////////////////////////////////////////////////////// -INLINE void GraphicsWindow::Properties:: -set_title(const string &title) { - _title = title; -} - -//////////////////////////////////////////////////////////////////// -// Function: GraphicsWindow::Properties::set_border -// Access: Published -// Description: Specifies whether the window should be created with a -// border (true, the default) or not (false). -//////////////////////////////////////////////////////////////////// -INLINE void GraphicsWindow::Properties:: -set_border(bool border) { - _border = border; -} - -/* -//////////////////////////////////////////////////////////////////// -// Function: GraphicsWindow::Properties::set_cursor_visible -// Access: Published -// Description: Specifies if mouse cursor is visible -//////////////////////////////////////////////////////////////////// -INLINE void GraphicsWindow::Properties:: -set_cursor_visible(bool IsVisible) { - _bCursorIsVisible=IsVisible; // note: gsg should override to implement -} -*/ - -//////////////////////////////////////////////////////////////////// -// Function: GraphicsWindow::Properties::set_mask -// Access: Published -// Description: Specifies the set of graphics properties that are -// required for the context associated with the window. -// This should be the union of the appropriate bits -// defined in WindowModeType. -//////////////////////////////////////////////////////////////////// -INLINE void GraphicsWindow::Properties:: -set_mask(uint mask) { - _mask = mask; -} - -//////////////////////////////////////////////////////////////////// -// Function: GraphicsWindow::Properties::set_bit_depth -// Access: Published -// Description: Specifies the minimum number of bits that are -// required for the depth buffer and color buffer, -// respectively. -//////////////////////////////////////////////////////////////////// -INLINE void GraphicsWindow::Properties:: -set_bit_depth(int want_depth_bits, int want_color_bits) { - _want_depth_bits = want_depth_bits; - _want_color_bits = want_color_bits; -} - -//////////////////////////////////////////////////////////////////// -// Function: GraphicsWindow::get_properties -// Access: Published -// Description: Returns the full Properties structure that describes -// the window. -//////////////////////////////////////////////////////////////////// -INLINE const GraphicsWindow::Properties &GraphicsWindow:: -get_properties() const { - return _props; -} - -//////////////////////////////////////////////////////////////////// -// Function: GraphicsWindow::get_width -// Access: Published -// Description: -//////////////////////////////////////////////////////////////////// -INLINE int GraphicsWindow:: -get_width() const { - return (_props._xsize); -} - -//////////////////////////////////////////////////////////////////// -// Function: GraphicsWindow::get_height -// Access: Published -// Description: -//////////////////////////////////////////////////////////////////// -INLINE int GraphicsWindow:: -get_height() const { - return (_props._ysize); -} - -//////////////////////////////////////////////////////////////////// -// Function: GraphicsWindow::get_xorg -// Access: Published -// Description: -//////////////////////////////////////////////////////////////////// -INLINE int GraphicsWindow:: -get_xorg() const { - return (_props._xorg); -} - -//////////////////////////////////////////////////////////////////// -// Function: GraphicsWindow::get_yorg -// Access: Published -// Description: -//////////////////////////////////////////////////////////////////// -INLINE int GraphicsWindow:: -get_yorg() const { - return (_props._yorg); -} - INLINE bool GraphicsWindow:: is_fullscreen() const { - return (_props._fullscreen); + return _properties.get_fullscreen(); } //////////////////////////////////////////////////////////////////// @@ -209,13 +63,13 @@ is_fullscreen() const { // There is a one-to-one association between windows and // GSG's. // -// It is invalid to call this if the window has been -// closed; that is, if is_closed() returns true. In -// this case the GSG has been closed as well. +// This may return NULL if the graphics context has not +// yet been created for the window, e.g. before the +// first frame has rendered; or after the window has +// been closed. //////////////////////////////////////////////////////////////////// INLINE GraphicsStateGuardian *GraphicsWindow:: get_gsg() const { - nassertr(!is_closed(), NULL); return _gsg; } @@ -234,207 +88,6 @@ get_pipe() const { return _pipe; } -//////////////////////////////////////////////////////////////////// -// Function: GraphicsWindow::close_window -// Access: Published -// Description: Closes the window and frees all resources associated -// with it, including the GSG. The window may not be -// opened again. -//////////////////////////////////////////////////////////////////// -INLINE void GraphicsWindow:: -close_window() { - if (!is_closed()) { - do_close_window(); - release_gsg(); - } -} - -//////////////////////////////////////////////////////////////////// -// Function: GraphicsWindow::is_closed -// Access: Published -// Description: Returns true if close_window() has been called on -// this window, false otherwise. If the window has been -// closed, most of its interface is no longer valid. -//////////////////////////////////////////////////////////////////// -INLINE bool GraphicsWindow:: -is_closed() const { - - return (_gsg == (GraphicsStateGuardian *)NULL); -} - -//////////////////////////////////////////////////////////////////// -// Function: GraphicsWindow::set_frame_number -// Access: Published -// Description: Sets the current frame number of the window. This -// affects the frame numbers written for %f in a RIB or -// image filename template. The frame number is -// initially zero, and it increments at each call to -// end_frame(). -//////////////////////////////////////////////////////////////////// -INLINE void GraphicsWindow:: -set_frame_number(const int f) { - _frame_number = f; -} - -//////////////////////////////////////////////////////////////////// -// Function: GraphicsWindow::get_frame_number -// Access: Published -// Description: Returns the current frame number of the window. See -// set_frame_number(). -//////////////////////////////////////////////////////////////////// -INLINE int GraphicsWindow:: -get_frame_number() const { - return _frame_number; -} - -//////////////////////////////////////////////////////////////////// -// Function: GraphicsWindow::set_draw_callback -// Access: Public -// Description: -//////////////////////////////////////////////////////////////////// -INLINE void GraphicsWindow:: -set_draw_callback(Callback *c) { - _draw_callback = c; -} - -//////////////////////////////////////////////////////////////////// -// Function: GraphicsWindow::set_idle_callback -// Access: Public -// Description: -//////////////////////////////////////////////////////////////////// -INLINE void GraphicsWindow:: -set_idle_callback(Callback *c) { - _idle_callback = c; -} - -//////////////////////////////////////////////////////////////////// -// Function: GraphicsWindow::call_draw_callback -// Access: Public -// Description: -//////////////////////////////////////////////////////////////////// -INLINE void GraphicsWindow:: -call_draw_callback(bool force_redraw) { - if (_draw_callback) { - _draw_callback->draw(force_redraw); - } -} - -//////////////////////////////////////////////////////////////////// -// Function: GraphicsWindow::call_idle_callback -// Access: Public -// Description: -//////////////////////////////////////////////////////////////////// -INLINE void GraphicsWindow:: -call_idle_callback() { - if (_idle_callback) { - _idle_callback->idle(); - } -} - -//////////////////////////////////////////////////////////////////// -// Function: GraphicsWindow::get_num_input_devices -// Access: Published -// Description: Returns the number of separate input devices -// associated with the window. Typically, a window will -// have exactly one input device: the keyboard/mouse -// pair. However, some windows may have no input -// devices, and others may add additional devices, for -// instance for a joystick. -//////////////////////////////////////////////////////////////////// -INLINE int GraphicsWindow:: -get_num_input_devices() const { - return _input_devices.size(); -} - -//////////////////////////////////////////////////////////////////// -// Function: GraphicsWindow::get_input_device_name -// Access: Published -// Description: Returns the name of the nth input device. -//////////////////////////////////////////////////////////////////// -INLINE string GraphicsWindow:: -get_input_device_name(int device) const { - nassertr(device >= 0 && device < (int)_input_devices.size(), ""); - return _input_devices[device].get_name(); -} - -//////////////////////////////////////////////////////////////////// -// Function: GraphicsWindow::has_pointer -// Access: Published -// Description: Returns true if the nth input device has a -// screen-space pointer (for instance, a mouse), false -// otherwise. -//////////////////////////////////////////////////////////////////// -INLINE bool GraphicsWindow:: -has_pointer(int device) const { - nassertr(device >= 0 && device < (int)_input_devices.size(), false); - return _input_devices[device].has_pointer(); -} - -//////////////////////////////////////////////////////////////////// -// Function: GraphicsWindow::has_keyboard -// Access: Published -// Description: Returns true if the nth input device has a keyboard, -// false otherwise. -//////////////////////////////////////////////////////////////////// -INLINE bool GraphicsWindow:: -has_keyboard(int device) const { - nassertr(device >= 0 && device < (int)_input_devices.size(), false); - return _input_devices[device].has_keyboard(); -} - -//////////////////////////////////////////////////////////////////// -// Function: GraphicsWindow::get_mouse_data -// Access: Published -// Description: Returns the MouseData associated with the nth input -// device. -//////////////////////////////////////////////////////////////////// -INLINE const MouseData &GraphicsWindow:: -get_mouse_data(int device) const { - nassertr(device >= 0 && device < (int)_input_devices.size(), - *(new MouseData)); - return _input_devices[device].get_mouse_data(); -} - -//////////////////////////////////////////////////////////////////// -// Function: GraphicsWindow::has_button_event -// Access: Published -// Description: Returns true if the indicated device has a pending -// button event (a mouse button or keyboard button -// down/up), false otherwise. If this returns true, the -// particular event may be extracted via -// get_button_event(). -//////////////////////////////////////////////////////////////////// -INLINE bool GraphicsWindow:: -has_button_event(int device) const { - nassertr(device >= 0 && device < (int)_input_devices.size(), false); - return _input_devices[device].has_button_event(); -} - -//////////////////////////////////////////////////////////////////// -// Function: GraphicsWindow::get_button_event -// Access: Published -// Description: Assuming a previous call to has_button_event() -// returned true, this returns the pending button event. -//////////////////////////////////////////////////////////////////// -INLINE ButtonEvent GraphicsWindow:: -get_button_event(int device) { - nassertr(has_button_event(device), ButtonEvent()); - return _input_devices[device].get_button_event(); -} - -//////////////////////////////////////////////////////////////////// -// Function: GraphicsWindow::get_window_active -// Access: Public -// Description: Returns true if the window is currently active and -// ready to be rendered into, or false otherwise. This -// state is normally updated only by the GSG, or by the -// window itself. -//////////////////////////////////////////////////////////////////// -INLINE bool GraphicsWindow:: -get_window_active() const { - return _window_active; -} - //////////////////////////////////////////////////////////////////// // Function: GraphicsWindow::win_display_regions_changed // Access: Public @@ -448,56 +101,6 @@ win_display_regions_changed() { _display_regions_stale = true; } -//////////////////////////////////////////////////////////////////// -// Function: GraphicsWindow::set_sync -// Access: Public -// Description: Sets flag for whether the buffer swap is done -// implicitely at the end of each frame, or done -// explicitely for the purpose of synchronization. -//////////////////////////////////////////////////////////////////// -INLINE void GraphicsWindow:: -set_sync(const bool b) { - _is_synced = b; -} - -//////////////////////////////////////////////////////////////////// -// Function: GraphicsWindow::get_sync -// Access: Public -// Description: Returns whether buffer swap is done explicitely by -// call to swap() method. -//////////////////////////////////////////////////////////////////// -INLINE bool GraphicsWindow:: -get_sync() const { - return _is_synced; -} - -//////////////////////////////////////////////////////////////////// -// Function: GraphicsWindow::get_num_display_regions -// Access: Published -// Description: Returns the number of active DisplayRegions that have -// been created within the various layers and channels -// of the window. -//////////////////////////////////////////////////////////////////// -INLINE int GraphicsWindow:: -get_num_display_regions() const { - determine_display_regions(); - return _display_regions.size(); -} - -//////////////////////////////////////////////////////////////////// -// Function: GraphicsWindow::get_display_region -// Access: Published -// Description: Returns the nth active DisplayRegion of those that -// have been created within the various layers and -// channels of the window. -//////////////////////////////////////////////////////////////////// -INLINE DisplayRegion *GraphicsWindow:: -get_display_region(int n) const { - determine_display_regions(); - nassertr(n >= 0 && n < (int)_display_regions.size(), NULL); - return _display_regions[n]; -} - //////////////////////////////////////////////////////////////////// // Function: GraphicsWindow::determine_display_regions diff --git a/panda/src/display/graphicsWindow.cxx b/panda/src/display/graphicsWindow.cxx index 39234db110..eb5c7c1b55 100644 --- a/panda/src/display/graphicsWindow.cxx +++ b/panda/src/display/graphicsWindow.cxx @@ -19,188 +19,83 @@ #include "graphicsWindow.h" #include "graphicsPipe.h" #include "config_display.h" - -#include -#include +#include "mouseButton.h" +#include "keyboardButton.h" +#include "mutexHolder.h" +#include "hardwareChannel.h" +#include "throw_event.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"); +//////////////////////////////////////////////////////////////////// +// Function: GraphicsWindow::Constructor +// Access: Protected +// Description: Normally, the GraphicsWindow constructor is not +// called directly; these are created instead via the +// GraphicsEngine::make_window() function. +//////////////////////////////////////////////////////////////////// +GraphicsWindow:: +GraphicsWindow(GraphicsPipe *pipe) { +#ifdef DO_MEMORY_USAGE + MemoryUsage::update_type(this, this); #endif + _pipe = pipe; -//////////////////////////////////////////////////////////////////// -// 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; + // Some default properties for windows unless specified otherwise. + // Other properties (size, title, etc.) must be explicitly + // specified. + _properties.set_open(false); + _properties.set_undecorated(false); + _properties.set_fullscreen(false); + _properties.set_minimized(false); + _properties.set_cursor_hidden(false); + _properties.set_depth_bits(1); + _properties.set_color_bits(1); + _properties.set_framebuffer_mode(WindowProperties::FM_rgba | + WindowProperties::FM_double_buffer | + WindowProperties::FM_depth); + _display_regions_stale = false; + _window_event = "window-event"; // By default, windows are set up to clear color and depth. set_clear_color_active(true); set_clear_depth_active(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, - const GraphicsWindow::Properties &props) : - Configurable(), - ClearableRegion(props) -{ -#ifdef DO_MEMORY_USAGE - MemoryUsage::update_type(this, this); -#endif - _pipe = pipe; - _props = props; - - _draw_callback = NULL; - _idle_callback = NULL; - _frame_number = 0; - _is_synced = false; - _window_active = true; - _display_regions_stale = false; -} - //////////////////////////////////////////////////////////////////// // Function: GraphicsWindow::Copy Constructor -// Access: Public +// Access: Private // Description: //////////////////////////////////////////////////////////////////// GraphicsWindow:: -GraphicsWindow(const GraphicsWindow&) { - display_cat.error() - << "GraphicsWindows should not be copied" << endl; +GraphicsWindow(const GraphicsWindow &) { + nassertv(false); } //////////////////////////////////////////////////////////////////// // Function: GraphicsWindow::Copy Assignment Operator -// Access: Public +// Access: Private // Description: //////////////////////////////////////////////////////////////////// -GraphicsWindow& GraphicsWindow:: -operator=(const GraphicsWindow&) { - display_cat.error() - << "GraphicsWindows should not be assigned" << endl; - return *this; +void GraphicsWindow:: +operator = (const GraphicsWindow &) { + nassertv(false); } //////////////////////////////////////////////////////////////////// // Function: GraphicsWindow::Destructor -// Access: Public, Virtual +// Access: Published, 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(); + // The window should be closed by the time we destruct. + nassertv(!_properties.get_open()); + // And we shouldn't have a GraphicsPipe pointer anymore. + nassertv(_pipe == (GraphicsPipe *)NULL); // We don't have to destruct our child channels explicitly, since // they are all reference-counted and will go away when their @@ -210,11 +105,92 @@ GraphicsWindow:: 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_properties +// Access: Published +// Description: Returns the current properties of the window. +//////////////////////////////////////////////////////////////////// +WindowProperties GraphicsWindow:: +get_properties() const { + WindowProperties result; + { + MutexHolder holder(_lock); + result = _properties; + } + return result; +} + +//////////////////////////////////////////////////////////////////// +// Function: GraphicsWindow::get_requested_properties +// Access: Published +// Description: Returns the properties of the window that are +// currently requested. These properties will be +// applied to the window (if valid) at the next +// execution of process_events(). +//////////////////////////////////////////////////////////////////// +WindowProperties GraphicsWindow:: +get_requested_properties() const { + WindowProperties result; + { + MutexHolder holder(_lock); + result = _requested_properties; + } + return result; +} + +//////////////////////////////////////////////////////////////////// +// Function: GraphicsWindow::request_properties +// Access: Published +// Description: Requests a property change on the window. For +// example, use this method to request a window change +// size or minimize or something. +// +// The change is not made immediately; rather, the +// request is saved and will be applied the next time +// the window task is run (probably at the next frame). +//////////////////////////////////////////////////////////////////// +void GraphicsWindow:: +request_properties(const WindowProperties &requested_properties) { + MutexHolder holder(_lock); + _requested_properties.add_properties(requested_properties); +} + +//////////////////////////////////////////////////////////////////// +// Function: GraphicsWindow::set_window_event +// Access: Published +// Description: Changes the name of the event that is generated when +// this window is modified externally, e.g. to be +// resized or closed by the user. +// +// By default, all windows have the same window event +// unless they are explicitly changed. When the event +// is generated, it includes one parameter: the window +// itself. +//////////////////////////////////////////////////////////////////// +void GraphicsWindow:: +set_window_event(const string &window_event) { + MutexHolder holder(_lock); + _window_event = window_event; +} + +//////////////////////////////////////////////////////////////////// +// Function: GraphicsWindow::get_window_event +// Access: Published +// Description: Returns the name of the event that is generated when +// this window is modified externally, e.g. to be +// resized or closed by the user. See set_window_event(). +//////////////////////////////////////////////////////////////////// +string GraphicsWindow:: +get_window_event() const { + string result; + MutexHolder holder(_lock); + result = _window_event; + return result; +} + + //////////////////////////////////////////////////////////////////// // Function: GraphicsWindow::get_channel // Access: Public @@ -234,6 +210,7 @@ GraphicsWindow:: //////////////////////////////////////////////////////////////////// GraphicsChannel *GraphicsWindow:: get_channel(int index) { + MutexHolder holder(_lock); nassertr(index >= 0, NULL); if (index < (int)_channels.size()) { @@ -250,14 +227,16 @@ get_channel(int index) { 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; + GraphicsPipe *pipe = _pipe; + if (pipe != (GraphicsPipe *)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; + } } } } @@ -279,6 +258,7 @@ get_channel(int index) { //////////////////////////////////////////////////////////////////// void GraphicsWindow:: remove_channel(int index) { + MutexHolder holder(_lock); if (index >= 0 && index < (int)_channels.size()) { _channels[index].clear(); } @@ -297,7 +277,12 @@ remove_channel(int index) { //////////////////////////////////////////////////////////////////// int GraphicsWindow:: get_max_channel_index() const { - return _channels.size(); + int result; + { + MutexHolder holder(_lock); + result = _channels.size(); + } + return result; } //////////////////////////////////////////////////////////////////// @@ -312,10 +297,581 @@ get_max_channel_index() const { //////////////////////////////////////////////////////////////////// bool GraphicsWindow:: is_channel_defined(int index) const { - if (index < 0 || index >= (int)_channels.size()) { - return false; + bool result; + { + MutexHolder holder(_lock); + if (index < 0 || index >= (int)_channels.size()) { + result = false; + } else { + result = (_channels[index] != (GraphicsChannel *)NULL); + } + } + return result; +} + +//////////////////////////////////////////////////////////////////// +// Function: GraphicsWindow::get_num_display_regions +// Access: Published +// Description: Returns the number of active DisplayRegions that have +// been created within the various layers and channels +// of the window. +//////////////////////////////////////////////////////////////////// +int GraphicsWindow:: +get_num_display_regions() const { + determine_display_regions(); + int result; + { + MutexHolder holder(_lock); + result = _display_regions.size(); + } + return result; +} + +//////////////////////////////////////////////////////////////////// +// Function: GraphicsWindow::get_display_region +// Access: Published +// Description: Returns the nth active DisplayRegion of those that +// have been created within the various layers and +// channels of the window. This may return NULL if n is +// out of bounds; particularly likely if the number of +// display regions has changed since the last call to +// get_num_display_regions(). +//////////////////////////////////////////////////////////////////// +DisplayRegion *GraphicsWindow:: +get_display_region(int n) const { + determine_display_regions(); + DisplayRegion *result; + { + MutexHolder holder(_lock); + if (n >= 0 && n < (int)_display_regions.size()) { + result = _display_regions[n]; + } else { + result = NULL; + } + } + return result; +} + +//////////////////////////////////////////////////////////////////// +// Function: GraphicsWindow::get_num_input_devices +// Access: Published +// Description: Returns the number of separate input devices +// associated with the window. Typically, a window will +// have exactly one input device: the keyboard/mouse +// pair. However, some windows may have no input +// devices, and others may add additional devices, for +// instance for a joystick. +//////////////////////////////////////////////////////////////////// +int GraphicsWindow:: +get_num_input_devices() const { + int result; + { + MutexHolder holder(_input_lock); + result = _input_devices.size(); + } + return result; +} + +//////////////////////////////////////////////////////////////////// +// Function: GraphicsWindow::get_input_device_name +// Access: Published +// Description: Returns the name of the nth input device. +//////////////////////////////////////////////////////////////////// +string GraphicsWindow:: +get_input_device_name(int device) const { + string result; + { + MutexHolder holder(_input_lock); + nassertr(device >= 0 && device < (int)_input_devices.size(), ""); + result = _input_devices[device].get_name(); + } + return result; +} + +//////////////////////////////////////////////////////////////////// +// Function: GraphicsWindow::has_pointer +// Access: Published +// Description: Returns true if the nth input device has a +// screen-space pointer (for instance, a mouse), false +// otherwise. +//////////////////////////////////////////////////////////////////// +bool GraphicsWindow:: +has_pointer(int device) const { + bool result; + { + MutexHolder holder(_input_lock); + nassertr(device >= 0 && device < (int)_input_devices.size(), false); + result = _input_devices[device].has_pointer(); + } + return result; +} + +//////////////////////////////////////////////////////////////////// +// Function: GraphicsWindow::has_keyboard +// Access: Published +// Description: Returns true if the nth input device has a keyboard, +// false otherwise. +//////////////////////////////////////////////////////////////////// +bool GraphicsWindow:: +has_keyboard(int device) const { + bool result; + { + MutexHolder holder(_input_lock); + nassertr(device >= 0 && device < (int)_input_devices.size(), false); + result = _input_devices[device].has_keyboard(); + } + return result; +} + +//////////////////////////////////////////////////////////////////// +// Function: GraphicsWindow::get_mouse_data +// Access: Public +// Description: Returns the MouseData associated with the nth input +// device. +//////////////////////////////////////////////////////////////////// +MouseData GraphicsWindow:: +get_mouse_data(int device) const { + MouseData result; + { + MutexHolder holder(_input_lock); + nassertr(device >= 0 && device < (int)_input_devices.size(), MouseData()); + result = _input_devices[device].get_mouse_data(); + } + return result; +} + +//////////////////////////////////////////////////////////////////// +// Function: GraphicsWindow::has_button_event +// Access: Public +// Description: Returns true if the indicated device has a pending +// button event (a mouse button or keyboard button +// down/up), false otherwise. If this returns true, the +// particular event may be extracted via +// get_button_event(). +//////////////////////////////////////////////////////////////////// +bool GraphicsWindow:: +has_button_event(int device) const { + bool result; + { + MutexHolder holder(_input_lock); + nassertr(device >= 0 && device < (int)_input_devices.size(), false); + result = _input_devices[device].has_button_event(); + } + return result; +} + +//////////////////////////////////////////////////////////////////// +// Function: GraphicsWindow::get_button_event +// Access: Public +// Description: Assuming a previous call to has_button_event() +// returned true, this returns the pending button event. +//////////////////////////////////////////////////////////////////// +ButtonEvent GraphicsWindow:: +get_button_event(int device) { + ButtonEvent result; + { + MutexHolder holder(_input_lock); + nassertr(device >= 0 && device < (int)_input_devices.size(), ButtonEvent()); + nassertr(_input_devices[device].has_button_event(), ButtonEvent()); + result = _input_devices[device].get_button_event(); + } + return result; +} + +//////////////////////////////////////////////////////////////////// +// Function: GraphicsWindow::verify_window_sizes +// Access: Public, Virtual +// Description: Determines which of the indicated window sizes are +// supported by available hardware (e.g. in fullscreen +// mode). +// +// On entry, dimen is an array containing contiguous x,y +// pairs specifying possible display sizes; it is +// numsizes*2 words long. The function will zero out +// any invalid x,y size pairs. The return value is the +// number of valid sizes that were found. +// +// Note this doesn't guarantee a resize attempt will +// work; you still need to check the return value. +// +// (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.) +//////////////////////////////////////////////////////////////////// +int GraphicsWindow:: +verify_window_sizes(int numsizes, int *dimen) { + return numsizes; +} + +//////////////////////////////////////////////////////////////////// +// 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 provided in GraphicsLayer. +//////////////////////////////////////////////////////////////////// +PT(DisplayRegion) GraphicsWindow:: +make_scratch_display_region(int x_size, int y_size) const { +#ifndef NDEBUG + { + MutexHolder holder(_lock); + if (x_size > _properties.get_x_size() || + y_size > _properties.get_y_size()) { + display_cat.error() + << "make_scratch_display_region(): requested region of size " + << x_size << ", " << y_size << " is larger than window of size " + << _properties.get_x_size() << ", " << _properties.get_y_size() + << ".\n"; + x_size = min(x_size, _properties.get_x_size()); + y_size = min(y_size, _properties.get_y_size()); + } + } +#endif + + PT(DisplayRegion) region = new DisplayRegion(x_size, y_size); + region->copy_clear_settings(*this); + return region; +} + +//////////////////////////////////////////////////////////////////// +// Function: GraphicsWindow::begin_frame +// Access: Public, Virtual +// Description: This function will be called within the draw thread +// before beginning rendering for a given frame. It +// should do whatever setup is required, and return true +// if the frame should be rendered, or false if it +// should be skipped. +//////////////////////////////////////////////////////////////////// +bool GraphicsWindow:: +begin_frame() { + if (_gsg == (GraphicsStateGuardian *)NULL) { + MutexHolder holder(_lock); + // Oops, we don't have a GSG yet. + if (!_properties.get_open()) { + return false; + } + make_gsg(); + if (_gsg == (GraphicsStateGuardian *)NULL) { + // Still couldn't make the GSG for some reason. + return false; + } + } else { + // Okay, we already have a GSG, so activate it. + make_current(); + } + + return _gsg->begin_frame(); +} + +//////////////////////////////////////////////////////////////////// +// Function: GraphicsWindow::clear +// Access: Public +// Description: Clears the entire framebuffer before rendering, +// according to the settings of get_color_clear_active() +// and get_depth_clear_active() (inherited from +// ClearableRegion). +// +// This function is called only within the draw thread. +//////////////////////////////////////////////////////////////////// +void GraphicsWindow:: +clear() { + if (is_any_clear_active()) { + nassertv(_gsg != (GraphicsStateGuardian *)NULL); + + int x_size, y_size; + { + MutexHolder holder(_lock); + x_size = _properties.get_x_size(); + y_size = _properties.get_y_size(); + } + PT(DisplayRegion) win_dr = + make_scratch_display_region(x_size, y_size); + DisplayRegionStack old_dr = _gsg->push_display_region(win_dr); + _gsg->clear(this); + _gsg->pop_display_region(old_dr); + } +} + +//////////////////////////////////////////////////////////////////// +// Function: GraphicsWindow::end_frame +// Access: Public, Virtual +// Description: This function will be called within the draw thread +// after rendering is completed for a given frame. It +// should do whatever finalization is required. +//////////////////////////////////////////////////////////////////// +void GraphicsWindow:: +end_frame() { + nassertv(_gsg != (GraphicsStateGuardian *)NULL); + _gsg->end_frame(); +} + +//////////////////////////////////////////////////////////////////// +// Function: GraphicsWindow::make_gsg +// Access: Public, Virtual +// Description: Creates a new GSG for the window and stores it in the +// _gsg pointer. This should only be called from within +// the draw thread. +//////////////////////////////////////////////////////////////////// +void GraphicsWindow:: +make_gsg() { +} + +//////////////////////////////////////////////////////////////////// +// Function: GraphicsWindow::release_gsg +// Access: Public, Virtual +// Description: Releases the current GSG pointer, if it is currently +// held, and resets the GSG to NULL. This should only +// be called from within the draw thread. +//////////////////////////////////////////////////////////////////// +void GraphicsWindow:: +release_gsg() { + if (_gsg != (GraphicsStateGuardian *)NULL) { + _gsg->close_gsg(); + _gsg.clear(); + } +} + +//////////////////////////////////////////////////////////////////// +// Function: GraphicsWindow::make_current +// Access: Public, Virtual +// Description: This function will be called within the draw thread +// during begin_frame() to ensure the graphics context +// is ready for drawing. +//////////////////////////////////////////////////////////////////// +void GraphicsWindow:: +make_current() { +} + +//////////////////////////////////////////////////////////////////// +// Function: GraphicsWindow::begin_flip +// Access: Public, Virtual +// Description: This function will be called within the draw thread +// after end_frame() has been called on all windows, to +// initiate the exchange of the front and back buffers. +// +// This should instruct the window to prepare for the +// flip at the next video sync, but it should not wait. +// +// We have the two separate functions, begin_flip() and +// end_flip(), to make it easier to flip all of the +// windows at the same time. +//////////////////////////////////////////////////////////////////// +void GraphicsWindow:: +begin_flip() { +} + +//////////////////////////////////////////////////////////////////// +// Function: GraphicsWindow::end_flip +// Access: Public, Virtual +// Description: This function will be called within the draw thread +// after begin_flip() has been called on all windows, to +// finish the exchange of the front and back buffers. +// +// This should cause the window to wait for the flip, if +// necessary. +//////////////////////////////////////////////////////////////////// +void GraphicsWindow:: +end_flip() { +} + +//////////////////////////////////////////////////////////////////// +// Function: GraphicsWindow::process_events +// Access: Public, Virtual +// Description: Do whatever processing is necessary to ensure that +// the window responds to user events. Also, honor any +// requests recently made via request_properties(). +// +// This function is called only within the window +// thread. +//////////////////////////////////////////////////////////////////// +void GraphicsWindow:: +process_events() { + if (_requested_properties.is_any_specified()) { + // We don't bother to grab the mutex until after we have already + // checked whether any properties have been specified. This is + // technically sloppy, but it ought to be o.k. since it's just a + // bitmask after all. + WindowProperties properties; + { + MutexHolder holder(_lock); + properties = _requested_properties; + _requested_properties = WindowProperties(); + } + set_properties_now(properties); + if (properties.is_any_specified()) { + display_cat.info() + << "Unable to set window properties: " << properties << "\n"; + } + } +} + +//////////////////////////////////////////////////////////////////// +// Function: GraphicsWindow::set_properties_now +// Access: Public, Virtual +// Description: Applies the requested set of properties to the +// window, if possible, for instance to request a change +// in size or minimization status. +// +// The window properties are applied immediately, rather +// than waiting until the next frame. This implies that +// this method may *only* be called from within the +// window thread. +// +// The properties that have been applied are cleared +// from the structure by this function; so on return, +// whatever remains in the properties structure are +// those that were unchanged for some reason (probably +// because the underlying interface does not support +// changing that property on an open window). +//////////////////////////////////////////////////////////////////// +void GraphicsWindow:: +set_properties_now(WindowProperties &properties) { + if (properties.has_open() && + properties.get_open() != _properties.get_open()) { + // Open or close a new window. In this case we can get all of the + // properties at once. + _properties.add_properties(properties); + properties.clear(); + + if (_properties.get_open()) { + if (!open_window()) { + _properties.set_open(false); + } + + } else { + // We can't close the window if its GSG hasn't been released + // yet. + nassertv(_gsg == (GraphicsStateGuardian *)NULL); + close_window(); + } + return; + } + + if (!_properties.get_open()) { + // The window is not currently open; we can set properties at + // will. + _properties.add_properties(properties); + properties.clear(); + return; + } + + // The window is already open; we are limited to what we can change + // on the fly. + + if (properties.has_size() || properties.has_origin()) { + // Consider changing the window's size and/or position. + WindowProperties reshape_props; + if (properties.has_size()) { + reshape_props.set_size(properties.get_x_size(), properties.get_y_size()); + } else { + reshape_props.set_size(_properties.get_x_size(), _properties.get_y_size()); + } + if (properties.has_origin() && !is_fullscreen()) { + reshape_props.set_origin(properties.get_x_origin(), properties.get_y_origin()); + } else { + reshape_props.set_origin(_properties.get_x_origin(), _properties.get_y_origin()); + } + + if (reshape_props.get_x_size() != _properties.get_x_size() || + reshape_props.get_y_size() != _properties.get_y_size() || + reshape_props.get_x_origin() != _properties.get_x_origin() || + reshape_props.get_y_origin() != _properties.get_y_origin()) { + if (do_reshape_request(reshape_props.get_x_origin(), + reshape_props.get_y_origin(), + reshape_props.get_x_size(), + reshape_props.get_y_size())) { + system_changed_size(reshape_props.get_x_size(), + reshape_props.get_y_size()); + _properties.add_properties(reshape_props); + properties.clear_size(); + properties.clear_origin(); + } + } + } +} + +//////////////////////////////////////////////////////////////////// +// Function: GraphicsWindow::close_window +// Access: Protected, Virtual +// Description: Closes the window right now. Called from the window +// thread. +//////////////////////////////////////////////////////////////////// +void GraphicsWindow:: +close_window() { +} + +//////////////////////////////////////////////////////////////////// +// Function: GraphicsWindow::open_window +// Access: Protected, Virtual +// Description: Opens the window right now. Called from the window +// thread. Returns true if the window is successfully +// opened, or false if there was a problem. +//////////////////////////////////////////////////////////////////// +bool GraphicsWindow:: +open_window() { + return false; +} + +//////////////////////////////////////////////////////////////////// +// Function: GraphicsWindow::open_window +// Access: Protected, Virtual +// Description: Called from the window thread in response to a request +// from within the code (via request_properties()) to +// change the size and/or position of the window. +// Returns true if the window is successfully changed, +// or false if there was a problem. +//////////////////////////////////////////////////////////////////// +bool GraphicsWindow:: +do_reshape_request(int x_origin, int y_origin, int x_size, int y_size) { + return false; +} + +//////////////////////////////////////////////////////////////////// +// Function: GraphicsWindow::system_changed_properties +// Access: Protected +// Description: Should be called (from within the window thread) when +// process_events() detects an external change in some +// important window property; for instance, when the +// user resizes the window. +//////////////////////////////////////////////////////////////////// +void GraphicsWindow:: +system_changed_properties(const WindowProperties &properties) { + MutexHolder holder(_lock); + + if (properties.has_size()) { + system_changed_size(properties.get_x_size(), properties.get_y_size()); + } + + WindowProperties old_properties = _properties; + _properties.add_properties(properties); + if (_properties != old_properties) { + throw_event(_window_event, this); + } +} + +//////////////////////////////////////////////////////////////////// +// Function: GraphicsWindow::system_changed_size +// Access: Protected +// Description: An internal function to update all the channels with +// the new size of the window. This should always be +// called before changing the _size members of the +// _properties structure. +//////////////////////////////////////////////////////////////////// +void GraphicsWindow:: +system_changed_size(int x_size, int y_size) { + if (x_size != _properties.get_x_size() || + y_size != _properties.get_y_size()) { + Channels::iterator ci; + for (ci = _channels.begin(); ci != _channels.end(); ++ci) { + GraphicsChannel *chan = (*ci); + chan->window_resized(x_size, y_size); + } } - return (_channels[index] != (GraphicsChannel *)NULL); } //////////////////////////////////////////////////////////////////// @@ -324,6 +880,9 @@ is_channel_defined(int index) const { // Description: An internal function to add the indicated // newly-created channel to the list at the indicated // channel number. +// +// The caller must grab and hold _lock before making +// this call. //////////////////////////////////////////////////////////////////// void GraphicsWindow:: declare_channel(int index, GraphicsChannel *chan) { @@ -347,6 +906,8 @@ declare_channel(int index, GraphicsChannel *chan) { //////////////////////////////////////////////////////////////////// void GraphicsWindow:: do_determine_display_regions() { + MutexHolder holder(_lock); + _display_regions_stale = false; _display_regions.clear(); Channels::const_iterator ci; for (ci = _channels.begin(); ci != _channels.end(); ++ci) { @@ -369,338 +930,6 @@ do_determine_display_regions() { } } } - - _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 provided 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; - } - - PT(DisplayRegion) region = new DisplayRegion(xsize, ysize); - region->copy_clear_settings(*this); - return region; -} - -//////////////////////////////////////////////////////////////////// -// 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(bool bStartRendering) { - _gsg->begin_frame(); - - // app may not want to automatically call start_rendering() if - // it wants to switch the rendertarget buffer first - if(bStartRendering) - _gsg->start_rendering(); -} - -//////////////////////////////////////////////////////////////////// -// Function: GraphicsWindow::clear -// Access: Public -// Description: Clears the entire framebuffer before rendering, -// according to the settings of get_color_clear_active() -// and get_depth_clear_active() (inherited from -// ClearableRegion). -//////////////////////////////////////////////////////////////////// -void GraphicsWindow:: -clear() { - if (is_any_clear_active()) { - nassertv(_gsg != (GraphicsStateGuardian *)NULL); - - PT(DisplayRegion) win_dr = - make_scratch_display_region(get_width(), get_height()); - DisplayRegionStack old_dr = _gsg->push_display_region(win_dr); - _gsg->clear(this); - _gsg->pop_display_region(old_dr); - } -} - -//////////////////////////////////////////////////////////////////// -// 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(void) { - // finish_rendering not called here since gsg's own end_frame - // will usually want to finish_rendering() itself, - // then swap double buffers, then call GraphicsStateGuardian::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; } void GraphicsWindow:: diff --git a/panda/src/display/graphicsWindow.h b/panda/src/display/graphicsWindow.h index aab6adfd3b..90b750b9b0 100644 --- a/panda/src/display/graphicsWindow.h +++ b/panda/src/display/graphicsWindow.h @@ -21,244 +21,154 @@ #include "pandabase.h" #include "graphicsWindowInputDevice.h" +#include "windowProperties.h" #include "graphicsChannel.h" +#include "graphicsPipe.h" #include "displayRegion.h" #include "graphicsStateGuardian.h" #include "clearableRegion.h" -#include "typedef.h" -#include "configurable.h" -#include "referenceCount.h" +#include "typedReferenceCount.h" #include "mouseData.h" #include "modifierButtons.h" #include "buttonEvent.h" #include "iterator_types.h" -#include "factory.h" -#include "pStatCollector.h" +#include "notify.h" +#include "mutex.h" #include "pvector.h" #include "pdeque.h" -//////////////////////////////////////////////////////////////////// -// Defines -//////////////////////////////////////////////////////////////////// -enum WindowModeType -{ - W_RGBA = 0, - W_RGB = 0, - W_INDEX = 1, - W_SINGLE = 0, - W_DOUBLE = 2, - W_ACCUM = 4, - W_ALPHA = 8, - W_DEPTH = 16, - W_STENCIL = 32, - W_MULTISAMPLE = 128, - W_STEREO = 256, - W_LUMINANCE = 512 -}; - class GraphicsPipe; class GraphicsWindow; class CullHandler; //////////////////////////////////////////////////////////////////// // Class : GraphicsWindow -// Description : +// Description : An output medium for receiving the results of +// rendering. Typically this is a window on the +// computer desktop, but it may also be the entire +// desktop or console screen (i.e. a fullscreen window), +// or a window on another machine, or even a disk file. +// +// The GraphicsWindow class handles all of the details +// about creating a window and its framebuffer, and +// managing the properties associated with the windowing +// system, such as position and size and keyboard/mouse +// input. The actual rendering, and anything associated +// with the graphics context itself, is managed by the +// window's GraphicsStateGuardian. //////////////////////////////////////////////////////////////////// -class EXPCL_PANDA GraphicsWindow : public Configurable, public ReferenceCount, public ClearableRegion { +class EXPCL_PANDA GraphicsWindow : public TypedReferenceCount, public ClearableRegion { +protected: + GraphicsWindow(GraphicsPipe *pipe); + +private: + GraphicsWindow(const GraphicsWindow ©); + void operator = (const GraphicsWindow ©); + PUBLISHED: - class EXPCL_PANDA Properties : public ClearableRegion { - PUBLISHED: - Properties(); - INLINE Properties(const Properties ©); - INLINE void operator = (const Properties ©); - INLINE ~Properties(); - - // all these methods essentially do nothing since they do not get passed down to the gsg - // and maybe should be removed or commented out until they do, since - // they modify parameters that usually require re-creation of the window - // except for set_size(), which is superseded by resize(), which actually works. - - INLINE void set_origin(int xorg, int yorg); - INLINE void set_size(int xsize, int ysize); - INLINE void set_title(const string &title); - INLINE void set_border(bool border); - INLINE void set_mask(uint mask); - INLINE void set_bit_depth(int want_depth_bits, int want_color_bits); - - public: - int _xorg; - int _yorg; - int _xsize; - int _ysize; - string _title; - bool _border; - bool _fullscreen; - bool _bCursorIsVisible; - uint _mask; - int _want_depth_bits; - int _want_color_bits; - }; - -public: - class EXPCL_PANDA Callback { - public: - virtual void draw(bool); - virtual void idle(); - }; - typedef void (*vfn)(); - typedef void (*vfnii)(int, int); - -public: - - GraphicsWindow(GraphicsPipe *pipe, const Properties &props = Properties()); virtual ~GraphicsWindow(); - INLINE const Properties& get_properties() const; - - virtual void get_framebuffer_format(PixelBuffer::Type &fb_type, PixelBuffer::Format &fb_format); - -PUBLISHED: - INLINE int get_width() const; - INLINE int get_height() const; - INLINE int get_xorg() const; - INLINE int get_yorg() const; + WindowProperties get_properties() const; + WindowProperties get_requested_properties() const; + void request_properties(const WindowProperties &requested_properties); + INLINE bool is_closed() const; + INLINE bool is_active() const; INLINE bool is_fullscreen() const; - // # of z bits/pixel. purpose is to adjust camera near plane if have fewer z bits - virtual int get_depth_bitwidth(void); + void set_window_event(const string &window_event); + string get_window_event() const; INLINE GraphicsStateGuardian *get_gsg() const; INLINE GraphicsPipe *get_pipe() const; - INLINE void close_window(); - INLINE bool is_closed() const; - - INLINE void set_frame_number(const int); - INLINE int get_frame_number() const; - - INLINE void set_sync(const bool); - INLINE bool get_sync() const; - - // since this requires gsg modification, dont worry about implementing it yet - // since init control is good enough - // virtual void set_cursor_visible(bool bIsVisible); // should be overridden by gsg to implement - - // resize the window to the given size - virtual bool resize(unsigned int xsize,unsigned int ysize); - - virtual void swap(); - -public: - virtual void resized(const unsigned int, const unsigned int); - - // see if window sizes are supported (i.e. in fullscrn mode) - // - // 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. - virtual unsigned int verify_window_sizes(unsigned int numsizes,unsigned int *dimen); - - INLINE virtual void set_draw_callback(Callback *c); - INLINE virtual void set_idle_callback(Callback *c); - - INLINE void call_draw_callback(bool force_redraw); - INLINE void call_idle_callback(); - - PT(DisplayRegion) make_scratch_display_region(int xsize, - int ysize) const; - - virtual TypeHandle get_gsg_type() const=0; - -public: - // context setting - virtual void make_current(); - virtual void unmake_current(); - -PUBLISHED: - // Mouse and keyboard routines - INLINE int get_num_input_devices() const; - INLINE string get_input_device_name(int device) const; - INLINE bool has_pointer(int device) const; - INLINE bool has_keyboard(int device) const; - -public: - INLINE const MouseData &get_mouse_data(int device) const; - INLINE bool has_button_event(int device) const; - INLINE ButtonEvent get_button_event(int device); - -PUBLISHED: - // GUI glue methods - virtual void flag_redisplay(); - virtual void register_draw_function(GraphicsWindow::vfn); - virtual void register_idle_function(GraphicsWindow::vfn); - -public: - virtual void begin_frame(bool bStartRendering = true); - void clear(); - virtual void end_frame(); - - virtual void process_events(); - - INLINE bool get_window_active() const; - virtual void deactivate_window(); - virtual void reactivate_window(); - - INLINE void win_display_regions_changed(); - - // Statistics - static PStatCollector _app_pcollector; - static PStatCollector _show_code_pcollector; - static PStatCollector _swap_pcollector; // dxgsg needs access so this is public - static PStatCollector _clear_pcollector; - static PStatCollector _show_fps_pcollector; - static PStatCollector _make_current_pcollector; - -protected: - void make_gsg(); - void release_gsg(); - virtual void do_close_window(); - - typedef vector_GraphicsWindowInputDevice InputDevices; - InputDevices _input_devices; - - PT(GraphicsStateGuardian) _gsg; - Properties _props; - - GraphicsPipe *_pipe; - vfn _draw_function; - vfn _idle_function; - vfnii _resize_function; - int _frame_number; - - bool _is_synced; - bool _window_active; - -protected: - - Callback *_draw_callback; - Callback *_idle_callback; - -PUBLISHED: - virtual GraphicsChannel *get_channel(int index); + GraphicsChannel *get_channel(int index); void remove_channel(int index); int get_max_channel_index() const; bool is_channel_defined(int index) const; - INLINE int get_num_display_regions() const; - INLINE DisplayRegion *get_display_region(int n) const; + int get_num_display_regions() const; + DisplayRegion *get_display_region(int n) const; + + // Mouse and keyboard routines + int get_num_input_devices() const; + string get_input_device_name(int device) const; + bool has_pointer(int device) const; + bool has_keyboard(int device) const; + +public: + // No need to publish these. + MouseData get_mouse_data(int device) const; + bool has_button_event(int device) const; + ButtonEvent get_button_event(int device); + + virtual void get_framebuffer_format(PixelBuffer::Type &fb_type, PixelBuffer::Format &fb_format); + +public: + virtual int verify_window_sizes(int numsizes, int *dimen); + PT(DisplayRegion) make_scratch_display_region(int x_size, int y_size) const; + + INLINE void win_display_regions_changed(); + +public: + // It is an error to call any of the following methods from any + // thread other than the draw thread. These methods are normally + // called by the GraphicsEngine. + virtual bool begin_frame(); + void clear(); + virtual void end_frame(); + + virtual void make_gsg(); + virtual void release_gsg(); + + // This method is called in the draw thread prior to issuing any + // drawing commands for the window. + virtual void make_current(); + + // These methods will be called within the app (main) thread. + virtual void begin_flip(); + virtual void end_flip(); + + // It is an error to call any of the following methods from any + // thread other than the window thread. These methods are normally + // called by the GraphicsEngine. + virtual void process_events(); + virtual void set_properties_now(WindowProperties &properties); protected: + virtual void close_window(); + virtual bool open_window(); + virtual bool do_reshape_request(int x_origin, int y_origin, + int x_size, int y_size); + void declare_channel(int index, GraphicsChannel *chan); + // It is an error to call any of the following methods from any + // thread other than the window thread. + void system_changed_properties(const WindowProperties &properties); + void system_changed_size(int x_size, int y_size); + +protected: + typedef vector_GraphicsWindowInputDevice InputDevices; + InputDevices _input_devices; + Mutex _input_lock; + + PT(GraphicsStateGuardian) _gsg; + GraphicsPipe *_pipe; + private: INLINE void determine_display_regions() const; void do_determine_display_regions(); +protected: + WindowProperties _properties; + +private: + Mutex _lock; + // protects _channels, _display_regions, and _requested_properties. + typedef pvector< PT(GraphicsChannel) > Channels; Channels _channels; @@ -266,67 +176,17 @@ private: DisplayRegions _display_regions; bool _display_regions_stale; -public: - - // factory stuff - typedef Factory WindowFactory; - typedef FactoryParam WindowParam; - - // make a factory parameter type for the window properties - class EXPCL_PANDA WindowProps : public FactoryParam { - public: - INLINE WindowProps(void) : WindowParam() {} - INLINE WindowProps(const Properties& p) : WindowParam(), _p(p) {} - virtual ~WindowProps(void); - INLINE Properties get_properties(void) { return _p; } - public: - static TypeHandle get_class_type(void); - static void init_type(void); - virtual TypeHandle get_type(void) const; - virtual TypeHandle force_init_type(void); - private: - Properties _p; - static TypeHandle _type_handle; - }; - // make a factory parameter type for the GraphicsPipe* - class EXPCL_PANDA WindowPipe : public FactoryParam { - public: - INLINE WindowPipe(GraphicsPipe* p) : WindowParam(), _p(p) {} - virtual ~WindowPipe(void); - INLINE GraphicsPipe* get_pipe(void) { return _p; } - public: - static TypeHandle get_class_type(void); - static void init_type(void); - virtual TypeHandle get_type(void) const; - virtual TypeHandle force_init_type(void); - private: - GraphicsPipe* _p; - static TypeHandle _type_handle; - - INLINE WindowPipe(void) : WindowParam() {} - }; - - static WindowFactory &get_factory(); - -private: - - static void read_priorities(void); - - GraphicsWindow(const GraphicsWindow&); - GraphicsWindow &operator=(const GraphicsWindow&); - - static WindowFactory *_factory; - + WindowProperties _requested_properties; + string _window_event; + public: static TypeHandle get_class_type() { return _type_handle; } static void init_type() { - Configurable::init_type(); - ReferenceCount::init_type(); + TypedReferenceCount::init_type(); register_type(_type_handle, "GraphicsWindow", - Configurable::get_class_type(), - ReferenceCount::get_class_type()); + TypedReferenceCount::get_class_type()); } virtual TypeHandle get_type() const { return get_class_type(); @@ -337,6 +197,7 @@ private: static TypeHandle _type_handle; friend class GraphicsPipe; + friend class GraphicsEngine; }; #include "graphicsWindow.I" diff --git a/panda/src/display/graphicsWindowInputDevice.cxx b/panda/src/display/graphicsWindowInputDevice.cxx index ceb8f09251..53807e68e9 100644 --- a/panda/src/display/graphicsWindowInputDevice.cxx +++ b/panda/src/display/graphicsWindowInputDevice.cxx @@ -18,15 +18,15 @@ #include "graphicsWindowInputDevice.h" -#include -#include +#include "mouseButton.h" +#include "keyboardButton.h" #define EXPCL EXPCL_PANDA #define EXPTP EXPTP_PANDA #define TYPE GraphicsWindowInputDevice #define NAME vector_GraphicsWindowInputDevice -#include +#include "vector_src.cxx" // Tell GCC that we'll take care of the instantiation explicitly here. #ifdef __GNUC__ diff --git a/panda/src/display/graphicsWindowInputDevice.h b/panda/src/display/graphicsWindowInputDevice.h index 7995b181c2..6c0c2540ac 100644 --- a/panda/src/display/graphicsWindowInputDevice.h +++ b/panda/src/display/graphicsWindowInputDevice.h @@ -19,10 +19,10 @@ #ifndef GRAPHICSWINDOWINPUTDEVICE_H #define GRAPHICSWINDOWINPUTDEVICE_H -#include +#include "pandabase.h" -#include -#include +#include "buttonEvent.h" +#include "mouseData.h" #include "pdeque.h" #include "pvector.h" diff --git a/panda/src/display/interactiveGraphicsPipe.cxx b/panda/src/display/interactiveGraphicsPipe.cxx deleted file mode 100644 index 541aff980d..0000000000 --- a/panda/src/display/interactiveGraphicsPipe.cxx +++ /dev/null @@ -1,73 +0,0 @@ -// Filename: interactiveGraphicsPipe.cxx -// Created by: cary (10Mar99) -// -//////////////////////////////////////////////////////////////////// -// -// 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 "interactiveGraphicsPipe.h" -#include "config_display.h" - -//////////////////////////////////////////////////////////////////// -// Static variables -//////////////////////////////////////////////////////////////////// -TypeHandle InteractiveGraphicsPipe::_type_handle; - -InteractiveGraphicsPipe:: -InteractiveGraphicsPipe(const PipeSpecifier& spec) : - GraphicsPipe(spec) -{ -} - - -InteractiveGraphicsPipe:: -~InteractiveGraphicsPipe() { -} - -TypeHandle InteractiveGraphicsPipe:: -get_class_type(void) { - return _type_handle; -} - -void InteractiveGraphicsPipe:: -init_type(void) { - GraphicsPipe::init_type(); - register_type(_type_handle, "InteractiveGraphicsPipe", - GraphicsPipe::get_class_type()); -} - -TypeHandle InteractiveGraphicsPipe:: -get_type(void) const { - return get_class_type(); -} - -InteractiveGraphicsPipe:: -InteractiveGraphicsPipe(void) { - display_cat.error() - << "InteractiveGraphicsPipe should not be created with default constructor" << endl; -} - -InteractiveGraphicsPipe:: -InteractiveGraphicsPipe(const InteractiveGraphicsPipe&) { - display_cat.error() - << "InteractiveGraphicsPipes should not be copied" << endl; -} - -InteractiveGraphicsPipe &InteractiveGraphicsPipe:: -operator=(const InteractiveGraphicsPipe&) { - display_cat.error() - << "InteractiveGraphicsPipes should not be assigned" << endl; - return *this; -} diff --git a/panda/src/display/interactiveGraphicsPipe.h b/panda/src/display/interactiveGraphicsPipe.h deleted file mode 100644 index 49c6f51571..0000000000 --- a/panda/src/display/interactiveGraphicsPipe.h +++ /dev/null @@ -1,51 +0,0 @@ -// Filename: interactiveGraphicsPipe.h -// Created by: cary (10Mar99) -// -//////////////////////////////////////////////////////////////////// -// -// 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 __INTERACTIVEGRAPHICSPIPE_H__ -#define __INTERACTIVEGRAPHICSPIPE_H__ - -#include - -#include "graphicsPipe.h" - -class EXPCL_PANDA InteractiveGraphicsPipe : public GraphicsPipe { -PUBLISHED: - InteractiveGraphicsPipe( const PipeSpecifier& ); - virtual ~InteractiveGraphicsPipe(void); - -public: - - static TypeHandle get_class_type(void); - static void init_type(void); - virtual TypeHandle get_type(void) const; - virtual TypeHandle force_init_type() {init_type(); return get_class_type();} - -private: - - static TypeHandle _type_handle; - -protected: - - InteractiveGraphicsPipe(void); - InteractiveGraphicsPipe(const InteractiveGraphicsPipe&); - InteractiveGraphicsPipe& operator=(const InteractiveGraphicsPipe&); -}; - -#include "interactiveGraphicsPipe.I" - -#endif /* __INTERACTIVEGRAPHICSPIPE_H__ */ diff --git a/panda/src/display/noninteractiveGraphicsPipe.cxx b/panda/src/display/noninteractiveGraphicsPipe.cxx deleted file mode 100644 index 885f90e974..0000000000 --- a/panda/src/display/noninteractiveGraphicsPipe.cxx +++ /dev/null @@ -1,61 +0,0 @@ -// Filename: noninteractiveGraphicsPipe.cxx -// Created by: cary (10Mar99) -// -//////////////////////////////////////////////////////////////////// -// -// 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 "noninteractiveGraphicsPipe.h" -#include "config_display.h" - -//////////////////////////////////////////////////////////////////// -// Static variables -//////////////////////////////////////////////////////////////////// -TypeHandle NoninteractiveGraphicsPipe::_type_handle; - -NoninteractiveGraphicsPipe::NoninteractiveGraphicsPipe(const PipeSpecifier& spec) - : GraphicsPipe(spec) {} - -NoninteractiveGraphicsPipe::~NoninteractiveGraphicsPipe(void) {} - -NoninteractiveGraphicsPipe::NoninteractiveGraphicsPipe(void) { - display_cat.error() - << "NoninteractiveGraphicsPipe should not be created with default constructor" << endl; -} - -NoninteractiveGraphicsPipe::NoninteractiveGraphicsPipe(const NoninteractiveGraphicsPipe&) { - display_cat.error() - << "NoninteractiveGraphicsPipes should not be copied" << endl; -} - -NoninteractiveGraphicsPipe& NoninteractiveGraphicsPipe::operator=(const NoninteractiveGraphicsPipe&) { - display_cat.error() - << "NoninteractiveGraphicsPipes should not be assigned" << endl; - return *this; -} - -TypeHandle NoninteractiveGraphicsPipe::get_class_type(void) { - return _type_handle; -} - -void NoninteractiveGraphicsPipe::init_type(void) { - GraphicsPipe::init_type(); - register_type(_type_handle, "NoninteractiveGraphicsPipe", - GraphicsPipe::get_class_type()); -} - -TypeHandle NoninteractiveGraphicsPipe::get_type(void) const { - return get_class_type(); -} diff --git a/panda/src/display/noninteractiveGraphicsPipe.h b/panda/src/display/noninteractiveGraphicsPipe.h deleted file mode 100644 index eeeb2b2398..0000000000 --- a/panda/src/display/noninteractiveGraphicsPipe.h +++ /dev/null @@ -1,52 +0,0 @@ -// Filename: noninteractiveGraphicsPipe.h -// Created by: cary (10Mar99) -// -//////////////////////////////////////////////////////////////////// -// -// 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 __NONINTERACTIVEGRAPHICSPIPE_H__ -#define __NONINTERACTIVEGRAPHICSPIPE_H__ - -#include - -#include "graphicsPipe.h" - -class EXPCL_PANDA NoninteractiveGraphicsPipe : public GraphicsPipe { -public: - - NoninteractiveGraphicsPipe( const PipeSpecifier& ); - virtual ~NoninteractiveGraphicsPipe(void) = 0; - -public: - - static TypeHandle get_class_type(void); - static void init_type(void); - virtual TypeHandle get_type(void) const; - virtual TypeHandle force_init_type() {init_type(); return get_class_type();} - -private: - - static TypeHandle _type_handle; - -protected: - - NoninteractiveGraphicsPipe(void); - NoninteractiveGraphicsPipe(const NoninteractiveGraphicsPipe&); - NoninteractiveGraphicsPipe& operator=(const NoninteractiveGraphicsPipe&); -}; - -#include "noninteractiveGraphicsPipe.I" - -#endif /* __NONINTERACTIVEGRAPHICSPIPE_H__ */ diff --git a/panda/src/display/pipeSpec.I b/panda/src/display/pipeSpec.I deleted file mode 100644 index 3dd2841e6f..0000000000 --- a/panda/src/display/pipeSpec.I +++ /dev/null @@ -1,78 +0,0 @@ -// Filename: pipeSpec.I -// Created by: frang (07Mar99) -// -//////////////////////////////////////////////////////////////////// -// -// 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 . -// -//////////////////////////////////////////////////////////////////// - -INLINE void PipeSpecifier::set_name(const std::string& name) { - _name = name; -} - -INLINE std::string PipeSpecifier::get_name(void) const { - return _name; -} - -INLINE void PipeSpecifier::unset_machine(void) { - if (!_is_file) { - _is_file = true; - _machine = ""; - _is_remote = false; - } -} - -INLINE void PipeSpecifier::unset_file(void) { - if (_is_file) { - _is_file = false; - _filename = ""; - } -} - -INLINE void PipeSpecifier::set_machine_name(const std::string& name) { - _machine = name; - if (_machine.empty()) - _is_remote = false; - else - _is_remote = true; - unset_file(); -} - -INLINE std::string PipeSpecifier::get_machine_name(void) const { - return _machine; -} - -INLINE void PipeSpecifier::set_file_name(const std::string& name) { - _filename = name; - unset_machine(); -} - -INLINE std::string PipeSpecifier::get_file_name(void) const { - return _filename; -} - -INLINE void PipeSpecifier::set_pipe_number(const int p) { - _pipe_number = p; -} - -INLINE int PipeSpecifier::get_pipe_number(void) const { - return _pipe_number; -} - -INLINE bool PipeSpecifier::is_file(void) const { - return _is_file; -} - -INLINE bool PipeSpecifier::is_remote(void) const { - return _is_remote; -} diff --git a/panda/src/display/pipeSpec.cxx b/panda/src/display/pipeSpec.cxx deleted file mode 100644 index 9651cd5f9b..0000000000 --- a/panda/src/display/pipeSpec.cxx +++ /dev/null @@ -1,55 +0,0 @@ -// Filename: pipeSpec.cxx -// Created by: frang (07Mar99) -// -//////////////////////////////////////////////////////////////////// -// -// 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 "config_display.h" - -#include "pipeSpec.h" - -PipeSpecifier::PipeSpecifier(void) - : _machine(pipe_spec_machine), - _filename(pipe_spec_filename), - _pipe_number(pipe_spec_pipe_number), - _is_file(pipe_spec_is_file), - _is_remote(pipe_spec_is_remote) {} - -PipeSpecifier::PipeSpecifier(const PipeSpecifier& c) - : _name(c._name), _machine(c._machine), _filename(c._filename), - _pipe_number(c._pipe_number), _is_file(c._is_file), - _is_remote(c._is_remote) {} - -PipeSpecifier::~PipeSpecifier(void) {} - -std::string PipeSpecifier::get_X_specifier(void) const { - std::string ret; - - if (!_is_file) { - if (_machine.empty()) { - if (getenv("DISPLAY")) { - ret = getenv("DISPLAY"); - } - } - - if (ret.empty()) { - ostringstream ss; - ss << _machine << ":" << ((_pipe_number<0)?0:_pipe_number) << ".0"; - ret = ss.str(); - } - } - return ret; -} diff --git a/panda/src/display/pipeSpec.h b/panda/src/display/pipeSpec.h deleted file mode 100644 index 2ad07f87b0..0000000000 --- a/panda/src/display/pipeSpec.h +++ /dev/null @@ -1,60 +0,0 @@ -// Filename: pipeSpec.h -// Created by: frang (07Mar99) -// -//////////////////////////////////////////////////////////////////// -// -// 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 __PIPESPEC_H__ -#define __PIPESPEC_H__ - -#include - -#include - -class EXPCL_PANDA PipeSpecifier { -PUBLISHED: - PipeSpecifier(void); - PipeSpecifier(const PipeSpecifier&); - ~PipeSpecifier(void); - - INLINE void set_name(const std::string&); - INLINE std::string get_name(void) const; - INLINE void set_machine_name(const std::string&); - INLINE std::string get_machine_name(void) const; - INLINE void set_file_name(const std::string&); - INLINE std::string get_file_name(void) const; - INLINE void set_pipe_number(const int); - INLINE int get_pipe_number(void) const; - - INLINE bool is_file(void) const; - INLINE bool is_remote(void) const; - - std::string get_X_specifier(void) const; - -private: - std::string _name; - std::string _machine; - std::string _filename; - int _pipe_number; - bool _is_file; - bool _is_remote; - - INLINE void unset_machine(void); - INLINE void unset_file(void); -}; - -#include "pipeSpec.I" - -#endif /* __PIPESPEC_H__ */ diff --git a/panda/src/display/renderBuffer.h b/panda/src/display/renderBuffer.h index 6e81b9bac4..915c93de93 100644 --- a/panda/src/display/renderBuffer.h +++ b/panda/src/display/renderBuffer.h @@ -19,6 +19,7 @@ #ifndef RENDERBUFFER_H #define RENDERBUFFER_H +#include "pandabase.h" class GraphicsStateGuardian; diff --git a/panda/src/display/windowProperties.I b/panda/src/display/windowProperties.I new file mode 100644 index 0000000000..d3f8eaf915 --- /dev/null +++ b/panda/src/display/windowProperties.I @@ -0,0 +1,664 @@ +// Filename: windowProperties.I +// Created by: drose (13Aug02) +// +//////////////////////////////////////////////////////////////////// +// +// 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: WindowProperties::Copy Constructor +// Access: Published +// Description: +//////////////////////////////////////////////////////////////////// +INLINE WindowProperties:: +WindowProperties(const WindowProperties ©) { + (*this) = copy; +} + +//////////////////////////////////////////////////////////////////// +// Function: WindowProperties::Destructor +// Access: Published +// Description: +//////////////////////////////////////////////////////////////////// +INLINE WindowProperties:: +~WindowProperties() { +} + +//////////////////////////////////////////////////////////////////// +// Function: WindowProperties::operator != +// Access: Published +// Description: +//////////////////////////////////////////////////////////////////// +INLINE bool WindowProperties:: +operator != (const WindowProperties &other) const { + return !operator == (other); +} + +//////////////////////////////////////////////////////////////////// +// Function: WindowProperties::is_any_specified +// Access: Published +// Description: Returns true if any properties have been specified, +// false otherwise. +//////////////////////////////////////////////////////////////////// +INLINE bool WindowProperties:: +is_any_specified() const { + return (_specified != 0); +} + +//////////////////////////////////////////////////////////////////// +// Function: WindowProperties::set_origin +// Access: Published +// Description: Specifies the origin on the screen (in pixels, +// relative to the top-left corner) at which the window +// should appear. This is the origin of the top-left +// corner of the useful part of the window, not +// including decorations. +//////////////////////////////////////////////////////////////////// +INLINE void WindowProperties:: +set_origin(int x_origin, int y_origin) { + _x_origin = x_origin; + _y_origin = y_origin; + _specified |= S_origin; +} + +//////////////////////////////////////////////////////////////////// +// Function: WindowProperties::get_x_origin +// Access: Published +// Description: Returns the x coordinate of the window's top-left +// corner, not including decorations. +//////////////////////////////////////////////////////////////////// +INLINE int WindowProperties:: +get_x_origin() const { + nassertr(has_origin(), 0); + return _x_origin; +} + +//////////////////////////////////////////////////////////////////// +// Function: WindowProperties::get_y_origin +// Access: Published +// Description: Returns the y coordinate of the window's top-left +// corner, not including decorations. +//////////////////////////////////////////////////////////////////// +INLINE int WindowProperties:: +get_y_origin() const { + nassertr(has_origin(), 0); + return _y_origin; +} + +//////////////////////////////////////////////////////////////////// +// Function: WindowProperties::has_origin +// Access: Published +// Description: Returns true if the window origin has been specified, +// false otherwise. +//////////////////////////////////////////////////////////////////// +INLINE bool WindowProperties:: +has_origin() const { + return ((_specified & S_origin) != 0); +} + +//////////////////////////////////////////////////////////////////// +// Function: WindowProperties::clear_origin +// Access: Published +// Description: Removes the origin specification from the properties. +//////////////////////////////////////////////////////////////////// +INLINE void WindowProperties:: +clear_origin() { + _specified &= ~S_origin; + _x_origin = 0; + _y_origin = 0; +} + +//////////////////////////////////////////////////////////////////// +// Function: WindowProperties::set_size +// Access: Published +// Description: Specifies the requested size of the window, in +// pixels. This is the size of the useful part of the +// window, not including decorations. +//////////////////////////////////////////////////////////////////// +INLINE void WindowProperties:: +set_size(int x_size, int y_size) { + _x_size = x_size; + _y_size = y_size; + _specified |= S_size; +} + +//////////////////////////////////////////////////////////////////// +// Function: WindowProperties::get_x_size +// Access: Published +// Description: Returns size in pixels in the x dimension of the +// useful part of the window, not including decorations. +// That is, this is the window's width. +//////////////////////////////////////////////////////////////////// +INLINE int WindowProperties:: +get_x_size() const { + nassertr(has_size(), 0); + return _x_size; +} + +//////////////////////////////////////////////////////////////////// +// Function: WindowProperties::get_y_size +// Access: Published +// Description: Returns size in pixels in the y dimension of the +// useful part of the window, not including decorations. +// That is, this is the window's height. +//////////////////////////////////////////////////////////////////// +INLINE int WindowProperties:: +get_y_size() const { + nassertr(has_size(), 0); + return _y_size; +} + +//////////////////////////////////////////////////////////////////// +// Function: WindowProperties::has_size +// Access: Published +// Description: Returns true if the window size has been specified, +// false otherwise. +//////////////////////////////////////////////////////////////////// +INLINE bool WindowProperties:: +has_size() const { + return ((_specified & S_size) != 0); +} + +//////////////////////////////////////////////////////////////////// +// Function: WindowProperties::clear_size +// Access: Published +// Description: Removes the size specification from the properties. +//////////////////////////////////////////////////////////////////// +INLINE void WindowProperties:: +clear_size() { + _specified &= ~S_size; + _x_size = 0; + _y_size = 0; +} + +//////////////////////////////////////////////////////////////////// +// Function: WindowProperties::set_title +// Access: Published +// Description: Specifies the title that should be assigned to the +// window. +//////////////////////////////////////////////////////////////////// +INLINE void WindowProperties:: +set_title(const string &title) { + _title = title; + _specified |= S_title; +} + +//////////////////////////////////////////////////////////////////// +// Function: WindowProperties::get_title +// Access: Published +// Description: Returns the window's title. +//////////////////////////////////////////////////////////////////// +INLINE const string &WindowProperties:: +get_title() const { + nassertr(has_title(), _title); + return _title; +} + +//////////////////////////////////////////////////////////////////// +// Function: WindowProperties::has_title +// Access: Published +// Description: Returns true if the window title has been specified, +// false otherwise. +//////////////////////////////////////////////////////////////////// +INLINE bool WindowProperties:: +has_title() const { + return ((_specified & S_title) != 0); +} + +//////////////////////////////////////////////////////////////////// +// Function: WindowProperties::clear_title +// Access: Published +// Description: Removes the title specification from the properties. +//////////////////////////////////////////////////////////////////// +INLINE void WindowProperties:: +clear_title() { + _specified &= ~S_title; + _title = string(); +} + +//////////////////////////////////////////////////////////////////// +// Function: WindowProperties::set_undecorated +// Access: Published +// Description: Specifies whether the window should be created with a +// visible title and border (false, the default) or not +// (true). +//////////////////////////////////////////////////////////////////// +INLINE void WindowProperties:: +set_undecorated(bool undecorated) { + if (undecorated) { + _flags |= F_undecorated; + } else { + _flags &= ~F_undecorated; + } + _specified |= S_undecorated; +} + +//////////////////////////////////////////////////////////////////// +// Function: WindowProperties::get_undecorated +// Access: Published +// Description: Returns true if the window has no border. +//////////////////////////////////////////////////////////////////// +INLINE bool WindowProperties:: +get_undecorated() const { + return (_flags & F_undecorated) != 0; +} + +//////////////////////////////////////////////////////////////////// +// Function: WindowProperties::has_undecorated +// Access: Published +// Description: Returns true if set_undecorated() has been specified. +//////////////////////////////////////////////////////////////////// +INLINE bool WindowProperties:: +has_undecorated() const { + return ((_specified & S_undecorated) != 0); +} + +//////////////////////////////////////////////////////////////////// +// Function: WindowProperties::clear_undecorated +// Access: Published +// Description: Removes the undecorated specification from the properties. +//////////////////////////////////////////////////////////////////// +INLINE void WindowProperties:: +clear_undecorated() { + _specified &= ~S_undecorated; + _flags &= ~F_undecorated; +} + +//////////////////////////////////////////////////////////////////// +// Function: WindowProperties::set_fullscreen +// Access: Published +// Description: Specifies whether the window should be opened in +// fullscreen mode (true) or normal windowed mode +// (false, the default). +//////////////////////////////////////////////////////////////////// +INLINE void WindowProperties:: +set_fullscreen(bool fullscreen) { + if (fullscreen) { + _flags |= F_fullscreen; + } else { + _flags &= ~F_fullscreen; + } + _specified |= S_fullscreen; +} + +//////////////////////////////////////////////////////////////////// +// Function: WindowProperties::get_fullscreen +// Access: Published +// Description: Returns true if the window is in fullscreen mode. +//////////////////////////////////////////////////////////////////// +INLINE bool WindowProperties:: +get_fullscreen() const { + return (_flags & F_fullscreen) != 0; +} + +//////////////////////////////////////////////////////////////////// +// Function: WindowProperties::has_fullscreen +// Access: Published +// Description: Returns true if set_fullscreen() has been specified. +//////////////////////////////////////////////////////////////////// +INLINE bool WindowProperties:: +has_fullscreen() const { + return ((_specified & S_fullscreen) != 0); +} + +//////////////////////////////////////////////////////////////////// +// Function: WindowProperties::clear_fullscreen +// Access: Published +// Description: Removes the fullscreen specification from the properties. +//////////////////////////////////////////////////////////////////// +INLINE void WindowProperties:: +clear_fullscreen() { + _specified &= ~S_fullscreen; + _flags &= ~F_fullscreen; +} + +//////////////////////////////////////////////////////////////////// +// Function: WindowProperties::set_foreground +// Access: Published +// Description: Specifies whether the window should be opened in +// the foreground (true), or left in the background +// (false). +//////////////////////////////////////////////////////////////////// +INLINE void WindowProperties:: +set_foreground(bool foreground) { + if (foreground) { + _flags |= F_foreground; + } else { + _flags &= ~F_foreground; + } + _specified |= S_foreground; +} + +//////////////////////////////////////////////////////////////////// +// Function: WindowProperties::get_foreground +// Access: Published +// Description: Returns true if the window is in the foreground. +//////////////////////////////////////////////////////////////////// +INLINE bool WindowProperties:: +get_foreground() const { + return (_flags & F_foreground) != 0; +} + +//////////////////////////////////////////////////////////////////// +// Function: WindowProperties::has_foreground +// Access: Published +// Description: Returns true if set_foreground() has been specified. +//////////////////////////////////////////////////////////////////// +INLINE bool WindowProperties:: +has_foreground() const { + return ((_specified & S_foreground) != 0); +} + +//////////////////////////////////////////////////////////////////// +// Function: WindowProperties::clear_foreground +// Access: Published +// Description: Removes the foreground specification from the properties. +//////////////////////////////////////////////////////////////////// +INLINE void WindowProperties:: +clear_foreground() { + _specified &= ~S_foreground; + _flags &= ~F_foreground; +} + +//////////////////////////////////////////////////////////////////// +// Function: WindowProperties::set_minimized +// Access: Published +// Description: Specifies whether the window should be created +// minimized (true), or normal (false). +//////////////////////////////////////////////////////////////////// +INLINE void WindowProperties:: +set_minimized(bool minimized) { + if (minimized) { + _flags |= F_minimized; + } else { + _flags &= ~F_minimized; + } + _specified |= S_minimized; +} + +//////////////////////////////////////////////////////////////////// +// Function: WindowProperties::get_minimized +// Access: Published +// Description: Returns true if the window is minimized. +//////////////////////////////////////////////////////////////////// +INLINE bool WindowProperties:: +get_minimized() const { + return (_flags & F_minimized) != 0; +} + +//////////////////////////////////////////////////////////////////// +// Function: WindowProperties::has_minimized +// Access: Published +// Description: Returns true if set_minimized() has been specified. +//////////////////////////////////////////////////////////////////// +INLINE bool WindowProperties:: +has_minimized() const { + return ((_specified & S_minimized) != 0); +} + +//////////////////////////////////////////////////////////////////// +// Function: WindowProperties::clear_minimized +// Access: Published +// Description: Removes the minimized specification from the properties. +//////////////////////////////////////////////////////////////////// +INLINE void WindowProperties:: +clear_minimized() { + _specified &= ~S_minimized; + _flags &= ~F_minimized; +} + +//////////////////////////////////////////////////////////////////// +// Function: WindowProperties::set_open +// Access: Published +// Description: Specifies whether the window should be open. It is +// legal to create a GraphicsWindow in the closed state, +// and later request it to open by changing this flag. +//////////////////////////////////////////////////////////////////// +INLINE void WindowProperties:: +set_open(bool open) { + if (open) { + _flags |= F_open; + } else { + _flags &= ~F_open; + } + _specified |= S_open; +} + +//////////////////////////////////////////////////////////////////// +// Function: WindowProperties::get_open +// Access: Published +// Description: Returns true if the window is open. +//////////////////////////////////////////////////////////////////// +INLINE bool WindowProperties:: +get_open() const { + return (_flags & F_open) != 0; +} + +//////////////////////////////////////////////////////////////////// +// Function: WindowProperties::has_open +// Access: Published +// Description: Returns true if set_open() has been specified. +//////////////////////////////////////////////////////////////////// +INLINE bool WindowProperties:: +has_open() const { + return ((_specified & S_open) != 0); +} + +//////////////////////////////////////////////////////////////////// +// Function: WindowProperties::clear_open +// Access: Published +// Description: Removes the open specification from the properties. +//////////////////////////////////////////////////////////////////// +INLINE void WindowProperties:: +clear_open() { + _specified &= ~S_open; + _flags &= ~F_open; +} + +//////////////////////////////////////////////////////////////////// +// Function: WindowProperties::set_cursor_hidden +// Access: Published +// Description: Specifies whether the mouse cursor should be visible. +//////////////////////////////////////////////////////////////////// +INLINE void WindowProperties:: +set_cursor_hidden(bool cursor_hidden) { + if (cursor_hidden) { + _flags |= F_cursor_hidden; + } else { + _flags &= ~F_cursor_hidden; + } + _specified |= S_cursor_hidden; +} + +//////////////////////////////////////////////////////////////////// +// Function: WindowProperties::set_cursor_hidden +// Access: Published +// Description: Returns true if the mouse cursor is invisible. +//////////////////////////////////////////////////////////////////// +INLINE bool WindowProperties:: +get_cursor_hidden() const { + return (_flags & F_cursor_hidden) != 0; +} + +//////////////////////////////////////////////////////////////////// +// Function: WindowProperties::has_cursor_hidden +// Access: Published +// Description: Returns true if set_cursor_hidden() has been specified. +//////////////////////////////////////////////////////////////////// +INLINE bool WindowProperties:: +has_cursor_hidden() const { + return ((_specified & S_cursor_hidden) != 0); +} + +//////////////////////////////////////////////////////////////////// +// Function: WindowProperties::clear_cursor_hidden +// Access: Published +// Description: Removes the cursor_hidden specification from the properties. +//////////////////////////////////////////////////////////////////// +INLINE void WindowProperties:: +clear_cursor_hidden() { + _specified &= ~S_cursor_hidden; + _flags &= ~F_cursor_hidden; +} + +//////////////////////////////////////////////////////////////////// +// Function: WindowProperties::set_framebuffer_mode +// Access: Published +// Description: Specifies the set of graphics properties that are +// required for the context associated with the window. +// This should be the union of the appropriate bits +// defined in FramebufferMode. +//////////////////////////////////////////////////////////////////// +INLINE void WindowProperties:: +set_framebuffer_mode(int framebuffer_mode) { + _framebuffer_mode = framebuffer_mode; + _specified |= S_framebuffer_mode; +} + +//////////////////////////////////////////////////////////////////// +// Function: WindowProperties::get_framebuffer_mode +// Access: Published +// Description: Returns the set of graphics properties that are +// in effect for the window. This will be the union of +// the corresponding bits from FramebufferMode. +//////////////////////////////////////////////////////////////////// +INLINE int WindowProperties:: +get_framebuffer_mode() const { + nassertr(has_framebuffer_mode(), false); + return _framebuffer_mode; +} + +//////////////////////////////////////////////////////////////////// +// Function: WindowProperties::has_framebuffer_mode +// Access: Published +// Description: Returns true if the framebuffer mode has been +// specified, false otherwise. +//////////////////////////////////////////////////////////////////// +INLINE bool WindowProperties:: +has_framebuffer_mode() const { + return ((_specified & S_framebuffer_mode) != 0); +} + +//////////////////////////////////////////////////////////////////// +// Function: WindowProperties::clear_framebuffer_mode +// Access: Published +// Description: Removes the framebuffer_mode specification from the +// properties. +//////////////////////////////////////////////////////////////////// +INLINE void WindowProperties:: +clear_framebuffer_mode() { + _specified &= ~S_framebuffer_mode; + _framebuffer_mode = 0; +} + +//////////////////////////////////////////////////////////////////// +// Function: WindowProperties::set_depth_bits +// Access: Published +// Description: Specifies the minimum number of bits that are +// required for the depth buffer. +//////////////////////////////////////////////////////////////////// +INLINE void WindowProperties:: +set_depth_bits(int depth_bits) { + _depth_bits = depth_bits; + _specified |= S_depth_bits; +} + +//////////////////////////////////////////////////////////////////// +// Function: WindowProperties::get_depth_bits +// Access: Published +// Description: Returns the number of bits specified for the depth +// buffer. +//////////////////////////////////////////////////////////////////// +INLINE int WindowProperties:: +get_depth_bits() const { + return _depth_bits; +} + +//////////////////////////////////////////////////////////////////// +// Function: WindowProperties::has_depth_bits +// Access: Published +// Description: Returns true if the number of bits for the depth +// buffer has been specified, false otherwise. +//////////////////////////////////////////////////////////////////// +INLINE bool WindowProperties:: +has_depth_bits() const { + return ((_specified & S_depth_bits) != 0); +} + +//////////////////////////////////////////////////////////////////// +// Function: WindowProperties::clear_depth_bits +// Access: Published +// Description: Removes the depth_bits specification from the +// properties. +//////////////////////////////////////////////////////////////////// +INLINE void WindowProperties:: +clear_depth_bits() { + _specified &= ~S_depth_bits; + _depth_bits = 0; +} + +//////////////////////////////////////////////////////////////////// +// Function: WindowProperties::set_color_bits +// Access: Published +// Description: Specifies the minimum number of bits that are +// required for all three channels of the color buffer. +// That is, this is the per-channel color requirement +// times three. +//////////////////////////////////////////////////////////////////// +INLINE void WindowProperties:: +set_color_bits(int color_bits) { + _color_bits = color_bits; + _specified |= S_color_bits; +} + +//////////////////////////////////////////////////////////////////// +// Function: WindowProperties::get_color_bits +// Access: Published +// Description: Returns the number of bits specified for the color +// buffer. +//////////////////////////////////////////////////////////////////// +INLINE int WindowProperties:: +get_color_bits() const { + return _color_bits; +} + +//////////////////////////////////////////////////////////////////// +// Function: WindowProperties::has_color_bits +// Access: Published +// Description: Returns true if the number of bits for the color +// buffer has been specified, false otherwise. +//////////////////////////////////////////////////////////////////// +INLINE bool WindowProperties:: +has_color_bits() const { + return ((_specified & S_color_bits) != 0); +} + +//////////////////////////////////////////////////////////////////// +// Function: WindowProperties::clear_color_bits +// Access: Published +// Description: Removes the color_bits specification from the +// properties. +//////////////////////////////////////////////////////////////////// +INLINE void WindowProperties:: +clear_color_bits() { + _specified &= ~S_color_bits; + _color_bits = 0; +} + +INLINE ostream & +operator << (ostream &out, const WindowProperties &properties) { + properties.output(out); + return out; +} diff --git a/panda/src/display/windowProperties.cxx b/panda/src/display/windowProperties.cxx new file mode 100644 index 0000000000..3aa5483083 --- /dev/null +++ b/panda/src/display/windowProperties.cxx @@ -0,0 +1,220 @@ +// Filename: windowProperties.cxx +// Created by: drose (13Aug02) +// +//////////////////////////////////////////////////////////////////// +// +// 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 "windowProperties.h" + + +//////////////////////////////////////////////////////////////////// +// Function: WindowProperties::Constructor +// Access: Published +// Description: +//////////////////////////////////////////////////////////////////// +WindowProperties:: +WindowProperties() { + clear(); +} + +//////////////////////////////////////////////////////////////////// +// Function: WindowProperties::Copy Assignment Operator +// Access: Published +// Description: +//////////////////////////////////////////////////////////////////// +void WindowProperties:: +operator = (const WindowProperties ©) { + _specified = copy._specified; + _x_origin = copy._x_origin; + _y_origin = copy._y_origin; + _x_size = copy._x_size; + _y_size = copy._y_size; + _title = copy._title; + _flags = copy._flags; + _framebuffer_mode = copy._framebuffer_mode; + _depth_bits = copy._depth_bits; + _color_bits = copy._color_bits; +} + +//////////////////////////////////////////////////////////////////// +// Function: WindowProperties::operator == +// Access: Published +// Description: +//////////////////////////////////////////////////////////////////// +bool WindowProperties:: +operator == (const WindowProperties &other) const { + return (_specified == other._specified && + _flags == other._flags && + _x_origin == other._x_origin && + _y_origin == other._y_origin && + _x_size == other._x_size && + _y_size == other._y_size && + _title == other._title && + _framebuffer_mode == other._framebuffer_mode && + _depth_bits == other._depth_bits && + _color_bits == other._color_bits); +} + +//////////////////////////////////////////////////////////////////// +// Function: WindowProperties::clear +// Access: Published +// Description: Unsets all properties that have been specified so +// far, and resets the WindowProperties structure to its +// initial empty state. +//////////////////////////////////////////////////////////////////// +void WindowProperties:: +clear() { + _specified = 0; + _x_origin = 0; + _y_origin = 0; + _x_size = 0; + _y_size = 0; + _title = string(); + _flags = 0; + _framebuffer_mode = 0; + _depth_bits = 0; + _color_bits = 0; +} + +//////////////////////////////////////////////////////////////////// +// Function: WindowProperties::add_properties +// Access: Published +// Description: Sets any properties that are explicitly specified in +// other on this object. Leaves other properties +// unchanged. +//////////////////////////////////////////////////////////////////// +void WindowProperties:: +add_properties(const WindowProperties &other) { + if (other.has_origin()) { + set_origin(other.get_x_origin(), other.get_y_origin()); + } + if (other.has_size()) { + set_size(other.get_x_size(), other.get_y_size()); + } + if (other.has_title()) { + set_title(other.get_title()); + } + if (other.has_undecorated()) { + set_undecorated(other.get_undecorated()); + } + if (other.has_fullscreen()) { + set_fullscreen(other.get_fullscreen()); + } + if (other.has_foreground()) { + set_foreground(other.get_foreground()); + } + if (other.has_minimized()) { + set_minimized(other.get_minimized()); + } + if (other.has_open()) { + set_open(other.get_open()); + } + if (other.has_cursor_hidden()) { + set_cursor_hidden(other.get_cursor_hidden()); + } + if (other.has_framebuffer_mode()) { + set_framebuffer_mode(other.get_framebuffer_mode()); + } + if (other.has_depth_bits()) { + set_depth_bits(other.get_depth_bits()); + } + if (other.has_color_bits()) { + set_color_bits(other.get_color_bits()); + } +} + +//////////////////////////////////////////////////////////////////// +// Function: WindowProperties::output +// Access: Published +// Description: Sets any properties that are explicitly specified in +// other on this object. Leaves other properties +// unchanged. +//////////////////////////////////////////////////////////////////// +void WindowProperties:: +output(ostream &out) const { + if (has_origin()) { + out << "origin=(" << get_x_origin() << ", " << get_y_origin() << ") "; + } + if (has_size()) { + out << "size=(" << get_x_size() << ", " << get_y_size() << ") "; + } + if (has_title()) { + out << "title=\"" << get_title() << "\"" << " "; + } + if (has_undecorated()) { + out << (get_undecorated() ? "undecorated " : "!undecorated "); + } + if (has_fullscreen()) { + out << (get_fullscreen() ? "fullscreen " : "!fullscreen "); + } + if (has_foreground()) { + out << (get_foreground() ? "foreground " : "!foreground "); + } + if (has_minimized()) { + out << (get_minimized() ? "minimized " : "!minimized "); + } + if (has_open()) { + out << (get_open() ? "open " : "!open "); + } + if (has_cursor_hidden()) { + out << (get_cursor_hidden() ? "cursor_hidden " : "!cursor_hidden "); + } + if (has_framebuffer_mode()) { + out << "framebuffer_mode="; + int framebuffer_mode = get_framebuffer_mode(); + if ((framebuffer_mode & FM_index) != 0) { + out << "FM_index"; + } else { + out << "FM_rgb"; + } + + if ((framebuffer_mode & FM_triple_buffer) != 0) { + out << "|FM_triple_buffer"; + } else if ((framebuffer_mode & FM_double_buffer) != 0) { + out << "|FM_double_buffer"; + } else { + out << "|FM_single_buffer"; + } + + if ((framebuffer_mode & FM_accum) != 0) { + out << "|FM_accum"; + } + if ((framebuffer_mode & FM_alpha) != 0) { + out << "|FM_alpha"; + } + if ((framebuffer_mode & FM_depth) != 0) { + out << "|FM_depth"; + } + if ((framebuffer_mode & FM_stencil) != 0) { + out << "|FM_stencil"; + } + if ((framebuffer_mode & FM_multisample) != 0) { + out << "|FM_multisample"; + } + if ((framebuffer_mode & FM_stereo) != 0) { + out << "|FM_stereo"; + } + if ((framebuffer_mode & FM_luminance) != 0) { + out << "|FM_luminance"; + } + out << " "; + } + if (has_depth_bits()) { + out << "depth_bits=" << get_depth_bits() << " "; + } + if (has_color_bits()) { + out << "color_bits=" << get_color_bits() << " "; + } +} diff --git a/panda/src/display/windowProperties.h b/panda/src/display/windowProperties.h new file mode 100644 index 0000000000..45bf274a87 --- /dev/null +++ b/panda/src/display/windowProperties.h @@ -0,0 +1,173 @@ +// Filename: windowProperties.h +// Created by: drose (13Aug02) +// +//////////////////////////////////////////////////////////////////// +// +// 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 WINDOWPROPERTIES_H +#define WINDOWPROPERTIES_H + +#include "pandabase.h" + +//////////////////////////////////////////////////////////////////// +// Class : WindowProperties +// Description : A container for the various kinds of properties we +// might ask to have on a graphics window before we open +// it. This also serves to hold the current properties +// for a window after it has been opened. +//////////////////////////////////////////////////////////////////// +class EXPCL_PANDA WindowProperties { +PUBLISHED: + WindowProperties(); + INLINE WindowProperties(const WindowProperties ©); + void operator = (const WindowProperties ©); + INLINE ~WindowProperties(); + + bool operator == (const WindowProperties &other) const; + INLINE bool operator != (const WindowProperties &other) const; + + enum FramebufferMode { + FM_rgba = 0x0000, + FM_rgb = 0x0000, + FM_index = 0x0001, + FM_single_buffer = 0x0000, + FM_double_buffer = 0x0002, + FM_triple_buffer = 0x0004, + FM_accum = 0x0008, + FM_alpha = 0x0010, + FM_depth = 0x0020, + FM_stencil = 0x0040, + FM_multisample = 0x0080, + FM_stereo = 0x0100, + FM_luminance = 0x0200, + }; + + void clear(); + INLINE bool is_any_specified() const; + + INLINE void set_origin(int x_origin, int y_origin); + INLINE int get_x_origin() const; + INLINE int get_y_origin() const; + INLINE bool has_origin() const; + INLINE void clear_origin(); + + INLINE void set_size(int x_size, int y_size); + INLINE int get_x_size() const; + INLINE int get_y_size() const; + INLINE bool has_size() const; + INLINE void clear_size(); + + INLINE void set_title(const string &title); + INLINE const string &get_title() const; + INLINE bool has_title() const; + INLINE void clear_title(); + + INLINE void set_undecorated(bool undecorated); + INLINE bool get_undecorated() const; + INLINE bool has_undecorated() const; + INLINE void clear_undecorated(); + + INLINE void set_fullscreen(bool fullscreen); + INLINE bool get_fullscreen() const; + INLINE bool has_fullscreen() const; + INLINE void clear_fullscreen(); + + INLINE void set_foreground(bool foreground); + INLINE bool get_foreground() const; + INLINE bool has_foreground() const; + INLINE void clear_foreground(); + + INLINE void set_minimized(bool minimized); + INLINE bool get_minimized() const; + INLINE bool has_minimized() const; + INLINE void clear_minimized(); + + INLINE void set_open(bool open); + INLINE bool get_open() const; + INLINE bool has_open() const; + INLINE void clear_open(); + + INLINE void set_cursor_hidden(bool cursor_hidden); + INLINE bool get_cursor_hidden() const; + INLINE bool has_cursor_hidden() const; + INLINE void clear_cursor_hidden(); + + INLINE void set_framebuffer_mode(int framebuffer_mode); + INLINE int get_framebuffer_mode() const; + INLINE bool has_framebuffer_mode() const; + INLINE void clear_framebuffer_mode(); + + INLINE void set_depth_bits(int depth_bits); + INLINE int get_depth_bits() const; + INLINE bool has_depth_bits() const; + INLINE void clear_depth_bits(); + + INLINE void set_color_bits(int color_bits); + INLINE int get_color_bits() const; + INLINE bool has_color_bits() const; + INLINE void clear_color_bits(); + + void add_properties(const WindowProperties &other); + + void output(ostream &out) const; + +private: + // This bitmask indicates which of the parameters in the properties + // structure have been filled in by the user, and which remain + // unspecified. + enum Specified { + S_origin = 0x0001, + S_size = 0x0002, + S_title = 0x0004, + S_undecorated = 0x0008, + S_fullscreen = 0x0010, + S_foreground = 0x0020, + S_minimized = 0x0040, + S_open = 0x0080, + S_cursor_hidden = 0x0100, + S_framebuffer_mode = 0x0200, + S_depth_bits = 0x0400, + S_color_bits = 0x0800, + }; + + // This bitmask represents the true/false settings for various + // boolean flags (assuming the corresponding S_* bit has been set, + // above). + enum Flags { + F_undecorated = S_undecorated, + F_fullscreen = S_fullscreen, + F_foreground = S_foreground, + F_minimized = S_minimized, + F_open = S_open, + F_cursor_hidden = S_cursor_hidden, + }; + + int _specified; + int _x_origin; + int _y_origin; + int _x_size; + int _y_size; + string _title; + int _flags; + int _framebuffer_mode; + int _depth_bits; + int _color_bits; +}; + +INLINE ostream &operator << (ostream &out, const WindowProperties &properties); + +#include "windowProperties.I" + +#endif diff --git a/panda/src/distort/nonlinearImager.cxx b/panda/src/distort/nonlinearImager.cxx index 2f875febcb..a16008dfdb 100644 --- a/panda/src/distort/nonlinearImager.cxx +++ b/panda/src/distort/nonlinearImager.cxx @@ -601,7 +601,7 @@ render_screen(GraphicsEngine *engine, NonlinearImager::Screen &screen) { PT(DisplayRegion) scratch_region = _gsg->get_window()->make_scratch_display_region(screen._tex_width, screen._tex_height); scratch_region->set_camera(screen._source_camera); - engine->render_subframe(_gsg, scratch_region); + engine->render_subframe(_gsg, scratch_region, true); // Copy the results of the render from the frame buffer into the // screen's texture. diff --git a/panda/src/dxgsg/Sources.pp b/panda/src/dxgsg/Sources.pp deleted file mode 100644 index fd7f77a34e..0000000000 --- a/panda/src/dxgsg/Sources.pp +++ /dev/null @@ -1,29 +0,0 @@ -#define BUILD_DIRECTORY $[HAVE_DX] - -#define OTHER_LIBS interrogatedb:c dconfig:c dtoolconfig:m \ - dtoolutil:c dtoolbase:c dtool:m -#define USE_PACKAGES dx - -#begin lib_target - - #define TARGET dxgsg - #define LOCAL_LIBS \ - gsgmisc gsgbase gobj display \ - putil linmath mathutil pnmimage event - - #define COMBINED_SOURCES $[TARGET]_composite1.cxx - - // need to install these due to external projects that link directly with libpandadx (bartop) - #define INSTALL_HEADERS \ - config_dxgsg.h dxGraphicsStateGuardian.I dxGraphicsStateGuardian.h \ - dxTextureContext.h dxGeomNodeContext.h dxGeomNodeContext.I dxgsgbase.h - - // build dxGraphicsStateGuardian separately since its so big - - #define SOURCES \ - dxGraphicsStateGuardian.cxx dxSavedFrameBuffer.I dxSavedFrameBuffer.h $[INSTALL_HEADERS] - - #define INCLUDED_SOURCES \ - config_dxgsg.cxx dxSavedFrameBuffer.cxx dxTextureContext.cxx dxGeomNodeContext.cxx - -#end lib_target diff --git a/panda/src/dxgsg/dxgsg_composite1.cxx b/panda/src/dxgsg/dxgsg_composite1.cxx deleted file mode 100644 index b12fee76c0..0000000000 --- a/panda/src/dxgsg/dxgsg_composite1.cxx +++ /dev/null @@ -1,4 +0,0 @@ -#include "config_dxgsg.cxx" -#include "dxSavedFrameBuffer.cxx" -#include "dxTextureContext.cxx" -#include "dxGeomNodeContext.cxx" diff --git a/panda/src/dxgsg7/Sources.pp b/panda/src/dxgsg7/Sources.pp new file mode 100644 index 0000000000..b69cf51f41 --- /dev/null +++ b/panda/src/dxgsg7/Sources.pp @@ -0,0 +1,36 @@ +#define BUILD_DIRECTORY $[HAVE_DX] + +#define OTHER_LIBS interrogatedb:c dconfig:c dtoolconfig:m \ + dtoolutil:c dtoolbase:c dtool:m +#define USE_PACKAGES dx + +#begin lib_target + + #define TARGET dxgsg7 + #define LOCAL_LIBS \ + gsgmisc gsgbase gobj display windisplay \ + putil linmath mathutil pnmimage event + + #define COMBINED_SOURCES $[TARGET]_composite1.cxx + + // need to install these due to external projects that link directly with libpandadx (bartop) + #define INSTALL_HEADERS \ + config_dxgsg7.h dxGraphicsStateGuardian7.I dxGraphicsStateGuardian7.h \ + dxTextureContext7.h dxGeomNodeContext7.h dxGeomNodeContext7.I dxgsg7base.h + + // build dxGraphicsStateGuardian separately since its so big + + #define SOURCES \ + dxGraphicsStateGuardian7.cxx dxSavedFrameBuffer7.I dxSavedFrameBuffer7.h \ + wdxGraphicsPipe7.I wdxGraphicsPipe7.h \ + wdxGraphicsWindow7.I wdxGraphicsWindow7.h \ + $[INSTALL_HEADERS] + + #define INCLUDED_SOURCES \ + config_dxgsg7.cxx \ + dxgsg7base.cxx \ + dxSavedFrameBuffer7.cxx dxTextureContext7.cxx \ + dxGeomNodeContext7.cxx \ + wdxGraphicsPipe7.cxx wdxGraphicsWindow7.cxx + +#end lib_target diff --git a/panda/src/dxgsg/config_dxgsg.cxx b/panda/src/dxgsg7/config_dxgsg7.cxx similarity index 53% rename from panda/src/dxgsg/config_dxgsg.cxx rename to panda/src/dxgsg7/config_dxgsg7.cxx index 076a6a1799..2ac195413f 100644 --- a/panda/src/dxgsg/config_dxgsg.cxx +++ b/panda/src/dxgsg7/config_dxgsg7.cxx @@ -16,41 +16,45 @@ // //////////////////////////////////////////////////////////////////// -#include "config_dxgsg.h" -#include "dxGraphicsStateGuardian.h" -#include "dxSavedFrameBuffer.h" -#include "dxTextureContext.h" +#include "config_dxgsg7.h" +#include "dxGraphicsStateGuardian7.h" +#include "dxSavedFrameBuffer7.h" +#include "dxTextureContext7.h" +#include "wdxGraphicsPipe7.h" +#include "wdxGraphicsWindow7.h" +#include "graphicsPipeSelection.h" -#include +#include "dconfig.h" -Configure(config_dxgsg); -NotifyCategoryDef(dxgsg, ":display:gsg"); +Configure(config_dxgsg7); +NotifyCategoryDef(dxgsg7, ":display:gsg"); +NotifyCategoryDef(wdxdisplay7, "windisplay"); // Configure this variable true to cause the DXGSG to show each // transform space it renders by drawing a little unit axis. This // cannot be enabled when the player is compiled in NDEBUG mode. -bool dx_show_transforms = config_dxgsg.GetBool("dx-show-transforms", false); +bool dx_show_transforms = config_dxgsg7.GetBool("dx-show-transforms", false); // Configure this to TRUE if you want DirectX to control the entire screen, // If false, it will just blit into a window. -bool dx_full_screen = config_dxgsg.GetBool("dx-full-screen", false); +bool dx_full_screen = config_dxgsg7.GetBool("dx-full-screen", false); // Configure this true to force the rendering to sync to the video // refresh, or false to let your frame rate go as high as it can, // irrespective of the video refresh. -bool dx_sync_video = config_dxgsg.GetBool("sync-video", true); +bool dx_sync_video = config_dxgsg7.GetBool("sync-video", true); // enable this to turn on full-screen anti-aliasing, if the HW supports it // this var is also used in wdxGraphicsWindows.cxx -bool dx_full_screen_antialiasing = config_dxgsg.GetBool("dx-antialias", false); +bool dx_full_screen_antialiasing = config_dxgsg7.GetBool("dx-antialias", false); // Configure this true to perform a cull traversal over the geometry // by default, false otherwise. The cull traversal provides support // for state-sorting, z-sorting, and binning. -bool dx_cull_traversal = config_dxgsg.GetBool("dx-cull-traversal", true); +bool dx_cull_traversal = config_dxgsg7.GetBool("dx-cull-traversal", true); // if true, if card only supports per-vertex fog, it will be treated as no-HW fog capability -bool dx_no_vertex_fog = config_dxgsg.GetBool("dx-no-vertex-fog", false); +bool dx_no_vertex_fog = config_dxgsg7.GetBool("dx-no-vertex-fog", false); // Configure this true to cause all lighting normals to automatically // be normalized by the CPU before rendering. This is @@ -58,43 +62,43 @@ bool dx_no_vertex_fog = config_dxgsg.GetBool("dx-no-vertex-fog", false); // expect lighting to work correctly. Maybe one day there will be // another way to set this at runtime, instead of only as a configure // variable -bool dx_auto_normalize_lighting = config_dxgsg.GetBool("auto-normalize-lighting", false); +bool dx_auto_normalize_lighting = config_dxgsg7.GetBool("auto-normalize-lighting", false); -bool dx_allow_software_renderer = config_dxgsg.GetBool("dx-allow-software-renderer", false); -bool dx_force_software_renderer = config_dxgsg.GetBool("dx-force-software-renderer", false); - -bool dx_show_fps_meter = config_dxgsg.GetBool("show-fps-meter", false); -float dx_fps_meter_update_interval = max(0.5,config_dxgsg.GetFloat("fps-meter-update-interval", 1.7)); +bool dx_allow_software_renderer = config_dxgsg7.GetBool("dx-allow-software-renderer", false); +bool dx_force_software_renderer = config_dxgsg7.GetBool("dx-force-software-renderer", false); #ifndef NDEBUG // debugging flag // values are same as D3DCULL enumtype, 0 - no force, 1 - force none, 2 - force CW, 3 - force CCW -int dx_force_backface_culling = config_dxgsg.GetInt("dx-force-backface-culling", 0); +int dx_force_backface_culling = config_dxgsg7.GetInt("dx-force-backface-culling", 0); #endif -bool dx_mipmap_everything = config_dxgsg.GetBool("dx-mipmap-everything", false); -bool dx_ignore_mipmaps = config_dxgsg.GetBool("dx-ignore-mipmaps", false); +bool dx_mipmap_everything = config_dxgsg7.GetBool("dx-mipmap-everything", false); +bool dx_ignore_mipmaps = config_dxgsg7.GetBool("dx-ignore-mipmaps", false); // if this is set, more accurate but more expensive fog computations are performed -bool dx_use_rangebased_fog = config_dxgsg.GetBool("dx-use-rangebased-fog", false); -bool dx_force_16bpptextures = config_dxgsg.GetBool("dx-force-16bpptextures", false); -bool dx_no_dithering = config_dxgsg.GetBool("dx-no-dithering", false); +bool dx_use_rangebased_fog = config_dxgsg7.GetBool("dx-use-rangebased-fog", false); +bool dx_force_16bpptextures = config_dxgsg7.GetBool("dx-force-16bpptextures", false); +bool dx_no_dithering = config_dxgsg7.GetBool("dx-no-dithering", false); +bool dx_force_16bpp_zbuffer = config_dxgsg7.GetBool("dx-force-16bpp-zbuffer", false); +bool dx_do_vidmemsize_check = config_dxgsg7.GetBool("do-vidmemsize-check", true); +bool dx_preserve_fpu_state = config_dxgsg7.GetBool("dx-preserve-fpu-state", false); // Configure this true to try to implement decals using a // DepthOffsetAttrib, false to do them with the more reliable 3-pass // rendering method instead. -bool dx_depth_offset_decals = config_dxgsg.GetBool("depth-offset-decals", false); +bool dx_depth_offset_decals = config_dxgsg7.GetBool("depth-offset-decals", false); #ifdef _DEBUG -float dx_global_miplevel_bias = config_dxgsg.GetFloat("dx-global-miplevel-bias", 0.0); -bool dx_debug_view_mipmaps = config_dxgsg.GetBool("dx-debug-view-mipmaps", false); -bool dx_force_anisotropic_filtering = config_dxgsg.GetBool("dx-force-anisotropic-filtering", false); -//int dx_print_texstats = config_dxgsg.GetBool("dx-print-texstats", 0); +float dx_global_miplevel_bias = config_dxgsg7.GetFloat("dx-global-miplevel-bias", 0.0); +bool dx_debug_view_mipmaps = config_dxgsg7.GetBool("dx-debug-view-mipmaps", false); +bool dx_force_anisotropic_filtering = config_dxgsg7.GetBool("dx-force-anisotropic-filtering", false); +//int dx_print_texstats = config_dxgsg7.GetBool("dx-print-texstats", 0); #endif // set 'retained-mode #t' and this to have prepare_geom concatenate all tristrips within a geom // together using degenerate tris -const bool link_tristrips = config_dxgsg.GetBool("link-tristrips", false); +const bool link_tristrips = config_dxgsg7.GetBool("link-tristrips", false); // note: offset currently disabled since it wasnt working properly DXDecalType dx_decal_type = GDT_blend; @@ -108,16 +112,16 @@ parse_decal_type(const string &type) { } else if (type == "offset") { return GDT_offset; } - dxgsg_cat.error() << "Invalid dx-decal-type: " << type << "\n"; + dxgsg7_cat.error() << "Invalid dx-decal-type: " << type << "\n"; return GDT_blend; } -ConfigureFn(config_dxgsg) { - init_libdxgsg(); +ConfigureFn(config_dxgsg7) { + init_libdxgsg7(); } //////////////////////////////////////////////////////////////////// -// Function: init_libdxgsg +// Function: init_libdxgsg7 // Description: Initializes the library. This must be called at // least once before any of the functions or classes in // this library can be used. Normally it will be @@ -125,24 +129,27 @@ ConfigureFn(config_dxgsg) { // called explicitly, but special cases exist. //////////////////////////////////////////////////////////////////// void -init_libdxgsg() { +init_libdxgsg7() { static bool initialized = false; if (initialized) { return; } initialized = true; - string decal_type = config_dxgsg.GetString("dx-decal-type", ""); + string decal_type = config_dxgsg7.GetString("dx-decal-type", ""); if (!decal_type.empty()) { dx_decal_type = parse_decal_type(decal_type); } - DXGraphicsStateGuardian::init_type(); - DXSavedFrameBuffer::init_type(); - DXTextureContext::init_type(); - DXGeomNodeContext::init_type(); + DXGraphicsStateGuardian7::init_type(); + DXSavedFrameBuffer7::init_type(); + DXTextureContext7::init_type(); + DXGeomNodeContext7::init_type(); - GraphicsStateGuardian::get_factory().register_factory - (DXGraphicsStateGuardian::get_class_type(), - DXGraphicsStateGuardian::make_DXGraphicsStateGuardian); + wdxGraphicsPipe7::init_type(); + wdxGraphicsWindow7::init_type(); + + GraphicsPipeSelection *selection = GraphicsPipeSelection::get_global_ptr(); + selection->add_pipe_type(wdxGraphicsPipe7::get_class_type(), + wdxGraphicsPipe7::pipe_constructor); } diff --git a/panda/src/dxgsg/config_dxgsg.h b/panda/src/dxgsg7/config_dxgsg7.h similarity index 83% rename from panda/src/dxgsg/config_dxgsg.h rename to panda/src/dxgsg7/config_dxgsg7.h index d56ca0ded0..7b95433449 100644 --- a/panda/src/dxgsg/config_dxgsg.h +++ b/panda/src/dxgsg7/config_dxgsg7.h @@ -1,4 +1,4 @@ -// Filename: config_dxgsg.h +// Filename: config_dxgsg7.h // Created by: drose (06Oct99) // //////////////////////////////////////////////////////////////////// @@ -16,21 +16,20 @@ // //////////////////////////////////////////////////////////////////// -#ifndef CONFIG_DXGSG_H -#define CONFIG_DXGSG_H +#ifndef CONFIG_DXGSG7_H +#define CONFIG_DXGSG7_H #include #include -NotifyCategoryDecl(dxgsg, EXPCL_PANDADX, EXPTP_PANDADX); +NotifyCategoryDecl(dxgsg7, EXPCL_PANDADX, EXPTP_PANDADX); +NotifyCategoryDecl(wdxdisplay7, EXPCL_PANDADX, EXPTP_PANDADX); extern bool dx_full_screen; extern bool dx_sync_video; extern bool dx_cull_traversal; -extern bool dx_show_fps_meter; extern bool dx_no_vertex_fog; extern bool dx_full_screen_antialiasing; -extern float dx_fps_meter_update_interval; extern bool dx_auto_normalize_lighting; extern bool dx_use_rangebased_fog; extern bool dx_allow_software_renderer; @@ -43,6 +42,9 @@ extern bool dx_mipmap_everything; extern bool dx_show_transforms; extern bool dx_force_16bpptextures; extern bool dx_no_dithering; +extern bool dx_force_16bpp_zbuffer; +extern bool dx_do_vidmemsize_check; +extern bool dx_preserve_fpu_state; extern bool dx_depth_offset_decals; @@ -64,6 +66,6 @@ enum DXDecalType { }; extern DXDecalType dx_decal_type; -extern EXPCL_PANDADX void init_libdxgsg(); +extern EXPCL_PANDADX void init_libdxgsg7(); #endif diff --git a/panda/src/dxgsg/dxGeomNodeContext.I b/panda/src/dxgsg7/dxGeomNodeContext7.I similarity index 84% rename from panda/src/dxgsg/dxGeomNodeContext.I rename to panda/src/dxgsg7/dxGeomNodeContext7.I index 8d30be3c3b..45be3ef483 100644 --- a/panda/src/dxgsg/dxGeomNodeContext.I +++ b/panda/src/dxgsg7/dxGeomNodeContext7.I @@ -1,4 +1,4 @@ -// Filename: dxGeomNodeContext.I +// Filename: dxGeomNodeContext7.I // Created by: drose (12Jun01) // //////////////////////////////////////////////////////////////////// @@ -18,12 +18,12 @@ //////////////////////////////////////////////////////////////////// -// Function: dxGeomNodeContext::Constructor +// Function: DXGeomNodeContext7::Constructor // Access: Public // Description: //////////////////////////////////////////////////////////////////// -INLINE DXGeomNodeContext:: -DXGeomNodeContext(GeomNode *node) : GeomNodeContext(node) +INLINE DXGeomNodeContext7:: +DXGeomNodeContext7(GeomNode *node) : GeomNodeContext(node) { _num_verts = 0; _pVB = NULL; diff --git a/panda/src/dxgsg/dxGeomNodeContext.cxx b/panda/src/dxgsg7/dxGeomNodeContext7.cxx similarity index 83% rename from panda/src/dxgsg/dxGeomNodeContext.cxx rename to panda/src/dxgsg7/dxGeomNodeContext7.cxx index fee6d21cb3..fe76ba756c 100644 --- a/panda/src/dxgsg/dxGeomNodeContext.cxx +++ b/panda/src/dxgsg7/dxGeomNodeContext7.cxx @@ -1,4 +1,4 @@ -// Filename: dxGeomNodeContext.cxx +// Filename: dxGeomNodeContext7.cxx // Created by: drose (12Jun01) // //////////////////////////////////////////////////////////////////// @@ -16,11 +16,11 @@ // //////////////////////////////////////////////////////////////////// -#include "dxGeomNodeContext.h" +#include "DXGeomNodeContext7.h" -TypeHandle DXGeomNodeContext::_type_handle; +TypeHandle DXGeomNodeContext7::_type_handle; -DXGeomNodeContext::~DXGeomNodeContext() +DXGeomNodeContext7::~DXGeomNodeContext7() { if(_pXformed_VB!=NULL) _pXformed_VB->Release(); diff --git a/panda/src/dxgsg/dxGeomNodeContext.h b/panda/src/dxgsg7/dxGeomNodeContext7.h similarity index 85% rename from panda/src/dxgsg/dxGeomNodeContext.h rename to panda/src/dxgsg7/dxGeomNodeContext7.h index 0e4d7b9481..108f0b383a 100644 --- a/panda/src/dxgsg/dxGeomNodeContext.h +++ b/panda/src/dxgsg7/dxGeomNodeContext7.h @@ -1,4 +1,4 @@ -// Filename: dxGeomNodeContext.h +// Filename: dxGeomNodeContext7.h // Created by: drose (12Jun01) // //////////////////////////////////////////////////////////////////// @@ -16,10 +16,10 @@ // //////////////////////////////////////////////////////////////////// -#ifndef DXGEOMNODECONTEXT_H -#define DXGEOMNODECONTEXT_H +#ifndef DXGEOMNODECONTEXT7_H +#define DXGEOMNODECONTEXT7_H -#include "dxgsgbase.h" +#include "dxgsg7base.h" #include "geomNodeContext.h" #include "geomNode.h" @@ -31,13 +31,13 @@ typedef struct { } DPInfo; //////////////////////////////////////////////////////////////////// -// Class : DXGeomNodeContext +// Class : DXGeomNodeContext7 // Description : //////////////////////////////////////////////////////////////////// -class EXPCL_PANDADX DXGeomNodeContext : public GeomNodeContext { +class EXPCL_PANDADX DXGeomNodeContext7 : public GeomNodeContext { public: - INLINE DXGeomNodeContext(GeomNode *node); - ~DXGeomNodeContext(); + INLINE DXGeomNodeContext7(GeomNode *node); + ~DXGeomNodeContext7(); // A list of the dynamic Geoms within the GeomNode; these aren't // part of the above display list and must be drawn separately @@ -66,7 +66,7 @@ public: } static void init_type() { GeomNodeContext::init_type(); - register_type(_type_handle, "DXGeomNodeContext", + register_type(_type_handle, "DXGeomNodeContext7", GeomNodeContext::get_class_type()); } virtual TypeHandle get_type() const { @@ -78,7 +78,7 @@ private: static TypeHandle _type_handle; }; -#include "dxGeomNodeContext.I" +#include "dxGeomNodeContext7.I" #endif diff --git a/panda/src/dxgsg/dxGraphicsStateGuardian.I b/panda/src/dxgsg7/dxGraphicsStateGuardian7.I similarity index 68% rename from panda/src/dxgsg/dxGraphicsStateGuardian.I rename to panda/src/dxgsg7/dxGraphicsStateGuardian7.I index d2c81b04af..71100e92ef 100644 --- a/panda/src/dxgsg/dxGraphicsStateGuardian.I +++ b/panda/src/dxgsg7/dxGraphicsStateGuardian7.I @@ -1,4 +1,4 @@ -// Filename: dxGraphicsStateGuardian.I +// Filename: dxGraphicsStateGuardian7.I // Created by: mike (02Feb99) // //////////////////////////////////////////////////////////////////// @@ -16,22 +16,22 @@ // //////////////////////////////////////////////////////////////////// -#include "config_dxgsg.h" +#include "config_dxgsg7.h" #include //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::enable_line_smooth +// Function: DXGraphicsStateGuardian7::enable_line_smooth // Access: // Description: //////////////////////////////////////////////////////////////////// -INLINE void DXGraphicsStateGuardian:: +INLINE void DXGraphicsStateGuardian7:: enable_line_smooth(bool val) { if(_line_smooth_enabled != val) { _line_smooth_enabled = val; #ifdef NDEBUG { if(val && (scrn.D3DDevDesc.dpcTriCaps.dwRasterCaps & D3DPRASTERCAPS_ANTIALIASEDGES)) - dxgsg_cat.error() << "no HW support for line smoothing!!\n"; + dxgsg7_cat.error() << "no HW support for line smoothing!!\n"; } #endif @@ -40,18 +40,18 @@ enable_line_smooth(bool val) { } //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::enable_dither +// Function: DXGraphicsStateGuardian7::enable_dither // Access: // Description: //////////////////////////////////////////////////////////////////// -INLINE void DXGraphicsStateGuardian:: +INLINE void DXGraphicsStateGuardian7:: enable_dither(bool val) { if (_dither_enabled != val) { #ifdef _DEBUG { if(val && !(scrn.D3DDevDesc.dpcTriCaps.dwRasterCaps & D3DPRASTERCAPS_DITHER)) - dxgsg_cat.error() << "no HW support for color dithering!!\n"; + dxgsg7_cat.error() << "no HW support for color dithering!!\n"; return; } #endif @@ -62,11 +62,11 @@ enable_dither(bool val) { } //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::enable_stencil_test +// Function: DXGraphicsStateGuardian7::enable_stencil_test // Access: // Description: //////////////////////////////////////////////////////////////////// -INLINE void DXGraphicsStateGuardian:: +INLINE void DXGraphicsStateGuardian7:: enable_stencil_test(bool val) { if (_stencil_test_enabled != val) { _stencil_test_enabled = val; @@ -75,11 +75,11 @@ enable_stencil_test(bool val) { } //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::enable_color_material +// Function: DXGraphicsStateGuardian7::enable_color_material // Access: // Description: //////////////////////////////////////////////////////////////////// -INLINE void DXGraphicsStateGuardian:: +INLINE void DXGraphicsStateGuardian7:: enable_color_material(bool val) { if (_color_material_enabled != val) { _color_material_enabled = val; @@ -87,11 +87,11 @@ enable_color_material(bool val) { } //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::enable_blend +// Function: DXGraphicsStateGuardian7::enable_blend // Access: // Description: //////////////////////////////////////////////////////////////////// -INLINE void DXGraphicsStateGuardian:: +INLINE void DXGraphicsStateGuardian7:: enable_blend(bool val) { if (_blend_enabled != val) { _blend_enabled = val; @@ -100,11 +100,11 @@ enable_blend(bool val) { } //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::enable_blend +// Function: DXGraphicsStateGuardian7::enable_blend // Access: // Description: //////////////////////////////////////////////////////////////////// -INLINE void DXGraphicsStateGuardian:: +INLINE void DXGraphicsStateGuardian7:: set_shademode(D3DSHADEMODE val) { if (_CurShadeMode != val) { _CurShadeMode = val; @@ -112,7 +112,7 @@ set_shademode(D3DSHADEMODE val) { } } -INLINE void DXGraphicsStateGuardian:: +INLINE void DXGraphicsStateGuardian7:: enable_primitive_clipping(bool val) { if (_clipping_enabled != val) { _clipping_enabled = val; @@ -121,11 +121,11 @@ enable_primitive_clipping(bool val) { } //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::enable_fog +// Function: DXGraphicsStateGuardian7::enable_fog // Access: // Description: //////////////////////////////////////////////////////////////////// -INLINE void DXGraphicsStateGuardian:: +INLINE void DXGraphicsStateGuardian7:: enable_fog(bool val) { if ((_fog_enabled != val) && (_doFogType!=None)) { _fog_enabled = val; @@ -134,11 +134,11 @@ enable_fog(bool val) { } //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::enable_alpha_test +// Function: DXGraphicsStateGuardian7::enable_alpha_test // Access: // Description: //////////////////////////////////////////////////////////////////// -INLINE void DXGraphicsStateGuardian:: +INLINE void DXGraphicsStateGuardian7:: enable_alpha_test(bool val ) { if (_alpha_test_enabled != val) { @@ -148,17 +148,17 @@ enable_alpha_test(bool val ) } //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::call_dxLightModelAmbient +// Function: DXGraphicsStateGuardian7::call_dxLightModelAmbient // Access: // Description: //////////////////////////////////////////////////////////////////// -INLINE void DXGraphicsStateGuardian:: +INLINE void DXGraphicsStateGuardian7:: call_dxLightModelAmbient( const Colorf& color) { if (_lmodel_ambient != color) { _lmodel_ambient = color; #ifdef GSG_VERBOSE - dxgsg_cat.debug() << "dxLightModel(LIGHT_MODEL_AMBIENT, " << color << ")" << endl; + dxgsg7_cat.debug() << "dxLightModel(LIGHT_MODEL_AMBIENT, " << color << ")" << endl; #endif scrn.pD3DDevice->SetRenderState( D3DRENDERSTATE_AMBIENT, D3DRGBA(color[0], color[1], color[2], color[3])); @@ -166,43 +166,47 @@ call_dxLightModelAmbient( const Colorf& color) } //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::call_dxAlphaFunc +// Function: DXGraphicsStateGuardian7::call_dxAlphaFunc // Access: // Description: //////////////////////////////////////////////////////////////////// -INLINE void DXGraphicsStateGuardian:: +INLINE void DXGraphicsStateGuardian7:: call_dxAlphaFunc(D3DCMPFUNC func, float reference_alpha) { if (_alpha_func != func) { _alpha_func = func; #ifdef GSG_VERBOSE - dxgsg_cat.debug() << "dxAlphaFunc("; + dxgsg7_cat.debug() << "dxAlphaFunc("; switch (func) { case D3DCMP_NEVER: - dxgsg_cat.debug(false) << "D3DCMP_NEVER"; + dxgsg7_cat.debug(false) << "D3DCMP_NEVER"; break; case D3DCMP_LESS: - dxgsg_cat.debug(false) << "D3DCMP_LESS"; + dxgsg7_cat.debug(false) << "D3DCMP_LESS"; break; case D3DCMP_EQUAL: - dxgsg_cat.debug(false) << "D3DCMP_EQUAL"; + dxgsg7_cat.debug(false) << "D3DCMP_EQUAL"; break; +#ifdef D3DCMP_LEQUAL case D3DCMP_LEQUAL: - dxgsg_cat.debug(false) << "D3DCMP_LEQUAL"; + dxgsg7_cat.debug(false) << "D3DCMP_LEQUAL"; break; +#endif case D3DCMP_GREATER: - dxgsg_cat.debug(false) << "D3DCMP_GREATER"; + dxgsg7_cat.debug(false) << "D3DCMP_GREATER"; break; case D3DCMP_NOTEQUAL: - dxgsg_cat.debug(false) << "D3DCMP_NOTEQUAL"; + dxgsg7_cat.debug(false) << "D3DCMP_NOTEQUAL"; break; +#ifdef D3DCMP_GEQUAL case D3DCMP_GEQUAL: - dxgsg_cat.debug(false) << "D3DCMP_GEQUAL"; + dxgsg7_cat.debug(false) << "D3DCMP_GEQUAL"; break; +#endif case D3DCMP_ALWAYS: - dxgsg_cat.debug(false) << "D3DCMP_ALWAYS"; + dxgsg7_cat.debug(false) << "D3DCMP_ALWAYS"; break; } - dxgsg_cat.debug() << " , " << reference_alpha << ")" << endl; + dxgsg7_cat.debug() << " , " << reference_alpha << ")" << endl; #endif scrn.pD3DDevice->SetRenderState(D3DRENDERSTATE_ALPHAFUNC, func); } @@ -213,7 +217,7 @@ call_dxAlphaFunc(D3DCMPFUNC func, float reference_alpha) { } } -INLINE void DXGraphicsStateGuardian:: +INLINE void DXGraphicsStateGuardian7:: call_dxBlendFunc(D3DBLEND sfunc, D3DBLEND dfunc ) { if (_blend_source_func != sfunc) @@ -221,41 +225,41 @@ call_dxBlendFunc(D3DBLEND sfunc, D3DBLEND dfunc ) _blend_source_func = sfunc; scrn.pD3DDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, sfunc); #ifdef GSG_VERBOSE - dxgsg_cat.debug() << "dxSrcBlendFunc("; + dxgsg7_cat.debug() << "dxSrcBlendFunc("; switch (sfunc) { case D3DBLEND_ZERO: - dxgsg_cat.debug(false) << "ZERO, "; + dxgsg7_cat.debug(false) << "ZERO, "; break; case D3DBLEND_ONE: - dxgsg_cat.debug(false) << "ONE, "; + dxgsg7_cat.debug(false) << "ONE, "; break; case D3DBLEND_DESTCOLOR: - dxgsg_cat.debug(false) << "DESTCOLOR, "; + dxgsg7_cat.debug(false) << "DESTCOLOR, "; break; case D3DBLEND_INVDESTCOLOR: - dxgsg_cat.debug(false) << "INVDESTCOLOR, "; + dxgsg7_cat.debug(false) << "INVDESTCOLOR, "; break; case D3DBLEND_SRCALPHA: - dxgsg_cat.debug(false) << "SRCALPHA, "; + dxgsg7_cat.debug(false) << "SRCALPHA, "; break; case D3DBLEND_INVSRCALPHA: - dxgsg_cat.debug(false) << "INVSRCALPHA, "; + dxgsg7_cat.debug(false) << "INVSRCALPHA, "; break; case D3DBLEND_DESTALPHA: - dxgsg_cat.debug(false) << "DESTALPHA, "; + dxgsg7_cat.debug(false) << "DESTALPHA, "; break; case D3DBLEND_INVDESTALPHA: - dxgsg_cat.debug(false) << "INVDESTALPHA, "; + dxgsg7_cat.debug(false) << "INVDESTALPHA, "; break; case D3DBLEND_SRCALPHASAT: - dxgsg_cat.debug(false) << "SRCALPHASAT, "; + dxgsg7_cat.debug(false) << "SRCALPHASAT, "; break; default: - dxgsg_cat.debug(false) << "unknown, "; + dxgsg7_cat.debug(false) << "unknown, "; break; } - dxgsg_cat.debug(false) << endl; + dxgsg7_cat.debug(false) << endl; #endif } if ( _blend_dest_func != dfunc) @@ -263,43 +267,43 @@ call_dxBlendFunc(D3DBLEND sfunc, D3DBLEND dfunc ) _blend_dest_func = dfunc; scrn.pD3DDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, dfunc); #ifdef GSG_VERBOSE - dxgsg_cat.debug() << "dxDstBlendFunc("; + dxgsg7_cat.debug() << "dxDstBlendFunc("; switch (dfunc) { case D3DBLEND_ZERO: - dxgsg_cat.debug(false) << "ZERO, "; + dxgsg7_cat.debug(false) << "ZERO, "; break; case D3DBLEND_ONE: - dxgsg_cat.debug(false) << "ONE, "; + dxgsg7_cat.debug(false) << "ONE, "; break; case D3DBLEND_DESTCOLOR: - dxgsg_cat.debug(false) << "DESTCOLOR, "; + dxgsg7_cat.debug(false) << "DESTCOLOR, "; break; case D3DBLEND_INVDESTCOLOR: - dxgsg_cat.debug(false) << "INVDESTCOLOR, "; + dxgsg7_cat.debug(false) << "INVDESTCOLOR, "; break; case D3DBLEND_SRCALPHA: - dxgsg_cat.debug(false) << "SRCALPHA, "; + dxgsg7_cat.debug(false) << "SRCALPHA, "; break; case D3DBLEND_INVSRCALPHA: - dxgsg_cat.debug(false) << "INVSRCALPHA, "; + dxgsg7_cat.debug(false) << "INVSRCALPHA, "; break; case D3DBLEND_DESTALPHA: - dxgsg_cat.debug(false) << "DESTALPHA, "; + dxgsg7_cat.debug(false) << "DESTALPHA, "; break; case D3DBLEND_INVDESTALPHA: - dxgsg_cat.debug(false) << "INVDESTALPHA, "; + dxgsg7_cat.debug(false) << "INVDESTALPHA, "; break; case D3DBLEND_SRCALPHASAT: - dxgsg_cat.debug(false) << "SRCALPHASAT, "; + dxgsg7_cat.debug(false) << "SRCALPHASAT, "; break; } - dxgsg_cat.debug(false) << endl; + dxgsg7_cat.debug(false) << endl; #endif } } -INLINE void DXGraphicsStateGuardian:: +INLINE void DXGraphicsStateGuardian7:: enable_zwritemask(bool val) { if (_depth_write_enabled != val) { _depth_write_enabled = val; @@ -310,24 +314,24 @@ enable_zwritemask(bool val) { /** unimplemented //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::enable_multisample +// Function: DXGraphicsStateGuardian7::enable_multisample // Access: // Description: //////////////////////////////////////////////////////////////////// -INLINE void DXGraphicsStateGuardian:: +INLINE void DXGraphicsStateGuardian7:: enable_multisample(bool val) { _multisample_enabled = val; #ifdef NDEBUG - dxgsg_cat.error() << "dx multisample unimplemented!!\n"; + dxgsg7_cat.error() << "dx multisample unimplemented!!\n"; #endif } //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::enable_multisample_alpha_one +// Function: DXGraphicsStateGuardian7::enable_multisample_alpha_one // Access: // Description: //////////////////////////////////////////////////////////////////// -INLINE void DXGraphicsStateGuardian:: +INLINE void DXGraphicsStateGuardian7:: enable_multisample_alpha_one(bool val) { if (_multisample_alpha_one_enabled != val) { _multisample_alpha_one_enabled = val; @@ -335,11 +339,11 @@ enable_multisample_alpha_one(bool val) { } //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::enable_multisample_alpha_mask +// Function: DXGraphicsStateGuardian7::enable_multisample_alpha_mask // Access: // Description: //////////////////////////////////////////////////////////////////// -INLINE void DXGraphicsStateGuardian:: +INLINE void DXGraphicsStateGuardian7:: enable_multisample_alpha_mask(bool val) { if (_multisample_alpha_mask_enabled != val) { _multisample_alpha_mask_enabled = val; @@ -347,16 +351,16 @@ enable_multisample_alpha_mask(bool val) { } //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::enable_point_smooth +// Function: DXGraphicsStateGuardian7::enable_point_smooth // Access: // Description: //////////////////////////////////////////////////////////////////// -INLINE void DXGraphicsStateGuardian:: +INLINE void DXGraphicsStateGuardian7:: enable_point_smooth(bool val) { // _point_smooth_enabled = val; #ifdef NDEBUG - dxgsg_cat.error() << "dx point smoothing unimplemented!!\n"; + dxgsg7_cat.error() << "dx point smoothing unimplemented!!\n"; #endif } */ diff --git a/panda/src/dxgsg/dxGraphicsStateGuardian.cxx b/panda/src/dxgsg7/dxGraphicsStateGuardian7.cxx similarity index 81% rename from panda/src/dxgsg/dxGraphicsStateGuardian.cxx rename to panda/src/dxgsg7/dxGraphicsStateGuardian7.cxx index 1df2e7407f..5887243583 100644 --- a/panda/src/dxgsg/dxGraphicsStateGuardian.cxx +++ b/panda/src/dxgsg7/dxGraphicsStateGuardian7.cxx @@ -1,4 +1,4 @@ -// Filename: dxGraphicsStateGuardian.cxx +// Filename: dxGraphicsStateGuardian7.cxx // Created by: mike (02Feb99) // //////////////////////////////////////////////////////////////////// @@ -16,8 +16,8 @@ // //////////////////////////////////////////////////////////////////// -#include "dxGraphicsStateGuardian.h" -#include "config_dxgsg.h" +#include "dxGraphicsStateGuardian7.h" +#include "config_dxgsg7.h" #include "displayRegion.h" #include "renderBuffer.h" @@ -58,7 +58,6 @@ //#define COUNT_DRAWPRIMS //#define PRINT_TEXSTATS -// #define MAKE_FPSMETER_TRANSPARENT //#define DISABLE_DECALING #define DISABLE_POLYGON_OFFSET_DECALING @@ -81,7 +80,7 @@ const int VERT_BUFFER_SIZE = (32*6*1024L); // note multiple region code doesnt work now (see prepare_display_region,set_clipper) #define NO_MULTIPLE_DISPLAY_REGIONS -TypeHandle DXGraphicsStateGuardian::_type_handle; +TypeHandle DXGraphicsStateGuardian7::_type_handle; // bit masks used for drawing primitives // bitmask type: normal=0x1,color=0x2,texcoord=0x4 @@ -174,178 +173,70 @@ Colorf_to_D3DCOLOR(const Colorf &cColorf) { pop ebx } - // dxgsg_cat.debug() << (void*)d3dcolor << endl; + // dxgsg7_cat.debug() << (void*)d3dcolor << endl; return d3dcolor; #else //!_X86_ return MY_D3DRGBA(cColorf[0], cColorf[1], cColorf[2], cColorf[3]); #endif //!_X86_ } +#ifdef _DEBUG +void +dbgPrintVidMem(LPDIRECTDRAW7 pDD, LPDDSCAPS2 lpddsCaps,const char *pMsg) { + DWORD dwTotal,dwFree; + HRESULT hr; -void DXGraphicsStateGuardian:: + // These Caps bits arent allowed to be specified when calling GetAvailVidMem. + // They don't affect surface allocation in a vram heap. + +#define AVAILVIDMEM_BADCAPS (DDSCAPS_BACKBUFFER | \ + DDSCAPS_FRONTBUFFER | \ + DDSCAPS_COMPLEX | \ + DDSCAPS_FLIP | \ + DDSCAPS_OWNDC | \ + DDSCAPS_PALETTE | \ + DDSCAPS_SYSTEMMEMORY | \ + DDSCAPS_VISIBLE | \ + DDSCAPS_WRITEONLY) + + DDSCAPS2 ddsCaps = *lpddsCaps; + ddsCaps.dwCaps &= ~(AVAILVIDMEM_BADCAPS); // turn off the bad caps + // ddsCaps.dwCaps |= DDSCAPS_VIDEOMEMORY; done internally by DX anyway + + if(FAILED( hr = pDD->GetAvailableVidMem(&ddsCaps,&dwTotal,&dwFree))) { + wdxdisplay_cat.debug() << "GetAvailableVidMem failed : result = " << ConvD3DErrorToString(hr) << endl; + exit(1); + } + + // Write a debug message to the console reporting the texture memory. + char tmpstr[100],tmpstr2[100]; + sprintf(tmpstr,"%.4g",dwTotal/1000000.0); + sprintf(tmpstr2,"%.4g",dwFree/1000000.0); + if(wdxdisplay_cat.is_debug()) + wdxdisplay_cat.debug() << "AvailableVidMem before creating "<< pMsg << ",(megs) total: " << tmpstr << " free:" << tmpstr2 <GetSurfaceDesc(&ddsd); - - // init it to transparent black - if(FAILED( hr = _fpsmeter_font_surf->Lock( NULL, &ddsd, DDLOCK_NOSYSLOCK | DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT, NULL ))) { - dxgsg_cat.error() << "fps meter creation failed, Lock() failed on texture! hr = " << ConvD3DErrorToString(hr) << "\n"; - _bShowFPSMeter = false; - return; - } - ZeroMemory(ddsd.lpSurface,ddsd.dwWidth*ddsd.dwHeight*2); - _fpsmeter_font_surf->Unlock(NULL); - - // draw FPS text using GDI - HDC hDC; - if(FAILED( hr = _fpsmeter_font_surf->GetDC(&hDC))) { - dxgsg_cat.error() << "fps meter creation failed, GetDC failed on fps font surface! hr = " << ConvD3DErrorToString(hr) << "\n"; - _bShowFPSMeter = false; - return; - } - - HFONT hfnt = (HFONT) GetStockObject(ANSI_FIXED_FONT); - (void) SelectObject(hDC, hfnt); - - SetTextColor(hDC, RGB(255,255,128) ); - SetBkMode(hDC, TRANSPARENT ); - - char tstr[2] = {'\0','\0'}; - RECT Rect; - Rect.top = 0; Rect.bottom = FPSMETER_LETTER_HEIGHT-1; - Rect.left = 0; Rect.right = FPSMETER_LETTER_WIDTH; - - for(int i=0;iReleaseDC(hDC); - - // GDI writes 0x00 for alpha, have to make letter pixels opaque again - if(FAILED( hr = _fpsmeter_font_surf->Lock( NULL, &ddsd, DDLOCK_NOSYSLOCK | DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT, NULL ))) { - dxgsg_cat.error() << "fps meter creation failed, Lock() failed on texture! hr = " << ConvD3DErrorToString(hr) << "\n"; - _bShowFPSMeter = false; - return; - } - - DWORD numpixels=ddsd.dwWidth*ddsd.dwHeight; - - #ifdef MAKE_FPSMETER_TRANSPARENT - WORD *pPixel=(WORD*)ddsd.lpSurface; - for(int ii=numpixels;ii>0;ii--) { - WORD wPixel=*pPixel; - if(wPixel & 0x0FFF) { - *pPixel |= 0xF000; // make written pixels opaque - }/* else { - *pPixel = 0x700F; // otherwise background is translucent blue - }*/ - pPixel++; - } - #endif - _fpsmeter_font_surf->Unlock(NULL); -} - //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::Constructor +// Function: DXGraphicsStateGuardian7::Constructor // Access: Public // Description: //////////////////////////////////////////////////////////////////// -DXGraphicsStateGuardian:: -DXGraphicsStateGuardian(GraphicsWindow *win) : GraphicsStateGuardian(win) { +DXGraphicsStateGuardian7:: +DXGraphicsStateGuardian7(GraphicsWindow *win) : GraphicsStateGuardian(win) { // allocate local buffers used during rendering GraphicsStateGuardian::reset(); ZeroMemory(&scrn,sizeof(DXScreenData)); - _bShowFPSMeter = false; _pCurFvfBufPtr = NULL; _pFvfBufBasePtr = new BYTE[VERT_BUFFER_SIZE]; // allocate storage for vertex info. _index_buf = new WORD[D3DMAXNUMVERTICES]; // allocate storage for vertex index info. - _fpsmeter_verts=NULL; - _fpsmeter_font_surf=NULL; _dx_ready = false; _overlay_windows_supported = false; @@ -378,12 +269,12 @@ DXGraphicsStateGuardian(GraphicsWindow *win) : GraphicsStateGuardian(win) { } //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::Destructor +// Function: DXGraphicsStateGuardian7::Destructor // Access: Public // Description: //////////////////////////////////////////////////////////////////// -DXGraphicsStateGuardian:: -~DXGraphicsStateGuardian() { +DXGraphicsStateGuardian7:: +~DXGraphicsStateGuardian7() { if (scrn.pD3DDevice != NULL) scrn.pD3DDevice->SetTexture(0, NULL); // this frees reference to the old texture _pCurTexContext = NULL; @@ -394,21 +285,21 @@ DXGraphicsStateGuardian:: } //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::reset +// Function: DXGraphicsStateGuardian7::reset // Access: Public, Virtual // Description: Resets all internal state as if the gsg were newly // created. //////////////////////////////////////////////////////////////////// -void DXGraphicsStateGuardian:: +void DXGraphicsStateGuardian7:: reset(void) { GraphicsStateGuardian::reset(); - dxgsg_cat.error() << "DXGSG reset() not implemented properly yet!\n"; + dxgsg7_cat.error() << "DXGSG reset() not implemented properly yet!\n"; // delete all the objs too, right? //dx_init(); } // recreate dx objects without modifying gsg state, other than clearing state cache -void DXGraphicsStateGuardian:: +void DXGraphicsStateGuardian7:: free_dxgsg_objects(void) { ULONG refcnt; @@ -424,15 +315,15 @@ free_dxgsg_objects(void) { if (scrn.pD3DDevice!=NULL) { scrn.pD3DDevice->SetTexture(0,NULL); // should release this stuff internally anyway - RELEASE(scrn.pD3DDevice,dxgsg,"d3dDevice",RELEASE_DOWN_TO_ZERO); + RELEASE(scrn.pD3DDevice,dxgsg7,"d3dDevice",RELEASE_DOWN_TO_ZERO); } DeleteAllVideoSurfaces(); // Release the DDraw and D3D objects used by the app - RELEASE(scrn.pddsZBuf,dxgsg,"zbuffer",false); - RELEASE(scrn.pddsBack,dxgsg,"backbuffer",false); - RELEASE(scrn.pddsPrimary,dxgsg,"primary surface",false); + RELEASE(scrn.pddsZBuf,dxgsg7,"zbuffer",false); + RELEASE(scrn.pddsBack,dxgsg7,"backbuffer",false); + RELEASE(scrn.pddsPrimary,dxgsg7,"primary surface",false); } HRESULT CALLBACK EnumTexFmtsCallback( LPDDPIXELFORMAT pddpf, VOID* param ) { @@ -441,7 +332,7 @@ HRESULT CALLBACK EnumTexFmtsCallback( LPDDPIXELFORMAT pddpf, VOID* param ) { DDPixelFormatVec *pPixFmtVec = (DDPixelFormatVec *) param; pPixFmtVec->push_back(*pddpf); #else - DXGraphicsStateGuardian *mystate = (DXGraphicsStateGuardian *) param; + DXGraphicsStateGuardian7 *mystate = (DXGraphicsStateGuardian7 *) param; assert(mystate->_cNumTexPixFmts < MAX_DX_TEXPIXFMTS); memcpy( &(mystate->_pTexPixFmts[mystate->_cNumTexPixFmts]), pddpf, sizeof(DDPIXELFORMAT) ); mystate->_cNumTexPixFmts++; @@ -450,12 +341,12 @@ HRESULT CALLBACK EnumTexFmtsCallback( LPDDPIXELFORMAT pddpf, VOID* param ) { } //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::reset +// Function: DXGraphicsStateGuardian7::reset // Access: Public, Virtual // Description: Handles initialization which assumes that DX has already been // set up. //////////////////////////////////////////////////////////////////// -void DXGraphicsStateGuardian:: +void DXGraphicsStateGuardian7:: dx_init( void) { /* LPDIRECTDRAW7 context, @@ -538,7 +429,7 @@ dx_init( void) { // _line_width = 1.0f; // _point_size = 1.0f; - assert(scrn.pddsBack!=NULL); // dxgsg is always double-buffered right now + assert(scrn.pddsBack!=NULL); // dxgsg7 is always double-buffered right now #ifdef COUNT_DRAWPRIMS global_pD3DDevice = pDevice; @@ -565,16 +456,16 @@ dx_init( void) { if(FAILED(hr=scrn.pD3DDevice->EnumTextureFormats(EnumTexFmtsCallback, this))) { #endif if(hr==D3DERR_TEXTURE_NO_SUPPORT) { - dxgsg_cat.error() << "EnumTextureFormats indicates No Texturing Support on this HW!, exiting...\n"; + dxgsg7_cat.error() << "EnumTextureFormats indicates No Texturing Support on this HW!, exiting...\n"; exit(1); } else { - dxgsg_cat.error() << "EnumTextureFormats failed! hr = " << ConvD3DErrorToString(hr) << endl; + dxgsg7_cat.error() << "EnumTextureFormats failed! hr = " << ConvD3DErrorToString(hr) << endl; } } DX_DECLARE_CLEAN(DDCAPS,ddCaps); if (FAILED(hr = scrn.pDD->GetCaps(&ddCaps,NULL))) { - dxgsg_cat.fatal() << "GetCaps failed on DDraw! hr = " << ConvD3DErrorToString(hr) << "\n"; + dxgsg7_cat.fatal() << "GetCaps failed on DDraw! hr = " << ConvD3DErrorToString(hr) << "\n"; exit(1); } @@ -592,9 +483,9 @@ dx_init( void) { #ifdef _DEBUG // dx7 doesnt support PLANEMASK renderstate #if(DIRECT3D_VERSION < 0x700) - dxgsg_cat.debug() << "dx-decal-type 'offset' not supported by hardware, switching to decal masking\n"; + dxgsg7_cat.debug() << "dx-decal-type 'offset' not supported by hardware, switching to decal masking\n"; #else - dxgsg_cat.debug() << "dx-decal-type 'offset' not supported by hardware, switching to decal double-draw blend-based masking\n"; + dxgsg7_cat.debug() << "dx-decal-type 'offset' not supported by hardware, switching to decal double-draw blend-based masking\n"; #endif #endif #if(DIRECT3D_VERSION < 0x700) @@ -606,7 +497,7 @@ dx_init( void) { #ifdef DISABLE_POLYGON_OFFSET_DECALING #ifdef _DEBUG - dxgsg_cat.spam() << "polygon-offset decaling disabled in dxgsg, switching to double-draw decaling\n"; + dxgsg7_cat.spam() << "polygon-offset decaling disabled in dxgsg7, switching to double-draw decaling\n"; #endif #if(DIRECT3D_VERSION < 0x700) @@ -618,13 +509,13 @@ dx_init( void) { if ((dx_decal_type==GDT_mask) && !(scrn.D3DDevDesc.dpcTriCaps.dwMiscCaps & D3DPMISCCAPS_MASKPLANES)) { #ifdef _DEBUG - dxgsg_cat.debug() << "No hardware support for colorwrite disabling, switching to dx-decal-type 'mask' to 'blend'\n"; + dxgsg7_cat.debug() << "No hardware support for colorwrite disabling, switching to dx-decal-type 'mask' to 'blend'\n"; #endif dx_decal_type = GDT_blend; } if (((dx_decal_type==GDT_blend)||(dx_decal_type==GDT_mask)) && !(scrn.D3DDevDesc.dpcTriCaps.dwMiscCaps & D3DPMISCCAPS_MASKZ)) { - dxgsg_cat.error() << "dx-decal-type mask impossible to implement, no hardware support for Z-masking, decals will not appear correctly!\n"; + dxgsg7_cat.error() << "dx-decal-type mask impossible to implement, no hardware support for Z-masking, decals will not appear correctly!\n"; } //#define REQUIRED_BLENDCAPS (D3DPBLENDCAPS_ZERO|D3DPBLENDCAPS_ONE|D3DPBLENDCAPS_SRCCOLOR|D3DPBLENDCAPS_INVSRCCOLOR| \ @@ -636,30 +527,30 @@ dx_init( void) { if (((scrn.D3DDevDesc.dpcTriCaps.dwSrcBlendCaps & REQUIRED_BLENDCAPS)!=REQUIRED_BLENDCAPS) || ((scrn.D3DDevDesc.dpcTriCaps.dwDestBlendCaps & REQUIRED_BLENDCAPS)!=REQUIRED_BLENDCAPS)) { - dxgsg_cat.error() << "device is missing alpha blending capabilities, blending may not work correctly: SrcBlendCaps: 0x"<< (void*) scrn.D3DDevDesc.dpcTriCaps.dwSrcBlendCaps << " DestBlendCaps: "<< (void*) scrn.D3DDevDesc.dpcTriCaps.dwDestBlendCaps << endl; + dxgsg7_cat.error() << "device is missing alpha blending capabilities, blending may not work correctly: SrcBlendCaps: 0x"<< (void*) scrn.D3DDevDesc.dpcTriCaps.dwSrcBlendCaps << " DestBlendCaps: "<< (void*) scrn.D3DDevDesc.dpcTriCaps.dwDestBlendCaps << endl; } if (!(scrn.D3DDevDesc.dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_TRANSPARENCY)) { - dxgsg_cat.error() << "device is missing texture transparency capability, transparency may not work correctly! TextureCaps: 0x"<< (void*) scrn.D3DDevDesc.dpcTriCaps.dwTextureCaps << endl; + dxgsg7_cat.error() << "device is missing texture transparency capability, transparency may not work correctly! TextureCaps: 0x"<< (void*) scrn.D3DDevDesc.dpcTriCaps.dwTextureCaps << endl; } // just require trilinear. if it can do that, it can probably do all the lesser point-sampling variations too #define REQUIRED_TEXFILTERCAPS (D3DPTFILTERCAPS_MAGFLINEAR | D3DPTFILTERCAPS_MINFLINEAR | D3DPTFILTERCAPS_LINEAR) if ((scrn.D3DDevDesc.dpcTriCaps.dwTextureFilterCaps & REQUIRED_TEXFILTERCAPS)!=REQUIRED_TEXFILTERCAPS) { - dxgsg_cat.error() << "device is missing texture bilinear filtering capability, textures may appear blocky! TextureFilterCaps: 0x"<< (void*) scrn.D3DDevDesc.dpcTriCaps.dwTextureFilterCaps << endl; + dxgsg7_cat.error() << "device is missing texture bilinear filtering capability, textures may appear blocky! TextureFilterCaps: 0x"<< (void*) scrn.D3DDevDesc.dpcTriCaps.dwTextureFilterCaps << endl; } #define REQUIRED_MIPMAP_TEXFILTERCAPS (D3DPTFILTERCAPS_MIPFLINEAR | D3DPTFILTERCAPS_LINEARMIPLINEAR) if (!(ddCaps.ddsCaps.dwCaps & DDSCAPS_MIPMAP)) { - dxgsg_cat.debug() << "device does not have mipmap texturing filtering capability! TextureFilterCaps: 0x"<< (void*) scrn.D3DDevDesc.dpcTriCaps.dwTextureFilterCaps << endl; + dxgsg7_cat.debug() << "device does not have mipmap texturing filtering capability! TextureFilterCaps: 0x"<< (void*) scrn.D3DDevDesc.dpcTriCaps.dwTextureFilterCaps << endl; dx_ignore_mipmaps = TRUE; } else if ((scrn.D3DDevDesc.dpcTriCaps.dwTextureFilterCaps & REQUIRED_MIPMAP_TEXFILTERCAPS)!=REQUIRED_MIPMAP_TEXFILTERCAPS) { - dxgsg_cat.debug() << "device is missing tri-linear mipmap filtering capability, texture mipmaps may not supported! TextureFilterCaps: 0x"<< (void*) scrn.D3DDevDesc.dpcTriCaps.dwTextureFilterCaps << endl; + dxgsg7_cat.debug() << "device is missing tri-linear mipmap filtering capability, texture mipmaps may not supported! TextureFilterCaps: 0x"<< (void*) scrn.D3DDevDesc.dpcTriCaps.dwTextureFilterCaps << endl; } #define REQUIRED_TEXBLENDCAPS (D3DTEXOPCAPS_MODULATE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_SELECTARG2) if ((scrn.D3DDevDesc.dwTextureOpCaps & REQUIRED_TEXBLENDCAPS)!=REQUIRED_TEXBLENDCAPS) { - dxgsg_cat.error() << "device is missing some required texture blending capabilities, texture blending may not work properly! TextureOpCaps: 0x"<< (void*) scrn.D3DDevDesc.dwTextureOpCaps << endl; + dxgsg7_cat.error() << "device is missing some required texture blending capabilities, texture blending may not work properly! TextureOpCaps: 0x"<< (void*) scrn.D3DDevDesc.dwTextureOpCaps << endl; } if(scrn.D3DDevDesc.dpcTriCaps.dwRasterCaps & D3DPRASTERCAPS_FOGTABLE) { @@ -734,7 +625,7 @@ dx_init( void) { _CurTexAnisoDegree=1; // this code must match apply_texture() code for states above - // so DX TSS renderstate matches dxgsg state + // so DX TSS renderstate matches dxgsg7 state scrn.pD3DDevice->SetTextureStageState(0, D3DTSS_MAGFILTER, D3DTFG_POINT); scrn.pD3DDevice->SetTextureStageState(0, D3DTSS_MINFILTER, D3DTFP_POINT); @@ -750,14 +641,14 @@ dx_init( void) { } #endif - if(dx_full_screen_antialiasing) { + if (dx_full_screen_antialiasing) { if(scrn.D3DDevDesc.dpcTriCaps.dwRasterCaps & D3DPRASTERCAPS_ANTIALIASSORTINDEPENDENT) { scrn.pD3DDevice->SetRenderState(D3DRENDERSTATE_ANTIALIAS,D3DANTIALIAS_SORTINDEPENDENT); - if(dxgsg_cat.is_debug()) - dxgsg_cat.debug() << "enabling full-screen anti-aliasing\n"; + if(dxgsg7_cat.is_debug()) + dxgsg7_cat.debug() << "enabling full-screen anti-aliasing\n"; } else { - if(dxgsg_cat.is_debug()) - dxgsg_cat.debug() << "device doesnt support full-screen anti-aliasing\n"; + if(dxgsg7_cat.is_debug()) + dxgsg7_cat.debug() << "device doesnt support full-screen anti-aliasing\n"; } } @@ -768,8 +659,8 @@ dx_init( void) { scrn.pD3DDevice->SetRenderState(D3DRENDERSTATE_CULLMODE, dx_force_backface_culling); } else { dx_force_backface_culling=0; - if(dxgsg_cat.is_debug()) - dxgsg_cat.debug() << "error, invalid value for dx-force-backface-culling\n"; + if(dxgsg7_cat.is_debug()) + dxgsg7_cat.debug() << "error, invalid value for dx-force-backface-culling\n"; } } scrn.pD3DDevice->SetRenderState(D3DRENDERSTATE_CULLMODE, dx_force_backface_culling); @@ -784,129 +675,6 @@ dx_init( void) { _alpha_test_enabled = false; scrn.pD3DDevice->SetRenderState(D3DRENDERSTATE_ALPHATESTENABLE, _alpha_test_enabled); - // need to release this better, so dx_init can be called multiple times - - if(_bShowFPSMeter) { - _start_time = timeGetTime(); - _current_fps = 0.0f; - _start_frame_count = _cur_frame_count = 0; - - // create the fpsmeter font texture - DX_DECLARE_CLEAN(DDSURFACEDESC2, ddsd); - ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT ; - ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE; - - if(!scrn.bIsSWRast) - ddsd.ddsCaps.dwCaps2 = DDSCAPS2_TEXTUREMANAGE | DDSCAPS2_HINTSTATIC; - else { - ddsd.ddsCaps.dwCaps |= DDSCAPS_SYSTEMMEMORY; - } - - ddsd.dwTextureStage=0; - ddsd.dwFlags |= DDSD_TEXTURESTAGE; - ddsd.dwMipMapCount = 1; - - // note GDI cant draw to 4-4-4-4 fmt DDSURF on win9x (GetDC will fail) - - DDPIXELFORMAT *pCurPixFmt; - - int i; -#ifdef USE_TEXFMTVEC - for(i=0,pCurPixFmt=&scrn.TexPixFmts[scrn.TexPixFmts.size()-1];idwRGBBitCount==16) && - #ifdef MAKE_FPSMETER_TRANSPARENT - (pCurPixFmt->dwFlags & DDPF_ALPHAPIXELS) && - (pCurPixFmt->dwRGBAlphaBitMask==0x8000) - #else - ((pCurPixFmt->dwFlags & DDPF_ALPHAPIXELS)==0) && - (pCurPixFmt->dwBBitMask==0x001F) - #endif - ) // emacs gets confused if we don't match parens accurately. - break; - } - -#ifdef USE_TEXFMTVEC - if(i>=scrn.TexPixFmts.size()) -#else - if(i>=_cNumTexPixFmts) -#endif - { - // if this fails, no 4-4-4-4 fmt, need code to use 5-5-5-1 - dxgsg_cat.error() << "couldnt find 4-4-4-4 tex fmt for fpsmeter font!\n"; - _bShowFPSMeter = false; - return; - } - - memcpy(&ddsd.ddpfPixelFormat,pCurPixFmt,sizeof(DDPIXELFORMAT)); - - DWORD fontareaHeight = FPSMETER_LETTER_HEIGHT; - DWORD fontareaWidth = FPSMETER_LETTER_WIDTH * (FPSMETER_NUMFONTLETTERS + FPSMETER_SUFFIXLEN); - - // this is just the area used for the letters, not the suffix - DWORD letterfontareaWidth = FPSMETER_LETTER_WIDTH * FPSMETER_NUMFONTLETTERS; - - DWORD texdim_x = fontareaWidth; - DWORD texdim_y = fontareaHeight; - - #define ROUND_UP_TO_POW2(val) if(!ISPOW2(val)) { \ - for(int i=31;i>=0;i--) { \ - if(((1< texdim_x) - texdim_x = texdim_y; - texdim_y = texdim_x; - } - - ddsd.dwWidth = texdim_x; - ddsd.dwHeight = texdim_y; - - if(_fpsmeter_font_surf!=NULL) { - ULONG refcnt; - RELEASE(_fpsmeter_font_surf,dxgsg,"fpsmeter fontsurf",false); - } - - PRINTREFCNT(scrn.pDD,"pre-fpsmeter-font-create IDirectDraw7"); - - // Create a new surface for the texture - if(FAILED( hr = scrn.pDD->CreateSurface( &ddsd, &_fpsmeter_font_surf, NULL ) )) { - dxgsg_cat.error() << "CreateSurface() failed for fpsmeter font! hr = " << ConvD3DErrorToString(hr) << "\n"; - _bShowFPSMeter = false; - return; - } - - PRINTREFCNT(scrn.pDD,"post-fpsmeter-font-create IDirectDraw7"); - - FillFPSMeterTexture(); - - // make buffer for fps meter tri data - - _fps_vertexsize = sizeof(D3DVALUE) * 4 + sizeof(D3DCOLOR) + sizeof(float) * 2; - _fpsmeter_fvfflags = D3DFVF_XYZRHW | D3DFVF_DIFFUSE | (D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE2(0)); - - int numverts=(NUM_FPSMETER_LETTERS+1)*2*3; // +1 for square to hold suffix - - if(_fpsmeter_verts == NULL) - _fpsmeter_verts = (DWORD *) new BYTE[_fps_vertexsize*numverts]; - - _fps_u_usedwidth = letterfontareaWidth/(float)texdim_x; - _fps_v_usedheight = fontareaHeight/(float)texdim_y; - - SetFPSMeterPosition(scrn.view_rect); - } - // Make sure the DX state matches all of our initial attribute states. CPT(RenderAttrib) dta = DepthTestAttrib::make(DepthTestAttrib::M_less); CPT(RenderAttrib) dwa = DepthWriteAttrib::make(DepthWriteAttrib::M_on); @@ -918,14 +686,14 @@ dx_init( void) { } //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::do_clear +// Function: DXGraphicsStateGuardian7::do_clear // Access: Public, Virtual // Description: Clears all of the indicated buffers to their assigned // colors. //////////////////////////////////////////////////////////////////// -void DXGraphicsStateGuardian:: +void DXGraphicsStateGuardian7:: do_clear(const RenderBuffer &buffer) { - DO_PSTATS_STUFF(PStatTimer timer(_win->_clear_pcollector)); + // DO_PSTATS_STUFF(PStatTimer timer(_win->_clear_pcollector)); nassertv(buffer._gsg == this); int buffer_type = buffer._buffer_type; @@ -944,7 +712,7 @@ do_clear(const RenderBuffer &buffer) { HRESULT hr = scrn.pD3DDevice->Clear(0, NULL, flags, _d3dcolor_clear_value, (D3DVALUE) _depth_clear_value, (DWORD)_stencil_clear_value); if (hr != DD_OK) - dxgsg_cat.error() << "clear_buffer failed: Clear returned " << ConvD3DErrorToString(hr) << endl; + dxgsg7_cat.error() << "clear_buffer failed: Clear returned " << ConvD3DErrorToString(hr) << endl; /* The following line will cause the background to always clear to a medium red _color_clear_value[0] = .5; /* The following lines will cause the background color to cycle from black to red. @@ -954,36 +722,43 @@ do_clear(const RenderBuffer &buffer) { } //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::prepare_display_region +// Function: DXGraphicsStateGuardian7::prepare_display_region // Access: Public, Virtual // Description: Prepare a display region for rendering (set up // scissor region and viewport) //////////////////////////////////////////////////////////////////// -void DXGraphicsStateGuardian:: +void DXGraphicsStateGuardian7:: prepare_display_region() { - if (_current_display_region == (DisplayRegion*)0L) { - dxgsg_cat.error() - << "Invalid NULL display region in prepare_display_region()\n"; - } else if (_current_display_region != _actual_display_region) { - _actual_display_region = _current_display_region; + if (_current_display_region == (DisplayRegion*)0L) { + dxgsg7_cat.error() + << "Invalid NULL display region in prepare_display_region()\n"; - int l, b, w, h; - _actual_display_region->get_region_pixels(l, b, w, h); + } else if (_current_display_region != _actual_display_region) { + _actual_display_region = _current_display_region; - // Create the viewport - D3DVIEWPORT7 vp = {l,b,w,h,0.0f,1.0f}; - HRESULT hr = scrn.pD3DDevice->SetViewport( &vp ); - if(FAILED(hr)) { - dxgsg_cat.fatal() << "SetViewport failed : result = " << ConvD3DErrorToString(hr) << endl; - exit(1); - } + int l, b, w, h; + _actual_display_region->get_region_pixels(l, b, w, h); - // Note: for DX9, also change scissor clipping state here + // Create the viewport + D3DVIEWPORT7 vp = { + l, b, + w, h, + 0.0f, 1.0f + }; + HRESULT hr = scrn.pD3DDevice->SetViewport(&vp); + if (FAILED(hr)) { + dxgsg7_cat.error() + << "SetViewport(" << l << ", " << b << ", " << w << ", " << h + << ") failed : result = " << ConvD3DErrorToString(hr) + << endl; } + + // Note: for DX9, also change scissor clipping state here + } } //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::prepare_lens +// Function: DXGraphicsStateGuardian7::prepare_lens // Access: Public, Virtual // Description: Makes the current lens (whichever lens was most // recently specified with push_lens()) active, so that @@ -995,7 +770,7 @@ prepare_display_region() { // The return value is true if the lens is acceptable, // false if it is not. //////////////////////////////////////////////////////////////////// -bool DXGraphicsStateGuardian:: +bool DXGraphicsStateGuardian7:: prepare_lens() { if (_current_lens == (Lens *)NULL) { return false; @@ -1025,14 +800,14 @@ prepare_lens() { // Access: // Description: Useless in DX at the present time //////////////////////////////////////////////////////////////////// -void DXGraphicsStateGuardian::set_clipper(RECT cliprect) { +void DXGraphicsStateGuardian7::set_clipper(RECT cliprect) { LPDIRECTDRAWCLIPPER Clipper; HRESULT result; // For windowed mode, the clip region is associated with the window, // and DirectX does not allow you to create clip regions. - if (dx_full_screen) return; + if (_win->is_fullscreen()) return; /* The cliprect we receive is normalized so that (0,0) means the upper left of the client portion of the window. @@ -1076,7 +851,7 @@ void INLINE TestDrawPrimFailure(DP_Type dptype,HRESULT hr,LPDIRECTDRAW7 pDD,DWOR // loss of exclusive mode is not a real DrawPrim problem, ignore it HRESULT testcooplvl_hr = pDD->TestCooperativeLevel(); if((testcooplvl_hr != DDERR_NOEXCLUSIVEMODE)||(testcooplvl_hr != DDERR_EXCLUSIVEMODEALREADYSET)) { - dxgsg_cat.fatal() << DP_Type_Strs[dptype] << "() failed: result = " << ConvD3DErrorToString(hr) << endl; + dxgsg7_cat.fatal() << DP_Type_Strs[dptype] << "() failed: result = " << ConvD3DErrorToString(hr) << endl; exit(1); } } @@ -1088,11 +863,11 @@ void INLINE TestDrawPrimFailure(DP_Type dptype,HRESULT hr,LPDIRECTDRAW7 pDD,DWOR #endif //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::report_texmgr_stats +// Function: DXGraphicsStateGuardian7::report_texmgr_stats // Access: Protected // Description: Reports the DX texture manager's activity to PStats. //////////////////////////////////////////////////////////////////// -void DXGraphicsStateGuardian:: +void DXGraphicsStateGuardian7:: report_texmgr_stats() { #if defined(DO_PSTATS)||defined(PRINT_TEXSTATS) @@ -1110,13 +885,13 @@ report_texmgr_stats() { ddsCaps.dwCaps = DDSCAPS_VIDEOMEMORY | DDSCAPS_PRIMARYSURFACE | DDSCAPS_3DDEVICE; if(FAILED( hr = scrn.pDD->GetAvailableVidMem(&ddsCaps,&dwVidTotal,&dwVidFree))) { - dxgsg_cat.debug() << "report_texmgr GetAvailableVidMem for VIDMEM failed : result = " << ConvD3DErrorToString(hr) << endl; + dxgsg7_cat.debug() << "report_texmgr GetAvailableVidMem for VIDMEM failed : result = " << ConvD3DErrorToString(hr) << endl; exit(1); } ddsCaps.dwCaps = DDSCAPS_TEXTURE; if(FAILED( hr = scrn.pDD->GetAvailableVidMem(&ddsCaps,&dwTexTotal,&dwTexFree))) { - dxgsg_cat.debug() << "report_texmgr GetAvailableVidMem for TEXTURE failed : result = " << ConvD3DErrorToString(hr) << endl; + dxgsg7_cat.debug() << "report_texmgr GetAvailableVidMem for TEXTURE failed : result = " << ConvD3DErrorToString(hr) << endl; exit(1); } } @@ -1130,13 +905,13 @@ report_texmgr_stats() { if (hr==S_FALSE) { static int PrintedMsg=2; if(PrintedMsg>0) { - if(dxgsg_cat.is_debug()) - dxgsg_cat.debug() << " ************ texstats GetInfo() requires debug DX DLLs to be installed!! ***********\n"; + if(dxgsg7_cat.is_debug()) + dxgsg7_cat.debug() << " ************ texstats GetInfo() requires debug DX DLLs to be installed!! ***********\n"; ZeroMemory(&tminfo,sizeof(D3DDEVINFO_TEXTUREMANAGER)); bTexStatsRetrievalImpossible=true; } } else { - dxgsg_cat.error() << "d3ddev->GetInfo(TEXTUREMANAGER) failed to get tex stats: result = " << ConvD3DErrorToString(hr) << endl; + dxgsg7_cat.error() << "d3ddev->GetInfo(TEXTUREMANAGER) failed to get tex stats: result = " << ConvD3DErrorToString(hr) << endl; return; } } @@ -1148,11 +923,11 @@ report_texmgr_stats() { sprintf(tmpstr2,"%.4g",dwVidFree/1000000.0); sprintf(tmpstr3,"%.4g",dwTexTotal/1000000.0); sprintf(tmpstr4,"%.4g",dwTexFree/1000000.0); - dxgsg_cat.debug() << "\nAvailableVidMem for RenderSurfs: (megs) total: " << tmpstr1 << " free: " << tmpstr2 + dxgsg7_cat.debug() << "\nAvailableVidMem for RenderSurfs: (megs) total: " << tmpstr1 << " free: " << tmpstr2 << "\nAvailableVidMem for Textures: (megs) total: " << tmpstr3 << " free: " << tmpstr4 << endl; if(!bTexStatsRetrievalImpossible) { - dxgsg_cat.spam() + dxgsg7_cat.spam() << "\n bThrashing:\t" << tminfo.bThrashing << "\n NumEvicts:\t" << tminfo.dwNumEvicts << "\n NumVidCreates:\t" << tminfo.dwNumVidCreates @@ -1168,10 +943,10 @@ report_texmgr_stats() { ZeroMemory(&texappinfo,sizeof(D3DDEVINFO_TEXTURING)); hr = scrn.pD3DDevice->GetInfo(D3DDEVINFOID_TEXTURING,&texappinfo,sizeof(D3DDEVINFO_TEXTURING)); if (hr!=D3D_OK) { - dxgsg_cat.error() << "GetInfo(TEXTURING) failed : result = " << ConvD3DErrorToString(hr) << endl; + dxgsg7_cat.error() << "GetInfo(TEXTURING) failed : result = " << ConvD3DErrorToString(hr) << endl; return; } else { - dxgsg_cat.spam() + dxgsg7_cat.spam() << "\n NumTexLoads:\t" << texappinfo.dwNumLoads << "\n ApproxBytesLoaded:\t" << texappinfo.dwApproxBytesLoaded << "\n NumPreLoads:\t" << texappinfo.dwNumPreLoads @@ -1205,11 +980,11 @@ report_texmgr_stats() { } //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::add_to_FVFBuf +// Function: DXGraphicsStateGuardian7::add_to_FVFBuf // Access: Private // Description: This adds data to the flexible vertex format //////////////////////////////////////////////////////////////////// -INLINE void DXGraphicsStateGuardian:: +INLINE void DXGraphicsStateGuardian7:: add_to_FVFBuf(void *data, size_t bytes) { memcpy(_pCurFvfBufPtr, data, bytes); _pCurFvfBufPtr += bytes; @@ -1233,7 +1008,7 @@ typedef enum { _pCurrentGeomContext->_pEndofVertData+=numVertBytes; } -INLINE void DXGraphicsStateGuardian:: +INLINE void DXGraphicsStateGuardian7:: transform_color(Colorf &InColor,D3DCOLOR &OutRGBAColor) { Colorf transformed ((InColor[0] * _current_color_scale[0]) + _current_color_offset[0], @@ -1244,11 +1019,11 @@ transform_color(Colorf &InColor,D3DCOLOR &OutRGBAColor) { } //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::draw_prim_setup +// Function: DXGraphicsStateGuardian7::draw_prim_setup // Access: Private // Description: This adds data to the flexible vertex format //////////////////////////////////////////////////////////////////// -size_t DXGraphicsStateGuardian:: +size_t DXGraphicsStateGuardian7:: draw_prim_setup(const Geom *geom) { // Set the flags for the flexible vertex format and compute the bytes // required to store a single vertex. @@ -1374,12 +1149,12 @@ draw_prim_setup(const Geom *geom) { } //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::draw_prim_inner_loop +// Function: DXGraphicsStateGuardian7::draw_prim_inner_loop // Access: Private // Description: This adds data to the flexible vertex format with a check // for component normals and color //////////////////////////////////////////////////////////////////// -void DXGraphicsStateGuardian:: +void DXGraphicsStateGuardian7:: draw_prim_inner_loop(int nVerts, const Geom *geom, ushort perFlags) { Vertexf NextVert; @@ -1423,11 +1198,11 @@ draw_prim_inner_loop(int nVerts, const Geom *geom, ushort perFlags) { } //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::draw_prim_inner_loop_coordtexonly +// Function: DXGraphicsStateGuardian7::draw_prim_inner_loop_coordtexonly // Access: Private // Description: FastPath loop used by animated character data //////////////////////////////////////////////////////////////////// -void DXGraphicsStateGuardian:: +void DXGraphicsStateGuardian7:: draw_prim_inner_loop_coordtexonly(int nVerts, const Geom *geom) { // assumes coord and texcoord data is per-vertex, // color is not per-vert/component (which would require fetching new vals in the vertex loop), @@ -1486,15 +1261,15 @@ draw_prim_inner_loop_coordtexonly(int nVerts, const Geom *geom) { } //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::draw_point +// Function: DXGraphicsStateGuardian7::draw_point // Access: Public, Virtual // Description: //////////////////////////////////////////////////////////////////// -void DXGraphicsStateGuardian:: +void DXGraphicsStateGuardian7:: draw_point(GeomPoint *geom, GeomContext *gc) { #ifdef GSG_VERBOSE - dxgsg_cat.debug() << "draw_point()" << endl; + dxgsg7_cat.debug() << "draw_point()" << endl; #endif DO_PSTATS_STUFF(PStatTimer timer(_draw_primitive_pcollector)); @@ -1505,7 +1280,7 @@ draw_point(GeomPoint *geom, GeomContext *gc) { int nPrims = geom->get_num_prims(); if (nPrims==0) { - dxgsg_cat.warning() << "draw_point() called with ZERO vertices!!" << endl; + dxgsg7_cat.warning() << "draw_point() called with ZERO vertices!!" << endl; return; } @@ -1514,7 +1289,7 @@ draw_point(GeomPoint *geom, GeomContext *gc) { if (!bPrintedMsg && (geom->get_size()!=1.0f)) { bPrintedMsg=TRUE; - dxgsg_cat.warning() << "D3D does not support drawing points of non-unit size, setting point size to 1.0f!\n"; + dxgsg7_cat.warning() << "D3D does not support drawing points of non-unit size, setting point size to 1.0f!\n"; } #endif @@ -1632,15 +1407,15 @@ draw_point(GeomPoint *geom, GeomContext *gc) { } //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::draw_line +// Function: DXGraphicsStateGuardian7::draw_line // Access: Public, Virtual // Description: //////////////////////////////////////////////////////////////////// -void DXGraphicsStateGuardian:: +void DXGraphicsStateGuardian7:: draw_line(GeomLine* geom, GeomContext *gc) { #ifdef GSG_VERBOSE - dxgsg_cat.debug() << "draw_line()" << endl; + dxgsg7_cat.debug() << "draw_line()" << endl; #endif DO_PSTATS_STUFF(PStatTimer timer(_draw_primitive_pcollector)); DO_PSTATS_STUFF(_vertices_other_pcollector.add_level(geom->get_num_vertices())); @@ -1652,16 +1427,16 @@ draw_line(GeomLine* geom, GeomContext *gc) { if (!bPrintedMsg && (geom->get_width()!=1.0f)) { bPrintedMsg=TRUE; - if(dxgsg_cat.is_debug()) - dxgsg_cat.debug() << "DX does not support drawing lines with a non-1.0f pixel width, setting width to 1.0f!\n"; + if(dxgsg7_cat.is_debug()) + dxgsg7_cat.debug() << "DX does not support drawing lines with a non-1.0f pixel width, setting width to 1.0f!\n"; } #endif int nPrims = geom->get_num_prims(); if (nPrims==0) { - if(dxgsg_cat.is_debug()) - dxgsg_cat.debug() << "draw_line() called with ZERO vertices!!" << endl; + if(dxgsg7_cat.is_debug()) + dxgsg7_cat.debug() << "draw_line() called with ZERO vertices!!" << endl; return; } @@ -1732,7 +1507,7 @@ draw_line(GeomLine* geom, GeomContext *gc) { _pCurFvfBufPtr = NULL; } -void DXGraphicsStateGuardian:: +void DXGraphicsStateGuardian7:: draw_linestrip(GeomLinestrip* geom, GeomContext *gc) { #ifdef _DEBUG @@ -1740,8 +1515,8 @@ draw_linestrip(GeomLinestrip* geom, GeomContext *gc) { if (!bPrintedMsg && (geom->get_width()!=1.0f)) { bPrintedMsg=TRUE; - if(dxgsg_cat.is_debug()) - dxgsg_cat.debug() << "DX does not support drawing lines with a non-1.0f pixel width, setting width to 1.0f!\n"; + if(dxgsg7_cat.is_debug()) + dxgsg7_cat.debug() << "DX does not support drawing lines with a non-1.0f pixel width, setting width to 1.0f!\n"; } #endif @@ -1749,16 +1524,16 @@ draw_linestrip(GeomLinestrip* geom, GeomContext *gc) { } //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::draw_linestrip +// Function: DXGraphicsStateGuardian7::draw_linestrip // Access: Public, Virtual // Description: //////////////////////////////////////////////////////////////////// -void DXGraphicsStateGuardian:: +void DXGraphicsStateGuardian7:: draw_linestrip_base(Geom* geom, GeomContext *gc, bool bConnectEnds) { // Note draw_linestrip_base() may be called from non-line draw_fns to support wireframe mode #ifdef GSG_VERBOSE - dxgsg_cat.debug() << "draw_linestrip()" << endl; + dxgsg7_cat.debug() << "draw_linestrip()" << endl; #endif DO_PSTATS_STUFF(PStatTimer timer(_draw_primitive_pcollector)); @@ -1768,8 +1543,8 @@ draw_linestrip_base(Geom* geom, GeomContext *gc, bool bConnectEnds) { const int *pLengthArr = geom->get_lengths(); if(nPrims==0) { - if(dxgsg_cat.is_debug()) - dxgsg_cat.debug() << "draw_linestrip() called with ZERO vertices!!" << endl; + if(dxgsg7_cat.is_debug()) + dxgsg7_cat.debug() << "draw_linestrip() called with ZERO vertices!!" << endl; return; } @@ -1877,11 +1652,11 @@ struct draw_sprite_vertex_less { }; //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::draw_sprite +// Function: DXGraphicsStateGuardian7::draw_sprite // Access: Public, Virtual // Description: //////////////////////////////////////////////////////////////////// -void DXGraphicsStateGuardian:: +void DXGraphicsStateGuardian7:: draw_sprite(GeomSprite *geom, GeomContext *gc) { // this is a little bit of a mess, but it's ok. Here's the deal: @@ -1901,7 +1676,7 @@ draw_sprite(GeomSprite *geom, GeomContext *gc) { // Note: for DX8, try to use the PointSprite primitive instead of doing all the stuff below #ifdef GSG_VERBOSE - dxgsg_cat.debug() << "draw_sprite()" << endl; + dxgsg7_cat.debug() << "draw_sprite()" << endl; #endif // get the array traversal set up. int nprims = geom->get_num_prims(); @@ -2028,7 +1803,7 @@ draw_sprite(GeomSprite *geom, GeomContext *gc) { // alternately, alloc once when retained mode becomes available if (SpriteArray==NULL) { - dxgsg_cat.fatal() << "draw_sprite() out of memory!!" << endl; + dxgsg7_cat.fatal() << "draw_sprite() out of memory!!" << endl; return; } @@ -2257,15 +2032,15 @@ draw_sprite(GeomSprite *geom, GeomContext *gc) { } //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::draw_polygon +// Function: DXGraphicsStateGuardian7::draw_polygon // Access: Public, Virtual // Description: //////////////////////////////////////////////////////////////////// -void DXGraphicsStateGuardian:: +void DXGraphicsStateGuardian7:: draw_polygon(GeomPolygon *geom, GeomContext *gc) { #ifdef GSG_VERBOSE - dxgsg_cat.debug() << "draw_polygon()" << endl; + dxgsg7_cat.debug() << "draw_polygon()" << endl; #endif DO_PSTATS_STUFF(PStatTimer timer(_draw_primitive_pcollector)); DO_PSTATS_STUFF(_vertices_other_pcollector.add_level(geom->get_num_vertices())); @@ -2281,15 +2056,15 @@ draw_polygon(GeomPolygon *geom, GeomContext *gc) { } //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::draw_quad +// Function: DXGraphicsStateGuardian7::draw_quad // Access: Public, Virtual // Description: //////////////////////////////////////////////////////////////////// -void DXGraphicsStateGuardian:: +void DXGraphicsStateGuardian7:: draw_quad(GeomQuad *geom, GeomContext *gc) { #ifdef GSG_VERBOSE - dxgsg_cat.debug() << "draw_quad()" << endl; + dxgsg7_cat.debug() << "draw_quad()" << endl; #endif DO_PSTATS_STUFF(PStatTimer timer(_draw_primitive_pcollector)); DO_PSTATS_STUFF(_vertices_other_pcollector.add_level(geom->get_num_vertices())); @@ -2305,22 +2080,22 @@ draw_quad(GeomQuad *geom, GeomContext *gc) { } //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::draw_tri +// Function: DXGraphicsStateGuardian7::draw_tri // Access: Public, Virtual // Description: //////////////////////////////////////////////////////////////////// -void DXGraphicsStateGuardian:: +void DXGraphicsStateGuardian7:: draw_tri(GeomTri *geom, GeomContext *gc) { #ifdef GSG_VERBOSE - dxgsg_cat.debug() << "draw_tri()" << endl; + dxgsg7_cat.debug() << "draw_tri()" << endl; #endif DO_PSTATS_STUFF(PStatTimer timer(_draw_primitive_pcollector)); DO_PSTATS_STUFF(_vertices_tri_pcollector.add_level(geom->get_num_vertices())); #if 0 if (_pCurTexContext!=NULL) { - dxgsg_cat.spam() << "Cur active DX texture: " << _pCurTexContext->_tex->get_name() << "\n"; + dxgsg7_cat.spam() << "Cur active DX texture: " << _pCurTexContext->_tex->get_name() << "\n"; } #endif @@ -2679,15 +2454,15 @@ draw_tri(GeomTri *geom, GeomContext *gc) { } //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::draw_tristrip +// Function: DXGraphicsStateGuardian7::draw_tristrip // Access: Public, Virtual // Description: //////////////////////////////////////////////////////////////////// -void DXGraphicsStateGuardian:: +void DXGraphicsStateGuardian7:: draw_tristrip(GeomTristrip *geom, GeomContext *gc) { #ifdef GSG_VERBOSE - dxgsg_cat.debug() << "draw_tristrip()" << endl; + dxgsg7_cat.debug() << "draw_tristrip()" << endl; #endif DO_PSTATS_STUFF(PStatTimer timer(_draw_primitive_pcollector)); DO_PSTATS_STUFF(_vertices_tristrip_pcollector.add_level(geom->get_num_vertices())); @@ -2696,15 +2471,15 @@ draw_tristrip(GeomTristrip *geom, GeomContext *gc) { } //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::draw_trifan +// Function: DXGraphicsStateGuardian7::draw_trifan // Access: Public, Virtual // Description: //////////////////////////////////////////////////////////////////// -void DXGraphicsStateGuardian:: +void DXGraphicsStateGuardian7:: draw_trifan(GeomTrifan *geom, GeomContext *gc) { #ifdef GSG_VERBOSE - dxgsg_cat.debug() << "draw_trifan()" << endl; + dxgsg7_cat.debug() << "draw_trifan()" << endl; #endif DO_PSTATS_STUFF(PStatTimer timer(_draw_primitive_pcollector)); DO_PSTATS_STUFF(_vertices_trifan_pcollector.add_level(geom->get_num_vertices())); @@ -2713,11 +2488,11 @@ draw_trifan(GeomTrifan *geom, GeomContext *gc) { } //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::draw_multitri +// Function: DXGraphicsStateGuardian7::draw_multitri // Access: Public, Virtual // Description: handles trifans and tristrips //////////////////////////////////////////////////////////////////// -void DXGraphicsStateGuardian:: +void DXGraphicsStateGuardian7:: draw_multitri(Geom *geom, D3DPRIMITIVETYPE trilisttype) { DWORD nPrims = geom->get_num_prims(); @@ -2726,7 +2501,7 @@ draw_multitri(Geom *geom, D3DPRIMITIVETYPE trilisttype) { if(nPrims==0) { #ifdef _DEBUG - dxgsg_cat.warning() << "draw_multitri() called with ZERO vertices!!" << endl; + dxgsg7_cat.warning() << "draw_multitri() called with ZERO vertices!!" << endl; #endif return; } @@ -3176,7 +2951,7 @@ draw_multitri(Geom *geom, D3DPRIMITIVETYPE trilisttype) { // tries to match gluSphere behavior //----------------------------------------------------------------------------- -void DXGraphicsStateGuardian:: +void DXGraphicsStateGuardian7:: GenerateSphere(void *pVertexSpace,DWORD dwVertSpaceByteSize, void *pIndexSpace,DWORD dwIndexSpaceByteSize, D3DVECTOR *pCenter, float fRadius, @@ -3411,18 +3186,18 @@ GenerateSphere(void *pVertexSpace,DWORD dwVertSpaceByteSize, //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::draw_sphere +// Function: DXGraphicsStateGuardian7::draw_sphere // Access: Public, Virtual // Description: //////////////////////////////////////////////////////////////////// -void DXGraphicsStateGuardian:: +void DXGraphicsStateGuardian7:: draw_sphere(GeomSphere *geom, GeomContext *gc) { #define SPHERE_NUMSLICES 16 #define SPHERE_NUMSTACKS 10 #ifdef GSG_VERBOSE - dxgsg_cat.debug() << "draw_sphere()" << endl; + dxgsg7_cat.debug() << "draw_sphere()" << endl; #endif DO_PSTATS_STUFF(PStatTimer timer(_draw_primitive_pcollector)); DO_PSTATS_STUFF(_vertices_other_pcollector.add_level(geom->get_num_vertices())); @@ -3430,7 +3205,7 @@ draw_sphere(GeomSphere *geom, GeomContext *gc) { int nprims = geom->get_num_prims(); if (nprims==0) { - dxgsg_cat.warning() << "draw_sphere() called with ZERO vertices!!" << endl; + dxgsg7_cat.warning() << "draw_sphere() called with ZERO vertices!!" << endl; return; } @@ -3476,7 +3251,7 @@ draw_sphere(GeomSphere *geom, GeomContext *gc) { } //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::prepare_texture +// Function: DXGraphicsStateGuardian7::prepare_texture // Access: Public, Virtual // Description: Creates a new retained-mode representation of the // given texture, and returns a newly-allocated @@ -3485,10 +3260,10 @@ draw_sphere(GeomSphere *geom, GeomContext *gc) { // call release_texture() with this same pointer (which // will also delete the pointer). //////////////////////////////////////////////////////////////////// -TextureContext *DXGraphicsStateGuardian:: +TextureContext *DXGraphicsStateGuardian7:: prepare_texture(Texture *tex) { - DXTextureContext *dtc = new DXTextureContext(tex); + DXTextureContext7 *dtc = new DXTextureContext7(tex); #ifdef WBD_GL_MODE glGenTextures(1, >c->_index); @@ -3519,12 +3294,12 @@ prepare_texture(Texture *tex) { } //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::apply_texture +// Function: DXGraphicsStateGuardian7::apply_texture // Access: Public, Virtual // Description: Makes the texture the currently available texture for // rendering. //////////////////////////////////////////////////////////////////// -void DXGraphicsStateGuardian:: +void DXGraphicsStateGuardian7:: apply_texture(TextureContext *tc) { if (tc==NULL) { return; // use enable_texturing to disable/enable @@ -3537,9 +3312,9 @@ apply_texture(TextureContext *tc) { // specify_texture(tc->_texture); // Note: if this code changes, make sure to change initialization SetTSS code in dx_init as well - // so DX TSS renderstate matches dxgsg state + // so DX TSS renderstate matches dxgsg7 state - DXTextureContext *dtc = DCAST(DXTextureContext, tc); + DXTextureContext7 *dtc = DCAST(DXTextureContext7, tc); int dirty = dtc->get_dirty_flags(); @@ -3553,7 +3328,7 @@ apply_texture(TextureContext *tc) { // warning--it is likely that this change is the result of an // error or oversight. if ((dirty & Texture::DF_image) == 0) { - dxgsg_cat.warning() + dxgsg7_cat.warning() << "Texture " << *dtc->_texture << " has changed mipmap state.\n"; } @@ -3564,7 +3339,7 @@ apply_texture(TextureContext *tc) { if (dtc->CreateTexture(scrn.pD3DDevice,_cNumTexPixFmts,_pTexPixFmts,&scrn.D3DDevDesc) == NULL) { #endif // Oops, we can't re-create the texture for some reason. - dxgsg_cat.error() << "Unable to re-create texture " << *dtc->_texture << endl; + dxgsg7_cat.error() << "Unable to re-create texture " << *dtc->_texture << endl; release_texture(dtc); enable_texturing(false); @@ -3606,7 +3381,7 @@ apply_texture(TextureContext *tc) { #ifdef _DEBUG if((ft!=Texture::FT_linear)&&(ft!=Texture::FT_nearest)) { - dxgsg_cat.error() << "MipMap filter type setting for texture magfilter makes no sense, texture: " << tex->get_name() << "\n"; + dxgsg7_cat.error() << "MipMap filter type setting for texture magfilter makes no sense, texture: " << tex->get_name() << "\n"; } #endif } else { @@ -3639,7 +3414,7 @@ apply_texture(TextureContext *tc) { // sanity check extern char *PandaFilterNameStrs[]; if((!(dtc->_bHasMipMaps))&&(newMipFilter!=D3DTFP_NONE)) { - dxgsg_cat.error() << "Trying to set mipmap filtering for texture with no generated mipmaps!! texname[" << tex->get_name() << "], filter("<get_name() << "], filter("<_tex->get_name() << "\n"; + dxgsg7_cat.spam() << "Setting active DX texture: " << dtc->_tex->get_name() << "\n"; } #endif @@ -3675,14 +3450,14 @@ apply_texture(TextureContext *tc) { } //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::release_texture +// Function: DXGraphicsStateGuardian7::release_texture // Access: Public, Virtual // Description: Frees the GL resources previously allocated for the // texture. //////////////////////////////////////////////////////////////////// -void DXGraphicsStateGuardian:: +void DXGraphicsStateGuardian7:: release_texture(TextureContext *tc) { - DXTextureContext *gtc = DCAST(DXTextureContext, tc); + DXTextureContext7 *gtc = DCAST(DXTextureContext7, tc); Texture *tex = tc->_texture; gtc->DeleteTexture(); @@ -3699,9 +3474,9 @@ release_texture(TextureContext *tc) { #if 1 -void DXGraphicsStateGuardian:: +void DXGraphicsStateGuardian7:: copy_texture(TextureContext *tc, const DisplayRegion *dr) { - dxgsg_cat.fatal() << "DX copy_texture unimplemented!!!"; + dxgsg7_cat.fatal() << "DX copy_texture unimplemented!!!"; } #else @@ -3719,12 +3494,12 @@ static int binary_log_cap(const int x) { } //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::copy_texture +// Function: DXGraphicsStateGuardian7::copy_texture // Access: Public, Virtual // Description: Copy the pixel region indicated by the display // region from the framebuffer into texture memory //////////////////////////////////////////////////////////////////// -void DXGraphicsStateGuardian:: +void DXGraphicsStateGuardian7:: copy_texture(TextureContext *tc, const DisplayRegion *dr) { nassertv(tc != NULL && dr != NULL); @@ -3761,13 +3536,13 @@ copy_texture(TextureContext *tc, const DisplayRegion *dr) { #endif //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::copy_texture +// Function: DXGraphicsStateGuardian7::copy_texture // Access: Public, Virtual // Description: //////////////////////////////////////////////////////////////////// -void DXGraphicsStateGuardian:: +void DXGraphicsStateGuardian7:: copy_texture(TextureContext *tc, const DisplayRegion *dr, const RenderBuffer &rb) { - dxgsg_cat.fatal() << "DX copy_texture unimplemented!!!"; + dxgsg7_cat.fatal() << "DX copy_texture unimplemented!!!"; return; set_read_buffer(rb); @@ -3775,11 +3550,11 @@ copy_texture(TextureContext *tc, const DisplayRegion *dr, const RenderBuffer &rb } //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::texture_to_pixel_buffer +// Function: DXGraphicsStateGuardian7::texture_to_pixel_buffer // Access: Public, Virtual // Description: //////////////////////////////////////////////////////////////////// -void DXGraphicsStateGuardian:: +void DXGraphicsStateGuardian7:: texture_to_pixel_buffer(TextureContext *tc, PixelBuffer *pb) { nassertv(tc != NULL && pb != NULL); @@ -3800,23 +3575,23 @@ texture_to_pixel_buffer(TextureContext *tc, PixelBuffer *pb) { } //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::texture_to_pixel_buffer +// Function: DXGraphicsStateGuardian7::texture_to_pixel_buffer // Access: Public, Virtual // Description: //////////////////////////////////////////////////////////////////// -void DXGraphicsStateGuardian:: +void DXGraphicsStateGuardian7:: texture_to_pixel_buffer(TextureContext *tc, PixelBuffer *pb, const DisplayRegion *dr) { - dxgsg_cat.error() + dxgsg7_cat.error() << "texture_to_pixel_buffer unimplemented!\n"; } //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::copy_pixel_buffer +// Function: DXGraphicsStateGuardian7::copy_pixel_buffer // Access: Public, Virtual // Description: //////////////////////////////////////////////////////////////////// -void DXGraphicsStateGuardian:: +void DXGraphicsStateGuardian7:: copy_pixel_buffer(PixelBuffer *pb, const DisplayRegion *dr) { extern HRESULT ConvertDDSurftoPixBuf(PixelBuffer *pixbuf,LPDIRECTDRAWSURFACE7 pDDSurf); @@ -3848,11 +3623,11 @@ copy_pixel_buffer(PixelBuffer *pb, const DisplayRegion *dr) { } //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::copy_pixel_buffer +// Function: DXGraphicsStateGuardian7::copy_pixel_buffer // Access: Public, Virtual // Description: //////////////////////////////////////////////////////////////////// -void DXGraphicsStateGuardian:: +void DXGraphicsStateGuardian7:: copy_pixel_buffer(PixelBuffer *pb, const DisplayRegion *dr, const RenderBuffer &rb) { set_read_buffer(rb); @@ -3860,11 +3635,11 @@ copy_pixel_buffer(PixelBuffer *pb, const DisplayRegion *dr, } //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::apply_material +// Function: DXGraphicsStateGuardian7::apply_material // Access: Public, Virtual // Description: //////////////////////////////////////////////////////////////////// -void DXGraphicsStateGuardian::apply_material( const Material* material ) { +void DXGraphicsStateGuardian7::apply_material( const Material* material ) { D3DMATERIAL7 cur_material; cur_material.dcvDiffuse = *(D3DCOLORVALUE *)(material->get_diffuse().get_data()); cur_material.dcvAmbient = *(D3DCOLORVALUE *)(material->get_ambient().get_data()); @@ -3875,11 +3650,11 @@ void DXGraphicsStateGuardian::apply_material( const Material* material ) { } //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::apply_fog +// Function: DXGraphicsStateGuardian7::apply_fog // Access: Public, Virtual // Description: //////////////////////////////////////////////////////////////////// -void DXGraphicsStateGuardian:: +void DXGraphicsStateGuardian7:: apply_fog(Fog *fog) { if(_doFogType==None) return; @@ -3922,7 +3697,7 @@ apply_fog(Fog *fog) { } } -void DXGraphicsStateGuardian::SetTextureBlendMode(TextureApplyAttrib::Mode TexBlendMode,bool bCanJustEnable) { +void DXGraphicsStateGuardian7::SetTextureBlendMode(TextureApplyAttrib::Mode TexBlendMode,bool bCanJustEnable) { /*class TextureApplyAttrib { enum Mode { @@ -3978,7 +3753,7 @@ void DXGraphicsStateGuardian::SetTextureBlendMode(TextureApplyAttrib::Mode TexBl break; case TextureApplyAttrib::M_blend: - dxgsg_cat.error() + dxgsg7_cat.error() << "Impossible to emulate GL_BLEND in DX exactly " << (int) TexBlendMode << endl; /* // emulate GL_BLEND glTexEnv @@ -4006,18 +3781,18 @@ void DXGraphicsStateGuardian::SetTextureBlendMode(TextureApplyAttrib::Mode TexBl break; default: - dxgsg_cat.error() << "Unknown texture blend mode " << (int) TexBlendMode << endl; + dxgsg7_cat.error() << "Unknown texture blend mode " << (int) TexBlendMode << endl; break; } } //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::enable_texturing +// Function: DXGraphicsStateGuardian7::enable_texturing // Access: // Description: //////////////////////////////////////////////////////////////////// -INLINE void DXGraphicsStateGuardian:: +INLINE void DXGraphicsStateGuardian7:: enable_texturing(bool val) { // if (_texturing_enabled == val) { // this check is mostly for internal gsg calls, panda already screens out redundant state changes // return; @@ -4036,33 +3811,33 @@ enable_texturing(bool val) { } //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::issue_transform +// Function: DXGraphicsStateGuardian7::issue_transform // Access: Public, Virtual // Description: Sends the indicated transform matrix to the graphics // API to be applied to future vertices. //////////////////////////////////////////////////////////////////// -void DXGraphicsStateGuardian:: +void DXGraphicsStateGuardian7:: issue_transform(const TransformState *transform) { scrn.pD3DDevice->SetTransform(D3DTRANSFORMSTATE_WORLD, (LPD3DMATRIX)transform->get_mat().get_data()); } //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::issue_tex_matrix +// Function: DXGraphicsStateGuardian7::issue_tex_matrix // Access: Public, Virtual // Description: //////////////////////////////////////////////////////////////////// -void DXGraphicsStateGuardian:: +void DXGraphicsStateGuardian7:: issue_tex_matrix(const TexMatrixAttrib *attrib) { // Not implemented. } //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::issue_texture +// Function: DXGraphicsStateGuardian7::issue_texture // Access: Public, Virtual // Description: //////////////////////////////////////////////////////////////////// -void DXGraphicsStateGuardian:: +void DXGraphicsStateGuardian7:: issue_texture(const TextureAttrib *attrib) { if (attrib->is_off()) { enable_texturing(false); @@ -4075,11 +3850,11 @@ issue_texture(const TextureAttrib *attrib) { } //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::issue_material +// Function: DXGraphicsStateGuardian7::issue_material // Access: Public, Virtual // Description: //////////////////////////////////////////////////////////////////// -void DXGraphicsStateGuardian:: +void DXGraphicsStateGuardian7:: issue_material(const MaterialAttrib *attrib) { const Material *material = attrib->get_material(); if (material != (const Material *)NULL) { @@ -4092,11 +3867,11 @@ issue_material(const MaterialAttrib *attrib) { } //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::issue_render_mode +// Function: DXGraphicsStateGuardian7::issue_render_mode // Access: Public, Virtual // Description: //////////////////////////////////////////////////////////////////// -void DXGraphicsStateGuardian:: +void DXGraphicsStateGuardian7:: issue_render_mode(const RenderModeAttrib *attrib) { RenderModeAttrib::Mode mode = attrib->get_mode(); @@ -4110,7 +3885,7 @@ issue_render_mode(const RenderModeAttrib *attrib) { break; default: - dxgsg_cat.error() + dxgsg7_cat.error() << "Unknown render mode " << (int)mode << endl; } @@ -4118,20 +3893,20 @@ issue_render_mode(const RenderModeAttrib *attrib) { } //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::issue_texture_apply +// Function: DXGraphicsStateGuardian7::issue_texture_apply // Access: Public, Virtual // Description: //////////////////////////////////////////////////////////////////// -void DXGraphicsStateGuardian:: +void DXGraphicsStateGuardian7:: issue_texture_apply(const TextureApplyAttrib *attrib) { } //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::issue_depth_test +// Function: DXGraphicsStateGuardian7::issue_depth_test // Access: Public, Virtual // Description: //////////////////////////////////////////////////////////////////// -void DXGraphicsStateGuardian:: +void DXGraphicsStateGuardian7:: issue_depth_test(const DepthTestAttrib *attrib) { DepthTestAttrib::PandaCompareFunc mode = attrib->get_mode(); if (mode == DepthTestAttrib::M_none) { @@ -4145,11 +3920,11 @@ issue_depth_test(const DepthTestAttrib *attrib) { } //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::issue_alpha_test +// Function: DXGraphicsStateGuardian7::issue_alpha_test // Access: Public, Virtual // Description: //////////////////////////////////////////////////////////////////// -void DXGraphicsStateGuardian:: +void DXGraphicsStateGuardian7:: issue_alpha_test(const AlphaTestAttrib *attrib) { AlphaTestAttrib::PandaCompareFunc mode = attrib->get_mode(); if (mode == AlphaTestAttrib::M_none) { @@ -4162,21 +3937,21 @@ issue_alpha_test(const AlphaTestAttrib *attrib) { } //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::issue_depth_write +// Function: DXGraphicsStateGuardian7::issue_depth_write // Access: Public, Virtual // Description: //////////////////////////////////////////////////////////////////// -void DXGraphicsStateGuardian:: +void DXGraphicsStateGuardian7:: issue_depth_write(const DepthWriteAttrib *attrib) { enable_zwritemask(attrib->get_mode() == DepthWriteAttrib::M_on); } //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::issue_cull_face +// Function: DXGraphicsStateGuardian7::issue_cull_face // Access: Public, Virtual // Description: //////////////////////////////////////////////////////////////////// -void DXGraphicsStateGuardian:: +void DXGraphicsStateGuardian7:: issue_cull_face(const CullFaceAttrib *attrib) { CullFaceAttrib::Mode mode = attrib->get_mode(); @@ -4191,18 +3966,18 @@ issue_cull_face(const CullFaceAttrib *attrib) { scrn.pD3DDevice->SetRenderState(D3DRENDERSTATE_CULLMODE, D3DCULL_CCW); break; default: - dxgsg_cat.error() + dxgsg7_cat.error() << "invalid cull face mode " << (int)mode << endl; break; } } //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::issue_fog +// Function: DXGraphicsStateGuardian7::issue_fog // Access: Public, Virtual // Description: //////////////////////////////////////////////////////////////////// -void DXGraphicsStateGuardian:: +void DXGraphicsStateGuardian7:: issue_fog(const FogAttrib *attrib) { if (!attrib->is_off()) { enable_fog(true); @@ -4215,25 +3990,25 @@ issue_fog(const FogAttrib *attrib) { } //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::issue_depth_offset +// Function: DXGraphicsStateGuardian7::issue_depth_offset // Access: Public, Virtual // Description: //////////////////////////////////////////////////////////////////// -void DXGraphicsStateGuardian:: +void DXGraphicsStateGuardian7:: issue_depth_offset(const DepthOffsetAttrib *attrib) { int offset = attrib->get_offset(); scrn.pD3DDevice->SetRenderState(D3DRENDERSTATE_ZBIAS, offset); } //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::bind_light +// Function: DXGraphicsStateGuardian7::bind_light // Access: Public, Virtual // Description: Called the first time a particular light has been // bound to a given id within a frame, this should set // up the associated hardware light with the light's // properties. //////////////////////////////////////////////////////////////////// -void DXGraphicsStateGuardian:: +void DXGraphicsStateGuardian7:: bind_light(PointLight *light, int light_id) { // Get the light in "world coordinates". This means the light in // the coordinate space of the camera, converted to DX's coordinate @@ -4267,14 +4042,14 @@ bind_light(PointLight *light, int light_id) { } //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::bind_light +// Function: DXGraphicsStateGuardian7::bind_light // Access: Public, Virtual // Description: Called the first time a particular light has been // bound to a given id within a frame, this should set // up the associated hardware light with the light's // properties. //////////////////////////////////////////////////////////////////// -void DXGraphicsStateGuardian:: +void DXGraphicsStateGuardian7:: bind_light(DirectionalLight *light, int light_id) { // Get the light in "world coordinates". This means the light in // the coordinate space of the camera, converted to DX's coordinate @@ -4308,14 +4083,14 @@ bind_light(DirectionalLight *light, int light_id) { } //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::bind_light +// Function: DXGraphicsStateGuardian7::bind_light // Access: Public, Virtual // Description: Called the first time a particular light has been // bound to a given id within a frame, this should set // up the associated hardware light with the light's // properties. //////////////////////////////////////////////////////////////////// -void DXGraphicsStateGuardian:: +void DXGraphicsStateGuardian7:: bind_light(Spotlight *light, int light_id) { Lens *lens = light->get_lens(); nassertv(lens != (Lens *)NULL); @@ -4357,233 +4132,110 @@ bind_light(Spotlight *light, int light_id) { HRESULT res = scrn.pD3DDevice->SetLight(light_id, &alight); } -// Note: default gsg begin_frame() now calls start_rendering() -void DXGraphicsStateGuardian:: -start_rendering(void) { - HRESULT hr = scrn.pD3DDevice->BeginScene(); - - if(FAILED(hr)) { - if((hr==DDERR_SURFACELOST)||(hr==DDERR_SURFACEBUSY)) { - if(dxgsg_cat.is_debug()) - dxgsg_cat.debug() << "BeginScene returns " << ConvD3DErrorToString(hr) << endl; - - CheckCooperativeLevel(); - } else { - dxgsg_cat.error() << "BeginScene failed, unhandled error hr == " << ConvD3DErrorToString(hr) << endl; - exit(1); - } - return; - } -} - -void DXGraphicsStateGuardian:: -finish_rendering(void) { - HRESULT hr = scrn.pD3DDevice->EndScene(); - - if(FAILED(hr)) { - if((hr==DDERR_SURFACELOST)||(hr==DDERR_SURFACEBUSY)) { - if(dxgsg_cat.is_debug()) - dxgsg_cat.debug() << "EndScene returns " << ConvD3DErrorToString(hr) << endl; - - CheckCooperativeLevel(); - } else { - dxgsg_cat.error() << "EndScene failed, unhandled error hr == " << ConvD3DErrorToString(hr) << endl; - exit(1); - } - return; - } +//////////////////////////////////////////////////////////////////// +// Function: DXGraphicsStateGuardian7::begin_frame +// Access: Public, Virtual +// Description: Called before each frame is rendered, to allow the +// GSG a chance to do any internal cleanup before +// beginning the frame. +// +// The return value is true if successful (in which case +// the frame will be drawn and end_frame() will be +// called later), or false if unsuccessful (in which +// case nothing will be drawn and end_frame() will not +// be called). +//////////////////////////////////////////////////////////////////// +bool DXGraphicsStateGuardian7:: +begin_frame() { + return GraphicsStateGuardian::begin_frame(); } //////////////////////////////////////////////////////////////////// -// Function: GraphicsStateGuardian::end_frame +// Function: DXGraphicsStateGuardian7::begin_scene +// Access: Public, Virtual +// Description: Called between begin_frame() and end_frame() to mark +// the beginning of drawing commands for a "scene" +// (usually a particular DisplayRegion) within a frame. +// All 3-D drawing commands, except the clear operation, +// must be enclosed within begin_scene() .. end_scene(). +// +// The return value is true if successful (in which case +// the scene will be drawn and end_scene() will be +// called later), or false if unsuccessful (in which +// case nothing will be drawn and end_scene() will not +// be called). +//////////////////////////////////////////////////////////////////// +bool DXGraphicsStateGuardian7:: +begin_scene() { + if (!GraphicsStateGuardian::begin_scene()) { + return false; + } + + HRESULT hr = scrn.pD3DDevice->BeginScene(); + + if (FAILED(hr)) { + if ((hr == DDERR_SURFACELOST) || (hr == DDERR_SURFACEBUSY)) { + if (dxgsg7_cat.is_debug()) { + dxgsg7_cat.debug() + << "BeginScene returns " << ConvD3DErrorToString(hr) << endl; + } + + CheckCooperativeLevel(); + + } else { + dxgsg7_cat.error() + << "BeginScene failed, unhandled error hr == " + << ConvD3DErrorToString(hr) << endl; + exit(1); + } + return false; + } + + return true; +} + +//////////////////////////////////////////////////////////////////// +// Function: DXGraphicsStateGuardian7::end_scene +// Access: Public, Virtual +// Description: Called between begin_frame() and end_frame() to mark +// the end of drawing commands for a "scene" (usually a +// particular DisplayRegion) within a frame. All 3-D +// drawing commands, except the clear operation, must be +// enclosed within begin_scene() .. end_scene(). +//////////////////////////////////////////////////////////////////// +void DXGraphicsStateGuardian7:: +end_scene() { + HRESULT hr = scrn.pD3DDevice->EndScene(); + + if (FAILED(hr)) { + if ((hr == DDERR_SURFACELOST) || (hr == DDERR_SURFACEBUSY)) { + if (dxgsg7_cat.is_debug()) { + dxgsg7_cat.debug() + << "EndScene returns " << ConvD3DErrorToString(hr) << endl; + } + + CheckCooperativeLevel(); + + } else { + dxgsg7_cat.error() + << "EndScene failed, unhandled error hr == " + << ConvD3DErrorToString(hr) << endl; + exit(1); + } + } + + GraphicsStateGuardian::end_scene(); +} + +//////////////////////////////////////////////////////////////////// +// Function: DXGraphicsStateGuardian7::end_frame // Access: Public, Virtual // Description: Called after each frame is rendered, to allow the // GSG a chance to do any internal cleanup after // rendering the frame, and before the window flips. //////////////////////////////////////////////////////////////////// -void DXGraphicsStateGuardian:: +void DXGraphicsStateGuardian7:: end_frame() { - HRESULT hr; - - // draw new tri-based FPS meter - if (_bShowFPSMeter) { - DO_PSTATS_STUFF(PStatTimer timer(_win->_show_fps_pcollector)); - // compute and write new texture indices here - - char fps_msg[15]; - sprintf(fps_msg, "%6.02f fps", _current_fps); // 6 == NUM_FPSMETER_LETTERS - -#define WRITE_FPS_UV(u,v) {*fltptr=(u); fltptr[1]=(v); fltptr= (float*)(((BYTE*)fltptr)+_fps_vertexsize);} - float u_FPSMETER_LETTER_WIDTH = _fps_u_usedwidth/(float)FPSMETER_NUMFONTLETTERS; - - // write out texcoords - float *fltptr = (float*)_fpsmeter_verts; - fltptr+=5; // skip over 1st XYZ,RHW, and colr (5 DWORDs) - - for(DWORD c=0;c'9'))) { - uval1=0.0f; uval2=0.0f; vval2=0.0f; - } - - WRITE_FPS_UV(uval1,0.0f); - WRITE_FPS_UV(uval1,vval2); - WRITE_FPS_UV(uval2,vval2); - - WRITE_FPS_UV(uval2,vval2); - WRITE_FPS_UV(uval2,0.0f); - WRITE_FPS_UV(uval1,0.0f); - } - - // dont have to muck with World Transform since D3DFVF_XYZRHW type bypasses it - // Just deals with current ProjectMat tho - - // is this blending fn expensive? if so, can just overwrite everything - - // could a state-block be used here instead? definitely to set up, but to restore? -#ifdef MAKE_FPSMETER_TRANSPARENT - call_dxBlendFunc(D3DBLEND_SRCALPHA, D3DBLEND_INVSRCALPHA); - if(!_blend_enabled) - scrn.pD3DDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, true); -#else - if(_blend_enabled) - scrn.pD3DDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, false); -#endif - - if (_CurShadeMode != D3DSHADE_FLAT) { - scrn.pD3DDevice->SetRenderState(D3DRENDERSTATE_SHADEMODE, D3DSHADE_FLAT); - } - - DWORD saved_zfunc; - scrn.pD3DDevice->GetRenderState(D3DRENDERSTATE_ZFUNC,&saved_zfunc); - scrn.pD3DDevice->SetRenderState(D3DRENDERSTATE_ZFUNC,D3DCMP_ALWAYS); - - DWORD saved_fill_state; - if(_current_fill_mode != RenderModeAttrib::M_filled) { - scrn.pD3DDevice->GetRenderState(D3DRENDERSTATE_FILLMODE, &saved_fill_state); - scrn.pD3DDevice->SetRenderState(D3DRENDERSTATE_FILLMODE, D3DFILL_SOLID); - } - - - DWORD saved_clipping_state,saved_cull_state; - scrn.pD3DDevice->GetRenderState(D3DRENDERSTATE_CULLMODE, &saved_cull_state); - scrn.pD3DDevice->SetRenderState(D3DRENDERSTATE_CULLMODE, D3DCULL_NONE); - - scrn.pD3DDevice->GetRenderState(D3DRENDERSTATE_CLIPPING, &saved_clipping_state); - scrn.pD3DDevice->SetRenderState(D3DRENDERSTATE_CLIPPING, false); - - // ignore lighting state since verts are post-xform - - DWORD saved_magfilter,saved_minfilter,saved_mipfilter; - DWORD saved_colorop,saved_alphaop,saved_colorarg1,saved_alphaarg1; - LPDIRECTDRAWSURFACE7 saved_tex_surf=NULL; - - scrn.pD3DDevice->GetTextureStageState(0, D3DTSS_MAGFILTER, &saved_magfilter); - scrn.pD3DDevice->GetTextureStageState(0, D3DTSS_MINFILTER, &saved_minfilter); - scrn.pD3DDevice->GetTextureStageState(0, D3DTSS_MIPFILTER, &saved_mipfilter); - scrn.pD3DDevice->GetTextureStageState( 0, D3DTSS_COLOROP, &saved_colorop); - scrn.pD3DDevice->GetTextureStageState( 0, D3DTSS_COLORARG1, &saved_colorarg1); - scrn.pD3DDevice->GetTextureStageState( 0, D3DTSS_ALPHAOP, &saved_alphaop); - scrn.pD3DDevice->GetTextureStageState( 0, D3DTSS_ALPHAARG1, &saved_alphaarg1); - - if(saved_mipfilter!= D3DTFP_NONE) - scrn.pD3DDevice->SetTextureStageState(0, D3DTSS_MIPFILTER, D3DTFP_NONE); - -#define FPS_TEXFILTER(X) D3D##X##_POINT - - if(saved_minfilter!=FPS_TEXFILTER(TFN)) - scrn.pD3DDevice->SetTextureStageState(0, D3DTSS_MINFILTER, FPS_TEXFILTER(TFN)); - if(saved_magfilter!= FPS_TEXFILTER(TFG)) - scrn.pD3DDevice->SetTextureStageState(0, D3DTSS_MAGFILTER, FPS_TEXFILTER(TFG)); - - if(saved_colorop!=D3DTOP_SELECTARG1) - scrn.pD3DDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1); - if(saved_colorarg1!=D3DTA_TEXTURE) - scrn.pD3DDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE ); - if(saved_alphaop!=D3DTOP_SELECTARG1) - scrn.pD3DDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); - if(saved_alphaarg1!=D3DTA_TEXTURE) - scrn.pD3DDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE ); - - hr = scrn.pD3DDevice->SetTexture(0, _fpsmeter_font_surf); - if(FAILED(hr)) { - dxgsg_cat.error() << "SetTexture failed in draw fps meter, result = " << ConvD3DErrorToString(hr) << endl; - exit(1); - } - - DWORD nVerts = (NUM_FPSMETER_LETTERS+1)*2*3; // +1 for suffix square - hr = scrn.pD3DDevice->DrawPrimitive(D3DPT_TRIANGLELIST, _fpsmeter_fvfflags, _fpsmeter_verts, nVerts, NULL); - TestDrawPrimFailure(DrawPrim,hr,scrn.pDD,NUM_FPSMETER_LETTERS*2,0); - -#ifdef MAKE_FPSMETER_TRANSPARENT - if(!_blend_enabled) - scrn.pD3DDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, false); -#else - if(_blend_enabled) - scrn.pD3DDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, true); -#endif - - scrn.pD3DDevice->SetRenderState(D3DRENDERSTATE_ZFUNC, saved_zfunc); - - scrn.pD3DDevice->SetRenderState(D3DRENDERSTATE_CLIPPING, saved_clipping_state); - scrn.pD3DDevice->SetRenderState(D3DRENDERSTATE_CULLMODE, saved_cull_state); - - scrn.pD3DDevice->SetTextureStageState(0, D3DTSS_MAGFILTER, saved_magfilter); - scrn.pD3DDevice->SetTextureStageState(0, D3DTSS_MINFILTER, saved_minfilter); - scrn.pD3DDevice->SetTextureStageState(0, D3DTSS_MIPFILTER, saved_mipfilter); - scrn.pD3DDevice->SetTextureStageState( 0, D3DTSS_COLOROP, saved_colorop); - scrn.pD3DDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, saved_colorarg1); - scrn.pD3DDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, saved_alphaop); - scrn.pD3DDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG1, saved_alphaarg1); - - if (_CurShadeMode != D3DSHADE_FLAT) { - scrn.pD3DDevice->SetRenderState(D3DRENDERSTATE_SHADEMODE, _CurShadeMode); - } - - if(_current_fill_mode != RenderModeAttrib::M_filled) { - scrn.pD3DDevice->SetRenderState(D3DRENDERSTATE_FILLMODE, saved_fill_state); - } - - scrn.pD3DDevice->SetTexture(0, ((_pCurTexContext != NULL) ? _pCurTexContext->_surface : NULL)); - } - - DXGraphicsStateGuardian::finish_rendering(); - - // any GDI operations (which are mega-slow per-frame) MUST occur after EndScene - - if(_bShowFPSMeter) { - DO_PSTATS_STUFF(PStatTimer timer(_win->_show_fps_pcollector)); - - DWORD now = timeGetTime(); // this is win32 fn - - float time_delta = (now - _start_time) * 0.001f; - - if(time_delta > dx_fps_meter_update_interval) { - // didnt use global clock object, it wasnt working properly when I tried, - // its probably slower due to cache faults, and I can easily track all the - // info I need in dxgsg - DWORD num_frames = _cur_frame_count - _start_frame_count; - - _current_fps = num_frames / time_delta; - _start_time = now; - _start_frame_count = _cur_frame_count; - } - - _cur_frame_count++; // only used by fps meter right now - } - - show_frame(); - #ifdef COUNT_DRAWPRIMS { #define FRAMES_PER_DPINFO 90 @@ -4606,7 +4258,7 @@ end_frame() { float DrawPrims_per_Geom = cDPcount/(float)cGeomcount; float verts_per_Geom = cVertcount/(float)cGeomcount; - dxgsg_cat.debug() << "===================================" + dxgsg7_cat.debug() << "===================================" << "\n Avg Verts/sec:\t\t" << verts_per_sec << "\n Avg Tris/sec:\t\t" << tris_per_sec << "\n Avg Verts/frame:\t" << verts_per_frame @@ -4649,41 +4301,41 @@ end_frame() { } //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::wants_normals +// Function: DXGraphicsStateGuardian7::wants_normals // Access: Public, Virtual // Description: //////////////////////////////////////////////////////////////////// -INLINE bool DXGraphicsStateGuardian:: +INLINE bool DXGraphicsStateGuardian7:: wants_normals() const { return (_lighting_enabled || _normals_enabled); } //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::wants_texcoords +// Function: DXGraphicsStateGuardian7::wants_texcoords // Access: Public, Virtual // Description: //////////////////////////////////////////////////////////////////// -INLINE bool DXGraphicsStateGuardian:: +INLINE bool DXGraphicsStateGuardian7:: wants_texcoords() const { return _texturing_enabled; } //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::depth_offset_decals +// Function: DXGraphicsStateGuardian7::depth_offset_decals // Access: Public, Virtual // Description: Returns true if this GSG can implement decals using a // DepthOffsetAttrib, or false if that is unreliable // and the three-step rendering process should be used // instead. //////////////////////////////////////////////////////////////////// -bool DXGraphicsStateGuardian:: +bool DXGraphicsStateGuardian7:: depth_offset_decals() { return dx_depth_offset_decals; } //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::get_internal_coordinate_system +// Function: DXGraphicsStateGuardian7::get_internal_coordinate_system // Access: Public, Virtual // Description: Should be overridden by derived classes to return the // coordinate system used internally by the GSG, if any @@ -4695,22 +4347,22 @@ depth_offset_decals() { // GraphicsEngine will automatically convert all // transforms into the indicated coordinate system. //////////////////////////////////////////////////////////////////// -CoordinateSystem DXGraphicsStateGuardian:: +CoordinateSystem DXGraphicsStateGuardian7:: get_internal_coordinate_system() const { return CS_yup_left; } //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::compute_distance_to +// Function: DXGraphicsStateGuardian7::compute_distance_to // Access: Public, Virtual // Description: This function may only be called during a render // traversal; it will compute the distance to the // indicated point, assumed to be in modelview // coordinates, from the camera plane. //////////////////////////////////////////////////////////////////// -INLINE float DXGraphicsStateGuardian:: +INLINE float DXGraphicsStateGuardian7:: compute_distance_to(const LPoint3f &point) const { - // In the case of a DXGraphicsStateGuardian, we know that the + // In the case of a DXGraphicsStateGuardian7, we know that the // modelview matrix already includes the relative transform from the // camera, as well as a to-y-up conversion. Thus, the distance to // the camera plane is simply the +z distance. (negative of gl compute_distance_to, @@ -4720,16 +4372,16 @@ compute_distance_to(const LPoint3f &point) const { } //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::set_draw_buffer +// Function: DXGraphicsStateGuardian7::set_draw_buffer // Access: Protected // Description: Sets up the glDrawBuffer to render into the buffer // indicated by the RenderBuffer object. This only sets // up the color bits; it does not affect the depth, // stencil, accum layers. //////////////////////////////////////////////////////////////////// -void DXGraphicsStateGuardian:: +void DXGraphicsStateGuardian7:: set_draw_buffer(const RenderBuffer &rb) { - dxgsg_cat.fatal() << "DX set_draw_buffer unimplemented!!!"; + dxgsg7_cat.fatal() << "DX set_draw_buffer unimplemented!!!"; return; #ifdef WBD_GL_MODE @@ -4773,11 +4425,11 @@ set_draw_buffer(const RenderBuffer &rb) { } //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::set_read_buffer +// Function: DXGraphicsStateGuardian7::set_read_buffer // Access: Protected // Description: Vestigial analog of glReadBuffer //////////////////////////////////////////////////////////////////// -void DXGraphicsStateGuardian:: +void DXGraphicsStateGuardian7:: set_read_buffer(const RenderBuffer &rb) { if(rb._buffer_type & RenderBuffer::T_front) { @@ -4785,25 +4437,25 @@ set_read_buffer(const RenderBuffer &rb) { } else if(rb._buffer_type & RenderBuffer::T_back) { _cur_read_pixel_buffer=RenderBuffer::T_back; } else { - dxgsg_cat.error() << "Invalid or unimplemented Argument to set_read_buffer!\n"; + dxgsg7_cat.error() << "Invalid or unimplemented Argument to set_read_buffer!\n"; } return; } //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::get_texture_wrap_mode +// Function: DXGraphicsStateGuardian7::get_texture_wrap_mode // Access: Protected // Description: Maps from the Texture's internal wrap mode symbols to // GL's. //////////////////////////////////////////////////////////////////// -INLINE D3DTEXTUREADDRESS DXGraphicsStateGuardian:: +INLINE D3DTEXTUREADDRESS DXGraphicsStateGuardian7:: get_texture_wrap_mode(Texture::WrapMode wm) const { if (wm == Texture::WM_clamp) return D3DTADDRESS_CLAMP; else if (wm != Texture::WM_repeat) { #ifdef _DEBUG - dxgsg_cat.error() << "Invalid or Unimplemented Texture::WrapMode value!\n"; + dxgsg7_cat.error() << "Invalid or Unimplemented Texture::WrapMode value!\n"; #endif } @@ -4811,11 +4463,11 @@ get_texture_wrap_mode(Texture::WrapMode wm) const { } //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::get_fog_mode_type +// Function: DXGraphicsStateGuardian7::get_fog_mode_type // Access: Protected // Description: Maps from the fog types to gl version //////////////////////////////////////////////////////////////////// -INLINE D3DFOGMODE DXGraphicsStateGuardian:: +INLINE D3DFOGMODE DXGraphicsStateGuardian7:: get_fog_mode_type(Fog::Mode m) const { switch (m) { case Fog::M_linear: @@ -4825,56 +4477,56 @@ get_fog_mode_type(Fog::Mode m) const { case Fog::M_exponential_squared: return D3DFOG_EXP2; } - dxgsg_cat.error() << "Invalid Fog::Mode value" << endl; + dxgsg7_cat.error() << "Invalid Fog::Mode value" << endl; return D3DFOG_EXP; } //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::enable_lighting +// Function: DXGraphicsStateGuardian7::enable_lighting // Access: Protected, Virtual // Description: Intended to be overridden by a derived class to // enable or disable the use of lighting overall. This // is called by issue_light() according to whether any // lights are in use or not. //////////////////////////////////////////////////////////////////// -void DXGraphicsStateGuardian:: +void DXGraphicsStateGuardian7:: enable_lighting(bool enable) { scrn.pD3DDevice->SetRenderState(D3DRENDERSTATE_LIGHTING, (DWORD)enable); } //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::set_ambient_light +// Function: DXGraphicsStateGuardian7::set_ambient_light // Access: Protected, Virtual // Description: Intended to be overridden by a derived class to // indicate the color of the ambient light that should // be in effect. This is called by issue_light() after // all other lights have been enabled or disabled. //////////////////////////////////////////////////////////////////// -void DXGraphicsStateGuardian:: +void DXGraphicsStateGuardian7:: set_ambient_light(const Colorf &color) { scrn.pD3DDevice->SetRenderState(D3DRENDERSTATE_AMBIENT, Colorf_to_D3DCOLOR(color)); } //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::enable_light +// Function: DXGraphicsStateGuardian7::enable_light // Access: Protected, Virtual // Description: Intended to be overridden by a derived class to // enable the indicated light id. A specific Light will // already have been bound to this id via bind_light(). //////////////////////////////////////////////////////////////////// -void DXGraphicsStateGuardian:: +void DXGraphicsStateGuardian7:: enable_light(int light_id, bool enable) { HRESULT res = scrn.pD3DDevice->LightEnable(light_id, enable); #ifdef GSG_VERBOSE - dxgsg_cat.debug() - << "LightEnable(" << light << "=" << val << ")" << endl; + dxgsg7_cat.debug() + << "LightEnable(" << light_id << "=" << enable << ")" << endl; #endif } //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::slot_new_clip_plane +// Function: DXGraphicsStateGuardian7::slot_new_clip_plane // Access: Protected, Virtual // Description: This will be called by the base class before a // particular clip plane id will be used for the first @@ -4887,20 +4539,20 @@ enable_light(int light_id, bool enable) { // The return value should be true if the additional // plane is supported, or false if it is not. //////////////////////////////////////////////////////////////////// -bool DXGraphicsStateGuardian:: +bool DXGraphicsStateGuardian7:: slot_new_clip_plane(int plane_id) { return (plane_id < D3DMAXUSERCLIPPLANES); } //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::enable_clip_plane +// Function: DXGraphicsStateGuardian7::enable_clip_plane // Access: Protected, Virtual // Description: Intended to be overridden by a derived class to // enable the indicated clip_plane id. A specific // PlaneNode will already have been bound to this id via // bind_clip_plane(). //////////////////////////////////////////////////////////////////// -INLINE void DXGraphicsStateGuardian:: +INLINE void DXGraphicsStateGuardian7:: enable_clip_plane(int plane_id, bool enable) { assert(plane_id < D3DMAXUSERCLIPPLANES); @@ -4915,14 +4567,14 @@ enable_clip_plane(int plane_id, bool enable) { } //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::bind_clip_plane +// Function: DXGraphicsStateGuardian7::bind_clip_plane // Access: Protected, Virtual // Description: Called the first time a particular clip_plane has been // bound to a given id within a frame, this should set // up the associated hardware clip_plane with the clip_plane's // properties. //////////////////////////////////////////////////////////////////// -void DXGraphicsStateGuardian:: +void DXGraphicsStateGuardian7:: bind_clip_plane(PlaneNode *plane, int plane_id) { // Get the plane in "world coordinates". This means the plane in // the coordinate space of the camera, converted to DX's coordinate @@ -4936,14 +4588,14 @@ bind_clip_plane(PlaneNode *plane, int plane_id) { } //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::set_blend_mode +// Function: DXGraphicsStateGuardian7::set_blend_mode // Access: Protected, Virtual // Description: Called after any of these three blending states have // changed; this function is responsible for setting the // appropriate color blending mode based on the given // properties. //////////////////////////////////////////////////////////////////// -void DXGraphicsStateGuardian:: +void DXGraphicsStateGuardian7:: set_blend_mode(ColorWriteAttrib::Mode color_write_mode, ColorBlendAttrib::Mode color_blend_mode, TransparencyAttrib::Mode transparency_mode) { @@ -4977,7 +4629,7 @@ set_blend_mode(ColorWriteAttrib::Mode color_write_mode, return; default: - dxgsg_cat.error() + dxgsg7_cat.error() << "Unknown color blend mode " << (int)color_blend_mode << endl; break; } @@ -4998,7 +4650,7 @@ set_blend_mode(ColorWriteAttrib::Mode color_write_mode, return; default: - dxgsg_cat.error() + dxgsg7_cat.error() << "invalid transparency mode " << (int)transparency_mode << endl; break; } @@ -5008,12 +4660,12 @@ set_blend_mode(ColorWriteAttrib::Mode color_write_mode, } //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::free_pointers +// Function: DXGraphicsStateGuardian7::free_pointers // Access: Public // Description: Frees some memory that was explicitly allocated -// within the dxgsg. +// within the dxgsg7. //////////////////////////////////////////////////////////////////// -void DXGraphicsStateGuardian:: +void DXGraphicsStateGuardian7:: free_pointers() { #ifdef USE_TEXFMTVEC scrn.TexPixFmts.clear(); @@ -5023,15 +4675,10 @@ free_pointers() { _pTexPixFmts = NULL; } #endif - - if(_fpsmeter_verts!=NULL) { - delete [] _fpsmeter_verts; - _fpsmeter_verts = NULL; - } } //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::save_frame_buffer +// Function: DXGraphicsStateGuardian7::save_frame_buffer // Access: Public // Description: Saves the indicated planes of the frame buffer // (within the indicated display region) and returns it @@ -5040,15 +4687,15 @@ free_pointers() { // function for push_frame_buffer() and // pop_frame_buffer(). //////////////////////////////////////////////////////////////////// -PT(SavedFrameBuffer) DXGraphicsStateGuardian:: +PT(SavedFrameBuffer) DXGraphicsStateGuardian7:: save_frame_buffer(const RenderBuffer &buffer, CPT(DisplayRegion) dr) { - dxgsg_cat.error() << "save_frame_buffer unimplemented!!\n"; + dxgsg7_cat.error() << "save_frame_buffer unimplemented!!\n"; return NULL; #if 0 - DXSavedFrameBuffer *sfb = new DXSavedFrameBuffer(buffer, dr); + DXSavedFrameBuffer7 *sfb = new DXSavedFrameBuffer7(buffer, dr); if (buffer._buffer_type & RenderBuffer::T_depth) { // Save the depth buffer. @@ -5069,42 +4716,42 @@ save_frame_buffer(const RenderBuffer &buffer, } //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::restore_frame_buffer +// Function: DXGraphicsStateGuardian7::restore_frame_buffer // Access: Public // Description: Restores the frame buffer that was previously saved. //////////////////////////////////////////////////////////////////// -void DXGraphicsStateGuardian:: +void DXGraphicsStateGuardian7:: restore_frame_buffer(SavedFrameBuffer *frame_buffer) { - dxgsg_cat.error() << "restore_frame_buffer unimplemented!!\n"; + dxgsg7_cat.error() << "restore_frame_buffer unimplemented!!\n"; return; } // factory and type stuff -GraphicsStateGuardian *DXGraphicsStateGuardian:: +GraphicsStateGuardian *DXGraphicsStateGuardian7:: make_DXGraphicsStateGuardian(const FactoryParams ¶ms) { GraphicsStateGuardian::GsgWindow *win_param; if (!get_param_into(win_param, params)) { - dxgsg_cat.error() + dxgsg7_cat.error() << "No window specified for gsg creation!" << endl; return NULL; } GraphicsWindow *win = win_param->get_window(); - return new DXGraphicsStateGuardian(win); + return new DXGraphicsStateGuardian7(win); } -TypeHandle DXGraphicsStateGuardian::get_type(void) const { +TypeHandle DXGraphicsStateGuardian7::get_type(void) const { return get_class_type(); } -TypeHandle DXGraphicsStateGuardian::get_class_type(void) { +TypeHandle DXGraphicsStateGuardian7::get_class_type(void) { return _type_handle; } -void DXGraphicsStateGuardian::init_type(void) { +void DXGraphicsStateGuardian7::init_type(void) { GraphicsStateGuardian::init_type(); - register_type(_type_handle, "DXGraphicsStateGuardian", + register_type(_type_handle, "DXGraphicsStateGuardian7", GraphicsStateGuardian::get_class_type()); } @@ -5112,12 +4759,12 @@ void DXGraphicsStateGuardian::init_type(void) { // Function: dx_cleanup // Description: Clean up the DirectX environment. //////////////////////////////////////////////////////////////////// -void DXGraphicsStateGuardian:: +void DXGraphicsStateGuardian7:: dx_cleanup(bool bRestoreDisplayMode,bool bAtExitFnCalled) { static bool bAtExitFnEverCalled=false; - if(dxgsg_cat.is_spam()) { - dxgsg_cat.spam() << "dx_cleanup called, bAtExitFnCalled=" << bAtExitFnCalled << ", bAtExitFnEverCalled=" << bAtExitFnEverCalled << endl; + if(dxgsg7_cat.is_spam()) { + dxgsg7_cat.spam() << "dx_cleanup called, bAtExitFnCalled=" << bAtExitFnCalled << ", bAtExitFnEverCalled=" << bAtExitFnEverCalled << endl; } bAtExitFnEverCalled = (bAtExitFnEverCalled || bAtExitFnCalled); @@ -5146,28 +4793,24 @@ dx_cleanup(bool bRestoreDisplayMode,bool bAtExitFnCalled) { // if we're called from exit(), scrn.pD3DDevice may already have been released if (scrn.pD3DDevice!=NULL) { scrn.pD3DDevice->SetTexture(0,NULL); // should release this stuff internally anyway - RELEASE(scrn.pD3DDevice,dxgsg,"d3dDevice",RELEASE_DOWN_TO_ZERO); + RELEASE(scrn.pD3DDevice,dxgsg7,"d3dDevice",RELEASE_DOWN_TO_ZERO); } PRINTREFCNT(scrn.pDD,"after d3ddevice release IDirectDraw7"); - RELEASE(_fpsmeter_font_surf,dxgsg,"fpsmeter fontsurf",false); - - PRINTREFCNT(scrn.pDD,"after fpsfont release IDirectDraw7"); - if((scrn.pddsBack!=NULL)&&(scrn.pddsZBuf!=NULL)) scrn.pddsBack->DeleteAttachedSurface(0x0,scrn.pddsZBuf); // Release the DDraw and D3D objects used by the app - RELEASE(scrn.pddsZBuf,dxgsg,"zbuffer",false); + RELEASE(scrn.pddsZBuf,dxgsg7,"zbuffer",false); PRINTREFCNT(scrn.pDD,"before releasing d3d obj, IDirectDraw7"); - RELEASE(scrn.pD3D,dxgsg,"IDirect3D7 scrn.pD3D",false); //RELEASE_DOWN_TO_ZERO); + RELEASE(scrn.pD3D,dxgsg7,"IDirect3D7 scrn.pD3D",false); //RELEASE_DOWN_TO_ZERO); PRINTREFCNT(scrn.pDD,"after releasing d3d obj, IDirectDraw7"); // is it wrong to explictly release scrn.pddsBack if it is part of complex surface chain (as in fullscrn mode)? - RELEASE(scrn.pddsBack,dxgsg,"backbuffer",false); - RELEASE(scrn.pddsPrimary,dxgsg,"primary surface",false); + RELEASE(scrn.pddsBack,dxgsg7,"backbuffer",false); + RELEASE(scrn.pddsPrimary,dxgsg7,"primary surface",false); PRINTREFCNT(scrn.pDD,"after releasing all surfs, IDirectDraw7"); } @@ -5178,10 +4821,10 @@ dx_cleanup(bool bRestoreDisplayMode,bool bAtExitFnCalled) { if (scrn.pDD!=NULL) { if(bRestoreDisplayMode) { HRESULT hr = scrn.pDD->RestoreDisplayMode(); - if(dxgsg_cat.is_spam()) - dxgsg_cat.spam() << "dx_cleanup - Restoring original desktop DisplayMode\n"; + if(dxgsg7_cat.is_spam()) + dxgsg7_cat.spam() << "dx_cleanup - Restoring original desktop DisplayMode\n"; if(FAILED(hr)) { - dxgsg_cat.error() << "dx_cleanup - RestoreDisplayMode failed, hr = " << ConvD3DErrorToString(hr) << endl; + dxgsg7_cat.error() << "dx_cleanup - RestoreDisplayMode failed, hr = " << ConvD3DErrorToString(hr) << endl; } } @@ -5189,14 +4832,14 @@ dx_cleanup(bool bRestoreDisplayMode,bool bAtExitFnCalled) { // if exit() called, there is definitely no more need for the IDDraw object, // so we can make sure it's fully released // note currently this is never called - RELEASE(scrn.pDD,dxgsg,"IDirectDraw7 scrn.pDD", RELEASE_DOWN_TO_ZERO); + RELEASE(scrn.pDD,dxgsg7,"IDirectDraw7 scrn.pDD", RELEASE_DOWN_TO_ZERO); } else { // seems wrong to release to zero, since it might be being used somewhere else? - RELEASE(scrn.pDD,dxgsg,"IDirectDraw7 scrn.pDD", false); + RELEASE(scrn.pDD,dxgsg7,"IDirectDraw7 scrn.pDD", false); if(refcnt>0) { - if(dxgsg_cat.is_spam()) - dxgsg_cat.debug() << "dx_cleanup - warning IDDraw7 refcnt = " << refcnt << ", should be zero!\n"; + if(dxgsg7_cat.is_spam()) + dxgsg7_cat.debug() << "dx_cleanup - warning IDDraw7 refcnt = " << refcnt << ", should be zero!\n"; } } } @@ -5206,7 +4849,7 @@ dx_cleanup(bool bRestoreDisplayMode,bool bAtExitFnCalled) { // Function: dx_setup_after_resize // Description: Recreate the back buffer and zbuffers at the new size //////////////////////////////////////////////////////////////////// -void DXGraphicsStateGuardian:: +void DXGraphicsStateGuardian7:: dx_setup_after_resize(RECT viewrect, HWND mwindow) { if (scrn.pddsBack == NULL) // nothing created yet return; @@ -5225,9 +4868,9 @@ dx_setup_after_resize(RECT viewrect, HWND mwindow) { if((scrn.pddsBack!=NULL)&&(scrn.pddsZBuf!=NULL)) scrn.pddsBack->DeleteAttachedSurface(0x0,scrn.pddsZBuf); - RELEASE(scrn.pddsZBuf,dxgsg,"zbuffer",false); - RELEASE(scrn.pddsBack,dxgsg,"backbuffer",false); - RELEASE(scrn.pddsPrimary,dxgsg,"primary surface",false); + RELEASE(scrn.pddsZBuf,dxgsg7,"zbuffer",false); + RELEASE(scrn.pddsBack,dxgsg7,"backbuffer",false); + RELEASE(scrn.pddsPrimary,dxgsg7,"primary surface",false); assert((scrn.pddsPrimary == NULL) && (scrn.pddsBack == NULL) && (scrn.pddsZBuf == NULL)); scrn.view_rect = viewrect; @@ -5247,17 +4890,17 @@ dx_setup_after_resize(RECT viewrect, HWND mwindow) { HRESULT hr; if (FAILED(hr = scrn.pDD->CreateSurface( &ddsd, &scrn.pddsPrimary, NULL ))) { - dxgsg_cat.fatal() << "resize() - CreateSurface failed for primary : result = " << ConvD3DErrorToString(hr) << endl; + dxgsg7_cat.fatal() << "resize() - CreateSurface failed for primary : result = " << ConvD3DErrorToString(hr) << endl; exit(1); } - if(!dx_full_screen) { + if (!_win->is_fullscreen()) { // Create a clipper object which handles all our clipping for cases when // our window is partially obscured by other windows. LPDIRECTDRAWCLIPPER Clipper; if (FAILED(hr = scrn.pDD->CreateClipper( 0, &Clipper, NULL ))) { - dxgsg_cat.fatal() + dxgsg7_cat.fatal() << "CreateClipper after resize failed : result = " << ConvD3DErrorToString(hr) << endl; exit(1); } @@ -5269,7 +4912,8 @@ dx_setup_after_resize(RECT viewrect, HWND mwindow) { Clipper->Release(); } - // Recreate the backbuffer. (might want to handle failure due to running out of video memory) + // Recreate the backbuffer. (might want to handle failure due to + // running out of video memory) ddsd_back.dwFlags |= DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS; // just to make sure ddsd_back.ddsCaps.dwCaps |= DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE; @@ -5277,7 +4921,7 @@ dx_setup_after_resize(RECT viewrect, HWND mwindow) { PRINTVIDMEM(scrn.pDD,&ddsd_back.ddsCaps,"resize backbuffer surf"); if (FAILED(hr = scrn.pDD->CreateSurface( &ddsd_back, &scrn.pddsBack, NULL ))) { - dxgsg_cat.fatal() << "resize() - CreateSurface failed for backbuffer : result = " << ConvD3DErrorToString(hr) << endl; + dxgsg7_cat.fatal() << "resize() - CreateSurface failed for backbuffer : result = " << ConvD3DErrorToString(hr) << endl; exit(1); } @@ -5285,37 +4929,44 @@ dx_setup_after_resize(RECT viewrect, HWND mwindow) { // Recreate and attach a z-buffer. if (FAILED(hr = scrn.pDD->CreateSurface( &ddsd_zbuf, &scrn.pddsZBuf, NULL ))) { - dxgsg_cat.fatal() << "resize() - CreateSurface failed for Z buffer: result = " << ConvD3DErrorToString(hr) << endl; + dxgsg7_cat.fatal() << "resize() - CreateSurface failed for Z buffer: result = " << ConvD3DErrorToString(hr) << endl; exit(1); } // Attach the z-buffer to the back buffer. if ((hr = scrn.pddsBack->AddAttachedSurface( scrn.pddsZBuf ) ) != DD_OK) { - dxgsg_cat.fatal() << "resize() - AddAttachedSurface failed : result = " << ConvD3DErrorToString(hr) << endl; + dxgsg7_cat.fatal() << "resize() - AddAttachedSurface failed : result = " << ConvD3DErrorToString(hr) << endl; exit(1); } if ((hr = scrn.pD3DDevice->SetRenderTarget(scrn.pddsBack,0x0) ) != DD_OK) { - dxgsg_cat.fatal() << "resize() - SetRenderTarget failed : result = " << ConvD3DErrorToString(hr) << endl; + dxgsg7_cat.fatal() << "resize() - SetRenderTarget failed : result = " << ConvD3DErrorToString(hr) << endl; exit(1); } + // It doesn't seem necessary to create a new viewport for the + // window, since Panda creates a new viewport before rendering + // into each DisplayRegion. Creating this redundant viewport may + // just lead to confusion. + /* // Create the viewport - D3DVIEWPORT7 vp = { 0, 0, renderWid, renderHt, 0.0f, 1.0f}; + D3DVIEWPORT7 vp = { + 0, 0, + renderWid, renderHt, + 0.0f, 1.0f + }; hr = scrn.pD3DDevice->SetViewport( &vp ); if (hr != DD_OK) { - dxgsg_cat.fatal() + dxgsg7_cat.fatal() << "SetViewport failed : result = " << ConvD3DErrorToString(hr) << endl; exit(1); } - - if(_bShowFPSMeter) - SetFPSMeterPosition(scrn.view_rect); + */ } -bool refill_tex_callback(TextureContext *tc,void *void_dxgsg_ptr) { - DXTextureContext *dtc = DCAST(DXTextureContext, tc); -// DXGraphicsStateGuardian *dxgsg = (DXGraphicsStateGuardian *)void_dxgsg_ptr; not needed? +bool refill_tex_callback(TextureContext *tc,void *void_dxgsg7_ptr) { + DXTextureContext7 *dtc = DCAST(DXTextureContext7, tc); +// DXGraphicsStateGuardian7 *dxgsg7 = (DXGraphicsStateGuardian7 *)void_dxgsg7_ptr; not needed? // Re-fill the contents of textures and vertex buffers // which just got restored now. @@ -5323,60 +4974,55 @@ bool refill_tex_callback(TextureContext *tc,void *void_dxgsg_ptr) { return hr==S_OK; } -bool delete_tex_callback(TextureContext *tc,void *void_dxgsg_ptr) { - DXTextureContext *dtc = DCAST(DXTextureContext, tc); +bool delete_tex_callback(TextureContext *tc,void *void_dxgsg7_ptr) { + DXTextureContext7 *dtc = DCAST(DXTextureContext7, tc); // release DDSurf (but not the texture context) dtc->DeleteTexture(); return true; } -bool recreate_tex_callback(TextureContext *tc,void *void_dxgsg_ptr) { - DXTextureContext *dtc = DCAST(DXTextureContext, tc); - DXGraphicsStateGuardian *dxgsg = (DXGraphicsStateGuardian *)void_dxgsg_ptr; +bool recreate_tex_callback(TextureContext *tc,void *void_dxgsg7_ptr) { + DXTextureContext7 *dtc = DCAST(DXTextureContext7, tc); + DXGraphicsStateGuardian7 *dxgsg7 = (DXGraphicsStateGuardian7 *)void_dxgsg7_ptr; // Re-fill the contents of textures and vertex buffers // which just got restored now. LPDIRECTDRAWSURFACE7 ddtex = #ifdef USE_TEXFMTVEC - dtc->CreateTexture(dxgsg->scrn.pD3DDevice,scrn.TexPixFmts,&dxgsg->scrn.D3DDevDesc); + dtc->CreateTexture(dxgsg7->scrn.pD3DDevice,scrn.TexPixFmts,&dxgsg7->scrn.D3DDevDesc); #else - dtc->CreateTexture(dxgsg->scrn.pD3DDevice,dxgsg->_cNumTexPixFmts,dxgsg->_pTexPixFmts,&dxgsg->scrn.D3DDevDesc); + dtc->CreateTexture(dxgsg7->scrn.pD3DDevice,dxgsg7->_cNumTexPixFmts,dxgsg7->_pTexPixFmts,&dxgsg7->scrn.D3DDevDesc); #endif return ddtex!=NULL; } // release all textures and vertex/index buffers -HRESULT DXGraphicsStateGuardian::DeleteAllVideoSurfaces(void) { +HRESULT DXGraphicsStateGuardian7::DeleteAllVideoSurfaces(void) { // BUGBUG: need to handle vertexbuffer handling here // cant access template in libpanda.dll directly due to vc++ limitations, use traverser to get around it traverse_prepared_textures(delete_tex_callback,this); - ULONG refcnt; - - if(_bShowFPSMeter) - RELEASE(_fpsmeter_font_surf,dxgsg,"fpsmeter fontsurf",false); - - if(dxgsg_cat.is_debug()) - dxgsg_cat.debug() << "release of all textures complete\n"; + if(dxgsg7_cat.is_debug()) + dxgsg7_cat.debug() << "release of all textures complete\n"; return S_OK; } // recreate all textures and vertex/index buffers -HRESULT DXGraphicsStateGuardian::RecreateAllVideoSurfaces(void) { +HRESULT DXGraphicsStateGuardian7::RecreateAllVideoSurfaces(void) { // BUGBUG: need to handle vertexbuffer handling here // cant access template in libpanda.dll directly due to vc++ limitations, use traverser to get around it traverse_prepared_textures(recreate_tex_callback,this); - if(dxgsg_cat.is_debug()) - dxgsg_cat.debug() << "recreation of all textures complete\n"; + if(dxgsg7_cat.is_debug()) + dxgsg7_cat.debug() << "recreation of all textures complete\n"; return S_OK; } -HRESULT DXGraphicsStateGuardian::RestoreAllVideoSurfaces(void) { +HRESULT DXGraphicsStateGuardian7::RestoreAllVideoSurfaces(void) { // BUGBUG: this should also restore vertex buffer contents when they are implemented // You will need to destroy and recreate // optimized vertex buffers however, restoring is not enough. @@ -5386,18 +5032,15 @@ HRESULT DXGraphicsStateGuardian::RestoreAllVideoSurfaces(void) { // note: could go through and just restore surfs that return IsLost() true // apparently that isnt as reliable w/some drivers tho if (FAILED(hr = scrn.pDD->RestoreAllSurfaces() )) { - dxgsg_cat.fatal() << "RestoreAllSurfs failed : result = " << ConvD3DErrorToString(hr) << endl; + dxgsg7_cat.fatal() << "RestoreAllSurfs failed : result = " << ConvD3DErrorToString(hr) << endl; exit(1); } // cant access template in libpanda.dll directly due to vc++ limitations, use traverser to get around it traverse_prepared_textures(refill_tex_callback,this); - if(_bShowFPSMeter) - FillFPSMeterTexture(); - - if(dxgsg_cat.is_debug()) - dxgsg_cat.debug() << "restore and refill of video surfaces complete...\n"; + if(dxgsg7_cat.is_debug()) + dxgsg7_cat.debug() << "restore and refill of video surfaces complete...\n"; return S_OK; } @@ -5407,13 +5050,13 @@ HRESULT DXGraphicsStateGuardian::RestoreAllVideoSurfaces(void) { // Access: // Description: Repaint primary buffer from back buffer //////////////////////////////////////////////////////////////////// -void DXGraphicsStateGuardian::show_frame(void) { +void DXGraphicsStateGuardian7::show_frame(void) { if(scrn.pddsPrimary==NULL) return; - DO_PSTATS_STUFF(PStatTimer timer(_win->_swap_pcollector)); // this times just the flip, so it must go here in dxgsg, instead of wdxdisplay, which would time the whole frame + // DO_PSTATS_STUFF(PStatTimer timer(_win->_swap_pcollector)); // this times just the flip, so it must go here in dxgsg7, instead of wdxdisplay, which would time the whole frame - if(dx_full_screen) { + if (_win->is_fullscreen()) { show_full_screen_frame(); } else { show_windowed_frame(); @@ -5421,7 +5064,7 @@ void DXGraphicsStateGuardian::show_frame(void) { } //////////////////////////////////////////////////////////////////// -// Function: dxGraphicsStateGuardian::support_overlay_window +// Function: dxGraphicsStateGuardian7::support_overlay_window // Access: Public // Description: Specifies whether dialog windows placed on top of the // dx rendering window should be supported. This @@ -5435,13 +5078,13 @@ void DXGraphicsStateGuardian::show_frame(void) { // This is not necessary when running in windowed mode, // but it does no harm. //////////////////////////////////////////////////////////////////// -void DXGraphicsStateGuardian:: +void DXGraphicsStateGuardian7:: support_overlay_window(bool flag) { if (_overlay_windows_supported && !flag) { // Disable support for overlay windows. _overlay_windows_supported = false; - if (dx_full_screen) { + if (_win->is_fullscreen()) { scrn.pddsPrimary->SetClipper(NULL); } @@ -5449,7 +5092,7 @@ support_overlay_window(bool flag) { // Enable support for overlay windows. _overlay_windows_supported = true; - if (dx_full_screen) { + if (_win->is_fullscreen()) { // Create a Clipper object to blt the whole screen. LPDIRECTDRAWCLIPPER Clipper; @@ -5469,7 +5112,7 @@ support_overlay_window(bool flag) { // Access: // Description: Repaint primary buffer from back buffer //////////////////////////////////////////////////////////////////// -void DXGraphicsStateGuardian::show_full_screen_frame(void) { +void DXGraphicsStateGuardian7::show_full_screen_frame(void) { HRESULT hr; // Flip the front and back buffers, to make what we just rendered @@ -5502,7 +5145,7 @@ void DXGraphicsStateGuardian::show_full_screen_frame(void) { if((hr == DDERR_SURFACELOST) || (hr == DDERR_SURFACEBUSY)) { CheckCooperativeLevel(); } else { - dxgsg_cat.error() << "show_frame() - Flip failed w/unexpected error code: " << ConvD3DErrorToString(hr) << endl; + dxgsg7_cat.error() << "show_frame() - Flip failed w/unexpected error code: " << ConvD3DErrorToString(hr) << endl; exit(1); } } @@ -5514,7 +5157,7 @@ void DXGraphicsStateGuardian::show_full_screen_frame(void) { // Description: Repaint primary buffer from back buffer (windowed // mode only) //////////////////////////////////////////////////////////////////// -void DXGraphicsStateGuardian::show_windowed_frame(void) { +void DXGraphicsStateGuardian7::show_windowed_frame(void) { HRESULT hr; DX_DECLARE_CLEAN(DDBLTFX, bltfx); @@ -5543,7 +5186,7 @@ void DXGraphicsStateGuardian::show_windowed_frame(void) { if (dx_sync_video) { HRESULT hr = scrn.pDD->WaitForVerticalBlank(DDWAITVB_BLOCKBEGIN, NULL); if(hr != DD_OK) { - dxgsg_cat.error() << "WaitForVerticalBlank() failed : " << ConvD3DErrorToString(hr) << endl; + dxgsg7_cat.error() << "WaitForVerticalBlank() failed : " << ConvD3DErrorToString(hr) << endl; exit(1); } } @@ -5552,92 +5195,96 @@ void DXGraphicsStateGuardian::show_windowed_frame(void) { if((hr == DDERR_SURFACELOST) || (hr == DDERR_SURFACEBUSY)) { CheckCooperativeLevel(); } else { - dxgsg_cat.error() << "show_frame() - Blt failed : " << ConvD3DErrorToString(hr) << endl; + dxgsg7_cat.error() << "show_frame() - Blt failed : " << ConvD3DErrorToString(hr) << endl; exit(1); } } } -bool DXGraphicsStateGuardian::CheckCooperativeLevel(bool bDoReactivateWindow) { +bool DXGraphicsStateGuardian7:: +CheckCooperativeLevel(bool bDoReactivateWindow) { + HRESULT hr = scrn.pDD->TestCooperativeLevel(); - HRESULT hr = scrn.pDD->TestCooperativeLevel(); - - if(SUCCEEDED(_last_testcooplevel_result)) { - if(SUCCEEDED(hr)) // this means this was just a safety check, dont need to restore surfs - return true; - - // otherwise something just went wrong - - HRESULT hr; - - // TestCooperativeLevel returns DD_OK: If the current mode is same as the one which the App set. - // The following error is returned only for exclusivemode apps. - // DDERR_NOEXCLUSIVEMODE: Some other app took exclusive mode. - - hr = scrn.pDD->TestCooperativeLevel(); - - HRESULT expected_error = (dx_full_screen ? DDERR_NOEXCLUSIVEMODE : DDERR_EXCLUSIVEMODEALREADYSET); - - if(hr == expected_error) { - // This means that mode changes had taken place, surfaces - // were lost but still we are in the original mode, so we - // simply restore all surfaces and keep going. - - if(dxgsg_cat.is_debug()) { - if(dx_full_screen) - dxgsg_cat.debug() << "Lost access to DDRAW exclusive mode, waiting to regain it...\n"; - else dxgsg_cat.debug() << "Another app has DDRAW exclusive mode, waiting...\n"; - } - - if(_dx_ready) { - _win->deactivate_window(); - _dx_ready = FALSE; - } - } else if(hr==DDERR_WRONGMODE) { - // This means that the desktop mode has changed - // need to destroy all of dx stuff and recreate everything - // back again, which is a big hit - dxgsg_cat.error() << "detected display mode change in TestCoopLevel, must recreate all DDraw surfaces, D3D devices, this is not handled yet. hr == " << ConvD3DErrorToString(hr) << endl; - exit(1); - } else if(FAILED(hr)) { - dxgsg_cat.error() << "unexpected return code from TestCoopLevel: " << ConvD3DErrorToString(hr) << endl; - exit(1); - } - } else { - // testcooplvl was failing, handle case where it now succeeds - - if(SUCCEEDED(hr)) { - if(_last_testcooplevel_result == DDERR_EXCLUSIVEMODEALREADYSET) { - if(dxgsg_cat.is_debug()) - dxgsg_cat.debug() << "other app relinquished exclusive mode, refilling surfs...\n"; - } else if(_last_testcooplevel_result == DDERR_NOEXCLUSIVEMODE) { - if(dxgsg_cat.is_debug()) - dxgsg_cat.debug() << "regained exclusive mode, refilling surfs...\n"; - } - - if(bDoReactivateWindow) - _win->reactivate_window(); //must reactivate window before you can restore surfaces (otherwise you are in WRONGVIDEOMODE, and DDraw RestoreAllSurfaces fails) - - RestoreAllVideoSurfaces(); - - _dx_ready = TRUE; - - } else if(hr==DDERR_WRONGMODE) { - // This means that the desktop mode has changed - // need to destroy all of dx stuff and recreate everything - // back again, which is a big hit - dxgsg_cat.error() << "detected desktop display mode change in TestCoopLevel, must recreate all DDraw surfaces & D3D devices, this is not handled yet. " << ConvD3DErrorToString(hr) << endl; - _win->close_window(); - exit(1); - } else if((hr!=DDERR_NOEXCLUSIVEMODE) && (hr!=DDERR_EXCLUSIVEMODEALREADYSET)) { - dxgsg_cat.error() << "unexpected return code from TestCoopLevel: " << ConvD3DErrorToString(hr) << endl; - exit(1); - } + if (SUCCEEDED(_last_testcooplevel_result)) { + if (SUCCEEDED(hr)) { + // this means this was just a safety check, dont need to restore surfs + return true; } - _last_testcooplevel_result = hr; - return SUCCEEDED(hr); + // otherwise something just went wrong + if (hr == DDERR_NOEXCLUSIVEMODE || hr == DDERR_EXCLUSIVEMODEALREADYSET) { + // This means that mode changes had taken place, surfaces + // were lost but still we are in the original mode, so we + // simply restore all surfaces and keep going. + + if (dxgsg7_cat.is_debug()) { + dxgsg7_cat.debug() + << "Another app has DDRAW exclusive mode, waiting...\n"; + } + + // This doesn't seem to be necessary. + /* + if (_dx_ready) { + _win->deactivate_window(); + _dx_ready = FALSE; + } + */ + + } else if (hr == DDERR_WRONGMODE) { + // This means that the desktop mode has changed. need to + // destroy all of dx stuff and recreate everything back again, + // which is a big hit + dxgsg7_cat.error() + << "detected display mode change in TestCoopLevel, must recreate all DDraw surfaces, D3D devices, this is not handled yet. hr == " << ConvD3DErrorToString(hr) << endl; + exit(1); + } else if (FAILED(hr)) { + dxgsg7_cat.error() + << "unexpected return code from TestCoopLevel: " + << ConvD3DErrorToString(hr) << endl; + exit(1); + } + + } else { + // testcooplvl was failing, handle case where it now succeeds + + if (SUCCEEDED(hr)) { + if (_last_testcooplevel_result == DDERR_EXCLUSIVEMODEALREADYSET || + _last_testcooplevel_result == DDERR_NOEXCLUSIVEMODE) { + if (dxgsg7_cat.is_debug()) { + dxgsg7_cat.debug() + << "other app relinquished exclusive mode, refilling surfs...\n"; + } + } + + // This isn't necessary either. + /* + if (bDoReactivateWindow) { + _win->reactivate_window(); + } + */ + + RestoreAllVideoSurfaces(); + + // _dx_ready = TRUE; + + } else if (hr == DDERR_WRONGMODE) { + // This means that the desktop mode has changed. need to + // destroy all of dx stuff and recreate everything back again, + // which is a big hit + dxgsg7_cat.error() + << "detected desktop display mode change in TestCoopLevel, must recreate all DDraw surfaces & D3D devices, this is not handled yet. " << ConvD3DErrorToString(hr) << endl; + //_win->close_window(); + exit(1); + } else if ((hr!=DDERR_NOEXCLUSIVEMODE) && (hr!=DDERR_EXCLUSIVEMODEALREADYSET)) { + dxgsg7_cat.error() + << "unexpected return code from TestCoopLevel: " << ConvD3DErrorToString(hr) << endl; + exit(1); + } + } + + _last_testcooplevel_result = hr; + return SUCCEEDED(hr); } //////////////////////////////////////////////////////////////////// @@ -5645,7 +5292,7 @@ bool DXGraphicsStateGuardian::CheckCooperativeLevel(bool bDoReactivateWindow) { // Access: // Description: we receive the new x and y position of the client //////////////////////////////////////////////////////////////////// -void DXGraphicsStateGuardian::adjust_view_rect(int x, int y) { +void DXGraphicsStateGuardian7::adjust_view_rect(int x, int y) { if (scrn.view_rect.left != x || scrn.view_rect.top != y) { scrn.view_rect.right = x + scrn.view_rect.right - scrn.view_rect.left; scrn.view_rect.left = x; @@ -5665,7 +5312,7 @@ void DXGraphicsStateGuardian::adjust_view_rect(int x, int y) { // (which must also be the currently active texture in // the GL state) as a separate image file to disk. //////////////////////////////////////////////////////////////////// -void DXGraphicsStateGuardian::read_mipmap_images(Texture *tex) { +void DXGraphicsStateGuardian7::read_mipmap_images(Texture *tex) { Filename filename = tex->get_name(); string name; if (filename.empty()) { @@ -5778,7 +5425,7 @@ HRESULT SetViewMatrix( D3DMATRIX& mat, D3DVECTOR& vFrom, D3DVECTOR& vAt, //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::prepare_geom_node +// Function: DXGraphicsStateGuardian7::prepare_geom_node // Access: Public, Virtual // Description: Prepares the indicated GeomNode for retained-mode // rendering. If this function returns non-NULL, the @@ -5786,7 +5433,7 @@ HRESULT SetViewMatrix( D3DMATRIX& mat, D3DVECTOR& vFrom, D3DVECTOR& vAt, // to draw_geom_node(), which is expected to draw the // contents of the node. //////////////////////////////////////////////////////////////////// -GeomNodeContext *DXGraphicsStateGuardian:: +GeomNodeContext *DXGraphicsStateGuardian7:: prepare_geom_node(GeomNode *node) { #if 0 // temporarily disabled until ported to new scene graph if(link_tristrips) { @@ -5809,10 +5456,10 @@ prepare_geom_node(GeomNode *node) { if(nPrims==1) continue; - if(dxgsg_cat.is_debug()) { + if(dxgsg7_cat.is_debug()) { static bool bPrintedMsg=false; if(!bPrintedMsg) { - dxgsg_cat.debug() << "linking tristrips together with degenerate tris\n"; + dxgsg7_cat.debug() << "linking tristrips together with degenerate tris\n"; bPrintedMsg=true; } } @@ -5902,7 +5549,7 @@ prepare_geom_node(GeomNode *node) { /* vtx order must be reversed*/ \ \ OLDVERT_ITERATOR+=((VECLENGTH)-1); /* start at last vert, and go back*/ \ - /*dxgsg_cat.debug() << "doing reversal on strip " << p << " of length " << nVerts << endl;*/ \ + /*dxgsg7_cat.debug() << "doing reversal on strip " << p << " of length " << nVerts << endl;*/ \ \ if(p!=0) { \ /* copy first vert twice to link with last strip*/ \ @@ -6035,25 +5682,25 @@ prepare_geom_node(GeomNode *node) { /* int ii; for( ii=0;iiD3DMAXNUMVERTICES) { - dxgsg_cat.error() << "geom node contains more than " << D3DMAXNUMVERTICES << " vertices, cant create 1 vertex buffer\n"; + dxgsg7_cat.error() << "geom node contains more than " << D3DMAXNUMVERTICES << " vertices, cant create 1 vertex buffer\n"; exit(1); } // Ok, we've got something; use it. - DXGeomNodeContext *dx_gnc = new DXGeomNodeContext(node); + DXGeomNodeContext7 *dx_gnc = new DXGeomNodeContext7(node); assert(dx_gnc!=NULL); @@ -6137,7 +5784,7 @@ prepare_geom_node(GeomNode *node) { hr=pD3D->CreateVertexBuffer(&VBdesc,&pD3DVertexBuffer,0x0); if(FAILED(hr)) { - dxgsg_cat.error() << "error creating vertex buffer: " << ConvD3DErrorToString(hr) << endl; + dxgsg7_cat.error() << "error creating vertex buffer: " << ConvD3DErrorToString(hr) << endl; delete dx_gnc; exit(1); } @@ -6154,7 +5801,7 @@ prepare_geom_node(GeomNode *node) { hr=pD3D->CreateVertexBuffer(&VBdesc,&pD3DVertexBuffer,0x0); if(FAILED(hr)) { - dxgsg_cat.error() << "error creating xformed vertex buffer: " << ConvD3DErrorToString(hr) << endl; + dxgsg7_cat.error() << "error creating xformed vertex buffer: " << ConvD3DErrorToString(hr) << endl; delete dx_gnc; exit(1); } @@ -6173,7 +5820,7 @@ prepare_geom_node(GeomNode *node) { hr=dx_gnc->_pVB->Lock(dwVBFlags,&pVertData,NULL); if(FAILED(hr)) { - dxgsg_cat.error() << "error locking vertex buffer: " << ConvD3DErrorToString(hr) << endl; + dxgsg7_cat.error() << "error locking vertex buffer: " << ConvD3DErrorToString(hr) << endl; delete dx_gnc; exit(1); } @@ -6206,7 +5853,7 @@ prepare_geom_node(GeomNode *node) { hr=dx_gnc->_pVB->Unlock(); if(FAILED(hr)) { - dxgsg_cat.error() << "error unlocking vertex buffer: " << ConvD3DErrorToString(hr) << endl; + dxgsg7_cat.error() << "error unlocking vertex buffer: " << ConvD3DErrorToString(hr) << endl; delete dx_gnc; exit(1); } @@ -6215,13 +5862,13 @@ prepare_geom_node(GeomNode *node) { hr=dx_gnc->_pVB->Optimize(scrn.pD3DDevice,0x0); if(FAILED(hr)) { - dxgsg_cat.error() << "error optimizing vertex buffer: " << ConvD3DErrorToString(hr) << endl; + dxgsg7_cat.error() << "error optimizing vertex buffer: " << ConvD3DErrorToString(hr) << endl; delete dx_gnc; exit(1); } - if(dxgsg_cat.is_spam()) - dxgsg_cat.spam() << "creating vertex buffer of size: " << cNumVerts << endl; + if(dxgsg7_cat.is_spam()) + dxgsg7_cat.spam() << "creating vertex buffer of size: " << cNumVerts << endl; #if 0 //DO_PSTATS float num_verts_after = @@ -6246,12 +5893,12 @@ prepare_geom_node(GeomNode *node) { } //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::draw_geom_node +// Function: DXGraphicsStateGuardian7::draw_geom_node // Access: Public, Virtual // Description: Draws a GeomNode previously indicated by a call to // prepare_geom_node(). //////////////////////////////////////////////////////////////////// -void DXGraphicsStateGuardian:: +void DXGraphicsStateGuardian7:: draw_geom_node(GeomNode *node, const RenderState *state, GeomNodeContext *gnc) { #if 0 // temporarily disabled until ported to new scene graph @@ -6269,7 +5916,7 @@ draw_geom_node(GeomNode *node, const RenderState *state, GeomNodeContext *gnc) { // We do have a saved context; use it. add_to_geom_node_record(gnc); - DXGeomNodeContext *dx_gnc = DCAST(DXGeomNodeContext, gnc); + DXGeomNodeContext7 *dx_gnc = DCAST(DXGeomNodeContext7, gnc); #ifdef _DEBUG assert(dx_gnc->_pVB!=NULL); @@ -6285,7 +5932,7 @@ draw_geom_node(GeomNode *node, const RenderState *state, GeomNodeContext *gnc) { VBdesc.dwSize=sizeof(VBdesc); hr=dx_gnc->_pVB->GetVertexBufferDesc(&VBdesc); // would be useful to keep fvf in vertbuf struct to avoid having to do this if(FAILED(hr)) { - dxgsg_cat.error() << "error in getvbdesc: " << ConvD3DErrorToString(hr) << endl; + dxgsg7_cat.error() << "error in getvbdesc: " << ConvD3DErrorToString(hr) << endl; exit(1); } @@ -6295,7 +5942,7 @@ draw_geom_node(GeomNode *node, const RenderState *state, GeomNodeContext *gnc) { hr=dx_gnc->_pXformed_VB->ProcessVertices(PVOp,0,dx_gnc->_num_verts,dx_gnc->_pVB,0,scrn.pD3DDevice,0x0); if(FAILED(hr)) { - dxgsg_cat.error() << "error in ProcessVertices: " << ConvD3DErrorToString(hr) << endl; + dxgsg7_cat.error() << "error in ProcessVertices: " << ConvD3DErrorToString(hr) << endl; exit(1); } @@ -6344,17 +5991,17 @@ draw_geom_node(GeomNode *node, const RenderState *state, GeomNodeContext *gnc) { } //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::release_geom_node +// Function: DXGraphicsStateGuardian7::release_geom_node // Access: Public, Virtual // Description: Frees the resources previously allocated via a call // to prepare_geom_node(), including deleting the // GeomNodeContext itself, if necessary. //////////////////////////////////////////////////////////////////// -void DXGraphicsStateGuardian:: +void DXGraphicsStateGuardian7:: release_geom_node(GeomNodeContext *gnc) { #if 0 // temporarily disabled until ported to new scene graph if (gnc != (GeomNodeContext *)NULL) { - DXGeomNodeContext *dx_gnc = DCAST(DXGeomNodeContext, gnc); + DXGeomNodeContext7 *dx_gnc = DCAST(DXGeomNodeContext7, gnc); bool erased = unmark_prepared_geom_node(dx_gnc); diff --git a/panda/src/dxgsg/dxGraphicsStateGuardian.h b/panda/src/dxgsg7/dxGraphicsStateGuardian7.h similarity index 90% rename from panda/src/dxgsg/dxGraphicsStateGuardian.h rename to panda/src/dxgsg7/dxGraphicsStateGuardian7.h index 4c8b03eb76..a0f11b32e8 100644 --- a/panda/src/dxgsg/dxGraphicsStateGuardian.h +++ b/panda/src/dxgsg7/dxGraphicsStateGuardian7.h @@ -1,4 +1,4 @@ -// Filename: dxGraphicsStateGuardian.h +// Filename: dxGraphicsStateGuardian7.h // Created by: mike (02Feb99) // //////////////////////////////////////////////////////////////////// @@ -16,12 +16,14 @@ // //////////////////////////////////////////////////////////////////// -#ifndef DXGRAPHICSSTATEGUARDIAN_H -#define DXGRAPHICSSTATEGUARDIAN_H +#ifndef DXGRAPHICSSTATEGUARDIAN7_H +#define DXGRAPHICSSTATEGUARDIAN7_H -#include "dxgsgbase.h" -#include "dxGeomNodeContext.h" -#include "dxTextureContext.h" +//#define GSG_VERBOSE 1 + +#include "dxgsg7base.h" +#include "dxGeomNodeContext7.h" +#include "dxTextureContext7.h" #include "graphicsStateGuardian.h" #include "geomprimitives.h" @@ -51,20 +53,20 @@ extern void dbgPrintVidMem(LPDIRECTDRAW7 pDD, LPDDSCAPS2 lpddsCaps,const char *p #endif //////////////////////////////////////////////////////////////////// -// Class : DXGraphicsStateGuardian +// Class : DXGraphicsStateGuardian7 // Description : A GraphicsStateGuardian specialized for rendering // into DX. There should be no DX calls // outside of this object. //////////////////////////////////////////////////////////////////// -class EXPCL_PANDADX DXGraphicsStateGuardian : public GraphicsStateGuardian { - friend class wdxGraphicsWindow; - friend class wdxGraphicsPipe; - friend class wdxGraphicsWindowGroup; - friend class DXTextureContext; +class EXPCL_PANDADX DXGraphicsStateGuardian7 : public GraphicsStateGuardian { + friend class wdxGraphicsWindow7; + friend class wdxGraphicsPipe7; + friend class wdxGraphicsWindow7Group; + friend class DXTextureContext7; public: - DXGraphicsStateGuardian(GraphicsWindow *win); - ~DXGraphicsStateGuardian(); + DXGraphicsStateGuardian7(GraphicsWindow *win); + ~DXGraphicsStateGuardian7(); virtual void reset(); @@ -126,12 +128,11 @@ public: virtual void bind_light(DirectionalLight *light, int light_id); virtual void bind_light(Spotlight *light, int light_id); - // default gsg begin_frame() used + virtual bool begin_frame(); + virtual bool begin_scene(); + virtual void end_scene(); virtual void end_frame(); - virtual void start_rendering(); - virtual void finish_rendering(); - virtual bool wants_normals(void) const; virtual bool wants_texcoords(void) const; @@ -180,10 +181,8 @@ protected: bool _dx_ready; HRESULT _last_testcooplevel_result; - bool _bShowFPSMeter; - HDC _front_hdc; - DXTextureContext *_pCurTexContext; + DXTextureContext7 *_pCurTexContext; bool _bTransformIssued; // decaling needs to tell when a transform has been issued D3DMATRIX _SavedTransform; @@ -243,7 +242,7 @@ protected: D3DSHADEMODE _CurShadeMode; bool _bDrawPrimDoSetupVertexBuffer; // if true, draw methods just copy vertex data into pCurrentGeomContext - DXGeomNodeContext *_pCurrentGeomContext; // used in vertex buffer setup + DXGeomNodeContext7 *_pCurrentGeomContext; // used in vertex buffer setup // iterators for primitives Geom::VertexIterator vi; @@ -322,19 +321,6 @@ protected: bool _overlay_windows_supported; - // vars for frames/sec meter - DWORD _start_time; - DWORD _start_frame_count; - DWORD _cur_frame_count; - float _current_fps; - DWORD *_fpsmeter_verts; - DWORD _fpsmeter_fvfflags; - LPDIRECTDRAWSURFACE7 _fpsmeter_font_surf; - float _fps_u_usedwidth,_fps_v_usedheight; // fraction of fps font texture actually used - DWORD _fps_vertexsize; // size of verts used to render fps meter - void SetFPSMeterPosition(RECT &view_rect); - void FillFPSMeterTexture(void); - public: static GraphicsStateGuardian* make_DXGraphicsStateGuardian(const FactoryParams ¶ms); @@ -353,7 +339,7 @@ public: void adjust_view_rect(int x, int y); INLINE void SetDXReady(bool stat) { _dx_ready = stat; } INLINE bool GetDXReady(void) { return _dx_ready;} - void DXGraphicsStateGuardian::SetTextureBlendMode(TextureApplyAttrib::Mode TexBlendMode,bool bJustEnable); + void DXGraphicsStateGuardian7::SetTextureBlendMode(TextureApplyAttrib::Mode TexBlendMode,bool bJustEnable); void dx_cleanup(bool bRestoreDisplayMode,bool bAtExitFnCalled); @@ -383,7 +369,7 @@ private: static TypeHandle _type_handle; }; -#include "dxGraphicsStateGuardian.I" +#include "dxGraphicsStateGuardian7.I" #endif diff --git a/panda/src/dxgsg/dxSavedFrameBuffer.I b/panda/src/dxgsg7/dxSavedFrameBuffer7.I similarity index 77% rename from panda/src/dxgsg/dxSavedFrameBuffer.I rename to panda/src/dxgsg7/dxSavedFrameBuffer7.I index d621f689f2..d088c5e270 100644 --- a/panda/src/dxgsg/dxSavedFrameBuffer.I +++ b/panda/src/dxgsg7/dxSavedFrameBuffer7.I @@ -1,4 +1,4 @@ -// Filename: dxSavedFrameBuffer.I +// Filename: dxSavedFrameBuffer7.I // Created by: drose (06Oct99) // //////////////////////////////////////////////////////////////////// @@ -18,22 +18,22 @@ //////////////////////////////////////////////////////////////////// -// Function: DXSavedFrameBuffer::Constructor +// Function: DXSavedFrameBuffer7::Constructor // Access: Public // Description: //////////////////////////////////////////////////////////////////// -INLINE DXSavedFrameBuffer:: -DXSavedFrameBuffer(const RenderBuffer &buffer, CPT(DisplayRegion) dr) : +INLINE DXSavedFrameBuffer7:: +DXSavedFrameBuffer7(const RenderBuffer &buffer, CPT(DisplayRegion) dr) : SavedFrameBuffer(buffer, dr) { } //////////////////////////////////////////////////////////////////// -// Function: DXSavedFrameBuffer::Destructor +// Function: DXSavedFrameBuffer7::Destructor // Access: Public // Description: //////////////////////////////////////////////////////////////////// -INLINE DXSavedFrameBuffer:: -~DXSavedFrameBuffer() { +INLINE DXSavedFrameBuffer7:: +~DXSavedFrameBuffer7() { } diff --git a/panda/src/dxgsg/dxSavedFrameBuffer.cxx b/panda/src/dxgsg7/dxSavedFrameBuffer7.cxx similarity index 84% rename from panda/src/dxgsg/dxSavedFrameBuffer.cxx rename to panda/src/dxgsg7/dxSavedFrameBuffer7.cxx index c174d6411c..9cabfb3190 100644 --- a/panda/src/dxgsg/dxSavedFrameBuffer.cxx +++ b/panda/src/dxgsg7/dxSavedFrameBuffer7.cxx @@ -1,4 +1,4 @@ -// Filename: dxSavedFrameBuffer.cxx +// Filename: dxSavedFrameBuffer7.cxx // Created by: drose (06Oct99) // //////////////////////////////////////////////////////////////////// @@ -16,6 +16,6 @@ // //////////////////////////////////////////////////////////////////// -#include "dxSavedFrameBuffer.h" +#include "dxSavedFrameBuffer7.h" -TypeHandle DXSavedFrameBuffer::_type_handle; +TypeHandle DXSavedFrameBuffer7::_type_handle; diff --git a/panda/src/dxgsg/dxSavedFrameBuffer.h b/panda/src/dxgsg7/dxSavedFrameBuffer7.h similarity index 79% rename from panda/src/dxgsg/dxSavedFrameBuffer.h rename to panda/src/dxgsg7/dxSavedFrameBuffer7.h index 32617b342b..f7432dc55d 100644 --- a/panda/src/dxgsg/dxSavedFrameBuffer.h +++ b/panda/src/dxgsg7/dxSavedFrameBuffer7.h @@ -1,4 +1,4 @@ -// Filename: dxSavedFrameBuffer.h +// Filename: dxSavedFrameBuffer7.h // Created by: drose (06Oct99) // //////////////////////////////////////////////////////////////////// @@ -16,8 +16,8 @@ // //////////////////////////////////////////////////////////////////// -#ifndef DXSAVEDFRAMEBUFFER_H -#define DXSAVEDFRAMEBUFFER_H +#ifndef DXSAVEDFRAMEBUFFER7_H +#define DXSAVEDFRAMEBUFFER7_H #include @@ -28,14 +28,14 @@ //////////////////////////////////////////////////////////////////// -// Class : DXSavedFrameBuffer +// Class : DXSavedFrameBuffer7 // Description : //////////////////////////////////////////////////////////////////// -class EXPCL_PANDADX DXSavedFrameBuffer : public SavedFrameBuffer { +class EXPCL_PANDADX DXSavedFrameBuffer7 : public SavedFrameBuffer { public: - INLINE DXSavedFrameBuffer(const RenderBuffer &buffer, + INLINE DXSavedFrameBuffer7(const RenderBuffer &buffer, CPT(DisplayRegion) dr); - INLINE ~DXSavedFrameBuffer(); + INLINE ~DXSavedFrameBuffer7(); PT(Texture) _back_rgba; PT(PixelBuffer) _depth; @@ -46,7 +46,7 @@ public: } static void init_type() { SavedFrameBuffer::init_type(); - register_type(_type_handle, "DXSavedFrameBuffer", + register_type(_type_handle, "DXSavedFrameBuffer7", SavedFrameBuffer::get_class_type()); } virtual TypeHandle get_type() const { @@ -58,7 +58,7 @@ private: static TypeHandle _type_handle; }; -#include "dxSavedFrameBuffer.I" +#include "dxSavedFrameBuffer7.I" #endif diff --git a/panda/src/dxgsg/dxTextureContext.cxx b/panda/src/dxgsg7/dxTextureContext7.cxx similarity index 93% rename from panda/src/dxgsg/dxTextureContext.cxx rename to panda/src/dxgsg7/dxTextureContext7.cxx index fe80f65657..4aee9052dd 100644 --- a/panda/src/dxgsg/dxTextureContext.cxx +++ b/panda/src/dxgsg7/dxTextureContext7.cxx @@ -1,4 +1,4 @@ -// Filename: dxTextureContext.cxx +// Filename: dxTextureContext7.cxx // Created by: drose (07Oct99) // //////////////////////////////////////////////////////////////////// @@ -18,9 +18,9 @@ #include #include -#include "dxTextureContext.h" -#include "config_dxgsg.h" -#include "dxGraphicsStateGuardian.h" +#include "dxTextureContext7.h" +#include "config_dxgsg7.h" +#include "dxGraphicsStateGuardian7.h" #include "pnmImage.h" static const DWORD g_LowByteMask = 0x000000FF; @@ -64,14 +64,14 @@ char *PandaFilterNameStrs[] = {"FT_nearest","FT_linear","FT_nearest_mipmap_neare "FT_nearest_mipmap_linear", "FT_linear_mipmap_linear" }; -TypeHandle DXTextureContext::_type_handle; +TypeHandle DXTextureContext7::_type_handle; #define SWAPDWORDS(X,Y) { DWORD temp=X; X=Y; Y=temp; } #ifdef _DEBUG static void DebugPrintPixFmt(DDPIXELFORMAT* pddpf) { static int iddpfnum=0; - ostream *dbgout = &dxgsg_cat.debug(); + ostream *dbgout = &dxgsg7_cat.debug(); *dbgout << "DDPF[" << iddpfnum << "]: RGBBitCount:" << pddpf->dwRGBBitCount << " Flags:" << (void *)pddpf->dwFlags ; @@ -148,7 +148,7 @@ enum Format { */ //////////////////////////////////////////////////////////////////// -// Function: DXTextureContext::get_bits_per_pixel +// Function: DXTextureContext7::get_bits_per_pixel // Access: Protected // Description: Maps from the PixelBuffer's Format symbols // to bpp. returns # of alpha bits @@ -156,7 +156,7 @@ enum Format { // not the stored format, which is indicated by pixelbuffer type //////////////////////////////////////////////////////////////////// -unsigned int DXTextureContext:: +unsigned int DXTextureContext7:: get_bits_per_pixel(PixelBuffer::Format format, int *alphbits) { *alphbits = 0; // assume no alpha bits switch(format) { @@ -209,12 +209,12 @@ HRESULT ConvertPixBuftoDDSurf(ConversionType ConvNeeded,BYTE *pbuf,LPDIRECTDRAWS DX_DECLARE_CLEAN(DDSURFACEDESC2, ddsd); if(IsBadWritePtr(pDDSurf,sizeof(DWORD))) { - dxgsg_cat.error() << "ConvertPixBuftoDDSurf failed: bad pDDSurf ptr value (" << ((void*)pDDSurf) << ")\n"; + dxgsg7_cat.error() << "ConvertPixBuftoDDSurf failed: bad pDDSurf ptr value (" << ((void*)pDDSurf) << ")\n"; exit(1); } if(FAILED( hr = pDDSurf->Lock( NULL, &ddsd, DDLOCK_NOSYSLOCK | DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT, NULL ))) { - dxgsg_cat.error() << "CreateTexture failed: _surface->Lock() failed on texture! hr = " << ConvD3DErrorToString(hr) << "\n"; + dxgsg7_cat.error() << "CreateTexture failed: _surface->Lock() failed on texture! hr = " << ConvD3DErrorToString(hr) << "\n"; return hr; } @@ -662,7 +662,7 @@ HRESULT ConvertPixBuftoDDSurf(ConversionType ConvNeeded,BYTE *pbuf,LPDIRECTDRAWS } default: - dxgsg_cat.error() << "CreateTexture failed! unhandled texture conversion type: "<< ConvNeeded <<" \n"; + dxgsg7_cat.error() << "CreateTexture failed! unhandled texture conversion type: "<< ConvNeeded <<" \n"; pDDSurf->Unlock(NULL); return E_INVALIDARG; } @@ -686,12 +686,12 @@ HRESULT ConvertDDSurftoPixBuf(PixelBuffer *pixbuf,LPDIRECTDRAWSURFACE7 pDDSurf) BYTE *pbuf=pixbuf->_image.p(); if(IsBadWritePtr(pDDSurf,sizeof(DWORD))) { - dxgsg_cat.error() << "ConvertDDSurftoPixBuf failed: bad pDDSurf ptr value (" << ((void*)pDDSurf) << ")\n"; + dxgsg7_cat.error() << "ConvertDDSurftoPixBuf failed: bad pDDSurf ptr value (" << ((void*)pDDSurf) << ")\n"; exit(1); } if(FAILED( hr = pDDSurf->Lock( NULL, &ddsd, DDLOCK_NOSYSLOCK | DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT, NULL ))) { - dxgsg_cat.error() << "ConvertDDSurftoPixBuf Lock() failed! hr = " << ConvD3DErrorToString(hr) << "\n"; + dxgsg7_cat.error() << "ConvertDDSurftoPixBuf Lock() failed! hr = " << ConvD3DErrorToString(hr) << "\n"; return hr; } @@ -705,7 +705,7 @@ HRESULT ConvertDDSurftoPixBuf(PixelBuffer *pixbuf,LPDIRECTDRAWSURFACE7 pDDSurf) #ifdef _DEBUG if(FAILED(hr) && !((hr == DDERR_NOCLIPPERATTACHED) && dx_full_screen)) { - dxgsg_cat.error() << "ConvertDDSurftoPixBuf GetClipper failed! hr = " << ConvD3DErrorToString(hr) << "\n"; + dxgsg7_cat.error() << "ConvertDDSurftoPixBuf GetClipper failed! hr = " << ConvD3DErrorToString(hr) << "\n"; return hr; } #endif @@ -714,7 +714,7 @@ HRESULT ConvertDDSurftoPixBuf(PixelBuffer *pixbuf,LPDIRECTDRAWSURFACE7 pDDSurf) HWND hWin; if(FAILED(hr = pDDClipper->GetHWnd(&hWin))) { - dxgsg_cat.error() << "ConvertDDSurftoPixBuf GetHwnd failed! hr = " << ConvD3DErrorToString(hr) << "\n"; + dxgsg7_cat.error() << "ConvertDDSurftoPixBuf GetHwnd failed! hr = " << ConvD3DErrorToString(hr) << "\n"; return hr; } @@ -737,7 +737,7 @@ HRESULT ConvertDDSurftoPixBuf(PixelBuffer *pixbuf,LPDIRECTDRAWSURFACE7 pDDSurf) if(!((dwCopyWidth==pixbuf->get_xsize()) && (dwCopyHeight<=(DWORD)pixbuf->get_ysize()))) { pDDSurf->Unlock(NULL); assert(0); - dxgsg_cat.error() << "ConvertDDSurftoPixBuf, PixBuf incorrect size to hold display surface!\n"; + dxgsg7_cat.error() << "ConvertDDSurftoPixBuf, PixBuf incorrect size to hold display surface!\n"; return E_FAIL; } @@ -751,8 +751,8 @@ HRESULT ConvertDDSurftoPixBuf(PixelBuffer *pixbuf,LPDIRECTDRAWSURFACE7 pDDSurf) // writes out last line in DDSurf first in PixelBuf, so Y line order precedes inversely - if(dxgsg_cat.is_debug()) - dxgsg_cat.debug() << "ConvertDDSurftoPixBuf converting " << ddsd.ddpfPixelFormat.dwRGBBitCount << "bpp DDSurf to " + if(dxgsg7_cat.is_debug()) + dxgsg7_cat.debug() << "ConvertDDSurftoPixBuf converting " << ddsd.ddpfPixelFormat.dwRGBBitCount << "bpp DDSurf to " << dwNumComponents << "-channel panda PixelBuffer\n"; @@ -1003,7 +1003,7 @@ HRESULT ConvertDDSurftoPixBuf(PixelBuffer *pixbuf,LPDIRECTDRAWSURFACE7 pDDSurf) // gets the attributes of the texture from the bitmap, creates the // texture, and then copies the bitmap into the texture. //----------------------------------------------------------------------------- -LPDIRECTDRAWSURFACE7 DXTextureContext::CreateTexture(LPDIRECT3DDEVICE7 pd3dDevice, +LPDIRECTDRAWSURFACE7 DXTextureContext7::CreateTexture(LPDIRECT3DDEVICE7 pd3dDevice, #ifdef USE_TEXFMTVEC DDPixelFormatVec &TexFmts,LPD3DDEVICEDESC7 pD3DDevDesc) #else @@ -1045,7 +1045,7 @@ LPDIRECTDRAWSURFACE7 DXTextureContext::CreateTexture(LPDIRECT3DDEVICE7 pd3dDevic assert(pixbuf_type==PixelBuffer::T_unsigned_byte); // cant handle anything else now if((pixbuf_type != PixelBuffer::T_unsigned_byte) || (pbuf->get_component_width()!=1)) { - dxgsg_cat.error() << "CreateTexture failed, havent handled non 8-bit channel pixelbuffer types yet! \n"; + dxgsg7_cat.error() << "CreateTexture failed, havent handled non 8-bit channel pixelbuffer types yet! \n"; return NULL; } @@ -1099,7 +1099,7 @@ LPDIRECTDRAWSURFACE7 DXTextureContext::CreateTexture(LPDIRECT3DDEVICE7 pd3dDevic ddsd.dwHeight = dwOrigHeight; if(!ISPOW2(ddsd.dwWidth) || !ISPOW2(ddsd.dwHeight)) { - dxgsg_cat.error() << "ERROR: texture dimensions are not a power of 2 for " << _tex->get_name() << "!!!!! \n"; + dxgsg7_cat.error() << "ERROR: texture dimensions are not a power of 2 for " << _tex->get_name() << "!!!!! \n"; #ifdef _DEBUG exit(1); // want to catch badtexsize errors #else @@ -1112,7 +1112,7 @@ LPDIRECTDRAWSURFACE7 DXTextureContext::CreateTexture(LPDIRECT3DDEVICE7 pd3dDevic if((dwOrigWidth>pD3DDevDesc->dwMaxTextureWidth)||(dwOrigHeight>pD3DDevDesc->dwMaxTextureHeight)) { #ifdef _DEBUG - dxgsg_cat.error() << "WARNING: " <<_tex->get_name() << ": Image size exceeds max texture dimensions of (" << pD3DDevDesc->dwMaxTextureWidth << "," << pD3DDevDesc->dwMaxTextureHeight << ") !!\n" + dxgsg7_cat.error() << "WARNING: " <<_tex->get_name() << ": Image size exceeds max texture dimensions of (" << pD3DDevDesc->dwMaxTextureWidth << "," << pD3DDevDesc->dwMaxTextureHeight << ") !!\n" << "Scaling "<< _tex->get_name() << " ("<< dwOrigWidth<<"," < ("<< pD3DDevDesc->dwMaxTextureWidth << "," << pD3DDevDesc->dwMaxTextureHeight << ") !\n"; #endif @@ -1134,7 +1134,7 @@ LPDIRECTDRAWSURFACE7 DXTextureContext::CreateTexture(LPDIRECT3DDEVICE7 pd3dDevic bShrinkOriginal=true; #ifdef _DEBUG - dxgsg_cat.debug() << "Scaling "<< _tex->get_name() << " ("<< dwOrigWidth<<"," < ("<< ddsd.dwWidth<<"," << ddsd.dwHeight << ") to meet HW square texture reqmt\n"; + dxgsg7_cat.debug() << "Scaling "<< _tex->get_name() << " ("<< dwOrigWidth<<"," < ("<< ddsd.dwWidth<<"," << ddsd.dwHeight << ") to meet HW square texture reqmt\n"; #endif } @@ -1157,7 +1157,7 @@ LPDIRECTDRAWSURFACE7 DXTextureContext::CreateTexture(LPDIRECT3DDEVICE7 pd3dDevic // easier to use dxcapsviewer instead of this { static BOOL bPrinted=FALSE; if(!bPrinted) { - dxgsg_cat.debug() << "Gfx card supported TexFmts:\n"; + dxgsg7_cat.debug() << "Gfx card supported TexFmts:\n"; for(i=0;iget_name() << "]\n"; + dxgsg7_cat.spam() << "Forcing mipmap filtering on DX texture [" << _tex->get_name() << "]\n"; } ft = Texture::FT_linear_mipmap_linear; _tex->set_minfilter(ft); @@ -1594,14 +1594,14 @@ LPDIRECTDRAWSURFACE7 DXTextureContext::CreateTexture(LPDIRECT3DDEVICE7 pd3dDevic } _tex->set_anisotropic_degree(aniso_degree); #ifdef _DEBUG - dxgsg_cat.spam() << "CreateTexture: setting aniso degree for "<< _tex->get_name() << " to: " << aniso_degree << endl; + dxgsg7_cat.spam() << "CreateTexture: setting aniso degree for "<< _tex->get_name() << " to: " << aniso_degree << endl; #endif if(_bHasMipMaps) { // We dont specify mipmapcount, so CreateSurface will auto-create surfs // for all mipmaps down to 1x1 (if driver supports deep-mipmaps, otherwise Nx1) ddsd.ddsCaps.dwCaps |= (DDSCAPS_MIPMAP | DDSCAPS_COMPLEX); - dxgsg_cat.debug() << "CreateTexture: generating mipmaps for "<< _tex->get_name() << endl; + dxgsg7_cat.debug() << "CreateTexture: generating mipmaps for "<< _tex->get_name() << endl; } if(pD3DDevDesc->dwDevCaps & D3DDEVCAPS_SEPARATETEXTUREMEMORIES) { @@ -1615,13 +1615,13 @@ LPDIRECTDRAWSURFACE7 DXTextureContext::CreateTexture(LPDIRECT3DDEVICE7 pd3dDevic // Create a new surface for the texture if(FAILED( hr = pDD->CreateSurface( &ddsd, &_surface, NULL ) )) { - dxgsg_cat.error() << "CreateTexture failed: pDD->CreateSurface() failed! hr = " << ConvD3DErrorToString(hr) << "\n"; + dxgsg7_cat.error() << "CreateTexture failed: pDD->CreateSurface() failed! hr = " << ConvD3DErrorToString(hr) << "\n"; goto error_exit; } #ifdef _DEBUG - dxgsg_cat.debug() << "CreateTexture: "<< _tex->get_name() <<" converted " << ConvNameStrs[ConvNeeded] << " \n"; + dxgsg7_cat.debug() << "CreateTexture: "<< _tex->get_name() <<" converted " << ConvNameStrs[ConvNeeded] << " \n"; #endif _PixBufConversionType=ConvNeeded; @@ -1652,12 +1652,12 @@ LPDIRECTDRAWSURFACE7 DXTextureContext::CreateTexture(LPDIRECT3DDEVICE7 pd3dDevic return NULL; } -HRESULT DXTextureContext:: +HRESULT DXTextureContext7:: FillDDSurfTexturePixels(void) { PixelBuffer *pbuf = _texture->get_ram_image(); if (pbuf == (PixelBuffer *)NULL) { - dxgsg_cat.fatal() << "CreateTexture: get_ram_image() failed\n"; + dxgsg7_cat.fatal() << "CreateTexture: get_ram_image() failed\n"; // The texture doesn't have an image to load. return E_FAIL; } @@ -1762,7 +1762,7 @@ FillDDSurfTexturePixels(void) { hr = pCurDDSurf->GetAttachedSurface(&ddsCaps, &pMipLevel_DDSurf); if(FAILED(hr)) { - dxgsg_cat.error() << "CreateTexture failed creating mipmaps: GetAttachedSurf hr = " << ConvD3DErrorToString(hr) << "\n"; + dxgsg7_cat.error() << "CreateTexture failed creating mipmaps: GetAttachedSurf hr = " << ConvD3DErrorToString(hr) << "\n"; delete [] pMipMapPixBufSpace; pCurDDSurf->Release(); return hr; @@ -1790,7 +1790,7 @@ FillDDSurfTexturePixels(void) { if(dx_debug_view_mipmaps) { #if 0 if(!(ddcaps.dwCaps & DDCAPS_BLTSTRETCH)) { - dxgsg_cat.error() << "CreateTexture failed debug-viewing mipmaps, BLT stretching not supported! ( we need to do SW stretch) \n"; + dxgsg7_cat.error() << "CreateTexture failed debug-viewing mipmaps, BLT stretching not supported! ( we need to do SW stretch) \n"; return hr; } #endif @@ -1817,14 +1817,14 @@ FillDDSurfTexturePixels(void) { hr = pTexturePrev->GetDC(&hTexDC); if(FAILED(hr)) { - dxgsg_cat.error() << "GetDC failed hr = " << ConvD3DErrorToString(hr) << "\n"; + dxgsg7_cat.error() << "GetDC failed hr = " << ConvD3DErrorToString(hr) << "\n"; break; } BOOL res; - // res = BitBlt(_dxgsg->_hdc,0,0,ddsd.dwWidth,ddsd.dwHeight, TexDC,0,0,SRCCOPY); + // res = BitBlt(_dxgsg7->_hdc,0,0,ddsd.dwWidth,ddsd.dwHeight, TexDC,0,0,SRCCOPY); // loader inverts y, so use StretchBlt to re-invert it - // res = StretchBlt(_dxgsg->hdc,0,ddsd_cur.dwHeight+cury,ddsd_cur.dwWidth,-ddsd_cur.dwHeight, TexDC,0,0,ddsd_cur.dwWidth,ddsd_cur.dwHeight,SRCCOPY); + // res = StretchBlt(_dxgsg7->hdc,0,ddsd_cur.dwHeight+cury,ddsd_cur.dwWidth,-ddsd_cur.dwHeight, TexDC,0,0,ddsd_cur.dwWidth,ddsd_cur.dwHeight,SRCCOPY); #if 0 if(cNumAlphaBits>0) { BLENDFUNCTION bf; @@ -1833,7 +1833,7 @@ FillDDSurfTexturePixels(void) { res = AlphaBlend(hScreenDC,curx,cury,ddsd_cur.dwWidth,ddsd_cur.dwHeight, TexDC,0,0,ddsd_cur.dwWidth,ddsd_cur.dwHeight,bf); if(!res) { PrintLastError(msg); - dxgsg_cat.error() << "AlphaBlend BLT failed: "<ReleaseDC(hTexDC); if(FAILED(hr)) { - dxgsg_cat.error() << "tex ReleaseDC failed for mip "<GetAttachedSurface(&ddsCaps, &pTextureCurrent); if(FAILED(hr)) { - dxgsg_cat.error() << " failed displaying mipmaps: GetAttachedSurf hr = " << ConvD3DErrorToString(hr) << "\n"; + dxgsg7_cat.error() << " failed displaying mipmaps: GetAttachedSurf hr = " << ConvD3DErrorToString(hr) << "\n"; } // done with the previous texture pTexturePrev->Release(); @@ -1891,9 +1891,9 @@ FillDDSurfTexturePixels(void) { int val=MsgWaitForMultipleObjects(1,hArr,TRUE,INFINITE,QS_KEY); if(val==-1) { PrintLastError(msg); - dxgsg_cat.error() << " MsgWaitForMultipleObjects returns " << val << " " <get_name() << "\n"; + if(dxgsg7_cat.is_spam()) { + dxgsg7_cat.spam() << "Deleting DX texture for " << _tex->get_name() << "\n"; } ULONG refcnt; @@ -1922,26 +1922,26 @@ DeleteTexture( ) { pDD->Release(); PRINTREFCNT(pDD,"before DeleteTex, IDDraw7"); - RELEASE(_surface,dxgsg,"texture",false); + RELEASE(_surface,dxgsg7,"texture",false); PRINTREFCNT(pDD,"after DeleteTex, IDDraw7"); } #else - RELEASE(_surface,dxgsg,"texture",false); + RELEASE(_surface,dxgsg7,"texture",false); #endif } //////////////////////////////////////////////////////////////////// -// Function: DXTextureContext::Constructor +// Function: DXTextureContext7::Constructor // Access: Public // Description: //////////////////////////////////////////////////////////////////// -DXTextureContext:: -DXTextureContext(Texture *tex) : +DXTextureContext7:: +DXTextureContext7(Texture *tex) : TextureContext(tex) { //#ifdef NDEBUG - if(dxgsg_cat.is_spam()) { - dxgsg_cat.spam() << "Creating DX texture [" << tex->get_name() << "], minfilter(" << PandaFilterNameStrs[tex->get_minfilter()] << "), magfilter("<get_magfilter()] << "), anisodeg(" << tex->get_anisotropic_degree() << ")\n"; + if(dxgsg7_cat.is_spam()) { + dxgsg7_cat.spam() << "Creating DX texture [" << tex->get_name() << "], minfilter(" << PandaFilterNameStrs[tex->get_minfilter()] << "), magfilter("<get_magfilter()] << "), anisodeg(" << tex->get_anisotropic_degree() << ")\n"; } //#endif _surface = NULL; @@ -1949,8 +1949,8 @@ TextureContext(tex) { _tex = tex; } -DXTextureContext:: -~DXTextureContext() { +DXTextureContext7:: +~DXTextureContext7() { DeleteTexture(); TextureContext::~TextureContext(); _tex = NULL; diff --git a/panda/src/dxgsg/dxTextureContext.h b/panda/src/dxgsg7/dxTextureContext7.h similarity index 83% rename from panda/src/dxgsg/dxTextureContext.h rename to panda/src/dxgsg7/dxTextureContext7.h index 0ae1e8bbe4..99cc6d4064 100644 --- a/panda/src/dxgsg/dxTextureContext.h +++ b/panda/src/dxgsg7/dxTextureContext7.h @@ -1,4 +1,4 @@ -// Filename: dxTextureContext.h +// Filename: dxTextureContext7.h // Created by: drose (07Oct99) // //////////////////////////////////////////////////////////////////// @@ -16,25 +16,25 @@ // //////////////////////////////////////////////////////////////////// -#ifndef DXTEXTURECONTEXT_H -#define DXTEXTURECONTEXT_H +#ifndef DXTEXTURECONTEXT7_H +#define DXTEXTURECONTEXT7_H -#include "dxgsgbase.h" +#include "dxgsg7base.h" #include #include //////////////////////////////////////////////////////////////////// -// Class : DXTextureContext +// Class : DXTextureContext7 // Description : //////////////////////////////////////////////////////////////////// -class EXPCL_PANDADX DXTextureContext : public TextureContext { - friend class DXGraphicsStateGuardian; - friend class wdxGraphicsWindow; +class EXPCL_PANDADX DXTextureContext7 : public TextureContext { + friend class DXGraphicsStateGuardian7; + friend class wdxGraphicsWindow7; public: - DXTextureContext(Texture *tex); - ~DXTextureContext(); + DXTextureContext7(Texture *tex); + ~DXTextureContext7(); LPDIRECTDRAWSURFACE7 _surface; Texture *_tex; // ptr to parent, primarily for access to namestr @@ -63,7 +63,7 @@ public: } static void init_type() { TextureContext::init_type(); - register_type(_type_handle, "DXTextureContext", + register_type(_type_handle, "DXTextureContext7", TextureContext::get_class_type()); } virtual TypeHandle get_type() const { diff --git a/panda/src/dxgsg7/dxgsg7_composite1.cxx b/panda/src/dxgsg7/dxgsg7_composite1.cxx new file mode 100644 index 0000000000..79003e66a6 --- /dev/null +++ b/panda/src/dxgsg7/dxgsg7_composite1.cxx @@ -0,0 +1,7 @@ +#include "config_dxgsg7.cxx" +#include "dxgsg7base.cxx" +#include "dxSavedFrameBuffer7.cxx" +#include "dxTextureContext7.cxx" +#include "dxGeomNodeContext7.cxx" +#include "wdxGraphicsPipe7.cxx" +#include "wdxGraphicsWindow7.cxx" diff --git a/panda/src/dxgsg7/dxgsg7base.cxx b/panda/src/dxgsg7/dxgsg7base.cxx new file mode 100644 index 0000000000..ceaeb38682 --- /dev/null +++ b/panda/src/dxgsg7/dxgsg7base.cxx @@ -0,0 +1,1516 @@ +// Filename: dxgsg7base.cxx +// Created by: drose (02Jan03) +// +//////////////////////////////////////////////////////////////////// +// +// 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 "dxgsg7base.h" + +#include + +const char * +ConvD3DErrorToString(HRESULT error) { + switch (error) { + case E_FAIL: + return "Unspecified error E_FAIL"; + + case DD_OK: + return "No error."; + case D3DERR_BADMAJORVERSION : // (700) + return "D3DERR_BADMAJORVERSION"; + case D3DERR_BADMINORVERSION : // (701) + return "D3DERR_BADMINORVERSION"; + case D3DERR_INVALID_DEVICE : // (705) + return "D3DERR_INVALID_DEVICE"; + case D3DERR_INITFAILED : // (706) + return "D3DERR_INITFAILED"; + case D3DERR_DEVICEAGGREGATED : // (707) + return "D3DERR_DEVICEAGGREGATED"; + case D3DERR_EXECUTE_CREATE_FAILED : // (710) + return "D3DERR_EXECUTE_CREATE_FAILED"; + case D3DERR_EXECUTE_DESTROY_FAILED : // (711) + return "D3DERR_EXECUTE_DESTROY_FAILED"; + case D3DERR_EXECUTE_LOCK_FAILED : // (712) + return "D3DERR_EXECUTE_LOCK_FAILED"; + case D3DERR_EXECUTE_UNLOCK_FAILED : // (713) + return "D3DERR_EXECUTE_UNLOCK_FAILED"; + case D3DERR_EXECUTE_LOCKED : // (714) + return "D3DERR_EXECUTE_LOCKED"; + case D3DERR_EXECUTE_NOT_LOCKED : // (715) + return "D3DERR_EXECUTE_NOT_LOCKED"; + case D3DERR_EXECUTE_FAILED : // (716) + return "D3DERR_EXECUTE_FAILED"; + case D3DERR_EXECUTE_CLIPPED_FAILED : // (717) + return "D3DERR_EXECUTE_CLIPPED_FAILED"; + case D3DERR_TEXTURE_NO_SUPPORT : // (720) + return "D3DERR_TEXTURE_NO_SUPPORT"; + case D3DERR_TEXTURE_CREATE_FAILED : // (721) + return "D3DERR_TEXTURE_CREATE_FAILED"; + case D3DERR_TEXTURE_DESTROY_FAILED : // (722) + return "D3DERR_TEXTURE_DESTROY_FAILED"; + case D3DERR_TEXTURE_LOCK_FAILED : // (723) + return "D3DERR_TEXTURE_LOCK_FAILED"; + case D3DERR_TEXTURE_UNLOCK_FAILED : // (724) + return "D3DERR_TEXTURE_UNLOCK_FAILED"; + case D3DERR_TEXTURE_LOAD_FAILED : // (725) + return "D3DERR_TEXTURE_LOAD_FAILED"; + case D3DERR_TEXTURE_SWAP_FAILED : // (726) + return "D3DERR_TEXTURE_SWAP_FAILED"; + case D3DERR_TEXTURE_LOCKED : // (727) + return "D3DERR_TEXTURE_LOCKED"; + case D3DERR_TEXTURE_NOT_LOCKED : // (728) + return "D3DERR_TEXTURE_NOT_LOCKED"; + case D3DERR_TEXTURE_GETSURF_FAILED : // (729) + return "D3DERR_TEXTURE_GETSURF_FAILED"; + case D3DERR_MATRIX_CREATE_FAILED : // (730) + return "D3DERR_MATRIX_CREATE_FAILED"; + case D3DERR_MATRIX_DESTROY_FAILED : // (731) + return "D3DERR_MATRIX_DESTROY_FAILED"; + case D3DERR_MATRIX_SETDATA_FAILED : // (732) + return "D3DERR_MATRIX_SETDATA_FAILED"; + case D3DERR_MATRIX_GETDATA_FAILED : // (733) + return "D3DERR_MATRIX_GETDATA_FAILED"; + case D3DERR_SETVIEWPORTDATA_FAILED : // (734) + return "D3DERR_SETVIEWPORTDATA_FAILED"; + case D3DERR_INVALIDCURRENTVIEWPORT : // (735) + return "D3DERR_INVALIDCURRENTVIEWPORT"; + case D3DERR_INVALIDPRIMITIVETYPE : // (736) + return "D3DERR_INVALIDPRIMITIVETYPE"; + case D3DERR_INVALIDVERTEXTYPE : // (737) + return "D3DERR_INVALIDVERTEXTYPE"; + case D3DERR_TEXTURE_BADSIZE : // (738) + return "D3DERR_TEXTURE_BADSIZE"; + case D3DERR_INVALIDRAMPTEXTURE : // (739) + return "D3DERR_INVALIDRAMPTEXTURE"; + case D3DERR_MATERIAL_CREATE_FAILED : // (740) + return "D3DERR_MATERIAL_CREATE_FAILED"; + case D3DERR_MATERIAL_DESTROY_FAILED : // (741) + return "D3DERR_MATERIAL_DESTROY_FAILED"; + case D3DERR_MATERIAL_SETDATA_FAILED : // (742) + return "D3DERR_MATERIAL_SETDATA_FAILED"; + case D3DERR_MATERIAL_GETDATA_FAILED : // (743) + return "D3DERR_MATERIAL_GETDATA_FAILED"; + case D3DERR_INVALIDPALETTE : // (744) + return "D3DERR_INVALIDPALETTE"; + case D3DERR_ZBUFF_NEEDS_SYSTEMMEMORY : // (745) + return "D3DERR_ZBUFF_NEEDS_SYSTEMMEMORY"; + case D3DERR_ZBUFF_NEEDS_VIDEOMEMORY : // (746) + return "D3DERR_ZBUFF_NEEDS_VIDEOMEMORY"; + case D3DERR_SURFACENOTINVIDMEM : // (747) + return "D3DERR_SURFACENOTINVIDMEM"; + case D3DERR_LIGHT_SET_FAILED : // (750) + return "D3DERR_LIGHT_SET_FAILED"; + case D3DERR_LIGHTHASVIEWPORT : // (751) + return "D3DERR_LIGHTHASVIEWPORT"; + case D3DERR_LIGHTNOTINTHISVIEWPORT : // (752) + return "D3DERR_LIGHTNOTINTHISVIEWPORT"; + case D3DERR_SCENE_IN_SCENE : // (760) + return "D3DERR_SCENE_IN_SCENE"; + case D3DERR_SCENE_NOT_IN_SCENE : // (761) + return "D3DERR_SCENE_NOT_IN_SCENE"; + case D3DERR_SCENE_BEGIN_FAILED : // (762) + return "D3DERR_SCENE_BEGIN_FAILED"; + case D3DERR_SCENE_END_FAILED : // (763) + return "D3DERR_SCENE_END_FAILED"; + case D3DERR_INBEGIN : // (770) + return "D3DERR_INBEGIN"; + case D3DERR_NOTINBEGIN : // (771) + return "D3DERR_NOTINBEGIN"; + case D3DERR_NOVIEWPORTS : // (772) + return "D3DERR_NOVIEWPORTS"; + case D3DERR_VIEWPORTDATANOTSET : // (773) + return "D3DERR_VIEWPORTDATANOTSET"; + case D3DERR_VIEWPORTHASNODEVICE : // (774) + return "D3DERR_VIEWPORTHASNODEVICE"; + case D3DERR_NOCURRENTVIEWPORT : // (775) + return "D3DERR_NOCURRENTVIEWPORT"; + case D3DERR_INVALIDVERTEXFORMAT : // (2048) + return "D3DERR_INVALIDVERTEXFORMAT"; + case D3DERR_COLORKEYATTACHED : // (2050) + return "D3DERR_COLORKEYATTACHED"; + case D3DERR_VERTEXBUFFEROPTIMIZED : // (2060) + return "D3DERR_VERTEXBUFFEROPTIMIZED"; + case D3DERR_VBUF_CREATE_FAILED : // (2061) + return "D3DERR_VBUF_CREATE_FAILED"; + case D3DERR_VERTEXBUFFERLOCKED : // (2062) + return "D3DERR_VERTEXBUFFERLOCKED"; + case D3DERR_ZBUFFER_NOTPRESENT : // (2070) + return "D3DERR_ZBUFFER_NOTPRESENT"; + case D3DERR_STENCILBUFFER_NOTPRESENT : // (2071) + return "D3DERR_STENCILBUFFER_NOTPRESENT"; + case D3DERR_WRONGTEXTUREFORMAT : // (2072) + return "D3DERR_WRONGTEXTUREFORMAT"; + case D3DERR_UNSUPPORTEDCOLOROPERATION : // (2073) + return "D3DERR_UNSUPPORTEDCOLOROPERATION"; + case D3DERR_UNSUPPORTEDCOLORARG : // (2074) + return "D3DERR_UNSUPPORTEDCOLORARG"; + case D3DERR_UNSUPPORTEDALPHAOPERATION : // (2075) + return "D3DERR_UNSUPPORTEDALPHAOPERATION"; + case D3DERR_UNSUPPORTEDALPHAARG : // (2076) + return "D3DERR_UNSUPPORTEDALPHAARG"; + case D3DERR_TOOMANYOPERATIONS : // (2077) + return "D3DERR_TOOMANYOPERATIONS"; + case D3DERR_CONFLICTINGTEXTUREFILTER : // (2078) + return "D3DERR_CONFLICTINGTEXTUREFILTER"; + case D3DERR_UNSUPPORTEDFACTORVALUE : // (2079) + return "D3DERR_UNSUPPORTEDFACTORVALUE"; + case D3DERR_CONFLICTINGRENDERSTATE : // (2081) + return "D3DERR_CONFLICTINGRENDERSTATE"; + case D3DERR_UNSUPPORTEDTEXTUREFILTER : // (2082) + return "D3DERR_UNSUPPORTEDTEXTUREFILTER"; + case D3DERR_TOOMANYPRIMITIVES : // (2083) + return "D3DERR_TOOMANYPRIMITIVES"; + case D3DERR_INVALIDMATRIX : // (2084) + return "D3DERR_INVALIDMATRIX"; + case D3DERR_TOOMANYVERTICES : // (2085) + return "D3DERR_TOOMANYVERTICES"; + case D3DERR_CONFLICTINGTEXTUREPALETTE : // (2086) + return "D3DERR_CONFLICTINGTEXTUREPALETTE"; + //#if DX7 + case D3DERR_VERTEXBUFFERUNLOCKFAILED : // (2063) + return "D3DERR_VERTEXBUFFERUNLOCKFAILED"; + case D3DERR_INVALIDSTATEBLOCK : // (2100) + return "D3DERR_INVALIDSTATEBLOCK"; + case D3DERR_INBEGINSTATEBLOCK : // (2101) + return "D3DERR_INBEGINSTATEBLOCK"; + case D3DERR_NOTINBEGINSTATEBLOCK : // (2102) + return "D3DERR_NOTINBEGINSTATEBLOCK"; + //case D3DERR_INOVERLAYSTATEBLOCK : // (2103) + // return "D3DERR_INOVERLAYSTATEBLOCK"; + case DDERR_NOSTEREOHARDWARE : // ( 181 ) + return "DDERR_NOSTEREOHARDWARE "; + case DDERR_NOSURFACELEFT : // ( 182 ) + return "DDERR_NOSURFACELEFT "; + case DDERR_DDSCAPSCOMPLEXREQUIRED : // ( 542 ) + return "DDERR_DDSCAPSCOMPLEXREQUIRED"; + case DDERR_NOTONMIPMAPSUBLEVEL : // ( 603 ) + return "DDERR_NOTONMIPMAPSUBLEVEL"; + case DDERR_TESTFINISHED : // ( 692 ) + return "DDERR_TESTFINISHED"; + case DDERR_NEWMODE : // ( 693 ) + return "DDERR_NEWMODE"; + //#endif + //case D3DERR_COMMAND_UNPARSED : // (3000) + /// return "case";//D3DERR_COMMAND_UNPARSED : // (3000) + + case DDERR_ALREADYINITIALIZED : // ( 5 ) + return "DDERR_ALREADYINITIALIZED "; + case DDERR_CANNOTATTACHSURFACE : // ( 10 ) + return "DDERR_CANNOTATTACHSURFACE "; + case DDERR_CANNOTDETACHSURFACE : // ( 20 ) + return "DDERR_CANNOTDETACHSURFACE "; + case DDERR_CURRENTLYNOTAVAIL : // ( 40 ) + return "DDERR_CURRENTLYNOTAVAIL "; + case DDERR_EXCEPTION : // ( 55 ) + return "DDERR_EXCEPTION "; + case DDERR_HEIGHTALIGN : // ( 90 ) + return "DDERR_HEIGHTALIGN "; + case DDERR_INCOMPATIBLEPRIMARY : // ( 95 ) + return "DDERR_INCOMPATIBLEPRIMARY "; + case DDERR_INVALIDCAPS : // ( 100 ) + return "DDERR_INVALIDCAPS "; + case DDERR_INVALIDCLIPLIST : // ( 110 ) + return "DDERR_INVALIDCLIPLIST "; + case DDERR_INVALIDMODE : // ( 120 ) + return "DDERR_INVALIDMODE "; + case DDERR_INVALIDOBJECT : // ( 130 ) + return "DDERR_INVALIDOBJECT "; + case DDERR_INVALIDPIXELFORMAT : // ( 145 ) + return "DDERR_INVALIDPIXELFORMAT "; + case DDERR_INVALIDRECT : // ( 150 ) + return "DDERR_INVALIDRECT "; + case DDERR_LOCKEDSURFACES : // ( 160 ) + return "DDERR_LOCKEDSURFACES "; + case DDERR_NO3D : // ( 170 ) + return "DDERR_NO3D "; + case DDERR_NOALPHAHW : // ( 180 ) + return "DDERR_NOALPHAHW "; + case DDERR_NOCLIPLIST : // ( 205 ) + return "DDERR_NOCLIPLIST "; + case DDERR_NOCOLORCONVHW : // ( 210 ) + return "DDERR_NOCOLORCONVHW "; + case DDERR_NOCOOPERATIVELEVELSET : // ( 212 ) + return "DDERR_NOCOOPERATIVELEVELSET "; + case DDERR_NOCOLORKEY : // ( 215 ) + return "DDERR_NOCOLORKEY "; + case DDERR_NOCOLORKEYHW : // ( 220 ) + return "DDERR_NOCOLORKEYHW "; + case DDERR_NODIRECTDRAWSUPPORT : // ( 222 ) + return "DDERR_NODIRECTDRAWSUPPORT "; + case DDERR_NOEXCLUSIVEMODE : // ( 225 ) + return "DDERR_NOEXCLUSIVEMODE "; + case DDERR_NOFLIPHW : // ( 230 ) + return "DDERR_NOFLIPHW "; + case DDERR_NOGDI : // ( 240 ) + return "DDERR_NOGDI "; + case DDERR_NOMIRRORHW : // ( 250 ) + return "DDERR_NOMIRRORHW "; + case DDERR_NOTFOUND : // ( 255 ) + return "DDERR_NOTFOUND "; + case DDERR_NOOVERLAYHW : // ( 260 ) + return "DDERR_NOOVERLAYHW "; + case DDERR_OVERLAPPINGRECTS : // ( 270 ) + return "DDERR_OVERLAPPINGRECTS "; + case DDERR_NORASTEROPHW : // ( 280 ) + return "DDERR_NORASTEROPHW "; + case DDERR_NOROTATIONHW : // ( 290 ) + return "DDERR_NOROTATIONHW "; + case DDERR_NOSTRETCHHW : // ( 310 ) + return "DDERR_NOSTRETCHHW "; + case DDERR_NOT4BITCOLOR : // ( 316 ) + return "DDERR_NOT4BITCOLOR "; + case DDERR_NOT4BITCOLORINDEX : // ( 317 ) + return "DDERR_NOT4BITCOLORINDEX "; + case DDERR_NOT8BITCOLOR : // ( 320 ) + return "DDERR_NOT8BITCOLOR "; + case DDERR_NOTEXTUREHW : // ( 330 ) + return "DDERR_NOTEXTUREHW "; + case DDERR_NOVSYNCHW : // ( 335 ) + return "DDERR_NOVSYNCHW "; + case DDERR_NOZBUFFERHW : // ( 340 ) + return "DDERR_NOZBUFFERHW "; + case DDERR_NOZOVERLAYHW : // ( 350 ) + return "DDERR_NOZOVERLAYHW "; + case DDERR_OUTOFCAPS : // ( 360 ) + return "DDERR_OUTOFCAPS "; + case DDERR_OUTOFVIDEOMEMORY : // ( 380 ) + return "DDERR_OUTOFVIDEOMEMORY "; + case DDERR_OVERLAYCANTCLIP : // ( 382 ) + return "DDERR_OVERLAYCANTCLIP "; + case DDERR_OVERLAYCOLORKEYONLYONEACTIVE : // ( 384 ) + return "DDERR_OVERLAYCOLORKEYONLYONEACTIVE "; + case DDERR_PALETTEBUSY : // ( 387 ) + return "DDERR_PALETTEBUSY "; + case DDERR_COLORKEYNOTSET : // ( 400 ) + return "DDERR_COLORKEYNOTSET "; + case DDERR_SURFACEALREADYATTACHED : // ( 410 ) + return "DDERR_SURFACEALREADYATTACHED "; + case DDERR_SURFACEALREADYDEPENDENT : // ( 420 ) + return "DDERR_SURFACEALREADYDEPENDENT "; + case DDERR_SURFACEBUSY : // ( 430 ) + return "DDERR_SURFACEBUSY "; + case DDERR_CANTLOCKSURFACE : // ( 435 ) + return "DDERR_CANTLOCKSURFACE"; + case DDERR_SURFACEISOBSCURED : // ( 440 ) + return "DDERR_SURFACEISOBSCURED "; + case DDERR_SURFACELOST : // ( 450 ) + return "DDERR_SURFACELOST "; + case DDERR_SURFACENOTATTACHED : // ( 460 ) + return "DDERR_SURFACENOTATTACHED "; + case DDERR_TOOBIGHEIGHT : // ( 470 ) + return "DDERR_TOOBIGHEIGHT "; + case DDERR_TOOBIGSIZE : // ( 480 ) + return "DDERR_TOOBIGSIZE "; + case DDERR_TOOBIGWIDTH : // ( 490 ) + return "DDERR_TOOBIGWIDTH "; + case DDERR_UNSUPPORTEDFORMAT : // ( 510 ) + return "DDERR_UNSUPPORTEDFORMAT "; + case DDERR_UNSUPPORTEDMASK : // ( 520 ) + return "DDERR_UNSUPPORTEDMASK "; + case DDERR_INVALIDSTREAM : // ( 521 ) + return "DDERR_INVALIDSTREAM"; + case DDERR_VERTICALBLANKINPROGRESS : // ( 537 ) + return "DDERR_VERTICALBLANKINPROGRESS "; + case DDERR_WASSTILLDRAWING : // ( 540 ) + return "DDERR_WASSTILLDRAWING "; + case DDERR_XALIGN : // ( 560 ) + return "DDERR_XALIGN "; + case DDERR_INVALIDDIRECTDRAWGUID : // ( 561 ) + return "DDERR_INVALIDDIRECTDRAWGUID "; + case DDERR_DIRECTDRAWALREADYCREATED : // ( 562 ) + return "DDERR_DIRECTDRAWALREADYCREATED "; + case DDERR_NODIRECTDRAWHW : // ( 563 ) + return "DDERR_NODIRECTDRAWHW "; + case DDERR_PRIMARYSURFACEALREADYEXISTS : // ( 564 ) + return "DDERR_PRIMARYSURFACEALREADYEXISTS "; + case DDERR_NOEMULATION : // ( 565 ) + return "DDERR_NOEMULATION "; + case DDERR_REGIONTOOSMALL : // ( 566 ) + return "DDERR_REGIONTOOSMALL "; + case DDERR_CLIPPERISUSINGHWND : // ( 567 ) + return "DDERR_CLIPPERISUSINGHWND "; + case DDERR_NOCLIPPERATTACHED : // ( 568 ) + return "DDERR_NOCLIPPERATTACHED "; + case DDERR_NOHWND : // ( 569 ) + return "DDERR_NOHWND "; + case DDERR_HWNDSUBCLASSED : // ( 570 ) + return "DDERR_HWNDSUBCLASSED "; + case DDERR_HWNDALREADYSET : // ( 571 ) + return "DDERR_HWNDALREADYSET "; + case DDERR_NOPALETTEATTACHED : // ( 572 ) + return "DDERR_NOPALETTEATTACHED "; + case DDERR_NOPALETTEHW : // ( 573 ) + return "DDERR_NOPALETTEHW "; + case DDERR_BLTFASTCANTCLIP : // ( 574 ) + return "DDERR_BLTFASTCANTCLIP "; + case DDERR_NOBLTHW : // ( 575 ) + return "DDERR_NOBLTHW "; + case DDERR_NODDROPSHW : // ( 576 ) + return "DDERR_NODDROPSHW "; + case DDERR_OVERLAYNOTVISIBLE : // ( 577 ) + return "DDERR_OVERLAYNOTVISIBLE "; + case DDERR_NOOVERLAYDEST : // ( 578 ) + return "DDERR_NOOVERLAYDEST "; + case DDERR_INVALIDPOSITION : // ( 579 ) + return "DDERR_INVALIDPOSITION "; + case DDERR_NOTAOVERLAYSURFACE : // ( 580 ) + return "DDERR_NOTAOVERLAYSURFACE "; + case DDERR_EXCLUSIVEMODEALREADYSET : // ( 581 ) + return "DDERR_EXCLUSIVEMODEALREADYSET "; + case DDERR_NOTFLIPPABLE : // ( 582 ) + return "DDERR_NOTFLIPPABLE "; + case DDERR_CANTDUPLICATE : // ( 583 ) + return "DDERR_CANTDUPLICATE "; + case DDERR_NOTLOCKED : // ( 584 ) + return "DDERR_NOTLOCKED "; + case DDERR_CANTCREATEDC : // ( 585 ) + return "DDERR_CANTCREATEDC "; + case DDERR_NODC : // ( 586 ) + return "DDERR_NODC "; + case DDERR_WRONGMODE : // ( 587 ) + return "DDERR_WRONGMODE "; + case DDERR_IMPLICITLYCREATED : // ( 588 ) + return "DDERR_IMPLICITLYCREATED "; + case DDERR_NOTPALETTIZED : // ( 589 ) + return "DDERR_NOTPALETTIZED "; + case DDERR_UNSUPPORTEDMODE : // ( 590 ) + return "DDERR_UNSUPPORTEDMODE "; + case DDERR_NOMIPMAPHW : // ( 591 ) + return "DDERR_NOMIPMAPHW "; + case DDERR_INVALIDSURFACETYPE : // ( 592 ) + return "DDERR_INVALIDSURFACETYPE"; + case DDERR_NOOPTIMIZEHW : // ( 600 ) + return "DDERR_NOOPTIMIZEHW"; + case DDERR_NOTLOADED : // ( 601 ) + return "DDERR_NOTLOADED"; + case DDERR_NOFOCUSWINDOW : // ( 602 ) + return "DDERR_NOFOCUSWINDOW"; + case DDERR_DCALREADYCREATED : // ( 620 ) + return "DDERR_DCALREADYCREATED "; + case DDERR_NONONLOCALVIDMEM : // ( 630 ) + return "DDERR_NONONLOCALVIDMEM"; + case DDERR_CANTPAGELOCK : // ( 640 ) + return "DDERR_CANTPAGELOCK "; + case DDERR_CANTPAGEUNLOCK : // ( 660 ) + return "DDERR_CANTPAGEUNLOCK "; + case DDERR_NOTPAGELOCKED : // ( 680 ) + return "DDERR_NOTPAGELOCKED "; + case DDERR_MOREDATA : // ( 690 ) + return "DDERR_MOREDATA "; + case DDERR_EXPIRED : // ( 691 ) + return "DDERR_EXPIRED"; + case DDERR_VIDEONOTACTIVE : // ( 695 ) + return "DDERR_VIDEONOTACTIVE "; + case DDERR_DEVICEDOESNTOWNSURFACE : // ( 699 ) + return "DDERR_DEVICEDOESNTOWNSURFACE "; + case DXFILEERR_BADOBJECT : // (850) + return "DXFILEERR_BADOBJECT"; + case DXFILEERR_BADVALUE : // (851) + return "DXFILEERR_BADVALUE"; + case DXFILEERR_BADTYPE : // (852) + return "DXFILEERR_BADTYPE"; + case DXFILEERR_BADSTREAMHANDLE : // (853) + return "DXFILEERR_BADSTREAMHANDLE"; + case DXFILEERR_BADALLOC : // (854) + return "DXFILEERR_BADALLOC"; + case DXFILEERR_NOTFOUND : // (855) + return "DXFILEERR_NOTFOUND"; + case DXFILEERR_NOTDONEYET : // (856) + return "DXFILEERR_NOTDONEYET"; + case DXFILEERR_FILENOTFOUND : // (857) + return "DXFILEERR_FILENOTFOUND"; + case DXFILEERR_RESOURCENOTFOUND : // (858) + return "DXFILEERR_RESOURCENOTFOUND"; + case DXFILEERR_URLNOTFOUND : // (859) + return "DXFILEERR_URLNOTFOUND"; + case DXFILEERR_BADRESOURCE : // (860) + return "DXFILEERR_BADRESOURCE"; + case DXFILEERR_BADFILETYPE : // (861) + return "DXFILEERR_BADFILETYPE"; + case DXFILEERR_BADFILEVERSION : // (862) + return "DXFILEERR_BADFILEVERSION"; + case DXFILEERR_BADFILEFLOATSIZE : // (863) + return "DXFILEERR_BADFILEFLOATSIZE"; + case DXFILEERR_BADFILECOMPRESSIONTYPE : // (864) + return "DXFILEERR_BADFILECOMPRESSIONTYPE"; + case DXFILEERR_BADFILE : // (865) + return "DXFILEERR_BADFILE"; + case DXFILEERR_PARSEERROR : // (866) + return "DXFILEERR_PARSEERROR"; + case DXFILEERR_NOTEMPLATE : // (867) + return "DXFILEERR_NOTEMPLATE"; + case DXFILEERR_BADARRAYSIZE : // (868) + return "DXFILEERR_BADARRAYSIZE"; + case DXFILEERR_BADDATAREFERENCE : // (869) + return "DXFILEERR_BADDATAREFERENCE"; + case DXFILEERR_INTERNALERROR : // (870) + return "DXFILEERR_INTERNALERROR"; + case DXFILEERR_NOMOREOBJECTS : // (871) + return "DXFILEERR_NOMOREOBJECTS"; + case DXFILEERR_BADINTRINSICS : // (872) + return "DXFILEERR_BADINTRINSICS"; + case DXFILEERR_NOMORESTREAMHANDLES : // (873) + return "DXFILEERR_NOMORESTREAMHANDLES"; + case DXFILEERR_NOMOREDATA : // (874) + return "DXFILEERR_NOMOREDATA"; + case DXFILEERR_BADCACHEFILE : // (875) + return "DXFILEERR_BADCACHEFILE"; + case DXFILEERR_NOINTERNET : // (876) + return "DXFILEERR_NOINTERNET"; + + case E_UNEXPECTED : + return "E_UNEXPECTED "; + case E_NOTIMPL : + return "E_NOTIMPL "; + case E_OUTOFMEMORY : + return "E_OUTOFMEMORY "; + case E_INVALIDARG : + return "E_INVALIDARG or DDERR_INVALIDPARAMS"; + case E_NOINTERFACE : + return "E_NOINTERFACE "; + case E_POINTER : + return "E_POINTER "; + case E_HANDLE : + return "E_HANDLE "; + case E_ABORT : + return "E_ABORT "; + // case E_FAIL : + // return "E_FAIL "; + case E_ACCESSDENIED : + return "E_ACCESSDENIED "; + case E_PENDING : + return "E_PENDING "; + case CO_E_INIT_TLS : + return "CO_E_INIT_TLS "; + case CO_E_INIT_SHARED_ALLOCATOR : + return "CO_E_INIT_SHARED_ALLOCATOR "; + case CO_E_INIT_MEMORY_ALLOCATOR : + return "CO_E_INIT_MEMORY_ALLOCATOR "; + case CO_E_INIT_CLASS_CACHE : + return "CO_E_INIT_CLASS_CACHE "; + case CO_E_INIT_RPC_CHANNEL : + return "CO_E_INIT_RPC_CHANNEL "; + case CO_E_INIT_TLS_SET_CHANNEL_CONTROL : + return "CO_E_INIT_TLS_SET_CHANNEL_CONTROL "; + case CO_E_INIT_TLS_CHANNEL_CONTROL : + return "CO_E_INIT_TLS_CHANNEL_CONTROL "; + case CO_E_INIT_UNACCEPTED_USER_ALLOCATOR : + return "CO_E_INIT_UNACCEPTED_USER_ALLOCATOR "; + case CO_E_INIT_SCM_MUTEX_EXISTS : + return "CO_E_INIT_SCM_MUTEX_EXISTS "; + case CO_E_INIT_SCM_FILE_MAPPING_EXISTS : + return "CO_E_INIT_SCM_FILE_MAPPING_EXISTS "; + case CO_E_INIT_SCM_MAP_VIEW_OF_FILE : + return "CO_E_INIT_SCM_MAP_VIEW_OF_FILE "; + case CO_E_INIT_SCM_EXEC_FAILURE : + return "CO_E_INIT_SCM_EXEC_FAILURE "; + case CO_E_INIT_ONLY_SINGLE_THREADED : + return "CO_E_INIT_ONLY_SINGLE_THREADED "; + case CO_E_CANT_REMOTE : + return "CO_E_CANT_REMOTE "; + case CO_E_BAD_SERVER_NAME : + return "CO_E_BAD_SERVER_NAME "; + case CO_E_WRONG_SERVER_IDENTITY : + return "CO_E_WRONG_SERVER_IDENTITY "; + case CO_E_OLE1DDE_DISABLED : + return "CO_E_OLE1DDE_DISABLED "; + case CO_E_RUNAS_SYNTAX : + return "CO_E_RUNAS_SYNTAX "; + case CO_E_CREATEPROCESS_FAILURE : + return "CO_E_CREATEPROCESS_FAILURE "; + case CO_E_RUNAS_CREATEPROCESS_FAILURE : + return "CO_E_RUNAS_CREATEPROCESS_FAILURE "; + case CO_E_RUNAS_LOGON_FAILURE : + return "CO_E_RUNAS_LOGON_FAILURE "; + case CO_E_LAUNCH_PERMSSION_DENIED : + return "CO_E_LAUNCH_PERMSSION_DENIED "; + case CO_E_START_SERVICE_FAILURE : + return "CO_E_START_SERVICE_FAILURE "; + case CO_E_REMOTE_COMMUNICATION_FAILURE : + return "CO_E_REMOTE_COMMUNICATION_FAILURE "; + case CO_E_SERVER_START_TIMEOUT : + return "CO_E_SERVER_START_TIMEOUT "; + case CO_E_CLSREG_INCONSISTENT : + return "CO_E_CLSREG_INCONSISTENT "; + case CO_E_IIDREG_INCONSISTENT : + return "CO_E_IIDREG_INCONSISTENT "; + case CO_E_NOT_SUPPORTED : + return "CO_E_NOT_SUPPORTED "; + case CO_E_RELOAD_DLL : + return "CO_E_RELOAD_DLL "; + case CO_E_MSI_ERROR : + return "CO_E_MSI_ERROR "; + case OLE_E_OLEVERB : + return "OLE_E_OLEVERB "; + case OLE_E_ADVF : + return "OLE_E_ADVF "; + case OLE_E_ENUM_NOMORE : + return "OLE_E_ENUM_NOMORE "; + case OLE_E_ADVISENOTSUPPORTED : + return "OLE_E_ADVISENOTSUPPORTED "; + case OLE_E_NOCONNECTION : + return "OLE_E_NOCONNECTION "; + case OLE_E_NOTRUNNING : + return "OLE_E_NOTRUNNING "; + case OLE_E_NOCACHE : + return "OLE_E_NOCACHE "; + case OLE_E_BLANK : + return "OLE_E_BLANK "; + case OLE_E_CLASSDIFF : + return "OLE_E_CLASSDIFF "; + case OLE_E_CANT_GETMONIKER : + return "OLE_E_CANT_GETMONIKER "; + case OLE_E_CANT_BINDTOSOURCE : + return "OLE_E_CANT_BINDTOSOURCE "; + case OLE_E_STATIC : + return "OLE_E_STATIC "; + case OLE_E_PROMPTSAVECANCELLED : + return "OLE_E_PROMPTSAVECANCELLED "; + case OLE_E_INVALIDRECT : + return "OLE_E_INVALIDRECT "; + case OLE_E_WRONGCOMPOBJ : + return "OLE_E_WRONGCOMPOBJ "; + case OLE_E_INVALIDHWND : + return "OLE_E_INVALIDHWND "; + case OLE_E_NOT_INPLACEACTIVE : + return "OLE_E_NOT_INPLACEACTIVE "; + case OLE_E_CANTCONVERT : + return "OLE_E_CANTCONVERT "; + case OLE_E_NOSTORAGE : + return "OLE_E_NOSTORAGE "; + case DV_E_FORMATETC : + return "DV_E_FORMATETC "; + case DV_E_DVTARGETDEVICE : + return "DV_E_DVTARGETDEVICE "; + case DV_E_STGMEDIUM : + return "DV_E_STGMEDIUM "; + case DV_E_STATDATA : + return "DV_E_STATDATA "; + case DV_E_LINDEX : + return "DV_E_LINDEX "; + case DV_E_TYMED : + return "DV_E_TYMED "; + case DV_E_CLIPFORMAT : + return "DV_E_CLIPFORMAT "; + case DV_E_DVASPECT : + return "DV_E_DVASPECT "; + case DV_E_DVTARGETDEVICE_SIZE : + return "DV_E_DVTARGETDEVICE_SIZE "; + case DV_E_NOIVIEWOBJECT : + return "DV_E_NOIVIEWOBJECT "; + case DRAGDROP_E_NOTREGISTERED : + return "DRAGDROP_E_NOTREGISTERED "; + case DRAGDROP_E_ALREADYREGISTERED : + return "DRAGDROP_E_ALREADYREGISTERED "; + case DRAGDROP_E_INVALIDHWND : + return "DRAGDROP_E_INVALIDHWND "; + case CLASS_E_NOAGGREGATION : + return "CLASS_E_NOAGGREGATION "; + case CLASS_E_CLASSNOTAVAILABLE : + return "CLASS_E_CLASSNOTAVAILABLE "; + case CLASS_E_NOTLICENSED : + return "CLASS_E_NOTLICENSED "; + case VIEW_E_DRAW : + return "VIEW_E_DRAW "; + case REGDB_E_READREGDB : + return "REGDB_E_READREGDB "; + case REGDB_E_WRITEREGDB : + return "REGDB_E_WRITEREGDB "; + case REGDB_E_KEYMISSING : + return "REGDB_E_KEYMISSING "; + case REGDB_E_INVALIDVALUE : + return "REGDB_E_INVALIDVALUE "; + case REGDB_E_CLASSNOTREG : + return "REGDB_E_CLASSNOTREG "; + case REGDB_E_IIDNOTREG : + return "REGDB_E_IIDNOTREG "; + case CAT_E_CATIDNOEXIST : + return "CAT_E_CATIDNOEXIST "; + case CAT_E_NODESCRIPTION : + return "CAT_E_NODESCRIPTION "; + case CS_E_PACKAGE_NOTFOUND : + return "CS_E_PACKAGE_NOTFOUND "; + case CS_E_NOT_DELETABLE : + return "CS_E_NOT_DELETABLE "; + case CS_E_CLASS_NOTFOUND : + return "CS_E_CLASS_NOTFOUND "; + case CS_E_INVALID_VERSION : + return "CS_E_INVALID_VERSION "; + case CS_E_NO_CLASSSTORE : + return "CS_E_NO_CLASSSTORE "; + case CACHE_E_NOCACHE_UPDATED : + return "CACHE_E_NOCACHE_UPDATED "; + case OLEOBJ_E_NOVERBS : + return "OLEOBJ_E_NOVERBS "; + case OLEOBJ_E_INVALIDVERB : + return "OLEOBJ_E_INVALIDVERB "; + case INPLACE_E_NOTUNDOABLE : + return "INPLACE_E_NOTUNDOABLE "; + case INPLACE_E_NOTOOLSPACE : + return "INPLACE_E_NOTOOLSPACE "; + case CONVERT10_E_OLESTREAM_GET : + return "CONVERT10_E_OLESTREAM_GET "; + case CONVERT10_E_OLESTREAM_PUT : + return "CONVERT10_E_OLESTREAM_PUT "; + case CONVERT10_E_OLESTREAM_FMT : + return "CONVERT10_E_OLESTREAM_FMT "; + case CONVERT10_E_OLESTREAM_BITMAP_TO_DIB : + return "CONVERT10_E_OLESTREAM_BITMAP_TO_DIB "; + case CONVERT10_E_STG_FMT : + return "CONVERT10_E_STG_FMT "; + case CONVERT10_E_STG_NO_STD_STREAM : + return "CONVERT10_E_STG_NO_STD_STREAM "; + case CONVERT10_E_STG_DIB_TO_BITMAP : + return "CONVERT10_E_STG_DIB_TO_BITMAP "; + case CLIPBRD_E_CANT_OPEN : + return "CLIPBRD_E_CANT_OPEN "; + case CLIPBRD_E_CANT_EMPTY : + return "CLIPBRD_E_CANT_EMPTY "; + case CLIPBRD_E_CANT_SET : + return "CLIPBRD_E_CANT_SET "; + case CLIPBRD_E_BAD_DATA : + return "CLIPBRD_E_BAD_DATA "; + case CLIPBRD_E_CANT_CLOSE : + return "CLIPBRD_E_CANT_CLOSE "; + case MK_E_CONNECTMANUALLY : + return "MK_E_CONNECTMANUALLY "; + case MK_E_EXCEEDEDDEADLINE : + return "MK_E_EXCEEDEDDEADLINE "; + case MK_E_NEEDGENERIC : + return "MK_E_NEEDGENERIC "; + case MK_E_UNAVAILABLE : + return "MK_E_UNAVAILABLE "; + case MK_E_SYNTAX : + return "MK_E_SYNTAX "; + case MK_E_NOOBJECT : + return "MK_E_NOOBJECT "; + case MK_E_INVALIDEXTENSION : + return "MK_E_INVALIDEXTENSION "; + case MK_E_INTERMEDIATEINTERFACENOTSUPPORTED : + return "MK_E_INTERMEDIATEINTERFACENOTSUPPORTED "; + case MK_E_NOTBINDABLE : + return "MK_E_NOTBINDABLE "; + case MK_E_NOTBOUND : + return "MK_E_NOTBOUND "; + case MK_E_CANTOPENFILE : + return "MK_E_CANTOPENFILE "; + case MK_E_MUSTBOTHERUSER : + return "MK_E_MUSTBOTHERUSER "; + case MK_E_NOINVERSE : + return "MK_E_NOINVERSE "; + case MK_E_NOSTORAGE : + return "MK_E_NOSTORAGE "; + case MK_E_NOPREFIX : + return "MK_E_NOPREFIX "; + case MK_E_ENUMERATION_FAILED : + return "MK_E_ENUMERATION_FAILED "; + case CO_E_NOTINITIALIZED : + return "CO_E_NOTINITIALIZED "; + case CO_E_ALREADYINITIALIZED : + return "CO_E_ALREADYINITIALIZED "; + case CO_E_CANTDETERMINECLASS : + return "CO_E_CANTDETERMINECLASS "; + case CO_E_CLASSSTRING : + return "CO_E_CLASSSTRING "; + case CO_E_IIDSTRING : + return "CO_E_IIDSTRING "; + case CO_E_APPNOTFOUND : + return "CO_E_APPNOTFOUND "; + case CO_E_APPSINGLEUSE : + return "CO_E_APPSINGLEUSE "; + case CO_E_ERRORINAPP : + return "CO_E_ERRORINAPP "; + case CO_E_DLLNOTFOUND : + return "CO_E_DLLNOTFOUND "; + case CO_E_ERRORINDLL : + return "CO_E_ERRORINDLL "; + case CO_E_WRONGOSFORAPP : + return "CO_E_WRONGOSFORAPP "; + case CO_E_OBJNOTREG : + return "CO_E_OBJNOTREG "; + case CO_E_OBJISREG : + return "CO_E_OBJISREG "; + case CO_E_OBJNOTCONNECTED : + return "CO_E_OBJNOTCONNECTED "; + case CO_E_APPDIDNTREG : + return "CO_E_APPDIDNTREG "; + case CO_E_RELEASED : + return "CO_E_RELEASED "; + case CO_E_FAILEDTOIMPERSONATE : + return "CO_E_FAILEDTOIMPERSONATE "; + case CO_E_FAILEDTOGETSECCTX : + return "CO_E_FAILEDTOGETSECCTX "; + case CO_E_FAILEDTOOPENTHREADTOKEN : + return "CO_E_FAILEDTOOPENTHREADTOKEN "; + case CO_E_FAILEDTOGETTOKENINFO : + return "CO_E_FAILEDTOGETTOKENINFO "; + case CO_E_TRUSTEEDOESNTMATCHCLIENT : + return "CO_E_TRUSTEEDOESNTMATCHCLIENT "; + case CO_E_FAILEDTOQUERYCLIENTBLANKET : + return "CO_E_FAILEDTOQUERYCLIENTBLANKET "; + case CO_E_FAILEDTOSETDACL : + return "CO_E_FAILEDTOSETDACL "; + case CO_E_ACCESSCHECKFAILED : + return "CO_E_ACCESSCHECKFAILED "; + case CO_E_NETACCESSAPIFAILED : + return "CO_E_NETACCESSAPIFAILED "; + case CO_E_WRONGTRUSTEENAMESYNTAX : + return "CO_E_WRONGTRUSTEENAMESYNTAX "; + case CO_E_INVALIDSID : + return "CO_E_INVALIDSID "; + case CO_E_CONVERSIONFAILED : + return "CO_E_CONVERSIONFAILED "; + case CO_E_NOMATCHINGSIDFOUND : + return "CO_E_NOMATCHINGSIDFOUND "; + case CO_E_LOOKUPACCSIDFAILED : + return "CO_E_LOOKUPACCSIDFAILED "; + case CO_E_NOMATCHINGNAMEFOUND : + return "CO_E_NOMATCHINGNAMEFOUND "; + case CO_E_LOOKUPACCNAMEFAILED : + return "CO_E_LOOKUPACCNAMEFAILED "; + case CO_E_SETSERLHNDLFAILED : + return "CO_E_SETSERLHNDLFAILED "; + case CO_E_FAILEDTOGETWINDIR : + return "CO_E_FAILEDTOGETWINDIR "; + case CO_E_PATHTOOLONG : + return "CO_E_PATHTOOLONG "; + case CO_E_FAILEDTOGENUUID : + return "CO_E_FAILEDTOGENUUID "; + case CO_E_FAILEDTOCREATEFILE : + return "CO_E_FAILEDTOCREATEFILE "; + case CO_E_FAILEDTOCLOSEHANDLE : + return "CO_E_FAILEDTOCLOSEHANDLE "; + case CO_E_EXCEEDSYSACLLIMIT : + return "CO_E_EXCEEDSYSACLLIMIT "; + case CO_E_ACESINWRONGORDER : + return "CO_E_ACESINWRONGORDER "; + case CO_E_INCOMPATIBLESTREAMVERSION : + return "CO_E_INCOMPATIBLESTREAMVERSION "; + case CO_E_FAILEDTOOPENPROCESSTOKEN : + return "CO_E_FAILEDTOOPENPROCESSTOKEN "; + case CO_E_DECODEFAILED : + return "CO_E_DECODEFAILED "; + case CO_E_ACNOTINITIALIZED : + return "CO_E_ACNOTINITIALIZED "; + case OLE_S_USEREG : + return "OLE_S_USEREG "; + case OLE_S_STATIC : + return "OLE_S_STATIC "; + case OLE_S_MAC_CLIPFORMAT : + return "OLE_S_MAC_CLIPFORMAT "; + case DRAGDROP_S_DROP : + return "DRAGDROP_S_DROP "; + case DRAGDROP_S_CANCEL : + return "DRAGDROP_S_CANCEL "; + case DRAGDROP_S_USEDEFAULTCURSORS : + return "DRAGDROP_S_USEDEFAULTCURSORS "; + case DATA_S_SAMEFORMATETC : + return "DATA_S_SAMEFORMATETC "; + case VIEW_S_ALREADY_FROZEN : + return "VIEW_S_ALREADY_FROZEN "; + case CACHE_S_FORMATETC_NOTSUPPORTED : + return "CACHE_S_FORMATETC_NOTSUPPORTED "; + case CACHE_S_SAMECACHE : + return "CACHE_S_SAMECACHE "; + case CACHE_S_SOMECACHES_NOTUPDATED : + return "CACHE_S_SOMECACHES_NOTUPDATED "; + case OLEOBJ_S_INVALIDVERB : + return "OLEOBJ_S_INVALIDVERB "; + case OLEOBJ_S_CANNOT_DOVERB_NOW : + return "OLEOBJ_S_CANNOT_DOVERB_NOW "; + case OLEOBJ_S_INVALIDHWND : + return "OLEOBJ_S_INVALIDHWND "; + case INPLACE_S_TRUNCATED : + return "INPLACE_S_TRUNCATED "; + case CONVERT10_S_NO_PRESENTATION : + return "CONVERT10_S_NO_PRESENTATION "; + case MK_S_REDUCED_TO_SELF : + return "MK_S_REDUCED_TO_SELF "; + case MK_S_ME : + return "MK_S_ME "; + case MK_S_HIM : + return "MK_S_HIM "; + case MK_S_US : + return "MK_S_US "; + case MK_S_MONIKERALREADYREGISTERED : + return "MK_S_MONIKERALREADYREGISTERED "; + case CO_E_CLASS_CREATE_FAILED : + return "CO_E_CLASS_CREATE_FAILED "; + case CO_E_SCM_ERROR : + return "CO_E_SCM_ERROR "; + case CO_E_SCM_RPC_FAILURE : + return "CO_E_SCM_RPC_FAILURE "; + case CO_E_BAD_PATH : + return "CO_E_BAD_PATH "; + case CO_E_SERVER_EXEC_FAILURE : + return "CO_E_SERVER_EXEC_FAILURE "; + case CO_E_OBJSRV_RPC_FAILURE : + return "CO_E_OBJSRV_RPC_FAILURE "; + case MK_E_NO_NORMALIZED : + return "MK_E_NO_NORMALIZED "; + case CO_E_SERVER_STOPPING : + return "CO_E_SERVER_STOPPING "; + case MEM_E_INVALID_ROOT : + return "MEM_E_INVALID_ROOT "; + case MEM_E_INVALID_LINK : + return "MEM_E_INVALID_LINK "; + case MEM_E_INVALID_SIZE : + return "MEM_E_INVALID_SIZE "; + case CO_S_NOTALLINTERFACES : + return "CO_S_NOTALLINTERFACES "; + case DISP_E_UNKNOWNINTERFACE : + return "DISP_E_UNKNOWNINTERFACE "; + case DISP_E_MEMBERNOTFOUND : + return "DISP_E_MEMBERNOTFOUND "; + case DISP_E_PARAMNOTFOUND : + return "DISP_E_PARAMNOTFOUND "; + case DISP_E_TYPEMISMATCH : + return "DISP_E_TYPEMISMATCH "; + case DISP_E_UNKNOWNNAME : + return "DISP_E_UNKNOWNNAME "; + case DISP_E_NONAMEDARGS : + return "DISP_E_NONAMEDARGS "; + case DISP_E_BADVARTYPE : + return "DISP_E_BADVARTYPE "; + case DISP_E_EXCEPTION : + return "DISP_E_EXCEPTION "; + case DISP_E_OVERFLOW : + return "DISP_E_OVERFLOW "; + case DISP_E_BADINDEX : + return "DISP_E_BADINDEX "; + case DISP_E_UNKNOWNLCID : + return "DISP_E_UNKNOWNLCID "; + case DISP_E_ARRAYISLOCKED : + return "DISP_E_ARRAYISLOCKED "; + case DISP_E_BADPARAMCOUNT : + return "DISP_E_BADPARAMCOUNT "; + case DISP_E_PARAMNOTOPTIONAL : + return "DISP_E_PARAMNOTOPTIONAL "; + case DISP_E_BADCALLEE : + return "DISP_E_BADCALLEE "; + case DISP_E_NOTACOLLECTION : + return "DISP_E_NOTACOLLECTION "; + case DISP_E_DIVBYZERO : + return "DISP_E_DIVBYZERO "; + case TYPE_E_BUFFERTOOSMALL : + return "TYPE_E_BUFFERTOOSMALL "; + case TYPE_E_FIELDNOTFOUND : + return "TYPE_E_FIELDNOTFOUND "; + case TYPE_E_INVDATAREAD : + return "TYPE_E_INVDATAREAD "; + case TYPE_E_UNSUPFORMAT : + return "TYPE_E_UNSUPFORMAT "; + case TYPE_E_REGISTRYACCESS : + return "TYPE_E_REGISTRYACCESS "; + case TYPE_E_LIBNOTREGISTERED : + return "TYPE_E_LIBNOTREGISTERED "; + case TYPE_E_UNDEFINEDTYPE : + return "TYPE_E_UNDEFINEDTYPE "; + case TYPE_E_QUALIFIEDNAMEDISALLOWED : + return "TYPE_E_QUALIFIEDNAMEDISALLOWED "; + case TYPE_E_INVALIDSTATE : + return "TYPE_E_INVALIDSTATE "; + case TYPE_E_WRONGTYPEKIND : + return "TYPE_E_WRONGTYPEKIND "; + case TYPE_E_ELEMENTNOTFOUND : + return "TYPE_E_ELEMENTNOTFOUND "; + case TYPE_E_AMBIGUOUSNAME : + return "TYPE_E_AMBIGUOUSNAME "; + case TYPE_E_NAMECONFLICT : + return "TYPE_E_NAMECONFLICT "; + case TYPE_E_UNKNOWNLCID : + return "TYPE_E_UNKNOWNLCID "; + case TYPE_E_DLLFUNCTIONNOTFOUND : + return "TYPE_E_DLLFUNCTIONNOTFOUND "; + case TYPE_E_BADMODULEKIND : + return "TYPE_E_BADMODULEKIND "; + case TYPE_E_SIZETOOBIG : + return "TYPE_E_SIZETOOBIG "; + case TYPE_E_DUPLICATEID : + return "TYPE_E_DUPLICATEID "; + case TYPE_E_INVALIDID : + return "TYPE_E_INVALIDID "; + case TYPE_E_TYPEMISMATCH : + return "TYPE_E_TYPEMISMATCH "; + case TYPE_E_OUTOFBOUNDS : + return "TYPE_E_OUTOFBOUNDS "; + case TYPE_E_IOERROR : + return "TYPE_E_IOERROR "; + case TYPE_E_CANTCREATETMPFILE : + return "TYPE_E_CANTCREATETMPFILE "; + case TYPE_E_CANTLOADLIBRARY : + return "TYPE_E_CANTLOADLIBRARY "; + case TYPE_E_INCONSISTENTPROPFUNCS : + return "TYPE_E_INCONSISTENTPROPFUNCS "; + case TYPE_E_CIRCULARTYPE : + return "TYPE_E_CIRCULARTYPE "; + case STG_E_INVALIDFUNCTION : + return "STG_E_INVALIDFUNCTION "; + case STG_E_FILENOTFOUND : + return "STG_E_FILENOTFOUND "; + case STG_E_PATHNOTFOUND : + return "STG_E_PATHNOTFOUND "; + case STG_E_TOOMANYOPENFILES : + return "STG_E_TOOMANYOPENFILES "; + case STG_E_ACCESSDENIED : + return "STG_E_ACCESSDENIED "; + case STG_E_INVALIDHANDLE : + return "STG_E_INVALIDHANDLE "; + case STG_E_INSUFFICIENTMEMORY : + return "STG_E_INSUFFICIENTMEMORY "; + case STG_E_INVALIDPOINTER : + return "STG_E_INVALIDPOINTER "; + case STG_E_NOMOREFILES : + return "STG_E_NOMOREFILES "; + case STG_E_DISKISWRITEPROTECTED : + return "STG_E_DISKISWRITEPROTECTED "; + case STG_E_SEEKERROR : + return "STG_E_SEEKERROR "; + case STG_E_WRITEFAULT : + return "STG_E_WRITEFAULT "; + case STG_E_READFAULT : + return "STG_E_READFAULT "; + case STG_E_SHAREVIOLATION : + return "STG_E_SHAREVIOLATION "; + case STG_E_LOCKVIOLATION : + return "STG_E_LOCKVIOLATION "; + case STG_E_FILEALREADYEXISTS : + return "STG_E_FILEALREADYEXISTS "; + case STG_E_INVALIDPARAMETER : + return "STG_E_INVALIDPARAMETER "; + case STG_E_MEDIUMFULL : + return "STG_E_MEDIUMFULL "; + case STG_E_PROPSETMISMATCHED : + return "STG_E_PROPSETMISMATCHED "; + case STG_E_ABNORMALAPIEXIT : + return "STG_E_ABNORMALAPIEXIT "; + case STG_E_INVALIDHEADER : + return "STG_E_INVALIDHEADER "; + case STG_E_INVALIDNAME : + return "STG_E_INVALIDNAME "; + case STG_E_UNKNOWN : + return "STG_E_UNKNOWN "; + case STG_E_UNIMPLEMENTEDFUNCTION : + return "STG_E_UNIMPLEMENTEDFUNCTION "; + case STG_E_INVALIDFLAG : + return "STG_E_INVALIDFLAG "; + case STG_E_INUSE : + return "STG_E_INUSE "; + case STG_E_NOTCURRENT : + return "STG_E_NOTCURRENT "; + case STG_E_REVERTED : + return "STG_E_REVERTED "; + case STG_E_CANTSAVE : + return "STG_E_CANTSAVE "; + case STG_E_OLDFORMAT : + return "STG_E_OLDFORMAT "; + case STG_E_OLDDLL : + return "STG_E_OLDDLL "; + case STG_E_SHAREREQUIRED : + return "STG_E_SHAREREQUIRED "; + case STG_E_NOTFILEBASEDSTORAGE : + return "STG_E_NOTFILEBASEDSTORAGE "; + case STG_E_EXTANTMARSHALLINGS : + return "STG_E_EXTANTMARSHALLINGS "; + case STG_E_DOCFILECORRUPT : + return "STG_E_DOCFILECORRUPT "; + case STG_E_BADBASEADDRESS : + return "STG_E_BADBASEADDRESS "; + case STG_E_INCOMPLETE : + return "STG_E_INCOMPLETE "; + case STG_E_TERMINATED : + return "STG_E_TERMINATED "; + case STG_S_CONVERTED : + return "STG_S_CONVERTED "; + case STG_S_BLOCK : + return "STG_S_BLOCK "; + case STG_S_RETRYNOW : + return "STG_S_RETRYNOW "; + case STG_S_MONITORING : + return "STG_S_MONITORING "; + case STG_S_MULTIPLEOPENS : + return "STG_S_MULTIPLEOPENS "; + case STG_S_CONSOLIDATIONFAILED : + return "STG_S_CONSOLIDATIONFAILED "; + case STG_S_CANNOTCONSOLIDATE : + return "STG_S_CANNOTCONSOLIDATE "; + case RPC_E_CALL_REJECTED : + return "RPC_E_CALL_REJECTED "; + case RPC_E_CALL_CANCELED : + return "RPC_E_CALL_CANCELED "; + case RPC_E_CANTPOST_INSENDCALL : + return "RPC_E_CANTPOST_INSENDCALL "; + case RPC_E_CANTCALLOUT_INASYNCCALL : + return "RPC_E_CANTCALLOUT_INASYNCCALL "; + case RPC_E_CANTCALLOUT_INEXTERNALCALL : + return "RPC_E_CANTCALLOUT_INEXTERNALCALL "; + case RPC_E_CONNECTION_TERMINATED : + return "RPC_E_CONNECTION_TERMINATED "; + case RPC_E_SERVER_DIED : + return "RPC_E_SERVER_DIED "; + case RPC_E_CLIENT_DIED : + return "RPC_E_CLIENT_DIED "; + case RPC_E_INVALID_DATAPACKET : + return "RPC_E_INVALID_DATAPACKET "; + case RPC_E_CANTTRANSMIT_CALL : + return "RPC_E_CANTTRANSMIT_CALL "; + case RPC_E_CLIENT_CANTMARSHAL_DATA : + return "RPC_E_CLIENT_CANTMARSHAL_DATA "; + case RPC_E_CLIENT_CANTUNMARSHAL_DATA : + return "RPC_E_CLIENT_CANTUNMARSHAL_DATA "; + case RPC_E_SERVER_CANTMARSHAL_DATA : + return "RPC_E_SERVER_CANTMARSHAL_DATA "; + case RPC_E_SERVER_CANTUNMARSHAL_DATA : + return "RPC_E_SERVER_CANTUNMARSHAL_DATA "; + case RPC_E_INVALID_DATA : + return "RPC_E_INVALID_DATA "; + case RPC_E_INVALID_PARAMETER : + return "RPC_E_INVALID_PARAMETER "; + case RPC_E_CANTCALLOUT_AGAIN : + return "RPC_E_CANTCALLOUT_AGAIN "; + case RPC_E_SERVER_DIED_DNE : + return "RPC_E_SERVER_DIED_DNE "; + case RPC_E_SYS_CALL_FAILED : + return "RPC_E_SYS_CALL_FAILED "; + case RPC_E_OUT_OF_RESOURCES : + return "RPC_E_OUT_OF_RESOURCES "; + case RPC_E_ATTEMPTED_MULTITHREAD : + return "RPC_E_ATTEMPTED_MULTITHREAD "; + case RPC_E_NOT_REGISTERED : + return "RPC_E_NOT_REGISTERED "; + case RPC_E_FAULT : + return "RPC_E_FAULT "; + case RPC_E_SERVERFAULT : + return "RPC_E_SERVERFAULT "; + case RPC_E_CHANGED_MODE : + return "RPC_E_CHANGED_MODE "; + case RPC_E_INVALIDMETHOD : + return "RPC_E_INVALIDMETHOD "; + case RPC_E_DISCONNECTED : + return "RPC_E_DISCONNECTED "; + case RPC_E_RETRY : + return "RPC_E_RETRY "; + case RPC_E_SERVERCALL_RETRYLATER : + return "RPC_E_SERVERCALL_RETRYLATER "; + case RPC_E_SERVERCALL_REJECTED : + return "RPC_E_SERVERCALL_REJECTED "; + case RPC_E_INVALID_CALLDATA : + return "RPC_E_INVALID_CALLDATA "; + case RPC_E_CANTCALLOUT_ININPUTSYNCCALL : + return "RPC_E_CANTCALLOUT_ININPUTSYNCCALL "; + case RPC_E_WRONG_THREAD : + return "RPC_E_WRONG_THREAD "; + case RPC_E_THREAD_NOT_INIT : + return "RPC_E_THREAD_NOT_INIT "; + case RPC_E_VERSION_MISMATCH : + return "RPC_E_VERSION_MISMATCH "; + case RPC_E_INVALID_HEADER : + return "RPC_E_INVALID_HEADER "; + case RPC_E_INVALID_EXTENSION : + return "RPC_E_INVALID_EXTENSION "; + case RPC_E_INVALID_IPID : + return "RPC_E_INVALID_IPID "; + case RPC_E_INVALID_OBJECT : + return "RPC_E_INVALID_OBJECT "; + case RPC_S_CALLPENDING : + return "RPC_S_CALLPENDING "; + case RPC_S_WAITONTIMER : + return "RPC_S_WAITONTIMER "; + case RPC_E_CALL_COMPLETE : + return "RPC_E_CALL_COMPLETE "; + case RPC_E_UNSECURE_CALL : + return "RPC_E_UNSECURE_CALL "; + case RPC_E_TOO_LATE : + return "RPC_E_TOO_LATE "; + case RPC_E_NO_GOOD_SECURITY_PACKAGES : + return "RPC_E_NO_GOOD_SECURITY_PACKAGES "; + case RPC_E_ACCESS_DENIED : + return "RPC_E_ACCESS_DENIED "; + case RPC_E_REMOTE_DISABLED : + return "RPC_E_REMOTE_DISABLED "; + case RPC_E_INVALID_OBJREF : + return "RPC_E_INVALID_OBJREF "; + case RPC_E_NO_CONTEXT : + return "RPC_E_NO_CONTEXT "; + case RPC_E_TIMEOUT : + return "RPC_E_TIMEOUT "; + case RPC_E_NO_SYNC : + return "RPC_E_NO_SYNC "; + case RPC_E_UNEXPECTED : + return "RPC_E_UNEXPECTED "; + case NTE_BAD_UID : + return "NTE_BAD_UID "; + case NTE_BAD_HASH : + return "NTE_BAD_HASH "; + //case NTE_BAD_HASH : + //return "NTE_BAD_HASH "; + case NTE_BAD_KEY : + return "NTE_BAD_KEY "; + case NTE_BAD_LEN : + return "NTE_BAD_LEN "; + case NTE_BAD_DATA : + return "NTE_BAD_DATA "; + case NTE_BAD_SIGNATURE : + return "NTE_BAD_SIGNATURE "; + case NTE_BAD_VER : + return "NTE_BAD_VER "; + case NTE_BAD_ALGID : + return "NTE_BAD_ALGID "; + case NTE_BAD_FLAGS : + return "NTE_BAD_FLAGS "; + case NTE_BAD_TYPE : + return "NTE_BAD_TYPE "; + case NTE_BAD_KEY_STATE : + return "NTE_BAD_KEY_STATE "; + case NTE_BAD_HASH_STATE : + return "NTE_BAD_HASH_STATE "; + case NTE_NO_KEY : + return "NTE_NO_KEY "; + case NTE_NO_MEMORY : + return "NTE_NO_MEMORY "; + case NTE_EXISTS : + return "NTE_EXISTS "; + case NTE_PERM : + return "NTE_PERM "; + case NTE_NOT_FOUND : + return "NTE_NOT_FOUND "; + case NTE_DOUBLE_ENCRYPT : + return "NTE_DOUBLE_ENCRYPT "; + case NTE_BAD_PROVIDER : + return "NTE_BAD_PROVIDER "; + case NTE_BAD_PROV_TYPE : + return "NTE_BAD_PROV_TYPE "; + case NTE_BAD_PUBLIC_KEY : + return "NTE_BAD_PUBLIC_KEY "; + case NTE_BAD_KEYSET : + return "NTE_BAD_KEYSET "; + case NTE_PROV_TYPE_NOT_DEF : + return "NTE_PROV_TYPE_NOT_DEF "; + case NTE_PROV_TYPE_ENTRY_BAD : + return "NTE_PROV_TYPE_ENTRY_BAD "; + case NTE_KEYSET_NOT_DEF : + return "NTE_KEYSET_NOT_DEF "; + case NTE_KEYSET_ENTRY_BAD : + return "NTE_KEYSET_ENTRY_BAD "; + case NTE_PROV_TYPE_NO_MATCH : + return "NTE_PROV_TYPE_NO_MATCH "; + case NTE_SIGNATURE_FILE_BAD : + return "NTE_SIGNATURE_FILE_BAD "; + case NTE_PROVIDER_DLL_FAIL : + return "NTE_PROVIDER_DLL_FAIL "; + case NTE_PROV_DLL_NOT_FOUND : + return "NTE_PROV_DLL_NOT_FOUND "; + case NTE_BAD_KEYSET_PARAM : + return "NTE_BAD_KEYSET_PARAM "; + case NTE_FAIL : + return "NTE_FAIL "; + case NTE_SYS_ERR : + return "NTE_SYS_ERR "; + case CRYPT_E_MSG_ERROR : + return "CRYPT_E_MSG_ERROR "; + case CRYPT_E_UNKNOWN_ALGO : + return "CRYPT_E_UNKNOWN_ALGO "; + case CRYPT_E_OID_FORMAT : + return "CRYPT_E_OID_FORMAT "; + case CRYPT_E_INVALID_MSG_TYPE : + return "CRYPT_E_INVALID_MSG_TYPE "; + case CRYPT_E_UNEXPECTED_ENCODING : + return "CRYPT_E_UNEXPECTED_ENCODING "; + case CRYPT_E_AUTH_ATTR_MISSING : + return "CRYPT_E_AUTH_ATTR_MISSING "; + case CRYPT_E_HASH_VALUE : + return "CRYPT_E_HASH_VALUE "; + case CRYPT_E_INVALID_INDEX : + return "CRYPT_E_INVALID_INDEX "; + case CRYPT_E_ALREADY_DECRYPTED : + return "CRYPT_E_ALREADY_DECRYPTED "; + case CRYPT_E_NOT_DECRYPTED : + return "CRYPT_E_NOT_DECRYPTED "; + case CRYPT_E_RECIPIENT_NOT_FOUND : + return "CRYPT_E_RECIPIENT_NOT_FOUND "; + case CRYPT_E_CONTROL_TYPE : + return "CRYPT_E_CONTROL_TYPE "; + case CRYPT_E_ISSUER_SERIALNUMBER : + return "CRYPT_E_ISSUER_SERIALNUMBER "; + case CRYPT_E_SIGNER_NOT_FOUND : + return "CRYPT_E_SIGNER_NOT_FOUND "; + case CRYPT_E_ATTRIBUTES_MISSING : + return "CRYPT_E_ATTRIBUTES_MISSING "; + case CRYPT_E_STREAM_MSG_NOT_READY : + return "CRYPT_E_STREAM_MSG_NOT_READY "; + case CRYPT_E_STREAM_INSUFFICIENT_DATA : + return "CRYPT_E_STREAM_INSUFFICIENT_DATA "; + case CRYPT_E_BAD_LEN : + return "CRYPT_E_BAD_LEN "; + case CRYPT_E_BAD_ENCODE : + return "CRYPT_E_BAD_ENCODE "; + case CRYPT_E_FILE_ERROR : + return "CRYPT_E_FILE_ERROR "; + case CRYPT_E_NOT_FOUND : + return "CRYPT_E_NOT_FOUND "; + case CRYPT_E_EXISTS : + return "CRYPT_E_EXISTS "; + case CRYPT_E_NO_PROVIDER : + return "CRYPT_E_NO_PROVIDER "; + case CRYPT_E_SELF_SIGNED : + return "CRYPT_E_SELF_SIGNED "; + case CRYPT_E_DELETED_PREV : + return "CRYPT_E_DELETED_PREV "; + case CRYPT_E_NO_MATCH : + return "CRYPT_E_NO_MATCH "; + case CRYPT_E_UNEXPECTED_MSG_TYPE : + return "CRYPT_E_UNEXPECTED_MSG_TYPE "; + case CRYPT_E_NO_KEY_PROPERTY : + return "CRYPT_E_NO_KEY_PROPERTY "; + case CRYPT_E_NO_DECRYPT_CERT : + return "CRYPT_E_NO_DECRYPT_CERT "; + case CRYPT_E_BAD_MSG : + return "CRYPT_E_BAD_MSG "; + case CRYPT_E_NO_SIGNER : + return "CRYPT_E_NO_SIGNER "; + case CRYPT_E_PENDING_CLOSE : + return "CRYPT_E_PENDING_CLOSE "; + case CRYPT_E_REVOKED : + return "CRYPT_E_REVOKED "; + case CRYPT_E_NO_REVOCATION_DLL : + return "CRYPT_E_NO_REVOCATION_DLL "; + case CRYPT_E_NO_REVOCATION_CHECK : + return "CRYPT_E_NO_REVOCATION_CHECK "; + case CRYPT_E_REVOCATION_OFFLINE : + return "CRYPT_E_REVOCATION_OFFLINE "; + case CRYPT_E_NOT_IN_REVOCATION_DATABASE : + return "CRYPT_E_NOT_IN_REVOCATION_DATABASE "; + case CRYPT_E_INVALID_NUMERIC_STRING : + return "CRYPT_E_INVALID_NUMERIC_STRING "; + case CRYPT_E_INVALID_PRINTABLE_STRING : + return "CRYPT_E_INVALID_PRINTABLE_STRING "; + case CRYPT_E_INVALID_IA5_STRING : + return "CRYPT_E_INVALID_IA5_STRING "; + case CRYPT_E_INVALID_X500_STRING : + return "CRYPT_E_INVALID_X500_STRING "; + case CRYPT_E_NOT_CHAR_STRING : + return "CRYPT_E_NOT_CHAR_STRING "; + case CRYPT_E_FILERESIZED : + return "CRYPT_E_FILERESIZED "; + case CRYPT_E_SECURITY_SETTINGS : + return "CRYPT_E_SECURITY_SETTINGS "; + case CRYPT_E_NO_VERIFY_USAGE_DLL : + return "CRYPT_E_NO_VERIFY_USAGE_DLL "; + case CRYPT_E_NO_VERIFY_USAGE_CHECK : + return "CRYPT_E_NO_VERIFY_USAGE_CHECK "; + case CRYPT_E_VERIFY_USAGE_OFFLINE : + return "CRYPT_E_VERIFY_USAGE_OFFLINE "; + case CRYPT_E_NOT_IN_CTL : + return "CRYPT_E_NOT_IN_CTL "; + case CRYPT_E_NO_TRUSTED_SIGNER : + return "CRYPT_E_NO_TRUSTED_SIGNER "; + case CRYPT_E_OSS_ERROR : + return "CRYPT_E_OSS_ERROR "; + case CERTSRV_E_BAD_REQUESTSUBJECT : + return "CERTSRV_E_BAD_REQUESTSUBJECT "; + case CERTSRV_E_NO_REQUEST : + return "CERTSRV_E_NO_REQUEST "; + case CERTSRV_E_BAD_REQUESTSTATUS : + return "CERTSRV_E_BAD_REQUESTSTATUS "; + case CERTSRV_E_PROPERTY_EMPTY : + return "CERTSRV_E_PROPERTY_EMPTY "; + //case CERTDB_E_JET_ERROR : + //return "CERTDB_E_JET_ERROR "; + case TRUST_E_SYSTEM_ERROR : + return "TRUST_E_SYSTEM_ERROR "; + case TRUST_E_NO_SIGNER_CERT : + return "TRUST_E_NO_SIGNER_CERT "; + case TRUST_E_COUNTER_SIGNER : + return "TRUST_E_COUNTER_SIGNER "; + case TRUST_E_CERT_SIGNATURE : + return "TRUST_E_CERT_SIGNATURE "; + case TRUST_E_TIME_STAMP : + return "TRUST_E_TIME_STAMP "; + case TRUST_E_BAD_DIGEST : + return "TRUST_E_BAD_DIGEST "; + case TRUST_E_BASIC_CONSTRAINTS : + return "TRUST_E_BASIC_CONSTRAINTS "; + case TRUST_E_FINANCIAL_CRITERIA : + return "TRUST_E_FINANCIAL_CRITERIA "; + case TRUST_E_PROVIDER_UNKNOWN : + return "TRUST_E_PROVIDER_UNKNOWN "; + case TRUST_E_ACTION_UNKNOWN : + return "TRUST_E_ACTION_UNKNOWN "; + case TRUST_E_SUBJECT_FORM_UNKNOWN : + return "TRUST_E_SUBJECT_FORM_UNKNOWN "; + case TRUST_E_SUBJECT_NOT_TRUSTED : + return "TRUST_E_SUBJECT_NOT_TRUSTED "; + case DIGSIG_E_ENCODE : + return "DIGSIG_E_ENCODE "; + case DIGSIG_E_DECODE : + return "DIGSIG_E_DECODE "; + case DIGSIG_E_EXTENSIBILITY : + return "DIGSIG_E_EXTENSIBILITY "; + case DIGSIG_E_CRYPTO : + return "DIGSIG_E_CRYPTO "; + case PERSIST_E_SIZEDEFINITE : + return "PERSIST_E_SIZEDEFINITE "; + case PERSIST_E_SIZEINDEFINITE : + return "PERSIST_E_SIZEINDEFINITE "; + case PERSIST_E_NOTSELFSIZING : + return "PERSIST_E_NOTSELFSIZING "; + case TRUST_E_NOSIGNATURE : + return "TRUST_E_NOSIGNATURE "; + case CERT_E_EXPIRED : + return "CERT_E_EXPIRED "; + case CERT_E_VALIDITYPERIODNESTING : + return "CERT_E_VALIDITYPERIODNESTING "; + case CERT_E_ROLE : + return "CERT_E_ROLE "; + case CERT_E_PATHLENCONST : + return "CERT_E_PATHLENCONST "; + case CERT_E_CRITICAL : + return "CERT_E_CRITICAL "; + case CERT_E_PURPOSE : + return "CERT_E_PURPOSE "; + case CERT_E_ISSUERCHAINING : + return "CERT_E_ISSUERCHAINING "; + case CERT_E_MALFORMED : + return "CERT_E_MALFORMED "; + case CERT_E_UNTRUSTEDROOT : + return "CERT_E_UNTRUSTEDROOT "; + case CERT_E_CHAINING : + return "CERT_E_CHAINING "; + case TRUST_E_FAIL : + return "TRUST_E_FAIL "; + case CERT_E_REVOKED : + return "CERT_E_REVOKED "; + case CERT_E_UNTRUSTEDTESTROOT : + return "CERT_E_UNTRUSTEDTESTROOT "; + case CERT_E_REVOCATION_FAILURE : + return "CERT_E_REVOCATION_FAILURE "; + case CERT_E_CN_NO_MATCH : + return "CERT_E_CN_NO_MATCH "; + case CERT_E_WRONG_USAGE : + return "CERT_E_WRONG_USAGE "; + case SPAPI_E_EXPECTED_SECTION_NAME : + return "SPAPI_E_EXPECTED_SECTION_NAME "; + case SPAPI_E_BAD_SECTION_NAME_LINE : + return "SPAPI_E_BAD_SECTION_NAME_LINE "; + case SPAPI_E_SECTION_NAME_TOO_LONG : + return "SPAPI_E_SECTION_NAME_TOO_LONG "; + case SPAPI_E_GENERAL_SYNTAX : + return "SPAPI_E_GENERAL_SYNTAX "; + case SPAPI_E_WRONG_INF_STYLE : + return "SPAPI_E_WRONG_INF_STYLE "; + case SPAPI_E_SECTION_NOT_FOUND : + return "SPAPI_E_SECTION_NOT_FOUND "; + case SPAPI_E_LINE_NOT_FOUND : + return "SPAPI_E_LINE_NOT_FOUND "; + case SPAPI_E_NO_ASSOCIATED_CLASS : + return "SPAPI_E_NO_ASSOCIATED_CLASS "; + case SPAPI_E_CLASS_MISMATCH : + return "SPAPI_E_CLASS_MISMATCH "; + case SPAPI_E_DUPLICATE_FOUND : + return "SPAPI_E_DUPLICATE_FOUND "; + case SPAPI_E_NO_DRIVER_SELECTED : + return "SPAPI_E_NO_DRIVER_SELECTED "; + case SPAPI_E_KEY_DOES_NOT_EXIST : + return "SPAPI_E_KEY_DOES_NOT_EXIST "; + case SPAPI_E_INVALID_DEVINST_NAME : + return "SPAPI_E_INVALID_DEVINST_NAME "; + case SPAPI_E_INVALID_CLASS : + return "SPAPI_E_INVALID_CLASS "; + case SPAPI_E_DEVINST_ALREADY_EXISTS : + return "SPAPI_E_DEVINST_ALREADY_EXISTS "; + case SPAPI_E_DEVINFO_NOT_REGISTERED : + return "SPAPI_E_DEVINFO_NOT_REGISTERED "; + case SPAPI_E_INVALID_REG_PROPERTY : + return "SPAPI_E_INVALID_REG_PROPERTY "; + case SPAPI_E_NO_INF : + return "SPAPI_E_NO_INF "; + case SPAPI_E_NO_SUCH_DEVINST : + return "SPAPI_E_NO_SUCH_DEVINST "; + case SPAPI_E_CANT_LOAD_CLASS_ICON : + return "SPAPI_E_CANT_LOAD_CLASS_ICON "; + case SPAPI_E_INVALID_CLASS_INSTALLER : + return "SPAPI_E_INVALID_CLASS_INSTALLER "; + case SPAPI_E_DI_DO_DEFAULT : + return "SPAPI_E_DI_DO_DEFAULT "; + case SPAPI_E_DI_NOFILECOPY : + return "SPAPI_E_DI_NOFILECOPY "; + case SPAPI_E_INVALID_HWPROFILE : + return "SPAPI_E_INVALID_HWPROFILE "; + case SPAPI_E_NO_DEVICE_SELECTED : + return "SPAPI_E_NO_DEVICE_SELECTED "; + case SPAPI_E_DEVINFO_LIST_LOCKED : + return "SPAPI_E_DEVINFO_LIST_LOCKED "; + case SPAPI_E_DEVINFO_DATA_LOCKED : + return "SPAPI_E_DEVINFO_DATA_LOCKED "; + case SPAPI_E_DI_BAD_PATH : + return "SPAPI_E_DI_BAD_PATH "; + case SPAPI_E_NO_CLASSINSTALL_PARAMS : + return "SPAPI_E_NO_CLASSINSTALL_PARAMS "; + case SPAPI_E_FILEQUEUE_LOCKED : + return "SPAPI_E_FILEQUEUE_LOCKED "; + case SPAPI_E_BAD_SERVICE_INSTALLSECT : + return "SPAPI_E_BAD_SERVICE_INSTALLSECT "; + case SPAPI_E_NO_CLASS_DRIVER_LIST : + return "SPAPI_E_NO_CLASS_DRIVER_LIST "; + case SPAPI_E_NO_ASSOCIATED_SERVICE : + return "SPAPI_E_NO_ASSOCIATED_SERVICE "; + case SPAPI_E_NO_DEFAULT_DEVICE_INTERFACE : + return "SPAPI_E_NO_DEFAULT_DEVICE_INTERFACE "; + case SPAPI_E_DEVICE_INTERFACE_ACTIVE : + return "SPAPI_E_DEVICE_INTERFACE_ACTIVE "; + case SPAPI_E_DEVICE_INTERFACE_REMOVED : + return "SPAPI_E_DEVICE_INTERFACE_REMOVED "; + case SPAPI_E_BAD_INTERFACE_INSTALLSECT : + return "SPAPI_E_BAD_INTERFACE_INSTALLSECT "; + case SPAPI_E_NO_SUCH_INTERFACE_CLASS : + return "SPAPI_E_NO_SUCH_INTERFACE_CLASS "; + case SPAPI_E_INVALID_REFERENCE_STRING : + return "SPAPI_E_INVALID_REFERENCE_STRING "; + case SPAPI_E_INVALID_MACHINENAME : + return "SPAPI_E_INVALID_MACHINENAME "; + case SPAPI_E_REMOTE_COMM_FAILURE : + return "SPAPI_E_REMOTE_COMM_FAILURE "; + case SPAPI_E_MACHINE_UNAVAILABLE : + return "SPAPI_E_MACHINE_UNAVAILABLE "; + case SPAPI_E_NO_CONFIGMGR_SERVICES : + return "SPAPI_E_NO_CONFIGMGR_SERVICES "; + case SPAPI_E_INVALID_PROPPAGE_PROVIDER : + return "SPAPI_E_INVALID_PROPPAGE_PROVIDER "; + case SPAPI_E_NO_SUCH_DEVICE_INTERFACE : + return "SPAPI_E_NO_SUCH_DEVICE_INTERFACE "; + case SPAPI_E_DI_POSTPROCESSING_REQUIRED : + return "SPAPI_E_DI_POSTPROCESSING_REQUIRED "; + case SPAPI_E_INVALID_COINSTALLER : + return "SPAPI_E_INVALID_COINSTALLER "; + case SPAPI_E_NO_COMPAT_DRIVERS : + return "SPAPI_E_NO_COMPAT_DRIVERS "; + case SPAPI_E_NO_DEVICE_ICON : + return "SPAPI_E_NO_DEVICE_ICON "; + case SPAPI_E_INVALID_INF_LOGCONFIG : + return "SPAPI_E_INVALID_INF_LOGCONFIG "; + case SPAPI_E_DI_DONT_INSTALL : + return "SPAPI_E_DI_DONT_INSTALL "; + case SPAPI_E_INVALID_FILTER_DRIVER : + return "SPAPI_E_INVALID_FILTER_DRIVER "; + case SPAPI_E_ERROR_NOT_INSTALLED : + return "SPAPI_E_ERROR_NOT_INSTALLED "; + + default: + static char buff[1000]; + sprintf(buff, "Unrecognized error value: %08X\0", error); + + return buff; + } +} diff --git a/panda/src/dxgsg/dxgsgbase.h b/panda/src/dxgsg7/dxgsg7base.h similarity index 94% rename from panda/src/dxgsg/dxgsgbase.h rename to panda/src/dxgsg7/dxgsg7base.h index c0d45fea34..fc29b16cbf 100644 --- a/panda/src/dxgsg/dxgsgbase.h +++ b/panda/src/dxgsg7/dxgsg7base.h @@ -1,4 +1,4 @@ -// Filename: dxTextureContext.h +// Filename: dxTextureContext7.h // Created by: drose (07Oct99) // //////////////////////////////////////////////////////////////////// @@ -86,7 +86,7 @@ typedef pvector DDPixelFormatVec; MODULE##_cat.debug() << DBGSTR << " not released, ptr == NULL" << endl; \ } -#define PRINTREFCNT(OBJECT,STR) { (OBJECT)->AddRef(); dxgsg_cat.debug() << STR << " refcnt = " << (OBJECT)->Release() << endl; } +#define PRINTREFCNT(OBJECT,STR) { (OBJECT)->AddRef(); dxgsg7_cat.debug() << STR << " refcnt = " << (OBJECT)->Release() << endl; } #else #define RELEASE(OBJECT,MODULE,DBGSTR,bDoDownToZero) \ if(((OBJECT)!=NULL)&&(!IsBadWritePtr((OBJECT),4))) { \ @@ -109,7 +109,7 @@ typedef pvector DDPixelFormatVec; #define DO_PSTATS_STUFF(XX) #endif -extern char * ConvD3DErrorToString(const HRESULT &error); // defined in wdxGraphicsPipe.cxx +const char *ConvD3DErrorToString(HRESULT error); typedef struct { LPDIRECT3DDEVICE7 pD3DDevice; diff --git a/panda/src/display/interactiveGraphicsPipe.I b/panda/src/dxgsg7/wdxGraphicsPipe7.I similarity index 89% rename from panda/src/display/interactiveGraphicsPipe.I rename to panda/src/dxgsg7/wdxGraphicsPipe7.I index bc7d017c53..8da50a9923 100644 --- a/panda/src/display/interactiveGraphicsPipe.I +++ b/panda/src/dxgsg7/wdxGraphicsPipe7.I @@ -1,5 +1,5 @@ -// Filename: interactiveGraphicsPipe.I -// Created by: cary (10Mar99) +// Filename: wdxGraphicsPipe7.I +// Created by: drose (20Dec02) // //////////////////////////////////////////////////////////////////// // @@ -15,4 +15,3 @@ // panda3d@yahoogroups.com . // //////////////////////////////////////////////////////////////////// - diff --git a/panda/src/dxgsg7/wdxGraphicsPipe7.cxx b/panda/src/dxgsg7/wdxGraphicsPipe7.cxx new file mode 100644 index 0000000000..13b560a8b6 --- /dev/null +++ b/panda/src/dxgsg7/wdxGraphicsPipe7.cxx @@ -0,0 +1,63 @@ +// Filename: wdxGraphicsPipe7.cxx +// Created by: drose (20Dec02) +// +//////////////////////////////////////////////////////////////////// +// +// 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 "wdxGraphicsPipe7.h" +#include "wdxGraphicsWindow7.h" +#include "config_dxgsg7.h" + +TypeHandle wdxGraphicsPipe7::_type_handle; + +//////////////////////////////////////////////////////////////////// +// Function: wdxGraphicsPipe7::Constructor +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +wdxGraphicsPipe7:: +wdxGraphicsPipe7() { +} + +//////////////////////////////////////////////////////////////////// +// Function: wdxGraphicsPipe7::Destructor +// Access: Public, Virtual +// Description: +//////////////////////////////////////////////////////////////////// +wdxGraphicsPipe7:: +~wdxGraphicsPipe7() { +} + +//////////////////////////////////////////////////////////////////// +// Function: wdxGraphicsPipe7::pipe_constructor +// Access: Public, Static +// Description: This function is passed to the GraphicsPipeSelection +// object to allow the user to make a default +// wdxGraphicsPipe7. +//////////////////////////////////////////////////////////////////// +PT(GraphicsPipe) wdxGraphicsPipe7:: +pipe_constructor() { + return new wdxGraphicsPipe7; +} + +//////////////////////////////////////////////////////////////////// +// Function: wdxGraphicsPipe7::make_window +// Access: Protected, Virtual +// Description: Creates a new window on the pipe, if possible. +//////////////////////////////////////////////////////////////////// +PT(GraphicsWindow) wdxGraphicsPipe7:: +make_window() { + return new wdxGraphicsWindow7(this); +} diff --git a/panda/src/dxgsg7/wdxGraphicsPipe7.h b/panda/src/dxgsg7/wdxGraphicsPipe7.h new file mode 100644 index 0000000000..26e8e93e6c --- /dev/null +++ b/panda/src/dxgsg7/wdxGraphicsPipe7.h @@ -0,0 +1,60 @@ +// Filename: wdxGraphicsPipe7.h +// Created by: drose (20Dec02) +// +//////////////////////////////////////////////////////////////////// +// +// 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 WDXGRAPHICSPIPE7_H +#define WDXGRAPHICSPIPE7_H + +#include "pandabase.h" +#include "winGraphicsPipe.h" + +//////////////////////////////////////////////////////////////////// +// Class : wdxGraphicsPipe7 +// Description : This graphics pipe represents the interface for +// creating DirectX graphics windows. +//////////////////////////////////////////////////////////////////// +class EXPCL_PANDADX wdxGraphicsPipe7 : public WinGraphicsPipe { +public: + wdxGraphicsPipe7(); + virtual ~wdxGraphicsPipe7(); + + static PT(GraphicsPipe) pipe_constructor(); + +protected: + virtual PT(GraphicsWindow) make_window(); + +public: + static TypeHandle get_class_type() { + return _type_handle; + } + static void init_type() { + WinGraphicsPipe::init_type(); + register_type(_type_handle, "wdxGraphicsPipe7", + WinGraphicsPipe::get_class_type()); + } + virtual TypeHandle get_type() const { + return get_class_type(); + } + virtual TypeHandle force_init_type() {init_type(); return get_class_type();} + +private: + static TypeHandle _type_handle; +}; + +#include "wdxGraphicsPipe7.I" + +#endif diff --git a/panda/src/display/noninteractiveGraphicsPipe.I b/panda/src/dxgsg7/wdxGraphicsWindow7.I similarity index 88% rename from panda/src/display/noninteractiveGraphicsPipe.I rename to panda/src/dxgsg7/wdxGraphicsWindow7.I index 2e73f9b4ad..dc9c54c1e9 100644 --- a/panda/src/display/noninteractiveGraphicsPipe.I +++ b/panda/src/dxgsg7/wdxGraphicsWindow7.I @@ -1,5 +1,5 @@ -// Filename: noninteractiveGraphicsPipe.I -// Created by: cary (10Mar99) +// Filename: wdxGraphicsWindow7.I +// Created by: drose (20Dec02) // //////////////////////////////////////////////////////////////////// // diff --git a/panda/src/dxgsg7/wdxGraphicsWindow7.cxx b/panda/src/dxgsg7/wdxGraphicsWindow7.cxx new file mode 100644 index 0000000000..c7e72e4f1b --- /dev/null +++ b/panda/src/dxgsg7/wdxGraphicsWindow7.cxx @@ -0,0 +1,1331 @@ +// Filename: wdxGraphicsWindow7.cxx +// Created by: drose (20Dec02) +// +//////////////////////////////////////////////////////////////////// +// +// 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 "wdxGraphicsWindow7.h" +#include "config_dxgsg7.h" +#include "config_windisplay.h" +#include "wdxGraphicsPipe7.h" +#include "dxGraphicsStateGuardian7.h" + +#include + +static DWORD +BitDepth_2_DDBDMask(DWORD iBitDepth) { + switch (iBitDepth) { + case 16: return DDBD_16; + case 32: return DDBD_32; + case 24: return DDBD_24; + case 8: return DDBD_8; + case 1: return DDBD_1; + case 2: return DDBD_2; + case 4: return DDBD_4; + } + return 0x0; +} + +#define MAX_DX_ZBUF_FMTS 20 +static int cNumZBufFmts; + +HRESULT CALLBACK +EnumZBufFmtsCallback(LPDDPIXELFORMAT pddpf, VOID *param) { + DDPIXELFORMAT *ZBufFmtsArr = (DDPIXELFORMAT *) param; + assert(cNumZBufFmts < MAX_DX_ZBUF_FMTS); + memcpy(&(ZBufFmtsArr[cNumZBufFmts]), pddpf, sizeof(DDPIXELFORMAT)); + cNumZBufFmts++; + return DDENUMRET_OK; +} + +HRESULT CALLBACK +EnumDevicesCallback(LPSTR pDeviceDescription, LPSTR pDeviceName, + LPD3DDEVICEDESC7 pD3DDeviceDesc,LPVOID pContext) { + D3DDEVICEDESC7 *pd3ddevs = (D3DDEVICEDESC7 *)pContext; +#ifdef _DEBUG + wdxdisplay7_cat.spam() + << "Enumerating Device " << pDeviceName << " : " + << pDeviceDescription << endl; +#endif + +#define REGHALIDX 0 +#define TNLHALIDX 1 +#define SWRASTIDX 2 + + if (IsEqualGUID(pD3DDeviceDesc->deviceGUID, IID_IDirect3DHALDevice)) { + CopyMemory(&pd3ddevs[REGHALIDX], pD3DDeviceDesc, sizeof(D3DDEVICEDESC7)); + } else if (IsEqualGUID(pD3DDeviceDesc->deviceGUID, IID_IDirect3DTnLHalDevice)) { + CopyMemory(&pd3ddevs[TNLHALIDX], pD3DDeviceDesc, sizeof(D3DDEVICEDESC7)); + } else if(IsEqualGUID(pD3DDeviceDesc->deviceGUID, IID_IDirect3DRGBDevice)) { + CopyMemory(&pd3ddevs[SWRASTIDX], pD3DDeviceDesc, sizeof(D3DDEVICEDESC7)); + } + return DDENUMRET_OK; +} + +#define MAX_DISPLAY_MODES 100 // probably dont need this much, since i already screen for width&hgt +typedef struct { + DWORD maxWidth,maxHeight; + DWORD supportedBitDepths; // uses DDBD_* flags + LPDDSURFACEDESC2 pDDSD_Arr; + DWORD cNumSurfDescs; +} DisplayModeInfo; + +HRESULT WINAPI +EnumDisplayModesCallBack(LPDDSURFACEDESC2 lpDDSurfaceDesc,LPVOID lpContext) { + DisplayModeInfo *pDMI = (DisplayModeInfo *) lpContext; + + // ddsd_search should assure this is true + assert((lpDDSurfaceDesc->dwWidth == pDMI->maxWidth) && (lpDDSurfaceDesc->dwHeight == pDMI->maxHeight)); + + // ignore refresh rates under 60Hz (and special values of 0 & 1) + if ((lpDDSurfaceDesc->dwRefreshRate > 1) && + (lpDDSurfaceDesc->dwRefreshRate < 60)) { + return DDENUMRET_OK; + } + + assert(pDMI->cNumSurfDescs < MAX_DISPLAY_MODES); + memcpy(&(pDMI->pDDSD_Arr[pDMI->cNumSurfDescs]), lpDDSurfaceDesc, sizeof(DDSURFACEDESC2)); + pDMI->cNumSurfDescs++; + pDMI->supportedBitDepths |= BitDepth_2_DDBDMask(lpDDSurfaceDesc->ddpfPixelFormat.dwRGBBitCount); + + return DDENUMRET_OK; +} + +// imperfect method to ID NVid? could also scan desc str, but that isnt fullproof either +#define IS_NVIDIA(DDDEVICEID) ((DDDEVICEID.dwVendorId==0x10DE) || (DDDEVICEID.dwVendorId==0x12D2)) +#define IS_ATI(DDDEVICEID) (DDDEVICEID.dwVendorId==0x1002) +#define IS_MATROX(DDDEVICEID) (DDDEVICEID.dwVendorId==0x102B) + +HINSTANCE wdxGraphicsWindow7::_hDDrawDLL = NULL; +LPDIRECTDRAWCREATEEX wdxGraphicsWindow7::_pDDCreateEx = NULL; + +TypeHandle wdxGraphicsWindow7::_type_handle; + +//////////////////////////////////////////////////////////////////// +// Function: wdxGraphicsWindow7::Constructor +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +wdxGraphicsWindow7:: +wdxGraphicsWindow7(GraphicsPipe *pipe) : + WinGraphicsWindow(pipe) +{ + _dxgsg = (DXGraphicsStateGuardian7 *)NULL; +} + +//////////////////////////////////////////////////////////////////// +// Function: wdxGraphicsWindow7::Destructor +// Access: Public, Virtual +// Description: +//////////////////////////////////////////////////////////////////// +wdxGraphicsWindow7:: +~wdxGraphicsWindow7() { +} + +//////////////////////////////////////////////////////////////////// +// Function: wdxGraphicsWindow7::make_gsg +// Access: Public, Virtual +// Description: Creates a new GSG for the window and stores it in the +// _gsg pointer. This should only be called from within +// the draw thread. +//////////////////////////////////////////////////////////////////// +void wdxGraphicsWindow7:: +make_gsg() { + nassertv(_gsg == (GraphicsStateGuardian *)NULL); + _dxgsg = new DXGraphicsStateGuardian7(this); + _gsg = _dxgsg; + // Tell the associated dxGSG about the window handle. + _dxgsg->scrn.hWnd = _mwindow; + + init_ddraw(); + if (!search_for_device(0, NULL)) { + wdxdisplay7_cat.error() + << "Unable to find suitable rendering device.\n"; + release_gsg(); + return; + } + + set_coop_levels_and_display_modes(); + create_screen_buffers_and_device(_dxgsg->scrn, dx_force_16bpp_zbuffer); +} + +//////////////////////////////////////////////////////////////////// +// Function: wdxGraphicsWindow7::release_gsg +// Access: Public, Virtual +// Description: Releases the current GSG pointer, if it is currently +// held, and resets the GSG to NULL. This should only +// be called from within the draw thread. +//////////////////////////////////////////////////////////////////// +void wdxGraphicsWindow7:: +release_gsg() { + if (_gsg != (GraphicsStateGuardian *)NULL) { + GraphicsWindow::release_gsg(); + } +} + +//////////////////////////////////////////////////////////////////// +// Function: wdxGraphicsWindow7::end_flip +// Access: Public, Virtual +// Description: This function will be called within the draw thread +// after begin_flip() has been called on all windows, to +// finish the exchange of the front and back buffers. +// +// This should cause the window to wait for the flip, if +// necessary. +//////////////////////////////////////////////////////////////////// +void wdxGraphicsWindow7:: +end_flip() { + if (_dxgsg != (DXGraphicsStateGuardian7 *)NULL && is_active()) { + _dxgsg->show_frame(); + } +} + +//////////////////////////////////////////////////////////////////// +// Function: wdxGraphicsWindow7::fullscreen_restored +// Access: Protected, Virtual +// Description: This is a hook for derived classes to do something +// special, if necessary, when a fullscreen window has +// been restored after being minimized. The given +// WindowProperties struct will be applied to this +// window's properties after this function returns. +//////////////////////////////////////////////////////////////////// +void wdxGraphicsWindow7:: +fullscreen_restored(WindowProperties &properties) { + // For some reason, this message comes in twice, once while the + // fullscreen window is still minimized, and once again when it has + // been restored. + + // In DX7, it seems to be necessary to render one frame between the + // two cases, so we must set the minimized property to false even in + // the first case. + properties.set_minimized(false); +} + +//////////////////////////////////////////////////////////////////// +// Function: wdxGraphicsWindow7::handle_reshape +// Access: Protected, Virtual +// Description: Called in the window thread when the window size or +// location is changed, this updates the properties +// structure accordingly. +//////////////////////////////////////////////////////////////////// +void wdxGraphicsWindow7:: +handle_reshape() { + GdiFlush(); + WinGraphicsWindow::handle_reshape(); + + if (_dxgsg!=NULL) { + HRESULT hr; + + if (_dxgsg->scrn.pddsBack == NULL) { + // assume this is initial creation reshape and ignore this call + return; + } + + // Clear the back/primary surface to black + DX_DECLARE_CLEAN(DDBLTFX, bltfx); + bltfx.dwDDFX |= DDBLTFX_NOTEARING; + hr = _dxgsg->scrn.pddsPrimary->Blt + (NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &bltfx); + if (FAILED(hr)) { + wdxdisplay7_cat.fatal() + << "Blt to Black of Primary Surf failed! : result = " + << ConvD3DErrorToString(hr) << endl; + exit(1); + } + + hr = _dxgsg->scrn.pDD->TestCooperativeLevel(); + if (FAILED(hr)) { + wdxdisplay7_cat.error() + << "TestCooperativeLevel failed : result = " + << ConvD3DErrorToString(hr) << endl; + return; + } + + _dxgsg->RestoreAllVideoSurfaces(); + + set_to_temp_rendertarget(); + + // create the new resized rendertargets + RECT view_rect; + HWND hWnd = _dxgsg->scrn.hWnd; + get_client_rect_screen(hWnd, &view_rect); + _dxgsg->dx_setup_after_resize(view_rect, hWnd); + } +} + +//////////////////////////////////////////////////////////////////// +// Function: wdxGraphicsWindow7::do_fullscreen_resize +// Access: Protected, Virtual +// Description: Called in the window thread to resize a fullscreen +// window. +//////////////////////////////////////////////////////////////////// +bool wdxGraphicsWindow7:: +do_fullscreen_resize(int x_size, int y_size) { + _dxgsg->SetDXReady(false); + + HRESULT hr; + + DX_DECLARE_CLEAN(DDSURFACEDESC2,ddsd_curmode); + + hr = _dxgsg->scrn.pDD->GetDisplayMode(&ddsd_curmode); + if (FAILED(hr)) { + wdxdisplay7_cat.fatal() + << "resize() - GetDisplayMode failed, result = " + << ConvD3DErrorToString(hr) << endl; + exit(1); + } + + DX_DECLARE_CLEAN(DDSURFACEDESC2, ddsd_search); + + ddsd_search.dwFlags = DDSD_HEIGHT | DDSD_WIDTH; + ddsd_search.dwWidth=x_size; + ddsd_search.dwHeight=y_size; + + // not requesting same refresh rate since changing res might not + // support same refresh rate + + DDSURFACEDESC2 DDSD_Arr[MAX_DISPLAY_MODES]; + DisplayModeInfo DMI; + ZeroMemory(&DDSD_Arr,sizeof(DDSD_Arr)); + ZeroMemory(&DMI,sizeof(DMI)); + DMI.maxWidth = x_size; + DMI.maxHeight = y_size; + DMI.pDDSD_Arr = DDSD_Arr; + + hr = _dxgsg->scrn.pDD->EnumDisplayModes(DDEDM_REFRESHRATES, &ddsd_search, + &DMI, EnumDisplayModesCallBack); + if (FAILED(hr)) { + wdxdisplay7_cat.fatal() + << "resize() - EnumDisplayModes failed, result = " + << ConvD3DErrorToString(hr) << endl; + return false; + } + + DMI.supportedBitDepths &= _dxgsg->scrn.D3DDevDesc.dwDeviceRenderBitDepth; + + DWORD dwFullScreenBitDepth; + DWORD requested_bpp = ddsd_curmode.ddpfPixelFormat.dwRGBBitCount; + + // would like to match current bpp first. if that is not possible, + // try 16bpp, then 32 + DWORD requested_bpp_DDBD = BitDepth_2_DDBDMask(requested_bpp); + + if (DMI.supportedBitDepths & requested_bpp_DDBD) { + dwFullScreenBitDepth = requested_bpp; + } else if (DMI.supportedBitDepths & DDBD_16) { + dwFullScreenBitDepth = 16; + } else if (DMI.supportedBitDepths & DDBD_32) { + dwFullScreenBitDepth = 32; + } else { + wdxdisplay7_cat.error() + << "resize failed, no fullScreen resolutions at " << x_size + << "x" << y_size << endl; + return false; + } + + hr = _dxgsg->scrn.pDD->TestCooperativeLevel(); + if (FAILED(hr)) { + wdxdisplay7_cat.error() + << "TestCooperativeLevel failed : result = " + << ConvD3DErrorToString(hr) << endl; + wdxdisplay7_cat.error() + << "Full screen app failed to get exclusive mode on resize, exiting..\n"; + return false; + } + + _dxgsg->free_dxgsg_objects(); + + // let driver choose default refresh rate (hopefully its >=60Hz) + hr = _dxgsg->scrn.pDD->SetDisplayMode(x_size, y_size, dwFullScreenBitDepth, + 0L, 0L); + if (FAILED(hr)) { + wdxdisplay7_cat.error() + << "resize failed to reset display mode to (" + << x_size << "x" << y_size << "x" + << dwFullScreenBitDepth << "): result = " + << ConvD3DErrorToString(hr) << endl; + } + + if (wdxdisplay7_cat.is_debug()) { + DX_DECLARE_CLEAN(DDSURFACEDESC2,ddsd34); + _dxgsg->scrn.pDD->GetDisplayMode(&ddsd34); + wdxdisplay7_cat.debug() + << "set displaymode to " << ddsd34.dwWidth << "x" << ddsd34.dwHeight + << " at "<< ddsd34.ddpfPixelFormat.dwRGBBitCount << "bpp, " + << ddsd34.dwRefreshRate << "Hz\n"; + } + + _dxgsg->scrn.dwRenderWidth = x_size; + _dxgsg->scrn.dwRenderHeight = y_size; + + create_screen_buffers_and_device(_dxgsg->scrn, dx_force_16bpp_zbuffer); + _dxgsg->RecreateAllVideoSurfaces(); + _dxgsg->SetDXReady(true); + return true; +} + +//////////////////////////////////////////////////////////////////// +// Function: wdxGraphicsWindow7::set_to_temp_rendertarget +// Access: Private +// Description: Constructs a temporary tiny render target for the d3d +// device (and sets the d3d device to use it). This is +// called by handle_reshape() just before the full-sized +// rendertargets are constructed, in order to save video +// memory and thereby allow resizing of the window to +// work on 4MB cards. +//////////////////////////////////////////////////////////////////// +bool wdxGraphicsWindow7:: +set_to_temp_rendertarget() { + LPDIRECTDRAWSURFACE7 pddsDummy = NULL, pddsDummyZ = NULL; + ULONG refcnt; + HRESULT hr; + + DX_DECLARE_CLEAN(DDSURFACEDESC2, ddsd); + + _dxgsg->scrn.pddsBack->GetSurfaceDesc(&ddsd); + LPDIRECTDRAW7 pDD = _dxgsg->scrn.pDD; + + ddsd.dwFlags &= ~DDSD_PITCH; + ddsd.dwWidth = 1; + ddsd.dwHeight = 1; + ddsd.ddsCaps.dwCaps &= ~(DDSCAPS_COMPLEX | DDSCAPS_FLIP | DDSCAPS_FRONTBUFFER | DDSCAPS_BACKBUFFER); + + PRINTVIDMEM(pDD, &ddsd.ddsCaps, "dummy backbuf"); + + hr = pDD->CreateSurface(&ddsd, &pddsDummy, NULL); + if (FAILED(hr)) { + wdxdisplay7_cat.error() + << "Resize CreateSurface for temp backbuf failed : result = " + << ConvD3DErrorToString(hr) << endl; + return false; + } + + if (_dxgsg->scrn.pddsZBuf != NULL) { + DX_DECLARE_CLEAN(DDSURFACEDESC2, ddsdZ); + _dxgsg->scrn.pddsZBuf->GetSurfaceDesc(&ddsdZ); + ddsdZ.dwFlags &= ~DDSD_PITCH; + ddsdZ.dwWidth = 1; + ddsdZ.dwHeight = 1; + + PRINTVIDMEM(pDD,&ddsdZ.ddsCaps,"dummy zbuf"); + + hr = pDD->CreateSurface(&ddsdZ, &pddsDummyZ, NULL); + if (FAILED(hr)) { + wdxdisplay7_cat.error() + << "Resize CreateSurface for temp zbuf failed : result = " + << ConvD3DErrorToString(hr) << endl; + return false; + } + + hr = pddsDummy->AddAttachedSurface(pddsDummyZ); + if (FAILED(hr)) { + wdxdisplay7_cat.error() + << "Resize AddAttachedSurf for temp zbuf failed : result = " + << ConvD3DErrorToString(hr) << endl; + return false; + } + } + + hr = _dxgsg->scrn.pD3DDevice->SetRenderTarget(pddsDummy, 0x0); + if (FAILED(hr)) { + wdxdisplay7_cat.error() + << "Resize failed to set render target to temporary surface, result = " + << ConvD3DErrorToString(hr) << endl; + return false; + } + + RELEASE(pddsDummyZ, wdxdisplay7, "dummy resize zbuffer", false); + RELEASE(pddsDummy, wdxdisplay7, "dummy resize rendertarget buffer", false); + + return true; +} + +//////////////////////////////////////////////////////////////////// +// Function: wdxGraphicsWindow7::create_screen_buffers_and_device +// Access: Private +// Description: Called whenever the window is resized, this recreates +// the necessary buffers for rendering. +//////////////////////////////////////////////////////////////////// +void wdxGraphicsWindow7:: +create_screen_buffers_and_device(DXScreenData &Display, bool force_16bpp_zbuffer) { + DWORD dwRenderWidth=Display.dwRenderWidth; + DWORD dwRenderHeight=Display.dwRenderHeight; + LPDIRECT3D7 pD3DI=Display.pD3D; + LPDIRECTDRAW7 pDD=Display.pDD; + D3DDEVICEDESC7 *pD3DDevDesc=&Display.D3DDevDesc; + + LPDIRECTDRAWSURFACE7 pPrimaryDDSurf,pBackDDSurf,pZDDSurf; + LPDIRECT3DDEVICE7 pD3DDevice; + RECT view_rect; + int i; + HRESULT hr; + DX_DECLARE_CLEAN(DDSURFACEDESC2, SurfaceDesc); + + assert(pDD!=NULL); + assert(pD3DI!=NULL); + + DX_DECLARE_CLEAN(DDCAPS, DDCaps); + pDD->GetCaps(&DDCaps, NULL); + + // if window is not foreground in exclusive mode, ddraw thinks you + // are 'not active', so it changes your WM_ACTIVATEAPP from true to + // false, causing us to go into a 'wait-for WM_ACTIVATEAPP true' + // loop, and the event never comes so we hang in fullscreen wait. + SetForegroundWindow(Display.hWnd); + + if (is_fullscreen()) { + // Setup to create the primary surface w/backbuffer + DX_DECLARE_CLEAN(DDSURFACEDESC2,ddsd); + ddsd.dwFlags = DDSD_CAPS|DDSD_BACKBUFFERCOUNT; + ddsd.ddsCaps.dwCaps = + DDSCAPS_PRIMARYSURFACE | DDSCAPS_3DDEVICE | + DDSCAPS_FLIP | DDSCAPS_COMPLEX; + ddsd.dwBackBufferCount = 1; + + if (dx_full_screen_antialiasing) { + // cant check that d3ddevice has this capability yet, so got to + // set it anyway. hope this is OK. + ddsd.ddsCaps.dwCaps2 |= DDSCAPS2_HINTANTIALIASING; + } + + PRINTVIDMEM(pDD, &ddsd.ddsCaps, "initial primary & backbuf"); + + // Create the primary surface + hr = pDD->CreateSurface(&ddsd, &pPrimaryDDSurf, NULL); + if (FAILED(hr)) { + wdxdisplay7_cat.fatal() + << "CreateSurface failed for primary surface: result = " + << ConvD3DErrorToString(hr) << endl; + + if (((hr == DDERR_OUTOFVIDEOMEMORY)||(hr == DDERR_OUTOFMEMORY)) && + (Display.dwFullScreenBitDepth > 16)) { + // emergency fallback to 16bpp (shouldnt have to do this + // unless GetAvailVidMem lied) will this work for multimon? + // what if surfs are already created on 1st mon? + Display.dwFullScreenBitDepth=16; + + wdxdisplay7_cat.info() + << "GetAvailVidMem lied, not enough VidMem for 32bpp, so trying 16bpp on device #" + << Display.CardIDNum << endl; + + hr = pDD->SetDisplayMode(Display.dwRenderWidth, + Display.dwRenderHeight, + Display.dwFullScreenBitDepth, 0, 0); + if (FAILED(hr)) { + wdxdisplay7_cat.fatal() + << "SetDisplayMode failed to set (" + << Display.dwRenderWidth << "x" << Display.dwRenderHeight + << "x" << Display.dwFullScreenBitDepth << ") on device #" + << Display.CardIDNum << ": result = " + << ConvD3DErrorToString(hr) << endl; + exit(1); + } + create_screen_buffers_and_device(Display, true); + return; + } else { + exit(1); + } + } + + // Clear the primary surface to black + DX_DECLARE_CLEAN(DDBLTFX, bltfx); + bltfx.dwDDFX |= DDBLTFX_NOTEARING; + hr = pPrimaryDDSurf->Blt(NULL, NULL, NULL, + DDBLT_COLORFILL | DDBLT_WAIT, &bltfx); + + if (FAILED(hr)) { + wdxdisplay7_cat.fatal() + << "Blt to Black of Primary Surf failed! : result = " + << ConvD3DErrorToString(hr) << endl; + exit(1); + } + + // Get the backbuffer, which was created along with the primary. + DDSCAPS2 ddscaps = { + DDSCAPS_BACKBUFFER, 0, 0, 0 + }; + hr = pPrimaryDDSurf->GetAttachedSurface(&ddscaps, &pBackDDSurf); + if (FAILED(hr)) { + wdxdisplay7_cat.fatal() + << "Can't get the backbuffer: result = " + << ConvD3DErrorToString(hr) << endl; + exit(1); + } + + hr = pBackDDSurf->Blt(NULL,NULL,NULL,DDBLT_COLORFILL | DDBLT_WAIT,&bltfx); + if (FAILED(hr)) { + wdxdisplay7_cat.fatal() + << "Blt to Black of Back Surf failed! : result = " + << ConvD3DErrorToString(hr) << endl; + exit(1); + } + + SetRect(&view_rect, 0, 0, dwRenderWidth, dwRenderHeight); + // end create full screen buffers + + } else { // CREATE WINDOWED BUFFERS + if (!(DDCaps.dwCaps2 & DDCAPS2_CANRENDERWINDOWED)) { + wdxdisplay7_cat.fatal() + << "the 3D HW cannot render windowed, exiting..." << endl; + exit(1); + } + + hr = pDD->GetDisplayMode(&SurfaceDesc); + if (FAILED(hr)) { + wdxdisplay7_cat.fatal() + << "GetDisplayMode failed result = " + << ConvD3DErrorToString(hr) << endl; + exit(1); + } + if (SurfaceDesc.ddpfPixelFormat.dwRGBBitCount <= 8) { + wdxdisplay7_cat.fatal() + << "Can't run windowed in an 8-bit or less display mode" << endl; + exit(1); + } + + if (!(BitDepth_2_DDBDMask(SurfaceDesc.ddpfPixelFormat.dwRGBBitCount) & pD3DDevDesc->dwDeviceRenderBitDepth)) { + wdxdisplay7_cat.fatal() + << "3D Device doesnt support rendering at " + << SurfaceDesc.ddpfPixelFormat.dwRGBBitCount + << "bpp (current desktop bitdepth)" << endl; + exit(1); + } + + // Get the dimensions of the viewport and screen bounds + get_client_rect_screen(Display.hWnd, &view_rect); + + dwRenderWidth = view_rect.right - view_rect.left; + dwRenderHeight = view_rect.bottom - view_rect.top; + + // _properties should reflect view rectangle + WindowProperties properties; + properties.set_origin(view_rect.left, view_rect.top); + properties.set_size(dwRenderWidth, dwRenderHeight); + system_changed_properties(properties); + + // Initialize the description of the primary surface + ZeroMemory(&SurfaceDesc, sizeof(DDSURFACEDESC2)); + SurfaceDesc.dwSize = sizeof(DDSURFACEDESC2); + SurfaceDesc.dwFlags = DDSD_CAPS ; + SurfaceDesc.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; + + PRINTVIDMEM(pDD, &SurfaceDesc.ddsCaps, "initial primary surface"); + + // Create the primary surface. This includes all of the visible + // window, so no need to specify height/width + hr = pDD->CreateSurface(&SurfaceDesc, &pPrimaryDDSurf, NULL); + if (FAILED(hr)) { + wdxdisplay7_cat.fatal() + << "CreateSurface failed for primary surface: result = " + << ConvD3DErrorToString(hr) << endl; + exit(1); + } + + // Create a clipper object which handles all our clipping for + // cases when our window is partially obscured by other windows. + LPDIRECTDRAWCLIPPER Clipper; + hr = pDD->CreateClipper(0, &Clipper, NULL); + if (FAILED(hr)) { + wdxdisplay7_cat.fatal() + << "CreateClipper failed : result = " + << ConvD3DErrorToString(hr) << endl; + exit(1); + } + + // Associate the clipper with our window. Note that, afterwards, + // the clipper is internally referenced by the primary surface, so + // it is safe to release our local reference to it. + Clipper->SetHWnd(0, Display.hWnd); + pPrimaryDDSurf->SetClipper(Clipper); + Clipper->Release(); + + // Clear the primary surface to black + DX_DECLARE_CLEAN(DDBLTFX, bltfx); + + hr = pPrimaryDDSurf->Blt(NULL,NULL,NULL,DDBLT_COLORFILL | DDBLT_WAIT,&bltfx); + if (FAILED(hr)) { + wdxdisplay7_cat.fatal() + << "Blt to Black of Primary Surf failed! : result = " << ConvD3DErrorToString(hr) << endl; + exit(1); + } + + // Set up a surface description to create a backbuffer. + SurfaceDesc.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS; + SurfaceDesc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE | DDSCAPS_VIDEOMEMORY; + SurfaceDesc.dwWidth = dwRenderWidth; + SurfaceDesc.dwHeight = dwRenderHeight; + + if (dx_full_screen_antialiasing) { + // cant check that d3ddevice has this capability yet, so got to + // set it anyway. hope this is OK. + SurfaceDesc.ddsCaps.dwCaps2 |= DDSCAPS2_HINTANTIALIASING; + } + + PRINTVIDMEM(pDD, &SurfaceDesc.ddsCaps, "initial backbuf"); + + // Create the backbuffer. (might want to handle failure due to + // running out of video memory) + hr = pDD->CreateSurface(&SurfaceDesc, &pBackDDSurf, NULL); + if (FAILED(hr)) { + wdxdisplay7_cat.fatal() + << "CreateSurface failed for backbuffer : result = " + << ConvD3DErrorToString(hr) << endl; + exit(1); + } + + hr = pBackDDSurf->Blt(NULL,NULL,NULL,DDBLT_COLORFILL | DDBLT_WAIT,&bltfx); + if (FAILED(hr)) { + wdxdisplay7_cat.fatal() + << "Blt to Black of Back Surf failed! : result = " + << ConvD3DErrorToString(hr) << endl; + exit(1); + } + } // end create windowed buffers + + // ======================================================== + + // resized(dwRenderWidth, dwRenderHeight); // update panda channel/display rgn info + + int framebuffer_mode = get_properties().get_framebuffer_mode(); + +#ifndef NDEBUG + if ((framebuffer_mode & WindowProperties::FM_depth) == 0) { + wdxdisplay7_cat.info() + << "no zbuffer requested, skipping zbuffer creation\n"; + } +#endif + + // Check if the device supports z-bufferless hidden surface + // removal. If so, we don't really need a z-buffer + if ((!(pD3DDevDesc->dpcTriCaps.dwRasterCaps & D3DPRASTERCAPS_ZBUFFERLESSHSR )) && + ((framebuffer_mode & WindowProperties::FM_depth) != 0)) { + + // Get z-buffer dimensions from the render target + DX_DECLARE_CLEAN(DDSURFACEDESC2,ddsd); + pBackDDSurf->GetSurfaceDesc( &ddsd ); + + // Setup the surface desc for the z-buffer. + ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_PIXELFORMAT; + ddsd.ddsCaps.dwCaps = DDSCAPS_ZBUFFER | ((_dxgsg->scrn.bIsSWRast) ? DDSCAPS_SYSTEMMEMORY : DDSCAPS_VIDEOMEMORY); + + DDPIXELFORMAT ZBufPixFmts[MAX_DX_ZBUF_FMTS]; + cNumZBufFmts=0; + + // Get an appropiate pixel format from enumeration of the + // formats. On the first pass, we look for a zbuffer dpeth which + // is equal to the frame buffer depth (as some cards unfornately + // require this). + hr = pD3DI->EnumZBufferFormats((Display.bIsTNLDevice ? IID_IDirect3DHALDevice : IID_IDirect3DTnLHalDevice), + EnumZBufFmtsCallback, + (VOID*)&ZBufPixFmts); + if (FAILED(hr)) { + wdxdisplay7_cat.fatal() << "EnumZBufferFormats failed" << endl; + exit(1); + } + +#ifdef _DEBUG + { + static BOOL bPrinted=FALSE; + if (!bPrinted) { + for (i = 0; i < cNumZBufFmts; i++) { + DebugPrintPixFmt(&ZBufPixFmts[i]); + } + bPrinted=TRUE; + } + } +#endif + + // should we pay attn to these at some point? + //int want_depth_bits = _props._want_depth_bits; + //int want_color_bits = _props._want_color_bits; + bool bWantStencil = ((framebuffer_mode & WindowProperties::FM_stencil) != 0); + + LPDDPIXELFORMAT pCurPixFmt, pz16 = NULL, pz24 = NULL, pz32 = NULL; + for (i = 0, pCurPixFmt = ZBufPixFmts; + i < cNumZBufFmts; + i++, pCurPixFmt++) { + if (bWantStencil == ((pCurPixFmt->dwFlags & DDPF_STENCILBUFFER)!=0)) { + switch (pCurPixFmt->dwRGBBitCount) { + case 16: + pz16 = pCurPixFmt; + break; + case 24: + pz24 = pCurPixFmt; + break; + case 32: + pz32 = pCurPixFmt; + break; + } + } + } + + if ((pz16 == NULL) && (pz24 == NULL) && (pz32 == NULL)) { + if (bWantStencil) { + wdxdisplay7_cat.fatal() + << "stencil buffer requested, device has no stencil capability\n"; + } else { + wdxdisplay7_cat.fatal() + << "failed to find adequate zbuffer capability\n"; + } + exit(1); + } + +#define SET_ZBUF_DEPTH(DEPTH) { assert(pz##DEPTH != NULL); Display.depth_buffer_bitdepth=DEPTH; ddsd.ddpfPixelFormat = *pz##DEPTH;} + + if (_dxgsg->scrn.bIsSWRast) { + SET_ZBUF_DEPTH(16); // need this for fast path rasterizers + } else { + if (IS_NVIDIA(Display.DXDeviceID)) { + DX_DECLARE_CLEAN(DDSURFACEDESC2,ddsd_pri); + pPrimaryDDSurf->GetSurfaceDesc(&ddsd_pri); + + // must pick zbuf depth to match primary surface depth for nvidia + if (ddsd_pri.ddpfPixelFormat.dwRGBBitCount==16) { + SET_ZBUF_DEPTH(16); + } else { + if (force_16bpp_zbuffer) { + wdxdisplay7_cat.fatal() + << "'dx-force-16bpp-zbuffer #t' requires a 16bpp desktop on nvidia cards\n"; + exit(1); + } + // take the smaller of 24 or 32. (already assured to match stencil capability) + if(pz24 != NULL) { + SET_ZBUF_DEPTH(24); + } else { + SET_ZBUF_DEPTH(32); + } + } + } else { + if (force_16bpp_zbuffer) { + if (pz16 == NULL) { + wdxdisplay7_cat.fatal() + << "'dx-force-16bpp-zbuffer #t', but no 16bpp zbuf fmts available on this card\n"; + exit(1); + } + + if(wdxdisplay7_cat.is_debug()) { + wdxdisplay7_cat.debug() << "forcing use of 16bpp Z-Buffer\n"; + } + SET_ZBUF_DEPTH(16); + ddsd.ddpfPixelFormat = *pz16; + + } else { + // pick the highest res zbuffer format avail. Note: this is + // choosing to waste vid-memory and possibly perf for more + // accuracy, less z-fighting at long distance (std 16bpp + // would be smaller, maybe faster) order of preference 24: + // (should be enough), 32: probably means 24 of Z, then 16 + + if (bWantStencil && (pz32!=NULL)) { + // dont want to select 16/8 z/stencil over 24/8 z/stenc + SET_ZBUF_DEPTH(32); + } else { + if (pz24!=NULL) { + SET_ZBUF_DEPTH(24); + } else if (pz32!=NULL) { + SET_ZBUF_DEPTH(32); + } else { + SET_ZBUF_DEPTH(16); + } + } + } + } + } + + PRINTVIDMEM(pDD, &ddsd.ddsCaps, "initial zbuf"); + +#ifdef _DEBUG + wdxdisplay7_cat.info() + << "Creating " << ddsd.ddpfPixelFormat.dwRGBBitCount << "bpp zbuffer\n"; +#endif + + // Create and attach a z-buffer + hr = pDD->CreateSurface(&ddsd, &pZDDSurf, NULL); + if (FAILED(hr)) { + wdxdisplay7_cat.fatal() + << "CreateSurface failed for Z buffer: result = " + << ConvD3DErrorToString(hr) << endl; + + if (((hr==DDERR_OUTOFVIDEOMEMORY)||(hr==DDERR_OUTOFMEMORY)) && + ((Display.dwFullScreenBitDepth>16)||(ddsd.ddpfPixelFormat.dwRGBBitCount>16))) { + Display.dwFullScreenBitDepth=16; + // emergency fallback to 16bpp (shouldnt have to do this + // unless GetAvailVidMem lied) will this work for multimon? + // what if surfs are already created on 1st mon? + + wdxdisplay7_cat.info() + << "GetAvailVidMem lied, not enough VidMem for 32bpp, so trying 16bpp on device #" + << Display.CardIDNum << endl; + + ULONG refcnt; + + // free pri and back (maybe should just free pri since created + // as complex chain?) + RELEASE(pBackDDSurf, wdxdisplay7, "backbuffer", false); + RELEASE(pPrimaryDDSurf, wdxdisplay7, "primary surface", false); + + hr = pDD->SetDisplayMode(Display.dwRenderWidth, + Display.dwRenderHeight, + Display.dwFullScreenBitDepth, + 0, 0); + if (FAILED(hr)) { + wdxdisplay7_cat.fatal() + << "SetDisplayMode failed to set (" + << Display.dwRenderWidth << "x" << Display.dwRenderHeight + << "x" << Display.dwFullScreenBitDepth << ") on device #" + << Display.CardIDNum << ": result = " + << ConvD3DErrorToString(hr) << endl; + exit(1); + } + create_screen_buffers_and_device(Display, true); + return; + + } else { + exit(1); + } + } + + hr = pBackDDSurf->AddAttachedSurface(pZDDSurf); + if (FAILED(hr)) { + wdxdisplay7_cat.fatal() + << "AddAttachedSurface failed : result = " + << ConvD3DErrorToString(hr) << endl; + exit(1); + } + } + + // Create the device. The device is created off of our back buffer, + // which becomes the render target for the newly created device. + hr = pD3DI->CreateDevice(pD3DDevDesc->deviceGUID, pBackDDSurf, &pD3DDevice); + if (hr != DD_OK) { + wdxdisplay7_cat.fatal() + << "CreateDevice failed : result = " + << ConvD3DErrorToString(hr) << endl; + exit(1); + } + + // No reason to create a viewport at this point. + /* + // Create the viewport + WindowProperties properties = get_properties(); + D3DVIEWPORT7 vp = { + 0, 0, + properties.get_x_size(), properties.get_y_size(), + 0.0f, 1.0f + }; + hr = pD3DDevice->SetViewport(&vp); + if (hr != DD_OK) { + wdxdisplay7_cat.fatal() + << "SetViewport failed : result = " << ConvD3DErrorToString(hr) << endl; + exit(1); + } + */ + + Display.pD3DDevice = pD3DDevice; + Display.pddsPrimary = pPrimaryDDSurf; + Display.pddsBack = pBackDDSurf; + Display.pddsZBuf = pZDDSurf; + Display.view_rect = view_rect; + + //pDD, pPrimaryDDSurf, pBackDDSurf, pZDDSurf, pD3DI, pD3DDevice, view_rect); + _dxgsg->dx_init(); + + // do not SetDXReady() yet since caller may want to do more work + // before letting rendering proceed + + // Oh, go ahead and call it. + _dxgsg->SetDXReady(true); +} + +//////////////////////////////////////////////////////////////////// +// Function: wdxGraphicsWindow7::search_for_device +// Access: Private +// Description: Searches for a suitable hardware device for +// rendering. +//////////////////////////////////////////////////////////////////// +bool wdxGraphicsWindow7:: +search_for_device(int devnum, DXDeviceInfo *pDevinfo) { + DWORD dwRenderWidth = get_properties().get_x_size(); + DWORD dwRenderHeight = get_properties().get_y_size(); + LPDIRECTDRAW7 pDD=NULL; + HRESULT hr; + + assert(_dxgsg != NULL); + + GUID *pDDDeviceGUID; + if (pDevinfo == NULL) { + pDDDeviceGUID = NULL; + } else { + pDDDeviceGUID = &pDevinfo->guidDeviceIdentifier; + } + + assert(_pDDCreateEx != NULL); + + // Create the Direct Draw Objects + hr = (*(_pDDCreateEx))(pDDDeviceGUID,(void **)&pDD, + IID_IDirectDraw7, NULL); + if ((hr != DD_OK) || (pDD == NULL)) { + wdxdisplay7_cat.fatal() + << "DirectDrawCreateEx failed for monitor(" << devnum + << "): result = " << ConvD3DErrorToString(hr) << endl; + return false; + } + + _dxgsg->scrn.pDD = pDD; + + // GetDeviceID bug writes an extra 4 bytes, so need xtra space + BYTE id_arr[sizeof(DDDEVICEIDENTIFIER2) + 4]; + pDD->GetDeviceIdentifier((DDDEVICEIDENTIFIER2 *)&id_arr, 0x0); + + memcpy(&_dxgsg->scrn.DXDeviceID, id_arr, sizeof(DDDEVICEIDENTIFIER2)); + + if (wdxdisplay7_cat.is_info()) { + DDDEVICEIDENTIFIER2 *pDevID = &_dxgsg->scrn.DXDeviceID; + wdxdisplay7_cat.info() + << "GfxCard: " << pDevID->szDescription << "; DriverFile: '" + << pDevID->szDriver + << "'; VendorID: 0x" << (void*)pDevID->dwVendorId + << "; DeviceID: 0x" << (void*)pDevID->dwDeviceId + << "; DriverVer: " + << HIWORD(pDevID->liDriverVersion.HighPart) << "." + << LOWORD(pDevID->liDriverVersion.HighPart) << "." + << HIWORD(pDevID->liDriverVersion.LowPart) << "." + << LOWORD(pDevID->liDriverVersion.LowPart) << endl; + } + + // Query DirectDraw for access to Direct3D + hr = pDD->QueryInterface(IID_IDirect3D7, (VOID**)&_dxgsg->scrn.pD3D); + if(hr != DD_OK) { + wdxdisplay7_cat.fatal() + << "QI for D3D failed : result = " << ConvD3DErrorToString(hr) << endl; + goto error_exit; + } + + D3DDEVICEDESC7 d3ddevs[3]; // put HAL in 0, TnLHAL in 1, SW rast in 2 + + // just look for HAL and TnL devices right now. I dont think + // we have any interest in the sw rasts at this point + + ZeroMemory(d3ddevs,3*sizeof(D3DDEVICEDESC7)); + + hr = _dxgsg->scrn.pD3D->EnumDevices(EnumDevicesCallback, d3ddevs); + if(hr != DD_OK) { + wdxdisplay7_cat.fatal() + << "EnumDevices failed : result = " << ConvD3DErrorToString(hr) << endl; + goto error_exit; + } + + WORD DeviceIdx; + + // select TNL if present + if (d3ddevs[TNLHALIDX].dwDevCaps & D3DDEVCAPS_HWRASTERIZATION) { + DeviceIdx = TNLHALIDX; + } else if (d3ddevs[REGHALIDX].dwDevCaps & D3DDEVCAPS_HWRASTERIZATION) { + DeviceIdx = REGHALIDX; + } else if (dx_allow_software_renderer || dx_force_software_renderer) { + DeviceIdx = SWRASTIDX; + } else { + wdxdisplay7_cat.error() + << "No 3D HW present on device #" << devnum << ", skipping it... (" + << _dxgsg->scrn.DXDeviceID.szDescription<<")\n"; + goto error_exit; + } + + if (dx_force_software_renderer) { + DeviceIdx = SWRASTIDX; + } + + memcpy(&_dxgsg->scrn.D3DDevDesc, &d3ddevs[DeviceIdx], + sizeof(D3DDEVICEDESC7)); + + _dxgsg->scrn.bIsTNLDevice = (DeviceIdx == TNLHALIDX); + + // Get Current VidMem avail. Note this is only an estimate, when we + // switch to fullscreen mode from desktop, more vidmem will be + // available (typically 1.2 meg). I dont want to switch to + // fullscreen more than once due to the annoying monitor flicker, so + // try to figure out optimal mode using this estimate + DDSCAPS2 ddsGAVMCaps; + DWORD dwVidMemTotal, dwVidMemFree; + dwVidMemTotal = dwVidMemFree = 0; + ZeroMemory(&ddsGAVMCaps, sizeof(DDSCAPS2)); + ddsGAVMCaps.dwCaps = DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM; // dont count AGP mem! + hr = pDD->GetAvailableVidMem(&ddsGAVMCaps,&dwVidMemTotal,&dwVidMemFree); + if (FAILED(hr)) { + wdxdisplay7_cat.error() + << "GetAvailableVidMem failed for device #" << devnum + << ": result = " << ConvD3DErrorToString(hr) << endl; + // goto skip_device; + exit(1); // probably want to exit, since it may be my fault + } + + // after SetDisplayMode, GetAvailVidMem totalmem seems to go down by + // 1.2 meg (contradicting above comment and what I think would be + // correct behavior (shouldnt FS mode release the desktop vidmem?), + // so this is the true value + _dxgsg->scrn.MaxAvailVidMem = dwVidMemTotal; + +#define LOWVIDMEMTHRESHOLD 5500000 +#define CRAPPY_DRIVER_IS_LYING_VIDMEMTHRESHOLD 1000000 // every vidcard we deal with should have at least 1MB + + // assume buggy drivers (this means you, FireGL2) may return zero for dwVidMemTotal, so ignore value if its < CRAPPY_DRIVER_IS_LYING_VIDMEMTHRESHOLD + _dxgsg->scrn.bIsLowVidMemCard = + ((dwVidMemTotal>CRAPPY_DRIVER_IS_LYING_VIDMEMTHRESHOLD) && + (dwVidMemTotal< LOWVIDMEMTHRESHOLD)); + + if (!dx_do_vidmemsize_check) { + _dxgsg->scrn.MaxAvailVidMem = 0xFFFFFFFF; + _dxgsg->scrn.bIsLowVidMemCard = false; + } + + if (DeviceIdx == SWRASTIDX) { + // this will force 640x480x16, is this what we want for all sw rast? + _dxgsg->scrn.bIsLowVidMemCard = true; + _dxgsg->scrn.bIsSWRast = true; + dx_force_16bpp_zbuffer = true; + } + + if (dx_full_screen) { + DX_DECLARE_CLEAN(DDSURFACEDESC2,ddsd_search); + ddsd_search.dwFlags = DDSD_HEIGHT | DDSD_WIDTH; + ddsd_search.dwWidth = dwRenderWidth; + ddsd_search.dwHeight = dwRenderHeight; + + DDSURFACEDESC2 DDSD_Arr[MAX_DISPLAY_MODES]; + DisplayModeInfo DMI; + ZeroMemory(&DDSD_Arr, sizeof(DDSD_Arr)); + ZeroMemory(&DMI, sizeof(DMI)); + DMI.maxWidth = dwRenderWidth; + DMI.maxHeight = dwRenderHeight; + DMI.pDDSD_Arr = DDSD_Arr; + + hr= pDD->EnumDisplayModes(DDEDM_REFRESHRATES, &ddsd_search, + &DMI, EnumDisplayModesCallBack); + if (FAILED(hr)) { + wdxdisplay7_cat.fatal() + << "EnumDisplayModes failed for device #" << devnum + << " (" << _dxgsg->scrn.DXDeviceID.szDescription + << "), result = " << ConvD3DErrorToString(hr) << endl; + // goto skip_device; + exit(1); // probably want to exit, since it may be my fault + } + + if (wdxdisplay7_cat.is_info()) { + wdxdisplay7_cat.info() + << "Before fullscreen switch: GetAvailableVidMem for device #" + << devnum << " returns Total: " << dwVidMemTotal/1000000.0 + << " Free: " << dwVidMemFree/1000000.0 << endl; + } + + // Now we try to figure out if we can use requested screen + // resolution and best rendertarget bpp and still have at least 2 + // meg of texture vidmem + + DMI.supportedBitDepths &= _dxgsg->scrn.D3DDevDesc.dwDeviceRenderBitDepth; + + DWORD dwFullScreenBitDepth; + + // note: this chooses 32bpp, which may not be preferred over 16 + // for memory & speed reasons + if (DMI.supportedBitDepths & DDBD_32) { + dwFullScreenBitDepth = 32; // go for 32bpp if its avail + } else if (DMI.supportedBitDepths & DDBD_24) { + dwFullScreenBitDepth = 24; // go for 24bpp if its avail + } else if (DMI.supportedBitDepths & DDBD_16) { + dwFullScreenBitDepth = 16; // do 16bpp + } else { + wdxdisplay7_cat.fatal() + << "No Supported FullScreen resolutions at " << dwRenderWidth + << "x" << dwRenderHeight << " for device #" << devnum + << " (" << _dxgsg->scrn.DXDeviceID.szDescription + << "), skipping device...\n"; + goto error_exit; + } + + if (_dxgsg->scrn.bIsLowVidMemCard) { + { + // hack: figuring out exactly what res to use is tricky, + // instead I will just use 640x480 if we have < 3 meg avail + + dwFullScreenBitDepth = 16; + dwRenderWidth = 640; + dwRenderHeight = 480; + dx_force_16bpptextures = true; + + if (wdxdisplay7_cat.is_info()) + wdxdisplay7_cat.info() + << "Available VidMem (" << dwVidMemFree << ") is under " + << LOWVIDMEMTHRESHOLD + << ", using 640x480 16bpp rendertargets to save tex vidmem.\n"; + } + } + + _dxgsg->scrn.dwFullScreenBitDepth = dwFullScreenBitDepth; + } + + _dxgsg->scrn.dwRenderWidth = dwRenderWidth; + _dxgsg->scrn.dwRenderHeight = dwRenderHeight; + if (pDevinfo) { + _dxgsg->scrn.hMon = pDevinfo->hMon; + } + _dxgsg->scrn.CardIDNum = devnum; // add ID tag for dbgprint purposes + + return true; + + // handle errors within this for device loop + + error_exit: + if (_dxgsg->scrn.pD3D != NULL) + _dxgsg->scrn.pD3D->Release(); + if (_dxgsg->scrn.pDD != NULL) + _dxgsg->scrn.pDD->Release(); + + _dxgsg->scrn.pDD = NULL; + _dxgsg->scrn.pD3D = NULL; + return false; +} + +//////////////////////////////////////////////////////////////////// +// Function: wdxGraphicsWindow7::set_coop_levels_and_display_modes +// Access: Private +// Description: +//////////////////////////////////////////////////////////////////// +void wdxGraphicsWindow7:: +set_coop_levels_and_display_modes() { + HRESULT hr; + DWORD SCL_FPUFlag; + + if (dx_preserve_fpu_state) { + // tell d3d to preserve the fpu state across calls. this hurts + // perf, but is good for dbgging + SCL_FPUFlag = DDSCL_FPUPRESERVE; + + } else { + SCL_FPUFlag = DDSCL_FPUSETUP; + } + + DXScreenData *pScrn = &_dxgsg->scrn; + + if (!is_fullscreen()) { + hr = pScrn->pDD->SetCooperativeLevel(_mwindow, + SCL_FPUFlag | DDSCL_NORMAL); + if (FAILED(hr)) { + wdxdisplay7_cat.fatal() + << "SetCooperativeLevel failed : result = " + << ConvD3DErrorToString(hr) << endl; + exit(1); + } + return; + } + + DWORD SCL_FLAGS = SCL_FPUFlag | DDSCL_FULLSCREEN | DDSCL_EXCLUSIVE | DDSCL_ALLOWREBOOT; + + // The following code would be done per window if were supporting + // multiple fullscreen windows on different graphics cards. TODO: + // restore that functionality. + DWORD devnum = 0; + { + DXScreenData *pScrn = &_dxgsg->scrn; + + // need to set focus/device windows for multimon + // focus window is primary monitor that will receive keybd input + // all ddraw objs need to have same focus window + /* + if(_windows.size()>1) { + if(FAILED(hr = pScrn->pDD->SetCooperativeLevel(_hParentWindow, DDSCL_SETFOCUSWINDOW))) { + wdxdisplay7_cat.fatal() << "SetCooperativeLevel SetFocusWindow failed on device 0: result = " << ConvD3DErrorToString(hr) << endl; + exit(1); + } + } + */ + + // s3 savage2000 on w95 seems to set EXCLUSIVE_MODE only if you call + // SetCoopLevel twice. so we do it, it really shouldnt be necessary + // if drivers werent buggy + for (int jj=0; jj<2; jj++) { + hr = pScrn->pDD->SetCooperativeLevel(pScrn->hWnd, SCL_FLAGS); + if (FAILED(hr)) { + wdxdisplay7_cat.fatal() + << "SetCooperativeLevel failed for device #" << devnum + << ": result = " << ConvD3DErrorToString(hr) << endl; + exit(1); + } + } + + hr = pScrn->pDD->TestCooperativeLevel(); + if (FAILED(hr)) { + wdxdisplay7_cat.fatal() + << "TestCooperativeLevel failed: result = " << ConvD3DErrorToString(hr) + << endl; + wdxdisplay7_cat.fatal() + << "Full screen app failed to get exclusive mode on init, exiting..\n"; + exit(1); + } + + // note: its important we call SetDisplayMode on all cards before + // creating surfaces on any of them let driver choose default + // refresh rate (hopefully its >=60Hz) + hr = pScrn->pDD->SetDisplayMode(pScrn->dwRenderWidth, + pScrn->dwRenderHeight, + pScrn->dwFullScreenBitDepth, 0, 0); + if (FAILED(hr)) { + wdxdisplay7_cat.fatal() + << "SetDisplayMode failed to set (" << pScrn->dwRenderWidth + << "x" <dwRenderHeight << "x" << pScrn->dwFullScreenBitDepth + << ") on device #" << pScrn->CardIDNum << ": result = " + << ConvD3DErrorToString(hr) << endl; + exit(1); + } + + if(wdxdisplay7_cat.is_debug()) { + DX_DECLARE_CLEAN(DDSURFACEDESC2,ddsd34); + pScrn->pDD->GetDisplayMode(&ddsd34); + wdxdisplay7_cat.debug() + << "set displaymode to " << ddsd34.dwWidth << "x" << ddsd34.dwHeight + << " at " << ddsd34.ddpfPixelFormat.dwRGBBitCount << "bpp, " + << ddsd34.dwRefreshRate<< "Hz\n"; + } + } +} + + +//////////////////////////////////////////////////////////////////// +// Function: wdxGraphicsWindow7::init_ddraw +// Access: Private, Static +// Description: Gets the pointer to the DirectDrawCreateEx function +// from ddraw.dll, if it hasn't been retrieved already. +//////////////////////////////////////////////////////////////////// +void wdxGraphicsWindow7:: +init_ddraw() { + if (_hDDrawDLL != NULL) { + return; + } + + static const char * const ddraw_name = "ddraw.dll"; + _hDDrawDLL = LoadLibrary(ddraw_name); + if(_hDDrawDLL == 0) { + wdxdisplay7_cat.fatal() + << "can't locate " << ddraw_name <<"!\n"; + exit(1); + } + + _pDDCreateEx = (LPDIRECTDRAWCREATEEX)GetProcAddress(_hDDrawDLL,"DirectDrawCreateEx"); + if(_pDDCreateEx == NULL) { + wdxdisplay7_cat.fatal() + << "Panda currently requires at least DirectX 7.0!\n"; + exit(1); + } +} + diff --git a/panda/src/dxgsg7/wdxGraphicsWindow7.h b/panda/src/dxgsg7/wdxGraphicsWindow7.h new file mode 100644 index 0000000000..a47eed93fa --- /dev/null +++ b/panda/src/dxgsg7/wdxGraphicsWindow7.h @@ -0,0 +1,92 @@ +// Filename: wdxGraphicsWindow7.h +// Created by: drose (20Dec02) +// +//////////////////////////////////////////////////////////////////// +// +// 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 WDXGRAPHICSWINDOW7_H +#define WDXGRAPHICSWINDOW7_H + +#include "pandabase.h" +#include "winGraphicsWindow.h" +#include "pvector.h" + +class DXGraphicsStateGuardian7; + +typedef struct { + char szDriver[MAX_DDDEVICEID_STRING]; + char szDescription[MAX_DDDEVICEID_STRING]; + GUID guidDeviceIdentifier; + HMONITOR hMon; +} DXDeviceInfo; +typedef pvector DXDeviceInfoVec; + +typedef HRESULT (WINAPI * LPDIRECTDRAWCREATEEX)(GUID FAR * lpGuid, LPVOID *lplpDD, REFIID iid,IUnknown FAR *pUnkOuter); + +//////////////////////////////////////////////////////////////////// +// Class : wdxGraphicsWindow7 +// Description : A single graphics window for rendering DirectX under +// Microsoft Windows. +//////////////////////////////////////////////////////////////////// +class EXPCL_PANDADX wdxGraphicsWindow7 : public WinGraphicsWindow { +public: + wdxGraphicsWindow7(GraphicsPipe *pipe); + virtual ~wdxGraphicsWindow7(); + + virtual void make_gsg(); + virtual void release_gsg(); + + virtual void end_flip(); + +protected: + virtual void fullscreen_restored(WindowProperties &properties); + virtual void handle_reshape(); + virtual bool do_fullscreen_resize(int x_size, int y_size); + +private: + bool set_to_temp_rendertarget(); + void create_screen_buffers_and_device(DXScreenData &Display, + bool force_16bpp_zbuffer); + bool search_for_device(int devnum, DXDeviceInfo *pDevinfo); + void set_coop_levels_and_display_modes(); + + static void init_ddraw(); + + DXGraphicsStateGuardian7 *_dxgsg; + + static HINSTANCE _hDDrawDLL; + static LPDIRECTDRAWCREATEEX _pDDCreateEx; + +public: + static TypeHandle get_class_type() { + return _type_handle; + } + static void init_type() { + WinGraphicsWindow::init_type(); + register_type(_type_handle, "wdxGraphicsWindow7", + WinGraphicsWindow::get_class_type()); + } + virtual TypeHandle get_type() const { + return get_class_type(); + } + virtual TypeHandle force_init_type() {init_type(); return get_class_type();} + +private: + static TypeHandle _type_handle; +}; + +#include "wdxGraphicsWindow7.I" + +#endif diff --git a/panda/src/dxgsg8/Sources.pp b/panda/src/dxgsg8/Sources.pp index dcea0faeb8..d6f1171fe1 100644 --- a/panda/src/dxgsg8/Sources.pp +++ b/panda/src/dxgsg8/Sources.pp @@ -7,7 +7,7 @@ #begin lib_target #define TARGET dxgsg8 #define LOCAL_LIBS \ - gsgmisc gsgbase gobj display \ + gsgmisc gsgbase gobj display windisplay \ putil linmath mathutil pnmimage event #define COMBINED_SOURCES $[TARGET]_composite1.cxx @@ -20,9 +20,16 @@ // build dxGraphicsStateGuardian separately since its so big #define SOURCES \ - dxGraphicsStateGuardian8.cxx dxSavedFrameBuffer8.I dxSavedFrameBuffer8.h $[INSTALL_HEADERS] + dxGraphicsStateGuardian8.cxx dxSavedFrameBuffer8.I dxSavedFrameBuffer8.h \ + wdxGraphicsPipe8.I wdxGraphicsPipe8.h \ + wdxGraphicsWindow8.I wdxGraphicsWindow8.h \ + $[INSTALL_HEADERS] #define INCLUDED_SOURCES \ - config_dxgsg8.cxx dxSavedFrameBuffer8.cxx dxTextureContext8.cxx dxGeomNodeContext8.cxx d3dfont8.cxx + config_dxgsg8.cxx \ + dxSavedFrameBuffer8.cxx dxTextureContext8.cxx \ + dxGeomNodeContext8.cxx \ + d3dfont8.cxx \ + wdxGraphicsPipe8.cxx wdxGraphicsWindow8.cxx #end lib_target diff --git a/panda/src/dxgsg8/config_dxgsg8.cxx b/panda/src/dxgsg8/config_dxgsg8.cxx index 970ff206ae..f28cb74c7e 100644 --- a/panda/src/dxgsg8/config_dxgsg8.cxx +++ b/panda/src/dxgsg8/config_dxgsg8.cxx @@ -1,4 +1,4 @@ -// Filename: config_dxgsg.cxx +// Filename: config_dxgsg8.cxx // Created by: drose (06Oct99) // //////////////////////////////////////////////////////////////////// @@ -20,39 +20,43 @@ #include "dxGraphicsStateGuardian8.h" #include "dxSavedFrameBuffer8.h" #include "dxTextureContext8.h" +#include "graphicsPipeSelection.h" +#include "wdxGraphicsWindow8.h" +#include "wdxGraphicsPipe8.h" #include -Configure(config_dxgsg); -NotifyCategoryDef(dxgsg, ":display:gsg"); +Configure(config_dxgsg8); +NotifyCategoryDef(dxgsg8, ":display:gsg"); +NotifyCategoryDef(wdxdisplay8, "windisplay"); // Configure this variable true to cause the DXGSG to show each // transform space it renders by drawing a little unit axis. This // cannot be enabled when the player is compiled in NDEBUG mode. -bool dx_show_transforms = config_dxgsg.GetBool("dx-show-transforms", false); +bool dx_show_transforms = config_dxgsg8.GetBool("dx-show-transforms", false); // Configure this to TRUE if you want DirectX to control the entire screen, // If false, it will just blit into a window. -bool dx_full_screen = config_dxgsg.GetBool("dx-full-screen", false); +bool dx_full_screen = config_dxgsg8.GetBool("dx-full-screen", false); // Configure this true to force the rendering to sync to the video // refresh, or false to let your frame rate go as high as it can, // irrespective of the video refresh. -bool dx_sync_video = config_dxgsg.GetBool("sync-video", true); +bool dx_sync_video = config_dxgsg8.GetBool("sync-video", true); // Set Level of MultiSampling to be used, if HW supports it. Valid values are 2-16. -DWORD dx_multisample_antialiasing_level = (DWORD) config_dxgsg.GetInt("dx-multisample-antialiasing-level", 0); +DWORD dx_multisample_antialiasing_level = (DWORD) config_dxgsg8.GetInt("dx-multisample-antialiasing-level", 0); // Configure this true to perform a cull traversal over the geometry // by default, false otherwise. The cull traversal provides support // for state-sorting, z-sorting, and binning. -bool dx_cull_traversal = config_dxgsg.GetBool("dx-cull-traversal", true); +bool dx_cull_traversal = config_dxgsg8.GetBool("dx-cull-traversal", true); // if true, if card only supports per-vertex fog, it will be treated as no-HW fog capability -bool dx_no_vertex_fog = config_dxgsg.GetBool("dx-no-vertex-fog", false); +bool dx_no_vertex_fog = config_dxgsg8.GetBool("dx-no-vertex-fog", false); // if true, overwrite cursor bitmap tip with "D3D" to distinguish it from GDI cursor -bool dx_show_cursor_watermark = config_dxgsg.GetBool("dx-show-cursor-watermark", +bool dx_show_cursor_watermark = config_dxgsg8.GetBool("dx-show-cursor-watermark", #ifdef _DEBUG true #else @@ -61,7 +65,7 @@ bool dx_show_cursor_watermark = config_dxgsg.GetBool("dx-show-cursor-watermark", ); // if true, triangle filter will be used to generate mipmap levels instead of default box filter -bool dx_use_triangle_mipgen_filter = config_dxgsg.GetBool("dx-use-triangle-mipgen-filter", false); +bool dx_use_triangle_mipgen_filter = config_dxgsg8.GetBool("dx-use-triangle-mipgen-filter", false); // Configure this true to cause all lighting normals to automatically // be normalized by the CPU before rendering. This is @@ -69,40 +73,50 @@ bool dx_use_triangle_mipgen_filter = config_dxgsg.GetBool("dx-use-triangle-mipge // expect lighting to work correctly. Maybe one day there will be // another way to set this at runtime, instead of only as a configure // variable -bool dx_auto_normalize_lighting = config_dxgsg.GetBool("auto-normalize-lighting", false); +bool dx_auto_normalize_lighting = config_dxgsg8.GetBool("auto-normalize-lighting", false); -bool dx_show_fps_meter = config_dxgsg.GetBool("show-fps-meter", false); -float dx_fps_meter_update_interval = max(0.5,config_dxgsg.GetFloat("fps-meter-update-interval", 1.7)); +bool dx_show_fps_meter = config_dxgsg8.GetBool("show-fps-meter", false); +float dx_fps_meter_update_interval = max(0.5,config_dxgsg8.GetFloat("fps-meter-update-interval", 1.7)); #ifndef NDEBUG // debugging flag // values are same as D3DCULL enumtype, 0 - no force, 1 - force none, 2 - force CW, 3 - force CCW -int dx_force_backface_culling = config_dxgsg.GetInt("dx-force-backface-culling", 0); +int dx_force_backface_culling = config_dxgsg8.GetInt("dx-force-backface-culling", 0); #endif -bool dx_mipmap_everything = config_dxgsg.GetBool("dx-mipmap-everything", false); -bool dx_ignore_mipmaps = config_dxgsg.GetBool("dx-ignore-mipmaps", false); +bool dx_mipmap_everything = config_dxgsg8.GetBool("dx-mipmap-everything", false); +bool dx_ignore_mipmaps = config_dxgsg8.GetBool("dx-ignore-mipmaps", false); // if this is set, more accurate but more expensive fog computations are performed -bool dx_use_rangebased_fog = config_dxgsg.GetBool("dx-use-rangebased-fog", false); -bool dx_force_16bpptextures = config_dxgsg.GetBool("dx-force-16bpptextures", false); -bool dx_no_dithering = config_dxgsg.GetBool("dx-no-dithering", false); +bool dx_use_rangebased_fog = config_dxgsg8.GetBool("dx-use-rangebased-fog", false); +bool dx_force_16bpptextures = config_dxgsg8.GetBool("dx-force-16bpptextures", false); +bool dx_no_dithering = config_dxgsg8.GetBool("dx-no-dithering", false); +bool dx_force_16bpp_zbuffer = config_dxgsg8.GetBool("dx-force-16bpp-zbuffer", false); +bool dx_do_vidmemsize_check = config_dxgsg8.GetBool("do-vidmemsize-check", true); +bool dx_preserve_fpu_state = config_dxgsg8.GetBool("dx-preserve-fpu-state", false); + +// if true, override win-width/height and use driver vidmem info to +// pick what will be a fullscreen window size close to the best perf +// capability of card, based on a heuristic +bool dx_pick_best_screenres = config_dxgsg8.GetBool("pick-best-screenres", false); + +int dx_preferred_device_id = config_dxgsg8.GetInt("dx-preferred-device-id", -1); #ifdef _DEBUG -float dx_global_miplevel_bias = config_dxgsg.GetFloat("dx-global-miplevel-bias", 0.0); -bool dx_debug_view_mipmaps = config_dxgsg.GetBool("dx-debug-view-mipmaps", false); -//int dx_print_texstats = config_dxgsg.GetBool("dx-print-texstats", 0); +float dx_global_miplevel_bias = config_dxgsg8.GetFloat("dx-global-miplevel-bias", 0.0); +bool dx_debug_view_mipmaps = config_dxgsg8.GetBool("dx-debug-view-mipmaps", false); +//int dx_print_texstats = config_dxgsg8.GetBool("dx-print-texstats", 0); #endif // use dx8 or GDI mouse cursor in fullscreen mode? // Nvidia dx8 cursor is invisible as of 28.32 drivers, so using GDI in fullscrn by default for now -bool dx_use_dx_cursor = config_dxgsg.GetBool("dx-use-dx-cursor", false); +bool dx_use_dx_cursor = config_dxgsg8.GetBool("dx-use-dx-cursor", false); -bool dx_force_anisotropic_filtering = config_dxgsg.GetBool("dx-force-anisotropic-filtering", false); +bool dx_force_anisotropic_filtering = config_dxgsg8.GetBool("dx-force-anisotropic-filtering", false); // set 'retained-mode #t' and this to have prepare_geom concatenate all tristrips within a geom // together using degenerate tris -const bool link_tristrips = config_dxgsg.GetBool("link-tristrips", false); +const bool link_tristrips = config_dxgsg8.GetBool("link-tristrips", false); // note: offset currently disabled since it wasnt working properly DXDecalType dx_decal_type = GDT_mask; @@ -116,7 +130,7 @@ string *pdx_pixelshader_filename=NULL; // texture file to be set globally, usually for special FX string *pdx_globaltexture_filename=NULL; // tex stagenum to set the global tex to -UINT dx_globaltexture_stagenum = (UINT) config_dxgsg.GetInt("dx-globaltexture-stagenum", 0); +UINT dx_globaltexture_stagenum = (UINT) config_dxgsg8.GetInt("dx-globaltexture-stagenum", 0); static DXDecalType parse_decal_type(const string &type) { @@ -127,11 +141,11 @@ parse_decal_type(const string &type) { } else if (type == "offset") { return GDT_offset; } - dxgsg_cat.error() << "Invalid dx-decal-type: " << type << "\n"; + dxgsg8_cat.error() << "Invalid dx-decal-type: " << type << "\n"; return GDT_mask; } -ConfigureFn(config_dxgsg) { +ConfigureFn(config_dxgsg8) { init_libdxgsg8(); } @@ -139,7 +153,7 @@ void init_config_string(string *&pFname,const char *ConfigrcVarname) { // pFname is reference to string ptr // dont try to take the & of a soon-to-be-gone stack var string, this must be on the heap! - pFname = new string(config_dxgsg.GetString(ConfigrcVarname, "")); + pFname = new string(config_dxgsg8.GetString(ConfigrcVarname, "")); if(pFname->empty()) { delete pFname; pFname=NULL; @@ -162,7 +176,7 @@ init_libdxgsg8() { } initialized = true; - string decal_type = config_dxgsg.GetString("dx-decal-type", ""); + string decal_type = config_dxgsg8.GetString("dx-decal-type", ""); if (!decal_type.empty()) { dx_decal_type = parse_decal_type(decal_type); } @@ -171,14 +185,17 @@ init_libdxgsg8() { init_config_string(pdx_pixelshader_filename,"dx-pixelshader-filename"); init_config_string(pdx_globaltexture_filename,"dx-globaltexture-filename"); - DXGraphicsStateGuardian::init_type(); - DXSavedFrameBuffer::init_type(); - DXTextureContext::init_type(); - DXGeomNodeContext::init_type(); + DXGraphicsStateGuardian8::init_type(); + DXSavedFrameBuffer8::init_type(); + DXTextureContext8::init_type(); + DXGeomNodeContext8::init_type(); - GraphicsStateGuardian::get_factory().register_factory - (DXGraphicsStateGuardian::get_class_type(), - DXGraphicsStateGuardian::make_DXGraphicsStateGuardian); + wdxGraphicsPipe8::init_type(); + wdxGraphicsWindow8::init_type(); + + GraphicsPipeSelection *selection = GraphicsPipeSelection::get_global_ptr(); + selection->add_pipe_type(wdxGraphicsPipe8::get_class_type(), + wdxGraphicsPipe8::pipe_constructor); } const char *D3DFormatStr(D3DFORMAT fmt) { diff --git a/panda/src/dxgsg8/config_dxgsg8.h b/panda/src/dxgsg8/config_dxgsg8.h index 59fe747332..48ebcfc469 100644 --- a/panda/src/dxgsg8/config_dxgsg8.h +++ b/panda/src/dxgsg8/config_dxgsg8.h @@ -19,11 +19,12 @@ #ifndef CONFIG_DXGSG8_H #define CONFIG_DXGSG8_H -#include -#include +#include "pandabase.h" +#include "notifyCategoryProxy.h" #include -NotifyCategoryDecl(dxgsg, EXPCL_PANDADX, EXPTP_PANDADX); +NotifyCategoryDecl(dxgsg8, EXPCL_PANDADX, EXPTP_PANDADX); +NotifyCategoryDecl(wdxdisplay8, EXPCL_PANDADX, EXPTP_PANDADX); extern bool dx_full_screen; extern bool dx_sync_video; @@ -48,6 +49,11 @@ extern bool dx_show_transforms; extern bool dx_force_16bpptextures; extern bool dx_no_dithering; extern bool dx_force_anisotropic_filtering; +extern bool dx_force_16bpp_zbuffer; +extern bool dx_do_vidmemsize_check; +extern bool dx_preserve_fpu_state; +extern bool dx_pick_best_screenres; +extern int dx_preferred_device_id; extern string *pdx_vertexshader_filename; extern string *pdx_pixelshader_filename; diff --git a/panda/src/dxgsg8/d3dfont8.cxx b/panda/src/dxgsg8/d3dfont8.cxx index 09243ebca2..e64113406a 100644 --- a/panda/src/dxgsg8/d3dfont8.cxx +++ b/panda/src/dxgsg8/d3dfont8.cxx @@ -123,7 +123,7 @@ HRESULT CD3DFont::InitDeviceObjects( LPDIRECT3DDEVICE8 pd3dDevice ) { CLIP_DEFAULT_PRECIS, ANTIALIASED_QUALITY, VARIABLE_PITCH, m_strFontName ); if(NULL==hFont) { - dxgsg_cat.error() << "CD3DFont InitDeviceObjects(): initial CreateFont failed! GetLastError=" << GetLastError() << endl; + dxgsg8_cat.error() << "CD3DFont InitDeviceObjects(): initial CreateFont failed! GetLastError=" << GetLastError() << endl; return E_FAIL; } @@ -194,7 +194,7 @@ HRESULT CD3DFont::InitDeviceObjects( LPDIRECT3DDEVICE8 pd3dDevice ) { // moved here to allow deletion of GDI objects if(dwTexSize == 0) { - dxgsg_cat.error() << "CD3DFont InitDeviceObjects() error: Texture didnt fit, creation failed!\n"; + dxgsg8_cat.error() << "CD3DFont InitDeviceObjects() error: Texture didnt fit, creation failed!\n"; return E_FAIL; } @@ -228,7 +228,7 @@ HRESULT CD3DFont::InitDeviceObjects( LPDIRECT3DDEVICE8 pd3dDevice ) { VARIABLE_PITCH, m_strFontName ); if(NULL==hFont) { - dxgsg_cat.error() << "CD3DFont InitDeviceObjects(): optimal CreateFont failed! GetLastError=" << GetLastError() << endl; + dxgsg8_cat.error() << "CD3DFont InitDeviceObjects(): optimal CreateFont failed! GetLastError=" << GetLastError() << endl; return E_FAIL; } @@ -263,7 +263,7 @@ HRESULT CD3DFont::InitDeviceObjects( LPDIRECT3DDEVICE8 pd3dDevice ) { DeleteObject( hFont ); DeleteDC( hDC ); - dxgsg_cat.error() << "CD3DFont InitDeviceObjs CreateTexture failed!" << D3DERRORSTRING(hr); + dxgsg8_cat.error() << "CD3DFont InitDeviceObjs CreateTexture failed!" << D3DERRORSTRING(hr); return hr; }; @@ -341,11 +341,11 @@ HRESULT CD3DFont::RestoreDeviceObjects() { D3DUSAGE_WRITEONLY | D3DUSAGE_DYNAMIC, 0, D3DPOOL_DEFAULT, // D3DUSAGE_DYNAMIC makes D3DPOOL_MANAGED impossible &m_pVB ) )) { - dxgsg_cat.error() << "CD3DFont CreateVB failed!" << D3DERRORSTRING(hr); + dxgsg8_cat.error() << "CD3DFont CreateVB failed!" << D3DERRORSTRING(hr); return hr; } - PRINT_REFCNT(dxgsg,m_pd3dDevice); + PRINT_REFCNT(dxgsg8,m_pd3dDevice); // Create the state blocks for rendering text for(UINT which=0; which<2; which++) { @@ -403,7 +403,7 @@ HRESULT CD3DFont::RestoreDeviceObjects() { HRESULT CD3DFont::InvalidateDeviceObjects() { HRESULT hr; - PRINT_REFCNT(dxgsg,m_pd3dDevice); + PRINT_REFCNT(dxgsg8,m_pd3dDevice); if(IS_VALID_PTR(m_pd3dDevice)) { // undo SetStreamSource before releasing VB @@ -416,11 +416,11 @@ HRESULT CD3DFont::InvalidateDeviceObjects() { hr = m_pd3dDevice->SetStreamSource(0,NULL,0); } - PRINT_REFCNT(dxgsg,m_pVB); + PRINT_REFCNT(dxgsg8,m_pVB); - RELEASE(m_pVB,dxgsg,"d3dfont VB",RELEASE_ONCE); + RELEASE(m_pVB,dxgsg8,"d3dfont VB",RELEASE_ONCE); - PRINT_REFCNT(dxgsg,m_pd3dDevice); + PRINT_REFCNT(dxgsg8,m_pd3dDevice); // Delete the state blocks if(m_pd3dDevice) { @@ -431,7 +431,7 @@ HRESULT CD3DFont::InvalidateDeviceObjects() { m_pd3dDevice->DeleteStateBlock( m_dwDrawTextStateBlock ); } - PRINT_REFCNT(dxgsg,m_pd3dDevice); + PRINT_REFCNT(dxgsg8,m_pd3dDevice); m_dwSavedStateBlock = NULL; m_dwDrawTextStateBlock = NULL; @@ -445,13 +445,13 @@ HRESULT CD3DFont::InvalidateDeviceObjects() { // Desc: Destroys all device-dependent objects //----------------------------------------------------------------------------- HRESULT CD3DFont::DeleteDeviceObjects() { - PRINT_REFCNT(dxgsg,m_pd3dDevice); + PRINT_REFCNT(dxgsg8,m_pd3dDevice); InvalidateDeviceObjects(); SAFE_RELEASE( m_pTexture ); - PRINT_REFCNT(dxgsg,m_pd3dDevice); + PRINT_REFCNT(dxgsg8,m_pd3dDevice); m_pd3dDevice = NULL; @@ -581,7 +581,7 @@ HRESULT CD3DFont::DeferedDraw FLOAT fXScale, FLOAT fYScale, DWORD dwColor, TCHAR* strText, DWORD dwFlags ) { if(m_nDeferedCalls >= MaxCalls) { - dxgsg_cat.error() << "CD3DFont DeferedDraw() error, MaxCalls exceeded!\n"; + dxgsg8_cat.error() << "CD3DFont DeferedDraw() error, MaxCalls exceeded!\n"; return E_FAIL ; } @@ -591,7 +591,7 @@ HRESULT CD3DFont::DeferedDraw int nStrLen = strlen ( strText ) + 1 ; int nUsed = m_pTextBuffer - & m_pTextBuffer [ 0 ] ; if(nUsed + nStrLen > TextBufferLength) { - dxgsg_cat.error() << "CD3DFont DeferedDraw() error, TextBufferLength exceeded!\n"; + dxgsg8_cat.error() << "CD3DFont DeferedDraw() error, TextBufferLength exceeded!\n"; return E_FAIL ; } @@ -637,7 +637,7 @@ HRESULT CD3DFont::EndText ( void ) { hr = m_pd3dDevice->GetStreamSource(0,&pSavedStreamData,&SavedStreamStride); if(FAILED(hr)) { - dxgsg_cat.error() << "CD3DFont EndText GetStreamSource() failed!" << D3DERRORSTRING(hr); + dxgsg8_cat.error() << "CD3DFont EndText GetStreamSource() failed!" << D3DERRORSTRING(hr); return E_FAIL; } @@ -647,7 +647,7 @@ HRESULT CD3DFont::EndText ( void ) { if((pSavedStreamData!=m_pVB)||(SavedStreamStride!=sizeof(FONT2DVERTEX))) { hr = m_pd3dDevice->SetStreamSource(0,m_pVB,sizeof(FONT2DVERTEX)); if(FAILED(hr)) { - dxgsg_cat.error() << "CD3DFont EndText initial SetStreamSource() failed!" << D3DERRORSTRING(hr); + dxgsg8_cat.error() << "CD3DFont EndText initial SetStreamSource() failed!" << D3DERRORSTRING(hr); return E_FAIL; } } @@ -821,7 +821,7 @@ HRESULT CD3DFont::EndText ( void ) { if(IS_VALID_PTR(pSavedStreamData) && ((pSavedStreamData!=m_pVB)||(SavedStreamStride!=sizeof(FONT2DVERTEX)))) { hr = m_pd3dDevice->SetStreamSource(0,pSavedStreamData,SavedStreamStride); if(FAILED(hr)) { - dxgsg_cat.error() << "CD3DFont EndText restore SetStreamSource() failed!" << D3DERRORSTRING(hr); + dxgsg8_cat.error() << "CD3DFont EndText restore SetStreamSource() failed!" << D3DERRORSTRING(hr); return E_FAIL; } pSavedStreamData->Release(); diff --git a/panda/src/dxgsg8/dxGeomNodeContext8.I b/panda/src/dxgsg8/dxGeomNodeContext8.I index 739d1d127a..c557e9ac2d 100644 --- a/panda/src/dxgsg8/dxGeomNodeContext8.I +++ b/panda/src/dxgsg8/dxGeomNodeContext8.I @@ -18,12 +18,12 @@ //////////////////////////////////////////////////////////////////// -// Function: dxGeomNodeContext::Constructor +// Function: DXGeomNodeContext8::Constructor // Access: Public // Description: //////////////////////////////////////////////////////////////////// -INLINE DXGeomNodeContext:: -DXGeomNodeContext(GeomNode *node) : GeomNodeContext(node) +INLINE DXGeomNodeContext8:: +DXGeomNodeContext8(GeomNode *node) : GeomNodeContext(node) { _num_verts = 0; /* diff --git a/panda/src/dxgsg8/dxGeomNodeContext8.cxx b/panda/src/dxgsg8/dxGeomNodeContext8.cxx index ccf16586d7..036a06e450 100644 --- a/panda/src/dxgsg8/dxGeomNodeContext8.cxx +++ b/panda/src/dxgsg8/dxGeomNodeContext8.cxx @@ -18,9 +18,9 @@ #include "dxGeomNodeContext8.h" -TypeHandle DXGeomNodeContext::_type_handle; +TypeHandle DXGeomNodeContext8::_type_handle; -DXGeomNodeContext::~DXGeomNodeContext() +DXGeomNodeContext8::~DXGeomNodeContext8() { /* if(_pXformed_VB!=NULL) diff --git a/panda/src/dxgsg8/dxGeomNodeContext8.h b/panda/src/dxgsg8/dxGeomNodeContext8.h index 8a30204793..fef97cf052 100644 --- a/panda/src/dxgsg8/dxGeomNodeContext8.h +++ b/panda/src/dxgsg8/dxGeomNodeContext8.h @@ -1,4 +1,4 @@ -// Filename: dxGeomNodeContext.h +// Filename: dxGeomNodeContext8.h // Created by: drose (12Jun01) // //////////////////////////////////////////////////////////////////// @@ -16,8 +16,8 @@ // //////////////////////////////////////////////////////////////////// -#ifndef DXGEOMNODECONTEXT_H -#define DXGEOMNODECONTEXT_H +#ifndef DXGEOMNODECONTEXT8_H +#define DXGEOMNODECONTEXT8_H #include "dxgsg8base.h" @@ -33,13 +33,13 @@ typedef struct { // empty shell unimplemented for DX8 right now //////////////////////////////////////////////////////////////////// -// Class : DXGeomNodeContext +// Class : DXGeomNodeContext8 // Description : //////////////////////////////////////////////////////////////////// -class EXPCL_PANDADX DXGeomNodeContext : public GeomNodeContext { +class EXPCL_PANDADX DXGeomNodeContext8 : public GeomNodeContext { public: - INLINE DXGeomNodeContext(GeomNode *node); - ~DXGeomNodeContext(); + INLINE DXGeomNodeContext8(GeomNode *node); + ~DXGeomNodeContext8(); // A list of the dynamic Geoms within the GeomNode; these aren't // part of the above display list and must be drawn separately @@ -71,7 +71,7 @@ public: } static void init_type() { GeomNodeContext::init_type(); - register_type(_type_handle, "DXGeomNodeContext", + register_type(_type_handle, "DXGeomNodeContext8", GeomNodeContext::get_class_type()); } virtual TypeHandle get_type() const { diff --git a/panda/src/dxgsg8/dxGraphicsStateGuardian8.I b/panda/src/dxgsg8/dxGraphicsStateGuardian8.I index c8c325628d..a3448cb8a6 100644 --- a/panda/src/dxgsg8/dxGraphicsStateGuardian8.I +++ b/panda/src/dxgsg8/dxGraphicsStateGuardian8.I @@ -1,4 +1,4 @@ -// Filename: dxGraphicsStateGuardian.I +// Filename: dxGraphicsStateGuardian8.I // Created by: mike (02Feb99) // //////////////////////////////////////////////////////////////////// @@ -16,22 +16,22 @@ // //////////////////////////////////////////////////////////////////// -// for dxgsg_cat stuff +// for dxgsg8_cat stuff #include "config_dxgsg8.h" //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::enable_line_smooth +// Function: DXGraphicsStateGuardian8::enable_line_smooth // Access: // Description: //////////////////////////////////////////////////////////////////// -INLINE void DXGraphicsStateGuardian:: +INLINE void DXGraphicsStateGuardian8:: enable_line_smooth(bool val) { if(_line_smooth_enabled != val) { _line_smooth_enabled = val; #ifdef NDEBUG { if(val && (scrn.d3dcaps.RasterCaps & D3DPRASTERCAPS_ANTIALIASEDGES)) - dxgsg_cat.error() << "no HW support for line smoothing!!\n"; + dxgsg8_cat.error() << "no HW support for line smoothing!!\n"; } #endif @@ -40,18 +40,18 @@ enable_line_smooth(bool val) { } //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::enable_dither +// Function: DXGraphicsStateGuardian8::enable_dither // Access: // Description: //////////////////////////////////////////////////////////////////// -INLINE void DXGraphicsStateGuardian:: +INLINE void DXGraphicsStateGuardian8:: enable_dither(bool val) { if (_dither_enabled != val) { #ifdef _DEBUG { if(val && !(scrn.d3dcaps.RasterCaps & D3DPRASTERCAPS_DITHER)) - dxgsg_cat.error() << "no HW support for color dithering!!\n"; + dxgsg8_cat.error() << "no HW support for color dithering!!\n"; return; } #endif @@ -62,11 +62,11 @@ enable_dither(bool val) { } //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::enable_stencil_test +// Function: DXGraphicsStateGuardian8::enable_stencil_test // Access: // Description: //////////////////////////////////////////////////////////////////// -INLINE void DXGraphicsStateGuardian:: +INLINE void DXGraphicsStateGuardian8:: enable_stencil_test(bool val) { if (_stencil_test_enabled != val) { _stencil_test_enabled = val; @@ -75,11 +75,11 @@ enable_stencil_test(bool val) { } //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::enable_color_material +// Function: DXGraphicsStateGuardian8::enable_color_material // Access: // Description: //////////////////////////////////////////////////////////////////// -INLINE void DXGraphicsStateGuardian:: +INLINE void DXGraphicsStateGuardian8:: enable_color_material(bool val) { if (_color_material_enabled != val) { _color_material_enabled = val; @@ -88,11 +88,11 @@ enable_color_material(bool val) { //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::enable_blend +// Function: DXGraphicsStateGuardian8::enable_blend // Access: // Description: //////////////////////////////////////////////////////////////////// -INLINE void DXGraphicsStateGuardian:: +INLINE void DXGraphicsStateGuardian8:: enable_blend(bool val) { if (_blend_enabled != val) { _blend_enabled = val; @@ -101,11 +101,11 @@ enable_blend(bool val) { } //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::set_color_writemask +// Function: DXGraphicsStateGuardian8::set_color_writemask // Access: // Description: //////////////////////////////////////////////////////////////////// -INLINE void DXGraphicsStateGuardian:: +INLINE void DXGraphicsStateGuardian8:: set_color_writemask(UINT color_writemask) { if (_color_writemask != color_writemask) { _color_writemask = color_writemask; @@ -121,11 +121,11 @@ set_color_writemask(UINT color_writemask) { } //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::enable_blend +// Function: DXGraphicsStateGuardian8::enable_blend // Access: // Description: //////////////////////////////////////////////////////////////////// -INLINE void DXGraphicsStateGuardian:: +INLINE void DXGraphicsStateGuardian8:: enable_gouraud_shading(bool val) { if (_bGouraudShadingOn != val) { _bGouraudShadingOn = val; @@ -133,7 +133,7 @@ enable_gouraud_shading(bool val) { } } -INLINE void DXGraphicsStateGuardian:: +INLINE void DXGraphicsStateGuardian8:: enable_primitive_clipping(bool val) { if (_clipping_enabled != val) { _clipping_enabled = val; @@ -142,11 +142,11 @@ enable_primitive_clipping(bool val) { } //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::enable_fog +// Function: DXGraphicsStateGuardian8::enable_fog // Access: // Description: //////////////////////////////////////////////////////////////////// -INLINE void DXGraphicsStateGuardian:: +INLINE void DXGraphicsStateGuardian8:: enable_fog(bool val) { if ((_fog_enabled != val) && (_doFogType!=None)) { _fog_enabled = val; @@ -155,11 +155,11 @@ enable_fog(bool val) { } //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::set_vertex_format +// Function: DXGraphicsStateGuardian8::set_vertex_format // Access: // Description: //////////////////////////////////////////////////////////////////// -INLINE void DXGraphicsStateGuardian:: +INLINE void DXGraphicsStateGuardian8:: set_vertex_format(DWORD NewFvfType) { #ifdef USE_VERTEX_SHADERS if(_CurVertexShader!=NULL) { @@ -167,7 +167,7 @@ set_vertex_format(DWORD NewFvfType) { HRESULT hr = scrn.pD3DDevice->SetVertexShader(_CurVertexShader); #ifndef NDEBUG if(FAILED(hr)) { - dxgsg_cat.error() << "SetVertexShader for custom vtx shader failed" << D3DERRORSTRING(hr); + dxgsg8_cat.error() << "SetVertexShader for custom vtx shader failed" << D3DERRORSTRING(hr); exit(1); } #endif @@ -182,7 +182,7 @@ set_vertex_format(DWORD NewFvfType) { HRESULT hr = scrn.pD3DDevice->SetVertexShader(NewFvfType); #ifndef NDEBUG if(FAILED(hr)) { - dxgsg_cat.error() << "SetVertexShader(0x" << (void*)NewFvfType<<") failed" << D3DERRORSTRING(hr); + dxgsg8_cat.error() << "SetVertexShader(0x" << (void*)NewFvfType<<") failed" << D3DERRORSTRING(hr); exit(1); } #endif @@ -190,11 +190,11 @@ set_vertex_format(DWORD NewFvfType) { } //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::enable_alpha_test +// Function: DXGraphicsStateGuardian8::enable_alpha_test // Access: // Description: //////////////////////////////////////////////////////////////////// -INLINE void DXGraphicsStateGuardian:: +INLINE void DXGraphicsStateGuardian8:: enable_alpha_test(bool val ) { if (_alpha_test_enabled != val) { @@ -204,17 +204,17 @@ enable_alpha_test(bool val ) } //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::call_dxLightModelAmbient +// Function: DXGraphicsStateGuardian8::call_dxLightModelAmbient // Access: // Description: //////////////////////////////////////////////////////////////////// -INLINE void DXGraphicsStateGuardian:: +INLINE void DXGraphicsStateGuardian8:: call_dxLightModelAmbient( const Colorf& color) { if (_lmodel_ambient != color) { _lmodel_ambient = color; #ifdef GSG_VERBOSE - dxgsg_cat.debug() << "dxLightModel(LIGHT_MODEL_AMBIENT, " << color << ")" << endl; + dxgsg8_cat.debug() << "dxLightModel(LIGHT_MODEL_AMBIENT, " << color << ")" << endl; #endif scrn.pD3DDevice->SetRenderState( D3DRS_AMBIENT, D3DCOLOR_COLORVALUE(color[0], color[1], color[2], color[3])); @@ -223,43 +223,47 @@ call_dxLightModelAmbient( const Colorf& color) //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::call_dxAlphaFunc +// Function: DXGraphicsStateGuardian8::call_dxAlphaFunc // Access: // Description: //////////////////////////////////////////////////////////////////// -INLINE void DXGraphicsStateGuardian:: +INLINE void DXGraphicsStateGuardian8:: call_dxAlphaFunc(D3DCMPFUNC func, float reference_alpha) { if (_alpha_func != func) { _alpha_func = func; #ifdef GSG_VERBOSE - dxgsg_cat.debug() << "dxAlphaFunc("; + dxgsg8_cat.debug() << "dxAlphaFunc("; switch (func) { case D3DCMP_NEVER: - dxgsg_cat.debug(false) << "D3DCMP_NEVER"; + dxgsg8_cat.debug(false) << "D3DCMP_NEVER"; break; case D3DCMP_LESS: - dxgsg_cat.debug(false) << "D3DCMP_LESS"; + dxgsg8_cat.debug(false) << "D3DCMP_LESS"; break; case D3DCMP_EQUAL: - dxgsg_cat.debug(false) << "D3DCMP_EQUAL"; + dxgsg8_cat.debug(false) << "D3DCMP_EQUAL"; break; +#ifdef D3DCMP_LEQUAL case D3DCMP_LEQUAL: - dxgsg_cat.debug(false) << "D3DCMP_LEQUAL"; + dxgsg8_cat.debug(false) << "D3DCMP_LEQUAL"; break; +#endif case D3DCMP_GREATER: - dxgsg_cat.debug(false) << "D3DCMP_GREATER"; + dxgsg8_cat.debug(false) << "D3DCMP_GREATER"; break; case D3DCMP_NOTEQUAL: - dxgsg_cat.debug(false) << "D3DCMP_NOTEQUAL"; + dxgsg8_cat.debug(false) << "D3DCMP_NOTEQUAL"; break; +#ifdef D3DCMP_GEQUAL case D3DCMP_GEQUAL: - dxgsg_cat.debug(false) << "D3DCMP_GEQUAL"; + dxgsg8_cat.debug(false) << "D3DCMP_GEQUAL"; break; +#endif case D3DCMP_ALWAYS: - dxgsg_cat.debug(false) << "D3DCMP_ALWAYS"; + dxgsg8_cat.debug(false) << "D3DCMP_ALWAYS"; break; } - dxgsg_cat.debug() << " , " << reference_alpha << ")" << endl; + dxgsg8_cat.debug() << " , " << reference_alpha << ")" << endl; #endif scrn.pD3DDevice->SetRenderState(D3DRS_ALPHAFUNC, func); } @@ -271,7 +275,7 @@ call_dxAlphaFunc(D3DCMPFUNC func, float reference_alpha) { } -INLINE void DXGraphicsStateGuardian:: +INLINE void DXGraphicsStateGuardian8:: call_dxBlendFunc(D3DBLEND sfunc, D3DBLEND dfunc ) { if (_blend_source_func != sfunc) @@ -279,41 +283,41 @@ call_dxBlendFunc(D3DBLEND sfunc, D3DBLEND dfunc ) _blend_source_func = sfunc; scrn.pD3DDevice->SetRenderState(D3DRS_SRCBLEND, sfunc); #ifdef GSG_VERBOSE - dxgsg_cat.debug() << "dxSrcBlendFunc("; + dxgsg8_cat.debug() << "dxSrcBlendFunc("; switch (sfunc) { case D3DBLEND_ZERO: - dxgsg_cat.debug(false) << "ZERO, "; + dxgsg8_cat.debug(false) << "ZERO, "; break; case D3DBLEND_ONE: - dxgsg_cat.debug(false) << "ONE, "; + dxgsg8_cat.debug(false) << "ONE, "; break; case D3DBLEND_DESTCOLOR: - dxgsg_cat.debug(false) << "DESTCOLOR, "; + dxgsg8_cat.debug(false) << "DESTCOLOR, "; break; case D3DBLEND_INVDESTCOLOR: - dxgsg_cat.debug(false) << "INVDESTCOLOR, "; + dxgsg8_cat.debug(false) << "INVDESTCOLOR, "; break; case D3DBLEND_SRCALPHA: - dxgsg_cat.debug(false) << "SRCALPHA, "; + dxgsg8_cat.debug(false) << "SRCALPHA, "; break; case D3DBLEND_INVSRCALPHA: - dxgsg_cat.debug(false) << "INVSRCALPHA, "; + dxgsg8_cat.debug(false) << "INVSRCALPHA, "; break; case D3DBLEND_DESTALPHA: - dxgsg_cat.debug(false) << "DESTALPHA, "; + dxgsg8_cat.debug(false) << "DESTALPHA, "; break; case D3DBLEND_INVDESTALPHA: - dxgsg_cat.debug(false) << "INVDESTALPHA, "; + dxgsg8_cat.debug(false) << "INVDESTALPHA, "; break; case D3DBLEND_SRCALPHASAT: - dxgsg_cat.debug(false) << "SRCALPHASAT, "; + dxgsg8_cat.debug(false) << "SRCALPHASAT, "; break; default: - dxgsg_cat.debug(false) << "unknown, "; + dxgsg8_cat.debug(false) << "unknown, "; break; } - dxgsg_cat.debug(false) << endl; + dxgsg8_cat.debug(false) << endl; #endif } if ( _blend_dest_func != dfunc) @@ -321,43 +325,43 @@ call_dxBlendFunc(D3DBLEND sfunc, D3DBLEND dfunc ) _blend_dest_func = dfunc; scrn.pD3DDevice->SetRenderState(D3DRS_DESTBLEND, dfunc); #ifdef GSG_VERBOSE - dxgsg_cat.debug() << "dxDstBlendFunc("; + dxgsg8_cat.debug() << "dxDstBlendFunc("; switch (dfunc) { case D3DBLEND_ZERO: - dxgsg_cat.debug(false) << "ZERO, "; + dxgsg8_cat.debug(false) << "ZERO, "; break; case D3DBLEND_ONE: - dxgsg_cat.debug(false) << "ONE, "; + dxgsg8_cat.debug(false) << "ONE, "; break; case D3DBLEND_DESTCOLOR: - dxgsg_cat.debug(false) << "DESTCOLOR, "; + dxgsg8_cat.debug(false) << "DESTCOLOR, "; break; case D3DBLEND_INVDESTCOLOR: - dxgsg_cat.debug(false) << "INVDESTCOLOR, "; + dxgsg8_cat.debug(false) << "INVDESTCOLOR, "; break; case D3DBLEND_SRCALPHA: - dxgsg_cat.debug(false) << "SRCALPHA, "; + dxgsg8_cat.debug(false) << "SRCALPHA, "; break; case D3DBLEND_INVSRCALPHA: - dxgsg_cat.debug(false) << "INVSRCALPHA, "; + dxgsg8_cat.debug(false) << "INVSRCALPHA, "; break; case D3DBLEND_DESTALPHA: - dxgsg_cat.debug(false) << "DESTALPHA, "; + dxgsg8_cat.debug(false) << "DESTALPHA, "; break; case D3DBLEND_INVDESTALPHA: - dxgsg_cat.debug(false) << "INVDESTALPHA, "; + dxgsg8_cat.debug(false) << "INVDESTALPHA, "; break; case D3DBLEND_SRCALPHASAT: - dxgsg_cat.debug(false) << "SRCALPHASAT, "; + dxgsg8_cat.debug(false) << "SRCALPHASAT, "; break; } - dxgsg_cat.debug(false) << endl; + dxgsg8_cat.debug(false) << endl; #endif } } -INLINE void DXGraphicsStateGuardian:: +INLINE void DXGraphicsStateGuardian8:: enable_zwritemask(bool val) { if (_depth_write_enabled != val) { _depth_write_enabled = val; @@ -368,24 +372,24 @@ enable_zwritemask(bool val) { /** unimplemented //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::enable_multisample +// Function: DXGraphicsStateGuardian8::enable_multisample // Access: // Description: //////////////////////////////////////////////////////////////////// -INLINE void DXGraphicsStateGuardian:: +INLINE void DXGraphicsStateGuardian8:: enable_multisample(bool val) { _multisample_enabled = val; #ifdef NDEBUG - dxgsg_cat.error() << "dx multisample unimplemented!!\n"; + dxgsg8_cat.error() << "dx multisample unimplemented!!\n"; #endif } //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::enable_multisample_alpha_one +// Function: DXGraphicsStateGuardian8::enable_multisample_alpha_one // Access: // Description: //////////////////////////////////////////////////////////////////// -INLINE void DXGraphicsStateGuardian:: +INLINE void DXGraphicsStateGuardian8:: enable_multisample_alpha_one(bool val) { if (_multisample_alpha_one_enabled != val) { _multisample_alpha_one_enabled = val; @@ -393,11 +397,11 @@ enable_multisample_alpha_one(bool val) { } //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::enable_multisample_alpha_mask +// Function: DXGraphicsStateGuardian8::enable_multisample_alpha_mask // Access: // Description: //////////////////////////////////////////////////////////////////// -INLINE void DXGraphicsStateGuardian:: +INLINE void DXGraphicsStateGuardian8:: enable_multisample_alpha_mask(bool val) { if (_multisample_alpha_mask_enabled != val) { _multisample_alpha_mask_enabled = val; @@ -405,16 +409,16 @@ enable_multisample_alpha_mask(bool val) { } //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::enable_point_smooth +// Function: DXGraphicsStateGuardian8::enable_point_smooth // Access: // Description: //////////////////////////////////////////////////////////////////// -INLINE void DXGraphicsStateGuardian:: +INLINE void DXGraphicsStateGuardian8:: enable_point_smooth(bool val) { // _point_smooth_enabled = val; #ifdef NDEBUG - dxgsg_cat.error() << "dx point smoothing unimplemented!!\n"; + dxgsg8_cat.error() << "dx point smoothing unimplemented!!\n"; #endif } */ diff --git a/panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx b/panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx index af40579f38..148cd53d99 100644 --- a/panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx +++ b/panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx @@ -77,7 +77,7 @@ const int VERT_BUFFER_SIZE = (32*6*1024L); // note multiple region code doesnt work now (see prepare_display_region,set_clipper) #define NO_MULTIPLE_DISPLAY_REGIONS -TypeHandle DXGraphicsStateGuardian::_type_handle; +TypeHandle DXGraphicsStateGuardian8::_type_handle; // bit masks used for drawing primitives // bitmask type: normal=0x1,color=0x2,texcoord=0x4 @@ -176,7 +176,7 @@ Colorf_to_D3DCOLOR(const Colorf &cColorf) { pop ebx } - // dxgsg_cat.debug() << (void*)d3dcolor << endl; + // dxgsg8_cat.debug() << (void*)d3dcolor << endl; return d3dcolor; #else //!_X86_ return MY_D3DRGBA(cColorf[0], cColorf[1], cColorf[2], cColorf[3]); @@ -225,13 +225,13 @@ void make_D3DFORMAT_map(void) { INSERT_ELEM(DXT5); } -void DXGraphicsStateGuardian:: +void DXGraphicsStateGuardian8:: set_color_clear_value(const Colorf& value) { _color_clear_value = value; _d3dcolor_clear_value = Colorf_to_D3DCOLOR(value); } -DXShaderHandle DXGraphicsStateGuardian:: +DXShaderHandle DXGraphicsStateGuardian8:: read_pixel_shader(string &filename) { HRESULT hr; DXShaderHandle hShader=NULL; @@ -246,7 +246,7 @@ read_pixel_shader(string &filename) { if(bIsCompiledShader) { hFile = CreateFile(filename.c_str(), GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL); if(hFile == INVALID_HANDLE_VALUE) { - dxgsg_cat.error() << "Could not find shader file '"<< filename << "'\n"; + dxgsg8_cat.error() << "Could not find shader file '"<< filename << "'\n"; return NULL; } @@ -254,7 +254,7 @@ read_pixel_shader(string &filename) { pShaderBytes = new BYTE[FileSize]; if (pShaderBytes==NULL) { - dxgsg_cat.error() << "MemAlloc failed for shader file '"<< filename << "'\n"; + dxgsg8_cat.error() << "MemAlloc failed for shader file '"<< filename << "'\n"; goto exit_create_pshader; } @@ -263,23 +263,23 @@ read_pixel_shader(string &filename) { } else { #if defined(NDEBUG) && !defined(COMPILE_TEXT_SHADERFILES) // want to keep bulky d3dx shader assembler stuff out of publish build - dxgsg_cat.error() << "publish build only reads .vso compiled shaders!\n"; + dxgsg8_cat.error() << "publish build only reads .vso compiled shaders!\n"; exit(1); #else // check for file existence WIN32_FIND_DATA Junk; HANDLE FindFileHandle = FindFirstFile(filename.c_str(),&Junk); if ( FindFileHandle == INVALID_HANDLE_VALUE ) { - dxgsg_cat.error() << "Could not find shader file '"<< filename << "'\n"; + dxgsg8_cat.error() << "Could not find shader file '"<< filename << "'\n"; return NULL; } FindClose(FindFileHandle); hr = D3DXAssembleShaderFromFile(filename.c_str(),D3DXASM_DEBUG,NULL,&pD3DXBuf_CompiledShader,&pD3DXBuf_CompilationErrors); if(FAILED(hr)) { - dxgsg_cat.error() << "D3DXAssembleShader failed for '"<< filename << "' " << D3DERRORSTRING(hr); + dxgsg8_cat.error() << "D3DXAssembleShader failed for '"<< filename << "' " << D3DERRORSTRING(hr); if(pD3DXBuf_CompilationErrors!=NULL) { - dxgsg_cat.error() << "Compilation Errors: " << (char*) pD3DXBuf_CompilationErrors->GetBufferPointer() << endl; + dxgsg8_cat.error() << "Compilation Errors: " << (char*) pD3DXBuf_CompilationErrors->GetBufferPointer() << endl; } exit(1); } @@ -290,14 +290,14 @@ read_pixel_shader(string &filename) { hr = scrn.pD3DDevice->CreatePixelShader((DWORD*) ((pD3DXBuf_CompiledShader!=NULL) ? pD3DXBuf_CompiledShader->GetBufferPointer() : pShaderBytes), &hShader); if (FAILED(hr)) { - dxgsg_cat.error() << "CreatePixelShader failed for '"<< filename << "' " << D3DERRORSTRING(hr); + dxgsg8_cat.error() << "CreatePixelShader failed for '"<< filename << "' " << D3DERRORSTRING(hr); hShader=NULL; } assert(hShader!=NULL); // NULL is invalid I hope #ifdef _DEBUG - dxgsg_cat.debug() << "CreatePixelShader succeeded for "<< filename << endl; + dxgsg8_cat.debug() << "CreatePixelShader succeeded for "<< filename << endl; #endif exit_create_pshader: @@ -309,7 +309,7 @@ read_pixel_shader(string &filename) { } -DXShaderHandle DXGraphicsStateGuardian:: +DXShaderHandle DXGraphicsStateGuardian8:: read_vertex_shader(string &filename) { #ifndef USE_VERTEX_SHADERS return NULL; @@ -342,7 +342,7 @@ read_vertex_shader(string &filename) { if(bIsCompiledShader) { hFile = CreateFile(filename.c_str(), GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL); if(hFile == INVALID_HANDLE_VALUE) { - dxgsg_cat.error() << "Could not find shader file '"<< filename << "'\n"; + dxgsg8_cat.error() << "Could not find shader file '"<< filename << "'\n"; return NULL; } @@ -350,7 +350,7 @@ read_vertex_shader(string &filename) { pShaderBytes = new BYTE[FileSize]; if (pShaderBytes==NULL) { - dxgsg_cat.error() << "MemAlloc failed for shader file '"<< filename << "'\n"; + dxgsg8_cat.error() << "MemAlloc failed for shader file '"<< filename << "'\n"; goto exit_create_vshader; } @@ -359,23 +359,23 @@ read_vertex_shader(string &filename) { } else { #if defined(NDEBUG) && !defined(COMPILE_TEXT_SHADERFILES) // want to keep bulky d3dx shader assembler stuff out of publish build - dxgsg_cat.error() << "publish build only reads .vso compiled shaders!\n"; + dxgsg8_cat.error() << "publish build only reads .vso compiled shaders!\n"; exit(1); #else // check for file existence WIN32_FIND_DATA Junk; HANDLE FindFileHandle = FindFirstFile(filename.c_str(),&Junk); if ( FindFileHandle == INVALID_HANDLE_VALUE ) { - dxgsg_cat.error() << "Could not find shader file '"<< filename << "'\n"; + dxgsg8_cat.error() << "Could not find shader file '"<< filename << "'\n"; return NULL; } FindClose(FindFileHandle); hr = D3DXAssembleShaderFromFile(filename.c_str(),D3DXASM_DEBUG,&pD3DXBuf_Constants,&pD3DXBuf_CompiledShader,&pD3DXBuf_CompilationErrors); if(FAILED(hr)) { - dxgsg_cat.error() << "D3DXAssembleShader failed for '"<< filename << "' " << D3DERRORSTRING(hr); + dxgsg8_cat.error() << "D3DXAssembleShader failed for '"<< filename << "' " << D3DERRORSTRING(hr); if(pD3DXBuf_CompilationErrors!=NULL) { - dxgsg_cat.error() << "Compilation Errors: " << (char*) pD3DXBuf_CompilationErrors->GetBufferPointer() << endl; + dxgsg8_cat.error() << "Compilation Errors: " << (char*) pD3DXBuf_CompilationErrors->GetBufferPointer() << endl; } exit(1); } @@ -398,14 +398,14 @@ read_vertex_shader(string &filename) { (DWORD*) ((pD3DXBuf_CompiledShader!=NULL) ? pD3DXBuf_CompiledShader->GetBufferPointer() : pShaderBytes), &hShader, UsageFlags); if(FAILED(hr)) { - dxgsg_cat.error() << "CreateVertexShader failed for '"<< filename << "' " << D3DERRORSTRING(hr); + dxgsg8_cat.error() << "CreateVertexShader failed for '"<< filename << "' " << D3DERRORSTRING(hr); hShader=NULL; } assert(hShader!=NULL); // NULL is invalid I hope #ifdef _DEBUG - dxgsg_cat.debug() << "CreateVertexShader succeeded for "<< filename << endl; + dxgsg8_cat.debug() << "CreateVertexShader succeeded for "<< filename << endl; #endif exit_create_vshader: @@ -417,7 +417,7 @@ read_vertex_shader(string &filename) { #endif } -void DXGraphicsStateGuardian:: +void DXGraphicsStateGuardian8:: reset_panda_gsg(void) { GraphicsStateGuardian::reset(); @@ -437,12 +437,12 @@ reset_panda_gsg(void) { } //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::Constructor +// Function: DXGraphicsStateGuardian8::Constructor // Access: Public // Description: //////////////////////////////////////////////////////////////////// -DXGraphicsStateGuardian:: -DXGraphicsStateGuardian(GraphicsWindow *win) : GraphicsStateGuardian(win) { +DXGraphicsStateGuardian8:: +DXGraphicsStateGuardian8(GraphicsWindow *win) : GraphicsStateGuardian(win) { reset_panda_gsg(); // allocate local buffers used during rendering @@ -454,9 +454,6 @@ DXGraphicsStateGuardian(GraphicsWindow *win) : GraphicsStateGuardian(win) { _pFvfBufBasePtr = NULL; _index_buf=NULL; - _pStatMeterFont=NULL; - _bShowFPSMeter = false; - // may persist across dx_init's? (for dx8.1 but not dx8.0?) _CurVertexShader = _CurPixelShader = NULL; _pGlobalTexture = NULL; @@ -477,12 +474,12 @@ DXGraphicsStateGuardian(GraphicsWindow *win) : GraphicsStateGuardian(win) { } //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::Destructor +// Function: DXGraphicsStateGuardian8::Destructor // Access: Public // Description: //////////////////////////////////////////////////////////////////// -DXGraphicsStateGuardian:: -~DXGraphicsStateGuardian() { +DXGraphicsStateGuardian8:: +~DXGraphicsStateGuardian8() { if (scrn.pD3DDevice != NULL) scrn.pD3DDevice->SetTexture(0, NULL); // this frees reference to the old texture _pCurTexContext = NULL; @@ -491,15 +488,15 @@ DXGraphicsStateGuardian:: } //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::reset +// Function: DXGraphicsStateGuardian8::reset // Access: Public, Virtual // Description: Resets all internal state as if the gsg were newly // created. //////////////////////////////////////////////////////////////////// -void DXGraphicsStateGuardian:: +void DXGraphicsStateGuardian8:: reset(void) { reset_panda_gsg(); - dxgsg_cat.error() << "DXGSG reset() not implemented properly yet!\n"; + dxgsg8_cat.error() << "DXGSG reset() not implemented properly yet!\n"; // what else do we need to do? // delete all the objs too, right? // need to do a @@ -507,7 +504,7 @@ reset(void) { } // setup up for re-calling dx_init(), this is not the final exit cleanup routine (see dx_cleanup) -void DXGraphicsStateGuardian:: +void DXGraphicsStateGuardian8:: free_d3d_device(void) { // dont want a full reset of gsg, just a state clear set_state(RenderState::make_empty()); @@ -522,7 +519,7 @@ free_d3d_device(void) { DeleteAllDeviceObjects(); if (scrn.pD3DDevice!=NULL) - RELEASE(scrn.pD3DDevice,dxgsg,"d3dDevice",RELEASE_DOWN_TO_ZERO); + RELEASE(scrn.pD3DDevice,dxgsg8,"d3dDevice",RELEASE_DOWN_TO_ZERO); free_nondx_resources(); @@ -530,12 +527,12 @@ free_d3d_device(void) { } //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::free_nondx_resources +// Function: DXGraphicsStateGuardian8::free_nondx_resources // Access: Public // Description: Frees some memory that was explicitly allocated // within the dxgsg. //////////////////////////////////////////////////////////////////// -void DXGraphicsStateGuardian:: +void DXGraphicsStateGuardian8:: free_nondx_resources() { // this must not release any objects associated with D3D/DX! // those should be released in free_dxgsg_objects instead @@ -544,12 +541,12 @@ free_nondx_resources() { } //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::reset +// Function: DXGraphicsStateGuardian8::reset // Access: Public, Virtual // Description: Handles initialization which assumes that DX has already been // set up. //////////////////////////////////////////////////////////////////// -void DXGraphicsStateGuardian:: +void DXGraphicsStateGuardian8:: dx_init(HCURSOR hMouseCursor) { HRESULT hr; @@ -656,35 +653,35 @@ dx_init(HCURSOR hMouseCursor) { if ((dx_decal_type==GDT_offset) && !(scrn.d3dcaps.RasterCaps & D3DPRASTERCAPS_ZBIAS)) { if(scrn.d3dcaps.PrimitiveMiscCaps & D3DPMISCCAPS_COLORWRITEENABLE) { - if(dxgsg_cat.is_debug()) - dxgsg_cat.debug() << "dx-decal-type 'offset' not supported by hardware, switching to mask-type decals\n"; + if(dxgsg8_cat.is_debug()) + dxgsg8_cat.debug() << "dx-decal-type 'offset' not supported by hardware, switching to mask-type decals\n"; dx_decal_type = GDT_mask; } else { - if(dxgsg_cat.is_debug()) - dxgsg_cat.debug() << "dx-decal-type 'offset' and color-writemasking not supported by hardware, switching to decal double-draw blend-based masking\n"; + if(dxgsg8_cat.is_debug()) + dxgsg8_cat.debug() << "dx-decal-type 'offset' and color-writemasking not supported by hardware, switching to decal double-draw blend-based masking\n"; dx_decal_type = GDT_blend; } } #ifdef DISABLE_POLYGON_OFFSET_DECALING if(dx_decal_type==GDT_offset) { - if(dxgsg_cat.is_spam()) - dxgsg_cat.spam() << "polygon-offset decaling disabled in dxgsg, switching to double-draw decaling\n"; + if(dxgsg8_cat.is_spam()) + dxgsg8_cat.spam() << "polygon-offset decaling disabled in dxgsg, switching to double-draw decaling\n"; if(scrn.d3dcaps.PrimitiveMiscCaps & D3DPMISCCAPS_COLORWRITEENABLE) { - if(dxgsg_cat.is_debug()) - dxgsg_cat.debug() << "using dx-decal-type 'GDT_mask'\n"; + if(dxgsg8_cat.is_debug()) + dxgsg8_cat.debug() << "using dx-decal-type 'GDT_mask'\n"; dx_decal_type = GDT_mask; } else { - if(dxgsg_cat.is_debug()) - dxgsg_cat.debug() << "dx-decal-type 'mask' not supported by hardware, switching to GDT_blend\n"; + if(dxgsg8_cat.is_debug()) + dxgsg8_cat.debug() << "dx-decal-type 'mask' not supported by hardware, switching to GDT_blend\n"; dx_decal_type = GDT_blend; } } #endif if (((dx_decal_type==GDT_blend)||(dx_decal_type==GDT_mask)) && !(scrn.d3dcaps.PrimitiveMiscCaps & D3DPMISCCAPS_MASKZ)) { - dxgsg_cat.error() << "dx-decal-types mask&blend impossible to implement, no hardware support for Z-masking, decals will not appear correctly!\n"; + dxgsg8_cat.error() << "dx-decal-types mask&blend impossible to implement, no hardware support for Z-masking, decals will not appear correctly!\n"; } #define REQUIRED_DESTBLENDCAPS (D3DPBLENDCAPS_ZERO|D3DPBLENDCAPS_ONE| D3DPBLENDCAPS_SRCALPHA) @@ -692,26 +689,26 @@ dx_init(HCURSOR hMouseCursor) { if (((scrn.d3dcaps.SrcBlendCaps & REQUIRED_SRCBLENDCAPS)!=REQUIRED_SRCBLENDCAPS) || ((scrn.d3dcaps.DestBlendCaps & REQUIRED_DESTBLENDCAPS)!=REQUIRED_DESTBLENDCAPS)) { - dxgsg_cat.error() << "device is missing alpha blending capabilities, blending may not work correctly: SrcBlendCaps: 0x"<< (void*) scrn.d3dcaps.SrcBlendCaps << " DestBlendCaps: "<< (void*) scrn.d3dcaps.DestBlendCaps << endl; + dxgsg8_cat.error() << "device is missing alpha blending capabilities, blending may not work correctly: SrcBlendCaps: 0x"<< (void*) scrn.d3dcaps.SrcBlendCaps << " DestBlendCaps: "<< (void*) scrn.d3dcaps.DestBlendCaps << endl; } // just 'require' bilinear with mip nearest. #define REQUIRED_TEXFILTERCAPS (D3DPTFILTERCAPS_MAGFLINEAR | D3DPTFILTERCAPS_MIPFPOINT | D3DPTFILTERCAPS_MINFLINEAR) if ((scrn.d3dcaps.TextureFilterCaps & REQUIRED_TEXFILTERCAPS)!=REQUIRED_TEXFILTERCAPS) { - dxgsg_cat.error() << "device is missing texture bilinear filtering capability, textures may appear blocky! TextureFilterCaps: 0x"<< (void*) scrn.d3dcaps.TextureFilterCaps << endl; + dxgsg8_cat.error() << "device is missing texture bilinear filtering capability, textures may appear blocky! TextureFilterCaps: 0x"<< (void*) scrn.d3dcaps.TextureFilterCaps << endl; } #define TRILINEAR_MIPMAP_TEXFILTERCAPS (D3DPTFILTERCAPS_MIPFLINEAR | D3DPTFILTERCAPS_MINFLINEAR) // give a warning if we dont at least have bilinear + nearest mip filtering if (!(scrn.d3dcaps.TextureCaps & D3DPTEXTURECAPS_MIPMAP)) { - if(dxgsg_cat.is_debug()) - dxgsg_cat.debug() << "device does not have mipmap texturing filtering capability! TextureFilterCaps: 0x"<< (void*) scrn.d3dcaps.TextureFilterCaps << endl; + if(dxgsg8_cat.is_debug()) + dxgsg8_cat.debug() << "device does not have mipmap texturing filtering capability! TextureFilterCaps: 0x"<< (void*) scrn.d3dcaps.TextureFilterCaps << endl; dx_ignore_mipmaps = TRUE; } else if ((scrn.d3dcaps.TextureFilterCaps & TRILINEAR_MIPMAP_TEXFILTERCAPS)!=TRILINEAR_MIPMAP_TEXFILTERCAPS) { - if(dxgsg_cat.is_debug()) - dxgsg_cat.debug() << "device is missing tri-linear mipmap filtering capability, textures may look crappy\n"; + if(dxgsg8_cat.is_debug()) + dxgsg8_cat.debug() << "device is missing tri-linear mipmap filtering capability, textures may look crappy\n"; } else if(scrn.d3dcaps.DevCaps & D3DDEVCAPS_SEPARATETEXTUREMEMORIES) { // this cap is pretty much voodoo2-specific // turn off trilinear filtering on voodoo2 since it doubles the reqd texture memory, degrade to mip point filtering @@ -720,7 +717,7 @@ dx_init(HCURSOR hMouseCursor) { #define REQUIRED_TEXBLENDCAPS (D3DTEXOPCAPS_MODULATE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_SELECTARG2) if ((scrn.d3dcaps.TextureOpCaps & REQUIRED_TEXBLENDCAPS)!=REQUIRED_TEXBLENDCAPS) { - dxgsg_cat.error() << "device is missing some required texture blending capabilities, texture blending may not work properly! TextureOpCaps: 0x"<< (void*) scrn.d3dcaps.TextureOpCaps << endl; + dxgsg8_cat.error() << "device is missing some required texture blending capabilities, texture blending may not work properly! TextureOpCaps: 0x"<< (void*) scrn.d3dcaps.TextureOpCaps << endl; } if(scrn.d3dcaps.RasterCaps & D3DPRASTERCAPS_FOGTABLE) { @@ -825,8 +822,8 @@ dx_init(HCURSOR hMouseCursor) { scrn.pD3DDevice->SetRenderState(D3DRS_CULLMODE, dx_force_backface_culling); } else { dx_force_backface_culling=0; - if(dxgsg_cat.is_debug()) - dxgsg_cat.debug() << "error, invalid value for dx-force-backface-culling\n"; + if(dxgsg8_cat.is_debug()) + dxgsg8_cat.debug() << "error, invalid value for dx-force-backface-culling\n"; } } scrn.pD3DDevice->SetRenderState(D3DRS_CULLMODE, dx_force_backface_culling); @@ -845,65 +842,10 @@ dx_init(HCURSOR hMouseCursor) { // must check (scrn.d3dcaps.PrimitiveMiscCaps & D3DPMISCCAPS_BLENDOP) (yes on GF2/Radeon8500, no on TNT) scrn.pD3DDevice->SetRenderState(D3DRS_BLENDOP,D3DBLENDOP_ADD); - if((scrn.pProps->_fullscreen) && dx_use_dx_cursor) { + if((_win->is_fullscreen()) && dx_use_dx_cursor) { hr = CreateDX8Cursor(scrn.pD3DDevice,hMouseCursor,dx_show_cursor_watermark); if(FAILED(hr)) - dxgsg_cat.error() << "CreateDX8Cursor failed!\n"; - } - - // need to release this better, so dx_init can be called multiple times - if(_bShowFPSMeter) { - // statmeter uses d3dpool default, so it must be destroyed and recreated every time - assert(_pStatMeterFont == NULL); - hr=S_OK; - SIZE TextRectSize; - - PRINT_REFCNT(dxgsg,scrn.pD3DDevice); - _pStatMeterFont = new CD3DFont(_T("Arial"),12,D3DFONT_BOLD); - PRINT_REFCNT(dxgsg,scrn.pD3DDevice); - if(IS_VALID_PTR(_pStatMeterFont)) - hr=_pStatMeterFont->InitDeviceObjects(scrn.pD3DDevice); - - PRINT_REFCNT(dxgsg,scrn.pD3DDevice); - - if(IS_VALID_PTR(_pStatMeterFont) && SUCCEEDED(hr)) { - // instead of computing offset every frame (could change based on font chars, - // do it once here. if we wanted top left corner instead of top right, - // could get rid of this alignment stuff - - UINT xsize = scrn.pProps->_xsize; - UINT ysize = scrn.pProps->_ysize; - - #define FPS_MSG_FORMAT_STR " %dx%dx%d\n%6.02f fps" - - char fps_msg[50]; - sprintf(fps_msg,FPS_MSG_FORMAT_STR,xsize,ysize,32,800.00f); // 6 == NUM_FPSMETER_LETTERS - - hr = _pStatMeterFont->GetTextExtent(fps_msg,&TextRectSize); - - PRINT_REFCNT(dxgsg,scrn.pD3DDevice); - if(SUCCEEDED(hr)) { - UINT xsize = scrn.pProps->_xsize; - - _fpsmeter_x_offset=xsize-TextRectSize.cx-20; - _fpsmeter_y_offset=20; - - // make sure its onscreen for any wnd size - if((_fpsmeter_x_offset<0.0f) || (_fpsmeter_x_offset+TextRectSize.cx)>=scrn.pProps->_xsize) - _fpsmeter_x_offset=0.0f; - - if((_fpsmeter_y_offset<0.0f) || (_fpsmeter_y_offset+TextRectSize.cy)>=scrn.pProps->_ysize) - _fpsmeter_y_offset=0.0f; - } - } - - if(FAILED(hr)) { - _bShowFPSMeter=false; - } - - _start_time = timeGetTime(); - _current_fps = 0.0f; - _start_frame_count = _cur_frame_count = 0; + dxgsg8_cat.error() << "CreateDX8Cursor failed!\n"; } PRINT_REFCNT(dxgsg,scrn.pD3DDevice); @@ -924,13 +866,13 @@ dx_init(HCURSOR hMouseCursor) { // bypasses panda tex mechanism hr = D3DXCreateTextureFromFile(scrn.pD3DDevice,pdx_globaltexture_filename->c_str(),&_pGlobalTexture); if(FAILED(hr)) { - dxgsg_cat.fatal() << "CreateTexFromFile failed" << D3DERRORSTRING(hr); + dxgsg8_cat.fatal() << "CreateTexFromFile failed" << D3DERRORSTRING(hr); exit(1); } hr=scrn.pD3DDevice->SetTexture(dx_globaltexture_stagenum,_pGlobalTexture); if(FAILED(hr)) { - dxgsg_cat.fatal() << "SetTexture failed" << D3DERRORSTRING(hr); + dxgsg8_cat.fatal() << "SetTexture failed" << D3DERRORSTRING(hr); exit(1); } } @@ -938,7 +880,7 @@ dx_init(HCURSOR hMouseCursor) { PRINT_REFCNT(dxgsg,scrn.pD3DDevice); } -void DXGraphicsStateGuardian:: +void DXGraphicsStateGuardian8:: init_shader(ShaderType stype,DXShaderHandle &hShader,string *pFname) { if((pFname==NULL) || pFname->empty()) { @@ -954,7 +896,7 @@ init_shader(ShaderType stype,DXShaderHandle &hShader,string *pFname) { else sh_typename="Pixel"; if((stype==PixelShader) && (!scrn.bCanUsePixelShaders)) { - dxgsg_cat.error() << "HW doesnt support pixel shaders!\n"; + dxgsg8_cat.error() << "HW doesnt support pixel shaders!\n"; exit(1); } @@ -964,7 +906,7 @@ init_shader(ShaderType stype,DXShaderHandle &hShader,string *pFname) { hr = scrn.pD3DDevice->DeleteVertexShader(hShader); else hr = scrn.pD3DDevice->DeletePixelShader(hShader); if(FAILED(hr)) - dxgsg_cat.error() << "Delete"<< sh_typename<<"Shader failed!" << D3DERRORSTRING(hr); + dxgsg8_cat.error() << "Delete"<< sh_typename<<"Shader failed!" << D3DERRORSTRING(hr); hShader=NULL; } @@ -981,12 +923,12 @@ init_shader(ShaderType stype,DXShaderHandle &hShader,string *pFname) { } if(FAILED(hr)) - dxgsg_cat.error() << "Set"<_clear_pcollector)); + // DO_PSTATS_STUFF(PStatTimer timer(_win->_clear_pcollector)); nassertv(buffer._gsg == this); int buffer_type = buffer._buffer_type; @@ -1063,7 +1005,7 @@ do_clear(const RenderBuffer &buffer) { HRESULT hr = scrn.pD3DDevice->Clear(0, NULL, flags, _d3dcolor_clear_value, _depth_clear_value, (DWORD)_stencil_clear_value); if(FAILED(hr)) - dxgsg_cat.error() << "clear_buffer failed: Clear returned " << D3DERRORSTRING(hr); + dxgsg8_cat.error() << "clear_buffer failed: Clear returned " << D3DERRORSTRING(hr); /* The following line will cause the background to always clear to a medium red _color_clear_value[0] = .5; /* The following lines will cause the background color to cycle from black to red. @@ -1073,36 +1015,36 @@ do_clear(const RenderBuffer &buffer) { } //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::prepare_display_region +// Function: DXGraphicsStateGuardian8::prepare_display_region // Access: Public, Virtual // Description: Prepare a display region for rendering (set up // scissor region and viewport) //////////////////////////////////////////////////////////////////// -void DXGraphicsStateGuardian:: +void DXGraphicsStateGuardian8:: prepare_display_region() { - if (_current_display_region == (DisplayRegion*)0L) { - dxgsg_cat.error() - << "Invalid NULL display region in prepare_display_region()\n"; - } else if (_current_display_region != _actual_display_region) { - _actual_display_region = _current_display_region; - - int l, b, w, h; - _actual_display_region->get_region_pixels(l, b, w, h); - - // Create the viewport - D3DVIEWPORT8 vp = {l,b,w,h,0.0f,1.0f}; - HRESULT hr = scrn.pD3DDevice->SetViewport( &vp ); - if(FAILED(hr)) { - dxgsg_cat.fatal() << "SetViewport failed for device #" << scrn.CardIDNum << D3DERRORSTRING(hr); - exit(1); - } - - // Note: for DX9, also change scissor clipping state here + if (_current_display_region == (DisplayRegion*)0L) { + dxgsg8_cat.error() + << "Invalid NULL display region in prepare_display_region()\n"; + } else if (_current_display_region != _actual_display_region) { + _actual_display_region = _current_display_region; + + int l, b, w, h; + _actual_display_region->get_region_pixels(l, b, w, h); + + // Create the viewport + D3DVIEWPORT8 vp = {l,b,w,h,0.0f,1.0f}; + HRESULT hr = scrn.pD3DDevice->SetViewport( &vp ); + if (FAILED(hr)) { + dxgsg8_cat.error() + << "SetViewport(" << l << ", " << b << ", " << w << ", " << h + << ") failed" << D3DERRORSTRING(hr); } + // Note: for DX9, also change scissor clipping state here + } } //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::prepare_lens +// Function: DXGraphicsStateGuardian8::prepare_lens // Access: Public, Virtual // Description: Makes the current lens (whichever lens was most // recently specified with push_lens()) active, so that @@ -1114,7 +1056,7 @@ prepare_display_region() { // The return value is true if the lens is acceptable, // false if it is not. //////////////////////////////////////////////////////////////////// -bool DXGraphicsStateGuardian:: +bool DXGraphicsStateGuardian8:: prepare_lens() { if (_current_lens == (Lens *)NULL) { return false; @@ -1144,7 +1086,7 @@ prepare_lens() { // Access: // Description: Useless in DX at the present time //////////////////////////////////////////////////////////////////// -void DXGraphicsStateGuardian::set_clipper(RECT cliprect) { +void DXGraphicsStateGuardian8::set_clipper(RECT cliprect) { LPDIRECTDRAWCLIPPER Clipper; HRESULT result; @@ -1195,7 +1137,7 @@ void INLINE TestDrawPrimFailure(DP_Type dptype,HRESULT hr,IDirect3DDevice8 *pD3D // loss of exclusive mode is not a real DrawPrim problem, ignore it HRESULT testcooplvl_hr = pD3DDevice->TestCooperativeLevel(); if((testcooplvl_hr != D3DERR_DEVICELOST)||(testcooplvl_hr != D3DERR_DEVICENOTRESET)) { - dxgsg_cat.fatal() << DP_Type_Strs[dptype] << "() failed: result = " << D3DERRORSTRING(hr); + dxgsg8_cat.fatal() << DP_Type_Strs[dptype] << "() failed: result = " << D3DERRORSTRING(hr); exit(1); } } @@ -1207,11 +1149,11 @@ void INLINE TestDrawPrimFailure(DP_Type dptype,HRESULT hr,IDirect3DDevice8 *pD3D #endif //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::report_texmgr_stats +// Function: DXGraphicsStateGuardian8::report_texmgr_stats // Access: Protected // Description: Reports the DX texture manager's activity to PStats. //////////////////////////////////////////////////////////////////// -void DXGraphicsStateGuardian:: +void DXGraphicsStateGuardian8:: report_texmgr_stats() { #if defined(DO_PSTATS)||defined(PRINT_RESOURCESTATS) @@ -1230,13 +1172,13 @@ report_texmgr_stats() { ddsCaps.dwCaps = DDSCAPS_VIDEOMEMORY | DDSCAPS_PRIMARYSURFACE | DDSCAPS_3DDEVICE; if(FAILED( hr = scrn.pD3DDevice->GetAvailableVidMem(&ddsCaps,&dwVidTotal,&dwVidFree))) { - dxgsg_cat.debug() << "report_texmgr GetAvailableVidMem for VIDMEM failed : result = " << D3DERRORSTRING(hr); + dxgsg8_cat.fatal() << "report_texmgr GetAvailableVidMem for VIDMEM failed : result = " << D3DERRORSTRING(hr); exit(1); } ddsCaps.dwCaps = DDSCAPS_TEXTURE; if(FAILED( hr = scrn.pD3DDevice->GetAvailableVidMem(&ddsCaps,&dwTexTotal,&dwTexFree))) { - dxgsg_cat.debug() << "report_texmgr GetAvailableVidMem for TEXTURE failed : result = " << D3DERRORSTRING(hr); + dxgsg8_cat.fatal() << "report_texmgr GetAvailableVidMem for TEXTURE failed : result = " << D3DERRORSTRING(hr); exit(1); } } @@ -1251,13 +1193,13 @@ report_texmgr_stats() { if (hr==S_FALSE) { static int PrintedMsg=2; if(PrintedMsg>0) { - if(dxgsg_cat.is_debug()) - dxgsg_cat.debug() << "Error: texstats GetInfo() requires debug DX DLLs to be installed!! ***********\n"; + if(dxgsg8_cat.is_debug()) + dxgsg8_cat.debug() << "Error: texstats GetInfo() requires debug DX DLLs to be installed!! ***********\n"; ZeroMemory(&all_resource_stats,sizeof(D3DDEVINFO_RESOURCEMANAGER)); bTexStatsRetrievalImpossible=true; } } else { - dxgsg_cat.error() << "GetInfo(RESOURCEMANAGER) failed to get tex stats: result = " << D3DERRORSTRING(hr); + dxgsg8_cat.error() << "GetInfo(RESOURCEMANAGER) failed to get tex stats: result = " << D3DERRORSTRING(hr); return; } } @@ -1270,7 +1212,7 @@ report_texmgr_stats() { sprintf(tmpstr2,"%.4g",dwVidFree/1000000.0); sprintf(tmpstr3,"%.4g",dwTexTotal/1000000.0); sprintf(tmpstr4,"%.4g",dwTexFree/1000000.0); - dxgsg_cat.debug() << "\nAvailableVidMem for RenderSurfs: (megs) total: " << tmpstr1 << " free: " << tmpstr2 + dxgsg8_cat.debug() << "\nAvailableVidMem for RenderSurfs: (megs) total: " << tmpstr1 << " free: " << tmpstr2 << "\nAvailableVidMem for Textures: (megs) total: " << tmpstr3 << " free: " << tmpstr4 << endl; #endif @@ -1289,7 +1231,7 @@ report_texmgr_stats() { float fHitRate = (pRStats->NumUsedInVidMem * 100.0f) / pRStats->NumUsed; sprintf(hitrate_str,"%.1f",fHitRate); - dxgsg_cat.spam() + dxgsg8_cat.spam() << "\n***** Stats for " << ResourceNameStrs[r] << " ********" << "\n HitRate:\t" << hitrate_str << "%" << "\n bThrashing:\t" << pRStats->bThrashing @@ -1304,7 +1246,7 @@ report_texmgr_stats() { << "\n TotalBytes:\t" << pRStats->TotalBytes << "\n LastPri:\t" << pRStats->LastPri << endl; } else { - dxgsg_cat.spam() + dxgsg8_cat.spam() << "\n***** Stats for " << ResourceNameStrs[r] << " ********" << "\n NumUsed: 0\n"; } @@ -1314,10 +1256,10 @@ report_texmgr_stats() { ZeroMemory(&vtxstats,sizeof(D3DDEVINFO_D3DVERTEXSTATS)); hr = scrn.pD3DDevice->GetInfo(D3DDEVINFOID_VERTEXSTATS,&vtxstats,sizeof(D3DDEVINFO_D3DVERTEXSTATS)); if (hr!=D3D_OK) { - dxgsg_cat.error() << "GetInfo(D3DVERTEXSTATS) failed : result = " << D3DERRORSTRING(hr); + dxgsg8_cat.error() << "GetInfo(D3DVERTEXSTATS) failed : result = " << D3DERRORSTRING(hr); return; } else { - dxgsg_cat.spam() + dxgsg8_cat.spam() << "\n***** Triangle Stats ********" << "\n NumRenderedTriangles:\t" << vtxstats.NumRenderedTriangles << "\n NumExtraClippingTriangles:\t" << vtxstats.NumExtraClippingTriangles << endl; @@ -1344,11 +1286,11 @@ report_texmgr_stats() { } //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::add_to_FVFBuf +// Function: DXGraphicsStateGuardian8::add_to_FVFBuf // Access: Private // Description: This adds data to the flexible vertex format //////////////////////////////////////////////////////////////////// -INLINE void DXGraphicsStateGuardian:: +INLINE void DXGraphicsStateGuardian8:: add_to_FVFBuf(void *data, size_t bytes) { memcpy(_pCurFvfBufPtr, data, bytes); _pCurFvfBufPtr += bytes; @@ -1372,7 +1314,7 @@ typedef enum { _pCurrentGeomContext->_pEndofVertData+=numVertBytes; } -INLINE void DXGraphicsStateGuardian:: +INLINE void DXGraphicsStateGuardian8:: transform_color(Colorf &InColor,D3DCOLOR &OutRGBAColor) { Colorf transformed ((InColor[0] * _current_color_scale[0]) + _current_color_offset[0], @@ -1383,11 +1325,11 @@ transform_color(Colorf &InColor,D3DCOLOR &OutRGBAColor) { } //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::draw_prim_setup +// Function: DXGraphicsStateGuardian8::draw_prim_setup // Access: Private // Description: This adds data to the flexible vertex format //////////////////////////////////////////////////////////////////// -size_t DXGraphicsStateGuardian:: +size_t DXGraphicsStateGuardian8:: draw_prim_setup(const Geom *geom) { // Set the flags for the flexible vertex format and compute the bytes // required to store a single vertex. @@ -1513,12 +1455,12 @@ draw_prim_setup(const Geom *geom) { } //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::draw_prim_inner_loop +// Function: DXGraphicsStateGuardian8::draw_prim_inner_loop // Access: Private // Description: This adds data to the flexible vertex format with a check // for component normals and color //////////////////////////////////////////////////////////////////// -void DXGraphicsStateGuardian:: +void DXGraphicsStateGuardian8:: draw_prim_inner_loop(int nVerts, const Geom *geom, ushort perFlags) { Vertexf NextVert; @@ -1563,11 +1505,11 @@ draw_prim_inner_loop(int nVerts, const Geom *geom, ushort perFlags) { //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::draw_prim_inner_loop_coordtexonly +// Function: DXGraphicsStateGuardian8::draw_prim_inner_loop_coordtexonly // Access: Private // Description: FastPath loop used by animated character data //////////////////////////////////////////////////////////////////// -void DXGraphicsStateGuardian:: +void DXGraphicsStateGuardian8:: draw_prim_inner_loop_coordtexonly(int nVerts, const Geom *geom) { // assumes coord and texcoord data is per-vertex, // color is not per-vert/component (which would require fetching new vals in the vertex loop), @@ -1626,15 +1568,15 @@ draw_prim_inner_loop_coordtexonly(int nVerts, const Geom *geom) { } //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::draw_point +// Function: DXGraphicsStateGuardian8::draw_point // Access: Public, Virtual // Description: //////////////////////////////////////////////////////////////////// -void DXGraphicsStateGuardian:: +void DXGraphicsStateGuardian8:: draw_point(GeomPoint *geom, GeomContext *gc) { #ifdef GSG_VERBOSE - dxgsg_cat.debug() << "draw_point()" << endl; + dxgsg8_cat.debug() << "draw_point()" << endl; #endif DO_PSTATS_STUFF(PStatTimer timer(_draw_primitive_pcollector)); @@ -1645,7 +1587,7 @@ draw_point(GeomPoint *geom, GeomContext *gc) { int nPrims = geom->get_num_prims(); if (nPrims==0) { - dxgsg_cat.warning() << "draw_point() called with ZERO vertices!!" << endl; + dxgsg8_cat.warning() << "draw_point() called with ZERO vertices!!" << endl; return; } @@ -1654,7 +1596,7 @@ draw_point(GeomPoint *geom, GeomContext *gc) { if (!bPrintedMsg && (geom->get_size()!=1.0f)) { bPrintedMsg=true; - dxgsg_cat.warning() << "D3D does not support drawing points of non-unit size, setting point size to 1.0f!\n"; + dxgsg8_cat.warning() << "D3D does not support drawing points of non-unit size, setting point size to 1.0f!\n"; } #endif @@ -1703,15 +1645,15 @@ draw_point(GeomPoint *geom, GeomContext *gc) { //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::draw_line +// Function: DXGraphicsStateGuardian8::draw_line // Access: Public, Virtual // Description: //////////////////////////////////////////////////////////////////// -void DXGraphicsStateGuardian:: +void DXGraphicsStateGuardian8:: draw_line(GeomLine* geom, GeomContext *gc) { #ifdef GSG_VERBOSE - dxgsg_cat.debug() << "draw_line()" << endl; + dxgsg8_cat.debug() << "draw_line()" << endl; #endif DO_PSTATS_STUFF(PStatTimer timer(_draw_primitive_pcollector)); DO_PSTATS_STUFF(_vertices_other_pcollector.add_level(geom->get_num_vertices())); @@ -1723,16 +1665,16 @@ draw_line(GeomLine* geom, GeomContext *gc) { if (!bPrintedMsg && (geom->get_width()!=1.0f)) { bPrintedMsg=true; - if(dxgsg_cat.is_debug()) - dxgsg_cat.debug() << "DX does not support drawing lines with a non-1.0f pixel width, setting width to 1.0f!\n"; + if(dxgsg8_cat.is_debug()) + dxgsg8_cat.debug() << "DX does not support drawing lines with a non-1.0f pixel width, setting width to 1.0f!\n"; } #endif int nPrims = geom->get_num_prims(); if (nPrims==0) { - if(dxgsg_cat.is_debug()) - dxgsg_cat.debug() << "draw_line() called with ZERO vertices!!" << endl; + if(dxgsg8_cat.is_debug()) + dxgsg8_cat.debug() << "draw_line() called with ZERO vertices!!" << endl; return; } @@ -1803,7 +1745,7 @@ draw_line(GeomLine* geom, GeomContext *gc) { _pCurFvfBufPtr = NULL; } -void DXGraphicsStateGuardian:: +void DXGraphicsStateGuardian8:: draw_linestrip(GeomLinestrip* geom, GeomContext *gc) { #ifdef _DEBUG @@ -1811,7 +1753,7 @@ draw_linestrip(GeomLinestrip* geom, GeomContext *gc) { if (!bPrintedMsg && (geom->get_width()!=1.0f)) { bPrintedMsg=true; - dxgsg_cat.warning() << "DX does not support drawing lines with a non-1.0f pixel width, setting width to 1.0f!\n"; + dxgsg8_cat.warning() << "DX does not support drawing lines with a non-1.0f pixel width, setting width to 1.0f!\n"; } #endif @@ -1819,16 +1761,16 @@ draw_linestrip(GeomLinestrip* geom, GeomContext *gc) { } //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::draw_linestrip +// Function: DXGraphicsStateGuardian8::draw_linestrip // Access: Public, Virtual // Description: //////////////////////////////////////////////////////////////////// -void DXGraphicsStateGuardian:: +void DXGraphicsStateGuardian8:: draw_linestrip_base(Geom* geom, GeomContext *gc, bool bConnectEnds) { // Note draw_linestrip_base() may be called from non-line draw_fns to support wireframe mode #ifdef GSG_VERBOSE - dxgsg_cat.debug() << "draw_linestrip()" << endl; + dxgsg8_cat.debug() << "draw_linestrip()" << endl; #endif DO_PSTATS_STUFF(PStatTimer timer(_draw_primitive_pcollector)); @@ -1838,8 +1780,8 @@ draw_linestrip_base(Geom* geom, GeomContext *gc, bool bConnectEnds) { const int *pLengthArr = geom->get_lengths(); if(nPrims==0) { - if(dxgsg_cat.is_debug()) - dxgsg_cat.debug() << "draw_linestrip() called with ZERO vertices!!" << endl; + if(dxgsg8_cat.is_debug()) + dxgsg8_cat.debug() << "draw_linestrip() called with ZERO vertices!!" << endl; return; } @@ -1947,11 +1889,11 @@ struct draw_sprite_vertex_less { }; //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::draw_sprite +// Function: DXGraphicsStateGuardian8::draw_sprite // Access: Public, Virtual // Description: //////////////////////////////////////////////////////////////////// -void DXGraphicsStateGuardian:: +void DXGraphicsStateGuardian8:: draw_sprite(GeomSprite *geom, GeomContext *gc) { // this is a little bit of a mess, but it's ok. Here's the deal: @@ -1971,7 +1913,7 @@ draw_sprite(GeomSprite *geom, GeomContext *gc) { // Note: for DX8, try to use the PointSprite primitive instead of doing all the stuff below #ifdef GSG_VERBOSE - dxgsg_cat.debug() << "draw_sprite()" << endl; + dxgsg8_cat.debug() << "draw_sprite()" << endl; #endif // get the array traversal set up. int nPrims = geom->get_num_prims(); @@ -2103,7 +2045,7 @@ draw_sprite(GeomSprite *geom, GeomContext *gc) { // alternately, alloc once when retained mode becomes available if (SpriteArray==NULL) { - dxgsg_cat.fatal() << "draw_sprite() out of memory!!" << endl; + dxgsg8_cat.fatal() << "draw_sprite() out of memory!!" << endl; return; } @@ -2315,15 +2257,15 @@ draw_sprite(GeomSprite *geom, GeomContext *gc) { } //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::draw_polygon +// Function: DXGraphicsStateGuardian8::draw_polygon // Access: Public, Virtual // Description: //////////////////////////////////////////////////////////////////// -void DXGraphicsStateGuardian:: +void DXGraphicsStateGuardian8:: draw_polygon(GeomPolygon *geom, GeomContext *gc) { #ifdef GSG_VERBOSE - dxgsg_cat.debug() << "draw_polygon()" << endl; + dxgsg8_cat.debug() << "draw_polygon()" << endl; #endif DO_PSTATS_STUFF(PStatTimer timer(_draw_primitive_pcollector)); DO_PSTATS_STUFF(_vertices_other_pcollector.add_level(geom->get_num_vertices())); @@ -2339,15 +2281,15 @@ draw_polygon(GeomPolygon *geom, GeomContext *gc) { } //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::draw_quad +// Function: DXGraphicsStateGuardian8::draw_quad // Access: Public, Virtual // Description: //////////////////////////////////////////////////////////////////// -void DXGraphicsStateGuardian:: +void DXGraphicsStateGuardian8:: draw_quad(GeomQuad *geom, GeomContext *gc) { #ifdef GSG_VERBOSE - dxgsg_cat.debug() << "draw_quad()" << endl; + dxgsg8_cat.debug() << "draw_quad()" << endl; #endif DO_PSTATS_STUFF(PStatTimer timer(_draw_primitive_pcollector)); DO_PSTATS_STUFF(_vertices_other_pcollector.add_level(geom->get_num_vertices())); @@ -2364,22 +2306,21 @@ draw_quad(GeomQuad *geom, GeomContext *gc) { //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::draw_tri +// Function: DXGraphicsStateGuardian8::draw_tri // Access: Public, Virtual // Description: //////////////////////////////////////////////////////////////////// -void DXGraphicsStateGuardian:: +void DXGraphicsStateGuardian8:: draw_tri(GeomTri *geom, GeomContext *gc) { - #ifdef GSG_VERBOSE - dxgsg_cat.debug() << "draw_tri()" << endl; + dxgsg8_cat.debug() << "draw_tri()" << endl; #endif DO_PSTATS_STUFF(PStatTimer timer(_draw_primitive_pcollector)); DO_PSTATS_STUFF(_vertices_tri_pcollector.add_level(geom->get_num_vertices())); #if 0 if (_pCurTexContext!=NULL) { - dxgsg_cat.spam() << "Cur active DX texture: " << _pCurTexContext->_tex->get_name() << "\n"; + dxgsg8_cat.spam() << "Cur active DX texture: " << _pCurTexContext->_tex->get_name() << "\n"; } #endif @@ -2514,15 +2455,15 @@ draw_tri(GeomTri *geom, GeomContext *gc) { } //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::draw_tristrip +// Function: DXGraphicsStateGuardian8::draw_tristrip // Access: Public, Virtual // Description: //////////////////////////////////////////////////////////////////// -void DXGraphicsStateGuardian:: +void DXGraphicsStateGuardian8:: draw_tristrip(GeomTristrip *geom, GeomContext *gc) { #ifdef GSG_VERBOSE - dxgsg_cat.debug() << "draw_tristrip()" << endl; + dxgsg8_cat.debug() << "draw_tristrip()" << endl; #endif DO_PSTATS_STUFF(PStatTimer timer(_draw_primitive_pcollector)); DO_PSTATS_STUFF(_vertices_tristrip_pcollector.add_level(geom->get_num_vertices())); @@ -2531,15 +2472,15 @@ draw_tristrip(GeomTristrip *geom, GeomContext *gc) { } //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::draw_trifan +// Function: DXGraphicsStateGuardian8::draw_trifan // Access: Public, Virtual // Description: //////////////////////////////////////////////////////////////////// -void DXGraphicsStateGuardian:: +void DXGraphicsStateGuardian8:: draw_trifan(GeomTrifan *geom, GeomContext *gc) { #ifdef GSG_VERBOSE - dxgsg_cat.debug() << "draw_trifan()" << endl; + dxgsg8_cat.debug() << "draw_trifan()" << endl; #endif DO_PSTATS_STUFF(PStatTimer timer(_draw_primitive_pcollector)); DO_PSTATS_STUFF(_vertices_trifan_pcollector.add_level(geom->get_num_vertices())); @@ -2548,11 +2489,11 @@ draw_trifan(GeomTrifan *geom, GeomContext *gc) { } //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::draw_multitri +// Function: DXGraphicsStateGuardian8::draw_multitri // Access: Public, Virtual // Description: handles trifans and tristrips //////////////////////////////////////////////////////////////////// -void DXGraphicsStateGuardian:: +void DXGraphicsStateGuardian8:: draw_multitri(Geom *geom, D3DPRIMITIVETYPE trilisttype) { DWORD nPrims = geom->get_num_prims(); @@ -2561,7 +2502,7 @@ draw_multitri(Geom *geom, D3DPRIMITIVETYPE trilisttype) { if(nPrims==0) { #ifdef _DEBUG - dxgsg_cat.warning() << "draw_multitri() called with ZERO vertices!!" << endl; + dxgsg8_cat.warning() << "draw_multitri() called with ZERO vertices!!" << endl; #endif return; } @@ -2740,7 +2681,7 @@ draw_multitri(Geom *geom, D3DPRIMITIVETYPE trilisttype) { // probably want to replace this with D3DX8 call -void DXGraphicsStateGuardian:: +void DXGraphicsStateGuardian8:: GenerateSphere(void *pVertexSpace,DWORD dwVertSpaceByteSize, void *pIndexSpace,DWORD dwIndexSpaceByteSize, D3DXVECTOR3 *pCenter, float fRadius, @@ -2981,18 +2922,18 @@ GenerateSphere(void *pVertexSpace,DWORD dwVertSpaceByteSize, //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::draw_sphere +// Function: DXGraphicsStateGuardian8::draw_sphere // Access: Public, Virtual // Description: //////////////////////////////////////////////////////////////////// -void DXGraphicsStateGuardian:: +void DXGraphicsStateGuardian8:: draw_sphere(GeomSphere *geom, GeomContext *gc) { #define SPHERE_NUMSLICES 16 #define SPHERE_NUMSTACKS 10 #ifdef GSG_VERBOSE - dxgsg_cat.debug() << "draw_sphere()" << endl; + dxgsg8_cat.debug() << "draw_sphere()" << endl; #endif DO_PSTATS_STUFF(PStatTimer timer(_draw_primitive_pcollector)); DO_PSTATS_STUFF(_vertices_other_pcollector.add_level(geom->get_num_vertices())); @@ -3000,7 +2941,7 @@ draw_sphere(GeomSphere *geom, GeomContext *gc) { int nprims = geom->get_num_prims(); if (nprims==0) { - dxgsg_cat.warning() << "draw_sphere() called with ZERO vertices!!" << endl; + dxgsg8_cat.warning() << "draw_sphere() called with ZERO vertices!!" << endl; return; } @@ -3045,7 +2986,7 @@ draw_sphere(GeomSphere *geom, GeomContext *gc) { } //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::prepare_texture +// Function: DXGraphicsStateGuardian8::prepare_texture // Access: Public, Virtual // Description: Creates a new retained-mode representation of the // given texture, and returns a newly-allocated @@ -3054,10 +2995,10 @@ draw_sphere(GeomSphere *geom, GeomContext *gc) { // call release_texture() with this same pointer (which // will also delete the pointer). //////////////////////////////////////////////////////////////////// -TextureContext *DXGraphicsStateGuardian:: +TextureContext *DXGraphicsStateGuardian8:: prepare_texture(Texture *tex) { - DXTextureContext *dtc = new DXTextureContext(tex); + DXTextureContext8 *dtc = new DXTextureContext8(tex); #ifdef WBD_GL_MODE glGenTextures(1, >c->_index); @@ -3084,12 +3025,12 @@ prepare_texture(Texture *tex) { } //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::apply_texture +// Function: DXGraphicsStateGuardian8::apply_texture // Access: Public, Virtual // Description: Makes the texture the currently available texture for // rendering. //////////////////////////////////////////////////////////////////// -void DXGraphicsStateGuardian:: +void DXGraphicsStateGuardian8:: apply_texture(TextureContext *tc) { if (tc==NULL) { return; // use enable_texturing to disable/enable @@ -3104,7 +3045,7 @@ apply_texture(TextureContext *tc) { // Note: if this code changes, make sure to change initialization SetTSS code in dx_init as well // so DX TSS renderstate matches dxgsg state - DXTextureContext *dtc = DCAST(DXTextureContext, tc); + DXTextureContext8 *dtc = DCAST(DXTextureContext8, tc); int dirty = dtc->get_dirty_flags(); @@ -3118,7 +3059,7 @@ apply_texture(TextureContext *tc) { // warning--it is likely that this change is the result of an // error or oversight. if ((dirty & Texture::DF_image) == 0) { - dxgsg_cat.warning() + dxgsg8_cat.warning() << "Texture " << *dtc->_texture << " has changed mipmap state.\n"; } @@ -3126,7 +3067,7 @@ apply_texture(TextureContext *tc) { if (dtc->CreateTexture(scrn) == NULL) { // Oops, we can't re-create the texture for some reason. - dxgsg_cat.error() << "Unable to re-create texture " << *dtc->_texture << endl; + dxgsg8_cat.error() << "Unable to re-create texture " << *dtc->_texture << endl; release_texture(dtc); enable_texturing(false); @@ -3168,7 +3109,7 @@ apply_texture(TextureContext *tc) { #ifdef _DEBUG if((ft!=Texture::FT_linear)&&(ft!=Texture::FT_nearest)) { - dxgsg_cat.error() << "MipMap filter type setting for texture magfilter makes no sense, texture: " << tex->get_name() << "\n"; + dxgsg8_cat.error() << "MipMap filter type setting for texture magfilter makes no sense, texture: " << tex->get_name() << "\n"; } #endif } else { @@ -3198,7 +3139,7 @@ apply_texture(TextureContext *tc) { #ifdef _DEBUG if(ft > Texture::FT_linear_mipmap_linear) { - dxgsg_cat.error() << "Unknown tex filter type for tex: " << tex->get_name() << " filter: "<<(DWORD)ft<<"\n"; + dxgsg8_cat.error() << "Unknown tex filter type for tex: " << tex->get_name() << " filter: "<<(DWORD)ft<<"\n"; return; } #endif @@ -3209,7 +3150,7 @@ apply_texture(TextureContext *tc) { // sanity check extern char *PandaFilterNameStrs[]; if((!(dtc->_bHasMipMaps))&&(newMipFilter!=D3DTEXF_NONE)) { - dxgsg_cat.error() << "Trying to set mipmap filtering for texture with no generated mipmaps!! texname[" << tex->get_name() << "], filter("<get_name() << "], filter("<_tex->get_name() << "\n"; + dxgsg8_cat.spam() << "Setting active DX texture: " << dtc->_tex->get_name() << "\n"; } #endif @@ -3245,14 +3186,14 @@ apply_texture(TextureContext *tc) { } //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::release_texture +// Function: DXGraphicsStateGuardian8::release_texture // Access: Public, Virtual // Description: Frees the GL resources previously allocated for the // texture. //////////////////////////////////////////////////////////////////// -void DXGraphicsStateGuardian:: +void DXGraphicsStateGuardian8:: release_texture(TextureContext *tc) { - DXTextureContext *gtc = DCAST(DXTextureContext, tc); + DXTextureContext8 *gtc = DCAST(DXTextureContext8, tc); Texture *tex = tc->_texture; gtc->DeleteTexture(); @@ -3269,27 +3210,27 @@ release_texture(TextureContext *tc) { // copies current display region in framebuffer to the texture // usually its more efficient to do SetRenderTgt -void DXGraphicsStateGuardian:: +void DXGraphicsStateGuardian8:: copy_texture(TextureContext *tc, const DisplayRegion *dr) { HRESULT hr; int xo, yo, w, h; dr->get_region_pixels(xo, yo, w, h); - DXTextureContext *dtc = DCAST(DXTextureContext, tc); + DXTextureContext8 *dtc = DCAST(DXTextureContext8, tc); PixelBuffer *pb = dtc->_tex->_pbuffer; pb->set_size(0,0,w-xo,h-yo); IDirect3DSurface8 *pTexSurfaceLev0,*pCurRenderTarget; hr = dtc->_pD3DTexture8->GetSurfaceLevel(0,&pTexSurfaceLev0); if(FAILED(hr)) { - dxgsg_cat.error() << "GetSurfaceLev failed in copy_texture" << D3DERRORSTRING(hr); + dxgsg8_cat.error() << "GetSurfaceLev failed in copy_texture" << D3DERRORSTRING(hr); exit(1); } hr = scrn.pD3DDevice->GetRenderTarget(&pCurRenderTarget); if(FAILED(hr)) { - dxgsg_cat.error() << "GetRenderTgt failed in copy_texture" << D3DERRORSTRING(hr); + dxgsg8_cat.error() << "GetRenderTgt failed in copy_texture" << D3DERRORSTRING(hr); exit(1); } @@ -3304,7 +3245,7 @@ copy_texture(TextureContext *tc, const DisplayRegion *dr) { // now copy from fb to tex hr = scrn.pD3DDevice->CopyRects(pCurRenderTarget,&SrcRect,1,pTexSurfaceLev0,NULL); if(FAILED(hr)) { - dxgsg_cat.error() << "CopyRects failed in copy_texture" << D3DERRORSTRING(hr); + dxgsg8_cat.error() << "CopyRects failed in copy_texture" << D3DERRORSTRING(hr); exit(1); } @@ -3314,22 +3255,22 @@ copy_texture(TextureContext *tc, const DisplayRegion *dr) { //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::copy_texture +// Function: DXGraphicsStateGuardian8::copy_texture // Access: Public, Virtual // Description: //////////////////////////////////////////////////////////////////// -void DXGraphicsStateGuardian:: +void DXGraphicsStateGuardian8:: copy_texture(TextureContext *tc, const DisplayRegion *dr, const RenderBuffer &rb) { set_read_buffer(rb); copy_texture(tc, dr); } //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::texture_to_pixel_buffer +// Function: DXGraphicsStateGuardian8::texture_to_pixel_buffer // Access: Public, Virtual // Description: //////////////////////////////////////////////////////////////////// -void DXGraphicsStateGuardian:: +void DXGraphicsStateGuardian8:: texture_to_pixel_buffer(TextureContext *tc, PixelBuffer *pb) { nassertv(tc != NULL && pb != NULL); @@ -3350,23 +3291,23 @@ texture_to_pixel_buffer(TextureContext *tc, PixelBuffer *pb) { } //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::texture_to_pixel_buffer +// Function: DXGraphicsStateGuardian8::texture_to_pixel_buffer // Access: Public, Virtual // Description: //////////////////////////////////////////////////////////////////// -void DXGraphicsStateGuardian:: +void DXGraphicsStateGuardian8:: texture_to_pixel_buffer(TextureContext *tc, PixelBuffer *pb, const DisplayRegion *dr) { - dxgsg_cat.error() + dxgsg8_cat.error() << "texture_to_pixel_buffer unimplemented!\n"; } //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::copy_pixel_buffer +// Function: DXGraphicsStateGuardian8::copy_pixel_buffer // Access: Public, Virtual // Description: //////////////////////////////////////////////////////////////////// -void DXGraphicsStateGuardian:: +void DXGraphicsStateGuardian8:: copy_pixel_buffer(PixelBuffer *pb, const DisplayRegion *dr) { RECT SrcCopyRect; @@ -3392,7 +3333,7 @@ copy_pixel_buffer(PixelBuffer *pb, const DisplayRegion *dr) { hr=scrn.pD3DDevice->GetBackBuffer(0,D3DBACKBUFFER_TYPE_MONO,&pD3DSurf); if(FAILED(hr)) { - dxgsg_cat.error() << "GetBackBuffer failed" << D3DERRORSTRING(hr); + dxgsg8_cat.error() << "GetBackBuffer failed" << D3DERRORSTRING(hr); exit(1); } @@ -3436,7 +3377,7 @@ copy_pixel_buffer(PixelBuffer *pb, const DisplayRegion *dr) { hr=scrn.pD3DDevice->CreateImageSurface(TmpSurfXsize,TmpSurfYsize,D3DFMT_A8R8G8B8,&pD3DSurf); if(FAILED(hr)) { - dxgsg_cat.error() << "CreateImageSurface failed in copy_pixel_buffer()" << D3DERRORSTRING(hr); + dxgsg8_cat.error() << "CreateImageSurface failed in copy_pixel_buffer()" << D3DERRORSTRING(hr); exit(1); } @@ -3445,31 +3386,31 @@ copy_pixel_buffer(PixelBuffer *pb, const DisplayRegion *dr) { if(hr==D3DERR_DEVICELOST) { // dont necessary want to exit in this case pD3DSurf->Release(); - dxgsg_cat.error() << "copy_pixel_buffer failed: device lost\n"; + dxgsg8_cat.error() << "copy_pixel_buffer failed: device lost\n"; return; } } else { - dxgsg_cat.error() << "copy_pixel_buffer: unhandled current_read_pixel_buffer type\n"; + dxgsg8_cat.error() << "copy_pixel_buffer: unhandled current_read_pixel_buffer type\n"; } if((RECT_XSIZE(SrcCopyRect)>w) || (RECT_YSIZE(SrcCopyRect)>h)) { - dxgsg_cat.error() << "copy_pixel_buffer: pixel buffer size does not match selected screen RenderBuffer size!\n"; + dxgsg8_cat.error() << "copy_pixel_buffer: pixel buffer size does not match selected screen RenderBuffer size!\n"; exit(1); } (void) ConvertD3DSurftoPixBuf(SrcCopyRect,pD3DSurf,pb); - RELEASE(pD3DSurf,dxgsg,"pD3DSurf",RELEASE_ONCE); + RELEASE(pD3DSurf,dxgsg8,"pD3DSurf",RELEASE_ONCE); nassertv(!pb->_image.empty()); } //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::copy_pixel_buffer +// Function: DXGraphicsStateGuardian8::copy_pixel_buffer // Access: Public, Virtual // Description: //////////////////////////////////////////////////////////////////// -void DXGraphicsStateGuardian:: +void DXGraphicsStateGuardian8:: copy_pixel_buffer(PixelBuffer *pb, const DisplayRegion *dr, const RenderBuffer &rb) { set_read_buffer(rb); @@ -3477,11 +3418,11 @@ copy_pixel_buffer(PixelBuffer *pb, const DisplayRegion *dr, } //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::apply_material +// Function: DXGraphicsStateGuardian8::apply_material // Access: Public, Virtual // Description: //////////////////////////////////////////////////////////////////// -void DXGraphicsStateGuardian::apply_material( const Material* material ) { +void DXGraphicsStateGuardian8::apply_material( const Material* material ) { D3DMATERIAL8 cur_material; cur_material.Diffuse = *(D3DCOLORVALUE *)(material->get_diffuse().get_data()); cur_material.Ambient = *(D3DCOLORVALUE *)(material->get_ambient().get_data()); @@ -3492,11 +3433,11 @@ void DXGraphicsStateGuardian::apply_material( const Material* material ) { } //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::apply_fog +// Function: DXGraphicsStateGuardian8::apply_fog // Access: Public, Virtual // Description: //////////////////////////////////////////////////////////////////// -void DXGraphicsStateGuardian:: +void DXGraphicsStateGuardian8:: apply_fog(Fog *fog) { if(_doFogType==None) @@ -3540,7 +3481,7 @@ apply_fog(Fog *fog) { } } -void DXGraphicsStateGuardian::SetTextureBlendMode(TextureApplyAttrib::Mode TexBlendMode,bool bCanJustEnable) { +void DXGraphicsStateGuardian8::SetTextureBlendMode(TextureApplyAttrib::Mode TexBlendMode,bool bCanJustEnable) { /*class TextureApplyAttrib { enum Mode { @@ -3596,7 +3537,7 @@ void DXGraphicsStateGuardian::SetTextureBlendMode(TextureApplyAttrib::Mode TexBl break; case TextureApplyAttrib::M_blend: - dxgsg_cat.error() + dxgsg8_cat.error() << "Impossible to emulate GL_BLEND in DX exactly " << (int) TexBlendMode << endl; /* // emulate GL_BLEND glTexEnv @@ -3624,18 +3565,18 @@ void DXGraphicsStateGuardian::SetTextureBlendMode(TextureApplyAttrib::Mode TexBl break; default: - dxgsg_cat.error() << "Unknown texture blend mode " << (int) TexBlendMode << endl; + dxgsg8_cat.error() << "Unknown texture blend mode " << (int) TexBlendMode << endl; break; } } //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::enable_texturing +// Function: DXGraphicsStateGuardian8::enable_texturing // Access: // Description: //////////////////////////////////////////////////////////////////// -INLINE void DXGraphicsStateGuardian:: +INLINE void DXGraphicsStateGuardian8:: enable_texturing(bool val) { // if (_texturing_enabled == val) { // this check is mostly for internal gsg calls, panda already screens out redundant state changes // return; @@ -3654,12 +3595,12 @@ enable_texturing(bool val) { } //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::issue_transform +// Function: DXGraphicsStateGuardian8::issue_transform // Access: Public, Virtual // Description: Sends the indicated transform matrix to the graphics // API to be applied to future vertices. //////////////////////////////////////////////////////////////////// -void DXGraphicsStateGuardian:: +void DXGraphicsStateGuardian8:: issue_transform(const TransformState *transform) { // if we're using ONLY vertex shaders, could get avoid calling SetTrans D3DMATRIX *pMat = (D3DMATRIX*)transform->get_mat().get_data(); @@ -3672,7 +3613,7 @@ issue_transform(const TransformState *transform) { HRESULT hr = scrn.pD3DDevice->SetVertexShaderConstant(VSHADER_XFORMMATRIX_CONSTANTREGNUMSTART, pMat, 4); #ifdef _DEBUG if(FAILED(hr)) { - dxgsg_cat.error() << "SetVertexShader failed" << D3DERRORSTRING(hr); + dxgsg8_cat.error() << "SetVertexShader failed" << D3DERRORSTRING(hr); exit(1); } #endif @@ -3681,21 +3622,21 @@ issue_transform(const TransformState *transform) { } //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::issue_tex_matrix +// Function: DXGraphicsStateGuardian8::issue_tex_matrix // Access: Public, Virtual // Description: //////////////////////////////////////////////////////////////////// -void DXGraphicsStateGuardian:: +void DXGraphicsStateGuardian8:: issue_tex_matrix(const TexMatrixAttrib *attrib) { // Not implemented yet. } //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::issue_texture +// Function: DXGraphicsStateGuardian8::issue_texture // Access: Public, Virtual // Description: //////////////////////////////////////////////////////////////////// -void DXGraphicsStateGuardian:: +void DXGraphicsStateGuardian8:: issue_texture(const TextureAttrib *attrib) { if (attrib->is_off()) { enable_texturing(false); @@ -3708,11 +3649,11 @@ issue_texture(const TextureAttrib *attrib) { } //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::issue_material +// Function: DXGraphicsStateGuardian8::issue_material // Access: Public, Virtual // Description: //////////////////////////////////////////////////////////////////// -void DXGraphicsStateGuardian:: +void DXGraphicsStateGuardian8:: issue_material(const MaterialAttrib *attrib) { const Material *material = attrib->get_material(); if (material != (const Material *)NULL) { @@ -3725,11 +3666,11 @@ issue_material(const MaterialAttrib *attrib) { } //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::issue_render_mode +// Function: DXGraphicsStateGuardian8::issue_render_mode // Access: Public, Virtual // Description: //////////////////////////////////////////////////////////////////// -void DXGraphicsStateGuardian:: +void DXGraphicsStateGuardian8:: issue_render_mode(const RenderModeAttrib *attrib) { RenderModeAttrib::Mode mode = attrib->get_mode(); @@ -3743,7 +3684,7 @@ issue_render_mode(const RenderModeAttrib *attrib) { break; default: - dxgsg_cat.error() + dxgsg8_cat.error() << "Unknown render mode " << (int)mode << endl; } @@ -3751,20 +3692,20 @@ issue_render_mode(const RenderModeAttrib *attrib) { } //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::issue_texture_apply +// Function: DXGraphicsStateGuardian8::issue_texture_apply // Access: Public, Virtual // Description: //////////////////////////////////////////////////////////////////// -void DXGraphicsStateGuardian:: +void DXGraphicsStateGuardian8:: issue_texture_apply(const TextureApplyAttrib *attrib) { } //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::issue_depth_test +// Function: DXGraphicsStateGuardian8::issue_depth_test // Access: Public, Virtual // Description: //////////////////////////////////////////////////////////////////// -void DXGraphicsStateGuardian:: +void DXGraphicsStateGuardian8:: issue_depth_test(const DepthTestAttrib *attrib) { DepthTestAttrib::PandaCompareFunc mode = attrib->get_mode(); if (mode == DepthTestAttrib::M_none) { @@ -3778,11 +3719,11 @@ issue_depth_test(const DepthTestAttrib *attrib) { } //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::issue_alpha_test +// Function: DXGraphicsStateGuardian8::issue_alpha_test // Access: Public, Virtual // Description: //////////////////////////////////////////////////////////////////// -void DXGraphicsStateGuardian:: +void DXGraphicsStateGuardian8:: issue_alpha_test(const AlphaTestAttrib *attrib) { AlphaTestAttrib::PandaCompareFunc mode = attrib->get_mode(); if (mode == AlphaTestAttrib::M_none) { @@ -3795,21 +3736,21 @@ issue_alpha_test(const AlphaTestAttrib *attrib) { } //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::issue_depth_write +// Function: DXGraphicsStateGuardian8::issue_depth_write // Access: Public, Virtual // Description: //////////////////////////////////////////////////////////////////// -void DXGraphicsStateGuardian:: +void DXGraphicsStateGuardian8:: issue_depth_write(const DepthWriteAttrib *attrib) { enable_zwritemask(attrib->get_mode() == DepthWriteAttrib::M_on); } //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::issue_cull_face +// Function: DXGraphicsStateGuardian8::issue_cull_face // Access: Public, Virtual // Description: //////////////////////////////////////////////////////////////////// -void DXGraphicsStateGuardian:: +void DXGraphicsStateGuardian8:: issue_cull_face(const CullFaceAttrib *attrib) { CullFaceAttrib::Mode mode = attrib->get_mode(); @@ -3824,18 +3765,18 @@ issue_cull_face(const CullFaceAttrib *attrib) { scrn.pD3DDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW); break; default: - dxgsg_cat.error() + dxgsg8_cat.error() << "invalid cull face mode " << (int)mode << endl; break; } } //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::issue_fog +// Function: DXGraphicsStateGuardian8::issue_fog // Access: Public, Virtual // Description: //////////////////////////////////////////////////////////////////// -void DXGraphicsStateGuardian:: +void DXGraphicsStateGuardian8:: issue_fog(const FogAttrib *attrib) { if (!attrib->is_off()) { enable_fog(true); @@ -3848,25 +3789,25 @@ issue_fog(const FogAttrib *attrib) { } //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::issue_depth_offset +// Function: DXGraphicsStateGuardian8::issue_depth_offset // Access: Public, Virtual // Description: //////////////////////////////////////////////////////////////////// -void DXGraphicsStateGuardian:: +void DXGraphicsStateGuardian8:: issue_depth_offset(const DepthOffsetAttrib *attrib) { int offset = attrib->get_offset(); scrn.pD3DDevice->SetRenderState(D3DRS_ZBIAS, offset); } //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::bind_light +// Function: DXGraphicsStateGuardian8::bind_light // Access: Public, Virtual // Description: Called the first time a particular light has been // bound to a given id within a frame, this should set // up the associated hardware light with the light's // properties. //////////////////////////////////////////////////////////////////// -void DXGraphicsStateGuardian:: +void DXGraphicsStateGuardian8:: bind_light(PointLight *light, int light_id) { // Get the light in "world coordinates". This means the light in // the coordinate space of the camera, converted to DX's coordinate @@ -3900,14 +3841,14 @@ bind_light(PointLight *light, int light_id) { } //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::bind_light +// Function: DXGraphicsStateGuardian8::bind_light // Access: Public, Virtual // Description: Called the first time a particular light has been // bound to a given id within a frame, this should set // up the associated hardware light with the light's // properties. //////////////////////////////////////////////////////////////////// -void DXGraphicsStateGuardian:: +void DXGraphicsStateGuardian8:: bind_light(DirectionalLight *light, int light_id) { // Get the light in "world coordinates". This means the light in // the coordinate space of the camera, converted to DX's coordinate @@ -3941,14 +3882,14 @@ bind_light(DirectionalLight *light, int light_id) { } //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::bind_light +// Function: DXGraphicsStateGuardian8::bind_light // Access: Public, Virtual // Description: Called the first time a particular light has been // bound to a given id within a frame, this should set // up the associated hardware light with the light's // properties. //////////////////////////////////////////////////////////////////// -void DXGraphicsStateGuardian:: +void DXGraphicsStateGuardian8:: bind_light(Spotlight *light, int light_id) { Lens *lens = light->get_lens(); nassertv(lens != (Lens *)NULL); @@ -3990,42 +3931,99 @@ bind_light(Spotlight *light, int light_id) { HRESULT res = scrn.pD3DDevice->SetLight(light_id, &alight); } -// Note: default gsg begin_frame() now calls start_rendering() +//////////////////////////////////////////////////////////////////// +// Function: DXGraphicsStateGuardian8::begin_frame +// Access: Public, Virtual +// Description: Called before each frame is rendered, to allow the +// GSG a chance to do any internal cleanup before +// beginning the frame. +// +// The return value is true if successful (in which case +// the frame will be drawn and end_frame() will be +// called later), or false if unsuccessful (in which +// case nothing will be drawn and end_frame() will not +// be called). +//////////////////////////////////////////////////////////////////// +bool DXGraphicsStateGuardian8:: +begin_frame() { + return GraphicsStateGuardian::begin_frame(); +} + +//////////////////////////////////////////////////////////////////// +// Function: DXGraphicsStateGuardian8::begin_scene +// Access: Public, Virtual +// Description: Called between begin_frame() and end_frame() to mark +// the beginning of drawing commands for a "scene" +// (usually a particular DisplayRegion) within a frame. +// All 3-D drawing commands, except the clear operation, +// must be enclosed within begin_scene() .. end_scene(). +// +// The return value is true if successful (in which case +// the scene will be drawn and end_scene() will be +// called later), or false if unsuccessful (in which +// case nothing will be drawn and end_scene() will not +// be called). +//////////////////////////////////////////////////////////////////// +bool DXGraphicsStateGuardian8:: +begin_scene() { + if (!GraphicsStateGuardian::begin_scene()) { + return false; + } -void DXGraphicsStateGuardian:: -start_rendering(void) { HRESULT hr = scrn.pD3DDevice->BeginScene(); - if(FAILED(hr)) { - if(hr==D3DERR_DEVICELOST) { - if(dxgsg_cat.is_debug()) - dxgsg_cat.debug() << "BeginScene returns DeviceLost\n"; - CheckCooperativeLevel(); + if (FAILED(hr)) { + if (hr == D3DERR_DEVICELOST) { + if (dxgsg8_cat.is_debug()) { + dxgsg8_cat.debug() + << "BeginScene returns D3DERR_DEVICELOST" << endl; + } + + CheckCooperativeLevel(); + } else { - dxgsg_cat.error() << "BeginScene failed, unhandled error" << D3DERRORSTRING(hr); - exit(1); + dxgsg8_cat.error() + << "BeginScene failed, unhandled error hr == " + << D3DERRORSTRING(hr) << endl; + exit(1); + } + return false; + } + + return true; +} + +//////////////////////////////////////////////////////////////////// +// Function: DXGraphicsStateGuardian8::end_scene +// Access: Public, Virtual +// Description: Called between begin_frame() and end_frame() to mark +// the end of drawing commands for a "scene" (usually a +// particular DisplayRegion) within a frame. All 3-D +// drawing commands, except the clear operation, must be +// enclosed within begin_scene() .. end_scene(). +//////////////////////////////////////////////////////////////////// +void DXGraphicsStateGuardian8:: +end_scene() { + HRESULT hr = scrn.pD3DDevice->EndScene(); + + if (FAILED(hr)) { + + if (hr == D3DERR_DEVICELOST) { + if(dxgsg8_cat.is_debug()) { + dxgsg8_cat.debug() + << "EndScene returns DeviceLost\n"; + } + CheckCooperativeLevel(); + + } else { + dxgsg8_cat.error() + << "EndScene failed, unhandled error hr == " << D3DERRORSTRING(hr); + exit(1); } return; } } -void DXGraphicsStateGuardian:: -finish_rendering(void) { - HRESULT hr = scrn.pD3DDevice->EndScene(); - - if(FAILED(hr)) { - if(hr==D3DERR_DEVICELOST) { - if(dxgsg_cat.is_debug()) - dxgsg_cat.debug() << "EndScene returns DeviceLost\n"; - CheckCooperativeLevel(); - } else { - dxgsg_cat.error() << "EndScene failed, unhandled error hr == " << D3DERRORSTRING(hr); - exit(1); - } - return; - } -} - //////////////////////////////////////////////////////////////////// // Function: GraphicsStateGuardian::end_frame // Access: Public, Virtual @@ -4033,62 +4031,8 @@ finish_rendering(void) { // GSG a chance to do any internal cleanup after // rendering the frame, and before the window flips. //////////////////////////////////////////////////////////////////// -void DXGraphicsStateGuardian:: +void DXGraphicsStateGuardian8:: end_frame() { - HRESULT hr; - - // draw fps meter stuff before calling EndScene - if(_bShowFPSMeter) { - DO_PSTATS_STUFF(PStatTimer timer(_win->_show_fps_pcollector)); - - assert(IS_VALID_PTR(_pStatMeterFont)); - - D3DCOLOR fontColor = D3DCOLOR_ARGB(255,255,255,0); // yellow - - char fps_msg[50]; - sprintf(fps_msg,FPS_MSG_FORMAT_STR,scrn.pProps->_xsize,scrn.pProps->_ysize, - (IS_16BPP_DISPLAY_FORMAT(scrn.PresParams.BackBufferFormat) ? 16 : 32),_current_fps); - - // usually only want to call BeginText() & EndText() once/frame - // to bracket all the text for a given cd3dfont obj - hr=_pStatMeterFont->BeginText(); - if(SUCCEEDED(hr)) - hr=_pStatMeterFont->DrawText(_fpsmeter_x_offset, _fpsmeter_y_offset, fontColor, fps_msg); - if(SUCCEEDED(hr)) - hr=_pStatMeterFont->EndText(); - if(FAILED(hr)) - _bShowFPSMeter=false; - } - - DXGraphicsStateGuardian::finish_rendering(); - - // any GDI operations MUST occur after EndScene - - if(_bShowFPSMeter) { - // update frame stats - - DO_PSTATS_STUFF(PStatTimer timer(_win->_show_fps_pcollector)); - - DWORD now = timeGetTime(); // this is win32 fn - - float time_delta = (now - _start_time) * 0.001f; - - if(time_delta > dx_fps_meter_update_interval) { - // didnt use global clock object, it wasnt working properly when I tried, - // its probably slower due to cache faults, and I can easily track all the - // info I need in dxgsg - DWORD num_frames = _cur_frame_count - _start_frame_count; - - _current_fps = num_frames / time_delta; - _start_time = now; - _start_frame_count = _cur_frame_count; - } - - _cur_frame_count++; // only used by fps meter right now - } - - show_frame(); - #ifdef COUNT_DRAWPRIMS { #define FRAMES_PER_DPINFO 90 @@ -4112,7 +4056,7 @@ end_frame() { float DrawPrims_per_Geom = cDPcount/(float)cGeomcount; float verts_per_Geom = cVertcount/(float)cGeomcount; - dxgsg_cat.debug() << "===================================" + dxgsg8_cat.debug() << "===================================" << "\n Avg Verts/sec:\t\t" << verts_per_sec << "\n Avg Tris/sec:\t\t" << tris_per_sec << "\n Avg Verts/frame:\t" << verts_per_frame @@ -4155,42 +4099,42 @@ end_frame() { } //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::wants_normals +// Function: DXGraphicsStateGuardian8::wants_normals // Access: Public, Virtual // Description: //////////////////////////////////////////////////////////////////// -INLINE bool DXGraphicsStateGuardian:: +INLINE bool DXGraphicsStateGuardian8:: wants_normals() const { return (_lighting_enabled || _normals_enabled); } //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::wants_texcoords +// Function: DXGraphicsStateGuardian8::wants_texcoords // Access: Public, Virtual // Description: //////////////////////////////////////////////////////////////////// -INLINE bool DXGraphicsStateGuardian:: +INLINE bool DXGraphicsStateGuardian8:: wants_texcoords() const { return _texturing_enabled; } //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::depth_offset_decals +// Function: DXGraphicsStateGuardian8::depth_offset_decals // Access: Public, Virtual // Description: Returns true if this GSG can implement decals using a // DepthOffsetAttrib, or false if that is unreliable // and the three-step rendering process should be used // instead. //////////////////////////////////////////////////////////////////// -bool DXGraphicsStateGuardian:: +bool DXGraphicsStateGuardian8:: depth_offset_decals() { // False for now. return false; } //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::get_internal_coordinate_system +// Function: DXGraphicsStateGuardian8::get_internal_coordinate_system // Access: Public, Virtual // Description: Should be overridden by derived classes to return the // coordinate system used internally by the GSG, if any @@ -4202,22 +4146,22 @@ depth_offset_decals() { // GraphicsEngine will automatically convert all // transforms into the indicated coordinate system. //////////////////////////////////////////////////////////////////// -CoordinateSystem DXGraphicsStateGuardian:: +CoordinateSystem DXGraphicsStateGuardian8:: get_internal_coordinate_system() const { return CS_yup_left; } //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::compute_distance_to +// Function: DXGraphicsStateGuardian8::compute_distance_to // Access: Public, Virtual // Description: This function may only be called during a render // traversal; it will compute the distance to the // indicated point, assumed to be in modelview // coordinates, from the camera plane. //////////////////////////////////////////////////////////////////// -INLINE float DXGraphicsStateGuardian:: +INLINE float DXGraphicsStateGuardian8:: compute_distance_to(const LPoint3f &point) const { - // In the case of a DXGraphicsStateGuardian, we know that the + // In the case of a DXGraphicsStateGuardian8, we know that the // modelview matrix already includes the relative transform from the // camera, as well as a to-y-up conversion. Thus, the distance to // the camera plane is simply the +z distance. (negative of gl compute_distance_to, @@ -4227,16 +4171,16 @@ compute_distance_to(const LPoint3f &point) const { } //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::set_draw_buffer +// Function: DXGraphicsStateGuardian8::set_draw_buffer // Access: Protected // Description: Sets up the glDrawBuffer to render into the buffer // indicated by the RenderBuffer object. This only sets // up the color bits; it does not affect the depth, // stencil, accum layers. //////////////////////////////////////////////////////////////////// -void DXGraphicsStateGuardian:: +void DXGraphicsStateGuardian8:: set_draw_buffer(const RenderBuffer &rb) { - dxgsg_cat.fatal() << "DX set_draw_buffer unimplemented!!!"; + dxgsg8_cat.fatal() << "DX set_draw_buffer unimplemented!!!"; return; #ifdef WBD_GL_MODE @@ -4280,11 +4224,11 @@ set_draw_buffer(const RenderBuffer &rb) { } //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::set_read_buffer +// Function: DXGraphicsStateGuardian8::set_read_buffer // Access: Protected // Description: Vestigial analog of glReadBuffer //////////////////////////////////////////////////////////////////// -void DXGraphicsStateGuardian:: +void DXGraphicsStateGuardian8:: set_read_buffer(const RenderBuffer &rb) { if(rb._buffer_type & RenderBuffer::T_front) { @@ -4292,18 +4236,18 @@ set_read_buffer(const RenderBuffer &rb) { } else if(rb._buffer_type & RenderBuffer::T_back) { _cur_read_pixel_buffer=RenderBuffer::T_back; } else { - dxgsg_cat.error() << "Invalid or unimplemented Argument to set_read_buffer!\n"; + dxgsg8_cat.error() << "Invalid or unimplemented Argument to set_read_buffer!\n"; } return; } //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::get_texture_wrap_mode +// Function: DXGraphicsStateGuardian8::get_texture_wrap_mode // Access: Protected // Description: Maps from the Texture's internal wrap mode symbols to // GL's. //////////////////////////////////////////////////////////////////// -INLINE D3DTEXTUREADDRESS DXGraphicsStateGuardian:: +INLINE D3DTEXTUREADDRESS DXGraphicsStateGuardian8:: get_texture_wrap_mode(Texture::WrapMode wm) const { static D3DTEXTUREADDRESS PandaTexWrapMode_to_D3DTexWrapMode[Texture::WM_invalid] = { D3DTADDRESS_CLAMP,D3DTADDRESS_WRAP,D3DTADDRESS_MIRROR,D3DTADDRESS_MIRRORONCE,D3DTADDRESS_BORDER}; @@ -4312,11 +4256,11 @@ get_texture_wrap_mode(Texture::WrapMode wm) const { } //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::get_fog_mode_type +// Function: DXGraphicsStateGuardian8::get_fog_mode_type // Access: Protected // Description: Maps from the fog types to gl version //////////////////////////////////////////////////////////////////// -INLINE D3DFOGMODE DXGraphicsStateGuardian:: +INLINE D3DFOGMODE DXGraphicsStateGuardian8:: get_fog_mode_type(Fog::Mode m) const { switch (m) { case Fog::M_linear: @@ -4326,56 +4270,56 @@ get_fog_mode_type(Fog::Mode m) const { case Fog::M_exponential_squared: return D3DFOG_EXP2; } - dxgsg_cat.error() << "Invalid Fog::Mode value" << endl; + dxgsg8_cat.error() << "Invalid Fog::Mode value" << endl; return D3DFOG_EXP; } //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::enable_lighting +// Function: DXGraphicsStateGuardian8::enable_lighting // Access: Protected, Virtual // Description: Intended to be overridden by a derived class to // enable or disable the use of lighting overall. This // is called by issue_light() according to whether any // lights are in use or not. //////////////////////////////////////////////////////////////////// -void DXGraphicsStateGuardian:: +void DXGraphicsStateGuardian8:: enable_lighting(bool enable) { scrn.pD3DDevice->SetRenderState(D3DRS_LIGHTING, (DWORD)enable); } //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::set_ambient_light +// Function: DXGraphicsStateGuardian8::set_ambient_light // Access: Protected, Virtual // Description: Intended to be overridden by a derived class to // indicate the color of the ambient light that should // be in effect. This is called by issue_light() after // all other lights have been enabled or disabled. //////////////////////////////////////////////////////////////////// -void DXGraphicsStateGuardian:: +void DXGraphicsStateGuardian8:: set_ambient_light(const Colorf &color) { scrn.pD3DDevice->SetRenderState(D3DRS_AMBIENT, Colorf_to_D3DCOLOR(color)); } //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::enable_light +// Function: DXGraphicsStateGuardian8::enable_light // Access: Protected, Virtual // Description: Intended to be overridden by a derived class to // enable the indicated light id. A specific Light will // already have been bound to this id via bind_light(). //////////////////////////////////////////////////////////////////// -void DXGraphicsStateGuardian:: +void DXGraphicsStateGuardian8:: enable_light(int light_id, bool enable) { HRESULT res = scrn.pD3DDevice->LightEnable(light_id, enable); #ifdef GSG_VERBOSE - dxgsg_cat.debug() - << "LightEnable(" << light << "=" << val << ")" << endl; + dxgsg8_cat.debug() + << "LightEnable(" << light_id << "=" << enable << ")" << endl; #endif } //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::slot_new_clip_plane +// Function: DXGraphicsStateGuardian8::slot_new_clip_plane // Access: Protected, Virtual // Description: This will be called by the base class before a // particular clip plane id will be used for the first @@ -4388,20 +4332,20 @@ enable_light(int light_id, bool enable) { // The return value should be true if the additional // plane is supported, or false if it is not. //////////////////////////////////////////////////////////////////// -bool DXGraphicsStateGuardian:: +bool DXGraphicsStateGuardian8:: slot_new_clip_plane(int plane_id) { return (plane_id < D3DMAXUSERCLIPPLANES); } //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::enable_clip_plane +// Function: DXGraphicsStateGuardian8::enable_clip_plane // Access: Protected, Virtual // Description: Intended to be overridden by a derived class to // enable the indicated clip_plane id. A specific // PlaneNode will already have been bound to this id via // bind_clip_plane(). //////////////////////////////////////////////////////////////////// -INLINE void DXGraphicsStateGuardian:: +INLINE void DXGraphicsStateGuardian8:: enable_clip_plane(int plane_id, bool enable) { assert(plane_id < D3DMAXUSERCLIPPLANES); @@ -4416,14 +4360,14 @@ enable_clip_plane(int plane_id, bool enable) { } //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::bind_clip_plane +// Function: DXGraphicsStateGuardian8::bind_clip_plane // Access: Protected, Virtual // Description: Called the first time a particular clip_plane has been // bound to a given id within a frame, this should set // up the associated hardware clip_plane with the clip_plane's // properties. //////////////////////////////////////////////////////////////////// -void DXGraphicsStateGuardian:: +void DXGraphicsStateGuardian8:: bind_clip_plane(PlaneNode *plane, int plane_id) { // Get the plane in "world coordinates". This means the plane in // the coordinate space of the camera, converted to DX's coordinate @@ -4436,21 +4380,21 @@ bind_clip_plane(PlaneNode *plane, int plane_id) { scrn.pD3DDevice->SetClipPlane(plane_id, world_plane.get_data()); } -void DXGraphicsStateGuardian:: +void DXGraphicsStateGuardian8:: issue_color_write(const ColorWriteAttrib *attrib) { _color_write_mode = attrib->get_mode(); set_color_writemask((_color_write_mode ==ColorWriteAttrib::M_on) ? 0xFFFFFFFF : 0x0); } //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::set_blend_mode +// Function: DXGraphicsStateGuardian8::set_blend_mode // Access: Protected, Virtual // Description: Called after any of these three blending states have // changed; this function is responsible for setting the // appropriate color blending mode based on the given // properties. //////////////////////////////////////////////////////////////////// -void DXGraphicsStateGuardian:: +void DXGraphicsStateGuardian8:: set_blend_mode(ColorWriteAttrib::Mode color_write_mode, ColorBlendAttrib::Mode color_blend_mode, TransparencyAttrib::Mode transparency_mode) { @@ -4485,7 +4429,7 @@ set_blend_mode(ColorWriteAttrib::Mode color_write_mode, return; default: - dxgsg_cat.error() + dxgsg8_cat.error() << "Unknown color blend mode " << (int)color_blend_mode << endl; break; } @@ -4506,7 +4450,7 @@ set_blend_mode(ColorWriteAttrib::Mode color_write_mode, return; default: - dxgsg_cat.error() + dxgsg8_cat.error() << "invalid transparency mode " << (int)transparency_mode << endl; break; } @@ -4516,7 +4460,7 @@ set_blend_mode(ColorWriteAttrib::Mode color_write_mode, } //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::save_frame_buffer +// Function: DXGraphicsStateGuardian8::save_frame_buffer // Access: Public // Description: Saves the indicated planes of the frame buffer // (within the indicated display region) and returns it @@ -4525,11 +4469,11 @@ set_blend_mode(ColorWriteAttrib::Mode color_write_mode, // function for push_frame_buffer() and // pop_frame_buffer(). //////////////////////////////////////////////////////////////////// -PT(SavedFrameBuffer) DXGraphicsStateGuardian:: +PT(SavedFrameBuffer) DXGraphicsStateGuardian8:: save_frame_buffer(const RenderBuffer &buffer, CPT(DisplayRegion) dr) { - dxgsg_cat.error() << "save_frame_buffer unimplemented!!\n"; + dxgsg8_cat.error() << "save_frame_buffer unimplemented!!\n"; return NULL; #if 0 @@ -4554,39 +4498,39 @@ save_frame_buffer(const RenderBuffer &buffer, } //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::restore_frame_buffer +// Function: DXGraphicsStateGuardian8::restore_frame_buffer // Access: Public // Description: Restores the frame buffer that was previously saved. //////////////////////////////////////////////////////////////////// -void DXGraphicsStateGuardian:: +void DXGraphicsStateGuardian8:: restore_frame_buffer(SavedFrameBuffer *frame_buffer) { - dxgsg_cat.error() << "restore_frame_buffer unimplemented!!\n"; + dxgsg8_cat.error() << "restore_frame_buffer unimplemented!!\n"; return; } // factory and type stuff -GraphicsStateGuardian *DXGraphicsStateGuardian:: -make_DXGraphicsStateGuardian(const FactoryParams ¶ms) { +GraphicsStateGuardian *DXGraphicsStateGuardian8:: +make_DXGraphicsStateGuardian8(const FactoryParams ¶ms) { GraphicsStateGuardian::GsgWindow *win_param; if (!get_param_into(win_param, params)) { - dxgsg_cat.error() << "No window specified for gsg creation!" << endl; + dxgsg8_cat.error() << "No window specified for gsg creation!" << endl; return NULL; } GraphicsWindow *win = win_param->get_window(); - return new DXGraphicsStateGuardian(win); + return new DXGraphicsStateGuardian8(win); } -TypeHandle DXGraphicsStateGuardian::get_type(void) const { +TypeHandle DXGraphicsStateGuardian8::get_type(void) const { return get_class_type(); } -TypeHandle DXGraphicsStateGuardian::get_class_type(void) { +TypeHandle DXGraphicsStateGuardian8::get_class_type(void) { return _type_handle; } -void DXGraphicsStateGuardian::init_type(void) { +void DXGraphicsStateGuardian8::init_type(void) { GraphicsStateGuardian::init_type(); register_type(_type_handle, "DXGraphicsStateGuardian8", GraphicsStateGuardian::get_class_type()); @@ -4596,12 +4540,12 @@ void DXGraphicsStateGuardian::init_type(void) { // Function: dx_cleanup // Description: Clean up the DirectX environment, accounting for exit() //////////////////////////////////////////////////////////////////// -void DXGraphicsStateGuardian:: +void DXGraphicsStateGuardian8:: dx_cleanup(bool bRestoreDisplayMode,bool bAtExitFnCalled) { static bool bAtExitFnEverCalled=false; - if(dxgsg_cat.is_spam()) { - dxgsg_cat.spam() << "dx_cleanup called, bAtExitFnCalled=" << bAtExitFnCalled << ", bAtExitFnEverCalled=" << bAtExitFnEverCalled << endl; + if(dxgsg8_cat.is_spam()) { + dxgsg8_cat.spam() << "dx_cleanup called, bAtExitFnCalled=" << bAtExitFnCalled << ", bAtExitFnEverCalled=" << bAtExitFnEverCalled << endl; } bAtExitFnEverCalled = (bAtExitFnEverCalled || bAtExitFnCalled); @@ -4626,7 +4570,6 @@ dx_cleanup(bool bRestoreDisplayMode,bool bAtExitFnCalled) { PRINT_REFCNT(dxgsg,scrn.pD3DDevice); // delete non-panda-texture/geom DX objects (VBs/textures/shaders) - SAFE_DELETE(_pStatMeterFont); SAFE_DELSHADER(Vertex,_CurVertexShader,scrn.pD3DDevice); SAFE_DELSHADER(Pixel,_CurPixelShader,scrn.pD3DDevice); SAFE_RELEASE(_pGlobalTexture); @@ -4638,15 +4581,15 @@ dx_cleanup(bool bRestoreDisplayMode,bool bAtExitFnCalled) { if (scrn.pD3DDevice!=NULL) { for(int i=0;iSetTexture(i,NULL); // d3d should release this stuff internally anyway, but whatever - RELEASE(scrn.pD3DDevice,dxgsg,"d3dDevice",RELEASE_DOWN_TO_ZERO); + RELEASE(scrn.pD3DDevice,dxgsg8,"d3dDevice",RELEASE_DOWN_TO_ZERO); } - RELEASE(scrn.pD3D8,dxgsg,"ID3D8",RELEASE_DOWN_TO_ZERO); + RELEASE(scrn.pD3D8,dxgsg8,"ID3D8",RELEASE_DOWN_TO_ZERO); } bool refill_tex_callback(TextureContext *tc,void *void_dxgsg_ptr) { - DXTextureContext *dtc = DCAST(DXTextureContext, tc); -// DXGraphicsStateGuardian *dxgsg = (DXGraphicsStateGuardian *)void_dxgsg_ptr; not needed? + DXTextureContext8 *dtc = DCAST(DXTextureContext8, tc); +// DXGraphicsStateGuardian8 *dxgsg = (DXGraphicsStateGuardian8 *)void_dxgsg_ptr; not needed? // Re-fill the contents of textures and vertex buffers // which just got restored now. @@ -4655,7 +4598,7 @@ bool refill_tex_callback(TextureContext *tc,void *void_dxgsg_ptr) { } bool delete_tex_callback(TextureContext *tc,void *void_dxgsg_ptr) { - DXTextureContext *dtc = DCAST(DXTextureContext, tc); + DXTextureContext8 *dtc = DCAST(DXTextureContext8, tc); // release DDSurf (but not the texture context) dtc->DeleteTexture(); @@ -4663,8 +4606,8 @@ bool delete_tex_callback(TextureContext *tc,void *void_dxgsg_ptr) { } bool recreate_tex_callback(TextureContext *tc,void *void_dxgsg_ptr) { - DXTextureContext *dtc = DCAST(DXTextureContext, tc); - DXGraphicsStateGuardian *dxgsg = (DXGraphicsStateGuardian *)void_dxgsg_ptr; + DXTextureContext8 *dtc = DCAST(DXTextureContext8, tc); + DXGraphicsStateGuardian8 *dxgsg = (DXGraphicsStateGuardian8 *)void_dxgsg_ptr; // Re-fill the contents of textures and vertex buffers // which just got restored now. @@ -4674,7 +4617,7 @@ bool recreate_tex_callback(TextureContext *tc,void *void_dxgsg_ptr) { } // release all textures and vertex/index buffers -HRESULT DXGraphicsStateGuardian::DeleteAllDeviceObjects(void) { +HRESULT DXGraphicsStateGuardian8::DeleteAllDeviceObjects(void) { // BUGBUG: need to release any vertexbuffers here // cant access template in libpanda.dll directly due to vc++ limitations, use traverser to get around it @@ -4684,11 +4627,10 @@ HRESULT DXGraphicsStateGuardian::DeleteAllDeviceObjects(void) { // bugbug: do I still need to delete all the textures since they are all D3DPOOL_MANAGED now? traverse_prepared_textures(delete_tex_callback,this); - if(dxgsg_cat.is_debug()) - dxgsg_cat.debug() << "release of all textures complete\n"; + if(dxgsg8_cat.is_debug()) + dxgsg8_cat.debug() << "release of all textures complete\n"; // delete non-panda-texture/geom DX objects (VBs/textures/shaders) - SAFE_DELETE(_pStatMeterFont); SAFE_DELSHADER(Vertex,_CurVertexShader,scrn.pD3DDevice); SAFE_DELSHADER(Pixel,_CurPixelShader,scrn.pD3DDevice); SAFE_RELEASE(_pGlobalTexture); @@ -4703,26 +4645,19 @@ HRESULT DXGraphicsStateGuardian::DeleteAllDeviceObjects(void) { } // recreate all textures and vertex/index buffers -HRESULT DXGraphicsStateGuardian::RecreateAllDeviceObjects(void) { +HRESULT DXGraphicsStateGuardian8::RecreateAllDeviceObjects(void) { // BUGBUG: need to handle vertexbuffer handling here - if(IS_VALID_PTR(_pStatMeterFont)) { - _pStatMeterFont->RestoreDeviceObjects(); - } - // cant access template in libpanda.dll directly due to vc++ limitations, use traverser to get around it traverse_prepared_textures(recreate_tex_callback,this); - if(dxgsg_cat.is_debug()) - dxgsg_cat.debug() << "recreation of all textures complete\n"; + if(dxgsg8_cat.is_debug()) + dxgsg8_cat.debug() << "recreation of all textures complete\n"; return S_OK; } -HRESULT DXGraphicsStateGuardian::ReleaseAllDeviceObjects(void) { +HRESULT DXGraphicsStateGuardian8::ReleaseAllDeviceObjects(void) { // release any D3DPOOL_DEFAULT objects here (currently none) - - // StatMeter uses dynamic D3DPOOL_DEFAULT VertBuf, must destroy it now - SAFE_DELETE(_pStatMeterFont); return S_OK; } @@ -4731,11 +4666,11 @@ HRESULT DXGraphicsStateGuardian::ReleaseAllDeviceObjects(void) { // Access: // Description: redraw primary buffer //////////////////////////////////////////////////////////////////// -void DXGraphicsStateGuardian::show_frame(bool bNoNewFrameDrawn) { +void DXGraphicsStateGuardian8::show_frame(bool bNoNewFrameDrawn) { if(scrn.pD3DDevice==NULL) return; - DO_PSTATS_STUFF(PStatTimer timer(_win->_swap_pcollector)); // this times just the flip, so it must go here in dxgsg, instead of wdxdisplay, which would time the whole frame + // DO_PSTATS_STUFF(PStatTimer timer(_win->_swap_pcollector)); // this times just the flip, so it must go here in dxgsg, instead of wdxdisplay, which would time the whole frame HRESULT hr; if(bNoNewFrameDrawn) { @@ -4764,13 +4699,13 @@ void DXGraphicsStateGuardian::show_frame(bool bNoNewFrameDrawn) { if(hr == D3DERR_DEVICELOST) { CheckCooperativeLevel(); } else { - dxgsg_cat.error() << "show_frame() - Present() failed" << D3DERRORSTRING(hr); + dxgsg8_cat.error() << "show_frame() - Present() failed" << D3DERRORSTRING(hr); exit(1); } } } -HRESULT DXGraphicsStateGuardian::reset_d3d_device(D3DPRESENT_PARAMETERS *pPresParams) { +HRESULT DXGraphicsStateGuardian8::reset_d3d_device(D3DPRESENT_PARAMETERS *pPresParams) { HRESULT hr; assert(IS_VALID_PTR(pPresParams)); @@ -4795,113 +4730,53 @@ HRESULT DXGraphicsStateGuardian::reset_d3d_device(D3DPRESENT_PARAMETERS *pPresPa return hr; } -bool DXGraphicsStateGuardian::CheckCooperativeLevel(bool bDoReactivateWindow) { +bool DXGraphicsStateGuardian8:: +CheckCooperativeLevel(bool bDoReactivateWindow) { + HRESULT hr = scrn.pD3DDevice->TestCooperativeLevel(); - HRESULT hr = scrn.pD3DDevice->TestCooperativeLevel(); - if(SUCCEEDED(hr)) { - assert(SUCCEEDED(_last_testcooplevel_result)); - return true; + if(SUCCEEDED(hr)) { + assert(SUCCEEDED(_last_testcooplevel_result)); + return true; + } + + switch(hr) { + case D3DERR_DEVICENOTRESET: + _bDXisReady = false; + hr=reset_d3d_device(&scrn.PresParams); + if (FAILED(hr)) { + // I think this shouldnt fail unless I've screwed up the PresParams from the original working ones somehow + dxgsg8_cat.error() + << "CheckCooperativeLevel Reset() failed, hr = " << D3DERRORSTRING(hr); + exit(1); } - switch(hr) { - case D3DERR_DEVICENOTRESET: - _bDXisReady = false; - hr=reset_d3d_device(&scrn.PresParams); - if(FAILED(hr)) { - // I think this shouldnt fail unless I've screwed up the PresParams from the original working ones somehow - dxgsg_cat.error() << "CheckCooperativeLevel Reset() failed, hr = " << D3DERRORSTRING(hr); - exit(1); - } - - if(bDoReactivateWindow) - _win->reactivate_window(); //must reactivate window before you can restore surfaces (otherwise you are in WRONGVIDEOMODE, and DDraw RestoreAllSurfaces fails) - hr = scrn.pD3DDevice->TestCooperativeLevel(); - if(FAILED(hr)) { - // internal chk, shouldnt fail - dxgsg_cat.error() << "TestCooperativeLevel following Reset() failed, hr = " << D3DERRORSTRING(hr); - exit(1); - } - - _bDXisReady = TRUE; - - break; - - case D3DERR_DEVICELOST: - if(SUCCEEDED(_last_testcooplevel_result)) { - if(_bDXisReady) { - _win->deactivate_window(); - _bDXisReady = false; - if(dxgsg_cat.is_debug()) - dxgsg_cat.debug() << "D3D Device was Lost, waiting...\n"; - } - } + if(bDoReactivateWindow) { + // _win->reactivate_window(); //must reactivate window before you can restore surfaces (otherwise you are in WRONGVIDEOMODE, and DDraw RestoreAllSurfaces fails) + } + hr = scrn.pD3DDevice->TestCooperativeLevel(); + if(FAILED(hr)) { + // internal chk, shouldnt fail + dxgsg8_cat.error() + << "TestCooperativeLevel following Reset() failed, hr = " << D3DERRORSTRING(hr); + exit(1); } -/* - if(SUCCEEDED(hr)) // this means this was just a safety check, dont need to restore surfs - return true; + _bDXisReady = TRUE; + break; - // otherwise something just went wrong - - if(hr==D3DERR_DEVICELOST) { - // This means that mode changes had taken place, surfaces - // were lost but still we are in the original mode, so we - // simply restore all surfaces and keep going. - - if(dxgsg_cat.is_debug()) { - if(dx_full_screen) - dxgsg_cat.debug() << "Lost access to DDRAW exclusive mode, waiting to regain it...\n"; - else dxgsg_cat.debug() << "Another app has DDRAW exclusive mode, waiting...\n"; - } - - } else if(hr==D3DERR_DEVICENOTRESET) { - // need to call Reset() - - // do I want to do it here, or do - HRESULT hr=scrn.pD3DDevice->Reset(&scrn.PresParams); - if(FAILED(hr)) { - dxgsg_cat.error() << "CheckCooperativeLevel Reset() failed, hr = " << D3DERRORSTRING(hr); - exit(1); - } - - } else { - dxgsg_cat.error() << "unexpected return code from TestCoopLevel: " << D3DERRORSTRING(hr); - exit(1); - } - } else { - // testcooplvl was failing, handle case where it now succeeds - - if(SUCCEEDED(hr)) { - if(_last_testcooplevel_result == DDERR_EXCLUSIVEMODEALREADYSET) { - if(dxgsg_cat.is_debug()) - dxgsg_cat.debug() << "other app relinquished exclusive mode, refilling surfs...\n"; - } else if(_last_testcooplevel_result == DDERR_NOEXCLUSIVEMODE) { - if(dxgsg_cat.is_debug()) - dxgsg_cat.debug() << "regained exclusive mode, refilling surfs...\n"; - } - - if(bDoReactivateWindow) - _win->reactivate_window(); //must reactivate window before you can restore surfaces (otherwise you are in WRONGVIDEOMODE, and DDraw RestoreAllSurfaces fails) - - RestoreAllVideoSurfaces(); - - _bDXisReady = TRUE; - - } else if(hr==DDERR_WRONGMODE) { - // This means that the desktop mode has changed - // need to destroy all of dx stuff and recreate everything - // back again, which is a big hit - dxgsg_cat.error() << "detected desktop display mode change in TestCoopLevel, must recreate all DDraw surfaces & D3D devices, this is not handled yet. " << D3DERRORSTRING(hr); - _win->close_window(); - exit(1); - } else if((hr!=DDERR_NOEXCLUSIVEMODE) && (hr!=DDERR_EXCLUSIVEMODEALREADYSET)) { - dxgsg_cat.error() << "unexpected return code from TestCoopLevel: " << D3DERRORSTRING(hr); - exit(1); - } + case D3DERR_DEVICELOST: + if(SUCCEEDED(_last_testcooplevel_result)) { + if(_bDXisReady) { + // _win->deactivate_window(); + _bDXisReady = false; + if(dxgsg8_cat.is_debug()) + dxgsg8_cat.debug() << "D3D Device was Lost, waiting...\n"; + } } -*/ - _last_testcooplevel_result = hr; - return SUCCEEDED(hr); + } + + _last_testcooplevel_result = hr; + return SUCCEEDED(hr); } /* @@ -4910,7 +4785,7 @@ bool DXGraphicsStateGuardian::CheckCooperativeLevel(bool bDoReactivateWindow) { // Access: // Description: we receive the new x and y position of the client //////////////////////////////////////////////////////////////////// -void DXGraphicsStateGuardian::adjust_view_rect(int x, int y) { +void DXGraphicsStateGuardian8::adjust_view_rect(int x, int y) { if (scrn.view_rect.left != x || scrn.view_rect.top != y) { scrn.view_rect.right = x + RECT_XSIZE(scrn.view_rect); @@ -4932,7 +4807,7 @@ void DXGraphicsStateGuardian::adjust_view_rect(int x, int y) { // (which must also be the currently active texture in // the GL state) as a separate image file to disk. //////////////////////////////////////////////////////////////////// -void DXGraphicsStateGuardian::read_mipmap_images(Texture *tex) { +void DXGraphicsStateGuardian8::read_mipmap_images(Texture *tex) { Filename filename = tex->get_name(); string name; if (filename.empty()) { @@ -5045,7 +4920,7 @@ HRESULT SetViewMatrix( D3DMATRIX& mat, D3DXVECTOR3& vFrom, D3DXVECTOR3& vAt, //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::prepare_geom_node +// Function: DXGraphicsStateGuardian8::prepare_geom_node // Access: Public, Virtual // Description: Prepares the indicated GeomNode for retained-mode // rendering. If this function returns non-NULL, the @@ -5053,32 +4928,32 @@ HRESULT SetViewMatrix( D3DMATRIX& mat, D3DXVECTOR3& vFrom, D3DXVECTOR3& vAt, // to draw_geom_node(), which is expected to draw the // contents of the node. //////////////////////////////////////////////////////////////////// -GeomNodeContext *DXGraphicsStateGuardian:: +GeomNodeContext *DXGraphicsStateGuardian8:: prepare_geom_node(GeomNode *node) { - dxgsg_cat.error() << "prepare_geom_node unimplemented for DX8!\n"; + dxgsg8_cat.error() << "prepare_geom_node unimplemented for DX8!\n"; return NULL; } //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::draw_geom_node +// Function: DXGraphicsStateGuardian8::draw_geom_node // Access: Public, Virtual // Description: Draws a GeomNode previously indicated by a call to // prepare_geom_node(). //////////////////////////////////////////////////////////////////// -void DXGraphicsStateGuardian:: +void DXGraphicsStateGuardian8:: draw_geom_node(GeomNode *node, const RenderState *state, GeomNodeContext *gnc) { return; // unimplemented } //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::release_geom_node +// Function: DXGraphicsStateGuardian8::release_geom_node // Access: Public, Virtual // Description: Frees the resources previously allocated via a call // to prepare_geom_node(), including deleting the // GeomNodeContext itself, if necessary. //////////////////////////////////////////////////////////////////// -void DXGraphicsStateGuardian:: +void DXGraphicsStateGuardian8:: release_geom_node(GeomNodeContext *gnc) { } @@ -5230,7 +5105,7 @@ End: SAFE_DELETE_ARRAY( pcrArrayColor ); SAFE_DELETE_ARRAY( pcrArrayMask ); - RELEASE(pCursorBitmap,dxgsg,"pCursorBitmap",RELEASE_ONCE); + RELEASE(pCursorBitmap,dxgsg8,"pCursorBitmap",RELEASE_ONCE); return hr; } diff --git a/panda/src/dxgsg8/dxGraphicsStateGuardian8.h b/panda/src/dxgsg8/dxGraphicsStateGuardian8.h index a164ef7731..e94f7db46a 100644 --- a/panda/src/dxgsg8/dxGraphicsStateGuardian8.h +++ b/panda/src/dxgsg8/dxGraphicsStateGuardian8.h @@ -19,7 +19,7 @@ #ifndef DXGRAPHICSSTATEGUARDIAN_H #define DXGRAPHICSSTATEGUARDIAN_H -//#define GSG_VERBOSE +//#define GSG_VERBOSE 1 #include "dxgsg8base.h" #include "dxGeomNodeContext8.h" @@ -58,20 +58,20 @@ extern void dbgPrintVidMem(LPDIRECTDRAW7 pDD, LPDDSCAPS2 lpddsCaps,const char *p #endif //////////////////////////////////////////////////////////////////// -// Class : DXGraphicsStateGuardian +// Class : DXGraphicsStateGuardian8 // Description : A GraphicsStateGuardian specialized for rendering // into DX. There should be no DX calls // outside of this object. //////////////////////////////////////////////////////////////////// -class EXPCL_PANDADX DXGraphicsStateGuardian : public GraphicsStateGuardian { - friend class wdxGraphicsWindow; - friend class wdxGraphicsPipe; - friend class wdxGraphicsWindowGroup; - friend class DXTextureContext; +class EXPCL_PANDADX DXGraphicsStateGuardian8 : public GraphicsStateGuardian { + friend class wdxGraphicsWindow8; + friend class wdxGraphicsPipe8; + friend class wdxGraphicsWindowGroup8; + friend class DXTextureContext8; public: - DXGraphicsStateGuardian(GraphicsWindow *win); - ~DXGraphicsStateGuardian(); + DXGraphicsStateGuardian8(GraphicsWindow *win); + ~DXGraphicsStateGuardian8(); virtual void reset(); @@ -134,12 +134,11 @@ public: virtual void bind_light(DirectionalLight *light, int light_id); virtual void bind_light(Spotlight *light, int light_id); - // default gsg begin_frame() used + virtual bool begin_frame(); + virtual bool begin_scene(); + virtual void end_scene(); virtual void end_frame(); - virtual void start_rendering(); - virtual void finish_rendering(); - virtual bool wants_normals(void) const; virtual bool wants_texcoords(void) const; @@ -179,8 +178,7 @@ protected: bool _bDXisReady; HRESULT _last_testcooplevel_result; - bool _bShowFPSMeter; - DXTextureContext *_pCurTexContext; + DXTextureContext8 *_pCurTexContext; bool _bTransformIssued; // decaling needs to tell when a transform has been issued D3DMATRIX _SavedTransform; @@ -246,7 +244,7 @@ protected: bool _bGouraudShadingOn; UINT _color_writemask; bool _bDrawPrimDoSetupVertexBuffer; // if true, draw methods just copy vertex data into pCurrentGeomContext - DXGeomNodeContext *_pCurrentGeomContext; // used in vertex buffer setup + DXGeomNodeContext8 *_pCurrentGeomContext; // used in vertex buffer setup // iterators for primitives Geom::VertexIterator vi; @@ -322,16 +320,9 @@ protected: bool _overlay_windows_supported; - // vars for frames/sec meter - DWORD _start_time; - DWORD _start_frame_count; - DWORD _cur_frame_count; - float _current_fps,_fpsmeter_x_offset,_fpsmeter_y_offset; - ::CD3DFont *_pStatMeterFont; - public: static GraphicsStateGuardian* - make_DXGraphicsStateGuardian(const FactoryParams ¶ms); + make_DXGraphicsStateGuardian8(const FactoryParams ¶ms); static TypeHandle get_class_type(void); static void init_type(void); @@ -339,7 +330,7 @@ public: virtual TypeHandle force_init_type() {init_type(); return get_class_type();} INLINE void SetDXReady(bool status) { _bDXisReady = status; } INLINE bool GetDXReady(void) { return _bDXisReady;} - void DXGraphicsStateGuardian::SetTextureBlendMode(TextureApplyAttrib::Mode TexBlendMode,bool bJustEnable); + void DXGraphicsStateGuardian8::SetTextureBlendMode(TextureApplyAttrib::Mode TexBlendMode,bool bJustEnable); // Shader Stuff DXShaderHandle read_vertex_shader(string &filename); @@ -364,7 +355,7 @@ private: static TypeHandle _type_handle; }; -#include "dxGraphicsStateGuardian8.I" +#include "DXGraphicsStateGuardian8.I" #endif diff --git a/panda/src/dxgsg8/dxSavedFrameBuffer8.I b/panda/src/dxgsg8/dxSavedFrameBuffer8.I index d621f689f2..71534f488b 100644 --- a/panda/src/dxgsg8/dxSavedFrameBuffer8.I +++ b/panda/src/dxgsg8/dxSavedFrameBuffer8.I @@ -1,4 +1,4 @@ -// Filename: dxSavedFrameBuffer.I +// Filename: dxSavedFrameBuffer8.I // Created by: drose (06Oct99) // //////////////////////////////////////////////////////////////////// @@ -18,22 +18,22 @@ //////////////////////////////////////////////////////////////////// -// Function: DXSavedFrameBuffer::Constructor +// Function: DXSavedFrameBuffer8::Constructor // Access: Public // Description: //////////////////////////////////////////////////////////////////// -INLINE DXSavedFrameBuffer:: -DXSavedFrameBuffer(const RenderBuffer &buffer, CPT(DisplayRegion) dr) : +INLINE DXSavedFrameBuffer8:: +DXSavedFrameBuffer8(const RenderBuffer &buffer, CPT(DisplayRegion) dr) : SavedFrameBuffer(buffer, dr) { } //////////////////////////////////////////////////////////////////// -// Function: DXSavedFrameBuffer::Destructor +// Function: DXSavedFrameBuffer8::Destructor // Access: Public // Description: //////////////////////////////////////////////////////////////////// -INLINE DXSavedFrameBuffer:: -~DXSavedFrameBuffer() { +INLINE DXSavedFrameBuffer8:: +~DXSavedFrameBuffer8() { } diff --git a/panda/src/dxgsg8/dxSavedFrameBuffer8.cxx b/panda/src/dxgsg8/dxSavedFrameBuffer8.cxx index cbc95c2735..225a4dfb01 100644 --- a/panda/src/dxgsg8/dxSavedFrameBuffer8.cxx +++ b/panda/src/dxgsg8/dxSavedFrameBuffer8.cxx @@ -1,4 +1,4 @@ -// Filename: dxSavedFrameBuffer.cxx +// Filename: dxSavedFrameBuffer8.cxx // Created by: drose (06Oct99) // //////////////////////////////////////////////////////////////////// @@ -18,4 +18,4 @@ #include "dxSavedFrameBuffer8.h" -TypeHandle DXSavedFrameBuffer::_type_handle; +TypeHandle DXSavedFrameBuffer8::_type_handle; diff --git a/panda/src/dxgsg8/dxSavedFrameBuffer8.h b/panda/src/dxgsg8/dxSavedFrameBuffer8.h index 36e0548fbf..8f9babc0eb 100644 --- a/panda/src/dxgsg8/dxSavedFrameBuffer8.h +++ b/panda/src/dxgsg8/dxSavedFrameBuffer8.h @@ -1,4 +1,4 @@ -// Filename: dxSavedFrameBuffer.h +// Filename: dxSavedFrameBuffer8.h // Created by: drose (06Oct99) // //////////////////////////////////////////////////////////////////// @@ -28,14 +28,14 @@ //////////////////////////////////////////////////////////////////// -// Class : DXSavedFrameBuffer +// Class : DXSavedFrameBuffer8 // Description : //////////////////////////////////////////////////////////////////// -class EXPCL_PANDADX DXSavedFrameBuffer : public SavedFrameBuffer { +class EXPCL_PANDADX DXSavedFrameBuffer8 : public SavedFrameBuffer { public: - INLINE DXSavedFrameBuffer(const RenderBuffer &buffer, + INLINE DXSavedFrameBuffer8(const RenderBuffer &buffer, CPT(DisplayRegion) dr); - INLINE ~DXSavedFrameBuffer(); + INLINE ~DXSavedFrameBuffer8(); PT(Texture) _back_rgba; PT(PixelBuffer) _depth; @@ -46,7 +46,7 @@ public: } static void init_type() { SavedFrameBuffer::init_type(); - register_type(_type_handle, "DXSavedFrameBuffer", + register_type(_type_handle, "DXSavedFrameBuffer8", SavedFrameBuffer::get_class_type()); } virtual TypeHandle get_type() const { @@ -58,7 +58,7 @@ private: static TypeHandle _type_handle; }; -#include "dxSavedFrameBuffer8.I" +#include "DXSavedFrameBuffer8.I" #endif diff --git a/panda/src/dxgsg8/dxTextureContext8.cxx b/panda/src/dxgsg8/dxTextureContext8.cxx index 79c14beb3b..6d6cb6e328 100644 --- a/panda/src/dxgsg8/dxTextureContext8.cxx +++ b/panda/src/dxgsg8/dxTextureContext8.cxx @@ -67,7 +67,7 @@ char *PandaFilterNameStrs[] = {"FT_nearest","FT_linear","FT_nearest_mipmap_neare }; -TypeHandle DXTextureContext::_type_handle; +TypeHandle DXTextureContext8::_type_handle; #define SWAPDWORDS(X,Y) { DWORD temp=X; X=Y; Y=temp; } @@ -152,7 +152,7 @@ enum Format { */ //////////////////////////////////////////////////////////////////// -// Function: DXTextureContext::get_bits_per_pixel +// Function: DXTextureContext8::get_bits_per_pixel // Access: Protected // Description: Maps from the PixelBuffer's Format symbols // to bpp. returns # of alpha bits @@ -160,7 +160,7 @@ enum Format { // not the stored format, which is indicated by pixelbuffer type //////////////////////////////////////////////////////////////////// -unsigned int DXTextureContext:: +unsigned int DXTextureContext8:: get_bits_per_pixel(PixelBuffer::Format format, int *alphbits) { *alphbits = 0; // assume no alpha bits switch(format) { @@ -725,7 +725,7 @@ HRESULT ConvertD3DSurftoPixBuf(RECT &SrcRect,IDirect3DSurface8 *pD3DSurf8,PixelB BYTE *pbuf=pixbuf->_image.p(); if(IsBadWritePtr(pD3DSurf8,sizeof(DWORD))) { - dxgsg_cat.error() << "ConvertDDSurftoPixBuf failed: bad pD3DSurf ptr value (" << ((void*)pD3DSurf8) << ")\n"; + dxgsg8_cat.error() << "ConvertDDSurftoPixBuf failed: bad pD3DSurf ptr value (" << ((void*)pD3DSurf8) << ")\n"; exit(1); } @@ -745,14 +745,14 @@ HRESULT ConvertD3DSurftoPixBuf(RECT &SrcRect,IDirect3DSurface8 *pD3DSurf8,PixelB // or scanlines will be too long if(!((dwCopyWidth==pixbuf->get_xsize()) && (dwCopyHeight<=(DWORD)pixbuf->get_ysize()))) { - dxgsg_cat.error() << "ConvertDDSurftoPixBuf, PixBuf size too small to hold display surface!\n"; + dxgsg8_cat.error() << "ConvertDDSurftoPixBuf, PixBuf size too small to hold display surface!\n"; assert(0); return E_FAIL; } hr = pD3DSurf8->LockRect(&LockedRect,(CONST RECT*)NULL,(D3DLOCK_READONLY | D3DLOCK_NO_DIRTY_UPDATE /* | D3DLOCK_NOSYSLOCK */)); if(FAILED(hr)) { - dxgsg_cat.error() << "ConvertDDSurftoPixBuf LockRect() failed!" << D3DERRORSTRING(hr); + dxgsg8_cat.error() << "ConvertDDSurftoPixBuf LockRect() failed!" << D3DERRORSTRING(hr); return hr; } @@ -768,8 +768,8 @@ HRESULT ConvertD3DSurftoPixBuf(RECT &SrcRect,IDirect3DSurface8 *pD3DSurf8,PixelB // writes out last line in DDSurf first in PixelBuf, so Y line order precedes inversely - if(dxgsg_cat.is_debug()) { - dxgsg_cat.debug() << "ConvertD3DSurftoPixBuf converting " << D3DFormatStr(SurfDesc.Format) << "bpp DDSurf to " + if(dxgsg8_cat.is_debug()) { + dxgsg8_cat.debug() << "ConvertD3DSurftoPixBuf converting " << D3DFormatStr(SurfDesc.Format) << "bpp DDSurf to " << dwNumComponents << "-channel panda PixelBuffer\n"; } @@ -970,7 +970,7 @@ HRESULT ConvertD3DSurftoPixBuf(RECT &SrcRect,IDirect3DSurface8 *pD3DSurf8,PixelB } default: - dxgsg_cat.error() << "ConvertD3DSurftoPixBuf: unsupported D3DFORMAT!\n"; + dxgsg8_cat.error() << "ConvertD3DSurftoPixBuf: unsupported D3DFORMAT!\n"; } pD3DSurf8->UnlockRect(); @@ -983,7 +983,7 @@ HRESULT ConvertD3DSurftoPixBuf(RECT &SrcRect,IDirect3DSurface8 *pD3DSurf8,PixelB // This code gets the attributes of the texture from the bitmap, creates the // texture, and then copies the bitmap into the texture. //----------------------------------------------------------------------------- -IDirect3DTexture8 *DXTextureContext::CreateTexture(DXScreenData &scrn) { +IDirect3DTexture8 *DXTextureContext8::CreateTexture(DXScreenData &scrn) { HRESULT hr; int cNumAlphaBits; // number of alpha bits in texture pixfmt D3DFORMAT TargetPixFmt=D3DFMT_UNKNOWN; @@ -1001,7 +1001,7 @@ IDirect3DTexture8 *DXTextureContext::CreateTexture(DXScreenData &scrn) { assert(pixbuf_type==PixelBuffer::T_unsigned_byte); // cant handle anything else now if((pixbuf_type!=PixelBuffer::T_unsigned_byte) || (pbuf->get_component_width()!=1)) { - dxgsg_cat.error() << "CreateTexture failed, havent handled non 8-bit channel pixelbuffer types yet! \n"; + dxgsg8_cat.error() << "CreateTexture failed, havent handled non 8-bit channel pixelbuffer types yet! \n"; return NULL; } @@ -1016,7 +1016,7 @@ IDirect3DTexture8 *DXTextureContext::CreateTexture(DXScreenData &scrn) { if(cNumAlphaBits>0) { if(cNumColorChannels==3) { - dxgsg_cat.error() << "ERROR: texture " << _tex->get_name() << " has no inherent alpha channel, but alpha format is requested (that would be wasteful)!\n"; + dxgsg8_cat.error() << "ERROR: texture " << _tex->get_name() << " has no inherent alpha channel, but alpha format is requested (that would be wasteful)!\n"; exit(1); } } @@ -1053,7 +1053,7 @@ IDirect3DTexture8 *DXTextureContext::CreateTexture(DXScreenData &scrn) { DWORD TargetHeight=dwOrigHeight; if(!ISPOW2(dwOrigWidth) || !ISPOW2(dwOrigHeight)) { - dxgsg_cat.error() << "ERROR: texture dimensions are not a power of 2 for " << _tex->get_name() << "! Please rescale them so it doesnt have to be done at runtime.\n"; + dxgsg8_cat.error() << "ERROR: texture dimensions are not a power of 2 for " << _tex->get_name() << "! Please rescale them so it doesnt have to be done at runtime.\n"; #ifndef NDEBUG exit(1); // want to catch badtexsize errors #else @@ -1066,7 +1066,7 @@ IDirect3DTexture8 *DXTextureContext::CreateTexture(DXScreenData &scrn) { if((dwOrigWidth>scrn.d3dcaps.MaxTextureWidth)||(dwOrigHeight>scrn.d3dcaps.MaxTextureHeight)) { #ifdef _DEBUG - dxgsg_cat.error() << "WARNING: " <<_tex->get_name() << ": Image size exceeds max texture dimensions of (" << scrn.d3dcaps.MaxTextureWidth << "," << scrn.d3dcaps.MaxTextureHeight << ") !!\n" + dxgsg8_cat.error() << "WARNING: " <<_tex->get_name() << ": Image size exceeds max texture dimensions of (" << scrn.d3dcaps.MaxTextureWidth << "," << scrn.d3dcaps.MaxTextureHeight << ") !!\n" << "Scaling "<< _tex->get_name() << " ("<< dwOrigWidth<<"," < ("<< scrn.d3dcaps.MaxTextureWidth << "," << scrn.d3dcaps.MaxTextureHeight << ") !\n"; #endif @@ -1087,7 +1087,7 @@ IDirect3DTexture8 *DXTextureContext::CreateTexture(DXScreenData &scrn) { bShrinkOriginal=true; #ifdef _DEBUG - dxgsg_cat.debug() << "Scaling "<< _tex->get_name() << " ("<< dwOrigWidth<<"," < ("<< TargetWidth<<"," << TargetHeight << ") to meet HW square texture reqmt\n"; + dxgsg8_cat.debug() << "Scaling "<< _tex->get_name() << " ("<< dwOrigWidth<<"," < ("<< TargetWidth<<"," << TargetHeight << ") to meet HW square texture reqmt\n"; #endif } /* @@ -1109,10 +1109,10 @@ IDirect3DTexture8 *DXTextureContext::CreateTexture(DXScreenData &scrn) { char *szErrorMsg; - szErrorMsg = "CreateTexture failed: couldn't find compatible device Texture Pixel Format for input texture: "; + szErrorMsg = "CreateTexture failed: couldn't find compatible device Texture Pixel Format for input texture"; - if(dxgsg_cat.is_spam()) - dxgsg_cat.spam() << "CreateTexture handling target bitdepth: " << target_bpp << " alphabits: " << cNumAlphaBits << endl; + if(dxgsg8_cat.is_spam()) + dxgsg8_cat.spam() << "CreateTexture handling target bitdepth: " << target_bpp << " alphabits: " << cNumAlphaBits << endl; // I could possibly replace some of this logic with D3DXCheckTextureRequirements(), but // it wouldnt handle all my specialized low-memory cases perfectly @@ -1298,7 +1298,7 @@ IDirect3DTexture8 *DXTextureContext::CreateTexture(DXScreenData &scrn) { } // if we've gotten here, haven't found a match - dxgsg_cat.error() << szErrorMsg << ": " << _tex->get_name() << endl + dxgsg8_cat.error() << szErrorMsg << ": " << _tex->get_name() << endl << "NumColorChannels: " <get_name() << "]\n"; + dxgsg8_cat.spam() << "Forcing trilinear mipmapping on DX texture [" << _tex->get_name() << "]\n"; } ft = Texture::FT_linear_mipmap_linear; _tex->set_minfilter(ft); @@ -1397,7 +1397,7 @@ IDirect3DTexture8 *DXTextureContext::CreateTexture(DXScreenData &scrn) { _tex->set_anisotropic_degree(aniso_degree); #ifdef _DEBUG - dxgsg_cat.spam() << "CreateTexture: setting aniso degree for "<< _tex->get_name() << " to: " << aniso_degree << endl; + dxgsg8_cat.spam() << "CreateTexture: setting aniso degree for "<< _tex->get_name() << " to: " << aniso_degree << endl; #endif UINT cMipLevelCount; @@ -1405,13 +1405,13 @@ IDirect3DTexture8 *DXTextureContext::CreateTexture(DXScreenData &scrn) { if(_bHasMipMaps) { cMipLevelCount=0; // tell CreateTex to alloc space for all mip levels down to 1x1 - if(dxgsg_cat.is_debug()) - dxgsg_cat.debug() << "CreateTexture: generating mipmaps for "<< _tex->get_name() << endl; + if(dxgsg8_cat.is_debug()) + dxgsg8_cat.debug() << "CreateTexture: generating mipmaps for "<< _tex->get_name() << endl; } else cMipLevelCount=1; if(FAILED( hr = scrn.pD3DDevice->CreateTexture(TargetWidth,TargetHeight,cMipLevelCount,0x0, TargetPixFmt,D3DPOOL_MANAGED,&_pD3DTexture8) )) { - dxgsg_cat.error() << "pD3DDevice->CreateTexture() failed!" << D3DERRORSTRING(hr); + dxgsg8_cat.error() << "pD3DDevice->CreateTexture() failed!" << D3DERRORSTRING(hr); goto error_exit; } @@ -1421,9 +1421,9 @@ IDirect3DTexture8 *DXTextureContext::CreateTexture(DXScreenData &scrn) { #ifdef _DEBUG #ifdef DO_CUSTOM_CONVERSIONS - dxgsg_cat.debug() << "CreateTexture: "<< _tex->get_name() <<" converting " << ConvNameStrs[ConvNeeded] << " \n"; + dxgsg8_cat.debug() << "CreateTexture: "<< _tex->get_name() <<" converting " << ConvNameStrs[ConvNeeded] << " \n"; #else - dxgsg_cat.debug() << "CreateTexture: "<< _tex->get_name() <<" converting panda equivalent of " << D3DFormatStr(_PixBufD3DFmt) << " => " << D3DFormatStr(TargetPixFmt) << endl; + dxgsg8_cat.debug() << "CreateTexture: "<< _tex->get_name() <<" converting panda equivalent of " << D3DFormatStr(_PixBufD3DFmt) << " => " << D3DFormatStr(TargetPixFmt) << endl; #endif #endif @@ -1439,23 +1439,23 @@ IDirect3DTexture8 *DXTextureContext::CreateTexture(DXScreenData &scrn) { error_exit: - RELEASE(_pD3DTexture8,dxgsg,"texture",RELEASE_ONCE); + RELEASE(_pD3DTexture8,dxgsg8,"texture",RELEASE_ONCE); return NULL; } -HRESULT DXTextureContext:: +HRESULT DXTextureContext8:: FillDDSurfTexturePixels(void) { HRESULT hr=E_FAIL; assert(IS_VALID_PTR(_texture)); if(!_texture->has_ram_image()) { - dxgsg_cat.warning() << "CreateTexture: tried to fill surface that has no ram image!\n"; + dxgsg8_cat.warning() << "CreateTexture: tried to fill surface that has no ram image!\n"; return S_OK; } PixelBuffer *pbuf = _texture->get_ram_image(); if (pbuf == (PixelBuffer *)NULL) { - dxgsg_cat.fatal() << "CreateTexture: get_ram_image() failed\n"; + dxgsg8_cat.fatal() << "CreateTexture: get_ram_image() failed\n"; // The texture doesn't have an image to load. return E_FAIL; } @@ -1473,7 +1473,7 @@ FillDDSurfTexturePixels(void) { IDirect3DSurface8 *pMipLevel0; hr=_pD3DTexture8->GetSurfaceLevel(0,&pMipLevel0); if(FAILED(hr)) { - dxgsg_cat.error() << "FillDDSurfaceTexturePixels failed for "<< _tex->get_name() <<", GetSurfaceLevel failed" << D3DERRORSTRING(hr); + dxgsg8_cat.error() << "FillDDSurfaceTexturePixels failed for "<< _tex->get_name() <<", GetSurfaceLevel failed" << D3DERRORSTRING(hr); return E_FAIL; } @@ -1496,7 +1496,7 @@ FillDDSurfTexturePixels(void) { // alloc buffer for explicit D3DFMT_A8L8 USHORT *pTempPixBuf=new USHORT[OrigWidth*OrigHeight]; if(!IS_VALID_PTR(pTempPixBuf)) { - dxgsg_cat.error() << "FillDDSurfaceTexturePixels couldnt alloc mem for temp pixbuf!\n"; + dxgsg8_cat.error() << "FillDDSurfaceTexturePixels couldnt alloc mem for temp pixbuf!\n"; goto exit_FillDDSurf; } bUsingTempPixBuf=true; @@ -1516,7 +1516,7 @@ FillDDSurfTexturePixels(void) { hr=D3DXLoadSurfaceFromMemory(pMipLevel0,(PALETTEENTRY*)NULL,(RECT*)NULL,(LPCVOID)pPixels,SrcFormat, SrcPixBufRowByteLength,(PALETTEENTRY*)NULL,&SrcSize,Lev0Filter,(D3DCOLOR)0x0); if(FAILED(hr)) { - dxgsg_cat.error() << "FillDDSurfaceTexturePixels failed for "<< _tex->get_name() <<", D3DXLoadSurfFromMem failed" << D3DERRORSTRING(hr); + dxgsg8_cat.error() << "FillDDSurfaceTexturePixels failed for "<< _tex->get_name() <<", D3DXLoadSurfFromMem failed" << D3DERRORSTRING(hr); goto exit_FillDDSurf; } @@ -1529,7 +1529,7 @@ FillDDSurfTexturePixels(void) { hr=D3DXFilterTexture(_pD3DTexture8,(PALETTEENTRY*)NULL,0,MipFilterFlags); if(FAILED(hr)) { - dxgsg_cat.error() << "FillDDSurfaceTexturePixels failed for "<< _tex->get_name() <<", D3DXFilterTex failed" << D3DERRORSTRING(hr); + dxgsg8_cat.error() << "FillDDSurfaceTexturePixels failed for "<< _tex->get_name() <<", D3DXFilterTex failed" << D3DERRORSTRING(hr); goto exit_FillDDSurf; } } @@ -1538,7 +1538,7 @@ FillDDSurfTexturePixels(void) { if(bUsingTempPixBuf) { SAFE_DELETE_ARRAY(pPixels); } - RELEASE(pMipLevel0,dxgsg,"texture",RELEASE_ONCE); + RELEASE(pMipLevel0,dxgsg8,"texture",RELEASE_ONCE); return hr; } @@ -1548,13 +1548,13 @@ FillDDSurfTexturePixels(void) { // Name: DeleteTexture() // Desc: Release the surface used to store the texture //----------------------------------------------------------------------------- -void DXTextureContext:: +void DXTextureContext8:: DeleteTexture( ) { - if(dxgsg_cat.is_spam()) { - dxgsg_cat.spam() << "Deleting DX texture for " << _tex->get_name() << "\n"; + if(dxgsg8_cat.is_spam()) { + dxgsg8_cat.spam() << "Deleting DX texture for " << _tex->get_name() << "\n"; } - RELEASE(_pD3DTexture8,dxgsg,"texture",RELEASE_ONCE); + RELEASE(_pD3DTexture8,dxgsg8,"texture",RELEASE_ONCE); /* #ifdef DEBUG_RELEASES if(_surface) { @@ -1563,28 +1563,28 @@ DeleteTexture( ) { pDD->Release(); PRINTREFCNT(pDD,"before DeleteTex, IDDraw7"); - RELEASE(_surface,dxgsg,"texture",false); + RELEASE(_surface,dxgsg8,"texture",false); PRINTREFCNT(pDD,"after DeleteTex, IDDraw7"); } #else - RELEASE(_pD3DSurf8,dxgsg,"texture",false); + RELEASE(_pD3DSurf8,dxgsg8,"texture",false); #endif */ } //////////////////////////////////////////////////////////////////// -// Function: DXTextureContext::Constructor +// Function: DXTextureContext8::Constructor // Access: Public // Description: //////////////////////////////////////////////////////////////////// -DXTextureContext:: -DXTextureContext(Texture *tex) : +DXTextureContext8:: +DXTextureContext8(Texture *tex) : TextureContext(tex) { - if(dxgsg_cat.is_spam()) { - dxgsg_cat.spam() << "Creating DX texture [" << tex->get_name() << "], minfilter(" << PandaFilterNameStrs[tex->get_minfilter()] << "), magfilter("<get_magfilter()] << "), anisodeg(" << tex->get_anisotropic_degree() << ")\n"; + if(dxgsg8_cat.is_spam()) { + dxgsg8_cat.spam() << "Creating DX texture [" << tex->get_name() << "], minfilter(" << PandaFilterNameStrs[tex->get_minfilter()] << "), magfilter("<get_magfilter()] << "), anisodeg(" << tex->get_anisotropic_degree() << ")\n"; } _pD3DTexture8 = NULL; @@ -1592,8 +1592,8 @@ TextureContext(tex) { _tex = tex; } -DXTextureContext:: -~DXTextureContext() { +DXTextureContext8:: +~DXTextureContext8() { DeleteTexture(); TextureContext::~TextureContext(); _tex = NULL; diff --git a/panda/src/dxgsg8/dxTextureContext8.h b/panda/src/dxgsg8/dxTextureContext8.h index d4d58fab14..3ff2bcaf82 100644 --- a/panda/src/dxgsg8/dxTextureContext8.h +++ b/panda/src/dxgsg8/dxTextureContext8.h @@ -1,4 +1,4 @@ -// Filename: dxTextureContext.h +// Filename: dxTextureContext8.h // Created by: drose (07Oct99) // //////////////////////////////////////////////////////////////////// @@ -16,26 +16,26 @@ // //////////////////////////////////////////////////////////////////// -#ifndef DXTEXTURECONTEXT_H -#define DXTEXTURECONTEXT_H +#ifndef DXTEXTURECONTEXT8_H +#define DXTEXTURECONTEXT8_H #include "dxgsg8base.h" -#include -#include +#include "texture.h" +#include "textureContext.h" //#define DO_CUSTOM_CONVERSIONS //////////////////////////////////////////////////////////////////// -// Class : DXTextureContext +// Class : DXTextureContext8 // Description : //////////////////////////////////////////////////////////////////// -class EXPCL_PANDADX DXTextureContext : public TextureContext { +class EXPCL_PANDADX DXTextureContext8 : public TextureContext { friend class DXGraphicsStateGuardian; friend class wdxGraphicsWindow; public: - DXTextureContext(Texture *tex); - ~DXTextureContext(); + DXTextureContext8(Texture *tex); + ~DXTextureContext8(); IDirect3DTexture8 *_pD3DTexture8; Texture *_tex; // ptr to parent, primarily for access to namestr @@ -62,7 +62,7 @@ public: } static void init_type() { TextureContext::init_type(); - register_type(_type_handle, "DXTextureContext", + register_type(_type_handle, "DXTextureContext8", TextureContext::get_class_type()); } virtual TypeHandle get_type() const { diff --git a/panda/src/dxgsg8/dxgsg8_composite1.cxx b/panda/src/dxgsg8/dxgsg8_composite1.cxx index b73e8772fe..5ad1814a9f 100644 --- a/panda/src/dxgsg8/dxgsg8_composite1.cxx +++ b/panda/src/dxgsg8/dxgsg8_composite1.cxx @@ -3,3 +3,5 @@ #include "dxTextureContext8.cxx" #include "dxGeomNodeContext8.cxx" #include "d3dfont8.cxx" +#include "wdxGraphicsPipe8.cxx" +#include "wdxGraphicsWindow8.cxx" diff --git a/panda/src/dxgsg8/dxgsg8base.h b/panda/src/dxgsg8/dxgsg8base.h index 48a0d97447..8e19322a87 100644 --- a/panda/src/dxgsg8/dxgsg8base.h +++ b/panda/src/dxgsg8/dxgsg8base.h @@ -186,7 +186,6 @@ typedef struct { LPDIRECT3D8 pD3D8; HWND hWnd; HMONITOR hMon; - GraphicsWindow::Properties *pProps; // can get window rect here (or from GetWindowRect(hWnd), can also get window size in PresParams DWORD MaxAvailVidMem; ushort CardIDNum; // adapter ID ushort depth_buffer_bitdepth; //GetSurfaceDesc is not reliable so must store this explicitly diff --git a/panda/src/sgiglutdisplay/config_sgiglutdisplay.h b/panda/src/dxgsg8/wdxGraphicsPipe8.I similarity index 68% rename from panda/src/sgiglutdisplay/config_sgiglutdisplay.h rename to panda/src/dxgsg8/wdxGraphicsPipe8.I index a78ee5318e..a0c8959cad 100644 --- a/panda/src/sgiglutdisplay/config_sgiglutdisplay.h +++ b/panda/src/dxgsg8/wdxGraphicsPipe8.I @@ -1,5 +1,5 @@ -// Filename: config_sgiglutdisplay.h -// Created by: cary (07Oct99) +// Filename: wdxGraphicsPipe8.I +// Created by: drose (20Dec02) // //////////////////////////////////////////////////////////////////// // @@ -15,13 +15,3 @@ // panda3d@yahoogroups.com . // //////////////////////////////////////////////////////////////////// - -#ifndef CONFIG_SGIGLUTDISPLAY_H -#define CONFIG_SGIGLUTDISPLAY_H - -#include -#include - -NotifyCategoryDecl(sgiglutdisplay, EXPCL_PANDAGL, EXPTP_PANDAGL); - -#endif diff --git a/panda/src/dxgsg8/wdxGraphicsPipe8.cxx b/panda/src/dxgsg8/wdxGraphicsPipe8.cxx new file mode 100644 index 0000000000..01d5ab201a --- /dev/null +++ b/panda/src/dxgsg8/wdxGraphicsPipe8.cxx @@ -0,0 +1,339 @@ +// Filename: wdxGraphicsPipe8.cxx +// Created by: drose (20Dec02) +// +//////////////////////////////////////////////////////////////////// +// +// 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 "wdxGraphicsPipe8.h" +#include "wdxGraphicsWindow8.h" +#include "config_dxgsg8.h" + +TypeHandle wdxGraphicsPipe8::_type_handle; + +// #define LOWVIDMEMTHRESHOLD 3500000 +// #define CRAPPY_DRIVER_IS_LYING_VIDMEMTHRESHOLD 1000000 +#define LOWVIDMEMTHRESHOLD 5700000 // 4MB cards should fall below this +#define CRAPPY_DRIVER_IS_LYING_VIDMEMTHRESHOLD 1000000 // if # is > 1MB, card is lying and I cant tell what it is + +#define UNKNOWN_VIDMEM_SIZE 0xFFFFFFFF + +//////////////////////////////////////////////////////////////////// +// Function: wdxGraphicsPipe8::Constructor +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +wdxGraphicsPipe8:: +wdxGraphicsPipe8() { + _hDDrawDLL = NULL; + _hD3D8_DLL = NULL; + _is_valid = init(); +} + +//////////////////////////////////////////////////////////////////// +// Function: wdxGraphicsPipe8::Destructor +// Access: Public, Virtual +// Description: +//////////////////////////////////////////////////////////////////// +wdxGraphicsPipe8:: +~wdxGraphicsPipe8() { + if (_hDDrawDLL != NULL) { + FreeLibrary(_hDDrawDLL); + _hDDrawDLL = NULL; + } + if(_hD3D8_DLL != NULL) { + FreeLibrary(_hD3D8_DLL); + _hD3D8_DLL = NULL; + } +} + +//////////////////////////////////////////////////////////////////// +// Function: wdxGraphicsPipe8::pipe_constructor +// Access: Public, Static +// Description: This function is passed to the GraphicsPipeSelection +// object to allow the user to make a default +// wdxGraphicsPipe8. +//////////////////////////////////////////////////////////////////// +PT(GraphicsPipe) wdxGraphicsPipe8:: +pipe_constructor() { + return new wdxGraphicsPipe8; +} + +//////////////////////////////////////////////////////////////////// +// Function: wdxGraphicsPipe8::make_window +// Access: Protected, Virtual +// Description: Creates a new window on the pipe, if possible. +//////////////////////////////////////////////////////////////////// +PT(GraphicsWindow) wdxGraphicsPipe8:: +make_window() { + if (!_is_valid) { + return NULL; + } + + return new wdxGraphicsWindow8(this); +} + +//////////////////////////////////////////////////////////////////// +// Function: wdxGraphicsPipe8::init +// Access: Private +// Description: Performs some initialization steps to load up +// function pointers from the relevant DLL's, and +// determine the number and type of available graphics +// adapters, etc. Returns true on success, false on +// failure. +//////////////////////////////////////////////////////////////////// +bool wdxGraphicsPipe8:: +init() { + static const char * const ddraw_name = "ddraw.dll"; + _hDDrawDLL = LoadLibrary(ddraw_name); + if(_hDDrawDLL == 0) { + wdxdisplay8_cat.error() + << "can't locate " << ddraw_name << "!\n"; + return false; + } + + _DirectDrawCreateEx = + (LPDIRECTDRAWCREATEEX)GetProcAddress(_hDDrawDLL, "DirectDrawCreateEx"); + if (_DirectDrawCreateEx == NULL) { + wdxdisplay8_cat.error() + << "GetProcAddr failed for DDCreateEx" << endl; + return false; + } + + _DirectDrawEnumerateExA = (LPDIRECTDRAWENUMERATEEX)GetProcAddress(_hDDrawDLL, "DirectDrawEnumerateExA"); + if (_DirectDrawEnumerateExA == NULL) { + wdxdisplay8_cat.error() + << "GetProcAddr failed for DirectDrawEnumerateEx! (win95 system?)\n"; + return false; + } + + static const char * const d3d8_name = "d3d8.dll"; + _hD3D8_DLL = LoadLibrary(d3d8_name); + if (_hD3D8_DLL == 0) { + wdxdisplay8_cat.error() + << "PandaDX8 requires DX8, can't locate " << d3d8_name << "!\n"; + return false; + } + + // dont want to statically link to possibly non-existent d3d8 dll, + // so must call D3DCr8 indirectly + static const char * const d3dcreate8_name = "Direct3DCreate8"; + _Direct3DCreate8 = + (Direct3DCreate8_ProcPtr)GetProcAddress(_hD3D8_DLL, d3dcreate8_name); + + if (_Direct3DCreate8 == NULL) { + wdxdisplay8_cat.error() + << "GetProcAddress for " << d3dcreate8_name << "failed!" << endl; + return false; + } + + return find_all_card_memavails(); +} + +//////////////////////////////////////////////////////////////////// +// Function: wdxGraphicsPipe8::find_all_card_memavails +// Access: Private +// Description: Uses DX7 calls to determine how much video memory is +// available for each video adapter in the system. +// Returns true on success, false on failure. +//////////////////////////////////////////////////////////////////// +bool wdxGraphicsPipe8:: +find_all_card_memavails() { + HRESULT hr; + + hr = (*_DirectDrawEnumerateExA)(dx7_driver_enum_callback, this, + DDENUM_ATTACHEDSECONDARYDEVICES | DDENUM_NONDISPLAYDEVICES); + if (FAILED(hr)) { + wdxdisplay8_cat.fatal() + << "DirectDrawEnumerateEx failed" << D3DERRORSTRING(hr); + return false; + } + + if (_card_ids.empty()) { + wdxdisplay8_cat.error() + << "DirectDrawEnumerateEx enum'ed no devices!\n"; + return false; + } + + GUID ZeroGUID; + ZeroMemory(&ZeroGUID, sizeof(GUID)); + + if (_card_ids.size() > 1) { + assert(IsEqualGUID(ZeroGUID, _card_ids[0].DX7_DeviceGUID)); + // delete enum of primary display (always the first), since it is + // duplicated by explicit entry + _card_ids.erase(_card_ids.begin()); + } + + for (UINT i=0; i < _card_ids.size(); i++) { + LPDIRECTDRAW7 pDD; + BYTE ddd_space[sizeof(DDDEVICEIDENTIFIER2)+4]; //bug in DX7 requires 4 extra bytes for GetDeviceID + DDDEVICEIDENTIFIER2 *pDX7DeviceID=(DDDEVICEIDENTIFIER2 *)&ddd_space[0]; + GUID *pGUID= &(_card_ids[i].DX7_DeviceGUID); + + if (IsEqualGUID(*pGUID, ZeroGUID)) { + pGUID=NULL; + } + + // Create the Direct Draw Object + hr = (*_DirectDrawCreateEx)(pGUID,(void **)&pDD, IID_IDirectDraw7, NULL); + if (FAILED(hr)) { + wdxdisplay8_cat.error() + << "DirectDrawCreateEx failed for device (" << i + << ")" << D3DERRORSTRING(hr); + continue; + } + + ZeroMemory(ddd_space, sizeof(DDDEVICEIDENTIFIER2)); + + hr = pDD->GetDeviceIdentifier(pDX7DeviceID, 0x0); + if (FAILED(hr)) { + wdxdisplay8_cat.error() + << "GetDeviceID failed for device ("<< i << ")" << D3DERRORSTRING(hr); + continue; + } + + _card_ids[i].DeviceID = pDX7DeviceID->dwDeviceId; + _card_ids[i].VendorID = pDX7DeviceID->dwVendorId; + + // Get Current VidMem avail. Note this is only an estimate, when + // we switch to fullscreen mode from desktop, more vidmem will be + // available (typically 1.2 meg). I dont want to switch to + // fullscreen more than once due to the annoying monitor flicker, + // so try to figure out optimal mode using this estimate + DDSCAPS2 ddsGAVMCaps; + DWORD dwVidMemTotal,dwVidMemFree; + dwVidMemTotal=dwVidMemFree=0; + { + // print out total INCLUDING AGP just for information purposes + // and future use. The real value I'm interested in for + // purposes of measuring possible valid screen sizes shouldnt + // include AGP. + ZeroMemory(&ddsGAVMCaps, sizeof(DDSCAPS2)); + ddsGAVMCaps.dwCaps = DDSCAPS_VIDEOMEMORY; + + hr = pDD->GetAvailableVidMem(&ddsGAVMCaps, &dwVidMemTotal, &dwVidMemFree); + if (FAILED(hr)) { + wdxdisplay8_cat.error() + << "GetAvailableVidMem failed for device #" << i + << D3DERRORSTRING(hr); + // goto skip_device; + exit(1); // probably want to exit, since it may be my fault + } + } + + wdxdisplay8_cat.info() + << "GetAvailableVidMem (including AGP) returns Total: " + << dwVidMemTotal <<", Free: " << dwVidMemFree + << " for device #" << i << endl; + + ZeroMemory(&ddsGAVMCaps, sizeof(DDSCAPS2)); + + // just want to measure localvidmem, not AGP texmem + ddsGAVMCaps.dwCaps = DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM; + + hr = pDD->GetAvailableVidMem(&ddsGAVMCaps, &dwVidMemTotal, &dwVidMemFree); + if (FAILED(hr)) { + wdxdisplay8_cat.error() + << "GetAvailableVidMem failed for device #"<< i<< D3DERRORSTRING(hr); + // goto skip_device; + exit(1); // probably want to exit, since it may be my fault + } + + wdxdisplay8_cat.info() + << "GetAvailableVidMem (no AGP) returns Total: " << dwVidMemTotal + << ", Free: " << dwVidMemFree << " for device #"<< i<< endl; + + pDD->Release(); // release DD obj, since this is all we needed it for + + if (!dx_do_vidmemsize_check) { + // still calling the DD stuff to get deviceID, etc. is this necessary? + _card_ids[i].MaxAvailVidMem = UNKNOWN_VIDMEM_SIZE; + _card_ids[i].bIsLowVidMemCard = false; + continue; + } + + if (dwVidMemTotal == 0) { // unreliable driver + dwVidMemTotal = UNKNOWN_VIDMEM_SIZE; + } else { + if (!ISPOW2(dwVidMemTotal)) { + // assume they wont return a proper max value, so + // round up to next pow of 2 + UINT count=0; + while ((dwVidMemTotal >> count) != 0x0) { + count++; + } + dwVidMemTotal = (1 << count); + } + } + + // after SetDisplayMode, GetAvailVidMem totalmem seems to go down + // by 1.2 meg (contradicting above comment and what I think would + // be correct behavior (shouldnt FS mode release the desktop + // vidmem?), so this is the true value + _card_ids[i].MaxAvailVidMem = dwVidMemTotal; + + // I can never get this stuff to work reliably, so I'm just + // rounding up to nearest pow2. Could try to get + // HardwareInformation.Memory_size MB number from registry like + // video control panel, but its not clear how to find the proper + // registry location for a given card + + // assume buggy drivers (this means you, FireGL2) may return zero + // (or small amts) for dwVidMemTotal, so ignore value if its < + // CRAPPY_DRIVER_IS_LYING_VIDMEMTHRESHOLD + bool bLowVidMemFlag = + ((dwVidMemTotal > CRAPPY_DRIVER_IS_LYING_VIDMEMTHRESHOLD) && + (dwVidMemTotal< LOWVIDMEMTHRESHOLD)); + + _card_ids[i].bIsLowVidMemCard = bLowVidMemFlag; + wdxdisplay8_cat.info() + << "SetLowVidMem flag to " << bLowVidMemFlag + << " based on adjusted VidMemTotal: " << dwVidMemTotal << endl; + } + return true; +} + +//////////////////////////////////////////////////////////////////// +// Function: wdxGraphicsPipe8::dx7_driver_enum_callback +// Access: Private, Static +// Description: +//////////////////////////////////////////////////////////////////// +BOOL WINAPI wdxGraphicsPipe8:: +dx7_driver_enum_callback(GUID *pGUID, TCHAR *strDesc, TCHAR *strName, + VOID *argptr, HMONITOR hm) { + // #define PRNT(XX) ((XX!=NULL) ? XX : "NULL") + // cout << "strDesc: "<< PRNT(strDesc) << " strName: "<< PRNT(strName)<_card_ids.push_back(card_id); + + return DDENUMRET_OK; +} diff --git a/panda/src/dxgsg8/wdxGraphicsPipe8.h b/panda/src/dxgsg8/wdxGraphicsPipe8.h new file mode 100644 index 0000000000..fffe66e652 --- /dev/null +++ b/panda/src/dxgsg8/wdxGraphicsPipe8.h @@ -0,0 +1,109 @@ +// Filename: wdxGraphicsPipe8.h +// Created by: drose (20Dec02) +// +//////////////////////////////////////////////////////////////////// +// +// 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 WDXGRAPHICSPIPE8_H +#define WDXGRAPHICSPIPE8_H + +#include "pandabase.h" +#include "winGraphicsPipe.h" +#include "pvector.h" + +#include + +typedef struct { + UINT cardID; + char szDriver[MAX_DEVICE_IDENTIFIER_STRING]; + char szDescription[MAX_DEVICE_IDENTIFIER_STRING]; + GUID guidDeviceIdentifier; + DWORD VendorID, DeviceID; + HMONITOR hMon; +} DXDeviceInfo; +typedef pvector DXDeviceInfoVec; + +//////////////////////////////////////////////////////////////////// +// Class : wdxGraphicsPipe8 +// Description : This graphics pipe represents the interface for +// creating DirectX graphics windows. +//////////////////////////////////////////////////////////////////// +class EXPCL_PANDADX wdxGraphicsPipe8 : public WinGraphicsPipe { +public: + wdxGraphicsPipe8(); + virtual ~wdxGraphicsPipe8(); + + static PT(GraphicsPipe) pipe_constructor(); + +protected: + virtual PT(GraphicsWindow) make_window(); + +private: + bool init(); + bool find_all_card_memavails(); + + static BOOL WINAPI + dx7_driver_enum_callback(GUID *pGUID, TCHAR *strDesc, TCHAR *strName, + VOID *argptr, HMONITOR hm); + +private: + HINSTANCE _hDDrawDLL; + HINSTANCE _hD3D8_DLL; + bool _is_valid; + + typedef LPDIRECT3D8 (WINAPI *Direct3DCreate8_ProcPtr)(UINT SDKVersion); + typedef HRESULT (WINAPI * LPDIRECTDRAWCREATEEX)(GUID FAR * lpGuid, LPVOID *lplpDD, REFIID iid, IUnknown FAR *pUnkOuter); + + LPDIRECTDRAWCREATEEX _DirectDrawCreateEx; + LPDIRECTDRAWENUMERATEEX _DirectDrawEnumerateExA; + Direct3DCreate8_ProcPtr _Direct3DCreate8; + + // CardID is used in DX7 lowmem card-classification pass so DX8 can + // establish correspondence b/w DX7 mem info & DX8 device + struct CardID { + HMONITOR hMon; + DWORD MaxAvailVidMem; + bool bIsLowVidMemCard; + GUID DX7_DeviceGUID; + DWORD VendorID, DeviceID; + // char szDriver[MAX_DEVICE_IDENTIFIER_STRING]; + }; + + typedef pvector CardIDs; + CardIDs _card_ids; + + +public: + static TypeHandle get_class_type() { + return _type_handle; + } + static void init_type() { + WinGraphicsPipe::init_type(); + register_type(_type_handle, "wdxGraphicsPipe8", + WinGraphicsPipe::get_class_type()); + } + virtual TypeHandle get_type() const { + return get_class_type(); + } + virtual TypeHandle force_init_type() {init_type(); return get_class_type();} + +private: + static TypeHandle _type_handle; + friend class wdxGraphicsWindow8; +}; + +#include "wdxGraphicsPipe8.I" + +#endif diff --git a/panda/src/dxgsg8/wdxGraphicsWindow8.I b/panda/src/dxgsg8/wdxGraphicsWindow8.I new file mode 100644 index 0000000000..0aa4597db2 --- /dev/null +++ b/panda/src/dxgsg8/wdxGraphicsWindow8.I @@ -0,0 +1,17 @@ +// Filename: wdxGraphicsWindow8.I +// Created by: drose (20Dec02) +// +//////////////////////////////////////////////////////////////////// +// +// 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 . +// +//////////////////////////////////////////////////////////////////// diff --git a/panda/src/dxgsg8/wdxGraphicsWindow8.cxx b/panda/src/dxgsg8/wdxGraphicsWindow8.cxx new file mode 100644 index 0000000000..e86d901a9e --- /dev/null +++ b/panda/src/dxgsg8/wdxGraphicsWindow8.cxx @@ -0,0 +1,1515 @@ +// Filename: wdxGraphicsWindow8.cxx +// Created by: mike (09Jan00) +// +//////////////////////////////////////////////////////////////////// +// +// 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 +#include +#include +#include +#include "wdxGraphicsWindow8.h" +#include "wdxGraphicsPipe8.h" +#include "config_dxgsg8.h" + +#include "keyboardButton.h" +#include "mouseButton.h" +#include "throw_event.h" + +#ifdef DO_PSTATS +#include "pStatTimer.h" +#endif + +#include +#include + +TypeHandle wdxGraphicsWindow8::_type_handle; + +#define LAST_ERROR 0 +#define ERRORBOX_TITLE "Panda3D Error" +#define WDX_WINDOWCLASSNAME "wdxDisplay" +#define WDX_WINDOWCLASSNAME_NOCURSOR WDX_WINDOWCLASSNAME "_NoCursor" +#define DEFAULT_CURSOR IDC_ARROW + + +// define this to enable debug testing of dinput joystick +//#define DINPUT_DEBUG_POLL + +typedef map HWND_PANDAWIN_MAP; + +HWND_PANDAWIN_MAP hwnd_pandawin_map; +wdxGraphicsWindow8* global_wdxwinptr = NULL; // need this for temporary windproc + +#define MAX_DISPLAYS 20 + +#define PAUSED_TIMER_ID 7 // completely arbitrary choice +#define JOYSTICK_POLL_TIMER_ID 8 +#define DX_IS_READY ((_dxgsg!=NULL)&&(_dxgsg->GetDXReady())) + +LONG WINAPI static_window_proc(HWND hwnd, UINT msg, WPARAM wparam,LPARAM lparam); + +// imperfect method to ID NVid? could also scan desc str, but that isnt fullproof either +#define IS_NVIDIA(DDDEVICEID) ((DDDEVICEID.VendorId==0x10DE) || (DDDEVICEID.VendorId==0x12D2)) +#define IS_ATI(DDDEVICEID) (DDDEVICEID.VendorId==0x1002) +#define IS_MATROX(DDDEVICEID) (DDDEVICEID.VendorId==0x102B) + +// because we dont have access to ModifierButtons, as a hack just synchronize state of these +// keys on get/lose keybd focus +#define NUM_MODIFIER_KEYS 16 +unsigned int hardcoded_modifier_buttons[NUM_MODIFIER_KEYS]={VK_SHIFT,VK_MENU,VK_CONTROL,VK_SPACE,VK_TAB, + VK_UP,VK_DOWN,VK_LEFT,VK_RIGHT,VK_PRIOR,VK_NEXT,VK_HOME,VK_END, + VK_INSERT,VK_DELETE,VK_ESCAPE}; + +#define UNKNOWN_VIDMEM_SIZE 0xFFFFFFFF + +// pops up MsgBox w/system error msg +#define LAST_ERROR 0 +void PrintErrorMessage(DWORD msgID) { + LPTSTR pMessageBuffer; + + if (msgID==LAST_ERROR) + msgID=GetLastError(); + + FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, + NULL,msgID, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), //The user default language + (LPTSTR) &pMessageBuffer, // the weird ptrptr->ptr cast is intentional, see FORMAT_MESSAGE_ALLOCATE_BUFFER + 1024, NULL); + MessageBox(GetDesktopWindow(),pMessageBuffer,_T(ERRORBOX_TITLE),MB_OK); + wdxdisplay8_cat.fatal() << "System error msg: " << pMessageBuffer << endl; + LocalFree( pMessageBuffer ); +} + +void ClearToBlack(HWND hWnd, const WindowProperties &props) { + // clear to black + HDC hDC=GetDC(hWnd); // GetDC is not particularly fast. if this needs to be super-quick, we should cache GetDC's hDC + RECT clrRect = { + props.get_x_origin(), props.get_y_origin(), + props.get_x_origin() + props.get_x_size(), + props.get_y_origin() + props.get_y_size() + }; + FillRect(hDC,&clrRect,(HBRUSH)GetStockObject(BLACK_BRUSH)); + ReleaseDC(hWnd,hDC); + GdiFlush(); +} + +//////////////////////////////////////////////////////////////////// +// Function: wdxGraphicsWindow8::Constructor +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +wdxGraphicsWindow8:: +wdxGraphicsWindow8(GraphicsPipe *pipe) : + WinGraphicsWindow(pipe) +{ + _dxgsg = (DXGraphicsStateGuardian8 *)NULL; + _depth_buffer_bpp = 0; + _awaiting_restore = false; +} + +//////////////////////////////////////////////////////////////////// +// Function: wdxGraphicsWindow8::Destructor +// Access: Public, Virtual +// Description: +//////////////////////////////////////////////////////////////////// +wdxGraphicsWindow8:: +~wdxGraphicsWindow8() { +} + +//////////////////////////////////////////////////////////////////// +// Function: wdxGraphicsWindow8::make_gsg +// Access: Public, Virtual +// Description: Creates a new GSG for the window and stores it in the +// _gsg pointer. This should only be called from within +// the draw thread. +//////////////////////////////////////////////////////////////////// +void wdxGraphicsWindow8:: +make_gsg() { + wdxGraphicsPipe8 *pipe8; + DCAST_INTO_V(pipe8, _pipe); + + nassertv(_gsg == (GraphicsStateGuardian *)NULL); + _dxgsg = new DXGraphicsStateGuardian8(this); + _gsg = _dxgsg; + + // Tell the associated dxGSG about the window handle. + _dxgsg->scrn.hWnd = _mwindow; + + // Create a Direct3D object. + LPDIRECT3D8 pD3D8; + + // these were taken from the 8.0 and 8.1 d3d8.h SDK headers +#define D3D_SDK_VERSION_8_0 120 +#define D3D_SDK_VERSION_8_1 220 + + // are we using 8.0 or 8.1? + WIN32_FIND_DATA TempFindData; + HANDLE hFind; + char tmppath[MAX_PATH + 128]; + GetSystemDirectory(tmppath, MAX_PATH); + strcat(tmppath, "\\dpnhpast.dll"); + hFind = FindFirstFile (tmppath, &TempFindData); + if (hFind != INVALID_HANDLE_VALUE) { + FindClose(hFind); + _dxgsg->scrn.bIsDX81 = true; + pD3D8 = (*pipe8->_Direct3DCreate8)(D3D_SDK_VERSION_8_1); + } else { + _dxgsg->scrn.bIsDX81 = false; + pD3D8 = (*pipe8->_Direct3DCreate8)(D3D_SDK_VERSION_8_0); + } + + if (pD3D8 == NULL) { + wdxdisplay8_cat.error() + << "Direct3DCreate8 failed!\n"; + release_gsg(); + return; + } + + if (!choose_adapter(pD3D8)) { + wdxdisplay8_cat.error() + << "Unable to find suitable rendering device.\n"; + release_gsg(); + return; + } + + create_screen_buffers_and_device(_dxgsg->scrn, dx_force_16bpp_zbuffer); +} + +//////////////////////////////////////////////////////////////////// +// Function: wdxGraphicsWindow8::release_gsg +// Access: Public, Virtual +// Description: Releases the current GSG pointer, if it is currently +// held, and resets the GSG to NULL. This should only +// be called from within the draw thread. +//////////////////////////////////////////////////////////////////// +void wdxGraphicsWindow8:: +release_gsg() { + if (_gsg != (GraphicsStateGuardian *)NULL) { + GraphicsWindow::release_gsg(); + } +} + +//////////////////////////////////////////////////////////////////// +// Function: wdxGraphicsWindow8::begin_frame +// Access: Public, Virtual +// Description: This function will be called within the draw thread +// before beginning rendering for a given frame. It +// should do whatever setup is required, and return true +// if the frame should be rendered, or false if it +// should be skipped. +//////////////////////////////////////////////////////////////////// +bool wdxGraphicsWindow8:: +begin_frame() { + if (_awaiting_restore) { + // The fullscreen window was recently restored; we can't continue + // until the GSG says we can. + if (!_dxgsg->CheckCooperativeLevel()) { + // Keep waiting. + return false; + } + _awaiting_restore = false; + + init_resized_window(); + } + + return WinGraphicsWindow::begin_frame(); +} + +//////////////////////////////////////////////////////////////////// +// Function: wdxGraphicsWindow8::end_flip +// Access: Public, Virtual +// Description: This function will be called within the draw thread +// after begin_flip() has been called on all windows, to +// finish the exchange of the front and back buffers. +// +// This should cause the window to wait for the flip, if +// necessary. +//////////////////////////////////////////////////////////////////// +void wdxGraphicsWindow8:: +end_flip() { + if (_dxgsg != (DXGraphicsStateGuardian8 *)NULL && is_active()) { + _dxgsg->show_frame(); + } +} + +//////////////////////////////////////////////////////////////////// +// Function: wdxGraphicsWindow8::fullscreen_restored +// Access: Protected, Virtual +// Description: This is a hook for derived classes to do something +// special, if necessary, when a fullscreen window has +// been restored after being minimized. The given +// WindowProperties struct will be applied to this +// window's properties after this function returns. +//////////////////////////////////////////////////////////////////// +void wdxGraphicsWindow8:: +fullscreen_restored(WindowProperties &properties) { + // In DX8, unlike DX7, for some reason we can't immediately start + // rendering as soon as the window is restored, even though + // BeginScene() says we can. Instead, we have to wait until + // TestCooperativeLevel() lets us in. We need to set a flag so we + // can handle this special case in begin_frame(). + if (_dxgsg != NULL) { + _awaiting_restore = true; + } +} + +//////////////////////////////////////////////////////////////////// +// Function: wdxGraphicsWindow8::handle_reshape +// Access: Protected, Virtual +// Description: Called in the window thread when the window size or +// location is changed, this updates the properties +// structure accordingly. +//////////////////////////////////////////////////////////////////// +void wdxGraphicsWindow8:: +handle_reshape() { + GdiFlush(); + WinGraphicsWindow::handle_reshape(); + + if (_dxgsg != NULL) { + // create the new resized rendertargets + WindowProperties props = get_properties(); + int x_size = props.get_x_size(); + int y_size = props.get_y_size(); + bool resize_succeeded = reset_device_resize_window(x_size, y_size); + if (!resize_succeeded) { + if (wdxdisplay8_cat.is_debug()) { + wdxdisplay8_cat.debug() + << "windowed_resize to size: (" << x_size << "," << y_size + << ") failed due to out-of-memory\n"; + } else { + if (wdxdisplay8_cat.is_debug()) { + int x_origin = props.get_x_origin(); + int y_origin = props.get_y_origin(); + wdxdisplay8_cat.debug() + << "windowed_resize to origin: (" << x_origin << "," + << y_origin << "), size: (" << x_size + << "," << y_size << ")\n"; + } + } + } + } +} + +//////////////////////////////////////////////////////////////////// +// Function: wdxGraphicsWindow8::do_fullscreen_resize +// Access: Protected, Virtual +// Description: Called in the window thread to resize a fullscreen +// window. +//////////////////////////////////////////////////////////////////// +bool wdxGraphicsWindow8:: +do_fullscreen_resize(int x_size, int y_size) { + bool bCouldntFindValidZBuf; + D3DFORMAT pixFmt; + bool bNeedZBuffer = (_dxgsg->scrn.PresParams.EnableAutoDepthStencil!=false); + bool bNeedStencilBuffer = IS_STENCIL_FORMAT(_dxgsg->scrn.PresParams.AutoDepthStencilFormat); + + bool bIsGoodMode=false; + + if (!special_check_fullscreen_resolution(x_size,y_size)) { + // bypass the lowvidmem test below for certain "lowmem" cards we know have valid modes + + // wdxdisplay8_cat.info() << "1111111 lowvidmemcard="<< _dxgsg->scrn.bIsLowVidMemCard << endl; + if (_dxgsg->scrn.bIsLowVidMemCard && (!((x_size==640) && (y_size==480)))) { + wdxdisplay8_cat.error() << "resize() failed: will not try to resize low vidmem device #" << _dxgsg->scrn.CardIDNum << " to non-640x480!\n"; + goto Error_Return; + } + } + + // must ALWAYS use search_for_valid_displaymode even if we know + // a-priori that res is valid so we can get a valid pixfmt + search_for_valid_displaymode(x_size, y_size, + bNeedZBuffer, bNeedStencilBuffer, + &_dxgsg->scrn.SupportedScreenDepthsMask, + &bCouldntFindValidZBuf, + &pixFmt); + bIsGoodMode=(pixFmt!=D3DFMT_UNKNOWN); + + if (!bIsGoodMode) { + wdxdisplay8_cat.error() << "resize() failed: " + << (bCouldntFindValidZBuf ? "Couldnt find valid zbuffer format to go with FullScreen mode" : "No supported FullScreen modes") + << " at " << x_size << "x" << y_size << " for device #" << _dxgsg->scrn.CardIDNum <scrn.DisplayMode.Width=x_size; + _dxgsg->scrn.DisplayMode.Height=y_size; + _dxgsg->scrn.DisplayMode.Format = pixFmt; + _dxgsg->scrn.DisplayMode.RefreshRate = D3DPRESENT_RATE_DEFAULT; + + _dxgsg->scrn.PresParams.BackBufferFormat = pixFmt; // make reset_device_resize use presparams or displaymode?? + + bool bResizeSucceeded = reset_device_resize_window(x_size, y_size); + + if (!bResizeSucceeded) { + wdxdisplay8_cat.error() << "resize() failed with OUT-OF-MEMORY error!\n"; + + if ((!IS_16BPP_DISPLAY_FORMAT(_dxgsg->scrn.PresParams.BackBufferFormat)) && + (_dxgsg->scrn.SupportedScreenDepthsMask & (R5G6B5_FLAG|X1R5G5B5_FLAG))) { + // fallback strategy, if we trying >16bpp, fallback to 16bpp buffers + _dxgsg->scrn.DisplayMode.Format = ((_dxgsg->scrn.SupportedScreenDepthsMask & R5G6B5_FLAG) ? D3DFMT_R5G6B5 : D3DFMT_X1R5G5B5); + dx_force_16bpp_zbuffer=true; + if (wdxdisplay8_cat.info()) + wdxdisplay8_cat.info() << "CreateDevice failed with out-of-vidmem, retrying w/16bpp buffers on device #"<< _dxgsg->scrn.CardIDNum << endl; + + bResizeSucceeded= reset_device_resize_window(x_size, y_size); // create the new resized rendertargets + } + } + + Error_Return: + + if (wdxdisplay8_cat.is_debug()) + wdxdisplay8_cat.debug() << "fullscrn resize("<DevCaps & D3DDEVCAPS_HWRASTERIZATION); + + pPresParams->BackBufferFormat = Display.DisplayMode.Format; // dont need dest alpha, so just use adapter format + + if (dx_sync_video && !(pD3DCaps->Caps & D3DCAPS_READ_SCANLINE)) { + wdxdisplay8_cat.info() << "HW doesnt support syncing to vertical refresh, ignoring dx_sync_video\n"; + dx_sync_video=false; + } + + // verify the rendertarget fmt one last time + if (FAILED(pD3D8->CheckDeviceFormat(Display.CardIDNum, D3DDEVTYPE_HAL, Display.DisplayMode.Format,D3DUSAGE_RENDERTARGET, + D3DRTYPE_SURFACE, pPresParams->BackBufferFormat))) { + wdxdisplay8_cat.error() << "device #"<BackBufferFormat) << endl; + goto Fallback_to_16bpp_buffers; + } + + if (FAILED(pD3D8->CheckDeviceType(Display.CardIDNum,D3DDEVTYPE_HAL, Display.DisplayMode.Format,pPresParams->BackBufferFormat, + is_fullscreen()))) { + wdxdisplay8_cat.error() << "device #"<BackBufferFormat) << endl; + goto Fallback_to_16bpp_buffers; + } + + if (Display.PresParams.EnableAutoDepthStencil) { + if (!find_best_depth_format(Display, Display.DisplayMode, + &Display.PresParams.AutoDepthStencilFormat, + bWantStencil, false)) { + wdxdisplay8_cat.error() + << "find_best_depth_format failed in CreateScreenBuffers for device #" + << Display.CardIDNum << endl; + goto Fallback_to_16bpp_buffers; + } + _depth_buffer_bpp = D3DFMT_to_DepthBits(Display.PresParams.AutoDepthStencilFormat); + } else { + _depth_buffer_bpp = 0; + } + + pPresParams->Windowed = !is_fullscreen(); + + if (dx_multisample_antialiasing_level>1) { + // need to check both rendertarget and zbuffer fmts + hr = pD3D8->CheckDeviceMultiSampleType(Display.CardIDNum, D3DDEVTYPE_HAL, Display.DisplayMode.Format, + is_fullscreen(), D3DMULTISAMPLE_TYPE(dx_multisample_antialiasing_level)); + if (FAILED(hr)) { + wdxdisplay8_cat.fatal() << "device #"<CheckDeviceMultiSampleType(Display.CardIDNum, D3DDEVTYPE_HAL, Display.PresParams.AutoDepthStencilFormat, + is_fullscreen(), D3DMULTISAMPLE_TYPE(dx_multisample_antialiasing_level)); + if (FAILED(hr)) { + wdxdisplay8_cat.fatal() << "device #"<MultiSampleType = D3DMULTISAMPLE_TYPE(dx_multisample_antialiasing_level); + + if (wdxdisplay8_cat.is_info()) + wdxdisplay8_cat.info() << "device #"<BackBufferCount = 1; + pPresParams->Flags = 0x0; + pPresParams->hDeviceWindow = Display.hWnd; + pPresParams->BackBufferWidth = Display.DisplayMode.Width; + pPresParams->BackBufferHeight = Display.DisplayMode.Height; + DWORD dwBehaviorFlags=0x0; + + if (_dxgsg->scrn.bIsTNLDevice) { + dwBehaviorFlags|=D3DCREATE_HARDWARE_VERTEXPROCESSING; + // note: we could create a pure device in this case if I eliminated the GetRenderState calls in dxgsg + + // also, no software vertex processing available since I specify D3DCREATE_HARDWARE_VERTEXPROCESSING + // and not D3DCREATE_MIXED_VERTEXPROCESSING + } else { + dwBehaviorFlags|=D3DCREATE_SOFTWARE_VERTEXPROCESSING; + } + + if (dx_preserve_fpu_state) + dwBehaviorFlags|=D3DCREATE_FPU_PRESERVE; + + // if window is not foreground in exclusive mode, ddraw thinks you are 'not active', so + // it changes your WM_ACTIVATEAPP from true to false, causing us + // to go into a 'wait-for WM_ACTIVATEAPP true' loop, and the event never comes so we hang + // in fullscreen wait. also doing this for windowed mode since it was requested. + if (!SetForegroundWindow(Display.hWnd)) { + wdxdisplay8_cat.warning() << "SetForegroundWindow() failed!\n"; + } + + if (is_fullscreen()) { + pPresParams->SwapEffect = D3DSWAPEFFECT_DISCARD; // we dont care about preserving contents of old frame + pPresParams->FullScreen_PresentationInterval = (dx_sync_video ? D3DPRESENT_INTERVAL_ONE : D3DPRESENT_INTERVAL_IMMEDIATE); + pPresParams->FullScreen_RefreshRateInHz = Display.DisplayMode.RefreshRate; + +#ifdef _DEBUG + if (pPresParams->MultiSampleType != D3DMULTISAMPLE_NONE) + assert(pPresParams->SwapEffect == D3DSWAPEFFECT_DISCARD); // only valid effect for multisample +#endif + + ClearToBlack(Display.hWnd, get_properties()); + + hr = pD3D8->CreateDevice(Display.CardIDNum, D3DDEVTYPE_HAL, _mwindow, + dwBehaviorFlags, pPresParams, &Display.pD3DDevice); + + if (FAILED(hr)) { + wdxdisplay8_cat.fatal() << "D3D CreateDevice failed for device #" << Display.CardIDNum << ", " << D3DERRORSTRING(hr); + + if (hr == D3DERR_OUTOFVIDEOMEMORY) + goto Fallback_to_16bpp_buffers; + } + + SetRect(&view_rect, 0, 0, dwRenderWidth, dwRenderHeight); + } // end create full screen buffers + + else { // CREATE WINDOWED BUFFERS + + if (!(pD3DCaps->Caps2 & D3DCAPS2_CANRENDERWINDOWED)) { + wdxdisplay8_cat.fatal() << "the 3D HW cannot render windowed, exiting..." << endl; + exit(1); + } + + D3DDISPLAYMODE dispmode; + hr = Display.pD3D8->GetAdapterDisplayMode(Display.CardIDNum, &dispmode); + + if (FAILED(hr)) { + wdxdisplay8_cat.fatal() << "GetAdapterDisplayMode failed" << D3DERRORSTRING(hr); + exit(1); + } + + if (dispmode.Format == D3DFMT_P8) { + wdxdisplay8_cat.fatal() << "Can't run windowed in an 8-bit or less display mode" << endl; + exit(1); + } + + pPresParams->FullScreen_PresentationInterval = 0; + + if (dx_multisample_antialiasing_level<2) { + if (dx_sync_video) { + pPresParams->SwapEffect = D3DSWAPEFFECT_COPY_VSYNC; + } else { + pPresParams->SwapEffect = D3DSWAPEFFECT_DISCARD; //D3DSWAPEFFECT_COPY; does this make any difference? + } + } else { + pPresParams->SwapEffect = D3DSWAPEFFECT_DISCARD; + } + + assert((dwRenderWidth==pPresParams->BackBufferWidth)&&(dwRenderHeight==pPresParams->BackBufferHeight)); + + hr = pD3D8->CreateDevice(Display.CardIDNum, D3DDEVTYPE_HAL, _mwindow, + dwBehaviorFlags, pPresParams, &Display.pD3DDevice); + + if (FAILED(hr)) { + wdxdisplay8_cat.fatal() << "D3D CreateDevice failed for device #" << Display.CardIDNum << D3DERRORSTRING(hr); + exit(1); + } + } // end create windowed buffers + + // ======================================================== + + PRINT_REFCNT(wdxdisplay,_dxgsg->scrn.pD3DDevice); + + if (pPresParams->EnableAutoDepthStencil) { + _dxgsg->_buffer_mask |= RenderBuffer::T_depth; + if (IS_STENCIL_FORMAT(pPresParams->AutoDepthStencilFormat)) + _dxgsg->_buffer_mask |= RenderBuffer::T_stencil; + } + + init_resized_window(); + + return; + + Fallback_to_16bpp_buffers: + + if ((!IS_16BPP_DISPLAY_FORMAT(pPresParams->BackBufferFormat)) && + (Display.SupportedScreenDepthsMask & (R5G6B5_FLAG|X1R5G5B5_FLAG))) { + // fallback strategy, if we trying >16bpp, fallback to 16bpp buffers + + Display.DisplayMode.Format = ((Display.SupportedScreenDepthsMask & R5G6B5_FLAG) ? D3DFMT_R5G6B5 : D3DFMT_X1R5G5B5); + + if (wdxdisplay8_cat.info()) { + wdxdisplay8_cat.info() + << "CreateDevice failed with out-of-vidmem, retrying w/16bpp buffers on device #" + << Display.CardIDNum << endl; + } + create_screen_buffers_and_device(Display, true); + return; + + } else if (!((dwRenderWidth==640)&&(dwRenderHeight==480))) { + if (wdxdisplay8_cat.info()) + wdxdisplay8_cat.info() << "CreateDevice failed w/out-of-vidmem, retrying at 640x480 w/16bpp buffers on device #"<< Display.CardIDNum << endl; + // try final fallback to 640x480x16 + Display.DisplayMode.Width=640; + Display.DisplayMode.Height=480; + create_screen_buffers_and_device(Display, true); + return; + + } else { + wdxdisplay8_cat.fatal() + << "Can't create any screen buffers, bailing out.\n"; + exit(1); + } +} + +//////////////////////////////////////////////////////////////////// +// Function: wdxGraphicsWindow8::choose_adapter +// Access: Private +// Description: Looks at the list of available graphics adapters and +// chooses a suitable one for the window. +// +// Returns true if successful, false on failure. +//////////////////////////////////////////////////////////////////// +bool wdxGraphicsWindow8:: +choose_adapter(LPDIRECT3D8 pD3D8) { + HRESULT hr; + + int num_adapters = pD3D8->GetAdapterCount(); + DXDeviceInfoVec device_infos; + + for (int i = 0; i < num_adapters; i++) { + D3DADAPTER_IDENTIFIER8 adapter_info; + ZeroMemory(&adapter_info, sizeof(D3DADAPTER_IDENTIFIER8)); + hr = pD3D8->GetAdapterIdentifier(i, D3DENUM_NO_WHQL_LEVEL, &adapter_info); + if (FAILED(hr)) { + wdxdisplay8_cat.fatal() + << "D3D GetAdapterID(" << i << ") failed: " + << D3DERRORSTRING(hr) << endl; + continue; + } + + LARGE_INTEGER *DrvVer = &adapter_info.DriverVersion; + + wdxdisplay8_cat.info() + << "D3D8 Adapter[" << i << "]: " << adapter_info.Description + << ", Driver: " << adapter_info.Driver << ", DriverVersion: (" + << HIWORD(DrvVer->HighPart) << "." << LOWORD(DrvVer->HighPart) << "." + << HIWORD(DrvVer->LowPart) << "." << LOWORD(DrvVer->LowPart) + << ")\nVendorID: 0x" << (void*) adapter_info.VendorId + << " DeviceID: 0x" << (void*) adapter_info.DeviceId + << " SubsysID: 0x" << (void*) adapter_info.SubSysId + << " Revision: 0x" << (void*) adapter_info.Revision << endl; + + HMONITOR hMon = pD3D8->GetAdapterMonitor(i); + if (hMon == NULL) { + wdxdisplay8_cat.info() + << "D3D8 Adapter[" << i << "]: seems to be disabled, skipping it\n"; + continue; + } + + DXDeviceInfo devinfo; + ZeroMemory(&devinfo, sizeof(devinfo)); + memcpy(&devinfo.guidDeviceIdentifier, &adapter_info.DeviceIdentifier, + sizeof(GUID)); + strncpy(devinfo.szDescription, adapter_info.Description, + MAX_DEVICE_IDENTIFIER_STRING); + strncpy(devinfo.szDriver, adapter_info.Driver, + MAX_DEVICE_IDENTIFIER_STRING); + devinfo.VendorID = adapter_info.VendorId; + devinfo.DeviceID = adapter_info.DeviceId; + devinfo.hMon = hMon; + devinfo.cardID = i; + + device_infos.push_back(devinfo); + } + + if (device_infos.empty()) { + wdxdisplay8_cat.error() + << "No available D3D8 devices found.\n"; + return false; + } + + // Since some adapters may have been disabled, we should re-obtain + // the number of available adapters. + num_adapters = (int)device_infos.size(); + + // Now choose a suitable adapter. + + int adapter_num = D3DADAPTER_DEFAULT; + + // Eventually, we should have some interface for specifying a device + // index interactively, instead of only via Configrc. + if (dx_preferred_device_id != -1) { + if (dx_preferred_device_id < 0 || dx_preferred_device_id >= num_adapters) { + wdxdisplay8_cat.error() + << "invalid 'dx-preferred-device-id', valid values are 0-" + << num_adapters - 1 << ", using default adapter instead.\n"; + } else { + adapter_num = dx_preferred_device_id; + } + } + + return search_for_device(pD3D8, &device_infos[adapter_num]); +} + +//////////////////////////////////////////////////////////////////// +// Function: wdxGraphicsWindow8::search_for_device +// Access: Private +// Description: Searches for a suitable hardware device for +// rendering. +//////////////////////////////////////////////////////////////////// +bool wdxGraphicsWindow8:: +search_for_device(LPDIRECT3D8 pD3D8, DXDeviceInfo *device_info) { + wdxGraphicsPipe8 *pipe8; + DCAST_INTO_R(pipe8, _pipe, false); + + DWORD dwRenderWidth = get_properties().get_x_size(); + DWORD dwRenderHeight = get_properties().get_y_size(); + HRESULT hr; + + assert(_dxgsg != NULL); + _dxgsg->scrn.pD3D8 = pD3D8; + _dxgsg->scrn.CardIDNum = device_info->cardID; // could this change by end? + + int framebuffer_mode = get_properties().get_framebuffer_mode(); + bool bWantStencil = ((framebuffer_mode & WindowProperties::FM_stencil) != 0); + + hr = pD3D8->GetAdapterIdentifier(device_info->cardID, D3DENUM_NO_WHQL_LEVEL, + &_dxgsg->scrn.DXDeviceID); + if (FAILED(hr)) { + wdxdisplay8_cat.error() + << "D3D GetAdapterID failed" << D3DERRORSTRING(hr); + return false; + } + + D3DCAPS8 d3dcaps; + hr = pD3D8->GetDeviceCaps(device_info->cardID,D3DDEVTYPE_HAL,&d3dcaps); + if (FAILED(hr)) { + if ((hr==D3DERR_INVALIDDEVICE)||(hr==D3DERR_NOTAVAILABLE)) { + wdxdisplay8_cat.error() + << "No DirectX 8 D3D-capable 3D hardware detected for device # " + << device_info->cardID << " (" <szDescription + << ")!\n"; + } else { + wdxdisplay8_cat.error() + << "GetDeviceCaps failed: " << D3DERRORSTRING(hr) << endl; + } + return false; + } + + //search_for_valid_displaymode needs these to be set + memcpy(&_dxgsg->scrn.d3dcaps, &d3dcaps,sizeof(D3DCAPS8)); + _dxgsg->scrn.CardIDNum = device_info->cardID; + + _dxgsg->scrn.MaxAvailVidMem = UNKNOWN_VIDMEM_SIZE; + _dxgsg->scrn.bIsLowVidMemCard = false; + + // bugbug: wouldnt we like to do GetAVailVidMem so we can do + // upper-limit memory computation for dx8 cards too? otherwise + // verify_window_sizes cant do much + if ((d3dcaps.MaxStreams==0) || dx_pick_best_screenres) { + if (wdxdisplay8_cat.is_debug()) { + wdxdisplay8_cat.debug() + << "checking vidmem size\n"; + } + // assert(IS_VALID_PTR(_pParentWindowGroup)); + + // look for low memory video cards + // _pParentWindowGroup->find_all_card_memavails(); + + UINT IDnum; + + // simple linear search to match DX7 card info w/DX8 card ID + for (IDnum=0; IDnum < pipe8->_card_ids.size(); IDnum++) { + // wdxdisplay8_cat.info() + // << "comparing '" << pipe8->_card_ids[IDnum].Driver + // << "' to '" << _dxgsg->scrn.DXDeviceID.Driver << "'\n"; + if (//(stricmp(pipe8->_card_ids[IDnum].szDriver,device_info->szDriver)==0) && + (device_info->VendorID==pipe8->_card_ids[IDnum].VendorID) && + (device_info->DeviceID==pipe8->_card_ids[IDnum].DeviceID) && + (device_info->hMon==pipe8->_card_ids[IDnum].hMon)) + break; + } + + if (IDnum < pipe8->_card_ids.size()) { + _dxgsg->scrn.MaxAvailVidMem = pipe8->_card_ids[IDnum].MaxAvailVidMem; + _dxgsg->scrn.bIsLowVidMemCard = pipe8->_card_ids[IDnum].bIsLowVidMemCard; + } else { + wdxdisplay8_cat.error() + << "Error: couldnt find a CardID match in DX7 info, assuming card is not a lowmem card\n"; + } + } + + if ((bWantStencil) && (d3dcaps.StencilCaps==0x0)) { + wdxdisplay8_cat.fatal() + << "Stencil ability requested, but device #" << device_info->cardID + << " (" << _dxgsg->scrn.DXDeviceID.Description + << "), has no stencil capability!\n"; + return false; + } + + // just because TNL is true, it doesnt mean vtx shaders are + // supported in HW (see GF2) for this case, you probably want MIXED + // processing to use HW for fixed-fn vertex processing and SW for + // vtx shaders + _dxgsg->scrn.bIsTNLDevice = + ((d3dcaps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT) != 0); + _dxgsg->scrn.bCanUseHWVertexShaders = + (d3dcaps.VertexShaderVersion >= D3DVS_VERSION(1, 0)); + _dxgsg->scrn.bCanUsePixelShaders = + (d3dcaps.PixelShaderVersion >= D3DPS_VERSION(1, 0)); + + bool bNeedZBuffer = + ((!(d3dcaps.RasterCaps & D3DPRASTERCAPS_ZBUFFERLESSHSR )) && + ((framebuffer_mode & WindowProperties::FM_depth) != 0)); + + _dxgsg->scrn.PresParams.EnableAutoDepthStencil = bNeedZBuffer; + + D3DFORMAT pixFmt = D3DFMT_UNKNOWN; + + if (is_fullscreen()) { + bool bCouldntFindValidZBuf; + if (!_dxgsg->scrn.bIsLowVidMemCard) { + bool bUseDefaultSize = dx_pick_best_screenres && + ((_dxgsg->scrn.MaxAvailVidMem == UNKNOWN_VIDMEM_SIZE) || + is_badvidmem_card(&_dxgsg->scrn.DXDeviceID)); + + if (dx_pick_best_screenres && !bUseDefaultSize) { + typedef struct { + UINT memlimit; + DWORD scrnX,scrnY; + } Memlimres; + + const Memlimres MemRes[] = { + { 0, 640, 480}, + { 8000000, 800, 600}, +#if 0 + {16000000, 1024, 768}, + {32000000, 1280,1024}, // 32MB+ cards will choose this +#else + // unfortunately the 32MB card perf varies greatly (TNT2-GF2), + // so we need to be conservative since frame rate difference + // can change from 15->30fps when going from 1280x1024->800x600 + // on low-end 32mb cards + {16000000, 800, 600}, + {32000000, 800, 600}, // 32MB+ cards will choose this +#endif + // some monitors have trouble w/1600x1200, so dont pick this by deflt, + // even though 64MB cards should handle it + {64000000, 1280,1024} // 64MB+ cards will choose this + }; + const NumResLims = (sizeof(MemRes)/sizeof(Memlimres)); + + for(int i = NumResLims - 1; i >= 0; i--) { + // find biggest slot card can handle + if (_dxgsg->scrn.MaxAvailVidMem > MemRes[i].memlimit) { + dwRenderWidth = MemRes[i].scrnX; + dwRenderHeight = MemRes[i].scrnY; + + wdxdisplay8_cat.info() + << "pick_best_screenres: trying " << dwRenderWidth + << "x" << dwRenderHeight << " based on " + << _dxgsg->scrn.MaxAvailVidMem << " bytes avail\n"; + + search_for_valid_displaymode(dwRenderWidth, dwRenderHeight, + bNeedZBuffer, bWantStencil, + &_dxgsg->scrn.SupportedScreenDepthsMask, + &bCouldntFindValidZBuf, + &pixFmt); + + // note I'm not saving refresh rate, will just use adapter + // default at given res for now + + if (pixFmt != D3DFMT_UNKNOWN) { + break; + } + + wdxdisplay8_cat.info() + << "skipping scrnres; " + << (bCouldntFindValidZBuf ? "Couldnt find valid zbuffer format to go with FullScreen mode" : "No supported FullScreen modes") + << " at " << dwRenderWidth << "x" << dwRenderHeight + << " for device #" << _dxgsg->scrn.CardIDNum << endl; + } + } + // otherwise just go with whatever was specified (we probably shouldve marked this card as lowmem if it gets to end of loop w/o breaking + } + + if (pixFmt == D3DFMT_UNKNOWN) { + if (bUseDefaultSize) { + wdxdisplay8_cat.info() + << "pick_best_screenres: defaulted 800x600 based on no reliable vidmem size\n"; + dwRenderWidth=800; + dwRenderHeight=600; + } + + search_for_valid_displaymode(dwRenderWidth, dwRenderHeight, + bNeedZBuffer, bWantStencil, + &_dxgsg->scrn.SupportedScreenDepthsMask, + &bCouldntFindValidZBuf, + &pixFmt); + + // note I'm not saving refresh rate, will just use adapter + // default at given res for now + + if (pixFmt == D3DFMT_UNKNOWN) { + wdxdisplay8_cat.error() + << (bCouldntFindValidZBuf ? "Couldnt find valid zbuffer format to go with FullScreen mode" : "No supported FullScreen modes") + << " at " << dwRenderWidth << "x" << dwRenderHeight << " for device #" << _dxgsg->scrn.CardIDNum <scrn.SupportedScreenDepthsMask, + &bCouldntFindValidZBuf, + &pixFmt, true); + return false; + } + } + } else { + // Low Memory card + dwRenderWidth=640; + dwRenderHeight=480; + dx_force_16bpptextures = true; + + // force 16bpp zbuf? or let user get extra bits if they have the mem? + + search_for_valid_displaymode(dwRenderWidth, dwRenderHeight, + bNeedZBuffer, bWantStencil, + &_dxgsg->scrn.SupportedScreenDepthsMask, + &bCouldntFindValidZBuf, + &pixFmt); + + // hack: figuring out exactly what res to use is tricky, instead I will + // just use 640x480 if we have < 3 meg avail + + if (_dxgsg->scrn.SupportedScreenDepthsMask & R5G6B5_FLAG) { + pixFmt = D3DFMT_R5G6B5; + } else if (_dxgsg->scrn.SupportedScreenDepthsMask & X1R5G5B5_FLAG) { + pixFmt = D3DFMT_X1R5G5B5; + } else { + wdxdisplay8_cat.fatal() + << "Low Memory VidCard has no supported FullScreen 16bpp resolutions at " + << dwRenderWidth << "x" << dwRenderHeight << " for device #" + << device_info->cardID << " (" + << _dxgsg->scrn.DXDeviceID.Description << "), skipping device...\n"; + + // run it again in verbose mode to get more dbg info to log + search_for_valid_displaymode(dwRenderWidth, dwRenderHeight, + bNeedZBuffer, bWantStencil, + &_dxgsg->scrn.SupportedScreenDepthsMask, + &bCouldntFindValidZBuf, + &pixFmt, true); + return false; + } + + if (wdxdisplay8_cat.is_info()) { + wdxdisplay8_cat.info() + << "Available VidMem (" << _dxgsg->scrn.MaxAvailVidMem + << ") is under threshold, using 640x480 16bpp rendertargets to save tex vidmem.\n"; + } + } + } else { + // Windowed Mode + + D3DDISPLAYMODE dispmode; + hr = pD3D8->GetAdapterDisplayMode(device_info->cardID,&dispmode); + if (FAILED(hr)) { + wdxdisplay8_cat.error() + << "GetAdapterDisplayMode(" << device_info->cardID + << ") failed" << D3DERRORSTRING(hr); + return false; + } + pixFmt = dispmode.Format; + } + + _dxgsg->scrn.DisplayMode.Width = dwRenderWidth; + _dxgsg->scrn.DisplayMode.Height = dwRenderHeight; + _dxgsg->scrn.DisplayMode.Format = pixFmt; + _dxgsg->scrn.DisplayMode.RefreshRate = D3DPRESENT_RATE_DEFAULT; + _dxgsg->scrn.hMon = device_info->hMon; + return true; +} + +//////////////////////////////////////////////////////////////////// +// Function: wdxGraphicsWindow8::special_check_fullscreen_resolution +// Access: Private +// Description: overrides of the general estimator for known working +// cases +//////////////////////////////////////////////////////////////////// +bool wdxGraphicsWindow8:: +special_check_fullscreen_resolution(UINT x_size,UINT y_size) { + assert(IS_VALID_PTR(_dxgsg)); + + DWORD VendorId = _dxgsg->scrn.DXDeviceID.VendorId; + DWORD DeviceId = _dxgsg->scrn.DXDeviceID.DeviceId; + switch (VendorId) { + case 0x8086: // Intel + /*for now, just validate all the intel cards at these resolutions. + I dont have a complete list of intel deviceIDs (missing 82830, 845, etc) + // Intel i810,i815,82810 + if ((DeviceId==0x7121)||(DeviceId==0x7123)||(DeviceId==0x7125)|| + (DeviceId==0x1132)) + */ + if ((x_size == 640) && (y_size == 480)) { + return true; + } + if ((x_size == 800) && (y_size == 600)) { + return true; + } + if ((x_size == 1024) && (y_size == 768)) { + return true; + } + break; + } + + return false; +} + +//////////////////////////////////////////////////////////////////// +// Function: wdxGraphicsWindow8::search_for_valid_displaymode +// Access: Private +// Description: All ptr args are output parameters. If no valid mode +// found, returns *pSuggestedPixFmt = D3DFMT_UNKNOWN; +//////////////////////////////////////////////////////////////////// +void wdxGraphicsWindow8:: +search_for_valid_displaymode(UINT RequestedX_Size, UINT RequestedY_Size, + bool bWantZBuffer, bool bWantStencil, + UINT *pSupportedScreenDepthsMask, + bool *pCouldntFindAnyValidZBuf, + D3DFORMAT *pSuggestedPixFmt, + bool bVerboseMode) { + assert(IS_VALID_PTR(_dxgsg)); + assert(IS_VALID_PTR(_dxgsg->scrn.pD3D8)); + HRESULT hr; + +#ifndef NDEBUG + // no longer true, due to special_check_fullscreen_res, where lowvidmem cards are allowed higher resolutions + // if (_dxgsg->scrn.bIsLowVidMemCard) + // nassertv((RequestedX_Size==640)&&(RequestedY_Size==480)); +#endif + + *pSuggestedPixFmt = D3DFMT_UNKNOWN; + *pSupportedScreenDepthsMask = 0x0; + *pCouldntFindAnyValidZBuf = false; + + int cNumModes = _dxgsg->scrn.pD3D8->GetAdapterModeCount(_dxgsg->scrn.CardIDNum); + D3DDISPLAYMODE BestDispMode; + ZeroMemory(&BestDispMode,sizeof(BestDispMode)); + + if (bVerboseMode) { + wdxdisplay8_cat.info() + << "searching for valid display modes at res: (" + << RequestedX_Size << "," << RequestedY_Size + << "), TotalModes: " << cNumModes << endl; + } + + // ignore memory based checks for min res 640x480. some cards just + // dont give accurate memavails. (should I do the check anyway for + // 640x480 32bpp?) + bool bDoMemBasedChecks = + ((!((RequestedX_Size==640)&&(RequestedY_Size==480))) && + (_dxgsg->scrn.MaxAvailVidMem!=UNKNOWN_VIDMEM_SIZE) && + (!special_check_fullscreen_resolution(RequestedX_Size,RequestedY_Size))); + + if (bVerboseMode || wdxdisplay8_cat.is_spam()) { + wdxdisplay8_cat.info() + << "DoMemBasedChecks = " << bDoMemBasedChecks << endl; + } + + for (int i=0; i < cNumModes; i++) { + D3DDISPLAYMODE dispmode; + hr = _dxgsg->scrn.pD3D8->EnumAdapterModes(_dxgsg->scrn.CardIDNum,i,&dispmode); + if (FAILED(hr)) { + wdxdisplay8_cat.error() + << "EnumAdapterDisplayMode failed for device #" + << _dxgsg->scrn.CardIDNum << D3DERRORSTRING(hr); + exit(1); + } + + if ((dispmode.Width!=RequestedX_Size) || + (dispmode.Height!=RequestedY_Size)) { + continue; + } + + if ((dispmode.RefreshRate<60) && (dispmode.RefreshRate>1)) { + // dont want refresh rates under 60Hz, but 0 or 1 might indicate + // a default refresh rate, which is usually >=60 + if (bVerboseMode) { + wdxdisplay8_cat.info() + << "skipping mode[" << i << "], bad refresh rate: " + << dispmode.RefreshRate << endl; + } + continue; + } + + // Note no attempt is made to verify if format will work at + // requested size, so even if this call succeeds, could still get + // an out-of-video-mem error + + hr = _dxgsg->scrn.pD3D8->CheckDeviceFormat(_dxgsg->scrn.CardIDNum, + D3DDEVTYPE_HAL, dispmode.Format, + D3DUSAGE_RENDERTARGET, + D3DRTYPE_SURFACE, + dispmode.Format); + if (FAILED(hr)) { + if (hr==D3DERR_NOTAVAILABLE) { + if (bVerboseMode) { + wdxdisplay8_cat.info() + << "skipping mode[" << i + << "], CheckDevFmt returns NotAvail for fmt: " + << D3DFormatStr(dispmode.Format) << endl; + } + continue; + } else { + wdxdisplay8_cat.error() + << "CheckDeviceFormat failed for device #" + << _dxgsg->scrn.CardIDNum << D3DERRORSTRING(hr); + exit(1); + } + } + + bool bIs16bppRenderTgt = IS_16BPP_DISPLAY_FORMAT(dispmode.Format); + float RendTgtMinMemReqmt; + + // if we have a valid memavail value, try to determine if we have + // enough space + if (bDoMemBasedChecks) { + // assume user is testing fullscreen, not windowed, so use the + // dwTotal value see if 3 scrnbufs (front/back/z)at 16bpp at + // x_size*y_size will fit with a few extra megs for texmem + + // 8MB Rage Pro says it has 6.8 megs Total free and will run at + // 1024x768, so formula makes it so that is OK + +#define REQD_TEXMEM 1800000 + + float bytes_per_pixel = (bIs16bppRenderTgt ? 2 : 4); + assert((get_properties().get_framebuffer_mode() & WindowProperties::FM_double_buffer) != 0); + + // *2 for double buffer + + RendTgtMinMemReqmt = + ((float)RequestedX_Size) * ((float)RequestedY_Size) * + bytes_per_pixel * 2 + REQD_TEXMEM; + + if (bVerboseMode || wdxdisplay8_cat.is_spam()) + wdxdisplay8_cat.info() + << "Testing Mode (" <scrn.MaxAvailVidMem << endl; + + if (RendTgtMinMemReqmt > _dxgsg->scrn.MaxAvailVidMem) { + if (bVerboseMode || wdxdisplay8_cat.is_debug()) + wdxdisplay8_cat.info() + << "not enough VidMem for render tgt, skipping display fmt " + << D3DFormatStr(dispmode.Format) << " (" + << (int)RendTgtMinMemReqmt << " > " + << _dxgsg->scrn.MaxAvailVidMem << ")\n"; + continue; + } + } + + if (bWantZBuffer) { + D3DFORMAT zformat; + if (!find_best_depth_format(_dxgsg->scrn,dispmode, &zformat, + bWantStencil, false)) { + *pCouldntFindAnyValidZBuf=true; + continue; + } + + float MinMemReqmt = 0.0f; + + if (bDoMemBasedChecks) { + // test memory again, this time including zbuf size + float zbytes_per_pixel = (IS_16BPP_ZBUFFER(zformat) ? 2 : 4); + float MinMemReqmt = RendTgtMinMemReqmt + ((float)RequestedX_Size)*((float)RequestedY_Size)*zbytes_per_pixel; + + if (bVerboseMode || wdxdisplay8_cat.is_spam()) + wdxdisplay8_cat.info() + << "Testing Mode w/Z (" << RequestedX_Size << "x" + << RequestedY_Size << "," << D3DFormatStr(dispmode.Format) + << ")\nReqdVidMem: "<< (int)MinMemReqmt << " AvailVidMem: " + << _dxgsg->scrn.MaxAvailVidMem << endl; + + if (MinMemReqmt > _dxgsg->scrn.MaxAvailVidMem) { + if (bVerboseMode || wdxdisplay8_cat.is_debug()) + wdxdisplay8_cat.info() + << "not enough VidMem for RendTgt+zbuf, skipping display fmt " + << D3DFormatStr(dispmode.Format) << " (" << (int)MinMemReqmt + << " > " << _dxgsg->scrn.MaxAvailVidMem << ")\n"; + continue; + } + } + + if ((!bDoMemBasedChecks) || (MinMemReqmt<_dxgsg->scrn.MaxAvailVidMem)) { + if (!IS_16BPP_ZBUFFER(zformat)) { + // see if things fit with a 16bpp zbuffer + + if (!find_best_depth_format(_dxgsg->scrn, dispmode, &zformat, + bWantStencil, true, bVerboseMode)) { + if (bVerboseMode) + wdxdisplay8_cat.info() + << "FindBestDepthFmt rejected Mode[" << i << "] (" + << RequestedX_Size << "x" << RequestedY_Size + << "," << D3DFormatStr(dispmode.Format) << endl; + *pCouldntFindAnyValidZBuf=true; + continue; + } + + // right now I'm not going to use these flags, just let the + // create fail out-of-mem and retry at 16bpp + *pSupportedScreenDepthsMask |= + (IS_16BPP_DISPLAY_FORMAT(dispmode.Format) ? DISPLAY_16BPP_REQUIRES_16BPP_ZBUFFER_FLAG : DISPLAY_32BPP_REQUIRES_16BPP_ZBUFFER_FLAG); + } + } + } + + if (bVerboseMode || wdxdisplay8_cat.is_spam()) + wdxdisplay8_cat.info() + << "Validated Mode (" << RequestedX_Size << "x" + << RequestedY_Size << "," << D3DFormatStr(dispmode.Format) << endl; + + switch (dispmode.Format) { + case D3DFMT_X1R5G5B5: + *pSupportedScreenDepthsMask |= X1R5G5B5_FLAG; + break; + case D3DFMT_X8R8G8B8: + *pSupportedScreenDepthsMask |= X8R8G8B8_FLAG; + break; + case D3DFMT_R8G8B8: + *pSupportedScreenDepthsMask |= R8G8B8_FLAG; + break; + case D3DFMT_R5G6B5: + *pSupportedScreenDepthsMask |= R5G6B5_FLAG; + break; + default: + // Render target formats should be only D3DFMT_X1R5G5B5, + // D3DFMT_R5G6B5, D3DFMT_X8R8G8B8 (or R8G8B8?) + wdxdisplay8_cat.error() + << "unrecognized supported fmt "<< D3DFormatStr(dispmode.Format) + << " returned by EnumAdapterDisplayModes!\n"; + } + } + + // note: this chooses 32bpp, which may not be preferred over 16 for + // memory & speed reasons on some older cards in particular + if (*pSupportedScreenDepthsMask & X8R8G8B8_FLAG) { + *pSuggestedPixFmt = D3DFMT_X8R8G8B8; + } else if (*pSupportedScreenDepthsMask & R8G8B8_FLAG) { + *pSuggestedPixFmt = D3DFMT_R8G8B8; + } else if (*pSupportedScreenDepthsMask & R5G6B5_FLAG) { + *pSuggestedPixFmt = D3DFMT_R5G6B5; + } else if (*pSupportedScreenDepthsMask & X1R5G5B5_FLAG) { + *pSuggestedPixFmt = D3DFMT_X1R5G5B5; + } + + if (bVerboseMode || wdxdisplay8_cat.is_spam()) { + wdxdisplay8_cat.info() + << "search_for_valid_device returns fmt: " + << D3DFormatStr(*pSuggestedPixFmt) << endl; + } +} + +//////////////////////////////////////////////////////////////////// +// Function: wdxGraphicsWindow8::reset_device_resize_window +// Access: Private +// Description: Called after a window (either fullscreen or windowed) +// has been resized, this recreates the D3D structures +// to match the new size. +//////////////////////////////////////////////////////////////////// +bool wdxGraphicsWindow8:: +reset_device_resize_window(UINT new_xsize, UINT new_ysize) { + DXScreenData *pScrn = &_dxgsg->scrn; + assert((new_xsize > 0) && (new_ysize > 0)); + bool bRetval = true; + + D3DPRESENT_PARAMETERS d3dpp; + memcpy(&d3dpp, &pScrn->PresParams, sizeof(D3DPRESENT_PARAMETERS)); + d3dpp.BackBufferWidth = new_xsize; + d3dpp.BackBufferHeight = new_ysize; + HRESULT hr = _dxgsg->reset_d3d_device(&d3dpp); + + if (FAILED(hr)) { + bRetval = false; + wdxdisplay8_cat.error() + << "reset_device_resize_window Reset() failed" << D3DERRORSTRING(hr); + if (hr == D3DERR_OUTOFVIDEOMEMORY) { + hr = _dxgsg->reset_d3d_device(&pScrn->PresParams); + if (FAILED(hr)) { + wdxdisplay8_cat.error() + << "reset_device_resize_window Reset() failed OutOfVidmem, then failed again doing Reset w/original params:" << D3DERRORSTRING(hr); + exit(1); + } else { + if (wdxdisplay8_cat.is_info()) + wdxdisplay8_cat.info() + << "reset of original size (" << pScrn->PresParams.BackBufferWidth + << "," << pScrn->PresParams.BackBufferHeight << ") succeeded\n"; + } + } else { + wdxdisplay8_cat.fatal() + << "Can't reset device, bailing out.\n"; + exit(1); + } + } + + init_resized_window(); + return bRetval; +} + +//////////////////////////////////////////////////////////////////// +// Function: wdxGraphicsWindow8::init_resized_window +// Access: Private +// Description: Reinitializes the window after it has been resized, +// or after it is first created. +// +// Assumes CreateDevice or Device->Reset() has just been +// called, and the new size is specified in +// _dxgsg->scrn.PresParams. +//////////////////////////////////////////////////////////////////// +void wdxGraphicsWindow8:: +init_resized_window() { + DXScreenData *pDisplay=&_dxgsg->scrn; + HRESULT hr; + + DWORD newWidth = pDisplay->PresParams.BackBufferWidth; + DWORD newHeight = pDisplay->PresParams.BackBufferHeight; + + if (pDisplay->PresParams.Windowed) { + POINT ul,lr; + RECT client_rect; + + // need to figure out x,y origin offset of window client area on screen + // (we already know the client area size) + + GetClientRect(pDisplay->hWnd, &client_rect); + ul.x = client_rect.left; + ul.y = client_rect.top; + lr.x = client_rect.right; + lr.y=client_rect.bottom; + ClientToScreen(pDisplay->hWnd, &ul); + ClientToScreen(pDisplay->hWnd, &lr); + client_rect.left = ul.x; + client_rect.top = ul.y; + client_rect.right = lr.x; + client_rect.bottom = lr.y; + // _props._xorg = client_rect.left; // _props should reflect view rectangle + // _props._yorg = client_rect.top; + +#ifdef _DEBUG + // try to make sure GDI and DX agree on window client area size + // but client rect will not include any offscreen areas, so dont + // do check if window was bigger than screen (there are other bad + // cases too, like when window is positioned partly offscreen, + // or if window trim border make size bigger than screen) + + RECT desktop_rect; + GetClientRect(GetDesktopWindow(), &desktop_rect); + int x_size = get_properties().get_x_size(); + int y_size = get_properties().get_y_size(); + if ((x_size < RECT_X_SIZE(desktop_rect)) && + (y_size < RECT_Y_SIZE(desktop_rect))) + assert((RECT_X_SIZE(client_rect) == newWidth) && + (RECT_Y_SIZE(client_rect) == newHeight)); +#endif + } + + // resized(newWidth, newHeight); // update panda channel/display rgn info, _props.x_size, _props.y_size + + // clear window to black ASAP + ClearToBlack(pDisplay->hWnd, get_properties()); + + // clear textures and VB's out of video&AGP mem, so cache is reset + hr = pDisplay->pD3DDevice->ResourceManagerDiscardBytes(0); + if (FAILED(hr)) { + wdxdisplay8_cat.error() + << "ResourceManagerDiscardBytes failed for device #" + << pDisplay->CardIDNum << D3DERRORSTRING(hr); + } + + _dxgsg->dx_init(_mouse_cursor); +} + +//////////////////////////////////////////////////////////////////// +// Function: wdxGraphicsWindow8::find_best_depth_format +// Access: Private +// Description: +//////////////////////////////////////////////////////////////////// +bool wdxGraphicsWindow8:: +find_best_depth_format(DXScreenData &Display, D3DDISPLAYMODE &TestDisplayMode, + D3DFORMAT *pBestFmt, bool bWantStencil, + bool bForce16bpp, bool bVerboseMode) const { + // list fmts in order of preference +#define NUM_TEST_ZFMTS 3 + static D3DFORMAT NoStencilPrefList[NUM_TEST_ZFMTS]={D3DFMT_D32,D3DFMT_D24X8,D3DFMT_D16}; + static D3DFORMAT StencilPrefList[NUM_TEST_ZFMTS]={D3DFMT_D24S8,D3DFMT_D24X4S4,D3DFMT_D15S1}; + + // do not use Display.DisplayMode since that is probably not set yet, use TestDisplayMode instead + + // int want_color_bits = _props._want_color_bits; + // int want_depth_bits = _props._want_depth_bits; should we pay attn to these so panda user can select bitdepth? + + *pBestFmt = D3DFMT_UNKNOWN; + HRESULT hr; + + // nvidia likes zbuf depth to match rendertarget depth + bool bOnlySelect16bpp = (dx_force_16bpp_zbuffer || bForce16bpp || + (IS_NVIDIA(Display.DXDeviceID) && IS_16BPP_DISPLAY_FORMAT(TestDisplayMode.Format))); + + if (bVerboseMode) { + wdxdisplay8_cat.info() + << "FindBestDepthFmt: bSelectOnly16bpp: " << bOnlySelect16bpp << endl; + } + + for (int i=0; i < NUM_TEST_ZFMTS; i++) { + D3DFORMAT TestDepthFmt = + (bWantStencil ? StencilPrefList[i] : NoStencilPrefList[i]); + + if (bOnlySelect16bpp && !IS_16BPP_ZBUFFER(TestDepthFmt)) { + continue; + } + + hr = Display.pD3D8->CheckDeviceFormat(Display.CardIDNum, + D3DDEVTYPE_HAL, + TestDisplayMode.Format, + D3DUSAGE_DEPTHSTENCIL, + D3DRTYPE_SURFACE,TestDepthFmt); + + if (FAILED(hr)) { + if (hr == D3DERR_NOTAVAILABLE) { + if (bVerboseMode) + wdxdisplay8_cat.info() + << "FindBestDepthFmt: ChkDevFmt returns NotAvail for " + << D3DFormatStr(TestDepthFmt) << endl; + continue; + } + + wdxdisplay8_cat.error() + << "unexpected CheckDeviceFormat failure" << D3DERRORSTRING(hr) + << endl; + exit(1); + } + + hr = Display.pD3D8->CheckDepthStencilMatch(Display.CardIDNum, + D3DDEVTYPE_HAL, + TestDisplayMode.Format, // adapter format + TestDisplayMode.Format, // backbuffer fmt (should be the same in my apps) + TestDepthFmt); + if (SUCCEEDED(hr)) { + *pBestFmt = TestDepthFmt; + break; + } else { + if (hr==D3DERR_NOTAVAILABLE) { + if (bVerboseMode) { + wdxdisplay8_cat.info() + << "FindBestDepthFmt: ChkDepMatch returns NotAvail for " + << D3DFormatStr(TestDisplayMode.Format) << ", " + << D3DFormatStr(TestDepthFmt) << endl; + } + } else { + wdxdisplay8_cat.error() + << "unexpected CheckDepthStencilMatch failure for " + << D3DFormatStr(TestDisplayMode.Format) << ", " + << D3DFormatStr(TestDepthFmt) << endl; + exit(1); + } + } + } + + if (bVerboseMode) { + wdxdisplay8_cat.info() + << "FindBestDepthFmt returns fmt " << D3DFormatStr(*pBestFmt) << endl; + } + + return (*pBestFmt != D3DFMT_UNKNOWN); +} + +//////////////////////////////////////////////////////////////////// +// Function: wdxGraphicsWindow8::D3DFMT_to_DepthBits +// Access: Private, Static +// Description: Returns the number of depth bits represented by the +// indicated D3DFORMAT value. +//////////////////////////////////////////////////////////////////// +int wdxGraphicsWindow8:: +D3DFMT_to_DepthBits(D3DFORMAT fmt) { + switch(fmt) { + case D3DFMT_D16: + return 16; + + case D3DFMT_D24X8: + case D3DFMT_D24X4S4: + case D3DFMT_D24S8: + return 24; + + case D3DFMT_D32: + return 32; + + case D3DFMT_D15S1: + return 15; + + default: + wdxdisplay8_cat.debug() + << "D3DFMT_DepthBits: unhandled D3DFMT!\n"; + return 0; + } +} + +//////////////////////////////////////////////////////////////////// +// Function: wdxGraphicsWindow8::is_badvidmem_card +// Access: Private, Static +// Description: Returns true if the indicated video adapter card is +// known to report an inaccurate figure for available +// video memory. +//////////////////////////////////////////////////////////////////// +bool wdxGraphicsWindow8:: +is_badvidmem_card(D3DADAPTER_IDENTIFIER8 *pDevID) { + // dont trust Intel cards since they often use regular memory as vidmem + if (pDevID->VendorId == 0x00008086) { + return true; + } + + return false; +} diff --git a/panda/src/dxgsg8/wdxGraphicsWindow8.h b/panda/src/dxgsg8/wdxGraphicsWindow8.h new file mode 100644 index 0000000000..02248e9c86 --- /dev/null +++ b/panda/src/dxgsg8/wdxGraphicsWindow8.h @@ -0,0 +1,111 @@ +// Filename: wdxGraphicsWindow8.h +// 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 . +// +//////////////////////////////////////////////////////////////////// + +#ifndef WDXGRAPHICSWINDOW8_H +#define WDXGRAPHICSWINDOW8_H + +#include "pandabase.h" +#include "winGraphicsWindow.h" +#include "dxGraphicsStateGuardian8.h" +#include "dxInput8.h" +#include "wdxGraphicsPipe8.h" + +class wdxGraphicsPipe8; + +static const int WDXWIN_CONFIGURE = 4; +static const int WDXWIN_EVENT = 8; + +//#define FIND_CARD_MEMAVAILS + +//////////////////////////////////////////////////////////////////// +// Class : wdxGraphicsWindow8 +// Description : A single graphics window for rendering DirectX under +// Microsoft Windows. +//////////////////////////////////////////////////////////////////// +class EXPCL_PANDADX wdxGraphicsWindow8 : public WinGraphicsWindow { +public: + wdxGraphicsWindow8(GraphicsPipe *pipe); + virtual ~wdxGraphicsWindow8(); + + virtual void make_gsg(); + virtual void release_gsg(); + + virtual bool begin_frame(); + virtual void end_flip(); + +protected: + virtual void fullscreen_restored(WindowProperties &properties); + virtual void handle_reshape(); + virtual bool do_fullscreen_resize(int x_size, int y_size); + +private: + // bool set_to_temp_rendertarget(); + void create_screen_buffers_and_device(DXScreenData &Display, + bool force_16bpp_zbuffer); + + bool choose_adapter(LPDIRECT3D8 pD3D8); + bool search_for_device(LPDIRECT3D8 pD3D8, DXDeviceInfo *device_info); + + // void set_coop_levels_and_display_modes(); + bool special_check_fullscreen_resolution(UINT x_size,UINT y_size); + + void search_for_valid_displaymode(UINT RequestedX_Size, UINT RequestedY_Size, + bool bWantZBuffer, bool bWantStencil, + UINT *pSupportedScreenDepthsMask, + bool *pCouldntFindAnyValidZBuf, + D3DFORMAT *pSuggestedPixFmt, + bool bVerboseMode = false); + + bool reset_device_resize_window(UINT new_xsize, UINT new_ysize); + void init_resized_window(); + bool find_best_depth_format(DXScreenData &Display, + D3DDISPLAYMODE &TestDisplayMode, + D3DFORMAT *pBestFmt, bool bWantStencil, + bool bForce16bpp, bool bVerboseMode = false) const; + + static int D3DFMT_to_DepthBits(D3DFORMAT fmt); + static bool is_badvidmem_card(D3DADAPTER_IDENTIFIER8 *pDevID); + + DXGraphicsStateGuardian8 *_dxgsg; + int _depth_buffer_bpp; + bool _awaiting_restore; + +public: + static TypeHandle get_class_type() { + return _type_handle; + } + static void init_type() { + WinGraphicsWindow::init_type(); + register_type(_type_handle, "wdxGraphicsWindow8", + WinGraphicsWindow::get_class_type()); + } + virtual TypeHandle get_type() const { + return get_class_type(); + } + virtual TypeHandle force_init_type() {init_type(); return get_class_type();} + +private: + static TypeHandle _type_handle; + friend class wdxGraphicsPipe8; +}; + +//extern bool is_badvidmem_card(D3DADAPTER_IDENTIFIER8 *pDevID); + +#include "wdxGraphicsWindow8.I" + +#endif diff --git a/panda/src/express/crypto_utils.cxx b/panda/src/express/crypto_utils.cxx index ce946fb890..0c4e931cd5 100644 --- a/panda/src/express/crypto_utils.cxx +++ b/panda/src/express/crypto_utils.cxx @@ -80,8 +80,6 @@ read32(istream& is) { void md5_a_file(const Filename &name, HashVal &ret) { - nassertv(name.exists()); - ostringstream os; MD5 md5; @@ -93,6 +91,13 @@ md5_a_file(const Filename &name, HashVal &ret) { } catch (...) { express_cat.warning() << "Unable to read " << name << " to compute md5 hash.\n"; + if (!name.exists()) { + express_cat.warning() + << "(file does not exist.)\n"; + } else { + express_cat.warning() + << "(file exists but cannot be read.)\n"; + } ret.hv[0] = 0; ret.hv[1] = 0; ret.hv[2] = 0; diff --git a/panda/src/express/mutex.I b/panda/src/express/mutex.I index 363651a195..07143b51af 100644 --- a/panda/src/express/mutex.I +++ b/panda/src/express/mutex.I @@ -64,11 +64,15 @@ operator = (const Mutex ©) { // return until the mutex is held; you should then call // unlock(). // +// This method is considered const so that you can lock +// and unlock const mutexes, mainly to allow thread-safe +// access to otherwise const data. +// // Also see MutexHolder. //////////////////////////////////////////////////////////////////// INLINE void Mutex:: -lock() { - _impl.lock(); +lock() const { + ((MutexImpl &)_impl).lock(); } //////////////////////////////////////////////////////////////////// @@ -76,8 +80,12 @@ lock() { // Access: Public // Description: Releases the mutex. It is an error to call this if // the mutex was not already locked. +// +// This method is considered const so that you can lock +// and unlock const mutexes, mainly to allow thread-safe +// access to otherwise const data. //////////////////////////////////////////////////////////////////// INLINE void Mutex:: -release() { - _impl.release(); +release() const { + ((MutexImpl &)_impl).release(); } diff --git a/panda/src/express/mutex.h b/panda/src/express/mutex.h index 5b547b7740..8041274849 100644 --- a/panda/src/express/mutex.h +++ b/panda/src/express/mutex.h @@ -39,8 +39,8 @@ private: INLINE void operator = (const Mutex ©); public: - INLINE void lock(); - INLINE void release(); + INLINE void lock() const; + INLINE void release() const; private: MutexImpl _impl; diff --git a/panda/src/express/mutexHolder.I b/panda/src/express/mutexHolder.I index 00f148872c..7a142d7f83 100644 --- a/panda/src/express/mutexHolder.I +++ b/panda/src/express/mutexHolder.I @@ -23,7 +23,7 @@ // Description: //////////////////////////////////////////////////////////////////// INLINE MutexHolder:: -MutexHolder(Mutex &mutex) { +MutexHolder(const Mutex &mutex) { #ifdef HAVE_THREADS _mutex = &mutex; _mutex->lock(); diff --git a/panda/src/express/mutexHolder.h b/panda/src/express/mutexHolder.h index 4288a0f43d..3b0327727e 100644 --- a/panda/src/express/mutexHolder.h +++ b/panda/src/express/mutexHolder.h @@ -32,7 +32,7 @@ //////////////////////////////////////////////////////////////////// class EXPCL_PANDA MutexHolder { public: - INLINE MutexHolder(Mutex &mutex); + INLINE MutexHolder(const Mutex &mutex); INLINE MutexHolder(Mutex *&mutex); INLINE ~MutexHolder(); private: @@ -41,7 +41,7 @@ private: private: #ifdef HAVE_THREADS - Mutex *_mutex; + const Mutex *_mutex; #endif }; diff --git a/panda/src/framework/config_framework.cxx b/panda/src/framework/config_framework.cxx index bf46691701..b37c25b69a 100644 --- a/panda/src/framework/config_framework.cxx +++ b/panda/src/framework/config_framework.cxx @@ -29,6 +29,8 @@ ConfigureFn(config_framework) { const int win_width = config_framework.GetInt("win-width", 640); const int win_height = config_framework.GetInt("win-height", 480); const bool fullscreen = config_framework.GetBool("fullscreen", false); +const bool undecorated = config_framework.GetBool("undecorated", false); +const bool cursor_hidden = config_framework.GetBool("cursor-hidden", false); // The default window background color. const float win_background_r = config_framework.GetFloat("win-background-r", 0.41); diff --git a/panda/src/framework/config_framework.h b/panda/src/framework/config_framework.h index 433959ca3d..b7c66e8097 100644 --- a/panda/src/framework/config_framework.h +++ b/panda/src/framework/config_framework.h @@ -28,6 +28,8 @@ NotifyCategoryDecl(framework, EXPCL_FRAMEWORK, EXPTP_FRAMEWORK); extern const int win_width; extern const int win_height; extern const bool fullscreen; +extern const bool undecorated; +extern const bool cursor_hidden; extern const float win_background_r; extern const float win_background_g; diff --git a/panda/src/framework/pandaFramework.I b/panda/src/framework/pandaFramework.I index ed7255a0ae..946ef85a2e 100644 --- a/panda/src/framework/pandaFramework.I +++ b/panda/src/framework/pandaFramework.I @@ -126,6 +126,16 @@ get_lighting() const { return _lighting_enabled; } +//////////////////////////////////////////////////////////////////// +// Function: PandaFramework::get_background_type +// Access: Public +// Description: Returns the current background type setting. +//////////////////////////////////////////////////////////////////// +INLINE WindowFramework::BackgroundType PandaFramework:: +get_background_type() const { + return _background_type; +} + //////////////////////////////////////////////////////////////////// // Function: PandaFramework::has_highlight // Access: Public diff --git a/panda/src/framework/pandaFramework.cxx b/panda/src/framework/pandaFramework.cxx index 198505d5dc..5669b0a0ca 100644 --- a/panda/src/framework/pandaFramework.cxx +++ b/panda/src/framework/pandaFramework.cxx @@ -21,9 +21,9 @@ #include "pStatClient.h" #include "eventQueue.h" #include "dataGraphTraverser.h" -#include "interactiveGraphicsPipe.h" #include "collisionNode.h" #include "config_framework.h" +#include "graphicsPipeSelection.h" //////////////////////////////////////////////////////////////////// // Function: PandaFramework::Constructor @@ -44,6 +44,7 @@ PandaFramework() : _texture_enabled = true; _two_sided_enabled = false; _lighting_enabled = false; + _background_type = WindowFramework::BT_gray; _default_keys_enabled = false; _exit_flag = false; } @@ -94,8 +95,8 @@ close_framework() { } close_all_windows(); - // We should define this function on GraphicsEngine. - // _engine.remove_all_windows(); + // Also close down any other windows that might have been opened. + _engine.remove_all_windows(); _event_handler.remove_all_hooks(); _is_open = false; @@ -144,16 +145,13 @@ get_default_pipe() { // application. //////////////////////////////////////////////////////////////////// void PandaFramework:: -get_default_window_props(GraphicsWindow::Properties &props) { - props._xorg = 0; - props._yorg = 0; - props._xsize = win_width; - props._ysize = win_height; - props._fullscreen = fullscreen; - props._title = _window_title; - - props.set_clear_color(Colorf(win_background_r, win_background_g, - win_background_b, 1.0f)); +get_default_window_props(WindowProperties &props) { + props.set_open(true); + props.set_size(win_width, win_height); + props.set_fullscreen(fullscreen); + props.set_undecorated(undecorated); + props.set_cursor_hidden(cursor_hidden); + props.set_title(_window_title); } //////////////////////////////////////////////////////////////////// @@ -167,7 +165,7 @@ WindowFramework *PandaFramework:: open_window(GraphicsPipe *pipe) { nassertr(_is_open, NULL); - GraphicsWindow::Properties props; + WindowProperties props; get_default_window_props(props); return open_window(props, pipe); @@ -184,7 +182,7 @@ open_window(GraphicsPipe *pipe) { // NULL if not. //////////////////////////////////////////////////////////////////// WindowFramework *PandaFramework:: -open_window(const GraphicsWindow::Properties &props, GraphicsPipe *pipe) { +open_window(const WindowProperties &props, GraphicsPipe *pipe) { if (pipe == (GraphicsPipe *)NULL) { pipe = get_default_pipe(); if (pipe == (GraphicsPipe *)NULL) { @@ -195,12 +193,14 @@ open_window(const GraphicsWindow::Properties &props, GraphicsPipe *pipe) { nassertr(_is_open, NULL); WindowFramework *wf = make_window_framework(); + wf->set_wireframe(get_wireframe()); + wf->set_texture(get_texture()); + wf->set_two_sided(get_two_sided()); + wf->set_lighting(get_lighting()); + wf->set_background_type(get_background_type()); _windows.push_back(wf); - GraphicsWindow *win = wf->open_window(props, pipe); - if (win != (GraphicsWindow *)NULL) { - _engine.add_window(win); - } + wf->open_window(props, &_engine, pipe); return wf; } @@ -219,7 +219,7 @@ close_window(int n) { if (win != (GraphicsWindow *)NULL) { _engine.remove_window(win); } - + wf->close_window(); delete wf; _windows.erase(_windows.begin() + n); @@ -249,6 +249,25 @@ close_all_windows() { _windows.clear(); } +//////////////////////////////////////////////////////////////////// +// Function: PandaFramework::all_windows_closed +// Access: Public +// Description: Returns true if all of the opened windows have been +// closed by the user, false otherwise. +//////////////////////////////////////////////////////////////////// +bool PandaFramework:: +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()) { + return false; + } + } + + return true; +} + //////////////////////////////////////////////////////////////////// // Function: PandaFramework::get_models // Access: Public @@ -360,6 +379,22 @@ set_lighting(bool enable) { _lighting_enabled = enable; } +//////////////////////////////////////////////////////////////////// +// Function: BackgroundFramework::set_background_type +// Access: Public +// Description: Sets the background type of all windows. +//////////////////////////////////////////////////////////////////// +void PandaFramework:: +set_background_type(WindowFramework::BackgroundType type) { + Windows::iterator wi; + for (wi = _windows.begin(); wi != _windows.end(); ++wi) { + WindowFramework *wf = (*wi); + wf->set_background_type(type); + } + + _background_type = type; +} + //////////////////////////////////////////////////////////////////// // Function: PandaFramework::hide_collision_solids // Access: Public @@ -516,13 +551,16 @@ make_default_pipe() { // This depends on the shared library or libraries (DLL's to you // Windows folks) that have been loaded in at runtime from the // load-display Configrc variable. - GraphicsPipe::resolve_modules(); + GraphicsPipeSelection *selection = GraphicsPipeSelection::get_global_ptr(); + selection->resolve_modules(); nout << "Known pipe types:" << endl; - GraphicsPipe::get_factory().write_types(nout, 2); + int num_pipe_types = selection->get_num_pipe_types(); + for (int i = 0; i < num_pipe_types; i++) { + nout << " " << selection->get_pipe_type(i) << "\n"; + } - _default_pipe = GraphicsPipe::get_factory(). - make_instance(InteractiveGraphicsPipe::get_class_type()); + _default_pipe = selection->make_default_pipe(); if (_default_pipe == (GraphicsPipe*)NULL) { nout << "No interactive pipe is available! Check your Configrc!\n"; @@ -553,6 +591,8 @@ do_enable_default_keys() { _event_handler.add_hook("arrow_left", event_arrow_left, this); _event_handler.add_hook("arrow_right", event_arrow_right, this); _event_handler.add_hook("shift-s", event_S, this); + _event_handler.add_hook(",", event_comma, this); + _event_handler.add_hook("window-event", event_window_event, this); } //////////////////////////////////////////////////////////////////// @@ -823,3 +863,48 @@ event_S(CPT_Event, void *data) { nout << "Stats host not supported." << endl; #endif } + +//////////////////////////////////////////////////////////////////// +// Function: PandaFramework::event_comma +// Access: Protected, Static +// Description: Default handler for comma key: rotate background color. +//////////////////////////////////////////////////////////////////// +void PandaFramework:: +event_comma(CPT_Event, void *data) { + PandaFramework *self = (PandaFramework *)data; + + switch (self->get_background_type()) { + case WindowFramework::BT_other: + break; + + case WindowFramework::BT_none: + self->set_background_type(WindowFramework::BT_default); + break; + + default: + self->set_background_type((WindowFramework::BackgroundType)(self->get_background_type() + 1)); + } +} + +//////////////////////////////////////////////////////////////////// +// Function: PandaFramework::event_window_event +// Access: Protected, Static +// Description: Default handler for window events: window resized or +// closed, etc. +//////////////////////////////////////////////////////////////////// +void PandaFramework:: +event_window_event(CPT_Event event, void *data) { + PandaFramework *self = (PandaFramework *)data; + if (event->get_num_parameters() == 1) { + EventParameter param = event->get_parameter(0); + const GraphicsWindow *win; + DCAST_INTO_V(win, param.get_ptr()); + + if (!win->get_properties().get_open()) { + // If the last window was closed, exit the application. + if (self->all_windows_closed()) { + self->_exit_flag = true; + } + } + } +} diff --git a/panda/src/framework/pandaFramework.h b/panda/src/framework/pandaFramework.h index 4b361f3cd4..3815faa37b 100644 --- a/panda/src/framework/pandaFramework.h +++ b/panda/src/framework/pandaFramework.h @@ -52,16 +52,17 @@ public: INLINE EventHandler &get_event_handler(); INLINE void set_window_title(const string &title); - virtual void get_default_window_props(GraphicsWindow::Properties &props); + virtual void get_default_window_props(WindowProperties &props); WindowFramework *open_window(GraphicsPipe *pipe = NULL); - WindowFramework *open_window(const GraphicsWindow::Properties &props, + WindowFramework *open_window(const WindowProperties &props, GraphicsPipe *pipe = NULL); INLINE int get_num_windows() const; INLINE WindowFramework *get_window(int n) const; void close_window(int n); void close_all_windows(); + bool all_windows_closed() const; const NodePath &get_models(); @@ -72,11 +73,13 @@ public: void set_texture(bool enable); void set_two_sided(bool enable); void set_lighting(bool enable); + void set_background_type(WindowFramework::BackgroundType type); INLINE bool get_wireframe() const; INLINE bool get_texture() const; INLINE bool get_two_sided() const; INLINE bool get_lighting() const; + INLINE WindowFramework::BackgroundType get_background_type() const; static int hide_collision_solids(NodePath node); static int show_collision_solids(NodePath node); @@ -114,6 +117,8 @@ protected: static void event_arrow_left(CPT_Event, void *data); static void event_arrow_right(CPT_Event, void *data); static void event_S(CPT_Event, void *data); + static void event_comma(CPT_Event, void *data); + static void event_window_event(CPT_Event, void *data); private: @@ -141,6 +146,7 @@ private: bool _texture_enabled; bool _two_sided_enabled; bool _lighting_enabled; + WindowFramework::BackgroundType _background_type; NodePath _highlight; diff --git a/panda/src/framework/windowFramework.I b/panda/src/framework/windowFramework.I index f5d7333004..1f11dc1b3c 100644 --- a/panda/src/framework/windowFramework.I +++ b/panda/src/framework/windowFramework.I @@ -102,3 +102,13 @@ INLINE bool WindowFramework:: get_lighting() const { return _lighting_enabled; } + +//////////////////////////////////////////////////////////////////// +// Function: WindowFramework::get_background_type +// Access: Public +// Description: Returns the current background type setting. +//////////////////////////////////////////////////////////////////// +INLINE WindowFramework::BackgroundType WindowFramework:: +get_background_type() const { + return _background_type; +} diff --git a/panda/src/framework/windowFramework.cxx b/panda/src/framework/windowFramework.cxx index 65813ac674..fde02d5090 100644 --- a/panda/src/framework/windowFramework.cxx +++ b/panda/src/framework/windowFramework.cxx @@ -59,6 +59,7 @@ WindowFramework(PandaFramework *panda_framework) : _texture_enabled = true; _two_sided_enabled = false; _lighting_enabled = false; + _background_type = BT_default; } //////////////////////////////////////////////////////////////////// @@ -78,10 +79,15 @@ WindowFramework:: // only from PandaFramework::open_window(). //////////////////////////////////////////////////////////////////// GraphicsWindow *WindowFramework:: -open_window(const GraphicsWindow::Properties &props, GraphicsPipe *pipe) { +open_window(const WindowProperties &props, GraphicsEngine *engine, + GraphicsPipe *pipe) { nassertr(_window == (GraphicsWindow *)NULL, _window); - _window = pipe->make_window(props); + _window = engine->make_window(pipe); + if (_window != (GraphicsWindow *)NULL) { + _window->request_properties(props); + set_background_type(_background_type); + } // Set up a 3-d camera for the window by default. make_camera(); @@ -167,6 +173,7 @@ get_render_2d() { const NodePath &WindowFramework:: get_mouse() { if (_mouse.is_empty()) { + nassertr(_window->get_num_input_devices() > 0, _mouse); NodePath data_root = _panda_framework->get_data_root(); MouseAndKeyboard *mouse_node = new MouseAndKeyboard(_window, 0, "mouse"); @@ -187,15 +194,17 @@ enable_keyboard() { return; } - NodePath mouse = get_mouse(); + if (_window->get_num_input_devices() > 0) { + NodePath mouse = get_mouse(); - PT(ButtonThrower) bt = new ButtonThrower("kb-events"); - ModifierButtons mods; - mods.add_button(KeyboardButton::shift()); - mods.add_button(KeyboardButton::control()); - mods.add_button(KeyboardButton::alt()); - bt->set_modifier_buttons(mods); - mouse.attach_new_node(bt); + PT(ButtonThrower) bt = new ButtonThrower("kb-events"); + ModifierButtons mods; + mods.add_button(KeyboardButton::shift()); + mods.add_button(KeyboardButton::control()); + mods.add_button(KeyboardButton::alt()); + bt->set_modifier_buttons(mods); + mouse.attach_new_node(bt); + } _got_keyboard = true; } @@ -211,16 +220,18 @@ setup_trackball() { return; } - NodePath mouse = get_mouse(); - NodePath camera = get_camera_group(); + if (_window->get_num_input_devices() > 0) { + NodePath mouse = get_mouse(); + NodePath camera = get_camera_group(); - _trackball = new Trackball("trackball"); - _trackball->set_pos(LVector3f::forward() * 50.0); - mouse.attach_new_node(_trackball); - - PT(Transform2SG) tball2cam = new Transform2SG("tball2cam"); - tball2cam->set_node(camera.node()); - _trackball->add_child(tball2cam); + _trackball = new Trackball("trackball"); + _trackball->set_pos(LVector3f::forward() * 50.0); + mouse.attach_new_node(_trackball); + + PT(Transform2SG) tball2cam = new Transform2SG("tball2cam"); + tball2cam->set_node(camera.node()); + _trackball->add_child(tball2cam); + } _got_trackball = true; } @@ -233,6 +244,10 @@ setup_trackball() { //////////////////////////////////////////////////////////////////// void WindowFramework:: center_trackball(const NodePath &object) { + if (_trackball == (Trackball *)NULL) { + return; + } + PT(BoundingVolume) volume = object.get_bounds(); // We expect at least a geometric bounding volume around the world. nassertv(volume != (BoundingVolume *)NULL); @@ -541,6 +556,53 @@ set_lighting(bool enable) { _lighting_enabled = enable; } +//////////////////////////////////////////////////////////////////// +// Function: WindowFramework::set_background_type +// Access: Public +// Description: Sets the background of the window to one of the +// pre-canned background types (or to BT_other, which +// indicates the user intends to set up his own special +// background mode). +//////////////////////////////////////////////////////////////////// +void WindowFramework:: +set_background_type(WindowFramework::BackgroundType type) { + _background_type = type; + + if (_window != (GraphicsWindow *)NULL) { + switch (_background_type) { + case BT_other: + break; + + case BT_default: + _window->set_clear_color_active(true); + _window->set_clear_depth_active(true); + _window->set_clear_color(Colorf(win_background_r, win_background_g, + win_background_b, 1.0f)); + _window->set_clear_depth(1.0f); + break; + + case BT_gray: + _window->set_clear_color_active(true); + _window->set_clear_depth_active(true); + _window->set_clear_color(Colorf(0.3f, 0.3f, 0.3f, 1.0f)); + _window->set_clear_depth(1.0f); + break; + + case BT_black: + _window->set_clear_color_active(true); + _window->set_clear_depth_active(true); + _window->set_clear_color(Colorf(0.0f, 0.0f, 0.0f, 1.0f)); + _window->set_clear_depth(1.0f); + break; + + case BT_none: + _window->set_clear_color_active(false); + _window->set_clear_depth_active(false); + break; + } + } +} + //////////////////////////////////////////////////////////////////// // Function: WindowFramework::make_camera // Access: Protected @@ -564,7 +626,13 @@ make_camera() { _cameras.push_back(camera); PT(Lens) lens = new PerspectiveLens; - lens->set_film_size(_window->get_width(), _window->get_height()); + 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()); + } camera->set_lens(lens); camera->set_scene(get_render()); dr->set_camera(camera_np); diff --git a/panda/src/framework/windowFramework.h b/panda/src/framework/windowFramework.h index 4e4258b8a7..07a2f4bf69 100644 --- a/panda/src/framework/windowFramework.h +++ b/panda/src/framework/windowFramework.h @@ -32,6 +32,8 @@ class PandaFramework; class AmbientLight; class DirectionalLight; +class GraphicsEngine; +class GraphicsPipe; //////////////////////////////////////////////////////////////////// // Class : WindowFramework @@ -43,8 +45,8 @@ protected: WindowFramework(PandaFramework *panda_framework); virtual ~WindowFramework(); - GraphicsWindow *open_window(const GraphicsWindow::Properties &props, - GraphicsPipe *pipe); + GraphicsWindow *open_window(const WindowProperties &props, + GraphicsEngine *engine, GraphicsPipe *pipe); void close_window(); public: @@ -71,15 +73,25 @@ public: NodePath load_default_model(const NodePath &parent); void loop_animations(); + enum BackgroundType { + BT_other = 0, + BT_default, + BT_gray, + BT_black, + BT_none + }; + void set_wireframe(bool enable); void set_texture(bool enable); void set_two_sided(bool enable); void set_lighting(bool enable); + void set_background_type(BackgroundType type); INLINE bool get_wireframe() const; INLINE bool get_texture() const; INLINE bool get_two_sided() const; INLINE bool get_lighting() const; + INLINE BackgroundType get_background_type() const; protected: PT(Camera) make_camera(); @@ -112,6 +124,8 @@ private: bool _two_sided_enabled; bool _lighting_enabled; + BackgroundType _background_type; + friend class PandaFramework; }; diff --git a/panda/src/glgsg/glGraphicsStateGuardian.I b/panda/src/glgsg/glGraphicsStateGuardian.I index 44f1ff631d..f4f74c6a2b 100644 --- a/panda/src/glgsg/glGraphicsStateGuardian.I +++ b/panda/src/glgsg/glGraphicsStateGuardian.I @@ -18,23 +18,26 @@ #include "config_glgsg.h" -#include +#include "graphicsWindow.h" //////////////////////////////////////////////////////////////////// -// Function: GLGraphicsStateGuardian::activate -// Access: Public -// Description: Sets this context to be the active context for future -// GL commands. +// Function: GLGraphicsStateGuardian::report_errors +// Access: Public, Static +// Description: Checks for any outstanding error codes and outputs +// them, if found. If NDEBUG is defined, this function +// does nothing. +// +// This is a static method so it can be called when +// there's no gsg pointer around. //////////////////////////////////////////////////////////////////// INLINE void GLGraphicsStateGuardian:: -activate() { - // This operation seems to be incredibly expensive on some - // platforms--particularly for the NVidia drivers under Linux. It - // doesn't seem to check if we already had the context current - // before we switch contexts. For now, we'll limit our use of this - // function. - - _win->make_current(); +report_errors(int line, const char *source_file) { +#ifndef NDEBUG + GLenum error_code = glGetError(); + if (error_code != GL_NO_ERROR) { + report_errors_loop(line, source_file, error_code); + } +#endif } //////////////////////////////////////////////////////////////////// @@ -1008,23 +1011,3 @@ issue_scene_graph_color() { _scene_graph_color_stale = false; } } - -//////////////////////////////////////////////////////////////////// -// Function: GLGraphicsStateGuardian::report_errors -// Access: Public -// Description: Checks for any outstanding error codes and outputs -// them, if found. If NDEBUG is defined, this function -// does nothing. -//////////////////////////////////////////////////////////////////// -INLINE void -report_errors() { - // pulling this out of gsg since I'd like to call it when there's no gsg ptr around -#ifndef NDEBUG - extern void report_errors_loop(GLenum error_code); - - GLenum error_code = glGetError(); - if (error_code != GL_NO_ERROR) { - report_errors_loop(error_code); - } -#endif -} diff --git a/panda/src/glgsg/glGraphicsStateGuardian.cxx b/panda/src/glgsg/glGraphicsStateGuardian.cxx index c9b95598c0..b0a3e764f1 100644 --- a/panda/src/glgsg/glGraphicsStateGuardian.cxx +++ b/panda/src/glgsg/glGraphicsStateGuardian.cxx @@ -153,7 +153,6 @@ GLGraphicsStateGuardian:: void GLGraphicsStateGuardian:: reset() { free_pointers(); - activate(); GraphicsStateGuardian::reset(); _buffer_mask = 0; @@ -165,6 +164,10 @@ reset() { RenderBuffer::T_accum); // Check to see if we have double-buffering. + + // This isn't completely right. Instead of just clearing this bit + // and disallowing writes to T_back, we need to set T_front on + // operations that might have had T_back set otherwise. GLboolean has_back; glGetBooleanv(GL_DOUBLEBUFFER, &has_back); if (!has_back) { @@ -296,6 +299,7 @@ reset() { if(glgsg_cat.is_debug()) glgsg_cat.debug() << "frame buffer depth < 8bits channel, enabling dithering\n"; } + report_gl_errors(); } @@ -307,9 +311,7 @@ reset() { //////////////////////////////////////////////////////////////////// void GLGraphicsStateGuardian:: do_clear(const RenderBuffer &buffer) { - DO_PSTATS_STUFF(PStatTimer timer(_win->_clear_pcollector);) - // activate(); - + // DO_PSTATS_STUFF(PStatTimer timer(_win->_clear_pcollector);) nassertv(buffer._gsg == this); int buffer_type = buffer._buffer_type; GLbitfield mask = 0; @@ -368,7 +370,9 @@ do_clear(const RenderBuffer &buffer) { #endif modify_state(state); + glClear(mask); + report_gl_errors(); } //////////////////////////////////////////////////////////////////// @@ -398,6 +402,7 @@ prepare_display_region() { call_glScissor( x, y, width, height ); call_glViewport( x, y, width, height ); } + report_gl_errors(); } //////////////////////////////////////////////////////////////////// @@ -442,10 +447,47 @@ prepare_lens() { #endif glMatrixMode(GL_PROJECTION); glLoadMatrixf(new_projection_mat.get_data()); + report_gl_errors(); return true; } +//////////////////////////////////////////////////////////////////// +// Function: GraphicsStateGuardian::begin_frame +// Access: Public, Virtual +// Description: Called before each frame is rendered, to allow the +// GSG a chance to do any internal cleanup before +// beginning the frame. +// +// The return value is true if successful (in which case +// the frame will be drawn and end_frame() will be +// called later), or false if unsuccessful (in which +// case nothing will be drawn and end_frame() will not +// be called). +//////////////////////////////////////////////////////////////////// +bool GLGraphicsStateGuardian:: +begin_frame() { + if (!GraphicsStateGuardian::begin_frame()) { + return false; + } + + report_gl_errors(); + return true; +} + +//////////////////////////////////////////////////////////////////// +// Function: GLGraphicsStateGuardian::end_frame +// Access: Public, Virtual +// Description: Called after each frame is rendered, to allow the +// GSG a chance to do any internal cleanup after +// rendering the frame, and before the window flips. +//////////////////////////////////////////////////////////////////// +void GLGraphicsStateGuardian:: +end_frame() { + GraphicsStateGuardian::end_frame(); + report_gl_errors(); +} + //////////////////////////////////////////////////////////////////// // Function: GLGraphicsStateGuardian::draw_point // Access: Public, Virtual @@ -453,8 +495,6 @@ prepare_lens() { //////////////////////////////////////////////////////////////////// void GLGraphicsStateGuardian:: draw_point(GeomPoint *geom, GeomContext *) { - // activate(); - #ifdef GSG_VERBOSE glgsg_cat.debug() << "draw_point()" << endl; #endif @@ -505,7 +545,7 @@ draw_point(GeomPoint *geom, GeomContext *) { } glEnd(); - report_errors(); + report_gl_errors(); } //////////////////////////////////////////////////////////////////// @@ -515,8 +555,6 @@ draw_point(GeomPoint *geom, GeomContext *) { //////////////////////////////////////////////////////////////////// void GLGraphicsStateGuardian:: draw_line(GeomLine *geom, GeomContext *) { - // activate(); - #ifdef GSG_VERBOSE glgsg_cat.debug() << "draw_line()" << endl; #endif @@ -578,7 +616,7 @@ draw_line(GeomLine *geom, GeomContext *) { } glEnd(); - report_errors(); + report_gl_errors(); } //////////////////////////////////////////////////////////////////// @@ -588,8 +626,6 @@ draw_line(GeomLine *geom, GeomContext *) { //////////////////////////////////////////////////////////////////// void GLGraphicsStateGuardian:: draw_linestrip(GeomLinestrip *geom, GeomContext *) { - // activate(); - #ifdef GSG_VERBOSE glgsg_cat.debug() << "draw_linestrip()" << endl; #endif @@ -676,7 +712,7 @@ draw_linestrip(GeomLinestrip *geom, GeomContext *) { } glEnd(); } - report_errors(); + report_gl_errors(); DO_PSTATS_STUFF(_draw_primitive_pcollector.stop()); } @@ -949,7 +985,7 @@ draw_sprite(GeomSprite *geom, GeomContext *) { if(alpha && _dithering_enabled) glEnable(GL_DITHER); - report_errors(); + report_gl_errors(); DO_PSTATS_STUFF(_draw_primitive_pcollector.stop()); } @@ -961,8 +997,6 @@ draw_sprite(GeomSprite *geom, GeomContext *) { //////////////////////////////////////////////////////////////////// void GLGraphicsStateGuardian:: draw_polygon(GeomPolygon *geom, GeomContext *) { - // activate(); - #ifdef GSG_VERBOSE glgsg_cat.debug() << "draw_polygon()" << endl; #endif @@ -1031,7 +1065,7 @@ draw_polygon(GeomPolygon *geom, GeomContext *) { } glEnd(); } - report_errors(); + report_gl_errors(); DO_PSTATS_STUFF(_draw_primitive_pcollector.stop()); } @@ -1042,8 +1076,6 @@ draw_polygon(GeomPolygon *geom, GeomContext *) { //////////////////////////////////////////////////////////////////// void GLGraphicsStateGuardian:: draw_tri(GeomTri *geom, GeomContext *) { - // activate(); - #ifdef GSG_VERBOSE glgsg_cat.debug() << "draw_tri()" << endl; #endif @@ -1107,7 +1139,7 @@ draw_tri(GeomTri *geom, GeomContext *) { } glEnd(); - report_errors(); + report_gl_errors(); #ifdef DO_PSTATS _draw_primitive_pcollector.stop(); #endif @@ -1120,8 +1152,6 @@ draw_tri(GeomTri *geom, GeomContext *) { //////////////////////////////////////////////////////////////////// void GLGraphicsStateGuardian:: draw_quad(GeomQuad *geom, GeomContext *) { - // activate(); - #ifdef GSG_VERBOSE glgsg_cat.debug() << "draw_quad()" << endl; #endif @@ -1185,7 +1215,7 @@ draw_quad(GeomQuad *geom, GeomContext *) { } glEnd(); - report_errors(); + report_gl_errors(); DO_PSTATS_STUFF(_draw_primitive_pcollector.stop()); } @@ -1196,8 +1226,6 @@ draw_quad(GeomQuad *geom, GeomContext *) { //////////////////////////////////////////////////////////////////// void GLGraphicsStateGuardian:: draw_tristrip(GeomTristrip *geom, GeomContext *) { - // activate(); - #ifdef GSG_VERBOSE glgsg_cat.debug() << "draw_tristrip()" << endl; #endif @@ -1283,7 +1311,7 @@ draw_tristrip(GeomTristrip *geom, GeomContext *) { } glEnd(); } - report_errors(); + report_gl_errors(); DO_PSTATS_STUFF(_draw_primitive_pcollector.stop()); } @@ -1294,8 +1322,6 @@ draw_tristrip(GeomTristrip *geom, GeomContext *) { //////////////////////////////////////////////////////////////////// void GLGraphicsStateGuardian:: draw_trifan(GeomTrifan *geom, GeomContext *) { - // activate(); - #ifdef GSG_VERBOSE glgsg_cat.debug() << "draw_trifan()" << endl; #endif @@ -1381,7 +1407,7 @@ draw_trifan(GeomTrifan *geom, GeomContext *) { } glEnd(); } - report_errors(); + report_gl_errors(); DO_PSTATS_STUFF(_draw_primitive_pcollector.stop()); } @@ -1393,8 +1419,6 @@ draw_trifan(GeomTrifan *geom, GeomContext *) { //////////////////////////////////////////////////////////////////// void GLGraphicsStateGuardian:: draw_sphere(GeomSphere *geom, GeomContext *) { - // activate(); - #ifdef GSG_VERBOSE glgsg_cat.debug() << "draw_sphere()" << endl; #endif @@ -1470,7 +1494,7 @@ draw_sphere(GeomSphere *geom, GeomContext *) { } gluDeleteQuadric(sph); - report_errors(); + report_gl_errors(); DO_PSTATS_STUFF(_draw_primitive_pcollector.stop()); } @@ -1486,8 +1510,6 @@ draw_sphere(GeomSphere *geom, GeomContext *) { //////////////////////////////////////////////////////////////////// TextureContext *GLGraphicsStateGuardian:: prepare_texture(Texture *tex) { - // activate(); - GLint max_tex_size; glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max_tex_size); @@ -1524,7 +1546,7 @@ prepare_texture(Texture *tex) { // detect this. nassertr(inserted, NULL); - report_errors(); + report_gl_errors(); return gtc; } @@ -1536,7 +1558,6 @@ prepare_texture(Texture *tex) { //////////////////////////////////////////////////////////////////// void GLGraphicsStateGuardian:: apply_texture(TextureContext *tc) { - // activate(); add_to_texture_record(tc); bind_texture(tc); @@ -1552,7 +1573,7 @@ apply_texture(TextureContext *tc) { tc->clear_dirty_flags(); - report_errors(); + report_gl_errors(); } //////////////////////////////////////////////////////////////////// @@ -1563,7 +1584,6 @@ apply_texture(TextureContext *tc) { //////////////////////////////////////////////////////////////////// void GLGraphicsStateGuardian:: release_texture(TextureContext *tc) { - // activate(); GLTextureContext *gtc = DCAST(GLTextureContext, tc); Texture *tex = tc->_texture; @@ -1581,7 +1601,7 @@ release_texture(TextureContext *tc) { tex->clear_gsg(this); delete gtc; - report_errors(); + report_gl_errors(); } //////////////////////////////////////////////////////////////////// @@ -1772,8 +1792,6 @@ static int binary_log_cap(const int x) { void GLGraphicsStateGuardian:: copy_texture(TextureContext *tc, const DisplayRegion *dr) { nassertv(tc != NULL && dr != NULL); - // activate(); - Texture *tex = tc->_texture; int xo, yo, w, h; @@ -1819,7 +1837,6 @@ copy_texture(TextureContext *tc, const DisplayRegion *dr) { //////////////////////////////////////////////////////////////////// void GLGraphicsStateGuardian:: copy_texture(TextureContext *tc, const DisplayRegion *dr, const RenderBuffer &rb) { - // activate(); set_read_buffer(rb); copy_texture(tc, dr); } @@ -1832,8 +1849,6 @@ copy_texture(TextureContext *tc, const DisplayRegion *dr, const RenderBuffer &rb void GLGraphicsStateGuardian:: texture_to_pixel_buffer(TextureContext *tc, PixelBuffer *pb) { nassertv(tc != NULL && pb != NULL); - // activate(); - Texture *tex = tc->_texture; int w = tex->_pbuffer->get_xsize(); @@ -1848,7 +1863,7 @@ texture_to_pixel_buffer(TextureContext *tc, PixelBuffer *pb) { texture_to_pixel_buffer(tc, pb, dr); pop_frame_buffer(old_fb); - report_errors(); + report_gl_errors(); } //////////////////////////////////////////////////////////////////// @@ -1860,8 +1875,6 @@ void GLGraphicsStateGuardian:: texture_to_pixel_buffer(TextureContext *tc, PixelBuffer *pb, const DisplayRegion *dr) { nassertv(tc != NULL && pb != NULL && dr != NULL); - // activate(); - Texture *tex = tc->_texture; // Do a deep copy to initialize the pixel buffer @@ -1876,7 +1889,7 @@ texture_to_pixel_buffer(TextureContext *tc, PixelBuffer *pb, pb->_image = PTA_uchar::empty_array(w * h * pb->get_num_components()); copy_pixel_buffer(pb, dr); } - report_errors(); + report_gl_errors(); } //////////////////////////////////////////////////////////////////// @@ -1887,7 +1900,6 @@ texture_to_pixel_buffer(TextureContext *tc, PixelBuffer *pb, void GLGraphicsStateGuardian:: copy_pixel_buffer(PixelBuffer *pb, const DisplayRegion *dr) { nassertv(pb != NULL && dr != NULL); - // activate(); set_pack_alignment(1); // Bug fix for RE, RE2, and VTX - need to disable texturing in order @@ -1950,7 +1962,7 @@ copy_pixel_buffer(PixelBuffer *pb, const DisplayRegion *dr) { get_image_type(pb->get_image_type()), pb->_image.p()); - report_errors(); + report_gl_errors(); } //////////////////////////////////////////////////////////////////// @@ -1961,7 +1973,6 @@ copy_pixel_buffer(PixelBuffer *pb, const DisplayRegion *dr) { void GLGraphicsStateGuardian:: copy_pixel_buffer(PixelBuffer *pb, const DisplayRegion *dr, const RenderBuffer &rb) { - // activate(); set_read_buffer(rb); copy_pixel_buffer(pb, dr); } @@ -2008,7 +2019,7 @@ void GLGraphicsStateGuardian::apply_material(const Material *material) { call_glLightModelLocal(material->get_local()); call_glLightModelTwoSide(material->get_twoside()); - report_errors(); + report_gl_errors(); } //////////////////////////////////////////////////////////////////// @@ -2033,7 +2044,7 @@ apply_fog(Fog *fog) { } call_glFogColor(fog->get_color()); - report_errors(); + report_gl_errors(); } //////////////////////////////////////////////////////////////////// @@ -2051,7 +2062,7 @@ issue_transform(const TransformState *transform) { glMatrixMode(GL_MODELVIEW); glLoadMatrixf(transform->get_mat().get_data()); - report_errors(); + report_gl_errors(); } //////////////////////////////////////////////////////////////////// @@ -2063,7 +2074,7 @@ void GLGraphicsStateGuardian:: issue_tex_matrix(const TexMatrixAttrib *attrib) { glMatrixMode(GL_TEXTURE); glLoadMatrixf(attrib->get_mat().get_data()); - report_errors(); + report_gl_errors(); } //////////////////////////////////////////////////////////////////// @@ -2081,7 +2092,7 @@ issue_texture(const TextureAttrib *attrib) { nassertv(tex != (Texture *)NULL); tex->apply(this); } - report_errors(); + report_gl_errors(); } //////////////////////////////////////////////////////////////////// @@ -2099,7 +2110,7 @@ issue_material(const MaterialAttrib *attrib) { Material empty; apply_material(&empty); } - report_errors(); + report_gl_errors(); } //////////////////////////////////////////////////////////////////// @@ -2125,7 +2136,7 @@ issue_render_mode(const RenderModeAttrib *attrib) { glgsg_cat.error() << "Unknown render mode " << (int)mode << endl; } - report_errors(); + report_gl_errors(); } //////////////////////////////////////////////////////////////////// @@ -2137,7 +2148,7 @@ void GLGraphicsStateGuardian:: issue_texture_apply(const TextureApplyAttrib *attrib) { GLint glmode = get_texture_apply_mode_type(attrib->get_mode()); glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, glmode); - report_errors(); + report_gl_errors(); } //////////////////////////////////////////////////////////////////// @@ -2159,7 +2170,7 @@ issue_color_write(const ColorWriteAttrib *attrib) { } else { glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); } - report_errors(); + report_gl_errors(); } else { // Some implementations don't seem to handle glColorMask() very @@ -2185,7 +2196,7 @@ issue_depth_test(const DepthTestAttrib *attrib) { enable_depth_test(true); glDepthFunc(PANDA_TO_GL_COMPAREFUNC(mode)); } - report_errors(); + report_gl_errors(); } //////////////////////////////////////////////////////////////////// @@ -2218,7 +2229,7 @@ issue_depth_write(const DepthWriteAttrib *attrib) { } else { glDepthMask(GL_TRUE); } - report_errors(); + report_gl_errors(); } //////////////////////////////////////////////////////////////////// @@ -2247,7 +2258,7 @@ issue_cull_face(const CullFaceAttrib *attrib) { << "invalid cull face mode " << (int)mode << endl; break; } - report_errors(); + report_gl_errors(); } //////////////////////////////////////////////////////////////////// @@ -2265,7 +2276,7 @@ issue_fog(const FogAttrib *attrib) { } else { enable_fog(false); } - report_errors(); + report_gl_errors(); } //////////////////////////////////////////////////////////////////// @@ -2287,7 +2298,7 @@ issue_depth_offset(const DepthOffsetAttrib *attrib) { enable_polygon_offset(false); } - report_errors(); + report_gl_errors(); } //////////////////////////////////////////////////////////////////// @@ -2328,7 +2339,7 @@ bind_light(PointLight *light, int light_id) { glLightf(id, GL_LINEAR_ATTENUATION, att[1]); glLightf(id, GL_QUADRATIC_ATTENUATION, att[2]); - report_errors(); + report_gl_errors(); } //////////////////////////////////////////////////////////////////// @@ -2370,7 +2381,7 @@ bind_light(DirectionalLight *light, int light_id) { glLightf(id, GL_LINEAR_ATTENUATION, 0.0f); glLightf(id, GL_QUADRATIC_ATTENUATION, 0.0f); - report_errors(); + report_gl_errors(); } //////////////////////////////////////////////////////////////////// @@ -2411,7 +2422,7 @@ bind_light(Spotlight *light, int light_id) { glLightf(id, GL_LINEAR_ATTENUATION, att[1]); glLightf(id, GL_QUADRATIC_ATTENUATION, att[2]); - report_errors(); + report_gl_errors(); } //////////////////////////////////////////////////////////////////// @@ -2485,26 +2496,29 @@ compute_distance_to(const LPoint3f &point) const { //////////////////////////////////////////////////////////////////// // Function: report_errors_loop -// Access: Protected +// Access: Protected, Static // Description: The internal implementation of report_errors(). // Don't call this function; use report_errors() // instead. //////////////////////////////////////////////////////////////////// - -void report_errors_loop(GLenum error_code) { +void GLGraphicsStateGuardian:: +report_errors_loop(int line, const char *source_file, GLenum error_code) { #ifndef NDEBUG -#define MAXGLERRORSREPORTED 20 - int cnt=0; - while ((cnt_index); - report_errors(); + report_gl_errors(); } //////////////////////////////////////////////////////////////////// @@ -2651,7 +2664,7 @@ specify_texture(Texture *tex) { glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, get_texture_filter_type(tex->get_magfilter())); } - report_errors(); + report_gl_errors(); } #ifndef NDEBUG @@ -2833,7 +2846,7 @@ apply_texture_immediate(Texture *tex) { } #endif } - report_errors(); + report_gl_errors(); if (locally_allocated_image != (uchar *)NULL) { delete[] locally_allocated_image; @@ -2847,7 +2860,7 @@ apply_texture_immediate(Texture *tex) { xsize, ysize, pb->get_border(), external_format, type, image); - //report_errors(); + //report_gl_errors(); // want to give explict error for texture creation failure GLenum error_code = glGetError(); if(error_code != GL_NO_ERROR) { @@ -2871,8 +2884,6 @@ apply_texture_immediate(Texture *tex) { void GLGraphicsStateGuardian:: draw_texture(TextureContext *tc, const DisplayRegion *dr) { nassertv(tc != NULL && dr != NULL); - // activate(); - Texture *tex = tc->_texture; DisplayRegionStack old_dr = push_display_region(dr); @@ -2947,7 +2958,6 @@ draw_texture(TextureContext *tc, const DisplayRegion *dr) { void GLGraphicsStateGuardian:: draw_texture(TextureContext *tc, const DisplayRegion *dr, const RenderBuffer &rb) { - // activate(); set_draw_buffer(rb); draw_texture(tc, dr); } @@ -2962,8 +2972,6 @@ void GLGraphicsStateGuardian:: draw_pixel_buffer(PixelBuffer *pb, const DisplayRegion *dr) { nassertv(pb != NULL && dr != NULL); nassertv(!pb->_image.empty()); - // activate(); - DisplayRegionStack old_dr = push_display_region(dr); prepare_display_region(); @@ -3011,11 +3019,13 @@ draw_pixel_buffer(PixelBuffer *pb, const DisplayRegion *dr) { set_unpack_alignment(1); + WindowProperties props = _win->get_properties(); + glMatrixMode( GL_PROJECTION ); glPushMatrix(); glLoadIdentity(); - gluOrtho2D(0, _win->get_width(), - 0, _win->get_height()); + gluOrtho2D(0, props.get_x_size(), + 0, props.get_y_size()); #ifdef GSG_VERBOSE glgsg_cat.debug() @@ -3068,7 +3078,7 @@ draw_pixel_buffer(PixelBuffer *pb, const DisplayRegion *dr) { glPopMatrix(); pop_display_region(old_dr); - report_errors(); + report_gl_errors(); } //////////////////////////////////////////////////////////////////// @@ -3079,7 +3089,6 @@ draw_pixel_buffer(PixelBuffer *pb, const DisplayRegion *dr) { void GLGraphicsStateGuardian:: draw_pixel_buffer(PixelBuffer *pb, const DisplayRegion *dr, const RenderBuffer &rb) { - // activate(); set_draw_buffer(rb); draw_pixel_buffer(pb, dr); } @@ -3340,8 +3349,6 @@ void GLGraphicsStateGuardian:: print_gfx_visual() { GLint i; GLboolean j; - // activate(); - cout << "Graphics Visual Info (# bits of each):" << endl; cout << "RGBA: "; @@ -3588,7 +3595,7 @@ bind_clip_plane(PlaneNode *plane, int plane_id) { xformed_plane._c, xformed_plane._d); glClipPlane(id, double_plane.get_data()); - report_errors(); + report_gl_errors(); } //////////////////////////////////////////////////////////////////// @@ -3710,7 +3717,7 @@ set_blend_mode(ColorWriteAttrib::Mode color_write_mode, //////////////////////////////////////////////////////////////////// // Function: GLGraphicsStateGuardian::free_pointers -// Access: Protected +// Access: Protected, Virtual // Description: Frees some memory that was explicitly allocated // within the glgsg. //////////////////////////////////////////////////////////////////// @@ -3994,7 +4001,6 @@ dump_state(void) { if (glgsg_cat.is_debug()) { - int i; ostream &dump = glgsg_cat.debug(false); glgsg_cat.debug() << "Dumping GL State" << endl; diff --git a/panda/src/glgsg/glGraphicsStateGuardian.h b/panda/src/glgsg/glGraphicsStateGuardian.h index 9d48bd30d9..d922fb604d 100644 --- a/panda/src/glgsg/glGraphicsStateGuardian.h +++ b/panda/src/glgsg/glGraphicsStateGuardian.h @@ -19,7 +19,7 @@ #ifndef GLGRAPHICSSTATEGUARDIAN_H #define GLGRAPHICSSTATEGUARDIAN_H -//#define GSG_VERBOSE +//#define GSG_VERBOSE 1 #include "pandabase.h" @@ -73,6 +73,9 @@ public: virtual void prepare_display_region(); virtual bool prepare_lens(); + virtual bool begin_frame(); + virtual void end_frame(); + virtual void draw_point(GeomPoint *geom, GeomContext *gc); virtual void draw_line(GeomLine *geom, GeomContext *gc); virtual void draw_linestrip(GeomLinestrip *geom, GeomContext *gc); @@ -144,7 +147,11 @@ public: void issue_transformed_color(const Colorf &color) const; + INLINE static void report_errors(int line, const char *source_file); + protected: + static void report_errors_loop(int line, const char *source_file, + GLenum error_code); virtual bool slot_new_light(int light_id); virtual void enable_lighting(bool enable); virtual void set_ambient_light(const Colorf &color); @@ -162,13 +169,11 @@ protected: ColorBlendAttrib::Mode color_blend_mode, TransparencyAttrib::Mode transparency_mode); - void free_pointers(); + virtual void free_pointers(); virtual PT(SavedFrameBuffer) save_frame_buffer(const RenderBuffer &buffer, CPT(DisplayRegion) dr); virtual void restore_frame_buffer(SavedFrameBuffer *frame_buffer); - INLINE void activate(); - INLINE void call_glClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha); INLINE void call_glClearDepth(GLclampd depth); @@ -343,6 +348,13 @@ private: #define ISPOW2(X) (((X) & ((X)-1))==0) +#ifndef NDEBUG +#define report_gl_errors() \ + GLGraphicsStateGuardian::report_errors(__LINE__, __FILE__) +#else +#define report_gl_errors() +#endif + #include "glGraphicsStateGuardian.I" #endif diff --git a/panda/src/glutdisplay/Sources.pp b/panda/src/glutdisplay/Sources.pp deleted file mode 100644 index e061e86f55..0000000000 --- a/panda/src/glutdisplay/Sources.pp +++ /dev/null @@ -1,19 +0,0 @@ -#define BUILD_DIRECTORY $[HAVE_GLUT] - -#define OTHER_LIBS interrogatedb:c dconfig:c dtoolconfig:m \ - dtoolutil:c dtoolbase:c dtool:m -#define USE_PACKAGES gl glut - -#begin lib_target - #define TARGET glutdisplay - #define LOCAL_LIBS \ - glgsg display putil gobj gsgbase pnmimage mathutil - - #define SOURCES \ - config_glutdisplay.cxx config_glutdisplay.h glutGraphicsPipe.cxx \ - glutGraphicsPipe.h glutGraphicsWindow.cxx glutGraphicsWindow.h - - #define INSTALL_HEADERS \ - glutGraphicsPipe.h glutGraphicsWindow.h - -#end lib_target diff --git a/panda/src/glutdisplay/config_glutdisplay.cxx b/panda/src/glutdisplay/config_glutdisplay.cxx deleted file mode 100644 index 1d3e36c62c..0000000000 --- a/panda/src/glutdisplay/config_glutdisplay.cxx +++ /dev/null @@ -1,35 +0,0 @@ -// Filename: config_glutdisplay.cxx -// Created by: cary (07Oct99) -// -//////////////////////////////////////////////////////////////////// -// -// 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 "config_glutdisplay.h" -#include "glutGraphicsPipe.h" -#include "glutGraphicsWindow.h" - -#include - -Configure(config_glutdisplay); -NotifyCategoryDef(glutdisplay, "display"); - -ConfigureFn(config_glutdisplay) { - glutGraphicsPipe::init_type(); - GraphicsPipe::get_factory().register_factory(glutGraphicsPipe::get_class_type(), - glutGraphicsPipe::make_glutGraphicsPipe); - glutGraphicsWindow::init_type(); - GraphicsWindow::get_factory().register_factory(glutGraphicsWindow::get_class_type(), - glutGraphicsWindow::make_GlutGraphicsWindow); -} diff --git a/panda/src/glutdisplay/config_glutdisplay.h b/panda/src/glutdisplay/config_glutdisplay.h deleted file mode 100644 index 35815feefc..0000000000 --- a/panda/src/glutdisplay/config_glutdisplay.h +++ /dev/null @@ -1,28 +0,0 @@ -// Filename: config_glutdisplay.h -// Created by: cary (07Oct99) -// -//////////////////////////////////////////////////////////////////// -// -// 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 CONFIG_GLUTDISPLAY_H -#define CONFIG_GLUTDISPLAY_H - -#include -#include - -NotifyCategoryDecl(glutdisplay, EXPCL_PANDAGLUT, EXPTP_PANDAGLUT); - - -#endif /* CONFIG_GLUTDISPLAY_H */ diff --git a/panda/src/glutdisplay/glutGraphicsPipe.cxx b/panda/src/glutdisplay/glutGraphicsPipe.cxx deleted file mode 100644 index d207977671..0000000000 --- a/panda/src/glutdisplay/glutGraphicsPipe.cxx +++ /dev/null @@ -1,79 +0,0 @@ -// Filename: glutGraphicsPipe.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 "glutGraphicsPipe.h" -#include "config_glutdisplay.h" - -//////////////////////////////////////////////////////////////////// -// Static variables -//////////////////////////////////////////////////////////////////// -TypeHandle glutGraphicsPipe::_type_handle; - -glutGraphicsPipe::glutGraphicsPipe(const PipeSpecifier& spec) - : InteractiveGraphicsPipe(spec) {} - -//////////////////////////////////////////////////////////////////// -// Function: glutGraphicsPipe::get_window_type -// Access: Public, Virtual -// Description: Returns the TypeHandle of the kind of window -// preferred by this kind of pipe. -//////////////////////////////////////////////////////////////////// -TypeHandle glutGraphicsPipe:: -get_window_type() const { - return glutGraphicsWindow::get_class_type(); -} - -GraphicsPipe* -glutGraphicsPipe::make_glutGraphicsPipe(const FactoryParams ¶ms) { - GraphicsPipe::PipeSpec *pipe_param; - if (!get_param_into(pipe_param, params)) { - return new glutGraphicsPipe(PipeSpecifier()); - } else { - return new glutGraphicsPipe(pipe_param->get_specifier()); - } -} - -TypeHandle glutGraphicsPipe::get_class_type(void) { - return _type_handle; -} - -void glutGraphicsPipe::init_type(void) { - InteractiveGraphicsPipe::init_type(); - register_type(_type_handle, "glutGraphicsPipe", - InteractiveGraphicsPipe::get_class_type()); -} - -TypeHandle glutGraphicsPipe::get_type(void) const { - return get_class_type(); -} - -glutGraphicsPipe::glutGraphicsPipe(void) { - glutdisplay_cat.error() - << "glutGraphicsPipes should not be created with the default constructor" - << endl; -} - -glutGraphicsPipe::glutGraphicsPipe(const glutGraphicsPipe&) { - glutdisplay_cat.error() - << "glutGraphicsPipes should not be copied" << endl; -} - -glutGraphicsPipe& glutGraphicsPipe::operator=(const glutGraphicsPipe&) { - glutdisplay_cat.error() - << "glutGraphicsPipes should not be assigned" << endl; - return *this; -} diff --git a/panda/src/glutdisplay/glutGraphicsPipe.h b/panda/src/glutdisplay/glutGraphicsPipe.h deleted file mode 100644 index 82d7e76757..0000000000 --- a/panda/src/glutdisplay/glutGraphicsPipe.h +++ /dev/null @@ -1,62 +0,0 @@ -// Filename: glutGraphicsPipe.h -// 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 . -// -//////////////////////////////////////////////////////////////////// -#ifndef GLUTGRAPHICSPIPE_H -#define GLUTGRAPHICSPIPE_H -// -//////////////////////////////////////////////////////////////////// -// Includes -//////////////////////////////////////////////////////////////////// -#include - -#include -#include -#include "glutGraphicsWindow.h" - -//////////////////////////////////////////////////////////////////// -// Defines -//////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////// -// Class : glutGraphicsPipe -// Description : -//////////////////////////////////////////////////////////////////// -class EXPCL_PANDAGLUT glutGraphicsPipe : public InteractiveGraphicsPipe -{ -public: - glutGraphicsPipe( const PipeSpecifier& ); - - virtual TypeHandle get_window_type() const; - -public: - static GraphicsPipe* make_glutGraphicsPipe(const FactoryParams ¶ms); - - static TypeHandle get_class_type(void); - static void init_type(void); - virtual TypeHandle get_type(void) const; - virtual TypeHandle force_init_type() {init_type(); return get_class_type();} - -private: - static TypeHandle _type_handle; - -protected: - glutGraphicsPipe( void ); - glutGraphicsPipe( const glutGraphicsPipe& ); - glutGraphicsPipe& operator=(const glutGraphicsPipe&); -}; - -#endif diff --git a/panda/src/glutdisplay/glutGraphicsWindow.cxx b/panda/src/glutdisplay/glutGraphicsWindow.cxx deleted file mode 100644 index 09489400ad..0000000000 --- a/panda/src/glutdisplay/glutGraphicsWindow.cxx +++ /dev/null @@ -1,319 +0,0 @@ -// Filename: glutGraphicsWindow.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 "glutGraphicsWindow.h" -#include "glutGraphicsPipe.h" -#include "config_glutdisplay.h" - -#include -#include -#include -#include - -#ifdef WIN32_VC -#define WINDOWS_LEAN_AND_MEAN -#include -#undef WINDOWS_LEAN_AND_MEAN -#endif - -#include - -//////////////////////////////////////////////////////////////////// -// Static variables -//////////////////////////////////////////////////////////////////// -TypeHandle glutGraphicsWindow::_type_handle; -glutGraphicsWindow* glutGraphicsWindow::_global_window; - -//////////////////////////////////////////////////////////////////// -// Function: Constructor -// Access: -// Description: -//////////////////////////////////////////////////////////////////// -glutGraphicsWindow::glutGraphicsWindow( GraphicsPipe* pipe ) : - GraphicsWindow( pipe ) -{ - _global_window = this; - config(); -} - -//////////////////////////////////////////////////////////////////// -// Function: Constructor -// Access: -// Description: -//////////////////////////////////////////////////////////////////// -glutGraphicsWindow::glutGraphicsWindow( GraphicsPipe* pipe, const - GraphicsWindow::Properties& props ) : GraphicsWindow( pipe, props ) -{ - _global_window = this; - config(); -} - -//////////////////////////////////////////////////////////////////// -// Function: Destructor -// Access: -// Description: -//////////////////////////////////////////////////////////////////// -glutGraphicsWindow::~glutGraphicsWindow(void) { -} - -//////////////////////////////////////////////////////////////////// -// Function: config -// Access: -// Description: -//////////////////////////////////////////////////////////////////// -void glutGraphicsWindow::config( void ) -{ - glutInitDisplayMode( _props._mask ); - glutInitWindowPosition( _props._xorg, _props._yorg ); - glutInitWindowSize( _props._xsize, _props._ysize ); - _handle = glutCreateWindow( _props._title.c_str() ); - glutReshapeFunc( glut_handle_reshape ); - - // Mouse callbacks - glutMouseFunc( glut_handle_mouse_input ); - glutMotionFunc( glut_handle_mouse_motion ); - glutPassiveMotionFunc( glut_handle_mouse_motion ); - - // Keyboard callbacks - glutKeyboardFunc( glut_handle_ascii_keyboard_input ); - glutSpecialFunc( glut_handle_special_keyboard_input ); - - // Indicate that we have our keyboard/mouse device ready. - GraphicsWindowInputDevice device = - GraphicsWindowInputDevice::pointer_and_keyboard("keyboard/mouse"); - _input_devices.push_back(device); - - // Create a GSG to manage the graphics - make_gsg(); -} - -//////////////////////////////////////////////////////////////////// -// Function: end_frame -// Access: -// Description: Swaps the front and back buffers. -//////////////////////////////////////////////////////////////////// -void glutGraphicsWindow::end_frame( void ) -{ - { - PStatTimer timer(_swap_pcollector); - glutSwapBuffers(); - } - glutPostRedisplay(); - PStatClient::main_tick(); -} - -//////////////////////////////////////////////////////////////////// -// Function: handle_reshape -// Access: -// Description: -//////////////////////////////////////////////////////////////////// -void glutGraphicsWindow::handle_reshape( int w, int h ) -{ - _props._xsize = w; - _props._ysize = h; -} - -//////////////////////////////////////////////////////////////////// -// Function: handle_mouse_input -// Access: -// Description: -//////////////////////////////////////////////////////////////////// -void glutGraphicsWindow::handle_mouse_input( int button, int state, - int x, int y ) -{ - _input_devices[0].set_pointer_in_window(x, y); - - ButtonHandle handle; - switch (button) { - case GLUT_LEFT_BUTTON: - handle = MouseButton::one(); - break; - - case GLUT_MIDDLE_BUTTON: - handle = MouseButton::two(); - break; - - case GLUT_RIGHT_BUTTON: - handle = MouseButton::three(); - break; - } - - if (handle != ButtonHandle::none()) { - if (state == GLUT_DOWN) { - _input_devices[0].button_down(handle); - } else { - _input_devices[0].button_up(handle); - } - } -} - -//////////////////////////////////////////////////////////////////// -// Function: handle_mouse_motion -// Access: -// Description: -//////////////////////////////////////////////////////////////////// -void glutGraphicsWindow::handle_mouse_motion( int x, int y ) -{ - _input_devices[0].set_pointer_in_window(x, y); -} - -//////////////////////////////////////////////////////////////////// -// Function: handle_mouse_entry -// Access: -// Description: -//////////////////////////////////////////////////////////////////// -void glutGraphicsWindow::handle_mouse_entry( int state ) -{ - if (state == GLUT_LEFT) { - _input_devices[0].set_pointer_out_of_window(); - } -} - -//////////////////////////////////////////////////////////////////// -// Function: handle_ascii_keyboard_input -// Access: -// Description: -//////////////////////////////////////////////////////////////////// -void glutGraphicsWindow::handle_ascii_keyboard_input( uchar key, int x, int y ) -{ - _input_devices[0].set_pointer_in_window(x, y); - - ButtonHandle handle = KeyboardButton::ascii_key(key); - if (handle != ButtonHandle::none()) { - _input_devices[0].button_down(handle); - } -} - -//////////////////////////////////////////////////////////////////// -// Function: handle_special_keyboard_input -// Access: -// Description: -//////////////////////////////////////////////////////////////////// -void glutGraphicsWindow::handle_special_keyboard_input( int key, int x, int y ) -{ - _input_devices[0].set_pointer_in_window(x, y); - - ButtonHandle handle = ButtonHandle::none(); - - switch ( key ) { - case GLUT_KEY_F1: handle = KeyboardButton::f1(); break; - case GLUT_KEY_F2: handle = KeyboardButton::f2(); break; - case GLUT_KEY_F3: handle = KeyboardButton::f3(); break; - case GLUT_KEY_F4: handle = KeyboardButton::f4(); break; - case GLUT_KEY_F5: handle = KeyboardButton::f5(); break; - case GLUT_KEY_F6: handle = KeyboardButton::f6(); break; - case GLUT_KEY_F7: handle = KeyboardButton::f7(); break; - case GLUT_KEY_F8: handle = KeyboardButton::f8(); break; - case GLUT_KEY_F9: handle = KeyboardButton::f9(); break; - case GLUT_KEY_F10: handle = KeyboardButton::f10(); break; - case GLUT_KEY_F11: handle = KeyboardButton::f11(); break; - case GLUT_KEY_F12: handle = KeyboardButton::f12(); break; - case GLUT_KEY_LEFT: handle = KeyboardButton::left(); break; - case GLUT_KEY_RIGHT: handle = KeyboardButton::right(); break; - case GLUT_KEY_UP: handle = KeyboardButton::up(); break; - case GLUT_KEY_DOWN: handle = KeyboardButton::down(); break; - case GLUT_KEY_PAGE_UP: handle = KeyboardButton::page_up(); break; - case GLUT_KEY_PAGE_DOWN: handle = KeyboardButton::page_down(); break; - case GLUT_KEY_HOME: handle = KeyboardButton::home(); break; - case GLUT_KEY_END: handle = KeyboardButton::end(); break; - case GLUT_KEY_INSERT: handle = KeyboardButton::insert(); break; - } - - if (handle != ButtonHandle::none()) { - _input_devices[0].button_down(handle); - } -} - -void glutGraphicsWindow::flag_redisplay(void) { - glutPostRedisplay(); -} - -void glutGraphicsWindow::register_draw_function(GraphicsWindow::vfn f) { - GraphicsWindow::register_draw_function(f); - glutDisplayFunc(f); -} - -void glutGraphicsWindow::register_idle_function(GraphicsWindow::vfn f) { - GraphicsWindow::register_idle_function(f); - glutIdleFunc(f); -} - -/* -void glutGraphicsWindow::register_resize_function(GraphicsWindow::vfnii f) { - GraphicsWindow::register_resize_function(f); - glutReshapeFunc(f); -} -*/ - -void glutGraphicsWindow::main_loop(void) { - glutMainLoop(); -} - -void glutGraphicsWindow::make_current(void) { - if (_global_window != this) { - PStatTimer timer(_make_current_pcollector); - glutSetWindow(_handle); - _global_window = this; - } -} - -void glutGraphicsWindow::unmake_current(void) { -} - -//////////////////////////////////////////////////////////////////// -// Function: glutGraphicsWindow::get_gsg_type -// Access: Public, Virtual -// Description: Returns the TypeHandle of the kind of GSG preferred -// by this kind of window. -//////////////////////////////////////////////////////////////////// -TypeHandle glutGraphicsWindow:: -get_gsg_type() const { - return GLGraphicsStateGuardian::get_class_type(); -} - -GraphicsWindow *glutGraphicsWindow:: -make_GlutGraphicsWindow(const FactoryParams ¶ms) { - GraphicsWindow::WindowPipe *pipe_param; - if (!get_param_into(pipe_param, params)) { - glutdisplay_cat.error() - << "No pipe specified for window creation!" << endl; - return NULL; - } - - GraphicsPipe *pipe = pipe_param->get_pipe(); - - GraphicsWindow::WindowProps *props_param; - if (!get_param_into(props_param, params)) { - return new glutGraphicsWindow(pipe); - } else { - return new glutGraphicsWindow(pipe, props_param->get_properties()); - } -} - -TypeHandle glutGraphicsWindow::get_class_type(void) { - return _type_handle; -} - -void glutGraphicsWindow::init_type(void) { - GraphicsWindow::init_type(); - register_type(_type_handle, "glutGraphicsWindow", - GraphicsWindow::get_class_type()); -} - -TypeHandle glutGraphicsWindow::get_type(void) const { - return get_class_type(); -} diff --git a/panda/src/glutdisplay/glutGraphicsWindow.h b/panda/src/glutdisplay/glutGraphicsWindow.h deleted file mode 100644 index 735dbef3ed..0000000000 --- a/panda/src/glutdisplay/glutGraphicsWindow.h +++ /dev/null @@ -1,109 +0,0 @@ -// Filename: glutGraphicsWindow.h -// 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 . -// -//////////////////////////////////////////////////////////////////// -#ifndef GLUTGRAPHICSWINDOW_H -#define GLUTGRAPHICSWINDOW_H -// -//////////////////////////////////////////////////////////////////// -// Includes -//////////////////////////////////////////////////////////////////// -#include - -#include - -//////////////////////////////////////////////////////////////////// -// Defines -//////////////////////////////////////////////////////////////////// -class glutGraphicsPipe; - -//////////////////////////////////////////////////////////////////// -// Class : glutGraphicsWindow -// Description : -//////////////////////////////////////////////////////////////////// -class EXPCL_PANDAGLUT glutGraphicsWindow : public GraphicsWindow -{ -public: - glutGraphicsWindow( GraphicsPipe* pipe ); - glutGraphicsWindow( GraphicsPipe* pipe, - const GraphicsWindow::Properties& props ); - virtual ~glutGraphicsWindow( void ); - - virtual void config( void ); - virtual void end_frame( void ); - -public: - // context setting - virtual void make_current(void); - virtual void unmake_current(void); - -protected: - // Window routines - static void glut_handle_reshape( int w, int h ) { - _global_window->handle_reshape( w, h ); - } - void handle_reshape( int w, int h ); - - // Mouse routines - static void glut_handle_mouse_input( int button, int state, int x, - int y ) { - _global_window->handle_mouse_input( button, state, x, y ); - } - void handle_mouse_input( int button, int state, int x, int y ); - static void glut_handle_mouse_motion( int x, int y ) { - _global_window->handle_mouse_motion( x, y ); - } - void handle_mouse_motion( int x, int y ); - static void glut_handle_mouse_entry( int state ) { - _global_window->handle_mouse_entry( state ); - } - void handle_mouse_entry( int state ); - - // Keyboard routines - static void glut_handle_ascii_keyboard_input( uchar key, int x, int y ) { - _global_window->handle_ascii_keyboard_input( key, x, y ); - } - void handle_ascii_keyboard_input( uchar key, int, int ); - static void glut_handle_special_keyboard_input( int key, int x, int y ) { - _global_window->handle_special_keyboard_input( key, x, y ); - } - void handle_special_keyboard_input( int key, int, int ); - -protected: - static glutGraphicsWindow* _global_window; - int _handle; - -public: - virtual void flag_redisplay(void); - virtual void register_draw_function(GraphicsWindow::vfn); - virtual void register_idle_function(GraphicsWindow::vfn); - // virtual void register_resize_function(GraphicsWindow::vfnii); - virtual void main_loop(void); - - virtual TypeHandle get_gsg_type() const; - static GraphicsWindow* make_GlutGraphicsWindow(const FactoryParams ¶ms); - -public: - static TypeHandle get_class_type(void); - static void init_type(void); - virtual TypeHandle get_type(void) const; - virtual TypeHandle force_init_type() {init_type(); return get_class_type();} - -private: - static TypeHandle _type_handle; -}; - -#endif diff --git a/panda/src/glutdisplay/test_glut.cxx b/panda/src/glutdisplay/test_glut.cxx deleted file mode 100644 index e6203f00e4..0000000000 --- a/panda/src/glutdisplay/test_glut.cxx +++ /dev/null @@ -1,79 +0,0 @@ -// Filename: test_glut.cxx -// Created by: mike (02Feb00) -// -//////////////////////////////////////////////////////////////////// -// -// 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 "glutGraphicsPipe.h" -//#include "glutGraphicsWindow.h" -#include -#include -#include - -#include - -PT(GraphicsPipe) main_pipe; -PT(GraphicsWindow) main_win; -PT_NamedNode render; - -void render_frame(GraphicsPipe *pipe) { - GraphicsPipe::wins_iterator wi; - for (wi = pipe->get_win_begin(); - wi != pipe->get_win_end(); - ++wi) { - (*wi)->get_gsg()->render_frame(render); - } -} - -void display_func(void) { - render_frame(main_pipe); -} - -int main() { - - GraphicsPipe::resolve_modules(); - - cout << "Known pipe types:" << endl; - GraphicsPipe::PipeFactory::FactoryTypesIter pti; - for (pti = GraphicsPipe::_factory.get_types_begin(); - pti != GraphicsPipe::_factory.get_types_end(); ++pti) { - cout << " " << (*pti) << endl; - } - cout << "after Known pipe types" << endl; - - GraphicsPipe::PipeFactory& factory = GraphicsPipe::_factory; - GraphicsPipe::PipePrioritiesIter pribegin = - GraphicsPipe::get_priorities_begin(); - GraphicsPipe::PipePrioritiesIter priend = GraphicsPipe::get_priorities_end(); - - GraphicsPipe::PipeParams ps1; - if (pribegin == priend) - main_pipe = factory.instance(InteractiveGraphicsPipe::get_class_type(), - ps1.begin(), ps1.end()); - else - main_pipe = factory.instance(InteractiveGraphicsPipe::get_class_type(), - ps1.begin(), ps1.end(), pribegin, priend); - nassertr(main_pipe != (GraphicsPipe*)0L, 0); - cout << "Opened a '" << main_pipe->get_type().get_name() - << "' interactive graphics pipe." << endl; - -#if 0 - main_win = new glutGraphicsWindow(main_pipe); - main_win->register_draw_function(display_func); - main_win->main_loop(); -#endif - - return 0; -} diff --git a/panda/src/glutdisplay/test_glut_win.cxx b/panda/src/glutdisplay/test_glut_win.cxx deleted file mode 100644 index d1e3eaebce..0000000000 --- a/panda/src/glutdisplay/test_glut_win.cxx +++ /dev/null @@ -1,38 +0,0 @@ -// Filename: test_glut_win.cxx -// Created by: mike (02Feb00) -// -//////////////////////////////////////////////////////////////////// -// -// 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 -#include - -#ifdef WIN32_VC -#include -#endif -#include - -void display_func(void) { - cerr << "in display func" << endl; - glutPostRedisplay(); -} - -int main() { - glutInitWindowSize(256, 256); - glutCreateWindow("test glut window"); - glutDisplayFunc(display_func); - glutMainLoop(); - return 0; -} diff --git a/panda/src/glxdisplay/Sources.pp b/panda/src/glxdisplay/Sources.pp index adca876c9e..51a3580cb4 100644 --- a/panda/src/glxdisplay/Sources.pp +++ b/panda/src/glxdisplay/Sources.pp @@ -11,13 +11,13 @@ #define SOURCES \ config_glxdisplay.cxx config_glxdisplay.h \ - glxDisplay.I glxDisplay.h glxDisplay.cxx glxGraphicsPipe.cxx \ + glxGraphicsPipe.I glxGraphicsPipe.cxx \ glxGraphicsPipe.h glxGraphicsWindow.I glxGraphicsWindow.cxx \ glxGraphicsWindow.h #define INSTALL_HEADERS \ - glxDisplay.I glxDisplay.h \ - glxGraphicsPipe.h glxGraphicsWindow.I glxGraphicsWindow.h + glxGraphicsPipe.I glxGraphicsPipe.h \ + glxGraphicsWindow.I glxGraphicsWindow.h #define IGATESCAN glxGraphicsPipe.h diff --git a/panda/src/glxdisplay/config_glxdisplay.cxx b/panda/src/glxdisplay/config_glxdisplay.cxx index c12dfad93f..fa898fa4f6 100644 --- a/panda/src/glxdisplay/config_glxdisplay.cxx +++ b/panda/src/glxdisplay/config_glxdisplay.cxx @@ -19,22 +19,40 @@ #include "config_glxdisplay.h" #include "glxGraphicsPipe.h" #include "glxGraphicsWindow.h" -#include "glxDisplay.h" - -#include +#include "graphicsPipeSelection.h" +#include "dconfig.h" Configure(config_glxdisplay); NotifyCategoryDef(glxdisplay, "display"); ConfigureFn(config_glxdisplay) { + init_libglxdisplay(); +} + +//////////////////////////////////////////////////////////////////// +// Function: init_libglxdisplay +// Description: Initializes the library. This must be called at +// least once before any of the functions or classes in +// this library can be used. Normally it will be +// called by the static initializers and need not be +// called explicitly, but special cases exist. +//////////////////////////////////////////////////////////////////// +void +init_libglxdisplay() { + static bool initialized = false; + if (initialized) { + return; + } + initialized = true; + glxGraphicsPipe::init_type(); - GraphicsPipe::get_factory().register_factory(glxGraphicsPipe::get_class_type(), - glxGraphicsPipe::make_glxGraphicsPipe); glxGraphicsWindow::init_type(); - GraphicsWindow::get_factory().register_factory(glxGraphicsWindow::get_class_type(), - glxGraphicsWindow::make_GlxGraphicsWindow); - glxDisplay::init_type(); + + GraphicsPipeSelection *selection = GraphicsPipeSelection::get_global_ptr(); + selection->add_pipe_type(glxGraphicsPipe::get_class_type(), + glxGraphicsPipe::pipe_constructor); } bool gl_show_fps_meter = config_glxdisplay.GetBool("show-fps-meter", false); float gl_fps_meter_update_interval = max((float)0.5,config_glxdisplay.GetFloat("fps-meter-update-interval", 1.7)); +const string display_cfg = config_glxdisplay.GetString("display", ""); diff --git a/panda/src/glxdisplay/config_glxdisplay.h b/panda/src/glxdisplay/config_glxdisplay.h index bf55a16cc5..5d5f67771b 100644 --- a/panda/src/glxdisplay/config_glxdisplay.h +++ b/panda/src/glxdisplay/config_glxdisplay.h @@ -24,7 +24,10 @@ NotifyCategoryDecl(glxdisplay, EXPCL_PANDAGL, EXPTP_PANDAGL); +extern EXPCL_PANDAGL void init_libglxdisplay(); + extern bool gl_show_fps_meter; extern float gl_fps_meter_update_interval; +extern const string display_cfg; #endif /* __CONFIG_GLXDISPLAY_H__ */ diff --git a/panda/src/glxdisplay/glxDisplay.cxx b/panda/src/glxdisplay/glxDisplay.cxx deleted file mode 100644 index c50bb63c34..0000000000 --- a/panda/src/glxdisplay/glxDisplay.cxx +++ /dev/null @@ -1,75 +0,0 @@ -// Filename: glxDisplay.cxx -// Created by: drose (30Oct00) -// -//////////////////////////////////////////////////////////////////// -// -// 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 "glxDisplay.h" -#include "glxGraphicsWindow.h" -#include "config_glxdisplay.h" - -#include - -#include - -TypeHandle glxDisplay::_type_handle; - -//////////////////////////////////////////////////////////////////// -// Function: glxDisplay::Constructor -// Access: Public -// Description: -//////////////////////////////////////////////////////////////////// -glxDisplay:: -glxDisplay(GraphicsPipe *pipe, const string &x_specifier) { - _pipe = pipe; - _display = XOpenDisplay(x_specifier.c_str()); - if (!_display) { - glxdisplay_cat.fatal() - << "glxGraphicsPipe::construct(): Could not open display: " - << x_specifier << endl; - exit(1); - } - int errorBase, eventBase; - if (!glXQueryExtension(_display, &errorBase, &eventBase)) { - glxdisplay_cat.fatal() - << "glxGraphicsPipe::construct(): OpenGL GLX extension not " - << "supported by display: " << x_specifier << endl; - exit(1); - } - _screen = DefaultScreen(_display); - _root = RootWindow(_display, _screen); - _width = DisplayWidth(_display, _screen); - _height = DisplayHeight(_display, _screen); -} - - -//////////////////////////////////////////////////////////////////// -// Function: glxDisplay::find_window -// Access: Public -// Description: Find the window that has the xwindow "win" in the -// window list for the pipe (if it exists) -//////////////////////////////////////////////////////////////////// -glxGraphicsWindow *glxDisplay:: -find_window(Window win) const { - int num_windows = _pipe->get_num_windows(); - for (int w = 0; w < num_windows; w++) { - glxGraphicsWindow *window; - DCAST_INTO_R(window, _pipe->get_window(w), NULL); - if (window->get_xwindow() == win) { - return window; - } - } - return NULL; -} diff --git a/panda/src/glxdisplay/glxDisplay.h b/panda/src/glxdisplay/glxDisplay.h deleted file mode 100644 index 08cad47abe..0000000000 --- a/panda/src/glxdisplay/glxDisplay.h +++ /dev/null @@ -1,84 +0,0 @@ -// Filename: glxDisplay.h -// Created by: drose (30Oct00) -// -//////////////////////////////////////////////////////////////////// -// -// 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 GLXDISPLAY_H -#define GLXDISPLAY_H - -#include "pandabase.h" -#include "typedObject.h" - -#include - -class GraphicsPipe; -class glxGraphicsWindow; - -#ifdef CPPPARSER -// A simple hack so interrogate can parse this file. -typedef int Display; -typedef int Window; -#endif - -//////////////////////////////////////////////////////////////////// -// Class : glxDisplay -// Description : This class is a base class of glxGraphicsPipe, and -// also of SgiGlxGraphicsPipe and potentially other -// glx-based pipes. It simply records some information -// about the display that's useful to the -// glxGraphicsWindow. -//////////////////////////////////////////////////////////////////// -class glxDisplay : public TypedObject { -public: - glxDisplay(GraphicsPipe *pipe, const string &x_specifier); - - INLINE Display *get_display() const; - INLINE int get_screen() const; - INLINE Window get_root() const; - INLINE int get_display_width() const; - INLINE int get_display_height() const; - - glxGraphicsWindow *find_window(Window win) const; - -private: - GraphicsPipe *_pipe; - Display *_display; - int _screen; - Window _root; - int _width; - int _height; - -public: - static TypeHandle get_class_type() { - return _type_handle; - } - static void init_type() { - TypedObject::init_type(); - register_type(_type_handle, "glxDisplay", - TypedObject::get_class_type()); - } - virtual TypeHandle get_type() const { - return get_class_type(); - } - virtual TypeHandle force_init_type() {init_type(); return get_class_type();} - -private: - static TypeHandle _type_handle; -}; - -#include "glxDisplay.I" - -#endif diff --git a/panda/src/glxdisplay/glxDisplay.I b/panda/src/glxdisplay/glxGraphicsPipe.I similarity index 81% rename from panda/src/glxdisplay/glxDisplay.I rename to panda/src/glxdisplay/glxGraphicsPipe.I index f934f85ba5..4600c23f4a 100644 --- a/panda/src/glxdisplay/glxDisplay.I +++ b/panda/src/glxdisplay/glxGraphicsPipe.I @@ -1,4 +1,4 @@ -// Filename: glxDisplay.I +// Filename: glxGraphicsPipe.I // Created by: drose (30Oct00) // //////////////////////////////////////////////////////////////////// @@ -18,53 +18,53 @@ //////////////////////////////////////////////////////////////////// -// Function: glxDisplay::get_display +// Function: glxGraphicsPipe::get_display // Access: Public // Description: Returns a pointer to the X display associated with // the pipe: the display on which to create the windows. //////////////////////////////////////////////////////////////////// -INLINE Display *glxDisplay:: +INLINE Display *glxGraphicsPipe:: get_display() const { return _display; } //////////////////////////////////////////////////////////////////// -// Function: glxDisplay::get_screen +// Function: glxGraphicsPipe::get_screen // Access: Public // Description: Returns the X screen number associated with the pipe. //////////////////////////////////////////////////////////////////// -INLINE int glxDisplay:: +INLINE int glxGraphicsPipe:: get_screen() const { return _screen; } //////////////////////////////////////////////////////////////////// -// Function: glxDisplay::get_root +// Function: glxGraphicsPipe::get_root // Access: Public // Description: Returns the handle to the root window on the pipe's // display. //////////////////////////////////////////////////////////////////// -INLINE Window glxDisplay:: +INLINE Window glxGraphicsPipe:: get_root() const { return _root; } //////////////////////////////////////////////////////////////////// -// Function: glxDisplay::get_display_width +// Function: glxGraphicsPipe::get_display_width // Access: Public // Description: Returns the width of the entire display. //////////////////////////////////////////////////////////////////// -INLINE int glxDisplay:: +INLINE int glxGraphicsPipe:: get_display_width() const { - return _width; + return _display_width; } //////////////////////////////////////////////////////////////////// -// Function: glxDisplay::get_display_height +// Function: glxGraphicsPipe::get_display_height // Access: Public // Description: Returns the height of the entire display. //////////////////////////////////////////////////////////////////// -INLINE int glxDisplay:: +INLINE int glxGraphicsPipe:: get_display_height() const { - return _height; + return _display_height; } diff --git a/panda/src/glxdisplay/glxGraphicsPipe.cxx b/panda/src/glxdisplay/glxGraphicsPipe.cxx index c3139ad536..888dab11f4 100644 --- a/panda/src/glxdisplay/glxGraphicsPipe.cxx +++ b/panda/src/glxdisplay/glxGraphicsPipe.cxx @@ -19,64 +19,89 @@ #include "glxGraphicsPipe.h" #include "glxGraphicsWindow.h" #include "config_glxdisplay.h" +#include "mutexHolder.h" #include -//////////////////////////////////////////////////////////////////// -// Static variables -//////////////////////////////////////////////////////////////////// TypeHandle glxGraphicsPipe::_type_handle; -glxGraphicsPipe::glxGraphicsPipe(const PipeSpecifier& spec) - : InteractiveGraphicsPipe(spec), - glxDisplay(this, spec.get_X_specifier()) -{ +//////////////////////////////////////////////////////////////////// +// Function: glxGraphicsPipe::Constructor +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +glxGraphicsPipe:: +glxGraphicsPipe(const string &display) { + string display_spec = display; + if (display_spec.empty()) { + display_spec = display_cfg; + } + if (display_spec.empty()) { + display_spec = ExecutionEnvironment::get_environment_variable("DISPLAY"); + } + + _is_valid = false; + _display = NULL; + _screen = 0; + _root = (Window)NULL; + _display_width = 0; + _display_height = 0; + + _display = XOpenDisplay(display_spec.c_str()); + if (!_display) { + glxdisplay_cat.error() + << "Could not open display \"" << display_spec << "\".\n"; + return; + } + + int errorBase, eventBase; + if (!glXQueryExtension(_display, &errorBase, &eventBase)) { + glxdisplay_cat.error() + << "OpenGL GLX extension not supported on display \"" << display_spec + << "\".\n"; + return; + } + + _screen = DefaultScreen(_display); + _root = RootWindow(_display, _screen); + _display_width = DisplayWidth(_display, _screen); + _display_height = DisplayHeight(_display, _screen); + _is_valid = true; } //////////////////////////////////////////////////////////////////// -// Function: glxGraphicsPipe::get_window_type +// Function: glxGraphicsPipe::Destructor // Access: Public, Virtual -// Description: Returns the TypeHandle of the kind of window -// preferred by this kind of pipe. +// Description: //////////////////////////////////////////////////////////////////// -TypeHandle glxGraphicsPipe:: -get_window_type() const { - return glxGraphicsWindow::get_class_type(); -} - -//////////////////////////////////////////////////////////////////// -// Function: glxGraphicsPipe::get_glx_display -// Access: Public, Virtual -// Description: Returns the glxDisplay information associated with -// this pipe. -//////////////////////////////////////////////////////////////////// -glxDisplay *glxGraphicsPipe:: -get_glx_display() { - return this; -} - -GraphicsPipe *glxGraphicsPipe:: -make_glxGraphicsPipe(const FactoryParams ¶ms) { - GraphicsPipe::PipeSpec *pipe_param; - if (!get_param_into(pipe_param, params)) { - return new glxGraphicsPipe(PipeSpecifier()); - } else { - return new glxGraphicsPipe(pipe_param->get_specifier()); +glxGraphicsPipe:: +~glxGraphicsPipe() { + if (_display) { + XCloseDisplay(_display); } } -TypeHandle glxGraphicsPipe::get_class_type(void) { - return _type_handle; +//////////////////////////////////////////////////////////////////// +// Function: glxGraphicsPipe::pipe_constructor +// Access: Public, Static +// Description: This function is passed to the GraphicsPipeSelection +// object to allow the user to make a default +// glxGraphicsPipe. +//////////////////////////////////////////////////////////////////// +PT(GraphicsPipe) glxGraphicsPipe:: +pipe_constructor() { + return new glxGraphicsPipe; } -void glxGraphicsPipe::init_type(void) { - InteractiveGraphicsPipe::init_type(); - glxDisplay::init_type(); - register_type(_type_handle, "glxGraphicsPipe", - InteractiveGraphicsPipe::get_class_type(), - glxDisplay::get_class_type()); -} - -TypeHandle glxGraphicsPipe::get_type(void) const { - return get_class_type(); +//////////////////////////////////////////////////////////////////// +// Function: glxGraphicsPipe::make_window +// Access: Protected, Virtual +// Description: Creates a new window on the pipe, if possible. +//////////////////////////////////////////////////////////////////// +PT(GraphicsWindow) glxGraphicsPipe:: +make_window() { + if (!_is_valid) { + return NULL; + } + return new glxGraphicsWindow(this); } diff --git a/panda/src/glxdisplay/glxGraphicsPipe.h b/panda/src/glxdisplay/glxGraphicsPipe.h index 6bef98c199..f0cb804cce 100644 --- a/panda/src/glxdisplay/glxGraphicsPipe.h +++ b/panda/src/glxdisplay/glxGraphicsPipe.h @@ -20,32 +20,67 @@ #define GLXGRAPHICSPIPE_H #include "pandabase.h" -#include "glxDisplay.h" -#include "interactiveGraphicsPipe.h" +#include "graphicsPipe.h" + +#include + +class glxGraphicsWindow; + +#ifdef CPPPARSER +// A simple hack so interrogate can parse this file. +typedef int Display; +typedef int Window; +#endif //////////////////////////////////////////////////////////////////// // Class : glxGraphicsPipe -// Description : +// Description : This graphics pipe represents the interface for +// creating OpenGL graphics windows on an X-based +// (e.g. Unix) client. //////////////////////////////////////////////////////////////////// -class glxGraphicsPipe : public InteractiveGraphicsPipe, public glxDisplay { -PUBLISHED: - glxGraphicsPipe( const PipeSpecifier& ); +class glxGraphicsPipe : public GraphicsPipe { +public: + glxGraphicsPipe(const string &display = string()); + virtual ~glxGraphicsPipe(); - virtual TypeHandle get_window_type() const; + static PT(GraphicsPipe) pipe_constructor(); + + INLINE Display *get_display() const; + INLINE int get_screen() const; + INLINE Window get_root() const; + INLINE int get_display_width() const; + INLINE int get_display_height() const; + +protected: + virtual PT(GraphicsWindow) make_window(); + +private: + bool _is_valid; + Display *_display; + int _screen; + Window _root; + int _display_width; + int _display_height; -public: - virtual glxDisplay *get_glx_display(); public: - static GraphicsPipe *make_glxGraphicsPipe(const FactoryParams ¶ms); - - static TypeHandle get_class_type(void); - static void init_type(void); - virtual TypeHandle get_type(void) const; + static TypeHandle get_class_type() { + return _type_handle; + } + static void init_type() { + GraphicsPipe::init_type(); + register_type(_type_handle, "glxGraphicsPipe", + GraphicsPipe::get_class_type()); + } + virtual TypeHandle get_type() const { + return get_class_type(); + } virtual TypeHandle force_init_type() {init_type(); return get_class_type();} - + private: static TypeHandle _type_handle; }; +#include "glxGraphicsPipe.I" + #endif diff --git a/panda/src/glxdisplay/glxGraphicsWindow.I b/panda/src/glxdisplay/glxGraphicsWindow.I index 045455917f..b648f30b21 100644 --- a/panda/src/glxdisplay/glxGraphicsWindow.I +++ b/panda/src/glxdisplay/glxGraphicsWindow.I @@ -16,28 +16,3 @@ // //////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////// -// Function: add_event_mask -// Access: Protected -// Description: Ensures we only update window events once -//////////////////////////////////////////////////////////////////// -INLINE void glxGraphicsWindow::add_event_mask(long event_mask) -{ - if ((_event_mask & event_mask) != event_mask) { - _event_mask |= event_mask; - _change_mask |= GLXWIN_EVENT; - } -} - -//////////////////////////////////////////////////////////////////// -// Function: remove_event_mask -// Access: Protected -// Description: Ensures we only update window events once -//////////////////////////////////////////////////////////////////// -INLINE void glxGraphicsWindow::remove_event_mask(long event_mask) -{ - if (_event_mask & event_mask) { - _event_mask &= ~event_mask; - _change_mask |= GLXWIN_EVENT; - } -} diff --git a/panda/src/glxdisplay/glxGraphicsWindow.cxx b/panda/src/glxdisplay/glxGraphicsWindow.cxx index 244bb635d8..6900c80e40 100644 --- a/panda/src/glxdisplay/glxGraphicsWindow.cxx +++ b/panda/src/glxdisplay/glxGraphicsWindow.cxx @@ -15,129 +15,446 @@ // panda3d@yahoogroups.com . // //////////////////////////////////////////////////////////////////// + #include "glxGraphicsWindow.h" -#include "glxDisplay.h" #include "config_glxdisplay.h" +#include "glxGraphicsPipe.h" #include "graphicsPipe.h" #include "keyboardButton.h" #include "mouseButton.h" #include "glGraphicsStateGuardian.h" -#include "pStatTimer.h" #include "clockObject.h" #include #include #include #include -#include // for sprintf() -//////////////////////////////////////////////////////////////////// -// Static variables -//////////////////////////////////////////////////////////////////// TypeHandle glxGraphicsWindow::_type_handle; -const char* glxGraphicsWindow::_glx_extensions = NULL; - -#define MOUSE_ENTERED 0 -#define MOUSE_EXITED 1 - -#define FONT_BITMAP_OGLDISPLAYLISTNUM 1000 // some arbitrary # - //////////////////////////////////////////////////////////////////// -// Function: Constructor -// Access: +// Function: glxGraphicsWindow::Constructor +// Access: Public // Description: //////////////////////////////////////////////////////////////////// -glxGraphicsWindow::glxGraphicsWindow( GraphicsPipe* pipe ) : - GraphicsWindow( pipe ) +glxGraphicsWindow:: +glxGraphicsWindow(GraphicsPipe *pipe) : + GraphicsWindow(pipe) { - config(); + glxGraphicsPipe *glx_pipe; + DCAST_INTO_V(glx_pipe, _pipe); + _display = glx_pipe->get_display(); + _screen = glx_pipe->get_screen(); + _xwindow = (Window)0; + _context = (GLXContext)0; + _visual = (XVisualInfo *)NULL; + + GraphicsWindowInputDevice device = + GraphicsWindowInputDevice::pointer_and_keyboard("keyboard/mouse"); + _input_devices.push_back(device); } //////////////////////////////////////////////////////////////////// -// Function: Constructor -// Access: +// Function: glxGraphicsWindow::Destructor +// Access: Public, Virtual // Description: //////////////////////////////////////////////////////////////////// -glxGraphicsWindow::glxGraphicsWindow( GraphicsPipe* pipe, const - GraphicsWindow::Properties& props ) : GraphicsWindow( pipe, props ) -{ - config(); +glxGraphicsWindow:: +~glxGraphicsWindow() { } //////////////////////////////////////////////////////////////////// -// Function: Destructor -// Access: -// Description: +// Function: glxGraphicsWindow::make_gsg +// Access: Public, Virtual +// Description: Creates a new GSG for the window and stores it in the +// _gsg pointer. This should only be called from within +// the draw thread. //////////////////////////////////////////////////////////////////// -glxGraphicsWindow::~glxGraphicsWindow(void) -{ - // The GL context is already gone. Don't try to destroy it again; - // that will cause a seg fault on exit. - // unmake_current(); - // glXDestroyContext(_display, _context); +void glxGraphicsWindow:: +make_gsg() { + nassertv(_gsg == (GraphicsStateGuardian *)NULL); - if (gl_show_fps_meter) - glDeleteLists(FONT_BITMAP_OGLDISPLAYLISTNUM, 128); + // First, we need to create the rendering context. + _context = glXCreateContext(_display, _visual, None, GL_TRUE); + if (!_context) { + glxdisplay_cat.error() + << "Could not create GLX context.\n"; + return; + } - XDestroyWindow(_display, _xwindow); - if (_colormap) - XFreeColormap(_display, _colormap); - XFree(_visual); + // And make sure the new context is current. + glXMakeCurrent(_display, _xwindow, _context); + + // Now we can make a GSG. + _gsg = new GLGraphicsStateGuardian(this); } //////////////////////////////////////////////////////////////////// -// Function: glx_supports -// Access: -// Description: +// Function: glxGraphicsWindow::release_gsg +// Access: Public, Virtual +// Description: Releases the current GSG pointer, if it is currently +// held, and resets the GSG to NULL. This should only +// be called from within the draw thread. //////////////////////////////////////////////////////////////////// -bool glxGraphicsWindow::glx_supports(const char* extension) -{ -#if defined(GLX_VERSION_1_1) - const char* start; - char* where, *terminator; - int major, minor; +void glxGraphicsWindow:: +release_gsg() { + if (_gsg != (GraphicsStateGuardian *)NULL) { + GraphicsWindow::release_gsg(); + glXDestroyContext(_display, _context); + _context = (GLXContext)0; + } +} - glxDisplay *glx = _pipe->get_glx_display(); - nassertr(glx != (glxDisplay *)NULL, false); +//////////////////////////////////////////////////////////////////// +// Function: glxGraphicsWindow::make_current +// Access: Public, Virtual +// Description: This function will be called within the draw thread +// during begin_frame() to ensure the graphics context +// is ready for drawing. +//////////////////////////////////////////////////////////////////// +void glxGraphicsWindow:: +make_current() { + nassertv(_gsg != (GraphicsStateGuardian *)NULL); + glXMakeCurrent(_display, _xwindow, _context); +} - glXQueryVersion(_display, &major, &minor); - if ((major == 1 && minor >= 1) || (major > 1)) { - if (!_glx_extensions) { - _glx_extensions = - glXQueryExtensionsString(_display, glx->get_screen()); - } - start = _glx_extensions; - for (;;) { - where = strstr(start, extension); - if (!where) - return false; - terminator = where + strlen(extension); - if (where == start || *(where - 1) == ' ') { - if (*terminator == ' ' || *terminator == '\0') { - return true; +//////////////////////////////////////////////////////////////////// +// Function: glxGraphicsWindow::begin_flip +// Access: Public, Virtual +// Description: This function will be called within the draw thread +// after end_frame() has been called on all windows, to +// initiate the exchange of the front and back buffers. +// +// This should instruct the window to prepare for the +// flip at the next video sync, but it should not wait. +// +// We have the two separate functions, begin_flip() and +// end_flip(), to make it easier to flip all of the +// windows at the same time. +//////////////////////////////////////////////////////////////////// +void glxGraphicsWindow:: +begin_flip() { + if (_gsg != (GraphicsStateGuardian *)NULL) { + glXMakeCurrent(_display, _xwindow, _context); + glXSwapBuffers(_display, _xwindow); + } +} + +//////////////////////////////////////////////////////////////////// +// Function: glxGraphicsWindow::process_events +// Access: Public, Virtual +// Description: Do whatever processing is necessary to ensure that +// the window responds to user events. Also, honor any +// requests recently made via request_properties() +// +// This function is called only within the window +// thread. +//////////////////////////////////////////////////////////////////// +void glxGraphicsWindow:: +process_events() { + GraphicsWindow::process_events(); + + XEvent event; + while (XCheckWindowEvent(_display, _xwindow, _event_mask, &event)) { + WindowProperties properties; + ButtonHandle button; + + switch (event.type) { + case ReparentNotify: + break; + + case ConfigureNotify: + properties.set_size(event.xconfigure.width, event.xconfigure.height); + system_changed_properties(properties); + break; + + case ButtonPress: + // This refers to the mouse buttons. + button = MouseButton::button(event.xbutton.button - 1); + _input_devices[0].set_pointer_in_window(event.xbutton.x, event.xbutton.y); + _input_devices[0].button_down(button); + break; + + case ButtonRelease: + button = MouseButton::button(event.xbutton.button - 1); + _input_devices[0].set_pointer_in_window(event.xbutton.x, event.xbutton.y); + _input_devices[0].button_up(button); + break; + + case MotionNotify: + _input_devices[0].set_pointer_in_window(event.xmotion.x, event.xmotion.y); + break; + + case KeyPress: + { + _input_devices[0].set_pointer_in_window(event.xkey.x, event.xkey.y); + int index = ((event.xkey.state & ShiftMask) != 0) ? 1 : 0; + + // First, get the keystroke, as modified by the shift key. + KeySym key = XLookupKeysym(&event.xkey, index); + if (key > 0 && key < 128) { + // If it's an ASCII key, press it. + _input_devices[0].keystroke(key); + } + + // Now get the raw unshifted button. + ButtonHandle button = get_button(&event.xkey); + if (button != ButtonHandle::none()) { + _input_devices[0].button_down(button); } } - start = terminator; + break; + + case KeyRelease: + button = get_button(&event.xkey); + if (button != ButtonHandle::none()) { + _input_devices[0].button_up(button); + } + break; + + case EnterNotify: + _input_devices[0].set_pointer_in_window(event.xcrossing.x, event.xcrossing.y); + break; + + case LeaveNotify: + _input_devices[0].set_pointer_out_of_window(); + break; + + case FocusIn: + properties.set_foreground(true); + system_changed_properties(properties); + break; + + case FocusOut: + properties.set_foreground(false); + system_changed_properties(properties); + break; + + case UnmapNotify: + properties.set_minimized(true); + system_changed_properties(properties); + break; + + case MapNotify: + properties.set_minimized(false); + system_changed_properties(properties); + break; + + case DestroyNotify: + cerr << "destroy\n"; + break; + + default: + cerr << "unhandled X event type " << event.type << "\n"; } } - return false; -#else - return false; -#endif } //////////////////////////////////////////////////////////////////// -// Function: try_for_visual -// Description: This is a static function that attempts to get the -// requested visual, if it is available. It's just a -// wrapper around glXChooseVisual(). It returns the -// visual information if possible, or NULL if it is not. +// Function: glxGraphicsWindow::set_properties_now +// Access: Public, Virtual +// Description: Applies the requested set of properties to the +// window, if possible, for instance to request a change +// in size or minimization status. +// +// The window properties are applied immediately, rather +// than waiting until the next frame. This implies that +// this method may *only* be called from within the +// window thread. +// +// The return value is true if the properties are set, +// false if they are ignored. This is mainly useful for +// derived classes to implement extensions to this +// function. //////////////////////////////////////////////////////////////////// -static XVisualInfo * -try_for_visual(glxDisplay *glx, int mask, - int want_depth_bits = 1, int want_color_bits = 1) { +void glxGraphicsWindow:: +set_properties_now(WindowProperties &properties) { + GraphicsWindow::set_properties_now(properties); + if (!properties.is_any_specified()) { + return; + } + + // The window is already open; we are limited to what we can change + // on the fly. This appears to be just the window title. + if (properties.has_title()) { + WindowProperties wm_properties; + wm_properties.set_title(properties.get_title()); + _properties.set_title(properties.get_title()); + set_wm_properties(wm_properties); + properties.clear_title(); + } +} + +//////////////////////////////////////////////////////////////////// +// Function: glxGraphicsWindow::close_window +// Access: Protected, Virtual +// Description: Closes the window right now. Called from the window +// thread. +//////////////////////////////////////////////////////////////////// +void glxGraphicsWindow:: +close_window() { + if (_xwindow != (Window)0) { + XDestroyWindow(_display, _xwindow); + _xwindow = (Window)0; + + // This may be necessary if we just closed the last X window in an + // application, so the server hears the close request. + XFlush(_display); + } +} + +//////////////////////////////////////////////////////////////////// +// Function: glxGraphicsWindow::open_window +// Access: Protected, Virtual +// Description: Opens the window right now. Called from the window +// thread. Returns true if the window is successfully +// opened, or false if there was a problem. +//////////////////////////////////////////////////////////////////// +bool glxGraphicsWindow:: +open_window() { + if (!_properties.has_origin()) { + _properties.set_origin(0, 0); + } + if (!_properties.has_size()) { + _properties.set_size(100, 100); + } + + glxGraphicsPipe *glx_pipe; + DCAST_INTO_R(glx_pipe, _pipe, false); + Window root_window = glx_pipe->get_root(); + + if (!choose_visual()) { + return false; + } + setup_colormap(); + + _event_mask = + ButtonPressMask | ButtonReleaseMask | + KeyPressMask | KeyReleaseMask | + EnterWindowMask | LeaveWindowMask | + PointerMotionMask | + FocusChangeMask | + StructureNotifyMask; + + // Initialize window attributes + XSetWindowAttributes wa; + wa.background_pixel = XBlackPixel(_display, _screen); + wa.border_pixel = 0; + wa.colormap = _colormap; + wa.event_mask = _event_mask; + wa.do_not_propagate_mask = 0; + + unsigned long attrib_mask = + CWBackPixel | CWBorderPixel | CWColormap | CWEventMask; + + _xwindow = XCreateWindow + (_display, root_window, + _properties.get_x_origin(), _properties.get_y_origin(), + _properties.get_x_size(), _properties.get_y_size(), + 0, + _visual->depth, InputOutput, _visual->visual, + attrib_mask, &wa); + + if (_xwindow == (Window)0) { + glxdisplay_cat.error() + << "failed to create X window.\n"; + return false; + } + set_wm_properties(_properties); + + XMapWindow(_display, _xwindow); + + return true; +} + +//////////////////////////////////////////////////////////////////// +// Function: glxGraphicsWindow::set_wm_properties +// Access: Private +// Description: Asks the window manager to set the appropriate +// properties. In X, these properties cannot be +// specified directly by the application; they must be +// requested via the window manager, which may or may +// not choose to honor the request. +//////////////////////////////////////////////////////////////////// +void glxGraphicsWindow:: +set_wm_properties(const WindowProperties &properties) { + // Name the window if there is a name + XTextProperty window_name; + XTextProperty *window_name_p = (XTextProperty *)NULL; + if (properties.has_title()) { + char *name = (char *)properties.get_title().c_str(); + if (XStringListToTextProperty(&name, 1, &window_name) != 0) { + window_name_p = &window_name; + } + } + + // Setup size hints + XSizeHints *size_hints_p = NULL; + if (properties.has_origin() || properties.has_size()) { + size_hints_p = XAllocSizeHints(); + if (size_hints_p != (XSizeHints *)NULL) { + if (properties.has_origin()) { + size_hints_p->x = properties.get_x_origin(); + size_hints_p->y = properties.get_y_origin(); + size_hints_p->flags |= USPosition; + } + if (properties.has_size()) { + size_hints_p->width = properties.get_x_size(); + size_hints_p->height = properties.get_y_size(); + size_hints_p->flags |= USSize; + } + } + } + + // Setup window manager hints + XWMHints *wm_hints_p = NULL; + wm_hints_p = XAllocWMHints(); + if (wm_hints_p != (XWMHints *)NULL) { + if (properties.has_minimized() && properties.get_minimized()) { + wm_hints_p->initial_state = IconicState; + } else { + wm_hints_p->initial_state = NormalState; + } + wm_hints_p->flags = StateHint; + } + + // If we asked for a window without a border, there's no good way to + // arrange that. It completely depends on the user's window manager + // of choice. Instead, we'll totally punt and just set the window's + // Class to "Undecorated", and let the user configure his/her window + // manager not to put a border around windows of this class. + XClassHint *class_hints_p = NULL; + if (properties.has_undecorated() && properties.get_undecorated()) { + class_hints_p = XAllocClassHint(); + class_hints_p->res_class = "Undecorated"; + } + + XSetWMProperties(_display, _xwindow, window_name_p, window_name_p, + NULL, 0, size_hints_p, wm_hints_p, class_hints_p); + + if (size_hints_p != (XSizeHints *)NULL) { + XFree(size_hints_p); + } + if (wm_hints_p != (XWMHints *)NULL) { + XFree(wm_hints_p); + } + if (class_hints_p != (XClassHint *)NULL) { + XFree(class_hints_p); + } +} + +//////////////////////////////////////////////////////////////////// +// Function: glxGraphicsWindow::try_for_visual +// Access: Private +// Description: Attempt to get the requested visual, if it is +// available. It's just a wrapper around +// glXChooseVisual(). It returns the visual information +// if possible, or NULL if it is not. +//////////////////////////////////////////////////////////////////// +XVisualInfo *glxGraphicsWindow:: +try_for_visual(int framebuffer_mode, + int want_depth_bits, int want_color_bits) const { static const int max_attrib_list = 32; int attrib_list[max_attrib_list]; int n=0; @@ -146,13 +463,12 @@ try_for_visual(glxDisplay *glx, int mask, << "Trying for visual with: RGB(" << want_color_bits << ")"; int want_color_component_bits; - if (mask & W_ALPHA) { + if (framebuffer_mode & WindowProperties::FM_alpha) { want_color_component_bits = max(want_color_bits / 4, 1); } else { want_color_component_bits = max(want_color_bits / 3, 1); } - attrib_list[n++] = GLX_RGBA; attrib_list[n++] = GLX_RED_SIZE; attrib_list[n++] = want_color_component_bits; @@ -161,30 +477,30 @@ try_for_visual(glxDisplay *glx, int mask, attrib_list[n++] = GLX_BLUE_SIZE; attrib_list[n++] = want_color_component_bits; - if (mask & W_ALPHA) { + if (framebuffer_mode & WindowProperties::FM_alpha) { glxdisplay_cat.debug(false) << " ALPHA"; attrib_list[n++] = GLX_ALPHA_SIZE; attrib_list[n++] = want_color_component_bits; } - if (mask & W_DOUBLE) { + if (framebuffer_mode & WindowProperties::FM_double_buffer) { glxdisplay_cat.debug(false) << " DOUBLEBUFFER"; attrib_list[n++] = GLX_DOUBLEBUFFER; } - if (mask & W_STEREO) { + if (framebuffer_mode & WindowProperties::FM_stereo) { glxdisplay_cat.debug(false) << " STEREO"; attrib_list[n++] = GLX_STEREO; } - if (mask & W_DEPTH) { + if (framebuffer_mode & WindowProperties::FM_depth) { glxdisplay_cat.debug(false) << " DEPTH(" << want_depth_bits << ")"; attrib_list[n++] = GLX_DEPTH_SIZE; attrib_list[n++] = want_depth_bits; } - if (mask & W_STENCIL) { + if (framebuffer_mode & WindowProperties::FM_stencil) { glxdisplay_cat.debug(false) << " STENCIL"; attrib_list[n++] = GLX_STENCIL_SIZE; attrib_list[n++] = 1; } - if (mask & W_ACCUM) { + if (framebuffer_mode & WindowProperties::FM_accum) { glxdisplay_cat.debug(false) << " ACCUM"; attrib_list[n++] = GLX_ACCUM_RED_SIZE; attrib_list[n++] = want_color_component_bits; @@ -192,13 +508,13 @@ try_for_visual(glxDisplay *glx, int mask, attrib_list[n++] = want_color_component_bits; attrib_list[n++] = GLX_ACCUM_BLUE_SIZE; attrib_list[n++] = want_color_component_bits; - if (mask & W_ALPHA) { + if (framebuffer_mode & WindowProperties::FM_alpha) { attrib_list[n++] = GLX_ACCUM_ALPHA_SIZE; attrib_list[n++] = want_color_component_bits; } } #if defined(GLX_VERSION_1_1) && defined(GLX_SGIS_multisample) - if (mask & W_MULTISAMPLE) { + if (framebuffer_mode & WindowProperties::FM_multisample) { glxdisplay_cat.debug(false) << " MULTISAMPLE"; attrib_list[n++] = GLX_SAMPLES_SGIS; // We decide 4 is minimum number of samples @@ -210,8 +526,7 @@ try_for_visual(glxDisplay *glx, int mask, nassertr(n < max_attrib_list, NULL); attrib_list[n] = (int)None; - XVisualInfo *vinfo = - glXChooseVisual(glx->get_display(), glx->get_screen(), attrib_list); + XVisualInfo *vinfo = glXChooseVisual(_display, _screen, attrib_list); if (glxdisplay_cat.is_debug()) { if (vinfo != NULL) { @@ -225,31 +540,44 @@ try_for_visual(glxDisplay *glx, int mask, } //////////////////////////////////////////////////////////////////// -// Function: choose visual -// Access: -// Description: +// Function: glxGraphicsWindow::choose visual +// Access: Private +// Description: Selects an appropriate X visual for the window based +// on the window properties. Returns true if +// successful, false otherwise. +// +// Initializes _visual, and modifies _properties +// according to the actual visual chosen. //////////////////////////////////////////////////////////////////// -void glxGraphicsWindow::choose_visual(void) -{ - glxDisplay *glx = _pipe->get_glx_display(); - nassertv(glx != (glxDisplay *)NULL); +bool glxGraphicsWindow:: +choose_visual() { + int framebuffer_mode = 0; + int want_depth_bits = 0; + int want_color_bits = 0; - int mask = _props._mask; - int want_depth_bits = _props._want_depth_bits; - int want_color_bits = _props._want_color_bits; + if (_properties.has_framebuffer_mode()) { + framebuffer_mode = _properties.get_framebuffer_mode(); + } -#if defined(GLX_VERSION_1_1) && defined(GLX_SGIS_multisample) - if (mask & W_MULTISAMPLE) { + if (_properties.has_depth_bits()) { + want_depth_bits = _properties.get_depth_bits(); + } + + if (_properties.has_color_bits()) { + want_color_bits = _properties.get_color_bits(); + } + + /* + if (framebuffer_mode & WindowProperties::FM_multisample) { if (!glx_supports("GLX_SGIS_multisample")) { glxdisplay_cat.info() - << "glxGraphicsWindow::config() - multisample not supported" - << endl; - mask &= ~W_MULTISAMPLE; + << "multisample not supported by this glx implementation.\n"; + framebuffer_mode &= ~WindowProperties::FM_multisample; } } -#endif + */ - _visual = try_for_visual(glx, mask, want_depth_bits, want_color_bits); + _visual = try_for_visual(framebuffer_mode, want_depth_bits, want_color_bits); // This is the severity level at which we'll report the details of // the visual we actually do find. Normally, it's debug-level @@ -279,7 +607,7 @@ void glxGraphicsWindow::choose_visual(void) // Actually, first we'll eliminate all of the minimum sizes, to // try to open a window with all of the requested options, but // maybe not as many bits in some options as we'd like. - _visual = try_for_visual(glx, mask); + _visual = try_for_visual(framebuffer_mode, 1, 1); } if (_visual == NULL) { @@ -287,60 +615,60 @@ void glxGraphicsWindow::choose_visual(void) // as many bits as we asked for. // This array keeps the bitmasks of options that we pull out of - // the requested mask, in order. + // the requested framebuffer_mode, in order. static const int strip_properties[] = { // One esoteric option removed. - W_MULTISAMPLE, - W_STENCIL, - W_ACCUM, - W_ALPHA, - W_STEREO, + WindowProperties::FM_multisample, + WindowProperties::FM_stencil, + WindowProperties::FM_accum, + WindowProperties::FM_alpha, + WindowProperties::FM_stereo, // Two esoteric options removed. - W_STENCIL | W_MULTISAMPLE, - W_ACCUM | W_MULTISAMPLE, - W_ALPHA | W_MULTISAMPLE, - W_STEREO | W_MULTISAMPLE, - W_STENCIL | W_ACCUM, - W_ALPHA | W_STEREO, - W_STENCIL | W_ACCUM | W_MULTISAMPLE, - W_ALPHA | W_STEREO | W_MULTISAMPLE, + WindowProperties::FM_stencil | WindowProperties::FM_multisample, + WindowProperties::FM_accum | WindowProperties::FM_multisample, + WindowProperties::FM_alpha | WindowProperties::FM_multisample, + WindowProperties::FM_stereo | WindowProperties::FM_multisample, + WindowProperties::FM_stencil | WindowProperties::FM_accum, + WindowProperties::FM_alpha | WindowProperties::FM_stereo, + WindowProperties::FM_stencil | WindowProperties::FM_accum | WindowProperties::FM_multisample, + WindowProperties::FM_alpha | WindowProperties::FM_stereo | WindowProperties::FM_multisample, // All esoteric options removed. - W_STENCIL | W_ACCUM | W_ALPHA | W_STEREO | W_MULTISAMPLE, + WindowProperties::FM_stencil | WindowProperties::FM_accum | WindowProperties::FM_alpha | WindowProperties::FM_stereo | WindowProperties::FM_multisample, // All esoteric options, plus some we'd really really prefer, // removed. - W_STENCIL | W_ACCUM | W_ALPHA | W_STEREO | W_MULTISAMPLE | W_DOUBLE, + WindowProperties::FM_stencil | WindowProperties::FM_accum | WindowProperties::FM_alpha | WindowProperties::FM_stereo | WindowProperties::FM_multisample | WindowProperties::FM_double_buffer, // A zero marks the end of the array. 0 }; pset tried_masks; - tried_masks.insert(mask); + tried_masks.insert(framebuffer_mode); int i; for (i = 0; _visual == NULL && strip_properties[i] != 0; i++) { - int new_mask = mask & ~strip_properties[i]; - if (tried_masks.insert(new_mask).second) { - _visual = try_for_visual(glx, new_mask, want_depth_bits, + int new_framebuffer_mode = framebuffer_mode & ~strip_properties[i]; + if (tried_masks.insert(new_framebuffer_mode).second) { + _visual = try_for_visual(new_framebuffer_mode, want_depth_bits, want_color_bits); } } if (special_size_request) { tried_masks.clear(); - tried_masks.insert(mask); + tried_masks.insert(framebuffer_mode); if (_visual == NULL) { // Try once more, this time eliminating all of the size // requests. for (i = 0; _visual == NULL && strip_properties[i] != 0; i++) { - int new_mask = mask & ~strip_properties[i]; - if (tried_masks.insert(new_mask).second) { - _visual = try_for_visual(glx, new_mask); + int new_framebuffer_mode = framebuffer_mode & ~strip_properties[i]; + if (tried_masks.insert(new_framebuffer_mode).second) { + _visual = try_for_visual(new_framebuffer_mode, 1, 1); } } } @@ -349,14 +677,13 @@ void glxGraphicsWindow::choose_visual(void) if (_visual == NULL) { // Here's our last-ditch desparation attempt: give us any GLX // visual at all! - _visual = try_for_visual(glx, 0); + _visual = try_for_visual(0, 1, 1); } if (_visual == NULL) { - glxdisplay_cat.fatal() - << "glxGraphicsWindow::choose_visual() - could not get any " - "GLX visual." << endl; - exit(1); + glxdisplay_cat.error() + << "Could not get any GLX visual.\n"; + return false; } } } @@ -364,25 +691,53 @@ void glxGraphicsWindow::choose_visual(void) glxdisplay_cat.info() << "Got visual 0x" << hex << (int)_visual->visualid << dec << ".\n"; + // Now update our frambuffer_mode and bit depth appropriately. + int render_mode, double_buffer, stereo, red_size, green_size, blue_size, + alpha_size, ared_size, agreen_size, ablue_size, aalpha_size, + depth_size, stencil_size; + + glXGetConfig(_display, _visual, GLX_RGBA, &render_mode); + glXGetConfig(_display, _visual, GLX_DOUBLEBUFFER, &double_buffer); + glXGetConfig(_display, _visual, GLX_STEREO, &stereo); + glXGetConfig(_display, _visual, GLX_RED_SIZE, &red_size); + glXGetConfig(_display, _visual, GLX_GREEN_SIZE, &green_size); + glXGetConfig(_display, _visual, GLX_BLUE_SIZE, &blue_size); + glXGetConfig(_display, _visual, GLX_ALPHA_SIZE, &alpha_size); + glXGetConfig(_display, _visual, GLX_ACCUM_RED_SIZE, &ared_size); + glXGetConfig(_display, _visual, GLX_ACCUM_GREEN_SIZE, &agreen_size); + glXGetConfig(_display, _visual, GLX_ACCUM_BLUE_SIZE, &ablue_size); + glXGetConfig(_display, _visual, GLX_ACCUM_ALPHA_SIZE, &aalpha_size); + glXGetConfig(_display, _visual, GLX_DEPTH_SIZE, &depth_size); + glXGetConfig(_display, _visual, GLX_STENCIL_SIZE, &stencil_size); + + framebuffer_mode = 0; + if (double_buffer) { + framebuffer_mode |= WindowProperties::FM_double_buffer; + } + if (stereo) { + framebuffer_mode |= WindowProperties::FM_stereo; + } + if (!render_mode) { + framebuffer_mode |= WindowProperties::FM_index; + } + if (stencil_size != 0) { + framebuffer_mode |= WindowProperties::FM_stencil; + } + if (depth_size != 0) { + framebuffer_mode |= WindowProperties::FM_depth; + } + if (alpha_size != 0) { + framebuffer_mode |= WindowProperties::FM_alpha; + } + if (ared_size + agreen_size + ablue_size != 0) { + framebuffer_mode |= WindowProperties::FM_accum; + } + + _properties.set_framebuffer_mode(framebuffer_mode); + _properties.set_color_bits(red_size + green_size + blue_size + alpha_size); + _properties.set_depth_bits(depth_size); + if (glxdisplay_cat.is_on(show_visual_severity)) { - int render_mode, double_buffer, stereo, red_size, green_size, blue_size, - alpha_size, ared_size, agreen_size, ablue_size, aalpha_size, - depth_size, stencil_size; - - glXGetConfig(_display, _visual, GLX_RGBA, &render_mode); - glXGetConfig(_display, _visual, GLX_DOUBLEBUFFER, &double_buffer); - glXGetConfig(_display, _visual, GLX_STEREO, &stereo); - glXGetConfig(_display, _visual, GLX_RED_SIZE, &red_size); - glXGetConfig(_display, _visual, GLX_GREEN_SIZE, &green_size); - glXGetConfig(_display, _visual, GLX_BLUE_SIZE, &blue_size); - glXGetConfig(_display, _visual, GLX_ALPHA_SIZE, &alpha_size); - glXGetConfig(_display, _visual, GLX_ACCUM_RED_SIZE, &ared_size); - glXGetConfig(_display, _visual, GLX_ACCUM_GREEN_SIZE, &agreen_size); - glXGetConfig(_display, _visual, GLX_ACCUM_BLUE_SIZE, &ablue_size); - glXGetConfig(_display, _visual, GLX_ACCUM_ALPHA_SIZE, &aalpha_size); - glXGetConfig(_display, _visual, GLX_DEPTH_SIZE, &depth_size); - glXGetConfig(_display, _visual, GLX_STENCIL_SIZE, &stencil_size); - glxdisplay_cat.out(show_visual_severity) << "GLX Visual Info (# bits of each):" << endl << " RGBA: " << red_size << " " << green_size << " " << blue_size @@ -394,398 +749,69 @@ void glxGraphicsWindow::choose_visual(void) << " DoubleBuffer? " << double_buffer << endl << " Stereo? " << stereo << endl; } + + return true; } //////////////////////////////////////////////////////////////////// -// Function: config -// Access: -// Description: +// Function: glxGraphicsWindow::setup_colormap +// Access: Private +// Description: Allocates a colormap appropriate to the visual and +// stores in in the _colormap method. //////////////////////////////////////////////////////////////////// -void glxGraphicsWindow::config( void ) -{ - GraphicsWindow::config(); +void glxGraphicsWindow:: +setup_colormap() { + glxGraphicsPipe *glx_pipe; + DCAST_INTO_V(glx_pipe, _pipe); + Window root_window = glx_pipe->get_root(); - glxDisplay *glx = _pipe->get_glx_display(); - nassertv(glx != (glxDisplay *)NULL); - - _display = glx->get_display(); - - // Configure the framebuffer according to parameters specified in _props - // Initializes _visual - choose_visual(); - - // Initializes _colormap - setup_colormap(); - - uint attrib_mask = CWBackPixmap | CWBorderPixel | CWColormap | CWEventMask; - - // Do we even need structure notify? - _event_mask = StructureNotifyMask; - - // Initialize window attributes - XSetWindowAttributes wa; - wa.background_pixmap = None; - wa.border_pixel = 0; - wa.colormap = _colormap; - wa.event_mask = _event_mask; - wa.do_not_propagate_mask = 0; - - _xwindow = XCreateWindow(_display, glx->get_root(), - _props._xorg, _props._yorg, _props._xsize, _props._ysize, 0, - _visual->depth, InputOutput, _visual->visual, attrib_mask, &wa); - if (!_xwindow) { - glxdisplay_cat.fatal() - << "glxGraphicsWindow::config() - failed to create Xwindow" << endl; - exit(0); - } - - setup_properties(); - - _context = glXCreateContext(_display, _visual, None, GL_TRUE); - if (!_context) { - glxdisplay_cat.fatal() - << "glxGraphicsWindow::config() - failed to create OpenGL rendering " - << "context" << endl; - exit(0); - } - - if (!(glXIsDirect(_display, _context))) { - glxdisplay_cat.info() - << "Graphics context is not direct (it does not bypass X)." - << endl; - } - - _change_mask = 0; - _configure_mask = 0; - - _mouse_input_enabled = false; - _mouse_motion_enabled = false; - _mouse_passive_motion_enabled = false; - _mouse_entry_enabled = false; - _entry_state = -1; - - XSelectInput(_display, _xwindow, _event_mask); - XMapWindow(_display, _xwindow); - - _connection_fd = ConnectionNumber(_display); - - // Enable detection of mouse input - enable_mouse_input(true); - enable_mouse_motion(true); - enable_mouse_passive_motion(true); - enable_mouse_entry(true); - - // Enable detection of keyboard input - add_event_mask(KeyPressMask | KeyReleaseMask); - - // Now indicate that we have our keyboard/mouse device ready. - GraphicsWindowInputDevice device = - GraphicsWindowInputDevice::pointer_and_keyboard("keyboard/mouse"); - _input_devices.push_back(device); - - // Create a GSG to manage the graphics - // First make the new context and window the current one so GL knows how - // to configure itself in the gsg - make_current(); - make_gsg(); - - if (gl_show_fps_meter) { - // 128 handles all the ascii chars - // this creates a display list for each char. displist numbering starts - // at FONT_BITMAP_OGLDISPLAYLISTNUM. Might want to optimize just to save - // mem by just allocating bitmaps for chars we need (0-9,f,p,s,SPC) - XFontStruct* foo; - // I /know/ there has to be a way to get a useful handle to the default - // font, but I have to date been unable to find one - foo = XLoadQueryFont(_display, "-*-*-*-*-*--12-*-*-*-*-*-*-*"); - if (foo == (XFontStruct *)NULL) { - glxdisplay_cat.warning() - << "Unable to load X display font for FPS meter\n"; - gl_show_fps_meter = false; - } else { - glxdisplay_cat.info() - << "Loaded X display font for FPS meter\n"; - glXUseXFont(foo->fid, 0, 128, FONT_BITMAP_OGLDISPLAYLISTNUM); - _start_time = ClockObject::get_global_clock()->get_real_time(); - _start_frame_count = 0; - _cur_frame_count = 0; - _current_fps = 0.; - } - } -} - -//////////////////////////////////////////////////////////////////// -// Function: setup_colormap -// Access: -// Description: -//////////////////////////////////////////////////////////////////// -void glxGraphicsWindow::setup_colormap(void) -{ - int visual_class, rc, is_rgb; -#if defined(__cplusplus) || defined(c_plusplus) - visual_class = _visual->c_class; -#else - visual_class = _visual->class; -#endif - glxDisplay *glx = _pipe->get_glx_display(); - nassertv(glx != (glxDisplay *)NULL); + int visual_class = _visual->c_class; + int rc, is_rgb; switch (visual_class) { case PseudoColor: rc = glXGetConfig(_display, _visual, GLX_RGBA, &is_rgb); if (rc == 0 && is_rgb) { - glxdisplay_cat.info() - << "glxGraphicsWindow::setup_colormap() - mesa pseudocolor " - << "not supported" << endl; - // this is a terrible terrible hack, that seems to work + glxdisplay_cat.warning() + << "mesa pseudocolor not supported.\n"; + // this is a terrible terrible hack, but it seems to work _colormap = (Colormap)0; + } else { - _colormap = XCreateColormap(_display, glx->get_root(), - _visual->visual, AllocAll); + _colormap = XCreateColormap(_display, root_window, + _visual->visual, AllocAll); } break; case TrueColor: case DirectColor: - _colormap = XCreateColormap(_display, glx->get_root(), - _visual->visual, AllocNone); + _colormap = XCreateColormap(_display, root_window, + _visual->visual, AllocNone); break; case StaticColor: case StaticGray: case GrayScale: - _colormap = XCreateColormap(_display, glx->get_root(), - _visual->visual, AllocNone); + _colormap = XCreateColormap(_display, root_window, + _visual->visual, AllocNone); break; default: glxdisplay_cat.error() - << "glxGraphicsWindow::setup_colormap() - could not allocate a " - << "colormap for visual type: " << visual_class << endl; + << "Could not allocate a colormap for visual class " + << visual_class << ".\n"; break; } } //////////////////////////////////////////////////////////////////// -// Function: setup_properties -// Access: -// Description: +// Function: glxGraphicsWindow::get_button +// Access: Private +// Description: Returns the Panda ButtonHandle corresponding to the +// keyboard button indicated by the given key event. //////////////////////////////////////////////////////////////////// -void glxGraphicsWindow::setup_properties(void) -{ - // Name the window if there is a name - XTextProperty window_name; - if (!_props._title.empty()) { - char *name = (char *)_props._title.c_str(); - if (XStringListToTextProperty(&name, 1, &window_name) == 0) { - glxdisplay_cat.error() - << "glxGraphicsWindow::config() - failed to allocate window name " - << "structure" << endl; - } - } - - // Setup size hints - XSizeHints size_hints = {0}; - if (_props._xorg >= 0 && _props._yorg >= 0) { - size_hints.x = _props._xorg; - size_hints.y = _props._yorg; - size_hints.flags |= USPosition; - } - else - size_hints.flags &= ~USPosition; - if (_props._xsize >= 0 && _props._ysize >= 0) { - size_hints.width = _props._xsize; - size_hints.height = _props._ysize; - size_hints.flags |= USSize; - } - else - size_hints.flags &= ~USSize; - - // Setup window manager hints - XWMHints* wm_hints; - if (!(wm_hints = XAllocWMHints())) { - glxdisplay_cat.fatal() - << "failed to allocate wm hints" << endl; - exit(-1); - } - wm_hints->initial_state = NormalState; - wm_hints->flags = StateHint; - - XSetWMProperties(_display, _xwindow, &window_name, &window_name, - NULL, 0, &size_hints, wm_hints, NULL); - XFree(wm_hints); - - // If we asked for a window without a border, there's no sure-fire - // way to arrange that. It really depends on the user's window - // manager of choice. Instead, we'll totally punt and just set the - // window's Class to "Undecorated", and let the user configure - // his/her window manager not to put a border around windows of this - // class. - if (!_props._border) { - XClassHint *class_hint = XAllocClassHint(); - class_hint->res_class = "Undecorated"; - XSetClassHint(_display, _xwindow, class_hint); - XFree(class_hint); - } -} - -//////////////////////////////////////////////////////////////////// -// Function: end_frame -// Access: -// Description: Swaps the front and back buffers. -//////////////////////////////////////////////////////////////////// -void glxGraphicsWindow::end_frame( void ) -{ - if (gl_show_fps_meter) { - PStatTimer timer(_show_fps_pcollector); - ClockObject* co = ClockObject::get_global_clock(); - double now = co->get_real_time(); - double time_delta = now - _start_time; - if (time_delta > gl_fps_meter_update_interval) { - double num_frames = _cur_frame_count - _start_frame_count; - _current_fps = num_frames / time_delta; - _start_time = now; - _start_frame_count = _cur_frame_count; - } - char fps_msg[20]; - sprintf(fps_msg, "%7.02f fps", _current_fps); - glColor3f(0., 1., 1.); - GLboolean tex_was_on = glIsEnabled(GL_TEXTURE_2D); - if (tex_was_on) - glDisable(GL_TEXTURE_2D); - glMatrixMode(GL_MODELVIEW); - glPushMatrix(); - glLoadMatrixf(LMatrix4f::ident_mat().get_data()); - glMatrixMode(GL_PROJECTION); - glPushMatrix(); - glLoadMatrixf(LMatrix4f::ident_mat().get_data()); - - glOrtho(_props._xorg,_props._xorg+_props._xsize, - _props._yorg,_props._yorg+_props._ysize,-1.0,1.0); - - // these seem to be good for default font - glRasterPos2f(_props._xsize-75,_props._ysize-20); - - // set up for a string-drawing display list call - glListBase(FONT_BITMAP_OGLDISPLAYLISTNUM); - - // draw a string using font display lists. chars index their - // corresponding displist name - glCallLists(strlen(fps_msg), GL_UNSIGNED_BYTE, fps_msg); - - glPopMatrix(); - glMatrixMode(GL_MODELVIEW); - glPopMatrix(); - - if(tex_was_on) - glEnable(GL_TEXTURE_2D); - - _cur_frame_count++; // only used by fps meter right now - } - - { - PStatTimer timer(_swap_pcollector); - if(_is_synced)glFinish(); - else glXSwapBuffers(_display, _xwindow); - } - - GraphicsWindow::end_frame(); -} - -void glxGraphicsWindow::swap() -{ - if(_is_synced) glXSwapBuffers(_display, _xwindow); -} - -//////////////////////////////////////////////////////////////////// -// Function: handle_reshape -// Access: -// Description: -//////////////////////////////////////////////////////////////////// -void glxGraphicsWindow::handle_reshape(int w, int h) -{ - resized(w, h); - // Do we want to reshape the glViewport here as well? - //glViewport(0, 0, (GLsizei)_props._xsize, (GLsizei)_props._ysize); -} - -//////////////////////////////////////////////////////////////////// -// Function: handle_mouse_motion -// Access: -// Description: -//////////////////////////////////////////////////////////////////// -void glxGraphicsWindow::handle_mouse_motion(int x, int y) { - _input_devices[0].set_pointer_in_window(x, y); -} - -//////////////////////////////////////////////////////////////////// -// Function: handle_mouse_entry -// Access: -// Description: -//////////////////////////////////////////////////////////////////// -void glxGraphicsWindow::handle_mouse_entry(int state) { - if (state == MOUSE_EXITED) { - _input_devices[0].set_pointer_out_of_window(); - } -} - -//////////////////////////////////////////////////////////////////// -// Function: handle_keypress -// Access: -// Description: -//////////////////////////////////////////////////////////////////// -void glxGraphicsWindow:: -handle_keypress(ButtonHandle key, int x, int y) { - _input_devices[0].set_pointer_in_window(x, y); - if (key != ButtonHandle::none()) { - if (key.has_ascii_equivalent()) { - int ch = key.get_ascii_equivalent(); - _input_devices[0].keystroke(ch); - - // For buttons (as opposed to keystrokes), we need to make - // uppercase keynames into lowercase keynames, by Panda - // convention. - _input_devices[0].button_down(KeyboardButton::ascii_key(tolower(ch))); - } else { - _input_devices[0].button_down(key); - } - } -} - -//////////////////////////////////////////////////////////////////// -// Function: handle_keyrelease -// Access: -// Description: -//////////////////////////////////////////////////////////////////// -void glxGraphicsWindow:: -handle_keyrelease(ButtonHandle key, int, int) { - if (key != ButtonHandle::none()) { - if (key.has_ascii_equivalent()) { - int ch = key.get_ascii_equivalent(); - - // For buttons (as opposed to keystrokes), we need to make - // uppercase keynames into lowercase keynames, by Panda - // convention. - _input_devices[0].button_up(KeyboardButton::ascii_key(tolower(ch))); - } else { - _input_devices[0].button_up(key); - } - } -} - ButtonHandle glxGraphicsWindow:: -lookup_key(XEvent event) { - // First, get the string key name. If it fits in one character, it - // must be the ASCII equivalent for the key. - char tmp[1]; - if (XLookupString(&event.xkey, tmp, 1, NULL, NULL)) { - ButtonHandle button = KeyboardButton::ascii_key(tmp[0]); - if (button != ButtonHandle::none()) { - return button; - } - } +get_button(XKeyEvent *key_event) { + KeySym key = XLookupKeysym(key_event, 0); - // Otherwise, look it up the hard way. - KeySym ks = XLookupKeysym((XKeyEvent *)&event, 0); - - switch (ks) { + switch (key) { case XK_BackSpace: return KeyboardButton::backspace(); case XK_Tab: @@ -1058,432 +1084,3 @@ lookup_key(XEvent event) { return ButtonHandle::none(); } - -//////////////////////////////////////////////////////////////////// -// Function: interruptible_xnextevent -// Access: -// Description: -//////////////////////////////////////////////////////////////////// -int glxGraphicsWindow::interruptible_xnextevent(Display* display, XEvent* event) -{ - XFlush(display); - if (XPending(display)) { - XNextEvent(display, event); - return 1; - } else - return 0; -} - -//////////////////////////////////////////////////////////////////// -// Function: handle_changes -// Access: -// Description: -//////////////////////////////////////////////////////////////////// -void glxGraphicsWindow::handle_changes(void) -{ - // As an optimization, check to see if change is anything other than a - // redisplay - if (_change_mask & (GLXWIN_CONFIGURE | GLXWIN_EVENT)) { - if (_change_mask & GLXWIN_CONFIGURE) { - XWindowChanges changes; - changes.x = _props._xorg; - changes.y = _props._yorg; - if (_configure_mask & (CWWidth | CWHeight)) { - changes.width = _props._xsize; - changes.height = _props._ysize; - } - XConfigureWindow(_display, _xwindow, _configure_mask, &changes); - _configure_mask = 0; - } - if (_change_mask & GLXWIN_EVENT) { - XSelectInput(_display, _xwindow, _event_mask); - } - } - - _change_mask = 0; -} - -//////////////////////////////////////////////////////////////////// -// Function: process_event -// Access: -// Description: -//////////////////////////////////////////////////////////////////// -void glxGraphicsWindow::process_event(XEvent event) -{ - switch (event.type) { - case MappingNotify: - break; - case ConfigureNotify: - if (_props._xsize != event.xconfigure.width || - _props._ysize != event.xconfigure.height) { - _props._xsize = event.xconfigure.width; - _props._ysize = event.xconfigure.height; - make_current(); - // Do not execute OpenGL out of sequence with respect to the - // XResizeWindow request - glXWaitX(); - handle_reshape(event.xconfigure.width, event.xconfigure.height); - _change_mask |= GLXWIN_CONFIGURE; - } - break; - case Expose: - break; - - case ButtonPress: - make_current(); - handle_keypress(MouseButton::button(event.xbutton.button - 1), - event.xkey.x, event.xkey.y); - break; - - case ButtonRelease: - make_current(); - handle_keyrelease(MouseButton::button(event.xbutton.button - 1), - event.xkey.x, event.xkey.y); - break; - - case MotionNotify: - if (_mouse_motion_enabled && event.xmotion.state & - (Button1Mask | Button2Mask | Button3Mask)) { - make_current(); - handle_mouse_motion(event.xmotion.x, event.xmotion.y); - } else if (_mouse_passive_motion_enabled && - ((event.xmotion.state & - (Button1Mask | Button2Mask | Button3Mask)) == 0)) { - make_current(); - handle_mouse_motion(event.xmotion.x, event.xmotion.y); - } - break; - - case KeyPress: - make_current(); - handle_keypress(lookup_key(event), event.xkey.x, event.xkey.y); - break; - - case KeyRelease: - make_current(); - handle_keyrelease(lookup_key(event), event.xkey.x, event.xkey.y); - break; - - case EnterNotify: - case LeaveNotify: - if (_mouse_entry_enabled) { - if (event.type == EnterNotify) { - // Overlays can generate multiple enter events - if (_entry_state != EnterNotify) { - _entry_state = EnterNotify; - make_current(); - handle_mouse_entry(MOUSE_ENTERED); - if (_mouse_passive_motion_enabled) { - handle_mouse_motion(event.xcrossing.x, event.xcrossing.y); - } - } - } else { // event.type == LeaveNotify - if (_entry_state != LeaveNotify) { - _entry_state = LeaveNotify; - make_current(); - handle_mouse_entry(MOUSE_EXITED); - } - } - } else if (_mouse_passive_motion_enabled) { - make_current(); - handle_mouse_motion(event.xcrossing.x, event.xcrossing.y); - } - break; - - case DestroyNotify: - close_window(); - break; - - case UnmapNotify: - case VisibilityNotify: - case ClientMessage: - case CirculateNotify: - case CreateNotify: - case GravityNotify: - case ReparentNotify: - break; - default: - break; - } -} - -//////////////////////////////////////////////////////////////////// -// Function: process_events -// Access: -// Description: -//////////////////////////////////////////////////////////////////// -void glxGraphicsWindow::process_events(void) -{ - XEvent event; - int got_event; - glxGraphicsWindow* window; - - if (_change_mask) - handle_changes(); - - glxDisplay *glx = _pipe->get_glx_display(); - nassertv(glx != (glxDisplay *)NULL); - - do { - got_event = interruptible_xnextevent(_display, &event); - if (got_event) { - switch (event.type) { - case MappingNotify: - XRefreshKeyboardMapping((XMappingEvent *) &event); - break; - case ConfigureNotify: - if ((window = glx->find_window(event.xconfigure.window)) != NULL) - window->process_event(event); - break; - case Expose: - XEvent ahead; - while (XEventsQueued(_display, QueuedAfterReading) > 0) { - XPeekEvent(_display, &ahead); - if (ahead.type != Expose || - ahead.xexpose.window != event.xexpose.window) { - break; - } - XNextEvent(_display, &event); - } - break; - case ButtonPress: - case ButtonRelease: - if ((window = glx->find_window(event.xbutton.window)) != NULL) - window->process_event(event); - break; - case MotionNotify: - if ((window = glx->find_window(event.xmotion.window)) != NULL) - window->process_event(event); - break; - case KeyPress: - case KeyRelease: - if ((window = glx->find_window(event.xmotion.window)) != NULL) - window->process_event(event); - break; - case EnterNotify: - case LeaveNotify: - if (event.xcrossing.mode != NotifyNormal || - event.xcrossing.mode == NotifyNonlinearVirtual || - event.xcrossing.mode == NotifyVirtual) { - // Ignore "virtual" window enter/leave events - break; - } - if ((window = glx->find_window(event.xcrossing.window)) != NULL) - window->process_event(event); - break; - case UnmapNotify: - case VisibilityNotify: - break; - case ClientMessage: - break; - case DestroyNotify: - case CirculateNotify: - case CreateNotify: - case GravityNotify: - case ReparentNotify: - break; - default: - break; - } - } - } - while (XPending(_display)); -} - -//////////////////////////////////////////////////////////////////// -// Function: idle_wait -// Access: -// Description: -//////////////////////////////////////////////////////////////////// -void glxGraphicsWindow::idle_wait(void) -{ - if (XPending(_display)) - process_events(); - - call_idle_callback(); -} - - -//////////////////////////////////////////////////////////////////// -// Function: glxGraphicsWindow::supports_update -// Access: Public, Virtual -// Description: Returns true if this particular kind of -// GraphicsWindow supports use of the update() function -// to update the graphics one frame at a time, so that -// the window does not need to be the program's main -// loop. Returns false if the only way to update the -// window is to call main_loop(). -//////////////////////////////////////////////////////////////////// -bool glxGraphicsWindow:: -supports_update() const { - return true; -} - -//////////////////////////////////////////////////////////////////// -// Function: update -// Access: -// Description: -//////////////////////////////////////////////////////////////////// -void glxGraphicsWindow::update(void) -{ - _show_code_pcollector.stop(); - - PStatClient::main_tick(); - - if (_change_mask) - handle_changes(); - - make_current(); - - // Always ask for a redisplay for now - call_draw_callback(true); - - if (_idle_callback) - idle_wait(); - else - process_events(); - - _show_code_pcollector.start(); -} - -//////////////////////////////////////////////////////////////////// -// Function: enable_mouse_input -// Access: -// Description: -//////////////////////////////////////////////////////////////////// -void glxGraphicsWindow::enable_mouse_input(bool val) -{ - long emask = ButtonPressMask | ButtonReleaseMask; - - // See if we need to enable or disable mouse events - if (_mouse_input_enabled == false && val == true) - add_event_mask(emask); - else if (_mouse_input_enabled == true && val == false) - remove_event_mask(emask); - _mouse_input_enabled = val; -} - -//////////////////////////////////////////////////////////////////// -// Function: enable_mouse_motion -// Access: -// Description: -//////////////////////////////////////////////////////////////////// -void glxGraphicsWindow::enable_mouse_motion(bool val) -{ - // Some window managers (4Dwm by default) will mask motion events unless - // button presses are selected as well - long input_mask = ButtonPressMask | ButtonReleaseMask; - long motion_mask = Button1MotionMask | Button2MotionMask | Button3MotionMask; - if (_mouse_motion_enabled == false && val == true) { - add_event_mask(input_mask); - add_event_mask(motion_mask); - } - else if (_mouse_motion_enabled == true && val == false) { - remove_event_mask(motion_mask); - if (_mouse_input_enabled == false) - remove_event_mask(input_mask); - } - _mouse_motion_enabled = val; -} - -//////////////////////////////////////////////////////////////////// -// Function: enable_mouse_passive_motion -// Access: -// Description: -//////////////////////////////////////////////////////////////////// -void glxGraphicsWindow::enable_mouse_passive_motion(bool val) -{ - long entry_mask = EnterWindowMask | LeaveWindowMask; - if (_mouse_passive_motion_enabled == false && val == true) { - add_event_mask(PointerMotionMask); - // Passive motion requires watching enters and leaves so a fake passive - // motion event can be generated on an enter - if (_mouse_entry_enabled == false) - add_event_mask(entry_mask); - } - else if (_mouse_passive_motion_enabled == true && val == false) { - remove_event_mask(PointerMotionMask); - if (_mouse_entry_enabled == false) - remove_event_mask(entry_mask); - } - _mouse_passive_motion_enabled = val; -} - -//////////////////////////////////////////////////////////////////// -// Function: enable_mouse_entry -// Access: -// Description: -//////////////////////////////////////////////////////////////////// -void glxGraphicsWindow::enable_mouse_entry(bool val) -{ - if (_mouse_entry_enabled == false && val == true) { - add_event_mask(EnterWindowMask | LeaveWindowMask); - } - else if (_mouse_entry_enabled == true && val == false) { - remove_event_mask(EnterWindowMask | LeaveWindowMask); - } - _mouse_entry_enabled = val; -} - -//////////////////////////////////////////////////////////////////// -// Function: make_current -// Access: Public -// Description: -//////////////////////////////////////////////////////////////////// -void glxGraphicsWindow::make_current(void) { - PStatTimer timer(_make_current_pcollector); - glXMakeCurrent(_display, _xwindow, _context); -} - -//////////////////////////////////////////////////////////////////// -// Function: unmake_current -// Access: Public -// Description: -//////////////////////////////////////////////////////////////////// -void glxGraphicsWindow::unmake_current(void) { - glXMakeCurrent(_display, None, NULL); -} - -//////////////////////////////////////////////////////////////////// -// Function: glxGraphicsWindow::get_gsg_type -// Access: Public, Virtual -// Description: Returns the TypeHandle of the kind of GSG preferred -// by this kind of window. -//////////////////////////////////////////////////////////////////// -TypeHandle glxGraphicsWindow:: -get_gsg_type() const { - return GLGraphicsStateGuardian::get_class_type(); -} - -GraphicsWindow *glxGraphicsWindow:: -make_GlxGraphicsWindow(const FactoryParams ¶ms) { - GraphicsWindow::WindowPipe *pipe_param; - if (!get_param_into(pipe_param, params)) { - glxdisplay_cat.error() - << "No pipe specified for window creation!" << endl; - return NULL; - } - - GraphicsPipe *pipe = pipe_param->get_pipe(); - - GraphicsWindow::WindowProps *props_param; - if (!get_param_into(props_param, params)) { - return new glxGraphicsWindow(pipe); - } else { - return new glxGraphicsWindow(pipe, props_param->get_properties()); - } -} - -TypeHandle glxGraphicsWindow::get_class_type(void) { - return _type_handle; -} - -void glxGraphicsWindow::init_type(void) { - GraphicsWindow::init_type(); - register_type(_type_handle, "glxGraphicsWindow", - GraphicsWindow::get_class_type()); -} - -TypeHandle glxGraphicsWindow::get_type(void) const { - return get_class_type(); -} diff --git a/panda/src/glxdisplay/glxGraphicsWindow.h b/panda/src/glxdisplay/glxGraphicsWindow.h index 17d19d8c19..26894a4143 100644 --- a/panda/src/glxdisplay/glxGraphicsWindow.h +++ b/panda/src/glxdisplay/glxGraphicsWindow.h @@ -15,115 +15,74 @@ // panda3d@yahoogroups.com . // //////////////////////////////////////////////////////////////////// + #ifndef GLXGRAPHICSWINDOW_H #define GLXGRAPHICSWINDOW_H -// -//////////////////////////////////////////////////////////////////// -// Includes -//////////////////////////////////////////////////////////////////// -#include -#include -#include +#include "pandabase.h" + +#include "graphicsWindow.h" +#include "buttonHandle.h" #include #include -//////////////////////////////////////////////////////////////////// -// Defines -//////////////////////////////////////////////////////////////////// class glxGraphicsPipe; -const int GLXWIN_PROCESSING = 1; -const int GLXWIN_REDISPLAY = 2; -const int GLXWIN_CONFIGURE = 4; -const int GLXWIN_EVENT = 8; - //////////////////////////////////////////////////////////////////// // Class : glxGraphicsWindow -// Description : +// Description : An interface to the glx system for managing GL +// windows under X. //////////////////////////////////////////////////////////////////// -class glxGraphicsWindow : public GraphicsWindow -{ +class glxGraphicsWindow : public GraphicsWindow { public: - glxGraphicsWindow( GraphicsPipe* pipe ); - glxGraphicsWindow( GraphicsPipe* pipe, - const GraphicsWindow::Properties& props ); - virtual ~glxGraphicsWindow( void ); + glxGraphicsWindow(GraphicsPipe *pipe); + virtual ~glxGraphicsWindow(); - virtual bool supports_update() const; - virtual void update(void); - virtual void end_frame( void ); + virtual void make_gsg(); + virtual void release_gsg(); + virtual void make_current(); - virtual void swap(void); + virtual void begin_flip(); - INLINE Window get_xwindow(void) { return _xwindow; } - - virtual TypeHandle get_gsg_type() const; - static GraphicsWindow* make_GlxGraphicsWindow(const FactoryParams ¶ms); - -public: - virtual void make_current(void); - virtual void unmake_current(void); + virtual void process_events(); + virtual void set_properties_now(WindowProperties &properties); protected: - void choose_visual(void); - virtual void config( void ); - void setup_colormap(void); - void setup_properties(void); - - void enable_mouse_input(bool val); - void enable_mouse_motion(bool val); - void enable_mouse_passive_motion(bool val); - void enable_mouse_entry(bool val); - - void handle_reshape( int w, int h ); - void handle_mouse_motion( int x, int y ); - void handle_mouse_entry( int state ); - void handle_keypress( ButtonHandle key, int x, int y ); - void handle_keyrelease( ButtonHandle key, int x, int y ); - ButtonHandle lookup_key(XEvent event); - - int interruptible_xnextevent(Display* display, XEvent* event); - bool glx_supports(const char* extension); - - void handle_changes(void); - void process_event(XEvent); - void process_events(void); - void idle_wait(void); - - INLINE void add_event_mask(long event_mask); - INLINE void remove_event_mask(long event_mask); + virtual void close_window(); + virtual bool open_window(); private: - Display* _display; - Window _xwindow; - GLXContext _context; - XVisualInfo* _visual; - Colormap _colormap; - int _connection_fd; - uint _change_mask; - int _configure_mask; - long _event_mask; + void set_wm_properties(const WindowProperties &properties); - static const char* _glx_extensions; - bool _mouse_input_enabled; - bool _mouse_motion_enabled; - bool _mouse_passive_motion_enabled; - bool _mouse_entry_enabled; - int _entry_state; - bool _ignore_key_repeat; + XVisualInfo *try_for_visual(int framebuffer_mode, + int want_depth_bits, int want_color_bits) const; + bool choose_visual(); + void setup_colormap(); + ButtonHandle get_button(XKeyEvent *key_event); + +private: + Display *_display; + int _screen; + Window _xwindow; + GLXContext _context; + XVisualInfo *_visual; + Colormap _colormap; + long _event_mask; - // fps meter stuff - double _start_time; - long _start_frame_count; - long _cur_frame_count; - float _current_fps; public: - static TypeHandle get_class_type(void); - static void init_type(void); - virtual TypeHandle get_type(void) const; + static TypeHandle get_class_type() { + return _type_handle; + } + static void init_type() { + GraphicsWindow::init_type(); + register_type(_type_handle, "glxGraphicsWindow", + GraphicsWindow::get_class_type()); + } + virtual TypeHandle get_type() const { + return get_class_type(); + } virtual TypeHandle force_init_type() {init_type(); return get_class_type();} private: diff --git a/panda/src/pandabase/pandasymbols.h b/panda/src/pandabase/pandasymbols.h index 97df45a58d..3fd7b28af5 100644 --- a/panda/src/pandabase/pandasymbols.h +++ b/panda/src/pandabase/pandasymbols.h @@ -132,6 +132,14 @@ #define EXPTP_PANDARIB extern #endif +#ifdef BUILDING_PANDAWIN + #define EXPCL_PANDAWIN __declspec(dllexport) + #define EXPTP_PANDAWIN +#else + #define EXPCL_PANDAWIN __declspec(dllimport) + #define EXPTP_PANDAWIN extern +#endif + #ifdef BUILDING_SHADER #define EXPCL_SHADER __declspec(dllexport) #define EXPTP_SHADER @@ -181,6 +189,9 @@ #define EXPCL_PANDARIB #define EXPTP_PANDARIB +#define EXPCL_PANDAWIN +#define EXPTP_PANDAWIN + #define EXPCL_SHADER #define EXPTP_SHADER diff --git a/panda/src/putil/mouseData.I b/panda/src/putil/mouseData.I index 64f88405d1..11d8f5abc8 100644 --- a/panda/src/putil/mouseData.I +++ b/panda/src/putil/mouseData.I @@ -17,6 +17,43 @@ //////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////// +// Function: MouseData::Constructor +// Access: Published +// Description: +//////////////////////////////////////////////////////////////////// +INLINE MouseData:: +MouseData() { + _in_window = false; + _xpos = 0; + _ypos = 0; +} + +//////////////////////////////////////////////////////////////////// +// Function: MouseData::Copy Constructor +// Access: Published +// Description: +//////////////////////////////////////////////////////////////////// +INLINE MouseData:: +MouseData(const MouseData ©) : + _in_window(copy._in_window), + _xpos(copy._xpos), + _ypos(copy._ypos) +{ +} + +//////////////////////////////////////////////////////////////////// +// Function: MouseData::Copy Assignment Operator +// Access: Published +// Description: +//////////////////////////////////////////////////////////////////// +INLINE void MouseData:: +operator = (const MouseData ©) { + _in_window = copy._in_window; + _xpos = copy._xpos; + _ypos = copy._ypos; +} + //////////////////////////////////////////////////////////////////// // Function: MouseData::get_x // Access: Published diff --git a/panda/src/putil/mouseData.cxx b/panda/src/putil/mouseData.cxx index 5907de9f11..93c301d56e 100644 --- a/panda/src/putil/mouseData.cxx +++ b/panda/src/putil/mouseData.cxx @@ -17,15 +17,3 @@ //////////////////////////////////////////////////////////////////// #include "mouseData.h" - -//////////////////////////////////////////////////////////////////// -// Function: MouseData::Constructor -// Access: Published -// Description: -//////////////////////////////////////////////////////////////////// -MouseData:: -MouseData() { - _in_window = false; - _xpos = 0; - _ypos = 0; -} diff --git a/panda/src/putil/mouseData.h b/panda/src/putil/mouseData.h index afbe5322c0..03c278dc9e 100644 --- a/panda/src/putil/mouseData.h +++ b/panda/src/putil/mouseData.h @@ -31,7 +31,9 @@ //////////////////////////////////////////////////////////////////// class EXPCL_PANDA MouseData { PUBLISHED: - MouseData(); + INLINE MouseData(); + INLINE MouseData(const MouseData ©); + INLINE void operator = (const MouseData ©); INLINE int get_x() const; INLINE int get_y() const; diff --git a/panda/src/sgiglutdisplay/Sources.pp b/panda/src/sgiglutdisplay/Sources.pp deleted file mode 100644 index ca9fb1df81..0000000000 --- a/panda/src/sgiglutdisplay/Sources.pp +++ /dev/null @@ -1,19 +0,0 @@ -#define BUILD_DIRECTORY $[and $[HAVE_SGIGL],$[HAVE_GLUT]] - -#define OTHER_LIBS interrogatedb:c dconfig:c dtoolconfig:m \ - dtoolutil:c dtoolbase:c dtool:m - -#begin lib_target - #define TARGET sgiglutdisplay - #define LOCAL_LIBS \ - sgidisplay glutdisplay - - #define SOURCES \ - config_sgiglutdisplay.cxx config_sgiglutdisplay.h \ - sgiglutGraphicsPipe.cxx sgiglutGraphicsPipe.h - - #define INSTALL_HEADERS \ - sgiglutGraphicsPipe.h - -#end lib_target - diff --git a/panda/src/sgiglutdisplay/config_sgiglutdisplay.cxx b/panda/src/sgiglutdisplay/config_sgiglutdisplay.cxx deleted file mode 100644 index 0207034547..0000000000 --- a/panda/src/sgiglutdisplay/config_sgiglutdisplay.cxx +++ /dev/null @@ -1,31 +0,0 @@ -// Filename: config_sgiglutdisplay.cxx -// Created by: cary (07Oct99) -// -//////////////////////////////////////////////////////////////////// -// -// 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 "config_sgiglutdisplay.h" -#include "sgiglutGraphicsPipe.h" - -#include - -Configure(config_sgiglutdisplay); -NotifyCategoryDef(sgiglutdisplay, "display"); - -ConfigureFn(config_sgiglutdisplay) { - sgiglutGraphicsPipe::init_type(); - GraphicsPipe::get_factory().register_factory(sgiglutGraphicsPipe::get_class_type(), - sgiglutGraphicsPipe::make_sgiglutGraphicsPipe); -} diff --git a/panda/src/sgiglutdisplay/sgiglutGraphicsPipe.cxx b/panda/src/sgiglutdisplay/sgiglutGraphicsPipe.cxx deleted file mode 100644 index ae508a8b2b..0000000000 --- a/panda/src/sgiglutdisplay/sgiglutGraphicsPipe.cxx +++ /dev/null @@ -1,62 +0,0 @@ -// Filename: sgiglutGraphicsPipe.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 "sgiglutGraphicsPipe.h" -#include "config_sgiglutdisplay.h" - -//////////////////////////////////////////////////////////////////// -// Static variables -//////////////////////////////////////////////////////////////////// -TypeHandle sgiglutGraphicsPipe::_type_handle; - -sgiglutGraphicsPipe::sgiglutGraphicsPipe(const PipeSpecifier& spec) - : sgiGraphicsPipe(spec) {} - -//////////////////////////////////////////////////////////////////// -// Function: sgiglutGraphicsPipe::get_window_type -// Access: Public, Virtual -// Description: Returns the TypeHandle of the kind of window -// preferred by this kind of pipe. -//////////////////////////////////////////////////////////////////// -TypeHandle sgiglutGraphicsPipe:: -get_window_type() const { - return glutGraphicsWindow::get_class_type(); -} - -GraphicsPipe *sgiglutGraphicsPipe:: -make_sgiglutGraphicsPipe(const FactoryParams ¶ms) { - GraphicsPipe::PipeSpec *pipe_param; - if (!get_param_into(pipe_param, params)) { - return new sgiglutGraphicsPipe(PipeSpecifier()); - } else { - return new sgiglutGraphicsPipe(pipe_param->get_specifier()); - } -} - -TypeHandle sgiglutGraphicsPipe::get_class_type(void) { - return _type_handle; -} - -void sgiglutGraphicsPipe::init_type(void) { - sgiGraphicsPipe::init_type(); - register_type(_type_handle, "sgiglutGraphicsPipe", - sgiGraphicsPipe::get_class_type()); -} - -TypeHandle sgiglutGraphicsPipe::get_type(void) const { - return get_class_type(); -} diff --git a/panda/src/sgiglutdisplay/sgiglutGraphicsPipe.h b/panda/src/sgiglutdisplay/sgiglutGraphicsPipe.h deleted file mode 100644 index d6a77ebddd..0000000000 --- a/panda/src/sgiglutdisplay/sgiglutGraphicsPipe.h +++ /dev/null @@ -1,59 +0,0 @@ -// Filename: sgiglutGraphicsPipe.h -// 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 . -// -//////////////////////////////////////////////////////////////////// -#ifndef SGIGLUTGRAPHICSPIPE_H -#define SGIGLUTGRAPHICSPIPE_H -// -//////////////////////////////////////////////////////////////////// -// Includes -//////////////////////////////////////////////////////////////////// -#include - -#include -#include -#include - -//////////////////////////////////////////////////////////////////// -// Defines -//////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////// -// Class : sgiglutGraphicsPipe -// Description : This kind of pipe can create glut windows but -// supports the functionality of an sgi pipe with -// hardware channels -//////////////////////////////////////////////////////////////////// -class sgiglutGraphicsPipe : public sgiGraphicsPipe -{ -public: - sgiglutGraphicsPipe( const PipeSpecifier& ); - - virtual TypeHandle get_window_type() const; - -public: - static GraphicsPipe* make_sgiglutGraphicsPipe(const FactoryParams ¶ms); - - static TypeHandle get_class_type(void); - static void init_type(void); - virtual TypeHandle get_type(void) const; - virtual TypeHandle force_init_type() {init_type(); return get_class_type();} - -private: - static TypeHandle _type_handle; -}; - -#endif diff --git a/panda/src/testbed/pview.cxx b/panda/src/testbed/pview.cxx index f0f2d87b7d..5f833a9ff9 100644 --- a/panda/src/testbed/pview.cxx +++ b/panda/src/testbed/pview.cxx @@ -18,9 +18,21 @@ #include "pandaFramework.h" +PandaFramework framework; + +void +event_W(CPT_Event, void *) { + // shift-W: open a new window on the same scene. + WindowFramework *window = framework.open_window(); + if (window != (WindowFramework *)NULL) { + window->enable_keyboard(); + window->setup_trackball(); + framework.get_models().instance_to(window->get_render()); + } +} + int main(int argc, char *argv[]) { - PandaFramework framework; framework.open_framework(argc, argv); framework.set_window_title("Panda Viewer"); @@ -40,9 +52,10 @@ main(int argc, char *argv[]) { window->loop_animations(); framework.enable_default_keys(); + framework.get_event_handler().add_hook("shift-w", event_W, NULL); framework.main_loop(); + framework.report_frame_rate(nout); } - framework.report_frame_rate(nout); return (0); } diff --git a/panda/src/wdxdisplay/Sources.pp b/panda/src/wdxdisplay/Sources.pp deleted file mode 100644 index d63c765f52..0000000000 --- a/panda/src/wdxdisplay/Sources.pp +++ /dev/null @@ -1,29 +0,0 @@ -#define BUILD_DIRECTORY $[HAVE_DX] - -#define OTHER_LIBS interrogatedb:c dconfig:c dtoolconfig:m \ - dtoolutil:c dtoolbase:c dtool:m -#define WIN_SYS_LIBS Imm32.lib -#define USE_PACKAGES dx - -#begin lib_target - #define TARGET wdxdisplay - #define LOCAL_LIBS \ - dxgsg - - #define COMBINED_SOURCES $[TARGET]_composite1.cxx - - // need to install these due to external projects that link directly with libpandadx (bartop) - #define INSTALL_HEADERS \ - config_wdxdisplay.h wdxGraphicsPipe.h wdxGraphicsWindow.h - - #define INCLUDED_SOURCES \ - config_wdxdisplay.cxx wdxGraphicsPipe.cxx - - // note SOURCES shoult NOT include INCLUDED_SOURCES, that would cause a double build - // SOURCES should be headers and separately-built cxx files - // build wdxGraphicsWindow.cxx separately since its big - - #define SOURCES wdxGraphicsWindow.cxx $[INSTALL_HEADERS] - -#end lib_target - diff --git a/panda/src/wdxdisplay/config_wdxdisplay.cxx b/panda/src/wdxdisplay/config_wdxdisplay.cxx deleted file mode 100644 index e128afb7e0..0000000000 --- a/panda/src/wdxdisplay/config_wdxdisplay.cxx +++ /dev/null @@ -1,91 +0,0 @@ -// Filename: config_wdxdisplay.cxx -// Created by: mike (07Oct99) -// -//////////////////////////////////////////////////////////////////// -// -// 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 "config_wdxdisplay.h" -#include "wdxGraphicsPipe.h" -#include "wdxGraphicsWindow.h" - -#include - -Configure(config_wdxdisplay); -NotifyCategoryDef(wdxdisplay, "display"); - -ConfigureFn(config_wdxdisplay) { - init_libwdxdisplay(); -} - -bool dx_force_16bpp_zbuffer = config_wdxdisplay.GetBool("dx-force-16bpp-zbuffer", false); -bool bResponsive_minimized_fullscreen_window = config_wdxdisplay.GetBool("responsive-minimized-fullscreen-window",false); -bool dx_preserve_fpu_state = config_wdxdisplay.GetBool("dx-preserve-fpu-state", false); - -// if true, use ddraw's GetAvailVidMem to fail if driver says it has too little video mem -bool dx_do_vidmemsize_check = config_wdxdisplay.GetBool("do-vidmemsize-check", true); - -// For now, set this true to use the IME correctly on Win2000, or -// false on Win98. This is temporary; once we have been able to -// verify that this distinction is actually necessary, we can replace -// this config variable with an actual OS detection. -bool ime_composition_w = config_wdxdisplay.GetBool("ime-composition-w", true); - -extern void AtExitFn(void); - -//////////////////////////////////////////////////////////////////// -// Function: init_libwdxdisplay -// Description: Initializes the library. This must be called at -// least once before any of the functions or classes in -// this library can be used. Normally it will be -// called by the static initializers and need not be -// called explicitly, but special cases exist. -//////////////////////////////////////////////////////////////////// -void -init_libwdxdisplay() { - static bool initialized = false; - if (initialized) { - return; - } - initialized = true; - - atexit(AtExitFn); - - wdxGraphicsPipe::init_type(); - GraphicsPipe::get_factory().register_factory( - wdxGraphicsPipe::get_class_type(), - wdxGraphicsPipe::make_wdxGraphicsPipe); - wdxGraphicsWindow::init_type(); - GraphicsWindow::get_factory().register_factory( - wdxGraphicsWindow::get_class_type(), - wdxGraphicsWindow::make_wdxGraphicsWindow); - - set_global_parameters(); -} - -// cant use global var cleanly because global var static init executed after init_libwdxdisplay(), incorrectly reiniting var -Filename get_icon_filename() { - string iconname = config_wdxdisplay.GetString("win32-window-icon",""); - return ExecutionEnvironment::expand_string(iconname); -} - -Filename get_color_cursor_filename() { - string cursorname = config_wdxdisplay.GetString("win32-color-cursor",""); - return ExecutionEnvironment::expand_string(cursorname); -} - -Filename get_mono_cursor_filename() { - string cursorname = config_wdxdisplay.GetString("win32-mono-cursor",""); - return ExecutionEnvironment::expand_string(cursorname); -} diff --git a/panda/src/wdxdisplay/wdxGraphicsPipe.cxx b/panda/src/wdxdisplay/wdxGraphicsPipe.cxx deleted file mode 100644 index 824314621b..0000000000 --- a/panda/src/wdxdisplay/wdxGraphicsPipe.cxx +++ /dev/null @@ -1,1603 +0,0 @@ -// Filename: wdxGraphicsPipe.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 "wdxGraphicsPipe.h" -#include "config_wdxdisplay.h" -#include -#include -#include - -//////////////////////////////////////////////////////////////////// -// Static variables -//////////////////////////////////////////////////////////////////// -TypeHandle wdxGraphicsPipe::_type_handle; - -//wdxGraphicsPipe *global_pipe; - -wdxGraphicsPipe::wdxGraphicsPipe(const PipeSpecifier& spec) -: InteractiveGraphicsPipe(spec) { -// _width = GetSystemMetrics(SM_CXSCREEN); -// _height = GetSystemMetrics(SM_CYSCREEN); -// _shift = false; -// global_pipe = this; -} - -//////////////////////////////////////////////////////////////////// -// Function: wdxGraphicsPipe::get_window_type -// Access: Public, Virtual -// Description: Returns the TypeHandle of the kind of window -// preferred by this kind of pipe. -//////////////////////////////////////////////////////////////////// -TypeHandle wdxGraphicsPipe:: -get_window_type() const { - return wdxGraphicsWindow::get_class_type(); -} - -GraphicsPipe *wdxGraphicsPipe:: -make_wdxGraphicsPipe(const FactoryParams ¶ms) { - GraphicsPipe::PipeSpec *pipe_param; - if(!get_param_into(pipe_param, params)) { - return new wdxGraphicsPipe(PipeSpecifier()); - } else { - return new wdxGraphicsPipe(pipe_param->get_specifier()); - } -} - -TypeHandle wdxGraphicsPipe::get_class_type(void) { - return _type_handle; -} - -const char *pipe_type_name="wdxGraphicsPipe"; - -void wdxGraphicsPipe::init_type(void) { - InteractiveGraphicsPipe::init_type(); - register_type(_type_handle, pipe_type_name, - InteractiveGraphicsPipe::get_class_type()); -} - -TypeHandle wdxGraphicsPipe::get_type(void) const { - return get_class_type(); -} - -wdxGraphicsPipe::wdxGraphicsPipe(void) { - wdxdisplay_cat.error() - << pipe_type_name <<"s should not be created with the default constructor" << endl; -} - -wdxGraphicsPipe::wdxGraphicsPipe(const wdxGraphicsPipe&) { - wdxdisplay_cat.error() - << pipe_type_name << "s should not be copied" << endl; -} - -wdxGraphicsPipe& wdxGraphicsPipe::operator=(const wdxGraphicsPipe&) { - wdxdisplay_cat.error() - << pipe_type_name << "s should not be assigned" << endl; - return *this; -} - -//////////////////////////////////////////////////////////////////// -// Function: find_window -// Access: -// Description: Find the window that has the xwindow "win" in the -// window list for the pipe (if it exists) -//////////////////////////////////////////////////////////////////// -wdxGraphicsWindow *wdxGraphicsPipe:: -find_window(HWND win) { - int num_windows = get_num_windows(); - for(int w = 0; w < num_windows; w++) { - wdxGraphicsWindow *window = DCAST(wdxGraphicsWindow, get_window(w)); - if(window->_dxgsg->scrn.hWnd == win) - return window; - } - return NULL; -} - -extern char * ConvD3DErrorToString(const HRESULT &error) { - switch(error) { - case E_FAIL: - return "Unspecified error E_FAIL"; - - case DD_OK: - return "No error.\0"; - case D3DERR_BADMAJORVERSION : // (700) - return "D3DERR_BADMAJORVERSION";//: // (700) - case D3DERR_BADMINORVERSION : // (701) - return "D3DERR_BADMINORVERSION";//: // (701) - case D3DERR_INVALID_DEVICE : // (705) - return "D3DERR_INVALID_DEVICE";//: // (705) - case D3DERR_INITFAILED : // (706) - return "D3DERR_INITFAILED";//: // (706) - case D3DERR_DEVICEAGGREGATED : // (707) - return "D3DERR_DEVICEAGGREGATED";//: // (707) - case D3DERR_EXECUTE_CREATE_FAILED : // (710) - return "D3DERR_EXECUTE_CREATE_FAILED";//: // (710) - case D3DERR_EXECUTE_DESTROY_FAILED : // (711) - return "D3DERR_EXECUTE_DESTROY_FAILED";//: // (711) - case D3DERR_EXECUTE_LOCK_FAILED : // (712) - return "D3DERR_EXECUTE_LOCK_FAILED";//: // (712) - case D3DERR_EXECUTE_UNLOCK_FAILED : // (713) - return "D3DERR_EXECUTE_UNLOCK_FAILED";//: // (713) - case D3DERR_EXECUTE_LOCKED : // (714) - return "D3DERR_EXECUTE_LOCKED";//: // (714) - case D3DERR_EXECUTE_NOT_LOCKED : // (715) - return "D3DERR_EXECUTE_NOT_LOCKED";//: // (715) - case D3DERR_EXECUTE_FAILED : // (716) - return "D3DERR_EXECUTE_FAILED";//: // (716) - case D3DERR_EXECUTE_CLIPPED_FAILED : // (717) - return "D3DERR_EXECUTE_CLIPPED_FAILED";//: // (717) - case D3DERR_TEXTURE_NO_SUPPORT : // (720) - return "D3DERR_TEXTURE_NO_SUPPORT";//: // (720) - case D3DERR_TEXTURE_CREATE_FAILED : // (721) - return "D3DERR_TEXTURE_CREATE_FAILED";//: // (721) - case D3DERR_TEXTURE_DESTROY_FAILED : // (722) - return "D3DERR_TEXTURE_DESTROY_FAILED";//: // (722) - case D3DERR_TEXTURE_LOCK_FAILED : // (723) - return "D3DERR_TEXTURE_LOCK_FAILED";//: // (723) - case D3DERR_TEXTURE_UNLOCK_FAILED : // (724) - return "D3DERR_TEXTURE_UNLOCK_FAILED";//: // (724) - case D3DERR_TEXTURE_LOAD_FAILED : // (725) - return "D3DERR_TEXTURE_LOAD_FAILED";//: // (725) - case D3DERR_TEXTURE_SWAP_FAILED : // (726) - return "D3DERR_TEXTURE_SWAP_FAILED";//: // (726) - case D3DERR_TEXTURE_LOCKED : // (727) - return "D3DERR_TEXTURE_LOCKED";//: // (727) - case D3DERR_TEXTURE_NOT_LOCKED : // (728) - return "D3DERR_TEXTURE_NOT_LOCKED";//: // (728) - case D3DERR_TEXTURE_GETSURF_FAILED : // (729) - return "D3DERR_TEXTURE_GETSURF_FAILED";//: // (729) - case D3DERR_MATRIX_CREATE_FAILED : // (730) - return "D3DERR_MATRIX_CREATE_FAILED";//: // (730) - case D3DERR_MATRIX_DESTROY_FAILED : // (731) - return "D3DERR_MATRIX_DESTROY_FAILED";//: // (731) - case D3DERR_MATRIX_SETDATA_FAILED : // (732) - return "D3DERR_MATRIX_SETDATA_FAILED";//: // (732) - case D3DERR_MATRIX_GETDATA_FAILED : // (733) - return "D3DERR_MATRIX_GETDATA_FAILED";//: // (733) - case D3DERR_SETVIEWPORTDATA_FAILED : // (734) - return "D3DERR_SETVIEWPORTDATA_FAILED";//: // (734) - case D3DERR_INVALIDCURRENTVIEWPORT : // (735) - return "D3DERR_INVALIDCURRENTVIEWPORT";//: // (735) - case D3DERR_INVALIDPRIMITIVETYPE : // (736) - return "D3DERR_INVALIDPRIMITIVETYPE";//: // (736) - case D3DERR_INVALIDVERTEXTYPE : // (737) - return "D3DERR_INVALIDVERTEXTYPE";//: // (737) - case D3DERR_TEXTURE_BADSIZE : // (738) - return "D3DERR_TEXTURE_BADSIZE";//: // (738) - case D3DERR_INVALIDRAMPTEXTURE : // (739) - return "D3DERR_INVALIDRAMPTEXTURE";//: // (739) - case D3DERR_MATERIAL_CREATE_FAILED : // (740) - return "D3DERR_MATERIAL_CREATE_FAILED";//: // (740) - case D3DERR_MATERIAL_DESTROY_FAILED : // (741) - return "D3DERR_MATERIAL_DESTROY_FAILED";//: // (741) - case D3DERR_MATERIAL_SETDATA_FAILED : // (742) - return "D3DERR_MATERIAL_SETDATA_FAILED";//: // (742) - case D3DERR_MATERIAL_GETDATA_FAILED : // (743) - return "D3DERR_MATERIAL_GETDATA_FAILED";//: // (743) - case D3DERR_INVALIDPALETTE : // (744) - return "D3DERR_INVALIDPALETTE";//: // (744) - case D3DERR_ZBUFF_NEEDS_SYSTEMMEMORY : // (745) - return "D3DERR_ZBUFF_NEEDS_SYSTEMMEMORY";//: // (745) - case D3DERR_ZBUFF_NEEDS_VIDEOMEMORY : // (746) - return "D3DERR_ZBUFF_NEEDS_VIDEOMEMORY";//: // (746) - case D3DERR_SURFACENOTINVIDMEM : // (747) - return "D3DERR_SURFACENOTINVIDMEM";//: // (747) - case D3DERR_LIGHT_SET_FAILED : // (750) - return "D3DERR_LIGHT_SET_FAILED";//: // (750) - case D3DERR_LIGHTHASVIEWPORT : // (751) - return "D3DERR_LIGHTHASVIEWPORT";//: // (751) - case D3DERR_LIGHTNOTINTHISVIEWPORT : // (752) - return "D3DERR_LIGHTNOTINTHISVIEWPORT";//: // (752) - case D3DERR_SCENE_IN_SCENE : // (760) - return "D3DERR_SCENE_IN_SCENE";//: // (760) - case D3DERR_SCENE_NOT_IN_SCENE : // (761) - return "D3DERR_SCENE_NOT_IN_SCENE";//: // (761) - case D3DERR_SCENE_BEGIN_FAILED : // (762) - return "D3DERR_SCENE_BEGIN_FAILED";//: // (762) - case D3DERR_SCENE_END_FAILED : // (763) - return "D3DERR_SCENE_END_FAILED";//: // (763) - case D3DERR_INBEGIN : // (770) - return "D3DERR_INBEGIN";//: // (770) - case D3DERR_NOTINBEGIN : // (771) - return "D3DERR_NOTINBEGIN";//: // (771) - case D3DERR_NOVIEWPORTS : // (772) - return "D3DERR_NOVIEWPORTS";//: // (772) - case D3DERR_VIEWPORTDATANOTSET : // (773) - return "D3DERR_VIEWPORTDATANOTSET";//: // (773) - case D3DERR_VIEWPORTHASNODEVICE : // (774) - return "D3DERR_VIEWPORTHASNODEVICE";//: // (774) - case D3DERR_NOCURRENTVIEWPORT : // (775) - return "D3DERR_NOCURRENTVIEWPORT";//: // (775) - case D3DERR_INVALIDVERTEXFORMAT : // (2048) - return "D3DERR_INVALIDVERTEXFORMAT";//: // (2048) - case D3DERR_COLORKEYATTACHED : // (2050) - return "D3DERR_COLORKEYATTACHED";//: // (2050) - case D3DERR_VERTEXBUFFEROPTIMIZED : // (2060) - return "D3DERR_VERTEXBUFFEROPTIMIZED";//: // (2060) - case D3DERR_VBUF_CREATE_FAILED : // (2061) - return "D3DERR_VBUF_CREATE_FAILED";//: // (2061) - case D3DERR_VERTEXBUFFERLOCKED : // (2062) - return "D3DERR_VERTEXBUFFERLOCKED";//: // (2062) - case D3DERR_ZBUFFER_NOTPRESENT : // (2070) - return "D3DERR_ZBUFFER_NOTPRESENT";//: // (2070) - case D3DERR_STENCILBUFFER_NOTPRESENT : // (2071) - return "D3DERR_STENCILBUFFER_NOTPRESENT";//: // (2071) - case D3DERR_WRONGTEXTUREFORMAT : // (2072) - return "D3DERR_WRONGTEXTUREFORMAT";//: // (2072) - case D3DERR_UNSUPPORTEDCOLOROPERATION : // (2073) - return "D3DERR_UNSUPPORTEDCOLOROPERATION";//: // (2073) - case D3DERR_UNSUPPORTEDCOLORARG : // (2074) - return "D3DERR_UNSUPPORTEDCOLORARG";//: // (2074) - case D3DERR_UNSUPPORTEDALPHAOPERATION : // (2075) - return "D3DERR_UNSUPPORTEDALPHAOPERATION";//: // (2075) - case D3DERR_UNSUPPORTEDALPHAARG : // (2076) - return "D3DERR_UNSUPPORTEDALPHAARG";//: // (2076) - case D3DERR_TOOMANYOPERATIONS : // (2077) - return "D3DERR_TOOMANYOPERATIONS";//: // (2077) - case D3DERR_CONFLICTINGTEXTUREFILTER : // (2078) - return "D3DERR_CONFLICTINGTEXTUREFILTER";//: // (2078) - case D3DERR_UNSUPPORTEDFACTORVALUE : // (2079) - return "D3DERR_UNSUPPORTEDFACTORVALUE";//: // (2079) - case D3DERR_CONFLICTINGRENDERSTATE : // (2081) - return "D3DERR_CONFLICTINGRENDERSTATE";//: // (2081) - case D3DERR_UNSUPPORTEDTEXTUREFILTER : // (2082) - return "D3DERR_UNSUPPORTEDTEXTUREFILTER";//: // (2082) - case D3DERR_TOOMANYPRIMITIVES : // (2083) - return "D3DERR_TOOMANYPRIMITIVES";//: // (2083) - case D3DERR_INVALIDMATRIX : // (2084) - return "D3DERR_INVALIDMATRIX";//: // (2084) - case D3DERR_TOOMANYVERTICES : // (2085) - return "D3DERR_TOOMANYVERTICES";//: // (2085) - case D3DERR_CONFLICTINGTEXTUREPALETTE : // (2086) - return "D3DERR_CONFLICTINGTEXTUREPALETTE";//: // (2086) -//#if DX7 - case D3DERR_VERTEXBUFFERUNLOCKFAILED : // (2063) - return "D3DERR_VERTEXBUFFERUNLOCKFAILED";//: // (2063) - case D3DERR_INVALIDSTATEBLOCK : // (2100) - return "D3DERR_INVALIDSTATEBLOCK";//: // (2100) - case D3DERR_INBEGINSTATEBLOCK : // (2101) - return "D3DERR_INBEGINSTATEBLOCK";//: // (2101) - case D3DERR_NOTINBEGINSTATEBLOCK : // (2102) - return "D3DERR_NOTINBEGINSTATEBLOCK";//: // (2102) - //case D3DERR_INOVERLAYSTATEBLOCK : // (2103) - // return "D3DERR_INOVERLAYSTATEBLOCK";//: // (2103) - case DDERR_NOSTEREOHARDWARE : // ( 181 ) - return "DDERR_NOSTEREOHARDWARE ";//: // ( 181 ) - case DDERR_NOSURFACELEFT : // ( 182 ) - return "DDERR_NOSURFACELEFT ";//: // ( 182 ) - case DDERR_DDSCAPSCOMPLEXREQUIRED : // ( 542 ) - return "DDERR_DDSCAPSCOMPLEXREQUIRED";//: // ( 542 ) - case DDERR_NOTONMIPMAPSUBLEVEL : // ( 603 ) - return "DDERR_NOTONMIPMAPSUBLEVEL";//: // ( 603 ) - case DDERR_TESTFINISHED : // ( 692 ) - return "DDERR_TESTFINISHED";//: // ( 692 ) - case DDERR_NEWMODE : // ( 693 ) - return "DDERR_NEWMODE";//: // ( 693 ) -//#endif - //case D3DERR_COMMAND_UNPARSED : // (3000) - /// return "case";//D3DERR_COMMAND_UNPARSED : // (3000) - - case DDERR_ALREADYINITIALIZED : // ( 5 ) - return "DDERR_ALREADYINITIALIZED ";//: // ( 5 ) - case DDERR_CANNOTATTACHSURFACE : // ( 10 ) - return "DDERR_CANNOTATTACHSURFACE ";//: // ( 10 ) - case DDERR_CANNOTDETACHSURFACE : // ( 20 ) - return "DDERR_CANNOTDETACHSURFACE ";//: // ( 20 ) - case DDERR_CURRENTLYNOTAVAIL : // ( 40 ) - return "DDERR_CURRENTLYNOTAVAIL ";//: // ( 40 ) - case DDERR_EXCEPTION : // ( 55 ) - return "DDERR_EXCEPTION ";//: // ( 55 ) - case DDERR_HEIGHTALIGN : // ( 90 ) - return "DDERR_HEIGHTALIGN ";//: // ( 90 ) - case DDERR_INCOMPATIBLEPRIMARY : // ( 95 ) - return "DDERR_INCOMPATIBLEPRIMARY ";//: // ( 95 ) - case DDERR_INVALIDCAPS : // ( 100 ) - return "DDERR_INVALIDCAPS ";//: // ( 100 ) - case DDERR_INVALIDCLIPLIST : // ( 110 ) - return "DDERR_INVALIDCLIPLIST ";//: // ( 110 ) - case DDERR_INVALIDMODE : // ( 120 ) - return "DDERR_INVALIDMODE ";//: // ( 120 ) - case DDERR_INVALIDOBJECT : // ( 130 ) - return "DDERR_INVALIDOBJECT ";//: // ( 130 ) - case DDERR_INVALIDPIXELFORMAT : // ( 145 ) - return "DDERR_INVALIDPIXELFORMAT ";//: // ( 145 ) - case DDERR_INVALIDRECT : // ( 150 ) - return "DDERR_INVALIDRECT ";//: // ( 150 ) - case DDERR_LOCKEDSURFACES : // ( 160 ) - return "DDERR_LOCKEDSURFACES ";//: // ( 160 ) - case DDERR_NO3D : // ( 170 ) - return "DDERR_NO3D ";//: // ( 170 ) - case DDERR_NOALPHAHW : // ( 180 ) - return "DDERR_NOALPHAHW ";//: // ( 180 ) - case DDERR_NOCLIPLIST : // ( 205 ) - return "DDERR_NOCLIPLIST ";//: // ( 205 ) - case DDERR_NOCOLORCONVHW : // ( 210 ) - return "DDERR_NOCOLORCONVHW ";//: // ( 210 ) - case DDERR_NOCOOPERATIVELEVELSET : // ( 212 ) - return "DDERR_NOCOOPERATIVELEVELSET ";//: // ( 212 ) - case DDERR_NOCOLORKEY : // ( 215 ) - return "DDERR_NOCOLORKEY ";//: // ( 215 ) - case DDERR_NOCOLORKEYHW : // ( 220 ) - return "DDERR_NOCOLORKEYHW ";//: // ( 220 ) - case DDERR_NODIRECTDRAWSUPPORT : // ( 222 ) - return "DDERR_NODIRECTDRAWSUPPORT ";//: // ( 222 ) - case DDERR_NOEXCLUSIVEMODE : // ( 225 ) - return "DDERR_NOEXCLUSIVEMODE ";//: // ( 225 ) - case DDERR_NOFLIPHW : // ( 230 ) - return "DDERR_NOFLIPHW ";//: // ( 230 ) - case DDERR_NOGDI : // ( 240 ) - return "DDERR_NOGDI ";//: // ( 240 ) - case DDERR_NOMIRRORHW : // ( 250 ) - return "DDERR_NOMIRRORHW ";//: // ( 250 ) - case DDERR_NOTFOUND : // ( 255 ) - return "DDERR_NOTFOUND ";//: // ( 255 ) - case DDERR_NOOVERLAYHW : // ( 260 ) - return "DDERR_NOOVERLAYHW ";//: // ( 260 ) - case DDERR_OVERLAPPINGRECTS : // ( 270 ) - return "DDERR_OVERLAPPINGRECTS ";//: // ( 270 ) - case DDERR_NORASTEROPHW : // ( 280 ) - return "DDERR_NORASTEROPHW ";//: // ( 280 ) - case DDERR_NOROTATIONHW : // ( 290 ) - return "DDERR_NOROTATIONHW ";//: // ( 290 ) - case DDERR_NOSTRETCHHW : // ( 310 ) - return "DDERR_NOSTRETCHHW ";//: // ( 310 ) - case DDERR_NOT4BITCOLOR : // ( 316 ) - return "DDERR_NOT4BITCOLOR ";//: // ( 316 ) - case DDERR_NOT4BITCOLORINDEX : // ( 317 ) - return "DDERR_NOT4BITCOLORINDEX ";//: // ( 317 ) - case DDERR_NOT8BITCOLOR : // ( 320 ) - return "DDERR_NOT8BITCOLOR ";//: // ( 320 ) - case DDERR_NOTEXTUREHW : // ( 330 ) - return "DDERR_NOTEXTUREHW ";//: // ( 330 ) - case DDERR_NOVSYNCHW : // ( 335 ) - return "DDERR_NOVSYNCHW ";//: // ( 335 ) - case DDERR_NOZBUFFERHW : // ( 340 ) - return "DDERR_NOZBUFFERHW ";//: // ( 340 ) - case DDERR_NOZOVERLAYHW : // ( 350 ) - return "DDERR_NOZOVERLAYHW ";//: // ( 350 ) - case DDERR_OUTOFCAPS : // ( 360 ) - return "DDERR_OUTOFCAPS ";//: // ( 360 ) - case DDERR_OUTOFVIDEOMEMORY : // ( 380 ) - return "DDERR_OUTOFVIDEOMEMORY ";//: // ( 380 ) - case DDERR_OVERLAYCANTCLIP : // ( 382 ) - return "DDERR_OVERLAYCANTCLIP ";//: // ( 382 ) - case DDERR_OVERLAYCOLORKEYONLYONEACTIVE : // ( 384 ) - return "DDERR_OVERLAYCOLORKEYONLYONEACTIVE ";//: // ( 384 ) - case DDERR_PALETTEBUSY : // ( 387 ) - return "DDERR_PALETTEBUSY ";//: // ( 387 ) - case DDERR_COLORKEYNOTSET : // ( 400 ) - return "DDERR_COLORKEYNOTSET ";//: // ( 400 ) - case DDERR_SURFACEALREADYATTACHED : // ( 410 ) - return "DDERR_SURFACEALREADYATTACHED ";//: // ( 410 ) - case DDERR_SURFACEALREADYDEPENDENT : // ( 420 ) - return "DDERR_SURFACEALREADYDEPENDENT ";//: // ( 420 ) - case DDERR_SURFACEBUSY : // ( 430 ) - return "DDERR_SURFACEBUSY ";//: // ( 430 ) - case DDERR_CANTLOCKSURFACE : // ( 435 ) - return "DDERR_CANTLOCKSURFACE";//: // ( 435 ) - case DDERR_SURFACEISOBSCURED : // ( 440 ) - return "DDERR_SURFACEISOBSCURED ";//: // ( 440 ) - case DDERR_SURFACELOST : // ( 450 ) - return "DDERR_SURFACELOST ";//: // ( 450 ) - case DDERR_SURFACENOTATTACHED : // ( 460 ) - return "DDERR_SURFACENOTATTACHED ";//: // ( 460 ) - case DDERR_TOOBIGHEIGHT : // ( 470 ) - return "DDERR_TOOBIGHEIGHT ";//: // ( 470 ) - case DDERR_TOOBIGSIZE : // ( 480 ) - return "DDERR_TOOBIGSIZE ";//: // ( 480 ) - case DDERR_TOOBIGWIDTH : // ( 490 ) - return "DDERR_TOOBIGWIDTH ";//: // ( 490 ) - case DDERR_UNSUPPORTEDFORMAT : // ( 510 ) - return "DDERR_UNSUPPORTEDFORMAT ";//: // ( 510 ) - case DDERR_UNSUPPORTEDMASK : // ( 520 ) - return "DDERR_UNSUPPORTEDMASK ";//: // ( 520 ) - case DDERR_INVALIDSTREAM : // ( 521 ) - return "DDERR_INVALIDSTREAM";//: // ( 521 ) - case DDERR_VERTICALBLANKINPROGRESS : // ( 537 ) - return "DDERR_VERTICALBLANKINPROGRESS ";//: // ( 537 ) - case DDERR_WASSTILLDRAWING : // ( 540 ) - return "DDERR_WASSTILLDRAWING ";//: // ( 540 ) - case DDERR_XALIGN : // ( 560 ) - return "DDERR_XALIGN ";//: // ( 560 ) - case DDERR_INVALIDDIRECTDRAWGUID : // ( 561 ) - return "DDERR_INVALIDDIRECTDRAWGUID ";//: // ( 561 ) - case DDERR_DIRECTDRAWALREADYCREATED : // ( 562 ) - return "DDERR_DIRECTDRAWALREADYCREATED ";//: // ( 562 ) - case DDERR_NODIRECTDRAWHW : // ( 563 ) - return "DDERR_NODIRECTDRAWHW ";//: // ( 563 ) - case DDERR_PRIMARYSURFACEALREADYEXISTS : // ( 564 ) - return "DDERR_PRIMARYSURFACEALREADYEXISTS ";//: // ( 564 ) - case DDERR_NOEMULATION : // ( 565 ) - return "DDERR_NOEMULATION ";//: // ( 565 ) - case DDERR_REGIONTOOSMALL : // ( 566 ) - return "DDERR_REGIONTOOSMALL ";//: // ( 566 ) - case DDERR_CLIPPERISUSINGHWND : // ( 567 ) - return "DDERR_CLIPPERISUSINGHWND ";//: // ( 567 ) - case DDERR_NOCLIPPERATTACHED : // ( 568 ) - return "DDERR_NOCLIPPERATTACHED ";//: // ( 568 ) - case DDERR_NOHWND : // ( 569 ) - return "DDERR_NOHWND ";//: // ( 569 ) - case DDERR_HWNDSUBCLASSED : // ( 570 ) - return "DDERR_HWNDSUBCLASSED ";//: // ( 570 ) - case DDERR_HWNDALREADYSET : // ( 571 ) - return "DDERR_HWNDALREADYSET ";//: // ( 571 ) - case DDERR_NOPALETTEATTACHED : // ( 572 ) - return "DDERR_NOPALETTEATTACHED ";//: // ( 572 ) - case DDERR_NOPALETTEHW : // ( 573 ) - return "DDERR_NOPALETTEHW ";//: // ( 573 ) - case DDERR_BLTFASTCANTCLIP : // ( 574 ) - return "DDERR_BLTFASTCANTCLIP ";//: // ( 574 ) - case DDERR_NOBLTHW : // ( 575 ) - return "DDERR_NOBLTHW ";//: // ( 575 ) - case DDERR_NODDROPSHW : // ( 576 ) - return "DDERR_NODDROPSHW ";//: // ( 576 ) - case DDERR_OVERLAYNOTVISIBLE : // ( 577 ) - return "DDERR_OVERLAYNOTVISIBLE ";//: // ( 577 ) - case DDERR_NOOVERLAYDEST : // ( 578 ) - return "DDERR_NOOVERLAYDEST ";//: // ( 578 ) - case DDERR_INVALIDPOSITION : // ( 579 ) - return "DDERR_INVALIDPOSITION ";//: // ( 579 ) - case DDERR_NOTAOVERLAYSURFACE : // ( 580 ) - return "DDERR_NOTAOVERLAYSURFACE ";//: // ( 580 ) - case DDERR_EXCLUSIVEMODEALREADYSET : // ( 581 ) - return "DDERR_EXCLUSIVEMODEALREADYSET ";//: // ( 581 ) - case DDERR_NOTFLIPPABLE : // ( 582 ) - return "DDERR_NOTFLIPPABLE ";//: // ( 582 ) - case DDERR_CANTDUPLICATE : // ( 583 ) - return "DDERR_CANTDUPLICATE ";//: // ( 583 ) - case DDERR_NOTLOCKED : // ( 584 ) - return "DDERR_NOTLOCKED ";//: // ( 584 ) - case DDERR_CANTCREATEDC : // ( 585 ) - return "DDERR_CANTCREATEDC ";//: // ( 585 ) - case DDERR_NODC : // ( 586 ) - return "DDERR_NODC ";//: // ( 586 ) - case DDERR_WRONGMODE : // ( 587 ) - return "DDERR_WRONGMODE ";//: // ( 587 ) - case DDERR_IMPLICITLYCREATED : // ( 588 ) - return "DDERR_IMPLICITLYCREATED ";//: // ( 588 ) - case DDERR_NOTPALETTIZED : // ( 589 ) - return "DDERR_NOTPALETTIZED ";//: // ( 589 ) - case DDERR_UNSUPPORTEDMODE : // ( 590 ) - return "DDERR_UNSUPPORTEDMODE ";//: // ( 590 ) - case DDERR_NOMIPMAPHW : // ( 591 ) - return "DDERR_NOMIPMAPHW ";//: // ( 591 ) - case DDERR_INVALIDSURFACETYPE : // ( 592 ) - return "DDERR_INVALIDSURFACETYPE";//: // ( 592 ) - case DDERR_NOOPTIMIZEHW : // ( 600 ) - return "DDERR_NOOPTIMIZEHW";//: // ( 600 ) - case DDERR_NOTLOADED : // ( 601 ) - return "DDERR_NOTLOADED";//: // ( 601 ) - case DDERR_NOFOCUSWINDOW : // ( 602 ) - return "DDERR_NOFOCUSWINDOW";//: // ( 602 ) - case DDERR_DCALREADYCREATED : // ( 620 ) - return "DDERR_DCALREADYCREATED ";//: // ( 620 ) - case DDERR_NONONLOCALVIDMEM : // ( 630 ) - return "DDERR_NONONLOCALVIDMEM";//: // ( 630 ) - case DDERR_CANTPAGELOCK : // ( 640 ) - return "DDERR_CANTPAGELOCK ";//: // ( 640 ) - case DDERR_CANTPAGEUNLOCK : // ( 660 ) - return "DDERR_CANTPAGEUNLOCK ";//: // ( 660 ) - case DDERR_NOTPAGELOCKED : // ( 680 ) - return "DDERR_NOTPAGELOCKED ";//: // ( 680 ) - case DDERR_MOREDATA : // ( 690 ) - return "DDERR_MOREDATA ";//: // ( 690 ) - case DDERR_EXPIRED : // ( 691 ) - return "DDERR_EXPIRED";//: // ( 691 ) - case DDERR_VIDEONOTACTIVE : // ( 695 ) - return "DDERR_VIDEONOTACTIVE ";//: // ( 695 ) - case DDERR_DEVICEDOESNTOWNSURFACE : // ( 699 ) - return "DDERR_DEVICEDOESNTOWNSURFACE ";//: // ( 699 ) - case DXFILEERR_BADOBJECT : // (850) - return "DXFILEERR_BADOBJECT";//: // (850) - case DXFILEERR_BADVALUE : // (851) - return "DXFILEERR_BADVALUE";//: // (851) - case DXFILEERR_BADTYPE : // (852) - return "DXFILEERR_BADTYPE";//: // (852) - case DXFILEERR_BADSTREAMHANDLE : // (853) - return "DXFILEERR_BADSTREAMHANDLE";//: // (853) - case DXFILEERR_BADALLOC : // (854) - return "DXFILEERR_BADALLOC";//: // (854) - case DXFILEERR_NOTFOUND : // (855) - return "DXFILEERR_NOTFOUND";//: // (855) - case DXFILEERR_NOTDONEYET : // (856) - return "DXFILEERR_NOTDONEYET";//: // (856) - case DXFILEERR_FILENOTFOUND : // (857) - return "DXFILEERR_FILENOTFOUND";//: // (857) - case DXFILEERR_RESOURCENOTFOUND : // (858) - return "DXFILEERR_RESOURCENOTFOUND";//: // (858) - case DXFILEERR_URLNOTFOUND : // (859) - return "DXFILEERR_URLNOTFOUND";//: // (859) - case DXFILEERR_BADRESOURCE : // (860) - return "DXFILEERR_BADRESOURCE";//: // (860) - case DXFILEERR_BADFILETYPE : // (861) - return "DXFILEERR_BADFILETYPE";//: // (861) - case DXFILEERR_BADFILEVERSION : // (862) - return "DXFILEERR_BADFILEVERSION";//: // (862) - case DXFILEERR_BADFILEFLOATSIZE : // (863) - return "DXFILEERR_BADFILEFLOATSIZE";//: // (863) - case DXFILEERR_BADFILECOMPRESSIONTYPE : // (864) - return "DXFILEERR_BADFILECOMPRESSIONTYPE";//: // (864) - case DXFILEERR_BADFILE : // (865) - return "DXFILEERR_BADFILE";//: // (865) - case DXFILEERR_PARSEERROR : // (866) - return "DXFILEERR_PARSEERROR";//: // (866) - case DXFILEERR_NOTEMPLATE : // (867) - return "DXFILEERR_NOTEMPLATE";//: // (867) - case DXFILEERR_BADARRAYSIZE : // (868) - return "DXFILEERR_BADARRAYSIZE";//: // (868) - case DXFILEERR_BADDATAREFERENCE : // (869) - return "DXFILEERR_BADDATAREFERENCE";//: // (869) - case DXFILEERR_INTERNALERROR : // (870) - return "DXFILEERR_INTERNALERROR";//: // (870) - case DXFILEERR_NOMOREOBJECTS : // (871) - return "DXFILEERR_NOMOREOBJECTS";//: // (871) - case DXFILEERR_BADINTRINSICS : // (872) - return "DXFILEERR_BADINTRINSICS";//: // (872) - case DXFILEERR_NOMORESTREAMHANDLES : // (873) - return "DXFILEERR_NOMORESTREAMHANDLES";//: // (873) - case DXFILEERR_NOMOREDATA : // (874) - return "DXFILEERR_NOMOREDATA";//: // (874) - case DXFILEERR_BADCACHEFILE : // (875) - return "DXFILEERR_BADCACHEFILE";//: // (875) - case DXFILEERR_NOINTERNET : // (876) - return "DXFILEERR_NOINTERNET";//: // (876) - - case E_UNEXPECTED : - return "E_UNEXPECTED "; - case E_NOTIMPL : - return "E_NOTIMPL "; - case E_OUTOFMEMORY : - return "E_OUTOFMEMORY "; - case E_INVALIDARG : - return "E_INVALIDARG or DDERR_INVALIDPARAMS"; - case E_NOINTERFACE : - return "E_NOINTERFACE "; - case E_POINTER : - return "E_POINTER "; - case E_HANDLE : - return "E_HANDLE "; - case E_ABORT : - return "E_ABORT "; -// case E_FAIL : -// return "E_FAIL "; - case E_ACCESSDENIED : - return "E_ACCESSDENIED "; - case E_PENDING : - return "E_PENDING "; - case CO_E_INIT_TLS : - return "CO_E_INIT_TLS "; - case CO_E_INIT_SHARED_ALLOCATOR : - return "CO_E_INIT_SHARED_ALLOCATOR "; - case CO_E_INIT_MEMORY_ALLOCATOR : - return "CO_E_INIT_MEMORY_ALLOCATOR "; - case CO_E_INIT_CLASS_CACHE : - return "CO_E_INIT_CLASS_CACHE "; - case CO_E_INIT_RPC_CHANNEL : - return "CO_E_INIT_RPC_CHANNEL "; - case CO_E_INIT_TLS_SET_CHANNEL_CONTROL : - return "CO_E_INIT_TLS_SET_CHANNEL_CONTROL "; - case CO_E_INIT_TLS_CHANNEL_CONTROL : - return "CO_E_INIT_TLS_CHANNEL_CONTROL "; - case CO_E_INIT_UNACCEPTED_USER_ALLOCATOR : - return "CO_E_INIT_UNACCEPTED_USER_ALLOCATOR "; - case CO_E_INIT_SCM_MUTEX_EXISTS : - return "CO_E_INIT_SCM_MUTEX_EXISTS "; - case CO_E_INIT_SCM_FILE_MAPPING_EXISTS : - return "CO_E_INIT_SCM_FILE_MAPPING_EXISTS "; - case CO_E_INIT_SCM_MAP_VIEW_OF_FILE : - return "CO_E_INIT_SCM_MAP_VIEW_OF_FILE "; - case CO_E_INIT_SCM_EXEC_FAILURE : - return "CO_E_INIT_SCM_EXEC_FAILURE "; - case CO_E_INIT_ONLY_SINGLE_THREADED : - return "CO_E_INIT_ONLY_SINGLE_THREADED "; - case CO_E_CANT_REMOTE : - return "CO_E_CANT_REMOTE "; - case CO_E_BAD_SERVER_NAME : - return "CO_E_BAD_SERVER_NAME "; - case CO_E_WRONG_SERVER_IDENTITY : - return "CO_E_WRONG_SERVER_IDENTITY "; - case CO_E_OLE1DDE_DISABLED : - return "CO_E_OLE1DDE_DISABLED "; - case CO_E_RUNAS_SYNTAX : - return "CO_E_RUNAS_SYNTAX "; - case CO_E_CREATEPROCESS_FAILURE : - return "CO_E_CREATEPROCESS_FAILURE "; - case CO_E_RUNAS_CREATEPROCESS_FAILURE : - return "CO_E_RUNAS_CREATEPROCESS_FAILURE "; - case CO_E_RUNAS_LOGON_FAILURE : - return "CO_E_RUNAS_LOGON_FAILURE "; - case CO_E_LAUNCH_PERMSSION_DENIED : - return "CO_E_LAUNCH_PERMSSION_DENIED "; - case CO_E_START_SERVICE_FAILURE : - return "CO_E_START_SERVICE_FAILURE "; - case CO_E_REMOTE_COMMUNICATION_FAILURE : - return "CO_E_REMOTE_COMMUNICATION_FAILURE "; - case CO_E_SERVER_START_TIMEOUT : - return "CO_E_SERVER_START_TIMEOUT "; - case CO_E_CLSREG_INCONSISTENT : - return "CO_E_CLSREG_INCONSISTENT "; - case CO_E_IIDREG_INCONSISTENT : - return "CO_E_IIDREG_INCONSISTENT "; - case CO_E_NOT_SUPPORTED : - return "CO_E_NOT_SUPPORTED "; - case CO_E_RELOAD_DLL : - return "CO_E_RELOAD_DLL "; - case CO_E_MSI_ERROR : - return "CO_E_MSI_ERROR "; - case OLE_E_OLEVERB : - return "OLE_E_OLEVERB "; - case OLE_E_ADVF : - return "OLE_E_ADVF "; - case OLE_E_ENUM_NOMORE : - return "OLE_E_ENUM_NOMORE "; - case OLE_E_ADVISENOTSUPPORTED : - return "OLE_E_ADVISENOTSUPPORTED "; - case OLE_E_NOCONNECTION : - return "OLE_E_NOCONNECTION "; - case OLE_E_NOTRUNNING : - return "OLE_E_NOTRUNNING "; - case OLE_E_NOCACHE : - return "OLE_E_NOCACHE "; - case OLE_E_BLANK : - return "OLE_E_BLANK "; - case OLE_E_CLASSDIFF : - return "OLE_E_CLASSDIFF "; - case OLE_E_CANT_GETMONIKER : - return "OLE_E_CANT_GETMONIKER "; - case OLE_E_CANT_BINDTOSOURCE : - return "OLE_E_CANT_BINDTOSOURCE "; - case OLE_E_STATIC : - return "OLE_E_STATIC "; - case OLE_E_PROMPTSAVECANCELLED : - return "OLE_E_PROMPTSAVECANCELLED "; - case OLE_E_INVALIDRECT : - return "OLE_E_INVALIDRECT "; - case OLE_E_WRONGCOMPOBJ : - return "OLE_E_WRONGCOMPOBJ "; - case OLE_E_INVALIDHWND : - return "OLE_E_INVALIDHWND "; - case OLE_E_NOT_INPLACEACTIVE : - return "OLE_E_NOT_INPLACEACTIVE "; - case OLE_E_CANTCONVERT : - return "OLE_E_CANTCONVERT "; - case OLE_E_NOSTORAGE : - return "OLE_E_NOSTORAGE "; - case DV_E_FORMATETC : - return "DV_E_FORMATETC "; - case DV_E_DVTARGETDEVICE : - return "DV_E_DVTARGETDEVICE "; - case DV_E_STGMEDIUM : - return "DV_E_STGMEDIUM "; - case DV_E_STATDATA : - return "DV_E_STATDATA "; - case DV_E_LINDEX : - return "DV_E_LINDEX "; - case DV_E_TYMED : - return "DV_E_TYMED "; - case DV_E_CLIPFORMAT : - return "DV_E_CLIPFORMAT "; - case DV_E_DVASPECT : - return "DV_E_DVASPECT "; - case DV_E_DVTARGETDEVICE_SIZE : - return "DV_E_DVTARGETDEVICE_SIZE "; - case DV_E_NOIVIEWOBJECT : - return "DV_E_NOIVIEWOBJECT "; - case DRAGDROP_E_NOTREGISTERED : - return "DRAGDROP_E_NOTREGISTERED "; - case DRAGDROP_E_ALREADYREGISTERED : - return "DRAGDROP_E_ALREADYREGISTERED "; - case DRAGDROP_E_INVALIDHWND : - return "DRAGDROP_E_INVALIDHWND "; - case CLASS_E_NOAGGREGATION : - return "CLASS_E_NOAGGREGATION "; - case CLASS_E_CLASSNOTAVAILABLE : - return "CLASS_E_CLASSNOTAVAILABLE "; - case CLASS_E_NOTLICENSED : - return "CLASS_E_NOTLICENSED "; - case VIEW_E_DRAW : - return "VIEW_E_DRAW "; - case REGDB_E_READREGDB : - return "REGDB_E_READREGDB "; - case REGDB_E_WRITEREGDB : - return "REGDB_E_WRITEREGDB "; - case REGDB_E_KEYMISSING : - return "REGDB_E_KEYMISSING "; - case REGDB_E_INVALIDVALUE : - return "REGDB_E_INVALIDVALUE "; - case REGDB_E_CLASSNOTREG : - return "REGDB_E_CLASSNOTREG "; - case REGDB_E_IIDNOTREG : - return "REGDB_E_IIDNOTREG "; - case CAT_E_CATIDNOEXIST : - return "CAT_E_CATIDNOEXIST "; - case CAT_E_NODESCRIPTION : - return "CAT_E_NODESCRIPTION "; - case CS_E_PACKAGE_NOTFOUND : - return "CS_E_PACKAGE_NOTFOUND "; - case CS_E_NOT_DELETABLE : - return "CS_E_NOT_DELETABLE "; - case CS_E_CLASS_NOTFOUND : - return "CS_E_CLASS_NOTFOUND "; - case CS_E_INVALID_VERSION : - return "CS_E_INVALID_VERSION "; - case CS_E_NO_CLASSSTORE : - return "CS_E_NO_CLASSSTORE "; - case CACHE_E_NOCACHE_UPDATED : - return "CACHE_E_NOCACHE_UPDATED "; - case OLEOBJ_E_NOVERBS : - return "OLEOBJ_E_NOVERBS "; - case OLEOBJ_E_INVALIDVERB : - return "OLEOBJ_E_INVALIDVERB "; - case INPLACE_E_NOTUNDOABLE : - return "INPLACE_E_NOTUNDOABLE "; - case INPLACE_E_NOTOOLSPACE : - return "INPLACE_E_NOTOOLSPACE "; - case CONVERT10_E_OLESTREAM_GET : - return "CONVERT10_E_OLESTREAM_GET "; - case CONVERT10_E_OLESTREAM_PUT : - return "CONVERT10_E_OLESTREAM_PUT "; - case CONVERT10_E_OLESTREAM_FMT : - return "CONVERT10_E_OLESTREAM_FMT "; - case CONVERT10_E_OLESTREAM_BITMAP_TO_DIB : - return "CONVERT10_E_OLESTREAM_BITMAP_TO_DIB "; - case CONVERT10_E_STG_FMT : - return "CONVERT10_E_STG_FMT "; - case CONVERT10_E_STG_NO_STD_STREAM : - return "CONVERT10_E_STG_NO_STD_STREAM "; - case CONVERT10_E_STG_DIB_TO_BITMAP : - return "CONVERT10_E_STG_DIB_TO_BITMAP "; - case CLIPBRD_E_CANT_OPEN : - return "CLIPBRD_E_CANT_OPEN "; - case CLIPBRD_E_CANT_EMPTY : - return "CLIPBRD_E_CANT_EMPTY "; - case CLIPBRD_E_CANT_SET : - return "CLIPBRD_E_CANT_SET "; - case CLIPBRD_E_BAD_DATA : - return "CLIPBRD_E_BAD_DATA "; - case CLIPBRD_E_CANT_CLOSE : - return "CLIPBRD_E_CANT_CLOSE "; - case MK_E_CONNECTMANUALLY : - return "MK_E_CONNECTMANUALLY "; - case MK_E_EXCEEDEDDEADLINE : - return "MK_E_EXCEEDEDDEADLINE "; - case MK_E_NEEDGENERIC : - return "MK_E_NEEDGENERIC "; - case MK_E_UNAVAILABLE : - return "MK_E_UNAVAILABLE "; - case MK_E_SYNTAX : - return "MK_E_SYNTAX "; - case MK_E_NOOBJECT : - return "MK_E_NOOBJECT "; - case MK_E_INVALIDEXTENSION : - return "MK_E_INVALIDEXTENSION "; - case MK_E_INTERMEDIATEINTERFACENOTSUPPORTED : - return "MK_E_INTERMEDIATEINTERFACENOTSUPPORTED "; - case MK_E_NOTBINDABLE : - return "MK_E_NOTBINDABLE "; - case MK_E_NOTBOUND : - return "MK_E_NOTBOUND "; - case MK_E_CANTOPENFILE : - return "MK_E_CANTOPENFILE "; - case MK_E_MUSTBOTHERUSER : - return "MK_E_MUSTBOTHERUSER "; - case MK_E_NOINVERSE : - return "MK_E_NOINVERSE "; - case MK_E_NOSTORAGE : - return "MK_E_NOSTORAGE "; - case MK_E_NOPREFIX : - return "MK_E_NOPREFIX "; - case MK_E_ENUMERATION_FAILED : - return "MK_E_ENUMERATION_FAILED "; - case CO_E_NOTINITIALIZED : - return "CO_E_NOTINITIALIZED "; - case CO_E_ALREADYINITIALIZED : - return "CO_E_ALREADYINITIALIZED "; - case CO_E_CANTDETERMINECLASS : - return "CO_E_CANTDETERMINECLASS "; - case CO_E_CLASSSTRING : - return "CO_E_CLASSSTRING "; - case CO_E_IIDSTRING : - return "CO_E_IIDSTRING "; - case CO_E_APPNOTFOUND : - return "CO_E_APPNOTFOUND "; - case CO_E_APPSINGLEUSE : - return "CO_E_APPSINGLEUSE "; - case CO_E_ERRORINAPP : - return "CO_E_ERRORINAPP "; - case CO_E_DLLNOTFOUND : - return "CO_E_DLLNOTFOUND "; - case CO_E_ERRORINDLL : - return "CO_E_ERRORINDLL "; - case CO_E_WRONGOSFORAPP : - return "CO_E_WRONGOSFORAPP "; - case CO_E_OBJNOTREG : - return "CO_E_OBJNOTREG "; - case CO_E_OBJISREG : - return "CO_E_OBJISREG "; - case CO_E_OBJNOTCONNECTED : - return "CO_E_OBJNOTCONNECTED "; - case CO_E_APPDIDNTREG : - return "CO_E_APPDIDNTREG "; - case CO_E_RELEASED : - return "CO_E_RELEASED "; - case CO_E_FAILEDTOIMPERSONATE : - return "CO_E_FAILEDTOIMPERSONATE "; - case CO_E_FAILEDTOGETSECCTX : - return "CO_E_FAILEDTOGETSECCTX "; - case CO_E_FAILEDTOOPENTHREADTOKEN : - return "CO_E_FAILEDTOOPENTHREADTOKEN "; - case CO_E_FAILEDTOGETTOKENINFO : - return "CO_E_FAILEDTOGETTOKENINFO "; - case CO_E_TRUSTEEDOESNTMATCHCLIENT : - return "CO_E_TRUSTEEDOESNTMATCHCLIENT "; - case CO_E_FAILEDTOQUERYCLIENTBLANKET : - return "CO_E_FAILEDTOQUERYCLIENTBLANKET "; - case CO_E_FAILEDTOSETDACL : - return "CO_E_FAILEDTOSETDACL "; - case CO_E_ACCESSCHECKFAILED : - return "CO_E_ACCESSCHECKFAILED "; - case CO_E_NETACCESSAPIFAILED : - return "CO_E_NETACCESSAPIFAILED "; - case CO_E_WRONGTRUSTEENAMESYNTAX : - return "CO_E_WRONGTRUSTEENAMESYNTAX "; - case CO_E_INVALIDSID : - return "CO_E_INVALIDSID "; - case CO_E_CONVERSIONFAILED : - return "CO_E_CONVERSIONFAILED "; - case CO_E_NOMATCHINGSIDFOUND : - return "CO_E_NOMATCHINGSIDFOUND "; - case CO_E_LOOKUPACCSIDFAILED : - return "CO_E_LOOKUPACCSIDFAILED "; - case CO_E_NOMATCHINGNAMEFOUND : - return "CO_E_NOMATCHINGNAMEFOUND "; - case CO_E_LOOKUPACCNAMEFAILED : - return "CO_E_LOOKUPACCNAMEFAILED "; - case CO_E_SETSERLHNDLFAILED : - return "CO_E_SETSERLHNDLFAILED "; - case CO_E_FAILEDTOGETWINDIR : - return "CO_E_FAILEDTOGETWINDIR "; - case CO_E_PATHTOOLONG : - return "CO_E_PATHTOOLONG "; - case CO_E_FAILEDTOGENUUID : - return "CO_E_FAILEDTOGENUUID "; - case CO_E_FAILEDTOCREATEFILE : - return "CO_E_FAILEDTOCREATEFILE "; - case CO_E_FAILEDTOCLOSEHANDLE : - return "CO_E_FAILEDTOCLOSEHANDLE "; - case CO_E_EXCEEDSYSACLLIMIT : - return "CO_E_EXCEEDSYSACLLIMIT "; - case CO_E_ACESINWRONGORDER : - return "CO_E_ACESINWRONGORDER "; - case CO_E_INCOMPATIBLESTREAMVERSION : - return "CO_E_INCOMPATIBLESTREAMVERSION "; - case CO_E_FAILEDTOOPENPROCESSTOKEN : - return "CO_E_FAILEDTOOPENPROCESSTOKEN "; - case CO_E_DECODEFAILED : - return "CO_E_DECODEFAILED "; - case CO_E_ACNOTINITIALIZED : - return "CO_E_ACNOTINITIALIZED "; - case OLE_S_USEREG : - return "OLE_S_USEREG "; - case OLE_S_STATIC : - return "OLE_S_STATIC "; - case OLE_S_MAC_CLIPFORMAT : - return "OLE_S_MAC_CLIPFORMAT "; - case DRAGDROP_S_DROP : - return "DRAGDROP_S_DROP "; - case DRAGDROP_S_CANCEL : - return "DRAGDROP_S_CANCEL "; - case DRAGDROP_S_USEDEFAULTCURSORS : - return "DRAGDROP_S_USEDEFAULTCURSORS "; - case DATA_S_SAMEFORMATETC : - return "DATA_S_SAMEFORMATETC "; - case VIEW_S_ALREADY_FROZEN : - return "VIEW_S_ALREADY_FROZEN "; - case CACHE_S_FORMATETC_NOTSUPPORTED : - return "CACHE_S_FORMATETC_NOTSUPPORTED "; - case CACHE_S_SAMECACHE : - return "CACHE_S_SAMECACHE "; - case CACHE_S_SOMECACHES_NOTUPDATED : - return "CACHE_S_SOMECACHES_NOTUPDATED "; - case OLEOBJ_S_INVALIDVERB : - return "OLEOBJ_S_INVALIDVERB "; - case OLEOBJ_S_CANNOT_DOVERB_NOW : - return "OLEOBJ_S_CANNOT_DOVERB_NOW "; - case OLEOBJ_S_INVALIDHWND : - return "OLEOBJ_S_INVALIDHWND "; - case INPLACE_S_TRUNCATED : - return "INPLACE_S_TRUNCATED "; - case CONVERT10_S_NO_PRESENTATION : - return "CONVERT10_S_NO_PRESENTATION "; - case MK_S_REDUCED_TO_SELF : - return "MK_S_REDUCED_TO_SELF "; - case MK_S_ME : - return "MK_S_ME "; - case MK_S_HIM : - return "MK_S_HIM "; - case MK_S_US : - return "MK_S_US "; - case MK_S_MONIKERALREADYREGISTERED : - return "MK_S_MONIKERALREADYREGISTERED "; - case CO_E_CLASS_CREATE_FAILED : - return "CO_E_CLASS_CREATE_FAILED "; - case CO_E_SCM_ERROR : - return "CO_E_SCM_ERROR "; - case CO_E_SCM_RPC_FAILURE : - return "CO_E_SCM_RPC_FAILURE "; - case CO_E_BAD_PATH : - return "CO_E_BAD_PATH "; - case CO_E_SERVER_EXEC_FAILURE : - return "CO_E_SERVER_EXEC_FAILURE "; - case CO_E_OBJSRV_RPC_FAILURE : - return "CO_E_OBJSRV_RPC_FAILURE "; - case MK_E_NO_NORMALIZED : - return "MK_E_NO_NORMALIZED "; - case CO_E_SERVER_STOPPING : - return "CO_E_SERVER_STOPPING "; - case MEM_E_INVALID_ROOT : - return "MEM_E_INVALID_ROOT "; - case MEM_E_INVALID_LINK : - return "MEM_E_INVALID_LINK "; - case MEM_E_INVALID_SIZE : - return "MEM_E_INVALID_SIZE "; - case CO_S_NOTALLINTERFACES : - return "CO_S_NOTALLINTERFACES "; - case DISP_E_UNKNOWNINTERFACE : - return "DISP_E_UNKNOWNINTERFACE "; - case DISP_E_MEMBERNOTFOUND : - return "DISP_E_MEMBERNOTFOUND "; - case DISP_E_PARAMNOTFOUND : - return "DISP_E_PARAMNOTFOUND "; - case DISP_E_TYPEMISMATCH : - return "DISP_E_TYPEMISMATCH "; - case DISP_E_UNKNOWNNAME : - return "DISP_E_UNKNOWNNAME "; - case DISP_E_NONAMEDARGS : - return "DISP_E_NONAMEDARGS "; - case DISP_E_BADVARTYPE : - return "DISP_E_BADVARTYPE "; - case DISP_E_EXCEPTION : - return "DISP_E_EXCEPTION "; - case DISP_E_OVERFLOW : - return "DISP_E_OVERFLOW "; - case DISP_E_BADINDEX : - return "DISP_E_BADINDEX "; - case DISP_E_UNKNOWNLCID : - return "DISP_E_UNKNOWNLCID "; - case DISP_E_ARRAYISLOCKED : - return "DISP_E_ARRAYISLOCKED "; - case DISP_E_BADPARAMCOUNT : - return "DISP_E_BADPARAMCOUNT "; - case DISP_E_PARAMNOTOPTIONAL : - return "DISP_E_PARAMNOTOPTIONAL "; - case DISP_E_BADCALLEE : - return "DISP_E_BADCALLEE "; - case DISP_E_NOTACOLLECTION : - return "DISP_E_NOTACOLLECTION "; - case DISP_E_DIVBYZERO : - return "DISP_E_DIVBYZERO "; - case TYPE_E_BUFFERTOOSMALL : - return "TYPE_E_BUFFERTOOSMALL "; - case TYPE_E_FIELDNOTFOUND : - return "TYPE_E_FIELDNOTFOUND "; - case TYPE_E_INVDATAREAD : - return "TYPE_E_INVDATAREAD "; - case TYPE_E_UNSUPFORMAT : - return "TYPE_E_UNSUPFORMAT "; - case TYPE_E_REGISTRYACCESS : - return "TYPE_E_REGISTRYACCESS "; - case TYPE_E_LIBNOTREGISTERED : - return "TYPE_E_LIBNOTREGISTERED "; - case TYPE_E_UNDEFINEDTYPE : - return "TYPE_E_UNDEFINEDTYPE "; - case TYPE_E_QUALIFIEDNAMEDISALLOWED : - return "TYPE_E_QUALIFIEDNAMEDISALLOWED "; - case TYPE_E_INVALIDSTATE : - return "TYPE_E_INVALIDSTATE "; - case TYPE_E_WRONGTYPEKIND : - return "TYPE_E_WRONGTYPEKIND "; - case TYPE_E_ELEMENTNOTFOUND : - return "TYPE_E_ELEMENTNOTFOUND "; - case TYPE_E_AMBIGUOUSNAME : - return "TYPE_E_AMBIGUOUSNAME "; - case TYPE_E_NAMECONFLICT : - return "TYPE_E_NAMECONFLICT "; - case TYPE_E_UNKNOWNLCID : - return "TYPE_E_UNKNOWNLCID "; - case TYPE_E_DLLFUNCTIONNOTFOUND : - return "TYPE_E_DLLFUNCTIONNOTFOUND "; - case TYPE_E_BADMODULEKIND : - return "TYPE_E_BADMODULEKIND "; - case TYPE_E_SIZETOOBIG : - return "TYPE_E_SIZETOOBIG "; - case TYPE_E_DUPLICATEID : - return "TYPE_E_DUPLICATEID "; - case TYPE_E_INVALIDID : - return "TYPE_E_INVALIDID "; - case TYPE_E_TYPEMISMATCH : - return "TYPE_E_TYPEMISMATCH "; - case TYPE_E_OUTOFBOUNDS : - return "TYPE_E_OUTOFBOUNDS "; - case TYPE_E_IOERROR : - return "TYPE_E_IOERROR "; - case TYPE_E_CANTCREATETMPFILE : - return "TYPE_E_CANTCREATETMPFILE "; - case TYPE_E_CANTLOADLIBRARY : - return "TYPE_E_CANTLOADLIBRARY "; - case TYPE_E_INCONSISTENTPROPFUNCS : - return "TYPE_E_INCONSISTENTPROPFUNCS "; - case TYPE_E_CIRCULARTYPE : - return "TYPE_E_CIRCULARTYPE "; - case STG_E_INVALIDFUNCTION : - return "STG_E_INVALIDFUNCTION "; - case STG_E_FILENOTFOUND : - return "STG_E_FILENOTFOUND "; - case STG_E_PATHNOTFOUND : - return "STG_E_PATHNOTFOUND "; - case STG_E_TOOMANYOPENFILES : - return "STG_E_TOOMANYOPENFILES "; - case STG_E_ACCESSDENIED : - return "STG_E_ACCESSDENIED "; - case STG_E_INVALIDHANDLE : - return "STG_E_INVALIDHANDLE "; - case STG_E_INSUFFICIENTMEMORY : - return "STG_E_INSUFFICIENTMEMORY "; - case STG_E_INVALIDPOINTER : - return "STG_E_INVALIDPOINTER "; - case STG_E_NOMOREFILES : - return "STG_E_NOMOREFILES "; - case STG_E_DISKISWRITEPROTECTED : - return "STG_E_DISKISWRITEPROTECTED "; - case STG_E_SEEKERROR : - return "STG_E_SEEKERROR "; - case STG_E_WRITEFAULT : - return "STG_E_WRITEFAULT "; - case STG_E_READFAULT : - return "STG_E_READFAULT "; - case STG_E_SHAREVIOLATION : - return "STG_E_SHAREVIOLATION "; - case STG_E_LOCKVIOLATION : - return "STG_E_LOCKVIOLATION "; - case STG_E_FILEALREADYEXISTS : - return "STG_E_FILEALREADYEXISTS "; - case STG_E_INVALIDPARAMETER : - return "STG_E_INVALIDPARAMETER "; - case STG_E_MEDIUMFULL : - return "STG_E_MEDIUMFULL "; - case STG_E_PROPSETMISMATCHED : - return "STG_E_PROPSETMISMATCHED "; - case STG_E_ABNORMALAPIEXIT : - return "STG_E_ABNORMALAPIEXIT "; - case STG_E_INVALIDHEADER : - return "STG_E_INVALIDHEADER "; - case STG_E_INVALIDNAME : - return "STG_E_INVALIDNAME "; - case STG_E_UNKNOWN : - return "STG_E_UNKNOWN "; - case STG_E_UNIMPLEMENTEDFUNCTION : - return "STG_E_UNIMPLEMENTEDFUNCTION "; - case STG_E_INVALIDFLAG : - return "STG_E_INVALIDFLAG "; - case STG_E_INUSE : - return "STG_E_INUSE "; - case STG_E_NOTCURRENT : - return "STG_E_NOTCURRENT "; - case STG_E_REVERTED : - return "STG_E_REVERTED "; - case STG_E_CANTSAVE : - return "STG_E_CANTSAVE "; - case STG_E_OLDFORMAT : - return "STG_E_OLDFORMAT "; - case STG_E_OLDDLL : - return "STG_E_OLDDLL "; - case STG_E_SHAREREQUIRED : - return "STG_E_SHAREREQUIRED "; - case STG_E_NOTFILEBASEDSTORAGE : - return "STG_E_NOTFILEBASEDSTORAGE "; - case STG_E_EXTANTMARSHALLINGS : - return "STG_E_EXTANTMARSHALLINGS "; - case STG_E_DOCFILECORRUPT : - return "STG_E_DOCFILECORRUPT "; - case STG_E_BADBASEADDRESS : - return "STG_E_BADBASEADDRESS "; - case STG_E_INCOMPLETE : - return "STG_E_INCOMPLETE "; - case STG_E_TERMINATED : - return "STG_E_TERMINATED "; - case STG_S_CONVERTED : - return "STG_S_CONVERTED "; - case STG_S_BLOCK : - return "STG_S_BLOCK "; - case STG_S_RETRYNOW : - return "STG_S_RETRYNOW "; - case STG_S_MONITORING : - return "STG_S_MONITORING "; - case STG_S_MULTIPLEOPENS : - return "STG_S_MULTIPLEOPENS "; - case STG_S_CONSOLIDATIONFAILED : - return "STG_S_CONSOLIDATIONFAILED "; - case STG_S_CANNOTCONSOLIDATE : - return "STG_S_CANNOTCONSOLIDATE "; - case RPC_E_CALL_REJECTED : - return "RPC_E_CALL_REJECTED "; - case RPC_E_CALL_CANCELED : - return "RPC_E_CALL_CANCELED "; - case RPC_E_CANTPOST_INSENDCALL : - return "RPC_E_CANTPOST_INSENDCALL "; - case RPC_E_CANTCALLOUT_INASYNCCALL : - return "RPC_E_CANTCALLOUT_INASYNCCALL "; - case RPC_E_CANTCALLOUT_INEXTERNALCALL : - return "RPC_E_CANTCALLOUT_INEXTERNALCALL "; - case RPC_E_CONNECTION_TERMINATED : - return "RPC_E_CONNECTION_TERMINATED "; - case RPC_E_SERVER_DIED : - return "RPC_E_SERVER_DIED "; - case RPC_E_CLIENT_DIED : - return "RPC_E_CLIENT_DIED "; - case RPC_E_INVALID_DATAPACKET : - return "RPC_E_INVALID_DATAPACKET "; - case RPC_E_CANTTRANSMIT_CALL : - return "RPC_E_CANTTRANSMIT_CALL "; - case RPC_E_CLIENT_CANTMARSHAL_DATA : - return "RPC_E_CLIENT_CANTMARSHAL_DATA "; - case RPC_E_CLIENT_CANTUNMARSHAL_DATA : - return "RPC_E_CLIENT_CANTUNMARSHAL_DATA "; - case RPC_E_SERVER_CANTMARSHAL_DATA : - return "RPC_E_SERVER_CANTMARSHAL_DATA "; - case RPC_E_SERVER_CANTUNMARSHAL_DATA : - return "RPC_E_SERVER_CANTUNMARSHAL_DATA "; - case RPC_E_INVALID_DATA : - return "RPC_E_INVALID_DATA "; - case RPC_E_INVALID_PARAMETER : - return "RPC_E_INVALID_PARAMETER "; - case RPC_E_CANTCALLOUT_AGAIN : - return "RPC_E_CANTCALLOUT_AGAIN "; - case RPC_E_SERVER_DIED_DNE : - return "RPC_E_SERVER_DIED_DNE "; - case RPC_E_SYS_CALL_FAILED : - return "RPC_E_SYS_CALL_FAILED "; - case RPC_E_OUT_OF_RESOURCES : - return "RPC_E_OUT_OF_RESOURCES "; - case RPC_E_ATTEMPTED_MULTITHREAD : - return "RPC_E_ATTEMPTED_MULTITHREAD "; - case RPC_E_NOT_REGISTERED : - return "RPC_E_NOT_REGISTERED "; - case RPC_E_FAULT : - return "RPC_E_FAULT "; - case RPC_E_SERVERFAULT : - return "RPC_E_SERVERFAULT "; - case RPC_E_CHANGED_MODE : - return "RPC_E_CHANGED_MODE "; - case RPC_E_INVALIDMETHOD : - return "RPC_E_INVALIDMETHOD "; - case RPC_E_DISCONNECTED : - return "RPC_E_DISCONNECTED "; - case RPC_E_RETRY : - return "RPC_E_RETRY "; - case RPC_E_SERVERCALL_RETRYLATER : - return "RPC_E_SERVERCALL_RETRYLATER "; - case RPC_E_SERVERCALL_REJECTED : - return "RPC_E_SERVERCALL_REJECTED "; - case RPC_E_INVALID_CALLDATA : - return "RPC_E_INVALID_CALLDATA "; - case RPC_E_CANTCALLOUT_ININPUTSYNCCALL : - return "RPC_E_CANTCALLOUT_ININPUTSYNCCALL "; - case RPC_E_WRONG_THREAD : - return "RPC_E_WRONG_THREAD "; - case RPC_E_THREAD_NOT_INIT : - return "RPC_E_THREAD_NOT_INIT "; - case RPC_E_VERSION_MISMATCH : - return "RPC_E_VERSION_MISMATCH "; - case RPC_E_INVALID_HEADER : - return "RPC_E_INVALID_HEADER "; - case RPC_E_INVALID_EXTENSION : - return "RPC_E_INVALID_EXTENSION "; - case RPC_E_INVALID_IPID : - return "RPC_E_INVALID_IPID "; - case RPC_E_INVALID_OBJECT : - return "RPC_E_INVALID_OBJECT "; - case RPC_S_CALLPENDING : - return "RPC_S_CALLPENDING "; - case RPC_S_WAITONTIMER : - return "RPC_S_WAITONTIMER "; - case RPC_E_CALL_COMPLETE : - return "RPC_E_CALL_COMPLETE "; - case RPC_E_UNSECURE_CALL : - return "RPC_E_UNSECURE_CALL "; - case RPC_E_TOO_LATE : - return "RPC_E_TOO_LATE "; - case RPC_E_NO_GOOD_SECURITY_PACKAGES : - return "RPC_E_NO_GOOD_SECURITY_PACKAGES "; - case RPC_E_ACCESS_DENIED : - return "RPC_E_ACCESS_DENIED "; - case RPC_E_REMOTE_DISABLED : - return "RPC_E_REMOTE_DISABLED "; - case RPC_E_INVALID_OBJREF : - return "RPC_E_INVALID_OBJREF "; - case RPC_E_NO_CONTEXT : - return "RPC_E_NO_CONTEXT "; - case RPC_E_TIMEOUT : - return "RPC_E_TIMEOUT "; - case RPC_E_NO_SYNC : - return "RPC_E_NO_SYNC "; - case RPC_E_UNEXPECTED : - return "RPC_E_UNEXPECTED "; - case NTE_BAD_UID : - return "NTE_BAD_UID "; - case NTE_BAD_HASH : - return "NTE_BAD_HASH "; - //case NTE_BAD_HASH : - //return "NTE_BAD_HASH "; - case NTE_BAD_KEY : - return "NTE_BAD_KEY "; - case NTE_BAD_LEN : - return "NTE_BAD_LEN "; - case NTE_BAD_DATA : - return "NTE_BAD_DATA "; - case NTE_BAD_SIGNATURE : - return "NTE_BAD_SIGNATURE "; - case NTE_BAD_VER : - return "NTE_BAD_VER "; - case NTE_BAD_ALGID : - return "NTE_BAD_ALGID "; - case NTE_BAD_FLAGS : - return "NTE_BAD_FLAGS "; - case NTE_BAD_TYPE : - return "NTE_BAD_TYPE "; - case NTE_BAD_KEY_STATE : - return "NTE_BAD_KEY_STATE "; - case NTE_BAD_HASH_STATE : - return "NTE_BAD_HASH_STATE "; - case NTE_NO_KEY : - return "NTE_NO_KEY "; - case NTE_NO_MEMORY : - return "NTE_NO_MEMORY "; - case NTE_EXISTS : - return "NTE_EXISTS "; - case NTE_PERM : - return "NTE_PERM "; - case NTE_NOT_FOUND : - return "NTE_NOT_FOUND "; - case NTE_DOUBLE_ENCRYPT : - return "NTE_DOUBLE_ENCRYPT "; - case NTE_BAD_PROVIDER : - return "NTE_BAD_PROVIDER "; - case NTE_BAD_PROV_TYPE : - return "NTE_BAD_PROV_TYPE "; - case NTE_BAD_PUBLIC_KEY : - return "NTE_BAD_PUBLIC_KEY "; - case NTE_BAD_KEYSET : - return "NTE_BAD_KEYSET "; - case NTE_PROV_TYPE_NOT_DEF : - return "NTE_PROV_TYPE_NOT_DEF "; - case NTE_PROV_TYPE_ENTRY_BAD : - return "NTE_PROV_TYPE_ENTRY_BAD "; - case NTE_KEYSET_NOT_DEF : - return "NTE_KEYSET_NOT_DEF "; - case NTE_KEYSET_ENTRY_BAD : - return "NTE_KEYSET_ENTRY_BAD "; - case NTE_PROV_TYPE_NO_MATCH : - return "NTE_PROV_TYPE_NO_MATCH "; - case NTE_SIGNATURE_FILE_BAD : - return "NTE_SIGNATURE_FILE_BAD "; - case NTE_PROVIDER_DLL_FAIL : - return "NTE_PROVIDER_DLL_FAIL "; - case NTE_PROV_DLL_NOT_FOUND : - return "NTE_PROV_DLL_NOT_FOUND "; - case NTE_BAD_KEYSET_PARAM : - return "NTE_BAD_KEYSET_PARAM "; - case NTE_FAIL : - return "NTE_FAIL "; - case NTE_SYS_ERR : - return "NTE_SYS_ERR "; - case CRYPT_E_MSG_ERROR : - return "CRYPT_E_MSG_ERROR "; - case CRYPT_E_UNKNOWN_ALGO : - return "CRYPT_E_UNKNOWN_ALGO "; - case CRYPT_E_OID_FORMAT : - return "CRYPT_E_OID_FORMAT "; - case CRYPT_E_INVALID_MSG_TYPE : - return "CRYPT_E_INVALID_MSG_TYPE "; - case CRYPT_E_UNEXPECTED_ENCODING : - return "CRYPT_E_UNEXPECTED_ENCODING "; - case CRYPT_E_AUTH_ATTR_MISSING : - return "CRYPT_E_AUTH_ATTR_MISSING "; - case CRYPT_E_HASH_VALUE : - return "CRYPT_E_HASH_VALUE "; - case CRYPT_E_INVALID_INDEX : - return "CRYPT_E_INVALID_INDEX "; - case CRYPT_E_ALREADY_DECRYPTED : - return "CRYPT_E_ALREADY_DECRYPTED "; - case CRYPT_E_NOT_DECRYPTED : - return "CRYPT_E_NOT_DECRYPTED "; - case CRYPT_E_RECIPIENT_NOT_FOUND : - return "CRYPT_E_RECIPIENT_NOT_FOUND "; - case CRYPT_E_CONTROL_TYPE : - return "CRYPT_E_CONTROL_TYPE "; - case CRYPT_E_ISSUER_SERIALNUMBER : - return "CRYPT_E_ISSUER_SERIALNUMBER "; - case CRYPT_E_SIGNER_NOT_FOUND : - return "CRYPT_E_SIGNER_NOT_FOUND "; - case CRYPT_E_ATTRIBUTES_MISSING : - return "CRYPT_E_ATTRIBUTES_MISSING "; - case CRYPT_E_STREAM_MSG_NOT_READY : - return "CRYPT_E_STREAM_MSG_NOT_READY "; - case CRYPT_E_STREAM_INSUFFICIENT_DATA : - return "CRYPT_E_STREAM_INSUFFICIENT_DATA "; - case CRYPT_E_BAD_LEN : - return "CRYPT_E_BAD_LEN "; - case CRYPT_E_BAD_ENCODE : - return "CRYPT_E_BAD_ENCODE "; - case CRYPT_E_FILE_ERROR : - return "CRYPT_E_FILE_ERROR "; - case CRYPT_E_NOT_FOUND : - return "CRYPT_E_NOT_FOUND "; - case CRYPT_E_EXISTS : - return "CRYPT_E_EXISTS "; - case CRYPT_E_NO_PROVIDER : - return "CRYPT_E_NO_PROVIDER "; - case CRYPT_E_SELF_SIGNED : - return "CRYPT_E_SELF_SIGNED "; - case CRYPT_E_DELETED_PREV : - return "CRYPT_E_DELETED_PREV "; - case CRYPT_E_NO_MATCH : - return "CRYPT_E_NO_MATCH "; - case CRYPT_E_UNEXPECTED_MSG_TYPE : - return "CRYPT_E_UNEXPECTED_MSG_TYPE "; - case CRYPT_E_NO_KEY_PROPERTY : - return "CRYPT_E_NO_KEY_PROPERTY "; - case CRYPT_E_NO_DECRYPT_CERT : - return "CRYPT_E_NO_DECRYPT_CERT "; - case CRYPT_E_BAD_MSG : - return "CRYPT_E_BAD_MSG "; - case CRYPT_E_NO_SIGNER : - return "CRYPT_E_NO_SIGNER "; - case CRYPT_E_PENDING_CLOSE : - return "CRYPT_E_PENDING_CLOSE "; - case CRYPT_E_REVOKED : - return "CRYPT_E_REVOKED "; - case CRYPT_E_NO_REVOCATION_DLL : - return "CRYPT_E_NO_REVOCATION_DLL "; - case CRYPT_E_NO_REVOCATION_CHECK : - return "CRYPT_E_NO_REVOCATION_CHECK "; - case CRYPT_E_REVOCATION_OFFLINE : - return "CRYPT_E_REVOCATION_OFFLINE "; - case CRYPT_E_NOT_IN_REVOCATION_DATABASE : - return "CRYPT_E_NOT_IN_REVOCATION_DATABASE "; - case CRYPT_E_INVALID_NUMERIC_STRING : - return "CRYPT_E_INVALID_NUMERIC_STRING "; - case CRYPT_E_INVALID_PRINTABLE_STRING : - return "CRYPT_E_INVALID_PRINTABLE_STRING "; - case CRYPT_E_INVALID_IA5_STRING : - return "CRYPT_E_INVALID_IA5_STRING "; - case CRYPT_E_INVALID_X500_STRING : - return "CRYPT_E_INVALID_X500_STRING "; - case CRYPT_E_NOT_CHAR_STRING : - return "CRYPT_E_NOT_CHAR_STRING "; - case CRYPT_E_FILERESIZED : - return "CRYPT_E_FILERESIZED "; - case CRYPT_E_SECURITY_SETTINGS : - return "CRYPT_E_SECURITY_SETTINGS "; - case CRYPT_E_NO_VERIFY_USAGE_DLL : - return "CRYPT_E_NO_VERIFY_USAGE_DLL "; - case CRYPT_E_NO_VERIFY_USAGE_CHECK : - return "CRYPT_E_NO_VERIFY_USAGE_CHECK "; - case CRYPT_E_VERIFY_USAGE_OFFLINE : - return "CRYPT_E_VERIFY_USAGE_OFFLINE "; - case CRYPT_E_NOT_IN_CTL : - return "CRYPT_E_NOT_IN_CTL "; - case CRYPT_E_NO_TRUSTED_SIGNER : - return "CRYPT_E_NO_TRUSTED_SIGNER "; - case CRYPT_E_OSS_ERROR : - return "CRYPT_E_OSS_ERROR "; - case CERTSRV_E_BAD_REQUESTSUBJECT : - return "CERTSRV_E_BAD_REQUESTSUBJECT "; - case CERTSRV_E_NO_REQUEST : - return "CERTSRV_E_NO_REQUEST "; - case CERTSRV_E_BAD_REQUESTSTATUS : - return "CERTSRV_E_BAD_REQUESTSTATUS "; - case CERTSRV_E_PROPERTY_EMPTY : - return "CERTSRV_E_PROPERTY_EMPTY "; - //case CERTDB_E_JET_ERROR : - //return "CERTDB_E_JET_ERROR "; - case TRUST_E_SYSTEM_ERROR : - return "TRUST_E_SYSTEM_ERROR "; - case TRUST_E_NO_SIGNER_CERT : - return "TRUST_E_NO_SIGNER_CERT "; - case TRUST_E_COUNTER_SIGNER : - return "TRUST_E_COUNTER_SIGNER "; - case TRUST_E_CERT_SIGNATURE : - return "TRUST_E_CERT_SIGNATURE "; - case TRUST_E_TIME_STAMP : - return "TRUST_E_TIME_STAMP "; - case TRUST_E_BAD_DIGEST : - return "TRUST_E_BAD_DIGEST "; - case TRUST_E_BASIC_CONSTRAINTS : - return "TRUST_E_BASIC_CONSTRAINTS "; - case TRUST_E_FINANCIAL_CRITERIA : - return "TRUST_E_FINANCIAL_CRITERIA "; - case TRUST_E_PROVIDER_UNKNOWN : - return "TRUST_E_PROVIDER_UNKNOWN "; - case TRUST_E_ACTION_UNKNOWN : - return "TRUST_E_ACTION_UNKNOWN "; - case TRUST_E_SUBJECT_FORM_UNKNOWN : - return "TRUST_E_SUBJECT_FORM_UNKNOWN "; - case TRUST_E_SUBJECT_NOT_TRUSTED : - return "TRUST_E_SUBJECT_NOT_TRUSTED "; - case DIGSIG_E_ENCODE : - return "DIGSIG_E_ENCODE "; - case DIGSIG_E_DECODE : - return "DIGSIG_E_DECODE "; - case DIGSIG_E_EXTENSIBILITY : - return "DIGSIG_E_EXTENSIBILITY "; - case DIGSIG_E_CRYPTO : - return "DIGSIG_E_CRYPTO "; - case PERSIST_E_SIZEDEFINITE : - return "PERSIST_E_SIZEDEFINITE "; - case PERSIST_E_SIZEINDEFINITE : - return "PERSIST_E_SIZEINDEFINITE "; - case PERSIST_E_NOTSELFSIZING : - return "PERSIST_E_NOTSELFSIZING "; - case TRUST_E_NOSIGNATURE : - return "TRUST_E_NOSIGNATURE "; - case CERT_E_EXPIRED : - return "CERT_E_EXPIRED "; - case CERT_E_VALIDITYPERIODNESTING : - return "CERT_E_VALIDITYPERIODNESTING "; - case CERT_E_ROLE : - return "CERT_E_ROLE "; - case CERT_E_PATHLENCONST : - return "CERT_E_PATHLENCONST "; - case CERT_E_CRITICAL : - return "CERT_E_CRITICAL "; - case CERT_E_PURPOSE : - return "CERT_E_PURPOSE "; - case CERT_E_ISSUERCHAINING : - return "CERT_E_ISSUERCHAINING "; - case CERT_E_MALFORMED : - return "CERT_E_MALFORMED "; - case CERT_E_UNTRUSTEDROOT : - return "CERT_E_UNTRUSTEDROOT "; - case CERT_E_CHAINING : - return "CERT_E_CHAINING "; - case TRUST_E_FAIL : - return "TRUST_E_FAIL "; - case CERT_E_REVOKED : - return "CERT_E_REVOKED "; - case CERT_E_UNTRUSTEDTESTROOT : - return "CERT_E_UNTRUSTEDTESTROOT "; - case CERT_E_REVOCATION_FAILURE : - return "CERT_E_REVOCATION_FAILURE "; - case CERT_E_CN_NO_MATCH : - return "CERT_E_CN_NO_MATCH "; - case CERT_E_WRONG_USAGE : - return "CERT_E_WRONG_USAGE "; - case SPAPI_E_EXPECTED_SECTION_NAME : - return "SPAPI_E_EXPECTED_SECTION_NAME "; - case SPAPI_E_BAD_SECTION_NAME_LINE : - return "SPAPI_E_BAD_SECTION_NAME_LINE "; - case SPAPI_E_SECTION_NAME_TOO_LONG : - return "SPAPI_E_SECTION_NAME_TOO_LONG "; - case SPAPI_E_GENERAL_SYNTAX : - return "SPAPI_E_GENERAL_SYNTAX "; - case SPAPI_E_WRONG_INF_STYLE : - return "SPAPI_E_WRONG_INF_STYLE "; - case SPAPI_E_SECTION_NOT_FOUND : - return "SPAPI_E_SECTION_NOT_FOUND "; - case SPAPI_E_LINE_NOT_FOUND : - return "SPAPI_E_LINE_NOT_FOUND "; - case SPAPI_E_NO_ASSOCIATED_CLASS : - return "SPAPI_E_NO_ASSOCIATED_CLASS "; - case SPAPI_E_CLASS_MISMATCH : - return "SPAPI_E_CLASS_MISMATCH "; - case SPAPI_E_DUPLICATE_FOUND : - return "SPAPI_E_DUPLICATE_FOUND "; - case SPAPI_E_NO_DRIVER_SELECTED : - return "SPAPI_E_NO_DRIVER_SELECTED "; - case SPAPI_E_KEY_DOES_NOT_EXIST : - return "SPAPI_E_KEY_DOES_NOT_EXIST "; - case SPAPI_E_INVALID_DEVINST_NAME : - return "SPAPI_E_INVALID_DEVINST_NAME "; - case SPAPI_E_INVALID_CLASS : - return "SPAPI_E_INVALID_CLASS "; - case SPAPI_E_DEVINST_ALREADY_EXISTS : - return "SPAPI_E_DEVINST_ALREADY_EXISTS "; - case SPAPI_E_DEVINFO_NOT_REGISTERED : - return "SPAPI_E_DEVINFO_NOT_REGISTERED "; - case SPAPI_E_INVALID_REG_PROPERTY : - return "SPAPI_E_INVALID_REG_PROPERTY "; - case SPAPI_E_NO_INF : - return "SPAPI_E_NO_INF "; - case SPAPI_E_NO_SUCH_DEVINST : - return "SPAPI_E_NO_SUCH_DEVINST "; - case SPAPI_E_CANT_LOAD_CLASS_ICON : - return "SPAPI_E_CANT_LOAD_CLASS_ICON "; - case SPAPI_E_INVALID_CLASS_INSTALLER : - return "SPAPI_E_INVALID_CLASS_INSTALLER "; - case SPAPI_E_DI_DO_DEFAULT : - return "SPAPI_E_DI_DO_DEFAULT "; - case SPAPI_E_DI_NOFILECOPY : - return "SPAPI_E_DI_NOFILECOPY "; - case SPAPI_E_INVALID_HWPROFILE : - return "SPAPI_E_INVALID_HWPROFILE "; - case SPAPI_E_NO_DEVICE_SELECTED : - return "SPAPI_E_NO_DEVICE_SELECTED "; - case SPAPI_E_DEVINFO_LIST_LOCKED : - return "SPAPI_E_DEVINFO_LIST_LOCKED "; - case SPAPI_E_DEVINFO_DATA_LOCKED : - return "SPAPI_E_DEVINFO_DATA_LOCKED "; - case SPAPI_E_DI_BAD_PATH : - return "SPAPI_E_DI_BAD_PATH "; - case SPAPI_E_NO_CLASSINSTALL_PARAMS : - return "SPAPI_E_NO_CLASSINSTALL_PARAMS "; - case SPAPI_E_FILEQUEUE_LOCKED : - return "SPAPI_E_FILEQUEUE_LOCKED "; - case SPAPI_E_BAD_SERVICE_INSTALLSECT : - return "SPAPI_E_BAD_SERVICE_INSTALLSECT "; - case SPAPI_E_NO_CLASS_DRIVER_LIST : - return "SPAPI_E_NO_CLASS_DRIVER_LIST "; - case SPAPI_E_NO_ASSOCIATED_SERVICE : - return "SPAPI_E_NO_ASSOCIATED_SERVICE "; - case SPAPI_E_NO_DEFAULT_DEVICE_INTERFACE : - return "SPAPI_E_NO_DEFAULT_DEVICE_INTERFACE "; - case SPAPI_E_DEVICE_INTERFACE_ACTIVE : - return "SPAPI_E_DEVICE_INTERFACE_ACTIVE "; - case SPAPI_E_DEVICE_INTERFACE_REMOVED : - return "SPAPI_E_DEVICE_INTERFACE_REMOVED "; - case SPAPI_E_BAD_INTERFACE_INSTALLSECT : - return "SPAPI_E_BAD_INTERFACE_INSTALLSECT "; - case SPAPI_E_NO_SUCH_INTERFACE_CLASS : - return "SPAPI_E_NO_SUCH_INTERFACE_CLASS "; - case SPAPI_E_INVALID_REFERENCE_STRING : - return "SPAPI_E_INVALID_REFERENCE_STRING "; - case SPAPI_E_INVALID_MACHINENAME : - return "SPAPI_E_INVALID_MACHINENAME "; - case SPAPI_E_REMOTE_COMM_FAILURE : - return "SPAPI_E_REMOTE_COMM_FAILURE "; - case SPAPI_E_MACHINE_UNAVAILABLE : - return "SPAPI_E_MACHINE_UNAVAILABLE "; - case SPAPI_E_NO_CONFIGMGR_SERVICES : - return "SPAPI_E_NO_CONFIGMGR_SERVICES "; - case SPAPI_E_INVALID_PROPPAGE_PROVIDER : - return "SPAPI_E_INVALID_PROPPAGE_PROVIDER "; - case SPAPI_E_NO_SUCH_DEVICE_INTERFACE : - return "SPAPI_E_NO_SUCH_DEVICE_INTERFACE "; - case SPAPI_E_DI_POSTPROCESSING_REQUIRED : - return "SPAPI_E_DI_POSTPROCESSING_REQUIRED "; - case SPAPI_E_INVALID_COINSTALLER : - return "SPAPI_E_INVALID_COINSTALLER "; - case SPAPI_E_NO_COMPAT_DRIVERS : - return "SPAPI_E_NO_COMPAT_DRIVERS "; - case SPAPI_E_NO_DEVICE_ICON : - return "SPAPI_E_NO_DEVICE_ICON "; - case SPAPI_E_INVALID_INF_LOGCONFIG : - return "SPAPI_E_INVALID_INF_LOGCONFIG "; - case SPAPI_E_DI_DONT_INSTALL : - return "SPAPI_E_DI_DONT_INSTALL "; - case SPAPI_E_INVALID_FILTER_DRIVER : - return "SPAPI_E_INVALID_FILTER_DRIVER "; - case SPAPI_E_ERROR_NOT_INSTALLED : - return "SPAPI_E_ERROR_NOT_INSTALLED "; - - default: - static char buff[1000]; - sprintf(buff, "Unrecognized error value: %08X\0", error); - - return buff; - } -} - diff --git a/panda/src/wdxdisplay/wdxGraphicsPipe.h b/panda/src/wdxdisplay/wdxGraphicsPipe.h deleted file mode 100644 index 9302c00b00..0000000000 --- a/panda/src/wdxdisplay/wdxGraphicsPipe.h +++ /dev/null @@ -1,67 +0,0 @@ -// Filename: wdxGraphicsPipe.h -// 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 . -// -//////////////////////////////////////////////////////////////////// -#ifndef WDXGRAPHICSPIPE_H -#define WDXGRAPHICSPIPE_H -// -//////////////////////////////////////////////////////////////////// -// Includes -//////////////////////////////////////////////////////////////////// - -#include -#include "wdxGraphicsWindow.h" -#include - -//////////////////////////////////////////////////////////////////// -// Class : wdxGraphicsPipe -// Description : -//////////////////////////////////////////////////////////////////// -class EXPCL_PANDADX wdxGraphicsPipe : public InteractiveGraphicsPipe { -public: - wdxGraphicsPipe(const PipeSpecifier&); - - wdxGraphicsWindow* find_window(HWND win); -// ButtonHandle lookup_key(WPARAM wparam) const; - - virtual TypeHandle get_window_type() const; - -public: - - static GraphicsPipe* make_wdxGraphicsPipe(const FactoryParams ¶ms); - - static TypeHandle get_class_type(void); - static void init_type(void); - virtual TypeHandle get_type(void) const; - virtual TypeHandle force_init_type() {init_type(); return get_class_type();} - -private: - - static TypeHandle _type_handle; - -// int _width; -// int _height; -// bool _shift; - -protected: - - wdxGraphicsPipe(void); - wdxGraphicsPipe(const wdxGraphicsPipe&); - wdxGraphicsPipe& operator=(const wdxGraphicsPipe&); - -}; - -#endif diff --git a/panda/src/wdxdisplay/wdxGraphicsWindow.cxx b/panda/src/wdxdisplay/wdxGraphicsWindow.cxx deleted file mode 100644 index 9a6a89dd31..0000000000 --- a/panda/src/wdxdisplay/wdxGraphicsWindow.cxx +++ /dev/null @@ -1,3010 +0,0 @@ -// Filename: wdxGraphicsWindow.cxx -// Created by: mike (09Jan00) -// -//////////////////////////////////////////////////////////////////// -// -// 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 -#include -#include -#include -#include "wdxGraphicsWindow.h" -#include "wdxGraphicsPipe.h" -#include "config_wdxdisplay.h" - -#include -#include -#include - -#ifdef DO_PSTATS -#include -#endif - -#include - -//////////////////////////////////////////////////////////////////// -// Static variables -//////////////////////////////////////////////////////////////////// -TypeHandle wdxGraphicsWindow::_type_handle; - -#define LAST_ERROR 0 -#define ERRORBOX_TITLE "Panda3D Error" -#define WDX_WINDOWCLASSNAME "wdxDisplay" -#define DEFAULT_CURSOR IDC_ARROW - -typedef map HWND_PANDAWIN_MAP; - -HWND_PANDAWIN_MAP hwnd_pandawin_map; -wdxGraphicsWindow* global_wdxwinptr = NULL; // need this for temporary windproc - -#define MAX_DISPLAYS 20 - -extern bool dx_full_screen_antialiasing; // defined in dxgsg_config.cxx - -#define PAUSED_TIMER_ID 7 // completely arbitrary choice -#define DXREADY ((_dxgsg!=NULL)&&(_dxgsg->GetDXReady())) - -LONG WINAPI static_window_proc(HWND hwnd, UINT msg, WPARAM wparam,LPARAM lparam); - -// imperfect method to ID NVid? could also scan desc str, but that isnt fullproof either -#define IS_NVIDIA(DDDEVICEID) ((DDDEVICEID.dwVendorId==0x10DE) || (DDDEVICEID.dwVendorId==0x12D2)) -#define IS_ATI(DDDEVICEID) (DDDEVICEID.dwVendorId==0x1002) -#define IS_MATROX(DDDEVICEID) (DDDEVICEID.dwVendorId==0x102B) - -// because we dont have access to ModifierButtons, as a hack just synchronize state of these -// keys on get/lose keybd focus -#define NUM_MODIFIER_KEYS 16 -unsigned int hardcoded_modifier_buttons[NUM_MODIFIER_KEYS]={VK_SHIFT,VK_MENU,VK_CONTROL,VK_SPACE,VK_TAB, - VK_UP,VK_DOWN,VK_LEFT,VK_RIGHT,VK_PRIOR,VK_NEXT,VK_HOME,VK_END, - VK_INSERT,VK_DELETE,VK_ESCAPE}; - -static DWORD BitDepth_2_DDBDMask(DWORD iBitDepth) { - switch(iBitDepth) { - case 16: return DDBD_16; - case 32: return DDBD_32; - case 24: return DDBD_24; - case 8: return DDBD_8; - case 1: return DDBD_1; - case 2: return DDBD_2; - case 4: return DDBD_4; - } - return 0x0; -} -/* -typedef enum {DBGLEV_FATAL,DBGLEV_ERROR,DBGLEV_WARNING,DBGLEV_INFO,DBGLEV_DEBUG,DBGLEV_SPAM - } DebugLevels; - -void PrintDBGStr(DebugLevels level,HRESULT hr,const char *msgstr) { - ostream *pstrm; - static ostream dbg_strms[DBGLEV_SPAM+1]={wdxdisplay_cat.fatal,wdxdisplay_cat.error, - wdxdisplay_cat.warning,wdxdisplay_cat.info,wdxdisplay_cat.debug,wdxdisplay_cat.spam}; - assert(level<=DBGLEV_SPAM); - - pstrm=dbg_strms[level]; - (*pstrm)->fatal() << "GetDisplayMode failed, result = " << ConvD3DErrorToString(hr) << endl; -} -*/ -#ifdef _DEBUG -static void DebugPrintPixFmt(DDPIXELFORMAT* pddpf) { - static int iddpfnum=0; - ostream *dbgout = &dxgsg_cat.debug(); - - *dbgout << "ZBuf DDPF[" << iddpfnum << "]: RGBBitCount:" << pddpf->dwRGBBitCount - << " Flags:" << (void *)pddpf->dwFlags ; - - if(pddpf->dwFlags & DDPF_STENCILBUFFER) { - *dbgout << " StencilBits:" << (void *) pddpf->dwStencilBitDepth; - } - - *dbgout << endl; - - iddpfnum++; -} -#endif - -// pops up MsgBox w/system error msg -#define LAST_ERROR 0 -void PrintErrorMessage(DWORD msgID) { - LPTSTR pMessageBuffer; - - if(msgID==LAST_ERROR) - msgID=GetLastError(); - - FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, - NULL,msgID, - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), //The user default language - (LPTSTR) &pMessageBuffer, // the weird ptrptr->ptr cast is intentional, see FORMAT_MESSAGE_ALLOCATE_BUFFER - 1024, NULL); - MessageBox(GetDesktopWindow(),pMessageBuffer,_T(ERRORBOX_TITLE),MB_OK); - wdxdisplay_cat.fatal() << "System error msg: " << pMessageBuffer << endl; - LocalFree( pMessageBuffer ); -} - -//#if defined(NOTIFY_DEBUG) || defined(DO_PSTATS) -#ifdef _DEBUG -extern void dbgPrintVidMem(LPDIRECTDRAW7 pDD, LPDDSCAPS2 lpddsCaps,const char *pMsg) { - DWORD dwTotal,dwFree; - HRESULT hr; - - // These Caps bits arent allowed to be specified when calling GetAvailVidMem. - // They don't affect surface allocation in a vram heap. - -#define AVAILVIDMEM_BADCAPS (DDSCAPS_BACKBUFFER | \ - DDSCAPS_FRONTBUFFER | \ - DDSCAPS_COMPLEX | \ - DDSCAPS_FLIP | \ - DDSCAPS_OWNDC | \ - DDSCAPS_PALETTE | \ - DDSCAPS_SYSTEMMEMORY | \ - DDSCAPS_VISIBLE | \ - DDSCAPS_WRITEONLY) - - DDSCAPS2 ddsCaps = *lpddsCaps; - ddsCaps.dwCaps &= ~(AVAILVIDMEM_BADCAPS); // turn off the bad caps -// ddsCaps.dwCaps |= DDSCAPS_VIDEOMEMORY; done internally by DX anyway - - if(FAILED( hr = pDD->GetAvailableVidMem(&ddsCaps,&dwTotal,&dwFree))) { - wdxdisplay_cat.debug() << "GetAvailableVidMem failed : result = " << ConvD3DErrorToString(hr) << endl; - exit(1); - } - - // Write a debug message to the console reporting the texture memory. - char tmpstr[100],tmpstr2[100]; - sprintf(tmpstr,"%.4g",dwTotal/1000000.0); - sprintf(tmpstr2,"%.4g",dwFree/1000000.0); - if(wdxdisplay_cat.is_debug()) - wdxdisplay_cat.debug() << "AvailableVidMem before creating "<< pMsg << ",(megs) total: " << tmpstr << " free:" << tmpstr2 <DestroyMe(bAtExitFnCalled); - } -} - -void AtExitFn() { -#ifdef _DEBUG - wdxdisplay_cat.spam() << "AtExitFn called\n"; -#endif - - restore_global_parameters(); - - DestroyAllWindows(true); -} - -//////////////////////////////////////////////////////////////////// -// Function: wdxGraphicsWindow::set_window_handle -// Access: Public -// Description: This is called on the object once the actual Window -// has been created. It gives the window handle of the -// created window so the wdxGraphicsWindow object can -// perform any additional initialization based on this. -//////////////////////////////////////////////////////////////////// -void wdxGraphicsWindow:: -set_window_handle(HWND hwnd) { - // Tell the associated dxGSG about the window handle. - _dxgsg->scrn.hWnd = hwnd; - - // Determine the initial open status of the IME. - _ime_open = false; - _ime_active = false; - HIMC hIMC = ImmGetContext(hwnd); - if (hIMC != 0) { - _ime_open = (ImmGetOpenStatus(hIMC) != 0); - ImmReleaseContext(hwnd, hIMC); - } -} - -//////////////////////////////////////////////////////////////////// -// Function: static_window_proc -// Access: -// Description: -//////////////////////////////////////////////////////////////////// -LONG WINAPI static_window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) { - HWND_PANDAWIN_MAP::iterator pwin; - pwin=hwnd_pandawin_map.find(hwnd); - - if(pwin!=hwnd_pandawin_map.end()) { - wdxGraphicsWindow *wdxwinptr=(*pwin).second; - return wdxwinptr->window_proc(hwnd, msg, wparam, lparam); - } else if(global_wdxwinptr!=NULL){ - // this stuff should only be used during CreateWindow() - return global_wdxwinptr->window_proc(hwnd, msg, wparam, lparam); - } else { - // should never need this?? (maybe at shutdwn?) - return DefWindowProc(hwnd, msg, wparam, lparam); - } -} - -// Note: could use _TrackMouseEvent in comctrl32.dll (part of IE 3.0+) which emulates -// TrackMouseEvent on w95, but that requires another 500K of memory to hold that DLL, -// which is lame just to support w95, which probably has other issues anyway -INLINE void wdxGraphicsWindow:: -track_mouse_leaving(HWND hwnd) { - if(_pParentWindowGroup->_pfnTrackMouseEvent==NULL) - return; - - TRACKMOUSEEVENT tme = {sizeof(TRACKMOUSEEVENT),TME_LEAVE,hwnd,0}; - BOOL bSucceeded = _pParentWindowGroup->_pfnTrackMouseEvent(&tme); // tell win32 to post WM_MOUSELEAVE msgs - - if((!bSucceeded) && wdxdisplay_cat.is_debug()) - wdxdisplay_cat.debug() << "TrackMouseEvent failed!, LastError=" << GetLastError() << endl; - - _tracking_mouse_leaving=true; -} - -//////////////////////////////////////////////////////////////////// -// Function: window_proc -// Access: -// Description: -//////////////////////////////////////////////////////////////////// -LONG wdxGraphicsWindow:: -window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) { - int button = -1; - int x, y, width, height; - - switch(msg) { - case WM_PAINT: { - PAINTSTRUCT ps; - BeginPaint(hwnd, &ps); - if(DXREADY) - _dxgsg->show_frame(); - EndPaint(hwnd, &ps); - return 0; - } - - case WM_MOUSEMOVE: - if(!DXREADY) - break; - - // Win32 doesn't return the same numbers as X does when the mouse - // goes beyond the upper or left side of the window - #define SET_MOUSE_COORD(iVal,VAL) { \ - iVal = VAL; \ - if(iVal & 0x8000) \ - iVal -= 0x10000; \ - } - - if(!_tracking_mouse_leaving) { - // need to re-call TrackMouseEvent every time mouse re-enters window - track_mouse_leaving(hwnd); - } - - SET_MOUSE_COORD(x,LOWORD(lparam)); - SET_MOUSE_COORD(y,HIWORD(lparam)); - - handle_mouse_motion(x, y); - return 0; - - // if cursor is invisible, make it visible when moving in the window bars,etc - case WM_NCMOUSEMOVE: { - if(!_props._bCursorIsVisible) { - if(!_cursor_in_windowclientarea) { - ShowCursor(true); - _cursor_in_windowclientarea=true; - } - } - break; - } - - case WM_NCMOUSELEAVE: { - if(!_props._bCursorIsVisible) { - ShowCursor(false); - _cursor_in_windowclientarea=false; - } - break; - } - - case WM_MOUSELEAVE: { - // wdxdisplay_cat.fatal() << "XXXXX WM_MOUSELEAVE received\n"; - - _tracking_mouse_leaving=false; - handle_mouse_entry(false,0,0); - break; - } - - case WM_CREATE: { - track_mouse_leaving(hwnd); - - _cursor_in_windowclientarea=false; - if(!_props._bCursorIsVisible) - ShowCursor(false); - break; - } - - case WM_IME_NOTIFY: - if (wparam == IMN_SETOPENSTATUS) { - HIMC hIMC = ImmGetContext(hwnd); - nassertr(hIMC != 0, 0); - _ime_open = (ImmGetOpenStatus(hIMC) != 0); - if (!_ime_open) { - _ime_active = false; // Sanity enforcement. - } - ImmReleaseContext(hwnd, hIMC); - } - break; - - case WM_IME_STARTCOMPOSITION: - // In case we're running fullscreen mode, we have to turn on - // explicit DX support for overlay windows now, so we'll be able - // to see the IME window. - _dxgsg->support_overlay_window(true); - _ime_active = true; - break; - - case WM_IME_ENDCOMPOSITION: - // Turn off the support for overlay windows, since we're done - // with the IME window for now and it just slows things down. - _dxgsg->support_overlay_window(false); - _ime_active = false; - break; - - case WM_IME_COMPOSITION: - if (lparam & GCS_RESULTSTR) { - if (!_input_devices.empty()) { - HIMC hIMC = ImmGetContext(hwnd); - nassertr(hIMC != 0, 0); - - static const int max_ime_result = 128; - static char ime_result[max_ime_result]; - - if (_ime_composition_w) { - // Since ImmGetCompositionStringA() doesn't seem to work - // for Win2000 (it always returns question mark - // characters), we have to use ImmGetCompositionStringW() - // on this OS. This is actually the easier of the two - // functions to use. - - DWORD result_size = - ImmGetCompositionStringW(hIMC, GCS_RESULTSTR, - ime_result, max_ime_result); - - // Add this string into the text buffer of the application. - - // ImmGetCompositionStringW() returns a string, but it's - // filled in with wstring data: every two characters defines a - // 16-bit unicode char. The docs aren't clear on the - // endianness of this. I guess it's safe to assume all Win32 - // machines are little-endian. - for (DWORD i = 0; i < result_size; i += 2) { - int result = - ((int)(unsigned char)ime_result[i + 1] << 8) | - (unsigned char)ime_result[i]; - _input_devices[0].keystroke(result); - } - } else { - // On the other hand, ImmGetCompositionStringW() doesn't - // work on Win95 or Win98; for these OS's we must use - // ImmGetCompositionStringA(). - DWORD result_size = - ImmGetCompositionStringA(hIMC, GCS_RESULTSTR, - ime_result, max_ime_result); - - // ImmGetCompositionStringA() returns an encoded ANSI - // string, which we now have to map to wide-character - // Unicode. - static const int max_wide_result = 128; - static wchar_t wide_result[max_wide_result]; - - int wide_size = - MultiByteToWideChar(CP_ACP, 0, - ime_result, result_size, - wide_result, max_wide_result); - if (wide_size == 0) { - PrintErrorMessage(LAST_ERROR); - } - for (int i = 0; i < wide_size; i++) { - _input_devices[0].keystroke(wide_result[i]); - } - } - - ImmReleaseContext(hwnd, hIMC); - } - return 0; - } - break; - - case WM_CHAR: - // Ignore WM_CHAR messages if we have the IME open, since - // everything will come in through WM_IME_COMPOSITION. (It's - // supposed to come in through WM_CHAR, too, but there seems to - // be a bug in Win2000 in that it only sends question mark - // characters through here.) - if (!_ime_open && !_input_devices.empty()) { - _input_devices[0].keystroke(wparam); - } - break; - - case WM_SYSKEYDOWN: { - // Alt and F10 are sent as WM_SYSKEYDOWN instead of WM_KEYDOWN - // want to use defwindproc on Alt syskey so std windows cmd Alt-F4 works, etc - POINT point; - GetCursorPos(&point); - ScreenToClient(hwnd, &point); - handle_keypress(lookup_key(wparam), point.x, point.y); - if (wparam == VK_F10) { - //bypass default windproc F10 behavior (it activates the main menu, but we have none) - return 0; - } - } - break; - - case WM_SYSCOMMAND: - if(wparam==SC_KEYMENU) { - // if Alt is released (alone w/o other keys), defwindproc will send - // this command, which will 'activate' the title bar menu (we have none) - // and give focus to it. we dont want this to happen, so kill this msg - return 0; - } - break; - - case WM_KEYDOWN: { - POINT point; - GetCursorPos(&point); - ScreenToClient(hwnd, &point); - handle_keypress(lookup_key(wparam), point.x, point.y); - - // Handle Cntrl-V paste from clipboard. Is there a better way - // to detect this hotkey? - if ((wparam=='V') && (GetKeyState(VK_CONTROL) < 0) && - !_input_devices.empty()) { - HGLOBAL hglb; - char *lptstr; - - if (!IsClipboardFormatAvailable(CF_TEXT)) - return 0; - - if (!OpenClipboard(NULL)) - return 0; - - // Maybe we should support CF_UNICODETEXT if it is available - // too? - hglb = GetClipboardData(CF_TEXT); - if (hglb!=NULL) { - lptstr = (char *) GlobalLock(hglb); - if (lptstr != NULL) { - char *pChar; - for(pChar=lptstr;*pChar!=NULL;pChar++) { - _input_devices[0].keystroke((uchar)*pChar); - } - GlobalUnlock(hglb); - } - } - CloseClipboard(); - } - break; - } - - case WM_SYSKEYUP: - case WM_KEYUP: - handle_keyrelease(lookup_key(wparam)); - break; - - case WM_LBUTTONDOWN: - button = 0; - case WM_MBUTTONDOWN: - if(button < 0) - button = 1; - case WM_RBUTTONDOWN: - if(!DXREADY) - break; - - if(button < 0) - button = 2; - SetCapture(hwnd); - SET_MOUSE_COORD(x,LOWORD(lparam)); - SET_MOUSE_COORD(y,HIWORD(lparam)); - handle_keypress(MouseButton::button(button), x, y); - return 0; - - case WM_LBUTTONUP: - button = 0; - case WM_MBUTTONUP: - if(button < 0) - button = 1; - case WM_RBUTTONUP: - if(!DXREADY) - break; - - if(button < 0) - button = 2; - ReleaseCapture(); - #if 0 - SET_MOUSE_COORD(x,LOWORD(lparam)); - SET_MOUSE_COORD(y,HIWORD(lparam)); - #endif - handle_keyrelease(MouseButton::button(button)); - return 0; - - case WM_MOVE: - if(!DXREADY) - break; - handle_window_move(LOWORD(lparam), HIWORD(lparam) ); - return 0; - - case WM_EXITSIZEMOVE: - #ifdef _DEBUG - wdxdisplay_cat.spam() << "WM_EXITSIZEMOVE received" << endl; - #endif - - if(_WindowAdjustingType==Resizing) { - handle_reshape(true); - } - - _WindowAdjustingType = NotAdjusting; - return 0; - - case WM_ENTERSIZEMOVE: { - if(_dxgsg!=NULL) - _dxgsg->SetDXReady(true); // dont disable here because I want to see pic as I resize - _WindowAdjustingType = MovingOrResizing; - } - break; - - case WM_DISPLAYCHANGE: { - #ifdef _DEBUG - width = LOWORD(lparam); height = HIWORD(lparam); - DWORD newbitdepth=wparam; - wdxdisplay_cat.spam() <<"WM_DISPLAYCHANGE received with width:" << width << " height: " << height << " bpp: " << wparam<< endl; - #endif - - // unfortunately this doesnt seem to work because RestoreAllSurfaces doesn't - // seem to think we're back in the original displaymode even after I've received - // the WM_DISPLAYCHANGE msg, and returns WRONGMODE error. So the only way I can - // think of to make this work is to have the timer periodically check for restored - // coop level - - // if(_props._fullscreen && !_window_active) { - // if(_dxgsg!=NULL) - // _dxgsg->CheckCooperativeLevel(DO_REACTIVATE_WINDOW); - // else reactivate_window(); - // } - - // does the windowed case handle displaychange properly? no. need to recreate all devices - } - break; - - case WM_SIZE: { - #ifdef _DEBUG - { - width = LOWORD(lparam); height = HIWORD(lparam); - wdxdisplay_cat.spam() << "WM_SIZE received with width:" << width << " height: " << height << " flags: " << - ((wparam == SIZE_MAXHIDE)? "SIZE_MAXHIDE " : "") << ((wparam == SIZE_MAXSHOW)? "SIZE_MAXSHOW " : "") << - ((wparam == SIZE_MINIMIZED)? "SIZE_MINIMIZED " : "") << ((wparam == SIZE_RESTORED)? "SIZE_RESTORED " : "") << - ((wparam == SIZE_MAXIMIZED)? "SIZE_MAXIMIZED " : "") << endl; - } - #endif - // old comment -- added SIZE_RESTORED to handle 3dfx case - if(dx_full_screen || ((_dxgsg==NULL) || (_dxgsg->scrn.hWnd==NULL)) || ((wparam != SIZE_RESTORED) && (wparam != SIZE_MAXIMIZED))) - break; - - width = LOWORD(lparam); height = HIWORD(lparam); - - if((_props._xsize != width) || (_props._ysize != height)) { - _WindowAdjustingType = Resizing; - - // for maximized,unmaximize, need to call resize code artificially - // since no WM_EXITSIZEMOVE is generated. - if(wparam==SIZE_MAXIMIZED) { - _bSizeIsMaximized=TRUE; - window_proc(hwnd, WM_EXITSIZEMOVE, 0x0,0x0); - } else if((wparam==SIZE_RESTORED) && _bSizeIsMaximized) { - _bSizeIsMaximized=FALSE; // only want to reinit dx if restoring from maximized state - window_proc(hwnd, WM_EXITSIZEMOVE, 0x0,0x0); - } - } - - break; - } - - case WM_SETFOCUS: { - if(!DXREADY) { - break; - } - - POINT point; - GetCursorPos(&point); - ScreenToClient(hwnd, &point); - - // this is a hack to make sure common modifier keys have proper state - // since at focus loss, app may never receive key-up event corresponding to - // a key-down. it would be better to know the exact set of ModifierButtons the - // user is using, since we may miss some here - - int i; - for(i=0;iflags << endl; - break; - } - - case WM_GETMINMAXINFO: - wdxdisplay_cat.spam() << "WM_GETMINMAXINFO received\n" << endl; - break; -#endif - - case WM_ERASEBKGND: - // WM_ERASEBKGND will be ignored during resizing, because - // we dont want to redraw as user is manually resizing window - if(_WindowAdjustingType) - break; - return 0; // dont let GDI waste time redrawing the deflt background - - case WM_TIMER: - // 2 cases of app deactivation: - // - // 1) user has switched out of fullscreen mode - // this is first signalled when ACTIVATEAPP returns false - // for this case, we dont wake up until WM_SIZE returns restore or maximize - // and WM_TIMER just periodically reawakens app for idle processing - - // unfortunately this doesnt seem to work because RestoreAllSurfaces doesn't - // seem to think we're back in the original displaymode even after I've received - // the WM_DISPLAYCHANGE msg, and returns WRONGMODE error. So the only way I can - // think of to make this work is to have the timer periodically check for restored - // coop level, as it does in case 2) - - // - // 2) windowed app has lost access to dx because another app has taken dx exclusive mode - // here we rely on WM_TIMER to periodically check if it is ok to reawaken app. - // windowed apps currently run regardless of if its window is in the foreground - // so we cannot rely on window messages to reawaken app - - if((wparam==_PandaPausedTimer) && (!_window_active||_active_minimized_fullscreen)) { - assert(_dxgsg!=NULL); - _dxgsg->CheckCooperativeLevel(DO_REACTIVATE_WINDOW); - - // wdxdisplay_cat.spam() << "periodic return of control to app\n"; - _return_control_to_app = true; - // throw_event("PandaPaused"); - // do we still need to do this since I return control to app periodically using timer msgs? - // does app need to know to avoid major computation? - } - return 0; - - case WM_CLOSE: - // close_window(); - delete _pParentWindowGroup; - - // BUGBUG: right now there is no way to tell the panda app the graphics window is invalid or - // has been closed by the user, to prevent further methods from being called on the window. - // this needs to be added to panda for multiple windows to work. in the meantime, just - // trigger an exit here if # windows==0, since that is the expected behavior when all - // windows are closed (should be done by the app though, and it assumes you only make this - // type of panda gfx window) - - if(hwnd_pandawin_map.size()==0) { - exit(0); - } - return 0; - - - case WM_ACTIVATEAPP: { - #ifdef _DEBUG - wdxdisplay_cat.spam() << "WM_ACTIVATEAPP(" << (bool)(wparam!=0) <<") received\n"; - #endif - - if((!wparam) && _props._fullscreen) { - deactivate_window(); - return 0; - } // dont want to reactivate until window is actually un-minimized (see WM_SIZE) - break; - } - } - - return DefWindowProc(hwnd, msg, wparam, lparam); -} - - -//////////////////////////////////////////////////////////////////// -// Function: handle_reshape -// Access: -// Description: -//////////////////////////////////////////////////////////////////// -void wdxGraphicsWindow::handle_reshape(bool bDoDxReset) { - - GdiFlush(); - - if(bDoDxReset && _dxgsg!=NULL) { - HRESULT hr; - - if(_dxgsg->scrn.pddsBack==NULL) { - //assume this is initial creation reshape and ignore this call - return; - } - - // Clear the back/primary surface to black - DX_DECLARE_CLEAN(DDBLTFX, bltfx) - bltfx.dwDDFX |= DDBLTFX_NOTEARING; - hr = _dxgsg->scrn.pddsPrimary->Blt(NULL,NULL,NULL,DDBLT_COLORFILL | DDBLT_WAIT,&bltfx); - if(FAILED( hr )) { - wdxdisplay_cat.fatal() << "Blt to Black of Primary Surf failed! : result = " << ConvD3DErrorToString(hr) << endl; - exit(1); - } - - if(FAILED(hr = _dxgsg->scrn.pDD->TestCooperativeLevel())) { - wdxdisplay_cat.error() << "TestCooperativeLevel failed : result = " << ConvD3DErrorToString(hr) << endl; - return; - } - - _dxgsg->SetDXReady(false); // disable rendering whilst we mess with surfs - - _dxgsg->RestoreAllVideoSurfaces(); - - // Want to change rendertarget size without destroying d3d device. To save vid memory - // (and make resizing work on memory-starved 4MB cards), we need to construct - // a temporary mini-sized render target for the d3d device (it cannot point to a - // NULL rendertarget) before creating the fully resized buffers. The old - // rendertargets will be freed when these temp targets are set, and that will give - // us the memory to create the resized target - - LPDIRECTDRAWSURFACE7 pddsDummy = NULL, pddsDummyZ = NULL; - ULONG refcnt; - - DX_DECLARE_CLEAN( DDSURFACEDESC2, ddsd ); - - _dxgsg->scrn.pddsBack->GetSurfaceDesc(&ddsd); - LPDIRECTDRAW7 pDD = _dxgsg->scrn.pDD; - - ddsd.dwFlags &= ~DDSD_PITCH; - ddsd.dwWidth = 1; ddsd.dwHeight = 1; - ddsd.ddsCaps.dwCaps &= ~(DDSCAPS_COMPLEX | DDSCAPS_FLIP | DDSCAPS_FRONTBUFFER | DDSCAPS_BACKBUFFER); - - PRINTVIDMEM(pDD,&ddsd.ddsCaps,"dummy backbuf"); - - if(FAILED( hr = pDD->CreateSurface( &ddsd, &pddsDummy, NULL ) )) { - wdxdisplay_cat.fatal() << "Resize CreateSurface for temp backbuf failed : result = " << ConvD3DErrorToString(hr) << endl; - exit(1); - } - - if(_dxgsg->scrn.pddsZBuf!=NULL) { - DX_DECLARE_CLEAN( DDSURFACEDESC2, ddsdZ ); - _dxgsg->scrn.pddsZBuf->GetSurfaceDesc(&ddsdZ); - ddsdZ.dwFlags &= ~DDSD_PITCH; - ddsdZ.dwWidth = 1; ddsdZ.dwHeight = 1; - - PRINTVIDMEM(pDD,&ddsdZ.ddsCaps,"dummy zbuf"); - - if(FAILED( hr = pDD->CreateSurface( &ddsdZ, &pddsDummyZ, NULL ) )) { - wdxdisplay_cat.fatal() << "Resize CreateSurface for temp zbuf failed : result = " << ConvD3DErrorToString(hr) << endl; - exit(1); - } - - if(FAILED( hr = pddsDummy->AddAttachedSurface( pddsDummyZ ) )) { - wdxdisplay_cat.fatal() << "Resize AddAttachedSurf for temp zbuf failed : result = " << ConvD3DErrorToString(hr) << endl; - exit(1); - } - } - - if(FAILED( hr = _dxgsg->scrn.pD3DDevice->SetRenderTarget( pddsDummy, 0x0 ))) { - wdxdisplay_cat.fatal() - << "Resize failed to set render target to temporary surface, result = " << ConvD3DErrorToString(hr) << endl; - exit(1); - } - RELEASE(pddsDummyZ,wdxdisplay,"dummy resize zbuffer",false); - RELEASE(pddsDummy,wdxdisplay,"dummy resize rendertarget buffer",false); - } - - RECT view_rect; - - assert(!dx_full_screen); - - HWND hWnd=_dxgsg->scrn.hWnd; - GetClientRect( hWnd, &view_rect ); - ClientToScreen( hWnd, (POINT*)&view_rect.left ); // translates top,left pnt - ClientToScreen( hWnd, (POINT*)&view_rect.right ); // translates right,bottom pnt - - // change _props xsize,ysize - resized((view_rect.right - view_rect.left),(view_rect.bottom - view_rect.top)); - - _props._xorg = view_rect.left; // _props origin should reflect upper left of view rectangle - _props._yorg = view_rect.top; - - if(wdxdisplay_cat.is_spam()) { - wdxdisplay_cat.spam() << "reshape to origin: (" << _props._xorg << "," << _props._yorg << "), size: (" << _props._xsize << "," << _props._ysize << ")\n"; - } - - if(_dxgsg!=NULL) { - if(bDoDxReset) - _dxgsg->dx_setup_after_resize(view_rect,hWnd); // create the new resized rendertargets - _dxgsg->SetDXReady(true); - } -} - -void wdxGraphicsWindow::deactivate_window(void) { - // current policy is to suspend minimized or deactivated fullscreen windows, but leave - // regular windows running normally - - if(!_window_active || _exiting_window || _active_minimized_fullscreen) { - #ifdef _DEBUG - if(wdxdisplay_cat.is_spam()) - wdxdisplay_cat.spam() << "deactivate_window called, but ignored in current mode\n"; - #endif - return; - } - - if(bResponsive_minimized_fullscreen_window) { - if(wdxdisplay_cat.is_spam()) - wdxdisplay_cat.spam() << "WDX fullscreen window switching to active minimized mode...\n"; - _active_minimized_fullscreen = true; - } else { - - if(wdxdisplay_cat.is_spam()) - wdxdisplay_cat.spam() << "WDX window deactivated, waiting...\n"; - - _window_active = false; - } - - if(_props._fullscreen) { - // make sure window is minimized - - WINDOWPLACEMENT wndpl; - wndpl.length=sizeof(WINDOWPLACEMENT); - if(!GetWindowPlacement(_dxgsg->scrn.hWnd,&wndpl)) { - wdxdisplay_cat.error() << "GetWindowPlacement failed!\n"; - return; - } - - if((wndpl.showCmd!=SW_MINIMIZE)&&(wndpl.showCmd!=SW_SHOWMINIMIZED)) { - ShowWindow(_dxgsg->scrn.hWnd, SW_MINIMIZE); - } - - throw_event("PandaPaused"); // right now this is used to signal python event handler to disable audio - } - -// if(!bResponsive_minimized_fullscreen_window) { - // need this even in responsive-mode to trigger the dxgsg check of cooplvl, i think? - - _PandaPausedTimer = SetTimer(_dxgsg->scrn.hWnd,PAUSED_TIMER_ID,500,NULL); - if(_PandaPausedTimer!=PAUSED_TIMER_ID) { - wdxdisplay_cat.error() << "Error in SetTimer!\n"; - } -// } -} - -void wdxGraphicsWindow::reactivate_window(void) { - if(!_window_active) { - - // first see if dx cooperative level is OK for reactivation - // if(!_dxgsg->CheckCooperativeLevel()) - // return; - - if(wdxdisplay_cat.is_spam()) - wdxdisplay_cat.spam() << "WDX window re-activated...\n"; - - _window_active = true; - - if(_PandaPausedTimer!=NULL) { - KillTimer(_dxgsg->scrn.hWnd,_PandaPausedTimer); - _PandaPausedTimer = NULL; - } - - // move window to top of zorder - // if(_props._fullscreen) - // SetWindowPos(_DisplayDataArray[0].hWnd, HWND_TOP, 0,0,0,0, SWP_NOMOVE | SWP_NOSENDCHANGING | SWP_NOSIZE | SWP_NOOWNERZORDER); - GdiFlush(); - - } else if(_active_minimized_fullscreen) { - if(wdxdisplay_cat.is_spam()) - wdxdisplay_cat.spam() << "WDX window unminimized from active-minimized state...\n"; - - if(_PandaPausedTimer!=NULL) { - KillTimer(_dxgsg->scrn.hWnd,_PandaPausedTimer); - _PandaPausedTimer = NULL; - } - - _active_minimized_fullscreen = false; - - // move window to top of zorder - // if(_props._fullscreen) - // SetWindowPos(_DisplayDataArray[0].hWnd, HWND_TOP, 0,0,0,0, SWP_NOMOVE | SWP_NOSENDCHANGING | SWP_NOSIZE | SWP_NOOWNERZORDER); - GdiFlush(); - } - - if(_props._fullscreen) { - throw_event("PandaRestarted"); // right now this is used to signal python event handler to re-enable audio - } -} - -//////////////////////////////////////////////////////////////////// -// Function: Constructor -// Access: -// Description: -//////////////////////////////////////////////////////////////////// -wdxGraphicsWindow::wdxGraphicsWindow(GraphicsPipe* pipe) : GraphicsWindow(pipe) { - _ime_active = false; - _pParentWindowGroup=NULL; - _pParentWindowGroup=new wdxGraphicsWindowGroup(this); -} - -//////////////////////////////////////////////////////////////////// -// Function: Constructor -// Access: -// Description: -//////////////////////////////////////////////////////////////////// -wdxGraphicsWindow::wdxGraphicsWindow(GraphicsPipe* pipe, const GraphicsWindow::Properties& props) - : GraphicsWindow(pipe, props) { - _ime_open = false; - _pParentWindowGroup=NULL; - _pParentWindowGroup=new wdxGraphicsWindowGroup(this); -} - -bool supports_color_cursors(DDDEVICEIDENTIFIER2 &DevID) { - // TODO: add more cards as more testing is done - if(IS_NVIDIA(DevID)) { - // all nvidia seem to support 256 color - return true; - } else if(IS_ATI(DevID)) { - // radeons seem to be in the 5100 range and support color, assume anything in 6000 or above - // is newer than radeon and supports 256 color - if(((DevID.dwDeviceId>=0x5100) && (DevID.dwDeviceId<=0x5200)) || - (DevID.dwDeviceId>=0x6000)) - return true; - } else if IS_MATROX(DevID) { - if(DevID.dwDeviceId==0x0525) // G400 seems to support color cursors, havent tested other matrox - return true; - } - - return false; -} - -void wdxGraphicsWindowGroup::CreateWindows(void) { - HINSTANCE hProgramInstance = GetModuleHandle(NULL); - WNDCLASS wc; - static bool wc_registered = false; - _hParentWindow = NULL; - - // these fns arent defined on win95, so get dynamic ptrs to them to avoid - // ugly DLL loader failures on w95 - HINSTANCE hUser32 = (HINSTANCE) LoadLibrary("user32.dll"); - assert(hUser32); - - _pfnGetMonitorInfo = (PFN_GETMONITORINFO) GetProcAddress(hUser32, "GetMonitorInfoA"); - _pfnTrackMouseEvent = (PFN_TRACKMOUSEEVENT) GetProcAddress(hUser32, "TrackMouseEvent"); - FreeLibrary(hUser32); - - // Clear before filling in window structure! - ZeroMemory(&wc, sizeof(WNDCLASS)); - wc.style = CS_HREDRAW | CS_VREDRAW; //CS_OWNDC; - wc.lpfnWndProc = (WNDPROC) static_window_proc; - wc.hInstance = hProgramInstance; - - string windows_icon_filename = get_icon_filename().to_os_specific(); - string windows_mono_cursor_filename = get_mono_cursor_filename().to_os_specific(); - string windows_color_cursor_filename = get_color_cursor_filename().to_os_specific(); - - if(!windows_icon_filename.empty()) { - // Note: LoadImage seems to cause win2k internal heap corruption (outputdbgstr warnings) - // if icon is more than 8bpp - - // loads a .ico fmt file - wc.hIcon = (HICON) LoadImage(NULL, windows_icon_filename.c_str(), IMAGE_ICON, 0, 0, LR_LOADFROMFILE ); - - if(wc.hIcon==NULL) { - wdxdisplay_cat.warning() << "windows icon filename '" << windows_icon_filename << "' not found!!\n"; - } - } else { - wc.hIcon = NULL; // use default app icon - } - - _bLoadedCustomCursor=false; - _hMouseCursor=NULL; - - if(!windows_color_cursor_filename.empty()) { - // card support for full color non-black/white GDI cursors varies greatly. if the cursor is not supported, - // it is rendered in software by GDI, which causes a flickering effect (because it's not synced - // with flip?). GDI transparently masks the lack of HW support so there is no easy way for app to detect - // if HW cursor support exists. alternatives are to tie cursor motion to frame rate using DDraw blts - // or overlays (this is done automatically by DX8 runtime mouse cursor support), or to have separate thread draw cursor - // (sync issues?). instead we do mono cursor unless card is known to support 256 color cursors - bool bSupportsColorCursor=true; - - /* if any card doesnt support color, dont load it*/ - for(DWORD w=0;w<_windows.size();w++) - bSupportsColorCursor &= supports_color_cursors(_windows[w]->_dxgsg->scrn.DXDeviceID); - - if(bSupportsColorCursor) { - DWORD load_flags = LR_LOADFROMFILE; - - if(dx_full_screen) { - // I think cursors should use LR_CREATEDIBSECTION since they should not be mapped to the device palette (in the case of 256-color cursors) - // since they are not going to be used on the desktop - load_flags |= LR_CREATEDIBSECTION; - } - - // Note: LoadImage seems to cause win2k internal heap corruption (outputdbgstr warnings) - // if icon is more than 8bpp - - // loads a .cur fmt file. - _hMouseCursor = (HCURSOR) LoadImage(NULL, windows_color_cursor_filename.c_str(), IMAGE_CURSOR, 0, 0, load_flags ); - - if(_hMouseCursor==NULL) { - wdxdisplay_cat.warning() << "windows color cursor filename '" << windows_color_cursor_filename << "' not found!!\n"; - goto try_mono_cursor; - - } - -/* dont need these anymore since we are do mousestuff before window creation - SetClassLongPtr(_mwindow, GCLP_HCURSOR, (LONG_PTR) hNewMouseCursor); - SetCursor(hNewMouseCursor); - - if(_bLoadedCustomCursor) - DestroyCursor(_hMouseCursor); -*/ - _bLoadedCustomCursor=true; - } - } - - try_mono_cursor: - - if((!_bLoadedCustomCursor) && (!windows_mono_cursor_filename.empty())) { - // Note: LoadImage seems to cause win2k internal heap corruption (outputdbgstr warnings) - // if icon is more than 8bpp - - DWORD load_flags = LR_LOADFROMFILE; - - if(dx_full_screen) { - // I think cursors should use LR_CREATEDIBSECTION since they should not be mapped to the device palette (in the case of 256-color cursors) - // since they are not going to be used on the desktop - load_flags |= LR_CREATEDIBSECTION; - } - // loads a .cur fmt file. - _hMouseCursor = (HCURSOR) LoadImage(NULL, windows_mono_cursor_filename.c_str(), IMAGE_CURSOR, 0, 0, load_flags); - - if(_hMouseCursor==NULL) { - wdxdisplay_cat.warning() << "windows mono cursor filename '" << windows_mono_cursor_filename << "' not found!!\n"; - } else _bLoadedCustomCursor=true; - } - - if(!_bLoadedCustomCursor) - _hMouseCursor = LoadCursor(NULL, DEFAULT_CURSOR); - - if (!wc_registered) { - // We only need to register the window class once per session. - wc.hCursor = _hMouseCursor; - wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH); - wc.lpszMenuName = NULL; - wc.lpszClassName = WDX_WINDOWCLASSNAME; - - if(!RegisterClass(&wc)) { - wdxdisplay_cat.error() << "could not register window class!" << endl; - } - wc_registered = true; - } - - DWORD window_style = WS_POPUP | WS_SYSMENU; // for CreateWindow - - global_wdxwinptr = _windows[0]; // for use during createwin() bugbug look at this again - - // rect now contains the coords for the entire window, not the client - if(dx_full_screen) { - - // extra windows must be parented to the first so app doesnt minimize when user selects them - for(DWORD devnum=0;devnum<_windows.size();devnum++) { - MONITORINFO minfo; - ZeroMemory(&minfo, sizeof(MONITORINFO)); - minfo.cbSize = sizeof(MONITORINFO); - if(_pfnGetMonitorInfo!=NULL) - // get upper-left corner coords using GetMonitorInfo - (*_pfnGetMonitorInfo)(_windows[devnum]->_dxgsg->scrn.hMon, &minfo); - else { - minfo.rcMonitor.left = minfo.rcMonitor.top = 0; - } - - GraphicsWindow::Properties *props = &_windows[devnum]->_props; - - wdxdisplay_cat.info() << "opening " << props->_xsize << "x" << props->_ysize << " fullscreen window\n"; - - HWND hWin = CreateWindow(WDX_WINDOWCLASSNAME, props->_title.c_str(), - window_style, minfo.rcMonitor.left, minfo.rcMonitor.top, - props->_xsize,props->_ysize, - _hParentWindow, NULL, hProgramInstance, 0); - - if(!hWin) { - wdxdisplay_cat.fatal() << "CreateWindow failed for monitor " << devnum << "!, LastError=" << GetLastError() << endl; - #ifdef _DEBUG - PrintErrorMessage(LAST_ERROR); - #endif - exit(1); - } - - _windows[devnum]->set_window_handle(hWin); - if(devnum==0) { - _hParentWindow=hWin; - } - } - } else { - assert(_windows.size()==1); - - GraphicsWindow::Properties *props = &_windows[0]->_props; - - RECT win_rect; - SetRect(&win_rect, props->_xorg, props->_yorg, props->_xorg + props->_xsize, - props->_yorg + props->_ysize); - - if(props->_border) - window_style |= WS_OVERLAPPEDWINDOW; // should we just use WS_THICKFRAME instead? - - AdjustWindowRect(&win_rect, window_style, FALSE); //compute window size based on desired client area size - - // make sure origin is on screen - if(win_rect.left < 0) { - win_rect.right -= win_rect.left; win_rect.left = 0; - } - if(win_rect.top < 0) { - win_rect.bottom -= win_rect.top; win_rect.top = 0; - } - - UINT xsize = win_rect.right-win_rect.left; - UINT ysize = win_rect.bottom-win_rect.top; - - wdxdisplay_cat.info() << "opening " << props->_xsize << "x" << props->_ysize << " regular window\n"; - - _hParentWindow = - CreateWindow(WDX_WINDOWCLASSNAME, props->_title.c_str(), - window_style, win_rect.left, win_rect.top, xsize,ysize, - NULL, NULL, hProgramInstance, 0); - _windows[0]->set_window_handle(_hParentWindow); - } - - if(_hParentWindow==NULL) { - wdxdisplay_cat.fatal() << "CreateWindow failed!\n"; - exit(1); - } - - for(DWORD devnum=0;devnum<_windows.size();devnum++) { - wdxGraphicsWindow *pWDXWin = _windows[devnum]; - // for use by the window_proc - hwnd_pandawin_map[pWDXWin->_dxgsg->scrn.hWnd] = pWDXWin; - -/* - // DC is mostly used for writing fps meter (but also old palette code, which needs updating) - // probably only need to do this for devnum 0 - HDC hdc = GetDC(pWDXWin->_dxgsg_>scrn.hWnd); - pWDXWin->_dxgsg->Set_HDC(hdc); -*/ - } - - // now we can stop using the global_wdxwinptr crutch since windows are created - global_wdxwinptr = NULL; // get rid of any reference to this obj -} - -//////////////////////////////////////////////////////////////////// -// Function: config -// Access: -// Description: Set up win32 window. -//////////////////////////////////////////////////////////////////// -void wdxGraphicsWindow::config_window(wdxGraphicsWindowGroup *pParentGroup) { -// assert(_pParentWindowGroup==NULL); - _pParentWindowGroup=pParentGroup; - - GraphicsWindow::config(); - - _hdc = NULL; - _gsg = _dxgsg = NULL; - _exiting_window = false; - _window_active = true; - _return_control_to_app = false; - _active_minimized_fullscreen = false; - - if(dx_full_screen || _props._fullscreen) { - _props._fullscreen = dx_full_screen = true; - } - - _WindowAdjustingType = NotAdjusting; - _bSizeIsMaximized=FALSE; - - _gsg = _dxgsg = NULL; - // Create a GSG to manage the graphics - if(_gsg==NULL) { - make_gsg(); - if(_gsg==NULL) { - wdxdisplay_cat.error() << "make_gsg() failed!\n"; - exit(1); - } - } - _dxgsg = DCAST(DXGraphicsStateGuardian, _gsg); - - // Check the version of the OS we are running. If we are running - // win2000, we must use ImmGetCompositionStringW() to report the - // characters returned by the IME, since WM_CHAR and - // ImmGetCompositionStringA() both just return question marks. - // However, this function doesn't work for Win98; on this OS, we - // have to use ImmGetCompositionStringA() instead, which returns an - // encoded string in shift-jis (which we then have to decode). - - // For now, this is user-configurable, to allow testing of this code - // on both OS's. After we verify that truth of the above claim, we - // should base this decision on GetVersionEx() or maybe - // VerifyVersionInfo(). - _ime_composition_w = ime_composition_w; -} - -void wdxGraphicsWindow::finish_window_setup(void) { - // Now indicate that we have our keyboard/mouse device ready. - GraphicsWindowInputDevice device = GraphicsWindowInputDevice::pointer_and_keyboard("keyboard/mouse"); - _input_devices.push_back(device); - - // move windows to top of zorder - HWND hWin = _dxgsg->scrn.hWnd; - - SetWindowPos(hWin, HWND_TOP, 0,0,0,0, SWP_NOMOVE | SWP_NOSENDCHANGING | SWP_NOSIZE); - // call twice to override STARTUPINFO value, which may be set to hidden initially (by emacs for instance) - ShowWindow(hWin, SW_SHOWNORMAL); - ShowWindow(hWin, SW_SHOWNORMAL); - // UpdateWindow( _mwindow ); -} - - - -HRESULT CALLBACK EnumDevicesCallback(LPSTR pDeviceDescription, LPSTR pDeviceName, - LPD3DDEVICEDESC7 pD3DDeviceDesc,LPVOID pContext) { - D3DDEVICEDESC7 *pd3ddevs = (D3DDEVICEDESC7 *)pContext; -#ifdef _DEBUG - wdxdisplay_cat.spam() << "Enumerating Device " << pDeviceName << " : " << pDeviceDescription << endl; -#endif - - -#define REGHALIDX 0 -#define TNLHALIDX 1 -#define SWRASTIDX 2 - - if(IsEqualGUID(pD3DDeviceDesc->deviceGUID,IID_IDirect3DHALDevice)) { - CopyMemory(&pd3ddevs[REGHALIDX],pD3DDeviceDesc,sizeof(D3DDEVICEDESC7)); - } else if(IsEqualGUID(pD3DDeviceDesc->deviceGUID,IID_IDirect3DTnLHalDevice)) { - CopyMemory(&pd3ddevs[TNLHALIDX],pD3DDeviceDesc,sizeof(D3DDEVICEDESC7)); - } else if(IsEqualGUID(pD3DDeviceDesc->deviceGUID,IID_IDirect3DRGBDevice)) { - CopyMemory(&pd3ddevs[SWRASTIDX],pD3DDeviceDesc,sizeof(D3DDEVICEDESC7)); - } - return DDENUMRET_OK; -} - -#define MAX_DISPLAY_MODES 100 // probably dont need this much, since i already screen for width&hgt -typedef struct { - DWORD maxWidth,maxHeight; - DWORD supportedBitDepths; // uses DDBD_* flags - LPDDSURFACEDESC2 pDDSD_Arr; - DWORD cNumSurfDescs; -} DisplayModeInfo; - -HRESULT WINAPI EnumDisplayModesCallBack(LPDDSURFACEDESC2 lpDDSurfaceDesc,LPVOID lpContext) { - DisplayModeInfo *pDMI = (DisplayModeInfo *) lpContext; - - // ddsd_search should assure this is true - assert((lpDDSurfaceDesc->dwWidth == pDMI->maxWidth) && (lpDDSurfaceDesc->dwHeight == pDMI->maxHeight)); - - // ignore refresh rates under 60Hz (and special values of 0 & 1) - if((lpDDSurfaceDesc->dwRefreshRate>1) && (lpDDSurfaceDesc->dwRefreshRate<60)) - return DDENUMRET_OK; - - assert(pDMI->cNumSurfDescs < MAX_DISPLAY_MODES); - memcpy( &(pDMI->pDDSD_Arr[pDMI->cNumSurfDescs]), lpDDSurfaceDesc, sizeof(DDSURFACEDESC2) ); - pDMI->cNumSurfDescs++; - pDMI->supportedBitDepths |= BitDepth_2_DDBDMask(lpDDSurfaceDesc->ddpfPixelFormat.dwRGBBitCount); - - return DDENUMRET_OK; -} - -/* -BOOL WINAPI DriverEnumCallback_Voodoo1( GUID* pGUID, TCHAR* strDesc,TCHAR* strName, - VOID *argptr, HMONITOR hm) { - - if(hm!=NULL) // skip over non-primary and non-voodoo-type display devices - return DDENUMRET_OK; - - GUID null_guid; - ZeroMemory(&null_guid,sizeof(GUID)); - - // primary display driver will have NULL guid - // ignore that and save any non-null value, which - // indicates a secondary driver, which is usually voodoo1/2 - if((pGUID!=NULL) && !IsEqualGUID(null_guid,*pGUID)) { - memcpy(argptr,pGUID,sizeof(GUID)); - } - - return DDENUMRET_OK; -} -*/ - -BOOL WINAPI save_devinfo( GUID* pGUID, TCHAR* strDesc,TCHAR* strName,VOID *argptr, HMONITOR hm) { - - DXDeviceInfoVec *pDevInfoArr = (DXDeviceInfoVec *) argptr; - - DXDeviceInfo devinfo; - ZeroMemory(&devinfo,sizeof(devinfo)); - - // primary display driver will have NULL guid - if(pGUID!=NULL) { - memcpy(&devinfo.guidDeviceIdentifier,pGUID,sizeof(GUID)); - } - if(strDesc!=NULL) { - _tcsncpy(devinfo.szDescription, - strDesc, - MAX_DDDEVICEID_STRING); - } - if(strName!=NULL) { - _tcsncpy(devinfo.szDriver,strName,MAX_DDDEVICEID_STRING); - } - devinfo.hMon=hm; - - pDevInfoArr->push_back(devinfo); - return DDENUMRET_OK; -} - -BOOL WINAPI DriverEnumCallback_MultiMon( GUID* pGUID, TCHAR* strDesc,TCHAR* strName,VOID *argptr, HMONITOR hm) { - if(hm==NULL) { - // skip over the 'primary' since it will duplicated later as an explicit device - return DDENUMRET_OK; - } - - return save_devinfo(pGUID,strDesc,strName,argptr,hm); -} - -bool wdxGraphicsWindow::resize(unsigned int xsize,unsigned int ysize) { - - if (!_props._fullscreen) { - if(wdxdisplay_cat.is_debug()) - wdxdisplay_cat.debug() << "resize("<scrn.hWnd, NULL, 0,0, xsize, ysize, SWP_NOZORDER | SWP_NOMOVE | SWP_NOSENDCHANGING); - // WM_ERASEBKGND will be ignored, because _WindowAdjustingType!=NotAdjusting because - // we dont want to redraw as user is manually resizing window, so need to force explicit - // background clear for the programmatic resize fn call - _WindowAdjustingType=NotAdjusting; - - // this doesnt seem to be working in toontown resize, so I put ddraw blackblt in handle_reshape instead - //window_proc(_mwindow, WM_ERASEBKGND,(WPARAM)_hdc,0x0); - handle_reshape(true); - return true; - } - - if(wdxdisplay_cat.is_info()) - wdxdisplay_cat.info() << "resize("<SetDXReady(false); - - HRESULT hr; - - DX_DECLARE_CLEAN(DDSURFACEDESC2,ddsd_curmode); - - if(FAILED(hr = _dxgsg->scrn.pDD->GetDisplayMode(&ddsd_curmode))) { - wdxdisplay_cat.fatal() << "resize() - GetDisplayMode failed, result = " << ConvD3DErrorToString(hr) << endl; - exit(1); - } - - DX_DECLARE_CLEAN(DDSURFACEDESC2,ddsd_search); - - ddsd_search.dwFlags = DDSD_HEIGHT | DDSD_WIDTH; - ddsd_search.dwWidth=xsize; ddsd_search.dwHeight=ysize; - - // not requesting same refresh rate since changing res might not support same refresh rate - - DDSURFACEDESC2 DDSD_Arr[MAX_DISPLAY_MODES]; - DisplayModeInfo DMI; - ZeroMemory(&DDSD_Arr,sizeof(DDSD_Arr)); - ZeroMemory(&DMI,sizeof(DMI)); - DMI.maxWidth=xsize; DMI.maxHeight=ysize; - DMI.pDDSD_Arr=DDSD_Arr; - - if(FAILED(hr = _dxgsg->scrn.pDD->EnumDisplayModes(DDEDM_REFRESHRATES,&ddsd_search,&DMI,EnumDisplayModesCallBack))) { - wdxdisplay_cat.fatal() << "resize() - EnumDisplayModes failed, result = " << ConvD3DErrorToString(hr) << endl; - return false; - } - - DMI.supportedBitDepths &= _dxgsg->scrn.D3DDevDesc.dwDeviceRenderBitDepth; - - DWORD dwFullScreenBitDepth; - DWORD requested_bpp=ddsd_curmode.ddpfPixelFormat.dwRGBBitCount; - - // would like to match current bpp first. if that is not possible, try 16bpp, then 32 - DWORD requested_bpp_DDBD = BitDepth_2_DDBDMask(requested_bpp); - - if(DMI.supportedBitDepths & requested_bpp_DDBD) { - dwFullScreenBitDepth=requested_bpp; - } else if(DMI.supportedBitDepths & DDBD_16) { - dwFullScreenBitDepth=16; - } else if(DMI.supportedBitDepths & DDBD_32) { - dwFullScreenBitDepth=32; - } else { - wdxdisplay_cat.error() - << "resize failed, no fullScreen resolutions at " << xsize << "x" << ysize << endl; - return false; - } - - if(FAILED(hr = _dxgsg->scrn.pDD->TestCooperativeLevel())) { - wdxdisplay_cat.error() << "TestCooperativeLevel failed : result = " << ConvD3DErrorToString(hr) << endl; - wdxdisplay_cat.error() << "Full screen app failed to get exclusive mode on resize, exiting..\n"; - return false; - } - - _dxgsg->free_dxgsg_objects(); - - // let driver choose default refresh rate (hopefully its >=60Hz) - if(FAILED( hr = _dxgsg->scrn.pDD->SetDisplayMode( xsize,ysize,dwFullScreenBitDepth, 0L, 0L ))) { - wdxdisplay_cat.error() << "resize failed to reset display mode to (" << xsize <<"x"<scrn.dwRenderWidth=xsize; - _dxgsg->scrn.dwRenderHeight=ysize; - - CreateScreenBuffersAndDevice(_dxgsg->scrn); - _dxgsg->RecreateAllVideoSurfaces(); - _dxgsg->SetDXReady(true); - return true; -} - - -// overrides of the general estimator for known working cases -bool wdxGraphicsWindow:: -special_check_fullscreen_resolution(UINT xsize,UINT ysize) { - // assert(IS_VALID_PTR(_dxgsg)); - - DWORD VendorId=_dxgsg->scrn.DXDeviceID.dwVendorId; - DWORD DeviceId=_dxgsg->scrn.DXDeviceID.dwDeviceId; - switch(VendorId) { - case 0x8086: // Intel - /*for now, just validate all the intel cards at these resolutions. - I dont have a complete list of deviceIDs (missing 82830, 845, etc) - // Intel i810,i815,82810 - if((DeviceId==0x7121)||(DeviceId==0x7123)||(DeviceId==0x7125)|| - (DeviceId==0x1132)) - */ - { - if((xsize==640)&&(ysize==480)) - return true; - if((xsize==800)&&(ysize==600)) - return true; - if((xsize==1024)&&(ysize==768)) - return true; - } - break; - } - - return false; -} - -unsigned int wdxGraphicsWindow:: -verify_window_sizes(unsigned int numsizes,unsigned int *dimen) { - DWORD num_valid_modes=0; - HRESULT hr; - - // not requesting same refresh rate since changing res might not support same refresh rate at new size - - DDSURFACEDESC2 DDSD_Arr[MAX_DISPLAY_MODES]; - DisplayModeInfo DMI; - DWORD i,*pCurDim=(DWORD *)dimen; - - for(i=0;iscrn.pDD->EnumDisplayModes(DDEDM_REFRESHRATES,&ddsd_search,&DMI,EnumDisplayModesCallBack))) { - wdxdisplay_cat.fatal() << "resize() - EnumDisplayModes failed, result = " << ConvD3DErrorToString(hr) << endl; - return 0; - } - - // get rid of bpp's we cant render at - DMI.supportedBitDepths &= _dxgsg->scrn.D3DDevDesc.dwDeviceRenderBitDepth; - - bool bIsGoodMode=false; - - if(DMI.supportedBitDepths & (DDBD_16 | DDBD_24 | DDBD_32)) { - if(special_check_fullscreen_resolution(xsize,ysize)) { - // bypass the test below for certain cards we know have valid modes - bIsGoodMode=true; - } else { - if(_dxgsg->scrn.bIsLowVidMemCard) - bIsGoodMode=(((float)xsize*(float)ysize)<=(float)(640*480)); - else { - // assume user is testing fullscreen, not windowed, so use the dwTotal value - // see if 3 scrnbufs (front/back/z)at 16bpp at xsize*ysize will fit with a few - // extra megs for texmem - - // 8MB Rage Pro says it has 6.8 megs Total free and will run at 1024x768, so - // formula makes it so that is OK - - #define REQD_TEXMEM 1800000.0f - - if(_dxgsg->scrn.MaxAvailVidMem==0) { - //assume buggy drivers return bad val of 0 and everything will be OK - bIsGoodMode=true; - } else { - bIsGoodMode = ((((float)xsize*(float)ysize)*6+REQD_TEXMEM) < (float)_dxgsg->scrn.MaxAvailVidMem); - } - } - } - } - - if(bIsGoodMode) - num_valid_modes++; - else { - pCurDim[0] = 0; - pCurDim[1] = 0; - } - } - - return num_valid_modes; -} - -/* -void wdxGraphicsWindow:: -check_for_color_cursor_support(void) { - // card support for non-black/white GDI cursors varies greatly. if the cursor is not supported, - // it is rendered in software by GDI, which causes a flickering effect (because it's not synced - // with flip?). GDI transparently masks what's happening so there is no easy way for app to detect - // if HW cursor support exists. alternatives are to tie cursor motion to frame rate using DDraw blts - // or overlays, or to have separate thread draw cursor (sync issues?). instead we do mono cursor - // unless card is known to support 256 color cursors - - string windows_color_cursor_filename = get_color_cursor_filename().to_os_specific(); - if(windows_color_cursor_filename.empty()) - return; - - bool bSupportsColorCursor=false; - - if(IS_NVIDIA(_DXDeviceID)) { - // all nvidia seem to support 256 color - bSupportsColorCursor=true; - } else if(IS_ATI(_DXDeviceID)) { - // radeons seem to be in the 5100 range and support color, assume anything in 6000 or above - // is newer than radeon and supports 256 color - if(((_DXDeviceID.dwDeviceId>=0x5100) && (_DXDeviceID.dwDeviceId<=0x5200)) || - (_DXDeviceID.dwDeviceId>=0x6000)) - bSupportsColorCursor=true; - } else if IS_MATROX(_DXDeviceID) { - if(_DXDeviceID.dwDeviceId==0x0525) // G400 seems to support color cursors, havent tested other matrox - bSupportsColorCursor=true; - } - - // TODO: add more cards as more testing is done - - if(bSupportsColorCursor) { - // Note: LoadImage seems to cause win2k internal heap corruption (outputdbgstr warnings) - // if icon is more than 8bpp - - DWORD load_flags = LR_LOADFROMFILE; - - if(dx_full_screen) { - // I think cursors should use LR_CREATEDIBSECTION since they should not be mapped to the device palette (in the case of 256-color cursors) - // since they are not going to be used on the desktop - load_flags |= LR_CREATEDIBSECTION; - } - - // loads a .cur fmt file. - HCURSOR hNewMouseCursor = (HCURSOR) LoadImage(NULL, windows_color_cursor_filename.c_str(), IMAGE_CURSOR, 0, 0, load_flags ); - - if(hNewMouseCursor==NULL) { - wdxdisplay_cat.warning() << "windows color cursor filename '" << windows_color_cursor_filename << "' not found!!\n"; - return; - } - - SetClassLongPtr(_mwindow, GCLP_HCURSOR, (LONG_PTR) hNewMouseCursor); - SetCursor(hNewMouseCursor); - - if(_bLoadedCustomCursor) - DestroyCursor(_hMouseCursor); - _hMouseCursor = hNewMouseCursor; - } -} -*/ - -// returns true if successful -bool wdxGraphicsWindow::search_for_device(int devnum,DXDeviceInfo *pDevinfo) { - DWORD dwRenderWidth = _props._xsize; - DWORD dwRenderHeight = _props._ysize; - LPDIRECTDRAW7 pDD=NULL; - HRESULT hr; - - assert(_dxgsg!=NULL); - - GUID *pDDDeviceGUID; - if(pDevinfo==NULL) - pDDDeviceGUID=NULL; - else pDDDeviceGUID=&pDevinfo->guidDeviceIdentifier; - - assert(_pParentWindowGroup->_pDDCreateEx!=NULL); - - // Create the Direct Draw Objects - hr = (*(_pParentWindowGroup->_pDDCreateEx))(pDDDeviceGUID,(void **)&pDD, IID_IDirectDraw7, NULL); - if((hr != DD_OK)||(pDD==NULL)) { - wdxdisplay_cat.fatal() << "DirectDrawCreateEx failed for monitor("<szDescription << "; DriverFile: '" << pDevID->szDriver - << "'; VendorID: 0x" << (void*)pDevID->dwVendorId - << "; DeviceID: 0x" << (void*)pDevID->dwDeviceId - << "; DriverVer: " - << HIWORD(pDevID->liDriverVersion.HighPart) << "." - << LOWORD(pDevID->liDriverVersion.HighPart) << "." - << HIWORD(pDevID->liDriverVersion.LowPart) << "." - << LOWORD(pDevID->liDriverVersion.LowPart) << endl; - } - - // Query DirectDraw for access to Direct3D - hr = pDD->QueryInterface( IID_IDirect3D7, (VOID**)&_dxgsg->scrn.pD3D); - if(hr != DD_OK) { - wdxdisplay_cat.fatal() << "QI for D3D failed : result = " << ConvD3DErrorToString(hr) << endl; - goto error_exit; - } - - D3DDEVICEDESC7 d3ddevs[3]; // put HAL in 0, TnLHAL in 1, SW rast in 2 - - // just look for HAL and TnL devices right now. I dont think - // we have any interest in the sw rasts at this point - - ZeroMemory(d3ddevs,3*sizeof(D3DDEVICEDESC7)); - - hr = _dxgsg->scrn.pD3D->EnumDevices(EnumDevicesCallback,d3ddevs); - if(hr != DD_OK) { - wdxdisplay_cat.fatal() << "EnumDevices failed : result = " << ConvD3DErrorToString(hr) << endl; - goto error_exit; - } - - WORD DeviceIdx; - - // select TNL if present - if(d3ddevs[TNLHALIDX].dwDevCaps & D3DDEVCAPS_HWRASTERIZATION) { - DeviceIdx=TNLHALIDX; - } else if(d3ddevs[REGHALIDX].dwDevCaps & D3DDEVCAPS_HWRASTERIZATION) { - DeviceIdx=REGHALIDX; - } else if(dx_allow_software_renderer || dx_force_software_renderer) { - DeviceIdx=SWRASTIDX; - } else { - wdxdisplay_cat.error() << "No 3D HW present on device #"<scrn.DXDeviceID.szDescription<<")\n"; - goto error_exit; - } - - if(dx_force_software_renderer) { - DeviceIdx=SWRASTIDX; - } - - memcpy(&_dxgsg->scrn.D3DDevDesc,&d3ddevs[DeviceIdx],sizeof(D3DDEVICEDESC7)); - - _dxgsg->scrn.bIsTNLDevice=(DeviceIdx==TNLHALIDX); - - // Get Current VidMem avail. Note this is only an estimate, when we switch to fullscreen - // mode from desktop, more vidmem will be available (typically 1.2 meg). I dont want - // to switch to fullscreen more than once due to the annoying monitor flicker, so try - // to figure out optimal mode using this estimate - DDSCAPS2 ddsGAVMCaps; - DWORD dwVidMemTotal,dwVidMemFree; - dwVidMemTotal=dwVidMemFree=0; - ZeroMemory(&ddsGAVMCaps,sizeof(DDSCAPS2)); - ddsGAVMCaps.dwCaps = DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM; // dont count AGP mem! - if(FAILED(hr = pDD->GetAvailableVidMem(&ddsGAVMCaps,&dwVidMemTotal,&dwVidMemFree))) { - wdxdisplay_cat.error() << "GetAvailableVidMem failed for device #"<scrn.DXDeviceID.szDescription<<"), result = " << ConvD3DErrorToString(hr) << endl; - // goto skip_device; - exit(1); // probably want to exit, since it may be my fault - } - - if(wdxdisplay_cat.is_info()) - wdxdisplay_cat.info() << "Before fullscreen switch: GetAvailableVidMem for device #"<scrn.D3DDevDesc.dwDeviceRenderBitDepth; - - DWORD dwFullScreenBitDepth; - - // note: this chooses 32bpp, which may not be preferred over 16 for memory & speed reasons - if(DMI.supportedBitDepths & DDBD_32) { - dwFullScreenBitDepth=32; // go for 32bpp if its avail - } else if(DMI.supportedBitDepths & DDBD_24) { - dwFullScreenBitDepth=24; // go for 24bpp if its avail - } else if(DMI.supportedBitDepths & DDBD_16) { - dwFullScreenBitDepth=16; // do 16bpp - } else { - wdxdisplay_cat.fatal() << "No Supported FullScreen resolutions at " << dwRenderWidth << "x" << dwRenderHeight - << " for device #" << devnum << " (" << _dxgsg->scrn.DXDeviceID.szDescription<<"), skipping device...\n"; - goto error_exit; - } - - if(_dxgsg->scrn.bIsLowVidMemCard) { - { - // hack: figuring out exactly what res to use is tricky, instead I will - // just use 640x480 if we have < 3 meg avail - - dwFullScreenBitDepth=16; - dwRenderWidth=640; - dwRenderHeight=480; - dx_force_16bpptextures = true; - - if(wdxdisplay_cat.is_info()) - wdxdisplay_cat.info() << "Available VidMem (" << dwVidMemFree<<") is under " << LOWVIDMEMTHRESHOLD <<", using 640x480 16bpp rendertargets to save tex vidmem.\n"; - } - - #if 0 - /* - // cant use this method without more accurate way to estimate mem used before actually switching - // to that fullscrn mode. simply computing memsize based on GetDisplayMode doesnt seem - // to be accurate within more than 1 meg - - // we think we need to reserve at least 2 megs of vidmem for textures. - // to do this, reduce buffer bitdepth if possible - #define RESERVEDTEXVIDMEM 2000000 - - int rendertargetmem=dwRenderWidth*dwRenderHeight*(dwFullScreenBitDepth>>3); - int memleft = dwFree-rendertargetmem*2; //*2 to handle backbuf/zbuf - - if(memleft < RESERVEDTEXVIDMEM) { - dwFullScreenBitDepth=16; - wdxdisplay_cat.debug() << "using 16bpp rendertargets to save tex vidmem\n"; - assert((DMI.supportedBitDepths & DDBD_16) && (pD3DDevDesc->dwDeviceRenderBitDepth & DDBD_16)); // probably a safe assumption - rendertargetmem=dwRenderWidth*dwRenderHeight*(dwFullScreenBitDepth>>3); - memleft = dwFree-rendertargetmem*2; - - // BUGBUG: if we still cant reserve 2 megs of vidmem, need to auto-reduce the scrn res - if(memleft < RESERVEDTEXVIDMEM) - wdxdisplay_cat.debug() << "XXXX WARNING: cant reserve 2MB of tex vidmem. only " << memleft << " bytes available. Need to rewrite wdxdisplay to try lower resolutions XXXXXXXX\n"; - } - */ - #endif - } - - _dxgsg->scrn.dwFullScreenBitDepth=dwFullScreenBitDepth; - } - - _dxgsg->scrn.dwRenderWidth=dwRenderWidth; - _dxgsg->scrn.dwRenderHeight=dwRenderHeight; - if(pDevinfo) - _dxgsg->scrn.hMon=pDevinfo->hMon; - _dxgsg->scrn.CardIDNum=devnum; // add ID tag for dbgprint purposes - - return true; - - // handle errors within this for device loop - - error_exit: - if(_dxgsg->scrn.pD3D!=NULL) - _dxgsg->scrn.pD3D->Release(); - if(_dxgsg->scrn.pDD!=NULL) - _dxgsg->scrn.pDD->Release(); - - _dxgsg->scrn.pDD=NULL; - _dxgsg->scrn.pD3D=NULL; - return false; -} - -void wdxGraphicsWindowGroup:: -SetCoopLevelsAndDisplayModes(void) { - HRESULT hr; - DWORD SCL_FPUFlag; - - if(dx_preserve_fpu_state) - SCL_FPUFlag = DDSCL_FPUPRESERVE; // tell d3d to preserve the fpu state across calls. this hurts perf, but is good for dbgging - else SCL_FPUFlag = DDSCL_FPUSETUP; - - DXScreenData *pScrn=&_windows[0]->_dxgsg->scrn; - // All SetCoopLevels must use the parent window - - if(!dx_full_screen) { - if(FAILED(hr = pScrn->pDD->SetCooperativeLevel(_hParentWindow, SCL_FPUFlag | DDSCL_NORMAL))) { - wdxdisplay_cat.fatal() << "SetCooperativeLevel failed : result = " << ConvD3DErrorToString(hr) << endl; - exit(1); - } - return; - } - - DWORD SCL_FLAGS = SCL_FPUFlag | DDSCL_FULLSCREEN | DDSCL_EXCLUSIVE | DDSCL_ALLOWREBOOT; - - if(_windows.size()>1) { - SCL_FLAGS |= DDSCL_SETDEVICEWINDOW; - } - - for(DWORD devnum=0;devnum<_windows.size();devnum++) { - DXScreenData *pScrn=&_windows[devnum]->_dxgsg->scrn; - - // need to set focus/device windows for multimon - // focus window is primary monitor that will receive keybd input - // all ddraw objs need to have same focus window - if(_windows.size()>1) { - if(FAILED(hr = pScrn->pDD->SetCooperativeLevel(_hParentWindow, DDSCL_SETFOCUSWINDOW))) { - wdxdisplay_cat.fatal() << "SetCooperativeLevel SetFocusWindow failed on device 0: result = " << ConvD3DErrorToString(hr) << endl; - exit(1); - } - } - - // s3 savage2000 on w95 seems to set EXCLUSIVE_MODE only if you call SetCoopLevel twice. - // so we do it, it really shouldnt be necessary if drivers werent buggy - for(int jj=0;jj<2;jj++) { - if(FAILED(hr = pScrn->pDD->SetCooperativeLevel(pScrn->hWnd, SCL_FLAGS))) { - wdxdisplay_cat.fatal() << "SetCooperativeLevel failed for device #"<< devnum<<": result = " << ConvD3DErrorToString(hr) << endl; - exit(1); - } - } - - if(FAILED(hr = pScrn->pDD->TestCooperativeLevel())) { - wdxdisplay_cat.fatal() << "TestCooperativeLevel failed for device #"<< devnum<<": result = " << ConvD3DErrorToString(hr) << endl; - wdxdisplay_cat.fatal() << "Full screen app failed to get exclusive mode on init, exiting..\n"; - exit(1); - } - - // note: its important we call SetDisplayMode on all cards before creating surfaces on any of them - // let driver choose default refresh rate (hopefully its >=60Hz) - if(FAILED( hr = pScrn->pDD->SetDisplayMode( pScrn->dwRenderWidth, pScrn->dwRenderHeight, - pScrn->dwFullScreenBitDepth, 0, 0 ))) { - wdxdisplay_cat.fatal() << "SetDisplayMode failed to set ("<dwRenderWidth<<"x"<dwRenderHeight<<"x"<dwFullScreenBitDepth<<") on device #"<< pScrn->CardIDNum<<": result = " << ConvD3DErrorToString(hr) << endl; - exit(1); - } - - if(wdxdisplay_cat.is_debug()) { - DX_DECLARE_CLEAN(DDSURFACEDESC2,ddsd34); - pScrn->pDD->GetDisplayMode(&ddsd34); - wdxdisplay_cat.debug() << "set displaymode to " << ddsd34.dwWidth << "x" << ddsd34.dwHeight << " at "<< ddsd34.ddpfPixelFormat.dwRGBBitCount << "bpp, " << ddsd34.dwRefreshRate<< "Hz\n"; - - /* - #ifdef _DEBUG - if(FAILED(hr = (*Disply).pDD->GetAvailableVidMem(&ddsGAVMCaps,&dwVidMemTotal,&dwVidMemFree))) { - wdxdisplay_cat.debug() << "GetAvailableVidMem failed : result = " << ConvD3DErrorToString(hr) << endl; - exit(1); - } - wdxdisplay_cat.debug() << "after fullscreen switch: GetAvailableVidMem returns Total: " << dwVidMemTotal/1000000.0 << " Free: " << dwVidMemFree/1000000.0 << endl; - #endif - */ - } - } -} - -//return true if successful -void wdxGraphicsWindow:: -CreateScreenBuffersAndDevice(DXScreenData &Display) { - - DWORD dwRenderWidth=Display.dwRenderWidth; - DWORD dwRenderHeight=Display.dwRenderHeight; - LPDIRECT3D7 pD3DI=Display.pD3D; - LPDIRECTDRAW7 pDD=Display.pDD; - D3DDEVICEDESC7 *pD3DDevDesc=&Display.D3DDevDesc; - - LPDIRECTDRAWSURFACE7 pPrimaryDDSurf,pBackDDSurf,pZDDSurf; - LPDIRECT3DDEVICE7 pD3DDevice; - RECT view_rect; - int i; - HRESULT hr; - DX_DECLARE_CLEAN( DDSURFACEDESC2, SurfaceDesc ); - - assert(pDD!=NULL); - assert(pD3DI!=NULL); - -/* - // select the best device if the caller does not provide one - D3DDEVICEDESC7 d3ddevs[2]; // put HAL in 0, TnLHAL in 1 - - if(pD3DDevDesc==NULL) { - // just look for HAL and TnL devices right now. I dont think - // we have any interest in the sw rasts at this point - - ZeroMemory(d3ddevs,2*sizeof(D3DDEVICEDESC7)); - - hr = pD3DI->EnumDevices(EnumDevicesCallback,d3ddevs); - if(hr != DD_OK) { - wdxdisplay_cat.fatal() << "EnumDevices failed : result = " << ConvD3DErrorToString(hr) << endl; - exit(1); - } - - WORD DeviceIdx=REGHALIDX; - - if(!(d3ddevs[DeviceIdx].dwDevCaps & D3DDEVCAPS_HWRASTERIZATION )) { - wdxdisplay_cat.fatal() << "No 3D HW present, exiting..." << endl; - exit(1); - } - - // select TNL if present - if(d3ddevs[TNLHALIDX].dwDevCaps & D3DDEVCAPS_HWRASTERIZATION) { - DeviceIdx=TNLHALIDX; - } - - pD3DDevDesc=&d3ddevs[DeviceIdx]; - } -*/ - - DX_DECLARE_CLEAN(DDCAPS,DDCaps); - pDD->GetCaps(&DDCaps,NULL); - - // if window is not foreground in exclusive mode, ddraw thinks you are 'not active', so - // it changes your WM_ACTIVATEAPP from true to false, causing us - // to go into a 'wait-for WM_ACTIVATEAPP true' loop, and the event never comes so we hang - // in fullscreen wait. - - SetForegroundWindow(Display.hWnd); - - if(dx_full_screen) { - // Setup to create the primary surface w/backbuffer - DX_DECLARE_CLEAN(DDSURFACEDESC2,ddsd) - ddsd.dwFlags = DDSD_CAPS|DDSD_BACKBUFFERCOUNT; - ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_3DDEVICE | - DDSCAPS_FLIP | DDSCAPS_COMPLEX; - ddsd.dwBackBufferCount = 1; - - if(dx_full_screen_antialiasing) { - // cant check that d3ddevice has this capability yet, so got to set it anyway. - // hope this is OK. - ddsd.ddsCaps.dwCaps2 |= DDSCAPS2_HINTANTIALIASING; - } - - PRINTVIDMEM(pDD,&ddsd.ddsCaps,"initial primary & backbuf"); - - // Create the primary surface - if(FAILED( hr = pDD->CreateSurface( &ddsd, &pPrimaryDDSurf, NULL ) )) { - wdxdisplay_cat.fatal() << "CreateSurface failed for primary surface: result = " << ConvD3DErrorToString(hr) << endl; - - if(((hr==DDERR_OUTOFVIDEOMEMORY)||(hr==DDERR_OUTOFMEMORY)) && - (Display.dwFullScreenBitDepth>16)) { - // emergency fallback to 16bpp (shouldnt have to do this unless GetAvailVidMem lied) - // will this work for multimon? what if surfs are already created on 1st mon? - Display.dwFullScreenBitDepth=16; - - if(wdxdisplay_cat.info()) - wdxdisplay_cat.info() << "GetAvailVidMem lied, not enough VidMem for 32bpp, so trying 16bpp on device #"<< Display.CardIDNum<< endl; - - if(FAILED( hr = pDD->SetDisplayMode( Display.dwRenderWidth, Display.dwRenderHeight,Display.dwFullScreenBitDepth, 0, 0 ))) { - wdxdisplay_cat.fatal() << "SetDisplayMode failed to set ("<GetDisplayMode( &SurfaceDesc ))) { - wdxdisplay_cat.fatal() << "GetDisplayMode failed result = " << ConvD3DErrorToString(hr) << endl; - exit(1); - } - if(SurfaceDesc.ddpfPixelFormat.dwRGBBitCount <= 8) { - wdxdisplay_cat.fatal() << "Can't run windowed in an 8-bit or less display mode" << endl; - exit(1); - } - - if(!(BitDepth_2_DDBDMask(SurfaceDesc.ddpfPixelFormat.dwRGBBitCount) & pD3DDevDesc->dwDeviceRenderBitDepth)) { - wdxdisplay_cat.fatal() << "3D Device doesnt support rendering at " << SurfaceDesc.ddpfPixelFormat.dwRGBBitCount << "bpp (current desktop bitdepth)" << endl; - exit(1); - } - - - // Get the dimensions of the viewport and screen bounds - - GetClientRect( Display.hWnd, &view_rect ); - POINT ul,lr; - ul.x=view_rect.left; ul.y=view_rect.top; - lr.x=view_rect.right; lr.y=view_rect.bottom; - ClientToScreen(Display.hWnd, &ul ); - ClientToScreen(Display.hWnd, &lr ); - view_rect.left=ul.x; view_rect.top=ul.y; - view_rect.right=lr.x; view_rect.bottom=lr.y; - - dwRenderWidth = view_rect.right - view_rect.left; - dwRenderHeight = view_rect.bottom - view_rect.top; - _props._xorg = view_rect.left; // _props should reflect view rectangle - _props._yorg = view_rect.top; - _props._xsize = dwRenderWidth; - _props._ysize = dwRenderHeight; - - // Initialize the description of the primary surface - ZeroMemory( &SurfaceDesc, sizeof(DDSURFACEDESC2) ); - SurfaceDesc.dwSize = sizeof(DDSURFACEDESC2); - SurfaceDesc.dwFlags = DDSD_CAPS ; - SurfaceDesc.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; - - PRINTVIDMEM(pDD,&SurfaceDesc.ddsCaps,"initial primary surface"); - - // Create the primary surface. This includes all of the visible - // window, so no need to specify height/width - if(FAILED(hr = pDD->CreateSurface( &SurfaceDesc, &pPrimaryDDSurf, NULL ))) { - wdxdisplay_cat.fatal() - << "CreateSurface failed for primary surface: result = " << ConvD3DErrorToString(hr) << endl; - exit(1); - } - - // Create a clipper object which handles all our clipping for cases when - // our window is partially obscured by other windows. - LPDIRECTDRAWCLIPPER Clipper; - if(FAILED(hr = pDD->CreateClipper( 0, &Clipper, NULL ))) { - wdxdisplay_cat.fatal() << "CreateClipper failed : result = " << ConvD3DErrorToString(hr) << endl; - exit(1); - } - - // Associate the clipper with our window. Note that, afterwards, the - // clipper is internally referenced by the primary surface, so it is safe - // to release our local reference to it. - Clipper->SetHWnd( 0, Display.hWnd ); - pPrimaryDDSurf->SetClipper( Clipper ); - Clipper->Release(); - - // Clear the primary surface to black - DX_DECLARE_CLEAN(DDBLTFX, bltfx) - - if(FAILED( hr = pPrimaryDDSurf->Blt(NULL,NULL,NULL,DDBLT_COLORFILL | DDBLT_WAIT,&bltfx))) { - wdxdisplay_cat.fatal() - << "Blt to Black of Primary Surf failed! : result = " << ConvD3DErrorToString(hr) << endl; - exit(1); - } - - // Setup a surface description to create a backbuffer. - SurfaceDesc.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS; - SurfaceDesc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE | DDSCAPS_VIDEOMEMORY; - SurfaceDesc.dwWidth = dwRenderWidth; - SurfaceDesc.dwHeight = dwRenderHeight; - - if(dx_full_screen_antialiasing) { - // cant check that d3ddevice has this capability yet, so got to set it anyway. - // hope this is OK. - SurfaceDesc.ddsCaps.dwCaps2 |= DDSCAPS2_HINTANTIALIASING; - } - - PRINTVIDMEM(pDD,&SurfaceDesc.ddsCaps,"initial backbuf"); - - // Create the backbuffer. (might want to handle failure due to running out of video memory) - if(FAILED(hr = pDD->CreateSurface( &SurfaceDesc, &pBackDDSurf, NULL ))) { - wdxdisplay_cat.fatal() - << "CreateSurface failed for backbuffer : result = " << ConvD3DErrorToString(hr) << endl; - exit(1); - } - - if(FAILED( hr = pBackDDSurf->Blt(NULL,NULL,NULL,DDBLT_COLORFILL | DDBLT_WAIT,&bltfx))) { - wdxdisplay_cat.fatal() - << "Blt to Black of Back Surf failed! : result = " << ConvD3DErrorToString(hr) << endl; - exit(1); - } - - } // end create windowed buffers - -// ======================================================== - - resized(dwRenderWidth,dwRenderHeight); // update panda channel/display rgn info - - #ifndef NDEBUG - if(!(_props._mask & W_DEPTH)) { - wdxdisplay_cat.info() << "no zbuffer requested, skipping zbuffer creation\n"; - } - #endif - - // Check if the device supports z-bufferless hidden surface removal. If so, - // we don't really need a z-buffer - if((!(pD3DDevDesc->dpcTriCaps.dwRasterCaps & D3DPRASTERCAPS_ZBUFFERLESSHSR )) && - (_props._mask & W_DEPTH)) { - - // Get z-buffer dimensions from the render target - DX_DECLARE_CLEAN(DDSURFACEDESC2,ddsd); - pBackDDSurf->GetSurfaceDesc( &ddsd ); - - // Setup the surface desc for the z-buffer. - ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_PIXELFORMAT; - ddsd.ddsCaps.dwCaps = DDSCAPS_ZBUFFER | ((_dxgsg->scrn.bIsSWRast) ? DDSCAPS_SYSTEMMEMORY : DDSCAPS_VIDEOMEMORY); - - DDPIXELFORMAT ZBufPixFmts[MAX_DX_ZBUF_FMTS]; - cNumZBufFmts=0; - - // Get an appropiate pixel format from enumeration of the formats. On the - // first pass, we look for a zbuffer dpeth which is equal to the frame - // buffer depth (as some cards unfornately require this). - if(FAILED(pD3DI->EnumZBufferFormats((Display.bIsTNLDevice ? IID_IDirect3DHALDevice : IID_IDirect3DTnLHalDevice), - EnumZBufFmtsCallback, - (VOID*)&ZBufPixFmts ))) { - wdxdisplay_cat.fatal() << "EnumZBufferFormats failed" << endl; - exit(1); - } - -#ifdef _DEBUG - { static BOOL bPrinted=FALSE; - if(!bPrinted) { - for(i=0;idwFlags & DDPF_STENCILBUFFER)!=0)) { - switch(pCurPixFmt->dwRGBBitCount) { - case 16: - pz16=pCurPixFmt; - break; - case 24: - pz24=pCurPixFmt; - break; - case 32: - pz32=pCurPixFmt; - break; - } - } - } - - if((pz16==NULL)&&(pz24==NULL)&&(pz32==NULL)) { - if(bWantStencil) - wdxdisplay_cat.fatal() << "stencil buffer requested, device has no stencil capability\n"; - else wdxdisplay_cat.fatal() << "failed to find adequate zbuffer capability\n"; - exit(1); - } - - #define SET_ZBUF_DEPTH(DEPTH) { assert(pz##DEPTH != NULL); Display.depth_buffer_bitdepth=DEPTH; ddsd.ddpfPixelFormat = *pz##DEPTH;} - - if(_dxgsg->scrn.bIsSWRast) { - SET_ZBUF_DEPTH(16); // need this for fast path rasterizers - } else - if(IS_NVIDIA(Display.DXDeviceID)) { - DX_DECLARE_CLEAN(DDSURFACEDESC2,ddsd_pri) - pPrimaryDDSurf->GetSurfaceDesc(&ddsd_pri); - - // must pick zbuf depth to match primary surface depth for nvidia - if(ddsd_pri.ddpfPixelFormat.dwRGBBitCount==16) { - SET_ZBUF_DEPTH(16); - } else { - if(dx_force_16bpp_zbuffer) { - wdxdisplay_cat.fatal() << "'dx-force-16bpp-zbuffer #t' requires a 16bpp desktop on nvidia cards\n"; - exit(1); - } - // take the smaller of 24 or 32. (already assured to match stencil capability) - if(pz24!=NULL) { - SET_ZBUF_DEPTH(24); - } else SET_ZBUF_DEPTH(32); - } - } else { - if(dx_force_16bpp_zbuffer) { - if(pz16==NULL) { - wdxdisplay_cat.fatal() << "'dx-force-16bpp-zbuffer #t', but no 16bpp zbuf fmts available on this card\n"; - exit(1); - } - - if(wdxdisplay_cat.is_debug()) - wdxdisplay_cat.debug() << "forcing use of 16bpp Z-Buffer\n"; - SET_ZBUF_DEPTH(16); - ddsd.ddpfPixelFormat = *pz16; - } else { - // pick the highest res zbuffer format avail. Note: this is choosing to waste vid-memory - // and possibly perf for more accuracy, less z-fighting at long distance (std 16bpp would - // be smaller// maybe faster) - // order of preference 24: (should be enough), 32: probably means 24 of Z, then 16 - - if(bWantStencil && (pz32!=NULL)) { - // dont want to select 16/8 z/stencil over 24/8 z/stenc - SET_ZBUF_DEPTH(32); - } else { - if(pz24!=NULL) { - SET_ZBUF_DEPTH(24); - } else if(pz32!=NULL) { - SET_ZBUF_DEPTH(32); - } else { - SET_ZBUF_DEPTH(16); - } - } - } - } - - PRINTVIDMEM(pDD,&ddsd.ddsCaps,"initial zbuf"); - -#ifdef _DEBUG - wdxdisplay_cat.info() << "Creating " << ddsd.ddpfPixelFormat.dwRGBBitCount << "bpp zbuffer\n"; -#endif - - // Create and attach a z-buffer - if(FAILED( hr = pDD->CreateSurface( &ddsd, &pZDDSurf, NULL ) )) { - wdxdisplay_cat.fatal() << "CreateSurface failed for Z buffer: result = " << ConvD3DErrorToString(hr) << endl; - - if(((hr==DDERR_OUTOFVIDEOMEMORY)||(hr==DDERR_OUTOFMEMORY)) && - ((Display.dwFullScreenBitDepth>16)||(ddsd.ddpfPixelFormat.dwRGBBitCount>16))) { - Display.dwFullScreenBitDepth=16; - // emergency fallback to 16bpp (shouldnt have to do this unless GetAvailVidMem lied) - // will this work for multimon? what if surfs are already created on 1st mon? - - if(wdxdisplay_cat.info()) - wdxdisplay_cat.info() << "GetAvailVidMem lied, not enough VidMem for 32bpp, so trying 16bpp on device #"<< Display.CardIDNum<< endl; - - ULONG refcnt; - - // free pri and back (maybe should just free pri since created as complex chain?) - RELEASE(pBackDDSurf,wdxdisplay,"backbuffer",false); - RELEASE(pPrimaryDDSurf,wdxdisplay,"primary surface",false); - - if(FAILED( hr = pDD->SetDisplayMode( Display.dwRenderWidth, Display.dwRenderHeight,Display.dwFullScreenBitDepth, 0, 0 ))) { - wdxdisplay_cat.fatal() << "SetDisplayMode failed to set ("<get_pipe(); - - GraphicsWindow::WindowProps *props_param; - if(!get_param_into(props_param, params)) { - return new wdxGraphicsWindow(pipe); - } else { - return new wdxGraphicsWindow(pipe, props_param->get_properties()); - } -} - -TypeHandle wdxGraphicsWindow::get_class_type(void) { - return _type_handle; -} - -void wdxGraphicsWindow::init_type(void) { - GraphicsWindow::init_type(); - register_type(_type_handle, "wdxGraphicsWindow", - GraphicsWindow::get_class_type()); -} - -TypeHandle wdxGraphicsWindow::get_type(void) const { - return get_class_type(); -} - -//////////////////////////////////////////////////////////////////// -// Function: lookup_key -// Access: -// Description: -//////////////////////////////////////////////////////////////////// -ButtonHandle wdxGraphicsWindow:: -lookup_key(WPARAM wparam) const { - // First, check for a few buttons that we filter out when the IME - // window is open. - if (!_ime_active) { - switch(wparam) { - case VK_BACK: return KeyboardButton::backspace(); - case VK_DELETE: return KeyboardButton::del(); - case VK_ESCAPE: return KeyboardButton::escape(); - case VK_SPACE: return KeyboardButton::space(); - case VK_UP: return KeyboardButton::up(); - case VK_DOWN: return KeyboardButton::down(); - case VK_LEFT: return KeyboardButton::left(); - case VK_RIGHT: return KeyboardButton::right(); - } - } - - // Now check for the rest of the buttons, including the ones that - // we allow through even when the IME window is open. - switch(wparam) { - case VK_TAB: return KeyboardButton::tab(); - case VK_PRIOR: return KeyboardButton::page_up(); - case VK_NEXT: return KeyboardButton::page_down(); - case VK_HOME: return KeyboardButton::home(); - case VK_END: return KeyboardButton::end(); - case VK_F1: return KeyboardButton::f1(); - case VK_F2: return KeyboardButton::f2(); - case VK_F3: return KeyboardButton::f3(); - case VK_F4: return KeyboardButton::f4(); - case VK_F5: return KeyboardButton::f5(); - case VK_F6: return KeyboardButton::f6(); - case VK_F7: return KeyboardButton::f7(); - case VK_F8: return KeyboardButton::f8(); - case VK_F9: return KeyboardButton::f9(); - case VK_F10: return KeyboardButton::f10(); - case VK_F11: return KeyboardButton::f11(); - case VK_F12: return KeyboardButton::f12(); - case VK_INSERT: return KeyboardButton::insert(); - case VK_CAPITAL: return KeyboardButton::caps_lock(); - case VK_NUMLOCK: return KeyboardButton::num_lock(); - case VK_SCROLL: return KeyboardButton::scroll_lock(); - case VK_SNAPSHOT: return KeyboardButton::print_screen(); - - case VK_SHIFT: - case VK_LSHIFT: - case VK_RSHIFT: - return KeyboardButton::shift(); - - case VK_CONTROL: - case VK_LCONTROL: - case VK_RCONTROL: - return KeyboardButton::control(); - - case VK_MENU: - case VK_LMENU: - case VK_RMENU: { - return KeyboardButton::alt(); - } - - default: - int key = MapVirtualKey(wparam, 2); - if (isascii(key) && key != 0) { - // We used to try to remap lowercase to uppercase keys - // here based on the state of the shift and/or caps lock - // keys. But that's a mistake, and doesn't allow for - // international or user-defined keyboards; let Windows - // do that mapping. - - // Nowadays, we make a distinction between a "button" - // and a "keystroke". A button corresponds to a - // physical button on the keyboard and has a down and up - // event associated. A keystroke may or may not - // correspond to a physical button, but will be some - // Unicode character and will not have a corresponding - // up event. - return KeyboardButton::ascii_key(tolower(key)); - } - break; - } - return ButtonHandle::none(); -} - -int wdxGraphicsWindow:: -get_depth_bitwidth(void) { - assert(_dxgsg!=NULL); - if(_dxgsg->scrn.pddsZBuf!=NULL) - return _dxgsg->scrn.depth_buffer_bitdepth; - else return 0; - -// GetSurfaceDesc is not reliable, on GF2, GetSurfDesc returns 32bpp when you created a 24bpp zbuf -// instead store the depth used at creation time - -// DX_DECLARE_CLEAN(DDSURFACEDESC2, ddsd); -// _dxgsg->_zbuf->GetSurfaceDesc(&ddsd); -// return ddsd.ddpfPixelFormat.dwRGBBitCount; -} - -// Global system parameters we want to modify during our run -static int iMouseTrails; -static bool bCursorShadowOn,bMouseVanish; - -#ifndef SPI_GETMOUSEVANISH -// get rid of this when we upgrade to winxp winuser.h in newest platform sdk -#define SPI_GETMOUSEVANISH 0x1020 -#define SPI_SETMOUSEVANISH 0x1021 -#endif - -#ifndef SPI_GETCURSORSHADOW -#error You have old windows headers, need to get latest MS Platform SDK -#endif - -void set_global_parameters(void) { - // turn off mousetrails and cursor shadow and mouse cursor vanish - // cursor shadow causes cursor blink and reduced frame rate due to lack of driver support for - // cursor alpha blending - - // this is a win2k/xp only param, could use GetVersionEx to do it just for win2k, - // but since it is just a param it will just cause a silent error on other OS's - // that should be ok - SystemParametersInfo(SPI_GETCURSORSHADOW,NULL,&bCursorShadowOn,NULL); - SystemParametersInfo(SPI_SETCURSORSHADOW,NULL,(PVOID)false,NULL); - - SystemParametersInfo(SPI_GETMOUSETRAILS,NULL,&iMouseTrails,NULL); - SystemParametersInfo(SPI_SETMOUSETRAILS,NULL,(PVOID)0,NULL); - - // this is ME/XP only feature - SystemParametersInfo(SPI_GETMOUSEVANISH,NULL,&bMouseVanish,NULL); - SystemParametersInfo(SPI_SETMOUSEVANISH,NULL,(PVOID)false,NULL); -} - -void restore_global_parameters(void) { - SystemParametersInfo(SPI_SETCURSORSHADOW,NULL,(PVOID)bCursorShadowOn,NULL); - SystemParametersInfo(SPI_SETMOUSETRAILS,NULL,(PVOID)iMouseTrails,NULL); - SystemParametersInfo(SPI_SETMOUSEVANISH,NULL,(PVOID)bMouseVanish,NULL); -} - - -// fns for exporting to python, which cant pass variable length arrays -wdxGraphicsWindowGroup::wdxGraphicsWindowGroup(GraphicsPipe *pipe,const GraphicsWindow::Properties &Win1Prop) { - GraphicsWindow::Properties WinPropArr[1]; - WinPropArr[0]=Win1Prop; - make_windows(pipe,1,WinPropArr); -} - -wdxGraphicsWindowGroup::wdxGraphicsWindowGroup(GraphicsPipe *pipe, - const GraphicsWindow::Properties &Win1Prop, - const GraphicsWindow::Properties &Win2Prop) { - GraphicsWindow::Properties WinPropArr[2]; - - WinPropArr[0]=Win1Prop; - WinPropArr[1]=Win2Prop; - make_windows(pipe,2,WinPropArr); -} - -wdxGraphicsWindowGroup::wdxGraphicsWindowGroup(GraphicsPipe *pipe, - const GraphicsWindow::Properties &Win1Prop, - const GraphicsWindow::Properties &Win2Prop, - const GraphicsWindow::Properties &Win3Prop) { - GraphicsWindow::Properties WinPropArr[3]; - - WinPropArr[0]=Win1Prop; - WinPropArr[1]=Win2Prop; - WinPropArr[2]=Win3Prop; - make_windows(pipe,3,WinPropArr); -} - -wdxGraphicsWindowGroup::wdxGraphicsWindowGroup(wdxGraphicsWindow *OneWindow) { - // init a 1 window group - // called from config_window - - _windows.reserve(1); - _windows.push_back(OneWindow); - initWindowGroup(); -} - -void wdxGraphicsWindowGroup::initWindowGroup(void) { - HRESULT hr; - unsigned int i; - - assert(_windows.size()>0); - _hOldForegroundWindow=GetForegroundWindow(); - _bClosingAllWindows= false; - - unsigned int num_windows=_windows.size(); - - #define DDRAW_NAME "ddraw.dll" - - _hDDrawDLL = LoadLibrary(DDRAW_NAME); - if(_hDDrawDLL == 0) { - wdxdisplay_cat.fatal() << "can't locate " << DDRAW_NAME <<"!\n"; - exit(1); - } - - _hMouseCursor = NULL; - _bLoadedCustomCursor = false; - - // can only get multimon HW acceleration in fullscrn on DX7 - - unsigned int numMonitors = GetSystemMetrics(SM_CMONITORS); - - if(numMonitors < num_windows) { - if(numMonitors==0) { - numMonitors=1; //win95 system will fail this call - } else { - wdxdisplay_cat.fatal() << "system has only "<< numMonitors << " monitors attached, couldn't find enough devices to meet multi window reqmt of " << num_windows << endl; - exit(1); - } - } - - _pDDCreateEx = (LPDIRECTDRAWCREATEEX) GetProcAddress(_hDDrawDLL,"DirectDrawCreateEx"); - if(_pDDCreateEx == NULL) { - wdxdisplay_cat.fatal() << "Panda currently requires at least DirectX 7.0!\n"; - exit(1); - } - - if(_windows.size()>1) { - // just do Enumeration for multimon case. - // enumeration was reqd to select voodoo1-class devices, but I'm no longer - // going to support them on DX7 due to lack of mouse cursor - - LPDIRECTDRAWENUMERATEEX pDDEnumEx = (LPDIRECTDRAWENUMERATEEX) GetProcAddress(_hDDrawDLL,"DirectDrawEnumerateExA"); - if(pDDEnumEx == NULL) { - wdxdisplay_cat.fatal() << "GetProcAddr failed for DirectDrawEnumerateEx!\n"; - exit(1); - } - - hr = (*pDDEnumEx)(DriverEnumCallback_MultiMon, &_DeviceInfoVec, DDENUM_ATTACHEDSECONDARYDEVICES | DDENUM_NONDISPLAYDEVICES); - if(FAILED(hr)) { - wdxdisplay_cat.fatal() << "DirectDrawEnumerateEx failed : result = " << ConvD3DErrorToString(hr) << endl; - exit(1); - } - - if(_DeviceInfoVec.size() < num_windows) { - wdxdisplay_cat.fatal() << "couldn't find enough devices attached to meet multi window reqmt of " << num_windows << endl; - exit(1); - } - } - - assert(_windows[0] != NULL); - - for(i=0;iconfig_window(this); - } - - assert(_windows[0] != NULL); - - DWORD good_device_count=0; - - if(num_windows==1) { - assert(_windows[0] != NULL); - if(_windows[0]->search_for_device(0,NULL)) - good_device_count=1; - } else { - for(DWORD devnum=0;devnum<_DeviceInfoVec.size() && (good_device_count < num_windows);devnum++) { - if(_windows[devnum]->search_for_device(devnum,&(_DeviceInfoVec[devnum]))) - good_device_count++; - } - } - - if(good_device_count < num_windows) { - if(good_device_count==0) - wdxdisplay_cat.fatal() << "no usable display devices, exiting...\n"; - else wdxdisplay_cat.fatal() << "multi-device request for " << num_windows << "devices, found only "<< good_device_count << endl; - exit(1); - } - - _DeviceInfoVec.clear(); // dont need this anymore - - CreateWindows(); // creates win32 windows (need to do this before Setting coopLvls and display modes, - // but after we have all the monitor handles needed by CreateWindow() - - SetCoopLevelsAndDisplayModes(); - - if(dx_show_fps_meter) - _windows[0]->_dxgsg->_bShowFPSMeter = true; // just show fps on 1st mon - - for(i=0;iCreateScreenBuffersAndDevice(_windows[i]->_dxgsg->scrn); - } - - for(i=0;ifinish_window_setup(); - } - - for(i=0;i_dxgsg->SetDXReady(true); - } -} - -wdxGraphicsWindowGroup::wdxGraphicsWindowGroup(GraphicsPipe *pipe,int num_windows,GraphicsWindow::Properties *WinPropArray) { - make_windows(pipe,num_windows,WinPropArray); -} - -void wdxGraphicsWindowGroup:: -make_windows(GraphicsPipe *pipe,int num_windows,GraphicsWindow::Properties *WinPropArray) { - _hParentWindow=NULL; - _windows.reserve(num_windows); - int i; - - // first make all the objs without running the dx config() stuff - for(i=0;iclose_window(); - } - - if((_hOldForegroundWindow!=NULL) /*&& (scrn.hWnd==GetForegroundWindow())*/) { - SetForegroundWindow(_hOldForegroundWindow); - } - - if(_bLoadedCustomCursor && (_hMouseCursor!=NULL)) - DestroyCursor(_hMouseCursor); - - - if(_hDDrawDLL != NULL) { - FreeLibrary(_hDDrawDLL); - _hDDrawDLL = NULL; - } -} - diff --git a/panda/src/wdxdisplay/wdxGraphicsWindow.h b/panda/src/wdxdisplay/wdxGraphicsWindow.h deleted file mode 100644 index fb268c5163..0000000000 --- a/panda/src/wdxdisplay/wdxGraphicsWindow.h +++ /dev/null @@ -1,176 +0,0 @@ -// Filename: wdxGraphicsWindow.h -// 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 . -// -//////////////////////////////////////////////////////////////////// -#ifndef WDXGRAPHICSWINDOW_H -#define WDXGRAPHICSWINDOW_H -//#define WBD_GL_MODE 1 // if setting this, do it in wdxGraphicsStateGuardian.h too -// -//////////////////////////////////////////////////////////////////// -// Includes -//////////////////////////////////////////////////////////////////// -#include "dxGraphicsStateGuardian.h" - -//////////////////////////////////////////////////////////////////// -// Defines -//////////////////////////////////////////////////////////////////// -class wdxGraphicsPipe; -class wdxGraphicsWindowGroup; - -const int WDXWIN_CONFIGURE = 4; -const int WDXWIN_EVENT = 8; - -typedef HRESULT (WINAPI * LPDIRECTDRAWCREATEEX)(GUID FAR * lpGuid, LPVOID *lplpDD, REFIID iid,IUnknown FAR *pUnkOuter); - -typedef struct { - char szDriver[MAX_DDDEVICEID_STRING]; - char szDescription[MAX_DDDEVICEID_STRING]; - GUID guidDeviceIdentifier; - HMONITOR hMon; -} DXDeviceInfo; -typedef vector DXDeviceInfoVec; - -//////////////////////////////////////////////////////////////////// -// Class : wdxGraphicsWindow -// Description : -//////////////////////////////////////////////////////////////////// -class EXPCL_PANDADX wdxGraphicsWindow : public GraphicsWindow { - friend class DXGraphicsStateGuardian; - friend class DXTextureContext; - friend class wdxGraphicsWindowGroup; - -public: - wdxGraphicsWindow(GraphicsPipe* pipe); - wdxGraphicsWindow(GraphicsPipe* pipe,const GraphicsWindow::Properties& props); - - // this constructor will not initialize the wdx stuff, only the panda graphicswindow stuff - wdxGraphicsWindow(GraphicsPipe* pipe,const GraphicsWindow::Properties& props,wdxGraphicsWindowGroup *pParentGroup); - - virtual ~wdxGraphicsWindow(void); - - virtual TypeHandle get_gsg_type() const; - static GraphicsWindow* make_wdxGraphicsWindow(const FactoryParams ¶ms); - - void set_window_handle(HWND hwnd); - - LONG window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam); - void process_events(void); - - INLINE void handle_mouse_motion(int x, int y); - INLINE void handle_mouse_entry(bool bEntering, int x, int y); - INLINE void handle_keypress(ButtonHandle key, int x, int y ); - INLINE void handle_keyrelease(ButtonHandle key); - void handle_window_move(int x, int y); - void dx_setup(); - virtual bool resize(unsigned int xsize,unsigned int ysize); - virtual unsigned int verify_window_sizes(unsigned int numsizes,unsigned int *dimen); - bool special_check_fullscreen_resolution(UINT xsize,UINT ysize); - virtual int get_depth_bitwidth(void); - -protected: - void CreateScreenBuffersAndDevice(LPDIRECTDRAW7 pDD,LPDIRECT3D7 pD3DI); - ButtonHandle lookup_key(WPARAM wparam) const; -// virtual void config(void); - void config_single_window(void); - void config_window(wdxGraphicsWindowGroup *pParentGroup); - void finish_window_setup(void); - bool search_for_device(int devnum,DXDeviceInfo *pDevinfo); - void setup_colormap(void); - -public: - UINT_PTR _PandaPausedTimer; - DXGraphicsStateGuardian *_dxgsg; - void CreateScreenBuffersAndDevice(DXScreenData &Display); - -private: - INLINE void track_mouse_leaving(HWND hwnd); - wdxGraphicsWindowGroup *_pParentWindowGroup; - HDC _hdc; - HPALETTE _colormap; - typedef enum { NotAdjusting,MovingOrResizing,Resizing } WindowAdjustType; - WindowAdjustType _WindowAdjustingType; - bool _bSizeIsMaximized; - bool _cursor_in_windowclientarea; - bool _tracking_mouse_leaving; - bool _ime_open; - bool _ime_active; - bool _ime_composition_w; - bool _exiting_window; - bool _window_inactive; - bool _active_minimized_fullscreen; - bool _return_control_to_app; - int _depth_buffer_bpp; - -public: - static TypeHandle get_class_type(void); - static void init_type(void); - virtual TypeHandle get_type(void) const; - virtual TypeHandle force_init_type() {init_type(); return get_class_type();} - - void DestroyMe(bool bAtExitFnCalled); - virtual void do_close_window(); - void deactivate_window(void); - void reactivate_window(void); - void handle_reshape(bool bDoDXReset); - -private: - static TypeHandle _type_handle; -}; - -// this class really belongs in panda, not here -class EXPCL_PANDADX wdxGraphicsWindowGroup { -// group of windows are all created at the same time - friend class wdxGraphicsWindow; - -PUBLISHED: - wdxGraphicsWindowGroup(GraphicsPipe *,const GraphicsWindow::Properties&); - wdxGraphicsWindowGroup(GraphicsPipe *,const GraphicsWindow::Properties&,const GraphicsWindow::Properties&); - wdxGraphicsWindowGroup(GraphicsPipe *,const GraphicsWindow::Properties&,const GraphicsWindow::Properties&, - const GraphicsWindow::Properties&); -public: - wdxGraphicsWindowGroup(wdxGraphicsWindow *OneWindow); - // dont publish variable length one, since FFI wont support it - wdxGraphicsWindowGroup(GraphicsPipe *pipe,int num_windows,GraphicsWindow::Properties *WinPropArray); - ~wdxGraphicsWindowGroup(); - void SetCoopLevelsAndDisplayModes(void); -public: - void CreateWindows(void); - void make_windows(GraphicsPipe *,int num_windows,GraphicsWindow::Properties *pWinPropArray); - void initWindowGroup(void); - - pvector _windows; - DXDeviceInfoVec *_pDeviceInfoVec; // only used during init to store valid devices - HWND _hParentWindow; - HINSTANCE _hDDrawDLL; - HWND _hOldForegroundWindow; - HCURSOR _hMouseCursor; - bool _bLoadedCustomCursor; - bool _bClosingAllWindows; - int _numMonitors; - LPDIRECTDRAWCREATEEX _pDDCreateEx; - DXDeviceInfoVec _DeviceInfoVec; - - // win32 fns that dont exist on w95 - typedef BOOL (WINAPI* PFN_GETMONITORINFO)(HMONITOR, LPMONITORINFO); - PFN_GETMONITORINFO _pfnGetMonitorInfo; - typedef BOOL (WINAPI* PFN_TRACKMOUSEEVENT)(LPTRACKMOUSEEVENT); - PFN_TRACKMOUSEEVENT _pfnTrackMouseEvent; -}; - -extern void set_global_parameters(void); -extern void restore_global_parameters(void); - -#endif diff --git a/panda/src/wdxdisplay/wdxdisplay_composite1.cxx b/panda/src/wdxdisplay/wdxdisplay_composite1.cxx deleted file mode 100644 index 3dda3e88ff..0000000000 --- a/panda/src/wdxdisplay/wdxdisplay_composite1.cxx +++ /dev/null @@ -1,4 +0,0 @@ - -#include "config_wdxdisplay.cxx" -#include "wdxGraphicsPipe.cxx" - diff --git a/panda/src/wdxdisplay8/Sources.pp b/panda/src/wdxdisplay8/Sources.pp deleted file mode 100644 index 98d4d11901..0000000000 --- a/panda/src/wdxdisplay8/Sources.pp +++ /dev/null @@ -1,28 +0,0 @@ -#define BUILD_DIRECTORY $[HAVE_DX] - -#define OTHER_LIBS interrogatedb:c dconfig:c dtoolconfig:m \ - dtoolutil:c dtoolbase:c dtool:m -#define WIN_SYS_LIBS Imm32.lib dinput8.lib -#define USE_PACKAGES dx - -#begin lib_target - #define TARGET wdxdisplay8 - #define LOCAL_LIBS dxgsg8 - - #define COMBINED_SOURCES $[TARGET]_composite1.cxx - - // need to install these due to external projects that link directly with libpandadx (bartop) - #define INSTALL_HEADERS \ - config_wdxdisplay8.h wdxGraphicsPipe8.h wdxGraphicsWindow8.h dxInput8.h - - - #define INCLUDED_SOURCES \ - config_wdxdisplay8.cxx wdxGraphicsPipe8.cxx dxInput8.cxx - - // note SOURCES should NOT include INCLUDED_SOURCES, that would cause a double build - // SOURCES should be headers and separately-built cxx files - // build wdxGraphicsWindow.cxx separately since its big - - #define SOURCES wdxGraphicsWindow8.cxx $[INSTALL_HEADERS] - -#end lib_target diff --git a/panda/src/wgldisplay/Sources.pp b/panda/src/wgldisplay/Sources.pp index 1720d67318..bf9a3b2e1c 100644 --- a/panda/src/wgldisplay/Sources.pp +++ b/panda/src/wgldisplay/Sources.pp @@ -4,34 +4,26 @@ #define OTHER_LIBS interrogatedb:c dconfig:c dtoolconfig:m \ dtoolutil:c dtoolbase:c dtool:m -#define WIN_SYS_LIBS Imm32.lib - #begin lib_target #define TARGET wgldisplay #define LOCAL_LIBS \ - glgsg display putil + display putil windisplay glgsg #define COMBINED_SOURCES $[TARGET]_composite1.cxx #define INSTALL_HEADERS \ - config_wgldisplay.h wglGraphicsPipe.h wglGraphicsWindow.h Win32Defs.h - - #define SOURCES \ - wglGraphicsWindow.cxx wglext.h $[INSTALL_HEADERS] + config_wgldisplay.h \ + wglGraphicsPipe.I wglGraphicsPipe.h \ + wglGraphicsWindow.I wglGraphicsWindow.h +// Win32Defs.h #define INCLUDED_SOURCES \ - config_wgldisplay.cxx wglGraphicsPipe.cxx - -#end lib_target - -#begin test_bin_target - #define TARGET test_wgl - #define LOCAL_LIBS \ - putil display mathutil gobj pgraph wgldisplay glgsg + config_wgldisplay.cxx wglGraphicsPipe.cxx wglGraphicsWindow.cxx #define SOURCES \ - test_wgl.cxx + $[INSTALL_HEADERS] +// wglext.h -#end test_bin_target +#end lib_target diff --git a/panda/src/wgldisplay/Win32Defs.h b/panda/src/wgldisplay/Win32Defs.h deleted file mode 100644 index 26a0245d15..0000000000 --- a/panda/src/wgldisplay/Win32Defs.h +++ /dev/null @@ -1,33 +0,0 @@ - -// This file exists so OGL can compile with original VC6 headers -// without latest MS Platform SDK. It simply reproduces all the -// necessary defs here - -#ifndef DECLSPEC_SELECTANY -#define DECLSPEC_SELECTANY __declspec(selectany) -#endif - -#ifndef SetClassLongPtr -#define SetClassLongPtr SetClassLong -#endif - -#ifndef GCLP_HCURSOR -#define GCLP_HCURSOR GCL_HCURSOR -#endif - -#ifndef SPI_GETMOUSEVANISH -// from WinXP winuser.h -#define SPI_GETMOUSEVANISH 0x1020 -#define SPI_SETMOUSEVANISH 0x1021 -#endif - -#ifndef SPI_GETCURSORSHADOW -#define SPI_GETCURSORSHADOW 0x101A -#define SPI_SETCURSORSHADOW 0x101B -#endif - -#ifndef __int3264 -#define LONG_PTR LONG -#endif - - diff --git a/panda/src/wgldisplay/config_wgldisplay.cxx b/panda/src/wgldisplay/config_wgldisplay.cxx index 39d1ac553c..9fd053c79b 100644 --- a/panda/src/wgldisplay/config_wgldisplay.cxx +++ b/panda/src/wgldisplay/config_wgldisplay.cxx @@ -1,5 +1,5 @@ // Filename: config_wgldisplay.cxx -// Created by: mike (07Oct99) +// Created by: drose (20Dec02) // //////////////////////////////////////////////////////////////////// // @@ -19,48 +19,16 @@ #include "config_wgldisplay.h" #include "wglGraphicsPipe.h" #include "wglGraphicsWindow.h" - -#include +#include "graphicsPipeSelection.h" +#include "dconfig.h" Configure(config_wgldisplay); -NotifyCategoryDef(wgldisplay, "display"); +NotifyCategoryDef(wgldisplay, "windisplay"); ConfigureFn(config_wgldisplay) { init_libwgldisplay(); } -// Configure this true to force the rendering to sync to the video -// refresh, or false to let your frame rate go as high as it can, -// irrespective of the video refresh. (if this capability is available in the ICD) -bool gl_sync_video = config_wgldisplay.GetBool("sync-video", true); - -bool gl_show_fps_meter = config_wgldisplay.GetBool("show-fps-meter", false); -float gl_fps_meter_update_interval = max(0.5,config_wgldisplay.GetFloat("fps-meter-update-interval", 1.7)); -int gl_forced_pixfmt=config_wgldisplay.GetInt("gl-force-pixfmt", 0); - -bool wgl_force_sw_renderer = config_wgldisplay.GetBool("gl-force-software-renderer", false); -bool wgl_allow_sw_renderer = config_wgldisplay.GetBool("gl-allow-software-renderer", false); - -bool bResponsive_minimized_fullscreen_window = config_wgldisplay.GetBool("responsive-minimized-fullscreen-window",false); - -// Set this true to not attempt to use any of the function calls that -// will crab out WireGL. -bool support_wiregl = config_wgldisplay.GetBool("support-wiregl", false); - -// Set this true to enable HW swapbuffer frame-lock on 3dlabs cards -bool gl_swapbuffer_framelock = config_wgldisplay.GetBool("gl-swapbuffer-framelock", false); - -// if true, use ddraw's GetAvailVidMem to fail if driver says it has too little video mem -bool gl_do_vidmemsize_check = config_wgldisplay.GetBool("do-vidmemsize-check", true); - -// For now, set this true to use the IME correctly on Win2000, or -// false on Win98. This is temporary; once we have been able to -// verify that this distinction is actually necessary, we can replace -// this config variable with an actual OS detection. -bool ime_composition_w = config_wgldisplay.GetBool("ime-composition-w", true); - -extern void AtExitFn(void); - //////////////////////////////////////////////////////////////////// // Function: init_libwgldisplay // Description: Initializes the library. This must be called at @@ -78,31 +46,12 @@ init_libwgldisplay() { initialized = true; wglGraphicsPipe::init_type(); - GraphicsPipe::get_factory().register_factory( - wglGraphicsPipe::get_class_type(), - wglGraphicsPipe::make_wglGraphicsPipe); wglGraphicsWindow::init_type(); - GraphicsWindow::get_factory().register_factory( - wglGraphicsWindow::get_class_type(), - wglGraphicsWindow::make_wglGraphicsWindow); - atexit(AtExitFn); - - set_global_parameters(); + GraphicsPipeSelection *selection = GraphicsPipeSelection::get_global_ptr(); + selection->add_pipe_type(wglGraphicsPipe::get_class_type(), + wglGraphicsPipe::pipe_constructor); } -// cant use global var cleanly because global var static init executed after init_libwgl(), incorrectly reiniting var -Filename get_icon_filename_2() { - string iconname = config_wgldisplay.GetString("win32-window-icon",""); - return ExecutionEnvironment::expand_string(iconname); -} +int gl_force_pixfmt = config_wgldisplay.GetInt("gl-force-pixfmt", 0); -Filename get_color_cursor_filename_2() { - string cursorname = config_wgldisplay.GetString("win32-color-cursor",""); - return ExecutionEnvironment::expand_string(cursorname); -} - -Filename get_mono_cursor_filename_2() { - string cursorname = config_wgldisplay.GetString("win32-mono-cursor",""); - return ExecutionEnvironment::expand_string(cursorname); -} diff --git a/panda/src/wgldisplay/config_wgldisplay.h b/panda/src/wgldisplay/config_wgldisplay.h index b819a6271f..34908c35bb 100644 --- a/panda/src/wgldisplay/config_wgldisplay.h +++ b/panda/src/wgldisplay/config_wgldisplay.h @@ -1,5 +1,5 @@ // Filename: config_wgldisplay.h -// Created by: mike (07Oct99) +// Created by: drose (20Dec02) // //////////////////////////////////////////////////////////////////// // @@ -16,33 +16,16 @@ // //////////////////////////////////////////////////////////////////// -#ifndef __CONFIG_WGLDISPLAY_H__ -#define __CONFIG_WGLDISPLAY_H__ +#ifndef CONFIG_WGLDISPLAY_H +#define CONFIG_WGLDISPLAY_H -#include -#include -#include +#include "pandabase.h" +#include "notifyCategoryProxy.h" NotifyCategoryDecl(wgldisplay, EXPCL_PANDAGL, EXPTP_PANDAGL); -// for some reason there is a conflict with the pandadx versions of get_icon_filename during linking, -// so appended '_2' to name -extern Filename get_icon_filename_2(); -extern Filename get_color_cursor_filename_2(); -extern Filename get_mono_cursor_filename_2(); - -extern bool gl_show_fps_meter; -extern float gl_fps_meter_update_interval; -extern bool gl_sync_video; -extern bool gl_swapbuffer_framelock; -extern int gl_forced_pixfmt; -extern bool bResponsive_minimized_fullscreen_window; -extern bool gl_do_vidmemsize_check; -extern bool support_wiregl; -extern bool ime_composition_w; -extern bool wgl_force_sw_renderer; -extern bool wgl_allow_sw_renderer; - extern EXPCL_PANDAGL void init_libwgldisplay(); -#endif /* __CONFIG_WGLDISPLAY_H__ */ +extern int gl_force_pixfmt; + +#endif diff --git a/panda/src/wgldisplay/test_wgl.cxx b/panda/src/wgldisplay/test_wgl.cxx deleted file mode 100644 index a14a693405..0000000000 --- a/panda/src/wgldisplay/test_wgl.cxx +++ /dev/null @@ -1,78 +0,0 @@ -// Filename: test_wgl.cxx -// Created by: mike (02Feb00) -// -//////////////////////////////////////////////////////////////////// -// -// 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 -#include -#include -#include - -#include "wglGraphicsWindow.h" - -PT(GraphicsPipe) main_pipe; -PT(GraphicsWindow) main_win; -PT_NamedNode render; - -void render_frame(GraphicsPipe *pipe) { - GraphicsPipe::wins_iterator wi; - for (wi = pipe->get_win_begin(); - wi != pipe->get_win_end(); - ++wi) { - (*wi)->get_gsg()->render_frame(); - } -} - -void display_func(void) { - render_frame(main_pipe); -} - -int main() { - - GraphicsPipe::resolve_modules(); - - cout << "Known pipe types:" << endl; - GraphicsPipe::PipeFactory::FactoryTypesIter pti; - for (pti = GraphicsPipe::_factory.get_types_begin(); - pti != GraphicsPipe::_factory.get_types_end(); ++pti) { - cout << " " << (*pti) << endl; - } - cout << "after Known pipe types" << endl; - - GraphicsPipe::PipeFactory& factory = GraphicsPipe::_factory; - GraphicsPipe::PipePrioritiesIter pribegin = - GraphicsPipe::get_priorities_begin(); - GraphicsPipe::PipePrioritiesIter priend = GraphicsPipe::get_priorities_end(); - - GraphicsPipe::PipeParams ps1; - if (pribegin == priend) - main_pipe = factory.instance(InteractiveGraphicsPipe::get_class_type(), - ps1.begin(), ps1.end()); - else - main_pipe = factory.instance(InteractiveGraphicsPipe::get_class_type(), - ps1.begin(), ps1.end(), pribegin, priend); - nassertr(main_pipe != (GraphicsPipe*)0L, 0); - cout << "Opened a '" << main_pipe->get_type().get_name() - << "' interactive graphics pipe." << endl; - - main_win = new wglGraphicsWindow(main_pipe); -#if 0 - main_win->register_draw_function(display_func); - main_win->main_loop(); -#endif - - return 0; -} diff --git a/panda/src/wgldisplay/wglGraphicsPipe.I b/panda/src/wgldisplay/wglGraphicsPipe.I new file mode 100644 index 0000000000..92b37a7f46 --- /dev/null +++ b/panda/src/wgldisplay/wglGraphicsPipe.I @@ -0,0 +1,17 @@ +// Filename: wglGraphicsPipe.I +// Created by: drose (20Dec02) +// +//////////////////////////////////////////////////////////////////// +// +// 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 . +// +//////////////////////////////////////////////////////////////////// diff --git a/panda/src/wgldisplay/wglGraphicsPipe.cxx b/panda/src/wgldisplay/wglGraphicsPipe.cxx index e08696bdd9..6e4d829848 100644 --- a/panda/src/wgldisplay/wglGraphicsPipe.cxx +++ b/panda/src/wgldisplay/wglGraphicsPipe.cxx @@ -1,5 +1,5 @@ // Filename: wglGraphicsPipe.cxx -// Created by: mike (09Jan97) +// Created by: drose (20Dec02) // //////////////////////////////////////////////////////////////////// // @@ -15,68 +15,48 @@ // panda3d@yahoogroups.com . // //////////////////////////////////////////////////////////////////// + #include "wglGraphicsPipe.h" #include "config_wgldisplay.h" -//////////////////////////////////////////////////////////////////// -// Static variables -//////////////////////////////////////////////////////////////////// TypeHandle wglGraphicsPipe::_type_handle; -wglGraphicsPipe::wglGraphicsPipe(const PipeSpecifier& spec) - : InteractiveGraphicsPipe(spec) -{} +//////////////////////////////////////////////////////////////////// +// Function: wglGraphicsPipe::Constructor +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +wglGraphicsPipe:: +wglGraphicsPipe() { +} //////////////////////////////////////////////////////////////////// -// Function: wglGraphicsPipe::get_window_type +// Function: wglGraphicsPipe::Destructor // Access: Public, Virtual -// Description: Returns the TypeHandle of the kind of window -// preferred by this kind of pipe. +// Description: //////////////////////////////////////////////////////////////////// -TypeHandle wglGraphicsPipe:: -get_window_type() const { - return wglGraphicsWindow::get_class_type(); +wglGraphicsPipe:: +~wglGraphicsPipe() { } -GraphicsPipe *wglGraphicsPipe:: -make_wglGraphicsPipe(const FactoryParams ¶ms) { - GraphicsPipe::PipeSpec *pipe_param; - if (!get_param_into(pipe_param, params)) { - return new wglGraphicsPipe(PipeSpecifier()); - } else { - return new wglGraphicsPipe(pipe_param->get_specifier()); - } +//////////////////////////////////////////////////////////////////// +// Function: wglGraphicsPipe::pipe_constructor +// Access: Public, Static +// Description: This function is passed to the GraphicsPipeSelection +// object to allow the user to make a default +// wglGraphicsPipe. +//////////////////////////////////////////////////////////////////// +PT(GraphicsPipe) wglGraphicsPipe:: +pipe_constructor() { + return new wglGraphicsPipe; } - -TypeHandle wglGraphicsPipe::get_class_type(void) { - return _type_handle; -} - -const char *pipe_type_name="wglGraphicsPipe"; - -void wglGraphicsPipe::init_type(void) { - InteractiveGraphicsPipe::init_type(); - register_type(_type_handle, pipe_type_name, - InteractiveGraphicsPipe::get_class_type()); -} - -TypeHandle wglGraphicsPipe::get_type(void) const { - return get_class_type(); -} - -wglGraphicsPipe::wglGraphicsPipe(void) { - wgldisplay_cat.error() - << pipe_type_name <<"s should not be created with the default constructor" << endl; -} - -wglGraphicsPipe::wglGraphicsPipe(const wglGraphicsPipe&) { - wgldisplay_cat.error() - << pipe_type_name << "s should not be copied" << endl; -} - -wglGraphicsPipe& wglGraphicsPipe::operator=(const wglGraphicsPipe&) { - wgldisplay_cat.error() - << pipe_type_name << "s should not be assigned" << endl; - return *this; +//////////////////////////////////////////////////////////////////// +// Function: wglGraphicsPipe::make_window +// Access: Protected, Virtual +// Description: Creates a new window on the pipe, if possible. +//////////////////////////////////////////////////////////////////// +PT(GraphicsWindow) wglGraphicsPipe:: +make_window() { + return new wglGraphicsWindow(this); } diff --git a/panda/src/wgldisplay/wglGraphicsPipe.h b/panda/src/wgldisplay/wglGraphicsPipe.h index 35090b212a..379299e805 100644 --- a/panda/src/wgldisplay/wglGraphicsPipe.h +++ b/panda/src/wgldisplay/wglGraphicsPipe.h @@ -1,5 +1,5 @@ // Filename: wglGraphicsPipe.h -// Created by: mike (09Jan97) +// Created by: drose (20Dec02) // //////////////////////////////////////////////////////////////////// // @@ -15,49 +15,47 @@ // panda3d@yahoogroups.com . // //////////////////////////////////////////////////////////////////// + #ifndef WGLGRAPHICSPIPE_H #define WGLGRAPHICSPIPE_H -// -//////////////////////////////////////////////////////////////////// -// Includes -//////////////////////////////////////////////////////////////////// -#include -#include -#include -#include "wglGraphicsWindow.h" -#define WINDOWS_LEAN_AND_MEAN -#include -#undef WINDOWS_LEAN_AND_MEAN +#include "pandabase.h" +#include "winGraphicsPipe.h" //////////////////////////////////////////////////////////////////// // Class : wglGraphicsPipe -// Description : +// Description : This graphics pipe represents the interface for +// creating OpenGL graphics windows on the various +// Windows OSes. //////////////////////////////////////////////////////////////////// -class EXPCL_PANDAGL wglGraphicsPipe : public InteractiveGraphicsPipe { +class EXPCL_PANDAGL wglGraphicsPipe : public WinGraphicsPipe { public: - wglGraphicsPipe(const PipeSpecifier&); + wglGraphicsPipe(); + virtual ~wglGraphicsPipe(); - virtual TypeHandle get_window_type() const; + static PT(GraphicsPipe) pipe_constructor(); + +protected: + virtual PT(GraphicsWindow) make_window(); public: - - static GraphicsPipe* make_wglGraphicsPipe(const FactoryParams ¶ms); - - static TypeHandle get_class_type(); - static void init_type(); - virtual TypeHandle get_type() const; + static TypeHandle get_class_type() { + return _type_handle; + } + static void init_type() { + WinGraphicsPipe::init_type(); + register_type(_type_handle, "wglGraphicsPipe", + WinGraphicsPipe::get_class_type()); + } + virtual TypeHandle get_type() const { + return get_class_type(); + } virtual TypeHandle force_init_type() {init_type(); return get_class_type();} private: - static TypeHandle _type_handle; - -protected: - - wglGraphicsPipe(); - wglGraphicsPipe(const wglGraphicsPipe&); - wglGraphicsPipe& operator=(const wglGraphicsPipe&); }; +#include "wglGraphicsPipe.I" + #endif diff --git a/panda/src/wgldisplay/wglGraphicsWindow.I b/panda/src/wgldisplay/wglGraphicsWindow.I new file mode 100644 index 0000000000..27a87d1513 --- /dev/null +++ b/panda/src/wgldisplay/wglGraphicsWindow.I @@ -0,0 +1,17 @@ +// Filename: wglGraphicsWindow.I +// Created by: drose (20Dec02) +// +//////////////////////////////////////////////////////////////////// +// +// 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 . +// +//////////////////////////////////////////////////////////////////// diff --git a/panda/src/wgldisplay/wglGraphicsWindow.cxx b/panda/src/wgldisplay/wglGraphicsWindow.cxx index 3d70af589d..4af87ba397 100644 --- a/panda/src/wgldisplay/wglGraphicsWindow.cxx +++ b/panda/src/wgldisplay/wglGraphicsWindow.cxx @@ -1,5 +1,5 @@ -// Filename: wcrGraphicsWindow.cxx -// Created by: +// Filename: wglGraphicsWindow.cxx +// Created by: drose (20Dec02) // //////////////////////////////////////////////////////////////////// // @@ -17,987 +17,371 @@ //////////////////////////////////////////////////////////////////// #include "wglGraphicsWindow.h" -#include "wglGraphicsPipe.h" #include "config_wgldisplay.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -//#include -#include -#include "Win32Defs.h" +#include "config_windisplay.h" +#include "wglGraphicsPipe.h" +#include "glGraphicsStateGuardian.h" -#ifdef DO_PSTATS -#include -#endif - -#define WGL_WGLEXT_PROTOTYPES -#include "wglext.h" - -//////////////////////////////////////////////////////////////////// -// Static variables -//////////////////////////////////////////////////////////////////// -TypeHandle wglGraphicsWindow::_type_handle; - -static bool wc_registered = false; - -#define FONT_BITMAP_OGLDISPLAYLISTNUM 1000 // an arbitrary ID # - -#define LAST_ERROR 0 -#define ERRORBOX_TITLE "Panda3D Error" -#define WGL_WINDOWCLASSNAME "wglDisplay" - -#define PAUSED_TIMER_ID 7 // completely arbitrary choice - -typedef map HWND_PANDAWIN_MAP; - -HWND_PANDAWIN_MAP hwnd_pandawin_map; -wglGraphicsWindow *global_wglwinptr=NULL; // need this for temporary windproc +#include typedef enum {Software, MCD, ICD} OGLDriverType; -static char *OGLDrvStrings[3] = {"Software","MCD","ICD"}; +static const char * const OGLDrvStrings[] = { "Software", "MCD", "ICD" }; -LONG WINAPI static_window_proc(HWND hwnd, UINT msg, WPARAM wparam,LPARAM lparam); -extern char *ConvDDErrorToString(const HRESULT &error); - -// because we dont have access to ModifierButtons, as a hack just synchronize state of these -// keys on get/lose keybd focus -#define NUM_MODIFIER_KEYS 16 -unsigned int hardcoded_modifier_buttons[NUM_MODIFIER_KEYS]={VK_SHIFT,VK_MENU,VK_CONTROL,VK_SPACE,VK_TAB, - VK_UP,VK_DOWN,VK_LEFT,VK_RIGHT,VK_PRIOR,VK_NEXT,VK_HOME,VK_END, - VK_INSERT,VK_DELETE,VK_ESCAPE}; - -// dont pick any video modes < MIN_REFRESH_RATE Hz -#define MIN_REFRESH_RATE 60 -// EnumDisplaySettings may indicate 0 or 1 for refresh rate, which means use driver default rate (assume its >min_refresh_rate) -#define ACCEPTABLE_REFRESH_RATE(RATE) ((RATE >= MIN_REFRESH_RATE) || (RATE==0) || (RATE==1)) - -void PrintErrorMessage(DWORD msgID) { - LPTSTR pMessageBuffer; - - if (msgID==LAST_ERROR) - msgID=GetLastError(); - - FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, - NULL,msgID, - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), //The user default language - (LPTSTR) &pMessageBuffer, // the weird ptrptr->ptr cast is intentional, see FORMAT_MESSAGE_ALLOCATE_BUFFER - 1024, NULL); - MessageBox(GetDesktopWindow(),pMessageBuffer,_T(ERRORBOX_TITLE),MB_OK); - wgldisplay_cat.fatal() << "System error msg: " << pMessageBuffer << endl; - LocalFree(pMessageBuffer); -} - -// fn exists so AtExitFn can call it without refcntr blowing up since its !=0 -void wglGraphicsWindow::DestroyMe(bool bAtExitFnCalled) { - - _exiting_window = true; // needed before DestroyWindow call - - // several GL drivers (voodoo,ATI, not nvidia) crash if we call these wgl deletion routines from - // an atexit() fn. Possible that GL has already unloaded itself. So we just wont call them for now - // for that case, we're exiting the app anyway. - if (!bAtExitFnCalled) { - // to do gl releases, we need to have the context be current - if ((_hdc!=NULL)&&(_context!=NULL)) { - // need to bypass make_current() since it checks _window_active which we need to ignore - HGLRC current_context = wglGetCurrentContext(); - HDC current_dc = wglGetCurrentDC(); - - if ((current_context != _context) || (current_dc != _hdc)) { - if (!wglMakeCurrent(_hdc, _context)) { - PrintErrorMessage(LAST_ERROR); - } - } - report_errors(); - } - - if (gl_show_fps_meter) - glDeleteLists(FONT_BITMAP_OGLDISPLAYLISTNUM, 128); - - report_errors(); - - // implicitly calls gsg destructors which release GL objects (textures, display lists, etc) - release_gsg(); - - report_errors(); - // cant report errors after we set cur context to NULL - - HGLRC curcxt=wglGetCurrentContext(); - if (curcxt!=NULL) - unmake_current(); - - if (_context!=NULL) { - wglDeleteContext(_context); - _context = NULL; - } - } - - if (_hdc!=NULL) { - ReleaseDC(_mwindow,_hdc); - _hdc = NULL; - } - - if ((_hOldForegroundWindow!=NULL) && (_mwindow==GetForegroundWindow())) { - SetForegroundWindow(_hOldForegroundWindow); - } - - if (_mwindow!=NULL) { - if (_bLoadedCustomCursor && _hMouseCursor!=NULL) - DestroyCursor(_hMouseCursor); - - DestroyWindow(_mwindow); - hwnd_pandawin_map.erase(_mwindow); - _mwindow = NULL; - } - - if (_pCurrent_display_settings!=NULL) { - delete _pCurrent_display_settings; - _pCurrent_display_settings = NULL; - } - - if (_props._fullscreen) { - // revert to default display mode - ChangeDisplaySettings(NULL,0x0); - } -} - -void wglGraphicsWindow::do_close_window() { - GraphicsWindow::do_close_window(); - DestroyMe(false); -} +TypeHandle wglGraphicsWindow::_type_handle; //////////////////////////////////////////////////////////////////// -// Function: Destructor -// Access: +// Function: wglGraphicsWindow::Constructor +// Access: Public // Description: //////////////////////////////////////////////////////////////////// -wglGraphicsWindow::~wglGraphicsWindow() { - close_window(); +wglGraphicsWindow:: +wglGraphicsWindow(GraphicsPipe *pipe) : + WinGraphicsWindow(pipe) +{ + _context = (HGLRC)0; + _hdc = (HDC)0; } -void DestroyAllWindows(bool bAtExitFnCalled) { - // need to go through all windows in map var and delete them - while(!hwnd_pandawin_map.empty()) { - // cant use a for loop cause DestroyMe erases things out from under us, so iterator is invalid - HWND_PANDAWIN_MAP::iterator pwin = hwnd_pandawin_map.begin(); - if ((*pwin).second != NULL) - (*pwin).second->DestroyMe(bAtExitFnCalled); - } -} - -void AtExitFn() { -#ifdef _DEBUG - wgldisplay_cat.spam() << "AtExitFn called\n"; -#endif - - restore_global_parameters(); - - DestroyAllWindows(true); -} - -// spare me the trouble of linking with dxguid.lib or defining ALL the dx guids in this .obj by #defining INITGUID -#define MY_DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \ - EXTERN_C const GUID DECLSPEC_SELECTANY name \ - = { l, w1, w2, { b1, b2, b3, b4, b5, b6, b7, b8 } } - -MY_DEFINE_GUID(IID_IDirectDraw2, 0xB3A6F3E0,0x2B43,0x11CF,0xA2,0xDE,0x00,0xAA,0x00,0xB9,0x33,0x56); - //////////////////////////////////////////////////////////////////// -// Function: GetAvailVidMem -// Description: Uses DDraw to get available video memory +// Function: wglGraphicsWindow::Destructor +// Access: Public, Virtual +// Description: //////////////////////////////////////////////////////////////////// -static DWORD GetAvailVidMem() { - - LPDIRECTDRAW2 pDD2; - LPDIRECTDRAW pDD; - HRESULT hr; - - typedef HRESULT (WINAPI *DIRECTDRAWCREATEPROC)(GUID FAR *lpGUID,LPDIRECTDRAW FAR *lplpDD,IUnknown FAR *pUnkOuter); - DIRECTDRAWCREATEPROC pfnDDCreate=NULL; - - HINSTANCE DDHinst = LoadLibrary("ddraw.dll"); - if (DDHinst == 0) { - wgldisplay_cat.fatal() << "LoadLibrary() can't find DDRAW.DLL!" << endl; - exit(1); - } - - pfnDDCreate = (DIRECTDRAWCREATEPROC) GetProcAddress(DDHinst, "DirectDrawCreate"); - - // just use DX5 DD interface, since that's the minimum ver we need - if (NULL == pfnDDCreate) { - wgldisplay_cat.fatal() << "GetProcAddress failed on DirectDrawCreate\n"; - exit(1); - } - - // Create the Direct Draw Object - hr = (*pfnDDCreate)((GUID *)DDCREATE_HARDWAREONLY, &pDD, NULL); - if (hr != DD_OK) { - wgldisplay_cat.fatal() - << "DirectDrawCreate failed : result = " << ConvDDErrorToString(hr) << endl; - exit(1); - } - - FreeLibrary(DDHinst); //undo LoadLib above, decrement ddrawl.dll refcnt (after DDrawCreate, since dont want to unload/reload) - - // need DDraw2 interface for GetAvailVidMem - hr = pDD->QueryInterface(IID_IDirectDraw2, (LPVOID *)&pDD2); - if (hr != DD_OK) { - wgldisplay_cat.fatal() << "DDraw QueryInterface failed : result = " << ConvDDErrorToString(hr) << endl; - exit(1); - } - - pDD->Release(); - - // Now we try to figure out if we can use requested screen resolution and best - // rendertarget bpp and still have at least 2 meg of texture vidmem - - // Get Current VidMem avail. Note this is only an estimate, when we switch to fullscreen - // mode from desktop, more vidmem will be available (typically 1.2 meg). I dont want - // to switch to fullscreen more than once due to the annoying monitor flicker, so try - // to figure out optimal mode using this estimate - DDSCAPS ddsCaps; - DWORD dwTotal,dwFree; - ZeroMemory(&ddsCaps,sizeof(DDSCAPS)); - ddsCaps.dwCaps = DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM; // dont count AGP mem! - if (FAILED(hr = pDD2->GetAvailableVidMem(&ddsCaps,&dwTotal,&dwFree))) { - if (hr==DDERR_NODIRECTDRAWHW) { - if (wgldisplay_cat.is_debug()) - wgldisplay_cat.debug() << "GetAvailableVidMem returns no-DDraw HW, assuming we have plenty of vidmem\n"; - dwTotal=dwFree=0x7FFFFFFF; - } else { - wgldisplay_cat.fatal() << "GetAvailableVidMem failed : result = " << ConvDDErrorToString(hr) << endl; - exit(1); - } - } else { - if (wgldisplay_cat.is_debug()) - wgldisplay_cat.debug() << "before FullScreen switch: GetAvailableVidMem returns Total: " << dwTotal/1000000.0 << " Free: " << dwFree/1000000.0 << endl; - if (dwTotal==0) { - if (wgldisplay_cat.is_debug()) - wgldisplay_cat.debug() << "GetAvailVidMem returns bogus total of 0, assuming we have plenty of vidmem\n"; - dwTotal=dwFree=0x7FFFFFFF; - } - } - - pDD2->Release(); // bye-bye ddraw - - return dwFree; +wglGraphicsWindow:: +~wglGraphicsWindow() { } -bool find_acceptable_display_mode(DWORD dwWidth,DWORD dwHeight,DWORD bpp,DEVMODE &dm) { - int modenum=0; +//////////////////////////////////////////////////////////////////// +// Function: wglGraphicsWindow::make_gsg +// Access: Public, Virtual +// Description: Creates a new GSG for the window and stores it in the +// _gsg pointer. This should only be called from within +// the draw thread. +//////////////////////////////////////////////////////////////////// +void wglGraphicsWindow:: +make_gsg() { + nassertv(_gsg == (GraphicsStateGuardian *)NULL); - // look for acceptable mode - while(1) { - ZeroMemory(&dm, sizeof(dm)); - dm.dmSize = sizeof(dm); + _context = wglCreateContext(_hdc); + if (!_context) { + wgldisplay_cat.error() + << "Could not create GL context.\n"; + return; + } - if (!EnumDisplaySettings(NULL,modenum,&dm)) - break; + // And make sure the new context is current. + wglMakeCurrent(_hdc, _context); - if ((dm.dmPelsWidth==dwWidth) && (dm.dmPelsHeight==dwHeight) && - (dm.dmBitsPerPel==bpp) && ACCEPTABLE_REFRESH_RATE(dm.dmDisplayFrequency)) { - return true; - } - modenum++; - } + // Now we can make a GSG. + _gsg = new GLGraphicsStateGuardian(this); +} +//////////////////////////////////////////////////////////////////// +// Function: wglGraphicsWindow::release_gsg +// Access: Public, Virtual +// Description: Releases the current GSG pointer, if it is currently +// held, and resets the GSG to NULL. This should only +// be called from within the draw thread. +//////////////////////////////////////////////////////////////////// +void wglGraphicsWindow:: +release_gsg() { + if (_gsg != (GraphicsStateGuardian *)NULL) { + GraphicsWindow::release_gsg(); + wglDeleteContext(_context); + _context = (HGLRC)0; + } +} + +//////////////////////////////////////////////////////////////////// +// Function: wglGraphicsWindow::make_current +// Access: Public, Virtual +// Description: This function will be called within the draw thread +// during begin_frame() to ensure the graphics context +// is ready for drawing. +//////////////////////////////////////////////////////////////////// +void wglGraphicsWindow:: +make_current() { + nassertv(_gsg != (GraphicsStateGuardian *)NULL); + wglMakeCurrent(_hdc, _context); +} + +//////////////////////////////////////////////////////////////////// +// Function: wglGraphicsWindow::begin_flip +// Access: Public, Virtual +// Description: This function will be called within the draw thread +// after end_frame() has been called on all windows, to +// initiate the exchange of the front and back buffers. +// +// This should instruct the window to prepare for the +// flip at the next video sync, but it should not wait. +// +// We have the two separate functions, begin_flip() and +// end_flip(), to make it easier to flip all of the +// windows at the same time. +//////////////////////////////////////////////////////////////////// +void wglGraphicsWindow:: +begin_flip() { + if (_gsg != (GraphicsStateGuardian *)NULL) { + wglMakeCurrent(_hdc, _context); + glFinish(); + SwapBuffers(_hdc); + } +} + +//////////////////////////////////////////////////////////////////// +// Function: wglGraphicsWindow::open_window +// Access: Protected, Virtual +// Description: Opens the window right now. Called from the window +// thread. Returns true if the window is successfully +// opened, or false if there was a problem. +//////////////////////////////////////////////////////////////////// +bool wglGraphicsWindow:: +open_window() { + if (!WinGraphicsWindow::open_window()) { return false; -} - -//////////////////////////////////////////////////////////////////// -// Function: config -// Access: -// Description: -//////////////////////////////////////////////////////////////////// -void wglGraphicsWindow::config() { - - GraphicsWindow::config(); - - HINSTANCE hinstance = GetModuleHandle(NULL); - HWND hDesktopWindow = GetDesktopWindow(); - - global_wglwinptr = this; // need this until we get an HWND from CreateWindow - - _exiting_window = false; - _return_control_to_app = false; - _bIsLowVidMemCard = false; - _active_minimized_fullscreen = false; - _PandaPausedTimer = NULL; - _context = NULL; - _hdc = NULL; - _window_active = true; - _pCurrent_display_settings = NULL; - _mwindow = NULL; - _gsg = NULL; - ZeroMemory(&_pixelformat,sizeof(_pixelformat)); - _hOldForegroundWindow=GetForegroundWindow(); - - WNDCLASS wc; - - // these fns arent defined on win95, so get dynamic ptrs to them to avoid - // ugly DLL loader failures on w95 - HINSTANCE hUser32 = (HINSTANCE) LoadLibrary("user32.dll"); - assert(hUser32); - _pfnTrackMouseEvent = (PFN_TRACKMOUSEEVENT) GetProcAddress(hUser32, "TrackMouseEvent"); - FreeLibrary(hUser32); - - // Clear before filling in window structure! - ZeroMemory(&wc, sizeof(WNDCLASS)); - wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; - wc.lpfnWndProc = (WNDPROC) static_window_proc; - wc.hInstance = hinstance; - - string windows_icon_filename = get_icon_filename_2().to_os_specific(); - string windows_mono_cursor_filename = get_mono_cursor_filename_2().to_os_specific(); - - if (!windows_icon_filename.empty()) { - // Note: LoadImage seems to cause win2k internal heap corruption (outputdbgstr warnings) - // if icon is more than 8bpp - - // loads a .ico fmt file - wc.hIcon = (HICON) LoadImage(NULL, windows_icon_filename.c_str(), IMAGE_ICON, 0, 0, LR_LOADFROMFILE); - - if (wc.hIcon==NULL) { - wgldisplay_cat.warning() << "windows icon filename '" << windows_icon_filename << "' not found!!\n"; - } - } else { - wc.hIcon = NULL; // use default app icon - } - - _bLoadedCustomCursor = false; - if (!windows_mono_cursor_filename.empty()) { - // Note: LoadImage seems to cause win2k internal heap corruption (outputdbgstr warnings) - // if icon is more than 8bpp (because it was 'mapping' 16bpp colors to the device?) - - DWORD load_flags = LR_LOADFROMFILE; - - if (_props._fullscreen) { - // I think cursors should use LR_CREATEDIBSECTION since they should not be mapped to the device palette (in the case of 256-color cursors) - // since they are not going to be used on the desktop - load_flags |= LR_CREATEDIBSECTION; - } - - // loads a .cur fmt file - _hMouseCursor = (HCURSOR) LoadImage(NULL, windows_mono_cursor_filename.c_str(), IMAGE_CURSOR, 0, 0, load_flags); - - if (_hMouseCursor==NULL) { - wgldisplay_cat.warning() << "windows cursor filename '" << windows_mono_cursor_filename << "' not found!!\n"; - } - _bLoadedCustomCursor = true; - } else { - _hMouseCursor = LoadCursor(NULL, IDC_ARROW); - } - - if (!wc_registered) { - // We only need to register the window class once per session. - - wc.hCursor = _hMouseCursor; // even if cursor isnt visible, we need to load it so its visible in client-area window border - wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH); - wc.lpszMenuName = NULL; - wc.lpszClassName = WGL_WINDOWCLASSNAME; - - if (!RegisterClass(&wc)) { - wgldisplay_cat.error() << "could not register window class!" << endl; - } - wc_registered = true; - } - -// from MSDN: -// An OpenGL window has its own pixel format. Because of this, only device contexts retrieved -// for the client area of an OpenGL window are allowed to draw into the window. As a result, an -// OpenGL window should be created with the WS_CLIPCHILDREN and WS_CLIPSIBLINGS styles. Additionally, -// the window class attribute should not include the CS_PARENTDC style. - - DWORD window_style = WS_POPUP | WS_SYSMENU | WS_CLIPCHILDREN | WS_CLIPSIBLINGS; // for CreateWindow - - // rect now contains the coords for the entire window, not the client - if (_props._fullscreen) { - DWORD dwWidth = _props._xsize; - DWORD dwHeight = _props._ysize; - - HDC scrnDC=GetDC(hDesktopWindow); - DWORD drvr_ver=GetDeviceCaps(scrnDC,DRIVERVERSION); - DWORD cur_bitdepth=GetDeviceCaps(scrnDC,BITSPIXEL); - DWORD cur_scrnwidth=GetDeviceCaps(scrnDC,HORZRES); - DWORD cur_scrnheight=GetDeviceCaps(scrnDC,VERTRES); - ReleaseDC(hDesktopWindow,scrnDC); - - DWORD dwFullScreenBitDepth=cur_bitdepth; - - #define LOWVIDMEMTHRESHOLD 3500000 - if (gl_do_vidmemsize_check && (GetAvailVidMem() < LOWVIDMEMTHRESHOLD)) { - _bIsLowVidMemCard = true; - wgldisplay_cat.debug() << "small video memory card detect, switching fullscreen to minimum 640x480x16 config\n"; - // we're going to need 640x480 at 16 bit to save enough tex vidmem - dwFullScreenBitDepth=16; - dwWidth=640; - dwHeight=480; - } - - DEVMODE dm; - if (!find_acceptable_display_mode(dwWidth,dwHeight,dwFullScreenBitDepth,dm)) { - wgldisplay_cat.fatal() << "Videocard has no supported display resolutions at specified res (" << dwWidth << " X " << dwHeight << " X " << dwFullScreenBitDepth <<")\n"; - exit(1); - } - - // I'd prefer to CreateWindow after DisplayChange in case it messes up GL somehow, - // but I need the window's black background to cover up the desktop during the mode change - _mwindow = CreateWindow(WGL_WINDOWCLASSNAME, _props._title.c_str(), - window_style,0,0,dwWidth,dwHeight,hDesktopWindow, NULL, hinstance, 0); - - // move window to top of zorder, - SetWindowPos(_mwindow, HWND_TOP, 0,0,0,0, SWP_NOMOVE | SWP_NOSENDCHANGING | SWP_NOSIZE); - - ShowWindow(_mwindow, SW_SHOWNORMAL); - ShowWindow(_mwindow, SW_SHOWNORMAL); - - if(!SetForegroundWindow(_mwindow)) { - wgldisplay_cat.warning() << "SetForegroundWindow() failed!\n"; - } - - int chg_result = ChangeDisplaySettings(&dm, CDS_FULLSCREEN); - - if (chg_result!=DISP_CHANGE_SUCCESSFUL) { - wgldisplay_cat.fatal() << "ChangeDisplaySettings failed (error code: " << chg_result <<") for specified res (" << dwWidth << " X " << dwHeight << " X " << dwFullScreenBitDepth <<"), " << dm.dmDisplayFrequency << "Hz\n"; - exit(1); - } - - _pCurrent_display_settings = new(DEVMODE); - memcpy(_pCurrent_display_settings,&dm,sizeof(DEVMODE)); - - _props._xorg = 0; - _props._yorg = 0; - _props._xsize = dwWidth; - _props._ysize = dwHeight; - } else { - - RECT win_rect; - SetRect(&win_rect, _props._xorg, _props._yorg, _props._xorg + _props._xsize, - _props._yorg + _props._ysize); - - if (_props._border) { - window_style |= WS_OVERLAPPEDWINDOW; - } - - BOOL bRes = AdjustWindowRect(&win_rect, window_style, FALSE); //compute window size based on desired client area size - - if (!bRes) { - wgldisplay_cat.fatal() << "AdjustWindowRect failed!" << endl; - exit(1); - } - - // make sure origin is on screen, slide far bounds over if necessary - if (win_rect.left < 0) { - win_rect.right += abs(win_rect.left); win_rect.left = 0; - } - if (win_rect.top < 0) { - win_rect.bottom += abs(win_rect.top); win_rect.top = 0; - } - - _mwindow = CreateWindow(WGL_WINDOWCLASSNAME, _props._title.c_str(), - window_style, win_rect.left, win_rect.top, win_rect.right-win_rect.left, - win_rect.bottom-win_rect.top, - NULL, NULL, hinstance, 0); - - SetForegroundWindow(_mwindow); } - wgldisplay_cat.info() << "opening " << _props._xsize << "x" << _props._ysize - << (_props._fullscreen ? " fullscreen" : " regular") << " window\n"; - - if (!_mwindow) { - wgldisplay_cat.fatal() << "CreateWindow() failed!" << endl; - PrintErrorMessage(LAST_ERROR); - exit(1); - } - - // Determine the initial open status of the IME. - _ime_open = false; - _ime_active = false; - HIMC hIMC = ImmGetContext(_mwindow); - if (hIMC != 0) { - _ime_open = (ImmGetOpenStatus(hIMC) != 0); - ImmReleaseContext(_mwindow, hIMC); - } - - // Check the version of the OS we are running. If we are running - // win2000, we must use ImmGetCompositionStringW() to report the - // characters returned by the IME, since WM_CHAR and - // ImmGetCompositionStringA() both just return question marks. - // However, this function doesn't work for Win98; on this OS, we - // have to use ImmGetCompositionStringA() instead, which returns an - // encoded string in shift-jis (which we then have to decode). - - // For now, this is user-configurable, to allow testing of this code - // on both OS's. After we verify that truth of the above claim, we - // should base this decision on GetVersionEx() or maybe - // VerifyVersionInfo(). - _ime_composition_w = ime_composition_w; - - hwnd_pandawin_map[_mwindow] = this; - global_wglwinptr = NULL; // get rid of any reference to this obj - - // move window to top of zorder - SetWindowPos(_mwindow, HWND_TOP, 0,0,0,0, SWP_NOMOVE | SWP_NOSENDCHANGING | SWP_NOSIZE | SWP_NOOWNERZORDER); - + // Set up the pixel format of the window appropriately for GL. _hdc = GetDC(_mwindow); - // Configure the framebuffer according to parameters specified in _props - // Initializes _pixelformat - int pfnum=choose_visual(); + int pfnum = choose_pfnum(); - if (gl_forced_pixfmt!=0) { + if (gl_force_pixfmt != 0) { if (wgldisplay_cat.is_debug()) - wgldisplay_cat.debug() << "overriding pixfmt choice algorithm (" << pfnum << ") with gl-force-pixfmt("<dwFlags & PFD_GENERIC_ACCELERATED) && (pfd->dwFlags & PFD_GENERIC_FORMAT)) - drvtype=MCD; - else if (!(pfd->dwFlags & PFD_GENERIC_ACCELERATED) && !(pfd->dwFlags & PFD_GENERIC_FORMAT)) - drvtype=ICD; - else { - drvtype=Software; - } - -#define PrintFlag(FLG) ((pfd->dwFlags & PFD_##FLG) ? (" PFD_" #FLG "|") : "") - wgldisplay_cat.spam() << "================================\n"; - - wgldisplay_cat.spam() << msg << ", " << OGLDrvStrings[drvtype] << " driver\n" - << "PFD flags: 0x" << (void*)pfd->dwFlags << " (" << - PrintFlag(GENERIC_ACCELERATED) << - PrintFlag(GENERIC_FORMAT) << - PrintFlag(DOUBLEBUFFER) << - PrintFlag(SUPPORT_OPENGL) << - PrintFlag(SUPPORT_GDI) << - PrintFlag(STEREO) << - PrintFlag(DRAW_TO_WINDOW) << - PrintFlag(DRAW_TO_BITMAP) << - PrintFlag(SWAP_EXCHANGE) << - PrintFlag(SWAP_COPY) << - PrintFlag(SWAP_LAYER_BUFFERS) << - PrintFlag(NEED_PALETTE) << - PrintFlag(NEED_SYSTEM_PALETTE) << - PrintFlag(SUPPORT_DIRECTDRAW) << ")\n" - << "PFD iPixelType: " << ((pfd->iPixelType==PFD_TYPE_RGBA) ? "PFD_TYPE_RGBA":"PFD_TYPE_COLORINDEX") << endl - << "PFD cColorBits: " << (DWORD)pfd->cColorBits << " R: " << (DWORD)pfd->cRedBits <<" G: " << (DWORD)pfd->cGreenBits <<" B: " << (DWORD)pfd->cBlueBits << endl - << "PFD cAlphaBits: " << (DWORD)pfd->cAlphaBits << " DepthBits: " << (DWORD)pfd->cDepthBits <<" StencilBits: " << (DWORD)pfd->cStencilBits <<" AccumBits: " << (DWORD)pfd->cAccumBits << endl; -} -#endif - -// this helper routine looks for either HW-only or SW-only format, but not both -// returns number of pixelformat -int wglGraphicsWindow::find_pixfmtnum(bool bLookforHW) { - int mask = _props._mask; - int want_depth_bits = _props._want_depth_bits; - int want_color_bits = _props._want_color_bits; - OGLDriverType drvtype; - - if (mask & W_MULTISAMPLE) { - wgldisplay_cat.error() << "config() - multisample not supported"<< endl; - mask &= ~W_MULTISAMPLE; - } - - if(wgldisplay_cat.is_debug()) - wgldisplay_cat.debug() << "mask =0x" << (void*) mask << endl; - - PIXELFORMATDESCRIPTOR pfd; - ZeroMemory(&pfd,sizeof(PIXELFORMATDESCRIPTOR)); - pfd.nSize=sizeof(PIXELFORMATDESCRIPTOR); - pfd.nVersion=1; - - // if (_props._fullscreen) { - // do anything different for fullscrn? - - // just use the pixfmt of the current desktop - - int MaxPixFmtNum=DescribePixelFormat(_hdc, 1, sizeof(PIXELFORMATDESCRIPTOR), &pfd); - int cur_bpp=GetDeviceCaps(_hdc,BITSPIXEL); - int pfnum; - - for(pfnum=1;pfnum<=MaxPixFmtNum;pfnum++) { - DescribePixelFormat(_hdc, pfnum, sizeof(PIXELFORMATDESCRIPTOR), &pfd); - - // official, nvidia sanctioned way. should be equiv to my algorithm - if ((pfd.dwFlags & PFD_GENERIC_FORMAT) != 0) - drvtype = Software; - else if (pfd.dwFlags & PFD_GENERIC_ACCELERATED) - drvtype = MCD; - else drvtype = ICD; - - #if MY_OLD_ALGORITHM - if ((pfd.dwFlags & PFD_GENERIC_ACCELERATED) && (pfd.dwFlags & PFD_GENERIC_FORMAT)) - drvtype=MCD; - else if (!(pfd.dwFlags & PFD_GENERIC_ACCELERATED) && !(pfd.dwFlags & PFD_GENERIC_FORMAT)) - drvtype=ICD; - else { - drvtype=Software; - continue; // skipping all SW fmts - } - #endif - - // skip driver types we are not looking for - if(bLookforHW) { - if(drvtype==Software) - continue; - } else { - if(drvtype!=Software) - continue; - } - - if ((pfd.iPixelType == PFD_TYPE_COLORINDEX) && !(mask & W_INDEX)) - continue; - - DWORD dwReqFlags=(PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW); - - if (wgldisplay_cat.is_debug()) { - wgldisplay_cat->debug() << "----------------" << endl; - - if (mask & W_ALPHA) - wgldisplay_cat->debug() << "want alpha, pfd says '" - << (int)(pfd.cAlphaBits) << "'" << endl; - if (mask & W_DEPTH) - wgldisplay_cat->debug() << "want depth, pfd says '" - << (int)(pfd.cDepthBits) << "'" << endl; - if (mask & W_STENCIL) - wgldisplay_cat->debug() << "want stencil, pfd says '" - << (int)(pfd.cStencilBits) << "'" << endl; - wgldisplay_cat->debug() << "final flag check " - << (int)(pfd.dwFlags & dwReqFlags) << " =? " - << (int)dwReqFlags << endl; - wgldisplay_cat->debug() << "pfd bits = " << (int)(pfd.cColorBits) - << endl; - wgldisplay_cat->debug() << "cur_bpp = " << cur_bpp << endl; - } - - if (mask & W_DOUBLE) - dwReqFlags|= PFD_DOUBLEBUFFER; - if ((mask & W_ALPHA) && (pfd.cAlphaBits==0)) - continue; - if ((mask & W_DEPTH) && (pfd.cDepthBits==0)) - continue; - if ((mask & W_STENCIL) && (pfd.cStencilBits==0)) - continue; - - if ((pfd.dwFlags & dwReqFlags)!=dwReqFlags) - continue; - - // now we ignore the specified want_color_bits for windowed mode - // instead we use the current screen depth - - if ((pfd.cColorBits!=cur_bpp) && (!((cur_bpp==16) && (pfd.cColorBits==15))) - && (!((cur_bpp==32) && (pfd.cColorBits==24)))) - continue; - // we've passed all the tests, go ahead and pick this fmt - // note: could go continue looping looking for more alpha bits or more depth bits - // so this would pick 16bpp depth buffer, probably not 24bpp - - break; - } - - if(pfnum>MaxPixFmtNum) - pfnum=0; - - return pfnum; -} - -//////////////////////////////////////////////////////////////////// -// Function: choose visual -// Access: -// Description: -//////////////////////////////////////////////////////////////////// -int wglGraphicsWindow::choose_visual(void) { +int wglGraphicsWindow:: +choose_pfnum() const { int pfnum; - bool bUsingSoftware=false; + bool bUsingSoftware = false; - if(wgl_force_sw_renderer) { - pfnum=find_pixfmtnum(false); + if (force_software_renderer) { + pfnum = find_pixfmtnum(false); + + if (pfnum == 0) { + wgldisplay_cat.error() + << "Couldn't find compatible software-renderer OpenGL pixfmt, check your window properties!\n"; + return 0; + } + bUsingSoftware = true; - if(pfnum==0) { - wgldisplay_cat.error() << "ERROR: couldn't find compatible software-renderer OpenGL pixfmt, check your window properties!\n"; - exit(1); + } else { + pfnum = find_pixfmtnum(true); + if (pfnum == 0) { + if (allow_software_renderer) { + pfnum = find_pixfmtnum(false); + if(pfnum == 0) { + wgldisplay_cat.error() + << "Couldn't find HW or Software OpenGL pixfmt appropriate for this desktop!!\n"; + } + } else { + wgldisplay_cat.error() + << "Couldn't find HW-accelerated OpenGL pixfmt appropriate for this desktop!!\n"; + } + + if (pfnum == 0) { + wgldisplay_cat.error() + << "make sure OpenGL driver is installed, and try reducing the screen size, reducing the\n" + << "desktop screen pixeldepth to 16bpp,and check your panda window properties\n"; + return 0; } bUsingSoftware=true; - } else { - pfnum=find_pixfmtnum(true); - if(pfnum==0) { - if(wgl_allow_sw_renderer) { - pfnum=find_pixfmtnum(false); - if(pfnum==0) { - wgldisplay_cat.error() << "ERROR: couldn't find HW or Software OpenGL pixfmt appropriate for this desktop!!\n"; - } - } else { - wgldisplay_cat.error() << "ERROR: couldn't find HW-accelerated OpenGL pixfmt appropriate for this desktop!!\n"; - } + } + } + + if (bUsingSoftware) { + wgldisplay_cat.info() + << "Couldn't find compatible OGL HW pixelformat, using software rendering.\n"; + } + + return pfnum; +} - if(pfnum==0) { - wgldisplay_cat.error() - << "make sure OpenGL driver is installed, and try reducing the screen size, reducing the\n" - << "desktop screen pixeldepth to 16bpp,and check your panda window properties\n"; - exit(1); - } - bUsingSoftware=true; +//////////////////////////////////////////////////////////////////// +// Function: wglGraphicsWindow::find_pixfmtnum +// Access: Private +// Description: This helper routine looks for either HW-only or +// SW-only format, but not both. Returns the +// pixelformat number, or 0 if a suitable format could +// not be found. +//////////////////////////////////////////////////////////////////// +int wglGraphicsWindow:: +find_pixfmtnum(bool bLookforHW) const { + int framebuffer_mode = _properties.get_framebuffer_mode(); + bool want_depth_bits = _properties.has_depth_bits(); + bool want_color_bits = _properties.has_color_bits(); + OGLDriverType drvtype; + + PIXELFORMATDESCRIPTOR pfd; + ZeroMemory(&pfd,sizeof(PIXELFORMATDESCRIPTOR)); + pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR); + pfd.nVersion = 1; + + // just use the pixfmt of the current desktop + + int MaxPixFmtNum = + DescribePixelFormat(_hdc, 1, sizeof(PIXELFORMATDESCRIPTOR), &pfd); + int cur_bpp = GetDeviceCaps(_hdc,BITSPIXEL); + int pfnum; + + for(pfnum = 1; pfnum <= MaxPixFmtNum; pfnum++) { + DescribePixelFormat(_hdc, pfnum, sizeof(PIXELFORMATDESCRIPTOR), &pfd); + + // official, nvidia sanctioned way. + if ((pfd.dwFlags & PFD_GENERIC_FORMAT) != 0) { + drvtype = Software; + } else if (pfd.dwFlags & PFD_GENERIC_ACCELERATED) { + drvtype = MCD; + } else { + drvtype = ICD; + } + + // skip driver types we are not looking for + if (bLookforHW) { + if (drvtype == Software) { + continue; } + } else { + if (drvtype != Software) { + continue; + } + } + + if ((pfd.iPixelType == PFD_TYPE_COLORINDEX) && + (framebuffer_mode & WindowProperties::FM_index) == 0) { + continue; + } + + DWORD dwReqFlags = (PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW); + + if (wgldisplay_cat.is_debug()) { + wgldisplay_cat->debug() + << "----------------" << endl; + + if ((framebuffer_mode & WindowProperties::FM_alpha) != 0) { + wgldisplay_cat->debug() + << "want alpha, pfd says '" + << (int)(pfd.cAlphaBits) << "'" << endl; + } + if ((framebuffer_mode & WindowProperties::FM_depth) != 0) { + wgldisplay_cat->debug() + << "want depth, pfd says '" + << (int)(pfd.cDepthBits) << "'" << endl; + } + if ((framebuffer_mode & WindowProperties::FM_stencil) != 0) { + wgldisplay_cat->debug() + << "want stencil, pfd says '" + << (int)(pfd.cStencilBits) << "'" << endl; + } + wgldisplay_cat->debug() + << "final flag check " << (int)(pfd.dwFlags & dwReqFlags) << " =? " + << (int)dwReqFlags << endl; + wgldisplay_cat->debug() + << "pfd bits = " << (int)(pfd.cColorBits) << endl; + wgldisplay_cat->debug() + << "cur_bpp = " << cur_bpp << endl; + } + + if ((framebuffer_mode & WindowProperties::FM_double_buffer) != 0) { + dwReqFlags|= PFD_DOUBLEBUFFER; + } + if ((framebuffer_mode & WindowProperties::FM_alpha) != 0 && + (pfd.cAlphaBits==0)) { + continue; + } + if ((framebuffer_mode & WindowProperties::FM_depth) != 0 && + (pfd.cDepthBits==0)) { + continue; + } + if ((framebuffer_mode & WindowProperties::FM_stencil) != 0 && + (pfd.cStencilBits==0)) { + continue; + } + + if ((pfd.dwFlags & dwReqFlags) != dwReqFlags) { + continue; + } + + // now we ignore the specified want_color_bits for windowed mode + // instead we use the current screen depth + + if ((pfd.cColorBits!=cur_bpp) && + (!((cur_bpp==16) && (pfd.cColorBits==15))) && + (!((cur_bpp==32) && (pfd.cColorBits==24)))) { + continue; + } + + // We've passed all the tests, go ahead and pick this fmt. + // Note: could go continue looping looking for more alpha bits or + // more depth bits so this would pick 16bpp depth buffer, probably + // not 24bpp + break; } - if(wgl_allow_sw_renderer && bUsingSoftware) { - wgldisplay_cat.info() << "Couldn't find compatible OGL HW pixelformat, using software rendering...\n"; + if (pfnum > MaxPixFmtNum) { + pfnum = 0; } - DescribePixelFormat(_hdc, pfnum, sizeof(PIXELFORMATDESCRIPTOR), &_pixelformat); - - #ifdef _DEBUG - char msg[200]; - sprintf(msg,"Selected GL PixelFormat is #%d",pfnum); - PrintPFD(&_pixelformat,msg); - #endif - return pfnum; } //////////////////////////////////////////////////////////////////// -// Function: setup_colormap -// Access: -// Description: +// Function: wglGraphicsWindow::setup_colormap +// Access: Private +// Description: Sets up a colormap for the window matching the +// selected pixel format. This is necessary before +// creating a GL context. //////////////////////////////////////////////////////////////////// -void wglGraphicsWindow::setup_colormap() { - +void wglGraphicsWindow:: +setup_colormap() { PIXELFORMATDESCRIPTOR pfd; LOGPALETTE *logical; int n; @@ -1051,2516 +435,57 @@ void wglGraphicsWindow::setup_colormap() { RealizePalette(_hdc); } +#ifdef _DEBUG //////////////////////////////////////////////////////////////////// -// Function: end_frame -// Access: -// Description: Swaps the front and back buffers. -//////////////////////////////////////////////////////////////////// -void wglGraphicsWindow::end_frame() { - if (gl_show_fps_meter) { - DO_PSTATS_STUFF(PStatTimer timer(_show_fps_pcollector);) - DWORD now = timeGetTime(); // this is win32 fn - - float time_delta = (now - _start_time) * 0.001f; - - if (time_delta > gl_fps_meter_update_interval) { - // didnt use global clock object, it wasnt working properly when - // I tried, its probably slower due to cache faults, and I can - // easily track all the info I need in dxgsg - DWORD num_frames = _cur_frame_count - _start_frame_count; - - _current_fps = num_frames / time_delta; - _start_time = now; - _start_frame_count = _cur_frame_count; - } - - char fps_msg[15]; - sprintf(fps_msg, "%.02f fps", _current_fps); - - // Note: we cant use simple GDI TextOut calls to draw FPS meter - // chars (like DX fps meter) because WGL doesnt support GDI in - // double-buffered mode. Instead we have to use glBitMap display - // lists created by wglUseFontBitmaps - - GLfloat saved_color[4]; - glGetFloatv(GL_CURRENT_COLOR,saved_color); - glColor3f(0.0f,1.0f,1.0f); - - GLboolean tex_was_on = glIsEnabled(GL_TEXTURE_2D); - - if (tex_was_on) - glDisable(GL_TEXTURE_2D); - - glMatrixMode(GL_MODELVIEW); - glPushMatrix(); - glLoadIdentity(); - glMatrixMode(GL_PROJECTION); - glPushMatrix(); - glLoadIdentity(); - - glOrtho(0.0f,_props._xsize, - 0.0f,_props._ysize, - -1.0f,1.0f); - - // problem to not restore the rasterPos state? - glRasterPos2f(_props._xsize-70,_props._ysize-20); // these seem to be good for default font - - // set up for a string-drawing display list call - glListBase(FONT_BITMAP_OGLDISPLAYLISTNUM); - - // draw a string using font display lists. chars index their - // corresponding displist name - glCallLists(strlen(fps_msg), GL_UNSIGNED_BYTE, fps_msg); - - // restore original gl state - glPopMatrix(); - glMatrixMode(GL_MODELVIEW); - glPopMatrix(); - glColor4fv(saved_color); - if (tex_was_on) - glEnable(GL_TEXTURE_2D); - - _cur_frame_count++; // only used by fps meter right now - } - - { - DO_PSTATS_STUFF(PStatTimer timer(_swap_pcollector);) - if (_is_synced) - glFinish(); - else SwapBuffers(_hdc); - } - GraphicsWindow::end_frame(); -} - -//////////////////////////////////////////////////////////////////// -// Function: swap -// Access: -// Description: Swaps the front and back buffers explicitly. -//////////////////////////////////////////////////////////////////// -void wglGraphicsWindow::swap() { - if (_is_synced) - SwapBuffers(_hdc); -} - -bool wglGraphicsWindow::resize(unsigned int xsize,unsigned int ysize) { - if (!_props._fullscreen) { - // resizing windowed mode is easy - SetWindowPos(_mwindow, NULL, 0,0, xsize,ysize, SWP_NOZORDER | SWP_NOMOVE | SWP_NOSENDCHANGING); - } else { - DWORD dwWidth = xsize; - DWORD dwHeight = ysize; - - HWND hDesktopWindow = GetDesktopWindow(); - HDC scrnDC=GetDC(hDesktopWindow); - DWORD dwFullScreenBitDepth=GetDeviceCaps(scrnDC,BITSPIXEL); - ReleaseDC(hDesktopWindow,scrnDC); - - // resize will always leave screen bitdepth unchanged - - // allowing resizing of lowvidmem cards to > 640x480. why? I'll assume - // check was already done by caller, so he knows what he wants - - DEVMODE dm; - if (!find_acceptable_display_mode(dwWidth,dwHeight,dwFullScreenBitDepth,dm)) { - wgldisplay_cat.fatal() << "window resize(" << xsize << "," << ysize << ") failed, no compatible fullscreen display mode found!\n"; - return false; - } - - // this causes WM_SIZE msg to be produced - SetWindowPos(_mwindow, NULL, 0,0, xsize, ysize, SWP_NOZORDER | SWP_NOMOVE | SWP_NOSENDCHANGING); - - int chg_result = ChangeDisplaySettings(&dm, CDS_FULLSCREEN); - - if (chg_result!=DISP_CHANGE_SUCCESSFUL) { - wgldisplay_cat.fatal() << "resize ChangeDisplaySettings failed (error code: " << chg_result <<") for specified res (" << dwWidth << " X " << dwHeight << " X " << dwFullScreenBitDepth <<"), " << dm.dmDisplayFrequency << "Hz\n"; - exit(1); - } - - // this assertion could be violated if we eventually allow dynamic fullscrn/windowed mode switching - assert(_pCurrent_display_settings!=NULL); - memcpy(_pCurrent_display_settings,&dm,sizeof(DEVMODE)); - } - return true; -} - -unsigned int wglGraphicsWindow:: -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. - - if (!_props._fullscreen || (numsizes==0)) { - return numsizes; - } - - assert(dimen!=NULL); - - HWND hDesktopWindow = GetDesktopWindow(); - HDC scrnDC=GetDC(hDesktopWindow); - DWORD dwFullScreenBitDepth=GetDeviceCaps(scrnDC,BITSPIXEL); - ReleaseDC(hDesktopWindow,scrnDC); - - // gonna do an n^2 loop alg for simplicity. if speed is necessary, - // could do linear time with some kind of STL hash container I guess - - DEVMODE dm; - uint modenum=0; - uint goodmodes=0; - unsigned int *cur_dim_pair=dimen; - for(;modenumdwFlags & PFD_GENERIC_ACCELERATED) && + (pfd->dwFlags & PFD_GENERIC_FORMAT)) { + drvtype=MCD; + } else if (!(pfd->dwFlags & PFD_GENERIC_ACCELERATED) && !(pfd->dwFlags & PFD_GENERIC_FORMAT)) { + drvtype=ICD; } else { - MSG msg; - - // handle all msgs on queue in a row - while(PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE)) { - process_1_event(); - } - } -} - -//////////////////////////////////////////////////////////////////// -// Function: make_current -// Access: Public -// Description: -//////////////////////////////////////////////////////////////////// -void wglGraphicsWindow::make_current() { - if ((_hdc==NULL)||(_context==NULL)||(!_window_active)) { - return; // we're only allow unmake_current() to set this to NULL + drvtype=Software; } - DO_PSTATS_STUFF(PStatTimer timer(_make_current_pcollector);) - HGLRC current_context = wglGetCurrentContext(); - HDC current_dc = wglGetCurrentDC(); +#define PRINT_FLAG(FLG) ((pfd->dwFlags & PFD_##FLG) ? (" PFD_" #FLG "|") : "") + wgldisplay_cat.spam() + << "================================\n"; - if ((current_context != _context) || (current_dc != _hdc)) { - if (!wglMakeCurrent(_hdc, _context)) { - PrintErrorMessage(LAST_ERROR); - } - } - - report_errors(); + wgldisplay_cat.spam() + << msg << ", " << OGLDrvStrings[drvtype] << " driver\n" + << "PFD flags: 0x" << (void*)pfd->dwFlags << " (" + << PRINT_FLAG(GENERIC_ACCELERATED) + << PRINT_FLAG(GENERIC_FORMAT) + << PRINT_FLAG(DOUBLEBUFFER) + << PRINT_FLAG(SUPPORT_OPENGL) + << PRINT_FLAG(SUPPORT_GDI) + << PRINT_FLAG(STEREO) + << PRINT_FLAG(DRAW_TO_WINDOW) + << PRINT_FLAG(DRAW_TO_BITMAP) + << PRINT_FLAG(SWAP_EXCHANGE) + << PRINT_FLAG(SWAP_COPY) + << PRINT_FLAG(SWAP_LAYER_BUFFERS) + << PRINT_FLAG(NEED_PALETTE) + << PRINT_FLAG(NEED_SYSTEM_PALETTE) + << PRINT_FLAG(SUPPORT_DIRECTDRAW) << ")\n" + << "PFD iPixelType: " + << ((pfd->iPixelType==PFD_TYPE_RGBA) ? "PFD_TYPE_RGBA":"PFD_TYPE_COLORINDEX") + << endl + << "PFD cColorBits: " << (DWORD)pfd->cColorBits + << " R: " << (DWORD)pfd->cRedBits + <<" G: " << (DWORD)pfd->cGreenBits + <<" B: " << (DWORD)pfd->cBlueBits << endl + << "PFD cAlphaBits: " << (DWORD)pfd->cAlphaBits + << " DepthBits: " << (DWORD)pfd->cDepthBits + <<" StencilBits: " << (DWORD)pfd->cStencilBits + <<" AccumBits: " << (DWORD)pfd->cAccumBits + << endl; } - -//////////////////////////////////////////////////////////////////// -// Function: unmake_current -// Access: Public -// Description: -//////////////////////////////////////////////////////////////////// -void wglGraphicsWindow::unmake_current() { - report_errors(); - - if (!wglMakeCurrent(NULL, NULL)) { - PrintErrorMessage(LAST_ERROR); - } -} - -int wglGraphicsWindow::get_depth_bitwidth() { - return _pixelformat.cDepthBits; -} - -//////////////////////////////////////////////////////////////////// -// Function: wglGraphicsWindow::get_gsg_type -// Access: Public, Virtual -// Description: Returns the TypeHandle of the kind of GSG preferred -// by this kind of window. -//////////////////////////////////////////////////////////////////// -TypeHandle wglGraphicsWindow:: -get_gsg_type() const { - return GLGraphicsStateGuardian::get_class_type(); -} - -GraphicsWindow *wglGraphicsWindow:: -make_wglGraphicsWindow(const FactoryParams ¶ms) { - GraphicsWindow::WindowPipe *pipe_param; - if (!get_param_into(pipe_param, params)) { - wgldisplay_cat.error() - << "No pipe specified for window creation!" << endl; - return NULL; - } - - GraphicsPipe *pipe = pipe_param->get_pipe(); - - GraphicsWindow::WindowProps *props_param; - if (!get_param_into(props_param, params)) { - return new wglGraphicsWindow(pipe); - } else { - return new wglGraphicsWindow(pipe, props_param->get_properties()); - } -} - -TypeHandle wglGraphicsWindow::get_class_type() { - return _type_handle; -} - -void wglGraphicsWindow::init_type() { - GraphicsWindow::init_type(); - register_type(_type_handle, "wglGraphicsWindow", - GraphicsWindow::get_class_type()); -} - -TypeHandle wglGraphicsWindow::get_type() const { - return get_class_type(); -} - -//////////////////////////////////////////////////////////////////// -// Function: static_window_proc -// Access: -// Description: -//////////////////////////////////////////////////////////////////// -LONG WINAPI static_window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) { - HWND_PANDAWIN_MAP::iterator pwin; - pwin=hwnd_pandawin_map.find(hwnd); - - if (pwin!=hwnd_pandawin_map.end()) { - wglGraphicsWindow *wglwinptr=(*pwin).second; - return wglwinptr->window_proc(hwnd, msg, wparam, lparam); - } else if (global_wglwinptr!=NULL){ - // this stuff should only be used during CreateWindow() - return global_wglwinptr->window_proc(hwnd, msg, wparam, lparam); - } else { - // should never need this?? (maybe at shutdwn?) - return DefWindowProc(hwnd, msg, wparam, lparam); - } -} - -void wglGraphicsWindow::deactivate_window() { - // current policy is to suspend minimized or deactivated fullscreen windows, but leave - // regular windows running normally - - if ((!_props._fullscreen) || _exiting_window || !_window_active || _active_minimized_fullscreen) { - #ifdef _DEBUG - if (wgldisplay_cat.is_spam()) - wgldisplay_cat.spam() << "deactivate_window called, but ignored in current mode" << endl; - #endif - return; - } - - throw_event("PandaPaused"); // right now this is used to signal python event handler to disable audio - - if (!bResponsive_minimized_fullscreen_window) { - if (wgldisplay_cat.is_spam()) - wgldisplay_cat.spam() << "WGL window deactivated, releasing gl context and waiting...\n"; - - _window_active = false; - unmake_current(); - } else { - _active_minimized_fullscreen = true; - assert(_props._fullscreen); - - if (wgldisplay_cat.is_spam()) - wgldisplay_cat.spam() << "WGL window minimized from fullscreen mode, remaining active...\n"; - } - - // make sure window is minimized - - WINDOWPLACEMENT wndpl; - wndpl.length=sizeof(WINDOWPLACEMENT); - - if (!GetWindowPlacement(_mwindow,&wndpl)) { - wgldisplay_cat.error() << "GetWindowPlacement failed!\n"; - return; - } - - if ((wndpl.showCmd!=SW_MINIMIZE)&&(wndpl.showCmd!=SW_SHOWMINIMIZED)) { - ShowWindow(_mwindow, SW_MINIMIZE); - } - - // revert to default display mode - ChangeDisplaySettings(NULL,0x0); - - if (!bResponsive_minimized_fullscreen_window) { - _PandaPausedTimer = SetTimer(_mwindow,PAUSED_TIMER_ID,1500,NULL); - if (_PandaPausedTimer!=PAUSED_TIMER_ID) { - wgldisplay_cat.error() << "Error in SetTimer!\n"; - } - } - - if (_props._fullscreen) { - throw_event("PandaRestarted"); // right now this is used to signal python event handler to re-enable audio - } -} - -void wglGraphicsWindow::reactivate_window() { - if (!_window_active) { - if (wgldisplay_cat.is_spam()) - wgldisplay_cat.spam() << "WGL window re-activated...\n"; - - _window_active = true; - - if (_PandaPausedTimer!=NULL) { - KillTimer(_mwindow,_PandaPausedTimer); - _PandaPausedTimer = NULL; - } - - // move window to top of zorder, - SetWindowPos(_mwindow, HWND_TOP, 0,0,0,0, SWP_NOMOVE | SWP_NOSENDCHANGING | SWP_NOSIZE | SWP_NOOWNERZORDER); - - ChangeDisplaySettings(_pCurrent_display_settings,CDS_FULLSCREEN); - - GdiFlush(); - make_current(); - } else if (_active_minimized_fullscreen) { - if (wgldisplay_cat.is_spam()) - wgldisplay_cat.spam() << "redisplaying minimized fullscrn active WGL window...\n"; - - // move window to top of zorder, - SetWindowPos(_mwindow, HWND_TOP, 0,0,0,0, SWP_NOMOVE | SWP_NOSENDCHANGING | SWP_NOSIZE | SWP_NOOWNERZORDER); - - ChangeDisplaySettings(_pCurrent_display_settings,CDS_FULLSCREEN); - - GdiFlush(); - make_current(); - _active_minimized_fullscreen = false; - } -} - -// Note: could use _TrackMouseEvent in comctrl32.dll (part of IE 3.0+) which emulates -// TrackMouseEvent on w95, but that requires another 500K of memory to hold that DLL, -// which is lame just to support w95, which probably has other issues anyway -INLINE void wglGraphicsWindow:: -track_mouse_leaving(HWND hwnd) { - if(_pfnTrackMouseEvent==NULL) - return; - - TRACKMOUSEEVENT tme = {sizeof(TRACKMOUSEEVENT),TME_LEAVE,hwnd,0}; - BOOL bSucceeded = _pfnTrackMouseEvent(&tme); // tell win32 to post WM_MOUSELEAVE msgs - - if((!bSucceeded) && wgldisplay_cat.is_debug()) - wgldisplay_cat.debug() << "TrackMouseEvent failed!, LastError=" << GetLastError() << endl; - - _tracking_mouse_leaving=true; -} - -//////////////////////////////////////////////////////////////////// -// Function: window_proc -// Access: -// Description: -//////////////////////////////////////////////////////////////////// -LONG WINAPI wglGraphicsWindow:: -window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) { - int button = -1; - int x, y; - - switch (msg) { - - case WM_MOUSEMOVE: { - // Win32 doesn't return the same numbers as X does when the mouse - // goes beyond the upper or left side of the window - #define SET_MOUSE_COORD(iVal,VAL) { \ - iVal = VAL; \ - if(iVal & 0x8000) \ - iVal -= 0x10000; \ - } - - if(!_tracking_mouse_leaving) { - // need to re-call TrackMouseEvent every time mouse re-enters window - track_mouse_leaving(hwnd); - } - - SET_MOUSE_COORD(x,LOWORD(lparam)); - SET_MOUSE_COORD(y,HIWORD(lparam)); - - handle_mouse_motion(x, y); - - break; - } - - // if cursor is invisible, make it visible when moving in the window bars,etc - case WM_NCMOUSEMOVE: { - if(!_props._bCursorIsVisible) { - if(!_cursor_in_windowclientarea) { - // wgldisplay_cat.error() << "NCMOUSEMOVE show=true\n"; - ShowCursor(true); - _cursor_in_windowclientarea=true; - } - } - break; - } - - case WM_NCMOUSELEAVE: { - if(!_props._bCursorIsVisible) { - // wgldisplay_cat.error() << "NCMOUSELEAVE show=false\n"; - ShowCursor(false); - _cursor_in_windowclientarea=false; - } - break; - } - - case WM_MOUSELEAVE: { - _tracking_mouse_leaving=false; - handle_mouse_exit(); - break; - } - - case WM_CREATE: { - track_mouse_leaving(hwnd); - - _cursor_in_windowclientarea=false; - if(!_props._bCursorIsVisible) - ShowCursor(false); - break; - } - - case WM_CLOSE: - close_window(); - - // BUGBUG: right now there is no way to tell the panda app the graphics window is invalid or - // has been closed by the user, to prevent further methods from being called on the window. - // this needs to be added to panda for multiple windows to work. in the meantime, just - // trigger an exit here if numwindows==0, since that is the expected behavior when all - // windows are closed (should be done by the app though, and it assumes you only make this - // type of panda gfx window) - - if (hwnd_pandawin_map.size()==0) { - exit(0); - } - break; - - case WM_MOVE: - // handle all this stuff in EXITSIZEMOVE. will rendering work during moving? do we care? - //_props._xorg = LOWORD(lparam); - //_props._yorg = HIWORD(lparam); - break; - - - case WM_ACTIVATEAPP: { - #ifdef _DEBUG - wgldisplay_cat.spam() << "WM_ACTIVATEAPP(" << (bool)(wparam!=0) <<") received\n"; - #endif - - if (!wparam) { - deactivate_window(); - return 0; - } // dont want to reactivate until window is actually un-minimized (see WM_SIZE) - break; - } - - case WM_EXITSIZEMOVE: - #ifdef _DEBUG - wgldisplay_cat.spam() << "WM_EXITSIZEMOVE received" << endl; - #endif - - reactivate_window(); - handle_reshape(); - break; - - case WM_ENTERSIZEMOVE: - break; - - case WM_SIZE: { - DWORD width,height; - - width = LOWORD(lparam); height = HIWORD(lparam); - #ifdef _DEBUG - { - wgldisplay_cat.spam() << "WM_SIZE received with width:" << width << " height: " << height << " flags: " << - ((wparam == SIZE_MAXHIDE)? "SIZE_MAXHIDE " : "") << ((wparam == SIZE_MAXSHOW)? "SIZE_MAXSHOW " : "") << - ((wparam == SIZE_MINIMIZED)? "SIZE_MINIMIZED " : "") << ((wparam == SIZE_RESTORED)? "SIZE_RESTORED " : "") << - ((wparam == SIZE_MAXIMIZED)? "SIZE_MAXIMIZED " : "") << endl; - } - #endif - if (_mwindow==NULL) - break; - - if ((wparam==SIZE_MAXIMIZED) || (wparam==SIZE_RESTORED)) { // old comment -- added SIZE_RESTORED to handle 3dfx case (what does this mean?) - reactivate_window(); - -// if ((_props._xsize != width) || (_props._ysize != height)) - handle_reshape(); - } - break; - } - - case WM_PAINT: { - PAINTSTRUCT ps; - BeginPaint(hwnd, &ps); - // glReadBuffer(GL_BACK); need to copy current rendering to front buffer, a la wdxdisplay? - EndPaint(hwnd, &ps); - return 0; - } - - case WM_IME_NOTIFY: - if (wparam == IMN_SETOPENSTATUS) { - HIMC hIMC = ImmGetContext(hwnd); - nassertr(hIMC != 0, 0); - _ime_open = (ImmGetOpenStatus(hIMC) != 0); - if (!_ime_open) { - _ime_active = false; // Sanity enforcement. - } - ImmReleaseContext(hwnd, hIMC); - } - break; - - case WM_IME_STARTCOMPOSITION: - _ime_active = true; - break; - - case WM_IME_ENDCOMPOSITION: - _ime_active = false; - break; - - case WM_IME_COMPOSITION: - if (lparam & GCS_RESULTSTR) { - if (!_input_devices.empty()) { - HIMC hIMC = ImmGetContext(hwnd); - nassertr(hIMC != 0, 0); - - static const int max_ime_result = 128; - static char ime_result[max_ime_result]; - - if (_ime_composition_w) { - // Since ImmGetCompositionStringA() doesn't seem to work - // for Win2000 (it always returns question mark - // characters), we have to use ImmGetCompositionStringW() - // on this OS. This is actually the easier of the two - // functions to use. - - DWORD result_size = - ImmGetCompositionStringW(hIMC, GCS_RESULTSTR, - ime_result, max_ime_result); - - // Add this string into the text buffer of the application. - - // ImmGetCompositionStringW() returns a string, but it's - // filled in with wstring data: every two characters defines a - // 16-bit unicode char. The docs aren't clear on the - // endianness of this. I guess it's safe to assume all Win32 - // machines are little-endian. - for (DWORD i = 0; i < result_size; i += 2) { - int result = - ((int)(unsigned char)ime_result[i + 1] << 8) | - (unsigned char)ime_result[i]; - _input_devices[0].keystroke(result); - } - } else { - // On the other hand, ImmGetCompositionStringW() doesn't - // work on Win95 or Win98; for these OS's we must use - // ImmGetCompositionStringA(). - DWORD result_size = - ImmGetCompositionStringA(hIMC, GCS_RESULTSTR, - ime_result, max_ime_result); - - // ImmGetCompositionStringA() returns an encoded ANSI - // string, which we now have to map to wide-character - // Unicode. - static const int max_wide_result = 128; - static wchar_t wide_result[max_wide_result]; - - int wide_size = - MultiByteToWideChar(CP_ACP, 0, - ime_result, result_size, - wide_result, max_wide_result); - if (wide_size == 0) { - PrintErrorMessage(LAST_ERROR); - } - for (int i = 0; i < wide_size; i++) { - _input_devices[0].keystroke(wide_result[i]); - } - } - - ImmReleaseContext(hwnd, hIMC); - } - return 0; - } - break; - - case WM_CHAR: - // Ignore WM_CHAR messages if we have the IME open, since - // everything will come in through WM_IME_COMPOSITION. (It's - // supposed to come in through WM_CHAR, too, but there seems to - // be a bug in Win2000 in that it only sends question mark - // characters through here.) - if (!_ime_open && !_input_devices.empty()) { - _input_devices[0].keystroke(wparam); - } - break; - - case WM_SYSKEYDOWN: { - // Alt and F10 are sent as WM_SYSKEYDOWN instead of WM_KEYDOWN - // want to use defwindproc on Alt syskey so std windows cmd Alt-F4 works, etc - POINT point; - GetCursorPos(&point); - ScreenToClient(hwnd, &point); - handle_keypress(lookup_key(wparam), point.x, point.y); - if (wparam == VK_F10) { - //bypass default windproc F10 behavior (it activates the main menu, but we have none) - return 0; - } - } - break; - - case WM_SYSCOMMAND: - if(wparam==SC_KEYMENU) { - // if Alt is released (alone w/o other keys), defwindproc will send - // this command, which will 'activate' the title bar menu (we have none) - // and give focus to it. we dont want this to happen, so kill this msg - return 0; - } - break; - - case WM_KEYDOWN: { - POINT point; - - GetCursorPos(&point); - ScreenToClient(hwnd, &point); - handle_keypress(lookup_key(wparam), point.x, point.y); - - // Handle Cntrl-V paste from clipboard. Is there a better way - // to detect this hotkey? - if ((wparam=='V') && (GetKeyState(VK_CONTROL) < 0) && - !_input_devices.empty()) { - HGLOBAL hglb; - char *lptstr; - - if (!IsClipboardFormatAvailable(CF_TEXT)) - return 0; - - if (!OpenClipboard(NULL)) - return 0; - - // Maybe we should support CF_UNICODETEXT if it is available - // too? - hglb = GetClipboardData(CF_TEXT); - if (hglb!=NULL) { - lptstr = (char *) GlobalLock(hglb); - if (lptstr != NULL) { - char *pChar; - for(pChar=lptstr;*pChar!=NULL;pChar++) { - _input_devices[0].keystroke((uchar)*pChar); - } - GlobalUnlock(hglb); - } - } - CloseClipboard(); - } - break; - } - - case WM_SYSKEYUP: - case WM_KEYUP: - handle_keyrelease(lookup_key(wparam)); - break; - - case WM_LBUTTONDOWN: - button = 0; - case WM_MBUTTONDOWN: - if (button < 0) - button = 1; - - case WM_RBUTTONDOWN: - if (button < 0) - button = 2; - SetCapture(hwnd); - SET_MOUSE_COORD(x,LOWORD(lparam)); - SET_MOUSE_COORD(y,HIWORD(lparam)); - handle_keypress(MouseButton::button(button), x, y); - break; - case WM_LBUTTONUP: - button = 0; - case WM_MBUTTONUP: - if (button < 0) - button = 1; - case WM_RBUTTONUP: - if (button < 0) - button = 2; - ReleaseCapture(); - #if 0 - SET_MOUSE_COORD(x,LOWORD(lparam)); - SET_MOUSE_COORD(y,HIWORD(lparam)); - #endif - handle_keyrelease(MouseButton::button(button)); - break; - - case WM_SETFOCUS: { - // wgldisplay_cat.info() << "got WM_SETFOCUS\n"; - - // make_current(); causes errors when Alt-tabbing? - - POINT point; - GetCursorPos(&point); - ScreenToClient(hwnd, &point); - - // this is a hack to make sure common modifier keys have proper state - // since at focus loss, app may never receive key-up event corresponding to - // a key-down. it would be better to know the exact set of ModifierButtons the - // user is using, since we may miss some here - - for(int i=0;idwFlags & (PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW)) { - if (visual->iPixelType == PFD_TYPE_COLORINDEX && - visual->cColorBits >= 24) { - *value = 0; - } else { - *value = 1; - } - } else { - *value = 0; - } - break; - case GLX_BUFFER_SIZE: - if (visual->iPixelType == PFD_TYPE_RGBA) - *value = visual->cColorBits; - else - *value = 8; - break; - case GLX_LEVEL: - *value = visual->bReserved; - break; - case GLX_RGBA: - *value = visual->iPixelType == PFD_TYPE_RGBA; - break; - case GLX_DOUBLEBUFFER: - *value = visual->dwFlags & PFD_DOUBLEBUFFER; - break; - case GLX_STEREO: - *value = visual->dwFlags & PFD_STEREO; - break; - case GLX_AUX_BUFFERS: - *value = visual->cAuxBuffers; - break; - case GLX_RED_SIZE: - *value = visual->cRedBits; - break; - case GLX_GREEN_SIZE: - *value = visual->cGreenBits; - break; - case GLX_BLUE_SIZE: - *value = visual->cBlueBits; - break; - case GLX_ALPHA_SIZE: - *value = visual->cAlphaBits; - break; - case GLX_DEPTH_SIZE: - *value = visual->cDepthBits; - break; - case GLX_STENCIL_SIZE: - *value = visual->cStencilBits; - break; - case GLX_ACCUM_RED_SIZE: - *value = visual->cAccumRedBits; - break; - case GLX_ACCUM_GREEN_SIZE: - *value = visual->cAccumGreenBits; - break; - case GLX_ACCUM_BLUE_SIZE: - *value = visual->cAccumBlueBits; - break; - case GLX_ACCUM_ALPHA_SIZE: - *value = visual->cAccumAlphaBits; - break; - } -} - -//////////////////////////////////////////////////////////////////// -// Function: try_for_visual -// Description: This is a static function that attempts to get the -// requested visual, if it is available. It's just a -// wrapper around glXChooseVisual(). It returns the -// visual information if possible, or NULL if it is not. -//////////////////////////////////////////////////////////////////// -PIXELFORMATDESCRIPTOR* wglGraphicsWindow:: -try_for_visual(wglGraphicsPipe *pipe, int mask, - int want_depth_bits, int want_color_bits) { - static const int max_attrib_list = 32; - int attrib_list[max_attrib_list]; - int n=0; - - wgldisplay_cat.debug() - << "Trying for visual with: RGB(" << want_color_bits << ")"; - - int want_color_component_bits; - if (mask & W_ALPHA) { - want_color_component_bits = max(want_color_bits / 4, 1); - } else { - want_color_component_bits = max(want_color_bits / 3, 1); - } - - attrib_list[n++] = GLX_RGBA; - attrib_list[n++] = GLX_RED_SIZE; - attrib_list[n++] = want_color_component_bits; - attrib_list[n++] = GLX_GREEN_SIZE; - attrib_list[n++] = want_color_component_bits; - attrib_list[n++] = GLX_BLUE_SIZE; - attrib_list[n++] = want_color_component_bits; - - if (mask & W_ALPHA) { - wgldisplay_cat.debug(false) << " ALPHA"; - attrib_list[n++] = GLX_ALPHA_SIZE; - attrib_list[n++] = want_color_component_bits; - } - if (mask & W_DOUBLE) { - wgldisplay_cat.debug(false) << " DOUBLEBUFFER"; - attrib_list[n++] = GLX_DOUBLEBUFFER; - } - if (mask & W_STEREO) { - wgldisplay_cat.debug(false) << " STEREO"; - attrib_list[n++] = GLX_STEREO; - } - if (mask & W_DEPTH) { - wgldisplay_cat.debug(false) << " DEPTH(" << want_depth_bits << ")"; - attrib_list[n++] = GLX_DEPTH_SIZE; - attrib_list[n++] = want_depth_bits; - } - if (mask & W_STENCIL) { - wgldisplay_cat.debug(false) << " STENCIL"; - attrib_list[n++] = GLX_STENCIL_SIZE; - attrib_list[n++] = 1; - } - if (mask & W_ACCUM) { - wgldisplay_cat.debug(false) << " ACCUM"; - attrib_list[n++] = GLX_ACCUM_RED_SIZE; - attrib_list[n++] = want_color_component_bits; - attrib_list[n++] = GLX_ACCUM_GREEN_SIZE; - attrib_list[n++] = want_color_component_bits; - attrib_list[n++] = GLX_ACCUM_BLUE_SIZE; - attrib_list[n++] = want_color_component_bits; - if (mask & W_ALPHA) { - attrib_list[n++] = GLX_ACCUM_ALPHA_SIZE; - attrib_list[n++] = want_color_component_bits; - } - } - - // Terminate the list - nassertr(n < max_attrib_list, NULL); - attrib_list[n] = 0L; - - PIXELFORMATDESCRIPTOR pfd; - PIXELFORMATDESCRIPTOR *match = NULL; - bool stereo = false; - - memset(&pfd, 0, sizeof(PIXELFORMATDESCRIPTOR)); - pfd.nSize = (sizeof(PIXELFORMATDESCRIPTOR)); - pfd.nVersion = 1; - - // Defaults - pfd.dwFlags = PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW; - pfd.iPixelType = PFD_TYPE_COLORINDEX; - pfd.cColorBits = 32; - pfd.cDepthBits = 0; - - int *p = attrib_list; - while (*p) { - switch (*p) { - case GLX_USE_GL: - pfd.dwFlags |= PFD_SUPPORT_OPENGL; - break; - case GLX_LEVEL: - pfd.bReserved = *(++p); - break; - case GLX_RGBA: - pfd.iPixelType = PFD_TYPE_RGBA; - break; - case GLX_DOUBLEBUFFER: - pfd.dwFlags |= PFD_DOUBLEBUFFER; - break; - case GLX_STEREO: - stereo = true; - pfd.dwFlags |= PFD_STEREO; - break; - case GLX_AUX_BUFFERS: - pfd.cAuxBuffers = *(++p); - break; - case GLX_RED_SIZE: - pfd.cRedBits = 8; // Try to get the maximum - ++p; - break; - case GLX_GREEN_SIZE: - pfd.cGreenBits = 8; // Try to get the maximum - ++p; - break; - case GLX_BLUE_SIZE: - pfd.cBlueBits = 8; // Try to get the maximum - ++p; - break; - case GLX_ALPHA_SIZE: - pfd.cAlphaBits = 8; // Try to get the maximum - ++p; - break; - case GLX_DEPTH_SIZE: - pfd.cDepthBits = 32; // Try to get the maximum - ++p; - break; - case GLX_STENCIL_SIZE: - pfd.cStencilBits = *(++p); - break; - case GLX_ACCUM_RED_SIZE: - case GLX_ACCUM_GREEN_SIZE: - case GLX_ACCUM_BLUE_SIZE: - case GLX_ACCUM_ALPHA_SIZE: - // Only cAccumBits is used for requesting accum buffer - pfd.cAccumBits = 1; - ++p; - break; - } - ++p; - } - - int pf = ChoosePixelFormat(_hdc, &pfd); - if (pf > 0) { - DescribePixelFormat(_hdc, pf, sizeof(PIXELFORMATDESCRIPTOR), &_pixelformat); - - // ChoosePixelFormat is dumb about stereo - if (stereo) { - if (!(_pixelformat->dwFlags & PFD_STEREO)) { - wgldisplay_cat.info() << "try_for_visual() - request for stereo failed" << endl; - } - } - } - - return match; -} - #endif - -extern char *ConvDDErrorToString(const HRESULT &error) { - switch(error) { - case E_FAIL: - return "Unspecified error E_FAIL"; - - case DD_OK: - return "No error.\0"; - - case DDERR_ALREADYINITIALIZED : // (5) - return "DDERR_ALREADYINITIALIZED ";//: // (5) - case DDERR_CANNOTATTACHSURFACE : // (10) - return "DDERR_CANNOTATTACHSURFACE ";//: // (10) - case DDERR_CANNOTDETACHSURFACE : // (20) - return "DDERR_CANNOTDETACHSURFACE ";//: // (20) - case DDERR_CURRENTLYNOTAVAIL : // (40) - return "DDERR_CURRENTLYNOTAVAIL ";//: // (40) - case DDERR_EXCEPTION : // (55) - return "DDERR_EXCEPTION ";//: // (55) - case DDERR_HEIGHTALIGN : // (90) - return "DDERR_HEIGHTALIGN ";//: // (90) - case DDERR_INCOMPATIBLEPRIMARY : // (95) - return "DDERR_INCOMPATIBLEPRIMARY ";//: // (95) - case DDERR_INVALIDCAPS : // (100) - return "DDERR_INVALIDCAPS ";//: // (100) - case DDERR_INVALIDCLIPLIST : // (110) - return "DDERR_INVALIDCLIPLIST ";//: // (110) - case DDERR_INVALIDMODE : // (120) - return "DDERR_INVALIDMODE ";//: // (120) - case DDERR_INVALIDOBJECT : // (130) - return "DDERR_INVALIDOBJECT ";//: // (130) - case DDERR_INVALIDPIXELFORMAT : // (145) - return "DDERR_INVALIDPIXELFORMAT ";//: // (145) - case DDERR_INVALIDRECT : // (150) - return "DDERR_INVALIDRECT ";//: // (150) - case DDERR_LOCKEDSURFACES : // (160) - return "DDERR_LOCKEDSURFACES ";//: // (160) - case DDERR_NO3D : // (170) - return "DDERR_NO3D ";//: // (170) - case DDERR_NOALPHAHW : // (180) - return "DDERR_NOALPHAHW ";//: // (180) - case DDERR_NOCLIPLIST : // (205) - return "DDERR_NOCLIPLIST ";//: // (205) - case DDERR_NOCOLORCONVHW : // (210) - return "DDERR_NOCOLORCONVHW ";//: // (210) - case DDERR_NOCOOPERATIVELEVELSET : // (212) - return "DDERR_NOCOOPERATIVELEVELSET ";//: // (212) - case DDERR_NOCOLORKEY : // (215) - return "DDERR_NOCOLORKEY ";//: // (215) - case DDERR_NOCOLORKEYHW : // (220) - return "DDERR_NOCOLORKEYHW ";//: // (220) - case DDERR_NODIRECTDRAWSUPPORT : // (222) - return "DDERR_NODIRECTDRAWSUPPORT ";//: // (222) - case DDERR_NOEXCLUSIVEMODE : // (225) - return "DDERR_NOEXCLUSIVEMODE ";//: // (225) - case DDERR_NOFLIPHW : // (230) - return "DDERR_NOFLIPHW ";//: // (230) - case DDERR_NOGDI : // (240) - return "DDERR_NOGDI ";//: // (240) - case DDERR_NOMIRRORHW : // (250) - return "DDERR_NOMIRRORHW ";//: // (250) - case DDERR_NOTFOUND : // (255) - return "DDERR_NOTFOUND ";//: // (255) - case DDERR_NOOVERLAYHW : // (260) - return "DDERR_NOOVERLAYHW ";//: // (260) - case DDERR_NORASTEROPHW : // (280) - return "DDERR_NORASTEROPHW ";//: // (280) - case DDERR_NOROTATIONHW : // (290) - return "DDERR_NOROTATIONHW ";//: // (290) - case DDERR_NOSTRETCHHW : // (310) - return "DDERR_NOSTRETCHHW ";//: // (310) - case DDERR_NOT4BITCOLOR : // (316) - return "DDERR_NOT4BITCOLOR ";//: // (316) - case DDERR_NOT4BITCOLORINDEX : // (317) - return "DDERR_NOT4BITCOLORINDEX ";//: // (317) - case DDERR_NOT8BITCOLOR : // (320) - return "DDERR_NOT8BITCOLOR ";//: // (320) - case DDERR_NOTEXTUREHW : // (330) - return "DDERR_NOTEXTUREHW ";//: // (330) - case DDERR_NOVSYNCHW : // (335) - return "DDERR_NOVSYNCHW ";//: // (335) - case DDERR_NOZBUFFERHW : // (340) - return "DDERR_NOZBUFFERHW ";//: // (340) - case DDERR_NOZOVERLAYHW : // (350) - return "DDERR_NOZOVERLAYHW ";//: // (350) - case DDERR_OUTOFCAPS : // (360) - return "DDERR_OUTOFCAPS ";//: // (360) - case DDERR_OUTOFVIDEOMEMORY : // (380) - return "DDERR_OUTOFVIDEOMEMORY ";//: // (380) - case DDERR_OVERLAYCANTCLIP : // (382) - return "DDERR_OVERLAYCANTCLIP ";//: // (382) - case DDERR_OVERLAYCOLORKEYONLYONEACTIVE : // (384) - return "DDERR_OVERLAYCOLORKEYONLYONEACTIVE ";//: // (384) - case DDERR_PALETTEBUSY : // (387) - return "DDERR_PALETTEBUSY ";//: // (387) - case DDERR_COLORKEYNOTSET : // (400) - return "DDERR_COLORKEYNOTSET ";//: // (400) - case DDERR_SURFACEALREADYATTACHED : // (410) - return "DDERR_SURFACEALREADYATTACHED ";//: // (410) - case DDERR_SURFACEALREADYDEPENDENT : // (420) - return "DDERR_SURFACEALREADYDEPENDENT ";//: // (420) - case DDERR_SURFACEBUSY : // (430) - return "DDERR_SURFACEBUSY ";//: // (430) - case DDERR_CANTLOCKSURFACE : // (435) - return "DDERR_CANTLOCKSURFACE";//: // (435) - case DDERR_SURFACEISOBSCURED : // (440) - return "DDERR_SURFACEISOBSCURED ";//: // (440) - case DDERR_SURFACELOST : // (450) - return "DDERR_SURFACELOST ";//: // (450) - case DDERR_SURFACENOTATTACHED : // (460) - return "DDERR_SURFACENOTATTACHED ";//: // (460) - case DDERR_TOOBIGHEIGHT : // (470) - return "DDERR_TOOBIGHEIGHT ";//: // (470) - case DDERR_TOOBIGSIZE : // (480) - return "DDERR_TOOBIGSIZE ";//: // (480) - case DDERR_TOOBIGWIDTH : // (490) - return "DDERR_TOOBIGWIDTH ";//: // (490) - case DDERR_UNSUPPORTEDFORMAT : // (510) - return "DDERR_UNSUPPORTEDFORMAT ";//: // (510) - case DDERR_UNSUPPORTEDMASK : // (520) - return "DDERR_UNSUPPORTEDMASK ";//: // (520) - case DDERR_VERTICALBLANKINPROGRESS : // (537) - return "DDERR_VERTICALBLANKINPROGRESS ";//: // (537) - case DDERR_WASSTILLDRAWING : // (540) - return "DDERR_WASSTILLDRAWING ";//: // (540) - case DDERR_XALIGN : // (560) - return "DDERR_XALIGN ";//: // (560) - case DDERR_INVALIDDIRECTDRAWGUID : // (561) - return "DDERR_INVALIDDIRECTDRAWGUID ";//: // (561) - case DDERR_DIRECTDRAWALREADYCREATED : // (562) - return "DDERR_DIRECTDRAWALREADYCREATED ";//: // (562) - case DDERR_NODIRECTDRAWHW : // (563) - return "DDERR_NODIRECTDRAWHW ";//: // (563) - case DDERR_PRIMARYSURFACEALREADYEXISTS : // (564) - return "DDERR_PRIMARYSURFACEALREADYEXISTS ";//: // (564) - case DDERR_NOEMULATION : // (565) - return "DDERR_NOEMULATION ";//: // (565) - case DDERR_REGIONTOOSMALL : // (566) - return "DDERR_REGIONTOOSMALL ";//: // (566) - case DDERR_CLIPPERISUSINGHWND : // (567) - return "DDERR_CLIPPERISUSINGHWND ";//: // (567) - case DDERR_NOCLIPPERATTACHED : // (568) - return "DDERR_NOCLIPPERATTACHED ";//: // (568) - case DDERR_NOHWND : // (569) - return "DDERR_NOHWND ";//: // (569) - case DDERR_HWNDSUBCLASSED : // (570) - return "DDERR_HWNDSUBCLASSED ";//: // (570) - case DDERR_HWNDALREADYSET : // (571) - return "DDERR_HWNDALREADYSET ";//: // (571) - case DDERR_NOPALETTEATTACHED : // (572) - return "DDERR_NOPALETTEATTACHED ";//: // (572) - case DDERR_NOPALETTEHW : // (573) - return "DDERR_NOPALETTEHW ";//: // (573) - case DDERR_BLTFASTCANTCLIP : // (574) - return "DDERR_BLTFASTCANTCLIP ";//: // (574) - case DDERR_NOBLTHW : // (575) - return "DDERR_NOBLTHW ";//: // (575) - case DDERR_NODDROPSHW : // (576) - return "DDERR_NODDROPSHW ";//: // (576) - case DDERR_OVERLAYNOTVISIBLE : // (577) - return "DDERR_OVERLAYNOTVISIBLE ";//: // (577) - case DDERR_NOOVERLAYDEST : // (578) - return "DDERR_NOOVERLAYDEST ";//: // (578) - case DDERR_INVALIDPOSITION : // (579) - return "DDERR_INVALIDPOSITION ";//: // (579) - case DDERR_NOTAOVERLAYSURFACE : // (580) - return "DDERR_NOTAOVERLAYSURFACE ";//: // (580) - case DDERR_EXCLUSIVEMODEALREADYSET : // (581) - return "DDERR_EXCLUSIVEMODEALREADYSET ";//: // (581) - case DDERR_NOTFLIPPABLE : // (582) - return "DDERR_NOTFLIPPABLE ";//: // (582) - case DDERR_CANTDUPLICATE : // (583) - return "DDERR_CANTDUPLICATE ";//: // (583) - case DDERR_NOTLOCKED : // (584) - return "DDERR_NOTLOCKED ";//: // (584) - case DDERR_CANTCREATEDC : // (585) - return "DDERR_CANTCREATEDC ";//: // (585) - case DDERR_NODC : // (586) - return "DDERR_NODC ";//: // (586) - case DDERR_WRONGMODE : // (587) - return "DDERR_WRONGMODE ";//: // (587) - case DDERR_IMPLICITLYCREATED : // (588) - return "DDERR_IMPLICITLYCREATED ";//: // (588) - case DDERR_NOTPALETTIZED : // (589) - return "DDERR_NOTPALETTIZED ";//: // (589) - case DDERR_UNSUPPORTEDMODE : // (590) - return "DDERR_UNSUPPORTEDMODE ";//: // (590) - case DDERR_NOMIPMAPHW : // (591) - return "DDERR_NOMIPMAPHW ";//: // (591) - case DDERR_INVALIDSURFACETYPE : // (592) - return "DDERR_INVALIDSURFACETYPE";//: // (592) - case DDERR_NOOPTIMIZEHW : // (600) - return "DDERR_NOOPTIMIZEHW";//: // (600) - case DDERR_NOTLOADED : // (601) - return "DDERR_NOTLOADED";//: // (601) - case DDERR_NOFOCUSWINDOW : // (602) - return "DDERR_NOFOCUSWINDOW";//: // (602) - case DDERR_DCALREADYCREATED : // (620) - return "DDERR_DCALREADYCREATED ";//: // (620) - case DDERR_NONONLOCALVIDMEM : // (630) - return "DDERR_NONONLOCALVIDMEM";//: // (630) - case DDERR_CANTPAGELOCK : // (640) - return "DDERR_CANTPAGELOCK ";//: // (640) - case DDERR_CANTPAGEUNLOCK : // (660) - return "DDERR_CANTPAGEUNLOCK ";//: // (660) - case DDERR_NOTPAGELOCKED : // (680) - return "DDERR_NOTPAGELOCKED ";//: // (680) - case DDERR_MOREDATA : // (690) - return "DDERR_MOREDATA ";//: // (690) - case DDERR_VIDEONOTACTIVE : // (695) - return "DDERR_VIDEONOTACTIVE ";//: // (695) - case DDERR_DEVICEDOESNTOWNSURFACE : // (699) - return "DDERR_DEVICEDOESNTOWNSURFACE ";//: // (699) - - case E_UNEXPECTED : - return "E_UNEXPECTED "; - case E_NOTIMPL : - return "E_NOTIMPL "; - case E_OUTOFMEMORY : - return "E_OUTOFMEMORY "; - case E_INVALIDARG : - return "E_INVALIDARG or DDERR_INVALIDPARAMS"; - case E_NOINTERFACE : - return "E_NOINTERFACE "; - case E_POINTER : - return "E_POINTER "; - case E_HANDLE : - return "E_HANDLE "; - case E_ABORT : - return "E_ABORT "; -// case E_FAIL : -// return "E_FAIL "; - case E_ACCESSDENIED : - return "E_ACCESSDENIED "; - case E_PENDING : - return "E_PENDING "; - case CO_E_INIT_TLS : - return "CO_E_INIT_TLS "; - case CO_E_INIT_SHARED_ALLOCATOR : - return "CO_E_INIT_SHARED_ALLOCATOR "; - case CO_E_INIT_MEMORY_ALLOCATOR : - return "CO_E_INIT_MEMORY_ALLOCATOR "; - case CO_E_INIT_CLASS_CACHE : - return "CO_E_INIT_CLASS_CACHE "; - case CO_E_INIT_RPC_CHANNEL : - return "CO_E_INIT_RPC_CHANNEL "; - case CO_E_INIT_TLS_SET_CHANNEL_CONTROL : - return "CO_E_INIT_TLS_SET_CHANNEL_CONTROL "; - case CO_E_INIT_TLS_CHANNEL_CONTROL : - return "CO_E_INIT_TLS_CHANNEL_CONTROL "; - case CO_E_INIT_UNACCEPTED_USER_ALLOCATOR : - return "CO_E_INIT_UNACCEPTED_USER_ALLOCATOR "; - case CO_E_INIT_SCM_MUTEX_EXISTS : - return "CO_E_INIT_SCM_MUTEX_EXISTS "; - case CO_E_INIT_SCM_FILE_MAPPING_EXISTS : - return "CO_E_INIT_SCM_FILE_MAPPING_EXISTS "; - case CO_E_INIT_SCM_MAP_VIEW_OF_FILE : - return "CO_E_INIT_SCM_MAP_VIEW_OF_FILE "; - case CO_E_INIT_SCM_EXEC_FAILURE : - return "CO_E_INIT_SCM_EXEC_FAILURE "; - case CO_E_INIT_ONLY_SINGLE_THREADED : - return "CO_E_INIT_ONLY_SINGLE_THREADED "; - case CO_E_CANT_REMOTE : - return "CO_E_CANT_REMOTE "; - case CO_E_BAD_SERVER_NAME : - return "CO_E_BAD_SERVER_NAME "; - case CO_E_WRONG_SERVER_IDENTITY : - return "CO_E_WRONG_SERVER_IDENTITY "; - case CO_E_OLE1DDE_DISABLED : - return "CO_E_OLE1DDE_DISABLED "; - case CO_E_RUNAS_SYNTAX : - return "CO_E_RUNAS_SYNTAX "; - case CO_E_CREATEPROCESS_FAILURE : - return "CO_E_CREATEPROCESS_FAILURE "; - case CO_E_RUNAS_CREATEPROCESS_FAILURE : - return "CO_E_RUNAS_CREATEPROCESS_FAILURE "; - case CO_E_RUNAS_LOGON_FAILURE : - return "CO_E_RUNAS_LOGON_FAILURE "; - case CO_E_LAUNCH_PERMSSION_DENIED : - return "CO_E_LAUNCH_PERMSSION_DENIED "; - case CO_E_START_SERVICE_FAILURE : - return "CO_E_START_SERVICE_FAILURE "; - case CO_E_REMOTE_COMMUNICATION_FAILURE : - return "CO_E_REMOTE_COMMUNICATION_FAILURE "; - case CO_E_SERVER_START_TIMEOUT : - return "CO_E_SERVER_START_TIMEOUT "; - case CO_E_CLSREG_INCONSISTENT : - return "CO_E_CLSREG_INCONSISTENT "; - case CO_E_IIDREG_INCONSISTENT : - return "CO_E_IIDREG_INCONSISTENT "; - case CO_E_NOT_SUPPORTED : - return "CO_E_NOT_SUPPORTED "; - case CO_E_RELOAD_DLL : - return "CO_E_RELOAD_DLL "; - case CO_E_MSI_ERROR : - return "CO_E_MSI_ERROR "; - case OLE_E_OLEVERB : - return "OLE_E_OLEVERB "; - case OLE_E_ADVF : - return "OLE_E_ADVF "; - case OLE_E_ENUM_NOMORE : - return "OLE_E_ENUM_NOMORE "; - case OLE_E_ADVISENOTSUPPORTED : - return "OLE_E_ADVISENOTSUPPORTED "; - case OLE_E_NOCONNECTION : - return "OLE_E_NOCONNECTION "; - case OLE_E_NOTRUNNING : - return "OLE_E_NOTRUNNING "; - case OLE_E_NOCACHE : - return "OLE_E_NOCACHE "; - case OLE_E_BLANK : - return "OLE_E_BLANK "; - case OLE_E_CLASSDIFF : - return "OLE_E_CLASSDIFF "; - case OLE_E_CANT_GETMONIKER : - return "OLE_E_CANT_GETMONIKER "; - case OLE_E_CANT_BINDTOSOURCE : - return "OLE_E_CANT_BINDTOSOURCE "; - case OLE_E_STATIC : - return "OLE_E_STATIC "; - case OLE_E_PROMPTSAVECANCELLED : - return "OLE_E_PROMPTSAVECANCELLED "; - case OLE_E_INVALIDRECT : - return "OLE_E_INVALIDRECT "; - case OLE_E_WRONGCOMPOBJ : - return "OLE_E_WRONGCOMPOBJ "; - case OLE_E_INVALIDHWND : - return "OLE_E_INVALIDHWND "; - case OLE_E_NOT_INPLACEACTIVE : - return "OLE_E_NOT_INPLACEACTIVE "; - case OLE_E_CANTCONVERT : - return "OLE_E_CANTCONVERT "; - case OLE_E_NOSTORAGE : - return "OLE_E_NOSTORAGE "; - case DV_E_FORMATETC : - return "DV_E_FORMATETC "; - case DV_E_DVTARGETDEVICE : - return "DV_E_DVTARGETDEVICE "; - case DV_E_STGMEDIUM : - return "DV_E_STGMEDIUM "; - case DV_E_STATDATA : - return "DV_E_STATDATA "; - case DV_E_LINDEX : - return "DV_E_LINDEX "; - case DV_E_TYMED : - return "DV_E_TYMED "; - case DV_E_CLIPFORMAT : - return "DV_E_CLIPFORMAT "; - case DV_E_DVASPECT : - return "DV_E_DVASPECT "; - case DV_E_DVTARGETDEVICE_SIZE : - return "DV_E_DVTARGETDEVICE_SIZE "; - case DV_E_NOIVIEWOBJECT : - return "DV_E_NOIVIEWOBJECT "; - case DRAGDROP_E_NOTREGISTERED : - return "DRAGDROP_E_NOTREGISTERED "; - case DRAGDROP_E_ALREADYREGISTERED : - return "DRAGDROP_E_ALREADYREGISTERED "; - case DRAGDROP_E_INVALIDHWND : - return "DRAGDROP_E_INVALIDHWND "; - case CLASS_E_NOAGGREGATION : - return "CLASS_E_NOAGGREGATION "; - case CLASS_E_CLASSNOTAVAILABLE : - return "CLASS_E_CLASSNOTAVAILABLE "; - case CLASS_E_NOTLICENSED : - return "CLASS_E_NOTLICENSED "; - case VIEW_E_DRAW : - return "VIEW_E_DRAW "; - case REGDB_E_READREGDB : - return "REGDB_E_READREGDB "; - case REGDB_E_WRITEREGDB : - return "REGDB_E_WRITEREGDB "; - case REGDB_E_KEYMISSING : - return "REGDB_E_KEYMISSING "; - case REGDB_E_INVALIDVALUE : - return "REGDB_E_INVALIDVALUE "; - case REGDB_E_CLASSNOTREG : - return "REGDB_E_CLASSNOTREG "; - case REGDB_E_IIDNOTREG : - return "REGDB_E_IIDNOTREG "; - case CAT_E_CATIDNOEXIST : - return "CAT_E_CATIDNOEXIST "; - case CAT_E_NODESCRIPTION : - return "CAT_E_NODESCRIPTION "; - case CS_E_PACKAGE_NOTFOUND : - return "CS_E_PACKAGE_NOTFOUND "; - case CS_E_NOT_DELETABLE : - return "CS_E_NOT_DELETABLE "; - case CS_E_CLASS_NOTFOUND : - return "CS_E_CLASS_NOTFOUND "; - case CS_E_INVALID_VERSION : - return "CS_E_INVALID_VERSION "; - case CS_E_NO_CLASSSTORE : - return "CS_E_NO_CLASSSTORE "; - case CACHE_E_NOCACHE_UPDATED : - return "CACHE_E_NOCACHE_UPDATED "; - case OLEOBJ_E_NOVERBS : - return "OLEOBJ_E_NOVERBS "; - case OLEOBJ_E_INVALIDVERB : - return "OLEOBJ_E_INVALIDVERB "; - case INPLACE_E_NOTUNDOABLE : - return "INPLACE_E_NOTUNDOABLE "; - case INPLACE_E_NOTOOLSPACE : - return "INPLACE_E_NOTOOLSPACE "; - case CONVERT10_E_OLESTREAM_GET : - return "CONVERT10_E_OLESTREAM_GET "; - case CONVERT10_E_OLESTREAM_PUT : - return "CONVERT10_E_OLESTREAM_PUT "; - case CONVERT10_E_OLESTREAM_FMT : - return "CONVERT10_E_OLESTREAM_FMT "; - case CONVERT10_E_OLESTREAM_BITMAP_TO_DIB : - return "CONVERT10_E_OLESTREAM_BITMAP_TO_DIB "; - case CONVERT10_E_STG_FMT : - return "CONVERT10_E_STG_FMT "; - case CONVERT10_E_STG_NO_STD_STREAM : - return "CONVERT10_E_STG_NO_STD_STREAM "; - case CONVERT10_E_STG_DIB_TO_BITMAP : - return "CONVERT10_E_STG_DIB_TO_BITMAP "; - case CLIPBRD_E_CANT_OPEN : - return "CLIPBRD_E_CANT_OPEN "; - case CLIPBRD_E_CANT_EMPTY : - return "CLIPBRD_E_CANT_EMPTY "; - case CLIPBRD_E_CANT_SET : - return "CLIPBRD_E_CANT_SET "; - case CLIPBRD_E_BAD_DATA : - return "CLIPBRD_E_BAD_DATA "; - case CLIPBRD_E_CANT_CLOSE : - return "CLIPBRD_E_CANT_CLOSE "; - case MK_E_CONNECTMANUALLY : - return "MK_E_CONNECTMANUALLY "; - case MK_E_EXCEEDEDDEADLINE : - return "MK_E_EXCEEDEDDEADLINE "; - case MK_E_NEEDGENERIC : - return "MK_E_NEEDGENERIC "; - case MK_E_UNAVAILABLE : - return "MK_E_UNAVAILABLE "; - case MK_E_SYNTAX : - return "MK_E_SYNTAX "; - case MK_E_NOOBJECT : - return "MK_E_NOOBJECT "; - case MK_E_INVALIDEXTENSION : - return "MK_E_INVALIDEXTENSION "; - case MK_E_INTERMEDIATEINTERFACENOTSUPPORTED : - return "MK_E_INTERMEDIATEINTERFACENOTSUPPORTED "; - case MK_E_NOTBINDABLE : - return "MK_E_NOTBINDABLE "; - case MK_E_NOTBOUND : - return "MK_E_NOTBOUND "; - case MK_E_CANTOPENFILE : - return "MK_E_CANTOPENFILE "; - case MK_E_MUSTBOTHERUSER : - return "MK_E_MUSTBOTHERUSER "; - case MK_E_NOINVERSE : - return "MK_E_NOINVERSE "; - case MK_E_NOSTORAGE : - return "MK_E_NOSTORAGE "; - case MK_E_NOPREFIX : - return "MK_E_NOPREFIX "; - case MK_E_ENUMERATION_FAILED : - return "MK_E_ENUMERATION_FAILED "; - case CO_E_NOTINITIALIZED : - return "CO_E_NOTINITIALIZED "; - case CO_E_ALREADYINITIALIZED : - return "CO_E_ALREADYINITIALIZED "; - case CO_E_CANTDETERMINECLASS : - return "CO_E_CANTDETERMINECLASS "; - case CO_E_CLASSSTRING : - return "CO_E_CLASSSTRING "; - case CO_E_IIDSTRING : - return "CO_E_IIDSTRING "; - case CO_E_APPNOTFOUND : - return "CO_E_APPNOTFOUND "; - case CO_E_APPSINGLEUSE : - return "CO_E_APPSINGLEUSE "; - case CO_E_ERRORINAPP : - return "CO_E_ERRORINAPP "; - case CO_E_DLLNOTFOUND : - return "CO_E_DLLNOTFOUND "; - case CO_E_ERRORINDLL : - return "CO_E_ERRORINDLL "; - case CO_E_WRONGOSFORAPP : - return "CO_E_WRONGOSFORAPP "; - case CO_E_OBJNOTREG : - return "CO_E_OBJNOTREG "; - case CO_E_OBJISREG : - return "CO_E_OBJISREG "; - case CO_E_OBJNOTCONNECTED : - return "CO_E_OBJNOTCONNECTED "; - case CO_E_APPDIDNTREG : - return "CO_E_APPDIDNTREG "; - case CO_E_RELEASED : - return "CO_E_RELEASED "; - case CO_E_FAILEDTOIMPERSONATE : - return "CO_E_FAILEDTOIMPERSONATE "; - case CO_E_FAILEDTOGETSECCTX : - return "CO_E_FAILEDTOGETSECCTX "; - case CO_E_FAILEDTOOPENTHREADTOKEN : - return "CO_E_FAILEDTOOPENTHREADTOKEN "; - case CO_E_FAILEDTOGETTOKENINFO : - return "CO_E_FAILEDTOGETTOKENINFO "; - case CO_E_TRUSTEEDOESNTMATCHCLIENT : - return "CO_E_TRUSTEEDOESNTMATCHCLIENT "; - case CO_E_FAILEDTOQUERYCLIENTBLANKET : - return "CO_E_FAILEDTOQUERYCLIENTBLANKET "; - case CO_E_FAILEDTOSETDACL : - return "CO_E_FAILEDTOSETDACL "; - case CO_E_ACCESSCHECKFAILED : - return "CO_E_ACCESSCHECKFAILED "; - case CO_E_NETACCESSAPIFAILED : - return "CO_E_NETACCESSAPIFAILED "; - case CO_E_WRONGTRUSTEENAMESYNTAX : - return "CO_E_WRONGTRUSTEENAMESYNTAX "; - case CO_E_INVALIDSID : - return "CO_E_INVALIDSID "; - case CO_E_CONVERSIONFAILED : - return "CO_E_CONVERSIONFAILED "; - case CO_E_NOMATCHINGSIDFOUND : - return "CO_E_NOMATCHINGSIDFOUND "; - case CO_E_LOOKUPACCSIDFAILED : - return "CO_E_LOOKUPACCSIDFAILED "; - case CO_E_NOMATCHINGNAMEFOUND : - return "CO_E_NOMATCHINGNAMEFOUND "; - case CO_E_LOOKUPACCNAMEFAILED : - return "CO_E_LOOKUPACCNAMEFAILED "; - case CO_E_SETSERLHNDLFAILED : - return "CO_E_SETSERLHNDLFAILED "; - case CO_E_FAILEDTOGETWINDIR : - return "CO_E_FAILEDTOGETWINDIR "; - case CO_E_PATHTOOLONG : - return "CO_E_PATHTOOLONG "; - case CO_E_FAILEDTOGENUUID : - return "CO_E_FAILEDTOGENUUID "; - case CO_E_FAILEDTOCREATEFILE : - return "CO_E_FAILEDTOCREATEFILE "; - case CO_E_FAILEDTOCLOSEHANDLE : - return "CO_E_FAILEDTOCLOSEHANDLE "; - case CO_E_EXCEEDSYSACLLIMIT : - return "CO_E_EXCEEDSYSACLLIMIT "; - case CO_E_ACESINWRONGORDER : - return "CO_E_ACESINWRONGORDER "; - case CO_E_INCOMPATIBLESTREAMVERSION : - return "CO_E_INCOMPATIBLESTREAMVERSION "; - case CO_E_FAILEDTOOPENPROCESSTOKEN : - return "CO_E_FAILEDTOOPENPROCESSTOKEN "; - case CO_E_DECODEFAILED : - return "CO_E_DECODEFAILED "; - case CO_E_ACNOTINITIALIZED : - return "CO_E_ACNOTINITIALIZED "; - case OLE_S_USEREG : - return "OLE_S_USEREG "; - case OLE_S_STATIC : - return "OLE_S_STATIC "; - case OLE_S_MAC_CLIPFORMAT : - return "OLE_S_MAC_CLIPFORMAT "; - case DRAGDROP_S_DROP : - return "DRAGDROP_S_DROP "; - case DRAGDROP_S_CANCEL : - return "DRAGDROP_S_CANCEL "; - case DRAGDROP_S_USEDEFAULTCURSORS : - return "DRAGDROP_S_USEDEFAULTCURSORS "; - case DATA_S_SAMEFORMATETC : - return "DATA_S_SAMEFORMATETC "; - case VIEW_S_ALREADY_FROZEN : - return "VIEW_S_ALREADY_FROZEN "; - case CACHE_S_FORMATETC_NOTSUPPORTED : - return "CACHE_S_FORMATETC_NOTSUPPORTED "; - case CACHE_S_SAMECACHE : - return "CACHE_S_SAMECACHE "; - case CACHE_S_SOMECACHES_NOTUPDATED : - return "CACHE_S_SOMECACHES_NOTUPDATED "; - case OLEOBJ_S_INVALIDVERB : - return "OLEOBJ_S_INVALIDVERB "; - case OLEOBJ_S_CANNOT_DOVERB_NOW : - return "OLEOBJ_S_CANNOT_DOVERB_NOW "; - case OLEOBJ_S_INVALIDHWND : - return "OLEOBJ_S_INVALIDHWND "; - case INPLACE_S_TRUNCATED : - return "INPLACE_S_TRUNCATED "; - case CONVERT10_S_NO_PRESENTATION : - return "CONVERT10_S_NO_PRESENTATION "; - case MK_S_REDUCED_TO_SELF : - return "MK_S_REDUCED_TO_SELF "; - case MK_S_ME : - return "MK_S_ME "; - case MK_S_HIM : - return "MK_S_HIM "; - case MK_S_US : - return "MK_S_US "; - case MK_S_MONIKERALREADYREGISTERED : - return "MK_S_MONIKERALREADYREGISTERED "; - case CO_E_CLASS_CREATE_FAILED : - return "CO_E_CLASS_CREATE_FAILED "; - case CO_E_SCM_ERROR : - return "CO_E_SCM_ERROR "; - case CO_E_SCM_RPC_FAILURE : - return "CO_E_SCM_RPC_FAILURE "; - case CO_E_BAD_PATH : - return "CO_E_BAD_PATH "; - case CO_E_SERVER_EXEC_FAILURE : - return "CO_E_SERVER_EXEC_FAILURE "; - case CO_E_OBJSRV_RPC_FAILURE : - return "CO_E_OBJSRV_RPC_FAILURE "; - case MK_E_NO_NORMALIZED : - return "MK_E_NO_NORMALIZED "; - case CO_E_SERVER_STOPPING : - return "CO_E_SERVER_STOPPING "; - case MEM_E_INVALID_ROOT : - return "MEM_E_INVALID_ROOT "; - case MEM_E_INVALID_LINK : - return "MEM_E_INVALID_LINK "; - case MEM_E_INVALID_SIZE : - return "MEM_E_INVALID_SIZE "; - case CO_S_NOTALLINTERFACES : - return "CO_S_NOTALLINTERFACES "; - case DISP_E_UNKNOWNINTERFACE : - return "DISP_E_UNKNOWNINTERFACE "; - case DISP_E_MEMBERNOTFOUND : - return "DISP_E_MEMBERNOTFOUND "; - case DISP_E_PARAMNOTFOUND : - return "DISP_E_PARAMNOTFOUND "; - case DISP_E_TYPEMISMATCH : - return "DISP_E_TYPEMISMATCH "; - case DISP_E_UNKNOWNNAME : - return "DISP_E_UNKNOWNNAME "; - case DISP_E_NONAMEDARGS : - return "DISP_E_NONAMEDARGS "; - case DISP_E_BADVARTYPE : - return "DISP_E_BADVARTYPE "; - case DISP_E_EXCEPTION : - return "DISP_E_EXCEPTION "; - case DISP_E_OVERFLOW : - return "DISP_E_OVERFLOW "; - case DISP_E_BADINDEX : - return "DISP_E_BADINDEX "; - case DISP_E_UNKNOWNLCID : - return "DISP_E_UNKNOWNLCID "; - case DISP_E_ARRAYISLOCKED : - return "DISP_E_ARRAYISLOCKED "; - case DISP_E_BADPARAMCOUNT : - return "DISP_E_BADPARAMCOUNT "; - case DISP_E_PARAMNOTOPTIONAL : - return "DISP_E_PARAMNOTOPTIONAL "; - case DISP_E_BADCALLEE : - return "DISP_E_BADCALLEE "; - case DISP_E_NOTACOLLECTION : - return "DISP_E_NOTACOLLECTION "; - case DISP_E_DIVBYZERO : - return "DISP_E_DIVBYZERO "; - case TYPE_E_BUFFERTOOSMALL : - return "TYPE_E_BUFFERTOOSMALL "; - case TYPE_E_FIELDNOTFOUND : - return "TYPE_E_FIELDNOTFOUND "; - case TYPE_E_INVDATAREAD : - return "TYPE_E_INVDATAREAD "; - case TYPE_E_UNSUPFORMAT : - return "TYPE_E_UNSUPFORMAT "; - case TYPE_E_REGISTRYACCESS : - return "TYPE_E_REGISTRYACCESS "; - case TYPE_E_LIBNOTREGISTERED : - return "TYPE_E_LIBNOTREGISTERED "; - case TYPE_E_UNDEFINEDTYPE : - return "TYPE_E_UNDEFINEDTYPE "; - case TYPE_E_QUALIFIEDNAMEDISALLOWED : - return "TYPE_E_QUALIFIEDNAMEDISALLOWED "; - case TYPE_E_INVALIDSTATE : - return "TYPE_E_INVALIDSTATE "; - case TYPE_E_WRONGTYPEKIND : - return "TYPE_E_WRONGTYPEKIND "; - case TYPE_E_ELEMENTNOTFOUND : - return "TYPE_E_ELEMENTNOTFOUND "; - case TYPE_E_AMBIGUOUSNAME : - return "TYPE_E_AMBIGUOUSNAME "; - case TYPE_E_NAMECONFLICT : - return "TYPE_E_NAMECONFLICT "; - case TYPE_E_UNKNOWNLCID : - return "TYPE_E_UNKNOWNLCID "; - case TYPE_E_DLLFUNCTIONNOTFOUND : - return "TYPE_E_DLLFUNCTIONNOTFOUND "; - case TYPE_E_BADMODULEKIND : - return "TYPE_E_BADMODULEKIND "; - case TYPE_E_SIZETOOBIG : - return "TYPE_E_SIZETOOBIG "; - case TYPE_E_DUPLICATEID : - return "TYPE_E_DUPLICATEID "; - case TYPE_E_INVALIDID : - return "TYPE_E_INVALIDID "; - case TYPE_E_TYPEMISMATCH : - return "TYPE_E_TYPEMISMATCH "; - case TYPE_E_OUTOFBOUNDS : - return "TYPE_E_OUTOFBOUNDS "; - case TYPE_E_IOERROR : - return "TYPE_E_IOERROR "; - case TYPE_E_CANTCREATETMPFILE : - return "TYPE_E_CANTCREATETMPFILE "; - case TYPE_E_CANTLOADLIBRARY : - return "TYPE_E_CANTLOADLIBRARY "; - case TYPE_E_INCONSISTENTPROPFUNCS : - return "TYPE_E_INCONSISTENTPROPFUNCS "; - case TYPE_E_CIRCULARTYPE : - return "TYPE_E_CIRCULARTYPE "; - case STG_E_INVALIDFUNCTION : - return "STG_E_INVALIDFUNCTION "; - case STG_E_FILENOTFOUND : - return "STG_E_FILENOTFOUND "; - case STG_E_PATHNOTFOUND : - return "STG_E_PATHNOTFOUND "; - case STG_E_TOOMANYOPENFILES : - return "STG_E_TOOMANYOPENFILES "; - case STG_E_ACCESSDENIED : - return "STG_E_ACCESSDENIED "; - case STG_E_INVALIDHANDLE : - return "STG_E_INVALIDHANDLE "; - case STG_E_INSUFFICIENTMEMORY : - return "STG_E_INSUFFICIENTMEMORY "; - case STG_E_INVALIDPOINTER : - return "STG_E_INVALIDPOINTER "; - case STG_E_NOMOREFILES : - return "STG_E_NOMOREFILES "; - case STG_E_DISKISWRITEPROTECTED : - return "STG_E_DISKISWRITEPROTECTED "; - case STG_E_SEEKERROR : - return "STG_E_SEEKERROR "; - case STG_E_WRITEFAULT : - return "STG_E_WRITEFAULT "; - case STG_E_READFAULT : - return "STG_E_READFAULT "; - case STG_E_SHAREVIOLATION : - return "STG_E_SHAREVIOLATION "; - case STG_E_LOCKVIOLATION : - return "STG_E_LOCKVIOLATION "; - case STG_E_FILEALREADYEXISTS : - return "STG_E_FILEALREADYEXISTS "; - case STG_E_INVALIDPARAMETER : - return "STG_E_INVALIDPARAMETER "; - case STG_E_MEDIUMFULL : - return "STG_E_MEDIUMFULL "; - case STG_E_PROPSETMISMATCHED : - return "STG_E_PROPSETMISMATCHED "; - case STG_E_ABNORMALAPIEXIT : - return "STG_E_ABNORMALAPIEXIT "; - case STG_E_INVALIDHEADER : - return "STG_E_INVALIDHEADER "; - case STG_E_INVALIDNAME : - return "STG_E_INVALIDNAME "; - case STG_E_UNKNOWN : - return "STG_E_UNKNOWN "; - case STG_E_UNIMPLEMENTEDFUNCTION : - return "STG_E_UNIMPLEMENTEDFUNCTION "; - case STG_E_INVALIDFLAG : - return "STG_E_INVALIDFLAG "; - case STG_E_INUSE : - return "STG_E_INUSE "; - case STG_E_NOTCURRENT : - return "STG_E_NOTCURRENT "; - case STG_E_REVERTED : - return "STG_E_REVERTED "; - case STG_E_CANTSAVE : - return "STG_E_CANTSAVE "; - case STG_E_OLDFORMAT : - return "STG_E_OLDFORMAT "; - case STG_E_OLDDLL : - return "STG_E_OLDDLL "; - case STG_E_SHAREREQUIRED : - return "STG_E_SHAREREQUIRED "; - case STG_E_NOTFILEBASEDSTORAGE : - return "STG_E_NOTFILEBASEDSTORAGE "; - case STG_E_EXTANTMARSHALLINGS : - return "STG_E_EXTANTMARSHALLINGS "; - case STG_E_DOCFILECORRUPT : - return "STG_E_DOCFILECORRUPT "; - case STG_E_BADBASEADDRESS : - return "STG_E_BADBASEADDRESS "; - case STG_E_INCOMPLETE : - return "STG_E_INCOMPLETE "; - case STG_E_TERMINATED : - return "STG_E_TERMINATED "; - case STG_S_CONVERTED : - return "STG_S_CONVERTED "; - case STG_S_BLOCK : - return "STG_S_BLOCK "; - case STG_S_RETRYNOW : - return "STG_S_RETRYNOW "; - case STG_S_MONITORING : - return "STG_S_MONITORING "; - case STG_S_MULTIPLEOPENS : - return "STG_S_MULTIPLEOPENS "; - case STG_S_CONSOLIDATIONFAILED : - return "STG_S_CONSOLIDATIONFAILED "; - case STG_S_CANNOTCONSOLIDATE : - return "STG_S_CANNOTCONSOLIDATE "; - case RPC_E_CALL_REJECTED : - return "RPC_E_CALL_REJECTED "; - case RPC_E_CALL_CANCELED : - return "RPC_E_CALL_CANCELED "; - case RPC_E_CANTPOST_INSENDCALL : - return "RPC_E_CANTPOST_INSENDCALL "; - case RPC_E_CANTCALLOUT_INASYNCCALL : - return "RPC_E_CANTCALLOUT_INASYNCCALL "; - case RPC_E_CANTCALLOUT_INEXTERNALCALL : - return "RPC_E_CANTCALLOUT_INEXTERNALCALL "; - case RPC_E_CONNECTION_TERMINATED : - return "RPC_E_CONNECTION_TERMINATED "; - case RPC_E_SERVER_DIED : - return "RPC_E_SERVER_DIED "; - case RPC_E_CLIENT_DIED : - return "RPC_E_CLIENT_DIED "; - case RPC_E_INVALID_DATAPACKET : - return "RPC_E_INVALID_DATAPACKET "; - case RPC_E_CANTTRANSMIT_CALL : - return "RPC_E_CANTTRANSMIT_CALL "; - case RPC_E_CLIENT_CANTMARSHAL_DATA : - return "RPC_E_CLIENT_CANTMARSHAL_DATA "; - case RPC_E_CLIENT_CANTUNMARSHAL_DATA : - return "RPC_E_CLIENT_CANTUNMARSHAL_DATA "; - case RPC_E_SERVER_CANTMARSHAL_DATA : - return "RPC_E_SERVER_CANTMARSHAL_DATA "; - case RPC_E_SERVER_CANTUNMARSHAL_DATA : - return "RPC_E_SERVER_CANTUNMARSHAL_DATA "; - case RPC_E_INVALID_DATA : - return "RPC_E_INVALID_DATA "; - case RPC_E_INVALID_PARAMETER : - return "RPC_E_INVALID_PARAMETER "; - case RPC_E_CANTCALLOUT_AGAIN : - return "RPC_E_CANTCALLOUT_AGAIN "; - case RPC_E_SERVER_DIED_DNE : - return "RPC_E_SERVER_DIED_DNE "; - case RPC_E_SYS_CALL_FAILED : - return "RPC_E_SYS_CALL_FAILED "; - case RPC_E_OUT_OF_RESOURCES : - return "RPC_E_OUT_OF_RESOURCES "; - case RPC_E_ATTEMPTED_MULTITHREAD : - return "RPC_E_ATTEMPTED_MULTITHREAD "; - case RPC_E_NOT_REGISTERED : - return "RPC_E_NOT_REGISTERED "; - case RPC_E_FAULT : - return "RPC_E_FAULT "; - case RPC_E_SERVERFAULT : - return "RPC_E_SERVERFAULT "; - case RPC_E_CHANGED_MODE : - return "RPC_E_CHANGED_MODE "; - case RPC_E_INVALIDMETHOD : - return "RPC_E_INVALIDMETHOD "; - case RPC_E_DISCONNECTED : - return "RPC_E_DISCONNECTED "; - case RPC_E_RETRY : - return "RPC_E_RETRY "; - case RPC_E_SERVERCALL_RETRYLATER : - return "RPC_E_SERVERCALL_RETRYLATER "; - case RPC_E_SERVERCALL_REJECTED : - return "RPC_E_SERVERCALL_REJECTED "; - case RPC_E_INVALID_CALLDATA : - return "RPC_E_INVALID_CALLDATA "; - case RPC_E_CANTCALLOUT_ININPUTSYNCCALL : - return "RPC_E_CANTCALLOUT_ININPUTSYNCCALL "; - case RPC_E_WRONG_THREAD : - return "RPC_E_WRONG_THREAD "; - case RPC_E_THREAD_NOT_INIT : - return "RPC_E_THREAD_NOT_INIT "; - case RPC_E_VERSION_MISMATCH : - return "RPC_E_VERSION_MISMATCH "; - case RPC_E_INVALID_HEADER : - return "RPC_E_INVALID_HEADER "; - case RPC_E_INVALID_EXTENSION : - return "RPC_E_INVALID_EXTENSION "; - case RPC_E_INVALID_IPID : - return "RPC_E_INVALID_IPID "; - case RPC_E_INVALID_OBJECT : - return "RPC_E_INVALID_OBJECT "; - case RPC_S_CALLPENDING : - return "RPC_S_CALLPENDING "; - case RPC_S_WAITONTIMER : - return "RPC_S_WAITONTIMER "; - case RPC_E_CALL_COMPLETE : - return "RPC_E_CALL_COMPLETE "; - case RPC_E_UNSECURE_CALL : - return "RPC_E_UNSECURE_CALL "; - case RPC_E_TOO_LATE : - return "RPC_E_TOO_LATE "; - case RPC_E_NO_GOOD_SECURITY_PACKAGES : - return "RPC_E_NO_GOOD_SECURITY_PACKAGES "; - case RPC_E_ACCESS_DENIED : - return "RPC_E_ACCESS_DENIED "; - case RPC_E_REMOTE_DISABLED : - return "RPC_E_REMOTE_DISABLED "; - case RPC_E_INVALID_OBJREF : - return "RPC_E_INVALID_OBJREF "; - case RPC_E_NO_CONTEXT : - return "RPC_E_NO_CONTEXT "; - case RPC_E_TIMEOUT : - return "RPC_E_TIMEOUT "; - case RPC_E_NO_SYNC : - return "RPC_E_NO_SYNC "; - case RPC_E_UNEXPECTED : - return "RPC_E_UNEXPECTED "; - case NTE_BAD_UID : - return "NTE_BAD_UID "; - case NTE_BAD_HASH : - return "NTE_BAD_HASH "; - //case NTE_BAD_HASH : - //return "NTE_BAD_HASH "; - case NTE_BAD_KEY : - return "NTE_BAD_KEY "; - case NTE_BAD_LEN : - return "NTE_BAD_LEN "; - case NTE_BAD_DATA : - return "NTE_BAD_DATA "; - case NTE_BAD_SIGNATURE : - return "NTE_BAD_SIGNATURE "; - case NTE_BAD_VER : - return "NTE_BAD_VER "; - case NTE_BAD_ALGID : - return "NTE_BAD_ALGID "; - case NTE_BAD_FLAGS : - return "NTE_BAD_FLAGS "; - case NTE_BAD_TYPE : - return "NTE_BAD_TYPE "; - case NTE_BAD_KEY_STATE : - return "NTE_BAD_KEY_STATE "; - case NTE_BAD_HASH_STATE : - return "NTE_BAD_HASH_STATE "; - case NTE_NO_KEY : - return "NTE_NO_KEY "; - case NTE_NO_MEMORY : - return "NTE_NO_MEMORY "; - case NTE_EXISTS : - return "NTE_EXISTS "; - case NTE_PERM : - return "NTE_PERM "; - case NTE_NOT_FOUND : - return "NTE_NOT_FOUND "; - case NTE_DOUBLE_ENCRYPT : - return "NTE_DOUBLE_ENCRYPT "; - case NTE_BAD_PROVIDER : - return "NTE_BAD_PROVIDER "; - case NTE_BAD_PROV_TYPE : - return "NTE_BAD_PROV_TYPE "; - case NTE_BAD_PUBLIC_KEY : - return "NTE_BAD_PUBLIC_KEY "; - case NTE_BAD_KEYSET : - return "NTE_BAD_KEYSET "; - case NTE_PROV_TYPE_NOT_DEF : - return "NTE_PROV_TYPE_NOT_DEF "; - case NTE_PROV_TYPE_ENTRY_BAD : - return "NTE_PROV_TYPE_ENTRY_BAD "; - case NTE_KEYSET_NOT_DEF : - return "NTE_KEYSET_NOT_DEF "; - case NTE_KEYSET_ENTRY_BAD : - return "NTE_KEYSET_ENTRY_BAD "; - case NTE_PROV_TYPE_NO_MATCH : - return "NTE_PROV_TYPE_NO_MATCH "; - case NTE_SIGNATURE_FILE_BAD : - return "NTE_SIGNATURE_FILE_BAD "; - case NTE_PROVIDER_DLL_FAIL : - return "NTE_PROVIDER_DLL_FAIL "; - case NTE_PROV_DLL_NOT_FOUND : - return "NTE_PROV_DLL_NOT_FOUND "; - case NTE_BAD_KEYSET_PARAM : - return "NTE_BAD_KEYSET_PARAM "; - case NTE_FAIL : - return "NTE_FAIL "; - case NTE_SYS_ERR : - return "NTE_SYS_ERR "; - case CRYPT_E_MSG_ERROR : - return "CRYPT_E_MSG_ERROR "; - case CRYPT_E_UNKNOWN_ALGO : - return "CRYPT_E_UNKNOWN_ALGO "; - case CRYPT_E_OID_FORMAT : - return "CRYPT_E_OID_FORMAT "; - case CRYPT_E_INVALID_MSG_TYPE : - return "CRYPT_E_INVALID_MSG_TYPE "; - case CRYPT_E_UNEXPECTED_ENCODING : - return "CRYPT_E_UNEXPECTED_ENCODING "; - case CRYPT_E_AUTH_ATTR_MISSING : - return "CRYPT_E_AUTH_ATTR_MISSING "; - case CRYPT_E_HASH_VALUE : - return "CRYPT_E_HASH_VALUE "; - case CRYPT_E_INVALID_INDEX : - return "CRYPT_E_INVALID_INDEX "; - case CRYPT_E_ALREADY_DECRYPTED : - return "CRYPT_E_ALREADY_DECRYPTED "; - case CRYPT_E_NOT_DECRYPTED : - return "CRYPT_E_NOT_DECRYPTED "; - case CRYPT_E_RECIPIENT_NOT_FOUND : - return "CRYPT_E_RECIPIENT_NOT_FOUND "; - case CRYPT_E_CONTROL_TYPE : - return "CRYPT_E_CONTROL_TYPE "; - case CRYPT_E_ISSUER_SERIALNUMBER : - return "CRYPT_E_ISSUER_SERIALNUMBER "; - case CRYPT_E_SIGNER_NOT_FOUND : - return "CRYPT_E_SIGNER_NOT_FOUND "; - case CRYPT_E_ATTRIBUTES_MISSING : - return "CRYPT_E_ATTRIBUTES_MISSING "; - case CRYPT_E_STREAM_MSG_NOT_READY : - return "CRYPT_E_STREAM_MSG_NOT_READY "; - case CRYPT_E_STREAM_INSUFFICIENT_DATA : - return "CRYPT_E_STREAM_INSUFFICIENT_DATA "; - case CRYPT_E_BAD_LEN : - return "CRYPT_E_BAD_LEN "; - case CRYPT_E_BAD_ENCODE : - return "CRYPT_E_BAD_ENCODE "; - case CRYPT_E_FILE_ERROR : - return "CRYPT_E_FILE_ERROR "; - case CRYPT_E_NOT_FOUND : - return "CRYPT_E_NOT_FOUND "; - case CRYPT_E_EXISTS : - return "CRYPT_E_EXISTS "; - case CRYPT_E_NO_PROVIDER : - return "CRYPT_E_NO_PROVIDER "; - case CRYPT_E_SELF_SIGNED : - return "CRYPT_E_SELF_SIGNED "; - case CRYPT_E_DELETED_PREV : - return "CRYPT_E_DELETED_PREV "; - case CRYPT_E_NO_MATCH : - return "CRYPT_E_NO_MATCH "; - case CRYPT_E_UNEXPECTED_MSG_TYPE : - return "CRYPT_E_UNEXPECTED_MSG_TYPE "; - case CRYPT_E_NO_KEY_PROPERTY : - return "CRYPT_E_NO_KEY_PROPERTY "; - case CRYPT_E_NO_DECRYPT_CERT : - return "CRYPT_E_NO_DECRYPT_CERT "; - case CRYPT_E_BAD_MSG : - return "CRYPT_E_BAD_MSG "; - case CRYPT_E_NO_SIGNER : - return "CRYPT_E_NO_SIGNER "; - case CRYPT_E_PENDING_CLOSE : - return "CRYPT_E_PENDING_CLOSE "; - case CRYPT_E_REVOKED : - return "CRYPT_E_REVOKED "; - case CRYPT_E_NO_REVOCATION_DLL : - return "CRYPT_E_NO_REVOCATION_DLL "; - case CRYPT_E_NO_REVOCATION_CHECK : - return "CRYPT_E_NO_REVOCATION_CHECK "; - case CRYPT_E_REVOCATION_OFFLINE : - return "CRYPT_E_REVOCATION_OFFLINE "; - case CRYPT_E_NOT_IN_REVOCATION_DATABASE : - return "CRYPT_E_NOT_IN_REVOCATION_DATABASE "; - case CRYPT_E_INVALID_NUMERIC_STRING : - return "CRYPT_E_INVALID_NUMERIC_STRING "; - case CRYPT_E_INVALID_PRINTABLE_STRING : - return "CRYPT_E_INVALID_PRINTABLE_STRING "; - case CRYPT_E_INVALID_IA5_STRING : - return "CRYPT_E_INVALID_IA5_STRING "; - case CRYPT_E_INVALID_X500_STRING : - return "CRYPT_E_INVALID_X500_STRING "; - case CRYPT_E_NOT_CHAR_STRING : - return "CRYPT_E_NOT_CHAR_STRING "; - case CRYPT_E_FILERESIZED : - return "CRYPT_E_FILERESIZED "; - case CRYPT_E_SECURITY_SETTINGS : - return "CRYPT_E_SECURITY_SETTINGS "; - case CRYPT_E_NO_VERIFY_USAGE_DLL : - return "CRYPT_E_NO_VERIFY_USAGE_DLL "; - case CRYPT_E_NO_VERIFY_USAGE_CHECK : - return "CRYPT_E_NO_VERIFY_USAGE_CHECK "; - case CRYPT_E_VERIFY_USAGE_OFFLINE : - return "CRYPT_E_VERIFY_USAGE_OFFLINE "; - case CRYPT_E_NOT_IN_CTL : - return "CRYPT_E_NOT_IN_CTL "; - case CRYPT_E_NO_TRUSTED_SIGNER : - return "CRYPT_E_NO_TRUSTED_SIGNER "; - case CRYPT_E_OSS_ERROR : - return "CRYPT_E_OSS_ERROR "; - case CERTSRV_E_BAD_REQUESTSUBJECT : - return "CERTSRV_E_BAD_REQUESTSUBJECT "; - case CERTSRV_E_NO_REQUEST : - return "CERTSRV_E_NO_REQUEST "; - case CERTSRV_E_BAD_REQUESTSTATUS : - return "CERTSRV_E_BAD_REQUESTSTATUS "; - case CERTSRV_E_PROPERTY_EMPTY : - return "CERTSRV_E_PROPERTY_EMPTY "; - //case CERTDB_E_JET_ERROR : - //return "CERTDB_E_JET_ERROR "; - case TRUST_E_SYSTEM_ERROR : - return "TRUST_E_SYSTEM_ERROR "; - case TRUST_E_NO_SIGNER_CERT : - return "TRUST_E_NO_SIGNER_CERT "; - case TRUST_E_COUNTER_SIGNER : - return "TRUST_E_COUNTER_SIGNER "; - case TRUST_E_CERT_SIGNATURE : - return "TRUST_E_CERT_SIGNATURE "; - case TRUST_E_TIME_STAMP : - return "TRUST_E_TIME_STAMP "; - case TRUST_E_BAD_DIGEST : - return "TRUST_E_BAD_DIGEST "; - case TRUST_E_BASIC_CONSTRAINTS : - return "TRUST_E_BASIC_CONSTRAINTS "; - case TRUST_E_FINANCIAL_CRITERIA : - return "TRUST_E_FINANCIAL_CRITERIA "; - case TRUST_E_PROVIDER_UNKNOWN : - return "TRUST_E_PROVIDER_UNKNOWN "; - case TRUST_E_ACTION_UNKNOWN : - return "TRUST_E_ACTION_UNKNOWN "; - case TRUST_E_SUBJECT_FORM_UNKNOWN : - return "TRUST_E_SUBJECT_FORM_UNKNOWN "; - case TRUST_E_SUBJECT_NOT_TRUSTED : - return "TRUST_E_SUBJECT_NOT_TRUSTED "; - case DIGSIG_E_ENCODE : - return "DIGSIG_E_ENCODE "; - case DIGSIG_E_DECODE : - return "DIGSIG_E_DECODE "; - case DIGSIG_E_EXTENSIBILITY : - return "DIGSIG_E_EXTENSIBILITY "; - case DIGSIG_E_CRYPTO : - return "DIGSIG_E_CRYPTO "; - case PERSIST_E_SIZEDEFINITE : - return "PERSIST_E_SIZEDEFINITE "; - case PERSIST_E_SIZEINDEFINITE : - return "PERSIST_E_SIZEINDEFINITE "; - case PERSIST_E_NOTSELFSIZING : - return "PERSIST_E_NOTSELFSIZING "; - case TRUST_E_NOSIGNATURE : - return "TRUST_E_NOSIGNATURE "; - case CERT_E_EXPIRED : - return "CERT_E_EXPIRED "; - case CERT_E_VALIDITYPERIODNESTING : - return "CERT_E_VALIDITYPERIODNESTING "; - case CERT_E_ROLE : - return "CERT_E_ROLE "; - case CERT_E_PATHLENCONST : - return "CERT_E_PATHLENCONST "; - case CERT_E_CRITICAL : - return "CERT_E_CRITICAL "; - case CERT_E_PURPOSE : - return "CERT_E_PURPOSE "; - case CERT_E_ISSUERCHAINING : - return "CERT_E_ISSUERCHAINING "; - case CERT_E_MALFORMED : - return "CERT_E_MALFORMED "; - case CERT_E_UNTRUSTEDROOT : - return "CERT_E_UNTRUSTEDROOT "; - case CERT_E_CHAINING : - return "CERT_E_CHAINING "; - case TRUST_E_FAIL : - return "TRUST_E_FAIL "; - case CERT_E_REVOKED : - return "CERT_E_REVOKED "; - case CERT_E_UNTRUSTEDTESTROOT : - return "CERT_E_UNTRUSTEDTESTROOT "; - case CERT_E_REVOCATION_FAILURE : - return "CERT_E_REVOCATION_FAILURE "; - case CERT_E_CN_NO_MATCH : - return "CERT_E_CN_NO_MATCH "; - case CERT_E_WRONG_USAGE : - return "CERT_E_WRONG_USAGE "; - case SPAPI_E_EXPECTED_SECTION_NAME : - return "SPAPI_E_EXPECTED_SECTION_NAME "; - case SPAPI_E_BAD_SECTION_NAME_LINE : - return "SPAPI_E_BAD_SECTION_NAME_LINE "; - case SPAPI_E_SECTION_NAME_TOO_LONG : - return "SPAPI_E_SECTION_NAME_TOO_LONG "; - case SPAPI_E_GENERAL_SYNTAX : - return "SPAPI_E_GENERAL_SYNTAX "; - case SPAPI_E_WRONG_INF_STYLE : - return "SPAPI_E_WRONG_INF_STYLE "; - case SPAPI_E_SECTION_NOT_FOUND : - return "SPAPI_E_SECTION_NOT_FOUND "; - case SPAPI_E_LINE_NOT_FOUND : - return "SPAPI_E_LINE_NOT_FOUND "; - case SPAPI_E_NO_ASSOCIATED_CLASS : - return "SPAPI_E_NO_ASSOCIATED_CLASS "; - case SPAPI_E_CLASS_MISMATCH : - return "SPAPI_E_CLASS_MISMATCH "; - case SPAPI_E_DUPLICATE_FOUND : - return "SPAPI_E_DUPLICATE_FOUND "; - case SPAPI_E_NO_DRIVER_SELECTED : - return "SPAPI_E_NO_DRIVER_SELECTED "; - case SPAPI_E_KEY_DOES_NOT_EXIST : - return "SPAPI_E_KEY_DOES_NOT_EXIST "; - case SPAPI_E_INVALID_DEVINST_NAME : - return "SPAPI_E_INVALID_DEVINST_NAME "; - case SPAPI_E_INVALID_CLASS : - return "SPAPI_E_INVALID_CLASS "; - case SPAPI_E_DEVINST_ALREADY_EXISTS : - return "SPAPI_E_DEVINST_ALREADY_EXISTS "; - case SPAPI_E_DEVINFO_NOT_REGISTERED : - return "SPAPI_E_DEVINFO_NOT_REGISTERED "; - case SPAPI_E_INVALID_REG_PROPERTY : - return "SPAPI_E_INVALID_REG_PROPERTY "; - case SPAPI_E_NO_INF : - return "SPAPI_E_NO_INF "; - case SPAPI_E_NO_SUCH_DEVINST : - return "SPAPI_E_NO_SUCH_DEVINST "; - case SPAPI_E_CANT_LOAD_CLASS_ICON : - return "SPAPI_E_CANT_LOAD_CLASS_ICON "; - case SPAPI_E_INVALID_CLASS_INSTALLER : - return "SPAPI_E_INVALID_CLASS_INSTALLER "; - case SPAPI_E_DI_DO_DEFAULT : - return "SPAPI_E_DI_DO_DEFAULT "; - case SPAPI_E_DI_NOFILECOPY : - return "SPAPI_E_DI_NOFILECOPY "; - case SPAPI_E_INVALID_HWPROFILE : - return "SPAPI_E_INVALID_HWPROFILE "; - case SPAPI_E_NO_DEVICE_SELECTED : - return "SPAPI_E_NO_DEVICE_SELECTED "; - case SPAPI_E_DEVINFO_LIST_LOCKED : - return "SPAPI_E_DEVINFO_LIST_LOCKED "; - case SPAPI_E_DEVINFO_DATA_LOCKED : - return "SPAPI_E_DEVINFO_DATA_LOCKED "; - case SPAPI_E_DI_BAD_PATH : - return "SPAPI_E_DI_BAD_PATH "; - case SPAPI_E_NO_CLASSINSTALL_PARAMS : - return "SPAPI_E_NO_CLASSINSTALL_PARAMS "; - case SPAPI_E_FILEQUEUE_LOCKED : - return "SPAPI_E_FILEQUEUE_LOCKED "; - case SPAPI_E_BAD_SERVICE_INSTALLSECT : - return "SPAPI_E_BAD_SERVICE_INSTALLSECT "; - case SPAPI_E_NO_CLASS_DRIVER_LIST : - return "SPAPI_E_NO_CLASS_DRIVER_LIST "; - case SPAPI_E_NO_ASSOCIATED_SERVICE : - return "SPAPI_E_NO_ASSOCIATED_SERVICE "; - case SPAPI_E_NO_DEFAULT_DEVICE_INTERFACE : - return "SPAPI_E_NO_DEFAULT_DEVICE_INTERFACE "; - case SPAPI_E_DEVICE_INTERFACE_ACTIVE : - return "SPAPI_E_DEVICE_INTERFACE_ACTIVE "; - case SPAPI_E_DEVICE_INTERFACE_REMOVED : - return "SPAPI_E_DEVICE_INTERFACE_REMOVED "; - case SPAPI_E_BAD_INTERFACE_INSTALLSECT : - return "SPAPI_E_BAD_INTERFACE_INSTALLSECT "; - case SPAPI_E_NO_SUCH_INTERFACE_CLASS : - return "SPAPI_E_NO_SUCH_INTERFACE_CLASS "; - case SPAPI_E_INVALID_REFERENCE_STRING : - return "SPAPI_E_INVALID_REFERENCE_STRING "; - case SPAPI_E_INVALID_MACHINENAME : - return "SPAPI_E_INVALID_MACHINENAME "; - case SPAPI_E_REMOTE_COMM_FAILURE : - return "SPAPI_E_REMOTE_COMM_FAILURE "; - case SPAPI_E_MACHINE_UNAVAILABLE : - return "SPAPI_E_MACHINE_UNAVAILABLE "; - case SPAPI_E_NO_CONFIGMGR_SERVICES : - return "SPAPI_E_NO_CONFIGMGR_SERVICES "; - case SPAPI_E_INVALID_PROPPAGE_PROVIDER : - return "SPAPI_E_INVALID_PROPPAGE_PROVIDER "; - case SPAPI_E_NO_SUCH_DEVICE_INTERFACE : - return "SPAPI_E_NO_SUCH_DEVICE_INTERFACE "; - case SPAPI_E_DI_POSTPROCESSING_REQUIRED : - return "SPAPI_E_DI_POSTPROCESSING_REQUIRED "; - case SPAPI_E_INVALID_COINSTALLER : - return "SPAPI_E_INVALID_COINSTALLER "; - case SPAPI_E_NO_COMPAT_DRIVERS : - return "SPAPI_E_NO_COMPAT_DRIVERS "; - case SPAPI_E_NO_DEVICE_ICON : - return "SPAPI_E_NO_DEVICE_ICON "; - case SPAPI_E_INVALID_INF_LOGCONFIG : - return "SPAPI_E_INVALID_INF_LOGCONFIG "; - case SPAPI_E_DI_DONT_INSTALL : - return "SPAPI_E_DI_DONT_INSTALL "; - case SPAPI_E_INVALID_FILTER_DRIVER : - return "SPAPI_E_INVALID_FILTER_DRIVER "; - case SPAPI_E_ERROR_NOT_INSTALLED : - return "SPAPI_E_ERROR_NOT_INSTALLED "; - - default: - static char buff[1000]; - sprintf(buff, "Unrecognized error value: %08X\0", error); - - return buff; - } -} - -// Global system parameters we want to modify during our run -static int iMouseTrails; -static bool bCursorShadowOn,bMouseVanish; - -void set_global_parameters() { - // turn off mousetrails and cursor shadow and mouse cursor vanish - // cursor shadow causes cursor blink and reduced frame rate due to lack of driver support for - // cursor alpha blending - - // this is a win2k/xp only param, could use GetVersionEx to do it just for win2k, - // but since it is just a param it will just cause a silent error on other OS's - // that should be ok - SystemParametersInfo(SPI_GETCURSORSHADOW,NULL,&bCursorShadowOn,NULL); - SystemParametersInfo(SPI_SETCURSORSHADOW,NULL,(PVOID)false,NULL); - - SystemParametersInfo(SPI_GETMOUSETRAILS,NULL,&iMouseTrails,NULL); - SystemParametersInfo(SPI_SETMOUSETRAILS,NULL,(PVOID)0,NULL); - - // this is ME/XP only feature - SystemParametersInfo(SPI_GETMOUSEVANISH,NULL,&bMouseVanish,NULL); - SystemParametersInfo(SPI_SETMOUSEVANISH,NULL,(PVOID)false,NULL); -} - -void restore_global_parameters() { - SystemParametersInfo(SPI_SETCURSORSHADOW,NULL,(PVOID)bCursorShadowOn,NULL); - SystemParametersInfo(SPI_SETMOUSETRAILS,NULL,(PVOID)iMouseTrails,NULL); - SystemParametersInfo(SPI_SETMOUSEVANISH,NULL,(PVOID)bMouseVanish,NULL); -} - diff --git a/panda/src/wgldisplay/wglGraphicsWindow.h b/panda/src/wgldisplay/wglGraphicsWindow.h index e14337ab6d..d3802c46ca 100644 --- a/panda/src/wgldisplay/wglGraphicsWindow.h +++ b/panda/src/wgldisplay/wglGraphicsWindow.h @@ -1,5 +1,5 @@ // Filename: wglGraphicsWindow.h -// Created by: mike (09Jan97) +// Created by: drose (20Dec02) // //////////////////////////////////////////////////////////////////// // @@ -15,144 +15,65 @@ // panda3d@yahoogroups.com . // //////////////////////////////////////////////////////////////////// + #ifndef WGLGRAPHICSWINDOW_H #define WGLGRAPHICSWINDOW_H -// -//////////////////////////////////////////////////////////////////// -// Includes -//////////////////////////////////////////////////////////////////// -// include win32 defns for everything up to XP, and assume I'm smart enough to -// use GetProcAddress for backward compat on w95/w98 for newer fns -#define _WIN32_WINNT 0x0501 - -#define WINDOWS_LEAN_AND_MEAN -#include -#undef WINDOWS_LEAN_AND_MEAN - -#include -#include - -//////////////////////////////////////////////////////////////////// -// Defines -//////////////////////////////////////////////////////////////////// -class wglGraphicsPipe; - -#if 0 -#define GLX_USE_GL 1 /* support GLX rendering */ -#define GLX_BUFFER_SIZE 2 /* depth of the color buffer */ -#define GLX_LEVEL 3 /* level in plane stacking */ -#define GLX_RGBA 4 /* true if RGBA mode */ -#define GLX_DOUBLEBUFFER 5 /* double buffering supported */ -#define GLX_STEREO 6 /* stereo buffering supported */ -#define GLX_AUX_BUFFERS 7 /* number of aux buffers */ -#define GLX_RED_SIZE 8 /* number of red component bits */ -#define GLX_GREEN_SIZE 9 /* number of green component bits */ -#define GLX_BLUE_SIZE 10 /* number of blue component bits */ -#define GLX_ALPHA_SIZE 11 /* number of alpha component bits */ -#define GLX_DEPTH_SIZE 12 /* number of depth bits */ -#define GLX_STENCIL_SIZE 13 /* number of stencil bits */ -#define GLX_ACCUM_RED_SIZE 14 /* number of red accum bits */ -#define GLX_ACCUM_GREEN_SIZE 15 /* number of green accum bits */ -#define GLX_ACCUM_BLUE_SIZE 16 /* number of blue accum bits */ -#define GLX_ACCUM_ALPHA_SIZE 17 /* number of alpha accum bits */ -#endif +#include "pandabase.h" +#include "winGraphicsWindow.h" //////////////////////////////////////////////////////////////////// // Class : wglGraphicsWindow -// Description : +// Description : A single graphics window for rendering OpenGL under +// Microsoft Windows. //////////////////////////////////////////////////////////////////// -class EXPCL_PANDAGL wglGraphicsWindow : public GraphicsWindow { +class EXPCL_PANDAGL wglGraphicsWindow : public WinGraphicsWindow { public: - wglGraphicsWindow(GraphicsPipe* pipe); - wglGraphicsWindow(GraphicsPipe* pipe, - const GraphicsWindow::Properties& props); + wglGraphicsWindow(GraphicsPipe *pipe); virtual ~wglGraphicsWindow(); - virtual void end_frame(); - virtual void swap(); - virtual int get_depth_bitwidth(); - - virtual TypeHandle get_gsg_type() const; - static GraphicsWindow* make_wglGraphicsWindow(const FactoryParams ¶ms); - -public: + virtual void make_gsg(); + virtual void release_gsg(); virtual void make_current(); - virtual void unmake_current(); - void handle_mouse_motion(int x, int y); - void handle_mouse_exit(void); - INLINE void track_mouse_leaving(HWND hwnd); - void handle_keypress(ButtonHandle key, int x, int y); - void handle_keyrelease(ButtonHandle key); + + virtual void begin_flip(); protected: - int choose_visual(void); - int find_pixfmtnum(bool bLookforHW); - virtual void config(); - void setup_colormap(void); - void handle_reshape(); - void process_events(); - -public: - HWND _mwindow; + virtual bool open_window(); + virtual bool do_fullscreen_resize(int x_size, int y_size); private: - HGLRC _context; - HDC _hdc; - PIXELFORMATDESCRIPTOR _pixelformat; - HPALETTE _colormap; - HCURSOR _hMouseCursor; - HWND _hOldForegroundWindow; - UINT_PTR _PandaPausedTimer; + int choose_pfnum() const; + int find_pixfmtnum(bool bLookforHW) const; + void setup_colormap(); - DEVMODE *_pCurrent_display_settings; - bool _bIsLowVidMemCard; - bool _bLoadedCustomCursor; +#ifdef _DEBUG + static void print_pfd(PIXELFORMATDESCRIPTOR *pfd, char *msg); +#endif - bool _active_minimized_fullscreen; - bool _return_control_to_app; - bool _exiting_window; - bool _cursor_in_windowclientarea; - bool _tracking_mouse_leaving; - bool _ime_open; - bool _ime_active; - bool _ime_composition_w; - - // vars for frames/sec meter - DWORD _start_time; - DWORD _start_frame_count; - DWORD _cur_frame_count; - float _current_fps; - - string _extensions_str; - - typedef BOOL (WINAPI* PFN_TRACKMOUSEEVENT)(LPTRACKMOUSEEVENT); - PFN_TRACKMOUSEEVENT _pfnTrackMouseEvent; + HGLRC _context; + HDC _hdc; + PIXELFORMATDESCRIPTOR _pixelformat; + HPALETTE _colormap; public: - static TypeHandle get_class_type(); - static void init_type(); - virtual TypeHandle get_type() const; + static TypeHandle get_class_type() { + return _type_handle; + } + static void init_type() { + WinGraphicsWindow::init_type(); + register_type(_type_handle, "wglGraphicsWindow", + WinGraphicsWindow::get_class_type()); + } + virtual TypeHandle get_type() const { + return get_class_type(); + } virtual TypeHandle force_init_type() {init_type(); return get_class_type();} - LONG WINAPI window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam); - ButtonHandle lookup_key(WPARAM wparam) const; - void DestroyMe(bool bAtExitFnCalled); - virtual void deactivate_window(); - virtual void reactivate_window(); - - virtual bool resize(unsigned int xsize,unsigned int ysize); - virtual unsigned int verify_window_sizes(unsigned int numsizes,unsigned int *dimen); - -protected: - virtual void do_close_window(); - void check_for_color_cursor_support(); - private: static TypeHandle _type_handle; }; -extern void set_global_parameters(); -extern void restore_global_parameters(); +#include "wglGraphicsWindow.I" #endif diff --git a/panda/src/wgldisplay/wgldisplay_composite1.cxx b/panda/src/wgldisplay/wgldisplay_composite1.cxx index 9e626a1d40..a810e1c47f 100644 --- a/panda/src/wgldisplay/wgldisplay_composite1.cxx +++ b/panda/src/wgldisplay/wgldisplay_composite1.cxx @@ -1,3 +1,4 @@ +#include "config_wgldisplay.cxx" +#include "wglGraphicsPipe.cxx" +#include "wglGraphicsWindow.cxx" -#include"config_wgldisplay.cxx" -#include"wglGraphicsPipe.cxx" diff --git a/panda/src/wgldisplay/wglext.h b/panda/src/wgldisplay/wglext.h deleted file mode 100644 index 4d1fe5a6a0..0000000000 --- a/panda/src/wgldisplay/wglext.h +++ /dev/null @@ -1,416 +0,0 @@ -#ifndef __wglext_h_ -#define __wglext_h_ - -#ifdef __cplusplus -extern "C" { -#endif - -/* -** License Applicability. Except to the extent portions of this file are -** made subject to an alternative license as permitted in the SGI Free -** Software License B, Version 1.1 (the "License"), the contents of this -** file are subject only to the provisions of the License. You may not use -** this file except in compliance with the License. You may obtain a copy -** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 -** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: -** -** http://oss.sgi.com/projects/FreeB -** -** Note that, as provided in the License, the Software is distributed on an -** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS -** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND -** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A -** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. -** -** Original Code. The Original Code is: OpenGL Sample Implementation, -** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, -** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. -** Copyright in any portions created by third parties is as indicated -** elsewhere herein. All Rights Reserved. -** -** Additional Notice Provisions: This software was created using the -** OpenGL(R) version 1.2.1 Sample Implementation published by SGI, but has -** not been independently verified as being compliant with the OpenGL(R) -** version 1.2.1 Specification. -*/ - -#if defined(_WIN32) && !defined(APIENTRY) && !defined(__CYGWIN__) -#define WIN32_LEAN_AND_MEAN 1 -#include -#endif - -#ifndef APIENTRY -#define APIENTRY -#endif - -/*************************************************************/ - -/* Header file version number */ -#define WGL_WGLEXT_VERSION 1 - -#ifndef WGL_ARB_buffer_region -#define WGL_FRONT_COLOR_BUFFER_BIT_ARB 0x00000001 -#define WGL_BACK_COLOR_BUFFER_BIT_ARB 0x00000002 -#define WGL_DEPTH_BUFFER_BIT_ARB 0x00000004 -#define WGL_STENCIL_BUFFER_BIT_ARB 0x00000008 -#endif - -#ifndef WGL_ARB_extensions_string -#endif - -#ifndef WGL_ARB_pixel_format -#define WGL_NUMBER_PIXEL_FORMATS_ARB 0x2000 -#define WGL_DRAW_TO_WINDOW_ARB 0x2001 -#define WGL_DRAW_TO_BITMAP_ARB 0x2002 -#define WGL_ACCELERATION_ARB 0x2003 -#define WGL_NEED_PALETTE_ARB 0x2004 -#define WGL_NEED_SYSTEM_PALETTE_ARB 0x2005 -#define WGL_SWAP_LAYER_BUFFERS_ARB 0x2006 -#define WGL_SWAP_METHOD_ARB 0x2007 -#define WGL_NUMBER_OVERLAYS_ARB 0x2008 -#define WGL_NUMBER_UNDERLAYS_ARB 0x2009 -#define WGL_TRANSPARENT_ARB 0x200A -#define WGL_TRANSPARENT_RED_VALUE_ARB 0x2037 -#define WGL_TRANSPARENT_GREEN_VALUE_ARB 0x2038 -#define WGL_TRANSPARENT_BLUE_VALUE_ARB 0x2039 -#define WGL_TRANSPARENT_ALPHA_VALUE_ARB 0x203A -#define WGL_TRANSPARENT_INDEX_VALUE_ARB 0x203B -#define WGL_SHARE_DEPTH_ARB 0x200C -#define WGL_SHARE_STENCIL_ARB 0x200D -#define WGL_SHARE_ACCUM_ARB 0x200E -#define WGL_SUPPORT_GDI_ARB 0x200F -#define WGL_SUPPORT_OPENGL_ARB 0x2010 -#define WGL_DOUBLE_BUFFER_ARB 0x2011 -#define WGL_STEREO_ARB 0x2012 -#define WGL_PIXEL_TYPE_ARB 0x2013 -#define WGL_COLOR_BITS_ARB 0x2014 -#define WGL_RED_BITS_ARB 0x2015 -#define WGL_RED_SHIFT_ARB 0x2016 -#define WGL_GREEN_BITS_ARB 0x2017 -#define WGL_GREEN_SHIFT_ARB 0x2018 -#define WGL_BLUE_BITS_ARB 0x2019 -#define WGL_BLUE_SHIFT_ARB 0x201A -#define WGL_ALPHA_BITS_ARB 0x201B -#define WGL_ALPHA_SHIFT_ARB 0x201C -#define WGL_ACCUM_BITS_ARB 0x201D -#define WGL_ACCUM_RED_BITS_ARB 0x201E -#define WGL_ACCUM_GREEN_BITS_ARB 0x201F -#define WGL_ACCUM_BLUE_BITS_ARB 0x2020 -#define WGL_ACCUM_ALPHA_BITS_ARB 0x2021 -#define WGL_DEPTH_BITS_ARB 0x2022 -#define WGL_STENCIL_BITS_ARB 0x2023 -#define WGL_AUX_BUFFERS_ARB 0x2024 -#define WGL_NO_ACCELERATION_ARB 0x2025 -#define WGL_GENERIC_ACCELERATION_ARB 0x2026 -#define WGL_FULL_ACCELERATION_ARB 0x2027 -#define WGL_SWAP_EXCHANGE_ARB 0x2028 -#define WGL_SWAP_COPY_ARB 0x2029 -#define WGL_SWAP_UNDEFINED_ARB 0x202A -#define WGL_TYPE_RGBA_ARB 0x202B -#define WGL_TYPE_COLORINDEX_ARB 0x202C -#endif - -#ifndef WGL_ARB_make_current_read -#define ERROR_INVALID_PIXEL_TYPE_ARB 0x2043 -#define ERROR_INCOMPATIBLE_DEVICE_CONTEXTS_ARB 0x2054 -#endif - -#ifndef WGL_ARB_pbuffer -#define WGL_DRAW_TO_PBUFFER_ARB 0x202D -#define WGL_MAX_PBUFFER_PIXELS_ARB 0x202E -#define WGL_MAX_PBUFFER_WIDTH_ARB 0x202F -#define WGL_MAX_PBUFFER_HEIGHT_ARB 0x2030 -#define WGL_PBUFFER_LARGEST_ARB 0x2033 -#define WGL_PBUFFER_WIDTH_ARB 0x2034 -#define WGL_PBUFFER_HEIGHT_ARB 0x2035 -#define WGL_PBUFFER_LOST_ARB 0x2036 -#endif - -#ifndef WGL_EXT_make_current_read -#define ERROR_INVALID_PIXEL_TYPE_EXT 0x2043 -#endif - -#ifndef WGL_EXT_pixel_format -#define WGL_NUMBER_PIXEL_FORMATS_EXT 0x2000 -#define WGL_DRAW_TO_WINDOW_EXT 0x2001 -#define WGL_DRAW_TO_BITMAP_EXT 0x2002 -#define WGL_ACCELERATION_EXT 0x2003 -#define WGL_NEED_PALETTE_EXT 0x2004 -#define WGL_NEED_SYSTEM_PALETTE_EXT 0x2005 -#define WGL_SWAP_LAYER_BUFFERS_EXT 0x2006 -#define WGL_SWAP_METHOD_EXT 0x2007 -#define WGL_NUMBER_OVERLAYS_EXT 0x2008 -#define WGL_NUMBER_UNDERLAYS_EXT 0x2009 -#define WGL_TRANSPARENT_EXT 0x200A -#define WGL_TRANSPARENT_VALUE_EXT 0x200B -#define WGL_SHARE_DEPTH_EXT 0x200C -#define WGL_SHARE_STENCIL_EXT 0x200D -#define WGL_SHARE_ACCUM_EXT 0x200E -#define WGL_SUPPORT_GDI_EXT 0x200F -#define WGL_SUPPORT_OPENGL_EXT 0x2010 -#define WGL_DOUBLE_BUFFER_EXT 0x2011 -#define WGL_STEREO_EXT 0x2012 -#define WGL_PIXEL_TYPE_EXT 0x2013 -#define WGL_COLOR_BITS_EXT 0x2014 -#define WGL_RED_BITS_EXT 0x2015 -#define WGL_RED_SHIFT_EXT 0x2016 -#define WGL_GREEN_BITS_EXT 0x2017 -#define WGL_GREEN_SHIFT_EXT 0x2018 -#define WGL_BLUE_BITS_EXT 0x2019 -#define WGL_BLUE_SHIFT_EXT 0x201A -#define WGL_ALPHA_BITS_EXT 0x201B -#define WGL_ALPHA_SHIFT_EXT 0x201C -#define WGL_ACCUM_BITS_EXT 0x201D -#define WGL_ACCUM_RED_BITS_EXT 0x201E -#define WGL_ACCUM_GREEN_BITS_EXT 0x201F -#define WGL_ACCUM_BLUE_BITS_EXT 0x2020 -#define WGL_ACCUM_ALPHA_BITS_EXT 0x2021 -#define WGL_DEPTH_BITS_EXT 0x2022 -#define WGL_STENCIL_BITS_EXT 0x2023 -#define WGL_AUX_BUFFERS_EXT 0x2024 -#define WGL_NO_ACCELERATION_EXT 0x2025 -#define WGL_GENERIC_ACCELERATION_EXT 0x2026 -#define WGL_FULL_ACCELERATION_EXT 0x2027 -#define WGL_SWAP_EXCHANGE_EXT 0x2028 -#define WGL_SWAP_COPY_EXT 0x2029 -#define WGL_SWAP_UNDEFINED_EXT 0x202A -#define WGL_TYPE_RGBA_EXT 0x202B -#define WGL_TYPE_COLORINDEX_EXT 0x202C -#endif - -#ifndef WGL_EXT_pbuffer -#define WGL_DRAW_TO_PBUFFER_EXT 0x202D -#define WGL_MAX_PBUFFER_PIXELS_EXT 0x202E -#define WGL_MAX_PBUFFER_WIDTH_EXT 0x202F -#define WGL_MAX_PBUFFER_HEIGHT_EXT 0x2030 -#define WGL_OPTIMAL_PBUFFER_WIDTH_EXT 0x2031 -#define WGL_OPTIMAL_PBUFFER_HEIGHT_EXT 0x2032 -#define WGL_PBUFFER_LARGEST_EXT 0x2033 -#define WGL_PBUFFER_WIDTH_EXT 0x2034 -#define WGL_PBUFFER_HEIGHT_EXT 0x2035 -#endif - -#ifndef WGL_EXT_depth_float -#define WGL_DEPTH_FLOAT_EXT 0x2040 -#endif - -#ifndef WGL_3DFX_multisample -#define WGL_SAMPLE_BUFFERS_3DFX 0x2060 -#define WGL_SAMPLES_3DFX 0x2061 -#endif - -#ifndef WGL_EXT_multisample -#define WGL_SAMPLE_BUFFERS_EXT 0x2041 -#define WGL_SAMPLES_EXT 0x2042 -#endif - -#ifndef WGL_I3D_unknown_genlock_extension_name -#define WGL_GENLOCK_SOURCE_MULTIVIEW_I3D 0x2044 -#define WGL_GENLOCK_SOURCE_EXTENAL_SYNC_I3D 0x2045 -#define WGL_GENLOCK_SOURCE_EXTENAL_FIELD_I3D 0x2046 -#define WGL_GENLOCK_SOURCE_EXTENAL_TTL_I3D 0x2047 -#define WGL_GENLOCK_SOURCE_DIGITAL_SYNC_I3D 0x2048 -#define WGL_GENLOCK_SOURCE_DIGITAL_FIELD_I3D 0x2049 -#define WGL_GENLOCK_SOURCE_EDGE_FALLING_I3D 0x204A -#define WGL_GENLOCK_SOURCE_EDGE_RISING_I3D 0x204B -#define WGL_GENLOCK_SOURCE_EDGE_BOTH_I3D 0x204C -#endif - -#ifndef WGL_I3D_unknown_gamma_extension_name -#define WGL_GAMMA_TABLE_SIZE_I3D 0x204E -#define WGL_GAMMA_EXCLUDE_DESKTOP_I3D 0x204F -#endif - -#ifndef WGL_I3D_unknown_digital_video_cursor_extension_name -#define WGL_DIGITAL_VIDEO_CURSOR_ALPHA_FRAMEBUFFER_I3D 0x2050 -#define WGL_DIGITAL_VIDEO_CURSOR_ALPHA_VALUE_I3D 0x2051 -#define WGL_DIGITAL_VIDEO_CURSOR_INCLUDED_I3D 0x2052 -#define WGL_DIGITAL_VIDEO_GAMMA_CORRECTED_I3D 0x2053 -#endif - - -/*************************************************************/ - -#ifndef WGL_ARB_pbuffer -DECLARE_HANDLE(HPBUFFERARB); -#endif -#ifndef WGL_EXT_pbuffer -DECLARE_HANDLE(HPBUFFEREXT); -#endif - -#ifndef WGL_ARB_buffer_region -#define WGL_ARB_buffer_region 1 -#ifdef WGL_WGLEXT_PROTOTYPES -extern HANDLE WINAPI wglCreateBufferRegionARB (HDC, int, UINT); -extern VOID WINAPI wglDeleteBufferRegionARB (HANDLE); -extern BOOL WINAPI wglSaveBufferRegionARB (HANDLE, int, int, int, int); -extern BOOL WINAPI wglRestoreBufferRegionARB (HANDLE, int, int, int, int, int, int); -#endif /* WGL_WGLEXT_PROTOTYPES */ -typedef HANDLE (WINAPI * PFNWGLCREATEBUFFERREGIONARBPROC) (HDC hDC, int iLayerPlane, UINT uType); -typedef VOID (WINAPI * PFNWGLDELETEBUFFERREGIONARBPROC) (HANDLE hRegion); -typedef BOOL (WINAPI * PFNWGLSAVEBUFFERREGIONARBPROC) (HANDLE hRegion, int x, int y, int width, int height); -typedef BOOL (WINAPI * PFNWGLRESTOREBUFFERREGIONARBPROC) (HANDLE hRegion, int x, int y, int width, int height, int xSrc, int ySrc); -#endif - -#ifndef WGL_ARB_extensions_string -#define WGL_ARB_extensions_string 1 -#ifdef WGL_WGLEXT_PROTOTYPES -extern const char * WINAPI wglGetExtensionsStringARB (HDC); -#endif /* WGL_WGLEXT_PROTOTYPES */ -typedef const char * (WINAPI * PFNWGLGETEXTENSIONSSTRINGARBPROC) (HDC hdc); -#endif - -#ifndef WGL_ARB_pixel_format -#define WGL_ARB_pixel_format 1 -#ifdef WGL_WGLEXT_PROTOTYPES -extern BOOL WINAPI wglGetPixelFormatAttribivARB (HDC, int, int, UINT, const int *, int *); -extern BOOL WINAPI wglGetPixelFormatAttribfvARB (HDC, int, int, UINT, const int *, FLOAT *); -extern BOOL WINAPI wglChoosePixelFormatARB (HDC, const int *, const FLOAT *, UINT, int *, UINT *); -#endif /* WGL_WGLEXT_PROTOTYPES */ -typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBIVARBPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, int *piValues); -typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBFVARBPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, FLOAT *pfValues); -typedef BOOL (WINAPI * PFNWGLCHOOSEPIXELFORMATARBPROC) (HDC hdc, const int *piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats); -#endif - -#ifndef WGL_ARB_make_current_read -#define WGL_ARB_make_current_read 1 -#ifdef WGL_WGLEXT_PROTOTYPES -extern BOOL WINAPI wglMakeContextCurrentARB (HDC, HDC, HGLRC); -extern HDC WINAPI wglGetCurrentReadDCARB (void); -#endif /* WGL_WGLEXT_PROTOTYPES */ -typedef BOOL (WINAPI * PFNWGLMAKECONTEXTCURRENTARBPROC) (HDC hDrawDC, HDC hReadDC, HGLRC hglrc); -typedef HDC (WINAPI * PFNWGLGETCURRENTREADDCARBPROC) (void); -#endif - -#ifndef WGL_ARB_pbuffer -#define WGL_ARB_pbuffer 1 -#ifdef WGL_WGLEXT_PROTOTYPES -extern HPBUFFERARB WINAPI wglCreatePbufferARB (HDC, int, int, int, const int *); -extern HDC WINAPI wglGetPbufferDCARB (HPBUFFERARB); -extern int WINAPI wglReleasePbufferDCARB (HPBUFFERARB, HDC); -extern BOOL WINAPI wglDestroyPbufferARB (HPBUFFERARB); -extern BOOL WINAPI wglQueryPbufferARB (HPBUFFERARB, int, int *); -#endif /* WGL_WGLEXT_PROTOTYPES */ -typedef HPBUFFERARB (WINAPI * PFNWGLCREATEPBUFFERARBPROC) (HDC hDC, int iPixelFormat, int iWidth, int iHeight, const int *piAttribList); -typedef HDC (WINAPI * PFNWGLGETPBUFFERDCARBPROC) (HPBUFFERARB hPbuffer); -typedef int (WINAPI * PFNWGLRELEASEPBUFFERDCARBPROC) (HPBUFFERARB hPbuffer, HDC hDC); -typedef BOOL (WINAPI * PFNWGLDESTROYPBUFFERARBPROC) (HPBUFFERARB hPbuffer); -typedef BOOL (WINAPI * PFNWGLQUERYPBUFFERARBPROC) (HPBUFFERARB hPbuffer, int iAttribute, int *piValue); -#endif - -#ifndef WGL_EXT_display_color_table -#define WGL_EXT_display_color_table 1 -#ifdef WGL_WGLEXT_PROTOTYPES -extern GLboolean WINAPI wglCreateDisplayColorTableEXT (GLushort); -extern GLboolean WINAPI wglLoadDisplayColorTableEXT (const GLushort *, GLuint); -extern GLboolean WINAPI wglBindDisplayColorTableEXT (GLushort); -extern VOID WINAPI wglDestroyDisplayColorTableEXT (GLushort); -#endif /* WGL_WGLEXT_PROTOTYPES */ -typedef GLboolean (WINAPI * PFNWGLCREATEDISPLAYCOLORTABLEEXTPROC) (GLushort id); -typedef GLboolean (WINAPI * PFNWGLLOADDISPLAYCOLORTABLEEXTPROC) (const GLushort *table, GLuint length); -typedef GLboolean (WINAPI * PFNWGLBINDDISPLAYCOLORTABLEEXTPROC) (GLushort id); -typedef VOID (WINAPI * PFNWGLDESTROYDISPLAYCOLORTABLEEXTPROC) (GLushort id); -#endif - -#ifndef WGL_EXT_extensions_string -#define WGL_EXT_extensions_string 1 -#ifdef WGL_WGLEXT_PROTOTYPES -extern const char * WINAPI wglGetExtensionsStringEXT (void); -#endif /* WGL_WGLEXT_PROTOTYPES */ -typedef const char * (WINAPI * PFNWGLGETEXTENSIONSSTRINGEXTPROC) (void); -#endif - -#ifndef WGL_EXT_make_current_read -#define WGL_EXT_make_current_read 1 -#ifdef WGL_WGLEXT_PROTOTYPES -extern BOOL WINAPI wglMakeContextCurrentEXT (HDC, HDC, HGLRC); -extern HDC WINAPI wglGetCurrentReadDCEXT (void); -#endif /* WGL_WGLEXT_PROTOTYPES */ -typedef BOOL (WINAPI * PFNWGLMAKECONTEXTCURRENTEXTPROC) (HDC hDrawDC, HDC hReadDC, HGLRC hglrc); -typedef HDC (WINAPI * PFNWGLGETCURRENTREADDCEXTPROC) (void); -#endif - -#ifndef WGL_EXT_pbuffer -#define WGL_EXT_pbuffer 1 -#ifdef WGL_WGLEXT_PROTOTYPES -extern HPBUFFEREXT WINAPI wglCreatePbufferEXT (HDC, int, int, int, const int *); -extern HDC WINAPI wglGetPbufferDCEXT (HPBUFFEREXT); -extern int WINAPI wglReleasePbufferDCEXT (HPBUFFEREXT, HDC); -extern BOOL WINAPI wglDestroyPbufferEXT (HPBUFFEREXT); -extern BOOL WINAPI wglQueryPbufferEXT (HPBUFFEREXT, int, int *); -#endif /* WGL_WGLEXT_PROTOTYPES */ -typedef HPBUFFEREXT (WINAPI * PFNWGLCREATEPBUFFEREXTPROC) (HDC hDC, int iPixelFormat, int iWidth, int iHeight, const int *piAttribList); -typedef HDC (WINAPI * PFNWGLGETPBUFFERDCEXTPROC) (HPBUFFEREXT hPbuffer); -typedef int (WINAPI * PFNWGLRELEASEPBUFFERDCEXTPROC) (HPBUFFEREXT hPbuffer, HDC hDC); -typedef BOOL (WINAPI * PFNWGLDESTROYPBUFFEREXTPROC) (HPBUFFEREXT hPbuffer); -typedef BOOL (WINAPI * PFNWGLQUERYPBUFFEREXTPROC) (HPBUFFEREXT hPbuffer, int iAttribute, int *piValue); -#endif - -#ifndef WGL_EXT_pixel_format -#define WGL_EXT_pixel_format 1 -#ifdef WGL_WGLEXT_PROTOTYPES -extern BOOL WINAPI wglGetPixelFormatAttribivEXT (HDC, int, int, UINT, int *, int *); -extern BOOL WINAPI wglGetPixelFormatAttribfvEXT (HDC, int, int, UINT, int *, FLOAT *); -extern BOOL WINAPI wglChoosePixelFormatEXT (HDC, const int *, const FLOAT *, UINT, int *, UINT *); -#endif /* WGL_WGLEXT_PROTOTYPES */ -typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBIVEXTPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, int *piAttributes, int *piValues); -typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBFVEXTPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, int *piAttributes, FLOAT *pfValues); -typedef BOOL (WINAPI * PFNWGLCHOOSEPIXELFORMATEXTPROC) (HDC hdc, const int *piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats); -#endif - -#ifndef WGL_EXT_swap_control -#define WGL_EXT_swap_control 1 -#ifdef WGL_WGLEXT_PROTOTYPES -extern BOOL WINAPI wglSwapIntervalEXT (int); -extern int WINAPI wglGetSwapIntervalEXT (void); -#endif /* WGL_WGLEXT_PROTOTYPES */ -typedef BOOL (WINAPI * PFNWGLSWAPINTERVALEXTPROC) (int interval); -typedef int (WINAPI * PFNWGLGETSWAPINTERVALEXTPROC) (void); -#endif - -#ifndef WGL_WGL_EXT_depth_float -#define WGL_WGL_EXT_depth_float 1 -#endif - -#ifndef WGL_WGL_3DFX_multisample -#define WGL_WGL_3DFX_multisample 1 -#endif - -#ifndef WGL_WGL_EXT_multisample -#define WGL_WGL_EXT_multisample 1 -#endif - -/* added by Cass -- but this should already be in here! */ -#ifndef WGL_NV_allocate_memory -#define WGL_NV_allocate_memory 1 -#ifdef WGL_WGLEXT_PROTOTYPES -extern void * wglAllocateMemoryNV(int size, float readfreq, float writefreq, float priority); -extern void wglFreeMemoryNV(void * pointer); -#endif -typedef void * (APIENTRY * PFNWGLALLOCATEMEMORYNVPROC) (int size, float readfreq, float writefreq, float priority); -typedef void (APIENTRY * PFNWGLFREEMEMORYNVPROC) (void *pointer); -#endif - -// added from 3dlabs glext.h -/* - * Constants and typedefs for the WGL swap_frame_usage extension. - */ -typedef BOOL (APIENTRY *WGLGETFRAMEUSAGEI3DFUNCPTR)(float *); - - -/* - * Constants and typedefs for the WGL swap_frame_lock extension. - */ -typedef BOOL (APIENTRY *WGLENABLEFRAMELOCKI3DFUNCPTR)(VOID); -typedef BOOL (APIENTRY *WGLDISABLEFRAMELOCKI3DFUNCPTR)(VOID); -typedef BOOL (APIENTRY *WGLISENABLEDFRAMELOCKI3DFUNCPTR)(BOOL *); -typedef BOOL (APIENTRY *WGLQUERYFRAMELOCKMASTERI3DFUNCPTR)(BOOL *); - - -#ifdef __cplusplus -} -#endif - -#endif - - diff --git a/panda/src/windisplay/Sources.pp b/panda/src/windisplay/Sources.pp new file mode 100644 index 0000000000..31d86ea91c --- /dev/null +++ b/panda/src/windisplay/Sources.pp @@ -0,0 +1,29 @@ +#define BUILD_DIRECTORY $[WINDOWS_PLATFORM] + +#define OTHER_LIBS interrogatedb:c dconfig:c dtoolconfig:m \ + dtoolutil:c dtoolbase:c dtool:m +#define WIN_SYS_LIBS Imm32.lib +#define BUILDING_DLL BUILDING_PANDAWIN + +#begin lib_target + #define TARGET windisplay + #define LOCAL_LIBS \ + display putil + +// #define COMBINED_SOURCES $[TARGET]_composite1.cxx + + #define INSTALL_HEADERS \ + config_windisplay.h \ + winGraphicsPipe.I winGraphicsPipe.h \ + winGraphicsWindow.I winGraphicsWindow.h +// Win32Defs.h + + #define INCLUDED_SOURCES \ + config_windisplay.cxx winGraphicsPipe.cxx + + #define SOURCES \ + winGraphicsWindow.cxx $[INCLUDED_SOURCES] $[INSTALL_HEADERS] + + #define WIN_SYS_LIBS Imm32.lib winmm.lib kernel32.lib oldnames.lib user32.lib gdi32.lib + +#end lib_target diff --git a/panda/src/windisplay/config_windisplay.cxx b/panda/src/windisplay/config_windisplay.cxx new file mode 100644 index 0000000000..56eeeaaf20 --- /dev/null +++ b/panda/src/windisplay/config_windisplay.cxx @@ -0,0 +1,97 @@ +// Filename: config_windisplay.cxx +// Created by: drose (20Dec02) +// +//////////////////////////////////////////////////////////////////// +// +// 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 "config_windisplay.h" +#include "winGraphicsPipe.h" +#include "winGraphicsWindow.h" +#include "dconfig.h" + +Configure(config_windisplay); +NotifyCategoryDef(windisplay, "display"); + +ConfigureFn(config_windisplay) { + init_libwindisplay(); +} + +bool show_fps_meter = config_windisplay.GetBool("show-fps-meter", false); +float fps_meter_update_interval = max(0.5,config_windisplay.GetFloat("fps-meter-update-interval", 1.7)); + +bool responsive_minimized_fullscreen_window = config_windisplay.GetBool("responsive-minimized-fullscreen-window",false); + +// Set this true to not attempt to use any of the function calls that +// will crab out WireGL. +bool support_wiregl = config_windisplay.GetBool("support-wiregl", false); + +// if true, use ddraw's GetAvailVidMem to fail if driver says it has too little video mem +bool do_vidmemsize_check = config_windisplay.GetBool("do-vidmemsize-check", true); + +// For now, set this true to use the IME correctly on Win2000, or +// false on Win98. This is temporary; once we have been able to +// verify that this distinction is actually necessary, we can replace +// this config variable with an actual OS detection. +bool ime_composition_w = config_windisplay.GetBool("ime-composition-w", true); + +//////////////////////////////////////////////////////////////////// +// Function: init_libwindisplay +// Description: Initializes the library. This must be called at +// least once before any of the functions or classes in +// this library can be used. Normally it will be +// called by the static initializers and need not be +// called explicitly, but special cases exist. +//////////////////////////////////////////////////////////////////// +void +init_libwindisplay() { + static bool initialized = false; + if (initialized) { + return; + } + initialized = true; + + WinGraphicsPipe::init_type(); + WinGraphicsWindow::init_type(); +} + +// cant use global var cleanly because global var static init executed +// after init_libwin(), incorrectly reiniting var +Filename get_icon_filename() { + string iconname = config_windisplay.GetString("win32-window-icon",""); + return ExecutionEnvironment::expand_string(iconname); +} + +Filename get_color_cursor_filename() { + string cursorname = config_windisplay.GetString("win32-color-cursor",""); + return ExecutionEnvironment::expand_string(cursorname); +} + +Filename get_mono_cursor_filename() { + string cursorname = config_windisplay.GetString("win32-mono-cursor",""); + return ExecutionEnvironment::expand_string(cursorname); +} + + +// Configure this true to force the rendering to sync to the video +// refresh, or false to let your frame rate go as high as it can, +// irrespective of the video refresh. (if this capability is +// available in the ICD) +bool sync_video = config_windisplay.GetBool("sync-video", true); + +// Set this true to enable HW swapbuffer frame-lock on 3dlabs cards +bool swapbuffer_framelock = config_windisplay.GetBool("swapbuffer-framelock", false); + +bool force_software_renderer = config_windisplay.GetBool("force-software-renderer", false); +bool allow_software_renderer = config_windisplay.GetBool("allow-software-renderer", false); diff --git a/panda/src/wdxdisplay/config_wdxdisplay.h b/panda/src/windisplay/config_windisplay.h similarity index 53% rename from panda/src/wdxdisplay/config_wdxdisplay.h rename to panda/src/windisplay/config_windisplay.h index 373d13e7be..d3c7eed469 100644 --- a/panda/src/wdxdisplay/config_wdxdisplay.h +++ b/panda/src/windisplay/config_windisplay.h @@ -1,5 +1,5 @@ -// Filename: config_wdxdisplay.h -// Created by: mike (07Oct99) +// Filename: config_windisplay.h +// Created by: drose (20Dec02) // //////////////////////////////////////////////////////////////////// // @@ -16,24 +16,29 @@ // //////////////////////////////////////////////////////////////////// -#ifndef __CONFIG_WDXDISPLAY_H__ -#define __CONFIG_WDXDISPLAY_H__ +#ifndef CONFIG_WINDISPLAY_H +#define CONFIG_WINDISPLAY_H -#include -#include -#include +#include "pandabase.h" +#include "notifyCategoryProxy.h" -NotifyCategoryDecl(wdxdisplay, EXPCL_PANDADX, EXPTP_PANDADX); +NotifyCategoryDecl(windisplay, EXPCL_PANDAWIN, EXPTP_PANDAWIN); -extern bool bResponsive_minimized_fullscreen_window; -extern bool dx_force_16bpp_zbuffer; -extern bool dx_preserve_fpu_state; -extern bool dx_do_vidmemsize_check; extern Filename get_icon_filename(); -extern Filename get_mono_cursor_filename(); extern Filename get_color_cursor_filename(); +extern Filename get_mono_cursor_filename(); + +extern bool show_fps_meter; +extern float fps_meter_update_interval; +extern bool responsive_minimized_fullscreen_window; +extern bool do_vidmemsize_check; extern bool ime_composition_w; -extern EXPCL_PANDADX void init_libwdxdisplay(); +extern EXPCL_PANDAWIN bool sync_video; +extern EXPCL_PANDAWIN bool swapbuffer_framelock; +extern EXPCL_PANDAWIN bool force_software_renderer; +extern EXPCL_PANDAWIN bool allow_software_renderer; -#endif /* __CONFIG_WDXDISPLAY_H__ */ +extern EXPCL_PANDAWIN void init_libwindisplay(); + +#endif diff --git a/panda/src/windisplay/winGraphicsPipe.I b/panda/src/windisplay/winGraphicsPipe.I new file mode 100644 index 0000000000..62b7894688 --- /dev/null +++ b/panda/src/windisplay/winGraphicsPipe.I @@ -0,0 +1,17 @@ +// Filename: winGraphicsPipe.I +// Created by: drose (20Dec02) +// +//////////////////////////////////////////////////////////////////// +// +// 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 . +// +//////////////////////////////////////////////////////////////////// diff --git a/panda/src/windisplay/winGraphicsPipe.cxx b/panda/src/windisplay/winGraphicsPipe.cxx new file mode 100644 index 0000000000..318f62ed09 --- /dev/null +++ b/panda/src/windisplay/winGraphicsPipe.cxx @@ -0,0 +1,40 @@ +// Filename: winGraphicsPipe.cxx +// Created by: drose (20Dec02) +// +//////////////////////////////////////////////////////////////////// +// +// 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 "winGraphicsPipe.h" +#include "config_windisplay.h" + +TypeHandle WinGraphicsPipe::_type_handle; + +//////////////////////////////////////////////////////////////////// +// Function: WinGraphicsPipe::Constructor +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +WinGraphicsPipe:: +WinGraphicsPipe() { +} + +//////////////////////////////////////////////////////////////////// +// Function: WinGraphicsPipe::Destructor +// Access: Public, Virtual +// Description: +//////////////////////////////////////////////////////////////////// +WinGraphicsPipe:: +~WinGraphicsPipe() { +} diff --git a/panda/src/windisplay/winGraphicsPipe.h b/panda/src/windisplay/winGraphicsPipe.h new file mode 100644 index 0000000000..cb56c05f92 --- /dev/null +++ b/panda/src/windisplay/winGraphicsPipe.h @@ -0,0 +1,64 @@ +// Filename: winGraphicsPipe.h +// Created by: drose (20Dec02) +// +//////////////////////////////////////////////////////////////////// +// +// 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 WINGRAPHICSPIPE_H +#define WINGRAPHICSPIPE_H + +#include "pandabase.h" +#include "graphicsPipe.h" + +//////////////////////////////////////////////////////////////////// +// Class : WinGraphicsPipe +// Description : This is an abstract base class for wglGraphicsPipe +// and wdxGraphicsPipe; that is, those graphics pipes +// that are specialized for working with Microsoft +// Windows. +// +// There isn't much code here, since most of the fancy +// stuff is handled in WinGraphicsWindow. You could +// make a case that we don't even need a WinGraphicsPipe +// class at all, but it is provided mainly for +// completeness. +//////////////////////////////////////////////////////////////////// +class EXPCL_PANDAWIN WinGraphicsPipe : public GraphicsPipe { +public: + WinGraphicsPipe(); + virtual ~WinGraphicsPipe(); + + +public: + static TypeHandle get_class_type() { + return _type_handle; + } + static void init_type() { + GraphicsPipe::init_type(); + register_type(_type_handle, "WinGraphicsPipe", + GraphicsPipe::get_class_type()); + } + virtual TypeHandle get_type() const { + return get_class_type(); + } + virtual TypeHandle force_init_type() {init_type(); return get_class_type();} + +private: + static TypeHandle _type_handle; +}; + +#include "winGraphicsPipe.I" + +#endif diff --git a/panda/src/windisplay/winGraphicsWindow.I b/panda/src/windisplay/winGraphicsWindow.I new file mode 100644 index 0000000000..335db1421e --- /dev/null +++ b/panda/src/windisplay/winGraphicsWindow.I @@ -0,0 +1,115 @@ +// Filename: winGraphicsWindow.I +// Created by: drose (20Dec02) +// +//////////////////////////////////////////////////////////////////// +// +// 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: WinGraphicsWindow::handle_mouse_motion +// Access: Private +// Description: +//////////////////////////////////////////////////////////////////// +INLINE void WinGraphicsWindow:: +handle_mouse_motion(int x, int y) { + _input_devices[0].set_pointer_in_window(x, y); +} + +//////////////////////////////////////////////////////////////////// +// Function: WinGraphicsWindow::handle_mouse_exit +// Access: Private +// Description: +//////////////////////////////////////////////////////////////////// +INLINE void WinGraphicsWindow:: +handle_mouse_exit() { + // note: 'mouse_motion' is considered the 'entry' event + _input_devices[0].set_pointer_out_of_window(); +} + +//////////////////////////////////////////////////////////////////// +// Function: WinGraphicsWindow::handle_keypress +// Access: Private +// Description: +//////////////////////////////////////////////////////////////////// +INLINE void WinGraphicsWindow:: +handle_keypress(ButtonHandle key, int x, int y) { + _input_devices[0].set_pointer_in_window(x, y); + if (key != ButtonHandle::none()) { + _input_devices[0].button_down(key); + } +} + +//////////////////////////////////////////////////////////////////// +// Function: WinGraphicsWindow::handle_keyrelease +// Access: Private +// Description: +//////////////////////////////////////////////////////////////////// +INLINE void WinGraphicsWindow:: +handle_keyrelease(ButtonHandle key) { + _input_devices[0].button_up(key); +} + +//////////////////////////////////////////////////////////////////// +// Function: WinGraphicsWindow::translate_mouse +// Access: Private +// Description: Translates the mouse pixel coordinate (either x or y) +// as returned by the Windows message to the signed +// number expected by Panda. +//////////////////////////////////////////////////////////////////// +INLINE int WinGraphicsWindow:: +translate_mouse(int pos) const { + if (pos & 0x8000) { + pos -= 0x10000; + } + return pos; +} + +//////////////////////////////////////////////////////////////////// +// Function: WinGraphicsWindow::set_cursor_in_window +// Access: Private +// Description: Called during the window thread in response to the +// various Windows messages to indicate whether we +// believe the mouse is presently within the window's +// client rectangle or not. This in turn will determine +// whether we should call update_cursor_window() to hide +// or show the cursor (or otherwise change its +// properties) as it moves between the various +// GraphicsWindows that we control. +//////////////////////////////////////////////////////////////////// +INLINE void WinGraphicsWindow:: +set_cursor_in_window() { + if (_cursor_window != this) { + update_cursor_window(this); + } +} + +//////////////////////////////////////////////////////////////////// +// Function: WinGraphicsWindow::set_cursor_out_of_window +// Access: Private +// Description: Called during the window thread in response to the +// various Windows messages to indicate whether we +// believe the mouse is presently within the window's +// client rectangle or not. This in turn will determine +// whether we should call update_cursor_window() to hide +// or show the cursor (or otherwise change its +// properties) as it moves between the various +// GraphicsWindows that we control. +//////////////////////////////////////////////////////////////////// +INLINE void WinGraphicsWindow:: +set_cursor_out_of_window() { + if (_cursor_window == this) { + update_cursor_window(NULL); + } +} diff --git a/panda/src/windisplay/winGraphicsWindow.cxx b/panda/src/windisplay/winGraphicsWindow.cxx new file mode 100644 index 0000000000..d10dc6746a --- /dev/null +++ b/panda/src/windisplay/winGraphicsWindow.cxx @@ -0,0 +1,1312 @@ +// Filename: winGraphicsWindow.cxx +// Created by: drose (20Dec02) +// +//////////////////////////////////////////////////////////////////// +// +// 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 "winGraphicsWindow.h" +#include "config_windisplay.h" +#include "winGraphicsPipe.h" + +#include "graphicsPipe.h" +#include "keyboardButton.h" +#include "mouseButton.h" +#include "clockObject.h" + +#include + +TypeHandle WinGraphicsWindow::_type_handle; + +bool WinGraphicsWindow::_got_dynamic_fns = false; +WinGraphicsWindow::PFN_TRACKMOUSEEVENT WinGraphicsWindow::_pfnTrackMouseEvent = NULL; + +bool WinGraphicsWindow::_loaded_custom_cursor; +HCURSOR WinGraphicsWindow::_mouse_cursor; +const char * const WinGraphicsWindow::_window_class_name = "WinGraphicsWindow"; +bool WinGraphicsWindow::_window_class_registered = false; + +WinGraphicsWindow::WindowHandles WinGraphicsWindow::_window_handles; +WinGraphicsWindow *WinGraphicsWindow::_creating_window = NULL; + +WinGraphicsWindow *WinGraphicsWindow::_cursor_window = NULL; +bool WinGraphicsWindow::_cursor_hidden = false; + +// These are used to save the previous state of the fancy Win2000 +// effects that interfere with rendering when the mouse wanders into a +// window's client area. +bool WinGraphicsWindow::_got_saved_params = false; +int WinGraphicsWindow::_saved_mouse_trails; +bool WinGraphicsWindow::_saved_cursor_shadow; +bool WinGraphicsWindow::_saved_mouse_vanish; + +static const char * const errorbox_title = "Panda3D Error"; + + +// because we dont have access to ModifierButtons, as a hack just +// synchronize state of these keys on get/lose keybd focus +#define NUM_MODIFIER_KEYS 16 +static unsigned int hardcoded_modifier_buttons[NUM_MODIFIER_KEYS] = { + VK_SHIFT, VK_MENU, VK_CONTROL, VK_SPACE, VK_TAB, + VK_UP, VK_DOWN, VK_LEFT, VK_RIGHT, VK_PRIOR, VK_NEXT, VK_HOME, VK_END, + VK_INSERT, VK_DELETE, VK_ESCAPE +}; + +//////////////////////////////////////////////////////////////////// +// Function: WinGraphicsWindow::Constructor +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +WinGraphicsWindow:: +WinGraphicsWindow(GraphicsPipe *pipe) : + GraphicsWindow(pipe) +{ + GraphicsWindowInputDevice device = + GraphicsWindowInputDevice::pointer_and_keyboard("keyboard/mouse"); + _input_devices.push_back(device); + _mwindow = (HWND)0; + _ime_open = false; + _ime_active = false; + _ime_composition_w = false; + _tracking_mouse_leaving = false; + _maximized = false; + + if (!_got_dynamic_fns) { + // these fns arent defined on win95, so get dynamic ptrs to them + // to avoid ugly DLL loader failures on w95 + HINSTANCE hUser32 = (HINSTANCE)LoadLibrary("user32.dll"); + if (hUser32) { + _pfnTrackMouseEvent = + (PFN_TRACKMOUSEEVENT)GetProcAddress(hUser32, "TrackMouseEvent"); + FreeLibrary(hUser32); + } + + _got_dynamic_fns = true; + } +} + +//////////////////////////////////////////////////////////////////// +// Function: WinGraphicsWindow::Destructor +// Access: Public, Virtual +// Description: +//////////////////////////////////////////////////////////////////// +WinGraphicsWindow:: +~WinGraphicsWindow() { +} + +//////////////////////////////////////////////////////////////////// +// Function: WinGraphicsWindow::begin_flip +// Access: Public, Virtual +// Description: This function will be called within the draw thread +// after end_frame() has been called on all windows, to +// initiate the exchange of the front and back buffers. +// +// This should instruct the window to prepare for the +// flip at the next video sync, but it should not wait. +// +// We have the two separate functions, begin_flip() and +// end_flip(), to make it easier to flip all of the +// windows at the same time. +//////////////////////////////////////////////////////////////////// +void WinGraphicsWindow:: +begin_flip() { +} + +//////////////////////////////////////////////////////////////////// +// Function: WinGraphicsWindow::process_events +// Access: Public, Virtual +// Description: Do whatever processing is necessary to ensure that +// the window responds to user events. Also, honor any +// requests recently made via request_properties() +// +// This function is called only within the window +// thread. +//////////////////////////////////////////////////////////////////// +void WinGraphicsWindow:: +process_events() { + GraphicsWindow::process_events(); + + // We can't treat the message loop specially just because the window + // is minimized, because we might be reading messages queued up for + // some other window, which is not minimized. + /* + if (!_window_active) { + // Get 1 msg at a time until no more are left and we block and sleep, + // or message changes _return_control_to_app or !_window_active status + + while(!_window_active && (!_return_control_to_app)) { + process_1_event(); + } + _return_control_to_app = false; + + } else + */ + + MSG msg; + + // Handle all the messages on the queue in a row. Some of these + // might be for another window, but they will get dispatched + // appropriately. + while (PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE)) { + process_1_event(); + } +} +//////////////////////////////////////////////////////////////////// +// Function: WinGraphicsWindow::set_properties_now +// Access: Public, Virtual +// Description: Applies the requested set of properties to the +// window, if possible, for instance to request a change +// in size or minimization status. +// +// The window properties are applied immediately, rather +// than waiting until the next frame. This implies that +// this method may *only* be called from within the +// window thread. +// +// The properties that have been applied are cleared +// from the structure by this function; so on return, +// whatever remains in the properties structure are +// those that were unchanged for some reason (probably +// because the underlying interface does not support +// changing that property on an open window). +//////////////////////////////////////////////////////////////////// +void WinGraphicsWindow:: +set_properties_now(WindowProperties &properties) { + GraphicsWindow::set_properties_now(properties); + if (!properties.is_any_specified()) { + // The base class has already handled this case. + return; + } +} + +//////////////////////////////////////////////////////////////////// +// Function: WinGraphicsWindow::close_window +// Access: Protected, Virtual +// Description: Closes the window right now. Called from the window +// thread. +//////////////////////////////////////////////////////////////////// +void WinGraphicsWindow:: +close_window() { + set_cursor_out_of_window(); + DestroyWindow(_mwindow); + + // Remove the window handle from our global map. + _window_handles.erase(_mwindow); + _mwindow = (HWND)0; + + if (is_fullscreen()) { + // revert to default display mode. + ChangeDisplaySettings(NULL, 0x0); + } +} + +//////////////////////////////////////////////////////////////////// +// Function: WinGraphicsWindow::open_window +// Access: Protected, Virtual +// Description: Opens the window right now. Called from the window +// thread. Returns true if the window is successfully +// opened, or false if there was a problem. +//////////////////////////////////////////////////////////////////// +bool WinGraphicsWindow:: +open_window() { + // Store the current window pointer in _creating_window, so we can + // call CreateWindow() and know which window it is sending events to + // even before it gives us a handle. Warning: this is not thread + // safe! + _creating_window = this; + bool opened; + if (is_fullscreen()) { + opened = open_fullscreen_window(); + } else { + opened = open_regular_window(); + } + _creating_window = (WinGraphicsWindow *)NULL; + + if (!opened) { + return false; + } + + // Now that we have a window handle, store it in our global map, so + // future messages for this window can be routed properly. + _window_handles.insert(WindowHandles::value_type(_mwindow, this)); + + // move window to top of zorder. + SetWindowPos(_mwindow, HWND_TOP, 0,0,0,0, + SWP_NOMOVE | SWP_NOSENDCHANGING | SWP_NOSIZE); + + // need to do twice to override any minimized flags in StartProcessInfo + ShowWindow(_mwindow, SW_SHOWNORMAL); + ShowWindow(_mwindow, SW_SHOWNORMAL); + + if (!SetForegroundWindow(_mwindow)) { + windisplay_cat.warning() + << "SetForegroundWindow() failed!\n"; + } + + // Determine the initial open status of the IME. + _ime_open = false; + _ime_active = false; + HIMC hIMC = ImmGetContext(_mwindow); + if (hIMC != 0) { + _ime_open = (ImmGetOpenStatus(hIMC) != 0); + ImmReleaseContext(_mwindow, hIMC); + } + + // Check the version of the OS we are running. If we are running + // win2000, we must use ImmGetCompositionStringW() to report the + // characters returned by the IME, since WM_CHAR and + // ImmGetCompositionStringA() both just return question marks. + // However, this function doesn't work for Win98; on this OS, we + // have to use ImmGetCompositionStringA() instead, which returns an + // encoded string in shift-jis (which we then have to decode). + + // For now, this is user-configurable, to allow testing of this code + // on both OS's. After we verify that truth of the above claim, we + // should base this decision on GetVersionEx() or maybe + // VerifyVersionInfo(). + _ime_composition_w = ime_composition_w; + + // need to re-evaluate above in light of this, it seems that + // ImmGetCompositionStringW should work on both: + // The Input Method Editor and Unicode Windows 98/Me, Windows + // NT/2000/XP: Windows supports a Unicode interface for the + // IME, in addition to the ANSI interface originally supported. + // Windows 98/Me supports all the Unicode functions except + // ImmIsUIMessage. Also, all the messages in Windows 98/Me are + // ANSI based. Since Windows 98/Me does not support Unicode + // messages, applications can use ImmGetCompositionString to + // receive Unicode characters from a Unicode based IME on + // Windows 98/Me. There are two issues involved with Unicode + // handling and the IME. One is that the Unicode versions of + // IME routines return the size of a buffer in bytes rather + // than 16-bit Unicode characters,and the other is the IME + // normally returns Unicode characters (rather than DBCS) in + // the WM_CHAR and WM_IME_CHAR messages. Use RegisterClassW + // to cause the WM_CHAR and WM_IME_CHAR messages to return + // Unicode characters in the wParam parameter rather than DBCS + // characters. This is only available under Windows NT; it is + // stubbed out in Windows 95/98/Me. + + return true; +} + +//////////////////////////////////////////////////////////////////// +// Function: WinGraphicsWindow::fullscreen_minimized +// Access: Protected, Virtual +// Description: This is a hook for derived classes to do something +// special, if necessary, when a fullscreen window has +// been minimized. The given WindowProperties struct +// will be applied to this window's properties after +// this function returns. +//////////////////////////////////////////////////////////////////// +void WinGraphicsWindow:: +fullscreen_minimized(WindowProperties &) { +} + +//////////////////////////////////////////////////////////////////// +// Function: WinGraphicsWindow::fullscreen_restored +// Access: Protected, Virtual +// Description: This is a hook for derived classes to do something +// special, if necessary, when a fullscreen window has +// been restored after being minimized. The given +// WindowProperties struct will be applied to this +// window's properties after this function returns. +//////////////////////////////////////////////////////////////////// +void WinGraphicsWindow:: +fullscreen_restored(WindowProperties &) { +} + +//////////////////////////////////////////////////////////////////// +// Function: WinGraphicsWindow::open_window +// Access: Protected, Virtual +// Description: Called from the window thread in response to a request +// from within the code (via request_properties()) to +// change the size and/or position of the window. +// Returns true if the window is successfully changed, +// or false if there was a problem. +//////////////////////////////////////////////////////////////////// +bool WinGraphicsWindow:: +do_reshape_request(int x_origin, int y_origin, int x_size, int y_size) { + if (!is_fullscreen()) { + // Compute the appropriate size and placement for the window, + // including decorations. + RECT view_rect; + SetRect(&view_rect, x_origin, y_origin, + x_origin + x_size, y_origin + y_size); + WINDOWINFO wi; + GetWindowInfo(_mwindow, &wi); + AdjustWindowRectEx(&view_rect, wi.dwStyle, false, wi.dwExStyle); + + SetWindowPos(_mwindow, NULL, view_rect.left, view_rect.top, + view_rect.right - view_rect.left, + view_rect.bottom - view_rect.top, + SWP_NOZORDER | SWP_NOMOVE | SWP_NOSENDCHANGING); + + // This isn't quite right, because handle_reshape() calls + // system_changed_properties(), generating the event indicating + // the window has changed size externally--even though it changed + // due to an internal request. + handle_reshape(); + return true; + } + + // Resizing a fullscreen window is a little trickier. + return do_fullscreen_resize(x_size, y_size); +} + +//////////////////////////////////////////////////////////////////// +// Function: WinGraphicsWindow::handle_reshape +// Access: Protected, Virtual +// Description: Called in the window thread when the window size or +// location is changed, this updates the properties +// structure accordingly. +//////////////////////////////////////////////////////////////////// +void WinGraphicsWindow:: +handle_reshape() { + RECT view_rect; + GetClientRect(_mwindow, &view_rect); + ClientToScreen(_mwindow, (POINT*)&view_rect.left); // translates top,left pnt + ClientToScreen(_mwindow, (POINT*)&view_rect.right); // translates right,bottom pnt + + WindowProperties properties; + properties.set_size((view_rect.right - view_rect.left), + (view_rect.bottom - view_rect.top)); + + // _props origin should reflect upper left of view rectangle + properties.set_origin(view_rect.left, view_rect.top); + + if (windisplay_cat.is_spam()) { + windisplay_cat.spam() + << "reshape to origin: (" << properties.get_x_origin() << "," + << properties.get_y_origin() << "), size: (" << properties.get_x_size() + << "," << properties.get_y_size() << ")\n"; + } + + system_changed_properties(properties); +} + +//////////////////////////////////////////////////////////////////// +// Function: WinGraphicsWindow::do_fullscreen_resize +// Access: Protected, Virtual +// Description: Called in the window thread to resize a fullscreen +// window. +//////////////////////////////////////////////////////////////////// +bool WinGraphicsWindow:: +do_fullscreen_resize(int x_size, int y_size) { + return false; +} + +//////////////////////////////////////////////////////////////////// +// Function: WinGraphicsWindow::get_client_rect_screen +// Access: Protected +// Description: Fills view_rect with the coordinates of the client +// area of the indicated window, converted to screen +// coordinates. +//////////////////////////////////////////////////////////////////// +void WinGraphicsWindow:: +get_client_rect_screen(HWND hwnd, RECT *view_rect) { + GetClientRect(hwnd, view_rect); + + POINT ul, lr; + ul.x = view_rect->left; + ul.y = view_rect->top; + lr.x = view_rect->right; + lr.y = view_rect->bottom; + + ClientToScreen(hwnd, &ul); + ClientToScreen(hwnd, &lr); + + view_rect->left = ul.x; + view_rect->top = ul.y; + view_rect->right = lr.x; + view_rect->bottom = lr.y; +} + +//////////////////////////////////////////////////////////////////// +// Function: WinGraphicsWindow::open_fullscreen_window +// Access: Private +// Description: Creates a fullscreen-style window. +//////////////////////////////////////////////////////////////////// +bool WinGraphicsWindow:: +open_fullscreen_window() { + // from MSDN: + // An OpenGL window has its own pixel format. Because of this, only + // device contexts retrieved for the client area of an OpenGL + // window are allowed to draw into the window. As a result, an + // OpenGL window should be created with the WS_CLIPCHILDREN and + // WS_CLIPSIBLINGS styles. Additionally, the window class attribute + // should not include the CS_PARENTDC style. + DWORD window_style = + WS_POPUP | WS_SYSMENU | WS_CLIPCHILDREN | WS_CLIPSIBLINGS; + + if (!_properties.has_size()) { + // Just pick a stupid default size if one isn't specified. + _properties.set_size(640, 480); + } + + DWORD dwWidth = _properties.get_x_size(); + DWORD dwHeight = _properties.get_y_size(); + + HWND hDesktopWindow = GetDesktopWindow(); + HDC scrnDC = GetDC(hDesktopWindow); + DWORD cur_bitdepth = GetDeviceCaps(scrnDC, BITSPIXEL); + // DWORD drvr_ver = GetDeviceCaps(scrnDC, DRIVERVERSION); + // DWORD cur_scrnwidth = GetDeviceCaps(scrnDC, HORZRES); + // DWORD cur_scrnheight = GetDeviceCaps(scrnDC, VERTRES); + ReleaseDC(hDesktopWindow, scrnDC); + + DWORD dwFullScreenBitDepth = cur_bitdepth; + + if (!find_acceptable_display_mode(dwWidth, dwHeight, dwFullScreenBitDepth, + _fullscreen_display_mode)) { + windisplay_cat.error() + << "Videocard has no supported display resolutions at specified res (" + << dwWidth << " x " << dwHeight << " x " << dwFullScreenBitDepth <<")\n"; + return false; + } + + string title; + if (_properties.has_title()) { + title = _properties.get_title(); + } + + // I'd prefer to CreateWindow after DisplayChange in case it messes + // up GL somehow, but I need the window's black background to cover + // up the desktop during the mode change + register_window_class(); + HINSTANCE hinstance = GetModuleHandle(NULL); + _mwindow = CreateWindow(_window_class_name, title.c_str(), window_style, + 0, 0, dwWidth, dwHeight, + hDesktopWindow, NULL, hinstance, 0); + if (!_mwindow) { + windisplay_cat.error() + << "CreateWindow() failed!" << endl; + show_error_message(); + return false; + } + + int chg_result = ChangeDisplaySettings(&_fullscreen_display_mode, CDS_FULLSCREEN); + if (chg_result != DISP_CHANGE_SUCCESSFUL) { + windisplay_cat.error() + << "ChangeDisplaySettings failed (error code: " + << chg_result << ") for specified res (" << dwWidth + << " x " << dwHeight << " x " << dwFullScreenBitDepth + << "), " << _fullscreen_display_mode.dmDisplayFrequency << "Hz\n"; + return false; + } + + _properties.set_origin(0, 0); + _properties.set_size(dwWidth, dwHeight); + return true; +} + +//////////////////////////////////////////////////////////////////// +// Function: WinGraphicsWindow::open_regular_window +// Access: Private +// Description: Creates a non-fullscreen window, on the desktop. +//////////////////////////////////////////////////////////////////// +bool WinGraphicsWindow:: +open_regular_window() { + // from MSDN: + // An OpenGL window has its own pixel format. Because of this, only + // device contexts retrieved for the client area of an OpenGL + // window are allowed to draw into the window. As a result, an + // OpenGL window should be created with the WS_CLIPCHILDREN and + // WS_CLIPSIBLINGS styles. Additionally, the window class attribute + // should not include the CS_PARENTDC style. + DWORD window_style = + WS_POPUP | WS_SYSMENU | WS_CLIPCHILDREN | WS_CLIPSIBLINGS; + + if (!_properties.has_undecorated() || !_properties.get_undecorated()) { + window_style |= WS_OVERLAPPEDWINDOW; + } + + if (!_properties.has_origin()) { + _properties.set_origin(0, 0); + } + if (!_properties.has_size()) { + _properties.set_size(100, 100); + } + + RECT win_rect; + SetRect(&win_rect, + _properties.get_x_origin(), + _properties.get_y_origin(), + _properties.get_x_origin() + _properties.get_x_size(), + _properties.get_y_origin() + _properties.get_y_size()); + + // compute window size based on desired client area size + if (!AdjustWindowRect(&win_rect, window_style, FALSE)) { + windisplay_cat.error() + << "AdjustWindowRect failed!" << endl; + return false; + } + + // make sure origin is on screen; slide far bounds over if necessary + if (win_rect.left < 0) { + win_rect.right += abs(win_rect.left); + win_rect.left = 0; + } + if (win_rect.top < 0) { + win_rect.bottom += abs(win_rect.top); + win_rect.top = 0; + } + + string title; + if (_properties.has_title()) { + title = _properties.get_title(); + } + + register_window_class(); + HINSTANCE hinstance = GetModuleHandle(NULL); + _mwindow = CreateWindow(_window_class_name, title.c_str(), window_style, + win_rect.left, win_rect.top, + win_rect.right - win_rect.left, + win_rect.bottom - win_rect.top, + NULL, NULL, hinstance, 0); + + if (!_mwindow) { + windisplay_cat.error() + << "CreateWindow() failed!" << endl; + show_error_message(); + return false; + } + + return true; +} + +//////////////////////////////////////////////////////////////////// +// Function: WinGraphicsWindow::track_mouse_leaving +// Access: Private +// Description: Intended to be called whenever mouse motion is +// detected within the window, this indicates that the +// mouse is within the window and tells Windows that we +// want to be told when the mouse leaves the window. +//////////////////////////////////////////////////////////////////// +void WinGraphicsWindow:: +track_mouse_leaving(HWND hwnd) { + // Note: could use _TrackMouseEvent in comctrl32.dll (part of IE + // 3.0+) which emulates TrackMouseEvent on w95, but that requires + // another 500K of memory to hold that DLL, which is lame just to + // support w95, which probably has other issues anyway + if (_pfnTrackMouseEvent != NULL) { + TRACKMOUSEEVENT tme = { + sizeof(TRACKMOUSEEVENT), + TME_LEAVE, + hwnd, + 0 + }; + + // tell win32 to post WM_MOUSELEAVE msgs + BOOL bSucceeded = _pfnTrackMouseEvent(&tme); + + if ((!bSucceeded) && windisplay_cat.is_debug()) { + windisplay_cat.debug() + << "TrackMouseEvent failed!, LastError=" << GetLastError() << endl; + } + + _tracking_mouse_leaving = true; + } +} + +//////////////////////////////////////////////////////////////////// +// Function: WinGraphicsWindow::window_proc +// Access: Private +// Description: This is the nonstatic window_proc function. It is +// called to handle window events for this particular +// window. +//////////////////////////////////////////////////////////////////// +LONG WinGraphicsWindow:: +window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) { + /* + cerr << ClockObject::get_global_clock()->get_real_time() + << " window_proc(" << (void *)this << ", " << hwnd << ", " + << msg << ", " << wparam << ", " << lparam << ")\n"; + */ + WindowProperties properties; + int button = -1; + + switch (msg) { + case WM_MOUSEMOVE: + if (!_tracking_mouse_leaving) { + // need to re-call TrackMouseEvent every time mouse re-enters window + track_mouse_leaving(hwnd); + } + set_cursor_in_window(); + handle_mouse_motion(translate_mouse(LOWORD(lparam)), + translate_mouse(HIWORD(lparam))); + break; + + case WM_MOUSELEAVE: + _tracking_mouse_leaving = false; + handle_mouse_exit(); + set_cursor_out_of_window(); + break; + + case WM_CREATE: + track_mouse_leaving(hwnd); + + // Assume the mouse cursor is within the window initially. It + // remains to be seen whether this is assumption does any harm. + set_cursor_in_window(); + break; + + case WM_CLOSE: + properties.set_open(false); + system_changed_properties(properties); + + // TODO: make sure we release the GSG properly. + break; + + case WM_ACTIVATE: + properties.set_minimized((wparam & 0xffff0000) != 0); + if ((wparam & 0xffff) != WA_INACTIVE) { + properties.set_foreground(true); + if (is_fullscreen()) { + // When a fullscreen window goes active, it automatically gets + // un-minimized. + ChangeDisplaySettings(&_fullscreen_display_mode, CDS_FULLSCREEN); + GdiFlush(); + SetWindowPos(_mwindow, HWND_TOP, 0,0,0,0, + SWP_NOMOVE | SWP_NOSENDCHANGING | SWP_NOSIZE | SWP_NOOWNERZORDER); + fullscreen_restored(properties); + } + } else { + properties.set_foreground(false); + if (is_fullscreen()) { + // When a fullscreen window goes inactive, it automatically + // gets minimized. + properties.set_minimized(true); + + // It seems order is important here. We must minimize the + // window before restoring the display settings, or risk + // losing the graphics context. + ShowWindow(_mwindow, SW_MINIMIZE); + GdiFlush(); + ChangeDisplaySettings(NULL, 0x0); + fullscreen_minimized(properties); + } + } + system_changed_properties(properties); + break; + + case WM_SIZE: + // for maximized, unmaximize, need to call resize code + // artificially since no WM_EXITSIZEMOVE is generated. + if (wparam == SIZE_MAXIMIZED) { + _maximized = true; + handle_reshape(); + + } else if (wparam == SIZE_RESTORED && _maximized) { + // SIZE_RESTORED might mean we restored to its original size + // before the maximize, but it might also be called while the + // user is resizing the window by hand. Checking the _maximized + // flag that we set above allows us to differentiate the two + // cases. + _maximized = false; + handle_reshape(); + } + break; + + case WM_EXITSIZEMOVE: + handle_reshape(); + break; + + case WM_LBUTTONDOWN: + button = 0; + // fall through + case WM_MBUTTONDOWN: + if (button < 0) { + button = 1; + } + // fall through + case WM_RBUTTONDOWN: + if (button < 0) { + button = 2; + } + SetCapture(hwnd); + handle_keypress(MouseButton::button(button), + translate_mouse(LOWORD(lparam)), translate_mouse(HIWORD(lparam))); + break; + + case WM_LBUTTONUP: + button = 0; + // fall through + case WM_MBUTTONUP: + if (button < 0) { + button = 1; + } + // fall through + case WM_RBUTTONUP: + if (button < 0) { + button = 2; + } + ReleaseCapture(); + handle_keyrelease(MouseButton::button(button)); + break; + + case WM_IME_NOTIFY: + if (wparam == IMN_SETOPENSTATUS) { + HIMC hIMC = ImmGetContext(hwnd); + nassertr(hIMC != 0, 0); + _ime_open = (ImmGetOpenStatus(hIMC) != 0); + if (!_ime_open) { + _ime_active = false; // Sanity enforcement. + } + ImmReleaseContext(hwnd, hIMC); + } + break; + + case WM_IME_STARTCOMPOSITION: + _ime_active = true; + break; + + case WM_IME_ENDCOMPOSITION: + _ime_active = false; + break; + + case WM_IME_COMPOSITION: + if (lparam & GCS_RESULTSTR) { + HIMC hIMC = ImmGetContext(hwnd); + nassertr(hIMC != 0, 0); + + static const int max_ime_result = 128; + static char ime_result[max_ime_result]; + + if (_ime_composition_w) { + // Since ImmGetCompositionStringA() doesn't seem to work + // for Win2000 (it always returns question mark + // characters), we have to use ImmGetCompositionStringW() + // on this OS. This is actually the easier of the two + // functions to use. + + DWORD result_size = + ImmGetCompositionStringW(hIMC, GCS_RESULTSTR, + ime_result, max_ime_result); + + // Add this string into the text buffer of the application. + + // ImmGetCompositionStringW() returns a string, but it's + // filled in with wstring data: every two characters defines a + // 16-bit unicode char. The docs aren't clear on the + // endianness of this. I guess it's safe to assume all Win32 + // machines are little-endian. + for (DWORD i = 0; i < result_size; i += 2) { + int result = + ((int)(unsigned char)ime_result[i + 1] << 8) | + (unsigned char)ime_result[i]; + _input_devices[0].keystroke(result); + } + } else { + // On the other hand, ImmGetCompositionStringW() doesn't + // work on Win95 or Win98; for these OS's we must use + // ImmGetCompositionStringA(). + DWORD result_size = + ImmGetCompositionStringA(hIMC, GCS_RESULTSTR, + ime_result, max_ime_result); + + // ImmGetCompositionStringA() returns an encoded ANSI + // string, which we now have to map to wide-character + // Unicode. + static const int max_wide_result = 128; + static wchar_t wide_result[max_wide_result]; + + int wide_size = + MultiByteToWideChar(CP_ACP, 0, + ime_result, result_size, + wide_result, max_wide_result); + if (wide_size == 0) { + show_error_message(); + } + for (int i = 0; i < wide_size; i++) { + _input_devices[0].keystroke(wide_result[i]); + } + } + + ImmReleaseContext(hwnd, hIMC); + return 0; + } + break; + + case WM_CHAR: + // Ignore WM_CHAR messages if we have the IME open, since + // everything will come in through WM_IME_COMPOSITION. (It's + // supposed to come in through WM_CHAR, too, but there seems to + // be a bug in Win2000 in that it only sends question mark + // characters through here.) + if (!_ime_open) { + _input_devices[0].keystroke(wparam); + } + break; + + case WM_SYSKEYDOWN: + { + // Alt and F10 are sent as WM_SYSKEYDOWN instead of WM_KEYDOWN + // want to use defwindproc on Alt syskey so std windows cmd + // Alt-F4 works, etc + POINT point; + GetCursorPos(&point); + ScreenToClient(hwnd, &point); + handle_keypress(lookup_key(wparam), point.x, point.y); + if (wparam == VK_F10) { + // bypass default windproc F10 behavior (it activates the main + // menu, but we have none) + return 0; + } + } + break; + + case WM_SYSCOMMAND: + if (wparam == SC_KEYMENU) { + // if Alt is released (alone w/o other keys), defwindproc will + // send this command, which will 'activate' the title bar menu + // (we have none) and give focus to it. we dont want this to + // happen, so kill this msg + return 0; + } + break; + + case WM_KEYDOWN: + { + POINT point; + + GetCursorPos(&point); + ScreenToClient(hwnd, &point); + handle_keypress(lookup_key(wparam), point.x, point.y); + + // Handle Cntrl-V paste from clipboard. Is there a better way + // to detect this hotkey? + if ((wparam=='V') && (GetKeyState(VK_CONTROL) < 0) && + !_input_devices.empty()) { + HGLOBAL hglb; + char *lptstr; + + if (IsClipboardFormatAvailable(CF_TEXT) && OpenClipboard(NULL)) { + // Maybe we should support CF_UNICODETEXT if it is available + // too? + hglb = GetClipboardData(CF_TEXT); + if (hglb!=NULL) { + lptstr = (char *) GlobalLock(hglb); + if (lptstr != NULL) { + char *pChar; + for (pChar=lptstr; *pChar!=NULL; pChar++) { + _input_devices[0].keystroke((uchar)*pChar); + } + GlobalUnlock(hglb); + } + } + CloseClipboard(); + } + } + } + break; + + case WM_SYSKEYUP: + case WM_KEYUP: + handle_keyrelease(lookup_key(wparam)); + break; + + case WM_SETFOCUS: + { + POINT point; + GetCursorPos(&point); + ScreenToClient(hwnd, &point); + + // this is a hack to make sure common modifier keys have proper + // state since at focus loss, app may never receive key-up event + // corresponding to a key-down. it would be better to know the + // exact set of ModifierButtons the user is using, since we may + // miss some here + int i; + for (i=0; i < NUM_MODIFIER_KEYS; i++) { + if (GetKeyState(hardcoded_modifier_buttons[i]) < 0) { + handle_keypress(lookup_key(hardcoded_modifier_buttons[i]), + point.x, point.y); + } + } + } + return 0; + + case WM_KILLFOCUS: + { + int i; + for (i=0; i < NUM_MODIFIER_KEYS; i++) { + if (GetKeyState(hardcoded_modifier_buttons[i]) < 0) { + handle_keyrelease(lookup_key(hardcoded_modifier_buttons[i])); + } + } + } + return 0; + } + + return DefWindowProc(hwnd, msg, wparam, lparam); +} + +//////////////////////////////////////////////////////////////////// +// Function: WinGraphicsWindow::static_window_proc +// Access: Private, Static +// Description: This is attached to the window class for all +// WinGraphicsWindow windows; it is called to handle +// window events. +//////////////////////////////////////////////////////////////////// +LONG WINAPI WinGraphicsWindow:: +static_window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) { + // Look up the window in our global map. + WindowHandles::const_iterator wi; + wi = _window_handles.find(hwnd); + if (wi != _window_handles.end()) { + // We found the window. + return (*wi).second->window_proc(hwnd, msg, wparam, lparam); + } + + // The window wasn't in the map; we must be creating it right now. + if (_creating_window != (WinGraphicsWindow *)NULL) { + return _creating_window->window_proc(hwnd, msg, wparam, lparam); + } + + // Oops, we weren't creating a window! Don't know how to handle the + // message, so just pass it on to Windows to deal with it. + return DefWindowProc(hwnd, msg, wparam, lparam); +} + +//////////////////////////////////////////////////////////////////// +// Function: WinGraphicsWindow::process_1_event +// Access: Private, Static +// Description: Handles one event from the message queue. +//////////////////////////////////////////////////////////////////// +void WinGraphicsWindow:: +process_1_event() { + MSG msg; + + if (!GetMessage(&msg, NULL, 0, 0)) { + // WM_QUIT received. We need a cleaner way to deal with this. + // DestroyAllWindows(false); + exit(msg.wParam); // this will invoke AtExitFn + } + + // Translate virtual key messages + TranslateMessage(&msg); + // Call window_proc + DispatchMessage(&msg); +} + +//////////////////////////////////////////////////////////////////// +// Function: WinGraphicsWindow::update_cursor_window +// Access: Private, Static +// Description: Changes _cursor_window from its current value to the +// indicated value. This also changes the cursor +// properties appropriately. +//////////////////////////////////////////////////////////////////// +void WinGraphicsWindow:: +update_cursor_window(WinGraphicsWindow *to_window) { + bool hide_cursor = false; + if (to_window == (WinGraphicsWindow *)NULL) { + // We are leaving a graphics window; we should restore the Win2000 + // effects. + if (_got_saved_params) { + SystemParametersInfo(SPI_SETMOUSETRAILS, NULL, + (PVOID)_saved_mouse_trails, NULL); + SystemParametersInfo(SPI_SETCURSORSHADOW, NULL, + (PVOID)_saved_cursor_shadow, NULL); + SystemParametersInfo(SPI_SETMOUSEVANISH, NULL, + (PVOID)_saved_mouse_vanish, NULL); + _got_saved_params = false; + } + + } else { + const WindowProperties &to_props = to_window->get_properties(); + hide_cursor = to_props.get_cursor_hidden(); + + // We are entering a graphics window; we should save and disable + // the Win2000 effects. These don't work at all well over a 3-D + // window. + + // These parameters are only defined for Win2000/XP, but they + // should just cause a silent error on earlier OS's, which is OK. + if (!_got_saved_params) { + SystemParametersInfo(SPI_GETMOUSETRAILS, NULL, + &_saved_mouse_trails, NULL); + SystemParametersInfo(SPI_GETCURSORSHADOW, NULL, + &_saved_cursor_shadow, NULL); + SystemParametersInfo(SPI_GETMOUSEVANISH, NULL, + &_saved_mouse_vanish, NULL); + _got_saved_params = true; + + SystemParametersInfo(SPI_SETMOUSETRAILS, NULL, (PVOID)0, NULL); + SystemParametersInfo(SPI_SETCURSORSHADOW, NULL, (PVOID)false, NULL); + SystemParametersInfo(SPI_SETMOUSEVANISH, NULL, (PVOID)false, NULL); + } + } + + if (hide_cursor) { + // We should hide the cursor in the new window. + if (!_cursor_hidden) { + ShowCursor(false); + _cursor_hidden = true; + } + } else { + // We should reveal the cursor in the new window. + if (_cursor_hidden) { + ShowCursor(true); + _cursor_hidden = false; + } + } + + _cursor_window = to_window; +} + +//////////////////////////////////////////////////////////////////// +// Function: WinGraphicsWindow::register_window_class +// Access: Private, Static +// Description: Registers a Window class for all WinGraphicsWindows. +// This only needs to be done once per session. +//////////////////////////////////////////////////////////////////// +void WinGraphicsWindow:: +register_window_class() { + if (_window_class_registered) { + return; + } + + WNDCLASS wc; + + HINSTANCE instance = GetModuleHandle(NULL); + + // Clear before filling in window structure! + ZeroMemory(&wc, sizeof(WNDCLASS)); + wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; + wc.lpfnWndProc = (WNDPROC)static_window_proc; + wc.hInstance = instance; + + // Might be nice to move these properties into the WindowProperties + // structure, so they don't have to be global for all windows. + string windows_icon_filename = get_icon_filename().to_os_specific(); + string windows_mono_cursor_filename = get_mono_cursor_filename().to_os_specific(); + + if (!windows_icon_filename.empty()) { + // Note: LoadImage seems to cause win2k internal heap corruption + // (outputdbgstr warnings) if icon is more than 8bpp + + // loads a .ico fmt file + wc.hIcon = (HICON)LoadImage(NULL, windows_icon_filename.c_str(), + IMAGE_ICON, 0, 0, LR_LOADFROMFILE); + + if (wc.hIcon == NULL) { + windisplay_cat.warning() + << "windows icon filename '" << windows_icon_filename + << "' not found!!\n"; + } + } else { + wc.hIcon = NULL; // use default app icon + } + + _loaded_custom_cursor = false; + if (!windows_mono_cursor_filename.empty()) { + // Note: LoadImage seems to cause win2k internal heap corruption + // (outputdbgstr warnings) if icon is more than 8bpp (because it + // was 'mapping' 16bpp colors to the device?) + + DWORD load_flags = LR_LOADFROMFILE; + + /* + if (_props._fullscreen) { + // I think cursors should use LR_CREATEDIBSECTION since they + // should not be mapped to the device palette (in the case of + // 256-color cursors) since they are not going to be used on the + // desktop + load_flags |= LR_CREATEDIBSECTION; + + // Of course, we can't make this determination here because one + // window class is used for all windows, fullscreen as well as + // desktop windows. + } + */ + + // loads a .cur fmt file + _mouse_cursor = (HCURSOR) LoadImage(NULL, windows_mono_cursor_filename.c_str(), IMAGE_CURSOR, 0, 0, load_flags); + + if (_mouse_cursor == NULL) { + windisplay_cat.warning() + << "windows cursor filename '" << windows_mono_cursor_filename + << "' not found!!\n"; + } else { + _loaded_custom_cursor = true; + } + } + + if (!_loaded_custom_cursor) { + _mouse_cursor = LoadCursor(NULL, IDC_ARROW); + } + + // even if cursor isnt visible, we need to load it so its visible + // in client-area window border + wc.hCursor = _mouse_cursor; + wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH); + wc.lpszMenuName = NULL; + wc.lpszClassName = _window_class_name; + + if (!RegisterClass(&wc)) { + windisplay_cat.error() + << "could not register window class!" << endl; + return; + } + _window_class_registered = true; +} + +// dont pick any video modes < MIN_REFRESH_RATE Hz +#define MIN_REFRESH_RATE 60 +// EnumDisplaySettings may indicate 0 or 1 for refresh rate, which means use driver default rate (assume its >min_refresh_rate) +#define ACCEPTABLE_REFRESH_RATE(RATE) ((RATE >= MIN_REFRESH_RATE) || (RATE==0) || (RATE==1)) + +//////////////////////////////////////////////////////////////////// +// Function: WinGraphicsWindow::find_acceptable_display_mode +// Access: Private, Static +// Description: Looks for a fullscreen mode that meets the specified +// size and bitdepth requirements. Returns true if a +// suitable mode is found, false otherwise. +//////////////////////////////////////////////////////////////////// +bool WinGraphicsWindow:: +find_acceptable_display_mode(DWORD dwWidth, DWORD dwHeight, DWORD bpp, + DEVMODE &dm) { + int modenum = 0; + + while (1) { + ZeroMemory(&dm, sizeof(dm)); + dm.dmSize = sizeof(dm); + + if (!EnumDisplaySettings(NULL, modenum, &dm)) { + break; + } + + if ((dm.dmPelsWidth == dwWidth) && (dm.dmPelsHeight == dwHeight) && + (dm.dmBitsPerPel == bpp) && + ACCEPTABLE_REFRESH_RATE(dm.dmDisplayFrequency)) { + return true; + } + modenum++; + } + + return false; +} + +//////////////////////////////////////////////////////////////////// +// Function: WinGraphicsWindow::show_error_message +// Access: Private, Static +// Description: Pops up a dialog box with the indicated Windows error +// message ID (or the last error message generated) for +// meaningful display to the user. +//////////////////////////////////////////////////////////////////// +void WinGraphicsWindow:: +show_error_message(DWORD message_id) { + LPTSTR message_buffer; + + if (message_id == 0) { + message_id = GetLastError(); + } + + FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, + NULL, message_id, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), //The user default language + (LPTSTR)&message_buffer, // the weird ptrptr->ptr cast is intentional, see FORMAT_MESSAGE_ALLOCATE_BUFFER + 1024, NULL); + MessageBox(GetDesktopWindow(), message_buffer, _T(errorbox_title), MB_OK); + windisplay_cat.fatal() << "System error msg: " << message_buffer << endl; + LocalFree(message_buffer); +} + +//////////////////////////////////////////////////////////////////// +// Function: WinGraphicsWindow::lookup_key +// Access: Private +// Description: Translates the keycode reported by Windows to an +// appropriate Panda ButtonHandle. +//////////////////////////////////////////////////////////////////// +ButtonHandle WinGraphicsWindow:: +lookup_key(WPARAM wparam) const { + // First, check for a few buttons that we filter out when the IME + // window is open. + if (!_ime_active) { + switch(wparam) { + case VK_BACK: return KeyboardButton::backspace(); + case VK_DELETE: return KeyboardButton::del(); + case VK_ESCAPE: return KeyboardButton::escape(); + case VK_SPACE: return KeyboardButton::space(); + case VK_UP: return KeyboardButton::up(); + case VK_DOWN: return KeyboardButton::down(); + case VK_LEFT: return KeyboardButton::left(); + case VK_RIGHT: return KeyboardButton::right(); + } + } + + // Now check for the rest of the buttons, including the ones that + // we allow through even when the IME window is open. + switch(wparam) { + case VK_TAB: return KeyboardButton::tab(); + case VK_PRIOR: return KeyboardButton::page_up(); + case VK_NEXT: return KeyboardButton::page_down(); + case VK_HOME: return KeyboardButton::home(); + case VK_END: return KeyboardButton::end(); + case VK_F1: return KeyboardButton::f1(); + case VK_F2: return KeyboardButton::f2(); + case VK_F3: return KeyboardButton::f3(); + case VK_F4: return KeyboardButton::f4(); + case VK_F5: return KeyboardButton::f5(); + case VK_F6: return KeyboardButton::f6(); + case VK_F7: return KeyboardButton::f7(); + case VK_F8: return KeyboardButton::f8(); + case VK_F9: return KeyboardButton::f9(); + case VK_F10: return KeyboardButton::f10(); + case VK_F11: return KeyboardButton::f11(); + case VK_F12: return KeyboardButton::f12(); + case VK_INSERT: return KeyboardButton::insert(); + case VK_CAPITAL: return KeyboardButton::caps_lock(); + case VK_NUMLOCK: return KeyboardButton::num_lock(); + case VK_SCROLL: return KeyboardButton::scroll_lock(); + case VK_SNAPSHOT: return KeyboardButton::print_screen(); + + case VK_SHIFT: + case VK_LSHIFT: + case VK_RSHIFT: + return KeyboardButton::shift(); + + case VK_CONTROL: + case VK_LCONTROL: + case VK_RCONTROL: + return KeyboardButton::control(); + + case VK_MENU: + case VK_LMENU: + case VK_RMENU: + return KeyboardButton::alt(); + + default: + int key = MapVirtualKey(wparam, 2); + if (isascii(key) && key != 0) { + // We used to try to remap lowercase to uppercase keys + // here based on the state of the shift and/or caps lock + // keys. But that's a mistake, and doesn't allow for + // international or user-defined keyboards; let Windows + // do that mapping. + + // Nowadays, we make a distinction between a "button" + // and a "keystroke". A button corresponds to a + // physical button on the keyboard and has a down and up + // event associated. A keystroke may or may not + // correspond to a physical button, but will be some + // Unicode character and will not have a corresponding + // up event. + return KeyboardButton::ascii_key(tolower(key)); + } + break; + } + return ButtonHandle::none(); +} diff --git a/panda/src/windisplay/winGraphicsWindow.h b/panda/src/windisplay/winGraphicsWindow.h new file mode 100644 index 0000000000..5fccedcf66 --- /dev/null +++ b/panda/src/windisplay/winGraphicsWindow.h @@ -0,0 +1,164 @@ +// Filename: winGraphicsWindow.h +// Created by: drose (20Dec02) +// +//////////////////////////////////////////////////////////////////// +// +// 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 WINGRAPHICSWINDOW_H +#define WINGRAPHICSWINDOW_H + +// include win32 defns for everything up to XP, and assume I'm smart +// enough to use GetProcAddress for backward compat on w95/w98 for +// newer fns +#define _WIN32_WINNT 0x0501 + +#define WINDOWS_LEAN_AND_MEAN +#include +#undef WINDOWS_LEAN_AND_MEAN + +#include "pandabase.h" +#include "graphicsWindow.h" + +class WinGraphicsPipe; + +//////////////////////////////////////////////////////////////////// +// Class : WinGraphicsWindow +// Description : An abstract base class for glGraphicsWindow and +// dxGraphicsWindow (and, in general, graphics windows +// that interface with the Microsoft Windows API). +// +// This class includes all the code for manipulating +// windows themselves: opening them, closing them, +// responding to user keyboard and mouse input, and so +// on. It does not make any 3-D rendering calls into +// the window; that is the province of the +// GraphicsStateGuardian. +//////////////////////////////////////////////////////////////////// +class EXPCL_PANDAWIN WinGraphicsWindow : public GraphicsWindow { +public: + WinGraphicsWindow(GraphicsPipe *pipe); + virtual ~WinGraphicsWindow(); + + virtual void begin_flip(); + + virtual void process_events(); + virtual void set_properties_now(WindowProperties &properties); + +protected: + virtual void close_window(); + virtual bool open_window(); + virtual void fullscreen_minimized(WindowProperties &properties); + virtual void fullscreen_restored(WindowProperties &properties); + + virtual bool do_reshape_request(int x_origin, int y_origin, + int x_size, int y_size); + + virtual void handle_reshape(); + virtual bool do_fullscreen_resize(int x_size, int y_size); + + void get_client_rect_screen(HWND hwnd, RECT *view_rect); + +private: + bool open_fullscreen_window(); + bool open_regular_window(); + void track_mouse_leaving(HWND hwnd); + + LONG window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam); + static LONG WINAPI + static_window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam); + static void process_1_event(); + + INLINE void handle_mouse_motion(int x, int y); + INLINE void handle_mouse_exit(void); + INLINE void handle_keypress(ButtonHandle key, int x, int y); + INLINE void handle_keyrelease(ButtonHandle key); + ButtonHandle lookup_key(WPARAM wparam) const; + INLINE int translate_mouse(int pos) const; + INLINE void set_cursor_in_window(); + INLINE void set_cursor_out_of_window(); + static void update_cursor_window(WinGraphicsWindow *to_window); + + static void register_window_class(); + static bool find_acceptable_display_mode(DWORD dwWidth, DWORD dwHeight, + DWORD bpp, DEVMODE &dm); + static void show_error_message(DWORD message_id = 0); + +protected: + HWND _mwindow; + +private: + bool _ime_open; + bool _ime_active; + bool _ime_composition_w; + bool _tracking_mouse_leaving; + bool _maximized; + DEVMODE _fullscreen_display_mode; + + static bool _got_dynamic_fns; + typedef BOOL (WINAPI *PFN_TRACKMOUSEEVENT)(LPTRACKMOUSEEVENT); + static PFN_TRACKMOUSEEVENT _pfnTrackMouseEvent; + +protected: + static bool _loaded_custom_cursor; + static HCURSOR _mouse_cursor; + static const char * const _window_class_name; + static bool _window_class_registered; + +private: + // We need this map to support per-window calls to window_proc(). + typedef map WindowHandles; + static WindowHandles _window_handles; + + // And we need a static pointer to the current WinGraphicsWindow we + // are creating at the moment, since CreateWindow() starts + // generating window events before it gives us the window handle. + static WinGraphicsWindow *_creating_window; + + // This tracks the current GraphicsWindow whose client area contains + // the mouse. There will only be one of these at a time, and + // storing the pointer here allows us to handle ambiguities in the + // order in which messages are passed from Windows to the various + // windows we manage. This pointer is used by + // set_cursor_in_window() to determine when it is time to call + // update_cursor() to hide the cursor (or do other related + // operations). + static WinGraphicsWindow *_cursor_window; + static bool _cursor_hidden; + static bool _got_saved_params; + static int _saved_mouse_trails; + static bool _saved_cursor_shadow; + static bool _saved_mouse_vanish; + +public: + static TypeHandle get_class_type() { + return _type_handle; + } + static void init_type() { + GraphicsWindow::init_type(); + register_type(_type_handle, "WinGraphicsWindow", + GraphicsWindow::get_class_type()); + } + virtual TypeHandle get_type() const { + return get_class_type(); + } + virtual TypeHandle force_init_type() {init_type(); return get_class_type();} + +private: + static TypeHandle _type_handle; +}; + +#include "winGraphicsWindow.I" + +#endif