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

Author Topic: New render cache in combination with OpenGL  (Read 3091 times)

0 Members and 1 Guest are viewing this topic.

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6286
  • Thor Developer
    • View Profile
    • Bromeon
New render cache in combination with OpenGL
« on: December 31, 2011, 05:08:59 pm »
The revision with the new render cache introduced bugs at me: Some sprites and shapes aren't rendered at all, some seem to be shifted. When I comment code that uses OpenGL out, everything works fine. Other codes using OpenGL (Thor.Particles or the SFML sample) seem to work well so far...

Is there something more to consider than PushGlStates() and PopGlStates()? Might the render cache get into trouble when one is using separate OpenGL states?

This is part of a bigger project, so it would take some time to extract everything to a minimal example. Maybe you have some general tips, otherwise I'll try to find a reproducable example.
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
New render cache in combination with OpenGL
« Reply #1 on: December 31, 2011, 05:20:38 pm »
It should be ok.

I don't expect the first implementation of the states cache to be bug free, but it will be hard to find out what's wrong without a minimal code.

Maybe you're using an OpenGL state that SFML doesn't reset (it can't reset everything) and that messes up its rendering.
Laurent Gomila - SFML developer

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6286
  • Thor Developer
    • View Profile
    • Bromeon
New render cache in combination with OpenGL
« Reply #2 on: January 01, 2012, 06:19:38 pm »
Ok, it looks like I have had calls to glGenTextures(), glBindTexture(), glTexImage2D() and glTexParameteri() without surrounding Push/PopGLStates(). I.e. I forgot to save the texture states. This ancient Pre-Thor particle system in a project of mine, I hate it and need to replace it ASAP... :)

But also in Thor, I have stored too few attributes. Now I use
Code: [Select]
glPushAttrib(GL_COLOR_BUFFER_BIT | GL_TEXTURE_BIT | GL_TRANSFORM_BIT | GL_ENABLE_BIT);
But I'm not sure whether I store too few or too much. How can I find it out? I've looked up the DGL wiki, but the attributes are described only briefly. I could also store GL_ALL_ATTRIB_BITS, but that would probably be unnecessarily slow... I'm using these OpenGL functions:
Code: [Select]

glDisable(GL_DEPTH_TEST);
glEnable(GL_TEXTURE_2D);
glEnable(GL_BLEND);
...
mTexture->Bind(); // sf::Texture

... // Push projection, texture, modelview matrix

// Draw particles in modelview matrix
glLoadIdentity();
glTranslatef(...);
glRotatef(...);
glScalef(...);
glColor4ub(...);

glBegin(GL_TRIANGLE_STRIP);
...
glEnd();

And I could try to use sf::VertexArray in the future. But some OpenGL knowledge isn't bad either, since I'm not really experienced ;)
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
New render cache in combination with OpenGL
« Reply #3 on: January 01, 2012, 06:40:35 pm »
Quote
Ok, it looks like I have had calls to glGenTextures(), glBindTexture(), glTexImage2D() and glTexParameteri() without surrounding Push/PopGLStates().

Push/PopGlStates are supposed to surround SFML calls, not OpenGL ones.

Quote
But I'm not sure whether I store too few or too much. How can I find it out? I've looked up the DGL wiki, but the attributes are described only briefly. I could also store GL_ALL_ATTRIB_BITS, but that would probably be unnecessarily slow...

Hmm, why are you using PushGlStates if you call glPushAttrib yourself?

Could you show me how you use these functions? I have the feeling that you're doing something wrong :P
Laurent Gomila - SFML developer

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6286
  • Thor Developer
    • View Profile
    • Bromeon
New render cache in combination with OpenGL
« Reply #4 on: January 01, 2012, 07:58:30 pm »
Quote from: "Laurent"
Push/PopGlStates are supposed to surround SFML calls, not OpenGL ones.
I saw that in the OpenGL sample. I thought it wouldn't matter, main point is that the states of SFML and custom OpenGL are kept separate. And it seems to work, shouldn't it?

