客户端程序中的 glewInit() 和 GLEW_ARB_xxx_ 失败
Posted
技术标签:
【中文标题】客户端程序中的 glewInit() 和 GLEW_ARB_xxx_ 失败【英文标题】:glewInit() and GLEW_ARB_xxx_ failure in client program 【发布时间】:2014-12-01 20:41:51 【问题描述】:我编写了一个使用 glew 初始化 OpenGL 上下文的 DLL。首先,我创建了一个虚拟窗口来创建适当的上下文。其次,创建最终的上下文和窗口。
glewInit()
函数调用成功,一些布尔变量,如 GLEW_ARB_texture_storage
设置为 1(我有一个与 opengl 3.3 兼容的视频适配器)。
注意
glewExperimental=GL_TRUE
虽然。
但是,当我使用上面的 DLL 编写客户端程序时,相同的 GLEW_ARB_texture_storage
变量等于 GL_FALSE
。
因此,我想知道最终应该在哪里调用 glewInit()
?
似乎从 DLL 调用它是不够的。我也应该从客户端程序端调用它吗?
【问题讨论】:
【参考方案1】:我实际上不会从您的虚拟上下文中初始化 GLEW。考虑手动加载您需要手动创建最终上下文的一两个扩展(例如WGL_ARB_create_context
和WGL_ARB_pixel_format
)。当您创建两个不同的上下文时,不能保证在 Windows 上获得相同的 ICD 实现。这就是创建 GLEW MX 的原因。
现在,我怀疑您的情况实际上并不是您获得了两个不同的 ICD(这在现实世界中极为罕见),而是实际上您创建的第一个上下文是兼容性配置文件,而第二个是一个核心配置文件。
GLEW 使用扩展字符串初始化变量,例如GLEW_ARB_texture_storage
,但在核心配置文件中,GLEW 不够聪明,无法正确解析该字符串(多次调用glGetStringi (...)
)。这就是为什么你必须使用GLEW_EXPERIMENTAL
。
GLEW_EXPERIMNETAL
告诉 GLEW 尝试加载它知道的每个扩展的每个函数指针,而无需首先解析任何扩展字符串以检查可用性。这在核心配置文件中是必要的,但在兼容性方面不是(因为旧的扩展字符串机制在兼容性方面仍然有效)。任何依赖解析扩展字符串的 GLEW 部分都无法在核心配置文件中正常工作。
【讨论】:
好的。它是否也解释了为什么 glGetString(GL_EXTENSIONS) 在创建虚拟上下文时返回一个有效字符串而在创建最终上下文时返回一个 NULL 指针? @Zyend:是的,不仅如此。但是当您在最终上下文中调用它时,它也会生成GL_INVALID_ENUM
。在调用它之前和之后检查glGetError (...)
。
你说得对,Andon,第一个创建的上下文是兼容性配置文件,第二个是核心配置文件。将 GLEW_EXPERIMENTAL 设置为 GL_TRUE 可以解决我图书馆方面的问题。但是,在客户端程序中,例如,我无法测试 GLEW_ARB_texture_storage。而在 DLL 端这个变量 = GL_TRUE。我将我的 DLL 更改为静态库......它在那里工作。
但是,尽管在 glGetString(GL_EXTENSIONS) 中找到了 GL_EXT_direct_state_access,但 GLEW_EXT_direct_state_access 怎么可能等于 FALSE?【参考方案2】:
我编写了一个使用 glew 初始化 OpenGL 上下文的 DLL
这不是 GLEW 所做的。 GLEW 不初始化 OpenGL 上下文,GLEW 加载 OpenGL 扩展函数地址并用它们初始化函数指针。您必须调用 GLEW,并在调用 glewInit()
的线程中创建预先存在的 OpenGL 上下文并使其成为当前上下文。
您的程序在某处创建了一个 OpenGL 上下文,然后显然调用了glewInit()
。而且从您描述的方式来看,您的DLL可能只是通过DllMain
入口函数调用glewInit()
,该函数在加载DLL时调用,通常在进程WinMain
或/main
函数之前调用,因此尚未创建 OpenGL 上下文。当然,您可以在 DLL 中创建 OpenGL 上下文,但您必须问问自己,这对 DLL 的用户是否有意义。
【讨论】:
你好。在我的 DLL 中,我当然在调用 glewInit() 之前创建了一个相应的窗口和一个有效的 opengl 上下文。以上是关于客户端程序中的 glewInit() 和 GLEW_ARB_xxx_ 失败的主要内容,如果未能解决你的问题,请参考以下文章