Mzsmunna
10/16/2019 - 3:07 PM

Texture-3D


#include <GL/glut.h>
 
/*
  An example of using OpenGL to render a simple object with
  a texture. The texture is saved in a ppm format file.
  You can also use the program dmconvert to tell you more about
  the image file.
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

/*This next is referred to in several places, and because of the callback
interface, cannot be passed as a parameter, hence, global*/

/*WARNING - using the PPM file format, and you must delete the first few lines of text
starting only from the image size data*/

typedef GLubyte Pixel[3]; /*represents red green blue*/


int Width, Height; /*of image*/

/*array of pixels*/
Pixel *Image;

/*name of image file*/
char *Filename = "../default.ppm";

int allowedSize(int x)
/*returns max power of 2 <= x*/
{
	int r;
	
	r = 1;
	while(r < x) r=(r<<1);
	
	if(r==x) return r;	
	else return r>>1;
}

void readImage(void)
/*reads the image file assumes ppm format*/
{
	
	int w,h,max;
	int i,j;
	unsigned int r,g,b;
	int k;
	char ch;
	FILE *fp;
	
	fp = fopen(Filename,"r");
	
	printf("filename = %s\n",Filename);

	/*read the header*/
	
    fscanf(fp, "P%c\n", &ch);
	if (ch != '3') {
		fprintf(stderr, "Only ascii mode 3 channel PPM files");
		exit(-1);
	}

	/*strip comment lines*/
	ch = getc(fp);
	while (ch == '#') {
      do {
		  ch = getc(fp);
      }
	  while (ch != '\n');
      ch = getc(fp); 
    }
	ungetc(ch, fp);

	/*read the width*/
	fscanf(fp,"%d",&w);
	
	/*read the height*/
	fscanf(fp,"%d",&h);
	
	/*max intensity - not used here*/
	fscanf(fp,"%d",&max);
	
	/*width and height must be powers of 2 - taking the simple option
	here of finding the max power of 2 <= w and h*/

	Width = allowedSize(w);
	Height = allowedSize(h);
	
	printf("Width = %d, Height = %d\n",Width,Height);
	
	Image = (Pixel *)malloc(Width*Height*sizeof(Pixel));
	
	
	for(i=0;i<Height;++i){
		for(j=0;j<Width;++j) {
			fscanf(fp,"%d %d %d",&r,&g,&b);
			k = i*Width+j; /*ok, can be more efficient here!*/
			(*(Image+k))[0] = (GLubyte)r;
			(*(Image+k))[1] = (GLubyte)g;
			(*(Image+k))[2] = (GLubyte)b;
		}
		/*better scan to the end of the row*/
		for(j=Width; j<w; ++j) fscanf(fp,"%c %c %c",&r,&g,&b);
	}
	fclose(fp);
}


void initialiseTextures(void)
{
	GLint level = 0;      /*only one level - no level of detail*/
	GLint components = 3; /*3 means R, G, and B components only*/
	GLint border = 0;     /*no border around the image*/
	
	/*read the image file*/
	readImage();
	
	/*each pixelrow on a byte alignment boundary*/
	glPixelStorei(GL_UNPACK_ALIGNMENT,1);
	
	/*define information about the image*/
	glTexImage2D(GL_TEXTURE_2D,level,components,
			(GLsizei)Width, (GLsizei)Height,
		     	border, GL_RGB, GL_UNSIGNED_BYTE,Image);

	/*ensures that image is not wrapped*/
	glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP);
	glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP);
	
	/*chooses mapping type from texels to pixels*/
	glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
	glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
	/*this says for minification and magnfication choose texel that 
	GL_NEAREST chooses the texel nearest the centre of the pixel
	is nearest to the centre of the pixel, rather than GL_LINEAR which
	performs a linear interpolation on the 4 surrounding texels*/
	
	/*GL_DECAL - this says overwrite pixel with texture colour*/
	glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_DECAL);
	/*an alternative is GL_MODULATE which modulates the lighting
	by the texel value by multiplication*/
	
	/*this enables texturing*/
	glEnable(GL_TEXTURE_2D);
}
	
	
	

static void cubebase(void)
/*specifies a side of a cube*/
{
	glBegin(GL_POLYGON);
		glTexCoord2f(0.0,0.0);
		glVertex3d(-0.5,-0.5,0.0);
		
		glTexCoord2f(0.0,1.0);
		glVertex3d(-0.5,0.5,0.0);
		
		glTexCoord2f(1.0,1.0);
		glVertex3d(0.5,0.5,0.0);
		
		glTexCoord2f(1.0,0.0);
		glVertex3d(0.5,-0.5,0.0);
	glEnd();
}

