tweak graphicsBuffer, add wglGraphicsBuffer

This commit is contained in:
David Rose 2004-02-09 13:37:49 +00:00
parent 36cf062b96
commit 57eefece08
27 changed files with 2084 additions and 1412 deletions

View File

@ -44,6 +44,7 @@ PUBLISHED:
FM_single_buffer = 0x0000,
FM_double_buffer = 0x0002,
FM_triple_buffer = 0x0004,
FM_buffer = 0x0006, // == (FM_single_buffer | FM_double_buffer | FM_triple_buffer)
FM_accum = 0x0008,
FM_alpha = 0x0010,
FM_depth = 0x0020,

View File

@ -16,3 +16,35 @@
//
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
// Function: GraphicsBuffer::has_texture
// Access: Published
// Description: Returns true if the GraphicsBuffer is set to render
// into a texture (because want_texture has been passed
// to the GraphicsBuffer constructor), or false
// otherwise.
////////////////////////////////////////////////////////////////////
INLINE bool GraphicsBuffer::
has_texture() const {
return !(_texture.is_null());
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsBuffer::get_texture
// Access: Published
// Description: Returns the texture into which the GraphicsBuffer
// renders, if any, or NULL if want_texture was passed
// into the constructor as false.
//
// If the texture is non-NULL, it may be applied to
// geometry to be rendered for any other windows or
// buffers that share the same GSG as this
// GraphicsBuffer. The effect is undefined for windows
// that share a different GSG; usually in these cases
// the texture will be invalid.
////////////////////////////////////////////////////////////////////
INLINE Texture *GraphicsBuffer::
get_texture() const {
return _texture;
}

View File

@ -29,7 +29,7 @@ TypeHandle GraphicsBuffer::_type_handle;
////////////////////////////////////////////////////////////////////
GraphicsBuffer::
GraphicsBuffer(GraphicsPipe *pipe, GraphicsStateGuardian *gsg,
int x_size, int y_size) :
int x_size, int y_size, bool want_texture) :
GraphicsOutput(pipe, gsg)
{
#ifdef DO_MEMORY_USAGE
@ -41,9 +41,14 @@ GraphicsBuffer(GraphicsPipe *pipe, GraphicsStateGuardian *gsg,
<< "Creating new offscreen buffer using GSG " << (void *)gsg << "\n";
}
if (want_texture) {
_texture = new Texture();
}
_x_size = x_size;
_y_size = y_size;
_has_size = true;
_open_request = OR_none;
}
////////////////////////////////////////////////////////////////////
@ -54,3 +59,94 @@ GraphicsBuffer(GraphicsPipe *pipe, GraphicsStateGuardian *gsg,
GraphicsBuffer::
~GraphicsBuffer() {
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsBuffer::request_open
// Access: Public, Virtual
// Description: This is called by the GraphicsEngine to request that
// the buffer (or whatever) open itself or, in general,
// make itself valid, at the next call to
// process_events().
////////////////////////////////////////////////////////////////////
void GraphicsBuffer::
request_open() {
_open_request = OR_open;
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsBuffer::request_close
// Access: Public, Virtual
// Description: This is called by the GraphicsEngine to request that
// the buffer (or whatever) close itself or, in general,
// make itself invalid, at the next call to
// process_events(). By that time we promise the gsg
// pointer will be cleared.
////////////////////////////////////////////////////////////////////
void GraphicsBuffer::
request_close() {
_open_request = OR_none;
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsBuffer::set_close_now
// Access: Public, Virtual
// Description: This is called by the GraphicsEngine to insist that
// the buffer be closed immediately. This is only
// called from the buffer thread.
////////////////////////////////////////////////////////////////////
void GraphicsBuffer::
set_close_now() {
_open_request = OR_none;
close_buffer();
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsBuffer::process_events
// Access: Public, Virtual
// Description: Honor any requests recently made via request_open()
// or request_close().
//
// This function is called only within the window
// thread.
////////////////////////////////////////////////////////////////////
void GraphicsBuffer::
process_events() {
switch (_open_request) {
case OR_none:
return;
case OR_open:
open_buffer();
break;
case OR_close:
close_buffer();
break;
}
_open_request = OR_none;
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsBuffer::close_buffer
// Access: Protected, Virtual
// Description: Closes the buffer right now. Called from the window
// thread.
////////////////////////////////////////////////////////////////////
void GraphicsBuffer::
close_buffer() {
display_cat.info()
<< "Closing " << get_type() << "\n";
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsBuffer::open_buffer
// Access: Protected, Virtual
// Description: Opens the buffer right now. Called from the window
// thread. Returns true if the buffer is successfully
// opened, or false if there was a problem.
////////////////////////////////////////////////////////////////////
bool GraphicsBuffer::
open_buffer() {
return false;
}

View File

@ -22,20 +22,56 @@
#include "pandabase.h"
#include "graphicsOutput.h"
#include "texture.h"
#include "pointerTo.h"
////////////////////////////////////////////////////////////////////
// Class : GraphicsBuffer
// Description : An offscreen buffer for rendering into. Pretty much
// all you can do with this is render into it and then
// get the framebuffer out as an image.
// Description : An offscreen buffer for rendering into. This is
// similar in function to a GraphicsWindow, except that
// the output is not visible to the user.
//
// If want_texture is passed true into the constructor,
// the GraphicsBuffer will render directly into a
// texture which can be retrieved via get_texture().
// This may then be applied to geometry for rendering in
// other windows or buffers using the same
// GraphicsStateGuardian.
////////////////////////////////////////////////////////////////////
class EXPCL_PANDA GraphicsBuffer : public GraphicsOutput {
protected:
GraphicsBuffer(GraphicsPipe *pipe, GraphicsStateGuardian *gsg,
int x_size, int y_size);
int x_size, int y_size, bool want_texture);
PUBLISHED:
virtual ~GraphicsBuffer();
INLINE bool has_texture() const;
INLINE Texture *get_texture() const;
public:
virtual void request_open();
virtual void request_close();
// 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 set_close_now();
virtual void process_events();
protected:
virtual void close_buffer();
virtual bool open_buffer();
protected:
PT(Texture) _texture;
enum OpenRequest {
OR_none,
OR_open,
OR_close,
};
OpenRequest _open_request;
public:
static TypeHandle get_class_type() {
@ -57,4 +93,4 @@ private:
#include "graphicsBuffer.I"
#endif /* GRAPHICSBUFFER_H */
#endif

View File

@ -105,8 +105,9 @@ make_window(GraphicsPipe *pipe, GraphicsStateGuardian *gsg) {
////////////////////////////////////////////////////////////////////
INLINE GraphicsBuffer *GraphicsEngine::
make_buffer(GraphicsPipe *pipe, GraphicsStateGuardian *gsg,
int x_size, int y_size) {
return make_buffer(pipe, gsg, x_size, y_size, get_threading_model());
int x_size, int y_size, bool want_texture) {
return make_buffer(pipe, gsg, x_size, y_size, want_texture,
get_threading_model());
}
////////////////////////////////////////////////////////////////////

View File

@ -224,7 +224,7 @@ make_window(GraphicsPipe *pipe, GraphicsStateGuardian *gsg,
////////////////////////////////////////////////////////////////////
GraphicsBuffer *GraphicsEngine::
make_buffer(GraphicsPipe *pipe, GraphicsStateGuardian *gsg,
int x_size, int y_size,
int x_size, int y_size, bool want_texture,
const GraphicsThreadingModel &threading_model) {
if (gsg != (GraphicsStateGuardian *)NULL) {
nassertr(pipe == gsg->get_pipe(), NULL);
@ -234,7 +234,8 @@ make_buffer(GraphicsPipe *pipe, GraphicsStateGuardian *gsg,
}
// TODO: ask the window thread to make the buffer.
PT(GraphicsBuffer) buffer = pipe->make_buffer(gsg, x_size, y_size);
PT(GraphicsBuffer) buffer =
pipe->make_buffer(gsg, x_size, y_size, want_texture);
do_add_window(buffer, gsg, threading_model);
return buffer;
}
@ -881,6 +882,9 @@ do_add_window(GraphicsOutput *window, GraphicsStateGuardian *gsg,
display_cat.info()
<< "Created " << window->get_type() << "\n";
// By default, try to open each window as it is added.
window->request_open();
}
}

View File

@ -36,6 +36,7 @@ class Pipeline;
class DisplayRegion;
class GraphicsPipe;
class FrameBufferProperties;
class Texture;
////////////////////////////////////////////////////////////////////
// Class : GraphicsEngine
@ -78,10 +79,10 @@ PUBLISHED:
const GraphicsThreadingModel &threading_model);
INLINE GraphicsBuffer *make_buffer(GraphicsPipe *pipe,
GraphicsStateGuardian *gsg,
int x_size, int y_size);
int x_size, int y_size, bool want_texture);
GraphicsBuffer *make_buffer(GraphicsPipe *pipe,
GraphicsStateGuardian *gsg,
int x_size, int y_size,
int x_size, int y_size, bool want_texture,
const GraphicsThreadingModel &threading_model);
bool remove_window(GraphicsOutput *window);

View File

@ -461,6 +461,18 @@ request_close() {
void GraphicsOutput::
set_close_now() {
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsOutput::reset_window
// Access: Protected, Virtual
// Description: resets the window framebuffer from its derived
// children. Does nothing here.
////////////////////////////////////////////////////////////////////
void GraphicsOutput::
reset_window(bool swapchain) {
display_cat.info()
<< "Resetting " << get_type() << "\n";
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsOutput::begin_frame
@ -588,42 +600,6 @@ void GraphicsOutput::
process_events() {
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsOutput::close_window
// Access: Protected, Virtual
// Description: Closes the window right now. Called from the window
// thread.
////////////////////////////////////////////////////////////////////
void GraphicsOutput::
close_window() {
display_cat.info()
<< "Closing " << get_type() << "\n";
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsOutput::reset_window
// Access: Protected, Virtual
// Description: resets the window framebuffer from its derived
// children. Does nothing here.
////////////////////////////////////////////////////////////////////
void GraphicsOutput::
reset_window(bool swapchain) {
display_cat.info()
<< "Resetting " << get_type() << "\n";
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsOutput::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 GraphicsOutput::
open_window() {
return false;
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsOutput::declare_channel
// Access: Protected

View File

@ -101,9 +101,10 @@ public:
virtual void request_open();
virtual void request_close();
virtual void set_close_now();
public:
virtual void set_close_now();
virtual void reset_window(bool swapchain);
// 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.
@ -126,10 +127,6 @@ public:
virtual void process_events();
protected:
virtual void close_window();
virtual bool open_window();
virtual void reset_window(bool swapchain);
void declare_channel(int index, GraphicsChannel *chan);
protected:

View File

@ -164,6 +164,6 @@ make_window(GraphicsStateGuardian *) {
// Description: Creates a new offscreen buffer on the pipe, if possible.
////////////////////////////////////////////////////////////////////
PT(GraphicsBuffer) GraphicsPipe::
make_buffer(GraphicsStateGuardian *, int, int) {
make_buffer(GraphicsStateGuardian *, int, int, bool) {
return NULL;
}

View File

@ -32,6 +32,7 @@ class GraphicsWindow;
class GraphicsBuffer;
class GraphicsStateGuardian;
class FrameBufferProperties;
class Texture;
////////////////////////////////////////////////////////////////////
// Class : GraphicsPipe
@ -94,7 +95,8 @@ protected:
virtual PT(GraphicsStateGuardian) make_gsg(const FrameBufferProperties &properties);
virtual void close_gsg(GraphicsStateGuardian *gsg);
virtual PT(GraphicsWindow) make_window(GraphicsStateGuardian *gsg);
virtual PT(GraphicsBuffer) make_buffer(GraphicsStateGuardian *gsg, int x_size, int y_size);
virtual PT(GraphicsBuffer) make_buffer(GraphicsStateGuardian *gsg,
int x_size, int y_size, bool want_texture);
Mutex _lock;

View File

@ -537,6 +537,42 @@ set_properties_now(WindowProperties &properties) {
}
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsWindow::close_window
// Access: Protected, Virtual
// Description: Closes the window right now. Called from the window
// thread.
////////////////////////////////////////////////////////////////////
void GraphicsWindow::
close_window() {
display_cat.info()
<< "Closing " << get_type() << "\n";
}
////////////////////////////////////////////////////////////////////
// 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::reset_window
// Access: Protected, Virtual
// Description: resets the window framebuffer from its derived
// children. Does nothing here.
////////////////////////////////////////////////////////////////////
void GraphicsWindow::
reset_window(bool swapchain) {
display_cat.info()
<< "Resetting " << get_type() << "\n";
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsWindow::do_reshape_request
// Access: Protected, Virtual

View File

@ -73,15 +73,19 @@ public:
public:
virtual void request_open();
virtual void request_close();
virtual void set_close_now();
// 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 set_close_now();
virtual void process_events();
virtual void set_properties_now(WindowProperties &properties);
protected:
virtual void close_window();
virtual bool open_window();
virtual void reset_window(bool swapchain);
virtual bool do_reshape_request(int x_origin, int y_origin,
int x_size, int y_size);

View File

@ -1643,35 +1643,6 @@ draw_sphere(GeomSphere *geom, GeomContext *) {
////////////////////////////////////////////////////////////////////
TextureContext *GLGraphicsStateGuardian::
prepare_texture(Texture *tex) {
GLint max_tex_size;
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max_tex_size);
int xsize = tex->_pbuffer->get_xsize();
int ysize = tex->_pbuffer->get_ysize();
if ((xsize> max_tex_size) || (ysize > max_tex_size)) {
glgsg_cat.warning()
<< tex->get_name() <<": "<< xsize << "x" << ysize
<< " exceeds max tex size " << max_tex_size << "x" << max_tex_size << endl;
// Rather than returning NULL in these error cases, which will
// crab out Panda, we simply let GL go ahead and do the best it
// can do.
}
// regular GL does not allow non-pow2 size textures
// the GL_NV_texture_rectangle EXT does allow non-pow2 sizes, albeit with no mipmaps or coord wrapping
// should probably add checks for that in here at some point
// or you could use gluBuild2DMipMaps to scale the texture to the nearest pow2 size
if (!(ISPOW2(xsize) && ISPOW2(ysize))) {
glgsg_cat.warning()
<< tex->get_name() <<": "<< xsize << "x" << ysize
<< " is not a power of 2 size!\n";
// Rather than returning NULL in these error cases, which will
// crab out Panda, we simply let GL go ahead and do the best it
// can do.
}
GLTextureContext *gtc = new GLTextureContext(tex);
glGenTextures(1, &gtc->_index);

View File

@ -24,7 +24,7 @@
// render itself into the indicated window.
////////////////////////////////////////////////////////////////////
INLINE void FrameRateMeter::
setup_layer(GraphicsWindow *window) {
setup_layer(GraphicsOutput *window) {
setup_layer(window->get_channel(0));
}

View File

@ -22,7 +22,7 @@
#include "pandabase.h"
#include "textNode.h"
#include "nodePath.h"
#include "graphicsWindow.h"
#include "graphicsOutput.h"
#include "graphicsLayer.h"
#include "pointerTo.h"
#include "pStatCollector.h"
@ -47,7 +47,7 @@ PUBLISHED:
FrameRateMeter(const string &name);
virtual ~FrameRateMeter();
INLINE void setup_layer(GraphicsWindow *window);
INLINE void setup_layer(GraphicsOutput *window);
void setup_layer(GraphicsChannel *channel);
void clear_layer();

View File

@ -13,21 +13,21 @@
#define COMBINED_SOURCES $[TARGET]_composite1.cxx
#define INSTALL_HEADERS \
config_wgldisplay.h \
wglGraphicsPipe.I wglGraphicsPipe.h \
wglGraphicsStateGuardian.I wglGraphicsStateGuardian.h \
wglGraphicsWindow.I wglGraphicsWindow.h
// Win32Defs.h
config_wgldisplay.h \
wglGraphicsBuffer.I wglGraphicsBuffer.h \
wglGraphicsPipe.I wglGraphicsPipe.h \
wglGraphicsStateGuardian.I wglGraphicsStateGuardian.h \
wglGraphicsWindow.I wglGraphicsWindow.h
#define INCLUDED_SOURCES \
config_wgldisplay.cxx \
wglGraphicsBuffer.cxx \
wglGraphicsPipe.cxx \
wglGraphicsStateGuardian.cxx \
wglGraphicsWindow.cxx
#define SOURCES \
$[INSTALL_HEADERS]
// wglext.h
#end lib_target

View File

@ -17,6 +17,7 @@
////////////////////////////////////////////////////////////////////
#include "config_wgldisplay.h"
#include "wglGraphicsBuffer.h"
#include "wglGraphicsPipe.h"
#include "wglGraphicsStateGuardian.h"
#include "wglGraphicsWindow.h"
@ -46,6 +47,7 @@ init_libwgldisplay() {
}
initialized = true;
wglGraphicsBuffer::init_type();
wglGraphicsPipe::init_type();
wglGraphicsStateGuardian::init_type();
wglGraphicsWindow::init_type();

View File

@ -0,0 +1,17 @@
// Filename: wglGraphicsWindow.I
// Created by: drose (08Feb04)
//
////////////////////////////////////////////////////////////////////
//
// 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 .
//
////////////////////////////////////////////////////////////////////

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,90 @@
// Filename: wglGraphicsBuffer.h
// Created by: drose (08Feb04)
//
////////////////////////////////////////////////////////////////////
//
// 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 WGLGRAPHICSBUFFER_H
#define WGLGRAPHICSBUFFER_H
#include "pandabase.h"
#include "graphicsBuffer.h"
#include <windows.h>
////////////////////////////////////////////////////////////////////
// Class : wglGraphicsBuffer
// Description : An offscreen render buffer. In OpenGL under Windows,
// this simply renders into a window that is never made
// visible. There's a Windows interface for rendering
// into a DIB, but this puts restrictions on the kind of
// pixelformat we can use, and thus makes it difficult
// to support one GSG rendering into an offscreen buffer
// and also into a window.
////////////////////////////////////////////////////////////////////
class EXPCL_PANDAGL wglGraphicsBuffer : public GraphicsBuffer {
public:
wglGraphicsBuffer(GraphicsPipe *pipe, GraphicsStateGuardian *gsg,
int x_size, int y_size, bool want_texture);
virtual ~wglGraphicsBuffer();
virtual void make_current();
virtual void release_gsg();
virtual void begin_flip();
protected:
virtual void close_buffer();
virtual bool open_buffer();
private:
void setup_colormap(const PIXELFORMATDESCRIPTOR &pixelformat);
#ifdef _DEBUG
static void print_pfd(PIXELFORMATDESCRIPTOR *pfd, char *msg);
#endif
static void register_window_class();
static LONG WINAPI static_window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam);
static void show_error_message(DWORD message_id = 0);
HWND _hWnd;
HDC _hdc;
HPALETTE _colormap;
static const char * const _window_class_name;
static bool _window_class_registered;
public:
static TypeHandle get_class_type() {
return _type_handle;
}
static void init_type() {
GraphicsBuffer::init_type();
register_type(_type_handle, "wglGraphicsBuffer",
GraphicsBuffer::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 "wglGraphicsBuffer.I"
#endif

View File

@ -19,6 +19,8 @@
#include "wglGraphicsPipe.h"
#include "config_wgldisplay.h"
#include "config_windisplay.h"
#include "wglGraphicsWindow.h"
#include "wglGraphicsBuffer.h"
typedef enum {Software, MCD, ICD} OGLDriverType;
static const char * const OGLDrvStrings[] = { "Software", "MCD", "ICD" };
@ -82,14 +84,16 @@ make_gsg(const FrameBufferProperties &properties) {
if (!_is_valid) {
return NULL;
}
// Make a copy of the supplied properties so we can possibly modify
// them to suit our available properties.
FrameBufferProperties new_properties = properties;
// Get a handle to the screen's DC so we can choose a pixel format
// (and a corresponding set of frame buffer properties) suitable for
// rendering to windows on this screen.
// We need a DC to examine the available pixel formats. We'll use
// the screen DC.
HDC hdc = GetDC(NULL);
int pfnum = choose_pfnum(new_properties, hdc);
ReleaseDC(NULL, hdc);
if (gl_force_pixfmt != 0) {
wgldisplay_cat.info()
@ -103,12 +107,8 @@ make_gsg(const FrameBufferProperties &properties) {
<< "config() - picking pixfmt #" << pfnum <<endl;
}
// Now we're done with the screen's hdc, so release it.
ReleaseDC(NULL, hdc);
// Now we can make a GSG.
PT(wglGraphicsStateGuardian) gsg =
new wglGraphicsStateGuardian(new_properties, pfnum);
new wglGraphicsStateGuardian(properties, pfnum);
return gsg.p();
}
@ -123,9 +123,20 @@ make_window(GraphicsStateGuardian *gsg) {
return new wglGraphicsWindow(this, gsg);
}
////////////////////////////////////////////////////////////////////
// Function: wglGraphicsPipe::make_buffer
// Access: Protected, Virtual
// Description: Creates a new offscreen buffer on the pipe, if possible.
////////////////////////////////////////////////////////////////////
PT(GraphicsBuffer) wglGraphicsPipe::
make_buffer(GraphicsStateGuardian *gsg, int x_size, int y_size,
bool want_texture) {
return new wglGraphicsBuffer(this, gsg, x_size, y_size, want_texture);
}
////////////////////////////////////////////////////////////////////
// Function: wglGraphicsPipe::choose_pfnum
// Access: Private
// Access: Private, Static
// Description: Selects a suitable pixel format number for the given
// frame buffer properties. Returns the selected number
// if successful, or 0 otherwise.
@ -134,9 +145,8 @@ make_window(GraphicsStateGuardian *gsg) {
// the actual visual chosen.
////////////////////////////////////////////////////////////////////
int wglGraphicsPipe::
choose_pfnum(FrameBufferProperties &properties, HDC hdc) const {
choose_pfnum(FrameBufferProperties &properties, HDC hdc) {
int pfnum;
bool bUsingSoftware = false;
if (force_software_renderer) {
pfnum = find_pixfmtnum(properties, hdc, false);
@ -146,7 +156,6 @@ choose_pfnum(FrameBufferProperties &properties, HDC hdc) const {
<< "Couldn't find compatible software-renderer OpenGL pixfmt, check your window properties!\n";
return 0;
}
bUsingSoftware = true;
} else {
pfnum = find_pixfmtnum(properties, hdc, true);
@ -156,7 +165,11 @@ choose_pfnum(FrameBufferProperties &properties, HDC hdc) const {
if (pfnum == 0) {
wgldisplay_cat.error()
<< "Couldn't find HW or Software OpenGL pixfmt appropriate for this desktop!!\n";
} else {
wgldisplay_cat.info()
<< "Couldn't find compatible OGL HW pixelformat, using software rendering.\n";
}
} else {
wgldisplay_cat.error()
<< "Couldn't find HW-accelerated OpenGL pixfmt appropriate for this desktop!!\n";
@ -168,21 +181,15 @@ choose_pfnum(FrameBufferProperties &properties, HDC hdc) const {
<< "desktop screen pixeldepth to 16bpp,and check your panda window properties\n";
return 0;
}
bUsingSoftware = true;
}
}
if (bUsingSoftware) {
wgldisplay_cat.info()
<< "Couldn't find compatible OGL HW pixelformat, using software rendering.\n";
}
return pfnum;
}
////////////////////////////////////////////////////////////////////
// Function: wglGraphicsPipe::find_pixfmtnum
// Access: Private
// Access: Private, Static
// 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
@ -190,7 +197,7 @@ choose_pfnum(FrameBufferProperties &properties, HDC hdc) const {
////////////////////////////////////////////////////////////////////
int wglGraphicsPipe::
find_pixfmtnum(FrameBufferProperties &properties, HDC hdc,
bool bLookforHW) const {
bool bLookforHW) {
int frame_buffer_mode = properties.get_frame_buffer_mode();
bool want_depth_bits = properties.has_depth_bits();
bool want_color_bits = properties.has_color_bits();
@ -201,14 +208,14 @@ find_pixfmtnum(FrameBufferProperties &properties, HDC hdc,
pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR);
pfd.nVersion = 1;
// just use the pixfmt of the current desktop
// We have to call DescribePixelFormat() once just to get the
// highest pfnum available. Then we can iterate through all of the
// pfnums.
int max_pfnum = DescribePixelFormat(hdc, 1, 0, NULL);
int cur_bpp = GetDeviceCaps(hdc, BITSPIXEL);
int pfnum = 0;
int MaxPixFmtNum =
DescribePixelFormat(hdc, 1, sizeof(PIXELFORMATDESCRIPTOR), &pfd);
int cur_bpp = GetDeviceCaps(hdc,BITSPIXEL);
int pfnum;
for(pfnum = 1; pfnum <= MaxPixFmtNum; pfnum++) {
for (pfnum = 1; pfnum <= max_pfnum; pfnum++) {
DescribePixelFormat(hdc, pfnum, sizeof(PIXELFORMATDESCRIPTOR), &pfd);
// official, nvidia sanctioned way.
@ -237,58 +244,70 @@ find_pixfmtnum(FrameBufferProperties &properties, HDC hdc,
}
DWORD dwReqFlags = (PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW);
if ((frame_buffer_mode & FrameBufferProperties::FM_double_buffer) != 0) {
dwReqFlags|= PFD_DOUBLEBUFFER;
}
if (wgldisplay_cat.is_debug()) {
wgldisplay_cat->debug()
wgldisplay_cat.debug()
<< "----------------" << endl;
if ((frame_buffer_mode & FrameBufferProperties::FM_alpha) != 0) {
wgldisplay_cat->debug()
wgldisplay_cat.debug()
<< "want alpha, pfd says '"
<< (int)(pfd.cAlphaBits) << "'" << endl;
}
if ((frame_buffer_mode & FrameBufferProperties::FM_depth) != 0) {
wgldisplay_cat->debug()
wgldisplay_cat.debug()
<< "want depth, pfd says '"
<< (int)(pfd.cDepthBits) << "'" << endl;
}
if ((frame_buffer_mode & FrameBufferProperties::FM_stencil) != 0) {
wgldisplay_cat->debug()
wgldisplay_cat.debug()
<< "want stencil, pfd says '"
<< (int)(pfd.cStencilBits) << "'" << endl;
}
wgldisplay_cat->debug()
wgldisplay_cat.debug()
<< "final flag check " << (int)(pfd.dwFlags & dwReqFlags) << " =? "
<< (int)dwReqFlags << endl;
wgldisplay_cat->debug()
wgldisplay_cat.debug()
<< "pfd bits = " << (int)(pfd.cColorBits) << endl;
wgldisplay_cat->debug()
wgldisplay_cat.debug()
<< "cur_bpp = " << cur_bpp << endl;
}
if ((frame_buffer_mode & FrameBufferProperties::FM_double_buffer) != 0) {
dwReqFlags|= PFD_DOUBLEBUFFER;
}
if ((frame_buffer_mode & FrameBufferProperties::FM_alpha) != 0 &&
(pfd.cAlphaBits==0)) {
wgldisplay_cat.debug()
<< " rejecting because alpha is missing.\n";
continue;
}
if ((frame_buffer_mode & FrameBufferProperties::FM_depth) != 0 &&
(pfd.cDepthBits==0)) {
wgldisplay_cat.debug()
<< " rejecting because depth is missing.\n";
continue;
}
if ((frame_buffer_mode & FrameBufferProperties::FM_stencil) != 0 &&
(pfd.cStencilBits==0)) {
wgldisplay_cat.debug()
<< " rejecting because stencil is missing.\n";
continue;
}
if ((pfd.dwFlags & dwReqFlags) != dwReqFlags) {
wgldisplay_cat.debug()
<< " rejecting because some other required flags are missing.\n";
continue;
}
// now we ignore the specified want_color_bits for windowed mode
// instead we use the current screen depth
// drose: Does this help anything? Checking the current screen
// depth doesn't make sense if we are rendering offscreen or if we
// are planning to open a fullscreen window, and it seems like it
// shouldn't be necessary anyway.
if ((pfd.cColorBits!=cur_bpp) &&
(!((cur_bpp==16) && (pfd.cColorBits==15))) &&
(!((cur_bpp==32) && (pfd.cColorBits==24)))) {
@ -299,12 +318,9 @@ find_pixfmtnum(FrameBufferProperties &properties, HDC hdc,
// 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;
return pfnum;
}
if (pfnum > MaxPixFmtNum) {
pfnum = 0;
}
return pfnum;
// No pfnum was acceptable.
return 0;
}

View File

@ -39,11 +39,12 @@ public:
protected:
virtual PT(GraphicsStateGuardian) make_gsg(const FrameBufferProperties &properties);
virtual PT(GraphicsWindow) make_window(GraphicsStateGuardian *gsg);
virtual PT(GraphicsBuffer) make_buffer(GraphicsStateGuardian *gsg,
int x_size, int y_size, bool want_texture);
private:
int choose_pfnum(FrameBufferProperties &properties, HDC hdc) const;
int find_pixfmtnum(FrameBufferProperties &properties, HDC hdc,
bool bLookforHW) const;
static int choose_pfnum(FrameBufferProperties &properties, HDC hdc);
static int find_pixfmtnum(FrameBufferProperties &properties, HDC hdc,
bool bLookforHW);
public:
static TypeHandle get_class_type() {

View File

@ -20,7 +20,12 @@
// Function: wglGraphicsStateGuardian::get_pfnum
// Access: Public
// Description: Returns the pixel format number chosen for windows
// that use this context.
// that use this context. In OpenGL under Microsoft
// Windows, the window must be created first and then
// the GL context is created from the window, and the
// context inherits the pixel format of the window.
// Therefore, all windows that share a particular
// context must also share the same pixel format.
////////////////////////////////////////////////////////////////////
INLINE int wglGraphicsStateGuardian::
get_pfnum() const {

View File

@ -39,8 +39,12 @@ public:
private:
void make_context(HDC hdc);
bool _made_context;
// All windows that share a particular GL context must also share
// the same pixel format; therefore, we store the pixel format
// number in the GSG.
int _pfnum;
bool _made_context;
HGLRC _context;
public:

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,5 @@
#include "config_wgldisplay.cxx"
#include "wglGraphicsBuffer.cxx"
#include "wglGraphicsPipe.cxx"
#include "wglGraphicsStateGuardian.cxx"
#include "wglGraphicsWindow.cxx"