美文网首页
OpenGL--绘制镜面球体

OpenGL--绘制镜面球体

作者: BigBowen | 来源:发表于2019-05-27 18:13 被阅读0次

效果:

镜面球体.gif

详细代码见githup:

MirrorSphere

实现思路:

这里讲几个主要的方法及注意点:

键盘命令监听:

这里监听键盘的上下左右几个操作,相应的改变观察者的位置.

void SpeacialKeys(int key,int x,int y)
{
    
    float linear = 0.1f;
    float angular = float(m3dDegToRad(5.0f));
    
    if (key == GLUT_KEY_UP) {
        
        //MoveForward 平移
        cameraFrame.MoveForward(linear);
    }
    
    if (key == GLUT_KEY_DOWN) {
        cameraFrame.MoveForward(-linear);
    }
    
    if (key == GLUT_KEY_LEFT) {
        //RotateWorld 旋转
        cameraFrame.RotateWorld(angular, 0.0f, 1.0f, 0.0f);
    }
    
    if (key == GLUT_KEY_RIGHT) {
        cameraFrame.RotateWorld(-angular, 0.0f, 1.0f, 0.0f);
    }
    
}
设置顶点:

根据gif显示,需要展示的有:
1.自转的大球
2.围绕大球公转的小球
3.其它悬浮不动的小球
4.地板
5.地板之下的各种球(gif的镜面效果,实际上是在地板下把全部的球再画一遍,配合颜色混合,展示出镜面效果,这里可以直接复用球的顶点数据,再围绕y轴做翻转和平移即可,不需要额外设置顶点).

//设置大球顶点
void setBigSphereVertex(){
    //60是径向的,80是横向的,都是越大球越圆
    gltMakeSphere(bigSphereBatch, 0.5f, 60, 80);
}
//设置小球顶点
void setSmallSphereVertex(){
    gltMakeSphere(smallSphereBatch, 0.2, 30, 40);
}
//设置龙套小球的顶点
void setOtherSphereVertex(){
    gltMakeSphere(otherSphereBatch, 0.2, 20, 40);
    
    //7.随机小球球顶点坐标数据
    for (int i = 0; i < NUM_SPHERES; i++) {
        
        //y轴不变,X,Z产生随机值
        GLfloat x = ((GLfloat)((rand() % 400) - 200 ) * 0.1f);
        GLfloat y = (GLfloat)((rand() % 4));
        GLfloat z = ((GLfloat)((rand() % 400) - 200 ) * 0.1f);
        
        //在y方向,将球体设置为0.0的位置,这使得它们看起来是飘浮在眼睛的高度
        //对spheres数组中的每一个顶点,设置顶点数据
        spheres[i].SetOrigin(x, y, z);
    }
}
//设置地板顶点
void setFloorVertex(){
    
    GLfloat texSize = 10.0f;
    floorBatch.Begin(GL_TRIANGLE_FAN, 4,1);
    floorBatch.MultiTexCoord2f(0, 0.0f, 0.0f);
    floorBatch.Vertex3f(-20.f, -0.41f, 20.0f);
    
    floorBatch.MultiTexCoord2f(0, texSize, 0.0f);
    floorBatch.Vertex3f(20.0f, -0.41f, 20.f);
    
    floorBatch.MultiTexCoord2f(0, texSize, texSize);
    floorBatch.Vertex3f(20.0f, -0.41f, -20.0f);
    
    floorBatch.MultiTexCoord2f(0, 0.0f, texSize);
    floorBatch.Vertex3f(-20.0f, -0.41f, -20.0f);
    floorBatch.End();
}
场景渲染

注意点在代码注释中已经标明

//绘制场景
void RenderScene(void)
{
    
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    //这次压栈是为了接收到键盘命令时,移动观察者
    //ps:这个PushMatrix()函数会自动帮我们把栈顶的元素copy一份,然后压入栈中,配合PopMatrix()函数,能让变化只在push和pop之间有效,pop之后恢复原值;这样设计能把不同物体的渲染独立开,不会相互影响.
    modelViewMatrix.PushMatrix();
    M3DMatrix44f mCamera;
    //从cameraFrame取值,然后赋值给矩阵mCamera
    cameraFrame.GetCameraMatrix(mCamera);
    modelViewMatrix.MultMatrix(mCamera);
    
    //绘制镜面开始
    modelViewMatrix.PushMatrix();
    modelViewMatrix.Scale(1.0f, -1.0f, 1.0f);
    modelViewMatrix.Translate(0.0f, 1.0f, -1.0f);
    //指定顺时针为正面,因为物体翻转了,否则看到的是背面
    glFrontFace(GL_CW);
    drawBigSphere();
    drawSmallSphere();
    drawOtherSphere();
    //恢复为逆时针为正面
    glFrontFace(GL_CCW);
    //绘制镜面结束
    modelViewMatrix.PopMatrix();
    
    //开启混合
    glEnable(GL_BLEND);
    //指定glBlendFunc 颜色混合方程式
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    drawFloor();
    //取消混合
    glDisable(GL_BLEND);
    
    //整体上移,否则大球会被地板挡住
    modelViewMatrix.Translate(0.0f, 0.1f, -1.0f);
    drawBigSphere();
    drawSmallSphere();
    drawOtherSphere();
    
    //不能太早pop,这个观察者是针对所有的物体的
    modelViewMatrix.PopMatrix();
    glutSwapBuffers();
    glutPostRedisplay();
}

相关文章

  • OpenGL--绘制镜面球体

    效果: 详细代码见githup: MirrorSphere 实现思路: 这里讲几个主要的方法及注意点: 键盘命令监...

  • OpenGL ES之旋转的地球

    前言 本篇文章包含以下内容: 1、球体绘制 2、纹理映射到球体 3、球体自转 先来看下最终效果: 1、球体绘制 1...

  • OpenGL球体纹理填充

    上篇文章我们介绍过 纹理的使用,以及常用函数。今天我们来使用纹理填充球体,以及镜面效果的绘制。 首先我们来看一下绘...

  • OpenGL--图元绘制

    前言 这篇文章的目的是了解OpenGL中图形渲染的基本图元以及如何绘制基本图元,真正从原理入手,了解图形渲染的基本...

  • 球体世界

    为球体贴上纹理以及实现镜面效果,代码如下: 运行效果如下:

  • OpenGL ES 学习笔记(2)-复杂图形绘制

    结合球体和圆环,学习复杂图形绘制 1. 球体绘制 1.1. 思路 在上一篇笔记中说过,OpenGL可以画点、线和三...

  • OpenGL:世界球体(移动,公转,自转)

    OpenGL: 世界球体(移动,公转,自转) void SetupRC() 绘制地板 很多个矩形组成 绘制花托 v...

  • opengl-球体的绘制

    opengl-pbr 光照一讲里,以球体为案例进行说明。球体的绘制第一次接触理解花了点时间 一、球体坐标分解 按照...

  • OpenGL绘制球体世界

    本文主要记录使用所学OpenGL相关知识绘制OpenGL中的一个经典案例--球体世界,最终实现效果如下: 准备工作...

  • OpenGL纹理案例解析

    这个案例是在之前的案例球体旋转Demo的基础上,加以改动做的,主要是给了球体添加纹理,以及做了一个镜面的效果,具体...

网友评论

      本文标题:OpenGL--绘制镜面球体

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