Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

[Work in progress] [macOS] Syphon output #63

Closed
wants to merge 6 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ include(SDL2Target)
include(dependencies_check.cmake)

add_subdirectory(src)
add_subdirectory(src/glad)

if(ENABLE_TESTING)
add_subdirectory(test)
Expand Down
10 changes: 10 additions & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ add_executable(projectMSDL WIN32
RenderLoop.h
SDLRenderingWindow.h
SDLRenderingWindow.cpp
TextureSharing.h
TextureSharing.mm
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you check that this still compiles on Windows and Linux, as those OSes don't have Obj-C++ support?

Because on my Linux machine, I get an error configuring the project:

Cannot get compiler information:
	Compiler exited with error code 1: /usr/bin/c++ -xobjective-c++ -DAUDIO_IMPL_HEADER=\"AudioCaptureImpl_SDL.h\" -DPOCO_ENABLE_CPP11 -DPOCO_ENABLE_CPP14 -DPOCO_HAVE_FD_EPOLL -DPOCO_OS_FAMILY_UNIX -DPOCO_STATIC -DPROJECTMSDL_VERSION=\"2.0.0\" -DPROJECTM_STATIC_DEFINE -DXML_DTD -D_DEBUG -D_FILE_OFFSET_BITS=64 -D_LARGEFILE64_SOURCE -D_REENTRANT -D_THREAD_SAFE -D_XOPEN_SOURCE=500 -isystem/home/kai/Dev/install/projectM-latest-shared/include -isystem/home/kai/Dev/install/Poco/static/include -isystem/home/kai/Dev/install/libSDL/64/include -isystem/home/kai/Dev/install/libSDL/64/include/SDL2 -g -std=gnu++14 -fPIE -fopenmp -fpch-preprocess -v -dD -E
	Using built-in specs.
	COLLECT_GCC=/usr/bin/c++
	Target: x86_64-pc-linux-gnu
	Configured with: /var/tmp/portage/sys-devel/gcc-12.3.0/work/gcc-12.3.0/configure --host=x86_64-pc-linux-gnu --build=x86_64-pc-linux-gnu --prefix=/usr --bindir=/usr/x86_64-pc-linux-gnu/gcc-bin/12 --includedir=/usr/lib/gcc/x86_64-pc-linux-gnu/12/include --datadir=/usr/share/gcc-data/x86_64-pc-linux-gnu/12 --mandir=/usr/share/gcc-data/x86_64-pc-linux-gnu/12/man --infodir=/usr/share/gcc-data/x86_64-pc-linux-gnu/12/info --with-gxx-include-dir=/usr/lib/gcc/x86_64-pc-linux-gnu/12/include/g++-v12 --with-python-dir=/share/gcc-data/x86_64-pc-linux-gnu/12/python --enable-languages=c,c++,fortran --enable-obsolete --enable-secureplt --disable-werror --with-system-zlib --enable-nls --without-included-gettext --disable-libunwind-exceptions --enable-checking=release --with-bugurl=https://bugs.gentoo.org/ --with-pkgversion='Gentoo 12.3.0 p2' --with-gcc-major-version-only --disable-esp --enable-libstdcxx-time --enable-lto --disable-libstdcxx-pch --enable-shared --enable-threads=posix --enable-__cxa_atexit --enable-clocale=gnu --enable-multilib --with-multilib-list=m32,m64 --disable-fixed-point --enable-targets=all --enable-libgomp --disable-libssp --disable-libada --disable-cet --disable-systemtap --disable-valgrind-annotations --disable-vtable-verify --disable-libvtv --without-zstd --without-isl --enable-default-pie --enable-default-ssp
	Thread model: posix
	Supported LTO compression algorithms: zlib
	gcc version 12.3.0 (Gentoo 12.3.0 p2) 
	c++: error: language objective-c++ not recognized
	c++: error: language objective-c++ not recognized

)

