当前位置: 首页 > 知识库问答 >
问题:

如何计算glFrustum参数?

桓瀚
2023-03-14

我有这个代码:

/*
 * This is a simple program that computes FPS
 * by means of a circular buffer
 */
#include <GL/glut.h>
//#include <numeric>
#include <unistd.h>
#include <time.h>
#include <stdio.h>

// Number of elements in the circular buffer
#define NELS    10

// Number of lines
#define NLINES  10000

// circular buffer used to compute frame rate
float circularBuffer[NELS];
int firstInd = 0, nEls = 0;

// function to get the number of elapsed ticks
uint32_t getTick()
{
    struct timespec ts;
    unsigned theTick = 0U;
    clock_gettime( CLOCK_REALTIME, &ts );
    theTick  = ts.tv_nsec / 1000000;
    theTick += ts.tv_sec * 1000;
    return theTick;
}

// Function to compute real modulus and NOT remained as % does
inline int modulo(int a, int b) {
    const int result = a % b;
    return result >= 0 ? result : result + b;
}

// Compute sum of the elements in the circular buffer
float sumCircularBuffer()
{
    int ind;
    float sum = 0;

    if (nEls > 0) {
        for (ind=1; ind<=nEls; ind++) {
            sum = sum + circularBuffer[modulo(firstInd-ind, NELS)];
        }
    }

    return sum;
}

// accumulate buffer and update window title
void computeAndShowFrameRate(void)
{
    static float lastTime = 0.0f;
    static unsigned int frameCount = 0;
    char windowTitle[100];
    float sumFPS;

    float currentTime = (float)getTick() * 0.001f;
    // Initialize lastTime to the current time
    if (lastTime == 0) {
        lastTime = currentTime;
    }

    // increase frame count
    frameCount++;
    if (currentTime - lastTime > 1.0f) {
        // insert the current fps in the circular buffer
        circularBuffer[firstInd] = ((float)frameCount) / (currentTime - lastTime);

        // update variable lastTime
        lastTime = currentTime;

        //circularBuffer[firstInd] = (float)frameCount;
        firstInd = ((firstInd+1)%NELS);
        if (nEls < NELS) {
            nEls++;
        }
        frameCount = 0;

        // sum elements in circular buffer
        sumFPS = sumCircularBuffer();
        snprintf(windowTitle, 100, "FPS = %6.2f", sumFPS/nEls);
        // update window title
        glutSetWindowTitle(windowTitle);
    }
}

// display function
void display(void)
{
    int currLineInd;

    // get current frame rate
    computeAndShowFrameRate();

    // clear buffer
    glClear (GL_COLOR_BUFFER_BIT);

    for (currLineInd = 0; currLineInd<NLINES; currLineInd++) {
        // draw line
        glBegin(GL_LINES);
        // random color
        glColor3f((float)rand()/RAND_MAX, (float)rand()/RAND_MAX, (float)rand()/RAND_MAX);
        // random first point
        glVertex2f((float)rand()/RAND_MAX, (float)rand()/RAND_MAX);
        // random color
        glColor3f((float)rand()/RAND_MAX, (float)rand()/RAND_MAX, (float)rand()/RAND_MAX);
        // random second point
        glVertex2f((float)rand()/RAND_MAX, (float)rand()/RAND_MAX);
        glEnd();
    }

    glFinish();
    glutPostRedisplay();
}

// initialization function
void init (void)
{
    // Use current time as seed for random generator
    srand(time(0));

    // select clearing color
    glClearColor (0.0, 0.0, 0.0, 0.0);

    // Orthographic projection
    glOrtho(0.0, 1.0, 0.0, 1.0, -1.0, 1.0);
}

// Window size and mode
int main(int argc, char** argv)
{
    // pass potential input arguments to glutInit
    glutInit(&argc, argv);

    // set display mode
    // GLUT_SINGLE = single buffer window
    glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB);

    glutInitWindowSize (400, 400);
    glutInitWindowPosition (100, 100);
    glutCreateWindow ("OpenGL Window");

    // Call initialization routinesx
    init();
    glutDisplayFunc(display);
    glutMainLoop();
    return 0;
}

我必须用glFrustum替换glOrtho函数并得到相同的结果。

我阅读了khronos上的opengl指南,理解了glOrtho和glFrustum之间的区别,但我不知道如何计算参数。

如何计算传递给glFrustum函数的参数?

共有2个答案

施洛城
2023-03-14

将产生的值取决于您的实现和您正在使用的模型的规模。如上所述,如果投影的几何体在近平面的前面或远平面的后面,它将被剪掉,因此它将不可见。

要解决这个问题,您要么必须重新计算glfrustum()函数的参数(这是个坏主意),要么沿着z轴移动相机/场景。

参考资料:

  1. http://www.songho.ca/opengl/gl_transform.html
  2. https://learnopengl.com/gett-start/cordinate-systems
华建同
2023-03-14

在透视投影中,距离远近平面的距离必须大于0,

0 < near < far

因为您要定义一个查看截头体:

如果到近平面的距离小于0,则结果是未定义的(通常指令完全没有作用)。

请参阅glfrustum:

void glFrustum( GLdouble left,
    GLdouble right,
    GLdouble bottom,
    GLdouble top,
    GLdouble nearVal,
    GLdouble farVal);

距离,,是在近平面上从视图中心到截头体侧面的距离。nearfar指定到截头体的近平面和远平面的距离。

几何图形必须在近平面和远平面之间,否则就会被裁剪。因此,您必须沿z轴向负方向移动移位(在negativ方向,因为视图空间z轴指向视图之外):

// initialization function
void init (void)
{
    // [...]

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glFrustum(-0.1, 0.1, -0.1, 0.1, 0.1, 50.0);

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    glTranslatef(0.0f, 0.0f, -5.0f);
}
 类似资料:
  • 问题内容: 当我在实现接口的Eclipse中创建Java类时,收到警告 可序列化的类ABCD没有声明类型为long的静态最终serialVersionUID字段 因此,当我单击警告时,我在Eclipse中获得了一个选项 添加生成的序列号ID 选择该选项后,Eclipse会自动为我创建一个变量。 现在我想知道该数字是在什么基础上生成的。这是一个随机数吗?我可以提供自己的随机数吗? 问题答案: 它是根

  • 我正在使用千层面为MNIST数据集创建CNN。我将密切关注这个示例:卷积神经网络和Python特征提取。 我目前拥有的CNN架构(不包括任何退出层)是: 这将输出以下图层信息: 并输出可学习参数的数量为217,706 我想知道这个数字是如何计算的?我已经阅读了许多资源,包括这个StackOverflow的问题,但没有一个明确概括了计算。 如果可能,每层可学习参数的计算是否可以泛化? 例如,卷积层:

  • 我尝试使用曲线拟合来定义以下形式的函数: 我想计算参数Rth和tau的第一个四个值。目前,它的作品罚款如果我使用整个功能像这样: 但这肯定不是一个好方法,例如,如果我有一个包含4个以上指数项的很长的函数,我想得到所有的参数。如何调整它,使其在曲线拟合后返回特定数量的Rth和tau值? 例如,如果我想从一个8项指数函数中得到16个参数,我不需要写完整的8项,只需要写一个一般形式,它就会给出所需的输出

  • 我想知道如何计算的累计总和在AnyLogic中。具体地说,我有一个循环事件,每周改变一个参数的值。从这个参数我想计算它收到的值的累计总和,我怎么做呢? 该事件是循环模式的超时。操作是: "name_parameter"=圆形(max(正常(10,200),0));

  • 问题内容: 该方法在Java中返回什么值? 我读到它是一个对象的内存引用…的哈希值是1;的哈希值是97。 我很困惑:是ASCII还是什么类型的值? 问题答案: 哈希码是一个整数值,表示被调用的对象的状态。这就是为什么将设置为1的an 返回哈希码“ 1”的原因,因为哈希码及其值是相同的。字符的哈希码等于其ASCII字符码。如果编写自定义类型,则负责创建一个最佳实现,该实现将最能代表当前实例的状态。

  • 问题内容: 如果用户输入为2255,而我的输出应为10分钟,那么我如何计算24小时内的时差。我的想法是将输入分为2个部分,2位数字和2位数字。前2位数字是小时,将其乘以60使其变为分钟。然后再加上第二个2位数字,然后计算出差异。我不想使用任何日期日历数据类型或API来解决它。谢谢 问题答案: 如何在不使用String chartAt的情况下获取前两位数字。 最高两位数:数字/ 100最低两位数:数