SFML community forums

Help => Window => Topic started by: tntexplosivesltd on February 04, 2011, 08:33:19 am

Title: OpenGL Initialisation in Constructor
Post by: tntexplosivesltd on February 04, 2011, 08:33:19 am
At the moment I have a rendering class with a constructor, and a draw() method. The OpenGL initialisation is in the constructor, and the draw() method draws a cube. My main game loop creates a rendering constructor outside the loop, then inside the loop it calls draw() each frame. the problem is that all OpenGL initialisation is forgotten about when the game loop calls the draw() method. Using PreserveOpenGLStates doesn't work.

By the way, I am using SFML 1.6 :wink:
Title: OpenGL Initialisation in Constructor
Post by: Laurent on February 04, 2011, 08:45:25 am
Do you initialize your OpenGL states after the window is created?

Can you show a minimal/complete code that reproduces the problem?
Title: OpenGL Initialisation in Constructor
Post by: tntexplosivesltd on February 04, 2011, 11:01:47 am
Okay here we go. It's a bit big.
rendering.hpp:
Code: [Select]

class Rendering
{

  private:
    const float HALFSIZE;

  public:
    Rendering() : HALFSIZE(8)
    {
      // OpenGL initialisation
      // Light stuff
      GLfloat mat_specular[] = { 0.5, 0.5, 0.5, 0.0 };
      GLfloat mat_shininess[] = { 100.0 };
      GLfloat light_position[] = {0.f, 100.f, 100.f, 0.f};


      //glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
      //glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);
      glLightfv(GL_LIGHT0, GL_POSITION, light_position);
      glEnable(GL_LIGHTING);
      glEnable(GL_LIGHT0);

      glEnable(GL_DEPTH_TEST);
      //glShadeModel(GL_SMOOTH);
      //glClearDepth(1.f);
      glClearColor(0.f, 0.f, 0.3f, 0.f);
      glDepthMask(GL_TRUE);
      glDepthFunc(GL_LEQUAL);
    }

    void set_frustum(float width, float height, float z_far)
    {
      // switch to projection matrix
      glMatrixMode(GL_PROJECTION);
      glLoadIdentity();
      glFrustum(-1.f, 1.f, -(height / width), (height / width), 1.5f, z_far);
      glViewport(0.f, 0.f, width, height);
    }

    void adjust_viewport(float width, float height)
    {
      glViewport(0.f, 0.f, width, height);
    }
    void draw()
    {
      // change to model matrix
      glMatrixMode(GL_MODELVIEW);
      glLoadIdentity();

      glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        glMatrixMode(GL_MODELVIEW);
        // draw blocks
        glBegin(GL_QUADS);
          glTexCoord2f(0.f, 0.f); glVertex3f(-HALFSIZE, -HALFSIZE, -HALFSIZE);
          glTexCoord2f(0.f, 1.f); glVertex3f(-HALFSIZE,  HALFSIZE, -HALFSIZE);
          glTexCoord2f(1.f, 1.f); glVertex3f( HALFSIZE,  HALFSIZE, -HALFSIZE);
          glTexCoord2f(1.f, 0.f); glVertex3f( HALFSIZE, -HALFSIZE, -HALFSIZE);

          glTexCoord2f(0.f, 0.f); glVertex3f(-HALFSIZE, -HALFSIZE, HALFSIZE);
          glTexCoord2f(0.f, 1.f); glVertex3f(-HALFSIZE,  HALFSIZE, HALFSIZE);
          glTexCoord2f(1.f, 1.f); glVertex3f( HALFSIZE,  HALFSIZE, HALFSIZE);
          glTexCoord2f(1.f, 0.f); glVertex3f( HALFSIZE, -HALFSIZE, HALFSIZE);

          glTexCoord2f(0.f, 0.f); glVertex3f(-HALFSIZE, -HALFSIZE, -HALFSIZE);
          glTexCoord2f(0.f, 1.f); glVertex3f(-HALFSIZE,  HALFSIZE, -HALFSIZE);
          glTexCoord2f(1.f, 1.f); glVertex3f(-HALFSIZE,  HALFSIZE,  HALFSIZE);
          glTexCoord2f(1.f, 0.f); glVertex3f(-HALFSIZE, -HALFSIZE,  HALFSIZE);

          glTexCoord2f(0.f, 0.f); glVertex3f(HALFSIZE, -HALFSIZE, -HALFSIZE);
          glTexCoord2f(0.f, 1.f); glVertex3f(HALFSIZE,  HALFSIZE, -HALFSIZE);
          glTexCoord2f(1.f, 1.f); glVertex3f(HALFSIZE,  HALFSIZE,  HALFSIZE);
          glTexCoord2f(1.f, 0.f); glVertex3f(HALFSIZE, -HALFSIZE,  HALFSIZE);

          glTexCoord2f(0.f, 0.f); glVertex3f(-HALFSIZE, -HALFSIZE,  HALFSIZE);
          glTexCoord2f(0.f, 1.f); glVertex3f(-HALFSIZE, -HALFSIZE, -HALFSIZE);
          glTexCoord2f(1.f, 1.f); glVertex3f( HALFSIZE, -HALFSIZE, -HALFSIZE);
          glTexCoord2f(1.f, 0.f); glVertex3f( HALFSIZE, -HALFSIZE,  HALFSIZE);

          glTexCoord2f(0.f, 0.f); glVertex3f(-HALFSIZE, HALFSIZE,  HALFSIZE);
          glTexCoord2f(0.f, 1.f); glVertex3f(-HALFSIZE, HALFSIZE, -HALFSIZE);
          glTexCoord2f(1.f, 1.f); glVertex3f( HALFSIZE, HALFSIZE, -HALFSIZE);
          glTexCoord2f(1.f, 0.f); glVertex3f( HALFSIZE, HALFSIZE,  HALFSIZE);
        glEnd();
        glFlush();
      }
};


