PDA

View Full Version : volumetric rendering with 3D Textures



PhilY
06-10-2002, 04:42 AM
I'm trying to use 3D textures for volumetric rendering...

I've created the texture in memory; I'm not too sure how to actually use it (show it) for volumetric rendering. I've found this http://www.opengl.org/developers/code/sig99/advanced99/notes/node299.html but it seems not very efficient.

I was thinking more like creating a cube (or box) and bind the 3D texture to the cube - not just surfaces but the whole volumetric texture. Is such way possible?

Thanks.

[This message has been edited by PhilY (edited 06-10-2002).]

davepermen
06-10-2002, 05:20 AM
gl draws triangles.
textured triangles.

this should answer your question..

dorbie
06-10-2002, 05:40 AM
That's not much of an answer. This is not a simple texturing operation.

For volume rendering you must draw many slices through the volume to sample the texture along the ray paths and accumulate the final color to the framebuffer.

This page should help:
http://www.dorbie.com/volume.html

Here's another link:
http://www.sgi.com/software/opengl/advanced97/notes/node179.html#SECTION000150000 000000000000 (http://www.sgi.com/software/opengl/advanced97/notes/node179.html#SECTION000150000000000000000)

There are more sophisticated approaches now which improve on the simple slice approach using multitexture and dependent reads, I'm not sure you need that but here's a link:
http://www9.informatik.uni-erlangen.de/Persons/Rezk/paper/paper_HWWS00.pdf

P.S. your notes link didn't work for me. The link I gave is probably similar but earlier. It is not efficient, but it is faster than other methods due to the hardware acceleration. You need a prodigeous ammount of textured blended pixel fill performance for OpenGL volume rendering and generally you try and keep the resolution low. You shouldn't need a high resolution result because the volume typically isn't that high resolution anyway.


[This message has been edited by dorbie (edited 06-10-2002).]

PhilY
06-10-2002, 08:32 AM
Thanks for your replies.

I accidentally put a comma at the end of the link - it's fixed now. However, it seems like they're about the same, as you noted, dorbie. I actually checked out your site a few days ago searching through google. Your page is very informative.

I think I'll read through the paper that you've linked. It seems like something I might actually implement. Thanks for your help, dorbie.

davepermen
06-10-2002, 09:25 AM
Originally posted by dorbie:
That's not much of an answer. This is not a simple texturing operation.

actually it IS the answer..

all you can do to render a 3d volume is render textured triangles. as slices. as mentoyed above from himself. he asked for a bether way but there is no really bether way wich works fast on hardware. and why? because all gl does is drawing triangles. textured triangles..

http://www.opengl.org/discussion_boards/ubb/smile.gif (or points or lines)

