|
刚开始学OPENGL,看到12章交互式图形。运行光盘所附带的例子Moons和Planets,发现只要鼠标一点击,窗口中就会显示写乱七八糟的东西,完全达不到想达到的效果。不知道是示例程序错误还是我的系统有问题。有谁遇到过这种情况请告诉我是怎么回事。Moons例子如下:
// Moons.cpp
// OpenGL SuperBible, 3rd Edition
// Richard S. Wright Jr.
// rwright@starstonesoftware.com
#include "../../Common/OpenGLSB.h" // System and OpenGL Stuff
#include <memory.h>
///////////////////////////////
// Define object names
#define EARTH 1
#define MARS 2
#define MOON1 3
#define MOON2 4
///////////////////////////////////////////////////////////
// Just draw a sphere of some given radius
void DrawSphere(float radius)
{
GLUquadricObj *pObj;
pObj = gluNewQuadric();
gluQuadricNormals(pObj, GLU_SMOOTH);
gluSphere(pObj, radius, 26, 13);
gluDeleteQuadric(pObj);
}
///////////////////////////////////////////////////////////
// Called to draw scene
void RenderScene(void)
{
// Clear the window with current clearing color
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Save the matrix state and do the rotations
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
// Translate the whole scene out and into view
glTranslatef(0.0f, 0.0f, -300.0f);
// Initialize the names stack
glInitNames();
glPushName(0);
// Draw the Earth
glPushMatrix();
glColor3f(0.0f, 0.0f, 1.0f);
glTranslatef(-100.0f,0.0f,0.0f);
glLoadName(EARTH);
DrawSphere(30.0f);
// Draw the Moon
glTranslatef(45.0f, 0.0f, 0.0f);
glColor3f(0.85f, 0.85f, 0.85f);
glPushName(MOON1);
DrawSphere(5.0f);
glPopName();
glPopMatrix();
// Draw Mars
glColor3f(1.0f, 0.0f, 0.0f);
glPushMatrix();
glTranslatef(100.0f, 0.0f, 0.0f);
glLoadName(MARS);
DrawSphere(20.0f);
// Draw Moon1
glTranslatef(-40.0f, 40.0f, 0.0f);
glColor3f(0.85f, 0.85f, 0.85f);
glPushName(MOON1);
DrawSphere(5.0f);
glPopName();
// Draw Moon2
glTranslatef(0.0f, -80.0f, 0.0f);
glPushName(MOON2);
DrawSphere(5.0f);
glPopName();
glPopMatrix();
// Restore the matrix state
glPopMatrix(); // Modelview matrix
glutSwapBuffers();
}
///////////////////////////////////////////////////////////
// Parse the selection buffer to see which
// planet/moon was selected
void ProcessPlanet(GLuint *pSelectBuff)
{
int id,count;
char cMessage[64];
strcpy(cMessage,"Error, no selection detected");
memset(cMessage,0,64);
// How many names on the name stack
count = pSelectBuff[0];
// Bottom of the name stack
id = pSelectBuff[3];
// Select on earth or mars, whichever was picked
switch(id)
{
case EARTH:
strcpy(cMessage,"You clicked Earth.");
// If there is another name on the name stack,
// then it must be the moon that was selected
// This is what was actually clicked on
if(count == 2)
strcat(cMessage," - Specifically the moon.");
break;
case MARS:
strcpy(cMessage,"You clicked Mars.");
// We know the name stack is only two deep. The precise
// moon that was selected will be here.
if(count == 2)
{
if(pSelectBuff[4] == MOON1)
strcat(cMessage," - Specifically Moon #1.");
else
strcat(cMessage," - Specifically Moon #2.");
}
break;
}
// Display the message about planet and moon selection
glutSetWindowTitle(cMessage);
}
///////////////////////////////////////////////////////////
// Process the selection, which is triggered by a right mouse
// click at (xPos, yPos).
#define BUFFER_LENGTH 64
void ProcessSelection(int xPos, int yPos)
{
GLfloat fAspect; // Screen aspect ratio
// Space for selection buffer
GLuint selectBuff[BUFFER_LENGTH];
// Hit counter and viewport storeage
GLint hits=0, viewport[4];
// Setup selection buffer
glSelectBuffer(BUFFER_LENGTH, selectBuff);
// Get the viewport
glGetIntegerv(GL_VIEWPORT, viewport);
// Switch to projection and save the matrix
glMatrixMode(GL_PROJECTION);
glPushMatrix();
// Change render mode
glRenderMode(GL_SELECT);
// Establish new clipping volume to be unit cube around
// mouse cursor point (xPos, yPos) and extending two pixels
// in the vertical and horzontal direction. Remember OpenGL specifies the
// y coordinate from the bottom, Windows from the top. So windows position
// (as measured from the top) subtract the height and you get it in terms
// OpenGL Likes.
glLoadIdentity();
gluPickMatrix(xPos, viewport[3] - yPos, 2,2, viewport);
// Apply perspective matrix
fAspect = (float)viewport[2] / (float)viewport[3];
gluPerspective(45.0f, fAspect, 1.0, 425.0);
// Draw the scene
RenderScene();
// Collect the hits
hits = glRenderMode(GL_RENDER);
// If a single hit occured, display the info.
if(hits == 1)
ProcessPlanet(selectBuff);
else
glutSetWindowTitle("You clicked empty space!");
// Restore the projection matrix
glMatrixMode(GL_PROJECTION);
glPopMatrix();
// Go back to modelview for normal rendering
glMatrixMode(GL_MODELVIEW);
}
///////////////////////////////////////////////////////////
// Process the mouse click
void MouseCallback(int button, int state, int x, int y)
{
if(button == GLUT_LEFT_BUTTON && state == GLUT_DOWN)
ProcessSelection(x, y);
}
///////////////////////////////////////////////////////////
// This function does any needed initialization on the
// rendering context.
void SetupRC()
{
// Lighting values
GLfloat dimLight[] = { 0.1f, 0.1f, 0.1f, 1.0f };
GLfloat sourceLight[] = { 0.65f, 0.65f, 0.65f, 1.0f };
GLfloat lightPos[] = { 0.0f, 0.0f, 0.0f, 1.0f };
// Light values and coordinates
glEnable(GL_DEPTH_TEST); // Hidden surface removal
glFrontFace(GL_CCW); // Counter clock-wise polygons face out
glEnable(GL_CULL_FACE); // Do not calculate insides
// Enable lighting
glEnable(GL_LIGHTING);
// Setup and enable light 0
glLightfv(GL_LIGHT0, GL_AMBIENT, dimLight);
glLightfv(GL_LIGHT0,GL_DIFFUSE,sourceLight);
glLightfv(GL_LIGHT0,GL_POSITION,lightPos);
glEnable(GL_LIGHT0);
// Enable color tracking
glEnable(GL_COLOR_MATERIAL);
// Set Material properties to follow glColor values
glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);
// Gray background
glClearColor(0.60f, 0.60f, 0.60f, 1.0f );
}
///////////////////////////////////////////////////////////
// Window changed size, reset viewport and projection
void ChangeSize(int w, int h)
{
GLfloat fAspect; // Screen aspect ratio
// Prevent a divide by zero
if(h == 0)
h = 1;
// Set Viewport to window dimensions
glViewport(0, 0, w, h);
// Calculate aspect ratio of the window
fAspect = (GLfloat)w/(GLfloat)h;
// Set the perspective coordinate system
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
// Field of view of 45 degrees, near and far planes 1.0 and 425
gluPerspective(45.0f, fAspect, 1.0, 425.0);
// Modelview matrix reset
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
///////////////////////////////////////////////////////////
// Entry point of the program
int main(int argc, char* argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(800,600);
glutCreateWindow(" ick a Planet or Moon");
glutReshapeFunc(ChangeSize);
glutMouseFunc(MouseCallback);
glutDisplayFunc(RenderScene);
SetupRC();
glutMainLoop();
return 0;
}
|
|