美文网首页
5.综合案例

5.综合案例

作者: bytebytebyte | 来源:发表于2020-11-26 09:24 被阅读0次
#include "GLShaderManager.h"
#include "GLTools.h"
#include "GLFrustum.h"
#include "GLBatch.h"
#include "GLMatrixStack.h"
#include "GLGeometryTransform.h"
#include "StopWatch.h"

#include <math.h>
#include <stdio.h>

#ifdef __APPLE__
#include <glut/glut.h>
#else
#define FREEGLUT_STATIC
#include <GL/glut.h>
#endif

GLShaderManager shaderManager;           //着色管理器
GLMatrixStack modelViewMatrix;           //模型视图矩阵
GLMatrixStack projectionMatrix;          //投影矩阵
GLFrustum viewFrustum;                   //视景体
GLGeometryTransform transformPipeline;   //几何图形变换管道
GLTriangleBatch torusBatch;              //打球
GLTriangleBatch sphereBatch;             //小球
GLBatch floorBatch;                      //地板
GLFrame cameraFrame;                     //照相机角色帧
//添加附加随机球
#define NUM_SPHERES 50
GLFrame spheres[NUM_SPHERES];

//为程序做一次性的设置
void setupRC() {
    //1.初始化
    glClearColor(0, 0, 0, 1);
    shaderManager.InitializeStockShaders();
    
    //2.开启深度测试
    glEnable(GL_DEPTH_TEST);
    
    //3.设置地板顶点数据
    floorBatch.Begin(GL_LINES, 324);
    for (GLfloat x = -20; x <= 20; x += 0.5) {
        floorBatch.Vertex3f(x, -0.55, 20);
        floorBatch.Vertex3f(x, -0.55, -20);
        floorBatch.Vertex3f(20, -0.55, x);
        floorBatch.Vertex3f(-20, -0.55, x);
    }
    floorBatch.End();
    
    //4.设置打球模型
    gltMakeSphere(torusBatch, 0.4, 40, 80);
    
    //5.设置小球模型
    gltMakeSphere(sphereBatch, 0.1, 26, 13);
    
    //6.随机位置放置小球
    for (int i = 0; i < NUM_SPHERES; i ++) {
        //y轴不变,X,Z产生随机值
        GLfloat x = ((GLfloat)(rand() % 400 - 200)) * 0.1;
        GLfloat z = ((GLfloat)(rand() % 400 - 200)) * 0.1;
        //在y方向,将球体设置为0,0的位置,这使得它们看起来是漂浮在眼镜的高度
        //对spheres数组中的每一个顶点,设置顶点数据
        spheres[i].SetOrigin(x, 0, z);
    }
}

//绘制场景
void renderScene(void) {
    //1.颜色值
    static GLfloat vFloorColor[] = { 0, 1, 0, 1 };
    static GLfloat vTorusColor[] = { 1, 0, 0, 1 };
    static GLfloat vSphereColor[] = { 0, 0, 1, 1 };
    
    //2.基于时间动画
    static CStopWatch rotTimer;
    float yRot = rotTimer.GetElapsedSeconds() * 60;
    
    //3.清除时间缓冲区和深度缓冲区
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    
    //4.加入观察者平移10步(地板,打球,小球,小小球)
    M3DMatrix44f mCamera;
    cameraFrame.GetCameraMatrix(mCamera);
    modelViewMatrix.PushMatrix(mCamera);
    
    //5.获取光源位置
    M3DVector4f vLightPos = { 0, 10, 5, 1 };
    
    //6.绘制地面
    shaderManager.UseStockShader(GLT_SHADER_FLAT, transformPipeline.GetModelViewProjectionMatrix(), vFloorColor);
    floorBatch.Draw();
    
    //打球默认位置是(0,0,0)Z深度(3)正负指的是方向,数字指的是移动距离
    //7.使得大球位置平移(3)向屏幕里面,只移动一次
    modelViewMatrix.Translate(0, 0, -3);
    
    //8.压栈(复制栈顶)
    modelViewMatrix.PushMatrix();
    
    //9.大球自转
    modelViewMatrix.Rotate(yRot, 0, 1, 0);
    
    //10.指定合适的着色器,点光源着色器
    shaderManager.UseStockShader(GLT_SHADER_POINT_LIGHT_DIFF, transformPipeline.GetModelViewMatrix(), transformPipeline.GetProjectionMatrix(), vLightPos, vTorusColor);
    torusBatch.Draw();
    
    //11.绘制完毕pop
    modelViewMatrix.PopMatrix();
    
    //12.画小球
    for (int i = 0; i < NUM_SPHERES; i ++) {
        modelViewMatrix.PushMatrix();
        modelViewMatrix.MultMatrix(spheres[i]);
        shaderManager.UseStockShader(GLT_SHADER_POINT_LIGHT_DIFF, transformPipeline.GetModelViewMatrix(), transformPipeline.GetProjectionMatrix(), vLightPos, vSphereColor);
        sphereBatch.Draw();
        modelViewMatrix.PopMatrix();
    }
    
    //13.让一个小球围绕打球公转自转
    //为何这里没加PushMatrix/PopMatrix?可以加,因为是最后的绘图因为没有不会影响就没有添加
    modelViewMatrix.PushMatrix();
    
    modelViewMatrix.Rotate(yRot * -2, 0, 1, 0);
    modelViewMatrix.Translate(0.8, 0, 0);
    shaderManager.UseStockShader(GLT_SHADER_FLAT, transformPipeline.GetModelViewProjectionMatrix(), vSphereColor);
    sphereBatch.Draw();
    
    modelViewMatrix.PopMatrix();
    
    modelViewMatrix.PopMatrix();
    
    glutSwapBuffers();
    glutPostRedisplay();
    
}

