OpenGL三维漫游

一堆机器人的一个三维场景漫游,详细制作过程去年传到了B站(click here)和YouTube,突然想起来就发一下博客,并不难理解。

#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <GL/glut.h>
#include <math.h>

#include <GL/glext.h>

#define windowWidth 800
#define windowHeight 600

void display(void);
void bmpReader(void);
static GLint imagewidth;
static GLint imageheight;
static GLint pixellength;
static GLubyte* pixeldata;
//...Menu
GLfloat red=0.0,green=0.0,blue=0.0;

void init(void);
void Ttttttest(void);
void Tttest(int selOption);
void Testtt(int colOption);

int selFlag=1;
//...Demo
struct Coordinate{
    GLfloat x;
    GLfloat y;
    GLfloat z;
}cameraPos,sightLin,defaultVal;

static GLint demo_display_list;
static float angle=0.0,ratio=0.0;

void sightLine(int w,int h);
void keyboardDemo(int key,int x,int y);
void rotate(GLfloat ang);
void transla(GLint direct);
void displayDemo(void);
GLuint speupList(void);
void initList(void);
void displayDemo(void);
//...Main
int main(int argc,char* argv[]){
    glutInit(&argc,argv);
    glutInitDisplayMode(GLUT_DEPTH|GLUT_DOUBLE|GLUT_RGB);
    glutInitWindowPosition(233,233);
    glutInitWindowSize(windowWidth,windowHeight);
    int forSub=glutCreateWindow("F");

    init();
    initList();

    int subArgument=glutCreateMenu(Testtt);
    glutAddMenuEntry("Red",1);
    glutAddMenuEntry("Green",2);
    glutAddMenuEntry("Blue",3);
    glutCreateMenu(Tttest);
    glutAddMenuEntry("Roming",3);
    glutAddMenuEntry("Triangle",1);
    glutAddMenuEntry("Rectangle",2);
    glutAddSubMenu("Color",subArgument);
    glutAttachMenu(GLUT_RIGHT_BUTTON);
    glutSpecialFunc(keyboardDemo);
    glutReshapeFunc(sightLine);
    glutDisplayFunc(displayDemo);

    glutMainLoop();
}

void init(void){
    glClearColor(0.0,0.2,1.0,1.0);
    glMatrixMode(GL_PROJECTION);
    gluOrtho2D(0.0,800.0,0.0,600.0);

    cameraPos.x=0.0;cameraPos.y=1.75;cameraPos.z=5.0;
    sightLin.x=0.0;sightLin.y=0.0;sightLin.z=-1.0;
    defaultVal.x=0.0;defaultVal.y=1.0;defaultVal.z=0.0;
}
//......Menu;
void Ttttttest(void){
    glClear(GL_COLOR_BUFFER_BIT);
    glColor3f(red,green,blue);
    if (selFlag==1){
        glBegin(GL_TRIANGLES);
            glVertex2d(100.0,100.0);
            glVertex2d(700.0,100.0);
            glVertex2d(400.0,500.0);
        glEnd();
    }
    else if (selFlag==2){
        glBegin(GL_POLYGON);
            glVertex2d(100.0,100.0);
            glVertex2d(700.0,100.0);
            glVertex2d(700.0,500.0);
            glVertex2d(100.0,500.0);
        glEnd();
    }
    else if (selFlag==3){
        ;
    }
    glFlush();
}

void Tttest(int selOption){
    switch (selOption){
    case 1:
        selFlag=1;
        break;
    case 2:
        selFlag=2;
        break;
    case 3:
        selFlag=3;
    default:
        break;
    }
    glutPostRedisplay();
}

void Testtt(int colOption){
    switch (colOption){
    case 1:
        red=1.0;green=0.0;blue=0.0;
        break;
    case 2:
        red=0.0;green=1.0;blue=0.0;
        break;
    case 3:
        red=0.0;green=0.0;blue=1.0;
        break;
    default:
        break;
    }
    glutPostRedisplay();
}
//......End Menu.
void sightLine(int w,int h){
    ratio=w/h;
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();

    glViewport(0,0,w,h);

    gluPerspective(45,ratio,1,1000);

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

    gluLookAt(cameraPos.x,cameraPos.y,cameraPos.z,
              cameraPos.x+sightLin.x,cameraPos.y+sightLin.y,cameraPos.z+sightLin.z,
              defaultVal.x,defaultVal.y,defaultVal.z);
}

void keyboardDemo(int key,int x,int y){
    switch (key){
    case GLUT_KEY_LEFT:
        angle-=0.05f;rotate(angle);
        break;
    case GLUT_KEY_RIGHT:
        angle+=0.05f;rotate(angle);
        break;
    case GLUT_KEY_UP:
        transla(1);
        break;
    case GLUT_KEY_DOWN:
        transla(-1);
        break;
    default:
        break;
    }
    glutPostRedisplay();
}

