I have been failing to render to a 3D texture for voxelization so I decided to go a slightly different route. I am able to create a FBO, and given a SINGLE clip plane, can render slices into the 3D texture traversing from front to back. This creates a solid voxelization, as instead of rendering slices (like slices of bread), it simply shears off everything in nearest the viewer. So to get a hollow voxelization, I want ‘bread slices’, so I added a second clipping plane… but then I was no longer able render into a 3D texture, for whatever reason.
So my hope is to use glReadPixels to get the FBO data, then use glTexSubImage3D to write the data directly into the 3D texture.
Thus far, glTexSubImage3D has been throwing glError with GL_INVALID_OPERATION:
http://www.opengl.org/sdk/docs/man/xhtml/glTexSubImage3D.xml
I believe I have narrowed down the issue to the GL_PIXEL_UNPACK_BUFFER, as it doesn’t seems like the other causes of this error apply to my program. Thing is, I’m not really sure what the GL_PIXEL_UNPACK_BUFFER is or how it relates.
Any thoughts?
Texture setup:
//Set texture dimensions
texX = texY = texZ = size;
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_3D, texture);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA8, texX, texY, texZ, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
Render to texture
void renderToTex(){
glGenFramebuffers(1,&framebufferObject);
glBindTexture(GL_TEXTURE_3D, texture);
image = new GLubyte[texX * texY * 4];
glBindFramebuffer(GL_FRAMEBUFFER, framebufferObject);
glActiveTexture(GL_TEXTURE0);
for(int z = 0; z < texZ; z++){
glFramebufferTextureLayer(GL_FRAMEBUFFER,
GL_COLOR_ATTACHMENT0,
texture,
0,
z);
//Check frame buffer status
cout << endl << "FRAMEBUFFER STATUS: ";
checkFramebufferStatus();
printFramebufferInfo();
//Render into texture
renderIntoSlice(z);
//Fill FBO image data
glReadPixels(0,0, texX, texY, GL_RGBA, GL_UNSIGNED_BYTE, image);
//Copy FBO image data into texture
glTexSubImage3D(GL_TEXTURE_3D, 0, 0, 0, z, texX, texY, 1, GL_RGBA, GL_UNSIGNED_BYTE, image);
//Print texel values by slice; prints contents of 'image' array
printPixelsInSlice(z);
}
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
Render a single slice:
void renderIntoSlice(int z){
GLclampf foreColor[3] = {1.0, 1.0, 1.0f};
GLclampf backColor[3] = {0, 0, 0};
double equation0[4]; // near slice; not the same clipping plane used for the viewing box
double equation1[4]; // far slice; not the same clipping plane used for the viewing box
double zDis = sigFloor(ply.zMin) + ortho - (ortho / texZ * z);
//Background color should have alpha == 0?
glClearColor(backColor[0], backColor[1], backColor[2], 0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_DEPTH_TEST);
//Get equation of 'near slice' clipping plane
equationPlane(0, 0, -1, //Normal
0, 0, zDis,
equation0);
glClipPlane(GL_CLIP_PLANE0, equation0);
glEnable(GL_CLIP_PLANE0);
//Get equation of 'far slice' clipping plane
equationPlane(0, 0, 1, //Normal
0, 0, sigFloor(ply.zMin) + ortho - (ortho / texZ * (z + 1)),
equation1);
glClipPlane(GL_CLIP_PLANE1, equation1);
glEnable(GL_CLIP_PLANE1);
glColor3fv(foreColor);
drawMesh();
glDisable(GL_CULL_FACE);
}