讓openGL告訴你,什么是物體的移動與旋轉


 

需求:繪制一個簡單的地月太陽的旋轉模型:地球繞太陽(繞y軸)旋轉,月球繞地球(繞x軸)旋轉。

實現的步驟:
    //openGL 坐標系:z朝向屏幕外, y朝上,x朝右
push
    向里移動300

    畫了一顆太陽

    繞y軸旋轉坐標系,旋轉角度為fEarthRot //(此時太陽的坐標系已經在繞太陽中心點(繞x軸)旋轉呢,不管后面有沒有下一步。理解這點很重要。)

    向上移動105 

    畫一個顆地球 //(這時地球自然而然在繞y軸旋轉,半徑為上面移動的105。)

    繞x軸旋轉坐標系,旋轉角度為fMoonRot //(此時地球的坐標系在繞地球中心點(繞x軸)旋轉。)

    向上移動30

    畫一顆月亮 //(這時地球自然而然在繞x軸旋轉,半徑為上面移動的30。)
pop //(物體坐標系又回到世界坐標系原點)

    //注意它兩是靜態變量
    fEarthRot++
    fMoonRot++

    循環上面這動作,實現了動畫。

效果:

實現:

#include<gl/glut.h>
#include <math.h>

// Lighting values
GLfloat  whiteLight[] = { 0.2f, 0.2f, 0.2f, 1.0f };
GLfloat  sourceLight[] = { 0.8f, 0.8f, 0.8f, 1.0f };
GLfloat     lightPos[] = { 0.0f, 0.0f, 0.0f, 1.0f };

void createCoordinate();

//執行順序: main --> SetupRC --> TimerFunc --> ChangeSize -->RenderScene
// Called to draw scene
void RenderScene(void)
{
    //openGL 坐標系:z朝向屏幕外, y朝上,x朝右
    // Earth and Moon angle of revolution
    static float fMoonRot = 0.0f;
    static float fEarthRot = 0.0f;

    // 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    
    //向里移動300
    glTranslatef(0.0f, 0.0f, -300.0f);    
    createCoordinate();

    // Set material color, Red
    // Sun 畫了一顆太陽
    glDisable(GL_LIGHTING);
    glColor3ub(255, 255, 0);
    glutSolidSphere(15.0f, 30, 17);
    glEnable(GL_LIGHTING);

    // Move the light after we draw the sun!
    glLightfv(GL_LIGHT0,GL_POSITION,lightPos);

    // 繞y軸旋轉坐標系
    glRotatef(fEarthRot, 0.0f, 1.0f, 0.0f);

    //向上移動105 
    glTranslatef(105.0f,0.0f,0.0f);

    //畫一個顆地球
    glColor3ub(0,0,255);
    glutSolidSphere(15.0f, 30, 17);

    //繪制一個坐標系,
    createCoordinate();

    // Rotate from Earth based coordinates and draw Moon
    glColor3ub(200,200,200);
    //繞x軸旋轉
    glRotatef(fMoonRot,1.0f, 0.0f, 0.0f);
    //向上移動30
    glTranslatef(0.0f, 30.0f, 0.0f);
    
    //畫一顆月亮
    glutSolidSphere(6.0f, 30, 17);

    createCoordinate();

    // Restore the matrix state
    glPopMatrix();    // Modelview matrix

    //月亮在轉
    fMoonRot+= 5.0f;
    if(fMoonRot > 360.0f)
        fMoonRot = 0.0f;
    // Step earth orbit 5 degrees

    //地球在轉
    fEarthRot += 5.0f;
    if(fEarthRot > 360.0f)
        fEarthRot = 0.0f;

    // Show the image
    glutSwapBuffers();
}

void createCoordinate(){
    //繪制一個坐標系,

    GLint factor = 2;
    GLushort pattern = 0x5555;
    //啟用點畫    
    glEnable(GL_LINE_STIPPLE);
    //點畫模式
    glLineStipple(factor,pattern);

    glLineWidth(1.0f);    

    glBegin(GL_LINES);
    //x軸
    glColor3ub((GLubyte)255,(GLubyte)0,(GLubyte)0);

    glVertex3f(-100.0f,0.0f,0.0f);
    glVertex3f(100.0f,0.0f,0.0f);

    glColor3ub((GLubyte)0,(GLubyte)255,(GLubyte)0);

    //y軸
    glVertex3f(0.0f,-100.0f,0.0f);
    glVertex3f(0.0f,100.0f,0.0f);

    //z軸
    glColor3ub((GLubyte)0,(GLubyte)0,(GLubyte)255);

    glVertex3f(0.0f,0.0f,-100.0f);
    glVertex3f(0.0f,0.0f,100.0f);
    glEnd();

    //關閉點畫    
    glDisable(GL_LINE_STIPPLE);
}

// This function does any needed initialization on the rendering
// context. 
void SetupRC()
{
    // 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 inside of jet

    // Enable lighting
    glEnable(GL_LIGHTING);

    // Setup and enable light 0
    glLightModelfv(GL_LIGHT_MODEL_AMBIENT,whiteLight);
    glLightfv(GL_LIGHT0,GL_DIFFUSE,sourceLight);
    glLightfv(GL_LIGHT0,GL_POSITION,lightPos);
    glEnable(GL_LIGHT0);

    // Enable color tracking
    glEnable(GL_COLOR_MATERIAL);

    glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);

    glClearColor(0.0f, 0.0f, 0.0f, 1.0f );
}

void TimerFunc(int value)
{
    glutPostRedisplay();
    glutTimerFunc(100, TimerFunc, 1);
}

void ChangeSize(int w, int h)
{
    GLfloat fAspect;

    if(h == 0)h = 1;

    glViewport(0, 0, w, h);

    fAspect = (GLfloat)w/(GLfloat)h;

    //使用並初始化投影矩陣
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();

    gluPerspective(45.0f, fAspect, 1.0, 425.0);

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
}


int main(int argc, char* argv[])
{
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
    glutInitWindowSize(800, 600);
    glutCreateWindow("Earth/Moon/Sun System");
    glutReshapeFunc(ChangeSize);
    glutDisplayFunc(RenderScene);
    glutTimerFunc(250, TimerFunc, 1);
    SetupRC();
    glutMainLoop();
    return 0;
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM