glViewport()函数和glOrtho()函数的理解

关于Opengl各种矩阵变换(MVPW)的自我理解 关于Opengl各种矩阵变换的理解 OpenGL的矩阵变换一直比较迷糊,貌似懂了又貌似不懂,今天貌似懂了过几天又貌似忘记怎么回事了,还是没有理解透彻,因此痛下决心,一定要把这个事情弄懂。经过几天的反复思考查看资料,我自己理解的结果就是:mv用来调整相机位置组成一个新坐标系,p用来在这个坐标系里面切出一块来变成-1,1之间的立方体显示,w用来把这个-1,1的立方体转到指定的视口上。如果这个不够 阅读详情

在OpenGL中有两个比较重要的投影变换函数,glViewport和glOrtho。

glOrtho是创建一个正交平行的视景体。 一般用于物体不会因为离屏幕的远近而产生大小的变换的情况。比如,常用的工程中的制图等。需要比较精确的显示。 而作为它的对立情况, glFrustum则产生一个透视投影。这是一种模拟真是生活中,人们视野观测物体的真实情况。例如:观察两条平行的火车到,在过了很远之后,这两条铁轨是会相交于一处的。还有,离眼睛近的物体看起来大一些,远的物体看起来小一些。

glOrtho(left, right, bottom, top, near, far), left表示视景体左面的坐标,right表示右面的坐标,bottom表示下面的,top表示上面的。这个函数简单理解起来,就是一个物体摆在那里,你怎么去截取他。这里,我们先抛开glViewport函数不看。先单独理解glOrtho的功能。 假设有一个球体,半径为1,圆心在(0, 0, 0),那么,我们设定glOrtho(-1.5, 1.5, -1.5, 1.5, -10, 10);就表示用一个宽高都是3的框框把这个球体整个都装了进来。  如果设定glOrtho(0.0, 1.5, -1.5, 1.5, -10, 10);就表示用一个宽是1.5, 高是3的框框把整个球体的右面装进来;如果设定glOrtho(0.0, 1.5, 0.0, 1.5, -10, 10);就表示用一个宽和高都是1.5的框框把球体的右上角装了进来。上述三种情况可以见图:

glViewport()函数和glOrtho()函数的理解(转) - WAYNE - 闲逛 

glViewport()函数和glOrtho()函数的理解(转) - WAYNE - 闲逛 

glViewport()函数和glOrtho()函数的理解(转) - WAYNE - 闲逛 

从上述三种情况,我们可以大致了解glOrtho函数的用法。glOrtho函数只是负责使用什么样的视景体来截取图像,并不负责使用某种规则把图像呈现在屏幕上。

glViewport主要完成这样的功能。它负责把视景体截取的图像按照怎样的高和宽显示到屏幕上。

比如:如果我们使用glut库建立一个窗体:glutInitWindowSize(500, 500); 然后使用glutReshapeFunc(reshape); reshape代码如下:

void reshape(int width, int height)

{

    glViewport(0, 0, (GLsizei)width, (GLsizei)height);

    glMatrixModel(GL_PROJECTION);

    glLoadIdentity();

    glOrtho(-1.5, 1.5, -1.5, 1.5, -10, 10);

    ....

}

这样是可以看到一个正常的球体的。但是,如果我们创建窗体时glutInitWindowSize(800, 500),那么看到的图像就是变形的。上述情况见图。 

glViewport()函数和glOrtho()函数的理解(转) - WAYNE - 闲逛

 

因为我们是用一个正方形截面的视景体截取的图像,但是拉伸到屏幕上显示的时候,就变成了glViewport(0, 0, 800, 500);也就是显示屏变宽了, 倒是显示的时候把一个正方形的图像“活生生的给拉宽了”。就会产生变形。这样,就需要我们调整我们的OpenGL显示屏了。我们可以不用800那么宽,因为我们是用的正方形的视景体,所以虽然窗体是800宽,但是我们只用其中的500就够了。修改一下程序。

void reshape(int width, int height)

{

    int dis = width < height ? width : height;

    glViewport(0, 0, dis, dis);   /*这里dis应该是500*/

    glMatrixModel(GL_PROJECTION);

    glLoadIdentity();

    glOrtho(-1.5, 1.5, -1.5, 1.5, -10, 10);

    .....

}

glViewport()函数和glOrtho()函数的理解(转) - WAYNE - 闲逛

OK。如果你能看明白我写的内容。你可能对glViewport函数有个大致的了解。

