OpenGL ES2... many questions

Member
Posts: 25
Joined: 2011.08
Post: #31
Hi, I feel spammy for making a new thread for every problem I encounter so I'll just ask here...
I'm working on a simple sprite engine, I started from the OpenGL template and continued from there.
I made a Sprite class, and I'm probably doing something wrong because I have really bad performance...
I made a test app- it's just spinning sprites...
I have an NSMutableArray of Sprites, and every frame I run over the array and update and render all the sprites. Whenever I touch the screen a new Sprite is allocated and initialized at a random place, and added to the MutableArray.
When I get to 30 object I'm starting to lose some fps and when I get to ~40 I go down to 30 fps. (In the condition that I'm actually calculating fps the right way Rasp) But I can see that the movement is loosing smoothness.
I thought about working with structs instead of classes of sprites, but I thought I'll go and ask here before doing that...
I'm binding the texture only once, so it's not that...

This is how my code works- the Sprite class has these properties:
x, y, xScale, yScale, angle, color, alpha, width, height
and in the sprite.m I declared three float arrays (C arrays) for the vertices, texture coordinates and colors.
In the render method (also a method of Sprite) I insert the values based on the properties to the arrays, and then bind everything and call glDrawArrays.

If any more info is needed tell me... Also I don't mind posting the source code even though I'm pretty ashamed Smile
Quote this message in a reply
Member
Posts: 96
Joined: 2011.07
Post: #32
What's the platform? Are you calling glDrawArrays for each sprite? If so try combining everything into one mesh and make only one draw call. Or try to get less than ten draw calls at least. Run the app with Instruments and see where the bottleneck occurs. I don't think converting the objects into structs will make a difference. PM me if needed.

respect,
pk

iFrog is coming.
Quote this message in a reply
Member
Posts: 25
Joined: 2011.08
Post: #33
(Sep 1, 2011 08:32 AM)ipeku Wrote:  What's the platform? Are you calling glDrawArrays for each sprite? If so try combining everything into one mesh and make only one draw call. Or try to get less than ten draw calls at least. Run the app with Instruments and see where the bottleneck occurs. I don't think converting the objects into structs will make a difference. PM me if needed.

Sorry for being a noob, how do I run the app with Instruments?
I mean I clicked Profile instead of Run and it opened Instruments but I have no idea how to use it...
I'm running on an iPhone 4.
Yes, I'm calling glDrawArrays for each sprite, but it seems weird that I lose performance so quickly, I mean... It's an iPhone 4 it runs crazy 3d games with tons of objects and textures...


EDIT:
This is the Sprite render method: (Happens every frame per sprite)
Code:
-(void) render {
    float c = cosf(angle);
    float s = sinf(angle);
    float x1,y1,x2,y2,x3,y3,x4,y4,nx1,nx2,nx3,nx4,ny1,ny2,ny3,ny4;
    float xc = halfW * scaleX;
    float yc = halfH * scaleY;
    x1 = -xc;
    y1 = -yc;
    x2 = +xc;
    y2 = -yc;
    x3 = -xc;
    y3 = +yc;
    x4 = +xc;
    y4 = +yc;
    nx1 = x+c*x1 - s*y1;
    ny1 = y+s*x1 + c*y1;
    nx2 = x+c*x2 - s*y2;
    ny2 = y+s*x2 + c*y2;
    nx3 = x+c*x3 - s*y3;
    ny3 = y+s*x3 + c*y3;
    nx4 = x+c*x4 - s*y4;
    ny4 = y+s*x4 + c*y4;
    
    // these three are C functions that insert the values to the array which is the first argument
    insert8Vals(vertices,
                nx1, ny1,
                nx2, ny2,
                nx3, ny3,
                nx4, ny4);
    
    insert8Vals(textureCoords,
                0.0f, 1.0f,
                1.0f, 1.0f,
                0.0f, 0.0f,
                1.0f, 0.0f);
    
    insert16Vals(colors,
                 color.r * alpha, color.g * alpha, color.b * alpha, alpha,
                 color.r * alpha, color.g * alpha, color.b * alpha, alpha,
                 color.r * alpha, color.g * alpha, color.b * alpha, alpha,
                 color.r * alpha, color.g * alpha, color.b * alpha, alpha);
    
    glVertexAttribPointer(ATTRIB_TEX_COORD_IN, 2, GL_FLOAT, GL_FALSE, 0, textureCoords);
    glEnableVertexAttribArray(ATTRIB_TEX_COORD_IN);
    
    static bool blah = NO; // this is temporary, sorry for lameness
    if(!blah) {
    glBindTexture(GL_TEXTURE_2D, textureId);
        blah = YES;
    }
    
    glVertexAttribPointer(ATTRIB_VERTEX, 2, GL_FLOAT, GL_FALSE, 0, vertices);
    glEnableVertexAttribArray(ATTRIB_VERTEX);
    glVertexAttribPointer(ATTRIB_COLOR, 4, GL_FLOAT, GL_FALSE, 0, colors);
    glEnableVertexAttribArray(ATTRIB_COLOR);
    
    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
}
Quote this message in a reply
Moderator
Posts: 1,560
Joined: 2003.10
Post: #34
You must be hitting a bottleneck somewhere. I've never managed to get much useful information out of Instruments (though that's probably just because I never took the time to figure it out), but Shark and OpenGL Profiler are quite valuable. You can find them in /Developer/Applications/Performance Tools and /Developer/Applications/Graphics Tools, respectively. Shark will help you determine what's taking you the most CPU time, and OpenGL Profiler does the same for the GPU. If your performance is suffering, usually you'll be overloaded on one and underloaded on the other.

