batch opengl calls

Member
Posts: 166
Joined: 2009.04
Post: #16
kendric Wrote:So if i render a square(2 triangles) and i specify the texture co-ordinates unrotated, and I specify the vertex's each rotated around its center by 45 degrees i will get the exact same thing as if i rotated normally 45 degrees and drew it with un rotated vertexes?

Of course ... well, not exactly because if you rotate texture coordinates you have to make sure your image was designed for that sort of manipulation ( in other words, if you have some details sitting in the corner , with texture rotation, it might get rotated out of 0-1 uv coordinate space and thus become invisible.)
Furthermore, you can’t even attempt to rotate uvs if you are using texture atlases …

On the other hand if you rotate vertices , you will never hit that problem.
Quote this message in a reply
Member
Posts: 306
Joined: 2009.03
Post: #17
Yeah I was asking about just rotating verticies, and leaving the texture cords as normal. I Do use texture atlases. Do you guys basically have your own layer that mimics the model projection basically and then all your renders automatically check that and adjust? Thats what I am thinking of trying.
Quote this message in a reply
Member
Posts: 166
Joined: 2009.04
Post: #18
kendric Wrote:Yeah I was asking about just rotating verticies, and leaving the texture cords as normal. I Do use texture atlases. Do you guys basically have your own layer that mimics the model projection basically and then all your renders automatically check that and adjust? Thats what I am thinking of trying.

I personally use a class ( which I call DynamicRenderable) which is essentially a large vertex/index buffer filled with quads .... anytime I want to draw a quad I simply set relevant values ( vertex coordinates, colors etc ) and adjust the end of array marker ( so that my rendering code knows how many quads within the array need to be rendered)

As far as transformations ... for 3d quads ( essentially camera oriented particles) I use my own code to calculate vertex positions and have them specified in world coordinates and then simply use a regular projection/view OpenGL matrix.

For 2d rendering all my quads simply use screen coordinates ( which requires a specially prepared OpenGL matrix)
Quote this message in a reply
Member
Posts: 306
Joined: 2009.03
Post: #19
I am trying this now. I can't see any info in the documentation for the color array if its per vertex or per shape. I am going to assume per vertex, such that the size of this array should be 2x the size of the vertex and texture array(since it needs 4 values per vertex instead of 2). Also I am assuming that since i have to render 2 triangles, i will have to have a for loop that sets the active color into the next 12 places in the colors array as shown:
Code:
for(int i=0;i<24;i+=4)
    {
        colorVertices[i]=_GGLOptions.r;
        colorVertices[i+1]=_GGLOptions.g;
        colorVertices[i+2]=_GGLOptions.b;
        colorVertices[i+3]=_GGLOptions.a;
    }

24 being 6 vertexes and 4 floats per color
Quote this message in a reply
Member
Posts: 306
Joined: 2009.03
Post: #20
I got this 99% working the good news is my framerate took a HUGE leap from this change. During heavy battle times my frame rate dipped from 60 to 30 at the most hectic of times. This time playing through a level i never saw it go below like 48. The only issue i am having is my hud is dimming randomly. Prob some alpha bug. Once i work that out I will post this code for anyone else who wants a "render queing" engine to use for their game. Its prob not the most perfect code anyone has ever written but I think its fairly good.
Quote this message in a reply
Member
Posts: 166
Joined: 2009.04
Post: #21
kendric Wrote:I got this 99% working the good news is my framerate took a HUGE leap from this change. During heavy battle times my frame rate dipped from 60 to 30 at the most hectic of times. This time playing through a level i never saw it go below like 48. The only issue i am having is my hud is dimming randomly. Prob some alpha bug. Once i work that out I will post this code for anyone else who wants a "render queing" engine to use for their game. Its prob not the most perfect code anyone has ever written but I think its fairly good.

OpenGL is a state machine , once you set something to be on it will continue, so most likely your dimming problem is related to one of your sprite drawing routines not reseting some state properly.
Quote this message in a reply
Member
Posts: 306
Joined: 2009.03
Post: #22
Thats what I thought too but the thing is that hud draws in between 2 other things and all three use this same new single function to do the rendering. I am going to play around with the b color in the rgb to see if i am off by 1. if i am right then setting that hud piece's b color to like 0.1 should make the hud go mostly transparent. If it loses its blue value then that means its not the problem. I also noticed that the change from normal to dim(ie transparent i guess though its possible all three color values are reduced) happens when somethign is added or removed from the screen. Almost like an even odd issue with the total # of projectiles\ships etc.

