首页 > 代码库 > Lane-学习OpenGL(2)-七个简单例子

Lane-学习OpenGL(2)-七个简单例子

运行环境:
(1)Windows 7
(2)CodeBlocks
(3)GLUT
(4)Author:Lane
2014-12-03

1.行星系统,按d,D,y,Y旋转.

#include <windows.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glut.h>

#include <cstdlib>
#include <cstdio>
#include <cmath>

static int year = 0, day = 0;

void init(void){
    glClearColor(0.0,0.0,0.0,0.0);
    glShadeModel(GL_FLAT);//单调着色
}

void display(void){
    glClear(GL_COLOR_BUFFER_BIT);
    glColor3f(1.0,1.0,1.0);
    glPushMatrix();
        glutWireSphere(1.0,20,16);//绘制一个球体
        glRotatef((GLfloat)year,0.0,1.0,0.0);//旋转
        glTranslatef(2.0,0.0,0.0);//位移
        glRotatef((GLfloat)day,0.0,1.0,0.0);
        glutWireSphere(0.2,10,8);
    glPopMatrix();
    glutSwapBuffers();//交换缓冲区,因为设置了双缓冲区,一个缓冲区显示,一个缓冲区绘制
}

void reshape(int w,int h){
    glViewport(0,0,(GLsizei)w,(GLsizei)h);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(60.0,(GLfloat)w/(GLfloat)h,1.0,20.0);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    gluLookAt(0.0,0.0,5.0,0.0,0.0,0.0,0.0,1.0,0.0);
}

void keyboard(unsigned char key,int x,int y){
    switch(key){
    case 'd':
        day = (day + 10) % 360;
        glutPostRedisplay();//窗口重新绘制
        break;
    case 'D':
        day = (day - 10) % 360;
        glutPostRedisplay();
        break;
    case 'y':
        year = (year + 5) % 360;
        glutPostRedisplay();
        break;
    case 'Y':
        year = (year - 5) % 360;
        glutPostRedisplay();
        break;
    default:
        break;
    }
}

int main(int argc,char** argv){
    glutInit(&argc,argv);
    glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGB);//双缓冲
    glutInitWindowSize(500,500);
    glutInitWindowPosition(100,100);
    glutCreateWindow(argv[0]);
    init();
    glutDisplayFunc(display);
    glutReshapeFunc(reshape);
    glutKeyboardFunc(keyboard);//设置键盘事件
    glutMainLoop();
    return 0;
}

2.机器人手臂,按e,E,s,S变换位置

#include <windows.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glut.h>

#include <cstdlib>
#include <cstdio>
#include <cmath>

static int shoulder = 0, elbow = 0;

void init(void){
    glClearColor(0.0,0.0,0.0,0.0);
    glShadeModel(GL_FLAT);//单调着色
}

void display(void){
    glClear(GL_COLOR_BUFFER_BIT);
    glPushMatrix();
        glTranslatef(-1.0,0.0,0.0);
        glRotatef((GLfloat)shoulder,0.0,0.0,1.0);
        glTranslatef(1.0,0.0,0.0);
        glPushMatrix();
            glScalef(2.0,0.4,1.0);
            glutWireCube(1.0);
        glPopMatrix();
        glTranslatef(1.0,0.0,0.0);
        glRotatef((GLfloat)elbow,0.0,0.0,1.0);
        glTranslatef(1.0,0.0,0.0);
        glPushMatrix();
            glScalef(2.0,0.4,1.0);
            glutWireCube(1.0);
        glPopMatrix();
    glPopMatrix();
    glutSwapBuffers();
}

void reshape(int w,int h){
    glViewport(0,0,(GLsizei)w,(GLsizei)h);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(65.0,(GLfloat)w/(GLfloat)h,1.0,20.0);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    glTranslatef(0.0,0.0,-5.0);
}

void keyboard(unsigned char key,int x,int y){
    switch (key){
    case 's':
        shoulder = (shoulder + 5) % 360;
        glutPostRedisplay();
        break;
    case 'S':
        shoulder = (shoulder - 5) % 360;
        glutPostRedisplay();
        break;
    case 'e':
        elbow = (elbow + 5) % 360;
        glutPostRedisplay();
        break;
    case 'E':
        elbow = (elbow - 5) % 360;
        glutPostRedisplay();
        break;
    default:
        break;
    }
}

int main(int argc,char** argv){
    glutInit(&argc,argv);
    glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGB);//双缓冲
    glutInitWindowSize(500,500);
    glutInitWindowPosition(100,100);
    glutCreateWindow(argv[0]);
    init();
    glutDisplayFunc(display);
    glutReshapeFunc(reshape);
    glutKeyboardFunc(keyboard);
    glutMainLoop();
    return 0;
}

2014-12-04

3.读取鼠标位置,并确定鼠标光标位置经过变换之后在三维空间的近侧裁剪平面和远侧

裁剪平面上的点,经过计算得的物体坐标被打印到标准输出.

#include <windows.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glut.h>

#include <cstdlib>
#include <cstdio>
#include <cmath>

void display(void){
    glClear(GL_COLOR_BUFFER_BIT);
    glFlush();
}

void reshape(int w,int h){
    glViewport(0,0,(GLsizei)w,(GLsizei)h);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(45.0,(GLfloat)w/(GLfloat)h,1.0,100.0);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
}

void mouse(int button,int state,int x,int y){
    GLint viewport[4];
    GLdouble mvmatrix[16],projmatrix[16];
    GLint realy;
    GLdouble wx,wy,wz;
    switch (button){
    case GLUT_LEFT_BUTTON:
        if(state == GLUT_DOWN){
            glGetIntegerv(GL_VIEWPORT,viewport);
            glGetDoublev(GL_MODELVIEW_MATRIX,mvmatrix);
            glGetDoublev(GL_PROJECTION_MATRIX,projmatrix);
            realy = viewport[3]-(GLint)y-1;
            printf("Coordinates at cursor are (%4d,%4d)\n ",x,realy);
            gluUnProject((GLdouble)x,(GLdouble)realy,1.0,mvmatrix,projmatrix,viewport,&wx,&wy,&wz);
            printf("World coords at z=1.0 are (%f,%f,%f)\n ",wx,wy,wz);
        }
        break;
    case GLUT_RIGHT_BUTTON:
        if(state == GLUT_DOWN)
            exit(0);
        break;
    default:
        break;
    }
}

int main(int argc,char** argv){
    glutInit(&argc,argv);
    glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);
    glutInitWindowSize(500,500);
    glutInitWindowPosition(100,100);
    glutCreateWindow(argv[0]);
    glutDisplayFunc(display);
    glutReshapeFunc(reshape);
    glutMouseFunc(mouse);
    glutMainLoop();
    return 0;
}

4.平滑着色三角形

#include <windows.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glut.h>

#include <cstdlib>
#include <cstdio>
#include <cmath>

void init(void){
    glClearColor(0.0,0.0,0.0,0.0);
    glShadeModel(GL_SMOOTH);//平滑着色
}

void triangle(void){
    glBegin(GL_TRIANGLES);
    glColor3f(1.0,0.0,0.0);//红色
    glVertex2f(5.0,5.0);
    glColor3f(0.0,1.0,0.0);//绿色
    glVertex2f(25.0,5.0);
    glColor3f(0.0,0.0,1.0);//蓝色
    glVertex2f(5.0,25.0);
    glEnd();
}

void display(void){
    glClear(GL_COLOR_BUFFER_BIT);
    triangle();
    glFlush();
}

void reshape(int w, int h){
    glViewport(0,0,(GLsizei)w,(GLsizei) h);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    if(w<=h)
        gluOrtho2D(0.0,30.0,0.0,30.0*(GLfloat)h/(GLfloat)w);
    else
        gluOrtho2D(0.0,30.0*(GLfloat)w/(GLfloat)h,0.0,30.0);
    glMatrixMode(GL_MODELVIEW);
}

