3

I have this code:

/*
 * 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;
}

I have to replace the glOrtho function with glFrustum and get the same result.

I read the opengl guide on khronos and understood the differences between glOrtho and glFrustum but i can't figure out how to calculate the parameters.

How do I calculate the parameters to pass to the glFrustum function?

Lore99
  • 31
  • 1
  • 1
    I think most people don't, they use gluPerspective. – user253751 Mar 19 '21 at 15:36
  • @user253751 No, nobody uses `gluPerspecctive` or `glFrustum` these days, because the fixed-function pipeline has been out of date for decades. – Rabbid76 Mar 20 '21 at 07:16
  • @Rabbid76 well yeah, but when they *are* using the fixed-function pipeline, they use gluPerspective. Or glm::perspective for those of us not using that. – user253751 Mar 20 '21 at 13:05
  • @user253751 You're right. For a symmetrical projection the more common way is `glm::perspective`. – Rabbid76 Mar 20 '21 at 13:37

2 Answers2

2

glFrustum() require 6 parameters to specify 6 clipping planes: left, right, bottom, top, near and far planes. A visual representation would be like this: enter image description here

The values that will come up with depend on your implementation and the scale of the models you are working with. As mentioned above, if the projected geometry is in front of the near plane or behind the far plane it will be clipped thus it won't be visible.

To solve this you either have to recompute the parameters for the glFrustum() function(bad idea) or move the camera/scene along the z-axis.

References:

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

With Perspective projection the distnace to the near and far plane have to be grater than 0,

0 < near < far

because you want to define a Viewing frustum:

If the distance to the near plane is less than 0, the result is undefined (Usually the instruction has no effect at all).

See glFrustum:

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

The distances left, right, bottom and top, are the distances from the center of the view to the side faces of the frustum, on the near plane. near and far specify the distances to the near and far plane of the frustum.

The geometry has to be between the near and the far plane, else it is clipped. Therefore, you have to move the shift along the z-axis in the negative direction (in negativ direction, because the view space z-axis points out of the view):

// 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);
}
Rabbid76
  • 202,892
  • 27
  • 131
  • 174