31 const std::string &name,
46 ~wglGraphicsWindow() {
58 begin_frame_spam(mode);
59 if (_gsg ==
nullptr) {
64 if (wgldisplay_cat.is_spam()) {
66 <<
"Not drawing " <<
this <<
": unexposed.\n";
71 if (wgldisplay_cat.is_spam()) {
73 <<
"Drawing " <<
this <<
": exposed.\n";
77 DCAST_INTO_R(wglgsg, _gsg,
false);
80 nassertr(context,
false);
82 if (!wglGraphicsPipe::wgl_make_current(_hdc, context, &_make_current_pcollector)) {
83 wgldisplay_cat.error()
84 <<
"Failed to make WGL context current.\n";
87 wglgsg->reset_if_new();
89 if (mode == FM_render) {
90 wglgsg->push_group_marker(std::string(
"wglGraphicsWindow ") +
get_name());
91 clear_cube_map_selection();
95 return _gsg->begin_frame(current_thread);
105 end_frame_spam(mode);
107 nassertv(_gsg !=
nullptr);
109 if (mode == FM_render) {
113 _gsg->end_frame(current_thread);
115 if (mode == FM_render) {
117 clear_cube_map_selection();
120 DCAST_INTO_V(wglgsg, _gsg);
121 wglgsg->pop_group_marker();
159 DCAST_INTO_V(wglgsg, _gsg);
162 wglGraphicsPipe::wgl_make_current(_hdc, context, &_make_current_pcollector);
176 if (_hdc !=
nullptr && _flip_ready) {
182 DCAST_INTO_V(wglgsg, _gsg);
185 wglGraphicsPipe::wgl_make_current(_hdc, context, &_make_current_pcollector);
194 void wglGraphicsWindow::
196 if (_gsg !=
nullptr) {
197 wglGraphicsPipe::wgl_make_current(_hdc,
nullptr, &_make_current_pcollector);
200 ReleaseDC(_hWnd, _hdc);
202 WinGraphicsWindow::close_window();
209 bool wglGraphicsWindow::
211 if (!WinGraphicsWindow::open_window()) {
226 DCAST_INTO_R(wglgsg, _gsg,
false);
238 PIXELFORMATDESCRIPTOR pixelformat;
239 DescribePixelFormat(_hdc, pfnum,
sizeof(PIXELFORMATDESCRIPTOR),
244 sprintf(msg,
"Selected GL PixelFormat is #%d", pfnum);
245 print_pfd(&pixelformat, msg);
248 BOOL set_pfnum = SetPixelFormat(_hdc, pfnum, &pixelformat);
252 wgldisplay_cat.error()
253 <<
"SetPixelFormat(" << pfnum <<
") failed; trying "
257 DescribePixelFormat(_hdc, pfnum,
sizeof(PIXELFORMATDESCRIPTOR),
261 sprintf(msg,
"Selected GL PixelFormat is #%d", pfnum);
262 print_pfd(&pixelformat, msg);
265 DescribePixelFormat(_hdc, pfnum,
sizeof(PIXELFORMATDESCRIPTOR),
267 set_pfnum = SetPixelFormat(_hdc, pfnum, &pixelformat);
272 wgldisplay_cat.error()
273 <<
"SetPixelFormat(" << pfnum <<
") failed after window create\n";
279 if (gl_force_invalid) {
280 wgldisplay_cat.error()
281 <<
"Artificially failing window.\n";
288 setup_colormap(pixelformat);
294 wgldisplay_cat.error()
295 <<
"Closing window because no valid context is available.\n";
301 wglGraphicsPipe::wgl_make_current(_hdc, context, &_make_current_pcollector);
302 wglgsg->reset_if_new();
303 wglgsg->report_my_gl_errors();
305 (_fb_properties,wglgsg->get_gl_renderer())) {
318 void wglGraphicsWindow::
319 setup_colormap(
const PIXELFORMATDESCRIPTOR &pixelformat) {
323 if (!(pixelformat.dwFlags & PFD_NEED_PALETTE ||
324 pixelformat.iPixelType == PFD_TYPE_COLORINDEX))
327 n = 1 << pixelformat.cColorBits;
331 logical = (LOGPALETTE*)malloc(
sizeof(LOGPALETTE) +
332 sizeof(PALETTEENTRY) * n);
333 memset(logical, 0,
sizeof(LOGPALETTE) +
sizeof(PALETTEENTRY) * n);
336 logical->palVersion = 0x300;
337 logical->palNumEntries = n;
340 GetSystemPaletteEntries(_hdc, 0, 256, &logical->palPalEntry[0]);
342 if (pixelformat.iPixelType == PFD_TYPE_RGBA) {
343 int redMask = (1 << pixelformat.cRedBits) - 1;
344 int greenMask = (1 << pixelformat.cGreenBits) - 1;
345 int blueMask = (1 << pixelformat.cBlueBits) - 1;
349 for (i = 0; i < n; ++i) {
350 logical->palPalEntry[i].peRed =
351 (((i >> pixelformat.cRedShift) & redMask) * 255) / redMask;
352 logical->palPalEntry[i].peGreen =
353 (((i >> pixelformat.cGreenShift) & greenMask) * 255) / greenMask;
354 logical->palPalEntry[i].peBlue =
355 (((i >> pixelformat.cBlueShift) & blueMask) * 255) / blueMask;
356 logical->palPalEntry[i].peFlags = 0;
360 _colormap = CreatePalette(logical);
363 SelectPalette(_hdc, _colormap, FALSE);
364 RealizePalette(_hdc);
369 typedef enum {Software, MCD, ICD} OGLDriverType;
370 static const char *OGLDrvStrings[3] = {
"Software",
"MCD",
"ICD"};
376 void wglGraphicsWindow::
377 print_pfd(PIXELFORMATDESCRIPTOR *pfd,
char *msg) {
378 if (!wgldisplay_cat.is_debug()) {
382 OGLDriverType drvtype;
383 if ((pfd->dwFlags & PFD_GENERIC_ACCELERATED) &&
384 (pfd->dwFlags & PFD_GENERIC_FORMAT)) {
386 }
else if (!(pfd->dwFlags & PFD_GENERIC_ACCELERATED) && !(pfd->dwFlags & PFD_GENERIC_FORMAT)) {
392 #define PRINT_FLAG(FLG) ((pfd->dwFlags & PFD_##FLG) ? (" PFD_" #FLG "|") : "")
393 wgldisplay_cat.debug()
394 <<
"================================\n";
396 wgldisplay_cat.debug()
397 << msg <<
", " << OGLDrvStrings[drvtype] <<
" driver\n"
398 <<
"PFD flags: 0x" << std::hex << pfd->dwFlags << std::dec <<
" ("
399 << PRINT_FLAG(GENERIC_ACCELERATED)
400 << PRINT_FLAG(GENERIC_FORMAT)
401 << PRINT_FLAG(DOUBLEBUFFER)
402 << PRINT_FLAG(SUPPORT_OPENGL)
403 << PRINT_FLAG(SUPPORT_GDI)
404 << PRINT_FLAG(STEREO)
405 << PRINT_FLAG(DRAW_TO_WINDOW)
406 << PRINT_FLAG(DRAW_TO_BITMAP)
407 << PRINT_FLAG(SWAP_EXCHANGE)
408 << PRINT_FLAG(SWAP_COPY)
409 << PRINT_FLAG(SWAP_LAYER_BUFFERS)
410 << PRINT_FLAG(NEED_PALETTE)
411 << PRINT_FLAG(NEED_SYSTEM_PALETTE)
412 << PRINT_FLAG(SUPPORT_DIRECTDRAW) <<
")\n"
413 <<
"PFD iPixelType: "
414 << ((pfd->iPixelType==PFD_TYPE_RGBA) ?
"PFD_TYPE_RGBA":
"PFD_TYPE_COLORINDEX")
416 <<
"PFD cColorBits: " << (DWORD)pfd->cColorBits
417 <<
" R: " << (DWORD)pfd->cRedBits
418 <<
" G: " << (DWORD)pfd->cGreenBits
419 <<
" B: " << (DWORD)pfd->cBlueBits << std::endl
420 <<
"PFD cAlphaBits: " << (DWORD)pfd->cAlphaBits
421 <<
" DepthBits: " << (DWORD)pfd->cDepthBits
422 <<
" StencilBits: " << (DWORD)pfd->cStencilBits
423 <<
" AccumBits: " << (DWORD)pfd->cAccumBits
A container for the various kinds of properties we might ask to have on a graphics frameBuffer before...
bool verify_hardware_software(const FrameBufferProperties &props, const std::string &renderer) const
Validates that the properties represent the desired kind of renderer (hardware or software).
bool subsumes(const FrameBufferProperties &other) const
Returns true if this set of properties makes strictly greater or equal demands of the framebuffer tha...
This class is the main interface to controlling the render process.
This is a base class for the various different classes that represent the result of a frame of render...
virtual void end_flip()
This function will be called within the draw thread after begin_flip() has been called on all windows...
const FrameBufferProperties & get_fb_properties() const
Returns the framebuffer properties of the window.
get_name
Returns the name that was passed to the GraphicsOutput constructor.
An object to create GraphicsOutputs that share a particular 3-D API.
Encapsulates all the communication with a particular instance of a given rendering backend.
get_unexposed_draw
See set_unexposed_draw().
A thread; that is, a lightweight process.
TypeHandle is the identifier used to differentiate C++ class types.
An abstract base class for glGraphicsWindow and dxGraphicsWindow (and, in general,...
A container for the various kinds of properties we might ask to have on a graphics window before we o...
A tiny specialization on GLGraphicsStateGuardian to add some wgl-specific information.
void choose_pixel_format(const FrameBufferProperties &properties, bool need_pbuffer)
Selects a pixel format for all the windows and buffers that use this gsg.
int get_pfnum() const
Returns the pixel format number chosen for windows that use this context.
bool fail_pfnum()
This is called by wglGraphicsWindow when it finds it cannot use the pfnum determined by the GSG.
const FrameBufferProperties & get_fb_properties() const
Returns the properties of the pixel format that was chosen for this gsg.
HGLRC get_context(HDC hdc)
Returns the GL context associated with the GSG.
virtual bool begin_frame(FrameMode mode, Thread *current_thread)
This function will be called within the draw thread before beginning rendering for a given frame.
virtual void begin_flip()
This function will be called within the draw thread after end_frame() has been called on all windows,...
virtual void end_frame(FrameMode mode, Thread *current_thread)
This function will be called within the draw thread after rendering is completed for a given frame.
virtual void ready_flip()
This function will be called within the draw thread after end_frame() has been called on all windows,...
virtual void end_flip()
This function will be called within the draw thread after begin_flip() has been called on all windows...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.