码迷,mamicode.com
首页 > 其他好文 > 详细

NeHe OpenGL lesson 7

时间:2014-09-16 09:17:10      阅读:271      评论:0      收藏:0      [点我收藏+]

标签:mac

HeHe OpenGL 第七节,纹理部分,光照初步。由于Mac 上面没有Page键,所以用G 、 H键替换


// NeHe OpenGL lession 7
// Texture Filters, Lighting & keyboard Control
//

/**
 *	Linux
 *  #include <GL/glut.h>
 *	#include <GL/gl.h>
 *  #include <GL/glu.h>
 */

#include <GLUT/GLUT.h>
#include <OpenGL/OpenGL.h>
#include <stdio.h>	
#include <unistd.h>	  // Header file for Sleeping
#include <stdlib.h> 	// Header for malloc/free

/* ascii code for various special keys */
#define ESCAPE 			27
#define PAGE_UP			73
#define PAGE_DOWN		81
#define UP_ARROW		72
#define DOWN_ARROW	80
#define LEFT_ARROW  75
#define RIGHT_ARROW 77
#define KEY_G  	    103
#define KEY_H       104

/* The number of our GLUT window */
int window;

/* lighting on/off (1 == on, 0 == off) */
int light;

/* L pressed (1 == yes, 0 == no) */
int lp;

/* F pressed (1 == yes, 0 == no) */
int fp;

GLfloat xrot; 	// x rotation
GLfloat yrot; 	// y rotation
GLfloat xspeed;	// x rotation speed
GLfloat yspeed; // y rotation speed

GLfloat z = -5.0f; // depth into the screen.

/* white ambient light at half intensity (rgba) */
GLfloat lightAmbient[] = { 0.5f, 0.5f, 0.5f, 1.0f };

/* super bright, full intensity fiffuse light. */
GLfloat lightDiffuse[] = { 1.0f, 1.0f, 1.0f, 1.0f };

/* position of light (x, y, z, (position of light) */
GLfloat lightPosition[] = { 0.0f, 0.0f, 2.0f, 1.0f };

GLuint filter; 			/* which filter to use (nearest/linear/mipmapped) */
GLuint texture[3]; 	/* storage for 3 texture. */

/* Image type - contains height, white, and data */
struct Image {
	unsigned long sizeX;
	unsigned long sizeY;
	char *data;
};
typedef struct Image Image;

// quick and dirty bitmap loader.. for 24 bit bitmaps with 1 plane only.
// if mesa ever gets glaux, let me know
// BMP
int imageLoad(char *filename, Image *image) {
	FILE *file;
	unsigned long size; 				// size of the image in bytes.
	unsigned long i;						// standard counter.
	unsigned short int planes;	// number of planes in image (must be 1)
  unsigned short int bpp; 		// number of bits per pixel (must be 24)
	char temp; 									// used to convert bgr to rgb color

	// make sure the file is there.
	if ((file = fopen(filename, "rb")) == NULL) {
		printf("File not found: %s\n", filename);
		return 1;
	}

	// seek through the bmp header, up to the width/height
	fseek(file, 18, SEEK_CUR);

	// read the width
	if ((i = fread(&image->sizeX, 4, 1, file)) != 1) {
		printf("Error reading with from %s.\n", filename);
//		return 1;
	}

	printf("Width of %s: %lu\n", filename, image->sizeX);

	// read the height
	if ((i = fread(&image->sizeY, 4, 1, file)) != 1) {
		printf("Error reading height from %s.\n", filename);
//  return 1;
	}

	if (image->sizeX > 256)
		image->sizeX = 256;
	if (image->sizeY > 256)
		image->sizeY = 256;

	// calculate the size (assuming 24 bits or 3 bytes per pixel).
	size = image->sizeX * image->sizeY * 3;

	// read the planes
	if ((fread(&planes, 2, 1, file)) != 1) {
		printf("Error rading planes from %s.\n", filename);
		return -2;
	}

	if (planes != 1) {
		printf("Planes from %s is not 1: %u\n", filename, planes);
		return -3;
	}

	// read the bpp
	if ((i = fread(&bpp, 2, 1, file)) != 1) {
		printf("Error reading bpp from %s.\n", filename);
		return -3;
	}

	if (bpp != 24) {
		printf("bpp from %s is not 24: %u\n", filename, bpp);
		return 0;
	}

	// seek past the rest of the bitmap header
	fseek(file, 24, SEEK_CUR);
	
	// read the data.
	image->data = (char *) malloc(size);
	if (image->data == NULL) {
		printf("Error allocating memory for color-corrected iamge data");
		return 0;	
	}

	if ((i = fread(image->data, size, 1, file)) != 1) {
		printf("Error reading image data from %s.\n", filename);
		return 0;
	}

	for (i = 0; i < size; i += 3) {
		temp = image->data[i];
		image->data[i] = image->data[i+2];
		image->data[i+2] = temp;
	}
	
	// we're done.
	return 1;
}


