diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5e47c93130..3316aa91bb 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,6 +1,351 @@ name: Continuous Integration on: [push, pull_request] + jobs: + cmake: + name: CMake Buildsystem + + strategy: + fail-fast: false + + matrix: + profile: + - ubuntu-xenial-standard-unity-makefile + - ubuntu-bionic-coverage-ninja + - macos-eigen-coverage-unity-xcode + - macos-nometa-standard-makefile +# - windows-standard-unity-msvc # FIXME when GH Actions runners upgrade CMake to >=3.16.1 + - windows-nopython-nometa-standard-msvc + + include: + - profile: ubuntu-xenial-standard-unity-makefile + os: ubuntu-16.04 + config: Standard + unity: YES + generator: Unix Makefiles + compiler: Default + metalibs: YES + python: YES + eigen: NO + + - profile: ubuntu-bionic-coverage-ninja + os: ubuntu-18.04 + config: Coverage + unity: NO + generator: Ninja + compiler: Clang + metalibs: YES + python: YES + eigen: NO + + - profile: macos-eigen-coverage-unity-xcode + os: macOS-latest + config: Coverage + unity: YES + generator: Xcode + compiler: Default + metalibs: YES + python: YES + eigen: YES + + - profile: macos-nometa-standard-makefile + os: macOS-latest + config: Standard + unity: NO + generator: Unix Makefiles + compiler: Default + metalibs: NO + python: YES + eigen: NO + + - profile: windows-standard-unity-msvc + os: windows-2019 + config: Standard + unity: YES + generator: Visual Studio 16 2019 + compiler: Default + metalibs: YES + python: YES + eigen: NO + + - profile: windows-nopython-nometa-standard-msvc + os: windows-2019 + config: Standard + unity: NO + generator: Visual Studio 16 2019 + compiler: Default + metalibs: NO + python: NO + eigen: NO + + runs-on: ${{ matrix.os }} + + steps: + - uses: actions/checkout@v1 + with: + fetch-depth: 10 + + - name: Self-destruct makepanda + run: python makepanda/selfdestruct.py --yes + + - name: Install dependencies (macOS) + if: runner.os == 'macOS' + run: | + curl -O https://www.panda3d.org/download/panda3d-1.10.5/panda3d-1.10.5-tools-mac.tar.gz + tar -xf panda3d-1.10.5-tools-mac.tar.gz + + brew install ccache + + echo "##[set-env name=thirdpartyOption;]-D THIRDPARTY_DIRECTORY=../panda3d-1.10.5/thirdparty" -DHAVE_CG=OFF + + - name: Install dependencies (Ubuntu) + if: startsWith(matrix.os, 'ubuntu') + run: > + sudo apt-get update + + sudo apt-get install + build-essential ninja-build clang llvm ccache + bison flex + libeigen3-dev libfreetype6-dev libgl1-mesa-dev libjpeg-dev libode-dev + libopenal-dev libpng-dev libssl-dev libvorbis-dev libx11-dev + libxcursor-dev libxrandr-dev nvidia-cg-toolkit zlib1g-dev + + # Workaround for CMake 3.12 finding this first: + + sudo rm /usr/bin/x86_64-linux-gnu-python2.7-config + + - name: Cache dependencies (Windows) + if: runner.os == 'Windows' + uses: actions/cache@v1 + with: + path: thirdparty-tools + key: ci-cmake-${{ runner.OS }}-thirdparty-v1.10.5-r1 + - name: Install dependencies (Windows) + if: runner.os == 'Windows' + shell: powershell + run: | + if (!(Test-Path thirdparty-tools/panda3d-1.10.5)) { + $wc = New-Object System.Net.WebClient + $wc.DownloadFile("https://www.panda3d.org/download/panda3d-1.10.5/panda3d-1.10.5-tools-win64.zip", "thirdparty-tools.zip") + Expand-Archive -Path thirdparty-tools.zip + } + + echo "##[set-env name=thirdpartyOption;]-D THIRDPARTY_DIRECTORY=../thirdparty-tools/panda3d-1.10.5/thirdparty" + + - name: ccache (non-Windows) + if: runner.os != 'Windows' + uses: actions/cache@v1 + with: + path: ccache + key: ci-cmake-ccache-${{ matrix.profile }} + + - name: Configure + shell: bash + env: + CMAKE_GENERATOR: "${{ matrix.generator }}" + run: > + mkdir build + + cd build + + if ${{ matrix.compiler == 'Clang' }}; then + if [[ "$CMAKE_GENERATOR" == *Studio*2019* ]]; then + export CMAKE_GENERATOR_TOOLSET=ClangCL thirdpartyOption="$thirdpartyOption -DHAVE_HARFBUZZ=NO" + elif [[ "$CMAKE_GENERATOR" == *Studio* ]]; then + export CMAKE_GENERATOR_TOOLSET=LLVM thirdpartyOption="$thirdpartyOption -DHAVE_HARFBUZZ=NO" + else + export CC=clang CXX=clang++ + fi + fi + + if ${{ runner.os != 'Windows' }}; then + compilerLauncher=$(echo -DCMAKE_C{,XX}_COMPILER_LAUNCHER=ccache) + echo "##[set-env name=CCACHE_DIR;]$(dirname $PWD)/ccache" + fi + + cmake + ${compilerLauncher:-} + -D CMAKE_UNITY_BUILD=${{ matrix.unity }} + -D CMAKE_BUILD_TYPE="${{ matrix.config }}" + -D BUILD_METALIBS=${{ matrix.metalibs }} + -D HAVE_PYTHON=${{ matrix.python }} + -D HAVE_EIGEN=${{ matrix.eigen }} + ${thirdpartyOption:-} + .. + + - name: Build (no Python) + if: contains(matrix.python, 'NO') + # BEGIN A + working-directory: build + run: cmake --build . --config ${{ matrix.config }} --parallel 4 + # END A + + - name: Setup Python (Python 2.7) + if: contains(matrix.python, 'YES') + uses: actions/setup-python@v1 + with: + python-version: 2.7 + - name: Configure (Python 2.7) + if: contains(matrix.python, 'YES') + working-directory: build + shell: bash + run: > + cmake -DWANT_PYTHON_VERSION=2.7 + -DPython_FIND_REGISTRY=NEVER -DPython_ROOT=$pythonLocation . + - name: Build (Python 2.7) + if: contains(matrix.python, 'YES') + # BEGIN A + working-directory: build + run: cmake --build . --config ${{ matrix.config }} --parallel 4 + # END A + - name: Test (Python 2.7) + # BEGIN B + if: contains(matrix.python, 'YES') + working-directory: build + shell: bash + run: | + PYTHON_EXECUTABLE=$(grep 'Python_EXECUTABLE:FILEPATH' CMakeCache.txt | sed 's/.*=//') + $PYTHON_EXECUTABLE -m pip install pytest pytest-cov + export COVERAGE_FILE=.coverage.$RANDOM LLVM_PROFILE_FILE=$PWD/pid-%p.profraw + ctest -V -C ${{ matrix.config }} + # END B + + - name: Setup Python (Python 3.5) + if: contains(matrix.python, 'YES') + uses: actions/setup-python@v1 + with: + python-version: 3.5 + - name: Configure (Python 3.5) + if: contains(matrix.python, 'YES') + working-directory: build + shell: bash + run: > + cmake -DWANT_PYTHON_VERSION=3.5 + -DPython_FIND_REGISTRY=NEVER -DPython_ROOT=$pythonLocation . + - name: Build (Python 3.5) + if: contains(matrix.python, 'YES') + # BEGIN A + working-directory: build + run: cmake --build . --config ${{ matrix.config }} --parallel 4 + # END A + - name: Test (Python 3.5) + # BEGIN B + if: contains(matrix.python, 'YES') + working-directory: build + shell: bash + run: | + PYTHON_EXECUTABLE=$(grep 'Python_EXECUTABLE:FILEPATH' CMakeCache.txt | sed 's/.*=//') + $PYTHON_EXECUTABLE -m pip install pytest pytest-cov + export COVERAGE_FILE=.coverage.$RANDOM LLVM_PROFILE_FILE=$PWD/pid-%p.profraw + ctest -V -C ${{ matrix.config }} + # END B + + - name: Setup Python (Python 3.6) + if: contains(matrix.python, 'YES') + uses: actions/setup-python@v1 + with: + python-version: 3.6 + - name: Configure (Python 3.6) + if: contains(matrix.python, 'YES') + working-directory: build + shell: bash + run: > + cmake -DWANT_PYTHON_VERSION=3.6 + -DPython_FIND_REGISTRY=NEVER -DPython_ROOT=$pythonLocation . + - name: Build (Python 3.6) + if: contains(matrix.python, 'YES') + # BEGIN A + working-directory: build + run: cmake --build . --config ${{ matrix.config }} --parallel 4 + # END A + - name: Test (Python 3.6) + # BEGIN B + if: contains(matrix.python, 'YES') + working-directory: build + shell: bash + run: | + PYTHON_EXECUTABLE=$(grep 'Python_EXECUTABLE:FILEPATH' CMakeCache.txt | sed 's/.*=//') + $PYTHON_EXECUTABLE -m pip install pytest pytest-cov + export COVERAGE_FILE=.coverage.$RANDOM LLVM_PROFILE_FILE=$PWD/pid-%p.profraw + ctest -V -C ${{ matrix.config }} + # END B + + - name: Setup Python (Python 3.7) + if: contains(matrix.python, 'YES') + uses: actions/setup-python@v1 + with: + python-version: 3.7 + - name: Configure (Python 3.7) + if: contains(matrix.python, 'YES') + working-directory: build + shell: bash + run: > + cmake -DWANT_PYTHON_VERSION=3.7 + -DPython_FIND_REGISTRY=NEVER -DPython_ROOT=$pythonLocation . + - name: Build (Python 3.7) + if: contains(matrix.python, 'YES') + # BEGIN A + working-directory: build + run: cmake --build . --config ${{ matrix.config }} --parallel 4 + # END A + - name: Test (Python 3.7) + # BEGIN B + if: contains(matrix.python, 'YES') + working-directory: build + shell: bash + run: | + PYTHON_EXECUTABLE=$(grep 'Python_EXECUTABLE:FILEPATH' CMakeCache.txt | sed 's/.*=//') + $PYTHON_EXECUTABLE -m pip install pytest pytest-cov + export COVERAGE_FILE=.coverage.$RANDOM LLVM_PROFILE_FILE=$PWD/pid-%p.profraw + ctest -V -C ${{ matrix.config }} + # END B + + - name: Setup Python (Python 3.8) + if: contains(matrix.python, 'YES') + uses: actions/setup-python@v1 + with: + python-version: 3.8 + - name: Configure (Python 3.8) + if: contains(matrix.python, 'YES') + working-directory: build + shell: bash + run: > + cmake -DWANT_PYTHON_VERSION=3.8 + -DPython_FIND_REGISTRY=NEVER -DPython_ROOT=$pythonLocation . + - name: Build (Python 3.8) + if: contains(matrix.python, 'YES') + # BEGIN A + working-directory: build + run: cmake --build . --config ${{ matrix.config }} --parallel 4 + # END A + - name: Test (Python 3.8) + # BEGIN B + if: contains(matrix.python, 'YES') + working-directory: build + shell: bash + run: | + PYTHON_EXECUTABLE=$(grep 'Python_EXECUTABLE:FILEPATH' CMakeCache.txt | sed 's/.*=//') + $PYTHON_EXECUTABLE -m pip install pytest pytest-cov + export COVERAGE_FILE=.coverage.$RANDOM LLVM_PROFILE_FILE=$PWD/pid-%p.profraw + ctest -V -C ${{ matrix.config }} + # END B + + - name: Upload coverage reports + if: always() && matrix.config == 'Coverage' + working-directory: build + shell: bash + env: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} + run: | + shopt -s expand_aliases + if ${{ runner.os == 'macOS' }}; then alias llvm-profdata='xcrun llvm-profdata' llvm-cov='xcrun llvm-cov'; fi + + python -m coverage combine $(find . -name '.coverage.*') + + llvm-profdata merge pid-*.profraw -o coverage.profdata + llvm-cov show $(grep -Rl LLVM_PROFILE_FILE . | sed 's/^/-object /') -instr-profile=coverage.profdata > coverage.txt + bash <(curl -s https://codecov.io/bash) + makepanda: strategy: matrix: diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000000..3c6daf90b0 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,152 @@ +cmake_minimum_required(VERSION 3.0.2) +set(CMAKE_DISABLE_SOURCE_CHANGES ON) # Must go before project() below +set(CMAKE_DISABLE_IN_SOURCE_BUILD ON) # Must go before project() below + +if(CMAKE_VERSION VERSION_GREATER "3.11" OR POLICY CMP0072) + # Prefer GLVND over libGL when available; this will be enabled by default + # once the minimum CMake version is at least 3.11. + cmake_policy(SET CMP0072 NEW) +endif() + +if(CMAKE_VERSION VERSION_GREATER "3.12" OR POLICY CMP0074) + # Needed for THIRDPARTY_DIRECTORY support; this will be enabled by default + # once the minimum CMake version is at least 3.12. + cmake_policy(SET CMP0074 NEW) +endif() + +# Figure out the version +set(_s "[\\t ]*") # CMake doesn't support \s* +file(STRINGS "setup.cfg" _version REGEX "^version${_s}=${_s}") +string(REGEX REPLACE "^.*=${_s}" "" _version "${_version}") +project(Panda3D VERSION ${_version}) +unset(_version) +unset(_s) + +enable_testing() + +string(REPLACE "$(EFFECTIVE_PLATFORM_NAME)" "" PANDA_CFG_INTDIR "${CMAKE_CFG_INTDIR}") + +# Add generic modules to cmake module path, +# and add Panda3D specific modules to cmake module path +set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/modules/") +set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/macros/") + +if(CMAKE_VERSION VERSION_GREATER "3.8") + # When using the Xcode generator, don't append the platform name to the + # intermediate configuration directory. + set_property(GLOBAL PROPERTY XCODE_EMIT_EFFECTIVE_PLATFORM_NAME OFF) +endif() + +# Include modules builtin to CMake +include(GNUInstallDirs) # Defines CMAKE_INSTALL_ variables + +# Include global modules needed for configure scripts +include(PackageConfig) # Defines package_option + +# Configure Panda3D +include(dtool/CompilerFlags.cmake) +include(dtool/PandaVersion.cmake) +include(dtool/Package.cmake) +include(dtool/Config.cmake) + +# Include global modules +include(AddBisonTarget) # Defines add_bison_target function +include(AddFlexTarget) # Defines add_flex_target function +include(BuildMetalib) # Defines add_component_library AND add_metalib +include(CompositeSources) # Defines composite_sources function +include(Python) # Defines add_python_target AND install_python_package +include(Interrogate) # Defines target_interrogate AND add_python_module +include(RunPzip) # Defines run_pzip function +include(Versioning) # Hooks 'add_library' to apply VERSION/SOVERSION + +# Determine which trees to build. +option(BUILD_DTOOL "Build the dtool source tree." ON) +option(BUILD_PANDA "Build the panda source tree." ON) +option(BUILD_DIRECT "Build the direct source tree." ON) +option(BUILD_PANDATOOL "Build the pandatool source tree." ON) +option(BUILD_CONTRIB "Build the contrib source tree." ON) +option(BUILD_MODELS "Build/install the built-in models." ON) + +# Include Panda3D packages +if(BUILD_DTOOL) + add_subdirectory(dtool "${CMAKE_BINARY_DIR}/dtool") +endif() + +if(BUILD_PANDA) + add_subdirectory(panda "${CMAKE_BINARY_DIR}/panda") +endif() + +if(BUILD_DIRECT) + add_subdirectory(direct "${CMAKE_BINARY_DIR}/direct") +endif() + +if(BUILD_PANDATOOL) + add_subdirectory(pandatool "${CMAKE_BINARY_DIR}/pandatool") +endif() + +if(BUILD_CONTRIB) + add_subdirectory(contrib "${CMAKE_BINARY_DIR}/contrib") +endif() + +if(BUILD_MODELS) + run_pzip(models + "${CMAKE_CURRENT_SOURCE_DIR}/models/" + "${PROJECT_BINARY_DIR}/${PANDA_CFG_INTDIR}/models" + *.egg) + run_pzip(dmodels + "${CMAKE_CURRENT_SOURCE_DIR}/dmodels/src/" + "${PROJECT_BINARY_DIR}/${PANDA_CFG_INTDIR}/models" + *.egg) + + add_custom_command(TARGET models + POST_BUILD + COMMAND ${CMAKE_COMMAND} + -DSOURCE="${CMAKE_CURRENT_SOURCE_DIR}/models/maps/" + -DDESTINATION="${PANDA_OUTPUT_DIR}/models/maps" + -P ${PROJECT_SOURCE_DIR}/cmake/scripts/CopyPattern.cmake + COMMENT "Copying models/maps") + add_custom_command(TARGET dmodels + POST_BUILD + COMMAND ${CMAKE_COMMAND} + -DSOURCE="${CMAKE_CURRENT_SOURCE_DIR}/dmodels/src/" + -DDESTINATION="${PANDA_OUTPUT_DIR}/models" + -DFILES_MATCHING="PATTERN;*.rgb;PATTERN;*.png;PATTERN;*.jpg;PATTERN;*.wav" + -P ${PROJECT_SOURCE_DIR}/cmake/scripts/CopyPattern.cmake + COMMENT "Copying dmodels' assets") + + install(DIRECTORY "${PANDA_OUTPUT_DIR}/models" + COMPONENT Models DESTINATION ${CMAKE_INSTALL_DATADIR}/panda3d) +endif() + +if(INTERROGATE_PYTHON_INTERFACE) + # If we built the Python interface, run the test suite. Note, we do NOT test + # for pytest before adding this test. If the user doesn't have pytest, we'd + # like for the tests to fail. + + # In the Coverage configuration, we also require pytest-cov + + add_test(NAME pytest + COMMAND "${PYTHON_EXECUTABLE}" -m pytest "${PROJECT_SOURCE_DIR}/tests" + $<$:--cov=.> + WORKING_DIRECTORY "${PANDA_OUTPUT_DIR}") +endif() + +# Generate the Panda3DConfig.cmake file so find_package(Panda3D) works, and +# also register the build directory with CMake's package registry. + +file(COPY "${PROJECT_SOURCE_DIR}/cmake/install/Panda3DConfig.cmake" + DESTINATION "${PROJECT_BINARY_DIR}") +install(FILES "${PROJECT_SOURCE_DIR}/cmake/install/Panda3DConfig.cmake" + DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/Panda3D") + +include(CMakePackageConfigHelpers) +write_basic_package_version_file( + "${PROJECT_BINARY_DIR}/Panda3DConfigVersion.cmake" + VERSION "${PROJECT_VERSION}" + COMPATIBILITY AnyNewerVersion) +install(FILES "${PROJECT_BINARY_DIR}/Panda3DConfigVersion.cmake" + DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/Panda3D") + +if(NOT CMAKE_CROSSCOMPILING) + export(PACKAGE Panda3D) +endif() diff --git a/cmake/README.md b/cmake/README.md new file mode 100644 index 0000000000..e90246ccdb --- /dev/null +++ b/cmake/README.md @@ -0,0 +1,78 @@ +Building with CMake +------------------- + +On Windows and macOS, please ensure that you have the very latest version of +CMake installed; older versions may work, but if not, please upgrade to the +latest available version of CMake before requesting help. + +On systems that package CMake themselves (e.g. Linux distributions), we most +likely support the provided version of CMake as long as the system itself is +supported. + +CMake will also require that you already have your system's developer tools +installed. + +The quickest way to build and install Panda with CMake is to install any +third-party dependencies and then run: +```sh +mkdir build && cd build +cmake .. +cmake --build . --config Standard --parallel 4 +[sudo] cmake --build . --config Standard --target install +``` + +Note that, if you are targeting 64-bit on Windows, it is necessary to supply +the `-A x64` option when first invoking `cmake` (as `cmake -A x64 ..`). + +CMake itself does not build Panda; rather, it generates project files for an +existing IDE or build tool. To select a build tool, pass the `-G` option when +first invoking CMake, (`cmake -G Ninja ..` is highly recommended on Linux). +Some of these (Xcode, Visual Studio) support targeting multiple configurations +(the `--config Standard`, above, selects the `Standard` configuration in those +cases). Other build tools (Ninja, Makefiles, ...) do not support multiple +configurations, and the `--config` option is ignored. To change the +configuration in these cases (from `Standard`, the default), it is necessary to +change the `CMAKE_BUILD_TYPE` variable as explained below. + +The configurations are: + +| Configuration | Explanation | +| -------------- | ------------------------------------------------------ | +| Standard | Default; build provided to users of SDK | +| Release | Distribution for end-users | +| MinSizeRel | Like Release, but optimized for size | +| RelWithDebInfo | Like Release, but include debug symbols | +| Debug | Do not optimize, enable optional debugging features | +| Coverage | Like Debug, but profile code coverage; developers only | + +To configure CMake, it is recommended to use cmake-gui (`cmake-gui .`), +or ccmake (`ccmake .`), however it is also possible to configure it entirely +through CMake's command-line interface; see `man cmake` for more details. + +In general, the config variable for a particular third party library is: +``` + HAVE_=YES/NO # Example: USE_JPEG +``` +Panda subpackage building is handled by: +``` + BUILD_=YES/NO # Example: BUILD_DTOOL, BUILD_PANDA +``` +Other configuration settings use their historical names (same names as in-source): +``` + # Examples + PANDA_DISTRIBUTOR="MyDistributor" + LINMATH_ALIGN=YES + + # ... etc ... + +``` + +For example, `makepanda.py --distributor X` becomes `cmake -DPANDA_DISTRIBUTOR=X` + +All found third-party libraries are enabled by default, and makepanda-style +tools packages are searched in the same path as makepanda (however this may be +overridden with the `THIRDPARTY_DIRECTORY` option). + +Most config settings are set to a sensible default for a typical PC/desktop +Panda3D distribution. Third-party libraries and other settings can be enabled +or disabled through configuration with the cmake GUI or CLI. diff --git a/cmake/install/Panda3DConfig.cmake b/cmake/install/Panda3DConfig.cmake new file mode 100644 index 0000000000..b062bcb175 --- /dev/null +++ b/cmake/install/Panda3DConfig.cmake @@ -0,0 +1,157 @@ +# PANDA 3D SOFTWARE +# Copyright (c) Carnegie Mellon University. All rights reserved. +# +# All use of this software is subject to the terms of the revised BSD +# license. You should have received a copy of this license along +# with this source code in a file named "LICENSE." +# +# Author: CFSworks (Dec. 11, 2018) + +# This file is installed to CMake's package search path, and is invoked for +# find_package(Panda3D [COMPONENTS ...]) +# +# The following components are available for importing: +# +# Core - The core Panda3D libraries; this component is always included. +# +# Panda3D::Core::panda +# Panda3D::Core::pandaexpress +# etc. +# +# +# Python - Python targets, which can be used for linking against the Python +# extension modules directly. Note that this also imports the +# Python bindings for other requested components that have them. +# +# Panda3D::Python::panda3d.core +# Panda3D::Python::panda3d.physics +# etc. +# +# +# Tools - Various tools used in asset manipulation and debugging. +# +# Panda3D::Tools::egg2bam +# Panda3D::Tools::egg-optchar +# Panda3D::Tools::pview +# etc. +# +# +# Direct - Panda's "direct" Python framework; C++ support library. +# +# Panda3D::Direct::p3direct +# +# +# Contrib - Extensions not part of the Panda3D core, but contributed by the +# community. +# +# Panda3D::Contrib::p3ai +# Panda3D::Contrib::p3rplight +# +# +# Framework - Panda's "p3framework" C++ framework. +# +# Panda3D::Framework::p3framework +# +# +# Egg - Support for the Egg file format. +# +# Panda3D::Egg::pandaegg +# +# +# Bullet - Support for Bullet physics. +# +# Panda3D::Bullet::p3bullet +# +# +# ODE - Support for the ODE physics engine. +# +# Panda3D::ODE::p3ode +# +# +# FFmpeg - Support for FFmpeg media format loading. +# +# Panda3D::FFmpeg::p3ffmpeg +# +# +# OpenAL - Support for OpenAL audio output. +# +# Panda3D::OpenAL::p3openal_audio +# +# +# FMOD - Support for FMOD audio output. +# +# Panda3D::FMOD::p3fmod_audio +# +# +# OpenGL - Support for OpenGL rendering. +# +# Panda3D::OpenGL::pandagl +# +# +# DX9 - Support for Direct3D 9 rendering. +# +# Panda3D::DX9::pandadx9 +# +# +# OpenGLES1 - Support for OpenGL ES 1.x rendering. +# +# Panda3D::OpenGLES1::pandagles +# +# +# OpenGLES2 - Support for OpenGL ES 2.x+ rendering. +# +# Panda3D::OpenGLES2::pandagles2 +# +# +# Vision - Support for vision processing. +# +# Panda3D::Vision::p3vision +# +# +# VRPN - Support for connecting to a VRPN virtual reality server. +# +# Panda3D::VRPN::p3vrpn + +if("${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}" LESS 3.0) + message(FATAL_ERROR "CMake >= 3.0.2 required") +endif() + +get_filename_component(_panda_config_prefix "${CMAKE_CURRENT_LIST_FILE}" PATH) + +include("${_panda_config_prefix}/Panda3DPackages.cmake") + +set(_panda_components + Core Python Tools + Direct Contrib Framework Egg + Bullet ODE + FFmpeg + OpenAL FMOD + OpenGL DX9 OpenGLES1 OpenGLES2 + Vision VRPN +) + +set(Panda3D_FIND_REQUIRED_Core ON) + +foreach(_comp Core ${Panda3D_FIND_COMPONENTS}) + if(";${_panda_components};" MATCHES ";${_comp};" AND + EXISTS "${_panda_config_prefix}/Panda3D${_comp}Targets.cmake") + + include("${_panda_config_prefix}/Panda3D${_comp}Targets.cmake") + + if(";${Panda3D_FIND_COMPONENTS};" MATCHES ";Python;" AND + EXISTS "${_panda_config_prefix}/Panda3D${_comp}PythonTargets.cmake") + + include("${_panda_config_prefix}/Panda3D${_comp}PythonTargets.cmake") + + endif() + + elseif(Panda3D_FIND_REQUIRED_${_comp}) + + message(FATAL_ERROR "Panda3D REQUIRED component ${_comp} not found") + + endif() + +endforeach(_comp) +unset(_comp) + +unset(_panda_components) diff --git a/cmake/macros/AddBisonTarget.cmake b/cmake/macros/AddBisonTarget.cmake new file mode 100644 index 0000000000..0feb2616ee --- /dev/null +++ b/cmake/macros/AddBisonTarget.cmake @@ -0,0 +1,75 @@ +# Filename: AddBisonTarget.cmake +# Description: This file defines the function add_bison_target which instructs +# cmake to use bison on an input .yxx file. If bison is not available on +# the system, add_bison_target tries to use .prebuilt .cxx files instead. +# +# Usage: +# add_bison_target(output_cxx input_yxx [DEFINES output_h] [PREFIX prefix]) +# + +# Define add_bison_target() +function(add_bison_target output_cxx input_yxx) + set(arguments "") + set(outputs "${output_cxx}") + set(keyword "") + + # Parse the extra arguments to the function. + foreach(arg ${ARGN}) + if(arg STREQUAL "DEFINES") + set(keyword "DEFINES") + + elseif(arg STREQUAL "PREFIX") + set(keyword "PREFIX") + + elseif(keyword STREQUAL "PREFIX") + list(APPEND arguments -p "${arg}") + + elseif(keyword STREQUAL "DEFINES") + list(APPEND arguments --defines="${arg}") + list(APPEND outputs "${arg}") + + else() + message(SEND_ERROR "Unexpected argument ${arg} to add_bison_target") + + endif() + endforeach() + + if(keyword STREQUAL arg AND NOT keyword STREQUAL "") + message(SEND_ERROR "Expected argument after ${keyword}") + endif() + + if(HAVE_BISON) + get_source_file_property(input_yxx "${input_yxx}" LOCATION) + + # If we have bison, we can of course just run it. + add_custom_command( + OUTPUT ${outputs} + COMMAND ${BISON_EXECUTABLE} + -o "${output_cxx}" ${arguments} + "${input_yxx}" + MAIN_DEPENDENCY "${input_yxx}" + ) + + else() + # Look for prebuilt versions of the outputs. + set(commands "") + set(depends "") + + foreach(output ${outputs}) + set(prebuilt_file "${output}.prebuilt") + get_filename_component(prebuilt_file "${prebuilt_file}" ABSOLUTE) + + if(NOT EXISTS "${prebuilt_file}") + message(SEND_ERROR "Bison was not found and ${prebuilt_file} does not exist!") + endif() + + list(APPEND depends "${prebuilt_file}") + list(APPEND commands COMMAND ${CMAKE_COMMAND} -E copy ${prebuilt_file} ${output}) + endforeach() + + add_custom_command( + OUTPUT ${outputs} + ${commands} + DEPENDS ${depends}) + endif() +endfunction(add_bison_target) diff --git a/cmake/macros/AddFlexTarget.cmake b/cmake/macros/AddFlexTarget.cmake new file mode 100644 index 0000000000..b24aeb95fc --- /dev/null +++ b/cmake/macros/AddFlexTarget.cmake @@ -0,0 +1,77 @@ +# Filename: AddFlexTarget.cmake +# Description: This file defines the function add_flex_target which instructs +# cmake to use flex on an input .lxx file. If flex is not available on +# the system, add_flex_target tries to use .prebuilt .cxx files instead. +# +# Usage: +# add_flex_target(output_cxx input_lxx [DEFINES output_h] [PREFIX prefix]) +# + +# Define add_flex_target() +function(add_flex_target output_cxx input_lxx) + set(arguments "") + set(outputs "${output_cxx}") + set(keyword "") + + # Parse the extra arguments to the function. + foreach(arg ${ARGN}) + if(arg STREQUAL "DEFINES") + set(keyword "DEFINES") + + elseif(arg STREQUAL "PREFIX") + set(keyword "PREFIX") + + elseif(arg STREQUAL "CASE_INSENSITIVE") + list(APPEND arguments "-i") + + elseif(keyword STREQUAL "PREFIX") + list(APPEND arguments "-P${arg}") + + elseif(keyword STREQUAL "DEFINES") + list(APPEND arguments "--header-file=${arg}") + list(APPEND outputs "${arg}") + + else() + message(SEND_ERROR "Unexpected argument ${arg} to add_flex_target") + + endif() + endforeach() + + if(keyword STREQUAL arg AND NOT keyword STREQUAL "") + message(SEND_ERROR "Expected argument after ${keyword}") + endif() + + if(HAVE_FLEX) + get_source_file_property(input_lxx "${input_lxx}" LOCATION) + + # If we have flex, we can of course just run it. + add_custom_command( + OUTPUT ${outputs} + COMMAND ${FLEX_EXECUTABLE} + "-o${output_cxx}" ${arguments} + "${input_lxx}" + MAIN_DEPENDENCY "${input_lxx}") + + else() + # Look for prebuilt versions of the outputs. + set(commands "") + set(depends "") + + foreach(output ${outputs}) + set(prebuilt_file "${output}.prebuilt") + get_filename_component(prebuilt_file "${prebuilt_file}" ABSOLUTE) + + if(NOT EXISTS "${prebuilt_file}") + message(SEND_ERROR "Flex was not found and ${prebuilt_file} does not exist!") + endif() + + list(APPEND depends "${prebuilt_file}") + list(APPEND commands COMMAND ${CMAKE_COMMAND} -E copy ${prebuilt_file} ${output}) + endforeach() + + add_custom_command( + OUTPUT ${outputs} + ${commands} + DEPENDS ${depends}) + endif() +endfunction(add_flex_target) diff --git a/cmake/macros/BuildMetalib.cmake b/cmake/macros/BuildMetalib.cmake new file mode 100644 index 0000000000..079b794b85 --- /dev/null +++ b/cmake/macros/BuildMetalib.cmake @@ -0,0 +1,426 @@ +# Filename: BuildMetalib.cmake +# +# Description: This file contains macros to build Panda3D's "metalibs" - these +# are special libraries that contain no unique code themselves and are +# instead just an agglomeration of the various component libraries that get +# linked into them. A library of libraries - a "metalibrary." + +# +# Function: target_link_libraries(...) +# +# Overrides CMake's target_link_libraries() to support "linking" object +# libraries. This is a partial reimplementation of CMake commit dc38970f83, +# which is only available in CMake 3.12+ +# +if(CMAKE_VERSION VERSION_LESS "3.12") + function(target_link_libraries target) + get_target_property(target_type "${target}" TYPE) + if(NOT target_type STREQUAL "OBJECT_LIBRARY") + _target_link_libraries("${target}" ${ARGN}) + return() + endif() + + foreach(library ${ARGN}) + # This is a quick and dirty regex to tell targets apart from other stuff. + # It just checks if it's alphanumeric and starts with p3/panda. + if(library MATCHES "^(PKG::|p3|panda)[A-Za-z0-9]*$") + # We need to add "library"'s include directories to "target" + # (and transitively to INTERFACE_INCLUDE_DIRECTORIES so further + # dependencies will work) + set(include_directories "$") + set_property(TARGET "${target}" APPEND PROPERTY INCLUDE_DIRECTORIES "${include_directories}") + set_property(TARGET "${target}" APPEND PROPERTY INTERFACE_INCLUDE_DIRECTORIES "${include_directories}") + + # SYSTEM include directories should still be reported as SYSTEM, so + # that warnings from those includes are suppressed + set(sys_include_directories + "$") + target_include_directories("${target}" SYSTEM PUBLIC "${sys_include_directories}") + + # And for INTERFACE_COMPILE_DEFINITIONS as well + set(compile_definitions "$") + set_property(TARGET "${target}" APPEND PROPERTY COMPILE_DEFINITIONS "${compile_definitions}") + set_property(TARGET "${target}" APPEND PROPERTY INTERFACE_COMPILE_DEFINITIONS "${compile_definitions}") + + # Build up some generator expressions for determining whether `library` + # is a component library or not. + if(library MATCHES ".*::.*") + # "::" messes up CMake's genex parser; fortunately, a library whose + # name contains that is either an interface library or alias, and + # definitely not a component + set(is_component 0) + set(name_of_component "") + set(name_of_non_component "${library}") + + else() + set(is_component "$") + + # CMake complains if we lookup IS_COMPONENT on an INTERFACE library :( + set(is_object "$,OBJECT_LIBRARY>") + set(is_component "$>") + + set(name_of_component "$<${is_component}:$>") + set(name_of_non_component "$<$:$>") + + endif() + + # Libraries are only linked transitively if they aren't components. + set_property(TARGET "${target}" APPEND PROPERTY + INTERFACE_LINK_LIBRARIES "${name_of_non_component}") + + else() + # This is a file path to an out-of-tree library - this needs to be + # recorded so that the metalib can link them. (They aren't needed at + # all for the object libraries themselves, so they don't have to work + # transitively.) + set_property(TARGET "${target}" APPEND PROPERTY INTERFACE_LINK_LIBRARIES "${library}") + + endif() + + endforeach(library) + + endfunction(target_link_libraries) +endif() + +# +# Function: add_component_library(target [SYMBOL building_symbol] +# [SOURCES] [[NOINIT]/[INIT func [header]]]) +# +# Used very similarly to add_library. You can specify a symbol with SYMBOL, +# which works like CMake's own DEFINE_SYMBOL property: it's defined when +# building the library, but not when building something that links against the +# library. +# +# INIT specifies the init function that should be called from a metalib's init +# function when this is added to a metalib. The header parameter can further +# clarify what header declares this function. By default, this is +# init_libTARGET and config_TARGET.h, respectively, where TARGET is the +# target name (with 'p3' stripped off, if applicable). The NOINIT keyword +# suppresses this default. +# +# Note that this function gets to decide whether the component library is +# OBJECT or SHARED, and whether the library is installed or not. Also, as +# a rule, component libraries may only be linked by other component libraries +# in the same metalib - outside of the metalib, you must link the metalib +# itself. +# +function(add_component_library target_name) + set(sources) + unset(symbol) + + if(target_name MATCHES "^p3.*") + string(SUBSTRING "${target_name}" 2 -1 name_without_prefix) + + else() + set(name_without_prefix "${target_name}") + + endif() + + set(init_func "init_lib${name_without_prefix}") + set(init_header "config_${name_without_prefix}.h") + + set(symbol_keyword OFF) + set(init_keyword 0) + foreach(source ${ARGN}) + if(source STREQUAL "SYMBOL") + set(symbol_keyword ON) + set(init_keyword 0) + + elseif(source STREQUAL "INIT") + set(symbol_keyword OFF) + set(init_keyword 2) + + elseif(source STREQUAL "NOINIT") + set(init_func) + set(init_header) + + elseif(symbol_keyword) + set(symbol_keyword OFF) + set(symbol "${source}") + + elseif(init_keyword EQUAL 2) + set(init_func "${source}") + set(init_keyword 1) + + elseif(init_keyword EQUAL 1) + set(init_header "${source}") + set(init_keyword 0) + + else() + list(APPEND sources "${source}") + + endif() + endforeach() + + if(BUILD_METALIBS) + # CMake 3.0.2 doesn't like .I/.N/.T files! We let it know that they're only + # headers. + foreach(source ${sources}) + if(source MATCHES "\\.[INT]$") + set_source_files_properties(${source} PROPERTIES HEADER_FILE_ONLY ON) + endif() + endforeach(source) + + add_library("${target_name}" OBJECT ${sources}) + + else() + add_library("${target_name}" ${sources}) + + endif() + + set_target_properties("${target_name}" PROPERTIES + IS_COMPONENT ON + INIT_FUNCTION "${init_func}" + INIT_HEADER "${init_header}") + + if(symbol) + set_property(TARGET "${target_name}" PROPERTY DEFINE_SYMBOL "${symbol}") + + if(BUILD_METALIBS) + # ... DEFINE_SYMBOL is apparently not respected for object libraries? + set_property(TARGET "${target_name}" APPEND PROPERTY COMPILE_DEFINITIONS "${symbol}") + + # Make sure other component libraries relying on this one inherit the + # symbol + set_property(TARGET "${target_name}" APPEND PROPERTY + INTERFACE_COMPILE_DEFINITIONS "$<$>:${symbol}>") + endif() + endif() + + if(BUILD_METALIBS) + # Apparently neither is CMAKE_INCLUDE_CURRENT_DIR_IN_INTERFACE? + set_property(TARGET "${target_name}" PROPERTY + INTERFACE_INCLUDE_DIRECTORIES "${CMAKE_CURRENT_SOURCE_DIR}") + + # If we're building dynamic libraries, the object library needs to be -fPIC + if(BUILD_SHARED_LIBS) + set_property(TARGET "${target_name}" PROPERTY + POSITION_INDEPENDENT_CODE ON) + endif() + endif() + +endfunction(add_component_library) + +# +# Function: add_metalib(target [source1 source2] +# [INCLUDE header1.h ...] +# [INIT initfunc [initheader.h] [EXPORT type name expr]] +# [COMPONENTS component1 ...]) +# +# This is add_library, but for metalibs. +# +# The INIT keyword can specify an initialization function/header (which will be +# autogenerated by this function) that calls the underlying component libs' +# init functions. +# +# The EXPORT keyword exports the expression `expr`, which yields a value of +# type `type`, as the undecorated (extern "C") symbol `name` +# +# The INCLUDE keyword allows the init file to pull in additional headers, which +# may be useful for EXPORT. +# +function(add_metalib target_name) + set(components_keyword OFF) + set(init_keyword 0) + set(init_func) + set(init_header "${target_name}.h") + set(export_keyword 0) + set(export_declarations) + set(export_definitions) + set(component_init_headers) + set(components) + set(sources) + + foreach(arg ${ARGN}) + if(arg STREQUAL "COMPONENTS") + set(components_keyword ON) + set(include_keyword OFF) + set(init_keyword 0) + set(export_keyword 0) + + elseif(arg STREQUAL "INCLUDE") + set(include_keyword ON) + set(components_keyword OFF) + set(init_keyword 0) + set(export_keyword 0) + + elseif(arg STREQUAL "INIT") + set(init_keyword 2) + set(components_keyword OFF) + set(include_keyword OFF) + set(export_keyword 0) + + elseif(arg STREQUAL "EXPORT") + if(NOT init_func) + message(FATAL_ERROR "EXPORT cannot be used before INIT") + endif() + + set(export_keyword 3) + set(components_keyword OFF) + set(include_keyword OFF) + set(init_keyword 0) + + elseif(components_keyword) + list(APPEND components "${arg}") + + elseif(include_keyword) + set(component_init_headers + "${component_init_headers}#include \"${arg}\"\n") + + elseif(init_keyword EQUAL 2) + set(init_func "${arg}") + set(init_keyword 1) + + elseif(init_keyword EQUAL 1) + set(init_header "${arg}") + set(init_keyword 0) + + elseif(export_keyword EQUAL 3) + set(_export_type "${arg}") + set(export_keyword 2) + + elseif(export_keyword EQUAL 2) + set(_export_name "${arg}") + set(export_keyword 1) + + elseif(export_keyword EQUAL 1) + set(export_declarations + "${export_declarations}\nextern \"C\" IMPORT_CLASS ${_export_type} ${_export_name}();") + set(export_definitions + "${export_definitions}\nextern \"C\" EXPORT_CLASS ${_export_type} ${_export_name}() { return ${arg}; }") + unset(_export_type) + unset(_export_name) + set(export_keyword 0) + + else() + list(APPEND sources "${arg}") + + endif() + endforeach() + + string(REPLACE ";" "|" piped_components "${components}") + set(component_genex_regex ".*TARGET_PROPERTY:(${piped_components}),.*") + + set(private_defines) + set(interface_defines) + set(includes) + set(libs) + set(component_init_funcs "") + foreach(component ${components}) + if(NOT TARGET "${component}") + message(FATAL_ERROR + "Missing component library ${component} referenced by metalib ${target_name}! + (Component library targets must be created BEFORE add_metalib.)") + endif() + + get_target_property(is_component "${component}" IS_COMPONENT) + if(NOT is_component) + message(FATAL_ERROR + "Attempted to metalink non-component ${component} into ${target_name}!") + endif() + + get_target_property(component_init_header "${component}" INIT_HEADER) + get_target_property(component_init_func "${component}" INIT_FUNCTION) + + if(component_init_header) + set(component_init_headers + "${component_init_headers}#include \"${component_init_header}\"\n") + endif() + + if(component_init_func) + set(component_init_funcs + "${component_init_funcs} ${component_init_func}();\n") + endif() + + if(BUILD_METALIBS) + # This will be an object library we're pulling in; rather than link, + # let's try to "flatten" all of its properties into ours. + + # Private defines: Just reference using a generator expression + list(APPEND private_defines "$") + + # Interface defines: Copy those, but filter out generator expressions + # referencing a component library + get_target_property(component_defines "${component}" INTERFACE_COMPILE_DEFINITIONS) + if(component_defines) + foreach(component_define ${component_defines}) + if(component_define MATCHES "${component_genex_regex}") + # Filter, it's a genex referencing one of our components + elseif(component_define MATCHES ".*IS_COMPONENT.*") + # Filter, it's testing to see if the consumer is a component + else() + list(APPEND interface_defines ${component_define}) + endif() + endforeach(component_define) + endif() + + # Include directories: Filter out anything that references a component + # library or anything in the project path + get_target_property(component_includes "${component}" INTERFACE_INCLUDE_DIRECTORIES) + foreach(component_include ${component_includes}) + if(component_include MATCHES "${component_genex_regex}") + # Ignore component references + + elseif(component_include MATCHES "^${PROJECT_SOURCE_DIR}") + # Include path within project; should only be included when building + list(APPEND includes "$") + + else() + # Anything else gets included + list(APPEND includes "${component_include}") + + endif() + endforeach(component_include) + + # Link libraries: Filter out component libraries; we aren't linking + # against them, we're using their objects + get_target_property(component_libraries "${component}" INTERFACE_LINK_LIBRARIES) + foreach(component_library ${component_libraries}) + if(NOT component_library) + # NOTFOUND - guess there are no INTERFACE_LINK_LIBRARIES + + elseif(component_library MATCHES "${component_genex_regex}") + # Ignore component references + + elseif(component_library MATCHES ".*(${piped_components}).*") + # Component library, ignore + + else() + # Anything else gets included + list(APPEND libs "${component_library}") + + endif() + endforeach(component_library) + + # Consume this component's objects + list(APPEND sources "$") + + else() # NOT BUILD_METALIBS + list(APPEND libs "${component}") + + endif() + endforeach() + + if(init_func) + set(init_source_path "${CMAKE_CURRENT_BINARY_DIR}/init_${target_name}.cxx") + set(init_header_path "${CMAKE_CURRENT_BINARY_DIR}/${init_header}") + + configure_file("${PROJECT_SOURCE_DIR}/cmake/templates/metalib_init.cxx.in" + "${init_source_path}") + list(APPEND sources "${init_source_path}") + + configure_file("${PROJECT_SOURCE_DIR}/cmake/templates/metalib_init.h.in" + "${init_header_path}") + install(FILES "${init_header_path}" DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d) + endif() + + add_library("${target_name}" ${sources}) + target_compile_definitions("${target_name}" + PRIVATE ${private_defines} + INTERFACE ${interface_defines}) + target_link_libraries("${target_name}" ${libs}) + target_include_directories("${target_name}" + PUBLIC ${includes} + INTERFACE "$/${CMAKE_INSTALL_INCLUDEDIR}/panda3d>") + +endfunction(add_metalib) diff --git a/cmake/macros/CompositeSources.cmake b/cmake/macros/CompositeSources.cmake new file mode 100644 index 0000000000..82decc5400 --- /dev/null +++ b/cmake/macros/CompositeSources.cmake @@ -0,0 +1,167 @@ +# Filename: CompositeSources.cmake +# Description: This file defines the function composite_sources which looks at +# a provided list of sources, generates _compositeN.cxx, and appends the +# composites to the list. The original files in the list are marked as headers +# so that they will be available in an IDE, but not compiled at build time. +# +# Usage: +# composite_sources(target source_var) +# +# Example: +# set(MY_SOURCES a.cxx b.cxx c.cxx) +# composite_sources(my_lib MY_SOURCES) +# add_library(my_lib ${MY_SOURCES}) +# + + +# Settings for composite builds. Should be moved to Config.cmake? +set(CMAKE_UNITY_BUILD "ON" CACHE BOOL + "Enable unity builds; Panda defaults this to on.") + +set(CMAKE_UNITY_BUILD_BATCH_SIZE "30" CACHE STRING + "How many source files to build at a time through the unity build mechanism. + A high value will speed up the build dramatically but will be more memory + intensive than a low value.") + +set(COMPOSITE_SOURCE_EXTENSIONS ".cxx;.mm;.c" CACHE STRING + "Only files of these extensions will be composited.") + +set(COMPOSITE_SOURCE_EXCLUSIONS "" CACHE STRING + "A list of targets to skip when compositing sources. This is mainly +desirable for CI builds.") + +set(COMPOSITE_GENERATOR "${CMAKE_SOURCE_DIR}/cmake/scripts/MakeComposite.cmake") + + +# Define composite_sources() +function(composite_sources target sources_var) + if(NOT CMAKE_VERSION VERSION_LESS "3.16") + # CMake 3.16+ implements CMAKE_UNITY_BUILD* natively; no need to continue! + + # Actually - <=3.16.2 has difficulty with multi-language support, so only + # allow .cxx in. Hopefully this can be removed soon. + foreach(_source ${${sources_var}}) + get_filename_component(_source_ext "${_source}" EXT) + if(NOT _source_ext STREQUAL ".cxx") + set_source_files_properties(${_source} PROPERTIES + SKIP_UNITY_BUILD_INCLUSION YES) + endif() + endforeach(_source) + + return() + endif() + + if(NOT CMAKE_UNITY_BUILD) + # We've been turned off + return() + endif() + + # How many sources were specified? + set(orig_sources ${${sources_var}}) + set(sources ${orig_sources}) + list(LENGTH sources num_sources) + + # Don't composite if in the list of exclusions, and don't bother compositing + # with too few sources + list (FIND COMPOSITE_SOURCE_EXCLUSIONS ${target} _index) + if(num_sources LESS 2 OR ${CMAKE_UNITY_BUILD_BATCH_SIZE} LESS 2 OR ${_index} GREATER -1) + return() + endif() + + # Sort each source file into a list. + foreach(source ${sources}) + get_filename_component(extension "${source}" EXT) + get_source_file_property(generated "${source}" GENERATED) + get_source_file_property(is_header "${source}" HEADER_FILE_ONLY) + get_source_file_property(skip_compositing "${source}" SKIP_UNITY_BUILD_INCLUSION) + + # Check if we can safely add this to a composite file. + if(NOT generated AND NOT is_header AND NOT skip_compositing AND + ";${COMPOSITE_SOURCE_EXTENSIONS};" MATCHES ";${extension};") + + if(NOT DEFINED sources_${extension}) + set(sources_${extension}) + endif() + + # Append it to one of the lists. + list(APPEND sources_${extension} "${source}") + endif() + endforeach(source) + + # Now, put it all into one big list! + set(sorted_sources) + foreach(extension ${COMPOSITE_SOURCE_EXTENSIONS}) + if(DEFINED sources_${extension}) + list(APPEND sorted_sources ${sources_${extension}}) + endif() + endforeach(extension) + + set(composite_files) + set(composite_sources) + + # Fill in composite_ext so we can kick off the loop. + list(GET sorted_sources 0 first_source) + get_filename_component(first_source_ext "${first_source}" EXT) + set(composite_ext ${first_source_ext}) + + while(num_sources GREATER 0) + # Pop the first element and adjust the sorted_sources length accordingly. + list(GET sorted_sources 0 source) + list(REMOVE_AT sorted_sources 0) + list(LENGTH sorted_sources num_sources) + + # Add this file to our composite_sources buffer. + list(APPEND composite_sources ${source}) + list(LENGTH composite_sources num_composite_sources) + + # Get the next source file's extension, so we can see if we're done with + # this set of source files. + if(num_sources GREATER 0) + list(GET sorted_sources 0 next_source) + get_filename_component(next_extension "${next_source}" EXT) + else() + set(next_extension "") + endif() + + # Check if this is the point where we should cut the file. + if(num_sources EQUAL 0 OR NOT num_composite_sources LESS ${CMAKE_UNITY_BUILD_BATCH_SIZE} + OR NOT composite_ext STREQUAL next_extension) + # It's pointless to make a composite source from just one file. + if(num_composite_sources GREATER 1) + + # Figure out the name of our composite file. + list(LENGTH composite_files index) + math(EXPR index "1+${index}") + set(composite_file "${CMAKE_CURRENT_BINARY_DIR}/${target}_composite${index}${composite_ext}") + list(APPEND composite_files "${composite_file}") + + # Set HEADER_FILE_ONLY to prevent it from showing up in the + # compiler command, but still show up in the IDE environment. + set_source_files_properties(${composite_sources} PROPERTIES HEADER_FILE_ONLY ON) + + # We'll interrogate the composite files, so exclude the original sources. + set_source_files_properties(${composite_sources} PROPERTIES WRAP_EXCLUDE YES) + + # Finally, add the target that generates the composite file. + add_custom_command( + OUTPUT "${composite_file}" + COMMAND ${CMAKE_COMMAND} + -DCOMPOSITE_FILE="${composite_file}" + -DCOMPOSITE_SOURCES="${composite_sources}" + -P "${COMPOSITE_GENERATOR}" + DEPENDS ${composite_sources}) + endif() + + # Reset for the next composite file. + set(composite_sources "") + set(composite_ext ${next_extension}) + endif() + endwhile() + + set_source_files_properties(${composite_files} PROPERTIES GENERATED YES) + + # The new files are added to the existing files, which means the old files + # are still there, but they won't be compiled due to the HEADER_FILE_ONLY setting. + set(${sources_var} ${orig_sources} ${composite_files} PARENT_SCOPE) + +endfunction(composite_sources) diff --git a/cmake/macros/Interrogate.cmake b/cmake/macros/Interrogate.cmake new file mode 100644 index 0000000000..eb441e4b13 --- /dev/null +++ b/cmake/macros/Interrogate.cmake @@ -0,0 +1,400 @@ +# Filename: Interrogate.cmake +# +# Description: This file contains macros and functions that are used to invoke +# interrogate, to generate wrappers for Python and/or other languages. +# +# Functions: +# target_interrogate(target [ALL] [source1 [source2 ...]]) +# add_python_module(module [lib1 [lib2 ...]]) +# add_python_target(target [source1 [source2 ...]]) +# + +set(IGATE_FLAGS -DCPPPARSER -D__cplusplus -Dvolatile -Dmutable) + +# In addition, Interrogate needs to know if this is a 64-bit build: +include(CheckTypeSize) +check_type_size(long CMAKE_SIZEOF_LONG) +if(CMAKE_SIZEOF_LONG EQUAL 8) + list(APPEND IGATE_FLAGS "-D_LP64") +endif() + + +# This is a list of regexes that are applied to every filename. If one of the +# regexes matches, that file will not be passed to Interrogate. +set(INTERROGATE_EXCLUDE_REGEXES + ".*\\.I$" + ".*\\.N$" + ".*\\.c$" + ".*\\.lxx$" + ".*\\.yxx$" + ".*_src\\..*" +) + +if(WIN32) + list(APPEND IGATE_FLAGS -D_X86_ -D__STDC__=1 -D "_declspec(param)=" -D "__declspec(param)=" -D_near -D_far -D__near -D__far -D_WIN32 -D__stdcall) +endif() +if(MSVC_VERSION) + list(APPEND IGATE_FLAGS "-D_MSC_VER=${MSVC_VERSION}") +endif() +if(INTERROGATE_VERBOSE) + list(APPEND IGATE_FLAGS "-v") +endif() + +set(IMOD_FLAGS -python-native) + +# This stores the names of every module added to the Interrogate system: +set(ALL_INTERROGATE_MODULES CACHE INTERNAL "Internal variable") + +# +# Function: target_interrogate(target [ALL] [source1 [source2 ...]]) +# NB. This doesn't actually invoke interrogate, but merely adds the +# sources to the list of scan sources associated with the target. +# Interrogate will be invoked when add_python_module is called. +# If ALL is specified, all of the sources from the associated +# target are added. +# +function(target_interrogate target) + set(sources) + set(extensions) + set(want_all OFF) + set(extensions_keyword OFF) + foreach(arg ${ARGN}) + if(arg STREQUAL "ALL") + set(want_all ON) + + elseif(arg STREQUAL "EXTENSIONS") + set(extensions_keyword ON) + + elseif(extensions_keyword) + list(APPEND extensions "${arg}") + + else() + list(APPEND sources "${arg}") + + endif() + endforeach() + + # If ALL was specified, pull in all sources from the target. + if(want_all) + get_target_property(target_sources "${target}" SOURCES) + list(APPEND sources ${target_sources}) + endif() + + list(REMOVE_DUPLICATES sources) + + # Now let's get everything's absolute path, so that it can be passed + # through a property while still preserving the reference. + set(absolute_sources) + foreach(source ${sources}) + get_source_file_property(exclude "${source}" WRAP_EXCLUDE) + if(NOT exclude) + get_source_file_property(location "${source}" LOCATION) + list(APPEND absolute_sources ${location}) + endif() + endforeach(source) + + set(absolute_extensions) + foreach(extension ${extensions}) + get_source_file_property(location "${extension}" LOCATION) + list(APPEND absolute_extensions ${location}) + endforeach(extension) + + set_target_properties("${target}" PROPERTIES + IGATE_SOURCES "${absolute_sources}") + set_target_properties("${target}" PROPERTIES + IGATE_EXTENSIONS "${absolute_extensions}") + + # CMake has no property for determining the source directory where the + # target was originally added. interrogate_sources makes use of this + # property (if it is set) in order to make all paths on the command-line + # relative to it, thereby shortening the command-line even more. + # Since this is not an Interrogate-specific property, it is not named with + # an IGATE_ prefix. + set_target_properties("${target}" PROPERTIES + TARGET_SRCDIR "${CMAKE_CURRENT_SOURCE_DIR}") + + # Also store where the build files are kept, so the Interrogate output can go + # there as well. + set_target_properties("${target}" PROPERTIES + TARGET_BINDIR "${CMAKE_CURRENT_BINARY_DIR}/${PANDA_CFG_INTDIR}") + +endfunction(target_interrogate) + +# +# Function: interrogate_sources(target output database language_flags module) +# +# This function actually runs a component-level interrogation against 'target'. +# It generates the outfile.cxx (output) and dbfile.in (database) files, which +# can then be used during the interrogate_module step to produce language +# bindings. +# +# The target must first have had sources selected with target_interrogate. +# Failure to do so will result in an error. +# +function(interrogate_sources target output database language_flags) + get_target_property(sources "${target}" IGATE_SOURCES) + get_target_property(extensions "${target}" IGATE_EXTENSIONS) + + if(NOT sources) + message(FATAL_ERROR + "Cannot interrogate ${target} unless it's run through target_interrogate first!") + endif() + + get_target_property(srcdir "${target}" TARGET_SRCDIR) + if(NOT srcdir) + # No TARGET_SRCDIR was set, so we'll do everything relative to our + # current binary dir instead: + set(srcdir "${CMAKE_CURRENT_BINARY_DIR}") + endif() + + set(scan_sources) + set(nfiles) + foreach(source ${sources}) + get_filename_component(source_basename "${source}" NAME) + + # Only certain sources should actually be scanned by Interrogate. The + # rest are merely dependencies. This uses the exclusion regex above in + # order to determine what files are okay: + set(exclude OFF) + foreach(regex ${INTERROGATE_EXCLUDE_REGEXES}) + if("${source_basename}" MATCHES "${regex}") + set(exclude ON) + endif() + endforeach(regex) + + if(NOT exclude) + # This file is to be scanned by Interrogate. In order to avoid + # cluttering up the command line, we should first make it relative: + file(RELATIVE_PATH rel_source "${srcdir}" "${source}") + list(APPEND scan_sources "${rel_source}") + + # Also see if this file has a .N counterpart, which has directives + # specific for Interrogate. If there is a .N file, we add it as a dep, + # so that CMake will rerun Interrogate if the .N files are modified: + get_filename_component(source_path "${source}" PATH) + get_filename_component(source_name_we "${source}" NAME_WE) + set(nfile "${source_path}/${source_name_we}.N") + if(EXISTS "${nfile}") + list(APPEND nfiles "${nfile}") + endif() + endif() + endforeach(source) + + # Also add extensions, in relative-path form + foreach(extension ${extensions}) + file(RELATIVE_PATH rel_extension "${srcdir}" "${extension}") + list(APPEND scan_sources "${rel_extension}") + endforeach(extension) + + # Interrogate also needs the include paths, so we'll extract them from the + # target. These are available via a generator expression. + + # When we read the INTERFACE_INCLUDE_DIRECTORIES property, we need to read it + # from a target that has the IS_INTERROGATE=1 property. + # (See PackageConfig.cmake for an explanation why.) + # The problem is, custom commands are not targets, so we can't put target + # properties on them. And if you try to use the $ + # generator expression from the context of a custom command, it'll instead + # read the property from the most recent actual target. As a workaround for + # this, we create a fake target with the IS_INTERROGATE property set and pull + # the INTERFACE_INCLUDE_DIRECTORIES property out through that. + # I hate it, but such is CMake. + add_custom_target(${target}_igate_internal) + set_target_properties(${target}_igate_internal PROPERTIES + IS_INTERROGATE 1 + INTERFACE_INCLUDE_DIRECTORIES "$") + + # Note, the \t is a workaround for a CMake bug where using a plain space in + # a JOIN will cause it to be escaped. Tabs are not escaped and will + # separate correctly. + set(include_flags "-I$,\t-I>") + + # Get the compiler definition flags. These must be passed to Interrogate + # in the same way that they are passed to the compiler so that Interrogate + # will preprocess each file in the same way. + set(_compile_defs "$") + if(NOT CMAKE_HOST_WIN32) + # Win32's command-line parser doesn't understand "'" + # that's fine, it also ignores '"' + set(_q "'") + endif() + set(_compile_defs_flags "-D${_q}$${_q}") + # We may have just ended up with -D'' if there are no flags; filter that + set(define_flags + "$<$>:${_compile_defs_flags}>") + + # Some of the definitions may be specified using -D flags in the global + # CXX_FLAGS variables; parse those out (this also picks up NDEBUG) + set(_configs ${CMAKE_CONFIGURATION_TYPES} ${CMAKE_BUILD_TYPE} "") + list(REMOVE_DUPLICATES _configs) + foreach(_config ${_configs}) + if(_config STREQUAL "") + set(flags "${CMAKE_CXX_FLAGS}") + else() + string(TOUPPER "${_config}" _CONFIG) + set(flags "${CMAKE_CXX_FLAGS_${_CONFIG}}") + endif() + + # Convert "/D define1" and "-Ddefine2" flags, interspersed with other + # compiler nonsense, into a basic "-Ddefine1 -Ddefine2" string + string(REGEX MATCHALL "[/-]D[ \t]*[A-Za-z0-9_]+" igate_flags "${flags}") + string(REPLACE ";" " " igate_flags "${igate_flags}") + string(REPLACE "/D" "-D" igate_flags "${igate_flags}") + + if(_config STREQUAL "") + list(APPEND define_flags "${igate_flags}") + else() + list(APPEND define_flags "$<$:${igate_flags}>") + endif() + endforeach(_config) + + get_filename_component(output_directory "${output}" DIRECTORY) + get_filename_component(database_directory "${database}" DIRECTORY) + + add_custom_command( + OUTPUT "${output}" "${database}" + COMMAND ${CMAKE_COMMAND} -E + make_directory "${output_directory}" + COMMAND ${CMAKE_COMMAND} -E + make_directory "${database_directory}" + COMMAND host_interrogate + -oc "${output}" + -od "${database}" + -srcdir "${srcdir}" + -library ${target} + ${INTERROGATE_OPTIONS} + ${IGATE_FLAGS} + ${language_flags} + ${define_flags} + -S "${PROJECT_SOURCE_DIR}/dtool/src/interrogatedb" + -S "${PROJECT_SOURCE_DIR}/dtool/src/parser-inc" + -S "${PYTHON_INCLUDE_DIRS}" + ${include_flags} + ${scan_sources} + + DEPENDS host_interrogate ${sources} ${extensions} ${nfiles} + COMMENT "Interrogating ${target}") + + # Propagate the target's compile definitions to the output file + set_source_files_properties("${output}" PROPERTIES + COMPILE_DEFINITIONS "$") + +endfunction(interrogate_sources) + +# +# Function: add_python_module(module [lib1 [lib2 ...]] [LINK lib1 ...] +# [IMPORT mod1 ...]) +# Uses interrogate to create a Python module. If the LINK keyword is specified, +# the Python module is linked against the specified libraries instead of those +# listed before. The IMPORT keyword makes the output module import another +# Python module when it's initialized. +# +function(add_python_module module) + if(NOT INTERROGATE_PYTHON_INTERFACE) + return() + endif() + + set(targets) + set(component "Python") + set(link_targets) + set(import_flags) + set(infiles_rel) + set(infiles_abs) + set(sources_abs) + set(extensions) + + set(keyword) + foreach(arg ${ARGN}) + if(arg STREQUAL "LINK" OR arg STREQUAL "IMPORT" OR arg STREQUAL "COMPONENT") + set(keyword "${arg}") + + elseif(keyword STREQUAL "LINK") + list(APPEND link_targets "${arg}") + set(keyword) + + elseif(keyword STREQUAL "IMPORT") + list(APPEND import_flags "-import" "${arg}") + set(keyword) + + elseif(keyword STREQUAL "COMPONENT") + set(component "${arg}") + set(keyword) + + else() + list(APPEND targets "${arg}") + + endif() + endforeach(arg) + + if(NOT link_targets) + set(link_targets ${targets}) + endif() + + string(REGEX REPLACE "^.*\\." "" modname "${module}") + + foreach(target ${targets}) + get_target_property(workdir_abs "${target}" TARGET_BINDIR) + if(NOT workdir_abs) + # No TARGET_BINDIR was set, so we'll just use our current directory: + set(workdir_abs "${CMAKE_CURRENT_BINARY_DIR}/${PANDA_CFG_INTDIR}") + endif() + # Keep command lines short + file(RELATIVE_PATH workdir_rel "${CMAKE_CURRENT_BINARY_DIR}" "${workdir_abs}") + + interrogate_sources(${target} + "${workdir_abs}/${target}_igate.cxx" + "${workdir_abs}/${target}.in" + "-python-native;-module;${module}") + + get_target_property(target_extensions "${target}" IGATE_EXTENSIONS) + list(APPEND infiles_rel "${workdir_rel}/${target}.in") + list(APPEND infiles_abs "${workdir_abs}/${target}.in") + list(APPEND sources_abs "${workdir_abs}/${target}_igate.cxx") + list(APPEND extensions ${target_extensions}) + endforeach(target) + + add_custom_command( + OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${PANDA_CFG_INTDIR}/${module}_module.cxx" + COMMAND ${CMAKE_COMMAND} -E + make_directory "${CMAKE_CURRENT_BINARY_DIR}/${PANDA_CFG_INTDIR}" + COMMAND host_interrogate_module + -oc "${CMAKE_CURRENT_BINARY_DIR}/${PANDA_CFG_INTDIR}/${module}_module.cxx" + -module ${modname} -library ${modname} + ${import_flags} + ${INTERROGATE_MODULE_OPTIONS} + ${IMOD_FLAGS} ${infiles_rel} + DEPENDS host_interrogate_module ${infiles_abs} + COMMENT "Generating module ${module}") + + # CMake chokes on ${CMAKE_CFG_INTDIR} in source paths when unity builds are + # enabled. The easiest way out of this is to skip unity for those paths. + # Since generated Interrogate .cxx files are pretty big already, this doesn't + # really inconvenience us at all. + set_source_files_properties( + "${CMAKE_CURRENT_BINARY_DIR}/${PANDA_CFG_INTDIR}/${module}_module.cxx" + ${sources_abs} PROPERTIES + SKIP_UNITY_BUILD_INCLUSION YES) + + add_python_target(${module} COMPONENT "${component}" EXPORT "${component}" + "${CMAKE_CURRENT_BINARY_DIR}/${PANDA_CFG_INTDIR}/${module}_module.cxx" + ${sources_abs} ${extensions}) + target_link_libraries(${module} ${link_targets}) + + if(CMAKE_VERSION VERSION_LESS "3.11") + # CMake <3.11 doesn't allow generator expressions on source files, so we + # need to copy them to our target, which does allow them. + + foreach(source ${sources_abs}) + get_source_file_property(compile_definitions "${source}" COMPILE_DEFINITIONS) + if(compile_definitions) + set_property(TARGET ${module} APPEND PROPERTY + COMPILE_DEFINITIONS ${compile_definitions}) + + set_source_files_properties("${source}" PROPERTIES COMPILE_DEFINITIONS "") + endif() + endforeach(source) + endif() + + list(APPEND ALL_INTERROGATE_MODULES "${module}") + set(ALL_INTERROGATE_MODULES "${ALL_INTERROGATE_MODULES}" CACHE INTERNAL "Internal variable") +endfunction(add_python_module) diff --git a/cmake/macros/PackageConfig.cmake b/cmake/macros/PackageConfig.cmake new file mode 100644 index 0000000000..b3160e49fe --- /dev/null +++ b/cmake/macros/PackageConfig.cmake @@ -0,0 +1,506 @@ +# Filename: PackageConfig.cmake +# +# This module defines functions which find and configure libraries +# and packages for Panda3D. +# +# Assumes an attempt to find the package has already been made with +# find_package(). (i.e. relies on packagename_FOUND variable) +# +# The packages are added as imported/interface libraries in the PKG:: +# namespace. If the package is not found (or disabled by the user), +# a dummy package will be created instead. Therefore, it is safe +# to link against the PKG::PACKAGENAME target unconditionally. +# +# Function: package_option +# Usage: +# package_option(package_name package_doc_string +# [DEFAULT ON | OFF] +# [IMPORTED_AS CMake::Imported::Target [...]] +# [FOUND_AS find_name] +# [LICENSE license]) +# +# Examples: +# package_option(LIBNAME "Enables LIBNAME support." DEFAULT OFF) +# +# If no default is given, the default in normal +# builds is to enable all found third-party packages. +# In builds for redistribution, there is the additional requirement that +# the package be suitably-licensed. +# +# FOUND_AS indicates the name of the CMake find_package() module, which +# may differ from Panda3D's internal name for that package. +# +# IMPORTED_AS is used to indicate that the find_package() may have +# provided one or more IMPORTED targets, and that if at least one is +# found, the IMPORTED target(s) should be used instead of the +# variables provided by find_package() +# +# +# Function: package_status +# Usage: +# package_status(package_name "Package description" ["Config summary"]) +# +# Examples: +# package_status(OpenAL "OpenAL Audio Output") +# package_status(ROCKET "Rocket" "without Python bindings") +# +# +# Function: show_packages +# Usage: +# show_packages() +# +# This prints the package usage report using the information provided in +# calls to package_status above. +# + +set(_ALL_PACKAGE_OPTIONS CACHE INTERNAL "Internal variable") + +# +# package_option +# +# In order to make sure no third-party licenses are inadvertently violated, +# this imposes a few rules regarding license: +# 1) If there is no license, no special restrictions. +# 2) If there is a license, but the build is not flagged for redistribution, +# no special restrictions. +# 3) If there is a license, and this is for redistribution, the package is +# forcibly defaulted off and must be explicitly enabled, unless the license +# matches a list of licenses suitable for redistribution. +# +function(package_option name) + # Parse the arguments. + set(command) + set(default) + set(found_as "${name}") + set(imported_as) + set(license "") + set(cache_string) + + string(TOUPPER "${name}" name) + + foreach(arg ${ARGN}) + if(command STREQUAL "DEFAULT") + set(default "${arg}") + set(command) + + elseif(command STREQUAL "FOUND_AS") + set(found_as "${arg}") + set(command) + + elseif(command STREQUAL "LICENSE") + set(license "${arg}") + set(command) + + elseif(arg STREQUAL "DEFAULT") + set(command "DEFAULT") + + elseif(arg STREQUAL "FOUND_AS") + set(command "FOUND_AS") + + elseif(arg STREQUAL "LICENSE") + set(command "LICENSE") + + elseif(arg STREQUAL "IMPORTED_AS") + set(command "IMPORTED_AS") + + elseif(command STREQUAL "IMPORTED_AS") + list(APPEND imported_as "${arg}") + + else() + # Yes, a list, because semicolons can be in there, and + # that gets split up into multiple args, so we have to + # join it back together here. + list(APPEND cache_string "${arg}") + + endif() + endforeach() + + if(command AND NOT command STREQUAL "IMPORTED_AS") + message(SEND_ERROR "${command} in package_option takes an argument") + endif() + + # If the default is not set, we set it. + if(NOT DEFINED default) + if(IS_DIST_BUILD) + # Accept things that don't have a configured license + if(license STREQUAL "") + set(default "${${found_as}_FOUND}") + + else() + list(FIND PANDA_DIST_USE_LICENSES ${license} license_index) + # If the license isn't in the accept listed, don't use the package + if(${license_index} EQUAL "-1") + set(default OFF) + + else() + set(default "${${found_as}_FOUND}") + + endif() + + endif() + + else() + set(default "${${found_as}_FOUND}") + + endif() + endif() + + # If it was set by the user but not found, display an error. + string(TOUPPER "${found_as}" FOUND_AS) + if(HAVE_${name} AND NOT ${found_as}_FOUND AND NOT ${FOUND_AS}_FOUND) + message(SEND_ERROR "NOT FOUND: ${name}. Disable HAVE_${name} to continue.") + endif() + + # Prevent the function from being called twice. + # This would indicate a cmake error. + if(";${_ALL_PACKAGE_OPTIONS};" MATCHES ";${name};") + message(SEND_ERROR "package_option(${name}) was called twice. + This is a bug in the cmake build scripts.") + + else() + list(APPEND _ALL_PACKAGE_OPTIONS "${name}") + set(_ALL_PACKAGE_OPTIONS "${_ALL_PACKAGE_OPTIONS}" CACHE INTERNAL "Internal variable") + + endif() + + set(PANDA_PACKAGE_DEFAULT_${name} "${default}" PARENT_SCOPE) + + # Create the INTERFACE library used to depend on this package. + add_library(PKG::${name} INTERFACE IMPORTED GLOBAL) + + # Explicitly record the package's include directories as system include + # directories. CMake does do this automatically for INTERFACE libraries, but + # it does it by discovering all transitive links first, then reading + # INTERFACE_INCLUDE_DIRECTORIES for those which are INTERFACE libraries. So, + # this would be broken for the metalib system (pre CMake 3.12) which doesn't + # "link" the object libraries. + if(CMAKE_VERSION VERSION_LESS "3.12") + set_target_properties(PKG::${name} PROPERTIES + INTERFACE_SYSTEM_INCLUDE_DIRECTORIES + "$") + endif() + + # Create the option, and if it actually is enabled, populate the INTERFACE + # library created above + option("HAVE_${name}" "${cache_string}" "${default}") + if(HAVE_${name}) + set(use_variables ON) + + # This is gross, but we actually want to hide package include directories + # from Interrogate to make sure it relies on parser-inc instead, so we'll + # use some generator expressions to do that. + set(_is_not_interface_lib + "$,INTERFACE_LIBRARY>>") + set(_is_not_interrogate + "$>>>") + + foreach(implib ${imported_as}) + if(TARGET ${implib}) + # We found one of the implibs, so we don't need to use variables + # (below) anymore + set(use_variables OFF) + + # Hide it from Interrogate + target_link_libraries(PKG::${name} INTERFACE + "$<${_is_not_interrogate}:$>") + endif() + endforeach(implib) + + if(use_variables) + if(DEFINED ${found_as}_INCLUDE_DIRS) + set(includes ${${found_as}_INCLUDE_DIRS}) + elseif(DEFINED ${found_as}_INCLUDE_DIR) + set(includes "${${found_as}_INCLUDE_DIR}") + elseif(DEFINED ${FOUND_AS}_INCLUDE_DIRS) + set(includes ${${FOUND_AS}_INCLUDE_DIRS}) + else() + set(includes "${${FOUND_AS}_INCLUDE_DIR}") + endif() + + if(DEFINED ${found_as}_LIBRARIES) + set(libs ${${found_as}_LIBRARIES}) + elseif(DEFINED ${found_as}_LIBRARY) + set(libs "${${found_as}_LIBRARY}") + elseif(DEFINED ${FOUND_AS}_LIBRARIES) + set(libs ${${FOUND_AS}_LIBRARIES}) + else() + set(libs "${${FOUND_AS}_LIBRARY}") + endif() + + target_link_libraries(PKG::${name} INTERFACE ${libs}) + + # Hide it from Interrogate + set_target_properties(PKG::${name} PROPERTIES + INTERFACE_INCLUDE_DIRECTORIES "$<${_is_not_interrogate}:${includes}>") + endif() + endif() +endfunction(package_option) + +set(_ALL_CONFIG_PACKAGES CACHE INTERNAL "Internal variable") + +# +# package_status +# +function(package_status name desc) + set(note "") + foreach(arg ${ARGN}) + set(note "${arg}") + endforeach() + + string(TOUPPER "${name}" name) + + if(NOT ";${_ALL_PACKAGE_OPTIONS};" MATCHES ";${name};") + message(SEND_ERROR "package_status(${name}) was called before package_option(${name}). + This is a bug in the cmake build scripts.") + return() + endif() + + if(";${_ALL_CONFIG_PACKAGES};" MATCHES ";${name};") + message(SEND_ERROR "package_status(${name}) was called twice. + This is a bug in the cmake build scripts.") + + else() + list(APPEND _ALL_CONFIG_PACKAGES "${name}") + set(_ALL_CONFIG_PACKAGES "${_ALL_CONFIG_PACKAGES}" CACHE INTERNAL "Internal variable") + + endif() + + set(PANDA_PACKAGE_DESC_${name} "${desc}" PARENT_SCOPE) + set(PANDA_PACKAGE_NOTE_${name} "${note}" PARENT_SCOPE) +endfunction() + +# +# show_packages +# +function(show_packages) + message("") + message("Configuring support for the following optional third-party packages:") + + foreach(package ${_ALL_CONFIG_PACKAGES}) + set(desc "${PANDA_PACKAGE_DESC_${package}}") + set(note "${PANDA_PACKAGE_NOTE_${package}}") + if(HAVE_${package}) + if(NOT note STREQUAL "") + message("+ ${desc} (${note})") + else() + message("+ ${desc}") + endif() + + else() + if(NOT ${package}_FOUND) + set(reason "not found") + elseif(NOT PANDA_PACKAGE_DEFAULT_${package}) + set(reason "not requested") + else() + set(reason "disabled") + endif() + + message("- ${desc} (${reason})") + + endif() + endforeach() +endfunction() + +# +# export_packages(filename) +# +# Generates an includable CMake file that contains definitions for every PKG:: +# package defined. +# +function(export_packages filename) + set(exports "# Exports for Panda3D PKG:: packages\n") + + foreach(pkg ${_ALL_PACKAGE_OPTIONS}) + set(exports "${exports}\n# Create imported target PKG::${pkg}\n") + set(exports "${exports}add_library(PKG::${pkg} INTERFACE IMPORTED)\n\n") + + set(exports "${exports}set_target_properties(PKG::${pkg} PROPERTIES\n") + foreach(prop + INTERFACE_COMPILE_DEFINITIONS + INTERFACE_COMPILE_FEATURES + INTERFACE_COMPILE_OPTIONS + INTERFACE_INCLUDE_DIRECTORIES + INTERFACE_LINK_DEPENDS + INTERFACE_LINK_DIRECTORIES + INTERFACE_LINK_OPTIONS + INTERFACE_POSITION_INDEPENDENT_CODE + #INTERFACE_SYSTEM_INCLUDE_DIRECTORIES # Let the consumer dictate this + INTERFACE_SOURCES) + + set(prop_ex "$") + set(exports "${exports}$<$: ${prop} \"${prop_ex}\"\n>") + + endforeach(prop) + + # Ugh, INTERFACE_LINK_LIBRARIES isn't transitive. Fine. Take care of it + # by hand: + set(libraries) + set(stack "PKG::${pkg}") + set(history) + while(stack) + # Remove head item from stack + unset(head) + while(NOT DEFINED head) + if(NOT stack) + break() + endif() + + list(GET stack 0 head) + list(REMOVE_AT stack 0) + + # Don't visit anything twice + list(FIND history "${head}" _index) + if(_index GREATER -1) + unset(head) + endif() + endwhile() + + if(head) + list(APPEND history "${head}") + else() + break() + endif() + + # If head isn't a target, add it to `libraries`, else recurse + if(TARGET "${head}") + get_target_property(link_libs "${head}" INTERFACE_LINK_LIBRARIES) + if(link_libs) + list(APPEND stack ${link_libs}) + endif() + + get_target_property(type "${head}" TYPE) + if(NOT type STREQUAL "INTERFACE_LIBRARY") + get_target_property(imported_location "${head}" IMPORTED_LOCATION) + get_target_property(imported_implib "${head}" IMPORTED_IMPLIB) + if(imported_implib) + list(APPEND libraries ${imported_implib}) + elseif(imported_location) + list(APPEND libraries ${imported_location}) + endif() + + get_target_property(configs "${head}" IMPORTED_CONFIGURATIONS) + if(configs AND NOT imported_location) + foreach(config ${configs}) + get_target_property(imported_location "${head}" IMPORTED_LOCATION_${config}) + + # Prefer IMPORTED_IMPLIB where present + get_target_property(imported_implib "${head}" IMPORTED_IMPLIB_${config}) + if(imported_implib) + set(imported_location "${imported_implib}") + endif() + + if(imported_location) + if(configs MATCHES ".*;.*") + set(_bling "$<1:$>") # genex-escaped $ + list(APPEND libraries "${_bling}<${_bling}:${imported_location}>") + + else() + list(APPEND libraries ${imported_location}) + + endif() + endif() + endforeach(config) + endif() + + elseif(CMAKE_VERSION VERSION_GREATER "3.8") + # This is an INTERFACE_LIBRARY, and CMake is new enough to support + # IMPORTED_IMPLIB + get_target_property(imported_libname "${head}" IMPORTED_LIBNAME) + if(imported_libname) + list(APPEND libraries ${imported_libname}) + endif() + + endif() + + elseif("${head}" MATCHES "\\$]+\)>") + string(REGEX REPLACE ".*\\$]+\)>.*" "\\1" match "${head}") + list(APPEND stack "${match}") + + else() + list(APPEND libraries "${head}") + + endif() + endwhile(stack) + + set(exports "${exports} INTERFACE_LINK_LIBRARIES \"${libraries}\"\n") + + set(exports "${exports})\n") + endforeach(pkg) + + # file(GENERATE) does not like $ (and it's meant to be + # consumed by our importer) so we escape it + set(_bling "$<1:$>") # genex-escaped $ + string(REPLACE "$ "${destination}/${dstfile}" < "${source}/${filename}" + DEPENDS host_pzip + COMMENT "") + + else() + # If pzip isn't built, we just copy instead. + list(APPEND dstfiles "${destination}/${filename}") + + add_custom_command(OUTPUT "${destination}/${filename}" + COMMAND ${CMAKE_COMMAND} -E + copy_if_different "${source}/${filename}" "${destination}/${filename}" + COMMENT "") + + endif() + + endforeach(filename) + + add_custom_target(${target_name} ALL + DEPENDS ${dstfiles} + WORKING_DIRECTORY "${destination}") + +endfunction(run_pzip) diff --git a/cmake/macros/Versioning.cmake b/cmake/macros/Versioning.cmake new file mode 100644 index 0000000000..33dbeb87d2 --- /dev/null +++ b/cmake/macros/Versioning.cmake @@ -0,0 +1,21 @@ +# Filename: Versioning.cmake +# +# Description: Contains an override for add_library to set the +# VERSION and SOVERSION properties on all shared libraries, automatically, to +# the project version. +# +# Functions: +# add_library(...) +# + +function(add_library target_name) + _add_library("${target_name}" ${ARGN}) + + get_target_property(type "${target_name}" TYPE) + if(type STREQUAL "SHARED_LIBRARY") + set_target_properties("${target_name}" PROPERTIES + VERSION "${PROJECT_VERSION}" + SOVERSION "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}") + endif() + +endfunction(add_library) diff --git a/cmake/modules/FindARToolKit.cmake b/cmake/modules/FindARToolKit.cmake new file mode 100644 index 0000000000..fa383768e6 --- /dev/null +++ b/cmake/modules/FindARToolKit.cmake @@ -0,0 +1,33 @@ +# Filename: FindARToolKit.cmake +# Authors: CFSworks (3 Nov, 2018) +# +# Usage: +# find_package(ARToolKit [REQUIRED] [QUIET]) +# +# Once done this will define: +# ARTOOLKIT_FOUND - system has ARToolKit +# ARTOOLKIT_INCLUDE_DIR - the include directory containing ARToolKit header files +# ARTOOLKIT_LIBRARIES - the paths to the ARToolKit client libraries +# + +find_path(ARTOOLKIT_INCLUDE_DIR "AR/ar.h") + +find_library(ARTOOLKIT_AR_LIBRARY + NAMES "AR" "libAR") + +find_library(ARTOOLKIT_ARMulti_LIBRARY + NAMES "ARMulti" "libARMulti") + +mark_as_advanced(ARTOOLKIT_INCLUDE_DIR ARTOOLKIT_AR_LIBRARY ARTOOLKIT_ARMulti_LIBRARY) + +set(ARTOOLKIT_LIBRARIES) +if(ARTOOLKIT_AR_LIBRARY) + list(APPEND ARTOOLKIT_LIBRARIES "${ARTOOLKIT_AR_LIBRARY}") +endif() +if(ARTOOLKIT_ARMulti_LIBRARY) + list(APPEND ARTOOLKIT_LIBRARIES "${ARTOOLKIT_ARMulti_LIBRARY}") +endif() + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(ARToolKit DEFAULT_MSG + ARTOOLKIT_INCLUDE_DIR ARTOOLKIT_LIBRARIES) diff --git a/cmake/modules/FindAssimp.cmake b/cmake/modules/FindAssimp.cmake new file mode 100644 index 0000000000..2a73babc9b --- /dev/null +++ b/cmake/modules/FindAssimp.cmake @@ -0,0 +1,33 @@ +# Filename: FindAssimp.cmake +# Authors: CFSworks (9 Nov, 2018) +# +# Usage: +# find_package(Assimp [REQUIRED] [QUIET]) +# +# Once done this will define: +# ASSIMP_FOUND - system has Assimp +# ASSIMP_INCLUDE_DIR - the path to the location of the assimp/ directory +# ASSIMP_LIBRARIES - the libraries to link against for Assimp +# + +find_path(ASSIMP_INCLUDE_DIR + NAMES "assimp/Importer.hpp") + +find_library(ASSIMP_ASSIMP_LIBRARY + NAMES "assimp") + +find_library(ASSIMP_IRRXML_LIBRARY + NAMES "IrrXML") + +if(ASSIMP_ASSIMP_LIBRARY) + set(ASSIMP_LIBRARIES "${ASSIMP_ASSIMP_LIBRARY}") + + if(ASSIMP_IRRXML_LIBRARY) + list(APPEND ASSIMP_LIBRARIES "${ASSIMP_IRRXML_LIBRARY}") + endif() +endif() + +mark_as_advanced(ASSIMP_INCLUDE_DIR ASSIMP_LIBRARIES) + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(Assimp DEFAULT_MSG ASSIMP_INCLUDE_DIR ASSIMP_LIBRARIES) diff --git a/cmake/modules/FindCg.cmake b/cmake/modules/FindCg.cmake new file mode 100644 index 0000000000..ed6805c4be --- /dev/null +++ b/cmake/modules/FindCg.cmake @@ -0,0 +1,175 @@ +# Filename: FindCg.cmake +# Author: kestred (8 Dec, 2013) +# +# Usage: +# find_package(Cg [REQUIRED] [QUIET]) +# +# Once done this will define: +# CG_FOUND - system has NvidiaCg +# CG_INCLUDE_DIR - the NvidiaCg include directory +# CG_INCLUDE_DIRS - directories for all NvidiaCg components +# CG_LIBRARY_DIR - the NvidiaCg library directory +# CG_LIBRARY - the path to the library binary +# CG_LIBRARIES - the paths to the Cg library and each library below. +# +# CGGL_FOUND - system has CgGL +# CGGL_INCLUDE_DIR - the CgGL include directory +# CGGL_LIBRARY_DIR - the CgGL library directory +# CGGL_LIBRARY - the path to the library binary +# + + +### Define macros to find each sublibrary ### + +# Find Cg for OpenGL +macro(find_cggl) + if(APPLE) + # GL support is built-in on Apple + set(CGGL_LIBRARY "${CG_LIBRARY}") + set(CGGL_LIBRARY_DIR "${CG_LIBRARY_DIR}") + set(CGGL_INCLUDE_DIR "${CG_INCLUDE_DIR}") + endif() + + if(Cg_FIND_QUIETLY) + set(CgGL_FIND_QUIETLY TRUE) + endif() + if(NOT CGGL_LIBRARY_DIR OR NOT CGGL_INCLUDE_DIR) + # Find the include directory + find_path(CGGL_INCLUDE_DIR + NAMES "cgGL.h" + PATHS "C:/Program Files/Cg" + "C:/Program Files/NVIDIA Corporation/Cg/include" + "/usr/include" + "/usr/local/include" + "/opt/Cg" + "/opt/nvidia-cg-toolkit/include" # Gentoo + PATH_SUFFIXES "" "Cg" "cg" + DOC "The path to NvidiaCgGL's include directory." + ) + + # Find the library directory + find_library(CGGL_LIBRARY + NAMES "CgGL" "libCgGL" + PATHS "C:/Program Files/Cg" + "C:/Program Files/NVIDIA Corporation/Cg" + "/usr" + "/usr/lib/x86_64-linux-gnu" + "/usr/local" + "/opt/Cg" + "/opt/nvidia-cg-toolkit" # Gentoo + PATH_SUFFIXES "" "lib" "lib32" "lib64" + DOC "The filepath to NvidiaCgGL's libary binary." + ) + get_filename_component(CGGL_LIBRARY_DIR "${CGGL_LIBRARY}" PATH) + set(CGGL_LIBRARY_DIR "${CGGL_LIBRARY_DIR}" CACHE PATH "The path to the CgGL library directory.") # Library path + + mark_as_advanced(CGGL_INCLUDE_DIR) + mark_as_advanced(CGGL_LIBRARY_DIR) + mark_as_advanced(CGGL_LIBRARY) + endif() + + find_package_handle_standard_args(CgGL DEFAULT_MSG CGGL_LIBRARY CGGL_INCLUDE_DIR CGGL_LIBRARY_DIR) + +endmacro() + + +# Find Cg for Direct3D 9 +macro(find_cgd3d9) + if(Cg_FIND_QUIETLY) + set(CgD3D9_FIND_QUIETLY TRUE) + endif() + if(NOT CGD3D9_LIBRARY_DIR OR NOT CGD3D9_INCLUDE_DIR) + # Find the include directory + find_path(CGD3D9_INCLUDE_DIR + NAMES "cgD3D9.h" + PATHS "C:/Program Files/Cg" + "C:/Program Files/NVIDIA Corporation/Cg/include" + "/usr/include" + "/usr/local/include" + "/opt/Cg" + "/opt/nvidia-cg-toolkit/include" # Gentoo + PATH_SUFFIXES "" "Cg" "cg" + DOC "The path to NvidiaCgD3D9's include directory." + ) + + # Find the library directory + find_library(CGD3D9_LIBRARY + NAMES "CgD3D9" "libCgD3D9" + PATHS "C:/Program Files/Cg" + "C:/Program Files/NVIDIA Corporation/Cg" + "/usr" + "/usr/lib/x86_64-linux-gnu" + "/usr/local" + "/opt/Cg" + "/opt/nvidia-cg-toolkit" # Gentoo + PATH_SUFFIXES "" "lib" "lib32" "lib64" + DOC "The filepath to NvidiaCgD3D9's libary binary." + ) + get_filename_component(CGD3D9_LIBRARY_DIR "${CGD3D9_LIBRARY}" PATH) + set(CGD3D9_LIBRARY_DIR "${CGD3D9_LIBRARY_DIR}" CACHE PATH "The path to the CgD3D9 library directory.") # Library path + + mark_as_advanced(CGD3D9_INCLUDE_DIR) + mark_as_advanced(CGD3D9_LIBRARY_DIR) + mark_as_advanced(CGD3D9_LIBRARY) + endif() + + find_package_handle_standard_args(CgD3D9 DEFAULT_MSG CGD3D9_LIBRARY CGD3D9_INCLUDE_DIR CGD3D9_LIBRARY_DIR) + +endmacro() + + + +# Find base Nvidia Cg +if(NOT CG_LIBRARY_DIR OR NOT CG_INCLUDE_DIRS) + # Find the include directory + find_path(CG_INCLUDE_DIR + NAMES "Cg/cg.h" + PATHS "C:/Program Files/Cg" + "C:/Program Files/NVIDIA Corporation/Cg/include" + "/usr/include" + "/usr/local/include" + "/opt/Cg" + "/opt/nvidia-cg-toolkit/include" # Gentoo + PATH_SUFFIXES "" "Cg" "cg" + DOC "The path to NvidiaCg's include directory." + ) + + # Find the library directory + find_library(CG_LIBRARY + NAMES "Cg" "libCg" + PATHS "C:/Program Files/Cg" + "C:/Program Files/NVIDIA Corporation/Cg" + "/usr" + "/usr/lib/x86_64-linux-gnu" + "/usr/local" + "/opt/Cg" + "/opt/nvidia-cg-toolkit" # Gentoo + PATH_SUFFIXES "" "lib" "lib32" "lib64" + ) + get_filename_component(CG_LIBRARY_DIR "${CG_LIBRARY}" PATH) + set(CG_LIBRARY_DIR "${CG_LIBRARY_DIR}" CACHE PATH "The path to NvidiaCG's library directory.") # Library path + + string(REGEX REPLACE "/Cg$" "" CG_BASE_INCLUDE_DIR "${CG_INCLUDE_DIR}") + set(CG_INCLUDE_DIRS ${CG_BASE_INCLUDE_DIR} ${CG_INCLUDE_DIR}) + + mark_as_advanced(CG_INCLUDE_DIRS) + mark_as_advanced(CG_INCLUDE_DIR) + mark_as_advanced(CG_LIBRARY_DIR) + mark_as_advanced(CG_LIBRARY) +endif() + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(Cg DEFAULT_MSG CG_LIBRARY CG_INCLUDE_DIRS CG_LIBRARY_DIR) + +if(CG_INCLUDE_DIR AND CG_LIBRARY_DIR) + find_cggl() + find_cgd3d9() + + set(CG_LIBRARIES ${CG_LIBRARY}) + if(CGGL_LIBRARY) + list(APPEND CG_LIBRARIES "${CGGL_LIBRARY}") + endif() + if(CGD3D9_LIBRARY) + list(APPEND CG_LIBRARIES "${CGD3D9_LIBRARY}") + endif() +endif() diff --git a/cmake/modules/FindDirect3D9.cmake b/cmake/modules/FindDirect3D9.cmake new file mode 100644 index 0000000000..4752150b4b --- /dev/null +++ b/cmake/modules/FindDirect3D9.cmake @@ -0,0 +1,104 @@ +# Filename: FindDirect3D9.cmake +# Authors: CFSworks (26 Oct, 2018) +# +# Usage: +# find_package(Direct3D9 [REQUIRED] [QUIET]) +# +# This supports the following components: +# d3dx9 +# dxerr +# dxguid +# +# Once done this will define: +# DIRECT3D9_FOUND - system has Direct3D 9.x +# DIRECT3D9_INCLUDE_DIR - the include directory containing d3d9.h - note that +# this will be empty if it's part of the Windows SDK. +# DIRECT3D9_LIBRARY - the path to d3d9.lib +# DIRECT3D9_LIBRARIES - the path to d3d9.lib and all extra component +# libraries +# + +include(CheckIncludeFile) + +if(Direct3D9_FIND_QUIETLY) + if(DEFINED CMAKE_REQUIRED_QUIET) + set(_OLD_CMAKE_REQUIRED_QUIET ${CMAKE_REQUIRED_QUIET}) + endif() + # Suppress check_include_file messages + set(CMAKE_REQUIRED_QUIET ON) +endif() + +check_include_file("d3d9.h" SYSTEM_INCLUDE_D3D9_H) +mark_as_advanced(SYSTEM_INCLUDE_D3D9_H) + +if(Direct3D9_FIND_QUIETLY) + if(DEFINED _OLD_CMAKE_REQUIRED_QUIET) + set(CMAKE_REQUIRED_QUIET ${_OLD_CMAKE_REQUIRED_QUIET}) + unset(_OLD_CMAKE_REQUIRED_QUIET) + else() + unset(CMAKE_REQUIRED_QUIET) + endif() +endif() + +if(SYSTEM_INCLUDE_D3D9_H + AND NOT Direct3D9_FIND_REQUIRED_d3dx9 + AND NOT Direct3D9_FIND_REQUIRED_dxerr) + # It's available as #include - easy enough. We'll use "." as a way + # of saying "We found it, but please erase this variable later." + set(DIRECT3D9_INCLUDE_DIR ".") + + # Since d3d9.h is on the search path, we can pretty much assume d3d9.lib is + # as well. + set(DIRECT3D9_LIBRARY "d3d9.lib") + + # And dxguid.lib, why not + set(DIRECT3D9_dxguid_LIBRARY "dxguid.lib") + +else() + # We could not find it easily - maybe it's installed separately as part of + # the DirectX SDK? + + find_path(DIRECT3D9_INCLUDE_DIR + NAMES d3d9.h + PATHS "$ENV{DXSDK_DIR}/Include") + + if(CMAKE_SIZEOF_VOID_P EQUAL 8) + set(dx_lib_path "$ENV{DXSDK_DIR}/Lib/x64/") + else() + set(dx_lib_path "$ENV{DXSDK_DIR}/Lib/x86/") + endif() + + find_library(DIRECT3D9_LIBRARY d3d9 "${dx_lib_path}" NO_DEFAULT_PATH) + + find_library(DIRECT3D9_d3dx9_LIBRARY d3dx9 "${dx_lib_path}" NO_DEFAULT_PATH) + find_library(DIRECT3D9_dxerr_LIBRARY dxerr "${dx_lib_path}" NO_DEFAULT_PATH) + find_library(DIRECT3D9_dxguid_LIBRARY dxguid "${dx_lib_path}" NO_DEFAULT_PATH) + + unset(dx_lib_path) +endif() + +mark_as_advanced(DIRECT3D9_INCLUDE_DIR DIRECT3D9_LIBRARY) +set(DIRECT3D9_LIBRARIES "${DIRECT3D9_LIBRARY}") + +foreach(_component d3dx9 dxerr dxguid) + if(DIRECT3D9_${_component}_LIBRARY) + set(Direct3D9_${_component}_FOUND ON) + list(FIND Direct3D9_FIND_COMPONENTS "${_component}" _index) + if(${_index} GREATER -1) + list(APPEND DIRECT3D9_LIBRARIES "${DIRECT3D9_${_component}_LIBRARY}") + endif() + unset(_index) + endif() +endforeach(_component) +unset(_component) + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(Direct3D9 HANDLE_COMPONENTS + REQUIRED_VARS DIRECT3D9_INCLUDE_DIR DIRECT3D9_LIBRARY DIRECT3D9_LIBRARIES) + +# See above - if we found the include as part of the system path, we don't want +# to actually modify the include search path, but we need a non-empty string to +# satisfy find_package_handle_standard_args() +if(DIRECT3D9_INCLUDE_DIR STREQUAL ".") + set(DIRECT3D9_INCLUDE_DIR "") +endif() diff --git a/cmake/modules/FindEGL.cmake b/cmake/modules/FindEGL.cmake new file mode 100644 index 0000000000..111083db85 --- /dev/null +++ b/cmake/modules/FindEGL.cmake @@ -0,0 +1,21 @@ +# Filename: FindEGL.cmake +# Authors: CFSworks (21 Oct, 2018) +# +# Usage: +# find_package(EGL [REQUIRED] [QUIET]) +# +# Once done this will define: +# EGL_FOUND - system has EGL +# EGL_INCLUDE_DIR - the include directory containing EGL/egl.h +# EGL_LIBRARY - the library to link against for EGL +# + +find_path(EGL_INCLUDE_DIR "EGL/egl.h") + +find_library(EGL_LIBRARY + NAMES "EGL") + +mark_as_advanced(EGL_INCLUDE_DIR EGL_LIBRARY) + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(EGL DEFAULT_MSG EGL_INCLUDE_DIR EGL_LIBRARY) diff --git a/cmake/modules/FindEigen3.cmake b/cmake/modules/FindEigen3.cmake new file mode 100644 index 0000000000..6b56819383 --- /dev/null +++ b/cmake/modules/FindEigen3.cmake @@ -0,0 +1,25 @@ +# Filename: FindEigen3.cmake +# Authors: kestred (13 Dec, 2013) +# +# Usage: +# find_package(Eigen3 [REQUIRED] [QUIET]) +# +# Once done this will define: +# EIGEN_FOUND - system has any version of Eigen +# EIGEN3_FOUND - system has Eigen3 +# EIGEN3_INCLUDE_DIR - the Eigen3 include directory +# + +find_path(EIGEN3_INCLUDE_DIR + NAMES signature_of_eigen3_matrix_library + PATH_SUFFIXES eigen3 eigen) + +mark_as_advanced(EIGEN3_INCLUDE_DIR) + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(Eigen3 DEFAULT_MSG EIGEN3_INCLUDE_DIR) + +if(EIGEN3_FOUND) + set(EIGEN_FOUND TRUE) + set(EIGEN_INCLUDE_DIR ${EIGEN3_INCLUDE_DIR}) +endif() diff --git a/cmake/modules/FindFCollada.cmake b/cmake/modules/FindFCollada.cmake new file mode 100644 index 0000000000..fcf4ee492d --- /dev/null +++ b/cmake/modules/FindFCollada.cmake @@ -0,0 +1,88 @@ +# Filename: FindFCollada.cmake +# Author: CFSworks (17 Mar, 2019) +# +# Usage: +# find_package(FCollada [REQUIRED] [QUIET]) +# +# Once done this will define: +# FCOLLADA_FOUND - system has FCollada +# FCOLLADA_INCLUDE_DIR - the FCollada include directory +# +# FCOLLADA_RELEASE_LIBRARY - the filepath of the FCollada release library +# FCOLLADA_DEBUG_LIBRARY - the filepath of the FCollada debug library +# +# FCollada::FCollada - The recommended FCollada library to link against +# + +# Find the FCollada include files +find_path(FCOLLADA_INCLUDE_DIR "FCollada.h" PATH_SUFFIXES "FCollada") + +# Find the library built for release +find_library(FCOLLADA_RELEASE_LIBRARY + NAMES "FCollada" "libFCollada" + "FColladaS" "libFColladaS" + "FColladaU" "libFColladaU" + "FColladaSU" "libFColladaSU" +) + +# Find the library built for debug +find_library(FCOLLADA_DEBUG_LIBRARY + NAMES "FColladaD" "libFColladaD" + "FColladaSD" "libFColladaSD" + "FColladaUD" "libFColladaUD" + "FColladaSUD" "libFColladaSUD" +) + +mark_as_advanced(FCOLLADA_INCLUDE_DIR) +mark_as_advanced(FCOLLADA_RELEASE_LIBRARY) +mark_as_advanced(FCOLLADA_DEBUG_LIBRARY) + +set(_defines) +if(FCOLLADA_RELEASE_LIBRARY MATCHES "FCollada[^/]*U" OR + FCOLLADA_DEBUG_LIBRARY MATCHES "FCollada[^/]*U") + list(APPEND _defines "UNICODE") +endif() +if(NOT MSVC AND + NOT FCOLLADA_RELEASE_LIBRARY MATCHES "FCollada[^/]*S" AND + NOT FCOLLADA_DEBUG_LIBRARY MATCHES "FCollada[^/]*S") + list(APPEND _defines "FCOLLADA_DLL") +endif() + +# Identify the configs which we have available +set(_configs) +if(FCOLLADA_INCLUDE_DIR) + if(FCOLLADA_RELEASE_LIBRARY) + list(APPEND _configs RELEASE) + endif() + if(FCOLLADA_DEBUG_LIBRARY) + list(APPEND _configs DEBUG) + endif() + + if(_configs) + set(_HAS_FCOLLADA_LIBRARY ON) + add_library(FCollada::FCollada UNKNOWN IMPORTED GLOBAL) + + set_target_properties(FCollada::FCollada PROPERTIES + INTERFACE_COMPILE_DEFINITIONS "${_defines}" + INTERFACE_INCLUDE_DIRECTORIES "${FCOLLADA_INCLUDE_DIR}") + + endif() + +endif() + +foreach(_config ${_configs}) + set_property(TARGET FCollada::FCollada + APPEND PROPERTY IMPORTED_CONFIGURATIONS "${_config}") + + set_target_properties(FCollada::FCollada PROPERTIES + IMPORTED_LOCATION_${_config} "${FCOLLADA_${_config}_LIBRARY}") + +endforeach(_config) +unset(_config) +unset(_configs) +unset(_defines) + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(FCollada DEFAULT_MSG FCOLLADA_INCLUDE_DIR _HAS_FCOLLADA_LIBRARY) + +unset(_HAS_FCOLLADA_LIBRARY) diff --git a/cmake/modules/FindFFMPEG.cmake b/cmake/modules/FindFFMPEG.cmake new file mode 100644 index 0000000000..88a0021be6 --- /dev/null +++ b/cmake/modules/FindFFMPEG.cmake @@ -0,0 +1,116 @@ +# Filename: FindFFMPEG.cmake +# Author: CFSworks (10 Apr, 2014) +# +# Usage: +# find_package(FFMPEG [REQUIRED] [QUIET]) +# +# Once done this will define: +# FFMPEG_FOUND - system has ffmpeg +# FFMPEG_INCLUDE_DIR - the ffmpeg include directory +# FFMPEG_LIBRARIES - the path to the library binary +# +# FFMPEG_LIBAVCODEC - the path to the libavcodec library binary +# FFMPEG_LIBAVFORMAT - the path to the libavformat library binary +# FFMPEG_LIBAVUTIL - the path to the libavutil library binary +# + +# Find the libffmpeg include files +find_path(FFMPEG_INCLUDE_DIR + NAMES "libavcodec/avcodec.h" + PATHS "/usr/include" + "/usr/local/include" + "/sw/include" + "/opt/include" + "/opt/local/include" + "/opt/csw/include" + PATH_SUFFIXES "libav" "ffmpeg" +) + +# Find the libavcodec library +find_library(FFMPEG_LIBAVCODEC + NAMES "avcodec" + PATHS "/usr" + "/usr/local" + "/usr/freeware" + "/sw" + "/opt" + "/opt/csw" + PATH_SUFFIXES "lib" "lib32" "lib64" +) + +# Find the libavformat library +find_library(FFMPEG_LIBAVFORMAT + NAMES "avformat" + PATHS "/usr" + "/usr/local" + "/usr/freeware" + "/sw" + "/opt" + "/opt/csw" + PATH_SUFFIXES "lib" "lib32" "lib64" +) + +# Find the libavutil library +find_library(FFMPEG_LIBAVUTIL + NAMES "avutil" + PATHS "/usr" + "/usr/local" + "/usr/freeware" + "/sw" + "/opt" + "/opt/csw" + PATH_SUFFIXES "lib" "lib32" "lib64" +) + +mark_as_advanced(FFMPEG_INCLUDE_DIR) +mark_as_advanced(FFMPEG_LIBAVCODEC) +mark_as_advanced(FFMPEG_LIBAVFORMAT) +mark_as_advanced(FFMPEG_LIBAVUTIL) + +# Translate library into library directory +if(FFMPEG_LIBAVCODEC) + unset(FFMPEG_LIBRARY_DIR CACHE) + get_filename_component(FFMPEG_LIBRARY_DIR "${FFMPEG_LIBAVCODEC}" PATH) + set(FFMPEG_LIBRARY_DIR "${FFMPEG_LIBRARY_DIR}" CACHE PATH "The path to libffmpeg's library directory.") # Library path +endif() + +set(FFMPEG_LIBRARIES) +if(FFMPEG_LIBAVCODEC) + list(APPEND FFMPEG_LIBRARIES "${FFMPEG_LIBAVCODEC}") +endif() +if(FFMPEG_LIBAVFORMAT) + list(APPEND FFMPEG_LIBRARIES "${FFMPEG_LIBAVFORMAT}") +endif() +if(FFMPEG_LIBAVUTIL) + list(APPEND FFMPEG_LIBRARIES "${FFMPEG_LIBAVUTIL}") +endif() + +if(APPLE) + # When statically built for Apple, FFMPEG may have dependencies on these + # additional frameworks and libraries. + + find_library(APPLE_COREVIDEO_LIBRARY CoreVideo) + if(APPLE_COREVIDEO_LIBRARY) + list(APPEND FFMPEG_LIBRARIES "${APPLE_COREVIDEO_LIBRARY}") + endif() + + find_library(APPLE_VDA_LIBRARY VideoDecodeAcceleration) + if(APPLE_VDA_LIBRARY) + list(APPEND FFMPEG_LIBRARIES "${APPLE_VDA_LIBRARY}") + endif() + + find_library(APPLE_ICONV_LIBRARY iconv) + if(APPLE_ICONV_LIBRARY) + list(APPEND FFMPEG_LIBRARIES "${APPLE_ICONV_LIBRARY}") + endif() + + find_library(APPLE_BZ2_LIBRARY bz2) + if(APPLE_BZ2_LIBRARY) + list(APPEND FFMPEG_LIBRARIES "${APPLE_BZ2_LIBRARY}") + endif() +endif() + +mark_as_advanced(FFMPEG_LIBRARY_DIR) + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(FFMPEG DEFAULT_MSG FFMPEG_LIBRARIES FFMPEG_LIBAVCODEC FFMPEG_LIBAVFORMAT FFMPEG_LIBAVUTIL FFMPEG_INCLUDE_DIR FFMPEG_LIBRARY_DIR) diff --git a/cmake/modules/FindFFTW3.cmake b/cmake/modules/FindFFTW3.cmake new file mode 100644 index 0000000000..23f76cc5e5 --- /dev/null +++ b/cmake/modules/FindFFTW3.cmake @@ -0,0 +1,107 @@ +# Filename: FindFFTW.cmake +# Author: Unknown (???), kestred (29 Nov, 2013) +# +# Usage: +# find_package(FFTW [REQUIRED] [QUIET]) +# +# Once done this will define: +# FFTW3_FOUND - true if fftw is found on the system +# FFTW3_INCLUDE_DIR - the fftw include directory +# FFTW3_LIBRARY_DIR - the fftw library directory +# FFTW3_LIBRARY - the path to the library binary +# +# The following variables will be checked by the function +# FFTW3_ROOT - if set, the libraries are exclusively searched under this path +# + +# Check if we can use PkgConfig +find_package(PkgConfig QUIET) + +#Determine from PKG +if(PKG_CONFIG_FOUND AND NOT FFTW3_ROOT) + pkg_check_modules(PKG_FFTW QUIET "fftw3") +endif() + +if(FFTW3_ROOT) + # Try to find headers under root + find_path(FFTW3_INCLUDE_DIR + NAMES "fftw3.h" + PATHS ${FFTW3_ROOT} + PATH_SUFFIXES "include" + NO_DEFAULT_PATH + ) + + # Try to find library under root + find_library(FFTW3_LIBRARY + NAMES "fftw3" + PATHS ${FFTW3_ROOT} + PATH_SUFFIXES "lib" "lib64" + NO_DEFAULT_PATH + ) + + find_library(FFTW3_FFTWF_LIBRARY + NAMES "fftw3f" + PATHS ${FFTW3_ROOT} + PATH_SUFFIXES "lib" "lib64" + NO_DEFAULT_PATH + ) + + find_library(FFTW3_FFTWL_LIBRARY + NAMES "fftw3l" + PATHS ${FFTW3_ROOT} + PATH_SUFFIXES "lib" "lib64" + NO_DEFAULT_PATH + ) +else() + # Find headers the normal way + find_path(FFTW3_INCLUDE_DIR + NAMES "fftw3.h" + PATHS ${PKG_FFTW3_INCLUDE_DIRS} + ${INCLUDE_INSTALL_DIR} + "/usr/include" + "/usr/local/include" + PATH_SUFFIXES "" "fftw" + ) + + # Find library the normal way + find_library(FFTW3_LIBRARY + NAMES "fftw3" + PATHS ${PKG_FFTW3_LIBRARY_DIRS} + ${LIB_INSTALL_DIR} + "/usr" + "/usr/local" + PATH_SUFFIXES "" "lib" "lib32" "lib64" + ) + + find_library(FFTW3_FFTWF_LIBRARY + NAMES "fftw3f" + PATHS ${PKG_FFTW3_LIBRARY_DIRS} + ${LIB_INSTALL_DIR} + "/usr" + "/usr/local" + PATH_SUFFIXES "" "lib" "lib32" "lib64" + ) + + + find_library(FFTW3_FFTWL_LIBRARY + NAMES "fftw3l" + PATHS ${PKG_FFTW3_LIBRARY_DIRS} + ${LIB_INSTALL_DIR} + "/usr" + "/usr/local" + PATH_SUFFIXES "" "lib" "lib32" "lib64" + ) +endif() + +# Get the directory conaining FFTW3_LIBRARY +get_filename_component(FFTW3_LIBRARY_DIR "${FFTW3_LIBRARY}" PATH) +set(FFTW3_LIBRARY_DIR "${FFTW3_LIBRARY_DIR}" CACHE PATH "The path to fftw's library directory.") # Library path + +mark_as_advanced(FFTW3_INCLUDE_DIR) +mark_as_advanced(FFTW3_LIBRARY_DIR) +mark_as_advanced(FFTW3_LIBRARY) +mark_as_advanced(FFTW3_FFTWF_LIBRARY) +mark_as_advanced(FFTW3_FFTWL_LIBRARY) + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(FFTW3 DEFAULT_MSG FFTW3_LIBRARY FFTW3_INCLUDE_DIR FFTW3_LIBRARY_DIR) diff --git a/cmake/modules/FindFMODEx.cmake b/cmake/modules/FindFMODEx.cmake new file mode 100644 index 0000000000..63d0b2437a --- /dev/null +++ b/cmake/modules/FindFMODEx.cmake @@ -0,0 +1,83 @@ +# Filename: FindFMODEx.cmake +# Author: kestred (8 Dec, 2013) +# +# Usage: +# find_pcackage(FMODEx [REQUIRED] [QUIET]) +# +# Once done this will define: +# FMODEX_FOUND - system has FMOD Ex +# FMODEX_INCLUDE_DIR - the FMOD Ex include directory +# FMODEX_LIBRARY_DIR - the FMOD Ex library directory +# FMODEX_LIBRARY - the path to the library binary +# +# FMODEX_32_LIBRARY - the filepath of the FMOD Ex SDK 32-bit library +# FMOXEX_64_LIBRARY - the filepath of the FMOD Ex SDK 64-bit library +# + +# Find the include directory +find_path(FMODEX_INCLUDE_DIR + NAMES "fmod.h" + PATHS "/usr/include" + "/usr/local/include" + "/sw/include" + "/opt/include" + "/opt/local/include" + "/opt/csw/include" + "/opt/fmodex/include" + "/opt/fmodex/api/inc" + "C:/Program Files (x86)/FMOD SoundSystem/FMOD Programmers API Win32/api/inc" + PATH_SUFFIXES "" "fmodex/fmod" "fmodex/fmod3" "fmod" "fmod3" + DOC "The path to FMOD Ex's include directory." +) + +# Find the 32-bit library +find_library(FMODEX_32_LIBRARY + NAMES "fmodex_vc" "fmodex_bc" "fmodex" "fmodexL" "libfmodex" "libfmodexL" "fmodex_vc" "fmodexL_vc" + PATHS "/usr" + "/usr/local" + "/usr/X11R6" + "/usr/local/X11R6" + "/sw" + "/opt" + "/opt/local" + "/opt/csw" + "/opt/fmodex" + "/opt/fmodex/api" + "C:/Program Files (x86)/FMOD SoundSystem/FMOD Programmers API Win32/api/lib" + PATH_SUFFIXES "" "lib" "lib32" +) + +# Find the 64-bit library +find_library(FMODEX_64_LIBRARY + NAMES "fmodex64" "libfmodex64" "fmodexL64" "libfmodexL64" "fmodex64_vc" "fmodexL64_vc" + PATHS "/usr" + "/usr/local" + "/usr/X11R6" + "/usr/local/X11R6" + "/sw" + "/opt" + "/opt/local" + "/opt/csw" + "/opt/fmodex" + "/opt/fmodex/api" + "/usr/freeware" + PATH_SUFFIXES "" "lib" "lib64" +) + +if(FMODEX_32_LIBRARY) + set(FMODEX_LIBRARY ${FMODEX_32_LIBRARY} CACHE FILEPATH "The filepath to FMOD Ex's library binary.") +elseif(FMODEX_64_LIBRARY) + set(FMODEX_LIBRARY ${FMODEX_64_LIBRARY} CACHE FILEPATH "The filepath to FMOD Ex's library binary.") +endif() + +get_filename_component(FMODEX_LIBRARY_DIR "${FMODEX_LIBRARY}" PATH) +set(FMODEX_LIBRARY_DIR "${FMODEX_LIBRARY_DIR}" CACHE PATH "The path to FMOD Ex's library directory.") + +mark_as_advanced(FMODEX_INCLUDE_DIR) +mark_as_advanced(FMODEX_LIBRARY_DIR) +mark_as_advanced(FMODEX_LIBRARY) +mark_as_advanced(FMODEX_32_LIBRARY) +mark_as_advanced(FMODEX_64_LIBRARY) + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(FMODEx DEFAULT_MSG FMODEX_LIBRARY FMODEX_INCLUDE_DIR FMODEX_LIBRARY_DIR) diff --git a/cmake/modules/FindHarfBuzz.cmake b/cmake/modules/FindHarfBuzz.cmake new file mode 100644 index 0000000000..fd27ea603a --- /dev/null +++ b/cmake/modules/FindHarfBuzz.cmake @@ -0,0 +1,23 @@ +# Filename: FindHarfBuzz.cmake +# Authors: CFSworks (2 Nov, 2018) +# +# Usage: +# find_package(HarfBuzz [REQUIRED] [QUIET]) +# +# Once done this will define: +# HARFBUZZ_FOUND - system has HarfBuzz +# HARFBUZZ_INCLUDE_DIR - the include directory containing hb.h +# HARFBUZZ_LIBRARY - the path to the HarfBuzz library +# + +find_path(HARFBUZZ_INCLUDE_DIR + NAMES "hb.h" + PATH_SUFFIXES "harfbuzz") + +find_library(HARFBUZZ_LIBRARY + NAMES "harfbuzz") + +mark_as_advanced(HARFBUZZ_INCLUDE_DIR HARFBUZZ_LIBRARY) + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(HarfBuzz DEFAULT_MSG HARFBUZZ_INCLUDE_DIR HARFBUZZ_LIBRARY) diff --git a/cmake/modules/FindLibSquish.cmake b/cmake/modules/FindLibSquish.cmake new file mode 100644 index 0000000000..3399d81ae7 --- /dev/null +++ b/cmake/modules/FindLibSquish.cmake @@ -0,0 +1,78 @@ +# Filename: FindLibSquish.cmake +# Author: kestred (7 Dec, 2013) +# +# Usage: +# find_package(LibSquish [REQUIRED] [QUIET]) +# +# Once done this will define: +# LIBSQUISH_FOUND - system has libsquish +# LIBSQUISH_INCLUDE_DIR - the libsquish include directory +# LIBSQUISH_LIBRARY_DIR - the libsquish library directory +# LIBSQUISH_LIBRARY - the path to the library binary +# +# LIBSQUISH_RELEASE_LIBRARY - the filepath of the libsquish release library +# LIBSQUISH_DEBUG_LIBRARY - the filepath of the libsquish debug library +# + +# Find the libsquish include files +find_path(LIBSQUISH_INCLUDE_DIR + NAMES "squish.h" + PATHS "/usr/include" + "/usr/local/include" + "/sw/include" + "/opt/include" + "/opt/local/include" + "/opt/csw/include" + PATH_SUFFIXES "" "cppunit" +) + +# Find the libsquish library built for release +find_library(LIBSQUISH_RELEASE_LIBRARY + NAMES "squish" "libsquish" + PATHS "/usr" + "/usr/local" + "/usr/freeware" + "/sw" + "/opt" + "/opt/csw" + PATH_SUFFIXES "lib" "lib32" "lib64" +) + +# Find the libsquish library built for debug +find_library(LIBSQUISH_DEBUG_LIBRARY + NAMES "squishd" "libsquishd" + PATHS "/usr" + "/usr/local" + "/usr/freeware" + "/sw" + "/opt" + "/opt/csw" + PATH_SUFFIXES "lib" "lib32" "lib64" +) + + +mark_as_advanced(LIBSQUISH_INCLUDE_DIR) +mark_as_advanced(LIBSQUISH_RELEASE_LIBRARY) +mark_as_advanced(LIBSQUISH_DEBUG_LIBRARY) + +# Choose library +if(CMAKE_BUILD_TYPE MATCHES "Debug" AND LIBSQUISH_DEBUG_LIBRARY) + set(LIBSQUISH_LIBRARY ${LIBSQUISH_DEBUG_LIBRARY} CACHE FILEPATH "The filepath to libsquish's library binary.") +elseif(LIBSQUISH_RELEASE_LIBRARY) + set(LIBSQUISH_LIBRARY ${LIBSQUISH_RELEASE_LIBRARY} CACHE FILEPATH "The filepath to libsquish's library binary.") +elseif(LIBSQUISH_DEBUG_LIBRARY) + set(LIBSQUISH_LIBRARY ${LIBSQUISH_DEBUG_LIBRARY} CACHE FILEPATH "The filepath to libsquish's library binary.") +endif() + +# Translate library into library directory +if(LIBSQUISH_LIBRARY) + unset(LIBSQUISH_LIBRARY_DIR CACHE) + get_filename_component(LIBSQUISH_LIBRARY_DIR "${LIBSQUISH_LIBRARY}" PATH) + set(LIBSQUISH_LIBRARY_DIR "${LIBSQUISH_LIBRARY_DIR}" CACHE PATH "The path to libsquish's library directory.") # Library path +endif() + +mark_as_advanced(LIBSQUISH_LIBRARY) +mark_as_advanced(LIBSQUISH_LIBRARY_DIR) + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(LibSquish DEFAULT_MSG LIBSQUISH_LIBRARY LIBSQUISH_INCLUDE_DIR LIBSQUISH_LIBRARY_DIR) diff --git a/cmake/modules/FindODE.cmake b/cmake/modules/FindODE.cmake new file mode 100644 index 0000000000..6bd51c21f3 --- /dev/null +++ b/cmake/modules/FindODE.cmake @@ -0,0 +1,157 @@ +# Filename: FindODE.cmake +# Author: CFSworks (7 Feb, 2014) +# +# Usage: +# find_package(ODE [REQUIRED] [QUIET]) +# +# Once done this will define: +# ODE_FOUND - system has ode +# ODE_INCLUDE_DIR - the ode include directory +# +# ODE_RELEASE_LIBRARY - the filepath of the ode release library +# ODE_DEBUG_LIBRARY - the filepath of the ode debug library +# +# ODE_SINGLE_DEBUG_LIBRARY - the filepath of the single-precision ode debug library +# ODE_SINGLE_RELEASE_LIBRARY - the filepath of the single-precision ode release library +# ODE_DOUBLE_DEBUG_LIBRARY - the filepath of the double-precision ode debug library +# ODE_DOUBLE_RELEASE_LIBRARY - the filepath of the double-precision ode release library +# +# ODE::ODE - The recommended ODE library to link against +# ODE::ODE_single - If available, this links against single-precision ODE +# ODE::ODE_double - If available, this links against double-precision ODE +# + +# Find the libode include files +find_path(ODE_INCLUDE_DIR "ode/ode.h") + +# Find the libode library built for release +find_library(ODE_RELEASE_LIBRARY + NAMES "ode" "libode") + +# Find the libode library built for debug +find_library(ODE_DEBUG_LIBRARY + NAMES "oded" "liboded") + +# Find the single-precision library built for release +find_library(ODE_SINGLE_RELEASE_LIBRARY + NAMES "ode_single" "libode_single") + +# Find the single-precision library built for debug +find_library(ODE_SINGLE_DEBUG_LIBRARY + NAMES "ode_singled" "libode_singled") + +# Find the double-precision library built for release +find_library(ODE_DOUBLE_RELEASE_LIBRARY + NAMES "ode_double" "libode_double") + +# Find the double-precision library built for debug +find_library(ODE_DOUBLE_DEBUG_LIBRARY + NAMES "ode_doubled" "libode_doubled") + +# Find libccd, which ODE sometimes links against, so we want to let the linker +# know about it if it's present. +find_library(ODE_LIBCCD_LIBRARY + NAMES "ccd" "libccd") + +mark_as_advanced(ODE_INCLUDE_DIR) +mark_as_advanced(ODE_RELEASE_LIBRARY) +mark_as_advanced(ODE_DEBUG_LIBRARY) +mark_as_advanced(ODE_SINGLE_RELEASE_LIBRARY) +mark_as_advanced(ODE_SINGLE_DEBUG_LIBRARY) +mark_as_advanced(ODE_DOUBLE_RELEASE_LIBRARY) +mark_as_advanced(ODE_DOUBLE_DEBUG_LIBRARY) +mark_as_advanced(ODE_LIBCCD_LIBRARY) + +# Define targets for both precisions (and unspecified) +foreach(_precision _single _double "") + string(TOUPPER "${_precision}" _PRECISION) + + if(EXISTS "${ODE${_PRECISION}_RELEASE_LIBRARY}" OR + EXISTS "${ODE${_PRECISION}_DEBUG_LIBRARY}") + if(NOT TARGET ODE::ODE${_precision}) + add_library(ODE::ODE${_precision} UNKNOWN IMPORTED GLOBAL) + + set_target_properties(ODE::ODE${_precision} PROPERTIES + INTERFACE_INCLUDE_DIRECTORIES "${ODE_INCLUDE_DIR}") + + if(ODE_LIBCCD_LIBRARY) + set_target_properties(ODE::ODE${_precision} PROPERTIES + INTERFACE_LINK_LIBRARIES "${ODE_LIBCCD_LIBRARY}") + endif() + + if(EXISTS "${ODE${_PRECISION}_RELEASE_LIBRARY}") + set_property(TARGET ODE::ODE${_precision} APPEND PROPERTY + IMPORTED_CONFIGURATIONS RELEASE) + set_target_properties(ODE::ODE${_precision} PROPERTIES + IMPORTED_LINK_INTERFACE_LANGUAGES_RELEASE "C" + IMPORTED_LOCATION_RELEASE "${ODE${_PRECISION}_RELEASE_LIBRARY}") + endif() + + if(EXISTS "${ODE${_PRECISION}_DEBUG_LIBRARY}") + set_property(TARGET ODE::ODE${_precision} APPEND PROPERTY + IMPORTED_CONFIGURATIONS DEBUG) + set_target_properties(ODE::ODE${_precision} PROPERTIES + IMPORTED_LINK_INTERFACE_LANGUAGES_DEBUG "C" + IMPORTED_LOCATION_DEBUG "${ODE${_PRECISION}_DEBUG_LIBRARY}") + endif() + + # If this has a precision, we should be sure to define + # dIDESINGLE/dIDEDOUBLE to keep it consistent + if(_precision) + string(REPLACE "_" "dIDE" _precision_symbol "${_PRECISION}") + + set_target_properties(ODE::ODE${_precision} PROPERTIES + INTERFACE_COMPILE_DEFINITIONS "${_precision_symbol}") + + unset(_precision_symbol) + endif() + + endif() + endif() +endforeach(_precision) +unset(_precision) +unset(_PRECISION) + +# OKAY. If everything went well, we have ODE::ODE_single and/or +# ODE::ODE_double. We might even have an ODE::ODE, but if not, we need to +# alias one of the other two to it. +if(NOT TARGET ODE::ODE) + if(TARGET ODE::ODE_single) + set(_copy_from "ODE::ODE_single") + elseif(TARGET ODE::ODE_double) + set(_copy_from "ODE::ODE_double") + endif() + + if(DEFINED _copy_from) + add_library(ODE::ODE UNKNOWN IMPORTED GLOBAL) + + foreach(_prop + INTERFACE_INCLUDE_DIRECTORIES + INTERFACE_COMPILE_DEFINITIONS + INTERFACE_LINK_LIBRARIES + IMPORTED_CONFIGURATIONS + IMPORTED_LINK_INTERFACE_LANGUAGES_RELEASE + IMPORTED_LOCATION_RELEASE + IMPORTED_LINK_INTERFACE_LANGUAGES_DEBUG + IMPORTED_LOCATION_DEBUG) + + get_target_property(_value "${_copy_from}" "${_prop}") + if(_value) + set_target_properties(ODE::ODE PROPERTIES "${_prop}" "${_value}") + endif() + unset(_value) + endforeach(_prop) + unset(_prop) + endif() + + unset(_copy_from) +endif() + +if(TARGET ODE::ODE) + set(_HAS_ODE_LIBRARY ON) +endif() + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(ODE DEFAULT_MSG ODE_INCLUDE_DIR _HAS_ODE_LIBRARY) + +unset(_HAS_ODE_LIBRARY) diff --git a/cmake/modules/FindOgg.cmake b/cmake/modules/FindOgg.cmake new file mode 100644 index 0000000000..f9de72f127 --- /dev/null +++ b/cmake/modules/FindOgg.cmake @@ -0,0 +1,20 @@ +# Filename: FindOgg.cmake +# Authors: CFSworks (13 Jan, 2019) +# +# Usage: +# find_package(Ogg [REQUIRED] [QUIET]) +# +# Once done this will define: +# OGG_FOUND - system has Ogg +# OGG_INCLUDE_DIR - the include directory containing ogg/ +# OGG_LIBRARY - the path to the ogg library +# + +find_path(OGG_INCLUDE_DIR NAMES "ogg/ogg.h") + +find_library(OGG_LIBRARY NAMES "ogg" "libogg_static") + +mark_as_advanced(OGG_INCLUDE_DIR OGG_LIBRARY) + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(Ogg DEFAULT_MSG OGG_INCLUDE_DIR OGG_LIBRARY) diff --git a/cmake/modules/FindOpenCV.cmake b/cmake/modules/FindOpenCV.cmake new file mode 100644 index 0000000000..77d49edfbe --- /dev/null +++ b/cmake/modules/FindOpenCV.cmake @@ -0,0 +1,92 @@ +# Filename: FindOpenCV.cmake +# Authors: CFSworks (3 Nov, 2018) +# +# Usage: +# find_package(OpenCV [REQUIRED] [QUIET]) +# +# This supports the following components: +# calib3d +# contrib +# core +# features2d +# flann +# gpu +# highgui +# imgproc +# legacy +# ml +# nonfree +# objdetect +# photo +# stitching +# superres +# video +# videoio +# videostab +# +# Once done this will define: +# OPENCV_FOUND - system has OpenCV +# OpenCV_INCLUDE_DIRS - the include dir(s) containing OpenCV header files +# OpenCV_comp_LIBRARY - the path to the OpenCV library for the particular +# component +# OpenCV_LIBS - the paths to the OpenCV libraries for the requested +# component(s) +# OpenCV_VERSION_MAJOR- a "best guess" of the major version (X.x) +# OpenCV_VERSION_MINOR- a "best guess" of the minor version (x.X) +# + +set(OpenCV_INCLUDE_DIRS) + +find_path(OpenCV_V1_INCLUDE_DIR + NAMES "cv.h" + PATH_SUFFIXES "opencv") +mark_as_advanced(OpenCV_V1_INCLUDE_DIR) +if(OpenCV_V1_INCLUDE_DIR) + list(APPEND OpenCV_INCLUDE_DIRS "${OpenCV_V1_INCLUDE_DIR}") + + # This is a wild guess: + set(OpenCV_VERSION_MAJOR 1) + set(OpenCV_VERSION_MINOR 0) +endif() + +find_path(OpenCV_V2_INCLUDE_DIR "opencv2/core/version.hpp") +mark_as_advanced(OpenCV_V2_INCLUDE_DIR) +if(OpenCV_V2_INCLUDE_DIR) + list(APPEND OpenCV_INCLUDE_DIRS "${OpenCV_V2_INCLUDE_DIR}") + + file(STRINGS "${OpenCV_V2_INCLUDE_DIR}/opencv2/core/version.hpp" + _version_major REGEX "#define CV_VERSION_EPOCH") + file(STRINGS "${OpenCV_V2_INCLUDE_DIR}/opencv2/core/version.hpp" + _version_minor REGEX "#define CV_VERSION_MAJOR") + + string(REGEX REPLACE "[^0-9]" "" OpenCV_VERSION_MAJOR "${_version_major}") + string(REGEX REPLACE "[^0-9]" "" OpenCV_VERSION_MINOR "${_version_minor}") + unset(_version_major) + unset(_version_minor) +endif() + +set(OpenCV_LIBS) +foreach(_component calib3d contrib core features2d flann gpu highgui imgproc + legacy ml nonfree objdetect photo stitching superres video + videoio videostab) + + list(FIND OpenCV_FIND_COMPONENTS "${_component}" _index) + if(_index GREATER -1 OR _component STREQUAL "core") + if(NOT OpenCV_${_component}_LIBRARY) + find_library(OpenCV_${_component}_LIBRARY + NAMES "opencv_${_component}") + endif() + + if(OpenCV_${_component}_LIBRARY) + list(APPEND OpenCV_LIBS "${OpenCV_${_component}_LIBRARY}") + set(OpenCV_${_component}_FOUND ON) + endif() + endif() + unset(_index) +endforeach(_component) +unset(_component) + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(OpenCV HANDLE_COMPONENTS + REQUIRED_VARS OpenCV_INCLUDE_DIRS OpenCV_LIBS + OpenCV_VERSION_MAJOR OpenCV_VERSION_MINOR) diff --git a/cmake/modules/FindOpenEXR.cmake b/cmake/modules/FindOpenEXR.cmake new file mode 100644 index 0000000000..365ceec733 --- /dev/null +++ b/cmake/modules/FindOpenEXR.cmake @@ -0,0 +1,88 @@ +# Filename: FindOpenEXR.cmake +# Authors: CFSworks (5 Nov, 2018) +# +# Usage: +# find_package(OpenEXR [REQUIRED] [QUIET]) +# +# Once done this will define: +# OPENEXR_FOUND - system has OpenEXR +# OPENEXR_INCLUDE_DIR - the include directory containing OpenEXR header files +# OPENEXR_LIBRARIES - the path to the OpenEXR libraries +# + +find_path(OPENEXR_INCLUDE_DIR + "ImfVersion.h" + PATH_SUFFIXES "OpenEXR") + +mark_as_advanced(OPENEXR_INCLUDE_DIR) + +find_library(OPENEXR_imf_LIBRARY + NAMES "IlmImf") + +if(OPENEXR_imf_LIBRARY) + get_filename_component(_imf_dir "${OPENEXR_imf_LIBRARY}" DIRECTORY) + find_library(OPENEXR_imfutil_LIBRARY + NAMES "IlmImfUtil" + PATHS "${_imf_dir}" + NO_DEFAULT_PATH) + + find_library(OPENEXR_ilmthread_LIBRARY + NAMES "IlmThread" + PATHS "${_imf_dir}" + NO_DEFAULT_PATH) + + find_library(OPENEXR_iex_LIBRARY + NAMES "Iex" + PATHS "${_imf_dir}" + NO_DEFAULT_PATH) + + find_library(OPENEXR_iexmath_LIBRARY + NAMES "IexMath" + PATHS "${_imf_dir}" + NO_DEFAULT_PATH) + + find_library(OPENEXR_imath_LIBRARY + NAMES "Imath" + PATHS "${_imf_dir}" + NO_DEFAULT_PATH) + + find_library(OPENEXR_half_LIBRARY + NAMES "Half" + PATHS "${_imf_dir}" + NO_DEFAULT_PATH) + + unset(_imf_dir) +endif() + +mark_as_advanced( + OPENEXR_imf_LIBRARY + OPENEXR_imfutil_LIBRARY + OPENEXR_ilmthread_LIBRARY + OPENEXR_iex_LIBRARY + OPENEXR_iexmath_LIBRARY + OPENEXR_imath_LIBRARY + OPENEXR_half_LIBRARY +) + +set(OPENEXR_LIBRARIES + ${OPENEXR_imf_LIBRARY} + ${OPENEXR_imfutil_LIBRARY} + ${OPENEXR_ilmthread_LIBRARY} + ${OPENEXR_iex_LIBRARY} + ${OPENEXR_iexmath_LIBRARY} + ${OPENEXR_imath_LIBRARY} + ${OPENEXR_half_LIBRARY} +) + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(OpenEXR DEFAULT_MSG + OPENEXR_INCLUDE_DIR OPENEXR_LIBRARIES + + OPENEXR_imf_LIBRARY + OPENEXR_imfutil_LIBRARY + OPENEXR_ilmthread_LIBRARY + OPENEXR_iex_LIBRARY + OPENEXR_iexmath_LIBRARY + OPENEXR_imath_LIBRARY + OPENEXR_half_LIBRARY +) diff --git a/cmake/modules/FindOpenGLES1.cmake b/cmake/modules/FindOpenGLES1.cmake new file mode 100644 index 0000000000..ab4305088d --- /dev/null +++ b/cmake/modules/FindOpenGLES1.cmake @@ -0,0 +1,21 @@ +# Filename: FindOpenGLES1.cmake +# Authors: CFSworks (21 Oct, 2018) +# +# Usage: +# find_package(OpenGLES1 [REQUIRED] [QUIET]) +# +# Once done this will define: +# OPENGLES1_FOUND - system has OpenGL ES 1.x +# OPENGLES1_INCLUDE_DIR - the include directory containing GLES/gl.h +# OPENGLES1_LIBRARY - the library to link against for OpenGL ES 1.x +# + +find_path(OPENGLES1_INCLUDE_DIR "GLES/gl.h") + +find_library(OPENGLES1_LIBRARY + NAMES "GLESv1" "GLESv1_CM" "GLES_CM") + +mark_as_advanced(OPENGLES1_INCLUDE_DIR OPENGLES1_LIBRARY) + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(OpenGLES1 DEFAULT_MSG OPENGLES1_INCLUDE_DIR OPENGLES1_LIBRARY) diff --git a/cmake/modules/FindOpenGLES2.cmake b/cmake/modules/FindOpenGLES2.cmake new file mode 100644 index 0000000000..f1e4752ad2 --- /dev/null +++ b/cmake/modules/FindOpenGLES2.cmake @@ -0,0 +1,21 @@ +# Filename: FindOpenGLES2.cmake +# Authors: CFSworks (21 Oct, 2018) +# +# Usage: +# find_package(OpenGLES2 [REQUIRED] [QUIET]) +# +# Once done this will define: +# OPENGLES2_FOUND - system has OpenGL ES 2.x +# OPENGLES2_INCLUDE_DIR - the include directory containing GLES2/gl2.h +# OPENGLES2_LIBRARY - the library to link against for OpenGL ES 2.x +# + +find_path(OPENGLES2_INCLUDE_DIR "GLES2/gl2.h") + +find_library(OPENGLES2_LIBRARY + NAMES "GLESv2") + +mark_as_advanced(OPENGLES2_INCLUDE_DIR OPENGLES2_LIBRARY) + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(OpenGLES2 DEFAULT_MSG OPENGLES2_INCLUDE_DIR OPENGLES2_LIBRARY) diff --git a/cmake/modules/FindOpusFile.cmake b/cmake/modules/FindOpusFile.cmake new file mode 100644 index 0000000000..88139de084 --- /dev/null +++ b/cmake/modules/FindOpusFile.cmake @@ -0,0 +1,34 @@ +# Filename: FindOpusFile.cmake +# Authors: CFSworks (13 Jan, 2019) +# +# Usage: +# find_package(OpusFile [REQUIRED] [QUIET]) +# +# Once done this will define: +# OPUSFILE_FOUND - system has Ogg and opusfile +# OPUSFILE_INCLUDE_DIRS - the include directory/ies containing opus/ and ogg/ +# OPUSFILE_LIBRARIES - the paths to the opus and opusfile libraries +# + +# Find Ogg +find_package(Ogg QUIET) + +# Find Opus +find_path(OPUS_INCLUDE_DIR NAMES "opus/opusfile.h") + +find_library(OPUS_opus_LIBRARY NAMES "opus") +find_library(OPUS_opusfile_LIBRARY NAMES "opusfile") + +mark_as_advanced(OPUS_INCLUDE_DIR OPUS_opus_LIBRARY OPUS_opusfile_LIBRARY) + +# Define output variables +set(OPUSFILE_INCLUDE_DIRS ${OPUS_INCLUDE_DIR} "${OPUS_INCLUDE_DIR}/opus") +if(NOT OGG_INCLUDE_DIR STREQUAL OPUS_INCLUDE_DIR) + list(APPEND OPUSFILE_INCLUDE_DIRS ${OGG_INCLUDE_DIR}) +endif() +set(OPUSFILE_LIBRARIES ${OPUS_opusfile_LIBRARY} ${OPUS_opus_LIBRARY} ${OGG_LIBRARY}) + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(OpusFile DEFAULT_MSG + Ogg_FOUND + OPUS_INCLUDE_DIR OPUS_opus_LIBRARY OPUS_opusfile_LIBRARY) diff --git a/cmake/modules/FindSWResample.cmake b/cmake/modules/FindSWResample.cmake new file mode 100644 index 0000000000..eb3ec28f03 --- /dev/null +++ b/cmake/modules/FindSWResample.cmake @@ -0,0 +1,50 @@ +# Filename: FindSWResample.cmake +# Author: CFSworks (10 Apr, 2014) +# +# Usage: +# find_package(SWResample [REQUIRED] [QUIET]) +# +# Once done this will define: +# SWRESAMPLE_FOUND - system has ffmpeg's libswresample +# SWRESAMPLE_INCLUDE_DIR - the libswresample include directory +# SWRESAMPLE_LIBRARY - the path to the library binary +# + +# Find the libswresample include files +find_path(SWRESAMPLE_INCLUDE_DIR + NAMES "libswresample/swresample.h" + PATHS "/usr/include" + "/usr/local/include" + "/sw/include" + "/opt/include" + "/opt/local/include" + "/opt/csw/include" + PATH_SUFFIXES "libav" "ffmpeg" +) + +# Find the libswresample library +find_library(SWRESAMPLE_LIBRARY + NAMES "swresample" + PATHS "/usr" + "/usr/local" + "/usr/freeware" + "/sw" + "/opt" + "/opt/csw" + PATH_SUFFIXES "lib" "lib32" "lib64" +) + +mark_as_advanced(SWRESAMPLE_INCLUDE_DIR) +mark_as_advanced(SWRESAMPLE_LIBRARY) + +# Translate library into library directory +if(SWRESAMPLE_LIBRARY) + unset(SWRESAMPLE_LIBRARY_DIR CACHE) + get_filename_component(SWRESAMPLE_LIBRARY_DIR "${SWRESAMPLE_LIBRARY}" PATH) + set(SWRESAMPLE_LIBRARY_DIR "${SWRESAMPLE_LIBRARY_DIR}" CACHE PATH "The path to libffmpeg's library directory.") # Library path +endif() + +mark_as_advanced(SWRESAMPLE_LIBRARY_DIR) + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(SWResample DEFAULT_MSG SWRESAMPLE_LIBRARY SWRESAMPLE_INCLUDE_DIR SWRESAMPLE_LIBRARY_DIR) diff --git a/cmake/modules/FindSWScale.cmake b/cmake/modules/FindSWScale.cmake new file mode 100644 index 0000000000..f337f9b988 --- /dev/null +++ b/cmake/modules/FindSWScale.cmake @@ -0,0 +1,50 @@ +# Filename: FindSWScale.cmake +# Author: CFSworks (10 Apr, 2014) +# +# Usage: +# find_package(SWScale [REQUIRED] [QUIET]) +# +# Once done this will define: +# SWSCALE_FOUND - system has ffmpeg's libswscale +# SWSCALE_INCLUDE_DIR - the libswscale include directory +# SWSCALE_LIBRARY - the path to the library binary +# + +# Find the libswscale include files +find_path(SWSCALE_INCLUDE_DIR + NAMES "libswscale/swscale.h" + PATHS "/usr/include" + "/usr/local/include" + "/sw/include" + "/opt/include" + "/opt/local/include" + "/opt/csw/include" + PATH_SUFFIXES "libav" "ffmpeg" +) + +# Find the libswscale library +find_library(SWSCALE_LIBRARY + NAMES "swscale" + PATHS "/usr" + "/usr/local" + "/usr/freeware" + "/sw" + "/opt" + "/opt/csw" + PATH_SUFFIXES "lib" "lib32" "lib64" +) + +mark_as_advanced(SWSCALE_INCLUDE_DIR) +mark_as_advanced(SWSCALE_LIBRARY) + +# Translate library into library directory +if(SWSCALE_LIBRARY) + unset(SWSCALE_LIBRARY_DIR CACHE) + get_filename_component(SWSCALE_LIBRARY_DIR "${SWSCALE_LIBRARY}" PATH) + set(SWSCALE_LIBRARY_DIR "${SWSCALE_LIBRARY_DIR}" CACHE PATH "The path to libffmpeg's library directory.") # Library path +endif() + +mark_as_advanced(SWSCALE_LIBRARY_DIR) + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(SWScale DEFAULT_MSG SWSCALE_LIBRARY SWSCALE_INCLUDE_DIR SWSCALE_LIBRARY_DIR) diff --git a/cmake/modules/FindVRPN.cmake b/cmake/modules/FindVRPN.cmake new file mode 100644 index 0000000000..6a7599e205 --- /dev/null +++ b/cmake/modules/FindVRPN.cmake @@ -0,0 +1,40 @@ +# Filename: FindVRPN.cmake +# Authors: CFSworks (2 Nov, 2018) +# +# Usage: +# find_package(VRPN [REQUIRED] [QUIET]) +# +# Once done this will define: +# VRPN_FOUND - system has VRPN +# VRPN_INCLUDE_DIR - the include directory containing VRPN header files +# VRPN_LIBRARIES - the path to the VRPN client libraries +# + +find_path(VRPN_INCLUDE_DIR "vrpn_Connection.h") + +find_library(VRPN_vrpn_LIBRARY + NAMES "vrpn") + +mark_as_advanced(VRPN_INCLUDE_DIR VRPN_vrpn_LIBRARY) + +if(VRPN_vrpn_LIBRARY) + get_filename_component(_vrpn_dir "${VRPN_vrpn_LIBRARY}" DIRECTORY) + find_library(VRPN_quat_LIBRARY + NAMES "quat" + PATHS "${_vrpn_dir}" + NO_DEFAULT_PATH) + + unset(_vrpn_dir) + mark_as_advanced(VRPN_quat_LIBRARY) +endif() + +set(VRPN_LIBRARIES) +if(VRPN_vrpn_LIBRARY) + list(APPEND VRPN_LIBRARIES "${VRPN_vrpn_LIBRARY}") +endif() +if(VRPN_quat_LIBRARY) + list(APPEND VRPN_LIBRARIES "${VRPN_quat_LIBRARY}") +endif() + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(VRPN DEFAULT_MSG VRPN_INCLUDE_DIR VRPN_LIBRARIES) diff --git a/cmake/modules/FindVorbisFile.cmake b/cmake/modules/FindVorbisFile.cmake new file mode 100644 index 0000000000..f85e847d0a --- /dev/null +++ b/cmake/modules/FindVorbisFile.cmake @@ -0,0 +1,34 @@ +# Filename: FindVorbisFile.cmake +# Authors: CFSworks (13 Jan, 2019) +# +# Usage: +# find_package(VorbisFile [REQUIRED] [QUIET]) +# +# Once done this will define: +# VORBISFILE_FOUND - system has Ogg and vorbisfile +# VORBISFILE_INCLUDE_DIRS - the include directory/ies containing vorbis/ and ogg/ +# VORBISFILE_LIBRARIES - the paths to the vorbis and vorbisfile libraries +# + +# Find Ogg +find_package(Ogg QUIET) + +# Find Vorbis +find_path(VORBIS_INCLUDE_DIR NAMES "vorbis/vorbisfile.h") + +find_library(VORBIS_vorbis_LIBRARY NAMES "vorbis" "libvorbis_static") +find_library(VORBIS_vorbisfile_LIBRARY NAMES "vorbisfile" "libvorbisfile_static") + +mark_as_advanced(VORBIS_INCLUDE_DIR VORBIS_vorbis_LIBRARY VORBIS_vorbisfile_LIBRARY) + +# Define output variables +set(VORBISFILE_INCLUDE_DIRS ${VORBIS_INCLUDE_DIR}) +if(NOT OGG_INCLUDE_DIR STREQUAL VORBIS_INCLUDE_DIR) + list(APPEND VORBISFILE_INCLUDE_DIRS ${OGG_INCLUDE_DIR}) +endif() +set(VORBISFILE_LIBRARIES ${VORBIS_vorbisfile_LIBRARY} ${VORBIS_vorbis_LIBRARY} ${OGG_LIBRARY}) + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(VorbisFile DEFAULT_MSG + Ogg_FOUND + VORBIS_INCLUDE_DIR VORBIS_vorbis_LIBRARY VORBIS_vorbisfile_LIBRARY) diff --git a/cmake/modules/README.md b/cmake/modules/README.md new file mode 100644 index 0000000000..057b9cc95d --- /dev/null +++ b/cmake/modules/README.md @@ -0,0 +1,7 @@ +Directory Info +-------------- +**Directory:** /cmake/modules +**License:** Unlicense +**Description:** This directory is used for standard CMake modules which are safe +to use outside of a Panda3D project. This should be the normal location for +most FindXYZZY packages that are written for Panda3D. diff --git a/cmake/scripts/ConcatenateToCXX.cmake b/cmake/scripts/ConcatenateToCXX.cmake new file mode 100644 index 0000000000..2ed19085b1 --- /dev/null +++ b/cmake/scripts/ConcatenateToCXX.cmake @@ -0,0 +1,70 @@ +# Filename: ConcatenateToCXX.cmake +# +# Description: When run, creates a single C++ file which includes a const char[] +# containing the bytes from one or more files. +# +# There is a {SYMBOL_NAME}_size symbol defined as well, storing the total +# number of bytes in the concatenated input files. +# +# A single null terminator byte is added for the benefit of programs that +# simply treat the data array as a string. +# +# Usage: +# This script is invoked via add_custom_target, like this: +# cmake -D OUTPUT_FILE="out.cxx" -D SYMBOL_NAME=data -D INPUT_FILES="a.bin b.bin" -P ConcatenateToCXX.cmake +# + +if(NOT CMAKE_SCRIPT_MODE_FILE) + message(FATAL_ERROR "ConcatenateToCXX.cmake should not be included but run in script mode.") + return() +endif() + +if(NOT DEFINED OUTPUT_FILE) + message(FATAL_ERROR "OUTPUT_FILE should be defined when running ConcatenateToCXX.cmake!") + return() +endif() + +if(NOT DEFINED SYMBOL_NAME) + set(SYMBOL_NAME "data") +endif() + +file(WRITE "${OUTPUT_FILE}" "/* Generated by CMake. DO NOT EDIT. */ + +extern const char ${SYMBOL_NAME}[]; +extern const int ${SYMBOL_NAME}_size; + +const char ${SYMBOL_NAME}[] = {\n") + +set(byte_count 0) +separate_arguments(INPUT_FILES) +foreach(infile ${INPUT_FILES}) + file(APPEND "${OUTPUT_FILE}" " /* ${infile} */\n") + + set(offset 0) + while(1) + # Read up to 1024 bytes from the input file + file(READ "${infile}" data LIMIT 1024 OFFSET ${offset} HEX) + math(EXPR offset "${offset} + 1024") + + # If 'data' is empty, we're done + if(NOT data) + break() + endif() + + # Count the bytes we're adding + string(LENGTH "${data}" strlen) + math(EXPR byte_count "${byte_count} + (${strlen} / 2)") + + # Format runs of up to 32 hex chars by indenting and giving a newline + string(REGEX REPLACE + "(...?.?.?.?.?.?.?.?.?.?.?.?.?.?.?.?.?.?.?.?.?.?.?.?.?.?.?.?.?.?)" " \\1\n" + data "${data}") + # Format each byte (2 hex chars) in each line with 0x prefix and comma suffix + string(REGEX REPLACE "([0-9a-fA-F][0-9a-fA-F])" " 0x\\1," data "${data}") + file(APPEND "${OUTPUT_FILE}" "${data}") + endwhile() +endforeach(infile) + +file(APPEND "${OUTPUT_FILE}" " 0\n}; + +extern const int ${SYMBOL_NAME}_size = ${byte_count};\n") diff --git a/cmake/scripts/CopyPattern.cmake b/cmake/scripts/CopyPattern.cmake new file mode 100644 index 0000000000..52b66cb91c --- /dev/null +++ b/cmake/scripts/CopyPattern.cmake @@ -0,0 +1,27 @@ +# Filename: CopyPattern.cmake +# +# Description: This is a standalone version of CMake's file(COPY) command so we +# can use all of its features during build-time instead of +# config-time. +# +# Usage: +# This script is invoked via add_custom_target, like this: +# cmake -D SOURCE=[source directory] +# -D DESTINATION=[destination directory] +# -D FILES_MATCHING="[globbing patterns passed to file(COPY)]" +# -P CopyPattern.cmake +if(NOT DEFINED SOURCE OR NOT DEFINED DESTINATION) + message(SEND_ERROR "CopyPattern.cmake requires SOURCE and DESTINATION to be +defined.") +endif() + +if(DEFINED FILES_MATCHING) + separate_arguments(FILES_MATCHING UNIX_COMMAND ${FILES_MATCHING}) + + file(COPY "${SOURCE}" + DESTINATION "${DESTINATION}" + FILES_MATCHING ${FILES_MATCHING}) +else() + file(COPY "${SOURCE}" + DESTINATION "${DESTINATION}") +endif() diff --git a/cmake/scripts/CopyPython.cmake b/cmake/scripts/CopyPython.cmake new file mode 100644 index 0000000000..a611850b62 --- /dev/null +++ b/cmake/scripts/CopyPython.cmake @@ -0,0 +1,78 @@ +# Filename: CopyPython.cmake +# +# Description: When run, copies Python files from a source directory to a +# build directory located somewhere in the project's binary path. If +# PYTHON_EXECUTABLES is provided, it will also invoke compileall in the +# destination dir(s) to precache .pyc/.pyo files. +# +# Usage: +# This script is invoked via add_custom_target, like this: +# cmake -D OUTPUT_DIR="/out/dir/Release" +# -D SOURCE_DIR="/panda3d/direct/src/" +# -D PYTHON_EXECUTABLES="/usr/bin/python3.6" +# -P CopyPython.cmake +# + +if(NOT CMAKE_SCRIPT_MODE_FILE) + message(FATAL_ERROR "CopyPython.cmake should not be included but run in script mode.") + return() +endif() + +if(NOT DEFINED OUTPUT_DIR) + message(FATAL_ERROR "OUTPUT_DIR should be defined when running CopyPython.cmake!") + return() +endif() + +# Ensure OUTPUT_DIR exists +file(MAKE_DIRECTORY ${OUTPUT_DIR}) + +# If there's a SOURCE_DIR, glob for .py files and copy +# (this is done by hand to avoid the CMake bug where it creates empty dirs) +if(DEFINED SOURCE_DIR) + file(GLOB_RECURSE py_files RELATIVE "${SOURCE_DIR}" "${SOURCE_DIR}/*.py") + foreach(py_file ${py_files}) + get_filename_component(py_file_parent "${py_file}" DIRECTORY) + file(TIMESTAMP "${SOURCE_DIR}/${py_file}" src_stamp) + file(TIMESTAMP "${OUTPUT_DIR}/${py_file}" dst_stamp) + + # The file is only copied if: + # - there's an __init__.py in its dir (or file is in the root) (i.e. file belongs to a package), and + # - the modification timestamp differs (i.e. file changed or never copied) + if((py_file_parent STREQUAL "." OR NOT py_file_parent + OR EXISTS "${SOURCE_DIR}/${py_file_parent}/__init__.py") + AND NOT src_stamp STREQUAL dst_stamp) + + file(COPY "${SOURCE_DIR}/${py_file}" DESTINATION "${OUTPUT_DIR}/${py_file_parent}") + set(changed YES) + endif() + + endforeach(py_file) + +else() + # No SOURCE_DIR; assume we're outdated since our caller might be populating + # the OUTPUT_DIR themselves + set(changed YES) + +endif() + +# Make sure Python recognizes OUTPUT_DIR as a package +if(NOT EXISTS "${OUTPUT_DIR}/__init__.py") + file(WRITE "${OUTPUT_DIR}/__init__.py" "") + set(changed YES) +endif() + +# Generate .pyc files for each Python version, if our caller wants +if(changed AND DEFINED PYTHON_EXECUTABLES) + foreach(interp ${PYTHON_EXECUTABLES}) + execute_process( + COMMAND "${interp}" -m compileall . + OUTPUT_QUIET + WORKING_DIRECTORY "${OUTPUT_DIR}") + + execute_process( + COMMAND "${interp}" -O -m compileall . + OUTPUT_QUIET + WORKING_DIRECTORY "${OUTPUT_DIR}") + + endforeach(interp) +endif() diff --git a/cmake/scripts/MakeComposite.cmake b/cmake/scripts/MakeComposite.cmake new file mode 100644 index 0000000000..fb4d88f6b6 --- /dev/null +++ b/cmake/scripts/MakeComposite.cmake @@ -0,0 +1,28 @@ +# Filename: MakeComposite.cmake +# +# Description: When run, creates a single C++ file which includes multiple +# other C++ files, to help facilitate unity builds. +# Unity builds provide significantly increased compile speed. +# +# Usage: +# This script is invoked via add_custom_target, like this: +# cmake -P MakeComposite.cmake -D COMPOSITE_FILE="x_composite1.cxx" -D COMPOSITE_SOURCES="a.cxx b.cxx" +# + +if(CMAKE_SCRIPT_MODE_FILE) + if(NOT DEFINED COMPOSITE_FILE) + message(FATAL_ERROR "COMPOSITE_FILE should be defined when running MakeComposite.cmake!") + return() + endif() + + file(WRITE "${COMPOSITE_FILE}" "/* Generated by CMake. DO NOT EDIT. */\n") + + separate_arguments(COMPOSITE_SOURCES) + foreach(source ${COMPOSITE_SOURCES}) + file(APPEND "${COMPOSITE_FILE}" "#include \"${source}\"\n") + endforeach() + +else() + message(SEND_ERROR "MakeComposite.cmake should not be included but run in script mode.") + +endif() diff --git a/cmake/scripts/README.md b/cmake/scripts/README.md new file mode 100644 index 0000000000..1f97423ab8 --- /dev/null +++ b/cmake/scripts/README.md @@ -0,0 +1,10 @@ +Directory Info +-------------- +**Directory:** /cmake/scripts +**License:** Unlicense +**Description:** This directory is used for cmake files which are not meant to +be included using CMake's normal include() directive. Typically, files in this +directory will be invoked as a custom command/target in the form of: +``` + cmake -P [... other options ...] +``` diff --git a/cmake/templates/metalib_init.cxx.in b/cmake/templates/metalib_init.cxx.in new file mode 100644 index 0000000000..f8975d400d --- /dev/null +++ b/cmake/templates/metalib_init.cxx.in @@ -0,0 +1,9 @@ +#include "dtoolbase.h" + +@component_init_headers@ + +EXPORT_CLASS void +@init_func@() { +@component_init_funcs@ +} +@export_definitions@ diff --git a/cmake/templates/metalib_init.h.in b/cmake/templates/metalib_init.h.in new file mode 100644 index 0000000000..4ae8db0d34 --- /dev/null +++ b/cmake/templates/metalib_init.h.in @@ -0,0 +1,9 @@ +#ifndef _METALIB_INIT_@target_name@ +#define _METALIB_INIT_@target_name@ + +#include "dtoolbase.h" + +IMPORT_CLASS void @init_func@(); +@export_declarations@ + +#endif diff --git a/cmake/templates/win32_python/__init__.py b/cmake/templates/win32_python/__init__.py new file mode 100644 index 0000000000..758478f46b --- /dev/null +++ b/cmake/templates/win32_python/__init__.py @@ -0,0 +1,23 @@ +def _fixup_dlls(): + try: + path = __path__[0] + except (NameError, IndexError): + return # Not a package, or not on filesystem + + import os + + relpath = os.path.relpath(path, __path__[-1]) + dll_path = os.path.abspath(os.path.join(__path__[-1], '../bin', relpath)) + if not os.path.isdir(dll_path): + return + + if hasattr(os, 'add_dll_directory'): + os.add_dll_directory(dll_path) + else: + os_path = os.environ.get('PATH', '') + os_path = os_path.split(os.pathsep) if os_path else [] + os_path.insert(0, dll_path) + os.environ['PATH'] = os.pathsep.join(os_path) + +_fixup_dlls() +del _fixup_dlls diff --git a/contrib/CMakeLists.txt b/contrib/CMakeLists.txt new file mode 100644 index 0000000000..ff5145261e --- /dev/null +++ b/contrib/CMakeLists.txt @@ -0,0 +1,18 @@ +if(NOT BUILD_PANDA) + message(FATAL_ERROR "Cannot build contrib without panda! Please enable the BUILD_PANDA option.") +endif() + +# Include source directories +add_subdirectory(src/ai) +add_subdirectory(src/contribbase) +add_subdirectory(src/rplight) + +if(HAVE_PYTHON) + add_python_module(panda3d.ai p3ai + IMPORT panda3d.core COMPONENT ContribPython) + + add_python_module(panda3d._rplight p3rplight + IMPORT panda3d.core COMPONENT ContribPython) +endif() + +export_targets(Contrib COMPONENT ContribDevel) diff --git a/contrib/src/ai/CMakeLists.txt b/contrib/src/ai/CMakeLists.txt new file mode 100644 index 0000000000..3e7f028444 --- /dev/null +++ b/contrib/src/ai/CMakeLists.txt @@ -0,0 +1,54 @@ +set(P3AI_HEADERS + aiBehaviors.h + aiCharacter.h + aiGlobals.h + aiNode.h + aiPathFinder.h + aiWorld.h + arrival.h + config_ai.h + evade.h + flee.h + flock.h + meshNode.h + obstacleAvoidance.h + pathFind.h + pathFollow.h + pursue.h + seek.h + wander.h +) + +set(P3AI_SOURCES + aiBehaviors.cxx + aiCharacter.cxx + aiNode.cxx + aiPathFinder.cxx + aiWorld.cxx + arrival.cxx + config_ai.cxx + evade.cxx + flee.cxx + flock.cxx + meshNode.cxx + obstacleAvoidance.cxx + pathFind.cxx + pathFollow.cxx + pursue.cxx + seek.cxx + wander.cxx +) + +composite_sources(p3ai P3AI_SOURCES) +add_library(p3ai ${P3AI_HEADERS} ${P3AI_SOURCES}) +set_target_properties(p3ai PROPERTIES DEFINE_SYMBOL BUILDING_PANDAAI) +target_link_libraries(p3ai p3contribbase) +target_interrogate(p3ai ALL) + +install(TARGETS p3ai + EXPORT Contrib COMPONENT Contrib + DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d + ARCHIVE COMPONENT ContribDevel) +install(FILES ${P3AI_HEADERS} COMPONENT ContribDevel DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d) diff --git a/contrib/src/contribbase/CMakeLists.txt b/contrib/src/contribbase/CMakeLists.txt new file mode 100644 index 0000000000..630bffc0a6 --- /dev/null +++ b/contrib/src/contribbase/CMakeLists.txt @@ -0,0 +1,14 @@ +set(P3CONTRIBBASE_SOURCES + contribbase.cxx +) + +set(P3CONTRIBBASE_HEADERS + contribbase.h contribsymbols.h +) + +# Yes, INTERFACE: don't build it, there's no code! +add_library(p3contribbase INTERFACE) +target_link_libraries(p3contribbase INTERFACE panda) + +install(TARGETS p3contribbase EXPORT Contrib COMPONENT Contrib) +install(FILES ${P3CONTRIBBASE_HEADERS} COMPONENT ContribDevel DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d) diff --git a/contrib/src/rplight/CMakeLists.txt b/contrib/src/rplight/CMakeLists.txt new file mode 100644 index 0000000000..9f476c30cd --- /dev/null +++ b/contrib/src/rplight/CMakeLists.txt @@ -0,0 +1,52 @@ +set(P3RPLIGHT_HEADERS + config_rplight.h + gpuCommand.h gpuCommand.I + gpuCommandList.h + iesDataset.h + internalLightManager.h internalLightManager.I + pointerSlotStorage.h + pssmCameraRig.h pssmCameraRig.I + rpLight.h rpLight.I + rpPointLight.h rpPointLight.I + rpSpotLight.h rpSpotLight.I + shadowAtlas.h shadowAtlas.I + shadowManager.h shadowManager.I + shadowSource.h shadowSource.I + tagStateManager.h tagStateManager.I +) + +set(P3RPLIGHT_SOURCES + config_rplight.cxx + gpuCommand.cxx + gpuCommandList.cxx + iesDataset.cxx + internalLightManager.cxx + pssmCameraRig.cxx + rpLight.cxx + rpPointLight.cxx + rpSpotLight.cxx + shadowAtlas.cxx + shadowManager.cxx + shadowSource.cxx + tagStateManager.cxx +) + +composite_sources(p3rplight P3RPLIGHT_SOURCES) +# STATIC, because it doesn't contain any EXPCL_ stuff +add_library(p3rplight STATIC ${P3RPLIGHT_HEADERS} ${P3RPLIGHT_SOURCES}) +target_link_libraries(p3rplight p3contribbase) +target_interrogate(p3rplight ALL) + +if(MODULE_TYPE STREQUAL "MODULE") + # Because it's STATIC (see above), we need to make it PIC so it can link into + # a Python module + set_target_properties(p3rplight PROPERTIES POSITION_INDEPENDENT_CODE ON) +endif() + +install(TARGETS p3rplight + EXPORT Contrib COMPONENT Contrib + DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d + ARCHIVE COMPONENT ContribDevel) +install(FILES ${P3RPLIGHT_HEADERS} COMPONENT ContribDevel DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d) diff --git a/direct/CMakeLists.txt b/direct/CMakeLists.txt new file mode 100644 index 0000000000..686ca23cc5 --- /dev/null +++ b/direct/CMakeLists.txt @@ -0,0 +1,75 @@ +if(NOT BUILD_PANDA) + message(FATAL_ERROR "Cannot build direct without panda! Please enable the BUILD_PANDA option.") +endif() + +# Include source directories which have C++ components: +add_subdirectory(src/dcparse) +add_subdirectory(src/dcparser) +add_subdirectory(src/deadrec) +add_subdirectory(src/directbase) +#add_subdirectory(src/directd) +#add_subdirectory(src/directdServer) +add_subdirectory(src/distributed) +add_subdirectory(src/interval) +add_subdirectory(src/motiontrail) +add_subdirectory(src/showbase) + +set(P3DIRECT_COMPONENTS + p3dcparser p3deadrec + p3interval p3motiontrail p3showbase +) +if(HAVE_PYTHON) + list(APPEND P3DIRECT_COMPONENTS p3distributed) +endif() + +set(CMAKE_INSTALL_DEFAULT_COMPONENT_NAME "DirectDevel") +add_metalib(p3direct INIT init_libdirect direct.h COMPONENTS ${P3DIRECT_COMPONENTS}) +unset(CMAKE_INSTALL_DEFAULT_COMPONENT_NAME) +set_property(TARGET p3direct PROPERTY LINKER_LANGUAGE "CXX") + +# Installation: +install(TARGETS p3direct + EXPORT Direct COMPONENT Direct + DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + ARCHIVE COMPONENT DirectDevel) + +if(HAVE_PYTHON) + # Now for the Python side of everything + + add_python_module(panda3d.direct + p3dcparser p3deadrec p3distributed p3interval + p3motiontrail p3showbase LINK p3direct IMPORT panda3d.core COMPONENT Direct) + + # Copy Python source files into the build directory + install_python_package(direct SOURCE "${CMAKE_CURRENT_SOURCE_DIR}/src" LIB COMPONENT Direct) + + # This bit is to generate the 'pandac' compatibility shim. It's deprecated now, + # but in older versions of Panda3D, one would use + # from pandac.PandaModules import * + # instead of + # from panda3d.FOO import * + # Generate PandaModules: + file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/pandac/PandaModules.py" + "\"This module is deprecated. Import from panda3d.core and other panda3d.* modules instead.\" + +print(\"Warning: pandac.PandaModules is deprecated, import from panda3d.core instead\")\n") + + foreach(module ${ALL_INTERROGATE_MODULES}) + string(REGEX REPLACE "^.*\\." "" module_name "${module}") + file(APPEND "${CMAKE_CURRENT_BINARY_DIR}/pandac/PandaModules.py" " +try: + from ${module} import * +except ImportError as err: + if not (\"No module named\" in str(err) and \"${module_name}\" in str(err)): + raise +") + endforeach() + + # Now install ourselves: + install_python_package(pandac SOURCE "${CMAKE_CURRENT_BINARY_DIR}/pandac" LIB COMPONENT Direct) +endif() + +# "Direct" component contains both the Python stuff and the non-Python stuff, +# because direct has a pretty solid dependency on Python. +export_targets(Direct NAMESPACE "Panda3D::Direct::" COMPONENT DirectDevel) diff --git a/direct/src/actor/Actor.py b/direct/src/actor/Actor.py index 11d4990351..7aeed5d535 100644 --- a/direct/src/actor/Actor.py +++ b/direct/src/actor/Actor.py @@ -212,7 +212,7 @@ class Actor(DirectObject, NodePath): self.__LODCenter = Point3(0, 0, 0) self.switches = None - if (other == None): + if other is None: # act like a normal constructor # create base hierarchy @@ -352,7 +352,7 @@ class Actor(DirectObject, NodePath): self.gotName = other.gotName # copy the scene graph elements of other - if (overwrite): + if overwrite: otherCopy = other.copyTo(NodePath()) otherCopy.detachNode() # assign these elements to ourselve (overwrite) @@ -372,7 +372,7 @@ class Actor(DirectObject, NodePath): self.switches = other.switches self.__LODNode = self.find('**/+LODNode') self.__hasLOD = 0 - if (not self.__LODNode.isEmpty()): + if not self.__LODNode.isEmpty(): self.__hasLOD = 1 @@ -418,7 +418,7 @@ class Actor(DirectObject, NodePath): subpartDef = self.__subpartDict.get(partName, Actor.SubpartDef(partName)) partDef = partBundleDict.get(subpartDef.truePartName) - if partDef == None: + if partDef is None: Actor.notify.error("no part named: %s" % (partName)) self.__doListJoints(0, partDef.getBundle(), @@ -491,7 +491,7 @@ class Actor(DirectObject, NodePath): for animName, file, animControl in animInfo: print(' Anim: %s' % animName) print(' File: %s' % file) - if animControl == None: + if animControl is None: print(' (not loaded)') else: print(' NumFrames: %d PlayRate: %0.2f' % @@ -500,7 +500,12 @@ class Actor(DirectObject, NodePath): def cleanup(self): """ - Actor cleanup function + This method should be called when intending to destroy the Actor, and + cleans up any additional resources stored on the Actor class before + removing the underlying node using `removeNode()`. + + Note that `removeNode()` itself is not sufficient to destroy actors, + which is why this method exists. """ self.stop(None) self.clearPythonData() @@ -512,6 +517,11 @@ class Actor(DirectObject, NodePath): self.removeNode() def removeNode(self): + """ + You should call `cleanup()` for Actor objects instead, since + :meth:`~panda3d.core.NodePath.removeNode()` is not sufficient for + completely destroying Actor objects. + """ if self.__geomNode and (self.__geomNode.getNumChildren() > 0): assert self.notify.warning("called actor.removeNode() on %s without calling cleanup()" % self.getName()) NodePath.removeNode(self) @@ -525,7 +535,7 @@ class Actor(DirectObject, NodePath): def flush(self): """ - Actor flush function + Actor flush function. Used by `cleanup()`. """ self.clearPythonData() @@ -557,14 +567,14 @@ class Actor(DirectObject, NodePath): bundles = [] for lodName, partBundleDict in self.__partBundleDict.items(): - if partName == None: + if partName is None: for partDef in partBundleDict.values(): bundles.append(partDef.getBundle()) else: subpartDef = self.__subpartDict.get(partName, Actor.SubpartDef(partName)) partDef = partBundleDict.get(subpartDef.truePartName) - if partDef != None: + if partDef is not None: bundles.append(partDef.getBundle()) else: Actor.notify.warning("Couldn't find part: %s" % (partName)) @@ -635,7 +645,7 @@ class Actor(DirectObject, NodePath): Set the node that switches actor geometry in and out. If one is not supplied as an argument, make one """ - if (node == None): + if node is None: node = LODNode.makeDefaultLod("lod") if self.__LODNode: @@ -685,7 +695,7 @@ class Actor(DirectObject, NodePath): self.switches[lodName] = [inDist, outDist] # add the switch distance info self.__LODNode.node().addSwitch(inDist, outDist) - if center != None: + if center is not None: self.setCenter(center) def setLOD(self, lodName, inDist=0, outDist=0): @@ -724,7 +734,7 @@ class Actor(DirectObject, NodePath): return self.__hasLOD def setCenter(self, center): - if center == None: + if center is None: center = Point3(0, 0, 0) self.__LODCenter = center if self.__LODNode: @@ -782,7 +792,7 @@ class Actor(DirectObject, NodePath): Returns True if any joint has changed as a result of this, False otherwise. """ - if lodName == None: + if lodName is None: lodNames = self.getLODNames() else: lodNames = [lodName] @@ -790,7 +800,7 @@ class Actor(DirectObject, NodePath): anyChanged = False if lod < len(lodNames): lodName = lodNames[lod] - if partName == None: + if partName is None: partBundleDict = self.__partBundleDict[lodName] partNames = list(partBundleDict.keys()) else: @@ -906,11 +916,11 @@ class Actor(DirectObject, NodePath): return lodName, animControlDict = next(iter(self.__animControlDict.items())) - if partName == None: + if partName is None: partName, animDict = next(iter(animControlDict.items())) else: animDict = animControlDict.get(partName) - if animDict == None: + if animDict is None: # part was not present Actor.notify.warning("couldn't find part: %s" % (partName)) return None @@ -931,11 +941,11 @@ class Actor(DirectObject, NodePath): in dictionary. NOTE: only returns info for an arbitrary LOD """ lodName, animControlDict = next(iter(self.__animControlDict.items())) - if partName == None: + if partName is None: partName, animDict = next(iter(animControlDict.items())) else: animDict = animControlDict.get(partName) - if animDict == None: + if animDict is None: # part was not present Actor.notify.warning("couldn't find part: %s" % (partName)) return None @@ -969,7 +979,7 @@ class Actor(DirectObject, NodePath): return None subpartDef = self.__subpartDict.get(partName, Actor.SubpartDef(partName)) partDef = partBundleDict.get(subpartDef.truePartName) - if partDef != None: + if partDef is not None: return partDef.partBundleNP return None @@ -984,7 +994,7 @@ class Actor(DirectObject, NodePath): return None subpartDef = self.__subpartDict.get(partName, Actor.SubpartDef(partName)) partDef = partBundleDict.get(subpartDef.truePartName) - if partDef != None: + if partDef is not None: return partDef.getBundle() return None @@ -1001,9 +1011,9 @@ class Actor(DirectObject, NodePath): return # remove the part - if (partName in partBundleDict): + if partName in partBundleDict: partBundleDict[partName].partBundleNP.removeNode() - del(partBundleDict[partName]) + del partBundleDict[partName] # find the corresponding anim control dict if self.mergeLODBundles: @@ -1014,8 +1024,8 @@ class Actor(DirectObject, NodePath): return # remove the animations - if (partName in partDict): - del(partDict[partName]) + if partName in partDict: + del partDict[partName] def hidePart(self, partName, lodName="lodRoot"): """ @@ -1093,7 +1103,7 @@ class Actor(DirectObject, NodePath): if node is None: node = partDef.partBundleNP.attachNewNode(jointName) - if (joint): + if joint: if localTransform: joint.addLocalTransform(node.node()) else: @@ -1125,7 +1135,7 @@ class Actor(DirectObject, NodePath): # Get a handle to the joint. joint = bundle.findChild(jointName) - if (joint): + if joint: joint.clearNetTransforms() joint.clearLocalTransforms() else: @@ -1139,11 +1149,11 @@ class Actor(DirectObject, NodePath): joints=[] pattern = GlobPattern(jointName) - if lodName == None and self.mergeLODBundles: + if lodName is None and self.mergeLODBundles: # Get the common bundle. partBundleDicts = [self.__commonBundleHandles] - elif lodName == None: + elif lodName is None: # Get all LOD's. partBundleDicts = self.__partBundleDict.values() else: @@ -1232,7 +1242,7 @@ class Actor(DirectObject, NodePath): return None joint = bundle.findChild(jointName) - if joint == None: + if joint is None: Actor.notify.warning("no joint named %s!" % (jointName)) return None return joint.getDefaultValue() @@ -1252,7 +1262,7 @@ class Actor(DirectObject, NodePath): return None joint = bundle.findChild(jointName) - if joint == None: + if joint is None: Actor.notify.warning("no joint named %s!" % (jointName)) return None return joint.getTransformState() @@ -1277,7 +1287,7 @@ class Actor(DirectObject, NodePath): anyGood = False for bundleDict in self.__partBundleDict.values(): bundle = bundleDict[trueName].getBundle() - if node == None: + if node is None: node = self.attachNewNode(ModelNode(jointName)) joint = bundle.findChild(jointName) if joint and isinstance(joint, MovingPartMatrix): @@ -1299,7 +1309,7 @@ class Actor(DirectObject, NodePath): optimal than controlJoint() for cases in which the transform is not intended to be animated during the lifetime of the Actor. """ - if transform == None: + if transform is None: transform = TransformState.makePosHprScale(pos, hpr, scale) subpartDef = self.__subpartDict.get(partName, Actor.SubpartDef(partName)) @@ -1330,7 +1340,7 @@ class Actor(DirectObject, NodePath): partDef = partBundleDict.get(subpartDef.truePartName) if partDef: joint = partDef.partBundleNP.find("**/" + jointName) - if (joint.isEmpty()): + if joint.isEmpty(): Actor.notify.warning("%s not found!" % (jointName)) else: return path.instanceTo(joint) @@ -1350,7 +1360,7 @@ class Actor(DirectObject, NodePath): anotherPartDef = partBundleDict.get(anotherPartName) if anotherPartDef: joint = anotherPartDef.partBundleNP.find("**/" + jointName) - if (joint.isEmpty()): + if joint.isEmpty(): Actor.notify.warning("%s not found!" % (jointName)) else: partDef.partBundleNP.reparentTo(joint) @@ -1395,10 +1405,10 @@ class Actor(DirectObject, NodePath): root under the given lod. """ # check to see if we are working within an lod - if lodName != None: + if lodName is not None: # find the named lod node lodRoot = self.__LODNode.find(str(lodName)) - if root == None: + if root is None: # no need to look further root = lodRoot else: @@ -1406,7 +1416,7 @@ class Actor(DirectObject, NodePath): root = lodRoot.find("**/" + root) else: # start search from self if no root and no lod given - if root == None: + if root is None: root = self frontParts = root.findAllMatches("**/" + frontPartName) @@ -1426,7 +1436,7 @@ class Actor(DirectObject, NodePath): # Find the back part. backPart = root.find("**/" + backPartName) - if (backPart.isEmpty()): + if backPart.isEmpty(): Actor.notify.warning("no part named %s!" % (backPartName)) return @@ -1442,7 +1452,7 @@ class Actor(DirectObject, NodePath): def fixBounds(self, partName = None): - if(partName == None): + if partName is None: #iterate through everything for lodData in self.__partBundleDict.values(): for partData in lodData.values(): @@ -1473,7 +1483,7 @@ class Actor(DirectObject, NodePath): in this actor """ # if no part name specified fix all parts - if (part==None): + if part is None: part = self # update all characters first @@ -1531,12 +1541,12 @@ class Actor(DirectObject, NodePath): Play the given animation on the given part of the actor. If no part is specified, try to play on all parts. NOTE: plays over ALL LODs""" - if fromFrame == None: + if fromFrame is None: for control in self.getAnimControls(animName, partName): control.play() else: for control in self.getAnimControls(animName, partName): - if toFrame == None: + if toFrame is None: control.play(fromFrame, control.getNumFrames() - 1) else: control.play(fromFrame, toFrame) @@ -1550,12 +1560,12 @@ class Actor(DirectObject, NodePath): all LOD's """ - if fromFrame == None: + if fromFrame is None: for control in self.getAnimControls(animName, partName): control.loop(restart) else: for control in self.getAnimControls(animName, partName): - if toFrame == None: + if toFrame is None: control.loop(restart, fromFrame, control.getNumFrames() - 1) else: control.loop(restart, fromFrame, toFrame) @@ -1567,11 +1577,11 @@ class Actor(DirectObject, NodePath): restarting at zero frame if requested. If no part name is given then try to loop on all parts. NOTE: loops on all LOD's""" - if fromFrame == None: + if fromFrame is None: fromFrame = 0 for control in self.getAnimControls(animName, partName): - if toFrame == None: + if toFrame is None: control.pingpong(restart, fromFrame, control.getNumFrames() - 1) else: control.pingpong(restart, fromFrame, toFrame) @@ -1623,11 +1633,11 @@ class Actor(DirectObject, NodePath): Config.prc variable. """ for bundle in self.getPartBundles(partName = partName): - if blendType != None: + if blendType is not None: bundle.setBlendType(blendType) - if animBlend != None: + if animBlend is not None: bundle.setAnimBlendFlag(animBlend) - if frameBlend != None: + if frameBlend is not None: bundle.setFrameBlendFlag(frameBlend) def enableBlend(self, blendType = PartBundle.BTNormalizedLinear, partName = None): @@ -1706,15 +1716,15 @@ class Actor(DirectObject, NodePath): partDict = self.__animControlDict.get(lodName) # if this assertion fails, named lod was not present - assert partDict != None + assert partDict is not None animDict = partDict.get(partName) - if animDict == None: + if animDict is None: # part was not present Actor.notify.warning("couldn't find part: %s" % (partName)) else: anim = animDict.get(animName) - if anim == None: + if anim is None: # anim was not present assert Actor.notify.debug("couldn't find anim: %s" % (animName)) pass @@ -1750,7 +1760,7 @@ class Actor(DirectObject, NodePath): If lodName is None or omitted, all LOD's are returned. """ - if partName == None and self.__subpartsComplete: + if partName is None and self.__subpartsComplete: # If we have the __subpartsComplete flag, and no partName # is specified, it really means to play the animation on # all subparts, not on the overall Actor. @@ -1759,12 +1769,12 @@ class Actor(DirectObject, NodePath): controls = [] # build list of lodNames and corresponding animControlDicts # requested. - if lodName == None or self.mergeLODBundles: + if lodName is None or self.mergeLODBundles: # Get all LOD's animControlDictItems = self.__animControlDict.items() else: partDict = self.__animControlDict.get(lodName) - if partDict == None: + if partDict is None: Actor.notify.warning("couldn't find lod: %s" % (lodName)) animControlDictItems = [] else: @@ -1773,7 +1783,7 @@ class Actor(DirectObject, NodePath): for lodName, partDict in animControlDictItems: # Now, build the list of partNames and the corresponding # animDicts. - if partName == None: + if partName is None: # Get all main parts, but not sub-parts. animDictItems = [] for thisPart, animDict in partDict.items(): @@ -1791,14 +1801,14 @@ class Actor(DirectObject, NodePath): for pName in partNameList: animDict = partDict.get(pName) - if animDict == None: + if animDict is None: # Maybe it's a subpart that hasn't been bound yet. subpartDef = self.__subpartDict.get(pName) if subpartDef: animDict = {} partDict[pName] = animDict - if animDict == None: + if animDict is None: # part was not present Actor.notify.warning("couldn't find part: %s" % (pName)) else: @@ -1824,7 +1834,7 @@ class Actor(DirectObject, NodePath): names = animDict.keys() for animName in names: anim = animDict.get(animName) - if anim == None and partName != None: + if anim is None and partName is not None: for pName in partNameList: # Maybe it's a subpart that hasn't been bound yet. subpartDef = self.__subpartDict.get(pName) @@ -1835,14 +1845,14 @@ class Actor(DirectObject, NodePath): anim = anim.makeCopy() animDict[animName] = anim - if anim == None: + if anim is None: # anim was not present assert Actor.notify.debug("couldn't find anim: %s" % (animName)) pass else: # bind the animation first if we need to animControl = anim.animControl - if animControl == None: + if animControl is None: animControl = self.__bindAnimToPart( animName, thisPart, lodName, allowAsyncBind = allowAsyncBind) @@ -1869,7 +1879,7 @@ class Actor(DirectObject, NodePath): if isinstance(modelPath, NodePath): # If we got a NodePath instead of a string, use *that* as # the model directly. - if (copy): + if copy: model = modelPath.copyTo(NodePath()) else: model = modelPath @@ -1898,15 +1908,15 @@ class Actor(DirectObject, NodePath): if model is not None: model = NodePath(model) - if (model == None): + if model is None: raise IOError("Could not load Actor model %s" % (modelPath)) - if (model.node().isOfType(Character.getClassType())): + if model.node().isOfType(Character.getClassType()): bundleNP = model else: bundleNP = model.find("**/+Character") - if (bundleNP.isEmpty()): + if bundleNP.isEmpty(): Actor.notify.warning("%s is not a character!" % (modelPath)) model.reparentTo(self.__geomNode) else: @@ -1923,7 +1933,7 @@ class Actor(DirectObject, NodePath): # Now extract out the Character and integrate it with # the Actor. - if (lodName!="lodRoot"): + if lodName != "lodRoot": # parent to appropriate node under LOD switch bundleNP.reparentTo(self.__LODNode.find(str(lodName))) else: @@ -1965,7 +1975,7 @@ class Actor(DirectObject, NodePath): self.gotName = 1 bundleDict = self.__partBundleDict.get(lodName, None) - if bundleDict == None: + if bundleDict is None: # make a dictionary to store these parts in bundleDict = {} self.__partBundleDict[lodName] = bundleDict @@ -2254,7 +2264,7 @@ class Actor(DirectObject, NodePath): for lodName in lodNames: for partName in partNames: for animDef in self.__animControlDict[lodName][partName].values(): - if animDef.animControl != None: + if animDef.animControl is not None: # Try to clear any control effects before we let # our handle on them go. This is especially # important if the anim control was blending @@ -2266,12 +2276,12 @@ class Actor(DirectObject, NodePath): for partName in partNames: for anim in anims: animDef = self.__animControlDict[lodName][partName].get(anim) - if animDef and animDef.animControl != None: + if animDef and animDef.animControl is not None: # Try to clear any control effects before we let # our handle on them go. This is especially # important if the anim control was blending # animations. - animDef.animControl.getPart().clearControlEffects() + animDef.animControl.getPart().setControlEffect(animDef.animControl, 0.0) animDef.animControl = None @@ -2329,19 +2339,19 @@ class Actor(DirectObject, NodePath): partDict = self.__animControlDict[lodName] animDict = partDict.get(partName) - if animDict == None: + if animDict is None: # It must be a subpart that hasn't been bound yet. animDict = {} partDict[partName] = animDict anim = animDict.get(animName) - if anim == None: + if anim is None: # It must be a subpart that hasn't been bound yet. anim = partDict[subpartDef.truePartName].get(animName) anim = anim.makeCopy() animDict[animName] = anim - if anim == None: + if anim is None: Actor.notify.error("actor has no animation %s", animName) # only bind if not already bound! @@ -2396,7 +2406,7 @@ class Actor(DirectObject, NodePath): # find the part in our tree bundleNP = partLod.find("**/%s%s"%(Actor.partPrefix,partName)) - if (bundleNP != None): + if bundleNP is not None: # store the part bundle self.__prepareBundle(bundleNP, partDef.partModel, partName, lodName) @@ -2468,7 +2478,7 @@ class Actor(DirectObject, NodePath): else: lodNames = [lodName] - if partName == None and self.__subpartsComplete: + if partName is None and self.__subpartsComplete: partNames = self.__subpartDict.keys() else: partNames = [partName] diff --git a/direct/src/dcparse/CMakeLists.txt b/direct/src/dcparse/CMakeLists.txt new file mode 100644 index 0000000000..e5cdee5b18 --- /dev/null +++ b/direct/src/dcparse/CMakeLists.txt @@ -0,0 +1,3 @@ +add_executable(p3dcparse dcparse.cxx) +target_link_libraries(p3dcparse p3direct) +install(TARGETS p3dcparse EXPORT Direct COMPONENT Direct DESTINATION ${CMAKE_INSTALL_BINDIR}) diff --git a/direct/src/dcparser/CMakeLists.txt b/direct/src/dcparser/CMakeLists.txt new file mode 100644 index 0000000000..e90ca815d8 --- /dev/null +++ b/direct/src/dcparser/CMakeLists.txt @@ -0,0 +1,87 @@ +set(P3DCPARSER_HEADERS + dcAtomicField.h dcAtomicField.I + dcClass.h dcClass.I + dcDeclaration.h + dcField.h dcField.I + dcFile.h dcFile.I + dcKeyword.h dcKeywordList.h + dcLexer.lxx dcLexerDefs.h + dcMolecularField.h + dcParser.yxx dcParserDefs.h + dcSubatomicType.h + dcPackData.h dcPackData.I + dcPacker.h dcPacker.I + dcPackerCatalog.h dcPackerCatalog.I + dcPackerInterface.h dcPackerInterface.I + dcParameter.h + dcClassParameter.h + dcArrayParameter.h + dcSimpleParameter.h + dcSwitchParameter.h + dcNumericRange.h dcNumericRange.I + dcSwitch.h + dcTypedef.h + dcbase.h + dcindent.h + dcmsgtypes.h + hashGenerator.h + primeNumberGenerator.h +) + +set(P3DCPARSER_SOURCES + dcAtomicField.cxx + dcClass.cxx + dcDeclaration.cxx + dcField.cxx + dcFile.cxx + dcKeyword.cxx + dcKeywordList.cxx + dcMolecularField.cxx + dcSubatomicType.cxx + dcPackData.cxx + dcPacker.cxx + dcPackerCatalog.cxx + dcPackerInterface.cxx + dcParameter.cxx + dcClassParameter.cxx + dcArrayParameter.cxx + dcSimpleParameter.cxx + dcSwitchParameter.cxx + dcSwitch.cxx + dcTypedef.cxx + dcindent.cxx + hashGenerator.cxx + primeNumberGenerator.cxx +) + +set(P3DCPARSER_IGATEEXT + dcClass_ext.cxx dcClass_ext.h + dcField_ext.cxx dcField_ext.h + dcPacker_ext.cxx dcPacker_ext.h +) + +add_bison_target(dcParser.cxx dcParser.yxx DEFINES dcParser.h PREFIX dcyy) +add_flex_target(dcLexer.cxx dcLexer.lxx CASE_INSENSITIVE PREFIX dcyy) + +# These cannot be interrogated, and are excluded from the composites. +set(P3DCPARSER_PARSER_SOURCES + dcParser.cxx + dcLexer.cxx) + +composite_sources(p3dcparser P3DCPARSER_SOURCES) +add_component_library(p3dcparser NOINIT SYMBOL BUILDING_DIRECT_DCPARSER + ${P3DCPARSER_HEADERS} ${P3DCPARSER_SOURCES} ${P3DCPARSER_PARSER_SOURCES}) +target_compile_definitions(p3dcparser PUBLIC WITHIN_PANDA) +target_link_libraries(p3dcparser p3directbase panda) +target_interrogate(p3dcparser ${P3DCPARSER_HEADERS} ${P3DCPARSER_SOURCES} + EXTENSIONS ${P3DCPARSER_IGATEEXT}) + +if(NOT BUILD_METALIBS) + install(TARGETS p3dcparser + EXPORT Direct COMPONENT Direct + DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d + ARCHIVE COMPONENT DirectDevel) +endif() +install(FILES ${P3DCPARSER_HEADERS} COMPONENT DirectDevel DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d) diff --git a/direct/src/dcparser/dcbase.h b/direct/src/dcparser/dcbase.h index 3a3fbbd13e..75ddca8030 100644 --- a/direct/src/dcparser/dcbase.h +++ b/direct/src/dcparser/dcbase.h @@ -36,12 +36,12 @@ #else // WITHIN_PANDA -#ifdef WIN32 +#ifdef _MSC_VER /* C4786: 255 char debug symbols */ #pragma warning (disable : 4786) /* C4503: decorated name length exceeded */ #pragma warning (disable : 4503) -#endif /* WIN32_VC */ +#endif /* _MSC_VER */ #include #include @@ -54,7 +54,7 @@ // These header files are needed to compile dcLexer.cxx, the output from flex. // flex doesn't create a perfectly windows-friendly source file right out of // the box. -#ifdef WIN32 +#ifdef _WIN32 #include #include #else diff --git a/direct/src/deadrec/CMakeLists.txt b/direct/src/deadrec/CMakeLists.txt new file mode 100644 index 0000000000..0a2bb1b96a --- /dev/null +++ b/direct/src/deadrec/CMakeLists.txt @@ -0,0 +1,24 @@ +set(P3DEADREC_HEADERS + config_deadrec.h + smoothMover.h smoothMover.I +) + +set(P3DEADREC_SOURCES + config_deadrec.cxx + smoothMover.cxx +) + +add_component_library(p3deadrec SYMBOL BUILDING_DIRECT_DEADREC + ${P3DEADREC_HEADERS} ${P3DEADREC_SOURCES}) +target_link_libraries(p3deadrec p3directbase panda) +target_interrogate(p3deadrec ALL) + +if(NOT BUILD_METALIBS) + install(TARGETS p3deadrec + EXPORT Direct COMPONENT Direct + DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d + ARCHIVE COMPONENT DirectDevel) +endif() +install(FILES ${P3DEADREC_HEADERS} COMPONENT DirectDevel DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d) diff --git a/direct/src/directbase/CMakeLists.txt b/direct/src/directbase/CMakeLists.txt new file mode 100644 index 0000000000..eea5100de2 --- /dev/null +++ b/direct/src/directbase/CMakeLists.txt @@ -0,0 +1,14 @@ +set(P3DIRECTBASE_SOURCES + directbase.cxx +) + +set(P3DIRECTBASE_HEADERS + directbase.h directsymbols.h +) + +# Yes, INTERFACE: don't build it, there's no code! +add_library(p3directbase INTERFACE) +target_link_libraries(p3directbase INTERFACE panda) + +install(TARGETS p3directbase EXPORT Direct COMPONENT Direct) +install(FILES ${P3DIRECTBASE_HEADERS} COMPONENT DirectDevel DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d) diff --git a/direct/src/dist/commands.py b/direct/src/dist/commands.py index b70effdf87..644b3774c6 100644 --- a/direct/src/dist/commands.py +++ b/direct/src/dist/commands.py @@ -396,27 +396,22 @@ class build_apps(setuptools.Command): self.announce('Gathering wheels for platform: {}'.format(platform), distutils.log.INFO) - whldir = os.path.join(self.build_base, '__whl_cache__') + whlcache = os.path.join(self.build_base, '__whl_cache__') - #TODO find a better way to get abi tag than from internal/private pip APIs - if hasattr(pip, 'pep425tags'): - pep425tags = pip.pep425tags - wheel = pip.wheel - else: - from pip._internal import pep425tags, wheel + pip_version = int(pip.__version__.split('.')[0]) + if pip_version < 9: + raise RuntimeError("pip 9.0 or greater is required, but found {}".format(pip.__version__)) - abi_tag = pep425tags.get_abi_tag() - - if 'u' in abi_tag and (platform.startswith('win') or platform.startswith('macosx')): - abi_tag = abi_tag.replace('u', '') + abi_tag = 'cp%d%d' % (sys.version_info[:2]) + if sys.version_info < (3, 8): + abi_tag += 'm' # For these distributions, we need to append 'u' on Linux if abi_tag in ('cp26m', 'cp27m', 'cp32m') and not platform.startswith('win') and not platform.startswith('macosx'): abi_tag += 'u' - pip_version = pip.__version__.split('.') - if int(pip_version[0]) < 9: - raise RuntimeError("pip 9.0 or greater is required, but found {}".format(pip.__version__)) + whldir = os.path.join(whlcache, '_'.join((platform, abi_tag))) + os.makedirs(whldir, exist_ok=True) # Remove any .zip files. These are built from a VCS and block for an # interactive prompt on subsequent downloads. @@ -444,19 +439,12 @@ class build_apps(setuptools.Command): subprocess.check_call([sys.executable, '-m', 'pip'] + pip_args) - # Now figure out which of the downloaded wheels are relevant to us. - tags = pep425tags.get_supported(platform=platform, abi=abi_tag) - wheelpaths = [] - for filename in os.listdir(whldir): - try: - whl = wheel.Wheel(filename) - except wheel.InvalidWheelFilename: - continue - - if whl.supported(tags): - wheelpaths.append(os.path.join(whldir, filename)) - - return wheelpaths + # Return a list of paths to the downloaded whls + return [ + os.path.join(whldir, filename) + for filename in os.listdir(whldir) + if filename.endswith('.whl') + ] def update_pe_resources(self, appname, runtime): """Update resources (e.g., icons) in windows PE file""" diff --git a/direct/src/distributed/CMakeLists.txt b/direct/src/distributed/CMakeLists.txt new file mode 100644 index 0000000000..898323f0d5 --- /dev/null +++ b/direct/src/distributed/CMakeLists.txt @@ -0,0 +1,35 @@ +if(NOT HAVE_PYTHON) + return() +endif() + +set(P3DISTRIBUTED_HEADERS + config_distributed.h + cConnectionRepository.h + cConnectionRepository.I + cDistributedSmoothNodeBase.h + cDistributedSmoothNodeBase.I +) + +set(P3DISTRIBUTED_SOURCES + config_distributed.cxx +) + +set(P3DISTRIBUTED_IGATEEXT + cConnectionRepository.cxx + cDistributedSmoothNodeBase.cxx +) + +add_component_library(p3distributed NOINIT SYMBOL BUILDING_DIRECT_DISTRIBUTED + ${P3DISTRIBUTED_HEADERS} ${P3DISTRIBUTED_SOURCES}) +target_link_libraries(p3distributed p3directbase p3dcparser panda) +target_interrogate(p3distributed ALL EXTENSIONS ${P3DISTRIBUTED_IGATEEXT}) + +if(NOT BUILD_METALIBS) + install(TARGETS p3distributed + EXPORT Direct COMPONENT Direct + DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d + ARCHIVE COMPONENT DirectDevel) +endif() +install(FILES ${P3DISTRIBUTED_HEADERS} COMPONENT DirectDevel DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d) diff --git a/direct/src/fsm/FSM.py b/direct/src/fsm/FSM.py index eb67f55c0a..8236b64a75 100644 --- a/direct/src/fsm/FSM.py +++ b/direct/src/fsm/FSM.py @@ -153,6 +153,12 @@ class FSM(DirectObject): # must be approved by some filter function. defaultTransitions = None + # An enum class for special states like the DEFAULT or ANY state, + # that should be treatened by the FSM in a special way + class EnumStates(): + ANY = 1 + DEFAULT = 2 + def __init__(self, name): self.fsmLock = RLock() self._name = name @@ -382,6 +388,27 @@ class FSM(DirectObject): # accept it. return (request,) + args + elif FSM.EnumStates.ANY in self.defaultTransitions.get(self.state, []): + # Whenever we have a '*' as our to transition, we allow + # to transit to any other state + return (request,) + args + + elif request in self.defaultTransitions.get(FSM.EnumStates.ANY, []): + # If the requested state is in the default transitions + # from any state list, we also alow to transit to the + # new state + return (request,) + args + + elif FSM.EnumStates.ANY in self.defaultTransitions.get(FSM.EnumStates.ANY, []): + # This is like we had set the defaultTransitions to None. + # Any state can transit to any other state + return (request,) + args + + elif request in self.defaultTransitions.get(FSM.EnumStates.DEFAULT, []): + # This is the fallback state that we use whenever no + # other trnasition was possible + return (request,) + args + # If self.defaultTransitions is not None, it is an error # to request a direct state transition (capital letter # request) not listed in defaultTransitions and not diff --git a/direct/src/gui/DirectScrollBar.py b/direct/src/gui/DirectScrollBar.py index a873924456..822cb5b3a6 100644 --- a/direct/src/gui/DirectScrollBar.py +++ b/direct/src/gui/DirectScrollBar.py @@ -88,6 +88,8 @@ class DirectScrollBar(DirectFrame): else: self.incButton['frameSize'] = (f[0], f[1], f[2]*0.05, f[3]*0.05) + self._lastOrientation = self['orientation'] + self.guiItem.setThumbButton(self.thumb.guiItem) self.guiItem.setLeftButton(self.decButton.guiItem) self.guiItem.setRightButton(self.incButton.guiItem) @@ -140,13 +142,38 @@ class DirectScrollBar(DirectFrame): def setOrientation(self): if self['orientation'] == DGG.HORIZONTAL: + if self._lastOrientation in (DGG.VERTICAL, DGG.VERTICAL_INVERTED): + fpre = self['frameSize'] + # swap frameSize width and height to keep custom frameSizes + self['frameSize'] = (fpre[2], fpre[3], fpre[0], fpre[1]) + f = self.decButton['frameSize'] + self.decButton['frameSize'] = (f[2], f[3], f[0], f[1]) + f = self.incButton['frameSize'] + self.incButton['frameSize'] = (f[2], f[3], f[0], f[1]) self.guiItem.setAxis(Vec3(1, 0, 0)) elif self['orientation'] == DGG.VERTICAL: + if self._lastOrientation == DGG.HORIZONTAL: + fpre = self['frameSize'] + # swap frameSize width and height to keep custom frameSizes + self['frameSize'] = (fpre[2], fpre[3], fpre[0], fpre[1]) + f = self.decButton['frameSize'] + self.decButton['frameSize'] = (f[2], f[3], f[0], f[1]) + f = self.incButton['frameSize'] + self.incButton['frameSize'] = (f[2], f[3], f[0], f[1]) self.guiItem.setAxis(Vec3(0, 0, -1)) elif self['orientation'] == DGG.VERTICAL_INVERTED: + if self._lastOrientation == DGG.HORIZONTAL: + fpre = self['frameSize'] + # swap frameSize width and height to keep custom frameSizes + self['frameSize'] = (fpre[2], fpre[3], fpre[0], fpre[1]) + f = self.decButton['frameSize'] + self.decButton['frameSize'] = (f[2], f[3], f[0], f[1]) + f = self.incButton['frameSize'] + self.incButton['frameSize'] = (f[2], f[3], f[0], f[1]) self.guiItem.setAxis(Vec3(0, 0, 1)) else: raise ValueError('Invalid value for orientation: %s' % (self['orientation'])) + self._lastOrientation = self['orientation'] def setManageButtons(self): self.guiItem.setManagePieces(self['manageButtons']) diff --git a/direct/src/gui/DirectScrolledFrame.py b/direct/src/gui/DirectScrolledFrame.py index 7b30ba499e..c860797b74 100644 --- a/direct/src/gui/DirectScrolledFrame.py +++ b/direct/src/gui/DirectScrolledFrame.py @@ -77,9 +77,11 @@ class DirectScrolledFrame(DirectFrame): self.initialiseoptions(DirectScrolledFrame) def setScrollBarWidth(self): + if self.fInit: return + w = self['scrollBarWidth'] - self.verticalScroll["frameSize"] = (-w / 2.0, w / 2.0, -1, 1) - self.horizontalScroll["frameSize"] = (-1, 1, -w / 2.0, w / 2.0) + self.verticalScroll["frameSize"] = (-w / 2.0, w / 2.0, self.verticalScroll["frameSize"][2], self.verticalScroll["frameSize"][3]) + self.horizontalScroll["frameSize"] = (self.horizontalScroll["frameSize"][0], self.horizontalScroll["frameSize"][1], -w / 2.0, w / 2.0) def setCanvasSize(self): f = self['canvasSize'] diff --git a/direct/src/gui/DirectSlider.py b/direct/src/gui/DirectSlider.py index c5823a9efc..e113f34055 100644 --- a/direct/src/gui/DirectSlider.py +++ b/direct/src/gui/DirectSlider.py @@ -41,7 +41,7 @@ class DirectSlider(DirectFrame): ('extraArgs', [], None), ) - if kw.get('orientation') == DGG.VERTICAL: + if kw.get('orientation') in (DGG.VERTICAL, DGG.VERTICAL_INVERTED): # These are the default options for a vertical layout. optiondefs += ( ('frameSize', (-0.08, 0.08, -1, 1), None), @@ -72,6 +72,8 @@ class DirectSlider(DirectFrame): else: self.thumb['frameSize'] = (f[0], f[1], f[2]*0.05, f[3]*0.05) + self._lastOrientation = self['orientation'] + self.guiItem.setThumbButton(self.thumb.guiItem) # Bind command function @@ -115,11 +117,35 @@ class DirectSlider(DirectFrame): def setOrientation(self): if self['orientation'] == DGG.HORIZONTAL: + if self._lastOrientation in (DGG.VERTICAL, DGG.VERTICAL_INVERTED): + fpre = self['frameSize'] + # swap frameSize width and height to keep custom frameSizes + self['frameSize'] = (fpre[2], fpre[3], fpre[0], fpre[1]) + tf = self.thumb['frameSize'] + self.thumb['frameSize'] = (tf[2], tf[3], tf[0], tf[1]) self.guiItem.setAxis(Vec3(1, 0, 0)) + self['frameVisibleScale'] = (1, 0.25) elif self['orientation'] == DGG.VERTICAL: + if self._lastOrientation == DGG.HORIZONTAL: + fpre = self['frameSize'] + # swap frameSize width and height to keep custom frameSizes + self['frameSize'] = (fpre[2], fpre[3], fpre[0], fpre[1]) + tf = self.thumb['frameSize'] + self.thumb['frameSize'] = (tf[2], tf[3], tf[0], tf[1]) self.guiItem.setAxis(Vec3(0, 0, 1)) + self['frameVisibleScale'] = (0.25, 1) + elif self['orientation'] == DGG.VERTICAL_INVERTED: + if self._lastOrientation == DGG.HORIZONTAL: + fpre = self['frameSize'] + # swap frameSize width and height to keep custom frameSizes + self['frameSize'] = (fpre[2], fpre[3], fpre[0], fpre[1]) + tf = self.thumb['frameSize'] + self.thumb['frameSize'] = (tf[2], tf[3], tf[0], tf[1]) + self.guiItem.setAxis(Vec3(0, 0, -1)) + self['frameVisibleScale'] = (0.25, 1) else: raise ValueError('Invalid value for orientation: %s' % (self['orientation'])) + self._lastOrientation = self['orientation'] def destroy(self): if (hasattr(self, 'thumb')): diff --git a/direct/src/interval/CMakeLists.txt b/direct/src/interval/CMakeLists.txt new file mode 100644 index 0000000000..2eba8a917a --- /dev/null +++ b/direct/src/interval/CMakeLists.txt @@ -0,0 +1,54 @@ +set(P3INTERVAL_HEADERS + config_interval.h + cInterval.I cInterval.h + cIntervalManager.I cIntervalManager.h + cConstraintInterval.I cConstraintInterval.h + cConstrainTransformInterval.I cConstrainTransformInterval.h + cConstrainPosInterval.I cConstrainPosInterval.h + cConstrainHprInterval.I cConstrainHprInterval.h + cConstrainPosHprInterval.I cConstrainPosHprInterval.h + cLerpInterval.I cLerpInterval.h + cLerpNodePathInterval.I cLerpNodePathInterval.h + cLerpAnimEffectInterval.I cLerpAnimEffectInterval.h + cMetaInterval.I cMetaInterval.h + hideInterval.I hideInterval.h + lerpblend.h + showInterval.I showInterval.h + waitInterval.I waitInterval.h + lerp_helpers.h +) + +set(P3INTERVAL_SOURCES + config_interval.cxx + cInterval.cxx + cIntervalManager.cxx + cConstraintInterval.cxx + cConstrainTransformInterval.cxx + cConstrainPosInterval.cxx + cConstrainHprInterval.cxx + cConstrainPosHprInterval.cxx + cLerpInterval.cxx + cLerpNodePathInterval.cxx + cLerpAnimEffectInterval.cxx + cMetaInterval.cxx + hideInterval.cxx + lerpblend.cxx + showInterval.cxx + waitInterval.cxx +) + +composite_sources(p3interval P3INTERVAL_SOURCES) +add_component_library(p3interval SYMBOL BUILDING_DIRECT_INTERVAL + ${P3INTERVAL_HEADERS} ${P3INTERVAL_SOURCES}) +target_link_libraries(p3interval p3directbase panda) +target_interrogate(p3interval ALL) + +if(NOT BUILD_METALIBS) + install(TARGETS p3interval + EXPORT Direct COMPONENT Direct + DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d + ARCHIVE COMPONENT DirectDevel) +endif() +install(FILES ${P3INTERVAL_HEADERS} COMPONENT DirectDevel DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d) diff --git a/direct/src/motiontrail/CMakeLists.txt b/direct/src/motiontrail/CMakeLists.txt new file mode 100644 index 0000000000..2c4ba8b78b --- /dev/null +++ b/direct/src/motiontrail/CMakeLists.txt @@ -0,0 +1,24 @@ +set(P3MOTIONTRAIL_HEADERS + config_motiontrail.h + cMotionTrail.h +) + +set(P3MOTIONTRAIL_SOURCES + config_motiontrail.cxx + cMotionTrail.cxx +) + +add_component_library(p3motiontrail SYMBOL BUILDING_DIRECT_MOTIONTRAIL + ${P3MOTIONTRAIL_HEADERS} ${P3MOTIONTRAIL_SOURCES}) +target_link_libraries(p3motiontrail p3directbase panda) +target_interrogate(p3motiontrail ALL) + +if(NOT BUILD_METALIBS) + install(TARGETS p3motiontrail + EXPORT Direct COMPONENT Direct + DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d + ARCHIVE COMPONENT DirectDevel) +endif() +install(FILES ${P3MOTIONTRAIL_HEADERS} COMPONENT DirectDevel DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d) diff --git a/direct/src/particles/ParticleEffect.py b/direct/src/particles/ParticleEffect.py index 41930dd46b..2705ae39fd 100644 --- a/direct/src/particles/ParticleEffect.py +++ b/direct/src/particles/ParticleEffect.py @@ -36,6 +36,10 @@ class ParticleEffect(NodePath): self.addParticles(particles) self.renderParent = None + def birthLitter(self): + for p in self.particlesDict.values(): + p.birthLitter() + def cleanup(self): self.removeNode() self.disable() @@ -269,3 +273,4 @@ class ParticleEffect(NodePath): clear_to_initial = clearToInitial soft_stop = softStop soft_start = softStart + birth_litter = birthLitter diff --git a/direct/src/showbase/CMakeLists.txt b/direct/src/showbase/CMakeLists.txt new file mode 100644 index 0000000000..a45fa14b4b --- /dev/null +++ b/direct/src/showbase/CMakeLists.txt @@ -0,0 +1,32 @@ +set(P3SHOWBASE_HEADERS + showBase.h +) + +set(P3SHOWBASE_SOURCES + showBase.cxx +) + +if(APPLE) + list(APPEND P3SHOWBASE_SOURCES showBase_assist.mm) + + # Bug in CMake 3.16.2: it tries to put .mm with the .cxx + set_source_files_properties(showBase_assist.mm PROPERTIES + SKIP_UNITY_BUILD_INCLUSION YES) + +endif() + +add_component_library(p3showbase NOINIT SYMBOL BUILDING_DIRECT_SHOWBASE + ${P3SHOWBASE_HEADERS} ${P3SHOWBASE_SOURCES}) + +target_link_libraries(p3showbase p3directbase panda) +target_interrogate(p3showbase ALL) + +if(NOT BUILD_METALIBS) + install(TARGETS p3showbase + EXPORT Direct COMPONENT Direct + DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d + ARCHIVE COMPONENT DirectDevel) +endif() +install(FILES ${P3SHOWBASE_HEADERS} COMPONENT DirectDevel DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d) diff --git a/direct/src/showbase/showBase.cxx b/direct/src/showbase/showBase.cxx index 588dbb6540..7f90d4c93c 100644 --- a/direct/src/showbase/showBase.cxx +++ b/direct/src/showbase/showBase.cxx @@ -27,7 +27,7 @@ extern "C" { void CPSEnableForegroundOperation(ProcessSerialNumber* psn); } #include "camera.h" #include "graphicsPipeSelection.h" -#ifdef WIN32 +#ifdef _WIN32 #include // For SystemParametersInfo() STICKYKEYS g_StartupStickyKeys = {sizeof(STICKYKEYS), 0}; TOGGLEKEYS g_StartupToggleKeys = {sizeof(TOGGLEKEYS), 0}; @@ -131,7 +131,7 @@ query_fullscreen_testresult(int xsize, int ysize) { void store_accessibility_shortcut_keys() { -#ifdef WIN32 +#ifdef _WIN32 SystemParametersInfo(SPI_GETSTICKYKEYS, sizeof(STICKYKEYS), &g_StartupStickyKeys, 0); SystemParametersInfo(SPI_GETTOGGLEKEYS, sizeof(TOGGLEKEYS), &g_StartupToggleKeys, 0); SystemParametersInfo(SPI_GETFILTERKEYS, sizeof(FILTERKEYS), &g_StartupFilterKeys, 0); @@ -140,7 +140,7 @@ store_accessibility_shortcut_keys() { void allow_accessibility_shortcut_keys(bool allowKeys) { -#ifdef WIN32 +#ifdef _WIN32 if( allowKeys ) { // Restore StickyKeysetc to original state and enable Windows key diff --git a/dtool/CMakeLists.txt b/dtool/CMakeLists.txt new file mode 100644 index 0000000000..62308bd980 --- /dev/null +++ b/dtool/CMakeLists.txt @@ -0,0 +1,14 @@ +# Generate dtool_config.h +include(LocalSetup.cmake) + +# Include dtool source directories +add_subdirectory(src/cppparser) +add_subdirectory(src/dconfig) +add_subdirectory(src/dtoolbase) +add_subdirectory(src/dtoolutil) +add_subdirectory(src/interrogate) +add_subdirectory(src/interrogatedb) +add_subdirectory(src/prc) + +# Include dtool metalib +add_subdirectory(metalibs/dtool) diff --git a/dtool/CompilerFlags.cmake b/dtool/CompilerFlags.cmake new file mode 100644 index 0000000000..a947d50927 --- /dev/null +++ b/dtool/CompilerFlags.cmake @@ -0,0 +1,247 @@ +# +# CompilerFlags.cmake +# +# This file sets up various compiler flags (warning levels, turning off options +# we don't need, etc.) It must be included directly from the root +# CMakeLists.txt, due to its use of set(...) +# + +include(CheckCXXCompilerFlag) + +# These are flags for the custom configurations we add +# Standard +if(MSVC) + set(CMAKE_C_FLAGS_STANDARD "/Ox") + set(CMAKE_CXX_FLAGS_STANDARD "/Ox") +else() + set(CMAKE_C_FLAGS_STANDARD "-O3") + set(CMAKE_CXX_FLAGS_STANDARD "-O3") +endif() +set(CMAKE_SHARED_LINKER_FLAGS_STANDARD "") +set(CMAKE_MODULE_LINKER_FLAGS_STANDARD "") +set(CMAKE_EXE_LINKER_FLAGS_STANDARD "") + +# Coverage (when we know how to support it) +if(CMAKE_CXX_COMPILER_ID MATCHES "(AppleClang|Clang)") + set(CMAKE_C_FLAGS_COVERAGE + "${CMAKE_C_FLAGS_DEBUG} -fprofile-instr-generate -fcoverage-mapping") + set(CMAKE_CXX_FLAGS_COVERAGE + "${CMAKE_CXX_FLAGS_DEBUG} -fprofile-instr-generate -fcoverage-mapping") + + set(CMAKE_SHARED_LINKER_FLAGS_COVERAGE + "${CMAKE_SHARED_LINKER_FLAGS_DEBUG} -fprofile-instr-generate") + set(CMAKE_MODULE_LINKER_FLAGS_COVERAGE + "${CMAKE_MODULE_LINKER_FLAGS_DEBUG} -fprofile-instr-generate") + set(CMAKE_EXE_LINKER_FLAGS_COVERAGE + "${CMAKE_EXE_LINKER_FLAGS_DEBUG} -fprofile-instr-generate") + +elseif(CMAKE_CXX_COMPILER_ID STREQUAL "GCC") + set(CMAKE_C_FLAGS_COVERAGE "${CMAKE_C_FLAGS_DEBUG} --coverage") + set(CMAKE_CXX_FLAGS_COVERAGE "${CMAKE_CXX_FLAGS_DEBUG} --coverage") + + set(CMAKE_SHARED_LINKER_FLAGS_COVERAGE + "${CMAKE_SHARED_LINKER_FLAGS_DEBUG} --coverage") + set(CMAKE_MODULE_LINKER_FLAGS_COVERAGE + "${CMAKE_MODULE_LINKER_FLAGS_DEBUG} --coverage") + set(CMAKE_EXE_LINKER_FLAGS_COVERAGE + "${CMAKE_EXE_LINKER_FLAGS_DEBUG} --coverage") + +endif() + +# Panda3D is now a C++11 project. Newer versions of CMake support this out of +# the box; for older versions we take a shot in the dark: +if(CMAKE_VERSION VERSION_LESS "3.1") + check_cxx_compiler_flag("-std=gnu++11" COMPILER_SUPPORTS_CXX11) + if(COMPILER_SUPPORTS_CXX11) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++11") + else() + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++0x") + endif() + +else() + set(CMAKE_CXX_STANDARD 11) + set(CMAKE_CXX_STANDARD_REQUIRED ON) + +endif() + +# Set certain CMake flags we expect +set(CMAKE_INCLUDE_CURRENT_DIR_IN_INTERFACE ON) +set(CMAKE_INCLUDE_CURRENT_DIR ON) +set(CMAKE_FIND_PACKAGE_PREFER_CONFIG ON) + +# Set up the output directory structure, mimicking that of makepanda +set(CMAKE_BINARY_DIR "${CMAKE_BINARY_DIR}/cmake") + +if(CMAKE_CFG_INTDIR STREQUAL ".") + # Single-configuration generator; output goes straight in the binary dir + set(PANDA_OUTPUT_DIR "${PROJECT_BINARY_DIR}") + +else() + # Multi-configuration generator; add a per-configuration path prefix + set(PANDA_OUTPUT_DIR "${PROJECT_BINARY_DIR}/$") + +endif() + +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${PANDA_OUTPUT_DIR}/bin") +set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${PANDA_OUTPUT_DIR}/lib") +set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${PANDA_OUTPUT_DIR}/lib") + +set(MODULE_DESTINATION "${CMAKE_INSTALL_LIBDIR}") + +# Runtime code assumes that dynamic modules have a "lib" prefix; Windows +# assumes that debug libraries have a _d suffix. +set(CMAKE_SHARED_MODULE_PREFIX "lib") +if(WIN32) + set(CMAKE_DEBUG_POSTFIX "_d") + + # Windows uses libfoo.lib for static libraries and foo.lib/dll for dynamic. + set(CMAKE_STATIC_LIBRARY_PREFIX "lib") + + # On Windows, modules (DLLs) are located in bin; lib is just for .lib files + set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${PANDA_OUTPUT_DIR}/bin") + if(BUILD_SHARED_LIBS) + set(MODULE_DESTINATION "bin") + endif() +endif() + +# Though not technically correct, we'll still want MODULE type libraries +# (used for display and audio plugins) to use a .dylib extension. +if(APPLE) + set(CMAKE_SHARED_MODULE_SUFFIX ".dylib") +endif() + +# We want the output structured like build/CONFIG/bin, not build/bin/CONFIG per +# the default for multi-configuration generators. In CMake 3.4+, it switches +# automatically if the *_OUTPUT_DIRECTORY property contains a generator +# expresssion, but as of this writing we support as early as CMake 3.0.2. +# +# So, let's just do this: +if(CMAKE_VERSION VERSION_LESS "3.4") + foreach(_type RUNTIME ARCHIVE LIBRARY) + foreach(_config ${CMAKE_CONFIGURATION_TYPES}) + string(TOUPPER "${_config}" _config) + set(CMAKE_${_type}_OUTPUT_DIRECTORY_${_config} "${CMAKE_${_type}_OUTPUT_DIRECTORY}") + endforeach(_config) + endforeach(_type) +endif() + +# Set warning levels +if(MSVC) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /W3") + set(CMAKE_CCXX_FLAGS "${CMAKE_CXX_FLAGS} /W3") + +else() + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall") + +endif() + +if(CMAKE_CXX_COMPILER_ID MATCHES "(GNU|Clang)") + set(global_flags + "-Wno-unused-function -Wno-unused-parameter -fno-strict-aliasing") + set(release_flags "-Wno-unused-variable") + + if(NOT MSVC) + # These flags upset Clang when it's in MSVC mode + set(release_flags "${release_flags} -fno-stack-protector -ffast-math -fno-unsafe-math-optimizations") + + # Allow NaN to occur in the public SDK + set(standard_flags "${release_flags} -fno-finite-math-only") + + else() + set(standard_flags "${release_flags}") + + endif() + + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${global_flags}") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${global_flags} -Wno-reorder") + set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} ${release_flags}") + set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} ${release_flags}") + set(CMAKE_CXX_FLAGS_MINSIZEREL "${CMAKE_CXX_FLAGS_MINSIZEREL} ${release_flags}") + set(CMAKE_CXX_FLAGS_STANDARD "${CMAKE_CXX_FLAGS_STANDARD} ${standard_flags}") + + if(MSVC) + # Clang behaving as MSVC + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-unused-command-line-argument") + set(CMAKE_CXX_FLAGS + "${CMAKE_CXX_FLAGS} -Wno-microsoft-template -Wno-unused-command-line-argument") + endif() +endif() + +if(WIN32) + add_definitions(-D_CRT_SECURE_NO_WARNINGS) +endif() + +# CMake will often pass -rdynamic when linking executables as a convenience for +# projects that might forget when to use ENABLE_EXPORTS. This is preposterous, +# since it prevents the linker from removing symbols unneeded by the executable +# and stops us from identifying cases where ENABLE_EXPORTS is needed. +set(CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "") +set(CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS "") + +# As long as we're figuring out compiler flags, figure out the flags for +# turning C++ exception support on and off +if(MSVC) + set(cxx_exceptions_on "/EHsc") + set(cxx_exceptions_off "/D_HAS_EXCEPTIONS=0") + + set(cxx_rtti_on "/GR") + set(cxx_rtti_off "/GR-") + +else() + check_cxx_compiler_flag("-fno-exceptions" COMPILER_SUPPORTS_FEXCEPTIONS) + if(COMPILER_SUPPORTS_FEXCEPTIONS) + set(cxx_exceptions_on "-fexceptions") + set(cxx_exceptions_off "-fno-exceptions") + + else() + set(cxx_exceptions_on) + set(cxx_exceptions_off) + + endif() + + check_cxx_compiler_flag("-fno-rtti" COMPILER_SUPPORTS_FRTTI) + if(COMPILER_SUPPORTS_FRTTI) + set(cxx_rtti_on "-frtti") + set(cxx_rtti_off "-fno-rtti") + + else() + set(cxx_rtti_on) + set(cxx_rtti_off) + + endif() + +endif() + +set(cxx_exceptions_property "$>") +add_compile_options( + "$<${cxx_exceptions_property}:${cxx_exceptions_on}>" + "$<$:${cxx_exceptions_off}>") + +set(cxx_rtti_property "$>") +if(NOT ANDROID) + # Normally, our Debug build defaults RTTI on. This is not the case on + # Android, where we don't use it even on Debug, to save space. + + set(cxx_rtti_property "$,${cxx_rtti_property}>") +endif() +add_compile_options( + "$<${cxx_rtti_property}:${cxx_rtti_on}>" + "$<$:${cxx_rtti_off}>") +set_property(DIRECTORY "${PROJECT_SOURCE_DIR}" APPEND PROPERTY + COMPILE_DEFINITIONS "$<${cxx_rtti_property}:HAVE_RTTI>") + +if(MSVC) + set(msvc_bigobj_property "$>") + add_compile_options("$<${msvc_bigobj_property}:/bigobj>") +endif() + +# We should use -fvisibility=hidden everywhere, as it makes sure we think +# about what symbols really should be exposed externally. For more info, see: +# https://gcc.gnu.org/wiki/Visibility +if(NOT MSVC) + check_cxx_compiler_flag("-fvisibility=hidden" COMPILER_SUPPORTS_FVISIBILITY_HIDDEN) + if(COMPILER_SUPPORTS_FVISIBILITY_HIDDEN) + add_compile_options("-fvisibility=hidden") + endif() +endif() diff --git a/dtool/Config.cmake b/dtool/Config.cmake new file mode 100644 index 0000000000..e36d63b588 --- /dev/null +++ b/dtool/Config.cmake @@ -0,0 +1,600 @@ +# +# dtool/Config.cmake +# +# This file defines certain configuration variables that are written +# into the various make scripts. It is processed by CMake to +# generate build scripts appropriate to each environment. +# + +include(CMakeDependentOption) + +# Define our target platform. +# The values "UNIX", "WIN32", "MINGW", "MSYS", and "CYGWIN" +# are automatically provided by CMAKE. "APPLE" is also provided by +# CMAKE but may be True on systems that are not OS X. +if(CMAKE_SYSTEM_NAME MATCHES "Linux" OR CMAKE_SYSTEM_NAME MATCHES "Android") + set(IS_LINUX 1) +endif() +if(CMAKE_SYSTEM_NAME MATCHES "Darwin") + set(IS_OSX 1) +endif() +if(CMAKE_SYSTEM_NAME MATCHES "FreeBSD") + set(IS_FREEBSD 1) +endif() + +if(CMAKE_VERSION VERSION_GREATER "3.8") + get_property(IS_MULTICONFIG GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG) +else() + message(WARNING "Multi-configuration builds may not work properly when using +a CMake < 3.9. Making a guess if this is a multi-config generator.") + if(DEFINED CMAKE_CONFIGURATION_TYPES) + set(IS_MULTICONFIG ON) + else() + set(IS_MULTICONFIG OFF) + endif() +endif() + +# Define the type of build we are setting up. + +set(_configs Standard Release RelWithDebInfo Debug MinSizeRel) +if(DEFINED CMAKE_CXX_FLAGS_COVERAGE) + list(APPEND _configs Coverage) +endif() + +if(IS_MULTICONFIG) + set(CMAKE_CONFIGURATION_TYPES ${_configs}) +else() + # CMAKE_BUILD_TYPE can't just be set using the usual set(CACHE) method since + # it's an empty string by default. + if(NOT CMAKE_BUILD_TYPE) + set(CMAKE_BUILD_TYPE Standard) + endif() + set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS ${_configs}) +endif() + +set(PER_CONFIG_OPTIONS) + +# Are we building with static or dynamic linking? +option(BUILD_SHARED_LIBS + "Causes subpackages to be built separately -- setup for dynamic linking. +Utilities/tools/binaries/etc are then dynamically linked to the +libraries instead of being statically linked." ON) + +option(BUILD_METALIBS + "Should we build 'metalibs' -- fewer, larger libraries that contain the bulk +of the code instead of many smaller components. Note that turning this off +will still result in the 'metalibs' being built, but they will instead be many +smaller stub libraries and not 'meta' libraries." ON) + +# The character used to separate components of an OS-specific +# directory name depends on the platform (it is '/' on Unix, '\' on +# Windows). That character selection is hardcoded into Panda and +# cannot be changed here. (Note that an internal Panda filename +# always uses the forward slash, '/', to separate the components of a +# directory name.) + +# There's a different character used to separate the complete +# directory names in a search path specification. On Unix, the +# normal convention is ':', on Windows, it has to be ';', because the +# colon is already used to mark the drive letter. This character is +# selectable here. Most users won't want to change this. If +# multiple characters are placed in this string, any one of them may +# be used as a separator character. +if(WIN32) + set(DEFAULT_PATHSEP ";") +else() + set(DEFAULT_PATHSEP ":") +endif() + + +# Panda uses prc files for runtime configuration. There are many +# compiled-in options to customize the behavior of the prc config +# system; most users won't need to change any of them. Feel free to +# skip over all of the PRC_* variables defined here. + +# The default behavior is to search for files names *.prc in the +# directory specified by the PRC_DIR environment variable, and then +# to search along all of the directories named by the PRC_PATH +# environment variable. Either of these variables might be +# undefined; if both of them are undefined, the default is to search +# in the directory named here by DEFAULT_PRC_DIR. + +# By default, we specify the /etc dir, which is a special +# syntax that causes it to automatically search up the directory +# tree starting at the location of libpandaexpress.dll for any +# directories called 'etc'. + +if(UNIX) + set(_default_prc "etc/panda3d") +else() + set(_default_prc "etc") +endif() +set(DEFAULT_PRC_DIR "${_default_prc}" CACHE STRING + "The compiled-in default directory to look for the Config.prc file, +in the absence of the PRC_DIR environment variable set, and in +the absence of anything specified via the configpath directive.") + +# You can specify the names of the environment variables that are +# used to specify the search location(s) for prc files at runtime. +# These are space-separated lists of environment variable names. +# Specify empty string for either one of these to disable the +# feature. For instance, redefining PRC_DIR_ENVVARS here to +# PRC_DIR would cause the environment variable $PRC_DIR +# to be consulted at startup instead of the default value of +# $PANDA_PRC_DIR. + +set(PRC_DIR_ENVVARS "PANDA_PRC_DIR" CACHE STRING + "The compiled-in name of the environment variable(s) that contain +the name of a single directory in which to search for prc files.") + +set(PRC_PATH_ENVVARS "PANDA_PRC_PATH" CACHE STRING + "The compiled-in name of the environment variable(s) that contain +the name of multiple directories, separated by DEFAULT_PATHSEP, in +which to search for prc files.") + +# You can specify the name of the file(s) to search for in the above +# paths to be considered a config file. This should be a +# space-separated list of filename patterns. This is *.prc by +# default; normally there's no reason to change this. + +set(PRC_PATTERNS "*.prc" CACHE STRING + "The filename(s) to search for in the above paths. Normally this is +*.prc.") + +# You can optionally encrypt your prc file(s) to help protect them +# from curious eyes. You have to specify the encryption key, which +# gets hard-coded into the executable. (This feature provides mere +# obfuscation, not real security, since the encryption key can +# potentially be extracted by a hacker.) This requires building with +# OpenSSL. + +set(PRC_ENCRYPTED_PATTERNS "*.prc.pe" CACHE STRING + "The filename(s) for encrypted prc files.") + +set(PRC_ENCRYPTION_KEY "" CACHE STRING + "The encryption key used to decrypt any encrypted prc files +identified by PRC_ENCRYPTED_PATTERNS.") + +# One unusual feature of config is the ability to execute one or more +# of the files it discovers as if it were a program, and then treat +# the output of this program as a prc file. If you want to use this +# feature, define this variable to the filename pattern or patterns +# for such executable-style config programs (e.g. *prc.exe). This +# can be the same as the above if you like this sort of ambiguity; in +# that case, config will execute the file if it appears to be +# executable; otherwise, it will simply read it. + +set(PRC_EXECUTABLE_PATTERNS "" CACHE STRING + "The filename(s) to search for, and execute, in the above paths. +Normally this is empty.") + +# If you do use the above feature, you'll need another environment +# variable that specifies additional arguments to pass to the +# executable programs. The default definition, given here, makes +# that variable be $PANDA_PRC_XARGS. Sorry, the same arguments +# must be supplied to all executables in a given runtime session. + +set(PRC_EXECUTABLE_ARGS_ENVVAR "PANDA_PRC_XARGS" CACHE STRING + "The environment variable that defines optional args to pass to +executables found that match one of the above patterns.") + +# You can implement signed prc files, if you require this advanced +# feature. This allows certain config variables to be set only by a +# prc file that has been provided by a trusted source. To do this, +# first install and compile Dtool with OpenSSL and run the program +# make-prc-key, and then specify here the output filename generated +# by that program, and then recompile Dtool. + +set(PRC_PUBLIC_KEYS_FILENAME "" CACHE STRING "") + +# By default, the signed-prc feature, above, is enabled only for a +# release build. In a normal development environment, any prc file +# can set any config variable, whether or not it is signed. Set +# this variable true or false to explicitly enable or disable this +# feature. +#XXX For which build types should this be enabled? +if(CMAKE_BUILD_TYPE STREQUAL "Release") + set(DEFAULT_PRC_RESPECT_TRUST_LEVEL ON) +else() + set(DEFAULT_PRC_RESPECT_TRUST_LEVEL OFF) +endif() + +option(PRC_RESPECT_TRUST_LEVEL + "Define if we want to enable the trust_level feature of prc config +variables. This requires OpenSSL and PRC_PUBLIC_KEYS_FILENAME, +above." ${DEFAULT_PRC_RESPECT_TRUST_LEVEL}) + +# If trust level is in effect, this specifies the default trust level +# for any legacy (Dconfig) config variables (that is, variables +# created using the config.GetBool(), etc. interface, rather than the +# newer ConfigVariableBool interface). + +set(PRC_DCONFIG_TRUST_LEVEL "0" CACHE STRING + "The trust level value for any legacy (DConfig) variables.") + +# If trust level is in effect, you may globally increment the +# (mis)trust level of all variables by the specified amount. +# Incrementing this value by 1 will cause all variables to require at +# least a level 1 signature. + +set(PRC_INC_TRUST_LEVEL "0" CACHE STRING + "The amount by which we globally increment the trust level.") + +# Similarly, the descriptions are normally saved only in a +# development build, not in a release build. Set this value true to +# explicitly save them anyway. +#XXX only for release-release builds +option(PRC_SAVE_DESCRIPTIONS + "Define if you want to save the descriptions for ConfigVariables." + ON) + +mark_as_advanced(DEFAULT_PRC_DIR PRC_DIR_ENVVARS PRC_PATH_ENVVARS + PRC_PATTERNS PRC_ENCRYPTED_PATTERNS PRC_ENCRYPTION_KEY + PRC_EXECUTABLE_PATTERNS PRC_EXECUTABLE_ARGS_ENVVAR + PRC_PUBLIC_KEYS_FILENAME PRC_RESPECT_TRUST_LEVEL + PRC_DCONFIG_TRUST_LEVEL PRC_INC_TRUST_LEVEL PRC_SAVE_DESCRIPTIONS) + +# +# This is the end of the PRC variable customization section. The +# remaining variables are of general interest to everyone. +# + +# The following options relate to interrogate, the tool that is +# used to generate bindings for non-C++ languages. + +option(WANT_INTERROGATE + "Do you want to include Interrogate in the installation? This +program reads C++ source files and generates bindings for another +language. If you won't be building interfaces for other languages, +you don't need the program." ON) + +cmake_dependent_option(INTERROGATE_PYTHON_INTERFACE + "Do you want to generate a Python-callable interrogate interface? +This is only necessary if you plan to make calls into Panda from a +program written in Python. This is done only if HAVE_PYTHON is also +true." ON "HAVE_PYTHON" OFF) + +set(INTERROGATE_C_INTERFACE + "Do you want to generate a C-callable interrogate interface? This +generates an interface similar to the Python interface above, with +a C calling convention. It should be useful for most other kinds +of scripting language; the VR Studio used to use this to make calls +into Panda from Squeak." OFF) + +set(INTERROGATE_OPTIONS "-fnames;-string;-refcount;-assert" CACHE STRING + "What additional options should be passed to interrogate when +generating either of the above two interfaces? Generally, you +probably don't want to mess with this.") + +option(INTERROGATE_VERBOSE + "Set this if you would like interrogate to generate advanced +debugging information." OFF) + +mark_as_advanced(INTERROGATE_OPTIONS) + +# +# The following options have to do with the memory allocation system +# that will be used by Panda3D. +# + +option(DO_MEMORY_USAGE + "Do you want to compile in support for tracking memory usage? This +enables you to define the variable 'track-memory-usage' at runtime +to help track memory leaks, and also report total memory usage on +PStats. There is some small overhead for having this ability +available, even if it is unused." OFF) +list(APPEND PER_CONFIG_OPTIONS DO_MEMORY_USAGE) +set(DO_MEMORY_USAGE_Debug ON CACHE BOOL "") + +option(SIMULATE_NETWORK_DELAY + "This option compiles in support for simulating network delay via +the min-lag and max-lag prc variables. It adds a tiny bit of +overhead even when it is not activated, so it is typically enabled +only in a development build." OFF) +list(APPEND PER_CONFIG_OPTIONS SIMULATE_NETWORK_DELAY) +set(SIMULATE_NETWORK_DELAY_Debug ON CACHE BOOL "") + +option(SUPPORT_IMMEDIATE_MODE + "This option compiles in support for immediate-mode OpenGL +rendering. Since this is normally useful only for researching +buggy drivers, and since there is a tiny bit of per-primitive +overhead to have this option available even if it is unused, it is +by default enabled only in a development build. This has no effect +on DirectX rendering." OFF) +list(APPEND PER_CONFIG_OPTIONS SUPPORT_IMMEDIATE_MODE) +set(SUPPORT_IMMEDIATE_MODE_Debug ON CACHE BOOL "") + +option(NOTIFY_DEBUG + "Do you want to include the 'debug' and 'spam' Notify messages? +Normally, these are stripped out when we build for release, but sometimes it's +useful to keep them around. Turn this setting on to achieve that." OFF) +list(APPEND PER_CONFIG_OPTIONS NOTIFY_DEBUG) +set(NOTIFY_DEBUG_Debug ON CACHE BOOL "") + +option(SUPPORT_FIXED_FUNCTION + "This option compiles in support for the fixed-function OpenGL +pipeline. It is only really useful to turn this off if you are targeting +an OpenGL ES 2 system." ON) + +option(USE_MEMORY_DLMALLOC + "This is an optional alternative memory-allocation scheme +available within Panda. You can experiment with it to see +if it gives better performance than the system malloc(), but +at the time of this writing, it doesn't appear that it does." OFF) + +option(USE_MEMORY_PTMALLOC2 + "This is an optional alternative memory-allocation scheme +available within Panda. You can experiment with it to see +if it gives better performance than the system malloc(), but +at the time of this writing, it doesn't appear that it does." OFF) + +option(MEMORY_HOOK_DO_ALIGN + "Set this true if you prefer to use the system malloc library even +if 16-byte alignment must be performed on top of it, wasting up to +30% of memory usage. If you do not set this, and 16-byte alignment +is required and not provided by the system malloc library, then an +alternative malloc system (above) will be used instead." OFF) + +option(USE_DELETED_CHAIN + "Define this true to use the DELETED_CHAIN macros, which support +fast re-use of existing allocated blocks, minimizing the low-level +calls to malloc() and free() for frequently-created and -deleted +objects. There's usually no reason to set this false, unless you +suspect a bug in Panda's memory management code." ON) + +mark_as_advanced(DO_MEMORY_USAGE SIMULATE_NETWORK_DELAY + SUPPORT_IMMEDIATE_MODE USE_MEMORY_DLMALLOC USE_MEMORY_PTMALLOC2 + MEMORY_HOOK_DO_ALIGN USE_DELETED_CHAIN) + + +# +# This section relates to mobile-device/phone support and options +# + +# iPhone support +set(BUILD_IPHONE "" CACHE STRING + "Panda contains some experimental code to compile for IPhone. This +requires the Apple IPhone SDK, which is currently only available +for OS X platforms. Set this to either 'iPhoneSimulator' or +'iPhoneOS'. Note that this is still *experimental* and incomplete! +Don't enable this unless you know what you're doing!") +set_property(CACHE BUILD_IPHONE PROPERTY STRINGS "" iPhoneSimulator iPhoneOS) + + +# Android support +option(BUILD_ANDROID + "Panda contains some experimental code to compile for Android. +This requires the Google Android NDK. Besides BUILD_ANDROID, you'll +also have to set ANDROID_NDK_HOME." OFF) + +set(ANDROID_NDK_HOME "" CACHE STRING + "The location of the Android NDK directory. ANDROID_NDK_HOME may +not contain any spaces.") + +set(ANDROID_ABI "armeabi-v7a" CACHE STRING + "Can be be set to armeabi-v7a, arm64-v8a, x86, or x86_64, +depending on which architecture should be targeted.") +set_property(CACHE ANDROID_ABI PROPERTY STRINGS + armeabi-v7a arm64-v8a x86 x86_64) + +set(ANDROID_STL "c++_shared" CACHE STRING "") +set(ANDROID_PLATFORM "android-14" CACHE STRING "") +set(ANDROID_ARCH "arm" CACHE STRING "") +if(ANDROID_ARCH STREQUAL "arm") + set(ANDROID_TOOLCHAIN "arm-linux-androideabi") +else() + set(ANDROID_TOOLCHAIN "") +endif() + +mark_as_advanced(ANDROID_NDK_HOME ANDROID_ABI ANDROID_STL + ANDROID_PLATFORM ANDROID_ARCH) + + +# +# Now let's check for the presence of various thirdparty libraries. +# + + +# By default, we'll assume the user only wants to run with Debug +# python if he has to--that is, on Windows when building a debug build. +set(USE_DEBUG_PYTHON OFF) +if(WIN32) + set(USE_DEBUG_PYTHON_Debug ON) +endif() +list(APPEND PER_CONFIG_OPTIONS USE_DEBUG_PYTHON) + +cmake_dependent_option(HAVE_VIDEO4LINUX + "Set this to enable webcam support on Linux." ON + "IS_LINUX" OFF) + + +# If you are having trouble linking in OpenGL extension functions at +# runtime for some reason, you can set this variable. It also, +# requires you to install the OpenGL header files and compile-time +# libraries appropriate to the version you want to compile against. +set(MIN_GL_VERSION "1 1" CACHE STRING + "The variable is the major, minor version of OpenGL, separated by a +space (instead of a dot). Thus, \"1 1\" means OpenGL version 1.1. + +This defines the minimum runtime version of OpenGL that Panda will +require. Setting it to a higher version will compile in hard +references to the extension functions provided by that OpenGL +version and below, which may reduce runtime portability to other +systems, but it will avoid issues with getting extension function +pointers.") + + +# Should build tinydisplay? +#option(HAVE_TINYDISPLAY +# "Builds TinyDisplay, a light software renderer based on TinyGL, +#that is built into Panda. TinyDisplay is not as full-featured as Mesa +#but is many times faster." ON) +#option(HAVE_TINYDISPLAY_MinSizeRel "" OFF) +#list(APPEND PER_CONFIG_OPTIONS HAVE_TINYDISPLAY) + + +# Is SDL installed, and where? +set(Threads_FIND_QUIETLY TRUE) # Fix for builtin FindSDL +set(Eigen3_FIND_QUIETLY TRUE) # Fix for builtin FindSDL +set(PythonLibs_FIND_QUIETLY TRUE) # Fix for builtin FindSDL +set(PythonInterp_FIND_QUIETLY TRUE) # Fix for builtin FindSDL + +find_package(SDL QUIET) + +package_option(SDL + "The SDL library is useful only for tinydisplay, and is not even +required for that, as tinydisplay is also supported natively on +each supported platform.") + +# Cleanup after builtin FindSDL +mark_as_advanced(SDLMAIN_LIBRARY) +mark_as_advanced(SDL_INCLUDE_DIR) +mark_as_advanced(SDL_LIBRARY) +mark_as_advanced(SDL_LIBRARY_TEMP) + + +if(HAVE_GL AND HAVE_X11 AND NOT APPLE) + option(HAVE_GLX "Enables GLX. Requires OpenGL and X11." ON) +else() + option(HAVE_GLX "Enables GLX. Requires OpenGL and X11." OFF) +endif() + +option(LINK_IN_GLXGETPROCADDRESS + "Define this to compile in a reference to the glXGetProcAddress(). +This is only relevant from platforms using OpenGL under X." + OFF) + +if(WIN32 AND HAVE_GL) + option(HAVE_WGL "Enable WGL. Requires OpenGL on Windows." ON) +else() + option(HAVE_WGL "Enable WGL. Requires OpenGL on Windows." OFF) +endif() + +cmake_dependent_option(HAVE_COCOA "Enable Cocoa. Requires Mac OS X." ON + "APPLE" OFF) + +# +# Miscellaneous settings +# + +option(WANT_NATIVE_NET + "Define this true to build the low-level native network +implementation. Normally this should be set true." ON) + +option(HAVE_NET + "Do you want to build the high-level network interface? This layers +on top of the low-level native_net interface, specified above. +Normally, if you build NATIVE_NET, you will also build NET." + ${WANT_NATIVE_NET}) + +option(HAVE_EGG + "Do you want to build the egg loader? Usually there's no reason to +avoid building this, unless you really want to make a low-footprint +build (such as, for instance, for the iPhone)." ON) + +option(HAVE_AUDIO + "Do you want to build the audio interface?" ON) + +option(DO_PSTATS + "Enable the pstats client?" ON) + +option(USE_PANDAFILESTREAM + "Enable the PandaFileStream implementation of pfstream etc.?" ON) + +# These image formats don't require the assistance of a third-party +# library to read and write, so there's normally no reason to disable +# them int he build, unless you are looking to reduce the memory footprint. +option(HAVE_SGI_RGB "Enable support for loading SGI RGB images." ON) +option(HAVE_TGA "Enable support for loading TGA images." ON) +option(HAVE_IMG "Enable support for loading IMG images." ON) +option(HAVE_SOFTIMAGE_PIC "Enable support for loading SOFTIMAGE PIC images." ON) +option(HAVE_BMP "Enable support for loading BMP images." ON) +option(HAVE_PNM "Enable support for loading PNM images." ON) + +foreach(adv_image_format + HAVE_SGI_RGB HAVE_TGA HAVE_IMG HAVE_SOFTIMAGE_PIC HAVE_BMP HAVE_PNM) + + option(${adv_image_format}_MinSizeRel "" OFF) + list(APPEND PER_CONFIG_OPTIONS ${adv_image_format}) + + mark_as_advanced(${adv_image_format} ${adv_image_format}_MinSizeRel) + +endforeach(adv_image_format) + +# How to invoke bison and flex. Panda takes advantage of some +# bison/flex features, and therefore specifically requires bison and +# flex, not some other versions of yacc and lex. However, you only +# need to have these programs if you need to make changes to the +# bison or flex sources (see the next point, below). + +find_package(BISON QUIET) +find_package(FLEX QUIET) + +# You may not even have bison and flex installed. If you don't, no +# sweat; Panda ships with the pre-generated output of these programs, +# so you don't need them unless you want to make changes to the +# grammars themselves (files named *.yxx or *.lxx). + +set(HAVE_BISON ${BISON_FOUND}) +set(HAVE_FLEX ${FLEX_FOUND}) + + +### Configure threading support ### +set(CMAKE_THREAD_PREFER_PTHREAD ON) +set(THREADS_PREFER_PTHREAD_FLAG ON) +find_package(Threads QUIET) + +set(THREADS_LIBRARIES "${CMAKE_THREAD_LIBS_INIT}") +set(HAVE_POSIX_THREADS ${CMAKE_USE_PTHREADS_INIT}) + +# Add basic use flag for threading +package_option(THREADS + "If on, compile Panda3D with threading support. +Building in support for threading will enable Panda to take +advantage of multiple CPU's if you have them (and if the OS +supports kernel threads running on different CPU's), but it will +slightly slow down Panda for the single CPU case." + IMPORTED_AS Threads::Threads) + +# Configure debug threads +option(DEBUG_THREADS "If on, enables debugging of thread and sync operations (i.e. mutexes, deadlocks)" OFF) +list(APPEND PER_CONFIG_OPTIONS DEBUG_THREADS) +set(DEBUG_THREADS_Debug ON CACHE BOOL "") + +option(SIMPLE_THREADS + "If on, compile with simulated threads. Threads, by default, use +OS-provided threading constructs, which usually allows for full +multithreading support (i.e. the program can use multiple CPU's). +On the other hand, compiling in this full OS-provided support can +impose some substantial runtime overhead, making the application +run slower on a single-CPU machine. This settings avoid the overhead, +but still gain some of the basic functionality of threads." OFF) +list(APPEND PER_CONFIG_OPTIONS SIMPLE_THREADS) + +option(OS_SIMPLE_THREADS + "If on, OS threading constructs will be used to perform context switches. +A mutex is used to ensure that only one thread runs at a time, so the +normal SIMPLE_THREADS optimizations still apply, and the normal +SIMPLE_THREADS scheduler is used to switch between threads (instead +of the OS scheduler). This may be more portable and more reliable, +but it is a hybrid between user-space threads and os-provided threads." ON) +list(APPEND PER_CONFIG_OPTIONS OS_SIMPLE_THREADS) + +### Configure pipelining ### +option(DO_PIPELINING "If on, compile with pipelined rendering." ON) + +### Miscellaneous configuration +option(COMPILE_IN_DEFAULT_FONT + "If on, compiles in a default font, so that every TextNode will always +have a font available without requiring the user to specify one. +When turned off, the generated library will save a few kilobytes." ON) +list(APPEND PER_CONFIG_OPTIONS COMPILE_IN_DEFAULT_FONT) +set(COMPILE_IN_DEFAULT_FONT_MinSizeRel OFF CACHE BOOL "") + +option(STDFLOAT_DOUBLE + "Define this true to compile a special version of Panda to use a +'double' floating-precision type for most internal values, such as +positions and transforms, instead of the standard single-precision +'float' type. This does not affect the default numeric type of +vertices, which is controlled by the runtime config variable +vertices-float64." OFF) diff --git a/dtool/LocalSetup.cmake b/dtool/LocalSetup.cmake new file mode 100644 index 0000000000..eed31b0e84 --- /dev/null +++ b/dtool/LocalSetup.cmake @@ -0,0 +1,219 @@ +# +# LocalSetup.cmake +# +# This file contains further instructions to set up the DTOOL package +# when using CMake. In particular, it creates the dtool_config.h +# file based on the user's selected configure variables. +# + +include(CheckCXXSourceCompiles) +include(CheckCSourceRuns) +include(CheckIncludeFileCXX) +include(CheckFunctionExists) +include(CheckTypeSize) +include(TestBigEndian) +include(TestForSTDNamespace) + +# Check if this is a big-endian system. +test_big_endian(WORDS_BIGENDIAN) + +# Define if we have lockf(). +check_cxx_source_compiles(" +#include +int main(int argc, char *argv[]) { lockf(0, F_LOCK, 0); return 0; } +" PHAVE_LOCKF) + +# Define if we can trust the compiler not to insert extra bytes in +# structs between base structs and derived structs. +check_c_source_runs(" +struct A { int a; }; +struct B : public A { int b; }; +int main(int argc, char *argv[]) { + struct B i; + if ((size_t) &(i.b) == ((size_t) &(i.a)) + sizeof(struct A)) { + return 0; + } else { + return 1; + } +}" SIMPLE_STRUCT_POINTERS) + +# Define if we have STL hash_map etc. available. +# We're not using this functionality at the moment, it seems. +set(HAVE_STL_HASH OFF) + +# Check if we have a gettimeofday() function. +check_function_exists(gettimeofday HAVE_GETTIMEOFDAY) + +# Define if gettimeofday() takes only one parameter. +check_cxx_source_compiles(" +#include +int main(int argc, char *argv[]) { + struct timeval tv; + int result; + result = gettimeofday(&tv); + return 0; +}" GETTIMEOFDAY_ONE_PARAM) + +# Check if we have getopt. +check_function_exists(getopt HAVE_GETOPT) +check_function_exists(getopt_long_only HAVE_GETOPT_LONG_ONLY) +check_include_file_cxx(getopt.h PHAVE_GETOPT_H) + +# Define if you have ioctl(TIOCGWINSZ) to determine terminal width. +#XXX can we make a test case for this that isn't dependent on +# the current terminal? It might also be useful for Cygwin users. +if(UNIX) + set(IOCTL_TERMINAL_WIDTH 1) +endif() + +# Do the system headers define key ios typedefs like ios::openmode +# and ios::fmtflags? +check_cxx_source_compiles(" +#include +std::ios::openmode foo; +std::ios::fmtflags bar; +int main(int argc, char *argv[]) { return 0; } +" HAVE_IOS_TYPEDEFS) + +# Define if the C++ iostream library defines ios::binary. +check_cxx_source_compiles(" +#include +std::ios::openmode binary = std::ios::binary; +int main(int argc, char *argv[]) { return 0; } +" HAVE_IOS_BINARY) + +# Can we safely call getenv() at static init time? +if(WIN32 OR UNIX) + set(STATIC_INIT_GETENV 1) +endif() + +# Can we read the file /proc/self/[*] to determine our +# environment variables at static init time? +if(IS_LINUX) + set(HAVE_PROC_SELF_EXE 1) + set(HAVE_PROC_SELF_MAPS 1) + set(HAVE_PROC_SELF_ENVIRON 1) + set(HAVE_PROC_SELF_CMDLINE 1) +endif() + +if(IS_FREEBSD) + set(HAVE_PROC_CURPROC_FILE 1) + set(HAVE_PROC_CURPROC_MAP 1) + set(HAVE_PROC_CURPROC_CMDLINE 1) +endif() + +# Do we have a global pair of argc/argv variables that we can read at +# static init time? Should we prototype them? What are they called? +if(WIN32) + set(HAVE_GLOBAL_ARGV ON) + set(PROTOTYPE_GLOBAL_ARGV OFF) + set(GLOBAL_ARGV __argv) + set(GLOBAL_ARGC __argc) +endif() + +# Do we have all these header files? +check_include_file_cxx(io.h PHAVE_IO_H) +check_include_file_cxx(iostream PHAVE_IOSTREAM) +check_include_file_cxx(malloc.h PHAVE_MALLOC_H) +check_include_file_cxx(sys/malloc.h PHAVE_SYS_MALLOC_H) +check_include_file_cxx(alloca.h PHAVE_ALLOCA_H) +check_include_file_cxx(locale.h PHAVE_LOCALE_H) +check_include_file_cxx(string.h PHAVE_STRING_H) +check_include_file_cxx(stdlib.h PHAVE_STDLIB_H) +check_include_file_cxx(limits.h PHAVE_LIMITS_H) +check_include_file_cxx(sstream PHAVE_SSTREAM) +check_include_file_cxx(new PHAVE_NEW) +check_include_file_cxx(sys/types.h PHAVE_SYS_TYPES_H) +check_include_file_cxx(sys/time.h PHAVE_SYS_TIME_H) +check_include_file_cxx(unistd.h PHAVE_UNISTD_H) +check_include_file_cxx(utime.h PHAVE_UTIME_H) +check_include_file_cxx(glob.h PHAVE_GLOB_H) +check_include_file_cxx(dirent.h PHAVE_DIRENT_H) +check_include_file_cxx(ucontext.h PHAVE_UCONTEXT_H) #TODO doesn't work on OSX, use sys/ucontext.h +check_include_file_cxx(linux/input.h PHAVE_LINUX_INPUT_H) +check_include_file_cxx(stdint.h PHAVE_STDINT_H) + +# Do we have Posix threads? +#set(HAVE_POSIX_THREADS ${CMAKE_USE_PTHREADS_INIT}) + +# Do we have SSE2 support? +include(CheckCXXCompilerFlag) +check_cxx_compiler_flag(-msse2 HAVE_SSE2) + +# Set LINK_ALL_STATIC if we're building everything as static libraries. +# Also set the library type used for "modules" appropriately. +if(BUILD_SHARED_LIBS) + set(LINK_ALL_STATIC OFF) + set(MODULE_TYPE "MODULE" + CACHE INTERNAL "" FORCE) + +else() + set(LINK_ALL_STATIC ON) + set(MODULE_TYPE "STATIC" + CACHE INTERNAL "" FORCE) + +endif() + +# Now go through all the packages and report whether we have them. +show_packages() + +message("") +if(INTERROGATE_PYTHON_INTERFACE) + message("Compilation will generate Python interfaces for Python ${PYTHON_VERSION_STRING}.") +else() + message("Configuring Panda WITHOUT Python interfaces.") +endif() + +if(HAVE_THREADS) + if(SIMPLE_THREADS) + message("Compilation will include simulated threading support.") + elseif(DO_PIPELINING) + message("Compilation will include full, pipelined threading support.") + else() + message("Compilation will include nonpipelined threading support.") + endif() + +else() + message("Configuring Panda without threading support.") + +endif() + +message("") +message("See dtool_config.h for more details about the specified configuration.") + +message("") + +# Generate dtool_config.h +if(IS_MULTICONFIG) + foreach(config ${CMAKE_CONFIGURATION_TYPES}) + foreach(option ${PER_CONFIG_OPTIONS}) + # Check for the presence of a config-specific option, and override what's + # in the cache if there is. + if(DEFINED ${option}_${config}) + set(${option} ${${option}_${config}}) + endif() + endforeach(option) + + # Generate a dtool_config.h for this specific config + configure_file(dtool_config.h.in "${PROJECT_BINARY_DIR}/${config}/include/dtool_config.h") + + # unset() does not unset CACHE variables by default, just normal variables. + # By doing this we're reverting back to what was in the cache. + foreach(option ${PER_CONFIG_OPTIONS}) + unset(${option}) + endforeach(option) + endforeach(config) +else() + # Just configure things like normal. + configure_file(dtool_config.h.in "${PROJECT_BINARY_DIR}/include/dtool_config.h") +endif() + +install(FILES "${PANDA_OUTPUT_DIR}/include/dtool_config.h" + COMPONENT CoreDevel + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d) + +# Generate the package configuration file +export_packages("${PROJECT_BINARY_DIR}/Panda3DPackages.cmake") +install(FILES "${PROJECT_BINARY_DIR}/Panda3DPackages.cmake" + COMPONENT CoreDevel + DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/Panda3D") diff --git a/dtool/Package.cmake b/dtool/Package.cmake new file mode 100644 index 0000000000..fbf014390c --- /dev/null +++ b/dtool/Package.cmake @@ -0,0 +1,765 @@ +set(_thirdparty_dir_default "${PROJECT_SOURCE_DIR}/thirdparty") +if(NOT (APPLE OR WIN32) OR NOT IS_DIRECTORY "${_thirdparty_dir_default}") + set(_thirdparty_dir_default "") +endif() + +set(THIRDPARTY_DIRECTORY "${_thirdparty_dir_default}" CACHE PATH + "Optional location of a makepanda-style thirdparty directory. All libraries + located here will be prioritized over system libraries. Useful for + cross-compiling.") + +set(THIRDPARTY_DLLS) + +if(THIRDPARTY_DIRECTORY) + # This policy is necessary for PackageName_ROOT variables to be respected + if(POLICY CMP0074) + cmake_policy(GET CMP0074 _policy_cmp0074) + endif() + + if(NOT _policy_cmp0074 STREQUAL "NEW") + message(FATAL_ERROR + "Your version of CMake is too old; please upgrade or unset THIRDPARTY_DIRECTORY to continue.") + endif() + + # Dig up the actual "libs" directory + if(APPLE) + set(_package_dir "${THIRDPARTY_DIRECTORY}/darwin-libs-a") + + # Make sure thirdparty has the first shot, not system frameworks + set(CMAKE_FIND_FRAMEWORK LAST) + + elseif(WIN32) + if(CMAKE_SIZEOF_VOID_P EQUAL 8) + set(_package_dir "${THIRDPARTY_DIRECTORY}/win-libs-vc14-x64") + + file(GLOB _python_dirs "${THIRDPARTY_DIRECTORY}/win-python*-x64") + else() + set(_package_dir "${THIRDPARTY_DIRECTORY}/win-libs-vc14") + + file(GLOB _python_dirs "${THIRDPARTY_DIRECTORY}/win-python*") + endif() + + list(REVERSE _python_dirs) # Descending order of version + if(NOT DEFINED Python_ROOT) + set(Python_ROOT "${_python_dirs}") + endif() + + set(BISON_ROOT "${THIRDPARTY_DIRECTORY}/win-util") + set(FLEX_ROOT "${THIRDPARTY_DIRECTORY}/win-util") + + else() + message(FATAL_ERROR + "You can't use THIRDPARTY_DIRECTORY on this platform. Unset it to continue.") + + endif() + + if(NOT EXISTS "${_package_dir}") + message(FATAL_ERROR + "Either your THIRDPARTY_DIRECTORY path does not exist, or it is for the wrong platform.") + + endif() + + foreach(_Package + ARToolKit + Assimp + Bullet + Cg + Eigen3 + FCollada + FFMPEG + FMODEx + Freetype + HarfBuzz + JPEG + LibSquish + ODE + Ogg + OpenAL + OpenEXR + OpenSSL + OpusFile + PNG + SWResample + SWScale + TIFF + VorbisFile + VRPN + ZLIB + ) + + string(TOLOWER "${_Package}" _package) + string(TOUPPER "${_Package}" _PACKAGE) + + # Some packages in the thirdparty dir have different subdirectory names from + # the name of the CMake package + if(_package STREQUAL "cg") + set(_package "nvidiacg") + elseif(_package STREQUAL "eigen3") + set(_package "eigen") + elseif(_package STREQUAL "ogg") + set(_package "vorbis") # It's in the same install dir here + elseif(_package STREQUAL "opusfile") + set(_package "opus") + elseif(_package STREQUAL "libsquish") + set(_package "squish") + elseif(_package STREQUAL "swresample" OR _package STREQUAL "swscale") + set(_package "ffmpeg") # These are also part of FFmpeg + elseif(_package STREQUAL "vorbisfile") + set(_package "vorbis") + endif() + + # Set search path + set(${_Package}_ROOT "${_package_dir}/${_package}") + + # Set up copying DLLs, if necessary + file(GLOB _dlls "${${_Package}_ROOT}/bin/*.dll") + if(_dlls) + set(_havevar "HAVE_${_PACKAGE}") + set(THIRDPARTY_DLLS_${_havevar} "${_dlls}") + list(APPEND THIRDPARTY_DLLS "${_havevar}") + + endif() + + endforeach(_Package) + +endif() + +# This is used to copy the DLLs alongside the output of `package` +function(thirdparty_copy_alongside package) + set(_dlls) + + foreach(_havevar ${THIRDPARTY_DLLS}) + if(${_havevar}) + list(APPEND _dlls ${THIRDPARTY_DLLS_${_havevar}}) + endif() + endforeach(_havevar) + + if(NOT _dlls) + # Don't try to copy/install nothingness + return() + endif() + + add_custom_command(TARGET ${package} POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy_if_different + ${_dlls} $ + ) + + # Also install the DLLs + install(FILES ${_dlls} DESTINATION ${CMAKE_INSTALL_BINDIR}) + +endfunction(thirdparty_copy_alongside) + +# +# ------------ Python ------------ +# + +set(WANT_PYTHON_VERSION "" + CACHE STRING "Which Python version to seek out for building Panda3D against.") + +if(DEFINED _PREV_WANT_PYTHON_VERSION + AND NOT _PREV_WANT_PYTHON_VERSION STREQUAL WANT_PYTHON_VERSION) + # The user changed WANT_PYTHON_VERSION. We need to force FindPython to start + # anew, deleting any variable that was autodetected last time + foreach(_prev_var ${_PREV_PYTHON_VALUES}) + string(REPLACE "=" ";" _prev_var "${_prev_var}") + list(GET _prev_var 0 _prev_var_name) + list(GET _prev_var 1 _prev_var_sha1) + string(SHA1 _current_var_sha1 "${${_prev_var_name}}") + + if(_prev_var_sha1 STREQUAL _current_var_sha1) + unset(${_prev_var_name} CACHE) + endif() + + endforeach(_prev_var) + + unset(_PREV_PYTHON_VALUES CACHE) + +endif() + +if(WANT_PYTHON_VERSION) + # A specific version is requested; ensure we get that specific version + list(APPEND WANT_PYTHON_VERSION "EXACT") +endif() + +get_directory_property(_old_cache_vars CACHE_VARIABLES) +find_package(Python ${WANT_PYTHON_VERSION} QUIET COMPONENTS Interpreter Development) + +if(Python_FOUND) + set(PYTHON_FOUND ON) + set(PYTHON_EXECUTABLE ${Python_EXECUTABLE}) + set(PYTHON_INCLUDE_DIRS ${Python_INCLUDE_DIRS}) + set(PYTHON_LIBRARY_DIRS ${Python_LIBRARY_DIRS}) + set(PYTHON_VERSION_STRING ${Python_VERSION}) + +elseif(CMAKE_VERSION VERSION_LESS "3.12") + find_package(PythonInterp ${WANT_PYTHON_VERSION} QUIET) + find_package(PythonLibs ${PYTHON_VERSION_STRING} QUIET) + + if(PYTHONLIBS_FOUND) + set(PYTHON_FOUND ON) + + if(NOT PYTHON_VERSION_STRING) + set(PYTHON_VERSION_STRING ${PYTHONLIBS_VERSION_STRING}) + endif() + endif() + +endif() + +if(CMAKE_VERSION VERSION_LESS "3.15") + # CMake versions this old don't provide Python::Module, so we need to hack up + # the variables to ensure no explicit linkage against libpython occurs + + if(WIN32) + # Nothing needed here; explicit linkage is appropriate + set(PYTHON_LIBRARY "${Python_LIBRARY}") + set(PYTHON_LIBRARIES ${Python_LIBRARIES}) + + elseif(APPLE OR UNIX) + # Just unset and let the implicit linkage take over + set(PYTHON_LIBRARY "") + set(PYTHON_LIBRARIES "") + + if(APPLE) + # macOS requires this explicit flag on the linker command line to allow the + # references to the Python symbols to resolve at dynamic link time + string(APPEND CMAKE_MODULE_LINKER_FLAGS " -undefined dynamic_lookup") + + endif() + + else() + # On every other platform, guessing is a bad idea - insist the user upgrade + # their CMake instead. + message(WARNING "For Python support on this platform, please use CMake >= 3.15!") + set(PYTHON_FOUND OFF) + + endif() + +endif() + +package_option(Python + DEFAULT ON + "Enables support for Python. If INTERROGATE_PYTHON_INTERFACE +is also enabled, Python bindings will be generated." + IMPORTED_AS Python::Module) + +# Also detect the optimal install paths: +if(HAVE_PYTHON) + if(WIN32 AND NOT CYGWIN) + set(_LIB_DIR ".") + set(_ARCH_DIR ".") + + elseif(PYTHON_EXECUTABLE) + execute_process( + COMMAND ${PYTHON_EXECUTABLE} + -c "from distutils.sysconfig import get_python_lib; print(get_python_lib(False))" + OUTPUT_VARIABLE _LIB_DIR + OUTPUT_STRIP_TRAILING_WHITESPACE) + execute_process( + COMMAND ${PYTHON_EXECUTABLE} + -c "from distutils.sysconfig import get_python_lib; print(get_python_lib(True))" + OUTPUT_VARIABLE _ARCH_DIR + OUTPUT_STRIP_TRAILING_WHITESPACE) + + else() + set(_LIB_DIR "") + set(_ARCH_DIR "") + + endif() + + execute_process( + COMMAND ${PYTHON_EXECUTABLE} + -c "from sysconfig import get_config_var as g; print((g('EXT_SUFFIX') or g('SO'))[:])" + OUTPUT_VARIABLE _EXT_SUFFIX + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE) + + if(NOT _EXT_SUFFIX) + if(CYGWIN) + set(_EXT_SUFFIX ".dll") + elseif(WIN32) + set(_EXT_SUFFIX ".pyd") + else() + set(_EXT_SUFFIX ".so") + endif() + endif() + + set(PYTHON_LIB_INSTALL_DIR "${_LIB_DIR}" CACHE STRING + "Path to the Python architecture-independent package directory.") + + set(PYTHON_ARCH_INSTALL_DIR "${_ARCH_DIR}" CACHE STRING + "Path to the Python architecture-dependent package directory.") + + set(PYTHON_EXTENSION_SUFFIX "${_EXT_SUFFIX}" CACHE STRING + "Suffix for Python binary extension modules.") + +endif() + +if(NOT DEFINED _PREV_PYTHON_VALUES) + # We need to make note of all auto-defined Python variables + set(_prev_python_values) + + get_directory_property(_new_cache_vars CACHE_VARIABLES) + foreach(_cache_var ${_new_cache_vars}) + if(_cache_var MATCHES "^(Python|PYTHON)_" AND NOT _old_cache_vars MATCHES ";${_cache_var};") + string(SHA1 _cache_var_sha1 "${${_cache_var}}") + list(APPEND _prev_python_values "${_cache_var}=${_cache_var_sha1}") + endif() + endforeach(_cache_var) + + set(_PREV_PYTHON_VALUES "${_prev_python_values}" CACHE INTERNAL "Internal." FORCE) +endif() + +set(_PREV_WANT_PYTHON_VERSION "${WANT_PYTHON_VERSION}" CACHE INTERNAL "Internal." FORCE) + + +# +# ------------ Data handling libraries ------------ +# + +# OpenSSL +find_package(OpenSSL COMPONENTS SSL Crypto QUIET) + +package_option(OpenSSL + DEFAULT ON + "Enable OpenSSL support" + IMPORTED_AS OpenSSL::SSL OpenSSL::Crypto) + +option(REPORT_OPENSSL_ERRORS + "Define this true to include the OpenSSL code to report verbose +error messages when they occur." OFF) +option(REPORT_OPENSSL_ERRORS_Debug "" ON) + +package_status(OpenSSL "OpenSSL") + +# zlib +find_package(ZLIB QUIET) + +package_option(ZLIB + "Enables support for compression of Panda assets." + IMPORTED_AS ZLIB::ZLIB) + +package_status(ZLIB "zlib") + + +# +# ------------ Image formats ------------ +# + +# JPEG +find_package(JPEG QUIET) + +package_option(JPEG "Enable support for loading .jpg images.") + +package_status(JPEG "libjpeg") + +# PNG +find_package(PNG QUIET) + +package_option(PNG + "Enable support for loading .png images." + IMPORTED_AS PNG::PNG) + +package_status(PNG "libpng") + +# TIFF +find_package(TIFF QUIET) + +package_option(TIFF "Enable support for loading .tif images.") + +package_status(TIFF "libtiff") + +# OpenEXR +find_package(OpenEXR QUIET) + +package_option(OpenEXR "Enable support for loading .exr images.") + +package_status(OpenEXR "OpenEXR") + +# libsquish +find_package(LibSquish QUIET) + +package_option(SQUISH + "Enables support for automatic compression of DXT textures." + FOUND_AS LibSquish) + +package_status(SQUISH "libsquish") + + +# +# ------------ Asset formats ------------ +# + +# Assimp +find_package(Assimp QUIET) + +package_option(Assimp + "Build pandatool with support for loading 3D assets supported by Assimp.") + +package_status(Assimp "Assimp") + +# FCollada +find_package(FCollada QUIET) + +package_option(FCollada + "Build pandatool with support for loading Collada files using FCollada." + IMPORTED_AS FCollada::FCollada) + +package_status(FCollada "FCollada") + + +# +# ------------ Math libraries ------------ +# + +# Eigen +find_package(Eigen3 QUIET) + +package_option(EIGEN + "Enables use of the Eigen linear algebra library. +If this is provided, Panda will use this library as the fundamental +implementation of its own linmath library; otherwise, it will use +its own internal implementation. The primary advantage of using +Eigen is SSE2 support, which is only activated if LINMATH_ALIGN +is also enabled." + FOUND_AS Eigen3 + LICENSE "MPL-2") + +option(LINMATH_ALIGN + "This is required for activating SSE2 support using Eigen. +Activating this does constrain most objects in Panda to 16-byte +alignment, which could impact memory usage on very-low-memory +platforms. Currently experimental." ON) + +if(LINMATH_ALIGN) + package_status(EIGEN "Eigen linear algebra library" "vectorization enabled in build") +else() + package_status(EIGEN "Eigen linear algebra library" "vectorization NOT enabled in build") +endif() + +# FFTW +# FFTW 3.3.7, when built with autotools, doesn't install +# FFTW3LibraryDepends.cmake, which will crash us if we use CONFIG mode. BAH! +# Force MODULE mode to fix that. +find_package(FFTW3 MODULE QUIET) + +package_option(FFTW + "This enables support for compression of animations in .bam files. + This is only necessary for creating or reading .bam files containing + compressed animations." + FOUND_AS "FFTW3" + LICENSE "GPL") + +package_status(FFTW "FFTW") + + +# +# ------------ Multimedia formats ------------ +# + +# FFmpeg +find_package(FFMPEG QUIET) +find_package(SWScale QUIET) +find_package(SWResample QUIET) + +package_option(FFMPEG + "Enables support for audio- and video-decoding using the FFmpeg library.") +package_option(SWScale + "Enables support for FFmpeg's libswscale for video rescaling.") +package_option(SWResample + "Enables support for FFmpeg's libresample for audio resampling.") + +if(HAVE_SWSCALE AND HAVE_SWRESAMPLE) + set(ffmpeg_features "with swscale and swresample") +elseif(HAVE_SWSCALE) + set(ffmpeg_features "with swscale") +elseif(HAVE_SWRESAMPLE) + set(ffmpeg_features "with swresample") +else() + set(ffmpeg_features "without resampling/rescaling support") +endif() +package_status(FFMPEG "FFmpeg" "${ffmpeg_features}") + +# Vorbis +find_package(VorbisFile QUIET) + +package_option(VORBIS + FOUND_AS VorbisFile + "Enables support for decoding Vorbis-encoded .ogg audio files via libvorbisfile.") + +package_status(VORBIS "Vorbis") + +# Opus +find_package(OpusFile QUIET) + +package_option(OPUS + FOUND_AS OpusFile + "Enables support for decoding .opus audio files via libopusfile.") + +package_status(OPUS "Opus") + +# +# ------------ Audio libraries ------------ +# + +# FMOD Ex +find_package(FMODEx QUIET) + +package_option(FMODEx + "This enables support for the FMOD Ex sound library, + from Firelight Technologies. This audio library is free for non-commercial + use." + LICENSE "FMOD") + +package_status(FMODEx "FMOD Ex sound library") + +# OpenAL +find_package(OpenAL QUIET) + +package_option(OpenAL + "This enables support for audio output via OpenAL. Some platforms, such as + macOS, provide their own OpenAL implementation, which Panda3D can use. But, + on most platforms this will imply OpenAL Soft, which is LGPL licensed." + IMPORTED_AS OpenAL::OpenAL + LICENSE "LGPL") + +package_status(OpenAL "OpenAL sound library") + +if(OpenAL_FOUND AND APPLE OR OPENAL_FOUND AND APPLE) + set(HAVE_OPENAL_FRAMEWORK YES) +endif() + + +# +# ------------ UI libraries ------------ +# + +# Freetype + +find_package(Freetype QUIET) + +package_option(Freetype + "This enables support for the FreeType font-rendering library. If disabled, + Panda3D will only be able to read fonts specially made with egg-mkfont." + IMPORTED_AS freetype) + +package_status(Freetype "FreeType") + +# HarfBuzz + +# Some versions of harfbuzz-config.cmake contain an endless while loop, so we +# force MODULE mode here. +find_package(HarfBuzz MODULE QUIET) + +package_option(HarfBuzz + "This enables support for the HarfBuzz text shaping library." + IMPORTED_AS harfbuzz::harfbuzz) + +package_status(HarfBuzz "HarfBuzz") + +# GTK2 + +set(Freetype_FIND_QUIETLY TRUE) # Fix for builtin FindGTK2 +set(GTK2_GTK_FIND_QUIETLY TRUE) # Fix for builtin FindGTK2 +find_package(GTK2 QUIET COMPONENTS gtk) + +package_option(GTK2) + +package_status(GTK2 "gtk+-2") + + +# +# ------------ Physics engines ------------ +# + +# Bullet +find_package(Bullet MODULE QUIET) + +package_option(Bullet + "Enable this option to support game dynamics with the Bullet physics library.") + +package_status(Bullet "Bullet physics") + +# ODE +find_package(ODE QUIET) + +package_option(ODE + "Enable this option to support game dynamics with the Open Dynamics Engine (ODE)." + LICENSE "BSD-3" + IMPORTED_AS ODE::ODE) + +package_status(ODE "Open Dynamics Engine") + + +# +# ------------ SpeedTree ------------ +# + +# SpeedTree +find_package(SpeedTree QUIET) + +package_option(SpeedTree + "Enable this option to include scenegraph support for SpeedTree trees." + LICENSE "SpeedTree") + +package_status(SpeedTree "SpeedTree") + + +# +# ------------ Rendering APIs ------------ +# + +# OpenGL +find_package(OpenGL QUIET) + +package_option(GL + "Enable OpenGL support." + FOUND_AS OPENGL + IMPORTED_AS OpenGL::GL) + +package_status(GL "OpenGL") + +# OpenGL ES 1 +if(NOT APPLE) # Apple X11 ships the GLES headers but they're broken + find_package(OpenGLES1 QUIET) +endif() + +package_option(GLES1 + "Enable support for OpenGL ES 1.x rendering APIs." + FOUND_AS OPENGLES1) + +package_status(GLES1 "OpenGL ES 1.x") + +# OpenGL ES 2 +if(NOT APPLE) # Apple X11 ships the GLES headers but they're broken + find_package(OpenGLES2 QUIET) +endif() + +package_option(GLES2 + "Enable support for OpenGL ES 2.x rendering APIs." + FOUND_AS OPENGLES2) + +package_status(GLES2 "OpenGL ES 2.x") + +# Direct3D 9 +find_package(Direct3D9 QUIET COMPONENTS dxguid dxerr d3dx9) + +package_option(DX9 + "Enable support for DirectX 9. This is typically only viable on Windows." + FOUND_AS Direct3D9) + +package_status(DX9 "Direct3D 9.x") + +# Nvidia Cg +find_package(Cg QUIET) + +package_option(CG + "Enable support for Nvidia Cg Shading Language" + LICENSE "Nvidia") +package_option(CGGL + "Enable support for Nvidia Cg's OpenGL API." + LICENSE "Nvidia") +package_option(CGD3D9 + "Enable support for Nvidia Cg's Direct3D 9 API." + LICENSE "Nvidia") + +if(HAVE_CGGL AND HAVE_CGD3D9) + set(cg_apis "supporting OpenGL and Direct3D 9") +elseif(HAVE_CGGL) + set(cg_apis "supporting OpenGL") +elseif(HAVE_CGDX9) + set(cg_apis "supporting Direct3D 9") +else() + set(cg_apis "WITHOUT rendering backend support") +endif() +package_status(CG "Nvidia Cg Shading Language" "${cg_apis}") + + +# +# ------------ Display APIs ------------ +# + +# X11 (and GLX) + +if(NOT APPLE) + find_package(X11 QUIET) +endif() + +if(NOT X11_Xkb_FOUND OR NOT X11_Xutil_FOUND) + # Panda implicitly requires these supplementary X11 libs; if we can't find + # them, we just say we didn't find X11 at all. + set(X11_FOUND OFF) +endif() + +package_option(X11 + "Provides X-server support on Unix platforms. X11 may need to be linked +against for tinydisplay, but probably only on a Linux platform.") + +set(HAVE_GLX_AVAILABLE OFF) +if(HAVE_GL AND HAVE_X11 AND NOT APPLE) + set(HAVE_GLX_AVAILABLE ON) +endif() + +option(HAVE_GLX "Enables GLX. Requires OpenGL and X11." ${HAVE_GLX_AVAILABLE}) +if(HAVE_GLX AND NOT HAVE_GLX_AVAILABLE) + message(SEND_ERROR "HAVE_GLX manually set to ON but it is not available!") +endif() + +if(HAVE_GLX) + package_status(X11 "X11" "with GLX") +else() + package_status(X11 "X11" "without GLX") +endif() + +# EGL +find_package(EGL QUIET) + +package_option(EGL + "Enable support for the Khronos EGL context management interface for + OpenGL ES. This is necessary to support OpenGL ES under X11.") + +package_status(EGL "EGL") + +# +# ------------ Vision tools ------------ +# + +# OpenCV +find_package(OpenCV QUIET COMPONENTS core highgui OPTIONAL_COMPONENTS videoio) + +package_option(OpenCV + "Enable support for OpenCV. This will be built into the 'vision' package." + FOUND_AS OpenCV) + +package_status(OpenCV "OpenCV") + +# CMake <3.7 doesn't support GREATER_EQUAL, so this uses NOT LESS instead. +if(NOT OpenCV_VERSION_MAJOR LESS 3) + set(OPENCV_VER_3 ON) + +elseif(NOT OpenCV_VERSION_MAJOR LESS 2 AND + NOT OpenCV_VERSION_MINOR LESS 3) + set(OPENCV_VER_23 ON) + +endif() + +# ARToolKit +find_package(ARToolKit QUIET) + +package_option(ARToolKit + "Enable support for ARToolKit. This will be built into the 'vision' package.") + +package_status(ARToolKit "ARToolKit") + + +# +# ------------ VR integration ------------ +# + +# VRPN +find_package(VRPN QUIET) + +package_option(VRPN + "Enables support for connecting to VRPN servers. This is only needed if you + are building Panda3D for a fixed VRPN-based VR installation.") + +package_status(VRPN "VRPN") diff --git a/dtool/PandaVersion.cmake b/dtool/PandaVersion.cmake new file mode 100644 index 0000000000..2ca0a3e6e5 --- /dev/null +++ b/dtool/PandaVersion.cmake @@ -0,0 +1,103 @@ +# This file defines the current version number for Panda. It is read +# by the top CMakeLists.txt, which puts it in the global namespace for +# all CMake scripts for Panda. + +option(PANDA_OFFICIAL_VERSION + "This variable will be defined to false in the CVS repository, but +scripts that generate source tarballs and/or binary releases for +distribution, by checking out Panda from an official CVS tag, +should explictly set this to true. When false, it indicates that +the current version of Panda was checked out from CVS, so it may +not be a complete representation of the indicated version." + OFF) + +set(PANDA_DISTRIBUTOR homebuilt CACHE STRING + "This string is reported verbatim by PandaSystem::get_distributor(). +It should be set by whoever provides a particular distribution of +Panda. If you build your own Panda, leave this unchanged.") + +set(PANDA_DIST_USE_LICENSES "BSD-3;BSD-2;MIT" CACHE STRING + "This is a list of allowed licenses for 3rd-party packages to build +support for when performing a Distribution build of Panda3d. +Note: This only is checked for packages that CMake has declared with a +particular license. Some packages don't have a listed license because +they are almost always required/used, or because they are only used in +plugins that can be easily removed (eg. directx, ffmpeg, fmod, ...).") + +set(PANDA_PACKAGE_VERSION CACHE STRING + "This string is used to describe the Panda3D \"package\" associated +with this current build of Panda. It should increment with major +and minor version changes, but not sequence (or \"bugfix\") changes. +It should be unique for each unique distributor. The default is +the empty string, which means this build does not precisely match +any distributable Panda3D packages. If you are making a Panda3D +build which you will be using to produce a distributable Panda3D +package, you should set this string appropriately.") + +set(P3D_PLUGIN_VERSION "1.0.4" CACHE STRING + "We also define a version for the Panda3D plugin/runtime, +i.e. nppanda3d.dll, p3dactivex.ocx, and panda3d.exe. This is an +independent version number from PANDA_VERSION or +PANDA_PACKAGE_VERSION, because it is anticipated that this plugin +code, once settled, will need to be updated much less frequently +than Panda itself.") + +set(P3D_COREAPI_VERSION "${P3D_PLUGIN_VERSION}.1" CACHE STRING + "Finally, there's a separate version number for the Core API. At +first, we didn't believe we needed a Core API version number, but +in this belief we were naive. This version number is a little less +strict in its format requirements than P3D_PLUGIN_VERSION, above, +and it doesn't necessarily consist of a specific number of +integers, but by convention it will consist of four integers, with +the first three matching the plugin version, and the fourth integer +being incremented with each new Core API revision.") + +mark_as_advanced(PANDA_VERSION PANDA_OFFICIAL_VERSION + PANDA_PACKAGE_VERSION P3D_PLUGIN_VERSION P3D_COREAPI_VERSION + PANDA_DIST_USE_LICENSES) + +# The version gets a "c" at the end if it's not an official one. +if(PANDA_OFFICIAL_VERSION) + set(VERSION_SUFFIX "") +else() + set(VERSION_SUFFIX "c") +endif() + +set(PANDA_VERSION_STR "${PROJECT_VERSION}${VERSION_SUFFIX}") + +# This symbol is used to enforce ABI incompatibility between +# major versions of Panda3D. +set(PANDA_VERSION_SYMBOL panda_version_${PROJECT_VERSION_MAJOR}_${PROJECT_VERSION_MINOR}) + +# The Panda version as a number, with three digits reserved +# for each component. +math(EXPR PANDA_NUMERIC_VERSION "${PROJECT_VERSION_MAJOR}*1000000 + ${PROJECT_VERSION_MINOR}*1000 + ${PROJECT_VERSION_PATCH}") + +# The Panda Git SHA1 refspec, for PandaSystem::get_git_commit() +find_package(Git QUIET) +if(GIT_EXECUTABLE) + execute_process( + COMMAND "${GIT_EXECUTABLE}" rev-parse HEAD + WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}" + OUTPUT_VARIABLE PANDA_GIT_COMMIT_STR + ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE) +endif() + +# Separate the plugin version into its three components. +string(REPLACE "." ";" P3D_PLUGIN_VERSION_LIST "${P3D_PLUGIN_VERSION}") +list(GET P3D_PLUGIN_VERSION_LIST 0 P3D_PLUGIN_MAJOR_VERSION) +list(GET P3D_PLUGIN_VERSION_LIST 1 P3D_PLUGIN_MINOR_VERSION) +list(GET P3D_PLUGIN_VERSION_LIST 2 P3D_PLUGIN_SEQUENCE_VERSION) + +set(P3D_PLUGIN_VERSION_STR "${P3D_PLUGIN_VERSION}${VERSION_SUFFIX}") + +# The plugin version as dot-delimited integer quad, according to MS +# conventions for DLL version numbers. +if(PANDA_OFFICIAL_VERSION) + set(P3D_PLUGIN_DLL_DOT_VERSION "${P3D_PLUGIN_VERSION}.1000") +else() + set(P3D_PLUGIN_DLL_DOT_VERSION "${P3D_PLUGIN_VERSION}.0") +endif() + +# The same thing as a comma-delimited quad. +string(REPLACE "." "," P3D_PLUGIN_DLL_COMMA_VERSION "${P3D_PLUGIN_DLL_DOT_VERSION}") diff --git a/dtool/dtool_config.h.in b/dtool/dtool_config.h.in new file mode 100644 index 0000000000..159488ab9d --- /dev/null +++ b/dtool/dtool_config.h.in @@ -0,0 +1,251 @@ +/* dtool_config.h. Generated automatically by CMake. */ +#ifndef DTOOL_CONFIG_H +#define DTOOL_CONFIG_H + +/* Define if we have Eigen available. */ +#cmakedefine HAVE_EIGEN +#cmakedefine LINMATH_ALIGN + +/* Define if we have Python installed. */ +#cmakedefine HAVE_PYTHON +#cmakedefine USE_DEBUG_PYTHON +/* Define if we have Python as a framework (Mac OS X). */ +#cmakedefine PYTHON_FRAMEWORK + +/* Define if we have OpenAL installed as a framework. */ +#cmakedefine HAVE_OPENAL_FRAMEWORK + +/* Define if we have Freetype 2.0 or better available. */ +#cmakedefine HAVE_FREETYPE + +/* Define if we want to compile in a default font. */ +#cmakedefine COMPILE_IN_DEFAULT_FONT + +/* Define to use doubles for most numbers, intead of single-precision floats. */ +#cmakedefine STDFLOAT_DOUBLE + +/* Define if we have built libRocket available and built with Python support. */ +#cmakedefine HAVE_ROCKET_PYTHON + +/* Define if we have ARToolKit available. */ +#cmakedefine HAVE_ARTOOLKIT + +/* Define if we have libvorbisfile available. */ +#cmakedefine HAVE_VORBIS + +/* Define if we have libopus available. */ +#cmakedefine HAVE_OPUS + +/* Define if we have OpenSSL installed. */ +#cmakedefine HAVE_OPENSSL + +/* Define if we have libjpeg installed. */ +#cmakedefine HAVE_JPEG + +/* Define to build video-for-linux. */ +#cmakedefine HAVE_VIDEO4LINUX + +/* Define if we have libpng installed. */ +#cmakedefine HAVE_PNG + +/* Define if we have libtiff installed. */ +#cmakedefine HAVE_TIFF + +/* Define if we have OpenEXR installed. */ +#cmakedefine HAVE_OPENEXR + +/* Define if we want to build these other image file formats. */ +#cmakedefine HAVE_SGI_RGB +#cmakedefine HAVE_TGA +#cmakedefine HAVE_IMG +#cmakedefine HAVE_SOFTIMAGE_PIC +#cmakedefine HAVE_BMP +#cmakedefine HAVE_PNM + +/* Define if we have CG installed. */ +#cmakedefine HAVE_CG + +/* Define if we have zlib installed. */ +#cmakedefine HAVE_ZLIB + +/* Define if we have OpenGL installed and want to build for GL. */ +#cmakedefine MIN_GL_VERSION_MAJOR +#cmakedefine MIN_GL_VERSION_MINOR + +/* Define if we have OpenCV installed and want to build for OpenCV. */ +#cmakedefine HAVE_OPENCV + +/* The choice of generic vs. the specific dxerr library largely + depends on which SDK you have installed. */ +#cmakedefine USE_GENERIC_DXERR_LIBRARY + +/* Define if we have the SDL library. */ +#cmakedefine HAVE_SDL + +/* Define if we have X11. */ +#cmakedefine HAVE_X11 + +/* Define if we want to compile the threading code. */ +#cmakedefine HAVE_THREADS + +/* Define if we want to use fast, user-space simulated threads. */ +#cmakedefine SIMPLE_THREADS + +/* Define to enable deadlock detection, mutex recursion checks, etc. */ +#cmakedefine DEBUG_THREADS + +/* Define to implement mutexes and condition variables via a user-space spinlock. */ +#cmakedefine MUTEX_SPINLOCK + +/* Define to enable the PandaFileStream implementation of pfstream etc. */ +#cmakedefine USE_PANDAFILESTREAM + +/* Define if we want to compile the net code. */ +#cmakedefine HAVE_NET + +/* Define if we want to compile the audio code. */ +#cmakedefine HAVE_AUDIO + +/* Define if we want to use PStats. */ +#cmakedefine DO_PSTATS + +/* Define if we want to type-check downcasts. */ +#cmakedefine DO_DCAST + +/* Define if we want to provide collision system recording and + visualization tools. */ +#cmakedefine DO_COLLISION_RECORDING + +/* Define if we want to enable track-memory-usage. */ +#cmakedefine DO_MEMORY_USAGE + +/* Define if we want to enable min-lag and max-lag. */ +#cmakedefine SIMULATE_NETWORK_DELAY + +/* Define if we want to allow immediate mode OpenGL rendering. */ +#cmakedefine SUPPORT_IMMEDIATE_MODE + +/* Define if we want to support fixed-function OpenGL rendering. */ +#cmakedefine SUPPORT_FIXED_FUNCTION + +/* Define for either of the alternative malloc schemes. */ +#cmakedefine USE_MEMORY_DLMALLOC +#cmakedefine USE_MEMORY_PTMALLOC2 + +/* Define if we want to compile in support for pipelining. */ +#cmakedefine DO_PIPELINING + +/* Define if we want to keep Notify debug messages around, or undefine + to compile them out. */ +#cmakedefine NOTIFY_DEBUG + +/* The compiled-in character(s) to expect to separate different + components of a path list (e.g. $PRC_PATH). */ +#define DEFAULT_PATHSEP "@DEFAULT_PATHSEP@" + +/* Many of the prc variables are exported by + dtool/src/prc/prc_parameters.h.pp, instead of here. Only those prc + variables that must be visible outside of the prc directory are + exported here. */ + +/* Define if you want to save the descriptions for ConfigVariables. */ +#cmakedefine PRC_SAVE_DESCRIPTIONS + + +/* Define if your processor stores words with the most significant + byte first (like Motorola and SPARC, unlike Intel and VAX). */ +#cmakedefine WORDS_BIGENDIAN + +/* Define if we can trust the compiler not to insert extra bytes in + structs between base structs and derived structs. */ +#cmakedefine SIMPLE_STRUCT_POINTERS + +/* Define if we have Dinkumware STL installed. */ +#cmakedefine HAVE_DINKUM + +/* Define if we have STL hash_map etc. available */ +#cmakedefine HAVE_STL_HASH + +/* Define if you have the getopt function. */ +#cmakedefine HAVE_GETOPT + +/* Define if you have the getopt_long_only function. */ +#cmakedefine HAVE_GETOPT_LONG_ONLY + +/* Define if getopt appears in getopt.h. */ +#cmakedefine PHAVE_GETOPT_H + +/* Do the system headers define key ios typedefs like ios::openmode + and ios::fmtflags? */ +#cmakedefine HAVE_IOS_TYPEDEFS + +/* Define if you have the header file. */ +#cmakedefine PHAVE_IO_H + +/* Define if you have the header file. */ +#cmakedefine PHAVE_IOSTREAM + +/* Define if you have the header file. */ +#cmakedefine PHAVE_MALLOC_H + +/* Define if you have the header file. */ +#cmakedefine PHAVE_SYS_MALLOC_H + +/* Define if you have the header file. */ +#cmakedefine PHAVE_ALLOCA_H + +/* Define if you have the header file. */ +#cmakedefine PHAVE_LOCALE_H + +/* Define if you have the header file. */ +#cmakedefine PHAVE_STRING_H + +/* Define if you have the header file. */ +#cmakedefine PHAVE_STDLIB_H + +/* Define if you have the header file. */ +#cmakedefine PHAVE_LIMITS_H + +/* Define if you have the header file. */ +#cmakedefine PHAVE_SSTREAM + +/* Define if you have the header file. */ +#cmakedefine PHAVE_NEW + +/* Define if you have the header file. */ +#cmakedefine PHAVE_SYS_TYPES_H + +/* Define if you have the header file. */ +#cmakedefine PHAVE_SYS_TIME_H + +/* Define if you have the header file. */ +#cmakedefine PHAVE_UNISTD_H + +/* Do we have ? This enables us to use raw mouse input. */ +#cmakedefine PHAVE_LINUX_INPUT_H + +/* Do we have ? */ +#cmakedefine PHAVE_STDINT_H + +/* Do we have Posix threads? */ +#cmakedefine HAVE_POSIX_THREADS + +/* Is the code being compiled with the Tau profiler's instrumentor? */ +#cmakedefine USE_TAU + +// To activate the DELETED_CHAIN macros. +#cmakedefine USE_DELETED_CHAIN + +// If we are to build the native net interfaces. +#cmakedefine WANT_NATIVE_NET + +/* Static linkage instead of the normal dynamic linkage? */ +#cmakedefine LINK_ALL_STATIC + +/* Platform-identifying defines. */ +#cmakedefine IS_OSX +#cmakedefine IS_LINUX +#cmakedefine IS_FREEBSD +#cmakedefine BUILD_IPHONE + +#endif diff --git a/dtool/metalibs/dtool/CMakeLists.txt b/dtool/metalibs/dtool/CMakeLists.txt new file mode 100644 index 0000000000..812c457b72 --- /dev/null +++ b/dtool/metalibs/dtool/CMakeLists.txt @@ -0,0 +1,13 @@ +set(CMAKE_INSTALL_DEFAULT_COMPONENT_NAME "CoreDevel") +add_metalib(p3dtool INIT init_libdtool dtool.h COMPONENTS p3dtoolutil p3dtoolbase) +unset(CMAKE_INSTALL_DEFAULT_COMPONENT_NAME) + +install(TARGETS p3dtool + EXPORT Core COMPONENT Core + DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d + ARCHIVE COMPONENT CoreDevel) + +# Also handle thirdparty DLLs +thirdparty_copy_alongside(p3dtool) diff --git a/dtool/src/cppparser/CMakeLists.txt b/dtool/src/cppparser/CMakeLists.txt new file mode 100644 index 0000000000..4408a52198 --- /dev/null +++ b/dtool/src/cppparser/CMakeLists.txt @@ -0,0 +1,44 @@ +set(P3CPPPARSER_HEADERS + cppArrayType.h cppBison.yxx cppBisonDefs.h + cppClassTemplateParameter.h cppCommentBlock.h + cppClosureType.h cppConstType.h + cppDeclaration.h cppEnumType.h cppExpression.h + cppExpressionParser.h cppExtensionType.h cppFile.h + cppFunctionGroup.h cppFunctionType.h cppGlobals.h + cppIdentifier.h cppInstance.h cppInstanceIdentifier.h + cppMakeProperty.h cppMakeSeq.h cppManifest.h + cppNameComponent.h cppNamespace.h + cppParameterList.h cppParser.h cppPointerType.h + cppPreprocessor.h cppReferenceType.h cppScope.h + cppSimpleType.h cppStructType.h cppTBDType.h + cppTemplateParameterList.h cppTemplateScope.h cppToken.h + cppType.h cppTypeDeclaration.h cppTypeParser.h + cppTypeProxy.h cppTypedefType.h cppUsing.h cppVisibility.h +) + +set(P3CPPPARSER_SOURCES + cppArrayType.cxx ${CMAKE_CURRENT_BINARY_DIR}/cppBison.cxx + cppClassTemplateParameter.cxx + cppCommentBlock.cxx cppClosureType.cxx cppConstType.cxx cppDeclaration.cxx + cppEnumType.cxx cppExpression.cxx cppExpressionParser.cxx + cppExtensionType.cxx cppFile.cxx cppFunctionGroup.cxx + cppFunctionType.cxx cppGlobals.cxx cppIdentifier.cxx + cppInstance.cxx cppInstanceIdentifier.cxx + cppMakeProperty.cxx cppMakeSeq.cxx cppManifest.cxx + cppNameComponent.cxx cppNamespace.cxx cppParameterList.cxx + cppParser.cxx cppPointerType.cxx cppPreprocessor.cxx + cppReferenceType.cxx cppScope.cxx cppSimpleType.cxx + cppStructType.cxx cppTBDType.cxx + cppTemplateParameterList.cxx cppTemplateScope.cxx + cppToken.cxx cppType.cxx cppTypeDeclaration.cxx + cppTypeParser.cxx cppTypeProxy.cxx cppTypedefType.cxx + cppUsing.cxx cppVisibility.cxx +) + +add_bison_target(cppBison.cxx cppBison.yxx DEFINES cppBison.h PREFIX cppyy) + +composite_sources(p3cppParser P3CPPPARSER_SOURCES) +add_library(p3cppParser STATIC ${P3CPPPARSER_HEADERS} ${P3CPPPARSER_SOURCES}) +target_link_libraries(p3cppParser p3dtool) + +install(TARGETS p3cppParser EXPORT Core COMPONENT CoreDevel DESTINATION ${CMAKE_INSTALL_LIBDIR}) diff --git a/dtool/src/dconfig/CMakeLists.txt b/dtool/src/dconfig/CMakeLists.txt new file mode 100644 index 0000000000..ccd9e6c144 --- /dev/null +++ b/dtool/src/dconfig/CMakeLists.txt @@ -0,0 +1,6 @@ +# Yes, INTERFACE: don't build it, there's no code! +# We're only doing this to put the .h file on the path. +add_library(p3dconfig INTERFACE) + +install(FILES dconfig.h COMPONENT CoreDevel DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d) +install(TARGETS p3dconfig EXPORT Core COMPONENT Core) diff --git a/dtool/src/dtoolbase/CMakeLists.txt b/dtool/src/dtoolbase/CMakeLists.txt new file mode 100644 index 0000000000..aea0a1196f --- /dev/null +++ b/dtool/src/dtoolbase/CMakeLists.txt @@ -0,0 +1,106 @@ +configure_file(pandaVersion.h.in pandaVersion.h) +configure_file(checkPandaVersion.h.in checkPandaVersion.h) +configure_file(checkPandaVersion.cxx.in checkPandaVersion.cxx) + +if(CMAKE_CXX_STANDARD GREATER 16) + # This serves as a reminder to update checkPandaVersion.h.in when we upgrade + # to C++17, which supports inline variables - a cleaner way of depending on + # the Panda version symbol from a header than what we're currently doing. + message(FATAL_ERROR "Developer notice: Update checkPandaVersion.h.in for C++17!") +endif() + +set(P3DTOOLBASE_HEADERS + ${CMAKE_CURRENT_BINARY_DIR}/checkPandaVersion.h + ${CMAKE_CURRENT_BINARY_DIR}/pandaVersion.h + addHash.I addHash.h + atomicAdjust.h + atomicAdjustDummyImpl.h atomicAdjustDummyImpl.I + atomicAdjustGccImpl.h atomicAdjustGccImpl.I + atomicAdjustI386Impl.h atomicAdjustI386Impl.I + atomicAdjustPosixImpl.h atomicAdjustPosixImpl.I + atomicAdjustWin32Impl.h atomicAdjustWin32Impl.I + cmath.I cmath.h + deletedBufferChain.h deletedBufferChain.I + deletedChain.h deletedChain.T + dtoolbase.h dtoolbase_cc.h dtoolsymbols.h + dtool_platform.h + fakestringstream.h + indent.I indent.h + memoryBase.h + memoryHook.h memoryHook.I + mutexImpl.h + mutexDummyImpl.h mutexDummyImpl.I + mutexPosixImpl.h mutexPosixImpl.I + mutexWin32Impl.h mutexWin32Impl.I + mutexSpinlockImpl.h mutexSpinlockImpl.I + nearly_zero.h + neverFreeMemory.h neverFreeMemory.I + numeric_types.h + pdtoa.h + pstrtod.h + register_type.I register_type.h + selectThreadImpl.h + stl_compares.I stl_compares.h + typeHandle.I typeHandle.h + typeRegistry.I typeRegistry.h + typeRegistryNode.I typeRegistryNode.h + typedObject.I typedObject.h + pallocator.T pallocator.h + pdeque.h plist.h pmap.h pset.h + pvector.h epvector.h + lookup3.h + version.h +) + +set(P3DTOOLBASE_SOURCES + ${CMAKE_CURRENT_BINARY_DIR}/checkPandaVersion.cxx + addHash.cxx + atomicAdjustDummyImpl.cxx + atomicAdjustI386Impl.cxx + atomicAdjustPosixImpl.cxx + atomicAdjustWin32Impl.cxx + deletedBufferChain.cxx + dtoolbase.cxx + indent.cxx + lookup3.c + memoryBase.cxx + memoryHook.cxx + mutexDummyImpl.cxx + mutexPosixImpl.cxx + mutexWin32Impl.cxx + mutexSpinlockImpl.cxx + neverFreeMemory.cxx + pdtoa.cxx + pstrtod.cxx + register_type.cxx + typeHandle.cxx + typeRegistry.cxx typeRegistryNode.cxx + typedObject.cxx +) + +set(P3DTOOLBASE_IGATEEXT + typeHandle_ext.cxx + typeHandle_ext.h +) + +set_source_files_properties(indent.cxx PROPERTIES SKIP_UNITY_BUILD_INCLUSION YES) + +composite_sources(p3dtoolbase P3DTOOLBASE_SOURCES) +add_component_library(p3dtoolbase NOINIT SYMBOL BUILDING_DTOOL_DTOOLBASE + ${P3DTOOLBASE_HEADERS} ${P3DTOOLBASE_SOURCES}) +# Help other libraries find the autogenerated headers +target_include_directories(p3dtoolbase PUBLIC + $ + $) +target_link_libraries(p3dtoolbase PKG::EIGEN PKG::THREADS) +target_interrogate(p3dtoolbase ${P3DTOOLBASE_SOURCES} EXTENSIONS ${P3DTOOLBASE_IGATEEXT}) + +if(NOT BUILD_METALIBS) + install(TARGETS p3dtoolbase + EXPORT Core COMPONENT Core + DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d + ARCHIVE COMPONENT CoreDevel) +endif() +install(FILES ${P3DTOOLBASE_HEADERS} COMPONENT CoreDevel DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d) diff --git a/dtool/src/dtoolbase/atomicAdjustWin32Impl.cxx b/dtool/src/dtoolbase/atomicAdjustWin32Impl.cxx index 8128a8d2dd..19abfd3583 100644 --- a/dtool/src/dtoolbase/atomicAdjustWin32Impl.cxx +++ b/dtool/src/dtoolbase/atomicAdjustWin32Impl.cxx @@ -13,8 +13,8 @@ #include "selectThreadImpl.h" -#ifdef WIN32_VC +#ifdef _WIN32 #include "atomicAdjustWin32Impl.h" -#endif // WIN32_VC +#endif // _WIN32 diff --git a/dtool/src/dtoolbase/atomicAdjustWin32Impl.h b/dtool/src/dtoolbase/atomicAdjustWin32Impl.h index 25f2e78066..f83ee0150b 100644 --- a/dtool/src/dtoolbase/atomicAdjustWin32Impl.h +++ b/dtool/src/dtoolbase/atomicAdjustWin32Impl.h @@ -17,7 +17,7 @@ #include "dtoolbase.h" #include "selectThreadImpl.h" -#ifdef WIN32_VC +#ifdef _WIN32 #include "numeric_types.h" @@ -62,6 +62,6 @@ public: #include "atomicAdjustWin32Impl.I" -#endif // WIN32_VC +#endif // _WIN32 #endif diff --git a/dtool/src/dtoolbase/checkPandaVersion.cxx.in b/dtool/src/dtoolbase/checkPandaVersion.cxx.in new file mode 100644 index 0000000000..e62f0184c8 --- /dev/null +++ b/dtool/src/dtoolbase/checkPandaVersion.cxx.in @@ -0,0 +1,21 @@ +/* Filename: checkPandaVersion.cxx + * Created by: drose (26Jan05) + * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * + * PANDA 3D SOFTWARE + * Copyright (c) Carnegie Mellon University. All rights reserved. + * + * All use of this software is subject to the terms of the revised BSD + * license. You should have received a copy of this license along + * with this source code in a file named "LICENSE." + * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/******************************************************************* + * Generated automatically by CMake. + ***************************** DO NOT EDIT *************************/ + +#include "dtoolbase.h" + +EXPCL_DTOOL_DTOOLBASE int @PANDA_VERSION_SYMBOL@ = 0; diff --git a/dtool/src/dtoolbase/checkPandaVersion.h.in b/dtool/src/dtoolbase/checkPandaVersion.h.in new file mode 100644 index 0000000000..6f4b7ae403 --- /dev/null +++ b/dtool/src/dtoolbase/checkPandaVersion.h.in @@ -0,0 +1,64 @@ +/* Filename: checkPandaVersion.h + * Created by: drose (26Jan05) + * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * + * PANDA 3D SOFTWARE + * Copyright (c) Carnegie Mellon University. All rights reserved. + * + * All use of this software is subject to the terms of the revised BSD + * license. You should have received a copy of this license along + * with this source code in a file named "LICENSE." + * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/******************************************************************* + * Generated automatically by CMake. + ***************************** DO NOT EDIT *************************/ + +/* Include this file in code that compiles with Panda to guarantee + that it is linking with the same version of the Panda DLL's that it + was compiled with. */ + +/* We guarantee this by defining an external symbol which is based on + the version number. If that symbol is defined, then our DLL's + (probably) match. Otherwise, we must be running with the wrong + DLL; but the system linker will prevent the DLL from loading with + an undefined symbol. */ + +#ifndef CHECKPANDAVERSION_H +#define CHECKPANDAVERSION_H + +#include "dtoolbase.h" + +extern EXPCL_DTOOL_DTOOLBASE int @PANDA_VERSION_SYMBOL@; + +/* Just declaring the symbol isn't good enough. We need to force the + compiler and linker to preserve the external reference long enough + to end up in the output DLL. Therefore, we have to reference that + symbol somehow. + + Forcing the compiler to include a reference in its output object + file is easy enough: just define a function that makes use of it + in some way. The problem is the linker, which will enforce the + C++ One-Definition Rule and get upset about said definition + appearing in multiple places in the program. We can appease the + linker by forcing the compiler to emit a weak symbol. Many + compilers have syntax to request this explicitly, but since it + varies from compiler to compiler, that wouldn't be very portable. + + Fortunately, the C++ ODR itself has some exceptions, where a + definition can occur in multiple translation units *if and only if* + it's the same definition each time. In these cases, the compiler + must emit a weak symbol, because the ODR does not guarantee that + the same definition isn't repeated in any other translation units. + One such exception is template instantiation, which we use thus: */ +template +class CheckPandaVersion { +public: + int check_version() { return @PANDA_VERSION_SYMBOL@; } +}; + +template class CheckPandaVersion; + +#endif diff --git a/dtool/src/dtoolbase/dtoolbase.cxx b/dtool/src/dtoolbase/dtoolbase.cxx index 3bd34815c9..0b7c874db2 100644 --- a/dtool/src/dtoolbase/dtoolbase.cxx +++ b/dtool/src/dtoolbase/dtoolbase.cxx @@ -18,7 +18,7 @@ #error Buildsystem error: BUILDING_DTOOL_DTOOLBASE not defined #endif -#if defined(USE_TAU) && defined(WIN32) +#if defined(USE_TAU) && defined(_WIN32) // Hack around tau's lack of DLL export declarations for Profiler class. bool __tau_shutdown = false; #endif diff --git a/dtool/src/dtoolbase/dtoolbase.h b/dtool/src/dtoolbase/dtoolbase.h index 2207915f28..67dee423da 100644 --- a/dtool/src/dtoolbase/dtoolbase.h +++ b/dtool/src/dtoolbase/dtoolbase.h @@ -21,19 +21,7 @@ #include "dtool_config.h" -/* Make sure WIN32 and WIN32_VC are defined when using MSVC */ -#if defined(_WIN32) || defined(_WIN64) -#ifndef WIN32 -#define WIN32 -#endif #ifdef _MSC_VER -#ifndef WIN32_VC -#define WIN32_VC -#endif -#endif -#endif - -#ifdef WIN32_VC /* These warning pragmas must appear before anything else for VC++ to respect them. Sheesh. */ @@ -58,11 +46,11 @@ #pragma warning (disable : 4267) /* C4577: 'noexcept' used with no exception handling mode specified */ #pragma warning (disable : 4577) -#endif /* WIN32_VC */ +#endif /* _MSC_VER */ /* Windows likes to define min() and max() macros, which will conflict with std::min() and std::max() respectively, unless we do this: */ -#ifdef WIN32 +#ifdef _WIN32 #ifndef NOMINMAX #define NOMINMAX #endif @@ -485,7 +473,7 @@ typedef struct _object PyObject; #endif /* These symbols are used in dtoolsymbols.h and pandasymbols.h. */ -#if defined(WIN32_VC) && !defined(CPPPARSER) && !defined(LINK_ALL_STATIC) +#if defined(_WIN32) && !defined(CPPPARSER) && !defined(LINK_ALL_STATIC) #define EXPORT_CLASS __declspec(dllexport) #define IMPORT_CLASS __declspec(dllimport) #elif __GNUC__ >= 4 && !defined(CPPPARSER) && !defined(LINK_ALL_STATIC) diff --git a/dtool/src/dtoolbase/dtoolbase_cc.h b/dtool/src/dtoolbase/dtoolbase_cc.h index 8894469422..674462f6ac 100644 --- a/dtool/src/dtoolbase/dtoolbase_cc.h +++ b/dtool/src/dtoolbase/dtoolbase_cc.h @@ -251,7 +251,7 @@ INLINE void thread_consider_yield() { #endif // HAVE_THREADS && SIMPLE_THREADS -#if defined(USE_TAU) && defined(WIN32) +#if defined(USE_TAU) && defined(_WIN32) // Hack around tau's lack of DLL export declarations for Profiler class. extern EXPCL_DTOOL_DTOOLBASE bool __tau_shutdown; class EXPCL_DTOOL_DTOOLBASE TauProfile { diff --git a/dtool/src/dtoolbase/memoryHook.cxx b/dtool/src/dtoolbase/memoryHook.cxx index 24d5f11a11..4abc0661d8 100644 --- a/dtool/src/dtoolbase/memoryHook.cxx +++ b/dtool/src/dtoolbase/memoryHook.cxx @@ -16,7 +16,7 @@ #include #include "typeRegistry.h" -#ifdef WIN32 +#ifdef _WIN32 // Windows case. #ifndef WIN32_LEAN_AND_MEAN @@ -191,7 +191,7 @@ ptr_to_alloc(void *ptr, size_t &size) { */ MemoryHook:: MemoryHook() { -#ifdef WIN32 +#ifdef _WIN32 // Windows case. SYSTEM_INFO sysinfo; @@ -487,7 +487,7 @@ heap_trim(size_t pad) { _lock.unlock(); #endif -#ifdef WIN32 +#ifdef _WIN32 // Also, on Windows we have _heapmin(). if (_heapmin() == 0) { trimmed = true; @@ -516,7 +516,7 @@ mmap_alloc(size_t size, bool allow_exec) { _total_mmap_size += size; #endif -#ifdef WIN32 +#ifdef _WIN32 // Windows case. void *ptr = VirtualAlloc(nullptr, size, MEM_COMMIT | MEM_RESERVE, @@ -571,7 +571,7 @@ mmap_free(void *ptr, size_t size) { _total_mmap_size -= size; #endif -#ifdef WIN32 +#ifdef _WIN32 VirtualFree(ptr, 0, MEM_RELEASE); #else munmap(ptr, size); diff --git a/dtool/src/dtoolbase/mutexImpl.h b/dtool/src/dtoolbase/mutexImpl.h index add705bc39..cebd4e0de7 100644 --- a/dtool/src/dtoolbase/mutexImpl.h +++ b/dtool/src/dtoolbase/mutexImpl.h @@ -49,7 +49,7 @@ typedef ReMutexPosixImpl ReMutexImpl; // Also define what a true OS-provided lock will be, even if we don't have // threading enabled in the build. Sometimes we need to interface with an // external program or something that wants real locks. -#if defined(WIN32_VC) +#if defined(_WIN32) #include "mutexWin32Impl.h" typedef MutexWin32Impl TrueMutexImpl; diff --git a/dtool/src/dtoolbase/mutexWin32Impl.cxx b/dtool/src/dtoolbase/mutexWin32Impl.cxx index 4488c637ae..04d3ac0ec9 100644 --- a/dtool/src/dtoolbase/mutexWin32Impl.cxx +++ b/dtool/src/dtoolbase/mutexWin32Impl.cxx @@ -13,7 +13,7 @@ #include "selectThreadImpl.h" -#ifdef WIN32_VC +#if defined(_WIN32) && !defined(CPPPARSER) #include "mutexWin32Impl.h" @@ -28,4 +28,4 @@ ReMutexWin32Impl() { InitializeCriticalSectionAndSpinCount(&_lock, spin_count); } -#endif // WIN32_VC +#endif // _WIN32 diff --git a/dtool/src/dtoolbase/mutexWin32Impl.h b/dtool/src/dtoolbase/mutexWin32Impl.h index 0df0808459..debee81113 100644 --- a/dtool/src/dtoolbase/mutexWin32Impl.h +++ b/dtool/src/dtoolbase/mutexWin32Impl.h @@ -17,7 +17,7 @@ #include "dtoolbase.h" #include "selectThreadImpl.h" -#ifdef WIN32_VC +#ifdef _WIN32 #ifndef WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN 1 #endif @@ -68,6 +68,6 @@ private: #include "mutexWin32Impl.I" -#endif // WIN32_VC +#endif // _WIN32 #endif diff --git a/dtool/src/dtoolbase/pandaVersion.h.in b/dtool/src/dtoolbase/pandaVersion.h.in new file mode 100644 index 0000000000..ecaed20cd7 --- /dev/null +++ b/dtool/src/dtoolbase/pandaVersion.h.in @@ -0,0 +1,73 @@ +/* Filename: pandaVersion.h + * Created by: drose (26Jan05) + * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * + * PANDA 3D SOFTWARE + * Copyright (c) Carnegie Mellon University. All rights reserved. + * + * All use of this software is subject to the terms of the revised BSD + * license. You should have received a copy of this license along + * with this source code in a file named "LICENSE." + * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/******************************************************************* + * Generated automatically by CMake. + ***************************** DO NOT EDIT ************************* + + Do NOT attempt to edit the version number in this file. This is a + generated file, and your changes to this file will not persist. To + increment the version number, modify dtool/PandaVersion.cmake and + re-run ppremake. + + ***************************** DO NOT EDIT *************************/ + +/* Include this file anywhere you need to determine the Panda version + number at compile time. If you need the runtime Panda version, use + pandaSystem.h instead. */ + +/* Try to avoid including this file from another .h file; include it + only from .cxx instead. This helps prevent unnecessarily long + rebuilds just because the version number changes; if this file is + included in a .h file, then any other files which also include that + .h file will need to be rebuilt when the version number changes. */ + +#define PANDA_MAJOR_VERSION @PROJECT_VERSION_MAJOR@ +#define PANDA_MINOR_VERSION @PROJECT_VERSION_MINOR@ +#define PANDA_SEQUENCE_VERSION @PROJECT_VERSION_PATCH@ + +/* Define if this is an "official" version, undefine otherwise. */ +#cmakedefine PANDA_OFFICIAL_VERSION + +/* This is the panda numeric version as a single number, with three + digits reserved for each component. */ +#define PANDA_NUMERIC_VERSION @PANDA_NUMERIC_VERSION@ + +/* This is the panda version expressed as a string. It ends in the + letter "c" if this is not an "official" version (e.g. it was checked + out from CVS by the builder). */ +#define PANDA_VERSION_STR "@PANDA_VERSION_STR@" + +/* This is the Git commit we built Panda from, or an empty string if this isn't + known. */ +#define PANDA_GIT_COMMIT_STR "@PANDA_GIT_COMMIT_STR@" + +/* This is the version of the Panda3D ABI expressed as a string. + This usually means the major and minor version. It should be the + same for Panda3D versions that are supposed to be backward + ABI compatible with each other. */ +#define PANDA_ABI_VERSION_STR "@PROJECT_VERSION_MAJOR@.@PROJECT_VERSION_MINOR@" + +/* This is a string indicating who has provided this distribution. */ +#define PANDA_DISTRIBUTOR "@PANDA_DISTRIBUTOR@" + +/* The string indicating the version number of the associated Panda3D + distributable package, or empty string if there is no associated + package. */ +#define PANDA_PACKAGE_VERSION_STR "@PANDA_PACKAGE_VERSION@" + +/* The string indicating the URL from which the associated Panda3D + distributable package may be downloaded, or empty string if there + is no associated package. */ +#define PANDA_PACKAGE_HOST_URL "@PANDA_PACKAGE_HOST_URL@" diff --git a/dtool/src/dtoolbase/selectThreadImpl.h b/dtool/src/dtoolbase/selectThreadImpl.h index 743ea98af7..4ef55dc6f3 100644 --- a/dtool/src/dtoolbase/selectThreadImpl.h +++ b/dtool/src/dtoolbase/selectThreadImpl.h @@ -47,7 +47,7 @@ #undef TVOLATILE #define TVOLATILE -#elif defined(WIN32_VC) +#elif defined(_WIN32) // In Windows, use the native threading library. #define THREAD_WIN32_IMPL 1 diff --git a/dtool/src/dtoolutil/CMakeLists.txt b/dtool/src/dtoolutil/CMakeLists.txt new file mode 100644 index 0000000000..c3a43c319b --- /dev/null +++ b/dtool/src/dtoolutil/CMakeLists.txt @@ -0,0 +1,153 @@ +set(P3DTOOLUTIL_HEADERS + config_dtoolutil.h + dSearchPath.I dSearchPath.h + executionEnvironment.I executionEnvironment.h filename.I + filename.h + globPattern.I globPattern.h + lineStream.I lineStream.h + lineStreamBuf.I lineStreamBuf.h + load_dso.h + pandaFileStream.h pandaFileStream.I + pandaFileStreamBuf.h + pandaSystem.h + panda_getopt.h panda_getopt_long.h panda_getopt_impl.h + pfstream.h pfstream.I pfstreamBuf.h + preprocess_argv.h + string_utils.h string_utils.I + stringDecoder.h stringDecoder.I + textEncoder.h textEncoder.I + unicodeLatinMap.h + vector_double.h + vector_float.h + vector_int.h + vector_stdfloat.h + vector_string.h + vector_uchar.h + vector_src.h + win32ArgParser.h +) + +if(APPLE) + set(P3DTOOLUTIL_HEADERS ${P3DTOOLUTIL_HEADERS} + filename_assist.mm filename_assist.h) + + set_source_files_properties( + filename_assist.mm filename_assist.h PROPERTIES + WRAP_EXCLUDE YES + SKIP_UNITY_BUILD_INCLUSION YES) +endif() + +set(P3DTOOLUTIL_SOURCES + config_dtoolutil.cxx + dSearchPath.cxx + executionEnvironment.cxx filename.cxx + globPattern.cxx + lineStream.cxx lineStreamBuf.cxx + load_dso.cxx + pandaFileStream.cxx pandaFileStreamBuf.cxx + pandaSystem.cxx + panda_getopt_impl.cxx + pfstreamBuf.cxx pfstream.cxx + preprocess_argv.cxx + string_utils.cxx + stringDecoder.cxx + textEncoder.cxx + unicodeLatinMap.cxx + vector_double.cxx + vector_float.cxx + vector_int.cxx + vector_string.cxx + vector_uchar.cxx + win32ArgParser.cxx +) + +set(P3DTOOLUTIL_IGATEEXT + filename_ext.cxx + filename_ext.h + globPattern_ext.cxx + globPattern_ext.h + iostream_ext.cxx + iostream_ext.h + textEncoder_ext.cxx + textEncoder_ext.h +) + +composite_sources(p3dtoolutil P3DTOOLUTIL_SOURCES) +add_component_library(p3dtoolutil SYMBOL BUILDING_DTOOL_DTOOLUTIL + ${P3DTOOLUTIL_HEADERS} ${P3DTOOLUTIL_SOURCES}) +target_link_libraries(p3dtoolutil p3dtoolbase ${CMAKE_DL_LIBS}) +target_interrogate(p3dtoolutil ALL EXTENSIONS ${P3DTOOLUTIL_IGATEEXT}) + +if(APPLE) + find_library(FOUNDATION_LIBRARY Foundation) + find_library(APPKIT_LIBRARY AppKit) + target_link_libraries(p3dtoolutil ${FOUNDATION_LIBRARY} ${APPKIT_LIBRARY}) +endif() + +# These are all used by executionEnvironment.cxx/filename.cxx +foreach(var + # executionEnvironment.cxx: + HAVE_GLOBAL_ARGV + PROTOTYPE_GLOBAL_ARGV + GLOBAL_ARGV + GLOBAL_ARGC + + HAVE_PROC_CURPROC_CMDLINE + HAVE_PROC_CURPROC_FILE + HAVE_PROC_CURPROC_MAP + HAVE_PROC_SELF_CMDLINE + HAVE_PROC_SELF_ENVIRON + HAVE_PROC_SELF_EXE + HAVE_PROC_SELF_MAPS + + STATIC_INIT_GETENV + + # filename.cxx: + HAVE_IOS_BINARY + PHAVE_DIRENT_H + PHAVE_GLOB_H + PHAVE_LOCKF + PHAVE_UTIME_H +) + + if(${var}) + target_compile_definitions(p3dtoolutil PRIVATE "${var}=${${var}}") + endif() + +endforeach(var) + +if(BUILD_SHARED_LIBS) + # executionEnvironment.cxx needs to know the name(s) of the library file it + # will be linked into + if(BUILD_METALIBS) + set(library "p3dtool") + else() + set(library "p3dtoolutil") + endif() + + set(filenames) + foreach(prop TARGET_FILE_NAME TARGET_SONAME_FILE_NAME TARGET_LINKER_FILE_NAME) + list(APPEND filenames "$<${prop}:${library}>") + + if(CMAKE_IMPORT_LIBRARY_SUFFIX) + # Only the first property is valid/relevant on DLL platforms; bail out + # now and skip the others. + # (Yes, CMAKE_IMPORT_LIBRARY_SUFFIX being non-empty is how CMake defines + # a DLL platform where TARGET_SONAME_FILE_NAME is invalid.) + break() + endif() + endforeach(prop) + + target_compile_definitions(p3dtoolutil + PRIVATE "LIBP3DTOOL_FILENAMES=\"$\">\"") +endif() + +if(NOT BUILD_METALIBS) + install(TARGETS p3dtoolutil + EXPORT Core COMPONENT Core + DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d + ARCHIVE COMPONENT CoreDevel) +endif() +install(FILES ${P3DTOOLUTIL_HEADERS} COMPONENT CoreDevel DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d) diff --git a/dtool/src/dtoolutil/executionEnvironment.cxx b/dtool/src/dtoolutil/executionEnvironment.cxx index 4a10c9d168..5f40578f3d 100644 --- a/dtool/src/dtoolutil/executionEnvironment.cxx +++ b/dtool/src/dtoolutil/executionEnvironment.cxx @@ -101,7 +101,7 @@ static const char *const libp3dtool_filenames[] = { // libp3dtool dynamic library - no guesswork needed. LIBP3DTOOL_FILENAMES -#elif defined(WIN32_VC) +#elif defined(_WIN32) #ifdef _DEBUG "libp3dtool_d.dll", @@ -223,7 +223,7 @@ get_cwd() { Filename cwd = Filename::from_os_specific_w(buffer); cwd.make_true_case(); return cwd; -#else // WIN32_VC +#else // _WIN32 // getcwd() requires us to allocate a dynamic buffer and grow it on demand. static size_t bufsize = 1024; static char *buffer = nullptr; @@ -246,7 +246,7 @@ get_cwd() { Filename cwd = Filename::from_os_specific(buffer); cwd.make_true_case(); return cwd; -#endif // WIN32_VC +#endif // _WIN32 } /** @@ -585,7 +585,7 @@ read_args() { // the p3dtool library. #ifndef LINK_ALL_STATIC -#if defined(WIN32_VC) +#if defined(_WIN32) for (const char *filename : libp3dtool_filenames) { if (!_dtool_name.empty()) break; @@ -704,7 +704,7 @@ read_args() { // Now, we need to fill in _binary_name. This contains the full path to the // currently running executable. -#ifdef WIN32_VC +#ifdef _WIN32 if (_binary_name.empty()) { static const DWORD buffer_size = 1024; wchar_t buffer[buffer_size]; @@ -766,7 +766,7 @@ read_args() { // Next we need to fill in _args, which is a vector containing the command- // line arguments that the executable was invoked with. -#if defined(WIN32_VC) +#if defined(_WIN32) // We cannot rely on __argv when Python is linked in Unicode mode. Instead, // let's use GetCommandLine. diff --git a/dtool/src/dtoolutil/filename.cxx b/dtool/src/dtoolutil/filename.cxx index ba1db02198..e59aeb448e 100644 --- a/dtool/src/dtoolutil/filename.cxx +++ b/dtool/src/dtoolutil/filename.cxx @@ -70,15 +70,13 @@ TypeHandle Filename::_type_handle; string Filename::_internal_data_dir; #endif -#ifdef WIN32 +#ifdef _WIN32 /* begin Win32-specific code */ -#ifdef WIN32_VC #include #include #include #include -#endif // The MSVC 6.0 Win32 SDK lacks the following definitions, so we define them // here for compatibility. @@ -289,7 +287,7 @@ convert_executable_pathname(const string &unix_style_pathname) { return convert_pathname(unix_style_pathname); } -#endif //WIN32 +#endif // _WIN32 /** * This constructor composes the filename out of a directory part and a @@ -326,7 +324,7 @@ Filename(const Filename &dirname, const Filename &basename) { */ Filename Filename:: from_os_specific(const string &os_specific, Filename::Type type) { -#ifdef WIN32 +#ifdef _WIN32 string result = back_to_front_slash(os_specific); const string &panda_root = get_panda_root(); @@ -378,12 +376,12 @@ from_os_specific(const string &os_specific, Filename::Type type) { Filename filename(result); filename.set_type(type); return filename; -#else // WIN32 +#else // _WIN32 // Generic Unix-style filenames--no conversion necessary. Filename filename(os_specific); filename.set_type(type); return filename; -#endif // WIN32 +#endif // _WIN32 } /** @@ -487,7 +485,7 @@ get_home_directory() { } if (home_directory.empty()) { -#ifdef WIN32 +#ifdef _WIN32 wchar_t buffer[MAX_PATH]; // On Windows, fall back to the "My Documents" folder. @@ -513,7 +511,7 @@ get_home_directory() { #else // Posix case: check etcpasswd? -#endif // WIN32 +#endif // _WIN32 } if (home_directory.empty()) { @@ -540,7 +538,7 @@ get_temp_directory() { if (AtomicAdjust::get_ptr(_temp_directory) == nullptr) { Filename temp_directory; -#ifdef WIN32 +#ifdef _WIN32 static const size_t buffer_size = 4096; wchar_t buffer[buffer_size]; if (GetTempPathW(buffer_size, buffer) != 0) { @@ -562,7 +560,7 @@ get_temp_directory() { #else // Posix case. temp_directory = "/tmp"; -#endif // WIN32 +#endif // _WIN32 if (temp_directory.empty()) { // Fallback case. @@ -590,7 +588,7 @@ get_user_appdata_directory() { if (AtomicAdjust::get_ptr(_user_appdata_directory) == nullptr) { Filename user_appdata_directory; -#ifdef WIN32 +#ifdef _WIN32 wchar_t buffer[MAX_PATH]; if (SHGetSpecialFolderPathW(nullptr, buffer, CSIDL_LOCAL_APPDATA, true)) { @@ -619,7 +617,7 @@ get_user_appdata_directory() { user_appdata_directory = Filename(get_home_directory(), ".local/share"); } -#endif // WIN32 +#endif // _WIN32 if (user_appdata_directory.empty()) { // Fallback case. @@ -646,7 +644,7 @@ get_common_appdata_directory() { if (AtomicAdjust::get_ptr(_common_appdata_directory) == nullptr) { Filename common_appdata_directory; -#ifdef WIN32 +#ifdef _WIN32 wchar_t buffer[MAX_PATH]; if (SHGetSpecialFolderPathW(nullptr, buffer, CSIDL_COMMON_APPDATA, true)) { @@ -669,7 +667,7 @@ get_common_appdata_directory() { common_appdata_directory = "/usr/local/share"; #else common_appdata_directory = "/usr/share"; -#endif // WIN32 +#endif // _WIN32 if (common_appdata_directory.empty()) { // Fallback case. @@ -1019,7 +1017,7 @@ make_canonical() { return true; } -#ifndef WIN32 +#ifndef _WIN32 // Use realpath in order to resolve symlinks properly char newpath [PATH_MAX + 1]; if (realpath(c_str(), newpath) != nullptr) { @@ -1057,7 +1055,7 @@ make_true_case() { return true; } -#ifdef WIN32 +#ifdef _WIN32 wstring os_specific = to_os_specific_w(); // First, we have to convert it to its short name, then back to its long @@ -1105,9 +1103,9 @@ make_true_case() { (*this) = true_case; return true; -#else // WIN32 +#else // _WIN32 return true; -#endif // WIN32 +#endif // _WIN32 } /** @@ -1142,7 +1140,7 @@ to_os_specific() const { } #endif -#ifdef WIN32 +#ifdef _WIN32 switch (get_type()) { case T_dso: return convert_dso_pathname(standard.get_fullpath()); @@ -1151,9 +1149,9 @@ to_os_specific() const { default: return convert_pathname(standard.get_fullpath()); } -#else // WIN32 +#else // _WIN32 return standard.c_str(); -#endif // WIN32 +#endif // _WIN32 } /** @@ -1182,11 +1180,11 @@ string Filename:: to_os_generic() const { assert(!get_pattern()); -#ifdef WIN32 +#ifdef _WIN32 return back_to_front_slash(to_os_specific()); -#else // WIN32 +#else // _WIN32 return to_os_specific(); -#endif // WIN32 +#endif // _WIN32 } /** @@ -1202,7 +1200,7 @@ string Filename:: to_os_short_name() const { assert(!get_pattern()); -#ifdef WIN32 +#ifdef _WIN32 wstring os_specific = to_os_specific_w(); wchar_t short_name[MAX_PATH + 1]; @@ -1222,9 +1220,9 @@ to_os_short_name() const { encoder.set_wtext(short_name); return encoder.get_text(); -#else // WIN32 +#else // _WIN32 return to_os_specific(); -#endif // WIN32 +#endif // _WIN32 } /** @@ -1236,7 +1234,7 @@ string Filename:: to_os_long_name() const { assert(!get_pattern()); -#ifdef WIN32 +#ifdef _WIN32 wstring os_specific = to_os_specific_w(); wchar_t long_name[MAX_PATH + 1]; @@ -1253,9 +1251,9 @@ to_os_long_name() const { encoder.set_wtext(long_name); return encoder.get_text(); -#else // WIN32 +#else // _WIN32 return to_os_specific(); -#endif // WIN32 +#endif // _WIN32 } /** @@ -1265,7 +1263,7 @@ to_os_long_name() const { */ bool Filename:: exists() const { -#ifdef WIN32_VC +#ifdef _WIN32 wstring os_specific = get_filename_index(0).to_os_specific_w(); bool exists = false; @@ -1275,7 +1273,7 @@ exists() const { exists = true; } -#else // WIN32_VC +#else // _WIN32 string os_specific = get_filename_index(0).to_os_specific(); struct stat this_buf; @@ -1295,7 +1293,7 @@ exists() const { */ bool Filename:: is_regular_file() const { -#ifdef WIN32_VC +#ifdef _WIN32 wstring os_specific = get_filename_index(0).to_os_specific_w(); bool isreg = false; @@ -1305,7 +1303,7 @@ is_regular_file() const { isreg = ((results & (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_DEVICE)) == 0); } -#else // WIN32_VC +#else // _WIN32 string os_specific = get_filename_index(0).to_os_specific(); struct stat this_buf; @@ -1327,7 +1325,7 @@ bool Filename:: is_writable() const { bool writable = false; -#ifdef WIN32_VC +#ifdef _WIN32 wstring os_specific = get_filename_index(0).to_os_specific_w(); DWORD results = GetFileAttributesW(os_specific.c_str()); @@ -1340,7 +1338,7 @@ is_writable() const { writable = true; } } -#else // WIN32_VC +#else // _WIN32 string os_specific = get_filename_index(0).to_os_specific(); if (access(os_specific.c_str(), W_OK) == 0) { @@ -1357,7 +1355,7 @@ is_writable() const { */ bool Filename:: is_directory() const { -#ifdef WIN32_VC +#ifdef _WIN32 wstring os_specific = get_filename_index(0).to_os_specific_w(); bool isdir = false; @@ -1366,7 +1364,7 @@ is_directory() const { if (results != -1) { isdir = (results & FILE_ATTRIBUTE_DIRECTORY) != 0; } -#else // WIN32_VC +#else // _WIN32 string os_specific = get_filename_index(0).to_os_specific(); struct stat this_buf; @@ -1385,7 +1383,7 @@ is_directory() const { */ bool Filename:: is_executable() const { -#ifdef WIN32_VC +#ifdef _WIN32 // no access() in windows, but to our advantage executables can only end in // .exe or .com string extension = get_extension(); @@ -1393,12 +1391,12 @@ is_executable() const { return exists(); } -#else /* WIN32_VC */ +#else // _WIN32 string os_specific = get_filename_index(0).to_os_specific(); if (access(os_specific.c_str(), X_OK) == 0) { return true; } -#endif /* WIN32_VC */ +#endif // _WIN32 return false; } @@ -1417,7 +1415,7 @@ int Filename:: compare_timestamps(const Filename &other, bool this_missing_is_old, bool other_missing_is_old) const { -#ifdef WIN32_VC +#ifdef _WIN32 wstring os_specific = get_filename_index(0).to_os_specific_w(); wstring other_os_specific = other.get_filename_index(0).to_os_specific_w(); @@ -1434,7 +1432,7 @@ compare_timestamps(const Filename &other, if (_wstat(other_os_specific.c_str(), &other_buf) == 0) { other_exists = true; } -#else // WIN32_VC +#else // _WIN32 string os_specific = get_filename_index(0).to_os_specific(); string other_os_specific = other.get_filename_index(0).to_os_specific(); @@ -1495,7 +1493,7 @@ compare_timestamps(const Filename &other, */ time_t Filename:: get_timestamp() const { -#ifdef WIN32_VC +#ifdef _WIN32 wstring os_specific = get_filename_index(0).to_os_specific_w(); struct _stat this_buf; @@ -1503,7 +1501,7 @@ get_timestamp() const { if (_wstat(os_specific.c_str(), &this_buf) == 0) { return this_buf.st_mtime; } -#else // WIN32_VC +#else // _WIN32 string os_specific = get_filename_index(0).to_os_specific(); struct stat this_buf; @@ -1523,7 +1521,7 @@ get_timestamp() const { */ time_t Filename:: get_access_timestamp() const { -#ifdef WIN32_VC +#ifdef _WIN32 wstring os_specific = get_filename_index(0).to_os_specific_w(); struct _stat this_buf; @@ -1531,7 +1529,7 @@ get_access_timestamp() const { if (_wstat(os_specific.c_str(), &this_buf) == 0) { return this_buf.st_atime; } -#else // WIN32_VC +#else // _WIN32 string os_specific = get_filename_index(0).to_os_specific(); struct stat this_buf; @@ -1549,7 +1547,7 @@ get_access_timestamp() const { */ std::streamsize Filename:: get_file_size() const { -#ifdef WIN32_VC +#ifdef _WIN32 wstring os_specific = get_filename_index(0).to_os_specific_w(); struct _stat64 this_buf; @@ -1559,7 +1557,7 @@ get_file_size() const { if (_wstati64(os_specific.c_str(), &this_buf) == 0) { return this_buf.st_size; } -#else // WIN32_VC +#else // _WIN32 string os_specific = get_filename_index(0).to_os_specific(); struct stat this_buf; @@ -1718,7 +1716,7 @@ bool Filename:: scan_directory(vector_string &contents) const { assert(!get_pattern()); -#if defined(WIN32_VC) +#if defined(_WIN32) // Use Windows' FindFirstFile() FindNextFile() to walk through the list of // files in a directory. size_t orig_size = contents.size(); @@ -1874,13 +1872,13 @@ open_read(std::ifstream &stream) const { #endif stream.clear(); -#ifdef WIN32_VC +#ifdef _WIN32 wstring os_specific = to_os_specific_w(); stream.open(os_specific.c_str(), open_mode); #else string os_specific = to_os_specific(); stream.open(os_specific.c_str(), open_mode); -#endif // WIN32_VC +#endif // _WIN32 return (!stream.fail()); } @@ -1924,11 +1922,11 @@ open_write(std::ofstream &stream, bool truncate) const { #endif stream.clear(); -#ifdef WIN32_VC +#ifdef _WIN32 wstring os_specific = to_os_specific_w(); #else string os_specific = to_os_specific(); -#endif // WIN32_VC +#endif // _WIN32 stream.open(os_specific.c_str(), open_mode); return (!stream.fail()); @@ -1956,11 +1954,11 @@ open_append(std::ofstream &stream) const { #endif stream.clear(); -#ifdef WIN32_VC +#ifdef _WIN32 wstring os_specific = to_os_specific_w(); #else string os_specific = to_os_specific(); -#endif // WIN32_VC +#endif // _WIN32 stream.open(os_specific.c_str(), open_mode); return (!stream.fail()); @@ -1998,11 +1996,11 @@ open_read_write(std::fstream &stream, bool truncate) const { #endif stream.clear(); -#ifdef WIN32_VC +#ifdef _WIN32 wstring os_specific = to_os_specific_w(); #else string os_specific = to_os_specific(); -#endif // WIN32_VC +#endif // _WIN32 stream.open(os_specific.c_str(), open_mode); return (!stream.fail()); @@ -2030,11 +2028,11 @@ open_read_append(std::fstream &stream) const { #endif stream.clear(); -#ifdef WIN32_VC +#ifdef _WIN32 wstring os_specific = to_os_specific_w(); #else string os_specific = to_os_specific(); -#endif // WIN32_VC +#endif // _WIN32 stream.open(os_specific.c_str(), open_mode); return (!stream.fail()); @@ -2224,7 +2222,7 @@ open_read_append(pfstream &stream) const { bool Filename:: touch() const { assert(!get_pattern()); -#ifdef WIN32_VC +#ifdef _WIN32 // In Windows, we have to use the Windows API to do this reliably. // First, guarantee the file exists (and also get its handle). @@ -2285,14 +2283,14 @@ touch() const { return false; } return true; -#else // WIN32, PHAVE_UTIME_H +#else // _WIN32, PHAVE_UTIME_H // Other systems may not have an explicit control over the modification // time. For these systems, we'll just temporarily open the file in append // mode, then close it again (it gets closed when the pfstream goes out of // scope). pfstream file; return open_append(file); -#endif // WIN32, PHAVE_UTIME_H +#endif // _WIN32, PHAVE_UTIME_H } /** @@ -2301,13 +2299,13 @@ touch() const { */ bool Filename:: chdir() const { -#ifdef WIN32_VC +#ifdef _WIN32 wstring os_specific = to_os_specific_w(); return (_wchdir(os_specific.c_str()) >= 0); #else string os_specific = to_os_specific(); return (::chdir(os_specific.c_str()) >= 0); -#endif // WIN32_VC +#endif // _WIN32 } /** @@ -2318,7 +2316,7 @@ chdir() const { bool Filename:: unlink() const { assert(!get_pattern()); -#ifdef WIN32_VC +#ifdef _WIN32 // Windows can't delete a file if it's read-only. Weird. wstring os_specific = to_os_specific_w(); _wchmod(os_specific.c_str(), 0644); @@ -2326,7 +2324,7 @@ unlink() const { #else string os_specific = to_os_specific(); return (::unlink(os_specific.c_str()) == 0); -#endif // WIN32_VC +#endif // _WIN32 } @@ -2344,7 +2342,7 @@ rename_to(const Filename &other) const { return true; } -#ifdef WIN32_VC +#ifdef _WIN32 wstring os_specific = to_os_specific_w(); wstring other_os_specific = other.to_os_specific_w(); @@ -2383,7 +2381,7 @@ rename_to(const Filename &other) const { unlink(); return true; } -#else // WIN32_VC +#else // _WIN32 string os_specific = to_os_specific(); string other_os_specific = other.to_os_specific(); @@ -2422,7 +2420,7 @@ rename_to(const Filename &other) const { unlink(); return true; } -#endif // WIN32_VC +#endif // _WIN32 // Failed. temp.unlink(); @@ -2555,7 +2553,7 @@ mkdir() const { */ bool Filename:: rmdir() const { -#ifdef WIN32_VC +#ifdef _WIN32 wstring os_specific = to_os_specific_w(); int result = _wrmdir(os_specific.c_str()); @@ -2566,10 +2564,10 @@ rmdir() const { result = _wrmdir(os_specific.c_str()); } -#else // WIN32_VC +#else // _WIN32 string os_specific = to_os_specific(); int result = ::rmdir(os_specific.c_str()); -#endif // WIN32_VC +#endif // _WIN32 return (result == 0); } @@ -3046,7 +3044,7 @@ r_make_canonical(const Filename &cwd) { return false; } -#ifdef WIN32_VC +#ifdef _WIN32 // First, try to cd to the filename directly. wstring os_specific = to_os_specific_w(); if (_wchdir(os_specific.c_str()) >= 0) { @@ -3060,7 +3058,7 @@ r_make_canonical(const Filename &cwd) { } return true; } -#else // WIN32_VC +#else // _WIN32 // First, try to cd to the filename directly. string os_specific = to_os_specific(); if (::chdir(os_specific.c_str()) >= 0) { @@ -3074,7 +3072,7 @@ r_make_canonical(const Filename &cwd) { } return true; } -#endif // WIN32_VC +#endif // _WIN32 // That didn't work; maybe it's not a directory. Recursively go to the // directory above. diff --git a/dtool/src/dtoolutil/load_dso.cxx b/dtool/src/dtoolutil/load_dso.cxx index fcd0c9fffe..95650b88c2 100644 --- a/dtool/src/dtoolutil/load_dso.cxx +++ b/dtool/src/dtoolutil/load_dso.cxx @@ -32,7 +32,7 @@ static Filename resolve_dso(const DSearchPath &path, const Filename &filename) { } } -#if defined(WIN32) +#if defined(_WIN32) /* begin Win32-specific code */ #define WINDOWS_LEAN_AND_MEAN diff --git a/dtool/src/dtoolutil/pfstreamBuf.h b/dtool/src/dtoolutil/pfstreamBuf.h index 50875b2179..c72dff12ae 100644 --- a/dtool/src/dtoolutil/pfstreamBuf.h +++ b/dtool/src/dtoolutil/pfstreamBuf.h @@ -22,7 +22,7 @@ // compiling under Windows. Turn this off to use popen(), even on Windows. // (popen() doesn't seem to work on Win9x, although it does work on NT-based // variants.) -#ifdef WIN32_VC +#ifdef _WIN32 #define WIN_PIPE_CALLS 1 #endif @@ -34,7 +34,7 @@ #else // WIN_PIPE_CALLS -#ifdef WIN32_VC +#ifdef _WIN32 #define popen _popen #define pclose _pclose #endif diff --git a/dtool/src/dtoolutil/vector_src.h b/dtool/src/dtoolutil/vector_src.h index fae382b7e6..f2a57646ca 100644 --- a/dtool/src/dtoolutil/vector_src.h +++ b/dtool/src/dtoolutil/vector_src.h @@ -34,7 +34,7 @@ #include "pvector.h" -#if defined(WIN32_VC) && !defined(CPPPARSER) +#if defined(_MSC_VER) && !defined(CPPPARSER) #ifdef HAVE_DINKUM // With the Dinkum library, we must first export the base class, _Vector_val. diff --git a/dtool/src/dtoolutil/win32ArgParser.cxx b/dtool/src/dtoolutil/win32ArgParser.cxx index 4faf6bff95..81fb6ba7e9 100644 --- a/dtool/src/dtoolutil/win32ArgParser.cxx +++ b/dtool/src/dtoolutil/win32ArgParser.cxx @@ -22,7 +22,7 @@ #include "executionEnvironment.h" #include -#include +#include using std::string; diff --git a/dtool/src/interrogate/CMakeLists.txt b/dtool/src/interrogate/CMakeLists.txt new file mode 100644 index 0000000000..1ecba4623d --- /dev/null +++ b/dtool/src/interrogate/CMakeLists.txt @@ -0,0 +1,128 @@ +set(INTERROGATE_HEADERS + functionRemap.h + functionWriter.h + functionWriterPtrFromPython.h functionWriterPtrToPython.h + functionWriters.h + interfaceMaker.h + interfaceMakerC.h + interfaceMakerPython.h interfaceMakerPythonObj.h + interfaceMakerPythonSimple.h + interfaceMakerPythonNative.h + interrogate.h interrogateBuilder.h parameterRemap.I + parameterRemap.h + parameterRemapBasicStringPtrToString.h + parameterRemapBasicStringRefToString.h + parameterRemapBasicStringToString.h + parameterRemapCharStarToString.h + parameterRemapConcreteToPointer.h + parameterRemapConstToNonConst.h parameterRemapEnumToInt.h + parameterRemapPTToPointer.h + parameterRemapReferenceToConcrete.h + parameterRemapReferenceToPointer.h parameterRemapThis.h + parameterRemapToString.h + parameterRemapHandleToInt.h + parameterRemapUnchanged.h + typeManager.h +) + +set(INTERROGATE_SOURCES + functionRemap.cxx + functionWriter.cxx + functionWriterPtrFromPython.cxx functionWriterPtrToPython.cxx + functionWriters.cxx + interfaceMaker.cxx + interfaceMakerC.cxx + interfaceMakerPython.cxx interfaceMakerPythonObj.cxx + interfaceMakerPythonSimple.cxx + interfaceMakerPythonNative.cxx + interrogate.cxx interrogateBuilder.cxx parameterRemap.cxx + parameterRemapBasicStringPtrToString.cxx + parameterRemapBasicStringRefToString.cxx + parameterRemapBasicStringToString.cxx + parameterRemapCharStarToString.cxx + parameterRemapConcreteToPointer.cxx + parameterRemapConstToNonConst.cxx + parameterRemapEnumToInt.cxx parameterRemapPTToPointer.cxx + parameterRemapReferenceToConcrete.cxx + parameterRemapReferenceToPointer.cxx parameterRemapThis.cxx + parameterRemapToString.cxx + parameterRemapHandleToInt.cxx + parameterRemapUnchanged.cxx + typeManager.cxx +) + +set(INTERROGATE_PREAMBLE_PYTHON_NATIVE + ../interrogatedb/py_panda.cxx + ../interrogatedb/py_compat.cxx + ../interrogatedb/py_wrappers.cxx + ../interrogatedb/dtool_super_base.cxx +) + +composite_sources(interrogate INTERROGATE_SOURCES) +add_executable(interrogate ${INTERROGATE_HEADERS} ${INTERROGATE_SOURCES}) +target_link_libraries(interrogate p3cppParser p3interrogatedb + PKG::OPENSSL) + +# Python preamble for interrogate_module +set(_preamble_files) +foreach(_file ${INTERROGATE_PREAMBLE_PYTHON_NATIVE}) + # Resolve symlinks, use absolute path, and add a `#line 1 ...` directive + get_filename_component(_file "${_file}" REALPATH) + + string(SHA1 _hash "${_file}") + set(_line_file "${CMAKE_CURRENT_BINARY_DIR}/.${_hash}.h") + file(WRITE "${_line_file}" "#line 1 \"${_file}\"\n") + + list(APPEND _preamble_files "${_line_file}") + list(APPEND _preamble_files "${_file}") +endforeach(_file) + +add_custom_command( + OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/interrogate_preamble_python_native.cxx + COMMAND ${CMAKE_COMMAND} + -D OUTPUT_FILE="${CMAKE_CURRENT_BINARY_DIR}/interrogate_preamble_python_native.cxx" + -D INPUT_FILES="${_preamble_files}" + -D SYMBOL_NAME="interrogate_preamble_python_native" + -P ${PROJECT_SOURCE_DIR}/cmake/scripts/ConcatenateToCXX.cmake + DEPENDS ${INTERROGATE_PREAMBLE_PYTHON_NATIVE} + WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}") + +add_executable(interrogate_module interrogate_module.cxx + ${CMAKE_CURRENT_BINARY_DIR}/interrogate_preamble_python_native.cxx) +target_link_libraries(interrogate_module p3cppParser p3interrogatedb + PKG::OPENSSL) + +if(NOT CMAKE_CROSSCOMPILING) + add_executable(host_interrogate ALIAS interrogate) + add_executable(host_interrogate_module ALIAS interrogate_module) + +else() + # When cross-compiling, we must find the host Interrogate. + # TODO: We should also try to find_package(Panda3D ...) before falling back + # to searching manually. + find_program(HOST_PATH_INTERROGATE interrogate) + find_program(HOST_PATH_INTERROGATE_MODULE interrogate_module) + + add_executable(host_interrogate IMPORTED GLOBAL) + if(HOST_PATH_INTERROGATE) + set_target_properties(host_interrogate PROPERTIES + IMPORTED_LOCATION "${HOST_PATH_INTERROGATE}") + endif() + + add_executable(host_interrogate_module IMPORTED GLOBAL) + if(HOST_PATH_INTERROGATE_MODULE) + set_target_properties(host_interrogate_module PROPERTIES + IMPORTED_LOCATION "${HOST_PATH_INTERROGATE_MODULE}") + endif() + +endif() + +if(WANT_INTERROGATE) + install(TARGETS interrogate interrogate_module EXPORT Core COMPONENT CoreDevel DESTINATION ${CMAKE_INSTALL_BINDIR}) + install(FILES ${INTERROGATE_HEADERS} COMPONENT CoreDevel DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d) + +else() + set_target_properties(interrogate interrogate_module + PROPERTIES EXCLUDE_FROM_ALL ON) + +endif() diff --git a/dtool/src/interrogate/typeManager.cxx b/dtool/src/interrogate/typeManager.cxx index ab1fbffce3..dba10f4520 100644 --- a/dtool/src/interrogate/typeManager.cxx +++ b/dtool/src/interrogate/typeManager.cxx @@ -1442,7 +1442,7 @@ is_void(CPPType *type) { /** * Returns true if the indicated type is some class that derives from - * ReferenceCount, or false otherwise. + * ReferenceCount, or defines ref and unref(), or false otherwise. */ bool TypeManager:: is_reference_count(CPPType *type) { @@ -1459,6 +1459,14 @@ is_reference_count(CPPType *type) { case CPPDeclaration::ST_struct: { CPPStructType *stype = type->as_struct_type(); + + // If we have methods named ref() and unref(), this is good enough. + if (stype->_scope->_functions.count("ref") && + stype->_scope->_functions.count("unref") && + stype->_scope->_functions.count("get_ref_count")) { + return true; + } + CPPStructType::Derivation::const_iterator di; for (di = stype->_derivation.begin(); di != stype->_derivation.end(); diff --git a/dtool/src/interrogatedb/CMakeLists.txt b/dtool/src/interrogatedb/CMakeLists.txt new file mode 100644 index 0000000000..adadd5a24b --- /dev/null +++ b/dtool/src/interrogatedb/CMakeLists.txt @@ -0,0 +1,76 @@ +set(P3INTERROGATEDB_HEADERS + config_interrogatedb.h indexRemapper.h interrogateComponent.I + interrogateComponent.h interrogateDatabase.I + interrogateDatabase.h interrogateElement.I + interrogateElement.h interrogateFunction.I + interrogateFunction.h interrogateFunctionWrapper.I + interrogateFunctionWrapper.h + interrogateMakeSeq.I interrogateMakeSeq.h + interrogateManifest.I interrogateManifest.h + interrogateType.I interrogateType.h + interrogate_datafile.I interrogate_datafile.h + interrogate_interface.h interrogate_request.h +) + +set(P3INTERROGATEDB_SOURCES + config_interrogatedb.cxx + indexRemapper.cxx + interrogateComponent.cxx interrogateDatabase.cxx + interrogateElement.cxx interrogateFunction.cxx + interrogateFunctionWrapper.cxx + interrogateMakeSeq.cxx + interrogateManifest.cxx + interrogateType.cxx interrogate_datafile.cxx + interrogate_interface.cxx interrogate_request.cxx +) + +set(P3INTERROGATEDB_IGATE + interrogate_interface.h + interrogate_request.h +) + +set(P3IGATERUNTIME_HEADERS + extension.h py_compat.h py_panda.h py_panda.I py_wrappers.h +) + +composite_sources(p3interrogatedb P3INTERROGATEDB_SOURCES) +add_library(p3interrogatedb + ${P3INTERROGATEDB_HEADERS} ${P3INTERROGATEDB_SOURCES}) +set_target_properties(p3interrogatedb PROPERTIES DEFINE_SYMBOL BUILDING_INTERROGATEDB) +target_link_libraries(p3interrogatedb p3dconfig p3prc) + +install(TARGETS p3interrogatedb + EXPORT Core COMPONENT Core + DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d + ARCHIVE COMPONENT CoreDevel) +install(FILES ${P3INTERROGATEDB_HEADERS} COMPONENT CoreDevel DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d) +install(FILES ${P3IGATERUNTIME_HEADERS} COMPONENT CoreDevel DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d) + +# ALSO: This has an Interrogate binding! Take care of that if we want it. +# Note we don't use the regular Interrogate macros; this has some custom flags +# that would make it not worthwhile. + +if(NOT INTERROGATE_PYTHON_INTERFACE) + return() +endif() + +add_custom_command( + OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/interrogatedb_module.cxx" + COMMAND host_interrogate + -D EXPCL_INTERROGATEDB= + -nodb -python -promiscuous + -module panda3d.interrogatedb + -library interrogatedb + -string -true-names -do-module + -srcdir "${CMAKE_CURRENT_SOURCE_DIR}" + -oc "${CMAKE_CURRENT_BINARY_DIR}/interrogatedb_module.cxx" + ${P3INTERROGATEDB_IGATE} + + DEPENDS host_interrogate ${P3INTERROGATEDB_IGATE} + COMMENT "Interrogating interrogatedb") + +add_python_target(panda3d.interrogatedb + "${CMAKE_CURRENT_BINARY_DIR}/interrogatedb_module.cxx") +target_link_libraries(panda3d.interrogatedb p3interrogatedb) diff --git a/dtool/src/interrogatedb/config_interrogatedb.cxx b/dtool/src/interrogatedb/config_interrogatedb.cxx index 4971443cc1..16986de56b 100644 --- a/dtool/src/interrogatedb/config_interrogatedb.cxx +++ b/dtool/src/interrogatedb/config_interrogatedb.cxx @@ -17,7 +17,7 @@ #include "configVariableSearchPath.h" #include "dconfig.h" -#if defined(WIN32_VC) && defined(_DEBUG) +#if defined(_MSC_VER) && defined(_DEBUG) // _DEBUG assumes you are linking to msvcrt70d.dll, not msvcrt70.dll #define USE_WIN32_DBGHEAP #include diff --git a/dtool/src/prc/CMakeLists.txt b/dtool/src/prc/CMakeLists.txt new file mode 100644 index 0000000000..f2985662bd --- /dev/null +++ b/dtool/src/prc/CMakeLists.txt @@ -0,0 +1,157 @@ +set(P3PRC_HEADERS + androidLogStream.h + bigEndian.h + config_prc.h + configDeclaration.I configDeclaration.h + configFlags.I configFlags.h + configPage.I configPage.h + configPageManager.I configPageManager.h + configVariable.I configVariable.h + configVariableBase.I configVariableBase.h + configVariableBool.I configVariableBool.h + configVariableCore.I configVariableCore.h + configVariableDouble.I configVariableDouble.h + configVariableEnum.I configVariableEnum.h + configVariableFilename.I configVariableFilename.h + configVariableInt.I configVariableInt.h + configVariableInt64.I configVariableInt64.h + configVariableList.I configVariableList.h + configVariableManager.I configVariableManager.h + configVariableSearchPath.I configVariableSearchPath.h + configVariableString.I configVariableString.h + encryptStreamBuf.h encryptStreamBuf.I encryptStream.h encryptStream.I + littleEndian.h + nativeNumericData.I nativeNumericData.h + pnotify.I pnotify.h + notifyCategory.I notifyCategory.h + notifyCategoryProxy.I notifyCategoryProxy.h + notifySeverity.h + prcKeyRegistry.h prcKeyRegistry.I + reversedNumericData.I reversedNumericData.h + streamReader.I streamReader.h + streamWrapper.I streamWrapper.h + streamWriter.I streamWriter.h + ${CMAKE_CURRENT_BINARY_DIR}/prc_parameters.h +) + +set(P3PRC_SOURCES + config_prc.cxx + configDeclaration.cxx + configFlags.cxx + configPage.cxx + configPageManager.cxx + configVariable.cxx + configVariableBase.cxx + configVariableBool.cxx + configVariableCore.cxx + configVariableDouble.cxx + configVariableEnum.cxx + configVariableFilename.cxx + configVariableInt.cxx + configVariableInt64.cxx + configVariableList.cxx + configVariableManager.cxx + configVariableSearchPath.cxx + configVariableString.cxx + nativeNumericData.cxx + notify.cxx + notifyCategory.cxx + notifySeverity.cxx + prcKeyRegistry.cxx + reversedNumericData.cxx + streamReader.cxx streamWrapper.cxx streamWriter.cxx +) + +configure_file(prc_parameters.h.in prc_parameters.h) + +if(ANDROID) + set(P3PRC_SOURCES ${P3PRC_SOURCES} + androidLogStream.cxx) +endif() + +if(HAVE_OPENSSL) + list(APPEND P3PRC_SOURCES encryptStreamBuf.cxx encryptStream.cxx) +endif() + +set(P3PRC_IGATEEXT + streamReader_ext.cxx + streamReader_ext.h + streamWriter_ext.cxx + streamWriter_ext.h +) + +composite_sources(p3prc P3PRC_SOURCES) +add_library(p3prc + ${P3PRC_HEADERS} ${P3PRC_SOURCES}) +set_target_properties(p3prc PROPERTIES DEFINE_SYMBOL BUILDING_DTOOL_PRC) +target_include_directories(p3prc PUBLIC $) +target_link_libraries(p3prc p3dtool PKG::OPENSSL) +target_interrogate(p3prc ALL EXTENSIONS ${P3PRC_IGATEEXT}) + +if(ANDROID) + target_link_libraries(p3prc log) +endif() + +install(TARGETS p3prc + EXPORT Core COMPONENT Core + DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d + ARCHIVE COMPONENT CoreDevel) + +install(FILES ${P3PRC_HEADERS} COMPONENT CoreDevel DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d) + +# Also install under the old name "p3dtoolconfig" +# TODO: Remove this once "p3dtoolconfig" is deprecated +if(WIN32) + # Symlinks aren't pretty under WIN32 + set(_symlink "copy") +else() + set(_symlink "create_symlink") +endif() + +get_target_property(_type p3prc TYPE) +if(_type STREQUAL "SHARED_LIBRARY") + + set(_suffix "${CMAKE_SHARED_LIBRARY_SUFFIX}") + if(UNIX) + get_target_property(_soversion p3prc SOVERSION) + if(APPLE) + set(_suffix ".${_soversion}${_suffix}") + else() + set(_suffix "${_suffix}.${_soversion}") + endif() + + set(_file_genex "TARGET_SONAME_FILE") + set(_install_dir "${CMAKE_INSTALL_LIBDIR}") + + else() + # Win32? + set(_file_genex "TARGET_FILE") + set(_install_dir "${CMAKE_INSTALL_BINDIR}") + + endif() + + set(_soname "${CMAKE_SHARED_LIBRARY_PREFIX}p3dtoolconfig${_suffix}") + + add_custom_command(TARGET p3prc POST_BUILD + COMMAND "${CMAKE_COMMAND}" -E chdir "$<${_file_genex}_DIR:p3prc>" + "${CMAKE_COMMAND}" -E "${_symlink}" + "$<${_file_genex}_NAME:p3prc>" "${_soname}" + ) + install(FILES "$<${_file_genex}_DIR:p3prc>/${_soname}" + DESTINATION "${_install_dir}") +endif() + +if(WIN32) + set(_libname "${CMAKE_IMPORT_LIBRARY_PREFIX}p3dtoolconfig${CMAKE_IMPORT_LIBRARY_SUFFIX}") +else() + set(_libname "${CMAKE_${_type}_PREFIX}p3dtoolconfig${CMAKE_${_type}_SUFFIX}") +endif() +add_custom_command(TARGET p3prc POST_BUILD + COMMAND "${CMAKE_COMMAND}" -E chdir "$" + "${CMAKE_COMMAND}" -E "${_symlink}" + "$" "${_libname}" +) +install(FILES "$/${_libname}" + DESTINATION "${CMAKE_INSTALL_LIBDIR}") diff --git a/dtool/src/prc/configPageManager.cxx b/dtool/src/prc/configPageManager.cxx index 737d25026b..39b4adcc6c 100644 --- a/dtool/src/prc/configPageManager.cxx +++ b/dtool/src/prc/configPageManager.cxx @@ -162,7 +162,7 @@ reload_implicit_pages() { _prc_patterns.reserve(pat_list.size()); for (size_t i = 0; i < pat_list.size(); ++i) { GlobPattern glob(pat_list[i]); -#ifdef WIN32 +#ifdef _WIN32 // On windows, the file system is case-insensitive, so the pattern // should be too. glob.set_case_sensitive(false); @@ -184,7 +184,7 @@ reload_implicit_pages() { _prc_encrypted_patterns.reserve(pat_list.size()); for (size_t i = 0; i < pat_list.size(); ++i) { GlobPattern glob(pat_list[i]); -#ifdef WIN32 +#ifdef _WIN32 glob.set_case_sensitive(false); #endif // WIN32 _prc_encrypted_patterns.push_back(glob); @@ -204,7 +204,7 @@ reload_implicit_pages() { _prc_executable_patterns.reserve(pat_list.size()); for (size_t i = 0; i < pat_list.size(); ++i) { GlobPattern glob(pat_list[i]); -#ifdef WIN32 +#ifdef _WIN32 glob.set_case_sensitive(false); #endif // WIN32 _prc_executable_patterns.push_back(glob); @@ -481,7 +481,7 @@ reload_implicit_pages() { PandaFileStreamBuf::_newline_mode = newline_mode; #endif // USE_PANDAFILESTREAM -#ifdef WIN32 +#ifdef _WIN32 // We don't necessarily want an error dialog when we fail to load a .dll // file. But sometimes it is useful for debugging. ConfigVariableBool show_dll_error_dialog diff --git a/dtool/src/prc/notify.cxx b/dtool/src/prc/notify.cxx index 9c2ea8b79a..eff61c5696 100644 --- a/dtool/src/prc/notify.cxx +++ b/dtool/src/prc/notify.cxx @@ -355,7 +355,7 @@ assert_failure(const char *expression, int line, // Make sure the error message has been flushed to the output. nout.flush(); -#ifdef WIN32 +#ifdef _MSC_VER // How to trigger an exception in VC++ that offers to take us into the // debugger? abort() doesn't do it. We used to be able to assert(false), // but in VC++ 7 that just throws an exception, and an uncaught exception @@ -373,9 +373,9 @@ assert_failure(const char *expression, int line, int *ptr = nullptr; *ptr = 1; -#else // WIN32 +#else // _MSC_VER abort(); -#endif // WIN32 +#endif // _MSC_VER } return true; diff --git a/dtool/src/prc/prc_parameters.h.in b/dtool/src/prc/prc_parameters.h.in new file mode 100644 index 0000000000..80d4dcdb8d --- /dev/null +++ b/dtool/src/prc/prc_parameters.h.in @@ -0,0 +1,56 @@ +/* prc_parameters.h. Generated automatically by CMake. */ +/********************************** DO NOT EDIT ****************************/ + + +/* The compiled-in default directory to look for the Configrc file, in + the absence of the PRC_DIR environment variable set, and in + the absence of anything specified via the configpath directive. */ +#define DEFAULT_PRC_DIR "@DEFAULT_PRC_DIR@" + +/* The compiled-in name of the environment variable(s) that contain + the name of a single directory in which to search for prc files. */ +#define PRC_DIR_ENVVARS "@PRC_DIR_ENVVARS@" + +/* The compiled-in name of the environment variable(s) that contain + the name of multiple directories, separated by DEFAULT_PATHSEP, in + which to search for prc files. */ +#define PRC_PATH_ENVVARS "@PRC_PATH_ENVVARS@" + +/* This is a special variable that is rarely used; it exists primarily + to support the Cygwin-based "ctattach" tools used by the Walt + Disney VR Studio. This defines a set of environment variable(s) + that define a search path, as above; except that the directory + names on these search paths are Panda-style filenames, not + Windows-style filenames; and the path separator is always a space + character, regardless of DEFAULT_PATHSEP. */ +#define PRC_PATH2_ENVVARS "@PRC_PATH2_ENVVARS@" + +/* The filename(s) to search for in the above paths. Normally this is + *.prc. */ +#define PRC_PATTERNS "@PRC_PATTERNS@" + +/* The filename(s) for encrypted prc files. */ +#define PRC_ENCRYPTED_PATTERNS "@PRC_ENCRYPTED_PATTERNS@" + +/* The encryption key used to decrypt any encrypted prc files + identified by PRC_ENCRYPTED_PATTERNS. */ +#define PRC_ENCRYPTION_KEY "@PRC_ENCRYPTION_KEY@" + +/* The filename(s) to search for, and execute, in the above paths. + Normally this is empty. */ +#define PRC_EXECUTABLE_PATTERNS "@PRC_EXECUTABLE_PATTERNS@" + +/* The environment variable that defines optional args to pass to + executables found that match one of the above patterns. */ +#define PRC_EXECUTABLE_ARGS_ENVVAR "@PRC_EXECUTABLE_ARGS_ENVVAR@" + +/* Define if we want to enable the "trust_level" feature of prc config + variables. This requires OpenSSL and PRC_PUBLIC_KEYS_FILENAME, + above. */ +#cmakedefine PRC_RESPECT_TRUST_LEVEL + +/* The trust level value for any legacy (DConfig) variables. */ +#define PRC_DCONFIG_TRUST_LEVEL @PRC_DCONFIG_TRUST_LEVEL@ + +/* The amount by which we globally increment the trust level. */ +#define PRC_INC_TRUST_LEVEL @PRC_INC_TRUST_LEVEL@ diff --git a/dtool/src/prc/streamWrapper.I b/dtool/src/prc/streamWrapper.I index 6d2578262c..dcc953fa24 100644 --- a/dtool/src/prc/streamWrapper.I +++ b/dtool/src/prc/streamWrapper.I @@ -124,7 +124,7 @@ INLINE OStreamWrapper:: OStreamWrapper(std::ostream *stream, bool owns_pointer, bool stringstream_hack) : _ostream(stream), _owns_pointer(owns_pointer) -#ifdef WIN32_VC +#ifdef _MSC_VER , _stringstream_hack(stringstream_hack) #endif { @@ -137,7 +137,7 @@ INLINE OStreamWrapper:: OStreamWrapper(std::ostream &stream) : _ostream(&stream), _owns_pointer(false) -#ifdef WIN32_VC +#ifdef _MSC_VER , _stringstream_hack(false) #endif { diff --git a/dtool/src/prc/streamWrapper.cxx b/dtool/src/prc/streamWrapper.cxx index 3c59fb3a90..2df9ebbe49 100644 --- a/dtool/src/prc/streamWrapper.cxx +++ b/dtool/src/prc/streamWrapper.cxx @@ -25,7 +25,7 @@ IStreamWrapper:: // stream pointer does not call the appropriate global delete function; // instead apparently calling the system delete function. So we call the // delete function by hand instead. -#if !defined(WIN32_VC) && !defined(USE_MEMORY_NOWRAPPERS) && defined(REDEFINE_GLOBAL_OPERATOR_NEW) +#if !defined(_WIN32) && !defined(USE_MEMORY_NOWRAPPERS) && defined(REDEFINE_GLOBAL_OPERATOR_NEW) _istream->~istream(); (*global_operator_delete)(_istream); #else @@ -140,7 +140,7 @@ OStreamWrapper:: // stream pointer does not call the appropriate global delete function; // instead apparently calling the system delete function. So we call the // delete function by hand instead. -#if !defined(WIN32_VC) && !defined(USE_MEMORY_NOWRAPPERS) && defined(REDEFINE_GLOBAL_OPERATOR_NEW) +#if !defined(_WIN32) && !defined(USE_MEMORY_NOWRAPPERS) && defined(REDEFINE_GLOBAL_OPERATOR_NEW) _ostream->~ostream(); (*global_operator_delete)(_ostream); #else @@ -184,13 +184,13 @@ seek_write(streamsize pos, const char *buffer, streamsize num_bytes, _ostream->clear(); _ostream->seekp(pos); -#ifdef WIN32_VC +#ifdef _MSC_VER if (_ostream->fail() && _stringstream_hack && pos == 0) { // Ignore an unsuccessful attempt to seekp(0) if _stringstream_hack is // true. _ostream->clear(); } -#endif // WIN32_VC +#endif // _MSC_VER _ostream->write(buffer, num_bytes); fail = _ostream->fail(); @@ -208,13 +208,13 @@ seek_eof_write(const char *buffer, streamsize num_bytes, bool &fail) { _ostream->clear(); _ostream->seekp(0, std::ios::end); -#ifdef WIN32_VC +#ifdef _MSC_VER if (_ostream->fail() && _stringstream_hack) { // Ignore an unsuccessful attempt to seekp(0) if _stringstream_hack is // true. _ostream->clear(); } -#endif // WIN32_VC +#endif // _MSC_VER _ostream->write(buffer, num_bytes); fail = _ostream->fail(); @@ -232,7 +232,7 @@ seek_ppos_eof() { acquire(); _ostream->seekp(0, std::ios::end); -#ifdef WIN32_VC +#ifdef _MSC_VER if (_ostream->fail() && _stringstream_hack) { // Ignore an unsuccessful attempt to seekp(0) if _stringstream_hack is // true. @@ -240,7 +240,7 @@ seek_ppos_eof() { release(); return 0; } -#endif // WIN32_VC +#endif // _MSC_VER pos = _ostream->tellp(); release(); @@ -258,7 +258,7 @@ StreamWrapper:: // stream pointer does not call the appropriate global delete function; // instead apparently calling the system delete function. So we call the // delete function by hand instead. -#if !defined(WIN32_VC) && !defined(USE_MEMORY_NOWRAPPERS) && defined(REDEFINE_GLOBAL_OPERATOR_NEW) +#if !defined(_WIN32) && !defined(USE_MEMORY_NOWRAPPERS) && defined(REDEFINE_GLOBAL_OPERATOR_NEW) _iostream->~iostream(); (*global_operator_delete)(_iostream); #else diff --git a/dtool/src/prc/streamWrapper.h b/dtool/src/prc/streamWrapper.h index a837540129..94c7c7fac2 100644 --- a/dtool/src/prc/streamWrapper.h +++ b/dtool/src/prc/streamWrapper.h @@ -110,7 +110,7 @@ private: // until some data has been written to the stream. When this flag is set // true, we know we have a possibly-empty stringstream, so we allow seekp(0) // to fail silently, knowing that there's no harm in this case. -#ifdef WIN32_VC +#ifdef _MSC_VER bool _stringstream_hack; #endif }; diff --git a/dtool/src/test_interrogate/test_interrogate.cxx b/dtool/src/test_interrogate/test_interrogate.cxx index 426de102de..a518f12cc4 100644 --- a/dtool/src/test_interrogate/test_interrogate.cxx +++ b/dtool/src/test_interrogate/test_interrogate.cxx @@ -582,7 +582,7 @@ main(int argc, char **argv) { Filename pathname = Filename::dso_filename(argv[i]); cerr << "Loading " << pathname << "\n"; -#ifdef WIN32 +#ifdef _WIN32 // test_interrogate always wants to show an error dialog. SetErrorMode(0); #endif diff --git a/makepanda/makepanda.py b/makepanda/makepanda.py index 455d2b31fb..8e88a40930 100755 --- a/makepanda/makepanda.py +++ b/makepanda/makepanda.py @@ -397,6 +397,20 @@ elif target == 'linux' and (os.path.isfile("/lib/libc-2.5.so") or os.path.isfile else: PLATFORM = 'manylinux1-i686' +elif target == 'linux' and (os.path.isfile("/lib/libc-2.12.so") or os.path.isfile("/lib64/libc-2.12.so")) and os.path.isdir("/opt/python"): + # Same sloppy check for manylinux2010. + if GetTargetArch() in ('x86_64', 'amd64'): + PLATFORM = 'manylinux2010-x86_64' + else: + PLATFORM = 'manylinux2010-i686' + +elif target == 'linux' and (os.path.isfile("/lib/libc-2.17.so") or os.path.isfile("/lib64/libc-2.17.so")) and os.path.isdir("/opt/python"): + # Same sloppy check for manylinux2014. + if GetTargetArch() in ('x86_64', 'amd64'): + PLATFORM = 'manylinux2014-x86_64' + else: + PLATFORM = 'manylinux2014-i686' + elif not CrossCompiling(): if HasTargetArch(): # Replace the architecture in the platform string. @@ -797,6 +811,60 @@ if (COMPILER=="GCC"): elif os.path.isfile(GetThirdpartyDir() + "ffmpeg/lib/libavcodec.a"): # Needed when linking ffmpeg statically on Linux. LibName("FFMPEG", "-Wl,-Bsymbolic") + # Don't export ffmpeg symbols from libp3ffmpeg when linking statically. + for ffmpeg_lib in ffmpeg_libs: + LibName("FFMPEG", "-Wl,--exclude-libs,%s.a" % (ffmpeg_lib)) + + if GetTarget() != "darwin": + for fcollada_lib in fcollada_libs: + LibName("FCOLLADA", "-Wl,--exclude-libs,lib%s.a" % (fcollada_lib)) + + if not PkgSkip("SWSCALE"): + LibName("SWSCALE", "-Wl,--exclude-libs,libswscale.a") + + if not PkgSkip("SWRESAMPLE"): + LibName("SWRESAMPLE", "-Wl,--exclude-libs,libswresample.a") + + if not PkgSkip("JPEG"): + LibName("JPEG", "-Wl,--exclude-libs,libjpeg.a") + + if not PkgSkip("TIFF"): + LibName("TIFF", "-Wl,--exclude-libs,libtiff.a") + + if not PkgSkip("PNG"): + LibName("PNG", "-Wl,--exclude-libs,libpng.a") + LibName("PNG", "-Wl,--exclude-libs,libpng16.a") + + if not PkgSkip("SQUISH"): + LibName("SQUISH", "-Wl,--exclude-libs,libsquish.a") + + if not PkgSkip("OPENEXR"): + LibName("OPENEXR", "-Wl,--exclude-libs,libHalf.a") + LibName("OPENEXR", "-Wl,--exclude-libs,libIex.a") + LibName("OPENEXR", "-Wl,--exclude-libs,libIexMath.a") + LibName("OPENEXR", "-Wl,--exclude-libs,libIlmImf.a") + LibName("OPENEXR", "-Wl,--exclude-libs,libIlmImfUtil.a") + LibName("OPENEXR", "-Wl,--exclude-libs,libIlmThread.a") + LibName("OPENEXR", "-Wl,--exclude-libs,libImath.a") + + if not PkgSkip("VORBIS"): + LibName("VORBIS", "-Wl,--exclude-libs,libogg.a") + LibName("VORBIS", "-Wl,--exclude-libs,libvorbis.a") + LibName("VORBIS", "-Wl,--exclude-libs,libvorbisenc.a") + LibName("VORBIS", "-Wl,--exclude-libs,libvorbisfile.a") + + if not PkgSkip("OPUS"): + LibName("OPUS", "-Wl,--exclude-libs,libogg.a") + LibName("OPUS", "-Wl,--exclude-libs,libopus.a") + LibName("OPUS", "-Wl,--exclude-libs,libopusfile.a") + + if not PkgSkip("VRPN"): + LibName("VRPN", "-Wl,--exclude-libs,libvrpn.a") + LibName("VRPN", "-Wl,--exclude-libs,libquat.a") + + if not PkgSkip("ARTOOLKIT"): + LibName("ARTOOLKIT", "-Wl,--exclude-libs,libAR.a") + LibName("ARTOOLKIT", "-Wl,--exclude-libs,libARMulti.a") if PkgSkip("FFMPEG") or GetTarget() == "darwin": cv_lib = ChooseLib(("opencv_core", "cv"), "OPENCV") @@ -809,10 +877,13 @@ if (COMPILER=="GCC"): else: PkgDisable("OPENCV") - if GetTarget() == "darwin" and not PkgSkip("OPENAL"): - LibName("OPENAL", "-framework AudioUnit") - LibName("OPENAL", "-framework AudioToolbox") - LibName("OPENAL", "-framework CoreAudio") + if not PkgSkip("OPENAL"): + if GetTarget() == "darwin": + LibName("OPENAL", "-framework AudioUnit") + LibName("OPENAL", "-framework AudioToolbox") + LibName("OPENAL", "-framework CoreAudio") + else: + LibName("OPENAL", "-Wl,--exclude-libs,libopenal.a") if not PkgSkip("ASSIMP") and \ os.path.isfile(GetThirdpartyDir() + "assimp/lib/libassimp.a"): @@ -821,6 +892,10 @@ if (COMPILER=="GCC"): if os.path.isfile(irrxml): LibName("ASSIMP", irrxml) + if GetTarget() != "darwin": + LibName("ASSIMP", "-Wl,--exclude-libs,libassimp.a") + LibName("ASSIMP", "-Wl,--exclude-libs,libIrrXML.a") + if not PkgSkip("PYTHON"): python_lib = SDK["PYTHONVERSION"] SmartPkgEnable("PYTHON", "", python_lib, (SDK["PYTHONVERSION"], SDK["PYTHONVERSION"] + "/Python.h")) @@ -833,6 +908,10 @@ if (COMPILER=="GCC"): SmartPkgEnable("ZLIB", "zlib", ("z"), "zlib.h") SmartPkgEnable("GTK2", "gtk+-2.0") + if not PkgSkip("OPENSSL") and GetTarget() != "darwin": + LibName("OPENSSL", "-Wl,--exclude-libs,libssl.a") + LibName("OPENSSL", "-Wl,--exclude-libs,libcrypto.a") + if GetTarget() != 'darwin': # CgGL is covered by the Cg framework, and we don't need X11 components on OSX if not PkgSkip("NVIDIACG"): @@ -1056,7 +1135,7 @@ def CompileCxx(obj,src,opts): if ("BIGOBJ" in opts) or GetTargetArch() == 'x64': cmd += " /bigobj" - cmd += " /Zm300 /DWIN32_VC /DWIN32" + cmd += " /Zm300" if 'EXCEPTIONS' in opts: cmd += " /EHsc" else: @@ -1065,9 +1144,6 @@ def CompileCxx(obj,src,opts): if 'RTTI' not in opts: cmd += " /GR-" - if GetTargetArch() == 'x64': - cmd += " /DWIN64_VC /DWIN64" - cmd += " /W3 " + BracketNameWithQuotes(src) oscmd(cmd) else: @@ -1148,9 +1224,7 @@ def CompileCxx(obj,src,opts): cmd += " /Qopt-report:2 /Qopt-report-phase:hlo /Qopt-report-phase:hpo" # some optimization reports else: cmd += " /W1 " - cmd += " /EHa /Zm300 /DWIN32_VC /DWIN32" - if GetTargetArch() == 'x64': - cmd += " /DWIN64_VC /DWIN64" + cmd += " /EHa /Zm300" cmd += " " + BracketNameWithQuotes(src) oscmd(cmd) @@ -1389,9 +1463,9 @@ def CompileIgate(woutd,wsrc,opts): cmd += ' -srcdir %s -I%s' % (srcdir, srcdir) cmd += ' -DCPPPARSER -D__STDC__=1 -D__cplusplus=201103L' if (COMPILER=="MSVC"): - cmd += ' -DWIN32_VC -DWIN32 -D_WIN32' + cmd += ' -D_WIN32' if GetTargetArch() == 'x64': - cmd += ' -DWIN64_VC -DWIN64 -D_WIN64 -D_M_X64 -D_M_AMD64' + cmd += ' -D_WIN64 -D_M_X64 -D_M_AMD64' else: cmd += ' -D_M_IX86' # NOTE: this 1600 value is the version number for VC2010. @@ -2655,14 +2729,28 @@ else: # otherwise, disable it. confautoprc = confautoprc.replace('#st#', '#') -if PkgSkip("ASSIMP"): +confautoprc = confautoprc.replace('\r\n', '\n') + +if PkgSkip("ASSIMP") or GetLinkAllStatic(): confautoprc = confautoprc.replace("load-file-type p3assimp", "#load-file-type p3assimp") +if PkgSkip("EGG") or GetLinkAllStatic(): + confautoprc = confautoprc.replace("load-file-type egg pandaegg", "#load-file-type egg pandaegg") + +if PkgSkip("PANDATOOL") or PkgSkip("EGG") or GetLinkAllStatic(): + confautoprc = confautoprc.replace("load-file-type p3ptloader", "#load-file-type p3ptloader") + +if PkgSkip("FFMPEG") or GetLinkAllStatic(): + confautoprc = confautoprc.replace("load-audio-type * p3ffmpeg", "#load-audio-type * p3ffmpeg") + confautoprc = confautoprc.replace("load-video-type * p3ffmpeg", "#load-video-type * p3ffmpeg") + if (os.path.isfile("makepanda/myconfig.in")): configprc = ReadFile("makepanda/myconfig.in") else: configprc = ReadFile("makepanda/config.in") +configprc = configprc.replace('\r\n', '\n') + if (GetTarget() == 'windows'): configprc = configprc.replace("$XDG_CACHE_HOME/panda3d", "$USER_APPDATA/Panda3D-%s" % MAJOR_VERSION) else: @@ -2671,6 +2759,21 @@ else: if (GetTarget() == 'darwin'): configprc = configprc.replace("$XDG_CACHE_HOME/panda3d", "$HOME/Library/Caches/Panda3D-%s" % MAJOR_VERSION) +if PkgSkip("GL") or GetLinkAllStatic(): + configprc = configprc.replace("\nload-display pandagl", "\n#load-display pandagl") + +if PkgSkip("GLES") or GetLinkAllStatic(): + configprc = configprc.replace("\n#load-display pandagles", "") + +if PkgSkip("DX9") or GetLinkAllStatic(): + configprc = configprc.replace("\n#load-display pandadx9", "") + +if PkgSkip("TINYDISPLAY") or GetLinkAllStatic(): + configprc = configprc.replace("\n#load-display p3tinydisplay", "") + +if PkgSkip("OPENAL") or GetLinkAllStatic(): + configprc = configprc.replace("audio-library-name p3openal_audio", "#audio-library-name p3openal_audio") + if GetTarget() == 'windows': # Convert to Windows newlines. ConditionalWriteFile(GetOutputDir()+"/etc/Config.prc", configprc, newline='\r\n') @@ -3207,7 +3310,7 @@ TargetAdd('interrogate.exe', input='interrogate_composite2.obj') TargetAdd('interrogate.exe', input='libp3cppParser.ilb') TargetAdd('interrogate.exe', input=COMMON_DTOOL_LIBS) TargetAdd('interrogate.exe', input='libp3interrogatedb.dll') -TargetAdd('interrogate.exe', opts=['ADVAPI', 'OPENSSL', 'WINSHELL', 'WINGDI', 'WINUSER']) +TargetAdd('interrogate.exe', opts=['ADVAPI', 'WINSHELL', 'WINGDI', 'WINUSER']) preamble = WriteEmbeddedStringFile('interrogate_preamble_python_native', inputs=[ 'dtool/src/interrogatedb/py_panda.cxx', @@ -3222,14 +3325,14 @@ TargetAdd('interrogate_module.exe', input='interrogate_module_preamble_python_na TargetAdd('interrogate_module.exe', input='libp3cppParser.ilb') TargetAdd('interrogate_module.exe', input=COMMON_DTOOL_LIBS) TargetAdd('interrogate_module.exe', input='libp3interrogatedb.dll') -TargetAdd('interrogate_module.exe', opts=['ADVAPI', 'OPENSSL', 'WINSHELL', 'WINGDI', 'WINUSER']) +TargetAdd('interrogate_module.exe', opts=['ADVAPI', 'WINSHELL', 'WINGDI', 'WINUSER']) TargetAdd('parse_file_parse_file.obj', opts=OPTS, input='parse_file.cxx') TargetAdd('parse_file.exe', input='parse_file_parse_file.obj') TargetAdd('parse_file.exe', input='libp3cppParser.ilb') TargetAdd('parse_file.exe', input=COMMON_DTOOL_LIBS) TargetAdd('parse_file.exe', input='libp3interrogatedb.dll') -TargetAdd('parse_file.exe', opts=['ADVAPI', 'OPENSSL', 'WINSHELL', 'WINGDI', 'WINUSER']) +TargetAdd('parse_file.exe', opts=['ADVAPI', 'WINSHELL', 'WINGDI', 'WINUSER']) # # DIRECTORY: dtool/src/prckeys/ @@ -3240,7 +3343,7 @@ if (PkgSkip("OPENSSL")==0): TargetAdd('make-prc-key_makePrcKey.obj', opts=OPTS, input='makePrcKey.cxx') TargetAdd('make-prc-key.exe', input='make-prc-key_makePrcKey.obj') TargetAdd('make-prc-key.exe', input=COMMON_DTOOL_LIBS) - TargetAdd('make-prc-key.exe', opts=['ADVAPI', 'OPENSSL', 'WINSHELL', 'WINGDI', 'WINUSER']) + TargetAdd('make-prc-key.exe', opts=['ADVAPI', 'OPENSSL', 'WINSHELL', 'WINGDI', 'WINUSER']) # # DIRECTORY: dtool/src/test_interrogate/ @@ -3251,7 +3354,7 @@ TargetAdd('test_interrogate_test_interrogate.obj', opts=OPTS, input='test_interr TargetAdd('test_interrogate.exe', input='test_interrogate_test_interrogate.obj') TargetAdd('test_interrogate.exe', input='libp3interrogatedb.dll') TargetAdd('test_interrogate.exe', input=COMMON_DTOOL_LIBS) -TargetAdd('test_interrogate.exe', opts=['ADVAPI', 'OPENSSL', 'WINSHELL', 'WINGDI', 'WINUSER']) +TargetAdd('test_interrogate.exe', opts=['ADVAPI', 'WINSHELL', 'WINGDI', 'WINUSER']) # # DIRECTORY: dtool/src/dtoolbase/ @@ -3352,7 +3455,7 @@ TargetAdd('libpandaexpress.dll', input='p3express_composite1.obj') TargetAdd('libpandaexpress.dll', input='p3express_composite2.obj') TargetAdd('libpandaexpress.dll', input='p3pandabase_pandabase.obj') TargetAdd('libpandaexpress.dll', input=COMMON_DTOOL_LIBS) -TargetAdd('libpandaexpress.dll', opts=['ADVAPI', 'WINSOCK2', 'OPENSSL', 'ZLIB', 'WINGDI', 'WINUSER', 'ANDROID']) +TargetAdd('libpandaexpress.dll', opts=['ADVAPI', 'WINSOCK2', 'OPENSSL', 'ZLIB', 'WINGDI', 'WINUSER', 'ANDROID']) # # DIRECTORY: panda/src/pipeline/ @@ -3478,10 +3581,10 @@ PyTargetAdd('p3pnmimage_pfmFile_ext.obj', opts=OPTS, input='pfmFile_ext.cxx') # DIRECTORY: panda/src/nativenet/ # -OPTS=['DIR:panda/src/nativenet', 'OPENSSL', 'BUILDING:PANDA'] +OPTS=['DIR:panda/src/nativenet', 'BUILDING:PANDA'] TargetAdd('p3nativenet_composite1.obj', opts=OPTS, input='p3nativenet_composite1.cxx') -OPTS=['DIR:panda/src/nativenet', 'OPENSSL'] +OPTS=['DIR:panda/src/nativenet'] IGATEFILES=GetDirectoryContents('panda/src/nativenet', ["*.h", "*_composite*.cxx"]) TargetAdd('libp3nativenet.in', opts=OPTS, input=IGATEFILES) TargetAdd('libp3nativenet.in', opts=['IMOD:panda3d.core', 'ILIB:libp3nativenet', 'SRCDIR:panda/src/nativenet']) @@ -3794,7 +3897,7 @@ TargetAdd('libp3dxml.in', opts=['IMOD:panda3d.core', 'ILIB:libp3dxml', 'SRCDIR:p # OPTS=['DIR:panda/metalibs/panda', 'BUILDING:PANDA', 'JPEG', 'PNG', 'HARFBUZZ', - 'TIFF', 'OPENEXR', 'ZLIB', 'OPENSSL', 'FREETYPE', 'FFTW', 'ADVAPI', 'WINSOCK2', + 'TIFF', 'OPENEXR', 'ZLIB', 'FREETYPE', 'FFTW', 'ADVAPI', 'WINSOCK2', 'SQUISH', 'NVIDIACG', 'VORBIS', 'OPUS', 'WINUSER', 'WINMM', 'WINGDI', 'IPHLPAPI', 'SETUPAPI', 'IOKIT'] @@ -4151,7 +4254,7 @@ if PkgSkip("OPENAL") == 0: # if (PkgSkip("OPENSSL")==0 and PkgSkip("DEPLOYTOOLS")==0): - OPTS=['DIR:panda/src/downloadertools', 'OPENSSL', 'ADVAPI', 'WINSOCK2', 'WINSHELL', 'WINGDI', 'WINUSER'] + OPTS=['DIR:panda/src/downloadertools', 'ADVAPI', 'WINSOCK2', 'WINSHELL', 'WINGDI', 'WINUSER'] TargetAdd('pdecrypt_pdecrypt.obj', opts=OPTS, input='pdecrypt.cxx') TargetAdd('pdecrypt.exe', input=['pdecrypt_pdecrypt.obj']) @@ -4168,7 +4271,7 @@ if (PkgSkip("OPENSSL")==0 and PkgSkip("DEPLOYTOOLS")==0): # if (PkgSkip("ZLIB")==0 and PkgSkip("DEPLOYTOOLS")==0): - OPTS=['DIR:panda/src/downloadertools', 'ZLIB', 'OPENSSL', 'ADVAPI', 'WINSOCK2', 'WINSHELL', 'WINGDI', 'WINUSER'] + OPTS=['DIR:panda/src/downloadertools', 'ZLIB', 'ADVAPI', 'WINSOCK2', 'WINSHELL', 'WINGDI', 'WINUSER'] TargetAdd('multify_multify.obj', opts=OPTS, input='multify.cxx') TargetAdd('multify.exe', input=['multify_multify.obj']) @@ -4717,7 +4820,7 @@ if (PkgSkip("DIRECT")==0): OPTS=['DIR:direct/src/dcparser', 'BUILDING:DIRECT_DCPARSER', 'WITHINPANDA', 'BISONPREFIX_dcyy'] CreateFile(GetOutputDir()+"/include/dcParser.h") TargetAdd('p3dcparser_dcParser.obj', opts=OPTS, input='dcParser.yxx') - #TargetAdd('dcParser.h', input='p3dcparser_dcParser.obj', opts=['DEPENDENCYONLY']) + TargetAdd('dcParser.h', input='p3dcparser_dcParser.obj', opts=['DEPENDENCYONLY']) TargetAdd('p3dcparser_dcLexer.obj', opts=OPTS, input='dcLexer.lxx') TargetAdd('p3dcparser_composite1.obj', opts=OPTS, input='p3dcparser_composite1.cxx') TargetAdd('p3dcparser_composite2.obj', opts=OPTS, input='p3dcparser_composite2.cxx') @@ -4748,10 +4851,10 @@ if (PkgSkip("DIRECT")==0): # if (PkgSkip("DIRECT")==0): - OPTS=['DIR:direct/src/distributed', 'DIR:direct/src/dcparser', 'WITHINPANDA', 'BUILDING:DIRECT', 'OPENSSL'] + OPTS=['DIR:direct/src/distributed', 'DIR:direct/src/dcparser', 'WITHINPANDA', 'BUILDING:DIRECT'] TargetAdd('p3distributed_config_distributed.obj', opts=OPTS, input='config_distributed.cxx') - OPTS=['DIR:direct/src/distributed', 'WITHINPANDA', 'OPENSSL'] + OPTS=['DIR:direct/src/distributed', 'WITHINPANDA'] IGATEFILES=GetDirectoryContents('direct/src/distributed', ["*.h", "*.cxx"]) TargetAdd('libp3distributed.in', opts=OPTS, input=IGATEFILES) TargetAdd('libp3distributed.in', opts=['IMOD:panda3d.direct', 'ILIB:libp3distributed', 'SRCDIR:direct/src/distributed']) @@ -4819,7 +4922,7 @@ if (PkgSkip("DIRECT")==0): TargetAdd('libp3direct.dll', input='p3motiontrail_config_motiontrail.obj') TargetAdd('libp3direct.dll', input='p3motiontrail_cMotionTrail.obj') TargetAdd('libp3direct.dll', input=COMMON_PANDA_LIBS) - TargetAdd('libp3direct.dll', opts=['ADVAPI', 'OPENSSL', 'WINUSER', 'WINGDI']) + TargetAdd('libp3direct.dll', opts=['ADVAPI', 'WINUSER', 'WINGDI']) PyTargetAdd('direct_module.obj', input='libp3dcparser.in') PyTargetAdd('direct_module.obj', input='libp3showbase.in') @@ -4847,7 +4950,7 @@ if (PkgSkip("DIRECT")==0): PyTargetAdd('direct.pyd', input='libp3direct.dll') PyTargetAdd('direct.pyd', input='libp3interrogatedb.dll') PyTargetAdd('direct.pyd', input=COMMON_PANDA_LIBS) - PyTargetAdd('direct.pyd', opts=['OPENSSL', 'WINUSER', 'WINGDI', 'WINSOCK2']) + PyTargetAdd('direct.pyd', opts=['WINUSER', 'WINGDI', 'WINSOCK2']) # # DIRECTORY: direct/src/dcparse/ diff --git a/makepanda/makepanda.vcproj b/makepanda/makepanda.vcproj index 288a50784d..f777f99a85 100644 --- a/makepanda/makepanda.vcproj +++ b/makepanda/makepanda.vcproj @@ -3848,7 +3848,6 @@ - @@ -3859,7 +3858,6 @@ - diff --git a/makepanda/makewheel.py b/makepanda/makewheel.py index f1129a133d..a62417588f 100644 --- a/makepanda/makewheel.py +++ b/makepanda/makewheel.py @@ -92,7 +92,7 @@ EXCLUDE_EXT = [".pyc", ".pyo", ".N", ".prebuilt", ".xcf", ".plist", ".vcproj", " # Plug-ins to install. PLUGIN_LIBS = ["pandagl", "pandagles", "pandagles2", "pandadx9", "p3tinydisplay", "p3ptloader", "p3assimp", "p3ffmpeg", "p3openal_audio", "p3fmod_audio"] -# Libraries included in manylinux ABI that should be ignored. See PEP 513/571. +# Libraries included in manylinux ABI that should be ignored. See PEP 513/571/599. MANYLINUX_LIBS = [ "libgcc_s.so.1", "libstdc++.so.6", "libm.so.6", "libdl.so.2", "librt.so.1", "libcrypt.so.1", "libc.so.6", "libnsl.so.1", "libutil.so.1", @@ -530,10 +530,14 @@ def makewheel(version, output_dir, platform=None): else: print("Could not find platform.dat in build directory") platform = get_platform() - if platform.startswith("linux-"): - # Is this manylinux1? - if os.path.isfile("/lib/libc-2.5.so") and os.path.isdir("/opt/python"): + if platform.startswith("linux-") and os.path.isdir("/opt/python"): + # Is this manylinux? + if os.path.isfile("/lib/libc-2.5.so") or os.path.isfile("/lib64/libc-2.5.so"): platform = platform.replace("linux", "manylinux1") + elif os.path.isfile("/lib/libc-2.12.so") or os.path.isfile("/lib64/libc-2.12.so"): + platform = platform.replace("linux", "manylinux2010") + elif os.path.isfile("/lib/libc-2.17.so") or os.path.isfile("/lib64/libc-2.17.so"): + platform = platform.replace("linux", "manylinux2014") platform = platform.replace('-', '_').replace('.', '_') @@ -735,7 +739,12 @@ if __debug__: pylib_path = os.path.join(get_config_var('LIBDIR'), pylib_name) else: pylib_name = get_config_var('LDLIBRARY') - pylib_path = os.path.join(get_config_var('LIBDIR'), pylib_name) + pylib_arch = get_config_var('MULTIARCH') + libdir = get_config_var('LIBDIR') + if pylib_arch and os.path.exists(os.path.join(libdir, pylib_arch, pylib_name)): + pylib_path = os.path.join(libdir, pylib_arch, pylib_name) + else: + pylib_path = os.path.join(libdir, pylib_name) whl.write_file('deploy_libs/' + pylib_name, pylib_path) whl.close() diff --git a/makepanda/selfdestruct.py b/makepanda/selfdestruct.py new file mode 100755 index 0000000000..67d0303c20 --- /dev/null +++ b/makepanda/selfdestruct.py @@ -0,0 +1,47 @@ +#!/usr/bin/env python2 + +import os +import re +import sys +import shutil + +# Ensure user WANTS th +if len(sys.argv) < 2 or sys.argv[1] != '--yes': + print('======== MAKEPANDA SELF-DESTRUCT ========') + print('This script will destroy every trace of') + print('makepanda from the Panda3D directory that') + print('contains it. This is for testing CMake\'s') + print('dependencies and fully removing makepanda') + print('should the latter buildsystem no longer') + print('be desired.') + print('') + print('If you are sure, pass --yes') + sys.exit(1) + +# Some sanity-checks to make sure this script is in the right location: +scriptdir = os.path.abspath(os.path.dirname(__file__)) +assert os.path.split(scriptdir)[1] == 'makepanda' +root = os.path.dirname(scriptdir) +assert os.path.isfile(os.path.join(root, 'LICENSE')) +assert os.path.isdir(os.path.join(root, 'pandatool')) + +# Now we get to work! First, the makepanda directory isn't needed: +shutil.rmtree(os.path.join(root, 'makepanda')) + +# Then we look under each of the separate project trees: +projects = ['contrib', 'direct', 'dtool', 'panda', 'pandatool'] +for project in projects: + # Remove non-CMakeLists.txt files from */metalibs/*/ + for path, dirs, files in os.walk(os.path.join(root, project, 'metalibs')): + for filename in files: + if filename.lower() != 'cmakelists.txt': + os.unlink(os.path.join(path, filename)) + # Unlink the directory itself, if empty + if not os.listdir(path): + os.rmdir(path) + + for path, dirs, files in os.walk(os.path.join(root, project)): + # Get rid of _composite#.cxx files + for filename in files: + if re.match(r'.*_composite[0-9]*\.(cxx|h|mm)', filename): + os.unlink(os.path.join(path, filename)) diff --git a/panda/CMakeLists.txt b/panda/CMakeLists.txt new file mode 100644 index 0000000000..a545ef14bd --- /dev/null +++ b/panda/CMakeLists.txt @@ -0,0 +1,174 @@ +if(NOT BUILD_DTOOL) + message(FATAL_ERROR "Cannot build panda without dtool! Please enable the BUILD_DTOOL option.") +endif() + +# Include panda source directories +add_subdirectory(src/audio) +add_subdirectory(src/audiotraits) +add_subdirectory(src/chan) +add_subdirectory(src/char) +add_subdirectory(src/cocoadisplay) +add_subdirectory(src/collide) +add_subdirectory(src/configfiles) +add_subdirectory(src/cull) +add_subdirectory(src/device) +add_subdirectory(src/dgraph) +add_subdirectory(src/display) +add_subdirectory(src/distort) +add_subdirectory(src/downloader) +add_subdirectory(src/downloadertools) +add_subdirectory(src/dxgsg9) +add_subdirectory(src/dxml) +add_subdirectory(src/egg) +add_subdirectory(src/egg2pg) +add_subdirectory(src/egldisplay) +add_subdirectory(src/event) +add_subdirectory(src/express) +add_subdirectory(src/ffmpeg) +add_subdirectory(src/framework) +add_subdirectory(src/glesgsg) +add_subdirectory(src/gles2gsg) +add_subdirectory(src/glgsg) +add_subdirectory(src/glstuff) +add_subdirectory(src/glxdisplay) +add_subdirectory(src/gobj) +add_subdirectory(src/grutil) +add_subdirectory(src/gsgbase) +add_subdirectory(src/linmath) +add_subdirectory(src/mathutil) +add_subdirectory(src/movies) +add_subdirectory(src/nativenet) +add_subdirectory(src/net) +add_subdirectory(src/pandabase) +add_subdirectory(src/parametrics) +add_subdirectory(src/pgraph) +add_subdirectory(src/pgraphnodes) +add_subdirectory(src/pgui) +add_subdirectory(src/pipeline) +add_subdirectory(src/pnmimage) +add_subdirectory(src/pnmimagetypes) +add_subdirectory(src/pnmtext) +add_subdirectory(src/pstatclient) +add_subdirectory(src/putil) +add_subdirectory(src/recorder) +add_subdirectory(src/testbed) +add_subdirectory(src/text) +add_subdirectory(src/tform) +add_subdirectory(src/vision) +add_subdirectory(src/vrpn) +add_subdirectory(src/wgldisplay) +add_subdirectory(src/windisplay) +add_subdirectory(src/x11display) + +# For other components +# bullet +add_subdirectory(src/bullet) +# ode +add_subdirectory(src/ode) +# physics +add_subdirectory(src/particlesystem) +add_subdirectory(src/physics) + +# Include panda metalibs +add_subdirectory(metalibs/panda) +add_subdirectory(metalibs/pandadx9) +add_subdirectory(metalibs/pandaegg) +add_subdirectory(metalibs/pandaexpress) +add_subdirectory(metalibs/pandagl) +add_subdirectory(metalibs/pandagles) +add_subdirectory(metalibs/pandagles2) +add_subdirectory(metalibs/pandaphysics) + +# Now add the Python modules: +set(CORE_MODULE_COMPONENTS + p3chan p3char p3collide p3cull p3device p3dgraph p3display + p3downloader p3dxml p3event p3express p3gobj p3grutil p3gsgbase p3linmath + p3mathutil p3movies p3parametrics p3pgraph p3pgraphnodes p3pgui + p3pipeline p3pnmimage p3pstatclient p3putil p3recorder p3text p3tform + p3prc p3dtoolutil p3dtoolbase +) + +if(WANT_NATIVE_NET) + list(APPEND CORE_MODULE_COMPONENTS p3nativenet) + if(HAVE_NET) + list(APPEND CORE_MODULE_COMPONENTS p3net) + endif() +endif() + +if(HAVE_AUDIO) + list(APPEND CORE_MODULE_COMPONENTS p3audio) +endif() + +if(HAVE_FREETYPE) + list(APPEND CORE_MODULE_COMPONENTS p3pnmtext) +endif() + +if(INTERROGATE_PYTHON_INTERFACE) + add_python_module(panda3d.core ${CORE_MODULE_COMPONENTS} LINK panda) + + # Generate our __init__.py + if(WIN32) + file(READ "${PROJECT_SOURCE_DIR}/cmake/templates/win32_python/__init__.py" win32_init) + else() + set(win32_init "") + endif() + + file(WRITE "${PROJECT_BINARY_DIR}/panda3d/__init__.py" + "\"Python bindings for the Panda3D libraries\" + +__version__ = '${PROJECT_VERSION}' + +if __debug__: + import sys + if sys.version_info < (3, 0): + sys.stderr.write('''\\ +WARNING: Python 2.7 has reached EOL as of January 1, 2020. +To suppress this warning, upgrade to Python 3. +''') + sys.stdout.flush() + del sys + +${win32_init}") + + if(BUILD_SHARED_LIBS) + install_python_package(panda3d ARCH) + endif() + + if(HAVE_BULLET) + add_python_module(panda3d.bullet p3bullet IMPORT panda3d.core COMPONENT BulletPython) + + export_targets(BulletPython NAMESPACE "Panda3D::Python::" COMPONENT BulletDevel) + endif() + + if(HAVE_EGG) + add_python_module(panda3d.egg p3egg p3egg2pg LINK pandaegg IMPORT panda3d.core COMPONENT EggPython) + + export_targets(EggPython NAMESPACE "Panda3D::Python::" COMPONENT EggDevel) + endif() + + add_python_module(panda3d.fx pandafx IMPORT panda3d.core) + add_python_module(panda3d.physics p3physics p3particlesystem LINK pandaphysics IMPORT panda3d.core) + + if(HAVE_ODE) + add_python_module(panda3d.ode p3ode IMPORT panda3d.core COMPONENT ODEPython) + + export_targets(ODEPython NAMESPACE "Panda3D::Python::" COMPONENT ODEDevel) + endif() + + if(HAVE_OPENCV OR HAVE_ARTOOLKIT) + add_python_module(panda3d.vision p3vision IMPORT panda3d.core COMPONENT VisionPython) + + export_targets(VisionPython NAMESPACE "Panda3D::Python::" COMPONENT VisionDevel) + endif() + + if(HAVE_VRPN) + add_python_module(panda3d.vrpn p3vrpn IMPORT panda3d.core COMPONENT VRPNPython) + set_target_properties(panda3d.vrpn PROPERTIES CXX_EXCEPTIONS ON) + + export_targets(VRPNPython NAMESPACE "Panda3D::Python::" COMPONENT VRPNDevel) + endif() + + export_targets(Python NAMESPACE "Panda3D::Python::" COMPONENT CoreDevel) +endif() + +export_targets(Core COMPONENT CoreDevel) diff --git a/panda/metalibs/panda/CMakeLists.txt b/panda/metalibs/panda/CMakeLists.txt new file mode 100644 index 0000000000..d9dd160c8b --- /dev/null +++ b/panda/metalibs/panda/CMakeLists.txt @@ -0,0 +1,32 @@ +set(PANDA_LINK_TARGETS + p3chan p3char p3collide p3cull p3device p3dgraph p3display p3dxml + p3event p3gobj p3grutil p3gsgbase p3linmath p3mathutil + p3movies p3parametrics p3pgraph p3pgraphnodes p3pgui p3pipeline + p3pnmimage p3pnmimagetypes p3pstatclient p3putil p3recorder p3text p3tform +) + +if(WANT_NATIVE_NET) + list(APPEND PANDA_LINK_TARGETS p3nativenet) + if(HAVE_NET) + list(APPEND PANDA_LINK_TARGETS p3net) + endif() +endif() + +if(HAVE_AUDIO) + list(APPEND PANDA_LINK_TARGETS p3audio) +endif() + +if(HAVE_FREETYPE) + list(APPEND PANDA_LINK_TARGETS p3pnmtext) +endif() + +set(CMAKE_INSTALL_DEFAULT_COMPONENT_NAME "CoreDevel") +add_metalib(panda INIT init_libpanda panda.h COMPONENTS ${PANDA_LINK_TARGETS}) +unset(CMAKE_INSTALL_DEFAULT_COMPONENT_NAME) + +install(TARGETS panda + EXPORT Core COMPONENT Core + DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d + ARCHIVE COMPONENT CoreDevel) diff --git a/panda/metalibs/pandadx9/CMakeLists.txt b/panda/metalibs/pandadx9/CMakeLists.txt new file mode 100644 index 0000000000..70c8e2ff3a --- /dev/null +++ b/panda/metalibs/pandadx9/CMakeLists.txt @@ -0,0 +1,18 @@ +if(NOT HAVE_DX9) + return() +endif() + +set(CMAKE_INSTALL_DEFAULT_COMPONENT_NAME "DX9Devel") +add_metalib(pandadx9 ${MODULE_TYPE} + INCLUDE wdxGraphicsPipe9.h + INIT init_libpandadx9 pandadx9.h + EXPORT int get_pipe_type_pandadx9 "wdxGraphicsPipe9::get_class_type().get_index()" + COMPONENTS p3dxgsg9 p3windisplay) +unset(CMAKE_INSTALL_DEFAULT_COMPONENT_NAME) + +install(TARGETS pandadx9 + EXPORT DX9 COMPONENT DX9 + DESTINATION ${MODULE_DESTINATION} + ARCHIVE COMPONENT DX9Devel) + +export_targets(DX9 COMPONENT DX9Devel) diff --git a/panda/metalibs/pandaegg/CMakeLists.txt b/panda/metalibs/pandaegg/CMakeLists.txt new file mode 100644 index 0000000000..b8c4ba3730 --- /dev/null +++ b/panda/metalibs/pandaegg/CMakeLists.txt @@ -0,0 +1,19 @@ +if(NOT HAVE_EGG) + return() +endif() + +set(CMAKE_INSTALL_DEFAULT_COMPONENT_NAME "EggDevel") +add_metalib(pandaegg + INIT init_libpandaegg pandaegg.h + COMPONENTS p3egg p3egg2pg) +unset(CMAKE_INSTALL_DEFAULT_COMPONENT_NAME) +target_link_libraries(pandaegg panda) + +install(TARGETS pandaegg + EXPORT Egg COMPONENT Egg + DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d + ARCHIVE COMPONENT EggDevel) + +export_targets(Egg COMPONENT EggDevel) diff --git a/panda/metalibs/pandaexpress/CMakeLists.txt b/panda/metalibs/pandaexpress/CMakeLists.txt new file mode 100644 index 0000000000..0132dea0e9 --- /dev/null +++ b/panda/metalibs/pandaexpress/CMakeLists.txt @@ -0,0 +1,12 @@ +set(CMAKE_INSTALL_DEFAULT_COMPONENT_NAME "CoreDevel") +add_metalib(pandaexpress + INIT init_libpandaexpress pandaexpress.h + COMPONENTS p3downloader p3express) +unset(CMAKE_INSTALL_DEFAULT_COMPONENT_NAME) + +install(TARGETS pandaexpress + EXPORT Core COMPONENT Core + DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d + ARCHIVE COMPONENT CoreDevel) diff --git a/panda/metalibs/pandagl/CMakeLists.txt b/panda/metalibs/pandagl/CMakeLists.txt new file mode 100644 index 0000000000..f3bd4e8db9 --- /dev/null +++ b/panda/metalibs/pandagl/CMakeLists.txt @@ -0,0 +1,45 @@ +if(NOT HAVE_GL) + return() +endif() + +set(PANDAGL_LINK_TARGETS p3glgsg p3glstuff) + +if(HAVE_GLX) + list(APPEND PANDAGL_LINK_TARGETS p3glxdisplay p3x11display) + set(PANDAGL_PIPE_TYPE "glxGraphicsPipe") + +elseif(HAVE_WGL) + list(APPEND PANDAGL_LINK_TARGETS p3wgldisplay p3windisplay) + set(PANDAGL_PIPE_TYPE "wglGraphicsPipe") + +elseif(HAVE_COCOA) + list(APPEND PANDAGL_LINK_TARGETS p3cocoadisplay) + set(PANDAGL_PIPE_TYPE "CocoaGraphicsPipe") + set(PANDAGL_PIPE_INCLUDE "cocoaGraphicsPipe.h") + +else() + message("") # Add extra line before error + message(SEND_ERROR + "When compiling with OpenGL (HAVE_GL), at least one of: + HAVE_WGL, HAVE_COCOA, or HAVE_GLX must be defined.") + +endif() + +if(NOT PANDAGL_PIPE_INCLUDE) + set(PANDAGL_PIPE_INCLUDE "${PANDAGL_PIPE_TYPE}.h") +endif() + +set(CMAKE_INSTALL_DEFAULT_COMPONENT_NAME "OpenGLDevel") +add_metalib(pandagl ${MODULE_TYPE} + INCLUDE "${PANDAGL_PIPE_INCLUDE}" + INIT init_libpandagl pandagl.h + EXPORT int get_pipe_type_pandagl "${PANDAGL_PIPE_TYPE}::get_class_type().get_index()" + COMPONENTS ${PANDAGL_LINK_TARGETS}) +unset(CMAKE_INSTALL_DEFAULT_COMPONENT_NAME) + +install(TARGETS pandagl + EXPORT OpenGL COMPONENT OpenGL + DESTINATION ${MODULE_DESTINATION} + ARCHIVE COMPONENT OpenGLDevel) + +export_targets(OpenGL NAMESPACE "Panda3D::OpenGL::" COMPONENT OpenGLDevel) diff --git a/panda/metalibs/pandagles/CMakeLists.txt b/panda/metalibs/pandagles/CMakeLists.txt new file mode 100644 index 0000000000..d8563d4993 --- /dev/null +++ b/panda/metalibs/pandagles/CMakeLists.txt @@ -0,0 +1,28 @@ +if(NOT HAVE_GLES1 OR NOT HAVE_EGL) + return() +endif() + +if(ANDROID) + set(GLES1_PIPE_TYPE "AndroidGraphicsPipe") + set(GLES1_PIPE_INCLUDE "androidGraphicsPipe.h") + +else() + set(GLES1_PIPE_TYPE "eglGraphicsPipe") + set(GLES1_PIPE_INCLUDE "eglGraphicsPipe.h") + +endif() + +set(CMAKE_INSTALL_DEFAULT_COMPONENT_NAME "OpenGLES1Devel") +add_metalib(pandagles ${MODULE_TYPE} + INCLUDE "${GLES1_PIPE_INCLUDE}" + INIT init_libpandagles pandagles.h + EXPORT int get_pipe_type_pandagles "${GLES1_PIPE_TYPE}::get_class_type().get_index()" + COMPONENTS p3egldisplay_gles1 p3glesgsg p3glstuff p3x11display) +unset(CMAKE_INSTALL_DEFAULT_COMPONENT_NAME) + +install(TARGETS pandagles + EXPORT OpenGLES1 COMPONENT OpenGLES1 + DESTINATION ${MODULE_DESTINATION} + ARCHIVE COMPONENT OpenGLES1Devel) + +export_targets(OpenGLES1 COMPONENT OpenGLES1Devel) diff --git a/panda/metalibs/pandagles2/CMakeLists.txt b/panda/metalibs/pandagles2/CMakeLists.txt new file mode 100644 index 0000000000..f3e90f9dfb --- /dev/null +++ b/panda/metalibs/pandagles2/CMakeLists.txt @@ -0,0 +1,18 @@ +if(NOT HAVE_GLES2 OR NOT HAVE_EGL) + return() +endif() + +set(CMAKE_INSTALL_DEFAULT_COMPONENT_NAME "OpenGLES2Devel") +add_metalib(pandagles2 ${MODULE_TYPE} + INCLUDE eglGraphicsPipe.h + INIT init_libpandagles2 pandagles2.h + EXPORT int get_pipe_type_pandagles2 "eglGraphicsPipe::get_class_type().get_index()" + COMPONENTS p3egldisplay_gles2 p3gles2gsg p3glstuff p3x11display) +unset(CMAKE_INSTALL_DEFAULT_COMPONENT_NAME) + +install(TARGETS pandagles2 + EXPORT OpenGLES2 COMPONENT OpenGLES2 + DESTINATION ${MODULE_DESTINATION} + ARCHIVE COMPONENT OpenGLES2Devel) + +export_targets(OpenGLES2 COMPONENT OpenGLES2Devel) diff --git a/panda/metalibs/pandaphysics/CMakeLists.txt b/panda/metalibs/pandaphysics/CMakeLists.txt new file mode 100644 index 0000000000..49041f5973 --- /dev/null +++ b/panda/metalibs/pandaphysics/CMakeLists.txt @@ -0,0 +1,12 @@ +set(CMAKE_INSTALL_DEFAULT_COMPONENT_NAME "CoreDevel") +add_metalib(pandaphysics + INIT init_libpandaphysics pandaphysics.h + COMPONENTS p3physics p3particlesystem) +unset(CMAKE_INSTALL_DEFAULT_COMPONENT_NAME) + +install(TARGETS pandaphysics + EXPORT Core COMPONENT Core + DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d + ARCHIVE COMPONENT CoreDevel) diff --git a/panda/src/audio/CMakeLists.txt b/panda/src/audio/CMakeLists.txt new file mode 100644 index 0000000000..3d37816b00 --- /dev/null +++ b/panda/src/audio/CMakeLists.txt @@ -0,0 +1,39 @@ +if(NOT HAVE_AUDIO) + return() +endif() + +set(P3AUDIO_HEADERS + config_audio.h + filterProperties.h filterProperties.I + audioLoadRequest.h audioLoadRequest.I + audioManager.h audioManager.I + audioSound.h audioSound.I + nullAudioManager.h + nullAudioSound.h +) + +set(P3AUDIO_SOURCES + config_audio.cxx + filterProperties.cxx + audioLoadRequest.cxx + audioManager.cxx + audioSound.cxx + nullAudioManager.cxx + nullAudioSound.cxx +) + +composite_sources(p3audio P3AUDIO_SOURCES) +add_component_library(p3audio NOINIT SYMBOL BUILDING_PANDA_AUDIO + ${P3AUDIO_HEADERS} ${P3AUDIO_SOURCES}) +target_link_libraries(p3audio p3putil p3event p3movies p3linmath) +target_interrogate(p3audio ALL) + +if(NOT BUILD_METALIBS) + install(TARGETS p3audio + EXPORT Core COMPONENT Core + DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d + ARCHIVE COMPONENT CoreDevel) +endif() +install(FILES ${P3AUDIO_HEADERS} COMPONENT CoreDevel DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d) diff --git a/panda/src/audio/audioManager.cxx b/panda/src/audio/audioManager.cxx index cae10e675c..39f7588307 100644 --- a/panda/src/audio/audioManager.cxx +++ b/panda/src/audio/audioManager.cxx @@ -21,7 +21,7 @@ #include "config_putil.h" #include "load_dso.h" -#ifdef WIN32 +#ifdef _WIN32 #include // For GetSystemDirectory() #endif @@ -285,7 +285,7 @@ get_dls_pathname() { return dls_filename; } -#ifdef WIN32 +#ifdef _WIN32 Filename pathname; // Get the registry key from DirectMusic diff --git a/panda/src/audio/config_audio.h b/panda/src/audio/config_audio.h index 895ee000e4..deac9704be 100644 --- a/panda/src/audio/config_audio.h +++ b/panda/src/audio/config_audio.h @@ -22,7 +22,7 @@ #include "configVariableString.h" #include "configVariableFilename.h" -#if defined(WIN32_VC) || defined(WIN64_VC) +#ifdef _MVC_VER #pragma warning (disable : 4231) #endif diff --git a/panda/src/audiotraits/CMakeLists.txt b/panda/src/audiotraits/CMakeLists.txt new file mode 100644 index 0000000000..27b70e1bb6 --- /dev/null +++ b/panda/src/audiotraits/CMakeLists.txt @@ -0,0 +1,61 @@ +if(NOT HAVE_AUDIO) + return() +elseif(NOT HAVE_FMODEX AND NOT HAVE_OPENAL) + message(SEND_ERROR + "You must have an audio backend for audio support! Turn off HAVE_AUDIO to ignore this.") +endif() + +if(HAVE_FMODEX) + set(P3FMOD_HEADERS + config_fmodAudio.h + fmodAudioManager.h + fmodAudioSound.I fmodAudioSound.h + ) + + set(P3FMOD_SOURCES + config_fmodAudio.cxx fmodAudioManager.cxx fmodAudioSound.cxx + ) + + composite_sources(p3fmod_audio P3FMOD_SOURCES) + add_library(p3fmod_audio ${MODULE_TYPE} ${P3FMOD_HEADERS} ${P3FMOD_SOURCES}) + set_target_properties(p3fmod_audio PROPERTIES DEFINE_SYMBOL BUILDING_FMOD_AUDIO) + target_link_libraries(p3fmod_audio panda PKG::FMODEX) + + install(TARGETS p3fmod_audio + EXPORT FMOD COMPONENT FMOD + DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d + ARCHIVE COMPONENT FMODDevel) + install(FILES ${P3FMOD_HEADERS} COMPONENT FMODDevel DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d) + + export_targets(FMOD NAMESPACE "Panda3D::FMOD::" COMPONENT FMODDevel) +endif() + +if(HAVE_OPENAL) + set(P3OPENAL_HEADERS + config_openalAudio.h + openalAudioManager.h + openalAudioSound.I openalAudioSound.h + ) + + set(P3OPENAL_SOURCES + config_openalAudio.cxx openalAudioManager.cxx openalAudioSound.cxx + ) + + + composite_sources(p3openal_audio P3OPENAL_SOURCES) + add_library(p3openal_audio ${MODULE_TYPE} ${P3OPENAL_HEADERS} ${P3OPENAL_SOURCES}) + set_target_properties(p3openal_audio PROPERTIES DEFINE_SYMBOL BUILDING_OPENAL_AUDIO) + target_link_libraries(p3openal_audio panda PKG::OPENAL) + + install(TARGETS p3openal_audio + EXPORT OpenAL COMPONENT OpenAL + DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d + ARCHIVE COMPONENT OpenALDevel) + install(FILES ${P3OPENAL_HEADERS} COMPONENT OpenALDevel DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d) + + export_targets(OpenAL NAMESPACE "Panda3D::OpenAL::" COMPONENT OpenALDevel) +endif() diff --git a/panda/src/bullet/CMakeLists.txt b/panda/src/bullet/CMakeLists.txt new file mode 100644 index 0000000000..26c6b8762e --- /dev/null +++ b/panda/src/bullet/CMakeLists.txt @@ -0,0 +1,130 @@ +if(NOT HAVE_BULLET) + return() +endif() + +set(P3BULLET_HEADERS + config_bullet.h + bullet_includes.h + bullet_utils.I bullet_utils.h + bulletAllHitsRayResult.I bulletAllHitsRayResult.h + bulletBaseCharacterControllerNode.I bulletBaseCharacterControllerNode.h + bulletBodyNode.I bulletBodyNode.h + bulletBoxShape.I bulletBoxShape.h + bulletCapsuleShape.I bulletCapsuleShape.h + bulletCharacterControllerNode.I bulletCharacterControllerNode.h + bulletClosestHitRayResult.I bulletClosestHitRayResult.h + bulletClosestHitSweepResult.I bulletClosestHitSweepResult.h + bulletConeShape.I bulletConeShape.h + bulletConeTwistConstraint.I bulletConeTwistConstraint.h + bulletConstraint.I bulletConstraint.h + bulletContactCallbackData.I bulletContactCallbackData.h + bulletContactCallbacks.h + bulletContactResult.I bulletContactResult.h + bulletConvexHullShape.I bulletConvexHullShape.h + bulletConvexPointCloudShape.I bulletConvexPointCloudShape.h + bulletCylinderShape.I bulletCylinderShape.h + bulletDebugNode.I bulletDebugNode.h + bulletFilterCallbackData.I bulletFilterCallbackData.h + bulletGenericConstraint.I bulletGenericConstraint.h + bulletGhostNode.I bulletGhostNode.h + bulletHeightfieldShape.I bulletHeightfieldShape.h + bulletHelper.I bulletHelper.h + bulletHingeConstraint.I bulletHingeConstraint.h + bulletManifoldPoint.I bulletManifoldPoint.h + bulletMinkowskiSumShape.I bulletMinkowskiSumShape.h + bulletMultiSphereShape.I bulletMultiSphereShape.h + bulletPersistentManifold.I bulletPersistentManifold.h + bulletPlaneShape.I bulletPlaneShape.h + bulletRigidBodyNode.I bulletRigidBodyNode.h + bulletRotationalLimitMotor.I bulletRotationalLimitMotor.h + bulletShape.I bulletShape.h + bulletSliderConstraint.I bulletSliderConstraint.h + bulletSoftBodyConfig.I bulletSoftBodyConfig.h + bulletSoftBodyControl.I bulletSoftBodyControl.h + bulletSoftBodyMaterial.I bulletSoftBodyMaterial.h + bulletSoftBodyNode.I bulletSoftBodyNode.h + bulletSoftBodyShape.I bulletSoftBodyShape.h + bulletSoftBodyWorldInfo.I bulletSoftBodyWorldInfo.h + bulletSphereShape.I bulletSphereShape.h + bulletSphericalConstraint.I bulletSphericalConstraint.h + bulletTickCallbackData.I bulletTickCallbackData.h + bulletTranslationalLimitMotor.I bulletTranslationalLimitMotor.h + bulletTriangleMesh.I bulletTriangleMesh.h + bulletTriangleMeshShape.I bulletTriangleMeshShape.h + bulletVehicle.I bulletVehicle.h + bulletWheel.I bulletWheel.h + bulletWorld.I bulletWorld.h +) + +set(P3BULLET_SOURCES + config_bullet.cxx + bullet_utils.cxx + bulletAllHitsRayResult.cxx + bulletBaseCharacterControllerNode.cxx + bulletBodyNode.cxx + bulletBoxShape.cxx + bulletCapsuleShape.cxx + bulletCharacterControllerNode.cxx + bulletClosestHitRayResult.cxx + bulletClosestHitSweepResult.cxx + bulletConeShape.cxx + bulletConeTwistConstraint.cxx + bulletConstraint.cxx + bulletContactCallbackData.cxx + bulletContactResult.cxx + bulletConvexHullShape.cxx + bulletConvexPointCloudShape.cxx + bulletCylinderShape.cxx + bulletDebugNode.cxx + bulletFilterCallbackData.cxx + bulletGenericConstraint.cxx + bulletGhostNode.cxx + bulletHeightfieldShape.cxx + bulletHelper.cxx + bulletHingeConstraint.cxx + bulletManifoldPoint.cxx + bulletMinkowskiSumShape.cxx + bulletMultiSphereShape.cxx + bulletPersistentManifold.cxx + bulletPlaneShape.cxx + bulletRigidBodyNode.cxx + bulletRotationalLimitMotor.cxx + bulletShape.cxx + bulletSliderConstraint.cxx + bulletSoftBodyConfig.cxx + bulletSoftBodyControl.cxx + bulletSoftBodyMaterial.cxx + bulletSoftBodyNode.cxx + bulletSoftBodyShape.cxx + bulletSoftBodyWorldInfo.cxx + bulletSphereShape.cxx + bulletSphericalConstraint.cxx + bulletTickCallbackData.cxx + bulletTranslationalLimitMotor.cxx + bulletTriangleMesh.cxx + bulletTriangleMeshShape.cxx + bulletVehicle.cxx + bulletWheel.cxx + bulletWorld.cxx +) + +composite_sources(p3bullet P3BULLET_SOURCES) +add_library(p3bullet ${P3BULLET_SOURCES} ${P3BULLET_HEADERS}) +set_target_properties(p3bullet PROPERTIES DEFINE_SYMBOL BUILDING_PANDABULLET) +target_link_libraries(p3bullet panda PKG::BULLET) +target_interrogate(p3bullet ALL) + +if(MSVC AND CMAKE_CXX_COMPILER_ID STREQUAL "Clang") + # Clang emulating MSVC; it has builtin defines for __m128 + __m128 and co. + target_compile_definitions(p3bullet PUBLIC BT_NO_SIMD_OPERATOR_OVERLOADS) +endif() + +install(TARGETS p3bullet + EXPORT Bullet COMPONENT Bullet + DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d + ARCHIVE COMPONENT BulletDevel) +install(FILES ${P3BULLET_HEADERS} COMPONENT BulletDevel DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d) + +export_targets(Bullet COMPONENT BulletDevel) diff --git a/panda/src/bullet/bulletHeightfieldShape.cxx b/panda/src/bullet/bulletHeightfieldShape.cxx index 08f91bd036..55ed86d16e 100644 --- a/panda/src/bullet/bulletHeightfieldShape.cxx +++ b/panda/src/bullet/bulletHeightfieldShape.cxx @@ -200,7 +200,7 @@ fillin(DatagramIterator &scan, BamReader *manager) { size_t size = (size_t)_num_rows * (size_t)_num_cols; delete [] _data; - _data = new float[size]; + _data = new btScalar[size]; for (size_t i = 0; i < size; ++i) { _data[i] = scan.get_stdfloat(); diff --git a/panda/src/chan/CMakeLists.txt b/panda/src/chan/CMakeLists.txt new file mode 100644 index 0000000000..0b1565d198 --- /dev/null +++ b/panda/src/chan/CMakeLists.txt @@ -0,0 +1,69 @@ +set(P3CHAN_HEADERS + animBundle.I animBundle.h + animBundleNode.I animBundleNode.h + animChannel.I animChannel.h animChannelBase.I + animChannelBase.h + animChannelFixed.I animChannelFixed.h + animChannelMatrixDynamic.I animChannelMatrixDynamic.h + animChannelMatrixFixed.I animChannelMatrixFixed.h + animChannelMatrixXfmTable.I animChannelMatrixXfmTable.h + animChannelScalarDynamic.I animChannelScalarDynamic.h + animChannelScalarTable.I animChannelScalarTable.h + animControl.I + animControl.h animControlCollection.I + animControlCollection.h animGroup.I animGroup.h + animPreloadTable.I animPreloadTable.h + auto_bind.h + bindAnimRequest.I bindAnimRequest.h + config_chan.h + movingPart.I movingPart.h + movingPartBase.I movingPartBase.h + movingPartMatrix.I movingPartMatrix.h movingPartScalar.I + movingPartScalar.h partBundle.I partBundle.h + partBundleHandle.I partBundleHandle.h + partBundleNode.I partBundleNode.h + partGroup.I partGroup.h + partSubset.I partSubset.h + vector_PartGroupStar.h +) + +set(P3CHAN_SOURCES + animBundle.cxx + animBundleNode.cxx + animChannel.cxx + animChannelBase.cxx + animChannelFixed.cxx + animChannelMatrixDynamic.cxx + animChannelMatrixFixed.cxx + animChannelMatrixXfmTable.cxx + animChannelScalarDynamic.cxx + animChannelScalarTable.cxx + animControl.cxx + animControlCollection.cxx animGroup.cxx + animPreloadTable.cxx + auto_bind.cxx + bindAnimRequest.cxx + config_chan.cxx movingPartBase.cxx movingPartMatrix.cxx + movingPartScalar.cxx partBundle.cxx + partBundleHandle.cxx + partBundleNode.cxx + partGroup.cxx + partSubset.cxx + vector_PartGroupStar.cxx +) + +composite_sources(p3chan P3CHAN_SOURCES) +add_component_library(p3chan NOINIT SYMBOL BUILDING_PANDA_CHAN + ${P3CHAN_HEADERS} ${P3CHAN_SOURCES}) +target_link_libraries(p3chan p3pgraph) +target_interrogate(p3chan ALL) + +if(NOT BUILD_METALIBS) + install(TARGETS p3chan + EXPORT Core COMPONENT Core + DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d + ARCHIVE COMPONENT CoreDevel) +endif() +install(FILES ${P3CHAN_HEADERS} COMPONENT CoreDevel DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d) diff --git a/panda/src/chan/animChannelScalarTable.h b/panda/src/chan/animChannelScalarTable.h index 10e54815e3..db92167f56 100644 --- a/panda/src/chan/animChannelScalarTable.h +++ b/panda/src/chan/animChannelScalarTable.h @@ -30,9 +30,10 @@ protected: AnimChannelScalarTable(); AnimChannelScalarTable(AnimGroup *parent, const AnimChannelScalarTable ©); -public: +PUBLISHED: AnimChannelScalarTable(AnimGroup *parent, const std::string &name); +public: virtual bool has_changed(int last_frame, double last_frac, int this_frame, double this_frac); virtual void get_value(int frame, PN_stdfloat &value); diff --git a/panda/src/chan/movingPartScalar.I b/panda/src/chan/movingPartScalar.I index 1b585746e4..e67dad0562 100644 --- a/panda/src/chan/movingPartScalar.I +++ b/panda/src/chan/movingPartScalar.I @@ -25,7 +25,7 @@ MovingPartScalar(const MovingPartScalar ©) : */ INLINE MovingPartScalar:: MovingPartScalar(PartGroup *parent, const std::string &name, - const PN_stdfloat &default_value) + PN_stdfloat default_value) : MovingPart(parent, name, default_value) { } diff --git a/panda/src/chan/movingPartScalar.h b/panda/src/chan/movingPartScalar.h index d05e58f4e7..ee55f2e7b8 100644 --- a/panda/src/chan/movingPartScalar.h +++ b/panda/src/chan/movingPartScalar.h @@ -31,7 +31,7 @@ protected: public: INLINE MovingPartScalar(PartGroup *parent, const std::string &name, - const PN_stdfloat &default_value = 0); + PN_stdfloat default_value = 0); virtual ~MovingPartScalar(); virtual void get_blend_value(const PartBundle *root); diff --git a/panda/src/chan/partBundleNode.I b/panda/src/chan/partBundleNode.I index e9da42359c..d1e2e5597f 100644 --- a/panda/src/chan/partBundleNode.I +++ b/panda/src/chan/partBundleNode.I @@ -46,6 +46,7 @@ PartBundleNode(const PartBundleNode ©) : */ INLINE int PartBundleNode:: get_num_bundles() const { + LightMutexHolder holder(_lock); return _bundles.size(); } @@ -54,6 +55,7 @@ get_num_bundles() const { */ INLINE PartBundle *PartBundleNode:: get_bundle(int n) const { + LightMutexHolder holder(_lock); nassertr(n >= 0 && n < (int)_bundles.size(), nullptr); return _bundles[n]->get_bundle(); } @@ -65,6 +67,7 @@ get_bundle(int n) const { */ INLINE PartBundleHandle *PartBundleNode:: get_bundle_handle(int n) const { + LightMutexHolder holder(_lock); nassertr(n >= 0 && n < (int)_bundles.size(), nullptr); return _bundles[n]; } diff --git a/panda/src/chan/partBundleNode.cxx b/panda/src/chan/partBundleNode.cxx index 9fe5473fe0..5d54b194e4 100644 --- a/panda/src/chan/partBundleNode.cxx +++ b/panda/src/chan/partBundleNode.cxx @@ -25,9 +25,9 @@ TypeHandle PartBundleNode::_type_handle; */ PartBundleNode:: ~PartBundleNode() { - Bundles::iterator bi; - for (bi = _bundles.begin(); bi != _bundles.end(); ++bi) { - (*bi)->get_bundle()->remove_node(this); + LightMutexHolder holder(_lock); + for (PartBundleHandle *handle : _bundles) { + handle->get_bundle()->remove_node(this); } } @@ -44,9 +44,8 @@ void PartBundleNode:: apply_attribs_to_vertices(const AccumulatedAttribs &attribs, int attrib_types, GeomTransformer &transformer) { if ((attrib_types & SceneGraphReducer::TT_transform) != 0) { - Bundles::iterator bi; - for (bi = _bundles.begin(); bi != _bundles.end(); ++bi) { - PT(PartBundleHandle) handle = (*bi); + LightMutexHolder holder(_lock); + for (PT(PartBundleHandle) handle : _bundles) { PartBundle *bundle = handle->get_bundle(); PT(PartBundle) new_bundle = bundle->apply_transform(attribs._transform); update_bundle(handle, new_bundle); @@ -71,9 +70,8 @@ xform(const LMatrix4 &mat) { return; } - Bundles::iterator bi; - for (bi = _bundles.begin(); bi != _bundles.end(); ++bi) { - PT(PartBundleHandle) handle = (*bi); + LightMutexHolder holder(_lock); + for (PT(PartBundleHandle) handle : _bundles) { PartBundle *bundle = handle->get_bundle(); if (bundle->get_num_nodes() > 1) { PT(PartBundle) new_bundle = DCAST(PartBundle, bundle->copy_subgraph()); @@ -90,14 +88,15 @@ xform(const LMatrix4 &mat) { void PartBundleNode:: add_bundle(PartBundle *bundle) { PT(PartBundleHandle) handle = new PartBundleHandle(bundle); - add_bundle_handle(handle); + LightMutexHolder holder(_lock); + do_add_bundle_handle(handle); } /** - * + * Assumes the lock is held. */ void PartBundleNode:: -add_bundle_handle(PartBundleHandle *handle) { +do_add_bundle_handle(PartBundleHandle *handle) { Bundles::iterator bi = find(_bundles.begin(), _bundles.end(), handle); if (bi != _bundles.end()) { // This handle is already within the node. @@ -117,11 +116,15 @@ steal_bundles(PartBundleNode *other) { return; } - Bundles::iterator bi; - for (bi = other->_bundles.begin(); bi != other->_bundles.end(); ++bi) { - PartBundleHandle *handle = (*bi); + LightMutexHolder other_holder(other->_lock); + if (other->_bundles.empty()) { + return; + } + + LightMutexHolder holder(_lock); + for (PartBundleHandle *handle : other->_bundles) { handle->get_bundle()->remove_node(other); - add_bundle_handle(handle); + do_add_bundle_handle(handle); } other->_bundles.clear(); } @@ -129,6 +132,8 @@ steal_bundles(PartBundleNode *other) { /** * Replaces the contents of the indicated PartBundleHandle (presumably stored * within this node) with new_bundle. + * + * Assumes the lock is held. */ void PartBundleNode:: update_bundle(PartBundleHandle *old_bundle_handle, PartBundle *new_bundle) { @@ -146,10 +151,10 @@ void PartBundleNode:: write_datagram(BamWriter *manager, Datagram &dg) { PandaNode::write_datagram(manager, dg); + LightMutexHolder holder(_lock); dg.add_uint16(_bundles.size()); - Bundles::iterator bi; - for (bi = _bundles.begin(); bi != _bundles.end(); ++bi) { - manager->write_pointer(dg, (*bi)->get_bundle()); + for (PartBundleHandle *handle : _bundles) { + manager->write_pointer(dg, handle->get_bundle()); } } @@ -161,11 +166,11 @@ int PartBundleNode:: complete_pointers(TypedWritable **p_list, BamReader* manager) { int pi = PandaNode::complete_pointers(p_list, manager); - Bundles::iterator bi; - for (bi = _bundles.begin(); bi != _bundles.end(); ++bi) { + LightMutexHolder holder(_lock); + for (PT(PartBundleHandle) &handle : _bundles) { PT(PartBundle) bundle = DCAST(PartBundle, p_list[pi++]); bundle->add_node(this); - (*bi) = new PartBundleHandle(bundle); + handle = new PartBundleHandle(bundle); } return pi; diff --git a/panda/src/chan/partBundleNode.h b/panda/src/chan/partBundleNode.h index 6cb98638d1..a681af1d7c 100644 --- a/panda/src/chan/partBundleNode.h +++ b/panda/src/chan/partBundleNode.h @@ -18,7 +18,7 @@ #include "partBundle.h" #include "partBundleHandle.h" - +#include "lightMutex.h" #include "pandaNode.h" #include "dcast.h" #include "pvector.h" @@ -59,12 +59,13 @@ PUBLISHED: protected: void add_bundle(PartBundle *bundle); - void add_bundle_handle(PartBundleHandle *handle); + void do_add_bundle_handle(PartBundleHandle *handle); void steal_bundles(PartBundleNode *other); virtual void update_bundle(PartBundleHandle *old_bundle_handle, PartBundle *new_bundle); protected: + LightMutex _lock; typedef pvector< PT(PartBundleHandle) > Bundles; Bundles _bundles; diff --git a/panda/src/char/CMakeLists.txt b/panda/src/char/CMakeLists.txt new file mode 100644 index 0000000000..d33bd470b0 --- /dev/null +++ b/panda/src/char/CMakeLists.txt @@ -0,0 +1,36 @@ +set(P3CHAR_HEADERS + character.I character.h + characterJoint.I characterJoint.h + characterJointBundle.I characterJointBundle.h + characterJointEffect.h characterJointEffect.I + characterSlider.h + characterVertexSlider.I characterVertexSlider.h + config_char.h + jointVertexTransform.I jointVertexTransform.h +) + +set(P3CHAR_SOURCES + character.cxx + characterJoint.cxx characterJointBundle.cxx + characterJointEffect.cxx + characterSlider.cxx + characterVertexSlider.cxx + config_char.cxx + jointVertexTransform.cxx +) + +composite_sources(p3char P3CHAR_SOURCES) +add_component_library(p3char SYMBOL BUILDING_PANDA_CHAR + ${P3CHAR_HEADERS} ${P3CHAR_SOURCES}) +target_link_libraries(p3char p3chan) +target_interrogate(p3char ALL) + +if(NOT BUILD_METALIBS) + install(TARGETS p3char + EXPORT Core COMPONENT Core + DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d + ARCHIVE COMPONENT CoreDevel) +endif() +install(FILES ${P3CHAR_HEADERS} COMPONENT CoreDevel DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d) diff --git a/panda/src/char/character.cxx b/panda/src/char/character.cxx index eb894fe99c..d25b4e96ee 100644 --- a/panda/src/char/character.cxx +++ b/panda/src/char/character.cxx @@ -44,29 +44,29 @@ Character(const Character ©, bool copy_bundles) : _lod_delay_factor(copy._lod_delay_factor), _do_lod_animation(copy._do_lod_animation), _joints_pcollector(copy._joints_pcollector), - _skinning_pcollector(copy._skinning_pcollector) + _skinning_pcollector(copy._skinning_pcollector), + _last_auto_update(-1.0), + _view_frame(-1), + _view_distance2(0.0f) { set_cull_callback(); + LightMutexHolder holder(copy._lock); + if (copy_bundles) { // Copy the bundle(s). - int num_bundles = copy.get_num_bundles(); - for (int i = 0; i < num_bundles; ++i) { - PartBundle *orig_bundle = copy.get_bundle(i); + for (PartBundleHandle *handle : copy._bundles) { + PartBundle *orig_bundle = handle->get_bundle(); PT(PartBundle) new_bundle = DCAST(PartBundle, orig_bundle->copy_subgraph()); - add_bundle(new_bundle); + do_add_bundle_handle(new PartBundleHandle(new_bundle)); } } else { // Share the bundles. - int num_bundles = copy.get_num_bundles(); - for (int i = 0; i < num_bundles; ++i) { - PartBundle *orig_bundle = copy.get_bundle(i); - add_bundle(orig_bundle); + for (PartBundleHandle *handle : copy._bundles) { + PartBundle *orig_bundle = handle->get_bundle(); + do_add_bundle_handle(new PartBundleHandle(orig_bundle)); } } - _last_auto_update = -1.0; - _view_frame = -1; - _view_distance2 = 0.0f; } /** @@ -76,13 +76,13 @@ Character:: Character(const std::string &name) : PartBundleNode(name, new CharacterJointBundle(name)), _joints_pcollector(PStatCollector(_animation_pcollector, name), "Joints"), - _skinning_pcollector(PStatCollector(_animation_pcollector, name), "Vertices") + _skinning_pcollector(PStatCollector(_animation_pcollector, name), "Vertices"), + _last_auto_update(-1.0), + _view_frame(-1), + _view_distance2(0.0f) { set_cull_callback(); clear_lod_animation(); - _last_auto_update = -1.0; - _view_frame = -1; - _view_distance2 = 0.0f; } /** @@ -90,9 +90,9 @@ Character(const std::string &name) : */ Character:: ~Character() { - int num_bundles = get_num_bundles(); - for (int i = 0; i < num_bundles; ++i) { - r_clear_joint_characters(get_bundle(i)); + LightMutexHolder holder(_lock); + for (PartBundleHandle *handle : _bundles) { + r_clear_joint_characters(handle->get_bundle()); } } @@ -237,36 +237,6 @@ calc_tight_bounds(LPoint3 &min_point, LPoint3 &max_point, bool &found_any, found_any, transform, current_thread); } -/** - * Merges old_bundle with new_bundle. old_bundle must be one of the - * PartBundles within this node. At the end of this call, the old_bundle - * pointer within this node will be replaced with the new_bundle pointer, and - * all geometry within this node will be updated to reference new_bundle. - * - * @deprecated Use the newer version of this method, below. - */ -void Character:: -merge_bundles(PartBundle *old_bundle, PartBundle *new_bundle) { - if (old_bundle == new_bundle) { - // Trivially return. - return; - } - - // Find the PartBundleHandle of old_bundle. - PT(PartBundleHandle) old_bundle_handle; - Bundles::const_iterator bi; - for (bi = _bundles.begin(); bi != _bundles.end(); ++bi) { - if ((*bi)->get_bundle() == old_bundle) { - old_bundle_handle = (*bi); - break; - } - } - nassertv(!old_bundle_handle.is_null()); - - PT(PartBundleHandle) new_bundle_handle = new PartBundleHandle(new_bundle); - merge_bundles(old_bundle_handle, new_bundle_handle); -} - /** * Merges old_bundle_handle->get_bundle() with new_bundle. old_bundle_handle * must be one of the PartBundleHandle within this node. At the end of this @@ -293,6 +263,7 @@ merge_bundles(PartBundleHandle *old_bundle_handle, PartBundle *new_bundle = new_bundle_handle->get_bundle(); new_bundle->merge_anim_preloads(old_bundle); + LightMutexHolder holder(_lock); update_bundle(old_bundle_handle, new_bundle); } @@ -356,11 +327,11 @@ clear_lod_animation() { */ CharacterJoint *Character:: find_joint(const std::string &name) const { - int num_bundles = get_num_bundles(); - for (int i = 0; i < num_bundles; ++i) { - PartGroup *part = get_bundle(i)->find_child(name); + LightMutexHolder holder(_lock); + for (PartBundleHandle *handle : _bundles) { + PartGroup *part = handle->get_bundle()->find_child(name); if (part != nullptr && part->is_character_joint()) { - return DCAST(CharacterJoint, part); + return (CharacterJoint *)part; } } @@ -374,12 +345,12 @@ find_joint(const std::string &name) const { */ CharacterSlider *Character:: find_slider(const std::string &name) const { - int num_bundles = get_num_bundles(); - for (int i = 0; i < num_bundles; ++i) { - PartGroup *part = get_bundle(i)->find_child(name); + LightMutexHolder holder(_lock); + for (PartBundleHandle *handle : _bundles) { + PartGroup *part = handle->get_bundle()->find_child(name); if (part != nullptr && part->is_of_type(CharacterSlider::get_class_type())) { - return DCAST(CharacterSlider, part); + return (CharacterSlider *)part; } } @@ -392,9 +363,9 @@ find_slider(const std::string &name) const { */ void Character:: write_parts(std::ostream &out) const { - int num_bundles = get_num_bundles(); - for (int i = 0; i < num_bundles; ++i) { - get_bundle(i)->write(out, 0); + LightMutexHolder holder(_lock); + for (PartBundleHandle *handle : _bundles) { + handle->get_bundle()->write(out, 0); } } @@ -405,9 +376,9 @@ write_parts(std::ostream &out) const { */ void Character:: write_part_values(std::ostream &out) const { - int num_bundles = get_num_bundles(); - for (int i = 0; i < num_bundles; ++i) { - get_bundle(i)->write_with_value(out, 0); + LightMutexHolder holder(_lock); + for (PartBundleHandle *handle : _bundles) { + handle->get_bundle()->write_with_value(out, 0); } } @@ -431,6 +402,7 @@ update_to_now() { */ void Character:: update() { + LightMutexHolder holder(_lock); double now = ClockObject::get_global_clock()->get_frame_time(); if (now != _last_auto_update) { _last_auto_update = now; @@ -451,13 +423,14 @@ update() { */ void Character:: force_update() { + LightMutexHolder holder(_lock); + // Statistics PStatTimer timer(_joints_pcollector); // Update all the joints and sliders. - int num_bundles = get_num_bundles(); - for (int i = 0; i < num_bundles; ++i) { - get_bundle(i)->force_update(); + for (PartBundleHandle *handle : _bundles) { + handle->get_bundle()->force_update(); } } @@ -486,11 +459,13 @@ r_copy_children(const PandaNode *from, PandaNode::InstanceMap &inst_map, NodeMap node_map; JointMap joint_map; - int num_bundles = get_num_bundles(); - nassertv(from_char->get_num_bundles() == num_bundles); - int i; - for (i = 0; i < num_bundles; ++i) { - fill_joint_map(joint_map, get_bundle(i), from_char->get_bundle(i)); + LightMutexHolder from_holder(from_char->_lock); + LightMutexHolder holder(_lock); + + size_t num_bundles = _bundles.size(); + nassertv(from_char->_bundles.size() == num_bundles); + for (size_t i = 0; i < num_bundles; ++i) { + fill_joint_map(joint_map, _bundles[i]->get_bundle(), from_char->_bundles[i]->get_bundle()); } GeomVertexMap gvmap; @@ -499,14 +474,16 @@ r_copy_children(const PandaNode *from, PandaNode::InstanceMap &inst_map, r_copy_char(this, from_char, from_char, node_map, joint_map, gvmap, gjmap, gsmap); - for (i = 0; i < num_bundles; ++i) { - copy_node_pointers(node_map, get_bundle(i), from_char->get_bundle(i)); + for (size_t i = 0; i < num_bundles; ++i) { + copy_node_pointers(node_map, _bundles[i]->get_bundle(), from_char->_bundles[i]->get_bundle()); } } /** * Replaces the contents of the indicated PartBundleHandle (presumably stored * within this node) with new_bundle. + * + * Assumes the lock is held. */ void Character:: update_bundle(PartBundleHandle *old_bundle_handle, PartBundle *new_bundle) { @@ -560,20 +537,18 @@ get_rel_transform(CullTraverser *trav, CullTraverserData &data) { /** * The actual implementation of update(). Assumes the appropriate - * PStatCollector has already been started. + * PStatCollector has already been started, and that the lock is held. */ void Character:: do_update() { // Update all the joints and sliders. if (even_animation) { - int num_bundles = get_num_bundles(); - for (int i = 0; i < num_bundles; ++i) { - get_bundle(i)->force_update(); + for (PartBundleHandle *handle : _bundles) { + handle->get_bundle()->force_update(); } } else { - int num_bundles = get_num_bundles(); - for (int i = 0; i < num_bundles; ++i) { - get_bundle(i)->update(); + for (PartBundleHandle *handle : _bundles) { + handle->get_bundle()->update(); } } } @@ -584,9 +559,9 @@ do_update() { */ void Character:: set_lod_current_delay(double delay) { - int num_bundles = get_num_bundles(); - for (int i = 0; i < num_bundles; ++i) { - get_bundle(i)->set_update_delay(delay); + LightMutexHolder holder(_lock); + for (PartBundleHandle *handle : _bundles) { + handle->get_bundle()->set_update_delay(delay); } } @@ -594,6 +569,8 @@ set_lod_current_delay(double delay) { * After the joint hierarchy has already been copied from the indicated * hierarchy, this recursively walks through the joints and builds up a * mapping from old to new. + * + * Assumes the lock is held. */ void Character:: fill_joint_map(Character::JointMap &joint_map, @@ -624,6 +601,8 @@ fill_joint_map(Character::JointMap &joint_map, * Recursively checks the two bundles for a matching hierarchy, and adds nodes * as necessary to "new_group" where they are not already present. Also fills * joint_map in the same manner as fill_joint_map(). + * + * Assumes the lock is held. */ void Character:: r_merge_bundles(Character::JointMap &joint_map, @@ -730,11 +709,12 @@ r_merge_bundles(Character::JointMap &joint_map, new_group->_children.swap(new_children); } - /** * Recursively walks the scene graph hierarchy below the Character node, * duplicating it while noting the orig:copy node mappings, and also updates * any GeomNodes found. + * + * Assumes the lock is held. */ void Character:: r_copy_char(PandaNode *dest, const PandaNode *source, diff --git a/panda/src/char/character.h b/panda/src/char/character.h index a7c6c79f13..83aa754ee8 100644 --- a/panda/src/char/character.h +++ b/panda/src/char/character.h @@ -59,7 +59,6 @@ PUBLISHED: virtual PandaNode *combine_with(PandaNode *other); INLINE CharacterJointBundle *get_bundle(int i) const; - void merge_bundles(PartBundle *old_bundle, PartBundle *other_bundle); void merge_bundles(PartBundleHandle *old_bundle_handle, PartBundleHandle *other_bundle_handle); diff --git a/panda/src/char/characterSlider.cxx b/panda/src/char/characterSlider.cxx index b4ced5e782..26d0f35053 100644 --- a/panda/src/char/characterSlider.cxx +++ b/panda/src/char/characterSlider.cxx @@ -40,8 +40,9 @@ CharacterSlider(const CharacterSlider ©) : * */ CharacterSlider:: -CharacterSlider(PartGroup *parent, const std::string &name) - : MovingPartScalar(parent, name) { +CharacterSlider(PartGroup *parent, const std::string &name, + PN_stdfloat default_value) + : MovingPartScalar(parent, name, default_value) { } /** diff --git a/panda/src/char/characterSlider.h b/panda/src/char/characterSlider.h index 9871095afd..6a5da971b8 100644 --- a/panda/src/char/characterSlider.h +++ b/panda/src/char/characterSlider.h @@ -31,7 +31,8 @@ protected: CharacterSlider(const CharacterSlider ©); PUBLISHED: - explicit CharacterSlider(PartGroup *parent, const std::string &name); + explicit CharacterSlider(PartGroup *parent, const std::string &name, + PN_stdfloat default_value = 0); virtual ~CharacterSlider(); public: diff --git a/panda/src/cocoadisplay/CMakeLists.txt b/panda/src/cocoadisplay/CMakeLists.txt new file mode 100644 index 0000000000..ed6e4ca521 --- /dev/null +++ b/panda/src/cocoadisplay/CMakeLists.txt @@ -0,0 +1,47 @@ +if(NOT APPLE OR NOT HAVE_GL OR NOT HAVE_COCOA) + return() +endif() + +set(P3COCOADISPLAY_HEADERS + config_cocoadisplay.h + cocoaGraphicsBuffer.h cocoaGraphicsBuffer.I + cocoaGraphicsPipe.h cocoaGraphicsPipe.I + cocoaGraphicsWindow.h cocoaGraphicsWindow.I + cocoaGraphicsStateGuardian.h cocoaGraphicsStateGuardian.I + cocoaPandaApp.h + cocoaPandaView.h + cocoaPandaWindow.h + cocoaPandaWindowDelegate.h + cocoaPandaAppDelegate.h +) + +set(P3COCOADISPLAY_SOURCES + config_cocoadisplay.mm + cocoaGraphicsBuffer.mm + cocoaGraphicsPipe.mm + cocoaGraphicsStateGuardian.mm + cocoaGraphicsWindow.mm + cocoaPandaApp.mm + cocoaPandaView.mm + cocoaPandaWindow.mm + cocoaPandaWindowDelegate.mm + cocoaPandaAppDelegate.mm +) + +composite_sources(p3cocoadisplay P3COCOADISPLAY_SOURCES) +add_component_library(p3cocoadisplay SYMBOL BUILDING_PANDA_COCOADISPLAY + ${P3COCOADISPLAY_HEADERS} ${P3COCOADISPLAY_SOURCES}) +target_link_libraries(p3cocoadisplay p3glgsg panda) + +# Frameworks: +find_library(APPLICATIONSERVICES_LIBRARY ApplicationServices) +find_library(APPKIT_LIBRARY AppKit) +find_library(CARBON_LIBRARY Carbon) +find_library(CORE_VIDEO_LIBRARY CoreVideo) +target_link_libraries(p3cocoadisplay + ${APPLICATIONSERVICES_LIBRARY} ${APPKIT_LIBRARY} ${CARBON_LIBRARY} + ${CORE_VIDEO_LIBRARY}) + +if(NOT BUILD_METALIBS) + install(TARGETS p3cocoadisplay EXPORT OpenGL COMPONENT OpenGL DESTINATION ${CMAKE_INSTALL_LIBDIR}) +endif() diff --git a/panda/src/cocoadisplay/cocoaGraphicsWindow.h b/panda/src/cocoadisplay/cocoaGraphicsWindow.h index 5fb49093d3..1381339630 100644 --- a/panda/src/cocoadisplay/cocoaGraphicsWindow.h +++ b/panda/src/cocoadisplay/cocoaGraphicsWindow.h @@ -74,8 +74,11 @@ protected: virtual void mouse_mode_relative(); private: + NSData *load_image_data(const Filename &filename); NSImage *load_image(const Filename &filename); + NSCursor *load_cursor(const Filename &filename); + void handle_modifier(NSUInteger modifierFlags, NSUInteger mask, ButtonHandle button); ButtonHandle map_key(unsigned short c) const; ButtonHandle map_raw_key(unsigned short keycode) const; @@ -94,7 +97,7 @@ private: CGDisplayModeRef _fullscreen_mode; CGDisplayModeRef _windowed_mode; - typedef pmap IconImages; + typedef pmap IconImages; IconImages _images; public: diff --git a/panda/src/cocoadisplay/cocoaGraphicsWindow.mm b/panda/src/cocoadisplay/cocoaGraphicsWindow.mm index 7d19c6bb9e..1b941a5d84 100644 --- a/panda/src/cocoadisplay/cocoaGraphicsWindow.mm +++ b/panda/src/cocoadisplay/cocoaGraphicsWindow.mm @@ -568,17 +568,17 @@ open_window() { } if (_properties.has_cursor_filename()) { - NSImage *image = load_image(_properties.get_cursor_filename()); - NSCursor *cursor = nil; - // TODO: allow setting the hotspot, read it from file when loading .cur. - if (image != nil) { - cursor = [[NSCursor alloc] initWithImage:image hotSpot:NSMakePoint(0, 0)]; - } + NSCursor *cursor = load_cursor(_properties.get_cursor_filename()); + if (cursor != nil) { + if (_cursor != nil) { + [_cursor release]; + } _cursor = cursor; } else { _properties.clear_cursor_filename(); } + // This will ensure that NSView's resetCursorRects gets called, which sets // the appropriate cursor rects. [[_view window] invalidateCursorRectsForView:_view]; @@ -1031,19 +1031,15 @@ set_properties_now(WindowProperties &properties) { properties.set_cursor_filename(cursor_filename); properties.clear_cursor_filename(); } else { - NSImage *image = load_image(cursor_filename); - if (image != nil) { - NSCursor *cursor; - cursor = [[NSCursor alloc] initWithImage:image hotSpot:NSMakePoint(0, 0)]; - if (cursor != nil) { - // Replace the existing cursor. - if (_cursor != nil) { - [_cursor release]; - } - _cursor = cursor; - _properties.set_cursor_filename(cursor_filename); - properties.clear_cursor_filename(); + NSCursor *cursor = load_cursor(cursor_filename); + if (cursor != nil) { + // Replace the existing cursor. + if (_cursor != nil) { + [_cursor release]; } + _cursor = cursor; + _properties.set_cursor_filename(cursor_filename); + properties.clear_cursor_filename(); } } // This will ensure that NSView's resetCursorRects gets called, which sets @@ -1235,11 +1231,12 @@ do_switch_fullscreen(CGDisplayModeRef mode) { } /** - * Loads the indicated filename and returns an NSImage pointer, or NULL on - * failure. Must be called from the window thread. + * Loads the indicated filename and returns an NSData pointer (which can then + * be used to create a CGImageSource or NSImage), or NULL on failure. Must be + * called from the window thread. May return nil. */ -NSImage *CocoaGraphicsWindow:: -load_image(const Filename &filename) { +NSData *CocoaGraphicsWindow:: +load_image_data(const Filename &filename) { if (filename.empty()) { return nil; } @@ -1259,7 +1256,6 @@ load_image(const Filename &filename) { } // Look in our index. - NSImage *image = nil; IconImages::const_iterator it = _images.find(resolved); if (it != _images.end()) { // Found it. @@ -1269,7 +1265,7 @@ load_image(const Filename &filename) { cocoadisplay_cat.info() << "Loading NSImage from file " << resolved << "\n"; - PT(VirtualFile) vfile = vfs->get_file(filename); + PT(VirtualFile) vfile = vfs->get_file(resolved); if (vfile == NULL) { return nil; } @@ -1287,21 +1283,81 @@ load_image(const Filename &filename) { NSData *data = [NSData dataWithBytesNoCopy:buffer length:size]; if (data == nil) { + cocoadisplay_cat.error() + << "Could not load image data from file " << filename << "\n"; return nil; } - image = [[NSImage alloc] initWithData:data]; - [data release]; + _images[resolved] = data; + return data; +} + +/** + * Wraps image data loaded by load_image_data with an NSImage. The returned + * pointer is autoreleased. May return nil. + */ +NSImage *CocoaGraphicsWindow:: +load_image(const Filename &filename) { + NSData *image_data = load_image_data(filename); + NSImage *image = [[[NSImage alloc] initWithData:image_data] autorelease]; if (image == nil) { cocoadisplay_cat.error() << "Could not load image from file " << filename << "\n"; return nil; } - - _images[resolved] = image; return image; } +/** + * Returns a cursor with the proper hotspot if a .cur filename is passed in. + * You must release the returned pointer. May return nil. + */ +NSCursor *CocoaGraphicsWindow:: +load_cursor(const Filename &filename) { + NSData *image_data = load_image_data(cursor_filename); + if (image_data == nil) { + return nil; + } + + // Read the metadata from the image, which should contain hotspotX and + // hotspotY properties. + CGImageSourceRef cg_image = CGImageSourceCreateWithData((CFDataRef)image_data, nullptr); + if (cg_image == NULL) { + return nil; + } + + NSDictionary *image_props = (NSDictionary *)CGImageSourceCopyPropertiesAtIndex(cg_image, 0, nil); + CFRelease(cg_image); + + if (image_props == nil) { + return nil; + } + + CGFloat hotspot_x = 0.0f; + CGFloat hotspot_y = 0.0f; + if (NSNumber *number = image_props[@"hotspotX"]) { + hotspot_x = [number floatValue]; + } + if (NSNumber *number = image_props[@"hotspotY"]) { + hotspot_y = [number floatValue]; + } + [image_props release]; + + NSImage *image = [[NSImage alloc] initWithData:image_data]; + + NSCursor *cursor = nil; + if (image != nil) { + // Apple recognizes that hotspots are usually specified from a .cur + // file, whose origin is in the top-left, so there's no need to flip + // it like most other Cocoa coordinates. + cursor = [[NSCursor alloc] initWithImage:image + hotSpot:NSMakePoint(hotspot_x, hotspot_y)]; + [image release]; + } + + return cursor; +} + /** * Called by CocoaPandaView or the window delegate when the frame rect * changes. diff --git a/panda/src/collide/CMakeLists.txt b/panda/src/collide/CMakeLists.txt new file mode 100644 index 0000000000..63ac4163e8 --- /dev/null +++ b/panda/src/collide/CMakeLists.txt @@ -0,0 +1,82 @@ +set(P3COLLIDE_HEADERS + collisionBox.I collisionBox.h + collisionCapsule.I collisionCapsule.h + collisionEntry.I collisionEntry.h + collisionGeom.I collisionGeom.h + collisionHandler.I collisionHandler.h + collisionHandlerEvent.I collisionHandlerEvent.h + collisionHandlerHighestEvent.h + collisionHandlerFloor.I collisionHandlerFloor.h + collisionHandlerGravity.I collisionHandlerGravity.h + collisionHandlerPhysical.I collisionHandlerPhysical.h + collisionHandlerPusher.I collisionHandlerPusher.h + collisionHandlerFluidPusher.I collisionHandlerFluidPusher.h + collisionHandlerQueue.h + collisionInvSphere.I collisionInvSphere.h + collisionLine.I collisionLine.h + collisionLevelStateBase.I collisionLevelStateBase.h + collisionLevelState.I collisionLevelState.h + collisionNode.I collisionNode.h + collisionParabola.I collisionParabola.h + collisionPlane.I collisionPlane.h + collisionPolygon.I collisionPolygon.h + collisionFloorMesh.I collisionFloorMesh.h + collisionRay.I collisionRay.h + collisionRecorder.I collisionRecorder.h + collisionSegment.I collisionSegment.h + collisionSolid.I collisionSolid.h + collisionSphere.I collisionSphere.h + collisionTraverser.I collisionTraverser.h + collisionTube.h + collisionVisualizer.I collisionVisualizer.h + config_collide.h +) + +set(P3COLLIDE_SOURCES + collisionBox.cxx + collisionCapsule.cxx + collisionEntry.cxx + collisionGeom.cxx + collisionHandler.cxx + collisionHandlerEvent.cxx + collisionHandlerHighestEvent.cxx + collisionHandlerFloor.cxx + collisionHandlerGravity.cxx + collisionHandlerPhysical.cxx + collisionHandlerPusher.cxx + collisionHandlerFluidPusher.cxx + collisionHandlerQueue.cxx + collisionLevelStateBase.cxx + collisionLevelState.cxx + collisionInvSphere.cxx + collisionLine.cxx + collisionNode.cxx + collisionParabola.cxx + collisionPlane.cxx + collisionPolygon.cxx + collisionFloorMesh.cxx + collisionRay.cxx + collisionRecorder.cxx + collisionSegment.cxx + collisionSolid.cxx + collisionSphere.cxx + collisionTraverser.cxx + collisionVisualizer.cxx + config_collide.cxx +) + +composite_sources(p3collide P3COLLIDE_SOURCES) +add_component_library(p3collide SYMBOL BUILDING_PANDA_COLLIDE + ${P3COLLIDE_HEADERS} ${P3COLLIDE_SOURCES}) +target_link_libraries(p3collide p3tform) +target_interrogate(p3collide ALL) + +if(NOT BUILD_METALIBS) + install(TARGETS p3collide + EXPORT Core COMPONENT Core + DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d + ARCHIVE COMPONENT CoreDevel) +endif() +install(FILES ${P3COLLIDE_HEADERS} COMPONENT CoreDevel DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d) diff --git a/panda/src/configfiles/CMakeLists.txt b/panda/src/configfiles/CMakeLists.txt new file mode 100644 index 0000000000..58003c93e1 --- /dev/null +++ b/panda/src/configfiles/CMakeLists.txt @@ -0,0 +1,79 @@ +# Set some variables that are used in panda.prc.in. +set(AUX_DISPLAYS) + +if(HAVE_GL) + set(AUX_DISPLAYS "${AUX_DISPLAYS}\naux-display pandagl") +endif() + +if(HAVE_DX9) + set(AUX_DISPLAYS "${AUX_DISPLAYS}\naux-display pandadx9") +endif() + +if(HAVE_TINYDISPLAY) + set(AUX_DISPLAYS "${AUX_DISPLAYS}\naux-display p3tinydisplay") +endif() + +if(HAVE_OPENAL) + set(AUDIO_LIBRARY_NAME p3openal_audio) +elseif(HAVE_FMODEX) + set(AUDIO_LIBRARY_NAME p3fmod_audio) +else() + set(AUDIO_LIBRARY_NAME none) +endif() + +if(WIN32) + set(BAM_CACHE_DIR + "$USER_APPDATA/Panda3D-${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}") +elseif(APPLE) + set(BAM_CACHE_DIR + "$HOME/Library/Caches/Panda3D-${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}") +else() + set(BAM_CACHE_DIR + "$XDG_CACHE_HOME/panda3d") +endif() + +if(UNIX) + # On Unices, ask the GNUInstallDirs module where /etc is -- and then install + # ourselves into /etc/panda3d + set(prc_install_path "${CMAKE_INSTALL_FULL_SYSCONFDIR}/panda3d") + set(prc_build_path "${PANDA_OUTPUT_DIR}/etc/panda3d") +else() + set(prc_install_path "etc") + set(prc_build_path "${PANDA_OUTPUT_DIR}/etc") +endif() + +# Path from the directory containing *.prc to the directory containing plugins +file(RELATIVE_PATH PLUGINS_PATH + "${prc_build_path}" "${CMAKE_LIBRARY_OUTPUT_DIRECTORY}") + +# Path from the directory containing *.prc to the *parent of* models/ +# In the build tree, reckoning this is pretty easy +file(RELATIVE_PATH MODELS_PARENT_PATH "${prc_build_path}" "${PANDA_OUTPUT_DIR}") +configure_file(panda.prc.in "${CMAKE_CURRENT_BINARY_DIR}/20_panda.prc") + +# For the install tree, we need to introspect our paths +set(abs_prc_install_path "${prc_install_path}") +set(abs_datadir "${CMAKE_INSTALL_DATADIR}") +set(abs_plugindir "${MODULE_DESTINATION}") +if(NOT IS_ABSOLUTE "${abs_prc_install_path}") + set(abs_prc_install_path "${CMAKE_INSTALL_PREFIX}/${abs_prc_install_path}") +endif() +if(NOT IS_ABSOLUTE "${abs_datadir}") + set(abs_datadir "${CMAKE_INSTALL_PREFIX}/${abs_datadir}") +endif() +if(NOT IS_ABSOLUTE "${abs_plugindir}") + set(abs_plugindir "${CMAKE_INSTALL_PREFIX}/${abs_plugindir}") +endif() +file(RELATIVE_PATH PLUGINS_PATH + "${abs_prc_install_path}" "${abs_plugindir}") +file(RELATIVE_PATH MODELS_PARENT_PATH + "${abs_prc_install_path}" "${abs_datadir}/panda3d") +configure_file(panda.prc.in "${CMAKE_CURRENT_BINARY_DIR}/20_panda.prc.install") + +file(GENERATE OUTPUT "${prc_build_path}/20_panda.prc" + INPUT "${CMAKE_CURRENT_BINARY_DIR}/20_panda.prc") +file(GENERATE OUTPUT "${prc_build_path}/20_panda.prc.install" + INPUT "${CMAKE_CURRENT_BINARY_DIR}/20_panda.prc.install") + +install(FILES "${prc_build_path}/20_panda.prc.install" RENAME "20_panda.prc" + COMPONENT Core DESTINATION ${prc_install_path}) diff --git a/panda/src/configfiles/panda.prc.in b/panda/src/configfiles/panda.prc.in new file mode 100644 index 0000000000..bd04ccbe17 --- /dev/null +++ b/panda/src/configfiles/panda.prc.in @@ -0,0 +1,130 @@ +#### Generated automatically by CMake ${CMAKE_VERSION} from panda.prc.in. +################################# DO NOT EDIT ########################### + +# Some paths first... +plugin-path $THIS_PRC_DIR/${PLUGINS_PATH} +model-path $MAIN_DIR +model-path $THIS_PRC_DIR/${MODELS_PARENT_PATH} +model-path $THIS_PRC_DIR/${MODELS_PARENT_PATH}/models + +# Let's set up a default window size of 800x600. The user can +# override this in a separate, personal prc file. +win-origin -2 -2 +win-size 800 600 + +# For debugging, it's nice to have notify-level at the default setting of +# "info", but everywhere else we turn the verbosity down to "warning" +$<$:#>notify-level warning + +# Define the display types that have been compiled in. Panda will +# pick one of these by going through the list in this order until one +# is found that works, unless the user specifically requests a +# particular display type with the load-display directive. +${AUX_DISPLAYS} + +# Define an appropriate default audio library. +audio-library-name ${AUDIO_LIBRARY_NAME} + +# The egg loader is handy to have available by default. This allows +# clients to load egg files. (The bam loader is built-in so bam files +# are always loadable). + +# By qualifying with the extension "egg", we indicate the egg loader +# should be made available only if you explicitly name a file with an +# .egg extension. + +# Also see ptloader, which is built as part of pandatool; it allows +# files of more exotic types (like .flt, .mb, .lwo, and .dxf) to be +# loaded directly into Panda. + +load-file-type egg pandaegg +default-model-extension .egg + +# Enable the model-cache, but only for models, not textures. +model-cache-dir ${BAM_CACHE_DIR} +model-cache-textures #f + + +# These entries work very similar to load-file-type, except they are +# used by the MovieVideo and MovieAudio code to determine which module +# should be loaded in order to decode files of the given extension. + +# ffmpeg is added by default because it used to be compiled in. +# The * is a special catch-all extension that is consulted unless a +# loader has been defined with an explicit extension. + +load-audio-type * p3ffmpeg +load-video-type * p3ffmpeg + + +# The following lines define some handy object types to use within the +# egg syntax. This remaps { name } into whatever egg +# syntax is given by egg-object-type-name, which makes a handy +# abbreviation for modeling packages (like Maya) to insert +# sophisticated egg syntax into the generated egg file, using a single +# object type string. + +egg-object-type-portal portal { 1 } +egg-object-type-polylight polylight { 1 } +egg-object-type-seq24 { 1 } fps { 24 } +egg-object-type-seq12 { 1 } fps { 12 } +egg-object-type-seq10 { 1 } fps { 10 } +egg-object-type-seq8 { 1 } fps { 8 } +egg-object-type-seq6 { 1} fps { 6 } +egg-object-type-seq4 { 1} fps { 4 } +egg-object-type-seq2 { 1} fps { 2 } +egg-object-type-indexed indexed { 1 } + +egg-object-type-binary alpha { binary } +egg-object-type-dual alpha { dual } +egg-object-type-glass alpha { blend_no_occlude } + +# These are just shortcuts to define the Model and DCS flags, which +# indicate nodes that should not be flattened out of the hierarchy +# during the conversion process. DCS goes one step further and +# indicates that the node's transform is important and should be +# preserved (DCS stands for Dynamic Coordinate System). Notouch is +# even stronger, and means not to do any flattening below the node at +# all. +egg-object-type-model { 1 } +egg-object-type-dcs { 1 } +egg-object-type-notouch { no_touch } + +# The following define various kinds of collision geometry. These +# mark the geometry at this level and below as invisible collision +# polygons, which can be used by Panda's collision system to detect +# collisions more optimally than regular visible polygons. +egg-object-type-barrier { Polyset descend } +egg-object-type-sphere { Sphere descend } +egg-object-type-invsphere { InvSphere descend } +egg-object-type-tube { Tube descend } + +# As above, but these are flagged to be "intangible", so that they +# will trigger an event but not stop an object from passing through. +egg-object-type-trigger { Polyset descend intangible } +egg-object-type-trigger-sphere { Sphere descend intangible } + +# "floor" and "dupefloor" define the nodes in question as floor +# polygons. dupefloor means to duplicate the geometry first so that +# the same polygons serve both as visible geometry and as collision +# polygons. +egg-object-type-floor { Polyset descend level } +egg-object-type-dupefloor { Polyset keep descend level } + +# "bubble" puts an invisible bubble around an object, but does not +# otherwise remove the geometry. +egg-object-type-bubble { Sphere keep descend } + +# "ghost" turns off the normal collide bit that is set on visible +# geometry by default, so that if you are using visible geometry for +# collisions, this particular geometry will not be part of those +# collisions--it is ghostlike. +egg-object-type-ghost collide-mask { 0 } + +# "glow" is useful for halo effects and things of that ilk. It +# renders the object in add mode instead of the normal opaque mode. +egg-object-type-glow blend { add } + +# This isn't used in the egg loader, it controls a setting only within +# maya2egg itself. So if it appears in an egg file, it means nothing. +egg-object-type-keep-all-uvsets diff --git a/panda/src/cull/CMakeLists.txt b/panda/src/cull/CMakeLists.txt new file mode 100644 index 0000000000..0e5e099b00 --- /dev/null +++ b/panda/src/cull/CMakeLists.txt @@ -0,0 +1,37 @@ +set(P3CULL_HEADERS + binCullHandler.h binCullHandler.I + config_cull.h + cullBinBackToFront.h cullBinBackToFront.I + cullBinFixed.h cullBinFixed.I + cullBinFrontToBack.h cullBinFrontToBack.I + cullBinStateSorted.h cullBinStateSorted.I + cullBinUnsorted.h cullBinUnsorted.I + drawCullHandler.h drawCullHandler.I +) + +set(P3CULL_SOURCES + binCullHandler.cxx + config_cull.cxx + cullBinBackToFront.cxx + cullBinFixed.cxx + cullBinFrontToBack.cxx + cullBinStateSorted.cxx + cullBinUnsorted.cxx + drawCullHandler.cxx +) + +composite_sources(p3cull P3CULL_SOURCES) +add_component_library(p3cull SYMBOL BUILDING_PANDA_CULL + ${P3CULL_HEADERS} ${P3CULL_SOURCES}) +target_link_libraries(p3cull p3pgraph) +target_interrogate(p3cull ALL) + +if(NOT BUILD_METALIBS) + install(TARGETS p3cull + EXPORT Core COMPONENT Core + DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d + ARCHIVE COMPONENT CoreDevel) +endif() +install(FILES ${P3CULL_HEADERS} COMPONENT CoreDevel DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d) diff --git a/panda/src/device/CMakeLists.txt b/panda/src/device/CMakeLists.txt new file mode 100644 index 0000000000..f7c80e60f8 --- /dev/null +++ b/panda/src/device/CMakeLists.txt @@ -0,0 +1,80 @@ +set(P3DEVICE_HEADERS + analogNode.h analogNode.I + buttonNode.h buttonNode.I + clientAnalogDevice.h clientAnalogDevice.I + clientBase.h clientBase.I + clientButtonDevice.h clientButtonDevice.I + clientDevice.h clientDevice.I + clientDialDevice.h clientDialDevice.I + clientTrackerDevice.h clientTrackerDevice.I + config_device.h + dialNode.h dialNode.I + evdevInputDevice.h evdevInputDevice.I + inputDevice.h inputDevice.I + inputDeviceManager.h inputDeviceManager.I + inputDeviceNode.h + inputDeviceSet.h inputDeviceSet.I + ioKitInputDevice.h + ioKitInputDeviceManager.h + linuxInputDeviceManager.h + linuxJoystickDevice.h linuxJoystickDevice.I + trackerData.h trackerData.I + trackerNode.h trackerNode.I + virtualMouse.h + winInputDeviceManager.h + winRawInputDevice.h + xInputDevice.h +) + +set(P3DEVICE_SOURCES + analogNode.cxx + buttonNode.cxx + clientAnalogDevice.cxx + clientBase.cxx + clientButtonDevice.cxx + clientDevice.cxx + clientDialDevice.cxx + clientTrackerDevice.cxx + config_device.cxx + dialNode.cxx + evdevInputDevice.cxx + inputDevice.cxx + inputDeviceManager.cxx + inputDeviceNode.cxx + inputDeviceSet.cxx + ioKitInputDevice.cxx + ioKitInputDeviceManager.cxx + linuxInputDeviceManager.cxx + linuxJoystickDevice.cxx + trackerData.cxx + trackerNode.cxx + virtualMouse.cxx + winInputDeviceManager.cxx + winRawInputDevice.cxx + xInputDevice.cxx +) + +composite_sources(p3device P3DEVICE_SOURCES) +add_component_library(p3device SYMBOL BUILDING_PANDA_DEVICE + ${P3DEVICE_HEADERS} ${P3DEVICE_SOURCES}) +target_link_libraries(p3device p3dgraph) +target_interrogate(p3device ALL) + +if(WIN32) + target_link_libraries(p3device cfgmgr32.lib) + +elseif(APPLE) + find_library(IOKIT_LIBRARY IOKit) + target_link_libraries(p3device ${IOKIT_LIBRARY}) + +endif() + +if(NOT BUILD_METALIBS) + install(TARGETS p3device + EXPORT Core COMPONENT Core + DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d + ARCHIVE COMPONENT CoreDevel) +endif() +install(FILES ${P3DEVICE_HEADERS} COMPONENT CoreDevel DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d) diff --git a/panda/src/device/inputDeviceNode.cxx b/panda/src/device/inputDeviceNode.cxx index bdf849b93b..b5e749b2d6 100644 --- a/panda/src/device/inputDeviceNode.cxx +++ b/panda/src/device/inputDeviceNode.cxx @@ -54,7 +54,7 @@ void InputDeviceNode:: do_transmit_data(DataGraphTraverser *, const DataNodeTransmit &, DataNodeTransmit &output) { - if (_device == nullptr && !_device->is_connected()) { + if (_device == nullptr || !_device->is_connected()) { return; } diff --git a/panda/src/device/ioKitInputDevice.cxx b/panda/src/device/ioKitInputDevice.cxx index 079614a99f..e80dfccd94 100644 --- a/panda/src/device/ioKitInputDevice.cxx +++ b/panda/src/device/ioKitInputDevice.cxx @@ -23,15 +23,6 @@ #include "gamepadButton.h" #include "mouseButton.h" -static void removal_callback(void *ctx, IOReturn result, void *sender) { - // We need to hold a reference to this because it may otherwise be destroyed - // during the call to on_remove(). - PT(IOKitInputDevice) input_device = (IOKitInputDevice *)ctx; - nassertv(input_device != nullptr); - nassertv(input_device->test_ref_count_integrity()); - input_device->on_remove(); -} - /** * Protected constructor. */ @@ -139,7 +130,6 @@ IOKitInputDevice(IOHIDDeviceRef device) : } _is_connected = true; - IOHIDDeviceRegisterRemovalCallback(device, removal_callback, this); } /** @@ -149,31 +139,6 @@ IOKitInputDevice:: ~IOKitInputDevice() { } -/** - * The nonstatic version of on_remove_device. - */ -void IOKitInputDevice:: -on_remove() { - { - LightMutexHolder holder(_lock); - if (!_is_connected) { - return; - } - _is_connected = false; - } - - if (device_cat.is_debug()) { - device_cat.debug() - << "Removed input device " << *this << "\n"; - } - - IOHIDDeviceClose(_device, kIOHIDOptionsTypeNone); - - InputDeviceManager *mgr = InputDeviceManager::get_global_ptr(); - nassertv(mgr != nullptr); - mgr->remove_device(this); -} - /** * */ diff --git a/panda/src/device/ioKitInputDevice.h b/panda/src/device/ioKitInputDevice.h index f32f9c4256..e355a95826 100644 --- a/panda/src/device/ioKitInputDevice.h +++ b/panda/src/device/ioKitInputDevice.h @@ -30,8 +30,6 @@ public: IOKitInputDevice(IOHIDDeviceRef device); ~IOKitInputDevice(); - void on_remove(); - private: void parse_element(IOHIDElementRef element); diff --git a/panda/src/device/ioKitInputDeviceManager.cxx b/panda/src/device/ioKitInputDeviceManager.cxx index 6874d9baba..3f1c807469 100644 --- a/panda/src/device/ioKitInputDeviceManager.cxx +++ b/panda/src/device/ioKitInputDeviceManager.cxx @@ -59,6 +59,7 @@ IOKitInputDeviceManager() { CFRelease(match); IOHIDManagerRegisterDeviceMatchingCallback(_hid_manager, on_match_device, this); + IOHIDManagerRegisterDeviceRemovalCallback(_hid_manager, on_remove_device, this); IOHIDManagerScheduleWithRunLoop(_hid_manager, CFRunLoopGetMain(), kCFRunLoopCommonModes); IOHIDManagerOpen(_hid_manager, kIOHIDOptionsTypeNone); } @@ -78,16 +79,43 @@ IOKitInputDeviceManager:: */ void IOKitInputDeviceManager:: on_match_device(void *ctx, IOReturn result, void *sender, IOHIDDeviceRef device) { - InputDeviceManager *mgr = (InputDeviceManager *)ctx; + IOKitInputDeviceManager *mgr = (IOKitInputDeviceManager *)ctx; nassertv(mgr != nullptr); nassertv(device); - PT(InputDevice) input_device = new IOKitInputDevice(device); + IOKitInputDevice *input_device = new IOKitInputDevice(device); if (device_cat.is_debug()) { device_cat.debug() << "Discovered input device " << *input_device << "\n"; } mgr->add_device(input_device); + mgr->_devices_by_hidref[device] = input_device; } +/** + * Called by IOKit when an input device has disappeared. + */ +void IOKitInputDeviceManager:: +on_remove_device(void *ctx, IOReturn result, void *sender, IOHIDDeviceRef device) { + IOKitInputDeviceManager *mgr = (IOKitInputDeviceManager *)ctx; + nassertv(mgr != nullptr); + nassertv(device); + + auto it = mgr->_devices_by_hidref.find(device); + nassertv(it != mgr->_devices_by_hidref.end()); + IOKitInputDevice *input_device = it->second; + + input_device->set_connected(false); + + mgr->_devices_by_hidref.erase(device); + + IOHIDDeviceClose(device, kIOHIDOptionsTypeNone); + + if (device_cat.is_debug()) { + device_cat.debug() + << "Removed input device " << *input_device << "\n"; + } + + mgr->remove_device(input_device); +} #endif diff --git a/panda/src/device/ioKitInputDeviceManager.h b/panda/src/device/ioKitInputDeviceManager.h index f028a5f153..80005f99ab 100644 --- a/panda/src/device/ioKitInputDeviceManager.h +++ b/panda/src/device/ioKitInputDeviceManager.h @@ -19,6 +19,8 @@ #if defined(__APPLE__) && !defined(CPPPARSER) #include +class IOKitInputDevice; + /** * The macOS implementation of InputDeviceManager. */ @@ -30,7 +32,16 @@ protected: protected: IOHIDManagerRef _hid_manager; + // The device removal callback method we need to use requires us to remember + // which IOKitInputDevice corresponds to which IOHIDDeviceRef. This is the + // same strategy used by winInputDevice and friends. + // + // We can make this a mapping to raw pointers since we know _devices will be + // holding a reference until remove_device is called. + pmap _devices_by_hidref; + static void on_match_device(void *ctx, IOReturn result, void *sender, IOHIDDeviceRef device); + static void on_remove_device(void *ctx, IOReturn result, void *sender, IOHIDDeviceRef device); friend class InputDeviceManager; }; diff --git a/panda/src/device/winInputDeviceManager.h b/panda/src/device/winInputDeviceManager.h index 13cab3d7c0..e98a42a0bb 100644 --- a/panda/src/device/winInputDeviceManager.h +++ b/panda/src/device/winInputDeviceManager.h @@ -20,7 +20,7 @@ #include "xInputDevice.h" -#include +#include #include class WinRawInputDevice; diff --git a/panda/src/device/winRawInputDevice.cxx b/panda/src/device/winRawInputDevice.cxx index 9411ad508b..010766edf0 100644 --- a/panda/src/device/winRawInputDevice.cxx +++ b/panda/src/device/winRawInputDevice.cxx @@ -19,7 +19,7 @@ #if defined(_WIN32) && !defined(CPPPARSER) -#include +#include #include #include "phidsdi.h" diff --git a/panda/src/device/xInputDevice.cxx b/panda/src/device/xInputDevice.cxx index 74783f8751..bcc44cd3b1 100644 --- a/panda/src/device/xInputDevice.cxx +++ b/panda/src/device/xInputDevice.cxx @@ -19,8 +19,8 @@ #include "inputDeviceManager.h" #include "string_utils.h" -#include -#include +#include +#include #ifndef XUSER_MAX_COUNT #define XUSER_MAX_COUNT 4 diff --git a/panda/src/device/xInputDevice.h b/panda/src/device/xInputDevice.h index 2088c19182..c4a1f58d27 100644 --- a/panda/src/device/xInputDevice.h +++ b/panda/src/device/xInputDevice.h @@ -19,7 +19,7 @@ #if defined(_WIN32) && !defined(CPPPARSER) -#include +#include class InputDeviceManager; diff --git a/panda/src/dgraph/CMakeLists.txt b/panda/src/dgraph/CMakeLists.txt new file mode 100644 index 0000000000..10caff45ef --- /dev/null +++ b/panda/src/dgraph/CMakeLists.txt @@ -0,0 +1,29 @@ +set(P3DGRAPH_HEADERS + config_dgraph.h + dataGraphTraverser.I dataGraphTraverser.h + dataNode.I dataNode.h + dataNodeTransmit.I dataNodeTransmit.h +) + +set(P3DGRAPH_SOURCES + config_dgraph.cxx + dataGraphTraverser.cxx + dataNode.cxx + dataNodeTransmit.cxx +) + +composite_sources(p3dgraph P3DGRAPH_SOURCES) +add_component_library(p3dgraph NOINIT SYMBOL BUILDING_PANDA_DGRAPH + ${P3DGRAPH_HEADERS} ${P3DGRAPH_SOURCES}) +target_link_libraries(p3dgraph p3pgraph) +target_interrogate(p3dgraph ALL) + +if(NOT BUILD_METALIBS) + install(TARGETS p3dgraph + EXPORT Core COMPONENT Core + DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d + ARCHIVE COMPONENT CoreDevel) +endif() +install(FILES ${P3DGRAPH_HEADERS} COMPONENT CoreDevel DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d) diff --git a/panda/src/display/CMakeLists.txt b/panda/src/display/CMakeLists.txt new file mode 100644 index 0000000000..d2e50e5fc9 --- /dev/null +++ b/panda/src/display/CMakeLists.txt @@ -0,0 +1,116 @@ +set(P3DISPLAY_HEADERS + standardMunger.I standardMunger.h + config_display.h + callbackGraphicsWindow.I callbackGraphicsWindow.h + drawableRegion.I drawableRegion.h + displayRegion.I displayRegion.h + displayRegionCullCallbackData.I displayRegionCullCallbackData.h + displayRegionDrawCallbackData.I displayRegionDrawCallbackData.h + frameBufferProperties.I frameBufferProperties.h + get_x11.h pre_x11_include.h post_x11_include.h + graphicsEngine.I graphicsEngine.h + graphicsOutput.I graphicsOutput.h + graphicsBuffer.I graphicsBuffer.h + graphicsDevice.h graphicsDevice.I + graphicsPipe.I graphicsPipe.h + graphicsPipeSelection.I graphicsPipeSelection.h + graphicsStateGuardian.I graphicsStateGuardian.h + graphicsThreadingModel.I graphicsThreadingModel.h + graphicsWindow.I graphicsWindow.h + graphicsWindowInputDevice.I graphicsWindowInputDevice.h + graphicsWindowProc.h + graphicsWindowProcCallbackData.I graphicsWindowProcCallbackData.h + mouseAndKeyboard.h + nativeWindowHandle.I nativeWindowHandle.h + parasiteBuffer.I parasiteBuffer.h + pStatGPUTimer.I pStatGPUTimer.h + windowHandle.I windowHandle.h + windowProperties.I windowProperties.h + renderBuffer.h + stereoDisplayRegion.I stereoDisplayRegion.h + displaySearchParameters.h + displayInformation.h + subprocessWindow.h subprocessWindow.I + touchInfo.h +) + +set(P3DISPLAY_SOURCES + standardMunger.cxx + config_display.cxx + callbackGraphicsWindow.cxx + drawableRegion.cxx + displayRegion.cxx + displayRegionCullCallbackData.cxx + displayRegionDrawCallbackData.cxx + displaySearchParameters.cxx + displayInformation.cxx + frameBufferProperties.cxx + graphicsEngine.cxx + graphicsOutput.cxx + graphicsBuffer.cxx + graphicsPipe.cxx + graphicsPipeSelection.cxx + graphicsStateGuardian.cxx + graphicsThreadingModel.cxx + graphicsWindow.cxx graphicsWindowInputDevice.cxx + graphicsWindowProc.cxx + graphicsWindowProcCallbackData.cxx + graphicsDevice.cxx + mouseAndKeyboard.cxx + nativeWindowHandle.cxx + parasiteBuffer.cxx + windowHandle.cxx + windowProperties.cxx + stereoDisplayRegion.cxx + subprocessWindow.cxx + touchInfo.cxx +) + +set(P3DISPLAY_IGATEEXT + graphicsStateGuardian_ext.cxx + graphicsStateGuardian_ext.h + graphicsWindow_ext.cxx + graphicsWindow_ext.h + pythonGraphicsWindowProc.cxx + pythonGraphicsWindowProc.h + windowProperties_ext.cxx + windowProperties_ext.h +) + +if(APPLE) + set(P3DISPLAY_HEADERS + ${P3DISPLAY_HEADERS} + subprocessWindowBuffer.h + subprocessWindowBuffer.I + ) + + set(P3DISPLAY_SOURCES + ${P3DISPLAY_SOURCES} + subprocessWindowBuffer.cxx + ) +endif() + +# This is a large file; let's build it separately +set_source_files_properties(graphicsStateGuardian.cxx PROPERTIES SKIP_UNITY_BUILD_INCLUSION YES) + +composite_sources(p3display P3DISPLAY_SOURCES) +add_component_library(p3display SYMBOL BUILDING_PANDA_DISPLAY + ${P3DISPLAY_HEADERS} ${P3DISPLAY_SOURCES}) +target_link_libraries(p3display p3cull p3device p3pgraphnodes + PKG::X11) +target_interrogate(p3display ALL EXTENSIONS ${P3DISPLAY_IGATEEXT}) + +if(HAVE_EIGEN) + # Eigen puts this over the threshold where bigobj is needed on MSVC + set_target_properties(p3display PROPERTIES MSVC_BIGOBJ ON) +endif() + +if(NOT BUILD_METALIBS) + install(TARGETS p3display + EXPORT Core COMPONENT Core + DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d + ARCHIVE COMPONENT CoreDevel) +endif() +install(FILES ${P3DISPLAY_HEADERS} COMPONENT CoreDevel DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d) diff --git a/panda/src/display/graphicsEngine.cxx b/panda/src/display/graphicsEngine.cxx index 39a1e73aa2..9843f818ba 100644 --- a/panda/src/display/graphicsEngine.cxx +++ b/panda/src/display/graphicsEngine.cxx @@ -54,9 +54,9 @@ #include "winInputDeviceManager.h" #endif -#if defined(WIN32) +#if defined(_WIN32) #define WINDOWS_LEAN_AND_MEAN - #include + #include #include #undef WINDOWS_LEAN_AND_MEAN #else diff --git a/panda/src/display/graphicsStateGuardian.cxx b/panda/src/display/graphicsStateGuardian.cxx index 46c5bfa0f6..c36eea42ae 100644 --- a/panda/src/display/graphicsStateGuardian.cxx +++ b/panda/src/display/graphicsStateGuardian.cxx @@ -876,6 +876,22 @@ compute_distance_to(const LPoint3 &point) const { } } +/** + * A shader can request a number of values from the current render state. These + * are stored in the form of a matrix. Each ShaderContext caches the current + * value of these matrices, and calls this routine to update the matrices that + * have changed based on the aspects of the render state that were altered. + */ +void GraphicsStateGuardian:: +update_shader_matrix_cache(Shader *shader, LMatrix4 *cache, int altered) { + for (Shader::ShaderMatPart &part : shader->_mat_parts) { + if (altered & part._dep) { + fetch_specified_part(part._part, part._arg, cache, part._count); + } + cache += part._count; + } +} + /** * The gsg contains a large number of useful matrices: * @@ -902,54 +918,45 @@ compute_distance_to(const LPoint3 &point) const { * */ const LMatrix4 *GraphicsStateGuardian:: -fetch_specified_value(Shader::ShaderMatSpec &spec, int altered) { +fetch_specified_value(Shader::ShaderMatSpec &spec, const LMatrix4 *cache, int altered) { LVecBase3 v; - if (altered & spec._dep[0]) { - const LMatrix4 *t = fetch_specified_part(spec._part[0], spec._arg[0], spec._cache[0], spec._index); - if (t != &spec._cache[0]) { - spec._cache[0] = *t; - } - } - if (altered & spec._dep[1]) { - const LMatrix4 *t = fetch_specified_part(spec._part[1], spec._arg[1], spec._cache[1], spec._index); - if (t != &spec._cache[1]) { - spec._cache[1] = *t; - } - } + const LMatrix4 *cache0 = cache + spec._cache_offset[0]; + const LMatrix4 *cache1 = cache + spec._cache_offset[1]; - switch(spec._func) { + + switch (spec._func) { case Shader::SMF_compose: - spec._value.multiply(spec._cache[0], spec._cache[1]); + spec._value.multiply((*cache0), (*cache1)); return &spec._value; case Shader::SMF_transform_dlight: - spec._value = spec._cache[0]; - v = spec._cache[1].xform_vec(spec._cache[0].get_row3(2)); + spec._value = (*cache0); + v = (*cache1).xform_vec((*cache0).get_row3(2)); v.normalize(); spec._value.set_row(2, v); - v = spec._cache[1].xform_vec(spec._cache[0].get_row3(3)); + v = (*cache1).xform_vec((*cache0).get_row3(3)); v.normalize(); spec._value.set_row(3, v); return &spec._value; case Shader::SMF_transform_plight: { // Careful not to touch the w component, which contains the near value. - spec._value = spec._cache[0]; - LPoint3 point = spec._cache[1].xform_point(spec._cache[0].get_row3(2)); + spec._value = *cache0; + LPoint3 point = (*cache1).xform_point((*cache0).get_row3(2)); spec._value(2, 0) = point[0]; spec._value(2, 1) = point[1]; spec._value(2, 2) = point[2]; return &spec._value; } case Shader::SMF_transform_slight: - spec._value = spec._cache[0]; - spec._value.set_row(2, spec._cache[1].xform_point(spec._cache[0].get_row3(2))); - v = spec._cache[1].xform_vec(spec._cache[0].get_row3(3)); + spec._value = *cache0; + spec._value.set_row(2, (*cache1).xform_point((*cache0).get_row3(2))); + v = (*cache1).xform_vec((*cache0).get_row3(3)); v.normalize(); spec._value.set_row(3, v); return &spec._value; case Shader::SMF_first: - return &spec._cache[0]; + return cache0; default: // should never get here spec._value = LMatrix4::ident_mat(); @@ -960,57 +967,62 @@ fetch_specified_value(Shader::ShaderMatSpec &spec, int altered) { /** * See fetch_specified_value */ -const LMatrix4 *GraphicsStateGuardian:: +void GraphicsStateGuardian:: fetch_specified_part(Shader::ShaderMatInput part, InternalName *name, - LMatrix4 &t, int index) { + LMatrix4 *into, int count) { + nassertv(count > 0); + switch (part) { case Shader::SMO_identity: { - return &LMatrix4::ident_mat(); + for (int i = 0; i < count; ++i) { + into[i] = LMatrix4::ident_mat(); + } + return; } case Shader::SMO_window_size: case Shader::SMO_pixel_size: { LVecBase2i pixel_size = _current_display_region->get_pixel_size(); - t = LMatrix4::translate_mat(pixel_size[0], pixel_size[1], 0); - return &t; + into[0] = LMatrix4::translate_mat(pixel_size[0], pixel_size[1], 0); + return; } case Shader::SMO_frame_time: { PN_stdfloat time = ClockObject::get_global_clock()->get_frame_time(); - t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, time, time, time, time); - return &t; + into[0].set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, time, time, time, time); + return; } case Shader::SMO_frame_delta: { PN_stdfloat dt = ClockObject::get_global_clock()->get_dt(); - t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, dt, dt, dt, dt); - return &t; + into[0].set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, dt, dt, dt, dt); + return; } case Shader::SMO_texpad_x: { Texture *tex = _target_shader->get_shader_input_texture(name); - nassertr(tex != nullptr, &LMatrix4::zeros_mat()); + nassertv(tex != nullptr); int sx = tex->get_x_size() - tex->get_pad_x_size(); int sy = tex->get_y_size() - tex->get_pad_y_size(); int sz = tex->get_z_size() - tex->get_pad_z_size(); double cx = (sx * 0.5) / tex->get_x_size(); double cy = (sy * 0.5) / tex->get_y_size(); double cz = (sz * 0.5) / tex->get_z_size(); - t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, cx, cy, cz, 0); - return &t; + into[0].set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, cx, cy, cz, 0); + return; } case Shader::SMO_texpix_x: { Texture *tex = _target_shader->get_shader_input_texture(name); - nassertr(tex != nullptr, &LMatrix4::zeros_mat()); + nassertv(tex != nullptr); double px = 1.0 / tex->get_x_size(); double py = 1.0 / tex->get_y_size(); double pz = 1.0 / tex->get_z_size(); - t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, px, py, pz, 0); - return &t; + into[0].set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, px, py, pz, 0); + return; } case Shader::SMO_attr_material: { const MaterialAttrib *target_material = (const MaterialAttrib *) _target_rs->get_attrib_def(MaterialAttrib::get_class_slot()); // Material matrix contains AMBIENT, DIFFUSE, EMISSION, SPECULAR+SHININESS if (target_material->is_off()) { - t.set(1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0); - return &t; + into[0].set(1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0); + return; } Material *m = target_material->get_material(); LVecBase4 const &amb = m->get_ambient(); @@ -1018,148 +1030,152 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name, LVecBase4 const &emm = m->get_emission(); LVecBase4 spc = m->get_specular(); spc[3] = m->get_shininess(); - t.set(amb[0], amb[1], amb[2], amb[3], - dif[0], dif[1], dif[2], dif[3], - emm[0], emm[1], emm[2], emm[3], - spc[0], spc[1], spc[2], spc[3]); - return &t; + into[0].set(amb[0], amb[1], amb[2], amb[3], + dif[0], dif[1], dif[2], dif[3], + emm[0], emm[1], emm[2], emm[3], + spc[0], spc[1], spc[2], spc[3]); + return; } case Shader::SMO_attr_material2: { const MaterialAttrib *target_material = (const MaterialAttrib *) _target_rs->get_attrib_def(MaterialAttrib::get_class_slot()); if (target_material->is_off()) { - t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1); - return &t; + into[0].set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1); + return; } Material *m = target_material->get_material(); - t.set_row(0, m->get_base_color()); - t.set_row(3, LVecBase4(m->get_metallic(), m->get_refractive_index(), 0, m->get_roughness())); - return &t; + into[0].set_row(0, m->get_base_color()); + into[0].set_row(3, LVecBase4(m->get_metallic(), m->get_refractive_index(), 0, m->get_roughness())); + return; } case Shader::SMO_attr_color: { const ColorAttrib *target_color = (const ColorAttrib *) _target_rs->get_attrib_def(ColorAttrib::get_class_slot()); if (target_color->get_color_type() != ColorAttrib::T_flat) { - return &LMatrix4::ones_mat(); + into[0] = LMatrix4::ones_mat(); + return; } LVecBase4 c = target_color->get_color(); - t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, c[0], c[1], c[2], c[3]); - return &t; + into[0].set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, c[0], c[1], c[2], c[3]); + return; } case Shader::SMO_attr_colorscale: { const ColorScaleAttrib *target_color = (const ColorScaleAttrib *) _target_rs->get_attrib_def(ColorScaleAttrib::get_class_slot()); if (target_color->is_identity()) { - return &LMatrix4::ones_mat(); + into[0] = LMatrix4::ones_mat(); + return; } LVecBase4 cs = target_color->get_scale(); - t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, cs[0], cs[1], cs[2], cs[3]); - return &t; + into[0].set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, cs[0], cs[1], cs[2], cs[3]); + return; } case Shader::SMO_attr_fog: { const FogAttrib *target_fog = (const FogAttrib *) _target_rs->get_attrib_def(FogAttrib::get_class_slot()); Fog *fog = target_fog->get_fog(); if (fog == nullptr) { - return &LMatrix4::ones_mat(); + into[0] = LMatrix4::ones_mat(); + return; } PN_stdfloat start, end; fog->get_linear_range(start, end); - t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - fog->get_exp_density(), start, end, 1.0f / (end - start)); - return &t; + into[0].set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + fog->get_exp_density(), start, end, 1.0f / (end - start)); + return; } case Shader::SMO_attr_fogcolor: { const FogAttrib *target_fog = (const FogAttrib *) _target_rs->get_attrib_def(FogAttrib::get_class_slot()); Fog *fog = target_fog->get_fog(); if (fog == nullptr) { - return &LMatrix4::ones_mat(); + into[0] = LMatrix4::ones_mat(); + return; } LVecBase4 c = fog->get_color(); - t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, c[0], c[1], c[2], c[3]); - return &t; + into[0].set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, c[0], c[1], c[2], c[3]); + return; } case Shader::SMO_alight_x: { const NodePath &np = _target_shader->get_shader_input_nodepath(name); - nassertr(!np.is_empty(), &LMatrix4::zeros_mat()); + nassertv(!np.is_empty()); AmbientLight *lt; - DCAST_INTO_R(lt, np.node(), &LMatrix4::zeros_mat()); + DCAST_INTO_V(lt, np.node()); LColor const &c = lt->get_color(); - t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, c[0], c[1], c[2], c[3]); - return &t; + into[0].set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, c[0], c[1], c[2], c[3]); + return; } case Shader::SMO_satten_x: { const NodePath &np = _target_shader->get_shader_input_nodepath(name); - nassertr(!np.is_empty(), &LMatrix4::ones_mat()); + nassertv(!np.is_empty()); Spotlight *lt; - DCAST_INTO_R(lt, np.node(), &LMatrix4::ones_mat()); + DCAST_INTO_V(lt, np.node()); LVecBase3 const &a = lt->get_attenuation(); PN_stdfloat x = lt->get_exponent(); - t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, a[0], a[1], a[2], x); - return &t; + into[0].set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, a[0], a[1], a[2], x); + return; } case Shader::SMO_dlight_x: { // The dlight matrix contains COLOR, SPECULAR, DIRECTION, PSEUDOHALFANGLE const NodePath &np = _target_shader->get_shader_input_nodepath(name); - nassertr(!np.is_empty(), &LMatrix4::zeros_mat()); + nassertv(!np.is_empty()); DirectionalLight *lt; - DCAST_INTO_R(lt, np.node(), &LMatrix4::zeros_mat()); + DCAST_INTO_V(lt, np.node()); LColor const &c = lt->get_color(); LColor const &s = lt->get_specular_color(); - t = np.get_net_transform()->get_mat() * - _scene_setup->get_world_transform()->get_mat(); - LVecBase3 d = -(t.xform_vec(lt->get_direction())); + *into = np.get_net_transform()->get_mat() * + _scene_setup->get_world_transform()->get_mat(); + LVecBase3 d = -(into[0].xform_vec(lt->get_direction())); d.normalize(); LVecBase3 h = d + LVecBase3(0,-1,0); h.normalize(); - t.set(c[0], c[1], c[2], c[3], - s[0], s[1], s[2], c[3], - d[0], d[1], d[2], 0, - h[0], h[1], h[2], 0); - return &t; + into[0].set(c[0], c[1], c[2], c[3], + s[0], s[1], s[2], c[3], + d[0], d[1], d[2], 0, + h[0], h[1], h[2], 0); + return; } case Shader::SMO_plight_x: { // The plight matrix contains COLOR, SPECULAR, POINT, ATTENUATION const NodePath &np = _target_shader->get_shader_input_nodepath(name); - nassertr(!np.is_empty(), &LMatrix4::ones_mat()); + nassertv(!np.is_empty()); PointLight *lt; - DCAST_INTO_R(lt, np.node(), &LMatrix4::zeros_mat()); + DCAST_INTO_V(lt, np.node()); LColor const &c = lt->get_color(); LColor const &s = lt->get_specular_color(); - t = np.get_net_transform()->get_mat() * - _scene_setup->get_world_transform()->get_mat(); - LVecBase3 p = (t.xform_point(lt->get_point())); + into[0] = np.get_net_transform()->get_mat() * + _scene_setup->get_world_transform()->get_mat(); + LVecBase3 p = (into[0].xform_point(lt->get_point())); LVecBase3 a = lt->get_attenuation(); Lens *lens = lt->get_lens(0); PN_stdfloat lnear = lens->get_near(); PN_stdfloat lfar = lens->get_far(); - t.set(c[0], c[1], c[2], c[3], - s[0], s[1], s[2], s[3], - p[0], p[1], p[2], lnear, - a[0], a[1], a[2], lfar); - return &t; + into[0].set(c[0], c[1], c[2], c[3], + s[0], s[1], s[2], s[3], + p[0], p[1], p[2], lnear, + a[0], a[1], a[2], lfar); + return; } case Shader::SMO_slight_x: { // The slight matrix contains COLOR, SPECULAR, POINT, DIRECTION const NodePath &np = _target_shader->get_shader_input_nodepath(name); - nassertr(!np.is_empty(), &LMatrix4::zeros_mat()); + nassertv(!np.is_empty()); Spotlight *lt; - DCAST_INTO_R(lt, np.node(), &LMatrix4::zeros_mat()); + DCAST_INTO_V(lt, np.node()); Lens *lens = lt->get_lens(); - nassertr(lens != nullptr, &LMatrix4::zeros_mat()); + nassertv(lens != nullptr); LColor const &c = lt->get_color(); LColor const &s = lt->get_specular_color(); PN_stdfloat cutoff = ccos(deg_2_rad(lens->get_hfov() * 0.5f)); - t = np.get_net_transform()->get_mat() * - _scene_setup->get_world_transform()->get_mat(); - LVecBase3 p = t.xform_point(lens->get_nodal_point()); - LVecBase3 d = -(t.xform_vec(lens->get_view_vector())); - t.set(c[0], c[1], c[2], c[3], - s[0], s[1], s[2], s[3], - p[0], p[1], p[2], 0, - d[0], d[1], d[2], cutoff); - return &t; + into[0] = np.get_net_transform()->get_mat() * + _scene_setup->get_world_transform()->get_mat(); + LVecBase3 p = into[0].xform_point(lens->get_nodal_point()); + LVecBase3 d = -(into[0].xform_vec(lens->get_view_vector())); + into[0].set(c[0], c[1], c[2], c[3], + s[0], s[1], s[2], s[3], + p[0], p[1], p[2], 0, + d[0], d[1], d[2], cutoff); + return; } case Shader::SMO_light_ambient: { LColor cur_ambient_light(0.0f, 0.0f, 0.0f, 0.0f); @@ -1169,89 +1185,127 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name, if (!target_light->has_any_on_light()) { // There are no lights at all. This means, to follow the fixed- // function model, we pretend there is an all-white ambient light. - t.set_row(3, LVecBase4(1, 1, 1, 1)); + into[0].set_row(3, LVecBase4(1, 1, 1, 1)); } else { - t.set_row(3, target_light->get_ambient_contribution()); + into[0].set_row(3, target_light->get_ambient_contribution()); } - return &t; + return; } case Shader::SMO_texmat_i: { const TexMatrixAttrib *tma; const TextureAttrib *ta; - if (_target_rs->get_attrib(ta) && _target_rs->get_attrib(tma) && - index < ta->get_num_on_stages()) { - return &tma->get_mat(ta->get_on_stage(index)); - } else { - return &LMatrix4::ident_mat(); + + int num_stages = 0; + if (_target_rs->get_attrib(ta) && _target_rs->get_attrib(tma)) { + num_stages = std::min(count, (int)ta->get_num_on_stages()); } + + int i = 0; + for (; i < num_stages; ++i) { + into[i] = tma->get_mat(ta->get_on_stage(i)); + } + for (; i < count; ++i) { + into[i] = LMatrix4::ident_mat(); + } + return; } case Shader::SMO_inv_texmat_i: { const TexMatrixAttrib *tma; const TextureAttrib *ta; - if (_target_rs->get_attrib(ta) && _target_rs->get_attrib(tma) && - index < ta->get_num_on_stages()) { - t = tma->get_transform(ta->get_on_stage(index))->get_inverse()->get_mat(); - return &t; - } else { - return &LMatrix4::ident_mat(); + + int num_stages = 0; + if (_target_rs->get_attrib(ta) && _target_rs->get_attrib(tma)) { + num_stages = std::min(count, (int)ta->get_num_on_stages()); } + + int i = 0; + for (; i < num_stages; ++i) { + into[i] = tma->get_transform(ta->get_on_stage(i))->get_inverse()->get_mat(); + } + for (; i < count; ++i) { + into[i] = LMatrix4::ident_mat(); + } + return; } case Shader::SMO_texscale_i: { const TexMatrixAttrib *tma; const TextureAttrib *ta; - if (_target_rs->get_attrib(ta) && _target_rs->get_attrib(tma) && - index < ta->get_num_on_stages()) { - LVecBase3 scale = tma->get_transform(ta->get_on_stage(index))->get_scale(); - t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, scale[0], scale[1], scale[2], 0); - return &t; - } else { - return &LMatrix4::ident_mat(); + + int num_stages = 0; + if (_target_rs->get_attrib(ta) && _target_rs->get_attrib(tma)) { + num_stages = std::min(count, (int)ta->get_num_on_stages()); } + + int i = 0; + for (; i < num_stages; ++i) { + LVecBase3 scale = tma->get_transform(ta->get_on_stage(i))->get_scale(); + into[i].set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, scale[0], scale[1], scale[2], 0); + } + for (; i < count; ++i) { + into[i] = LMatrix4::ident_mat(); + } + return; } case Shader::SMO_texcolor_i: { const TextureAttrib *ta; - if (_target_rs->get_attrib(ta) && index < ta->get_num_on_stages()) { - TextureStage *ts = ta->get_on_stage(index); - t.set_row(3, ts->get_color()); - return &t; - } else { - return &LMatrix4::zeros_mat(); + + int num_stages = 0; + if (_target_rs->get_attrib(ta)) { + num_stages = std::min(count, (int)ta->get_num_on_stages()); } + + int i = 0; + for (; i < num_stages; ++i) { + TextureStage *ts = ta->get_on_stage(i); + into[i].set_row(3, ts->get_color()); + } + for (; i < count; ++i) { + into[i] = LMatrix4::ident_mat(); + } + return; } case Shader::SMO_tex_is_alpha_i: { // This is a hack so we can support both F_alpha and other formats in the // default shader, to fix font rendering in GLES2 const TextureAttrib *ta; - if (_target_rs->get_attrib(ta) && - index < ta->get_num_on_stages()) { - TextureStage *ts = ta->get_on_stage(index); - PN_stdfloat v = (ta->get_on_texture(ts)->get_format() == Texture::F_alpha); - t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, v, v, v, 0); - return &t; - } else { - return &LMatrix4::zeros_mat(); + + int num_stages = 0; + if (_target_rs->get_attrib(ta)) { + num_stages = std::min(count, (int)ta->get_num_on_stages()); } + + int i = 0; + for (; i < num_stages; ++i) { + TextureStage *ts = ta->get_on_stage(i); + PN_stdfloat v = (ta->get_on_texture(ts)->get_format() == Texture::F_alpha); + into[i].set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, v, v, v, 0); + } + for (; i < count; ++i) { + into[i] = LMatrix4::zeros_mat(); + } + return; } case Shader::SMO_plane_x: { const NodePath &np = _target_shader->get_shader_input_nodepath(name); - nassertr(!np.is_empty(), &LMatrix4::zeros_mat()); + nassertv(!np.is_empty()); const PlaneNode *plane_node; - DCAST_INTO_R(plane_node, np.node(), &LMatrix4::zeros_mat()); + DCAST_INTO_V(plane_node, np.node()); LPlane p = plane_node->get_plane(); - t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, p[0], p[1], p[2], p[3]); - return &t; + into[0].set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, p[0], p[1], p[2], p[3]); + return; } case Shader::SMO_clipplane_x: { const ClipPlaneAttrib *cpa; _target_rs->get_attrib_def(cpa); int planenr = atoi(name->get_name().c_str()); if (planenr >= cpa->get_num_on_planes()) { - return &LMatrix4::zeros_mat(); + into[0] = LMatrix4::zeros_mat(); + return; } const NodePath &np = cpa->get_on_plane(planenr); - nassertr(!np.is_empty(), &LMatrix4::zeros_mat()); + nassertv(!np.is_empty()); const PlaneNode *plane_node; - DCAST_INTO_R(plane_node, np.node(), &LMatrix4::zeros_mat()); + DCAST_INTO_V(plane_node, np.node()); // Transform plane to world space CPT(TransformState) transform = np.get_net_transform(); @@ -1259,206 +1313,223 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name, if (!transform->is_identity()) { plane.xform(transform->get_mat()); } - t.set_row(3, plane); - return &t; + into[0].set_row(3, plane); + return; } case Shader::SMO_apiview_clipplane_i: { const ClipPlaneAttrib *cpa; _target_rs->get_attrib_def(cpa); - if (index >= cpa->get_num_on_planes()) { - return &LMatrix4::zeros_mat(); + + int num_planes = std::min(count, (int)cpa->get_num_on_planes()); + int i = 0; + for (; i < num_planes; ++i) { + const NodePath &plane = cpa->get_on_plane(i); + nassertv(!plane.is_empty()); + const PlaneNode *plane_node; + DCAST_INTO_V(plane_node, plane.node()); + + CPT(TransformState) transform = + _scene_setup->get_cs_world_transform()->compose( + plane.get_transform(_scene_setup->get_scene_root().get_parent())); + + LPlane xformed_plane = plane_node->get_plane() * transform->get_mat(); + into[i].set_row(3, xformed_plane); } - const NodePath &plane = cpa->get_on_plane(index); - nassertr(!plane.is_empty(), &LMatrix4::zeros_mat()); - const PlaneNode *plane_node; - DCAST_INTO_R(plane_node, plane.node(), &LMatrix4::zeros_mat()); - - CPT(TransformState) transform = - _scene_setup->get_cs_world_transform()->compose( - plane.get_transform(_scene_setup->get_scene_root().get_parent())); - - LPlane xformed_plane = plane_node->get_plane() * transform->get_mat(); - t.set_row(3, xformed_plane); - return &t; + for (; i < count; ++i) { + // Fill the remainder with zeroes. + into[i] = LMatrix4::zeros_mat(); + } + return; } case Shader::SMO_mat_constant_x: { - return &_target_shader->get_shader_input_matrix(name, t); + _target_shader->get_shader_input_matrix(name, into[0]); + return; } case Shader::SMO_vec_constant_x: { const LVecBase4 &input = _target_shader->get_shader_input_vector(name); const PN_stdfloat *data = input.get_data(); - t.set(data[0], data[1], data[2], data[3], - data[0], data[1], data[2], data[3], - data[0], data[1], data[2], data[3], - data[0], data[1], data[2], data[3]); - return &t; + into[0].set(data[0], data[1], data[2], data[3], + data[0], data[1], data[2], data[3], + data[0], data[1], data[2], data[3], + data[0], data[1], data[2], data[3]); + return; } case Shader::SMO_world_to_view: { - return &(_scene_setup->get_world_transform()->get_mat()); + into[0] = _scene_setup->get_world_transform()->get_mat(); + return; } case Shader::SMO_view_to_world: { - return &(_scene_setup->get_camera_transform()->get_mat()); + into[0] = _scene_setup->get_camera_transform()->get_mat(); + return; } case Shader::SMO_model_to_view: { - t = _inv_cs_transform->compose(_internal_transform)->get_mat(); - return &t; + into[0] = _inv_cs_transform->compose(_internal_transform)->get_mat(); + return; } case Shader::SMO_model_to_apiview: { - return &(_internal_transform->get_mat()); + into[0] = _internal_transform->get_mat(); + return; } case Shader::SMO_view_to_model: { - t = _internal_transform->invert_compose(_cs_transform)->get_mat(); - return &t; + into[0] = _internal_transform->invert_compose(_cs_transform)->get_mat(); + return; } case Shader::SMO_apiview_to_model: { - t = _internal_transform->get_inverse()->get_mat(); - return &t; + into[0] = _internal_transform->get_inverse()->get_mat(); + return; } case Shader::SMO_apiview_to_view: { - return &(_inv_cs_transform->get_mat()); + into[0] = _inv_cs_transform->get_mat(); + return; } case Shader::SMO_view_to_apiview: { - return &(_cs_transform->get_mat()); + into[0] = _cs_transform->get_mat(); + return; } case Shader::SMO_clip_to_view: { if (_current_lens->get_coordinate_system() == _coordinate_system) { - return &(_current_lens->get_projection_mat_inv(_current_stereo_channel)); + into[0] = _current_lens->get_projection_mat_inv(_current_stereo_channel); } else { - t = _current_lens->get_projection_mat_inv(_current_stereo_channel) * - LMatrix4::convert_mat(_current_lens->get_coordinate_system(), _coordinate_system); - return &t; + into[0] = _current_lens->get_projection_mat_inv(_current_stereo_channel) * + LMatrix4::convert_mat(_current_lens->get_coordinate_system(), _coordinate_system); } + return; } case Shader::SMO_view_to_clip: { if (_current_lens->get_coordinate_system() == _coordinate_system) { - return &(_current_lens->get_projection_mat(_current_stereo_channel)); + into[0] = _current_lens->get_projection_mat(_current_stereo_channel); } else { - t = LMatrix4::convert_mat(_coordinate_system, _current_lens->get_coordinate_system()) * - _current_lens->get_projection_mat(_current_stereo_channel); - return &t; + into[0] = LMatrix4::convert_mat(_coordinate_system, _current_lens->get_coordinate_system()) * + _current_lens->get_projection_mat(_current_stereo_channel); } + return; } case Shader::SMO_apiclip_to_view: { - t = _projection_mat_inv->get_mat() * _inv_cs_transform->get_mat(); - return &t; + into[0] = _projection_mat_inv->get_mat() * _inv_cs_transform->get_mat(); + return; } case Shader::SMO_view_to_apiclip: { - t = _cs_transform->get_mat() * _projection_mat->get_mat(); - return &t; + into[0] = _cs_transform->get_mat() * _projection_mat->get_mat(); + return; } case Shader::SMO_apiclip_to_apiview: { - return &(_projection_mat_inv->get_mat()); + into[0] = _projection_mat_inv->get_mat(); + return; } case Shader::SMO_apiview_to_apiclip: { - return &(_projection_mat->get_mat()); + into[0] = _projection_mat->get_mat(); + return; } case Shader::SMO_view_x_to_view: { const NodePath &np = _target_shader->get_shader_input_nodepath(name); - nassertr(!np.is_empty(), &LMatrix4::ident_mat()); - t = np.get_net_transform()->get_mat() * + nassertv(!np.is_empty()); + into[0] = np.get_net_transform()->get_mat() * _scene_setup->get_world_transform()->get_mat(); - return &t; + return; } case Shader::SMO_view_to_view_x: { const NodePath &np = _target_shader->get_shader_input_nodepath(name); - nassertr(!np.is_empty(), &LMatrix4::ident_mat()); - t = _scene_setup->get_camera_transform()->get_mat() * + nassertv(!np.is_empty()); + into[0] = _scene_setup->get_camera_transform()->get_mat() * np.get_net_transform()->get_inverse()->get_mat(); - return &t; + return; } case Shader::SMO_apiview_x_to_view: { const NodePath &np = _target_shader->get_shader_input_nodepath(name); - nassertr(!np.is_empty(), &LMatrix4::ident_mat()); - t = LMatrix4::convert_mat(_internal_coordinate_system, _coordinate_system) * + nassertv(!np.is_empty()); + into[0] = LMatrix4::convert_mat(_internal_coordinate_system, _coordinate_system) * np.get_net_transform()->get_mat() * _scene_setup->get_world_transform()->get_mat(); - return &t; + return; } case Shader::SMO_view_to_apiview_x: { const NodePath &np = _target_shader->get_shader_input_nodepath(name); - nassertr(!np.is_empty(), &LMatrix4::ident_mat()); - t = (_scene_setup->get_camera_transform()->get_mat() * + nassertv(!np.is_empty()); + into[0] = (_scene_setup->get_camera_transform()->get_mat() * np.get_net_transform()->get_inverse()->get_mat() * LMatrix4::convert_mat(_coordinate_system, _internal_coordinate_system)); - return &t; + return; } case Shader::SMO_clip_x_to_view: { const NodePath &np = _target_shader->get_shader_input_nodepath(name); - nassertr(!np.is_empty(), &LMatrix4::ident_mat()); + nassertv(!np.is_empty()); const LensNode *node; - DCAST_INTO_R(node, np.node(), &LMatrix4::ident_mat()); + DCAST_INTO_V(node, np.node()); const Lens *lens = node->get_lens(); - t = lens->get_projection_mat_inv(_current_stereo_channel) * + into[0] = lens->get_projection_mat_inv(_current_stereo_channel) * LMatrix4::convert_mat(lens->get_coordinate_system(), _coordinate_system) * np.get_net_transform()->get_mat() * _scene_setup->get_world_transform()->get_mat(); - return &t; + return; } case Shader::SMO_view_to_clip_x: { const NodePath &np = _target_shader->get_shader_input_nodepath(name); - nassertr(!np.is_empty(), &LMatrix4::ident_mat()); + nassertv(!np.is_empty()); const LensNode *node; - DCAST_INTO_R(node, np.node(), &LMatrix4::ident_mat()); + DCAST_INTO_V(node, np.node()); const Lens *lens = node->get_lens(); - t = _scene_setup->get_camera_transform()->get_mat() * + into[0] = _scene_setup->get_camera_transform()->get_mat() * np.get_net_transform()->get_inverse()->get_mat() * LMatrix4::convert_mat(_coordinate_system, lens->get_coordinate_system()) * lens->get_projection_mat(_current_stereo_channel); - return &t; + return; } case Shader::SMO_apiclip_x_to_view: { const NodePath &np = _target_shader->get_shader_input_nodepath(name); - nassertr(!np.is_empty(), &LMatrix4::ident_mat()); + nassertv(!np.is_empty()); const LensNode *node; - DCAST_INTO_R(node, np.node(), &LMatrix4::ident_mat()); + DCAST_INTO_V(node, np.node()); const Lens *lens = node->get_lens(); - t = calc_projection_mat(lens)->get_inverse()->get_mat() * + into[0] = calc_projection_mat(lens)->get_inverse()->get_mat() * get_cs_transform_for(lens->get_coordinate_system())->get_inverse()->get_mat() * np.get_net_transform()->get_mat() * _scene_setup->get_world_transform()->get_mat(); - return &t; + return; } case Shader::SMO_view_to_apiclip_x: { const NodePath &np = _target_shader->get_shader_input_nodepath(name); - nassertr(!np.is_empty(), &LMatrix4::ident_mat()); + nassertv(!np.is_empty()); const LensNode *node; - DCAST_INTO_R(node, np.node(), &LMatrix4::ident_mat()); + DCAST_INTO_V(node, np.node()); const Lens *lens = node->get_lens(); - t = _scene_setup->get_camera_transform()->get_mat() * + into[0] = _scene_setup->get_camera_transform()->get_mat() * np.get_net_transform()->get_inverse()->get_mat() * get_cs_transform_for(lens->get_coordinate_system())->get_mat() * calc_projection_mat(lens)->get_mat(); - return &t; + return; } case Shader::SMO_mat_constant_x_attrib: { if (_target_shader->has_shader_input(name)) { // There is an input specifying precisely this whole thing, with dot and // all. Support this, even if only for backward compatibility. - return &_target_shader->get_shader_input_matrix(name, t); + _target_shader->get_shader_input_matrix(name, into[0]); + return; } const NodePath &np = _target_shader->get_shader_input_nodepath(name->get_parent()); - nassertr(!np.is_empty(), &LMatrix4::ident_mat()); + nassertv(!np.is_empty()); - return fetch_specified_member(np, name->get_basename(), t); + fetch_specified_member(np, name->get_basename(), into[0]); + return; } case Shader::SMO_vec_constant_x_attrib: { if (_target_shader->has_shader_input(name)) { // There is an input specifying precisely this whole thing, with dot and // all. Support this, even if only for backward compatibility. const LVecBase4 &data = _target_shader->get_shader_input_vector(name); - t.set(data[0], data[1], data[2], data[3], - data[0], data[1], data[2], data[3], - data[0], data[1], data[2], data[3], - data[0], data[1], data[2], data[3]); - return &t; + into[0].set(data[0], data[1], data[2], data[3], + data[0], data[1], data[2], data[3], + data[0], data[1], data[2], data[3], + data[0], data[1], data[2], data[3]); + return; } const NodePath &np = _target_shader->get_shader_input_nodepath(name->get_parent()); - nassertr(!np.is_empty(), &LMatrix4::ident_mat()); + nassertv(!np.is_empty()); - return fetch_specified_member(np, name->get_basename(), t); + fetch_specified_member(np, name->get_basename(), into[0]); + return; } case Shader::SMO_light_source_i_attrib: { const LightAttrib *target_light; @@ -1466,22 +1537,24 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name, // We don't count ambient lights, which would be pretty silly to handle // via this mechanism. - size_t num_lights = target_light->get_num_non_ambient_lights(); - if (index >= 0 && (size_t)index < num_lights) { - NodePath light = target_light->get_on_light((size_t)index); - nassertr(!light.is_empty(), &LMatrix4::ident_mat()); - Light *light_obj = light.node()->as_light(); - nassertr(light_obj != nullptr, &LMatrix4::ident_mat()); + size_t num_lights = std::min((size_t)count, target_light->get_num_non_ambient_lights()); - return fetch_specified_member(light, name, t); - - } else if (index == 0) { - // Apply the default OpenGL lights otherwise. - // Special exception for light 0, which defaults to white. - string basename = name->get_basename(); - return &LMatrix4::ones_mat(); + size_t i = 0; + for (i = 0; i < num_lights; ++i) { + NodePath light = target_light->get_on_light(i); + nassertv(!light.is_empty()); + fetch_specified_member(light, name, into[i]); } - return fetch_specified_member(NodePath(), name, t); + // Apply the default OpenGL lights otherwise. + // Special exception for light 0, which defaults to white. + if (i == 0) { + into[0] = LMatrix4::ones_mat(); + ++i; + } + for (; i < (size_t)count; ++i) { + fetch_specified_member(NodePath(), name, into[i]); + } + return; } case Shader::SMO_light_source_i_packed: { // The light matrix contains COLOR, ATTENUATION, POSITION, VIEWVECTOR @@ -1490,15 +1563,17 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name, // We don't count ambient lights, which would be pretty silly to handle // via this mechanism. - size_t num_lights = target_light->get_num_non_ambient_lights(); - if (index >= 0 && (size_t)index < num_lights) { - NodePath np = target_light->get_on_light((size_t)index); - nassertr(!np.is_empty(), &LMatrix4::ident_mat()); + size_t num_lights = std::min((size_t)count, target_light->get_num_non_ambient_lights()); + + size_t i = 0; + for (i = 0; i < num_lights; ++i) { + NodePath np = target_light->get_on_light(i); + nassertv(!np.is_empty()); PandaNode *node = np.node(); Light *light = node->as_light(); - nassertr(light != nullptr, &LMatrix4::zeros_mat()); - t.set_row(0, light->get_color()); - t.set_row(1, light->get_attenuation()); + nassertv(light != nullptr); + into[i].set_row(0, light->get_color()); + into[i].set_row(1, light->get_attenuation()); LMatrix4 mat = np.get_net_transform()->get_mat() * _scene_setup->get_world_transform()->get_mat(); @@ -1506,42 +1581,47 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name, if (node->is_of_type(DirectionalLight::get_class_type())) { LVecBase3 d = mat.xform_vec(((const DirectionalLight *)node)->get_direction()); d.normalize(); - t.set_row(2, LVecBase4(d, 0)); - t.set_row(3, LVecBase4(-d, 0)); + into[i].set_row(2, LVecBase4(d, 0)); + into[i].set_row(3, LVecBase4(-d, 0)); } else if (node->is_of_type(LightLensNode::get_class_type())) { const Lens *lens = ((const LightLensNode *)node)->get_lens(); LPoint3 p = mat.xform_point(lens->get_nodal_point()); - t.set_row(3, LVecBase4(p)); + into[i].set_row(3, LVecBase4(p)); // For shadowed point light we need to store near/far. // For spotlight we need to store cutoff angle. if (node->is_of_type(Spotlight::get_class_type())) { PN_stdfloat cutoff = ccos(deg_2_rad(lens->get_hfov() * 0.5f)); LVecBase3 d = -(mat.xform_vec(lens->get_view_vector())); - t.set_cell(1, 3, ((const Spotlight *)node)->get_exponent()); - t.set_row(2, LVecBase4(d, cutoff)); + into[i].set_cell(1, 3, ((const Spotlight *)node)->get_exponent()); + into[i].set_row(2, LVecBase4(d, cutoff)); } else if (node->is_of_type(PointLight::get_class_type())) { - t.set_cell(1, 3, lens->get_far()); - t.set_cell(3, 3, lens->get_near()); + into[i].set_cell(1, 3, lens->get_far()); + into[i].set_cell(3, 3, lens->get_near()); if (node->is_of_type(SphereLight::get_class_type())) { - t.set_cell(2, 3, ((const SphereLight *)node)->get_radius()); + into[i].set_cell(2, 3, ((const SphereLight *)node)->get_radius()); } } } - } else if (index == 0) { - // Apply the default OpenGL lights otherwise. - // Special exception for light 0, which defaults to white. - t.set_row(0, LVecBase4(1, 1, 1, 1)); } - return &t; + // Apply the default OpenGL lights otherwise. + // Special exception for light 0, which defaults to white. + if (i == 0) { + into[0].set_row(0, LVecBase4(1, 1, 1, 1)); + ++i; + } + for (; i < (size_t)count; ++i) { + fetch_specified_member(NodePath(), name, into[i]); + } + return; } default: - nassertr(false /*should never get here*/, &LMatrix4::ident_mat()); - return &LMatrix4::ident_mat(); + nassertv(false /*should never get here*/); + return; } } @@ -1549,7 +1629,7 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name, * Given a NodePath passed into a shader input that is a structure, fetches * the value for the given member. */ -const LMatrix4 *GraphicsStateGuardian:: +void GraphicsStateGuardian:: fetch_specified_member(const NodePath &np, CPT_InternalName attrib, LMatrix4 &t) { // This system is not ideal. It will be improved in the future. static const CPT_InternalName IN_color("color"); @@ -1575,20 +1655,19 @@ fetch_specified_member(const NodePath &np, CPT_InternalName attrib, LMatrix4 &t) if (attrib == IN_color) { if (node == nullptr) { - return &LMatrix4::ident_mat(); + t = LMatrix4::ident_mat(); } Light *light = node->as_light(); - nassertr(light != nullptr, &LMatrix4::ident_mat()); + nassertv(light != nullptr); LColor c = light->get_color(); t.set_row(3, c); - return &t; } else if (attrib == IN_ambient) { if (node == nullptr) { - return &LMatrix4::ident_mat(); + t = LMatrix4::ident_mat(); } Light *light = node->as_light(); - nassertr(light != nullptr, &LMatrix4::ident_mat()); + nassertv(light != nullptr); if (node->is_ambient_light()) { LColor c = light->get_color(); t.set_row(3, c); @@ -1596,14 +1675,13 @@ fetch_specified_member(const NodePath &np, CPT_InternalName attrib, LMatrix4 &t) // Non-ambient lights don't currently have an ambient color in Panda3D. t.set_row(3, LColor(0.0f, 0.0f, 0.0f, 1.0f)); } - return &t; } else if (attrib == IN_diffuse) { if (node == nullptr) { - return &LMatrix4::ident_mat(); + t = LMatrix4::ident_mat(); } Light *light = node->as_light(); - nassertr(light != nullptr, &LMatrix4::ones_mat()); + nassertv(light != nullptr); if (node->is_ambient_light()) { // Ambient light has no diffuse color. t.set_row(3, LColor(0.0f, 0.0f, 0.0f, 1.0f)); @@ -1611,39 +1689,34 @@ fetch_specified_member(const NodePath &np, CPT_InternalName attrib, LMatrix4 &t) LColor c = light->get_color(); t.set_row(3, c); } - return &t; } else if (attrib == IN_specular) { if (node == nullptr) { - return &LMatrix4::ident_mat(); + t = LMatrix4::ident_mat(); } Light *light = node->as_light(); - nassertr(light != nullptr, &LMatrix4::ones_mat()); + nassertv(light != nullptr); t.set_row(3, light->get_specular_color()); - return &t; } else if (attrib == IN_position) { if (np.is_empty()) { t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0); - return &t; } else if (node->is_ambient_light()) { // Ambient light has no position. t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); - return &t; } else if (node->is_of_type(DirectionalLight::get_class_type())) { DirectionalLight *light; - DCAST_INTO_R(light, node, &LMatrix4::ident_mat()); + DCAST_INTO_V(light, node); CPT(TransformState) transform = np.get_transform(_scene_setup->get_scene_root().get_parent()); LVector3 dir = -(light->get_direction() * transform->get_mat()); dir *= _scene_setup->get_cs_world_transform()->get_mat(); t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, dir[0], dir[1], dir[2], 0); - return &t; } else { LightLensNode *light; - DCAST_INTO_R(light, node, &LMatrix4::ident_mat()); + DCAST_INTO_V(light, node); Lens *lens = light->get_lens(); - nassertr(lens != nullptr, &LMatrix4::ident_mat()); + nassertv(lens != nullptr); CPT(TransformState) transform = _scene_setup->get_cs_world_transform()->compose( @@ -1652,20 +1725,17 @@ fetch_specified_member(const NodePath &np, CPT_InternalName attrib, LMatrix4 &t) const LMatrix4 &light_mat = transform->get_mat(); LPoint3 pos = lens->get_nodal_point() * light_mat; t = LMatrix4::translate_mat(pos); - return &t; } } else if (attrib == IN_halfVector) { if (np.is_empty()) { t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0); - return &t; } else if (node->is_ambient_light()) { // Ambient light has no half-vector. t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); - return &t; } else if (node->is_of_type(DirectionalLight::get_class_type())) { DirectionalLight *light; - DCAST_INTO_R(light, node, &LMatrix4::ident_mat()); + DCAST_INTO_V(light, node); CPT(TransformState) transform = np.get_transform(_scene_setup->get_scene_root().get_parent()); LVector3 dir = -(light->get_direction() * transform->get_mat()); @@ -1674,12 +1744,11 @@ fetch_specified_member(const NodePath &np, CPT_InternalName attrib, LMatrix4 &t) dir += LVector3(0, 0, 1); dir.normalize(); t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, dir[0], dir[1], dir[2], 1); - return &t; } else { LightLensNode *light; - DCAST_INTO_R(light, node, &LMatrix4::ident_mat()); + DCAST_INTO_V(light, node); Lens *lens = light->get_lens(); - nassertr(lens != nullptr, &LMatrix4::ident_mat()); + nassertv(lens != nullptr); CPT(TransformState) transform = _scene_setup->get_cs_world_transform()->compose( @@ -1691,22 +1760,19 @@ fetch_specified_member(const NodePath &np, CPT_InternalName attrib, LMatrix4 &t) pos += LVector3(0, 0, 1); pos.normalize(); t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, pos[0],pos[1],pos[2], 1); - return &t; } } else if (attrib == IN_spotDirection) { if (node == nullptr) { t.set_row(3, LVector3(0.0f, 0.0f, -1.0f)); - return &t; } else if (node->is_ambient_light()) { // Ambient light has no spot direction. t.set_row(3, LVector3(0.0f, 0.0f, 0.0f)); - return &t; } else { LightLensNode *light; - DCAST_INTO_R(light, node, &LMatrix4::ident_mat()); + DCAST_INTO_V(light, node); Lens *lens = light->get_lens(); - nassertr(lens != nullptr, &LMatrix4::ident_mat()); + nassertv(lens != nullptr); CPT(TransformState) transform = _scene_setup->get_cs_world_transform()->compose( @@ -1715,93 +1781,87 @@ fetch_specified_member(const NodePath &np, CPT_InternalName attrib, LMatrix4 &t) const LMatrix4 &light_mat = transform->get_mat(); LVector3 dir = lens->get_view_vector() * light_mat; t.set_row(3, dir); - return &t; } } else if (attrib == IN_spotCutoff) { if (node != nullptr && node->is_of_type(Spotlight::get_class_type())) { LightLensNode *light; - DCAST_INTO_R(light, node, &LMatrix4::ident_mat()); + DCAST_INTO_V(light, node); Lens *lens = light->get_lens(); - nassertr(lens != nullptr, &LMatrix4::ident_mat()); + nassertv(lens != nullptr); float cutoff = lens->get_hfov() * 0.5f; t.set_row(3, LVecBase4(cutoff)); - return &t; } else { // Other lights have no cut-off. t.set_row(3, LVecBase4(180)); - return &t; } } else if (attrib == IN_spotCosCutoff) { if (node != nullptr && node->is_of_type(Spotlight::get_class_type())) { LightLensNode *light; - DCAST_INTO_R(light, node, &LMatrix4::ident_mat()); + DCAST_INTO_V(light, node); Lens *lens = light->get_lens(); - nassertr(lens != nullptr, &LMatrix4::ident_mat()); + nassertv(lens != nullptr); float cutoff = lens->get_hfov() * 0.5f; t.set_row(3, LVecBase4(ccos(deg_2_rad(cutoff)))); - return &t; } else { // Other lights have no cut-off. t.set_row(3, LVecBase4(-1)); - return &t; } } else if (attrib == IN_spotExponent) { if (node == nullptr) { - return &LMatrix4::zeros_mat(); + t = LMatrix4::zeros_mat(); + return; } Light *light = node->as_light(); - nassertr(light != nullptr, &LMatrix4::ident_mat()); + nassertv(light != nullptr); t.set_row(3, LVecBase4(light->get_exponent())); - return &t; } else if (attrib == IN_attenuation) { if (node != nullptr) { Light *light = node->as_light(); - nassertr(light != nullptr, &LMatrix4::ones_mat()); + nassertv(light != nullptr); t.set_row(3, LVecBase4(light->get_attenuation(), 0)); } else { t.set_row(3, LVecBase4(1, 0, 0, 0)); } - return &t; } else if (attrib == IN_constantAttenuation) { if (node == nullptr) { - return &LMatrix4::ones_mat(); + t = LMatrix4::ones_mat(); + return; } Light *light = node->as_light(); - nassertr(light != nullptr, &LMatrix4::ones_mat()); + nassertv(light != nullptr); t.set_row(3, LVecBase4(light->get_attenuation()[0])); - return &t; } else if (attrib == IN_linearAttenuation) { if (node == nullptr) { - return &LMatrix4::zeros_mat(); + t = LMatrix4::zeros_mat(); + return; } Light *light = node->as_light(); - nassertr(light != nullptr, &LMatrix4::ident_mat()); + nassertv(light != nullptr); t.set_row(3, LVecBase4(light->get_attenuation()[1])); - return &t; } else if (attrib == IN_quadraticAttenuation) { if (node == nullptr) { - return &LMatrix4::zeros_mat(); + t = LMatrix4::zeros_mat(); + return; } Light *light = node->as_light(); - nassertr(light != nullptr, &LMatrix4::ident_mat()); + nassertv(light != nullptr); t.set_row(3, LVecBase4(light->get_attenuation()[2])); - return &t; } else if (attrib == IN_shadowViewMatrix) { static const LMatrix4 biasmat(0.5f, 0.0f, 0.0f, 0.0f, @@ -1810,11 +1870,12 @@ fetch_specified_member(const NodePath &np, CPT_InternalName attrib, LMatrix4 &t) 0.5f, 0.5f, 0.5f, 1.0f); if (node == nullptr) { - return &biasmat; + t = biasmat; + return; } LensNode *lnode; - DCAST_INTO_R(lnode, node, &LMatrix4::ident_mat()); + DCAST_INTO_V(lnode, node); Lens *lens = lnode->get_lens(); t = _inv_cs_transform->get_mat() * @@ -1825,13 +1886,12 @@ fetch_specified_member(const NodePath &np, CPT_InternalName attrib, LMatrix4 &t) if (!node->is_of_type(PointLight::get_class_type())) { t *= lens->get_projection_mat() * biasmat; } - return &t; } else { display_cat.error() << "Shader input requests invalid attribute " << *attrib << " from node " << np << "\n"; - return &LMatrix4::ident_mat(); + t = LMatrix4::ident_mat(); } } diff --git a/panda/src/display/graphicsStateGuardian.h b/panda/src/display/graphicsStateGuardian.h index 2e165b6dc6..8d14ab9aba 100644 --- a/panda/src/display/graphicsStateGuardian.h +++ b/panda/src/display/graphicsStateGuardian.h @@ -336,10 +336,12 @@ public: virtual void clear(DrawableRegion *clearable); - const LMatrix4 *fetch_specified_value(Shader::ShaderMatSpec &spec, int altered); - const LMatrix4 *fetch_specified_part(Shader::ShaderMatInput input, InternalName *name, - LMatrix4 &t, int index); - const LMatrix4 *fetch_specified_member(const NodePath &np, CPT_InternalName member, LMatrix4 &t); + void update_shader_matrix_cache(Shader *shader, LMatrix4 *cache, int altered); + const LMatrix4 *fetch_specified_value(Shader::ShaderMatSpec &spec, const LMatrix4 *cache, int altered); + void fetch_specified_part(Shader::ShaderMatInput input, InternalName *name, + LMatrix4 *into, int count = 1); + void fetch_specified_member(const NodePath &np, CPT_InternalName member, + LMatrix4 &t); PT(Texture) fetch_specified_texture(Shader::ShaderTexSpec &spec, SamplerState &sampler, int &view); const Shader::ShaderPtrData *fetch_ptr_parameter(const Shader::ShaderPtrSpec& spec); diff --git a/panda/src/display/graphicsWindowProc.h b/panda/src/display/graphicsWindowProc.h index a330c06a11..3e348200bb 100644 --- a/panda/src/display/graphicsWindowProc.h +++ b/panda/src/display/graphicsWindowProc.h @@ -16,7 +16,7 @@ #include "pandabase.h" -#ifdef WIN32 +#ifdef _WIN32 #ifndef WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN 1 #endif diff --git a/panda/src/display/graphicsWindowProcCallbackData.I b/panda/src/display/graphicsWindowProcCallbackData.I index eb12340a30..2efd54115e 100644 --- a/panda/src/display/graphicsWindowProcCallbackData.I +++ b/panda/src/display/graphicsWindowProcCallbackData.I @@ -27,7 +27,7 @@ get_graphics_window() const { return _graphicsWindow; } -#ifdef WIN32 +#ifdef _WIN32 /** * Returns the Windows proc hwnd parameter. diff --git a/panda/src/display/graphicsWindowProcCallbackData.cxx b/panda/src/display/graphicsWindowProcCallbackData.cxx index 82e57ef382..e96eb7057a 100644 --- a/panda/src/display/graphicsWindowProcCallbackData.cxx +++ b/panda/src/display/graphicsWindowProcCallbackData.cxx @@ -21,7 +21,7 @@ TypeHandle GraphicsWindowProcCallbackData::_type_handle; */ void GraphicsWindowProcCallbackData:: output(std::ostream &out) const { -#ifdef WIN32 +#ifdef _WIN32 out << get_type() << "(" << (void*)_graphicsWindow << ", " << _hwnd << ", " << _msg << ", " << _wparam << ", " << _lparam << ")"; #else diff --git a/panda/src/display/graphicsWindowProcCallbackData.h b/panda/src/display/graphicsWindowProcCallbackData.h index 23ae66d9c7..83ce91c8bb 100644 --- a/panda/src/display/graphicsWindowProcCallbackData.h +++ b/panda/src/display/graphicsWindowProcCallbackData.h @@ -31,7 +31,7 @@ public: INLINE GraphicsWindow* get_graphics_window() const; -#ifdef WIN32 +#ifdef _WIN32 INLINE void set_hwnd(uintptr_t hwnd); INLINE void set_msg(int msg); INLINE void set_wparam(int wparam); @@ -41,7 +41,7 @@ public: PUBLISHED: virtual void output(std::ostream &out) const; -#ifdef WIN32 +#ifdef _WIN32 INLINE uintptr_t get_hwnd() const; INLINE int get_msg() const; INLINE int get_wparam() const; @@ -54,7 +54,7 @@ PUBLISHED: private: GraphicsWindow* _graphicsWindow; -#ifdef WIN32 +#ifdef _WIN32 uintptr_t _hwnd; int _msg; int _wparam; diff --git a/panda/src/display/nativeWindowHandle.I b/panda/src/display/nativeWindowHandle.I index b897aa2f1c..a77163d672 100644 --- a/panda/src/display/nativeWindowHandle.I +++ b/panda/src/display/nativeWindowHandle.I @@ -60,7 +60,7 @@ get_handle() const { } #endif // HAVE_X11 -#if defined(WIN32) && !defined(CPPPARSER) +#if defined(_WIN32) && !defined(CPPPARSER) /** * */ @@ -69,7 +69,7 @@ WinHandle(HWND handle) : _handle(handle) { } #endif // WIN32 -#if defined(WIN32) && !defined(CPPPARSER) +#if defined(_WIN32) && !defined(CPPPARSER) /** * */ diff --git a/panda/src/display/nativeWindowHandle.cxx b/panda/src/display/nativeWindowHandle.cxx index 2ae1973a6f..e04ff12066 100644 --- a/panda/src/display/nativeWindowHandle.cxx +++ b/panda/src/display/nativeWindowHandle.cxx @@ -22,7 +22,7 @@ TypeHandle NativeWindowHandle::SubprocessHandle::_type_handle; #if defined(HAVE_X11) && !defined(CPPPARSER) TypeHandle NativeWindowHandle::X11Handle::_type_handle; #endif -#if defined(WIN32) && !defined(CPPPARSER) +#if defined(_WIN32) && !defined(CPPPARSER) TypeHandle NativeWindowHandle::WinHandle::_type_handle; #endif @@ -60,7 +60,7 @@ make_x11(X11_Window window) { } #endif // HAVE_X11 -#if defined(WIN32) && !defined(CPPPARSER) +#if defined(_WIN32) && !defined(CPPPARSER) /** * Constructs a new WindowHandle that references a window on Windows. */ @@ -68,7 +68,7 @@ PT(WindowHandle) NativeWindowHandle:: make_win(HWND window) { return new WindowHandle(new WinHandle(window)); } -#endif // WIN32 +#endif // _WIN32 /** * Returns the OS-specific handle converted to an integer, if this is possible @@ -116,7 +116,7 @@ output(ostream &out) const { } #endif // HAVE_X11 -#if defined(WIN32) && !defined(CPPPARSER) +#if defined(_WIN32) && !defined(CPPPARSER) /** * Returns the OS-specific handle converted to an integer, if this is possible * for the particular representation. Returns 0 if it is not. @@ -125,9 +125,9 @@ size_t NativeWindowHandle::WinHandle:: get_int_handle() const { return (size_t)_handle; } -#endif // WIN32 +#endif // _WIN32 -#if defined(WIN32) && !defined(CPPPARSER) +#if defined(_WIN32) && !defined(CPPPARSER) /** * */ diff --git a/panda/src/display/nativeWindowHandle.h b/panda/src/display/nativeWindowHandle.h index 14bab98815..8cabed8cb0 100644 --- a/panda/src/display/nativeWindowHandle.h +++ b/panda/src/display/nativeWindowHandle.h @@ -19,7 +19,7 @@ #include "windowHandle.h" #include "get_x11.h" -#ifdef WIN32 +#ifdef _WIN32 #ifndef WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN 1 #endif @@ -47,7 +47,7 @@ public: static PT(WindowHandle) make_x11(X11_Window window); #endif // HAVE_X11 -#if defined(WIN32) && !defined(CPPPARSER) +#if defined(_WIN32) && !defined(CPPPARSER) static PT(WindowHandle) make_win(HWND window); #endif // WIN32 @@ -141,7 +141,7 @@ public: #endif // HAVE_X11 -#if defined(WIN32) && !defined(CPPPARSER) +#if defined(_WIN32) && !defined(CPPPARSER) class EXPCL_PANDA_DISPLAY WinHandle : public OSHandle { public: INLINE WinHandle(HWND handle); @@ -186,7 +186,7 @@ public: #if defined(HAVE_X11) && !defined(CPPPARSER) X11Handle::init_type(); #endif -#if defined(WIN32) && !defined(CPPPARSER) +#if defined(_WIN32) && !defined(CPPPARSER) WinHandle::init_type(); #endif } diff --git a/panda/src/distort/CMakeLists.txt b/panda/src/distort/CMakeLists.txt new file mode 100644 index 0000000000..2a555fcdc9 --- /dev/null +++ b/panda/src/distort/CMakeLists.txt @@ -0,0 +1,33 @@ +set(P3DISTORT_HEADERS + config_distort.h + cylindricalLens.h cylindricalLens.I + fisheyeLens.h fisheyeLens.I + nonlinearImager.h nonlinearImager.I + oSphereLens.h oSphereLens.I + projectionScreen.h projectionScreen.I + pSphereLens.h pSphereLens.I +) + +set(P3DISTORT_SOURCES + config_distort.cxx + cylindricalLens.cxx + fisheyeLens.cxx + nonlinearImager.cxx + oSphereLens.cxx + projectionScreen.cxx + pSphereLens.cxx +) + +composite_sources(pandafx P3DISTORT_SOURCES) +add_library(pandafx ${P3DISTORT_HEADERS} ${P3DISTORT_SOURCES}) +set_target_properties(pandafx PROPERTIES DEFINE_SYMBOL BUILDING_PANDAFX) +target_link_libraries(pandafx panda) +target_interrogate(pandafx ALL) + +install(TARGETS pandafx + EXPORT Core COMPONENT Core + DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d + ARCHIVE COMPONENT CoreDevel) +install(FILES ${P3DISTORT_HEADERS} COMPONENT CoreDevel DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d) diff --git a/panda/src/downloader/CMakeLists.txt b/panda/src/downloader/CMakeLists.txt new file mode 100644 index 0000000000..25ba1f6efc --- /dev/null +++ b/panda/src/downloader/CMakeLists.txt @@ -0,0 +1,75 @@ +set(P3DOWNLOADER_HEADERS + bioPtr.I bioPtr.h + bioStreamPtr.I bioStreamPtr.h + bioStream.I bioStream.h bioStreamBuf.h + chunkedStream.I chunkedStream.h + chunkedStreamBuf.h chunkedStreamBuf.I + config_downloader.h + decompressor.h decompressor.I + documentSpec.h documentSpec.I + download_utils.h downloadDb.h downloadDb.I + extractor.h extractor.I + httpAuthorization.I httpAuthorization.h + httpBasicAuthorization.I httpBasicAuthorization.h + httpChannel.I httpChannel.h + httpClient.I httpClient.h + httpCookie.I httpCookie.h + httpDate.I httpDate.h + httpDigestAuthorization.I httpDigestAuthorization.h + httpEntityTag.I httpEntityTag.h + httpEnum.h + identityStream.I identityStream.h + identityStreamBuf.h identityStreamBuf.I + multiplexStream.I multiplexStream.h + multiplexStreamBuf.I multiplexStreamBuf.h + patcher.h patcher.I + socketStream.h socketStream.I + urlSpec.h urlSpec.I + virtualFileHTTP.I virtualFileHTTP.h + virtualFileMountHTTP.I virtualFileMountHTTP.h +) + +set(P3DOWNLOADER_SOURCES + config_downloader.cxx + bioPtr.cxx + bioStreamPtr.cxx + bioStream.cxx bioStreamBuf.cxx + chunkedStream.cxx chunkedStreamBuf.cxx + decompressor.cxx + documentSpec.cxx + downloadDb.cxx + download_utils.cxx + extractor.cxx + httpAuthorization.cxx + httpBasicAuthorization.cxx + httpChannel.cxx + httpClient.cxx + httpCookie.cxx + httpDate.cxx + httpDigestAuthorization.cxx + httpEntityTag.cxx + httpEnum.cxx + identityStream.cxx identityStreamBuf.cxx + multiplexStream.cxx multiplexStreamBuf.cxx + patcher.cxx + socketStream.cxx + urlSpec.cxx + virtualFileHTTP.cxx + virtualFileMountHTTP.cxx +) + +composite_sources(p3downloader P3DOWNLOADER_SOURCES) +add_component_library(p3downloader SYMBOL BUILDING_PANDA_DOWNLOADER + ${P3DOWNLOADER_HEADERS} ${P3DOWNLOADER_SOURCES}) +target_link_libraries(p3downloader p3express) +target_interrogate(p3downloader ALL) + +if(NOT BUILD_METALIBS) + install(TARGETS p3downloader + EXPORT Core COMPONENT Core + DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d + ARCHIVE COMPONENT CoreDevel) +endif() +install(FILES ${P3DOWNLOADER_HEADERS} COMPONENT CoreDevel DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d) diff --git a/panda/src/downloader/bioStreamBuf.cxx b/panda/src/downloader/bioStreamBuf.cxx index 1598b15259..ffa6a2994e 100644 --- a/panda/src/downloader/bioStreamBuf.cxx +++ b/panda/src/downloader/bioStreamBuf.cxx @@ -18,11 +18,11 @@ #ifdef HAVE_OPENSSL -#if defined(WIN32_VC) || defined(WIN64_VC) - #include +#ifdef _WIN32 + #include #include // for WSAGetLastError() #undef X509_NAME -#endif // WIN32_VC +#endif // _WIN32 /** * @@ -162,11 +162,11 @@ underflow() { if (read_count <= 0) { // Immediately save the os error in case we screw up and do something // that will change its value before we can output it. -#if defined(WIN32_VC) || defined(WIN64_VC) +#ifdef _WIN32 int os_error = WSAGetLastError(); #else int os_error = errno; -#endif // WIN32_VC +#endif // _WIN32 // Though BIO_eof() is tempting, it appears there are cases in which // that never returns true, if the socket is closed by the server. @@ -197,13 +197,13 @@ underflow() { << "\n"; } -#if defined(WIN32_VC) || defined(WIN64_VC) +#ifdef _WIN32 downloader_cat.warning() << "Windows error code: " << os_error << "\n"; #else downloader_cat.warning() << "Unix error code: " << os_error << "\n"; -#endif // WIN32_VC +#endif // _WIN32 } gbump(num_bytes); return EOF; diff --git a/panda/src/downloader/httpChannel.cxx b/panda/src/downloader/httpChannel.cxx index 365c819b0f..f066b24943 100644 --- a/panda/src/downloader/httpChannel.cxx +++ b/panda/src/downloader/httpChannel.cxx @@ -29,11 +29,11 @@ #include "openSSLWrapper.h" -#if defined(WIN32_VC) || defined(WIN64_VC) - #include +#ifdef _WIN32 + #include #include // for select() #undef X509_NAME -#endif // WIN32_VC +#endif // _WIN32 using std::istream; using std::min; diff --git a/panda/src/downloader/multiplexStreamBuf.cxx b/panda/src/downloader/multiplexStreamBuf.cxx index aa42d33f9e..9c58593282 100644 --- a/panda/src/downloader/multiplexStreamBuf.cxx +++ b/panda/src/downloader/multiplexStreamBuf.cxx @@ -13,7 +13,7 @@ #include "multiplexStreamBuf.h" -#if defined(WIN32_VC) || defined(WIN64_VC) +#ifdef _WIN32 #define WINDOWS_LEAN_AND_MEAN #include #undef WINDOWS_LEAN_AND_MEAN @@ -68,7 +68,7 @@ write_string(const string &str) { break; case OT_system_debug: -#if defined(WIN32_VC) || defined(WIN64_VC) +#ifdef _WIN32 OutputDebugString(str.c_str()); #endif break; diff --git a/panda/src/downloadertools/CMakeLists.txt b/panda/src/downloadertools/CMakeLists.txt new file mode 100644 index 0000000000..47abcb727f --- /dev/null +++ b/panda/src/downloadertools/CMakeLists.txt @@ -0,0 +1,46 @@ +if(NOT BUILD_PANDATOOL) + # It's safe to say, if the user doesn't want pandatool, they don't want these + # tools either. + return() +endif() + +if(HAVE_OPENSSL) + add_executable(pencrypt pencrypt.cxx) + target_link_libraries(pencrypt panda) + + add_executable(pdecrypt pdecrypt.cxx) + target_link_libraries(pdecrypt panda) + + install(TARGETS pencrypt pdecrypt + EXPORT Tools COMPONENT Tools + DESTINATION ${CMAKE_INSTALL_BINDIR}) +endif() + +if(HAVE_ZLIB) + add_executable(pzip pzip.cxx) + target_link_libraries(pzip panda) + + if(NOT CMAKE_CROSSCOMPILING) + add_executable(host_pzip ALIAS pzip) + else() + find_program(HOST_PATH_PZIP pzip) + + add_executable(host_pzip IMPORTED GLOBAL) + if(HOST_PATH_PZIP) + set_target_properties(host_pzip PROPERTIES + IMPORTED_LOCATION "${HOST_PATH_PZIP}") + endif() + + endif() + + add_executable(punzip punzip.cxx) + target_link_libraries(punzip panda) + + install(TARGETS pzip punzip + EXPORT Tools COMPONENT Tools + DESTINATION ${CMAKE_INSTALL_BINDIR}) +endif() + +add_executable(multify multify.cxx) +target_link_libraries(multify panda) +install(TARGETS multify EXPORT Tools COMPONENT Tools DESTINATION ${CMAKE_INSTALL_BINDIR}) diff --git a/panda/src/dxgsg9/CMakeLists.txt b/panda/src/dxgsg9/CMakeLists.txt new file mode 100644 index 0000000000..dd7ad9ff7f --- /dev/null +++ b/panda/src/dxgsg9/CMakeLists.txt @@ -0,0 +1,56 @@ +if(NOT HAVE_DX9) + return() +endif() + +set(P3DXGSG9_HEADERS + config_dxgsg9.h + dxGeomMunger9.h dxGeomMunger9.I + dxGraphicsDevice9.h + dxGraphicsStateGuardian9.h dxGraphicsStateGuardian9.I + dxgsg9base.h + dxIndexBufferContext9.h dxIndexBufferContext9.I + dxOcclusionQueryContext9.h dxOcclusionQueryContext9.I + dxShaderContext9.h dxShaderContext9.I + dxTextureContext9.h dxTextureContext9.I + dxVertexBufferContext9.h dxVertexBufferContext9.I + vertexElementArray.h + wdxGraphicsBuffer9.h wdxGraphicsBuffer9.I + wdxGraphicsPipe9.h wdxGraphicsPipe9.I + wdxGraphicsWindow9.h wdxGraphicsWindow9.I +) + +set(P3DXGSG9_SOURCES + config_dxgsg9.cxx + dxGeomMunger9.cxx + dxGraphicsDevice9.cxx + dxGraphicsStateGuardian9.cxx + dxIndexBufferContext9.cxx + dxOcclusionQueryContext9.cxx + dxShaderContext9.cxx + dxTextureContext9.cxx + dxVertexBufferContext9.cxx + vertexElementArray.cxx + wdxGraphicsBuffer9.cxx + wdxGraphicsPipe9.cxx + wdxGraphicsWindow9.cxx +) + +# This is a large file; let's build it separately +set_source_files_properties(dxGraphicsStateGuardian9.cxx PROPERTIES SKIP_UNITY_BUILD_INCLUSION YES) + +composite_sources(p3dxgsg9 P3DXGSG9_SOURCES) +add_component_library(p3dxgsg9 SYMBOL BUILDING_PANDADX + ${P3DXGSG9_HEADERS} ${P3DXGSG9_SOURCES}) +target_link_libraries(p3dxgsg9 p3windisplay panda + PKG::CG PKG::DX9) +target_compile_definitions(p3dxgsg9 PUBLIC USE_GENERIC_DXERR_LIBRARY) # FIXME + +if(NOT BUILD_METALIBS) + install(TARGETS p3dxgsg9 + EXPORT DX9 COMPONENT DX9 + DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d + ARCHIVE COMPONENT DX9Devel) +endif() +install(FILES ${P3DXGSG9_HEADERS} COMPONENT DX9Devel DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d) diff --git a/panda/src/dxgsg9/dxShaderContext9.cxx b/panda/src/dxgsg9/dxShaderContext9.cxx index a737c342bf..6c7a15d313 100644 --- a/panda/src/dxgsg9/dxShaderContext9.cxx +++ b/panda/src/dxgsg9/dxShaderContext9.cxx @@ -74,6 +74,8 @@ DXShaderContext9(Shader *s, GSG *gsg) : ShaderContext(s) { } } #endif + + _mat_part_cache = new LMatrix4[s->cp_get_mat_cache_size()]; } /** @@ -92,6 +94,8 @@ DXShaderContext9:: delete _vertex_element_array; _vertex_element_array = nullptr; } + + delete[] _mat_part_cache; } /** @@ -232,15 +236,20 @@ issue_parameters(GSG *gsg, int altered) { } } - for (size_t i = 0; i < _shader->_mat_spec.size(); ++i) { - Shader::ShaderMatSpec &spec = _shader->_mat_spec[i]; + if (altered & _shader->_mat_deps) { + gsg->update_shader_matrix_cache(_shader, _mat_part_cache, altered); + + for (Shader::ShaderMatSpec &spec : _shader->_mat_spec) { + if ((altered & spec._dep) == 0) { + continue; + } - if (altered & (spec._dep[0] | spec._dep[1])) { CGparameter p = _cg_parameter_map[spec._id._seqno]; if (p == nullptr) { continue; } - const LMatrix4 *val = gsg->fetch_specified_value(spec, altered); + + const LMatrix4 *val = gsg->fetch_specified_value(spec, _mat_part_cache, altered); if (val) { HRESULT hr; PN_stdfloat v [4]; diff --git a/panda/src/dxgsg9/dxShaderContext9.h b/panda/src/dxgsg9/dxShaderContext9.h index b637cb0a81..c02dcea201 100644 --- a/panda/src/dxgsg9/dxShaderContext9.h +++ b/panda/src/dxgsg9/dxShaderContext9.h @@ -87,6 +87,8 @@ private: pvector _cg_parameter_map; #endif + LMatrix4 *_mat_part_cache = nullptr; + private: void release_resources(void); diff --git a/panda/src/dxml/CMakeLists.txt b/panda/src/dxml/CMakeLists.txt new file mode 100644 index 0000000000..8b67b09d35 --- /dev/null +++ b/panda/src/dxml/CMakeLists.txt @@ -0,0 +1,28 @@ +set(P3DXML_HEADERS + config_dxml.h + tinyxml.h +) + +set(P3DXML_SOURCES + config_dxml.cxx + tinyxml.cpp + tinyxmlerror.cpp + tinyxmlparser.cpp +) + +composite_sources(p3dxml P3DXML_SOURCES) +add_definitions(-DTIXML_USE_STL) +add_component_library(p3dxml SYMBOL BUILDING_PANDA_DXML + ${P3DXML_HEADERS} ${P3DXML_SOURCES}) +target_link_libraries(p3dxml pandaexpress) +target_interrogate(p3dxml ALL) + +if(NOT BUILD_METALIBS) + install(TARGETS p3dxml + EXPORT Core COMPONENT Core + DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d + ARCHIVE COMPONENT CoreDevel) +endif() +install(FILES ${P3DXML_HEADERS} COMPONENT CoreDevel DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d) diff --git a/panda/src/egg/CMakeLists.txt b/panda/src/egg/CMakeLists.txt new file mode 100644 index 0000000000..5cdd891182 --- /dev/null +++ b/panda/src/egg/CMakeLists.txt @@ -0,0 +1,115 @@ +if(NOT HAVE_EGG) + return() +endif() + +set(P3EGG_HEADERS + config_egg.h eggAnimData.I eggAnimData.h + eggAnimPreload.I eggAnimPreload.h + eggAttributes.I + eggAttributes.h eggBin.h eggBinMaker.h eggComment.I + eggComment.h + eggCompositePrimitive.I eggCompositePrimitive.h + eggCoordinateSystem.I eggCoordinateSystem.h + eggCurve.I eggCurve.h eggData.I eggData.h + eggExternalReference.I eggExternalReference.h + eggFilenameNode.I eggFilenameNode.h eggGroup.I eggGroup.h + eggGroupNode.I eggGroupNode.h eggGroupUniquifier.h + eggLine.I eggLine.h + eggMaterial.I eggMaterial.h eggMaterialCollection.I + eggMaterialCollection.h + eggMesher.h eggMesher.I + eggMesherEdge.h eggMesherEdge.I + eggMesherFanMaker.h eggMesherFanMaker.I + eggMesherStrip.h eggMesherStrip.I + eggMiscFuncs.I eggMiscFuncs.h + eggMorph.I eggMorph.h eggMorphList.I eggMorphList.h + eggNamedObject.I eggNamedObject.h eggNameUniquifier.h + eggNode.I eggNode.h eggNurbsCurve.I eggNurbsCurve.h + eggNurbsSurface.I eggNurbsSurface.h eggObject.I eggObject.h + eggParameters.h + eggPatch.I eggPatch.h + eggPoint.I eggPoint.h eggPolygon.I + eggPolygon.h eggPolysetMaker.h eggPoolUniquifier.h + eggPrimitive.I eggPrimitive.h + eggRenderMode.I eggRenderMode.h + eggSAnimData.I eggSAnimData.h eggSurface.I eggSurface.h + eggSwitchCondition.h eggTable.I eggTable.h eggTexture.I + eggTexture.h eggTextureCollection.I eggTextureCollection.h + eggTriangleFan.I eggTriangleFan.h + eggTriangleStrip.I eggTriangleStrip.h + eggTransform.I eggTransform.h + eggUserData.I eggUserData.h + eggUtilities.I eggUtilities.h + eggVertex.I eggVertex.h + eggVertexAux.I eggVertexAux.h + eggVertexPool.I eggVertexPool.h + eggVertexUV.I eggVertexUV.h + eggXfmAnimData.I + eggXfmAnimData.h eggXfmSAnim.I eggXfmSAnim.h parserDefs.h + parser.yxx lexerDefs.h lexer.lxx pt_EggMaterial.h + vector_PT_EggMaterial.h pt_EggTexture.h + vector_PT_EggTexture.h pt_EggVertex.h vector_PT_EggVertex.h +) + +set(P3EGG_SOURCES + config_egg.cxx eggAnimData.cxx + eggAnimPreload.cxx + eggAttributes.cxx eggBin.cxx + eggBinMaker.cxx eggComment.cxx + eggCompositePrimitive.cxx + eggCoordinateSystem.cxx + eggCurve.cxx eggData.cxx eggExternalReference.cxx + eggFilenameNode.cxx eggGroup.cxx eggGroupNode.cxx + eggGroupUniquifier.cxx eggLine.cxx eggMaterial.cxx + eggMaterialCollection.cxx + eggMesher.cxx + eggMesherEdge.cxx + eggMesherFanMaker.cxx + eggMesherStrip.cxx + eggMiscFuncs.cxx eggMorphList.cxx + eggNamedObject.cxx eggNameUniquifier.cxx eggNode.cxx + eggNurbsCurve.cxx eggNurbsSurface.cxx eggObject.cxx + eggParameters.cxx + eggPatch.cxx + eggPoint.cxx eggPolygon.cxx eggPolysetMaker.cxx + eggPoolUniquifier.cxx eggPrimitive.cxx eggRenderMode.cxx + eggSAnimData.cxx eggSurface.cxx eggSwitchCondition.cxx + eggTable.cxx eggTexture.cxx eggTextureCollection.cxx + eggTransform.cxx + eggTriangleFan.cxx + eggTriangleStrip.cxx + eggUserData.cxx + eggUtilities.cxx eggVertex.cxx + eggVertexAux.cxx + eggVertexPool.cxx eggVertexUV.cxx + eggXfmAnimData.cxx eggXfmSAnim.cxx pt_EggMaterial.cxx + vector_PT_EggMaterial.cxx pt_EggTexture.cxx + vector_PT_EggTexture.cxx pt_EggVertex.cxx + vector_PT_EggVertex.cxx +) + +set(P3EGG_IGATEEXT + eggGroupNode_ext.cxx + eggGroupNode_ext.h +) + +# These cannot be interrogated, and are excluded from the composites. +add_bison_target(parser.cxx parser.yxx DEFINES parser.h PREFIX eggyy) +add_flex_target(lexer.cxx lexer.lxx CASE_INSENSITIVE PREFIX eggyy) +set(P3EGG_PARSER_SOURCES parser.cxx lexer.cxx) + +composite_sources(p3egg P3EGG_SOURCES) +add_component_library(p3egg SYMBOL BUILDING_PANDA_EGG + ${P3EGG_HEADERS} ${P3EGG_SOURCES} ${P3EGG_PARSER_SOURCES}) +target_link_libraries(p3egg panda) +target_interrogate(p3egg ${P3EGG_HEADERS} ${P3EGG_SOURCES} EXTENSIONS ${P3EGG_IGATEEXT}) + +if(NOT BUILD_METALIBS) + install(TARGETS p3egg + EXPORT Egg COMPONENT Egg + DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d + ARCHIVE COMPONENT EggDevel) +endif() +install(FILES ${P3EGG_HEADERS} COMPONENT EggDevel DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d) diff --git a/panda/src/egg/eggGroupNode.h b/panda/src/egg/eggGroupNode.h index 8bbf48aea0..6feaf2fab4 100644 --- a/panda/src/egg/eggGroupNode.h +++ b/panda/src/egg/eggGroupNode.h @@ -70,7 +70,7 @@ PUBLISHED: // limited add_childremove_child or inserterase interface. The following // implements this. public: -#if defined(WIN32_VC) || defined(WIN64_VC) +#ifdef _WIN32 typedef const PT(EggNode) *pointer; typedef const PT(EggNode) *const_pointer; #else diff --git a/panda/src/egg/eggPrimitive.h b/panda/src/egg/eggPrimitive.h index 4b8a035952..b20c81ba73 100644 --- a/panda/src/egg/eggPrimitive.h +++ b/panda/src/egg/eggPrimitive.h @@ -140,7 +140,7 @@ PUBLISHED: // through the limited add_vertexremove_vertex or inserterase interface. // The following implements this. public: -#if defined(WIN32_VC) || defined(WIN64_VC) +#ifdef _WIN32 typedef PT_EggVertex *pointer; typedef PT_EggVertex *const_pointer; #else diff --git a/panda/src/egg2pg/CMakeLists.txt b/panda/src/egg2pg/CMakeLists.txt new file mode 100644 index 0000000000..e0dcd91763 --- /dev/null +++ b/panda/src/egg2pg/CMakeLists.txt @@ -0,0 +1,49 @@ +if(NOT HAVE_EGG) + return() +endif() + +set(P3EGG2PG_HEADERS + animBundleMaker.h + characterMaker.h + config_egg2pg.h + deferredNodeProperty.h + eggBinner.h + eggLoader.h eggLoader.I + eggRenderState.h eggRenderState.I + eggSaver.h eggSaver.I + egg_parametrics.h + load_egg_file.h + save_egg_file.h + loaderFileTypeEgg.h +) + +set(P3EGG2PG_SOURCES + animBundleMaker.cxx + characterMaker.cxx + config_egg2pg.cxx + deferredNodeProperty.cxx + eggBinner.cxx + eggLoader.cxx + eggRenderState.cxx + eggSaver.cxx + egg_parametrics.cxx + load_egg_file.cxx + save_egg_file.cxx + loaderFileTypeEgg.cxx +) + +composite_sources(p3egg2pg P3EGG2PG_SOURCES) +add_component_library(p3egg2pg SYMBOL BUILDING_PANDA_EGG2PG + ${P3EGG2PG_HEADERS} ${P3EGG2PG_SOURCES}) +target_link_libraries(p3egg2pg panda p3egg) +target_interrogate(p3egg2pg ALL) + +if(NOT BUILD_METALIBS) + install(TARGETS p3egg2pg + EXPORT Egg COMPONENT Egg + DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d + ARCHIVE COMPONENT EggDevel) +endif() +install(FILES ${P3EGG2PG_HEADERS} COMPONENT EggDevel DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d) diff --git a/panda/src/egldisplay/CMakeLists.txt b/panda/src/egldisplay/CMakeLists.txt new file mode 100644 index 0000000000..d228f14f6c --- /dev/null +++ b/panda/src/egldisplay/CMakeLists.txt @@ -0,0 +1,68 @@ +if(NOT HAVE_EGL OR NOT HAVE_X11) + return() +endif() + +if(NOT HAVE_GLES1 AND NOT HAVE_GLES2) + return() +endif() + +set(P3EGLDISPLAY_HEADERS + config_egldisplay.h + eglGraphicsBuffer.h + eglGraphicsPipe.h eglGraphicsPipe.I + eglGraphicsPixmap.h + eglGraphicsStateGuardian.h eglGraphicsStateGuardian.I + eglGraphicsWindow.h eglGraphicsWindow.I +) + +set(P3EGLDISPLAY_SOURCES + config_egldisplay.cxx + eglGraphicsBuffer.cxx + eglGraphicsPipe.cxx + eglGraphicsPixmap.cxx + eglGraphicsStateGuardian.cxx + eglGraphicsWindow.cxx +) + +composite_sources(p3egldisplay P3EGLDISPLAY_SOURCES) + +# We actually build this twice! Once for GLES1, once for GLES2. +if(HAVE_GLES1) + add_component_library(p3egldisplay_gles1 SYMBOL BUILDING_PANDAGLES + INIT init_libegldisplay config_egldisplay.h + ${P3EGLDISPLAY_HEADERS} ${P3EGLDISPLAY_SOURCES}) + target_compile_definitions(p3egldisplay_gles1 PUBLIC OPENGLES_1) + target_link_libraries(p3egldisplay_gles1 p3glesgsg p3x11display + PKG::EGL PKG::GLES1) + + if(NOT BUILD_METALIBS) + install(TARGETS p3egldisplay_gles1 + EXPORT OpenGLES1 COMPONENT OpenGLES1 + DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d + ARCHIVE COMPONENT OpenGLES1Devel) + endif() + + install(FILES ${P3EGLDISPLAY_HEADERS} COMPONENT OpenGLES1Devel DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d) +endif() + +if(HAVE_GLES2) + add_component_library(p3egldisplay_gles2 SYMBOL BUILDING_PANDAGLES2 + INIT init_libegldisplay config_egldisplay.h + ${P3EGLDISPLAY_HEADERS} ${P3EGLDISPLAY_SOURCES}) + target_compile_definitions(p3egldisplay_gles2 PUBLIC OPENGLES_2) + target_link_libraries(p3egldisplay_gles2 p3gles2gsg p3x11display + PKG::EGL PKG::GLES2) + + if(NOT BUILD_METALIBS) + install(TARGETS p3egldisplay_gles2 + EXPORT OpenGLES2 COMPONENT OpenGLES2 + DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d + ARCHIVE COMPONENT OpenGLES2Devel) + endif() + + install(FILES ${P3EGLDISPLAY_HEADERS} COMPONENT OpenGLES2Devel DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d) +endif() diff --git a/panda/src/event/CMakeLists.txt b/panda/src/event/CMakeLists.txt new file mode 100644 index 0000000000..b0464ff793 --- /dev/null +++ b/panda/src/event/CMakeLists.txt @@ -0,0 +1,61 @@ +set(P3EVENT_HEADERS + asyncFuture.h asyncFuture.I + asyncTask.h asyncTask.I + asyncTaskChain.h asyncTaskChain.I + asyncTaskCollection.h asyncTaskCollection.I + asyncTaskManager.h asyncTaskManager.I + asyncTaskPause.h asyncTaskPause.I + asyncTaskSequence.h asyncTaskSequence.I + config_event.h + buttonEvent.I buttonEvent.h + buttonEventList.I buttonEventList.h + genericAsyncTask.h genericAsyncTask.I + pointerEvent.I pointerEvent.h + pointerEventList.I pointerEventList.h + event.I event.h eventHandler.h eventHandler.I + eventParameter.I eventParameter.h + eventQueue.I eventQueue.h eventReceiver.h + pt_Event.h throw_event.I throw_event.h +) + +set(P3EVENT_SOURCES + asyncFuture.cxx + asyncTask.cxx + asyncTaskChain.cxx + asyncTaskCollection.cxx + asyncTaskManager.cxx + asyncTaskPause.cxx + asyncTaskSequence.cxx + buttonEvent.cxx + buttonEventList.cxx + genericAsyncTask.cxx + pointerEvent.cxx + pointerEventList.cxx + config_event.cxx event.cxx eventHandler.cxx + eventParameter.cxx eventQueue.cxx eventReceiver.cxx + pt_Event.cxx +) + +set(P3EVENT_IGATEEXT + asyncFuture_ext.cxx + asyncFuture_ext.h + pythonTask.cxx + pythonTask.h + pythonTask.I +) + +composite_sources(p3event P3EVENT_SOURCES) +add_component_library(p3event NOINIT SYMBOL BUILDING_PANDA_EVENT + ${P3EVENT_HEADERS} ${P3EVENT_SOURCES}) +target_link_libraries(p3event p3linmath p3pstatclient) +target_interrogate(p3event ALL EXTENSIONS ${P3EVENT_IGATEEXT}) + +if(NOT BUILD_METALIBS) + install(TARGETS p3event + EXPORT Core COMPONENT Core + DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d + ARCHIVE COMPONENT CoreDevel) +endif() +install(FILES ${P3EVENT_HEADERS} COMPONENT CoreDevel DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d) diff --git a/panda/src/express/CMakeLists.txt b/panda/src/express/CMakeLists.txt new file mode 100644 index 0000000000..b45a55d11c --- /dev/null +++ b/panda/src/express/CMakeLists.txt @@ -0,0 +1,176 @@ +set(P3EXPRESS_HEADERS + buffer.I buffer.h + checksumHashGenerator.I checksumHashGenerator.h circBuffer.I + circBuffer.h + compress_string.h + config_express.h + copy_stream.h + datagram.I datagram.h datagramGenerator.I + datagramGenerator.h + datagramIterator.I datagramIterator.h datagramSink.I datagramSink.h + dcast.T dcast.h + encrypt_string.h + error_utils.h + export_dtool.h + fileReference.h fileReference.I + hashGeneratorBase.I hashGeneratorBase.h + hashVal.I hashVal.h + indirectLess.I indirectLess.h + memoryInfo.I memoryInfo.h + memoryUsage.I memoryUsage.h + memoryUsagePointerCounts.I memoryUsagePointerCounts.h + memoryUsagePointers.I memoryUsagePointers.h + multifile.I multifile.h + namable.I + namable.h + nodePointerTo.h nodePointerTo.I + nodePointerToBase.h nodePointerToBase.I + nodeReferenceCount.h nodeReferenceCount.I + openSSLWrapper.h openSSLWrapper.I + ordered_vector.h ordered_vector.I ordered_vector.T + pStatCollectorForwardBase.h + password_hash.h + patchfile.I patchfile.h + pointerTo.I pointerTo.h + pointerToArray.I pointerToArray.h + pointerToArrayBase.I pointerToArrayBase.h + pointerToBase.I pointerToBase.h + pointerToVoid.I pointerToVoid.h + pta_int.h + pta_uchar.h pta_double.h pta_float.h + pta_stdfloat.h + ramfile.I ramfile.h + referenceCount.I referenceCount.h + stringStreamBuf.I stringStreamBuf.h + stringStream.I stringStream.h + subStream.I subStream.h subStreamBuf.h + subfileInfo.h subfileInfo.I + temporaryFile.h temporaryFile.I + trueClock.I trueClock.h + typedReferenceCount.I typedReferenceCount.h typedef.h + virtualFileList.I virtualFileList.h + virtualFileComposite.h virtualFileComposite.I + virtualFile.h virtualFile.I + virtualFileMount.h virtualFileMount.I + virtualFileMountAndroidAsset.h virtualFileMountAndroidAsset.I + virtualFileMountMultifile.h virtualFileMountMultifile.I + virtualFileMountRamdisk.h virtualFileMountRamdisk.I + virtualFileMountSystem.h virtualFileMountSystem.I + virtualFileSimple.h virtualFileSimple.I + virtualFileSystem.h virtualFileSystem.I + weakPointerCallback.I weakPointerCallback.h + weakPointerTo.I weakPointerTo.h + weakPointerToBase.I weakPointerToBase.h + weakPointerToVoid.I weakPointerToVoid.h + weakReferenceList.I weakReferenceList.h + windowsRegistry.h + zStream.I zStream.h zStreamBuf.h +) + +set(P3EXPRESS_SOURCES + buffer.cxx checksumHashGenerator.cxx + compress_string.cxx + config_express.cxx + copy_stream.cxx + datagram.cxx datagramGenerator.cxx + datagramIterator.cxx + datagramSink.cxx dcast.cxx + encrypt_string.cxx + error_utils.cxx + fileReference.cxx + hashGeneratorBase.cxx hashVal.cxx + memoryInfo.cxx memoryUsage.cxx memoryUsagePointerCounts.cxx + memoryUsagePointers.cxx multifile.cxx + namable.cxx + nodePointerTo.cxx + nodePointerToBase.cxx + nodeReferenceCount.cxx + openSSLWrapper.cxx + ordered_vector.cxx + pStatCollectorForwardBase.cxx + password_hash.cxx + patchfile.cxx + pointerTo.cxx + pointerToArray.cxx + pointerToBase.cxx + pointerToVoid.cxx + pta_int.cxx + pta_uchar.cxx pta_double.cxx pta_float.cxx + ramfile.cxx + referenceCount.cxx + stringStreamBuf.cxx + stringStream.cxx + subStream.cxx subStreamBuf.cxx + subfileInfo.cxx + temporaryFile.cxx + trueClock.cxx + typedReferenceCount.cxx + virtualFileComposite.cxx virtualFile.cxx virtualFileList.cxx + virtualFileMount.cxx + virtualFileMountMultifile.cxx + virtualFileMountRamdisk.cxx + virtualFileMountSystem.cxx + virtualFileSimple.cxx virtualFileSystem.cxx + weakPointerCallback.cxx + weakPointerTo.cxx + weakPointerToBase.cxx + weakPointerToVoid.cxx + weakReferenceList.cxx + windowsRegistry.cxx + zStream.cxx zStreamBuf.cxx +) + +if(ANDROID) + list(APPEND P3EXPRESS_SOURCES virtualFileMountAndroidAsset.cxx) +endif() + +set(P3EXPRESS_IGATEEXT + datagram_ext.h + memoryUsagePointers_ext.cxx + memoryUsagePointers_ext.h + pointerToArray_ext.h + ramfile_ext.cxx + ramfile_ext.h + stringStream_ext.cxx + stringStream_ext.h + virtualFileSystem_ext.cxx + virtualFileSystem_ext.h + virtualFile_ext.cxx + virtualFile_ext.h +) + +composite_sources(p3express P3EXPRESS_SOURCES) +add_component_library(p3express SYMBOL BUILDING_PANDA_EXPRESS + ${P3EXPRESS_SOURCES} ${P3EXPRESS_HEADERS}) +target_link_libraries(p3express p3pandabase p3interrogatedb p3prc p3dtool + PKG::ZLIB PKG::OPENSSL) +target_interrogate(p3express ALL EXTENSIONS ${P3EXPRESS_IGATEEXT}) + +if(REPORT_OPENSSL_ERRORS) + target_compile_definitions(p3express PRIVATE REPORT_OPENSSL_ERRORS) +endif() +if(REPORT_OPENSSL_ERRORS_Debug) + target_compile_definitions(p3express PRIVATE $<$:REPORT_OPENSSL_ERRORS>) +endif() + +if(GETTIMEOFDAY_ONE_PARAM) + target_compile_definitions(p3express PRIVATE GETTIMEOFDAY_ONE_PARAM) +endif() + +if(WIN32) + target_link_libraries(p3express advapi32.lib ws2_32.lib) +endif() + +if(ANDROID) + target_link_libraries(p3express android) +endif() + +if(NOT BUILD_METALIBS) + install(TARGETS p3express + EXPORT Core COMPONENT Core + DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d + ARCHIVE COMPONENT CoreDevel) +endif() +install(FILES ${P3EXPRESS_HEADERS} COMPONENT CoreDevel DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d) diff --git a/panda/src/express/error_utils.cxx b/panda/src/express/error_utils.cxx index 0ede902fbf..7859c42d26 100644 --- a/panda/src/express/error_utils.cxx +++ b/panda/src/express/error_utils.cxx @@ -153,7 +153,7 @@ string error_to_text(ErrorUtilCode err) { */ int get_write_error() { -#if !defined(WIN32) && !defined(WIN64) +#ifndef _WIN32 return EU_error_abort; #else switch (errno) { @@ -189,7 +189,7 @@ get_write_error() { * */ string handle_socket_error() { -#if !defined(WIN32) && !defined(WIN64) +#ifndef _WIN32 return string(strerror(errno)); #else int err = WSAGetLastError(); @@ -248,7 +248,7 @@ string handle_socket_error() { */ int get_network_error() { -#if !defined(WIN32) && !defined(WIN64) +#ifndef _WIN32 return EU_error_abort; #else int err = WSAGetLastError(); diff --git a/panda/src/express/memoryUsage.cxx b/panda/src/express/memoryUsage.cxx index b76ae0ed3e..15acc27cf0 100644 --- a/panda/src/express/memoryUsage.cxx +++ b/panda/src/express/memoryUsage.cxx @@ -18,7 +18,7 @@ #include "mutexImpl.h" #include "interrogate_request.h" -#if (defined(WIN32_VC) || defined (WIN64_VC)) && defined(_DEBUG) +#if defined(_MSC_VER) && defined(_DEBUG) #include #endif @@ -426,7 +426,7 @@ mark_pointer(void *ptr, size_t size, ReferenceCount *ref_ptr) { #endif } -#if (defined(WIN32_VC) || defined (WIN64_VC))&& defined(_DEBUG) +#if defined(_WIN32) && defined(_DEBUG) /** * This callback is attached to the Win32 debug malloc system to be called * whenever a pointer is allocated, reallocated, or freed. It's used to track @@ -455,7 +455,7 @@ win32_malloc_hook(int alloc_type, void *ptr, mu->_total_size += increment; return true; } -#endif // WIN32_VC && _DEBUG +#endif // _WIN32 && _DEBUG @@ -520,7 +520,7 @@ MemoryUsage(const MemoryHook ©) : #error Cannot compile MemoryUsage without malloc wrappers! #endif -#if (defined(WIN32_VC) || defined(WIN64_VC)) && defined(_DEBUG) +#ifdef _MSC_VER // On a debug Windows build, we can set this malloc hook which allows // tracking every malloc call, even from subordinate libraries. _CrtSetAllocHook(&win32_malloc_hook); diff --git a/panda/src/express/memoryUsage.h b/panda/src/express/memoryUsage.h index 0371877ee0..86d1134073 100644 --- a/panda/src/express/memoryUsage.h +++ b/panda/src/express/memoryUsage.h @@ -55,7 +55,7 @@ protected: virtual void mark_pointer(void *ptr, size_t orig_size, ReferenceCount *ref_ptr); -#if (defined(WIN32_VC) || defined(WIN64_VC)) && defined(_DEBUG) +#if defined(_WIN32) && defined(_DEBUG) static int win32_malloc_hook(int alloc_type, void *ptr, size_t size, int block_use, long request, const unsigned char *filename, int line); diff --git a/panda/src/express/multifile.cxx b/panda/src/express/multifile.cxx index f857940774..f7055d2467 100644 --- a/panda/src/express/multifile.cxx +++ b/panda/src/express/multifile.cxx @@ -1631,7 +1631,7 @@ close_read_subfile(istream *stream) { // stream pointer does not call the appropriate global delete function; // instead apparently calling the system delete function. So we call the // delete function by hand instead. -#if !defined(WIN32_VC) && !defined(USE_MEMORY_NOWRAPPERS) && defined(REDEFINE_GLOBAL_OPERATOR_NEW) +#if defined(__GNUC__) && !defined(USE_MEMORY_NOWRAPPERS) && defined(REDEFINE_GLOBAL_OPERATOR_NEW) stream->~istream(); (*global_operator_delete)(stream); #else diff --git a/panda/src/express/pointerToArray.I b/panda/src/express/pointerToArray.I index 5fb560b695..a3d5e1d4f7 100644 --- a/panda/src/express/pointerToArray.I +++ b/panda/src/express/pointerToArray.I @@ -297,7 +297,7 @@ erase(iterator first, iterator last) { ((To *)(this->_void_ptr))->erase(first, last); } -#if !defined(WIN32_VC) && !defined(WIN64_VC) +#ifndef _WIN32 /** * */ @@ -844,7 +844,7 @@ back() const { return ((To *)(this->_void_ptr))->back(); } -#if !defined(WIN32_VC) && !defined(WIN64_VC) +#ifndef _WIN32 /** * */ diff --git a/panda/src/express/pointerToArray.h b/panda/src/express/pointerToArray.h index 7ff07a5ef1..ca6aab7ed4 100644 --- a/panda/src/express/pointerToArray.h +++ b/panda/src/express/pointerToArray.h @@ -61,7 +61,7 @@ #include "pointerToArrayBase.h" -#if (defined(WIN32_VC) || defined(WIN64_VC)) && !defined(__INTEL_COMPILER) +#if defined(_MSC_VER) && !defined(__INTEL_COMPILER) // disable mysterious MSVC warning for static inline PTA::empty_array method // need to chk if vc 7.0 still has this problem, would like to keep it enabled #pragma warning (disable : 4506) @@ -179,7 +179,7 @@ public: INLINE void erase(iterator position); INLINE void erase(iterator first, iterator last); -#if !defined(WIN32_VC) && !defined (WIN64_VC) +#ifndef _WIN32 INLINE reference operator [](size_type n) const; INLINE reference operator [](int n) const; #endif @@ -285,7 +285,7 @@ PUBLISHED: typedef typename pvector::const_reference const_reference; typedef typename pvector::const_iterator iterator; typedef typename pvector::const_iterator const_iterator; -#if defined(WIN32_VC) || defined(WIN64_VC) +#ifdef _MSC_VER // VC++ seems to break the const_reverse_iterator definition somehow. typedef typename pvector::reverse_iterator reverse_iterator; #else @@ -323,7 +323,7 @@ PUBLISHED: INLINE reference front() const; INLINE reference back() const; -#if !defined(WIN32_VC) && !defined(WIN64_VC) +#ifndef _WIN32 INLINE reference operator [](size_type n) const; INLINE reference operator [](int n) const; #endif diff --git a/panda/src/express/trueClock.I b/panda/src/express/trueClock.I index 3b7a80f66d..773a0ce8f0 100644 --- a/panda/src/express/trueClock.I +++ b/panda/src/express/trueClock.I @@ -11,7 +11,7 @@ * @date 2000-07-04 */ -#if defined(WIN32_VC) || defined(WIN64_VC) +#ifdef _WIN32 /** * @@ -36,7 +36,7 @@ get_short_time() { return time; } -#else // WIN32_VC +#else // _WIN32 /** * @@ -46,7 +46,7 @@ get_short_time() { return get_short_raw_time(); } -#endif // WIN32_VC +#endif // _WIN32 /** diff --git a/panda/src/express/trueClock.cxx b/panda/src/express/trueClock.cxx index e2298eb950..1df988e563 100644 --- a/panda/src/express/trueClock.cxx +++ b/panda/src/express/trueClock.cxx @@ -22,7 +22,7 @@ using std::min; TrueClock *TrueClock::_global_ptr = nullptr; -#if defined(WIN32_VC) || defined(WIN64_VC) +#ifdef _WIN32 // The Win32 implementation. @@ -471,7 +471,7 @@ set_time_scale(double time, double new_time_scale) { _time_scale = new_time_scale; } -#else // !WIN32_VC +#else // !_WIN32 // The Posix implementation. diff --git a/panda/src/express/trueClock.h b/panda/src/express/trueClock.h index b6255f211a..4775d02498 100644 --- a/panda/src/express/trueClock.h +++ b/panda/src/express/trueClock.h @@ -64,7 +64,7 @@ protected: static TrueClock *_global_ptr; -#ifdef WIN32 +#ifdef _WIN32 double correct_time(double time); void set_time_scale(double time, double new_time_scale); diff --git a/panda/src/express/virtualFileMountSystem.cxx b/panda/src/express/virtualFileMountSystem.cxx index ebf5fa6645..2420cb6f88 100644 --- a/panda/src/express/virtualFileMountSystem.cxx +++ b/panda/src/express/virtualFileMountSystem.cxx @@ -30,7 +30,7 @@ TypeHandle VirtualFileMountSystem::_type_handle; bool VirtualFileMountSystem:: has_file(const Filename &file) const { Filename pathname(_physical_filename, file); -#ifdef WIN32 +#ifdef _WIN32 if (VirtualFileSystem::get_global_ptr()->vfs_case_sensitive) { Filename case_pathname = pathname; if (!case_pathname.make_true_case()) { @@ -115,7 +115,7 @@ make_directory(const Filename &file) { */ bool VirtualFileMountSystem:: is_directory(const Filename &file) const { -#ifdef WIN32 +#ifdef _WIN32 // First ensure that the file exists to validate its case. if (VirtualFileSystem::get_global_ptr()->vfs_case_sensitive) { if (!has_file(file)) { @@ -133,7 +133,7 @@ is_directory(const Filename &file) const { */ bool VirtualFileMountSystem:: is_regular_file(const Filename &file) const { -#ifdef WIN32 +#ifdef _WIN32 // First ensure that the file exists to validate its case. if (VirtualFileSystem::get_global_ptr()->vfs_case_sensitive) { if (!has_file(file)) { @@ -151,7 +151,7 @@ is_regular_file(const Filename &file) const { */ bool VirtualFileMountSystem:: is_writable(const Filename &file) const { -#ifdef WIN32 +#ifdef _WIN32 // First ensure that the file exists to validate its case. if (VirtualFileSystem::get_global_ptr()->vfs_case_sensitive) { if (!has_file(file)) { @@ -170,7 +170,7 @@ is_writable(const Filename &file) const { */ istream *VirtualFileMountSystem:: open_read_file(const Filename &file) const { -#ifdef WIN32 +#ifdef _WIN32 // First ensure that the file exists to validate its case. if (VirtualFileSystem::get_global_ptr()->vfs_case_sensitive) { if (!has_file(file)) { @@ -196,7 +196,7 @@ open_read_file(const Filename &file) const { */ ostream *VirtualFileMountSystem:: open_write_file(const Filename &file, bool truncate) { -#ifdef WIN32 +#ifdef _WIN32 // First ensure that the file exists to validate its case. if (VirtualFileSystem::get_global_ptr()->vfs_case_sensitive) { if (!has_file(file)) { @@ -222,7 +222,7 @@ open_write_file(const Filename &file, bool truncate) { */ ostream *VirtualFileMountSystem:: open_append_file(const Filename &file) { -#ifdef WIN32 +#ifdef _WIN32 // First ensure that the file exists to validate its case. if (VirtualFileSystem::get_global_ptr()->vfs_case_sensitive) { if (!has_file(file)) { @@ -248,7 +248,7 @@ open_append_file(const Filename &file) { */ iostream *VirtualFileMountSystem:: open_read_write_file(const Filename &file, bool truncate) { -#ifdef WIN32 +#ifdef _WIN32 // First ensure that the file exists to validate its case. if (VirtualFileSystem::get_global_ptr()->vfs_case_sensitive) { if (!has_file(file)) { @@ -274,7 +274,7 @@ open_read_write_file(const Filename &file, bool truncate) { */ iostream *VirtualFileMountSystem:: open_read_append_file(const Filename &file) { -#ifdef WIN32 +#ifdef _WIN32 // First ensure that the file exists to validate its case. if (VirtualFileSystem::get_global_ptr()->vfs_case_sensitive) { if (!has_file(file)) { @@ -368,7 +368,7 @@ get_system_info(const Filename &file, SubfileInfo &info) { */ bool VirtualFileMountSystem:: scan_directory(vector_string &contents, const Filename &dir) const { -#ifdef WIN32 +#ifdef _WIN32 // First ensure that the file exists to validate its case. if (VirtualFileSystem::get_global_ptr()->vfs_case_sensitive) { if (!has_file(dir)) { @@ -388,7 +388,7 @@ bool VirtualFileMountSystem:: atomic_compare_and_exchange_contents(const Filename &file, string &orig_contents, const string &old_contents, const string &new_contents) { -#ifdef WIN32 +#ifdef _WIN32 // First ensure that the file exists to validate its case. if (VirtualFileSystem::get_global_ptr()->vfs_case_sensitive) { if (!has_file(file)) { @@ -405,7 +405,7 @@ atomic_compare_and_exchange_contents(const Filename &file, string &orig_contents */ bool VirtualFileMountSystem:: atomic_read_contents(const Filename &file, string &contents) const { -#ifdef WIN32 +#ifdef _WIN32 // First ensure that the file exists to validate its case. if (VirtualFileSystem::get_global_ptr()->vfs_case_sensitive) { if (!has_file(file)) { diff --git a/panda/src/express/virtualFileSystem.cxx b/panda/src/express/virtualFileSystem.cxx index eda84c4075..fe87f29645 100644 --- a/panda/src/express/virtualFileSystem.cxx +++ b/panda/src/express/virtualFileSystem.cxx @@ -870,7 +870,7 @@ close_read_file(istream *stream) { // stream pointer does not call the appropriate global delete function; // instead apparently calling the system delete function. So we call the // delete function by hand instead. -#if (!defined(WIN32_VC) && !defined(WIN64_VC)) && !defined(USE_MEMORY_NOWRAPPERS) && defined(REDEFINE_GLOBAL_OPERATOR_NEW) +#if defined(__GNUC__) && !defined(USE_MEMORY_NOWRAPPERS) && defined(REDEFINE_GLOBAL_OPERATOR_NEW) stream->~istream(); (*global_operator_delete)(stream); #else @@ -929,7 +929,7 @@ open_append_file(const Filename &filename) { void VirtualFileSystem:: close_write_file(ostream *stream) { if (stream != nullptr) { -#if (!defined(WIN32_VC) && !defined(WIN64_VC)) && !defined(USE_MEMORY_NOWRAPPERS) && defined(REDEFINE_GLOBAL_OPERATOR_NEW) +#if defined(__GNUC__) && !defined(USE_MEMORY_NOWRAPPERS) && defined(REDEFINE_GLOBAL_OPERATOR_NEW) stream->~ostream(); (*global_operator_delete)(stream); #else @@ -985,7 +985,7 @@ open_read_append_file(const Filename &filename) { void VirtualFileSystem:: close_read_write_file(iostream *stream) { if (stream != nullptr) { -#if (!defined(WIN32_VC) && !defined(WIN64_VC)) && !defined(USE_MEMORY_NOWRAPPERS) && defined(REDEFINE_GLOBAL_OPERATOR_NEW) +#if defined(__GNUC__) && !defined(USE_MEMORY_NOWRAPPERS) && defined(REDEFINE_GLOBAL_OPERATOR_NEW) stream->~iostream(); (*global_operator_delete)(stream); #else diff --git a/panda/src/ffmpeg/CMakeLists.txt b/panda/src/ffmpeg/CMakeLists.txt new file mode 100644 index 0000000000..a78a3d2cdc --- /dev/null +++ b/panda/src/ffmpeg/CMakeLists.txt @@ -0,0 +1,45 @@ +if(NOT HAVE_FFMPEG) + return() +endif() + +set(P3FFMPEG_HEADERS + config_ffmpeg.h + ffmpegVideo.h ffmpegVideo.I + ffmpegVideoCursor.h ffmpegVideoCursor.I + ffmpegAudio.h ffmpegAudio.I + ffmpegAudioCursor.h ffmpegAudioCursor.I + ffmpegVirtualFile.h ffmpegVirtualFile.I +) + +set(P3FFMPEG_SOURCES + config_ffmpeg.cxx + ffmpegVideo.cxx + ffmpegVideoCursor.cxx + ffmpegAudio.cxx + ffmpegAudioCursor.cxx + ffmpegVirtualFile.cxx +) + +composite_sources(p3ffmpeg P3FFMPEG_SOURCES) +add_library(p3ffmpeg ${MODULE_TYPE} ${P3FFMPEG_HEADERS} ${P3FFMPEG_SOURCES}) +set_target_properties(p3ffmpeg PROPERTIES DEFINE_SYMBOL BUILDING_FFMPEG) +target_link_libraries(p3ffmpeg panda + PKG::FFMPEG PKG::SWSCALE PKG::SWRESAMPLE) + +if(HAVE_SWSCALE) + target_compile_definitions(p3ffmpeg PRIVATE HAVE_SWSCALE) +endif() + +if(HAVE_SWRESAMPLE) + target_compile_definitions(p3ffmpeg PRIVATE HAVE_SWRESAMPLE) +endif() + +install(TARGETS p3ffmpeg + EXPORT FFmpeg COMPONENT FFmpeg + DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d + ARCHIVE COMPONENT FFmpegDevel) +install(FILES ${P3FFMPEG_HEADERS} COMPONENT FFmpegDevel DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d) + +export_targets(FFmpeg COMPONENT FFmpegDevel) diff --git a/panda/src/framework/CMakeLists.txt b/panda/src/framework/CMakeLists.txt new file mode 100644 index 0000000000..d299c86bd1 --- /dev/null +++ b/panda/src/framework/CMakeLists.txt @@ -0,0 +1,62 @@ +set(P3FRAMEWORK_HEADERS + config_framework.h + pandaFramework.I pandaFramework.h + windowFramework.I windowFramework.h +) + +set(P3FRAMEWORK_SOURCES + config_framework.cxx + pandaFramework.cxx + windowFramework.cxx +) + + +set(P3FRAMEWORK_LINK_TARGETS panda) +if(NOT BUILD_SHARED_LIBS) + # If we're statically linking, we need to explicitly link with + # at least one of the available renderers. + if(HAVE_GL) + list(APPEND P3FRAMEWORK_LINK_TARGETS pandagl) + elseif(HAVE_DX9) + list(APPEND P3FRAMEWORK_LINK_TARGETS pandadx9) + elseif(HAVE_TINYDISPLAY) + list(APPEND P3FRAMEWORK_LINK_TARGETS p3tinydisplay) + else() + message(WARNING "No renderer library available to link to p3framework.") + endif() + + # And we might like to have the p3egg loader available. + if(HAVE_EGG) + list(APPEND P3FRAMEWORK_LINK_TARGETS pandaegg) + endif() + +endif() + +composite_sources(p3framework P3FRAMEWORK_SOURCES) +# This one isn't a component library +add_library(p3framework ${P3FRAMEWORK_HEADERS} ${P3FRAMEWORK_SOURCES}) +set_target_properties(p3framework PROPERTIES DEFINE_SYMBOL BUILDING_FRAMEWORK) +target_link_libraries(p3framework ${P3FRAMEWORK_LINK_TARGETS}) + +foreach(var + HAVE_GL + HAVE_TINYDISPLAY + HAVE_DX9 + HAVE_EGG +) + + if(${var}) + target_compile_definitions(p3framework PRIVATE ${var}) + endif() + +endforeach(var) + +install(TARGETS p3framework + EXPORT Framework COMPONENT Framework + DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d + ARCHIVE COMPONENT FrameworkDevel) +install(FILES ${P3FRAMEWORK_HEADERS} COMPONENT FrameworkDevel DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d) + +export_targets(Framework COMPONENT FrameworkDevel) diff --git a/panda/src/gles2gsg/CMakeLists.txt b/panda/src/gles2gsg/CMakeLists.txt new file mode 100644 index 0000000000..62c4c90c8b --- /dev/null +++ b/panda/src/gles2gsg/CMakeLists.txt @@ -0,0 +1,29 @@ +if(NOT HAVE_GLES2) + return() +endif() + +set(P3GLES2GSG_HEADERS + config_gles2gsg.h + gles2gsg.h +) + +set(P3GLES2GSG_SOURCES + config_gles2gsg.cxx + gles2gsg.cxx +) + +composite_sources(p3gles2gsg P3GLES2GSG_SOURCES) +add_component_library(p3gles2gsg SYMBOL BUILDING_PANDAGLES2 + ${P3GLE2SGSG_HEADERS} ${P3GLES2GSG_SOURCES}) +target_link_libraries(p3gles2gsg p3glstuff panda + PKG::GLES2) + +if(NOT BUILD_METALIBS) + install(TARGETS p3gles2gsg + EXPORT OpenGLES2 COMPONENT OpenGLES2 + DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d + ARCHIVE COMPONENT OpenGLES2Devel) +endif() +install(FILES ${P3GLES2GSG_HEADERS} COMPONENT OpenGLES2Devel DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d) diff --git a/panda/src/glesgsg/CMakeLists.txt b/panda/src/glesgsg/CMakeLists.txt new file mode 100644 index 0000000000..c956b882d6 --- /dev/null +++ b/panda/src/glesgsg/CMakeLists.txt @@ -0,0 +1,29 @@ +if(NOT HAVE_GLES1) + return() +endif() + +set(P3GLESGSG_HEADERS + config_glesgsg.h + glesgsg.h +) + +set(P3GLESGSG_SOURCES + config_glesgsg.cxx + glesgsg.cxx +) + +composite_sources(p3glesgsg P3GLESGSG_SOURCES) +add_component_library(p3glesgsg SYMBOL BUILDING_PANDAGLES + ${P3GLESGSG_HEADERS} ${P3GLESGSG_SOURCES}) +target_link_libraries(p3glesgsg p3glstuff panda + PKG::GLES1) + +if(NOT BUILD_METALIBS) + install(TARGETS p3glesgsg + EXPORT OpenGLES1 COMPONENT OpenGLES1 + DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d + ARCHIVE COMPONENT OpenGLES1Devel) +endif() +install(FILES ${P3GLESGSG_HEADERS} COMPONENT OpenGLES1Devel DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d) diff --git a/panda/src/glgsg/CMakeLists.txt b/panda/src/glgsg/CMakeLists.txt new file mode 100644 index 0000000000..d8ddad03bb --- /dev/null +++ b/panda/src/glgsg/CMakeLists.txt @@ -0,0 +1,28 @@ +if(NOT HAVE_GL) + return() +endif() + +set(P3GLGSG_HEADERS + config_glgsg.h glgsg.h +) + +set(P3GLGSG_SOURCES + config_glgsg.cxx + glgsg.cxx +) + +composite_sources(p3glgsg P3GLGSG_SOURCES) +add_component_library(p3glgsg SYMBOL BUILDING_PANDA_GLGSG + ${P3GLGSG_HEADERS} ${P3GLGSG_SOURCES}) +target_link_libraries(p3glgsg p3glstuff panda + PKG::CG PKG::GL) + +if(NOT BUILD_METALIBS) + install(TARGETS p3glgsg + EXPORT OpenGL COMPONENT OpenGL + DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d + ARCHIVE COMPONENT OpenGLDevel) +endif() +install(FILES ${P3GLGSG_HEADERS} COMPONENT OpenGLDevel DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d) diff --git a/panda/src/glstuff/CMakeLists.txt b/panda/src/glstuff/CMakeLists.txt new file mode 100644 index 0000000000..016dafa81a --- /dev/null +++ b/panda/src/glstuff/CMakeLists.txt @@ -0,0 +1,54 @@ +if(NOT HAVE_GL) + return() +endif() + +set(P3GLSTUFF_HEADERS + glGeomContext_src.I + glGeomContext_src.h + glGeomMunger_src.I + glGeomMunger_src.h + glGraphicsStateGuardian_src.I + glGraphicsStateGuardian_src.h + glGraphicsBuffer_src.I + glGraphicsBuffer_src.h + glImmediateModeSender_src.I + glImmediateModeSender_src.h + glIndexBufferContext_src.I + glIndexBufferContext_src.h + glOcclusionQueryContext_src.I + glOcclusionQueryContext_src.h + glShaderContext_src.I + glShaderContext_src.h + glTextureContext_src.I + glTextureContext_src.h + glVertexBufferContext_src.I + glVertexBufferContext_src.h + glmisc_src.h + glstuff_src.h + glstuff_undef_src.h + panda_glext.h +) + +set(P3GLSTUFF_SOURCES + glpure.cxx +) + +composite_sources(p3glstuff P3GLSTUFF_SOURCES) +add_component_library(p3glstuff NOINIT ${P3GLSTUFF_HEADERS} ${P3GLSTUFF_SOURCES}) +target_link_libraries(p3glstuff panda) + +if(APPLE) + # We acknowledge Apple's hostility to open standards so that the SDK won't + # bother our users about it. + target_compile_definitions(p3glstuff PUBLIC GL_SILENCE_DEPRECATION) +endif() + +if(NOT BUILD_METALIBS) + install(TARGETS p3glstuff + EXPORT OpenGL COMPONENT OpenGL + DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d + ARCHIVE COMPONENT OpenGLDevel) +endif() +install(FILES ${P3GLSTUFF_HEADERS} COMPONENT OpenGLDevel DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d) diff --git a/panda/src/glstuff/glCgShaderContext_src.cxx b/panda/src/glstuff/glCgShaderContext_src.cxx index 8d90d1cd50..23d765b349 100644 --- a/panda/src/glstuff/glCgShaderContext_src.cxx +++ b/panda/src/glstuff/glCgShaderContext_src.cxx @@ -338,6 +338,8 @@ CLP(CgShaderContext)(CLP(GraphicsStateGuardian) *glgsg, Shader *s) : ShaderConte } } + _mat_part_cache = new LMatrix4[_shader->cp_get_mat_cache_size()]; + _glgsg->report_my_gl_errors(); } @@ -347,6 +349,7 @@ CLP(CgShaderContext)(CLP(GraphicsStateGuardian) *glgsg, Shader *s) : ShaderConte CLP(CgShaderContext):: ~CLP(CgShaderContext)() { // Don't call release_resources; we may not have an active context. + delete[] _mat_part_cache; } /** @@ -690,14 +693,14 @@ issue_parameters(int altered) { } if (altered & _shader->_mat_deps) { - for (int i = 0; i < (int)_shader->_mat_spec.size(); ++i) { - Shader::ShaderMatSpec &spec = _shader->_mat_spec[i]; + _glgsg->update_shader_matrix_cache(_shader, _mat_part_cache, altered); - if ((altered & (spec._dep[0] | spec._dep[1])) == 0) { + for (Shader::ShaderMatSpec &spec : _shader->_mat_spec) { + if ((altered & spec._dep) == 0) { continue; } - const LMatrix4 *val = _glgsg->fetch_specified_value(spec, altered); + const LMatrix4 *val = _glgsg->fetch_specified_value(spec, _mat_part_cache, altered); if (!val) continue; const PN_stdfloat *data = val->get_data(); diff --git a/panda/src/glstuff/glCgShaderContext_src.h b/panda/src/glstuff/glCgShaderContext_src.h index 553cafe487..35a2d5dd36 100644 --- a/panda/src/glstuff/glCgShaderContext_src.h +++ b/panda/src/glstuff/glCgShaderContext_src.h @@ -75,6 +75,7 @@ private: long _transform_table_size; long _slider_table_size; + LMatrix4 *_mat_part_cache = nullptr; pvector _cg_parameter_map; WCPT(RenderState) _state_rs; diff --git a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx index a6173f28b7..ff6ed7dd3e 100644 --- a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx +++ b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx @@ -1776,9 +1776,9 @@ reset() { _shader_caps._active_gprofile = (int)CG_PROFILE_GLSLG; } } - _shader_caps._ultimate_vprofile = (int)CG_PROFILE_VP40; - _shader_caps._ultimate_fprofile = (int)CG_PROFILE_FP40; - _shader_caps._ultimate_gprofile = (int)CG_PROFILE_GPU_GP; + _shader_caps._ultimate_vprofile = (int)CG_PROFILE_GLSLV; + _shader_caps._ultimate_fprofile = (int)CG_PROFILE_GLSLF; + _shader_caps._ultimate_gprofile = (int)CG_PROFILE_GLSLG; // Bug workaround for radeons. if (_shader_caps._active_fprofile == CG_PROFILE_ARBFP1) { diff --git a/panda/src/glstuff/glShaderContext_src.cxx b/panda/src/glstuff/glShaderContext_src.cxx index 6032417124..eb9c534b44 100644 --- a/panda/src/glstuff/glShaderContext_src.cxx +++ b/panda/src/glstuff/glShaderContext_src.cxx @@ -228,9 +228,7 @@ parse_and_set_short_hand_shader_vars(Shader::ShaderArgId &arg_id, GLenum param_t bind._part[1] = Shader::SMO_apiclip_to_view; } - objShader->cp_optimize_mat_spec(bind); - objShader->_mat_spec.push_back(bind); - objShader->_mat_deps |= bind._dep[0] | bind._dep[1]; + objShader->cp_add_mat_spec(bind); if (param_size > 1) { // We support arrays of rows and arrays of columns, so we can run the @@ -243,7 +241,7 @@ parse_and_set_short_hand_shader_vars(Shader::ShaderArgId &arg_id, GLenum param_t for (int i = 1; i < param_size; ++i) { bind._id._seqno += 1; bind._piece = (Shader::ShaderMatPiece)((int)bind._piece + 1); - objShader->_mat_spec.push_back(bind); + objShader->cp_add_mat_spec(bind); } } else { GLCAT.warning() << basename << "[" << param_size << "] should not be an array, only the first element will be defined\n"; @@ -380,6 +378,8 @@ CLP(ShaderContext)(CLP(GraphicsStateGuardian) *glgsg, Shader *s) : ShaderContext } else { _glgsg->_current_shader_context->bind(); } + + _mat_part_cache = new LMatrix4[_shader->cp_get_mat_cache_size()]; } /** @@ -885,15 +885,22 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) { bind._part[0] = inverse ? Shader::SMO_inv_texmat_i : Shader::SMO_texmat_i; bind._part[1] = Shader::SMO_identity; - bind._dep[0] = Shader::SSD_general | Shader::SSD_tex_matrix; - bind._dep[1] = 0; // Add it once for each index. for (bind._index = 0; bind._index < param_size; ++bind._index) { + // It was discovered in #846, that GLSL 4.10 and lower don't seem to + // guarantee that matrices occupy successive locations, and on macOS + // they indeed occupy four locations per element. + // As a big fat hack, we multiply by four on macOS, because this is + // hard to fix on the 1.10 branch. We'll have a proper fix on the + // master branch. +#ifdef __APPLE__ + bind._id._seqno = p + bind._index * 4; +#else bind._id._seqno = p + bind._index; - _shader->_mat_spec.push_back(bind); +#endif + _shader->cp_add_mat_spec(bind); } - _shader->_mat_deps |= bind._dep[0]; return; } else if (matrix_name.size() > 15 && @@ -938,9 +945,7 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) { GLCAT.error() << "Unrecognized uniform matrix name '" << matrix_name << "'!\n"; return; } - _shader->cp_optimize_mat_spec(bind); - _shader->_mat_spec.push_back(bind); - _shader->_mat_deps |= bind._dep[0] | bind._dep[1]; + _shader->cp_add_mat_spec(bind); return; } if (size > 7 && noprefix.substr(0, 7) == "Texture") { @@ -973,10 +978,8 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) { bind._func = Shader::SMF_first; bind._part[0] = Shader::SMO_attr_material; bind._arg[0] = nullptr; - bind._dep[0] = Shader::SSD_general | Shader::SSD_material | Shader::SSD_frame; bind._part[1] = Shader::SMO_identity; bind._arg[1] = nullptr; - bind._dep[1] = Shader::SSD_NONE; if (noprefix == "Material.baseColor") { if (param_type != GL_FLOAT_VEC4) { @@ -985,9 +988,7 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) { } bind._part[0] = Shader::SMO_attr_material2; bind._piece = Shader::SMP_row0; - bind._dep[0] |= Shader::SSD_color; - _shader->_mat_spec.push_back(bind); - _shader->_mat_deps |= bind._dep[0]; + _shader->cp_add_mat_spec(bind); return; } else if (noprefix == "Material.ambient") { @@ -996,8 +997,7 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) { << "p3d_Material.ambient should be vec4\n"; } bind._piece = Shader::SMP_row0; - _shader->_mat_spec.push_back(bind); - _shader->_mat_deps |= bind._dep[0]; + _shader->cp_add_mat_spec(bind); return; } else if (noprefix == "Material.diffuse") { @@ -1006,8 +1006,7 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) { << "p3d_Material.diffuse should be vec4\n"; } bind._piece = Shader::SMP_row1; - _shader->_mat_spec.push_back(bind); - _shader->_mat_deps |= bind._dep[0]; + _shader->cp_add_mat_spec(bind); return; } else if (noprefix == "Material.emission") { @@ -1016,8 +1015,7 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) { << "p3d_Material.emission should be vec4\n"; } bind._piece = Shader::SMP_row2; - _shader->_mat_spec.push_back(bind); - _shader->_mat_deps |= bind._dep[0]; + _shader->cp_add_mat_spec(bind); return; } else if (noprefix == "Material.specular") { @@ -1026,8 +1024,7 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) { << "p3d_Material.specular should be vec3\n"; } bind._piece = Shader::SMP_row3x3; - _shader->_mat_spec.push_back(bind); - _shader->_mat_deps |= bind._dep[0]; + _shader->cp_add_mat_spec(bind); return; } else if (noprefix == "Material.shininess") { @@ -1036,8 +1033,7 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) { << "p3d_Material.shininess should be float\n"; } bind._piece = Shader::SMP_cell15; - _shader->_mat_spec.push_back(bind); - _shader->_mat_deps |= bind._dep[0]; + _shader->cp_add_mat_spec(bind); return; } else if (noprefix == "Material.roughness") { @@ -1047,8 +1043,7 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) { } bind._part[0] = Shader::SMO_attr_material2; bind._piece = Shader::SMP_cell15; - _shader->_mat_spec.push_back(bind); - _shader->_mat_deps |= bind._dep[0]; + _shader->cp_add_mat_spec(bind); return; } else if (noprefix == "Material.metallic") { @@ -1058,8 +1053,7 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) { } bind._part[0] = Shader::SMO_attr_material2; bind._piece = Shader::SMP_row3x1; - _shader->_mat_spec.push_back(bind); - _shader->_mat_deps |= bind._dep[0]; + _shader->cp_add_mat_spec(bind); return; } else if (noprefix == "Material.refractiveIndex") { @@ -1069,8 +1063,7 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) { } bind._part[0] = Shader::SMO_attr_material2; bind._piece = Shader::SMP_cell13; - _shader->_mat_spec.push_back(bind); - _shader->_mat_deps |= bind._dep[0]; + _shader->cp_add_mat_spec(bind); return; } } @@ -1080,10 +1073,8 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) { bind._func = Shader::SMF_first; bind._part[0] = Shader::SMO_attr_colorscale; bind._arg[0] = nullptr; - bind._dep[0] = Shader::SSD_general | Shader::SSD_colorscale; bind._part[1] = Shader::SMO_identity; bind._arg[1] = nullptr; - bind._dep[1] = Shader::SSD_NONE; if (param_type == GL_FLOAT_VEC3) { bind._piece = Shader::SMP_row3x3; @@ -1094,8 +1085,7 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) { << "p3d_ColorScale should be vec3 or vec4\n"; return; } - _shader->_mat_spec.push_back(bind); - _shader->_mat_deps |= bind._dep[0]; + _shader->cp_add_mat_spec(bind); return; } if (noprefix == "Color") { @@ -1104,10 +1094,8 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) { bind._func = Shader::SMF_first; bind._part[0] = Shader::SMO_attr_color; bind._arg[0] = nullptr; - bind._dep[0] = Shader::SSD_general | Shader::SSD_color; bind._part[1] = Shader::SMO_identity; bind._arg[1] = nullptr; - bind._dep[1] = Shader::SSD_NONE; if (param_type == GL_FLOAT_VEC3) { bind._piece = Shader::SMP_row3x3; @@ -1118,8 +1106,7 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) { << "p3d_Color should be vec3 or vec4\n"; return; } - _shader->_mat_spec.push_back(bind); - _shader->_mat_deps |= bind._dep[0]; + _shader->cp_add_mat_spec(bind); return; } if (noprefix == "ClipPlane") { @@ -1137,12 +1124,9 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) { bind._index = i; bind._part[0] = Shader::SMO_apiview_clipplane_i; bind._arg[0] = nullptr; - bind._dep[0] = Shader::SSD_general | Shader::SSD_clip_planes; bind._part[1] = Shader::SMO_identity; bind._arg[1] = nullptr; - bind._dep[1] = Shader::SSD_NONE; - _shader->_mat_spec.push_back(bind); - _shader->_mat_deps |= bind._dep[0]; + _shader->cp_add_mat_spec(bind); } return; } @@ -1151,10 +1135,8 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) { bind._id = arg_id; bind._func = Shader::SMF_first; bind._arg[0] = nullptr; - bind._dep[0] = Shader::SSD_general | Shader::SSD_fog; bind._part[1] = Shader::SMO_identity; bind._arg[1] = nullptr; - bind._dep[1] = Shader::SSD_NONE; if (noprefix == "Fog.color") { bind._part[0] = Shader::SMO_attr_fogcolor; @@ -1214,8 +1196,7 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) { } } - _shader->_mat_spec.push_back(bind); - _shader->_mat_deps |= bind._dep[0]; + _shader->cp_add_mat_spec(bind); return; } if (noprefix == "LightModel.ambient") { @@ -1224,10 +1205,8 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) { bind._func = Shader::SMF_first; bind._part[0] = Shader::SMO_light_ambient; bind._arg[0] = nullptr; - bind._dep[0] = Shader::SSD_general | Shader::SSD_light; bind._part[1] = Shader::SMO_identity; bind._arg[1] = nullptr; - bind._dep[1] = Shader::SSD_NONE; if (param_type == GL_FLOAT_VEC3) { bind._piece = Shader::SMP_row3x3; @@ -1238,8 +1217,7 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) { << "p3d_LightModel.ambient should be vec3 or vec4\n"; return; } - _shader->_mat_spec.push_back(bind); - _shader->_mat_deps |= bind._dep[0]; + _shader->cp_add_mat_spec(bind); return; } if (size > 15 && noprefix.substr(0, 12) == "LightSource[") { @@ -1279,15 +1257,8 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) { bind._index = index; bind._part[0] = Shader::SMO_light_source_i_attrib; bind._arg[0] = InternalName::make(member_name); - bind._dep[0] = Shader::SSD_general | Shader::SSD_light | Shader::SSD_frame; bind._part[1] = Shader::SMO_identity; bind._arg[1] = nullptr; - bind._dep[1] = Shader::SSD_NONE; - - if (member_name == "position" || member_name == "halfVector" || - member_name == "spotDirection") { - bind._dep[0] |= Shader::SSD_view_transform; - } switch (param_type) { case GL_FLOAT: @@ -1311,8 +1282,7 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) { << "p3d_LightSource[]." << member_name << " should be float or vec\n"; return; } - _shader->_mat_spec.push_back(bind); - _shader->_mat_deps |= bind._dep[0] | bind._dep[1]; + _shader->cp_add_mat_spec(bind); return; } } @@ -1344,13 +1314,10 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) { bind._index = 0; bind._part[0] = Shader::SMO_tex_is_alpha_i; bind._arg[0] = nullptr; - bind._dep[0] = Shader::SSD_general | Shader::SSD_texture | Shader::SSD_frame; bind._part[1] = Shader::SMO_identity; bind._arg[1] = nullptr; - bind._dep[1] = Shader::SSD_NONE; bind._piece = Shader::SMP_row3; - _shader->_mat_spec.push_back(bind); - _shader->_mat_deps |= bind._dep[0] | bind._dep[1]; + _shader->cp_add_mat_spec(bind); return; } GLCAT.error() << "Unrecognized uniform name '" << param_name << "'!\n"; @@ -1371,10 +1338,7 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) { bind._func = Shader::SMF_compose; bind._part[0] = Shader::SMO_world_to_view; bind._part[1] = Shader::SMO_view_to_apiview; - bind._dep[0] = Shader::SSD_general | Shader::SSD_view_transform; - bind._dep[1] = Shader::SSD_general; - _shader->_mat_spec.push_back(bind); - _shader->_mat_deps |= bind._dep[0] | bind._dep[1]; + _shader->cp_add_mat_spec(bind); return; } else if (noprefix == "InverseViewMatrix" || noprefix == "ViewMatrixInverse") { @@ -1382,10 +1346,7 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) { bind._func = Shader::SMF_compose; bind._part[0] = Shader::SMO_apiview_to_view; bind._part[1] = Shader::SMO_view_to_world; - bind._dep[0] = Shader::SSD_general; - bind._dep[1] = Shader::SSD_general | Shader::SSD_view_transform; - _shader->_mat_spec.push_back(bind); - _shader->_mat_deps |= bind._dep[0] | bind._dep[1]; + _shader->cp_add_mat_spec(bind); return; } else if (noprefix == "FrameTime") { @@ -1393,10 +1354,7 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) { bind._func = Shader::SMF_first; bind._part[0] = Shader::SMO_frame_time; bind._part[1] = Shader::SMO_identity; - bind._dep[0] = Shader::SSD_general | Shader::SSD_frame; - bind._dep[1] = Shader::SSD_NONE; - _shader->_mat_spec.push_back(bind); - _shader->_mat_deps |= bind._dep[0] | bind._dep[1]; + _shader->cp_add_mat_spec(bind); return; } else if (noprefix == "DeltaFrameTime") { @@ -1404,10 +1362,7 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) { bind._func = Shader::SMF_first; bind._part[0] = Shader::SMO_frame_delta; bind._part[1] = Shader::SMO_identity; - bind._dep[0] = Shader::SSD_general | Shader::SSD_frame; - bind._dep[1] = Shader::SSD_NONE; - _shader->_mat_spec.push_back(bind); - _shader->_mat_deps |= bind._dep[0] | bind._dep[1]; + _shader->cp_add_mat_spec(bind); return; } else if (noprefix == "FrameNumber") { @@ -1491,12 +1446,9 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) { bind._func = Shader::SMF_first; bind._part[0] = Shader::SMO_mat_constant_x; bind._arg[0] = InternalName::make(param_name); - bind._dep[0] = Shader::SSD_general | Shader::SSD_shaderinputs | Shader::SSD_frame; bind._part[1] = Shader::SMO_identity; bind._arg[1] = nullptr; - bind._dep[1] = Shader::SSD_NONE; - _shader->_mat_spec.push_back(bind); - _shader->_mat_deps |= bind._dep[0]; + _shader->cp_add_mat_spec(bind); return; } case GL_FLOAT_MAT4: { @@ -1506,7 +1458,6 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) { bind._func = Shader::SMF_first; bind._part[1] = Shader::SMO_identity; bind._arg[1] = nullptr; - bind._dep[1] = Shader::SSD_NONE; PT(InternalName) iname = InternalName::make(param_name); if (iname->get_parent() != InternalName::get_root()) { // It might be something like an attribute of a shader input, like a @@ -1527,22 +1478,17 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) { bind._func = Shader::SMF_compose; bind._part[0] = Shader::SMO_model_to_apiview; bind._arg[0] = nullptr; - bind._dep[0] = Shader::SSD_general | Shader::SSD_transform; bind._part[1] = Shader::SMO_mat_constant_x_attrib; bind._arg[1] = iname->get_parent()->append("shadowViewMatrix"); - bind._dep[1] = Shader::SSD_general | Shader::SSD_shaderinputs | Shader::SSD_frame | Shader::SSD_view_transform; } else { bind._part[0] = Shader::SMO_mat_constant_x_attrib; bind._arg[0] = InternalName::make(param_name); - bind._dep[0] = Shader::SSD_general | Shader::SSD_shaderinputs | Shader::SSD_frame | Shader::SSD_view_transform; } } else { bind._part[0] = Shader::SMO_mat_constant_x; bind._arg[0] = InternalName::make(param_name); - bind._dep[0] = Shader::SSD_general | Shader::SSD_shaderinputs | Shader::SSD_frame; } - _shader->_mat_spec.push_back(bind); - _shader->_mat_deps |= bind._dep[0]; + _shader->cp_add_mat_spec(bind); return; } case GL_FLOAT: @@ -1572,14 +1518,9 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) { bind._func = Shader::SMF_first; bind._part[0] = Shader::SMO_vec_constant_x_attrib; bind._arg[0] = iname; - // We need SSD_view_transform since some attributes (eg. light - // position) have to be transformed to view space. - bind._dep[0] = Shader::SSD_general | Shader::SSD_shaderinputs | Shader::SSD_frame | Shader::SSD_view_transform; bind._part[1] = Shader::SMO_identity; bind._arg[1] = nullptr; - bind._dep[1] = Shader::SSD_NONE; - _shader->_mat_spec.push_back(bind); - _shader->_mat_deps |= bind._dep[0]; + _shader->cp_add_mat_spec(bind); return; } // else fall through } @@ -1913,6 +1854,7 @@ get_sampler_texture_type(int &out, GLenum param_type) { CLP(ShaderContext):: ~CLP(ShaderContext)() { // Don't call release_resources; we may not have an active context. + delete[] _mat_part_cache; } /** @@ -2230,14 +2172,14 @@ issue_parameters(int altered) { } if (altered & _shader->_mat_deps) { - for (int i = 0; i < (int)_shader->_mat_spec.size(); ++i) { - Shader::ShaderMatSpec &spec = _shader->_mat_spec[i]; + _glgsg->update_shader_matrix_cache(_shader, _mat_part_cache, altered); - if ((altered & (spec._dep[0] | spec._dep[1])) == 0) { + for (Shader::ShaderMatSpec &spec : _shader->_mat_spec) { + if ((altered & spec._dep) == 0) { continue; } - const LMatrix4 *val = _glgsg->fetch_specified_value(spec, altered); + const LMatrix4 *val = _glgsg->fetch_specified_value(spec, _mat_part_cache, altered); if (!val) continue; #ifndef STDFLOAT_DOUBLE // In this case, the data is already single-precision. diff --git a/panda/src/glstuff/glShaderContext_src.h b/panda/src/glstuff/glShaderContext_src.h index 0ccb99fe90..06561336fa 100644 --- a/panda/src/glstuff/glShaderContext_src.h +++ b/panda/src/glstuff/glShaderContext_src.h @@ -114,6 +114,8 @@ private: }; pvector _glsl_img_inputs; + LMatrix4 *_mat_part_cache = nullptr; + CLP(GraphicsStateGuardian) *_glgsg; bool _uses_standard_vertex_arrays; diff --git a/panda/src/glstuff/glmisc_src.h b/panda/src/glstuff/glmisc_src.h index 415286c674..b77143ce70 100644 --- a/panda/src/glstuff/glmisc_src.h +++ b/panda/src/glstuff/glmisc_src.h @@ -87,7 +87,7 @@ extern ConfigVariableEnum gl_coordinate_system; extern EXPCL_GL void CLP(init_classes)(); -#if !defined(WIN32) && defined(GSG_VERBOSE) +#if !defined(_WIN32) && defined(GSG_VERBOSE) std::ostream &output_gl_enum(std::ostream &out, GLenum v); INLINE std::ostream &operator << (std::ostream &out, GLenum v) { return output_gl_enum(out, v); diff --git a/panda/src/glstuff/glpure.cxx b/panda/src/glstuff/glpure.cxx index 15d3c7c4aa..c3913fccee 100644 --- a/panda/src/glstuff/glpure.cxx +++ b/panda/src/glstuff/glpure.cxx @@ -16,7 +16,7 @@ // This is the one file in this directory which is actually compiled. It // exists just so we can have some symbols and make the compiler happy. -#if (defined(WIN32_VC) || defined(WIN64_VC)) && !defined(CPPPARSER) && !defined(LINK_ALL_STATIC) +#if defined(_WIN32) && !defined(CPPPARSER) && !defined(LINK_ALL_STATIC) __declspec(dllexport) #endif int glpure; diff --git a/panda/src/glxdisplay/CMakeLists.txt b/panda/src/glxdisplay/CMakeLists.txt new file mode 100644 index 0000000000..06dcc5cc0e --- /dev/null +++ b/panda/src/glxdisplay/CMakeLists.txt @@ -0,0 +1,33 @@ +if(NOT HAVE_GLX) + return() +endif() + +set(P3GLXDISPLAY_HEADERS + config_glxdisplay.h + glxGraphicsBuffer.h glxGraphicsBuffer.I + glxGraphicsPipe.h glxGraphicsPipe.I + glxGraphicsPixmap.h glxGraphicsPixmap.I + glxGraphicsWindow.h glxGraphicsWindow.I + glxGraphicsStateGuardian.h glxGraphicsStateGuardian.I + posixGraphicsStateGuardian.h posixGraphicsStateGuardian.I + panda_glxext.h +) + +set(P3GLXDISPLAY_SOURCES + config_glxdisplay.cxx + glxGraphicsBuffer.cxx + glxGraphicsPipe.cxx + glxGraphicsPixmap.cxx + glxGraphicsWindow.cxx + glxGraphicsStateGuardian.cxx + posixGraphicsStateGuardian.cxx +) + +composite_sources(p3glxdisplay P3GLXDISPLAY_SOURCES) +add_component_library(p3glxdisplay SYMBOL BUILDING_PANDA_GLXDISPLAY + ${P3GLXDISPLAY_HEADERS} ${P3GLXDISPLAY_SOURCES}) +target_link_libraries(p3glxdisplay p3glgsg p3x11display) + +if(NOT BUILD_METALIBS) + install(TARGETS p3glxdisplay EXPORT OpenGL COMPONENT OpenGL DESTINATION ${CMAKE_INSTALL_LIBDIR}) +endif() diff --git a/panda/src/gobj/CMakeLists.txt b/panda/src/gobj/CMakeLists.txt new file mode 100644 index 0000000000..8ab4223467 --- /dev/null +++ b/panda/src/gobj/CMakeLists.txt @@ -0,0 +1,195 @@ +set(P3GOBJ_HEADERS + adaptiveLru.I adaptiveLru.h + animateVerticesRequest.I animateVerticesRequest.h + bufferContext.I bufferContext.h + bufferContextChain.I bufferContextChain.h + bufferResidencyTracker.I bufferResidencyTracker.h + config_gobj.h + geom.h geom.I + geomContext.I geomContext.h + geomEnums.h + geomMunger.h geomMunger.I + geomPrimitive.h geomPrimitive.I + geomPatches.h + geomTriangles.h + geomTrianglesAdjacency.h + geomTristrips.h + geomTristripsAdjacency.h + geomTrifans.h + geomLines.h + geomLinesAdjacency.h + geomLinestrips.h + geomLinestripsAdjacency.h + geomPoints.h + geomVertexArrayData.h geomVertexArrayData.I + geomVertexArrayFormat.h geomVertexArrayFormat.I + geomCacheEntry.h geomCacheEntry.I + geomCacheManager.h geomCacheManager.I + geomVertexAnimationSpec.h geomVertexAnimationSpec.I + geomVertexData.h geomVertexData.I + geomVertexColumn.h geomVertexColumn.I + geomVertexFormat.h geomVertexFormat.I + geomVertexReader.h geomVertexReader.I + geomVertexRewriter.h geomVertexRewriter.I + geomVertexWriter.h geomVertexWriter.I + indexBufferContext.I indexBufferContext.h + internalName.I internalName.h + lens.h lens.I + material.I material.h materialPool.I materialPool.h + matrixLens.I matrixLens.h + occlusionQueryContext.I occlusionQueryContext.h + orthographicLens.I orthographicLens.h + paramTexture.I paramTexture.h + perspectiveLens.I perspectiveLens.h + preparedGraphicsObjects.I preparedGraphicsObjects.h + queryContext.I queryContext.h + samplerContext.h samplerContext.I + samplerState.h samplerState.I + savedContext.I savedContext.h + shader.I shader.h + shaderBuffer.h shaderBuffer.I + shaderContext.h shaderContext.I + simpleAllocator.h simpleAllocator.I + simpleLru.h simpleLru.I + sliderTable.I sliderTable.h + texture.I texture.h + textureCollection.I textureCollection.h + textureContext.I textureContext.h + texturePeeker.I texturePeeker.h + texturePool.I texturePool.h + texturePoolFilter.I texturePoolFilter.h + textureReloadRequest.I textureReloadRequest.h + textureStage.I textureStage.h + textureStagePool.I textureStagePool.h + timerQueryContext.I timerQueryContext.h + transformBlend.I transformBlend.h + transformBlendTable.I transformBlendTable.h + transformTable.I transformTable.h + userVertexSlider.I userVertexSlider.h + userVertexTransform.I userVertexTransform.h + vertexBufferContext.I vertexBufferContext.h + vertexDataBlock.I vertexDataBlock.h + vertexDataBook.I vertexDataBook.h + vertexDataBuffer.I vertexDataBuffer.h + vertexDataPage.I vertexDataPage.h + vertexDataSaveFile.I vertexDataSaveFile.h + vertexSlider.I vertexSlider.h + vertexTransform.I vertexTransform.h + videoTexture.I videoTexture.h +) + +set(P3GOBJ_SOURCES + adaptiveLru.cxx + animateVerticesRequest.cxx + bufferContext.cxx + bufferContextChain.cxx + bufferResidencyTracker.cxx + config_gobj.cxx + geomContext.cxx + geom.cxx + geomEnums.cxx + geomMunger.cxx + geomPrimitive.cxx + geomPatches.cxx + geomTriangles.cxx + geomTrianglesAdjacency.cxx + geomTristrips.cxx + geomTristripsAdjacency.cxx + geomTrifans.cxx + geomLines.cxx + geomLinesAdjacency.cxx + geomLinestrips.cxx + geomLinestripsAdjacency.cxx + geomPoints.cxx + geomVertexArrayData.cxx + geomVertexArrayFormat.cxx + geomCacheEntry.cxx + geomCacheManager.cxx + geomVertexAnimationSpec.cxx + geomVertexData.cxx + geomVertexColumn.cxx + geomVertexFormat.cxx + geomVertexReader.cxx + geomVertexRewriter.cxx + geomVertexWriter.cxx + indexBufferContext.cxx + material.cxx + internalName.cxx + lens.cxx + materialPool.cxx matrixLens.cxx + occlusionQueryContext.cxx + orthographicLens.cxx + paramTexture.cxx + perspectiveLens.cxx + preparedGraphicsObjects.cxx + queryContext.cxx + samplerContext.cxx + samplerState.cxx + savedContext.cxx + shader.cxx + shaderBuffer.cxx + shaderContext.cxx + simpleAllocator.cxx + simpleLru.cxx + sliderTable.cxx + texture.cxx + textureCollection.cxx + textureContext.cxx + texturePeeker.cxx + texturePool.cxx + texturePoolFilter.cxx + textureReloadRequest.cxx + textureStage.cxx + textureStagePool.cxx + timerQueryContext.cxx + transformBlend.cxx + transformBlendTable.cxx + transformTable.cxx + userVertexSlider.cxx + userVertexTransform.cxx + vertexBufferContext.cxx + vertexDataBlock.cxx + vertexDataBook.cxx + vertexDataBuffer.cxx + vertexDataPage.cxx + vertexDataSaveFile.cxx + vertexSlider.cxx + vertexTransform.cxx + videoTexture.cxx +) + +set(P3GOBJ_IGATEEXT + internalName_ext.cxx + internalName_ext.h + geomVertexArrayData_ext.cxx + geomVertexArrayData_ext.h + texture_ext.cxx + texture_ext.h + textureCollection_ext.cxx + textureCollection_ext.h +) + +composite_sources(p3gobj P3GOBJ_SOURCES) +add_component_library(p3gobj NOINIT SYMBOL BUILDING_PANDA_GOBJ + ${P3GOBJ_HEADERS} ${P3GOBJ_SOURCES}) +target_link_libraries(p3gobj p3gsgbase p3pnmimage + PKG::ZLIB PKG::SQUISH PKG::CG) +target_interrogate(p3gobj ALL EXTENSIONS ${P3GOBJ_IGATEEXT}) + +if(HAVE_SQUISH) + target_compile_definitions(p3gobj PRIVATE HAVE_SQUISH) +endif() + +if(PHAVE_LOCKF) + target_compile_definitions(p3gobj PRIVATE PHAVE_LOCKF) +endif() + +if(NOT BUILD_METALIBS) + install(TARGETS p3gobj + EXPORT Core COMPONENT Core + DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d + ARCHIVE COMPONENT CoreDevel) +endif() +install(FILES ${P3GOBJ_HEADERS} COMPONENT CoreDevel DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d) diff --git a/panda/src/gobj/shader.cxx b/panda/src/gobj/shader.cxx index cf9631f660..a1067e9c9e 100644 --- a/panda/src/gobj/shader.cxx +++ b/panda/src/gobj/shader.cxx @@ -384,7 +384,7 @@ cp_dependency(ShaderMatInput inp) { if (inp == SMO_attr_material || inp == SMO_attr_material2) { dep |= SSD_material | SSD_frame; } - if (inp == SMO_attr_color) { + if (inp == SMO_attr_color || inp == SMO_attr_material2) { dep |= SSD_color; } if (inp == SMO_attr_colorscale) { @@ -422,6 +422,7 @@ cp_dependency(ShaderMatInput inp) { (inp == SMO_slight_x) || (inp == SMO_satten_x) || (inp == SMO_mat_constant_x) || + (inp == SMO_mat_constant_x_attrib) || (inp == SMO_vec_constant_x) || (inp == SMO_vec_constant_x_attrib) || (inp == SMO_view_x_to_view) || @@ -441,6 +442,8 @@ cp_dependency(ShaderMatInput inp) { (inp == SMO_plight_x) || (inp == SMO_slight_x) || (inp == SMO_satten_x) || + (inp == SMO_mat_constant_x) || + (inp == SMO_mat_constant_x_attrib) || (inp == SMO_vec_constant_x_attrib) || (inp == SMO_view_x_to_view) || (inp == SMO_view_to_view_x) || @@ -459,10 +462,13 @@ cp_dependency(ShaderMatInput inp) { (inp == SMO_light_source_i_attrib) || (inp == SMO_light_source_i_packed)) { dep |= SSD_light | SSD_frame; - if (inp == SMO_light_source_i_attrib || - inp == SMO_light_source_i_packed) { - dep |= SSD_view_transform; - } + } + if (inp == SMO_light_source_i_attrib || + inp == SMO_light_source_i_packed || + inp == SMO_mat_constant_x_attrib || + inp == SMO_vec_constant_x_attrib) { + // Some light attribs (eg. position) need to be transformed to view space. + dep |= SSD_view_transform; } if ((inp == SMO_light_product_i_ambient) || (inp == SMO_light_product_i_diffuse) || @@ -499,14 +505,10 @@ cp_dependency(ShaderMatInput inp) { } /** - * Analyzes a ShaderMatSpec and decides what it should use its cache for. It - * can cache the results of any one opcode, or, it can cache the entire - * result. This routine needs to be smart enough to know which data items can - * be correctly cached, and which cannot. + * Adds the given ShaderMatSpec to the shader's mat spec table. */ void Shader:: -cp_optimize_mat_spec(ShaderMatSpec &spec) { - +cp_add_mat_spec(ShaderMatSpec &spec) { // If we're composing with identity, simplify. if (spec._func == SMF_first) { @@ -563,10 +565,92 @@ cp_optimize_mat_spec(ShaderMatSpec &spec) { } } - // Calculate state and transform dependencies. + // Determine which part is an array, for determining which one the count and + // index refer to. (It can't be the case that both parts are arrays.) + int begin[2] = {0, 0}; + int end[2] = {1, 1}; + if (spec._index > 0) { + for (int i = 0; i < 2; ++i) { + if (spec._part[i] == SMO_texmat_i || + spec._part[i] == SMO_inv_texmat_i || + spec._part[i] == SMO_light_source_i_attrib || + spec._part[i] == SMO_light_product_i_ambient || + spec._part[i] == SMO_light_product_i_diffuse || + spec._part[i] == SMO_light_product_i_specular || + spec._part[i] == SMO_apiview_clipplane_i || + spec._part[i] == SMO_tex_is_alpha_i || + spec._part[i] == SMO_transform_i || + spec._part[i] == SMO_slider_i || + spec._part[i] == SMO_light_source_i_packed || + spec._part[i] == SMO_texscale_i || + spec._part[i] == SMO_texcolor_i) { + begin[i] = spec._index; + end[i] = spec._index + 1; + } + } + nassertv(end[0] == 1 || end[1] == 1); + } - spec._dep[0] = cp_dependency(spec._part[0]); - spec._dep[1] = cp_dependency(spec._part[1]); + // Make sure that we have a place in the part cache for both parts. + int num_parts = (spec._func != SMF_first) ? 2 : 1; + + for (int p = 0; p < num_parts; ++p) { + int dep = cp_dependency(spec._part[p]); + spec._dep |= dep; + + // Do we already have a spot in the cache for this part? + size_t i; + size_t offset = 0; + for (i = 0; i < _mat_parts.size(); ++i) { + ShaderMatPart &part = _mat_parts[i]; + if (part._part == spec._part[p] && part._arg == spec._arg[p]) { + int diff = end[p] - part._count; + if (diff <= 0) { + // The existing cache entry is big enough. + break; + } else { + // It's not big enough. Enlarge it, which means we have to change the + // offset of some of the other spec entries. + for (ShaderMatSpec &spec : _mat_spec) { + if (spec._cache_offset[0] >= offset + part._count) { + spec._cache_offset[0] += diff; + } + if (spec._cache_offset[1] >= offset + part._count) { + spec._cache_offset[1] += diff; + } + } + part._count = end[p]; + break; + } + } + offset += part._count; + } + if (i == _mat_parts.size()) { + // Didn't find this part yet, create a new one. + ShaderMatPart part; + part._part = spec._part[p]; + part._count = end[p]; + part._arg = spec._arg[p]; + part._dep = dep; + _mat_parts.push_back(std::move(part)); + } + spec._cache_offset[p] = offset + begin[p]; + } + + _mat_spec.push_back(spec); + _mat_deps |= spec._dep; +} + +/** + * Returns the total size of the matrix part cache. + */ +size_t Shader:: +cp_get_mat_cache_size() const { + size_t size = 0; + for (const ShaderMatPart &part : _mat_parts) { + size += part._count; + } + return size; } #ifdef HAVE_CG @@ -776,9 +860,7 @@ compile_parameter(ShaderArgInfo &p, int *arg_dim) { bind._arg[0] = nullptr; bind._index = atoi(pieces[2].c_str()); - cp_optimize_mat_spec(bind); - _mat_spec.push_back(bind); - _mat_deps |= bind._dep[0] | bind._dep[1]; + cp_add_mat_spec(bind); return true; } @@ -931,9 +1013,7 @@ compile_parameter(ShaderArgInfo &p, int *arg_dim) { if (!cp_parse_eol(p, pieces, next)) { return false; } - cp_optimize_mat_spec(bind); - _mat_spec.push_back(bind); - _mat_deps |= bind._dep[0] | bind._dep[1]; + cp_add_mat_spec(bind); return true; } @@ -1041,9 +1121,7 @@ compile_parameter(ShaderArgInfo &p, int *arg_dim) { return false; } - cp_optimize_mat_spec(bind); - _mat_spec.push_back(bind); - _mat_deps |= bind._dep[0] | bind._dep[1]; + cp_add_mat_spec(bind); return true; } @@ -1055,9 +1133,7 @@ compile_parameter(ShaderArgInfo &p, int *arg_dim) { } ShaderMatSpec bind; - cp_optimize_mat_spec(bind); - _mat_spec.push_back(bind); - _mat_deps |= bind._dep[0] | bind._dep[1]; + cp_add_mat_spec(bind); return true; } @@ -1079,9 +1155,7 @@ compile_parameter(ShaderArgInfo &p, int *arg_dim) { bind._part[1] = SMO_identity; bind._arg[1] = nullptr; - cp_optimize_mat_spec(bind); - _mat_spec.push_back(bind); - _mat_deps |= bind._dep[0] | bind._dep[1]; + cp_add_mat_spec(bind); return true; } @@ -1101,9 +1175,7 @@ compile_parameter(ShaderArgInfo &p, int *arg_dim) { bind._part[1] = SMO_identity; bind._arg[1] = nullptr; - cp_optimize_mat_spec(bind); - _mat_spec.push_back(bind); - _mat_deps |= bind._dep[0] | bind._dep[1]; + cp_add_mat_spec(bind); return true; } @@ -1143,9 +1215,7 @@ compile_parameter(ShaderArgInfo &p, int *arg_dim) { if (!cp_parse_eol(p, pieces, next)) { return false; } - cp_optimize_mat_spec(bind); - _mat_spec.push_back(bind); - _mat_deps |= bind._dep[0] | bind._dep[1]; + cp_add_mat_spec(bind); return true; } @@ -1166,9 +1236,7 @@ compile_parameter(ShaderArgInfo &p, int *arg_dim) { bind._arg[1] = nullptr; bind._index = atoi(pieces[1].c_str()); - cp_optimize_mat_spec(bind); - _mat_spec.push_back(bind); - _mat_deps |= bind._dep[0] | bind._dep[1]; + cp_add_mat_spec(bind); return true; } @@ -1189,9 +1257,7 @@ compile_parameter(ShaderArgInfo &p, int *arg_dim) { bind._arg[1] = nullptr; bind._index = atoi(pieces[1].c_str()); - cp_optimize_mat_spec(bind); - _mat_spec.push_back(bind); - _mat_deps |= bind._dep[0] | bind._dep[1]; + cp_add_mat_spec(bind); return true; } @@ -1212,9 +1278,7 @@ compile_parameter(ShaderArgInfo &p, int *arg_dim) { bind._arg[1] = nullptr; bind._index = atoi(pieces[1].c_str()); - cp_optimize_mat_spec(bind); - _mat_spec.push_back(bind); - _mat_deps |= bind._dep[0] | bind._dep[1]; + cp_add_mat_spec(bind); return true; } @@ -1234,9 +1298,7 @@ compile_parameter(ShaderArgInfo &p, int *arg_dim) { bind._part[1] = SMO_identity; bind._arg[1] = nullptr; - cp_optimize_mat_spec(bind); - _mat_spec.push_back(bind); - _mat_deps |= bind._dep[0] | bind._dep[1]; + cp_add_mat_spec(bind); return true; } @@ -1256,9 +1318,7 @@ compile_parameter(ShaderArgInfo &p, int *arg_dim) { bind._part[1] = SMO_identity; bind._arg[1] = nullptr; - cp_optimize_mat_spec(bind); - _mat_spec.push_back(bind); - _mat_deps |= bind._dep[0] | bind._dep[1]; + cp_add_mat_spec(bind); return true; } @@ -1303,9 +1363,7 @@ compile_parameter(ShaderArgInfo &p, int *arg_dim) { return false; } - cp_optimize_mat_spec(bind); - _mat_spec.push_back(bind); - _mat_deps |= bind._dep[0] | bind._dep[1]; + cp_add_mat_spec(bind); return true; } @@ -1388,9 +1446,7 @@ compile_parameter(ShaderArgInfo &p, int *arg_dim) { bind._arg[0] = InternalName::make(pieces[1]); bind._part[1] = SMO_identity; bind._arg[1] = nullptr; - cp_optimize_mat_spec(bind); - _mat_spec.push_back(bind); - _mat_deps |= bind._dep[0] | bind._dep[1]; + cp_add_mat_spec(bind); return true; } @@ -1409,9 +1465,7 @@ compile_parameter(ShaderArgInfo &p, int *arg_dim) { bind._arg[0] = InternalName::make(pieces[1]); bind._part[1] = SMO_identity; bind._arg[1] = nullptr; - cp_optimize_mat_spec(bind); - _mat_spec.push_back(bind); - _mat_deps |= bind._dep[0] | bind._dep[1]; + cp_add_mat_spec(bind); return true; } @@ -2362,7 +2416,6 @@ Shader(ShaderLanguage lang) : _loaded(false), _language(lang), _last_modified(0), - _mat_deps(0), _cache_compiled_shader(false) { #ifdef HAVE_CG @@ -2461,9 +2514,10 @@ read(const ShaderFile &sfile, BamCacheRecord *record) { // Determine which language the shader is written in. if (_language == SL_Cg) { #ifdef HAVE_CG - cg_get_profile_from_header(_default_caps); + ShaderCaps caps = _default_caps; + cg_get_profile_from_header(caps); - if (!cg_analyze_shader(_default_caps)) { + if (!cg_analyze_shader(caps)) { shader_cat.error() << "Shader encountered an error.\n"; return false; @@ -2553,9 +2607,10 @@ load(const ShaderFile &sbody, BamCacheRecord *record) { // Determine which language the shader is written in. if (_language == SL_Cg) { #ifdef HAVE_CG - cg_get_profile_from_header(_default_caps); + ShaderCaps caps = _default_caps; + cg_get_profile_from_header(caps); - if (!cg_analyze_shader(_default_caps)) { + if (!cg_analyze_shader(caps)) { shader_cat.error() << "Shader encountered an error.\n"; return false; diff --git a/panda/src/gobj/shader.h b/panda/src/gobj/shader.h index 720025d7b0..0cc7ce1dae 100644 --- a/panda/src/gobj/shader.h +++ b/panda/src/gobj/shader.h @@ -402,15 +402,30 @@ public: INLINE void read_datagram(DatagramIterator &source); }; + /** + * Describes a matrix making up a single part of the ShaderMatInput cache. + * The cache is made up of a continuous array of matrices, as described by + * a successive list of ShaderMatPart (each of which takes up _count matrices) + */ + struct ShaderMatPart { + ShaderMatInput _part; + PT(InternalName) _arg; + int _count = 1; + int _dep = SSD_NONE; + }; + + /** + * Describes a shader input that is sourced from the render state. + */ struct ShaderMatSpec { - LMatrix4 _cache[2]; - LMatrix4 _value; + size_t _cache_offset[2]; ShaderArgId _id; ShaderMatFunc _func; ShaderMatInput _part[2]; PT(InternalName) _arg[2]; - int _dep[2]; - int _index; + LMatrix4 _value; + int _dep = SSD_NONE; + int _index = 0; ShaderMatPiece _piece; }; @@ -514,7 +529,8 @@ public: vector_string &pieces, int &next, ShaderMatSpec &spec, bool fromflag); int cp_dependency(ShaderMatInput inp); - void cp_optimize_mat_spec(ShaderMatSpec &spec); + void cp_add_mat_spec(ShaderMatSpec &spec); + size_t cp_get_mat_cache_size() const; #ifdef HAVE_CG void cg_recurse_parameters(CGparameter parameter, @@ -578,7 +594,9 @@ public: epvector _mat_spec; pvector _tex_spec; pvector _var_spec; - int _mat_deps; + pvector _mat_parts; + int _mat_deps = 0; + int _mat_cache_size = 0; bool _error_flag; ShaderFile _text; diff --git a/panda/src/grutil/CMakeLists.txt b/panda/src/grutil/CMakeLists.txt new file mode 100644 index 0000000000..bffcce6559 --- /dev/null +++ b/panda/src/grutil/CMakeLists.txt @@ -0,0 +1,66 @@ +set(P3GRUTIL_HEADERS + pipeOcclusionCullTraverser.I pipeOcclusionCullTraverser.h + cardMaker.I cardMaker.h + config_grutil.h + movieTexture.I movieTexture.h + fisheyeMaker.I fisheyeMaker.h + frameRateMeter.I frameRateMeter.h + meshDrawer.I meshDrawer.h + meshDrawer2D.I meshDrawer2D.h + geoMipTerrain.I geoMipTerrain.h + sceneGraphAnalyzerMeter.I sceneGraphAnalyzerMeter.h + heightfieldTesselator.I heightfieldTesselator.h + shaderTerrainMesh.I shaderTerrainMesh.h + lineSegs.I lineSegs.h + multitexReducer.I multitexReducer.h + nodeVertexTransform.I nodeVertexTransform.h + pfmVizzer.I pfmVizzer.h + rigidBodyCombiner.I rigidBodyCombiner.h +) + +set(P3GRUTIL_SOURCES + cardMaker.cxx + movieTexture.cxx + fisheyeMaker.cxx + config_grutil.cxx + frameRateMeter.cxx + meshDrawer.cxx + meshDrawer2D.cxx + geoMipTerrain.cxx + sceneGraphAnalyzerMeter.cxx + heightfieldTesselator.cxx + shaderTerrainMesh.cxx + multitexReducer.cxx + nodeVertexTransform.cxx + pfmVizzer.cxx + pipeOcclusionCullTraverser.cxx + lineSegs.cxx + rigidBodyCombiner.cxx +) + +# This is a large file; let's build it separately +set_source_files_properties(multitexReducer.cxx PROPERTIES SKIP_UNITY_BUILD_INCLUSION YES) + +composite_sources(p3grutil P3GRUTIL_SOURCES) +add_component_library(p3grutil SYMBOL BUILDING_PANDA_GRUTIL + ${P3GRUTIL_HEADERS} ${P3GRUTIL_SOURCES}) +target_link_libraries(p3grutil p3display p3text p3movies) +if(HAVE_AUDIO) + target_link_libraries(p3grutil p3audio) +endif() +target_interrogate(p3grutil ALL) + +if(HAVE_EIGEN) + # Eigen puts this over the threshold where bigobj is needed on MSVC + set_target_properties(p3grutil PROPERTIES MSVC_BIGOBJ ON) +endif() + +if(NOT BUILD_METALIBS) + install(TARGETS p3grutil + EXPORT Core COMPONENT Core + DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d + ARCHIVE COMPONENT CoreDevel) +endif() +install(FILES ${P3GRUTIL_HEADERS} COMPONENT CoreDevel DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d) diff --git a/panda/src/grutil/frameRateMeter.cxx b/panda/src/grutil/frameRateMeter.cxx index f015e0ab55..cb734110e3 100644 --- a/panda/src/grutil/frameRateMeter.cxx +++ b/panda/src/grutil/frameRateMeter.cxx @@ -214,7 +214,7 @@ do_update(Thread *current_thread) { static const size_t buffer_size = 1024; char buffer[buffer_size]; -#if defined(WIN32_VC) || defined(WIN64_VC) +#ifdef _WIN32 // Windows doesn't define snprintf(). Hope we don't overflow. sprintf(buffer, _text_pattern.c_str(), value, deviation); #else diff --git a/panda/src/grutil/sceneGraphAnalyzerMeter.cxx b/panda/src/grutil/sceneGraphAnalyzerMeter.cxx index 7b64422699..ad3ec115e8 100644 --- a/panda/src/grutil/sceneGraphAnalyzerMeter.cxx +++ b/panda/src/grutil/sceneGraphAnalyzerMeter.cxx @@ -206,7 +206,7 @@ do_update(Thread *current_thread) { "Points: %d\n" "Texture memory: %.1f KB\n"; -#if defined(WIN32_VC) || defined(WIN64_VC) +#ifdef _WIN32 _snprintf(buffer, buffer_size, pattern, _scene_graph_analyzer.get_num_nodes(), _scene_graph_analyzer.get_num_instances(), diff --git a/panda/src/gsgbase/CMakeLists.txt b/panda/src/gsgbase/CMakeLists.txt new file mode 100644 index 0000000000..8060686e04 --- /dev/null +++ b/panda/src/gsgbase/CMakeLists.txt @@ -0,0 +1,27 @@ +set(P3GSGBASE_HEADERS + config_gsgbase.h + graphicsOutputBase.I graphicsOutputBase.h + graphicsStateGuardianBase.h +) + +set(P3GSGBASE_SOURCES + config_gsgbase.cxx + graphicsOutputBase.cxx + graphicsStateGuardianBase.cxx +) + +composite_sources(p3gsgbase P3GSGBASE_SOURCES) +add_component_library(p3gsgbase NOINIT SYMBOL BUILDING_PANDA_GSGBASE + ${P3GSGBASE_HEADERS} ${P3GSGBASE_SOURCES}) +target_link_libraries(p3gsgbase p3putil p3linmath) +target_interrogate(p3gsgbase ALL) + +if(NOT BUILD_METALIBS) + install(TARGETS p3gsgbase + EXPORT Core COMPONENT Core + DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d + ARCHIVE COMPONENT CoreDevel) +endif() +install(FILES ${P3GSGBASE_HEADERS} COMPONENT CoreDevel DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d) diff --git a/panda/src/linmath/CMakeLists.txt b/panda/src/linmath/CMakeLists.txt new file mode 100644 index 0000000000..acbe732e93 --- /dev/null +++ b/panda/src/linmath/CMakeLists.txt @@ -0,0 +1,63 @@ +set(P3LINMATH_HEADERS + aa_luse.h + compose_matrix.h compose_matrix_src.I + compose_matrix_src.h config_linmath.h + configVariableColor.h configVariableColor.I + coordinateSystem.h dbl2fltnames.h dblnames.h + deg_2_rad.h deg_2_rad.I + flt2dblnames.h fltnames.h + intnames.h + lcast_to.h lcast_to_src.h lcast_to_src.I + lmatrix.h lmatrix_ext.h + lmat_ops.h lmat_ops_src.h lmat_ops_src.I + lmatrix3_src.h lmatrix3_src.I + lmatrix4_src.h lmatrix4_src.I + lorientation.h lorientation_src.h lorientation_src.I + lpoint2.h lpoint2_src.I lpoint2_src.h + lpoint3.h lpoint3_src.I lpoint3_src.h + lpoint4.h lpoint4_src.I lpoint4_src.h + lquaternion.h lquaternion_src.I + lquaternion_src.h lrotation.h lrotation_src.I + lrotation_src.h + lsimpleMatrix.h lsimpleMatrix.I + luse.I luse.N luse.h + lvec2_ops.h lvec2_ops_src.I lvec2_ops_src.h lvec3_ops.h + lvec3_ops_src.I lvec3_ops_src.h lvec4_ops.h lvec4_ops_src.I + lvec4_ops_src.h + lvecBase2.h lvecBase2_src.I lvecBase2_src.h + lvecBase3.h lvecBase3_src.I lvecBase3_src.h + lvecBase4.h lvecBase4_src.I lvecBase4_src.h + lvector2.h lvector2_src.I lvector2_src.h + lvector3.h lvector3_src.I lvector3_src.h + lvector4.h lvector4_src.I lvector4_src.h + lvector4.h lvector4_src.I lvector4_src.h + lvecBase2_ext.h lvecBase3_ext.h lvecBase4_ext.h + lpoint2_ext.h lpoint3_ext.h lpoint4_ext.h + lvector2_ext.h lvector3_ext.h lvector4_ext.h + mathNumbers.h mathNumbers.I +) + +set(P3LINMATH_SOURCES + compose_matrix.cxx config_linmath.cxx configVariableColor.cxx + coordinateSystem.cxx lmatrix.cxx + lorientation.cxx lpoint2.cxx + lpoint3.cxx lpoint4.cxx lquaternion.cxx lrotation.cxx + luse.cxx lvecBase2.cxx lvecBase3.cxx lvecBase4.cxx + lvector2.cxx lvector3.cxx lvector4.cxx mathNumbers.cxx +) + +composite_sources(p3linmath P3LINMATH_SOURCES) +add_component_library(p3linmath SYMBOL BUILDING_PANDA_LINMATH + ${P3LINMATH_HEADERS} ${P3LINMATH_SOURCES}) +target_link_libraries(p3linmath p3pandabase pandaexpress PKG::EIGEN) +target_interrogate(p3linmath ALL) + +if(NOT BUILD_METALIBS) + install(TARGETS p3linmath + EXPORT Core COMPONENT Core + DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d + ARCHIVE COMPONENT CoreDevel) +endif() +install(FILES ${P3LINMATH_HEADERS} COMPONENT CoreDevel DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d) diff --git a/panda/src/mathutil/CMakeLists.txt b/panda/src/mathutil/CMakeLists.txt new file mode 100644 index 0000000000..0716f4538d --- /dev/null +++ b/panda/src/mathutil/CMakeLists.txt @@ -0,0 +1,82 @@ +set(P3MATHUTIL_HEADERS + boundingHexahedron.I boundingHexahedron.h boundingLine.I + boundingLine.h + boundingBox.I boundingBox.h + boundingPlane.I boundingPlane.h + boundingSphere.I boundingSphere.h + boundingVolume.I boundingVolume.h config_mathutil.h + fftCompressor.h finiteBoundingVolume.h frustum.h + frustum_src.I frustum_src.h geometricBoundingVolume.I + geometricBoundingVolume.h + intersectionBoundingVolume.h intersectionBoundingVolume.I + linmath_events.h + look_at.h look_at_src.I + look_at_src.h + linmath_events.h + mersenne.h + omniBoundingVolume.I + omniBoundingVolume.h + parabola.h parabola_src.I parabola_src.h + perlinNoise.h perlinNoise.I + perlinNoise2.h perlinNoise2.I + perlinNoise3.h perlinNoise3.I + plane.h plane_src.I plane_src.h + pta_LMatrix4.h pta_LMatrix3.h pta_LVecBase3.h + pta_LVecBase4.h pta_LVecBase2.h + randomizer.h randomizer.I + rotate_to.h + stackedPerlinNoise2.h stackedPerlinNoise2.I + stackedPerlinNoise3.h stackedPerlinNoise3.I + triangulator.h triangulator.I + triangulator3.h triangulator3.I + unionBoundingVolume.h unionBoundingVolume.I +) + +set(P3MATHUTIL_SOURCES + boundingHexahedron.cxx boundingLine.cxx + boundingBox.cxx + boundingPlane.cxx + boundingSphere.cxx + boundingVolume.cxx config_mathutil.cxx fftCompressor.cxx + finiteBoundingVolume.cxx geometricBoundingVolume.cxx + intersectionBoundingVolume.cxx + look_at.cxx + linmath_events.cxx + mersenne.cxx + omniBoundingVolume.cxx + parabola.cxx + perlinNoise.cxx + perlinNoise2.cxx + perlinNoise3.cxx + plane.cxx + pta_LMatrix4.cxx pta_LMatrix3.cxx pta_LVecBase3.cxx + pta_LVecBase4.cxx pta_LVecBase2.cxx + randomizer.cxx + rotate_to.cxx + stackedPerlinNoise2.cxx + stackedPerlinNoise3.cxx + triangulator.cxx + triangulator3.cxx + unionBoundingVolume.cxx +) + +composite_sources(p3mathutil P3MATHUTIL_SOURCES) +add_component_library(p3mathutil SYMBOL BUILDING_PANDA_MATHUTIL + ${P3MATHUTIL_HEADERS} ${P3MATHUTIL_SOURCES}) +target_link_libraries(p3mathutil p3event + PKG::FFTW) +target_interrogate(p3mathutil ALL) + +if(HAVE_FFTW) + target_compile_definitions(p3mathutil PRIVATE HAVE_FFTW) +endif() + +if(NOT BUILD_METALIBS) + install(TARGETS p3mathutil + EXPORT Core COMPONENT Core + DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d + ARCHIVE COMPONENT CoreDevel) +endif() +install(FILES ${P3MATHUTIL_HEADERS} COMPONENT CoreDevel DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d) diff --git a/panda/src/movies/CMakeLists.txt b/panda/src/movies/CMakeLists.txt new file mode 100644 index 0000000000..30e01d254a --- /dev/null +++ b/panda/src/movies/CMakeLists.txt @@ -0,0 +1,62 @@ +set(P3MOVIES_HEADERS + dr_flac.h + config_movies.h + flacAudio.h flacAudio.I + flacAudioCursor.h flacAudioCursor.I + inkblotVideo.h inkblotVideo.I + inkblotVideoCursor.h inkblotVideoCursor.I + microphoneAudio.h microphoneAudio.I + movieAudio.h movieAudio.I + movieAudioCursor.h movieAudioCursor.I + movieTypeRegistry.h movieTypeRegistry.I + movieVideo.h movieVideo.I + movieVideoCursor.h movieVideoCursor.I + opusAudio.h opusAudio.I + opusAudioCursor.h opusAudioCursor.I + userDataAudio.h userDataAudio.I + userDataAudioCursor.h userDataAudioCursor.I + vorbisAudio.h vorbisAudio.I + vorbisAudioCursor.h vorbisAudioCursor.I + wavAudio.h wavAudio.I + wavAudioCursor.h wavAudioCursor.I +) + +set(P3MOVIES_SOURCES + config_movies.cxx + flacAudio.cxx + flacAudioCursor.cxx + inkblotVideo.cxx + inkblotVideoCursor.cxx + microphoneAudio.cxx + microphoneAudioDS.cxx + movieAudio.cxx + movieAudioCursor.cxx + movieTypeRegistry.cxx + movieVideo.cxx + movieVideoCursor.cxx + opusAudio.cxx + opusAudioCursor.cxx + userDataAudio.cxx + userDataAudioCursor.cxx + vorbisAudio.cxx + vorbisAudioCursor.cxx + wavAudio.cxx + wavAudioCursor.cxx +) + +composite_sources(p3movies P3MOVIES_SOURCES) +add_component_library(p3movies SYMBOL BUILDING_PANDA_MOVIES + ${P3MOVIES_HEADERS} ${P3MOVIES_SOURCES}) +target_link_libraries(p3movies p3pstatclient p3gobj p3pandabase pandaexpress + PKG::VORBIS PKG::OPUS) +target_interrogate(p3movies ALL) + +if(NOT BUILD_METALIBS) + install(TARGETS p3movies + EXPORT Core COMPONENT Core + DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d + ARCHIVE COMPONENT CoreDevel) +endif() +install(FILES ${P3MOVIES_HEADERS} COMPONENT CoreDevel DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d) diff --git a/panda/src/nativenet/CMakeLists.txt b/panda/src/nativenet/CMakeLists.txt new file mode 100644 index 0000000000..614af16d33 --- /dev/null +++ b/panda/src/nativenet/CMakeLists.txt @@ -0,0 +1,47 @@ +if(NOT WANT_NATIVE_NET) + return() +endif() + +set(P3NATIVENET_HEADERS + config_nativenet.h + buffered_datagramconnection.h + buffered_datagramreader.h buffered_datagramreader.I + ringbuffer.h ringbuffer.I socket_ip.h + socket_tcp.h socket_tcp_listen.h + time_accumulator.h time_out.h + socket_address.I socket_address.h + socket_portable.h time_base.h time_span.h buffered_datagramwriter.h + socket_base.h socket_selector.h + socket_udp.h + socket_udp_incoming.h time_clock.h + membuffer.h membuffer.I socket_fdset.h + socket_udp_outgoing.h time_general.h +) + +set(P3NATIVENET_SOURCES + config_nativenet.cxx + buffered_datagramconnection.cxx + socket_address.cxx + socket_ip.cxx + socket_tcp.cxx + socket_tcp_listen.cxx + socket_udp.cxx + socket_udp_incoming.cxx + socket_udp_outgoing.cxx +) + +composite_sources(p3nativenet P3NATIVENET_SOURCES) +add_component_library(p3nativenet SYMBOL BUILDING_PANDA_NATIVENET + ${P3NATIVENET_HEADERS} ${P3NATIVENET_SOURCES}) +target_link_libraries(p3nativenet p3pandabase pandaexpress) +target_interrogate(p3nativenet ALL) + +if(NOT BUILD_METALIBS) + install(TARGETS p3nativenet + EXPORT Core COMPONENT Core + DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d + ARCHIVE COMPONENT CoreDevel) +endif() +install(FILES ${P3NATIVENET_HEADERS} COMPONENT CoreDevel DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d) diff --git a/panda/src/nativenet/config_nativenet.cxx b/panda/src/nativenet/config_nativenet.cxx index f90e106e81..af8b2d77cf 100644 --- a/panda/src/nativenet/config_nativenet.cxx +++ b/panda/src/nativenet/config_nativenet.cxx @@ -16,7 +16,6 @@ #include "socket_ip.h" #include "socket_tcp.h" #include "socket_tcp_listen.h" -#include "socket_tcp_ssl.h" #include "socket_udp_incoming.h" #include "socket_udp_outgoing.h" #include "socket_udp.h" @@ -55,9 +54,6 @@ init_libnativenet() { Socket_IP::init_type(); Socket_TCP::init_type(); Socket_TCP_Listen::init_type(); -#ifdef HAVE_OPENSSL - Socket_TCP_SSL::init_type(); -#endif Socket_UDP_Incoming::init_type(); Socket_UDP_Outgoing::init_type(); Socket_UDP::init_type(); diff --git a/panda/src/nativenet/p3nativenet_composite1.cxx b/panda/src/nativenet/p3nativenet_composite1.cxx index 1c842ac105..015473f8f8 100644 --- a/panda/src/nativenet/p3nativenet_composite1.cxx +++ b/panda/src/nativenet/p3nativenet_composite1.cxx @@ -4,7 +4,6 @@ #include "socket_ip.cxx" #include "socket_tcp.cxx" #include "socket_tcp_listen.cxx" -#include "socket_tcp_ssl.cxx" #include "socket_udp.cxx" #include "socket_udp_incoming.cxx" #include "socket_udp_outgoing.cxx" diff --git a/panda/src/nativenet/socket_fdset.h b/panda/src/nativenet/socket_fdset.h index 7da876c0f8..7af32a9d68 100644 --- a/panda/src/nativenet/socket_fdset.h +++ b/panda/src/nativenet/socket_fdset.h @@ -52,7 +52,7 @@ inline Socket_fdset::Socket_fdset() { inline void Socket_fdset::setForSocketNative(SOCKET inid) { assert( inid >= 0); -#ifndef WIN32 +#ifndef _WIN32 assert(inid < FD_SETSIZE); #endif @@ -68,7 +68,7 @@ inline void Socket_fdset::setForSocketNative(SOCKET inid) inline bool Socket_fdset::isSetForNative(SOCKET inid) const { assert( inid >= 0); -#ifndef WIN32 +#ifndef _WIN32 assert(inid < FD_SETSIZE); #endif diff --git a/panda/src/nativenet/socket_ip.h b/panda/src/nativenet/socket_ip.h index 3c03db2b3b..4b3ab34c7e 100644 --- a/panda/src/nativenet/socket_ip.h +++ b/panda/src/nativenet/socket_ip.h @@ -56,7 +56,6 @@ private: friend class Socket_TCP_Listen; friend class Socket_UDP_Incoming; friend class Socket_UDP_Outgoing; - friend class Socket_TCP_SSL; public: static TypeHandle get_class_type() { diff --git a/panda/src/nativenet/socket_portable.h b/panda/src/nativenet/socket_portable.h index a4a249f92e..2ac1c89248 100644 --- a/panda/src/nativenet/socket_portable.h +++ b/panda/src/nativenet/socket_portable.h @@ -53,7 +53,7 @@ typedef unsigned long SOCKET; ************************************************************************/ #elif defined(_WIN32) #include -#include +#include typedef u_short sa_family_t; diff --git a/panda/src/nativenet/socket_tcp_ssl.cxx b/panda/src/nativenet/socket_tcp_ssl.cxx deleted file mode 100644 index 0444d41802..0000000000 --- a/panda/src/nativenet/socket_tcp_ssl.cxx +++ /dev/null @@ -1,21 +0,0 @@ -/** - * PANDA 3D SOFTWARE - * Copyright (c) Carnegie Mellon University. All rights reserved. - * - * All use of this software is subject to the terms of the revised BSD - * license. You should have received a copy of this license along - * with this source code in a file named "LICENSE." - * - * @file socket_tcp_ssl.cxx - * @author drose - * @date 2007-03-01 - */ - -#include "socket_tcp_ssl.h" - -#ifdef HAVE_OPENSSL - -SSL_CTX *global_ssl_ctx; -TypeHandle Socket_TCP_SSL::_type_handle; - -#endif // HAVE_OPENSSL diff --git a/panda/src/nativenet/socket_tcp_ssl.h b/panda/src/nativenet/socket_tcp_ssl.h deleted file mode 100644 index 8f16f188dc..0000000000 --- a/panda/src/nativenet/socket_tcp_ssl.h +++ /dev/null @@ -1,299 +0,0 @@ -#ifndef __SOCKET_TCP_SSL_H__ -#define __SOCKET_TCP_SSL_H__ - -#include "pandabase.h" -#include "config_nativenet.h" -#include "socket_ip.h" -#include "numeric_types.h" - -#ifdef HAVE_OPENSSL - -#include /* SSLeay stuff */ -#include -#include -#include -#include -#include - -extern EXPCL_PANDA_NATIVENET SSL_CTX *global_ssl_ctx; - -struct SSlStartup { - SSlStartup() { - const SSL_METHOD *meth; - SSLeay_add_ssl_algorithms(); - // meth = SSLv23_server_method(); - meth = SSLv23_method(); - SSL_load_error_strings(); - // I hate this cast, but older versions of OpenSSL need it. - global_ssl_ctx = SSL_CTX_new((SSL_METHOD *) meth); - } - - ~SSlStartup() { - SSL_CTX_free (global_ssl_ctx); - global_ssl_ctx = nullptr; - } - - bool isactive() { return global_ssl_ctx != nullptr; }; -}; - -/** - * - */ -class EXPCL_PANDA_NATIVENET Socket_TCP_SSL : public Socket_IP { -public: - inline Socket_TCP_SSL(SOCKET); - inline Socket_TCP_SSL() : _ssl(nullptr) {} - - virtual inline ~Socket_TCP_SSL() - { - CleanSslUp(); - } - - inline int SetNoDelay(); - inline int SetLinger(int interval_seconds = 0); - inline int DontLinger(); - - inline int SetSendBufferSize(int insize); - inline bool ActiveOpen(const Socket_Address &theaddress); - inline int SendData(const char *data, int size); - inline int RecvData(char *data, int size); - inline bool ErrorIs_WouldBlocking(int err); - - inline SSL *get_ssl() { return _ssl; }; - - inline void DetailErrorFormat(void); - -private: - SSL *_ssl; - - void CleanSslUp() { - if (_ssl != nullptr) { - SSL_shutdown(_ssl); - SSL_free(_ssl); - _ssl = nullptr; - } - } - -public: - static TypeHandle get_class_type() { - return _type_handle; - } - static void init_type() { - Socket_IP::init_type(); - register_type(_type_handle, "Socket_TCP_SSL", - Socket_IP::get_class_type()); - } - virtual TypeHandle get_type() const { - return get_class_type(); - } - virtual TypeHandle force_init_type() {init_type(); return get_class_type();} - -private: - static TypeHandle _type_handle; -}; - -/** - * - */ -inline Socket_TCP_SSL:: -Socket_TCP_SSL(SOCKET sck) : ::Socket_IP(sck) { - // right know this will only work for a accepted ie a server socket ?? - SetNonBlocking(); // maybe should be blocking? - - _ssl = SSL_new(global_ssl_ctx); - if (_ssl == nullptr) { - return; - } - - SSL_set_fd(_ssl, (int)GetSocket()); - - SSL_accept(_ssl); - ERR_clear_error(); - - // printf(" Ssl Accept = %d \n",err); -} - -/** - * Disable Nagle algorithm. Don't delay send to coalesce packets - */ -inline int Socket_TCP_SSL:: -SetNoDelay() { - int nodel = 1; - int ret1; - ret1 = setsockopt(_socket, IPPROTO_TCP, TCP_NODELAY, (char *)&nodel, sizeof(nodel)); - - if (ret1 != 0) { - return BASIC_ERROR; - } - return ALL_OK; -} - -/** - * will control the behavior of SO_LINGER for a TCP socket - */ -int Socket_TCP_SSL:: -SetLinger(int interval_seconds) { - linger ll; - ll.l_linger = interval_seconds; - ll.l_onoff = 1; - int ret1 = setsockopt(_socket, SOL_SOCKET, SO_LINGER, (const char *)&ll, sizeof(linger)); - if (ret1 != 0) { - return BASIC_ERROR; - } - return ALL_OK; -} - -/** - * Turn off the linger flag. The socket will quickly release buffered items - * and free up OS resources. You may lose a stream if you use this flag and - * do not negotiate the close at the application layer. - */ -int Socket_TCP_SSL:: -DontLinger() { - linger ll; - ll.l_linger = 0; - ll.l_onoff = 0; - int ret1 = setsockopt(_socket, SOL_SOCKET, SO_LINGER, (const char *)&ll, sizeof(linger)); - if (ret1 != 0) { - return BASIC_ERROR; - } - return ALL_OK; -} - -/** - * Just like it sounds. Sets a buffered socket recv buffer size. This - * function does not refuse ranges outside hard-coded OS limits - */ -int Socket_TCP_SSL:: -SetSendBufferSize(int insize) { - if (setsockopt(_socket, (int) SOL_SOCKET, (int) SO_SNDBUF, (char *) &insize, sizeof(int))) { - return BASIC_ERROR; - } - return ALL_OK; -} - -/** -* This function will try and set the socket up for active open to a specified -* address and port provided by the input parameter -*/ -bool Socket_TCP_SSL:: -ActiveOpen(const Socket_Address &theaddress) { - _socket = DO_NEWTCP(theaddress.get_family()); - if (_socket == BAD_SOCKET) { - return false; - } - - if (DO_CONNECT(_socket, &theaddress.GetAddressInfo()) != 0) { - return ErrorClose(); - } - - _ssl = SSL_new(global_ssl_ctx); - if (_ssl == nullptr) { - return false; - } - SSL_set_fd(_ssl, (int)GetSocket()); - if (SSL_connect(_ssl) == -1) { - return false; - } - return true; - - // return SetSslUp(); -} - -/** - * Ok Lets Send the Data - if error 0 if socket closed for write or lengh is 0 - * + bytes writen ( May be smaller than requested) - */ -inline int Socket_TCP_SSL:: -SendData(const char *data, int size) { - if (_ssl == nullptr) { - return -1; - } - -// ERR_clear_error(); - - return SSL_write(_ssl, data, size); -} - -/** - * Read the data from the connection - if error 0 if socket closed for read or - * length is 0 + bytes read ( May be smaller than requested) - */ -inline int Socket_TCP_SSL:: -RecvData(char *data, int len) { - if (_ssl == nullptr) { - return -1; - } - - ERR_clear_error(); - - return SSL_read(_ssl, data, len); -} - -/** - * Is last error a blocking error ?? True is last error was a blocking error - */ -inline bool Socket_TCP_SSL:: -ErrorIs_WouldBlocking(int err) { - if (_ssl == nullptr || err >= 0) { - nativenet_cat.warning() - << "Socket_TCP_SSL::ErrorIs_WouldBlocking->Called With Error number " - << err << " or _ssl is NULL\n"; - return false; - } - - int ssl_error_code = SSL_get_error(_ssl,err); - bool answer = false; - - switch(ssl_error_code) { - case SSL_ERROR_WANT_READ: - case SSL_ERROR_WANT_WRITE: - case SSL_ERROR_WANT_CONNECT: -// case SSL_ERROR_WANT_ACCEPT: - answer = true; - break; -// hmm not sure we need this .. hmmmm - case SSL_ERROR_SYSCALL: - if(GETERROR() == LOCAL_BLOCKING_ERROR) { - answer = true; - } else { - DetailErrorFormat(); -// LOGWARNING("Socket_TCP_SSL::ErrorIs_WouldBlocking-> Not A blocking Error1 -// SSl_CODe=[%d] OS=[%d]",ssl_error_code,GETERROR()); - } - break; - default: - DetailErrorFormat(); -// LOGWARNING("Socket_TCP_SSL::ErrorIs_WouldBlocking-> Not A blocking Error2 -// SSl_CODe=[%d] OS=[%d]",ssl_error_code,GETERROR()); - answer = false; - break; - } - -// ERR_clear_error(); - return answer; -} - -inline void Socket_TCP_SSL:: -DetailErrorFormat(void) { - return; // turn on for debuging - - uint32_t l; - char buf[256]; - char buf2[4096]; - const char *file,*data; - int line,flags; - uint32_t es; - - es = CRYPTO_thread_id(); - while ((l = ERR_get_error_line_data(&file, &line, &data, &flags)) != 0) { - ERR_error_string_n(l, buf, sizeof(buf)); - BIO_snprintf(buf2, sizeof(buf2), "***%lu:%s:%s:%d:%s\n", (unsigned long) es, buf, file, line, (flags & ERR_TXT_STRING) ? data : "NoText"); - nativenet_cat.warning() - << "Socket_TCP_SSL::DetailErrorFormat->[" << buf2 << "]\n"; - } -} - -#endif // HAVE_OPENSSL - -#endif //__SOCKET_TCP_SSL_H__ diff --git a/panda/src/nativenet/time_base.h b/panda/src/nativenet/time_base.h index 8b7ea108f7..0aa12baf58 100644 --- a/panda/src/nativenet/time_base.h +++ b/panda/src/nativenet/time_base.h @@ -14,7 +14,7 @@ * returning the current system time ?? So use time functions that grab the * current system time sparingly ?? */ -#ifdef WIN32 +#ifdef _WIN32 #include #include #include @@ -64,7 +64,7 @@ inline void TimeAdd(const struct timeval &start, const struct timeval &delta, st NormalizeTime(answer); } -#ifdef WIN32 +#ifdef _WIN32 // Lets make Windows think it is a unix machine :) /** diff --git a/panda/src/net/CMakeLists.txt b/panda/src/net/CMakeLists.txt new file mode 100644 index 0000000000..d811b806e8 --- /dev/null +++ b/panda/src/net/CMakeLists.txt @@ -0,0 +1,51 @@ +if(NOT HAVE_NET OR NOT WANT_NATIVE_NET) + return() +endif() + +set(P3NET_HEADERS + config_net.h connection.h connectionListener.h + connectionManager.N connectionManager.h + connectionReader.I connectionReader.h + connectionWriter.h datagramQueue.h + datagramTCPHeader.I datagramTCPHeader.h + datagramUDPHeader.I datagramUDPHeader.h + netAddress.h netDatagram.I netDatagram.h + datagramGeneratorNet.I datagramGeneratorNet.h + datagramSinkNet.I datagramSinkNet.h + queuedConnectionListener.I + queuedConnectionListener.h queuedConnectionManager.h + queuedConnectionReader.h recentConnectionReader.h + queuedReturn.h queuedReturn.I +) + +set(P3NET_SOURCES + config_net.cxx connection.cxx connectionListener.cxx + connectionManager.cxx connectionReader.cxx + connectionWriter.cxx datagramQueue.cxx datagramTCPHeader.cxx + datagramUDPHeader.cxx netAddress.cxx netDatagram.cxx + datagramGeneratorNet.cxx + datagramSinkNet.cxx + queuedConnectionListener.cxx + queuedConnectionManager.cxx queuedConnectionReader.cxx + recentConnectionReader.cxx +) + +composite_sources(p3net P3NET_SOURCES) +add_component_library(p3net SYMBOL BUILDING_PANDA_NET + ${P3NET_HEADERS} ${P3NET_SOURCES}) +target_link_libraries(p3net p3nativenet p3pipeline p3pandabase pandaexpress) +target_interrogate(p3net ALL) + +if(WIN32) + target_link_libraries(p3net iphlpapi.lib) +endif() + +if(NOT BUILD_METALIBS) + install(TARGETS p3net + EXPORT Core COMPONENT Core + DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d + ARCHIVE COMPONENT CoreDevel) +endif() +install(FILES ${P3NET_HEADERS} COMPONENT CoreDevel DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d) diff --git a/panda/src/net/connectionManager.cxx b/panda/src/net/connectionManager.cxx index 6ad6063a8b..1af31a8f78 100644 --- a/panda/src/net/connectionManager.cxx +++ b/panda/src/net/connectionManager.cxx @@ -25,7 +25,7 @@ #if defined(CPPPARSER) #elif defined(_WIN32) #include // For gethostname() -#include // For GetAdaptersAddresses() +#include // For GetAdaptersAddresses() #elif defined(__ANDROID__) #include #else @@ -478,7 +478,7 @@ scan_interfaces() { _interfaces.clear(); _interfaces_scanned = true; -#ifdef WIN32_VC +#ifdef _WIN32 int flags = GAA_FLAG_INCLUDE_PREFIX | GAA_FLAG_SKIP_UNICAST | GAA_FLAG_SKIP_ANYCAST | GAA_FLAG_SKIP_MULTICAST | GAA_FLAG_SKIP_DNS_SERVER; ULONG family = support_ipv6 ? AF_UNSPEC : AF_INET; ULONG buffer_size = 0; @@ -544,7 +544,7 @@ scan_interfaces() { #elif defined(__ANDROID__) // TODO: implementation using netlink_socket? -#else // WIN32_VC +#else // _WIN32 struct ifaddrs *ifa; if (getifaddrs(&ifa) != 0) { // Failure. @@ -578,7 +578,7 @@ scan_interfaces() { freeifaddrs(ifa); -#endif // WIN32_VC +#endif // _WIN32 } /** diff --git a/panda/src/ode/CMakeLists.txt b/panda/src/ode/CMakeLists.txt new file mode 100644 index 0000000000..13bc422c74 --- /dev/null +++ b/panda/src/ode/CMakeLists.txt @@ -0,0 +1,103 @@ +if(NOT HAVE_ODE) + return() +endif() + +set(P3ODE_HEADERS + ode_includes.h config_ode.h + odeWorld.I odeWorld.h + odeMass.I odeMass.h + odeBody.I odeBody.h + odeJointGroup.I odeJointGroup.h + odeJoint.I odeJoint.h + odeUtil.h + odeSpace.I odeSpace.h + odeGeom.I odeGeom.h + odeSurfaceParameters.I odeSurfaceParameters.h + odeContactGeom.I odeContactGeom.h + odeContact.I odeContact.h + odeAMotorJoint.I odeAMotorJoint.h + odeBallJoint.I odeBallJoint.h + odeContactJoint.I odeContactJoint.h + odeFixedJoint.I odeFixedJoint.h + odeHingeJoint.I odeHingeJoint.h + odeHinge2Joint.I odeHinge2Joint.h + odeLMotorJoint.I odeLMotorJoint.h + odeNullJoint.I odeNullJoint.h + odePlane2dJoint.I odePlane2dJoint.h + odeSliderJoint.I odeSliderJoint.h + odeUniversalJoint.I odeUniversalJoint.h + odeJointCollection.I odeJointCollection.h + odeSimpleSpace.I odeSimpleSpace.h + odeHashSpace.I odeHashSpace.h + odeQuadTreeSpace.I odeQuadTreeSpace.h + odeSphereGeom.I odeSphereGeom.h + odeBoxGeom.I odeBoxGeom.h + odePlaneGeom.I odePlaneGeom.h + odeCappedCylinderGeom.I odeCappedCylinderGeom.h + odeCylinderGeom.I odeCylinderGeom.h + odeRayGeom.I odeRayGeom.h + odeTriMeshData.I odeTriMeshData.h + odeTriMeshGeom.I odeTriMeshGeom.h + odeCollisionEntry.I odeCollisionEntry.h + odeHelperStructs.h +) + +set(P3ODE_SOURCES + config_ode.cxx + odeWorld.cxx odeMass.cxx odeBody.cxx + odeJointGroup.cxx odeJoint.cxx + odeUtil.cxx + odeSpace.cxx + odeGeom.cxx + odeSurfaceParameters.cxx + odeContactGeom.cxx odeContact.cxx + odeAMotorJoint.cxx odeBallJoint.cxx + odeContactJoint.cxx odeFixedJoint.cxx + odeHingeJoint.cxx odeHinge2Joint.cxx + odeLMotorJoint.cxx odeNullJoint.cxx + odePlane2dJoint.cxx odeSliderJoint.cxx + odeUniversalJoint.cxx odeJointCollection.cxx + odeSimpleSpace.cxx + odeHashSpace.cxx odeQuadTreeSpace.cxx + odeSphereGeom.cxx odeBoxGeom.cxx + odePlaneGeom.cxx odeCappedCylinderGeom.cxx + odeCylinderGeom.cxx odeRayGeom.cxx + odeTriMeshData.cxx odeTriMeshGeom.cxx + odeCollisionEntry.cxx +) + +set(P3ODE_IGATEEXT + odeBody_ext.cxx + odeBody_ext.h + odeBody_ext.I + odeGeom_ext.cxx + odeGeom_ext.h + odeGeom_ext.I + odeJoint_ext.cxx + odeJoint_ext.h + odeSpace_ext.cxx + odeSpace_ext.h + odeSpace_ext.I + odeUtil_ext.cxx + odeUtil_ext.h +) + +set(P3ODE_IGATE_SOURCES "${P3ODE_HEADERS};${P3ODE_SOURCES}") +list(REMOVE_ITEM P3ODE_IGATE_SOURCES "odeHelperStructs.h") + +composite_sources(p3ode P3ODE_SOURCES) +add_library(p3ode ${P3ODE_SOURCES} ${P3ODE_HEADERS}) +set_target_properties(p3ode PROPERTIES DEFINE_SYMBOL BUILDING_PANDAODE) +target_link_libraries(p3ode panda + PKG::ODE) +target_interrogate(p3ode ${P3ODE_IGATE_SOURCES} EXTENSIONS ${P3ODE_IGATEEXT}) + +install(TARGETS p3ode + EXPORT ODE COMPONENT ODE + DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d + ARCHIVE COMPONENT ODEDevel) +install(FILES ${P3ODE_HEADERS} COMPONENT ODEDevel DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d) + +export_targets(ODE COMPONENT ODEDevel) diff --git a/panda/src/pandabase/CMakeLists.txt b/panda/src/pandabase/CMakeLists.txt new file mode 100644 index 0000000000..73633927c1 --- /dev/null +++ b/panda/src/pandabase/CMakeLists.txt @@ -0,0 +1,14 @@ +set(P3PANDABASE_HEADERS + pandabase.h pandasymbols.h +) + +set(P3PANDABASE_SOURCES + pandabase.cxx +) + +# Yes, INTERFACE: don't build it, there's no code! +add_library(p3pandabase INTERFACE) +target_link_libraries(p3pandabase INTERFACE p3dtool) + +install(FILES ${P3PANDABASE_HEADERS} COMPONENT CoreDevel DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d) +install(TARGETS p3pandabase EXPORT Core COMPONENT Core) diff --git a/panda/src/pandabase/pandasymbols.h b/panda/src/pandabase/pandasymbols.h index 1d4d487edd..3cabc46e8b 100644 --- a/panda/src/pandabase/pandasymbols.h +++ b/panda/src/pandabase/pandasymbols.h @@ -587,7 +587,7 @@ #define EXPTP_VRPN IMPORT_TEMPL #endif -#if (defined(WIN32_VC) || defined(WIN64_VC)) && !defined(CPPPARSER) +#if defined(_MSC_VER) && !defined(CPPPARSER) #define INLINE_LINMATH __forceinline #define INLINE_MATHUTIL __forceinline diff --git a/panda/src/parametrics/CMakeLists.txt b/panda/src/parametrics/CMakeLists.txt new file mode 100644 index 0000000000..5f1a96593f --- /dev/null +++ b/panda/src/parametrics/CMakeLists.txt @@ -0,0 +1,51 @@ +set(P3PARAMETRICS_HEADERS + config_parametrics.h + cubicCurveseg.h curveFitter.I curveFitter.h + hermiteCurve.h + nurbsCurve.I nurbsCurve.h + nurbsCurveEvaluator.I nurbsCurveEvaluator.h + nurbsCurveInterface.I nurbsCurveInterface.h + nurbsCurveResult.I nurbsCurveResult.h + nurbsBasisVector.I nurbsBasisVector.h + nurbsSurfaceEvaluator.I nurbsSurfaceEvaluator.h + nurbsSurfaceResult.I nurbsSurfaceResult.h + nurbsVertex.h nurbsVertex.I + parametricCurve.h + parametricCurveCollection.I parametricCurveCollection.h + piecewiseCurve.h + ropeNode.I ropeNode.h + sheetNode.I sheetNode.h +) + +set(P3PARAMETRICS_SOURCES + config_parametrics.cxx cubicCurveseg.cxx + curveFitter.cxx hermiteCurve.cxx + nurbsCurve.cxx + nurbsCurveEvaluator.cxx + nurbsCurveInterface.cxx + nurbsCurveResult.cxx + nurbsBasisVector.cxx + nurbsSurfaceEvaluator.cxx + nurbsSurfaceResult.cxx + nurbsVertex.cxx + parametricCurve.cxx parametricCurveCollection.cxx + piecewiseCurve.cxx + ropeNode.cxx + sheetNode.cxx +) + +composite_sources(p3parametrics P3PARAMETRICS_SOURCES) +add_component_library(p3parametrics NOINIT SYMBOL BUILDING_PANDA_PARAMETRICS + ${P3PARAMETRICS_HEADERS} ${P3PARAMETRICS_SOURCES}) +target_link_libraries(p3parametrics p3pgraph) +target_interrogate(p3parametrics ALL) + +if(NOT BUILD_METALIBS) + install(TARGETS p3parametrics + EXPORT Core COMPONENT Core + DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d + ARCHIVE COMPONENT CoreDevel) +endif() +install(FILES ${P3PARAMETRICS_HEADERS} COMPONENT CoreDevel DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d) diff --git a/panda/src/particlesystem/CMakeLists.txt b/panda/src/particlesystem/CMakeLists.txt new file mode 100644 index 0000000000..7a227f7dc6 --- /dev/null +++ b/panda/src/particlesystem/CMakeLists.txt @@ -0,0 +1,64 @@ +set(P3PARTICLESYSTEM_HEADERS + baseParticle.I baseParticle.h baseParticleEmitter.I + baseParticleEmitter.h baseParticleFactory.I + baseParticleFactory.h baseParticleRenderer.I + baseParticleRenderer.h arcEmitter.I arcEmitter.h + boxEmitter.I boxEmitter.h + config_particlesystem.h discEmitter.I discEmitter.h + emitters.h + geomParticleRenderer.I geomParticleRenderer.h lineEmitter.I + lineEmitter.h lineParticleRenderer.I lineParticleRenderer.h + particlefactories.h + particles.h + particleSystem.I particleSystem.h particleSystemManager.I + particleSystemManager.h pointEmitter.I pointEmitter.h + pointParticle.h pointParticleFactory.h + pointParticleRenderer.I pointParticleRenderer.h + rectangleEmitter.I rectangleEmitter.h ringEmitter.I + ringEmitter.h sparkleParticleRenderer.I + sparkleParticleRenderer.h sphereSurfaceEmitter.I + sphereSurfaceEmitter.h sphereVolumeEmitter.I + sphereVolumeEmitter.h spriteParticleRenderer.I + spriteParticleRenderer.h tangentRingEmitter.I + tangentRingEmitter.h zSpinParticle.I zSpinParticle.h + zSpinParticleFactory.I zSpinParticleFactory.h + particleCommonFuncs.h colorInterpolationManager.I + colorInterpolationManager.h +) + +set(P3PARTICLESYSTEM_SOURCES + baseParticle.cxx baseParticleEmitter.cxx baseParticleFactory.cxx + baseParticleRenderer.cxx boxEmitter.cxx arcEmitter.cxx + config_particlesystem.cxx discEmitter.cxx + geomParticleRenderer.cxx lineEmitter.cxx + lineParticleRenderer.cxx particleSystem.cxx + particleSystemManager.cxx pointEmitter.cxx pointParticle.cxx + pointParticleFactory.cxx pointParticleRenderer.cxx + rectangleEmitter.cxx ringEmitter.cxx + sparkleParticleRenderer.cxx sphereSurfaceEmitter.cxx + sphereVolumeEmitter.cxx spriteParticleRenderer.cxx + tangentRingEmitter.cxx zSpinParticle.cxx + zSpinParticleFactory.cxx colorInterpolationManager.cxx +) + +set(P3PARTICLESYSTEM_IGATE_SOURCES + ${P3PARTICLESYSTEM_HEADERS} ${P3PARTICLESYSTEM_SOURCES}) +list(REMOVE_ITEM P3PARTICLESYSTEM_IGATE_SOURCES "emitters.h") +list(REMOVE_ITEM P3PARTICLESYSTEM_IGATE_SOURCES "particlefactories.h") +list(REMOVE_ITEM P3PARTICLESYSTEM_IGATE_SOURCES "particles.h") + +composite_sources(p3particlesystem P3PARTICLESYSTEM_SOURCES) +add_component_library(p3particlesystem SYMBOL BUILDING_PANDA_PARTICLESYSTEM + ${P3PARTICLESYSTEM_HEADERS} ${P3PARTICLESYSTEM_SOURCES}) +target_link_libraries(p3particlesystem p3physics panda) +target_interrogate(p3particlesystem ${P3PARTICLESYSTEM_IGATE_SOURCES}) + +if(NOT BUILD_METALIBS) + install(TARGETS p3particlesystem + EXPORT Core COMPONENT Core + DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d + ARCHIVE COMPONENT CoreDevel) +endif() +install(FILES ${P3PARTICLESYSTEM_HEADERS} COMPONENT CoreDevel DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d) diff --git a/panda/src/particlesystem/particleSystem.h b/panda/src/particlesystem/particleSystem.h index 7518bbfd9a..6d77d520dc 100644 --- a/panda/src/particlesystem/particleSystem.h +++ b/panda/src/particlesystem/particleSystem.h @@ -104,6 +104,8 @@ PUBLISHED: virtual void write_spawn_templates(std::ostream &out, int indent=0) const; virtual void write(std::ostream &out, int indent=0) const; + void birth_litter(); + private: #ifdef PSSANITYCHECK int sanity_check(); @@ -111,7 +113,6 @@ private: bool birth_particle(); void kill_particle(int pool_index); - void birth_litter(); void resize_pool(int size); pdeque< int > _free_particle_fifo; diff --git a/panda/src/pgraph/CMakeLists.txt b/panda/src/pgraph/CMakeLists.txt new file mode 100644 index 0000000000..80559490c8 --- /dev/null +++ b/panda/src/pgraph/CMakeLists.txt @@ -0,0 +1,246 @@ +set(P3PGRAPH_HEADERS + accumulatedAttribs.I accumulatedAttribs.h + alphaTestAttrib.I alphaTestAttrib.h + antialiasAttrib.I antialiasAttrib.h + attribNodeRegistry.I attribNodeRegistry.h + audioVolumeAttrib.I audioVolumeAttrib.h + auxSceneData.I auxSceneData.h + auxBitplaneAttrib.I auxBitplaneAttrib.h + bamFile.I bamFile.h + billboardEffect.I billboardEffect.h + cacheStats.I cacheStats.h + camera.I camera.h + clipPlaneAttrib.I clipPlaneAttrib.h + colorAttrib.I colorAttrib.h + colorBlendAttrib.I colorBlendAttrib.h + colorScaleAttrib.I colorScaleAttrib.h + colorWriteAttrib.I colorWriteAttrib.h + compassEffect.I compassEffect.h + config_pgraph.h + cullBin.I cullBin.h + cullBinEnums.h + cullBinAttrib.I cullBinAttrib.h + cullBinManager.I cullBinManager.h + cullFaceAttrib.I cullFaceAttrib.h + cullHandler.I cullHandler.h + cullPlanes.I cullPlanes.h + cullResult.I cullResult.h + cullTraverser.I cullTraverser.h + cullTraverserData.I cullTraverserData.h + cullableObject.I cullableObject.h + decalEffect.I decalEffect.h + depthOffsetAttrib.I depthOffsetAttrib.h + depthTestAttrib.I depthTestAttrib.h + depthWriteAttrib.I depthWriteAttrib.h + findApproxLevelEntry.I findApproxLevelEntry.h + findApproxPath.I findApproxPath.h + fog.I fog.h + fogAttrib.I fogAttrib.h + geomDrawCallbackData.I geomDrawCallbackData.h + geomNode.I geomNode.h + geomTransformer.I geomTransformer.h + internalNameCollection.I internalNameCollection.h + lensNode.I lensNode.h + light.I light.h + lightAttrib.I lightAttrib.h + lightRampAttrib.I lightRampAttrib.h + loader.I loader.h + loaderFileType.h + loaderFileTypeBam.h + loaderFileTypeRegistry.h + logicOpAttrib.I logicOpAttrib.h + materialAttrib.I materialAttrib.h + materialCollection.I materialCollection.h + modelFlattenRequest.I modelFlattenRequest.h + modelLoadRequest.I modelLoadRequest.h + modelSaveRequest.I modelSaveRequest.h + modelNode.I modelNode.h + modelPool.I modelPool.h + modelRoot.I modelRoot.h + nodePath.I nodePath.h + nodePathCollection.I nodePathCollection.h + nodePathComponent.I nodePathComponent.h + occluderEffect.I occluderEffect.h + occluderNode.I occluderNode.h + pandaNode.I pandaNode.h + pandaNodeChain.I pandaNodeChain.h + planeNode.I planeNode.h + paramNodePath.I paramNodePath.h + polylightEffect.I polylightEffect.h + polylightNode.I polylightNode.h + portalNode.I portalNode.h + portalClipper.I portalClipper.h + renderAttrib.I renderAttrib.h + renderAttribRegistry.I renderAttribRegistry.h + renderEffect.I renderEffect.h + renderEffects.I renderEffects.h + renderModeAttrib.I renderModeAttrib.h + renderState.I renderState.h + rescaleNormalAttrib.I rescaleNormalAttrib.h + sceneGraphReducer.I sceneGraphReducer.h + sceneSetup.I sceneSetup.h + scissorAttrib.I scissorAttrib.h + scissorEffect.I scissorEffect.h + shadeModelAttrib.I shadeModelAttrib.h + shaderAttrib.I shaderAttrib.h + shaderInput.I shaderInput.h + shaderPool.I shaderPool.h + showBoundsEffect.I showBoundsEffect.h + stateMunger.I stateMunger.h + stencilAttrib.I stencilAttrib.h + texMatrixAttrib.I texMatrixAttrib.h + texProjectorEffect.I texProjectorEffect.h + textureAttrib.I textureAttrib.h + texGenAttrib.I texGenAttrib.h + textureStageCollection.I textureStageCollection.h + transformState.I transformState.h + transparencyAttrib.I transparencyAttrib.h + weakNodePath.I weakNodePath.h + workingNodePath.I workingNodePath.h +) + +set(P3PGRAPH_SOURCES + accumulatedAttribs.cxx + alphaTestAttrib.cxx + antialiasAttrib.cxx + attribNodeRegistry.cxx + audioVolumeAttrib.cxx + auxBitplaneAttrib.cxx + auxSceneData.cxx + bamFile.cxx + billboardEffect.cxx + cacheStats.cxx + camera.cxx + clipPlaneAttrib.cxx + colorAttrib.cxx + colorBlendAttrib.cxx + colorScaleAttrib.cxx + colorWriteAttrib.cxx + compassEffect.cxx + config_pgraph.cxx + cullBin.cxx + cullBinAttrib.cxx + cullBinManager.cxx + cullFaceAttrib.cxx + cullHandler.cxx + cullPlanes.cxx + cullResult.cxx + cullTraverser.cxx + cullTraverserData.cxx + cullableObject.cxx + decalEffect.cxx + depthOffsetAttrib.cxx + depthTestAttrib.cxx + depthWriteAttrib.cxx + findApproxLevelEntry.cxx + findApproxPath.cxx + fog.cxx + fogAttrib.cxx + geomDrawCallbackData.cxx + geomNode.cxx + geomTransformer.cxx + internalNameCollection.cxx + lensNode.cxx + light.cxx + lightAttrib.cxx + lightRampAttrib.cxx + loader.cxx + loaderFileType.cxx + loaderFileTypeBam.cxx + loaderFileTypeRegistry.cxx + logicOpAttrib.cxx + materialAttrib.cxx + materialCollection.cxx + modelFlattenRequest.cxx + modelLoadRequest.cxx + modelSaveRequest.cxx + modelNode.cxx + modelPool.cxx + modelRoot.cxx + nodePath.cxx + nodePathCollection.cxx + nodePathComponent.cxx + occluderEffect.cxx + occluderNode.cxx + pandaNode.cxx + pandaNodeChain.cxx + planeNode.cxx + paramNodePath.cxx + polylightEffect.cxx + polylightNode.cxx + portalNode.cxx + portalClipper.cxx + renderAttrib.cxx + renderAttribRegistry.cxx + renderEffect.cxx + renderEffects.cxx + renderModeAttrib.cxx + renderState.cxx + rescaleNormalAttrib.cxx + sceneGraphReducer.cxx + sceneSetup.cxx + scissorAttrib.cxx + scissorEffect.cxx + shadeModelAttrib.cxx + shaderAttrib.cxx + shaderInput.cxx + shaderPool.cxx + showBoundsEffect.cxx + stateMunger.cxx + stencilAttrib.cxx + texMatrixAttrib.cxx + texProjectorEffect.cxx + textureAttrib.cxx + texGenAttrib.cxx + textureStageCollection.cxx + transformState.cxx + transparencyAttrib.cxx + weakNodePath.cxx + workingNodePath.cxx +) + +set(P3PGRAPH_IGATEEXT + loaderFileTypeRegistry_ext.cxx + loaderFileTypeRegistry_ext.h + nodePathCollection_ext.cxx + nodePathCollection_ext.h + nodePath_ext.cxx + nodePath_ext.h + nodePath_ext.I + pandaNode_ext.cxx + pandaNode_ext.h + pythonLoaderFileType.cxx + pythonLoaderFileType.h + renderState_ext.cxx + renderState_ext.h + shaderAttrib_ext.cxx + shaderAttrib_ext.h + shaderInput_ext.cxx + shaderInput_ext.h + transformState_ext.cxx + transformState_ext.h +) + +# This is a large file; let's build it separately +set_source_files_properties(nodePath.cxx PROPERTIES SKIP_UNITY_BUILD_INCLUSION YES) + +composite_sources(p3pgraph P3PGRAPH_SOURCES) +add_component_library(p3pgraph SYMBOL BUILDING_PANDA_PGRAPH + ${P3PGRAPH_HEADERS} ${P3PGRAPH_SOURCES}) +target_link_libraries(p3pgraph p3gobj p3event p3gsgbase p3putil p3linmath pandaexpress) +target_interrogate(p3pgraph ALL EXTENSIONS ${P3PGRAPH_IGATEEXT}) + +if(HAVE_EIGEN) + # Eigen puts this over the threshold where bigobj is needed on MSVC + set_target_properties(p3pgraph PROPERTIES MSVC_BIGOBJ ON) +endif() + +if(NOT BUILD_METALIBS) + install(TARGETS p3pgraph + EXPORT Core COMPONENT Core + DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d + ARCHIVE COMPONENT CoreDevel) +endif() +install(FILES ${P3PGRAPH_HEADERS} COMPONENT CoreDevel DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d) diff --git a/panda/src/pgraph/cullableObject.cxx b/panda/src/pgraph/cullableObject.cxx index 920e524659..38f35f7024 100644 --- a/panda/src/pgraph/cullableObject.cxx +++ b/panda/src/pgraph/cullableObject.cxx @@ -223,29 +223,23 @@ munge_points_to_quads(const CullTraverser *traverser, bool force) { return false; } + GeomVertexDataPipelineReader reader(source_data, current_thread); + reader.check_array_readers(); + PStatTimer timer(_munge_sprites_pcollector, current_thread); - _sw_sprites_pcollector.add_level(source_data->get_num_rows()); + _sw_sprites_pcollector.add_level(reader.get_num_rows()); GraphicsStateGuardianBase *gsg = traverser->get_gsg(); - GeomVertexReader vertex(source_data, InternalName::get_vertex(), - current_thread); - GeomVertexReader normal(source_data, InternalName::get_normal(), - current_thread); - GeomVertexReader color(source_data, InternalName::get_color(), - current_thread); - GeomVertexReader texcoord(source_data, InternalName::get_texcoord(), - current_thread); - GeomVertexReader rotate(source_data, InternalName::get_rotate(), - current_thread); - GeomVertexReader size(source_data, InternalName::get_size(), - current_thread); - GeomVertexReader aspect_ratio(source_data, InternalName::get_aspect_ratio(), - current_thread); + GeomVertexReader vertex(&reader, InternalName::get_vertex()); + GeomVertexReader normal(&reader, InternalName::get_normal()); + GeomVertexReader rotate(&reader, InternalName::get_rotate()); + GeomVertexReader size(&reader, InternalName::get_size()); + GeomVertexReader aspect_ratio(&reader, InternalName::get_aspect_ratio()); bool has_normal = (normal.has_column()); - bool has_color = (color.has_column()); - bool has_texcoord = (texcoord.has_column()); + bool has_color = (reader.has_column(InternalName::get_color())); + bool has_texcoord = (reader.has_column(InternalName::get_texcoord())); bool has_rotate = (rotate.has_column()); bool has_size = (size.has_column()); bool has_aspect_ratio = (aspect_ratio.has_column()); @@ -280,7 +274,7 @@ munge_points_to_quads(const CullTraverser *traverser, bool force) { { LightMutexHolder holder(_format_lock); - SourceFormat sformat(source_data->get_format(), sprite_texcoord); + SourceFormat sformat(reader.get_format(), sprite_texcoord); FormatMap::iterator fmi = _format_map.find(sformat); if (fmi != _format_map.end()) { new_format = (*fmi).second; @@ -304,13 +298,13 @@ munge_points_to_quads(const CullTraverser *traverser, bool force) { Geom::C_clip_point); } if (has_normal) { - const GeomVertexColumn *c = normal.get_column(); + const GeomVertexColumn *c = reader.get_format()->get_normal_column(); new_array_format->add_column (InternalName::get_normal(), c->get_num_components(), c->get_numeric_type(), c->get_contents()); } if (has_color) { - const GeomVertexColumn *c = color.get_column(); + const GeomVertexColumn *c = reader.get_format()->get_color_column(); new_array_format->add_column (InternalName::get_color(), c->get_num_components(), c->get_numeric_type(), c->get_contents()); @@ -322,12 +316,34 @@ munge_points_to_quads(const CullTraverser *traverser, bool force) { Geom::C_texcoord); } else if (has_texcoord) { - const GeomVertexColumn *c = texcoord.get_column(); + const GeomVertexColumn *c = reader.get_format()->get_column(InternalName::get_texcoord()); new_array_format->add_column (InternalName::get_texcoord(), c->get_num_components(), c->get_numeric_type(), c->get_contents()); } + // Go through the other columns and copy them from the original. + for (size_t ai = 0; ai < sformat._format->get_num_arrays(); ++ai) { + const GeomVertexArrayFormat *aformat = sformat._format->get_array(ai); + + for (size_t ci = 0; ci < aformat->get_num_columns(); ++ci) { + const GeomVertexColumn *column = aformat->get_column(ci); + const InternalName *name = column->get_name(); + if (name != InternalName::get_vertex() && + name != InternalName::get_normal() && + name != InternalName::get_color() && + name != InternalName::get_texcoord() && + name != InternalName::get_rotate() && + name != InternalName::get_size() && + name != InternalName::get_aspect_ratio()) { + + new_array_format->add_column(name, + column->get_num_components(), column->get_numeric_type(), + column->get_contents()); + } + } + } + new_format = GeomVertexFormat::register_format(new_array_format); _format_map[sformat] = new_format; } @@ -362,7 +378,7 @@ munge_points_to_quads(const CullTraverser *traverser, bool force) { // Now convert all of the vertices in the GeomVertexData to quads. We // always convert all the vertices, assuming all the vertices are referenced // by GeomPrimitives, because we want to optimize for the most common case. - int orig_verts = source_data->get_num_rows(); + int orig_verts = reader.get_num_rows(); int new_verts = 4 * orig_verts; // each vertex becomes four. PT(GeomVertexData) new_data = new GeomVertexData @@ -371,9 +387,50 @@ munge_points_to_quads(const CullTraverser *traverser, bool force) { GeomVertexWriter new_vertex(new_data, InternalName::get_vertex()); GeomVertexWriter new_normal(new_data, InternalName::get_normal()); - GeomVertexWriter new_color(new_data, InternalName::get_color()); GeomVertexWriter new_texcoord(new_data, InternalName::get_texcoord()); + nassertr(new_vertex.has_column(), false); + unsigned char *write_ptr = new_vertex.get_array_handle()->get_write_pointer(); + + // Collect all other columns that we just need to copy the data of. + struct CopyOp { + unsigned char *_to_pointer; + const unsigned char *_from_pointer; + size_t _num_bytes; + size_t _from_stride; + }; + pvector copies; + + const GeomVertexArrayFormat *aformat = new_format->get_array(0); + for (size_t ci = 0; ci < aformat->get_num_columns(); ++ci) { + const GeomVertexColumn *column = aformat->get_column(ci); + const InternalName *name = column->get_name(); + if (name != InternalName::get_vertex() && + (retransform_sprites || name != InternalName::get_normal()) && + (!sprite_texcoord || name != InternalName::get_texcoord())) { + + int source_array; + const GeomVertexColumn *source_column; + if (reader.get_format()->get_array_info(name, source_array, source_column)) { + CopyOp copy; + copy._to_pointer = write_ptr + (size_t)column->get_start(); + copy._from_pointer = reader.get_array_reader(source_array)->get_read_pointer(true) + (size_t)source_column->get_start(); + copy._num_bytes = (size_t)column->get_total_bytes(); + copy._from_stride = reader.get_format()->get_array(source_array)->get_stride(); + + if (!copies.empty() && + (copy._to_pointer == copies.back()._to_pointer + copies.back()._num_bytes) && + (copy._from_pointer == copies.back()._from_pointer + copies.back()._num_bytes)) { + // Merge with previous. + copies.back()._num_bytes += copy._num_bytes; + } else { + copies.push_back(copy); + } + } + } + } + size_t to_stride = aformat->get_stride(); + // We'll keep an array of all of the points' eye-space coordinates, and // their distance from the camera, so we can sort the points for each // primitive, below. @@ -447,14 +504,6 @@ munge_points_to_quads(const CullTraverser *traverser, bool force) { new_vertex.set_data4(inv_render_transform.xform(LPoint4(p4[0] - c1[0], p4[1] - c1[1], p4[2], p4[3]))); new_vertex.set_data4(inv_render_transform.xform(LPoint4(p4[0] - c0[0], p4[1] - c0[1], p4[2], p4[3]))); - if (has_normal) { - const LNormal &c = normal.get_data3(); - new_normal.set_data3(c); - new_normal.set_data3(c); - new_normal.set_data3(c); - new_normal.set_data3(c); - } - } else { // Without retransform_sprites, we can simply load the clip-space // coordinates. @@ -464,6 +513,7 @@ munge_points_to_quads(const CullTraverser *traverser, bool force) { new_vertex.set_data4(p4[0] - c0[0], p4[1] - c0[1], p4[2], p4[3]); if (has_normal) { + // We need to transform the normals to clip-space too, then. LNormal c = render_transform.xform_vec(normal.get_data3()); new_normal.set_data3(c); new_normal.set_data3(c); @@ -471,24 +521,24 @@ munge_points_to_quads(const CullTraverser *traverser, bool force) { new_normal.set_data3(c); } } - if (has_color) { - const LColor &c = color.get_data4(); - new_color.set_data4(c); - new_color.set_data4(c); - new_color.set_data4(c); - new_color.set_data4(c); - } if (sprite_texcoord) { new_texcoord.set_data2(1.0f, 0.0f); new_texcoord.set_data2(0.0f, 0.0f); new_texcoord.set_data2(1.0f, 1.0f); new_texcoord.set_data2(0.0f, 1.0f); - } else if (has_texcoord) { - const LVecBase4 &c = texcoord.get_data4(); - new_texcoord.set_data4(c); - new_texcoord.set_data4(c); - new_texcoord.set_data4(c); - new_texcoord.set_data4(c); + } + + // Other columns are simply duplicated for each vertex. + for (CopyOp © : copies) { + memcpy(copy._to_pointer, copy._from_pointer, copy._num_bytes); + copy._to_pointer += to_stride; + memcpy(copy._to_pointer, copy._from_pointer, copy._num_bytes); + copy._to_pointer += to_stride; + memcpy(copy._to_pointer, copy._from_pointer, copy._num_bytes); + copy._to_pointer += to_stride; + memcpy(copy._to_pointer, copy._from_pointer, copy._num_bytes); + copy._to_pointer += to_stride; + copy._from_pointer += copy._from_stride; } ++vi; diff --git a/panda/src/pgraph/findApproxPath.h b/panda/src/pgraph/findApproxPath.h index fe3ac5d765..a9a7ba8827 100644 --- a/panda/src/pgraph/findApproxPath.h +++ b/panda/src/pgraph/findApproxPath.h @@ -59,7 +59,7 @@ public: void output(std::ostream &out) const; INLINE void output_component(std::ostream &out, int index) const; -#if !defined(WIN32_VC) && !defined(WIN64_VC) +#ifndef _MSC_VER // Visual C++ won't let us define the ostream operator functions for these // guys if they're private--even though we declare them friends. private: diff --git a/panda/src/pgraph/pandaNode.h b/panda/src/pgraph/pandaNode.h index cec5e220a2..b008a4f850 100644 --- a/panda/src/pgraph/pandaNode.h +++ b/panda/src/pgraph/pandaNode.h @@ -566,11 +566,6 @@ private: INLINE void set_fancy_bit(int bits, bool value); -#ifdef HAVE_PYTHON - void inc_py_refs(); - void dec_py_refs(); -#endif - CPT(RenderEffects) _effects; TagData _tag_data; diff --git a/panda/src/pgraph/shaderAttrib.cxx b/panda/src/pgraph/shaderAttrib.cxx index 7647945291..fde1a99a3d 100644 --- a/panda/src/pgraph/shaderAttrib.cxx +++ b/panda/src/pgraph/shaderAttrib.cxx @@ -530,7 +530,8 @@ get_shader_input_matrix(const InternalName *id, LMatrix4 &matrix) const { if (p.get_value_type() == ShaderInput::M_nodepath) { const NodePath &np = p.get_nodepath(); nassertr(!np.is_empty(), LMatrix4::ident_mat()); - return np.get_transform()->get_mat(); + matrix = np.get_transform()->get_mat(); + return matrix; } else if (p.get_value_type() == ShaderInput::M_numeric && p.get_ptr()._size >= 16 && (p.get_ptr()._size & 15) == 0) { diff --git a/panda/src/pgraphnodes/CMakeLists.txt b/panda/src/pgraphnodes/CMakeLists.txt new file mode 100644 index 0000000000..7b25e2b5bf --- /dev/null +++ b/panda/src/pgraphnodes/CMakeLists.txt @@ -0,0 +1,61 @@ +set(P3PGRAPHNODES_HEADERS + ambientLight.h ambientLight.I + callbackNode.h callbackNode.I + computeNode.h computeNode.I + config_pgraphnodes.h + directionalLight.h directionalLight.I + fadeLodNode.I fadeLodNode.h fadeLodNodeData.h + lightLensNode.h lightLensNode.I + lightNode.h lightNode.I + lodNode.I lodNode.h lodNodeType.h + nodeCullCallbackData.h nodeCullCallbackData.I + pointLight.h pointLight.I + rectangleLight.h rectangleLight.I + sceneGraphAnalyzer.h sceneGraphAnalyzer.I + selectiveChildNode.h selectiveChildNode.I + sequenceNode.h sequenceNode.I + shaderGenerator.h shaderGenerator.I + sphereLight.h sphereLight.I + spotlight.h spotlight.I + switchNode.h switchNode.I + uvScrollNode.I uvScrollNode.h +) + +set(P3PGRAPHNODES_SOURCES + ambientLight.cxx + callbackNode.cxx + computeNode.cxx + config_pgraphnodes.cxx + directionalLight.cxx + fadeLodNode.cxx fadeLodNodeData.cxx + lightLensNode.cxx + lightNode.cxx + lodNode.cxx lodNodeType.cxx + nodeCullCallbackData.cxx + pointLight.cxx + rectangleLight.cxx + sceneGraphAnalyzer.cxx + selectiveChildNode.cxx + sequenceNode.cxx + shaderGenerator.cxx + sphereLight.cxx + spotlight.cxx + switchNode.cxx + uvScrollNode.cxx +) + +composite_sources(p3pgraphnodes P3PGRAPHNODES_SOURCES) +add_component_library(p3pgraphnodes SYMBOL BUILDING_PANDA_PGRAPHNODES + ${P3PGRAPHNODES_HEADERS} ${P3PGRAPHNODES_SOURCES}) +target_link_libraries(p3pgraphnodes p3pgraph) +target_interrogate(p3pgraphnodes ALL) + +if(NOT BUILD_METALIBS) + install(TARGETS p3pgraphnodes + EXPORT Core COMPONENT Core + DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d + ARCHIVE COMPONENT CoreDevel) +endif() +install(FILES ${P3PGRAPHNODES_HEADERS} COMPONENT CoreDevel DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d) diff --git a/panda/src/pgui/CMakeLists.txt b/panda/src/pgui/CMakeLists.txt new file mode 100644 index 0000000000..0b68d56653 --- /dev/null +++ b/panda/src/pgui/CMakeLists.txt @@ -0,0 +1,57 @@ +set(P3PGUI_HEADERS + config_pgui.h + pgButton.I pgButton.h + pgButtonNotify.I pgButtonNotify.h + pgCullTraverser.I pgCullTraverser.h + pgEntry.I pgEntry.h + pgMouseWatcherGroup.I pgMouseWatcherGroup.h + pgMouseWatcherParameter.I pgMouseWatcherParameter.h + pgFrameStyle.I pgFrameStyle.h + pgItem.I pgItem.h + pgItemNotify.I pgItemNotify.h + pgMouseWatcherBackground.h + pgMouseWatcherRegion.I pgMouseWatcherRegion.h + pgScrollFrame.I pgScrollFrame.h + pgSliderBar.I pgSliderBar.h + pgSliderBarNotify.I pgSliderBarNotify.h + pgTop.I pgTop.h + pgVirtualFrame.I pgVirtualFrame.h + pgWaitBar.I pgWaitBar.h +) + +set(P3PGUI_SOURCES + config_pgui.cxx + pgButton.cxx + pgButtonNotify.cxx + pgCullTraverser.cxx + pgEntry.cxx + pgMouseWatcherGroup.cxx + pgMouseWatcherParameter.cxx + pgFrameStyle.cxx + pgItem.cxx + pgItemNotify.cxx + pgMouseWatcherBackground.cxx + pgMouseWatcherRegion.cxx + pgScrollFrame.cxx + pgSliderBar.cxx + pgSliderBarNotify.cxx + pgTop.cxx + pgVirtualFrame.cxx + pgWaitBar.cxx +) + +composite_sources(p3pgui P3PGUI_SOURCES) +add_component_library(p3pgui SYMBOL BUILDING_PANDA_PGUI + ${P3PGUI_HEADERS} ${P3PGUI_SOURCES}) +target_link_libraries(p3pgui p3tform) +target_interrogate(p3pgui ALL) + +if(NOT BUILD_METALIBS) + install(TARGETS p3pgui + EXPORT Core COMPONENT Core + DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d + ARCHIVE COMPONENT CoreDevel) +endif() +install(FILES ${P3PGUI_HEADERS} COMPONENT CoreDevel DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d) diff --git a/panda/src/physics/CMakeLists.txt b/panda/src/physics/CMakeLists.txt new file mode 100644 index 0000000000..9b0b9456b6 --- /dev/null +++ b/panda/src/physics/CMakeLists.txt @@ -0,0 +1,55 @@ +set(P3PHYSICS_HEADERS + actorNode.I actorNode.h angularEulerIntegrator.h angularForce.h + angularIntegrator.h angularVectorForce.I + angularVectorForce.h baseForce.I baseForce.h + baseIntegrator.I baseIntegrator.h config_physics.h + forces.h + forceNode.I forceNode.h + linearControlForce.I linearControlForce.h + linearCylinderVortexForce.I linearCylinderVortexForce.h + linearDistanceForce.I + linearDistanceForce.h linearEulerIntegrator.h linearForce.I + linearForce.h linearFrictionForce.I linearFrictionForce.h + linearIntegrator.h linearJitterForce.h linearNoiseForce.I + linearNoiseForce.h linearRandomForce.I linearRandomForce.h + linearSinkForce.h linearSourceForce.h + linearUserDefinedForce.I linearUserDefinedForce.h + linearVectorForce.I linearVectorForce.h physical.I + physical.h physicalNode.I physicalNode.h + physicsCollisionHandler.I physicsCollisionHandler.h + physicsManager.I physicsManager.h + physicsObject.I physicsObject.h + physicsObjectCollection.I physicsObjectCollection.h +) + +set(P3PHYSICS_SOURCES + actorNode.cxx angularEulerIntegrator.cxx angularForce.cxx + angularIntegrator.cxx angularVectorForce.cxx baseForce.cxx + baseIntegrator.cxx config_physics.cxx forceNode.cxx + linearControlForce.cxx + linearCylinderVortexForce.cxx linearDistanceForce.cxx + linearEulerIntegrator.cxx linearForce.cxx + linearFrictionForce.cxx linearIntegrator.cxx + linearJitterForce.cxx linearNoiseForce.cxx + linearRandomForce.cxx linearSinkForce.cxx + linearSourceForce.cxx linearUserDefinedForce.cxx + linearVectorForce.cxx physical.cxx physicalNode.cxx + physicsCollisionHandler.cxx physicsManager.cxx physicsObject.cxx + physicsObjectCollection.cxx +) + +composite_sources(p3physics P3PHYSICS_SOURCES) +add_component_library(p3physics SYMBOL BUILDING_PANDA_PHYSICS + ${P3PHYSICS_HEADERS} ${P3PHYSICS_SOURCES}) +target_link_libraries(p3physics panda) +target_interrogate(p3physics ALL) + +if(NOT BUILD_METALIBS) + install(TARGETS p3physics + EXPORT Core COMPONENT Core + DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d + ARCHIVE COMPONENT CoreDevel) +endif() +install(FILES ${P3PHYSICS_HEADERS} COMPONENT CoreDevel DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d) diff --git a/panda/src/pipeline/CMakeLists.txt b/panda/src/pipeline/CMakeLists.txt new file mode 100644 index 0000000000..aa7852623b --- /dev/null +++ b/panda/src/pipeline/CMakeLists.txt @@ -0,0 +1,148 @@ +set(P3PIPELINE_HEADERS + contextSwitch.h + blockerSimple.h blockerSimple.I + conditionVar.h conditionVar.I + conditionVarDebug.h conditionVarDebug.I + conditionVarDirect.h conditionVarDirect.I + conditionVarDummyImpl.h conditionVarDummyImpl.I + conditionVarFull.h + conditionVarImpl.h + conditionVarSimpleImpl.h conditionVarSimpleImpl.I + conditionVarSpinlockImpl.h conditionVarSpinlockImpl.I + conditionVarPosixImpl.h conditionVarPosixImpl.I + config_pipeline.h + cycleData.h cycleData.I + cycleDataLockedReader.h cycleDataLockedReader.I + cycleDataLockedStageReader.h cycleDataLockedStageReader.I + cycleDataReader.h cycleDataReader.I + cycleDataStageReader.h cycleDataStageReader.I + cycleDataStageWriter.h cycleDataStageWriter.I + cycleDataWriter.h cycleDataWriter.I + cyclerHolder.h cyclerHolder.I + externalThread.h + genericThread.h genericThread.I + lightMutex.I lightMutex.h + lightMutexDirect.h lightMutexDirect.I + lightMutexHolder.I lightMutexHolder.h + lightReMutex.I lightReMutex.h + lightReMutexDirect.h lightReMutexDirect.I + lightReMutexHolder.I lightReMutexHolder.h + mainThread.h + mutexDebug.h mutexDebug.I + mutexDirect.h mutexDirect.I + mutexHolder.h mutexHolder.I + mutexSimpleImpl.h mutexSimpleImpl.I + mutexTrueImpl.h + pipeline.h pipeline.I + pipelineCycler.h pipelineCycler.I + pipelineCyclerLinks.h pipelineCyclerLinks.I + pipelineCyclerBase.h + pipelineCyclerDummyImpl.h pipelineCyclerDummyImpl.I + pipelineCyclerTrivialImpl.h pipelineCyclerTrivialImpl.I + pipelineCyclerTrueImpl.h pipelineCyclerTrueImpl.I + pmutex.h pmutex.I + reMutex.I reMutex.h + reMutexDirect.h reMutexDirect.I + reMutexHolder.h reMutexHolder.I + reMutexSpinlockImpl.h reMutexSpinlockImpl.I + psemaphore.h psemaphore.I + thread.h thread.I threadImpl.h + threadDummyImpl.h threadDummyImpl.I + threadSimpleImpl.h threadSimpleImpl.I + threadPosixImpl.h threadPosixImpl.I + threadSimpleManager.h threadSimpleManager.I + threadPriority.h +) + +set(P3PIPELINE_SOURCES + contextSwitch.c + conditionVar.cxx + conditionVarDebug.cxx + conditionVarDirect.cxx + conditionVarDummyImpl.cxx + conditionVarSimpleImpl.cxx + conditionVarSpinlockImpl.cxx + conditionVarPosixImpl.cxx + config_pipeline.cxx + cycleData.cxx + cycleDataLockedReader.cxx + cycleDataLockedStageReader.cxx + cycleDataReader.cxx + cycleDataStageReader.cxx + cycleDataStageWriter.cxx + cycleDataWriter.cxx + cyclerHolder.cxx + externalThread.cxx + genericThread.cxx + lightMutex.cxx + lightMutexDirect.cxx + lightMutexHolder.cxx + lightReMutex.cxx + lightReMutexDirect.cxx + lightReMutexHolder.cxx + mainThread.cxx + mutexDebug.cxx + mutexDirect.cxx + mutexHolder.cxx + mutexSimpleImpl.cxx + pipeline.cxx + pipelineCycler.cxx + pipelineCyclerDummyImpl.cxx + pipelineCyclerTrivialImpl.cxx + pipelineCyclerTrueImpl.cxx + pmutex.cxx + reMutex.cxx + reMutexDirect.cxx + reMutexHolder.cxx + reMutexSpinlockImpl.cxx + psemaphore.cxx + thread.cxx + threadDummyImpl.cxx + threadPosixImpl.cxx + threadSimpleImpl.cxx + threadSimpleManager.cxx + threadPriority.cxx +) + +if(WIN32) + list(APPEND P3PIPELINE_HEADERS + conditionVarWin32Impl.h conditionVarWin32Impl.I + threadWin32Impl.h threadWin32Impl.I) + list(APPEND P3PIPELINE_SOURCES + conditionVarWin32Impl.cxx + threadWin32Impl.cxx) +endif() + +set(P3PIPELINE_IGATEEXT + pmutex_ext.h + pmutex_ext.I + pythonThread.cxx + pythonThread.h + reMutex_ext.h + reMutex_ext.I +) + +composite_sources(p3pipeline P3PIPELINE_SOURCES) +add_component_library(p3pipeline SYMBOL BUILDING_PANDA_PIPELINE + ${P3PIPELINE_HEADERS} ${P3PIPELINE_SOURCES}) +target_link_libraries(p3pipeline pandaexpress + PKG::THREADS) +target_interrogate(p3pipeline ALL EXTENSIONS ${P3PIPELINE_IGATEEXT}) + +if(PHAVE_UCONTEXT_H) + target_compile_definitions(p3pipeline PRIVATE PHAVE_UCONTEXT_H) +endif() + +if(OS_SIMPLE_THREADS) + target_compile_definitions(p3pipeline PRIVATE OS_SIMPLE_THREADS) +endif() + +if(NOT BUILD_METALIBS) + install(TARGETS p3pipeline + EXPORT Core COMPONENT Core + DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d + ARCHIVE COMPONENT CoreDevel) +endif() +install(FILES ${P3PIPELINE_HEADERS} COMPONENT CoreDevel DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d) diff --git a/panda/src/pipeline/conditionVarImpl.h b/panda/src/pipeline/conditionVarImpl.h index 774ab72753..880573340b 100644 --- a/panda/src/pipeline/conditionVarImpl.h +++ b/panda/src/pipeline/conditionVarImpl.h @@ -46,7 +46,7 @@ typedef ConditionVarPosixImpl ConditionVarImpl; typedef ConditionVarImpl ConditionVarFullImpl; -#if defined(WIN32_VC) +#ifdef _WIN32 #include "conditionVarWin32Impl.h" typedef ConditionVarWin32Impl TrueConditionVarImpl; diff --git a/panda/src/pipeline/conditionVarWin32Impl.cxx b/panda/src/pipeline/conditionVarWin32Impl.cxx index 9d3a95e0b1..5ba4165a0c 100644 --- a/panda/src/pipeline/conditionVarWin32Impl.cxx +++ b/panda/src/pipeline/conditionVarWin32Impl.cxx @@ -13,8 +13,8 @@ #include "selectThreadImpl.h" -#if defined(WIN32_VC) || defined(WIN64_VC) +#ifdef _WIN32 #include "conditionVarWin32Impl.h" -#endif // WIN32_VC +#endif // _WIN32 diff --git a/panda/src/pipeline/conditionVarWin32Impl.h b/panda/src/pipeline/conditionVarWin32Impl.h index b7daa767bd..5c8d4a91d3 100644 --- a/panda/src/pipeline/conditionVarWin32Impl.h +++ b/panda/src/pipeline/conditionVarWin32Impl.h @@ -17,7 +17,7 @@ #include "pandabase.h" #include "selectThreadImpl.h" -#if defined(WIN32_VC) +#ifdef _WIN32 #include "mutexWin32Impl.h" #include "pnotify.h" @@ -44,6 +44,6 @@ private: #include "conditionVarWin32Impl.I" -#endif // WIN32_VC +#endif // _WIN32 #endif diff --git a/panda/src/pipeline/test_delete.cxx b/panda/src/pipeline/test_delete.cxx index 3ea431f77b..af0c168ee7 100644 --- a/panda/src/pipeline/test_delete.cxx +++ b/panda/src/pipeline/test_delete.cxx @@ -29,7 +29,7 @@ static const int max_doobers_per_chunk = 1000; // The number of threads to spawn. static const int number_of_threads = 4; -#if defined(WIN32_VC) || defined(WIN64_VC) +#ifdef _WIN32 static int last_rand = 0; #endif /* __WIN32__ */ @@ -39,7 +39,7 @@ static double random_f(double max) { MutexHolder l(rand_mutex); int i = rand(); -#if defined(WIN32_VC) || defined(WIN64_VC) +#ifdef _WIN32 last_rand = i; #endif /* __WIN32__ */ return max * (double)i / (double)RAND_MAX; @@ -88,7 +88,7 @@ public: thread_main() { OUTPUT(nout << *this << " beginning.\n"); -#if defined(WIN32_VC) || defined(WIN64_VC) +#ifdef _WIN32 rand_mutex.acquire(); srand(last_rand); rand_mutex.release(); diff --git a/panda/src/pipeline/test_diners.cxx b/panda/src/pipeline/test_diners.cxx index a5ff82e446..24631078e9 100644 --- a/panda/src/pipeline/test_diners.cxx +++ b/panda/src/pipeline/test_diners.cxx @@ -26,7 +26,7 @@ using std::cerr; -#ifdef WIN32_VC +#ifdef _WIN32 // Under Windows, the rand() function seems to return a sequence per-thread, // so we use this trick to set each thread to a different seed. static int last_rand = 0; @@ -38,7 +38,7 @@ static double random_f(double max) { MutexHolder l(rand_mutex); int i = rand(); -#ifdef WIN32_VC +#ifdef _WIN32 last_rand = i; #endif /* __WIN32__ */ return max * (double)i / (double)RAND_MAX; @@ -76,7 +76,7 @@ class philosopher : public Thread { private: int _id; void thread_main() { -#ifdef WIN32_VC +#ifdef _WIN32 rand_mutex.acquire(); srand(last_rand); rand_mutex.release(); diff --git a/panda/src/pipeline/threadDummyImpl.I b/panda/src/pipeline/threadDummyImpl.I index 0bd2f7747a..7bab1ae408 100644 --- a/panda/src/pipeline/threadDummyImpl.I +++ b/panda/src/pipeline/threadDummyImpl.I @@ -101,14 +101,14 @@ is_simple_threads() { */ INLINE void ThreadDummyImpl:: sleep(double seconds) { -#ifdef WIN32 +#ifdef _WIN32 Sleep((int)(seconds * 1000)); #else struct timespec rqtp; rqtp.tv_sec = time_t(seconds); rqtp.tv_nsec = long((seconds - (double)rqtp.tv_sec) * 1000000000.0); nanosleep(&rqtp, nullptr); -#endif // WIN32 +#endif // _WIN32 } /** diff --git a/panda/src/pipeline/threadDummyImpl.cxx b/panda/src/pipeline/threadDummyImpl.cxx index 2d30630d98..e5d0d0642c 100644 --- a/panda/src/pipeline/threadDummyImpl.cxx +++ b/panda/src/pipeline/threadDummyImpl.cxx @@ -32,7 +32,7 @@ std::string ThreadDummyImpl:: get_unique_id() const { // In a single-threaded application, this is just the unique process ID. std::ostringstream strm; -#ifdef WIN32 +#ifdef _WIN32 strm << GetCurrentProcessId(); #else strm << getpid(); diff --git a/panda/src/pipeline/threadDummyImpl.h b/panda/src/pipeline/threadDummyImpl.h index 7721ca2d6c..c7cea7a3ca 100644 --- a/panda/src/pipeline/threadDummyImpl.h +++ b/panda/src/pipeline/threadDummyImpl.h @@ -24,7 +24,7 @@ class Thread; -#ifdef WIN32 +#ifdef _WIN32 #ifndef WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN 1 #endif diff --git a/panda/src/pnmimage/CMakeLists.txt b/panda/src/pnmimage/CMakeLists.txt new file mode 100644 index 0000000000..8c6e17abac --- /dev/null +++ b/panda/src/pnmimage/CMakeLists.txt @@ -0,0 +1,56 @@ +set(P3PNMIMAGE_HEADERS + config_pnmimage.h + convert_srgb.h convert_srgb.I + pfmFile.I pfmFile.h + pnmbitio.h + pnmBrush.h pnmBrush.I + pnmFileType.h pnmFileTypeRegistry.h pnmImage.I + pnmImage.h pnmImageHeader.I pnmImageHeader.h + pnmPainter.h pnmPainter.I + pnmReader.I + pnmReader.h pnmWriter.I pnmWriter.h pnmimage_base.h + ppmcmap.h +) + +set(P3PNMIMAGE_SOURCES + config_pnmimage.cxx + convert_srgb.cxx + convert_srgb_sse2.cxx + pfmFile.cxx + pnm-image-filter.cxx + pnmbitio.cxx + pnmBrush.cxx + pnmFileType.cxx + pnmFileTypeRegistry.cxx pnmImage.cxx pnmImageHeader.cxx + pnmPainter.cxx + pnmReader.cxx pnmWriter.cxx pnmimage_base.cxx + ppmcmap.cxx +) + +set(P3PNMIMAGE_IGATEEXT + pfmFile_ext.cxx + pfmFile_ext.h +) + +if(HAVE_SSE2 AND CMAKE_SIZEOF_VOID_P EQUAL 4 AND CMAKE_SYSTEM_PROCESSOR MATCHES "86") + # It's only necessary to do this on 32-bit x86; 64-bit makes SSE2 builtin. + set_source_files_properties(convert_srgb_sse2.cxx PROPERTIES + SKIP_UNITY_BUILD_INCLUSION YES + COMPILE_FLAGS -msse2) +endif() + +composite_sources(p3pnmimage P3PNMIMAGE_SOURCES) +add_component_library(p3pnmimage SYMBOL BUILDING_PANDA_PNMIMAGE + ${P3PNMIMAGE_HEADERS} ${P3PNMIMAGE_SOURCES}) +target_link_libraries(p3pnmimage p3mathutil) +target_interrogate(p3pnmimage ALL EXTENSIONS ${P3PNMIMAGE_IGATEEXT}) + +if(NOT BUILD_METALIBS) + install(TARGETS p3pnmimage + EXPORT Core COMPONENT Core + DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d + ARCHIVE COMPONENT CoreDevel) +endif() +install(FILES ${P3PNMIMAGE_HEADERS} COMPONENT CoreDevel DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d) diff --git a/panda/src/pnmimage/pnmimage_base.cxx b/panda/src/pnmimage/pnmimage_base.cxx index d5ef09e415..f30939575d 100644 --- a/panda/src/pnmimage/pnmimage_base.cxx +++ b/panda/src/pnmimage/pnmimage_base.cxx @@ -33,12 +33,8 @@ pm_message(const char *format, ...) { static const size_t buffer_size = 1024; char buffer[buffer_size]; -#if defined(WIN32_VC) || defined(WIN64_VC) - // Windows doesn't define vsnprintf(). Hope we don't overflow. - vsprintf(buffer, format, ap); -#else + vsnprintf(buffer, buffer_size, format, ap); -#endif nassertv(strlen(buffer) < buffer_size); pnmimage_cat.info() << buffer << "\n"; @@ -57,12 +53,8 @@ pm_error(const char *format, ...) { static const size_t buffer_size = 1024; char buffer[buffer_size]; -#if defined(WIN32_VC) || defined(WIN64_VC) - // Windows doesn't define vsnprintf(). Hope we don't overflow. - vsprintf(buffer, format, ap); -#else + vsnprintf(buffer, buffer_size, format, ap); -#endif nassertv(strlen(buffer) < buffer_size); pnmimage_cat.error() << buffer << "\n"; diff --git a/panda/src/pnmimagetypes/CMakeLists.txt b/panda/src/pnmimagetypes/CMakeLists.txt new file mode 100644 index 0000000000..84c8ceeab7 --- /dev/null +++ b/panda/src/pnmimagetypes/CMakeLists.txt @@ -0,0 +1,48 @@ +set(P3PNMIMAGETYPES_HEADERS + config_pnmimagetypes.h + pnmFileTypeBMP.h + pnmFileTypeEXR.h + pnmFileTypeIMG.h + pnmFileTypePNG.h + pnmFileTypePNM.h + pnmFileTypePfm.h + pnmFileTypeSGI.h pnmFileTypeSoftImage.h + pnmFileTypeStbImage.h + pnmFileTypeTGA.h + pnmFileTypeTIFF.h + pnmFileTypeJPG.h + sgi.h +) + +set(P3PNMIMAGETYPES_SOURCES + config_pnmimagetypes.cxx + pnmFileTypeBMPReader.cxx pnmFileTypeBMPWriter.cxx + pnmFileTypeBMP.cxx + pnmFileTypeEXR.cxx + pnmFileTypeIMG.cxx + pnmFileTypeJPG.cxx pnmFileTypeJPGReader.cxx pnmFileTypeJPGWriter.cxx + pnmFileTypePNG.cxx + pnmFileTypePNM.cxx + pnmFileTypePfm.cxx + pnmFileTypeSGI.cxx + pnmFileTypeSGIReader.cxx pnmFileTypeSGIWriter.cxx + pnmFileTypeSoftImage.cxx + pnmFileTypeStbImage.cxx + pnmFileTypeTIFF.cxx + pnmFileTypeTGA.cxx +) + +composite_sources(p3pnmimagetypes P3PNMIMAGETYPES_SOURCES) +add_component_library(p3pnmimagetypes SYMBOL BUILDING_PANDA_PNMIMAGETYPES + ${P3PNMIMAGETYPES_HEADERS} ${P3PNMIMAGETYPES_SOURCES}) +target_link_libraries(p3pnmimagetypes p3pnmimage + PKG::JPEG PKG::TIFF PKG::PNG PKG::OPENEXR) +set_target_properties(p3pnmimagetypes PROPERTIES CXX_EXCEPTIONS ON) + +if(NOT BUILD_METALIBS) + install(TARGETS p3pnmimagetypes + EXPORT Core COMPONENT Core + DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + ARCHIVE COMPONENT CoreDevel) +endif() diff --git a/panda/src/pnmimagetypes/colrops.c b/panda/src/pnmimagetypes/colrops.c index a82bf85399..51608dcbfe 100644 --- a/panda/src/pnmimagetypes/colrops.c +++ b/panda/src/pnmimagetypes/colrops.c @@ -1,5 +1,5 @@ /* Filename: colrops.c - * Created by: + * Created by: * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * @@ -23,7 +23,7 @@ #endif #define bmalloc malloc -#if !defined(WIN32_VC) && !defined(WIN64_VC) +#ifndef _WIN32 extern char *bmalloc(int); #else #include @@ -37,7 +37,7 @@ static BYTE *g_mant = NULL, *g_nexp = NULL; static BYTE (*g_bval)[256] = NULL; #ifndef pow -#if !defined(WIN32_VC) && !defined(WIN64_VC) +#ifndef _WIN32 extern double pow(double, double); #endif #endif diff --git a/panda/src/pnmimagetypes/pnmFileTypeBMP.h b/panda/src/pnmimagetypes/pnmFileTypeBMP.h index 6cd3e8e32f..1777699bcd 100644 --- a/panda/src/pnmimagetypes/pnmFileTypeBMP.h +++ b/panda/src/pnmimagetypes/pnmFileTypeBMP.h @@ -25,7 +25,7 @@ /** * For reading and writing Windows BMP files. */ -class EXPCL_PANDA_PNMIMAGETYPES PNMFileTypeBMP : public PNMFileType { +class PNMFileTypeBMP : public PNMFileType { public: PNMFileTypeBMP(); diff --git a/panda/src/pnmimagetypes/pnmFileTypeEXR.h b/panda/src/pnmimagetypes/pnmFileTypeEXR.h index 75a2b000e9..23e211ee98 100644 --- a/panda/src/pnmimagetypes/pnmFileTypeEXR.h +++ b/panda/src/pnmimagetypes/pnmFileTypeEXR.h @@ -36,7 +36,7 @@ class ImfStdIstream; /** * For reading and writing EXR floating-point or integer files. */ -class EXPCL_PANDA_PNMIMAGETYPES PNMFileTypeEXR : public PNMFileType { +class PNMFileTypeEXR : public PNMFileType { public: PNMFileTypeEXR(); diff --git a/panda/src/pnmimagetypes/pnmFileTypeIMG.h b/panda/src/pnmimagetypes/pnmFileTypeIMG.h index 2c406dfa68..e75aaeb972 100644 --- a/panda/src/pnmimagetypes/pnmFileTypeIMG.h +++ b/panda/src/pnmimagetypes/pnmFileTypeIMG.h @@ -25,7 +25,7 @@ /** * For reading and writing headerless R,G,B files. */ -class EXPCL_PANDA_PNMIMAGETYPES PNMFileTypeIMG : public PNMFileType { +class PNMFileTypeIMG : public PNMFileType { public: PNMFileTypeIMG(); diff --git a/panda/src/pnmimagetypes/pnmFileTypeJPG.h b/panda/src/pnmimagetypes/pnmFileTypeJPG.h index f851c6d226..d577e52bf6 100644 --- a/panda/src/pnmimagetypes/pnmFileTypeJPG.h +++ b/panda/src/pnmimagetypes/pnmFileTypeJPG.h @@ -55,7 +55,7 @@ extern "C" { /** * For reading and writing Jpeg files. */ -class EXPCL_PANDA_PNMIMAGETYPES PNMFileTypeJPG : public PNMFileType { +class PNMFileTypeJPG : public PNMFileType { public: PNMFileTypeJPG(); diff --git a/panda/src/pnmimagetypes/pnmFileTypePNG.h b/panda/src/pnmimagetypes/pnmFileTypePNG.h index 3c1df88cbc..535a5b2f43 100644 --- a/panda/src/pnmimagetypes/pnmFileTypePNG.h +++ b/panda/src/pnmimagetypes/pnmFileTypePNG.h @@ -28,7 +28,7 @@ /** * For reading and writing PNG files. */ -class EXPCL_PANDA_PNMIMAGETYPES PNMFileTypePNG : public PNMFileType { +class PNMFileTypePNG : public PNMFileType { public: PNMFileTypePNG(); diff --git a/panda/src/pnmimagetypes/pnmFileTypePNM.h b/panda/src/pnmimagetypes/pnmFileTypePNM.h index 1c65c19109..811661b1fa 100644 --- a/panda/src/pnmimagetypes/pnmFileTypePNM.h +++ b/panda/src/pnmimagetypes/pnmFileTypePNM.h @@ -25,7 +25,7 @@ /** * For reading and writing basic PNM files--*.pbm, *.ppm, *.pnm. */ -class EXPCL_PANDA_PNMIMAGETYPES PNMFileTypePNM : public PNMFileType { +class PNMFileTypePNM : public PNMFileType { public: PNMFileTypePNM(); diff --git a/panda/src/pnmimagetypes/pnmFileTypePfm.h b/panda/src/pnmimagetypes/pnmFileTypePfm.h index ab18685084..c97ec46eb6 100644 --- a/panda/src/pnmimagetypes/pnmFileTypePfm.h +++ b/panda/src/pnmimagetypes/pnmFileTypePfm.h @@ -25,7 +25,7 @@ * For reading and writing PFM files using the basic PNMImage interface, as if * they were basic RGB files. */ -class EXPCL_PANDA_PNMIMAGETYPES PNMFileTypePfm : public PNMFileType { +class PNMFileTypePfm : public PNMFileType { public: PNMFileTypePfm(); diff --git a/panda/src/pnmimagetypes/pnmFileTypeSGI.h b/panda/src/pnmimagetypes/pnmFileTypeSGI.h index ff026a3740..dbced028e2 100644 --- a/panda/src/pnmimagetypes/pnmFileTypeSGI.h +++ b/panda/src/pnmimagetypes/pnmFileTypeSGI.h @@ -25,7 +25,7 @@ /** * For reading and writing SGI RGB files. */ -class EXPCL_PANDA_PNMIMAGETYPES PNMFileTypeSGI : public PNMFileType { +class PNMFileTypeSGI : public PNMFileType { public: PNMFileTypeSGI(); diff --git a/panda/src/pnmimagetypes/pnmFileTypeSoftImage.h b/panda/src/pnmimagetypes/pnmFileTypeSoftImage.h index c6e6860621..55457bbfca 100644 --- a/panda/src/pnmimagetypes/pnmFileTypeSoftImage.h +++ b/panda/src/pnmimagetypes/pnmFileTypeSoftImage.h @@ -25,7 +25,7 @@ /** * For reading and SoftImage native image files. */ -class EXPCL_PANDA_PNMIMAGETYPES PNMFileTypeSoftImage : public PNMFileType { +class PNMFileTypeSoftImage : public PNMFileType { public: PNMFileTypeSoftImage(); diff --git a/panda/src/pnmimagetypes/pnmFileTypeStbImage.h b/panda/src/pnmimagetypes/pnmFileTypeStbImage.h index ce7d2d55ea..260d6dc61c 100644 --- a/panda/src/pnmimagetypes/pnmFileTypeStbImage.h +++ b/panda/src/pnmimagetypes/pnmFileTypeStbImage.h @@ -27,7 +27,7 @@ * when compiling without support for more specific libraries that are more * full-featured, such as libpng or libjpeg. */ -class EXPCL_PANDA_PNMIMAGETYPES PNMFileTypeStbImage : public PNMFileType { +class PNMFileTypeStbImage : public PNMFileType { public: PNMFileTypeStbImage(); diff --git a/panda/src/pnmimagetypes/pnmFileTypeTGA.h b/panda/src/pnmimagetypes/pnmFileTypeTGA.h index c50a09ed47..d4ce1426cd 100644 --- a/panda/src/pnmimagetypes/pnmFileTypeTGA.h +++ b/panda/src/pnmimagetypes/pnmFileTypeTGA.h @@ -26,11 +26,10 @@ struct ImageHeader; - /** * For reading and writing Targa image files. */ -class EXPCL_PANDA_PNMIMAGETYPES PNMFileTypeTGA : public PNMFileType { +class PNMFileTypeTGA : public PNMFileType { public: PNMFileTypeTGA(); diff --git a/panda/src/pnmimagetypes/pnmFileTypeTIFF.cxx b/panda/src/pnmimagetypes/pnmFileTypeTIFF.cxx index 3c4634055d..b90f416f9a 100644 --- a/panda/src/pnmimagetypes/pnmFileTypeTIFF.cxx +++ b/panda/src/pnmimagetypes/pnmFileTypeTIFF.cxx @@ -1215,11 +1215,7 @@ void PNMFileTypeTIFF:: tiff_warning(const char *, const char *format, va_list ap) { static const int buffer_size = 1024; char buffer[buffer_size]; -#if defined(WIN32_VC) || defined(WIN64_VC) - vsprintf(buffer, format, ap); -#else vsnprintf(buffer, buffer_size, format, ap); -#endif // We ignore the module. It seems generally useless to us. pnmimage_tiff_cat.warning() @@ -1234,11 +1230,7 @@ void PNMFileTypeTIFF:: tiff_error(const char *module, const char *format, va_list ap) { static const int buffer_size = 1024; char buffer[buffer_size]; -#if defined(WIN32_VC) || defined(WIN64_VC) - vsprintf(buffer, format, ap); -#else vsnprintf(buffer, buffer_size, format, ap); -#endif // We ignore the module. It seems generally useless to us. pnmimage_tiff_cat.error() diff --git a/panda/src/pnmimagetypes/pnmFileTypeTIFF.h b/panda/src/pnmimagetypes/pnmFileTypeTIFF.h index c61e4f53f1..36148a082e 100644 --- a/panda/src/pnmimagetypes/pnmFileTypeTIFF.h +++ b/panda/src/pnmimagetypes/pnmFileTypeTIFF.h @@ -30,7 +30,7 @@ /** * For reading and writing TIFF files. */ -class EXPCL_PANDA_PNMIMAGETYPES PNMFileTypeTIFF : public PNMFileType { +class PNMFileTypeTIFF : public PNMFileType { public: PNMFileTypeTIFF(); diff --git a/panda/src/pnmtext/CMakeLists.txt b/panda/src/pnmtext/CMakeLists.txt new file mode 100644 index 0000000000..6acc9bd910 --- /dev/null +++ b/panda/src/pnmtext/CMakeLists.txt @@ -0,0 +1,35 @@ +if(NOT HAVE_FREETYPE) + return() +endif() + +set(P3PNMTEXT_HEADERS + config_pnmtext.h + freetypeFace.h freetypeFace.I + freetypeFont.h freetypeFont.I + pnmTextGlyph.h pnmTextGlyph.I + pnmTextMaker.h pnmTextMaker.I +) + +set(P3PNMTEXT_SOURCES + config_pnmtext.cxx + freetypeFace.cxx + freetypeFont.cxx + pnmTextGlyph.cxx + pnmTextMaker.cxx +) + +composite_sources(p3pnmtext P3PNMTEXT_SOURCES) +add_component_library(p3pnmtext SYMBOL BUILDING_PANDA_PNMTEXT + ${P3PNMTEXT_HEADERS} ${P3PNMTEXT_SOURCES}) +target_link_libraries(p3pnmtext p3parametrics p3pnmimage PKG::FREETYPE) +target_interrogate(p3pnmtext ALL) + +if(NOT BUILD_METALIBS) + install(TARGETS p3pnmtext + EXPORT Core COMPONENT Core + DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d + ARCHIVE COMPONENT CoreDevel) +endif() +install(FILES ${P3PNMTEXT_HEADERS} COMPONENT CoreDevel DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d) diff --git a/panda/src/pstatclient/CMakeLists.txt b/panda/src/pstatclient/CMakeLists.txt new file mode 100644 index 0000000000..2aa8e37f77 --- /dev/null +++ b/panda/src/pstatclient/CMakeLists.txt @@ -0,0 +1,45 @@ +set(P3PSTATCLIENT_HEADERS + config_pstatclient.h pStatClient.I pStatClient.h + pStatClientImpl.I pStatClientImpl.h + pStatClientVersion.I + pStatClientVersion.h pStatClientControlMessage.h + pStatCollector.I pStatCollector.h pStatCollectorDef.h + pStatCollectorForward.I pStatCollectorForward.h + pStatFrameData.I pStatFrameData.h pStatProperties.h + pStatServerControlMessage.h pStatThread.I pStatThread.h + pStatTimer.I pStatTimer.h +) + +set(P3PSTATCLIENT_SOURCES + config_pstatclient.cxx pStatClient.cxx pStatClientImpl.cxx + pStatClientVersion.cxx + pStatClientControlMessage.cxx + pStatCollector.cxx + pStatCollectorDef.cxx + pStatCollectorForward.cxx + pStatFrameData.cxx pStatProperties.cxx + pStatServerControlMessage.cxx + pStatThread.cxx +) + +composite_sources(p3pstatclient P3PSTATCLIENT_SOURCES) +add_component_library(p3pstatclient SYMBOL BUILDING_PANDA_PSTATCLIENT + ${P3PSTATCLIENT_HEADERS} ${P3PSTATCLIENT_SOURCES}) +target_link_libraries(p3pstatclient p3putil pandaexpress) + +if(HAVE_NET AND WANT_NATIVE_NET) + target_link_libraries(p3pstatclient p3net) +endif() + +target_interrogate(p3pstatclient ALL) + +if(NOT BUILD_METALIBS) + install(TARGETS p3pstatclient + EXPORT Core COMPONENT Core + DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d + ARCHIVE COMPONENT CoreDevel) +endif() +install(FILES ${P3PSTATCLIENT_HEADERS} COMPONENT CoreDevel DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d) +install(FILES config_pstats.h COMPONENT CoreDevel DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d) diff --git a/panda/src/pstatclient/pStatClientImpl.cxx b/panda/src/pstatclient/pStatClientImpl.cxx index d607a53bd9..f25b863b97 100644 --- a/panda/src/pstatclient/pStatClientImpl.cxx +++ b/panda/src/pstatclient/pStatClientImpl.cxx @@ -27,8 +27,8 @@ #include -#if defined(WIN32_VC) || defined(WIN64_VC) -#include +#ifdef _WIN32 +#include #include #endif diff --git a/panda/src/putil/CMakeLists.txt b/panda/src/putil/CMakeLists.txt new file mode 100644 index 0000000000..5b5d841f19 --- /dev/null +++ b/panda/src/putil/CMakeLists.txt @@ -0,0 +1,150 @@ +set(P3PUTIL_HEADERS + animInterface.h animInterface.I + autoTextureScale.h + bam.h + bamCache.h bamCache.I + bamCacheIndex.h bamCacheIndex.I + bamCacheRecord.h bamCacheRecord.I + bamEnums.h + bamReader.I bamReader.h bamReaderParam.I + bamReaderParam.h + bamWriter.I bamWriter.h + bitArray.I bitArray.h + bitMask.I bitMask.h + buttonHandle.I buttonHandle.h + buttonMap.I buttonMap.h + buttonRegistry.I buttonRegistry.h + cachedTypedWritableReferenceCount.h cachedTypedWritableReferenceCount.I + callbackData.h callbackData.I + callbackObject.h callbackObject.I + clockObject.h clockObject.I + collideMask.h + colorSpace.h + copyOnWriteObject.h copyOnWriteObject.I + copyOnWritePointer.h copyOnWritePointer.I + compareTo.I compareTo.h + config_putil.N config_putil.h configurable.h + cPointerCallbackObject.h cPointerCallbackObject.I + datagramBuffer.I datagramBuffer.h + datagramInputFile.I datagramInputFile.h + datagramOutputFile.I datagramOutputFile.h + doubleBitMask.I doubleBitMask.h + drawMask.h + factory.I factory.h + factoryBase.I factoryBase.h + factoryParam.I factoryParam.h factoryParams.I + factoryParams.h + firstOfPairCompare.I firstOfPairCompare.h + firstOfPairLess.I firstOfPairLess.h + gamepadButton.h + globalPointerRegistry.I globalPointerRegistry.h + indirectCompareNames.I indirectCompareNames.h + indirectCompareSort.I indirectCompareSort.h + indirectCompareTo.I indirectCompareTo.h + ioPtaDatagramFloat.h ioPtaDatagramInt.h + ioPtaDatagramShort.h keyboardButton.h + iterator_types.h + linkedListNode.I linkedListNode.h + load_prc_file.h + loaderOptions.I loaderOptions.h + modifierButtons.I modifierButtons.h + mouseButton.h mouseData.h + nameUniquifier.I nameUniquifier.h + nodeCachedReferenceCount.h nodeCachedReferenceCount.I + paramValue.I paramValue.h + pbitops.I pbitops.h + pointerData.h pointerData.I + portalMask.h + pta_ushort.h + simpleHashMap.I simpleHashMap.h + sparseArray.I sparseArray.h + timedCycle.I timedCycle.h typedWritable.I + typedWritable.h typedWritableReferenceCount.I + typedWritableReferenceCount.h updateSeq.I updateSeq.h + uniqueIdAllocator.h + vector_typedWritable.h + vector_ulong.h + vector_ushort.h vector_writable.h + writableConfigurable.h + writableParam.I writableParam.h +) + +set(P3PUTIL_SOURCES + animInterface.cxx + autoTextureScale.cxx + bamCache.cxx + bamCacheIndex.cxx + bamCacheRecord.cxx + bamEnums.cxx + bamReader.cxx bamReaderParam.cxx + bamWriter.cxx + bitArray.cxx + bitMask.cxx + buttonHandle.cxx buttonMap.cxx buttonRegistry.cxx + cachedTypedWritableReferenceCount.cxx + callbackData.cxx + callbackObject.cxx + clockObject.cxx + colorSpace.cxx + copyOnWriteObject.cxx + copyOnWritePointer.cxx + config_putil.cxx configurable.cxx + cPointerCallbackObject.cxx + datagramBuffer.cxx + datagramInputFile.cxx datagramOutputFile.cxx + doubleBitMask.cxx + factoryBase.cxx + factoryParam.cxx factoryParams.cxx + gamepadButton.cxx + globalPointerRegistry.cxx + ioPtaDatagramFloat.cxx + ioPtaDatagramInt.cxx ioPtaDatagramShort.cxx + keyboardButton.cxx + linkedListNode.cxx + load_prc_file.cxx + loaderOptions.cxx + modifierButtons.cxx + mouseButton.cxx + nameUniquifier.cxx + nodeCachedReferenceCount.cxx + paramValue.cxx + pbitops.cxx + pointerData.cxx + pta_ushort.cxx + simpleHashMap.cxx + sparseArray.cxx + timedCycle.cxx typedWritable.cxx + typedWritableReferenceCount.cxx updateSeq.cxx + uniqueIdAllocator.cxx + vector_typedWritable.cxx + vector_ulong.cxx + vector_ushort.cxx vector_writable.cxx + writableConfigurable.cxx writableParam.cxx +) + +set(P3PUTIL_IGATEEXT + bamReader_ext.cxx + bamReader_ext.h + callbackObject_ext.h + pythonCallbackObject.cxx + pythonCallbackObject.h + typedWritable_ext.cxx + typedWritable_ext.h +) + +composite_sources(p3putil P3PUTIL_SOURCES) +add_component_library(p3putil SYMBOL BUILDING_PANDA_PUTIL + ${P3PUTIL_HEADERS} ${P3PUTIL_SOURCES}) +target_link_libraries(p3putil p3linmath p3pipeline) +target_interrogate(p3putil ALL EXTENSIONS ${P3PUTIL_IGATEEXT}) + +if(NOT BUILD_METALIBS) + install(TARGETS p3putil + EXPORT Core COMPONENT Core + DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d + ARCHIVE COMPONENT CoreDevel) +endif() +install(FILES ${P3PUTIL_HEADERS} COMPONENT CoreDevel DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d) +install(FILES config_util.h COMPONENT CoreDevel DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d) diff --git a/panda/src/recorder/CMakeLists.txt b/panda/src/recorder/CMakeLists.txt new file mode 100644 index 0000000000..b65627db79 --- /dev/null +++ b/panda/src/recorder/CMakeLists.txt @@ -0,0 +1,34 @@ +set(P3RECORDER_HEADERS + config_recorder.h + mouseRecorder.h + recorderBase.h recorderBase.I + recorderController.h recorderController.I + recorderFrame.h recorderFrame.I + recorderHeader.h recorderHeader.I + recorderTable.h recorderTable.I + socketStreamRecorder.h socketStreamRecorder.I +) + +set(P3RECORDER_SOURCES + config_recorder.cxx + mouseRecorder.cxx + recorderBase.cxx recorderController.cxx + recorderFrame.cxx recorderHeader.cxx recorderTable.cxx + socketStreamRecorder.cxx +) + +composite_sources(p3recorder P3RECORDER_SOURCES) +add_component_library(p3recorder NOINIT SYMBOL BUILDING_PANDA_RECORDER + ${P3RECORDER_HEADERS} ${P3RECORDER_SOURCES}) +target_link_libraries(p3recorder p3dgraph pandaexpress) +target_interrogate(p3recorder ALL) + +if(NOT BUILD_METALIBS) + install(TARGETS p3recorder + EXPORT Core COMPONENT Core + DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d + ARCHIVE COMPONENT CoreDevel) +endif() +install(FILES ${P3RECORDER_HEADERS} COMPONENT CoreDevel DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d) diff --git a/panda/src/speedtree/speedTreeNode.cxx b/panda/src/speedtree/speedTreeNode.cxx index b00af199bb..eed5399fc4 100644 --- a/panda/src/speedtree/speedTreeNode.cxx +++ b/panda/src/speedtree/speedTreeNode.cxx @@ -108,7 +108,7 @@ SpeedTreeNode(const string &name) : _os_shaders_dir = shaders_dir.to_os_specific(); // Ensure the path ends with a terminal slash; SpeedTree requires this. -#if defined(WIN32) || defined(WIN64) +#ifdef _WIN32 if (!_os_shaders_dir.empty() && _os_shaders_dir[_os_shaders_dir.length() - 1] != '\\') { _os_shaders_dir += "\\"; } @@ -1560,7 +1560,7 @@ setup_for_render(GraphicsStateGuardian *gsg) { os_textures_dir = speedtree_textures_dir.get_value().to_os_specific(); // Ensure the path ends with a terminal slash; SpeedTree requires // this. -#if defined(WIN32) || defined(WIN64) +#ifdef _WIN32 if (!os_textures_dir.empty() && os_textures_dir[os_textures_dir.length() - 1] != '\\') { os_textures_dir += "\\"; } diff --git a/panda/src/testbed/CMakeLists.txt b/panda/src/testbed/CMakeLists.txt new file mode 100644 index 0000000000..3c497f42ac --- /dev/null +++ b/panda/src/testbed/CMakeLists.txt @@ -0,0 +1,9 @@ +if(NOT BUILD_PANDATOOL) + # It's safe to say, if the user doesn't want pandatool, they don't want pview + # either. + return() +endif() + +add_executable(pview pview.cxx) +target_link_libraries(pview p3framework) +install(TARGETS pview EXPORT Tools COMPONENT Tools DESTINATION ${CMAKE_INSTALL_BINDIR}) diff --git a/panda/src/text/CMakeLists.txt b/panda/src/text/CMakeLists.txt new file mode 100644 index 0000000000..b7cbaee022 --- /dev/null +++ b/panda/src/text/CMakeLists.txt @@ -0,0 +1,58 @@ +set(P3TEXT_HEADERS + config_text.h + default_font.h + dynamicTextFont.I dynamicTextFont.h + dynamicTextGlyph.I dynamicTextGlyph.h + dynamicTextPage.I dynamicTextPage.h + fontPool.I fontPool.h + geomTextGlyph.I geomTextGlyph.h + staticTextFont.I staticTextFont.h + textAssembler.I textAssembler.h + textFont.I textFont.h + textGlyph.I textGlyph.h + textGraphic.I textGraphic.h + textNode.I textNode.h + textProperties.I textProperties.h + textPropertiesManager.I textPropertiesManager.h +) + +set(P3TEXT_SOURCES + config_text.cxx + default_font.cxx + dynamicTextFont.cxx + dynamicTextGlyph.cxx + dynamicTextPage.cxx + fontPool.cxx + geomTextGlyph.cxx + staticTextFont.cxx + textAssembler.cxx + textFont.cxx textGlyph.cxx + textGraphic.cxx + textNode.cxx + textProperties.cxx + textPropertiesManager.cxx +) + +composite_sources(p3text P3TEXT_SOURCES) +add_component_library(p3text SYMBOL BUILDING_PANDA_TEXT + ${P3TEXT_HEADERS} ${P3TEXT_SOURCES}) +target_link_libraries(p3text p3parametrics + PKG::HARFBUZZ) +if(HAVE_FREETYPE) + target_link_libraries(p3text p3pnmtext) +endif() +target_interrogate(p3text ALL) + +if(HAVE_HARFBUZZ) + target_compile_definitions(p3text PRIVATE HAVE_HARFBUZZ) +endif() + +if(NOT BUILD_METALIBS) + install(TARGETS p3text + EXPORT Core COMPONENT Core + DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d + ARCHIVE COMPONENT CoreDevel) +endif() +install(FILES ${P3TEXT_HEADERS} COMPONENT CoreDevel DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d) diff --git a/panda/src/tform/CMakeLists.txt b/panda/src/tform/CMakeLists.txt new file mode 100644 index 0000000000..c8da2e176c --- /dev/null +++ b/panda/src/tform/CMakeLists.txt @@ -0,0 +1,45 @@ +set(P3TFORM_HEADERS + buttonThrower.I buttonThrower.h + config_tform.h + driveInterface.I driveInterface.h + mouseInterfaceNode.I mouseInterfaceNode.h + mouseSubregion.I mouseSubregion.h + mouseWatcher.h mouseWatcher.I + mouseWatcherBase.h mouseWatcherBase.I + mouseWatcherGroup.h + mouseWatcherParameter.I mouseWatcherParameter.h + mouseWatcherRegion.I mouseWatcherRegion.h + trackball.h + transform2sg.h +) + +set(P3TFORM_SOURCES + buttonThrower.cxx + config_tform.cxx + driveInterface.cxx + mouseInterfaceNode.cxx + mouseSubregion.cxx + mouseWatcher.cxx + mouseWatcherBase.cxx + mouseWatcherGroup.cxx + mouseWatcherParameter.cxx + mouseWatcherRegion.cxx + trackball.cxx + transform2sg.cxx +) + +composite_sources(p3tform P3TFORM_SOURCES) +add_component_library(p3tform NOINIT SYMBOL BUILDING_PANDA_TFORM + ${P3TFORM_HEADERS} ${P3TFORM_SOURCES}) +target_link_libraries(p3tform p3device p3grutil) +target_interrogate(p3tform ALL) + +if(NOT BUILD_METALIBS) + install(TARGETS p3tform + EXPORT Core COMPONENT Core + DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d + ARCHIVE COMPONENT CoreDevel) +endif() +install(FILES ${P3TFORM_HEADERS} COMPONENT CoreDevel DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d) diff --git a/panda/src/tinydisplay/config_tinydisplay.cxx b/panda/src/tinydisplay/config_tinydisplay.cxx index 9b69b9bd00..b843f2e85d 100644 --- a/panda/src/tinydisplay/config_tinydisplay.cxx +++ b/panda/src/tinydisplay/config_tinydisplay.cxx @@ -87,7 +87,7 @@ init_libtinydisplay() { ps->set_system_tag("TinyPanda", "native_window_system", "X11"); #endif -#ifdef WIN32 +#ifdef _WIN32 TinyWinGraphicsPipe::init_type(); TinyWinGraphicsWindow::init_type(); selection->add_pipe_type(TinyWinGraphicsPipe::get_class_type(), @@ -116,7 +116,7 @@ init_libtinydisplay() { int get_pipe_type_p3tinydisplay() { -#ifdef WIN32 +#ifdef _WIN32 return TinyWinGraphicsPipe::get_class_type().get_index(); #endif diff --git a/panda/src/tinydisplay/tinyWinGraphicsPipe.cxx b/panda/src/tinydisplay/tinyWinGraphicsPipe.cxx index adc51e6c9f..1347d406aa 100644 --- a/panda/src/tinydisplay/tinyWinGraphicsPipe.cxx +++ b/panda/src/tinydisplay/tinyWinGraphicsPipe.cxx @@ -13,7 +13,7 @@ #include "pandabase.h" -#ifdef WIN32 +#ifdef _WIN32 #include "tinyWinGraphicsPipe.h" #include "config_tinydisplay.h" diff --git a/panda/src/tinydisplay/tinyWinGraphicsPipe.h b/panda/src/tinydisplay/tinyWinGraphicsPipe.h index 8626a9d675..72d6e875a5 100644 --- a/panda/src/tinydisplay/tinyWinGraphicsPipe.h +++ b/panda/src/tinydisplay/tinyWinGraphicsPipe.h @@ -16,7 +16,7 @@ #include "pandabase.h" -#ifdef WIN32 +#ifdef _WIN32 #include "winGraphicsPipe.h" #include "tinyGraphicsStateGuardian.h" diff --git a/panda/src/tinydisplay/tinyWinGraphicsWindow.cxx b/panda/src/tinydisplay/tinyWinGraphicsWindow.cxx index ac16d45bf2..9f39a20723 100644 --- a/panda/src/tinydisplay/tinyWinGraphicsWindow.cxx +++ b/panda/src/tinydisplay/tinyWinGraphicsWindow.cxx @@ -13,7 +13,7 @@ #include "pandabase.h" -#ifdef WIN32 +#ifdef _WIN32 #include "tinyWinGraphicsWindow.h" #include "config_tinydisplay.h" diff --git a/panda/src/tinydisplay/tinyWinGraphicsWindow.h b/panda/src/tinydisplay/tinyWinGraphicsWindow.h index ecc1365a0b..b234001540 100644 --- a/panda/src/tinydisplay/tinyWinGraphicsWindow.h +++ b/panda/src/tinydisplay/tinyWinGraphicsWindow.h @@ -16,7 +16,7 @@ #include "pandabase.h" -#ifdef WIN32 +#ifdef _WIN32 #include "winGraphicsWindow.h" #include "tinyWinGraphicsPipe.h" diff --git a/panda/src/tinydisplay/zfeatures.h b/panda/src/tinydisplay/zfeatures.h index 73a61d95c5..aab61bfa34 100644 --- a/panda/src/tinydisplay/zfeatures.h +++ b/panda/src/tinydisplay/zfeatures.h @@ -7,7 +7,7 @@ #define BIG_ENDIAN 4321 #if (defined(__i386__) || defined(__i386)) || \ - defined(__ia64__) || defined(WIN32) || \ + defined(__ia64__) || defined(_WIN32) || \ (defined(__alpha__) || defined(__alpha)) || \ defined(__arm__) || \ (defined(__mips__) && defined(__MIPSEL__)) || \ diff --git a/panda/src/vision/CMakeLists.txt b/panda/src/vision/CMakeLists.txt new file mode 100644 index 0000000000..284e764807 --- /dev/null +++ b/panda/src/vision/CMakeLists.txt @@ -0,0 +1,54 @@ +if(NOT HAVE_OPENCV AND NOT HAVE_ARTOOLKIT) + return() +endif() + +set(P3VISION_HEADERS + arToolKit.h arToolKit.I + config_vision.h + openCVTexture.h openCVTexture.I + webcamVideoCursorOpenCV.h + webcamVideoCursorV4L.h + webcamVideo.h webcamVideo.I + webcamVideoOpenCV.h + webcamVideoV4L.h +) + +set(P3VISION_SOURCES + arToolKit.cxx + config_vision.cxx + openCVTexture.cxx + webcamVideoCursorOpenCV.cxx + webcamVideoCursorV4L.cxx + webcamVideo.cxx + webcamVideoDS.cxx + webcamVideoOpenCV.cxx + webcamVideoV4L.cxx +) + +composite_sources(p3vision P3VISION_SOURCES) +add_library(p3vision ${P3VISION_HEADERS} ${P3VISION_SOURCES}) +set_target_properties(p3vision PROPERTIES DEFINE_SYMBOL BUILDING_VISION) +target_link_libraries(p3vision panda + PKG::OPENCV PKG::ARTOOLKIT) +set_target_properties(p3vision PROPERTIES CXX_EXCEPTIONS ON) +target_interrogate(p3vision ALL) + +if(OPENCV_VER_3) + set_target_properties(p3vision PROPERTIES COMPILE_DEFINITIONS "OPENCV_VER_3") +elseif(OPENCV_VER_23) + set_target_properties(p3vision PROPERTIES COMPILE_DEFINITIONS "OPENCV_VER_23") +endif() + +if(HAVE_FFMPEG) + target_compile_definitions(p3vision PRIVATE HAVE_FFMPEG) +endif() + +install(TARGETS p3vision + EXPORT Vision COMPONENT Vision + DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d + ARCHIVE COMPONENT VisionDevel) +install(FILES ${P3VISION_HEADERS} COMPONENT VisionDevel DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d) + +export_targets(Vision COMPONENT VisionDevel) diff --git a/panda/src/vrpn/CMakeLists.txt b/panda/src/vrpn/CMakeLists.txt new file mode 100644 index 0000000000..11e5a5fc61 --- /dev/null +++ b/panda/src/vrpn/CMakeLists.txt @@ -0,0 +1,48 @@ +if(NOT HAVE_VRPN) + return() +endif() + +set(P3VRPN_HEADERS + config_vrpn.h + vrpnAnalogDevice.h vrpnAnalogDevice.I + vrpnAnalog.h vrpnAnalog.I + vrpnButtonDevice.h vrpnButtonDevice.I + vrpnButton.h vrpnButton.I + vrpnClient.h vrpnClient.I + vrpnDialDevice.h vrpnDialDevice.I + vrpnDial.h vrpnDial.I + vrpn_interface.h + vrpnTrackerDevice.h vrpnTrackerDevice.I + vrpnTracker.h vrpnTracker.I +) + +set(P3VRPN_SOURCES + config_vrpn.cxx + vrpnAnalog.cxx + vrpnAnalogDevice.cxx + vrpnButton.cxx + vrpnButtonDevice.cxx + vrpnClient.cxx + vrpnDial.cxx + vrpnDialDevice.cxx + vrpnTracker.cxx + vrpnTrackerDevice.cxx +) + +composite_sources(p3vrpn P3VRPN_SOURCES) +add_library(p3vrpn ${P3VRPN_HEADERS} ${P3VRPN_SOURCES}) +set_target_properties(p3vrpn PROPERTIES DEFINE_SYMBOL BUILDING_VRPN) +target_link_libraries(p3vrpn panda PKG::VRPN) +target_interrogate(p3vrpn ALL) + +set_target_properties(p3vrpn PROPERTIES CXX_EXCEPTIONS ON) + +install(TARGETS p3vrpn + EXPORT VRPN COMPONENT VRPN + DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d + ARCHIVE COMPONENT VRPNDevel) +install(FILES ${P3VRPN_HEADERS} COMPONENT VRPNDevel DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d) + +export_targets(VRPN COMPONENT VRPNDevel) diff --git a/panda/src/vrpn/vrpnAnalog.I b/panda/src/vrpn/vrpnAnalog.I index afd951e417..234e6b4616 100644 --- a/panda/src/vrpn/vrpnAnalog.I +++ b/panda/src/vrpn/vrpnAnalog.I @@ -28,12 +28,3 @@ INLINE bool VrpnAnalog:: is_empty() const { return _devices.empty(); } - -/** - * Polls the connected device. Normally you should not call this directly; - * this will be called by the VrpnClient. - */ -INLINE void VrpnAnalog:: -poll() { - _analog->mainloop(); -} diff --git a/panda/src/vrpn/vrpnAnalog.cxx b/panda/src/vrpn/vrpnAnalog.cxx index 2745aab75e..b0b81c8867 100644 --- a/panda/src/vrpn/vrpnAnalog.cxx +++ b/panda/src/vrpn/vrpnAnalog.cxx @@ -70,6 +70,15 @@ unmark(VrpnAnalogDevice *device) { } } +/** + * Polls the connected device. Normally you should not call this directly; + * this will be called by the VrpnClient. + */ +void VrpnAnalog:: +poll() { + _analog->mainloop(); +} + /** * */ diff --git a/panda/src/vrpn/vrpnAnalog.h b/panda/src/vrpn/vrpnAnalog.h index 07f3c84b21..34bc51f277 100644 --- a/panda/src/vrpn/vrpnAnalog.h +++ b/panda/src/vrpn/vrpnAnalog.h @@ -46,7 +46,7 @@ public: void mark(VrpnAnalogDevice *device); void unmark(VrpnAnalogDevice *device); - INLINE void poll(); + void poll(); void output(std::ostream &out) const; void write(std::ostream &out, int indent_level = 0) const; diff --git a/panda/src/vrpn/vrpnButton.I b/panda/src/vrpn/vrpnButton.I index ed10b89fae..e083d0325b 100644 --- a/panda/src/vrpn/vrpnButton.I +++ b/panda/src/vrpn/vrpnButton.I @@ -28,12 +28,3 @@ INLINE bool VrpnButton:: is_empty() const { return _devices.empty(); } - -/** - * Polls the connected device. Normally you should not call this directly; - * this will be called by the VrpnClient. - */ -INLINE void VrpnButton:: -poll() { - _button->mainloop(); -} diff --git a/panda/src/vrpn/vrpnButton.cxx b/panda/src/vrpn/vrpnButton.cxx index 3312afa31d..eefbcf1015 100644 --- a/panda/src/vrpn/vrpnButton.cxx +++ b/panda/src/vrpn/vrpnButton.cxx @@ -70,6 +70,15 @@ unmark(VrpnButtonDevice *device) { } } +/** + * Polls the connected device. Normally you should not call this directly; + * this will be called by the VrpnClient. + */ +void VrpnButton:: +poll() { + _button->mainloop(); +} + /** * */ diff --git a/panda/src/vrpn/vrpnButton.h b/panda/src/vrpn/vrpnButton.h index 1b9fc14cf4..3b151b5130 100644 --- a/panda/src/vrpn/vrpnButton.h +++ b/panda/src/vrpn/vrpnButton.h @@ -45,7 +45,7 @@ public: void mark(VrpnButtonDevice *device); void unmark(VrpnButtonDevice *device); - INLINE void poll(); + void poll(); void output(std::ostream &out) const; void write(std::ostream &out, int indent_level = 0) const; diff --git a/panda/src/vrpn/vrpnClient.I b/panda/src/vrpn/vrpnClient.I index 486a4e29f6..908c77a0c9 100644 --- a/panda/src/vrpn/vrpnClient.I +++ b/panda/src/vrpn/vrpnClient.I @@ -19,25 +19,6 @@ get_server_name() const { return _server_name; } -/** - * Returns true if everything seems to be kosher with the server (even if - * there is no connection), or false otherwise. - */ -INLINE bool VrpnClient:: -is_valid() const { - return (_connection->doing_okay() != 0); -} - -/** - * Returns true if the connection is established successfully, false - * otherwise. - */ -INLINE bool VrpnClient:: -is_connected() const { - return (_connection->connected() != 0); -} - - /** * Little inline function to convert a struct timeval to only seconds */ diff --git a/panda/src/vrpn/vrpnClient.cxx b/panda/src/vrpn/vrpnClient.cxx index 1fb7fcb4ff..9bf4ea2795 100644 --- a/panda/src/vrpn/vrpnClient.cxx +++ b/panda/src/vrpn/vrpnClient.cxx @@ -60,6 +60,24 @@ VrpnClient:: delete _connection; } +/** + * Returns true if everything seems to be kosher with the server (even if + * there is no connection), or false otherwise. + */ +bool VrpnClient:: +is_valid() const { + return (_connection->doing_okay() != 0); +} + +/** + * Returns true if the connection is established successfully, false + * otherwise. + */ +bool VrpnClient:: +is_connected() const { + return (_connection->connected() != 0); +} + /** * Writes a list of the active devices that the VrpnClient is currently * polling each frame. diff --git a/panda/src/vrpn/vrpnClient.h b/panda/src/vrpn/vrpnClient.h index 127492d9cf..979351eac9 100644 --- a/panda/src/vrpn/vrpnClient.h +++ b/panda/src/vrpn/vrpnClient.h @@ -38,8 +38,8 @@ PUBLISHED: ~VrpnClient(); INLINE const std::string &get_server_name() const; - INLINE bool is_valid() const; - INLINE bool is_connected() const; + bool is_valid() const; + bool is_connected() const; void write(std::ostream &out, int indent_level = 0) const; diff --git a/panda/src/vrpn/vrpnDial.I b/panda/src/vrpn/vrpnDial.I index 2cb9981826..3813aa02be 100644 --- a/panda/src/vrpn/vrpnDial.I +++ b/panda/src/vrpn/vrpnDial.I @@ -27,12 +27,3 @@ INLINE bool VrpnDial:: is_empty() const { return _devices.empty(); } - -/** - * Polls the connected device. Normally you should not call this directly; - * this will be called by the VrpnClient. - */ -INLINE void VrpnDial:: -poll() { - _dial->mainloop(); -} diff --git a/panda/src/vrpn/vrpnDial.cxx b/panda/src/vrpn/vrpnDial.cxx index 62b1fe73df..04f19762df 100644 --- a/panda/src/vrpn/vrpnDial.cxx +++ b/panda/src/vrpn/vrpnDial.cxx @@ -70,6 +70,15 @@ unmark(VrpnDialDevice *device) { } } +/** + * Polls the connected device. Normally you should not call this directly; + * this will be called by the VrpnClient. + */ +void VrpnDial:: +poll() { + _dial->mainloop(); +} + /** * */ diff --git a/panda/src/vrpn/vrpnDial.h b/panda/src/vrpn/vrpnDial.h index e98fd7d99d..e7be9c8aa1 100644 --- a/panda/src/vrpn/vrpnDial.h +++ b/panda/src/vrpn/vrpnDial.h @@ -45,7 +45,7 @@ public: void mark(VrpnDialDevice *device); void unmark(VrpnDialDevice *device); - INLINE void poll(); + void poll(); void output(std::ostream &out) const; void write(std::ostream &out, int indent_level = 0) const; diff --git a/panda/src/vrpn/vrpnTracker.I b/panda/src/vrpn/vrpnTracker.I index b651121923..89c91084b5 100644 --- a/panda/src/vrpn/vrpnTracker.I +++ b/panda/src/vrpn/vrpnTracker.I @@ -28,12 +28,3 @@ INLINE bool VrpnTracker:: is_empty() const { return _devices.empty(); } - -/** - * Polls the connected device. Normally you should not call this directly; - * this will be called by the VrpnClient. - */ -INLINE void VrpnTracker:: -poll() { - _tracker->mainloop(); -} diff --git a/panda/src/vrpn/vrpnTracker.cxx b/panda/src/vrpn/vrpnTracker.cxx index e1b08e2a72..046eaf1d69 100644 --- a/panda/src/vrpn/vrpnTracker.cxx +++ b/panda/src/vrpn/vrpnTracker.cxx @@ -72,6 +72,15 @@ unmark(VrpnTrackerDevice *device) { } } +/** + * Polls the connected device. Normally you should not call this directly; + * this will be called by the VrpnClient. + */ +void VrpnTracker:: +poll() { + _tracker->mainloop(); +} + /** * */ diff --git a/panda/src/vrpn/vrpnTracker.h b/panda/src/vrpn/vrpnTracker.h index 1b6c30347d..bb6651cff7 100644 --- a/panda/src/vrpn/vrpnTracker.h +++ b/panda/src/vrpn/vrpnTracker.h @@ -45,7 +45,7 @@ public: void mark(VrpnTrackerDevice *device); void unmark(VrpnTrackerDevice *device); - INLINE void poll(); + void poll(); void output(std::ostream &out) const; void write(std::ostream &out, int indent_level = 0) const; diff --git a/panda/src/wgldisplay/CMakeLists.txt b/panda/src/wgldisplay/CMakeLists.txt new file mode 100644 index 0000000000..77c5e75db5 --- /dev/null +++ b/panda/src/wgldisplay/CMakeLists.txt @@ -0,0 +1,35 @@ +if(NOT HAVE_WGL) + return() +endif() + +set(P3WGLDISPLAY_HEADERS + config_wgldisplay.h + wglGraphicsBuffer.I wglGraphicsBuffer.h + wglGraphicsPipe.I wglGraphicsPipe.h + wglGraphicsStateGuardian.I wglGraphicsStateGuardian.h + wglGraphicsWindow.I wglGraphicsWindow.h + wglext.h +) + +set(P3WGLDISPLAY_SOURCES + config_wgldisplay.cxx + wglGraphicsBuffer.cxx + wglGraphicsPipe.cxx + wglGraphicsStateGuardian.cxx + wglGraphicsWindow.cxx +) + +composite_sources(p3wgldisplay P3WGLDISPLAY_SOURCES) +add_component_library(p3wgldisplay SYMBOL BUILDING_PANDA_WGLDISPLAY + ${P3WGLDISPLAY_HEADERS} ${P3WGLDISPLAY_SOURCES}) +target_link_libraries(p3wgldisplay p3glgsg p3windisplay) + +if(NOT BUILD_METALIBS) + install(TARGETS p3wgldisplay + EXPORT OpenGL COMPONENT OpenGL + DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d + ARCHIVE COMPONENT OpenGLDevel) +endif() +install(FILES ${P3WGLDISPLAY_HEADERS} COMPONENT OpenGLDevel DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d) diff --git a/panda/src/windisplay/CMakeLists.txt b/panda/src/windisplay/CMakeLists.txt new file mode 100644 index 0000000000..a966134957 --- /dev/null +++ b/panda/src/windisplay/CMakeLists.txt @@ -0,0 +1,33 @@ +if(NOT WIN32) + return() +endif() + +set(P3WINDISPLAY_HEADERS + config_windisplay.h + winGraphicsPipe.I winGraphicsPipe.h + winGraphicsWindow.I winGraphicsWindow.h + winDetectDx.h +) + +set(P3WINDISPLAY_SOURCES + config_windisplay.cxx winGraphicsPipe.cxx + winGraphicsWindow.cxx + winDetectDx9.cxx +) + +composite_sources(p3windisplay P3WINDISPLAY_SOURCES) +add_component_library(p3windisplay SYMBOL BUILDING_PANDAWIN + ${P3WINDISPLAY_HEADERS} ${P3WINDISPLAY_SOURCES}) +target_link_libraries(p3windisplay panda user32.lib imm32.lib) + +if(HAVE_DX9) + target_compile_definitions(p3windisplay PRIVATE HAVE_DX9) +endif() + +if(NOT BUILD_METALIBS) + install(TARGETS p3windisplay + EXPORT Core COMPONENT Core + DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + ARCHIVE COMPONENT CoreDevel) +endif() diff --git a/panda/src/x11display/CMakeLists.txt b/panda/src/x11display/CMakeLists.txt new file mode 100644 index 0000000000..d3a3ebbe12 --- /dev/null +++ b/panda/src/x11display/CMakeLists.txt @@ -0,0 +1,21 @@ +if(NOT HAVE_X11) + return() +endif() + +set(P3X11DISPLAY_HEADERS + config_x11display.h x11GraphicsPipe.I x11GraphicsPipe.h + x11GraphicsWindow.h x11GraphicsWindow.I +) + +set(P3X11DISPLAY_SOURCES + config_x11display.cxx x11GraphicsPipe.cxx x11GraphicsWindow.cxx +) + +composite_sources(p3x11display P3X11DISPLAY_SOURCES) +add_component_library(p3x11display SYMBOL BUILDING_PANDAX11 + ${P3X11DISPLAY_HEADERS} ${P3X11DISPLAY_SOURCES}) +target_link_libraries(p3x11display panda PKG::X11) + +if(NOT BUILD_METALIBS) + install(TARGETS p3x11display EXPORT Core COMPONENT Core DESTINATION ${CMAKE_INSTALL_LIBDIR}) +endif() diff --git a/panda/src/x11display/x11GraphicsPipe.I b/panda/src/x11display/x11GraphicsPipe.I index a516b2e6a2..3f608bad5b 100644 --- a/panda/src/x11display/x11GraphicsPipe.I +++ b/panda/src/x11display/x11GraphicsPipe.I @@ -58,18 +58,18 @@ get_hidden_cursor() { } /** - * Returns true if relative mouse mode is supported on this display. + * Returns true if a form of relative mouse mode is supported on this display. */ INLINE bool x11GraphicsPipe:: supports_relative_mouse() const { - return (_XF86DGADirectVideo != nullptr); + return (_XF86DGADirectVideo != nullptr) || (_XISelectEvents != nullptr); } /** * Enables relative mouse mode for this display. Returns false if unsupported. */ INLINE bool x11GraphicsPipe:: -enable_relative_mouse() { +enable_dga_mouse() { if (_XF86DGADirectVideo != nullptr) { x11display_cat.info() << "Enabling relative mouse using XF86DGA extension\n"; _XF86DGADirectVideo(_display, _screen, XF86DGADirectMouse); @@ -82,7 +82,7 @@ enable_relative_mouse() { * Disables relative mouse mode for this display. */ INLINE void x11GraphicsPipe:: -disable_relative_mouse() { +disable_dga_mouse() { if (_XF86DGADirectVideo != nullptr) { x11display_cat.info() << "Disabling relative mouse using XF86DGA extension\n"; _XF86DGADirectVideo(_display, _screen, 0); diff --git a/panda/src/x11display/x11GraphicsPipe.cxx b/panda/src/x11display/x11GraphicsPipe.cxx index 8f87b57609..e2f3da7d9d 100644 --- a/panda/src/x11display/x11GraphicsPipe.cxx +++ b/panda/src/x11display/x11GraphicsPipe.cxx @@ -107,7 +107,7 @@ x11GraphicsPipe(const std::string &display) : int major_ver, minor_ver; if (_XF86DGAQueryVersion == nullptr || _XF86DGADirectVideo == nullptr) { x11display_cat.warning() - << "libXxf86dga.so.1 does not provide required functions; relative mouse mode will not work.\n"; + << "libXxf86dga.so.1 does not provide required functions; relative mouse mode may not work.\n"; } else if (!_XF86DGAQueryVersion(_display, &major_ver, &minor_ver)) { _XF86DGADirectVideo = nullptr; @@ -116,7 +116,7 @@ x11GraphicsPipe(const std::string &display) : _XF86DGADirectVideo = nullptr; if (x11display_cat.is_debug()) { x11display_cat.debug() - << "cannot dlopen libXxf86dga.so.1; cursor changing will not work.\n"; + << "cannot dlopen libXxf86dga.so.1; relative mouse mode may not work.\n"; } } @@ -214,6 +214,44 @@ x11GraphicsPipe(const std::string &display) : } } + // Dynamically load the XInput2 extension. + int ev, err; + if (XQueryExtension(_display, "XInputExtension", &_xi_opcode, &ev, &err)) { + void *xi = dlopen("libXi.so.6", RTLD_NOW | RTLD_LOCAL); + if (xi != nullptr) { + pfn_XIQueryVersion _XIQueryVersion = (pfn_XIQueryVersion)dlsym(xi, "XIQueryVersion"); + _XISelectEvents = (pfn_XISelectEvents)dlsym(xi, "XISelectEvents"); + + int major_ver = 2, minor_ver = 0; + if (_XIQueryVersion == nullptr || _XISelectEvents == nullptr) { + x11display_cat.warning() + << "libXi.so.6 does not provide required functions; relative mouse mode will not work.\n"; + _XISelectEvents = nullptr; + dlclose(xi); + + } else if (_XIQueryVersion(_display, &major_ver, &minor_ver) == Success) { + if (x11display_cat.is_debug()) { + x11display_cat.debug() + << "Found XInput extension " << major_ver << "." << minor_ver << "\n"; + } + + } else { + if (x11display_cat.is_debug()) { + x11display_cat.debug() + << "XInput2 extension not supported; relative mouse mode will not work.\n"; + } + _XISelectEvents = nullptr; + dlclose(xi); + } + } else { + _XISelectEvents = nullptr; + if (x11display_cat.is_debug()) { + x11display_cat.debug() + << "cannot dlopen libXi.so.1; relative mouse mode will not work.\n"; + } + } + } + // Use Xrandr to fill in the supported resolution list. if (_have_xrandr) { // If we have XRRGetScreenResources, we prefer that. It seems to be more @@ -324,6 +362,59 @@ x11GraphicsPipe:: } } +/** + * Enables raw mouse mode for this display. Returns false if unsupported. + */ +INLINE bool x11GraphicsPipe:: +enable_raw_mouse() { + if (_num_raw_mouse_windows > 0) { + // Already enabled by another window. + ++_num_raw_mouse_windows; + return true; + } + if (_XISelectEvents != nullptr) { + XIEventMask event_mask; + unsigned char mask[XIMaskLen(XI_RawMotion)] = {0}; + + event_mask.deviceid = XIAllMasterDevices; + event_mask.mask_len = sizeof(mask); + event_mask.mask = mask; + XISetMask(mask, XI_RawMotion); + + if (_XISelectEvents(_display, _root, &event_mask, 1) == Success) { + if (x11display_cat.info()) { + x11display_cat.info() + << "Enabled raw mouse events using XInput2 extension\n"; + } + ++_num_raw_mouse_windows; + return true; + } + } + return false; +} + +/** + * Disables raw mouse mode for this display. + */ +void x11GraphicsPipe:: +disable_raw_mouse() { + if (--_num_raw_mouse_windows == 0) { + if (x11display_cat.is_debug()) { + x11display_cat.debug() + << "Disabling raw mouse events using XInput2 extension\n"; + } + + XIEventMask event_mask; + unsigned char mask[] = {0}; + + event_mask.deviceid = XIAllMasterDevices; + event_mask.mask_len = sizeof(mask); + event_mask.mask = mask; + + _XISelectEvents(_display, _root, &event_mask, 1); + } +} + /** * Returns an XRRScreenResources object, or null if RandR 1.2 is not supported. */ diff --git a/panda/src/x11display/x11GraphicsPipe.h b/panda/src/x11display/x11GraphicsPipe.h index e1abf80b00..260ec941d6 100644 --- a/panda/src/x11display/x11GraphicsPipe.h +++ b/panda/src/x11display/x11GraphicsPipe.h @@ -87,6 +87,45 @@ typedef struct _XRRCrtcInfo { typedef void (*pfn_XRRFreeScreenResources)(XRRScreenResources *resources); typedef void (*pfn_XRRFreeCrtcInfo)(XRRCrtcInfo *crtcInfo); +typedef struct { + int deviceid; + int mask_len; + unsigned char *mask; +} XIEventMask; + +typedef struct { + int mask_len; + unsigned char *mask; + double *values; +} XIValuatorState; + +typedef struct { + int type; + unsigned long serial; + Bool send_event; + X11_Display *display; + int extension; + int evtype; + Time time; + int deviceid; + int sourceid; + int detail; + int flags; + XIValuatorState valuators; + double *raw_values; +} XIRawEvent; + +#define XI_RawMotion 17 +#define XI_RawMotionMask (1 << XI_RawMotion) + +#define XISetMask(ptr, event) (((unsigned char*)(ptr))[(event)>>3] |= (1 << ((event) & 7))) +#define XIClearMask(ptr, event) (((unsigned char*)(ptr))[(event)>>3] &= ~(1 << ((event) & 7))) +#define XIMaskIsSet(ptr, event) (((unsigned char*)(ptr))[(event)>>3] & (1 << ((event) & 7))) +#define XIMaskLen(event) (((event) >> 3) + 1) + +#define XIAllDevices 0 +#define XIAllMasterDevices 1 + class FrameBufferProperties; /** @@ -106,8 +145,10 @@ public: INLINE X11_Cursor get_hidden_cursor(); INLINE bool supports_relative_mouse() const; - INLINE bool enable_relative_mouse(); - INLINE void disable_relative_mouse(); + INLINE bool enable_dga_mouse(); + INLINE void disable_dga_mouse(); + INLINE bool enable_raw_mouse(); + INLINE void disable_raw_mouse(); static INLINE int disable_x_error_messages(); static INLINE int enable_x_error_messages(); @@ -170,6 +211,8 @@ public: pfn_XRRConfigCurrentConfiguration _XRRConfigCurrentConfiguration; pfn_XRRSetScreenConfig _XRRSetScreenConfig; + int _xi_opcode; + protected: X11_Display *_display; int _screen; @@ -190,6 +233,11 @@ protected: pfn_XRRGetCrtcInfo _XRRGetCrtcInfo; pfn_XRRFreeCrtcInfo _XRRFreeCrtcInfo; + typedef Status (*pfn_XIQueryVersion)(X11_Display *, int*, int*); + typedef Status (*pfn_XISelectEvents)(X11_Display *, X11_Window, XIEventMask *, int); + pfn_XISelectEvents _XISelectEvents = nullptr; + int _num_raw_mouse_windows = 0; + private: void make_hidden_cursor(); void release_hidden_cursor(); diff --git a/panda/src/x11display/x11GraphicsWindow.cxx b/panda/src/x11display/x11GraphicsWindow.cxx index de58cd1028..c7d3455164 100644 --- a/panda/src/x11display/x11GraphicsWindow.cxx +++ b/panda/src/x11display/x11GraphicsWindow.cxx @@ -117,6 +117,7 @@ x11GraphicsWindow(GraphicsEngine *engine, GraphicsPipe *pipe, _awaiting_configure = false; _dga_mouse_enabled = false; + _raw_mouse_enabled = false; _override_redirect = False; _wm_delete_window = x11_pipe->_wm_delete_window; @@ -154,8 +155,8 @@ get_pointer(int device) const { // We recheck this immediately to get the most up-to-date value, but we // won't bother waiting for the lock if we can't. - if (device == 0 && !_dga_mouse_enabled && result._in_window && - x11GraphicsPipe::_x_mutex.try_lock()) { + if (device == 0 && !_dga_mouse_enabled && !_raw_mouse_enabled && + result._in_window && x11GraphicsPipe::_x_mutex.try_lock()) { XEvent event; if (_xwindow != None && XQueryPointer(_display, _xwindow, &event.xbutton.root, @@ -355,7 +356,7 @@ process_events() { case ButtonPress: // This refers to the mouse buttons. button = get_mouse_button(event.xbutton); - if (!_dga_mouse_enabled) { + if (_properties.get_mouse_mode() != WindowProperties::M_relative) { _input->set_pointer_in_window(event.xbutton.x, event.xbutton.y); } _input->button_down(button); @@ -363,18 +364,49 @@ process_events() { case ButtonRelease: button = get_mouse_button(event.xbutton); - if (!_dga_mouse_enabled) { + if (_properties.get_mouse_mode() != WindowProperties::M_relative) { _input->set_pointer_in_window(event.xbutton.x, event.xbutton.y); } _input->button_up(button); break; case MotionNotify: - if (_dga_mouse_enabled) { - PointerData md = _input->get_pointer(); - _input->set_pointer_in_window(md.get_x() + event.xmotion.x_root, md.get_y() + event.xmotion.y_root); - } else { - _input->set_pointer_in_window(event.xmotion.x, event.xmotion.y); + if (!_raw_mouse_enabled) { + if (_dga_mouse_enabled) { + PointerData md = _input->get_pointer(); + _input->set_pointer_in_window(md.get_x() + event.xmotion.x_root, md.get_y() + event.xmotion.y_root); + } else { + _input->set_pointer_in_window(event.xmotion.x, event.xmotion.y); + } + } + break; + + case GenericEvent: + if (_raw_mouse_enabled) { + XGenericEventCookie *cookie = &event.xcookie; + XGetEventData(_display, cookie); + + x11GraphicsPipe *x11_pipe; + DCAST_INTO_V(x11_pipe, _pipe); + + if (cookie->evtype == XI_RawMotion && + cookie->extension == x11_pipe->_xi_opcode) { + const XIRawEvent *raw_event = (const XIRawEvent *)cookie->data; + const double *values = raw_event->raw_values; + + double x = 0, y = 0; + if (XIMaskIsSet(raw_event->valuators.mask, 0)) { + x = values[0]; + } + if (XIMaskIsSet(raw_event->valuators.mask, 1)) { + y = values[1]; + } + + PointerData md = _input->get_pointer(); + _input->set_pointer_in_window(md.get_x() + x, md.get_y() + y); + } + + XFreeEventData(_display, cookie); } break; @@ -392,7 +424,7 @@ process_events() { break; case EnterNotify: - if (_dga_mouse_enabled) { + if (_properties.get_mouse_mode() == WindowProperties::M_relative) { PointerData md = _input->get_pointer(); _input->set_pointer_in_window(md.get_x(), md.get_y()); } else { @@ -508,9 +540,8 @@ process_events() { changed_properties = true; } - if (properties.has_foreground() && ( - _properties.get_mouse_mode() == WindowProperties::M_confined || - _dga_mouse_enabled)) { + if (properties.has_foreground() && + (_properties.get_mouse_mode() != WindowProperties::M_absolute)) { x11GraphicsPipe *x11_pipe; DCAST_INTO_V(x11_pipe, _pipe); @@ -525,13 +556,13 @@ process_events() { XGrabPointer(_display, _xwindow, True, 0, GrabModeAsync, GrabModeAsync, _xwindow, cursor, CurrentTime); if (_dga_mouse_enabled) { - x11_pipe->enable_relative_mouse(); + x11_pipe->enable_dga_mouse(); } } else { // window is leaving the foreground, ungrab the pointer if (_dga_mouse_enabled) { - x11_pipe->disable_relative_mouse(); + x11_pipe->disable_dga_mouse(); } else if (_properties.get_mouse_mode() == WindowProperties::M_confined) { XUngrabPointer(_display, CurrentTime); } @@ -850,9 +881,13 @@ set_properties_now(WindowProperties &properties) { case WindowProperties::M_absolute: XUngrabPointer(_display, CurrentTime); if (_dga_mouse_enabled) { - x11_pipe->disable_relative_mouse(); + x11_pipe->disable_dga_mouse(); _dga_mouse_enabled = false; } + if (_raw_mouse_enabled) { + x11_pipe->disable_raw_mouse(); + _raw_mouse_enabled = false; + } _properties.set_mouse_mode(WindowProperties::M_absolute); properties.clear_mouse_mode(); break; @@ -871,13 +906,16 @@ set_properties_now(WindowProperties &properties) { GrabModeAsync, _xwindow, cursor, CurrentTime) != GrabSuccess) { x11display_cat.error() << "Failed to grab pointer!\n"; } else { - x11_pipe->enable_relative_mouse(); + if (x11_pipe->enable_dga_mouse()) { + _dga_mouse_enabled = true; + } else { + _raw_mouse_enabled = _raw_mouse_enabled || x11_pipe->enable_raw_mouse(); + } _properties.set_mouse_mode(WindowProperties::M_relative); properties.clear_mouse_mode(); - _dga_mouse_enabled = true; - // Get the real mouse position, so we can addsubtract our relative + // Get the real mouse position, so we can add/subtract our relative // coordinates later. XEvent event; XQueryPointer(_display, _xwindow, &event.xbutton.root, @@ -885,10 +923,6 @@ set_properties_now(WindowProperties &properties) { &event.xbutton.x, &event.xbutton.y, &event.xbutton.state); _input->set_pointer_in_window(event.xbutton.x, event.xbutton.y); } - } else { - x11display_cat.warning() - << "XF86DGA extension not available, cannot enable relative mouse mode\n"; - _dga_mouse_enabled = false; } } break; @@ -899,9 +933,13 @@ set_properties_now(WindowProperties &properties) { DCAST_INTO_V(x11_pipe, _pipe); if (_dga_mouse_enabled) { - x11_pipe->disable_relative_mouse(); + x11_pipe->disable_dga_mouse(); _dga_mouse_enabled = false; } + if (_raw_mouse_enabled) { + x11_pipe->disable_raw_mouse(); + _raw_mouse_enabled = false; + } X11_Cursor cursor = None; if (_properties.get_cursor_hidden()) { cursor = x11_pipe->get_hidden_cursor(); @@ -1436,7 +1474,7 @@ open_raw_mice() { */ void x11GraphicsWindow:: handle_keystroke(XKeyEvent &event) { - if (!_dga_mouse_enabled) { + if (_properties.get_mouse_mode() != WindowProperties::M_relative) { _input->set_pointer_in_window(event.x, event.y); } @@ -1471,7 +1509,7 @@ handle_keystroke(XKeyEvent &event) { */ void x11GraphicsWindow:: handle_keypress(XKeyEvent &event) { - if (!_dga_mouse_enabled) { + if (_properties.get_mouse_mode() != WindowProperties::M_relative) { _input->set_pointer_in_window(event.x, event.y); } @@ -1506,7 +1544,7 @@ handle_keypress(XKeyEvent &event) { */ void x11GraphicsWindow:: handle_keyrelease(XKeyEvent &event) { - if (!_dga_mouse_enabled) { + if (_properties.get_mouse_mode() != WindowProperties::M_relative) { _input->set_pointer_in_window(event.x, event.y); } @@ -2000,6 +2038,13 @@ get_keyboard_map() const { LightReMutexHolder holder(x11GraphicsPipe::_x_mutex); for (int k = 9; k <= 135; ++k) { + if (k >= 78 && k <= 91) { + // Ignore numpad keys for now. These are not mapped to separate button + // handles in Panda, so we don't want their mappings to conflict with + // the regular numeric keys. + continue; + } + ButtonHandle raw_button = map_raw_button(k); if (raw_button == ButtonHandle::none()) { continue; @@ -2007,11 +2052,31 @@ get_keyboard_map() const { KeySym sym = XkbKeycodeToKeysym(_display, k, 0, 0); ButtonHandle button = map_button(sym); - if (button == ButtonHandle::none()) { + std::string label; + + // Compose a label for some keys; I have not yet been able to find an API + // that does this effectively. + if (sym >= XK_a && sym <= XK_z) { + label = toupper((char)sym); + } + else if (sym >= XK_F1 && sym <= XK_F35) { + label = "F" + format_string(sym - XK_F1 + 1); + } + else if (sym >= XK_exclamdown && sym <= XK_ydiaeresis) { + // A latin-1 symbol. Translate this to the label. + char buffer[255]; + int nbytes = XkbTranslateKeySym(_display, &sym, 0, buffer, 255, 0); + if (nbytes > 0) { + label.assign(buffer, nbytes); + } + } + + if (button == ButtonHandle::none() && label.empty()) { + // No label and no mapping; this is useless. continue; } - map->map_button(raw_button, button); + map->map_button(raw_button, button, label); } return map; @@ -2025,8 +2090,10 @@ Bool x11GraphicsWindow:: check_event(X11_Display *display, XEvent *event, char *arg) { const x11GraphicsWindow *self = (x11GraphicsWindow *)arg; - // We accept any event that is sent to our window. - return (event->xany.window == self->_xwindow); + // We accept any event that is sent to our window. However, we have to let + // raw mouse events through, since they're not associated with any window. + return (event->xany.window == self->_xwindow || + (event->type == GenericEvent && self->_raw_mouse_enabled)); } /** diff --git a/panda/src/x11display/x11GraphicsWindow.h b/panda/src/x11display/x11GraphicsWindow.h index f512b16a19..e3d4a86382 100644 --- a/panda/src/x11display/x11GraphicsWindow.h +++ b/panda/src/x11display/x11GraphicsWindow.h @@ -92,6 +92,7 @@ protected: long _event_mask; bool _awaiting_configure; bool _dga_mouse_enabled; + bool _raw_mouse_enabled; Bool _override_redirect; Atom _wm_delete_window; diff --git a/pandatool/CMakeLists.txt b/pandatool/CMakeLists.txt new file mode 100644 index 0000000000..8f26fb2d9a --- /dev/null +++ b/pandatool/CMakeLists.txt @@ -0,0 +1,48 @@ +if(NOT BUILD_PANDA) + message(FATAL_ERROR "Cannot build pandatool without panda! Please enable the BUILD_PANDA option.") +endif() + +# Include pandatool source directories +add_subdirectory(src/assimp) +add_subdirectory(src/bam) +add_subdirectory(src/converter) +add_subdirectory(src/daeegg) +add_subdirectory(src/daeprogs) +add_subdirectory(src/dxf) +add_subdirectory(src/dxfegg) +add_subdirectory(src/dxfprogs) +add_subdirectory(src/eggbase) +add_subdirectory(src/eggcharbase) +add_subdirectory(src/eggprogs) +add_subdirectory(src/egg-mkfont) +add_subdirectory(src/egg-optchar) +add_subdirectory(src/egg-palettize) +add_subdirectory(src/egg-qtess) +add_subdirectory(src/flt) +add_subdirectory(src/fltegg) +add_subdirectory(src/fltprogs) +add_subdirectory(src/gtk-stats) +add_subdirectory(src/imagebase) +add_subdirectory(src/imageprogs) +add_subdirectory(src/lwo) +add_subdirectory(src/lwoegg) +add_subdirectory(src/lwoprogs) +add_subdirectory(src/miscprogs) +add_subdirectory(src/objegg) +add_subdirectory(src/objprogs) +add_subdirectory(src/palettizer) +add_subdirectory(src/pandatoolbase) +add_subdirectory(src/pfmprogs) +add_subdirectory(src/progbase) +add_subdirectory(src/pstatserver) +add_subdirectory(src/ptloader) +add_subdirectory(src/text-stats) +add_subdirectory(src/vrml) +add_subdirectory(src/vrmlegg) +add_subdirectory(src/vrmlprogs) +add_subdirectory(src/win-stats) +add_subdirectory(src/xfile) +add_subdirectory(src/xfileegg) +add_subdirectory(src/xfileprogs) + +export_targets(Tools) diff --git a/pandatool/src/assimp/CMakeLists.txt b/pandatool/src/assimp/CMakeLists.txt new file mode 100644 index 0000000000..536d15ec39 --- /dev/null +++ b/pandatool/src/assimp/CMakeLists.txt @@ -0,0 +1,33 @@ +if(NOT HAVE_ASSIMP) + return() +endif() + +set(P3ASSIMP_HEADERS + assimpLoader.h assimpLoader.I + config_assimp.h + loaderFileTypeAssimp.h + pandaIOStream.h + pandaIOSystem.h + pandaLogger.h +) + +set(P3ASSIMP_SOURCES + assimpLoader.cxx + config_assimp.cxx + loaderFileTypeAssimp.cxx + pandaIOStream.cxx + pandaIOSystem.cxx + pandaLogger.cxx +) + +composite_sources(p3assimp P3ASSIMP_SOURCES) +add_library(p3assimp ${MODULE_TYPE} ${P3ASSIMP_HEADERS} ${P3ASSIMP_SOURCES}) +set_target_properties(p3assimp PROPERTIES DEFINE_SYMBOL BUILDING_ASSIMP) +target_link_libraries(p3assimp PRIVATE p3pandatoolbase) +target_link_libraries(p3assimp PUBLIC PKG::ASSIMP) + +if(BUILD_SHARED_LIBS) + # We can't install this if we're doing a static build, because it depends on + # a static library that isn't installed. + install(TARGETS p3assimp EXPORT Assimp COMPONENT Assimp DESTINATION ${MODULE_DESTINATION}) +endif() diff --git a/pandatool/src/bam/CMakeLists.txt b/pandatool/src/bam/CMakeLists.txt new file mode 100644 index 0000000000..79389b92ff --- /dev/null +++ b/pandatool/src/bam/CMakeLists.txt @@ -0,0 +1,23 @@ +add_executable(bam-info bamInfo.cxx bamInfo.h) +target_link_libraries(bam-info p3progbase panda) +install(TARGETS bam-info EXPORT Tools COMPONENT Tools DESTINATION ${CMAKE_INSTALL_BINDIR}) + +if(HAVE_EGG) + + add_executable(egg2bam eggToBam.cxx eggToBam.h) + target_link_libraries(egg2bam p3eggbase p3progbase panda) + install(TARGETS egg2bam EXPORT Tools COMPONENT Tools DESTINATION ${CMAKE_INSTALL_BINDIR}) + + if(HAVE_SQUISH) + target_compile_definitions(egg2bam PRIVATE HAVE_SQUISH) + endif() + + add_executable(bam2egg bamToEgg.cxx bamToEgg.h) + target_link_libraries(bam2egg p3converter p3eggbase p3progbase panda) + install(TARGETS bam2egg EXPORT Tools COMPONENT Tools DESTINATION ${CMAKE_INSTALL_BINDIR}) + + add_executable(pts2bam ptsToBam.cxx ptsToBam.h) + target_link_libraries(pts2bam p3progbase pandaegg panda) + install(TARGETS pts2bam EXPORT Tools COMPONENT Tools DESTINATION ${CMAKE_INSTALL_BINDIR}) + +endif() diff --git a/pandatool/src/converter/CMakeLists.txt b/pandatool/src/converter/CMakeLists.txt new file mode 100644 index 0000000000..2e75fed9f2 --- /dev/null +++ b/pandatool/src/converter/CMakeLists.txt @@ -0,0 +1,18 @@ +if(NOT HAVE_EGG) + return() +endif() + +set(P3CONVERTER_HEADERS + somethingToEggConverter.h somethingToEggConverter.I + eggToSomethingConverter.h eggToSomethingConverter.I +) + +set(P3CONVERTER_SOURCES + somethingToEggConverter.cxx eggToSomethingConverter.cxx +) + +add_library(p3converter STATIC ${P3CONVERTER_HEADERS} ${P3CONVERTER_SOURCES}) +target_link_libraries(p3converter p3pandatoolbase pandaegg) + +# This is only needed for binaries in the pandatool package. It is not useful +# for user applications, so it is not installed. diff --git a/pandatool/src/daeegg/CMakeLists.txt b/pandatool/src/daeegg/CMakeLists.txt new file mode 100644 index 0000000000..07b6320d14 --- /dev/null +++ b/pandatool/src/daeegg/CMakeLists.txt @@ -0,0 +1,26 @@ +if(NOT HAVE_EGG OR NOT HAVE_FCOLLADA) + return() +endif() + +set(P3DAEEGG_HEADERS + config_daeegg.h + daeCharacter.h + daeMaterials.h + daeToEggConverter.h + fcollada_utils.h + pre_fcollada_include.h +) + +set(P3DAEEGG_SOURCES + config_daeegg.cxx + daeCharacter.cxx + daeMaterials.cxx + daeToEggConverter.cxx +) + +add_library(p3daeegg STATIC ${P3DAEEGG_HEADERS} ${P3DAEEGG_SOURCES}) +target_link_libraries(p3daeegg p3eggbase + PKG::FCOLLADA) + +# This is only needed for binaries in the pandatool package. It is not useful +# for user applications, so it is not installed. diff --git a/pandatool/src/daeprogs/CMakeLists.txt b/pandatool/src/daeprogs/CMakeLists.txt new file mode 100644 index 0000000000..67ffc386c4 --- /dev/null +++ b/pandatool/src/daeprogs/CMakeLists.txt @@ -0,0 +1,11 @@ +if(HAVE_EGG AND HAVE_FCOLLADA) + + add_executable(egg2dae eggToDAE.cxx eggToDAE.h) + target_link_libraries(egg2dae p3daeegg p3eggbase p3progbase) + install(TARGETS egg2dae EXPORT Tools COMPONENT Tools DESTINATION ${CMAKE_INSTALL_BINDIR}) + + add_executable(dae2egg daeToEgg.cxx daeToEgg.h) + target_link_libraries(dae2egg p3daeegg p3eggbase p3progbase) + install(TARGETS dae2egg EXPORT Tools COMPONENT Tools DESTINATION ${CMAKE_INSTALL_BINDIR}) + +endif() diff --git a/pandatool/src/dxf/CMakeLists.txt b/pandatool/src/dxf/CMakeLists.txt new file mode 100644 index 0000000000..c8095a327f --- /dev/null +++ b/pandatool/src/dxf/CMakeLists.txt @@ -0,0 +1,20 @@ +set(P3DXF_HEADERS + dxfFile.h + dxfLayer.h + dxfLayerMap.h + dxfVertex.h +) + +set(P3DXF_SOURCES + dxfFile.cxx + dxfLayer.cxx + dxfLayerMap.cxx + dxfVertex.cxx +) + +composite_sources(p3dxf P3DXF_SOURCES) +add_library(p3dxf STATIC ${P3DXF_HEADERS} ${P3DXF_SOURCES}) +target_link_libraries(p3dxf p3pandatoolbase) + +# This is only needed for binaries in the pandatool package. It is not useful +# for user applications, so it is not installed. diff --git a/pandatool/src/dxfegg/CMakeLists.txt b/pandatool/src/dxfegg/CMakeLists.txt new file mode 100644 index 0000000000..74684b1c1f --- /dev/null +++ b/pandatool/src/dxfegg/CMakeLists.txt @@ -0,0 +1,19 @@ +if(NOT HAVE_EGG) + return() +endif() + +set(P3DXFEGG_HEADERS + dxfToEggConverter.h + dxfToEggLayer.h +) + +set(P3DXFEGG_SOURCES + dxfToEggConverter.cxx + dxfToEggLayer.cxx +) + +add_library(p3dxfegg STATIC ${P3DXFEGG_HEADERS} ${P3DXFEGG_SOURCES}) +target_link_libraries(p3dxfegg p3dxf p3eggbase) + +# This is only needed for binaries in the pandatool package. It is not useful +# for user applications, so it is not installed. diff --git a/pandatool/src/dxfprogs/CMakeLists.txt b/pandatool/src/dxfprogs/CMakeLists.txt new file mode 100644 index 0000000000..3cd39a0baa --- /dev/null +++ b/pandatool/src/dxfprogs/CMakeLists.txt @@ -0,0 +1,15 @@ +add_executable(dxf-points dxfPoints.cxx dxfPoints.h) +target_link_libraries(dxf-points p3progbase p3dxf) +install(TARGETS dxf-points EXPORT Tools COMPONENT Tools DESTINATION ${CMAKE_INSTALL_BINDIR}) + +if(HAVE_EGG) + + add_executable(egg2dxf eggToDXF.cxx eggToDXF.h eggToDXFLayer.cxx eggToDXFLayer.h) + target_link_libraries(egg2dxf p3dxfegg p3eggbase p3progbase) + install(TARGETS egg2dxf EXPORT Tools COMPONENT Tools DESTINATION ${CMAKE_INSTALL_BINDIR}) + + add_executable(dxf2egg dxfToEgg.cxx dxfToEgg.h) + target_link_libraries(dxf2egg p3dxfegg p3eggbase p3progbase) + install(TARGETS dxf2egg EXPORT Tools COMPONENT Tools DESTINATION ${CMAKE_INSTALL_BINDIR}) + +endif() diff --git a/pandatool/src/egg-mkfont/CMakeLists.txt b/pandatool/src/egg-mkfont/CMakeLists.txt new file mode 100644 index 0000000000..8b548e2e91 --- /dev/null +++ b/pandatool/src/egg-mkfont/CMakeLists.txt @@ -0,0 +1,21 @@ +if(NOT HAVE_EGG OR NOT HAVE_FREETYPE) + return() +endif() + +set(P3EGG_MKFONT_HEADERS + eggMakeFont.h + rangeDescription.h rangeDescription.I + rangeIterator.h rangeIterator.I +) + +set(P3EGG_MKFONT_SOURCES + eggMakeFont.cxx + rangeDescription.cxx + rangeIterator.cxx +) + +composite_sources(egg-mkfont P3EGG_MKFONT_SOURCES) +add_executable(egg-mkfont ${P3EGG_MKFONT_HEADERS} ${P3EGG_MKFONT_SOURCES}) +target_link_libraries(egg-mkfont p3palettizer p3eggbase p3pandatoolbase) + +install(TARGETS egg-mkfont EXPORT Tools COMPONENT Tools DESTINATION ${CMAKE_INSTALL_BINDIR}) diff --git a/pandatool/src/egg-optchar/CMakeLists.txt b/pandatool/src/egg-optchar/CMakeLists.txt new file mode 100644 index 0000000000..b30a070224 --- /dev/null +++ b/pandatool/src/egg-optchar/CMakeLists.txt @@ -0,0 +1,23 @@ +if(NOT HAVE_EGG) + return() +endif() + +set(P3EGG_OPTCHAR_HEADERS + config_egg_optchar.h + eggOptchar.h + eggOptcharUserData.h eggOptcharUserData.I + vertexMembership.h vertexMembership.I +) + +set(P3EGG_OPTCHAR_SOURCES + config_egg_optchar.cxx + eggOptchar.cxx + eggOptcharUserData.cxx + vertexMembership.cxx +) + +composite_sources(egg-optchar P3EGG_OPTCHAR_SOURCES) +add_executable(egg-optchar ${P3EGG_OPTCHAR_HEADERS} ${P3EGG_OPTCHAR_SOURCES}) +target_link_libraries(egg-optchar p3eggcharbase) + +install(TARGETS egg-optchar EXPORT Tools COMPONENT Tools DESTINATION ${CMAKE_INSTALL_BINDIR}) diff --git a/pandatool/src/egg-palettize/CMakeLists.txt b/pandatool/src/egg-palettize/CMakeLists.txt new file mode 100644 index 0000000000..18576f25d6 --- /dev/null +++ b/pandatool/src/egg-palettize/CMakeLists.txt @@ -0,0 +1,16 @@ +if(NOT HAVE_EGG) + return() +endif() + +add_executable(egg-palettize eggPalettize.cxx eggPalettize.h) +target_link_libraries(egg-palettize p3palettizer p3eggbase p3progbase) +install(TARGETS egg-palettize EXPORT Tools COMPONENT Tools DESTINATION ${CMAKE_INSTALL_BINDIR}) + +add_library(p3txafile txaFileFilter.cxx txaFileFilter.h txaFileFilter.I) +set_target_properties(p3txafile PROPERTIES DEFINE_SYMBOL BUILDING_MISC) +target_link_libraries(p3txafile PRIVATE p3palettizer) +if(BUILD_SHARED_LIBS) + # We can't install this if we're doing a static build, because it depends on + # a static library that isn't installed. + install(TARGETS p3txafile EXPORT Tools COMPONENT Tools DESTINATION ${CMAKE_INSTALL_LIBDIR} RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) +endif() diff --git a/pandatool/src/egg-qtess/CMakeLists.txt b/pandatool/src/egg-qtess/CMakeLists.txt new file mode 100644 index 0000000000..c8f4244c8a --- /dev/null +++ b/pandatool/src/egg-qtess/CMakeLists.txt @@ -0,0 +1,31 @@ +if(NOT HAVE_EGG) + return() +endif() + +set(P3EGG_QTESS_HEADERS + config_egg_qtess.h + eggQtess.h + isoPlacer.h isoPlacer.I + qtessGlobals.h + qtessInputEntry.h qtessInputEntry.I + qtessInputFile.h qtessInputFile.I + qtessSurface.h qtessSurface.I + subdivSegment.h subdivSegment.I +) + +set(P3EGG_QTESS_SOURCES + config_egg_qtess.cxx + eggQtess.cxx + isoPlacer.cxx + qtessGlobals.cxx + qtessInputEntry.cxx + qtessInputFile.cxx + qtessSurface.cxx + subdivSegment.cxx +) + +composite_sources(egg-qtess P3EGG_QTESS_SOURCES) +add_executable(egg-qtess ${P3EGG_QTESS_HEADERS} ${P3EGG_QTESS_SOURCES}) +target_link_libraries(egg-qtess p3eggbase) + +install(TARGETS egg-qtess EXPORT Tools COMPONENT Tools DESTINATION ${CMAKE_INSTALL_BINDIR}) diff --git a/pandatool/src/eggbase/CMakeLists.txt b/pandatool/src/eggbase/CMakeLists.txt new file mode 100644 index 0000000000..115ac0882c --- /dev/null +++ b/pandatool/src/eggbase/CMakeLists.txt @@ -0,0 +1,28 @@ +if(NOT HAVE_EGG) + return() +endif() + +set(P3EGGBASE_HEADERS + eggBase.h eggConverter.h eggFilter.h + eggMakeSomething.h + eggMultiBase.h eggMultiFilter.h + eggReader.h eggSingleBase.h + eggToSomething.h eggWriter.h + somethingToEgg.h +) + +set(P3EGGBASE_SOURCES + eggBase.cxx eggConverter.cxx eggFilter.cxx + eggMakeSomething.cxx + eggMultiBase.cxx + eggMultiFilter.cxx eggReader.cxx eggSingleBase.cxx + eggToSomething.cxx + eggWriter.cxx somethingToEgg.cxx +) + +composite_sources(p3eggbase P3EGGBASE_SOURCES) +add_library(p3eggbase STATIC ${P3EGGBASE_HEADERS} ${P3EGGBASE_SOURCES}) +target_link_libraries(p3eggbase p3progbase p3converter) + +# This is only needed for binaries in the pandatool package. It is not useful +# for user applications, so it is not installed. diff --git a/pandatool/src/eggcharbase/CMakeLists.txt b/pandatool/src/eggcharbase/CMakeLists.txt new file mode 100644 index 0000000000..384bebe032 --- /dev/null +++ b/pandatool/src/eggcharbase/CMakeLists.txt @@ -0,0 +1,46 @@ +if(NOT HAVE_EGG) + return() +endif() + +set(P3EGGCHARBASE_HEADERS + config_eggcharbase.h + eggBackPointer.h + eggCharacterCollection.h eggCharacterCollection.I + eggCharacterData.h eggCharacterData.I + eggCharacterDb.h eggCharacterDb.I + eggCharacterFilter.h + eggComponentData.h eggComponentData.I + eggJointData.h eggJointData.I + eggJointNodePointer.h + eggJointPointer.h eggJointPointer.I + eggMatrixTablePointer.h + eggScalarTablePointer.h + eggSliderData.h eggSliderData.I + eggSliderPointer.h + eggVertexPointer.h +) + +set(P3EGGCHARBASE_SOURCES + config_eggcharbase.cxx + eggBackPointer.cxx + eggCharacterCollection.cxx + eggCharacterData.cxx + eggCharacterDb.cxx + eggCharacterFilter.cxx + eggComponentData.cxx + eggJointData.cxx + eggJointNodePointer.cxx + eggJointPointer.cxx + eggMatrixTablePointer.cxx + eggScalarTablePointer.cxx + eggSliderData.cxx + eggSliderPointer.cxx + eggVertexPointer.cxx +) + +composite_sources(p3eggcharbase P3EGGCHARBASE_SOURCES) +add_library(p3eggcharbase STATIC ${P3EGGCHARBASE_HEADERS} ${P3EGGCHARBASE_SOURCES}) +target_link_libraries(p3eggcharbase p3eggbase) + +# This is only needed for binaries in the pandatool package. It is not useful +# for user applications, so it is not installed. diff --git a/pandatool/src/eggprogs/CMakeLists.txt b/pandatool/src/eggprogs/CMakeLists.txt new file mode 100644 index 0000000000..a14d33ab80 --- /dev/null +++ b/pandatool/src/eggprogs/CMakeLists.txt @@ -0,0 +1,39 @@ +if(NOT HAVE_EGG) + return() +endif() + +add_executable(egg-crop eggCrop.cxx eggCrop.h) +target_link_libraries(egg-crop p3eggbase) +install(TARGETS egg-crop EXPORT Tools COMPONENT Tools DESTINATION ${CMAKE_INSTALL_BINDIR}) + +add_executable(egg-list-textures eggListTextures.cxx eggListTextures.h) +target_link_libraries(egg-list-textures p3eggbase) +install(TARGETS egg-list-textures EXPORT Tools COMPONENT Tools DESTINATION ${CMAKE_INSTALL_BINDIR}) + +add_executable(egg-make-tube eggMakeTube.cxx eggMakeTube.h) +target_link_libraries(egg-make-tube p3eggbase) +install(TARGETS egg-make-tube EXPORT Tools COMPONENT Tools DESTINATION ${CMAKE_INSTALL_BINDIR}) + +add_executable(egg-rename eggRename.cxx eggRename.h) +target_link_libraries(egg-rename p3eggbase) +install(TARGETS egg-rename EXPORT Tools COMPONENT Tools DESTINATION ${CMAKE_INSTALL_BINDIR}) + +add_executable(egg-retarget-anim eggRetargetAnim.cxx eggRetargetAnim.h) +target_link_libraries(egg-retarget-anim p3eggcharbase) +install(TARGETS egg-retarget-anim EXPORT Tools COMPONENT Tools DESTINATION ${CMAKE_INSTALL_BINDIR}) + +add_executable(egg-texture-cards eggTextureCards.cxx eggTextureCards.h) +target_link_libraries(egg-texture-cards p3eggbase) +install(TARGETS egg-texture-cards EXPORT Tools COMPONENT Tools DESTINATION ${CMAKE_INSTALL_BINDIR}) + +add_executable(egg2c eggToC.cxx eggToC.h) +target_link_libraries(egg2c p3eggbase) +install(TARGETS egg2c EXPORT Tools COMPONENT Tools DESTINATION ${CMAKE_INSTALL_BINDIR}) + +add_executable(egg-topstrip eggTopstrip.cxx eggTopstrip.h) +target_link_libraries(egg-topstrip p3eggcharbase) +install(TARGETS egg-topstrip EXPORT Tools COMPONENT Tools DESTINATION ${CMAKE_INSTALL_BINDIR}) + +add_executable(egg-trans eggTrans.cxx eggTrans.h) +target_link_libraries(egg-trans p3eggbase) +install(TARGETS egg-trans EXPORT Tools COMPONENT Tools DESTINATION ${CMAKE_INSTALL_BINDIR}) diff --git a/pandatool/src/flt/CMakeLists.txt b/pandatool/src/flt/CMakeLists.txt new file mode 100644 index 0000000000..02f096b81b --- /dev/null +++ b/pandatool/src/flt/CMakeLists.txt @@ -0,0 +1,90 @@ +set(P3FLT_HEADERS + config_flt.h + fltBead.h + fltBeadID.h + fltCurve.h fltCurve.I + fltError.h + fltExternalReference.h + fltEyepoint.h + fltFace.h fltFace.I + fltGeometry.h fltGeometry.I + fltGroup.h + fltHeader.h + fltInstanceDefinition.h + fltInstanceRef.h + fltLightSourceDefinition.h + fltLocalVertexPool.h fltLocalVertexPool.I + fltLOD.h + fltMaterial.h + fltMesh.h fltMesh.I + fltMeshPrimitive.h fltMeshPrimitive.I + fltObject.h + fltOpcode.h + fltPackedColor.h fltPackedColor.I + fltRecord.h fltRecord.I + fltRecordReader.h + fltRecordWriter.h + fltTexture.h + fltTrackplane.h + fltTransformGeneralMatrix.h + fltTransformPut.h + fltTransformRecord.h + fltTransformRotateAboutEdge.h + fltTransformRotateAboutPoint.h + fltTransformRotateScale.h + fltTransformScale.h + fltTransformTranslate.h + fltUnsupportedRecord.h + fltVectorRecord.h + fltVertex.h fltVertex.I + fltVertexList.h +) + +set(P3FLT_SOURCES + config_flt.cxx + fltBead.cxx + fltBeadID.cxx + fltCurve.cxx + fltError.cxx + fltExternalReference.cxx + fltEyepoint.cxx + fltFace.cxx + fltGeometry.cxx + fltGroup.cxx + fltHeader.cxx + fltInstanceDefinition.cxx + fltInstanceRef.cxx + fltLightSourceDefinition.cxx + fltLocalVertexPool.cxx + fltLOD.cxx + fltMaterial.cxx + fltMesh.cxx + fltMeshPrimitive.cxx + fltObject.cxx + fltOpcode.cxx + fltPackedColor.cxx + fltRecord.cxx + fltRecordReader.cxx + fltRecordWriter.cxx + fltTexture.cxx + fltTrackplane.cxx + fltTransformGeneralMatrix.cxx + fltTransformPut.cxx + fltTransformRecord.cxx + fltTransformRotateAboutEdge.cxx + fltTransformRotateAboutPoint.cxx + fltTransformRotateScale.cxx + fltTransformScale.cxx + fltTransformTranslate.cxx + fltUnsupportedRecord.cxx + fltVectorRecord.cxx + fltVertex.cxx + fltVertexList.cxx +) + +composite_sources(p3flt P3FLT_SOURCES) +add_library(p3flt STATIC ${P3FLT_HEADERS} ${P3FLT_SOURCES}) +target_link_libraries(p3flt p3pandatoolbase panda) + +# This is only needed for binaries in the pandatool package. It is not useful +# for user applications, so it is not installed. diff --git a/pandatool/src/fltegg/CMakeLists.txt b/pandatool/src/fltegg/CMakeLists.txt new file mode 100644 index 0000000000..5a61e47ace --- /dev/null +++ b/pandatool/src/fltegg/CMakeLists.txt @@ -0,0 +1,19 @@ +if(NOT HAVE_EGG) + return() +endif() + +set(P3FLTEGG_HEADERS + fltToEggConverter.h fltToEggConverter.I + fltToEggLevelState.h fltToEggLevelState.I +) + +set(P3FLTEGG_SOURCES + fltToEggConverter.cxx + fltToEggLevelState.cxx +) + +add_library(p3fltegg STATIC ${P3FLTEGG_HEADERS} ${P3FLTEGG_SOURCES}) +target_link_libraries(p3fltegg p3flt p3eggbase) + +# This is only needed for binaries in the pandatool package. It is not useful +# for user applications, so it is not installed. diff --git a/pandatool/src/fltprogs/CMakeLists.txt b/pandatool/src/fltprogs/CMakeLists.txt new file mode 100644 index 0000000000..29a04166b7 --- /dev/null +++ b/pandatool/src/fltprogs/CMakeLists.txt @@ -0,0 +1,19 @@ +add_executable(flt-info fltInfo.cxx fltInfo.h) +target_link_libraries(flt-info p3progbase p3flt) +install(TARGETS flt-info EXPORT Tools COMPONENT Tools DESTINATION ${CMAKE_INSTALL_BINDIR}) + +add_executable(flt-trans fltTrans.cxx fltTrans.h) +target_link_libraries(flt-trans p3progbase p3flt) +install(TARGETS flt-trans EXPORT Tools COMPONENT Tools DESTINATION ${CMAKE_INSTALL_BINDIR}) + +if(HAVE_EGG) + + add_executable(egg2flt eggToFlt.cxx eggToFlt.h) + target_link_libraries(egg2flt p3fltegg p3eggbase p3progbase) + install(TARGETS egg2flt EXPORT Tools COMPONENT Tools DESTINATION ${CMAKE_INSTALL_BINDIR}) + + add_executable(flt2egg fltToEgg.cxx fltToEgg.h) + target_link_libraries(flt2egg p3fltegg p3eggbase p3progbase) + install(TARGETS flt2egg EXPORT Tools COMPONENT Tools DESTINATION ${CMAKE_INSTALL_BINDIR}) + +endif() diff --git a/pandatool/src/gtk-stats/CMakeLists.txt b/pandatool/src/gtk-stats/CMakeLists.txt new file mode 100644 index 0000000000..b78ebf2e80 --- /dev/null +++ b/pandatool/src/gtk-stats/CMakeLists.txt @@ -0,0 +1,41 @@ +if(NOT HAVE_GTK2 OR NOT HAVE_NET) + return() +endif() + +set(GTKSTATS_HEADERS + gtkStatsChartMenu.h + gtkStatsGraph.h + gtkStatsLabel.h + gtkStatsLabelStack.h + gtkStatsMenuId.h + gtkStatsMonitor.h gtkStatsMonitor.I + gtkStatsPianoRoll.h + gtkStatsServer.h + gtkStatsStripChart.h +) + +set(GTKSTATS_SOURCES + gtkStats.cxx + gtkStatsChartMenu.cxx + gtkStatsGraph.cxx + gtkStatsLabel.cxx + gtkStatsLabelStack.cxx + gtkStatsMonitor.cxx + gtkStatsPianoRoll.cxx + gtkStatsServer.cxx + gtkStatsStripChart.cxx +) + +composite_sources(gtk-stats GTKSTATS_SOURCES) +add_executable(gtk-stats ${GTKSTATS_HEADERS} ${GTKSTATS_SOURCES}) +target_link_libraries(gtk-stats p3progbase p3pstatserver PKG::GTK2) + +# This program is NOT actually called gtk-stats. It's pstats-gtk on Win32 and +# pstats everywhere else (as the Win32 GUI is not built). +if(WIN32) + set_target_properties(gtk-stats PROPERTIES OUTPUT_NAME "pstats-gtk") +else() + set_target_properties(gtk-stats PROPERTIES OUTPUT_NAME "pstats") +endif() + +install(TARGETS gtk-stats EXPORT Tools COMPONENT Tools DESTINATION ${CMAKE_INSTALL_BINDIR}) diff --git a/pandatool/src/imagebase/CMakeLists.txt b/pandatool/src/imagebase/CMakeLists.txt new file mode 100644 index 0000000000..46ffce3d5c --- /dev/null +++ b/pandatool/src/imagebase/CMakeLists.txt @@ -0,0 +1,20 @@ +set(P3IMAGEBASE_HEADERS + imageBase.h + imageFilter.h + imageReader.h + imageWriter.h imageWriter.I +) + +set(P3IMAGEBASE_SOURCES + imageBase.cxx + imageFilter.cxx + imageReader.cxx + imageWriter.cxx +) + +composite_sources(p3imagebase P3IMAGEBASE_SOURCES) +add_library(p3imagebase STATIC ${P3IMAGEBASE_HEADERS} ${P3IMAGEBASE_SOURCES}) +target_link_libraries(p3imagebase p3progbase) + +# This is only needed for binaries in the pandatool package. It is not useful +# for user applications, so it is not installed. diff --git a/pandatool/src/imageprogs/CMakeLists.txt b/pandatool/src/imageprogs/CMakeLists.txt new file mode 100644 index 0000000000..f39b4b90fb --- /dev/null +++ b/pandatool/src/imageprogs/CMakeLists.txt @@ -0,0 +1,19 @@ +add_executable(image-fix-hidden-color imageFixHiddenColor.cxx imageFixHiddenColor.h) +target_link_libraries(image-fix-hidden-color p3imagebase) +install(TARGETS image-fix-hidden-color EXPORT Tools COMPONENT Tools DESTINATION ${CMAKE_INSTALL_BINDIR}) + +add_executable(image-info imageInfo.cxx imageInfo.h) +target_link_libraries(image-info p3imagebase) +install(TARGETS image-info EXPORT Tools COMPONENT Tools DESTINATION ${CMAKE_INSTALL_BINDIR}) + +add_executable(image-resize imageResize.cxx imageResize.h) +target_link_libraries(image-resize p3imagebase) +install(TARGETS image-resize EXPORT Tools COMPONENT Tools DESTINATION ${CMAKE_INSTALL_BINDIR}) + +add_executable(image-transform-colors imageTransformColors.cxx imageTransformColors.h) +target_link_libraries(image-transform-colors p3imagebase) +install(TARGETS image-transform-colors EXPORT Tools COMPONENT Tools DESTINATION ${CMAKE_INSTALL_BINDIR}) + +add_executable(image-trans imageTrans.cxx imageTrans.h) +target_link_libraries(image-trans p3imagebase) +install(TARGETS image-trans EXPORT Tools COMPONENT Tools DESTINATION ${CMAKE_INSTALL_BINDIR}) diff --git a/pandatool/src/lwo/CMakeLists.txt b/pandatool/src/lwo/CMakeLists.txt new file mode 100644 index 0000000000..c7c7f33c35 --- /dev/null +++ b/pandatool/src/lwo/CMakeLists.txt @@ -0,0 +1,69 @@ +set(P3LWO_HEADERS + config_lwo.h + iffChunk.h iffChunk.I + iffGenericChunk.h iffGenericChunk.I + iffId.h iffId.I + iffInputFile.h iffInputFile.I + lwoBoundingBox.h + lwoChunk.h + lwoClip.h + lwoDiscontinuousVertexMap.h + lwoGroupChunk.h + lwoHeader.h lwoHeader.I + lwoInputFile.h lwoInputFile.I + lwoLayer.h + lwoPoints.h + lwoPolygons.h lwoPolygonTags.h + lwoStillImage.h + lwoSurfaceBlockAxis.h lwoSurfaceBlockChannel.h lwoSurfaceBlockCoordSys.h + lwoSurfaceBlockEnabled.h lwoSurfaceBlock.h lwoSurfaceBlockHeader.h + lwoSurfaceBlockImage.h lwoSurfaceBlockOpacity.h lwoSurfaceBlockProjection.h + lwoSurfaceBlockRefObj.h lwoSurfaceBlockRepeat.h lwoSurfaceBlockTMap.h + lwoSurfaceBlockTransform.h lwoSurfaceBlockVMapName.h lwoSurfaceBlockWrap.h + lwoSurfaceColor.h + lwoSurface.h + lwoSurfaceParameter.h + lwoSurfaceSidedness.h + lwoSurfaceSmoothingAngle.h + lwoTags.h + lwoVertexMap.h +) + +set(P3LWO_SOURCES + config_lwo.cxx + iffChunk.cxx + iffGenericChunk.cxx + iffId.cxx + iffInputFile.cxx + lwoBoundingBox.cxx + lwoChunk.cxx + lwoClip.cxx + lwoDiscontinuousVertexMap.cxx + lwoGroupChunk.cxx + lwoHeader.cxx + lwoInputFile.cxx + lwoLayer.cxx + lwoPoints.cxx + lwoPolygons.cxx + lwoPolygonTags.cxx + lwoStillImage.cxx + lwoSurfaceBlockAxis.cxx lwoSurfaceBlockChannel.cxx lwoSurfaceBlockCoordSys.cxx + lwoSurfaceBlock.cxx lwoSurfaceBlockEnabled.cxx lwoSurfaceBlockHeader.cxx + lwoSurfaceBlockImage.cxx lwoSurfaceBlockOpacity.cxx lwoSurfaceBlockProjection.cxx + lwoSurfaceBlockRefObj.cxx lwoSurfaceBlockRepeat.cxx lwoSurfaceBlockTMap.cxx + lwoSurfaceBlockTransform.cxx lwoSurfaceBlockVMapName.cxx lwoSurfaceBlockWrap.cxx + lwoSurfaceColor.cxx + lwoSurface.cxx + lwoSurfaceParameter.cxx + lwoSurfaceSidedness.cxx + lwoSurfaceSmoothingAngle.cxx + lwoTags.cxx + lwoVertexMap.cxx +) + +composite_sources(p3lwo P3LWO_SOURCES) +add_library(p3lwo STATIC ${P3LWO_HEADERS} ${P3LWO_SOURCES}) +target_link_libraries(p3lwo p3pandatoolbase) + +# This is only needed for binaries in the pandatool package. It is not useful +# for user applications, so it is not installed. diff --git a/pandatool/src/lwoegg/CMakeLists.txt b/pandatool/src/lwoegg/CMakeLists.txt new file mode 100644 index 0000000000..dbd4cff02f --- /dev/null +++ b/pandatool/src/lwoegg/CMakeLists.txt @@ -0,0 +1,31 @@ +if(NOT HAVE_EGG) + return() +endif() + +set(P3LWOEGG_HEADERS + cLwoClip.h cLwoClip.I + cLwoLayer.h cLwoLayer.I + cLwoPoints.h cLwoPoints.I + cLwoPolygons.h cLwoPolygons.I + cLwoSurfaceBlock.h cLwoSurfaceBlock.I + cLwoSurfaceBlockTMap.h cLwoSurfaceBlockTMap.I + cLwoSurface.h cLwoSurface.I + lwoToEggConverter.h lwoToEggConverter.I +) + +set(P3LWOEGG_SOURCES + cLwoClip.cxx + cLwoLayer.cxx + cLwoPoints.cxx + cLwoPolygons.cxx + cLwoSurfaceBlock.cxx + cLwoSurfaceBlockTMap.cxx + cLwoSurface.cxx + lwoToEggConverter.cxx +) + +add_library(p3lwoegg STATIC ${P3LWOEGG_HEADERS} ${P3LWOEGG_SOURCES}) +target_link_libraries(p3lwoegg p3lwo p3eggbase) + +# This is only needed for binaries in the pandatool package. It is not useful +# for user applications, so it is not installed. diff --git a/pandatool/src/lwoprogs/CMakeLists.txt b/pandatool/src/lwoprogs/CMakeLists.txt new file mode 100644 index 0000000000..0a3c1de2e5 --- /dev/null +++ b/pandatool/src/lwoprogs/CMakeLists.txt @@ -0,0 +1,11 @@ +add_executable(lwo-scan lwoScan.cxx lwoScan.h) +target_link_libraries(lwo-scan p3progbase p3lwo) +install(TARGETS lwo-scan EXPORT Tools COMPONENT Tools DESTINATION ${CMAKE_INSTALL_BINDIR}) + +if(HAVE_EGG) + + add_executable(lwo2egg lwoToEgg.cxx lwoToEgg.h) + target_link_libraries(lwo2egg p3lwoegg p3eggbase p3progbase) + install(TARGETS lwo2egg EXPORT Tools COMPONENT Tools DESTINATION ${CMAKE_INSTALL_BINDIR}) + +endif() diff --git a/pandatool/src/maya/mayaApi.cxx b/pandatool/src/maya/mayaApi.cxx index b045f45f32..d3324279ee 100644 --- a/pandatool/src/maya/mayaApi.cxx +++ b/pandatool/src/maya/mayaApi.cxx @@ -25,7 +25,7 @@ #include #include "post_maya_include.h" -#ifdef WIN32_VC +#ifdef _WIN32 #include // for chdir() #endif @@ -226,7 +226,7 @@ is_valid() const { return _is_valid; } -#ifdef WIN32 +#ifdef _WIN32 static string back_to_front_slash(const string &str) { string result = str; diff --git a/pandatool/src/mayaprogs/mayaPview.cxx b/pandatool/src/mayaprogs/mayaPview.cxx index 06fc171b14..1c956672b3 100644 --- a/pandatool/src/mayaprogs/mayaPview.cxx +++ b/pandatool/src/mayaprogs/mayaPview.cxx @@ -43,11 +43,11 @@ // On Windows, we have code to fork pview as a separate process, which seems // to be better for Maya. -#ifdef WIN32_VC +#ifdef _WIN32 #include #include #define SEPARATE_PVIEW 1 -#endif // WIN32_VC +#endif // _WIN32 /** * diff --git a/pandatool/src/mayaprogs/mayaSavePview.cxx b/pandatool/src/mayaprogs/mayaSavePview.cxx index 1537d95ce8..65a29236f3 100644 --- a/pandatool/src/mayaprogs/mayaSavePview.cxx +++ b/pandatool/src/mayaprogs/mayaSavePview.cxx @@ -22,7 +22,7 @@ #include -#ifdef WIN32_VC +#ifdef _WIN32 #include #endif @@ -69,7 +69,7 @@ doIt(const MArgList &args) { pview_args = "-cla"; } -#ifdef WIN32_VC +#ifdef _WIN32 // On Windows, we use the spawn function to run pview asynchronously. MString quoted = MString("\"") + filename + MString("\""); intptr_t retval = _spawnlp(_P_DETACH, "pview", @@ -78,7 +78,7 @@ doIt(const MArgList &args) { return MS::kFailure; } -#else // WIN32_VC +#else // _WIN32 // On non-Windows (e.g. Unix), we just use the system function, which runs // synchronously. We could fork a process, but no one's asked for this yet. MString command = MString("pview " + pview_args + MString(" \"") + filename + MString("\"")); @@ -87,7 +87,7 @@ doIt(const MArgList &args) { if (command_result != 0) { return MS::kFailure; } -#endif // WIN32_VC +#endif // _WIN32 return MS::kSuccess; } diff --git a/pandatool/src/mayaprogs/mayaSavePview.h b/pandatool/src/mayaprogs/mayaSavePview.h index d8f31d6688..56a84bf14c 100644 --- a/pandatool/src/mayaprogs/mayaSavePview.h +++ b/pandatool/src/mayaprogs/mayaSavePview.h @@ -71,7 +71,7 @@ public: // Since we don't include any of the Panda headers (other than // dtool_config.h), we have to define this macro ourselves, to tell Windows to // export the following functions from the DLL. -#ifdef WIN32_VC +#ifdef _WIN32 #define EXPCL_MISC __declspec(dllexport) #else #define EXPCL_MISC diff --git a/pandatool/src/mayaprogs/mayaToEgg_server.cxx b/pandatool/src/mayaprogs/mayaToEgg_server.cxx index e95118d33b..11b33a20d4 100644 --- a/pandatool/src/mayaprogs/mayaToEgg_server.cxx +++ b/pandatool/src/mayaprogs/mayaToEgg_server.cxx @@ -11,7 +11,7 @@ * @date 2009-11-09 */ -#if defined(WIN32_VC) || defined(WIN64_VC) +#ifdef _WIN32 #include // for chdir #endif #include "mayaToEgg_server.h" @@ -424,7 +424,7 @@ poll() { buffers.push_back(buffer); } // Change to the client's current dir -#ifdef WIN64_VC +#ifdef _WIN64 _chdir(cwd.c_str()); #else chdir(cwd.c_str()); diff --git a/pandatool/src/mayaprogs/mayapath.cxx b/pandatool/src/mayaprogs/mayapath.cxx index 255aa569cf..c98e38243b 100644 --- a/pandatool/src/mayaprogs/mayapath.cxx +++ b/pandatool/src/mayaprogs/mayapath.cxx @@ -347,7 +347,7 @@ main(int argc, char *argv[]) { putenv(putenv_cstr); } -#ifdef WIN32 +#ifdef _WIN32 string sep = ";"; #else string sep = ":"; diff --git a/pandatool/src/miscprogs/CMakeLists.txt b/pandatool/src/miscprogs/CMakeLists.txt new file mode 100644 index 0000000000..169cecc774 --- /dev/null +++ b/pandatool/src/miscprogs/CMakeLists.txt @@ -0,0 +1,3 @@ +add_executable(bin2c binToC.cxx binToC.h) +target_link_libraries(bin2c p3progbase) +install(TARGETS bin2c EXPORT Tools COMPONENT Tools DESTINATION ${CMAKE_INSTALL_BINDIR}) diff --git a/pandatool/src/objegg/CMakeLists.txt b/pandatool/src/objegg/CMakeLists.txt new file mode 100644 index 0000000000..c6106815b2 --- /dev/null +++ b/pandatool/src/objegg/CMakeLists.txt @@ -0,0 +1,23 @@ +if(NOT HAVE_EGG) + return() +endif() + +set(P3OBJEGG_HEADERS + config_objegg.h + eggToObjConverter.h + objToEggConverter.h + objToEggConverter.I +) + +set(P3OBJEGG_SOURCES + config_objegg.cxx + eggToObjConverter.cxx + objToEggConverter.cxx +) + +composite_sources(p3objegg P3OBJEGG_SOURCES) +add_library(p3objegg STATIC ${P3OBJEGG_HEADERS} ${P3OBJEGG_SOURCES}) +target_link_libraries(p3objegg p3eggbase) + +# This is only needed for binaries in the pandatool package. It is not useful +# for user applications, so it is not installed. diff --git a/pandatool/src/objprogs/CMakeLists.txt b/pandatool/src/objprogs/CMakeLists.txt new file mode 100644 index 0000000000..adc398fab4 --- /dev/null +++ b/pandatool/src/objprogs/CMakeLists.txt @@ -0,0 +1,11 @@ +if(NOT HAVE_EGG) + return() +endif() + +add_executable(egg2obj eggToObj.cxx eggToObj.h) +target_link_libraries(egg2obj p3objegg p3eggbase) +install(TARGETS egg2obj EXPORT Tools COMPONENT Tools DESTINATION ${CMAKE_INSTALL_BINDIR}) + +add_executable(obj2egg objToEgg.cxx objToEgg.h) +target_link_libraries(obj2egg p3objegg p3eggbase p3progbase) +install(TARGETS obj2egg EXPORT Tools COMPONENT Tools DESTINATION ${CMAKE_INSTALL_BINDIR}) diff --git a/pandatool/src/palettizer/CMakeLists.txt b/pandatool/src/palettizer/CMakeLists.txt new file mode 100644 index 0000000000..f3cb281893 --- /dev/null +++ b/pandatool/src/palettizer/CMakeLists.txt @@ -0,0 +1,60 @@ +if(NOT HAVE_EGG) + return() +endif() + +set(P3PALETTIZER_HEADERS + config_palettizer.h + destTextureImage.h + eggFile.h + filenameUnifier.h + imageFile.h + omitReason.h + paletteGroup.h + paletteGroups.h + paletteImage.h + palettePage.h + palettizer.h + pal_string_utils.h + sourceTextureImage.h + textureImage.h + textureMemoryCounter.h + texturePlacement.h + texturePosition.h + textureProperties.h + textureReference.h + textureRequest.h + txaFile.h + txaLine.h +) + +set(P3PALETTIZER_SOURCES + config_palettizer.cxx + destTextureImage.cxx + eggFile.cxx + filenameUnifier.cxx + imageFile.cxx + omitReason.cxx + paletteGroup.cxx + paletteGroups.cxx + paletteImage.cxx + palettePage.cxx + palettizer.cxx + pal_string_utils.cxx + sourceTextureImage.cxx + textureImage.cxx + textureMemoryCounter.cxx + texturePlacement.cxx + texturePosition.cxx + textureProperties.cxx + textureReference.cxx + textureRequest.cxx + txaFile.cxx + txaLine.cxx +) + +composite_sources(p3palettizer P3PALETTIZER_SOURCES) +add_library(p3palettizer STATIC ${P3PALETTIZER_HEADERS} ${P3PALETTIZER_SOURCES}) +target_link_libraries(p3palettizer p3progbase p3converter) + +# This is only needed for binaries in the pandatool package. It is not useful +# for user applications, so it is not installed. diff --git a/pandatool/src/palettizer/paletteGroups.h b/pandatool/src/palettizer/paletteGroups.h index 9a2cdd2b52..bdcfd248e1 100644 --- a/pandatool/src/palettizer/paletteGroups.h +++ b/pandatool/src/palettizer/paletteGroups.h @@ -30,7 +30,7 @@ private: typedef pset Groups; public: -#ifndef WIN32_VC +#ifndef _WIN32 typedef Groups::const_pointer pointer; typedef Groups::const_pointer const_pointer; #endif diff --git a/pandatool/src/pandatoolbase/CMakeLists.txt b/pandatool/src/pandatoolbase/CMakeLists.txt new file mode 100644 index 0000000000..93d9aae35e --- /dev/null +++ b/pandatool/src/pandatoolbase/CMakeLists.txt @@ -0,0 +1,31 @@ +set(P3PANDATOOLBASE_HEADERS + animationConvert.h + config_pandatoolbase.h + distanceUnit.h + pandatoolbase.h pandatoolsymbols.h + pathReplace.h pathReplace.I + pathStore.h +) + +set(P3PANDATOOLBASE_SOURCES + animationConvert.cxx + config_pandatoolbase.cxx + distanceUnit.cxx + pandatoolbase.cxx + pathReplace.cxx + pathStore.cxx +) + +composite_sources(p3pandatoolbase P3PANDATOOLBASE_SOURCES) +add_library(p3pandatoolbase STATIC ${P3PANDATOOLBASE_HEADERS} ${P3PANDATOOLBASE_SOURCES}) +target_link_libraries(p3pandatoolbase panda) + +# ptloader - a module - may need to link in libraries in this package, so: +if(MODULE_TYPE STREQUAL "MODULE") + set_target_properties(p3pandatoolbase PROPERTIES + POSITION_INDEPENDENT_CODE ON + INTERFACE_POSITION_INDEPENDENT_CODE ON) +endif() + +# This is only needed for binaries in the pandatool package. It is not useful +# for user applications, so it is not installed. diff --git a/pandatool/src/pfmprogs/CMakeLists.txt b/pandatool/src/pfmprogs/CMakeLists.txt new file mode 100644 index 0000000000..13cb6af787 --- /dev/null +++ b/pandatool/src/pfmprogs/CMakeLists.txt @@ -0,0 +1,9 @@ +add_executable(pfm-bba + config_pfmprogs.cxx config_pfmprogs.h + pfmBba.cxx pfmBba.h) +target_link_libraries(pfm-bba p3progbase) +install(TARGETS pfm-bba EXPORT Tools COMPONENT Tools DESTINATION ${CMAKE_INSTALL_BINDIR}) + +add_executable(pfm-trans pfmTrans.cxx pfmTrans.h) +target_link_libraries(pfm-trans p3progbase) +install(TARGETS pfm-trans EXPORT Tools COMPONENT Tools DESTINATION ${CMAKE_INSTALL_BINDIR}) diff --git a/pandatool/src/progbase/CMakeLists.txt b/pandatool/src/progbase/CMakeLists.txt new file mode 100644 index 0000000000..70e9212649 --- /dev/null +++ b/pandatool/src/progbase/CMakeLists.txt @@ -0,0 +1,22 @@ +set(P3PROGBASE_HEADERS + programBase.h programBase.I + withOutputFile.h withOutputFile.I + wordWrapStream.h wordWrapStreamBuf.I + wordWrapStreamBuf.h +) + +set(P3PROGBASE_SOURCES + programBase.cxx withOutputFile.cxx wordWrapStream.cxx + wordWrapStreamBuf.cxx +) + +composite_sources(p3progbase P3PROGBASE_SOURCES) +add_library(p3progbase STATIC ${P3PROGBASE_HEADERS} ${P3PROGBASE_SOURCES}) +target_link_libraries(p3progbase p3pandatoolbase panda PKG::ZLIB) + +if(IOCTL_TERMINAL_WIDTH) + target_compile_definitions(p3progbase PRIVATE IOCTL_TERMINAL_WIDTH) +endif() + +# This is only needed for binaries in the pandatool package. It is not useful +# for user applications, so it is not installed. diff --git a/pandatool/src/pstatserver/CMakeLists.txt b/pandatool/src/pstatserver/CMakeLists.txt new file mode 100644 index 0000000000..359f529b18 --- /dev/null +++ b/pandatool/src/pstatserver/CMakeLists.txt @@ -0,0 +1,33 @@ +if(NOT HAVE_NET) + return() +endif() + +set(P3PSTATSERVER_HEADERS + pStatClientData.h + pStatGraph.h pStatGraph.I + pStatListener.h + pStatMonitor.h pStatMonitor.I + pStatPianoRoll.h pStatPianoRoll.I + pStatReader.h + pStatServer.h + pStatStripChart.h pStatStripChart.I + pStatThreadData.h pStatThreadData.I + pStatView.h pStatView.I + pStatViewLevel.h pStatViewLevel.I +) + +set(P3PSTATSERVER_SOURCES + pStatClientData.cxx pStatGraph.cxx + pStatListener.cxx + pStatMonitor.cxx pStatPianoRoll.cxx + pStatReader.cxx pStatServer.cxx + pStatStripChart.cxx pStatThreadData.cxx + pStatView.cxx pStatViewLevel.cxx +) + +composite_sources(p3pstatserver P3PSTATSERVER_SOURCES) +add_library(p3pstatserver STATIC ${P3PSTATSERVER_HEADERS} ${P3PSTATSERVER_SOURCES}) +target_link_libraries(p3pstatserver p3pandatoolbase panda) + +# This is only needed for binaries in the pandatool package. It is not useful +# for user applications, so it is not installed. diff --git a/pandatool/src/ptloader/CMakeLists.txt b/pandatool/src/ptloader/CMakeLists.txt new file mode 100644 index 0000000000..0d98ee8377 --- /dev/null +++ b/pandatool/src/ptloader/CMakeLists.txt @@ -0,0 +1,31 @@ +if(NOT HAVE_EGG) + return() +endif() + +set(P3PTLOADER_HEADERS + config_ptloader.h + loaderFileTypePandatool.h +) + +set(P3PTLOADER_SOURCES + config_ptloader.cxx + loaderFileTypePandatool.cxx +) + +composite_sources(p3ptloader P3PTLOADER_SOURCES) +add_library(p3ptloader ${MODULE_TYPE} ${P3PTLOADER_HEADERS} ${P3PTLOADER_SOURCES}) +set_target_properties(p3ptloader PROPERTIES DEFINE_SYMBOL BUILDING_PTLOADER) +target_link_libraries(p3ptloader PRIVATE + p3dxfegg p3fltegg p3lwoegg p3objegg p3vrmlegg p3xfileegg + p3converter) + +if(HAVE_FCOLLADA) + target_link_libraries(p3ptloader PRIVATE p3daeegg) + target_compile_definitions(p3ptloader PRIVATE HAVE_FCOLLADA) +endif() + +if(BUILD_SHARED_LIBS) + # We can't install this if we're doing a static build, because it depends on + # a bunch of static libraries that aren't installed. + install(TARGETS p3ptloader EXPORT Tools COMPONENT Tools DESTINATION ${MODULE_DESTINATION}) +endif() diff --git a/pandatool/src/text-stats/CMakeLists.txt b/pandatool/src/text-stats/CMakeLists.txt new file mode 100644 index 0000000000..155b9013f3 --- /dev/null +++ b/pandatool/src/text-stats/CMakeLists.txt @@ -0,0 +1,19 @@ +if(NOT HAVE_NET) + return() +endif() + +set(TEXTSTATS_HEADERS + textMonitor.h textMonitor.I + textStats.h +) + +set(TEXTSTATS_SOURCES + textMonitor.cxx + textStats.cxx +) + +composite_sources(text-stats TEXTSTATS_SOURCES) +add_executable(text-stats ${TEXTSTATS_HEADERS} ${TEXTSTATS_SOURCES}) +target_link_libraries(text-stats p3progbase p3pstatserver) + +install(TARGETS text-stats EXPORT Tools COMPONENT Tools DESTINATION ${CMAKE_INSTALL_BINDIR}) diff --git a/pandatool/src/vrml/CMakeLists.txt b/pandatool/src/vrml/CMakeLists.txt new file mode 100644 index 0000000000..235ccbff4e --- /dev/null +++ b/pandatool/src/vrml/CMakeLists.txt @@ -0,0 +1,30 @@ +set(P3VRML_HEADERS + parse_vrml.h + standard_nodes.h + vrmlLexerDefs.h + vrmlNode.h + vrmlNodeType.h + vrmlParserDefs.h +) + +set(P3VRML_SOURCES + parse_vrml.cxx + standard_nodes.cxx + vrmlNode.cxx + vrmlNodeType.cxx +) + +set(P3VRML_PARSER_SOURCES + vrmlParser.cxx + vrmlLexer.cxx +) + +add_bison_target(vrmlParser.cxx vrmlParser.yxx DEFINES vrmlParser.h PREFIX vrmlyy) +add_flex_target(vrmlLexer.cxx vrmlLexer.lxx CASE_INSENSITIVE PREFIX vrmlyy) + +composite_sources(p3vrml P3VRML_SOURCES) +add_library(p3vrml STATIC ${P3VRML_HEADERS} ${P3VRML_SOURCES} ${P3VRML_PARSER_SOURCES}) +target_link_libraries(p3vrml p3pandatoolbase) + +# This is only needed for binaries in the pandatool package. It is not useful +# for user applications, so it is not installed. diff --git a/pandatool/src/vrmlegg/CMakeLists.txt b/pandatool/src/vrmlegg/CMakeLists.txt new file mode 100644 index 0000000000..b2a38c840e --- /dev/null +++ b/pandatool/src/vrmlegg/CMakeLists.txt @@ -0,0 +1,22 @@ +if(NOT HAVE_EGG) + return() +endif() + +set(P3VRMLEGG_HEADERS + indexedFaceSet.h + vrmlAppearance.h + vrmlToEggConverter.h +) + +set(P3VRMLEGG_SOURCES + indexedFaceSet.cxx + vrmlAppearance.cxx + vrmlToEggConverter.cxx +) + +composite_sources(p3vrmlegg P3VRMLEGG_SOURCES) +add_library(p3vrmlegg STATIC ${P3VRMLEGG_HEADERS} ${P3VRMLEGG_SOURCES}) +target_link_libraries(p3vrmlegg p3vrml p3eggbase) + +# This is only needed for binaries in the pandatool package. It is not useful +# for user applications, so it is not installed. diff --git a/pandatool/src/vrmlprogs/CMakeLists.txt b/pandatool/src/vrmlprogs/CMakeLists.txt new file mode 100644 index 0000000000..82a5e78bd3 --- /dev/null +++ b/pandatool/src/vrmlprogs/CMakeLists.txt @@ -0,0 +1,11 @@ +add_executable(vrml-trans vrmlTrans.cxx vrmlTrans.h) +target_link_libraries(vrml-trans p3progbase p3vrml) +install(TARGETS vrml-trans EXPORT Tools COMPONENT Tools DESTINATION ${CMAKE_INSTALL_BINDIR}) + +if(HAVE_EGG) + + add_executable(vrml2egg vrmlToEgg.cxx vrmlToEgg.h) + target_link_libraries(vrml2egg p3vrmlegg p3eggbase p3progbase) + install(TARGETS vrml2egg EXPORT Tools COMPONENT Tools DESTINATION ${CMAKE_INSTALL_BINDIR}) + +endif() diff --git a/pandatool/src/win-stats/CMakeLists.txt b/pandatool/src/win-stats/CMakeLists.txt new file mode 100644 index 0000000000..0cd7768c3a --- /dev/null +++ b/pandatool/src/win-stats/CMakeLists.txt @@ -0,0 +1,37 @@ +if(NOT WIN32 OR NOT HAVE_NET) + return() +endif() + +set(WINSTATS_HEADERS + winStatsChartMenu.h + winStatsGraph.h + winStats.h + winStatsLabel.h + winStatsLabelStack.h + winStatsMenuId.h + winStatsMonitor.h winStatsMonitor.I + winStatsPianoRoll.h + winStatsServer.h + winStatsStripChart.h +) + +set(WINSTATS_SOURCES + winStatsChartMenu.cxx + winStats.cxx + winStatsGraph.cxx + winStatsLabel.cxx + winStatsLabelStack.cxx + winStatsMonitor.cxx + winStatsPianoRoll.cxx + winStatsServer.cxx + winStatsStripChart.cxx +) + +composite_sources(win-stats WINSTATS_SOURCES) +add_executable(win-stats ${WINSTATS_HEADERS} ${WINSTATS_SOURCES}) +target_link_libraries(win-stats p3progbase p3pstatserver) + +# This program is NOT actually called win-stats. It's just pstats.exe +set_target_properties(win-stats PROPERTIES OUTPUT_NAME "pstats") + +install(TARGETS win-stats EXPORT Tools COMPONENT Tools DESTINATION ${CMAKE_INSTALL_BINDIR}) diff --git a/pandatool/src/xfile/CMakeLists.txt b/pandatool/src/xfile/CMakeLists.txt new file mode 100644 index 0000000000..1768ef35ed --- /dev/null +++ b/pandatool/src/xfile/CMakeLists.txt @@ -0,0 +1,56 @@ +set(P3XFILE_HEADERS + config_xfile.h + standard_templates.h + windowsGuid.h windowsGuid.I + xFileArrayDef.h xFileArrayDef.I + xFileDataDef.h xFileDataDef.I + xFileDataNode.h xFileDataNode.I + xFileDataNodeReference.h xFileDataNodeReference.I + xFileDataNodeTemplate.h xFileDataNodeTemplate.I + xFileDataObjectArray.h xFileDataObjectArray.I + xFileDataObjectDouble.h xFileDataObjectDouble.I + xFileDataObject.h xFileDataObject.I + xFileDataObjectInteger.h xFileDataObjectInteger.I + xFileDataObjectString.h xFileDataObjectString.I + xFile.h xFile.I + xFileNode.h xFileNode.I + xFileParseData.h xFileParseData.I + xFileTemplate.h xFileTemplate.I + xLexerDefs.h + xParserDefs.h +) + +set(P3XFILE_SOURCES + config_xfile.cxx + standard_templates.cxx + windowsGuid.cxx + xFileArrayDef.cxx + xFile.cxx + xFileDataDef.cxx + xFileDataNode.cxx + xFileDataNodeReference.cxx + xFileDataNodeTemplate.cxx + xFileDataObjectArray.cxx + xFileDataObject.cxx + xFileDataObjectDouble.cxx + xFileDataObjectInteger.cxx + xFileDataObjectString.cxx + xFileNode.cxx + xFileParseData.cxx + xFileTemplate.cxx +) + +set(P3XFILE_PARSER_SOURCES + xParser.cxx + xLexer.cxx +) + +add_bison_target(xParser.cxx xParser.yxx DEFINES xParser.h PREFIX xyy) +add_flex_target(xLexer.cxx xLexer.lxx CASE_INSENSITIVE PREFIX xyy) + +composite_sources(p3xfile P3XFILE_SOURCES) +add_library(p3xfile STATIC ${P3XFILE_HEADERS} ${P3XFILE_SOURCES} ${P3XFILE_PARSER_SOURCES}) +target_link_libraries(p3xfile p3pandatoolbase) + +# This is only needed for binaries in the pandatool package. It is not useful +# for user applications, so it is not installed. diff --git a/pandatool/src/xfileegg/CMakeLists.txt b/pandatool/src/xfileegg/CMakeLists.txt new file mode 100644 index 0000000000..eb8bd12e57 --- /dev/null +++ b/pandatool/src/xfileegg/CMakeLists.txt @@ -0,0 +1,26 @@ +if(NOT HAVE_EGG) + return() +endif() + +set(P3XFILEEGG_HEADERS + xFileAnimationSet.h xFileAnimationSet.I + xFileFace.h xFileMaker.h + xFileMaterial.h xFileMesh.h xFileNormal.h + xFileToEggConverter.h + xFileVertex.h xFileVertexPool.h +) + +set(P3XFILEEGG_SOURCES + xFileAnimationSet.cxx + xFileFace.cxx xFileMaker.cxx + xFileMaterial.cxx xFileMesh.cxx xFileNormal.cxx + xFileToEggConverter.cxx + xFileVertex.cxx +) + +composite_sources(p3xfileegg P3XFILEEGG_SOURCES) +add_library(p3xfileegg STATIC ${P3XFILEEGG_HEADERS} ${P3XFILEEGG_SOURCES}) +target_link_libraries(p3xfileegg p3xfile p3eggbase) + +# This is only needed for binaries in the pandatool package. It is not useful +# for user applications, so it is not installed. diff --git a/pandatool/src/xfileprogs/CMakeLists.txt b/pandatool/src/xfileprogs/CMakeLists.txt new file mode 100644 index 0000000000..29562db00d --- /dev/null +++ b/pandatool/src/xfileprogs/CMakeLists.txt @@ -0,0 +1,15 @@ +add_executable(x-trans xFileTrans.cxx xFileTrans.h) +target_link_libraries(x-trans p3progbase p3xfile) +install(TARGETS x-trans EXPORT Tools COMPONENT Tools DESTINATION ${CMAKE_INSTALL_BINDIR}) + +if(HAVE_EGG) + + add_executable(egg2x eggToX.cxx eggToX.h) + target_link_libraries(egg2x p3xfileegg p3eggbase p3progbase) + install(TARGETS egg2x EXPORT Tools COMPONENT Tools DESTINATION ${CMAKE_INSTALL_BINDIR}) + + add_executable(x2egg xFileToEgg.cxx xFileToEgg.h) + target_link_libraries(x2egg p3xfileegg p3eggbase p3progbase) + install(TARGETS x2egg EXPORT Tools COMPONENT Tools DESTINATION ${CMAKE_INSTALL_BINDIR}) + +endif() diff --git a/tests/display/test_glsl_shader.py b/tests/display/test_glsl_shader.py index a380f8ccfb..891410c3e7 100644 --- a/tests/display/test_glsl_shader.py +++ b/tests/display/test_glsl_shader.py @@ -261,6 +261,54 @@ def test_glsl_bool(gsg): run_glsl_test(gsg, code, preamble, flags) +def test_glsl_mat3(gsg): + param1 = core.LMatrix4(core.LMatrix3(1, 2, 3, 4, 5, 6, 7, 8, 9)) + + param2 = core.NodePath("param2") + param2.set_mat(core.LMatrix3(10, 11, 12, 13, 14, 15, 16, 17, 18)) + + preamble = """ + uniform mat3 param1; + uniform mat3 param2; + """ + code = """ + assert(param1[0] == vec3(1, 2, 3)); + assert(param1[1] == vec3(4, 5, 6)); + assert(param1[2] == vec3(7, 8, 9)); + assert(param2[0] == vec3(10, 11, 12)); + assert(param2[1] == vec3(13, 14, 15)); + assert(param2[2] == vec3(16, 17, 18)); + """ + run_glsl_test(gsg, code, preamble, {'param1': param1, 'param2': param2}) + + +def test_glsl_mat4(gsg): + param1 = core.LMatrix4(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16) + + param2 = core.NodePath("param2") + param2.set_mat(core.LMatrix4( + 17, 18, 19, 20, + 21, 22, 23, 24, + 25, 26, 27, 28, + 29, 30, 31, 32)) + + preamble = """ + uniform mat4 param1; + uniform mat4 param2; + """ + code = """ + assert(param1[0] == vec4(1, 2, 3, 4)); + assert(param1[1] == vec4(5, 6, 7, 8)); + assert(param1[2] == vec4(9, 10, 11, 12)); + assert(param1[3] == vec4(13, 14, 15, 16)); + assert(param2[0] == vec4(17, 18, 19, 20)); + assert(param2[1] == vec4(21, 22, 23, 24)); + assert(param2[2] == vec4(25, 26, 27, 28)); + assert(param2[3] == vec4(29, 30, 31, 32)); + """ + run_glsl_test(gsg, code, preamble, {'param1': param1, 'param2': param2}) + + def test_glsl_pta_int(gsg): pta = core.PTA_int((0, 1, 2, 3)) diff --git a/tests/gui/test_DirectScrolledFrame.py b/tests/gui/test_DirectScrolledFrame.py new file mode 100644 index 0000000000..85ad8a53d4 --- /dev/null +++ b/tests/gui/test_DirectScrolledFrame.py @@ -0,0 +1,36 @@ +from direct.gui.DirectScrolledFrame import DirectScrolledFrame +import pytest + + +def test_set_scrollbar_width(): + w = 1 + + frm = DirectScrolledFrame(scrollBarWidth=w) + + assert frm['scrollBarWidth'] == 1 + + assert frm.verticalScroll['frameSize'] == (-w / 2.0, w / 2.0, -1, 1) + assert frm.horizontalScroll['frameSize'] == (-1, 1, -w / 2.0, w / 2.0) + + # manual changes to the framesize + frm.verticalScroll['frameSize'] = (-2, 2, -4, 4) + frm.horizontalScroll['frameSize'] = (-4, 4, -2, 2) + assert frm.verticalScroll['frameSize'] == (-2, 2, -4, 4) + assert frm.horizontalScroll['frameSize'] == (-4, 4, -2, 2) + + # change scrollbar width to a new value + w = 2 + frm['scrollBarWidth'] = w + + # check, new value is set correct + assert frm['scrollBarWidth'] == 2 + + # check if new size is set correct + assert frm.verticalScroll['frameSize'] == (-w / 2.0, w / 2.0, -4, 4) + assert frm.horizontalScroll['frameSize'] == (-4, 4, -w / 2.0, w / 2.0) + + +def test_set_scrollbar_width_on_init(): + frm = DirectScrolledFrame(verticalScroll_frameSize=(-2, 2, -4, 4), horizontalScroll_frameSize=(-4, 4, -2, 2)) + assert frm.verticalScroll['frameSize'] == (-2, 2, -4, 4) + assert frm.horizontalScroll['frameSize'] == (-4, 4, -2, 2) diff --git a/tests/gui/test_DirectSlider.py b/tests/gui/test_DirectSlider.py new file mode 100644 index 0000000000..5c740c6c98 --- /dev/null +++ b/tests/gui/test_DirectSlider.py @@ -0,0 +1,29 @@ +from direct.gui.DirectSlider import DirectSlider +from direct.gui import DirectGuiGlobals as DGG +import pytest + +def test_slider_orientation(): + slider = DirectSlider() + + # Horizontal orientation is the default + assert slider['orientation'] == DGG.HORIZONTAL + assert slider['frameSize'] == (-1, 1, -0.08, 0.08) + assert slider['frameVisibleScale'] == (1, 0.25) + + # try change to vertical orientation + slider['orientation'] = DGG.VERTICAL + assert slider['orientation'] == DGG.VERTICAL + assert slider['frameSize'] == (-0.08, 0.08, -1, 1) + assert slider['frameVisibleScale'] == (0.25, 1) + + # back to horizontal + slider['orientation'] = DGG.HORIZONTAL + assert slider['orientation'] == DGG.HORIZONTAL + assert slider['frameSize'] == (-1, 1, -0.08, 0.08) + assert slider['frameVisibleScale'] == (1, 0.25) + + # finally change to inverted vertical orientation + slider['orientation'] = DGG.VERTICAL_INVERTED + assert slider['orientation'] == DGG.VERTICAL_INVERTED + assert slider['frameSize'] == (-0.08, 0.08, -1, 1) + assert slider['frameVisibleScale'] == (0.25, 1) diff --git a/tests/interrogate/test_property.py b/tests/interrogate/test_property.py index 4d521d03e5..fffcb78ac0 100755 --- a/tests/interrogate/test_property.py +++ b/tests/interrogate/test_property.py @@ -149,7 +149,7 @@ def test_seq_property_getitem(): prop[i] # Make sure it preserves refcount of invalid indices - i = "nonsense" + i = "nonsense195641" with constant_refcount(i): try: prop[i] @@ -250,7 +250,7 @@ def test_seq_property_index(): except ValueError: pass - nonsense = "nonsense" + nonsense = "nonsense854371" with constant_refcount(nonsense): try: prop.index(nonsense) @@ -271,7 +271,7 @@ def test_seq_property_count(): with constant_refcount(item_b): prop.count(item_b) - nonsense = "nonsense" + nonsense = "nonsense219449" with constant_refcount(nonsense): prop.count(nonsense) @@ -447,8 +447,8 @@ def test_map_property_empty(): def test_map_property_getitem(): - key = 'key' - value = 'value' + key = 'key162732' + value = 'value162732' prop = map_property(**{key: value}) with constant_refcount(key): @@ -462,8 +462,8 @@ def test_map_property_getitem(): def test_map_property_setitem(): - key = 'key' - value = 'value' + key = 'key559075' + value = 'value559075' prop = map_property() # Setting new key @@ -490,8 +490,8 @@ def test_map_property_setitem(): def test_map_property_delitem(): - key = 'key' - value = 'value' + key = 'key731691' + value = 'value731691' prop = map_property(**{key: value}) with constant_refcount(key): @@ -519,11 +519,11 @@ def test_map_property_contains(): def test_map_property_get(): - key = 'key' - value = 'value' + key = 'key861801' + value = 'value861801' prop = map_property(**{key: value}) - default = 'default' + default = 'default861801' with constant_refcount(key): with constant_refcount(default): assert prop.get(key) == value diff --git a/tests/linmath/test_lvector2.py b/tests/linmath/test_lvector2.py index d5aab7f96f..fe37409f3e 100644 --- a/tests/linmath/test_lvector2.py +++ b/tests/linmath/test_lvector2.py @@ -1,30 +1,90 @@ from math import floor, ceil import sys +from panda3d.core import Vec2, Vec3, Vec4, Vec2F, Vec2D import pytest -from panda3d.core import Vec2 - - -original_vector = Vec2(2.3, -2.6) reason = '''Rounding in Python 2.7 expects to return a float value, since it returns a Vector it does not work. When Python 2.7 gets deprecated, remove this check.''' + @pytest.mark.skipif(sys.version_info < (3, 5), reason=reason) def test_round(): + original_vector = Vec2(2.3, -2.6) + rounded_vector = round(original_vector) assert rounded_vector.x == 2 assert rounded_vector.y == -3 + @pytest.mark.skipif(sys.version_info < (3, 5), reason=reason) def test_floor(): + original_vector = Vec2(2.3, -2.6) + rounded_vector = floor(original_vector) assert rounded_vector.x == 2 assert rounded_vector.y == -3 + @pytest.mark.skipif(sys.version_info < (3, 5), reason=reason) def test_ceil(): + original_vector = Vec2(2.3, -2.6) + rounded_vector = ceil(original_vector) assert rounded_vector.x == 3 assert rounded_vector.y == -2 + + +def test_vec2_creation(): + assert Vec2(x=1, y=2) == Vec2(1, 2) == Vec2((1, 2)) + + +def test_vec2_getter_setter(): + original_vector = Vec2(2, 3) + + assert original_vector.x == 2 + assert original_vector.y == 3 + + original_vector.x = 1 + original_vector.y = 3 + + assert original_vector == Vec2(1, 3) + + original_vector[0] = 3 + original_vector[1] = 1 + + assert original_vector == Vec2(3, 1) + + original_vector.set_x(-8) + original_vector.set_y(6) + + assert original_vector.x == -8 + assert original_vector.y == 6 + + +def test_vec2_sum(): + original_vector = Vec2(2, 3) + + assert original_vector + original_vector == Vec2(4, 6) + assert original_vector + 3 == Vec2(5, 6) + + +def test_vec2_power(): + assert Vec2(2, -3) ** 2 == Vec2(4, 9) + + +def test_vec2_len(): + assert len(Vec2(2, -3)) == 2 + + +def test_vec2_swizzle_mask(): + original_vector = Vec2(3, 5) + + assert original_vector.yx == Vec2(5, 3) + assert original_vector.xy == original_vector + + +def test_vec2_str(): + assert str(Vec2F(2, 3)) == "LVector2f(2, 3)" + assert str(Vec2D(2, 3)) == "LVector2d(2, 3)" diff --git a/tests/linmath/test_lvector3.py b/tests/linmath/test_lvector3.py index 7ddefa728c..cbc8c51e9a 100644 --- a/tests/linmath/test_lvector3.py +++ b/tests/linmath/test_lvector3.py @@ -1,18 +1,17 @@ from math import floor, ceil import sys +from panda3d.core import Vec2, Vec3, Vec3F, Vec3D import pytest -from panda3d.core import Vec3 - - -original_vector = Vec3(2.3, -2.6, 3.5) reason = '''Rounding in Python 2.7 expects to return a float value, since it returns a Vector it does not work. When Python 2.7 gets deprecated, remove this check.''' @pytest.mark.skipif(sys.version_info < (3, 5), reason=reason) def test_round(): + original_vector = Vec3(2.3, -2.6, 3.5) + rounded_vector = round(original_vector) assert rounded_vector.x == 2 assert rounded_vector.y == -3 @@ -21,6 +20,8 @@ def test_round(): @pytest.mark.skipif(sys.version_info < (3, 5), reason=reason) def test_floor(): + original_vector = Vec3(2.3, -2.6, 3.5) + rounded_vector = floor(original_vector) assert rounded_vector.x == 2 assert rounded_vector.y == -3 @@ -29,7 +30,67 @@ def test_floor(): @pytest.mark.skipif(sys.version_info < (3, 5), reason=reason) def test_ceil(): + original_vector = Vec3(2.3, -2.6, 3.5) + rounded_vector = ceil(original_vector) assert rounded_vector.x == 3 assert rounded_vector.y == -2 assert rounded_vector.z == 4 + + +def test_vec3_creation(): + assert Vec3(x=1, y=2, z=1) == Vec3(1, 2, 1) == Vec3((1, 2, 1)) + + +def test_vec3_getter_setter(): + original_vector = Vec3(2, 3, 7) + + assert original_vector.x == 2 + assert original_vector.y == 3 + assert original_vector.z == 7 + + original_vector.x = 1 + original_vector.y = 3 + original_vector.z = 5 + + assert original_vector == Vec3(1, 3, 5) + + original_vector[0] = 3 + original_vector[1] = 1 + original_vector[2] = 1 + + assert original_vector == Vec3(3, 1, 1) + + original_vector.set_x(-8) + original_vector.set_y(6) + original_vector.set_z(10) + + assert original_vector.x == -8 + assert original_vector.y == 6 + assert original_vector.z == 10 + + +def test_vec3_sum(): + original_vector = Vec3(2, 3, -2) + + assert original_vector + original_vector == Vec3(4, 6, -4) + assert original_vector + 3 == Vec3(5, 6, 1) + + +def test_vec3_power(): + assert Vec3(2, -3, 2) ** 2 == Vec3(4, 9, 4) + + +def test_vec3_len(): + assert len(Vec3(2, -3, 10)) == 3 + +def test_vec3_swizzle_mask(): + original_vector = Vec3(3, 5, 1) + + assert original_vector.xy == Vec2(3, 5) + assert original_vector.zxy == Vec3(1, 3, 5) + + +def test_vec3_str(): + assert str(Vec3F(2, 3, 1)) == "LVector3f(2, 3, 1)" + assert str(Vec3D(2, 3, 1)) == "LVector3d(2, 3, 1)" diff --git a/tests/linmath/test_lvector4.py b/tests/linmath/test_lvector4.py index 61768f1434..a8ac1797c2 100644 --- a/tests/linmath/test_lvector4.py +++ b/tests/linmath/test_lvector4.py @@ -1,18 +1,17 @@ from math import floor, ceil import sys +from panda3d.core import Vec2, Vec3, Vec4, Vec4F, Vec4D import pytest -from panda3d.core import Vec4 - - -original_vector = Vec4(2.3, -2.6, 3.5, 1) reason = '''Rounding in Python 2.7 expects to return a float value, since it returns a Vector it does not work. When Python 2.7 gets deprecated, remove this check.''' @pytest.mark.skipif(sys.version_info < (3, 5), reason=reason) def test_round(): + original_vector = Vec4(2.3, -2.6, 3.5, 1) + rounded_vector = round(original_vector) assert rounded_vector.x == 2 assert rounded_vector.y == -3 @@ -22,6 +21,8 @@ def test_round(): @pytest.mark.skipif(sys.version_info < (3, 5), reason=reason) def test_floor(): + original_vector = Vec4(2.3, -2.6, 3.5, 1) + rounded_vector = floor(original_vector) assert rounded_vector.x == 2 assert rounded_vector.y == -3 @@ -31,8 +32,75 @@ def test_floor(): @pytest.mark.skipif(sys.version_info < (3, 5), reason=reason) def test_ceil(): + original_vector = Vec4(2.3, -2.6, 3.5, 1) + rounded_vector = ceil(original_vector) assert rounded_vector.x == 3 assert rounded_vector.y == -2 assert rounded_vector.z == 4 assert rounded_vector.w == 1 + + +def test_vec4_creation(): + assert Vec4(x=1, y=2, z=1, w=7) == Vec4(1, 2, 1, 7) == Vec4((1, 2, 1, 7)) + + +def test_vec4_getter_setter(): + original_vector = Vec4(2, 3, 7, 9) + + assert original_vector.x == 2 + assert original_vector.y == 3 + assert original_vector.z == 7 + assert original_vector.w == 9 + + original_vector.x = 1 + original_vector.y = 3 + original_vector.z = 5 + original_vector.w = -8 + + assert original_vector == Vec4(1, 3, 5, -8) + + original_vector[0] = 3 + original_vector[1] = 1 + original_vector[2] = 1 + original_vector[3] = -2 + + assert original_vector == Vec4(3, 1, 1, -2) + + original_vector.set_x(-8) + original_vector.set_y(6) + original_vector.set_z(10) + original_vector.set_w(30) + + assert original_vector.x == -8 + assert original_vector.y == 6 + assert original_vector.z == 10 + assert original_vector.w == 30 + + +def test_vec4_sum(): + original_vector = Vec4(2, 3, -2, 1) + + assert original_vector + original_vector == Vec4(4, 6, -4, 2) + assert original_vector + 3 == Vec4(5, 6, 1, 4) + + +def test_vec4_power(): + assert Vec4(2, -3, 2, -1) ** 2 == Vec4(4, 9, 4, 1) + + +def test_vec4_len(): + assert len(Vec4(2, -3, 10, 30)) == 4 + + +def test_vec4_swizzle_mask(): + original_vector = Vec4(3, 5, 1, 0) + + assert original_vector.xy == Vec2(3, 5) + assert original_vector.zxy == Vec3(1, 3, 5) + assert original_vector.zxyw == Vec4(1, 3, 5, 0) + + +def test_vec4_str(): + assert str(Vec4F(2, 3, 1, 9)) == "LVector4f(2, 3, 1, 9)" + assert str(Vec4D(2, 3, 1, 9)) == "LVector4d(2, 3, 1, 9)" diff --git a/tests/particles/test_particlesystem.py b/tests/particles/test_particlesystem.py index 9e2ff85c20..41dce1ccaf 100644 --- a/tests/particles/test_particlesystem.py +++ b/tests/particles/test_particlesystem.py @@ -101,3 +101,38 @@ def test_particle_soft_start(): system.update(1) assert system.get_living_particles() == 1 + + +def test_particle_burst_emission(): + effect = ParticleEffect() + system = Particles("testSystem", 10) + effect.add_particles(system) + + # Setup some dummy nodes, since it seems to want them + # We might normally call "start", but that calls "enable", which + # seems to assume that "base" exists and has physics and particle managers... + system.setRenderParent(NodePath(PandaNode("test"))) + system.setSpawnRenderNodePath(NodePath(PandaNode("test"))) + # However, we don't want normal emission, so we now soft-stop it immediately, + # before the system has a chance to update and emit. + effect.softStop() + + # Now, a sanity-check: assert that we have no particles, + # Then update the system, and assert again that we + # have no particles. If so, then we're (hopefully) + # not emitting normally! + + assert system.getLivingParticles() == 0 + system.update(1) + assert system.getLivingParticles() == 0 + + # Now, the real test: emit a particle-burst! + effect.birthLitter() + + # And assert that a particle has, in fact, been emitted. + assert system.getLivingParticles() == 1 + + # Check the snake-case version, too. + effect.birth_litter() + + assert system.getLivingParticles() == 2