3

While attempting to render a 3D object using OpenGL (and the GLFW library), the model experiences lots of flickering. Im reading the .obj file using a library that I've written on my own.

Written below is my render function: Unfortunately, in order to understand how faces and vertices are being inputted, I will have to provide all my code, which is linked: Zipped code along with executable and sample .obj: Source

Im using .obj files from here to test the program. Right now, the program doesn't support normals and textures, which isnt an issue since most of the models on the site dont have them. Also, (right now) it only reads from "123.obj" so the file should'nt be named anything else. And it only accepts a single space, not more than that.

 float render()
    {
        glfwSetTime(0.0f);
        int win_width;
        int win_height;
        glfwGetWindowSize(&win_width, &win_height);
        float win_aspect = (float)win_width / (float)win_height;
        glViewport(0, 0, win_width, win_height);

        glMatrixMode(GL_PROJECTION);
        glLoadIdentity();
        gluPerspective(90, win_aspect, 0, 100.0);

        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();
        gluLookAt(0, 0, 50.0, 0, 0, 0, 0.0, 1.0, 0.0);

        glEnable(GL_DEPTH);
        glEnable(GL_DEPTH_TEST);
        glEnable(GL_COLOR_MATERIAL);
        glEnable(GL_NORMALIZE); 
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

        glRotatef(angle , 0 , 1, 0);
        glColor3f(0.0f, 0.0f, 0.0f);
        int index = 0;
        for(int a = 0; a < faces.size(); a++)
        {
            if(faces[a].vertices.size() == 3)
            {
                glBegin(GL_TRIANGLES);
            }
            else
            {
                glBegin(GL_QUADS);
            }
            for(int b = 0; b < faces[a].vertices.size(); b++)
            {
                index = faces[a].vertices[b];
                glVertex3f(vertices[index].Dimensions[_x], vertices[index].Dimensions[_y], vertices[index].Dimensions[_z]);
            }
            glEnd();
        }
        glfwSwapBuffers();
        return (float)glfwGetTime();
BЈовић
  • 62,405
  • 41
  • 173
  • 273
viraj
  • 1,784
  • 4
  • 35
  • 52
  • I was thinking the same thing. I think that glfwSwapBuffers() does the double buffering? – NeilMonday Oct 20 '11 at 18:41
  • 1
    Flickering sounds like an issue with double buffering. You use glfwSwapBuffers(), but are you sure the context you're drawing to has double buffering enabled? – bames53 Oct 20 '11 at 18:41
  • Maybe driver issues? Have you tried updating drivers? – BЈовић Oct 20 '11 at 18:43
  • Drivers are up to date. And glfw always has double buffered windows. – viraj Oct 20 '11 at 18:47
  • Just a thought. What about fps limit. If its not limited, then probably you are rendering > 1000fps. which causes a lot of flickering/jerking and so on. It's better to make constant frame rendering like 60fps. – legion Oct 20 '11 at 18:48
  • Download the source with the exe to see what sort of flickering. – viraj Oct 20 '11 at 18:48
  • @NeilMonday: SwapBuffers just swaps them. But a double buffer must be explicitly requested. Without a doublebuffer SwapBuffers turns into glFinish(); – datenwolf Oct 20 '11 at 18:50

1 Answers1

7

Here's the problem

gluPerspective(90, win_aspect, 0, 100.0);

You cannot set 0 as your nearclip, set it to something larger like 0.1, or 1.0.

gluPerspective(90, win_aspect, 1.0, 100.0);

With nearclip at 0, all of your depths get mapped to z = 1, and you get z fighting.

EDIT : if you're interested, here's some theory on perspective depth:

For a given distance from the camera x, your perspective transform outputs a certian depth value z. At the farclip, this value will be the maximum of 1, and at nearclip it will be 0. Between these values however, relationship is not linear like you may expect. The curve looks similar to the following diagrams:

Diagram

When you go to the extreme of setting your nearclip to 0, your curve is heavily warped, so now all distances map to z = 1.

Because of all this, you should also try to keep the ratio far:near smaller than 10000:1

Hannesh
  • 7,256
  • 7
  • 46
  • 80
  • 1
    Another (small) question that I have is: if I want to rotate or translate only this particular model, does that mean that I have to iterate through each vertex and increment it, or is there an easier way? – viraj Oct 21 '11 at 03:33
  • 2
    Yes, there is a much easier way. Before your loop, add a **glPushMatrix();**, just after that do all of your rotations and translations (glTranslate(...), glRotate(...)). When you've finished drawing that model, write **glPopMatrix();**. That reverts it all to how it was before glPushMatrix. – Hannesh Oct 21 '11 at 11:51
  • Also, how do you rotate an object about it's own axis ? i've tried, but nothing works :|. I tried to translate to it's centre and then make it rotate around the x axis, but that still makes the object move in a radius around that point, while i just want it to spin. – viraj Oct 21 '11 at 18:45
  • Diagram link no longer works. :( This answer though solved an issue I've been having for months. – Matt Sep 12 '17 at 02:05