The idea is to ultimately have a program that runs in the background. This program paints pixels to the desktop wallpaper at a rate of at least 24 pixels per second.
I've already tried using certain dekstop handles but that does not have the desired result. This solution paints over cursor and icons as well.
Suggestions?
This rust crate can change the wallpaper of many OS:
https://docs.rs/wallpaper/2.0.1/wallpaper/
It may not yield the performance you where talking about, in my experience it can change the background a few times per second.
Related
the MFC application I'm currently working on is a little hobby project, supposed to look like the green code rain from the movie Matrix. My application has the window divided into thousands of little squares, each holding a letter and each of which might need a redraw to the screen after 25 milliseconds (one frame). Currently, I tried to do this with CClientDC::TextOutW. However, depending on how many of the tiles need an update, calling TextOutW for all the necessary tiles might take anywhere from 30 to 75 milliseconds, which is obviously way too long. The output looked great, but it was just progressing too slowly.
Then I tried to use some multithreading to do the redrawing, but for that, each thread needed access to the screen. I couldn't find any documentation on whether a CClientDC can be used by multiple threads or if multiple threads can have several CClientDCs at once, writing to the same device. The multithreaded apllication I wrote compiles and runs, but the output looks pretty garbled.
I might have made a mistake somewhere (I'm not that well-experienced with multithreading yet), but then again, I might be trying to push butter through stone here. Can anyone tell me if what I'm trying to do with the CClientDC is even possible?
If multithreaded output to the screen via CClientDC is not possible, does anyone have another idea how I could output about 2000 letters on different positions onto the screen in the timespan of 20 milliseconds?
Thanks in advance!
I want to draw a small dot at the center of the screen so that it must remain after running of any application. A dot should stay even after I launch an application in full screen mode. Like a dead pixel.
I have already installed Visual C++ on my computer with Windows 7. I have some experience with C++, but I never worked with graphics under Windows OS.
How can I draw a dot on a screen?
Many graphics cards have overlay features, and it is likely possible to set one up to be foremost on the screen regardless of what other applications are rendering in other layers.
But the method to do that would be specific to the video card model and driver.
Or, you can try to get your code inside the application doing full-screen rendering, find their rendering context, and draw to it at the ideal time. Which still requires a bunch of variants for all the different graphics APIs.
Here is someone who describes Steam's attempt to solve the portability issue (with a zillion implementations) and how to take advantage of that.
I would create a properly positioned 1x1 pixel (or whatever size you need) window with no borders or title bar, all client area and paint it appropriately. It's important that the window is created with the WS_EX_TOPMOST style. As long as your program is running, the window will be visible as long as there are no other windows with that style overlapping it.
I've done this as a prank. It worked really well over a full-screen OpenGL game (Quake III). I installed it on a friend's machine so that it would flash the word LOSER! in big letters in the center of the screen at random times during the game.
This worked perfectly well on an XP system. I imagine it should work on Windows 7.
What I need to do is create a program that overlays the whole screen and every 30 seconds the screen needs to flash black once.
the program just needs to be on top of everything, doesn't have to work over the top of games, but wouldn't say no if it did!
But i've got no idea where to start. Ideally the solution would be cross-platform for both windows and osx.
Does anybody have any ideas about where I should start or could whip up a quick demo?
OpenGL (you tagged it as such) will not help you with this.
Create a program, that overlays the whole screen,
The canonical way to do this is by creating a decorationless, borderless top level window with some stay-on-top property being set.
and every 30 seconds the screen needs to flash black once.
How do you define "flash back once"? You mean you want the display become visible for one single vertical retrace period or a given amount of time? Being the electronics tinkerer I am, honestly, I'd do this using a handfull of transistors, resistors and capacitors, blanking the analog VGA signal.
Anyway, if you want to do this using software, this is going to be hard work. If you'd do this using the aforementioned stay-on-top window, when you "flash" it away, all the programs with visible output would receive redraw events, which to process would take some time. In the best case scenario the system uses a compositing window manager which can practically immediately show the desktop. Without a compositor its going to be impossible to "flash" the screen.
Ideally the solution would be cross-platform for both windows and osx
A task like this can not be solved cross plattform. There's too much OS dependent work to do for this.
I presume this is for some kind of nerological or psychological experiment. I think doing this using some VGA intercepting circurity would be actually the easier, quicker to implement solution. I can help you with that. But I think there's another StackExchange better suited for this. Unfortunately digital display interfaces (DVI, HDMI and Display Port) use a complex line code scheme, which can not be blanked as easily as VGA, so you must have a computer capable of analog (=VGA) output and a display with a VGA input.
I'm currently writing a game of immense sophistication and cunning, that will fill you with awe and won- oh, OK, it's the 15 puzzle, and I'm just familiarising myself with SDL.
I'm running in windowed mode, and using SDL_Flip as the general-case page update, since it maps automatically to an SDL_UpdateRect of the full window in windowed mode. Not the optimum approach, but given that this is just the 15 puzzle...
Anyway, the tile moves are happening at ludicrous speed. IOW, SDL_Flip in windowed mode doesn't include any synchronisation with vertical retraces. I'm working in Windows XP ATM, but I assume this is correct behaviour for SDL and will occur on other platforms too.
Switching to using SDL_UpdateRect obviously won't change anything. Presumably, I need to implement the delay logic in my own code. But a simple clock-based timer could result in updates occuring when the window is half-drawn, causing visible distortions (I forget the technical name).
EDIT This problem is known as "tearing".
So - in a windowed mode game in SDL, how do I synchronise my page-flips with the vertical retrace?
EDIT I have seen several claims, while searching for a solution, that it is impossible to synchronise page-flips to the vertical retrace in a windowed application. On Windows, at least, this is simply false - I have written games (by which I mean things on a similar level to the 15-puzzle) that do this. I once wasted some time playing with Dark Basic and the Dark GDK - both DirectX-based and both syncronising page-flips to the vertical retrace in windowed mode.
Major Edit
It turns out I should have spent more time looking before asking. From the SDL FAQ...
http://sdl.beuc.net/sdl.wiki/FAQ_Double_Buffering_is_Tearing
That seems to imply quite strongly that synchronising with the vertical retrace isn't supported in SDL windowed-mode apps.
But...
The basic technique is possible on Windows, and I'm beginning the think SDL does it, in a sense. Just not quite certain yet.
On Windows, I said before, synchronising page-flips to vertical syncs in Windowed mode has been possible all the way back to the 16-bit days using WinG. It turns out that that's not exactly wrong, but misleading. I dug out some old source code using WinG, and there was a timer triggering the page-blits. WinG will run at ludicrous speed, just as I was surprised by SDL doing - the blit-to-screen page-flip operations don't wait for a vertical retrace.
On further investigation - when you do a blit to the screen in WinG, the blit is queued for later and the call exits. The blit is executed at the next vertical retrace, so hopefully no tearing. If you do further blits to the screen (dirty rectangles) before that retrace, they are combined. If you do loads of full-screen blits before the vertical retrace, you are rendering frames that are never displayed.
This blit-to-screen in WinG is obviously similar to the SDL_UpdateRect. SDL_UpdateRects is just an optimised way to manually combine some dirty rectangles (and be sure, perhaps, they are applied to the same frame). So maybe (on platforms where vertical retrace stuff is possible) it is being done in SDL, similarly to in WinG - no waiting, but no tearing either.
Well, I tested using a timer to trigger the frame updates, and the result (on Windows XP) is uncertain. I could get very slight and occasional tearing on my ancient laptop, but that may be no fault of SDLs - it could be that the "raster" is outrunning the blit. This is probably my fault for using SDL_Flip instead of a direct call to SDL_UpdateRect with a minimal dirty rectangle - though I was trying to get tearing in this case, to see if I could.
So I'm still uncertain, but it may be that windowed-mode SDL is as immune to tearing as it can be on those platforms that allow it. Results don't seem as bad as I imagined, even on my ancient laptop.
But - can anyone offer a definitive answer?
You can use the framerate control of SDL_gfx.
Looking at the docs of library, the flow of your application will be like this:
// initialization code
FPSManager *fpsManager;
SDL_initFramerate(fpsManager);
SDL_setFramerate(fpsManager, 60 /* desired FPS */);
// in the render loop
SDL_framerateDelay(fpsManager);
Also, you may look at the source code to create your own framerate control.
I noticed in an MFC application I'm developing that while dragging the scroll bar to smoothly scroll down the document, the framerate drops to choppy levels when a block containing about a paragraph of text is on screen, but silky smooth when it's offscreen. Investigating the performance, I found the single CDC::DrawText call for the paragraph of text responsible. This is in an optimised release build.
I used QueryPerformanceCounter to get a high-resolution measurement of just the DrawText call, like this:
QueryPerformanceCounter(...);
pDC->DrawText(some_cstring, some_crect, DT_WORDBREAK);
QueryPerformanceCounter(...);
The text is unicode, lorem-ipsum style filler, 865 characters long and wraps over 7-and-a-bit lines given the rectangle and font (Segoe UI, lfHeight = -12, a standard body text size). From my measurements, that call alone takes on average 7.5 ms, with the odd peak at 21ms. (Note to keep up with a 60Hz monitor you get about 16ms to render each update.)
I tried making some changes to improve the performance:
Removing the DT_WORDBREAK improves performance to about 1ms (about 7 times faster), but given only one line of text is making it to the screen, and there were just over 7 lines with word breaking, this seems to suggest to me the bottleneck is elsewhere.
I was drawing text in transparent mode (SetBkMode(TRANSPARENT)). So I tried opaque mode with a solid background fill. No improvement.
I thought ClearType rendering might be to blame. I changed the font lfQuality from CLEARTYPE_QUALITY to NONANTIALIASED_QUALITY. It looked like crap with sharp edges and all, and no improvement.
As per a comment suggestion, I was using a CMemDC, but I got rid of it and did direct drawing. It flickered like mad, and no improvement.
This is running on a Windows 7 64-bit laptop with an Intel Core 2 Duo P8400 # 2.26 GHz and 4 GB RAM - I don't think it counts as a slow system.
I'm calling DrawText() every time it draws and this obviously hammers the performance with such a slow function, especially if several of those text-blocks are visible at once. It's enough to make the experience feel sluggish. However, Firefox can render a page like this one in ClearType with much more text, and seems to cope just fine. What am I doing wrong? How can I get around the poor performance of an actual DrawText call?
Drawing the text at every refresh is wasteful. Use double buffering, that is, draw in an offscreen bitmap and just blit it to the screen. Then, for scrolling, just copy most of the bitmap up or down or sideways as necessary, then draw only the invalidated area (before blitting the result to the screen).
If even that turns out to be too slow, keep also the drawn text in an off-screen bitmap, and blit instead of draw.
Cheers & hth.,
According to this german blogpost, the issue has to do with support for asian language fonts. If you enable those in XP you get the same perf hit. In Vista/7, they are default enabled and you can't turn them off.
EDIT: Just maybe, using a different font might help.. (one that does not contain asian characters).
Users can't read text at 7 lines in 7 milliseconds, so the call itself is fast enough.
The 60 Hz refresh rate of the monitor is entirely irrelevant. You don't need to re-render the same text for every frame. The videocard will happily send the same pixels to the screen again.
So, I thibk you have another problem. Are you perhaps wondering about scrolling text? Please ask about the problem you really have, instead of assuming DrawText is the culprit.
In order to break the text on word breaks, DrawText needs to repeatedly try to get the width of a block of text to see if it will fit, then take the remainder and do it over. It will need to do this at every call. If your text is unchanging, this is an unnecessary overhead. As a workaround, you could measure the text yourself and insert temporary line breaks and remove the DT_WORDBREAK flag.
Have you considered Direct2D/DirectWrite?
Anyway it should work better if you just draw the text once to its own mem dc and blit that over to whatever dc you want it painted on with each iteration.