mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-03 02:15:43 -04:00
add show-pbuffers
This commit is contained in:
parent
141852abeb
commit
bbbe8cbf9f
@ -67,3 +67,9 @@ bool gl_force_invalid = config_wgldisplay.GetBool("gl-force-invalid", false);
|
|||||||
// requested. It only affects fullscreen windows.
|
// requested. It only affects fullscreen windows.
|
||||||
bool gl_do_vidmemsize_check = config_wgldisplay.GetBool("gl-do-vidmemsize-check", true);
|
bool gl_do_vidmemsize_check = config_wgldisplay.GetBool("gl-do-vidmemsize-check", true);
|
||||||
|
|
||||||
|
// For now, we fake offscreen rendering without using the
|
||||||
|
// poorly-supported pbuffer extension; we simply render into an
|
||||||
|
// invisible window. Some drivers don't like that, so for these
|
||||||
|
// drivers set show-pbuffers to true to force the window to be visible
|
||||||
|
// so you can at least get some work done.
|
||||||
|
bool show_pbuffers = config_wgldisplay.GetBool("show-pbuffers", false);
|
||||||
|
@ -29,5 +29,6 @@ extern EXPCL_PANDAGL void init_libwgldisplay();
|
|||||||
extern int gl_force_pixfmt;
|
extern int gl_force_pixfmt;
|
||||||
extern bool gl_force_invalid;
|
extern bool gl_force_invalid;
|
||||||
extern bool gl_do_vidmemsize_check;
|
extern bool gl_do_vidmemsize_check;
|
||||||
|
extern bool show_pbuffers;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -103,20 +103,45 @@ void wglGraphicsBuffer::
|
|||||||
begin_flip() {
|
begin_flip() {
|
||||||
if (_gsg != (GraphicsStateGuardian *)NULL) {
|
if (_gsg != (GraphicsStateGuardian *)NULL) {
|
||||||
make_current();
|
make_current();
|
||||||
|
glFinish();
|
||||||
|
|
||||||
if (has_texture()) {
|
if (has_texture()) {
|
||||||
// Use glCopyTexImage2D to copy the framebuffer to the texture.
|
// Use glCopyTexImage2D to copy the framebuffer to the texture.
|
||||||
// This appears to be the only way to "render to a texture" in
|
// This appears to be the only way to "render to a texture" in
|
||||||
// OpenGL; there's no interface to make the offscreen buffer
|
// OpenGL; there's no interface to make the offscreen buffer
|
||||||
// itself be a texture.
|
// itself be a texture.
|
||||||
DisplayRegion dr(_x_size, _y_size);
|
PT(DisplayRegion) dr = make_scratch_display_region(_x_size, _y_size);
|
||||||
get_texture()->copy(_gsg, &dr, _gsg->get_render_buffer(RenderBuffer::T_back));
|
get_texture()->copy(_gsg, dr, _gsg->get_render_buffer(RenderBuffer::T_back));
|
||||||
}
|
}
|
||||||
|
|
||||||
SwapBuffers(_window_dc);
|
SwapBuffers(_window_dc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: wglGraphicsBuffer::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 wglGraphicsBuffer::
|
||||||
|
process_events() {
|
||||||
|
GraphicsBuffer::process_events();
|
||||||
|
|
||||||
|
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: wglGraphicsBuffer::close_buffer
|
// Function: wglGraphicsBuffer::close_buffer
|
||||||
// Access: Protected, Virtual
|
// Access: Protected, Virtual
|
||||||
@ -150,13 +175,14 @@ open_buffer() {
|
|||||||
// only are wgl extensions incredibly convoluted to get to, but the
|
// only are wgl extensions incredibly convoluted to get to, but the
|
||||||
// pbuffer extension turned out not be supported on the Intel card I
|
// pbuffer extension turned out not be supported on the Intel card I
|
||||||
// tried it on, and crashed the driver for the nVidia card I tried
|
// tried it on, and crashed the driver for the nVidia card I tried
|
||||||
// it on. And it's not even supported on the software reference
|
// it on. And it's not even supported on the Microsoft software
|
||||||
// implementation. Not a good record.
|
// reference implementation. Not a good record.
|
||||||
|
|
||||||
// In lieu of the pbuffer extension, it appears that rendering to a
|
// In lieu of the pbuffer extension, it appears that rendering to a
|
||||||
// window that is simply never shown works fine.
|
// window that is hidden works fine on some drivers (although it
|
||||||
|
// doesn't work on other drivers).
|
||||||
|
|
||||||
DWORD window_style = WS_POPUP | WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
|
DWORD window_style = WS_POPUP | WS_SYSMENU | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_OVERLAPPEDWINDOW;
|
||||||
|
|
||||||
RECT win_rect;
|
RECT win_rect;
|
||||||
SetRect(&win_rect, 0, 0, _x_size, _y_size);
|
SetRect(&win_rect, 0, 0, _x_size, _y_size);
|
||||||
@ -182,6 +208,11 @@ open_buffer() {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ShowWindow(_window, SW_SHOWNORMAL);
|
||||||
|
if (!show_pbuffers) {
|
||||||
|
ShowWindow(_window, SW_HIDE);
|
||||||
|
}
|
||||||
|
|
||||||
_window_dc = GetDC(_window);
|
_window_dc = GetDC(_window);
|
||||||
|
|
||||||
wglGraphicsStateGuardian *wglgsg;
|
wglGraphicsStateGuardian *wglgsg;
|
||||||
@ -195,9 +226,31 @@ open_buffer() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_is_valid = true;
|
_is_valid = true;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: wglGraphicsBuffer::process_1_event
|
||||||
|
// Access: Private, Static
|
||||||
|
// Description: Handles one event from the message queue.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void wglGraphicsBuffer::
|
||||||
|
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: wglGraphicsBuffer::register_window_class
|
// Function: wglGraphicsBuffer::register_window_class
|
||||||
// Access: Private, Static
|
// Access: Private, Static
|
||||||
@ -217,7 +270,7 @@ register_window_class() {
|
|||||||
// Clear before filling in window structure!
|
// Clear before filling in window structure!
|
||||||
ZeroMemory(&wc, sizeof(WNDCLASS));
|
ZeroMemory(&wc, sizeof(WNDCLASS));
|
||||||
wc.style = CS_OWNDC;
|
wc.style = CS_OWNDC;
|
||||||
wc.lpfnWndProc = DefWindowProc;
|
wc.lpfnWndProc = static_window_proc;
|
||||||
wc.hInstance = instance;
|
wc.hInstance = instance;
|
||||||
wc.lpszClassName = _window_class_name;
|
wc.lpszClassName = _window_class_name;
|
||||||
|
|
||||||
@ -233,10 +286,89 @@ register_window_class() {
|
|||||||
// Function: wglGraphicsBuffer::static_window_proc
|
// Function: wglGraphicsBuffer::static_window_proc
|
||||||
// Access: Private, Static
|
// Access: Private, Static
|
||||||
// Description: This is attached to the window class for all
|
// Description: This is attached to the window class for all
|
||||||
// WinGraphicsWindow windows; it is called to handle
|
// wglGraphicsBuffer windows; it is called to handle
|
||||||
// window events.
|
// window events.
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
LONG WINAPI wglGraphicsBuffer::
|
LONG WINAPI wglGraphicsBuffer::
|
||||||
static_window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
|
static_window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
|
||||||
return DefWindowProc(hwnd, msg, wparam, lparam);
|
return DefWindowProc(hwnd, msg, wparam, lparam);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
if (wglgsg->_supports_pixel_format) {
|
||||||
|
// Get ready to query for a suitable pixel format that meets our
|
||||||
|
// minimum requirements.
|
||||||
|
static const int MAX_ATTRIBS = 128;
|
||||||
|
static const int MAX_PFORMATS = 128;
|
||||||
|
int iattributes[2*MAX_ATTRIBS];
|
||||||
|
float fattributes[2*MAX_ATTRIBS];
|
||||||
|
int nfattribs = 0;
|
||||||
|
int niattribs = 0;
|
||||||
|
// Attribute arrays must be "0" terminated--for simplicity, first
|
||||||
|
// just zero-out the array then fill from left to right.
|
||||||
|
for ( int a = 0; a < 2*MAX_ATTRIBS; a++ )
|
||||||
|
{
|
||||||
|
iattributes[a] = 0;
|
||||||
|
fattributes[a] = 0;
|
||||||
|
}
|
||||||
|
// Since we are trying to create a pbuffer, the pixel format we
|
||||||
|
// request (and subsequently use) must be "pbuffer capable".
|
||||||
|
iattributes[2*niattribs ] = WGL_DRAW_TO_PBUFFER_ARB;
|
||||||
|
iattributes[2*niattribs+1] = true;
|
||||||
|
niattribs++;
|
||||||
|
// We require a minimum of 24-bit depth.
|
||||||
|
iattributes[2*niattribs ] = WGL_DEPTH_BITS_ARB;
|
||||||
|
iattributes[2*niattribs+1] = 24;
|
||||||
|
niattribs++;
|
||||||
|
// We require a minimum of 8-bits for each R, G, B, and A.
|
||||||
|
iattributes[2*niattribs ] = WGL_RED_BITS_ARB;
|
||||||
|
iattributes[2*niattribs+1] = 8;
|
||||||
|
niattribs++;
|
||||||
|
iattributes[2*niattribs ] = WGL_GREEN_BITS_ARB;
|
||||||
|
iattributes[2*niattribs+1] = 8;
|
||||||
|
niattribs++;
|
||||||
|
iattributes[2*niattribs ] = WGL_BLUE_BITS_ARB;
|
||||||
|
iattributes[2*niattribs+1] = 8;
|
||||||
|
niattribs++;
|
||||||
|
iattributes[2*niattribs ] = WGL_ALPHA_BITS_ARB;
|
||||||
|
iattributes[2*niattribs+1] = 8;
|
||||||
|
niattribs++;
|
||||||
|
// Now obtain a list of pixel formats that meet these minimum
|
||||||
|
// requirements.
|
||||||
|
int pformat[MAX_PFORMATS];
|
||||||
|
memset(pformat, 0, sizeof(pformat));
|
||||||
|
unsigned int nformats = 0;
|
||||||
|
if (!wglgsg->_wglChoosePixelFormatARB(_window_dc, iattributes, fattributes,
|
||||||
|
MAX_PFORMATS, pformat, &nformats)) {
|
||||||
|
cerr << "pbuffer creation error: Couldn't find a suitable pixel format.\n";
|
||||||
|
} else {
|
||||||
|
cerr << "Found " << nformats << " formats, selecting " << pformat[0] << "\n";
|
||||||
|
pbformat = pformat[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
HPBUFFERARB _pbuffer;
|
||||||
|
wglMakeCurrent(_window_dc, wglgsg->get_context(_window_dc));
|
||||||
|
wglgsg->reset_if_new();
|
||||||
|
|
||||||
|
cerr << "Creating pbuffer(" << _window_dc << ", " << wglgsg->get_pfnum()
|
||||||
|
<< ", " << _x_size << ", " << _y_size << ", ...)\n";
|
||||||
|
int attrib_list[] = {
|
||||||
|
0,
|
||||||
|
};
|
||||||
|
|
||||||
|
HDC hdc = wglGetCurrentDC();
|
||||||
|
cerr << "current dc = " << hdc << " window dc = " << _window_dc << "\n";
|
||||||
|
_pbuffer = wglgsg->_wglCreatePbufferARB(hdc, pbformat,
|
||||||
|
_x_size, _y_size, attrib_list);
|
||||||
|
cerr << "pbuffer = " << (void *)_pbuffer << "\n";
|
||||||
|
|
||||||
|
if (_pbuffer == NULL) {
|
||||||
|
wgldisplay_cat.error()
|
||||||
|
<< "Attempt to create pbuffer failed.\n";
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
|
|
||||||
#include "pandabase.h"
|
#include "pandabase.h"
|
||||||
#include "graphicsBuffer.h"
|
#include "graphicsBuffer.h"
|
||||||
|
#include "wglExtensions.h"
|
||||||
|
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
|
||||||
@ -44,6 +45,7 @@ public:
|
|||||||
virtual void release_gsg();
|
virtual void release_gsg();
|
||||||
|
|
||||||
virtual void begin_flip();
|
virtual void begin_flip();
|
||||||
|
virtual void process_events();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void close_buffer();
|
virtual void close_buffer();
|
||||||
@ -51,6 +53,7 @@ protected:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
bool make_window();
|
bool make_window();
|
||||||
|
static void process_1_event();
|
||||||
|
|
||||||
static void register_window_class();
|
static void register_window_class();
|
||||||
static LONG WINAPI static_window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam);
|
static LONG WINAPI static_window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user