获取glFrustum的坐标 [英] Getting coordinates for glFrustum
问题描述
我刚开始阅读 OpenGL
主题,特别是关于 查看
以满足我当前的需求。我试图理解 glFrustum
对于我在屏幕上绘制的对象的透视投影,因为我理解 glFrustum
会使更远的对象比更近的对象更小。
我使用 openFrameworks
这里用于绘制对象,例如 Image
/ Box
等等,这里是我想做的一个简单的例子:
draw()
{
glMatrixMode );
glLoadIdentity();
glFrustum(-1.0,1.0,-1.0,1.0,3.0,500.0);
glMatrixMode(GL_MODELVIEW);
sceneImage.draw(0,0,ofGetWidth(),ofGetHeight()); //在窗口的宽度和高度在屏幕上绘制图像
}
glFrustum,我只是试图剪辑图像,看到图像的特定部分进行初始测试。我不知道 glFrustum
的那些参数实际上是甚至当我阅读关于 glFrustum
从上面的红皮书链接。参数当然是 left,right,bottom,top,near,far
,但是如何 1.0
c $ c> 1.0 正在计算?我期待屏幕坐标进去,尝试像 glFrustum(100,984,100,668,3,500)
但没有出现在屏幕上。 glFrustum
的参数如何计算?
你的问题是,如果不是只是让我知道,但如果你问如何计算 glFrustum
参数这是如何:
它实际上是关于宽高比和fov。通常你会找到关于如何使用垂直fov的透视矩阵的信息,但有时你会想使用水平fov。所以,我想出了我的想法,我不使用 glFrustum
但我想你可以简单地切换我的透视
函数它仍然可以工作:
// ---------------- -------------------------------------------------- --------------
//设置透视截锥体(右手)
//(左,右,底,顶,近,远)
// ------------------------------------------- ---------------------------------
void透视图(float l,float r,float b,float t,float n,float f)
{
m_projection.identity();
m_projection [0] = 2.0f * n /(r-l);
m_projection [2] =(r + 1)/(r-1);
m_projection [5] = 2.0f * n /(t-b);
m_projection [6] =(t + b)/(t-b);
m_projection [10] = - (f + n)/(f-n);
m_projection [11] = - (2.0f * f * n)/(f-n)
m_projection [14] = -1.0f;
m_projection [15] = 0.0f;
update();
}
// ----------------------------------- ---------------------------------------------
/ /设置对称透视视锥体
//((垂直,度)视野,(宽/高)宽高比,近,远)
// ---------- -------------------------------------------------- --------------------
void perspective_vertical(float fov,float aspect,float front,float back)
{
fov = DEG_TO_RAD(fov); // transform fov from degrees to radians
float tangent = tanf(fov / 2.0f); //正切半垂直fov
float height = front * tangent; //近平面的半高
float width = height * aspect; //近平面的半宽
透视图(宽度,宽度,高度,高度,正面,背面);
}
// ----------------------------------- ---------------------------------------------
/ /设置对称透视视锥体
//((水平,度)视野,(宽/高)宽高比,近,远)
// ---------- -------------------------------------------------- --------------------
void perspective_horizontal(float fov,float aspect,float front,float back)
{
fov = DEG_TO_RAD(fov); // transform fov from degrees to radians
fov = 2.0f * atanf(tanf(fov * 0.5f)/ aspect); //从水平fov转换为垂直fov
float tangent = tanf(fov / 2.0f); //正切半垂直fov
float height = front * tangent; //近平面的半高
float width = height * aspect; //近平面的半宽
透视图(宽度,宽度,高度,高度,正面,背面);
}
和帮助宏:
#define PI_OVER_180 0.0174532925199432957692369076849f
#define 180_OVER_PI 57.2957795130823208767981548141f
#define DEG_TO_RAD(x)(x * PI_OVER_180)
#define RAD_TO_DEG(x)(x * 180_OVER_PI)
代码大部分已注释,不得不进一步解释。参数应该是:
perspective_horizontal(85.0f / * fov of 85 degrees * /, width / height,0.001f / * using near of 3.0f is kinda too much,just do not use 0.0f * /,1000.0f)
如果你想更深入地去看实际看到的数字,你可以把一些断点或 printf
它看看如何作品。相当于85度水平是大约45度垂直。此外,opengl使用列专业,所以如果你最终使用像这样的矩阵而不是 glFrustum
确保你先转置它。
EDIT(更多关于下面的评论):
让我们带一个标准hd -400像素:(1920-400)宽和(1080-400)高。标准高清的宽高比为1.77,但是像素版本为(1920-400)/(1080-400)= 2.23。 现在调用 perspective_horizontal
函数的(1920-400)/(1080-400)
,fov 85
并在透视(...)
调用之前放置断点将给我们以下变量:
- fov float 0.778087676
- aspect float 2.2352941
- 前浮动0.00100000005
- back float 100 back float 100
- tangent float 0.40993762
- height float 0.000409937638
- 0.000916331192
请注意,0.000916331192 / 0.000409937638 = 2.23529412052和0.778087676弧度到度= 44.5811399度垂直,相当于85度水平。
也可以调用 perspective_horizontal
函数,其中包含(1920-400)/ 1080-400)
,fov的 105
代替将给我们以下变量:
- fov float 1.05568409
- aspect float 2.2352941
- front float 0.00100000005
- back float 100 back float 100
- tangent float 0.583021879
- height float 0.000583021902
- width float 0.00130322541
再次注意,0.00130322541 / 0.000583021902 = 2.23529408677和1.05568409弧度到度= 60.4862429度垂直,相当于105度水平。 >
对于实际的透视矩阵,我不能解释你的公式是如何工作的,但只是想象在gpu有神奇的独角兽,如果你喂他们 gl_Position = projectionMatrix * viewMatrix * modelMatrix * vec4(inputPosition,1.0f);
他们会做一些奇妙的事情,它会在屏幕上显示漂亮的东西; 3。 >
glFrustum
也会解释此处,这里,此处,此处 a>,这里,最重要的是这里。
也是一个很好的解释此处。
I just started reading about OpenGL
topics, specifically about Viewing
for my current needs. I am trying to understand glFrustum
for a perspective projection of objects that I have drawn on the screen and as I understand glFrustum
would make the farther objects smaller than the nearer objects.
I am using openFrameworks
here for drawing objects such as Image
/Box
etc. and here's a short example of what I am trying to do:
openFrameworks draw method
draw()
{
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glFrustum(-1.0, 1.0, -1.0, 1.0, 3.0, 500.0);
glMatrixMode(GL_MODELVIEW);
sceneImage.draw(0,0,ofGetWidth(), ofGetHeight()); //draw an image on the screen with window's width and dheight
}
With the above glFrustum, I am just trying to to clip the image and see a particular portion of the image for an initial test. I am not sure about what those arguments of glFrustum
actually are even as I read about glFrustum
from above link of Red book. The arguments of course are left, right, bottom, top, near, far
, but how is 1.0
or 1.0
being calculated? I was expecting screen coordinates to go in there and tried something like glFrustum(100, 984, 100, 668,3, 500)
but nothing appeared on the screen. How are those arguments for glFrustum
calculated?
I hope I got your question right, if not just let me know, but if you're asking "how you should calculate the glFrustum
arguments" this is how:
Its actually all about the aspect ratio and the fov. Usually you're going to find information about how to make the perspective matrix using the vertical fov, but some times you'll want to use the horizontal fov. So heres what I came up with, I don't use glFrustum
but I think you can simply switch my perspective
function with it and it should still work:
//--------------------------------------------------------------------------------
// set a perspective frustum (right hand)
// (left, right, bottom, top, near, far)
//--------------------------------------------------------------------------------
void perspective(float l, float r, float b, float t, float n, float f)
{
m_projection.identity();
m_projection[0] = 2.0f * n / (r - l);
m_projection[2] = (r + l) / (r - l);
m_projection[5] = 2.0f * n / (t - b);
m_projection[6] = (t + b) / (t - b);
m_projection[10] = -(f + n) / (f - n);
m_projection[11] = -(2.0f * f * n) / (f - n);
m_projection[14] = -1.0f;
m_projection[15] = 0.0f;
update();
}
//--------------------------------------------------------------------------------
// set a symmetric perspective frustum
// ((vertical, degrees) field of view, (width/height) aspect ratio, near, far)
//--------------------------------------------------------------------------------
void perspective_vertical(float fov, float aspect, float front, float back)
{
fov = DEG_TO_RAD(fov); // transform fov from degrees to radians
float tangent = tanf(fov / 2.0f); // tangent of half vertical fov
float height = front * tangent; // half height of near plane
float width = height * aspect; // half width of near plane
perspective(-width, width, -height, height, front, back);
}
//--------------------------------------------------------------------------------
// set a symmetric perspective frustum
// ((horizontal, degrees) field of view, (width/height) aspect ratio, near, far)
//--------------------------------------------------------------------------------
void perspective_horizontal(float fov, float aspect, float front, float back)
{
fov = DEG_TO_RAD(fov); // transform fov from degrees to radians
fov = 2.0f * atanf(tanf(fov * 0.5f) / aspect); // transform from horizontal fov to vertical fov
float tangent = tanf(fov / 2.0f); // tangent of half vertical fov
float height = front * tangent; // half height of near plane
float width = height * aspect; // half width of near plane
perspective(-width, width, -height, height, front, back);
}
And the helping macros:
#define PI_OVER_180 0.0174532925199432957692369076849f
#define 180_OVER_PI 57.2957795130823208767981548141f
#define DEG_TO_RAD(x) (x * PI_OVER_180)
#define RAD_TO_DEG(x) (x * 180_OVER_PI)
The code is mostly commented and should make sense without having to further explain it. The parameters should be something along the lines of:
perspective_horizontal(85.0f /* fov of 85 degrees */, (float)width/height, 0.001f /* using near of 3.0f is kinda too much, just don't use 0.0f */, 1000.0f)
If you want to go more in depth and actually see the numbers working you can put some break points or printf
it to see how it works. The equivalent of 85 degrees horizontal is about 45 degrees vertical. Also, opengl uses column major, so if you end up using a matrix like this instead of glFrustum
make sure you transpose it first.
EDIT (more about the comment below):
Lets take a window that is standard hd -400 pixels: (1920-400) wide and (1080-400) tall. The aspect ratio of a standard hd is 1.77 but -400 pixels version is (1920-400)/(1080-400) = 2.23.
Now calling the perspective_horizontal
function with aspect ration of (1920-400)/(1080-400)
, fov of 85
and putting a breakpoint before the perspective(...)
call is going to give us the following variables:
- fov float 0.778087676
- aspect float 2.2352941
- front float 0.00100000005
- back float 100
- tangent float 0.40993762
- height float 0.000409937638
- width float 0.000916331192
take note that 0.000916331192/0.000409937638 = 2.23529412052 and 0.778087676 radians to degrees = 44.5811399 degrees vertical which is the equivalent of 85 degrees horizontal.
Also calling the perspective_horizontal
function with aspect ration of (1920-400)/(1080-400)
, fov of 105
instead is going to give us the following variables:
- fov float 1.05568409
- aspect float 2.2352941
- front float 0.00100000005
- back float 100
- tangent float 0.583021879
- height float 0.000583021902
- width float 0.00130322541
take note again that 0.00130322541/0.000583021902 = 2.23529408677 and 1.05568409 radians to degrees = 60.4862429 degrees vertical which is the equivalent of 105 degrees horizontal.
As for the actual perspective matrix, I can't explain you how the formula works, but just imagine that there are magical unicorns in the gpu and if you feed them gl_Position = projectionMatrix * viewMatrix * modelMatrix * vec4(inputPosition, 1.0f);
they're going to make some magic happen and its going to display beautiful things on the screen ;3.
glFrustum
is also explained here, here, here, here, here and most importantly here.
Also theres one good explanation here.
这篇关于获取glFrustum的坐标的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!