簡體   English   中英

我如何計算 glFrustum 參數?

[英]how do i calculate glFrustum parameters?

我有這個代碼:

/*
 * 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 function 並獲得相同的結果。

我閱讀了有關 khronos 的 opengl 指南,並了解了 glOrtho 和 glFrustum 之間的區別,但我不知道如何計算參數。

如何計算要傳遞給 glFrustum function 的參數?

使用透視投影,到近平面和遠平面的距離必須大於 0,

0 < near < far

因為你想定義一個Viewing frustum

如果到近平面的距離小於 0,則結果未定義(通常該指令完全沒有效果)。

glFrustum

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

距離leftrightbottomtop是近平面上從視圖中心到截錐體側面的距離。 nearfar指定平截頭體的近平面和遠平面的距離。

幾何圖形必須位於近平面和遠平面之間,否則會被剪裁。 因此,您必須沿 z 軸向負方向移動移位(在負方向,因為視圖空間 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);
}

glFrustum()需要 6 個參數來指定 6 個剪切平面: leftrightbottomtopnearfar平面。 視覺表示將是這樣的: 在此處輸入圖像描述

將得出的值取決於您的實施和您正在使用的模型的規模。 如上所述,如果投影幾何體位於近平面之前或遠平面之后,它將被剪裁,因此不可見。

要解決這個問題,您要么必須重新計算glFrustum()函數的參數(壞主意),要么沿 z 軸移動相機/場景。

參考:

  1. http://www.songho.ca/opengl/gl_transform.html
  2. https://learnopengl.com/Getting-started/Coordinate-Systems

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM