GLKit:处理大型3D对象时的透明纹理

时间:2015-06-09 17:10:43

标签: ios objective-c opengl-es glkit

我正在编写一个显示.obj文件的3D查看器,并通过以下2个Raywenderlich教程提供一些基本手势(固定,旋转,缩放):  http://www.raywenderlich.com/48293/how-to-export-blender-models-to-opengl-es-part-1

http://www.raywenderlich.com/50398/opengl-es-transformations-gestures

我能够正确加载和显示小的.obj文件,但对于大的.obj文件,纹理突然变得透明!我已经使用相同的纹理文件进行了测试,因此我认为图像大小不是原因。请查看下面的屏幕截图以了解一下:

Big obj:大约20000个顶点 Big obj: about 20000 vertices

小obj:大约5000个顶点: Small obj: about 5000 vertices

相当大的obj:大约67000个顶点: Quite big obj: about 67000 vertices

只有2种颜色(蓝色和黄色)的纹理位图,用于大而大的objs A texture bitmap with only 2 colors (blue and yellow) which are used in big objs

胶囊纹理(我不使用2种颜色纹理,这样我们可以清楚地看到小obj没有透明度) The capsule texture

我在不同的obj上尝试了不同的纹理,它总是同样的问题:当obj文件很大时,纹理开始变得透明。我还测试了不同的物理Iphone,因此它不是模拟器特有的。启用/禁用gl_blend既不能解决问题。

您可以在http://pastecode.org/index.php/view/32247978找到完整的代码 这是我用来创建GLKBaseEffect和加载纹理图像的代码:

// Initialize
self.effect = [[GLKBaseEffect alloc] init];

// Texture
NSDictionary* options = @{ GLKTextureLoaderOriginBottomLeft: @YES };
NSError* error;
NSString* path = [[NSBundle mainBundle] pathForResource:@"capsule0.jpg" ofType:nil];

GLKTextureInfo* texture = [GLKTextureLoader textureWithContentsOfFile:path
                                                              options:options
                                                                error:&error];

if(texture == nil)
    NSLog(@"Error loading file: %@", [error localizedDescription]);

self.effect.texture2d0.name = texture.name;
self.effect.texture2d0.enabled = true;
self.effect.texture2d0.envMode = GLKTextureEnvModeReplace;


// Light
self.effect.light0.enabled = GL_TRUE;
self.effect.light0.position = GLKVector4Make(1.0f, 1.0f, 1.0f, 1.0f);
self.effect.lightingType = GLKLightingTypePerVertex;

此部分用于在创建效果后在viewDidLoad()中设置OpenGL:

// OpenGL ES Settings
glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
glEnable(GL_CULL_FACE);
glEnable(GL_DEPTH_TEST);

1 个答案:

答案 0 :(得分:0)

我终于找到了解决方案:

首先,您需要在GLKView的故事板中将深度格式设置为24或16: enter image description here

然后通过

启用viewDidLoad()中的深度
    glEnable(GL_DEPTH_TEST);

最后,对于每个绘制调用,您需要清除深度缓冲区:

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);