PDA

View Full Version : help volume!! please, it's Christmas!!



arthas
12-27-2007, 03:31 PM
Hi! The program I wrote, should read the values of a volume ( the array “volumevalues” is an example of 1x1x3 volume) map it into 3 poligons, blend them, and put the result in an array. It should simulate a radiography..
I have a problem, the program compiles, and runs.. but the result is:

Data before roundtrip:
0,000000
0,000000
0,000000
0,000000
0,000000
0,000000
0,000000
0,000000
0,000000
0,000000
0,000000
0,000000
Data after roundtrip:
0,000000
0,000000
0,000000
0,000000
0,000000
0,000000
0,000000
0,000000
0,000000
0,000000
0,000000
0,000000

Instead it should be the result of the volume values blended!Anyone has an idea? Please help!!

#include <cstdio>
#include <cstdlib>
using namespace std;


// --------------------------------------------
// Include
#include <gl\glew.h>
#include <gl\glut.h>
#include <gl\gl.h>
#include <gl\glu.h>

#include <windows.h>

//transform alpha from double to char
char DoubleToChar(double alpha){
return (char)(alpha*255,0);
}
int main(int argc, char **argv) {

//volume values: the volume contains 3 values along z
unsigned char volumevalues[12]={1,0,0,1,1,0,0,0,1,0,0,0};
volumevalues[7]=DoubleToChar(1.0/2.0);
volumevalues [11]=DoubleToChar(1.0/3.0);

unsigned char result[12]; //array for the result

// initialize glut
glutInit (&argc, argv);
glutCreateWindow("radiographic sumulation");
glewInit();

// create the texture
GLuint tex;
glGenTextures (1, &tex);
glBindTexture(GL_TEXTURE_3D,tex);

// sets the texture parameter
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP);

/*void glTexImage3D (GLenum target,GLint level,GLint internalformat,GLsizei width,GLsizei height,GLsizei depth,GLint border,GLenum format,GLenum type,const GLvoid * pixels)*/
// allocates graphic memory
glTexImage3D(GL_TEXTURE_3D,0,GL_RGBA,1,1,3,0,GL_RG BA,GL_UNSIGNED_BYTE, volumevalues);

/* void gluOrtho2D(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top); The clipping region is a rectangle with the lower-left corner at (left, bottom) and the upper-right corner at (right, top).
void glViewport(GLint x, GLint y, GLsizei width, GLsizei height); Defines a pixel rectangle in the window into which the final image is mapped. The (x, y) parameter specifies the lower-left corner of the
viewport, and width and height are the size of the viewport rectangle.*/
//viewport transform for 1:1 pixel=texel=data mapping
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0.0,1,0.0,1);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glViewport(0,0,1,1);



glClear(GL_COLOR_BUFFER_BIT);
glPushMatrix();

glEnable(GL_TEXTURE_3D);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);


float z= ((float)1)/3;
float y =((float)1)/3;
glBegin(GL_QUADS);
glTexCoord3f(0.0,0.0,0.0); glVertex2f(0,0);
glTexCoord3f(0.0,1.0,0.0); glVertex2f(0,1);
glTexCoord3f(1.0,1.0,0.0); glVertex2f(1,1);
glTexCoord3f(1.0,0.0,0.0); glVertex2f(1,0);

glTexCoord3f(0.0,0.0,z); glVertex2f(0,0);
glTexCoord3f(0.0,1.0,z); glVertex2f(0,1);
glTexCoord3f(1.0,1.0,z); glVertex2f(1,1);
glTexCoord3f(1.0,0.0,z); glVertex2f(1,0);

glTexCoord3f(0.0,0.0,y); glVertex2f(0,0);
glTexCoord3f(0.0,1.0,y); glVertex2f(0,1);
glTexCoord3f(1.0,1.0,y); glVertex2f(1,1);
glTexCoord3f(1.0,0.0,y); glVertex2f(1,0);

