今天从网站找到一个简单的opengl程序,虽然自己研究opengl许久,但是这个程序还是让我感叹了一番,现把程序代码摘录如下:
<code begin>
#include <windows.h>
#include <stdio.h>
#include <GL/gl.h>
#include <GL/glut.h>
#define WIDTH 800
#define HEIGHT 600
#define MAXTEX 10
static int winId = -1;
static int winWidth = WIDTH;
static int winHeight = HEIGHT;
static int texturesNeedInit = TRUE;
static unsigned char *texture[MAXTEX];
static unsigned int texId[MAXTEX];
static unsigned int texWidth[MAXTEX];
static unsigned int texHeight[MAXTEX];
static unsigned int numTextures = 0;
static float *points = NULL;
static int numPoints = 0, maxPoints = 0;
static float degrees = 0;
static int useTexture = TRUE;
static int usePen = FALSE;
static int useSpin = FALSE;
static int useLines = FALSE;
/*****************************************************************************
Load in a texture in PPM format from disk.
*****************************************************************************/
unsigned char *
loadTexture(char *fileName, unsigned int *width, unsigned int *height)
{
char buf[256];
unsigned char *data, *linebuf;
FILE *fp;
if (!(fp = fopen(fileName,"rb"))) {
fprintf(stderr,"Could not open /"%s/"/n", fileName);
return (NULL);
}
fgets(buf, 256, fp); /* P6 */
fgets(buf, 256, fp); /* W H */
sscanf(buf," %i %i ", width, height);
fgets(buf, 256, fp); /* 255 */
data = new unsigned char[(*width)*(*height)*4];
linebuf = new unsigned char[(*width)*3];
for (int y=0; y<(*height); y++) {
fread(linebuf, 1, (*width)*3, fp);
for (int x=0; x<(*width); x++) {
unsigned char red = linebuf[x*3+0];
unsigned char grn = linebuf[x*3+1];
unsigned char blu = linebuf[x*3+2];
data[(((*height)-y-1)*(*width)+x)*4+0] = red;
data[(((*height)-y-1)*(*width)+x)*4+1] = grn;
data[(((*height)-y-1)*(*width)+x)*4+2] = blu;
data[(((*height)-y-1)*(*width)+x)*4+3] = 255;
}
}
return (data);
}
/*****************************************************************************
Load and initialize texture for OpenGL.
*****************************************************************************/
void
initializeTextures()
{
char buf[256];
int i;
glEnable(GL_TEXTURE_2D);
for (i=0; i<numTextures; i++) {
sprintf(buf, "texture%i.ppm", i);
texture[i] = loadTexture(buf, &texWidth[i], &texHeight[i]);
glGenTextures(1, &texId[i]);
glBindTexture(GL_TEXTURE_2D, texId[i]);
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);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, texWidth[i], texHeight[i],
0, GL_RGBA, GL_UNSIGNED_BYTE, texture[i]);
}
glDisable(GL_TEXTURE_2D);
}
/*****************************************************************************
*****************************************************************************/
void
refreshCB()
{
int i;
// set to current window
glutSetWindow(winId);
// clear window
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
// set a standard 60-degree FOV perspective projection matrix
glMatrixMode(GL_PROJECTION);
glViewport(0, 0, winWidth, winHeight);
glLoadIdentity();
gluPerspective(60.0, (float)winWidth/(float)winHeight, 0.1, 1000.0);
// clear the modelview matrix stack
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
// do scales, translates, and rotates here
glTranslatef(0,0,-3);
glRotatef(degrees,0,1,0);
if (useSpin) degrees += 0.25;
// initialize textures (once)
if (texturesNeedInit) {
initializeTextures();
texturesNeedInit = FALSE;
}
glColor3f(1.0,0.0,0.0);
glutSolidCube(1.0);
if (useTexture) {
glEnable(GL_TEXTURE_2D);
for (i=0; i<numTextures; i++) {
glBindTexture(GL_TEXTURE_2D, texId[i]);
glBegin(GL_POLYGON);
glTexCoord2f(0, 0);
glVertex3f(-1,-1,0);
glTexCoord2f(1, 0);
glVertex3f( 1,-1,0);
glTexCoord2f(1, 1);
glVertex3f( 1, 1,0);
glTexCoord2f(0, 1);
glVertex3f(-1, 1,0);
glEnd();
}
glDisable(GL_TEXTURE_2D);
}
if (usePen) {
// set a standard 60-degree FOV perspective projection matrix
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, winWidth, 0, winHeight, -1, 1);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glColor3f(1,1,0);
if (useLines && numPoints >= 2) {
glLineWidth(2.0);
glBegin(GL_LINES);
for (i=0; i<((numPoints/2)*2)-1; i++) {
glVertex2f(points[i*2+0], points[i*2+1]);
glVertex2f(points[i*2+2], points[i*2+3]);
}
glEnd();
} else if (useLines == FALSE) {
glPointSize(2.0);
glBegin(GL_POINTS);
for (i=0; i<numPoints; i++) {
glVertex2f(points[i*2+0], points[i*2+1]);
}
glEnd();
}
glColor3f(1,1,1);
}
glutSwapBuffers();
}
/*****************************************************************************
*****************************************************************************/
static void
keyCB(unsigned char key, int /*x*/, int /*y*/)
{
switch (key) {
case 'l' : useLines ^= 1; break;
case 's' : useSpin ^= 1; break;
case 't' : useTexture ^= 1; break;
case 'p' : usePen ^= 1; break;
case 'r' : numPoints = 0; degrees = 0; break;
case 'q' : exit(0); break;
}
glutPostRedisplay();
}
/*****************************************************************************
*****************************************************************************/
static void
motionCB(int x, int y)
{
/* invert y so that ymax is up */
y = (winHeight - y - 1);
if (maxPoints == 0 || numPoints >= maxPoints) {
if (maxPoints == 0) {
maxPoints = 2;
points = new float[maxPoints*2];
} else {
maxPoints *= 2;
float *newPoints = new float[maxPoints*4];
for (int i=0; i<numPoints*2; i++)
newPoints[i] = points[i];
delete points;
points = newPoints;
}
}
points[numPoints*2+0] = x;
points[numPoints*2+1] = y;
numPoints++;
if (usePen)
glutPostRedisplay();
}
/*****************************************************************************
*****************************************************************************/
void
idleCB(void)
{
if (useSpin)
glutPostRedisplay();
}
/*****************************************************************************
*****************************************************************************/
main(int argc, char *argv[])
{
numTextures = 1;
glutInit(&argc, argv);
glCullFace(GL_BACK);
glDisable(GL_NORMALIZE);
glDisable(GL_BLEND);
glShadeModel(GL_SMOOTH);
glReadBuffer(GL_BACK);
glEnable(GL_SCISSOR_TEST);
glClearColor(0,0,0,1);
glutInitWindowPosition(100, 100);
glutInitWindowSize(winWidth, winHeight);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH);
winId = glutCreateWindow("Demo");
glutDisplayFunc(refreshCB);
glutKeyboardFunc(keyCB);
glutMotionFunc(motionCB);
glutIdleFunc(idleCB);
glutMainLoop();
return (TRUE);
}
<code end>