gpt4 book ai didi

iphone - OpenGL ES 2.0 和 iOS 中的异步纹理加载和共享组

转载 作者:行者123 更新时间:2023-12-01 18:21:08 24 4
gpt4 key购买 nike

我正在尝试创建一个 GLKView,在其中添加立方体并绘制它们。问题是,每个立方体都是 NSObject 类型,并且有自己的顶点和纹理缓冲区,但我想在单个上下文中绘制它们。为了做到这一点,我关注了一些 WWDC 视频并创建了两个上下文,一个用于渲染,一个用于纹理加载,我将它们放在同一个共享组中。在代码方面,我在这方面所做的是向我的 GLKView 添加一个名为 renderContext 的属性,我希望在其中绘制所有立方体,并且我还设置了一个 loaderContext 属性,我想在其中加载纹理。但是,根本没有绘制任何内容,我什么也没看到,有时我会崩溃并出现 GL 错误 0x0500。它曾经可以工作,模型 View 矩阵应该正确设置和一切。异步加载和两个共享上下文的引入导致了问题......

这是代码:

这是 GLKView:容器(包含多维数据集)

- (void)setupGL {

self.renderContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
self.loaderContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2 sharegroup:self.renderContext.sharegroup];

glGenFramebuffers(1, &defaultFrameBuffer);
glBindFramebuffer(GL_FRAMEBUFFER, defaultFrameBuffer);

glGenRenderbuffers(1, &depthBuffer);
glBindRenderbuffer(GL_RENDERBUFFER, depthBuffer);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, self.bounds.size.width, self.bounds.size.height);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthBuffer);

glEnable(GL_DEPTH_TEST);

}



- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect {


self.opaque = NO;

glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

[EAGLContext setCurrentContext:self.renderContext];

for(Cube *cube in self.cubes){

[cube draw];

}


}

每个单独的立方体都这样设置:
-(id)init {


self = [super init];
if(self){

self.effect = [[GLKBaseEffect alloc]init];
self.effect.transform.projectionMatrix = GLKMatrix4MakePerspective(45.0f,0.95f, 0.1f, 2.0f);
self.effect.transform.projectionMatrix = GLKMatrix4Translate(self.effect.transform.projectionMatrix, 0, 0.0, 0.0);
self.effect.transform.modelviewMatrix = GLKMatrix4Translate(self.effect.transform.modelviewMatrix,0,0,-1.3);


glGenBuffers(1, &vertexArray);
glBindBuffer(GL_ARRAY_BUFFER, vertexArray);
glEnableVertexAttribArray(GLKVertexAttribPosition);
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices), Vertices, GL_STATIC_DRAW);
glVertexAttribPointer(GLKVertexAttribPosition,3,GL_FLOAT,GL_FALSE,0,0);

glGenBuffers(1, &texArray);
glBindBuffer(GL_ARRAY_BUFFER, texArray);
glEnableVertexAttribArray(GLKVertexAttribTexCoord0);
glBufferData(GL_ARRAY_BUFFER, sizeof(TexCoords), TexCoords, GL_STATIC_DRAW);
glVertexAttribPointer(GLKVertexAttribTexCoord0, 2, GL_FLOAT, GL_FALSE, 0,0);


}

return self;




}

并有绘制方法:
-(void)draw{


[self.effect prepareToDraw];

self.effect.texture2d0.enabled = YES;


for(int i=0;i<6;i++){

if(i==0)glBindTexture(GL_TEXTURE_2D, frontTexture.name);
if(i==1)glBindTexture(GL_TEXTURE_2D, rightTexture.name);
if(i==2)glBindTexture(GL_TEXTURE_2D, backTexture.name);
if(i==3)glBindTexture(GL_TEXTURE_2D, leftTexture.name);
if(i==4)glBindTexture(GL_TEXTURE_2D, bottomTexture.name);
if(i==5)glBindTexture(GL_TEXTURE_2D, topTexture.name);
glDrawArrays(GL_TRIANGLES, i*6, 6);
}



}

这是我尝试异步加载纹理的方法:

注意:GLKView(容器)是每个单独的立方体的父级,我检索其 loaderContext,它在 renderContext 的共享组中,因此应该正确绘制纹理,对吗?
-(void)loadTextureForTexture:(GLKTextureInfo*)texN withView:(CubeView *)cV{

__block GLKTextureInfo *texName = texN;

EAGLContext *loaderContext = self.parent.loaderContext;
self.textureLoader = [[GLKTextureLoader alloc]initWithSharegroup:loaderContext.sharegroup];
[EAGLContext setCurrentContext:loaderContext];

NSDictionary *options = [NSDictionary dictionaryWithObject:[NSNumber numberWithBool:YES] forKey:GLKTextureLoaderOriginBottomLeft];

dispatch_queue_t loaderQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_queue_t mainQueue = dispatch_get_main_queue();



[self.textureLoader textureWithCGImage:[self imageWithView:cV].CGImage options:options queue:loaderQueue completionHandler:^(GLKTextureInfo *tex, NSError *err){

texName = tex;

if(err)
NSLog(@"%@", err);
else
NSLog(@"no error");

dispatch_async(mainQueue, ^{

[self display];

});

}];
}

最佳答案

看起来您正在做的上下文管理超出了必要的范围:

  • GLKTextureLoader只需要知道哪个 EAGLSharegroup在其中创建纹理。您不必创建 EAGLContext代表它,并且您在代码中创建的已经没有被传递到任何 GLKTextureLoader方法。
  • 您应该不需要手动管理当前 EAGLContext ——事实上,GLKView的文档特别提到您不应从绘图方法内部更改当前上下文。

  • 这样做的最终结果是除了提取 EAGLSharegroup从您现有的上下文中获取 GLKTextureLoader创建时,您应该没有新的上下文管理代码。

    此外,看起来加载纹理的结果永远不会超出 loadTextureForTexture:withView: .您的 texN变量不是通过引用传递给函数的,所以 texName仅对 loadTextureForTexture:withView: 可见和你的纹理加载完成块。曾经 loadTextureForTexture:withView:返回并调用您的完成块,数据消失了。似乎应该有某种 CubeView需要使用 GLKTextureInfo * 调用的 setter你收到了。

    关于iphone - OpenGL ES 2.0 和 iOS 中的异步纹理加载和共享组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17301848/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com