Otherwise, how could I hide these calls in Thor? I don't want the user to surround his own rendering calls with Push/PopGLStates(). I can't simply exchange them, since the first call would then be a Pop.


Quote from: "Laurent"
Hmm, why are you using PushGlStates if you call glPushAttrib yourself?
I am not. Sorry I explained it badly. In Thor, I directly use glPushAttrib() and glPopAttrib(). In an old project of mine, I used sf::RenderWindow::Push/PopGLStates().


Quote from: "Laurent"
Could you show me how you use these functions?
Sure:
Code: [Select]
void ParticleSystem::PushOpenGLStates(sf::RenderWindow& target) const
{
// Activate SFML window for OpenGL rendering
target.SetActive();

// Store attributes and assign them
glPushAttrib(GL_COLOR_BUFFER_BIT | GL_TEXTURE_BIT | GL_TRANSFORM_BIT | GL_ENABLE_BIT);
glDisable(GL_DEPTH_TEST);
glEnable(GL_TEXTURE_2D);
glEnable(GL_BLEND);

if (mGlow)
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
else
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

// Bind texture - instead of glBindTexture(GL_TEXTURE_2D, id)
mTexture->Bind();

// Push and initialize projection matrix (2D view)
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
detail::SetupOpenGL2DView(target.GetView());

// Push and initialize texture matrix
glMatrixMode(GL_TEXTURE);
glPushMatrix();
glLoadIdentity();

// Push modelview matrix
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
}

void ParticleSystem::PopOpenGLStates() const
{
// Restore modelview matrix
glMatrixMode(GL_MODELVIEW);
glPopMatrix();

// Restore texture matrix
glMatrixMode(GL_TEXTURE);
glPopMatrix();

// Restore projection matrix
glMatrixMode(GL_PROJECTION);
glPopMatrix();

// Restore attributes
glPopAttrib();
}

void ParticleSystem::DrawParticle(const Particle& particle) const
{
// Note: At the moment, the GL_MODELVIEW matrix is being edited

// Reset transforms
glLoadIdentity();

// Apply translation, rotation, scale
glTranslatef(particle.Position.x, particle.Position.y, 0.f);
glRotatef(particle.Rotation, 0.f, 0.f, 1.f);
glScalef(particle.Scale.x, particle.Scale.y, 1.f);

// Set color
glColor4ub(particle.Color.r, particle.Color.g, particle.Color.b, particle.Color.a);

// Draw vertices
glBegin(GL_TRIANGLE_STRIP);
glTexCoord2f(mTexCoordsEnd.x,   mTexCoordsEnd.y); glVertex2f(+mHalfSize.x, +mHalfSize.y);
glTexCoord2f(mTexCoordsBegin.x, mTexCoordsEnd.y); glVertex2f(-mHalfSize.x, +mHalfSize.y);
glTexCoord2f(mTexCoordsEnd.x,   mTexCoordsBegin.y); glVertex2f(+mHalfSize.x, -mHalfSize.y);
glTexCoord2f(mTexCoordsBegin.x, mTexCoordsBegin.y); glVertex2f(-mHalfSize.x, -mHalfSize.y);
glEnd();
}

void ParticleSystem::Draw(sf::RenderWindow& target) const
{
PushOpenGLStates(target);

THOR_CONST_FOREACH(ParticleContainer, mParticles, itr)
DrawParticle(*itr);

PopOpenGLStates();
}
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
New render cache in combination with OpenGL
« Reply #5 on: January 01, 2012, 08:22:52 pm »
Quote
I thought it wouldn't matter, main point is that the states of SFML and custom OpenGL are kept separate. And it seems to work, shouldn't it?

Nop. RenderTarget::PushGlStates() uses glPushAttrib like you do, but it also resets the constant states required by SFML (those that are set once at init, like disabling lighting).

So basically, if you find the right place for calling RenderTarget::ResetStates(), you should be able to solve your problem.
Laurent Gomila - SFML developer

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6286
  • Thor Developer
    • View Profile
    • Bromeon
New render cache in combination with OpenGL
« Reply #6 on: January 01, 2012, 08:38:21 pm »
Ok, thanks.

But if I use glPushAttrib() and glPopAttrib() like in the code above, is that enough? Generally, do you see some severe mistakes? ;)

If I understand correctly, ResetGLStates() is only needed if a new, uninitialized stack layer is opened with glPushAttrib() before SFML render calls. I thought that after rendering my particles with OpenGL, glPopAttrib() takes all relevant SFML attributes from the stack and restores them, so that SFML is ready for rendering again.
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
New render cache in combination with OpenGL
« Reply #7 on: January 01, 2012, 10:25:53 pm »
Quote
If I understand correctly, ResetGLStates() is only needed if a new, uninitialized stack layer is opened with glPushAttrib() before SFML render calls. I thought that after rendering my particles with OpenGL, glPopAttrib() takes all relevant SFML attributes from the stack and restores them, so that SFML is ready for rendering again.

Yes sorry, I already forgot that you were saving SFML's OpenGL states. In this case it's ok, but then it means that you must make sure that you restore your own OpenGL states after drawing an SFML object. Which is hard to do, because you don't know which OpenGL states SFML changed internally when you called Draw. But since it's SFML objects that are messed up, and not yours, I guess that this is not the problem here.

What happens if you use GL_ALL_ATTRIB_BITS? Does it solve the problem?
Laurent Gomila - SFML developer

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6286
  • Thor Developer
    • View Profile
    • Bromeon
New render cache in combination with OpenGL
« Reply #8 on: January 01, 2012, 10:35:03 pm »
Meanwhile, the problem seems to be solved, at least everything is rendered correctly. In Thor as well as in my other project.

Concerning Thor.Particles: Yes, GL_ALL_ATTRIB_BITS works, too. I didn't want to use it because it might be unnecessarily slow if it is called by multiple particle systems each frame.

Most attributes are reset every frame (see ParticleSystem::PushOpenGLStates() above): The 3 matrices, the texture, the blend function. I didn't reset lighting, fog etc. because SFML doesn't need it either. But I certainly forgot something else. ;)
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
New render cache in combination with OpenGL
« Reply #9 on: January 01, 2012, 10:54:44 pm »
Ok. So yes, you forgot something :)

Sorry that it took me so long to get into your problem, I was confused by the way you're managing OpenGL states.

But what do you mean by "the problem seems to be solved"? Did you do something? Because I didn't.
Laurent Gomila - SFML developer

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6286
  • Thor Developer
    • View Profile
    • Bromeon
New render cache in combination with OpenGL
« Reply #10 on: January 01, 2012, 11:02:50 pm »
Quote from: "Laurent"
Ok. So yes, you forgot something :)
Would you mind telling me what? :D

Quote from: "Laurent"
Sorry that it took me so long to get into your problem, I was confused by the way you're managing OpenGL states.
No problem. I was initially also confused: Because all these bugs only appeared after the render cache commit, I thought it might be connected and searched for bugs in the wrong place. But your render cache operates well so far :)

Quote from: "Laurent"
But what do you mean by "the problem seems to be solved"? Did you do something? Because I didn't.
Yes, I experimented a lot today. The code in my second post works (I just see I should have made that clearer, too; sorry again). I could leave it like this, but maybe I overlook something important... So do you directly see a mistake or an SFML attribute that I'm modifying and not saving?
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
New render cache in combination with OpenGL
« Reply #11 on: January 02, 2012, 08:15:10 am »
Ok, so if it works also without GL_ALL_ATTRIB_BITS, then it should be ok. Your code looks good.
Laurent Gomila - SFML developer

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6286
  • Thor Developer
    • View Profile
    • Bromeon
New render cache in combination with OpenGL
« Reply #12 on: January 02, 2012, 10:53:28 am »
Okay, thank you very much for your help! :)
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development: