游戏开发论坛

 找回密码
 立即注册
搜索
查看: 2092|回复: 0

OPENGL超级宝典12章的例子

[复制链接]

6

主题

26

帖子

26

积分

注册会员

Rank: 2

积分
26
发表于 2007-9-17 17:02:00 | 显示全部楼层 |阅读模式
刚开始学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(&quotick a Planet or Moon");
        glutReshapeFunc(ChangeSize);
        glutMouseFunc(MouseCallback);
        glutDisplayFunc(RenderScene);
        SetupRC();
        glutMainLoop();

        return 0;
        }
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

作品发布|文章投稿|广告合作|关于本站|游戏开发论坛 ( 闽ICP备17032699号-3 )

GMT+8, 2025-6-21 21:34

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表