欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

OpenGL三维漫游

程序员文章站 2022-07-04 09:08:58
...

一堆机器人的一个三维场景漫游,详细制作过程去年传到了B站和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);
}

相关标签: OpenGL 三维漫游