volumetric rendering with 3D Textures

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

thanks all.

p.s. I think anyone can pick up 3D texturing reading this post

It’s a beautiful creation :slight_smile:

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).]

Dorbie, I’m having trouble combining these two postings into one piece of code…

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_FILTER,GL_NEAREST);
glTexParameteri(GL_TEXTURE_3D_EXT,GL_TEXTURE_MAG_FILTER,GL_NEAREST);

glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,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();

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?

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.

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, &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_FILTER,GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,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, &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);
    }
    
    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(&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; 
}

bump.

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…

Wow I can’t belive the usefulness of that responce…
Anger edited.