Sign in to follow this  
nick5454

OpenGL help with quads for sprites in TextureAtlas

Recommended Posts

I have a texture atlas with 3 sprite images horizontally.
 
What I am trying to do is only display the first sprite ( 1/3 of the x axis )
 
I assume that when I load the texture I specify the quad for the entire and then I can define an additional quad that is 1/3. I am guessing that is wrong and I just load the texture and specify the quad at 1/3.

 

I am using GHLKit for iphone ( wrapper for openGL ). Can anyone tell me why I can't just show the first sprite and it always shows my entire atlas?

 

Here is my quad defined:

    TexturedQuad newQuad;
    newQuad.bl.geometryVertex = CGPointMake(0, 0);
    newQuad.br.geometryVertex = CGPointMake(self.textureInfo.width, 0);
    newQuad.tl.geometryVertex = CGPointMake(0, self.textureInfo.height);
    newQuad.tr.geometryVertex = CGPointMake(self.textureInfo.width, self.textureInfo.height);

    newQuad.bl.textureVertex = CGPointMake(0, 1);
    newQuad.br.textureVertex = CGPointMake(.3, 1);
    newQuad.tl.textureVertex = CGPointMake(0, 0);
    newQuad.tr.textureVertex = CGPointMake(.3, 0);
    
    self.quad = newQuad;

 

The problem is this just shows the image stretched and not cropped

 

Here is the sprite code:

- (void)setSprite:(NSString *)fileName effect:(GLKBaseEffect *)newEffect {

    // 1
    self.effect = newEffect;
        
    // 2
    NSDictionary * options = [NSDictionary dictionaryWithObjectsAndKeys:
                                  [NSNumber numberWithBool:YES],
                                  GLKTextureLoaderOriginBottomLeft,
                                  nil];
        
    // 3
    NSError * error;
    NSString *path = [[NSBundle mainBundle] pathForResource:fileName ofType:nil];
    
    // 4
    self.textureInfo = [GLKTextureLoader textureWithContentsOfFile:path options:options error:&error];
    if (self.textureInfo == nil) {
        NSLog(@"Error loading file: %@", [error localizedDescription]);
            return ;
    }

    TexturedQuad newQuad;
    newQuad.bl.geometryVertex = CGPointMake(0, 0);
    newQuad.br.geometryVertex = CGPointMake(self.textureInfo.width/3, 0);
    newQuad.tl.geometryVertex = CGPointMake(0, self.textureInfo.height);
    newQuad.tr.geometryVertex = CGPointMake(self.textureInfo.width/3, self.textureInfo.height);

    newQuad.bl.textureVertex = CGPointMake(0, 1);
    newQuad.br.textureVertex = CGPointMake(.3, 1);
    newQuad.tl.textureVertex = CGPointMake(0, 0);
    newQuad.tr.textureVertex = CGPointMake(.3, 0);
    
    self.quad = newQuad;

}

 

the render method:

- (void)render {
    
    // 1
    self.effect.texture2d0.name = self.textureInfo.name;
    self.effect.texture2d0.enabled = YES;
    
    // 2
    y++;
    self.effect.transform.modelviewMatrix = self.modelMatrix;
    [self.effect prepareToDraw];
    
    // 3
    glEnableVertexAttribArray(GLKVertexAttribPosition);
    glEnableVertexAttribArray(GLKVertexAttribTexCoord0);
    

    // 4
    long offset = (long)&_quad;
    glVertexAttribPointer(GLKVertexAttribPosition, 2, GL_FLOAT, GL_FALSE, sizeof(TexturedVertex), (void *) (offset + offsetof(TexturedVertex, geometryVertex)));
    glVertexAttribPointer(GLKVertexAttribTexCoord0, 2, GL_FLOAT, GL_FALSE, sizeof(TexturedVertex), (void *) (offset + offsetof(TexturedVertex, textureVertex)));
    
    // 5
    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
    
}
 

setup projection

- (void)setupGL
{
    [EAGLContext setCurrentContext:self.context];
    
    self.effect = [[GLKBaseEffect alloc] init];
    
    GLKMatrix4 projectionMatrix = GLKMatrix4MakeOrtho(0, 480, 320, 0, -1, 1);
    self.effect.transform.projectionMatrix = projectionMatrix;
    
    [self setSprite:@"NinjaSpriteSheet.png" effect:self.effect ];

}

Share this post


Link to post
Share on other sites
You have posted completely incoherent code. Texture width and 1/3 texture width are two different sprite sizes, and neither matches texture coordinates of 0 to 0.3.

Moreover, you aren't showing a true texture alias in which sprite geometry and texture coordinates are loaded from files or otherwise passed from outside, only one-off geometry with a painful amount of constants: that's why you can get coordinates wrong.

If the sprite is W*H pixels and it begins at (u0,v0) in a U*V atlas texture, you should draw a suitably translated and rotated W*H quad (x: 0 to W, y: 0 to H) with texture coordinates u from u0/U to (u0+W)/U and v from v0/V to (v0+H)/V (edges and rounding left as an exercise).

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this