SFML community forums
Help => Graphics => Topic started by: PhiLLe 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:
#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:
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?
-
Could somebody just try and compile? I would appreciate that.
-
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 :
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 :
#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;
}
-
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.
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:
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 :)
-
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.
-
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 :)