SFML community forums
Help => Graphics => Topic started by: tmac on July 08, 2008, 04:22:46 pm
-
Hello again
This is a question about PreserveOpenGLStates(true): In essence, I'm asking if using RenderWindow together with PreserveOpenGLStates is supposed to be equivalent to using the Window class, given that there is only OpenGL/GLU commands that do the drawing?
I have used SFML to draw a nice 3D snowman using only OpenGL and GLU commands. I can adjust the camera angle and resize the window without problems; the image reacts as expected.
Then I change to use RenderWindow instead (for the object called App), and also specify:
App.PreserveOpenGLStates(true);
But now the behaviour of my snowman is different when I resize the window. Now the snowman is no longer centered in the window after a resize. Is this expected or is it a bug?
Btw, as a side note, I noticed something quite strange going on with the event handling, it looked like mouse gestures had been enabled :-) As in the tutorial, I had lines like the following:
if((Event.Type == sf::Event::KeyPressed)&&(Event.Key.Code == sf::Key::Escape)) { App.Close(); }
I decided to try without the (Event.Type == sf::Event::KeyPressed) part, because I didn't understand it. It seemed to work, but now the different events I had specified like this were triggered when I moved the mouse around randomly. Maybe that's why the KeyPressed part is needed :-) ? I checked that the global mouse gestures in KDE were disabled.
Best regards,
Torquil Sørensen
-
For the second question, yes event matching is needed. Event is a big union, so Key.Code will only be relevant if the event is a keypressed one. Behavior is undefined if you check Event.Key.Code but the event is something else (as your Key.Code could be a mouse position, a window size, or anything).
-
But now the behaviour of my snowman is different when I resize the window. Now the snowman is no longer centered in the window after a resize. Is this expected or is it a bug?
Depends. Can you show the related code ?
decided to try without the (Event.Type == sf::Event::KeyPressed) part, because I didn't understand it
This should be the first thing to test when you receive an event, it is basically the type of event which happened. Hum, sorry, don't really know how to explain it better :)
Basically, you can't check which key has been pressed when what happened is a mouse move...
It's even more important as only the corresponding structure of the sf::Event union will be filled, ie. reading the Event.Key.Code on a mouse move event will produce completely unpredictable results.
-
Ok, I have stripped out everything that is unneeded, e.g. the snowman and the angular dependency of the camera position. Now the camera always looks at (0,0,0) from (0,0,5), with (0,1,0) being the up-vector needed by gluLookat(). What remains of the drawing is a wireframe box occupying the space [-1,1]x[-1,1]x[-1,1].
The problem is that the wireframe box is off-center after a window resize. The effect depends on which side or corner of the window that is resized. My point was that it works perfectly when not using RenderWindow + PreserveOpenGLStates(true).
Here is the code:
#include <SFML/Graphics.hpp>
#include <cmath>
using namespace std;
double l = 1.0;
double xmin = -l, xmax = l, ymin = -l, ymax = l, zmin = -l, zmax = l;
void setView(int w, int h)
{
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glViewport(0, 0, w, h);
gluPerspective(45, float(w)/h, 1, 1000);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(0.0, 0.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
}
GLint* mkDispList() {
GLint* dispList = new GLint;
*dispList = glGenLists(1);
glNewList(*dispList, GL_COMPILE);
glColor3f(1.0, 1.0, 1.0);
glBegin(GL_LINE_LOOP);
glVertex3f(xmin, ymin, zmin); glVertex3f(xmax, ymin, zmin);
glVertex3f(xmax, ymax, zmin); glVertex3f(xmin, ymax, zmin);
glEnd();
glBegin(GL_LINE_LOOP);
glVertex3f(xmin, ymin, zmax); glVertex3f(xmax, ymin, zmax);
glVertex3f(xmax, ymax, zmax); glVertex3f(xmin, ymax, zmax);
glEnd();
glBegin(GL_LINE_STRIP);
glVertex3f(xmax, ymax, zmin); glVertex3f(xmax, ymax, zmax);
glEnd();
glBegin(GL_LINE_STRIP);
glVertex3f(xmin, ymax, zmin); glVertex3f(xmin, ymax, zmax);
glEnd();
glBegin(GL_LINE_STRIP);
glVertex3f(xmin, ymin, zmin); glVertex3f(xmin, ymin, zmax);
glEnd();
glBegin(GL_LINE_STRIP);
glVertex3f(xmax, ymin, zmin); glVertex3f(xmax, ymin, zmax);
glEnd();
glEndList();
return(dispList);
}
int main()
{
sf::RenderWindow App(sf::VideoMode(640, 480, 32), "Snowman!");
App.PreserveOpenGLStates(true);
GLint* dispList = mkDispList();
glEnable(GL_DEPTH_TEST);
setView(640, 480);
while(App.IsOpened())
{
sf::Event Event;
while(App.GetEvent(Event)) {
if(Event.Type == sf::Event::Resized)
setView(Event.Size.Width, Event.Size.Height);
}
App.SetActive();
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
glCallList(*dispList);
App.Display();
}
return(0);
}
-
Could you first please enable the phpBB formatting elements, so that we can see your source code clearer ? :)
-
Sure, here goes my first attempt at this fancy BBcode thing :-)
#include <SFML/Graphics.hpp>
#include <cmath>
using namespace std;
double l = 1.0;
double xmin = -l, xmax = l, ymin = -l, ymax = l, zmin = -l, zmax = l;
void setView(int w, int h)
{
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glViewport(0, 0, w, h);
gluPerspective(45, float(w)/h, 1, 1000);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(0.0, 0.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
}
GLint* mkDispList() {
GLint* dispList = new GLint;
*dispList = glGenLists(1);
glNewList(*dispList, GL_COMPILE);
glColor3f(1.0, 1.0, 1.0);
glBegin(GL_LINE_LOOP);
glVertex3f(xmin, ymin, zmin); glVertex3f(xmax, ymin, zmin);
glVertex3f(xmax, ymax, zmin); glVertex3f(xmin, ymax, zmin);
glEnd();
glBegin(GL_LINE_LOOP);
glVertex3f(xmin, ymin, zmax); glVertex3f(xmax, ymin, zmax);
glVertex3f(xmax, ymax, zmax); glVertex3f(xmin, ymax, zmax);
glEnd();
glBegin(GL_LINE_STRIP);
glVertex3f(xmax, ymax, zmin); glVertex3f(xmax, ymax, zmax);
glEnd();
glBegin(GL_LINE_STRIP);
glVertex3f(xmin, ymax, zmin); glVertex3f(xmin, ymax, zmax);
glEnd();
glBegin(GL_LINE_STRIP);
glVertex3f(xmin, ymin, zmin); glVertex3f(xmin, ymin, zmax);
glEnd();
glBegin(GL_LINE_STRIP);
glVertex3f(xmax, ymin, zmin); glVertex3f(xmax, ymin, zmax);
glEnd();
glEndList();
return(dispList);
}
int main()
{
sf::RenderWindow App(sf::VideoMode(640, 480, 32), "Snowman!");
App.PreserveOpenGLStates(true);
GLint* dispList = mkDispList();
glEnable(GL_DEPTH_TEST);
setView(640, 480);
while(App.IsOpened())
{
sf::Event Event;
while(App.GetEvent(Event)) {
if(Event.Type == sf::Event::Resized)
setView(Event.Size.Width, Event.Size.Height);
}
App.SetActive();
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
glCallList(*dispList);
App.Display();
}
return(0);
}
-
Attempt no.2
#include <SFML/Graphics.hpp>
#include <cmath>
using namespace std;
double l = 1.0;
double xmin = -l, xmax = l, ymin = -l, ymax = l, zmin = -l, zmax = l;
void setView(int w, int h)
{
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glViewport(0, 0, w, h);
gluPerspective(45, float(w)/h, 1, 1000);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(0.0, 0.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
}
GLint* mkDispList() {
GLint* dispList = new GLint;
*dispList = glGenLists(1);
glNewList(*dispList, GL_COMPILE);
glColor3f(1.0, 1.0, 1.0);
glBegin(GL_LINE_LOOP);
glVertex3f(xmin, ymin, zmin); glVertex3f(xmax, ymin, zmin);
glVertex3f(xmax, ymax, zmin); glVertex3f(xmin, ymax, zmin);
glEnd();
glBegin(GL_LINE_LOOP);
glVertex3f(xmin, ymin, zmax); glVertex3f(xmax, ymin, zmax);
glVertex3f(xmax, ymax, zmax); glVertex3f(xmin, ymax, zmax);
glEnd();
glBegin(GL_LINE_STRIP);
glVertex3f(xmax, ymax, zmin); glVertex3f(xmax, ymax, zmax);
glEnd();
glBegin(GL_LINE_STRIP);
glVertex3f(xmin, ymax, zmin); glVertex3f(xmin, ymax, zmax);
glEnd();
glBegin(GL_LINE_STRIP);
glVertex3f(xmin, ymin, zmin); glVertex3f(xmin, ymin, zmax);
glEnd();
glBegin(GL_LINE_STRIP);
glVertex3f(xmax, ymin, zmin); glVertex3f(xmax, ymin, zmax);
glEnd();
glEndList();
return(dispList);
}
int main()
{
sf::RenderWindow App(sf::VideoMode(640, 480, 32), "Snowman!");
App.PreserveOpenGLStates(true);
GLint* dispList = mkDispList();
glEnable(GL_DEPTH_TEST);
setView(640, 480);
while(App.IsOpened())
{
sf::Event Event;
while(App.GetEvent(Event)) {
if(Event.Type == sf::Event::Resized)
setView(Event.Size.Width, Event.Size.Height);
}
App.SetActive();
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
glCallList(*dispList);
App.Display();
}
return(0);
}
-
Well now I noticed something strange. After a resize the image is no longer centred, but if I put the window behind another window temporarily, it is OK when I bring it back on top.