int main(int argc,char** argv){
    glutInit(&argc,argv);
    glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);
    glutInitWindowSize(500,500);
    glutInitWindowPosition(100,100);
    glutCreateWindow(argv[0]);
    init();
    glutDisplayFunc(display);
    glutReshapeFunc(reshape);
    glutMainLoop();
    return 0;
}

5.一个光照球体

#include <windows.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glut.h>

#include <cstdlib>
#include <cstdio>
#include <cmath>

void init(void){
    GLfloat mat_specular[] = {1.0,1.0,1.0,1.0};
    GLfloat mat_shininess[] = {50.0};
    GLfloat light_position[] = {1.0,1.0,1.0,0.0};
    GLfloat white_light[] = {1.0,1.0,1.0,1.0};
    GLfloat lmodel_ambient[] = {0.1,0.1,0.1,1.0};
    glClearColor(0.0,0.0,0.0,0.0);
    glShadeModel(GL_SMOOTH);//平滑着色
    glMaterialfv(GL_FRONT,GL_SPECULAR,mat_specular);
    glMaterialfv(GL_FRONT,GL_SHININESS,mat_shininess);
    glLightfv(GL_LIGHT0,GL_POSITION,light_position);
    glLightfv(GL_LIGHT0,GL_DIFFUSE,white_light);
    glLightfv(GL_LIGHT0,GL_SPECULAR,white_light);
    glLightModelfv(GL_LIGHT_MODEL_AMBIENT,lmodel_ambient);

    glEnable(GL_LIGHTING);//开启光照
    glEnable(GL_LIGHT0);//开启光源0
    glEnable(GL_DEPTH_TEST);
}

void display(void){
    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
    glutSolidSphere(1.0,20,16);//渲染球体
    glFlush();
}

void reshape(int w,int h){
    glViewport(0,0,(GLsizei) w, (GLsizei)h);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    if(w<=h)
        glOrtho(-1.5,1.5,-1.5*(GLfloat)h/(GLfloat)w,1.5*(GLfloat)h/(GLfloat)w,-10.0,10.0);
    else
        glOrtho(-1.5*(GLfloat)w/(GLfloat)h,1.5*(GLfloat)w/(GLfloat)h,-1.5,1.5,-10.0,10.0);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
}

int main(int argc,char** argv){
    glutInit(&argc,argv);
    glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB|GLUT_DEPTH);
    glutInitWindowSize(500,500);
    glutInitWindowPosition(100,100);
    glutCreateWindow(argv[0]);
    init();
    glutDisplayFunc(display);
    glutReshapeFunc(reshape);
    glutMainLoop();
    return 0;
}

6.使用模型视图变换移动光源

#include <windows.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glut.h>

#include <cstdlib>
#include <cstdio>
#include <cmath>

static int spin = 0;

void init(void){
    glClearColor(0.0,0.0,0.0,0.0);
    glShadeModel(GL_SMOOTH);//平滑着色
    glEnable(GL_LIGHTING);//开启光照
    glEnable(GL_LIGHT0);//开启光源0
    glEnable(GL_DEPTH_TEST);
}

void display(void){
    GLfloat position[] = {0.0,0.0,1.5,1.0};
    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
    glPushMatrix();
        glTranslatef(0.0,0.0,-5.0);
        glPushMatrix();
            glRotated((GLdouble)spin,1.0,0.0,0.0);
            glLightfv(GL_LIGHT0,GL_POSITION,position);
            glTranslated(0.0,0.0,1.5);
            glDisable(GL_LIGHTING);
            glColor3f(0.0,1.0,1.0);
            glutWireCube(0.1);//绘制立方体
            glEnable(GL_LIGHTING);
        glPopMatrix();
        glutSolidTorus(0.275,0.85,8,15);//绘制球体
    glPopMatrix();
    glFlush();
}

void reshape(int w, int h){
    glViewport(0,0,(GLsizei)w,(GLsizei)h);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(40.0,(GLfloat)w/(GLfloat)h,1.0,20.0);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
}

void mouse(int button,int state,int x,int y){
    switch(button){
    case GLUT_LEFT_BUTTON:
        if(state == GLUT_DOWN){
            spin = (spin + 30) % 360;
            glutPostRedisplay();//重绘窗口
        }
        break;
    default:
        break;
    }
}

int main(int argc,char** argv){
    glutInit(&argc,argv);
    glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB|GLUT_DEPTH);
    glutInitWindowSize(500,500);
    glutInitWindowPosition(100,100);
    glutCreateWindow(argv[0]);
    init();
    glutDisplayFunc(display);
    glutReshapeFunc(reshape);
    glutMouseFunc(mouse);
    glutMainLoop();
    return 0;
}

7.可以通过单击,滑轮点击,右键改变材质颜色的光照例子

#include <windows.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glut.h>

#include <cstdlib>
#include <cstdio>
#include <cmath>

GLfloat diffuseMaterial[4]={0.5,0.5,0.5,1.0};

void init(void){
    GLfloat mat_specular[]={1.0,1.0,1.0,1.0};//材料颜色
    GLfloat light_position[]={1.0,1.0,1.0,0.0};//光源位置
    glClearColor(0.0,0.0,0.0,0.0);
    glShadeModel(GL_SMOOTH);//光滑着色
    glEnable(GL_DEPTH_TEST);
    glMaterialfv(GL_FRONT,GL_DIFFUSE,diffuseMaterial);
    glMaterialfv(GL_FRONT,GL_SPECULAR,mat_specular);
    glMaterialf(GL_FRONT,GL_SHININESS,25.0);
    glLightfv(GL_LIGHT0,GL_POSITION,light_position);
    glEnable(GL_LIGHTING);
    glEnable(GL_LIGHT0);
    glColorMaterial(GL_FRONT,GL_DIFFUSE);
    glEnable(GL_COLOR_MATERIAL);//开启色彩材质(材料颜色绘制)
}

void display(void){
    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
    glutSolidSphere(1.0,20,16);//绘制球体
    glFlush();
}

void reshape(int w,int h){
    glViewport(0,0,(GLsizei)w,(GLsizei)h);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    if(w<=h)
        glOrtho(-1.5,1.5,-1.5*(GLfloat)h/(GLfloat)w,1.5*(GLfloat)h/(GLfloat)w,-10.0,10.0);
    else
        glOrtho(-1.5*(GLfloat)w/(GLfloat)h,1.5*(GLfloat)w/(GLfloat)h,-1.5,1.5,-10.0,10.0);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
}

void mouse(int button,int state,int x,int y){
    switch(button){
        case GLUT_LEFT_BUTTON:
            if(state == GLUT_DOWN){
                diffuseMaterial[0] += 0.1;
                if(diffuseMaterial[0]>1.0)
                    diffuseMaterial[0] = 0.0;
                glColor4fv(diffuseMaterial);
                glutPostRedisplay();//重新绘制
            }
            break;
        case GLUT_MIDDLE_BUTTON:
            if(state == GLUT_DOWN){
                diffuseMaterial[1]+=0.1;
                if(diffuseMaterial[1]>1.0)
                    diffuseMaterial[1]=0.0;
                glColor4fv(diffuseMaterial);
                glutPostRedisplay();//重新绘制
            }
            break;
        case GLUT_RIGHT_BUTTON:
            if(state == GLUT_DOWN){
                diffuseMaterial[2] += 0.1;
                if(diffuseMaterial[2] > 1.0)
                    diffuseMaterial[2] = 0.0;
                glColor4fv(diffuseMaterial);
                glutPostRedisplay();//重新绘制
            }
            break;
        default:
            break;
    }
}

int main(int argc,char** argv){
    glutInit(&argc,argv);
    glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB|GLUT_DEPTH);
    glutInitWindowSize(500,500);
    glutInitWindowPosition(100,100);
    glutCreateWindow(argv[0]);
    init();
    glutDisplayFunc(display);
    glutReshapeFunc(reshape);
    glutMouseFunc(mouse);
    glutMainLoop();
    return 0;
}


Lane-学习OpenGL(2)-七个简单例子