获取glFrustum的坐标 [英] Getting coordinates for glFrustum

查看:142
本文介绍了获取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_horizo​​ntal(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_horizo​​ntal(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_horizo​​ntal 函数的(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_horizo​​ntal 函数,其中包含(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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