注释掉glfwWindowHint()使代码能够正常工作(使用GLFW的OpenGL),为什么?

4
抱歉,我在翻译这个问题的适当名称时遇到了一些麻烦,但我遇到了一个难题,并希望至少知道其来源。
我一直在尝试学习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);

在按照教程操作时,我的代码发生了访问冲突异常。只有当我把以下代码注释掉后,才能使程序正常工作,就像教程所说的那样。关于被注释掉的代码,教程如下所述:“你会立刻注意到这三行代码仅与该库相关。规定我们需要OpenGL上下文支持至少OpenGL 3.2。 GLFW_OPENGL_PROFILE 选项指定我们要一个仅支持新核心功能的上下文。” 我想也许是因为我的驱动程序不支持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;

}

Works:

#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;

}

Header File

#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显卡的选项,这可能是问题所在吗?

编辑1: 我尝试通过右键单击并选择“使用图形处理器运行”来通过Windows资源管理器运行我的Visual Studio 2013,但没有成功。

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


1
你的Intel HD 3000显卡仅支持Windows上的OGL 3.1和Linux/Mac OS上的3.3(根据此链接)。尝试更改为3.1并将向前兼容性注释掉,看看是否有效。您还可以尝试启动二进制文件(使用3.2/3.3版本编译)而不是通过Visual Studio,而是在Windows资源管理器中找到它,右键单击它,并使用Nvidia显卡运行它(该显卡应至少支持OGL 4.0)。 - RippeR
好的,我尝试使用我的Nvidia显卡通过Windows资源管理器运行它,但仍然无法工作,并且异常仍然被抛出。我该如何将我的OpenGL使用更改为仅限于3.1而不是3.2呢?很抱歉,正如你所看到的,我非常新手。 - Bryan the Lion
1个回答

3
问题的真正原因(已由OP确认)是过时和/或功能不完整的驱动程序。这再次提醒我们,在OpenGL问题的情况下,第一步应该始终是升级到最新版本的图形驱动程序,直接从GPU制造商的下载站点获取。 这样做有两个原因:
  1. OEM驱动程序通常比GPU供应商落后很多个版本。

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


长话短说:您的程序可能会为缺乏请求的OpenGL功能的Intel HD图形获得OpenGL上下文。因此,当设置GLFW窗口提示时,窗口创建失败,由于您的程序未检查此错误,它将尝试使用该窗口,这当然会引起麻烦。
你应该怎么做?首先添加错误检查!下面是一个处理窗口创建失败的示例:
GLFWwindow* window = glfwCreateWindow(
     800,
     600,
     "OpenGL",
     nullptr,
     nullptr);
if( !window ) {
    print_some_error_message();
    exit(-1);
}
glfwMakeContextCurrent(window);

接下来,您希望强制系统使用NVidia显卡。不要用“通过资源管理器启动,在NVidia BS上运行”; 如果您将程序发送给其他人呢?您想把这个负担放到他们身上吗?或者当您想调试它时呢?

正确的方法是:告诉系统您想在Optimus配置中运行于NVidia硬件上。只需将以下内容链接到您的程序中即可:

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[])
{
    …

@BryantheLion:我只是指向前兼容性配置标志。其他标志则是在您的程序对OpenGL配置有明确要求时才有意义,因此建议使用。真正让我惊讶的是,添加NvOptimusEnablement标志并没有起作用。一个建议:您是否将NVidia驱动程序更新到最新版本(从NVidia网站下载而不是通过Windows Update)? - datenwolf
不,我没有直接访问Nvidia官网,我去了Asus官网(我的电脑是Asus),并在那里检查了驱动程序。我发现它们是相同的,所以我没有更改它们,然后我试图通过Windows设备管理器进行更新,但Windows显示我的驱动程序已经是最新版本。我会按照你的建议前往Nvidia官网查看,然后再告诉你。请问可以具体说明一下前向兼容性配置文件标志吗? - Bryan the Lion
嘿!我去了NVidia网站,从那里更新了我的驱动程序,然后它就可以用了!你能把这个加到你的答案里面吗?这样别人就更容易找到我需要做什么,谢谢。完成后请告诉我,我会接受你的答案。 - Bryan the Lion
@BryantheLion:更新了我的回答:请阅读更新,因为它可能会给你带来意想不到的信息(主要是关于微软作为微软的情况)。 - datenwolf
谢谢。我想点赞,但我还没有足够的声望。祝你有美好的一天! - Bryan the Lion
显示剩余6条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接