不过,我们采用上面的办法,就是只使用了原来屏幕的一部分(宽度从501到800我们没有用来显示图像)。如果我们想用整个OpenGL屏幕显示图像,但是又不使图像变形怎么办?

那就只能修改glOrtho函数了。也就是说,我们使用一个和窗体一样比例的视景体(而不再是正方形的视景体)来截取图像。例如,对于(800, 500)的窗体,我们使用glOrtho(-1.5 * 800/500, 1.5 * 800/500, -1.5, 1.5, -10, 10),就是截取的时候,我们就使用一个“扁扁”的视景体截取,那么,显示的到OpenGL屏幕时(800, 500),我们只要正常把这个扁扁的截取图像显示(扁扁的截取图像是指整个截取的图像,包括球形四周的黑色部分。 球形还是正常圆形的),就可以了。如:

void reshape(int width , int height)

{

    glViewport(width, height); //按照窗体大小制作OpenGL屏幕

    glMatrixMode(GL_PROJECTION);

    glLoadIdentity();

    if (width <= height)

        glOrtho(-1.5, 1.5, -1.5 * (GLfloat)height/(GLfloat)width, 1.5 * (GLfloat)height/(GLfloat)width, -10.0, 10.0);

    else

        glOrtho(-1.5*(GLfloat)width/(GLfloat)height, 1.5*(GLfloat)w/(GLfloat)h, -1.5, 1.5, -10.0, 10.0);

    ....

}

glViewport()函数和glOrtho()函数的理解(转) - WAYNE - 闲逛

另外,关于glViewport()函数,我们还可以用来调整图像的分辨率。例如,保持目前的窗体大小不变,我们如果用这个size来只显示整个物体的一部分,那么图像的分辨率就必然会增大。例如:

void reshape(int w, int h)

{

    glViewport(0, 0, (GLsizei)w, (GLsizei)h);

    glMatrixMode(GL_PROJECTION);

    glLoadIdentity();

    if (w <= h)

        glOrtho(0, 1.5, 0, 1.5 * (GLfloat)h/(GLfloat)w, -10.0, 10.0);

    else

        glOrtho(0, 1.5*(GLfloat)w/(GLfloat)h, 0, 1.5, -10.0, 10.0);

}

可以把分辨率扩大4倍。

glViewport()函数和glOrtho()函数的理解(转) - WAYNE - 闲逛

而如果再修改一下glViewport(0, 0, 2 * (GLsizei)w, 2 * (GLsizei)h); 则可以把分辨率扩大16倍。

glViewport()函数和glOrtho()函数的理解(转) - WAYNE - 闲逛

完整的测试程序:

/*Build on ubuntu 9.04*/

#include <GL/gl.h>

#include <GL/glu.h>

#include <GL/glut.h>

void init(void)

{

    GLfloat mat_specular[] = {1.0, 1.0, 1.0, 1.0};

    GLfloat mat_shininess[] = {50.0};

    GLfloat light_position[] = {1.0, 1.0f, 1.0, 0.0};

    GLfloat white_light[] = {1.0, 1.0, 1.0, 1.0};

    GLfloat lmodel_ambient[] = {0.1, 0.1, 0.1, 1.0};

    glClearColor(0.0, 0.0, 0.0, 0.0);

    glShadeModel(GL_SMOOTH);

    glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);

    glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);

    glLightfv(GL_LIGHT0, GL_POSITION, light_position);

    glLightfv(GL_LIGHT0, GL_DIFFUSE, white_light);

    glLightfv(GL_LIGHT0, GL_SPECULAR, white_light);

    glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient);

    glEnable(GL_LIGHTING);

    glEnable(GL_LIGHT0);

    glEnable(GL_DEPTH_TEST);

   

}

void display(void)

{

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glutSolidSphere(1.0, 20, 16);

    glFlush();

}

void reshape(int w, int h)

{

    glViewport(0, 0, (GLsizei)w, (GLsizei)h);

    glMatrixMode(GL_PROJECTION);

    glLoadIdentity();

    if (w <= h)

        glOrtho(-1.5, 1.5, -1.5 * (GLfloat)h/(GLfloat)w, 1.5 * (GLfloat)h/(GLfloat)w, -10.0, 10.0);

    else

        glOrtho(-1.5*(GLfloat)w/(GLfloat)h, 1.5*(GLfloat)w/(GLfloat)h, -1.5, 1.5, -10.0, 10.0);

    glMatrixMode(GL_MODELVIEW);

    glLoadIdentity();

}

int main(int argc, char **argv)

