用于显示图像的opengles问题

时间:2010-12-16 09:54:41

标签: iphone ipad opengl-es textures

我使用xcode Opengl App模板来创建示例。 我是opengles的新手,不得不尝试重写ES1Renderer.m中的'render'方法 我尝试创建一个纹理并在屏幕上显示它,但没有显示。 有人可以帮帮我吗?我不知道如何解决它:

- (void)render
{

    int imageW = 16;
    int imageH = 16;
    GLubyte *textureData = (GLubyte *) malloc(imageW * imageH << 2);

    for (int i = 0; i < imageW * imageH << 2; i++) {
        textureData[i]= 0xff & i;
    }

    GLuint textureId;

    glGenTextures(1, &textureId); 
    glBindTexture(GL_TEXTURE_2D, textureId);

    // when texture area is small, bilinear filter the closest mipmap
    glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
                    GL_LINEAR  );
    // when texture area is large, bilinear filter the original
    glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );

    // the texture wraps over at the edges (repeat)
    glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
    glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
    glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);

    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, imageW, imageH, 0, GL_RGBA, GL_UNSIGNED_BYTE, textureData);

    GLenum err = glGetError();
    if (err != GL_NO_ERROR)
        NSLog(@"Error uploading texture. glError: 0x%04X", err);

    free(textureData);


    float x = 10.0f;
    float y = 10.0f;
    float z = 0.0f;

    float scaleX = 1.0f;
    float scaleY = 1.0f;
    float scaleZ = 1.0f;

    int w = imageW /2;
    int h = imageH /2;

    const GLfloat squareVertices[] = {
        -w, -h,
        w, -h,
        -w,  h,
        w,  h,
    };

    const GLfloat textureCoords[] = {
        0, 0,
        1, 0,
        0, 1,
        1, 1,
    };

    glEnable(GL_TEXTURE_2D);
    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
    glEnableClientState(GL_VERTEX_ARRAY);

    glBindTexture(GL_TEXTURE_2D, textureId);

    glVertexPointer(2, GL_FLOAT, 0, squareVertices);
    glTexCoordPointer(2, GL_FLOAT, 0, textureCoords);

    glPushMatrix();
    glTranslatef(x, y, z);
    glScalef(scaleX, scaleY, scaleZ);
    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
    glPopMatrix();


    glDisable(GL_TEXTURE_2D);
    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
    glDisableClientState(GL_VERTEX_ARRAY);


    NSLog(@"-->");
    glDeleteTextures(1, &textureId);

    // This application only creates a single color renderbuffer which is already bound at this point.
    // This call is redundant, but needed if dealing with multiple renderbuffers.
    glBindRenderbufferOES(GL_RENDERBUFFER_OES, colorRenderbuffer);
    [context presentRenderbuffer:GL_RENDERBUFFER_OES];
}

1 个答案:

答案 0 :(得分:2)

可悲的是,Xcode提供的OpenGL模板在某些时候发生了变化 - 当前代码(从Xcode 3.2.5开始,使用'OpenGL ES Application'模板创建iOS应用程序)不再提供单独的ES1Renderer.m和ES2Renderer .m,更喜欢提供单个简化的EAGLView.m并在GLTestViewController.m中执行运行时测试。考虑到这一点,我修改了GLTestViewController.m的awakeFromNib不再尝试获取ES 2上下文:

- (void)awakeFromNib
{
    EAGLContext *aContext = nil;//[[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];

    if (!aContext)
    {
        aContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES1];
    }

    if (!aContext)
        NSLog(@"Failed to create ES context");
    else if (![EAGLContext setCurrentContext:aContext])
        NSLog(@"Failed to set ES context current");

    self.context = aContext;
    [aContext release];

    [(EAGLView *)self.view setContext:context];
    [(EAGLView *)self.view setFramebuffer];

    if ([context API] == kEAGLRenderingAPIOpenGLES2)
        [self loadShaders];

    animating = FALSE;
    animationFrameInterval = 1;
    self.displayLink = nil;
}

将代码的相关部分复制并粘贴到drawFrame中:

- (void)drawFrame
{
    [(EAGLView *)self.view setFramebuffer];

    // Replace the implementation of this method to do your own custom drawing.
    static const GLfloat squareVertices[] = {
        -0.5f, -0.33f,
        0.5f, -0.33f,
        -0.5f,  0.33f,
        0.5f,  0.33f,
    };

    const GLfloat textureCoords[] = {
        0, 0,
        1, 0,
        0, 1,
        1, 1,
    };
    static float transY = 0.0f;

    glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT);

    int imageW = 16;
    int imageH = 16;
    GLubyte *textureData = (GLubyte *) malloc(imageW * imageH << 2);

    for (int i = 0; i < imageW * imageH << 2; i++) {
        textureData[i]= 0xff & i;
    }

    GLuint textureId;

    glGenTextures(1, &textureId); 
    glBindTexture(GL_TEXTURE_2D, textureId);
    glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR  );
    glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
    glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
    glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
    glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);        
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, imageW, imageH, 0, GL_RGBA, GL_UNSIGNED_BYTE, textureData);
    free(textureData);

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    glTranslatef(0.0f, (GLfloat)(sinf(transY)/2.0f), 0.0f);
    transY += 0.075f;

    glEnable(GL_TEXTURE_2D);

    glVertexPointer(2, GL_FLOAT, 0, squareVertices);
    glEnableClientState(GL_VERTEX_ARRAY);
    glTexCoordPointer(2, GL_FLOAT, 0, textureCoords);
    glEnableClientState(GL_TEXTURE_COORD_ARRAY);

    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

    glDeleteTextures(1, &textureId);

    [(EAGLView *)self.view presentFramebuffer];
}

结果完全按照您的意图行事。猜测是否有可能:

  • 您正在设置除标识之外的其他内容作为投影矩阵,导致几何体被裁剪,因为它位于z = 0处?
  • 您已经忽略了放弃尝试ES 2渲染,导致意外结果,因为纹理渲染等任务与ES 2没有硬件连线,与ES1相同?