您的位置:首页 > 运维架构

NeHe OpenGL lesson 7

2014-09-16 08:52 337 查看
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;
}


源代码以及相关下载地址: http://download.csdn.net/detail/liyan223/7996141
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  Mac