{

    glutInit(&argc, argv);

    glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH);

    glutInitWindowSize(500, 500);

    glutInitWindowPosition(100, 100);

    glutCreateWindow(argv[0]);

    init();

    glutDisplayFunc(display);

    glutReshapeFunc(reshape);

    glutMainLoop();

    return 0;

}

/*CMakeLists.txt*/

PROJECT(s5)

CMAKE_MINIMUM_REQUIRED(VERSION 2.6)

ADD_EXECUTABLE(s5 main.cpp)

FIND_PACKAGE(OpenGL)

FIND_PACKAGE(GLUT)

IF(OPENGL_FOUND)

  INCLUDE_DIRECTORIES(${OPENGL_INCLUDE_DIR})

  TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${OPENGL_LIBRARIES})

ELSE(OPENGL_FOUND)

  MESSAGE(FATAL_ERROR "OpenGL not found")

ENDIF(OPENGL_FOUND)

IF(GLUT_FOUND)

  INCLUDE_DIRECTORIES(${GLUT_INCLUDE_DIR})

  TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${GLUT_LIBRARIES})

ELSE(GLUT_FOUND)

ENDIF(GLUT_FOUND)

【OpenGL实现04】glViewport - 玩家干预下改变视口和场景 游戏开发中,人机互动机制是必不可少的。输入装置要么操作杆、要么是键盘。视口改变是无论在3D还是2D都要出现的功能,比如,google地图就是一个显然的变视口问题,视口如同一个放大镜在地图上方移动,理论上可以看到地图上所有地方。本篇就模拟实现之。 阅读详情

相关推荐

glViewport()与glOrtho()函数的理解.doc

glViewport()与glOrtho()函数的理解glViewport()与glOrtho()函数的理解glViewport()与glOrtho()函数的理解glViewport()与glOrtho()函数的理解

OpenGL之glViewPort函数的用法

其函数原型为:glViewport(GLint x,GLint y,GLsizei width,GLsizei height)x,y 以像素为单位,指定了视口的左下角位置。width,height 表示这个视口矩形的宽度和高度,根据窗口的实时变化重绘窗口。在默认情况下,视口被设置为占据打开窗口的整个像素矩形,窗口大小和设置视口大小相同,所以为了选择一个更小的绘图区域,就可以用glViewport函...

草上爬的博客 4万+

xenomai内核解析--嵌入式实时linux概述

Linux系统作为一个GPOS(通用操作系统)发展至今已经非常成熟可靠了,并且由于遵循GPL协议,开放所有系统源代码,非常易于裁剪。更重要的是,与其他开源的GPOS或RTOS相比,Linux系统支持多种处理器、开发板,提供多种软件开发工具,同时Linux系统对网络和图形界面的支持非常出色。显然,选择Linux操作系统在产品的开发周期和成本控制方面都有巨大优势。 虽然Linux系统功能强大、实用性强...

wsg1100 3700

glViewport()函数和glOrtho()函数的理解(转)

在OpenGL中有两个比较重要的投影变换函数,glViewport和glOrtho。 glOrtho是创建一个正交平行的视景体。 一般用于物体不会因为离屏幕的远近而产生大小的变换的情况。比如,常用的工程中的制图等。需要比较精确的显示。 而作为它的对立情况, glFrustum则产生一个透视投影。这是一种模拟真是生活中,人们视野观测物体的真实情况。例如:观察两条平行的火车到,在过了很远之后,这两条

记录或不记录,博客就在这里 4109

想在瑞芯微RK3588上跑视频分类模型?避开3D卷积这个坑,试试这几种NPU友好的方案

本文探讨了在瑞芯微RK3588上部署视频分类模型时如何避开3D卷积的性能陷阱,提供了三种NPU友好的替代方案:MobileNetV2+GRU组合、Temporal Shift Module(TSM)和帧级池化。这些方案在保持较高准确率的同时,充分利用RKNPU的硬件加速能力,显著提升推理效率。文章还分享了从模型转换到部署优化的完整流程和实战经验。

weixin_28724319的博客 418

极速建站!用1Panel面板一键部署Halo博客的保姆级教程 | 企业官网/个人博客搭建教程

个人博客是一种在互联网上发布自己的文章、图片、视频等内容的平台,通常以文字为主要形式,但也可以包含其他媒体。个人博客的用途非常广泛。它可以用来记录博主的日常生活、分享自己的知识和经验、展示自己的作品和技能,以及交流自己的观点和看法。通过个人博客,博主可以与读者建立联系,分享自己的见解和体验,同时也可以从读者那里获得反馈和建议。

