PDA

View Full Version : glTexImage3D works! but... not. (PIC included)



avocados
07-12-2005, 06:08 PM
So I'm trying to render my terrain with a grass and rock texture using a 3D texture to blend between them. But when I go to render, it tiles the textures next to eachother. In this sample, I'm actually trying to render just the grass texture on a quad but its rendering the rock on the top half and the grass on the bottom half. Oops, that's my water texture in the picture, not grass.


void initTextures(void) {
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);

glGenTextures(1, &gui_tex);
glBindTexture(GL_TEXTURE_3D, gui_tex);

importBMP("512A.bmp", &bmp[0][0][0][0], 512);
importBMP("512B.bmp", &bmp[1][0][0][0], 512);

glTexImage3D(GL_TEXTURE_3D, 0, GL_RGB, 4, 512,
512, 0, GL_RGB, GL_UNSIGNED_BYTE, gui_bmp);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_REPEAT);
}

void renderScene(void) //**RENDERSCENE**//
{
glutTimerFunc( 1000/30.0, timer, 0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glEnable(GL_TEXTURE_3D);
glBegin(GL_QUADS);
glTexCoord3d(0,0,1); glVertex3f( 3, 3,0);
glTexCoord3d(0,0,0); glVertex3f( 3, -3,0);
glTexCoord3d(0,1,0); glVertex3f(-3, -3,0);
glTexCoord3d(0,1,1); glVertex3f(-3, 3,0);
glEnd();

glutSwapBuffers();
} http://img319.imageshack.us/img319/185/3dtexture4bt.th.jpg (http://img319.imageshack.us/my.php?image=3dtexture4bt.jpg)

dvm
07-13-2005, 02:43 AM
Well, I'd say you complicate things too much. Loading the bmp's in 4-D arrays? Anyway I think that your problem is the memory is not mapped as you expect it to be (or OpenGL reads the arrays different than you think) so one image interferes with the other. A simple pointer of GLubyte is enough for an image.

You could try using two different variables of 3 dimensions each I guess. That should seperate the memory. Ofcourse since C doesn't provide bounds checking you could still have problems. If that's the case I'd suggest using a pointer to GLubyte. Though, you've managed to get this far, I couldn't load 3D textures myself :(

T101
07-13-2005, 03:40 AM
importBMP("512A.bmp", &bmp[0][0][0][0], 512); importBMP("512B.bmp", &bmp[1][0][0][0], 512); glTexImage3D(GL_TEXTURE_3D, 0, GL_RGB, 4, 512, 512, 0, GL_RGB, GL_UNSIGNED_BYTE, gui_bmp); What does gui_bmp point to? You seem to be loading into a different buffer. (Unless it points to the same memory)

avocados
07-13-2005, 03:58 AM
Oh, the 3d texture is in

unsigned char bmp[4][512][512][3]
//[depth][height][width][rgb]And gui_bmp does point to bmp, I meant to change that for clarity as there is no reason for it anymore.

I'm having some kind of misunderstanding even though both textures are intact. They are rendered as one texture of 512x1024x3 for some reason. Notice how this quad with tex coords from 0,0 to 1,1 is rendering the 512x1024 monstrocity twice from left to right.

And I just realized my pic is from calling glTexImage3d and giving the texture a depth of 2, not 4 like I wrote above. Here's what it looks like with 4, as you can see, it then repeats 4 times left to right and the texture is now 512x2048.
http://img315.imageshack.us/img315/3231/3dtexture43fo.th.jpg (http://img315.imageshack.us/my.php?image=3dtexture43fo.jpg)

dvm
07-13-2005, 04:09 AM
Hmm, as I've said, maybe opengl does not expect having such a big array. Can't you change it to a single pointer to GLubyte for each image;

T101
07-13-2005, 04:10 AM
OK. Something else (I had to look it up first):

According to the bluebook, it's:

void glTexCoord3d( GLdouble s, GLdouble t, GLdouble r ) That means that the slice is the third parameter, not the first.
Which would explain why the top part is different from the bottom half.
But I don't know why you're not getting interpolation.

avocados
07-13-2005, 04:22 AM
DVM, I'm not sure how I could store the array differently. A GLubyte is the same as an unsigned char, right? And I think openGL just reads 4*512*512*3 bytes in memory after my pointer, so the number of arrays wouldn't matter. Although... maybe I'll take a closer look and make sure the textures aren't losing resolution somehow.

avocados
07-13-2005, 04:29 AM
Its true, they listed the texture coord axes in a different order but its all relative! :)