void rotate(GLfloat ang){
    sightLin.x=sin(ang);
    sightLin.z=-cos(ang);
    glLoadIdentity();
    gluLookAt(cameraPos.x,cameraPos.y,cameraPos.z,
              cameraPos.x+sightLin.x,cameraPos.y+sightLin.y,cameraPos.z+sightLin.z,
              defaultVal.x,defaultVal.y,defaultVal.z);
}

void transla(GLint direct){
    cameraPos.x=cameraPos.x+direct*sightLin.x*0.3;
    cameraPos.z=cameraPos.z+direct*sightLin.z*0.3;
    glLoadIdentity();
    gluLookAt(cameraPos.x,cameraPos.y,cameraPos.z,
              cameraPos.x+sightLin.x,cameraPos.y+sightLin.y,cameraPos.z+sightLin.z,
              defaultVal.x,defaultVal.y,defaultVal.z);
}

void listDemo(void){
    glColor3f(0.0,0.0,0.0);
    glRotated(90,0,1,0);
    glTranslatef(0.0,0.7,0.0);
    glutSolidTorus(0.15,0.25,15,40);//wheel
    glRotatef(90,0,-1,0);

    glColor3f(0.58,0.29,0.0);
    glTranslatef(0.0,0.55,0.0);
    glutSolidCube(0.5);
    glTranslatef(0.0,0.37,0.0);
    glutSolidCube(0.5);//body

    glColor3f(0.68,0.30,0.0);
    glTranslatef(0.0,0.63,0.0);
    glScalef(1.7,1.0,1.0);
    glutWireCube(0.75005);

    glColor3f(0.58,0.29,0.0);
    glutSolidCube(0.75);//head

    glColor3f(0.0,0.0,0.0);
    glTranslatef(-0.2,0.1,0.4);
    glScalef(0.5,1.0,0.7);
    glutSolidSphere(0.1,20,20);
    glTranslatef(0.8,0.0,0.0);
    glutSolidSphere(0.1,20,20);//eyes

    glColor3f(1.0,0.5,0.5);
    glTranslatef(-0.4,-0.2,0.0);
    glRotatef(0.0,1.0,0.0,0.0);
    glutSolidCone(0.1,0.5,20,7);//nose
}

GLuint speupList(void){
    GLuint modelList;
    modelList=glGenLists(1);
    glNewList(modelList,GL_COMPILE);
    listDemo();
    glEndList();
    return modelList;
}

void initList(void){
    glEnable(GL_DEPTH_TEST);
    demo_display_list=speupList();
    //glutInitDisplayMode(GLUT_DEPTH|GLUT_DOUBLE|GLUT_RGB);
}

void displayDemo(void){
    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
    glColor3f(0.2,1.0,0.0);
    glBegin(GL_QUADS);
        glVertex3f(-100,0,-100);
        glVertex3f(100,0,-100);
        glVertex3f(100,0,100);
        glVertex3f(-100,0,100);
    glEnd();
    //glEnable(GL_DEPTH_TEST);
    //demo_display_list=speupList();
    for (int i=-3;i<3;i++){
        for (int j=-3;j<3;j++){
            glPushMatrix();
            glTranslatef(i*10.0,0,j*10.0);
            glCallList(demo_display_list);
            glPopMatrix();
        }
    }

    glutSwapBuffers();
}

void display(void){
    //glClear(GL_COLOR_BUFFER_BIT);

    //绘制像素
    glDrawPixels(imagewidth,imageheight,GL_BGR_EXT,GL_UNSIGNED_BYTE,pixeldata);

    glFlush();
    glutSwapBuffers();
}

void bmpReader(void){
    //打开文件
    FILE* pfile=fopen("D:\\Documents\\desktop桌面文件\\期末 2018秋季学期 大二上学期\\bliss.bmp","rb");
    if(pfile == 0) exit(0);//直接退出了 问题在这里

    //读取图像大小
    fseek(pfile,0x0012,SEEK_SET);
    fread(&imagewidth,sizeof(imagewidth),1,pfile);
    fread(&imageheight,sizeof(imageheight),1,pfile);

    //计算像素数据长度
    pixellength=imagewidth*3;
    while(pixellength%4 != 0)pixellength++;
    pixellength *= imageheight;

    //读取像素数据
    pixeldata = (GLubyte*)malloc(pixellength);
    if(pixeldata == 0) exit(0);

    fseek(pfile,54,SEEK_SET);
    fread(pixeldata,pixellength,1,pfile);

    //关闭文件
    fclose(pfile);

    display();
    free(pixeldata);
}

  • 0
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值