使用OpenGL核心功能和扩展

时间:2014-10-12 08:52:53

标签: opengl

我想在我的程序中使用DXT压缩纹理,所以我正在加载核心函数指针,如下所示:

/* GL 1.3 core */
PFNGLCOMPRESSEDTEXIMAGE2DPROC       glCompressedTexImage2D      = NULL;

/* ... */

/* check GL version using glGetString(GL_VERSION) */

/* ... */

glCompressedTexImage2D = (PFNGLCOMPRESSEDTEXIMAGE2DPROC)wglGetProcAddress(
                "glCompressedTexImage2D");
if (!glCompressedTexImage2D)
return 0;

/* check if GL_EXT_texture_compression_s3tc is available */

之后,我使用这样的功能:

glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, width,
                    height, 0, size, ptr);

它运作良好,但我怀疑的原因是我被告知我不能将OpenGL核心函数与这样的扩展函数混合:

glGenBuffersARB(1, &id);
glBindBuffer(GL_ARRAY_BUFFER, id);

或者,带有令牌的核心功能通过某种扩展添加,如下所示:

glActiveTexture(GL_TEXTURE0_ARB);

但我正在使用glCompressedTexImage2D(核心功能)和GL_COMPRESSED_RGB_S3TC_DXT1_EXT(由GL_EXT_texture_compression_s3tc添加的令牌)。

那么,是否可以使用未添加到核心的扩展(例如GL_EXT_texture_compression_s3tc或WGL_EXT_swap_control等扩展)函数/令牌以及核心功能?

2 个答案:

答案 0 :(得分:2)

通常,不建议将核心和扩展定义混合使用相同的功能,这是一个很好的建议。通常,扩展会被提升为核心功能,具有相同的定义,并且不是问题。但有些情况下,核心功能与扩展中定义的相同功能的早期版本并不完全相同。

一个常见的例子是FBO(帧缓冲对象)。在将FBO作为OpenGL 3.0中的核心功能引入之前,有许多与FBO功能相关的不同扩展,其中一些扩展与最终作为核心功能的扩展并不完全相同。因此,为FBO混合较旧的扩展和核心定义将是一个坏主意。

然而,在这种特殊情况下,它完全没问题。预计许多/大多数压缩纹理格式都是扩展。其中许多是特定于供应商的,涉及专利,因此它们很可能永远不会成为核心功能。规范适应了这一点。 glCompressedTexImage2D()的一些规范引用明确指出:

  

internalformat必须是受支持的特定压缩内部格式。

     

对于所有其他压缩内部格式,压缩图像将根据定义内部格式令牌的规范进行解码。

     

特定压缩内部格式可能会对使用压缩图像规范调用或参数施加格式特定限制。

EXT_texture_compression_s3tc的扩展程序定义也确认COMPRESSED_RGB_S3TC_DXT1_EXT可用作glCompressedTExImage2D()的参数:

This extension introduces new tokens:

    COMPRESSED_RGB_S3TC_DXT1_EXT                   0x83F0
    COMPRESSED_RGBA_S3TC_DXT1_EXT                  0x83F1
    COMPRESSED_RGBA_S3TC_DXT3_EXT                  0x83F2
    COMPRESSED_RGBA_S3TC_DXT5_EXT                  0x83F3

In OpenGL 1.2.1 these tokens are accepted by the <internalformat> parameter
of TexImage2D, CopyTexImage2D, and CompressedTexImage2D and the <format>
parameter of CompressedTexSubImage2D.

也可以在不查询扩展名的情况下获得支持的压缩纹理格式列表。您可以使用glGetIntegerv()枚举它们:

GLint numFormats = 0;
glGetIntegerv(GL_NUM_COMPRESSED_TEXTURE_FORMATS, &numFormats);
GLint* formats = new GLint[numFormats];
glGetIntegerv(GL_COMPRESSED_TEXTURE_FORMATS, formats);

这会直接为您提供glCompressedTexImage2D()接受的格式列表。

答案 1 :(得分:1)

完全可以在核心中使用扩展。核心概况只是意味着,从过去的某些残余已被移除,核心。但是,您的OpenGL上下文报告的所有内容都在glGetStringi报告的扩展字符串中可用,可以从该上下文中合法使用。任何不符合“核心”的扩展都不会出现在纯核心环境中。

纹理压缩也是核心配置文件中高度关注的扩展之一。见https://www.opengl.org/wiki/OpenGL_Extension#Targeting_OpenGL_3.3