PDA

View Full Version : volume blending help!



arthas
12-20-2007, 04:16 AM
hi! i have a problem.. i tryed to implement a volume's slices blending using 3d texture. i can compile without problems, but when I run it, i have: exception not managed to 0x00000000 in volume.exe: 0xC0000005: Access Violation in reading path 0x00000000. please HELP!!

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

#include <gl\glew.h>
#include <gl\glut.h>
#include <gl\gl.h>
#include <gl\glu.h>
#include <windows.h>

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

//values of the volume: it's a volume of 3 blocks long z
char valuesVolume[12]={1,0,0,1,1,0,0,0,1,0,0,0};
valuesVolume[7]=DoubleToChar(1.0/2.0); //write the correct alphas
valuesVolume[11]=DoubleToChar(1.0/3.0);


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

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

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

// texture parameters
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)*/
// allocate graphic memory
glTexImage3D(GL_TEXTURE_3D,0,GL_RGBA, 1,1,3,0,GL_RGBA,GL_BYTE,valuesVolume);

/* 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 frame buffer and write them in "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",valuesVolume[i]);
printf("Data after roundtrip:\n");
for (int i=0; i<12; i++)
printf("%f\n",result[i]);
getchar();


return 0;

}

ZbuffeR
12-20-2007, 04:36 AM
Use a debugger.

arthas
12-20-2007, 04:40 AM
i used it.. the problem is here glTexImage3D(GL_TEXTURE_3D,0,GL_RGBA, 1,1,3,0,GL_RGBA,GL_BYTE,valuesVolume); but i don't understand why.. could you help me?

ZbuffeR
12-20-2007, 05:22 AM
Try with a 4x4x4 volume, as it mitigates the alignment effects.
See point 7 here :
http://www.opengl.org/resources/features/KilgardTechniques/oglpitfall/

-NiCo-
12-20-2007, 07:18 AM
Hmm, didn't you get a compiler warning when passing the data pointer? Try:

glTexImage3D(GL_TEXTURE_3D,0,GL_RGBA,1,1,3,0,GL_RG BA,GL_BYTE,&valuesVolume[0]);

Also, make sure your card supports ARB_texture_non_power_of_two.

N.

umugl
04-16-2008, 05:31 PM
glTexImage3D is an extension, for which you haven't gotten the procedure address. Thus you're calling a function at 0x00000000 and is why you are crashing. Get it's procedure address first.

micho2
04-17-2008, 01:46 AM
under windows try this code, like umugl said:
#ifdef _WIN32
PFNGLTEXIMAGE3DPROC glTexImage3D=0;
glTexImage3D = (PFNGLTEXIMAGE3DPROC) wglGetProcAddress("glTexImage3D");
#endif
if(glTexImage3D != NULL)
glTexImage3D(GL_TEXTURE_3D,......);

Relic
04-17-2008, 03:15 AM
Be careful with your data types as well!
You used char and GL_BYTE which is consistent, but if you actually want to read RGBA8 data and don't need signed chars you should change your data types to unsigned char or better GLubyte and GL_UNSIGNED_BYTE in the related places.
Reading from a fixed point color buffer will never result in negative values, using GL_BYTE just wastes a bit of precision.
Your conversion routine is not doing what the comment "0 to 255" indicates.

You should use GL_RGBA8 as internalFormat parameter in the glTexImage3D call. GL_RGBA is from older OpenGL versions and defined as 4. which just means "four components" but says nothing about the internal precision.

"glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP);"

A 3D texture needs to set the wrap mode the R coordinate as well and don't use GL_CLAMP unless you need it, you probably want GL_CLAMP_TO_EDGE. (Doesn't really matter for NEAREST filtering now, but just in case you switch to a linear filter in the future.)

Add glGetError() calls during debugging to catch problems, e.g. the non-power-of-two issue Nico mentioned.