Commit a06d5966 authored by Jan Möbius's avatar Jan Möbius

Merge branch 'cleanup' into 'master'

Cleanup

See merge request !186
parents 7048b62e 69ed7c0f
#include "CommandLineParser.hh"
#include <iostream>
#include <OpenFlipper/common/GlobalOptions.hh>
#include <OpenFlipper/BasePlugin/PluginFunctionsCore.hh>
// Parse all options
CommandLineParseResult parseCommandLine(QCommandLineParser &parser, QString *errorMessage) {
#ifndef WIN32
#ifndef __APPLE__
//workaround for bug with stereo mode on Qt5.7.0 and Qt5.7.1 on Linux
int QtVersionMajor, QtVersionMinor, QtVersionPatch;
if(sscanf(qVersion(),"%1d.%1d.%1d",&QtVersionMajor, &QtVersionMinor, &QtVersionPatch) == 3)
{
if(QtVersionMajor == 5 && QtVersionMinor >= 7)
{
if(QtVersionPatch < 2)
{
std::cerr << "The used Qt Version does not support stereo mode. Disabling stereo mode." << std::endl;
OpenFlipper::Options::stereo(false);
}
else
std::cerr << "Stereo Mode has not been tested for the used Qt Version." << std::endl;
}
}
#endif
#endif
parser.setSingleDashWordOptionMode(QCommandLineParser::ParseAsLongOptions);
QCommandLineOption debugOption(QStringList() << "d" << "debug",QCoreApplication::translate("main", "Enable debugging mode"));
parser.addOption(debugOption);
QCommandLineOption stereoOption("disable-stereo",QCoreApplication::translate("main", "Disable stereo mode"));
parser.addOption(stereoOption);
QCommandLineOption batchOption(QStringList() << "b" << "batch",QCoreApplication::translate("main", "Batch mode, you have to provide a script for execution"));
parser.addOption(batchOption);
QCommandLineOption logConsoleOption(QStringList() << "c" << "log-to-console",QCoreApplication::translate("main", "Write logger window contents to console"));
parser.addOption(logConsoleOption);
QCommandLineOption remoteControlOption("remote-control",QCoreApplication::translate("main", "Batch mode accepting remote connections"));
parser.addOption(remoteControlOption);
QCommandLineOption fulscreenOption(QStringList() << "f" << "fullscreen",QCoreApplication::translate("main", "Start in fullscreen mode"));
parser.addOption(fulscreenOption);
QCommandLineOption hideLoggerOption(QStringList() << "l" << "hide-logger",QCoreApplication::translate("main", "Start with hidden log window"));
parser.addOption(hideLoggerOption);
QCommandLineOption hideToolboxOption(QStringList() << "t" << "hide-toolbox",QCoreApplication::translate("main", "Start with hidden toolbox"));
parser.addOption(hideToolboxOption);
QCommandLineOption noSplashOption("no-splash",QCoreApplication::translate("main", "Hide splash screen"));
parser.addOption(noSplashOption);
QCommandLineOption polyMeshOption("p",QCoreApplication::translate("main", "Open files as PolyMeshes"));
parser.addOption(polyMeshOption);
QCommandLineOption remotePortOption("remote-port",QCoreApplication::translate("main", "Remote port"),"portnumber");
parser.addOption(remotePortOption);
QCommandLineOption coreProfileOption("core-profile",QCoreApplication::translate("main", "OpenGL Core Profile Mode"));
parser.addOption(coreProfileOption);
QCommandLineOption glVersionOption("glVersion",QCoreApplication::translate("main","Request OpenGL version <major>.<minor> "),QCoreApplication::translate("main","< 1.0 | 1.1 | ... | 4.6 >"));
parser.addOption(glVersionOption);
QCommandLineOption samplesOption("samples",QCoreApplication::translate("main","Overwrite multisampling sample count"),QCoreApplication::translate("main","< 0 | 1 | 2 | ... | 16 >"));
parser.addOption(samplesOption);
QCommandLineOption glStereoOption("glStereo",QCoreApplication::translate("main","Overwrite OpenGL Stereo setting"),QCoreApplication::translate("main","< true | false >"));
parser.addOption(glStereoOption);
QCommandLineOption profileOption("profile",QCoreApplication::translate("main","Request OpenGL context profile <profile> with profile set as compat or core"),QCoreApplication::translate("main","< compat | core >"));
parser.addOption(profileOption);
QCommandLineOption pluginOptionsOption(QStringList() << "o" << "pluginoptions",QCoreApplication::translate("main", "Pass options to plugins"), "key1=value1;key2=value2;...");
parser.addOption(pluginOptionsOption);
const QCommandLineOption helpOption = parser.addHelpOption();
const QCommandLineOption versionOption = parser.addVersionOption();
// Now parse the command line
if (!parser.parse(QCoreApplication::arguments())) {
*errorMessage = parser.errorText();
return CommandLineError;
}
if (parser.isSet(helpOption))
return CommandLineHelpRequested;
if (parser.isSet(versionOption))
return CommandLineVersionRequested;
if (parser.isSet(debugOption)) {
OpenFlipper::Options::debug(true);
}
if (parser.isSet(stereoOption)) {
OpenFlipper::Options::stereo(false);
}
if (parser.isSet(batchOption)) {
OpenFlipper::Options::nogui(true);
}
if (parser.isSet(logConsoleOption)) {
OpenFlipper::Options::logToConsole(true);
}
if (parser.isSet(remoteControlOption)) {
OpenFlipper::Options::remoteControl(true);
}
if (parser.isSet(fulscreenOption)) {
OpenFlipperSettings().setValue("Core/Gui/fullscreen",true);
}
if (parser.isSet(hideLoggerOption)) {
OpenFlipper::Options::loggerState(OpenFlipper::Options::Hidden);
}
if (parser.isSet(hideToolboxOption)) {
OpenFlipperSettings().setValue("Core/Gui/ToolBoxes/hidden",true);
}
if (parser.isSet(noSplashOption)) {
OpenFlipperSettings().setValue("Core/Gui/splash",false);
}
if (parser.isSet(polyMeshOption)) {
openPolyMeshes = true;
}
if (parser.isSet(remotePortOption)) {
const QString port = parser.value("remote-port");
std::cerr << "Got port option : " << port.toStdString() << std::endl;
OpenFlipper::Options::remoteControl(port.toInt());
}
if(parser.isSet("samples"))
OpenFlipper::Options::samples(parser.value("samples").toInt(),true);
if(parser.isSet("glVersion"))
{
QStringList values = parser.value("glVersion").split(".");
QPair<int,int> version(
values[0].toInt(),
values[1].toInt());
OpenFlipper::Options::glVersion(version,true);
}
if(parser.isSet("glStereo"))
OpenFlipper::Options::glStereo(parser.value("glStereo")=="true");
if(parser.value(profileOption)=="core")
{
OpenFlipper::Options::coreProfile(true, true);
}
else
{
if(parser.value(profileOption)=="compat")
{
OpenFlipper::Options::coreProfile(false, true);
}
}
if(parser.isSet(coreProfileOption)) {
OpenFlipper::Options::coreProfile(true, true);
}
if(parser.isSet(pluginOptionsOption))
{
QStringList poptions = parser.value(pluginOptionsOption).split(";");
QVector<QPair<QString, QString>> pcloptions;
for(auto s : poptions)
{
auto kvp = s.split("=");
// Only consider terms of the kind "key=value"
if(kvp.size() != 2u)
continue;
auto key = kvp[0];
auto value = kvp[1];
pcloptions.push_back({key, value});
}
PluginFunctions::setPluginCommandLineOptions(pcloptions);
}
return CommandLineOk;
}
#include <QCommandLineParser>
enum CommandLineParseResult
{
CommandLineOk,
CommandLineError,
CommandLineVersionRequested,
CommandLineHelpRequested
};
static bool openPolyMeshes = false;
static bool remoteControl = false;
// Parse all options
CommandLineParseResult parseCommandLine(QCommandLineParser &parser, QString *errorMessage);
......@@ -323,9 +323,9 @@ void Core::loadPlugins()
QSet<QString> staticPlugins = QSet<QString>::fromList(list);
#endif
for (int i = 0; i < pluginlist.size(); ) {
const QString bn = QFileInfo(pluginlist[i]).fileName();
const QString bn = QFileInfo(pluginlist[i]).baseName().remove("lib");
if (staticPlugins.contains(bn)) {
emit log(LOGOUT, tr("Not loading dynamic %1 as it is statically "
emit log(LOGWARN, tr("Not loading dynamic %1 as it is statically "
"linked against OpenFlipper.").arg(bn));
pluginlist.removeAt(i);
} else {
......
......@@ -23,7 +23,7 @@ if( APPLE )
)
# include all cmake files fouund for objecttypes here
# include all cmake files found for objecttypes here
foreach ( _buildInfo ${_plugin_buildinfos})
include ("${CMAKE_SOURCE_DIR}/${_buildInfo}")
endforeach ()
......@@ -39,7 +39,9 @@ set (headers
../Core/OpenFunctionThread.hh
../Core/PluginInfo.hh
../Core/SpinBoxEventFilter.hh
../Logging/PluginLogging.hh
../CommandLine/CommandLineParser.hh
../Logging/PluginLogging.hh
../OpenGL/OpenGLDetection.hh
../Scripting/ScriptingWrapper.hh
../Scripting/scriptPrototypes/prototypeDataType.hh
../Scripting/scriptPrototypes/prototypeIdList.hh
......@@ -79,6 +81,7 @@ set (headers
../widgets/rendererWidget/rendererWidget.hh
../widgets/pythonWidget/PythonSyntaxHighlighter.hh
../widgets/pythonWidget/pythonWidget.hh
../Windows/windows-startup.hh
../PythonInterpreter/PythonInterpreter.hh
../PythonInterpreter/PythonTypeConversions.hh
)
......@@ -86,6 +89,7 @@ set (headers
set( sources
../OpenFlipper.cc
../Core/BackupCommunication.cc
../CommandLine/CommandLineParser.cc
../Core/Core.cc
../Core/Logging.cc
../Core/OpenFunctionThread.cc
......@@ -166,8 +170,10 @@ set( sources
)
if (WIN32)
LIST(APPEND sources "../StackWalker/StackWalker.cc")
LIST(APPEND headers "../StackWalker/StackWalker.hh")
LIST(APPEND sources "../Windows/StackWalker/StackWalker.cc")
LIST(APPEND sources "../Windows/windows-startup.cc")
LIST(APPEND headers "../Windows/StackWalker/StackWalker.hh")
LIST(APPEND headers "../Windows/windows-startup.hh")
endif(WIN32)
......@@ -219,12 +225,18 @@ if ( EXISTS ${BRANDING_DIRECTORY}/branding.qrc )
endif()
endif()
# =======================================================
# Generate import file for static plugins
# =======================================================
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/static_plugins.cc" "#include <QtPlugin>\n\n")
foreach (plugin ${OPENFLIPPER_STATIC_PLUGIN_NAMES})
file(APPEND "${CMAKE_CURRENT_BINARY_DIR}/static_plugins.cc" "Q_IMPORT_PLUGIN(${plugin});\n")
endforeach()
# Create a static variable containing plugin filenames to skip the dynamic version while loading plugins.
file(APPEND "${CMAKE_CURRENT_BINARY_DIR}/static_plugins.cc" "\nnamespace cmake {\n")
file(APPEND "${CMAKE_CURRENT_BINARY_DIR}/static_plugins.cc" "\nconst char *static_plugins = \"\"\n")
......@@ -237,8 +249,17 @@ file(APPEND "${CMAKE_CURRENT_BINARY_DIR}/static_plugins.cc" ";\n} /* namespace c
list(APPEND RC_SRC "${CMAKE_CURRENT_BINARY_DIR}/static_plugins.cc")
# =======================================================
# Sort files into one OpenFLipper Tree in the IDE
# =======================================================
source_group(TREE ${CMAKE_SOURCE_DIR} FILES ${sources} ${headers} ${uifiles} )
# =======================================================
# Create Executable file
# =======================================================
if (WIN32)
# add app icon rc file to windows build
acg_add_executable (${OPENFLIPPER_PRODUCT_STRING} WIN32 ${CMAKE_CURRENT_SOURCE_DIR}/CoreApp.rc ${sources} ${headers} ${RC_SRC})
......@@ -251,6 +272,7 @@ else ()
acg_add_executable (${OPENFLIPPER_PRODUCT_STRING} ${sources} ${headers} ${RC_SRC} )
endif ()
if ( PYTHON3_FOUND)
target_link_libraries(${OPENFLIPPER_PRODUCT_STRING} ${PYTHON_LIBRARY} pybind11::module pybind11::embed Python3::Python )
endif()
......@@ -282,7 +304,7 @@ endif()
# ====================================================================================
# Get list of ll plugin dependencies and handle special ones
# Get list of plugin dependencies and handle special ones
# where we need to link the library directly into the core to prevent
# linker problems
# ====================================================================================
......
This diff is collapsed.
namespace
{
// Print human-readable GL profile strings
std::string profileToString(QSurfaceFormat::OpenGLContextProfile _profile)
{
if(_profile == QSurfaceFormat::CompatibilityProfile)
return "CompatibilityProfile";
if(_profile == QSurfaceFormat::CoreProfile)
return "CoreProfile";
if(_profile == QSurfaceFormat::NoProfile)
return "NoProfile";
return "[Unknown]";
}
// Check whether a specific context request can be fulfilled
// Can also return the format of the actually created context
bool verifySpecificContextFormat(QSurfaceFormat format, QSurfaceFormat* resultingFormat = nullptr)
{
// All created surfaces try to obey the given format
QSurfaceFormat::setDefaultFormat(format);
// We need a temporary qApp to create a surface and test the current context
int tempArgC = 0;
QApplication tempApp(tempArgC, nullptr);
QOffscreenSurface *surface = new QOffscreenSurface();
surface->create();
auto shareContext = QOpenGLContext::globalShareContext();
if(!shareContext)
{
std::cerr << "Error: Apparently no GL context was created!" << std::endl;
return false;
}
// Make the globally shared OpenGLContext current
shareContext->makeCurrent(surface);
// The opengl surface properties that have actually been applied
// (does not necessarily match the requested properties)
auto resultFormat = QOpenGLContext::globalShareContext()->format();
// Return the format of the actually created context (may be identical to the requested one)
if(resultingFormat != nullptr)
*resultingFormat = resultFormat;
auto curVersion = resultFormat.version();
// Human-readable name of requested profile
auto reqProfileString = profileToString(format.profile());
// Human-readable name of current profile
auto curProfileString = profileToString(resultFormat.profile());
// Example: OpenGL Version 4.6 -> 46
auto reqVersionInt = format.version().first * 10 + format.version().second;
auto curVersionInt = curVersion.first * 10 + curVersion.second;
// We set the following guidelines:
// 1. Whenever the actually received GL version is < than the requested one, the context is not the one requested
// 2. If the received profile is not the requested one, the context is not the one requested
if(curVersionInt < 32 && resultFormat.profile() == QSurfaceFormat::CoreProfile)
{
std::cerr << "Warning: Got an OpenGL core context with OpengGL version < 3.2 (" << curVersion.first << "." << curVersion.second << ")! This should not be possible." << std::endl;
return false;
}
// Check whether the conditions above are met.
// If not, print some error to the console
if(curVersionInt < reqVersionInt ||
format.profile()!= resultFormat.profile() )
{
std::cout << "[OpenGL context] Requested: "
<< format.version().first << "." << format.version().second << " (" << reqProfileString << ")"
<< ", Actually created: "
<< curVersion.first << "." << curVersion.second << " (" << curProfileString << ")"
<< std::endl;
return false;
}
std::cout << "[OpenGL context] Successfully created OpenGL context with version " << curVersion.first << "."
<< curVersion.second << " (" << curProfileString << ")." << std::endl;
return true;
}
// Create a QSurfaceFormat from the most important properties like version and profile
QSurfaceFormat createFormat(QSurfaceFormat::OpenGLContextProfile _profile, int _glMajor, int _glMinor, int _multisamplingSamples, bool _stereo, bool _debugContext)
{
QSurfaceFormat format;
format.setVersion(_glMajor, _glMinor);
format.setProfile(_profile);
format.setSamples(_multisamplingSamples);
format.setStereo(_stereo);
if(_profile != QSurfaceFormat::CoreProfile)
format.setOption(QSurfaceFormat::DeprecatedFunctions);
if (_debugContext)
format.setOption(QSurfaceFormat::DebugContext);
return format;
}
// This method tries to find the best possible OpenGL context format in the following order:
// 1. The profile/format requested via the settings
// 2. A 4.4 compatibility context (should contain all relevant GL functions)
// 3. A 3.2 core context (best choice e.g. on MacOS)
// 4. Return whatever context was applied instead of the requested ones
QSurfaceFormat getContextFormat()
{
auto reqProfile = OpenFlipper::Options::coreProfile() ? QSurfaceFormat::CoreProfile : QSurfaceFormat::CompatibilityProfile;
QPair<int,int> reqVersion = OpenFlipper::Options::glVersion();
auto reqSamples = OpenFlipper::Options::samples();
auto reqStereo = OpenFlipper::Options::glStereo();
bool debugContext = OpenFlipper::Options::debug();
/*
// Debug: test all (possible and impossible) OpenGL versions and profiles and exit
for(int majo = 1; majo < 5; ++majo)
for(int mino = 0; mino < 10; ++mino)
{
std::cout << "========== " << majo << "." << mino << " ==========="<<std::endl;
verifySpecificContextFormat(createFormat(QSurfaceFormat::CoreProfile, majo, mino, reqSamples, reqStereo, debugContext));
verifySpecificContextFormat(createFormat(QSurfaceFormat::CompatibilityProfile, majo, mino, reqSamples, reqStereo, debugContext));
verifySpecificContextFormat(createFormat(QSurfaceFormat::NoProfile, majo, mino, reqSamples, reqStereo, debugContext));
std::cout << "================================" << std::endl;
std::cout << std::endl;
}
exit(0);
*/
QSurfaceFormat resultFormat;
std::cout << "[OpenGL context] Trying to create a " << reqVersion.first << "." << reqVersion.second << " " << profileToString(reqProfile) << " context (default from settings)..." << std::endl;
bool success = verifySpecificContextFormat(createFormat(reqProfile, reqVersion.first, reqVersion.second, reqSamples, reqStereo, debugContext), &resultFormat);
// If that did not work...
if(!success)
{
std::cout << "[OpenGL context] Trying to create a 4.4 compat context..." << std::endl;
success = verifySpecificContextFormat(createFormat(QSurfaceFormat::CompatibilityProfile, 4, 4, reqSamples, reqStereo, debugContext), &resultFormat);
if(!success)
{
std::cout << "[OpenGL context] Trying to create a 3.2 core context..." << std::endl;
success = verifySpecificContextFormat(createFormat(QSurfaceFormat::CoreProfile, 3, 2, reqSamples, reqStereo, debugContext), &resultFormat);
if(!success)
{
std::cerr << "[OpenGL context] Warning: Could not create any of the requested GL contexts." << std::endl;
std::cerr << "[OpenGL context] The following context (proposed by the graphics driver) will be created:" << std::endl;
std::cerr << "[OpenGL context] Profile: " << profileToString(resultFormat.profile()) << ", Version: "
<< resultFormat.version().first << "." << resultFormat.version().second << std::endl;
std::cerr << "[OpenGL context] Please consider setting a supported OpenGL version and profile in the Options dialog." << std::endl;
}
}
}
return resultFormat;
}
}
#include "windows-startup.hh"
#include <windows.h>
#include <errhandlingapi.h>
#include <fstream>
#include <iostream>
#include <OpenFlipper/common/GlobalOptions.hh>
/* ==========================================================
*
* Stackwalker code. Used to get a backtrace if OpenFlipper
* crashes under windows
*
* ==========================================================*/
void StackWalkerToConsole::OnOutput(LPCSTR szText)
{
// Writes crash dump to .OpenFlipper config directory
std::ofstream crashFile;
QString crashName = OpenFlipper::Options::configDirStr() + QDir::separator() + "CrashDump.txt";
crashFile.open(crashName.toLatin1(),std::ios::out | std::ios::app);
crashFile << szText;
crashFile.close();
// Write crash dump to console as well
StackWalker::OnOutput(szText);
}
/* ==========================================================
*
* Console for Windows to get additional output written via
* cerr, cout, ... that is not forwarded to log window
*
* ==========================================================*/
void connect_console()
{
FILE* check = freopen("CONIN$", "r", stdin);
if (check) {
std::cerr << "Error reopening stdin" << std::endl;
}
check = freopen("CONOUT$", "w", stdout);
if (check) {
std::cerr << "Error reopening stdout" << std::endl;
}
check = freopen("CONOUT$", "w", stderr);
if (check) {
std::cerr << "Error reopening stderr" << std::endl;
}
std::cout.clear();
std::cerr.clear();
std::cin.clear();
std::wcout.clear();
std::wcerr.clear();
std::wcin.clear();
}
void attachConsole()
{
// try to attach the console of the parent process
if (AttachConsole(-1))
{
// if the console was attached change stdinput and output
connect_console();
}
else
{
// create and attach a new console if needed
#ifndef NDEBUG
// always open a console in debug mode
AllocConsole();
connect_console();
return;
#endif
if (OpenFlipper::Options::logToConsole())
{
AllocConsole();
connect_console();
}
}
}
#include "StackWalker/StackWalker.hh"
/* ==========================================================
*
* Stackwalker code. Used to get a backtrace if OpenFlipper
* crashes under windows
*
* ==========================================================*/
class StackWalkerToConsole : public StackWalker
{
protected:
virtual void OnOutput(LPCSTR szText) override;
};
/* ==========================================================
*
* Console for Windows to get additional output written via
* cerr, cout, ... that is not forwarded to log window
*
* ==========================================================*/
void connect_console();
void attachConsole();
......@@ -666,11 +666,9 @@ function (_build_openflipper_plugin plugin)
if (STATIC_PLUGIN_${_PLUGIN})
add_library (Plugin-Static-${plugin} STATIC ${ui-files} ${sources} ${headers} ${qrc} ${${_PLUGIN}_ADDSRC})
set_target_properties(Plugin-Static-${plugin} PROPERTIES COMPILE_DEFINITIONS "QT_STATICPLUGIN")
get_target_property(PLUGIN_OUTPUT_FILENAME Plugin-${plugin} LOCATION)
get_filename_component(PLUGIN_OUTPUT_FILENAME "${PLUGIN_OUTPUT_FILENAME}" NAME)
acg_set (OPENFLIPPER_STATIC_PLUGINS "${OPENFLIPPER_STATIC_PLUGINS};Plugin-Static-${plugin}")
acg_set (OPENFLIPPER_STATIC_PLUGIN_NAMES "${OPENFLIPPER_STATIC_PLUGIN_NAMES};${STATIC_PLUGIN_${_PLUGIN}}")
acg_set (OPENFLIPPER_STATIC_PLUGIN_FILES "${OPENFLIPPER_STATIC_PLUGIN_FILES};${PLUGIN_OUTPUT_FILENAME}")
acg_set (OPENFLIPPER_STATIC_PLUGIN_FILES "${OPENFLIPPER_STATIC_PLUGIN_FILES};Plugin-${plugin}")
endif ()
# Link plugin against python if possible
......@@ -743,6 +741,14 @@ function (_build_openflipper_plugin plugin)
)
endif ()
if (STATIC_PLUGIN_${_PLUGIN})
target_link_libraries (Plugin-Static-${plugin}
${${_PLUGIN}_DEPS_LIBRARIES}
${${_PLUGIN}_LIBRARIES}
${${_PLUGIN}_TYPE_DEPENDENCIES}
)
endif()
target_link_libraries (Plugin-${plugin}
${${_PLUGIN}_DEPS_LIBRARIES}
${${_PLUGIN}_LIBRARIES}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment