使用颜色选择在同一窗口中显示多个OpenGLES视图:glReadPixels不起作用

时间:2012-10-12 16:15:02

标签: objective-c ios opengl-es uiview opengl-es-2.0

我在同一窗口中显示两个带有自己的GLKViewControllers的GLKView。我能够正确显示内容。一个GLK视图包含一半的ipad窗口,另一半由另一个GLKview包含。我正在使用VBO和IBO来渲染我的对象。我也基于这里描述的colorPicking技术检测对象上的触摸(渲染到屏幕外缓冲区并对对象进行颜色编码): OpenGL ES 2.0 Object Picking on iOS

当我触摸view1中的对象(首先被初始化的对象)时,我的应用程序开始崩溃,所以我试图弄清楚出了什么问题。但是,对view2对象的触摸工作正常。崩溃时(在view1中触摸对象时)的错误是 glerunvertexsubmitARM 。在一些研究中,我发现错误与绑定的错误的veretx或索引缓冲区有关。所以我检查了我的对象的bufferIndex和vertexIndex。初始化我的第一个视图后,我的vertexbuffer和索引缓冲区的句柄再次从索引1开始。 根据我的理解,EAGLcontext对此负责。所以现在当我为我的view2生成新的EAGLContext时,我使用相同的EAGLsharegroup初始化它。这使得我的应用程序不再崩溃,而且我看到第二个视图的句柄不以1开头。根据我对EAGLSharegroup的理解,它负责共享资源,如顶点和索引缓冲区对象。 (VBO和IBO就是我在这里所需要的,它阻止我的应用程序崩溃)

但我根本无法有效地发现我的观点。 它很多次都没有读取任何像素,但有时它会读取。 如果我不触摸第一个视图,触摸第二个视图是完全正常的。 除了共享相同的EAGLsharegroup之外,我不确定还需要做什么。 我在下面发布我的代码。

此外,当我只使用一个视图时,一切都顺利而且很好。

触摸检测

-(NSNumber*)findBarbyPoint:(CGPoint)point {



NSInteger height = ((GLKView *)self.view).drawableHeight;
NSInteger width = ((GLKView *)self.view).drawableWidth;

GLubyte *pixelColor = (GLubyte*)malloc(4*sizeof(GLubyte)*1*1);

int k = 4*1*1;

GLuint colorRenderbuffer;
GLuint framebuffer;

glGenFramebuffers(1, &framebuffer);
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
glGenRenderbuffers(1, &colorRenderbuffer);
glBindRenderbuffer(GL_RENDERBUFFER, colorRenderbuffer);

glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8_OES, width, height);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER,  colorRenderbuffer);

GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
if (status != GL_FRAMEBUFFER_COMPLETE) {
    NSLog(@"Framebuffer status: %x", (int)status);
    return 0;
}


glClearColor(0.0f, 0.0f, 0.0f, 1.0f);

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

self.effect.transform.projectionMatrix = ProjectionMatrix;
//can be in a different function

for(int i=0; i<self.numberofBars ;i++)

{

    //Render the object with GLKBaseEffect

    iVBarNode *temp = [theBars objectAtIndex:i];
    NSLog(@"temp properties %f %f %f %f",temp.color.r, temp.color.g, temp.color.b, temp.position.x);

    self.effect.transform.modelviewMatrix = GLKMatrix4Multiply(ViewMatrix,modelMatrix);
    self.effect.transform.modelviewMatrix = GLKMatrix4Multiply(self.effect.transform.modelviewMatrix,temp.modelMatrix);

    self.effect.constantColor = GLKVector4Make(temp.color.r, temp.color.g, temp.color.b, 1.0);


    //bind corresponding buffer before drawing
    glBindBuffer(GL_ARRAY_BUFFER, [temp getVertexID]);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, [temp getIndexID]);

    glEnableVertexAttribArray(GLKVertexAttribPosition);
    glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 6*sizeof(GLfloat), BUFFER_OFFSET(0));
    glEnableVertexAttribArray(GLKVertexAttribNormal);
    glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, 6*sizeof(GLfloat), BUFFER_OFFSET(12));

    [self.effect prepareToDraw];

    glDrawElements(GL_TRIANGLES, [temp.bar getIndicesSize], GL_UNSIGNED_SHORT, (void*)0);

    glDisableVertexAttribArray(GLKVertexAttribPosition);
    glDisableVertexAttribArray(GLKVertexAttribNormal);

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
    glBindBuffer(GL_ARRAY_BUFFER, 0);

}
///rendering ends here

CGFloat scale = UIScreen.mainScreen.scale;
glReadPixels(point.x * scale, (height - (point.y * scale)), 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixelColor);

glDeleteRenderbuffers(1, &colorRenderbuffer);
glDeleteFramebuffers(1, &framebuffer);

for(int i=0; i<k; i=i+4)
{
    NSUInteger pixelr = pixelColor[i];NSUInteger pixelg = pixelColor[i+1]; NSUInteger pixelb = pixelColor[i+2];
    NSUInteger pixela = pixelColor[i+3];

    NSLog(@"read pixel = %d %d %d %d", pixelr, pixelg, pixelb, pixela);
}

return [NSNumber numberWithUnsignedChar:pixelColor[0]];


}

这是我为第二个视图(view2)初始化EAGLContext的方法。

 EAGLSharegroup *shareGRp = [[EAGLContext currentContext] sharegroup];

self.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2 sharegroup:shareGRp];

下面是生成veretx和索引缓冲区的代码,我将它们保存在带有类函数的实用程序类中,以生成我的VBO和IBO的句柄。

+ (GLuint) createBufferFromArray:(GLfloat*)array size:(int)size {
// set up buffer to store array
GLuint bufferIndex;
glGenBuffers(1, &bufferIndex);
glBindBuffer(GL_ARRAY_BUFFER, bufferIndex);

// Copy data from local memory
glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(size* sizeof(GLfloat)), array, GL_STATIC_DRAW);

GLenum err = glGetError();
if (err != GL_NO_ERROR) {
    NSLog(@"Error creating buffer %i. glError: 0x%04X", bufferIndex, err);
}
NSLog(@"bufferIndex=%d", bufferIndex);

return bufferIndex;
}

+ (GLuint) createBufferFromElementArray:(GLushort*)array size:(int)size {
// set up buffer to store array
GLuint bufferIndex;
glGenBuffers(1, &bufferIndex);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, bufferIndex);

// Copy data from local memory
glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)(size * sizeof(GLushort)), array, GL_STATIC_DRAW);

GLenum err = glGetError();
if (err != GL_NO_ERROR) {
    NSLog(@"Error creating buffer %i. glError: 0x%04X", bufferIndex, err);
}
NSLog(@"bufferIndex=%d", bufferIndex);

return bufferIndex;
}

0 个答案:

没有答案