Questions about OpenGL Settings and drawing over a mask in a window - opengl

I would like to know the OpenGL Rendering settings for having a program render OpenGL over top of any window on screen that has a specific color code (screen-level buffer?)
I.E. VLC Media Player and Media Player Classic both have rendering modes which allow you to full-screen then minimize player, but maintain watching media via allowing a specific color to act as a transparent mask. For example, you could set the background color of a terminal application to be 0x000010 for VLC 0x000001 for MPC and you could then type over the media using text (as it is in it's original color). When you try to do a "printscreen" all you get is the mask color, However, this is an acceptable side-effect.
Is it possible to do this as well with any OpenGL application with the right settings and hardware? If so, what are the settings or at least the terminology of this effect to further research it?

What you are trying to implement is called "overlay". You can try this angelcode tutorial. If I remember correctly, there was also a tutorial in DirectX SDK.
If you need to use OpenGL, you will need to perform offscreen rendering (using FBO or P-buffer), read the results using glReadPixels() and display using overlay.

Related

A video player based on QtAV with Direct2D / OpenGL rendering

I'm developing a video player in Qt C++ using QtAV. QtAV uses ffmpeg internally. I need to show semi transparent overlays both my watermark logo and subtitles. I'm writing the application for windows. I use OpenAL library. OpenGL and Direct2D are the choice for renderers.
If I use OpenGL renderer, it works fine in some systems. The overlay works fine. But in some other systems the whole application will be just a black window. Nothing else I can see.
If I use Direct2D, the overlay wont work. And the renderer is a bit slow. But it works on all systems, without this overlays.
I have no code to show here because its not the coding issue. Even the examples in QtAV are not working. I need to find a way to show the overlays using Direct2D renderer OR find a solid way to use OpenGL rendering on all systems without fail.
Direct2D is not well supported in QtAV. So you may need to implement your own functions to add filters in your video render. That includes text draw functions, setting transparency etc.

On Linux how can I capture the desktop to an OpenGL texture?

I'm writing a cross platform open source Oculus Rift desktop viewer. I decided to start with Linux because I prefer developing on it. I've already got the texture warping working but now I need to capture the desktop to an OpenGL texture. There are other issues I'm not entirely sure how to resolve like rendering the warped desktop to my window while capturing every window except mine. Any clue how I would go about this?
I think your best course of action would be actually to write a fully fledged compositor.
There is the GLX_texture_from_pixmap extension, that allows you to source any pixmap compatible X11 drawable into a OpenGL texture. For a start it might be enough to simply pull the root window (pixmap) as it is into a OpenGL texture. Later you might want to use the Composite extension to redirect windows to off-screen rendering and composite them in 3D space as a stereoscopic picture in the Occulus Rift.

SDL OpenGL Textures Lost

I have a fully working engine that is using SDL and OpenGL. I have a textured box on my OpenGL/SDL screen - however when I try to change the video mode (e.g. toggle fullscreen with F11) the texturing is lost (the box is just plain white), if I toggle back to windowed mode the box is still white (with the textured image lost). Does this mean I cannot change my video mode in the middle of the application (e.g. toggle fullscreen) or does it mean I have to reload my OGL textures every time I do so?
Some extra notes: I am using CodeBlocks with MinGW on windows 7, the libraries I have linked are: SOIL (a library for easily loading textures in OGL - http://www.lonesock.net/soil.html), OpenGL32, Glu32 and SDL.
I have some images to demonstrate my problem (the first one is windowed mode and the second one is when I try to change to fullscreen with a call to SDL_SetVideoMode(...) - SDL_WM_ToggleFullScreen doesn't work.
I have a textured box on my OpenGL/SDL screen - however when I try to change the video mode (e.g. toggle fullscreen with F11) the texturing is lost (the box is just plain white), if I toggle back to windowed mode the box is still white (with the textured image lost). Does this mean I cannot change my video mode in the middle of the application (e.g. toggle fullscreen) or does it mean I have to reload my OGL textures every time I do so?
It strongly depends on how the used framework implements video mode changes.
In general when deleting an OpenGL context all it's associated data is lost, except if there's another OpenGL context with which a "sharing" has been established. That can be used to keep all uploaded data persistent between context recreation. However a mere video mode change usually doesn't require a context recreation, and usually also not a window recreation.
However the framework used by you (SDL) will completely clean up a window and the context when changing the video mode, thus loosing you the loaded resources. Unstable development versions of SDL have better OpenGL support, allowing for video mode changes without context teardown inbetween.
Unfortunately, the problem stems from the way SDL recreates the window. I had this problem before and the solution for me was to set up a special uninitialize and initialize function that only got rid of/created images.
Essentially, when SDL's Resize event is called (http://www.libsdl.org/docs/html/sdlresizeevent.html) you would uninitialize any artistic assets required and then re-initialize them after entering or leaving fullscreen.

How to get X to render to an OpenGL texture?

I am trying to write a compositor, like Compiz, but with different graphical effects. I am stuck at the first step, though, which is that I can't find how to get X to render windows to a texture instead of to the framebuffer. Any advice on where to start?
X11 composition goes like following.
you redirect windows into a offscreen area. The Composite extension has the functions for this
you use the Damage extension to find out which windows did change their contents
in the compositor you use the GLX_EXT_texture_from_pixmap extension to submit each windows' contents into corresponding OpenGL textures.
you draw the textures into a composition layer window; the Composite extension provides you with a special screen layer, between the regular window layer and the screensaver layer in which to create the window composition is taking place in.

How to take reliable QGLWidget snapshot

In my application I take snapshots of a QGLWidget's contents for two purposes:
Not redraw the scene all the time when only an overlay changes, using a cached pixmap instead
Lat the user take screenshots of the particular plots (3D scene)
The first thing I tried is grabFrameBuffer(). It is natural to use this function as for the first application, what is currently visible in the widget is exactly what I want to cache.
PROBLEM: On some hardware (e.g. Intel integrade graphics, Mac OS X with GeForce graphics), the image obtained does not contain the current screen content, but the content before that. So if the scene would be drawn two times, on the screen you see the second drawing, in the image you see the first drawing (which should be the content of the backbuffer?).
The second thing I tried is renderToPixmap(). This renders using paintGL(), but not using paint(). I have all my stuff in paint(), as I use Qt's painting functionality and only a small piece of the code uses native GL (beginNativePainting(), endNativePainting()).
I also tried the regular QWidget's snapshot capability (QPixmap::fromWidget(), or what it is called), but there the GL framebuffer is black.
Any ideas on how to resolve the issue and get a reliable depiction of the currently drawn scene?
How to take reliable QGLWidget snapshot
Render current scene to framebuffer, save data from framebuffer to file. Or grab current backbuffer after glFlush. Anything else might include artifacts or incomplete scene.
It seems that QGLWidget::grabFrameBuffer() internally calls glReadPixels() from OpenGL. On double-bufferd configurations the initial mode reads the back buffer (GL_BACK), switch with the OpenGL call glReadBuffer(GL_FRONT) to the front buffer before using QGLWidget::grabFrameBuffer() displaying an image on the screen.
The result of QGLWidget::grabFrameBuffer(), like every other OpenGL calls, depends on the video driver. Qt merely forwards your call to the driver and grabs the image it returns, but the content of the image is not under Qt's control. Other than making sure you have installed the latest driver for your video card, there is not much you can do except report a bug to your video card manufacturer and pray.
I use paintGL(); and glFlush(); before using grabFrameBuffer(). The paintGL helps to draw current frame again before grab the frame buffer, which makes an exact copy of what is currently showing.