Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DirectX usage with Spout? #23

Closed
Vatyx opened this issue Jul 5, 2017 · 5 comments
Closed

DirectX usage with Spout? #23

Vatyx opened this issue Jul 5, 2017 · 5 comments

Comments

@Vatyx
Copy link

Vatyx commented Jul 5, 2017

I am wanting to share directx textures between CryEngine and OBS and was wanting to know if this documentation was updated for Spout2 http://spout.zeal.co/download/SpoutDirectXsdk4.pdf

I don't fully understand how the sending of the texture works. Is the shared texture handler something like a ID3D11RenderTargetView or ID3D11Texture2D? I am most likely going to have a texture with the format DXGI_FORMAT_R16G16B16A16_UNORM. Does OBS support DirectX 11 so I can use this texture?

@leadedge
Copy link
Owner

leadedge commented Jul 6, 2017

Sorry that the documentation you refer to has not been updated.

Spout OpenGL texture sharing links a DirectX shared texture with an OpenGL texture using the NVIDIA GL/DX interop functions. But you can still use the class methods to share DirectX textures directly.

Sharing of DirectX textures is done by way of a share handle which is returned when the texture is created. Another application can access the texture using this share handle. For D3D11 use "OpenSharedResource". Have a look at the function "OpenDX11shareHandle" in the SpoutDirectX class. For D3D9 you simply create a new texture with "CreateSharedDX9Texture" using the share handle.

If a sender creates a shared texture and a share handle, a receiver can access the same texture using the handle. All you do is keep updating this texture and the receiver will access it as required.

If you create a shared texture with the Spout function "CreateSharedDX11Texture" (SpoutDirectX class) you will derive a share handle (dxShareHandle), and it will have the format DXGI_FORMAT_B8G8R8A8_UNORM.

I am not sure whether DXGI_FORMAT_R16G16B16A16_UNORM is compatible with the NVIDIA OpenGL/DirectX interop extensions. The last time I tested formats I found that the only one that worked between D3D11 and D3D9 was DXGI_FORMAT_B8G8R8A8_UNORM and so that is used by default.

The 16 bit format might be OK for sharing if both applications use D3D11 and the same format. I am not familiar with OBS and I am not sure whether D3D11 is supported. I believe it supports OpenGL because there is a Syphon plugin. Do you intend to create a plugin for OBS to share your texture?

It would be good if such a plugin could be made so that other applications could share with OBS using Spout.

Edit: I looked at OBS and there is a folder "libobs-d3d11" and a file "d3d11-texture2d.cpp". There is also a folder "libobs-opengl" and a file "gl-texture2d.c", so it seems that support is there for both.

@Vatyx
Copy link
Author

Vatyx commented Jul 18, 2017

Thanks for the response. I've been reading it over and over again the past few days.

Within Lumberyard I am creating a texture that I am rendering. I've now given it the RESOURCE_MISC_SHARED flag which I am assuming is the only special flag it needs. I am wanting to show this texture in OBS using the Spout Cam which shows up in OBS as a virtual webcam.

If I pass a DX11 shared handler to Spout, do I have to use mutexes in order to do so or can I just pass it like normal. Will a DX11 texture automatically work with the webcam that's already in OBS if I am just using the CreateSender which only takes in a handle?

For updating a new texture, it seems that UpdateSender is called each time with the same texture handler. Is that how updating should be?

@leadedge
Copy link
Owner

The D3D11_RESOURCE_MISC_SHARED flag is one of the requirements but there are other limitations. Look at "CreateSharedDX11Texture" in SpoutDirectX.cpp to see how a shared DirectX 11 texture is created within Spout.

You then use the texture pointer as the "share handle" when you create a Spout sender. All Spout receivers will have immediate access to your shared texture.

After you have created the sender, you should see it listed by running the Spout demo receiver. You can do this for testing regardless of whether you have created a shared texture (as long as you don't select the sender).

A mutex is advisable to control access to the texture. Otherwise it is possible that your sender and multiple receivers could access the texture at the same time which might cause problems. But you can try without a mutex and see how it goes. At least this is the first thing to do to test the function of your program.

You might get some ideas from the Unity plugin :

https://github.com/sloopidoopi/Spout4Unity/blob/master/NativeSpoutPlugin/src/NativeSpoutPlugin.cpp

This gets away without using a mutex, so you might be OK without it. There is some control by the GL/DX interop functions which have a lock before the interop is activated. The mutex is on top of that.

If your texture is received by the Spout demo sender, and you know that SpoutCam works within OBS then SpoutCam will pick it up OK.

If you update your texture dimensions or create a new texture, you need to call UpdateSender. Otherwise the texture pointer remains the same so sender update is not necessary. Receivers will access whatever the texture contains.

@leadedge
Copy link
Owner

Recently I had another look at the UE4 plugin by AleDel -

https://github.com/AleDel/Spout-UE4

This uses DirectX textures and I believe that it is a good example for you to examine.

Let me know here how you are progressing. I will close this issue if there is nothing more to add.

@Vatyx
Copy link
Author

Vatyx commented Aug 14, 2017

Sorry I should have said something after your last comment. I was able to figure it out with what you said. I only used SpoutSenderNames and SpoutSharedMemory and that was enough to successfully shared a DirectX 11 texture to OBS. R16G16B16A16_FLOAT works as well with OBS.

Thanks for the help, it was invaluable.

@Vatyx Vatyx closed this as completed Aug 14, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants