From 53612512d572e132af2fb45e4005afbe10b7bf7a Mon Sep 17 00:00:00 2001 From: rdb Date: Fri, 3 May 2019 14:33:46 +0200 Subject: [PATCH 1/9] glgsg: more reliable check for core/compat profile Fixes #643 --- .../glstuff/glGraphicsStateGuardian_src.cxx | 27 +++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx index 6151a2c00d..3ad8e01428 100644 --- a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx +++ b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx @@ -597,8 +597,31 @@ reset() { query_glsl_version(); #ifndef OPENGLES - bool core_profile = is_at_least_gl_version(3, 2) && - !has_extension("GL_ARB_compatibility"); + // Determine whether this OpenGL context has compatibility features. + bool core_profile = false; + + if (_gl_version_major >= 3) { + if (_gl_version_major > 3 || _gl_version_minor >= 2) { + // OpenGL 3.2 has a built-in way to check this. + GLint profile_mask = 0; + glGetIntegerv(GL_CONTEXT_PROFILE_MASK, &profile_mask); + + if (profile_mask & GL_CONTEXT_CORE_PROFILE_BIT) { + core_profile = true; + } else if (profile_mask & GL_CONTEXT_COMPATIBILITY_PROFILE_BIT) { + core_profile = false; + } else { + core_profile = !has_extension("GL_ARB_compatibility"); + } + } else { + // OpenGL 3.0/3.1. + GLint flags = 0; + glGetIntegerv(GL_CONTEXT_FLAGS, &flags); + if (flags & GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT) { + core_profile = true; + } + } + } if (GLCAT.is_debug()) { if (core_profile) { From 475bd55bb1a9fcdaaf68c02dabcc6ed2370f52f4 Mon Sep 17 00:00:00 2001 From: rdb Date: Fri, 3 May 2019 15:46:01 +0200 Subject: [PATCH 2/9] glgsg: add gl-forward-compatible config variable This is meant to be used alongside gl-version to request a "forward compatible" OpenGL 3.0 or 3.1 context, which removes support for deprecated features such as the fixed-function pipeline. --- panda/src/glstuff/glmisc_src.cxx | 5 +++++ panda/src/glstuff/glmisc_src.h | 1 + panda/src/glxdisplay/glxGraphicsStateGuardian.cxx | 13 ++++++++++++- panda/src/wgldisplay/wglGraphicsStateGuardian.cxx | 13 ++++++++++++- 4 files changed, 30 insertions(+), 2 deletions(-) diff --git a/panda/src/glstuff/glmisc_src.cxx b/panda/src/glstuff/glmisc_src.cxx index 08e200a4a0..49eaf78a69 100644 --- a/panda/src/glstuff/glmisc_src.cxx +++ b/panda/src/glstuff/glmisc_src.cxx @@ -17,6 +17,11 @@ ConfigVariableInt gl_version ("gl-version", "", PRC_DESC("Set this to get an OpenGL context with a specific version.")); +ConfigVariableBool gl_forward_compatible + ("gl-forward-compatible", false, + PRC_DESC("Setting this to true will request a forward-compatible OpenGL " + "context, which will not support the fixed-function pipeline.")); + ConfigVariableBool gl_support_fbo ("gl-support-fbo", true, PRC_DESC("Configure this false if your GL's implementation of " diff --git a/panda/src/glstuff/glmisc_src.h b/panda/src/glstuff/glmisc_src.h index 3c6dd81e7b..415286c674 100644 --- a/panda/src/glstuff/glmisc_src.h +++ b/panda/src/glstuff/glmisc_src.h @@ -41,6 +41,7 @@ // #define GSG_VERBOSE 1 extern EXPCL_GL ConfigVariableInt gl_version; +extern EXPCL_GL ConfigVariableBool gl_forward_compatible; extern EXPCL_GL ConfigVariableBool gl_support_fbo; extern ConfigVariableBool gl_cheap_textures; extern ConfigVariableBool gl_ignore_clamp; diff --git a/panda/src/glxdisplay/glxGraphicsStateGuardian.cxx b/panda/src/glxdisplay/glxGraphicsStateGuardian.cxx index d620427afa..83ea5f2b2f 100644 --- a/panda/src/glxdisplay/glxGraphicsStateGuardian.cxx +++ b/panda/src/glxdisplay/glxGraphicsStateGuardian.cxx @@ -352,9 +352,20 @@ choose_pixel_format(const FrameBufferProperties &properties, attrib_list[n++] = gl_version[1]; } } + int flags = 0; if (gl_debug) { + flags |= GLX_CONTEXT_DEBUG_BIT_ARB; + } + if (gl_forward_compatible) { + flags |= GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB; + if (gl_version.get_num_words() == 0 || gl_version[0] < 2) { + glxdisplay_cat.error() + << "gl-forward-compatible requires gl-version >= 3 0\n"; + } + } + if (flags != 0) { attrib_list[n++] = GLX_CONTEXT_FLAGS_ARB; - attrib_list[n++] = GLX_CONTEXT_DEBUG_BIT_ARB; + attrib_list[n++] = flags; } attrib_list[n] = None; _context = _glXCreateContextAttribs(_display, _fbconfig, _share_context, diff --git a/panda/src/wgldisplay/wglGraphicsStateGuardian.cxx b/panda/src/wgldisplay/wglGraphicsStateGuardian.cxx index c98f12cf48..ed9b0e0b2c 100644 --- a/panda/src/wgldisplay/wglGraphicsStateGuardian.cxx +++ b/panda/src/wgldisplay/wglGraphicsStateGuardian.cxx @@ -609,9 +609,20 @@ make_context(HDC hdc) { attrib_list[n++] = gl_version[1]; } } + int flags = 0; if (gl_debug) { + flags |= WGL_CONTEXT_DEBUG_BIT_ARB; + } + if (gl_forward_compatible) { + flags |= WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB; + if (gl_version.get_num_words() == 0 || gl_version[0] < 2) { + wgldisplay_cat.error() + << "gl-forward-compatible requires gl-version >= 3 0\n"; + } + } + if (flags != 0) { attrib_list[n++] = WGL_CONTEXT_FLAGS_ARB; - attrib_list[n++] = WGL_CONTEXT_DEBUG_BIT_ARB; + attrib_list[n++] = flags; } #ifndef SUPPORT_FIXED_FUNCTION attrib_list[n++] = WGL_CONTEXT_PROFILE_MASK_ARB; From b08e38cf3dfcb2bcfdfad46665202548179a5423 Mon Sep 17 00:00:00 2001 From: rdb Date: Fri, 3 May 2019 16:12:20 +0200 Subject: [PATCH 3/9] deploy-ng: add nag screen warning users who are still on Python 2 See #602 --- direct/src/dist/commands.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/direct/src/dist/commands.py b/direct/src/dist/commands.py index 948891d19d..9ba567f067 100644 --- a/direct/src/dist/commands.py +++ b/direct/src/dist/commands.py @@ -13,6 +13,7 @@ import stat import struct import imp import string +import time import setuptools import distutils.log @@ -30,6 +31,15 @@ if sys.version_info < (3, 0): # Python 3 defines these subtypes of IOError, but Python 2 doesn't. FileNotFoundError = IOError + # Warn the user. They might be using Python 2 by accident. + print("=================================================================") + print("WARNING: You are using Python 2, which will soon be discontinued.") + print("WARNING: Please use Python 3 for best results and continued") + print("WARNING: support after the EOL date of December 31st, 2019.") + print("=================================================================") + sys.stdout.flush() + time.sleep(4.0) + def _parse_list(input): if isinstance(input, basestring): From ea0210640cebe63db93333d13ead2e33ddaff188 Mon Sep 17 00:00:00 2001 From: rdb Date: Fri, 3 May 2019 15:48:51 +0200 Subject: [PATCH 4/9] FilterManager: allow specifying custom fbprops in renderSceneInto Fixes #599 --- direct/src/filter/FilterManager.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/direct/src/filter/FilterManager.py b/direct/src/filter/FilterManager.py index 4150cba568..5696ac9460 100644 --- a/direct/src/filter/FilterManager.py +++ b/direct/src/filter/FilterManager.py @@ -124,7 +124,7 @@ class FilterManager(DirectObject): return winx,winy - def renderSceneInto(self, depthtex=None, colortex=None, auxtex=None, auxbits=0, textures=None): + def renderSceneInto(self, depthtex=None, colortex=None, auxtex=None, auxbits=0, textures=None, fbprops=None): """ Causes the scene to be rendered into the supplied textures instead of into the original window. Puts a fullscreen quad @@ -185,7 +185,10 @@ class FilterManager(DirectObject): # Choose the size of the offscreen buffer. (winx, winy) = self.getScaledSize(1,1,1) - buffer = self.createBuffer("filter-base", winx, winy, texgroup) + if fbprops is not None: + buffer = self.createBuffer("filter-base", winx, winy, texgroup, fbprops=fbprops) + else: + buffer = self.createBuffer("filter-base", winx, winy, texgroup) if (buffer == None): return None @@ -287,7 +290,7 @@ class FilterManager(DirectObject): return quad - def createBuffer(self, name, xsize, ysize, texgroup, depthbits=1): + def createBuffer(self, name, xsize, ysize, texgroup, depthbits=1, fbprops=None): """ Low-level buffer creation. Not intended for public use. """ winprops = WindowProperties() @@ -297,6 +300,9 @@ class FilterManager(DirectObject): props.setRgbColor(1) props.setDepthBits(depthbits) props.setStereo(self.win.isStereo()) + if fbprops is not None: + props.addProperties(fbprops) + depthtex, colortex, auxtex0, auxtex1 = texgroup if (auxtex0 != None): props.setAuxRgba(1) From 541a2a73f0e10ef89d177c742ea4fa48c43c7325 Mon Sep 17 00:00:00 2001 From: rdb Date: Fri, 3 May 2019 15:51:31 +0200 Subject: [PATCH 5/9] showbase: allow attaching default MouseWatcher in attachInputDevice This makes it easier to control GUIs using a gamepad. --- direct/src/showbase/ShowBase.py | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/direct/src/showbase/ShowBase.py b/direct/src/showbase/ShowBase.py index bff3b4652c..c0e6d9dd16 100644 --- a/direct/src/showbase/ShowBase.py +++ b/direct/src/showbase/ShowBase.py @@ -1677,13 +1677,17 @@ class ShowBase(DirectObject.DirectObject): return self.mouseWatcherNode.getModifierButtons().isDown( KeyboardButton.meta()) - def attachInputDevice(self, device, prefix=None): + def attachInputDevice(self, device, prefix=None, gui=False): """ This function attaches an input device to the data graph, which will cause the device to be polled and generate events. If a prefix is given and not None, it is used to prefix events generated by this device, separated by a hyphen. + The gui argument can be set to True (as of Panda3D 1.10.3) to set up + the default MouseWatcher to receive inputs from this device, allowing + it to control user interfaces. + If you call this, you should consider calling detachInputDevice when you are done with the device or when it is disconnected. """ @@ -1694,13 +1698,17 @@ class ShowBase(DirectObject.DirectObject): idn = self.dataRoot.attachNewNode(InputDeviceNode(device, device.name)) # Setup the button thrower to generate events for the device. - bt = idn.attachNewNode(ButtonThrower(device.name)) - if prefix is not None: - bt.node().setPrefix(prefix + '-') + if prefix is not None or not gui: + bt = idn.attachNewNode(ButtonThrower(device.name)) + if prefix is not None: + bt.node().setPrefix(prefix + '-') + self.deviceButtonThrowers.append(bt) assert self.notify.debug("Attached input device {0} with prefix {1}".format(device, prefix)) self.__inputDeviceNodes[device] = idn - self.deviceButtonThrowers.append(bt) + + if gui: + idn.node().addChild(self.mouseWatcherNode) def detachInputDevice(self, device): """ From db00baa230f57486043f2ca33267e665de6d5b8d Mon Sep 17 00:00:00 2001 From: rdb Date: Fri, 3 May 2019 17:52:08 +0200 Subject: [PATCH 6/9] deploy-ng: add link to index for thirdparty wheels This is where we can host wheels for packages that haven't uploaded wheels for all platforms, such as PyYAML and esper. [skip ci] --- direct/src/dist/commands.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/direct/src/dist/commands.py b/direct/src/dist/commands.py index 9ba567f067..e5d9ac4f72 100644 --- a/direct/src/dist/commands.py +++ b/direct/src/dist/commands.py @@ -239,7 +239,9 @@ class build_apps(setuptools.Command): self.requirements_path = os.path.join(os.getcwd(), 'requirements.txt') self.use_optimized_wheels = True self.optimized_wheel_index = '' - self.pypi_extra_indexes = [] + self.pypi_extra_indexes = [ + 'https://archive.panda3d.org/thirdparty', + ] self.file_handlers = {} self.exclude_dependencies = [ # Windows From 54c6eaeb960a404235d87f6d471dce95c1c9879c Mon Sep 17 00:00:00 2001 From: rdb Date: Fri, 3 May 2019 19:21:18 +0200 Subject: [PATCH 7/9] pgui: allow keyboard keys to be added as PGButton click buttons These will respond as clicks not when the mouse cursor is hovering over them, but when they have keyboard focus. Fixes #600 --- panda/src/pgui/pgButton.cxx | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/panda/src/pgui/pgButton.cxx b/panda/src/pgui/pgButton.cxx index d1eba186c0..09a91120d4 100644 --- a/panda/src/pgui/pgButton.cxx +++ b/panda/src/pgui/pgButton.cxx @@ -115,7 +115,11 @@ release(const MouseWatcherParameter ¶m, bool background) { if (has_click_button(param.get_button())) { _button_down = false; if (get_active()) { - if (param.is_outside()) { + // Note that a "click" may come from a keyboard button press. In that + // case, instead of checking that the mouse cursor is still over the + // button, we check whether the item has keyboard focus. + if (param.is_outside() && + (MouseButton::is_mouse_button(param.get_button()) || !get_focus())) { set_state(S_ready); } else { set_state(S_rollover); From 0568312324932552619138f9a9c8beb366c519e3 Mon Sep 17 00:00:00 2001 From: rdb Date: Fri, 3 May 2019 19:41:27 +0200 Subject: [PATCH 8/9] windisplay: add config var to disable Ctrl+V behaviour Fixes #512 --- panda/src/windisplay/config_windisplay.cxx | 5 +++++ panda/src/windisplay/config_windisplay.h | 1 + panda/src/windisplay/winGraphicsWindow.cxx | 2 +- 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/panda/src/windisplay/config_windisplay.cxx b/panda/src/windisplay/config_windisplay.cxx index 6e0ea2406d..62040c553a 100644 --- a/panda/src/windisplay/config_windisplay.cxx +++ b/panda/src/windisplay/config_windisplay.cxx @@ -86,6 +86,11 @@ ConfigVariableBool swapbuffer_framelock ("swapbuffer-framelock", false, PRC_DESC("Set this true to enable HW swapbuffer frame-lock on 3dlabs cards")); +ConfigVariableBool paste_emit_keystrokes +("paste-emit-keystrokes", true, + PRC_DESC("Handle paste events (Ctrl-V) as separate keystroke events for each " + "pasted character.")); + /** * Initializes the library. This must be called at least once before any of * the functions or classes in this library can be used. Normally it will be diff --git a/panda/src/windisplay/config_windisplay.h b/panda/src/windisplay/config_windisplay.h index 3256287f5b..7199b8603d 100644 --- a/panda/src/windisplay/config_windisplay.h +++ b/panda/src/windisplay/config_windisplay.h @@ -31,6 +31,7 @@ extern ConfigVariableBool ime_hide; extern ConfigVariableBool request_dxdisplay_information; extern ConfigVariableBool dpi_aware; extern ConfigVariableBool dpi_window_resize; +extern ConfigVariableBool paste_emit_keystrokes; extern EXPCL_PANDAWIN ConfigVariableBool swapbuffer_framelock; diff --git a/panda/src/windisplay/winGraphicsWindow.cxx b/panda/src/windisplay/winGraphicsWindow.cxx index d3e444cac9..c2e98beb0e 100644 --- a/panda/src/windisplay/winGraphicsWindow.cxx +++ b/panda/src/windisplay/winGraphicsWindow.cxx @@ -1927,7 +1927,7 @@ window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) { // Handle Cntrl-V paste from clipboard. Is there a better way to detect // this hotkey? if ((wparam=='V') && (GetKeyState(VK_CONTROL) < 0) && - !_input_devices.empty()) { + !_input_devices.empty() && paste_emit_keystrokes) { HGLOBAL hglb; char *lptstr; From f25532db78127efd58df34a98d735fc6f9345ad2 Mon Sep 17 00:00:00 2001 From: rdb Date: Fri, 3 May 2019 20:48:51 +0200 Subject: [PATCH 9/9] glgsg: properly handle shader compilation failure Fixes #645 --- panda/src/glstuff/glShaderContext_src.cxx | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/panda/src/glstuff/glShaderContext_src.cxx b/panda/src/glstuff/glShaderContext_src.cxx index 5a7eda65fc..200e39004d 100644 --- a/panda/src/glstuff/glShaderContext_src.cxx +++ b/panda/src/glstuff/glShaderContext_src.cxx @@ -3206,6 +3206,10 @@ glsl_compile_and_link() { valid &= glsl_compile_shader(Shader::ST_compute); } + if (!valid) { + return false; + } + // There might be warnings, so report those. GLSLShaders::const_iterator // it; for (it = _glsl_shaders.begin(); it != _glsl_shaders.end(); ++it) { // glsl_report_shader_errors(*it); }