OpenGL中的投影使用

OpenGL中的投影使用

大家好,又见面了,我是全栈君,祝每个程序员都可以多学几门语言。

OpenGL中的投影使用


         在OpenGL中,投影矩阵指定了可视区域的大小和形状。对于正投影与透视投影这两种不同的投影类型,它们分别有各自的用途。

 

正投影

         它适用于2D图形,如文本、建筑画图等。在它的应用场合,我们希望在屏幕上展示准确的物体大小和度量。

 

OpenGL中的投影使用

透视投影

         它使用透视除法,对距离观察者较远的物体进行缩短和收缩。由于可视区域前端和后端的宽度度量方法并不同样,导致两个逻辑大小同样的物体,当它们分别位于可视区域的前面和后面时,前者看上去要比后者大一些。

         下图展示了*截头体(frustum)所定义的透视投影,它的观察方向是从狭窄端到宽阔端。工具函数gluPerspective能够方便的定义一个*截头体:

      

         void gluPerspective(GLdouble fovy, GLdouble aspect, GLdouble near, GLdouble far);

        

         參数 fovy表示垂直方向的视野角度,aspect表示宽度与高度的纵横比,near与far表示*端和远端裁剪*面之间的距离。

OpenGL中的投影使用

OpenGL中的投影使用

 

         以下的代码设置使用了透视投影,展示了一个由太阳(黄色)、地球(红色)、月亮(灰色)三者构成的运动系统。这是一个经典的嵌套变换的样例,我们使用矩阵堆栈将一个物体依据还有一个物体进行变换,执行结果如图所看到的:

OpenGL中的投影使用

OpenGL中的投影使用

/* 程序清单 4-3

 * 2014/5/18

 */

#include <glut.h>

#include <math.h>

 

// 旋转的步进值

static float fMoonRot =0.0f;

static float fEarthRot= 0.0f;

 

// 设置渲染状态

void SetupRC()

{

         // 设置清除窗体的颜色(黑色背景)

         glClearColor(0.0f, 0.0f, 0.0f, 1.0f);

         // 设置画图颜色为绿色

         glColor3f(0.0f, 1.0f, 0.0f);

         // 打开深度測试

         glEnable(GL_DEPTH_TEST);

}

 

// 绘制场景(显示回调函数)

void RenderScene()

{

         // 用当前的清除颜色清除窗体

         glClear(GL_COLOR_BUFFER_BIT |GL_DEPTH_BUFFER_BIT);

         // 保存矩阵状态(模型视图矩阵)

         glMatrixMode(GL_MODELVIEW);

         glPushMatrix();

         // *移坐标系,注意是相对于视觉坐标的位置

         glTranslatef(0.0f, 0.0f, -300.0f);

 

         // 绘制太阳

         glColor3ub(255, 255, 0);

         glutSolidSphere(15.0f, 15, 15);

         // 旋转坐标系,累加效果

         glRotatef(fEarthRot, 0.0f, 1.0f, 0.0f);

 

         // 绘制地球

         glColor3ub(255, 0, 0);

         // *移坐标系,累加效果

         glTranslatef(105.0f, 0.0f, 0.0f);

         // 设置地球的旋转步进

         fEarthRot += 5.0f;

         if(fEarthRot > 360.0f) {

                  fEarthRot = 0.0f;

         }

         glutSolidSphere(15.0f, 15, 15);

 

         // 绘制月球

         glColor3ub(200, 200, 200);

         // 旋转坐标系,累加效果

         glRotatef(fMoonRot, 0.0f, 1.0f, 0.0f);

         // *移坐标系,累加效果

         glTranslatef(30.0f, 0.0f, 0.0f);

         // 设置月亮的旋转步进

         fMoonRot += 15.0f;

         if(fMoonRot > 360.0f) {

                  fMoonRot = 0.0f;

         }

         glutSolidSphere(6.0f, 15, 15);

 

         // 恢复矩阵状态(当前坐标系与视觉坐标重合)

         glPopMatrix();

 

         // 交换缓冲区,显示画面

         glutSwapBuffers();

}

 

// 当窗体大小改变时由GLUT函数库调用

void ChangeSize(GLsizei w, GLsizei h)