Finally one last question. The value in glColor4f should have no impact if i am using the colors array right?
Quote this message in a reply
Member
Posts: 306
Joined: 2009.03
Post: #23
So I don't know exactly whats going on with this transparency issue, but color4f does seem to have an impact. If i set it to 1,1,1,1 before every batch render, it fixed one of the 2 hud components but not both. I have no idea why but if anyone has gotten this technique to work correctly with the colors array I would be interested to see if you used color4f at all or what.
Thanks
Quote this message in a reply
Member
Posts: 306
Joined: 2009.03
Post: #24
Wahoo i figured it out. Somewhere i had changed the blend mode prior to doing a textur2d prerendered text render, and in the rexture2d render i had changed it to trigger a batch job since that render has to be done seperatly(due to the seperate blend mode). So my batch job went off after the blend mode was changed and rendered the hud stuff in the wrong mode. It was inconsistent because my text that i am drawing here is not always on the screen. Depends on game conditions. Here below I will post the entire batch draw code. I hope it can help somebody else out. The only thing to keep in mind is if you do any custom rendering, make sure to call the renderData function to ensure the que is emptied out.

Code:
//
//  OpenglUtils.h
//  SubHunt
//
//  Created by Tom Delorenzi on 3/6/09.
//  Copyright 2009 Greyhoundgames. All rights reserved.
//

#define ARC_SEGMENT 0.174532925199433f//(Math.PI / 18.0);

#import <Foundation/Foundation.h>
#import <OpenGLES/EAGL.h>
#import <OpenGLES/ES1/gl.h>
#import <OpenGLES/ES1/glext.h>
#import <OpenGLES/EAGLDrawable.h>

static GLfloat radiansToDegrees(GLfloat radians)
{
    return radians * DEGREES_PER_RADIAN;
}

static GLfloat degreesToRadians(GLfloat degrees)
{
    return degrees/DEGREES_PER_RADIAN;
}


typedef enum _Atlas
{
    Atlas_Units,
    Atlas_Misc,
    Atlas_FrontEnd,
    Atlas_Background,
    
    Atlas_Last
}Atlas;

//for the below struct, I may have the comment for the 2 wrong
//it might be top left and bottom right
typedef struct _AtlasRenderDetails
{
    GLuint textureID;//gl texture id
    CGPoint textureLocationsX1Y1;//pre computed bottom left of the texture
    CGPoint textureLocationsX2Y2;//pre computed top right of the picture
    short width;//width to draw it
    short height;//height to draw it
    Atlas atlas;//this is more specific to my engine so you can ignore
}AtlasRenderDetails;

typedef struct _GGLOptions
{
    bool textureEnabled;
    GLuint currentTexture;
    GLfloat *vertexArray;
    GLfloat *textureArray;
    GLfloat *colorArray;
    GLfloat arraySize;
    int arrayPosition;
    GLfloat rotation;
    GLfloat xTranslate;
    GLfloat yTranslate;
    GLfloat r;
    GLfloat g;
    GLfloat b;
    GLfloat a;

}GGLOptions;

GGLOptions _GGLOptions;

static void GGLinitOpenGL()
{
    _GGLOptions.textureEnabled=false;
    _GGLOptions.currentTexture=99999;
    _GGLOptions.arrayPosition=0;
    _GGLOptions.arraySize=100;
    _GGLOptions.vertexArray=malloc(sizeof(GLfloat)*_GGLOptions.arraySize);
    _GGLOptions.textureArray=malloc(sizeof(GLfloat)*_GGLOptions.arraySize);
    _GGLOptions.colorArray=malloc(sizeof(GLfloat)*_GGLOptions.arraySize*2);//because colors need 2x as much space
    _GGLOptions.r=1;
    _GGLOptions.g=1;
    _GGLOptions.b=1;
    _GGLOptions.a=1;
    _GGLOptions.rotation=0;
    _GGLOptions.xTranslate=0;
    _GGLOptions.yTranslate=0;
    glEnableClientState(GL_VERTEX_ARRAY);
    glDisable(GL_TEXTURE_2D);
    glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
    //glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    //glAlphaFunc(GL_GREATER,0.3f);
    //glEnable(GL_ALPHA_TEST);
    glEnable(GL_BLEND);
}