JasonM [ATI]
06-11-2002, 09:28 PM
For more source, you may also want to check out the RadeonVolVis (http://www.ati.com/developer/sdk/RadeonSDK/Html/Samples/OpenGL/RadeonVolVis.html) sample, which will run on any part supporting 3D textures including any chips in the RADEON 7000 and 8000 series (and beyond).

-Jason

PhilY
06-13-2002, 11:57 AM
I've implemented the 3D volume thingy and it almost works correctly http://www.opengl.org/discussion_boards/ubb/smile.gif

I'm rotating the model in respect to the X and the Y axis. When rotation about one single axis, everything is fine. However, if I rotate it about x and y axes, the texture and clipping planes rotate about different axes http://www.opengl.org/discussion_boards/ubb/frown.gif

I can't seem to find what is causing this. I'm not even using the MODELVIEW matrix, just the texture matrix. Any help will be greatly appreciated.

I've closely followed dorbie's example; here are some main parts of the code:


//-------------------------Texture Creation------------------------
glGenTextures(1,&ThreeDTexture);
glBindTexture(GL_TEXTURE_3D_EXT,ThreeDTexture);
glTexImage3DEXT(GL_TEXTURE_3D_EXT,0,GL_RGBA,64,64, 64,0,GL_RGBA,GL_UNSIGNED_BYTE,data);

glTexParameteri(GL_TEXTURE_3D_EXT,GL_TEXTURE_MIN_F ILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_3D_EXT,GL_TEXTURE_MAG_F ILTER,GL_LINEAR);

glTexParameteri(GL_TEXTURE_3D_EXT,GL_TEXTURE_WRAP_ S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_3D_EXT,GL_TEXTURE_WRAP_ T, GL_CLAMP);
glTexParameteri(GL_TEXTURE_3D_EXT,GL_TEXTURE_WRAP_ R_EXT, GL_CLAMP);


glEnable(GL_TEXTURE_GEN_S);
glEnable(GL_TEXTURE_GEN_T);
glEnable(GL_TEXTURE_GEN_R);

glEnable(GL_TEXTURE_3D_EXT);


//----------------------Rotation and Clipping----------------------

double eqnxy1[] = {0.0, 0.0, 1.0, 0};
double eqnxy2[] = {0.0, 0.0, -1.0, 1};
double eqnxz1[] = {0.0, 1.0, 0.0, 0};
double eqnxz2[] = {0.0, -1.0, 0.0, 1};
double eqnzy1[] = {1.0, 0.0, 0.0, 0};
double eqnzy2[] = {-1.0, 0.0, 0.0, 1};

glMatrixMode(GL_TEXTURE);

glLoadIdentity();

glTranslatef(.5, .5, .5);

glRotatef(rotateY, 1,0,0);
glRotatef(rotateX, 0,1,0);

float textureRotationMatrix[16];
glGetFloatv(GL_TEXTURE_MATRIX, textureRotationMatrix);

for(i=0; i<4; i++) {
clipEquation[i]=0.0;
for(j=0; j<4; j++)
clipEquation[i]+=textureRotationMatrix[i*4+j]*eqnxy1[j];
}

for(i=0; i<3; i++)
clipEquation[i]/=clipEquation[3];

clipEquation[3] = 1.0;

glClipPlane(GL_CLIP_PLANE0, &clipEquation[0]);
if (clipping) glEnable(GL_CLIP_PLANE0);


//.....and so on for all 6 clipping planes

//----------------------Finally, Rendering----------------------------

float planeS[] = {1,0,0,1};
float planeT[] = {0,1,0,1};
float planeR[] = {0,0,1,1};


glBindTexture(GL_TEXTURE_3D_EXT, ThreeDTexture);
glBegin(GL_QUADS);

for (float a = 0.0; a < 1.0; a += .02){

glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
glTexGenfv(GL_S, GL_EYE_PLANE, planeS);

glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
glTexGenfv(GL_T, GL_EYE_PLANE, planeT);

glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
glTexGenfv(GL_R, GL_EYE_PLANE, planeR);

glTexParameteri(GL_TEXTURE_3D_EXT,GL_TEXTURE_WRAP_ S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_3D_EXT,GL_TEXTURE_WRAP_ T, GL_CLAMP);
glTexParameteri(GL_TEXTURE_3D_EXT,GL_TEXTURE_WRAP_ R_EXT, GL_CLAMP);

glVertex3f(-1 ,-1 ,a);
glVertex3f(-1 ,1 ,a);
glVertex3f(1 ,1 ,a);
glVertex3f(1 ,-1 ,a);
}

glEnd();

[This message has been edited by PhilY (edited 06-13-2002).]

[This message has been edited by PhilY (edited 06-14-2002).]

PhilY
06-14-2002, 07:23 AM
ehhh... correction...

I just found out that nothing really works in the above code http://www.opengl.org/discussion_boards/ubb/frown.gif The texture coordinate generation only works if there is no rotation at all --> I guess I have to rotate plane[S,T,R] by the rotation matrix as well?

Again, any help will be greatly appreciated http://www.opengl.org/discussion_boards/ubb/smile.gif

dorbie
06-14-2002, 08:19 AM
Yes S,T,R has to be rotated.

You can use the modelview to transform the clip planes and the texgen equations. I suggest you do this, it's easier to tie them together.

The other way is to keep the whole thing fixed and use the modelview to rotate the viewer. This is completely equivalent but just a different way of conceptualizing things.

So apply the transformation to the modelview (inverse view or model, pick your poison). Then apply the clip planes and texgen. Then pop the modelview stack and draw the slice planes at the right depth in eye space (I think this is correct but it's untested). Applying the texgen in object space after the modelview manipulations means they will be transformed with the volume so no need for a texture matrix or manual manipulations.

I'd isolate each effect and try to get it working, for example get the planes fixed in eyespace under transform. Next get the texgen working with rotation on these planes. Next get the clip planes working.

dorbie
06-15-2002, 05:42 PM
P.S. when I say 'planes' on it's own in the last paragraph I mean the textured polygon slices through the data. Sorry if this caused confusion with "clip planes".

PhilY
06-18-2002, 11:12 AM
Hi, dorbie, thanks once again for your help.

First, the clipping problem was due to me not rendering the quads along the z-axis far enough. I was rendering them from -1 to 1, but when the cube gets rotated , it goes beyond [-1,1], obviously. I feel pretty stupid about that http://www.opengl.org/discussion_boards/ubb/smile.gif

I wrote a simple code to follow what you've suggested - quite an elegant way! The clipping planes are transformed fine but the texture does not want to get transformed no matter that I try to do. Even if I explicitly set the current matrix mode to texture and load the model transform matrix (commented out in the code below), I do not see any transformation. So basically, the texture stays the same no matter what the rotation but the clipping planes are working fine.

The below is my code, yet again, quite different this time. Do you see anything obvious that I've missed?

Another thing. I don't think I understand the automatic texture coordinate generation very well. For one thing, when the planes cross the 3D texture, the 3D texture can be projected on to the planes with as many as 6 vertices. But the quads only have 4 vertices and texture coordinates and the vertices are one-to-one match, correct? I'm a bit confused http://www.opengl.org/discussion_boards/ubb/frown.gif Would anyone know any good source to learn this from? (I've tried Red/Blue book, MSDN, and searching this forum)

glGenTextures(1,&ThreeDTexture);
glBindTexture(GL_TEXTURE_3D_EXT,ThreeDTexture);
glTexImage3DEXT(GL_TEXTURE_3D_EXT,0,GL_RGBA,SIZEX, SIZEY,SIZEZ,0,GL_RGBA,GL_UNSIGNED_BYTE,data);

glTexParameteri(GL_TEXTURE_3D_EXT,GL_TEXTURE_MIN_F ILTER,GL_NEAREST);
glTexParameteri(GL_TEXTURE_3D_EXT,GL_TEXTURE_MAG_F ILTER,GL_NEAREST);

glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTE R,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTE R,GL_LINEAR);

glTexParameteri(GL_TEXTURE_3D_EXT,GL_TEXTURE_WRAP_ S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_3D_EXT,GL_TEXTURE_WRAP_ T, GL_CLAMP);
glTexParameteri(GL_TEXTURE_3D_EXT,GL_TEXTURE_WRAP_ R_EXT, GL_CLAMP);


glEnable(GL_TEXTURE_GEN_S);
glEnable(GL_TEXTURE_GEN_T);
glEnable(GL_TEXTURE_GEN_R);

glEnable(GL_TEXTURE_3D_EXT);

double eqnxy1[] = {0.0, 0.0, 1.0, 0};
double eqnxy2[] = {0.0, 0.0, -1.0, 1};
double eqnxz1[] = {0.0, 1.0, 0.0, 0};
double eqnxz2[] = {0.0, -1.0, 0.0, 1};
double eqnzy1[] = {1.0, 0.0, 0.0, 0};
double eqnzy2[] = {-1.0, 0.0, 0.0, 1};

float planeS[] = {1,0,0,1};
float planeT[] = {0,1,0,1};
float planeR[] = {0,0,1,1};

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);


