• Advertisement
Sign in to follow this  

Volume Rendering problem

This topic is 4796 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi! I have a problem with the code below. It loads a model in rvf format and render it using 2D textures. The problem is that when I use modify the opacity of the color palette, the model disappears and I can't find why. Note that I am running it on Linux RHEL 3.0 with ATI9200 graphics card (direct rendering enabled). I can send the project by email if necessary. Many thanks.


/*
 * file  : volume.c

#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <time.h>
#include <GL/glut.h>
#include "texture3d.h"
#include "tga.h"
#include "bmp.h"

/* display list */
#define Z_FRONT 1
#define Z_BACK  2
#define Y_FRONT 3
#define Y_BACK  4
#define X_FRONT 5
#define X_BACK  6

/* palette */
#define PALETTE_SIZE    32
#define PALETTE_XOFFSET  5
#define PALETTE_YOFFSET  5

/* mouse mode */
#define ROTATION        1
#define COLOR_SELECTION 2

/* globals */
int   xs=500,ys=400;
/* BLEND and DEPTH_TEST */
int   alpha=1,depth=0;
int   drawCube=1,projection=1;
int   s1,s2,s3;
/* rotation & mouse */
float scaleFactor=1.;
int   oldx=0,oldy=0,xrot=0,yrot=0;
int   dx,dy;
int   inverseZ=1;
int   mode=ROTATION;
int   color_1,color_2;
/* texture */
tex3   tex;
int    px,py,pz;
GLuint *XTextureId;
GLuint *YTextureId;
GLuint *ZTextureId;
unsigned char *tex_buf;
/* palette */
char   *palname="default.pal";
GLuint checkerId;
unsigned char *pal;
unsigned char *reset_pal;
//char *filename="vht.rvf";
char *filename="brainsmall.rvf";
//char *filename="teddybear.raw"; // 128*128*62
//char   *filename="head.raw";
//char *filename="engine.raw";
//char* filename="nucleon.raw";
//char *filename="CT_Head_small.raw";
/* profiling */
int frame=0;
int oldtime=0;





int power[10]={
	1,2,4,8,16,32,64,128,256,512};

/* find the nearest power of two after t */
int nextPower(int t){
	int i;
	for(i=0;i<10;i++){
		if (power>=t)
			return power;
	}
	return 512;
}

/* load a nice default palette */
void load_default_palette(unsigned char *pal){
	int i;
	for(i=0;i<85;i++){
		pal[4*i+0]=i*3;
		pal[4*i+1]=0;
		pal[4*i+2]=0;
		pal[4*i+3]=i;
	}
	for(i=0;i<85;i++){
		pal[4*(i+85)+0]=255;
		pal[4*(i+85)+1]=i*3;
		pal[4*(i+85)+2]=0;
		pal[4*(i+85)+3]=i+85;
	}
	for(i=0;i<86;i++){
		pal[4*(i+85+85)+0]=(85-i)*3;
		pal[4*(i+85+85)+1]=255;
		pal[4*(i+85+85)+2]=i*3;
		pal[4*(i+85+85)+3]=i+85+85;
	}
}

/* load a palette from an ASCII file (unix's return style )*/
int load_palette(char *name,unsigned char *c){
	FILE *fp;
	int index=0;
	fp=fopen(name,"r");
	if (fp==NULL)
		return -1;
	while(fscanf(fp,"%d %d %d %d",c+index*4+0,c+index*4+1,c+index*4+2,c+index*4+3)==4){
		//		glutSetColor(index,(float)c[index*4]/256.,(float)c[index*4+1]/256.,(float)c[index*4+2]/256.);
		index++;
	}
	fclose(fp);
	return index!=256;
}

/* make the palette from c1 to c2 transparent */
void zeroAlpha(unsigned char *c,int c1,int c2){
	int i;
	if (c1>c2){
		i=c1;
		c1=c2;
		c2=i;
	}
	for(i=c1;i<=c2;i++){
		c[i*4+3]=0;
	}
}

