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

Author Topic: From Window to RenderWindow with OpenGL  (Read 4196 times)

0 Members and 1 Guest are viewing this topic.

tmac

  • Guest
From Window to RenderWindow with OpenGL
« 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

SirJulio

  • Full Member
  • ***
  • Posts: 241
    • View Profile
From Window to RenderWindow with OpenGL
« Reply #1 on: July 08, 2008, 04:35:28 pm »
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).

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
From Window to RenderWindow with OpenGL
« Reply #2 on: July 08, 2008, 04:39:05 pm »
Quote
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 ?

Quote
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.
Laurent Gomila - SFML developer

tmac

  • Guest
From Window to RenderWindow with OpenGL
« Reply #3 on: July 08, 2008, 04:53:21 pm »
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:

Code: [Select]
#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);
}

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
From Window to RenderWindow with OpenGL
« Reply #4 on: July 08, 2008, 05:04:24 pm »
Could you first please enable the phpBB formatting elements, so that we can see your source code clearer ? :)
Laurent Gomila - SFML developer

tmac

  • Guest
From Window to RenderWindow with OpenGL
« Reply #5 on: July 08, 2008, 05:06:59 pm »
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);
}

tmac

  • Guest
From Window to RenderWindow with OpenGL
« Reply #6 on: July 08, 2008, 05:10:06 pm »
Attempt no.2

Code: [Select]

#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);
}

tmac

  • Guest
From Window to RenderWindow with OpenGL
« Reply #7 on: July 08, 2008, 05:24:45 pm »
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.