Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: Crazy bug using OpenGL lighting and RenderWindow  (Read 3724 times)

0 Members and 1 Guest are viewing this topic.

PhiLLe

  • Newbie
  • *
  • Posts: 36
    • View Profile
Crazy bug using OpenGL lighting and RenderWindow
« on: May 12, 2011, 10:10:19 pm »
After I tried a lot to solve it I decided to show this to you guys.

I am pretty sure the code should be correct this way.
Sorry, but it can't be smaller:
Code: [Select]
#include <SFML/Graphics.hpp>
#include <SFML/OpenGL.hpp>

int main()
{
    sf::Clock clock;
    sf::RenderWindow App(sf::VideoMode(800, 600, 32), "SFML + OpenGL", sf::Style::Default, sf::ContextSettings(32));

    glEnable(GL_DEPTH_TEST);
    glDepthMask(GL_TRUE);
    glClearDepth(1.f);

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(70.f, App.GetWidth() / App.GetHeight(), 1.f, 600.f);

    glEnable(GL_LIGHTING);
    glEnable(GL_LIGHT0);

    GLfloat light_ambient[] = {0.0, 0.0, 0.0, 1.0};
    GLfloat light_diffuse[] = {1.0, 1.0, 1.0, 1.0};
    GLfloat light_specular[] = {1.0, 1.0, 1.0, 1.0};
    GLfloat light_position[] = {0.0, 0.0, 1.0, 0.0};

    glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient);
    glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);
    glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular);
    glLightfv(GL_LIGHT0, GL_POSITION, light_position);

    float red[] = {102.f/255.f, 51.f/255.f, 51.f/255.f};
    float blue[] = {51.f/255.f, 51.f/255.f, 102.f/255.f};
    float green[] = {51.f/255.f, 102.f/255.f, 51.f/255.f};


    while (App.IsOpened())
    {
        sf::Event Event;
        while (App.PollEvent(Event))
        {
            if (Event.Type == sf::Event::Closed)
                App.Close();

            if (Event.Type == sf::Event::Resized)
                glViewport(0, 0, Event.Size.Width, Event.Size.Height);
        }

        App.SaveGLStates();
        App.Clear(sf::Color(0, 0, 0, 1));
        App.RestoreGLStates();

        //glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        glClear(GL_DEPTH_BUFFER_BIT);

        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();
        glTranslatef(0.f, 0.f, -200.f);
        glRotatef(clock.GetElapsedTime() * 50, 1.f, 0.f, 0.f);
        glRotatef(clock.GetElapsedTime() * 30, 0.f, 1.f, 0.f);
        glRotatef(clock.GetElapsedTime() * 90, 0.f, 0.f, 1.f);

        // Draw a cube
        glBegin(GL_QUADS);

            glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, red);
            glColor3f(1.f, 0.f, 0.f);
            glNormal3f(0.f, 0.f, -1.f);
            glVertex3f(-50.f, -50.f, -50.f);
            glVertex3f(-50.f,  50.f, -50.f);
            glVertex3f( 50.f,  50.f, -50.f);
            glVertex3f( 50.f, -50.f, -50.f);

            glColor3f(1.f, 0.f, 0.f);
            glNormal3f(0.f, 0.f, 1.f);
            glVertex3f(-50.f, -50.f, 50.f);
            glVertex3f( 50.f,  -50.f, 50.f);
            glVertex3f( 50.f,  50.f, 50.f);
            glVertex3f(-50.f,  50.f, 50.f);

            glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, green);
            glColor3f(0.f, 1.f, 0.f);
            glNormal3f(-1.f, 0.f, 0.f);
            glVertex3f(-50.f, -50.f, -50.f);
            glVertex3f(-50.f,  50.f, -50.f);
            glVertex3f(-50.f,  50.f,  50.f);
            glVertex3f(-50.f, -50.f,  50.f);

            glColor3f(0.f, 1.f, 0.f);
            glNormal3f(1.f, 0.f, 0.f);
            glVertex3f(50.f, -50.f, -50.f);
            glVertex3f(50.f, -50.f,  50.f);
            glVertex3f(50.f,  50.f,  50.f);
            glVertex3f(50.f,  50.f, -50.f);

            glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, blue);
            glColor3f(0.f, 0.f, 1.f);
            glNormal3f(0.f, -1.f, 0.f);
            glVertex3f(-50.f, -50.f,  50.f);
            glVertex3f(-50.f, -50.f, -50.f);
            glVertex3f( 50.f, -50.f, -50.f);
            glVertex3f( 50.f, -50.f,  50.f);

            glColor3f(0.f, 1.f, 0.f);
            glNormal3f(0.f, 1.f, 0.f);
            glVertex3f(-50.f, 50.f,  50.f);
            glVertex3f(-50.f, 50.f, -50.f);
            glVertex3f( 50.f, 50.f, -50.f);
            glVertex3f( 50.f, 50.f,  50.f);

        glEnd();

        App.Display();
    }
    return EXIT_SUCCESS;
}