static void _GGLgrowArray()
{
    //this is called any time the que is not big enough
    GLfloat *newVertexArray=malloc(sizeof(GLfloat)*_GGLOptions.arraySize*2);
    GLfloat *newTextureArray=malloc(sizeof(GLfloat)*_GGLOptions.arraySize*2);
    GLfloat *newColorArray=malloc(sizeof(GLfloat)*_GGLOptions.arraySize*4);//because colors need 2x as much space
    memcpy(newVertexArray, _GGLOptions.vertexArray, _GGLOptions.arraySize);
    memcpy(newTextureArray, _GGLOptions.textureArray, _GGLOptions.arraySize);
    memcpy(newColorArray, _GGLOptions.colorArray, _GGLOptions.arraySize*2);//because colors need 2x as much space
    free(_GGLOptions.vertexArray);
    free(_GGLOptions.textureArray);
    free(_GGLOptions.colorArray);
    _GGLOptions.vertexArray=newVertexArray;
    _GGLOptions.textureArray=newTextureArray;
    _GGLOptions.colorArray=newColorArray;
    _GGLOptions.arraySize*=2;
    printf("Doubling size");
}

static void GGLsetTranslation(GLfloat xTranslation,GLfloat yTranslation)
{
    _GGLOptions.xTranslate=xTranslation;
    _GGLOptions.yTranslate=yTranslation;
}

static void GGLsetRotation(GLfloat rotationDegrees)
{
    _GGLOptions.rotation=degreesToRadians(rotationDegrees);
}

static void GGLrenderData()
{
    if(_GGLOptions.arrayPosition>0)
    {
        //do batch render
        //setup params
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        glEnableClientState(GL_COLOR_ARRAY);
        glTexCoordPointer(2, GL_FLOAT, 0, _GGLOptions.textureArray);
        glVertexPointer(2, GL_FLOAT, 0, _GGLOptions.vertexArray);
        glColorPointer(4, GL_FLOAT, 0, _GGLOptions.colorArray);
        //Draw the textured triangles
        glDrawArrays(GL_TRIANGLES, 0, _GGLOptions.arrayPosition/2);//Array position is in x and y terms, and this function is in vertex terms so its half
        glDisableClientState(GL_COLOR_ARRAY);
        //reset array
        _GGLOptions.arrayPosition=0;
    }
}

static void GGLsetColor(GLfloat r,GLfloat g,GLfloat b,GLfloat a)
{
    _GGLOptions.r=r*a;
    _GGLOptions.g=g*a;
    _GGLOptions.b=b*a;
    _GGLOptions.a=a;
}


static void GGLsetTexture(GLuint texture)
{
    if(!_GGLOptions.textureEnabled)
    {
        //if we are turning texturing on we need to reset these values
        _GGLOptions.textureEnabled=true;
        glEnable(GL_TEXTURE_2D);
        glEnableClientState(GL_TEXTURE_COORD_ARRAY);
    }
    if(_GGLOptions.currentTexture!=texture)
    {
        if(_GGLOptions.arrayPosition)
        {
            //if we have data to render that is qued, render it before changing
            GGLrenderData();
        }
        _GGLOptions.currentTexture=texture;
        glBindTexture(GL_TEXTURE_2D, texture);
    }
}

static void GGLclearTexture()
{
    if(_GGLOptions.arrayPosition)
    {
        //before we clear our texture we need to render anything that was qued for the previous texture
        GGLrenderData();
    }
    if(_GGLOptions.textureEnabled)
    {
        _GGLOptions.textureEnabled=false;
        glDisable(GL_TEXTURE_2D);
        glDisableClientState(GL_TEXTURE_COORD_ARRAY);
    }
}

