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

Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.


Messages - Suslik

Pages: 1 [2] 3
16
Houston, we've got a problem.

So I'm writing a plugin for some random program and using SFML window to render some debug stuff. The plugin has a structure like this:

struct MySystem
{
  MySystem()
  {
    window = new sf::RenderWindow(...);
  }
  ~MySystem()
  {
    delete window;
  }
  void Update()
  {
    sf::Event event;
    while(window->pollEvent(event);
  }
  sf::RenderWindow *window;
};
MySystem *mySystem;
void DLL_API PluginInit()
{
  mySystem = new MySystem();
}
void DLL_API PluginUpdate()
{
  mySystem->Update();
}
void DLL_API PluginRelease()
{
  delete mySystem;
}
 

So far, so good. Now imagine there's a button "stop plugin" in the program I'm making the plugin for. The button apparently has an event function like this:
void ProgramImMakingPluginFor::OnPluginStopButtonPressed()
{
  PluginRelease();
}
 

What happens is this: the program crashes when I hit the "StopPlugin" button and crashed stack trace points to my line with while(window->pollEvent(event)); A couple of restless nights pointed out that what actually happens is this:

During my Update() when I call window->pollEvent(event) instead of processing messages addressed to my window it processes messages to non-sfml windows as well. sf::Window::pollEvent() calls sf::Window::popEvent() that calls WindowImplWin32::processEvents() that looks like this:
void WindowImplWin32::processEvents()
{
    // We process the window events only if we own it
    if (!m_callback)
    {
        MSG message;
        while (PeekMessageW(&message, NULL/*SIC*/, 0, 0, PM_REMOVE))
        {
            TranslateMessage(&message);
            DispatchMessageW(&message);
        }
    }
}
 
And during MySystem::Update() pollEvent() calls ProgramImMakingPluginFor::OnPluginStopButtonPressed() that calls PluginRelease() and destroys mySystem. Apparently bad things happen if inside mySystem->Update() you destroy instance of mySystem.

Two questions:
1) Shouldn't it have been
while (PeekMessageW(&message, m_handle, 0, 0, PM_REMOVE))
 
instead of
while (PeekMessageW(&message, NULL, 0, 0, PM_REMOVE))
 
?
2) Which options do I have for a workaround?

17
Window / Multiple windows, top one does not receive input
« on: October 30, 2014, 02:21:14 am »
Minimal code:
#include <SFML/Graphics.hpp>
int main()
{
        sf::RenderWindow largerWindow(sf::VideoMode(800, 600), "Larger window");
        sf::RenderWindow smallerWindow(sf::VideoMode(200, 100), "Smaller window");

        while (smallerWindow.isOpen() || largerWindow.isOpen())
        {
                sf::Event event;
                while (smallerWindow.pollEvent(event))
                {
                        if (event.type == sf::Event::Closed)
                        smallerWindow.close();
                }
                while (largerWindow.pollEvent(event))
                {
                        if (event.type == sf::Event::Closed)
                        largerWindow.close();
                }
        }
        return 0;
}

 
The code creates a larger window and a smaller one on top of it:


The smaller window does not receive mouse input: you cannot drag or close it while it's above larger window. When you move larger window away you can select it though and after that it works as intended. Problem occurs only after creating windows - smaller one looks on top of larger one but acts as if it was under it.

Tested on Windows 7.

18
  The problem is, there's sometimes too much possibilities. Sometimes I don't want to get all creative and go invent a bicycle, I just need a well-tested and a well-performing way of solving a commonly-encountered problem.

  Current situation reminds me of C++ - the language is very powerful, allows using very different coding styles and design patterns. However in practice contrary to what one may expect that often goes as disadvantage because C++ programs often end up being designed too differently and even though the only way of finding best practices is experience, every programmer ends up converging to different code design strategies. Java, C# and other languages often have weaker syntax but explicitly specified best practice code design patterns which ends up in better usability.

  As a bottom line while it's fun tinkering with all different ways of solving problems OpenGL provides sometimes I need a well-tested best practice solution similar to ones DirectX SDK has.

19
Yeah thanks for the explanation. So do I understand correctly how efficient rendering goes in 3.3?
Init: create a single VAO for all scene objects that have the same layout.
Render: render parts of this VAO with different offsets passing each object's model matrix to the shader.