glMatrixMode(GL_MODELVIEW);

glLoadIdentity();

//Rotations
glTranslatef(.5, .5, .5);
glRotatef(rotateY, 1,0,0);
glRotatef(rotateX, 0,1,0);
glTranslatef(-.5, -.5, -.5);

//Store the MODELVIEW matrix into memory
float modelMatrix[16];
glGetFloatv(GL_MODELVIEW_MATRIX, modelMatrix);

//Set clipping planes
glClipPlane(GL_CLIP_PLANE0, &eqnxy1[0]);
glClipPlane(GL_CLIP_PLANE1, &eqnxy2[0]);
glClipPlane(GL_CLIP_PLANE2, &eqnxz1[0]);
glClipPlane(GL_CLIP_PLANE3, &eqnxz2[0]);
glClipPlane(GL_CLIP_PLANE4, &eqnzy1[0]);
glClipPlane(GL_CLIP_PLANE5, &eqnzy2[0]);

//Enable to the clipping planes
if (clipping){
glEnable(GL_CLIP_PLANE0);
glEnable(GL_CLIP_PLANE1);
glEnable(GL_CLIP_PLANE2);
glEnable(GL_CLIP_PLANE3);
glEnable(GL_CLIP_PLANE4);
glEnable(GL_CLIP_PLANE5);
}

glBindTexture(GL_TEXTURE_3D_EXT,ThreeDTexture);

glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);

//Start drawing the QUADs
glBegin(GL_QUADS);

for (float a = -2.0; a < 2.0; a += DISTANCE){

planeS[3] = planeT[3] = planeR[3] = a;

//glMatrixMode(GL_TEXTURE);
//glLoadMatrixf(modelMatrix);

//Generate the texture coordinates
glTexGenfv(GL_S, GL_EYE_PLANE, planeS);
glTexGenfv(GL_T, GL_EYE_PLANE, planeT);
glTexGenfv(GL_R, GL_EYE_PLANE, planeR);

//Render the QUADs using identity matrix
glPushMatrix();
glLoadIdentity();
glVertex3f(-2 ,-2 ,a);
glVertex3f(-2 ,2 ,a);
glVertex3f(2 ,2 ,a);
glVertex3f(2 ,-2 ,a);
glPopMatrix();

}

glEnd();

dorbie
06-18-2002, 01:12 PM
The biggest problem is you don't switch back to modelview matrix after you load on the texture matrix.

Equally bad, you're not allowed to do this stuff inside begin and end, that will be sure to cause problems esp. with the matrix stuff. Move begin end around your primitives.

Your code around the quad drawing is nasty. You also manipulate the plane equations with 'a' DON'T.

Move the push pop outside the loop.

Move the texgen stuff outside the loop.

One area I'm rusty on is the transformation of the plane equations through the modelview when specified. I dunno if this happens and whether it's object_plane or eye_plane do this.

This might make the texture matrix manips redundant, just a thought. For now apply them when the modelview is ident and go with the texture matrix manipulations. Experiment later if you want to eliminate texgen.

Try this, it's untested but close I think, and probably more elegant than you thought possible.





glMatrixMode(GL_TEXTURE);
glLoadMatrixf(modelMatrix);
glMatrixMode(GL_MODELVIEW);

glPushMatrix();
glLoadIdentity();

//Generate the texture coordinates
glTexGenfv(GL_S, GL_EYE_PLANE, planeS);
glTexGenfv(GL_T, GL_EYE_PLANE, planeT);
glTexGenfv(GL_R, GL_EYE_PLANE, planeR);

//Start drawing the QUADs
glBegin(GL_QUADS);

for (float a = -2.0; a < 2.0; a += DISTANCE){
glVertex3f(-2 ,-2 ,a);
glVertex3f(-2 ,2 ,a);
glVertex3f(2 ,2 ,a);
glVertex3f(2 ,-2 ,a);
}

glEnd();

glPopMatrix();



I explain texgen here:
http://www.dorbie.com/aqua.html


[This message has been edited by dorbie (edited 06-18-2002).]

Won
06-19-2002, 05:34 AM
While your answer was "true" it was nowhere near complete. It is obvious that OpenGL draws primarily textured triangles and not volumes. What is not obvious to everybody is how to use textured triangles to render a volume.

It's also obvious from your other posts that you have alot of experience with OpenGL, but alot of your comments (like this one) come off as rude, even when you are "right." It is not reasonable to expect Phil to conclude what you know about volumetric rendering from your curt suggestion, particularly if he's asking the question in the first place.

-Won

--EDIT--

Whoops! I should've indicated that this messages was intended for Dave. Sorry for the confusion!

[This message has been edited by Won (edited 06-19-2002).]

dorbie
06-19-2002, 07:11 AM
Won,

Phew, I thought you were talking to me when I started to read this, I wish you'd address it to the intended recipient :-).

PhilY, one other thing with identity on the modelview you are rendering in eyespace when you draw your quad slices. This means that you don't need to draw from -2 to 2. Itterate 'a' from -2 to -near_clip (or -4 to -near_clip), I'm unclear on your cube dimensions, and you need to ensure rotated corners don't get clipped on the far end of the volume.

If you want to translate the volume a distance away from the viewer you must ensure the slices cover the projected region in eyespace. Making this automatic would require adding a translation component to remain on the modelview and it probably wouldn't complicate the other stuff because your texgen etc is in eye space, but leaving it in eyespace would be important. All you'd do is leave the cube translate on the modelview when drawing the slice quads without the rotates. You then itterate 'a' from -1 to 1. (or -2 to 2 depending on the cube size I suppose).

Maybe you currently just draw it around the eye with you in the middle in that case you just need to add a translation immediately before the quad rendering loop (I think that's right).


[This message has been edited by dorbie (edited 06-19-2002).]

PhilY
06-19-2002, 08:32 AM
Thanks again, dorbie, for your help.

Won, thanks for your comment; I thought it was directed towards dorbie as well until I read dorbie's response http://www.opengl.org/discussion_boards/ubb/confused.gif

I'm trying to process all this information right now... I haven't been doing OpenGL (or graphics in general) for long, maybe 6 months or so; I'm kinda slow http://www.opengl.org/discussion_boards/ubb/smile.gif

I lost a little interest in this right now; I thought it was a real quick thing -> just change all gl...2D to gl...3D http://www.opengl.org/discussion_boards/ubb/biggrin.gif I was wrong.

I AM going to get this working in the near future, however, and I'll give you follow up on that. Once again, thank you very much, dorbie, for your help.

dorbie
06-19-2002, 08:41 AM
This is pretty advanced stuff you're attempting. Also, I don't think anyone does 3D volume rendering quite the same way I do :-). This is the "fully automatic use OpenGL to do as much of the work as possible" approach. You'll notice that when you get this working OpenGL will pretty much be doing ALL the calculations including slice clipping. Your hand coded transformations will be virtually non existant, you'll be using the modelview matrix and texture matrix for all transformations with no complex slice generation.

Won
06-19-2002, 09:31 AM
All -- sorry for the confusion from before! The post is now editted.

