注释掉 glfwWindowHint() 使代码起作用(带有 GLFW 的 OpenGL),为什么?

Commenting out glfwWindowHint() makes code functional (OpenGL with GLFW), why?

抱歉,我对这个问题的正确名称有点问题,但是我 运行 遇到了障碍,我想至少知道来源。

我一直在努力学习 openGL,并且正在学习本教程: open.gl

有问题的行:

glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);

在完成本教程的过程中,我的代码中出现了访问冲突异常。只有在我注释掉以下几行之后,我才能让程序按照教程所说的那样工作,它应该是第一次工作。本教程对注释掉的行说明如下:

"You'll immediately notice the first three lines of code that are only relevant for this library. It is specified that we require the OpenGL context to support OpenGL 3.2 at the least. The GLFW_OPENGL_PROFILE option specifies that we want a context that only supports the new core functionality."

我的想法是,也许我的驱动程序不支持 OpenGL 3.2 或更高版本,因为当我注释掉有问题的 行时 我的程序 运行 很好。 不过,我下载了一个叫GPU caps viewer的软件。当软件扫描我的硬件时,它说我的 NVIDIA GeForce GT 540M 和 HD Graphics 3000 都支持 OpenGL 4.3。所以我对问题的根源感到非常困惑,我做错了什么,或者这是硬件问题?

以下是 GPU CAPS 和 NVIDIA PORTAL 的快照:2 pictures on imgur

无效:

#include "stdafx.h"  //necessary headers in here


int _tmain(int argc, _TCHAR* argv[])
{
glfwInit();

glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);

GLFWwindow* window = glfwCreateWindow(800, 600, "OpenGL", nullptr, nullptr); // Windowed
glfwMakeContextCurrent(window);

while (!glfwWindowShouldClose(window))
{
    glfwSwapBuffers(window);
    glfwPollEvents();
    if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
        glfwSetWindowShouldClose(window, GL_TRUE);
}
glfwTerminate();
return 0;

}

作品:

#include "stdafx.h" //necessary headers in here


int _tmain(int argc, _TCHAR* argv[])
{
glfwInit();
/**
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);
**/
GLFWwindow* window = glfwCreateWindow(800, 600, "OpenGL", nullptr, nullptr); // Windowed
glfwMakeContextCurrent(window);

while (!glfwWindowShouldClose(window))
{
    glfwSwapBuffers(window);
    glfwPollEvents();
    if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
        glfwSetWindowShouldClose(window, GL_TRUE);
}
glfwTerminate();
return 0;

}

头文件

#pragma once
#define GLEW_STATIC
#include <glew.h>

#include "targetver.h"

#include <stdio.h>
#include <tchar.h>
#include <iostream>
#include <thread>

#define GLFW_INCLUDE_GLU
#include <glfw3.h>

最后想到的一件事是,当我进入 NVIDIA 控制面板时,它显示 Visual Studio 2013 仅使用 Intel HD 3000 显卡。它没有给我使用我的 GeForce 显卡的选项,这可能是问题所在吗?

EditOne: 我尝试通过 windows 资源管理器 运行ning 我的 Visual Studio 2013,方法是右键单击它并选择 "Run with graphics processor...",但无济于事。

感谢您浏览我的问题来帮助我解决问题,如果您自己也有这个问题,我希望它能帮助您解决问题。

问题的实际原因(由 OP 确认)是过时的 and/or 驱动程序功能不全。这再次提醒我们,如果出现 OpenGL 问题,首先应该始终升级到最新版本的图形驱动程序,直接从 GPU 制造商的下载站点获取。

有两个原因:

  1. OEM 驱动程序通常滞后于 GPU 供应商的大量版本。

  2. 更重要的是:通过 Windows 更新安装的驱动程序被 Microsoft 剥夺了适当的 OpenGL 支持,原因只有 Microsoft 知道。


长话短说:您的程序可能会为缺少所需 OpenGL 功能的英特尔高清显卡获取 OpenGL 上下文。因此,当设置这些 GLFW windows 提示时,window 创建失败,并且由于您的程序不检查此错误,它将尝试使用 window,这当然会导致麻烦。

你应该怎么办? 首先添加错误检查! 这是一个如何处理 window 创建失败的示例:

GLFWwindow* window = glfwCreateWindow(
     800,
     600,
     "OpenGL",
     nullptr,
     nullptr);
if( !window ) {
    print_some_error_message();
    exit(-1);
}
glfwMakeContextCurrent(window);

接下来你要强制系统使用NVidia卡。不要那样做"launch through explorer run on NVidia BS";说你把你的程序发给别人?你想把这个负担加在他们身上吗?或者你呢,当你想调试它的时候?

正确执行:告诉系统您想要 运行 在 Optimus 配置中的 NVidia 硬件上。只需 link 将以下内容添加到您的程序中:

extern "C" {
    _declspec(dllexport) DWORD NvOptimusEnablement = 0x00000001;
}

最好把它放在你程序的主要功能旁边,即在你的情况下

#include "stdafx.h"  //necessary headers in here

extern "C" {
    _declspec(dllexport) DWORD NvOptimusEnablement = 0x00000001;
} 

int _tmain(int argc, _TCHAR* argv[])
{
    …