/* reset the palette from c1 to c2 */
void resetAlpha(unsigned char *c,int c1,int c2){
	int i;
	if (c1>c2){
		i=c1;
		c1=c2;
		c2=i;
	}
	for(i=c1;i<=c2;i++){
		c[i*4+3]=reset_pal[i*4+3];
	}
}


void init_palette(){
	/* try to load the palette */
	pal=(unsigned char*)malloc(256*4);
	if (pal==NULL){
		fprintf(stderr,"Out of memory\n");
		exit(-1);
	}
	reset_pal=(unsigned char *)malloc(4*256);
	if (reset_pal==NULL){
		fprintf(stderr,"load_default_palette() : Out of memory\n");
		exit(-1);
	}
	if (load_palette(palname,reset_pal)){
		printf("no palette found (making default)\n");
		load_default_palette(reset_pal);
	}
	/* copy it */
	memcpy(pal,reset_pal,4*256);
	
	// test opacity
	zeroAlpha(pal,0,20);
	zeroAlpha(pal,240,255);
}

/* load a volume and create slices of it */
void load_tex(char *name){
	unsigned char *checker_buf;
	int i,j,k;
	float x,y,z;

	init_palette();
	/* load it */
	printf("loading 3d texture '%s' ... ",name);
	fflush(stdout);
	//	if (load_raw(&tex,name,128,128,62)){
	if (load_rvf(&tex,name)){
		fprintf(stderr,"abort\n");
		exit(-1);
	}
	px=nextPower(tex.x);
	py=nextPower(tex.y);
	pz=nextPower(tex.z);
	printf("done (%dx%dx%d)->(%dx%dx%d)\n",tex.x,tex.y,tex.z,px,py,pz);
	/* ask for some textures */
	XTextureId=(GLuint *)malloc(sizeof(GLuint)*tex.x);
	if (XTextureId==NULL){
		fprintf(stderr,"load_tex() : Out of memory\n");
		exit(-1);
	}
	YTextureId=(GLuint *)malloc(sizeof(GLuint)*tex.y);
	if (YTextureId==NULL){
		fprintf(stderr,"load_tex() : Out of memory\n");
		exit(-1);
	}
	ZTextureId=(GLuint *)malloc(sizeof(GLuint)*tex.z);
	if (ZTextureId==NULL){
		fprintf(stderr,"load_tex() : Out of memory\n");
		exit(-1);
	}

	/* generate textures */
	glGenTextures(tex.x,XTextureId);
	glGenTextures(tex.y,YTextureId);
	glGenTextures(tex.z,ZTextureId);
	glGenTextures(1,&checkerId);

	/* create slices */
	printf("creating slices [");
	fflush(stdout);

	/* xy slices */
	/* allocate a texture buffer */
	tex_buf=(unsigned char *)calloc(4*px*py,1);
	if (tex_buf==NULL){
		fprintf(stderr,"load_tex() : Out of memory\n");
		exit(-1);
	}

	/* xy-->z */
	for (k=0;k<tex.z;k+=1){
		if (floor(10.*k/tex.z)==(10.*k/tex.z)){
			printf("#");
			fflush(stdout);
		}
		glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
		glBindTexture(GL_TEXTURE_2D,ZTextureId[k]);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,GL_LINEAR);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,GL_LINEAR);
		for(i=0;i<tex.x;i++){
			for(j=0;j<tex.y;j++){
				tex_buf[(i+j*px)*4+0]=pal[tex.texture[i+tex.x*(j+tex.y*k)]*4+0];
				tex_buf[(i+j*px)*4+1]=pal[tex.texture[i+tex.x*(j+tex.y*k)]*4+1];
				tex_buf[(i+j*px)*4+2]=pal[tex.texture[i+tex.x*(j+tex.y*k)]*4+2];
				tex_buf[(i+j*px)*4+3]=pal[tex.texture[i+tex.x*(j+tex.y*k)]*4+3];
			}
		}
		glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, px,py,0,GL_RGBA,GL_UNSIGNED_BYTE,tex_buf);
	}
	free(tex_buf);
	printf("|");
	fflush(stdout);

	/* yz slices */
	/* allocate a new texture buffer */

	tex_buf=(unsigned char *)calloc(4*pz*py,1);
	memset(tex_buf,0,4*pz*py);
	if (tex_buf==NULL){
		fprintf(stderr,"load_tex() : Out of memory\n");
		exit(-1);
	}
	/* zy-->x */
	for (i=0;i<tex.x;i+=1){
		if (floor(10.*i/tex.x)==(10.*i/tex.x)){
			printf("#");
			fflush(stdout);
		}
		glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
		glBindTexture(GL_TEXTURE_2D,XTextureId);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,GL_LINEAR);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,GL_LINEAR);
		for(k=0;k<tex.z;k++){
			for(j=0;j<tex.y;j++){
				tex_buf[(k+j*pz)*4+0]=pal[tex.texture[i+tex.x*(j+tex.y*k)]*4+0];
				tex_buf[(k+j*pz)*4+1]=pal[tex.texture[i+tex.x*(j+tex.y*k)]*4+1];
				tex_buf[(k+j*pz)*4+2]=pal[tex.texture[i+tex.x*(j+tex.y*k)]*4+2];
				tex_buf[(k+j*pz)*4+3]=pal[tex.texture[i+tex.x*(j+tex.y*k)]*4+3];
			}
		}
		glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, pz,py,0,GL_RGBA,GL_UNSIGNED_BYTE,tex_buf);
	}
	free(tex_buf);
	printf("|");
	fflush(stdout);

	/* xz slices */
	/* allocate a new texture buffer */

	tex_buf=(unsigned char *)calloc(4*pz*px,1);
	if (tex_buf==NULL){
		fprintf(stderr,"load_tex() : Out of memory\n");
		exit(-1);
	}
	/* xz-->y */
	for (j=0;j<tex.y;j+=1){
		if (floor(10.*j/tex.y)==(10.*j/tex.y)){
			printf("#");
			fflush(stdout);
		}
		glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
		glBindTexture(GL_TEXTURE_2D,YTextureId[j]);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,GL_LINEAR);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,GL_LINEAR);
		for(k=0;k<tex.z;k++){
			for(i=0;i<tex.x;i++){
				tex_buf[(i+k*px)*4+0]=pal[tex.texture[i+tex.x*(j+tex.y*k)]*4+0];
				tex_buf[(i+k*px)*4+1]=pal[tex.texture[i+tex.x*(j+tex.y*k)]*4+1];
				tex_buf[(i+k*px)*4+2]=pal[tex.texture[i+tex.x*(j+tex.y*k)]*4+2];
				tex_buf[(i+k*px)*4+3]=pal[tex.texture[i+tex.x*(j+tex.y*k)]*4+3];
			}
		}
		glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, px,pz,0,GL_RGBA,GL_UNSIGNED_BYTE,tex_buf);
	}
	free(tex_buf);

	printf("] done\n");
	fflush(stdout);


	/* a nice checker texture for the palette's background */
	checker_buf=(unsigned char *)malloc(4*PALETTE_SIZE*256);
	if (checker_buf==NULL){
		fprintf(stderr,"load_tex() : Out of memory\n");
		exit(-1);
	}
	glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
	glBindTexture(GL_TEXTURE_2D,checkerId);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,GL_NEAREST);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,GL_NEAREST);
	for(i=0;i<PALETTE_SIZE;i++){
		for(j=0;j<256;j++){
			int a,b,c,step;
			step=8;
			a=!((i/step)%2*255);
			b=((j/step)%2*255);
			c=a?(b?255:0):
			(b?0:255);
			checker_buf[(i+j*PALETTE_SIZE)*4+0]=c;
			checker_buf[(i+j*PALETTE_SIZE)*4+1]=c;
			checker_buf[(i+j*PALETTE_SIZE)*4+2]=c;
			checker_buf[(i+j*PALETTE_SIZE)*4+3]=(!c)*255;
		}
	}
	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,PALETTE_SIZE,256,0,GL_RGBA,GL_UNSIGNED_BYTE,checker_buf);
	free(checker_buf);

	/* display lists */
	printf("making the display list ... ");
	fflush(stdout);
	/* We must draw slices from back to front in order to have a correct blending.
	* That's why we have to create a list for each case
	*/
	glNewList(Z_FRONT,GL_COMPILE);
	for(k=pz-tex.z;k<pz;k++){
		z=1.-2.*k/pz;
		glEnable(GL_TEXTURE_2D);
		glBindTexture(GL_TEXTURE_2D,ZTextureId[pz-k-1]);
		glBegin(GL_QUADS);
		glTexCoord2f(0,1);
		glVertex3f(-1,1,z);
		glTexCoord2f(1,1);
		glVertex3f(1,1,z);
		glTexCoord2f(1,0);
		glVertex3f(1,-1,z);
		glTexCoord2f(0,0);
		glVertex3f(-1,-1,z);
		glEnd();
	}
	glEndList();

	glNewList(Z_BACK,GL_COMPILE);
	for(k=pz;k>(pz-tex.z);k--){
		z=1.-2.*k/pz;
		glEnable(GL_TEXTURE_2D);
		glBindTexture(GL_TEXTURE_2D,ZTextureId[pz-k]);
		glBegin(GL_QUADS);
		glTexCoord2f(0,1);
		glVertex3f(-1,1,z);
		glTexCoord2f(1,1);
		glVertex3f(1,1,z);
		glTexCoord2f(1,0);
		glVertex3f(1,-1,z);
		glTexCoord2f(0,0);
		glVertex3f(-1,-1,z);
		glEnd();
	}
	glEndList();

	glNewList(X_FRONT,GL_COMPILE);
	for(i=px;i>(px-tex.x);i--){
		x=-1.+2.*i/px;
		glEnable(GL_TEXTURE_2D);
		glBindTexture(GL_TEXTURE_2D,XTextureId[tex.x-px+i-1]);
		glBegin(GL_QUADS);
		glTexCoord2f(0,0);
		glVertex3f(x,-1,-1);
		glTexCoord2f(0,1);
		glVertex3f(x,1,-1);
		glTexCoord2f(1,1);
		glVertex3f(x,1,1);
		glTexCoord2f(1,0);
		glVertex3f(x,-1,1);
		glEnd();
	}
	glEndList();

	glNewList(X_BACK,GL_COMPILE);
	for(i=px;i>(px-tex.x);i--){
		x=1.-2.*i/px;
		glEnable(GL_TEXTURE_2D);
		glBindTexture(GL_TEXTURE_2D,XTextureId[px-i]);
		glBegin(GL_QUADS);
 		glTexCoord2f(0,0);
		glVertex3f(x,-1,-1);
		glTexCoord2f(0,1);
		glVertex3f(x,1,-1);
		glTexCoord2f(1,1);
		glVertex3f(x,1,1);
		glTexCoord2f(1,0);
		glVertex3f(x,-1,1);
		glEnd();
	}
	glEndList();

	glNewList(Y_FRONT,GL_COMPILE);
	for(j=py;j>(py-tex.y);j--){
		y=-1.+2.*j/py;
		glEnable(GL_TEXTURE_2D);
		glBindTexture(GL_TEXTURE_2D,YTextureId[tex.y-py+j-1]);
		glBegin(GL_QUADS);
		glTexCoord2f(0,0);
		glVertex3f(-1,y,-1);
		glTexCoord2f(0,1);
		glVertex3f(-1,y,1);
		glTexCoord2f(1,1);
		glVertex3f(1,y,1);
		glTexCoord2f(1,0);
		glVertex3f(1,y,-1);
		glEnd();
	}
	glEndList();

	glNewList(Y_BACK,GL_COMPILE);
	for(j=py;j>(py-tex.y);j--){
		y=1.-2.*j/py;
		glEnable(GL_TEXTURE_2D);
		glBindTexture(GL_TEXTURE_2D,YTextureId[py-j]);
		glBegin(GL_QUADS);
		glTexCoord2f(0,0);
		glVertex3f(-1,y,-1);
		glTexCoord2f(0,1);
		glVertex3f(-1,y,1);
		glTexCoord2f(1,1);
		glVertex3f(1,y,1);
		glTexCoord2f(1,0);
		glVertex3f(1,y,-1);
		glEnd();
	}
	glEndList();

	printf("done\n");
}