static void GGLdrawTexture(GLfloat x,GLfloat y,GLfloat width,GLfloat height,AtlasRenderDetails renderDetails)
{
    GGLsetTexture(renderDetails.textureID);
    if(_GGLOptions.arrayPosition+12>=_GGLOptions.arraySize)
    {
        _GGLgrowArray();
    }
    //make temporary pointers that point to where the next one will be put in our big array
    GLfloat* textureVertices=_GGLOptions.textureArray+_GGLOptions.arrayPosition;
    GLfloat* spriteVertices=_GGLOptions.vertexArray+_GGLOptions.arrayPosition;
    GLfloat* colorVertices=_GGLOptions.colorArray+_GGLOptions.arrayPosition*2;//because there are 4 floats per vertex instead of 2
    //setup the below texture verticies based on precomputed values for our texture atlas. If you are not using atlases
    //these would be changed to 0s and 1s accordingly. x1y1 means bottom left corner and x2y2 means bottom right corner.
    //Some triangle verticies are a mix of both, for example the top left corner verticy of a triangle is x1,y2
    //triangle 1
    textureVertices[0]=renderDetails.textureLocationsX1Y1.x;
    textureVertices[1]=renderDetails.textureLocationsX1Y1.y;
    textureVertices[2]=renderDetails.textureLocationsX1Y1.x;
    textureVertices[3]=renderDetails.textureLocationsX2Y2.y;
    textureVertices[4]=renderDetails.textureLocationsX2Y2.x;
    textureVertices[5]=renderDetails.textureLocationsX2Y2.y;
    //triangle 2
    textureVertices[6]=renderDetails.textureLocationsX2Y2.x;
    textureVertices[7]=renderDetails.textureLocationsX2Y2.y;
    textureVertices[8]=renderDetails.textureLocationsX1Y1.x;
    textureVertices[9]=renderDetails.textureLocationsX1Y1.y;
    textureVertices[10]=renderDetails.textureLocationsX2Y2.x;
    textureVertices[11]=renderDetails.textureLocationsX1Y1.y;
    if(_GGLOptions.rotation!=0)
    {
        CGPoint topLeftRotated=CGPoint_create(x, y+height);
        CGPoint topRightRotated=CGPoint_create(x+width,y+height);
        CGPoint bottomLeftRotated=CGPoint_create(x, y);
        CGPoint bottomRightRotated=CGPoint_create(x+width,y);
        //use whatever rotate code you want in place of the below rotate function
        topLeftRotated=CGPoint_rotateCGPoint(topLeftRotated, _GGLOptions.rotation);
        topRightRotated=CGPoint_rotateCGPoint(topRightRotated, _GGLOptions.rotation);
        bottomLeftRotated=CGPoint_rotateCGPoint(bottomLeftRotated, _GGLOptions.rotation);
        bottomRightRotated=CGPoint_rotateCGPoint(bottomRightRotated, _GGLOptions.rotation);

        //triangle 1
        //top left vertex
        spriteVertices[0]=_GGLOptions.xTranslate+topLeftRotated.x;
        spriteVertices[1]=_GGLOptions.yTranslate+topLeftRotated.y;
        //bottom left vertex
        spriteVertices[2]=_GGLOptions.xTranslate+bottomLeftRotated.x;
        spriteVertices[3]=_GGLOptions.yTranslate+bottomLeftRotated.y;
        //bottom right vertex
        spriteVertices[4]=_GGLOptions.xTranslate+bottomRightRotated.x;
        spriteVertices[5]=_GGLOptions.yTranslate+bottomRightRotated.y;
        //triangle 2
        //bottom right vertex
        spriteVertices[6]=_GGLOptions.xTranslate+bottomRightRotated.x;
        spriteVertices[7]=_GGLOptions.yTranslate+bottomRightRotated.y;
        //top left vertex
        spriteVertices[8]=_GGLOptions.xTranslate+topLeftRotated.x;
        spriteVertices[9]=_GGLOptions.yTranslate+topLeftRotated.y;
        //top right vertex
        spriteVertices[10]=_GGLOptions.xTranslate+topRightRotated.x;
        spriteVertices[11]=_GGLOptions.yTranslate+topRightRotated.y;
    }
    else
    {
        //triangle 1
        //top left vertex
        spriteVertices[0]=_GGLOptions.xTranslate+x;
        spriteVertices[1]=_GGLOptions.yTranslate+y+height;
        //bottom left vertex
        spriteVertices[2]=spriteVertices[0];
        spriteVertices[3]=_GGLOptions.yTranslate+y;
        //bottom right vertex
        spriteVertices[4]=_GGLOptions.xTranslate+x+width;
        spriteVertices[5]=spriteVertices[3];
        //triangle 2
        //bottom right vertex
        spriteVertices[6]=spriteVertices[4];//x+width
        spriteVertices[7]=spriteVertices[3];//y
        //top left vertex
        spriteVertices[8]=spriteVertices[0];//x
        spriteVertices[9]=spriteVertices[1];//y+height
        //top right vertex
        spriteVertices[10]=spriteVertices[4];//x+width
        spriteVertices[11]=spriteVertices[1];//y+height
    }
    //set the colors to the active color
    for(int i=0;i<24;i+=4)
    {
        colorVertices[i]=_GGLOptions.r;
        colorVertices[i+1]=_GGLOptions.g;
        colorVertices[i+2]=_GGLOptions.b;
        colorVertices[i+3]=_GGLOptions.a;
    }
    
    _GGLOptions.arrayPosition+=12;
}