There are some other approaches for volume rendering, too. If the volume data is sparse, you might be able to just get away with drawing each of the voxels as points or imposter sprites.

Also, you can try to polygonalize the data using marching cubes. There are libraries that can do this for you like VTK (www.kitware.com).

I know that neither of these have anything to do with using volume textures, but thought I'd suggest some possible alternatives.

-Won

dorbie
06-19-2002, 09:59 AM
Won, the first approach you suggested is called "splatting".

The slice sampling of 3D texture in not unique but I haven't seen anyone else implement it as automatically in OpenGL. Typically there's a lot of CPU code generating slices and even texcoords in some cases. None of that is required if it's implemented as I'm describing. It's no big deal really but some implementations end up doing the whole thing entirely in hardware which is nice. It's just interesting to exercise OpenGL and keep the application code this simple. Ultimately it's equivalent to all other slicing approaches.

[This message has been edited by dorbie (edited 06-19-2002).]

davepermen
06-19-2002, 09:21 PM
Originally posted by Won:
..your message..(saving space)

sorry for sounding rude. i just don't have much time to write messages currently, thats all.
well, why i gave no more answers is simple:

a) he states the solution himself and asks if there is a direct volume rendering way. my answer in so far is an indirect but quite clear no. he knows yet the slice way, as he posts the link with the slice way. so i don't need to mentoin it

b) i have no practical expirience with 3dtextures. i have a gf2mx only.. can't wait to play with 3dtextures myself, thought.. (they simplify perpixellightingsetups quite much..)

