CMilby
CMilby

Reputation: 644

OpenGL ES Texture Not Rendering

I am attempting to render a texture to a plane with OpenGL ES on an iPhone. I have worked with OpenGL before but I'm not sure why this isn't working.

When I run the code the plane is rendered as a black square and not a textured square. I believe the problem may be when loading the texture although I see no errors when I run the code.

Hopefully someone will spot a problem and be able to help. Thanks in advance.

Here is my code for the mesh.

// Mesh loading
- ( id ) init {
    if ( self = [ super init ] ) {
        glGenVertexArraysOES( 1, &m_vertexArray );
        glBindVertexArrayOES( m_vertexArray );

        glGenBuffers( 1, &m_vertexBuffer );
        glBindBuffer( GL_ARRAY_BUFFER, m_vertexBuffer );
        glBufferData( GL_ARRAY_BUFFER, sizeof( g_vertices ), g_vertices, GL_STATIC_DRAW );

        glGenBuffers( 1, &m_texCoordBuffer );
        glBindBuffer( GL_ARRAY_BUFFER, m_texCoordBuffer );
        glBufferData( GL_ARRAY_BUFFER, sizeof( g_texCoords ), g_texCoords, GL_STATIC_DRAW );
    }
    return self;
}

- ( void ) render {
    glBindBuffer( GL_ARRAY_BUFFER, m_vertexBuffer );
    glVertexAttribPointer( GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 0, ( GLvoid* ) 0 );

    glBindBuffer( GL_ARRAY_BUFFER, m_texCoordBuffer );
    glVertexAttribPointer( GLKVertexAttribTexCoord0, 2, GL_FLOAT, GL_FALSE, 0, ( GLvoid* ) 0 );

    glDrawArrays( GL_TRIANGLES, 0, sizeof( g_vertices ) / sizeof( g_vertices[ 0 ] ) );
}

const GLfloat g_vertices[] = {
    -1.0, -1.0,  0.0,
     1.0,  1.0,  0.0,
    -1.0,  1.0,  0.0,

    -1.0, -1.0,  0.0,
     1.0, -1.0,  0.0,
     1.0,  1.0,  0.0
};

const GLfloat g_texCoords[] = {
    0.0, 0.0,
    1.0, 1.0,
    0.0, 1.0,

    0.0, 0.0,
    1.0, 0.0,
    1.0, 1.0
};

I only need a my vertices and tex coords right now so that is all I'm using.

Next is my texture loading.

- ( id ) init: ( NSString* ) filename {
    if ( self = [ super init ] ) {
        CGImageRef spriteImage = [ UIImage imageNamed: filename ].CGImage;
        if ( !spriteImage ) {
            NSLog( @"Failed to load image %@", filename );
            exit( 1 );
        }

        size_t width = CGImageGetWidth( spriteImage );
        size_t height = CGImageGetHeight( spriteImage );

        GLubyte *spriteData = ( GLubyte* ) calloc( width * height * 4, sizeof( GLubyte ) );
        CGContextRef spriteContext = CGBitmapContextCreate( spriteData, width, height, 8, 4 * width, CGImageGetColorSpace( spriteImage ), kCGImageAlphaPremultipliedLast );

        CGContextDrawImage( spriteContext, CGRectMake( 0, 0, width, height ), spriteImage );
        CGContextRelease( spriteContext );

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

        glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
        glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );

        glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, ( GLuint ) width, ( GLuint ) height, 0, GL_RGBA, GL_UNSIGNED_BYTE, spriteData );

        free( spriteData );
    }
    return self;
}

- ( void ) bind {
    glActiveTexture( GL_TEXTURE0 );
    glBindTexture( GL_TEXTURE_2D, m_texture );
}

I used the texture loading code from this tutorial.

Then here is my rendering code.

    - ( void ) glkView: ( GLKView* ) view drawInRect: ( CGRect ) rect {
    glClearColor( 0.65f, 0.65f, 0.65f, 1.0f );
    glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

    glUseProgram( m_shaderProgram );

    [ m_texture bind ];
     glUniform1i( uniforms[ UNIFORM_SAMPLER ], 0 );

    GLKMatrix4 mvp = GLKMatrix4Multiply( GLKMatrix4Multiply( m_projectionMatrix, m_viewMatrix ), m_modelMatrix );

    glUniformMatrix4fv( uniforms[ UNIFORM_MODELVIEWPROJECTION_MATRIX ], 1, 0, mvp.m );

    glEnableVertexAttribArray( GLKVertexAttribPosition );
    glEnableVertexAttribArray( GLKVertexAttribTexCoord0 );

    [ m_plane render ];

    glDisableVertexAttribArray( GLKVertexAttribTexCoord0 );
    glDisableVertexAttribArray( GLKVertexAttribPosition );
}

Vertex shader.

attribute vec3 position;
attribute vec2 texCoord;

varying lowp vec2 texCoord0;

uniform mat4 modelViewProjectionMatrix;

void main()
{
    texCoord0 = texCoord;
    gl_Position = modelViewProjectionMatrix * vec4( position, 1.0 );
}

And lastly fragment shader.

varying lowp vec2 texCoord0;

uniform sampler2D sampler;

void main()
{
    gl_FragColor = texture2D( sampler, texCoord0.st );
}

Upvotes: 0

Views: 179

Answers (1)

Prabindh
Prabindh

Reputation: 3504

As mentioned in the comment, you can check with a Power of Two (POT) texture. In addition, there are extensions that enable support for NonPOT (NPOT) textures like GL_IMG_texture_npot, refer to the discussion in this thread (Non power of two textures in iOS), and this thread (http://aras-p.info/blog/2012/10/17/non-power-of-two-textures/).

Upvotes: 1

Related Questions