Qt : screenshot with QOpenGLWidget - c++

Hellow,
I have an application based on Qt using QOpenGLWidget.
In the OpenGL widget (named oglwidget in my code) I draw meshes and lines using opengl functions. Then I use QPainter to draw scales and texts in teh same widgte.
Now when I use :
const QRect rect(0,0,oglwidget.width(),oglwidget.height());
QPiaxmap pixmap = oglwidget.grab(rect);
to save the pixmap in a file with :
pixmap.save(...);
only the objects drawn with opengl functions are saved.
What do I miss ? Is there any solution to save the entire scene ?
Would you please help ?
Thanks and regards.

If you will be using the QOpenGLWidget method for grabbing it will actually get the pixels from the frame buffer rendered by the opengl, if you want to capture the screenshoot you probably should have a look at this tutorial.
To be more specific you probably want the grab method from QScreen rather then grab on the openGL context (the QOpenGlWidget method).

Related

Drawing text with shadow on pixmap with QPainter

I am working on a project in C++ with Qt, and I am trying to find a way to apply a text shadow when drawing text on a QPixmap using QPainter.
I understand that QGraphicsDropShadowEffect is a thing, and I am using in other parts of my project, but I can't for the life of me find a way to apply a QGraphicsEffect when drawing with QPainter on a pixmap. Drawing the same text multiple times with different offsets and opacities doesn't quite cut it.
Are there any ways to do this?
If not, how could I go about making a function that does it, given a QGraphicsEffect to get the radius and color from?
Thanks in advance!
I don't think it is directly possible to "draw text with shadow", it is only possible to apply a shadow to something already drawn that would take in an element and use say its alpha channel to calculate the shadow.
You should use composition, either of the final products or during drawing. It should work if you use it on a text element. The other option would be to draw your text in black, apply Gaussian blur and then again draw the text on top of it with the desired offset.
Thanks for your answer ddriver, it made me search with some new keywords, which lead me to find a suiting solution for my project.
What I figured out is that you can simply create a QLabel with the text and effects you want (QGraphicsDropShadowEffect, in my case), and render it into a QPixmap using QWidget::grab(). You can then draw this new pixmap with QPainter as you would any other image, by converting your pixmap to a QImage and using QPainter's drawImage().

OpenGL draws over widgets in Qt

I'm developing a Qt app which uses Cocoa on the Mac and am using PowerVR SDK to enable OpenGL ES 2.0 on Mac Desktop.
I've managed to get it working, everything renders perfectly, the problem is
that when I'm creating a widget in that window, OpenGL renders over it, e.g
I'm creating a QLabel and it renders over it, making the label invisible.
I tried calling QLabel's repaint() method after rendering a single OpenGL frame, but that didn't help.
Has anyone encountered such or similar issue and has any suggestions?
Thanks!
If you wish widgets to interoperate with OpenGL content, you must use the QOpenGLWidget. It draws to an offscreen buffer that then gets composited with the widgets.
Alternatively, you must yourself render the label into a texture, and apply the texture to a quad.

libvlc-qt and OpenGL

I'm trying to make an app using libvlc-qt and Qt5.5. Some functionalities require displyaing semi-transparent text and graphics over video widget. I've found this thread, which says: "The video widget is opengl. You should be able to put a new opengl layer above."
My question is how do I approach this? I've tried creating overlapping QOpenGLWidgets and drawing using QPainter on them, and some similar simple solutions, but it resulted with nothing happening or random segfaults. Any ideas?
You can overlap QWidget over QOpenGLWidget, but not the other way around. And specifically, nothing in the parent widget and under the QOpenGLWidget will be visible.

Rendering over DirectX window with Awesomium (semi-transparent & rounded elements)

I wonder if it's possible to use Awesomium to render the GUI over the DirectX 11 game (I do NOT use .NET, it's C++/DirectX 11 game)?
It would involve:
Rendering the scene on the window with DirectX 11 (just as I am doing it now).
Rendering the GUI with Awesomium from HTML/CSS over the previously rendered scene.
Note that some GUI elements should be semi-transparent or rounded - so it's not only rendering on some rect, but also blending.
Is it possible? Or maybe I could make it another way (e.g. telling Awesomium to use DirectX for rendering somehow)?
Or maybe I could draw an semi-transparent DirectX texture in Awesomium, and then render it over the scene with DirectX? I know that rendering to texture resource is possible with Awesomium, but does it supports transparency & semi-transparency?
If not, are the good alternatives for what I wanted to achive with Awesomium?
Yes. It can be done.
If you look at the documentation of the Awesomium WebView class it has a surface() method which will return the views backing bitmap.
Here is some c++ documentation for the class.
http://awesomium.com/docs/1_7_0/cpp_api/class_awesomium_1_1_web_view.html
You can copy this bitmap to a texture in DirectX and render it as layer on top of your game creating your UI.
You also have to route and translate input into Awesomium. You can style your UI however you like using HTML, CSS and Javascript. You can make it rounded in this way and introduce transparency.
I won't repeat a perfectly good tutorial on doing this. You can find one here.
http://www.gamedev.net/blog/32/entry-2260646-sweet-snippets-rendering-web-pages-to-texture-using-awesomium-and-direct3d/
How you render your texture after it is written doesn't have anything to do with Awesomium. Choose your blend modes and/or use shaders with output texture for desired effect.

resizing QGLWidget to fit with each sprite size I have

I'm creating 2D Map editor using opengl to draw simple 32x32 sprites but it seems that I cannot resize my QGLWidget to a large size (i.e size * sprite size -> 1024 * 32), using 1024 only seems to work fine (using glwidget->setMinimumSize(...)). I've been googling for a while now about this, the only interesting thing I found is subclassing QAbstractScrollArea and setting my QGLWidget as it's viewport (That's what QGraphicsView does), I also seen all Qt opengl examples but i couldn't find anything that could help (except Image Viewer example which is not exactly what I want), I also tried the following:
horizontalScrollBar()->setMaximum(width * 32);
verticalScrollBar()->setMaximum(height * 32);
with the widget resizable set to true/false on the scrollarea but still nothing.
Any ideas how would I do that? I can show more code if you ask me to.
Using Qt v4.7.3.
I have two ideas:
If it's possible, drop the idea of using a QGLWidget and place the sprites directly in a graphics scene (QGraphicsPixmapItem). Possibly not what you want, but the graphics scene is made to handle a lot of items, so most things you need (trigger mouse events on items for example) are already implemented.
Or just place the QGLWidget in a graphics scene using a QGraphicsWidget. This should automatically tell the scene its size, which then tells the view the size of the scene. The scroll bars appear automatically if the scene doesn't fit into the view.
Update:
As described in this link, you can use OpenGL in any graphics view:
view.setViewport(new QGLWidget(QGLFormat(QGL::SampleBuffers)));
view.setViewportUpdateMode(QGraphicsView::FullViewportUpdate);