/* my nvidia tnt2 doesn't have the paletted texture extension */
void update_tex(){
	int i,j,k;
//	float x,y,z;

	/* delete old textures */
	printf("updating 3d texture ... [");
	fflush(stdout);
	glDeleteTextures(tex.x,XTextureId);
	glDeleteTextures(tex.y,YTextureId);
	glDeleteTextures(tex.z,ZTextureId);
	if (XTextureId==NULL){
		fprintf(stderr,"load_tex() : Out of memory\n");
		exit(-1);
	}
	if (YTextureId==NULL){
		fprintf(stderr,"load_tex() : Out of memory\n");
		exit(-1);
	}
	if (ZTextureId==NULL){
		fprintf(stderr,"load_tex() : Out of memory\n");
		exit(-1);
	}
	/* generate textures */
	glGenTextures(tex.x,XTextureId);
	glGenTextures(tex.y,YTextureId);
	glGenTextures(tex.z,ZTextureId);

	// xy-->z
	tex_buf=(unsigned char *)calloc(4*px*py,1);
	memset(tex_buf,0,4*px*py);
	if (tex_buf==NULL){
		fprintf(stderr,"load_tex() : Out of memory\n");
		exit(-1);
	}

	for (k=0;k<tex.z;k+=1){
		if (floor(10.*k/tex.z)==10.*k/tex.z){
			printf("#");
			fflush(stdout);
		}
		glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
		glBindTexture(GL_TEXTURE_2D,ZTextureId[k]);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,GL_LINEAR);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,GL_LINEAR);
		for(i=0;i<tex.x;i++){
			for(j=0;j<tex.y;j++){
				tex_buf[(i+j*px)*4+0]=pal[tex.texture[i+tex.x*(j+tex.y*k)]*4+0];
				tex_buf[(i+j*px)*4+1]=pal[tex.texture[i+tex.x*(j+tex.y*k)]*4+1];
				tex_buf[(i+j*px)*4+2]=pal[tex.texture[i+tex.x*(j+tex.y*k)]*4+2];
				tex_buf[(i+j*px)*4+3]=pal[tex.texture[i+tex.x*(j+tex.y*k)]*4+3];
			}
		}
		glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, px,py,0,GL_RGBA,GL_UNSIGNED_BYTE,tex_buf);
	}
	free(tex_buf);

	// zy-->x
	tex_buf=(unsigned char *)calloc(4*pz*py,1);
	memset(tex_buf,0,4*pz*py);
	if (tex_buf==NULL){
		fprintf(stderr,"load_tex() : Out of memory\n");
		exit(-1);
	}
	for (i=0;i<tex.x;i+=1){
		if (floor(10.*i/tex.x)==10.*i/tex.x){
			printf("#");
			fflush(stdout);
		}
		glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
		glBindTexture(GL_TEXTURE_2D,XTextureId);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,GL_LINEAR);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,GL_LINEAR);
		for(k=0;k<tex.z;k++){
			for(j=0;j<tex.y;j++){
				tex_buf[(k+j*pz)*4+0]=pal[tex.texture[i+tex.x*(j+tex.y*k)]*4+0];
				tex_buf[(k+j*pz)*4+1]=pal[tex.texture[i+tex.x*(j+tex.y*k)]*4+1];
				tex_buf[(k+j*pz)*4+2]=pal[tex.texture[i+tex.x*(j+tex.y*k)]*4+2];
				tex_buf[(k+j*pz)*4+3]=pal[tex.texture[i+tex.x*(j+tex.y*k)]*4+3];
			}
		}
		glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, pz,py,0,GL_RGBA,GL_UNSIGNED_BYTE,tex_buf);
	}
	free(tex_buf);

	tex_buf=(unsigned char *)calloc(4*pz*px,1);
	memset(tex_buf,0,4*pz*px);
	if (tex_buf==NULL){
		fprintf(stderr,"load_tex() : Out of memory\n");
		exit(-1);
	}
	// xz-->y
	for (j=0;
	j<tex.y;
	j+=1){
		if (floor(10.*j/tex.y)==10.*j/tex.y){
			printf("#");
			fflush(stdout);
		}
		glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
		glBindTexture(GL_TEXTURE_2D,YTextureId[j]);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,GL_LINEAR);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,GL_LINEAR);
		for(k=0;k<tex.z;k++){
			for(i=0;i<tex.x;i++){
				tex_buf[(i+k*px)*4+0]=pal[tex.texture[i+tex.x*(j+tex.y*k)]*4+0];
				tex_buf[(i+k*px)*4+1]=pal[tex.texture[i+tex.x*(j+tex.y*k)]*4+1];
				tex_buf[(i+k*px)*4+2]=pal[tex.texture[i+tex.x*(j+tex.y*k)]*4+2];
				tex_buf[(i+k*px)*4+3]=pal[tex.texture[i+tex.x*(j+tex.y*k)]*4+3];
			}
		}
		glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, px,pz,0,GL_RGBA,GL_UNSIGNED_BYTE,tex_buf);
	}
	free(tex_buf);

	printf("] done\n");
	
}