if(CMAKE_SYSTEM_NAME STREQUAL "Windows")
Expand Down Expand Up @@ -46,12 +48,20 @@ target_compile_definitions(projectMSDL
PROJECTMSDL_VERSION="${PROJECT_VERSION}"
)

if(APPLE)
include(fetch_syphon.cmake)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ObjC++")
find_library(SYPHON Syphon ${PROJECT_SOURCE_DIR})
target_link_libraries(projectMSDL PRIVATE ${SYPHON})
endif()

target_link_libraries(projectMSDL
PRIVATE
libprojectM::playlist
Poco::Util
SDL2::SDL2$<$<STREQUAL:${SDL2_LINKAGE},static>:-static>
SDL2::SDL2main
glad
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is glad required for all platforms, even macOS, when not building Syphon support? I'd suggest making All the Syphon-specific code, libraries etc. dependent on a specific ENABLE_SYPHON option or similar, then check for all required dependencies and requirements and give the user proper feedback of something's wrong or missing.

Also, use cmake_dependent_option() to only show the option to devs if the build is executed on macOS, as it doesn't make sense or works on any other platform.

)

if(MSVC)
Expand Down
4 changes: 4 additions & 0 deletions src/ProjectMSDLApplication.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,10 @@ void ProjectMSDLApplication::defineOptions(Poco::Util::OptionSet& options)
false, "<number>", true)
.binding("projectM.beatSensitivity", _commandLineOverrides));

options.addOption(Option("textureSharingEnabled", "", "Syphon texture sharing enabled.",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here - only provide the command-line option in builds which actually have Syphon support built-in. for any other build, it would confuse users.

false, "<0/1>", true)
.binding("projectM.textureSharingEnabled", _commandLineOverrides));

}

int ProjectMSDLApplication::main(POCO_UNUSED const std::vector<std::string>& args)
Expand Down
12 changes: 10 additions & 2 deletions src/ProjectMWrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,11 @@ void ProjectMWrapper::initialize(Poco::Util::Application& app)
projectm_playlist_add_path(_playlist, presetPath.c_str(), true, false);
projectm_playlist_sort(_playlist, 0, projectm_playlist_size(_playlist), SORT_PREDICATE_FILENAME_ONLY, SORT_ORDER_ASCENDING);
}

_textureSharingEnabled = _config->getBool("textureSharingEnabled", false);
if (_textureSharingEnabled) {
_textureSharing.initialize(canvasWidth, canvasHeight);
}
}
}

Expand Down Expand Up @@ -88,15 +93,18 @@ projectm_playlist_handle ProjectMWrapper::Playlist() const
int ProjectMWrapper::TargetFPS()
{
return _config->getInt("fps", 60);
;
}

void ProjectMWrapper::RenderFrame() const
void ProjectMWrapper::RenderFrame()
{
glClearColor(0.0, 0.0, 0.0, 0.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

projectm_opengl_render_frame(_projectM);

if (_textureSharingEnabled) {
_textureSharing.publish();
}
}

void ProjectMWrapper::DisplayInitialPreset()
Expand Down
9 changes: 7 additions & 2 deletions src/ProjectMWrapper.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@

#include <memory>

#include "TextureSharing.h"

class ProjectMWrapper : public Poco::Util::Subsystem
{
public:
Expand All @@ -30,7 +32,7 @@ class ProjectMWrapper : public Poco::Util::Subsystem
/**
* Renders a single projectM frame.
*/
void RenderFrame() const;
void RenderFrame();

int TargetFPS();

Expand All @@ -44,12 +46,15 @@ class ProjectMWrapper : public Poco::Util::Subsystem

void uninitialize() override;


protected:
Poco::AutoPtr<Poco::Util::AbstractConfiguration> _config; //!< View of the "projectM" configuration subkey.

projectm_handle _projectM{nullptr}; //!< Pointer to the projectM instance used by the application.
projectm_playlist_handle _playlist{nullptr}; //!< Pointer to the projectM playlist manager instance.

TextureSharing _textureSharing;

bool _textureSharingEnabled = false;

Poco::Logger& _logger{Poco::Logger::get("SDLRenderingWindow")}; //!< The class logger.
};
4 changes: 3 additions & 1 deletion src/SDLRenderingWindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

#include <Poco/Util/Application.h>

#include <SDL2/SDL_opengl.h>
#include <glad/glad.h>

const char* SDLRenderingWindow::name() const
{
Expand Down Expand Up @@ -247,6 +247,8 @@ void SDLRenderingWindow::CreateSDLWindow()
throw Poco::Exception(errorMessage);
}

gladLoadGLLoader(SDL_GL_GetProcAddress);

SDL_SetWindowTitle(_renderingWindow, "projectM");
SDL_GL_MakeCurrent(_renderingWindow, _glContext);
SDL_GL_SetSwapInterval(_config->getBool("waitForVerticalSync", true) ? 1 : 0);
Expand Down
35 changes: 35 additions & 0 deletions src/TextureSharing.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#pragma once

#include <SDL2/SDL.h>

#include <Poco/Logger.h>

#include <glad/glad.h>

#include <Syphon/Syphon.h>
/**
* @brief Class to help with texture sharing to other apps via Syphon/Spout.
*/
class TextureSharing
{
public:
/**
* @brief Performs initialization of texture sharing.
*/
void initialize(int width, int height);

/**
* @brief Publishes current texture.
*/
void publish();

protected:
void createFramebuffer(int width, int height);

Poco::Logger& _logger{Poco::Logger::get("TextureSharing")}; //!< The class logger.

GLuint _shareFramebuffer, _shareTexture;
int _width, _height;

SyphonOpenGLServer* _syphonServer = NULL;
};
51 changes: 51 additions & 0 deletions src/TextureSharing.mm
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
#include "TextureSharing.h"

#include <Poco/Util/Application.h>

void TextureSharing::createFramebuffer(int width, int height)
{
glGenFramebuffers(1, &_shareFramebuffer);
glBindFramebuffer(GL_FRAMEBUFFER, _shareFramebuffer);

glGenTextures(1, &_shareTexture);
glBindTexture(GL_TEXTURE_2D, _shareTexture);

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, _shareTexture, 0);

if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
{
poco_error_f1(_logger, "Failed to initialize texture sharing framebuffer: %s", std::string(SDL_GetError()));
return;
}

glBindFramebuffer(GL_FRAMEBUFFER, 0);
}

void TextureSharing::initialize(int width, int height)
{
// Syphon setup
CGLContextObj cgl_ctx = CGLGetCurrentContext();
_syphonServer = [[SyphonOpenGLServer alloc] initWithName:nil context:cgl_ctx options:nil];

_width = width;
_height = height;

createFramebuffer(_width, _height);
}

void TextureSharing::publish()
{
glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, _shareFramebuffer);

glBlitFramebuffer(0, 0, _width, _height, 0, 0, _width, _height, GL_COLOR_BUFFER_BIT, GL_LINEAR);

[_syphonServer publishFrameTexture:_shareTexture textureTarget:GL_TEXTURE_2D imageRegion:NSMakeRect(0, 0, _width, _height) textureDimensions:NSMakeSize(_width, _height) flipped:NO];

glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
14 changes: 14 additions & 0 deletions src/fetch_syphon.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@

# Download Syphon framework
file(DOWNLOAD
https://github.com/Syphon/Syphon-Framework/releases/download/5/Syphon.SDK.5.zip
Syphon.zip
EXPECTED_HASH SHA256=8a8993da2d39f84b7fbd9ad0071a8f300e947635a52c6c5a521c88df5ccb882f
TLS_VERIFY true
)

file(ARCHIVE_EXTRACT
INPUT Syphon.zip
DESTINATION .
PATTERNS "Syphon SDK 5/Syphon.framework/"
)
4 changes: 4 additions & 0 deletions src/glad/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
project(Glad)

add_library(glad include/glad/glad.h src/glad.c)
target_include_directories(glad PUBLIC include/)
Loading