And interfacing.hpp - the "main loop"
Code: [Select]

class Interface
{
  private:
    // SFML variables
    sf::Event Event;
    sf::RenderWindow App;
    sf::VideoMode best_mode;

    Rendering main_rendering;

    // constants
    const float PI;

    // window size variables
    float best_width;
    float best_height;
    float centre_x;
    float centre_y;

  public:

    Interface() :best_mode(sf::VideoMode::GetMode(0)), main_rendering(),
    {

      sf::WindowSettings Settings;
      Settings.DepthBits         = 24;
      Settings.StencilBits       = 8;
      Settings.AntialiasingLevel = 0;

      best_width = best_mode.Width;
      best_height = best_mode.Height;
      centre_x = best_width / 2;
      centre_y = best_height / 2;

      App.Create(sf::VideoMode(best_width, best_height, 32), "sake interfacing test", sf::Style::Fullscreen, Settings);

      App.ShowMouseCursor(false);

      // performance tweaks
      //App.SetFramerateLimit(200);
      //App.UseVerticalSync(true);
      //App.PreserveOpenGLStates(true);

      main_rendering.set_frustum(best_width, best_height, 10000);
    }

    void start()
    {
      while (App.IsOpened())
      {

        while (App.GetEvent(Event))
        {
          // Close window - exit
          if (Event.Type == sf::Event::Closed)
          {
            App.Close();
          }

          // Resize event - adjust viewport
          if (Event.Type == sf::Event::Resized)
          {
            //main_rendering.adjust_viewport(Event.Size.Width, Event.Size.Height);
          }

          // Escape key - exit
          if ((Event.Type == sf::Event::KeyPressed) && (Event.Key.Code == sf::Key::Escape))
          {
            App.Close();
          }

          // F5 key -  save a screenshot with timestamp in working directory
          if ((Event.Type == sf::Event::KeyPressed) && (Event.Key.Code == sf::Key::F5))
          {
            char time_and_date[32];
            time_t time_ref = time(0);
            tm * screenshot_time;

            screenshot_time = localtime(&time_ref);
            strftime(time_and_date, 32, "%Y-%m-%d-%H%M%S.jpg", screenshot_time);
            sf::Image Screen = App.Capture();
            Screen.SaveToFile(time_and_date);
          }

        // Set the active window before using OpenGL commands
        // It's useless here because active window is always the same,
        // but don't forget it if you use multiple windows or controls
        App.SetActive();
        main_rendering.draw();
        App.Display();
      }
    }
};


And main.cpp:
Code: [Select]

#include "interface.hpp"
#include "rendering.hpp"

int main()
{
  Interface my_interface;
  my_interface.start();
}

I got rid of as much as I could, but some odd stuff might be there  :?
Title: OpenGL Initialisation in Constructor
Post by: Laurent on February 04, 2011, 11:23:52 am
You must do your initializations after the window is created, otherwise the states that you set are applied to a different OpenGL context.

So... maybe you should not put them in the constructor.
Title: OpenGL Initialisation in Constructor
Post by: tntexplosivesltd on February 04, 2011, 11:52:38 am
Yeah, that makes sense. Thanks!