// Load bitmaps and convert to texture
GLvoid loadGLTextures(GLvoid) {
	// Load texture
	Image *image1;

	// allocate space for texture
	image1 = (Image *) malloc(sizeof(Image));
	if (image1 == NULL) {
		printf("Error allocating space for image");
		exit(0);
	}

  /* /Users/jabez/Developer/mac/09_12/Data/lesson7/crate.bmp */
	if (!imageLoad("/Users/jabez/Developer/mac/09_12/Data/lesson7/crate.bmp", image1)) {
		exit(1);
	}

	// Create textures
	glGenTextures(3, &texture[0]);
  
	// texture 1 (poor quality scaling)
	glBindTexture(GL_TEXTURE_2D, texture[0]); // 2d texture(x and y size)
	
  // check scaling when image bigger than texture
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 
  // check scaling when image smalled than texture
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 
  
  // 2d texture, level of detail 0 (normal), 3 components (red, green, blue)
	// x size from image, y size from image
  // border 0 (normal), rgb color data, unsigned byte data, 
  // and finally the data itself.
	glTexImage2D(GL_TEXTURE_2D, 0, 3, image1->sizeX, image1->sizeY,
    0, GL_RGB, GL_UNSIGNED_BYTE, image1->data);
	
	// texture 2 (linear scaling)
	glBindTexture(GL_TEXTURE_2D, texture[1]); // 2d texture (x and y size)
  // scale linearly when image bigger than texture
  glTexParameteri(GL_TEXTURE_2D, 	GL_TEXTURE_MAG_FILTER, GL_LINEAR);	
  // scale linearly + mipmap when image smalled than texture
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
	glTexImage2D(GL_TEXTURE_2D, 0, 3, image1->sizeX, image1->sizeY, 0,
    GL_RGB, GL_UNSIGNED_BYTE, image1->data);
}

/* A general OpenGL initialization function. Sets all of the initial parameters. */
// We call this right after our OpenGL window is created.
GLvoid initGL(GLsizei width, GLsizei height) {
  loadGLTextures(); // load the textures
	glEnable(GL_TEXTURE_2D); // Enable texture mapping.

	glClearColor(0.0f, 0.0f, 0.0f, 0.0f);  // This will Clear background color to black.
  glClearDepth(1.0);
  glDepthFunc(GL_LESS); 								// The type of test to do.
  glEnable(GL_DEPTH_TEST); 							// Enable Depth testing.
  glShadeModel(GL_SMOOTH); 							// Enables smooth color shading.
  
  glMatrixMode(GL_PROJECTION); 				
  glLoadIdentity(); 										// Reset the projection matrix.
	
  // Calcualte the aspect ratio of the window.
	gluPerspective(45.0f, (GLfloat) width / (GLfloat) height, 0.1f, 100.0f); 
    
  glMatrixMode(GL_MODELVIEW);

  // set up light number 1.
  glLightfv(GL_LIGHT1, GL_AMBIENT, lightAmbient);    // add lighting. (ambient)
  glLightfv(GL_LIGHT1, GL_DIFFUSE, lightDiffuse);    // add lighting. (diffuse).
  glLightfv(GL_LIGHT1, GL_POSITION, lightPosition);  // set light position.
  glEnable(GL_LIGHT1);
}


/* The function called when our window is resized (which shouldn't happen, because
   we're fullscreen) */
GLvoid resizeGLScene(GLsizei width, GLsizei height) {
  if (height == 0)
    height = 1;

  glViewport(0, 0, width, height);

  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();

  gluPerspective(45.0f, (GLfloat) width / (GLfloat) height, 0.1f, 100.0f);
  glMatrixMode(GL_MODELVIEW);
}

/* The main drawing function. */
GLvoid drawGLScene(GLvoid) {
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  glLoadIdentity(); // Reset the view
  
  glTranslatef(0.0f, 0.0f, z); 	// move z units out from the screen.

  glRotatef(xrot, 1.0f, 0.0f, 0.0f); 	// rotate on the x axis
  glRotatef(yrot, 0.0f, 1.0f, 0.0f);  // rotate on the y axis
  
  glBindTexture(GL_TEXTURE_2D, texture[filter]); // choose the texture to use.

	glBegin(GL_QUADS); 		// Begin drawing a cube.
    
    // Front face (note that texture's corners have to match the quad's corners)
    glNormal3f(0.0f, 0.0f, 1.0f);  // front face points out of the scren on z.
    glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f,  1.0f); // bottom left.
    glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f,  1.0f); // bottom right.
    glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f,  1.0f,  1.0f); // top right.
    glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f,  1.0f,  1.0f); // top left.

    // Back face
    glNormal3f(0.0f, 0.0f, -1.0f); // back face points into the screen on z.
    glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f); // bottom right.
    glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f,  1.0f, -1.0f); // top right.
    glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f,  1.0f, -1.0f); // top left.
    glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f); // bottom left.

	  // Top face
    glNormal3f(0.0f, 1.0f, 0.0f); // top face points up on y.
    glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f); // top left
    glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, 1.0f,  1.0f); // bottom left.
    glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, 1.0f,  1.0f); // bottom right.
    glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f); // top right.

    // Bottom face
    glNormal3f(0.0f, -1.0f, 0.0f); // bottom face points down on y.
    glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, -1.0f, -1.0f); // top right
    glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, -1.0f, -1.0f); // top left.
    glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f,  1.0f); // bottom left.
    glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f,  1.0f); // bottom right.

    // right face
    glNormal3f(1.0f, 0.0f, 0.0f); 
    glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f); // bottom right
    glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f,  1.0f, -1.0f); // top right
    glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f,  1.0f,  1.0f); // top left.
    glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f,  1.0f); // bottom left.

    // Left face
    glNormal3f(-1.0f, 0.0f, 0.0f);	// left face points left on x.
    glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f); // bottom left
    glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f,  1.0f); // bottom right
    glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f,  1.0f,  1.0f); // top right
    glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f,  1.0f, -1.0f); // top left
  
  glEnd(); // done with the polygon.

  xrot += xspeed;  // x axis rotation.
  yrot += yspeed;  // y axis rotation.

  // since this is double buffered, swap the buffers to display what just got drawn.
  glutSwapBuffers(); 
}

/* The function called whenever a normal key is pressed. */
void keyPressed(unsigned char key, int x, int y)
{
  printf("normal key: %c, %d\n", key, key);
  /* avoid thrashing this procedure */
  usleep(100);

  switch (key) {
    case ESCAPE:  // kill everything.
      glutDestroyWindow(window);  // shut down our window.
      exit(1); // exit the program...normal termination.
      break;
    case 76:
    case 108:  // switch the lighting.
      printf("L/l pressed; light is: %d\n", light);
      light = light ? 0 : 1; // swithc the current value of light, between 0 and 1.
      printf("Light is now: %d\n", light);
      if (!light) {
        glDisable(GL_LIGHTING);
			} else {
        glEnable(GL_LIGHTING);
      }
      break;

    case 70:
    case 102: // switch the filter.
      printf("F/f pressed; filter is: %d\n", filter);
      filter += 1;
      if (filter > 2) {
        filter = 0;
      }
      printf("Filter is no: %d\n", filter);
      break;
    
    case KEY_G: // move the cube into the distance.
      z -= 0.02f;
      break;
    
    case KEY_H: // move the cube closer.
      z += 0.02f;
      break;


    default:
      break;
  }  
}

/* The function called whenever a normal key is pressed. */
void specialKeyPressed(int key, int x, int y) {
 
 	printf("key: %c, %d\n", key, key);
  /* avoid thrashing this procedure */
  usleep(100);
  
  switch (key) {
    case GLUT_KEY_PAGE_UP: // move the cube into the distance.
      z -= 0.02f;
      break;
    
    case GLUT_KEY_PAGE_DOWN: // move the cube closer.
      z += 0.02f;
      break;

    case GLUT_KEY_UP: // decrease x rotation speed;
      xspeed -= 0.01;
      break;
   
    case GLUT_KEY_DOWN: // increase x rotation speed.
      xspeed += 0.01f; 
      break;
 
    case GLUT_KEY_LEFT: // decrease y rotation speed.
      yspeed -= 0.01f; 
      break;

    case GLUT_KEY_RIGHT:  // increase y rotation speed.
      break;

    default:
			printf("key: %c, %d\n", key, key);
      break;
  }
}

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

  glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_ALPHA | GLUT_DEPTH);

  glutInitWindowSize(640, 480); // 640 x 480 pixel window.

  /* the window starts at the upper left corner of the screen */
  glutInitWindowPosition(0, 0); 

  /* Open a window */
  window = glutCreateWindow("Jeff Molofee's GL Code Tutorial ... NeHe '99");

  /* Register the function to do all our OpenGL drawing. */
  glutDisplayFunc(&drawGLScene);

  /* Go Fullscreen. This is as soon as possible. */
//  glutFullScreen();
  
  /* Even if there are no events, redraw our gl scene. */
  glutIdleFunc(&drawGLScene);

  /* Register the function called when our window is resized. */
  glutReshapeFunc(&resizeGLScene); 

  /* register the function called when the keyboard is pressed. */
  glutKeyboardFunc(&keyPressed);

  /* Register the function called when special keys (arrows, page, down, etc)
    are pressed. */
  glutSpecialFunc(&specialKeyPressed);

  /* Initialize our window. */
  initGL(640, 480);
  
  /* starting event processing engine */
  glutMainLoop();

  return 1;    
}




NeHe OpenGL lesson 7

标签:mac

原文地址:http://blog.csdn.net/jabezlee/article/details/39312575

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!