//窗口改变时接受新的宽度和高度,0,0代表窗口中视口的左下角坐标,w,h代表像素
void ChangeSize(int w, int h) {
    //1.设置视口
    glViewport(0, 0, w, h);
    
    //2.创建投影矩阵并加载到投影矩阵堆栈中
    viewFrustum.SetPerspective(35, float(w) / float(h), 1, 100);
    projectionMatrix.LoadMatrix(viewFrustum.GetProjectionMatrix());
    
    //3.这个操作也可以在SetupRC 函数中完成,但是在窗口大小改变时或者窗口创建时设置它们并没有坏处。而且这样可以一次性完成矩阵和管线的设置。
    transformPipeline.SetMatrixStacks(modelViewMatrix, projectionMatrix);
}

void specialKeys(int key, int x, int y) {
    //移动步长
    float linear = 0.1;
    //旋转度数
    float angular = float(m3dDegToRad(5));
    if (key == GLUT_KEY_UP) {
        cameraFrame.MoveForward(linear);
    }
    if (key == GLUT_KEY_DOWN) {
        cameraFrame.MoveForward(-linear);
    }
    if (key == GLUT_KEY_LEFT) {
        cameraFrame.RotateWorld(angular, 0, 1, 0);
    }
    if (key == GLUT_KEY_RIGHT) {
        cameraFrame.RotateWorld(-angular, 0, 1, 0);
    }
}

int main(int argc, char *argv[]) {
    gltSetWorkingDirectory(argv[0]);
    
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
    glutInitWindowSize(800, 600);
    glutCreateWindow("OpenGL SphereWorld");
    
    glutReshapeFunc(ChangeSize);
    glutDisplayFunc(renderScene);
    glutSpecialFunc(specialKeys);
    GLenum err = glewInit();
    if (err != GLEW_OK) {
        fprintf(stderr, "GLEW Error:%s\n",glewGetErrorString(err));
        return 1;
    }
    setupRC();
    glutMainLoop();
    
    return 0;
}

相关文章

  • 5.综合案例

  • 5.综合案例要点

    tabs动态添加选项卡,加载远程资源细节: 使用iframe标签加载资源给content easyui中下拉框自适...

  • 综合案例

    来自拉钩教育-JAVA就业集训营 1.商城案例表设计 通过对商城项目的部分表关系进行分析,完成数据库表的设计 1....

  • 方法综合案例

    def __init__(self, name): self.name = name @stati...

  • 综合案例展示

    想做出效果如下的页面: html代码入下 CSS样式入下:

  • 方法综合案例

    class Game: top_stor=0 def __init__(self, name): ...

  • javaWeb综合案例

  • OpenGL综合案例

    今天我们来做一个关于OpenGL的一个综合案例,里面包含了点,线,三角形,金字塔等图形的绘制。 需要准备的东西之前...

  • OpenGL 综合案例

    在绘制之前,我们先来介绍下一下几个头文件的作用。 接下来我们需要在外部声明几个全局变量。 绘制地板 main函数工...

  • OpenGL 综合案例

    先看结果 核心代码 栈的机制 在changeSize()函数中,我们加载了投影矩阵,并把投影矩阵压入管道trans...

网友评论

      本文标题:5.综合案例

      本文链接:https://www.haomeiwen.com/subject/xpmpiktx.html