i try to not sound rude anymore. had a little war with dorbie, i bet that gave a bad view to both me and dorbie (at least, dorbie first thought you ment him, and others, too http://www.opengl.org/discussion_boards/ubb/wink.gif). my statements about cg are not sweet neighter but well, thats just mather of opinion http://www.opengl.org/discussion_boards/ubb/wink.gif.

won: about the drawing voxels as points or imposter sprites. well, this idea is quite good. with VAR you get that quite fast even on my fillratelimited gf2mx. and you can use the volumetric texture there as well (well.. i can't http://www.opengl.org/discussion_boards/ubb/wink.gif) and bind this to colorize the voxels automatically. its possibly the most easy approach (and the most "static" one, set up the vertexarray and just plot it down). but slicing is the fastest i guess.

marching cubes, well yeah. but it doesn't look like a typical volumetric object (they look so ghostlike you know http://www.opengl.org/discussion_boards/ubb/wink.gif)

PhilY
06-20-2002, 09:01 AM
Won, thanks for your suggestions. "Splatting" was something I had thought about - a bunch of 0 dimensional textures (actually a two dimensional texture that is 1X1) freely rotating depending on the view. I'm trying to learn 3D textures right now, tho.

Dorbie, I have another question for you, hopefully the last one - at least on this matter http://www.opengl.org/discussion_boards/ubb/smile.gif

All seemed well; then, I hit the same wall I had hit before, back when I was rotating the texture matrix manually - week ago?

The problem is that when the object is rotated about the y-axis and then about the x-axis, the clipping planes rotate in absolute manner (rotates about the axes of the view) while the texture rotates about its own axes.

I have assured and verified again and yet again that the MODELVIEW matrix and the TEXTURE matrix are identical. I guess I could manipulate either of the matrices so that the behaviors are the same but I prolly missed something obvious - order ?, or maybe there's yet another elegant way to fix this in GL?

I can't thank you enough, dorbie.

Here is the code: (I just figured out that UBB codes are enabled here http://www.opengl.org/discussion_boards/ubb/smile.gif )



glMatrixMode(GL_MODELVIEW);
glLoadIdentity();

//Rotations
glTranslatef(.5, .5, .5);
glRotatef(rotateY, 1,0,0);
glRotatef(rotateX, 0,1,0);
glTranslatef(-.5, -.5, -.5);

//Store the MODELVIEW matrix into memory
float modelMatrix[16];
glGetFloatv(GL_MODELVIEW_MATRIX, modelMatrix);

glMatrixMode(GL_TEXTURE);
glLoadMatrixf(modelMatrix);

glTranslatef(-1,-1,-1);

//Set clipping planes
glClipPlane(GL_CLIP_PLANE0, &amp;eqnxy1[0]);
glClipPlane(GL_CLIP_PLANE1, &amp;eqnxy2[0]);
glClipPlane(GL_CLIP_PLANE2, &amp;eqnxz1[0]);
glClipPlane(GL_CLIP_PLANE3, &amp;eqnxz2[0]);
glClipPlane(GL_CLIP_PLANE4, &amp;eqnzy1[0]);
glClipPlane(GL_CLIP_PLANE5, &amp;eqnzy2[0]);

//Enable to the clipping planes
if (clipping){
glEnable(GL_CLIP_PLANE0);
glEnable(GL_CLIP_PLANE1);
glEnable(GL_CLIP_PLANE2);
glEnable(GL_CLIP_PLANE3);
glEnable(GL_CLIP_PLANE4);
glEnable(GL_CLIP_PLANE5);
}

glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);

glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();

//Generate the texture coordinates
glTexGenfv(GL_S, GL_EYE_PLANE, planeS);
glTexGenfv(GL_T, GL_EYE_PLANE, planeT);
glTexGenfv(GL_R, GL_EYE_PLANE, planeR);

//Start drawing the QUADs
glBegin(GL_QUADS);
for (float a = -2.0; a < 2.0; a += DISTANCE){
glVertex3f(-2 ,-2 ,a);
glVertex3f(-2 ,2 ,a);
glVertex3f(2 ,2 ,a);
glVertex3f(2 ,-2 ,a);
}
glEnd();

glPopMatrix();



[This message has been edited by PhilY (edited 06-20-2002).]

PhilY
06-21-2002, 06:23 AM
Update:

It was just a matter of rotation order. I rotated the texture matrix in different order (x then y instead of y then x), while keeping the order for the modelview matrix the same, it now seems to be working http://www.opengl.org/discussion_boards/ubb/smile.gif http://www.opengl.org/discussion_boards/ubb/smile.gif

thanks all.

p.s. I think anyone can pick up 3D texturing reading this post http://www.opengl.org/discussion_boards/ubb/biggrin.gif

dorbie
06-21-2002, 06:30 AM
It's a beautiful creation :-)

Don't forget that with identity on the modelview you don't need to render the full range of quads. Itterate 'a' over a smaller distance unless you intend translating the geometry around (see above).

Instead of lifting the matrix off the modelview and loading on the texture matrix you could apply the same transforms on the texture matrix. It's just a very minor nit.

[This message has been edited by dorbie (edited 06-21-2002).]

KraftDinner
10-15-2004, 11:43 AM
Dorbie, I'm having trouble combining these two postings into one piece of code...




glGenTextures(1,&amp;ThreeDTexture);
glBindTexture(GL_TEXTURE_3D_EXT,ThreeDTexture);
glTexImage3DEXT(GL_TEXTURE_3D_EXT,0,GL_RGBA,SIZEX, SIZEY,SIZEZ,0,GL_RGBA,GL_UNSIGNED_BYTE,data);

glTexParameteri(GL_TEXTURE_3D_EXT,GL_TEXTURE_MIN_F ILTER,GL_NEAREST);
glTexParameteri(GL_TEXTURE_3D_EXT,GL_TEXTURE_MAG_F ILTER,GL_NEAREST);

glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTE R,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTE R,GL_LINEAR);

glTexParameteri(GL_TEXTURE_3D_EXT,GL_TEXTURE_WRAP_ S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_3D_EXT,GL_TEXTURE_WRAP_ T, GL_CLAMP);
glTexParameteri(GL_TEXTURE_3D_EXT,GL_TEXTURE_WRAP_ R_EXT, GL_CLAMP);


glEnable(GL_TEXTURE_GEN_S);
glEnable(GL_TEXTURE_GEN_T);
glEnable(GL_TEXTURE_GEN_R);

glEnable(GL_TEXTURE_3D_EXT);

double eqnxy1[] = {0.0, 0.0, 1.0, 0};
double eqnxy2[] = {0.0, 0.0, -1.0, 1};
double eqnxz1[] = {0.0, 1.0, 0.0, 0};
double eqnxz2[] = {0.0, -1.0, 0.0, 1};
double eqnzy1[] = {1.0, 0.0, 0.0, 0};
double eqnzy2[] = {-1.0, 0.0, 0.0, 1};

float planeS[] = {1,0,0,1};
float planeT[] = {0,1,0,1};
float planeR[] = {0,0,1,1};

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);


glMatrixMode(GL_MODELVIEW);

glLoadIdentity();

//Rotations
glTranslatef(.5, .5, .5);
glRotatef(rotateY, 1,0,0);
glRotatef(rotateX, 0,1,0);
glTranslatef(-.5, -.5, -.5);

//Store the MODELVIEW matrix into memory
float modelMatrix[16];
glGetFloatv(GL_MODELVIEW_MATRIX, modelMatrix);

//Set clipping planes
glClipPlane(GL_CLIP_PLANE0, &amp;eqnxy1[0]);
glClipPlane(GL_CLIP_PLANE1, &amp;eqnxy2[0]);
glClipPlane(GL_CLIP_PLANE2, &amp;eqnxz1[0]);
glClipPlane(GL_CLIP_PLANE3, &amp;eqnxz2[0]);
glClipPlane(GL_CLIP_PLANE4, &amp;eqnzy1[0]);
glClipPlane(GL_CLIP_PLANE5, &amp;eqnzy2[0]);