/* draw the palette */
void drawPalette(unsigned char *pal){
	int i;
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	glOrtho(0,xs,0,ys,0.001,1000);
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
	glColor3f(0.5,0.5,0.5);
	/* background */
	glEnable(GL_TEXTURE_2D);
	glBindTexture(GL_TEXTURE_2D,checkerId);
	glBegin(GL_QUADS);
	glTexCoord2f(0,1);
	glVertex3f(xs-PALETTE_SIZE-PALETTE_XOFFSET,PALETTE_YOFFSET,-1);
	glTexCoord2f(1,1);
	glVertex3f(xs-PALETTE_XOFFSET,PALETTE_YOFFSET,-1);
	glTexCoord2f(1,0);
	glVertex3f(xs-PALETTE_XOFFSET,256+PALETTE_YOFFSET,-1);
	glTexCoord2f(0,0);
	glVertex3f(xs-PALETTE_SIZE-PALETTE_XOFFSET,256+PALETTE_YOFFSET,-1);
	glEnd();
	glDisable(GL_TEXTURE_2D);
	/* palette */
	for(i=0;i<256;i++){
		glColor4ub(pal[i*4+0],pal[i*4+1],pal[i*4+2],pal[i*4+3]);
		glBegin(GL_LINES);
		glVertex3f(xs-PALETTE_SIZE-PALETTE_XOFFSET,i+PALETTE_YOFFSET,-1);
		glVertex3f(xs-PALETTE_XOFFSET,i+PALETTE_YOFFSET,-1);
		glEnd();
	}
	glColor3f(0,0,0);
	glBegin(GL_LINE_LOOP);
	glVertex3f(xs-PALETTE_SIZE-PALETTE_XOFFSET-3,PALETTE_YOFFSET-3,-1);
	glVertex3f(xs-PALETTE_XOFFSET+3,PALETTE_YOFFSET-3,-1);
	glVertex3f(xs-PALETTE_XOFFSET+3,256+PALETTE_YOFFSET+3,-1);
	glVertex3f(xs-PALETTE_SIZE-PALETTE_XOFFSET-3,256+PALETTE_YOFFSET+3,-1);
	glEnd();
	/* selection */
	if (mode==COLOR_SELECTION){
		glColor3f(0,0,0);
		glBegin(GL_LINE_LOOP);
		glVertex3f(xs-PALETTE_SIZE-PALETTE_XOFFSET,color_1+PALETTE_YOFFSET,-1);
		glVertex3f(xs-PALETTE_XOFFSET,color_1+PALETTE_YOFFSET,-1);
		glVertex3f(xs-PALETTE_XOFFSET,color_2+PALETTE_YOFFSET,-1);
		glVertex3f(xs-PALETTE_SIZE-PALETTE_XOFFSET,color_2+PALETTE_YOFFSET,-1);
		glEnd();
	}
}