Is this scheme correct? If so, I'll still have as many DIP's(in our case glDrawElements() calls) as scene objects. Can I somehow pass their model matrices and then render them all in 1 DIP?

I have also browsed through the links you gave above(I've read most of them while learning ogl 3.3) and all of them explain how to create vao's and vbo's which's not a problem really. But none of them explain how to use them effeciently in common bulk geometry rendering scenarios like a lot of objects with different textures and matrices. Do you have any links for that?

20
Am I right that the only benefit of VAO's is that you have only 1 ogl object bind per game object? So instead of setting separate buffers for vertices, normals and stuff you set up just 1 VAO? So the only benefit is reducing number of object bind calls?
It's kind of hard to explain, but simply put, it saves vertex attribute bindings as well as the element array binding.<...>
Umm. I don't see how that's any different from what I've said. Regardless, I'm definitely not after performance boost of saving 3 extra bindings per object atm. It's just a debug renderer and it has way more significant performance flaws(like I don't do any geometry frustum culling at all) yet it's nice to know how they actually do it right nowadays. Ty for the info/

21
10.5ms vs 14.2ms isn't significant? I don't like repeating what has been said many times before, but comparing FPS values doesn't make sense since it isn't linear. This is a 35% increase in performance and for me that is significant enough to warrant serious consideration.
30% fps increase is not that significant for a super-unoptimized renderer I had before. It's a very naive implementation of a debug renderer that I've written a few years ago and I expected way better performance boost after optimization. For example turning glHint (GL_LINE_SMOOTH_HINT, GL_NICEST); off increased performance about 2x times for me because OpenGL has really lame implementation of smoothed lines and I had a lot of them in the scene. I also used glBegin()/glEnd() back then and replacing them with client states had similar impact.

I don't know about you, but I have faith in the ARB only adding things that actually have functional value to the specification. It is "fancy" for a reason: It enables you to reduce the call and driver overhead of each frame, especially when drawing a large number of small batches. This has nothing to do with how vertex data is transferred. If you are unsure about what VAOs are and how to use them, you can read up about them more on the internet.
Am I right that the only benefit of VAO's is that you have only 1 ogl object bind per game object? So instead of setting separate buffers for vertices, normals and stuff you set up just 1 VAO? So the only benefit is reducing number of object bind calls?


If your application turns out to be bottlenecked by a high amount of glBufferSubDataARB() calls (remember, profile!), then you might want to consider introducing a buffer manager that batches updates into bigger chunks if you already store all of it in a single buffer. Often, it is "cheaper" to update buffer content once, even if you transfer more data than needed, than to update it many times each time transferring very little data. Driver overhead must never be underestimated.
My application is bottlenecked at physics simulation because, it's a physics simation program, duh. I was optimizing the debug renderer and making it more comfortable for use(swithed from my own old testbed to SFML). Also learning new tendencies in rendering code proved to be quite fun.

Huh? Yet another misconception... GLEW's sole purpose is to provide a cross-platform way to load extensions. If it were to only work on Windows, there would be no reason for people to use it. Indeed, there are even pre-built packages on every major Linux distribution of it. You can use GLEW, and SFML uses GLEW itself internally. However I would recommend against using SFML's copy of GLEW since it is going to be replaced soon. I currently use a custom generated loader using glLoadGen. It is much cleaner to use than GLEW and far more lightweight. Its documentation can be found here.
Well that's interesting. I always thought that W in GLEW stands for Windows. Pretty silly of me, then I think I'll just stick to it. Though header generation utility looks very interesting(boost has a similar one for stripping headers off).

22
Ok I did some testing. I used interleaved VBO vertices + indices in GL_STATIC_DRAW_ARB mode without passing any geometry to GPU every frame vs using fully client-based approach that dumps the whole geometry from RAM to GPU every frame without VBO. I have NVidia GF720 and results are as follows:
VBO: about 95fps
Client-based data: about 70fps

So there's a difference in favor of VBO but not super-significant. Scene consists of around 1000 meshes with 100-1000 polygons each. Using glBegin()/glEnd() is deprecated for a reason - drops fps about 10x.

I'm not sure I want to use VAO just because it's fancy and included in the new standard. Data is already relatively GPU-friendly and is not stored in RAM where possible(dynamically changing objects are still updated by glBufferSubDataARB()).

I'm currently using lame way of obtaining extensions like wglGetProcAddress("glGenBuffersARB"); There's also glew but it kinda kills cross-platformability of SFML because glew means windows. Is there a better way to use those extensions with SFML?

23
If you want performance while interleaving OpenGL and SFML rendering, you will have to resort to manually managing states as you are doing now. Client side arrays are deprecated anyway and if you are serious about OpenGL, you should probably look at the more modern way of rendering using server objects (Shader + VBO + VAO).
Even though client side arrays are deprecated in 3.0 they are performing better at my task than VBO's because I have a lot of small independent different objects whose geometry is changed every frame(they're soft bodies) and it looks like switching/updating/calling that many VBO's works slower than just passing these buffers every frame from client side arrays.

Even though I have used vbo's extensively before I have not yet tested a whole basic pipeline how it's supposed to work in OGL 3/4. Especially I'm interested in how to do so in SFML. Can you give me a basic example of OGL 3/4-way rendering geometry with SFML-based context? Also am I right that SFML itself uses deprecated features and is incompatible with 3.0 context so that I'll just have to use "modern" functions in "legacy" context?

24
Ok I got it. Cost me a night though. Looks like even though I did reset texture array just to be sure:
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
I have completely forgotten about other buffers that I never use. More specifically it's color buffer, resetting it as well solves the problem. Working code:
glPushClientAttrib(GL_CLIENT_ALL_ATTRIB_BITS);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisableClientState(GL_COLOR_ARRAY);
//initializing buffers I actually use
glDrawElements();
glPopClientAttrib();
window->draw(text);
window->display();
 
So the question is: Is there a better way than resetting all buffers manually? Unfortunately window->pushGlStates() and window->popGlStates(); seem to ignore client states altogether so they're irrelevant here. Any mechanisms that I'm supposed to use in this case?

25
Graphics / glDrawElements() + sf::Text = Access Violation in nvoglv32.dll
« on: October 28, 2014, 04:19:53 am »
Hey folks. Situation is as follows.
I render some debug text like this:
    sf::Text line0("Some text to render", debugInfoFont, 20);
    line0.setPosition(10.0f, 20.0f * 1);
    debugInfoWindow->draw(line0);
    //debugInfoWindow->resetGLStates(); //does not help
 
Then I render native opengl geometry like this:
      glEnableClientState (GL_VERTEX_ARRAY);
      glVertexPointer(3, GL_FLOAT, sizeof(Mesh::Vertex), &(vertices[0].pos.x));
      glEnableClientState(GL_NORMAL_ARRAY);
      glNormalPointer(GL_FLOAT, sizeof(Mesh::Vertex), &(vertices[0].norm.x));
      glDisableClientState(GL_TEXTURE_COORD_ARRAY); //just to ensure no texture coordinates are read
      glDrawElements(GL_TRIANGLES, faces.size() * 3, GL_UNSIGNED_INT, faces[0].incidentVertices);
 
And sometimes glDrawElements causes AV in nvoglv32.dll. Emphasis on "sometimes" because I was even unable to make a minimal code: even the large project I'm working on does not always crash. Sometimes it works just fine, sometimes it crashes on 2nd program loop iteration. Debug/Release do not affect behavior in any way. Program does not crash if I disable either text rendering or glDrawElements() calls. Looks like text rendering leaves some buffers unflushed and it breaks something later. I tried adding window->display() after rendering the text in hope that it'll flush the buffers but the program still crashes just the same way.

Also some debugging revealed that if I wrap my text rendering code into this:
glPushClientAttrib(GL_CLIENT_ALL_ATTRIB_BITS);
{
    sf::Text line2("howdy", debugInfoFont, 20);
    line2.setPosition(10.0f, 20.0f * 3);
    debugInfoWindow->draw(line2);
}
glPopClientAttrib();
 
the program no longer crashes but after rendering the 1st frame text disappears. Apparently it has something to do with SFML not resetting some of its buffers between calls, but how can that be helped?

Any suggestions?

26
In the initial post I've explained the problem that gl_TexCoord[0] gets messed if a textured geometry(with Pixel coordinate type) is rendered prior to shadered geometry that does not even use a texture or have texture assigned by a uniform. There are no OpenGL calls in the original post. Someone suggested that mixing OpenGL draw routines and SFML is a bad idea(even though there was no OpenGL code to start with):
The documentation for sf::Texture::bind() states:
Quote
This function is not part of the graphics API, it mustn't be used when drawing SFML entities. It must be used only if you mix sf::Texture with OpenGL code.
So I made another example that used only sf::Texture::bind() and native OpenGL code without SFML draw routines to demonstrate that the problem is not related to mixing SFML and OpenGL draw calls but solely to texture binding.

And now you're telling me I'm mixing OpenGL and SFML in a wrong way. Next time please do try reading the original post because actual problem is stated there. Every other example I posted was only for demonstrating others that the problem exists in different usage scenarios.

27
Quote
Then I have a question why this code is intended not to work?
Pixel coordinates are designed for internal use in sfml-graphics. It was never meant to be used with raw OpenGL, so we've never made it work for this use case. Everybody uses normalized coordinates with OpenGL, this is the intended (and only, without texture matrix hacks) way of handling texture coordinates, so I'd say, don't use pixel coordinates just because SFML provides this option.

Quote
Also why do window.push/popGlStates() or window.resetGlStates() not affect texture matrix so one has to use native gl functions to reset it?
sf::Texture::bind is just a convenience wrapper, it shouldn't be considered a sfml-graphics call, it acts as if you called glBindTexture yourself, and therefore anything that it changes is not affected by push/popGLStates.

The real issue here is:
1. understand how SFML and OpenGL are meant to be mixed (admittedly this is not always simple, this is an area that needs to be improved in the future)
2. do it right ;)
I think you're confusing raw OpenGL and GLSL safety measures. If the user resorts to calling native OpenGL function he indeed should have good reasons to do so and pay extra attention. Another area is using GLSL that's natively supported by SFML and that gets messed without making any raw OpenGL calls from C++ side. Latter can be hardly considered normal.

I suggest that we stop defending faulty design and find a decent solution how to avoid such troubles in future.

I understand that resetting texture matrix in sf::Texture::bind() may theoretically impact performance or cause unexpected behaviour for those who set texture matrix prior to this call. My proposal is rename sf::Texture::CoordinateType::Normalized to sf::Texture::CoordinateType::Current or ::NoChange and make it default. Actual normalized mode should be added as well, usage is as follows:
  //this call resets texture matrix to identity instead of what it does now
  sf::Texture::bind(&tex, sf::Texture::Normalized);
  //these calls are identical and they act as current sf::Texture::Normalized
  //it means they just bind the texture without affecting texture matrix
  sf::Texture::bind(&tex, sf::Texture::Current);
  sf::Texture::bind(&tex); //this call is identical to just calling glBindTexture() since it does not change texture matrix
  //this call acts exactly as current sf::Texture::Pixels
  sf::Texture::bind(&tex, sf::Texture::Pixels);
 

Additionally I propose resetting texture matrix whenever current texture is unbound, because sfml texture matrix is useful only for the texture it was built for and resetting it on unbind is what one would expect including your own team members:
When SFML unbinds any texture (yours or its own internally used ones), it will always reset the matrix back to identity.

<....>
You can simply bind the texture specifying normalized coordinates yourself before the draw and unbinding it after.

28
Ok. As far as I can understand this code not working is intended behavior:
  sf::Texture::bind(&randomTexture, sf::Texture::Pixels);
  //render something with non-normalized coordinates
  sf::Texture::bind(&randomTexture, sf::Texture::Normalized);
  //render something with normalized coordinates
 
Then I have a question why this code is intended not to work?

If this is due to optimization then using glBindTexture() usually takes way more time than glMatrixMode(GL_TEXTURE) + glLoadIdentity(); Also why do window.push/popGlStates() or window.resetGlStates() not affect texture matrix so one has to use native gl functions to reset it?

29
Seriously let me do your job. This is sf::Texture::bind() code from your repository:
void Texture::bind(const Texture* texture, CoordinateType coordinateType)
{
    ensureGlContext();

    if (texture && texture->m_texture)
    {
        // Bind the texture
        glCheck(glBindTexture(GL_TEXTURE_2D, texture->m_texture));

        // Check if we need to define a special texture matrix
        if ((coordinateType == Pixels) || texture->m_pixelsFlipped)
        {
            GLfloat matrix[16] = {1.f, 0.f, 0.f, 0.f,
                                  0.f, 1.f, 0.f, 0.f,
                                  0.f, 0.f, 1.f, 0.f,
                                  0.f, 0.f, 0.f, 1.f};

            // If non-normalized coordinates (= pixels) are requested, we need to
            // setup scale factors that convert the range [0 .. size] to [0 .. 1]
            if (coordinateType == Pixels)
            {
                matrix[0] = 1.f / texture->m_actualSize.x;
                matrix[5] = 1.f / texture->m_actualSize.y;
            }

            // If pixels are flipped we must invert the Y axis
            if (texture->m_pixelsFlipped)
            {
                matrix[5] = -matrix[5];
                matrix[13] = static_cast<float>(texture->m_size.y) / texture->m_actualSize.y;
            }

            // Load the matrix
            glCheck(glMatrixMode(GL_TEXTURE));
            glCheck(glLoadMatrixf(matrix));

            // Go back to model-view mode (sf::RenderTarget relies on it)
            glCheck(glMatrixMode(GL_MODELVIEW));
        }
    }
    else
    {
        // Bind no texture
        glCheck(glBindTexture(GL_TEXTURE_2D, 0));

        // Reset the texture matrix
        glCheck(glMatrixMode(GL_TEXTURE));
        glCheck(glLoadIdentity());

        // Go back to model-view mode (sf::RenderTarget relies on it)
        glCheck(glMatrixMode(GL_MODELVIEW));
    }
}
 
Now would you kindly notice that if (texture && texture->m_texture) is satisfied and if (coordinateType == Normalized), texture matrix remains as it was before the call instead of being reset?

30
I think you're missing the key point of binary's reply.  Though it's very possible I'm misunderstanding something myself, here's my attempt at a simpler explanation:

The documentation for sf::Texture::bind() states:
Quote
This function is not part of the graphics API, it mustn't be used when drawing SFML entities. It must be used only if you mix sf::Texture with OpenGL code.

This counts as "drawing SFML entities":
window.draw(vertices, 4, sf::Quads, &shader);

There are similar statements in the documentation for resetGLStates() and all the other functions that exist solely for interoperability with "raw" OpenGL.

As far as I know, none of those functions are meant to have any effect on the result of an SFML draw() call.
Ok let's pretend that it makes sense and I cannot mix SFML drawing call and GLSL. Following example uses sf::Texture::Bind() only in conjunction with native OpenGL - the way I'm supposed to use this:
void Render()
{
  glEnable(GL_TEXTURE_2D);

  sf::Texture::bind(&randomTexture, sf::Texture::Pixels);
  sf::Shader::bind(0);
  glBegin(GL_QUADS);
    glTexCoord2f(0.0, 0.0);
    glVertex2f(-1.0, -1.0);

    glTexCoord2f(randomTexture.getSize().x, 0.0);
    glVertex2f(1.0, -1.0);

    glTexCoord2f(randomTexture.getSize().x, randomTexture.getSize().y);
    glVertex2f(1.0, 1.0);

    glTexCoord2f(0, randomTexture.getSize().y);
    glVertex2f(-1.0, 1.0);
  glEnd();

  sf::Texture::bind(&randomTexture, sf::Texture::Normalized);
  sf::Shader::bind(&shader);
  glBegin(GL_QUADS);
    glTexCoord2f(0.0, 0.0);
    glVertex2f(-1.0, -1.0);

    glTexCoord2f(1.0, 0.0);
    glVertex2f(1.0, -1.0);

    glTexCoord2f(1.0, 1.0);
    glVertex2f(1.0, 1.0);

    glTexCoord2f(0, 1.0);
    glVertex2f(-1.0, 1.0);
  glEnd();
}
 
Result is identical: sf::Texture::bind(&randomTexture, sf::Texture::Pixels); messes up texture matrix and   sf::Texture::bind(&randomTexture, sf::Texture::Normalized); does not revert it back to identity which certainly is not what one would expect from the code.

Pages: 1 [2] 3
anything