lev*_*ker 5 textures opengl-es objective-c ios
我在iOS 6.1.4,OpenGL ES 2上,并且遇到了奇怪的行为,glGenTextures返回之前已经返回的纹理"名称" glGenTextures.
具体来说,在初始化时,我遍历我的纹理并让OpenGL知道它们,如下所示:
// Generate the OpenGL texture objects
for (Object3D *object3D in self.objects3D)
{
[self installIntoOpenGLObject3D:object3D];
}
- (void)installIntoOpenGLObject3D:(Object3D *)object3D
{
GLuint nID;
glGenTextures(1, &nID);
Texture *texture = object3D.texture;
texture.identifier = nID;
glBindTexture(GL_TEXTURE_2D, nID);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, [texture width], [texture height], 0, GL_RGBA, GL_UNSIGNED_BYTE, (GLvoid*)[texture pngData]);
ARLogInfo(@"Installed texture '%@' with OpenGL identifier %d", texture.name, texture.identifier);
}
Run Code Online (Sandbox Code Playgroud)
这时,我看到纹理名称就像1, 2, 3, ... n预期的那样.
但是,稍后(在异步网络调用返回之后)我创建新纹理并调用installIntoOpenGLObject3D:以安装它们.正是在这个晚些时候,我看到glGenTextures了先前发出的返回名字.显然,这会导致应用程序呈现不正确的纹理.
文档http://www.khronos.org/opengles/sdk/docs/man/xhtml/glGenTextures.xml表明:
通过调用glGenTextures返回的纹理名称不会被后续调用返回,除非它们首先使用glDeleteTextures删除.
我没有打电话给glDeleteTextures; 但是文档也说:
保证在调用glGenTextures之前没有任何返回的名称被使用.
这是令人困惑的,因为它暗示如果它们没有"使用",返回的名称可能是相同的.据我所知,通过调用glBindTexture纹理满足"使用中"的概念,但是,有些事情是错误的.
我的另一个想法可能EAGLContext是在第一组调用之间的某处改变glGenTextures但是,唉,在调试器中单步调试告诉我上下文没有改变.
作为一个(也许是愚蠢的)黑客的解决方法,我试图确保纹理名称本身就是独一无二的,正如你在下面看到的那样,但是我最终得到了一个我不跟踪的纹理名称,但仍然代表了不同的纹理,所以这个方法不提供解决方法:
- (void)installIntoOpenGLObject3D:(Object3D *)object3D
{
if (!self.object3DTextureIdentifiers)
{
self.object3DTextureIdentifiers = [NSMutableSet set];
}
GLuint nID;
NSNumber *idObj;
do {
glGenTextures(1, &nID);
GLboolean isTexture = glIsTexture(nID);
idObj = [NSNumber numberWithUnsignedInt:nID];
} while ([self.object3DTextureIdentifiers containsObject:idObj]);
[self.object3DTextureIdentifiers addObject:idObj];
Texture *texture = object3D.texture;
texture.identifier = nID;
glBindTexture(GL_TEXTURE_2D, nID);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, [texture width], [texture height], 0, GL_RGBA, GL_UNSIGNED_BYTE, (GLvoid*)[texture pngData]);
ARLogInfo(@"Installed texture '%@' with OpenGL identifier %d", texture.name, texture.identifier);
}
Run Code Online (Sandbox Code Playgroud)
有关为什么glGenTextures返回它之前返回的名字的任何想法?
经过多次调试,我相信根本原因是线程。
虽然我确定glGenTextures只是从一个线程(主线程)调用,但事实证明对其他 OpenGL 方法的调用是在不同的线程上调用的。重构以便调用glGenTextures也仅发生在其他线程(非主线程)上似乎可以解决该问题。
| 归档时间: |
|
| 查看次数: |
1148 次 |
| 最近记录: |