void draw(){
//	float z;
//	int k;

	glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	if (projection)
		gluPerspective(40.,(float)(xs-PALETTE_SIZE)/(float)ys,0.1,1000);
	else
		glOrtho(-2,2,-2,2,0,1000);
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
	gluLookAt(0,2,-5,0,0,0,0,1,0);
	glRotatef(yrot,-1,0,0);
	glRotatef(xrot,0,1,0);
	glScalef(scaleFactor,(inverseZ?-1:1)*scaleFactor,scaleFactor);

	glEnable(GL_TEXTURE_2D);
	glColor3f(1,1,1);
	/* select which set of slices we should draw */
	if (yrot>23&&yrot<(23+90)){
		glCallList(Y_FRONT);
	}
	else{
		if (yrot<293&&yrot>(293-90)){
			glCallList(Y_BACK);
		}
		else{
			if (xrot>=315||xrot<=45){
				glCallList(Z_FRONT);
			}
			else {
				if (xrot>=135&&xrot<=225){
					glCallList(Z_BACK);
				}
				else{
					if (xrot>=45&&xrot<=135){
						glCallList(X_BACK);
					}
					else {
						glCallList(X_FRONT);
					}
				}
			}
		}
	}
	/* cube */
	if (drawCube){
		glDisable(GL_TEXTURE_2D);
		glColor3f(0,0,0);
		glLineWidth(1.5);
		glutWireCube(2);
	}
	/* palette */
	drawPalette(pal);
	glutSwapBuffers();
	frame++;
}


