views:

61

answers:

2

What I want to achieve:

  • Drawing png files with alpha exactly as it appears originally, without transforming any pixel. This is because the image is very detailed and I don't want to lose any bit of information.
  • Animating those images by rotating them and moving. No scaling.

Actually I don't want to use any 3rd party libraries like cocos2d. I have been reading blogs about OpenGL ES, also checked Texture2D.m so I have basic idea about drawing primitives in 3D space. As far as I understand if I need to draw and animate an image(sprite?) I can just make rectangle and map texture. But the problem is that I want my png file appear exactly as original, not scaled or rotated.

What is the best technique to achieve points mentioned above? Drawing textured rectangle in orthogonal viewport? How to preserve original size/color of image?

Sorry if question is a bit messed up, I can clarify.

A: 

By your description, I don't understand why you'd use OpenGL ES. Using Quartz and layers would enable 1) drawing PNGs 2) rotating and moving them (even scaling if you wished). It would be easier than setting up an orthogonal projection in OpenGL + handling loading of images.

Now, if you really want to go OpenGL, yes, you should setup an orthogonal projection, with view size strictly equal to the screen size, and draw a rectangle of the exact size, with texture mapped with exact 0/1 coordinates. For the color aspect, you can use 8888 format, which is exact, no compression, no color reduction and with full alpha.

jv42
@jv42: The reason I want to use OpenGL is that later I may add some particle or other effects from OpenGL. I'm not sure how well Quartz2D can be mixed with OpenGL or is it good practice at all.
Michael
I have been told that mixing Quartz2D and OpenGL is not good practice. That being said, I have successfully done it in several apps.
Joe Cannatti
OK then go ahead and setup an ortho projection. It's a lot of boilerplate code, but not really difficult.
jv42
@jv42: Do I have to use lights?
Michael
Not really. You can have a default ambient white light which won't alter your images.
jv42
A: 

I know you said you don't want to use a third party library, but Cocos2D implements 2D graphics with OpenGL, so you can reference CCSprite.m to see how they did it. That said, you may want to consider if this library is appropriate for your application. In order to do your own 3D rendering all you have to do is extend CCSprite and put in your own code, as you can see in the comment below the state is already setup for you and everything.

CCSprite.m:

-(void) draw
{   
    NSAssert(!usesBatchNode_, @"If CCSprite is being rendered by CCSpriteBatchNode, CCSprite#draw SHOULD NOT be called");

    // Default GL states: GL_TEXTURE_2D, GL_VERTEX_ARRAY, GL_COLOR_ARRAY, GL_TEXTURE_COORD_ARRAY
    // Needed states: GL_TEXTURE_2D, GL_VERTEX_ARRAY, GL_COLOR_ARRAY, GL_TEXTURE_COORD_ARRAY
    // Unneeded states: -

    BOOL newBlend = NO;
    if( blendFunc_.src != CC_BLEND_SRC || blendFunc_.dst != CC_BLEND_DST ) {
        newBlend = YES;
        glBlendFunc( blendFunc_.src, blendFunc_.dst );
    }

#define kQuadSize sizeof(quad_.bl)
    glBindTexture(GL_TEXTURE_2D, [texture_ name]);

    long offset = (long)&quad_;

    // vertex
    NSInteger diff = offsetof( ccV3F_C4B_T2F, vertices);
    glVertexPointer(3, GL_FLOAT, kQuadSize, (void*) (offset + diff) );

    // color
    diff = offsetof( ccV3F_C4B_T2F, colors);
    glColorPointer(4, GL_UNSIGNED_BYTE, kQuadSize, (void*)(offset + diff));

    // tex coords
    diff = offsetof( ccV3F_C4B_T2F, texCoords);
    glTexCoordPointer(2, GL_FLOAT, kQuadSize, (void*)(offset + diff));

    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

    if( newBlend )
        glBlendFunc(CC_BLEND_SRC, CC_BLEND_DST);

#if CC_SPRITE_DEBUG_DRAW
    CGSize s = [self contentSize];
    CGPoint vertices[4]={
        ccp(0,0),ccp(s.width,0),
        ccp(s.width,s.height),ccp(0,s.height),
    };
    ccDrawPoly(vertices, 4, YES);
#endif // CC_TEXTURENODE_DEBUG_DRAW

}
Winder