This commit is contained in:
Squishy
2025-09-05 01:23:00 +02:00
111 changed files with 9991 additions and 44 deletions
Binary file not shown.
Binary file not shown.
+15 -44
View File
@@ -1,6 +1,4 @@
[settings]
StartPreset=Milkdrop3\presets\Mdgeorge - 3Body Glass - MilkDrop2077 Butterfly1.milk2
AudioDeviceSelected=Voicemeeter AUX Input (VB-Audio Voicemeeter VAIO)
Configured=2
HardCutsDisabled=1
EnableRating=1
@@ -21,47 +19,20 @@ TimeBetweenPresets=16.000000
TimeBetweenPresetsRand=10.000000
HardCutLoudnessThresh=2.500000
HardCutHalflife=60.000000
VideoAdapterIndex=0
Spout=1
ForcePS3Shaders=1
AutoHardCutMode=0
ShowFPS=0
ActivatePresetRating=1
ShowPresetName=0
ShowPresetRating=1
ShowInformations=0
SequentialPresetOrder=0
DoublePresetMode=0
FilterMilkFiles=1
WindowLeft=3275
WindowTop=0
WindowWidth=1186
WindowHeight=589
AlwaysOnTop=0
MaxFPS=60
[transitions]
zoom=1
side=1
plasma=1
plasma2=1
plasma3=1
cercle=1
square=0
snail=1
snail2=0
snail3=0
triangle=1
donuts=0
corner=1
patches=1
checkerboard=0
bubbles=0
stars=0
stars2=0
clock=1
nuclear=0
arrow=1
cisor=0
wave=0
curtain=1
vertical=0
horizontal=0
linesvertical=0
lineshorizontal=0
cross=0
cross2=0
ShowFPS=0
ShowPresetName=0
ShowPresetRating=0
ShowInformations=0
FilterMilkFiles=1
AutoHardCutMode=0
DoublePresetMode=0
SequentialPresetOrder=0
AudioDeviceSelected=Voicemeeter Input (VB-Audio Voicemeeter VAIO)
@@ -0,0 +1,44 @@
//--------------------------------------------------------------------------------------
// File: Tutorial04.fx
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//--------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------
// Constant Buffer Variables
//--------------------------------------------------------------------------------------
cbuffer ConstantBuffer : register( b0 )
{
matrix World;
matrix View;
matrix Projection;
}
//--------------------------------------------------------------------------------------
struct VS_OUTPUT
{
float4 Pos : SV_POSITION;
float4 Color : COLOR0;
};
//--------------------------------------------------------------------------------------
// Vertex Shader
//--------------------------------------------------------------------------------------
VS_OUTPUT VS( float4 Pos : POSITION, float4 Color : COLOR )
{
VS_OUTPUT output = (VS_OUTPUT)0;
output.Pos = mul( Pos, World );
output.Pos = mul( output.Pos, View );
output.Pos = mul( output.Pos, Projection );
output.Color = Color;
return output;
}
//--------------------------------------------------------------------------------------
// Pixel Shader
//--------------------------------------------------------------------------------------
float4 PS( VS_OUTPUT input ) : SV_Target
{
return input.Color;
}
@@ -0,0 +1,65 @@
//--------------------------------------------------------------------------------------
// File: Tutorial07.fx
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//--------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------
// Constant Buffer Variables
//--------------------------------------------------------------------------------------
Texture2D txDiffuse : register( t0 );
SamplerState samLinear : register( s0 );
cbuffer cbNeverChanges : register( b0 )
{
matrix View;
};
cbuffer cbChangeOnResize : register( b1 )
{
matrix Projection;
};
cbuffer cbChangesEveryFrame : register( b2 )
{
matrix World;
float4 vMeshColor;
};
//--------------------------------------------------------------------------------------
struct VS_INPUT
{
float4 Pos : POSITION;
float2 Tex : TEXCOORD0;
};
struct PS_INPUT
{
float4 Pos : SV_POSITION;
float2 Tex : TEXCOORD0;
};
//--------------------------------------------------------------------------------------
// Vertex Shader
//--------------------------------------------------------------------------------------
PS_INPUT VS( VS_INPUT input )
{
PS_INPUT output = (PS_INPUT)0;
output.Pos = mul( input.Pos, World );
output.Pos = mul( output.Pos, View );
output.Pos = mul( output.Pos, Projection );
output.Tex = input.Tex;
return output;
}
//--------------------------------------------------------------------------------------
// Pixel Shader
//--------------------------------------------------------------------------------------
float4 PS( PS_INPUT input) : SV_Target
{
return txDiffuse.Sample( samLinear, input.Tex ) * vMeshColor;
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 675 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 323 KiB

@@ -0,0 +1,31 @@
//*********************************************************
//
// Copyright (c) Microsoft. All rights reserved.
// This code is licensed under the MIT License (MIT).
// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
//
//*********************************************************
struct PSInput
{
float4 position : SV_POSITION;
float4 color : COLOR;
};
PSInput VSMain(float4 position : POSITION, float4 color : COLOR)
{
PSInput result;
result.position = position;
result.color = color;
return result;
}
float4 PSMain(PSInput input) : SV_TARGET
{
return input.color;
}
@@ -0,0 +1,34 @@
//*********************************************************
//
// Copyright (c) Microsoft. All rights reserved.
// This code is licensed under the MIT License (MIT).
// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
//
//*********************************************************
struct PSInput
{
float4 position : SV_POSITION;
float2 uv : TEXCOORD;
};
Texture2D g_texture : register(t0);
SamplerState g_sampler : register(s0);
PSInput VSMain(float4 position : POSITION, float4 uv : TEXCOORD)
{
PSInput result;
result.position = position;
result.uv = uv;
return result;
}
float4 PSMain(PSInput input) : SV_TARGET
{
return g_texture.Sample(g_sampler, input.uv);
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

@@ -0,0 +1 @@
Data files for the examples are accumulated here.
@@ -0,0 +1 @@
After build, the example executable files are copied here.
@@ -0,0 +1 @@
include(${CMAKE_CURRENT_LIST_DIR}/spout2-targets.cmake)
@@ -0,0 +1,99 @@
#----------------------------------------------------------------
# Generated CMake target import file for configuration "Release".
#----------------------------------------------------------------
# Commands may need to know the format version.
set(CMAKE_IMPORT_FILE_VERSION 1)
# Import target "Spout2::Spout" for configuration "Release"
set_property(TARGET Spout2::Spout APPEND PROPERTY IMPORTED_CONFIGURATIONS RELEASE)
set_target_properties(Spout2::Spout PROPERTIES
IMPORTED_IMPLIB_RELEASE "${_IMPORT_PREFIX}/lib/Spout.lib"
IMPORTED_LOCATION_RELEASE "${_IMPORT_PREFIX}/bin/Spout.dll"
)
list(APPEND _cmake_import_check_targets Spout2::Spout )
list(APPEND _cmake_import_check_files_for_Spout2::Spout "${_IMPORT_PREFIX}/lib/Spout.lib" "${_IMPORT_PREFIX}/bin/Spout.dll" )
# Import target "Spout2::Spout_static" for configuration "Release"
set_property(TARGET Spout2::Spout_static APPEND PROPERTY IMPORTED_CONFIGURATIONS RELEASE)
set_target_properties(Spout2::Spout_static PROPERTIES
IMPORTED_LINK_INTERFACE_LANGUAGES_RELEASE "CXX"
IMPORTED_LOCATION_RELEASE "${_IMPORT_PREFIX}/lib/Spout_static.lib"
)
list(APPEND _cmake_import_check_targets Spout2::Spout_static )
list(APPEND _cmake_import_check_files_for_Spout2::Spout_static "${_IMPORT_PREFIX}/lib/Spout_static.lib" )
# Import target "Spout2::SpoutDX" for configuration "Release"
set_property(TARGET Spout2::SpoutDX APPEND PROPERTY IMPORTED_CONFIGURATIONS RELEASE)
set_target_properties(Spout2::SpoutDX PROPERTIES
IMPORTED_IMPLIB_RELEASE "${_IMPORT_PREFIX}/lib/SpoutDX.lib"
IMPORTED_LOCATION_RELEASE "${_IMPORT_PREFIX}/bin/SpoutDX.dll"
)
list(APPEND _cmake_import_check_targets Spout2::SpoutDX )
list(APPEND _cmake_import_check_files_for_Spout2::SpoutDX "${_IMPORT_PREFIX}/lib/SpoutDX.lib" "${_IMPORT_PREFIX}/bin/SpoutDX.dll" )
# Import target "Spout2::SpoutDX_static" for configuration "Release"
set_property(TARGET Spout2::SpoutDX_static APPEND PROPERTY IMPORTED_CONFIGURATIONS RELEASE)
set_target_properties(Spout2::SpoutDX_static PROPERTIES
IMPORTED_LINK_INTERFACE_LANGUAGES_RELEASE "CXX"
IMPORTED_LOCATION_RELEASE "${_IMPORT_PREFIX}/lib/SpoutDX_static.lib"
)
list(APPEND _cmake_import_check_targets Spout2::SpoutDX_static )
list(APPEND _cmake_import_check_files_for_Spout2::SpoutDX_static "${_IMPORT_PREFIX}/lib/SpoutDX_static.lib" )
# Import target "Spout2::SpoutDX12" for configuration "Release"
set_property(TARGET Spout2::SpoutDX12 APPEND PROPERTY IMPORTED_CONFIGURATIONS RELEASE)
set_target_properties(Spout2::SpoutDX12 PROPERTIES
IMPORTED_IMPLIB_RELEASE "${_IMPORT_PREFIX}/lib/SpoutDX12.lib"
IMPORTED_LOCATION_RELEASE "${_IMPORT_PREFIX}/bin/SpoutDX12.dll"
)
list(APPEND _cmake_import_check_targets Spout2::SpoutDX12 )
list(APPEND _cmake_import_check_files_for_Spout2::SpoutDX12 "${_IMPORT_PREFIX}/lib/SpoutDX12.lib" "${_IMPORT_PREFIX}/bin/SpoutDX12.dll" )
# Import target "Spout2::SpoutDX12_static" for configuration "Release"
set_property(TARGET Spout2::SpoutDX12_static APPEND PROPERTY IMPORTED_CONFIGURATIONS RELEASE)
set_target_properties(Spout2::SpoutDX12_static PROPERTIES
IMPORTED_LINK_INTERFACE_LANGUAGES_RELEASE "CXX"
IMPORTED_LOCATION_RELEASE "${_IMPORT_PREFIX}/lib/SpoutDX12_static.lib"
)
list(APPEND _cmake_import_check_targets Spout2::SpoutDX12_static )
list(APPEND _cmake_import_check_files_for_Spout2::SpoutDX12_static "${_IMPORT_PREFIX}/lib/SpoutDX12_static.lib" )
# Import target "Spout2::SpoutDX9" for configuration "Release"
set_property(TARGET Spout2::SpoutDX9 APPEND PROPERTY IMPORTED_CONFIGURATIONS RELEASE)
set_target_properties(Spout2::SpoutDX9 PROPERTIES
IMPORTED_IMPLIB_RELEASE "${_IMPORT_PREFIX}/lib/SpoutDX9.lib"
IMPORTED_LOCATION_RELEASE "${_IMPORT_PREFIX}/bin/SpoutDX9.dll"
)
list(APPEND _cmake_import_check_targets Spout2::SpoutDX9 )
list(APPEND _cmake_import_check_files_for_Spout2::SpoutDX9 "${_IMPORT_PREFIX}/lib/SpoutDX9.lib" "${_IMPORT_PREFIX}/bin/SpoutDX9.dll" )
# Import target "Spout2::SpoutDX9_static" for configuration "Release"
set_property(TARGET Spout2::SpoutDX9_static APPEND PROPERTY IMPORTED_CONFIGURATIONS RELEASE)
set_target_properties(Spout2::SpoutDX9_static PROPERTIES
IMPORTED_LINK_INTERFACE_LANGUAGES_RELEASE "CXX"
IMPORTED_LOCATION_RELEASE "${_IMPORT_PREFIX}/lib/SpoutDX9_static.lib"
)
list(APPEND _cmake_import_check_targets Spout2::SpoutDX9_static )
list(APPEND _cmake_import_check_files_for_Spout2::SpoutDX9_static "${_IMPORT_PREFIX}/lib/SpoutDX9_static.lib" )
# Import target "Spout2::SpoutLibrary" for configuration "Release"
set_property(TARGET Spout2::SpoutLibrary APPEND PROPERTY IMPORTED_CONFIGURATIONS RELEASE)
set_target_properties(Spout2::SpoutLibrary PROPERTIES
IMPORTED_IMPLIB_RELEASE "${_IMPORT_PREFIX}/lib/SpoutLibrary.lib"
IMPORTED_LOCATION_RELEASE "${_IMPORT_PREFIX}/bin/SpoutLibrary.dll"
)
list(APPEND _cmake_import_check_targets Spout2::SpoutLibrary )
list(APPEND _cmake_import_check_files_for_Spout2::SpoutLibrary "${_IMPORT_PREFIX}/lib/SpoutLibrary.lib" "${_IMPORT_PREFIX}/bin/SpoutLibrary.dll" )
# Commands beyond this point should not need to know the version.
set(CMAKE_IMPORT_FILE_VERSION)
@@ -0,0 +1,163 @@
# Generated by CMake
if("${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}" LESS 2.8)
message(FATAL_ERROR "CMake >= 2.8.0 required")
endif()
if(CMAKE_VERSION VERSION_LESS "2.8.12")
message(FATAL_ERROR "CMake >= 2.8.12 required")
endif()
cmake_policy(PUSH)
cmake_policy(VERSION 2.8.12...3.28)
#----------------------------------------------------------------
# Generated CMake target import file.
#----------------------------------------------------------------
# Commands may need to know the format version.
set(CMAKE_IMPORT_FILE_VERSION 1)
# Protect against multiple inclusion, which would fail when already imported targets are added once more.
set(_cmake_targets_defined "")
set(_cmake_targets_not_defined "")
set(_cmake_expected_targets "")
foreach(_cmake_expected_target IN ITEMS Spout2::Spout Spout2::Spout_static Spout2::SpoutDX Spout2::SpoutDX_static Spout2::SpoutDX12 Spout2::SpoutDX12_static Spout2::SpoutDX9 Spout2::SpoutDX9_static Spout2::SpoutLibrary)
list(APPEND _cmake_expected_targets "${_cmake_expected_target}")
if(TARGET "${_cmake_expected_target}")
list(APPEND _cmake_targets_defined "${_cmake_expected_target}")
else()
list(APPEND _cmake_targets_not_defined "${_cmake_expected_target}")
endif()
endforeach()
unset(_cmake_expected_target)
if(_cmake_targets_defined STREQUAL _cmake_expected_targets)
unset(_cmake_targets_defined)
unset(_cmake_targets_not_defined)
unset(_cmake_expected_targets)
unset(CMAKE_IMPORT_FILE_VERSION)
cmake_policy(POP)
return()
endif()
if(NOT _cmake_targets_defined STREQUAL "")
string(REPLACE ";" ", " _cmake_targets_defined_text "${_cmake_targets_defined}")
string(REPLACE ";" ", " _cmake_targets_not_defined_text "${_cmake_targets_not_defined}")
message(FATAL_ERROR "Some (but not all) targets in this export set were already defined.\nTargets Defined: ${_cmake_targets_defined_text}\nTargets not yet defined: ${_cmake_targets_not_defined_text}\n")
endif()
unset(_cmake_targets_defined)
unset(_cmake_targets_not_defined)
unset(_cmake_expected_targets)
# Compute the installation prefix relative to this file.
get_filename_component(_IMPORT_PREFIX "${CMAKE_CURRENT_LIST_FILE}" PATH)
get_filename_component(_IMPORT_PREFIX "${_IMPORT_PREFIX}" PATH)
get_filename_component(_IMPORT_PREFIX "${_IMPORT_PREFIX}" PATH)
get_filename_component(_IMPORT_PREFIX "${_IMPORT_PREFIX}" PATH)
if(_IMPORT_PREFIX STREQUAL "/")
set(_IMPORT_PREFIX "")
endif()
# Create imported target Spout2::Spout
add_library(Spout2::Spout SHARED IMPORTED)
set_target_properties(Spout2::Spout PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${_IMPORT_PREFIX}/include"
)
# Create imported target Spout2::Spout_static
add_library(Spout2::Spout_static STATIC IMPORTED)
set_target_properties(Spout2::Spout_static PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${_IMPORT_PREFIX}/include"
INTERFACE_LINK_LIBRARIES "\$<LINK_ONLY:opengl32>;\$<LINK_ONLY:kernel32>;\$<LINK_ONLY:user32>;\$<LINK_ONLY:gdi32>;\$<LINK_ONLY:winspool>;\$<LINK_ONLY:comdlg32>;\$<LINK_ONLY:comctl32>;\$<LINK_ONLY:advapi32>;\$<LINK_ONLY:shell32>;\$<LINK_ONLY:ole32>;\$<LINK_ONLY:oleaut32>;\$<LINK_ONLY:uuid>;\$<LINK_ONLY:odbc32>;\$<LINK_ONLY:odbccp32>;\$<LINK_ONLY:d3d9>;\$<LINK_ONLY:d3d11>;\$<LINK_ONLY:DXGI>;\$<LINK_ONLY:Version>"
)
# Create imported target Spout2::SpoutDX
add_library(Spout2::SpoutDX SHARED IMPORTED)
set_target_properties(Spout2::SpoutDX PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${_IMPORT_PREFIX}/include"
)
# Create imported target Spout2::SpoutDX_static
add_library(Spout2::SpoutDX_static STATIC IMPORTED)
set_target_properties(Spout2::SpoutDX_static PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${_IMPORT_PREFIX}/include"
)
# Create imported target Spout2::SpoutDX12
add_library(Spout2::SpoutDX12 SHARED IMPORTED)
set_target_properties(Spout2::SpoutDX12 PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${_IMPORT_PREFIX}/include"
)
# Create imported target Spout2::SpoutDX12_static
add_library(Spout2::SpoutDX12_static STATIC IMPORTED)
set_target_properties(Spout2::SpoutDX12_static PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${_IMPORT_PREFIX}/include"
)
# Create imported target Spout2::SpoutDX9
add_library(Spout2::SpoutDX9 SHARED IMPORTED)
set_target_properties(Spout2::SpoutDX9 PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${_IMPORT_PREFIX}/include"
)
# Create imported target Spout2::SpoutDX9_static
add_library(Spout2::SpoutDX9_static STATIC IMPORTED)
set_target_properties(Spout2::SpoutDX9_static PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${_IMPORT_PREFIX}/include"
)
# Create imported target Spout2::SpoutLibrary
add_library(Spout2::SpoutLibrary SHARED IMPORTED)
set_target_properties(Spout2::SpoutLibrary PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${_IMPORT_PREFIX}/include"
)
# Load information for each installed configuration.
file(GLOB _cmake_config_files "${CMAKE_CURRENT_LIST_DIR}/spout2-targets-*.cmake")
foreach(_cmake_config_file IN LISTS _cmake_config_files)
include("${_cmake_config_file}")
endforeach()
unset(_cmake_config_file)
unset(_cmake_config_files)
# Cleanup temporary variables.
set(_IMPORT_PREFIX)
# Loop over all imported files and verify that they actually exist
foreach(_cmake_target IN LISTS _cmake_import_check_targets)
if(CMAKE_VERSION VERSION_LESS "3.28"
OR NOT DEFINED _cmake_import_check_xcframework_for_${_cmake_target}
OR NOT IS_DIRECTORY "${_cmake_import_check_xcframework_for_${_cmake_target}}")
foreach(_cmake_file IN LISTS "_cmake_import_check_files_for_${_cmake_target}")
if(NOT EXISTS "${_cmake_file}")
message(FATAL_ERROR "The imported target \"${_cmake_target}\" references the file
\"${_cmake_file}\"
but this file does not exist. Possible reasons include:
* The file was deleted, renamed, or moved to another location.
* An install or uninstall procedure did not complete successfully.
* The installation package was faulty and contained
\"${CMAKE_CURRENT_LIST_FILE}\"
but not all the files it references.
")
endif()
endforeach()
endif()
unset(_cmake_file)
unset("_cmake_import_check_files_for_${_cmake_target}")
endforeach()
unset(_cmake_target)
unset(_cmake_import_check_targets)
# This file does not depend on other imported targets which have
# been exported from the same project but in a separate export set.
# Commands beyond this point should not need to know the version.
set(CMAKE_IMPORT_FILE_VERSION)
cmake_policy(POP)
@@ -0,0 +1 @@
include(${CMAKE_CURRENT_LIST_DIR}/spout2-targets.cmake)
@@ -0,0 +1,99 @@
#----------------------------------------------------------------
# Generated CMake target import file for configuration "Release".
#----------------------------------------------------------------
# Commands may need to know the format version.
set(CMAKE_IMPORT_FILE_VERSION 1)
# Import target "Spout2::Spout" for configuration "Release"
set_property(TARGET Spout2::Spout APPEND PROPERTY IMPORTED_CONFIGURATIONS RELEASE)
set_target_properties(Spout2::Spout PROPERTIES
IMPORTED_IMPLIB_RELEASE "${_IMPORT_PREFIX}/lib/Spout.lib"
IMPORTED_LOCATION_RELEASE "${_IMPORT_PREFIX}/bin/Spout.dll"
)
list(APPEND _cmake_import_check_targets Spout2::Spout )
list(APPEND _cmake_import_check_files_for_Spout2::Spout "${_IMPORT_PREFIX}/lib/Spout.lib" "${_IMPORT_PREFIX}/bin/Spout.dll" )
# Import target "Spout2::Spout_static" for configuration "Release"
set_property(TARGET Spout2::Spout_static APPEND PROPERTY IMPORTED_CONFIGURATIONS RELEASE)
set_target_properties(Spout2::Spout_static PROPERTIES
IMPORTED_LINK_INTERFACE_LANGUAGES_RELEASE "CXX"
IMPORTED_LOCATION_RELEASE "${_IMPORT_PREFIX}/lib/Spout_static.lib"
)
list(APPEND _cmake_import_check_targets Spout2::Spout_static )
list(APPEND _cmake_import_check_files_for_Spout2::Spout_static "${_IMPORT_PREFIX}/lib/Spout_static.lib" )
# Import target "Spout2::SpoutDX" for configuration "Release"
set_property(TARGET Spout2::SpoutDX APPEND PROPERTY IMPORTED_CONFIGURATIONS RELEASE)
set_target_properties(Spout2::SpoutDX PROPERTIES
IMPORTED_IMPLIB_RELEASE "${_IMPORT_PREFIX}/lib/SpoutDX.lib"
IMPORTED_LOCATION_RELEASE "${_IMPORT_PREFIX}/bin/SpoutDX.dll"
)
list(APPEND _cmake_import_check_targets Spout2::SpoutDX )
list(APPEND _cmake_import_check_files_for_Spout2::SpoutDX "${_IMPORT_PREFIX}/lib/SpoutDX.lib" "${_IMPORT_PREFIX}/bin/SpoutDX.dll" )
# Import target "Spout2::SpoutDX_static" for configuration "Release"
set_property(TARGET Spout2::SpoutDX_static APPEND PROPERTY IMPORTED_CONFIGURATIONS RELEASE)
set_target_properties(Spout2::SpoutDX_static PROPERTIES
IMPORTED_LINK_INTERFACE_LANGUAGES_RELEASE "CXX"
IMPORTED_LOCATION_RELEASE "${_IMPORT_PREFIX}/lib/SpoutDX_static.lib"
)
list(APPEND _cmake_import_check_targets Spout2::SpoutDX_static )
list(APPEND _cmake_import_check_files_for_Spout2::SpoutDX_static "${_IMPORT_PREFIX}/lib/SpoutDX_static.lib" )
# Import target "Spout2::SpoutDX12" for configuration "Release"
set_property(TARGET Spout2::SpoutDX12 APPEND PROPERTY IMPORTED_CONFIGURATIONS RELEASE)
set_target_properties(Spout2::SpoutDX12 PROPERTIES
IMPORTED_IMPLIB_RELEASE "${_IMPORT_PREFIX}/lib/SpoutDX12.lib"
IMPORTED_LOCATION_RELEASE "${_IMPORT_PREFIX}/bin/SpoutDX12.dll"
)
list(APPEND _cmake_import_check_targets Spout2::SpoutDX12 )
list(APPEND _cmake_import_check_files_for_Spout2::SpoutDX12 "${_IMPORT_PREFIX}/lib/SpoutDX12.lib" "${_IMPORT_PREFIX}/bin/SpoutDX12.dll" )
# Import target "Spout2::SpoutDX12_static" for configuration "Release"
set_property(TARGET Spout2::SpoutDX12_static APPEND PROPERTY IMPORTED_CONFIGURATIONS RELEASE)
set_target_properties(Spout2::SpoutDX12_static PROPERTIES
IMPORTED_LINK_INTERFACE_LANGUAGES_RELEASE "CXX"
IMPORTED_LOCATION_RELEASE "${_IMPORT_PREFIX}/lib/SpoutDX12_static.lib"
)
list(APPEND _cmake_import_check_targets Spout2::SpoutDX12_static )
list(APPEND _cmake_import_check_files_for_Spout2::SpoutDX12_static "${_IMPORT_PREFIX}/lib/SpoutDX12_static.lib" )
# Import target "Spout2::SpoutDX9" for configuration "Release"
set_property(TARGET Spout2::SpoutDX9 APPEND PROPERTY IMPORTED_CONFIGURATIONS RELEASE)
set_target_properties(Spout2::SpoutDX9 PROPERTIES
IMPORTED_IMPLIB_RELEASE "${_IMPORT_PREFIX}/lib/SpoutDX9.lib"
IMPORTED_LOCATION_RELEASE "${_IMPORT_PREFIX}/bin/SpoutDX9.dll"
)
list(APPEND _cmake_import_check_targets Spout2::SpoutDX9 )
list(APPEND _cmake_import_check_files_for_Spout2::SpoutDX9 "${_IMPORT_PREFIX}/lib/SpoutDX9.lib" "${_IMPORT_PREFIX}/bin/SpoutDX9.dll" )
# Import target "Spout2::SpoutDX9_static" for configuration "Release"
set_property(TARGET Spout2::SpoutDX9_static APPEND PROPERTY IMPORTED_CONFIGURATIONS RELEASE)
set_target_properties(Spout2::SpoutDX9_static PROPERTIES
IMPORTED_LINK_INTERFACE_LANGUAGES_RELEASE "CXX"
IMPORTED_LOCATION_RELEASE "${_IMPORT_PREFIX}/lib/SpoutDX9_static.lib"
)
list(APPEND _cmake_import_check_targets Spout2::SpoutDX9_static )
list(APPEND _cmake_import_check_files_for_Spout2::SpoutDX9_static "${_IMPORT_PREFIX}/lib/SpoutDX9_static.lib" )
# Import target "Spout2::SpoutLibrary" for configuration "Release"
set_property(TARGET Spout2::SpoutLibrary APPEND PROPERTY IMPORTED_CONFIGURATIONS RELEASE)
set_target_properties(Spout2::SpoutLibrary PROPERTIES
IMPORTED_IMPLIB_RELEASE "${_IMPORT_PREFIX}/lib/SpoutLibrary.lib"
IMPORTED_LOCATION_RELEASE "${_IMPORT_PREFIX}/bin/SpoutLibrary.dll"
)
list(APPEND _cmake_import_check_targets Spout2::SpoutLibrary )
list(APPEND _cmake_import_check_files_for_Spout2::SpoutLibrary "${_IMPORT_PREFIX}/lib/SpoutLibrary.lib" "${_IMPORT_PREFIX}/bin/SpoutLibrary.dll" )
# Commands beyond this point should not need to know the version.
set(CMAKE_IMPORT_FILE_VERSION)
@@ -0,0 +1,163 @@
# Generated by CMake
if("${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}" LESS 2.8)
message(FATAL_ERROR "CMake >= 2.8.0 required")
endif()
if(CMAKE_VERSION VERSION_LESS "2.8.12")
message(FATAL_ERROR "CMake >= 2.8.12 required")
endif()
cmake_policy(PUSH)
cmake_policy(VERSION 2.8.12...3.28)
#----------------------------------------------------------------
# Generated CMake target import file.
#----------------------------------------------------------------
# Commands may need to know the format version.
set(CMAKE_IMPORT_FILE_VERSION 1)
# Protect against multiple inclusion, which would fail when already imported targets are added once more.
set(_cmake_targets_defined "")
set(_cmake_targets_not_defined "")
set(_cmake_expected_targets "")
foreach(_cmake_expected_target IN ITEMS Spout2::Spout Spout2::Spout_static Spout2::SpoutDX Spout2::SpoutDX_static Spout2::SpoutDX12 Spout2::SpoutDX12_static Spout2::SpoutDX9 Spout2::SpoutDX9_static Spout2::SpoutLibrary)
list(APPEND _cmake_expected_targets "${_cmake_expected_target}")
if(TARGET "${_cmake_expected_target}")
list(APPEND _cmake_targets_defined "${_cmake_expected_target}")
else()
list(APPEND _cmake_targets_not_defined "${_cmake_expected_target}")
endif()
endforeach()
unset(_cmake_expected_target)
if(_cmake_targets_defined STREQUAL _cmake_expected_targets)
unset(_cmake_targets_defined)
unset(_cmake_targets_not_defined)
unset(_cmake_expected_targets)
unset(CMAKE_IMPORT_FILE_VERSION)
cmake_policy(POP)
return()
endif()
if(NOT _cmake_targets_defined STREQUAL "")
string(REPLACE ";" ", " _cmake_targets_defined_text "${_cmake_targets_defined}")
string(REPLACE ";" ", " _cmake_targets_not_defined_text "${_cmake_targets_not_defined}")
message(FATAL_ERROR "Some (but not all) targets in this export set were already defined.\nTargets Defined: ${_cmake_targets_defined_text}\nTargets not yet defined: ${_cmake_targets_not_defined_text}\n")
endif()
unset(_cmake_targets_defined)
unset(_cmake_targets_not_defined)
unset(_cmake_expected_targets)
# Compute the installation prefix relative to this file.
get_filename_component(_IMPORT_PREFIX "${CMAKE_CURRENT_LIST_FILE}" PATH)
get_filename_component(_IMPORT_PREFIX "${_IMPORT_PREFIX}" PATH)
get_filename_component(_IMPORT_PREFIX "${_IMPORT_PREFIX}" PATH)
get_filename_component(_IMPORT_PREFIX "${_IMPORT_PREFIX}" PATH)
if(_IMPORT_PREFIX STREQUAL "/")
set(_IMPORT_PREFIX "")
endif()
# Create imported target Spout2::Spout
add_library(Spout2::Spout SHARED IMPORTED)
set_target_properties(Spout2::Spout PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${_IMPORT_PREFIX}/include"
)
# Create imported target Spout2::Spout_static
add_library(Spout2::Spout_static STATIC IMPORTED)
set_target_properties(Spout2::Spout_static PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${_IMPORT_PREFIX}/include"
INTERFACE_LINK_LIBRARIES "\$<LINK_ONLY:opengl32>;\$<LINK_ONLY:kernel32>;\$<LINK_ONLY:user32>;\$<LINK_ONLY:gdi32>;\$<LINK_ONLY:winspool>;\$<LINK_ONLY:comdlg32>;\$<LINK_ONLY:comctl32>;\$<LINK_ONLY:advapi32>;\$<LINK_ONLY:shell32>;\$<LINK_ONLY:ole32>;\$<LINK_ONLY:oleaut32>;\$<LINK_ONLY:uuid>;\$<LINK_ONLY:odbc32>;\$<LINK_ONLY:odbccp32>;\$<LINK_ONLY:d3d9>;\$<LINK_ONLY:d3d11>;\$<LINK_ONLY:DXGI>;\$<LINK_ONLY:Version>"
)
# Create imported target Spout2::SpoutDX
add_library(Spout2::SpoutDX SHARED IMPORTED)
set_target_properties(Spout2::SpoutDX PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${_IMPORT_PREFIX}/include"
)
# Create imported target Spout2::SpoutDX_static
add_library(Spout2::SpoutDX_static STATIC IMPORTED)
set_target_properties(Spout2::SpoutDX_static PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${_IMPORT_PREFIX}/include"
)
# Create imported target Spout2::SpoutDX12
add_library(Spout2::SpoutDX12 SHARED IMPORTED)
set_target_properties(Spout2::SpoutDX12 PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${_IMPORT_PREFIX}/include"
)
# Create imported target Spout2::SpoutDX12_static
add_library(Spout2::SpoutDX12_static STATIC IMPORTED)
set_target_properties(Spout2::SpoutDX12_static PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${_IMPORT_PREFIX}/include"
)
# Create imported target Spout2::SpoutDX9
add_library(Spout2::SpoutDX9 SHARED IMPORTED)
set_target_properties(Spout2::SpoutDX9 PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${_IMPORT_PREFIX}/include"
)
# Create imported target Spout2::SpoutDX9_static
add_library(Spout2::SpoutDX9_static STATIC IMPORTED)
set_target_properties(Spout2::SpoutDX9_static PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${_IMPORT_PREFIX}/include"
)
# Create imported target Spout2::SpoutLibrary
add_library(Spout2::SpoutLibrary SHARED IMPORTED)
set_target_properties(Spout2::SpoutLibrary PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${_IMPORT_PREFIX}/include"
)
# Load information for each installed configuration.
file(GLOB _cmake_config_files "${CMAKE_CURRENT_LIST_DIR}/spout2-targets-*.cmake")
foreach(_cmake_config_file IN LISTS _cmake_config_files)
include("${_cmake_config_file}")
endforeach()
unset(_cmake_config_file)
unset(_cmake_config_files)
# Cleanup temporary variables.
set(_IMPORT_PREFIX)
# Loop over all imported files and verify that they actually exist
foreach(_cmake_target IN LISTS _cmake_import_check_targets)
if(CMAKE_VERSION VERSION_LESS "3.28"
OR NOT DEFINED _cmake_import_check_xcframework_for_${_cmake_target}
OR NOT IS_DIRECTORY "${_cmake_import_check_xcframework_for_${_cmake_target}}")
foreach(_cmake_file IN LISTS "_cmake_import_check_files_for_${_cmake_target}")
if(NOT EXISTS "${_cmake_file}")
message(FATAL_ERROR "The imported target \"${_cmake_target}\" references the file
\"${_cmake_file}\"
but this file does not exist. Possible reasons include:
* The file was deleted, renamed, or moved to another location.
* An install or uninstall procedure did not complete successfully.
* The installation package was faulty and contained
\"${CMAKE_CURRENT_LIST_FILE}\"
but not all the files it references.
")
endif()
endforeach()
endif()
unset(_cmake_file)
unset("_cmake_import_check_files_for_${_cmake_target}")
endforeach()
unset(_cmake_target)
unset(_cmake_import_check_targets)
# This file does not depend on other imported targets which have
# been exported from the same project but in a separate export set.
# Commands beyond this point should not need to know the version.
set(CMAKE_IMPORT_FILE_VERSION)
cmake_policy(POP)
@@ -0,0 +1,102 @@
//
// Header: SpoutCommon.h
//
// Enables build of the SDK as a DLL.
//
// Includes header for common utilities namespace "SpoutUtils".
//
// Optional _#define legacyOpenGL_ to enable legacy draw functions
//
/*
Thanks and credit to Malcolm Bechard, the author of this file
https://github.com/mbechard
Copyright (c) 2014-2024, 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.
03.07.23 - Remove _MSC_VER condition from SPOUT_DLLEXP define
(#PR93 Fix MinGW error (beta branch)
07.12.23 - using namespace spoututils moved from SpoutGL.h
*/
#pragma once
#ifndef __SpoutCommon__
#define __SpoutCommon__
//
// To build the Spout library as a dll, define
// SPOUT_BUILD_DLL in the preprocessor defines.
// Properties > C++ > Preprocessor > Preprocessor Definitions
//
#ifndef SPOUT_DLLEXP
#if defined(SPOUT_BUILD_DLL)
#define SPOUT_DLLEXP __declspec(dllexport)
#elif defined(SPOUT_IMPORT_DLL)
#define SPOUT_DLLEXP __declspec(dllimport)
#else
#define SPOUT_DLLEXP
#endif
#endif
// Common utility functions namespace
#include "SpoutUtils.h"
//
// This definition enables legacy OpenGL rendering code
// used for shared texture Draw functions in SpoutGLDXinterop.cpp
// Not required unless compatibility with OpenGL < 3 is necessary
// Disabled by default for OpenGL 4 compliance
// * Note that the same definition is necessary in SpoutGLextensions.h
// so that SpoutGLextensions can be used independently of the Spout library.
//
// #define legacyOpenGL
//
//
// Visual Studio code analysis warnings
//
// C++11 scoped (class) enums are not compatible with early compilers (< VS2012 and others).
// The warning is designated "Prefer" and "C" standard unscoped enums are retained for compatibility.
#if defined(_MSC_VER)
#pragma warning(disable:26812) // unscoped enums
#endif
//
// For ARM build
// __movsd intrinsic not defined
//
#if defined _M_ARM64
#include <memory.h>
inline void __movsd(unsigned long* Destination,
const unsigned long* Source, size_t Count)
{
memcpy(Destination, Source, Count);
}
#endif
#endif
@@ -0,0 +1,223 @@
/*
SpoutCopy.h
Functions to manage pixel buffer copying
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Copyright (c) 2016-2024, 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 __spoutCopy__ // standard way as well
#define __spoutCopy__
#include "SpoutCommon.h"
#include <windows.h>
#include <stdio.h> // for debug printf
#include <gl/gl.h> // For OpenGL definitions
#include <intrin.h> // for cpuid to test for SSE2
#ifdef _M_ARM64
#include <sse2neon.h> // for NEON
#else
#include <emmintrin.h> // for SSE2
#include <tmmintrin.h> // for SSSE3
#endif
#include <cmath> // For compatibility with Clang. PR#81
#include <stdint.h> // for _uint32 etc
class SPOUT_DLLEXP spoutCopy {
public:
spoutCopy();
~spoutCopy();
// Copy image pixels and select fastest method based on image width
void CopyPixels(const unsigned char *src, unsigned char *dst,
unsigned int width, unsigned int height,
GLenum glFormat = GL_RGBA, bool bInvert = false) const;
// Flip a pixel buffer in place
void FlipBuffer(const unsigned char *src, unsigned char *dst,
unsigned int width, unsigned int height,
GLenum glFormat = GL_RGBA) const;
// Correct for image stride
void RemovePadding(const unsigned char* source, unsigned char* dest,
unsigned int width, unsigned int height,
unsigned int source_stride, GLenum glFormat) const;
// Clear alpha of rgba image pixels to the required value
void ClearAlpha(unsigned char* src, unsigned int width,
unsigned int height, unsigned char alpha) const;
// SSE2 version of memcpy
void memcpy_sse2(void* dst, const void* src, size_t size) const;
//
// RGBA <> RGBA
//
// Copy rgba buffers line by line allowing for source pitch using the fastest method
void rgba2rgba(const void* source, void* dest, unsigned int width, unsigned int height,
unsigned int sourcePitch, bool bInvert = false) const;
// Copy rgba buffers line by line allowing for source and destination line pitch
void rgba2rgba(const void* source, void* dest, unsigned int width, unsigned int height,
unsigned int sourcePitch, unsigned int destPitch, bool bInvert) const;
// Copy rgba buffers of differing size
void rgba2rgbaResample(const void* source, void* dest,
unsigned int sourceWidth, unsigned int sourceHeight, unsigned int sourcePitch,
unsigned int destWidth, unsigned int destHeight, bool bInvert = false) const;
//
// RGBA <> BGRA
//
// Copy rgba to bgra using the fastest method
void rgba2bgra(const void* rgba_source, void* bgra_dest, unsigned int width, unsigned int height, bool bInvert = false) const;
// Copy rgba to bgra line by line allowing for source pitch using the fastest method
void rgba2bgra(const void* rgba_source, void* bgra_dest, unsigned int width, unsigned int height,
unsigned int sourcePitch, bool bInvert = false) const;
// Copy rgba to bgra line allowing for source and destination line pitch
void rgba2bgra(const void* source, void* dest, unsigned int width, unsigned int height,
unsigned int sourcePitch, unsigned int destPitch, bool bInvert) const;
// Copy bgra to rgba
void bgra2rgba(const void* bgra_source, void *rgba_dest, unsigned int width, unsigned int height, bool bInvert = false) const;
//
// RGBA <> RGB, RGBA <> BGR
//
// TODO : add RGBA pitch to all functions
// TODO : avoid redundancy
// Copy RGBA to RGB or BGR allowing for source line pitch using the fastest method
void rgba2rgb (const void* rgba_source, void* rgb_dest, unsigned int width, unsigned int height,
unsigned int sourcePitch, // byte line pitch
bool bInvert = false, // Flip vertically
bool bMirror = false, // Mirror horizontally
bool bSwapRB = false) const; // swap red and blue (rgb > bgr) const;
// Copy RGBA to BGR allowing for source line pitch
void rgba2bgr(const void* rgba_source, void* rgb_dest, unsigned int width, unsigned int height,
unsigned int sourcePitch, bool bInvert = false) const;
// Copy RGBA to RGB allowing for source and destination pitch
void rgba2rgbResample(const void* source, void* dest,
unsigned int sourceWidth, unsigned int sourceHeight, unsigned int sourcePitch,
unsigned int destWidth, unsigned int destHeight,
bool bInvert = false, bool bMirror = false, bool bSwapRB = false) const;
// Copy RGBA to BGR allowing for source and destination pitch
void rgba2bgrResample(const void* source, void* dest,
unsigned int sourceWidth, unsigned int sourceHeight, unsigned int sourcePitch,
unsigned int destWidth, unsigned int destHeight, bool bInvert = false) const;
//
// SSE3 function
//
// RGBA to RGB/BGR with source line pitch
//
void rgba_to_rgb_sse3(const void* rgba_source, void* rgb_dest,
unsigned int width, unsigned int height,
unsigned int rgba_pitch, // line byte pitch
bool bInvert = false, // Flip image
bool bSwapRB = false) const; // Swap RG (BGR)
//
// Byte functions
//
// Copy RGB to RGBA
void rgb2rgba (const void* rgb_source, void *rgba_dest, unsigned int width, unsigned int height, bool bInvert = false) const;
// Copy RGB to RGBA allowing for destination pitch
void rgb2rgba(const void *rgb_source, void *rgba_dest,
unsigned int width, unsigned int height,
unsigned int dest_pitch, bool bInvert) const;
// Copy BGR to RGBA
void bgr2rgba (const void* bgr_source, void *rgba_dest, unsigned int width, unsigned int height, bool bInvert = false) const;
// Copy BGR to RGBA allowing for destination pitch
void bgr2rgba(const void *rgb_source, void *rgba_dest,
unsigned int width, unsigned int height,
unsigned int dest_pitch, bool bInvert) const;
//
// RGB > BGRA
//
// Copy RGB to BGRA
void rgb2bgra (const void* rgb_source, void *bgra_dest, unsigned int width, unsigned int height, bool bInvert = false) const;
// Copy RGB to BGRA allowing for destination pitch
void rgb2bgra(const void *rgb_source, void *bgra_dest,
unsigned int width, unsigned int height,
unsigned int dest_pitch, bool bInvert) const;
// Experimental SSE RGB to BGRA
// Single line
void rgb_to_bgrx_sse(unsigned int npixels, const void* rgb_source, void* bgrx_out) const;
// Full height
void rgb_to_bgra_sse3(void* rgb_source, void* rgba_dest, unsigned int width, unsigned int height) const;
// Copy BGR to BGRA
void bgr2bgra (const void* bgr_source, void *bgra_dest, unsigned int width, unsigned int height, bool bInvert = false) const;
// Copy RGBA to BGR
void rgba2bgr (const void* rgba_source, void *bgr_dest, unsigned int width, unsigned int height, bool bInvert = false) const;
// Copy BGRA to RGB
void bgra2rgb (const void* bgra_source, void *rgb_dest, unsigned int width, unsigned int height, bool bInvert = false) const;
// Copy BGRA to BGR
void bgra2bgr (const void* bgra_source, void *bgr_dest, unsigned int width, unsigned int height, bool bInvert = false) const;
// SSE capability
void GetSSE(bool &bSSE2, bool &bSSE3, bool &bSSSE3);
protected :
void CheckSSE();
bool m_bSSE2;
bool m_bSSE3;
bool m_bSSSE3;
void rgba_bgra(const void *rgba_source, void *bgra_dest, unsigned int width, unsigned int height, bool bInvert = false) const;
void rgba_bgra_sse2(const void *rgba_source, void *bgra_dest, unsigned int width, unsigned int height, bool bInvert = false) const;
void rgba_bgra_sse3(const void *rgba_source, void *bgra_dest, unsigned int width, unsigned int height, bool bInvert = false) const;
};
#endif
@@ -0,0 +1,381 @@
/*
SpoutDX.h
Sender and receiver for DirectX applications
Copyright (c) 2014-2024 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 __spoutDX__
#define __spoutDX__
//
// Include file path
//
// 1) If the include files are in the same folder there is no prefix.
// This applies for a build using SpoutDX dll or static library.
//
// 2) If the Spout source is built as a dll or static library,
// or an application is built using the repository folder structure
// the path prefix for include files is "..\..\SpoutGL\"
//
// 3) If the include files are in a different folder, change the prefix as required.
//
#if __has_include("SpoutCommon.h")
#include "SpoutCommon.h" // include files in the same folder
#include "SpoutDirectX.h"
#include "SpoutSenderNames.h"
#include "SpoutFrameCount.h"
#include "SpoutCopy.h"
#include "SpoutUtils.h"
#else
#include "..\..\SpoutGL\SpoutCommon.h" // repository folder structure
#include "..\..\SpoutGL\SpoutDirectX.h"
#include "..\..\SpoutGL\SpoutSenderNames.h"
#include "..\..\SpoutGL\SpoutFrameCount.h"
#include "..\..\SpoutGL\SpoutCopy.h"
#include "..\..\SpoutGL\SpoutUtils.h"
#endif
#include <direct.h> // for _getcwd
#include <TlHelp32.h> // for PROCESSENTRY32
#include <tchar.h> // for _tcsicmp
#include <psapi.h> // for GetModuleFileNameExA
#pragma comment(lib, "Psapi.lib")
class SPOUT_DLLEXP spoutDX {
public:
spoutDX();
~spoutDX();
//
// DIRECTX
//
bool OpenDirectX11(ID3D11Device* pDevice = nullptr);
ID3D11Device* GetDX11Device();
ID3D11DeviceContext* GetDX11Context();
void CloseDirectX11();
bool IsClassDevice();
//
// SENDER
//
// Set the sender name
bool SetSenderName(const char* sendername = nullptr);
// Set the sender texture format
void SetSenderFormat(DXGI_FORMAT format);
// Close sender and free resources
void ReleaseSender();
// Send the back buffer
bool SendBackBuffer();
// Send a texture
bool SendTexture(ID3D11Texture2D* pTexture);
// Send part of a texture
bool SendTexture(ID3D11Texture2D* pTexture,
unsigned int xoffset, unsigned int yoffset,
unsigned int width, unsigned int height);
// Send an image
bool SendImage(const unsigned char * pData, unsigned int width, unsigned int height);
// Sender status
bool IsInitialized();
// Sender name
const char * GetName();
// Get width
unsigned int GetWidth();
// Get height
unsigned int GetHeight();
// Get frame rate
double GetFps();
// Get frame number
long GetFrame();
//
// RECEIVER
//
// Set the sender to connect to
void SetReceiverName(const char * sendername = nullptr);
// Close receiver and free resources
void ReleaseReceiver();
// Receive from a sender
bool ReceiveTexture();
// Receive a texture from a sender
bool ReceiveTexture(ID3D11Texture2D** ppTexture);
// Receive an image
bool ReceiveImage(unsigned char * pixels, unsigned int width, unsigned int height, bool bRGB = false, bool bInvert = false);
// Read pixels from texture
bool ReadTexurePixels(ID3D11Texture2D* ppTexture, unsigned char* pixels);
// Open sender selection dialog
bool SelectSender(HWND hwnd = NULL);
// Sender has changed
bool IsUpdated();
// Connected to a sender
bool IsConnected();
// Received frame is new
bool IsFrameNew();
// Received texture
ID3D11Texture2D* GetSenderTexture();
// Received sender share handle
HANDLE GetSenderHandle();
// Received sender texture format
DXGI_FORMAT GetSenderFormat();
// Received sender name
const char * GetSenderName();
// Received sender width
unsigned int GetSenderWidth();
// Received sender height
unsigned int GetSenderHeight();
// Received sender frame rate
double GetSenderFps();
// Received sender frame number
long GetSenderFrame();
//
// COMMON
//
// Frame rate control
void HoldFps(int fps);
// Disable frame counting for this application
void DisableFrameCount();
// Return frame count status
bool IsFrameCountEnabled();
// Signal sync event
void SetFrameSync(const char* SenderName);
// Wait or test for a sync event
bool WaitFrameSync(const char *SenderName, DWORD dwTimeout = 0);
//
// Sender names
//
// Get number of senders
int GetSenderCount();
// Get sender name for a given index
bool GetSender(int index, char* sendername, int MaxSize = 256);
// Return a list of current senders
std::vector<std::string> GetSenderList();
// Sender index into the set of names
int GetSenderIndex(const char* sendername);
// Get sender details
bool GetSenderInfo(const char* sendername, unsigned int &width, unsigned int &height, HANDLE &dxShareHandle, DWORD &dwFormat);
// Get active sender name
bool GetActiveSender(char* sendername);
// set active sender name
bool SetActiveSender(const char* sendername);
// Get maximum senders allowed
int GetMaxSenders();
// Set maximum senders allowed
void SetMaxSenders(int maxSenders);
//
// Adapter functions
//
// Get the number of graphics adapters in the system
int GetNumAdapters();
// Get the adapter name for a given index
bool GetAdapterName(int index, char *adaptername, int maxchars);
// Get the current adapter description
bool GetAdapterInfo(char *renderdescription, char *displaydescription, int maxchars);
// Get the current adapter index
int GetAdapter();
// Set required graphics adapter for output (no args or -1 to reset)
bool SetAdapter(int index = -1);
// Get adapter pointer for a given adapter (-1 means current)
IDXGIAdapter* GetAdapterPointer(int index = -1);
// Set required graphics adapter for creating a device
void SetAdapterPointer(IDXGIAdapter* pAdapter);
// Get auto device switching status
bool GetAdapterAuto();
// Auto switch receiving device to use the same graphics adapter as the sender
void SetAdapterAuto(bool bAuto = true);
// Get sender adapter index and name for a given sender
int GetSenderAdapter(const char* sendername, char* adaptername = nullptr, int maxchars = 256);
//
// Graphics preference
//
// Windows 10 Vers 1803, build 17134 or later
#ifdef NTDDI_WIN10_RS4
// Get the Windows graphics preference for an application
// -1 - No preference
// 0 - Default
// 1 - Power saving
// 2 - High performance
// If no path is specified, use the current application path
int GetPerformancePreference(const char* path = nullptr);
// Set the Windows graphics preference for an application
// -1 - No preference
// 0 - Default
// 1 - Power saving
// 2 - High performance
// If no path is specified, use the current application path
bool SetPerformancePreference(int preference, const char* path = nullptr);
// Get the graphics adapter name for a Windows preference
bool GetPreferredAdapterName(int preference, char* adaptername, int maxchars);
// Set graphics adapter index for a Windows preference
bool SetPreferredAdapter(int preference);
// Windows graphics preference availability
bool IsPreferenceAvailable();
// Is the path a valid application
bool IsApplicationPath(const char* path);
#endif
//
// Sharing modes (2.006 compatibility)
//
// Get user selected DX9 mode (2.006)
bool GetDX9();
bool GetMemoryShareMode();
//
// Utility
//
void CheckSenderFormat(char * sendername);
bool CreateDX11texture(ID3D11Device* pd3dDevice,
unsigned int width, unsigned int height,
DXGI_FORMAT format, ID3D11Texture2D** ppTexture);
//
// SpoutUtils namespace functions for dll access
//
void OpenSpoutConsole();
void CloseSpoutConsole(bool bWarning = false);
void EnableSpoutLog();
void EnableSpoutLogFile(const char* filename, bool append = false);
void DisableSpoutLogFile();
void DisableSpoutLog();
int SpoutMessageBox(const char* message, DWORD dwMilliseconds = 0);
int SpoutMessageBox(const char* caption, UINT uType, const char* format, ...);
int SpoutMessageBox(HWND hwnd, LPCSTR message, LPCSTR caption, UINT uType, DWORD dwMilliseconds = 0);
int SpoutMessageBox(HWND hwnd, LPCSTR message, LPCSTR caption, UINT uType, const char* instruction, DWORD dwMilliseconds = 0);
int SpoutMessageBox(HWND hwnd, LPCSTR message, LPCSTR caption, UINT uType, std::string& text);
int SpoutMessageBox(HWND hwnd, LPCSTR message, LPCSTR caption, UINT uType, std::vector<std::string> items, int& selected);
//
// Data sharing
//
// Write data to shared memory
bool WriteMemoryBuffer(const char *name, const char* data, int length);
// Read data from shared memory
int ReadMemoryBuffer(const char* name, char* data, int maxlength);
// Create a shared memory buffer
bool CreateMemoryBuffer(const char *name, int length);
// Delete a shared memory buffer
bool DeleteMemoryBuffer();
// Get the number of bytes available for data transfer
int GetMemoryBufferSize(const char *name);
//
// Options used for SpoutCam
//
// Mirror image
void SetMirror(bool bMirror = true);
// RGB <> BGR
void SetSwap(bool bSwap = true);
bool GetMirror();
bool GetSwap();
//
// Public for external access
//
spoutSenderNames sendernames;
spoutFrameCount frame;
spoutDirectX spoutdx;
spoutCopy spoutcopy;
protected :
ID3D11Device* m_pd3dDevice;
ID3D11DeviceContext* m_pImmediateContext;
ID3D11Texture2D* m_pSharedTexture;
ID3D11Texture2D* m_pTexture;
ID3D11Texture2D* m_pStaging[2];
int m_Index;
int m_NextIndex;
HANDLE m_dxShareHandle;
DWORD m_dwFormat;
SharedTextureInfo m_SenderInfo;
char m_SenderNameSetup[256];
char m_SenderName[256];
unsigned int m_Width;
unsigned int m_Height;
bool m_bUpdated;
bool m_bConnected;
bool m_bSpoutInitialized;
bool m_bSpoutPanelOpened;
bool m_bSpoutPanelActive;
bool m_bClassDevice;
bool m_bAdapt;
bool m_bMemoryShare; // Using 2.006 memoryshare methods
bool m_bMirror; // Mirror image
bool m_bSwapRB; // RGB <> BGR
SHELLEXECUTEINFOA m_ShExecInfo; // For ShellExecute
// For WriteMemoryBuffer/ReadMemoryBuffer
SpoutSharedMemory memorybuffer;
bool CheckSender(unsigned int width, unsigned int height, DWORD dwFormat);
ID3D11Texture2D* CheckSenderTexture(char *sendername, HANDLE dxShareHandle);
bool ReceiveSenderData();
void CreateReceiver(const char * sendername, unsigned int width, unsigned int height, DWORD dwFormat);
// Read pixels from a staging texture
bool ReadPixelData(ID3D11Texture2D* pStagingSource, unsigned char* destpixels,
unsigned int width, unsigned int height, bool bRGB, bool bInvert, bool bSwap);
// Create or update staging textures
bool CheckStagingTextures(unsigned int width, unsigned int height, DWORD dwFormat = DXGI_FORMAT_B8G8R8A8_UNORM);
// Create or update class texture
bool CheckTexture(unsigned int width, unsigned int height, DWORD dwFormat);
bool SelectSenderPanel(const char* message = nullptr);
bool CheckSpoutPanel(char *sendername, int maxchars = 256);
};
#endif
@@ -0,0 +1,178 @@
/*
spoutDirectX.h
Functions to manage DirectX 11 texture sharing
Copyright (c) 2014 - 2024, 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 __spoutDirectX__
#define __spoutDirectX__
#include "SpoutCommon.h"
#include <d3d9.h> // For format definitions
#include <d3d11.h>
#include <d3d11_1.h>
#include <ntverp.h>
//
// Windows graphics preferences are available for Windows 10 Vers 1803
// build 17134 or later, and use dxgi1_6.
//
// If existing Visual Studio projects use Microsoft DirectX SDK (June 2010),
// this will conflict because the older SDK will be included first.
// The include order in the project file should be changed to include the older SDK last.
// Change :
// <IncludePath>$(DXSDK_DIR)Include$(IncludePath);</IncludePath>
// <LibraryPath>$(DXSDK_DIR)Lib\x86$(LibraryPath);</LibraryPath>
// To :
// <IncludePath>$(IncludePath);$(DXSDK_DIR)Include</IncludePath>
// <LibraryPath>$(LibraryPath);$(DXSDK_DIR)Lib\x86</LibraryPath>
//
#ifdef NTDDI_WIN10_RS4
#include <dxgi1_6.h> // for adapter performance preference
#endif
#pragma comment (lib, "d3d11.lib")// the Direct3D 11 Library file
#pragma comment (lib, "DXGI.lib") // for CreateDXGIFactory1
using namespace spoututils;
class SPOUT_DLLEXP spoutDirectX {
public:
spoutDirectX();
~spoutDirectX();
//
// DirectX11 device
//
// Initialize and prepare DirectX 11
bool OpenDirectX11(ID3D11Device* pDevice = nullptr);
// Release DirectX 11 device and context
void CloseDirectX11();
// Set the DirectX11 device
bool SetDX11Device(ID3D11Device* pDevice);
// Create a DirectX11 device
ID3D11Device* CreateDX11device();
// Return the class device
ID3D11Device* GetDX11Device();
// Return the device immediate context
ID3D11DeviceContext* GetDX11Context();
// Return the device feature level
D3D_FEATURE_LEVEL GetDX11FeatureLevel();
//
// DirectX11 texture
//
// Create a DirectX11 shared texture
bool CreateSharedDX11Texture(ID3D11Device* pDevice, unsigned int width, unsigned int height, DXGI_FORMAT format, ID3D11Texture2D** ppSharedTexture, HANDLE &dxShareHandle, bool bKeyed = false, bool bNThandle = false);
// Create a DirectX texture which is not shared
bool CreateDX11Texture(ID3D11Device* pDevice, unsigned int width, unsigned int height, DXGI_FORMAT format, ID3D11Texture2D** ppTexture);
// Create a DirectX 11 staging texture for read and write
bool CreateDX11StagingTexture(ID3D11Device* pDevice, unsigned int width, unsigned int height, DXGI_FORMAT format, ID3D11Texture2D** pStagingTexture);
// Retrieve the pointer of a DirectX11 shared texture
bool OpenDX11shareHandle(ID3D11Device* pDevice, ID3D11Texture2D** ppSharedTexture, HANDLE dxShareHandle);
//
// DirectX11 utilities
//
// Release a texture resource created with a class device
unsigned long ReleaseDX11Texture(ID3D11Texture2D* pTexture);
// Release a texture resource
unsigned long ReleaseDX11Texture(ID3D11Device* pd3dDevice, ID3D11Texture2D* pTexture);
// Release a device
unsigned long ReleaseDX11Device(ID3D11Device* pd3dDevice);
// Flush immediate context command queue
void Flush();
// Flush immediate context command queue and wait for completion
void FlushWait(ID3D11Device* pd3dDevice, ID3D11DeviceContext* pImmediateContext);
// Wait for completion after flush
void Wait(ID3D11Device* pd3dDevice, ID3D11DeviceContext* pImmediateContext);
//
// Graphics adapter
//
// Get the number of graphics adapters in the system
int GetNumAdapters();
// Get the name of an adapter index
bool GetAdapterName(int index, char *adaptername, int maxchars);
// Get the index of an adapter name
int GetAdapterIndex(const char* adaptername);
// Get the current adapter index
int GetAdapter();
// Set graphics adapter for CreateDX11device from an index
bool SetAdapter(int index = -1);
// Get the description and output display name of the current adapter
bool GetAdapterInfo(char* adaptername, char* output, int maxchars);
// Get the description and output display name for a given adapter
bool GetAdapterInfo(int index, char* adaptername, char* output, int maxchars);
// Get adapter pointer for a given adapter (-1 means current)
IDXGIAdapter* GetAdapterPointer(int index = -1);
// Set required graphics adapter for CreateDX11device
void SetAdapterPointer(IDXGIAdapter* pAdapter);
// Find the index of the NVIDIA adapter in a multi-adapter system
bool FindNVIDIA(int &nAdapter);
//
// Graphics preference
// Windows 10 Vers 1803, build 17134 or later
//
// Get the Windows graphics preference for an application
int GetPerformancePreference(const char* path = nullptr);
// Set the Windows graphics preference for an application
bool SetPerformancePreference(int preference, const char* path = nullptr);
// Get the graphics adapter name for a Windows preference
bool GetPreferredAdapterName(int preference, char* adaptername, int maxchars);
// Set graphics adapter index for a Windows preference
bool SetPreferredAdapter(int preference);
// Windows graphics preference availability
bool IsPreferenceAvailable();
// Is the path a valid application
bool IsApplicationPath(const char* path);
protected:
void DebugLog(ID3D11Device* pd3dDevice, const char* format, ...);
int m_AdapterIndex; // Adapter index
IDXGIAdapter* m_pAdapterDX11; // Adapter pointer
ID3D11Device* m_pd3dDevice; // DX11 device
ID3D11DeviceContext* m_pImmediateContext;
bool m_bClassDevice;
D3D_DRIVER_TYPE m_driverType;
D3D_FEATURE_LEVEL m_featureLevel;
ID3D11Device1* m_pd3dDevice1;
ID3D11DeviceContext1* m_pImmediateContext1;
};
#endif
@@ -0,0 +1,188 @@
/*
SpoutFrameCount.h
Frame counting management
Copyright (c) 2019-2025. 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 __spoutFrameCount__
#define __spoutFrameCount__
#include "SpoutCommon.h"
#include "SpoutSharedMemory.h"
#include <string>
#include <vector>
#include <d3d11.h>
#pragma comment (lib, "d3d11.lib") // for keyed mutex texture access
#pragma comment (lib, "Winmm.lib") // for timer resolution functions
using namespace spoututils;
// USE_CHRONO is defined in SpoutUtils.h
// Note comments about using an early platform toolset
#ifdef USE_CHRONO
#include <chrono> // c++11 timer
#include <thread>
#endif
class SPOUT_DLLEXP spoutFrameCount {
public:
spoutFrameCount();
~spoutFrameCount();
//
// Frame counting
//
// Enable or disable frame counting globally by registry setting
void SetFrameCount(bool bEnable);
// Enable frame counting for this sender
void EnableFrameCount(const char* SenderName);
// Disable frame counting
void DisableFrameCount();
// Pause frame counting
void PauseFrameCount(bool bPaused = true);
// Check status of frame counting
bool IsFrameCountEnabled();
// Is the received frame new
bool IsFrameNew();
// Received frame rate
double GetSenderFps();
// Received frame count
long GetSenderFrame();
// Frame rate control
void HoldFps(int fps);
//
// Used by other classes
//
// Sender increment the semaphore count
void SetNewFrame();
// Receiver read the semaphore count
bool GetNewFrame();
// For class cleanup functions
void CleanupFrameCount();
//
// Mutex locks including DirectX 11 keyed mutex
// DX11 texture keyed mutex functions are private
// and called by the follwoing functions
//
// Test for texture access using a named sender mutex or keyed texture mutex
bool CheckTextureAccess(ID3D11Texture2D* D3D11texture = nullptr);
// Release mutex and allow texture access
bool AllowTextureAccess(ID3D11Texture2D* D3D11texture = nullptr);
//
// Named mutex for shared texture access
//
// Create named mutex for a sender
bool CreateAccessMutex(const char * SenderName);
// Close the texture access mutex.
void CloseAccessMutex();
// Test access using a named mutex
bool CheckAccess();
// Allow access after gaining ownership
void AllowAccess();
// Test for keyed mutex
bool IsKeyedMutex(ID3D11Texture2D* D3D11texture);
//
// Sync events
//
// Set sync event
void SetFrameSync(const char* name);
// Wait or test for a sync event
bool WaitFrameSync(const char *name, DWORD dwTimeout = 0);
// Close sync event
void CloseFrameSync();
// Enable / disable frame sync
void EnableFrameSync(bool bSync = true);
// Check for frame sync option
bool IsFrameSyncEnabled();
protected:
// Texture access named mutex
HANDLE m_hAccessMutex;
// DX11 texture keyed mutex checks
bool CheckKeyedAccess(ID3D11Texture2D* D3D11texture);
bool AllowKeyedAccess(ID3D11Texture2D* D3D11texture);
// Frame count semaphore
bool m_bFrameCount; // Registry setting of frame count
bool m_bCountDisabled; // application disable
bool m_bIsNewFrame; // received frame is new
HANDLE m_hCountSemaphore; // semaphore handle
char m_CountSemaphoreName[256]; // semaphore name
char m_SenderName[256]; // sender currently connected to a receiver
long m_FrameCount; // sender frame count
long m_LastFrameCount; // receiver frame comparator
double m_FrameTime;
double m_FrameTimeTotal;
double m_FrameTimeNumber;
double m_lastFrame;
// Sender frame timing
double m_SystemFps;
double m_SenderFps;
void UpdateSenderFps(long framecount = 0);
// Windows minimum time period
UINT m_PeriodMin;
void StartTimePeriod();
void EndTimePeriod();
// Sync event
bool m_bFrameSync;
HANDLE m_hSyncEvent;
void OpenFrameSync(const char* SenderName);
#ifdef USE_CHRONO
// Avoid C4251 warnings in SpoutLibrary by using pointers
// USE_CHRONO is defined in SpoutUtils.h
// Use of std::unique_ptr to avoid warning C26409 using new/delete
// results in warning C4251 needs to have dll-interface
std::chrono::steady_clock::time_point* m_FpsStartPtr;
std::chrono::steady_clock::time_point* m_FpsEndPtr;
std::chrono::steady_clock::time_point* m_FrameStartPtr;
std::chrono::steady_clock::time_point* m_FrameEndPtr;
#endif
};
#endif
@@ -0,0 +1,219 @@
/*
spoutSenderNames.h
Spout sender management
Thanks and credit to Malcolm Bechard for modifications to this class
https://github.com/mbechard
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Copyright (c) 2014-2025, 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 __spoutSenderNames__ // standard way as well
#define __spoutSenderNames__
#include "SpoutCommon.h"
#include "SpoutSharedMemory.h"
#include <windowsx.h>
#include <wingdi.h>
#include <set>
#include <map>
#include <string>
#include <vector>
#include <unordered_map>
#include <intrin.h> // for __movsd
#include <stdint.h> // for _uint32
#include <assert.h>
#ifdef _M_ARM64
#include <sse2neon.h> // For ARM
#endif
// 100 msec wait for events
#define SPOUT_WAIT_TIMEOUT 100
// MaxSenders define replaced by a global class variable (Maximum for list of Sender names)
#define SpoutMaxSenderNameLen 256
// The texture information structure that is saved to shared memory
// and used for communication between senders and receivers
// uint32_t is used for compatibility between 32bit and 64bit
// The structure is declared here so that this class is can be independent of opengl
//
// Use helper functions for conversion between HANDLE and uint32_t
// https://msdn.microsoft.com/en-us/library/aa384267%28VS.85%29.aspx
// in SpoutGLDXinterop.cpp and SpoutSenderNames
//
struct SharedTextureInfo { // 280 bytes total
uint32_t shareHandle; // 4 bytes : texture handle
uint32_t width; // 4 bytes : texture width
uint32_t height; // 4 bytes : texture height
uint32_t format; // 4 bytes : texture pixel format
uint32_t usage; // 4 bytes : texture usage
uint8_t description[256]; // 256 bytes : description
uint32_t partnerId; // 4 bytes : ID
};
//
// GUIDs for additional sender information maps
// Used for development work
// Example
// {AB5C33D6-3654-43F9-85F6-F54872B0460B}
static const char* GUID_queue = "AB5C33D6-3654-43F9-85F6-F54872B0460B";
class SPOUT_DLLEXP spoutSenderNames {
public:
spoutSenderNames();
~spoutSenderNames();
//
// public functions
//
//
// Sender name registration
//
// Register a sender name in the list of senders
bool RegisterSenderName(char* sendername, bool bNewname = false);
// Remove a name from the list
bool ReleaseSenderName(const char* sendername);
// Find a name in the list
bool FindSenderName(const char* sendername);
//
// Functions to retrieve info about the sender set map and the senders in it
//
// Retrieve the sender name list as a set of names
bool GetSenderNames(std::set<std::string> *sendernames);
// Number of senders in the list
int GetSenderCount();
// Sender item name
bool GetSender(int index, char* sendername, int MaxSize = 256);
// Sender index into the set of names
int GetSenderIndex(const char* sendername);
// Information about a sender from an index into the list
bool GetSenderNameInfo(int index, char* sendername, int sendernameMaxSize, unsigned int &width, unsigned int &height, HANDLE &dxShareHandle);
//
// Maximum number of senders allowed in the list
// Applies for versions 2.005 and after
//
// Get the maximum number from the registry
int GetMaxSenders();
// Set the maximum number of senders in a new sender map
void SetMaxSenders(int maxSenders);
//
// Functions to read and write info to a sender memory map
//
// Get sender information
bool GetSenderInfo (const char* sendername, unsigned int &width, unsigned int &height, HANDLE &dxShareHandle, DWORD &dwFormat);
// Set sender information
bool SetSenderInfo (const char* sendername, unsigned int width, unsigned int height, HANDLE dxShareHandle, DWORD dwFormat);
// Set sender PartnerID field with "CPU" sharing method and GL/DX compatibility
bool SetSenderID(const char *sendername, bool bCPU, bool bGLDX);
// Generic sender map info read (returned in a shared texture information structure)
bool getSharedInfo (const char* sendername, SharedTextureInfo* info);
// Generic sender map info write
bool setSharedInfo (const char* sendername, const SharedTextureInfo* info);
// Test for shared info memory map existence
bool hasSharedInfo(const char* sendername);
//
// Functions to maintain the active sender
//
// Set the active sender - the first retrieved by a receiver
bool SetActiveSender (const char* sendername);
// Get the current active sender
bool GetActiveSender (char *sendername, const int maxlength = SpoutMaxSenderNameLen);
// Get active sender information
bool GetActiveSenderInfo (SharedTextureInfo* info);
// Return details of the current active sender
bool FindActiveSender (char *activename, unsigned int& width, unsigned int& height, HANDLE& hSharehandle, DWORD& dwFormat, const int maxlength = SpoutMaxSenderNameLen);
//
// Functions to Create, Find or Update a sender
// without initializing DirectX or the GL/DX interop functions
//
// Create a sender and register the name in the sender list
bool CreateSender(char* sendername, unsigned int width, unsigned int height, HANDLE hSharehandle, DWORD dwFormat = 0);
// Update an existing sender
bool UpdateSender (const char* sendername, unsigned int width, unsigned int height, HANDLE hSharehandle, DWORD dwFormat = 0);
// Check details of a sender
bool CheckSender (const char* sendername, unsigned int &width, unsigned int &height, HANDLE &hSharehandle, DWORD &dwFormat);
// Find a sender and return details
bool FindSender (char* sendername, unsigned int &width, unsigned int &height, HANDLE &hSharehandle, DWORD &dwFormat);
// Find a sender in the class names set
bool FindSender (const char* sendername);
// Release orphaned senders
void CleanSenders();
protected:
// Sender name set management
bool CreateSenderSet();
bool GetSenderSet (std::set<std::string>& SenderNames);
// Active sender management
bool setActiveSenderName (const char* SenderName);
// bool getActiveSenderName (char SenderName[SpoutMaxSenderNameLen]);
bool getActiveSenderName (char *SenderName, const int maxlength = SpoutMaxSenderNameLen);
// Goes through the full list of sender names and cleans up
// any that shouldn't still be around
void cleanSenderSet();
// Functions to manage shared memory map access
static void readSenderSetFromBuffer(const char* buffer, std::set<std::string>& SenderNames, int maxSenders);
static void writeBufferFromSenderSet(const std::set<std::string>& SenderNames, char *buffer, int maxSenders);
SpoutSharedMemory m_senderNames;
SpoutSharedMemory m_activeSender;
// This should be a unordered_map of sender names ->SharedMemory
// to handle multiple inputs and outputs all going through the
// same spoutSenderNames class
// Make this a pointer to avoid size differences between compilers
// if the .dll is compiled with something different
std::unordered_map<std::string, SpoutSharedMemory*>* m_senders;
int m_MaxSenders; // maximum number of senders via registry
};
#endif
@@ -0,0 +1,97 @@
/*
SpoutSharedMemory.h
Thanks and credit to Malcolm Bechard the author of this class
https://github.com/mbechard
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Copyright (c) 2014-2025, 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 __SpoutSharedMemory_ // standard way as well
#define __SpoutSharedMemory_
#include "SpoutCommon.h"
#include <windowsx.h>
#include <wingdi.h>
using namespace spoututils;
//
// Result of memory segment creation
//
enum SpoutCreateResult {
SPOUT_CREATE_FAILED = 0,
SPOUT_CREATE_SUCCESS,
SPOUT_ALREADY_EXISTS,
SPOUT_ALREADY_CREATED,
};
class SPOUT_DLLEXP SpoutSharedMemory {
public:
SpoutSharedMemory();
~SpoutSharedMemory();
// Create a new memory segment, or attach to an existing one
SpoutCreateResult Create(const char* name, int size);
// Open an existing memory map
bool Open(const char* name);
// Close a map
void Close();
// Lock an open map and return the buffer
char* Lock();
// Unlock a map
void Unlock();
// Name of an existing map
const char* Name();
// Size of an existing map
int Size();
// Print map information for debugging
void Debug();
private:
char* m_pBuffer; // Buffer pointer
HANDLE m_hMap; // Map handle
HANDLE m_hMutex; // Mutex for map access
int m_lockCount; // Map access lock count
char* m_pName; // Map name
int m_size; // Map size
};
#endif
@@ -0,0 +1,415 @@
/*
SpoutUtils.h
General utility functions
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Copyright (c) 2017-2025, 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 __spoutUtils__ // standard way as well
#define __spoutUtils__
// Enable this define to use independently of Spout source files
// See also the stand alone define in SpoutGLextensions
// #define standaloneUtils
#ifdef standaloneUtils
#define SPOUT_DLLEXP
#else
// For use together with Spout source files
#include "SpoutCommon.h" // for legacyOpenGL define and Utils
#include <stdint.h> // for _uint32 etc
#endif
#include <windows.h>
#include <stdio.h> // for console
#include <iostream> // std::cout, std::end
#include <fstream> // for log file
#include <time.h> // for time and date
#include <io.h> // for _access
#include <direct.h> // for _getcwd
#include <vector>
#include <string>
#include <Shellapi.h> // for shellexecute
#include <Commctrl.h> // For TaskDialogIndirect
#include <math.h> // for round
//
// C++11 timer is only available for MS Visual Studio 2015 and above.
//
// Note that _MSC_VER may not correspond correctly if an earlier platform toolset
// is selected for a later compiler e.g. Visual Studio 2010 platform toolset for
// a Visual studio 2017 compiler. "#include <chrono>" will then fail.
// If this is a problem, remove _MSC_VER_ and manually enable/disable the USE_CHRONO define.
//
// PR #84 Fixes for clang
// PR #114 Fixes for MingW
#if (defined(_MSC_VER) && (_MSC_VER >= 1900)) || (defined(__cplusplus) && (__cplusplus >= 201103L))
#define USE_CHRONO
#endif
#ifdef USE_CHRONO
#include <chrono> // c++11 timer
#include <thread>
#endif
#pragma comment(lib, "Shell32.lib") // for shellexecute
#pragma comment(lib, "Advapi32.lib") // for registry functions
#pragma comment(lib, "Version.lib") // for version resources where necessary
#pragma comment(lib, "Comctl32.lib") // For taskdialog
// TaskDialog requires comctl32.dll version 6
#ifdef _MSC_VER
// https://learn.microsoft.com/en-us/windows/win32/controls/cookbook-overview
#pragma comment(linker,"\"/manifestdependency:type='win32' \
name='Microsoft.Windows.Common-Controls' version='6.0.0.0' \
processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")
#endif
// SpoutUtils
namespace spoututils {
enum SpoutLogLevel {
// Disable all messages
SPOUT_LOG_SILENT,
// Show all messages
SPOUT_LOG_VERBOSE,
// Show information messages - default
SPOUT_LOG_NOTICE,
// Show warning, errors and fatal
SPOUT_LOG_WARNING,
// Show errors and fatal
SPOUT_LOG_ERROR,
// Show only fatal errors
SPOUT_LOG_FATAL,
// Ignore log levels
SPOUT_LOG_NONE
};
//
// Information
//
// Get SDK version number string e.g. "2.007.000"
// Optional - return as a single number
// e.g. 2.006 = 2006, 2.007 = 2007, 2.007.009 = 2007009
std::string SPOUT_DLLEXP GetSDKversion(int * number = nullptr);
// Get the user Spout version from the registry
// Optional - return as a single number
std::string SPOUT_DLLEXP GetSpoutVersion(int * number = nullptr);
// Computer type
bool SPOUT_DLLEXP IsLaptop();
// Get the module handle of an executable or dll
HMODULE SPOUT_DLLEXP GetCurrentModule();
// Get executable or dll version
std::string SPOUT_DLLEXP GetExeVersion(const char* path);
// Get executable or dll path
std::string SPOUT_DLLEXP GetExePath(bool bFull = false);
// Get executable or dll name
std::string SPOUT_DLLEXP GetExeName();
// Remove path and return the file name
void SPOUT_DLLEXP RemovePath(std::string& path);
// Remove file name and return the path
void SPOUT_DLLEXP RemoveName(std::string& path);
//
// Console management
//
// Open console window.
// A console window opens without logs.
// Useful for debugging with console output.
void SPOUT_DLLEXP OpenSpoutConsole(const char *title = nullptr);
// Close console window.
// The optional warning displays a MessageBox if user notification is required.
void SPOUT_DLLEXP CloseSpoutConsole(bool bWarning = false);
// Enable logging to the console.
// Logs are displayed in a console window.
// Useful for program development.
void SPOUT_DLLEXP EnableSpoutLog(const char* title = nullptr);
// Enable logging to a file with optional append.
// As well as a console window, you can output logs to a text file.
// Default extension is ".log" unless the full path is used.
// For no file name or path the executable name is used.
// Example : EnableSpoutLogFile("Sender.log");
// The log file is re-created every time the application starts
// unless you specify to append to the existing one.
// Example : EnableSpoutLogFile("Sender.log", true);
// The file is saved in the %AppData% folder unless you specify the full path :
// C:>Users>username>AppData>Roaming>Spout
// You can find and examine the log file after the application has run.
void SPOUT_DLLEXP EnableSpoutLogFile(const char* filename = nullptr, bool bAppend = false);
// Disable logging to file
void SPOUT_DLLEXP DisableSpoutLogFile();
// Remove a log file
void SPOUT_DLLEXP RemoveSpoutLogFile(const char* filename = nullptr);
// Disable logging to console and file
void SPOUT_DLLEXP DisableSpoutLog();
// Disable logging temporarily
void SPOUT_DLLEXP DisableLogs();
// Enable logging again
void SPOUT_DLLEXP EnableLogs();
// Are console logs enabled
bool SPOUT_DLLEXP LogsEnabled();
// Is file logging enabled
bool SPOUT_DLLEXP LogFileEnabled();
// Return the full log file path
std::string SPOUT_DLLEXP GetSpoutLogPath();
// Return the log file as a string
std::string SPOUT_DLLEXP GetSpoutLog(const char* filepath = nullptr);
// Show the log file folder in Windows Explorer
void SPOUT_DLLEXP ShowSpoutLogs();
// Set the current log level
void SPOUT_DLLEXP SetSpoutLogLevel(SpoutLogLevel level);
// General purpose log
void SPOUT_DLLEXP SpoutLog(const char* format, ...);
// Verbose - show log for SPOUT_LOG_VERBOSE or above
void SPOUT_DLLEXP SpoutLogVerbose(const char* format, ...);
// Notice - show log for SPOUT_LOG_NOTICE or above
void SPOUT_DLLEXP SpoutLogNotice(const char* format, ...);
// Warning - show log for SPOUT_LOG_WARNING or above
void SPOUT_DLLEXP SpoutLogWarning(const char* format, ...);
// Error - show log for SPOUT_LOG_ERROR or above
void SPOUT_DLLEXP SpoutLogError(const char* format, ...);
// Fatal - always show log
void SPOUT_DLLEXP SpoutLogFatal(const char* format, ...);
// Logging function.
void SPOUT_DLLEXP _doLog(SpoutLogLevel level, const char* format, va_list args);
// Print to console (printf replacement)
int SPOUT_DLLEXP _conprint(const char* format, ...);
//
// MessageBox dialog
//
// MessageBox dialog with optional timeout.
// The dialog closes itself if a timeout is specified.
int SPOUT_DLLEXP SpoutMessageBox(const char * message, DWORD dwMilliseconds = 0);
// MessageBox with variable arguments
int SPOUT_DLLEXP SpoutMessageBox(const char * caption, const char* format, ...);
// MessageBox with variable arguments and icon, buttons
int SPOUT_DLLEXP SpoutMessageBox(const char* caption, UINT uType, const char* format, ...);
// MessageBox dialog with standard arguments.
// Replaces an existing MessageBox call.
// uType options : standard MessageBox buttons and icons
// MB_USERICON - use together with SpoutMessageBoxIcon
// Hyperlinks can be included in the content using HTML format.
// For example : <a href=\"https://spout.zeal.co/\">Spout home page</a>
// Only double quotes are supported and must be escaped.
int SPOUT_DLLEXP SpoutMessageBox(HWND hwnd, LPCSTR message, LPCSTR caption, UINT uType, DWORD dwMilliseconds = 0);
// MessageBox dialog with standard arguments
// including taskdialog main instruction large text
int SPOUT_DLLEXP SpoutMessageBox(HWND hwnd, LPCSTR message, LPCSTR caption, UINT uType, const char* instruction, DWORD dwMilliseconds = 0);
// MessageBox dialog with an edit control for text input
// Can be used in place of a specific application resource dialog
// o For message content, the control is in the footer area
// o If no message, the control is in the main content area
// o All SpoutMessageBox functions such as user icon and buttons are available
int SPOUT_DLLEXP SpoutMessageBox(HWND hwnd, LPCSTR message, LPCSTR caption, UINT uType, std::string& text);
// MessageBox dialog with a combobox control for item selection
// Can be used in place of a specific application resource dialog
// Properties the same as the edit control
int SPOUT_DLLEXP SpoutMessageBox(HWND hwnd, LPCSTR message, LPCSTR caption, UINT uType, std::vector<std::string> items, int &selected);
// Custom icon for SpoutMessageBox from resources
void SPOUT_DLLEXP SpoutMessageBoxIcon(HICON hIcon);
// Custom icon for SpoutMessageBox from file
bool SPOUT_DLLEXP SpoutMessageBoxIcon(std::string iconfile);
// Custom button for SpoutMessageBox
void SPOUT_DLLEXP SpoutMessageBoxButton(int ID, std::wstring title);
// Activate modeless mode using SpoutPanel.exe
bool SPOUT_DLLEXP SpoutMessageBoxModeless(bool bMode = true);
// Window handle for SpoutMessageBox where not specified
void SPOUT_DLLEXP SpoutMessageBoxWindow(HWND hWnd);
// Position to centre SpoutMessageBox
void SPOUT_DLLEXP SpoutMessageBoxPosition(POINT pt);
// Copy text to the clipboard
bool SPOUT_DLLEXP CopyToClipBoard(HWND hwnd, const char* text);
// Open logs folder
bool SPOUT_DLLEXP OpenSpoutLogs();
//
// Registry utilities
//
// Read subkey DWORD value
bool SPOUT_DLLEXP ReadDwordFromRegistry(HKEY hKey, const char *subkey, const char *valuename, DWORD *pValue);
// Write subkey DWORD value
bool SPOUT_DLLEXP WriteDwordToRegistry(HKEY hKey, const char *subkey, const char *valuename, DWORD dwValue);
// Read subkey character string
bool SPOUT_DLLEXP ReadPathFromRegistry(HKEY hKey, const char *subkey, const char *valuename, char *filepath, DWORD dwSize = MAX_PATH);
// Write subkey character string
bool SPOUT_DLLEXP WritePathToRegistry(HKEY hKey, const char *subkey, const char *valuename, const char *filepath);
// Write subkey binary hex data string
bool SPOUT_DLLEXP WriteBinaryToRegistry(HKEY hKey, const char *subkey, const char *valuename, const unsigned char *hexdata, DWORD nchars);
// Remove subkey value name
bool SPOUT_DLLEXP RemovePathFromRegistry(HKEY hKey, const char *subkey, const char *valuename);
// Delete a subkey and its values.
// It must be a subkey of the key that hKey identifies, but it cannot have subkeys.
// Note that key names are not case sensitive.
bool SPOUT_DLLEXP RemoveSubKey(HKEY hKey, const char *subkey);
// Find subkey
bool SPOUT_DLLEXP FindSubKey(HKEY hKey, const char *subkey);
//
// Timing functions
//
// Monitor refresh rate
double SPOUT_DLLEXP GetRefreshRate();
// Start timing period
void SPOUT_DLLEXP StartTiming();
#ifdef USE_CHRONO
// Stop timing and return milliseconds or microseconds elapsed.
// (microseconds default).
// Code console output can be enabled for quick timing tests.
double SPOUT_DLLEXP EndTiming(bool microseconds = false);
// Microseconds elapsed since epoch
double SPOUT_DLLEXP ElapsedMicroseconds();
#else
double SPOUT_DLLEXP EndTiming();
#endif
void SPOUT_DLLEXP StartCounter();
double SPOUT_DLLEXP GetCounter();
//
// Private functions
//
namespace
{
// Local functions
void _logtofile(bool append = false);
std::string _getLogPath();
std::string _getLogFilePath(const char *filename);
std::string _levelName(SpoutLogLevel level);
// Taskdialog for SpoutMessageBox
int MessageTaskDialog(HWND hWnd, const char* content, const char* caption, DWORD dwButtons, DWORD dwMilliseconds);
// TaskDialogIndirect callback to handle timer, topmost and hyperlinks
HRESULT TDcallbackProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam, LONG_PTR lpRefData);
#ifndef _MSC_VER
// Timeout MessageBox for other compilers
int MessageBoxTimeoutA(IN HWND hWnd,
IN LPCSTR lpText, IN LPCSTR lpCaption, IN UINT uType,
IN WORD wLanguageId, IN DWORD dwMilliseconds);
#endif
// Use ShellExecutEx to open a program
bool ExecuteProcess(const char* path, const char* command = nullptr);
// Open SpoutPanel with command line for modeless SpoutMessageBox
bool OpenSpoutPanel(const char* message);
// Application window
HWND hwndMain = NULL;
// Position for TaskDialog window centre
POINT TDcentre = {};
// For topmost
HWND hwndTop = NULL;
bool bTopMost = false;
// Modeless TaskDialog by way of OpenSpoutPanel
bool bModeless = false; // Default use local TaskDialogIndirect
// For custom icon
HICON hTaskIcon = NULL;
// For custom buttons
std::vector<int>TDbuttonID;
std::vector<std::wstring>TDbuttonTitle;
// Main instruction text
std::wstring wstrInstruction;
// For edit text control
bool bEdit = false;
HWND hEdit = NULL;
std::string stredit;
#define IDC_TASK_EDIT 101
// For combo box control
bool bCombo = false;
HWND hCombo = NULL;
std::vector<std::string> comboitems;
int comboindex = 0;
#define IDC_TASK_COMBO 102
}
}
#endif
@@ -0,0 +1,102 @@
//
// Header: SpoutCommon.h
//
// Enables build of the SDK as a DLL.
//
// Includes header for common utilities namespace "SpoutUtils".
//
// Optional _#define legacyOpenGL_ to enable legacy draw functions
//
/*
Thanks and credit to Malcolm Bechard, the author of this file
https://github.com/mbechard
Copyright (c) 2014-2024, 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.
03.07.23 - Remove _MSC_VER condition from SPOUT_DLLEXP define
(#PR93 Fix MinGW error (beta branch)
07.12.23 - using namespace spoututils moved from SpoutGL.h
*/
#pragma once
#ifndef __SpoutCommon__
#define __SpoutCommon__
//
// To build the Spout library as a dll, define
// SPOUT_BUILD_DLL in the preprocessor defines.
// Properties > C++ > Preprocessor > Preprocessor Definitions
//
#ifndef SPOUT_DLLEXP
#if defined(SPOUT_BUILD_DLL)
#define SPOUT_DLLEXP __declspec(dllexport)
#elif defined(SPOUT_IMPORT_DLL)
#define SPOUT_DLLEXP __declspec(dllimport)
#else
#define SPOUT_DLLEXP
#endif
#endif
// Common utility functions namespace
#include "SpoutUtils.h"
//
// This definition enables legacy OpenGL rendering code
// used for shared texture Draw functions in SpoutGLDXinterop.cpp
// Not required unless compatibility with OpenGL < 3 is necessary
// Disabled by default for OpenGL 4 compliance
// * Note that the same definition is necessary in SpoutGLextensions.h
// so that SpoutGLextensions can be used independently of the Spout library.
//
// #define legacyOpenGL
//
//
// Visual Studio code analysis warnings
//
// C++11 scoped (class) enums are not compatible with early compilers (< VS2012 and others).
// The warning is designated "Prefer" and "C" standard unscoped enums are retained for compatibility.
#if defined(_MSC_VER)
#pragma warning(disable:26812) // unscoped enums
#endif
//
// For ARM build
// __movsd intrinsic not defined
//
#if defined _M_ARM64
#include <memory.h>
inline void __movsd(unsigned long* Destination,
const unsigned long* Source, size_t Count)
{
memcpy(Destination, Source, Count);
}
#endif
#endif
@@ -0,0 +1,223 @@
/*
SpoutCopy.h
Functions to manage pixel buffer copying
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Copyright (c) 2016-2024, 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 __spoutCopy__ // standard way as well
#define __spoutCopy__
#include "SpoutCommon.h"
#include <windows.h>
#include <stdio.h> // for debug printf
#include <gl/gl.h> // For OpenGL definitions
#include <intrin.h> // for cpuid to test for SSE2
#ifdef _M_ARM64
#include <sse2neon.h> // for NEON
#else
#include <emmintrin.h> // for SSE2
#include <tmmintrin.h> // for SSSE3
#endif
#include <cmath> // For compatibility with Clang. PR#81
#include <stdint.h> // for _uint32 etc
class SPOUT_DLLEXP spoutCopy {
public:
spoutCopy();
~spoutCopy();
// Copy image pixels and select fastest method based on image width
void CopyPixels(const unsigned char *src, unsigned char *dst,
unsigned int width, unsigned int height,
GLenum glFormat = GL_RGBA, bool bInvert = false) const;
// Flip a pixel buffer in place
void FlipBuffer(const unsigned char *src, unsigned char *dst,
unsigned int width, unsigned int height,
GLenum glFormat = GL_RGBA) const;
// Correct for image stride
void RemovePadding(const unsigned char* source, unsigned char* dest,
unsigned int width, unsigned int height,
unsigned int source_stride, GLenum glFormat) const;
// Clear alpha of rgba image pixels to the required value
void ClearAlpha(unsigned char* src, unsigned int width,
unsigned int height, unsigned char alpha) const;
// SSE2 version of memcpy
void memcpy_sse2(void* dst, const void* src, size_t size) const;
//
// RGBA <> RGBA
//
// Copy rgba buffers line by line allowing for source pitch using the fastest method
void rgba2rgba(const void* source, void* dest, unsigned int width, unsigned int height,
unsigned int sourcePitch, bool bInvert = false) const;
// Copy rgba buffers line by line allowing for source and destination line pitch
void rgba2rgba(const void* source, void* dest, unsigned int width, unsigned int height,
unsigned int sourcePitch, unsigned int destPitch, bool bInvert) const;
// Copy rgba buffers of differing size
void rgba2rgbaResample(const void* source, void* dest,
unsigned int sourceWidth, unsigned int sourceHeight, unsigned int sourcePitch,
unsigned int destWidth, unsigned int destHeight, bool bInvert = false) const;
//
// RGBA <> BGRA
//
// Copy rgba to bgra using the fastest method
void rgba2bgra(const void* rgba_source, void* bgra_dest, unsigned int width, unsigned int height, bool bInvert = false) const;
// Copy rgba to bgra line by line allowing for source pitch using the fastest method
void rgba2bgra(const void* rgba_source, void* bgra_dest, unsigned int width, unsigned int height,
unsigned int sourcePitch, bool bInvert = false) const;
// Copy rgba to bgra line allowing for source and destination line pitch
void rgba2bgra(const void* source, void* dest, unsigned int width, unsigned int height,
unsigned int sourcePitch, unsigned int destPitch, bool bInvert) const;
// Copy bgra to rgba
void bgra2rgba(const void* bgra_source, void *rgba_dest, unsigned int width, unsigned int height, bool bInvert = false) const;
//
// RGBA <> RGB, RGBA <> BGR
//
// TODO : add RGBA pitch to all functions
// TODO : avoid redundancy
// Copy RGBA to RGB or BGR allowing for source line pitch using the fastest method
void rgba2rgb (const void* rgba_source, void* rgb_dest, unsigned int width, unsigned int height,
unsigned int sourcePitch, // byte line pitch
bool bInvert = false, // Flip vertically
bool bMirror = false, // Mirror horizontally
bool bSwapRB = false) const; // swap red and blue (rgb > bgr) const;
// Copy RGBA to BGR allowing for source line pitch
void rgba2bgr(const void* rgba_source, void* rgb_dest, unsigned int width, unsigned int height,
unsigned int sourcePitch, bool bInvert = false) const;
// Copy RGBA to RGB allowing for source and destination pitch
void rgba2rgbResample(const void* source, void* dest,
unsigned int sourceWidth, unsigned int sourceHeight, unsigned int sourcePitch,
unsigned int destWidth, unsigned int destHeight,
bool bInvert = false, bool bMirror = false, bool bSwapRB = false) const;
// Copy RGBA to BGR allowing for source and destination pitch
void rgba2bgrResample(const void* source, void* dest,
unsigned int sourceWidth, unsigned int sourceHeight, unsigned int sourcePitch,
unsigned int destWidth, unsigned int destHeight, bool bInvert = false) const;
//
// SSE3 function
//
// RGBA to RGB/BGR with source line pitch
//
void rgba_to_rgb_sse3(const void* rgba_source, void* rgb_dest,
unsigned int width, unsigned int height,
unsigned int rgba_pitch, // line byte pitch
bool bInvert = false, // Flip image
bool bSwapRB = false) const; // Swap RG (BGR)
//
// Byte functions
//
// Copy RGB to RGBA
void rgb2rgba (const void* rgb_source, void *rgba_dest, unsigned int width, unsigned int height, bool bInvert = false) const;
// Copy RGB to RGBA allowing for destination pitch
void rgb2rgba(const void *rgb_source, void *rgba_dest,
unsigned int width, unsigned int height,
unsigned int dest_pitch, bool bInvert) const;
// Copy BGR to RGBA
void bgr2rgba (const void* bgr_source, void *rgba_dest, unsigned int width, unsigned int height, bool bInvert = false) const;
// Copy BGR to RGBA allowing for destination pitch
void bgr2rgba(const void *rgb_source, void *rgba_dest,
unsigned int width, unsigned int height,
unsigned int dest_pitch, bool bInvert) const;
//
// RGB > BGRA
//
// Copy RGB to BGRA
void rgb2bgra (const void* rgb_source, void *bgra_dest, unsigned int width, unsigned int height, bool bInvert = false) const;
// Copy RGB to BGRA allowing for destination pitch
void rgb2bgra(const void *rgb_source, void *bgra_dest,
unsigned int width, unsigned int height,
unsigned int dest_pitch, bool bInvert) const;
// Experimental SSE RGB to BGRA
// Single line
void rgb_to_bgrx_sse(unsigned int npixels, const void* rgb_source, void* bgrx_out) const;
// Full height
void rgb_to_bgra_sse3(void* rgb_source, void* rgba_dest, unsigned int width, unsigned int height) const;
// Copy BGR to BGRA
void bgr2bgra (const void* bgr_source, void *bgra_dest, unsigned int width, unsigned int height, bool bInvert = false) const;
// Copy RGBA to BGR
void rgba2bgr (const void* rgba_source, void *bgr_dest, unsigned int width, unsigned int height, bool bInvert = false) const;
// Copy BGRA to RGB
void bgra2rgb (const void* bgra_source, void *rgb_dest, unsigned int width, unsigned int height, bool bInvert = false) const;
// Copy BGRA to BGR
void bgra2bgr (const void* bgra_source, void *bgr_dest, unsigned int width, unsigned int height, bool bInvert = false) const;
// SSE capability
void GetSSE(bool &bSSE2, bool &bSSE3, bool &bSSSE3);
protected :
void CheckSSE();
bool m_bSSE2;
bool m_bSSE3;
bool m_bSSSE3;
void rgba_bgra(const void *rgba_source, void *bgra_dest, unsigned int width, unsigned int height, bool bInvert = false) const;
void rgba_bgra_sse2(const void *rgba_source, void *bgra_dest, unsigned int width, unsigned int height, bool bInvert = false) const;
void rgba_bgra_sse3(const void *rgba_source, void *bgra_dest, unsigned int width, unsigned int height, bool bInvert = false) const;
};
#endif
@@ -0,0 +1,381 @@
/*
SpoutDX.h
Sender and receiver for DirectX applications
Copyright (c) 2014-2024 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 __spoutDX__
#define __spoutDX__
//
// Include file path
//
// 1) If the include files are in the same folder there is no prefix.
// This applies for a build using SpoutDX dll or static library.
//
// 2) If the Spout source is built as a dll or static library,
// or an application is built using the repository folder structure
// the path prefix for include files is "..\..\SpoutGL\"
//
// 3) If the include files are in a different folder, change the prefix as required.
//
#if __has_include("SpoutCommon.h")
#include "SpoutCommon.h" // include files in the same folder
#include "SpoutDirectX.h"
#include "SpoutSenderNames.h"
#include "SpoutFrameCount.h"
#include "SpoutCopy.h"
#include "SpoutUtils.h"
#else
#include "..\..\SpoutGL\SpoutCommon.h" // repository folder structure
#include "..\..\SpoutGL\SpoutDirectX.h"
#include "..\..\SpoutGL\SpoutSenderNames.h"
#include "..\..\SpoutGL\SpoutFrameCount.h"
#include "..\..\SpoutGL\SpoutCopy.h"
#include "..\..\SpoutGL\SpoutUtils.h"
#endif
#include <direct.h> // for _getcwd
#include <TlHelp32.h> // for PROCESSENTRY32
#include <tchar.h> // for _tcsicmp
#include <psapi.h> // for GetModuleFileNameExA
#pragma comment(lib, "Psapi.lib")
class SPOUT_DLLEXP spoutDX {
public:
spoutDX();
~spoutDX();
//
// DIRECTX
//
bool OpenDirectX11(ID3D11Device* pDevice = nullptr);
ID3D11Device* GetDX11Device();
ID3D11DeviceContext* GetDX11Context();
void CloseDirectX11();
bool IsClassDevice();
//
// SENDER
//
// Set the sender name
bool SetSenderName(const char* sendername = nullptr);
// Set the sender texture format
void SetSenderFormat(DXGI_FORMAT format);
// Close sender and free resources
void ReleaseSender();
// Send the back buffer
bool SendBackBuffer();
// Send a texture
bool SendTexture(ID3D11Texture2D* pTexture);
// Send part of a texture
bool SendTexture(ID3D11Texture2D* pTexture,
unsigned int xoffset, unsigned int yoffset,
unsigned int width, unsigned int height);
// Send an image
bool SendImage(const unsigned char * pData, unsigned int width, unsigned int height);
// Sender status
bool IsInitialized();
// Sender name
const char * GetName();
// Get width
unsigned int GetWidth();
// Get height
unsigned int GetHeight();
// Get frame rate
double GetFps();
// Get frame number
long GetFrame();
//
// RECEIVER
//
// Set the sender to connect to
void SetReceiverName(const char * sendername = nullptr);
// Close receiver and free resources
void ReleaseReceiver();
// Receive from a sender
bool ReceiveTexture();
// Receive a texture from a sender
bool ReceiveTexture(ID3D11Texture2D** ppTexture);
// Receive an image
bool ReceiveImage(unsigned char * pixels, unsigned int width, unsigned int height, bool bRGB = false, bool bInvert = false);
// Read pixels from texture
bool ReadTexurePixels(ID3D11Texture2D* ppTexture, unsigned char* pixels);
// Open sender selection dialog
bool SelectSender(HWND hwnd = NULL);
// Sender has changed
bool IsUpdated();
// Connected to a sender
bool IsConnected();
// Received frame is new
bool IsFrameNew();
// Received texture
ID3D11Texture2D* GetSenderTexture();
// Received sender share handle
HANDLE GetSenderHandle();
// Received sender texture format
DXGI_FORMAT GetSenderFormat();
// Received sender name
const char * GetSenderName();
// Received sender width
unsigned int GetSenderWidth();
// Received sender height
unsigned int GetSenderHeight();
// Received sender frame rate
double GetSenderFps();
// Received sender frame number
long GetSenderFrame();
//
// COMMON
//
// Frame rate control
void HoldFps(int fps);
// Disable frame counting for this application
void DisableFrameCount();
// Return frame count status
bool IsFrameCountEnabled();
// Signal sync event
void SetFrameSync(const char* SenderName);
// Wait or test for a sync event
bool WaitFrameSync(const char *SenderName, DWORD dwTimeout = 0);
//
// Sender names
//
// Get number of senders
int GetSenderCount();
// Get sender name for a given index
bool GetSender(int index, char* sendername, int MaxSize = 256);
// Return a list of current senders
std::vector<std::string> GetSenderList();
// Sender index into the set of names
int GetSenderIndex(const char* sendername);
// Get sender details
bool GetSenderInfo(const char* sendername, unsigned int &width, unsigned int &height, HANDLE &dxShareHandle, DWORD &dwFormat);
// Get active sender name
bool GetActiveSender(char* sendername);
// set active sender name
bool SetActiveSender(const char* sendername);
// Get maximum senders allowed
int GetMaxSenders();
// Set maximum senders allowed
void SetMaxSenders(int maxSenders);
//
// Adapter functions
//
// Get the number of graphics adapters in the system
int GetNumAdapters();
// Get the adapter name for a given index
bool GetAdapterName(int index, char *adaptername, int maxchars);
// Get the current adapter description
bool GetAdapterInfo(char *renderdescription, char *displaydescription, int maxchars);
// Get the current adapter index
int GetAdapter();
// Set required graphics adapter for output (no args or -1 to reset)
bool SetAdapter(int index = -1);
// Get adapter pointer for a given adapter (-1 means current)
IDXGIAdapter* GetAdapterPointer(int index = -1);
// Set required graphics adapter for creating a device
void SetAdapterPointer(IDXGIAdapter* pAdapter);
// Get auto device switching status
bool GetAdapterAuto();
// Auto switch receiving device to use the same graphics adapter as the sender
void SetAdapterAuto(bool bAuto = true);
// Get sender adapter index and name for a given sender
int GetSenderAdapter(const char* sendername, char* adaptername = nullptr, int maxchars = 256);
//
// Graphics preference
//
// Windows 10 Vers 1803, build 17134 or later
#ifdef NTDDI_WIN10_RS4
// Get the Windows graphics preference for an application
// -1 - No preference
// 0 - Default
// 1 - Power saving
// 2 - High performance
// If no path is specified, use the current application path
int GetPerformancePreference(const char* path = nullptr);
// Set the Windows graphics preference for an application
// -1 - No preference
// 0 - Default
// 1 - Power saving
// 2 - High performance
// If no path is specified, use the current application path
bool SetPerformancePreference(int preference, const char* path = nullptr);
// Get the graphics adapter name for a Windows preference
bool GetPreferredAdapterName(int preference, char* adaptername, int maxchars);
// Set graphics adapter index for a Windows preference
bool SetPreferredAdapter(int preference);
// Windows graphics preference availability
bool IsPreferenceAvailable();
// Is the path a valid application
bool IsApplicationPath(const char* path);
#endif
//
// Sharing modes (2.006 compatibility)
//
// Get user selected DX9 mode (2.006)
bool GetDX9();
bool GetMemoryShareMode();
//
// Utility
//
void CheckSenderFormat(char * sendername);
bool CreateDX11texture(ID3D11Device* pd3dDevice,
unsigned int width, unsigned int height,
DXGI_FORMAT format, ID3D11Texture2D** ppTexture);
//
// SpoutUtils namespace functions for dll access
//
void OpenSpoutConsole();
void CloseSpoutConsole(bool bWarning = false);
void EnableSpoutLog();
void EnableSpoutLogFile(const char* filename, bool append = false);
void DisableSpoutLogFile();
void DisableSpoutLog();
int SpoutMessageBox(const char* message, DWORD dwMilliseconds = 0);
int SpoutMessageBox(const char* caption, UINT uType, const char* format, ...);
int SpoutMessageBox(HWND hwnd, LPCSTR message, LPCSTR caption, UINT uType, DWORD dwMilliseconds = 0);
int SpoutMessageBox(HWND hwnd, LPCSTR message, LPCSTR caption, UINT uType, const char* instruction, DWORD dwMilliseconds = 0);
int SpoutMessageBox(HWND hwnd, LPCSTR message, LPCSTR caption, UINT uType, std::string& text);
int SpoutMessageBox(HWND hwnd, LPCSTR message, LPCSTR caption, UINT uType, std::vector<std::string> items, int& selected);
//
// Data sharing
//
// Write data to shared memory
bool WriteMemoryBuffer(const char *name, const char* data, int length);
// Read data from shared memory
int ReadMemoryBuffer(const char* name, char* data, int maxlength);
// Create a shared memory buffer
bool CreateMemoryBuffer(const char *name, int length);
// Delete a shared memory buffer
bool DeleteMemoryBuffer();
// Get the number of bytes available for data transfer
int GetMemoryBufferSize(const char *name);
//
// Options used for SpoutCam
//
// Mirror image
void SetMirror(bool bMirror = true);
// RGB <> BGR
void SetSwap(bool bSwap = true);
bool GetMirror();
bool GetSwap();
//
// Public for external access
//
spoutSenderNames sendernames;
spoutFrameCount frame;
spoutDirectX spoutdx;
spoutCopy spoutcopy;
protected :
ID3D11Device* m_pd3dDevice;
ID3D11DeviceContext* m_pImmediateContext;
ID3D11Texture2D* m_pSharedTexture;
ID3D11Texture2D* m_pTexture;
ID3D11Texture2D* m_pStaging[2];
int m_Index;
int m_NextIndex;
HANDLE m_dxShareHandle;
DWORD m_dwFormat;
SharedTextureInfo m_SenderInfo;
char m_SenderNameSetup[256];
char m_SenderName[256];
unsigned int m_Width;
unsigned int m_Height;
bool m_bUpdated;
bool m_bConnected;
bool m_bSpoutInitialized;
bool m_bSpoutPanelOpened;
bool m_bSpoutPanelActive;
bool m_bClassDevice;
bool m_bAdapt;
bool m_bMemoryShare; // Using 2.006 memoryshare methods
bool m_bMirror; // Mirror image
bool m_bSwapRB; // RGB <> BGR
SHELLEXECUTEINFOA m_ShExecInfo; // For ShellExecute
// For WriteMemoryBuffer/ReadMemoryBuffer
SpoutSharedMemory memorybuffer;
bool CheckSender(unsigned int width, unsigned int height, DWORD dwFormat);
ID3D11Texture2D* CheckSenderTexture(char *sendername, HANDLE dxShareHandle);
bool ReceiveSenderData();
void CreateReceiver(const char * sendername, unsigned int width, unsigned int height, DWORD dwFormat);
// Read pixels from a staging texture
bool ReadPixelData(ID3D11Texture2D* pStagingSource, unsigned char* destpixels,
unsigned int width, unsigned int height, bool bRGB, bool bInvert, bool bSwap);
// Create or update staging textures
bool CheckStagingTextures(unsigned int width, unsigned int height, DWORD dwFormat = DXGI_FORMAT_B8G8R8A8_UNORM);
// Create or update class texture
bool CheckTexture(unsigned int width, unsigned int height, DWORD dwFormat);
bool SelectSenderPanel(const char* message = nullptr);
bool CheckSpoutPanel(char *sendername, int maxchars = 256);
};
#endif
@@ -0,0 +1,162 @@
/*
spoutDX12.h
Functions to manage DirectX 12 texture sharing by way of the D3D11On12
Copyright (c) 2020-2024, 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 __spoutDX12__
#define __spoutDX12__
//
// SpoutDX base class
//
// Include files are in the same folder as SpoutDX.h for build using a dll or library.
// SpoutDX.h is one level above for build using the repository folder structure.
//
#if __has_include("SpoutCommon.h")
#include "SpoutDX.h"
#else
#include "..\\SpoutDX.h"
#endif
#include <d3d12.h>
#include <d3d11on12.h>
#include <dxgi1_6.h> // for IDXGIFactory6 in GetHardwareAdapter
#pragma comment (lib, "d3d12.lib")// the Direct3D 11 Library file
#pragma comment (lib, "DXGI.lib") // for CreateDXGIFactory1
// Copied from Microsoft examples
struct DX12_HEAP_PROPERTIES : public D3D12_HEAP_PROPERTIES
{
DX12_HEAP_PROPERTIES() = default;
explicit DX12_HEAP_PROPERTIES(const D3D12_HEAP_PROPERTIES &o) noexcept :
D3D12_HEAP_PROPERTIES(o)
{}
DX12_HEAP_PROPERTIES(
D3D12_CPU_PAGE_PROPERTY cpuPageProperty,
D3D12_MEMORY_POOL memoryPoolPreference,
UINT creationNodeMask = 1,
UINT nodeMask = 1) noexcept
{
Type = D3D12_HEAP_TYPE_CUSTOM;
CPUPageProperty = cpuPageProperty;
MemoryPoolPreference = memoryPoolPreference;
CreationNodeMask = creationNodeMask;
VisibleNodeMask = nodeMask;
}
explicit DX12_HEAP_PROPERTIES(
D3D12_HEAP_TYPE type,
UINT creationNodeMask = 1,
UINT nodeMask = 1) noexcept
{
Type = type;
CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN;
MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN;
CreationNodeMask = creationNodeMask;
VisibleNodeMask = nodeMask;
}
bool IsCPUAccessible() const noexcept
{
return Type == D3D12_HEAP_TYPE_UPLOAD || Type == D3D12_HEAP_TYPE_READBACK || (Type == D3D12_HEAP_TYPE_CUSTOM &&
(CPUPageProperty == D3D12_CPU_PAGE_PROPERTY_WRITE_COMBINE || CPUPageProperty == D3D12_CPU_PAGE_PROPERTY_WRITE_BACK));
}
};
class SPOUT_DLLEXP spoutDX12 : public spoutDX {
public:
spoutDX12();
~spoutDX12();
// Initialize and prepare DirectX 12
bool OpenDirectX12();
bool OpenDirectX12(ID3D12Device* pd3dDevice12, IUnknown** ppCommandQueue = nullptr);
// Release DirectX 12
void CloseDirectX12();
// Send wrapped D3D11on12 D3D11 texture resource
bool SendDX11Resource(ID3D11Resource *pWrappedResource);
// Receive a texture from a sender to a D3D12 texture resource
bool ReceiveDX12Resource(ID3D12Resource** ppDX12Resource);
// Create a D3D11on12 device
ID3D11On12Device* CreateDX11on12device(ID3D12Device* pDevice12, IUnknown** ppCommandQueue = nullptr);
// Wrap a D3D12 resource for use with D3D11
bool WrapDX12Resource(ID3D12Resource* pDX12Resource, ID3D11Resource** ppWrapped11Resource, D3D12_RESOURCE_STATES InitialState);
// Update a wrapped D3D11 texture resource with a D3D11 texture
void UpdateWrappedResource(ID3D11Resource* pWrappedResource, ID3D11Resource *pResource);
// Create a D3D12 texture resource
bool CreateDX12texture(ID3D12Device* pDevice12,
unsigned int width, unsigned int height,
D3D12_RESOURCE_STATES InitialState,
DXGI_FORMAT format,
ID3D12Resource** ppTexture);
//
// Adapter functions
//
// Get IDXGIAdapter1 pointer for a given adapter (-1 means current)
IDXGIAdapter1* GetAdapterPointer1(int index = -1);
// Set required graphics adapter for creating a class D3D12 device
void SetAdapterPointer1(IDXGIAdapter1* pAdapter);
// Device pointers
ID3D12Device* GetD3D12device(); // D3D12 device
ID3D11Device* GetD3D11device(); // D3D11 device
ID3D11DeviceContext* GetD3D11context(); // D3D11 context
ID3D11On12Device* GetD3D11On12device(); // D3D11on12 device
protected:
ID3D12Device* CreateDX12device();
void GetHardwareAdapter(IDXGIFactory1* pFactory, IDXGIAdapter1** ppAdapter, bool requestHighPerformanceAdapter = false);
ID3D12Device* m_pd3dDevice12; // D3D12 device
ID3D11Device* m_pd3dDevice11; // D3D11 device
ID3D11DeviceContext* m_pd3dDeviceContext11; // D3D11 context
ID3D11On12Device* m_pd3d11On12Device; // D3D11on12 device
bool m_bClassDevice; // Using a class or application device
// The wrapped D3D11 resource for D3D12
ID3D11Resource* m_pReceivedResource11;
// Class adapter pointer
IDXGIAdapter1* m_pAdapterDX12;
};
#endif
@@ -0,0 +1,178 @@
/*
spoutDirectX.h
Functions to manage DirectX 11 texture sharing
Copyright (c) 2014 - 2024, 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 __spoutDirectX__
#define __spoutDirectX__
#include "SpoutCommon.h"
#include <d3d9.h> // For format definitions
#include <d3d11.h>
#include <d3d11_1.h>
#include <ntverp.h>
//
// Windows graphics preferences are available for Windows 10 Vers 1803
// build 17134 or later, and use dxgi1_6.
//
// If existing Visual Studio projects use Microsoft DirectX SDK (June 2010),
// this will conflict because the older SDK will be included first.
// The include order in the project file should be changed to include the older SDK last.
// Change :
// <IncludePath>$(DXSDK_DIR)Include$(IncludePath);</IncludePath>
// <LibraryPath>$(DXSDK_DIR)Lib\x86$(LibraryPath);</LibraryPath>
// To :
// <IncludePath>$(IncludePath);$(DXSDK_DIR)Include</IncludePath>
// <LibraryPath>$(LibraryPath);$(DXSDK_DIR)Lib\x86</LibraryPath>
//
#ifdef NTDDI_WIN10_RS4
#include <dxgi1_6.h> // for adapter performance preference
#endif
#pragma comment (lib, "d3d11.lib")// the Direct3D 11 Library file
#pragma comment (lib, "DXGI.lib") // for CreateDXGIFactory1
using namespace spoututils;
class SPOUT_DLLEXP spoutDirectX {
public:
spoutDirectX();
~spoutDirectX();
//
// DirectX11 device
//
// Initialize and prepare DirectX 11
bool OpenDirectX11(ID3D11Device* pDevice = nullptr);
// Release DirectX 11 device and context
void CloseDirectX11();
// Set the DirectX11 device
bool SetDX11Device(ID3D11Device* pDevice);
// Create a DirectX11 device
ID3D11Device* CreateDX11device();
// Return the class device
ID3D11Device* GetDX11Device();
// Return the device immediate context
ID3D11DeviceContext* GetDX11Context();
// Return the device feature level
D3D_FEATURE_LEVEL GetDX11FeatureLevel();
//
// DirectX11 texture
//
// Create a DirectX11 shared texture
bool CreateSharedDX11Texture(ID3D11Device* pDevice, unsigned int width, unsigned int height, DXGI_FORMAT format, ID3D11Texture2D** ppSharedTexture, HANDLE &dxShareHandle, bool bKeyed = false, bool bNThandle = false);
// Create a DirectX texture which is not shared
bool CreateDX11Texture(ID3D11Device* pDevice, unsigned int width, unsigned int height, DXGI_FORMAT format, ID3D11Texture2D** ppTexture);
// Create a DirectX 11 staging texture for read and write
bool CreateDX11StagingTexture(ID3D11Device* pDevice, unsigned int width, unsigned int height, DXGI_FORMAT format, ID3D11Texture2D** pStagingTexture);
// Retrieve the pointer of a DirectX11 shared texture
bool OpenDX11shareHandle(ID3D11Device* pDevice, ID3D11Texture2D** ppSharedTexture, HANDLE dxShareHandle);
//
// DirectX11 utilities
//
// Release a texture resource created with a class device
unsigned long ReleaseDX11Texture(ID3D11Texture2D* pTexture);
// Release a texture resource
unsigned long ReleaseDX11Texture(ID3D11Device* pd3dDevice, ID3D11Texture2D* pTexture);
// Release a device
unsigned long ReleaseDX11Device(ID3D11Device* pd3dDevice);
// Flush immediate context command queue
void Flush();
// Flush immediate context command queue and wait for completion
void FlushWait(ID3D11Device* pd3dDevice, ID3D11DeviceContext* pImmediateContext);
// Wait for completion after flush
void Wait(ID3D11Device* pd3dDevice, ID3D11DeviceContext* pImmediateContext);
//
// Graphics adapter
//
// Get the number of graphics adapters in the system
int GetNumAdapters();
// Get the name of an adapter index
bool GetAdapterName(int index, char *adaptername, int maxchars);
// Get the index of an adapter name
int GetAdapterIndex(const char* adaptername);
// Get the current adapter index
int GetAdapter();
// Set graphics adapter for CreateDX11device from an index
bool SetAdapter(int index = -1);
// Get the description and output display name of the current adapter
bool GetAdapterInfo(char* adaptername, char* output, int maxchars);
// Get the description and output display name for a given adapter
bool GetAdapterInfo(int index, char* adaptername, char* output, int maxchars);
// Get adapter pointer for a given adapter (-1 means current)
IDXGIAdapter* GetAdapterPointer(int index = -1);
// Set required graphics adapter for CreateDX11device
void SetAdapterPointer(IDXGIAdapter* pAdapter);
// Find the index of the NVIDIA adapter in a multi-adapter system
bool FindNVIDIA(int &nAdapter);
//
// Graphics preference
// Windows 10 Vers 1803, build 17134 or later
//
// Get the Windows graphics preference for an application
int GetPerformancePreference(const char* path = nullptr);
// Set the Windows graphics preference for an application
bool SetPerformancePreference(int preference, const char* path = nullptr);
// Get the graphics adapter name for a Windows preference
bool GetPreferredAdapterName(int preference, char* adaptername, int maxchars);
// Set graphics adapter index for a Windows preference
bool SetPreferredAdapter(int preference);
// Windows graphics preference availability
bool IsPreferenceAvailable();
// Is the path a valid application
bool IsApplicationPath(const char* path);
protected:
void DebugLog(ID3D11Device* pd3dDevice, const char* format, ...);
int m_AdapterIndex; // Adapter index
IDXGIAdapter* m_pAdapterDX11; // Adapter pointer
ID3D11Device* m_pd3dDevice; // DX11 device
ID3D11DeviceContext* m_pImmediateContext;
bool m_bClassDevice;
D3D_DRIVER_TYPE m_driverType;
D3D_FEATURE_LEVEL m_featureLevel;
ID3D11Device1* m_pd3dDevice1;
ID3D11DeviceContext1* m_pImmediateContext1;
};
#endif
@@ -0,0 +1,188 @@
/*
SpoutFrameCount.h
Frame counting management
Copyright (c) 2019-2025. 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 __spoutFrameCount__
#define __spoutFrameCount__
#include "SpoutCommon.h"
#include "SpoutSharedMemory.h"
#include <string>
#include <vector>
#include <d3d11.h>
#pragma comment (lib, "d3d11.lib") // for keyed mutex texture access
#pragma comment (lib, "Winmm.lib") // for timer resolution functions
using namespace spoututils;
// USE_CHRONO is defined in SpoutUtils.h
// Note comments about using an early platform toolset
#ifdef USE_CHRONO
#include <chrono> // c++11 timer
#include <thread>
#endif
class SPOUT_DLLEXP spoutFrameCount {
public:
spoutFrameCount();
~spoutFrameCount();
//
// Frame counting
//
// Enable or disable frame counting globally by registry setting
void SetFrameCount(bool bEnable);
// Enable frame counting for this sender
void EnableFrameCount(const char* SenderName);
// Disable frame counting
void DisableFrameCount();
// Pause frame counting
void PauseFrameCount(bool bPaused = true);
// Check status of frame counting
bool IsFrameCountEnabled();
// Is the received frame new
bool IsFrameNew();
// Received frame rate
double GetSenderFps();
// Received frame count
long GetSenderFrame();
// Frame rate control
void HoldFps(int fps);
//
// Used by other classes
//
// Sender increment the semaphore count
void SetNewFrame();
// Receiver read the semaphore count
bool GetNewFrame();
// For class cleanup functions
void CleanupFrameCount();
//
// Mutex locks including DirectX 11 keyed mutex
// DX11 texture keyed mutex functions are private
// and called by the follwoing functions
//
// Test for texture access using a named sender mutex or keyed texture mutex
bool CheckTextureAccess(ID3D11Texture2D* D3D11texture = nullptr);
// Release mutex and allow texture access
bool AllowTextureAccess(ID3D11Texture2D* D3D11texture = nullptr);
//
// Named mutex for shared texture access
//
// Create named mutex for a sender
bool CreateAccessMutex(const char * SenderName);
// Close the texture access mutex.
void CloseAccessMutex();
// Test access using a named mutex
bool CheckAccess();
// Allow access after gaining ownership
void AllowAccess();
// Test for keyed mutex
bool IsKeyedMutex(ID3D11Texture2D* D3D11texture);
//
// Sync events
//
// Set sync event
void SetFrameSync(const char* name);
// Wait or test for a sync event
bool WaitFrameSync(const char *name, DWORD dwTimeout = 0);
// Close sync event
void CloseFrameSync();
// Enable / disable frame sync
void EnableFrameSync(bool bSync = true);
// Check for frame sync option
bool IsFrameSyncEnabled();
protected:
// Texture access named mutex
HANDLE m_hAccessMutex;
// DX11 texture keyed mutex checks
bool CheckKeyedAccess(ID3D11Texture2D* D3D11texture);
bool AllowKeyedAccess(ID3D11Texture2D* D3D11texture);
// Frame count semaphore
bool m_bFrameCount; // Registry setting of frame count
bool m_bCountDisabled; // application disable
bool m_bIsNewFrame; // received frame is new
HANDLE m_hCountSemaphore; // semaphore handle
char m_CountSemaphoreName[256]; // semaphore name
char m_SenderName[256]; // sender currently connected to a receiver
long m_FrameCount; // sender frame count
long m_LastFrameCount; // receiver frame comparator
double m_FrameTime;
double m_FrameTimeTotal;
double m_FrameTimeNumber;
double m_lastFrame;
// Sender frame timing
double m_SystemFps;
double m_SenderFps;
void UpdateSenderFps(long framecount = 0);
// Windows minimum time period
UINT m_PeriodMin;
void StartTimePeriod();
void EndTimePeriod();
// Sync event
bool m_bFrameSync;
HANDLE m_hSyncEvent;
void OpenFrameSync(const char* SenderName);
#ifdef USE_CHRONO
// Avoid C4251 warnings in SpoutLibrary by using pointers
// USE_CHRONO is defined in SpoutUtils.h
// Use of std::unique_ptr to avoid warning C26409 using new/delete
// results in warning C4251 needs to have dll-interface
std::chrono::steady_clock::time_point* m_FpsStartPtr;
std::chrono::steady_clock::time_point* m_FpsEndPtr;
std::chrono::steady_clock::time_point* m_FrameStartPtr;
std::chrono::steady_clock::time_point* m_FrameEndPtr;
#endif
};
#endif
@@ -0,0 +1,219 @@
/*
spoutSenderNames.h
Spout sender management
Thanks and credit to Malcolm Bechard for modifications to this class
https://github.com/mbechard
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Copyright (c) 2014-2025, 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 __spoutSenderNames__ // standard way as well
#define __spoutSenderNames__
#include "SpoutCommon.h"
#include "SpoutSharedMemory.h"
#include <windowsx.h>
#include <wingdi.h>
#include <set>
#include <map>
#include <string>
#include <vector>
#include <unordered_map>
#include <intrin.h> // for __movsd
#include <stdint.h> // for _uint32
#include <assert.h>
#ifdef _M_ARM64
#include <sse2neon.h> // For ARM
#endif
// 100 msec wait for events
#define SPOUT_WAIT_TIMEOUT 100
// MaxSenders define replaced by a global class variable (Maximum for list of Sender names)
#define SpoutMaxSenderNameLen 256
// The texture information structure that is saved to shared memory
// and used for communication between senders and receivers
// uint32_t is used for compatibility between 32bit and 64bit
// The structure is declared here so that this class is can be independent of opengl
//
// Use helper functions for conversion between HANDLE and uint32_t
// https://msdn.microsoft.com/en-us/library/aa384267%28VS.85%29.aspx
// in SpoutGLDXinterop.cpp and SpoutSenderNames
//
struct SharedTextureInfo { // 280 bytes total
uint32_t shareHandle; // 4 bytes : texture handle
uint32_t width; // 4 bytes : texture width
uint32_t height; // 4 bytes : texture height
uint32_t format; // 4 bytes : texture pixel format
uint32_t usage; // 4 bytes : texture usage
uint8_t description[256]; // 256 bytes : description
uint32_t partnerId; // 4 bytes : ID
};
//
// GUIDs for additional sender information maps
// Used for development work
// Example
// {AB5C33D6-3654-43F9-85F6-F54872B0460B}
static const char* GUID_queue = "AB5C33D6-3654-43F9-85F6-F54872B0460B";
class SPOUT_DLLEXP spoutSenderNames {
public:
spoutSenderNames();
~spoutSenderNames();
//
// public functions
//
//
// Sender name registration
//
// Register a sender name in the list of senders
bool RegisterSenderName(char* sendername, bool bNewname = false);
// Remove a name from the list
bool ReleaseSenderName(const char* sendername);
// Find a name in the list
bool FindSenderName(const char* sendername);
//
// Functions to retrieve info about the sender set map and the senders in it
//
// Retrieve the sender name list as a set of names
bool GetSenderNames(std::set<std::string> *sendernames);
// Number of senders in the list
int GetSenderCount();
// Sender item name
bool GetSender(int index, char* sendername, int MaxSize = 256);
// Sender index into the set of names
int GetSenderIndex(const char* sendername);
// Information about a sender from an index into the list
bool GetSenderNameInfo(int index, char* sendername, int sendernameMaxSize, unsigned int &width, unsigned int &height, HANDLE &dxShareHandle);
//
// Maximum number of senders allowed in the list
// Applies for versions 2.005 and after
//
// Get the maximum number from the registry
int GetMaxSenders();
// Set the maximum number of senders in a new sender map
void SetMaxSenders(int maxSenders);
//
// Functions to read and write info to a sender memory map
//
// Get sender information
bool GetSenderInfo (const char* sendername, unsigned int &width, unsigned int &height, HANDLE &dxShareHandle, DWORD &dwFormat);
// Set sender information
bool SetSenderInfo (const char* sendername, unsigned int width, unsigned int height, HANDLE dxShareHandle, DWORD dwFormat);
// Set sender PartnerID field with "CPU" sharing method and GL/DX compatibility
bool SetSenderID(const char *sendername, bool bCPU, bool bGLDX);
// Generic sender map info read (returned in a shared texture information structure)
bool getSharedInfo (const char* sendername, SharedTextureInfo* info);
// Generic sender map info write
bool setSharedInfo (const char* sendername, const SharedTextureInfo* info);
// Test for shared info memory map existence
bool hasSharedInfo(const char* sendername);
//
// Functions to maintain the active sender
//
// Set the active sender - the first retrieved by a receiver
bool SetActiveSender (const char* sendername);
// Get the current active sender
bool GetActiveSender (char *sendername, const int maxlength = SpoutMaxSenderNameLen);
// Get active sender information
bool GetActiveSenderInfo (SharedTextureInfo* info);
// Return details of the current active sender
bool FindActiveSender (char *activename, unsigned int& width, unsigned int& height, HANDLE& hSharehandle, DWORD& dwFormat, const int maxlength = SpoutMaxSenderNameLen);
//
// Functions to Create, Find or Update a sender
// without initializing DirectX or the GL/DX interop functions
//
// Create a sender and register the name in the sender list
bool CreateSender(char* sendername, unsigned int width, unsigned int height, HANDLE hSharehandle, DWORD dwFormat = 0);
// Update an existing sender
bool UpdateSender (const char* sendername, unsigned int width, unsigned int height, HANDLE hSharehandle, DWORD dwFormat = 0);
// Check details of a sender
bool CheckSender (const char* sendername, unsigned int &width, unsigned int &height, HANDLE &hSharehandle, DWORD &dwFormat);
// Find a sender and return details
bool FindSender (char* sendername, unsigned int &width, unsigned int &height, HANDLE &hSharehandle, DWORD &dwFormat);
// Find a sender in the class names set
bool FindSender (const char* sendername);
// Release orphaned senders
void CleanSenders();
protected:
// Sender name set management
bool CreateSenderSet();
bool GetSenderSet (std::set<std::string>& SenderNames);
// Active sender management
bool setActiveSenderName (const char* SenderName);
// bool getActiveSenderName (char SenderName[SpoutMaxSenderNameLen]);
bool getActiveSenderName (char *SenderName, const int maxlength = SpoutMaxSenderNameLen);
// Goes through the full list of sender names and cleans up
// any that shouldn't still be around
void cleanSenderSet();
// Functions to manage shared memory map access
static void readSenderSetFromBuffer(const char* buffer, std::set<std::string>& SenderNames, int maxSenders);
static void writeBufferFromSenderSet(const std::set<std::string>& SenderNames, char *buffer, int maxSenders);
SpoutSharedMemory m_senderNames;
SpoutSharedMemory m_activeSender;
// This should be a unordered_map of sender names ->SharedMemory
// to handle multiple inputs and outputs all going through the
// same spoutSenderNames class
// Make this a pointer to avoid size differences between compilers
// if the .dll is compiled with something different
std::unordered_map<std::string, SpoutSharedMemory*>* m_senders;
int m_MaxSenders; // maximum number of senders via registry
};
#endif
@@ -0,0 +1,97 @@
/*
SpoutSharedMemory.h
Thanks and credit to Malcolm Bechard the author of this class
https://github.com/mbechard
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Copyright (c) 2014-2025, 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 __SpoutSharedMemory_ // standard way as well
#define __SpoutSharedMemory_
#include "SpoutCommon.h"
#include <windowsx.h>
#include <wingdi.h>
using namespace spoututils;
//
// Result of memory segment creation
//
enum SpoutCreateResult {
SPOUT_CREATE_FAILED = 0,
SPOUT_CREATE_SUCCESS,
SPOUT_ALREADY_EXISTS,
SPOUT_ALREADY_CREATED,
};
class SPOUT_DLLEXP SpoutSharedMemory {
public:
SpoutSharedMemory();
~SpoutSharedMemory();
// Create a new memory segment, or attach to an existing one
SpoutCreateResult Create(const char* name, int size);
// Open an existing memory map
bool Open(const char* name);
// Close a map
void Close();
// Lock an open map and return the buffer
char* Lock();
// Unlock a map
void Unlock();
// Name of an existing map
const char* Name();
// Size of an existing map
int Size();
// Print map information for debugging
void Debug();
private:
char* m_pBuffer; // Buffer pointer
HANDLE m_hMap; // Map handle
HANDLE m_hMutex; // Mutex for map access
int m_lockCount; // Map access lock count
char* m_pName; // Map name
int m_size; // Map size
};
#endif
@@ -0,0 +1,415 @@
/*
SpoutUtils.h
General utility functions
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Copyright (c) 2017-2025, 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 __spoutUtils__ // standard way as well
#define __spoutUtils__
// Enable this define to use independently of Spout source files
// See also the stand alone define in SpoutGLextensions
// #define standaloneUtils
#ifdef standaloneUtils
#define SPOUT_DLLEXP
#else
// For use together with Spout source files
#include "SpoutCommon.h" // for legacyOpenGL define and Utils
#include <stdint.h> // for _uint32 etc
#endif
#include <windows.h>
#include <stdio.h> // for console
#include <iostream> // std::cout, std::end
#include <fstream> // for log file
#include <time.h> // for time and date
#include <io.h> // for _access
#include <direct.h> // for _getcwd
#include <vector>
#include <string>
#include <Shellapi.h> // for shellexecute
#include <Commctrl.h> // For TaskDialogIndirect
#include <math.h> // for round
//
// C++11 timer is only available for MS Visual Studio 2015 and above.
//
// Note that _MSC_VER may not correspond correctly if an earlier platform toolset
// is selected for a later compiler e.g. Visual Studio 2010 platform toolset for
// a Visual studio 2017 compiler. "#include <chrono>" will then fail.
// If this is a problem, remove _MSC_VER_ and manually enable/disable the USE_CHRONO define.
//
// PR #84 Fixes for clang
// PR #114 Fixes for MingW
#if (defined(_MSC_VER) && (_MSC_VER >= 1900)) || (defined(__cplusplus) && (__cplusplus >= 201103L))
#define USE_CHRONO
#endif
#ifdef USE_CHRONO
#include <chrono> // c++11 timer
#include <thread>
#endif
#pragma comment(lib, "Shell32.lib") // for shellexecute
#pragma comment(lib, "Advapi32.lib") // for registry functions
#pragma comment(lib, "Version.lib") // for version resources where necessary
#pragma comment(lib, "Comctl32.lib") // For taskdialog
// TaskDialog requires comctl32.dll version 6
#ifdef _MSC_VER
// https://learn.microsoft.com/en-us/windows/win32/controls/cookbook-overview
#pragma comment(linker,"\"/manifestdependency:type='win32' \
name='Microsoft.Windows.Common-Controls' version='6.0.0.0' \
processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")
#endif
// SpoutUtils
namespace spoututils {
enum SpoutLogLevel {
// Disable all messages
SPOUT_LOG_SILENT,
// Show all messages
SPOUT_LOG_VERBOSE,
// Show information messages - default
SPOUT_LOG_NOTICE,
// Show warning, errors and fatal
SPOUT_LOG_WARNING,
// Show errors and fatal
SPOUT_LOG_ERROR,
// Show only fatal errors
SPOUT_LOG_FATAL,
// Ignore log levels
SPOUT_LOG_NONE
};
//
// Information
//
// Get SDK version number string e.g. "2.007.000"
// Optional - return as a single number
// e.g. 2.006 = 2006, 2.007 = 2007, 2.007.009 = 2007009
std::string SPOUT_DLLEXP GetSDKversion(int * number = nullptr);
// Get the user Spout version from the registry
// Optional - return as a single number
std::string SPOUT_DLLEXP GetSpoutVersion(int * number = nullptr);
// Computer type
bool SPOUT_DLLEXP IsLaptop();
// Get the module handle of an executable or dll
HMODULE SPOUT_DLLEXP GetCurrentModule();
// Get executable or dll version
std::string SPOUT_DLLEXP GetExeVersion(const char* path);
// Get executable or dll path
std::string SPOUT_DLLEXP GetExePath(bool bFull = false);
// Get executable or dll name
std::string SPOUT_DLLEXP GetExeName();
// Remove path and return the file name
void SPOUT_DLLEXP RemovePath(std::string& path);
// Remove file name and return the path
void SPOUT_DLLEXP RemoveName(std::string& path);
//
// Console management
//
// Open console window.
// A console window opens without logs.
// Useful for debugging with console output.
void SPOUT_DLLEXP OpenSpoutConsole(const char *title = nullptr);
// Close console window.
// The optional warning displays a MessageBox if user notification is required.
void SPOUT_DLLEXP CloseSpoutConsole(bool bWarning = false);
// Enable logging to the console.
// Logs are displayed in a console window.
// Useful for program development.
void SPOUT_DLLEXP EnableSpoutLog(const char* title = nullptr);
// Enable logging to a file with optional append.
// As well as a console window, you can output logs to a text file.
// Default extension is ".log" unless the full path is used.
// For no file name or path the executable name is used.
// Example : EnableSpoutLogFile("Sender.log");
// The log file is re-created every time the application starts
// unless you specify to append to the existing one.
// Example : EnableSpoutLogFile("Sender.log", true);
// The file is saved in the %AppData% folder unless you specify the full path :
// C:>Users>username>AppData>Roaming>Spout
// You can find and examine the log file after the application has run.
void SPOUT_DLLEXP EnableSpoutLogFile(const char* filename = nullptr, bool bAppend = false);
// Disable logging to file
void SPOUT_DLLEXP DisableSpoutLogFile();
// Remove a log file
void SPOUT_DLLEXP RemoveSpoutLogFile(const char* filename = nullptr);
// Disable logging to console and file
void SPOUT_DLLEXP DisableSpoutLog();
// Disable logging temporarily
void SPOUT_DLLEXP DisableLogs();
// Enable logging again
void SPOUT_DLLEXP EnableLogs();
// Are console logs enabled
bool SPOUT_DLLEXP LogsEnabled();
// Is file logging enabled
bool SPOUT_DLLEXP LogFileEnabled();
// Return the full log file path
std::string SPOUT_DLLEXP GetSpoutLogPath();
// Return the log file as a string
std::string SPOUT_DLLEXP GetSpoutLog(const char* filepath = nullptr);
// Show the log file folder in Windows Explorer
void SPOUT_DLLEXP ShowSpoutLogs();
// Set the current log level
void SPOUT_DLLEXP SetSpoutLogLevel(SpoutLogLevel level);
// General purpose log
void SPOUT_DLLEXP SpoutLog(const char* format, ...);
// Verbose - show log for SPOUT_LOG_VERBOSE or above
void SPOUT_DLLEXP SpoutLogVerbose(const char* format, ...);
// Notice - show log for SPOUT_LOG_NOTICE or above
void SPOUT_DLLEXP SpoutLogNotice(const char* format, ...);
// Warning - show log for SPOUT_LOG_WARNING or above
void SPOUT_DLLEXP SpoutLogWarning(const char* format, ...);
// Error - show log for SPOUT_LOG_ERROR or above
void SPOUT_DLLEXP SpoutLogError(const char* format, ...);
// Fatal - always show log
void SPOUT_DLLEXP SpoutLogFatal(const char* format, ...);
// Logging function.
void SPOUT_DLLEXP _doLog(SpoutLogLevel level, const char* format, va_list args);
// Print to console (printf replacement)
int SPOUT_DLLEXP _conprint(const char* format, ...);
//
// MessageBox dialog
//
// MessageBox dialog with optional timeout.
// The dialog closes itself if a timeout is specified.
int SPOUT_DLLEXP SpoutMessageBox(const char * message, DWORD dwMilliseconds = 0);
// MessageBox with variable arguments
int SPOUT_DLLEXP SpoutMessageBox(const char * caption, const char* format, ...);
// MessageBox with variable arguments and icon, buttons
int SPOUT_DLLEXP SpoutMessageBox(const char* caption, UINT uType, const char* format, ...);
// MessageBox dialog with standard arguments.
// Replaces an existing MessageBox call.
// uType options : standard MessageBox buttons and icons
// MB_USERICON - use together with SpoutMessageBoxIcon
// Hyperlinks can be included in the content using HTML format.
// For example : <a href=\"https://spout.zeal.co/\">Spout home page</a>
// Only double quotes are supported and must be escaped.
int SPOUT_DLLEXP SpoutMessageBox(HWND hwnd, LPCSTR message, LPCSTR caption, UINT uType, DWORD dwMilliseconds = 0);
// MessageBox dialog with standard arguments
// including taskdialog main instruction large text
int SPOUT_DLLEXP SpoutMessageBox(HWND hwnd, LPCSTR message, LPCSTR caption, UINT uType, const char* instruction, DWORD dwMilliseconds = 0);
// MessageBox dialog with an edit control for text input
// Can be used in place of a specific application resource dialog
// o For message content, the control is in the footer area
// o If no message, the control is in the main content area
// o All SpoutMessageBox functions such as user icon and buttons are available
int SPOUT_DLLEXP SpoutMessageBox(HWND hwnd, LPCSTR message, LPCSTR caption, UINT uType, std::string& text);
// MessageBox dialog with a combobox control for item selection
// Can be used in place of a specific application resource dialog
// Properties the same as the edit control
int SPOUT_DLLEXP SpoutMessageBox(HWND hwnd, LPCSTR message, LPCSTR caption, UINT uType, std::vector<std::string> items, int &selected);
// Custom icon for SpoutMessageBox from resources
void SPOUT_DLLEXP SpoutMessageBoxIcon(HICON hIcon);
// Custom icon for SpoutMessageBox from file
bool SPOUT_DLLEXP SpoutMessageBoxIcon(std::string iconfile);
// Custom button for SpoutMessageBox
void SPOUT_DLLEXP SpoutMessageBoxButton(int ID, std::wstring title);
// Activate modeless mode using SpoutPanel.exe
bool SPOUT_DLLEXP SpoutMessageBoxModeless(bool bMode = true);
// Window handle for SpoutMessageBox where not specified
void SPOUT_DLLEXP SpoutMessageBoxWindow(HWND hWnd);
// Position to centre SpoutMessageBox
void SPOUT_DLLEXP SpoutMessageBoxPosition(POINT pt);
// Copy text to the clipboard
bool SPOUT_DLLEXP CopyToClipBoard(HWND hwnd, const char* text);
// Open logs folder
bool SPOUT_DLLEXP OpenSpoutLogs();
//
// Registry utilities
//
// Read subkey DWORD value
bool SPOUT_DLLEXP ReadDwordFromRegistry(HKEY hKey, const char *subkey, const char *valuename, DWORD *pValue);
// Write subkey DWORD value
bool SPOUT_DLLEXP WriteDwordToRegistry(HKEY hKey, const char *subkey, const char *valuename, DWORD dwValue);
// Read subkey character string
bool SPOUT_DLLEXP ReadPathFromRegistry(HKEY hKey, const char *subkey, const char *valuename, char *filepath, DWORD dwSize = MAX_PATH);
// Write subkey character string
bool SPOUT_DLLEXP WritePathToRegistry(HKEY hKey, const char *subkey, const char *valuename, const char *filepath);
// Write subkey binary hex data string
bool SPOUT_DLLEXP WriteBinaryToRegistry(HKEY hKey, const char *subkey, const char *valuename, const unsigned char *hexdata, DWORD nchars);
// Remove subkey value name
bool SPOUT_DLLEXP RemovePathFromRegistry(HKEY hKey, const char *subkey, const char *valuename);
// Delete a subkey and its values.
// It must be a subkey of the key that hKey identifies, but it cannot have subkeys.
// Note that key names are not case sensitive.
bool SPOUT_DLLEXP RemoveSubKey(HKEY hKey, const char *subkey);
// Find subkey
bool SPOUT_DLLEXP FindSubKey(HKEY hKey, const char *subkey);
//
// Timing functions
//
// Monitor refresh rate
double SPOUT_DLLEXP GetRefreshRate();
// Start timing period
void SPOUT_DLLEXP StartTiming();
#ifdef USE_CHRONO
// Stop timing and return milliseconds or microseconds elapsed.
// (microseconds default).
// Code console output can be enabled for quick timing tests.
double SPOUT_DLLEXP EndTiming(bool microseconds = false);
// Microseconds elapsed since epoch
double SPOUT_DLLEXP ElapsedMicroseconds();
#else
double SPOUT_DLLEXP EndTiming();
#endif
void SPOUT_DLLEXP StartCounter();
double SPOUT_DLLEXP GetCounter();
//
// Private functions
//
namespace
{
// Local functions
void _logtofile(bool append = false);
std::string _getLogPath();
std::string _getLogFilePath(const char *filename);
std::string _levelName(SpoutLogLevel level);
// Taskdialog for SpoutMessageBox
int MessageTaskDialog(HWND hWnd, const char* content, const char* caption, DWORD dwButtons, DWORD dwMilliseconds);
// TaskDialogIndirect callback to handle timer, topmost and hyperlinks
HRESULT TDcallbackProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam, LONG_PTR lpRefData);
#ifndef _MSC_VER
// Timeout MessageBox for other compilers
int MessageBoxTimeoutA(IN HWND hWnd,
IN LPCSTR lpText, IN LPCSTR lpCaption, IN UINT uType,
IN WORD wLanguageId, IN DWORD dwMilliseconds);
#endif
// Use ShellExecutEx to open a program
bool ExecuteProcess(const char* path, const char* command = nullptr);
// Open SpoutPanel with command line for modeless SpoutMessageBox
bool OpenSpoutPanel(const char* message);
// Application window
HWND hwndMain = NULL;
// Position for TaskDialog window centre
POINT TDcentre = {};
// For topmost
HWND hwndTop = NULL;
bool bTopMost = false;
// Modeless TaskDialog by way of OpenSpoutPanel
bool bModeless = false; // Default use local TaskDialogIndirect
// For custom icon
HICON hTaskIcon = NULL;
// For custom buttons
std::vector<int>TDbuttonID;
std::vector<std::wstring>TDbuttonTitle;
// Main instruction text
std::wstring wstrInstruction;
// For edit text control
bool bEdit = false;
HWND hEdit = NULL;
std::string stredit;
#define IDC_TASK_EDIT 101
// For combo box control
bool bCombo = false;
HWND hCombo = NULL;
std::vector<std::string> comboitems;
int comboindex = 0;
#define IDC_TASK_COMBO 102
}
}
#endif
@@ -0,0 +1,102 @@
//
// Header: SpoutCommon.h
//
// Enables build of the SDK as a DLL.
//
// Includes header for common utilities namespace "SpoutUtils".
//
// Optional _#define legacyOpenGL_ to enable legacy draw functions
//
/*
Thanks and credit to Malcolm Bechard, the author of this file
https://github.com/mbechard
Copyright (c) 2014-2024, 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.
03.07.23 - Remove _MSC_VER condition from SPOUT_DLLEXP define
(#PR93 Fix MinGW error (beta branch)
07.12.23 - using namespace spoututils moved from SpoutGL.h
*/
#pragma once
#ifndef __SpoutCommon__
#define __SpoutCommon__
//
// To build the Spout library as a dll, define
// SPOUT_BUILD_DLL in the preprocessor defines.
// Properties > C++ > Preprocessor > Preprocessor Definitions
//
#ifndef SPOUT_DLLEXP
#if defined(SPOUT_BUILD_DLL)
#define SPOUT_DLLEXP __declspec(dllexport)
#elif defined(SPOUT_IMPORT_DLL)
#define SPOUT_DLLEXP __declspec(dllimport)
#else
#define SPOUT_DLLEXP
#endif
#endif
// Common utility functions namespace
#include "SpoutUtils.h"
//
// This definition enables legacy OpenGL rendering code
// used for shared texture Draw functions in SpoutGLDXinterop.cpp
// Not required unless compatibility with OpenGL < 3 is necessary
// Disabled by default for OpenGL 4 compliance
// * Note that the same definition is necessary in SpoutGLextensions.h
// so that SpoutGLextensions can be used independently of the Spout library.
//
// #define legacyOpenGL
//
//
// Visual Studio code analysis warnings
//
// C++11 scoped (class) enums are not compatible with early compilers (< VS2012 and others).
// The warning is designated "Prefer" and "C" standard unscoped enums are retained for compatibility.
#if defined(_MSC_VER)
#pragma warning(disable:26812) // unscoped enums
#endif
//
// For ARM build
// __movsd intrinsic not defined
//
#if defined _M_ARM64
#include <memory.h>
inline void __movsd(unsigned long* Destination,
const unsigned long* Source, size_t Count)
{
memcpy(Destination, Source, Count);
}
#endif
#endif
@@ -0,0 +1,231 @@
/*
spoutDX9.h
Functions to manage DirectX 9 texture sharing
Copyright (c) 2020-2024, 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 __spoutDX9__
#define __spoutDX9__
#pragma warning( disable : 4005 ) // Disable macro re-definition warnings
//
// Include file path
//
// 1) If the include files are in the same folder there is no prefix.
// This applies for a build using SpoutDX9 dll or static library.
//
// 2) If the Spout source is built as a dll or static library,
// or an application is built using the repository folder structure
// the path prefix for include files is "..\..\..\SpoutGL\"
//
// 3) If the include files are in a different folder, change the prefix as required.
//
#if __has_include("SpoutCommon.h")
#include "SpoutCommon.h" // include files in the same folder
#include "SpoutSenderNames.h"
#include "SpoutFrameCount.h"
#include "SpoutUtils.h"
#else
#include "..\..\..\SpoutGL\SpoutCommon.h" // repository folder structure
#include "..\..\..\SpoutGL\SpoutSenderNames.h"
#include "..\..\..\SpoutGL\SpoutFrameCount.h"
#include "..\..\..\SpoutGL\SpoutUtils.h"
#endif
#include <direct.h> // for _getcwd
#include <TlHelp32.h> // for PROCESSENTRY32
#include <tchar.h> // for _tcsicmp
#include <d3d9.h>
#pragma comment (lib, "d3d9.lib")
using namespace spoututils;
class SPOUT_DLLEXP spoutDX9 {
public:
spoutDX9();
~spoutDX9();
//
// DIRECTX9
//
// Initialize and prepare DirectX 9
bool OpenDirectX9(HWND hWnd = nullptr);
// Release DirectX9 class object and device
void CloseDirectX9();
// Create a DirectX9 object
IDirect3D9Ex* CreateDX9object();
// Create a DirectX9 device
IDirect3DDevice9Ex* CreateDX9device(IDirect3D9Ex* pD3D, HWND hWnd, unsigned int AdapterIndex = 0);
// Get DirectX9 object
IDirect3D9Ex* GetDX9object();
// Get DirectX9 device
IDirect3DDevice9Ex* GetDX9device();
// Set a DirectX9 device
void SetDX9device(IDirect3DDevice9Ex* pDevice);
//
// SENDER
//
// Set the sender name
bool SetSenderName(const char* sendername = nullptr);
// Send a DirectX9 surface
bool SendDX9surface(IDirect3DSurface9* pSurface, bool bUpdate = true);
// Close sender and free resources
void ReleaseDX9sender();
// Sender status
bool IsInitialized();
// Sender name
const char * GetName();
// Get width
unsigned int GetWidth();
// Get height
unsigned int GetHeight();
// Get frame rate
double GetFps();
// Get frame number
long GetFrame();
//
// RECEIVER
//
// Set the sender to connect to
void SetReceiverName(const char * sendername);
// Receive a DirectX 9 texture from a sender
bool ReceiveDX9Texture(LPDIRECT3DTEXTURE9 &pTexture);
// Close receiver and free resources
void ReleaseReceiver();
// Open sender selection dialog
bool SelectSender(HWND hwnd = nullptr);
// Sender has changed
bool IsUpdated();
// Connected to a sender
bool IsConnected();
// Received frame is new
bool IsFrameNew();
// Received sender share handle
HANDLE GetSenderHandle();
// Received sender texture format (DX11)
DWORD GetSenderFormat();
// Received sender name
const char * GetSenderName();
// Received sender width
unsigned int GetSenderWidth();
// Received sender height
unsigned int GetSenderHeight();
// Received sender frame rate
double GetSenderFps();
// Received sender frame number
long GetSenderFrame();
//
// Sender names
//
// Get number of senders
int GetSenderCount();
// Get sender name for a given index
bool GetSender(int index, char* sendername, int MaxSize = 256);
// Return a list of current senders
std::vector<std::string> GetSenderList();
// Sender index into the set of names
int GetSenderIndex(const char* sendername);
// Get sender details
bool GetSenderInfo(const char* sendername, unsigned int& width, unsigned int& height, HANDLE& dxShareHandle, DWORD& dwFormat);
// Get active sender name
bool GetActiveSender(char* sendername);
// set active sender name
bool SetActiveSender(const char* sendername);
// Get maximum senders allowed
int GetMaxSenders();
// Set maximum senders allowed
void SetMaxSenders(int maxSenders);
//
// COMMON
//
// Hold frame rate
void HoldFps(int fps);
// Create a DirectX9 shared texture
bool CreateSharedDX9Texture(IDirect3DDevice9Ex* pDevice, unsigned int width, unsigned int height, D3DFORMAT format, LPDIRECT3DTEXTURE9 &dxTexture, HANDLE &dxShareHandle);
protected:
spoutFrameCount frame;
spoutSenderNames sendernames;
IDirect3D9Ex* m_pD3D; // DX9 object
IDirect3DDevice9Ex* m_pDevice; // DX9 device
bool m_bSpoutInitialized;
HANDLE m_dxShareHandle;
LPDIRECT3DTEXTURE9 m_pSharedTexture; // Texture to be shared
DWORD m_dwFormat;
SharedTextureInfo m_SenderInfo;
char m_SenderNameSetup[256];
char m_SenderName[256];
unsigned int m_Width;
unsigned int m_Height;
bool m_bUpdated;
bool m_bConnected;
bool m_bNewFrame;
bool m_bSpoutPanelOpened;
bool m_bSpoutPanelActive;
bool m_bClassDevice;
SHELLEXECUTEINFOA m_ShExecInfo;
// Check that a sender is up to date
bool CheckDX9sender(unsigned int width, unsigned int height, DWORD dwFormat);
// Write to a DirectX9 system memory surface
bool WriteDX9memory(IDirect3DDevice9Ex* pDevice, LPDIRECT3DSURFACE9 surface, LPDIRECT3DTEXTURE9 dxTexture);
// Copy from a GPU DX9 surface to the DX9 shared texture
bool WriteDX9surface(IDirect3DDevice9Ex* pDevice, LPDIRECT3DSURFACE9 surface, LPDIRECT3DTEXTURE9 dxTexture);
// Connect to a sender
bool ReceiveSenderData();
// Copy from a sender shared texture to a DX9 texture
bool ReadDX9texture(IDirect3DDevice9Ex* pDevice, LPDIRECT3DTEXTURE9 &dxTexture);
// Create receiver resources
void CreateReceiver(const char * SenderName, unsigned int width, unsigned int height, DWORD dwFormat);
// Pop up SpoutPanel to allow the user to select a sender
bool SelectSenderPanel(const char* message);
// Check whether SpoutPanel opened and return the new sender name
bool CheckSpoutPanel(char *sendername, int maxchars = 256);
};
#endif
@@ -0,0 +1,188 @@
/*
SpoutFrameCount.h
Frame counting management
Copyright (c) 2019-2025. 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 __spoutFrameCount__
#define __spoutFrameCount__
#include "SpoutCommon.h"
#include "SpoutSharedMemory.h"
#include <string>
#include <vector>
#include <d3d11.h>
#pragma comment (lib, "d3d11.lib") // for keyed mutex texture access
#pragma comment (lib, "Winmm.lib") // for timer resolution functions
using namespace spoututils;
// USE_CHRONO is defined in SpoutUtils.h
// Note comments about using an early platform toolset
#ifdef USE_CHRONO
#include <chrono> // c++11 timer
#include <thread>
#endif
class SPOUT_DLLEXP spoutFrameCount {
public:
spoutFrameCount();
~spoutFrameCount();
//
// Frame counting
//
// Enable or disable frame counting globally by registry setting
void SetFrameCount(bool bEnable);
// Enable frame counting for this sender
void EnableFrameCount(const char* SenderName);
// Disable frame counting
void DisableFrameCount();
// Pause frame counting
void PauseFrameCount(bool bPaused = true);
// Check status of frame counting
bool IsFrameCountEnabled();
// Is the received frame new
bool IsFrameNew();
// Received frame rate
double GetSenderFps();
// Received frame count
long GetSenderFrame();
// Frame rate control
void HoldFps(int fps);
//
// Used by other classes
//
// Sender increment the semaphore count
void SetNewFrame();
// Receiver read the semaphore count
bool GetNewFrame();
// For class cleanup functions
void CleanupFrameCount();
//
// Mutex locks including DirectX 11 keyed mutex
// DX11 texture keyed mutex functions are private
// and called by the follwoing functions
//
// Test for texture access using a named sender mutex or keyed texture mutex
bool CheckTextureAccess(ID3D11Texture2D* D3D11texture = nullptr);
// Release mutex and allow texture access
bool AllowTextureAccess(ID3D11Texture2D* D3D11texture = nullptr);
//
// Named mutex for shared texture access
//
// Create named mutex for a sender
bool CreateAccessMutex(const char * SenderName);
// Close the texture access mutex.
void CloseAccessMutex();
// Test access using a named mutex
bool CheckAccess();
// Allow access after gaining ownership
void AllowAccess();
// Test for keyed mutex
bool IsKeyedMutex(ID3D11Texture2D* D3D11texture);
//
// Sync events
//
// Set sync event
void SetFrameSync(const char* name);
// Wait or test for a sync event
bool WaitFrameSync(const char *name, DWORD dwTimeout = 0);
// Close sync event
void CloseFrameSync();
// Enable / disable frame sync
void EnableFrameSync(bool bSync = true);
// Check for frame sync option
bool IsFrameSyncEnabled();
protected:
// Texture access named mutex
HANDLE m_hAccessMutex;
// DX11 texture keyed mutex checks
bool CheckKeyedAccess(ID3D11Texture2D* D3D11texture);
bool AllowKeyedAccess(ID3D11Texture2D* D3D11texture);
// Frame count semaphore
bool m_bFrameCount; // Registry setting of frame count
bool m_bCountDisabled; // application disable
bool m_bIsNewFrame; // received frame is new
HANDLE m_hCountSemaphore; // semaphore handle
char m_CountSemaphoreName[256]; // semaphore name
char m_SenderName[256]; // sender currently connected to a receiver
long m_FrameCount; // sender frame count
long m_LastFrameCount; // receiver frame comparator
double m_FrameTime;
double m_FrameTimeTotal;
double m_FrameTimeNumber;
double m_lastFrame;
// Sender frame timing
double m_SystemFps;
double m_SenderFps;
void UpdateSenderFps(long framecount = 0);
// Windows minimum time period
UINT m_PeriodMin;
void StartTimePeriod();
void EndTimePeriod();
// Sync event
bool m_bFrameSync;
HANDLE m_hSyncEvent;
void OpenFrameSync(const char* SenderName);
#ifdef USE_CHRONO
// Avoid C4251 warnings in SpoutLibrary by using pointers
// USE_CHRONO is defined in SpoutUtils.h
// Use of std::unique_ptr to avoid warning C26409 using new/delete
// results in warning C4251 needs to have dll-interface
std::chrono::steady_clock::time_point* m_FpsStartPtr;
std::chrono::steady_clock::time_point* m_FpsEndPtr;
std::chrono::steady_clock::time_point* m_FrameStartPtr;
std::chrono::steady_clock::time_point* m_FrameEndPtr;
#endif
};
#endif
@@ -0,0 +1,219 @@
/*
spoutSenderNames.h
Spout sender management
Thanks and credit to Malcolm Bechard for modifications to this class
https://github.com/mbechard
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Copyright (c) 2014-2025, 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 __spoutSenderNames__ // standard way as well
#define __spoutSenderNames__
#include "SpoutCommon.h"
#include "SpoutSharedMemory.h"
#include <windowsx.h>
#include <wingdi.h>
#include <set>
#include <map>
#include <string>
#include <vector>
#include <unordered_map>
#include <intrin.h> // for __movsd
#include <stdint.h> // for _uint32
#include <assert.h>
#ifdef _M_ARM64
#include <sse2neon.h> // For ARM
#endif
// 100 msec wait for events
#define SPOUT_WAIT_TIMEOUT 100
// MaxSenders define replaced by a global class variable (Maximum for list of Sender names)
#define SpoutMaxSenderNameLen 256
// The texture information structure that is saved to shared memory
// and used for communication between senders and receivers
// uint32_t is used for compatibility between 32bit and 64bit
// The structure is declared here so that this class is can be independent of opengl
//
// Use helper functions for conversion between HANDLE and uint32_t
// https://msdn.microsoft.com/en-us/library/aa384267%28VS.85%29.aspx
// in SpoutGLDXinterop.cpp and SpoutSenderNames
//
struct SharedTextureInfo { // 280 bytes total
uint32_t shareHandle; // 4 bytes : texture handle
uint32_t width; // 4 bytes : texture width
uint32_t height; // 4 bytes : texture height
uint32_t format; // 4 bytes : texture pixel format
uint32_t usage; // 4 bytes : texture usage
uint8_t description[256]; // 256 bytes : description
uint32_t partnerId; // 4 bytes : ID
};
//
// GUIDs for additional sender information maps
// Used for development work
// Example
// {AB5C33D6-3654-43F9-85F6-F54872B0460B}
static const char* GUID_queue = "AB5C33D6-3654-43F9-85F6-F54872B0460B";
class SPOUT_DLLEXP spoutSenderNames {
public:
spoutSenderNames();
~spoutSenderNames();
//
// public functions
//
//
// Sender name registration
//
// Register a sender name in the list of senders
bool RegisterSenderName(char* sendername, bool bNewname = false);
// Remove a name from the list
bool ReleaseSenderName(const char* sendername);
// Find a name in the list
bool FindSenderName(const char* sendername);
//
// Functions to retrieve info about the sender set map and the senders in it
//
// Retrieve the sender name list as a set of names
bool GetSenderNames(std::set<std::string> *sendernames);
// Number of senders in the list
int GetSenderCount();
// Sender item name
bool GetSender(int index, char* sendername, int MaxSize = 256);
// Sender index into the set of names
int GetSenderIndex(const char* sendername);
// Information about a sender from an index into the list
bool GetSenderNameInfo(int index, char* sendername, int sendernameMaxSize, unsigned int &width, unsigned int &height, HANDLE &dxShareHandle);
//
// Maximum number of senders allowed in the list
// Applies for versions 2.005 and after
//
// Get the maximum number from the registry
int GetMaxSenders();
// Set the maximum number of senders in a new sender map
void SetMaxSenders(int maxSenders);
//
// Functions to read and write info to a sender memory map
//
// Get sender information
bool GetSenderInfo (const char* sendername, unsigned int &width, unsigned int &height, HANDLE &dxShareHandle, DWORD &dwFormat);
// Set sender information
bool SetSenderInfo (const char* sendername, unsigned int width, unsigned int height, HANDLE dxShareHandle, DWORD dwFormat);
// Set sender PartnerID field with "CPU" sharing method and GL/DX compatibility
bool SetSenderID(const char *sendername, bool bCPU, bool bGLDX);
// Generic sender map info read (returned in a shared texture information structure)
bool getSharedInfo (const char* sendername, SharedTextureInfo* info);
// Generic sender map info write
bool setSharedInfo (const char* sendername, const SharedTextureInfo* info);
// Test for shared info memory map existence
bool hasSharedInfo(const char* sendername);
//
// Functions to maintain the active sender
//
// Set the active sender - the first retrieved by a receiver
bool SetActiveSender (const char* sendername);
// Get the current active sender
bool GetActiveSender (char *sendername, const int maxlength = SpoutMaxSenderNameLen);
// Get active sender information
bool GetActiveSenderInfo (SharedTextureInfo* info);
// Return details of the current active sender
bool FindActiveSender (char *activename, unsigned int& width, unsigned int& height, HANDLE& hSharehandle, DWORD& dwFormat, const int maxlength = SpoutMaxSenderNameLen);
//
// Functions to Create, Find or Update a sender
// without initializing DirectX or the GL/DX interop functions
//
// Create a sender and register the name in the sender list
bool CreateSender(char* sendername, unsigned int width, unsigned int height, HANDLE hSharehandle, DWORD dwFormat = 0);
// Update an existing sender
bool UpdateSender (const char* sendername, unsigned int width, unsigned int height, HANDLE hSharehandle, DWORD dwFormat = 0);
// Check details of a sender
bool CheckSender (const char* sendername, unsigned int &width, unsigned int &height, HANDLE &hSharehandle, DWORD &dwFormat);
// Find a sender and return details
bool FindSender (char* sendername, unsigned int &width, unsigned int &height, HANDLE &hSharehandle, DWORD &dwFormat);
// Find a sender in the class names set
bool FindSender (const char* sendername);
// Release orphaned senders
void CleanSenders();
protected:
// Sender name set management
bool CreateSenderSet();
bool GetSenderSet (std::set<std::string>& SenderNames);
// Active sender management
bool setActiveSenderName (const char* SenderName);
// bool getActiveSenderName (char SenderName[SpoutMaxSenderNameLen]);
bool getActiveSenderName (char *SenderName, const int maxlength = SpoutMaxSenderNameLen);
// Goes through the full list of sender names and cleans up
// any that shouldn't still be around
void cleanSenderSet();
// Functions to manage shared memory map access
static void readSenderSetFromBuffer(const char* buffer, std::set<std::string>& SenderNames, int maxSenders);
static void writeBufferFromSenderSet(const std::set<std::string>& SenderNames, char *buffer, int maxSenders);
SpoutSharedMemory m_senderNames;
SpoutSharedMemory m_activeSender;
// This should be a unordered_map of sender names ->SharedMemory
// to handle multiple inputs and outputs all going through the
// same spoutSenderNames class
// Make this a pointer to avoid size differences between compilers
// if the .dll is compiled with something different
std::unordered_map<std::string, SpoutSharedMemory*>* m_senders;
int m_MaxSenders; // maximum number of senders via registry
};
#endif
@@ -0,0 +1,97 @@
/*
SpoutSharedMemory.h
Thanks and credit to Malcolm Bechard the author of this class
https://github.com/mbechard
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Copyright (c) 2014-2025, 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 __SpoutSharedMemory_ // standard way as well
#define __SpoutSharedMemory_
#include "SpoutCommon.h"
#include <windowsx.h>
#include <wingdi.h>
using namespace spoututils;
//
// Result of memory segment creation
//
enum SpoutCreateResult {
SPOUT_CREATE_FAILED = 0,
SPOUT_CREATE_SUCCESS,
SPOUT_ALREADY_EXISTS,
SPOUT_ALREADY_CREATED,
};
class SPOUT_DLLEXP SpoutSharedMemory {
public:
SpoutSharedMemory();
~SpoutSharedMemory();
// Create a new memory segment, or attach to an existing one
SpoutCreateResult Create(const char* name, int size);
// Open an existing memory map
bool Open(const char* name);
// Close a map
void Close();
// Lock an open map and return the buffer
char* Lock();
// Unlock a map
void Unlock();
// Name of an existing map
const char* Name();
// Size of an existing map
int Size();
// Print map information for debugging
void Debug();
private:
char* m_pBuffer; // Buffer pointer
HANDLE m_hMap; // Map handle
HANDLE m_hMutex; // Mutex for map access
int m_lockCount; // Map access lock count
char* m_pName; // Map name
int m_size; // Map size
};
#endif
@@ -0,0 +1,415 @@
/*
SpoutUtils.h
General utility functions
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Copyright (c) 2017-2025, 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 __spoutUtils__ // standard way as well
#define __spoutUtils__
// Enable this define to use independently of Spout source files
// See also the stand alone define in SpoutGLextensions
// #define standaloneUtils
#ifdef standaloneUtils
#define SPOUT_DLLEXP
#else
// For use together with Spout source files
#include "SpoutCommon.h" // for legacyOpenGL define and Utils
#include <stdint.h> // for _uint32 etc
#endif
#include <windows.h>
#include <stdio.h> // for console
#include <iostream> // std::cout, std::end
#include <fstream> // for log file
#include <time.h> // for time and date
#include <io.h> // for _access
#include <direct.h> // for _getcwd
#include <vector>
#include <string>
#include <Shellapi.h> // for shellexecute
#include <Commctrl.h> // For TaskDialogIndirect
#include <math.h> // for round
//
// C++11 timer is only available for MS Visual Studio 2015 and above.
//
// Note that _MSC_VER may not correspond correctly if an earlier platform toolset
// is selected for a later compiler e.g. Visual Studio 2010 platform toolset for
// a Visual studio 2017 compiler. "#include <chrono>" will then fail.
// If this is a problem, remove _MSC_VER_ and manually enable/disable the USE_CHRONO define.
//
// PR #84 Fixes for clang
// PR #114 Fixes for MingW
#if (defined(_MSC_VER) && (_MSC_VER >= 1900)) || (defined(__cplusplus) && (__cplusplus >= 201103L))
#define USE_CHRONO
#endif
#ifdef USE_CHRONO
#include <chrono> // c++11 timer
#include <thread>
#endif
#pragma comment(lib, "Shell32.lib") // for shellexecute
#pragma comment(lib, "Advapi32.lib") // for registry functions
#pragma comment(lib, "Version.lib") // for version resources where necessary
#pragma comment(lib, "Comctl32.lib") // For taskdialog
// TaskDialog requires comctl32.dll version 6
#ifdef _MSC_VER
// https://learn.microsoft.com/en-us/windows/win32/controls/cookbook-overview
#pragma comment(linker,"\"/manifestdependency:type='win32' \
name='Microsoft.Windows.Common-Controls' version='6.0.0.0' \
processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")
#endif
// SpoutUtils
namespace spoututils {
enum SpoutLogLevel {
// Disable all messages
SPOUT_LOG_SILENT,
// Show all messages
SPOUT_LOG_VERBOSE,
// Show information messages - default
SPOUT_LOG_NOTICE,
// Show warning, errors and fatal
SPOUT_LOG_WARNING,
// Show errors and fatal
SPOUT_LOG_ERROR,
// Show only fatal errors
SPOUT_LOG_FATAL,
// Ignore log levels
SPOUT_LOG_NONE
};
//
// Information
//
// Get SDK version number string e.g. "2.007.000"
// Optional - return as a single number
// e.g. 2.006 = 2006, 2.007 = 2007, 2.007.009 = 2007009
std::string SPOUT_DLLEXP GetSDKversion(int * number = nullptr);
// Get the user Spout version from the registry
// Optional - return as a single number
std::string SPOUT_DLLEXP GetSpoutVersion(int * number = nullptr);
// Computer type
bool SPOUT_DLLEXP IsLaptop();
// Get the module handle of an executable or dll
HMODULE SPOUT_DLLEXP GetCurrentModule();
// Get executable or dll version
std::string SPOUT_DLLEXP GetExeVersion(const char* path);
// Get executable or dll path
std::string SPOUT_DLLEXP GetExePath(bool bFull = false);
// Get executable or dll name
std::string SPOUT_DLLEXP GetExeName();
// Remove path and return the file name
void SPOUT_DLLEXP RemovePath(std::string& path);
// Remove file name and return the path
void SPOUT_DLLEXP RemoveName(std::string& path);
//
// Console management
//
// Open console window.
// A console window opens without logs.
// Useful for debugging with console output.
void SPOUT_DLLEXP OpenSpoutConsole(const char *title = nullptr);
// Close console window.
// The optional warning displays a MessageBox if user notification is required.
void SPOUT_DLLEXP CloseSpoutConsole(bool bWarning = false);
// Enable logging to the console.
// Logs are displayed in a console window.
// Useful for program development.
void SPOUT_DLLEXP EnableSpoutLog(const char* title = nullptr);
// Enable logging to a file with optional append.
// As well as a console window, you can output logs to a text file.
// Default extension is ".log" unless the full path is used.
// For no file name or path the executable name is used.
// Example : EnableSpoutLogFile("Sender.log");
// The log file is re-created every time the application starts
// unless you specify to append to the existing one.
// Example : EnableSpoutLogFile("Sender.log", true);
// The file is saved in the %AppData% folder unless you specify the full path :
// C:>Users>username>AppData>Roaming>Spout
// You can find and examine the log file after the application has run.
void SPOUT_DLLEXP EnableSpoutLogFile(const char* filename = nullptr, bool bAppend = false);
// Disable logging to file
void SPOUT_DLLEXP DisableSpoutLogFile();
// Remove a log file
void SPOUT_DLLEXP RemoveSpoutLogFile(const char* filename = nullptr);
// Disable logging to console and file
void SPOUT_DLLEXP DisableSpoutLog();
// Disable logging temporarily
void SPOUT_DLLEXP DisableLogs();
// Enable logging again
void SPOUT_DLLEXP EnableLogs();
// Are console logs enabled
bool SPOUT_DLLEXP LogsEnabled();
// Is file logging enabled
bool SPOUT_DLLEXP LogFileEnabled();
// Return the full log file path
std::string SPOUT_DLLEXP GetSpoutLogPath();
// Return the log file as a string
std::string SPOUT_DLLEXP GetSpoutLog(const char* filepath = nullptr);
// Show the log file folder in Windows Explorer
void SPOUT_DLLEXP ShowSpoutLogs();
// Set the current log level
void SPOUT_DLLEXP SetSpoutLogLevel(SpoutLogLevel level);
// General purpose log
void SPOUT_DLLEXP SpoutLog(const char* format, ...);
// Verbose - show log for SPOUT_LOG_VERBOSE or above
void SPOUT_DLLEXP SpoutLogVerbose(const char* format, ...);
// Notice - show log for SPOUT_LOG_NOTICE or above
void SPOUT_DLLEXP SpoutLogNotice(const char* format, ...);
// Warning - show log for SPOUT_LOG_WARNING or above
void SPOUT_DLLEXP SpoutLogWarning(const char* format, ...);
// Error - show log for SPOUT_LOG_ERROR or above
void SPOUT_DLLEXP SpoutLogError(const char* format, ...);
// Fatal - always show log
void SPOUT_DLLEXP SpoutLogFatal(const char* format, ...);
// Logging function.
void SPOUT_DLLEXP _doLog(SpoutLogLevel level, const char* format, va_list args);
// Print to console (printf replacement)
int SPOUT_DLLEXP _conprint(const char* format, ...);
//
// MessageBox dialog
//
// MessageBox dialog with optional timeout.
// The dialog closes itself if a timeout is specified.
int SPOUT_DLLEXP SpoutMessageBox(const char * message, DWORD dwMilliseconds = 0);
// MessageBox with variable arguments
int SPOUT_DLLEXP SpoutMessageBox(const char * caption, const char* format, ...);
// MessageBox with variable arguments and icon, buttons
int SPOUT_DLLEXP SpoutMessageBox(const char* caption, UINT uType, const char* format, ...);
// MessageBox dialog with standard arguments.
// Replaces an existing MessageBox call.
// uType options : standard MessageBox buttons and icons
// MB_USERICON - use together with SpoutMessageBoxIcon
// Hyperlinks can be included in the content using HTML format.
// For example : <a href=\"https://spout.zeal.co/\">Spout home page</a>
// Only double quotes are supported and must be escaped.
int SPOUT_DLLEXP SpoutMessageBox(HWND hwnd, LPCSTR message, LPCSTR caption, UINT uType, DWORD dwMilliseconds = 0);
// MessageBox dialog with standard arguments
// including taskdialog main instruction large text
int SPOUT_DLLEXP SpoutMessageBox(HWND hwnd, LPCSTR message, LPCSTR caption, UINT uType, const char* instruction, DWORD dwMilliseconds = 0);
// MessageBox dialog with an edit control for text input
// Can be used in place of a specific application resource dialog
// o For message content, the control is in the footer area
// o If no message, the control is in the main content area
// o All SpoutMessageBox functions such as user icon and buttons are available
int SPOUT_DLLEXP SpoutMessageBox(HWND hwnd, LPCSTR message, LPCSTR caption, UINT uType, std::string& text);
// MessageBox dialog with a combobox control for item selection
// Can be used in place of a specific application resource dialog
// Properties the same as the edit control
int SPOUT_DLLEXP SpoutMessageBox(HWND hwnd, LPCSTR message, LPCSTR caption, UINT uType, std::vector<std::string> items, int &selected);
// Custom icon for SpoutMessageBox from resources
void SPOUT_DLLEXP SpoutMessageBoxIcon(HICON hIcon);
// Custom icon for SpoutMessageBox from file
bool SPOUT_DLLEXP SpoutMessageBoxIcon(std::string iconfile);
// Custom button for SpoutMessageBox
void SPOUT_DLLEXP SpoutMessageBoxButton(int ID, std::wstring title);
// Activate modeless mode using SpoutPanel.exe
bool SPOUT_DLLEXP SpoutMessageBoxModeless(bool bMode = true);
// Window handle for SpoutMessageBox where not specified
void SPOUT_DLLEXP SpoutMessageBoxWindow(HWND hWnd);
// Position to centre SpoutMessageBox
void SPOUT_DLLEXP SpoutMessageBoxPosition(POINT pt);
// Copy text to the clipboard
bool SPOUT_DLLEXP CopyToClipBoard(HWND hwnd, const char* text);
// Open logs folder
bool SPOUT_DLLEXP OpenSpoutLogs();
//
// Registry utilities
//
// Read subkey DWORD value
bool SPOUT_DLLEXP ReadDwordFromRegistry(HKEY hKey, const char *subkey, const char *valuename, DWORD *pValue);
// Write subkey DWORD value
bool SPOUT_DLLEXP WriteDwordToRegistry(HKEY hKey, const char *subkey, const char *valuename, DWORD dwValue);
// Read subkey character string
bool SPOUT_DLLEXP ReadPathFromRegistry(HKEY hKey, const char *subkey, const char *valuename, char *filepath, DWORD dwSize = MAX_PATH);
// Write subkey character string
bool SPOUT_DLLEXP WritePathToRegistry(HKEY hKey, const char *subkey, const char *valuename, const char *filepath);
// Write subkey binary hex data string
bool SPOUT_DLLEXP WriteBinaryToRegistry(HKEY hKey, const char *subkey, const char *valuename, const unsigned char *hexdata, DWORD nchars);
// Remove subkey value name
bool SPOUT_DLLEXP RemovePathFromRegistry(HKEY hKey, const char *subkey, const char *valuename);
// Delete a subkey and its values.
// It must be a subkey of the key that hKey identifies, but it cannot have subkeys.
// Note that key names are not case sensitive.
bool SPOUT_DLLEXP RemoveSubKey(HKEY hKey, const char *subkey);
// Find subkey
bool SPOUT_DLLEXP FindSubKey(HKEY hKey, const char *subkey);
//
// Timing functions
//
// Monitor refresh rate
double SPOUT_DLLEXP GetRefreshRate();
// Start timing period
void SPOUT_DLLEXP StartTiming();
#ifdef USE_CHRONO
// Stop timing and return milliseconds or microseconds elapsed.
// (microseconds default).
// Code console output can be enabled for quick timing tests.
double SPOUT_DLLEXP EndTiming(bool microseconds = false);
// Microseconds elapsed since epoch
double SPOUT_DLLEXP ElapsedMicroseconds();
#else
double SPOUT_DLLEXP EndTiming();
#endif
void SPOUT_DLLEXP StartCounter();
double SPOUT_DLLEXP GetCounter();
//
// Private functions
//
namespace
{
// Local functions
void _logtofile(bool append = false);
std::string _getLogPath();
std::string _getLogFilePath(const char *filename);
std::string _levelName(SpoutLogLevel level);
// Taskdialog for SpoutMessageBox
int MessageTaskDialog(HWND hWnd, const char* content, const char* caption, DWORD dwButtons, DWORD dwMilliseconds);
// TaskDialogIndirect callback to handle timer, topmost and hyperlinks
HRESULT TDcallbackProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam, LONG_PTR lpRefData);
#ifndef _MSC_VER
// Timeout MessageBox for other compilers
int MessageBoxTimeoutA(IN HWND hWnd,
IN LPCSTR lpText, IN LPCSTR lpCaption, IN UINT uType,
IN WORD wLanguageId, IN DWORD dwMilliseconds);
#endif
// Use ShellExecutEx to open a program
bool ExecuteProcess(const char* path, const char* command = nullptr);
// Open SpoutPanel with command line for modeless SpoutMessageBox
bool OpenSpoutPanel(const char* message);
// Application window
HWND hwndMain = NULL;
// Position for TaskDialog window centre
POINT TDcentre = {};
// For topmost
HWND hwndTop = NULL;
bool bTopMost = false;
// Modeless TaskDialog by way of OpenSpoutPanel
bool bModeless = false; // Default use local TaskDialogIndirect
// For custom icon
HICON hTaskIcon = NULL;
// For custom buttons
std::vector<int>TDbuttonID;
std::vector<std::wstring>TDbuttonTitle;
// Main instruction text
std::wstring wstrInstruction;
// For edit text control
bool bEdit = false;
HWND hEdit = NULL;
std::string stredit;
#define IDC_TASK_EDIT 101
// For combo box control
bool bCombo = false;
HWND hCombo = NULL;
std::vector<std::string> comboitems;
int comboindex = 0;
#define IDC_TASK_COMBO 102
}
}
#endif
@@ -0,0 +1,289 @@
/*
Spout.h
Documentation - https://spoutgl-site.netlify.app/
Copyright (c) 2014-2025, 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 "SpoutGL.h"
class SPOUT_DLLEXP Spout : public spoutGL {
public:
Spout();
~Spout();
//
// ===================== SENDER =========================
//
// Set name for sender creation
// If no name is specified, the executable name is used
void SetSenderName(const char* sendername = nullptr);
// Set sender DX11 shared texture format
void SetSenderFormat(DWORD dwFormat);
// Release sender and resources
void ReleaseSender();
// Send OpenGL framebuffer
// The fbo must be bound for read.
// The sending texture can be larger than the size that the sender is set up for
// For example, if the application is using only a portion of the allocated texture space,
// such as for Freeframe plugins. (The 2.006 equivalent is DrawToSharedTexture)
// To send the default OpenGL framebuffer, specify FboID = 0.
// If width and height are also 0, the function determines the viewport size.
bool SendFbo(GLuint FboID, unsigned int width, unsigned int height, bool bInvert = true);
// Send OpenGL texture
bool SendTexture(GLuint TextureID, GLuint TextureTarget, unsigned int width, unsigned int height, bool bInvert = true, GLuint HostFBO = 0);
// Send image pixels
bool SendImage(const unsigned char* pixels, unsigned int width, unsigned int height, GLenum glFormat = GL_RGBA, bool bInvert = false, GLuint HostFBO = 0);
// Sender status
bool IsInitialized();
// Sender name
const char * GetName();
// Sender width
unsigned int GetWidth();
// Sender height
unsigned int GetHeight();
// Sender frame rate
double GetFps();
// Sender frame number
long GetFrame();
// Sender share handle
HANDLE GetHandle();
// Sender sharing method
bool GetCPU();
// Sender GL/DX hardware compatibility
bool GetGLDX();
//
// ====================== RECEIVER ===========================
//
// Specify sender for connection
// If a name is specified, the receiver will not connect to any other unless the user selects one
// If that sender closes, the receiver will wait for the nominated sender to open
// If no name is specified, the receiver will connect to the active sender
void SetReceiverName(const char * sendername = nullptr);
// Get sender for connection
bool GetReceiverName(char* sendername, int maxchars = 256);
// Close receiver and release resources ready to connect to another sender
void ReleaseReceiver();
// Receive shared texture
// Connect to a sender and retrieve texture details ready for access
// (see BindSharedTexture and UnBindSharedTexture)
bool ReceiveTexture();
// Receive OpenGL texture
// Connect to a sender and inform the application to update
// the receiving texture if it has changed dimensions
// For no change, copy the sender shared texture to the application texture
// The texture must be RGBA of dimension (width * height)
bool ReceiveTexture(GLuint TextureID, GLuint TextureTarget, bool bInvert = false, GLuint HostFbo = 0);
// Receive image pixels
// Connect to a sender and inform the application to update
// the receiving buffer if it has changed dimensions
// For no change, copy the sender shared texture to the pixel buffer
// The receiving image can be RGBA, BGRA, RGB or BGR formats of dimension (width * height)
bool ReceiveImage(unsigned char* pixels, GLenum glFormat = GL_RGBA, bool bInvert = false, GLuint HostFbo = 0);
// Query whether the sender has changed
// Checked at every cycle before receiving data
bool IsUpdated();
// Query sender connection
// If the sender closes, receiving functions return false
bool IsConnected();
// Query received frame status
// The receiving texture or pixel buffer is only refreshed if the sender has produced a new frame
// This can be queried to process texture data only for new frames
bool IsFrameNew();
// Received sender name
const char * GetSenderName();
// Received sender width
unsigned int GetSenderWidth();
// Received sender height
unsigned int GetSenderHeight();
// Received sender DX11 texture format
DWORD GetSenderFormat();
// Received sender frame rate
double GetSenderFps();
// Received sender frame number
long GetSenderFrame();
// Received sender share handle
HANDLE GetSenderHandle();
// Received sender texture
ID3D11Texture2D* GetSenderTexture();
// Received sender sharing method
bool GetSenderCPU();
// Received sender GL/DX hardware compatibility
bool GetSenderGLDX();
// Return a list of current senders
std::vector<std::string> GetSenderList();
// Sender index into the set of names
int GetSenderIndex(const char* sendername);
// Open sender selection dialog
bool SelectSender(HWND hwnd = NULL);
//
// Frame count
//
// Enable or disable frame counting globally
void SetFrameCount(bool bEnable);
// Disable frame counting specifically for this application
void DisableFrameCount();
// Return frame count status
bool IsFrameCountEnabled();
// Frame rate control
void HoldFps(int fps);
// Signal sync event
void SetFrameSync(const char* SenderName);
// Wait or test for a sync event
bool WaitFrameSync(const char *SenderName, DWORD dwTimeout = 0);
// Enable / disable frame sync
void EnableFrameSync(bool bSync = true);
// Check for frame sync option
bool IsFrameSyncEnabled();
//
// Sender names
//
// Number of senders
int GetSenderCount();
// Sender item name
bool GetSender(int index, char* sendername, int MaxSize = 256);
// Sender information
bool GetSenderInfo(const char* sendername, unsigned int &width, unsigned int &height, HANDLE &dxShareHandle, DWORD &dwFormat);
// Current active sender
bool GetActiveSender(char* sendername);
// Set sender as active
bool SetActiveSender(const char* sendername);
//
// Adapter functions
//
// The number of graphics adapters in the system
int GetNumAdapters();
// Get adapter item name
bool GetAdapterName(int index, char *adaptername, int maxchars = 256);
// Return current adapter name
char * AdapterName();
// Get current adapter index
int GetAdapter();
// Get sender adapter index and name for a given sender
int GetSenderAdapter(const char* sendername, char* adaptername = nullptr, int maxchars = 256);
// Get the description and output display name of the current adapter
bool GetAdapterInfo(char* description, char* output, int maxchars);
// Get the description and output display name for a given adapter
bool GetAdapterInfo(int index, char* description, char* output, int maxchars);
//
// Graphics preference
// Windows 10 Vers 1803, build 17134 or later
//
// Get the Windows graphics preference for an application
int GetPerformancePreference(const char* path = nullptr);
// Set the Windows graphics preference for an application
bool SetPerformancePreference(int preference, const char* path = nullptr);
// Get the graphics adapter name for a Windows preference
bool GetPreferredAdapterName(int preference, char* adaptername, int maxchars);
// Set graphics adapter index for a Windows preference
bool SetPreferredAdapter(int preference);
// Availability of Windows graphics preference
bool IsPreferenceAvailable();
// Is the path a valid application
bool IsApplicationPath(const char* path);
//
// 2.006 compatibility
//
// Find the index of the NVIDIA adapter in a multi-adapter system
bool FindNVIDIA(int &nAdapter);
// Graphics adapter details
bool GetAdapterInfo(char* renderadapter,
char* renderdescription, char* renderversion,
char* displaydescription, char* displayversion,
int maxsize);
// Create a sender
bool CreateSender(const char *Sendername, unsigned int width = 0, unsigned int height = 0, DWORD dwFormat = 0);
// Update a sender
bool UpdateSender(const char* Sendername, unsigned int width, unsigned int height);
//
// 2.006 compatibility
//
// Create receiver connection
bool CreateReceiver(char* Sendername, unsigned int &width, unsigned int &height);
// Check receiver connection
bool CheckReceiver(char* Sendername, unsigned int &width, unsigned int &height, bool &bConnected);
// Receive OpenGL texture
bool ReceiveTexture(char* Sendername, unsigned int &width, unsigned int &height, GLuint TextureID = 0, GLuint TextureTarget = 0, bool bInvert = false, GLuint HostFBO = 0);
// Receive image pixels
bool ReceiveImage(char* Sendername, unsigned int &width, unsigned int &height, unsigned char* pixels, GLenum glFormat = GL_RGBA, bool bInvert = false, GLuint HostFBO = 0);
// Open dialog for the user to select a sender
// Optional message argument
bool SelectSenderPanel(const char* message = nullptr);
// Receiver detect sender selection
bool CheckSpoutPanel(char *sendername, int maxchars = 256);
// Legacy OpenGL Draw functions
// See _SpoutCommon.h_ #define legacyOpenGL
#ifdef legacyOpenGL
// Render the shared texture
bool DrawSharedTexture(float max_x = 1.0, float max_y = 1.0, float aspect = 1.0, bool bInvert = true, GLuint HostFBO = 0);
// Render a texture to the shared texture.
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);
#endif // #endif legacyOpenGL
protected:
// Sender creation and change
bool CheckSender(unsigned int width, unsigned int height);
// Create receiver connection
void InitReceiver(const char * sendername, unsigned int width, unsigned int height, DWORD dwFormat);
// Receiver find sender and retrieve information
bool ReceiveSenderData();
//
// Class globals
//
// Graphics adapter name
char m_AdapterName[256];
bool m_bAdapt; // Receiver adapt to the sender adapter
};
#endif
@@ -0,0 +1,102 @@
//
// Header: SpoutCommon.h
//
// Enables build of the SDK as a DLL.
//
// Includes header for common utilities namespace "SpoutUtils".
//
// Optional _#define legacyOpenGL_ to enable legacy draw functions
//
/*
Thanks and credit to Malcolm Bechard, the author of this file
https://github.com/mbechard
Copyright (c) 2014-2024, 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.
03.07.23 - Remove _MSC_VER condition from SPOUT_DLLEXP define
(#PR93 Fix MinGW error (beta branch)
07.12.23 - using namespace spoututils moved from SpoutGL.h
*/
#pragma once
#ifndef __SpoutCommon__
#define __SpoutCommon__
//
// To build the Spout library as a dll, define
// SPOUT_BUILD_DLL in the preprocessor defines.
// Properties > C++ > Preprocessor > Preprocessor Definitions
//
#ifndef SPOUT_DLLEXP
#if defined(SPOUT_BUILD_DLL)
#define SPOUT_DLLEXP __declspec(dllexport)
#elif defined(SPOUT_IMPORT_DLL)
#define SPOUT_DLLEXP __declspec(dllimport)
#else
#define SPOUT_DLLEXP
#endif
#endif
// Common utility functions namespace
#include "SpoutUtils.h"
//
// This definition enables legacy OpenGL rendering code
// used for shared texture Draw functions in SpoutGLDXinterop.cpp
// Not required unless compatibility with OpenGL < 3 is necessary
// Disabled by default for OpenGL 4 compliance
// * Note that the same definition is necessary in SpoutGLextensions.h
// so that SpoutGLextensions can be used independently of the Spout library.
//
// #define legacyOpenGL
//
//
// Visual Studio code analysis warnings
//
// C++11 scoped (class) enums are not compatible with early compilers (< VS2012 and others).
// The warning is designated "Prefer" and "C" standard unscoped enums are retained for compatibility.
#if defined(_MSC_VER)
#pragma warning(disable:26812) // unscoped enums
#endif
//
// For ARM build
// __movsd intrinsic not defined
//
#if defined _M_ARM64
#include <memory.h>
inline void __movsd(unsigned long* Destination,
const unsigned long* Source, size_t Count)
{
memcpy(Destination, Source, Count);
}
#endif
#endif

Some files were not shown because too many files have changed in this diff Show More