views:

840

answers:

2

I've had this problem a couple of times. Let's say I want to display a splash-screen or something in an OpenGL context (or DirectX for that matter, it's more of a conceptual thing), now, I could either just load a 2048x2048 texture and hope that the graphics card will cope with it (most will nowadays I suppose), but growing with old-school graphics card I have this bad conscience leaning over me and telling me I shouldn't use textures that large.

What is the preferred way nowadays? Is it to just cram that thing into video memory, tile it, or let the CPU do the work and glDrawPixels? Or something more elaborate?

A: 

I don't think there is a built-in opengl function, but you might find a library (or write the function yourself) to break the image down into smaller chunks and then print to screen the smaller chunks (128x128 tiles or similar).

I had problem with this using Slick2D for a Java game. You can check out their "BigImage" class for ideas here.

Bryan Denny
+6  A: 

If this is a single frame splash image with no animations, then there's no harm using glDrawPixels. If performance is crucial and you are required to use a texture, then the correct way to do it is to determine at runtime, the maximum supported texture size, using a proxy texture.

GLint width = 0;
while ( 0 == width ) {  /* use a better condition to prevent possible endless loop */
    glTexImage2D(GL_PROXY_TEXTURE_2D, 
                      0,                /* mip map level */
                      GL_RGBA,          /* internal format */
                      desiredWidth,     /* width of image */
                      desiredHeight,    /* height of image */
                      0,                /* texture border */
                      GL_RGBA           /* pixel data format, */ 
                      GL_UNSIGNED_BYTE, /* pixel data type */
                      NULL              /* null pointer because this a proxy texture */
    );

    /* the queried width will NOT be 0, if the texture format is supported */
    glGetTexLevelParameteriv(GL_PROXY_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &width);

    desiredWidth /= 2; desiredHeight /= 2;
}

Once you know the maximum texture size supported by the system's OpenGL driver, you have at least two options if your image doesn't fit:

  • Image tiling: use multiple quads after splitting your image into smaller supported chunks. Image tiling for something like a splash screen should not be too tricky. You can use glPixelStorei's GL_PACK_ROW_LENGTH parameter to load sections of a larger image into a texture.
  • Image resizing: resize your image to fit the maximum supported texture size. There's even a GLU helper function to do this for you, gluScaleImage.
codelogic
GLint width = 0; // ;-)
Will
oops ;-) (also just realized that my comment has a syntax error)
codelogic