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