void reshape(int w, int h){
	xs=w;
	ys=h;
	glViewport(0, 0, w, h);
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	if (projection)
		gluPerspective(40.,(float)(w-PALETTE_SIZE)/(float)h,0.1,1000);
	else
		glOrtho(-2,2,-2,2,0,1000);
	glEnable(GL_TEXTURE_2D);
}

void mouse(int b,int state,int x,int y){
	if(state == GLUT_DOWN) {
		color_1=ys-y-PALETTE_YOFFSET;
		if (x>(xs-PALETTE_SIZE-PALETTE_XOFFSET)&&x<(xs-PALETTE_XOFFSET)){
			if (color_1>=0&&color_1<256){
				mode=COLOR_SELECTION;
				color_2=color_1;
				return;
			}
		}
		mode=ROTATION;
		oldx = x;
		oldy = y;
	}
	if (state==GLUT_UP){
		if (mode==COLOR_SELECTION){
			color_2=ys-y-PALETTE_YOFFSET;
			if (color_2<0)
				color_2=0;
			else
			    if (color_2>255)
				color_2=255;
			/* make the selection transparent */
			if (b==GLUT_LEFT_BUTTON)
				zeroAlpha(pal,color_1,color_2);
			if (b==GLUT_RIGHT_BUTTON)
				resetAlpha(pal,color_1,color_2);
			mode=ROTATION;
			update_tex();
		}
	}
	draw();
}

