Giter Club home page Giter Club logo

Comments (10)

leadedge avatar leadedge commented on August 12, 2024

If you have an existing OpenGL application, you could create an OpenGL context using functions shown here line 189.

Also, instead of linking with OpenGL, you can also use DirectX shared textures directly. Have a look here.

But, similar to OpenGL, you would still need to create a DirectX device and context first. See here, line 122.

That is if you can use OpenGL or DirectX textures at that level. I am not familiar with services and not sure what access you have to the graphics driver.

If you are sending video, and you have a pixel buffer, you could look at using shared memory. There is no simple example of that but you might be able to use the "SpoutMemoryShare" class.

from spout2.

codersasha avatar codersasha commented on August 12, 2024

@leadedge , thank you for you reply. Actually, I am using the Spout DLL in my project. So I only have access to the methods exposed by the Spout DLL.

Is there a way I could verify if I have access to DirectX (instead of OpenGL) while running as a Windows service?

I'm trying to change from using SendImage to SendTexture, but can't find documentation on how to use DrawSharedTexture , BindSharedTexture, etc. I'm also not sure if this would solve the problem.

	bool SendTexture    (GLuint TextureID, GLuint TextureTarget, unsigned int width, unsigned int height, bool bInvert=true, GLuint HostFBO=0);
	bool SendImage      (const unsigned char* pixels, unsigned int width, unsigned int height, GLenum glFormat = GL_RGBA, bool bInvert=true, GLuint HostFBO = 0);
	bool ReceiveTexture (char* Sendername, unsigned int &width, unsigned int &height, GLuint TextureID = 0, GLuint TextureTarget = 0, bool bInvert = false, GLuint HostFBO=0);
	bool ReceiveImage   (char* Sendername, unsigned int &width, unsigned int &height, unsigned char* pixels, GLenum glFormat = GL_RGBA, bool bInvert = false, GLuint HostFBO=0);
	bool DrawSharedTexture(float max_x = 1.0, float max_y = 1.0, float aspect = 1.0, bool bInvert = true, GLuint HostFBO = 0);
	bool DrawToSharedTexture(GLuint TextureID, GLuint TextureTarget, unsigned int width, unsigned int height, float max_x = 1.0, float max_y = 1.0, float aspect = 1.0, bool bInvert = false, GLuint HostFBO = 0);
	bool BindSharedTexture();
	bool UnBindSharedTexture();

from spout2.

leadedge avatar leadedge commented on August 12, 2024

Sorry if this reply is a bit rambling, but I will try to answer some questions.

The beta branch has the CreateOpenGL and CloseOpenGL methods.

DrawSharedTexture and DrawToSharedTexture were created for Freeframe where the used portion of a texture can be smaller than the whole. You can see it used in the Freeframe plugin source. But these are legacy OpenGL and will be removed so I don't suggest you use them. There is an example of using BindSharedTexture etc in the beta branch here.

You might have more options by using the beta branch which is quite stable.

If you are starting with a pixel buffer, to copy into a texture the data has to be uploaded to the GPU anyway, so you probably won't gain much performance by doing that within the application instead of the functions used by SendImage.

As you say, you have to work out what you are able to do within the service. I have never had experience with this but from what I read it's not straightforward. Maybe a bit more Googling might turn something up.

I am not sure how you would verify this. Perhaps try to create an OpenGL context with "CreateOpenGL". If that works, see if you can do anything with it at all. Maybe you could do the same with DirectX. Create a device with and confirm that it succeeds, then create a test texture.

from spout2.

codersasha avatar codersasha commented on August 12, 2024

Thanks for pointing to the beta branch.

