2013-06-20 19 views
5

Tôi đang sử dụng iOS 6.1.4, OpenGL ES 2 và đang gặp phải hành vi lạ với glGenTextures trả về kết cấu "tên" trước đây đã được trả lại bởi glGenTextures.glGenTextures Trả lại Tên Kết cấu Hiện có

Cụ thể, vào thời điểm khởi, tôi lặp thông qua kết cấu của tôi và làm cho OpenGL nhận thức của họ, như thế này:

// 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); 
} 

Tại thời điểm này, tôi thấy tên texture như 1, 2, 3, ... n như mong đợi.

Tuy nhiên, đôi khi sau (sau khi cuộc gọi mạng không đồng bộ trả về), tôi tạo họa tiết mới và gọi installIntoOpenGLObject3D: để cài đặt chúng. Đó là vào thời điểm này sau khi tôi thấy glGenTextures trả lại tên đã được phát hành trước đó. Rõ ràng điều này khiến ứng dụng hiển thị kết cấu không chính xác.

Các tài liệu, http://www.khronos.org/opengles/sdk/docs/man/xhtml/glGenTextures.xml, gợi ý rằng:

tên Texture trả về bởi một cuộc gọi đến glGenTextures không được trả về bởi các cuộc gọi tiếp theo, trừ khi chúng được xóa đầu tiên với glDeleteTextures.

và tôi không thực hiện cuộc gọi nào tới glDeleteTextures; tuy nhiên, tài liệu cũng cho biết:

đảm bảo rằng không có tên trả lại nào được sử dụng ngay trước cuộc gọi đến glGenTextures.

gây nhầm lẫn, vì nó ngụ ý rằng tên được trả về có thể giống nhau nếu chúng không được "sử dụng". Để hiểu biết của tôi, bằng cách gọi glBindTexture cho kết cấu thỏa mãn khái niệm "đang sử dụng", nhưng có điều gì đó sai.

Một ý nghĩ khác mà tôi có lẽ là EAGLContext đang thay đổi một nơi nào đó giữa tập đầu tiên của cuộc gọi thành glGenTextures nhưng, than ôi, bước qua trong trình gỡ lỗi cho tôi biết ngữ cảnh không thay đổi.

Là một giải pháp hack (có lẽ ngu ngốc), tôi đã cố gắng đảm bảo tên kết cấu là duy nhất, như bạn có thể thấy bên dưới, tuy nhiên tôi chỉ đơn giản là kết thúc với tên kết cấu mà tôi không theo dõi. kết cấu, do đó, cách tiếp cận này không cung cấp giải pháp thay thế:

- (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); 
} 

Bất kỳ suy nghĩ nào về lý do tại sao glGenTextures đang trả lại tên mà trước đây quay trở lại?

+0

Ồ, và tôi quên đề cập đến lệnh gọi 'glIsTexture' trong' do while' luôn trả về false. – levigroker

+0

Chỉ cần breezing thông qua bài viết của bạn làm cho tôi nghĩ rằng bạn đang sử dụng nhiều chủ đề mà bạn làm điều này. Bạn có thể cố gắng buộc tải kết cấu sau, để được trên cùng một chủ đề như lần tải đầu tiên và báo cáo nếu sự cố vẫn tiếp diễn.(mỗi chủ đề nên tạo bối cảnh riêng của nó và nếu bạn muốn chia sẻ nội dung giữa các ngữ cảnh, bạn cần sử dụng nhóm chia sẻ) –

+0

Cảm ơn Matic. Tôi đã kiểm tra gấp đôi (triple?) Và lệnh gọi 'glGenTextures' luôn xuất hiện trên chuỗi chính. – levigroker

Trả lời

3

Sau khi gỡ lỗi nhiều, tôi tin rằng nguyên nhân gốc là luồng.

Trong khi tôi chắc chắn glGenTextures chỉ được gọi từ một chủ đề (chính), nó chỉ ra rằng các cuộc gọi đến các phương pháp OpenGL khác đã được gọi trên một chủ đề khác. Tái cấu trúc để các cuộc gọi đến glGenTextures cũng chỉ xảy ra trên chủ đề khác (không chính) dường như giải quyết vấn đề.