我有一个简单的GLKViewcontroller子类,在被告知时呈现纹理。这本身就很好用,正是我需要它做的。但是,出于某种原因,当我试图在一个场景中使用它时,我一次有6个相同视图控制器的副本(设置为指向同一视图的容器视图),它不起作用。我有一个加载和显示纹理方法来选择从加载纹理的地图绘制哪个纹理。似乎只有我加载纹理的最后一个视图才能正确绘制它们,其余部分显示为黑色方块。
这是我的故事板的截图:
这是我的加载和绘制代码:
-(void)glkView:(GLKView *)view drawInRect:(CGRect)rect
{
[EAGLContext setCurrentContext:self.context];
self.view.backgroundColor = [UIColor clearColor];
self.view.opaque = NO;
glClearColor(0, 0, 0, 0);
glClear(GL_COLOR_BUFFER_BIT);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);
//sprite render:
if ( self.showTexture )
{
if ( firstDraw )
{
self.imageShowTime = [ATAppDelegate getCurrentTime];
firstDraw = NO;
}
self.effect.texture2d0.name = selectedTexture.name;
self.effect.texture2d0.enabled = YES;
self.effect.transform.modelviewMatrix = self.modelMatrix;
[self.effect prepareToDraw];
long offset = (long)&_quad;
glEnableVertexAttribArray(GLKVertexAttribPosition);
glEnableVertexAttribArray(GLKVertexAttribTexCoord0);
glVertexAttribPointer(GLKVertexAttribPosition, 2, GL_FLOAT, GL_FALSE, sizeof(TexturedVertex), (void *) (offset + offsetof(TexturedVertex, geometryVertex)));
glVertexAttribPointer(GLKVertexAttribTexCoord0, 2, GL_FLOAT, GL_FALSE, sizeof(TexturedVertex), (void *) (offset + offsetof(TexturedVertex, textureVertex)));
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
}
else
{
firstDraw = YES;
}
}
-(void)loadTextures:(NSArray *)textureNames
{
if ( textures == nil )
{
textures = [[NSMutableDictionary alloc] init];
}
[textures removeAllObjects];
NSDictionary * options = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithBool:YES],
GLKTextureLoaderOriginBottomLeft,
nil];
NSError * error;
for ( NSString *texName in textureNames )
{
NSString *path = [[NSBundle mainBundle] pathForResource:texName ofType:nil];
GLKTextureInfo *newTex = [GLKTextureLoader textureWithContentsOfFile:path options:options error:&error];
if ( newTex == nil || error != nil )
{
NSLog(@"Error loading file: %@", [error localizedDescription]);
return ;
}
NSLog(@"Loaded texture: %@ for name: %@", newTex, texName);
CGSize contentSize = CGSizeMake(newTex.width, newTex.height);
NSDictionary *texInfo = @{@"texture" : newTex, @"contentSize" : [NSValue valueWithCGSize:contentSize]};
textures[texName] = texInfo;
}
}
-(void)showTexture:(NSString *)texture
{
NSDictionary *texInfo = textures[texture];
if ( texInfo == nil )
{
NSLog(@"ERROR: no texture info found for texture name :%@ in %@", texture, textures);
}
else
{
NSLog(@"Showing texture: %@", texInfo);
}
selectedTexture = texInfo[@"texture"];
curContentSize = [texInfo[@"contentSize"] CGSizeValue];
}
问题很可能出在openGL上下文中。事情是每个控制器将创建每个自己的上下文,每个必须在任何,绘图,呈现,纹理加载使用之前设置。
我从不使用像GLKView
或GLKViewController
这样的胡说八道。问题是纹理只在一个上下文中加载,您需要为每个上下文(视图控制器)加载它们,或者找到一种方法从其中一个控制器创建一个包含共享组的上下文:您创建一个上下文,您可以从中获取共享组,然后使用此共享组(上下文属性)初始化新上下文。结果是新上下文可以使用诸如在主上下文上创建的纹理之类的元素,反之亦然。更大的问题可能是这些控制器正在使用openGL进行一些额外的工作,并且在执行此操作之前不会重置上下文。
无论如何使用openGL制作多个视图应该可以正常工作,所以我希望你找到一个很好的解决方案来解决你的问题。也许您需要做的就是将当前上下文设置在loadTextures
方法的顶部。