dvm
07-13-2005, 04:53 AM
Well, for what I know even if I have a 1-D or 2-D texture I go on declaring it as a
GLubyte *bmpData;
Spot on for Glubyte being an unsigned char. I really don't know how opengl is reading the data, I'm just guessing since you have problems. Maybe you could try creating a small 4-D array and see in the debugger how the memory is mapped out.
My guess is that gl reads the first row_length * color_components * components_size bytes for each row. Then it reads the next row etc for image height . Then it goes to the next slice until it has all the slices. It's a bit hard as a concept to start with, 3D textures. Good luck!

T101
07-13-2005, 04:57 AM
OK. Now I'm confused:

According to what I've read (and according to the description of the various versions of texcoord in the bluebook), the r coordinate selects the slice, and s and t select the horizontal/vertical.
</font><blockquote><font size="1" face="Verdana, Arial">code:</font><hr /><pre style="font-size:x-small; font-family: monospace;"> +--------+
+--------+2|
+--------+1| |
|t 0| | |
|^ | | |

T101
07-13-2005, 05:00 AM
(Weird my post got truncated and it's listed as unregistered. Now I can't even edit it)

OK. Now I'm confused:

According to what I've read (and according to the description of the various versions of texcoord in the bluebook), the r coordinate selects the slice, and s and t select the horizontal/vertical.
</font><blockquote><font size="1" face="Verdana, Arial">code:</font><hr /><pre style="font-size:x-small; font-family: monospace;"> +--------+
+--------+2|
+--------+1| |
|t 0| | |
|^ | | |

T101
07-13-2005, 05:02 AM
(maybe it's the double "pipe")

+---------+
+---------+2|
+---------+1| |
| t 0| | |
| ^ | | |
| | | |-+
| -->s |-+
+---------+
S and T are always the "horizontal" and "vertical", R selects the slice.

You specify the following texture coordinates:

glTexCoord3d(0,0,1);
glTexCoord3d(0,0,0);
glTexCoord3d(0,1,0);
glTexCoord3d(0,1,1);The first is the bottom left corner of the second slice.
The second is the bottom left corner of the first slice.
The third is the top left corner of the first slice.
The last is the top left corner of the second slice.

So what I don't get is why you're still getting "proper" textures, not lines. Are the textures displayed rotated by 90 degrees by any chance?

avocados
07-13-2005, 06:47 AM
But its a volume of pixels, right? if it was 16x16x16, you could slice it in any direction. I'm reading my bmp files into the second array in bmp[2][512][512][3] because each row is going to be back to back in memory and its just easier to do it that way. If I had done bmp[512][512][2][3], I would have to skip every other RGB because the two textures would be interleaved in memory.

I found some source code... but its hard working with someone else's source. It doesn't look like he's doing anything differently. This is a good page complete with glut source and windows binary.

http://gpwiki.org/index.php/C:OpenGL_3D_Textures

avocados
07-13-2005, 07:02 AM
"I would have to skip every other RGB because the two textures would be interleaved in memory."

oh crap. :)

Thanks T101, there is something fishy here. Two pics interleaved in memory read in as one pic would produce this effect where they are half the size and rendered together.

avocados
07-13-2005, 03:12 PM
Alright then! I've got my 3d texture working. glTexImage3D reads the 3d texture array along the "width" of the volume. And that is important with non-cubic volumes, which I had some trouble realizing. So no more nice, neat, arrays of textures. The volume has to be rotated, which spreads the pixel data out in memory.