zeruns的博客 1832

glOrtho()函数和glViewport()函数的理解

glOrtho是创建一个正交平行的视景体。 一般用于物体不会因为离屏幕的远近而产生大小的变换的情况。比如,常用的工程中的制图等。需要比较精确的显示。 而作为它的对立情况, glFrustum则产生一个透视投影。这是一种模拟真是生活中,人们视野观测物体的真实情况。例如:观察两条平行的火车到,在过了很远之后,这两条铁轨是会相交于一处的。还有,离眼睛近的物体看起来大一些,远的物体看起来小一些。

成膜的博客 972

使用STM32制作智能窗帘控制

以上就是一个简单的基于STM32的智能窗帘控制代码案例。通过感知光线强度和控制步进电机的旋转,我们可以实现智能窗帘的自动开启和关闭。通过定时器的中断来控制步进电机的旋转,从而实现窗帘的开启和关闭动作。最后,我们需要实现主函数和中断函数。在主函数中,我们需要初始化硬件资源,然后进入一个无限循环来不断检测光敏电阻的值,并根据其值来控制窗帘的开启和关闭。接下来,我们需要编写功能函数,用于控制窗帘的开启和关闭。然后,我们需要配置STM32开发环境,并创建一个新的工程。接下来,我们初始化相关的硬件资源。

2401_85258012的博客 277

对glViewport()函数和glOrtho()函数的理解

最近学习OpenGL,搜集资料时 看到前辈们对glViewport()函数和glOrtho()函数的总结,觉得挺不错的,整理供大家分享学习 在OpenGL中有两个比较重要的投影变换函数,glViewport和glOrtho. glOrtho是创建一个正交平行的视景体。 一般用于物体不会因为离屏幕的远近而产生大小的变换的情况。比如,常用的工程中的制图等。需要比较精确的显示。 而作为它的对立情

fengkuangshixisheng的专栏 722

【光伏风电功率预测】基于 ICEEMDAN + MSCNN-BiGRU-Attention 的并行预测模型

本文提出一种基于ICEEMDAN分解与多尺度深度学习的光伏/风电功率并行预测框架。针对多能源、多时间尺度、强非平稳特性带来的建模挑战,该模型首先通过改进的ICEEMDAN算法将原始功率序列分解为不同频段的IMF分量;随后为每个IMF构建包含多尺度CNN、双向GRU和注意力机制的子模型,实现局部特征提取与时序依赖建模;最后通过并行预测与重构获得最终功率输出。实验表明,该方法能有效解决模式混叠问题,提升预测精度,并支持光伏/风电的独立或联合预测部署,适用于风光联合调度等工程场景。

专注AI大模型,软件混淆,授权 155

TIA博途中S7-1200进行MODBUS TCP通信(作为服务器)的具体方法演示

TIA博途中S7-1200进行MODBUS TCP通信(作为服务器)的具体方法演示

Robot_PLC_HMI_Automation 8614

OpenGl中的glViewport()函数和glOrtho()函数的理解

在OpenGL中有两个比较重要的投影变换函数,glViewport和glOrtho。 glOrtho是创建一个正交平行的视景体。 一般用于物体不会因为离屏幕的远近而产生大小的变换的情况。比如,常用的工程中的制图等。需要比较精确的显示。 而作为它的对立情况, glFrustum则产生一个透视投影。这是一种模拟真是生活中,人们视野观测物体的真实情况。例如:观察两条平行的火车到,在过了很远之后,这两条

1180

39、低功耗处理器性能评估与Cortex - M23/M33低功耗特性解析

本文深入解析了Cortex-M23和Cortex-M33处理器的低功耗特性及其性能评估方法。介绍了ULPMark、CoreMark、IoTMark-BLE和SecureMark-TLS等基准测试在能效评估中的应用,并详细阐述了处理器的睡眠模式、系统控制寄存器(SCR)配置、WFI/WFE指令、退出时睡眠、挂起时发送事件(SEVONPEND)以及唤醒中断控制器(WIC)等关键低功耗机制。结合状态保留技术,展示了如何通过芯片级设计大幅降低泄漏电流,实现高效能低功耗的物联网与嵌入式系统设计。

Pepper的专栏 130
上一篇: opencv2.2以上不支持CvvImage的解决办法
下一篇: 虚基类、虚函数以及纯虚函数
GeniusSnail
博客等级 码龄15年 8粉丝 10原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值