opengl es,glActiveTexture

时间:2016-01-14 19:42:21

标签: android qt opengl-es-2.0

我正在Android系统中开发基于Qt 5.4的应用程序。 我正在生成几个OES纹理并通过着色器在Qt FBO TEXTURE_2D中渲染。每个OES纹理都有自己的eglcontext,每个人都有相同的sharedContext。 OES纹理是逐个使用的,我的意思是,我不是要同时渲染多个纹理,但是我需要创建多个纹理,因为我必须能够在同一时间渲染多个纹理。将来

这是我必须更新时使用的代码:

m_program->bind();
glActiveTexture(GL_TEXTURE0 + textureId);
glBindTexture(GL_TEXTURE_EXTERNAL_OES, textureId);
/* my code to fill shader attr and glDraw*() */
glBindTexture(GL_TEXTURE_EXTERNAL_OES, 0);
m_program->release();

问题是,出于某种原因,我可以渲染第一个OES纹理,因为我在第二个尝试glActiveTexture时得到W/Adreno-ES20(28468): <core_glActiveTexture:348>: GL_INVALID_ENUM。因此,目标纹理填充为黑色。

我检查了所有这些并且是正确的:

  • textureId
  • 在调用eglCreateContext时的sharedContext。
  • 当前的eglContext渲染时,我的意思是,当调用上面的时候 代码。
  • 第二个OES纹理已填充
  • GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS 16
  • GL_MAX_TEXTURE_IMAGE_UNITS 16
  • GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS 32

我有点失落,我不确定这是我的代码中的限制还是错误。

有什么想法吗?

编辑:试用其他设备,应用程序正常工作,所以我认为问题是关于设备限制..

1 个答案:

答案 0 :(得分:2)

生成纹理时,无法保证id将从零开始或以1递增。因此,您可能不会期望值为[0,1,2,...]并且不能将活动纹理用作{ {1}}。您需要创建自己的自动增量系统,最好通过创建某种纹理对象来生成纹理,分配两个ID等等。

要增加内部ID,您需要做的就是使用一个静态整数值,该值会为您生成的每个纹理增加。这是最基本的系统,你只会在某个时候加载一些纹理然后重复使用它们,假设它们都不应该被释放和重用。其他系统需要包含对已发布纹理的某种跟踪,并能够重用空槽。

因此,对于基础知识,您将拥有一个对象/类,例如:

GL_TEXTURE0 + textureID

现在包含您在代码段中发布的所有功能。如果您愿意,也可以在构造函数中调用方法static GLint currentActiveTextureID = GL_TEXTURE0; class ActiveTextureObject { GLuint textureID; GLenum activeTextureID; void generateNew() { activeTextureID = currentActiveTextureID++; useActive(); glGenTextures(1, &activeTextureID); } void useActive() { glActiveTexture(activeTextureID); } void bind() { glBindTexture(GL_TEXTURE_2D, textureID); } void bindAndUseActive() { useActive(); bind(); } }; 。正如您所看到的,该对象将纹理和活动纹理绑定在一起,因此您可以简单地调用generateNew来执行这两项操作。

对于更复杂的系统,您可以使用一组元素来表示活动纹理的插槽。然后,您可以遍历数组以查找空插槽。

bindAndUseActive

现在在这种情况下,您宁愿在某处创建一个池来处理纹理。您可以轻松拥有一个或多个可用于多个上下文的池。最后,最好创建一个包含主上下文并具有纹理池的类。然后,上下文对象还可以为您正在生成的每个纹理创建共享上下文,并且还负责删除,回收纹理和上下文。