mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-04 10:54:24 -04:00
tweak graphicsBuffer, add wglGraphicsBuffer
This commit is contained in:
parent
36cf062b96
commit
57eefece08
@ -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,
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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:
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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, >c->_index);
|
||||
|
||||
|
@ -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));
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
|
17
panda/src/wgldisplay/wglGraphicsBuffer.I
Normal file
17
panda/src/wgldisplay/wglGraphicsBuffer.I
Normal 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 .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
1646
panda/src/wgldisplay/wglGraphicsBuffer.cxx
Normal file
1646
panda/src/wgldisplay/wglGraphicsBuffer.cxx
Normal file
File diff suppressed because it is too large
Load Diff
90
panda/src/wgldisplay/wglGraphicsBuffer.h
Normal file
90
panda/src/wgldisplay/wglGraphicsBuffer.h
Normal 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
|
@ -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;
|
||||
}
|
||||
|
@ -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() {
|
||||
|
@ -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 {
|
||||
|
@ -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
@ -1,4 +1,5 @@
|
||||
#include "config_wgldisplay.cxx"
|
||||
#include "wglGraphicsBuffer.cxx"
|
||||
#include "wglGraphicsPipe.cxx"
|
||||
#include "wglGraphicsStateGuardian.cxx"
|
||||
#include "wglGraphicsWindow.cxx"
|
||||
|
Loading…
x
Reference in New Issue
Block a user