static void GGLdrawTextureDetails(GLfloat x,GLfloat y,AtlasRenderDetails renderDetails)
{
    GGLdrawTexture(x,y,renderDetails.width,renderDetails.height,renderDetails);​
}

static void GGLdrawRectangle(CGRect rect,bool fill,Color color)
{
    //trigger a render data because we are about to draw non triangles and we won't be using batch rendering.
    //but we need this to trigger so that the order of drawing is preserved, otherwise this rect would go
    //underneath things qued up before it was called
    GGLrenderData();
    GGLclearTexture();
    glColor4f(color.r,color.g,color.b,color.a);
    GLfloat spriteVertices[8];
    glEnable(GL_LINE_SMOOTH);
    if(fill)
    {
        spriteVertices[0]=rect.origin.x;spriteVertices[1]= rect.origin.y;
        spriteVertices[2]=rect.origin.x+rect.size.width;spriteVertices[3]=rect.origin.y,
        spriteVertices[4]=rect.origin.x;spriteVertices[5]= rect.origin.y+rect.size.height,
        spriteVertices[6]=rect.origin.x+rect.size.width;spriteVertices[7]=rect.origin.y+rect.size.height;
    }
    else
    {
        spriteVertices[0]=rect.origin.x;spriteVertices[1]=rect.origin.y;
        spriteVertices[2]=rect.origin.x+rect.size.width;spriteVertices[3]=rect.origin.y;
        spriteVertices[4]=rect.origin.x+rect.size.width;spriteVertices[5]=rect.origin.y+rect.size.height;
        spriteVertices[6]=rect.origin.x;spriteVertices[7]=rect.origin.y+rect.size.height;
        
    }
    glVertexPointer (2, GL_FLOAT , 0, spriteVertices);
    if(fill)
    {
        glDrawArrays (GL_TRIANGLE_STRIP, 0, 4);
    }
    else
    {
        glDrawArrays(GL_LINE_LOOP, 0,4);
    }
    
}


