Skip to content
Search

GlGetTexImage

lastmod 2025-05-19created 2021-05-082 edits

Saving an OpenGL texture as BMP

When you want to debug in OpenGL while checking the current texture with your own eyes, save the texture as a bmp file as shown below. The important function here is glGetTexLevelParameteriv, which gets the parameters of the current texture at the current mipmap level; in the example there is only 1 level, so it is 0). It is saved as a 32-bit bmp. glGetTexImage gets the pixels of the current texture. Since a 32-bit bmp is GL_BGRA, specifying GL_RGBA inverts the colors.

#define GL_BGRA 0x80E1 // Use this for 32bit bmp
// ...
GLint cx, cy, format, bpp;
// 저장할 texture를 bind
glBindTexture( GL_TEXTURE_2D, id);
// cx,cy는 현재 texture의 width, height이다.
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &cx);
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &cy);
// 현재 texture의 internal format을 얻는다. 여기서는 GL_RGBA만 대상으로 한다.
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_INTERNAL_FORMAT, &format);
if(format == GL_RGBA)
{
    size_t data_size = 4*cx*cy;
    // 32비트 bmp텍스처의 픽셀버퍼 메모리할당
    unsigned char *data = new unsigned char[4*cx*cy];
    // 현재 texture의 픽셀을 얻어온다.
    glGetTexImage(GL_TEXTURE_2D, 0, GL_BGRA, GL_UNSIGNED_BYTE, data);
    // bmp구조를 만든다음 저장한다.
    BITMAPFILEHEADER bfh;
    BITMAPINFOHEADER bih;
    bfh.bfType = 0x4d42;
    // Entire file size(40+14+data_size)
    bfh.bfSize = sizeof(BITMAPINFOHEADER)+ sizeof(BITMAPFILEHEADER) + data_size;
    bfh.bfReserved1 = 0;
    bfh.bfReserved2 = 0;
    bfh.bfOffBits = 54;// offset(14+40)
    // major
    bih.biSize = sizeof(BITMAPINFOHEADER);//40
    bih.biWidth = cx;
    bih.biHeight = cy;
    bih.biPlanes = 1;
    bih.biBitCount = 32;
    // minor
    bih.biCompression = BI_RGB;
    bih.biSizeImage = data_size;
    bih.biXPelsPerMeter = 0;
    bih.biYPelsPerMeter = 0;
    bih.biClrUsed = 0;
    bih.biClrImportant = 0;
    FILE *fp = fopen("out.bmp", "wb");
    if(fp) {
        fwrite(&bfh, 1, sizeof(BITMAPFILEHEADER), fp);
        fwrite(&bih, 1, sizeof(BITMAPINFOHEADER), fp);
        fwrite(data, 1, data_size, fp);
        fclose(fp);
    }
    delete[] data;
}
// texture를 unbind
glBindTexture(GL_TEXTURE_2D, 0);

See also

author Zer0 sitemap