gluPerspective的具体含义

该博客详细解释了OpenGL中的正射投影和透视投影,重点讨论了透视投影的gluPerspective函数,包括fovy、aspect、zNear和zFar参数的作用。通过示例代码展示了不同fovy值如何改变视野效果,并提供了多个模型的绘制,以说明投影原理。同时,提到了zNear和zFar的设置对观察范围的影响。

OpenGL有两种投影:正射投影(垂直投影)和透视投影。透视投影通过指定一个平截头体来定义视见体的范围,平截头体如下图所示:

void gluPerspective (GLdouble fovy, GLdouble aspect, GLdouble zNear, GLdouble zFar)

fovy是眼睛上下睁开的幅度,角度值,值越小,视野范围越狭小(眯眼),值越大,视野范围越宽阔(睁开铜铃般的大眼);

zNear表示近裁剪面到眼睛的距离,zFar表示远裁剪面到眼睛的距离,注意zNear和zFar不能设置设置为负值(你怎么看到眼睛后面的东西)。

aspect表示裁剪面的宽w高h比,这个影响到视野的截面有多大。

下图中又三个模型,这时我们想要看到全部三个模型,绘制方法见代码:

void display(void) {
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);			// 清除屏幕及深度缓存
	glLoadIdentity();							// 重置当前的模型观察矩阵
    //glutSolidSphere(1.0, 400, 16);  //繪製一個球體
	/*当您调用glLoadIdentity()之后,您实际上将当前点移到了屏幕中心,X坐标轴从左至右,Y坐标轴从下至上,Z坐标轴从里至外。OpenGL屏幕中心的坐标值是X和Y轴上的0.0f点。中心左面的坐标值是负值,右面是正值。移向屏幕顶端是正值,移向屏幕底端是负值。移入屏幕深处是负值,移出屏幕则是正值。
     glTranslatef(x, y, z)沿着 X, Y 和 Z 轴移动。根据前面的次序,下面的代码沿着X轴左移1.5个单位,Y轴不动(0.0f),最后移入屏幕6.0f个单位。注意在glTranslatef(x, y, z)中当您移动的时候,您并不是相对屏幕中心移动,而是相对与当
`glPolygonOffset` 函数用于在不修改图元实际顶点的 Z 坐标的情况下,对片段的深度值进行调整,其函数原型如下: ```c void glPolygonOffset(GLfloat factor, GLfloat units); ``` 该函数包含两个参数,具体含义如下: - `factor`:一个浮点值,它与多边形的深度斜率(即多边形表面相对于观察方向的倾斜程度)相乘。深度斜率越大,`factor` 对深度偏移的影响就越大。例如,当多边形表面与观察方向垂直时,深度斜率为 0;当多边形表面与观察方向平行时,深度斜率达到最大值。 - `units`:也是一个浮点值,它与一个可实现的最小深度缓冲区值相乘。这个最小深度缓冲区值是由 OpenGL 实现定义的,通常与深度缓冲区的精度有关。`units` 直接影响深度偏移的大小,不考虑多边形的斜率。 在实际应用中,需要根据不同的场景来调整这两个参数,以下是一些常见场景及参数调整方法: - **避免 Z 冲突(Z-fighting)**:Z 冲突是指两个或多个图元在深度缓冲区中的深度值非常接近,导致它们在屏幕上交替显示,产生闪烁现象。为了解决这个问题,可以使用 `glPolygonOffset` 对其中一个图元的深度值进行偏移。一般可以将 `factor` 和 `units` 都设置为较小的正值,如 `glPolygonOffset(1.0, 1.0)`。这样可以确保第二个绘制的图元在深度上稍微落后于第一个图元,从而避免 Z 冲突。 ```python import pygame from pygame.locals import * from OpenGL.GL import * from OpenGL.GLU import * # 初始化 Pygame pygame.init() display = (800, 600) pygame.display.set_mode(display, DOUBLEBUF | OPENGL) # 设置 OpenGL 视角 gluPerspective(45, (display[0] / display[1]), 0.1, 50.0) glTranslatef(0.0, 0.0, -5) while True: for event in pygame.event.get(): if event.type == pygame.QUIT: pygame.quit() quit() # 第一次绘制 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) glBegin(GL_QUADS) glVertex3f(-1.0, -1.0, 0.0) glVertex3f(1.0, -1.0, 0.0) glVertex3f(1.0, 1.0, 0.0) glVertex3f(-1.0, 1.0, 0.0) glEnd() # 启用深度偏移 glEnable(GL_POLYGON_OFFSET_FILL) glPolygonOffset(1.0, 1.0) # 第二次绘制 glBegin(GL_QUADS) glVertex3f(-0.5, -0.5, 0.0) glVertex3f(0.5, -0.5, 0.0) glVertex3f(0.5, 0.5, 0.0) glVertex3f(-0.5, 0.5, 0.0) glEnd() # 禁用深度偏移 glDisable(GL_POLYGON_OFFSET_FILL) pygame.display.flip() pygame.time.wait(10) ``` - **绘制阴影**:在绘制阴影时,阴影通常会与地面或其他物体表面重叠,可能会出现 Z 冲突。为了避免这种情况,可以对阴影的深度值进行偏移。一般将 `factor` 设置为较小的正值,`units` 设置为一个适当的正值,以确保阴影在深度上稍微落后于物体表面。例如 `glPolygonOffset(0.5, 3.0)`。 ```python # 绘制物体 # ... # 启用深度偏移 glEnable(GL_POLYGON_OFFSET_FILL) glPolygonOffset(0.5, 3.0) # 绘制阴影 # ... # 禁用深度偏移 glDisable(GL_POLYGON_OFFSET_FILL) ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值