glAddSwapHintRectWIN

Started by
5 comments, last by lawnjelly 7 years, 7 months ago

Hi, I've been having some problems with this opengl extension, but only on some machines. I'm no great expert at using extensions, but I get a list of extensions with glGetString and find whether 'GL_WIN_swap_hint' is in the list. Then I use wglGetProcAddress to get the address of glAddSwapHintRectWin.

So far so good. As I understand it, if not supported, it should not be in the list or return NULL for the the address.

The problem I'm finding is that on some PCs it is acting correctly and only swapping the requested rect, but on others that say they support it, the command appears to be ignored? Perhaps I'm misunderstanding and they are allowed to totally ignore it, as it is just a 'hint'. But to me that negates half the use of the thing.

Basically I have a GUI and various other things being rendered to the screen. On most frames, I don't need to render the whole screen, just a small part of it. So I want to just render that part, and then call swapbuffers and only have that region swapped. My question would be, if a driver can't do the thing, and swap only part of the buffers, why doesn't it just return that it can't do it?

I now have a situation where I will have to make the default build run a rubbishy slow path, just in case the GL driver has an implementation that doesn't work... Unless it really is a driver bug, but I've had it happen on 2 out of 5 test machines, so it would seem unlikely.

I've also tried hard coding in a small rectangle, just to check I wasn't passing in garbage to the hint function, but same result. Has anyone had any luck with this extension?

Advertisement

To my opinion this extension is old and odd.

I would suggest you avoid using WGL extensions as they target only... Windows...

Finally, as the name says it, this is a hint. And just like any other hints in OpenGL, the OpenGL driver might not take care about the user request. So it is fully normal that it can work on some machines while it won't work on others.

I would usually agree on the WGL extensions, but this is for a windows only app, and was quite easy to put in.

I'm getting the impression that maybe the problem is that while opengl has a means of showing whether the extension is available (wglGetProcAddress and glGetString), it doesn't seem to have a way of letting you know whether the extension is working in your particular hardware configuration. :blink: I had a glimmer of hope as I found in the docs that in the PixelFormatDescriptor there were 2 new flags for glAddSwapHintRectWin, PFD_SWAP_COPY and PFD_SWAP_EXCHANGE. However when I checked them PFD_SWAP_EXCHANGE was set for both my machine where it was working, and the test machine where it wasn't, so it didn't provide a means of distinguishing whether the extension was 'active'.

https://msdn.microsoft.com/en-us/library/windows/desktop/dd368826(v=vs.85).aspx

The problem I'm facing is I'm combining a complex 3d model (say 300,000 polys) and a GUI user interface. I don't want to have to render the model, every time I change a tiny element in the user interface (say a cursor blinking on and off!). As it is, without the swaphint, because of double / triple buffering, I'm needing to do this because it is forcing me to update the whole frame. Unless I render the model to another surface then copy this to the main one. Which might be difficult as I'm trying to use OpenGL 1 lol. :D

I've now had to change my app code to by default update the whole frame each time, and then offer the 'proper' implementation of just updating subrects via a command line option. Which seems to be ridiculous. :wacko: If there is a better way of doing this I'd love to hear it! :)

OK.

Then you have very few options.

I'm unsure about it right now if they were already available (and couldn't find any suitable info about them), but glScissor might help you.

Also, you might be interested in viewports as long as your interface design allows it.

Also, again (maybe I was not clear from my last post), it's not because an extension is available and supported by a hardware and the driver that a hint function from this extension will always work. A hint is just an indication that we give to the driver. Then the driver will choose if it will honor this hint or not, depending on factors.

You can see for example glHint. You can put whatever you want as the arguments (as long as valid), and you might end with the same results.

You can also have a look at pbuffers.

It is for my little 3d paint app:

http://www.gamedev.net/blog/2199/entry-2262243-3d-paint-preview-video/

I am already using glScissor, and viewports, but they do not solve the problem of having to draw the whole frame, when swaphint does not work (and as I have no way of querying this, I am forced to draw the whole screen every time :( ).

After a bit of assessment, the problem is not hugely severe except causing lag with high poly models in the user interface, so I may just live with it. :rolleyes:

I am also already copying the 3d view to a texture in some modes to accelerate things, so could potentially use the same functionality and save the 3d view to a texture when I stop rotating the view, and then render the 3d view as a quad when doing small GUI rect updates.

This is still a convoluted way of doing things, and limiting the swap area would seem much more sensible. But perhaps there are hidden hardware reasons why this is not possible in some cases (tiled rendering or somesuch). A way of querying OpenGL whether the extension is active in the context would seem to be far more sensible than the current hint system, imo.

You're right, swapbuffers does not care at all about scissors and viewports...

I just saw your video and now I understand your problem more. And several things came to my mind:

You can use different windows, one for rendering, one or 2 for the interface. You'll then be able to easy choose which window to swap the buffer for.

Why targeting OpenGL 1 ? I have doubts that nowadays we can still find GC that can do GL 1 but no GL 2 or 3... I mean GL 2 came at the early 2000. This was 16 years ago... And you won't be forced to use shaders or to remove deprecated GL features.

I ask this because if you want to keep your interface inside GL (which it seems what you are doing), FBOs will be very helpful to you. You can render your GUI in FBOs then only have to patch them on a full quad rendered in the screen. You can of course do that with textures as you're already doing it, it will however be less quick. This will not remove your wish to swap only a portion of the screen however.

To my opinion it might be more effective for a GC to swap the full buffer than a portion for several reasons: memory alignment in the buffer, having to maintain the other buffers aligned too. This implies extra work for something that should be as easy as setting the address of a buffer to another value...

As a final thought, and the one you might prefer, what you can do is: don't clear your color buffer, and display a black rectangle for the GUI portion that had changed, then redraw on top of it. Then swap your buffer. Since you don't clear the buffer, you don't have to redraw your model each time... You'll have to play with the depth test to make it work well.

Another solution that you might not like would be to use a GUI toolkit as Qt or Gtk...

You can use different windows, one for rendering, one or 2 for the interface. You'll then be able to easy choose which window to swap the buffer for.

I initially had a look at this, but I had problems such as having the GUI draw over the 3d window (dropdown menus that obscure it etc).

Why targeting OpenGL 1 ? I have doubts that nowadays we can still find GC that can do GL 1 but no GL 2 or 3... I mean GL 2 came at the early 2000. This was 16 years ago... And you won't be forced to use shaders or to remove deprecated GL features.

Hehe I will update it if I get around to it (I would probably need it for normal and specular maps). I have an OpenGL ES 2.0 version of the GUI for Android, but just wanted something easy to get going that runs anywhere to start with for the paint app. And display lists and wireframe are nice and easy.

To my opinion it might be more effective for a GC to swap the full buffer than a portion for several reasons: memory alignment in the buffer, having to maintain the other buffers aligned too. This implies extra work for something that should be as easy as setting the address of a buffer to another value...

Yup this is true. I may have been assuming it was doing an extra copy somewhere for windowed rather than full screen, but that might well not be true. I guess it is a black box to me how this is implemented, and OpenGL has to work well with lots of different implementations under the hood.

As a final thought, and the one you might prefer, what you can do is: don't clear your color buffer, and display a black rectangle for the GUI portion that had changed, then redraw on top of it. Then swap your buffer. Since you don't clear the buffer, you don't have to redraw your model each time... You'll have to play with the depth test to make it work well.

I did end up with a situation like this by accident when things went wrong lol. It is a little more complex though because the app might be using single, double triple buffering etc, and if you try to force it to a single buffer, it would impede getting nice fluid graphics. So you have to make sure that not only your back buffer is filled with the right background, but the last 2 or 3.

This topic is closed to new replies.

Advertisement