chaos.desktopext Fullscreen DesktopPixmap()

BlitzMax Forums/BlitzMax Programming/chaos.desktopext Fullscreen DesktopPixmap()

Hezkore(Posted 2012) [#1]
I'm making an application that grabs screenshots for you.
It runs as its own application and when you press Printscreen it takes a screenshot using DesktopPixmap() from chaos.desktopext.
It's all working, except for when you're in fullscreen mode.
It just takes a black picture (or transparent sometimes...)

Anyone know why?
Or does anyone have a better way of capturing a screenshot that will work in fullscreen?


ima747(Posted 2012) [#2]
What platform?


Hezkore(Posted 2012) [#3]
Win32.
I believe chaos.desktopext only supports Win32 when it comes to DesktopPixmap()

Here's an example that shows how messed up this is.
SuperStrict
Import chaos.desktopext

Function MainFunction()
	For Local i:Int = 0 To 100
		DrawRect(Rand(0, GraphicsWidth()), Rand(0, GraphicsHeight()), 32, 32)
	Next
	SetColor(255, 0, 0)
	DrawText("Press Escape", 0, 0)
	SetColor(255, 255, 255)
	
	Flip()
	Cls()
End Function

Graphics(1024, 768, 0)
While Not KeyDown(KEY_ESCAPE)
	MainFunction()
Wend
SavePixmapPNG(chaos.desktopext.DesktopPixmap(), "Test_Window.png")
EndGraphics()

Graphics(1024, 768, 32)
While Not KeyDown(KEY_ESCAPE)
	MainFunction()
Wend
SavePixmapPNG(chaos.desktopext.DesktopPixmap(), "Test_Fullscreen.png")
End


Last edited 2012


col(Posted 2012) [#4]
Hiya,

Some questions...

Do you want to capture the dekstop or just your app window thats using graphics?
Do you want to just save the capture or manipulate it?

Because youre saying you want to do a capture during full screen and looking at the fact youre saving the capture to disk in your example above, I assume you want to capture just the app window and save it. Using D3D9 makes this very easy to capture the contents of the window, however to capture the desktop as a whole will require a different method.

Heres a simple example to capture a D3D9 app windowed and fullscreen ( tested on Win7 x64 )...

CaptureScreenToDisk(FileName$ , FileFormatExt$)
FileName$ : self explanatory, saves to the same folder as the .exe
FileFormatExt$ : Use either "jpg" "bmp" or "png"

You could easily save to other formats but BMax doesnt support them to load back in as images or pixmaps, unless of course you write a loader too using D3DX :P

One thing I will say is that this method captures the back buffer. Remember this could actually be different to what you see on the front buffer! So Flip the screen again to see what youre capturing. ( D3D9 does offer the functionality to capture the FrontBuffer directly buts its not always supported by all GPUs for some reason ).

This example Flips the screen a second time as described to show on the screen what is being captured to disk.




*(Posted 2012) [#5]
why not grab a pixmap and then savepixmappng?


Hezkore(Posted 2012) [#6]
I guess the active window is enough to capture.
But if it's 3D or software, that's outside of my control.

I'm making an arcade frontend, it launches different emulators and takes screenshots ingame and saves it to the disk.
And the only manipulation I want to do is resize the image down to 320x240.

So my program just sits in the background and then takes a screenshot of whatever's on display.

That means I can't just capture my own buffer (my real app is only a MaxGUI app without a graphics canvas or anything, just a hidden window) and I can't do stuff like use OpenGL instead, cause that's outside my control as an emulator might use Direct3D.

Last edited 2012


col(Posted 2012) [#7]
I understand.

Its easy to hack/modify chaos code to suit this and add an extra parameter to the DesktopPixmap() function. I only know how to do it for Windows unforuntately!



Then modify your code for the new parameter :-




Hezkore(Posted 2012) [#8]
I'll give this a test soon Col, thanks a bunch for the help.
Is there any way to make it auto detect if the fullscreen parameter is needed, so it doesn't try to capture fullscreen when there's no fullscreen window.


col(Posted 2012) [#9]
I did think of that myself and thought it would be nice if Max2D had a IsFullScreen() function, but then I realised...

From what I understand, your MaxGui fires up the emulator(s) as a seperate process? So is there a flag you can set, maybe on the command line, to start the emus in full screen?

If no, then I don't know how you would tell if that process has a screen mode that has exclusive ownership of the display or not? You'd need some kind of feedback from the emulator.

[EDIT REMOVED]

Last edited 2012


Hezkore(Posted 2012) [#10]
Yeah okay... That seems a bit overly complex.
I guess I could just assume it's always fullscreen... I mean who plays Emulators in windowmode on an Arcade machine? x_X

Thanks again Col. :)


col(Posted 2012) [#11]
I removed the suggestion anyway ;-)

I looked it up and while its more than likely possible, the vibe I got was its impossible :D

1 mo...
How are you creating the process??
As your firing up the process yourself you can get the window handle from the process handle.

Last edited 2012


Hezkore(Posted 2012) [#12]
Yeah I'm using Freeprocess to create the process.

Also, I just tested and your fullscreen capture does work very well! :)
Though there are some issues with size, because I seem to be getting very big black edges when running fullscreen in a low resolution.

EDIT: Actually, that only happened once.. it works fine now. :|

But yeah... being able to automatically get the fullscreen parameter would be good.

Last edited 2012


col(Posted 2012) [#13]
Hiya,

Here ya go :-)
After trying a hundred different ways...

[EDIT] Only seems to reliably pick up Dx windows and not so reliable with OpenGL windows!

IsFullScreen() will return if any windows are in a fullscreen state no matter how/who created them. You can use this as the third parameter with the modified chaos.dekstoppixmap([..])

Heres a version of your code with it incorporated :-


Last edited 2012


col(Posted 2012) [#14]
I should note:-

As the window will be created by a different process, be sure that the window is actually created and showing before using the IsFullScreen() test. It takes some time for windows to do its business in creating the process and window, so it's very possible that if you create the process and then immediately run IsFullScreen(), you may find that this function has finished and returned a value before windows has even had a chance to fire up the other process and create/register/show its window.

You can call IsFullScreen() as many times as you want to, it doesnt matter, just if you call it too early ( as above ) then you may get a false negative. Pretty much if you can see the window then youre ok.

Last edited 2012


Hezkore(Posted 2012) [#15]
Oh my! :o

I doubt there are any worries about using it too fast though, as the screenshot is supposed to be taken ingame, and it'll take a few second to actually get ingame.

Thanks again, and I'll give this a spin once the Guild Wars 2 beta is over, heh.

UPDATE: Wow thanks mate, this works perfectly sofar!
I am very very impressed heh. :)

I have yet to test it in few other emulators, but everything so far works.

Last edited 2012


col(Posted 2012) [#16]
Thats cool. Glad its working :-)