├── .gitattributes ├── .gitignore ├── IMG_20170512_130739.jpg ├── IMG_20170513_145051.jpg ├── IMG_VR_and_Projection.jpg ├── LICENSE.txt ├── MultiDisplaySpoutSystem.vcxproj ├── MultiDisplaySpoutSystem.vcxproj.filters ├── MultiDisplaySpoutSystem.vcxproj.user ├── PanoramaSpoutSender.unitypackage ├── README.md ├── addons.make ├── bin ├── FreeImage.dll ├── MultiDisplaySpoutSystem.exe ├── MultiDisplaySpoutSystem.exp ├── MultiDisplaySpoutSystem.lib ├── Zlib.dll ├── assimp.dll ├── avcodec-53.dll ├── avdevice-53.dll ├── avfilter-2.dll ├── avformat-53.dll ├── avutil-51.dll ├── data │ ├── .gitkeep │ ├── arial.ttf │ ├── caliPattern.jpg │ ├── params.xml │ └── sampleParams.xml ├── fmodex.dll ├── fmodexL.dll ├── freetype.dll ├── glut32.dll ├── libeay32.dll ├── postproc-51.dll ├── ssleay32.dll └── swscale-2.dll ├── icon.rc ├── imgs ├── 9ProjectorsParams.PNG ├── BuildSolution.PNG ├── SpoutSender.PNG ├── UnitySpoutSender.PNG ├── calibrationMode.png ├── dSwitch.PNG ├── executable.PNG ├── importSucceed.PNG ├── parameterFile.PNG ├── projectGenerator.PNG ├── projectorsParams.PNG ├── setProjectPath.PNG ├── successfullyRunUp.png ├── use9Projectors.jpg └── windowsDisplaySetting.PNG ├── photo3.jpg └── src ├── SpoutSDK ├── Spout.h ├── SpoutCommon.h ├── SpoutCopy.cpp ├── SpoutCopy.h ├── SpoutDirectX.cpp ├── SpoutDirectX.h ├── SpoutGLDXinterop.cpp ├── SpoutGLDXinterop.h ├── SpoutGLextensions.cpp ├── SpoutGLextensions.h ├── SpoutMemoryShare.cpp ├── SpoutMemoryShare.h ├── SpoutReceiver.cpp ├── SpoutReceiver.h ├── SpoutSDK.cpp ├── SpoutSDK.h ├── SpoutSender.cpp ├── SpoutSender.h ├── SpoutSenderNames.cpp ├── SpoutSenderNames.h ├── SpoutSharedMemory.cpp └── SpoutSharedMemory.h ├── displayApp.cpp ├── displayApp.h ├── main.cpp ├── ofApp.cpp ├── ofApp.h ├── ofxBezierWarp.cpp ├── ofxBezierWarp.h ├── ofxBezierWarpManager.cpp └── ofxBezierWarpManager.h /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | 7 | # Standard to msysgit 8 | *.doc diff=astextplain 9 | *.DOC diff=astextplain 10 | *.docx diff=astextplain 11 | *.DOCX diff=astextplain 12 | *.dot diff=astextplain 13 | *.DOT diff=astextplain 14 | *.pdf diff=astextplain 15 | *.PDF diff=astextplain 16 | *.rtf diff=astextplain 17 | *.RTF diff=astextplain 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ######################### 2 | # openFrameworks patterns 3 | ######################### 4 | 5 | # build files 6 | openFrameworks.a 7 | openFrameworksDebug.a 8 | openFrameworksUniversal.a 9 | libs/openFrameworksCompiled/lib/*/* 10 | !libs/openFrameworksCompiled/lib/*/.gitkeep 11 | 12 | # apothecary 13 | scripts/apothecary 14 | 15 | # rule to avoid non-official addons going into git 16 | # see addons/.gitignore 17 | addons/* 18 | 19 | # rule to avoid non-official apps going into git 20 | # see apps/.gitignore 21 | apps/* 22 | 23 | # rule to ignore compiled / downloaded libs 24 | /libs/* 25 | !/libs/openFrameworks 26 | !/libs/openFrameworksCompiled 27 | 28 | # also, see examples/.gitignore 29 | 30 | ######################### 31 | # general 32 | ######################### 33 | 34 | [Bb]uild/ 35 | [Oo]bj/ 36 | *.o 37 | examples/**/[Dd]ebug*/ 38 | examples/**/[Rr]elease*/ 39 | examples/**/gcc-debug/ 40 | examples/**/gcc-release/ 41 | tests/**/[Dd]ebug*/ 42 | tests/**/[Rr]elease*/ 43 | tests/**/gcc-debug/ 44 | tests/**/gcc-release/ 45 | *.mode* 46 | *.app/ 47 | *.pyc 48 | .svn/ 49 | *.log 50 | *.cpp.eep 51 | *.cpp.elf 52 | *.cpp.hex 53 | 54 | ######################### 55 | # IDE 56 | ######################### 57 | 58 | # XCode 59 | *.pbxuser 60 | *.perspective 61 | *.perspectivev3 62 | *.mode1v3 63 | *.mode2v3 64 | # XCode 4 65 | xcuserdata 66 | *.xcworkspace 67 | 68 | # Code::Blocks 69 | *.depend 70 | *.layout 71 | 72 | # Visual Studio 73 | *.sdf 74 | *.opensdf 75 | *.suo 76 | *.pdb 77 | *.ilk 78 | *.aps 79 | ipch/ 80 | 81 | # Eclipse 82 | .metadata 83 | local.properties 84 | .externalToolBuilders 85 | 86 | # Android Studio 87 | .idea 88 | .gradle 89 | gradle 90 | gradlew 91 | gradlew.bat 92 | 93 | # QtCreator 94 | *.qbs.user 95 | *.pro.user 96 | *.pri 97 | 98 | 99 | ######################### 100 | # operating system 101 | ######################### 102 | 103 | # Linux 104 | *~ 105 | # KDE 106 | .directory 107 | .AppleDouble 108 | 109 | # OSX 110 | .DS_Store 111 | *.swp 112 | *~.nib 113 | # Thumbnails 114 | ._* 115 | examples/ios/**/mediaAssets 116 | 117 | # Windows 118 | # Windows image file caches 119 | Thumbs.db 120 | # Folder config file 121 | Desktop.ini 122 | 123 | # Android 124 | .csettings 125 | /libs/openFrameworksCompiled/project/android/paths.make 126 | 127 | # Android Studio 128 | *.iml 129 | 130 | ######################### 131 | # miscellaneous 132 | ######################### 133 | 134 | .mailmap 135 | /apps*/ 136 | bin/data/BezierWarpManager_settings.xml -------------------------------------------------------------------------------- /IMG_20170512_130739.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gary9716/MultiDisplaySpoutSystem/b9bc7752bde2932ab1721276bd87ec1e59b583b6/IMG_20170512_130739.jpg -------------------------------------------------------------------------------- /IMG_20170513_145051.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gary9716/MultiDisplaySpoutSystem/b9bc7752bde2932ab1721276bd87ec1e59b583b6/IMG_20170513_145051.jpg -------------------------------------------------------------------------------- /IMG_VR_and_Projection.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gary9716/MultiDisplaySpoutSystem/b9bc7752bde2932ab1721276bd87ec1e59b583b6/IMG_VR_and_Projection.jpg -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | GNU LESSER GENERAL PUBLIC LICENSE 2 | Version 3, 29 June 2007 3 | 4 | Copyright (C) 2007 Free Software Foundation, Inc. 5 | Everyone is permitted to copy and distribute verbatim copies 6 | of this license document, but changing it is not allowed. 7 | 8 | 9 | This version of the GNU Lesser General Public License incorporates 10 | the terms and conditions of version 3 of the GNU General Public 11 | License, supplemented by the additional permissions listed below. 12 | 13 | 0. Additional Definitions. 14 | 15 | As used herein, "this License" refers to version 3 of the GNU Lesser 16 | General Public License, and the "GNU GPL" refers to version 3 of the GNU 17 | General Public License. 18 | 19 | "The Library" refers to a covered work governed by this License, 20 | other than an Application or a Combined Work as defined below. 21 | 22 | An "Application" is any work that makes use of an interface provided 23 | by the Library, but which is not otherwise based on the Library. 24 | Defining a subclass of a class defined by the Library is deemed a mode 25 | of using an interface provided by the Library. 26 | 27 | A "Combined Work" is a work produced by combining or linking an 28 | Application with the Library. The particular version of the Library 29 | with which the Combined Work was made is also called the "Linked 30 | Version". 31 | 32 | The "Minimal Corresponding Source" for a Combined Work means the 33 | Corresponding Source for the Combined Work, excluding any source code 34 | for portions of the Combined Work that, considered in isolation, are 35 | based on the Application, and not on the Linked Version. 36 | 37 | The "Corresponding Application Code" for a Combined Work means the 38 | object code and/or source code for the Application, including any data 39 | and utility programs needed for reproducing the Combined Work from the 40 | Application, but excluding the System Libraries of the Combined Work. 41 | 42 | 1. Exception to Section 3 of the GNU GPL. 43 | 44 | You may convey a covered work under sections 3 and 4 of this License 45 | without being bound by section 3 of the GNU GPL. 46 | 47 | 2. Conveying Modified Versions. 48 | 49 | If you modify a copy of the Library, and, in your modifications, a 50 | facility refers to a function or data to be supplied by an Application 51 | that uses the facility (other than as an argument passed when the 52 | facility is invoked), then you may convey a copy of the modified 53 | version: 54 | 55 | a) under this License, provided that you make a good faith effort to 56 | ensure that, in the event an Application does not supply the 57 | function or data, the facility still operates, and performs 58 | whatever part of its purpose remains meaningful, or 59 | 60 | b) under the GNU GPL, with none of the additional permissions of 61 | this License applicable to that copy. 62 | 63 | 3. Object Code Incorporating Material from Library Header Files. 64 | 65 | The object code form of an Application may incorporate material from 66 | a header file that is part of the Library. You may convey such object 67 | code under terms of your choice, provided that, if the incorporated 68 | material is not limited to numerical parameters, data structure 69 | layouts and accessors, or small macros, inline functions and templates 70 | (ten or fewer lines in length), you do both of the following: 71 | 72 | a) Give prominent notice with each copy of the object code that the 73 | Library is used in it and that the Library and its use are 74 | covered by this License. 75 | 76 | b) Accompany the object code with a copy of the GNU GPL and this license 77 | document. 78 | 79 | 4. Combined Works. 80 | 81 | You may convey a Combined Work under terms of your choice that, 82 | taken together, effectively do not restrict modification of the 83 | portions of the Library contained in the Combined Work and reverse 84 | engineering for debugging such modifications, if you also do each of 85 | the following: 86 | 87 | a) Give prominent notice with each copy of the Combined Work that 88 | the Library is used in it and that the Library and its use are 89 | covered by this License. 90 | 91 | b) Accompany the Combined Work with a copy of the GNU GPL and this license 92 | document. 93 | 94 | c) For a Combined Work that displays copyright notices during 95 | execution, include the copyright notice for the Library among 96 | these notices, as well as a reference directing the user to the 97 | copies of the GNU GPL and this license document. 98 | 99 | d) Do one of the following: 100 | 101 | 0) Convey the Minimal Corresponding Source under the terms of this 102 | License, and the Corresponding Application Code in a form 103 | suitable for, and under terms that permit, the user to 104 | recombine or relink the Application with a modified version of 105 | the Linked Version to produce a modified Combined Work, in the 106 | manner specified by section 6 of the GNU GPL for conveying 107 | Corresponding Source. 108 | 109 | 1) Use a suitable shared library mechanism for linking with the 110 | Library. A suitable mechanism is one that (a) uses at run time 111 | a copy of the Library already present on the user's computer 112 | system, and (b) will operate properly with a modified version 113 | of the Library that is interface-compatible with the Linked 114 | Version. 115 | 116 | e) Provide Installation Information, but only if you would otherwise 117 | be required to provide such information under section 6 of the 118 | GNU GPL, and only to the extent that such information is 119 | necessary to install and execute a modified version of the 120 | Combined Work produced by recombining or relinking the 121 | Application with a modified version of the Linked Version. (If 122 | you use option 4d0, the Installation Information must accompany 123 | the Minimal Corresponding Source and Corresponding Application 124 | Code. If you use option 4d1, you must provide the Installation 125 | Information in the manner specified by section 6 of the GNU GPL 126 | for conveying Corresponding Source.) 127 | 128 | 5. Combined Libraries. 129 | 130 | You may place library facilities that are a work based on the 131 | Library side by side in a single library together with other library 132 | facilities that are not Applications and are not covered by this 133 | License, and convey such a combined library under terms of your 134 | choice, if you do both of the following: 135 | 136 | a) Accompany the combined library with a copy of the same work based 137 | on the Library, uncombined with any other library facilities, 138 | conveyed under the terms of this License. 139 | 140 | b) Give prominent notice with the combined library that part of it 141 | is a work based on the Library, and explaining where to find the 142 | accompanying uncombined form of the same work. 143 | 144 | 6. Revised Versions of the GNU Lesser General Public License. 145 | 146 | The Free Software Foundation may publish revised and/or new versions 147 | of the GNU Lesser General Public License from time to time. Such new 148 | versions will be similar in spirit to the present version, but may 149 | differ in detail to address new problems or concerns. 150 | 151 | Each version is given a distinguishing version number. If the 152 | Library as you received it specifies that a certain numbered version 153 | of the GNU Lesser General Public License "or any later version" 154 | applies to it, you have the option of following the terms and 155 | conditions either of that published version or of any later version 156 | published by the Free Software Foundation. If the Library as you 157 | received it does not specify a version number of the GNU Lesser 158 | General Public License, you may choose any version of the GNU Lesser 159 | General Public License ever published by the Free Software Foundation. 160 | 161 | If the Library as you received it specifies that a proxy can decide 162 | whether future versions of the GNU Lesser General Public License shall 163 | apply, that proxy's public statement of acceptance of any version is 164 | permanent authorization for you to choose that version for the 165 | Library. 166 | -------------------------------------------------------------------------------- /MultiDisplaySpoutSystem.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | addons\ofxOsc\src 6 | 7 | 8 | addons\ofxOsc\src 9 | 10 | 11 | addons\ofxOsc\src 12 | 13 | 14 | addons\ofxOsc\src 15 | 16 | 17 | addons\ofxOsc\src 18 | 19 | 20 | addons\ofxOsc\libs\oscpack\src\ip 21 | 22 | 23 | addons\ofxOsc\libs\oscpack\src\ip\win32 24 | 25 | 26 | addons\ofxOsc\libs\oscpack\src\ip\win32 27 | 28 | 29 | addons\ofxOsc\libs\oscpack\src\osc 30 | 31 | 32 | addons\ofxOsc\libs\oscpack\src\osc 33 | 34 | 35 | addons\ofxOsc\libs\oscpack\src\osc 36 | 37 | 38 | addons\ofxOsc\libs\oscpack\src\osc 39 | 40 | 41 | addons\ofxXmlSettings\src 42 | 43 | 44 | addons\ofxXmlSettings\libs 45 | 46 | 47 | addons\ofxXmlSettings\libs 48 | 49 | 50 | addons\ofxXmlSettings\libs 51 | 52 | 53 | src 54 | 55 | 56 | src 57 | 58 | 59 | src 60 | 61 | 62 | src 63 | 64 | 65 | src 66 | 67 | 68 | src 69 | 70 | 71 | src 72 | 73 | 74 | src 75 | 76 | 77 | src 78 | 79 | 80 | src 81 | 82 | 83 | src 84 | 85 | 86 | src 87 | 88 | 89 | src 90 | 91 | 92 | src 93 | 94 | 95 | src 96 | 97 | 98 | 99 | 100 | {d8376475-7454-4a24-b08a-aac121d3ad6f} 101 | 102 | 103 | {69b8057a-12d3-4be5-8561-d09292782880} 104 | 105 | 106 | {2d4172ce-2b77-4e2a-8f09-bb4cdd558165} 107 | 108 | 109 | {bc0597c2-63de-4b31-a55e-0d27261c6e4c} 110 | 111 | 112 | {2e56b601-64db-4f25-8b74-08f3763371df} 113 | 114 | 115 | {a8aa60bd-2874-4bd9-a905-535cd0af1f7a} 116 | 117 | 118 | {0047ae97-4908-4262-83f9-0ca3fcfd5248} 119 | 120 | 121 | {1bfb6c65-02e2-41a1-812e-5f91085558a6} 122 | 123 | 124 | {4412d857-9444-47e5-aeb1-163dac350367} 125 | 126 | 127 | {72b19e9b-06eb-4367-93b0-7754625af8f9} 128 | 129 | 130 | {88b66b1f-0a38-475a-a488-ca67ccfe8997} 131 | 132 | 133 | {287b8ecf-d8ad-47df-b5c8-20bc027ff111} 134 | 135 | 136 | {e4b5c0c3-ae98-4c9f-b6fc-2538a9416cfb} 137 | 138 | 139 | 140 | 141 | addons\ofxOsc\src 142 | 143 | 144 | addons\ofxOsc\src 145 | 146 | 147 | addons\ofxOsc\src 148 | 149 | 150 | addons\ofxOsc\src 151 | 152 | 153 | addons\ofxOsc\src 154 | 155 | 156 | addons\ofxOsc\src 157 | 158 | 159 | addons\ofxOsc\src 160 | 161 | 162 | addons\ofxOsc\libs\oscpack\src\ip 163 | 164 | 165 | addons\ofxOsc\libs\oscpack\src\ip 166 | 167 | 168 | addons\ofxOsc\libs\oscpack\src\ip 169 | 170 | 171 | addons\ofxOsc\libs\oscpack\src\ip 172 | 173 | 174 | addons\ofxOsc\libs\oscpack\src\ip 175 | 176 | 177 | addons\ofxOsc\libs\oscpack\src\osc 178 | 179 | 180 | addons\ofxOsc\libs\oscpack\src\osc 181 | 182 | 183 | addons\ofxOsc\libs\oscpack\src\osc 184 | 185 | 186 | addons\ofxOsc\libs\oscpack\src\osc 187 | 188 | 189 | addons\ofxOsc\libs\oscpack\src\osc 190 | 191 | 192 | addons\ofxOsc\libs\oscpack\src\osc 193 | 194 | 195 | addons\ofxOsc\libs\oscpack\src\osc 196 | 197 | 198 | addons\ofxOsc\libs\oscpack\src\osc 199 | 200 | 201 | addons\ofxXmlSettings\src 202 | 203 | 204 | addons\ofxXmlSettings\libs 205 | 206 | 207 | src 208 | 209 | 210 | src 211 | 212 | 213 | src 214 | 215 | 216 | src 217 | 218 | 219 | src 220 | 221 | 222 | src 223 | 224 | 225 | src 226 | 227 | 228 | src 229 | 230 | 231 | src 232 | 233 | 234 | src 235 | 236 | 237 | src 238 | 239 | 240 | src 241 | 242 | 243 | src 244 | 245 | 246 | src 247 | 248 | 249 | src 250 | 251 | 252 | src 253 | 254 | 255 | 256 | 257 | 258 | -------------------------------------------------------------------------------- /MultiDisplaySpoutSystem.vcxproj.user: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /PanoramaSpoutSender.unitypackage: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gary9716/MultiDisplaySpoutSystem/b9bc7752bde2932ab1721276bd87ec1e59b583b6/PanoramaSpoutSender.unitypackage -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # MultiDisplaySpoutSystem 2 | 3 | It is a panoramic projection system implemented in Openframeworks and was used in my art exhibition in National Taiwan Museum of Fine Arts. It has been demonstrated that we can run the system that spawned 9 applications for projection, each of which rendered in the resolution of 1920 * 1200 and also run a Vive VR application on a single computer in the same time smoothly. (I forgot the actual frame rate but I wouldn't feel dizzy during the VR app experience.) 4 | The overall system contains 2 Openframeworks class and their roles are: 5 | 1. ofApp: 6 | * receive an large texture via [Spout](http://spout.zeal.co/) library (In my case, it received an texture with the resolution of 15390 * 1200 from Unity). 7 | * show calibration GUI in calibration mode. 8 | * receive mouse and keyboard events. 9 | * receive OSC message from other application like Unity so it can be controlled via application in other platform. 10 | * manage the visibility of other windows applications which are the instances of displayApp. 11 | * expose the texture processing API for displayApp. 12 | 2. displayApp: 13 | * process the texture(extract part of the texture and warp the extracted content) via the API in ofApp. 14 | * project it onto display. 15 | 16 | ## Getting Started 17 | 18 | These instructions will get you a copy of the project up and running on your local machine. 19 | 20 | ### Prerequisites 21 | 22 | * Windows OS (Currently,it only support Windows OS and has worked well in 8.1 and 10) 23 | * Openframeworks SDK (I developed this with SDK version 0.9.8) 24 | * Visual Studio 2015 25 | 26 | ### Setup this project 27 | 28 | 1. Follow the instructions in Openframeworks website: (it can be skipped if you have already setup OF SDK) 29 | * [Download SDK](http://openframeworks.cc/download/) 30 | * [Setup SDK with Visual Studio](http://openframeworks.cc/setup/vs/) 31 | 2. Download this repository and unzip it 32 | 3. Open the project generator in the Openframeworks SDK folder (the path would be "{path to the root of OF SDK}\projectGenerator-vs") 33 | 34 | ![projectGenerator](https://github.com/gary9716/MultiDisplaySpoutSystem/blob/master/imgs/projectGenerator.PNG?raw=true) 35 | 36 | 4. click the "import" button and select the project folder which is the root of bin and src. 37 | 38 | ![setProjPath](https://github.com/gary9716/MultiDisplaySpoutSystem/blob/master/imgs/setProjectPath.PNG?raw=true) 39 | 40 | 5. If the project is successfully imported, it should look like the image below. click the "Update" button and then click the "Open In IDE" button. 41 | 42 | ![importSucceed](https://github.com/gary9716/MultiDisplaySpoutSystem/blob/master/imgs/importSucceed.PNG?raw=true) 43 | 44 | 6. click Build > Build Solution and after the project is successfully built, the executable would be in the bin folder of project folder. 45 | 46 | ![BuildSolution](https://github.com/gary9716/MultiDisplaySpoutSystem/blob/master/imgs/BuildSolution.PNG?raw=true) 47 | 48 | ![executable](https://github.com/gary9716/MultiDisplaySpoutSystem/blob/master/imgs/executable.PNG?raw=true) 49 | 50 | ### Specify Parameters 51 | 52 | There is a parameter file called "param.xml" under the path {project path}\bin\data. 53 | The meaning of these parameters: 54 | 1. ShowDebugInfo: show debugging information like FPS. 55 | 56 | 2. MonitorIndices: the indices of monitors(or displays) you want to use. the information can be look up in console window. 57 | The console window in the image below sort the monitors' virtual position by their X position. 58 | 59 | ![consoleWin](https://github.com/gary9716/MultiDisplaySpoutSystem/blob/master/imgs/use9Projectors.jpg?raw=true) 60 | 61 | According to this information, one can set the params.xml like this: 62 | 63 | ![params](https://github.com/gary9716/MultiDisplaySpoutSystem/blob/master/imgs/9ProjectorsParams.PNG?raw=true) 64 | 65 | 3. SubSectionIndices: the indices used for calculating which part of texture should be extracted. 66 | Given the resolution of each display and their overlapping width, the left boundary of each extracted is calculated as ( resolutionX - overlappingWidth ) * index. 67 | For example: the left boundary of an application with subsection index 1 would be (1920 - 210) * 1 = 1710 68 | 69 | ![projectorsParams](https://github.com/gary9716/MultiDisplaySpoutSystem/blob/master/imgs/projectorsParams.PNG?raw=true) 70 | 71 | Because it’s circular, setting 1 and 2 are both valid setting. 72 | 73 | Another point is that the monitors in windows display setting also need to be arranged in the right order. 74 | 75 | ![windowsDisplaySetting](https://github.com/gary9716/MultiDisplaySpoutSystem/blob/master/imgs/windowsDisplaySetting.PNG?raw=true) 76 | 77 | 4. PauseAndLeave: pause for viewing the information in console window and terminate the application. mainly for adjusting parameters.(1 for using this function and 0 for not using this function) 78 | 79 | 5. AppMode: 0 for demonstration mode and 1 for calibration mode. 80 | 81 | 6. LoadMapping: load the bezier warping parameters saved in BezierWarpManager_settings.xml.(1 for loading and 0 for not loading) 82 | 83 | 7. DoWarp: 1 for applying bezier warping and 0 for simply displaying extracted region. 84 | 85 | 8. CornerX: the percentage of padding of X direction in calibration mode. 86 | 87 | 9. CornerY: the percentage of padding of Y direction in calibration mode. 88 | 89 | 10. OverlapPixels: the width of overlapping area between two consecutive displays. 90 | 91 | 11. SpoutSender: the name of the spout sender that sends the shared texture. 92 | 93 | 12. resolution: the resolution of certain monitor. 94 | 95 | ### Test the system 96 | 97 | To test the system, you would need a SpoutSender. Here I provide the Unity SpoutSender used in my art exhibition. It creates several cameras, aligns their frustum , makes them render to a large renderTexture and uses a SpoutSender to share the texture. 98 | Steps of setting up the SpoutSender in Unity: 99 | 1. drop the PanoramaSpoutSender.unitypackage into Unity asset folder. 100 | 2. drop the PanoramaCamAndSpout.prefab into a scene and save the scene.(if you didn't save the scene after dropping the prefab, it may crash during runtime) 101 | 3. click play button in Unity. 102 | 4. set the AppMode as 0 in param.xml and run the executable in the bin folder of project folder. 103 | 5. see whether the system project correctly. 104 | 105 | ![testResult](https://github.com/gary9716/MultiDisplaySpoutSystem/blob/master/imgs/successfullyRunUp.png?raw=true) 106 | 107 | ## Calibration 108 | ![caliMode](https://github.com/gary9716/MultiDisplaySpoutSystem/blob/master/imgs/calibrationMode.png?raw=true) 109 | In calibration mode, Main App(ofApp) would render the content based on currently selected displayApp. User can switch among displayApps, adjust the overlapping area and warp the content for adapting curve surface. 110 | How To: 111 | 1. set the AppMode as 1 and run the executable 112 | 2. focus on the Main App and user can do the following interaction. 113 | * key pressed: 114 | * F1 or F2: switch among displayApps 115 | * F5: save the warping parameters 116 | * F6: load the warping parameters 117 | * ESC: close the system 118 | * z: switch between drawing the warped texture or drawing calibration rectangles. 119 | ![zSwitch](https://github.com/gary9716/MultiDisplaySpoutSystem/blob/master/imgs/dSwitch.PNG?raw=true) 120 | * d: restore the default setting of current selected displayApp. 121 | * arrow keys: move the selected anchor or crosshair. 122 | * mouse interaction: 123 | * right click on one of crosshairs: show/hide bezier warping anchors. 124 | * left click on one of crosshairs or anchors: select clicked anchor or crosshair 125 | * left click and drag one of crosshairs or anchors: move the anchor or crosshair. 126 | 127 | ## Specs of the computer used in the art exhibition: 128 | 129 | * CPU: i7 7700K 130 | * GPU: GTX 1060 Mini ITX OC 3G, GTX 1050Ti OC 4G, HD7750 131 | * Motherboard: ROG STRIX Z270F 132 | * RAM: DDR4 2400 8GB * 2 133 | 134 | ## Built With 135 | 136 | * [Spout](http://spout.zeal.co/) - real-time video sharing system. 137 | * [ofxBezierWarp](https://github.com/patrick88/ofxBezierWarp) - an addon that can do bezier warping and control the warping with mouse and keyboard. 138 | * [ofxBezierWarpManager](https://github.com/TsubokuLab/ofxBezierWarpManager) - an addon that manage multiple bezier warps. 139 | 140 | ## Contributing 141 | 142 | Please read [CONTRIBUTING.md](https://gist.github.com/PurpleBooth/b24679402957c63ec426) for details on our code of conduct, and the process for submitting pull requests to us. 143 | 144 | ## Authors 145 | 146 | * Kuan-Ting Chou : the only developer of this system 147 | 148 | ## License 149 | 150 | This project is licensed under the GNU Lesser General Public License - see the [LICENSE.txt](https://github.com/gary9716/MultiDisplaySpoutSystem/blob/master/LICENSE.txt) file for details 151 | 152 | ## Art exhibition photos 153 | ![photo1](https://github.com/gary9716/MultiDisplaySpoutSystem/blob/master/IMG_20170512_130739.jpg?raw=true) 154 | 155 | ![photo2](https://github.com/gary9716/MultiDisplaySpoutSystem/blob/master/IMG_20170513_145051.jpg?raw=true) 156 | 157 | ![photo3](https://github.com/gary9716/MultiDisplaySpoutSystem/blob/master/photo3.jpg?raw=true) 158 | 159 | ![photo4](https://github.com/gary9716/MultiDisplaySpoutSystem/blob/master/IMG_VR_and_Projection.jpg?raw=true) 160 | 161 | ## Acknowledgments 162 | 163 | * The great addons and library I have used in this project 164 | * Inspired by my friend called Liu Ting Chun who is studying in Taipei National University of the Arts 165 | * NTMOFA for giving me an chance 166 | * [README Template](https://gist.github.com/PurpleBooth/b24679402957c63ec426) 167 | -------------------------------------------------------------------------------- /addons.make: -------------------------------------------------------------------------------- 1 | ofxOsc 2 | ofxXmlSettings 3 | -------------------------------------------------------------------------------- /bin/FreeImage.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gary9716/MultiDisplaySpoutSystem/b9bc7752bde2932ab1721276bd87ec1e59b583b6/bin/FreeImage.dll -------------------------------------------------------------------------------- /bin/MultiDisplaySpoutSystem.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gary9716/MultiDisplaySpoutSystem/b9bc7752bde2932ab1721276bd87ec1e59b583b6/bin/MultiDisplaySpoutSystem.exe -------------------------------------------------------------------------------- /bin/MultiDisplaySpoutSystem.exp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gary9716/MultiDisplaySpoutSystem/b9bc7752bde2932ab1721276bd87ec1e59b583b6/bin/MultiDisplaySpoutSystem.exp -------------------------------------------------------------------------------- /bin/MultiDisplaySpoutSystem.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gary9716/MultiDisplaySpoutSystem/b9bc7752bde2932ab1721276bd87ec1e59b583b6/bin/MultiDisplaySpoutSystem.lib -------------------------------------------------------------------------------- /bin/Zlib.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gary9716/MultiDisplaySpoutSystem/b9bc7752bde2932ab1721276bd87ec1e59b583b6/bin/Zlib.dll -------------------------------------------------------------------------------- /bin/assimp.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gary9716/MultiDisplaySpoutSystem/b9bc7752bde2932ab1721276bd87ec1e59b583b6/bin/assimp.dll -------------------------------------------------------------------------------- /bin/avcodec-53.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gary9716/MultiDisplaySpoutSystem/b9bc7752bde2932ab1721276bd87ec1e59b583b6/bin/avcodec-53.dll -------------------------------------------------------------------------------- /bin/avdevice-53.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gary9716/MultiDisplaySpoutSystem/b9bc7752bde2932ab1721276bd87ec1e59b583b6/bin/avdevice-53.dll -------------------------------------------------------------------------------- /bin/avfilter-2.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gary9716/MultiDisplaySpoutSystem/b9bc7752bde2932ab1721276bd87ec1e59b583b6/bin/avfilter-2.dll -------------------------------------------------------------------------------- /bin/avformat-53.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gary9716/MultiDisplaySpoutSystem/b9bc7752bde2932ab1721276bd87ec1e59b583b6/bin/avformat-53.dll -------------------------------------------------------------------------------- /bin/avutil-51.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gary9716/MultiDisplaySpoutSystem/b9bc7752bde2932ab1721276bd87ec1e59b583b6/bin/avutil-51.dll -------------------------------------------------------------------------------- /bin/data/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gary9716/MultiDisplaySpoutSystem/b9bc7752bde2932ab1721276bd87ec1e59b583b6/bin/data/.gitkeep -------------------------------------------------------------------------------- /bin/data/arial.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gary9716/MultiDisplaySpoutSystem/b9bc7752bde2932ab1721276bd87ec1e59b583b6/bin/data/arial.ttf -------------------------------------------------------------------------------- /bin/data/caliPattern.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gary9716/MultiDisplaySpoutSystem/b9bc7752bde2932ab1721276bd87ec1e59b583b6/bin/data/caliPattern.jpg -------------------------------------------------------------------------------- /bin/data/params.xml: -------------------------------------------------------------------------------- 1 | 1 2 | 1 3 | 1 4 | 1 5 | 1 6 | 0 7 | 0 8 | 0.040000000 9 | 0.020000000 10 | 210 11 | UnitySender1 12 | 13 | 1920 14 | 1080 15 | 16 | -------------------------------------------------------------------------------- /bin/data/sampleParams.xml: -------------------------------------------------------------------------------- 1 | 1 2 | 0,1 3 | 0,1 4 | 0 5 | 0 6 | 0 7 | 1 8 | 0.040000000 9 | 0.020000000 10 | 210 11 | UnitySender1 12 | 13 | 1920 14 | 1200 15 | 16 | 17 | 1920 18 | 1200 19 | 20 | -------------------------------------------------------------------------------- /bin/fmodex.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gary9716/MultiDisplaySpoutSystem/b9bc7752bde2932ab1721276bd87ec1e59b583b6/bin/fmodex.dll -------------------------------------------------------------------------------- /bin/fmodexL.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gary9716/MultiDisplaySpoutSystem/b9bc7752bde2932ab1721276bd87ec1e59b583b6/bin/fmodexL.dll -------------------------------------------------------------------------------- /bin/freetype.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gary9716/MultiDisplaySpoutSystem/b9bc7752bde2932ab1721276bd87ec1e59b583b6/bin/freetype.dll -------------------------------------------------------------------------------- /bin/glut32.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gary9716/MultiDisplaySpoutSystem/b9bc7752bde2932ab1721276bd87ec1e59b583b6/bin/glut32.dll -------------------------------------------------------------------------------- /bin/libeay32.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gary9716/MultiDisplaySpoutSystem/b9bc7752bde2932ab1721276bd87ec1e59b583b6/bin/libeay32.dll -------------------------------------------------------------------------------- /bin/postproc-51.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gary9716/MultiDisplaySpoutSystem/b9bc7752bde2932ab1721276bd87ec1e59b583b6/bin/postproc-51.dll -------------------------------------------------------------------------------- /bin/ssleay32.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gary9716/MultiDisplaySpoutSystem/b9bc7752bde2932ab1721276bd87ec1e59b583b6/bin/ssleay32.dll -------------------------------------------------------------------------------- /bin/swscale-2.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gary9716/MultiDisplaySpoutSystem/b9bc7752bde2932ab1721276bd87ec1e59b583b6/bin/swscale-2.dll -------------------------------------------------------------------------------- /icon.rc: -------------------------------------------------------------------------------- 1 | // Icon Resource Definition 2 | #define MAIN_ICON 102 3 | 4 | #if defined(_DEBUG) 5 | MAIN_ICON ICON "icon_debug.ico" 6 | #else 7 | MAIN_ICON ICON "icon.ico" 8 | #endif 9 | -------------------------------------------------------------------------------- /imgs/9ProjectorsParams.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gary9716/MultiDisplaySpoutSystem/b9bc7752bde2932ab1721276bd87ec1e59b583b6/imgs/9ProjectorsParams.PNG -------------------------------------------------------------------------------- /imgs/BuildSolution.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gary9716/MultiDisplaySpoutSystem/b9bc7752bde2932ab1721276bd87ec1e59b583b6/imgs/BuildSolution.PNG -------------------------------------------------------------------------------- /imgs/SpoutSender.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gary9716/MultiDisplaySpoutSystem/b9bc7752bde2932ab1721276bd87ec1e59b583b6/imgs/SpoutSender.PNG -------------------------------------------------------------------------------- /imgs/UnitySpoutSender.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gary9716/MultiDisplaySpoutSystem/b9bc7752bde2932ab1721276bd87ec1e59b583b6/imgs/UnitySpoutSender.PNG -------------------------------------------------------------------------------- /imgs/calibrationMode.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gary9716/MultiDisplaySpoutSystem/b9bc7752bde2932ab1721276bd87ec1e59b583b6/imgs/calibrationMode.png -------------------------------------------------------------------------------- /imgs/dSwitch.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gary9716/MultiDisplaySpoutSystem/b9bc7752bde2932ab1721276bd87ec1e59b583b6/imgs/dSwitch.PNG -------------------------------------------------------------------------------- /imgs/executable.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gary9716/MultiDisplaySpoutSystem/b9bc7752bde2932ab1721276bd87ec1e59b583b6/imgs/executable.PNG -------------------------------------------------------------------------------- /imgs/importSucceed.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gary9716/MultiDisplaySpoutSystem/b9bc7752bde2932ab1721276bd87ec1e59b583b6/imgs/importSucceed.PNG -------------------------------------------------------------------------------- /imgs/parameterFile.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gary9716/MultiDisplaySpoutSystem/b9bc7752bde2932ab1721276bd87ec1e59b583b6/imgs/parameterFile.PNG -------------------------------------------------------------------------------- /imgs/projectGenerator.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gary9716/MultiDisplaySpoutSystem/b9bc7752bde2932ab1721276bd87ec1e59b583b6/imgs/projectGenerator.PNG -------------------------------------------------------------------------------- /imgs/projectorsParams.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gary9716/MultiDisplaySpoutSystem/b9bc7752bde2932ab1721276bd87ec1e59b583b6/imgs/projectorsParams.PNG -------------------------------------------------------------------------------- /imgs/setProjectPath.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gary9716/MultiDisplaySpoutSystem/b9bc7752bde2932ab1721276bd87ec1e59b583b6/imgs/setProjectPath.PNG -------------------------------------------------------------------------------- /imgs/successfullyRunUp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gary9716/MultiDisplaySpoutSystem/b9bc7752bde2932ab1721276bd87ec1e59b583b6/imgs/successfullyRunUp.png -------------------------------------------------------------------------------- /imgs/use9Projectors.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gary9716/MultiDisplaySpoutSystem/b9bc7752bde2932ab1721276bd87ec1e59b583b6/imgs/use9Projectors.jpg -------------------------------------------------------------------------------- /imgs/windowsDisplaySetting.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gary9716/MultiDisplaySpoutSystem/b9bc7752bde2932ab1721276bd87ec1e59b583b6/imgs/windowsDisplaySetting.PNG -------------------------------------------------------------------------------- /photo3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gary9716/MultiDisplaySpoutSystem/b9bc7752bde2932ab1721276bd87ec1e59b583b6/photo3.jpg -------------------------------------------------------------------------------- /src/SpoutSDK/Spout.h: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Spout.h 4 | 5 | The main Spout include file for the SDK 6 | 7 | Copyright (c) 2014-2017, Lynn Jarvis. All rights reserved. 8 | 9 | Redistribution and use in source and binary forms, with or without modification, 10 | are permitted provided that the following conditions are met: 11 | 12 | 1. Redistributions of source code must retain the above copyright notice, 13 | this list of conditions and the following disclaimer. 14 | 15 | 2. Redistributions in binary form must reproduce the above copyright notice, 16 | this list of conditions and the following disclaimer in the documentation 17 | and/or other materials provided with the distribution. 18 | 19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 20 | EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 21 | OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22 | IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 23 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 24 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 26 | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | 29 | 30 | */ 31 | #pragma once 32 | 33 | #ifndef __Spout__ 34 | #define __Spout__ 35 | 36 | #include "SpoutSender.h" 37 | #include "SpoutReceiver.h" 38 | 39 | // All documentation in the SDK pdf = SpoutSDK.pdf 40 | 41 | #endif 42 | -------------------------------------------------------------------------------- /src/SpoutSDK/SpoutCommon.h: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Spout.h 4 | 5 | The main Spout include file for the SDK 6 | 7 | Copyright (c) 2014-2017, Lynn Jarvis. All rights reserved. 8 | 9 | Redistribution and use in source and binary forms, with or without modification, 10 | are permitted provided that the following conditions are met: 11 | 12 | 1. Redistributions of source code must retain the above copyright notice, 13 | this list of conditions and the following disclaimer. 14 | 15 | 2. Redistributions in binary form must reproduce the above copyright notice, 16 | this list of conditions and the following disclaimer in the documentation 17 | and/or other materials provided with the distribution. 18 | 19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 20 | EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 21 | OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22 | IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 23 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 24 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 26 | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | 29 | 30 | */ 31 | #pragma once 32 | 33 | #ifndef __SpoutCommon__ 34 | #define __SpoutCommon__ 35 | 36 | #if defined(_MSC_VER) 37 | #if defined(SPOUT_BUILD_DLL) 38 | #define SPOUT_DLLEXP __declspec(dllexport) 39 | #elif defined(SPOUT_IMPORT_DLL) 40 | #define SPOUT_DLLEXP __declspec(dllimport) 41 | #else 42 | #define SPOUT_DLLEXP 43 | #endif 44 | #else // _MSC_VER 45 | #define SPOUT_DLLEXP 46 | #endif // _MSC_VERR 47 | 48 | 49 | #endif 50 | -------------------------------------------------------------------------------- /src/SpoutSDK/SpoutCopy.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gary9716/MultiDisplaySpoutSystem/b9bc7752bde2932ab1721276bd87ec1e59b583b6/src/SpoutSDK/SpoutCopy.cpp -------------------------------------------------------------------------------- /src/SpoutSDK/SpoutCopy.h: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | SpoutCopy.h 4 | 5 | Functions to manage pixel buffer copying and rgb/rgba <> bgr/bgra conversion 6 | 7 | - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 8 | 9 | Copyright (c) 2016-2017, Lynn Jarvis. All rights reserved. 10 | 11 | Redistribution and use in source and binary forms, with or without modification, 12 | are permitted provided that the following conditions are met: 13 | 14 | 1. Redistributions of source code must retain the above copyright notice, 15 | this list of conditions and the following disclaimer. 16 | 17 | 2. Redistributions in binary form must reproduce the above copyright notice, 18 | this list of conditions and the following disclaimer in the documentation 19 | and/or other materials provided with the distribution. 20 | 21 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 22 | EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 23 | OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 24 | IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 25 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 26 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28 | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | 31 | */ 32 | #pragma once 33 | #ifndef __spoutCopy__ // standard way as well 34 | #define __spoutCopy__ 35 | 36 | #include "SpoutCommon.h" 37 | #include 38 | #include // for debug printf 39 | #include // For OpenGL definitions 40 | #include // for cpuid to test for SSE2 41 | #include // for SSE2 42 | #include // for SSSE3 43 | 44 | 45 | class SPOUT_DLLEXP spoutCopy { 46 | 47 | public: 48 | 49 | spoutCopy(); 50 | ~spoutCopy(); 51 | 52 | void CopyPixels(const unsigned char *src, unsigned char *dst, 53 | unsigned int width, unsigned int height, 54 | GLenum glFormat = GL_RGBA, bool bInvert = false); 55 | 56 | bool FlipBuffer(const unsigned char *src, unsigned char *dst, 57 | unsigned int width, unsigned int height, 58 | GLenum glFormat = GL_RGBA); 59 | 60 | void memcpy_sse2(void* dst, void* src, size_t size); 61 | 62 | void rgba2bgra(void* rgba_source, void *bgra_dest, unsigned int width, unsigned int height, bool bInvert = false); 63 | void bgra2rgba(void* bgra_source, void *rgba_dest, unsigned int width, unsigned int height, bool bInvert = false); 64 | 65 | void rgba_bgra(void *rgba_source, void *bgra_dest, unsigned int width, unsigned int height, bool bInvert = false); 66 | void rgba_bgra_sse2(void *rgba_source, void *rgba_dest, unsigned int width, unsigned int height, bool bInvert = false); 67 | void rgba_bgra_ssse3(void *rgba_source, void *rgba_dest, unsigned int width, unsigned int height, bool bInvert = false); 68 | 69 | // TODO avoid redundancy 70 | void rgb2rgba (void* rgb_source, void *rgba_dest, unsigned int width, unsigned int height, bool bInvert = false); 71 | void bgr2rgba (void* bgr_source, void *rgba_dest, unsigned int width, unsigned int height, bool bInvert = false); 72 | 73 | void rgb2bgra (void* rgb_source, void *bgra_dest, unsigned int width, unsigned int height, bool bInvert = false); 74 | void bgr2bgra (void* bgr_source, void *bgra_dest, unsigned int width, unsigned int height, bool bInvert = false); 75 | 76 | void rgba2rgb (void* rgba_source, void *rgb_dest, unsigned int width, unsigned int height, bool bInvert = false); 77 | void rgba2bgr (void* rgba_source, void *bgr_dest, unsigned int width, unsigned int height, bool bInvert = false); 78 | 79 | void bgra2rgb (void* bgra_source, void *rgb_dest, unsigned int width, unsigned int height, bool bInvert = false); 80 | void bgra2bgr (void* bgra_source, void *bgr_dest, unsigned int width, unsigned int height, bool bInvert = false); 81 | 82 | private : 83 | 84 | void CheckSSE(); 85 | bool m_bSSE2; 86 | bool m_bSSE3; 87 | bool m_bSSSE3; 88 | 89 | }; 90 | 91 | #endif 92 | -------------------------------------------------------------------------------- /src/SpoutSDK/SpoutDirectX.h: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | spoutDirectX.h 4 | 5 | DirectX functions to manage DirectX 11 texture sharing 6 | 7 | 8 | Copyright (c) 2014 - 2017, Lynn Jarvis. All rights reserved. 9 | 10 | Redistribution and use in source and binary forms, with or without modification, 11 | are permitted provided that the following conditions are met: 12 | 13 | 1. Redistributions of source code must retain the above copyright notice, 14 | this list of conditions and the following disclaimer. 15 | 16 | 2. Redistributions in binary form must reproduce the above copyright notice, 17 | this list of conditions and the following disclaimer in the documentation 18 | and/or other materials provided with the distribution. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 21 | EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 22 | OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 23 | IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 24 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 25 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27 | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | 30 | */ 31 | #pragma once 32 | #ifndef __spoutDirectX__ 33 | #define __spoutDirectX__ 34 | 35 | #include "SpoutCommon.h" 36 | #include 37 | #include 38 | #include 39 | // #include // LJ DEBUG 40 | #include 41 | #include 42 | 43 | #pragma comment (lib, "d3d9.lib") 44 | #pragma comment (lib, "d3d11.lib") 45 | #pragma comment (lib, "DXGI.lib") 46 | 47 | using namespace std; 48 | 49 | class SPOUT_DLLEXP spoutDirectX { 50 | 51 | public: 52 | 53 | spoutDirectX(); 54 | ~spoutDirectX(); 55 | 56 | // DX9 57 | IDirect3D9Ex* CreateDX9object(); // Create a DirectX9 object 58 | IDirect3DDevice9Ex* CreateDX9device(IDirect3D9Ex* pD3D, HWND hWnd); // Create a DirectX9 device 59 | bool CreateSharedDX9Texture(IDirect3DDevice9Ex* pDevice, unsigned int width, unsigned int height, D3DFORMAT format, LPDIRECT3DTEXTURE9 &dxTexture, HANDLE &dxShareHandle); 60 | bool WriteDX9surface(IDirect3DDevice9Ex* pDevice, LPDIRECT3DTEXTURE9 dxTexture, LPDIRECT3DSURFACE9 source_surface); 61 | 62 | // DX11 63 | ID3D11Device* CreateDX11device(); // Create a DX11 device 64 | bool CreateSharedDX11Texture(ID3D11Device* pDevice, unsigned int width, unsigned int height, DXGI_FORMAT format, ID3D11Texture2D** pSharedTexture, HANDLE &dxShareHandle); 65 | bool CreateDX11StagingTexture(ID3D11Device* pDevice, unsigned int width, unsigned int height, DXGI_FORMAT format, ID3D11Texture2D** pStagingTexture); 66 | bool OpenDX11shareHandle(ID3D11Device* pDevice, ID3D11Texture2D** ppSharedTexture, HANDLE dxShareHandle); 67 | 68 | // Output adapter selection 69 | int GetNumAdapters(); // Get the number of graphics adapters in the system 70 | bool GetAdapterName(int index, char *adaptername, int maxchars); // Get an adapter name 71 | bool SetAdapter(int index); // Set required graphics adapter for output 72 | int GetAdapter(); // Get the current adapter index 73 | bool GetAdapterInfo(char *renderdescription, char *displaydescription, int maxchars); 74 | bool FindNVIDIA(int &nAdapter); // Find the index of the NVIDIA adapter in a multi-adapter system 75 | 76 | // Registry read/write - 20.11.15 - moved from interop class 77 | bool ReadDwordFromRegistry(DWORD *pValue, const char *subkey, const char *valuename); 78 | bool WriteDwordToRegistry(DWORD dwValue, const char *subkey, const char *valuename); 79 | 80 | // Mutex locks for shared texture access 81 | bool CreateAccessMutex(const char *name, HANDLE &hAccessMutex); 82 | void CloseAccessMutex(HANDLE &hAccessMutex); 83 | bool CheckAccess(HANDLE hAccessMutex); 84 | void AllowAccess(HANDLE hAccessMutex); 85 | 86 | // For debugging only - to toggle texture access locks disable/enable 87 | bool bUseAccessLocks; 88 | 89 | protected: 90 | 91 | IDXGIAdapter* GetAdapterPointer(int index); // Get adapter pointer for DirectX 11 92 | int g_AdapterIndex; // Used for DX9 93 | IDXGIAdapter* g_pAdapterDX11; 94 | ID3D11DeviceContext* g_pImmediateContext; 95 | D3D_DRIVER_TYPE g_driverType; 96 | D3D_FEATURE_LEVEL g_featureLevel; 97 | 98 | }; 99 | 100 | #endif 101 | -------------------------------------------------------------------------------- /src/SpoutSDK/SpoutGLDXinterop.h: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | spoutGLDXinterop.h 4 | 5 | Functions to manage texture sharing using the NVIDIA GL/DX opengl extensions 6 | 7 | https://www.opengl.org/registry/specs/NV/DX_interop.txt 8 | 9 | 10 | Copyright (c) 2014-2017, Lynn Jarvis. All rights reserved. 11 | 12 | Redistribution and use in source and binary forms, with or without modification, 13 | are permitted provided that the following conditions are met: 14 | 15 | 1. Redistributions of source code must retain the above copyright notice, 16 | this list of conditions and the following disclaimer. 17 | 18 | 2. Redistributions in binary form must reproduce the above copyright notice, 19 | this list of conditions and the following disclaimer in the documentation 20 | and/or other materials provided with the distribution. 21 | 22 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 23 | EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 24 | OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 25 | IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 26 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 27 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 28 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | 32 | */ 33 | #pragma once 34 | #ifndef __spoutGLDXinterop__ // standard way as well 35 | #define __spoutGLDXinterop__ 36 | 37 | #include "SpoutCommon.h" 38 | #include "spoutDirectX.h" 39 | #include "spoutSenderNames.h" 40 | #include "SpoutMemoryShare.h" 41 | #include "spoutCopy.h" 42 | 43 | #include 44 | #include // DX9 45 | #include // DX11 46 | #include 47 | #include // For glerror 48 | #include // for path functions 49 | 50 | #include "spoutGLextensions.h" // include last due to redefinition problems with OpenCL 51 | 52 | 53 | class SPOUT_DLLEXP spoutGLDXinterop { 54 | 55 | public: 56 | 57 | spoutGLDXinterop(); 58 | ~spoutGLDXinterop(); 59 | 60 | // Spout objects 61 | spoutSenderNames senders; // Sender management 62 | spoutDirectX spoutdx; // DirectX functions 63 | spoutCopy spoutcopy; // Memory copy and rgb-rgba conversion functions 64 | spoutMemoryShare memoryshare; // Memory sharing 65 | 66 | // Initialization functions 67 | bool LoadGLextensions(); // Load required opengl extensions 68 | bool CreateInterop(HWND hWnd, const char* sendername, unsigned int width, unsigned int height, DWORD dwFormat, bool bReceive = true); 69 | void CleanupInterop(bool bExit = false); // Cleanup with flag to avoid unknown crash bug 70 | 71 | bool getSharedInfo(char* sharedMemoryName, SharedTextureInfo* info); 72 | bool setSharedInfo(char* sharedMemoryName, SharedTextureInfo* info); 73 | 74 | // Texture functions 75 | bool WriteTexture(GLuint TextureID, GLuint TextureTarget, unsigned int width, unsigned int height, bool bInvert=true, GLuint HostFBO=0); 76 | bool ReadTexture (GLuint TextureID, GLuint TextureTarget, unsigned int width, unsigned int height, bool bInvert=false, GLuint HostFBO=0); 77 | bool WriteTexturePixels(const unsigned char *pixels, unsigned int width, unsigned int height, GLenum glFormat = GL_RGBA, bool bInvert = false, GLuint HostFBO = 0); 78 | bool ReadTexturePixels (unsigned char *pixels, unsigned int width, unsigned int height, GLenum glFormat = GL_RGBA, bool bInvert = false, GLuint HostFBO=0); 79 | bool DrawSharedTexture (float max_x = 1.0, float max_y = 1.0, float aspect = 1.0, bool bInvert = true, GLuint HostFBO = 0); 80 | bool DrawToSharedTexture (GLuint TexID, GLuint TexTarget, 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); 81 | bool BindSharedTexture(); 82 | bool UnBindSharedTexture(); 83 | 84 | // DX11 shared texture write and read 85 | bool WriteTexture(ID3D11Texture2D** texture); 86 | bool ReadTexture (ID3D11Texture2D** texture); 87 | 88 | // PBO functions for external access 89 | bool UnloadTexturePixels(GLuint TextureID, GLuint TextureTarget, 90 | unsigned int width, unsigned int height, 91 | unsigned char *data, GLenum glFormat = GL_RGBA, 92 | bool bInvert = false, GLuint HostFBO = 0); 93 | 94 | bool LoadTexturePixels(GLuint TextureID, GLuint TextureTarget, 95 | unsigned int width, unsigned int height, 96 | const unsigned char *data, GLenum glFormat = GL_RGBA, 97 | bool bInvert = false); 98 | 99 | // DX9 100 | bool m_bUseDX9; // Use DX11 (default) or DX9 101 | bool GetDX9(); 102 | bool SetDX9(bool bDX9); 103 | bool UseDX9(bool bDX9); // Includes DX11 compatibility check 104 | bool isDX9(); // Test for DX11 in case it failed to initialize 105 | 106 | bool m_bUseCPU; // Use CPU texture processing 107 | bool SetCPUmode(bool bCPU = true); 108 | bool GetCPUmode(); 109 | 110 | bool m_bUseMemory; // Use memoryshare 111 | bool SetMemoryShareMode(bool bMem = true); 112 | bool GetMemoryShareMode(); 113 | 114 | int GetShareMode(); // 0 - memory, 1 - cpu, 2 - texture 115 | bool SetShareMode(int mode); 116 | 117 | bool IsBGRAavailable(); // are the bgra extensions available 118 | bool IsPBOavailable(); // Are pbo extensions supported 119 | void SetBufferMode(bool bActive); // Set the pbo availability on or off 120 | bool GetBufferMode(); 121 | 122 | int GetNumAdapters(); // Get the number of graphics adapters in the system 123 | bool GetAdapterName(int index, char *adaptername, int maxchars); // Get an adapter name 124 | bool SetAdapter(int index); // Set required graphics adapter for output 125 | int GetAdapter(); // Get the SpoutDirectX global adapter index 126 | bool GetHostPath(const char *sendername, char *hostpath, int maxchars); // The path of the host that produced the sender 127 | 128 | // DX9 129 | D3DFORMAT DX9format; // the DX9 texture format to be used 130 | void SetDX9format(D3DFORMAT textureformat); 131 | bool CreateDX9interop(unsigned int width, unsigned int height, DWORD dwFormat, bool bReceive = true); 132 | bool OpenDirectX9(HWND hWnd); // Initialize and prepare DirectX9 133 | void CleanupDX9(bool bExit = false); 134 | 135 | // DX11 136 | DXGI_FORMAT DX11format; // the DX11 texture format to be used 137 | void SetDX11format(DXGI_FORMAT textureformat); // set format by user 138 | bool CreateDX11interop(unsigned int width, unsigned int height, DWORD dwFormat, bool bReceive); 139 | bool OpenDirectX11(); // Initialize and prepare DirectX11 140 | bool DX11available(); // Test for DX11 by attempting to open a device 141 | void CleanupDX11(bool bExit = false); 142 | 143 | // Common 144 | bool OpenDirectX(HWND hWnd, bool bDX9); 145 | void CleanupDirectX(bool bExit = false); 146 | HANDLE LinkGLDXtextures(void* pDXdevice, void* pSharedTexture, HANDLE dxShareHandle, GLuint glTextureID); 147 | 148 | // Locks for gl/dx interop functions 149 | HRESULT LockInteropObject(HANDLE hDevice, HANDLE *hObject); 150 | HRESULT UnlockInteropObject(HANDLE hDevice, HANDLE *hObject); 151 | 152 | // Utilities 153 | bool GLDXcompatible(); 154 | bool isOptimus(); 155 | int GetVerticalSync(); 156 | bool SetVerticalSync(bool bSync = true); 157 | bool GetAdapterInfo(char *renderadapter, 158 | char *renderdescription, char *renderversion, 159 | char *displaydescription, char *displayversion, 160 | int maxsize, bool &bUseDX9); 161 | DWORD GetSpoutVersion(); // Get Spout version from the registry - starting at 2.005 162 | 163 | // OpenGL utilities 164 | bool InitOpenGL(); 165 | bool CloseOpenGL(); 166 | bool CopyTexture(GLuint SourceID, GLuint SourceTarget, GLuint DestID, GLuint DestTarget, 167 | unsigned int width, unsigned int height, bool bInvert, GLuint HostFBO); 168 | void InitTexture(GLuint &texID, GLenum GLformat, unsigned int width, unsigned int height); 169 | void CheckOpenGLTexture(GLuint &texID, GLenum GLformat, 170 | unsigned int newWidth, unsigned int newHeight, 171 | unsigned int &texWidth, unsigned int &texHeight); 172 | void SaveOpenGLstate(unsigned int width, unsigned int height, bool bFitWindow = true); 173 | void RestoreOpenGLstate(); 174 | GLuint GetGLtextureID(); // Get OpenGL shared texture ID 175 | void GLerror(); 176 | void PrintFBOstatus(GLenum status); 177 | 178 | GLuint m_glTexture; // the OpenGL texture linked to the shared DX texture 179 | GLuint m_fbo; // General fbo used for texture transfers 180 | 181 | // public for external access 182 | IDirect3DDevice9Ex* m_pDevice; // DX9 device 183 | LPDIRECT3DTEXTURE9 m_dxTexture; // the shared DX9 texture 184 | HANDLE m_dxShareHandle; // the shared DX texture handle 185 | ID3D11Device* g_pd3dDevice; // DX11 device 186 | ID3D11Texture2D* g_pSharedTexture; // The shared DX11 texture 187 | 188 | protected: 189 | 190 | bool m_bInitialized; // this instance initialized flag 191 | bool m_bExtensionsLoaded; // extensions have been loaded 192 | unsigned int m_caps; // extension capabilities 193 | bool m_bFBOavailable; // fbo extensions available 194 | bool m_bBLITavailable; // fbo blit extensions available 195 | bool m_bPBOavailable; // pbo extensions available 196 | bool m_bSWAPavailable; // swap extensions available 197 | bool m_bBGRAavailable; // BGRA extensions are supported 198 | bool m_bGLDXavailable; // GL/DX interop extensions are supported 199 | 200 | HWND m_hWnd; // parent window 201 | HANDLE m_hSharedMemory; // handle to the texture info shared memory 202 | SharedTextureInfo m_TextureInfo; // local texture info structure 203 | 204 | GLuint m_TexID; // Local texture used for memoryshare and CPU functions 205 | unsigned int m_TexWidth; // width and height of local texture 206 | unsigned int m_TexHeight; // height of local texture 207 | 208 | // PBO support 209 | GLuint m_pbo[2]; 210 | int PboIndex; 211 | int NextPboIndex; 212 | 213 | // For InitOpenGL and CloseOpenGL 214 | HDC m_hdc; 215 | HWND m_hwndButton; 216 | HGLRC m_hRc; 217 | 218 | // DX11 219 | ID3D11DeviceContext* g_pImmediateContext; 220 | D3D_DRIVER_TYPE g_driverType; 221 | D3D_FEATURE_LEVEL g_featureLevel; 222 | ID3D11Texture2D* g_pStagingTexture; // A staging texture for CPU access 223 | 224 | // DX9 225 | IDirect3D9Ex* m_pD3D; // DX9 object 226 | LPDIRECT3DSURFACE9 g_DX9surface; // A surface for CPU access 227 | 228 | // Interop 229 | HANDLE m_hInteropDevice; // handle to the DX/GL interop device 230 | HANDLE m_hInteropObject; // handle to the DX/GL interop object (the shared texture) 231 | HANDLE m_hAccessMutex; // Texture access mutex lock handle 232 | 233 | bool getSharedTextureInfo(const char* sharedMemoryName); 234 | bool setSharedTextureInfo(const char* sharedMemoryName); 235 | 236 | // GL/DX interop texture functions 237 | bool WriteGLDXtexture (GLuint TextureID, GLuint TextureTarget, unsigned int width, unsigned int height, bool bInvert=true, GLuint HostFBO=0); 238 | bool ReadGLDXtexture (GLuint TextureID, GLuint TextureTarget, unsigned int width, unsigned int height, bool bInvert=false, GLuint HostFBO=0); 239 | bool WriteGLDXpixels (const unsigned char *pixels, unsigned int width, unsigned int height, GLenum glFormat = GL_RGBA, bool bInvert = false, GLuint HostFBO = 0); 240 | bool ReadGLDXpixels (unsigned char *pixels, unsigned int width, unsigned int height, GLenum glFormat = GL_RGBA, bool bInvert = false, GLuint HostFBO=0); 241 | bool DrawGLDXtexture (float max_x = 1.0, float max_y = 1.0, float aspect = 1.0, bool bInvert = true); 242 | bool DrawToGLDXtexture(GLuint TexID, GLuint TexTarget, 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); 243 | 244 | // DX11 staging texture functions for CPU access 245 | bool WriteDX11texture (GLuint TextureID, GLuint TextureTarget, unsigned int width, unsigned int height, bool bInvert=false, GLuint HostFBO=0); 246 | bool ReadDX11texture (GLuint TextureID, GLuint TextureTarget, unsigned int width, unsigned int height, bool bInvert=false, GLuint HostFBO=0); 247 | bool WriteDX11pixels (const unsigned char *pixels, unsigned int width, unsigned int height, GLenum glFormat = GL_RGBA, bool bInvert=false); 248 | bool ReadDX11pixels (unsigned char *pixels, unsigned int width, unsigned int height, GLenum glFormat = GL_RGBA, bool bInvert=false); 249 | bool DrawDX11texture (float max_x = 1.0, float max_y = 1.0, float aspect = 1.0, bool bInvert = false, GLuint HostFBO=0); 250 | bool DrawToDX11texture(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); 251 | bool CheckStagingTexture(unsigned int width, unsigned int height); 252 | void FlushWait(); 253 | 254 | // DX9 surface functions for CPU access 255 | bool WriteDX9surface (LPDIRECT3DSURFACE9 source_surface); 256 | bool WriteDX9texture (GLuint TextureID, GLuint TextureTarget, unsigned int width, unsigned int height, bool bInvert=false, GLuint HostFBO=0); 257 | bool ReadDX9texture (GLuint TextureID, GLuint TextureTarget, unsigned int width, unsigned int height, bool bInvert=false, GLuint HostFBO=0); 258 | bool WriteDX9pixels (const unsigned char *pixels, unsigned int width, unsigned int height, GLenum glFormat = GL_RGBA, bool bInvert=false); 259 | bool ReadDX9pixels (unsigned char *pixels, unsigned int width, unsigned int height, GLenum glFormat = GL_RGBA, bool bInvert=false); 260 | bool DrawDX9texture (float max_x = 1.0, float max_y = 1.0, float aspect = 1.0, bool bInvert = false, GLuint HostFBO = 0); 261 | bool DrawToDX9texture(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); 262 | bool CheckDX9surface (unsigned int width, unsigned int height); 263 | 264 | // Memoryshare functions 265 | bool WriteMemory (GLuint TexID, GLuint TextureTarget, unsigned int width, unsigned int height, bool bInvert = false, GLuint HostFBO=0); 266 | bool ReadMemory (GLuint TexID, GLuint TextureTarget, unsigned int width, unsigned int height, bool bInvert = false, GLuint HostFBO=0); 267 | bool WriteMemoryPixels (const unsigned char *pixels, unsigned int width, unsigned int height, GLenum glFormat = GL_RGBA, bool bInvert = false); 268 | bool ReadMemoryPixels (unsigned char *pixels, unsigned int width, unsigned int height, GLenum glFormat = GL_RGBA, bool bInvert = false); 269 | bool DrawSharedMemory (float max_x = 1.0, float max_y = 1.0, float aspect = 1.0, bool bInvert = false); 270 | bool DrawToSharedMemory(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); 271 | 272 | // Utility 273 | bool OpenDeviceKey(const char* key, int maxsize, char *description, char *version); 274 | void trim(char * s); 275 | 276 | }; 277 | 278 | #endif 279 | -------------------------------------------------------------------------------- /src/SpoutSDK/SpoutGLextensions.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | // 3 | // 4 | // spoutGLextensions.cpp 5 | // 6 | // Used for load of openGL extensions with option 7 | // to use Glew or disable dynamic load of specific extensions 8 | // See spoutGLext.h 9 | // 10 | // 01.09.15 - added MessageBox error warning in LoadGLextensions 11 | // 11.11.15 - removed (unsigned) cast from GetProcAddress in FBO extensions 12 | // 17.03.16 - added bgra extensions to find out if they are supported at compile and runtime 13 | // 28.03.16 - caps is returned instead of fail for interop extensions 14 | // 29.03.16 - Fixed loadInteropExtensions flag test in loadGLextensions 15 | // 12.08.16 - Removed "isExtensionSupported" (https://github.com/leadedge/Spout2/issues/19) 16 | // 13.01.17 - Removed try/catch from wglDXRegisterObjectNV calls 17 | // - Clean up #ifdefs in all functions - return true if FBO of PBO are defined elsewhere 18 | // 19 | 20 | Copyright (c) 2014-2017, Lynn Jarvis. All rights reserved. 21 | 22 | Redistribution and use in source and binary forms, with or without modification, 23 | are permitted provided that the following conditions are met: 24 | 25 | 1. Redistributions of source code must retain the above copyright notice, 26 | this list of conditions and the following disclaimer. 27 | 28 | 2. Redistributions in binary form must reproduce the above copyright notice, 29 | this list of conditions and the following disclaimer in the documentation 30 | and/or other materials provided with the distribution. 31 | 32 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 33 | EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 34 | OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 35 | IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 36 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 37 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 38 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 39 | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 40 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 41 | */ 42 | 43 | #include "spoutGLextensions.h" 44 | 45 | #ifndef USE_GLEW 46 | 47 | // GL/DX extensions 48 | PFNWGLDXOPENDEVICENVPROC wglDXOpenDeviceNV = NULL; 49 | PFNWGLDXREGISTEROBJECTNVPROC wglDXRegisterObjectNV = NULL; 50 | PFNWGLDXSETRESOURCESHAREHANDLENVPROC wglDXSetResourceShareHandleNV = NULL; 51 | PFNWGLDXLOCKOBJECTSNVPROC wglDXLockObjectsNV = NULL; 52 | PFNWGLDXUNLOCKOBJECTSNVPROC wglDXUnlockObjectsNV = NULL; 53 | PFNWGLDXCLOSEDEVICENVPROC wglDXCloseDeviceNV = NULL; 54 | PFNWGLDXUNREGISTEROBJECTNVPROC wglDXUnregisterObjectNV = NULL; 55 | 56 | // FBO extensions 57 | #ifdef USE_FBO_EXTENSIONS 58 | glBindFramebufferEXTPROC glBindFramebufferEXT = NULL; 59 | glBindRenderbufferEXTPROC glBindRenderbufferEXT = NULL; 60 | glCheckFramebufferStatusEXTPROC glCheckFramebufferStatusEXT = NULL; 61 | glDeleteFramebuffersEXTPROC glDeleteFramebuffersEXT = NULL; 62 | glDeleteRenderBuffersEXTPROC glDeleteRenderBuffersEXT = NULL; 63 | glFramebufferRenderbufferEXTPROC glFramebufferRenderbufferEXT = NULL; 64 | glFramebufferTexture1DEXTPROC glFramebufferTexture1DEXT = NULL; 65 | glFramebufferTexture2DEXTPROC glFramebufferTexture2DEXT = NULL; 66 | glFramebufferTexture3DEXTPROC glFramebufferTexture3DEXT = NULL; 67 | glGenFramebuffersEXTPROC glGenFramebuffersEXT = NULL; 68 | glGenRenderbuffersEXTPROC glGenRenderbuffersEXT = NULL; 69 | glGenerateMipmapEXTPROC glGenerateMipmapEXT = NULL; 70 | glGetFramebufferAttachmentParameterivEXTPROC glGetFramebufferAttachmentParameterivEXT = NULL; 71 | glGetRenderbufferParameterivEXTPROC glGetRenderbufferParameterivEXT = NULL; 72 | glIsFramebufferEXTPROC glIsFramebufferEXT = NULL; 73 | glIsRenderbufferEXTPROC glIsRenderbufferEXT = NULL; 74 | glRenderbufferStorageEXTPROC glRenderbufferStorageEXT = NULL; 75 | #endif 76 | 77 | // FBO blit extensions 78 | glBlitFramebufferEXTPROC glBlitFramebufferEXT = NULL; 79 | 80 | #ifdef USE_FBO_EXTENSIONS 81 | // OpenGL sync control extensions 82 | PFNWGLSWAPINTERVALEXTPROC wglSwapIntervalEXT = NULL; 83 | PFNWGLGETSWAPINTERVALEXTPROC wglGetSwapIntervalEXT = NULL; 84 | #endif 85 | 86 | // PBO extensions 87 | #ifdef USE_PBO_EXTENSIONS 88 | glGenBuffersPROC glGenBuffersEXT = NULL; 89 | glDeleteBuffersPROC glDeleteBuffersEXT = NULL; 90 | glBindBufferPROC glBindBufferEXT = NULL; 91 | glBufferDataPROC glBufferDataEXT = NULL; 92 | glMapBufferPROC glMapBufferEXT = NULL; 93 | glUnmapBufferPROC glUnmapBufferEXT = NULL; 94 | #endif 95 | 96 | #endif 97 | 98 | // 99 | // Load the Nvidia-Extensions dynamically 100 | // 101 | bool loadInteropExtensions() { 102 | 103 | #ifdef USE_GLEW 104 | if(WGLEW_NV_DX_interop) 105 | return true; 106 | else 107 | return false; 108 | #else 109 | wglDXOpenDeviceNV = (PFNWGLDXOPENDEVICENVPROC)wglGetProcAddress("wglDXOpenDeviceNV"); 110 | if(!wglDXOpenDeviceNV) { 111 | return false; 112 | } 113 | wglDXRegisterObjectNV = (PFNWGLDXREGISTEROBJECTNVPROC)wglGetProcAddress("wglDXRegisterObjectNV"); 114 | if(!wglDXRegisterObjectNV) { 115 | return false; 116 | } 117 | wglDXUnregisterObjectNV = (PFNWGLDXUNREGISTEROBJECTNVPROC)wglGetProcAddress("wglDXUnregisterObjectNV"); 118 | if(!wglDXUnregisterObjectNV) { 119 | return false; 120 | } 121 | wglDXSetResourceShareHandleNV = (PFNWGLDXSETRESOURCESHAREHANDLENVPROC)wglGetProcAddress("wglDXSetResourceShareHandleNV"); 122 | if(!wglDXSetResourceShareHandleNV) { 123 | return false; 124 | } 125 | wglDXLockObjectsNV = (PFNWGLDXLOCKOBJECTSNVPROC)wglGetProcAddress("wglDXLockObjectsNV"); 126 | if(!wglDXLockObjectsNV) { 127 | return false; 128 | } 129 | wglDXUnlockObjectsNV = (PFNWGLDXUNLOCKOBJECTSNVPROC)wglGetProcAddress("wglDXUnlockObjectsNV"); 130 | if(!wglDXUnlockObjectsNV) { 131 | return false; 132 | } 133 | wglDXCloseDeviceNV = (PFNWGLDXCLOSEDEVICENVPROC)wglGetProcAddress("wglDXCloseDeviceNV"); 134 | if(!wglDXUnlockObjectsNV) { 135 | return false; 136 | } 137 | 138 | return true; 139 | #endif 140 | 141 | } 142 | 143 | bool loadFBOextensions() { 144 | 145 | #ifdef USE_FBO_EXTENSIONS 146 | 147 | #ifdef USE_GLEW 148 | if(GLEW_EXT_framebuffer_object) 149 | return true; 150 | else 151 | return false; 152 | #else 153 | glBindFramebufferEXT = (glBindFramebufferEXTPROC)wglGetProcAddress("glBindFramebufferEXT"); 154 | glBindRenderbufferEXT = (glBindRenderbufferEXTPROC)wglGetProcAddress("glBindRenderbufferEXT"); 155 | glCheckFramebufferStatusEXT = (glCheckFramebufferStatusEXTPROC)wglGetProcAddress("glCheckFramebufferStatusEXT"); 156 | glDeleteFramebuffersEXT = (glDeleteFramebuffersEXTPROC)wglGetProcAddress("glDeleteFramebuffersEXT"); 157 | glDeleteRenderBuffersEXT = (glDeleteRenderBuffersEXTPROC)wglGetProcAddress("glDeleteRenderbuffersEXT"); 158 | glFramebufferRenderbufferEXT = (glFramebufferRenderbufferEXTPROC)wglGetProcAddress("glFramebufferRenderbufferEXT"); 159 | glFramebufferTexture1DEXT = (glFramebufferTexture1DEXTPROC)wglGetProcAddress("glFramebufferTexture1DEXT"); 160 | glFramebufferTexture2DEXT = (glFramebufferTexture2DEXTPROC)wglGetProcAddress("glFramebufferTexture2DEXT"); 161 | glFramebufferTexture3DEXT = (glFramebufferTexture3DEXTPROC)wglGetProcAddress("glFramebufferTexture3DEXT"); 162 | glGenFramebuffersEXT = (glGenFramebuffersEXTPROC)wglGetProcAddress("glGenFramebuffersEXT"); 163 | glGenRenderbuffersEXT = (glGenRenderbuffersEXTPROC)wglGetProcAddress("glGenRenderbuffersEXT"); 164 | glGenerateMipmapEXT = (glGenerateMipmapEXTPROC)wglGetProcAddress("glGenerateMipmapEXT"); 165 | glGetFramebufferAttachmentParameterivEXT = (glGetFramebufferAttachmentParameterivEXTPROC)wglGetProcAddress("glGetFramebufferAttachmentParameterivEXT"); 166 | glGetRenderbufferParameterivEXT = (glGetRenderbufferParameterivEXTPROC)wglGetProcAddress("glGetRenderbufferParameterivEXT"); 167 | glIsFramebufferEXT = (glIsFramebufferEXTPROC)wglGetProcAddress("glIsFramebufferEXT"); 168 | glIsRenderbufferEXT = (glIsRenderbufferEXTPROC)wglGetProcAddress("glIsRenderbufferEXT"); 169 | glRenderbufferStorageEXT = (glRenderbufferStorageEXTPROC)wglGetProcAddress("glRenderbufferStorageEXT"); 170 | 171 | if ( glBindFramebufferEXT != NULL && 172 | glBindRenderbufferEXT != NULL && 173 | glCheckFramebufferStatusEXT != NULL && 174 | glDeleteFramebuffersEXT != NULL && 175 | glDeleteRenderBuffersEXT != NULL && 176 | glFramebufferRenderbufferEXT != NULL && 177 | glFramebufferTexture1DEXT != NULL && 178 | glFramebufferTexture2DEXT != NULL && 179 | glFramebufferTexture3DEXT != NULL && 180 | glGenFramebuffersEXT != NULL && 181 | glGenRenderbuffersEXT != NULL && 182 | glGenerateMipmapEXT != NULL && 183 | glGetFramebufferAttachmentParameterivEXT != NULL && 184 | glGetRenderbufferParameterivEXT != NULL && 185 | glIsFramebufferEXT != NULL && 186 | glIsRenderbufferEXT != NULL && 187 | glRenderbufferStorageEXT != NULL) { 188 | return true; 189 | } 190 | else { 191 | return false; 192 | } 193 | #endif 194 | #else 195 | // FBO extensions defined elsewhere 196 | return true; 197 | #endif 198 | } 199 | 200 | 201 | bool loadBLITextension() { 202 | 203 | #ifdef USE_GLEW 204 | if(GLEW_EXT_framebuffer_blit) 205 | return true; 206 | else 207 | return false; 208 | #else 209 | glBlitFramebufferEXT = (glBlitFramebufferEXTPROC) wglGetProcAddress("glBlitFramebufferEXT"); 210 | return glBlitFramebufferEXT!=NULL; 211 | #endif 212 | 213 | } 214 | 215 | bool loadSwapExtensions() 216 | { 217 | wglSwapIntervalEXT = (PFNWGLSWAPINTERVALEXTPROC)wglGetProcAddress("wglSwapIntervalEXT"); 218 | wglGetSwapIntervalEXT = (PFNWGLGETSWAPINTERVALEXTPROC)wglGetProcAddress("wglGetSwapIntervalEXT"); 219 | if(wglSwapIntervalEXT == NULL || wglGetSwapIntervalEXT == NULL) { 220 | return false; 221 | } 222 | 223 | return true; 224 | 225 | } 226 | 227 | 228 | // =================== PBO support 18.01.14 ================== 229 | bool loadPBOextensions() 230 | { 231 | 232 | #ifdef USE_PBO_EXTENSIONS 233 | 234 | #ifdef USE_GLEW 235 | if(glGenBuffersARB) 236 | return true; 237 | else 238 | return false; 239 | #else 240 | glGenBuffersEXT = (glGenBuffersPROC)wglGetProcAddress("glGenBuffers"); 241 | glDeleteBuffersEXT = (glDeleteBuffersPROC)wglGetProcAddress("glDeleteBuffers"); 242 | glBindBufferEXT = (glBindBufferPROC)wglGetProcAddress("glBindBuffer"); 243 | glBufferDataEXT = (glBufferDataPROC)wglGetProcAddress("glBufferData"); 244 | glMapBufferEXT = (glMapBufferPROC)wglGetProcAddress("glMapBuffer"); 245 | glUnmapBufferEXT = (glUnmapBufferPROC)wglGetProcAddress("glUnmapBuffer"); 246 | 247 | if(glGenBuffersEXT != NULL && glDeleteBuffersEXT != NULL 248 | && glBindBufferEXT != NULL && glBufferDataEXT != NULL 249 | && glMapBufferEXT != NULL && glUnmapBufferEXT != NULL) { 250 | return true; 251 | } 252 | else { 253 | return false; 254 | } 255 | #endif 256 | 257 | #else 258 | // PBO extensions defined elsewhere 259 | return true; 260 | #endif 261 | } 262 | 263 | 264 | 265 | bool InitializeGlew() 266 | { 267 | #ifdef USE_GLEW 268 | HGLRC glContext; 269 | GLenum glew_error; 270 | 271 | // Opengl context is necessary 272 | glContext = wglGetCurrentContext(); 273 | if(glContext == NULL) { 274 | return false; 275 | } 276 | // 277 | // Note from Glew : GLEW obtains information on the supported extensions from the graphics driver. 278 | // Experimental or pre-release drivers, however, might not report every available extension through 279 | // the standard mechanism, in which case GLEW will report it unsupported. To circumvent this situation, 280 | // the glewExperimental global switch can be turned on by setting it to GL_TRUE before calling glewInit(), 281 | // which ensures that all extensions with valid entry points will be exposed. 282 | // 283 | glewExperimental = GL_TRUE; 284 | glew_error = glewInit(); 285 | if (glew_error != GLEW_OK) { 286 | return false; 287 | } 288 | // 289 | // Glew should have loaded all the extensions and we can check for them 290 | // 291 | // http://glew.sourceforge.net/basic.html 292 | // 293 | return true; 294 | #else 295 | // Glew usage not defined so cannot initialize 296 | return false; 297 | #endif 298 | } 299 | 300 | // 301 | // Load GL extensions 302 | // 303 | unsigned int loadGLextensions() { 304 | 305 | unsigned int caps = 0; // as per elio glextensions 306 | 307 | // printf("loadGLextensions\n"); 308 | 309 | #ifdef USE_GLEW 310 | InitializeGlew(); // probably needs failure check 311 | #endif 312 | 313 | // Check for FBO extensions first - no use continuing without them 314 | if(!loadFBOextensions()) { 315 | printf(" loadFBOextensions fail\n"); 316 | return 0; 317 | } 318 | 319 | caps |= GLEXT_SUPPORT_FBO; 320 | 321 | // Load PBO extension and FBO blit extension 322 | if(loadBLITextension()) { 323 | caps |= GLEXT_SUPPORT_FBO_BLIT; 324 | } 325 | 326 | if(loadSwapExtensions()) { 327 | caps |= GLEXT_SUPPORT_SWAP; 328 | } 329 | 330 | if(loadPBOextensions()) { 331 | caps |= GLEXT_SUPPORT_PBO; 332 | } 333 | 334 | // Find out whether bgra extensions are supported at compile and runtime 335 | #ifdef GL_EXT_bgra 336 | // 337 | // "isExtensionSupported" code yet to be fully tested for 338 | // various compilers, operating systems and environments. 339 | // Activate this code if you are confident that it works OK. 340 | // 341 | // if(isExtensionSupported("GL_EXT_bgra")) { 342 | caps |= GLEXT_SUPPORT_BGRA; 343 | // } 344 | #endif 345 | 346 | // Load wgl interop extensions - not needed for memoryshare 347 | if (loadInteropExtensions()) { 348 | caps |= GLEXT_SUPPORT_NVINTEROP; 349 | } 350 | 351 | return caps; 352 | 353 | } 354 | 355 | 356 | // 357 | // Used to determine support for GL_EXT_bgra extensions 358 | // Currently not used 359 | /* 360 | bool isExtensionSupported(const char *extension) 361 | { 362 | const char * extensionsstr = NULL; 363 | const char * versionstr = NULL; 364 | const char * start; 365 | const char * exc; 366 | char *where, *terminator; 367 | int n, i; 368 | 369 | // Extension names should not have spaces. 370 | where = (char *)strchr(extension, ' '); 371 | if (where || *extension == '\0') 372 | return false; 373 | 374 | versionstr = (const char *)glGetString(GL_VERSION); 375 | // printf("OpenGL version (%s)\n", versionstr); 376 | 377 | extensionsstr = (const char *)glGetString(GL_EXTENSIONS); 378 | 379 | #ifndef GL_NUM_EXTENSIONS 380 | #define GL_NUM_EXTENSIONS 0x821D // in gl3.h 381 | #endif 382 | 383 | if(extensionsstr == NULL) { 384 | 385 | // printf("glGetString(GL_VERSION) not supported\n"); 386 | 387 | // 388 | // glGetstring not supported 389 | // 390 | // Code adapted from : https://bitbucket.org/Coin3D/coin/issues/54/support-for-opengl-3x-specifically 391 | // 392 | 393 | typedef GLubyte* (APIENTRY * COIN_PFNGLGETSTRINGIPROC)(GLenum enm, GLuint idx); 394 | COIN_PFNGLGETSTRINGIPROC glGetStringi = 0; 395 | glGetStringi = (COIN_PFNGLGETSTRINGIPROC)wglGetProcAddress("glGetStringi"); 396 | if(glGetStringi != NULL) { 397 | glGetIntegerv(GL_NUM_EXTENSIONS, &n); 398 | // printf("%d extensions\n", n); 399 | if(n > 0) { 400 | for (i = 0; i < n; i++) { 401 | exc = (const char *)glGetStringi(GL_EXTENSIONS, i); 402 | if(strcmp(exc, extension) == 0) { 403 | break; 404 | } 405 | } 406 | if(i < n) { 407 | // printf("glGetStringi(%d) %s found\n", i, exc); 408 | return true; 409 | } 410 | } 411 | else { 412 | // printf("glGetIntegerv(GL_NUM_EXTENSIONS) did not return a value\nso unable to get extensions for this gl driver\n"); 413 | } 414 | } 415 | else { 416 | // printf("glGetString(GL_EXTENSIONS) returned null, but glGetStringi is NULL,\nso unable to get extensions for this gl driver\n"); 417 | } 418 | } 419 | else { 420 | 421 | // printf("glGetString(GL_VERSION) supported\n"); 422 | 423 | // 424 | // glGetString supported 425 | // 426 | // Code adapted from : ftp://ftp.sgi.com/opengl/contrib/blythe/advanced99/notes/node395.html 427 | // 428 | 429 | // It takes a bit of care to be fool-proof about parsing the 430 | // OpenGL extensions string. Don't be fooled by sub-strings, etc. 431 | start = extensionsstr; 432 | for (;;) { 433 | where = (char *)strstr((const char *)start, extension); 434 | if (!where) 435 | break; 436 | terminator = where + strlen(extension); 437 | if (where == start || *(where - 1) == ' ') { 438 | if (*terminator == ' ' || *terminator == '\0') { 439 | *terminator = '\0'; 440 | // printf("Extension %s found\n", where); 441 | return true; 442 | } 443 | } 444 | start = terminator; 445 | } 446 | } 447 | 448 | return false; 449 | 450 | } 451 | */ 452 | -------------------------------------------------------------------------------- /src/SpoutSDK/SpoutGLextensions.h: -------------------------------------------------------------------------------- 1 | // 2 | // 3 | // spoutGLextensions.h 4 | // 5 | // Used for load of openGL extensions with options to 6 | // use Glew or disable dynamic load of specific extension types 7 | // 8 | // If Glew is used, none of the extensions are loaded dynamically. 9 | // Individual extension types can be disabled if they conflict 10 | // with extensions already managed by particular applications. 11 | // 12 | // NVIDIA GL/DX interop extensions 13 | // Fbo extensions 14 | // Fbo blit extensions 15 | // Pbo extensions 16 | // wglSwapInterval extensions 17 | // 18 | // Spout project FBO PBO GLEW SWAP BLIT GLDX 19 | // FFGL - SpoutReceiver, SpoutSender - - - + + + 20 | // MAX - jit.gl.spoutsender, jit.gl.spoutreceiver - - - + + + 21 | // PROCESSING - Jspout JNI dll + - - + + + 22 | // SpoutCam + - - + + + 23 | // SpoutPanel + - - + + + 24 | // Spout dll + + - + + + 25 | // WinSpout + - - + + + 26 | // OpenFrameWorks + - - + + + 27 | // Cinder + - - + + + 28 | // 29 | // 03.11.14 - added additional defines for framebuffer status checks 30 | // 02.01.15 - added GL_BGR for SpoutCam 31 | // 32 | /* 33 | 34 | Copyright (c) 2014-2017, Lynn Jarvis. All rights reserved. 35 | 36 | Redistribution and use in source and binary forms, with or without modification, 37 | are permitted provided that the following conditions are met: 38 | 39 | 1. Redistributions of source code must retain the above copyright notice, 40 | this list of conditions and the following disclaimer. 41 | 42 | 2. Redistributions in binary form must reproduce the above copyright notice, 43 | this list of conditions and the following disclaimer in the documentation 44 | and/or other materials provided with the distribution. 45 | 46 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 47 | EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 48 | OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 49 | IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 50 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 51 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 52 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 53 | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 54 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 55 | */ 56 | #pragma once 57 | #ifndef __spoutGLextensions__ // standard way as well 58 | #define __spoutGLextensions__ 59 | 60 | // set this to use GLEW instead of dynamic load of extensions 61 | // #define USE_GLEW 62 | // set this to use glew32s.lib instead of glew32.lib 63 | // #define GLEW_STATIC 64 | 65 | // *** Load of FBO extensions conflicts with FFGL or Jitter, disable them here *** 66 | #define USE_FBO_EXTENSIONS // don't use for jitter 67 | 68 | // If load of PBO extensions conflicts, disable them here - OK for Jitter 69 | #define USE_PBO_EXTENSIONS 70 | 71 | #include 72 | #include // for debug print 73 | #ifdef USE_GLEW 74 | #include 75 | #include // wglew.h and glxew.h, which define the available WGL and GLX extensions 76 | #else 77 | #include 78 | #ifndef USE_FBO_EXTENSIONS 79 | // For Max/Msp Jitter 80 | #include "jit.gl.h" 81 | #define glDeleteFramebuffersEXT (_jit_gl_get_proctable()->DeleteFramebuffersEXT) 82 | #endif 83 | #endif 84 | 85 | #ifndef GL_CLAMP_TO_EDGE 86 | #define GL_CLAMP_TO_EDGE 0x812F 87 | #endif 88 | 89 | #ifndef GL_READ_FRAMEBUFFER_EXT 90 | #define GL_READ_FRAMEBUFFER_EXT 0x8CA8 91 | #endif 92 | 93 | #ifndef GL_DRAW_FRAMEBUFFER_EXT 94 | #define GL_DRAW_FRAMEBUFFER_EXT 0x8CA9 95 | #endif 96 | 97 | #ifndef GL_DRAW_FRAMEBUFFER_BINDING_EXT 98 | #define GL_DRAW_FRAMEBUFFER_BINDING_EXT 0x8CA6 99 | #endif 100 | 101 | #ifndef GL_READ_FRAMEBUFFER_BINDING_EXT 102 | #define GL_READ_FRAMEBUFFER_BINDING_EXT 0x8CAA 103 | #endif 104 | 105 | #ifndef GL_INVALID_FRAMEBUFFER_OPERATION_EXT 106 | #define GL_INVALID_FRAMEBUFFER_OPERATION_EXT 0x0506 107 | #endif 108 | 109 | //------------------------------------ 110 | // EXTENSION SUPPORT FLAGS 111 | //------------------------------------ 112 | #define GLEXT_SUPPORT_NVINTEROP 1 113 | #define GLEXT_SUPPORT_FBO 2 114 | #define GLEXT_SUPPORT_FBO_BLIT 4 115 | #define GLEXT_SUPPORT_PBO 8 116 | #define GLEXT_SUPPORT_SWAP 16 117 | #define GLEXT_SUPPORT_BGRA 32 118 | 119 | //----------------------------------------------------- 120 | // GL consts that are needed and aren't present in GL.h 121 | //----------------------------------------------------- 122 | #define GL_TEXTURE_2D_MULTISAMPLE 0x9100 123 | #define WGL_ACCESS_READ_ONLY_NV 0x0000 124 | #define WGL_ACCESS_READ_WRITE_NV 0x0001 125 | #define WGL_ACCESS_WRITE_DISCARD_NV 0x0002 126 | 127 | #define GL_CLAMP_TO_EDGE 0x812F 128 | 129 | #ifndef USE_GLEW 130 | 131 | // ---------------------------- 132 | // Memory management extensions 133 | // ---------------------------- 134 | #define GL_GPU_MEM_INFO_TOTAL_AVAILABLE_MEM_NVX 0x9048 135 | #define GL_GPU_MEM_INFO_CURRENT_AVAILABLE_MEM_NVX 0x9049 136 | 137 | 138 | //---------------------- 139 | // GL interop extensions 140 | //---------------------- 141 | typedef HANDLE (WINAPI * PFNWGLDXOPENDEVICENVPROC) (void* dxDevice); 142 | typedef BOOL (WINAPI * PFNWGLDXCLOSEDEVICENVPROC) (HANDLE hDevice); 143 | typedef HANDLE (WINAPI * PFNWGLDXREGISTEROBJECTNVPROC) (HANDLE hDevice, void* dxObject, GLuint name, GLenum type, GLenum access); 144 | typedef BOOL (WINAPI * PFNWGLDXUNREGISTEROBJECTNVPROC) (HANDLE hDevice, HANDLE hObject); 145 | typedef BOOL (WINAPI * PFNWGLDXSETRESOURCESHAREHANDLENVPROC) (void *dxResource, HANDLE shareHandle); 146 | typedef BOOL (WINAPI * PFNWGLDXLOCKOBJECTSNVPROC) (HANDLE hDevice, GLint count, HANDLE *hObjects); 147 | typedef BOOL (WINAPI * PFNWGLDXUNLOCKOBJECTSNVPROC) (HANDLE hDevice, GLint count, HANDLE *hObjects); 148 | 149 | extern PFNWGLDXOPENDEVICENVPROC wglDXOpenDeviceNV; 150 | extern PFNWGLDXCLOSEDEVICENVPROC wglDXCloseDeviceNV; 151 | extern PFNWGLDXREGISTEROBJECTNVPROC wglDXRegisterObjectNV; 152 | extern PFNWGLDXUNREGISTEROBJECTNVPROC wglDXUnregisterObjectNV; 153 | extern PFNWGLDXSETRESOURCESHAREHANDLENVPROC wglDXSetResourceShareHandleNV; 154 | extern PFNWGLDXLOCKOBJECTSNVPROC wglDXLockObjectsNV; 155 | extern PFNWGLDXUNLOCKOBJECTSNVPROC wglDXUnlockObjectsNV; 156 | 157 | 158 | //--------------- 159 | // FBO extensions 160 | //--------------- 161 | #ifdef USE_FBO_EXTENSIONS 162 | #define GL_INVALID_FRAMEBUFFER_OPERATION_EXT 0x0506 163 | #define GL_FRAMEBUFFER_UNDEFINED_EXT 0x8219 164 | #define GL_MAX_RENDERBUFFER_SIZE_EXT 0x84E8 165 | #define GL_FRAMEBUFFER_BINDING_EXT 0x8CA6 166 | #define GL_RENDERBUFFER_BINDING_EXT 0x8CA7 167 | #define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT 0x8CD0 168 | #define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT 0x8CD1 169 | #define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_EXT 0x8CD2 170 | #define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE_EXT 0x8CD3 171 | #define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_EXT 0x8CD4 172 | #define GL_FRAMEBUFFER_COMPLETE_EXT 0x8CD5 173 | #define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT 0x8CD6 174 | #define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT 0x8CD7 175 | #define GL_FRAMEBUFFER_INCOMPLETE_DUPLICATE_ATTACHMENT_EXT 0x8CD8 176 | #define GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT 0x8CD9 177 | #define GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT 0x8CDA 178 | #define GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT 0x8CDB 179 | #define GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT 0x8CDC 180 | #define GL_FRAMEBUFFER_UNSUPPORTED_EXT 0x8CDD 181 | #define GL_FRAMEBUFFER_STATUS_ERROR_EXT 0x8CDE 182 | #define GL_MAX_COLOR_ATTACHMENTS_EXT 0x8CDF 183 | #define GL_COLOR_ATTACHMENT0_EXT 0x8CE0 184 | #define GL_COLOR_ATTACHMENT1_EXT 0x8CE1 185 | #define GL_COLOR_ATTACHMENT2_EXT 0x8CE2 186 | #define GL_COLOR_ATTACHMENT3_EXT 0x8CE3 187 | #define GL_COLOR_ATTACHMENT4_EXT 0x8CE4 188 | #define GL_COLOR_ATTACHMENT5_EXT 0x8CE5 189 | #define GL_COLOR_ATTACHMENT6_EXT 0x8CE6 190 | #define GL_COLOR_ATTACHMENT7_EXT 0x8CE7 191 | #define GL_COLOR_ATTACHMENT8_EXT 0x8CE8 192 | #define GL_COLOR_ATTACHMENT9_EXT 0x8CE9 193 | #define GL_COLOR_ATTACHMENT10_EXT 0x8CEA 194 | #define GL_COLOR_ATTACHMENT11_EXT 0x8CEB 195 | #define GL_COLOR_ATTACHMENT12_EXT 0x8CEC 196 | #define GL_COLOR_ATTACHMENT13_EXT 0x8CED 197 | #define GL_COLOR_ATTACHMENT14_EXT 0x8CEE 198 | #define GL_COLOR_ATTACHMENT15_EXT 0x8CEF 199 | #define GL_DEPTH_ATTACHMENT_EXT 0x8D00 200 | #define GL_STENCIL_ATTACHMENT_EXT 0x8D20 201 | #define GL_FRAMEBUFFER_EXT 0x8D40 202 | #define GL_RENDERBUFFER_EXT 0x8D41 203 | #define GL_RENDERBUFFER_WIDTH_EXT 0x8D42 204 | #define GL_RENDERBUFFER_HEIGHT_EXT 0x8D43 205 | #define GL_RENDERBUFFER_INTERNAL_FORMAT_EXT 0x8D44 206 | #define GL_STENCIL_INDEX_EXT 0x8D45 207 | #define GL_STENCIL_INDEX1_EXT 0x8D46 208 | #define GL_STENCIL_INDEX4_EXT 0x8D47 209 | #define GL_STENCIL_INDEX8_EXT 0x8D48 210 | #define GL_STENCIL_INDEX16_EXT 0x8D49 211 | #define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT 0x8D56 212 | #define GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_EXT 0x8DA8 213 | 214 | typedef void (APIENTRY *glBindFramebufferEXTPROC) (GLenum target, GLuint framebuffer); 215 | typedef void (APIENTRY *glBindRenderbufferEXTPROC) (GLenum target, GLuint renderbuffer); 216 | typedef GLenum (APIENTRY *glCheckFramebufferStatusEXTPROC) (GLenum target); 217 | typedef void (APIENTRY *glDeleteFramebuffersEXTPROC) (GLsizei n, const GLuint* framebuffers); 218 | typedef void (APIENTRY *glDeleteRenderBuffersEXTPROC) (GLsizei n, const GLuint* renderbuffers); 219 | typedef void (APIENTRY *glFramebufferRenderbufferEXTPROC) (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); 220 | typedef void (APIENTRY *glFramebufferTexture1DEXTPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); 221 | typedef void (APIENTRY *glFramebufferTexture2DEXTPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); 222 | typedef void (APIENTRY *glFramebufferTexture3DEXTPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset); 223 | typedef void (APIENTRY *glGenFramebuffersEXTPROC) (GLsizei n, GLuint* framebuffers); 224 | typedef void (APIENTRY *glGenRenderbuffersEXTPROC) (GLsizei n, GLuint* renderbuffers); 225 | typedef void (APIENTRY *glGenerateMipmapEXTPROC) (GLenum target); 226 | typedef void (APIENTRY *glGetFramebufferAttachmentParameterivEXTPROC) (GLenum target, GLenum attachment, GLenum pname, GLint* params); 227 | typedef void (APIENTRY *glGetRenderbufferParameterivEXTPROC) (GLenum target, GLenum pname, GLint* params); 228 | typedef GLboolean (APIENTRY *glIsFramebufferEXTPROC) (GLuint framebuffer); 229 | typedef GLboolean (APIENTRY *glIsRenderbufferEXTPROC) (GLuint renderbuffer); 230 | typedef void (APIENTRY *glRenderbufferStorageEXTPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height); 231 | 232 | extern glBindFramebufferEXTPROC glBindFramebufferEXT; 233 | extern glBindRenderbufferEXTPROC glBindRenderbufferEXT; 234 | extern glCheckFramebufferStatusEXTPROC glCheckFramebufferStatusEXT; 235 | extern glDeleteFramebuffersEXTPROC glDeleteFramebuffersEXT; 236 | extern glDeleteRenderBuffersEXTPROC glDeleteRenderBuffersEXT; 237 | extern glFramebufferRenderbufferEXTPROC glFramebufferRenderbufferEXT; 238 | extern glFramebufferTexture1DEXTPROC glFramebufferTexture1DEXT; 239 | extern glFramebufferTexture2DEXTPROC glFramebufferTexture2DEXT; 240 | extern glFramebufferTexture3DEXTPROC glFramebufferTexture3DEXT; 241 | extern glGenFramebuffersEXTPROC glGenFramebuffersEXT; 242 | extern glGenRenderbuffersEXTPROC glGenRenderbuffersEXT; 243 | extern glGenerateMipmapEXTPROC glGenerateMipmapEXT; 244 | extern glGetFramebufferAttachmentParameterivEXTPROC glGetFramebufferAttachmentParameterivEXT; 245 | extern glGetRenderbufferParameterivEXTPROC glGetRenderbufferParameterivEXT; 246 | extern glIsFramebufferEXTPROC glIsFramebufferEXT; 247 | extern glIsRenderbufferEXTPROC glIsRenderbufferEXT; 248 | extern glRenderbufferStorageEXTPROC glRenderbufferStorageEXT; 249 | #endif 250 | 251 | //------------------- 252 | // Blit FBO extension 253 | //------------------- 254 | #define READ_FRAMEBUFFER_EXT 0x8CA8 255 | #define DRAW_FRAMEBUFFER_EXT 0x8CA9 256 | 257 | typedef void (APIENTRY *glBlitFramebufferEXTPROC) (GLint srcX0,GLint srcY0,GLint srcX1,GLint srcY1,GLint dstX0,GLint dstY0,GLint dstX1,GLint dstY1,GLbitfield mask,GLenum filter); 258 | extern glBlitFramebufferEXTPROC glBlitFramebufferEXT; 259 | 260 | 261 | // ------------------------------ 262 | // OpenGL sync control extensions 263 | // ------------------------------ 264 | #ifdef USE_FBO_EXTENSIONS 265 | typedef BOOL (WINAPI * PFNWGLSWAPINTERVALEXTPROC) (int interval); 266 | typedef int (WINAPI * PFNWGLGETSWAPINTERVALEXTPROC) (void); 267 | extern PFNWGLSWAPINTERVALEXTPROC wglSwapIntervalEXT; 268 | extern PFNWGLGETSWAPINTERVALEXTPROC wglGetSwapIntervalEXT; 269 | #endif 270 | 271 | //---------------- 272 | // PBO extensions 273 | //---------------- 274 | #ifdef USE_PBO_EXTENSIONS 275 | #define GL_PIXEL_PACK_BUFFER 0x88EB 276 | #define GL_PIXEL_UNPACK_BUFFER 0x88EC 277 | #define GL_PIXEL_PACK_BUFFER_BINDING 0x88ED 278 | #define GL_PIXEL_UNPACK_BUFFER_BINDING 0x88EF 279 | #define GL_STREAM_DRAW 0x88E0 280 | #define GL_STREAM_READ 0x88E1 281 | #define GL_READ_ONLY 0x88B8 282 | #define GL_WRITE_ONLY 0x88B9 283 | 284 | 285 | // PBO functions 286 | typedef ptrdiff_t GLsizeiptr; 287 | typedef void (APIENTRY *glGenBuffersPROC) (GLsizei n, const GLuint* buffers); 288 | typedef void (APIENTRY *glDeleteBuffersPROC) (GLsizei n, const GLuint* buffers); 289 | typedef void (APIENTRY *glBindBufferPROC) (GLenum target, const GLuint buffer); 290 | typedef void (APIENTRY *glBufferDataPROC) (GLenum target, GLsizeiptr size, const GLvoid * data, GLenum usage); 291 | typedef void * (APIENTRY *glMapBufferPROC) (GLenum target, GLenum access); 292 | typedef void (APIENTRY *glUnmapBufferPROC) (GLenum target); 293 | 294 | extern glGenBuffersPROC glGenBuffersEXT; 295 | extern glDeleteBuffersPROC glDeleteBuffersEXT; 296 | extern glBindBufferPROC glBindBufferEXT; 297 | extern glBufferDataPROC glBufferDataEXT; 298 | extern glMapBufferPROC glMapBufferEXT; 299 | extern glUnmapBufferPROC glUnmapBufferEXT; 300 | #endif // USE_PBO_EXTENSIONS 301 | 302 | #endif // end GLEW 303 | 304 | //---------------- 305 | // Local functions 306 | //---------------- 307 | bool InitializeGlew(); 308 | unsigned int loadGLextensions(); 309 | bool loadInteropExtensions(); 310 | bool loadFBOextensions(); 311 | bool loadBLITextension(); 312 | bool loadSwapExtensions(); 313 | bool loadPBOextensions(); 314 | // bool isExtensionSupported(const char *extension); 315 | 316 | #endif 317 | -------------------------------------------------------------------------------- /src/SpoutSDK/SpoutMemoryShare.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | 3 | SpoutMemoryShare.cpp 4 | 5 | Spout memory map management for sharing images via shared memory 6 | Revised over original single reader/writer pair 7 | 8 | Thanks and credit to Malcolm Bechard for the SpoutSharedMemory class 9 | 10 | https://github.com/mbechard 11 | 12 | - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 13 | 21.08.15 - started class file 14 | 25.09.15 - set sendermem object pointer to NULL in constructor 15 | 11.10.15 - introduced global width and height and GetSenderMemorySize function 16 | 29.02.16 - cleanup 17 | - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 18 | 19 | Copyright (c) 2014-2017, Lynn Jarvis. All rights reserved. 20 | 21 | Redistribution and use in source and binary forms, with or without modification, 22 | are permitted provided that the following conditions are met: 23 | 24 | 1. Redistributions of source code must retain the above copyright notice, 25 | this list of conditions and the following disclaimer. 26 | 27 | 2. Redistributions in binary form must reproduce the above copyright notice, 28 | this list of conditions and the following disclaimer in the documentation 29 | and/or other materials provided with the distribution. 30 | 31 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 32 | EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 33 | OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 34 | IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 35 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 36 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 37 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 38 | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 39 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 40 | - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 41 | 42 | */ 43 | #include "spoutMemoryShare.h" 44 | #include 45 | 46 | spoutMemoryShare::spoutMemoryShare() { 47 | senderMem = NULL; // Important because this is checked 48 | m_Width = 0; 49 | m_Height = 0; 50 | } 51 | 52 | spoutMemoryShare::~spoutMemoryShare() { 53 | 54 | if(senderMem) delete senderMem; 55 | senderMem = NULL; 56 | m_Width = 0; 57 | m_Height = 0; 58 | 59 | } 60 | 61 | 62 | // SENDER : Create a sender named shared memory map 63 | // RECEIVER : Attach to an existing named shared memory map 64 | bool spoutMemoryShare::CreateSenderMemory(const char *sendername, unsigned int width, unsigned int height) 65 | { 66 | string namestring = sendername; 67 | 68 | // Create a name for the map from the sender name 69 | namestring += "_map"; 70 | 71 | // Create a new shared memory class object for this sender 72 | if(senderMem) delete senderMem; 73 | senderMem = new SpoutSharedMemory(); 74 | 75 | // Create a shared memory map for this sender 76 | // Allocate enough width*height*4 - RGBA image 77 | SpoutCreateResult result = senderMem->Create(namestring.c_str(), width*height*4 ); 78 | 79 | if(result == SPOUT_CREATE_FAILED) { 80 | delete senderMem; 81 | senderMem = NULL; 82 | m_Width = 0; 83 | m_Height = 0; 84 | return false; 85 | } 86 | 87 | // Set the global width and height for future reference 88 | m_Width = width; 89 | m_Height = height; 90 | 91 | return true; 92 | 93 | } // end CreateSenderMemory 94 | 95 | 96 | // SENDER : Update a sender shared memory map size 97 | // Only the sender can update the memory map size by creating a new one because 98 | // the sender creates the map and it's map handle cannot be released by a receiver, 99 | // so a new map cannot be created by a receiver. 100 | bool spoutMemoryShare::UpdateSenderMemorySize(const char *sendername, unsigned int width, unsigned int height) 101 | { 102 | string namestring = sendername; 103 | 104 | namestring += "_map"; 105 | 106 | // Delete the existing sender shared memory object - Releases mutex and maps 107 | if(senderMem) delete senderMem; 108 | // Create a new shared memory map for this sender 109 | senderMem = new SpoutSharedMemory(); 110 | 111 | SpoutCreateResult result = senderMem->Create(namestring.c_str(), width*height*4 ); 112 | if(result == SPOUT_CREATE_FAILED) { 113 | delete senderMem; 114 | senderMem = NULL; 115 | m_Width = 0; 116 | m_Height = 0; 117 | return false; 118 | } 119 | 120 | // Reset the global width and height 121 | m_Width = width; 122 | m_Height = height; 123 | 124 | return true; 125 | 126 | } // end UpdateSenderMemorySize 127 | 128 | 129 | 130 | // RECEIVER : Open an existing named shared memory map 131 | bool spoutMemoryShare::OpenSenderMemory(const char *sendername) 132 | { 133 | string namestring = sendername; 134 | 135 | // Create a name for the map from the sender name 136 | namestring += "_map"; 137 | 138 | // Create a new shared memory class object for this receiver 139 | if(!senderMem) senderMem = new SpoutSharedMemory(); 140 | 141 | if(!senderMem->Open(namestring.c_str()) ) { 142 | return false; 143 | } 144 | 145 | // TODO : Set the global width and height - how ? 146 | // m_Width = width; 147 | // m_Height = height; 148 | 149 | return true; 150 | 151 | } // end OpenSenderMemory 152 | 153 | 154 | // Return the global shared memory size 155 | bool spoutMemoryShare::GetSenderMemorySize(unsigned int &width, unsigned int &height) 156 | { 157 | if(m_Width == 0 || m_Height == 0) return false; 158 | 159 | width = m_Width; 160 | height = m_Height; 161 | 162 | return true; 163 | 164 | } // end GetSenderMemorySize 165 | 166 | 167 | 168 | // Close the sender shared memory map 169 | void spoutMemoryShare::CloseSenderMemory() 170 | { 171 | if(senderMem) senderMem->Close(); 172 | m_Width = 0; 173 | m_Height = 0; 174 | 175 | } // end CloseSenderMemory 176 | 177 | 178 | 179 | void spoutMemoryShare::ReleaseSenderMemory() 180 | { 181 | // Delete the sender shared memory object - Releases mutex and maps 182 | if(senderMem) delete senderMem; 183 | senderMem = NULL; 184 | m_Width = 0; 185 | m_Height = 0; 186 | 187 | } 188 | 189 | // Lock and unlock memory and retrieve buffer pointer - no size checks 190 | unsigned char * spoutMemoryShare::LockSenderMemory() 191 | { 192 | if(!senderMem) return NULL; 193 | 194 | char *pBuf = senderMem->Lock(); 195 | if (!pBuf) { 196 | // https://github.com/leadedge/Spout2/issues/15 197 | // senderMem->Unlock(); 198 | return NULL; 199 | } 200 | 201 | return (unsigned char *)pBuf; 202 | 203 | } 204 | 205 | void spoutMemoryShare::UnlockSenderMemory() 206 | { 207 | if(!senderMem) return; 208 | 209 | senderMem->Unlock(); 210 | } 211 | 212 | -------------------------------------------------------------------------------- /src/SpoutSDK/SpoutMemoryShare.h: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | SpoutMemoryShare.h 4 | 5 | Spout memory map management for sharing images via shared memory 6 | Revised over original single reader/writer pair 7 | 8 | Thanks and credit to Malcolm Bechard for the SpoutSharedMemory class 9 | 10 | https://github.com/mbechard 11 | 12 | - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 13 | Copyright (c) 2014-2017, Lynn Jarvis. All rights reserved. 14 | 15 | Redistribution and use in source and binary forms, with or without modification, 16 | are permitted provided that the following conditions are met: 17 | 18 | 1. Redistributions of source code must retain the above copyright notice, 19 | this list of conditions and the following disclaimer. 20 | 21 | 2. Redistributions in binary form must reproduce the above copyright notice, 22 | this list of conditions and the following disclaimer in the documentation 23 | and/or other materials provided with the distribution. 24 | 25 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 26 | EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 27 | OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 28 | IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 29 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 30 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 31 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 32 | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 33 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34 | 35 | */ 36 | #pragma once 37 | #ifndef __spoutMemoryShare__ 38 | #define __spoutMemoryShare__ 39 | 40 | #include 41 | #include 42 | #include "SpoutCommon.h" 43 | #include "SpoutSharedMemory.h" 44 | 45 | using namespace std; 46 | 47 | class SPOUT_DLLEXP spoutMemoryShare { 48 | 49 | public: 50 | 51 | spoutMemoryShare(); 52 | ~spoutMemoryShare(); 53 | 54 | // Create / Open, Update or Close a sender memory map 55 | bool CreateSenderMemory (const char *sendername, unsigned int width, unsigned int height); 56 | bool UpdateSenderMemorySize (const char* sendername, unsigned int width, unsigned int height); 57 | bool OpenSenderMemory (const char *sendername); 58 | void CloseSenderMemory (); 59 | 60 | // Retrieve global width and height 61 | bool GetSenderMemorySize(unsigned int &width, unsigned int &height); 62 | 63 | // Lock and unlock memory and retrieve buffer pointer 64 | unsigned char * LockSenderMemory(); 65 | void UnlockSenderMemory(); 66 | 67 | // Close and release memory object 68 | void ReleaseSenderMemory (); 69 | 70 | protected: 71 | 72 | SpoutSharedMemory *senderMem; 73 | unsigned int m_Width; 74 | unsigned int m_Height; 75 | 76 | }; 77 | 78 | #endif 79 | -------------------------------------------------------------------------------- /src/SpoutSDK/SpoutReceiver.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // SpoutReceiver 3 | // 4 | // Wrapper class so that a receiver object can be created independent of a sender 5 | // 6 | // ==================================================================================== 7 | // Revisions : 8 | // 9 | // 27-07-14 - CreateReceiver - bUseActive flag instead of null name 10 | // 03.09.14 - Cleanup 11 | // 23.09.14 - return DirectX 11 capability in SetDX9 12 | // 28.09.14 - Added Host FBO for ReceiveTexture 13 | // 12.10.14 - changed SelectSenderPanel arg to const char 14 | // 23.12.14 - added host fbo arg to ReceiveImage 15 | // 08.02.15 - Changed default texture format for ReceiveImage in header to GL_RGBA 16 | // 29.05.15 - Included SetAdapter for multiple adapters - Franz Hildgen. 17 | // 02.06.15 - Added GetAdapter, GetNumAdapters, GetAdapterName 18 | // 24.08.15 - Added GetHostPath to retrieve the path of the host that produced the sender 19 | // 15.09.15 - Removed SetMemoryShareMode for 2.005 - now done globally by SpoutDirectX.exe 20 | // 10.10.15 - Added transition flag to set invert true for 2.004 rather than default false for 2.005 21 | // - currently not used - see SpoutSDK.cpp CreateSender 22 | // 14.11.15 - changed functions to "const char *" where required 23 | // 18.11.15 - added CheckReceiver so that DrawSharedTexture can be used by a receiver 24 | // 18.06.16 - Add invert to ReceiveImage 25 | // 17.09.16 - removed CheckSpout2004() from constructor 26 | // 13.01.17 - Add SetCPUmode, GetCPUmode, SetBufferMode, GetBufferMode 27 | // - Add HostFBO arg to DrawSharedTexture 28 | // 15.01.17 - Add GetShareMode, SetShareMode 29 | // 30 | // ==================================================================================== 31 | /* 32 | Copyright (c) 2014-2017, Lynn Jarvis. All rights reserved. 33 | 34 | Redistribution and use in source and binary forms, with or without modification, 35 | are permitted provided that the following conditions are met: 36 | 37 | 1. Redistributions of source code must retain the above copyright notice, 38 | this list of conditions and the following disclaimer. 39 | 40 | 2. Redistributions in binary form must reproduce the above copyright notice, 41 | this list of conditions and the following disclaimer in the documentation 42 | and/or other materials provided with the distribution. 43 | 44 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 45 | EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 46 | OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 47 | IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 48 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 49 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 50 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 51 | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 52 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 53 | 54 | */ 55 | #include "SpoutReceiver.h" 56 | 57 | SpoutReceiver::SpoutReceiver() 58 | { 59 | 60 | } 61 | 62 | 63 | //--------------------------------------------------------- 64 | SpoutReceiver::~SpoutReceiver() 65 | { 66 | 67 | } 68 | 69 | 70 | //--------------------------------------------------------- 71 | bool SpoutReceiver::ReceiveTexture(char* name, unsigned int &width, unsigned int &height, GLuint TextureID, GLuint TextureTarget, bool bInvert, GLuint HostFBO) 72 | { 73 | return spout.ReceiveTexture(name, width, height, TextureID, TextureTarget, bInvert, HostFBO); 74 | } 75 | 76 | 77 | //--------------------------------------------------------- 78 | bool SpoutReceiver::ReceiveImage(char* Sendername, 79 | unsigned int &width, 80 | unsigned int &height, 81 | unsigned char* pixels, 82 | GLenum glFormat, 83 | bool bInvert, 84 | GLuint HostFBO) 85 | { 86 | return spout.ReceiveImage(Sendername, width, height, pixels, glFormat, bInvert, HostFBO); 87 | } 88 | 89 | 90 | //--------------------------------------------------------- 91 | bool SpoutReceiver::CheckReceiver(char* name, unsigned int &width, unsigned int &height, bool &bConnected) 92 | { 93 | return spout.CheckReceiver(name, width, height, bConnected); 94 | } 95 | 96 | //--------------------------------------------------------- 97 | bool SpoutReceiver::GetImageSize(char* name, unsigned int &width, unsigned int &height, bool &bMemoryMode) 98 | { 99 | return spout.GetImageSize(name, width, height, bMemoryMode); 100 | } 101 | 102 | 103 | //--------------------------------------------------------- 104 | bool SpoutReceiver::CreateReceiver(char* name, unsigned int &width, unsigned int &height, bool bUseActive) 105 | { 106 | return spout.CreateReceiver(name, width, height, bUseActive); 107 | } 108 | 109 | //--------------------------------------------------------- 110 | void SpoutReceiver::ReleaseReceiver() 111 | { 112 | spout.ReleaseReceiver(); 113 | } 114 | 115 | 116 | //--------------------------------------------------------- 117 | bool SpoutReceiver::BindSharedTexture() 118 | { 119 | return spout.BindSharedTexture(); 120 | } 121 | 122 | 123 | //--------------------------------------------------------- 124 | bool SpoutReceiver::UnBindSharedTexture() 125 | { 126 | return spout.UnBindSharedTexture(); 127 | } 128 | 129 | 130 | //--------------------------------------------------------- 131 | int SpoutReceiver::GetSenderCount() 132 | { 133 | return spout.GetSenderCount(); 134 | } 135 | 136 | //--------------------------------------------------------- 137 | bool SpoutReceiver::DrawSharedTexture(float max_x, float max_y, float aspect, bool bInvert, GLuint HostFBO) 138 | { 139 | return spout.DrawSharedTexture(max_x, max_y, aspect, bInvert, HostFBO); 140 | } 141 | 142 | 143 | //--------------------------------------------------------- 144 | bool SpoutReceiver::GetSenderName(int index, char* sendername, int MaxNameSize) 145 | { 146 | return spout.GetSenderName(index, sendername, MaxNameSize); 147 | } 148 | 149 | //--------------------------------------------------------- 150 | bool SpoutReceiver::GetActiveSender(char* Sendername) 151 | { 152 | return spout.GetActiveSender(Sendername); 153 | } 154 | 155 | 156 | //--------------------------------------------------------- 157 | bool SpoutReceiver::SetActiveSender(const char* Sendername) 158 | { 159 | return spout.SetActiveSender(Sendername); 160 | } 161 | 162 | 163 | //--------------------------------------------------------- 164 | bool SpoutReceiver::GetSenderInfo(const char* sendername, unsigned int &width, unsigned int &height, HANDLE &dxShareHandle, DWORD &dwFormat) 165 | { 166 | return spout.GetSenderInfo(sendername, width, height, dxShareHandle, dwFormat); 167 | } 168 | 169 | 170 | //--------------------------------------------------------- 171 | bool SpoutReceiver::SelectSenderPanel(const char* message) 172 | { 173 | return spout.SelectSenderPanel(message); 174 | } 175 | 176 | //--------------------------------------------------------- 177 | bool SpoutReceiver::SetMemoryShareMode(bool bMem) 178 | { 179 | return spout.SetMemoryShareMode(bMem); 180 | } 181 | 182 | //--------------------------------------------------------- 183 | bool SpoutReceiver::GetMemoryShareMode() 184 | { 185 | return spout.GetMemoryShareMode(); 186 | } 187 | 188 | //--------------------------------------------------------- 189 | bool SpoutReceiver::SetCPUmode(bool bCPU) 190 | { 191 | return (spout.SetCPUmode(bCPU)); 192 | } 193 | 194 | //--------------------------------------------------------- 195 | bool SpoutReceiver::GetCPUmode() 196 | { 197 | return (spout.GetCPUmode()); 198 | } 199 | 200 | //--------------------------------------------------------- 201 | int SpoutReceiver::GetShareMode() 202 | { 203 | return (spout.GetShareMode()); 204 | } 205 | 206 | //--------------------------------------------------------- 207 | bool SpoutReceiver::SetShareMode(int mode) 208 | { 209 | return (spout.SetShareMode(mode)); 210 | } 211 | 212 | //--------------------------------------------------------- 213 | void SpoutReceiver::SetBufferMode(bool bActive) 214 | { 215 | spout.SetBufferMode(bActive); 216 | } 217 | 218 | //--------------------------------------------------------- 219 | bool SpoutReceiver::GetBufferMode() 220 | { 221 | return spout.GetBufferMode(); 222 | } 223 | 224 | //--------------------------------------------------------- 225 | bool SpoutReceiver::SetDX9(bool bDX9) 226 | { 227 | return spout.interop.UseDX9(bDX9); 228 | } 229 | 230 | 231 | //--------------------------------------------------------- 232 | bool SpoutReceiver::GetDX9() 233 | { 234 | return spout.interop.isDX9(); 235 | } 236 | 237 | 238 | //--------------------------------------------------------- 239 | void SpoutReceiver::SetDX9compatible(bool bCompatible) 240 | { 241 | if(bCompatible) { 242 | // DX11 -> DX9 only works if the DX11 format is set to DXGI_FORMAT_B8G8R8A8_UNORM 243 | spout.interop.SetDX11format(DXGI_FORMAT_B8G8R8A8_UNORM); 244 | } 245 | else { 246 | // DX11 -> DX11 only 247 | spout.interop.SetDX11format(DXGI_FORMAT_R8G8B8A8_UNORM); 248 | } 249 | } 250 | 251 | 252 | //--------------------------------------------------------- 253 | bool SpoutReceiver::GetDX9compatible() 254 | { 255 | if(spout.interop.DX11format == DXGI_FORMAT_B8G8R8A8_UNORM) 256 | return true; 257 | else 258 | return false; 259 | } 260 | 261 | //--------------------------------------------------------- 262 | bool SpoutReceiver::SetAdapter(int index) 263 | { 264 | return spout.SetAdapter(index); 265 | } 266 | 267 | // Get current adapter index 268 | int SpoutReceiver::GetAdapter() 269 | { 270 | return spout.GetAdapter(); 271 | } 272 | 273 | // Get the number of graphics adapters in the system 274 | int SpoutReceiver::GetNumAdapters() 275 | { 276 | return spout.GetNumAdapters(); 277 | } 278 | 279 | // Get an adapter name 280 | bool SpoutReceiver::GetAdapterName(int index, char *adaptername, int maxchars) 281 | { 282 | return spout.GetAdapterName(index, adaptername, maxchars); 283 | } 284 | 285 | // Get the path of the host that created the sender 286 | bool SpoutReceiver::GetHostPath(const char *sendername, char *hostpath, int maxchars) 287 | { 288 | return spout.GetHostPath(sendername, hostpath, maxchars); 289 | } 290 | 291 | 292 | //--------------------------------------------------------- 293 | bool SpoutReceiver::SetVerticalSync(bool bSync) 294 | { 295 | return spout.interop.SetVerticalSync(bSync); 296 | } 297 | 298 | //--------------------------------------------------------- 299 | int SpoutReceiver::GetVerticalSync() 300 | { 301 | return spout.interop.GetVerticalSync(); 302 | } 303 | -------------------------------------------------------------------------------- /src/SpoutSDK/SpoutReceiver.h: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | SpoutReceiver.h 4 | 5 | Copyright (c) 2014-2017, Lynn Jarvis. All rights reserved. 6 | 7 | Redistribution and use in source and binary forms, with or without modification, 8 | are permitted provided that the following conditions are met: 9 | 10 | 1. Redistributions of source code must retain the above copyright notice, 11 | this list of conditions and the following disclaimer. 12 | 13 | 2. Redistributions in binary form must reproduce the above copyright notice, 14 | this list of conditions and the following disclaimer in the documentation 15 | and/or other materials provided with the distribution. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 18 | EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19 | OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 | IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 21 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 22 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | 27 | */ 28 | #pragma once 29 | 30 | #ifndef __SpoutReceiver__ 31 | #define __SpoutReceiver__ 32 | 33 | #include "spoutSDK.h" 34 | 35 | class SPOUT_DLLEXP SpoutReceiver { 36 | 37 | public: 38 | 39 | SpoutReceiver(); 40 | ~SpoutReceiver(); 41 | 42 | bool CreateReceiver(char* Sendername, unsigned int &width, unsigned int &height, bool bUseActive = false); 43 | bool ReceiveTexture(char* Sendername, unsigned int &width, unsigned int &height, GLuint TextureID = 0, GLuint TextureTarget = 0, bool bInvert = false, GLuint HostFBO = 0); 44 | bool ReceiveImage(char* Sendername, unsigned int &width, unsigned int &height, unsigned char* pixels, GLenum glFormat = GL_RGBA, bool bInvert = false, GLuint HostFBO=0); 45 | bool CheckReceiver (char* Sendername, unsigned int &width, unsigned int &height, bool &bConnected); 46 | bool GetImageSize (char* Sendername, unsigned int &width, unsigned int &height, bool &bMemoryMode); 47 | void ReleaseReceiver(); 48 | 49 | bool BindSharedTexture(); 50 | bool UnBindSharedTexture(); 51 | bool DrawSharedTexture(float max_x = 1.0, float max_y = 1.0, float aspect = 1.0, bool bInvert = true, GLuint HostFBO=0); 52 | 53 | int GetSenderCount(); 54 | bool GetSenderName(int index, char* Sendername, int MaxSize = 256); 55 | bool GetSenderInfo(const char* Sendername, unsigned int &width, unsigned int &height, HANDLE &dxShareHandle, DWORD &dwFormat); 56 | 57 | bool GetActiveSender(char* Sendername); 58 | bool SetActiveSender(const char* Sendername); 59 | 60 | bool SelectSenderPanel(const char* message = NULL); 61 | 62 | bool SetDX9(bool bDX9 = true); // set to use DirectX 9 (default is DirectX 11) 63 | bool GetDX9(); 64 | bool SetMemoryShareMode(bool bMem = true); 65 | bool GetMemoryShareMode(); 66 | bool SetCPUmode(bool bCPU = true); 67 | bool GetCPUmode(); 68 | int GetShareMode(); 69 | bool SetShareMode(int mode); 70 | void SetBufferMode(bool bActive); // Set the pbo availability on or off 71 | bool GetBufferMode(); 72 | 73 | void SetDX9compatible(bool bCompatible = true); 74 | bool GetDX9compatible(); 75 | 76 | int GetNumAdapters(); // Get the number of graphics adapters in the system 77 | bool GetAdapterName(int index, char *adaptername, int maxchars); // Get an adapter name 78 | bool SetAdapter(int index = 0); // Set required graphics adapter for output 79 | int GetAdapter(); // Get the current adapter index 80 | 81 | bool GetHostPath(const char *sendername, char *hostpath, int maxchars); // The path of the host that produced the sender 82 | 83 | bool SetVerticalSync(bool bSync = true); 84 | int GetVerticalSync(); 85 | 86 | Spout spout; // for access to all functions 87 | 88 | protected : 89 | 90 | }; 91 | 92 | #endif 93 | -------------------------------------------------------------------------------- /src/SpoutSDK/SpoutSDK.h: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | SpoutSDK.h 4 | 5 | The main SDK include file 6 | 7 | 8 | Copyright (c) 2014-2017, Lynn Jarvis. All rights reserved. 9 | 10 | Redistribution and use in source and binary forms, with or without modification, 11 | are permitted provided that the following conditions are met: 12 | 13 | 1. Redistributions of source code must retain the above copyright notice, 14 | this list of conditions and the following disclaimer. 15 | 16 | 2. Redistributions in binary form must reproduce the above copyright notice, 17 | this list of conditions and the following disclaimer in the documentation 18 | and/or other materials provided with the distribution. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 21 | EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 22 | OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 23 | IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 24 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 25 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27 | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | 30 | */ 31 | #pragma once 32 | #ifndef __SpoutSDK__ 33 | #define __SpoutSDK__ 34 | 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include // for timegettime 41 | #include // for _getcwd 42 | #include // for path functions 43 | #include "Shellapi.h" // for shellexecute 44 | 45 | #pragma comment(lib, "shlwapi.lib") // for path functions 46 | #pragma comment(lib, "Shell32.lib") // for shellexecute 47 | #pragma comment(lib, "Advapi32.lib") // for registry functions 48 | #pragma comment(lib, "Version.lib") // for VersionInfo API 49 | 50 | 51 | #include "SpoutCommon.h" 52 | #include "spoutMemoryShare.h" 53 | #include "SpoutSenderNames.h" 54 | #include "SpoutGLDXinterop.h" 55 | 56 | // Compile flag only - not currently used 57 | #if defined(__x86_64__) || defined(_M_X64) 58 | #define is64bit 59 | // #elif defined(__i386) || defined(_M_IX86) 60 | // x86 32-bit 61 | #endif 62 | 63 | class SPOUT_DLLEXP Spout { 64 | 65 | public: 66 | 67 | Spout(); 68 | ~Spout(); 69 | 70 | spoutGLDXinterop interop; // Opengl/directx interop texture sharing object 71 | 72 | // ================== // 73 | // PUBLIC FUNCTIONS // 74 | // ================== // 75 | 76 | // Sender 77 | bool CreateSender (const char *Sendername, unsigned int width, unsigned int height, DWORD dwFormat = 0); 78 | bool UpdateSender (const char* Sendername, unsigned int width, unsigned int height); 79 | void ReleaseSender (DWORD dwMsec = 0); 80 | 81 | // Receiver 82 | bool CreateReceiver (char* Sendername, unsigned int &width, unsigned int &height, bool bUseActive = false); 83 | void ReleaseReceiver(); 84 | bool CheckReceiver (char* Sendername, unsigned int &width, unsigned int &height, bool &bConnected); 85 | bool GetImageSize (char* sendername, unsigned int &width, unsigned int &height, bool &mMemoryMode); 86 | 87 | // Texture functions 88 | bool SendTexture (GLuint TextureID, GLuint TextureTarget, unsigned int width, unsigned int height, bool bInvert=true, GLuint HostFBO=0); 89 | bool SendImage (const unsigned char* pixels, unsigned int width, unsigned int height, GLenum glFormat = GL_RGBA, bool bInvert=true, GLuint HostFBO = 0); 90 | bool ReceiveTexture (char* Sendername, unsigned int &width, unsigned int &height, GLuint TextureID = 0, GLuint TextureTarget = 0, bool bInvert = false, GLuint HostFBO=0); 91 | bool ReceiveImage (char* Sendername, unsigned int &width, unsigned int &height, unsigned char* pixels, GLenum glFormat = GL_RGBA, bool bInvert = false, GLuint HostFBO=0); 92 | bool DrawSharedTexture(float max_x = 1.0, float max_y = 1.0, float aspect = 1.0, bool bInvert = true, GLuint HostFBO = 0); 93 | 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); 94 | bool BindSharedTexture(); 95 | bool UnBindSharedTexture(); 96 | 97 | int GetSenderCount (); 98 | bool GetSenderName (int index, char* sendername, int MaxSize = 256); 99 | bool GetSenderInfo (const char* sendername, unsigned int &width, unsigned int &height, HANDLE &dxShareHandle, DWORD &dwFormat); 100 | bool GetActiveSender(char* Sendername); 101 | bool SetActiveSender(const char* Sendername); 102 | 103 | // Utilities 104 | bool SetDX9(bool bDX9 = true); // User request to use DirectX 9 (default is DirectX 11) 105 | bool GetDX9(); // Return the flag that has been set 106 | bool SetMemoryShareMode(bool bMem = true); 107 | bool GetMemoryShareMode(); 108 | bool SetCPUmode(bool bCPU = true); 109 | bool GetCPUmode(); 110 | int GetShareMode(); 111 | bool SetShareMode(int mode); 112 | int GetMaxSenders(); // Get maximum senders allowed 113 | void SetMaxSenders(int maxSenders); // Set maximum senders allowed 114 | 115 | // Access to globals 116 | bool GetSpoutSenderName(char * sendername, int maxchars); // get the global sender name 117 | bool IsSpoutInitialized(); // has the class been initialized 118 | bool IsBGRAavailable(); // Are bgra extensions supported (in interop class) 119 | bool IsPBOavailable(); // Are pbo extensions supported (in interop class) 120 | void SetBufferMode(bool bActive); // Set the pbo availability on or off 121 | bool GetBufferMode(); 122 | 123 | // Adapter functions 124 | int GetNumAdapters(); // Get the number of graphics adapters in the system 125 | bool GetAdapterName(int index, char *adaptername, int maxchars); // Get an adapter name 126 | bool SetAdapter(int index = 0); // Set required graphics adapter for output 127 | int GetAdapter(); // Get the SpoutDirectX global adapter index 128 | 129 | bool GetHostPath(const char *sendername, char *hostpath, int maxchars); // The path of the host that produced the sender 130 | 131 | int GetVerticalSync(); 132 | bool SetVerticalSync(bool bSync = true); 133 | bool SelectSenderPanel(const char* message = NULL); 134 | 135 | bool CheckSpoutPanel(); // Public for debugging 136 | bool OpenSpout(); // Public for debugging 137 | 138 | // Registry read/write 139 | bool WritePathToRegistry (const char *filepath, const char *subkey, const char *valuename); 140 | bool ReadPathFromRegistry(char *filepath, const char *subkey, const char *valuename); 141 | bool RemovePathFromRegistry(const char *subkey, const char *valuename); 142 | 143 | // Public for debugging only 144 | void UseAccessLocks(bool bUseLocks); // to disable/enable texture access locks in SpoutDirectX.cpp 145 | void SpoutCleanUp(bool bExit = false); 146 | void CleanSenders(); 147 | int ReportMemory(); 148 | 149 | /* 150 | // 151 | // 152 | // http://msdn.microsoft.com/en-us/library/windows/desktop/bb172558%28v=vs.85%29.aspx 153 | // 154 | // Compatible DX11/DX9 format for Texture2D 155 | // http://msdn.microsoft.com/en-us/library/windows/desktop/ff471324%28v=vs.85%29.aspx 156 | // 157 | // DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, DXGI_FORMAT_B8G8R8A8_UNORM 158 | // are compatible with DX9 - D3DFMT_A8B8G8R8 159 | // 160 | // Noted that DX11 -> DX9 only works if the DX11 format is set to DXGI_FORMAT_B8G8R8A8_UNORM 161 | // if the DX9 format is set to D3DFMT_A8B8G8R8 162 | 163 | DXGI_FORMAT_R8G8B8A8_TYPELESS = 27, 164 | DXGI_FORMAT_R8G8B8A8_UNORM = 28, 165 | DXGI_FORMAT_R8G8B8A8_UNORM_SRGB = 29, 166 | DXGI_FORMAT_R8G8B8A8_UINT = 30, 167 | DXGI_FORMAT_R8G8B8A8_SNORM = 31, 168 | DXGI_FORMAT_R8G8B8A8_SINT = 32, 169 | DXGI_FORMAT_B8G8R8A8_UNORM = 87, 170 | DXGI_FORMAT_B8G8R8X8_UNORM = 88, 171 | DXGI_FORMAT_B8G8R8A8_TYPELESS = 90, 172 | DXGI_FORMAT_B8G8R8A8_UNORM_SRGB = 91, 173 | DXGI_FORMAT_B8G8R8X8_TYPELESS = 92, 174 | DXGI_FORMAT_B8G8R8X8_UNORM_SRGB = 93, 175 | 176 | */ 177 | 178 | protected : 179 | 180 | // ================================= // 181 | // PRIVATE VARIABLES AND FUNCTIONS // 182 | // ================================= // 183 | char g_SharedMemoryName[256]; 184 | char UserSenderName[256]; // used for the sender selection dialog 185 | unsigned int g_Width; 186 | unsigned int g_Height; 187 | HANDLE g_ShareHandle; 188 | DWORD g_Format; 189 | GLuint g_TexID; 190 | HWND g_hWnd; 191 | bool bGLDXcompatible; 192 | bool bMemoryShareInitOK; 193 | bool bDxInitOK; 194 | bool bUseCPU; 195 | bool bMemory; // force memoryshare flag 196 | bool bInitialized; 197 | bool bIsSending; 198 | bool bIsReceiving; 199 | bool bChangeRequested; 200 | bool bSpoutPanelOpened; 201 | bool bSpoutPanelActive; 202 | bool bUseActive; // Use the active sender for CreateReceiver 203 | SHELLEXECUTEINFOA m_ShExecInfo; 204 | 205 | bool GLDXcompatible(); 206 | bool OpenReceiver (char *name, unsigned int& width, unsigned int& height); 207 | bool InitReceiver (HWND hwnd, char* sendername, unsigned int width, unsigned int height, bool bMemoryMode); 208 | bool InitSender (HWND hwnd, const char* sendername, unsigned int width, unsigned int height, DWORD dwFormat, bool bMemoryMode); 209 | bool InitMemoryShare(bool bReceiver); 210 | bool ReleaseMemoryShare(); 211 | 212 | // Find a file version 213 | bool FindFileVersion(const char *filepath, DWORD &versMS, DWORD &versLS); 214 | 215 | }; 216 | 217 | #endif 218 | 219 | 220 | -------------------------------------------------------------------------------- /src/SpoutSDK/SpoutSender.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // SpoutSender 3 | // 4 | // Wrapper class so that a sender object can be created independent of a receiver 5 | // 6 | // ==================================================================================== 7 | // Revisions : 8 | // 9 | // 23.09.14 - return DirectX 11 capability in SetDX9 10 | // 28.09.14 - Added GL format for SendImage 11 | // - Added bAlignment (4 byte alignment) flag for SendImage 12 | // - Added Host FBO for SendTexture, DrawToSharedTexture 13 | // 08.02.15 - Changed default texture format for SendImage in header to GL_RGBA 14 | // 29.05.15 - Included SetAdapter for multiple adapters - Franz Hildgen. 15 | // 02.06.15 - Added GetAdapter, GetNumAdapters, GetAdapterName 16 | // 08.06.15 - Added SelectSenderPanel for user adapter output selection 17 | // 24.08.15 - Added GetHostPath to retrieve the path of the host that produced the sender 18 | // 25.09.15 - Changed SetMemoryShareMode for 2.005 - now will only set true for 2.005 and above 19 | // 09.10.15 - DrawToSharedTexture - invert default false instead of true 20 | // 10.10.15 - Added transition flag to set invert true for 2.004 rather than default false for 2.005 21 | // - currently not used - see SpoutSDK.cpp CreateSender 22 | // 14.11.15 - changed functions to "const char *" where required 23 | // 17.03.16 - changed to const unsigned char for Sendimage buffer 24 | // 17.09.16 - removed CheckSpout2004() from constructor 25 | // 13.01.17 - Add SetCPUmode, GetCPUmode, SetBufferMode, GetBufferMode 26 | // 15.01.17 - Add GetShareMode, SetShareMode 27 | // 28 | // ==================================================================================== 29 | /* 30 | 31 | Copyright (c) 2014-2017, Lynn Jarvis. All rights reserved. 32 | 33 | Redistribution and use in source and binary forms, with or without modification, 34 | are permitted provided that the following conditions are met: 35 | 36 | 1. Redistributions of source code must retain the above copyright notice, 37 | this list of conditions and the following disclaimer. 38 | 39 | 2. Redistributions in binary form must reproduce the above copyright notice, 40 | this list of conditions and the following disclaimer in the documentation 41 | and/or other materials provided with the distribution. 42 | 43 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 44 | EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 45 | OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 46 | IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 47 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 48 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 49 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 50 | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 51 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 52 | 53 | */ 54 | #include "SpoutSender.h" 55 | 56 | SpoutSender::SpoutSender() 57 | { 58 | 59 | } 60 | 61 | 62 | //--------------------------------------------------------- 63 | SpoutSender::~SpoutSender() 64 | { 65 | 66 | } 67 | 68 | 69 | //--------------------------------------------------------- 70 | bool SpoutSender::CreateSender(const char *name, unsigned int width, unsigned int height, DWORD dwFormat) 71 | { 72 | return spout.CreateSender(name, width, height, dwFormat); 73 | } 74 | 75 | 76 | //--------------------------------------------------------- 77 | bool SpoutSender::UpdateSender(const char *name, unsigned int width, unsigned int height) 78 | { 79 | return spout.UpdateSender(name, width, height); 80 | } 81 | 82 | 83 | //--------------------------------------------------------- 84 | void SpoutSender::ReleaseSender(DWORD dwMsec) 85 | { 86 | spout.ReleaseSender(dwMsec); 87 | } 88 | 89 | 90 | //--------------------------------------------------------- 91 | bool SpoutSender::SendImage(const unsigned char* pixels, unsigned int width, unsigned int height, GLenum glFormat, bool bInvert, GLuint HostFBO) 92 | { 93 | return spout.SendImage(pixels, width, height, glFormat, bInvert, HostFBO); 94 | } 95 | 96 | 97 | //--------------------------------------------------------- 98 | bool SpoutSender::SendTexture(GLuint TextureID, GLuint TextureTarget, unsigned int width, unsigned int height, bool bInvert, GLuint HostFBO) 99 | { 100 | return spout.SendTexture(TextureID, TextureTarget, width, height, bInvert, HostFBO); 101 | } 102 | 103 | 104 | //--------------------------------------------------------- 105 | bool SpoutSender::DrawToSharedTexture(GLuint TextureID, GLuint TextureTarget, unsigned int width, unsigned int height, float max_x, float max_y, float aspect, bool bInvert, GLuint HostFBO) 106 | { 107 | return spout.DrawToSharedTexture(TextureID, TextureTarget, width, height, max_x, max_y, aspect, bInvert, HostFBO); 108 | } 109 | 110 | 111 | //--------------------------------------------------------- 112 | bool SpoutSender::SelectSenderPanel(const char* message) 113 | { 114 | return spout.SelectSenderPanel(message); 115 | } 116 | 117 | 118 | //--------------------------------------------------------- 119 | bool SpoutSender::SetMemoryShareMode(bool bMem) 120 | { 121 | return spout.SetMemoryShareMode(bMem); 122 | } 123 | 124 | 125 | //--------------------------------------------------------- 126 | bool SpoutSender::GetMemoryShareMode() 127 | { 128 | return spout.GetMemoryShareMode(); 129 | } 130 | 131 | //--------------------------------------------------------- 132 | bool SpoutSender::SetCPUmode(bool bCPU) 133 | { 134 | return (spout.SetCPUmode(bCPU)); 135 | } 136 | 137 | //--------------------------------------------------------- 138 | bool SpoutSender::GetCPUmode() 139 | { 140 | return (spout.GetCPUmode()); 141 | } 142 | 143 | 144 | //--------------------------------------------------------- 145 | int SpoutSender::GetShareMode() 146 | { 147 | return (spout.GetShareMode()); 148 | } 149 | 150 | //--------------------------------------------------------- 151 | bool SpoutSender::SetShareMode(int mode) 152 | { 153 | return (spout.SetShareMode(mode)); 154 | } 155 | 156 | //--------------------------------------------------------- 157 | void SpoutSender::SetBufferMode(bool bActive) 158 | { 159 | spout.SetBufferMode(bActive); 160 | } 161 | 162 | //--------------------------------------------------------- 163 | bool SpoutSender::GetBufferMode() 164 | { 165 | return spout.GetBufferMode(); 166 | } 167 | 168 | //--------------------------------------------------------- 169 | bool SpoutSender::SetDX9(bool bDX9) 170 | { 171 | return spout.SetDX9(bDX9); 172 | } 173 | 174 | 175 | //--------------------------------------------------------- 176 | bool SpoutSender::GetDX9() 177 | { 178 | return spout.interop.isDX9(); 179 | } 180 | 181 | 182 | //--------------------------------------------------------- 183 | void SpoutSender::SetDX9compatible(bool bCompatible) 184 | { 185 | if(bCompatible) { 186 | // DX11 -> DX9 only works if the DX11 format is set to DXGI_FORMAT_B8G8R8A8_UNORM 187 | spout.interop.SetDX11format(DXGI_FORMAT_B8G8R8A8_UNORM); 188 | } 189 | else { 190 | // DX11 -> DX11 only 191 | spout.interop.SetDX11format(DXGI_FORMAT_R8G8B8A8_UNORM); 192 | } 193 | } 194 | 195 | 196 | //--------------------------------------------------------- 197 | bool SpoutSender::GetDX9compatible() 198 | { 199 | if(spout.interop.DX11format == DXGI_FORMAT_B8G8R8A8_UNORM) 200 | return true; 201 | else 202 | return false; 203 | 204 | } 205 | 206 | 207 | //--------------------------------------------------------- 208 | bool SpoutSender::SetAdapter(int index) 209 | { 210 | return spout.SetAdapter(index); 211 | } 212 | 213 | 214 | //--------------------------------------------------------- 215 | // Get current adapter index 216 | int SpoutSender::GetAdapter() 217 | { 218 | return spout.GetAdapter(); 219 | } 220 | 221 | 222 | //--------------------------------------------------------- 223 | // Get the number of graphics adapters in the system 224 | int SpoutSender::GetNumAdapters() 225 | { 226 | return spout.GetNumAdapters(); 227 | } 228 | 229 | 230 | //--------------------------------------------------------- 231 | // Get an adapter name 232 | bool SpoutSender::GetAdapterName(int index, char *adaptername, int maxchars) 233 | { 234 | return spout.GetAdapterName(index, adaptername, maxchars); 235 | } 236 | 237 | 238 | //--------------------------------------------------------- 239 | // Get the path of the host that created the sender 240 | bool SpoutSender::GetHostPath(const char *sendername, char *hostpath, int maxchars) 241 | { 242 | return spout.GetHostPath(sendername, hostpath, maxchars); 243 | } 244 | 245 | 246 | //--------------------------------------------------------- 247 | bool SpoutSender::SetVerticalSync(bool bSync) 248 | { 249 | return spout.interop.SetVerticalSync(bSync); 250 | } 251 | 252 | 253 | //--------------------------------------------------------- 254 | int SpoutSender::GetVerticalSync() 255 | { 256 | return spout.interop.GetVerticalSync(); 257 | } 258 | 259 | 260 | //------------------ debugging aid only -------------------- 261 | bool SpoutSender::SenderDebug(char *Sendername, int size) 262 | { 263 | return spout.interop.senders.SenderDebug(Sendername, size); 264 | 265 | } 266 | -------------------------------------------------------------------------------- /src/SpoutSDK/SpoutSender.h: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | SpoutSender.h 4 | 5 | 6 | Copyright (c) 2014-2017, Lynn Jarvis. All rights reserved. 7 | 8 | Redistribution and use in source and binary forms, with or without modification, 9 | are permitted provided that the following conditions are met: 10 | 11 | 1. Redistributions of source code must retain the above copyright notice, 12 | this list of conditions and the following disclaimer. 13 | 14 | 2. Redistributions in binary form must reproduce the above copyright notice, 15 | this list of conditions and the following disclaimer in the documentation 16 | and/or other materials provided with the distribution. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 19 | EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 20 | OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 21 | IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 22 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 23 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | 28 | */ 29 | #pragma once 30 | 31 | #ifndef __SpoutSender__ 32 | #define __SpoutSender__ 33 | 34 | #include "spoutSDK.h" 35 | 36 | class SPOUT_DLLEXP SpoutSender { 37 | 38 | public: 39 | 40 | SpoutSender(); 41 | ~SpoutSender(); 42 | 43 | bool CreateSender(const char *Sendername, unsigned int width, unsigned int height, DWORD dwFormat = 0); 44 | bool UpdateSender(const char *Sendername, unsigned int width, unsigned int height); 45 | void ReleaseSender(DWORD dwMsec = 0); 46 | 47 | bool SendImage(const unsigned char* pixels, unsigned int width, unsigned int height, GLenum glFormat = GL_RGBA, bool bInvert=false, GLuint HostFBO = 0); 48 | bool SendTexture(GLuint TextureID, GLuint TextureTarget, unsigned int width, unsigned int height, bool bInvert=true, GLuint HostFBO = 0); 49 | 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); 50 | 51 | bool SelectSenderPanel(const char* message = NULL); 52 | 53 | bool SetDX9(bool bDX9 = true); // set to use DirectX 9 (default is DirectX 11) 54 | bool GetDX9(); 55 | bool SetMemoryShareMode(bool bMem = true); 56 | bool GetMemoryShareMode(); 57 | bool SetCPUmode(bool bCPU = true); 58 | bool GetCPUmode(); 59 | int GetShareMode(); 60 | bool SetShareMode(int mode); 61 | void SetBufferMode(bool bActive); // Set the pbo availability on or off 62 | bool GetBufferMode(); 63 | 64 | void SetDX9compatible(bool bCompatible = true); // DirectX 11 format compatible with DirectX 9 65 | bool GetDX9compatible(); 66 | 67 | int GetNumAdapters(); // Get the number of graphics adapters in the system 68 | bool GetAdapterName(int index, char *adaptername, int maxchars); // Get an adapter name 69 | bool SetAdapter(int index = 0); // Set required graphics adapter for output 70 | int GetAdapter(); // Get the current adapter index 71 | 72 | bool GetHostPath(const char *sendername, char *hostpath, int maxchars); // The path of the host that produced the sender 73 | 74 | bool SetVerticalSync(bool bSync = true); 75 | int GetVerticalSync(); 76 | 77 | bool SenderDebug(char *Sendername, int size); 78 | 79 | Spout spout; // For access to all functions 80 | 81 | protected : 82 | 83 | }; 84 | 85 | #endif 86 | -------------------------------------------------------------------------------- /src/SpoutSDK/SpoutSenderNames.h: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | spoutSenderNames.h 4 | Spout sender management 5 | 6 | Thanks and credit to Malcolm Bechard for modifications to this class 7 | 8 | https://github.com/mbechard 9 | 10 | - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 11 | Copyright (c) 2014-2017, Lynn Jarvis. All rights reserved. 12 | 13 | Redistribution and use in source and binary forms, with or without modification, 14 | are permitted provided that the following conditions are met: 15 | 16 | 1. Redistributions of source code must retain the above copyright notice, 17 | this list of conditions and the following disclaimer. 18 | 19 | 2. Redistributions in binary form must reproduce the above copyright notice, 20 | this list of conditions and the following disclaimer in the documentation 21 | and/or other materials provided with the distribution. 22 | 23 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 24 | EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 25 | OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 26 | IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 27 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 28 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 29 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30 | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 31 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 | 33 | 34 | */ 35 | #pragma once 36 | #ifndef __spoutSenderNames__ // standard way as well 37 | #define __spoutSenderNames__ 38 | 39 | #include 40 | #include 41 | #include 42 | #include 43 | #include 44 | #include 45 | #include 46 | #include 47 | #include 48 | 49 | #include "SpoutCommon.h" 50 | #include "SpoutSharedMemory.h" 51 | 52 | #define SPOUT_WAIT_TIMEOUT 100 // 100 msec wait for events 53 | // Now replaced by a global class variable // #define MaxSenders 10 // Max for list of Sender names 54 | #define SpoutMaxSenderNameLen 256 55 | 56 | // The texture information structure that is saved to shared memory 57 | // and used for communication between senders and receivers 58 | // unsigned __int32 is used for compatibility between 32bit and 64bit 59 | // See : http://msdn.microsoft.com/en-us/library/windows/desktop/aa384203%28v=vs.85%29.aspx 60 | // This is also compatible with wyphon : 61 | // The structure is declared here so that this class is can be independent of opengl 62 | // 63 | // 03.07-16 - Use helper functions for conversion of 64bit HANDLE to unsigned __int32 64 | // and unsigned __int32 to 64bit HANDLE 65 | // https://msdn.microsoft.com/en-us/library/aa384267%28VS.85%29.aspx 66 | // in SpoutGLDXinterop.cpp and SpoutSenderNames 67 | // 68 | struct SharedTextureInfo { 69 | unsigned __int32 shareHandle; 70 | unsigned __int32 width; 71 | unsigned __int32 height; 72 | DWORD format; // Texture pixel format 73 | DWORD usage; // not used 74 | wchar_t description[128]; // Wyhon compatible description (not used) 75 | unsigned __int32 partnerId; // Wyphon id of partner that shared it with us (not unused) 76 | }; 77 | 78 | 79 | class SPOUT_DLLEXP spoutSenderNames { 80 | 81 | public: 82 | 83 | spoutSenderNames(); 84 | ~spoutSenderNames(); 85 | 86 | // public functions 87 | 88 | // ------------------------------------------------------------ 89 | // You must first register a sender name being using 90 | bool RegisterSenderName(const char* senderName); 91 | bool ReleaseSenderName(const char* senderName); 92 | bool FindSenderName (const char* Sendername); 93 | 94 | // ------------------------------------------------------------ 95 | // Functions to retrieve info about the sender set map and the senders in it 96 | bool GetSenderNames (std::set *Sendernames); 97 | int GetSenderCount(); 98 | bool GetSenderNameInfo (int index, char* sendername, int sendernameMaxSize, unsigned int &width, unsigned int &height, HANDLE &dxShareHandle); 99 | 100 | // ------------------------------------------------------------ 101 | // New for 2.005 102 | int GetMaxSenders(); 103 | void SetMaxSenders(int maxSenders); // Set the maximum number of senders in a new sender map 104 | 105 | // ------------------------------------------------------------ 106 | // Functions to read and write info to a sender memory map 107 | bool GetSenderInfo (const char* sendername, unsigned int &width, unsigned int &height, HANDLE &dxShareHandle, DWORD &dwFormat); 108 | bool SetSenderInfo (const char* sendername, unsigned int width, unsigned int height, HANDLE dxShareHandle, DWORD dwFormat); 109 | 110 | // Generic sender map info retrieval 111 | bool getSharedInfo (const char* SenderName, SharedTextureInfo* info); 112 | bool setSharedInfo (const char* SenderName, SharedTextureInfo* info); 113 | 114 | // ------------------------------------------------------------ 115 | // Functions to maintain the active sender 116 | bool SetActiveSender (const char* Sendername); 117 | bool GetActiveSender (char Sendername[SpoutMaxSenderNameLen]); 118 | bool GetActiveSenderInfo (SharedTextureInfo* info); 119 | bool FindActiveSender (char activename[SpoutMaxSenderNameLen], unsigned int &width, unsigned int &height, HANDLE &hSharehandle, DWORD &dwFormat); 120 | 121 | // ------------------------------------------------------------ 122 | // Functions to Create, Find or Update a sender without initializing DirectX or the GL/DX interop functions 123 | bool CreateSender (const char *sendername, unsigned int width, unsigned int height, HANDLE hSharehandle, DWORD dwFormat = 0); 124 | bool UpdateSender (const char *sendername, unsigned int width, unsigned int height, HANDLE hSharehandle, DWORD dwFormat = 0); 125 | bool CheckSender (const char *sendername, unsigned int &width, unsigned int &height, HANDLE &hSharehandle, DWORD &dwFormat); 126 | bool FindSender (char *sendername, unsigned int &width, unsigned int &height, HANDLE &hSharehandle, DWORD &dwFormat); 127 | // ------------------------------------------------------------ 128 | 129 | // Debug function 130 | bool SenderDebug (const char *Sendername, int size); 131 | 132 | protected: 133 | 134 | // Sender name set management 135 | bool CreateSenderSet(); 136 | bool GetSenderSet (std::set& SenderNames); 137 | 138 | // Active sender management 139 | bool setActiveSenderName (const char* SenderName); 140 | bool getActiveSenderName (char SenderName[SpoutMaxSenderNameLen]); 141 | 142 | 143 | // Goes through the full list of sender names and cleans up 144 | // any that shouldn't still be around 145 | void cleanSenderSet(); 146 | 147 | // Functions to manage shared memory map access 148 | static void readSenderSetFromBuffer(const char* buffer, std::set& SenderNames, int maxSenders); 149 | static void writeBufferFromSenderSet(const std::set& SenderNames, char *buffer, int maxSenders); 150 | 151 | SpoutSharedMemory m_senderNames; 152 | SpoutSharedMemory m_activeSender; 153 | 154 | // This should be a unordered_map of sender names ->SharedMemory 155 | // to handle multiple inputs and outputs all going through the 156 | // same spoutSenderNames class 157 | // Make this a pointer to avoid size differences between compilers 158 | // if the .dll is compiled with something different 159 | std::unordered_map* m_senders; 160 | int m_MaxSenders; // user defined maximum for the number of senders - development testing only 161 | 162 | }; 163 | 164 | #endif 165 | -------------------------------------------------------------------------------- /src/SpoutSDK/SpoutSharedMemory.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | 3 | http://www.codeproject.com/Articles/835818/Ultimate-Shared-Memory-A-flexible-class-for-interp 4 | 5 | SpoutSharedMemory.cpp 6 | 7 | Thanks and credit to Malcolm Bechard the author of this class 8 | 9 | https://github.com/mbechard 10 | 11 | - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 12 | 13 | Copyright (c) 2014-2017, Lynn Jarvis. All rights reserved. 14 | 15 | Redistribution and use in source and binary forms, with or without modification, 16 | are permitted provided that the following conditions are met: 17 | 18 | 1. Redistributions of source code must retain the above copyright notice, 19 | this list of conditions and the following disclaimer. 20 | 21 | 2. Redistributions in binary form must reproduce the above copyright notice, 22 | this list of conditions and the following disclaimer in the documentation 23 | and/or other materials provided with the distribution. 24 | 25 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 26 | EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 27 | OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 28 | IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 29 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 30 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 31 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 32 | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 33 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34 | - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 35 | 36 | */ 37 | 38 | #include "SpoutSharedMemory.h" 39 | #include 40 | #include 41 | 42 | SpoutSharedMemory::SpoutSharedMemory() 43 | { 44 | m_pBuffer = NULL; 45 | m_hMutex = NULL; 46 | m_hMap = NULL; 47 | m_pName = NULL; 48 | m_size = 0; 49 | m_lockCount = 0; 50 | } 51 | 52 | SpoutSharedMemory::~SpoutSharedMemory() 53 | { 54 | Close(); 55 | } 56 | 57 | // Create a new memory segment, or attach to an existing one 58 | SpoutCreateResult SpoutSharedMemory::Create(const char* name, int size) 59 | { 60 | DWORD err; 61 | 62 | // Don't call open twice on the same object without a Close() 63 | assert(name); 64 | assert(size); 65 | 66 | if (m_hMap != NULL) { 67 | assert(strcmp(name, m_pName) == 0); 68 | assert(m_pBuffer && m_hMutex); 69 | return SPOUT_ALREADY_CREATED; 70 | } 71 | 72 | // https://msdn.microsoft.com/en-us/library/windows/desktop/aa366537%28v=vs.85%29.aspx 73 | // Creates or opens a named or unnamed file mapping object for a specified file. 74 | // If hFile is INVALID_HANDLE_VALUE, the calling process must also specify a size 75 | // for the file mapping object in the dwMaximumSizeHigh and dwMaximumSizeLow parameters. 76 | // In this scenario, CreateFileMapping creates a file mapping object of a specified size 77 | // that is backed by the system paging file instead of by a file in the file system. 78 | 79 | m_hMap = CreateFileMappingA ( INVALID_HANDLE_VALUE, 80 | NULL, 81 | PAGE_READWRITE, 82 | 0, 83 | size, 84 | (LPCSTR)name); 85 | 86 | if (m_hMap == NULL) { 87 | return SPOUT_CREATE_FAILED; 88 | } 89 | 90 | // If the object exists before the function call, the function returns a handle 91 | // to the existing object (with its current size, not the specified size), 92 | // and GetLastError returns ERROR_ALREADY_EXISTS. 93 | err = GetLastError(); 94 | bool alreadyExists = false; 95 | if (err == ERROR_ALREADY_EXISTS) { 96 | alreadyExists = true; 97 | // The size of the map will be the same as when it was created. 98 | // 2.004 apps will have created a 10 sender map which will not be increased in size thereafter. 99 | } 100 | else { 101 | if(err != 0) printf("SpoutSharedMemory::Create - Error = %ld (0x%x)\n", err, err); 102 | } 103 | 104 | m_pBuffer = (char*)MapViewOfFile(m_hMap, FILE_MAP_ALL_ACCESS, 0, 0, 0); 105 | 106 | if (!m_pBuffer) { 107 | Close(); 108 | return SPOUT_CREATE_FAILED; 109 | } 110 | 111 | std::string mutexName; 112 | mutexName = name; 113 | mutexName += "_mutex"; 114 | 115 | m_hMutex = CreateMutexA(NULL, FALSE, mutexName.c_str()); 116 | 117 | if (!m_hMutex) { 118 | Close(); 119 | return SPOUT_CREATE_FAILED; 120 | } 121 | 122 | // Set the name and size 123 | m_pName = _strdup(name); 124 | m_size = size; 125 | 126 | return alreadyExists ? SPOUT_ALREADY_EXISTS : SPOUT_CREATE_SUCCESS; 127 | 128 | } 129 | 130 | 131 | bool SpoutSharedMemory::Open(const char* name) 132 | { 133 | // Don't call open twice on the same object without a Close() 134 | assert(name); 135 | 136 | if (m_hMap) { 137 | assert(strcmp(name, m_pName) == 0); 138 | assert(m_pBuffer && m_hMutex); 139 | return true; 140 | } 141 | 142 | m_hMap = OpenFileMappingA(FILE_MAP_ALL_ACCESS, FALSE, (LPCSTR)name); 143 | if (m_hMap == NULL) { 144 | return false; 145 | } 146 | 147 | m_pBuffer = (char*)MapViewOfFile(m_hMap, FILE_MAP_ALL_ACCESS, 0, 0, 0); 148 | if (!m_pBuffer) { 149 | Close(); 150 | return false; 151 | } 152 | 153 | std::string mutexName; 154 | mutexName = name; 155 | mutexName += "_mutex"; 156 | 157 | m_hMutex = CreateMutexA(NULL, FALSE, mutexName.c_str()); 158 | if (!m_hMutex) { 159 | Close(); 160 | return false; 161 | } 162 | 163 | m_pName = _strdup(name); 164 | m_size = 0; 165 | 166 | return true; 167 | 168 | } 169 | 170 | void SpoutSharedMemory::Close() 171 | { 172 | if (m_pBuffer) { 173 | UnmapViewOfFile((LPCVOID)m_pBuffer); 174 | m_pBuffer = NULL; 175 | } 176 | 177 | if (m_hMap) { 178 | CloseHandle(m_hMap); 179 | m_hMap = NULL; 180 | } 181 | 182 | if (m_hMutex) { 183 | CloseHandle(m_hMutex); 184 | m_hMutex = NULL; 185 | } 186 | 187 | if (m_pName) { 188 | free((void*)m_pName); 189 | m_pName = NULL; 190 | } 191 | 192 | } 193 | 194 | 195 | char* SpoutSharedMemory::Lock() 196 | { 197 | assert(m_lockCount >= 0); 198 | assert(m_hMutex); 199 | 200 | if(m_lockCount < 0) { 201 | return NULL; 202 | } 203 | 204 | if(!m_hMutex) { 205 | return NULL; 206 | } 207 | 208 | if(!m_pBuffer) { 209 | return NULL; 210 | } 211 | 212 | if (m_lockCount > 0) { 213 | assert(m_pBuffer); 214 | m_lockCount++; 215 | return m_pBuffer; 216 | } 217 | 218 | DWORD waitResult = WaitForSingleObject(m_hMutex, 67); 219 | if (waitResult != WAIT_OBJECT_0) { 220 | return NULL; 221 | } 222 | 223 | m_lockCount++; 224 | 225 | assert(m_pBuffer); 226 | return m_pBuffer; 227 | } 228 | 229 | void SpoutSharedMemory::Unlock() 230 | { 231 | 232 | assert(m_hMutex); 233 | 234 | m_lockCount--; 235 | assert(m_lockCount >= 0); 236 | 237 | if (m_lockCount == 0) { 238 | ReleaseMutex(m_hMutex); 239 | } 240 | } 241 | 242 | 243 | void SpoutSharedMemory::Debug() 244 | { 245 | /* 246 | if (m_pName) { 247 | printf("(%s) m_hMap = [%x], m_pBuffer = [%x]\n", m_pName, m_hMap, m_pBuffer); 248 | } 249 | else { 250 | printf("Shared Memory Map is not open\n"); 251 | } 252 | */ 253 | } 254 | -------------------------------------------------------------------------------- /src/SpoutSDK/SpoutSharedMemory.h: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | spoutSharedMemory.h 4 | 5 | Thanks and credit to Malcolm Bechard the author of this class 6 | 7 | https://github.com/mbechard 8 | 9 | - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 10 | Copyright (c) 2014-2017, Lynn Jarvis. All rights reserved. 11 | 12 | Redistribution and use in source and binary forms, with or without modification, 13 | are permitted provided that the following conditions are met: 14 | 15 | 1. Redistributions of source code must retain the above copyright notice, 16 | this list of conditions and the following disclaimer. 17 | 18 | 2. Redistributions in binary form must reproduce the above copyright notice, 19 | this list of conditions and the following disclaimer in the documentation 20 | and/or other materials provided with the distribution. 21 | 22 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 23 | EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 24 | OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 25 | IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 26 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 27 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 28 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | 32 | */ 33 | #pragma once 34 | 35 | #ifndef __SpoutSharedMemory_ // standard way as well 36 | #define __SpoutSharedMemory_ 37 | 38 | #include "SpoutCommon.h" 39 | #include 40 | #include 41 | #include 42 | 43 | enum SpoutCreateResult 44 | { 45 | SPOUT_CREATE_FAILED = 0, 46 | SPOUT_CREATE_SUCCESS, 47 | SPOUT_ALREADY_EXISTS, 48 | SPOUT_ALREADY_CREATED, 49 | }; 50 | 51 | class SPOUT_DLLEXP SpoutSharedMemory { 52 | public: 53 | SpoutSharedMemory(); 54 | ~SpoutSharedMemory(); 55 | 56 | 57 | // Create a new memory segment, or attach to an existing one 58 | SpoutCreateResult Create(const char* name, int size); 59 | 60 | // Opens an existing one 61 | bool Open(const char* name); 62 | void Close(); 63 | 64 | // Returns the buffer 65 | char* Lock(); 66 | void Unlock(); 67 | 68 | void Debug(); 69 | 70 | private: 71 | 72 | char* m_pBuffer; 73 | HANDLE m_hMap; 74 | HANDLE m_hMutex; 75 | 76 | int m_lockCount; 77 | 78 | const char* m_pName; 79 | int m_size; 80 | 81 | }; 82 | 83 | #endif 84 | -------------------------------------------------------------------------------- /src/displayApp.cpp: -------------------------------------------------------------------------------- 1 | //Created by Kuan-Ting Chou on 2017-04-22 2 | 3 | #include "displayApp.h" 4 | 5 | //-------------------------------------------------------------- 6 | void displayApp::setup() { 7 | 8 | ofBackground(0, 0, 0); 9 | sprintf(str, "Monitor %d app", monitorIndex); 10 | ofSetWindowTitle(str); 11 | winWidth = ofGetWidth(); 12 | winHeight = ofGetHeight(); 13 | 14 | font.loadFont("arial.ttf", mainAppPtr->fontSize); 15 | 16 | //sprintf(str, "testMsg from display app %d", appIndex); 17 | //mainAppPtr->gotMessage(ofMessage(str)); 18 | 19 | } // end setup 20 | 21 | 22 | //-------------------------------------------------------------- 23 | void displayApp::draw() { 24 | mainAppPtr->processTexWithAppIndex(appIndex); 25 | 26 | ofClear(0); 27 | if (finalTex->isAllocated()) 28 | finalTex->draw(0, 0, winWidth, winHeight); 29 | 30 | } 31 | 32 | void displayApp::gotMessage(ofMessage msg) { 33 | string& content = msg.message; 34 | } 35 | 36 | //-------------------------------------------------------------- 37 | void displayApp::update() { 38 | 39 | } 40 | 41 | void displayApp::drawFromCenter(const char* msg, float xOffset = 0, float yOffset = 0) { 42 | 43 | float msgH = font.stringHeight(msg); 44 | float msgW = font.stringWidth(msg); 45 | 46 | font.drawString(msg, (winWidth - msgW) / 2 + xOffset, (winHeight - msgH) / 2 + yOffset); 47 | 48 | } 49 | 50 | //-------------------------------------------------------------- 51 | void displayApp::exit() { 52 | 53 | } 54 | -------------------------------------------------------------------------------- /src/displayApp.h: -------------------------------------------------------------------------------- 1 | //Created by Kuan-Ting Chou on 2017-04-22 2 | 3 | #pragma once 4 | 5 | #include "ofMain.h" 6 | #include "ofxOsc.h" 7 | #include "ofApp.h" 8 | 9 | //we only display the final texture in this app. the final texture is processed(retrieve subSection and warp it) in main OF app(ofApp). 10 | class displayApp : public ofBaseApp 11 | { 12 | public: 13 | void setup(); 14 | void update(); 15 | void draw(); 16 | void exit(); 17 | void gotMessage(ofMessage msg); 18 | 19 | ofApp* mainAppPtr; //main OF app 20 | ofTexture* finalTex; //the texture for restoring final result 21 | ofTrueTypeFont font; 22 | 23 | int appIndex = -1; 24 | int monitorIndex = -1; 25 | 26 | displayApp(ofApp* mainAppPtr, 27 | int appIndex, 28 | int monitorIndex, 29 | ofTexture& finalTex) { 30 | 31 | this->mainAppPtr = mainAppPtr; 32 | this->appIndex = appIndex; 33 | this->monitorIndex = monitorIndex; 34 | this->finalTex = &finalTex; 35 | } 36 | 37 | void drawFromCenter(const char* msg, float xOffset, float yOffset); 38 | 39 | unsigned int winWidth = 0; 40 | unsigned int winHeight = 0; 41 | char str[256]; 42 | 43 | }; 44 | 45 | -------------------------------------------------------------------------------- /src/main.cpp: -------------------------------------------------------------------------------- 1 | #include "ofMain.h" 2 | #include "ofApp.h" 3 | #include "ofxXmlSettings.h" 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | /* 10 | ========================================================================= 11 | This program is free software: you can redistribute it and/or modify 12 | it under the terms of the GNU Lesser General Public License as published by 13 | the Free Software Foundation, either version 3 of the License, or 14 | (at your option) any later version. 15 | 16 | This program is distributed in the hope that it will be useful, 17 | but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 | GNU Lesser General Public License for more details. 20 | 21 | You should have received a copy of the GNU Lesser General Public License 22 | along with this program. If not, see . 23 | ========================================================================= 24 | 25 | adapted by Kuan-Ting Chou on 2017-04-22 for NTMOFA art exhibition 26 | */ 27 | 28 | //-------------------------------------------------------------- 29 | // to change options for console window (Visual Studio) 30 | // 31 | // Properties > Linker > System > Subsystem 32 | // for console : Windows (/SUBSYSTEM:CONSOLE) 33 | // 34 | // for Window : Windows (/SUBSYSTEM:WINDOWS) 35 | // 36 | // Click APPLY and OK. Then make changes to Main as below 37 | //-------------------------------------------------------------- 38 | 39 | 40 | int debugMsgSize = 40; //debug message's font size 41 | 42 | int outputMonitorInfo(); //output monitor's or display's information for configuring parameter file 43 | void trim(string &str); 44 | void PauseAndThenLeave(); //suspend application to view console output 45 | ofGLFWWindowSettings* createWinSettingForMainOfApp(int width, int height, shared_ptr sharedWin); 46 | void createSampleParamFile(const string& fileName); //create parameter template 47 | void parseParamsXml(const string& path, 48 | vector& monitorIndices, 49 | vector& subSectionIndices, 50 | vector& monitorResolution, 51 | bool& pauseAndLeave, 52 | int& appMode, 53 | bool& loadWarpSetting, 54 | bool& doWarp, 55 | float& cornerX, 56 | float& cornerY, 57 | unsigned int& overlapPixels, 58 | bool& isDebugging, 59 | string& spoutSenderName); 60 | shared_ptr createWindowInPrimaryMonitor(); 61 | 62 | // for displaying console ( debugging use ) 63 | //======================================================================== 64 | int main(int argc, // Number of strings in array argv 65 | char *argv[], // Array of command-line argument strings 66 | char *envp[]) // Array of environment variable strings 67 | { // Properties > Linker > System > Subsystem, set the field to "Windows (/SUBSYSTEM:CONSOLE)" 68 | 69 | // for hiding console 70 | //======================================================================== 71 | //int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd) { // Properties > Linker > System > Subsystem, set the field to "Windows (/SUBSYSTEM:WINDOWS)" 72 | 73 | //init and declare some local vars 74 | string line; 75 | vector monitorIndices; 76 | vector subSectionIndices; 77 | vector monitorResolution; 78 | bool pauseAndLeave = false; //pause for viewing monitor indices and size. terminiate the application after press any key. 79 | bool isDebugging = true; //show debug info 80 | int numMonIndices = 0; //number of monitors for displaying content 81 | int appMode = Demo; 82 | bool loadWarpSetting = false; //load bezier warping parameters saved before 83 | bool doWarp = true; //apply bezier warping effect or just fill up display without any warping 84 | float cornerX = 0, cornerY = 0; //the padding proportion in X and Y direction. 85 | unsigned int overlapPixels = 0; 86 | string spoutSenderName = ""; 87 | 88 | //createSampleParamFile("sampleParams.xml"); 89 | //exit(0); 90 | 91 | parseParamsXml("params.xml", 92 | monitorIndices, 93 | subSectionIndices, 94 | monitorResolution, 95 | pauseAndLeave, 96 | appMode, 97 | loadWarpSetting, 98 | doWarp, 99 | cornerX, 100 | cornerY, 101 | overlapPixels, 102 | isDebugging, 103 | spoutSenderName); 104 | 105 | int numAvailableMonitors = outputMonitorInfo(); 106 | if (numAvailableMonitors == 0) 107 | return -1; 108 | 109 | if (appMode >= NumAppMode) { 110 | return -1; 111 | } 112 | 113 | if (pauseAndLeave) 114 | PauseAndThenLeave(); 115 | 116 | auto mainWindow = createWindowInPrimaryMonitor(); 117 | 118 | auto mainApp = make_shared(appMode, 119 | doWarp, 120 | loadWarpSetting, 121 | isDebugging, 122 | debugMsgSize, 123 | overlapPixels, 124 | cornerX, 125 | cornerY, 126 | monitorResolution, 127 | subSectionIndices, 128 | monitorIndices, 129 | spoutSenderName); 130 | 131 | ofRunApp(mainWindow, mainApp); 132 | ofRunMainLoop(); 133 | 134 | } 135 | 136 | shared_ptr createWindowInPrimaryMonitor() { 137 | 138 | ofVec2f winSize(800, 600); 139 | auto settings = createWinSettingForMainOfApp(winSize.x, winSize.y, nullptr); 140 | 141 | //create first window and rest of windows would share the same opengl context with the first one 142 | return ofCreateWindow(*settings); 143 | 144 | } 145 | 146 | void createSampleParamFile(const string& path) { 147 | ofxXmlSettings xmlSettings; 148 | xmlSettings.setValue("ShowDebugInfo", 1); //1 for showing debug information, 0 for not showing it 149 | xmlSettings.setValue("MonitorIndices", "0,1");// list of monitor indices. please refer to the information output from the function "outputMonitorInfo" 150 | xmlSettings.setValue("SubSectionIndices", "0,1");// list of subsection indices. the index is used in calculate the subsection displayed on corresponding display 151 | xmlSettings.setValue("PauseAndLeave", 0); 152 | xmlSettings.setValue("AppMode", Demo); 153 | xmlSettings.setValue("LoadMapping", 0); 154 | xmlSettings.setValue("DoWarp", 1); 155 | xmlSettings.setValue("CornerX", 0.04); 156 | xmlSettings.setValue("CornerY", 0.02); 157 | xmlSettings.setValue("OverlapPixels", 210); 158 | xmlSettings.setValue("SpoutSender", "UnitySender1"); 159 | for (int i = 0; i < 2; i++) { 160 | int tagNum = xmlSettings.addTag("resolution"); 161 | xmlSettings.setValue("resolution:X", 1920, tagNum); 162 | xmlSettings.setValue("resolution:Y", 1200, tagNum); 163 | } 164 | 165 | xmlSettings.saveFile(path); 166 | } 167 | 168 | void parseParamsXml(const string& path, 169 | vector& monitorIndices, 170 | vector& subSectionIndices, 171 | vector& monitorResolution, 172 | bool& pauseAndLeave, 173 | int& appMode, 174 | bool& loadWarpSetting, 175 | bool& doWarp, 176 | float& cornerX, 177 | float& cornerY, 178 | unsigned int& overlapPixels, 179 | bool& isDebugging, 180 | string& spoutSenderName) { 181 | 182 | ofxXmlSettings xmlSettings; 183 | if (xmlSettings.loadFile(path)) { 184 | monitorIndices.clear(); 185 | auto params = ofSplitString( 186 | xmlSettings.getValue("MonitorIndices", ""), 187 | ",", true, true); 188 | for (string param : params) { 189 | monitorIndices.push_back(stoi(param)); 190 | } 191 | 192 | subSectionIndices.clear(); 193 | params = ofSplitString( 194 | xmlSettings.getValue("SubSectionIndices", ""), 195 | ",", true, true); 196 | for (string param : params) { 197 | subSectionIndices.push_back(stoi(param)); 198 | } 199 | 200 | pauseAndLeave = xmlSettings.getValue("PauseAndLeave", 0) == 1; 201 | appMode = xmlSettings.getValue("AppMode", Demo); 202 | loadWarpSetting = xmlSettings.getValue("LoadMapping", 0) == 1; 203 | doWarp = xmlSettings.getValue("DoWarp", 0) == 1; 204 | 205 | cornerX = xmlSettings.getValue("CornerX", 0.05); 206 | cornerY = xmlSettings.getValue("CornerY", 0.05); 207 | 208 | overlapPixels = xmlSettings.getValue("OverlapPixels", 0); 209 | isDebugging = xmlSettings.getValue("ShowDebugInfo", 0) == 1; 210 | spoutSenderName = xmlSettings.getValue("SpoutSender", ""); 211 | 212 | monitorResolution.clear(); 213 | int numTagsToParsed = monitorIndices.size(); 214 | for (int i = 0; i < numTagsToParsed; i++) { 215 | ofVec2f mSize( 216 | xmlSettings.getValue("resolution:X", 1920, i), 217 | xmlSettings.getValue("resolution:Y", 1200, i) 218 | ); 219 | cout << "m_i:" << monitorIndices[i] << ",w:" << mSize.x << ",h:" << mSize.y << endl; 220 | monitorResolution.push_back(mSize); 221 | } 222 | 223 | } 224 | else { 225 | cout << "cannot load the params xml file" << endl; 226 | cin.get(); 227 | exit(0); 228 | } 229 | 230 | } 231 | 232 | 233 | void trim(string &str) { 234 | std::remove(str.begin(), str.end(), ' '); 235 | std::remove(str.begin(), str.end(), '\n'); 236 | std::remove(str.begin(), str.end(), ' '); 237 | 238 | return; 239 | } 240 | 241 | void PauseAndThenLeave() { 242 | system("pause"); 243 | exit(0); 244 | } 245 | 246 | ofGLFWWindowSettings* createWinSettingForMainOfApp(int width, int height, shared_ptr sharedWin) { 247 | ofGLFWWindowSettings* settings = new ofGLFWWindowSettings(); 248 | settings->windowMode = OF_WINDOW; //in this mode, app would only run on primary display 249 | settings->resizable = false; 250 | settings->width = width; 251 | settings->height = height; 252 | settings->setPosition(ofVec2f(100, 100)); //set upper-left position 253 | settings->shareContextWith = sharedWin; //share opengl context 254 | return settings; 255 | } 256 | 257 | typedef struct monitorInfo { 258 | ofPoint phySize; 259 | ofPoint pos; 260 | GLFWmonitor *monitor; 261 | int monIndex; //index used to specify in window setting 262 | } MonInfo; 263 | 264 | //sort monitor info by its virtual monitor position in windows system 265 | bool cmp_by_posX(MonInfo a, MonInfo b) 266 | { 267 | return a.pos.x < b.pos.x; 268 | } 269 | 270 | int outputMonitorInfo() { 271 | ofAppGLFWWindow ofGLFWWin; 272 | if (glfwInit() != GL_TRUE) { 273 | cout << "fail to init glfw" << endl; 274 | exit(255); 275 | } 276 | 277 | int count; 278 | const auto monitors = glfwGetMonitors(&count); 279 | vector monInfos; 280 | //sort by it's x component of virtual desktop. 281 | for (int i = 0; i < count; i++) { 282 | auto monitor = monitors[i]; 283 | int w, h, x, y; 284 | MonInfo monInfo; 285 | glfwGetMonitorPhysicalSize(monitor, &w, &h); 286 | monInfo.phySize.x = w; 287 | monInfo.phySize.y = h; 288 | 289 | glfwGetMonitorPos(monitor, &x, &y); 290 | monInfo.pos.x = x; 291 | monInfo.pos.y = y; 292 | 293 | monInfo.monitor = monitor; 294 | monInfo.monIndex = i; 295 | monInfos.push_back(monInfo); 296 | } 297 | 298 | sort(monInfos.begin(), monInfos.end(), cmp_by_posX); 299 | 300 | for (int i = 0; i < count; i++) { 301 | MonInfo& monInfo = monInfos[i]; 302 | ofLogNotice() << "monitor index:" << monInfo.monIndex << ", physical size: " << monInfo.phySize.x << "x" << monInfo.phySize.y << "mm at " << monInfo.pos.x << ", " << monInfo.pos.y; 303 | } 304 | 305 | cout << "num available monitors:" << count << endl; 306 | 307 | return count; 308 | } 309 | -------------------------------------------------------------------------------- /src/ofApp.h: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Spout OpenFrameworks Receiver example 4 | 5 | Copyright (C) 2015-2017 Lynn Jarvis. 6 | 7 | This program is free software: you can redistribute it and/or modify 8 | it under the terms of the GNU Lesser General Public License as published by 9 | the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU Lesser General Public License for more details. 16 | 17 | You should have received a copy of the GNU Lesser General Public License 18 | along with this program. If not, see . 19 | 20 | adapted by Kuan-Ting Chou on 2017-04-22 for NTMOFA art exhibition 21 | */ 22 | #pragma once 23 | 24 | #include /* exit, EXIT_FAILURE */ 25 | #include "ofMain.h" 26 | #include "SpoutSDK/Spout.h" // Spout SDK 27 | #include "ofxOsc.h" 28 | #include "ofxBezierWarpManager.h" 29 | 30 | enum AppMode { 31 | Demo = 0, //simply display 32 | Cali = 1, //Calibration 33 | NumAppMode 34 | }; 35 | 36 | enum WinCtrlAct { 37 | floating = 0, //just show the window but it wont steal the focus 38 | select = 1, //select the certain app and output its content to main app 39 | hide = 2, //make it seems like minimized 40 | 41 | }; 42 | 43 | enum InputEventType { 44 | mPressed = 0, 45 | mDragged = 1 46 | }; 47 | 48 | class ofApp : public ofBaseApp{ 49 | public: 50 | void setup(); 51 | void update(); 52 | void draw(); 53 | void exit(); 54 | void closeApp(); 55 | void mousePressed(int x, int y, int button); 56 | void mouseDragged(int x, int y, int button); 57 | void keyPressed(int key); 58 | void gotMessage(ofMessage msg); 59 | void processTexWithAppIndex(int appIndex); 60 | 61 | bool bInitialized; // Initialization result 62 | bool setupDone = false; 63 | ofxBezierWarpManager bezManager; 64 | vector* bezWarps = nullptr; 65 | ofTexture wholeTex; //the single texture shared among all OF application 66 | 67 | ofFbo fbo; 68 | 69 | char SenderName[256] = {0}; // Sender name used by a receiver 70 | int g_Width, g_Height; // Used for checking sender size change 71 | 72 | int appMode = Demo; 73 | int numMonitorsToUse = 1; 74 | bool showDebugInfo = false; 75 | bool showMonitorIndex = false; 76 | bool loadWarpSettings = false; 77 | int selectedAppIndex = -1; //the content of selected app will be outputed to the screen where main app locate 78 | 79 | const int defaultFormat = GL_RGB; 80 | unsigned int overlapPixels = 210; 81 | const int mainAppOscPort = 10000; //the port for receiving osc message from Unity 82 | int fontSize = 32; 83 | int gridRes = 20; 84 | bool drawContent = true; 85 | bool drawGridInCali = false; 86 | float cornerOffsetX = 0.05f; 87 | float cornerOffsetY = 0.05f; 88 | 89 | ofApp(int appMode, 90 | bool toWarp, 91 | bool loadWarpSettings, 92 | bool showDebugInfo, 93 | int fontSize, 94 | unsigned int overlapPixels, 95 | float cornerX, 96 | float cornerY, 97 | vector& monitorResolution, 98 | vector& subSectionIndices, 99 | vector& monitorIndices, 100 | string& spoutSenderName) { 101 | 102 | this->loadWarpSettings = loadWarpSettings; 103 | this->showDebugInfo = showDebugInfo; 104 | this->fontSize = fontSize; 105 | this->monitorResolution = monitorResolution; 106 | this->numMonitorsToUse = monitorIndices.size(); 107 | this->subSectionIndices = subSectionIndices; 108 | this->monitorIndices = monitorIndices; 109 | this->appMode = appMode; 110 | this->noWarping = !toWarp; 111 | this->cornerOffsetX = cornerX; 112 | this->cornerOffsetY = cornerY; 113 | this->overlapPixels = overlapPixels; 114 | 115 | if(spoutSenderName.size() != 0) 116 | strncpy(SenderName, spoutSenderName.c_str(), spoutSenderName.size()); 117 | else 118 | SenderName[0] = 0; 119 | } 120 | 121 | private: 122 | void setAllWindowsForeground(); 123 | void setAllWindowsBackground(); 124 | void configSpout(); 125 | void spoutTryToReceiveTex(); 126 | void onOSCMessageReceived(ofxOscMessage &msg); 127 | void reallocateTexture(ofTexture& tex); 128 | void drawFromCenter(const char* msg, float xOffset, float yOffset); 129 | unique_ptr createWinSetting(ofVec2f& pos, int width, int height, int monitorIndex, shared_ptr sharedWin); 130 | void setupRestOfWindows(); 131 | void setAppMode(int appMode); 132 | ofFbo* createFboAndPutIntoVector(int width, int height, int format, vector& container); 133 | void showAndFocusOnConsole(); 134 | void showAndFocusOnThisAppWindow(); 135 | void passMouseEventToSelectedApp(float xRatio, float yRatio, int button, int eventType); 136 | void extractPartialFromWholeTexture(int resX, int resY, int appIndex); 137 | SpoutReceiver spoutreceiver; // A Spout receiver object 138 | ofxOscReceiver mainChannelReceiver; 139 | ofxOscMessage m; 140 | vector> windows; 141 | unsigned int winWidth = 0; 142 | unsigned int winHeight = 0; 143 | ofTrueTypeFont font; 144 | char str[256]; 145 | 146 | 147 | vector monitorResolution; 148 | vector subSectionIndices; 149 | vector monitorIndices; 150 | vector srcFbo; //list 151 | vector destFbo; //list of frame buffer that store the final result 152 | std::ostringstream oss; 153 | 154 | bool areWindowsSetup = false; 155 | 156 | bool warpInitPosRand = false; 157 | bool noWarping = false; //no bezier warping and masking 158 | HWINEVENTHOOK g_hook; 159 | RECT rcClip; 160 | RECT rcOldClip; 161 | }; 162 | -------------------------------------------------------------------------------- /src/ofxBezierWarp.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * ofxBezierWarp.cpp 3 | * 4 | * Created by Patrick Saint-Denis on 12-03-05. 5 | * 6 | * Forked by Teruaki Tsubokura on 13-08-28. 7 | * 8 | */ 9 | 10 | #include "ofxBezierWarp.h" 11 | 12 | void ofxBezierWarp::setup() { 13 | setup(800, 600, 10, 0); 14 | } 15 | 16 | void ofxBezierWarp::setup(ofFbo* _fbo, bool defaultNoRand, float cornerOffset) { 17 | this->defaultNoRand = defaultNoRand; 18 | this->cornerOffsetX = cornerOffset; 19 | this->cornerOffsetY = cornerOffset; 20 | fbo = _fbo; 21 | setup(fbo->getWidth(), fbo->getHeight(), 10, 0); 22 | } 23 | 24 | void ofxBezierWarp::setup(ofFbo * _fbo, bool defaultNoRand, float cornerOffsetX, float cornerOffsetY) 25 | { 26 | this->defaultNoRand = defaultNoRand; 27 | this->cornerOffsetX = cornerOffsetX; 28 | this->cornerOffsetY = cornerOffsetY; 29 | fbo = _fbo; 30 | setup(fbo->getWidth(), fbo->getHeight(), 10, 0); 31 | } 32 | 33 | void ofxBezierWarp::setup(int _width, int _height) { 34 | width = _width; 35 | height = _height; 36 | setup(_width, _height, 10, 0); 37 | } 38 | 39 | void ofxBezierWarp::setup(int _width, int _height, int grid, int _layer) { 40 | width = _width; 41 | height = _height; 42 | no = _layer; 43 | 44 | mouseON = 1; 45 | spritesON = 1; 46 | anchorControl = 0; 47 | setGridRes(grid); 48 | rad = 20; 49 | showGrid = false; 50 | 51 | defaults(); 52 | } 53 | 54 | void ofxBezierWarp::allocateBzPts() { 55 | if (allocatedGridRes == gridRes) 56 | return; 57 | bezSurfPoints.resize(gridRes + 1); 58 | for (int i = 0; i < gridRes + 1; i++) { 59 | bezSurfPoints[i].resize(gridRes + 1); 60 | } 61 | allocatedGridRes = gridRes; 62 | } 63 | 64 | // resets control points to default position 65 | void ofxBezierWarp::defaults() { 66 | selectedCenter = 0; 67 | for(int i = 0; i < 4; i++) { 68 | selectedSprite[i] = 0; 69 | } 70 | for(int i = 0; i < 8; i++) { 71 | selectedControlPoint[i] = 0; 72 | } 73 | 74 | float rnd_x = defaultNoRand? 0 : ofRandom(0.1, 0.6); 75 | float rnd_y = defaultNoRand? 0 : ofRandom(0.1, 0.6); 76 | 77 | // top left first then clockwise 78 | corners[0] = ofPoint(width * (0.0 + cornerOffsetX + rnd_x), height * (0.0 + cornerOffsetY + rnd_y)); 79 | corners[1] = ofPoint(width * (1 - cornerOffsetX + rnd_x), height * (0.0 + cornerOffsetY + rnd_y)); 80 | corners[2] = ofPoint(width * (1 - cornerOffsetX + rnd_x), height * (1 - cornerOffsetY + rnd_y)); 81 | corners[3] = ofPoint(width * (0.0 + cornerOffsetX + rnd_x), height * (1 - cornerOffsetY + rnd_y)); 82 | 83 | resetAnchors(); 84 | 85 | } 86 | 87 | void ofxBezierWarp::resetAnchors(){ 88 | for(int i = 0; i < 4; i++) { 89 | anchors[i * 2] = corners[i] + (corners[(i + 3) % 4] - corners[i]) / 3; 90 | anchors[i * 2 + 1] = corners[i] + (corners[(i + 1) % 4] - corners[i]) / 3; 91 | } 92 | } 93 | 94 | void ofxBezierWarp::update() { 95 | if (anchorControl == 0) { 96 | // not bezier 97 | for (int i = 0; i < 4; i++) { 98 | anchors[i * 2] = corners[i] + (corners[(i + 3) % 4] - corners[i]) / 3; 99 | anchors[i * 2 + 1] = corners[i] + (corners[(i + 1) % 4] - corners[i]) / 3; 100 | anchors[(i * 2 + 7) % 8] = corners[i] + (corners[(i + 3) % 4] - corners[i]) / 3 * 2; 101 | anchors[(i * 2 + 2) % 8] = corners[i] + (corners[(i + 1) % 4] - corners[i]) / 3 * 2; 102 | } 103 | } else { 104 | // bezier 105 | 106 | } 107 | } 108 | 109 | void ofxBezierWarp::draw() { 110 | // when fbo is null 111 | if (!fbo || !fbo->checkStatus()) return; 112 | 113 | if(spritesON == 1){ 114 | ofPushStyle(); 115 | fbo->begin(); 116 | drawGrid(gridRes, gridRes); 117 | fbo->end(); 118 | ofPopStyle(); 119 | } 120 | 121 | // draw bezier 122 | draw(fbo->getTextureReference()); 123 | 124 | } 125 | 126 | void ofxBezierWarp::draw(ofTexture& tex) { 127 | allocateBzPts(); 128 | 129 | for(int i = 0; i <= gridRes; i++) { 130 | for(int j = 0; j <= gridRes; j++) { 131 | float start_x = bezierPoint(corners[0].x, anchors[0].x, anchors[7].x, corners[3].x, (float)j/gridRes); 132 | float end_x = bezierPoint(corners[1].x, anchors[3].x, anchors[4].x, corners[2].x, (float)j/gridRes); 133 | float start_y = bezierPoint(corners[0].y, anchors[0].y, anchors[7].y, corners[3].y, (float)j/gridRes); 134 | float end_y = bezierPoint(corners[1].y, anchors[3].y, anchors[4].y, corners[2].y, (float)j/gridRes); 135 | 136 | float x = bezierPoint(start_x, ((anchors[1].x - anchors[6].x) * (1.0f - (float)j/gridRes)) + anchors[6].x, ((anchors[2].x - anchors[5].x) * (1.0f - (float)j/gridRes)) + anchors[5].x, end_x, (float)i/gridRes); 137 | float y = bezierPoint(start_y, ((anchors[1].y - anchors[6].y) * (1.0f - (float)j/gridRes)) + anchors[6].y, ((anchors[2].y - anchors[5].y) * (1.0f - (float)j/gridRes)) + anchors[5].y, end_y, (float)i/gridRes); 138 | 139 | bezSurfPoints[i][j] = ofPoint(x, y); 140 | } 141 | } 142 | for(int i = 0; i < gridRes; i++) { 143 | for(int j = 0; j < gridRes; j++) { 144 | tex.bind(); 145 | glBegin(GL_QUADS); 146 | 147 | glTexCoord2f((i) * (tex.getWidth()/gridRes), (j) * (tex.getHeight()/gridRes)); 148 | glVertex2f(bezSurfPoints[i][j].x, bezSurfPoints[i][j].y); 149 | 150 | glTexCoord2f((i+1) * (tex.getWidth()/gridRes), (j) * (tex.getHeight()/gridRes)); 151 | glVertex2f(bezSurfPoints[i+1][j].x, bezSurfPoints[i+1][j].y); 152 | 153 | glTexCoord2f((i+1) * (tex.getWidth()/gridRes), (j+1) * (tex.getHeight()/gridRes)); 154 | glVertex2f(bezSurfPoints[i+1][j+1].x, bezSurfPoints[i+1][j+1].y); 155 | 156 | glTexCoord2f((i) * (tex.getWidth()/gridRes), (j+1) * (tex.getHeight()/gridRes)); 157 | glVertex2f(bezSurfPoints[i][j+1].x, bezSurfPoints[i][j+1].y); 158 | 159 | glEnd(); 160 | tex.unbind(); 161 | } 162 | } 163 | 164 | sprites(); 165 | 166 | } 167 | 168 | 169 | void ofxBezierWarp::sprites() { 170 | if(spritesON == 1) { 171 | ofEnableSmoothing(); 172 | for(int i = 0; i < 4; i++) { 173 | if(selectedSprite[i] == 1) { 174 | if(anchorControl){ 175 | ofPoint m = ofPoint(mousePosX,mousePosY); 176 | anchors[i * 2] += m - corners[i]; 177 | anchors[i * 2 + 1] += m - corners[i]; 178 | }else{ 179 | anchors[i * 2] = corners[i] + (corners[(i + 3) % 4] - corners[i]) / 3; 180 | anchors[i * 2 + 1] = corners[i] + (corners[(i + 1) % 4] - corners[i]) / 3; 181 | anchors[(i * 2 + 7) % 8] = corners[i] + (corners[(i + 3) % 4] - corners[i]) / 3 * 2; 182 | anchors[(i * 2 + 2) % 8] = corners[i] + (corners[(i + 1) % 4] - corners[i]) / 3 * 2; 183 | } 184 | 185 | corners[i] = ofPoint(mousePosX,mousePosY); 186 | ofPushStyle(); 187 | ofEnableAlphaBlending(); 188 | ofSetColor(0, 255, 0, 150); 189 | ofFill(); 190 | ofSetLineWidth(2); 191 | ofCircle(corners[i].x, corners[i].y, rad); 192 | ofDisableAlphaBlending(); 193 | ofPopStyle(); 194 | ofPushStyle(); 195 | ofSetColor(255, 100, 0); 196 | ofNoFill(); 197 | ofSetLineWidth(2); 198 | ofCircle(corners[i].x, corners[i].y, rad); 199 | ofLine(corners[i].x, corners[i].y - (rad) - 5, corners[i].x, corners[i].y + (rad) + 5); 200 | ofLine(corners[i].x - (rad) - 5, corners[i].y, corners[i].x + (rad) + 5, corners[i].y); 201 | ofPopStyle(); 202 | } else { 203 | ofPushStyle(); 204 | ofSetColor(0, 255, 0); 205 | if(selectedCenter) ofSetColor(255, 100, 0); 206 | ofNoFill(); 207 | ofSetLineWidth(2); 208 | ofCircle(corners[i].x, corners[i].y, rad); 209 | ofLine(corners[i].x, corners[i].y - (rad) - 5, corners[i].x, corners[i].y + (rad) + 5); 210 | ofLine(corners[i].x - (rad) - 5, corners[i].y, corners[i].x + (rad) + 5, corners[i].y); 211 | ofPopStyle(); 212 | } 213 | } 214 | for(int i = 0; i < 8; i++) { 215 | if(selectedControlPoint[i] == 1) { 216 | anchors[i] = ofPoint(mousePosX,mousePosY); 217 | 218 | if(anchorControl == 1){ 219 | ofPushStyle(); 220 | ofEnableAlphaBlending(); 221 | ofSetColor(0, 255, 0, 150); 222 | ofFill(); 223 | ofSetLineWidth(2); 224 | ofCircle(anchors[i].x, anchors[i].y, rad/2); 225 | ofDisableAlphaBlending(); 226 | ofPopStyle(); 227 | 228 | ofPushStyle(); 229 | ofNoFill(); 230 | ofSetLineWidth(2); 231 | ofSetColor(255, 100, 0); 232 | ofCircle(anchors[i].x, anchors[i].y, rad/2); 233 | ofLine(corners[i/2].x, corners[i/2].y, anchors[i].x, anchors[i].y); 234 | ofPopStyle(); 235 | } 236 | 237 | ofPushStyle(); 238 | ofNoFill(); 239 | ofSetLineWidth(2); 240 | ofSetColor(0, 255, 0); 241 | if((i % 2) == 0) { 242 | if(anchorControl == 1){ 243 | ofBezier(corners[i/2].x, corners[i/2].y, anchors[(i+1) % 8].x, anchors[(i+1) % 8].y, anchors[(i+2) % 8].x, anchors[(i+2) % 8].y, corners[((i/2)+1) % 4].x, corners[((i/2)+1) % 4].y); 244 | }else{ 245 | ofLine(corners[i/2].x, corners[i/2].y, corners[((i/2)+1) % 4].x, corners[((i/2)+1) % 4].y); 246 | } 247 | } 248 | ofPopStyle(); 249 | } else { 250 | if(anchorControl == 1){ 251 | ofPushStyle(); 252 | ofNoFill(); 253 | ofSetLineWidth(2); 254 | ofSetColor(0, 255, 255); 255 | if(selectedCenter) ofSetColor(255, 100, 0); 256 | ofCircle(anchors[i].x, anchors[i].y, rad/2); 257 | ofLine(corners[i/2].x, corners[i/2].y, anchors[i].x, anchors[i].y); 258 | ofPopStyle(); 259 | } 260 | 261 | ofPushStyle(); 262 | ofNoFill(); 263 | ofSetLineWidth(2); 264 | ofSetColor(0, 255, 0); 265 | if(selectedCenter) ofSetColor(255, 100, 0); 266 | if((i % 2) == 0) { 267 | if(anchorControl == 1){ 268 | ofBezier(corners[i/2].x, corners[i/2].y, anchors[(i+1) % 8].x, anchors[(i+1) % 8].y, anchors[(i+2) % 8].x, anchors[(i+2) % 8].y, corners[((i/2)+1) % 4].x, corners[((i/2)+1) % 4].y); 269 | }else{ 270 | ofLine(corners[i/2].x, corners[i/2].y, corners[((i/2)+1) % 4].x, corners[((i/2)+1) % 4].y); 271 | } 272 | } 273 | ofPopStyle(); 274 | } 275 | } 276 | center = ofPoint(); 277 | for(int i = 0; i < 4; i++) { 278 | center += corners[i]; 279 | } 280 | center /= 4; 281 | ofPushStyle(); 282 | ofEnableAlphaBlending(); 283 | ofFill(); 284 | ofSetLineWidth(2); 285 | 286 | if(selectedCenter){ 287 | ofSetColor(255, 100, 0, 200); 288 | ofPoint m = ofPoint(mousePosX,mousePosY); 289 | for(int i = 0; i < 4; i++) { 290 | corners[i] += m - center; 291 | } 292 | for(int i = 0; i < 8; i++) { 293 | anchors[i] += m - center; 294 | } 295 | }else{ 296 | ofSetColor(0, 255, 0, 200); 297 | } 298 | ofCircle(center, rad * 2); 299 | ofDisableAlphaBlending(); 300 | ofPopStyle(); 301 | 302 | ofDisableSmoothing(); 303 | } 304 | } 305 | 306 | float ofxBezierWarp::bezierPoint(float x0, float x1, float x2, float x3, float t) { 307 | float ax, bx, cx; 308 | float ay, by, cy; 309 | float t2, t3; 310 | float x; 311 | 312 | // polynomial coefficients 313 | cx = 3.0f * (x1 - x0); 314 | bx = 3.0f * (x2 - x1) - cx; 315 | ax = x3 - x0 - cx - bx; 316 | 317 | t2 = t * t; 318 | t3 = t2 * t; 319 | x = (ax * t3) + (bx * t2) + (cx * t) + x0; 320 | 321 | return x; 322 | } 323 | 324 | //saves sprites positions 325 | void ofxBezierWarp::save() { 326 | 327 | // open and write data to the file 328 | string _name= "presets_" + ofToString(no) + ".bin"; 329 | std::fstream ofs( _name.c_str(), std::ios::out | std::ios::binary ); 330 | for(int i = 0; i < 4; i++) { 331 | ofs.write( (const char*) &corners[i].x, sizeof(corners[i].x) ); 332 | ofs.write( (const char*) &corners[i].y, sizeof(corners[i].y) ); 333 | } 334 | for(int i = 0; i < 8; i++) { 335 | ofs.write( (const char*) &anchors[i].x, sizeof(anchors[i].x) ); 336 | ofs.write( (const char*) &anchors[i].y, sizeof(anchors[i].y) ); 337 | } 338 | ofs.close(); 339 | } 340 | 341 | //reloads last saved sprites positions 342 | void ofxBezierWarp::load() { 343 | // re-open the file, but this time to read from it 344 | string _name= "presets_" + ofToString(no) + ".bin"; 345 | std::fstream ifs( _name.c_str(), std::ios::in | std::ios::binary ); 346 | for(int i = 0; i < 4; i++) { 347 | ifs.read( (char*) &corners[i].x, sizeof(corners[i].x) ); 348 | ifs.read( (char*) &corners[i].y, sizeof(corners[i].y) ); 349 | } 350 | for(int i = 0; i < 8; i++) { 351 | ifs.read( (char*) &anchors[i].x, sizeof(anchors[i].x) ); 352 | ifs.read( (char*) &anchors[i].y, sizeof(anchors[i].y) ); 353 | } 354 | ifs.close(); 355 | ofLogNotice("ofxBezierWarp::load() : \n" 356 | + ofToString(corners[0].x) + "," + ofToString(corners[0].y) + "\n" 357 | + ofToString(corners[1].x) + "," + ofToString(corners[1].y) + "\n" 358 | + ofToString(corners[2].x) + "," + ofToString(corners[2].y) + "\n" 359 | + ofToString(corners[3].x) + "," + ofToString(corners[3].y) + "\n" 360 | ); 361 | }; 362 | 363 | //handles mouse events 1 364 | void ofxBezierWarp::mousePressed(int x, int y, int button) { 365 | if(mouseON == 1){ 366 | mousePosX = x; 367 | mousePosY = y; 368 | 369 | selectedCenter = 0; 370 | for(int i = 0; i < 4; i++) { 371 | selectedSprite[i] = 0; 372 | } 373 | for(int i = 0; i < 8; i++) { 374 | selectedControlPoint[i] = 0; 375 | } 376 | 377 | if(spritesON == 1) { 378 | for(int i = 0; i < 4; i++) { 379 | // 380 | if(selectedSprite[i] == 0) { 381 | if((x > corners[i].x - (rad)) && (x < corners[i].x + (rad)) && (y > corners[i].y - (rad)) && (y < corners[i].y + (rad))) { 382 | if(button == 0){ 383 | selectedSprite[i] = 1; 384 | mousePosX = corners[i].x; 385 | mousePosY = corners[i].y; 386 | }else{ 387 | if(anchorControl == 0){ 388 | anchorControl = 1; 389 | }else{ 390 | anchorControl = 0; 391 | } 392 | } 393 | } 394 | } 395 | } 396 | for(int i = 0; i < 8; i++) { 397 | // 398 | if(selectedControlPoint[i] == 0 && anchorControl == 1) { 399 | if((x > anchors[i].x - (rad/2)) && (x < anchors[i].x + (rad/2)) && (y > anchors[i].y - (rad/2)) && (y < anchors[i].y + (rad/2))) { 400 | selectedControlPoint[i] = 1; 401 | mousePosX = anchors[i].x; 402 | mousePosY = anchors[i].y; 403 | } 404 | } 405 | } 406 | if(selectedCenter == 0){ 407 | if((x > center.x - (rad*2)) && (x < center.x + (rad*2)) && (y > center.y - (rad*2)) && (y < center.y + (rad*2))) { 408 | if(button == 0){ 409 | selectedCenter = 1; 410 | mousePosX = center.x; 411 | mousePosY = center.y; 412 | }else{ 413 | if(anchorControl == 0){ 414 | anchorControl = 1; 415 | }else{ 416 | anchorControl = 0; 417 | } 418 | } 419 | } 420 | } 421 | } 422 | } 423 | } 424 | 425 | //handles mouse events 3 426 | void ofxBezierWarp::mouseDragged(int x, int y, int button) { 427 | if(mouseON == 1){ 428 | mousePosX = x; 429 | mousePosY = y; 430 | } 431 | } 432 | 433 | //handles keyboard events 434 | void ofxBezierWarp::keyPressed(int key) { 435 | switch (key) { 436 | case OF_KEY_LEFT: 437 | mousePosX--; 438 | break; 439 | case OF_KEY_RIGHT: 440 | mousePosX++; 441 | break; 442 | case OF_KEY_UP: 443 | mousePosY--; 444 | break; 445 | case OF_KEY_DOWN: 446 | mousePosY++; 447 | break; 448 | } 449 | 450 | } 451 | 452 | bool ofxBezierWarp::isSelected(){ 453 | int _sum = 0; 454 | _sum += selectedCenter; 455 | for (int i=0; i<4; i++) { 456 | _sum += selectedSprite[i]; 457 | } 458 | if(_sum > 0){ 459 | return true; 460 | }else{ 461 | return false; 462 | } 463 | } 464 | 465 | void ofxBezierWarp::setCanvasSize(int _width, int _height){ 466 | if(_width > 0 && _height > 0){ 467 | width = _width; 468 | height = _height; 469 | }else{ 470 | ofLogWarning("[ofxBezierWarp] setCanvasSize : Width and height must be higher than 0."); 471 | } 472 | } 473 | 474 | void ofxBezierWarp::setWarpResolution(int _res){ 475 | if(_res > 0 && _res < 100){ 476 | setGridRes(_res); 477 | }else{ 478 | ofLogWarning("[ofxBezierWarp] setGridResolution : Resolution must be between 0 - 100."); 479 | } 480 | } 481 | 482 | void ofxBezierWarp::setGridVisible(bool _visible){ 483 | showGrid = _visible; 484 | spritesON = showGrid; 485 | } 486 | 487 | void ofxBezierWarp::drawGrid(float _stepX, float _stepY) 488 | { 489 | float w = fbo->getWidth(); 490 | float h = fbo->getHeight(); 491 | 492 | float perX = w / _stepX; 493 | float perY = h / _stepY; 494 | 495 | ofPushStyle(); 496 | ofEnableBlendMode(OF_BLENDMODE_ADD); 497 | for( int y = 0; y <= h; y+=perY){ 498 | ofSetColor(255, 255, 255, 100); 499 | ofSetLineWidth(4); 500 | ofLine(0, y, w, y); 501 | } 502 | for( int x = 0; x <= w; x+=perX){ 503 | ofSetColor(255, 255, 255, 100); 504 | ofSetLineWidth(4); 505 | ofLine(x, 0, x, h); 506 | } 507 | ofPopStyle(); 508 | } -------------------------------------------------------------------------------- /src/ofxBezierWarp.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ofxBezierWarp.h 3 | * 4 | * Created by Patrick Saint-Denis on 12-03-05. 5 | * A Bezier Warp made of multiple homographies 6 | * 7 | * Forked by Teruaki Tsubokura on 13-08-28. 8 | * 9 | */ 10 | 11 | #pragma once 12 | 13 | #include "ofMain.h" 14 | 15 | class ofxBezierWarp{ 16 | 17 | public: 18 | int no; 19 | int layer; 20 | ofFbo *fbo; 21 | ofPoint corners[4]; 22 | ofPoint anchors[8]; 23 | ofPoint center; 24 | float cornerOffsetX = 0; 25 | float cornerOffsetY = 0; 26 | 27 | int mouseON, spritesON, anchorControl; 28 | int selectedSprite[4], selectedControlPoint[8], selectedCenter; 29 | bool showGrid; 30 | 31 | int edgeCornerIndices[4][2] = { 32 | {0,3}, 33 | {0,1}, 34 | {1,2}, 35 | {2,3} 36 | }; 37 | 38 | ofxBezierWarp() { 39 | no = 0; 40 | layer = 0; 41 | gridRes = 0; 42 | prev_gridRes = 0; 43 | } 44 | 45 | void setup(ofFbo* _fbo, bool defaultNoRand, float cornerOffset); 46 | void setup(ofFbo* _fbo, bool defaultNoRand, float cornerOffsetX, float cornerOffsetY); 47 | void update(); // if you need 48 | void draw(); 49 | void draw(ofTexture& texture); 50 | void defaults(); 51 | void setGridRes(int gridRes) { 52 | this->prev_gridRes = this->gridRes; 53 | this->gridRes = gridRes; 54 | } 55 | 56 | int getGridRes() { 57 | return gridRes; 58 | } 59 | 60 | void resetAnchors(); 61 | void save(); 62 | void load(); 63 | void mousePressed(int x, int y, int button); 64 | void mouseDragged(int x, int y, int button); 65 | void keyPressed(int clef); 66 | bool isSelected(); 67 | 68 | void setCanvasSize(int _width, int _height); 69 | void setWarpResolution(int _res); 70 | void setGridVisible(bool _visible); 71 | bool bGradient; 72 | bool defaultNoRand; 73 | private: 74 | int mousePosX, mousePosY, rad; 75 | float width, height; 76 | int gridRes; 77 | int prev_gridRes; 78 | void setup(); 79 | void setup(int _width, int _height); 80 | void setup(int _width, int _height, int grid, int _layer); 81 | 82 | void sprites(); 83 | float bezierPoint(float x0, float x1, float x2, float x3, float t); 84 | void drawGrid(float _stepX, float _stepY); 85 | 86 | std::vector> bezSurfPoints; 87 | void allocateBzPts(); 88 | int allocatedGridRes; 89 | }; -------------------------------------------------------------------------------- /src/ofxBezierWarpManager.cpp: -------------------------------------------------------------------------------- 1 | #include "ofxBezierWarpManager.h" 2 | 3 | //-------------------------------------------------------------- 4 | ofxBezierWarpManager::ofxBezierWarpManager(){ 5 | bBezierGuide = true; 6 | } 7 | 8 | //-------------------------------------------------------------- 9 | void ofxBezierWarpManager::setup(int _resolution){ 10 | warpResolution = _resolution; 11 | } 12 | 13 | //-------------------------------------------------------------- 14 | void ofxBezierWarpManager::setWarpResolution(int _resolution){ 15 | warpResolution = _resolution; 16 | } 17 | 18 | //-------------------------------------------------------------- 19 | void ofxBezierWarpManager::update() { 20 | // update bezier 21 | for (int i = 0; i < bezierList.size(); i++) { 22 | bezierList[i].update(); 23 | } 24 | } 25 | 26 | //-------------------------------------------------------------- 27 | void ofxBezierWarpManager::draw(){ 28 | // draw bezier 29 | for (int i = 0; i < bezierList.size(); i++) { 30 | bezierList[i].draw(); 31 | } 32 | } 33 | 34 | //-------------------------------------------------------------- 35 | void ofxBezierWarpManager::keyPressed(int key){ 36 | for( int i = 0; i < bezierList.size(); i++){ 37 | bezierList[i].keyPressed(key); 38 | } 39 | } 40 | 41 | //-------------------------------------------------------------- 42 | void ofxBezierWarpManager::keyReleased(int key){ 43 | 44 | } 45 | 46 | 47 | //-------------------------------------------------------------- 48 | void ofxBezierWarpManager::mouseDragged(int x, int y, int button){ 49 | for( int i = 0; i < bezierList.size(); i++){ 50 | bezierList[i].mouseDragged(x, y, button); 51 | } 52 | } 53 | 54 | //-------------------------------------------------------------- 55 | void ofxBezierWarpManager::mousePressed(int x, int y, int button){ 56 | for( int i = 0; i < bezierList.size(); i++){ 57 | bezierList[i].mousePressed(x, y, button); 58 | } 59 | } 60 | 61 | //-------------------------------------------------------------- 62 | ofxBezierWarp& ofxBezierWarpManager::addFbo(ofFbo* _fbo, bool defaultNoRand, float cornerOffset){ 63 | return addFbo(_fbo, defaultNoRand, cornerOffset, cornerOffset); 64 | } 65 | 66 | ofxBezierWarp& ofxBezierWarpManager::addFbo(ofFbo * _fbo, bool defaultNoRand, float cornerOffsetX, float cornerOffsetY) 67 | { 68 | cout << "[ofxBezierWarpManager] addFbo(ofFbo* _fbo)" << endl; 69 | ofxBezierWarp* _bezier = new ofxBezierWarp(); 70 | _bezier->setup(_fbo, defaultNoRand, cornerOffsetX, cornerOffsetY); 71 | _bezier->setWarpResolution(warpResolution); 72 | bezierList.push_back(*_bezier); 73 | return bezierList.back(); 74 | } 75 | 76 | //-------------------------------------------------------------- 77 | void ofxBezierWarpManager::removeFbo(){ 78 | bezierList.pop_back(); 79 | } 80 | 81 | //-------------------------------------------------------------- 82 | void ofxBezierWarpManager::clear(){ 83 | bezierList.clear(); 84 | //maskList.clear(); 85 | } 86 | 87 | //-------------------------------------------------------------- 88 | void ofxBezierWarpManager::saveSettings(){ 89 | cout << "save warp settings" << endl; 90 | //screen settings 91 | ofxXmlSettings _xml = ofxXmlSettings(); 92 | int lastTagNumber; 93 | // screen 94 | for (int m = 0; m < bezierList.size(); m++) { 95 | lastTagNumber = _xml.addTag("SCREEN"); 96 | _xml.setValue("SCREEN:IS_BEZIER", (int)bezierList[m].anchorControl, lastTagNumber); 97 | _xml.setValue("SCREEN:RESOLUTION", (int)bezierList[m].getGridRes(), lastTagNumber); 98 | if( _xml.pushTag("SCREEN", lastTagNumber) ){ 99 | for (int c = 0; c < 4; c++) { 100 | int tagNum = _xml.addTag("CORNER"); 101 | _xml.setValue("CORNER:X", (int)bezierList[m].corners[c].x, tagNum); 102 | _xml.setValue("CORNER:Y", (int)bezierList[m].corners[c].y, tagNum); 103 | } 104 | for (int a = 0; a < 8; a++) { 105 | int tagNum = _xml.addTag("ANCHOR"); 106 | _xml.setValue("ANCHOR:X", (int)bezierList[m].anchors[a].x, tagNum); 107 | _xml.setValue("ANCHOR:Y", (int)bezierList[m].anchors[a].y, tagNum); 108 | } 109 | _xml.popTag(); 110 | } 111 | } 112 | 113 | _xml.saveFile("BezierWarpManager_settings.xml"); 114 | } 115 | 116 | //-------------------------------------------------------------- 117 | void ofxBezierWarpManager::loadSettings(){ 118 | ofxXmlSettings _xml; 119 | if( _xml.loadFile("BezierWarpManager_settings.xml") ){ 120 | cout << "[BezierWarpManager_settings.xml] loaded!" << endl; 121 | }else{ 122 | cout << "unable to load [BezierWarpManager_settings.xml] check data/ folder" << endl; 123 | return; 124 | } 125 | 126 | int numMovieTags = _xml.getNumTags("SCREEN"); 127 | 128 | // screen 129 | for(int n = bezierList.size(); n < numMovieTags; n++){ 130 | // add bezier 131 | ofxBezierWarp _bezier; 132 | bezierList.push_back(_bezier); 133 | } 134 | for(int m = 0; m < numMovieTags; m++){ 135 | _xml.pushTag("SCREEN", m); 136 | ofLog(OF_LOG_NOTICE," SCREEN:" + ofToString(m)); 137 | 138 | bezierList[m].anchorControl = _xml.getValue("IS_BEZIER", 0); 139 | bezierList[m].setGridRes(_xml.getValue("RESOLUTION", 10)); 140 | ofLog(OF_LOG_NOTICE," IS_BEZIER:" + ofToString(bezierList[m].anchorControl)); 141 | ofLog(OF_LOG_NOTICE," RESOLUTION:" + ofToString(bezierList[m].getGridRes())); 142 | int numCornerTags = _xml.getNumTags("CORNER"); 143 | for(int i = 0; i < numCornerTags; i++){ 144 | int x = _xml.getValue("CORNER:X", 0, i); 145 | int y = _xml.getValue("CORNER:Y", 0, i); 146 | bezierList[m].corners[i].x = x; 147 | bezierList[m].corners[i].y = y; 148 | ofLog(OF_LOG_NOTICE," CORNER:" + ofToString(i) + " x:"+ ofToString(x) + " y:" + ofToString(y)); 149 | } 150 | int numAnchorTags = _xml.getNumTags("ANCHOR"); 151 | for(int i = 0; i < numAnchorTags; i++){ 152 | int x = _xml.getValue("ANCHOR:X", 0, i); 153 | int y = _xml.getValue("ANCHOR:Y", 0, i); 154 | bezierList[m].anchors[i].x = x; 155 | bezierList[m].anchors[i].y = y; 156 | ofLog(OF_LOG_NOTICE," ANCHOR:" + ofToString(i) + " x:"+ ofToString(x) + " y:" + ofToString(y)); 157 | } 158 | _xml.popTag(); 159 | } 160 | } 161 | 162 | //-------------------------------------------------------------- 163 | void ofxBezierWarpManager::setGuideVisible(bool _visible, int _bezierNum){ 164 | if(_bezierNum <= -1){ 165 | bBezierGuide = _visible; 166 | for( int i = 0; i < bezierList.size(); i++){ 167 | bezierList[i].setGridVisible(bBezierGuide); 168 | } 169 | }else{ 170 | for( int i = 0; i < bezierList.size(); i++){ 171 | if(i == _bezierNum) bezierList[i].setGridVisible(_visible); 172 | } 173 | } 174 | } 175 | 176 | //-------------------------------------------------------------- 177 | void ofxBezierWarpManager::toggleGuideVisible(int _bezierNum){ 178 | 179 | if (_bezierNum <= -1) { 180 | bBezierGuide = !bBezierGuide; 181 | for (int i = 0; i < bezierList.size(); i++) { 182 | bezierList[i].setGridVisible(bBezierGuide); 183 | } 184 | } 185 | else { 186 | for (int i = 0; i < bezierList.size(); i++) { 187 | if (i == _bezierNum) bezierList[i].setGridVisible(!bezierList[i].showGrid); 188 | } 189 | } 190 | } 191 | -------------------------------------------------------------------------------- /src/ofxBezierWarpManager.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ofxBezierWarpManager.h 3 | * 4 | * Created by Teruaki Tsubokura on 14-10-15. 5 | * Manager of multiple Bezier Warp. 6 | * 7 | */ 8 | #pragma once 9 | 10 | #include "ofMain.h" 11 | #include "ofxBezierWarp.h" 12 | #include "ofxXmlSettings.h" 13 | 14 | class ofxBezierWarpManager{ 15 | 16 | public: 17 | ofxBezierWarpManager(); 18 | 19 | void setup(int _resolution = 10); 20 | void setWarpResolution(int _resolution); 21 | void update(); // if you need 22 | void draw(); 23 | 24 | void keyPressed(int key); 25 | void keyReleased(int key); 26 | void mouseDragged(int x, int y, int button); 27 | void mousePressed(int x, int y, int button); 28 | 29 | ofxBezierWarp& addFbo(ofFbo* _fbo, bool defaultNoRand, float cornerOffset); 30 | ofxBezierWarp& addFbo(ofFbo* _fbo, bool defaultNoRand, float cornerOffsetX, float cornerOffsetY); 31 | void removeFbo(); 32 | void clear(); 33 | 34 | void saveSettings(); 35 | void loadSettings(); 36 | 37 | void setGuideVisible(bool _visible, int _bezierNum = -1); 38 | void toggleGuideVisible(int _bezierNum = -1); 39 | 40 | vector bezierList; 41 | //vector maskList; 42 | 43 | int warpResolution; 44 | bool bBezierGuide; 45 | bool bGradient; 46 | ofImage gradientImg; 47 | ofFbo gradientFbo; 48 | ofFbo blackFbo; 49 | }; 50 | --------------------------------------------------------------------------------