glEnd();
glPopMatrix();


/*void glReadBuffer(GLenum mode): specifies a color buffer as the source for subsequent read and copy image commands*/
/*void glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels);*/
//reads datas from the frame buffer and put them into array "result"
glReadBuffer(GL_FRONT);
glReadPixels(0,0,1,1,GL_RGBA,GL_BYTE,result);

// print out results
printf("Data before roundtrip:\n");
for (int i=0; i<12; i++)
printf("%f\n", volumevalues [i]);
printf("Data after roundtrip:\n");
for (int i=0; i<12; i++)
printf("%f\n",result[i]);
getchar();


return 0;

}

arthas
12-28-2007, 03:33 AM
after the line glTexImage3D(GL_TEXTURE_3D,0,GL_RGBA,1,1,3,0,GL_RG BA,GL_UNSIGNED_BYTE, volumevalues);
i added a subroutine to check errors:
GLenum errCode;
const GLubyte *errString;
if ((errCode = glGetError()) != GL_NO_ERROR) {
errString = gluErrorString(errCode);
fprintf (stderr, "OpenGL Error: %s\n", errString);
}
but the output doesn't change :(

-NiCo-
12-28-2007, 07:13 AM
Well, first of all, I'm wondering what the comma is doing in:


char DoubleToChar(double alpha){
return (char)(alpha*255,0);
}

You probably meant to write a dot.

Secondly, I think you'll be better of using GLubyte instead of char, but that's just a matter of opinion.

Finally, you can't use %f in a printf function to print out chars. Check this:

char b = 128;
fprintf(stderr,"%f\n",b);


The results will always be 0.00000

N.

arthas
12-28-2007, 01:01 PM
thanks NiCo, i'm a totally stupid! i've corrected the printf:

printf("Data before roundtrip:\n");
for (int i=0; i<12; i++)
printf("%d\n",volumevalues[i]);
printf("Data after roundtrip:\n");
for (int i=0; i<12; i++)
printf("%d\n",result[i]);

the volume values(i changed the values of Red channel because i can have different values in the "slices"):

unsigned char volumevalues[12]={1,0,0,1,2,0,0,0,3,0,0,0};
volumevalues[3]=DoubleToChar(1.0);
volumevalues[7]=DoubleToChar(1.0/2.0);
volumevalues[11]=DoubleToChar(1.0/3.0);

and i think that i must change these values, because texture coordinates must be normalized fro 0 to 1, so I need to move along the volume:

float z= ((float)1)/3;
float y =((float)2)/3;

and now the output is:

data before roundtrip:
1
0
0
255
2
0
0
127
3
0
0
85
data after roundtrip:
0
0
0
127
204
204
204
204
204
204
204
204

the question are:
1) now the code is correct?
2) i read the result array, that should containd the values read from the frame buffer after the computation, so, in teory only a plane made of the 3 slices blended. why it contains 12 values? (= 3 slices?)

km,
12-28-2007, 03:12 PM
Use your planes (proxy-geometry) such that it is positioned appropriately in the volume. Currently all QUADS are at same position.

If you are doing back to front rendering (compositing) then try to pre-multiply you color with alpha and use blending function as
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA)

Also try to read the framebuffer before and ensure that it is cleared.

You have never initialized your result buffer, so it is bound to contain some junk values. Initialize result array to 0.

If even this fails, try to read back float values from the framebuffer as it will ensure that driver is not converting your RGBA and atleast you can confirm whether color is being composited correctly.

arthas
12-29-2007, 02:43 AM
i know that quads are at the same position, because what i want to do is blend 3 slices ( along z assix);what the program should do, is read the slices' values from the 3d texture, draw one at once and blend with the slices in the framebuffer ( initially the framebuffer is cleared) so, what i need to do is change the 3d texture position( i suppose). i'm just using glBlendFunc, and I clear the framebuffer.