Hi!
I have implemented a Ray-Casting algorithm using GPU. I’m having a framebuffer object with 3 textures attached to it (1 for the front face of the cube, one for the backface and one in which I would like to have my results). Of course I have a 3d texture too.
Code where I define textures and attach them to the farame buffer:
glGenTextures(1, &backfaceTex);
glBindTexture(GL_TEXTURE_2D, backfaceTex);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
glTexImage2D(GL_TEXTURE_2D, 0,GL_RGBA16F_ARB, WINDOW_SIZE, WINDOW_SIZE, 0, GL_RGBA, GL_FLOAT, NULL);
glGenTextures(1, &frontfaceTex);
glBindTexture(GL_TEXTURE_2D, frontfaceTex);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
glTexImage2D(GL_TEXTURE_2D, 0,GL_RGBA16F_ARB, WINDOW_SIZE, WINDOW_SIZE, 0, GL_RGBA, GL_FLOAT, NULL);
glGenTextures(1, &final_image);
glBindTexture(GL_TEXTURE_2D, final_image);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
glTexImage2D(GL_TEXTURE_2D, 0,GL_RGBA16F_ARB, WINDOW_SIZE, WINDOW_SIZE, 0, GL_RGBA, GL_FLOAT, NULL);
glGenFramebuffersEXT(1, &framebuffer);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT,framebuffer);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, backfaceTex, 0);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,GL_COLOR_ATTACHMENT1_EXT, GL_TEXTURE_2D, frontfaceTex, 0);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,GL_COLOR_ATTACHMENT2_EXT, GL_TEXTURE_2D, final_image, 0);
glGenRenderbuffersEXT(1, &renderbuffer);
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, renderbuffer);
glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, WINDOW_SIZE, WINDOW_SIZE);
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, renderbuffer);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
code for getting the two textures needed at ray casting:
void drawCubesToTextures()
{
static float rotate = 0;
//rotate += 15.25;
//std::cout<<rotate<<std::endl;
glPushMatrix();
resize(WINDOW_SIZE,WINDOW_SIZE);
glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, framebuffer);
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, renderbuffer);
glLoadIdentity();
glTranslatef(0,0,-2.25);
glRotatef(rotate,0,0,1);
glTranslatef(-0.5,-0.5,-0.5);// center the texturecube
glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, framebuffer);
//Back face cube
glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
glEnable(GL_CULL_FACE);
glCullFace(GL_FRONT);
drawQuads(1.0,1.0, 1.0);
glDisable(GL_CULL_FACE);
//end Back face cube
//Front face cube
glDrawBuffer(GL_COLOR_ATTACHMENT1_EXT);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);
drawQuads(1.0,1.0, 1.0);
glDisable(GL_CULL_FACE);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
glPopMatrix();
//end Front face cube
}
display function, where my problem appears: How to get the final image rendered to final_image texture, as in the code presented below it does not matter what texture I’m binding, or if I’m binding any, the volumetric image obtained after the ray casting algorithm will appear. (ray casting works just fine, I just want to put the result in the final_image texture)
void display()
{
drawCubesToTextures();
GLint location1,location2, location3D, locationTF;
//trying to render to GL_COLOR_ATTACHMENT2_EXT (final_image)
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, framebuffer);
glDrawBuffer(GL_COLOR_ATTACHMENT2_EXT);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
setShaders();
location1=glGetUniformLocationARB(p,"frontTexture");
glActiveTextureARB(GL_TEXTURE0_ARB);
glBindTexture(GL_TEXTURE_2D, frontfaceTex);
glUniform1iARB(location1, 0);
location2=glGetUniformLocationARB(p,"backTexture");
glActiveTextureARB(GL_TEXTURE1_ARB);
glBindTexture(GL_TEXTURE_2D, backfaceTex);
glUniform1iARB(location2, 1);
location3D=glGetUniformLocationARB(p,"texture3d");
glActiveTextureARB(GL_TEXTURE2_ARB);
glBindTexture(GL_TEXTURE_3D, texName3d);
glUniform1iARB(location3D, 2);
locationTF=glGetUniformLocationARB(p,"texTF");
glActiveTextureARB(GL_TEXTURE3_ARB);
glBindTexture(GL_TEXTURE_1D, texTF);
glUniform1iARB(locationTF, 3);
printInfoLog(v);
printInfoLog(f);
glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);
drawQuads(1.0,1.0, 1.0);
glDisable(GL_CULL_FACE);
releaseShaders();
//display final image
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
glLoadIdentity();
reshape_ortho(WINDOW_SIZE,WINDOW_SIZE);
glEnable(GL_TEXTURE_2D);
//?????????????
//glBindTexture(GL_TEXTURE_2D,final_image);
glBindTexture(GL_TEXTURE_2D,frontfaceTex);
///??????????????
glBegin( GL_QUADS );
glTexCoord2d(0.0,0.0); glVertex2f(0.0,0.0);
glTexCoord2d(1.0,0.0); glVertex2f(1.0,0.0);
glTexCoord2d(1.0,1.0); glVertex2f(1.0,1.0);
glTexCoord2d(0.0,1.0); glVertex2f(0.0,1.0);
glEnd();
glutSwapBuffers();
}
Shaders:
varying vec2 texCoord;
varying vec2 texCoord2;
varying vec3 texCoord3d;
varying vec4 Pos;
varying vec3 normal;
void main()
{
//gl_Position = ftransform();
Pos = gl_ModelViewProjectionMatrix * gl_Vertex;
texCoord = gl_MultiTexCoord0.st;
gl_Position = Pos;
normal = gl_NormalMatrix * gl_Normal ;
}
uniform sampler2D frontTexture;
uniform sampler2D backTexture;
uniform sampler3D texture3d;
uniform sampler1D texTF;
varying vec4 Pos;
varying vec3 normal;
varying vec2 texCoord;
void main()
{
float stepsize=0.02;
vec2 texc = ( (Pos.xy / Pos.w) + 1.0) / 2.0; // find the right place to lookup in the backside buffer
texc = (Pos.xy+1.0)/2.0;
//gl_FragColor = vec4 (0.0,0.0,0.2, 1.0);
vec4 start = texture2D(backTexture,texCoord);
vec4 stop = texture2D(frontTexture,texCoord);
vec3 dir = -start.xyz + stop.xyz;
float len = length (dir.xyz);
vec3 norm_dir = dir;
float delta = stepsize;
vec3 delta_dir = norm_dir * delta;
float delta_dir_len = length(delta_dir);
vec3 vec = start.xyz;
vec4 col_acc = vec4(0,0,0,0);
float alpha_acc = 0.0;
float length_acc = 0.0;
vec4 color_sample;
float alpha_sample;
for(int i = 0; i < 8; i++)
{
color_sample = texture3D(texture3d,vec);
alpha_sample = color_sample.a * stepsize;
col_acc += (1.0 - alpha_acc) * color_sample * alpha_sample * 3.0;
alpha_acc += alpha_sample;
vec += delta_dir;
length_acc += delta_dir_len;
if(length_acc >= len || alpha_acc > 1.0) break; // terminate if opacity > 1 or the ray is outside the volume
}
gl_FragColor = col_acc;
//gl_FragColor = texture1D(texTF,col_acc.r);
//gl_FragColor = vec4(color_sample);
}
tnx for your help,
Paul
p.s. most of the code is from:
http://www.daimi.au.dk/~trier/?page_id=98