static void cube(void)
/*uses cube side to construct a cube, making use of the modelview matrix*/
{
	/*make sure we're dealing with modelview matrix*/
	glMatrixMode(GL_MODELVIEW);
	        
	/*pushes and duplicates current matrix*/
	glPushMatrix();
	
	
	/*construct the base*/
	cubebase();
	
	glPushMatrix();
	/*construct side on +x axis*/
	glTranslated(0.5,0.0,0.5);
	glRotated(90.0,0.0,1.0,0.0);
	cubebase();
	
	glPopMatrix();

	/*construct side on -x axis*/
	glPushMatrix();
	glTranslated(-0.5,0.0,0.5);
	glRotated(-90.0,0.0,1.0,0.0);
	cubebase();
	glPopMatrix();

	/*construct side on +y axis*/
	glPushMatrix();
	glTranslated(0.0,0.5,0.5);
	glRotated(-90.0,1.0,0.0,0.0);
	cubebase();
	glPopMatrix();
	
	/*construct side on -y axis*/
	glPushMatrix();
	glTranslated(0.0,-0.5,0.5);
	glRotated(90.0,1.0,0.0,0.0);
	cubebase();
	glPopMatrix();

	/*construct top*/ 
	
	glBegin(GL_POLYGON);
		glTexCoord2f(0.0,0.0);
		glVertex3d(-0.5,-0.5,1.0);
		
		glTexCoord2f(1.0,0.0);
		glVertex3d(0.5,-0.5,1.0);
		
		glTexCoord2f(1.0,1.0);
		glVertex3d(0.5,0.5,1.0);
		
		glTexCoord2f(0.0,1.0);
		glVertex3d(-0.5,0.5,1.0);
	glEnd();
	
	
	glPopMatrix();
	
	glFlush();
}

static void stack(int n)
/*creates a smaller cube on top of larger one*/
{
	
	cube();
	if(n==0)return;
	
	glPushMatrix();
	glTranslated(0.0,0.0,1.0);
	glScaled(0.5,0.5,0.5);
	stack(n-1);
	glPopMatrix();
}
	


static void display(void)
{
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	stack(2);
	glutSwapBuffers();

}

	
static void rotate(void)
/*rotates around z-axis*/
{
	static GLdouble a = 0.0;
	
	/*make sure we're dealing with modelview matrix*/
	glMatrixMode(GL_MODELVIEW);
	glPushMatrix();
	glRotated(a,0.0,0.0,1.0);
	cube();
	display();
	glPopMatrix();
	a += 1.0;
}

 
static void reshape(GLsizei width, GLsizei height)
{ 	
	/*define the viewport - width and height of display window*/
	glViewport (0, 0, width, height);

	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	/*define view frustrum*/
	gluPerspective(50.0,(GLdouble)width/(GLdouble)height,0.01,10.0);
	/*35deg field of view vertically, with aspect ratio, and 
        front and back clipping planes of -1.0 and 10.0*/
}
	
static void initialise(void) 
{
	/*material properties*/
	GLfloat mat_diffuse[] = {1.0,1.0,0.0,0.0};

	/*lighting*/
	GLfloat light_diffuse[] = {1.0,1.0,1.0,1.0};

	/*light position*/
	GLfloat position[] = {1.0,1.0,4.0,1.0};

	/*flat shading*/
    	glShadeModel (GL_FLAT);

	/*create normals normalised and automatically*/
	glEnable(GL_NORMALIZE);
	glEnable(GL_AUTO_NORMAL);

    	/*set the background (clear) Color to white*/
    	glClearColor(1.0,1.0,1.0,0.0);

	
	/*for 2D the modelview matrix is the identity*/
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
	
	gluLookAt(3.0,3.0,4.0,		/*eye*/
		  0.0,0.0,0.0,		/*looking here*/
		  0.0, 0.0, 1.0);	/*up vector*/
		  
	/*enable lighting*/
	glEnable(GL_LIGHTING);
	glEnable(GL_LIGHT0);
	
	/*set the light position coordinates*/
	glPushMatrix();
	glLoadIdentity();
	glLightfv(GL_LIGHT0,GL_POSITION,position);
	glPopMatrix();
	
	/*set the material*/
	glMaterialfv(GL_FRONT,GL_DIFFUSE,mat_diffuse);
	
	glLightfv(GL_LIGHT0,GL_DIFFUSE,light_diffuse);
    
    	/*enable the depth buffer*/
    	glEnable(GL_DEPTH_TEST);
    
    	/*set the depth buffer for clearing*/
    	glClearDepth(1.0);
    	
    	/*initialise the texture map*/
    	initialiseTextures();
    	
}

     
int main(int argc, char** argv)
{	
	int window;
	
	glutInit(&argc,argv);

	glutInitWindowSize(500,500);     
	glutInitDisplayMode(GLUT_RGBA|GLUT_DOUBLE|GLUT_DEPTH);


	window = glutCreateWindow("Textured Stack ");
	glutSetWindow(window);

    	initialise();

	/*register callbacks*/
	glutDisplayFunc(display); /*display function*/
	glutReshapeFunc(reshape);
	glutIdleFunc(rotate);

	glutMainLoop();
}