diff --git a/Library/SpoutSDK.pyd b/Library/SpoutSDK.pyd index a8b0bfa..d1821d8 100644 Binary files a/Library/SpoutSDK.pyd and b/Library/SpoutSDK.pyd differ diff --git a/README.md b/README.md index 75d84c6..31f71b9 100644 --- a/README.md +++ b/README.md @@ -1,64 +1,70 @@ # Spout for Python A modified Spout library using Boost::Python to enable Spout texture sharing using Python. -![Spout for Python](https://raw.githubusercontent.com/spiraltechnica/Spout-for-Python/master/Images/neural%20style%20resolume.png) -This library is for use with Python 3.5 64bit. - -It was built against Boost 1.65 and Python 3.5.2-amd64 using Visual Studio 2015 on Windows 10 64bit -The Visual Studio solution depends on: +![Spout for Python](https://raw.githubusercontent.com/spiraltechnica/Spout-for-Python/master/Images/neural%20style%20resolume.png) -- Boost being located in C:\Program Files\boost_1_65_0 and +This library is for use with Python 3.7 64bit. -- Python 3.5 64bit being located in %UserProfile%\AppData\Local\Programs\Python\Python35\include +It was built against Boost 1.69 and Python 3.7.2-amd64 using Visual Studio 2017 on Windows 10 64bit -This modified library does not yet fully implement the functionality available in the SpoutSDK. +This modified library does not yet fully implement the functionality available in the SpoutSDK. ## Using the Library -The SpoutSDK.pyd library is located in the [Library/](Library/) folder of this repository. The example files are in the [Examples/](Examples/) folder. +The SpoutSDK.pyd library is located in the [Library/](Library/) folder of this repository. The example files are in the [Examples/](Examples/) folder. -You shouldn't need to compile Boost or have Visual Studio installed to run these examples and integrate the library into your own Python projects - -And of course, if you don't have Spout installed, you'll definitely need to get it and install it. It's available at http://spout.zeal.co/ +You shouldn't need to compile Boost or have Visual Studio installed to run these examples and integrate the library into your own Python projects, but you'll definitely need to install [Spout](http://spout.zeal.co/). ## Examples Take a look in the [Examples/](Examples/) folder for a list of python scripts that can interface with the modified SpoutSDK.pyd library. -The simplest example file is ```hello.py```. This merely attempts to import the library, create an instance of a Spout Sender, and call a function that returns text into the console. +The simplest example file is ```hello.py```. This merely attempts to import the library, create an instance of a Spout Sender, and call a function that returns text into the console. The example scripts ```spout_NST_receiver.py``` and ```spout_NST_sender_receiver.py``` will not run by themselves, because they are designed to work with Tensorflow Fast Style Transfer, located at https://github.com/hwalsuklee/tensorflow-fast-style-transfer ### Running the Examples -A number of the examples will require libraries not in the base Python 3.5 install. That base install is available at https://www.python.org/downloads/release/python-352/ +A number of the examples will require libraries not in the base Python 3.7 install. That base install is available at https://www.python.org/ftp/python/3.7.2/python-3.7.2-amd64.exe You'll need -- numpy-1.13.1+mkl-cp35-cp35m-win_amd64.whl -- opencv_python-3.3.0-cp35-cp35m-win_amd64.whl -- pygame-1.9.3-cp35-cp35m-win_amd64.whl -From the Unofficial Windows Binaries for Python Extension Packages at http://www.lfd.uci.edu/~gohlke/pythonlibs/ +- numpy 1.16.2 +- opencv-python 4.0.0.21 +- pygame 1.9.4 +- PyOpenGL 3.1.0 -Install them using the pip3 manager that comes with Python 3.5, using the ```pip install ``` command from the command line. +Install them using the pip manager that comes with Python 3.7, using the ```pip install ``` command from the command line. -In addition to the aforementioned packages, you'll need PyOpenGL from the pip default repositories: -- Install using ```pip install PyOpenGL``` command. The version I'm using is PyOpenGL 3.1.0 - It would be also worth installing Pillow with ```pip install Pillow```. I'm using Pillow 4.2.1 ## Building Boost -- Download the Boost 1.65 source for windows from http://www.boost.org/users/history/version_1_65_0.html -- Extract to C:\Program Files\boost_1_65_0 +Requires the prior installation of [MS Visual Studio 17](https://visualstudio.microsoft.com/de/vs/) Community Edition. + +- Download the Boost 1.69 source for windows from https://www.boost.org/users/history/version_1_69_0.html +- Extract to C:\Program Files\boost_1_69_0 - Open an Administrative access Command Prompt (right click on Command Prompt and Run As Administrator) -- cd into C:\Program Files\boost_1_65_0 +- cd into C:\Program Files\boost_1_69_0 - Type ```boostrap.bat``` and run the command -- Now run ```.\b2.exe --stagedir=./stage/x64 address-model=64 --build-type=complete --toolset=msvc-14.0 --threading=multi --runtime-link=shared --variant=debug``` -This will take some time. Once it's complete run -- ```.\b2.exe --stagedir=./stage/x64 address-model=64 --build-type=complete --toolset=msvc-14.0 --threading=multi --runtime-link=shared --variant=release``` +- Now run ```.\b2.exe --stagedir=./stage/x64 address-model=64 --build-type=complete --toolset=msvc-14.1 --threading=multi --runtime-link=shared --variant=debug``` + +This will take some time creating the debug libraries. Once it's complete run +- ```.\b2.exe --stagedir=./stage/x64 address-model=64 --build-type=complete --toolset=msvc-14.1 --threading=multi --runtime-link=shared --variant=release``` + +Which most likely will take much less time to create the release libraries. However, it should say it is successfully built at the end and give you locations for linker library include paths and compiler include paths. You only need them if you decided to extract and build boost at a different location. + +## Building the DLL rsp. PYD + +The Visual Studio solution depends on: + +- Boost being located in C:\Program Files\boost_1_69_0 and + +- Python 3.7 64bit being located in %UserProfile%\AppData\Local\Programs\Python\Python37\include -Which will also take some time. However, it should say it is successfully built at the end and give you locations for linker library include paths and compiler include paths. +With Boost and Python installed you should now be able to use Visual Studio 2017 and build the ```SpoutSDK.dll``` for 64bit architecture in Debug and Release modes. In order to interface the dll with Python, rename the dll from ```SpoutSDK.dll``` to ```SpoutSDK.pyd```. -## Building the DLL +## Credits -With Boost and Python installed you should now be able to use Visual Studio 2015 and build the ```SpoutSDK.dll``` for 64bit architecture in Debug and Release modes. In order to interface the dll with Python, rename the dll from ```SpoutSDK.dll``` to ```SpoutSDK.pyd```. +- Ryan Walker (http://www.spiraltechnica.com/) +- Martin Froehlich (http://tecartlab.com) diff --git a/SpoutSDK/SpoutSDK/Spout.h b/SpoutSDK/SpoutSDK/Spout.h index 2e141fc..9e78a02 100644 --- a/SpoutSDK/SpoutSDK/Spout.h +++ b/SpoutSDK/SpoutSDK/Spout.h @@ -1,11 +1,41 @@ +/* + + Spout.h + + The main Spout include file for the SDK + + Copyright (c) 2014-2017, Lynn Jarvis. All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, + are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +*/ #pragma once + #ifndef __Spout__ #define __Spout__ - #include "SpoutSender.h" #include "SpoutReceiver.h" // All documentation in the SDK pdf = SpoutSDK.pdf -#endif \ No newline at end of file +#endif diff --git a/SpoutSDK/SpoutSDK/SpoutDirectX.cpp b/SpoutSDK/SpoutSDK/SpoutDirectX.cpp index 1fb857c..a4b9c5f 100644 --- a/SpoutSDK/SpoutSDK/SpoutDirectX.cpp +++ b/SpoutSDK/SpoutSDK/SpoutDirectX.cpp @@ -33,12 +33,13 @@ // 04.09.16 - Add create DX11 staging texture // 16.01.17 - Add WriteDX9surface // 23.01.17 - pEventQuery->Release() for writeDX9surface -// 24.04.17 - Added MessageBox error warnings in CreateSharedDX11Texture +// 24.04.17 - Add MessageBox error warnings in CreateSharedDX11Texture +// 11.11.18 - Add GetImmediateContext() // // ==================================================================================== /* - Copyright (c) 2014-2017. Lynn Jarvis. All rights reserved. + Copyright (c) 2014-2018. Lynn Jarvis. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -345,6 +346,11 @@ ID3D11Device* spoutDirectX::CreateDX11device() } // end CreateDX11device +ID3D11DeviceContext* spoutDirectX::GetImmediateContext() +{ + return g_pImmediateContext; +} + bool spoutDirectX::CreateSharedDX11Texture(ID3D11Device* pd3dDevice, unsigned int width, @@ -783,7 +789,6 @@ bool spoutDirectX::FindNVIDIA(int &nAdapter) if(bFound) { printf("Found NVIDIA adapter %d (%S)\n", i, desc.Description); nAdapter = i; - // LJ DEBUG // 0x10DE NVIDIA // 0x163C intel // 0x8086 Intel diff --git a/SpoutSDK/SpoutSDK/SpoutDirectX.h b/SpoutSDK/SpoutSDK/SpoutDirectX.h index ef5e2f9..c529cd4 100644 --- a/SpoutSDK/SpoutSDK/SpoutDirectX.h +++ b/SpoutSDK/SpoutSDK/SpoutDirectX.h @@ -61,6 +61,7 @@ class SPOUT_DLLEXP spoutDirectX { // DX11 ID3D11Device* CreateDX11device(); // Create a DX11 device + ID3D11DeviceContext* GetImmediateContext(); bool CreateSharedDX11Texture(ID3D11Device* pDevice, unsigned int width, unsigned int height, DXGI_FORMAT format, ID3D11Texture2D** pSharedTexture, HANDLE &dxShareHandle); bool CreateDX11StagingTexture(ID3D11Device* pDevice, unsigned int width, unsigned int height, DXGI_FORMAT format, ID3D11Texture2D** pStagingTexture); bool OpenDX11shareHandle(ID3D11Device* pDevice, ID3D11Texture2D** ppSharedTexture, HANDLE dxShareHandle); @@ -86,6 +87,8 @@ class SPOUT_DLLEXP spoutDirectX { // For debugging only - to toggle texture access locks disable/enable bool bUseAccessLocks; + + protected: IDXGIAdapter* GetAdapterPointer(int index); // Get adapter pointer for DirectX 11 diff --git a/SpoutSDK/SpoutSDK/SpoutGLDXinterop.cpp b/SpoutSDK/SpoutSDK/SpoutGLDXinterop.cpp index 002c48f..64d230b 100644 --- a/SpoutSDK/SpoutSDK/SpoutGLDXinterop.cpp +++ b/SpoutSDK/SpoutSDK/SpoutGLDXinterop.cpp @@ -6,7 +6,7 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Copyright (c) 2014-2017, Lynn Jarvis. All rights reserved. + Copyright (c) 2014-2018, Lynn Jarvis. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -191,6 +191,9 @@ - CleanupDX9 change to prevent crash with Milkdrop - add pQuery->Release() to FlushWait 04.02.17 - corrected test for fbo blit extension + 11.11.18 - Correct release of DX11 immediate context + TODO : DX9 leak checking + 12.11.18 - Always release DX9 device. Fix Milkdrop crash. */ @@ -460,6 +463,8 @@ bool spoutGLDXinterop::OpenDirectX11() if(g_pd3dDevice == NULL) { return false; } + // 11.11.18 + g_pImmediateContext = spoutdx.GetImmediateContext(); return true; } @@ -477,8 +482,16 @@ bool spoutGLDXinterop::DX11available() if(pd3dDevice == NULL) return false; + // 11.11.18 + // Clear state and flush context to prevent deferred device release + spoutdx.GetImmediateContext()->ClearState(); + spoutdx.GetImmediateContext()->Flush(); + // Release the global immediate context in SpoutDirectX + spoutdx.GetImmediateContext()->Release(); + // Close it because not initialized yet and is just a test - pd3dDevice->Release(); + ULONG refcount = pd3dDevice->Release(); + // printf("DX11available - device release refcount = %ld\n", refcount); return true; } @@ -634,7 +647,7 @@ bool spoutGLDXinterop::CreateInterop(HWND hWnd, const char* sendername, unsigned // Needs an openGL context to work if(!wglGetCurrentContext()) { - MessageBoxA(NULL, "CreateInterop - no GL context", "SPOUT", MB_OK|MB_ICONEXCLAMATION); + // MessageBoxA(NULL, "CreateInterop - no GL context", "SPOUT", MB_OK|MB_ICONEXCLAMATION); return false; } @@ -966,8 +979,8 @@ bool spoutGLDXinterop::CreateDX11interop(unsigned int width, unsigned int height g_pStagingTexture->Release(); g_pStagingTexture = NULL; // Flush is needed or there is a GPU memory leak - if (!g_pImmediateContext) g_pd3dDevice->GetImmediateContext(&g_pImmediateContext); - if (g_pImmediateContext) g_pImmediateContext->Flush(); + if (g_pImmediateContext) + g_pImmediateContext->Flush(); } if(!spoutdx.CreateDX11StagingTexture(g_pd3dDevice, width, height, DX11format, &g_pStagingTexture)) { printf(" DX11 create staging texture failed\n"); @@ -1065,6 +1078,8 @@ void spoutGLDXinterop::CleanupDirectX(bool bExit) void spoutGLDXinterop::CleanupDX9(bool bExit) { + ULONG refcount = 0; + if (m_pD3D != NULL) { // 01.09.14 - texture release was missing for a receiver - caused a VRAM leak // If an existing texture exists, CreateTexture can fail with and "unknown error" @@ -1080,44 +1095,60 @@ void spoutGLDXinterop::CleanupDX9(bool bExit) g_DX9surface = NULL; } - if (bExit) { + // if (bExit) { // 25.08.15 - release device before the object ! // 22.01.17 - will crash if refcount is 1 for MilkDrop. TODO - why - /* - if (m_pDevice != NULL) - m_pDevice->Release(); - */ + // 12.11.18 - must always be freed, not only on exit. Device recreated for a new sender. + if (m_pDevice != NULL) + refcount = m_pDevice->Release(); + if (m_pD3D != NULL) - m_pD3D->Release(); + refcount = m_pD3D->Release(); + // printf("DX9 release - refcount = %d\n", refcount); + m_pDevice = NULL; m_pD3D = NULL; - } + // } + } } void spoutGLDXinterop::CleanupDX11(bool bExit) { + + // printf("CleanupDX11 - g_pd3dDevice = %d\n", g_pd3dDevice); + if (g_pd3dDevice != NULL) { - if (!g_pImmediateContext) g_pd3dDevice->GetImmediateContext(&g_pImmediateContext); if (g_pSharedTexture != NULL) { g_pSharedTexture->Release(); g_pSharedTexture = NULL; // 14.07.16 - flush is needed or there is a GPU memory leak - if (g_pImmediateContext) g_pImmediateContext->Flush(); + if (g_pImmediateContext) + g_pImmediateContext->Flush(); } // DX11 staging texture if(g_pStagingTexture != NULL) { g_pStagingTexture->Release(); g_pStagingTexture = NULL; - if (g_pImmediateContext) g_pImmediateContext->Flush(); + if (g_pImmediateContext) + g_pImmediateContext->Flush(); } - if (bExit) { + // 11.11.18 - release device + // if (bExit) { + // Clear state and flush context to prevent deferred device release + if (g_pImmediateContext) { + g_pImmediateContext->ClearState(); + g_pImmediateContext->Flush(); + // Release the global immediate context in SpoutDirectX + g_pImmediateContext->Release(); + g_pImmediateContext = NULL; + } g_pd3dDevice->Release(); g_pd3dDevice = NULL; - } + // } } } @@ -1749,7 +1780,7 @@ bool spoutGLDXinterop::ReadGLDXtexture(GLuint TextureID, GLuint TextureTarget, u glBindTexture(TextureTarget, 0); } } - else { + else { PrintFBOstatus(status); } @@ -1906,6 +1937,10 @@ bool spoutGLDXinterop::DrawToGLDXtexture(GLuint TextureID, GLuint TextureTarget, // Bind our fbo and attach the shared texture to it glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo); + + glClearColor(0.0f, 0.0f, 0.0f, 0.0f); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glFramebufferTexture2DEXT(GL_READ_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, m_glTexture, 0); status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); @@ -1947,7 +1982,6 @@ bool spoutGLDXinterop::DrawToGLDXtexture(GLuint TextureID, GLuint TextureTarget, glBindTexture(TextureTarget, 0); glDisable(TextureTarget); - } else { PrintFBOstatus(status); @@ -2038,12 +2072,10 @@ bool spoutGLDXinterop::WriteTexture(ID3D11Texture2D** texture) return false; } - if(!g_pImmediateContext) - g_pd3dDevice->GetImmediateContext(&g_pImmediateContext); - // Wait for access to the texture if(spoutdx.CheckAccess(m_hAccessMutex)) { - g_pImmediateContext->CopyResource(g_pSharedTexture, *texture); + if(g_pImmediateContext) + g_pImmediateContext->CopyResource(g_pSharedTexture, *texture); // Wait for access to the shared texture sor the receiver can read it straight away FlushWait(); spoutdx.AllowAccess(m_hAccessMutex); // Allow access to the texture @@ -2071,11 +2103,9 @@ bool spoutGLDXinterop::ReadTexture(ID3D11Texture2D** texture) return false; } - if(!g_pImmediateContext) - g_pd3dDevice->GetImmediateContext(&g_pImmediateContext); - if(spoutdx.CheckAccess(m_hAccessMutex)) { - g_pImmediateContext->CopyResource(*texture, g_pSharedTexture); + if(g_pImmediateContext) + g_pImmediateContext->CopyResource(*texture, g_pSharedTexture); spoutdx.AllowAccess(m_hAccessMutex); // Allow access to the texture return true; } @@ -2106,25 +2136,25 @@ void spoutGLDXinterop::FlushWait() // the flush and wait is necessary. For WriteTexture "the copy has not necessarily executed // by the time the method returns". The sender has to ensure that the copy is complete so // that the receiver will get the new frame. - if(!g_pImmediateContext) - g_pd3dDevice->GetImmediateContext(&g_pImmediateContext); - g_pImmediateContext->Flush(); - - // For a receiver, make sure that the GPU is finished processing commands before accessing the - // staging texture and before the sender fills the shared texture again on the next frame. - // For a sender, make sure the CopyResource fnction has completed before the receiver application - // accesses the shared texture. - // https://msdn.microsoft.com/en-us/library/windows/desktop/ff476578%28v=vs.85%29.aspx - ZeroMemory(&queryDesc, sizeof(queryDesc)); - queryDesc.Query = D3D11_QUERY_EVENT; - // When the GPU is finished, ID3D11DeviceContext::GetData will return S_OK. - // When using this type of query, ID3D11DeviceContext::Begin is disabled. - ZeroMemory(&queryDesc, sizeof(queryDesc)); - queryDesc.Query = D3D11_QUERY_EVENT; - g_pd3dDevice->CreateQuery(&queryDesc, &pQuery); - g_pImmediateContext->End(pQuery); - while( S_OK != g_pImmediateContext->GetData(pQuery, NULL, 0, 0)); - pQuery->Release(); + if(g_pImmediateContext) { + g_pImmediateContext->Flush(); + + // For a receiver, make sure that the GPU is finished processing commands before accessing the + // staging texture and before the sender fills the shared texture again on the next frame. + // For a sender, make sure the CopyResource fnction has completed before the receiver application + // accesses the shared texture. + // https://msdn.microsoft.com/en-us/library/windows/desktop/ff476578%28v=vs.85%29.aspx + ZeroMemory(&queryDesc, sizeof(queryDesc)); + queryDesc.Query = D3D11_QUERY_EVENT; + // When the GPU is finished, ID3D11DeviceContext::GetData will return S_OK. + // When using this type of query, ID3D11DeviceContext::Begin is disabled. + ZeroMemory(&queryDesc, sizeof(queryDesc)); + queryDesc.Query = D3D11_QUERY_EVENT; + g_pd3dDevice->CreateQuery(&queryDesc, &pQuery); + g_pImmediateContext->End(pQuery); + while( S_OK != g_pImmediateContext->GetData(pQuery, NULL, 0, 0)); + pQuery->Release(); + } } @@ -2334,59 +2364,60 @@ bool spoutGLDXinterop::WriteDX11texture (GLuint TextureID, GLuint TextureTarget, // Copy OpenGL texture pixels to the staging texture // - // Get context - if(!g_pImmediateContext) g_pd3dDevice->GetImmediateContext(&g_pImmediateContext); - // Get a pointer to the staging texture data - hr = g_pImmediateContext->Map(g_pStagingTexture, 0, D3D11_MAP_WRITE, 0, &mappedSubResource); - if(SUCCEEDED(hr)) { - // Copy the user OpenGL texture data directly to the staging texture - if(IsPBOavailable()) { // PBO method - UnloadTexturePixels(TextureID, TextureTarget, width, height, (unsigned char *)mappedSubResource.pData, GL_BGRA_EXT, bInvert, HostFBO); - } - else { - if(bInvert) { - // Create or resize a local OpenGL texture - CheckOpenGLTexture(m_TexID, GL_RGBA, width, height, m_TexWidth, m_TexHeight); - // Copy the user texture to the local texture - necessary for inversion - CopyTexture(TextureID, TextureTarget, m_TexID, GL_TEXTURE_2D, width, height, bInvert, HostFBO); - // Bind our local fbo - current fbo has to be passed in - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo); - // Attach the local rgba texture to the color buffer in our frame buffer - glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, m_TexID, 0); - GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); - if(status == GL_FRAMEBUFFER_COMPLETE_EXT) { - // read the pixels from the OpenGL framebuffer into the BGRA DX11 texture - glReadPixels(0, 0, width, height, GL_BGRA_EXT, GL_UNSIGNED_BYTE, mappedSubResource.pData); - } - else { - PrintFBOstatus(status); - } - // restore the previous fbo - default is 0 - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, HostFBO); + if(g_pImmediateContext) { + // Get a pointer to the staging texture data + hr = g_pImmediateContext->Map(g_pStagingTexture, 0, D3D11_MAP_WRITE, 0, &mappedSubResource); + if(SUCCEEDED(hr)) { + // Copy the user OpenGL texture data directly to the staging texture + if(IsPBOavailable()) { // PBO method + UnloadTexturePixels(TextureID, TextureTarget, width, height, (unsigned char *)mappedSubResource.pData, GL_BGRA_EXT, bInvert, HostFBO); } else { - // No invert so use the user texture - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo); - // Attach the user rgba texture to the color buffer in our frame buffer - glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, TextureTarget, TextureID, 0); - GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); - if(status == GL_FRAMEBUFFER_COMPLETE_EXT) { - // read the pixels from the OpenGL framebuffer into the BGRA DX11 texture - glReadPixels(0, 0, width, height, GL_BGRA_EXT, GL_UNSIGNED_BYTE, mappedSubResource.pData); + if(bInvert) { + // Create or resize a local OpenGL texture + CheckOpenGLTexture(m_TexID, GL_RGBA, width, height, m_TexWidth, m_TexHeight); + // Copy the user texture to the local texture - necessary for inversion + CopyTexture(TextureID, TextureTarget, m_TexID, GL_TEXTURE_2D, width, height, bInvert, HostFBO); + // Bind our local fbo - current fbo has to be passed in + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo); + // Attach the local rgba texture to the color buffer in our frame buffer + glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, m_TexID, 0); + GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); + if(status == GL_FRAMEBUFFER_COMPLETE_EXT) { + // read the pixels from the OpenGL framebuffer into the BGRA DX11 texture + glReadPixels(0, 0, width, height, GL_BGRA_EXT, GL_UNSIGNED_BYTE, mappedSubResource.pData); + } + else { + PrintFBOstatus(status); + } + // restore the previous fbo - default is 0 + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, HostFBO); } else { - PrintFBOstatus(status); + // No invert so use the user texture + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo); + // Attach the user rgba texture to the color buffer in our frame buffer + glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, TextureTarget, TextureID, 0); + GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); + if(status == GL_FRAMEBUFFER_COMPLETE_EXT) { + // read the pixels from the OpenGL framebuffer into the BGRA DX11 texture + glReadPixels(0, 0, width, height, GL_BGRA_EXT, GL_UNSIGNED_BYTE, mappedSubResource.pData); + } + else { + PrintFBOstatus(status); + } } } - } - g_pImmediateContext->Unmap(g_pStagingTexture, 0); + g_pImmediateContext->Unmap(g_pStagingTexture, 0); - // Write the staging texture to the shared texture - return WriteTexture(&g_pStagingTexture); + // Write the staging texture to the shared texture + return WriteTexture(&g_pStagingTexture); + } } // endif DX11 map OK return false; + } // end WriteDX11texture @@ -2420,36 +2451,37 @@ bool spoutGLDXinterop::ReadDX11texture (GLuint TextureID, if(ReadTexture(&g_pStagingTexture)) { FlushWait(); // Wait for access to the staging texture // Map the staging texture resource to access the pixels - if(!g_pImmediateContext) g_pd3dDevice->GetImmediateContext(&g_pImmediateContext); - hr = g_pImmediateContext->Map(g_pStagingTexture, 0, D3D11_MAP_READ, 0, &mappedSubResource); - if(SUCCEEDED(hr)) { - // Get a pointer to the staging texture data - dataPointer = mappedSubResource.pData; - if(dataPointer) { - if(IsPBOavailable()) { // PBO method - LoadTexturePixels(TextureID, TextureTarget, width, height, (const unsigned char *)dataPointer, GL_BGRA_EXT, bInvert); - } - else { - if(bInvert) { - // Create or resize a local OpenGL texture - CheckOpenGLTexture(m_TexID, GL_RGBA, width, height, m_TexWidth, m_TexHeight); - // Copy the DX11 pixels to it - glBindTexture(GL_TEXTURE_2D, m_TexID); - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_BGRA_EXT, GL_UNSIGNED_BYTE, dataPointer); - glBindTexture(GL_TEXTURE_2D, 0); - // Copy the local texture to the user texture and invert as necessary - CopyTexture(m_TexID, GL_TEXTURE_2D, TextureID, TextureTarget, width, height, bInvert, HostFBO); + if(g_pImmediateContext) { + hr = g_pImmediateContext->Map(g_pStagingTexture, 0, D3D11_MAP_READ, 0, &mappedSubResource); + if(SUCCEEDED(hr)) { + // Get a pointer to the staging texture data + dataPointer = mappedSubResource.pData; + if(dataPointer) { + if(IsPBOavailable()) { // PBO method + LoadTexturePixels(TextureID, TextureTarget, width, height, (const unsigned char *)dataPointer, GL_BGRA_EXT, bInvert); } else { - // Copy the DX11 pixels to the user texture - glBindTexture(TextureTarget, TextureID); - glTexSubImage2D(TextureTarget, 0, 0, 0, width, height, GL_BGRA_EXT, GL_UNSIGNED_BYTE, dataPointer); - glBindTexture(TextureTarget, 0); + if(bInvert) { + // Create or resize a local OpenGL texture + CheckOpenGLTexture(m_TexID, GL_RGBA, width, height, m_TexWidth, m_TexHeight); + // Copy the DX11 pixels to it + glBindTexture(GL_TEXTURE_2D, m_TexID); + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_BGRA_EXT, GL_UNSIGNED_BYTE, dataPointer); + glBindTexture(GL_TEXTURE_2D, 0); + // Copy the local texture to the user texture and invert as necessary + CopyTexture(m_TexID, GL_TEXTURE_2D, TextureID, TextureTarget, width, height, bInvert, HostFBO); + } + else { + // Copy the DX11 pixels to the user texture + glBindTexture(TextureTarget, TextureID); + glTexSubImage2D(TextureTarget, 0, 0, 0, width, height, GL_BGRA_EXT, GL_UNSIGNED_BYTE, dataPointer); + glBindTexture(TextureTarget, 0); + } } } + g_pImmediateContext->Unmap(g_pStagingTexture, 0); + return true; } - g_pImmediateContext->Unmap(g_pStagingTexture, 0); - return true; } // endif DX11 map OK } // endif ReadTexture OK return false; @@ -2482,32 +2514,33 @@ bool spoutGLDXinterop::WriteDX11pixels (const unsigned char *pixels, return false; // Copy the pixels to the staging texture - if(!g_pImmediateContext) g_pd3dDevice->GetImmediateContext(&g_pImmediateContext); - hr = g_pImmediateContext->Map(g_pStagingTexture, 0, D3D11_MAP_WRITE, 0, &mappedSubResource); - if(SUCCEEDED(hr)) { - // Get a pointer to the staging texture data - dataPointer = mappedSubResource.pData; - if(dataPointer) { - // Write the user pixel buffer to the staging texture - switch(glFormat) { - case GL_BGRA_EXT: // direct copy - spoutcopy.CopyPixels(pixels, (unsigned char *)dataPointer, width, height, GL_RGBA, bInvert); - break; - case GL_RGBA: // Convert the rgba pixels to bgra for the DX11 texture - spoutcopy.rgba2bgra((void *)pixels, dataPointer, width, height, bInvert); - break; - case GL_RGB: // Convert the rgb pixels to bgra for the DX11 texture - spoutcopy.rgb2bgra((void *)pixels, dataPointer, width, height, bInvert); - break; - case GL_BGR_EXT: // Convert the bgr pixels to bgra for the DX11 texture - spoutcopy.bgr2bgra((void *)pixels, dataPointer, width, height, bInvert); - break; - default: - break; + if(g_pImmediateContext) { + hr = g_pImmediateContext->Map(g_pStagingTexture, 0, D3D11_MAP_WRITE, 0, &mappedSubResource); + if(SUCCEEDED(hr)) { + // Get a pointer to the staging texture data + dataPointer = mappedSubResource.pData; + if(dataPointer) { + // Write the user pixel buffer to the staging texture + switch(glFormat) { + case GL_BGRA_EXT: // direct copy + spoutcopy.CopyPixels(pixels, (unsigned char *)dataPointer, width, height, GL_RGBA, bInvert); + break; + case GL_RGBA: // Convert the rgba pixels to bgra for the DX11 texture + spoutcopy.rgba2bgra((void *)pixels, dataPointer, width, height, bInvert); + break; + case GL_RGB: // Convert the rgb pixels to bgra for the DX11 texture + spoutcopy.rgb2bgra((void *)pixels, dataPointer, width, height, bInvert); + break; + case GL_BGR_EXT: // Convert the bgr pixels to bgra for the DX11 texture + spoutcopy.bgr2bgra((void *)pixels, dataPointer, width, height, bInvert); + break; + default: + break; + } + // Unmap and copy the staging texture resource to the shared texture + g_pImmediateContext->Unmap(g_pStagingTexture, 0); + return WriteTexture(&g_pStagingTexture); } - // Unmap and copy the staging texture resource to the shared texture - g_pImmediateContext->Unmap(g_pStagingTexture, 0); - return WriteTexture(&g_pStagingTexture); } // endif pointer OK } // endif DX11 map OK return false; @@ -2542,30 +2575,31 @@ bool spoutGLDXinterop::ReadDX11pixels (unsigned char *pixels, if(ReadTexture(&g_pStagingTexture)) { FlushWait(); // Wait for access to the staging texture // Map the resource so we can access the pixels - if(!g_pImmediateContext) g_pd3dDevice->GetImmediateContext(&g_pImmediateContext); - hr = g_pImmediateContext->Map(g_pStagingTexture, 0, D3D11_MAP_READ, 0, &mappedSubResource); - if(SUCCEEDED(hr)) { - // Get a pointer to the staging texture data - dataPointer = mappedSubResource.pData; - // Write the the bgra staging texture to the user pixel buffer - switch(glFormat) { - case GL_BGRA_EXT: // direct copy - spoutcopy.CopyPixels((unsigned char *)dataPointer, pixels, width, height, GL_RGBA, bInvert); - break; - case GL_RGBA: - spoutcopy.bgra2rgba(dataPointer, (void *)pixels, width, height, bInvert); - break; - case GL_RGB: - spoutcopy.bgra2rgb(dataPointer, (void *)pixels, width, height, bInvert); - break; - case GL_BGR_EXT: - spoutcopy.bgra2bgr(dataPointer, (void *)pixels, width, height, bInvert); - break; - default: - break; + if(g_pImmediateContext) { + hr = g_pImmediateContext->Map(g_pStagingTexture, 0, D3D11_MAP_READ, 0, &mappedSubResource); + if(SUCCEEDED(hr)) { + // Get a pointer to the staging texture data + dataPointer = mappedSubResource.pData; + // Write the the bgra staging texture to the user pixel buffer + switch(glFormat) { + case GL_BGRA_EXT: // direct copy + spoutcopy.CopyPixels((unsigned char *)dataPointer, pixels, width, height, GL_RGBA, bInvert); + break; + case GL_RGBA: + spoutcopy.bgra2rgba(dataPointer, (void *)pixels, width, height, bInvert); + break; + case GL_RGB: + spoutcopy.bgra2rgb(dataPointer, (void *)pixels, width, height, bInvert); + break; + case GL_BGR_EXT: + spoutcopy.bgra2bgr(dataPointer, (void *)pixels, width, height, bInvert); + break; + default: + break; + } + g_pImmediateContext->Unmap(g_pStagingTexture, 0); + return true; } - g_pImmediateContext->Unmap(g_pStagingTexture, 0); - return true; } // endif DX11 map OK } // endif ReadTexture OK @@ -2604,44 +2638,45 @@ bool spoutGLDXinterop::DrawDX11texture(float max_x, float max_y, float aspect, b if(ReadTexture(&g_pStagingTexture)) { FlushWait(); // Wait for access to the staging texture // Map the staging texture resource to access the pixels - if(!g_pImmediateContext) g_pd3dDevice->GetImmediateContext(&g_pImmediateContext); - hr = g_pImmediateContext->Map(g_pStagingTexture, 0, D3D11_MAP_READ, 0, &mappedSubResource); - if(SUCCEEDED(hr)) { - // Get a pointer to the staging texture data - dataPointer = mappedSubResource.pData; - if(dataPointer) { + if(g_pImmediateContext) { + hr = g_pImmediateContext->Map(g_pStagingTexture, 0, D3D11_MAP_READ, 0, &mappedSubResource); + if(SUCCEEDED(hr)) { + // Get a pointer to the staging texture data + dataPointer = mappedSubResource.pData; + if(dataPointer) { - // Copy the DX11 pixels to it - glBindTexture(GL_TEXTURE_2D, m_TexID); - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_BGRA_EXT, GL_UNSIGNED_BYTE, dataPointer); - glBindTexture(GL_TEXTURE_2D, 0); + // Copy the DX11 pixels to it + glBindTexture(GL_TEXTURE_2D, m_TexID); + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_BGRA_EXT, GL_UNSIGNED_BYTE, dataPointer); + glBindTexture(GL_TEXTURE_2D, 0); - // Draw the local texture and invert as necessary - SaveOpenGLstate(width, height); - glEnable(GL_TEXTURE_2D); - glBindTexture(GL_TEXTURE_2D, m_TexID); // bind texture - glColor4f(1.f, 1.f, 1.f, 1.f); - glBegin(GL_QUADS); - if(bInvert) { - // DirectX coordinates are already inverted - glTexCoord2f(0.0, 0.0); glVertex2f(-aspect,-1.0); // lower left - glTexCoord2f(0.0, max_y); glVertex2f(-aspect, 1.0); // upper left - glTexCoord2f(max_x, max_y); glVertex2f( aspect, 1.0); // upper right - glTexCoord2f(max_x, 0.0); glVertex2f( aspect,-1.0); // lower right - } - else { - glTexCoord2f(0.0, max_y); glVertex2f(-aspect,-1.0); // lower left - glTexCoord2f(0.0, 0.0); glVertex2f(-aspect, 1.0); // upper left - glTexCoord2f(max_x, 0.0); glVertex2f( aspect, 1.0); // upper right - glTexCoord2f(max_x, max_y); glVertex2f( aspect,-1.0); // lower right + // Draw the local texture and invert as necessary + SaveOpenGLstate(width, height); + glEnable(GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D, m_TexID); // bind texture + glColor4f(1.f, 1.f, 1.f, 1.f); + glBegin(GL_QUADS); + if(bInvert) { + // DirectX coordinates are already inverted + glTexCoord2f(0.0, 0.0); glVertex2f(-aspect,-1.0); // lower left + glTexCoord2f(0.0, max_y); glVertex2f(-aspect, 1.0); // upper left + glTexCoord2f(max_x, max_y); glVertex2f( aspect, 1.0); // upper right + glTexCoord2f(max_x, 0.0); glVertex2f( aspect,-1.0); // lower right + } + else { + glTexCoord2f(0.0, max_y); glVertex2f(-aspect,-1.0); // lower left + glTexCoord2f(0.0, 0.0); glVertex2f(-aspect, 1.0); // upper left + glTexCoord2f(max_x, 0.0); glVertex2f( aspect, 1.0); // upper right + glTexCoord2f(max_x, max_y); glVertex2f( aspect,-1.0); // lower right + } + glEnd(); + glBindTexture(GL_TEXTURE_2D, 0); // unbind shared texture + glDisable(GL_TEXTURE_2D); + RestoreOpenGLstate(); } - glEnd(); - glBindTexture(GL_TEXTURE_2D, 0); // unbind shared texture - glDisable(GL_TEXTURE_2D); - RestoreOpenGLstate(); + g_pImmediateContext->Unmap(g_pStagingTexture, 0); + return true; } - g_pImmediateContext->Unmap(g_pStagingTexture, 0); - return true; } // endif DX11 map OK } // endif ReadTexture OK @@ -3152,7 +3187,6 @@ bool spoutGLDXinterop::DrawToDX9texture(GLuint TextureID, GLuint TextureTarget, // Create or resize a local OpenGL texture CheckOpenGLTexture(m_TexID, GL_RGBA, width, height, m_TexWidth, m_TexHeight); - // Draw the input texture into the local texture via an fbo glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo); // Destination is the fbo with local texture attached @@ -3162,6 +3196,7 @@ bool spoutGLDXinterop::DrawToDX9texture(GLuint TextureID, GLuint TextureTarget, // Draw the input texture glColor4f(1.f, 1.f, 1.f, 1.f); + glEnable(TextureTarget); glBindTexture(TextureTarget, TextureID); GLfloat tc[4][2] = {0}; diff --git a/SpoutSDK/SpoutSDK/SpoutReceiver.cpp b/SpoutSDK/SpoutSDK/SpoutReceiver.cpp index 13f442d..137e00e 100644 --- a/SpoutSDK/SpoutSDK/SpoutReceiver.cpp +++ b/SpoutSDK/SpoutSDK/SpoutReceiver.cpp @@ -66,6 +66,48 @@ SpoutReceiver::~SpoutReceiver() } + +//--------------------------------------------------------- +bool SpoutReceiver::ReceiveTexture(char* name, unsigned int &width, unsigned int &height, GLuint TextureID, GLuint TextureTarget, bool bInvert, GLuint HostFBO) +{ + return spout.ReceiveTexture(name, width, height, TextureID, TextureTarget, bInvert, HostFBO); +} + +//--------------------------------------------------------- +// PYTHON WRAPPING Functions +//--------------------------------------------------------- +bool SpoutReceiver::pyCreateReceiver(const char* theName, unsigned int theWidth, unsigned int theHeight, bool bUseActive) +{ + char name[256]; + + strcpy_s(name, 256, theName); + unsigned int width = theWidth; + unsigned int height = theHeight; + + bool bRet = spout.CreateReceiver(name, width, height, bUseActive); + + if (bRet) { + //strcpy_s(theName, 256, name); + theWidth = width; + theHeight = height; + } + + return bRet; +} + +//--------------------------------------------------------- +bool SpoutReceiver::pyReceiveTexture(const char* theName, unsigned int theWidth, unsigned int theHeight, GLuint TextureID, GLuint TextureTarget, bool bInvert, GLuint HostFBO) +{ + char name[256]; + + strcpy_s(name, 256, theName); + unsigned int width = theWidth; + unsigned int height = theHeight; + + return spout.ReceiveTexture(name, width, height, TextureID, TextureTarget, bInvert, HostFBO); +} + +//--------------------------------------------------------- unsigned int SpoutReceiver::GetWidth(const char* theName) { unsigned int width; unsigned int height; @@ -78,6 +120,8 @@ unsigned int SpoutReceiver::GetWidth(const char* theName) { return 0; } } + +//--------------------------------------------------------- unsigned int SpoutReceiver::GetHeight(const char* theName) { unsigned int width; unsigned int height; @@ -90,25 +134,8 @@ unsigned int SpoutReceiver::GetHeight(const char* theName) { return 0; } } - //--------------------------------------------------------- -bool SpoutReceiver::ReceiveTexture(char* name, unsigned int &width, unsigned int &height, GLuint TextureID, GLuint TextureTarget, bool bInvert, GLuint HostFBO) -{ - - return spout.ReceiveTexture(name, width, height, TextureID, TextureTarget, bInvert, HostFBO); -} - -bool SpoutReceiver::pyReceiveTexture(const char* theName, unsigned int theWidth, unsigned int theHeight, GLuint TextureID, GLuint TextureTarget, bool bInvert, GLuint HostFBO) -{ - char name[256]; - - strcpy_s(name, 256, theName); - unsigned int width = theWidth; - unsigned int height = theHeight; - - return spout.ReceiveTexture(name, width, height, TextureID, TextureTarget, bInvert, HostFBO); -} - +//--------------------------------------------------------- //--------------------------------------------------------- bool SpoutReceiver::ReceiveImage(char* Sendername, @@ -142,25 +169,6 @@ bool SpoutReceiver::CreateReceiver(char* name, unsigned int &width, unsigned int return spout.CreateReceiver(name, width, height, bUseActive); } -bool SpoutReceiver::pyCreateReceiver(const char* theName, unsigned int theWidth, unsigned int theHeight, bool bUseActive) -{ - char name[256]; - - strcpy_s(name, 256, theName); - unsigned int width = theWidth; - unsigned int height = theHeight; - - bool bRet = spout.CreateReceiver(name, width, height, bUseActive); - - if (bRet) { - //strcpy_s(theName, 256, name); - theWidth = width; - theHeight = height; - } - - return bRet; -} - //--------------------------------------------------------- void SpoutReceiver::ReleaseReceiver() { diff --git a/SpoutSDK/SpoutSDK/SpoutReceiver.h b/SpoutSDK/SpoutSDK/SpoutReceiver.h index 31dd189..9d4d04b 100644 --- a/SpoutSDK/SpoutSDK/SpoutReceiver.h +++ b/SpoutSDK/SpoutSDK/SpoutReceiver.h @@ -32,18 +32,21 @@ #include "spoutSDK.h" - class SPOUT_DLLEXP SpoutReceiver { public: SpoutReceiver(); ~SpoutReceiver(); - + + //--------------------------------------------------------- + // PYTHON WRAPPING Functions + //--------------------------------------------------------- bool pyCreateReceiver(const char* theName, unsigned int theWidth, unsigned int theHeight, bool bUseActive); bool pyReceiveTexture(const char* theName, unsigned int theWidth, unsigned int theHeight, GLuint TextureID, GLuint TextureTarget, bool bInvert, GLuint HostFBO); unsigned int GetWidth(const char* theName); unsigned int GetHeight(const char* theName); + //--------------------------------------------------------- bool CreateReceiver(char* Sendername, unsigned int &width, unsigned int &height, bool bUseActive = false); bool ReceiveTexture(char* Sendername, unsigned int &width, unsigned int &height, GLuint TextureID = 0, GLuint TextureTarget = 0, bool bInvert = false, GLuint HostFBO = 0); diff --git a/SpoutSDK/SpoutSDK/SpoutSDK.cpp b/SpoutSDK/SpoutSDK/SpoutSDK.cpp index 82f5b33..275bbea 100644 --- a/SpoutSDK/SpoutSDK/SpoutSDK.cpp +++ b/SpoutSDK/SpoutSDK/SpoutSDK.cpp @@ -105,6 +105,10 @@ // 18.01.17 - GetImageSize redundant for 2.006 // 22.01.17 - include zero char in SelectSenderPanel NULL arg checks // 25.05.17 - corrected SendImage UpdateSender to use passed width and height +// 31.10.17 - CreateReceiver update +// https://github.com/leadedge/Spout2/issues/24 +// temporary changes to allow selection of a sender +// when a name is provided for CreateReceiver // // ================================================================ /* @@ -1037,6 +1041,8 @@ bool Spout::OpenReceiver (char* theName, unsigned int& theWidth, unsigned int& t width = g_Width; height = g_Height; dwFormat = g_Format; + // 31.10.17 + sharehandle = g_ShareHandle; } else { return false; @@ -1474,6 +1480,8 @@ bool Spout::CheckSpoutPanel() g_Width = (unsigned int)TextureInfo.width; g_Height = (unsigned int)TextureInfo.height; g_Format = TextureInfo.format; + // 31.10.17 + g_ShareHandle = (HANDLE)TextureInfo.shareHandle; // 24.11.15 - not needed if the sender exists - and it is already checked as active // Register in the list of senders and make it the active sender // interop.senders.RegisterSenderName(newname); @@ -1489,6 +1497,8 @@ bool Spout::CheckSpoutPanel() g_Width = (unsigned int)TextureInfo.width; g_Height = (unsigned int)TextureInfo.height; g_Format = TextureInfo.format; + // 31.10.17 + g_ShareHandle = (HANDLE)TextureInfo.shareHandle; bRet = true; // will pass on next call to receivetexture } } // no active sender diff --git a/SpoutSDK/SpoutSDK/SpoutSDK.vcxproj b/SpoutSDK/SpoutSDK/SpoutSDK.vcxproj index 984c0ed..3216032 100644 --- a/SpoutSDK/SpoutSDK/SpoutSDK.vcxproj +++ b/SpoutSDK/SpoutSDK/SpoutSDK.vcxproj @@ -1,5 +1,5 @@  - + Debug @@ -22,33 +22,33 @@ {9E8255CD-175A-4421-9B0D-F634E889B46B} Win32Proj SpoutSDK - 8.1 + 10.0.17763.0 SpoutSDK DynamicLibrary true - v140 + v141 Unicode DynamicLibrary false - v140 + v141 true Unicode DynamicLibrary true - v140 + v141 Unicode DynamicLibrary false - v140 + v141 true Unicode @@ -106,13 +106,13 @@ Disabled _DEBUG;_WINDOWS;_USRDLL;SPOUTFORPYTHON_EXPORTS;%(PreprocessorDefinitions) true - %UserProfile%\AppData\Local\Programs\Python\Python35\include;C:\Program Files\boost_1_65_0;%(AdditionalIncludeDirectories) + %UserProfile%\AppData\Local\Programs\Python\Python35\include;C:\Program Files\boost_1_69_0;%(AdditionalIncludeDirectories) Windows true opengl32.lib;%(AdditionalDependencies) - C:\Program Files\boost_1_65_0\stage\x64\lib;C:\Program Files\boost_1_65_0\;%UserProfile%\AppData\Local\Programs\Python\Python35\libs;%(AdditionalLibraryDirectories) + C:\Program Files\boost_1_69_0\stage\x64\lib;C:\Program Files\boost_1_69_0\;%UserProfile%\AppData\Local\Programs\Python\Python35\libs;%(AdditionalLibraryDirectories) @@ -145,7 +145,7 @@ true NDEBUG;_WINDOWS;_USRDLL;SPOUTFORPYTHON_EXPORTS;%(PreprocessorDefinitions) true - %UserProfile%\AppData\Local\Programs\Python\Python35\include;C:\Program Files\boost_1_65_0;%(AdditionalIncludeDirectories) + %UserProfile%\AppData\Local\Programs\Python\Python37\include;C:\Program Files\boost_1_69_0;%(AdditionalIncludeDirectories) Windows @@ -153,7 +153,7 @@ true true opengl32.lib;%(AdditionalDependencies) - C:\Program Files\boost_1_65_0\stage\x64\lib;C:\Program Files\boost_1_65_0\;%UserProfile%\AppData\Local\Programs\Python\Python35\libs;%(AdditionalLibraryDirectories) + C:\Program Files\boost_1_69_0\stage\x64\lib;C:\Program Files\boost_1_69_0\;%UserProfile%\AppData\Local\Programs\Python\Python37\libs;%(AdditionalLibraryDirectories) diff --git a/SpoutSDK/SpoutSDK/SpoutSDK.vcxproj.filters b/SpoutSDK/SpoutSDK/SpoutSDK.vcxproj.filters index 866cbe4..bdabc98 100644 --- a/SpoutSDK/SpoutSDK/SpoutSDK.vcxproj.filters +++ b/SpoutSDK/SpoutSDK/SpoutSDK.vcxproj.filters @@ -15,81 +15,81 @@ - + Header Files - + Header Files - + Header Files - + Header Files - + Header Files - + Header Files - + Header Files - + Header Files - + Header Files - + Header Files - + Header Files - + Header Files - + Header Files - + Source Files - + Source Files - + Source Files - + Source Files - + Source Files - + Source Files - + Source Files - + Source Files - + Source Files - + Source Files - + Source Files - + Source Files diff --git a/SpoutSDK/SpoutSDK/SpoutSender.cpp b/SpoutSDK/SpoutSDK/SpoutSender.cpp index 2fc19ee..91e6a3c 100644 --- a/SpoutSDK/SpoutSDK/SpoutSender.cpp +++ b/SpoutSDK/SpoutSDK/SpoutSender.cpp @@ -65,11 +65,15 @@ SpoutSender::~SpoutSender() } - +//--------------------------------------------------------- +// PYTHON WRAPPING Functions +//--------------------------------------------------------- char const* SpoutSender::SayHello() { return "Hello, from c++ dll!"; } +//--------------------------------------------------------- +//--------------------------------------------------------- //--------------------------------------------------------- bool SpoutSender::CreateSender(const char *name, unsigned int width, unsigned int height, DWORD dwFormat) diff --git a/SpoutSDK/SpoutSDK/SpoutSender.h b/SpoutSDK/SpoutSDK/SpoutSender.h index d148d52..5600813 100644 --- a/SpoutSDK/SpoutSDK/SpoutSender.h +++ b/SpoutSDK/SpoutSDK/SpoutSender.h @@ -40,8 +40,12 @@ class SPOUT_DLLEXP SpoutSender { SpoutSender(); ~SpoutSender(); + //--------------------------------------------------------- + // PYTHON WRAPPING Functions + //--------------------------------------------------------- char const* SayHello(); - + //--------------------------------------------------------- + //--------------------------------------------------------- bool CreateSender(const char *Sendername, unsigned int width, unsigned int height, DWORD dwFormat = 0); bool UpdateSender(const char *Sendername, unsigned int width, unsigned int height); diff --git a/SpoutSDK/SpoutSDK/SpoutSenderNames.cpp b/SpoutSDK/SpoutSDK/SpoutSenderNames.cpp index a96dbb1..d1bccd9 100644 --- a/SpoutSDK/SpoutSDK/SpoutSenderNames.cpp +++ b/SpoutSDK/SpoutSDK/SpoutSenderNames.cpp @@ -773,7 +773,7 @@ void spoutSenderNames::writeBufferFromSenderSet(const std::set& Sen // move the buffer pointer on for the next Sender name buf += SpoutMaxSenderNameLen; i++; - if(i > maxSenders) break; // do not exceed the size of the local buffer + if(i >= maxSenders) break; // do not exceed the size of the local buffer } // If we haven't totally filled the sender list,