In the beta branch, the following code, running in a Windows service:

    // Initialise GLFW.
    if (glfwInit() != GLFW_TRUE) {
        fprintf(stderr, "Failed to init glfw.");
    }

    // Create an invisible 1x1 window, for a truly off-screen render.
    glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE);
    GLFWwindow* window = glfwCreateWindow(1, 1, "", NULL, NULL);
    if (window == NULL) {
        fprintf(stderr, "Failed to create OpenGL window.");
    }
    glfwMakeContextCurrent(window);

    // Check we have an OpenGL context; this is what Spout will use.
    if (!glfwGetCurrentContext()) {
        fprintf(stderr, "No OpenGL context found.");
    }

    // Create a Spout sender object.
    SPOUTHANDLE spoutSender = GetSpout();
    if (!spoutSender) {
        fprintf(stderr, "Failed to load Spout library.");
    }

    fprintf(stderr, "GetDX9? %d\n", spoutSender->GetDX9());
    fprintf(stderr, "GetMemoryShareMode? %d\n", spoutSender->GetMemoryShareMode());
    fprintf(stderr, "GetMaxSenders? %d\n", spoutSender->GetMaxSenders());
    fprintf(stderr, "GetVerticalSync? %d\n", spoutSender->GetVerticalSync());

    bool result = spoutSender->CreateOpenGL();
    fprintf(stderr, "CreateOpenGL? %d\n", result);

    fprintf(stderr, "Initializing spout sender: '%s', %dx%d\n", obj->buffer_name_.c_str(), frameWidth, frameHeight);
    // Initialize the Spout sender.
    bool bInitialized = spoutSender->CreateSender(obj->buffer_name_.c_str(), frameWidth, frameHeight);
    if (!bInitialized) {
        fprintf(stderr, "Failed to init Spout sender.");
    }

Prints:

Failed to create OpenGL window.
No OpenGL context found.
GetDX9? 0
GetMemoryShareMode? 1
GetMaxSenders? 64
GetVerticalSync? 0
CreateOpenGL? 1
Initializing spout sender: 'MySpoutBuffer', 640x480
Failed to init Spout sender.
[ WARN:1] global C:\build\master_winpack_dldt-build-win64\opencv\modules\videoio\src\cap_msmf.cpp (435) `anonymous-namespace'::SourceReaderCB::~SourceReaderCB terminating async callback

So seems to be the same error.

Is there a way I can force trying DirectX instead of OpenGL? It seems to initialize properly - createOpenGL returns true.

from spout2.

codersasha avatar codersasha commented on August 12, 2024

@leadedge - looking at https://stackoverflow.com/questions/51705471/current-state-and-solutions-for-opengl-over-windows-remote, there's some hope that DirectX is available in Windows Services, even when OpenGL is not.

The code examples you linked to are quite complicated. Is there a small snippet I could run in an isolated program to test whether Spout can work with DirectX textures when running in a Windows service.

from spout2.

codersasha avatar codersasha commented on August 12, 2024

Here's the contents from the Spout logs:

[notice]     OpenGL window created OK
[notice] Spout::OpenSpout - 64bit 2.007 - this 0xe597ea50
[error] loadGLextensions : loadFBOextensions fail
[error] spoutGLDXinterop::LoadGLextensions failed
[fatal] spoutGLDXinterop::GLDXcompatible | OpenGL extensions failed to load
[warning] Spout::OpenSpout - not texture share compatible

from spout2.

leadedge avatar leadedge commented on August 12, 2024

This shows that creation of an OpenGL window fails, so nothing else is possible. There is probably a problem with the function because it should return false.

In any case, afterwards there is no OpenGL context and the extensions fail to load so that is the end.

DirectX programs are not simple. But for a test you could try creating a device. You might be able to use the SpoutDirectX class and the function "ID3D11Device* CreateDX11device()".

If that succeeds you have some possibility to use "SpoutDX" and "OpenDirectX11()" with other functions available to create a sender or receiver. You would start by looking at the Windows examples that do not assume any DirectX support.

from spout2.

leadedge avatar leadedge commented on August 12, 2024

I think that using DirectX is the key if that is available in a service.

I have just updated the DirectX examples using SpoutDX, so have a look at Tutorial04.

There is no swapchain or rendering so all you need is a device and a shared texture. The easiest way to find out would be something like -

#include "SpoutDX.h"
spoutDX sender;
ID3D11Device* g_pd3dDevice = nullptr;

if (sender.OpenDirectX11()) {
    g_pd3dDevice = sender.GetDX11Device();
}

from spout2.

leadedge avatar leadedge commented on August 12, 2024

I can't help much more with this, so will close it now, but I remain interested in how you get on.

from spout2.

RobertWn16 avatar RobertWn16 commented on August 12, 2024

Yes, it is possible but only with DirectX using CreateProcessForUser in service code with path to your sender program. Just google it there are so many examples. In STARTUP_INFORMATION u need to set desktop as ""WinSta0\Default" because services are running in non-interactive mode and that's why the Spout fails. If I think about it, it would also be possible with OpenGL in this way and to hide the window (hwnd you can return it from opengl and then hide it). It's just an idea, it's not tested yet, so I recommend Directx (I tested and it works fine).

from spout2.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.