{

         // 窗体的纵横比

         GLfloat fAspect;

         // 防止被0

         if (0== h) {

                  h = 1;

         }

         // 将视口设置为窗体的大小

         glViewport(0, 0, w, h);

         // 计算窗体的纵横比

         fAspect = (GLfloat)w / (GLfloat)h;

         // 设置当前操作的矩阵为投影矩阵

         glMatrixMode(GL_PROJECTION);

         glLoadIdentity();

         // 定义*截头体, 45度视野,*、远*面为1.0425.0

         gluPerspective(45.0f,fAspect, 1.0, 425.0);

         // 设置当前操作的矩阵为模型视图矩阵

         glMatrixMode(GL_MODELVIEW);

         glLoadIdentity();

}

 

// 计时器函数,每秒触发10次窗体重绘事件

void TimerFunc(intvalue)

{

         glutPostRedisplay();

         glutTimerFunc(100, TimerFunc, 1);

}

 

int main(int argc,char *argv[])

{

         // 传递命令行參数,并对GLUT函数库进行初始化

         glutInit(&argc, argv);

         // 设置创建窗体时的显示模式(双缓冲区、RGB颜色模式)

         glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGB);

         // 设置窗体的初始大小

         glutInitWindowSize(480, 320);

         // 创建窗体

         glutCreateWindow(“Bounce”);

         // 设置显示回调函数

         glutDisplayFunc(RenderScene);

         // 设置当窗体的大小发生变化时的回调函数

         glutReshapeFunc(ChangeSize);

         // 设置计时器函数

         glutTimerFunc(100, TimerFunc, 1);

         // 设置渲染状态

         SetupRC();

         // 启动GLUT框架的执行,一经调用便不再返回,直到程序终止

         glutMainLoop();

 

         return0;

}

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/118963.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • ubuntu开机进入tty1_基于linux内核自制系统

    ubuntu开机进入tty1_基于linux内核自制系统这个系统很迷你。完全符合变态操作控的习惯,如果你很喜欢洁净的系统,那么它就是你的玩具~可以试试自己的能力,是否能够在这系统里DIY一个属于你自己的LINUX。。。转载于:https://www.cnblogs.com/xiaoCon/archive/2013/03/31/2991221.html…

    2022年8月12日
    10
  • 大数据分析在职业体育应用

    大数据分析在职业体育应用大数据分析在职业体育应用(NBA)什么是大数据?举个例子,都说骑士队依赖詹姆斯,当詹姆斯在场上时,骑士队每100回合净胜对手6.9分;詹姆斯不在场,骑士队净负对手2.9分,两者之间差值为9.8分。而勇士队的库里在场上和在场下时,勇士队每100回合净胜分的差值为17分,可以说勇士队对库里的依赖甚至要更强。这样的数据才可以叫大数据,相比而言,像得分、篮板、助攻这样的技术统计简直弱爆了。大数据在N…

    2022年5月9日
    83
  • 看完了aspnetmvc nerdinner项目

    看完了aspnetmvc nerdinner项目这几天一直在看aspnetmvc-nerdinner这本书中的Nerdinner代码编写的全过程。其实觉得用最原始的办法:动手敲代码带给我们的好处比单纯的看然后Copy代码再运行要好的多,最起码加深了我们的记忆。前段时间看了ASP.NET网站上关于ASP.NETMVC编程的培训文章,觉得MVC挺强大的,然后就试着自己做了一个小项目,可是在做的过程中,很多东西确实见多人家怎么做,也知道大概…

    2022年9月29日
    3
  • socket默认端口号(socket和端口的关系)

    from:http://www.iana.org/assignments/port-numbers
     
    ////////////////////////////////////////////////////////////////////////////////
     PORTNUMBERS(lastupdated2010-09-24)Theportnumbersaredividedintothreeranges:theWel

    2022年4月17日
    179
  • RabbitMQ入门:主题路由器(Topic Exchange)[通俗易懂]

    上一篇博文中,我们使用directexchange代替了fanoutexchange,这次我们来看下topicexchange。一、TopicExchange介绍topicexchan

    2022年2月16日
    190
  • matlab画出三角函数图像_matlab二元函数绘图

    matlab画出三角函数图像_matlab二元函数绘图在matlab中绘制二元函数图像矩形区域上的绘制考虑f(x,y)=2×2+2y2+4xy−3y−3x+1f(x,y)=2x^2+2y^2+4xy-3y-3x+1f(x,y)=2×2+2y2+4xy−3y−3x+1在矩形区域[0,1]×[0,1][0,1]\times[0,1][0,1]×[0,1]上的图像。直接上代码:%meshf(x,y)onacertaindomainclear;clc;%generatedomainX=0:

    2025年9月28日
    5

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号