static void GGLdrawTextureArc(CGPoint center, GLfloat radius, GLfloat startArc, GLfloat endArc, GLuint atlasTexture,CGRect atlasImageLocation,Color color)
{
    //trigger a render data because we are about to draw non triangles and we won't be using batch rendering.
    //but we need this to trigger so that the order of drawing is preserved, otherwise this arc would go
    //underneath things qued up before it was called
    GGLrenderData();
    GGLsetTexture(atlasTexture);
    glColor4f(color.r,color.g,color.b,color.a);
    if (endArc < startArc)
    {
        float temp = endArc;
        endArc = startArc;
        startArc = temp;
    }
    
    //2 for the remainder when we draw the last arc
    //2 for the start point in the center since its a triangle fan
    GLfloat segments=endArc-startArc;
    segments/=ARC_SEGMENT;
    //if there is left over, we need to have room for the final verticy
    if(segments>(int)segments)
    {
        segments=(int)segments+1;
    }
    int numVertices=4+2*(segments);
    GLfloat spriteVertices[numVertices];
    GLfloat textureVertices[numVertices];
    float theta;
    spriteVertices[0]=center.x;
    spriteVertices[1]=center.y;
    GLfloat halfTextureWidth=atlasImageLocation.size.width/2.0f;
    GLfloat halfTextureHeight=atlasImageLocation.size.height/2.0f;
    textureVertices[0]=atlasImageLocation.origin.x+halfTextureWidth;
    textureVertices[1]=atlasImageLocation.origin.y+halfTextureHeight;
    int i=2;
    float radius2=radius*2;
    for (theta = startArc; theta < endArc; theta += ARC_SEGMENT)
    {
        float x=sinf(theta)*radius;
        float y=cosf(theta)*radius;
        //the texture verticy should be at the x,y offset of the texture+the width\height scaled by the portion of 2x the radius that dimension is using
        //Example if a texture file was just a single image, the origin would be 0,0 and the width would be 1, so you would get
        //a number between 0 and 1, releative to theta so it would go around in a circle
        textureVertices[i]=atlasImageLocation.origin.x+atlasImageLocation.size.width*((radius+x)/radius2);
        textureVertices[i+1]=atlasImageLocation.origin.y+atlasImageLocation.size.height*((radius+y)/radius2);
        textureVertices[i]=(radius+x)/radius2;
        textureVertices[i+1]=(radius+y)/radius2;
        spriteVertices[i]=center.x+x;
        spriteVertices[i+1]=center.y+y;
        i+=2;
    }
    //If the gap between our previous theta and the end arc is big enough, we need to draw the triangle strip one more vertex
    if(endArc-(theta-ARC_SEGMENT)>0.001)
    {
        float x = (float) sin(endArc-0.01f) * radius;
        float y = (float) cos(endArc-0.01f) * radius;
        textureVertices[i]=atlasImageLocation.origin.x+atlasImageLocation.size.width*((radius+x)/radius2);
        textureVertices[i+1]=atlasImageLocation.origin.y+atlasImageLocation.size.height*((radius+y)/radius2);        spriteVertices[i]=center.x+x;
        spriteVertices[i]=center.x+x;
        spriteVertices[i+1]=center.y+y;
        i+=2;
    }
    if(i>numVertices)
    {
        [Logger LogErrorString:[NSString stringWithFormat:@"Too many vertices used:%d",i] forID:@"OpenglUtils.drawTextureArc"];
    }
    glVertexPointer (2, GL_FLOAT , 0, spriteVertices);
    glTexCoordPointer(2, GL_FLOAT, 0, textureVertices);
    glDrawArrays (GL_TRIANGLE_FAN, 0, i/2);
    
}

static void GGLdrawArc(CGPoint center, GLfloat radius, GLfloat startArc, GLfloat endArc,Color color)
{
    //trigger a render data because we are about to draw non triangles and we won't be using batch rendering.
    //but we need this to trigger so that the order of drawing is preserved, otherwise this arc would go
    //underneath things qued up before it was called
    GGLrenderData();
    GGLclearTexture();    
    glColor4f(color.r,color.g,color.b,color.a);
    if (endArc < startArc)
    {
        float temp = endArc;
        endArc = startArc;
        startArc = temp;
    }
    
    //2 for the remainder when we draw the last arc
    //2 for the start point in the center since its a triangle fan
    GLfloat segments=endArc-startArc;
    segments/=ARC_SEGMENT;
    //if there is left over, we need to have room for the final verticy
    if(segments>(int)segments)
    {
        segments=(int)segments+1;
    }
    int numVertices=4+2*(segments);
    GLfloat spriteVertices[numVertices];
    float theta;
    spriteVertices[0]=center.x;
    spriteVertices[1]=center.y;
    int i=2;
    for (theta = startArc; theta < endArc; theta += ARC_SEGMENT)
    {
        float x=sinf(theta)*radius;
        float y=cosf(theta)*radius;
        spriteVertices[i]=center.x+x;
        spriteVertices[i+1]=center.y+y;
        i+=2;
    }
    //If the gap between our previous theta and the end arc is big enough, we need to draw the triangle strip one more vertex
    if(endArc-(theta-ARC_SEGMENT)>0.001)
    {
        float x = (float) sin(endArc-0.01f) * radius;
        float y = (float) cos(endArc-0.01f) * radius;
        spriteVertices[i]=center.x+x;
        spriteVertices[i+1]=center.y+y;
        i+=2;
    }    if(i>numVertices)
    {
        [Logger LogErrorString:[NSString stringWithFormat:@"Too many vertices used:%d",i] forID:@"OpenglUtils.drawTextureArc"];
    }
    glVertexPointer (2, GL_FLOAT , 0, spriteVertices);
    glDrawArrays (GL_TRIANGLE_FAN, 0, i/2);
    
    
}
Quote this message in a reply
Post Reply 

Possibly Related Threads...
Thread: Author Replies: Views: Last Post
  Trying to save draw-calls for framerate (iphone app) player___1 0 2,663 Jul 6, 2009 12:39 PM
Last Post: player___1