简体   繁体   中英

Problem with opengles to show an image

I use xcode Opengl App template to create a sample. I am new to opengles, and having to try re-write the 'render' method in ES1Renderer.m I try create a texture and show it on the screen, but nothing showed. Someone can help me ? I have no idea how to fix it:

- (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];
}

Sadly the OpenGL template provided by Xcode has changed at some point — the current code (as of Xcode 3.2.5, creating an iOS Application with the 'OpenGL ES Application' template) no longer supplies a separate ES1Renderer.m and ES2Renderer.m, preferring to provide a single, simplified EAGLView.m and to perform runtime tests within GLTestViewController.m. With that in mind, I modified GLTestViewController.m's awakeFromNib no longer to attempt to get an ES 2 context:

- (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;
}

And copied and pasted relevant portions of your code into 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];
}

The result works entirely as you seem to intend. At a guess, is it possible either that:

  • you're setting something other than the identity as your projection matrix, causing your geometry to be clipped because it is placed at z = 0?
  • you've neglected properly to abandon an attempt at ES 2 rendering, causing unexpected results because tasks like textured rendering aren't hardwired in with ES 2 in the same way that they are with ES1?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM