I'm building an app which uses Qt5 that aims to display a video from a digital camera (using Gstramer pipeline). Then with the help of QPainter I'm drawing some graphics on top of it (some text shapes, and icons).
The thing is that the video refresh rate is ~30 FPS, and I only need to update the graphics in ~10 FPS or so. Currently I redraw the graphics overlay for every video frame which is very wasteful in terms of CPU.
Is there a better approach in which I can re-use the overlay from the previous frame, and only update the background (the frame from the camera)?
One idea that I had was to paint the overlay into a QImage, and then just paint the image onto the QOpenGLWidget, but it just feels wrong.
Thank you...
Related
I wanted to use libVCL to display a video in my game, however I have issues with using HWND when the game is in fullscreen, the fullscreen surface overlaps the video.
I do have the D3DDevice handle available though so the video could draw inside the game surface.
But all I've found is libvlc_media_player_set_hwnd() and not a way to pass the video surface to my game's surface for drawing. Is there any way/example to do this?
There is no such function in LibVLC.
I think you need to use the video format callbacks and render the video buffer to a texture yourself. That is the I the approach I used (from Java with JMonkeyEngine for example).
See libvlc_video_set_callbacks, libvlc_video_set_format and libvlc_video_set_format_callbacks.
I've seen this play back full HD smoothly, but this will consume more CPU than having VLC render directly into a video surface.
I created QPropertyAnimation and connected it to my SonogramWidget that scroll a long picture vertically on animation events. The 'long picture' is composed of 100 pre-calculated QPixmap objects 1024x128 placed one after another vertically. They displayed in SonogramWidget::paintEvent() with QPainter. Drawing procedure paint not all QPixmap at once, but only visible of them, considering widget height and current vertical offset. CPU is almost free, because QPixmap is a fastest way to display a picture. There is no big calculations during scrolling, because all the 100 QPixmaps are pre-calculated and stored in memory.
I see strange effect: pulsating movement: 2 times a second the entire image slightly speed-up and moves up by 1..2 pixels faster than usual motion. The same effect when i replace Qt Animation Framework with single 60 fps QTimer and scroll the image in its SLOT.
Video: http://www.youtube.com/watch?v=KRk_LNd7EBg#t=8 (watch from 00:08; My firefox adds more chopping to video playing itself, google chrome plays the video much better).
I see the same effect for my Linux and Windows build.
SOLUTION
i figured out the issue: the "chopping" was not a bug, it was a feature! It is a feature of integer-number calculations, so sometimes we had to have different numbers for animations, like: 16,16,16,16,16,16,17,16,16,16,16,16,17,....
In the paintEvent add the following assert:
Q_ASSERT(m_animation->currentValue() == m_animatedPropertyValue);
If it triggers, then you know you must use currentValue() instead of the property value. This might be the case. Let me know.
im testing my game on iphone5 simulator
i have background sprite with 1136*640 pixels size image
if i set my background with,
background1.anchorPoint=CGPointZero;
background1.position=ccp(0,0);
cocos2d magnifies that image.
if i set my background with,
background1.anchorPoint=CGPointZero;
background1.position=ccp(0,0);
background1.scale=0.5;
image fits screen, which is perfect. but if i do so then i get wrong background.contentSize , is that magnification of sprite stoppable?
i'v also set [director enableRetinaDisplay:NO];
It's probably because you haven't named the sprite with the -widehd extension. Like: background-widehd.png OR -iphone5hd depending on your version of cocos2d. If you targeting retina displays you should:
[director enableRetinaDisplay:YES]
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.
i'm writing a menu-based OpenGL graphics editor.It is pretty basic. Every time i choose a new option in the pop-down menu, the older drawing disappears,this doesn't allow me to use the eraser tool...could anybody tell me how to solve this problem?thanx
Your question is vague. Anyway...
Are you drawing picture directly on the screen/window? Then of COURSE drawings will disappear.
Paint picture to texture (framebufferObjects or whatever. See NVidia OpenGL SDK for examples). Then render texture on the screen. clear screen, draw texture, then draw menu, every time you need to repaint window.