The bug is:
The two red quads don't show up.

This only happens when:
- you use lighting
- you use sf::RenderWindow instead of sf::Window (I wanted to display text, so I had to change to RenderWindow)

Crazy thing about it:
- When you change it to this the blue quads won't show up:
Code: [Select]
float blue[] = {51.f/255.f, 51.f/255.f, 102.f/255.f};
float red[] = {102.f/255.f, 51.f/255.f, 51.f/255.f};
float green[] = {51.f/255.f, 102.f/255.f, 51.f/255.f};


I am using SFML2 and CodeBlocks + MinGW.

Any ideas?

PhiLLe

  • Newbie
  • *
  • Posts: 36
    • View Profile
Crazy bug using OpenGL lighting and RenderWindow
« Reply #1 on: May 18, 2011, 06:03:46 pm »
Could somebody just try and compile? I would appreciate that.

Lokk

  • Full Member
  • ***
  • Posts: 228
    • View Profile
    • http://betadineproject.wordpress.com/
Crazy bug using OpenGL lighting and RenderWindow
« Reply #2 on: May 18, 2011, 08:48:31 pm »
SFML uses its own OpenGL statements, so you should include all your opengl calls within App.SaveGLStates(); and App.RestoreGLStates();

And, there is an error on your gluPerspective ratio, App.GetWidth() and App.GetHeight() need to be casted to float numbers like this :
Code: [Select]
gluPerspective(70.f, static_cast<float>(App.GetWidth()) / static_cast<float>(App.GetHeight()), 1.f, 600.f);

So here is a code which works for me :
Code: [Select]

#include <SFML/Graphics.hpp>
#include <SFML/OpenGL.hpp>

int main()
{
    sf::Clock clock;
    sf::RenderWindow App(sf::VideoMode(800, 600, 32), "SFML + OpenGL", sf::Style::Default, sf::ContextSettings(32));


    float red[] = {102.f/255.f, 51.f/255.f, 51.f/255.f};
    float blue[] = {51.f/255.f, 51.f/255.f, 102.f/255.f};
    float green[] = {51.f/255.f, 102.f/255.f, 51.f/255.f};

GLfloat light_ambient[] = {0.0, 0.0, 0.0, 1.0};
GLfloat light_diffuse[] = {1.0, 1.0, 1.0, 1.0};
GLfloat light_specular[] = {1.0, 1.0, 1.0, 1.0};
GLfloat light_position[] = {0.0, 0.0, 1.0, 0.0};

    while (App.IsOpened())
    {
        sf::Event Event;
        while (App.PollEvent(Event))
        {
            if (Event.Type == sf::Event::Closed)
                App.Close();

            if (Event.Type == sf::Event::Resized)
                glViewport(0, 0, Event.Size.Width, Event.Size.Height);
        }

App.Clear(sf::Color(0, 0, 0, 1));

        App.SaveGLStates();

glEnable(GL_DEPTH_TEST);
glDepthMask(GL_TRUE);
glClearDepth(1.f);

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(70.f, static_cast<float>(App.GetWidth()) / static_cast<float>(App.GetHeight()), 1.f, 600.f);

glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);

glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient);
glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);
glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular);
glLightfv(GL_LIGHT0, GL_POSITION, light_position);

        //glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        glClear(GL_DEPTH_BUFFER_BIT);

        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();
        glTranslatef(0.f, 0.f, -200.f);
        glRotatef(clock.GetElapsedTime() * 50, 1.f, 0.f, 0.f);
        glRotatef(clock.GetElapsedTime() * 30, 0.f, 1.f, 0.f);
        glRotatef(clock.GetElapsedTime() * 90, 0.f, 0.f, 1.f);

        // Draw a cube
        glBegin(GL_QUADS);

            glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, red);
            glColor3f(1.f, 0.f, 0.f);
            glNormal3f(0.f, 0.f, -1.f);
            glVertex3f(-50.f, -50.f, -50.f);
            glVertex3f(-50.f,  50.f, -50.f);
            glVertex3f( 50.f,  50.f, -50.f);
            glVertex3f( 50.f, -50.f, -50.f);

            glColor3f(1.f, 0.f, 0.f);
            glNormal3f(0.f, 0.f, 1.f);
            glVertex3f(-50.f, -50.f, 50.f);
            glVertex3f( 50.f,  -50.f, 50.f);
            glVertex3f( 50.f,  50.f, 50.f);
            glVertex3f(-50.f,  50.f, 50.f);

            glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, green);
            glColor3f(0.f, 1.f, 0.f);
            glNormal3f(-1.f, 0.f, 0.f);
            glVertex3f(-50.f, -50.f, -50.f);
            glVertex3f(-50.f,  50.f, -50.f);
            glVertex3f(-50.f,  50.f,  50.f);
            glVertex3f(-50.f, -50.f,  50.f);

            glColor3f(0.f, 1.f, 0.f);
            glNormal3f(1.f, 0.f, 0.f);
            glVertex3f(50.f, -50.f, -50.f);
            glVertex3f(50.f, -50.f,  50.f);
            glVertex3f(50.f,  50.f,  50.f);
            glVertex3f(50.f,  50.f, -50.f);

            glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, blue);
            glColor3f(0.f, 0.f, 1.f);
            glNormal3f(0.f, -1.f, 0.f);
            glVertex3f(-50.f, -50.f,  50.f);
            glVertex3f(-50.f, -50.f, -50.f);
            glVertex3f( 50.f, -50.f, -50.f);
            glVertex3f( 50.f, -50.f,  50.f);

            glColor3f(0.f, 1.f, 0.f);
            glNormal3f(0.f, 1.f, 0.f);
            glVertex3f(-50.f, 50.f,  50.f);
            glVertex3f(-50.f, 50.f, -50.f);
            glVertex3f( 50.f, 50.f, -50.f);
            glVertex3f( 50.f, 50.f,  50.f);

        glEnd();


        App.RestoreGLStates();
       
        App.Display();
    }
    return EXIT_SUCCESS;
}

PhiLLe

  • Newbie
  • *
  • Posts: 36
    • View Profile
Crazy bug using OpenGL lighting and RenderWindow
« Reply #3 on: May 19, 2011, 10:33:24 pm »
Quote from: "Lokk"
And, there is an error on your gluPerspective ratio, App.GetWidth() and App.GetHeight() need to be casted to float numbers like this :

Thanks, your right.

Quote from: "Lokk"
SFML uses its own OpenGL statements, so you should include all your opengl calls within App.SaveGLStates(); and App.RestoreGLStates();


As your code doesn't work for me I looked at the documentation and found this:
Quote
More specifically, it must be used around code that calls Draw functions. Example:

 // OpenGL code here...
 window.SaveGLStates();
 window.Draw(...);
 window.Draw(...);
 window.RestoreGLStates();
 // OpenGL code here...
http://www.sfml-dev.org/documentation/2.0/classsf_1_1RenderTarget.php#a17e9740485c9c72553971c1f75f96a16

I assume that window.Draw() is the only function that changes the GL states and I should put it around SFML code and not OpenGL code?! If thats true my code should work without SaveGLStates().

Another crazy thing:
- When I press "rebuild" and then "compile and build" (CodeBlocks+MinGW) it works the first time I execute (all 6 quads shown). Any other time it just shows 4 quads.

Now I get the feeling that it depends on my machine and that it is some kind of bug in my drivers. I will try on another machine and let you know :)

Lokk

  • Full Member
  • ***
  • Posts: 228
    • View Profile
    • http://betadineproject.wordpress.com/
Crazy bug using OpenGL lighting and RenderWindow
« Reply #4 on: May 20, 2011, 08:14:40 am »
Code: [Select]
so you should include all your opengl calls within App.SaveGLStates(); and App.RestoreGLStates();
Oh, my mistake !

You should also take a look at the OpenGL example, in  SFML sources.

PhiLLe

  • Newbie
  • *
  • Posts: 36
    • View Profile
Crazy bug using OpenGL lighting and RenderWindow
« Reply #5 on: May 20, 2011, 04:21:12 pm »
I did and there are only saves and restores around the two Draw() functions which I don't use at all. I tried and added lighting to the SFML2 example "OpenGL" and it works without any bugs. So I suppose the bad guy is the glMaterial function in this case because the example only uses textures. I will try to find out :)