美文网首页
OpenGL 综合案例球体的自传和公转

OpenGL 综合案例球体的自传和公转

作者: 番茄炒西红柿啊 | 来源:发表于2020-07-21 09:25 被阅读0次

效果图:

实现

入口函数,初始化
GLShaderManager     shaderManager;
GLFrustum           viewFrustum;
GLFrame             objectFrame;
GLFrame             cameraFrame;

GLMatrixStack       modelViewMatrix;
GLMatrixStack       projectionMatrix;

GLGeometryTransform transformPipeline;

GLBatch             floorBatch;
GLTriangleBatch     torusBatch;
GLTriangleBatch     sphereBatch;
GLTriangleBatch     sphere1Batch;
GLTriangleBatch     sphere2Batch;

int main(int argc, char *argv[]) {
    gltSetWorkingDirectory(argv[0]);
    // 初始化
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH | GLUT_STENCIL);
    glutInitWindowSize(800, 400);
    glutCreateWindow("");
    
    // 注册回调
    glutReshapeFunc(changeSize);
    glutDisplayFunc(renderScene);
    glutSpecialFunc(speciaKeys);
    
    // 判断
    GLenum err = glewInit();
    if (GLEW_OK != err) {
        fprintf(stderr, "GLEW Error: %s\n", glewGetErrorString(err));
        return 1;
    }
    
    setupRC();
    glutMainLoop();
    return 0;
}
changeSize回调
void changeSize(int w, int h) {
    glViewport(0, 0, w, h);
    viewFrustum.SetPerspective(35.0f, float(w)/float(h), 1.0f, 100.0f);
    projectionMatrix.LoadMatrix(viewFrustum.GetProjectionMatrix());
    transformPipeline.SetMatrixStacks(modelViewMatrix, projectionMatrix);
    modelViewMatrix.LoadIdentity();
}
绘制地板绿色网格
  • setupRC回调中
    // 画地板
    floorBatch.Begin(GL_LINES, 324);
    for(GLfloat x = -20.0; x <= 20.0f; x+= 0.5) {
        floorBatch.Vertex3f(x, -0.55f, 20.0f);
        floorBatch.Vertex3f(x, -0.55f, -20.0f);
        
        floorBatch.Vertex3f(20.0f, -0.55f, x);
        floorBatch.Vertex3f(-20.0f, -0.55f, x);
    }
    floorBatch.End();
  • renderScene回调中
   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
   glEnable(GL_DEPTH_TEST);
    
    // 颜色(地板,大球颜色,小球颜色)
    static GLfloat vFloorColor[] = {0.0f,1.0f,0.0f,1.0f};
    static GLfloat vTorusColor[] = {1.0f,0.0f,0.0f,1.0f};
    static GLfloat vSpereColor[] = {0.0f,0.0f,1.0f,1.0f};
    // 绘制地板
 shaderManager.UseStockShader(GLT_SHADER_FLAT,transformPipeline.GetModelViewProjectionMatrix(),vFloorColor);
    floorBatch.Draw();

    glutSwapBuffers();
    glutPostRedisplay();
    glDisable(GL_DEPTH_TEST);
绘制红色大球
  • setupRC中添加:
// 大球
gltMakeSphere(torusBatch, 0.4f, 40, 80);
  • renderScene
// 设置将观察者矩阵压入栈中
    M3DMatrix44f mCamera;
    cameraFrame.GetCameraMatrix(mCamera);
    modelViewMatrix.PushMatrix(mCamera);

    // 设置点光源位置
    M3DVector4f vLightPos = {0,10,5,1};
    // 使得整个往里平移 3.0
    modelViewMatrix.Translate(0.0f, 0.0f, -8.0f);

    // 大球的矩阵变换
    modelViewMatrix.PushMatrix();
    modelViewMatrix.Rotate(yRot, 0, 1, 0);
    shaderManager.UseStockShader(GLT_SHADER_POINT_LIGHT_DIFF,transformPipeline.GetModelViewMatrix(),transformPipeline.GetProjectionMatrix(),vLightPos,vTorusColor);
    torusBatch.Draw();
    modelViewMatrix.PopMatrix();
    modelViewMatrix.PopMatrix();

绘制红球整个过程中,矩阵堆栈的变化如图:


绘制红球矩阵堆栈变化过程
绘制蓝球
  • SetupRC中添加
// 绘制小球;
gltMakeSphere(sphereBatch, 0.1f, 13, 26);

*renderScene中添加

    // 小球的矩阵变换
    modelViewMatrix.PushMatrix();
    modelViewMatrix.Rotate(yRot * -2.0f, 0, 1, 0);
    modelViewMatrix.Translate(0.8f, 0.0f, 0.0f);
    shaderManager.UseStockShader(GLT_SHADER_POINT_LIGHT_DIFF,transformPipeline.GetModelViewMatrix(),transformPipeline.GetProjectionMatrix(),vLightPos,vSpereColor);
    sphereBatch.Draw();
    modelViewMatrix.PopMatrix();

绘制完成



绘制蓝球时堆栈变化



其他蓝球同理,只是修改了下坐标参数,就不重复贴代码了。

相关文章

网友评论

      本文标题:OpenGL 综合案例球体的自传和公转

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