//Enable to the clipping planes
if (clipping){
glEnable(GL_CLIP_PLANE0);
glEnable(GL_CLIP_PLANE1);
glEnable(GL_CLIP_PLANE2);
glEnable(GL_CLIP_PLANE3);
glEnable(GL_CLIP_PLANE4);
glEnable(GL_CLIP_PLANE5);
}

glBindTexture(GL_TEXTURE_3D_EXT,ThreeDTexture);

glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);

//Start drawing the QUADs
glBegin(GL_QUADS);

for (float a = -2.0; a < 2.0; a += DISTANCE){

planeS[3] = planeT[3] = planeR[3] = a;

//glMatrixMode(GL_TEXTURE);
//glLoadMatrixf(modelMatrix);

//Generate the texture coordinates
glTexGenfv(GL_S, GL_EYE_PLANE, planeS);
glTexGenfv(GL_T, GL_EYE_PLANE, planeT);
glTexGenfv(GL_R, GL_EYE_PLANE, planeR);

//Render the QUADs using identity matrix
glPushMatrix();
glLoadIdentity();
glVertex3f(-2 ,-2 ,a);
glVertex3f(-2 ,2 ,a);
glVertex3f(2 ,2 ,a);
glVertex3f(2 ,-2 ,a);
glPopMatrix();

}

glEnd(); AND




glMatrixMode(GL_TEXTURE);
glLoadMatrixf(modelMatrix);
glMatrixMode(GL_MODELVIEW);

glPushMatrix();
glLoadIdentity();

//Generate the texture coordinates
glTexGenfv(GL_S, GL_EYE_PLANE, planeS);
glTexGenfv(GL_T, GL_EYE_PLANE, planeT);
glTexGenfv(GL_R, GL_EYE_PLANE, planeR);

//Start drawing the QUADs
glBegin(GL_QUADS);

for (float a = -2.0; a < 2.0; a += DISTANCE){
glVertex3f(-2 ,-2 ,a);
glVertex3f(-2 ,2 ,a);
glVertex3f(2 ,2 ,a);
glVertex3f(2 ,-2 ,a);
}

glEnd();

glPopMatrix();Can you clarify this?

dorbie
10-15-2004, 12:27 PM
It pretty much replaces the last few lines. From about the bind onwards. You should really try to gain an understanding and implement from first prinncipals. PhilY's final code post is probably the cleaner example. There's a lot of setup in the larger example and you should be trying to understand the transformation of texture and clip planes.

KraftDinner
10-15-2004, 12:40 PM
Well I've banged my head till it black and blue...
This code doesn't work!

This is the best I can do to piece together this thread into an application....


#include <GL/glut.h>
#include <stdlib.h>
#include <stdio.h>

#define border (0)
#define iWidth (16+2*border)
#define iHeight (16+2*border)
#define iDepth (16+2*border)

static GLubyte image[iDepth][iHeight][iWidth][3];
static GLuint texName;
static int screenWidth;
static int screenHeight;

void makeImage(void)
{
int s, t, r;
for (r=0; r < iDepth; ++r)
{
for (t=0; t < iHeight; ++t)
{
for (s=0; s < iWidth; ++s)
{
image[r][t][s][0] = 0;
image[r][t][s][1] = 0;
image[r][t][s][2] = 255;
}
}
}

for (r=border; r < iDepth-border; ++r)
{
for (t=border; t < iHeight-border; ++t)
{
for (s=border; s < iWidth; ++s)
{
image[r][t][s][0] = (GLubyte) ((s-1) * 17);
image[r][t][s][1] = (GLubyte) ((t-1) * 17);
image[r][t][s][2] = (GLubyte) ((r-1) * 17);
}
}
}
}

void init(void)
{
glClearColor (0.0, 0.0, 0.0, 0.0);
glShadeModel(GL_FLAT);
glEnable(GL_DEPTH_TEST);

makeImage();

glPixelStorei(GL_UNPACK_ALIGNMENT, 1);

glGenTextures(1, &amp;texName);
glBindTexture(GL_TEXTURE_3D, texName);

glTexImage3D(GL_TEXTURE_3D, 0, GL_RGB, iWidth, iHeight, iDepth, border, GL_RGB, GL_UNSIGNED_BYTE, image);

glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTE R,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTE R,GL_LINEAR);

glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP);//_TO_BORDER);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP);//_TO_BORDER);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP);//_TO_BORDER);

glEnable(GL_TEXTURE_GEN_S);
glEnable(GL_TEXTURE_GEN_T);
glEnable(GL_TEXTURE_GEN_R);

glEnable(GL_TEXTURE_3D);
}