void motion(int x, int y) {
	if (mode==ROTATION){
		dx = x - oldx;
		dy = y - oldy;
		oldx = x;
		oldy = y;
		xrot+=dx/2;
		yrot+=dy/2;
		xrot=xrot<0?(xrot%360)+360:xrot%360;
		yrot=yrot<0?(yrot%360)+360:yrot%360;
	}
	if (mode==COLOR_SELECTION){
		color_2=ys-y-PALETTE_YOFFSET;
		if (color_2<0)
			color_2=0;
		else
		    if (color_2>255)
			color_2=255;
	}
	draw();
}

void idle(){
	char title[256];
	if (clock()-oldtime>CLOCKS_PER_SEC){
		sprintf(title,"Volume rendering with gl (%dfps)",frame);
		glutSetWindowTitle(title);
		frame=0;
		oldtime=clock();
	}
//	draw();
}

void keyboard(unsigned char key, int x, int y){
//	tga_t tga;
	bmp_t bmp;
	unsigned char *buf;
	char fn[256];
	static int id=0;

	switch (key) {
	case 'h':
		printf(" [s]   - take a snapshot \n");
		printf(" [+|-] - zoom \n");
		printf(" [c]   - toggle axis \n");
		printf(" 

- toggle projection mode\n"); printf(" [z] - inverse z axis\n"); printf(" [r] - reset palette\n"); break; case 's': init_bmp(&bmp,xs,ys,24); buf=(unsigned char*)malloc(3*xs*ys); if (buf==NULL){ fprintf(stderr,"Out of memory\n"); return; } glReadPixels(0, 0,xs,ys,GL_RGB,GL_UNSIGNED_BYTE, buf); sprintf(fn,"%s.%02d.bmp",filename,id); save_bmp(bmp,buf,fn); free(buf); id++; break; case '+': scaleFactor+=0.2; glutPostRedisplay(); break; case '-': scaleFactor-=0.2; glutPostRedisplay(); break; case 'a': if (alpha=!alpha) glEnable(GL_BLEND); else glDisable(GL_BLEND); glutPostRedisplay(); printf("alpha [%s]\n",alpha?"on":"off"); break; case 'd': if (depth=!depth) glEnable(GL_DEPTH_TEST); else glDisable(GL_DEPTH_TEST); glutPostRedisplay(); printf("depth [%s]\n",depth?"on":"off"); break; case 'c': printf("cube [%s]\n",(drawCube=!drawCube)?"on":"off"); glutPostRedisplay(); break; case 'p': printf("projection [%s]\n",(projection=!projection)?"perspective":"orthogonal"); reshape(xs,ys); glutPostRedisplay(); break; case 'z': printf("z [%s]\n",(inverseZ=!inverseZ)?"on":"off"); glutPostRedisplay(); break; case 'r': printf("reset palette\n"); memcpy(pal,reset_pal,256*4); update_tex(); break; case 27: if (tex.texture) free(tex.texture); exit(0); break; } } int main(int argc, char** argv){ glutInit(&argc, argv); glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_ALPHA | GLUT_DEPTH); /* glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH);*/ glutInitWindowSize (xs,ys); glutInitWindowPosition (0,0); glutCreateWindow("Volume rendering with gl"); glutReshapeFunc(reshape); glutDisplayFunc(draw); glutMouseFunc(mouse); glutMotionFunc(motion); glutKeyboardFunc (keyboard); glutIdleFunc(idle); /* enable transparency */ glEnable(GL_BLEND); glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); /* disable depth test */ glDisable(GL_DEPTH_TEST); glEnable(GL_TEXTURE_2D); /* check if there is an argument */ filename=argc>1?argv[1]:filename; /* load the volume */ load_tex(filename); /* I like this color */ glClearColor(1,1,1,1); glutMainLoop(); return 0; }

Share this post


Link to post
Share on other sites
Advertisement
first of all, no one is going to look at it as is, add [_source_] [_/source_] tags (with out the underscores) around your code, but also, no one WANTS to go through line after line of your(?) code, if nothing else, point us to certain portions of it to show us where you think the problem is and that youve done work on it before (well, youve doen that to some extent) but seriously large chunks of code scare people away

hope that helps
-Dan

Share this post


Link to post
Share on other sites
On the contrary I thought that someone would like to see most of the code, plus it is fairly short!
Anyways I think the problem comes from the function update_tex() which is called when the opacity is changed. I can't see what's wrong with it.

Thanks,

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement