Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to read data from a cubemap to the CPU in OpenGL with glGetTexImage?

Tags:

opengl

I have trouble reading a cubemap back to the CPU. When I pass data to the cubemap in the glTexImage2D call, this data can be read back without a problem. But when I render to the cubemap, only the positive-x side of the cubemap contains sensible data. Everything else is 0 (and not uninitialized).

I'm rendering to the cubemap using layered rendering and checked the contents of the cubemap by sampling from it in the shader afterwards. What I get there is correct. But glGetTexImage seems not to work the way I thought it would.

No framebuffer is bound when I call glGetTexImage as suggested by: www.gamedev.com

Am I doing this wrong? Does somebody have a clue what may be going wrong here?

glGenTextures(1, &c_cubemap);
glBindTexture(GL_TEXTURE_CUBE_MAP, c_cubemap);

// load data ...

auto width = positiveX->width;
auto height = positiveX->height;
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, GL_RGB16F, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, ...);
glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, GL_RGB16F, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, ...);
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, GL_RGB16F, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, ...);
glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, GL_RGB16F, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, ...);
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, GL_RGB16F, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, ...);
glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, GL_RGB16F, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, ...);

glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_REPEAT);

// Here, the rendering takes place.

auto size = width * height * 3;
auto bufferPositiveX = new float[size];
auto bufferNegativeX = new float[size];
auto bufferPositiveY = new float[size];
auto bufferNegativeY = new float[size];
auto bufferPositiveZ = new float[size];
auto bufferNegativeZ = new float[size];

glBindTexture(GL_TEXTURE_CUBE_MAP, c_cubemap);
glGetTexImage(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, GL_RGB, GL_FLOAT, bufferPositiveX);
glGetTexImage(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, GL_RGB, GL_FLOAT, bufferNegativeX);
glGetTexImage(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, GL_RGB, GL_FLOAT, bufferPositiveY);
glGetTexImage(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, GL_RGB, GL_FLOAT, bufferNegativeY);
glGetTexImage(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, GL_RGB, GL_FLOAT, bufferPositiveZ);
glGetTexImage(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, GL_RGB, GL_FLOAT, bufferNegativeZ);
glBindTexture(GL_TEXTURE_CUBE_MAP, 0);

I'm working with a NVIDIA GeForce GTX 780. The driver version is 364.72.

like image 288
Henkk Avatar asked Oct 30 '22 04:10

Henkk


1 Answers

I found the answer here: https://www.opengl.org/sdk/docs/man/html/glGetTexImage.xhtml

It says: "If glGetTextureImage is used against a cube map texture object, the texture is treated as a three-dimensional image of a depth of 6, where the cube map faces are ordered as image layers, in an order presented in the table below:"

Layer number    Cube Map Face
0               GL_TEXTURE_CUBE_MAP_POSITIVE_X
1               GL_TEXTURE_CUBE_MAP_NEGATIVE_X
2               GL_TEXTURE_CUBE_MAP_POSITIVE_Y
3               GL_TEXTURE_CUBE_MAP_NEGATIVE_Y
4               GL_TEXTURE_CUBE_MAP_POSITIVE_Z
5               GL_TEXTURE_CUBE_MAP_NEGATIVE_Z
like image 156
bofjas Avatar answered Jan 04 '23 13:01

bofjas