diff --git a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx index 6159dd5cfb..476e1af9f1 100644 --- a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx +++ b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx @@ -6835,10 +6835,9 @@ show_gl_string(const string &name, GLenum id) { const GLubyte *text = glGetString(id); if (text == (const GLubyte *)NULL) { - if (GLCAT.is_debug()) { - GLCAT.debug() - << "Unable to query " << name << "\n"; - } + GLCAT.warning() + << "Unable to query " << name << "\n"; + } else { result = (const char *)text; if (GLCAT.is_debug()) { @@ -6859,20 +6858,60 @@ void CLP(GraphicsStateGuardian):: query_gl_version() { _gl_vendor = show_gl_string("GL_VENDOR", GL_VENDOR); _gl_renderer = show_gl_string("GL_RENDERER", GL_RENDERER); + _gl_version = show_gl_string("GL_VERSION", GL_VERSION); _gl_version_major = 0; _gl_version_minor = 0; + // This is the most preposterous driver bug: NVIDIA drivers will claim + // that the version is 1.2 as long as the process is named pview.exe! +#ifndef OPENGLES + if (_gl_version.substr(0, 10) == "1.2 NVIDIA") { + Filename exec_name = ExecutionEnvironment::get_binary_name(); + if (cmp_nocase(exec_name.get_basename(), "pview.exe") == 0) { + glGetIntegerv(GL_MAJOR_VERSION, &_gl_version_major); + glGetIntegerv(GL_MINOR_VERSION, &_gl_version_minor); + + if (glGetError() == GL_INVALID_ENUM) { + _gl_version_major = 1; + _gl_version_minor = 2; + GLCAT.warning() + << "Driver possibly misreported GL_VERSION! Unable to detect " + "correct OpenGL version.\n"; + + } else if (_gl_version_major != 1 || _gl_version_minor != 2) { + GLCAT.debug() + << "Driver misreported GL_VERSION! Correct version detected as " + << _gl_version_major << "." << _gl_version_minor << "\n"; + } + return; + } + } +#endif + + // If we asked for a GL 3 context, let's first try and see if we + // can use the OpenGL 3 way to query version. + if (gl_version.get_num_words() > 0 && gl_version[0] >= 3) { + glGetIntegerv(GL_MAJOR_VERSION, &_gl_version_major); + glGetIntegerv(GL_MINOR_VERSION, &_gl_version_minor); + + if (_gl_version_major >= 1) { + // Fair enough, seems to check out. + if (GLCAT.is_debug()) { + GLCAT.debug() + << "Detected OpenGL version: " + << _gl_version_major << "." << _gl_version_minor << "\n"; + } + return; + } + } + + // Otherwise, parse the GL_VERSION string. + if (_gl_version.empty()) { + GLCAT.error() << "Unable to detect OpenGL version\n"; - const GLubyte *text = glGetString(GL_VERSION); - if (text == (const GLubyte *)NULL) { - GLCAT.warning() - << "Unable to query GL_VERSION\n"; } else { - string version((const char *)text); - _gl_version = version; - - string input = version; + string input = _gl_version; // Skip any initial words that don't begin with a digit. while (!input.empty() && !isdigit(input[0])) { @@ -6904,7 +6943,7 @@ query_gl_version() { if (GLCAT.is_debug()) { GLCAT.debug() - << "GL_VERSION = " << version << ", decoded to " + << "GL_VERSION decoded to: " << _gl_version_major << "." << _gl_version_minor << "\n"; } diff --git a/panda/src/wgldisplay/wglGraphicsStateGuardian.cxx b/panda/src/wgldisplay/wglGraphicsStateGuardian.cxx index e89ce1fdb6..236ab57a77 100644 --- a/panda/src/wgldisplay/wglGraphicsStateGuardian.cxx +++ b/panda/src/wgldisplay/wglGraphicsStateGuardian.cxx @@ -47,6 +47,8 @@ wglGraphicsStateGuardian(GraphicsEngine *engine, GraphicsPipe *pipe, _supports_wgl_multisample = false; _supports_wgl_render_texture = false; + _wglCreateContextAttribsARB = NULL; + get_gamma_table(); atexit(atexit_function); } @@ -345,6 +347,14 @@ choose_pixel_format(const FrameBufferProperties &properties, get_extra_extensions(); _supports_pixel_format = has_extension("WGL_ARB_pixel_format"); _supports_wgl_multisample = has_extension("WGL_ARB_multisample"); + + if (has_extension("WGL_ARB_create_context")) { + _wglCreateContextAttribsARB = + (PFNWGLCREATECONTEXTATTRIBSARBPROC)wglGetProcAddress("wglCreateContextAttribsARB"); + } else { + _wglCreateContextAttribsARB = NULL; + } + _extensions.clear(); if (!_supports_pixel_format) { @@ -614,7 +624,34 @@ make_context(HDC hdc) { // Attempt to create a context. wglGraphicsPipe::_current_valid = false; - _context = wglCreateContext(hdc); + + if (_wglCreateContextAttribsARB != NULL) { + // We have a fancier version of wglCreateContext that allows us + // to specify what kind of OpenGL context we would like. + int attrib_list[32]; + int n = 0; + attrib_list[0] = NULL; + + if (gl_version.get_num_words() > 0) { + attrib_list[n++] = WGL_CONTEXT_MAJOR_VERSION_ARB; + attrib_list[n++] = gl_version[0]; + if (gl_version.get_num_words() > 1) { + attrib_list[n++] = WGL_CONTEXT_MINOR_VERSION_ARB; + attrib_list[n++] = gl_version[1]; + } + } + if (gl_debug) { + attrib_list[n++] = WGL_CONTEXT_FLAGS_ARB; + attrib_list[n++] = WGL_CONTEXT_DEBUG_BIT_ARB; + } + attrib_list[n++] = WGL_CONTEXT_PROFILE_MASK_ARB; + attrib_list[n++] = WGL_CONTEXT_CORE_PROFILE_BIT_ARB; + attrib_list[n] = NULL; + + _context = _wglCreateContextAttribsARB(hdc, 0, attrib_list); + } else { + _context = wglCreateContext(hdc); + } if (_context == NULL) { wgldisplay_cat.error() diff --git a/panda/src/wgldisplay/wglGraphicsStateGuardian.h b/panda/src/wgldisplay/wglGraphicsStateGuardian.h index 4fa70b2a46..b76dac9578 100644 --- a/panda/src/wgldisplay/wglGraphicsStateGuardian.h +++ b/panda/src/wgldisplay/wglGraphicsStateGuardian.h @@ -118,6 +118,8 @@ public: PFNWGLRELEASETEXIMAGEARBPROC _wglReleaseTexImageARB; PFNWGLSETPBUFFERATTRIBARBPROC _wglSetPbufferAttribARB; + PFNWGLCREATECONTEXTATTRIBSARBPROC _wglCreateContextAttribsARB; + public: static TypeHandle get_class_type() { return _type_handle; diff --git a/panda/src/wgldisplay/wglGraphicsWindow.cxx b/panda/src/wgldisplay/wglGraphicsWindow.cxx index 0ddcdb208a..43a3d5a480 100644 --- a/panda/src/wgldisplay/wglGraphicsWindow.cxx +++ b/panda/src/wgldisplay/wglGraphicsWindow.cxx @@ -304,8 +304,18 @@ open_window() { // Initializes _colormap setup_colormap(pixelformat); + // Make sure we have a context created. + HGLRC context = wglgsg->get_context(_hdc); + if (!context) { + // The context failed to create for some reason. + wgldisplay_cat.error() + << "Closing window because no valid context is available.\n"; + close_window(); + return false; + } + // Initialize the gsg. - wglGraphicsPipe::wgl_make_current(_hdc, wglgsg->get_context(_hdc), &_make_current_pcollector); + wglGraphicsPipe::wgl_make_current(_hdc, context, &_make_current_pcollector); wglgsg->reset_if_new(); wglgsg->report_my_gl_errors(); if (!wglgsg->get_fb_properties().verify_hardware_software