void display(void)
{
static float rotateX = 0.0f;
static float rotateY = 0.0f;
static float rotateZ = 0.0f;
const bool clipping = true;

double eqnxy1[] = { 0.0, 0.0, 1.0, 0};
double eqnxy2[] = { 0.0, 0.0, -1.0, 1};
double eqnxz1[] = { 0.0, 1.0, 0.0, 0};
double eqnxz2[] = { 0.0, -1.0, 0.0, 1};
double eqnzy1[] = { 1.0, 0.0, 0.0, 0};
double eqnzy2[] = {-1.0, 0.0, 0.0, 1};

float planeS[] = {1,0,0,1};
float planeT[] = {0,1,0,1};
float planeR[] = {0,0,1,1};

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();

//Rotations
glTranslatef(.5, .5, .5);
glRotatef(rotateX, 1,0,0);
glRotatef(rotateY, 0,1,0);
glRotatef(rotateZ, 0,0,1);
glTranslatef(-.5, -.5, -.5);

//Store the MODELVIEW matrix into memory
float modelMatrix[16];
glGetFloatv(GL_MODELVIEW_MATRIX, modelMatrix);

glMatrixMode(GL_TEXTURE);
glLoadMatrixf(modelMatrix);

glTranslatef(-1,-1,-1);

//Set clipping planes
glClipPlane(GL_CLIP_PLANE0, &amp;eqnxy1[0]);
glClipPlane(GL_CLIP_PLANE1, &amp;eqnxy2[0]);
glClipPlane(GL_CLIP_PLANE2, &amp;eqnxz1[0]);
glClipPlane(GL_CLIP_PLANE3, &amp;eqnxz2[0]);
glClipPlane(GL_CLIP_PLANE4, &amp;eqnzy1[0]);
glClipPlane(GL_CLIP_PLANE5, &amp;eqnzy2[0]);

//Enable to the clipping planes
if (clipping)
{
glEnable(GL_CLIP_PLANE0);
glEnable(GL_CLIP_PLANE1);
glEnable(GL_CLIP_PLANE2);
glEnable(GL_CLIP_PLANE3);
glEnable(GL_CLIP_PLANE4);
glEnable(GL_CLIP_PLANE5);
}

glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);

glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();

//Generate the texture coordinates
glTexGenfv(GL_S, GL_EYE_PLANE, planeS);
glTexGenfv(GL_T, GL_EYE_PLANE, planeT);
glTexGenfv(GL_R, GL_EYE_PLANE, planeR);

//Start drawing the QUADs
glBegin(GL_QUADS);
for (float a = -2.0; a < 2.0; a += .2)
{
glVertex3f(-2, -2, a);
glVertex3f(-2, 2, a);
glVertex3f( 2, 2, a);
glVertex3f( 2, -2, a);
}
glEnd();

glPopMatrix();

glFlush();
glutSwapBuffers();

rotateX += .05f;
rotateY += .025f;
rotateZ += .0125f;
}

void reshape(int w, int h)
{
screenWidth=w;
screenHeight=h;

glViewport(0, 0, (GLsizei) w, (GLsizei) h);

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
//gluOrtho2D(0,w-1,h-1,0);
gluPerspective(60.0, (GLfloat) w / (GLfloat) h, 1.0, 30.0);
glTranslatef(0.0F, 0.0F, -5.0F); /* Move camera back */

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();

glMatrixMode(GL_TEXTURE);
glLoadIdentity();
}

void keyboard(unsigned char key, int x, int y)
{
static bool fullscreen=false;
switch (key)
{
case 27:
exit(0);
break;
case 'f':
case 'F':
if (fullscreen)
{
glutReshapeWindow(250, 250);
glutPositionWindow(100, 100);
fullscreen = false;
}
else
{
glutFullScreen();
fullscreen = true;
}
break;
default:
display();
}
}

void idle(void)
{
glutPostRedisplay();
}

int main(int argc, char** argv)
{
glutInit(&amp;argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH);
glutInitWindowSize(250, 250);
glutInitWindowPosition(100, 100);
glutCreateWindow(argv[0]);
init();
glutReshapeFunc(reshape);
glutDisplayFunc(display);
glutIdleFunc(idle);
glutKeyboardFunc (keyboard);
glutMainLoop();
return 0;
}

KraftDinner
10-17-2004, 11:46 AM
bump.

knackered
10-18-2004, 03:39 AM
I am so proud of davepermen - all my time tutoring him in the ways of the dark side were not in vain.
Now dave - on to the next lesson - have you heard of a drug called heroin? Now before you say anything, it's not as bad as it's made out, y'know...here, have this free sample, see what y'think.....

KraftDinner
10-18-2004, 08:40 AM
Wow I can't belive the usefulness of that responce..
Anger edited.