在OpenGL中绘制一个相机对齐的圆
Posted
技术标签:
【中文标题】在OpenGL中绘制一个相机对齐的圆【英文标题】:Drawing a camera aligned circle in OpenGL 【发布时间】:2014-05-01 16:58:41 【问题描述】:我喜欢在 OpenGL 环境中使用 gluSphere() 绘制球体。但是,我希望我可以在球体周围画一个边框,边框是一个与相机框架完美对齐的圆,这样圆实际上总是一个圆,而不是从不同角度看的椭圆。我正在使用一个为我设置 OpenGL 环境并处理相机的框架。当我画画时,我总是在世界坐标中思考,所以我觉得完成这个任务很困难。我希望将解决方案嵌入到我最深层次的 OpenGL 绘图命令中,如下所示:
// Draws a sphere with a camera plane aligned border around it (you wish).
void GLLib::drawBorderedSphere(float radius)
static GLUquadric* quadric = gluNewQuadric();
gluSphere(quadric, radius, 32, 32);
// Determine a rotation matrix depending on the current camera configuration.
// glRotate(somehow);
// drawCircle(radius); <-- this I already have.
谁能帮忙?
【问题讨论】:
根据您想对球体做什么,您甚至可以使用更少的几何体将它们渲染为冒名顶替者:***.com/questions/10488086/…,然后在片段着色器中使用球体的边界画一个边框。 虽然 drawCircle(radius) 在许多情况下是球体轮廓的精细近似值,但请记住,它对于许多球体和投影并不完全正确。例如,透视投影引入了鱼眼效应,使得视图外围的球体非线性失真。甚至当观察一个球体时,视线与球体相切的一组点——轮廓——是一个圆,其世界空间中心比球体中心更近,其半径更小。视觉示例:dchelsea.com/wp/?p=4575 【参考方案1】:其实这个任务很简单。您知道球体的中心点和相机的位置。这为您提供了平面的法线向量,圆所在的位置。现在您只需要在该位置内找到两个基本向量(理想情况下彼此正交)即可形成圆的坐标基础。这也很简单:将任何不平行于相机的矢量转换为球矢量(例如相机“向上”矢量)并使用 Gram-Schmidt 正交化将其正交化到圆法线,称之为“切线矢量”。为了得到第二个圆平面基向量,称为“双切线”,计算圆平面法线和切线的叉积。作为最后一步,将切线和双切线缩放到单位长度。
即
-
N = 相机 - 圆心
T = 正交化(N,Camera_Up)
B = 交叉(N,T)
T' = T/len(T); B' = B/len(B)
然后用T'和B'就可以画圆了:
drawCircle(radius):
p = []
for i in 0 .. points:
a = i*2*pi / points
p.append( radius*(T*sin(a) + B*cos(a)) )
draw_line_loop(p)
【讨论】:
但是,我不知道相机在哪里。我在世界坐标中的 OpenGL 环境中,并开始在坐标 (0,0,0) 处绘图。如何使用 OpenGL 调用找出世界坐标中的相机矢量? @user3593481:嗯,OpenGL 中没有相机,只有坐标变换。当然,您可以通过某种方式访问模型视图矩阵,该矩阵将模型空间坐标转换为视图空间坐标,查看器位于原点。因此,通过将球体的中心点与当前的模型视图投影矩阵相乘,您可以得到 N 向量。对于“向上”,您可以选择任何您喜欢的向量,只要它与 N 不共线即可;例如从 N 开始用 U_i:=N_j 和 i 用 N 做一个 U 所以 N_i 是 N 和 j 的最小元素,所以 N_j 是 N 的最大元素。 如果使用透视投影,我认为它比您描述的要复杂一些。对应于球体轮廓的圆不再位于通过中心的平面上。仍然不是很困难,但您还必须考虑相机和球体中心之间的距离。 @RetoKoradi:是的,就透视而言,你是对的。但本质上,这归结为找到一个更正的圆心和半径,而其余的计算保持不变。以上是关于在OpenGL中绘制一个相机对齐的圆的主要内容,如果未能解决你的问题,请参考以下文章