It's been a while since I've used either tool and my memory is unfortunately a bit fuzzy, but I'm fairly certain they can both be attached to an application running on your iPhone. It might take some fiddling to figure out how, but I've definitely done it with Shark at least. It is important that you attach to the application running on your actual device, since it'll have completely different performance characteristics than the simulator.

Sorry for being vague, but hopefully you'll be able to figure it out!
Quote this message in a reply
Member
Posts: 25
Joined: 2011.08
Post: #35
I don't have Shark, I think that it's gone Xcode 4 or something... I found it in the developer-old directory, but it doesn't load. Which doesn't matter because I don't know how to use these things anyway...
Well using a lot of trial and error I got to the conclusion that these are the problematic lines:
Code:
glVertexAttribPointer(ATTRIB_VERTEX, 2, GL_FLOAT, GL_FALSE, 0, vertices);
    glEnableVertexAttribArray(ATTRIB_VERTEX);
When I comment these out, it the fps stays pretty stable. (Obviously I don't see anything on the screen).
Now what?
I don't want to find myself batching textures so soon, and then find out that it wasn't the problem... (Getting to 30 fps on 40 sprites only... I think it's because I'm doing something wrong).


EDIT: I found a problem (I wish it was "THE" problem, but it's only "A" problem).
The texture that I was loading was huge. Way to big for what I'm rendering. So now the frame rate starts dropping at 60 objects and at 70 it's ~30 fps. So the problem still remains.
Is that normal? I'm not changing the bound texture, but I'm not batching any geometry so it's not the most efficient thing in the world, but 70 objects in 30 fps, that sounds really bad, probably something that I'm missing.
BTW- Is PVR has performance benefits in terms of fps? From what I read online I understood that it has quicker loading times...
Quote this message in a reply
Luminary
Posts: 5,143
Joined: 2002.04
Post: #36
Shark is gone (replaced by Instruments), and OpenGL Profiler is Mac-only.

If you don't understand Instruments, you should be able to find some introductory material in the WWDC videos.
Quote this message in a reply
Member
Posts: 25
Joined: 2011.08
Post: #37
Ok so I'm currently using GL_TRIANGLES to draw all the sprites in one glDrawArrays call per frame, and also instead of objects I'm using structs to manage the sprites, and I also changed highp to lowp in my fragment shader. I did get a performance boost, but still, at around ~230 objects I go down to 30 fps. I'm just asking if that's normal... If it isn't than what am I supposed to do? Commenting out glDrawArrays make the fps stay stable, so I don't see what else I can improve...
Quote this message in a reply
Member
Posts: 96
Joined: 2011.07
Post: #38
Consider drawing before you do the calculations. Like this:
1. CADisplayLink fires
2. Draw everything
3. Handle user input
4. "Game sim": Do all the calculations, update and build the verteces for the next draw call

respect,
pk

iFrog is coming.
Quote this message in a reply
Member
Posts: 25
Joined: 2011.08
Post: #39
(Sep 2, 2011 01:06 PM)ipeku Wrote:  Consider drawing before you do the calculations. Like this:
1. CADisplayLink fires
2. Draw everything
3. Handle user input
4. "Game sim": Do all the calculations, update and build the verteces for the next draw call

Tried it, didn't help... Annoyed
After reading a bit online and playing with instruments (I still don't know what to do with the information I'm getting from there)...
I think my problem is that I'm hitting the fillrate. (I may be terribly wrong). How can I solve that?
Oh and another question, how can I save a png in RGBA4_4_4_4 format, and what do I need to to in order to load it?
Even though since my graphics got a lot of gradients it'll probably look really bad. But I just wanna test to see what I should improve.

I'm really frustrated, I thought I was studying OpenGL to get great performance... Sad
Quote this message in a reply
Member
Posts: 96
Joined: 2011.07
Post: #40
Can you upload a screenshot?

respect,
pk

iFrog is coming.
Quote this message in a reply
Post Reply 

Possibly Related Threads...
Thread: Author Replies: Views: Last Post
  OpenGL ES questions regarding 2D mixed with 3D jeonghyunhan 5 5,950 Jun 20, 2009 03:54 PM
Last Post: jeonghyunhan
  OpenGL: glRotate and some 3D questions. mikey 1 3,635 May 19, 2009 05:11 PM
Last Post: ThemsAllTook
  Basic OpenGL questions Mercy 5 4,426 Dec 23, 2008 10:25 AM
Last Post: AnotherJake
  Some OpenGL 2D questions oskob 16 9,284 Oct 30, 2008 12:12 PM
Last Post: Wowbagger
  Dreaded noob questions: OpenGL in a Cocoa App 5thPeriodProductions 5 4,357 Apr 10, 2006 11:08 AM
Last Post: 5thPeriodProductions