OpenGL多重纹理- glActiveTexture为NULL

5

我开始了一个新项目,想要在其中使用多重纹理。我以前做过多重纹理,并且我的OpenGL版本支持它。

在头文件中我有:

GLuint  m_TerrainTexture[3];//heightmap, texture map and detail map
GLuint  m_SkyboxTexture[5]; //left, front, right, back and top textures

PFNGLMULTITEXCOORD2FARBPROC glMultiTexCoord2fARB;
PFNGLACTIVETEXTUREARBPROC   glActiveTexture;

在构造函数中,我有以下内容:
glActiveTexture = (PFNGLACTIVETEXTUREARBPROC) wglGetProcAddress((LPCSTR)"glActiveTextureARB");
glMultiTexCoord2fARB = (PFNGLMULTITEXCOORD2FARBPROC) wglGetProcAddress((LPCSTR)"glMultiTexCoord2fARB");

if(!glActiveTexture || !glMultiTexCoord2fARB)
{
    MessageBox(NULL, "multitexturing failed", "OGL_D3D Error", MB_OK);
}

glActiveTexture( GL_TEXTURE0_ARB );
...

这会显示一个名为“多重纹理失败”的消息框,以及glActiveTexture的内容为0x00000000。

当执行glActiveTexture( GL_TEXTURE0_ARB );时,我遇到了访问冲突错误。

我正在实现MVC图示,因此所有这些都在我的地形视图类中。


1
你确定在调用所有这些时有一个当前的GL上下文吗? - genpfault
我已经 #included <windows.h>, <gl\gl.h>, <gl\glu.h> 和 "glext.h",有什么我漏掉的吗? - Tim Orton
你有检查过 glGetString(GL_EXTENSIONS) 的内容吗?这是唯一可靠的方法来了解支持什么和不支持什么。你还应该检查 glGetString(GL_RENDERER) 和 glGetString(GL_VENDOR)。很可能,你的程序会陷入软件光栅化模式。 - datenwolf
它们都返回一个错误指针 - 表达式无法评估。 我不知道什么是软件光栅化模式... - Tim Orton
@Tim:你要找的是GL_ARB_multitexture。但是我现在注意到了一些东西。看看我的回答(虽然我不知道那是否真的是你的问题)。 - datenwolf
显示剩余2条评论
4个回答

1

你引用了以下代码来加载扩展:

PFNGLMULTITEXCOORD2FARBPROC glMultiTexCoord2fARB;
PFNGLACTIVETEXTUREARBPROC   glActiveTexture;

glActiveTexture = (PFNGLACTIVETEXTUREARBPROC) wglGetProcAddress((LPCSTR)"glActiveTextureARB");
glMultiTexCoord2fARB = (PFNGLMULTITEXCOORD2FARBPROC) wglGetProcAddress((LPCSTR)"glMultiTexCoord2fARB");

这是非常有问题的,因为它可能会重新定义已经存在的符号。 (动态) 链接器最终会遇到这个问题。例如,指针变量 glActiveTexture 的赋值可能会进入某个位置,但每当调用同名函数时,它就会调用从其他地方链接进来的东西。

在 C 中,通常使用预处理器宏和自定义前缀的组合来避免这个问题,而不必调整大量的代码。

PFNGLMULTITEXCOORD2FARBPROC myglMultiTexCoord2fARB;
#define glMultiTexCoord2fARB myglMultiTexCoord2fARB

PFNGLACTIVETEXTUREARBPROC   myglActiveTexture;
#define glActiveTexture myglActiveTexture

glActiveTexture = (PFNGLACTIVETEXTUREARBPROC) wglGetProcAddress((LPCSTR)"glActiveTextureARB");
glMultiTexCoord2fARB = (PFNGLMULTITEXCOORD2FARBPROC) wglGetProcAddress((LPCSTR)"glMultiTexCoord2fARB");

如果您已经激活了有效的渲染上下文并支持扩展,我真的不知道为什么其他事情会失败。


我的渲染上下文在main.cpp中,这会有影响吗?main.cpp调用了使用多重纹理的对象的初始化器。 我似乎也无法让GLuint纹理正常工作?我包含了所有正确的文件,但是wglGetProcAddress、glGenTextures和glBindTexture都会失败,有什么原因吗? - Tim Orton
1
glGenTextures失败的唯一原因是,在调用glGenTextures时没有有效的渲染上下文。你使用多线程了吗?如果是这样,请注意,一个渲染上下文一次只能在一个线程中激活。你可以通过首先释放一个线程中的上下文,然后再在另一个线程中将其设置为当前来切换线程。 - datenwolf
不,我没有使用多线程。 我唯一能想到的是我设置的方式,这是我第一次实现MVC。我首先在我的主函数中初始化渲染上下文,然后创建对象。GL代码位于MVC的视图层中。渲染上下文不能被作用域所覆盖。 如果您认为我初始化渲染上下文不正确,您能否向我展示一个网站,以便我学习如何正确地初始化它? - Tim Orton
@datenwolf:好的,我想我发现问题所在了;我是在 main() 方法之前初始化对象,在那里创建渲染上下文。我把它们初始化在 main() 方法外部,这样其他方法就可以看到它们——render()、idle() 等等... 我该如何安排使得渲染上下文先被调用呢? - Tim Orton
1
渲染上下文(render context)是由你自己创建(wglCreateContext, wglMakeContextCurrent),或者使用的库创建的。比如GLUT在glutCreateWindow中创建,SDL在SDL_SetVideoMode等函数中创建。所有需要上下文的操作必须在其创建之后完成。对于你的类,如果不知道它们的工作原理,很难确定在哪里以及如何放置它们。请至少提供一个详尽的例子。 - datenwolf
显示剩余3条评论

1

GLEE是一个已经停止更新很长时间的库。

GLEW是一个很好的扩展加载库,但在核心3.2及以上版本中存在一些问题。

我建议使用GL3W。它的美妙之处在于它是自动更新的;它会自己下载和解析头文件。缺点是你需要安装Python 2.6来生成加载器。但除此之外,它提供了相当不错的结果。


0

我建议使用GLEW/GLEE进行扩展管理。


1
不能保证。在像Windows这样的系统上,系统OpenGL库只有基本1.2函数的入口点,您必须自己加载所有其他函数指针。 - yuriks
...而GLEW/GLEE会为您处理所有这些 :) - genpfault
我刚刚尝试使用glee,但好像没有起作用。我需要初始化glMultiTexCoord2fARB和glActiveTexture吗? - Tim Orton

0

Rastertek教程提供了完整的设置,使wglGetProcAddress正常工作。 GLEW对我也不起作用,我尝试了我能想到的一切,并向许多人询问过,但它在VS 2012中根本无法工作,更不用说当我想编译着色器时所经历的巨大挫折。


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