-
Notifications
You must be signed in to change notification settings - Fork 8
How to create and initialize a Direct3D Device #11
Comments
There are a few example of how to get a |
Thanks a lot! That is helpful! |
I found https://github.com/robmikh/screenshot-rs that shows how to use this in Rust, but is uses Win32 APIs that aren't available in Python. If there is some sort of Python GUI library that uses Direct3D already, it may be possible to add some interop to connect it to this library. But, I couldn't find any other than a very old, unmaintained DirectPython library. I also found https://github.com/SerpentAI/D3DShot which may already do what you want. It uses |
I stumbled on D3DShot does seem to obtain an import ctypes
import win32gui
from d3dshot.dll.d3d import initialize_d3d_device
from winsdk.windows.graphics.capture import Direct3D11CaptureFramePool
from winsdk.windows.graphics.capture.interop import create_for_window
from winsdk.windows.graphics.directx import DirectXPixelFormat
def print_hwnd(hwnd: int, _):
window_text = win32gui.GetWindowText(hwnd)
if (
window_text
and window_text not in ("Default IME", "MSCTFIME UI")
and "Window" not in window_text
):
print(hwnd, window_text)
win32gui.EnumWindows(print_hwnd, '')
while True:
try:
hwnd = int(input("^ Enter an HWND from above ^ :"))
except:
print("not an int")
continue
try:
print("Selected window:", win32gui.GetWindowText(hwnd))
except:
print("not a valid HWND")
continue
graphics_capture_item = create_for_window(hwnd)
d3d_device_pointer = initialize_d3d_device(None)[0]
d3d_device = ctypes.byref(d3d_device_pointer)
test = Direct3D11CaptureFramePool.create_free_threaded(
d3d_device, # or directly d3dshot.create().displays[0].d3d_device
DirectXPixelFormat.B8_G8_R8_A8_UINT_NORMALIZED,
1,
graphics_capture_item.size) reuslts in
Microsoft documentation and examples use a |
For the record, D3DShot is dead and has been archived. |
Did anyone manage to find a solution? |
@lnfecteDru I had someone recommend the device from So I went with an hybrid approach just in case a user was using an older build: import asyncio
from winsdk.windows.ai.machinelearning import LearningModelDevice, LearningModelDeviceKind
from winsdk.windows.media.capture import MediaCapture
def get_direct3d_device():
try:
direct_3d_device = LearningModelDevice(LearningModelDeviceKind.DIRECT_X_HIGH_PERFORMANCE).direct3_d11_device
except: # TODO: Unknown potential error, I don't have an older Win10 machine to test.
direct_3d_device = None
if not direct_3d_device:
# Note: Must create in the same thread (can't use a global) otherwise when ran from not the main thread it will raise:
# OSError: The application called an interface that was marshalled for a different thread
media_capture = MediaCapture()
async def coroutine():
await (media_capture.initialize_async() or asyncio.sleep(0))
asyncio.run(coroutine())
direct_3d_device = media_capture.media_capture_settings and \
media_capture.media_capture_settings.direct3_d11_device
if not direct_3d_device:
raise OSError("Unable to initialize a Direct3D Device.")
return direct_3d_device
def try_get_direct3d_device():
try:
return get_direct3d_device()
except OSError:
return None |
@Avasam Looks like it works for me. Thank you for your response! |
In my case, using When I use it for the capture pool, the frames I get from calling I tried calling |
Is there a way to release framepool buffer now? |
Sorry my english is not good.
My python version is 3.7.3, system is windows10.
I am try to record the screen.
I have already get the item by using "pick_single_item_async", and then I want to create a frame pool by "Direct3D11CaptureFramePool.create_free_threaded", but I don't know how to get the first argument whose type is IDirect3DDevice.
I find a way to get a D3D device by MediaCapture, and I can create a frame pool:
but I got an error in line "await async_action":
what should I do to create a frame pool.
Thanks a lot!
The text was updated successfully, but these errors were encountered: