0

Why does a 800x600 rectangle in OpenGL take so much longer time than many small rectangles? In my head I would have thought drawing 1 would be better than many.

public class LWJGLtest {
int screenwidth = 1024;
int screenheight = 768;
private Texture texture;
int[][] Star1 = new int[100][2];

public void start() {
    try {
        Display.setDisplayMode(new DisplayMode(screenwidth, screenheight));
        Display.create();
    } catch (LWJGLException e) {
        e.printStackTrace();
        System.exit(0);
    }

    for (int r = 0; r < Star1.length; r++) {
        Star1[r][0] = (int) (screenwidth * Math.random());
        Star1[r][1] = (int) (screenheight * Math.random());
        for (int c = 0; c < Star1[r].length; c++) {
            System.out.print(" " + Star1[r][c]);
        }
        System.out.println("");
    }
    glEnable(GL_TEXTURE_2D);
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    glDisable(GL_DEPTH_TEST);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(0, screenwidth, screenheight, 0, 1, -1);
    try {
        texture = TextureLoader.getTexture("PNG", ResourceLoader.getResourceAsStream("fighter.png"));
    } catch (IOException ex) {
        Logger.getLogger(LWJGLtest.class.getName()).log(Level.SEVERE, null, ex);
    }
    //////////////////
    boolean bsmall = false;
    ////////////////////
    while (!Display.isCloseRequested()) {
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        glColor3f(1f, 0f, 0f);
        if (bsmall) {
            for (int i = 0; i < 100; i++) {
                int x = (int) (screenwidth * Math.random());
                int y = (int) (screenheight * Math.random());
                DrawImage(texture, x, y, 30, 30);
                //DrawRect(x, y, screenwidth, screenheight);
            }
        } else {
            for (int i = 0; i < 1; i++) {
                int x = 0;//(int) (screenwidth * Math.random());
                int y = 0;//(int) (screenheight * Math.random());
                DrawImage(texture, x, y, screenwidth, screenheight);
                //DrawRect(x, y, screenwidth, screenheight);
            }
        }
        Display.update();
    }
    Display.destroy();
}

void DrawImage(Texture tex, int x, int y, int w, int h) {
    if (tex == null) {
        return;
    }
    tex.bind();
    glBegin(GL_QUADS);
    glTexCoord2f(0, 0);
    glVertex2f(x, y);
    glTexCoord2f(1, 0);
    glVertex2f(x + w, y);
    glTexCoord2f(1, 1);
    glVertex2f(x + w, y + h);
    glTexCoord2f(0, 1);
    glVertex2f(x, y + h);
    glEnd();
}

public static void main(String[] argv) {
    LWJGLtest displayExample = new LWJGLtest();
    displayExample.start();
}
}

When bsmall == true I get 1000 better fps than when false?

Bart
  • 19,692
  • 7
  • 68
  • 77
Jason Gray
  • 97
  • 5

1 Answers1

3

This is a very deep question and very hardware dependent. However, notice that in your case the texture coordinates are fixed. That means your smaller rectangles draw smaller versions of the texture. Likely your textures use mipmapping. Mipmapping has smaller versions of a texture for when you display the texture as smaller like you are here.

Therefore, the smaller your rectangles, the less data you'll actually end up accessing. This is called texture fetching, and often its overhead is far greater than vertex processing. So yes, you are processing more vertices, you're drawing about the same number of pixels, and you're doing the same amount of texture fetching -- but your texture fetching is most likely entirely in texture cache, so it's very much faster to access.

You need to compare apples and apples -- make the output look exactly the same and then see which technique is faster.

Another example -- On PS3 graphics hardware there's a certain pattern of tiling full screen drawing that causes the shader quad distributor to do a better job distributing work to the fragment shading units. Likewise it could be with your graphics card. It's hard to know and hard to understand, especially when manufacturers don't like giving away all of their secrets.

Kaganar
  • 6,540
  • 2
  • 26
  • 59