Compare commits
12 Commits
colobot2
...
coolant-mo
Author | SHA1 | Date |
---|---|---|
|
8885f8476b | |
|
ad048ce60c | |
|
d7cf54c55b | |
|
80840b7c95 | |
|
e11cbae55e | |
|
8553be4ef3 | |
|
9d7fb57067 | |
|
0662424055 | |
|
8e54962c65 | |
|
346c2ee1f3 | |
|
cd49e4a702 | |
|
84585f4ebc |
|
@ -1,211 +0,0 @@
|
|||
name: Build
|
||||
|
||||
on: [push, pull_request]
|
||||
|
||||
jobs:
|
||||
build-linux:
|
||||
runs-on: ${{ matrix.host_os }}
|
||||
container: ${{ matrix.container }}
|
||||
strategy:
|
||||
matrix:
|
||||
target_os: [linux]
|
||||
host_os: [ubuntu-20.04]
|
||||
container: ['']
|
||||
fail-fast: false
|
||||
steps:
|
||||
- name: Install Colobot dependencies
|
||||
run: sudo apt-get update && sudo apt-get install -y --no-install-recommends build-essential cmake libsdl2-dev libsdl2-image-dev libsdl2-ttf-dev libsndfile1-dev libvorbis-dev libogg-dev libpng-dev libglew-dev libopenal-dev libphysfs-dev gettext git po4a vorbis-tools librsvg2-bin xmlstarlet libglm-dev libmpg123-dev
|
||||
if: matrix.container == ''
|
||||
- uses: actions/checkout@v3
|
||||
- name: Checkout the Google Test submodule
|
||||
run: git submodule update --init -- lib/googletest
|
||||
- name: Checkout the nlohmann json submodule
|
||||
run: git submodule update --init -- lib/json
|
||||
- name: Create build directory
|
||||
run: cmake -E make_directory build
|
||||
- name: Run CMake (for Linux)
|
||||
run: cmake --preset Linux-CI
|
||||
if: matrix.target_os == 'linux'
|
||||
- name: Build
|
||||
run: cmake --build --preset Linux-CI
|
||||
- name: Install
|
||||
run: cmake --build --preset Linux-CI --target install
|
||||
- name: Patch library path
|
||||
run: patchelf --set-rpath '.' install/colobot
|
||||
if: matrix.target_os == 'linux'
|
||||
- name: Upload build
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: ${{matrix.target_os}}-debug
|
||||
path: install
|
||||
if: matrix.host_os == 'ubuntu-20.04'
|
||||
- name: Create AppImage
|
||||
working-directory: build
|
||||
run: |
|
||||
# Download app image tool
|
||||
wget -N https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-x86_64.AppImage
|
||||
chmod +x linuxdeploy-x86_64.AppImage
|
||||
./linuxdeploy-x86_64.AppImage --appimage-extract
|
||||
|
||||
# Create AppImage
|
||||
NO_STRIP=1 ./squashfs-root/AppRun -e colobot --output appimage --appdir colobot.AppDir -d desktop/colobot.desktop -i ../desktop/colobot.svg
|
||||
chmod +x Colobot-x86_64.AppImage
|
||||
|
||||
# Prepare folder for zip
|
||||
mkdir -p appimage
|
||||
cp -rp ../install/data appimage/data
|
||||
cp -rp ../install/lang appimage/lang
|
||||
cp -p Colobot-x86_64.AppImage appimage/colobot
|
||||
if: matrix.target_os == 'linux'
|
||||
- name: Upload AppImage
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: ${{matrix.target_os}}-debug-AppImage
|
||||
path: build/appimage
|
||||
if: matrix.target_os == 'linux' && matrix.host_os == 'ubuntu-20.04'
|
||||
- name: Run tests
|
||||
# TODO: Maybe run Windows tests using wine as well?
|
||||
working-directory: build
|
||||
run: ./Colobot-UnitTests --gtest_output=xml:gtestresults.xml
|
||||
if: matrix.target_os == 'linux'
|
||||
- name: Upload test results
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: Test results (${{ matrix.target_os }}, ${{ matrix.host_os }})
|
||||
path: build/gtestresults.xml
|
||||
if: matrix.target_os == 'linux'
|
||||
build-macos:
|
||||
runs-on: ${{ matrix.host_os }}
|
||||
container: ${{ matrix.container }}
|
||||
strategy:
|
||||
matrix:
|
||||
target_os: [macos]
|
||||
host_os: [macos-11, macos-12]
|
||||
container: ['']
|
||||
fail-fast: false
|
||||
steps:
|
||||
- name: Install Colobot dependencies
|
||||
run: brew install cmake sdl2 sdl2_image sdl2_ttf glew physfs flac libsndfile libvorbis vorbis-tools gettext libicns librsvg wget xmlstarlet glm
|
||||
if: matrix.container == ''
|
||||
- uses: actions/checkout@v3
|
||||
- name: Checkout the Google Test submodule
|
||||
run: git submodule update --init -- lib/googletest
|
||||
- name: Checkout the nlohmann json submodule
|
||||
run: git submodule update --init -- lib/json
|
||||
- name: Create build directory
|
||||
run: cmake -E make_directory build
|
||||
- name: Run CMake (for Mac)
|
||||
run: cmake --preset MacOS-CI
|
||||
if: matrix.target_os == 'macos'
|
||||
- name: Build
|
||||
run: cmake --build --preset MacOS-CI
|
||||
- name: Run tests
|
||||
# TODO: Maybe run Windows tests using wine as well?
|
||||
working-directory: build
|
||||
run: ./Colobot-UnitTests --gtest_output=xml:gtestresults.xml
|
||||
if: matrix.target_os == 'macos'
|
||||
- name: Upload test results
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: Test results (${{ matrix.target_os }}, ${{ matrix.host_os }})
|
||||
path: build/gtestresults.xml
|
||||
if: matrix.target_os == 'macos'
|
||||
build-windows:
|
||||
runs-on: windows-2019
|
||||
strategy:
|
||||
matrix:
|
||||
include:
|
||||
- arch: amd64
|
||||
vcpkg_triplet: 'x64-windows-static'
|
||||
- arch: x86
|
||||
vcpkg_triplet: 'x86-windows-static'
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Checkout the Google Test submodule
|
||||
run: git submodule update --init -- lib/googletest
|
||||
- name: Checkout the nlohmann json submodule
|
||||
run: git submodule update --init -- lib/json
|
||||
- name: Install Ninja
|
||||
uses: seanmiddleditch/gha-setup-ninja@master
|
||||
- name: Setup VS Environment
|
||||
uses: seanmiddleditch/gha-setup-vsdevenv@master
|
||||
with:
|
||||
arch: ${{ matrix.arch }}
|
||||
- name: Install Colobot dependencies
|
||||
uses: lukka/run-vcpkg@v7
|
||||
with:
|
||||
setupOnly: true
|
||||
vcpkgGitCommitId: 'f6a5d4e8eb7476b8d7fc12a56dff300c1c986131'
|
||||
vcpkgTriplet: ${{ matrix.vcpkg_triplet }}
|
||||
# SHA-256 hash of the vcpkg.json file, recalculated automatically when it changes
|
||||
appendedCacheKey: ${{ hashFiles( '**/vcpkg.json' ) }}
|
||||
additionalCachedPaths: ${{ github.workspace }}/build/vcpkg_installed
|
||||
- name: Install external tools
|
||||
working-directory: ${{ github.workspace }}
|
||||
run: |
|
||||
echo "Downloading gettext..."
|
||||
(New-Object System.Net.WebClient).DownloadFile("https://github.com/mlocati/gettext-iconv-windows/releases/download/v0.20.2-v1.16/gettext0.20.2-iconv1.16-static-64.zip", "gettext.zip");
|
||||
echo "Unpacking gettext..."
|
||||
7z x -ogettext gettext.zip;
|
||||
echo "Adding gettext to PATH..."
|
||||
echo "${{ github.workspace }}\gettext\bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
|
||||
echo "Downloading xmlstarlet..."
|
||||
(New-Object System.Net.WebClient).DownloadFile("https://downloads.sourceforge.net/project/xmlstar/xmlstarlet/1.6.1/xmlstarlet-1.6.1-win32.zip", "xmlstarlet.zip");
|
||||
echo "Unpacking xmlstarlet..."
|
||||
7z x -oxmlstarlet xmlstarlet.zip;
|
||||
echo "Renaming xml.exe to xmlstarlet.exe"
|
||||
Rename-Item -Path "${{ github.workspace }}\xmlstarlet\xmlstarlet-1.6.1\xml.exe" -NewName "xmlstarlet.exe"
|
||||
echo "Adding xmlstarlet to PATH..."
|
||||
echo "${{ github.workspace }}\xmlstarlet\xmlstarlet-1.6.1" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
|
||||
echo "Downloading rsvg-convert..."
|
||||
(New-Object System.Net.WebClient).DownloadFile("https://downloads.sourceforge.net/project/tumagcc/rsvg-convert-2.40.20.7z", "rsvg-convert.zip");
|
||||
echo "Unpacking xmlstarlet..."
|
||||
7z x -orsvg-convert rsvg-convert.zip;
|
||||
echo "Adding rsvg-convert to PATH..."
|
||||
echo "${{ github.workspace }}\rsvg-convert" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
|
||||
shell: pwsh
|
||||
- name: Create build directory
|
||||
run: cmake -E make_directory build
|
||||
- name: Run CMake (for Windows)
|
||||
run: cmake --preset Windows-CI -DVCPKG_TARGET_TRIPLET=${{ matrix.vcpkg_triplet }} -DCMAKE_TOOLCHAIN_FILE=${{ env.VCPKG_ROOT }}\scripts\buildsystems\vcpkg.cmake
|
||||
- name: Build
|
||||
run: |
|
||||
$nproc = (Get-CIMInstance -Class 'CIM_Processor').NumberOfLogicalProcessors
|
||||
cmake --build --preset Windows-CI -j $nproc
|
||||
shell: pwsh
|
||||
- name: Install
|
||||
run: cmake --build --preset Windows-CI --target install
|
||||
- name: Upload build
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: windows-msvc-debug-${{ matrix.arch }}
|
||||
path: install
|
||||
- name: Run tests
|
||||
working-directory: build
|
||||
run: ./Colobot-UnitTests --gtest_output=xml:gtestresults.xml
|
||||
- name: Upload test results
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: 'Test results (windows, MSVC, ${{ matrix.arch }})'
|
||||
path: build/gtestresults.xml
|
||||
doc:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Install Colobot dependencies
|
||||
run: sudo apt-get update && sudo apt-get install -y --no-install-recommends build-essential cmake libsdl2-dev libsdl2-image-dev libsdl2-ttf-dev libsndfile1-dev libvorbis-dev libogg-dev libpng-dev libglew-dev libopenal-dev libphysfs-dev gettext git po4a vorbis-tools librsvg2-bin xmlstarlet doxygen graphviz libglm-dev libmpg123-dev
|
||||
- uses: actions/checkout@v3
|
||||
- name: Create build directory
|
||||
run: cmake -E make_directory build
|
||||
- name: Checkout the nlohmann json submodule
|
||||
run: git submodule update --init -- lib/json
|
||||
- name: Run CMake
|
||||
working-directory: build
|
||||
run: cmake ..
|
||||
- name: Build docs
|
||||
working-directory: build
|
||||
run: make doc
|
||||
- name: Upload docs
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: doc
|
||||
path: build/doc
|
|
@ -1,21 +0,0 @@
|
|||
name: Verify pull request target
|
||||
|
||||
on: [pull_request_target]
|
||||
|
||||
jobs:
|
||||
check_pr_target:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Send comment if wrong pull request target
|
||||
if: github.base_ref == 'master'
|
||||
uses: peter-evans/create-or-update-comment@v1
|
||||
with:
|
||||
issue-number: ${{ github.event.number }}
|
||||
body: |
|
||||
Hey! This pull request targets the `master` branch. You should probably target `dev` instead. Make sure to read the [contributing guidelines](https://github.com/colobot/colobot/blob/master/CONTRIBUTING.md#submitting-pull-requests) and [edit the target branch if necessary](https://docs.github.com/en/github/collaborating-with-issues-and-pull-requests/changing-the-base-branch-of-a-pull-request).
|
||||
- name: Wrong pull request target
|
||||
if: github.base_ref == 'master'
|
||||
run: echo "This pull request targets the master branch. Please edit the pull request to target dev." && exit 1
|
||||
- name: Correct pull request target
|
||||
if: github.base_ref != 'master'
|
||||
run: echo "This pull request targets the correct branch." && exit 0
|
|
@ -11,12 +11,11 @@ Makefile
|
|||
/src/libcolobotbase.a
|
||||
|
||||
# Ignore the generated documentation
|
||||
CMakeDoxyfile.in
|
||||
CMakeDoxygenDefaults.cmake
|
||||
/doc
|
||||
/Doxyfile
|
||||
|
||||
# Ignore targets
|
||||
/colobot
|
||||
/src/CBot/libCBot.so
|
||||
|
||||
# Ignore local data
|
||||
|
@ -24,7 +23,7 @@ CMakeDoxygenDefaults.cmake
|
|||
/saves
|
||||
|
||||
# Standard build directory
|
||||
/build*
|
||||
/build
|
||||
|
||||
# Ignore KDevelop files
|
||||
.kdev4
|
||||
|
@ -40,13 +39,6 @@ CMakeLists.txt.user.*
|
|||
# Ignore Visual Studio Code files
|
||||
/.vscode
|
||||
|
||||
# Ignore CLion files
|
||||
/.idea
|
||||
|
||||
# Ignore Visual Studio files
|
||||
/CMakeSettings.json
|
||||
/.vs
|
||||
/out
|
||||
|
||||
# Ignore CMakeUserPresets.json
|
||||
CMakeUserPresets.json
|
||||
|
|
|
@ -1,12 +1,3 @@
|
|||
[submodule "data"]
|
||||
path = data
|
||||
url = https://github.com/colobot/colobot-data.git
|
||||
branch = .
|
||||
update = rebase
|
||||
[submodule "lib/googletest"]
|
||||
path = lib/googletest
|
||||
url = https://github.com/google/googletest.git
|
||||
ignore = all
|
||||
[submodule "lib/json"]
|
||||
path = lib/json
|
||||
url = https://github.com/nlohmann/json
|
||||
url = git://github.com/colobot/colobot-data.git
|
||||
|
|
|
@ -1,175 +0,0 @@
|
|||
if(CBOT_STATIC)
|
||||
add_library(CBot STATIC)
|
||||
else()
|
||||
add_library(CBot SHARED)
|
||||
install(TARGETS CBot
|
||||
LIBRARY DESTINATION ${COLOBOT_INSTALL_LIB_DIR}
|
||||
ARCHIVE DESTINATION ${COLOBOT_INSTALL_LIB_DIR}
|
||||
RUNTIME DESTINATION ${COLOBOT_INSTALL_BIN_DIR})
|
||||
endif()
|
||||
|
||||
target_sources(CBot PRIVATE
|
||||
src/CBot/CBot.h
|
||||
src/CBot/CBotCStack.cpp
|
||||
src/CBot/CBotCStack.h
|
||||
src/CBot/CBotClass.cpp
|
||||
src/CBot/CBotClass.h
|
||||
src/CBot/CBotDebug.cpp
|
||||
src/CBot/CBotDebug.h
|
||||
src/CBot/CBotDefParam.cpp
|
||||
src/CBot/CBotDefParam.h
|
||||
src/CBot/CBotDefines.h
|
||||
src/CBot/CBotEnums.h
|
||||
src/CBot/CBotExternalCall.cpp
|
||||
src/CBot/CBotExternalCall.h
|
||||
src/CBot/CBotFileUtils.cpp
|
||||
src/CBot/CBotFileUtils.h
|
||||
src/CBot/CBotInstr/CBotBlock.cpp
|
||||
src/CBot/CBotInstr/CBotBlock.h
|
||||
src/CBot/CBotInstr/CBotBoolExpr.cpp
|
||||
src/CBot/CBotInstr/CBotBoolExpr.h
|
||||
src/CBot/CBotInstr/CBotBreak.cpp
|
||||
src/CBot/CBotInstr/CBotBreak.h
|
||||
src/CBot/CBotInstr/CBotCase.cpp
|
||||
src/CBot/CBotInstr/CBotCase.h
|
||||
src/CBot/CBotInstr/CBotCatch.cpp
|
||||
src/CBot/CBotInstr/CBotCatch.h
|
||||
src/CBot/CBotInstr/CBotCondition.cpp
|
||||
src/CBot/CBotInstr/CBotCondition.h
|
||||
src/CBot/CBotInstr/CBotDefArray.cpp
|
||||
src/CBot/CBotInstr/CBotDefArray.h
|
||||
src/CBot/CBotInstr/CBotDefBoolean.cpp
|
||||
src/CBot/CBotInstr/CBotDefBoolean.h
|
||||
src/CBot/CBotInstr/CBotDefClass.cpp
|
||||
src/CBot/CBotInstr/CBotDefClass.h
|
||||
src/CBot/CBotInstr/CBotDefFloat.cpp
|
||||
src/CBot/CBotInstr/CBotDefFloat.h
|
||||
src/CBot/CBotInstr/CBotDefInt.cpp
|
||||
src/CBot/CBotInstr/CBotDefInt.h
|
||||
src/CBot/CBotInstr/CBotDefString.cpp
|
||||
src/CBot/CBotInstr/CBotDefString.h
|
||||
src/CBot/CBotInstr/CBotDo.cpp
|
||||
src/CBot/CBotInstr/CBotDo.h
|
||||
src/CBot/CBotInstr/CBotEmpty.cpp
|
||||
src/CBot/CBotInstr/CBotEmpty.h
|
||||
src/CBot/CBotInstr/CBotExprLitBool.cpp
|
||||
src/CBot/CBotInstr/CBotExprLitBool.h
|
||||
src/CBot/CBotInstr/CBotExprLitChar.cpp
|
||||
src/CBot/CBotInstr/CBotExprLitChar.h
|
||||
src/CBot/CBotInstr/CBotExprLitNan.cpp
|
||||
src/CBot/CBotInstr/CBotExprLitNan.h
|
||||
src/CBot/CBotInstr/CBotExprLitNull.cpp
|
||||
src/CBot/CBotInstr/CBotExprLitNull.h
|
||||
src/CBot/CBotInstr/CBotExprLitNum.cpp
|
||||
src/CBot/CBotInstr/CBotExprLitNum.h
|
||||
src/CBot/CBotInstr/CBotExprLitString.cpp
|
||||
src/CBot/CBotInstr/CBotExprLitString.h
|
||||
src/CBot/CBotInstr/CBotExprRetVar.cpp
|
||||
src/CBot/CBotInstr/CBotExprRetVar.h
|
||||
src/CBot/CBotInstr/CBotExprUnaire.cpp
|
||||
src/CBot/CBotInstr/CBotExprUnaire.h
|
||||
src/CBot/CBotInstr/CBotExprVar.cpp
|
||||
src/CBot/CBotInstr/CBotExprVar.h
|
||||
src/CBot/CBotInstr/CBotExpression.cpp
|
||||
src/CBot/CBotInstr/CBotExpression.h
|
||||
src/CBot/CBotInstr/CBotFieldExpr.cpp
|
||||
src/CBot/CBotInstr/CBotFieldExpr.h
|
||||
src/CBot/CBotInstr/CBotFor.cpp
|
||||
src/CBot/CBotInstr/CBotFor.h
|
||||
src/CBot/CBotInstr/CBotFunction.cpp
|
||||
src/CBot/CBotInstr/CBotFunction.h
|
||||
src/CBot/CBotInstr/CBotIf.cpp
|
||||
src/CBot/CBotInstr/CBotIf.h
|
||||
src/CBot/CBotInstr/CBotIndexExpr.cpp
|
||||
src/CBot/CBotInstr/CBotIndexExpr.h
|
||||
src/CBot/CBotInstr/CBotInstr.cpp
|
||||
src/CBot/CBotInstr/CBotInstr.h
|
||||
src/CBot/CBotInstr/CBotInstrCall.cpp
|
||||
src/CBot/CBotInstr/CBotInstrCall.h
|
||||
src/CBot/CBotInstr/CBotInstrMethode.cpp
|
||||
src/CBot/CBotInstr/CBotInstrMethode.h
|
||||
src/CBot/CBotInstr/CBotInstrUtils.cpp
|
||||
src/CBot/CBotInstr/CBotInstrUtils.h
|
||||
src/CBot/CBotInstr/CBotLeftExpr.cpp
|
||||
src/CBot/CBotInstr/CBotLeftExpr.h
|
||||
src/CBot/CBotInstr/CBotLeftExprVar.cpp
|
||||
src/CBot/CBotInstr/CBotLeftExprVar.h
|
||||
src/CBot/CBotInstr/CBotListArray.cpp
|
||||
src/CBot/CBotInstr/CBotListArray.h
|
||||
src/CBot/CBotInstr/CBotListExpression.cpp
|
||||
src/CBot/CBotInstr/CBotListExpression.h
|
||||
src/CBot/CBotInstr/CBotListInstr.cpp
|
||||
src/CBot/CBotInstr/CBotListInstr.h
|
||||
src/CBot/CBotInstr/CBotLogicExpr.cpp
|
||||
src/CBot/CBotInstr/CBotLogicExpr.h
|
||||
src/CBot/CBotInstr/CBotNew.cpp
|
||||
src/CBot/CBotInstr/CBotNew.h
|
||||
src/CBot/CBotInstr/CBotParExpr.cpp
|
||||
src/CBot/CBotInstr/CBotParExpr.h
|
||||
src/CBot/CBotInstr/CBotPostIncExpr.cpp
|
||||
src/CBot/CBotInstr/CBotPostIncExpr.h
|
||||
src/CBot/CBotInstr/CBotPreIncExpr.cpp
|
||||
src/CBot/CBotInstr/CBotPreIncExpr.h
|
||||
src/CBot/CBotInstr/CBotRepeat.cpp
|
||||
src/CBot/CBotInstr/CBotRepeat.h
|
||||
src/CBot/CBotInstr/CBotReturn.cpp
|
||||
src/CBot/CBotInstr/CBotReturn.h
|
||||
src/CBot/CBotInstr/CBotSwitch.cpp
|
||||
src/CBot/CBotInstr/CBotSwitch.h
|
||||
src/CBot/CBotInstr/CBotThrow.cpp
|
||||
src/CBot/CBotInstr/CBotThrow.h
|
||||
src/CBot/CBotInstr/CBotTry.cpp
|
||||
src/CBot/CBotInstr/CBotTry.h
|
||||
src/CBot/CBotInstr/CBotTwoOpExpr.cpp
|
||||
src/CBot/CBotInstr/CBotTwoOpExpr.h
|
||||
src/CBot/CBotInstr/CBotWhile.cpp
|
||||
src/CBot/CBotInstr/CBotWhile.h
|
||||
src/CBot/CBotProgram.cpp
|
||||
src/CBot/CBotProgram.h
|
||||
src/CBot/CBotStack.cpp
|
||||
src/CBot/CBotStack.h
|
||||
src/CBot/CBotToken.cpp
|
||||
src/CBot/CBotToken.h
|
||||
src/CBot/CBotTypResult.cpp
|
||||
src/CBot/CBotTypResult.h
|
||||
src/CBot/CBotUtils.cpp
|
||||
src/CBot/CBotUtils.h
|
||||
src/CBot/CBotVar/CBotVar.cpp
|
||||
src/CBot/CBotVar/CBotVar.h
|
||||
src/CBot/CBotVar/CBotVarValue.h
|
||||
src/CBot/CBotVar/CBotVarArray.cpp
|
||||
src/CBot/CBotVar/CBotVarArray.h
|
||||
src/CBot/CBotVar/CBotVarBoolean.cpp
|
||||
src/CBot/CBotVar/CBotVarBoolean.h
|
||||
src/CBot/CBotVar/CBotVarByte.h
|
||||
src/CBot/CBotVar/CBotVarChar.h
|
||||
src/CBot/CBotVar/CBotVarClass.cpp
|
||||
src/CBot/CBotVar/CBotVarClass.h
|
||||
src/CBot/CBotVar/CBotVarDouble.h
|
||||
src/CBot/CBotVar/CBotVarFloat.cpp
|
||||
src/CBot/CBotVar/CBotVarFloat.h
|
||||
src/CBot/CBotVar/CBotVarInt.cpp
|
||||
src/CBot/CBotVar/CBotVarInt.h
|
||||
src/CBot/CBotVar/CBotVarLong.h
|
||||
src/CBot/CBotVar/CBotVarPointer.cpp
|
||||
src/CBot/CBotVar/CBotVarPointer.h
|
||||
src/CBot/CBotVar/CBotVarShort.h
|
||||
src/CBot/CBotVar/CBotVarString.cpp
|
||||
src/CBot/CBotVar/CBotVarString.h
|
||||
src/CBot/stdlib/Compilation.cpp
|
||||
src/CBot/stdlib/Compilation.h
|
||||
src/CBot/stdlib/FileFunctions.cpp
|
||||
src/CBot/stdlib/MathFunctions.cpp
|
||||
src/CBot/stdlib/StringFunctions.cpp
|
||||
src/CBot/stdlib/stdlib.h
|
||||
src/CBot/stdlib/stdlib_public.h
|
||||
)
|
||||
|
||||
target_include_directories(CBot PUBLIC src)
|
||||
target_link_libraries(CBot PRIVATE
|
||||
Colobot-Common
|
||||
)
|
||||
|
||||
if(COLOBOT_LINT_BUILD)
|
||||
add_fake_header_sources("src/CBot" CBot)
|
||||
endif()
|
|
@ -1,165 +0,0 @@
|
|||
/*
|
||||
* This file is part of the Colobot: Gold Edition source code
|
||||
* Copyright (C) 2001-2023, Daniel Roux, EPSITEC SA & TerranovaTeam
|
||||
* http://epsitec.ch; http://colobot.info; http://github.com/colobot
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see http://gnu.org/licenses
|
||||
*/
|
||||
|
||||
#include "CBot/CBotInstr/CBotRepeat.h"
|
||||
|
||||
#include "CBot/CBotInstr/CBotBlock.h"
|
||||
#include "CBot/CBotInstr/CBotExpression.h"
|
||||
|
||||
#include "CBot/CBotCStack.h"
|
||||
#include "CBot/CBotStack.h"
|
||||
|
||||
namespace CBot
|
||||
{
|
||||
|
||||
CBotRepeat::CBotRepeat()
|
||||
{
|
||||
m_expr = nullptr;
|
||||
m_block = nullptr;
|
||||
}
|
||||
|
||||
CBotRepeat::~CBotRepeat()
|
||||
{
|
||||
delete m_expr;
|
||||
delete m_block;
|
||||
}
|
||||
|
||||
CBotInstr* CBotRepeat::Compile(CBotToken* &p, CBotCStack* pStack)
|
||||
{
|
||||
CBotRepeat* inst = new CBotRepeat(); // creates the object
|
||||
CBotToken* pp = p; // preserves at the ^ token (starting position)
|
||||
|
||||
if ( IsOfType( p, TokenTypVar ) && IsOfType( p, ID_DOTS ) )
|
||||
inst->m_label = pp->GetString(); // register the name of label
|
||||
|
||||
inst->SetToken(p);
|
||||
if (!IsOfType(p, ID_REPEAT)) return nullptr; // should never happen
|
||||
|
||||
CBotCStack* pStk = pStack->TokenStack(pp);
|
||||
|
||||
if ( IsOfType(p, ID_OPENPAR ) )
|
||||
{
|
||||
CBotToken* ppp = p; // preserves the ^ token (starting position)
|
||||
if ( nullptr != (inst->m_expr = CBotExpression::Compile( p, pStk )) )
|
||||
{
|
||||
if ( pStk->GetType() < CBotTypLong )
|
||||
{
|
||||
if ( IsOfType(p, ID_CLOSEPAR ) )
|
||||
{
|
||||
IncLvl(inst->m_label);
|
||||
inst->m_block = CBotBlock::CompileBlkOrInst( p, pStk, true );
|
||||
DecLvl();
|
||||
|
||||
if ( pStk->IsOk() ) // the statement block is ok (it may be empty!)
|
||||
return pStack->Return(inst, pStk);
|
||||
}
|
||||
pStack->SetError(CBotErrClosePar, p->GetStart());
|
||||
}
|
||||
pStk->SetStartError(ppp->GetStart());
|
||||
pStk->SetError(CBotErrBadType1, p->GetStart());
|
||||
}
|
||||
pStack->SetError(CBotErrBadNum, p);
|
||||
}
|
||||
pStack->SetError(CBotErrOpenPar, p->GetStart());
|
||||
|
||||
delete inst;
|
||||
return pStack->Return(nullptr, pStk);
|
||||
}
|
||||
|
||||
// execution of intruction "repeat"
|
||||
|
||||
bool CBotRepeat::Execute(CBotStack* &pj)
|
||||
{
|
||||
CBotStack* pile = pj->AddStack(this); // adds an item to the stack
|
||||
// or find in case of recovery
|
||||
if ( pile->IfStep() ) return false;
|
||||
|
||||
while( true ) switch( pile->GetState() ) // executes the loop
|
||||
{ // there are two possible states (depending on recovery)
|
||||
case 0:
|
||||
// evaluates the number of iterations
|
||||
if ( !m_expr->Execute(pile) ) return false; // interrupted here ?
|
||||
|
||||
// the result of the condition is on the stack
|
||||
|
||||
// terminates if an error or if the condition is false
|
||||
int n;
|
||||
if ( !pile->IsOk() || ( n = pile->GetVal() ) < 1 )
|
||||
return pj->Return(pile); // releases the stack
|
||||
|
||||
// puts the number of iterations +1 to the "state"
|
||||
|
||||
if (!pile->SetState(n+1)) return false; // ready for further
|
||||
continue; // continue as a result
|
||||
|
||||
case 1:
|
||||
// normal end of the loop
|
||||
return pj->Return(pile); // releases the stack
|
||||
|
||||
default:
|
||||
// evaluates the associated statement block
|
||||
if ( m_block != nullptr && !m_block->Execute(pile) )
|
||||
{
|
||||
if (pile->IfContinue(pile->GetState()-1, m_label)) continue; // if continued, will return to test
|
||||
return pj->BreakReturn(pile, m_label); // releases the stack
|
||||
}
|
||||
|
||||
// terminates if there is an error
|
||||
if (!pile->IsOk()) return pj->Return(pile); // releases the stack
|
||||
|
||||
// returns to the test again
|
||||
if (!pile->SetState(pile->GetState()-1, 0)) return false;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
void CBotRepeat::RestoreState(CBotStack* &pj, bool bMain)
|
||||
{
|
||||
if ( !bMain ) return;
|
||||
CBotStack* pile = pj->RestoreStack(this); // adds an item to the stack
|
||||
if ( pile == nullptr ) return;
|
||||
|
||||
switch( pile->GetState() )
|
||||
{ // there are two possible states (depending on recovery)
|
||||
case 0:
|
||||
// evaluates the condition
|
||||
m_expr->RestoreState(pile, bMain);
|
||||
return;
|
||||
|
||||
case 1:
|
||||
// evaluates the associated statement block
|
||||
if ( m_block != nullptr ) m_block->RestoreState(pile, bMain);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
std::string CBotRepeat::GetDebugData()
|
||||
{
|
||||
return !m_label.empty() ? "m_label = " + m_label : "";
|
||||
}
|
||||
|
||||
std::map<std::string, CBotInstr*> CBotRepeat::GetDebugLinks()
|
||||
{
|
||||
auto links = CBotInstr::GetDebugLinks();
|
||||
links["m_expr"] = m_expr;
|
||||
links["m_block"] = m_block;
|
||||
return links;
|
||||
}
|
||||
|
||||
} // namespace CBot
|
|
@ -1,62 +0,0 @@
|
|||
/*
|
||||
* This file is part of the Colobot: Gold Edition source code
|
||||
* Copyright (C) 2001-2023, Daniel Roux, EPSITEC SA & TerranovaTeam
|
||||
* http://epsitec.ch; http://colobot.info; http://github.com/colobot
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see http://gnu.org/licenses
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CBot/CBotInstr/CBotInstr.h"
|
||||
|
||||
namespace CBot
|
||||
{
|
||||
|
||||
/**
|
||||
* \brief The "repeat" loop - repeat (times) { ... }
|
||||
*/
|
||||
class CBotRepeat : public CBotInstr
|
||||
{
|
||||
public:
|
||||
CBotRepeat();
|
||||
~CBotRepeat();
|
||||
|
||||
/// Static method used for compilation
|
||||
static CBotInstr* Compile(CBotToken* &p, CBotCStack* pStack);
|
||||
|
||||
/// Execute
|
||||
bool Execute(CBotStack* &pj) override;
|
||||
|
||||
/// Restore state
|
||||
void RestoreState(CBotStack* &pj, bool bMain) override;
|
||||
|
||||
protected:
|
||||
virtual const std::string GetDebugName() override { return "CBotRepeat"; }
|
||||
virtual std::string GetDebugData() override;
|
||||
virtual std::map<std::string, CBotInstr*> GetDebugLinks() override;
|
||||
|
||||
private:
|
||||
/// Number of iterations
|
||||
CBotInstr* m_expr;
|
||||
|
||||
/// Instructions
|
||||
CBotInstr* m_block;
|
||||
|
||||
/// Label
|
||||
std::string m_label; // a label if there is
|
||||
|
||||
};
|
||||
|
||||
} // namespace CBot
|
196
CMakeLists.txt
196
CMakeLists.txt
|
@ -3,21 +3,17 @@
|
|||
# Contains global options and definitions
|
||||
##
|
||||
|
||||
cmake_minimum_required(VERSION 3.21)
|
||||
cmake_minimum_required(VERSION 2.8)
|
||||
|
||||
project(colobot
|
||||
VERSION 0.2.1.0
|
||||
LANGUAGES C CXX
|
||||
)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED YES)
|
||||
set(CMAKE_CXX_EXTENSIONS NO)
|
||||
project(colobot C CXX)
|
||||
|
||||
##
|
||||
# Project version
|
||||
##
|
||||
set(COLOBOT_VERSION_CODENAME "Gold")
|
||||
set(COLOBOT_VERSION_MAJOR 0)
|
||||
set(COLOBOT_VERSION_MINOR 1)
|
||||
set(COLOBOT_VERSION_REVISION 12)
|
||||
|
||||
# Used on official releases
|
||||
#set(COLOBOT_VERSION_RELEASE_CODENAME "-alpha")
|
||||
|
@ -42,10 +38,10 @@ if(DEFINED COLOBOT_VERSION_UNRELEASED)
|
|||
set(COLOBOT_VERSION_DISPLAY "${COLOBOT_VERSION_CODENAME}-${COLOBOT_VERSION_UNRELEASED}")
|
||||
endif()
|
||||
else()
|
||||
set(COLOBOT_VERSION_DISPLAY "${CMAKE_PROJECT_VERSION}${COLOBOT_VERSION_RELEASE_CODENAME}")
|
||||
set(COLOBOT_VERSION_DISPLAY "${COLOBOT_VERSION_MAJOR}.${COLOBOT_VERSION_MINOR}.${COLOBOT_VERSION_REVISION}${COLOBOT_VERSION_RELEASE_CODENAME}")
|
||||
endif()
|
||||
|
||||
set(COLOBOT_VERSION_FULL "${CMAKE_PROJECT_VERSION}${COLOBOT_VERSION_UNRELEASED}${COLOBOT_VERSION_RELEASE_CODENAME}")
|
||||
set(COLOBOT_VERSION_FULL "${COLOBOT_VERSION_MAJOR}.${COLOBOT_VERSION_MINOR}.${COLOBOT_VERSION_REVISION}${COLOBOT_VERSION_UNRELEASED}${COLOBOT_VERSION_RELEASE_CODENAME}")
|
||||
message(STATUS "Building Colobot \"${COLOBOT_VERSION_CODENAME}\" (${COLOBOT_VERSION_FULL})")
|
||||
|
||||
set(BUILD_NUMBER 0)
|
||||
|
@ -106,8 +102,6 @@ elseif("${CMAKE_SYSTEM_NAME}" MATCHES "Darwin")
|
|||
# Platform-dependent implementation of system.h
|
||||
set(SYSTEM_CPP_MODULE "system_macosx.cpp")
|
||||
set(SYSTEM_H_MODULE "system_macosx.h")
|
||||
# Fix compilation errors in MacOS SDK files
|
||||
set(CMAKE_CXX_FLAGS "${NORMAL_CXX_FLAGS} -Wno-nullability-extension -Wno-nullability-completeness -Wno-expansion-to-defined -Wno-four-char-constants -Wno-gnu-zero-variadic-macro-arguments -Wno-variadic-macros -Wno-zero-length-array")
|
||||
# To avoid CMake warning
|
||||
set(CMAKE_MACOSX_RPATH 1)
|
||||
elseif("${CMAKE_SYSTEM_NAME}" MATCHES "FreeBSD")
|
||||
|
@ -148,9 +142,10 @@ endif()
|
|||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
|
||||
|
||||
# Include cmake directory with some additional scripts
|
||||
list(PREPEND CMAKE_MODULE_PATH
|
||||
${PROJECT_SOURCE_DIR}/cmake
|
||||
)
|
||||
set(CMAKE_MODULE_PATH "${colobot_SOURCE_DIR}/cmake" ${CMAKE_MODULE_PATH})
|
||||
|
||||
# MSVC needs different flags if linking statically
|
||||
option(MSVC_STATIC "Link statically when using MSVC" OFF)
|
||||
|
||||
# Compiler detection
|
||||
if(CMAKE_CXX_COMPILER_ID MATCHES "GNU")
|
||||
|
@ -160,7 +155,7 @@ if(CMAKE_CXX_COMPILER_ID MATCHES "GNU")
|
|||
|
||||
message(STATUS "Detected GCC version 4.7+")
|
||||
|
||||
set(NORMAL_CXX_FLAGS "-Wall -Wold-style-cast -pedantic-errors -Wmissing-declarations -lstdc++fs -fPIC")
|
||||
set(NORMAL_CXX_FLAGS "-std=gnu++11 -Wall -Werror -Wold-style-cast -pedantic-errors -Wmissing-declarations")
|
||||
set(NORMAL_CXX_FLAGS "${NORMAL_CXX_FLAGS} -Wno-error=deprecated-declarations") # updated version of physfs is not available on some platforms so we keep using deprecated functions, see #958
|
||||
|
||||
if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.0)
|
||||
|
@ -182,7 +177,7 @@ elseif(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
|
|||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fuse-ld=bfd")
|
||||
endif()
|
||||
|
||||
set(NORMAL_CXX_FLAGS "-Wall -Wold-style-cast -pedantic-errors -Wmissing-prototypes")
|
||||
set(NORMAL_CXX_FLAGS "-std=c++11 -Wall -Werror -Wold-style-cast -pedantic-errors -Wmissing-prototypes")
|
||||
set(NORMAL_CXX_FLAGS "${NORMAL_CXX_FLAGS} -Wno-error=deprecated-declarations") # updated version of physfs is not available on some platforms so we keep using deprecated functions, see #958
|
||||
set(RELEASE_CXX_FLAGS "-O2")
|
||||
set(DEBUG_CXX_FLAGS "-g -O0")
|
||||
|
@ -191,21 +186,19 @@ elseif(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
|
|||
elseif(CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
|
||||
message(STATUS "Detected MSVC compiler")
|
||||
|
||||
# Disable some useless warnings
|
||||
set(NORMAL_CXX_FLAGS "/wd\"4244\" /wd\"4309\" /wd\"4800\" /wd\"4996\" /wd\"4351\"")
|
||||
if(USE_STATIC_RUNTIME)
|
||||
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
|
||||
else()
|
||||
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>DLL")
|
||||
set(NORMAL_CXX_FLAGS "/wd\"4244\" /wd\"4309\" /wd\"4800\" /wd\"4996\" /wd\"4351\" /EHsc") # disable some useless warnings
|
||||
if(MSVC_STATIC)
|
||||
set(RELEASE_CXX_FLAGS "/MT /Ox")
|
||||
set(DEBUG_CXX_FLAGS "/MTd /ZI")
|
||||
else(MSVC_STATIC)
|
||||
set(RELEASE_CXX_FLAGS "/MD /Ox")
|
||||
set(DEBUG_CXX_FLAGS "/MDd /ZI")
|
||||
endif()
|
||||
set(TEST_CXX_FLAGS "")
|
||||
add_definitions(-DNOEXCEPT= -DHAS_MSVC_EXCEPTION_BUG)
|
||||
|
||||
# Increase the stack size to 8 MB (the default is 1 MB), needed for CBOT
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /STACK:8388608")
|
||||
|
||||
# Needed for Debug information (it's set to "No" by default for some reason)
|
||||
set(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS} /DEBUG /NODEFAULTLIB:MSVCRTD /NODEFAULTLIB:LIBCMT")
|
||||
set(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS} /DEBUG")
|
||||
set(CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO "${CMAKE_EXE_LINKER_FLAGS} /DEBUG")
|
||||
else()
|
||||
message(FATAL_ERROR "Your C++ compiler doesn't seem to be supported.")
|
||||
|
@ -216,6 +209,9 @@ endif()
|
|||
# These are specific to GCC/MinGW/clang; for other compilers, change as necessary
|
||||
# The flags are used throughout src/ and test/ subdirs
|
||||
|
||||
# Special flags for boost
|
||||
add_definitions(-DBOOST_NO_SCOPED_ENUMS -DBOOST_NO_CXX11_SCOPED_ENUMS)
|
||||
|
||||
set(COLOBOT_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${NORMAL_CXX_FLAGS}")
|
||||
set(COLOBOT_CXX_FLAGS_RELEASE "${RELEASE_CXX_FLAGS}")
|
||||
set(COLOBOT_CXX_FLAGS_DEBUG "${DEBUG_CXX_FLAGS}")
|
||||
|
@ -232,12 +228,9 @@ option(DEV_BUILD "Enable development build (enables some debugging tools, local
|
|||
|
||||
# Official build - changes text on the crash screen
|
||||
# PLEASE DO NOT USE ON UNOFFICIAL BUILDS. Thanks.
|
||||
option(COLOBOT_OFFICIAL_BUILD "Official build (changes crash screen text)" OFF)
|
||||
option(OFFICIAL_COLOBOT_BUILD "Official build (changes crash screen text)" OFF)
|
||||
|
||||
# Hardcode relative paths instead of absolute paths
|
||||
option(USE_RELATIVE_PATHS "Generate relative paths from absolute paths" OFF)
|
||||
|
||||
# Portable build - load all data from the base directory
|
||||
# Portable build - load all data from current directory
|
||||
option(PORTABLE "Portable build" OFF)
|
||||
|
||||
# Portable saves - suitable for e.g. putting the whole game on external storage and moving your saves with it
|
||||
|
@ -249,6 +242,9 @@ option(TESTS "Build tests" OFF)
|
|||
# Building tool programs can be enabled/disabled
|
||||
option(TOOLS "Build tool programs" OFF)
|
||||
|
||||
# CBot can also be a static library
|
||||
option(CBOT_STATIC "Build CBot as static libary" OFF)
|
||||
|
||||
# Generate desktop files, manpage, etc.
|
||||
option(DESKTOP "Generate desktop files, manpages, etc" ON)
|
||||
|
||||
|
@ -258,24 +254,19 @@ option(INSTALL_DOCS "Install Doxygen-generated documentation" OFF)
|
|||
# Build OpenAL sound support
|
||||
option(OPENAL_SOUND "Build OpenAL sound support" ON)
|
||||
|
||||
# Link runtime library statically (currently only works for MSVC)
|
||||
option(USE_STATIC_RUNTIME "Link the runtime library statically" OFF)
|
||||
|
||||
# CBot can also be a static library
|
||||
option(CBOT_STATIC "Build CBot as static libary" OFF)
|
||||
# This is useful in case you want to use static boost libraries
|
||||
option(BOOST_STATIC "Link with static boost libraries" OFF)
|
||||
|
||||
# This is useful on Windows, if linking against standard GLEW dll fails
|
||||
option(GLEW_STATIC "Link statically with GLEW" OFF)
|
||||
|
||||
# Link statically with LibSndFile
|
||||
option(SNDFILE_STATIC "Link statically with LibSndFile" OFF)
|
||||
|
||||
# Sometimes helpful if there is a different version of gtest installed on system vs bundled
|
||||
option(FORCE_BUNDLED_GTEST "Force the use of bundled gtest" OFF)
|
||||
|
||||
# This is for use with colobot-lint tool
|
||||
option(COLOBOT_LINT_BUILD "Generate some additional CMake targets for use with colobot-lint" OFF)
|
||||
|
||||
|
||||
# Default build type if not given is debug
|
||||
if(NOT CMAKE_BUILD_TYPE)
|
||||
message(STATUS "Build type not specified - assuming debug")
|
||||
|
@ -287,15 +278,6 @@ if(DEV_BUILD)
|
|||
message(STATUS "Building with development extensions")
|
||||
endif()
|
||||
|
||||
##
|
||||
# Additional settings for MSYS
|
||||
##
|
||||
include("${colobot_SOURCE_DIR}/cmake/msys.cmake")
|
||||
|
||||
##
|
||||
# Additional functions for colobot-lint
|
||||
##
|
||||
include("${colobot_SOURCE_DIR}/cmake/colobot-lint.cmake")
|
||||
|
||||
##
|
||||
# Searching for packages
|
||||
|
@ -308,29 +290,22 @@ find_package(SDL2_ttf REQUIRED)
|
|||
find_package(PNG 1.2 REQUIRED)
|
||||
find_package(Gettext REQUIRED)
|
||||
find_package(PhysFS REQUIRED)
|
||||
find_package(glm CONFIG REQUIRED)
|
||||
|
||||
# Add target alias glm::glm for older versions of the library
|
||||
if(NOT TARGET glm::glm)
|
||||
add_library(glm::glm ALIAS glm)
|
||||
endif()
|
||||
set(Boost_USE_STATIC_LIBS ${BOOST_STATIC})
|
||||
set(Boost_USE_MULTITHREADED ON)
|
||||
set(Boost_USE_STATIC_RUNTIME OFF)
|
||||
|
||||
find_package(nlohmann_json 3.10 QUIET)
|
||||
set(Boost_ADDITIONALVERSION "1.51" "1.51.0")
|
||||
find_package(Boost COMPONENTS system filesystem regex REQUIRED)
|
||||
|
||||
if(NOT nlohmann_json_FOUND)
|
||||
message(STATUS "Using nlohmann_json git submodule")
|
||||
set(JSON_BuildTests OFF CACHE INTERNAL "")
|
||||
add_subdirectory(lib/json)
|
||||
endif()
|
||||
|
||||
set(GLEW_USE_STATIC_LIBS ${GLEW_STATIC})
|
||||
find_package(GLEW REQUIRED)
|
||||
|
||||
if (OPENAL_SOUND)
|
||||
find_package(OpenAL REQUIRED)
|
||||
include_directories(${OPENAL_INCLUDE_DIR})
|
||||
find_package(LibSndFile REQUIRED)
|
||||
endif()
|
||||
|
||||
find_package(SndFile REQUIRED)
|
||||
|
||||
if(NOT ASSERTS)
|
||||
add_definitions(-DNDEBUG)
|
||||
|
@ -346,20 +321,43 @@ if(DEV_BUILD)
|
|||
add_definitions(-DDEV_BUILD)
|
||||
endif()
|
||||
|
||||
##
|
||||
# Additional settings to use when cross-compiling with MXE (http://mxe.cc/)
|
||||
##
|
||||
|
||||
include("${colobot_SOURCE_DIR}/cmake/mxe.cmake")
|
||||
|
||||
##
|
||||
# Additional settings for MSYS
|
||||
##
|
||||
include("${colobot_SOURCE_DIR}/cmake/msys.cmake")
|
||||
|
||||
##
|
||||
# Additional functions for colobot-lint
|
||||
##
|
||||
include("${colobot_SOURCE_DIR}/cmake/colobot-lint.cmake")
|
||||
|
||||
|
||||
##
|
||||
# MSVC specific settings
|
||||
##
|
||||
set(WINGETOPT 0)
|
||||
if(MSVC)
|
||||
if(CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
|
||||
message(STATUS "Adding MSVC-specific options")
|
||||
|
||||
set(CBOT_STATIC 1) # only this works for some reason
|
||||
set(WINGETOPT 1) # use wingetopt library
|
||||
|
||||
# Hide console in release builds
|
||||
if(NOT CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||
set(CMAKE_WIN32_EXECUTABLE 1)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
##
|
||||
# Localename
|
||||
##
|
||||
set(LOCALENAME_INCLUDE_DIR ${colobot_SOURCE_DIR}/lib/localename)
|
||||
add_subdirectory(lib/localename)
|
||||
|
||||
|
||||
|
@ -367,6 +365,7 @@ add_subdirectory(lib/localename)
|
|||
# Wingetopt
|
||||
##
|
||||
if(WINGETOPT)
|
||||
set(WINGETOPT_INCLUDE_DIR ${colobot_SOURCE_DIR}/lib/wingetopt/src)
|
||||
add_subdirectory(lib/wingetopt)
|
||||
endif()
|
||||
|
||||
|
@ -391,13 +390,13 @@ endif()
|
|||
##
|
||||
|
||||
# Installation paths defined before compiling sources
|
||||
if(PORTABLE)
|
||||
set(COLOBOT_INSTALL_BIN_DIR ${CMAKE_INSTALL_PREFIX}/ CACHE PATH "Colobot binary directory")
|
||||
set(COLOBOT_INSTALL_LIB_DIR ${CMAKE_INSTALL_PREFIX}/ CACHE PATH "Colobot libraries directory")
|
||||
set(COLOBOT_INSTALL_DATA_DIR ${CMAKE_INSTALL_PREFIX}/data CACHE PATH "Colobot shared data directory")
|
||||
set(COLOBOT_INSTALL_I18N_DIR ${CMAKE_INSTALL_PREFIX}/lang CACHE PATH "Colobot translations directory")
|
||||
set(COLOBOT_INSTALL_DOC_DIR ${CMAKE_INSTALL_PREFIX}/doc CACHE PATH "Colobot documentation directory")
|
||||
set(USE_RELATIVE_PATHS ON)
|
||||
if(PORTABLE OR (PLATFORM_WINDOWS AND MXE))
|
||||
# We need to use STRING because PATH doesn't accept relative paths
|
||||
set(COLOBOT_INSTALL_BIN_DIR ./ CACHE STRING "Colobot binary directory")
|
||||
set(COLOBOT_INSTALL_LIB_DIR ./ CACHE STRING "Colobot libraries directory")
|
||||
set(COLOBOT_INSTALL_DATA_DIR ./data CACHE STRING "Colobot shared data directory")
|
||||
set(COLOBOT_INSTALL_I18N_DIR ./lang CACHE STRING "Colobot translations directory")
|
||||
set(COLOBOT_INSTALL_DOC_DIR ./doc CACHE STRING "Colobot documentation directory")
|
||||
elseif(PLATFORM_WINDOWS)
|
||||
set(COLOBOT_INSTALL_BIN_DIR ${CMAKE_INSTALL_PREFIX}/ CACHE PATH "Colobot binary directory")
|
||||
set(COLOBOT_INSTALL_LIB_DIR ${CMAKE_INSTALL_PREFIX}/ CACHE PATH "Colobot libraries directory")
|
||||
|
@ -418,63 +417,36 @@ else()
|
|||
set(COLOBOT_INSTALL_DOC_DIR ${CMAKE_INSTALL_PREFIX}/share/doc/colobot CACHE PATH "Colobot documentation directory")
|
||||
endif()
|
||||
|
||||
# Generate relative paths from absolute paths
|
||||
if(USE_RELATIVE_PATHS)
|
||||
message(STATUS "Generating relative paths")
|
||||
file(RELATIVE_PATH COLOBOT_DATA_DIR ${COLOBOT_INSTALL_BIN_DIR} ${COLOBOT_INSTALL_DATA_DIR})
|
||||
file(RELATIVE_PATH COLOBOT_I18N_DIR ${COLOBOT_INSTALL_BIN_DIR} ${COLOBOT_INSTALL_I18N_DIR})
|
||||
|
||||
add_definitions(-DUSE_RELATIVE_PATHS)
|
||||
else()
|
||||
set(COLOBOT_DATA_DIR ${COLOBOT_INSTALL_DATA_DIR})
|
||||
set(COLOBOT_I18N_DIR ${COLOBOT_INSTALL_I18N_DIR})
|
||||
endif()
|
||||
|
||||
# Subdirectory with common implementation
|
||||
add_subdirectory(colobot-common)
|
||||
|
||||
# Add CBot
|
||||
add_subdirectory(CBot)
|
||||
|
||||
# Add base Colobot implementation
|
||||
add_subdirectory(colobot-base)
|
||||
|
||||
# Add Colobot executable
|
||||
add_subdirectory(colobot-app)
|
||||
# Subdirectory with sources
|
||||
add_subdirectory(src)
|
||||
|
||||
add_subdirectory(po)
|
||||
|
||||
if(TOOLS)
|
||||
add_subdirectory(tools)
|
||||
endif()
|
||||
|
||||
if(DESKTOP)
|
||||
add_subdirectory(desktop)
|
||||
endif()
|
||||
|
||||
if(TESTS)
|
||||
# Google Test library
|
||||
find_package(GTest 1.11.0 QUIET)
|
||||
if(NOT(FORCE_BUNDLED_GTEST) AND GTEST_FOUND)
|
||||
message(STATUS "Using system gtest library in ${GTEST_BOTH_LIBRARIES}")
|
||||
elseif(EXISTS "${colobot_SOURCE_DIR}/lib/googletest/googletest/CMakeLists.txt")
|
||||
message(STATUS "Using gtest git submodule")
|
||||
set(GOOGLETEST_VERSION "1.11.0")
|
||||
add_subdirectory("${colobot_SOURCE_DIR}/lib/googletest/googletest" "lib/googletest/googletest")
|
||||
# Add aliases so target names are compatible with the find_package above
|
||||
add_library(GTest::GTest ALIAS gtest)
|
||||
add_library(GTest::Main ALIAS gtest_main)
|
||||
find_path(GTEST_SRC_DIR NAMES src/gtest.cc src/gtest-all.cc PATHS /usr/src PATH_SUFFIXES gtest)
|
||||
find_path(GTEST_INCLUDE_DIR gtest/gtest.h PATHS /usr/include)
|
||||
if(NOT(FORCE_BUNDLED_GTEST) AND GTEST_SRC_DIR AND GTEST_INCLUDE_DIR)
|
||||
message(STATUS "Using system gtest library in ${GTEST_SRC_DIR}")
|
||||
else()
|
||||
message(FATAL_ERROR "Could not find gtest, cannot enable testing")
|
||||
message(STATUS "Using bundled gtest library")
|
||||
set(GTEST_SRC_DIR ${colobot_SOURCE_DIR}/lib/gtest)
|
||||
set(GTEST_INCLUDE_DIR ${colobot_SOURCE_DIR}/lib/gtest/include)
|
||||
endif()
|
||||
|
||||
add_subdirectory(${GTEST_SRC_DIR} lib/gtest)
|
||||
|
||||
# Hippomocks library
|
||||
add_subdirectory(${colobot_SOURCE_DIR}/lib/hippomocks)
|
||||
set(HIPPOMOCKS_INCLUDE_DIR ${colobot_SOURCE_DIR}/lib/hippomocks)
|
||||
|
||||
# Tests targets
|
||||
enable_testing()
|
||||
include(GoogleTest)
|
||||
add_subdirectory(test)
|
||||
|
||||
endif()
|
||||
|
||||
|
||||
|
|
|
@ -1,83 +0,0 @@
|
|||
{
|
||||
"version": 3,
|
||||
"cmakeMinimumRequired": {
|
||||
"major": 3,
|
||||
"minor": 21,
|
||||
"patch": 0
|
||||
},
|
||||
"configurePresets": [
|
||||
{
|
||||
"name": "CI",
|
||||
"description": "Base configuration for CI pipeline",
|
||||
"hidden": true,
|
||||
"binaryDir": "${sourceDir}/build",
|
||||
"installDir": "${sourceDir}/install"
|
||||
},
|
||||
{
|
||||
"name": "Windows-CI",
|
||||
"description": "Windows configuration for CI pipeline",
|
||||
"generator": "Ninja",
|
||||
"inherits": ["CI"],
|
||||
"cacheVariables": {
|
||||
"CMAKE_C_COMPILER": "cl.exe",
|
||||
"CMAKE_CXX_COMPILER": "cl.exe",
|
||||
"CMAKE_BUILD_TYPE": "RelWithDebInfo",
|
||||
"USE_STATIC_RUNTIME": true,
|
||||
"CBOT_STATIC": true,
|
||||
"GLEW_STATIC": true,
|
||||
"SNDFILE_STATIC": true,
|
||||
"DEV_BUILD": true,
|
||||
"PORTABLE": true,
|
||||
"TOOLS": true,
|
||||
"TESTS": true,
|
||||
"DESKTOP": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Linux-CI",
|
||||
"description": "Linux configuration for CI pipeline",
|
||||
"inherits": ["CI"],
|
||||
"cacheVariables": {
|
||||
"CMAKE_SKIP_INSTALL_RPATH": true,
|
||||
"CMAKE_BUILD_TYPE": "RelWithDebInfo",
|
||||
"CBOT_STATIC": true,
|
||||
"DEV_BUILD": true,
|
||||
"PORTABLE": true,
|
||||
"TOOLS": true,
|
||||
"TESTS": true,
|
||||
"DESKTOP": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "MacOS-CI",
|
||||
"description": "MacOS configuration for CI pipeline",
|
||||
"inherits": ["CI"],
|
||||
"cacheVariables": {
|
||||
"CMAKE_SKIP_INSTALL_RPATH": true,
|
||||
"CMAKE_BUILD_TYPE": "RelWithDebInfo",
|
||||
"DEV_BUILD": true,
|
||||
"PORTABLE": true,
|
||||
"TESTS": true,
|
||||
"DESKTOP": true,
|
||||
"OPENAL_LIBRARY": "/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/System/Library/Frameworks/OpenAL.framework/OpenAL.tbd"
|
||||
}
|
||||
}
|
||||
],
|
||||
"buildPresets": [
|
||||
{
|
||||
"name": "Windows-CI",
|
||||
"configurePreset": "Windows-CI",
|
||||
"configuration": "RelWithDebInfo"
|
||||
},
|
||||
{
|
||||
"name": "Linux-CI",
|
||||
"configurePreset": "Linux-CI",
|
||||
"configuration": "RelWithDebInfo"
|
||||
},
|
||||
{
|
||||
"name": "MacOS-CI",
|
||||
"configurePreset": "MacOS-CI",
|
||||
"configuration": "RelWithDebInfo"
|
||||
}
|
||||
]
|
||||
}
|
|
@ -3,30 +3,24 @@
|
|||
So you want to contribute to Colobot: Gold Edition? That's awesome! Before you start, read this page, it contains a lot of useful information on how to do so.
|
||||
|
||||
## General information
|
||||
|
||||
Before you start, read more about technical details of the project. They can be found in:
|
||||
|
||||
* [Developer README](docs/README-dev.md)
|
||||
* [Doxygen documentation (doc)](https://github.com/colobot/colobot/actions)
|
||||
* [Working with translations](https://github.com/colobot/colobot/wiki/Working-with-translations)
|
||||
* [Working with models](https://github.com/colobot/colobot/wiki/Working-with-Colobot:-Gold-Edition-models)
|
||||
* [Common issues](https://github.com/colobot/colobot/wiki/Common-Issues)
|
||||
* [Developer README](README-dev.md)
|
||||
* [Doxygen documentation](http://compiled.colobot.info/job/colobot/job/colobot/job/dev/Doxygen/)
|
||||
* [Game Design Document](http://compiled.colobot.info/job/colobot/job/colobot-misc/job/master/lastSuccessfulBuild/artifact/Colobot_Gold_Edition-Game_Design_Document.pdf)
|
||||
|
||||
## Before you start coding
|
||||
|
||||
* If you want to fix a bug, please first check the related [issue on GitHub's bug tracker](https://github.com/colobot/colobot/issues). If there isn't one, make it.
|
||||
* If you want to add a new feature or make any change to gameplay, please first discuss it either [on Discord](https://discord.gg/56Fm9kb) or in the related issue on GitHub. When your issue gets *accepted* label, that means that your suggestion got accepted and is waiting for somebody to work on it. Always wait for your suggestion to be accepted before you start writing any code.
|
||||
* If you want to add a new feature or make any change to gameplay, please first discuss it either [on the forums](http://colobot.info/forum) or in the related issue on GitHub. When your issue gets *accepted* label, that means that your suggestion got accepted and is waiting for somebody to work on it. Always wait for your suggestion to be accepted before you start writing any code.
|
||||
* Before you start, check *"Assignee"* field in the issue and read the comments to see if nobody else is working on the same issue. If somebody is assigned to it, but there was no activity for a long time, you can take it over. Also, please post a comment on the issue that you want to help us, so other people don't waste time working at that issue in the same time.
|
||||
|
||||
## Coding style
|
||||
|
||||
When writing code, please adhere to the following rules:
|
||||
|
||||
* Indent with spaces, 1 indentation level = 4 spaces. Unix line endings. And don't leave whitespace at the end of lines. Thank you.
|
||||
* Put braces in new lines.
|
||||
|
||||
Like that:
|
||||
|
||||
```c++
|
||||
if (a == b)
|
||||
{
|
||||
|
@ -37,9 +31,7 @@ Like that:
|
|||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
NOT like that:
|
||||
|
||||
```c++
|
||||
if (a == b) {
|
||||
// ...
|
||||
|
@ -47,14 +39,11 @@ NOT like that:
|
|||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
You may omit braces if there is only one line in block:
|
||||
|
||||
```c++
|
||||
if (a == b)
|
||||
doStuff();
|
||||
```
|
||||
|
||||
* Name functions beginning with upper case, e.g. `FooBar()`
|
||||
* Name classes beginning with C, e.g. `class CSomeClass`
|
||||
* Name accessors like so: `SetValue()` and `GetValue()`
|
||||
|
@ -81,7 +70,6 @@ We also have an automated tool for checking the code style. See [colobot-lint re
|
|||
If your pull request breaks the coding style, you will have to fix it before it gets merged.
|
||||
|
||||
## Commiting rules
|
||||
|
||||
Please adhere to the following rules:
|
||||
* Commits should have meaningful descriptions.
|
||||
* Commits should not break the build nor tests.
|
||||
|
@ -89,11 +77,9 @@ Please adhere to the following rules:
|
|||
* Merges to *master* branch must be discussed beforehand and should include fully finished features if possible.
|
||||
|
||||
## Submitting pull requests
|
||||
|
||||
After you finish working on your issue and want your code to be merged into the main repository, you should submit a **pull request**. Go to [this page](https://github.com/colobot/colobot/pulls) and select "New pull request". All pull requests should ALWAYS be submitted to the *dev* branch. After your PR gets reviewed by our development team, it will be merged to *dev* branch, and on the next release - to the *master* branch.
|
||||
|
||||
If you need more help, see [GitHub's help page on Pull Requests](https://help.github.com/articles/using-pull-requests/).
|
||||
|
||||
## Need help?
|
||||
|
||||
Ask on our [Discord server](https://discord.gg/56Fm9kb) or [GitHub Discussions](https://github.com/colobot/colobot/discussions). We're here to help :)
|
||||
Ask on our official Freenode channel (#colobot @ irc.freenode.net) or on our [forums](http://colobot.info/forum/). We're here to help :)
|
||||
|
|
|
@ -859,7 +859,7 @@ EXAMPLE_RECURSIVE = NO
|
|||
# that contain images that are to be included in the documentation (see the
|
||||
# \image command).
|
||||
|
||||
IMAGE_PATH = "@CMAKE_CURRENT_SOURCE_DIR@/docs/images"
|
||||
IMAGE_PATH = "@CMAKE_CURRENT_SOURCE_DIR@/docimg"
|
||||
|
||||
# The INPUT_FILTER tag can be used to specify a program that doxygen should
|
||||
# invoke to filter for each input file. Doxygen will invoke the filter program
|
||||
|
|
|
@ -110,7 +110,7 @@ Easy, isn't it?
|
|||
If you are lazy, you can just use this one-line command, although there is no guarantee it will work or install everything (might be out of date):
|
||||
|
||||
```sh
|
||||
pacman -S mingw-w64-i686-glew mingw-w64-i686-libpng gettext mingw-w64-i686-gettext mingw-w64-i686-libpng mingw-w64-i686-libsndfile mingw-w64-i686-libvorbis mingw-w64-i686-libogg mingw-w64-i686-openal mingw-w64_i686-physfs mingw-w64-i686-SDL2 mingw-w64-i686-SDL2_image mingw-w64-i686-SDL2_ttf
|
||||
pacman -S mingw-w64-i686-boost mingw-w64-i686-glew mingw-w64-i686-libpng gettext mingw-w64-i686-gettext mingw-w64-i686-libpng mingw-w64-i686-libsndfile mingw-w64-i686-libvorbis mingw-w64-i686-libogg mingw-w64-i686-openal mingw-w64-i686-SDL2 mingw-w64-i686-SDL2_image mingw-w64-i686-SDL2_ttf
|
||||
```
|
||||
|
||||
You should now have everything set up and working. You can close all instances of MSYS2 and autorebase to ensure everything installed properly.
|
|
@ -0,0 +1,91 @@
|
|||
# Cross-compiling with MXE
|
||||
|
||||
MXE works for any BSD-compatible system (including Linux).
|
||||
It is a complete package with cross-compiler to Win32 (a MinGW variant)
|
||||
and includes scripts to automatically download and build many 3rd party
|
||||
libraries and tools.
|
||||
|
||||
To cross-compile Colobot using MXE:
|
||||
|
||||
1. See the MXE website (http://mxe.cc) for list of required packages and make sure
|
||||
you have them installed.
|
||||
|
||||
2. Download MXE and unpack it in the directory, where you want to keep it
|
||||
permanently. During the build, MXE will write that path to many files,
|
||||
so moving that directory can be tricky.
|
||||
|
||||
3. `cd` to the MXE root directory.
|
||||
It already contains a universal Makefile for everything.
|
||||
Usage is simply `make name_of_package`.
|
||||
It will automatically check for dependencies, etc.
|
||||
The packages will be installed in the MXE directory under `usr/i686-w64-mingw32.static`.
|
||||
|
||||
You need to `make gcc` first for basic compiler and then do the same
|
||||
for some additional libraries. In the end, you should have the following
|
||||
packages installed (this is the final listing of `usr/i686-w64-mingw32.static/installed/`):
|
||||
* binutils
|
||||
* boost
|
||||
* bzip2
|
||||
* cairo
|
||||
* dbus
|
||||
* expat
|
||||
* flac
|
||||
* fontconfig
|
||||
* freetype
|
||||
* freetype-bootstrap
|
||||
* gcc
|
||||
* gcc-gmp
|
||||
* gcc-isl
|
||||
* gcc-mpc
|
||||
* gcc-mpfr
|
||||
* gettext
|
||||
* glew
|
||||
* glib
|
||||
* harfbuzz
|
||||
* icu4c
|
||||
* jpeg
|
||||
* libffi
|
||||
* libiconv
|
||||
* libpng
|
||||
* libsndfile
|
||||
* libwebp
|
||||
* lzo
|
||||
* mingw-w64
|
||||
* mxe-conf
|
||||
* ogg
|
||||
* openal
|
||||
* pcre
|
||||
* physfs
|
||||
* pixman
|
||||
* pkgconf
|
||||
* portaudio
|
||||
* sdl2
|
||||
* sdl2_image
|
||||
* sdl2_ttf
|
||||
* tiff
|
||||
* vorbis
|
||||
* xz
|
||||
* zlib
|
||||
|
||||
4. Now `cd` to directory with colobot sources.
|
||||
It is recommended that you create a separate directory for out-of-source build:
|
||||
`mkdir build-mxe && cd build-mxe`
|
||||
|
||||
In order to cross-compile a CMake project, you have to specify a CMake toolchain file.
|
||||
MXE has such file in MXE's directory: `usr/i686-w64-mingw32.static/share/cmake/mxe-conf.cmake`
|
||||
So you should use the following cmake command: `cmake -DCMAKE_TOOLCHAIN_FILE=/path/to/mxe-conf.cmake ..`
|
||||
CMake files in Colobot should detect that MXE is being used and they will
|
||||
modify flags, paths, etc. as required. You should not run into any problems.
|
||||
|
||||
5. `make` should now compile the game with the resulting executable as `colobot.exe`.
|
||||
The exe is linked against all libraries *statically*, so there are no dependencies
|
||||
on external DLLs. However, the resulting binary will be huge with all these libraries,
|
||||
so you might want to do: `strip colobot.exe`.
|
||||
|
||||
6. If you want to create a Colobot installer, you need to additionally build `nsis`
|
||||
in MXE. Then you can create the NSIS installer that way:
|
||||
`PATH=/path/to/mxe/binaries:$PATH make package`
|
||||
where `/path/to/mxe/binaries` is path to cross-compiled MXE binaries available
|
||||
in MXE's directory under `usr/i686-w64-mingw32.static/bin`.
|
||||
This will create a versioned colobot-$version.exe installer that will install Colobot
|
||||
in system directories, add a shortcut in the start menu and setup an uninstaller.
|
|
@ -4,11 +4,11 @@ To compile Colobot on MacOS X, you need to first get Developer Command Line Tool
|
|||
|
||||
After installing Developer Command Line Tools, you should have basic tools like clang and git installed. After that, you can grab other required packages with Homebrew. So as in instructions on [the project page](http://brew.sh/):
|
||||
```bash
|
||||
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
|
||||
ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
|
||||
```
|
||||
And then:
|
||||
```bash
|
||||
brew install cmake sdl2 sdl2_image sdl2_ttf glew physfs flac libsndfile libvorbis vorbis-tools gettext libicns librsvg wget xmlstarlet
|
||||
brew install cmake sdl2 sdl2_image sdl2_ttf boost glew physfs flac libsndfile libvorbis vorbis-tools gettext libicns librsvg wget xmlstarlet
|
||||
```
|
||||
Gettext is installed in separate directory without adding the files to system path, so in order to get it working normally, you should call also:
|
||||
```bash
|
||||
|
@ -20,7 +20,7 @@ If you've installed everything correctly, the simple way of compiling Colobot wi
|
|||
git clone --recursive https://github.com/colobot/colobot.git
|
||||
mkdir colobot/build
|
||||
cd colobot/build
|
||||
cmake -DOPENAL_LIBRARY=/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/System/Library/Frameworks/OpenAL.framework/OpenAL.tbd ../
|
||||
cmake ../
|
||||
make
|
||||
```
|
||||
|
40
INSTALL.md
40
INSTALL.md
|
@ -27,15 +27,24 @@ any of the missions.
|
|||
|
||||
### Compiling on Windows
|
||||
|
||||
You can also compile directly on Windows with MSYS2/MinGW-w64 or Visual Studio since version 2015.
|
||||
The recommended way of compiling for Windows is using Linux in a cross-compilation environment called MXE.
|
||||
This is the way our build bot service (http://compiled.colobot.info/) prepares the release packages.
|
||||
You can also compile directly on Windows with MSYS2/MinGW-w64 or MSVC 2013 but this is a bit more difficult to set up.
|
||||
|
||||
#### Cross-compiling using MXE
|
||||
|
||||
MXE (M cross environment, http://mxe.cc/) is a very good cross-compiling framework, complete with a suite of libraries
|
||||
that make it extremely easy to port applications to Win32. It runs on pretty much any *nix flavor and generates generic,
|
||||
statically linked Win32 binaries. More information is available in
|
||||
[INSTALL-MXE.md](INSTALL-MXE.md) file.
|
||||
|
||||
#### Compiling with MSYS2/MinGW-w64
|
||||
|
||||
See the [INSTALL-MSYS2.md](docs/INSTALL-MSYS2.md) file for details.
|
||||
See the [INSTALL-MSYS2.md](INSTALL-MSYS2.md) file for details.
|
||||
|
||||
#### Compiling with MSVC (Visual Studio)
|
||||
#### Compiling with MSVC
|
||||
|
||||
See [this wiki page](https://github.com/colobot/colobot/wiki/How-to-Build-Colobot:-Gold-Edition-Using-MSVC) for details.
|
||||
As of 0.1.5-alpha it's possible to compile binary with MSVC 2013. See [this post](http://colobot.info/forum/showthread.php?tid=595&pid=5831#pid5831) for details.
|
||||
|
||||
|
||||
### Compiling on Linux
|
||||
|
@ -44,24 +53,25 @@ Since there are so many Linux flavors, it is difficult to write generic instruct
|
|||
you will need to compile colobot.
|
||||
|
||||
You will need:
|
||||
* C++17 compiler
|
||||
* CMake >= 3.16
|
||||
* recent compiler (GCC >= 4.7, or Clang >= 3.1) since we are using some features of C++11
|
||||
* CMake >= 2.8
|
||||
* Boost >= 1.51 (header files + components: filesystem and regex)
|
||||
* SDL2
|
||||
* SDL2_image
|
||||
* SDL2_ttf
|
||||
* GLEW
|
||||
* libpng
|
||||
* gettext
|
||||
* libsndfile
|
||||
* libvorbis
|
||||
* libogg
|
||||
* OpenAL (OpenAL-Soft)
|
||||
* GLEW >= 1.8.0
|
||||
* libpng >= 1.2
|
||||
* gettext >= 0.18
|
||||
* libsndfile >= 1.0.25
|
||||
* libvorbis >= 1.3.2
|
||||
* libogg >= 1.3.0
|
||||
* OpenAL (OpenAL-Soft) >= 1.13
|
||||
* PhysFS
|
||||
* oggenc (to generate music files)
|
||||
|
||||
On Ubuntu (and probably any other Debian-based system), you can use the following command to install all required packages:
|
||||
```
|
||||
$ apt-get install build-essential cmake libsdl2-dev libsdl2-image-dev libsdl2-ttf-dev libsndfile1-dev libvorbis-dev libogg-dev libpng-dev libglew-dev libopenal-dev libphysfs-dev gettext git po4a vorbis-tools
|
||||
$ apt-get install build-essential cmake libsdl2-dev libsdl2-image-dev libsdl2-ttf-dev libsndfile1-dev libvorbis-dev libogg-dev libpng-dev libglew-dev libopenal-dev libboost-dev libboost-system-dev libboost-filesystem-dev libboost-regex-dev libphysfs-dev gettext git po4a vorbis-tools
|
||||
```
|
||||
|
||||
Make sure you install the packages along with header files (often distributed in separate *-dev packages). If you miss any requirements,
|
||||
|
@ -115,7 +125,7 @@ So if you provided prefix "/some/prefix", you can run:
|
|||
|
||||
### Compiling on MacOS X
|
||||
|
||||
As of 0.1.2-alpha, we have added MacOS X support. See [INSTALL-MacOSX.md](docs/INSTALL-MacOSX.md)
|
||||
As of 0.1.2-alpha, we have added MacOS X support. See [INSTALL-MacOSX.md](INSTALL-MacOSX.md)
|
||||
file for details.
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,295 @@
|
|||
#!/usr/bin/env groovy
|
||||
|
||||
pipeline {
|
||||
agent none
|
||||
options {
|
||||
buildDiscarder(logRotator(artifactDaysToKeepStr: '30', artifactNumToKeepStr: '20'))
|
||||
}
|
||||
stages {
|
||||
stage('Check pull request target') {
|
||||
when { changeRequest() }
|
||||
steps {
|
||||
script {
|
||||
if (env.CHANGE_TARGET == 'master') {
|
||||
throw "This pull request targets the wrong branch. Please reopen the pull request targetting the dev branch."
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
stage('Build') {
|
||||
parallel {
|
||||
stage('Build Windows') {
|
||||
agent {
|
||||
docker { image 'krzysh/colobot-build:latest' }
|
||||
}
|
||||
steps {
|
||||
sh 'mkdir -p build/windows'
|
||||
dir('build/windows') {
|
||||
sh '''
|
||||
# FIXME: without -lsetupapi linking sdl2 fails
|
||||
/opt/mxe/usr/bin/i686-w64-mingw32.static-cmake \
|
||||
-DCMAKE_CXX_STANDARD_LIBRARIES="-lkernel32 -luser32 -lgdi32 -lwinspool -lshell32 -lole32 -loleaut32 -luuid -lcomdlg32 -ladvapi32 -lsetupapi" \
|
||||
-DCMAKE_INSTALL_PREFIX=/install \
|
||||
-DCMAKE_BUILD_TYPE=RelWithDebInfo -DDEV_BUILD=1 -DPORTABLE=1 -DTOOLS=1 -DTESTS=0 ../..
|
||||
make
|
||||
rm -rf install
|
||||
DESTDIR=. make install
|
||||
'''
|
||||
}
|
||||
}
|
||||
post {
|
||||
success {
|
||||
sh 'rm -f windows-debug.zip'
|
||||
zip zipFile: 'windows-debug.zip', archive: true, dir: 'build/windows/install'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
stage('Build Linux') {
|
||||
agent {
|
||||
docker { image 'krzysh/colobot-build:latest' }
|
||||
}
|
||||
steps {
|
||||
sh 'mkdir -p build/linux'
|
||||
dir('build/linux') {
|
||||
sh '''
|
||||
cmake \
|
||||
-DCMAKE_INSTALL_PREFIX=/install -DCMAKE_SKIP_INSTALL_RPATH=ON \
|
||||
-DCMAKE_BUILD_TYPE=RelWithDebInfo -DDEV_BUILD=1 -DPORTABLE=1 -DTOOLS=1 -DTESTS=1 -DDESKTOP=1 ../..
|
||||
make
|
||||
rm -rf install
|
||||
DESTDIR=. make install
|
||||
patchelf --set-rpath '.' install/colobot
|
||||
'''
|
||||
}
|
||||
}
|
||||
post {
|
||||
success {
|
||||
sh 'rm -f linux-debug.zip'
|
||||
dir('build/linux') {
|
||||
sh '''
|
||||
# Clean up
|
||||
rm -rf squashfs-root
|
||||
rm -rf colobot.AppDir
|
||||
rm -rf appimage
|
||||
rm -f Colobot-x86_64.AppImage
|
||||
|
||||
# Download app image tool
|
||||
wget -N https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-x86_64.AppImage
|
||||
chmod +x linuxdeploy-x86_64.AppImage
|
||||
./linuxdeploy-x86_64.AppImage --appimage-extract
|
||||
|
||||
# Create AppImage
|
||||
NO_STRIP=1 ./squashfs-root/AppRun -e colobot --output appimage --appdir colobot.AppDir -d desktop/colobot.desktop -i ../../desktop/colobot.svg
|
||||
#rename AppImage file to avoid "No such file or directory" errors
|
||||
find . -maxdepth 1 -type f -name '*AppImage' -name 'Colobot*' -exec sh -c 'x="{}"; mv "$x" "Colobot-x86_64.AppImage"' \\;
|
||||
chmod +x Colobot-x86_64.AppImage
|
||||
|
||||
# Prepare folder for zip
|
||||
mkdir -p appimage
|
||||
cp -rp install/data appimage/data
|
||||
cp -rp install/lang appimage/lang
|
||||
cp -p Colobot-x86_64.AppImage appimage/colobot
|
||||
'''
|
||||
}
|
||||
zip zipFile: 'linux-debug.zip', archive: true, dir: 'build/linux/appimage'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
stage('Generate docs') {
|
||||
agent {
|
||||
docker { image 'krzysh/colobot-build:latest' }
|
||||
}
|
||||
steps {
|
||||
dir('build/linux') {
|
||||
sh 'make doc'
|
||||
}
|
||||
}
|
||||
post {
|
||||
success {
|
||||
publishHTML([reportName: 'Doxygen', reportDir: 'build/linux/doc/html', reportFiles: 'index.html', reportTitles: '', allowMissing: false, alwaysLinkToLastBuild: false, keepAll: false])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
stage('Run tests') {
|
||||
agent {
|
||||
docker { image 'krzysh/colobot-build:latest' }
|
||||
}
|
||||
steps {
|
||||
dir('build/linux') {
|
||||
sh './colobot_ut --gtest_output=xml:gtestresults.xml || true'
|
||||
}
|
||||
step([$class: 'XUnitBuilder', testTimeMargin: '3000', thresholdMode: 1, thresholds: [[$class: 'FailedThreshold', failureNewThreshold: '', failureThreshold: '', unstableNewThreshold: '', unstableThreshold: '0'], [$class: 'SkippedThreshold', failureNewThreshold: '', failureThreshold: '', unstableNewThreshold: '', unstableThreshold: '']], tools: [[$class: 'GoogleTestType', deleteOutputFiles: true, failIfNotNew: true, pattern: 'build/linux/gtestresults.xml', skipNoTestFiles: false, stopProcessingIfError: true]]])
|
||||
}
|
||||
// TODO: Maybe run Windows tests using wine as well?
|
||||
}
|
||||
|
||||
stage('Run colobot-lint') {
|
||||
agent {
|
||||
label 'colobot-build'
|
||||
}
|
||||
environment {
|
||||
CC = '/usr/lib/llvm-3.6/bin/clang'
|
||||
CXX = '/usr/lib/llvm-3.6/bin/clang++'
|
||||
CLANG_PREFIX = '/usr/lib/llvm-3.6'
|
||||
}
|
||||
steps {
|
||||
copyArtifacts filter: 'build/colobot-lint,build/html_report.tar.gz,Tools/count_errors.py', fingerprintArtifacts: true, projectName: 'colobot/colobot-lint/master', selector: lastSuccessful(), target: 'colobot-lint'
|
||||
sh 'chmod +x colobot-lint/Tools/count_errors.py' // TODO: ???
|
||||
sh 'mkdir -p build/lint'
|
||||
dir('build/lint') {
|
||||
// The cd is required here because /var/lib/jenkins is a symlink and colobot-lint breaks otherwise...
|
||||
sh 'cd $WORKSPACE/build/lint; cmake -DCOLOBOT_LINT_BUILD=1 -DTESTS=1 -DTOOLS=1 -DCMAKE_EXPORT_COMPILE_COMMANDS=1 $WORKSPACE'
|
||||
sh '''#!/bin/bash
|
||||
set -e +x
|
||||
|
||||
# Run colobot-lint
|
||||
|
||||
COLOBOT_DIR="$WORKSPACE"
|
||||
COLOBOT_BUILD_DIR="$WORKSPACE/build/lint"
|
||||
|
||||
COLOBOT_LINT_BUILD_DIR="$WORKSPACE/colobot-lint/build"
|
||||
|
||||
COLOBOT_LINT_REPORT_FILE="$WORKSPACE/build/lint/colobot_lint_report.xml"
|
||||
|
||||
# CLANG_PREFIX="/usr/lib/llvm-3.6" # Set in top-level environment block
|
||||
|
||||
cd "$COLOBOT_LINT_BUILD_DIR"
|
||||
chmod +x ./colobot-lint
|
||||
|
||||
# Workaround for Clang not finding system headers
|
||||
rm -rf bin/
|
||||
mkdir -p bin
|
||||
mv ./colobot-lint ./bin/
|
||||
rm -f ./lib
|
||||
ln -s ${CLANG_PREFIX}/lib ./lib
|
||||
|
||||
echo "Running colobot-lint"
|
||||
find "$WORKSPACE" \\( -wholename "$COLOBOT_DIR/src/*.cpp" \
|
||||
-or -wholename "$COLOBOT_DIR/test/unit/*.cpp" \
|
||||
-or -wholename "$COLOBOT_BUILD_DIR/fake_header_sources/src/*.cpp" \
|
||||
-or -wholename "$COLOBOT_BUILD_DIR/fake_header_sources/test/unit/*.cpp" \\) \
|
||||
-exec ./bin/colobot-lint \
|
||||
-verbose \
|
||||
-output-format xml \
|
||||
-output-file "$COLOBOT_LINT_REPORT_FILE" \
|
||||
-p "$COLOBOT_BUILD_DIR" \
|
||||
-project-local-include-path "$COLOBOT_DIR/src" -project-local-include-path "$COLOBOT_BUILD_DIR/src" \
|
||||
-license-template-file "$COLOBOT_DIR/LICENSE-HEADER.txt" \
|
||||
{} +
|
||||
'''
|
||||
sh '''#!/bin/bash
|
||||
set -e +x
|
||||
|
||||
# Generate HTML report
|
||||
|
||||
COLOBOT_LINT_BUILD_DIR="$WORKSPACE/colobot-lint/build"
|
||||
COLBOT_LINT_REPORT_FILE="$WORKSPACE/build/lint/colobot_lint_report.xml"
|
||||
HTML_REPORT_DIR="$WORKSPACE/build/lint/html_report"
|
||||
|
||||
echo "Generating HTML report"
|
||||
cd "$COLOBOT_LINT_BUILD_DIR"
|
||||
rm -rf HtmlReport/
|
||||
tar -zxf html_report.tar.gz
|
||||
HtmlReport/generate.py --xml-report "$COLBOT_LINT_REPORT_FILE" --output-dir "$HTML_REPORT_DIR"
|
||||
'''
|
||||
script {
|
||||
retcode = sh script: '''#!/bin/bash
|
||||
set -e +x
|
||||
|
||||
# Update stable/unstable build status
|
||||
|
||||
ret=0
|
||||
|
||||
COLOBOT_LINT_REPORT_FILE="$WORKSPACE/build/lint/colobot_lint_report.xml"
|
||||
COLOBOT_LINT_DIR="$WORKSPACE/colobot-lint"
|
||||
|
||||
OVERALL_STABLE_RULES=(
|
||||
"class naming"
|
||||
"code block placement"
|
||||
"compile error"
|
||||
# "compile warning"
|
||||
# "enum naming"
|
||||
# "function naming"
|
||||
"header file not self-contained"
|
||||
# "implicit bool cast"
|
||||
# "include style"
|
||||
# "inconsistent declaration parameter name"
|
||||
"license header"
|
||||
# "naked delete"
|
||||
# "naked new"
|
||||
# "old style function"
|
||||
"old-style null pointer"
|
||||
# "possible forward declaration"
|
||||
"undefined function"
|
||||
# "uninitialized field"
|
||||
# "uninitialized local variable"
|
||||
# "unused forward declaration"
|
||||
# "variable naming"
|
||||
"whitespace"
|
||||
)
|
||||
|
||||
echo "Checking rule stability (overall)"
|
||||
for ((i = 0; i < ${#OVERALL_STABLE_RULES[@]}; i++)); do
|
||||
rule="${OVERALL_STABLE_RULES[$i]}"
|
||||
count="$("$COLOBOT_LINT_DIR/Tools/count_errors.py" --rule-filter="$rule" --xml-report-file "$COLOBOT_LINT_REPORT_FILE")"
|
||||
if [ "$count" != "0" ]; then
|
||||
echo "UNSTABLE RULE: $rule ($count occurences)"
|
||||
ret=1
|
||||
fi
|
||||
done
|
||||
|
||||
STABLE_RULES_WITHOUT_CBOT=(
|
||||
"class naming"
|
||||
"code block placement"
|
||||
"compile error"
|
||||
"compile warning"
|
||||
# "enum naming"
|
||||
# "function naming"
|
||||
"header file not self-contained"
|
||||
# "implicit bool cast"
|
||||
"include style"
|
||||
"inconsistent declaration parameter name"
|
||||
"license header"
|
||||
"naked delete"
|
||||
"naked new"
|
||||
# "old style function"
|
||||
"old-style null pointer"
|
||||
# "possible forward declaration"
|
||||
"undefined function"
|
||||
"uninitialized field"
|
||||
# "uninitialized local variable"
|
||||
"unused forward declaration"
|
||||
# "variable naming"
|
||||
"whitespace"
|
||||
)
|
||||
|
||||
echo "Checking rule stability (without CBOT)"
|
||||
for ((i = 0; i < ${#STABLE_RULES_WITHOUT_CBOT[@]}; i++)); do
|
||||
rule="${STABLE_RULES_WITHOUT_CBOT[$i]}"
|
||||
count="$("$COLOBOT_LINT_DIR/Tools/count_errors.py" --rule-filter="$rule" --file-filter="-.*CBot.*" --xml-report-file "$COLOBOT_LINT_REPORT_FILE")"
|
||||
if [ "$count" != "0" ]; then
|
||||
echo "UNSTABLE RULE: $rule (without CBOT, $count occurences)"
|
||||
ret=1
|
||||
fi
|
||||
done
|
||||
|
||||
exit $ret
|
||||
''', returnStatus: true
|
||||
if (retcode != 0) {
|
||||
currentBuild.result = 'UNSTABLE'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
publishCppcheck pattern: 'build/lint/colobot_lint_report.xml'
|
||||
publishHTML([reportName: 'Colobot-lint HTML report', reportDir: 'build/lint/html_report', reportFiles: 'index.html', reportTitles: '', allowMissing: false, alwaysLinkToLastBuild: true, keepAll: true])
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* This file is part of the Colobot: Gold Edition source code
|
||||
* Copyright (C) 2001-2023, Daniel Roux, EPSITEC SA & TerranovaTeam
|
||||
* Copyright (C) 2001-2018, Daniel Roux, EPSITEC SA & TerranovaTeam
|
||||
* http://epsitec.ch; http://colobot.info; http://github.com/colobot
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
|
|
|
@ -1,25 +1,20 @@
|
|||
# README for developers
|
||||
|
||||
This file contains a ton of information useful for development of the game
|
||||
|
||||
## Repository setup
|
||||
|
||||
All the repositories related to Colobot can be found on our GitHub organization page: https://github.com/colobot
|
||||
|
||||
### Main code repository
|
||||
|
||||
This is the repository you are currently in.
|
||||
|
||||
This repository contains all the source files of Colobot, along with some 3rd party libraries, testing framework and build files for CMake.
|
||||
|
||||
### Data repository
|
||||
|
||||
The data repository is available at: https://github.com/colobot/colobot-data
|
||||
|
||||
This repository contains the data files necessary to run the game. These are level files, textures, models, sounds, music, help files, translations, etc. It contains many binary files, and so, it may grow up to considerable size. If that becomes a problem, we may remove some old revisions of binary files to free up space.
|
||||
|
||||
### Branch setup
|
||||
|
||||
Current setup is as follows:
|
||||
|
||||
* branch **master** - will always contain the best-playable version of the project so that new users could download and compile the project without problems. This branch is not intended for actual development but an integration branch for more "public" releases. The changes should be pulled from general development branch - *dev*. This branch will also have tags at certain commits to denote releases.
|
||||
|
@ -28,13 +23,11 @@ Current setup is as follows:
|
|||
Other **dev-*** branches may be created as needed, for work on major rewriting, or focusing on a set of features.
|
||||
|
||||
## 3rd party libraries
|
||||
|
||||
3rd party libraries are bundled in `lib/`. They are provided for ease of use since the standard packages are rare in OS distributions.
|
||||
|
||||
In case of GTest and GMock, CMake tries to detect if they are available in the system. If so, the system-provided versions will be used.
|
||||
|
||||
## CMake build system
|
||||
|
||||
The build system is as follows:
|
||||
|
||||
* `CMakeLists.txt` - definition of project, list of required packages, build type setup, general compiler options and reference to src subdirectory,
|
||||
|
@ -66,7 +59,6 @@ Note that the recommended way of building the project is to use separate build d
|
|||
```
|
||||
|
||||
## Tests organization
|
||||
|
||||
Tests are kept in `test/` directory which includes:
|
||||
|
||||
* `test/cbot` - CBOT interpreter for test purposes,
|
||||
|
@ -75,35 +67,33 @@ Tests are kept in `test/` directory which includes:
|
|||
Each test directory contains own `CMakeLists.txt` specifying targets. Note however that the only targets added as automated tests in CMake are in `test/unit` directory. The other targets are used as development support tools, not automated tests.
|
||||
|
||||
Tests can be enabled or disabled using CMake option TESTS (OFF by default). To run the automated tests (you must be in the build directory):
|
||||
|
||||
```
|
||||
./Colobot-UnitTests
|
||||
./colobot_ut
|
||||
# or:
|
||||
make test
|
||||
# or:
|
||||
ctest -V .
|
||||
```
|
||||
|
||||
We use [Google Test](https://github.com/google/googletest) for unit testing and [Hippomocks](https://github.com/dascandy/hippomocks) for mocking objects and function calls.
|
||||
For unit testing, we use Google Test framework (http://code.google.com/p/googletest/) and for mocking objects and function calls, GMock library (http://code.google.com/p/gmock/).
|
||||
|
||||
Note that currently there are very few well-tested parts of code. It is quite impossible to write unit tests for all the code we have but we should test as much code as possible, if not at unit level, then at module level. Hence the test environments and code snippets that enable us to test parts of code without actually running the full-fledged game.
|
||||
Note that currently, there are very few well-tested parts of code. It is quite impossible to write unit tests for all the code we have but we should test as much code as possible, if not at unit level, then at module level. Hence the test environments and code snippets that enable us to test parts of code without actually running the full-fledged game.
|
||||
|
||||
## CI and automated builds
|
||||
Our team is not large, but since compiling the whole project is lengthy and requires some knowledge, we use some automated services to facilitate the development.
|
||||
|
||||
Currently we use [GitHub Actions](https://github.com/colobot/colobot/actions) to run tests and provide compiled game binaries.
|
||||
Currently we use Jenkins server hosted at http://compiled.colobot.info/ to run tests and provide compiled game binaries.
|
||||
|
||||
Testers are encouraged to use these packages to test the game and report any problems.
|
||||
|
||||
## Code documentation
|
||||
[Doxygen](http://www.stack.nl/~dimitri/doxygen/) is used as the documentation tool.
|
||||
|
||||
[Doxygen](https://www.doxygen.nl/index.html) is used as the documentation tool.
|
||||
|
||||
The documentation is extracted from comment blocks in code by running `make doc`. The resulting HTML files are available in ''doc/'' inside the build directory. Generated documentation files '''will not''' be included in the repository. The idea is that anyone can generate the documentation at any time, in his local copy. GitHub Actions also builds documentation after every commit, see https://github.com/colobot/colobot/actions
|
||||
The documentation is extracted from comment blocks in code by running `make doc`. The resulting HTML files are available in ''doc/'' inside the build directory. Generated documentation files '''will not''' be included in the repository. The idea is that anyone can generate the documentation at any time, in his local copy. Our Jenkins also builds documentation after every commit, see http://compiled.colobot.info/job/colobot/job/colobot/job/dev/Doxygen/
|
||||
|
||||
Diagram generation (class inheritance, include dependencies, etc.) is disabled for now to speed up the generation process but you can of course enable it in your local copy.
|
||||
|
||||
Currently, only a few classes and structs are documented properly. If you can, please expand the documentation wherever possible.
|
||||
|
||||
## Coding rules
|
||||
|
||||
Please refer to the [CONTRIBUTING.md](CONTRIBUTING.md#coding-style) file.
|
74
README.md
74
README.md
|
@ -1,56 +1,50 @@
|
|||
<img src="https://raw.githubusercontent.com/colobot/colobot-misc/master/logos/ColobotGE-logo.svg" align="center">
|
||||
# Colobot: Gold Edition
|
||||
|
||||
<div align="center">
|
||||
<a href="https://colobot.info/"><img src="https://img.shields.io/badge/colobot.info-F5C700.svg?logo=wordpress&logoColor=white" alt="colobot.info"></a>
|
||||
<a href="https://discord.gg/56Fm9kb"><img src="https://img.shields.io/badge/Discord-5865F2.svg?logo=discord&logoColor=white" alt="Discord"></a>
|
||||
<a href="https://github.com/colobot/colobot/discussions"><img src="https://img.shields.io/badge/Discussions-24292F.svg?logo=github" alt="GitHub Discussions"></a>
|
||||
<a href="https://www.moddb.com/games/colobot-gold-edition"><img src="https://img.shields.io/badge/ModDB-CC0000.svg?logo=modrinth&logoColor=white" alt="ModDB"></a>
|
||||
<a href="https://www.youtube.com/@Colobot"><img src="https://img.shields.io/badge/YouTube-EA3223.svg?logo=youtube" alt="YouTube"></a>
|
||||
<a href="https://www.reddit.com/r/Colobot"><img src="https://img.shields.io/badge/Reddit-FF4300.svg?logo=reddit&logoColor=white" alt="Reddit"></a>
|
||||
<a href="https://twitter.com/ColobotGame"><img src="https://img.shields.io/badge/Twitter-009EF7.svg?logo=twitter&logoColor=white" alt="Twitter"></a>
|
||||
<a href="https://www.facebook.com/colobotgame"><img src="https://img.shields.io/badge/Facebook-1877F2.svg?logo=facebook&logoColor=white" alt="Facebook"></a>
|
||||
</div>
|
||||
Welcome to the Colobot: Gold Edition project code repository
|
||||
|
||||
This is the main repository for the open-source _Colobot: Gold Edition_ project developed by [TerranovaTeam](https://github.com/orgs/colobot/people) and community contributors, based on the original game by [Epsitec](https://www.epsitec.ch).
|
||||
This is official repository for the open-source Colobot: Gold Edition project developed by TerranovaTeam, part of International Colobot Community (ICC, previously known as Polish Portal of Colobot/PPC) with the official site at: [colobot.info](http://colobot.info/).
|
||||
|
||||
This repository contains only the source code of the project. The game also requires data files which are provided as a git submodule and are hosted in a [separate repository](https://github.com/colobot/colobot-data).
|
||||
The source code contained here was released by Epsitec -- the original creator of the game -- on open source (GPLv3) license. The code was given and the rights granted specifically to ICC community in March 2012. Since then, we have been developing the game further.
|
||||
|
||||
## Features
|
||||
More information for developers (in English) can be found on [our forum](http://colobot.info/forum/). However, the freshest source of information is our IRC channels (see below).
|
||||
|
||||
- Multiplatform - play the game on any modern OS.
|
||||
- New game modes - challenge yourself in _Missions+_ or challenge your friends in _CodeBattles_.
|
||||
- Mod support - download custom levels and assets from [our ModDB page](https://www.moddb.com/games/colobot-gold-edition).
|
||||
- Improved visuals, QoL additions, bug fixes, and [other improvements](https://colobot.info/category/news/updates).
|
||||
This repository contains only the source code of the project. The game requires also data files which are now provided as git submodule and are hosted in [separate repository](https://github.com/colobot/colobot-data).
|
||||
|
||||
## Download
|
||||
|
||||
### Stable releases
|
||||
## Status
|
||||
|
||||
Official builds for Windows, Linux, MacOS are available here:\
|
||||
[](https://colobot.info/download-colobot-gold)
|
||||
The original version of the game, as released to us by Epsitec, is available as download at [our download site](http://colobot.info/files/) along with original source code and related data files. However, we will not develop this version further, as we focused our efforts on new versions of the game. The original version is also known as Colobot Classic.
|
||||
|
||||
Linux packages:\
|
||||
[](https://repology.org/project/colobot/versions)\
|
||||
[](http://packages.debian.org/sid/colobot)\
|
||||
[](https://aur.archlinux.org/packages/colobot-gold)\
|
||||
[](http://software.opensuse.org/download.html?project=games&package=colobot)\
|
||||
[](https://src.fedoraproject.org/rpms/colobot)\
|
||||
[](https://packages.guix.gnu.org/packages/colobot)\
|
||||
[](https://github.com/void-linux/void-packages/tree/master/srcpkgs/colobot)
|
||||
We are now working on refreshed and updated version of original game, codename Colobot Gold and this is the version currently hosted in this repository. The goal is to rewrite the game engine to be multi-platform, refresh the graphics, include some enhancements and refactor the code to make the game easier to modify.
|
||||
|
||||
### Development builds
|
||||
The project at this point is in alpha stage - the game is mostly playable, both on Windows and Linux, and most major bugs have been corrected. We are now working steadily towards subsequent beta releases, correcting other bugs and introducing enhancements and new features. There is a lot of work ahead and we will gladly accept any and all help.
|
||||
|
||||
Development builds are compiled every push to the repository by GitHub Actions:\
|
||||
[](https://github.com/colobot/colobot/actions)
|
||||
In the future, we will begin development on a new installment in the Colobot series, codename Colobot 2. We have many ideas for the new game and we are still discussing them. Generally, the development of this version will begin only after finishing Colobot Gold (it will be probably hosted in another repository, forked off the Colobot Gold code).
|
||||
|
||||
## Compiling from source
|
||||
|
||||
Instructions on how to build the game from sources are available for the following environments:
|
||||
- [Linux](INSTALL.md)
|
||||
- [Windows (MSYS2)](docs/INSTALL-MSYS2.md)
|
||||
- [Windows (MSVC)](https://github.com/colobot/colobot/wiki/How-to-Build-Colobot%3A-Gold-Edition-Using-MSVC)
|
||||
- [MacOS](docs/INSTALL-MacOSX.md)
|
||||
## Download packages
|
||||
|
||||
We provide compiled packages of most recent versions using an [automated build bot service](http://compiled.colobot.info/). Available versions include packages for Windows and Linux in both Release and Debug configurations.
|
||||
|
||||
On some Linux distributions there are also distribution packages available:
|
||||
* Debian Sid (unstable): http://packages.debian.org/sid/colobot
|
||||
* Arch Linux (AUR): https://aur.archlinux.org/packages/colobot-gold
|
||||
* openSUSE: http://software.opensuse.org/download.html?project=games&package=colobot
|
||||
|
||||
|
||||
## Compiling and running the game
|
||||
|
||||
If you want to compile colobot yourself, see [INSTALL.md](INSTALL.md) file.
|
||||
|
||||
## Contributing
|
||||
|
||||
If you want to contribute to the project, see [CONTRIBUTING.md](CONTRIBUTING.md).
|
||||
If you want to contribute to the project, see [CONTRIBUTING.md](CONTRIBUTING.md) file. It contains a lot of useful information on how to get started.
|
||||
|
||||
## Contact
|
||||
|
||||
If you want to help in the project, please contact us on our IRC channels or [our forum](http://colobot.info/forum/).
|
||||
|
||||
### IRC channels
|
||||
|
||||
* [#colobot on Freenode](irc://freenode.net#colobot) - main development channel (English);
|
||||
* [#colobot on pirc.pl](irc://pirc.pl#colobot) - Polish community channel;
|
||||
|
|
|
@ -1,132 +0,0 @@
|
|||
CMake - Cross Platform Makefile Generator
|
||||
Copyright 2000-2020 Kitware, Inc. and Contributors
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
* Neither the name of Kitware, Inc. nor the names of Contributors
|
||||
may be used to endorse or promote products derived from this
|
||||
software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
The following individuals and institutions are among the Contributors:
|
||||
|
||||
* Aaron C. Meadows <cmake@shadowguarddev.com>
|
||||
* Adriaan de Groot <groot@kde.org>
|
||||
* Aleksey Avdeev <solo@altlinux.ru>
|
||||
* Alexander Neundorf <neundorf@kde.org>
|
||||
* Alexander Smorkalov <alexander.smorkalov@itseez.com>
|
||||
* Alexey Sokolov <sokolov@google.com>
|
||||
* Alex Merry <alex.merry@kde.org>
|
||||
* Alex Turbov <i.zaufi@gmail.com>
|
||||
* Andreas Pakulat <apaku@gmx.de>
|
||||
* Andreas Schneider <asn@cryptomilk.org>
|
||||
* André Rigland Brodtkorb <Andre.Brodtkorb@ifi.uio.no>
|
||||
* Axel Huebl, Helmholtz-Zentrum Dresden - Rossendorf
|
||||
* Benjamin Eikel
|
||||
* Bjoern Ricks <bjoern.ricks@gmail.com>
|
||||
* Brad Hards <bradh@kde.org>
|
||||
* Christopher Harvey
|
||||
* Christoph Grüninger <foss@grueninger.de>
|
||||
* Clement Creusot <creusot@cs.york.ac.uk>
|
||||
* Daniel Blezek <blezek@gmail.com>
|
||||
* Daniel Pfeifer <daniel@pfeifer-mail.de>
|
||||
* Enrico Scholz <enrico.scholz@informatik.tu-chemnitz.de>
|
||||
* Eran Ifrah <eran.ifrah@gmail.com>
|
||||
* Esben Mose Hansen, Ange Optimization ApS
|
||||
* Geoffrey Viola <geoffrey.viola@asirobots.com>
|
||||
* Google Inc
|
||||
* Gregor Jasny
|
||||
* Helio Chissini de Castro <helio@kde.org>
|
||||
* Ilya Lavrenov <ilya.lavrenov@itseez.com>
|
||||
* Insight Software Consortium <insightsoftwareconsortium.org>
|
||||
* Jan Woetzel
|
||||
* Julien Schueller
|
||||
* Kelly Thompson <kgt@lanl.gov>
|
||||
* Laurent Montel <montel@kde.org>
|
||||
* Konstantin Podsvirov <konstantin@podsvirov.pro>
|
||||
* Mario Bensi <mbensi@ipsquad.net>
|
||||
* Martin Gräßlin <mgraesslin@kde.org>
|
||||
* Mathieu Malaterre <mathieu.malaterre@gmail.com>
|
||||
* Matthaeus G. Chajdas
|
||||
* Matthias Kretz <kretz@kde.org>
|
||||
* Matthias Maennich <matthias@maennich.net>
|
||||
* Michael Hirsch, Ph.D. <www.scivision.co>
|
||||
* Michael Stürmer
|
||||
* Miguel A. Figueroa-Villanueva
|
||||
* Mike Jackson
|
||||
* Mike McQuaid <mike@mikemcquaid.com>
|
||||
* Nicolas Bock <nicolasbock@gmail.com>
|
||||
* Nicolas Despres <nicolas.despres@gmail.com>
|
||||
* Nikita Krupen'ko <krnekit@gmail.com>
|
||||
* NVIDIA Corporation <www.nvidia.com>
|
||||
* OpenGamma Ltd. <opengamma.com>
|
||||
* Patrick Stotko <stotko@cs.uni-bonn.de>
|
||||
* Per Øyvind Karlsen <peroyvind@mandriva.org>
|
||||
* Peter Collingbourne <peter@pcc.me.uk>
|
||||
* Petr Gotthard <gotthard@honeywell.com>
|
||||
* Philip Lowman <philip@yhbt.com>
|
||||
* Philippe Proulx <pproulx@efficios.com>
|
||||
* Raffi Enficiaud, Max Planck Society
|
||||
* Raumfeld <raumfeld.com>
|
||||
* Roger Leigh <rleigh@codelibre.net>
|
||||
* Rolf Eike Beer <eike@sf-mail.de>
|
||||
* Roman Donchenko <roman.donchenko@itseez.com>
|
||||
* Roman Kharitonov <roman.kharitonov@itseez.com>
|
||||
* Ruslan Baratov
|
||||
* Sebastian Holtermann <sebholt@xwmw.org>
|
||||
* Stephen Kelly <steveire@gmail.com>
|
||||
* Sylvain Joubert <joubert.sy@gmail.com>
|
||||
* The Qt Company Ltd.
|
||||
* Thomas Sondergaard <ts@medical-insight.com>
|
||||
* Tobias Hunger <tobias.hunger@qt.io>
|
||||
* Todd Gamblin <tgamblin@llnl.gov>
|
||||
* Tristan Carel
|
||||
* University of Dundee
|
||||
* Vadim Zhukov
|
||||
* Will Dicharry <wdicharry@stellarscience.com>
|
||||
|
||||
See version control history for details of individual contributions.
|
||||
|
||||
The above copyright and license notice applies to distributions of
|
||||
CMake in source and binary form. Third-party software packages supplied
|
||||
with CMake under compatible licenses provide their own copyright notices
|
||||
documented in corresponding subdirectories or source files.
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
CMake was initially developed by Kitware with the following sponsorship:
|
||||
|
||||
* National Library of Medicine at the National Institutes of Health
|
||||
as part of the Insight Segmentation and Registration Toolkit (ITK).
|
||||
|
||||
* US National Labs (Los Alamos, Livermore, Sandia) ASC Parallel
|
||||
Visualization Initiative.
|
||||
|
||||
* National Alliance for Medical Image Computing (NAMIC) is funded by the
|
||||
National Institutes of Health through the NIH Roadmap for Medical Research,
|
||||
Grant U54 EB005149.
|
||||
|
||||
* Kitware, Inc.
|
|
@ -1,69 +0,0 @@
|
|||
# - Find FLAC
|
||||
# Find the native FLAC includes and libraries
|
||||
#
|
||||
# FLAC_INCLUDE_DIRS - where to find FLAC headers.
|
||||
# FLAC_LIBRARIES - List of libraries when using libFLAC.
|
||||
# FLAC_FOUND - True if libFLAC found.
|
||||
# FLAC_DEFINITIONS - FLAC compile definitons
|
||||
|
||||
# From https://github.com/erikd/libsndfile/
|
||||
|
||||
if (FLAC_INCLUDE_DIR)
|
||||
# Already in cache, be silent
|
||||
set (FLAC_FIND_QUIETLY TRUE)
|
||||
endif ()
|
||||
|
||||
find_package (Ogg QUIET)
|
||||
|
||||
find_package (PkgConfig QUIET)
|
||||
pkg_check_modules(PC_FLAC QUIET flac)
|
||||
|
||||
set(FLAC_VERSION ${PC_FLAC_VERSION})
|
||||
|
||||
find_path (FLAC_INCLUDE_DIR FLAC/stream_decoder.h
|
||||
HINTS
|
||||
${PC_FLAC_INCLUDEDIR}
|
||||
${PC_FLAC_INCLUDE_DIRS}
|
||||
${FLAC_ROOT}
|
||||
)
|
||||
|
||||
# MSVC built libraries can name them *_static, which is good as it
|
||||
# distinguishes import libraries from static libraries with the same extension.
|
||||
find_library (FLAC_LIBRARY
|
||||
NAMES
|
||||
FLAC
|
||||
libFLAC
|
||||
libFLAC_dynamic
|
||||
libFLAC_static
|
||||
HINTS
|
||||
${PC_FLAC_LIBDIR}
|
||||
${PC_FLAC_LIBRARY_DIRS}
|
||||
${FLAC_ROOT}
|
||||
)
|
||||
|
||||
# Handle the QUIETLY and REQUIRED arguments and set FLAC_FOUND to TRUE if
|
||||
# all listed variables are TRUE.
|
||||
include (FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args (FLAC
|
||||
REQUIRED_VARS
|
||||
FLAC_LIBRARY
|
||||
FLAC_INCLUDE_DIR
|
||||
Ogg_FOUND
|
||||
VERSION_VAR
|
||||
FLAC_VERSION
|
||||
)
|
||||
|
||||
if (FLAC_FOUND)
|
||||
set (FLAC_INCLUDE_DIRS ${FLAC_INCLUDE_DIR})
|
||||
set (FLAC_LIBRARIES ${FLAC_LIBRARY} ${OGG_LIBRARIES})
|
||||
if (NOT TARGET FLAC::FLAC)
|
||||
add_library(FLAC::FLAC UNKNOWN IMPORTED)
|
||||
set_target_properties(FLAC::FLAC PROPERTIES
|
||||
INTERFACE_INCLUDE_DIRECTORIES "${FLAC_INCLUDE_DIR}"
|
||||
IMPORTED_LOCATION "${FLAC_LIBRARY}"
|
||||
INTERFACE_LINK_LIBRARIES Ogg::ogg
|
||||
)
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
mark_as_advanced(FLAC_INCLUDE_DIR FLAC_LIBRARY)
|
|
@ -1,342 +1,51 @@
|
|||
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
||||
# file Copyright.txt or https://cmake.org/licensing for details.
|
||||
|
||||
#[=======================================================================[.rst:
|
||||
FindGLEW
|
||||
--------
|
||||
|
||||
Find the OpenGL Extension Wrangler Library (GLEW)
|
||||
|
||||
Input Variables
|
||||
^^^^^^^^^^^^^^^
|
||||
|
||||
The following variables may be set to influence this module's behavior:
|
||||
|
||||
``GLEW_USE_STATIC_LIBS``
|
||||
to find and create :prop_tgt:`IMPORTED` target for static linkage.
|
||||
|
||||
``GLEW_VERBOSE``
|
||||
to output a detailed log of this module.
|
||||
|
||||
Imported Targets
|
||||
^^^^^^^^^^^^^^^^
|
||||
|
||||
This module defines the following :ref:`Imported Targets <Imported Targets>`:
|
||||
|
||||
|
||||
``GLEW::glew``
|
||||
The GLEW shared library.
|
||||
``GLEW::glew_s``
|
||||
The GLEW static library, if ``GLEW_USE_STATIC_LIBS`` is set to ``TRUE``.
|
||||
``GLEW::GLEW``
|
||||
Duplicates either ``GLEW::glew`` or ``GLEW::glew_s`` based on availability.
|
||||
|
||||
Result Variables
|
||||
^^^^^^^^^^^^^^^^
|
||||
|
||||
This module defines the following variables:
|
||||
|
||||
``GLEW_INCLUDE_DIRS``
|
||||
include directories for GLEW
|
||||
``GLEW_LIBRARIES``
|
||||
libraries to link against GLEW
|
||||
``GLEW_SHARED_LIBRARIES``
|
||||
libraries to link against shared GLEW
|
||||
``GLEW_STATIC_LIBRARIES``
|
||||
libraries to link against static GLEW
|
||||
``GLEW_FOUND``
|
||||
true if GLEW has been found and can be used
|
||||
``GLEW_VERSION``
|
||||
GLEW version
|
||||
``GLEW_VERSION_MAJOR``
|
||||
GLEW major version
|
||||
``GLEW_VERSION_MINOR``
|
||||
GLEW minor version
|
||||
``GLEW_VERSION_MICRO``
|
||||
GLEW micro version
|
||||
|
||||
#]=======================================================================]
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
|
||||
find_package(GLEW CONFIG QUIET)
|
||||
|
||||
if(GLEW_FOUND)
|
||||
find_package_handle_standard_args(GLEW DEFAULT_MSG GLEW_CONFIG)
|
||||
return()
|
||||
endif()
|
||||
|
||||
if(GLEW_VERBOSE)
|
||||
message(STATUS "FindGLEW: did not find GLEW CMake config file. Searching for libraries.")
|
||||
endif()
|
||||
|
||||
if(APPLE)
|
||||
find_package(OpenGL QUIET)
|
||||
|
||||
if(OpenGL_FOUND)
|
||||
if(GLEW_VERBOSE)
|
||||
message(STATUS "FindGLEW: Found OpenGL Framework.")
|
||||
message(STATUS "FindGLEW: OPENGL_LIBRARIES: ${OPENGL_LIBRARIES}")
|
||||
endif()
|
||||
else()
|
||||
if(GLEW_VERBOSE)
|
||||
message(STATUS "FindGLEW: could not find GLEW library.")
|
||||
endif()
|
||||
return()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
||||
function(__glew_set_find_library_suffix shared_or_static)
|
||||
if((UNIX AND NOT APPLE) AND "${shared_or_static}" MATCHES "SHARED")
|
||||
set(CMAKE_FIND_LIBRARY_SUFFIXES ".so" PARENT_SCOPE)
|
||||
elseif((UNIX AND NOT APPLE) AND "${shared_or_static}" MATCHES "STATIC")
|
||||
set(CMAKE_FIND_LIBRARY_SUFFIXES ".a" PARENT_SCOPE)
|
||||
elseif(APPLE AND "${shared_or_static}" MATCHES "SHARED")
|
||||
set(CMAKE_FIND_LIBRARY_SUFFIXES ".dylib;.so" PARENT_SCOPE)
|
||||
elseif(APPLE AND "${shared_or_static}" MATCHES "STATIC")
|
||||
set(CMAKE_FIND_LIBRARY_SUFFIXES ".a" PARENT_SCOPE)
|
||||
elseif(WIN32 AND "${shared_or_static}" MATCHES "SHARED")
|
||||
set(CMAKE_FIND_LIBRARY_SUFFIXES ".lib" PARENT_SCOPE)
|
||||
elseif(WIN32 AND "${shared_or_static}" MATCHES "STATIC")
|
||||
set(CMAKE_FIND_LIBRARY_SUFFIXES ".lib;.dll.a" PARENT_SCOPE)
|
||||
endif()
|
||||
|
||||
if(GLEW_VERBOSE)
|
||||
message(STATUS "FindGLEW: CMAKE_FIND_LIBRARY_SUFFIXES for ${shared_or_static}: ${CMAKE_FIND_LIBRARY_SUFFIXES}")
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
|
||||
if(GLEW_VERBOSE)
|
||||
if(DEFINED GLEW_USE_STATIC_LIBS)
|
||||
message(STATUS "FindGLEW: GLEW_USE_STATIC_LIBS: ${GLEW_USE_STATIC_LIBS}.")
|
||||
else()
|
||||
message(STATUS "FindGLEW: GLEW_USE_STATIC_LIBS is undefined. Treated as FALSE.")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
find_path(GLEW_INCLUDE_DIR GL/glew.h)
|
||||
mark_as_advanced(GLEW_INCLUDE_DIR)
|
||||
|
||||
set(GLEW_INCLUDE_DIRS ${GLEW_INCLUDE_DIR})
|
||||
|
||||
if(GLEW_VERBOSE)
|
||||
message(STATUS "FindGLEW: GLEW_INCLUDE_DIR: ${GLEW_INCLUDE_DIR}")
|
||||
message(STATUS "FindGLEW: GLEW_INCLUDE_DIRS: ${GLEW_INCLUDE_DIRS}")
|
||||
endif()
|
||||
|
||||
if("${CMAKE_GENERATOR_PLATFORM}" MATCHES "x64" OR "${CMAKE_GENERATOR}" MATCHES "Win64")
|
||||
set(_arch "x64")
|
||||
else()
|
||||
set(_arch "Win32")
|
||||
endif()
|
||||
|
||||
|
||||
set(__GLEW_CURRENT_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES})
|
||||
|
||||
__glew_set_find_library_suffix(SHARED)
|
||||
|
||||
find_library(GLEW_SHARED_LIBRARY_RELEASE
|
||||
NAMES GLEW glew glew32
|
||||
PATH_SUFFIXES lib lib64 libx32 lib/Release/${_arch}
|
||||
PATHS ENV GLEW_ROOT)
|
||||
|
||||
find_library(GLEW_SHARED_LIBRARY_DEBUG
|
||||
NAMES GLEWd glewd glew32d
|
||||
PATH_SUFFIXES lib lib64
|
||||
PATHS ENV GLEW_ROOT)
|
||||
|
||||
|
||||
__glew_set_find_library_suffix(STATIC)
|
||||
|
||||
find_library(GLEW_STATIC_LIBRARY_RELEASE
|
||||
NAMES GLEW glew glew32s
|
||||
PATH_SUFFIXES lib lib64 libx32 lib/Release/${_arch}
|
||||
PATHS ENV GLEW_ROOT)
|
||||
|
||||
find_library(GLEW_STATIC_LIBRARY_DEBUG
|
||||
NAMES GLEWds glewds glew32ds
|
||||
PATH_SUFFIXES lib lib64
|
||||
PATHS ENV GLEW_ROOT)
|
||||
|
||||
set(CMAKE_FIND_LIBRARY_SUFFIXES ${__GLEW_CURRENT_FIND_LIBRARY_SUFFIXES})
|
||||
unset(__GLEW_CURRENT_FIND_LIBRARY_SUFFIXES)
|
||||
|
||||
include(SelectLibraryConfigurations)
|
||||
|
||||
select_library_configurations(GLEW_SHARED)
|
||||
select_library_configurations(GLEW_STATIC)
|
||||
|
||||
if(NOT GLEW_USE_STATIC_LIBS)
|
||||
set(GLEW_LIBRARIES ${GLEW_SHARED_LIBRARY})
|
||||
else()
|
||||
set(GLEW_LIBRARIES ${GLEW_STATIC_LIBRARY})
|
||||
endif()
|
||||
|
||||
|
||||
if(GLEW_VERBOSE)
|
||||
message(STATUS "FindGLEW: GLEW_SHARED_LIBRARY_RELEASE: ${GLEW_SHARED_LIBRARY_RELEASE}")
|
||||
message(STATUS "FindGLEW: GLEW_STATIC_LIBRARY_RELEASE: ${GLEW_STATIC_LIBRARY_RELEASE}")
|
||||
message(STATUS "FindGLEW: GLEW_SHARED_LIBRARY_DEBUG: ${GLEW_SHARED_LIBRARY_DEBUG}")
|
||||
message(STATUS "FindGLEW: GLEW_STATIC_LIBRARY_DEBUG: ${GLEW_STATIC_LIBRARY_DEBUG}")
|
||||
message(STATUS "FindGLEW: GLEW_SHARED_LIBRARY: ${GLEW_SHARED_LIBRARY}")
|
||||
message(STATUS "FindGLEW: GLEW_STATIC_LIBRARY: ${GLEW_STATIC_LIBRARY}")
|
||||
message(STATUS "FindGLEW: GLEW_LIBRARIES: ${GLEW_LIBRARIES}")
|
||||
endif()
|
||||
|
||||
|
||||
# Read version from GL/glew.h file
|
||||
if(EXISTS "${GLEW_INCLUDE_DIR}/GL/glew.h")
|
||||
file(STRINGS "${GLEW_INCLUDE_DIR}/GL/glew.h" _contents REGEX "^VERSION_.+ [0-9]+")
|
||||
if(_contents)
|
||||
string(REGEX REPLACE ".*VERSION_MAJOR[ \t]+([0-9]+).*" "\\1" GLEW_VERSION_MAJOR "${_contents}")
|
||||
string(REGEX REPLACE ".*VERSION_MINOR[ \t]+([0-9]+).*" "\\1" GLEW_VERSION_MINOR "${_contents}")
|
||||
string(REGEX REPLACE ".*VERSION_MICRO[ \t]+([0-9]+).*" "\\1" GLEW_VERSION_MICRO "${_contents}")
|
||||
set(GLEW_VERSION "${GLEW_VERSION_MAJOR}.${GLEW_VERSION_MINOR}.${GLEW_VERSION_MICRO}")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(GLEW_VERBOSE)
|
||||
message(STATUS "FindGLEW: GLEW_VERSION_MAJOR: ${GLEW_VERSION_MAJOR}")
|
||||
message(STATUS "FindGLEW: GLEW_VERSION_MINOR: ${GLEW_VERSION_MINOR}")
|
||||
message(STATUS "FindGLEW: GLEW_VERSION_MICRO: ${GLEW_VERSION_MICRO}")
|
||||
message(STATUS "FindGLEW: GLEW_VERSION: ${GLEW_VERSION}")
|
||||
endif()
|
||||
|
||||
find_package_handle_standard_args(GLEW
|
||||
REQUIRED_VARS GLEW_INCLUDE_DIRS GLEW_LIBRARIES
|
||||
VERSION_VAR GLEW_VERSION)
|
||||
|
||||
if(NOT GLEW_FOUND)
|
||||
if(GLEW_VERBOSE)
|
||||
message(STATUS "FindGLEW: could not find GLEW library.")
|
||||
endif()
|
||||
return()
|
||||
endif()
|
||||
|
||||
|
||||
if(NOT TARGET GLEW::glew AND NOT GLEW_USE_STATIC_LIBS)
|
||||
if(GLEW_VERBOSE)
|
||||
message(STATUS "FindGLEW: Creating GLEW::glew imported target.")
|
||||
endif()
|
||||
|
||||
add_library(GLEW::glew UNKNOWN IMPORTED)
|
||||
|
||||
set_target_properties(GLEW::glew
|
||||
PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${GLEW_INCLUDE_DIRS}")
|
||||
|
||||
if(APPLE)
|
||||
set_target_properties(GLEW::glew
|
||||
PROPERTIES INTERFACE_LINK_LIBRARIES OpenGL::GL)
|
||||
endif()
|
||||
|
||||
if(GLEW_SHARED_LIBRARY_RELEASE)
|
||||
set_property(TARGET GLEW::glew
|
||||
APPEND
|
||||
PROPERTY IMPORTED_CONFIGURATIONS RELEASE)
|
||||
|
||||
set_target_properties(GLEW::glew
|
||||
PROPERTIES IMPORTED_LOCATION_RELEASE "${GLEW_SHARED_LIBRARY_RELEASE}")
|
||||
endif()
|
||||
|
||||
if(GLEW_SHARED_LIBRARY_DEBUG)
|
||||
set_property(TARGET GLEW::glew
|
||||
APPEND
|
||||
PROPERTY IMPORTED_CONFIGURATIONS DEBUG)
|
||||
|
||||
set_target_properties(GLEW::glew
|
||||
PROPERTIES IMPORTED_LOCATION_DEBUG "${GLEW_SHARED_LIBRARY_DEBUG}")
|
||||
endif()
|
||||
|
||||
elseif(NOT TARGET GLEW::glew_s AND GLEW_USE_STATIC_LIBS)
|
||||
if(GLEW_VERBOSE)
|
||||
message(STATUS "FindGLEW: Creating GLEW::glew_s imported target.")
|
||||
endif()
|
||||
|
||||
add_library(GLEW::glew_s UNKNOWN IMPORTED)
|
||||
|
||||
set_target_properties(GLEW::glew_s
|
||||
PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${GLEW_INCLUDE_DIRS}")
|
||||
|
||||
if(APPLE)
|
||||
set_target_properties(GLEW::glew_s
|
||||
PROPERTIES INTERFACE_LINK_LIBRARIES OpenGL::GL)
|
||||
endif()
|
||||
|
||||
if(GLEW_STATIC_LIBRARY_RELEASE)
|
||||
set_property(TARGET GLEW::glew_s
|
||||
APPEND
|
||||
PROPERTY IMPORTED_CONFIGURATIONS RELEASE)
|
||||
|
||||
set_target_properties(GLEW::glew_s
|
||||
PROPERTIES IMPORTED_LOCATION_RELEASE "${GLEW_STATIC_LIBRARY_RELEASE}")
|
||||
endif()
|
||||
|
||||
if(GLEW_STATIC_LIBRARY_DEBUG)
|
||||
set_property(TARGET GLEW::glew_s
|
||||
APPEND
|
||||
PROPERTY IMPORTED_CONFIGURATIONS DEBUG)
|
||||
|
||||
set_target_properties(GLEW::glew_s
|
||||
PROPERTIES IMPORTED_LOCATION_DEBUG "${GLEW_STATIC_LIBRARY_DEBUG}")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(NOT TARGET GLEW::GLEW)
|
||||
if(GLEW_VERBOSE)
|
||||
message(STATUS "FindGLEW: Creating GLEW::GLEW imported target.")
|
||||
endif()
|
||||
|
||||
add_library(GLEW::GLEW UNKNOWN IMPORTED)
|
||||
|
||||
set_target_properties(GLEW::GLEW
|
||||
PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${GLEW_INCLUDE_DIRS}")
|
||||
|
||||
if(APPLE)
|
||||
set_target_properties(GLEW::GLEW
|
||||
PROPERTIES INTERFACE_LINK_LIBRARIES OpenGL::GL)
|
||||
endif()
|
||||
|
||||
if(TARGET GLEW::glew)
|
||||
if(GLEW_SHARED_LIBRARY_RELEASE)
|
||||
set_property(TARGET GLEW::GLEW
|
||||
APPEND
|
||||
PROPERTY IMPORTED_CONFIGURATIONS RELEASE)
|
||||
|
||||
set_target_properties(GLEW::GLEW
|
||||
PROPERTIES IMPORTED_LOCATION_RELEASE "${GLEW_SHARED_LIBRARY_RELEASE}")
|
||||
endif()
|
||||
|
||||
if(GLEW_SHARED_LIBRARY_DEBUG)
|
||||
set_property(TARGET GLEW::GLEW
|
||||
APPEND
|
||||
PROPERTY IMPORTED_CONFIGURATIONS DEBUG)
|
||||
|
||||
set_target_properties(GLEW::GLEW
|
||||
PROPERTIES IMPORTED_LOCATION_DEBUG "${GLEW_SHARED_LIBRARY_DEBUG}")
|
||||
endif()
|
||||
|
||||
elseif(TARGET GLEW::glew_s)
|
||||
if(GLEW_STATIC_LIBRARY_RELEASE)
|
||||
set_property(TARGET GLEW::GLEW
|
||||
APPEND
|
||||
PROPERTY IMPORTED_CONFIGURATIONS RELEASE)
|
||||
|
||||
set_target_properties(GLEW::GLEW
|
||||
PROPERTIES IMPORTED_LOCATION_RELEASE "${GLEW_STATIC_LIBRARY_RELEASE}")
|
||||
endif()
|
||||
|
||||
if(GLEW_STATIC_LIBRARY_DEBUG AND GLEW_USE_STATIC_LIBS)
|
||||
set_property(TARGET GLEW::GLEW
|
||||
APPEND
|
||||
PROPERTY IMPORTED_CONFIGURATIONS DEBUG)
|
||||
|
||||
set_target_properties(GLEW::GLEW
|
||||
PROPERTIES IMPORTED_LOCATION_DEBUG "${GLEW_STATIC_LIBRARY_DEBUG}")
|
||||
endif()
|
||||
|
||||
elseif(GLEW_VERBOSE)
|
||||
message(WARNING "FindGLEW: no `GLEW::glew` or `GLEW::glew_s` target was created. Something went wrong in FindGLEW target creation.")
|
||||
endif()
|
||||
endif()
|
||||
# CMake module to find GLEW
|
||||
# Borrowed from http://code.google.com/p/nvidia-texture-tools/
|
||||
# MIT license Copyright (c) 2007 NVIDIA Corporation
|
||||
|
||||
# Try to find GLEW library and include path.
|
||||
# Once done this will define
|
||||
#
|
||||
# GLEW_FOUND
|
||||
# GLEW_INCLUDE_PATH
|
||||
# GLEW_LIBRARY
|
||||
#
|
||||
|
||||
IF (WIN32)
|
||||
FIND_PATH( GLEW_INCLUDE_PATH GL/glew.h
|
||||
$ENV{PROGRAMFILES}/GLEW/include
|
||||
${PROJECT_SOURCE_DIR}/src/nvgl/glew/include
|
||||
DOC "The directory where GL/glew.h resides")
|
||||
FIND_LIBRARY( GLEW_LIBRARY
|
||||
NAMES glew GLEW glew32 glew32s
|
||||
PATHS
|
||||
/mingw/bin # for MinGW's MSYS
|
||||
/mingw/lib
|
||||
${PROJECT_SOURCE_DIR}/glew/bin # or in local directory
|
||||
${PROJECT_SOURCE_DIR}/glew/lib
|
||||
DOC "The GLEW library")
|
||||
ELSE (WIN32)
|
||||
FIND_PATH( GLEW_INCLUDE_PATH GL/glew.h
|
||||
/usr/include
|
||||
/usr/local/include
|
||||
/sw/include
|
||||
/opt/local/include
|
||||
DOC "The directory where GL/glew.h resides")
|
||||
FIND_LIBRARY( GLEW_LIBRARY
|
||||
NAMES GLEW glew
|
||||
PATHS
|
||||
/usr/lib64
|
||||
/usr/lib
|
||||
/usr/local/lib64
|
||||
/usr/local/lib
|
||||
/sw/lib
|
||||
/opt/local/lib
|
||||
DOC "The GLEW library")
|
||||
ENDIF (WIN32)
|
||||
|
||||
IF (GLEW_INCLUDE_PATH)
|
||||
SET( GLEW_FOUND 1 CACHE STRING "Set to 1 if GLEW is found, 0 otherwise")
|
||||
ELSE (GLEW_INCLUDE_PATH)
|
||||
SET( GLEW_FOUND 0 CACHE STRING "Set to 1 if GLEW is found, 0 otherwise")
|
||||
ENDIF (GLEW_INCLUDE_PATH)
|
||||
|
||||
MARK_AS_ADVANCED( GLEW_FOUND )
|
||||
|
|
|
@ -1,68 +0,0 @@
|
|||
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
||||
# file Copyright.txt or https://cmake.org/licensing for details.
|
||||
|
||||
#[=======================================================================[.rst:
|
||||
FindIntl
|
||||
--------
|
||||
|
||||
Find the Gettext libintl headers and libraries.
|
||||
|
||||
This module reports information about the Gettext libintl
|
||||
installation in several variables. General variables::
|
||||
|
||||
Intl_FOUND - true if the libintl headers and libraries were found
|
||||
Intl_INCLUDE_DIRS - the directory containing the libintl headers
|
||||
Intl_LIBRARIES - libintl libraries to be linked
|
||||
|
||||
The following cache variables may also be set::
|
||||
|
||||
Intl_INCLUDE_DIR - the directory containing the libintl headers
|
||||
Intl_LIBRARY - the libintl library (if any)
|
||||
|
||||
.. note::
|
||||
On some platforms, such as Linux with GNU libc, the gettext
|
||||
functions are present in the C standard library and libintl
|
||||
is not required. ``Intl_LIBRARIES`` will be empty in this
|
||||
case.
|
||||
|
||||
.. note::
|
||||
If you wish to use the Gettext tools (``msgmerge``,
|
||||
``msgfmt``, etc.), use :module:`FindGettext`.
|
||||
#]=======================================================================]
|
||||
|
||||
|
||||
# Written by Roger Leigh <rleigh@codelibre.net>
|
||||
# Modified by Mateusz Przybył <matt@przybyl.io>
|
||||
|
||||
# Find include directory
|
||||
find_path(Intl_INCLUDE_DIR
|
||||
NAMES "libintl.h"
|
||||
DOC "libintl include directory")
|
||||
mark_as_advanced(Intl_INCLUDE_DIR)
|
||||
|
||||
# Find all Intl libraries
|
||||
find_library(Intl_LIBRARY NAMES intl libintl
|
||||
DOC "libintl libraries (if not in the C library)")
|
||||
mark_as_advanced(Intl_LIBRARY)
|
||||
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(Intl
|
||||
FOUND_VAR Intl_FOUND
|
||||
REQUIRED_VARS Intl_INCLUDE_DIR Intl_LIBRARY
|
||||
FAIL_MESSAGE "Failed to find Gettext libintl")
|
||||
|
||||
if(Intl_FOUND)
|
||||
set(Intl_INCLUDE_DIRS "${Intl_INCLUDE_DIR}")
|
||||
if(Intl_LIBRARY)
|
||||
set(Intl_LIBRARIES "${Intl_LIBRARY}")
|
||||
else()
|
||||
unset(Intl_LIBRARIES)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Export targets
|
||||
if(Intl_FOUND AND NOT TARGET Gettext::Intl)
|
||||
add_library(Gettext::Intl UNKNOWN IMPORTED)
|
||||
set_target_properties(Gettext::Intl PROPERTIES
|
||||
IMPORTED_LOCATION "${Intl_LIBRARY}"
|
||||
INTERFACE_INCLUDE_DIRECTORIES "${Intl_INCLUDE_DIR}")
|
||||
endif()
|
|
@ -0,0 +1,23 @@
|
|||
# Base Io build system
|
||||
# Written by Jeremy Tregunna <jeremy.tregunna@me.com>
|
||||
#
|
||||
# Find libsndfile.
|
||||
|
||||
FIND_PATH(LIBSNDFILE_INCLUDE_DIR sndfile.h)
|
||||
|
||||
SET(LIBSNDFILE_NAMES ${LIBSNDFILE_NAMES} sndfile libsndfile libsndfile-1)
|
||||
FIND_LIBRARY(LIBSNDFILE_LIBRARY NAMES ${LIBSNDFILE_NAMES} PATH)
|
||||
|
||||
IF(LIBSNDFILE_INCLUDE_DIR AND LIBSNDFILE_LIBRARY)
|
||||
SET(LIBSNDFILE_FOUND TRUE)
|
||||
ENDIF(LIBSNDFILE_INCLUDE_DIR AND LIBSNDFILE_LIBRARY)
|
||||
|
||||
IF(LIBSNDFILE_FOUND)
|
||||
IF(NOT LibSndFile_FIND_QUIETLY)
|
||||
MESSAGE(STATUS "Found LibSndFile: ${LIBSNDFILE_LIBRARY}")
|
||||
ENDIF (NOT LibSndFile_FIND_QUIETLY)
|
||||
ELSE(LIBSNDFILE_FOUND)
|
||||
IF(LibSndFile_FIND_REQUIRED)
|
||||
MESSAGE(FATAL_ERROR "Could not find sndfile")
|
||||
ENDIF(LibSndFile_FIND_REQUIRED)
|
||||
ENDIF (LIBSNDFILE_FOUND)
|
|
@ -1,63 +0,0 @@
|
|||
# - Find ogg
|
||||
# Find the native ogg includes and libraries
|
||||
#
|
||||
# OGG_INCLUDE_DIRS - where to find ogg.h, etc.
|
||||
# OGG_LIBRARIES - List of libraries when using ogg.
|
||||
# OGG_FOUND - True if ogg found.
|
||||
|
||||
# From https://github.com/erikd/libsndfile/
|
||||
|
||||
if (OGG_INCLUDE_DIR)
|
||||
# Already in cache, be silent
|
||||
set(OGG_FIND_QUIETLY TRUE)
|
||||
endif ()
|
||||
|
||||
find_package (PkgConfig QUIET)
|
||||
pkg_check_modules (PC_OGG QUIET ogg>=1.3.0)
|
||||
|
||||
set (OGG_VERSION ${PC_OGG_VERSION})
|
||||
|
||||
find_path (OGG_INCLUDE_DIR ogg/ogg.h
|
||||
HINTS
|
||||
${PC_OGG_INCLUDEDIR}
|
||||
${PC_OGG_INCLUDE_DIRS}
|
||||
${OGG_ROOT}
|
||||
)
|
||||
# MSVC built ogg may be named ogg_static.
|
||||
# The provided project files name the library with the lib prefix.
|
||||
find_library (OGG_LIBRARY
|
||||
NAMES
|
||||
ogg
|
||||
ogg_static
|
||||
libogg
|
||||
libogg_static
|
||||
HINTS
|
||||
${PC_OGG_LIBDIR}
|
||||
${PC_OGG_LIBRARY_DIRS}
|
||||
${OGG_ROOT}
|
||||
)
|
||||
# Handle the QUIETLY and REQUIRED arguments and set OGG_FOUND
|
||||
# to TRUE if all listed variables are TRUE.
|
||||
include (FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args (Ogg
|
||||
REQUIRED_VARS
|
||||
OGG_LIBRARY
|
||||
OGG_INCLUDE_DIR
|
||||
VERSION_VAR
|
||||
OGG_VERSION
|
||||
)
|
||||
|
||||
if (OGG_FOUND)
|
||||
set (OGG_LIBRARIES ${OGG_LIBRARY})
|
||||
set (OGG_INCLUDE_DIRS ${OGG_INCLUDE_DIR})
|
||||
|
||||
if(NOT TARGET Ogg::ogg)
|
||||
add_library(Ogg::ogg UNKNOWN IMPORTED)
|
||||
set_target_properties(Ogg::ogg PROPERTIES
|
||||
INTERFACE_INCLUDE_DIRECTORIES "${OGG_INCLUDE_DIRS}"
|
||||
IMPORTED_LOCATION "${OGG_LIBRARIES}"
|
||||
)
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
mark_as_advanced (OGG_INCLUDE_DIR OGG_LIBRARY)
|
|
@ -1,105 +0,0 @@
|
|||
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
||||
# file Copyright.txt or https://cmake.org/licensing for details.
|
||||
|
||||
#[=======================================================================[.rst:
|
||||
FindOpenAL
|
||||
----------
|
||||
|
||||
|
||||
Finds Open Audio Library (OpenAL).
|
||||
This module defines ``OPENAL_LIBRARY OPENAL_FOUND``, if
|
||||
false, do not try to link to OpenAL ``OPENAL_INCLUDE_DIR``, where to find
|
||||
the headers.
|
||||
|
||||
``$OPENALDIR`` is an environment variable that would correspond to the
|
||||
``./configure --prefix=$OPENALDIR`` used in building OpenAL.
|
||||
|
||||
Created by Eric Wing. This was influenced by the ``FindSDL.cmake``
|
||||
module.
|
||||
Modified by Mateusz Przybył <matt@przybyl.io>.
|
||||
#]=======================================================================]
|
||||
|
||||
# This makes the presumption that you are include al.h like
|
||||
# #include "al.h"
|
||||
# and not
|
||||
# #include <AL/al.h>
|
||||
# The reason for this is that the latter is not entirely portable.
|
||||
# Windows/Creative Labs does not by default put their headers in AL/ and
|
||||
# OS X uses the convention <OpenAL/al.h>.
|
||||
#
|
||||
# For Windows, Creative Labs seems to have added a registry key for their
|
||||
# OpenAL 1.1 installer. I have added that key to the list of search paths,
|
||||
# however, the key looks like it could be a little fragile depending on
|
||||
# if they decide to change the 1.00.0000 number for bug fix releases.
|
||||
# Also, they seem to have laid down groundwork for multiple library platforms
|
||||
# which puts the library in an extra subdirectory. Currently there is only
|
||||
# Win32 and I have hardcoded that here. This may need to be adjusted as
|
||||
# platforms are introduced.
|
||||
# The OpenAL 1.0 installer doesn't seem to have a useful key I can use.
|
||||
# I do not know if the Nvidia OpenAL SDK has a registry key.
|
||||
#
|
||||
# For OS X, remember that OpenAL was added by Apple in 10.4 (Tiger).
|
||||
# To support the framework, I originally wrote special framework detection
|
||||
# code in this module which I have now removed with CMake's introduction
|
||||
# of native support for frameworks.
|
||||
# In addition, OpenAL is open source, and it is possible to compile on Panther.
|
||||
# Furthermore, due to bugs in the initial OpenAL release, and the
|
||||
# transition to OpenAL 1.1, it is common to need to override the built-in
|
||||
# framework.
|
||||
# Per my request, CMake should search for frameworks first in
|
||||
# the following order:
|
||||
# ~/Library/Frameworks/OpenAL.framework/Headers
|
||||
# /Library/Frameworks/OpenAL.framework/Headers
|
||||
# /System/Library/Frameworks/OpenAL.framework/Headers
|
||||
#
|
||||
# On OS X, this will prefer the Framework version (if found) over others.
|
||||
# People will have to manually change the cache values of
|
||||
# OPENAL_LIBRARY to override this selection or set the CMake environment
|
||||
# CMAKE_INCLUDE_PATH to modify the search paths.
|
||||
|
||||
find_path(OPENAL_INCLUDE_DIR al.h
|
||||
HINTS
|
||||
ENV OPENALDIR
|
||||
PATH_SUFFIXES include/AL include/OpenAL include AL OpenAL
|
||||
PATHS
|
||||
~/Library/Frameworks
|
||||
/Library/Frameworks
|
||||
/opt
|
||||
[HKEY_LOCAL_MACHINE\\SOFTWARE\\Creative\ Labs\\OpenAL\ 1.1\ Software\ Development\ Kit\\1.00.0000;InstallDir]
|
||||
)
|
||||
|
||||
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||
set(_OpenAL_ARCH_DIR libs/Win64)
|
||||
else()
|
||||
set(_OpenAL_ARCH_DIR libs/Win32)
|
||||
endif()
|
||||
|
||||
find_library(OPENAL_LIBRARY
|
||||
NAMES OpenAL al openal OpenAL32
|
||||
HINTS
|
||||
ENV OPENALDIR
|
||||
PATH_SUFFIXES libx32 lib64 lib libs64 libs ${_OpenAL_ARCH_DIR}
|
||||
PATHS
|
||||
~/Library/Frameworks
|
||||
/Library/Frameworks
|
||||
/opt
|
||||
[HKEY_LOCAL_MACHINE\\SOFTWARE\\Creative\ Labs\\OpenAL\ 1.1\ Software\ Development\ Kit\\1.00.0000;InstallDir]
|
||||
)
|
||||
|
||||
unset(_OpenAL_ARCH_DIR)
|
||||
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(OpenAL DEFAULT_MSG OPENAL_LIBRARY OPENAL_INCLUDE_DIR)
|
||||
|
||||
mark_as_advanced(OPENAL_LIBRARY OPENAL_INCLUDE_DIR)
|
||||
|
||||
# Export targets
|
||||
# Note: OpenAL exports targets itself by OpenALConfig.cmake,
|
||||
# However, the file is not for some reason provided in packages in some Linux distros, e.g. Ubuntu 18.04
|
||||
# Hence this Find*.cmake file.
|
||||
if(OpenAL_FOUND AND NOT TARGET OpenAL::OpenAL)
|
||||
add_library(OpenAL::OpenAL UNKNOWN IMPORTED)
|
||||
set_target_properties(OpenAL::OpenAL PROPERTIES
|
||||
IMPORTED_LOCATION "${OPENAL_LIBRARY}"
|
||||
INTERFACE_INCLUDE_DIRECTORIES "${OPENAL_INCLUDE_DIR}"
|
||||
)
|
||||
endif()
|
|
@ -1,69 +0,0 @@
|
|||
# - Find opus
|
||||
# Find the native opus includes and libraries
|
||||
#
|
||||
# OPUS_INCLUDE_DIRS - where to find opus.h, etc.
|
||||
# OPUS_LIBRARIES - List of libraries when using opus.
|
||||
# OPUS_FOUND - True if Opus found.
|
||||
|
||||
# From https://github.com/erikd/libsndfile/
|
||||
|
||||
if (OPUS_INCLUDE_DIR)
|
||||
# Already in cache, be silent
|
||||
set(OPUS_FIND_QUIETLY TRUE)
|
||||
endif ()
|
||||
|
||||
find_package (Ogg QUIET)
|
||||
|
||||
find_package (PkgConfig QUIET)
|
||||
pkg_check_modules(PC_OPUS QUIET opus>=1.1)
|
||||
|
||||
set (OPUS_VERSION ${PC_OPUS_VERSION})
|
||||
|
||||
find_path (OPUS_INCLUDE_DIR opus/opus.h
|
||||
HINTS
|
||||
${PC_OPUS_INCLUDEDIR}
|
||||
${PC_OPUS_INCLUDE_DIRS}
|
||||
${OPUS_ROOT}
|
||||
)
|
||||
|
||||
# MSVC built opus may be named opus_static.
|
||||
# The provided project files name the library with the lib prefix.
|
||||
|
||||
find_library (OPUS_LIBRARY
|
||||
NAMES
|
||||
opus
|
||||
opus_static
|
||||
libopus
|
||||
libopus_static
|
||||
HINTS
|
||||
${PC_OPUS_LIBDIR}
|
||||
${PC_OPUS_LIBRARY_DIRS}
|
||||
${OPUS_ROOT}
|
||||
)
|
||||
|
||||
# Handle the QUIETLY and REQUIRED arguments and set OPUS_FOUND
|
||||
# to TRUE if all listed variables are TRUE.
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args (Opus
|
||||
REQUIRED_VARS
|
||||
OPUS_LIBRARY
|
||||
OPUS_INCLUDE_DIR
|
||||
OGG_FOUND
|
||||
VERSION_VAR
|
||||
OPUS_VERSION
|
||||
)
|
||||
|
||||
if (OPUS_FOUND)
|
||||
set (OPUS_LIBRARIES ${OPUS_LIBRARY})
|
||||
set (OPUS_INCLUDE_DIRS ${OPUS_INCLUDE_DIR})
|
||||
|
||||
if (NOT TARGET Opus::opus)
|
||||
add_library (Opus::opus UNKNOWN IMPORTED)
|
||||
set_target_properties (Opus::opus PROPERTIES
|
||||
INTERFACE_INCLUDE_DIRECTORIES "${OPUS_INCLUDE_DIRS}"
|
||||
IMPORTED_LOCATION "${OPUS_LIBRARIES}"
|
||||
)
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
mark_as_advanced(OPUS_INCLUDE_DIR OPUS_LIBRARY)
|
|
@ -33,12 +33,4 @@ ELSE (GLEW_INCLUDE_PATH)
|
|||
SET( PHYSFS_FOUND 0 CACHE STRING "Set to 1 if PhysFS is found, 0 otherwise")
|
||||
ENDIF (PHYSFS_INCLUDE_PATH)
|
||||
|
||||
MARK_AS_ADVANCED( PHYSFS_FOUND PHYSFS_INCLUDE_PATH PHYSFS_LIBRARY )
|
||||
|
||||
# Targets
|
||||
if(PHYSFS_FOUND AND NOT TARGET PhysFS::PhysFS)
|
||||
add_library(PhysFS::PhysFS UNKNOWN IMPORTED)
|
||||
set_target_properties(PhysFS::PhysFS PROPERTIES
|
||||
IMPORTED_LOCATION "${PHYSFS_LIBRARY}"
|
||||
INTERFACE_INCLUDE_DIRECTORIES "${PHYSFS_INCLUDE_PATH}")
|
||||
endif()
|
||||
MARK_AS_ADVANCED( PHYSFS_FOUND )
|
||||
|
|
|
@ -1,388 +1,163 @@
|
|||
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
||||
# file Copyright.txt or https://cmake.org/licensing for details.
|
||||
# Locate SDL2 library
|
||||
# This module defines
|
||||
# SDL2_LIBRARY, the name of the library to link against
|
||||
# SDL2_FOUND, if false, do not try to link to SDL2
|
||||
# SDL2_INCLUDE_DIR, where to find SDL.h
|
||||
#
|
||||
# This module responds to the the flag:
|
||||
# SDL2_BUILDING_LIBRARY
|
||||
# If this is defined, then no SDL2main will be linked in because
|
||||
# only applications need main().
|
||||
# Otherwise, it is assumed you are building an application and this
|
||||
# module will attempt to locate and set the the proper link flags
|
||||
# as part of the returned SDL2_LIBRARY variable.
|
||||
#
|
||||
# Don't forget to include SDLmain.h and SDLmain.m your project for the
|
||||
# OS X framework based version. (Other versions link to -lSDL2main which
|
||||
# this module will try to find on your behalf.) Also for OS X, this
|
||||
# module will automatically add the -framework Cocoa on your behalf.
|
||||
#
|
||||
#
|
||||
# Additional Note: If you see an empty SDL2_LIBRARY_TEMP in your configuration
|
||||
# and no SDL2_LIBRARY, it means CMake did not find your SDL2 library
|
||||
# (SDL2.dll, libsdl2.so, SDL2.framework, etc).
|
||||
# Set SDL2_LIBRARY_TEMP to point to your SDL2 library, and configure again.
|
||||
# Similarly, if you see an empty SDL2MAIN_LIBRARY, you should set this value
|
||||
# as appropriate. These values are used to generate the final SDL2_LIBRARY
|
||||
# variable, but when these values are unset, SDL2_LIBRARY does not get created.
|
||||
#
|
||||
#
|
||||
# $SDL2DIR is an environment variable that would
|
||||
# correspond to the ./configure --prefix=$SDL2DIR
|
||||
# used in building SDL2.
|
||||
# l.e.galup 9-20-02
|
||||
#
|
||||
# Modified by Eric Wing.
|
||||
# Added code to assist with automated building by using environmental variables
|
||||
# and providing a more controlled/consistent search behavior.
|
||||
# Added new modifications to recognize OS X frameworks and
|
||||
# additional Unix paths (FreeBSD, etc).
|
||||
# Also corrected the header search path to follow "proper" SDL guidelines.
|
||||
# Added a search for SDL2main which is needed by some platforms.
|
||||
# Added a search for threads which is needed by some platforms.
|
||||
# Added needed compile switches for MinGW.
|
||||
#
|
||||
# On OSX, this will prefer the Framework version (if found) over others.
|
||||
# People will have to manually change the cache values of
|
||||
# SDL2_LIBRARY to override this selection or set the CMake environment
|
||||
# CMAKE_INCLUDE_PATH to modify the search paths.
|
||||
#
|
||||
# Note that the header path has changed from SDL2/SDL.h to just SDL.h
|
||||
# This needed to change because "proper" SDL convention
|
||||
# is #include "SDL.h", not <SDL2/SDL.h>. This is done for portability
|
||||
# reasons because not all systems place things in SDL2/ (see FreeBSD).
|
||||
|
||||
# Copyright 2019 Amine Ben Hassouna <amine.benhassouna@gmail.com>
|
||||
# Copyright 2000-2019 Kitware, Inc. and Contributors
|
||||
# All rights reserved.
|
||||
#=============================================================================
|
||||
# Copyright 2003-2009 Kitware, Inc.
|
||||
#
|
||||
# Distributed under the OSI-approved BSD License (the "License");
|
||||
# see accompanying file Copyright.txt for details.
|
||||
#
|
||||
# This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
# See the License for more information.
|
||||
#=============================================================================
|
||||
# (To distribute this file outside of CMake, substitute the full
|
||||
# License text for the above reference.)
|
||||
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions
|
||||
# are met:
|
||||
|
||||
# * Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
|
||||
# * Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in the
|
||||
# documentation and/or other materials provided with the distribution.
|
||||
|
||||
# * Neither the name of Kitware, Inc. nor the names of Contributors
|
||||
# may be used to endorse or promote products derived from this
|
||||
# software without specific prior written permission.
|
||||
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#[=======================================================================[.rst:
|
||||
FindSDL2
|
||||
--------
|
||||
|
||||
Locate SDL2 library
|
||||
|
||||
This module defines the following 'IMPORTED' targets:
|
||||
|
||||
::
|
||||
|
||||
SDL2::Core
|
||||
The SDL2 library, if found.
|
||||
Libraries should link to SDL2::Core
|
||||
|
||||
SDL2::Main
|
||||
The SDL2main library, if found.
|
||||
Applications should link to SDL2::Main instead of SDL2::Core
|
||||
|
||||
|
||||
|
||||
This module will set the following variables in your project:
|
||||
|
||||
::
|
||||
|
||||
SDL2_LIBRARIES, the name of the library to link against
|
||||
SDL2_INCLUDE_DIRS, where to find SDL.h
|
||||
SDL2_FOUND, if false, do not try to link to SDL2
|
||||
SDL2MAIN_FOUND, if false, do not try to link to SDL2main
|
||||
SDL2_VERSION_STRING, human-readable string containing the version of SDL2
|
||||
|
||||
|
||||
|
||||
This module responds to the following cache variables:
|
||||
|
||||
::
|
||||
|
||||
SDL2_PATH
|
||||
Set a custom SDL2 Library path (default: empty)
|
||||
|
||||
SDL2_NO_DEFAULT_PATH
|
||||
Disable search SDL2 Library in default path.
|
||||
If SDL2_PATH (default: ON)
|
||||
Else (default: OFF)
|
||||
|
||||
SDL2_INCLUDE_DIR
|
||||
SDL2 headers path.
|
||||
|
||||
SDL2_LIBRARY
|
||||
SDL2 Library (.dll, .so, .a, etc) path.
|
||||
|
||||
SDL2MAIN_LIBRAY
|
||||
SDL2main Library (.a) path.
|
||||
|
||||
SDL2_BUILDING_LIBRARY
|
||||
This flag is useful only when linking to SDL2_LIBRARIES insead of
|
||||
SDL2::Main. It is required only when building a library that links to
|
||||
SDL2_LIBRARIES, because only applications need main() (No need to also
|
||||
link to SDL2main).
|
||||
If this flag is defined, then no SDL2main will be added to SDL2_LIBRARIES
|
||||
and no SDL2::Main target will be created.
|
||||
|
||||
|
||||
Don't forget to include SDLmain.h and SDLmain.m in your project for the
|
||||
OS X framework based version. (Other versions link to -lSDL2main which
|
||||
this module will try to find on your behalf.) Also for OS X, this
|
||||
module will automatically add the -framework Cocoa on your behalf.
|
||||
|
||||
|
||||
Additional Note: If you see an empty SDL2_LIBRARY in your project
|
||||
configuration, it means CMake did not find your SDL2 library
|
||||
(SDL2.dll, libsdl2.so, SDL2.framework, etc). Set SDL2_LIBRARY to point
|
||||
to your SDL2 library, and configure again. Similarly, if you see an
|
||||
empty SDL2MAIN_LIBRARY, you should set this value as appropriate. These
|
||||
values are used to generate the final SDL2_LIBRARIES variable and the
|
||||
SDL2::Core and SDL2::Main targets, but when these values are unset,
|
||||
SDL2_LIBRARIES, SDL2::Core and SDL2::Main does not get created.
|
||||
|
||||
|
||||
$SDL2DIR is an environment variable that would correspond to the
|
||||
./configure --prefix=$SDL2DIR used in building SDL2. l.e.galup 9-20-02
|
||||
|
||||
|
||||
|
||||
Created by Amine Ben Hassouna:
|
||||
Adapt FindSDL.cmake to SDL2 (FindSDL2.cmake).
|
||||
Add cache variables for more flexibility:
|
||||
SDL2_PATH, SDL2_NO_DEFAULT_PATH (for details, see doc above).
|
||||
Mark 'Threads' as a required dependency for non-OSX systems.
|
||||
Modernize the FindSDL2.cmake module by creating specific targets:
|
||||
SDL2::Core and SDL2::Main (for details, see doc above).
|
||||
|
||||
|
||||
Original FindSDL.cmake module:
|
||||
Modified by Eric Wing. Added code to assist with automated building
|
||||
by using environmental variables and providing a more
|
||||
controlled/consistent search behavior. Added new modifications to
|
||||
recognize OS X frameworks and additional Unix paths (FreeBSD, etc).
|
||||
Also corrected the header search path to follow "proper" SDL
|
||||
guidelines. Added a search for SDLmain which is needed by some
|
||||
platforms. Added a search for threads which is needed by some
|
||||
platforms. Added needed compile switches for MinGW.
|
||||
|
||||
On OSX, this will prefer the Framework version (if found) over others.
|
||||
People will have to manually change the cache value of SDL2_LIBRARY to
|
||||
override this selection or set the SDL2_PATH variable or the CMake
|
||||
environment CMAKE_INCLUDE_PATH to modify the search paths.
|
||||
|
||||
Note that the header path has changed from SDL/SDL.h to just SDL.h
|
||||
This needed to change because "proper" SDL convention is #include
|
||||
"SDL.h", not <SDL/SDL.h>. This is done for portability reasons
|
||||
because not all systems place things in SDL/ (see FreeBSD).
|
||||
#]=======================================================================]
|
||||
|
||||
# Define options for searching SDL2 Library in a custom path
|
||||
|
||||
set(SDL2_PATH "" CACHE STRING "Custom SDL2 Library path")
|
||||
|
||||
set(_SDL2_NO_DEFAULT_PATH OFF)
|
||||
if(SDL2_PATH)
|
||||
set(_SDL2_NO_DEFAULT_PATH ON)
|
||||
endif()
|
||||
|
||||
set(SDL2_NO_DEFAULT_PATH ${_SDL2_NO_DEFAULT_PATH}
|
||||
CACHE BOOL "Disable search SDL2 Library in default path")
|
||||
unset(_SDL2_NO_DEFAULT_PATH)
|
||||
|
||||
set(SDL2_NO_DEFAULT_PATH_CMD)
|
||||
if(SDL2_NO_DEFAULT_PATH)
|
||||
set(SDL2_NO_DEFAULT_PATH_CMD NO_DEFAULT_PATH)
|
||||
endif()
|
||||
|
||||
# Search for the SDL2 include directory
|
||||
find_path(SDL2_INCLUDE_DIR SDL.h
|
||||
HINTS
|
||||
ENV SDL2DIR
|
||||
${SDL2_NO_DEFAULT_PATH_CMD}
|
||||
PATH_SUFFIXES SDL2
|
||||
# path suffixes to search inside ENV{SDL2DIR}
|
||||
include/SDL2 include
|
||||
PATHS ${SDL2_PATH}
|
||||
DOC "Where the SDL2 headers can be found"
|
||||
SET(SDL2_SEARCH_PATHS
|
||||
~/Library/Frameworks
|
||||
/Library/Frameworks
|
||||
/usr/local
|
||||
/usr
|
||||
/sw # Fink
|
||||
/opt/local # DarwinPorts
|
||||
/opt/csw # Blastwave
|
||||
/opt
|
||||
)
|
||||
|
||||
set(SDL2_INCLUDE_DIRS "${SDL2_INCLUDE_DIR}")
|
||||
|
||||
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||
set(VC_LIB_PATH_SUFFIX lib/x64)
|
||||
else()
|
||||
set(VC_LIB_PATH_SUFFIX lib/x86)
|
||||
endif()
|
||||
|
||||
# SDL-2.0 is the name used by FreeBSD ports...
|
||||
# don't confuse it for the version number.
|
||||
find_library(SDL2_LIBRARY
|
||||
NAMES SDL2 SDL-2.0 SDL2-static
|
||||
HINTS
|
||||
ENV SDL2DIR
|
||||
${SDL2_NO_DEFAULT_PATH_CMD}
|
||||
PATH_SUFFIXES lib ${VC_LIB_PATH_SUFFIX}
|
||||
PATHS ${SDL2_PATH}
|
||||
DOC "Where the SDL2 Library can be found"
|
||||
FIND_PATH(SDL2_INCLUDE_DIR SDL.h
|
||||
HINTS
|
||||
$ENV{SDL2DIR}
|
||||
PATH_SUFFIXES include/SDL2 include
|
||||
PATHS ${SDL2_SEARCH_PATHS}
|
||||
)
|
||||
|
||||
set(SDL2_LIBRARIES "${SDL2_LIBRARY}")
|
||||
FIND_LIBRARY(SDL2_LIBRARY_TEMP
|
||||
NAMES SDL2
|
||||
HINTS
|
||||
$ENV{SDL2DIR}
|
||||
PATH_SUFFIXES lib64 lib
|
||||
PATHS ${SDL2_SEARCH_PATHS}
|
||||
)
|
||||
|
||||
if(NOT SDL2_BUILDING_LIBRARY)
|
||||
if(NOT SDL2_INCLUDE_DIR MATCHES ".framework")
|
||||
# Non-OS X framework versions expect you to also dynamically link to
|
||||
# SDL2main. This is mainly for Windows and OS X. Other (Unix) platforms
|
||||
# seem to provide SDL2main for compatibility even though they don't
|
||||
# necessarily need it.
|
||||
|
||||
if(SDL2_PATH)
|
||||
set(SDL2MAIN_LIBRARY_PATHS "${SDL2_PATH}")
|
||||
endif()
|
||||
|
||||
if(NOT SDL2_NO_DEFAULT_PATH)
|
||||
set(SDL2MAIN_LIBRARY_PATHS
|
||||
/sw
|
||||
/opt/local
|
||||
/opt/csw
|
||||
/opt
|
||||
"${SDL2MAIN_LIBRARY_PATHS}"
|
||||
)
|
||||
endif()
|
||||
|
||||
find_library(SDL2MAIN_LIBRARY
|
||||
NAMES SDL2main
|
||||
HINTS
|
||||
ENV SDL2DIR
|
||||
${SDL2_NO_DEFAULT_PATH_CMD}
|
||||
PATH_SUFFIXES lib lib/manual-link ${VC_LIB_PATH_SUFFIX}
|
||||
PATHS ${SDL2MAIN_LIBRARY_PATHS}
|
||||
DOC "Where the SDL2main library can be found"
|
||||
)
|
||||
unset(SDL2MAIN_LIBRARY_PATHS)
|
||||
endif()
|
||||
endif()
|
||||
IF(NOT SDL2_BUILDING_LIBRARY)
|
||||
IF(NOT ${SDL2_INCLUDE_DIR} MATCHES ".framework")
|
||||
# Non-OS X framework versions expect you to also dynamically link to
|
||||
# SDL2main. This is mainly for Windows and OS X. Other (Unix) platforms
|
||||
# seem to provide SDL2main for compatibility even though they don't
|
||||
# necessarily need it.
|
||||
FIND_LIBRARY(SDL2MAIN_LIBRARY
|
||||
NAMES SDL2main
|
||||
HINTS
|
||||
$ENV{SDL2DIR}
|
||||
PATH_SUFFIXES lib64 lib
|
||||
PATHS ${SDL2_SEARCH_PATHS}
|
||||
)
|
||||
ENDIF(NOT ${SDL2_INCLUDE_DIR} MATCHES ".framework")
|
||||
ENDIF(NOT SDL2_BUILDING_LIBRARY)
|
||||
|
||||
# SDL2 may require threads on your system.
|
||||
# The Apple build may not need an explicit flag because one of the
|
||||
# frameworks may already provide it.
|
||||
# But for non-OSX systems, I will use the CMake Threads package.
|
||||
if(NOT APPLE)
|
||||
find_package(Threads QUIET)
|
||||
if(NOT Threads_FOUND)
|
||||
set(SDL2_THREADS_NOT_FOUND "Could NOT find Threads (Threads is required by SDL2).")
|
||||
if(SDL2_FIND_REQUIRED)
|
||||
message(FATAL_ERROR ${SDL2_THREADS_NOT_FOUND})
|
||||
else()
|
||||
if(NOT SDL2_FIND_QUIETLY)
|
||||
message(STATUS ${SDL2_THREADS_NOT_FOUND})
|
||||
endif()
|
||||
return()
|
||||
endif()
|
||||
unset(SDL2_THREADS_NOT_FOUND)
|
||||
endif()
|
||||
endif()
|
||||
IF(NOT APPLE)
|
||||
FIND_PACKAGE(Threads)
|
||||
ENDIF(NOT APPLE)
|
||||
|
||||
# MinGW needs an additional link flag, -mwindows
|
||||
# It's total link flags should look like -lmingw32 -lSDL2main -lSDL2 -mwindows
|
||||
if(MINGW)
|
||||
set(MINGW32_LIBRARY mingw32 "-mwindows" CACHE STRING "link flags for MinGW")
|
||||
endif()
|
||||
# MinGW needs an additional library, mwindows
|
||||
# It's total link flags should look like -lmingw32 -lSDL2main -lSDL2 -lmwindows
|
||||
# (Actually on second look, I think it only needs one of the m* libraries.)
|
||||
IF(MINGW)
|
||||
SET(MINGW32_LIBRARY mingw32 CACHE STRING "mwindows for MinGW")
|
||||
ENDIF(MINGW)
|
||||
|
||||
if(SDL2_LIBRARY)
|
||||
# For SDL2main
|
||||
if(SDL2MAIN_LIBRARY AND NOT SDL2_BUILDING_LIBRARY)
|
||||
list(FIND SDL2_LIBRARIES "${SDL2MAIN_LIBRARY}" _SDL2_MAIN_INDEX)
|
||||
if(_SDL2_MAIN_INDEX EQUAL -1)
|
||||
set(SDL2_LIBRARIES "${SDL2MAIN_LIBRARY}" ${SDL2_LIBRARIES})
|
||||
endif()
|
||||
unset(_SDL2_MAIN_INDEX)
|
||||
endif()
|
||||
IF(SDL2_LIBRARY_TEMP)
|
||||
# For SDL2main
|
||||
IF(NOT SDL2_BUILDING_LIBRARY)
|
||||
IF(SDL2MAIN_LIBRARY)
|
||||
SET(SDL2_LIBRARY_TEMP ${SDL2MAIN_LIBRARY} ${SDL2_LIBRARY_TEMP})
|
||||
ENDIF(SDL2MAIN_LIBRARY)
|
||||
ENDIF(NOT SDL2_BUILDING_LIBRARY)
|
||||
|
||||
# For OS X, SDL2 uses Cocoa as a backend so it must link to Cocoa.
|
||||
# CMake doesn't display the -framework Cocoa string in the UI even
|
||||
# though it actually is there if I modify a pre-used variable.
|
||||
# I think it has something to do with the CACHE STRING.
|
||||
# So I use a temporary variable until the end so I can set the
|
||||
# "real" variable in one-shot.
|
||||
if(APPLE)
|
||||
set(SDL2_LIBRARIES ${SDL2_LIBRARIES} -framework Cocoa)
|
||||
endif()
|
||||
# For OS X, SDL2 uses Cocoa as a backend so it must link to Cocoa.
|
||||
# CMake doesn't display the -framework Cocoa string in the UI even
|
||||
# though it actually is there if I modify a pre-used variable.
|
||||
# I think it has something to do with the CACHE STRING.
|
||||
# So I use a temporary variable until the end so I can set the
|
||||
# "real" variable in one-shot.
|
||||
IF(APPLE)
|
||||
SET(SDL2_LIBRARY_TEMP ${SDL2_LIBRARY_TEMP} "-framework Cocoa")
|
||||
ENDIF(APPLE)
|
||||
|
||||
# For threads, as mentioned Apple doesn't need this.
|
||||
# In fact, there seems to be a problem if I used the Threads package
|
||||
# and try using this line, so I'm just skipping it entirely for OS X.
|
||||
if(NOT APPLE)
|
||||
set(SDL2_LIBRARIES ${SDL2_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT})
|
||||
endif()
|
||||
# For threads, as mentioned Apple doesn't need this.
|
||||
# In fact, there seems to be a problem if I used the Threads package
|
||||
# and try using this line, so I'm just skipping it entirely for OS X.
|
||||
IF(NOT APPLE)
|
||||
SET(SDL2_LIBRARY_TEMP ${SDL2_LIBRARY_TEMP} ${CMAKE_THREAD_LIBS_INIT})
|
||||
ENDIF(NOT APPLE)
|
||||
|
||||
# For MinGW library
|
||||
if(MINGW)
|
||||
set(SDL2_LIBRARIES ${MINGW32_LIBRARY} ${SDL2_LIBRARIES})
|
||||
endif()
|
||||
# For MinGW library
|
||||
IF(MINGW)
|
||||
SET(SDL2_LIBRARY_TEMP ${MINGW32_LIBRARY} ${SDL2_LIBRARY_TEMP})
|
||||
ENDIF(MINGW)
|
||||
|
||||
endif()
|
||||
# Set the final string here so the GUI reflects the final state.
|
||||
SET(SDL2_LIBRARY ${SDL2_LIBRARY_TEMP} CACHE STRING "Where the SDL2 Library can be found")
|
||||
# Set the temp variable to INTERNAL so it is not seen in the CMake GUI
|
||||
SET(SDL2_LIBRARY_TEMP "${SDL2_LIBRARY_TEMP}" CACHE INTERNAL "")
|
||||
ENDIF(SDL2_LIBRARY_TEMP)
|
||||
|
||||
# Read SDL2 version
|
||||
if(SDL2_INCLUDE_DIR AND EXISTS "${SDL2_INCLUDE_DIR}/SDL_version.h")
|
||||
file(STRINGS "${SDL2_INCLUDE_DIR}/SDL_version.h" SDL2_VERSION_MAJOR_LINE REGEX "^#define[ \t]+SDL_MAJOR_VERSION[ \t]+[0-9]+$")
|
||||
file(STRINGS "${SDL2_INCLUDE_DIR}/SDL_version.h" SDL2_VERSION_MINOR_LINE REGEX "^#define[ \t]+SDL_MINOR_VERSION[ \t]+[0-9]+$")
|
||||
file(STRINGS "${SDL2_INCLUDE_DIR}/SDL_version.h" SDL2_VERSION_PATCH_LINE REGEX "^#define[ \t]+SDL_PATCHLEVEL[ \t]+[0-9]+$")
|
||||
string(REGEX REPLACE "^#define[ \t]+SDL_MAJOR_VERSION[ \t]+([0-9]+)$" "\\1" SDL2_VERSION_MAJOR "${SDL2_VERSION_MAJOR_LINE}")
|
||||
string(REGEX REPLACE "^#define[ \t]+SDL_MINOR_VERSION[ \t]+([0-9]+)$" "\\1" SDL2_VERSION_MINOR "${SDL2_VERSION_MINOR_LINE}")
|
||||
string(REGEX REPLACE "^#define[ \t]+SDL_PATCHLEVEL[ \t]+([0-9]+)$" "\\1" SDL2_VERSION_PATCH "${SDL2_VERSION_PATCH_LINE}")
|
||||
set(SDL2_VERSION_STRING ${SDL2_VERSION_MAJOR}.${SDL2_VERSION_MINOR}.${SDL2_VERSION_PATCH})
|
||||
unset(SDL2_VERSION_MAJOR_LINE)
|
||||
unset(SDL2_VERSION_MINOR_LINE)
|
||||
unset(SDL2_VERSION_PATCH_LINE)
|
||||
unset(SDL2_VERSION_MAJOR)
|
||||
unset(SDL2_VERSION_MINOR)
|
||||
unset(SDL2_VERSION_PATCH)
|
||||
endif()
|
||||
INCLUDE(FindPackageHandleStandardArgs)
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(SDL2
|
||||
REQUIRED_VARS SDL2_LIBRARY SDL2_INCLUDE_DIR
|
||||
VERSION_VAR SDL2_VERSION_STRING)
|
||||
|
||||
if(SDL2MAIN_LIBRARY)
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(SDL2main
|
||||
REQUIRED_VARS SDL2MAIN_LIBRARY SDL2_INCLUDE_DIR
|
||||
VERSION_VAR SDL2_VERSION_STRING)
|
||||
endif()
|
||||
|
||||
|
||||
mark_as_advanced(SDL2_PATH
|
||||
SDL2_NO_DEFAULT_PATH
|
||||
SDL2_LIBRARY
|
||||
SDL2MAIN_LIBRARY
|
||||
SDL2_INCLUDE_DIR
|
||||
SDL2_BUILDING_LIBRARY)
|
||||
|
||||
|
||||
# SDL2:: targets (SDL2::Core and SDL2::Main)
|
||||
if(SDL2_FOUND)
|
||||
|
||||
# SDL2::Core target
|
||||
if(SDL2_LIBRARY AND NOT TARGET SDL2::Core)
|
||||
add_library(SDL2::Core UNKNOWN IMPORTED)
|
||||
set_target_properties(SDL2::Core PROPERTIES
|
||||
IMPORTED_LOCATION "${SDL2_LIBRARY}"
|
||||
INTERFACE_INCLUDE_DIRECTORIES "${SDL2_INCLUDE_DIR}")
|
||||
|
||||
if(APPLE)
|
||||
# For OS X, SDL2 uses Cocoa as a backend so it must link to Cocoa.
|
||||
# For more details, please see above.
|
||||
set_property(TARGET SDL2::Core APPEND PROPERTY
|
||||
INTERFACE_LINK_OPTIONS -framework Cocoa)
|
||||
else()
|
||||
# For threads, as mentioned Apple doesn't need this.
|
||||
# For more details, please see above.
|
||||
set_property(TARGET SDL2::Core APPEND PROPERTY
|
||||
INTERFACE_LINK_LIBRARIES Threads::Threads)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# SDL2::Main target
|
||||
# Applications should link to SDL2::Main instead of SDL2::Core
|
||||
# For more details, please see above.
|
||||
if(NOT SDL2_BUILDING_LIBRARY AND NOT TARGET SDL2::Main)
|
||||
|
||||
if(SDL2_INCLUDE_DIR MATCHES ".framework" OR NOT SDL2MAIN_LIBRARY)
|
||||
add_library(SDL2::Main INTERFACE IMPORTED)
|
||||
set_property(TARGET SDL2::Main PROPERTY
|
||||
INTERFACE_LINK_LIBRARIES SDL2::Core)
|
||||
elseif(SDL2MAIN_LIBRARY)
|
||||
# MinGW requires that the mingw32 library is specified before the
|
||||
# libSDL2main.a static library when linking.
|
||||
# The SDL2::MainInternal target is used internally to make sure that
|
||||
# CMake respects this condition.
|
||||
add_library(SDL2::MainInternal UNKNOWN IMPORTED)
|
||||
set_property(TARGET SDL2::MainInternal PROPERTY
|
||||
IMPORTED_LOCATION "${SDL2MAIN_LIBRARY}")
|
||||
set_property(TARGET SDL2::MainInternal PROPERTY
|
||||
INTERFACE_LINK_LIBRARIES SDL2::Core)
|
||||
|
||||
add_library(SDL2::Main INTERFACE IMPORTED)
|
||||
|
||||
if(MINGW)
|
||||
# MinGW needs an additional link flag '-mwindows' and link to mingw32
|
||||
set_property(TARGET SDL2::Main PROPERTY
|
||||
INTERFACE_LINK_LIBRARIES "mingw32" "-mwindows")
|
||||
endif()
|
||||
|
||||
set_property(TARGET SDL2::Main APPEND PROPERTY
|
||||
INTERFACE_LINK_LIBRARIES SDL2::MainInternal)
|
||||
endif()
|
||||
|
||||
endif()
|
||||
endif()
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(SDL2 REQUIRED_VARS SDL2_LIBRARY SDL2_INCLUDE_DIR)
|
||||
|
|
|
@ -1,222 +1,158 @@
|
|||
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
||||
# file Copyright.txt or https://cmake.org/licensing for details.
|
||||
# Locate SDL2_image library
|
||||
# This module defines
|
||||
# SDL2_IMAGE_LIBRARY, the name of the library to link against
|
||||
# SDL2_IMAGE_FOUND, if false, do not try to link to SDL2_image
|
||||
# SDL2_IMAGE_INCLUDE_DIR, where to find SDL_image.h
|
||||
#
|
||||
# Additional Note: If you see an empty SDL2_IMAGE_LIBRARY_TEMP in your configuration
|
||||
# and no SDL2_IMAGE_LIBRARY, it means CMake did not find your SDL2_Image library
|
||||
# (SDL2_image.dll, libsdl2_image.so, SDL2_image.framework, etc).
|
||||
# Set SDL2_IMAGE_LIBRARY_TEMP to point to your SDL2 library, and configure again.
|
||||
# Similarly, if you see an empty SDL2MAIN_LIBRARY, you should set this value
|
||||
# as appropriate. These values are used to generate the final SDL2_IMAGE_LIBRARY
|
||||
# variable, but when these values are unset, SDL2_IMAGE_LIBRARY does not get created.
|
||||
#
|
||||
# $SDL2 is an environment variable that would
|
||||
# correspond to the ./configure --prefix=$SDL2
|
||||
# used in building SDL2.
|
||||
# l.e.galup 9-20-02
|
||||
#
|
||||
# Modified by Eric Wing.
|
||||
# Added code to assist with automated building by using environmental variables
|
||||
# and providing a more controlled/consistent search behavior.
|
||||
# Added new modifications to recognize OS X frameworks and
|
||||
# additional Unix paths (FreeBSD, etc).
|
||||
# Also corrected the header search path to follow "proper" SDL2 guidelines.
|
||||
# Added a search for SDL2main which is needed by some platforms.
|
||||
# Added a search for threads which is needed by some platforms.
|
||||
# Added needed compile switches for MinGW.
|
||||
#
|
||||
# On OSX, this will prefer the Framework version (if found) over others.
|
||||
# People will have to manually change the cache values of
|
||||
# SDL2_IMAGE_LIBRARY to override this selection or set the CMake environment
|
||||
# CMAKE_INCLUDE_PATH to modify the search paths.
|
||||
#
|
||||
# Note that the header path has changed from SDL2/SDL.h to just SDL.h
|
||||
# This needed to change because "proper" SDL2 convention
|
||||
# is #include "SDL.h", not <SDL2/SDL.h>. This is done for portability
|
||||
# reasons because not all systems place things in SDL2/ (see FreeBSD).
|
||||
#
|
||||
# Ported by Johnny Patterson. This is a literal port for SDL2 of the FindSDL.cmake
|
||||
# module with the minor edit of changing "SDL" to "SDL2" where necessary. This
|
||||
# was not created for redistribution, and exists temporarily pending official
|
||||
# SDL2 CMake modules.
|
||||
#
|
||||
# Note that on windows this will only search for the 32bit libraries, to search
|
||||
# for 64bit change x86/i686-w64 to x64/x86_64-w64
|
||||
|
||||
# Copyright 2019 Amine Ben Hassouna <amine.benhassouna@gmail.com>
|
||||
# Copyright 2000-2019 Kitware, Inc. and Contributors
|
||||
# All rights reserved.
|
||||
#=============================================================================
|
||||
# Copyright 2003-2009 Kitware, Inc.
|
||||
#
|
||||
# CMake - Cross Platform Makefile Generator
|
||||
# Copyright 2000-2014 Kitware, Inc.
|
||||
# Copyright 2000-2011 Insight Software Consortium
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions
|
||||
# are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
#
|
||||
# * Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in the
|
||||
# documentation and/or other materials provided with the distribution.
|
||||
#
|
||||
# * Neither the names of Kitware, Inc., the Insight Software Consortium,
|
||||
# nor the names of their contributors may be used to endorse or promote
|
||||
# products derived from this software without specific prior written
|
||||
# permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
# This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
# See the License for more information.
|
||||
#=============================================================================
|
||||
# (To distribute this file outside of CMake, substitute the full
|
||||
# License text for the above reference.)
|
||||
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions
|
||||
# are met:
|
||||
|
||||
# * Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
|
||||
# * Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in the
|
||||
# documentation and/or other materials provided with the distribution.
|
||||
|
||||
# * Neither the name of Kitware, Inc. nor the names of Contributors
|
||||
# may be used to endorse or promote products derived from this
|
||||
# software without specific prior written permission.
|
||||
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#[=======================================================================[.rst:
|
||||
FindSDL2_image
|
||||
--------------
|
||||
|
||||
Locate SDL2_image library
|
||||
|
||||
This module defines the following 'IMPORTED' target:
|
||||
|
||||
::
|
||||
|
||||
SDL2::Image
|
||||
The SDL2_image library, if found.
|
||||
Have SDL2::Core as a link dependency.
|
||||
|
||||
|
||||
|
||||
This module will set the following variables in your project:
|
||||
|
||||
::
|
||||
|
||||
SDL2_IMAGE_LIBRARIES, the name of the library to link against
|
||||
SDL2_IMAGE_INCLUDE_DIRS, where to find the headers
|
||||
SDL2_IMAGE_FOUND, if false, do not try to link against
|
||||
SDL2_IMAGE_VERSION_STRING - human-readable string containing the
|
||||
version of SDL2_image
|
||||
|
||||
|
||||
|
||||
This module responds to the following cache variables:
|
||||
|
||||
::
|
||||
|
||||
SDL2_IMAGE_PATH
|
||||
Set a custom SDL2_image Library path (default: empty)
|
||||
|
||||
SDL2_IMAGE_NO_DEFAULT_PATH
|
||||
Disable search SDL2_image Library in default path.
|
||||
If SDL2_IMAGE_PATH (default: ON)
|
||||
Else (default: OFF)
|
||||
|
||||
SDL2_IMAGE_INCLUDE_DIR
|
||||
SDL2_image headers path.
|
||||
|
||||
SDL2_IMAGE_LIBRARY
|
||||
SDL2_image Library (.dll, .so, .a, etc) path.
|
||||
|
||||
|
||||
Additional Note: If you see an empty SDL2_IMAGE_LIBRARY in your project
|
||||
configuration, it means CMake did not find your SDL2_image library
|
||||
(SDL2_image.dll, libsdl2_image.so, etc). Set SDL2_IMAGE_LIBRARY to point
|
||||
to your SDL2_image library, and configure again. This value is used to
|
||||
generate the final SDL2_IMAGE_LIBRARIES variable and the SDL2::Image target,
|
||||
but when this value is unset, SDL2_IMAGE_LIBRARIES and SDL2::Image does not
|
||||
get created.
|
||||
|
||||
|
||||
$SDL2IMAGEDIR is an environment variable that would correspond to the
|
||||
./configure --prefix=$SDL2IMAGEDIR used in building SDL2_image.
|
||||
|
||||
$SDL2DIR is an environment variable that would correspond to the
|
||||
./configure --prefix=$SDL2DIR used in building SDL2.
|
||||
|
||||
|
||||
|
||||
Created by Amine Ben Hassouna:
|
||||
Adapt FindSDL_image.cmake to SDL2_image (FindSDL2_image.cmake).
|
||||
Add cache variables for more flexibility:
|
||||
SDL2_IMAGE_PATH, SDL2_IMAGE_NO_DEFAULT_PATH (for details, see doc above).
|
||||
Add SDL2 as a required dependency.
|
||||
Modernize the FindSDL2_image.cmake module by creating a specific target:
|
||||
SDL2::Image (for details, see doc above).
|
||||
|
||||
Original FindSDL_image.cmake module:
|
||||
Created by Eric Wing. This was influenced by the FindSDL.cmake
|
||||
module, but with modifications to recognize OS X frameworks and
|
||||
additional Unix paths (FreeBSD, etc).
|
||||
#]=======================================================================]
|
||||
|
||||
# SDL2 Library required
|
||||
find_package(SDL2 QUIET)
|
||||
if(NOT SDL2_FOUND)
|
||||
set(SDL2_IMAGE_SDL2_NOT_FOUND "Could NOT find SDL2 (SDL2 is required by SDL2_image).")
|
||||
if(SDL2_image_FIND_REQUIRED)
|
||||
message(FATAL_ERROR ${SDL2_IMAGE_SDL2_NOT_FOUND})
|
||||
else()
|
||||
if(NOT SDL2_image_FIND_QUIETLY)
|
||||
message(STATUS ${SDL2_IMAGE_SDL2_NOT_FOUND})
|
||||
endif()
|
||||
return()
|
||||
endif()
|
||||
unset(SDL2_IMAGE_SDL2_NOT_FOUND)
|
||||
endif()
|
||||
|
||||
|
||||
# Define options for searching SDL2_image Library in a custom path
|
||||
|
||||
set(SDL2_IMAGE_PATH "" CACHE STRING "Custom SDL2_image Library path")
|
||||
|
||||
set(_SDL2_IMAGE_NO_DEFAULT_PATH OFF)
|
||||
if(SDL2_IMAGE_PATH)
|
||||
set(_SDL2_IMAGE_NO_DEFAULT_PATH ON)
|
||||
endif()
|
||||
|
||||
set(SDL2_IMAGE_NO_DEFAULT_PATH ${_SDL2_IMAGE_NO_DEFAULT_PATH}
|
||||
CACHE BOOL "Disable search SDL2_image Library in default path")
|
||||
unset(_SDL2_IMAGE_NO_DEFAULT_PATH)
|
||||
|
||||
set(SDL2_IMAGE_NO_DEFAULT_PATH_CMD)
|
||||
if(SDL2_IMAGE_NO_DEFAULT_PATH)
|
||||
set(SDL2_IMAGE_NO_DEFAULT_PATH_CMD NO_DEFAULT_PATH)
|
||||
endif()
|
||||
|
||||
# Search for the SDL2_image include directory
|
||||
find_path(SDL2_IMAGE_INCLUDE_DIR SDL_image.h
|
||||
HINTS
|
||||
ENV SDL2IMAGEDIR
|
||||
ENV SDL2DIR
|
||||
${SDL2_IMAGE_NO_DEFAULT_PATH_CMD}
|
||||
PATH_SUFFIXES SDL2
|
||||
# path suffixes to search inside ENV{SDL2DIR}
|
||||
# and ENV{SDL2IMAGEDIR}
|
||||
include/SDL2 include
|
||||
PATHS ${SDL2_IMAGE_PATH}
|
||||
DOC "Where the SDL2_image headers can be found"
|
||||
FIND_PATH(SDL2_IMAGE_INCLUDE_DIR SDL_image.h
|
||||
HINTS
|
||||
${SDL2}
|
||||
$ENV{SDL2}
|
||||
$ENV{SDL2_IMAGE}
|
||||
PATH_SUFFIXES include/SDL2 include SDL2
|
||||
i686-w64-mingw32/include/SDL2
|
||||
x86_64-w64-mingw32/include/SDL2
|
||||
PATHS
|
||||
~/Library/Frameworks
|
||||
/Library/Frameworks
|
||||
/usr/local/include/SDL2
|
||||
/usr/include/SDL2
|
||||
/sw # Fink
|
||||
/opt/local # DarwinPorts
|
||||
/opt/csw # Blastwave
|
||||
/opt
|
||||
)
|
||||
|
||||
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||
set(VC_LIB_PATH_SUFFIX lib/x64)
|
||||
else()
|
||||
set(VC_LIB_PATH_SUFFIX lib/x86)
|
||||
endif()
|
||||
# Lookup the 64 bit libs on x64
|
||||
IF(CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||
FIND_LIBRARY(SDL2_IMAGE_LIBRARY_TEMP
|
||||
NAMES SDL2_image
|
||||
HINTS
|
||||
${SDL2}
|
||||
$ENV{SDL2}
|
||||
$ENV{SDL2_IMAGE}
|
||||
PATH_SUFFIXES lib64 lib
|
||||
lib/x64
|
||||
x86_64-w64-mingw32/lib
|
||||
PATHS
|
||||
/sw
|
||||
/opt/local
|
||||
/opt/csw
|
||||
/opt
|
||||
)
|
||||
# On 32bit build find the 32bit libs
|
||||
ELSE(CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||
FIND_LIBRARY(SDL2_IMAGE_LIBRARY_TEMP
|
||||
NAMES SDL2_image
|
||||
HINTS
|
||||
${SDL2}
|
||||
$ENV{SDL2}
|
||||
$ENV{SDL2_IMAGE}
|
||||
PATH_SUFFIXES lib
|
||||
lib/x86
|
||||
i686-w64-mingw32/lib
|
||||
PATHS
|
||||
/sw
|
||||
/opt/local
|
||||
/opt/csw
|
||||
/opt
|
||||
)
|
||||
ENDIF(CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||
|
||||
# Search for the SDL2_image library
|
||||
find_library(SDL2_IMAGE_LIBRARY
|
||||
NAMES SDL2_image SDL2_image-static
|
||||
HINTS
|
||||
ENV SDL2IMAGEDIR
|
||||
ENV SDL2DIR
|
||||
${SDL2_IMAGE_NO_DEFAULT_PATH_CMD}
|
||||
PATH_SUFFIXES lib ${VC_LIB_PATH_SUFFIX}
|
||||
PATHS ${SDL2_IMAGE_PATH}
|
||||
DOC "Where the SDL2_image Library can be found"
|
||||
)
|
||||
SET(SDL2_IMAGE_FOUND "NO")
|
||||
IF(SDL2_IMAGE_LIBRARY_TEMP)
|
||||
# Set the final string here so the GUI reflects the final state.
|
||||
SET(SDL2_IMAGE_LIBRARY ${SDL2_IMAGE_LIBRARY_TEMP} CACHE STRING "Where the SDL2_image Library can be found")
|
||||
# Set the temp variable to INTERNAL so it is not seen in the CMake GUI
|
||||
SET(SDL2_IMAGE_LIBRARY_TEMP "${SDL2_IMAGE_LIBRARY_TEMP}" CACHE INTERNAL "")
|
||||
SET(SDL2_IMAGE_FOUND "YES")
|
||||
ENDIF(SDL2_IMAGE_LIBRARY_TEMP)
|
||||
|
||||
# Read SDL2_image version
|
||||
if(SDL2_IMAGE_INCLUDE_DIR AND EXISTS "${SDL2_IMAGE_INCLUDE_DIR}/SDL_image.h")
|
||||
file(STRINGS "${SDL2_IMAGE_INCLUDE_DIR}/SDL_image.h" SDL2_IMAGE_VERSION_MAJOR_LINE REGEX "^#define[ \t]+SDL_IMAGE_MAJOR_VERSION[ \t]+[0-9]+$")
|
||||
file(STRINGS "${SDL2_IMAGE_INCLUDE_DIR}/SDL_image.h" SDL2_IMAGE_VERSION_MINOR_LINE REGEX "^#define[ \t]+SDL_IMAGE_MINOR_VERSION[ \t]+[0-9]+$")
|
||||
file(STRINGS "${SDL2_IMAGE_INCLUDE_DIR}/SDL_image.h" SDL2_IMAGE_VERSION_PATCH_LINE REGEX "^#define[ \t]+SDL_IMAGE_PATCHLEVEL[ \t]+[0-9]+$")
|
||||
string(REGEX REPLACE "^#define[ \t]+SDL_IMAGE_MAJOR_VERSION[ \t]+([0-9]+)$" "\\1" SDL2_IMAGE_VERSION_MAJOR "${SDL2_IMAGE_VERSION_MAJOR_LINE}")
|
||||
string(REGEX REPLACE "^#define[ \t]+SDL_IMAGE_MINOR_VERSION[ \t]+([0-9]+)$" "\\1" SDL2_IMAGE_VERSION_MINOR "${SDL2_IMAGE_VERSION_MINOR_LINE}")
|
||||
string(REGEX REPLACE "^#define[ \t]+SDL_IMAGE_PATCHLEVEL[ \t]+([0-9]+)$" "\\1" SDL2_IMAGE_VERSION_PATCH "${SDL2_IMAGE_VERSION_PATCH_LINE}")
|
||||
set(SDL2_IMAGE_VERSION_STRING ${SDL2_IMAGE_VERSION_MAJOR}.${SDL2_IMAGE_VERSION_MINOR}.${SDL2_IMAGE_VERSION_PATCH})
|
||||
unset(SDL2_IMAGE_VERSION_MAJOR_LINE)
|
||||
unset(SDL2_IMAGE_VERSION_MINOR_LINE)
|
||||
unset(SDL2_IMAGE_VERSION_PATCH_LINE)
|
||||
unset(SDL2_IMAGE_VERSION_MAJOR)
|
||||
unset(SDL2_IMAGE_VERSION_MINOR)
|
||||
unset(SDL2_IMAGE_VERSION_PATCH)
|
||||
endif()
|
||||
INCLUDE(FindPackageHandleStandardArgs)
|
||||
|
||||
set(SDL2_IMAGE_LIBRARIES ${SDL2_IMAGE_LIBRARY})
|
||||
set(SDL2_IMAGE_INCLUDE_DIRS ${SDL2_IMAGE_INCLUDE_DIR})
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(SDL2_IMAGE REQUIRED_VARS SDL2_IMAGE_LIBRARY SDL2_IMAGE_INCLUDE_DIR)
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(SDL2_image
|
||||
REQUIRED_VARS SDL2_IMAGE_LIBRARIES SDL2_IMAGE_INCLUDE_DIRS
|
||||
VERSION_VAR SDL2_IMAGE_VERSION_STRING)
|
||||
|
||||
|
||||
mark_as_advanced(SDL2_IMAGE_PATH
|
||||
SDL2_IMAGE_NO_DEFAULT_PATH
|
||||
SDL2_IMAGE_LIBRARY
|
||||
SDL2_IMAGE_INCLUDE_DIR)
|
||||
|
||||
|
||||
if(SDL2_IMAGE_FOUND)
|
||||
|
||||
# SDL2::Image target
|
||||
if(SDL2_IMAGE_LIBRARY AND NOT TARGET SDL2::Image)
|
||||
add_library(SDL2::Image UNKNOWN IMPORTED)
|
||||
set_target_properties(SDL2::Image PROPERTIES
|
||||
IMPORTED_LOCATION "${SDL2_IMAGE_LIBRARY}"
|
||||
INTERFACE_INCLUDE_DIRECTORIES "${SDL2_IMAGE_INCLUDE_DIR}"
|
||||
INTERFACE_LINK_LIBRARIES SDL2::Core)
|
||||
endif()
|
||||
endif()
|
||||
|
|
|
@ -1,222 +1,157 @@
|
|||
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
||||
# file Copyright.txt or https://cmake.org/licensing for details.
|
||||
# Locate SDL2_ttf library
|
||||
# This module defines
|
||||
# SDL2_TTF_LIBRARY, the name of the library to link against
|
||||
# SDL2_TTF_FOUND, if false, do not try to link to SDL2_ttf
|
||||
# SDL2_TTF_INCLUDE_DIR, where to find SDL_image.h
|
||||
#
|
||||
# Additional Note: If you see an empty SDL2_TTF_LIBRARY_TEMP in your configuration
|
||||
# and no SDL2_TTF_LIBRARY, it means CMake did not find your SDL2_Image library
|
||||
# (SDL2_ttf.dll, libsdl2_image.so, SDL2_ttf.framework, etc).
|
||||
# Set SDL2_TTF_LIBRARY_TEMP to point to your SDL2 library, and configure again.
|
||||
# Similarly, if you see an empty SDL2MAIN_LIBRARY, you should set this value
|
||||
# as appropriate. These values are used to generate the final SDL2_TTF_LIBRARY
|
||||
# variable, but when these values are unset, SDL2_TTF_LIBRARY does not get created.
|
||||
#
|
||||
# $SDL2 is an environment variable that would
|
||||
# correspond to the ./configure --prefix=$SDL2
|
||||
# used in building SDL2.
|
||||
# l.e.galup 9-20-02
|
||||
#
|
||||
# Modified by Eric Wing.
|
||||
# Added code to assist with automated building by using environmental variables
|
||||
# and providing a more controlled/consistent search behavior.
|
||||
# Added new modifications to recognize OS X frameworks and
|
||||
# additional Unix paths (FreeBSD, etc).
|
||||
# Also corrected the header search path to follow "proper" SDL2 guidelines.
|
||||
# Added a search for SDL2main which is needed by some platforms.
|
||||
# Added a search for threads which is needed by some platforms.
|
||||
# Added needed compile switches for MinGW.
|
||||
#
|
||||
# On OSX, this will prefer the Framework version (if found) over others.
|
||||
# People will have to manually change the cache values of
|
||||
# SDL2_TTF_LIBRARY to override this selection or set the CMake environment
|
||||
# CMAKE_INCLUDE_PATH to modify the search paths.
|
||||
#
|
||||
# Note that the header path has changed from SDL2/SDL.h to just SDL.h
|
||||
# This needed to change because "proper" SDL2 convention
|
||||
# is #include "SDL.h", not <SDL2/SDL.h>. This is done for portability
|
||||
# reasons because not all systems place things in SDL2/ (see FreeBSD).
|
||||
#
|
||||
# Ported by Johnny Patterson. This is a literal port for SDL2 of the FindSDL.cmake
|
||||
# module with the minor edit of changing "SDL" to "SDL2" where necessary. This
|
||||
# was not created for redistribution, and exists temporarily pending official
|
||||
# SDL2 CMake modules.
|
||||
#
|
||||
# Note that on windows this will only search for the 32bit libraries, to search
|
||||
# for 64bit change x86/i686-w64 to x64/x86_64-w64
|
||||
|
||||
# Copyright 2019 Amine Ben Hassouna <amine.benhassouna@gmail.com>
|
||||
# Copyright 2000-2019 Kitware, Inc. and Contributors
|
||||
# All rights reserved.
|
||||
#=============================================================================
|
||||
# Copyright 2003-2009 Kitware, Inc.
|
||||
#
|
||||
# CMake - Cross Platform Makefile Generator
|
||||
# Copyright 2000-2014 Kitware, Inc.
|
||||
# Copyright 2000-2011 Insight Software Consortium
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions
|
||||
# are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
#
|
||||
# * Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in the
|
||||
# documentation and/or other materials provided with the distribution.
|
||||
#
|
||||
# * Neither the names of Kitware, Inc., the Insight Software Consortium,
|
||||
# nor the names of their contributors may be used to endorse or promote
|
||||
# products derived from this software without specific prior written
|
||||
# permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
# This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
# See the License for more information.
|
||||
#=============================================================================
|
||||
# (To distribute this file outside of CMake, substitute the full
|
||||
# License text for the above reference.)
|
||||
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions
|
||||
# are met:
|
||||
|
||||
# * Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
|
||||
# * Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in the
|
||||
# documentation and/or other materials provided with the distribution.
|
||||
|
||||
# * Neither the name of Kitware, Inc. nor the names of Contributors
|
||||
# may be used to endorse or promote products derived from this
|
||||
# software without specific prior written permission.
|
||||
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#[=======================================================================[.rst:
|
||||
FindSDL2_ttf
|
||||
------------
|
||||
|
||||
Locate SDL2_ttf library
|
||||
|
||||
This module defines the following 'IMPORTED' target:
|
||||
|
||||
::
|
||||
|
||||
SDL2::TTF
|
||||
The SDL2_ttf library, if found.
|
||||
Have SDL2::Core as a link dependency.
|
||||
|
||||
|
||||
|
||||
This module will set the following variables in your project:
|
||||
|
||||
::
|
||||
|
||||
SDL2_TTF_LIBRARIES, the name of the library to link against
|
||||
SDL2_TTF_INCLUDE_DIRS, where to find the headers
|
||||
SDL2_TTF_FOUND, if false, do not try to link against
|
||||
SDL2_TTF_VERSION_STRING - human-readable string containing the
|
||||
version of SDL2_ttf
|
||||
|
||||
|
||||
|
||||
This module responds to the following cache variables:
|
||||
|
||||
::
|
||||
|
||||
SDL2_TTF_PATH
|
||||
Set a custom SDL2_ttf Library path (default: empty)
|
||||
|
||||
SDL2_TTF_NO_DEFAULT_PATH
|
||||
Disable search SDL2_ttf Library in default path.
|
||||
If SDL2_TTF_PATH (default: ON)
|
||||
Else (default: OFF)
|
||||
|
||||
SDL2_TTF_INCLUDE_DIR
|
||||
SDL2_ttf headers path.
|
||||
|
||||
SDL2_TTF_LIBRARY
|
||||
SDL2_ttf Library (.dll, .so, .a, etc) path.
|
||||
|
||||
|
||||
Additional Note: If you see an empty SDL2_TTF_LIBRARY in your project
|
||||
configuration, it means CMake did not find your SDL2_ttf library
|
||||
(SDL2_ttf.dll, libsdl2_ttf.so, etc). Set SDL2_TTF_LIBRARY to point
|
||||
to your SDL2_ttf library, and configure again. This value is used to
|
||||
generate the final SDL2_TTF_LIBRARIES variable and the SDL2::TTF target,
|
||||
but when this value is unset, SDL2_TTF_LIBRARIES and SDL2::TTF does not
|
||||
get created.
|
||||
|
||||
|
||||
$SDL2TTFDIR is an environment variable that would correspond to the
|
||||
./configure --prefix=$SDL2TTFDIR used in building SDL2_ttf.
|
||||
|
||||
$SDL2DIR is an environment variable that would correspond to the
|
||||
./configure --prefix=$SDL2DIR used in building SDL2.
|
||||
|
||||
|
||||
|
||||
Created by Amine Ben Hassouna:
|
||||
Adapt FindSDL_ttf.cmake to SDL2_ttf (FindSDL2_ttf.cmake).
|
||||
Add cache variables for more flexibility:
|
||||
SDL2_TTF_PATH, SDL2_TTF_NO_DEFAULT_PATH (for details, see doc above).
|
||||
Add SDL2 as a required dependency.
|
||||
Modernize the FindSDL2_ttf.cmake module by creating a specific target:
|
||||
SDL2::TTF (for details, see doc above).
|
||||
|
||||
Original FindSDL_ttf.cmake module:
|
||||
Created by Eric Wing. This was influenced by the FindSDL.cmake
|
||||
module, but with modifications to recognize OS X frameworks and
|
||||
additional Unix paths (FreeBSD, etc).
|
||||
#]=======================================================================]
|
||||
|
||||
# SDL2 Library required
|
||||
find_package(SDL2 QUIET)
|
||||
if(NOT SDL2_FOUND)
|
||||
set(SDL2_TTF_SDL2_NOT_FOUND "Could NOT find SDL2 (SDL2 is required by SDL2_ttf).")
|
||||
if(SDL2_ttf_FIND_REQUIRED)
|
||||
message(FATAL_ERROR ${SDL2_TTF_SDL2_NOT_FOUND})
|
||||
else()
|
||||
if(NOT SDL2_ttf_FIND_QUIETLY)
|
||||
message(STATUS ${SDL2_TTF_SDL2_NOT_FOUND})
|
||||
endif()
|
||||
return()
|
||||
endif()
|
||||
unset(SDL2_TTF_SDL2_NOT_FOUND)
|
||||
endif()
|
||||
|
||||
|
||||
# Define options for searching SDL2_ttf Library in a custom path
|
||||
|
||||
set(SDL2_TTF_PATH "" CACHE STRING "Custom SDL2_ttf Library path")
|
||||
|
||||
set(_SDL2_TTF_NO_DEFAULT_PATH OFF)
|
||||
if(SDL2_TTF_PATH)
|
||||
set(_SDL2_TTF_NO_DEFAULT_PATH ON)
|
||||
endif()
|
||||
|
||||
set(SDL2_TTF_NO_DEFAULT_PATH ${_SDL2_TTF_NO_DEFAULT_PATH}
|
||||
CACHE BOOL "Disable search SDL2_ttf Library in default path")
|
||||
unset(_SDL2_TTF_NO_DEFAULT_PATH)
|
||||
|
||||
set(SDL2_TTF_NO_DEFAULT_PATH_CMD)
|
||||
if(SDL2_TTF_NO_DEFAULT_PATH)
|
||||
set(SDL2_TTF_NO_DEFAULT_PATH_CMD NO_DEFAULT_PATH)
|
||||
endif()
|
||||
|
||||
# Search for the SDL2_ttf include directory
|
||||
find_path(SDL2_TTF_INCLUDE_DIR SDL_ttf.h
|
||||
HINTS
|
||||
ENV SDL2TTFDIR
|
||||
ENV SDL2DIR
|
||||
${SDL2_TTF_NO_DEFAULT_PATH_CMD}
|
||||
PATH_SUFFIXES SDL2
|
||||
# path suffixes to search inside ENV{SDL2DIR}
|
||||
# and ENV{SDL2TTFDIR}
|
||||
include/SDL2 include
|
||||
PATHS ${SDL2_TTF_PATH}
|
||||
DOC "Where the SDL2_ttf headers can be found"
|
||||
FIND_PATH(SDL2_TTF_INCLUDE_DIR SDL_ttf.h
|
||||
HINTS
|
||||
${SDL2}
|
||||
$ENV{SDL2}
|
||||
$ENV{SDL2_TTF}
|
||||
PATH_SUFFIXES include/SDL2 include SDL2
|
||||
i686-w64-mingw32/include/SDL2
|
||||
PATHS
|
||||
~/Library/Frameworks
|
||||
/Library/Frameworks
|
||||
/usr/local/include/SDL2
|
||||
/usr/include/SDL2
|
||||
/sw # Fink
|
||||
/opt/local # DarwinPorts
|
||||
/opt/csw # Blastwave
|
||||
/opt
|
||||
)
|
||||
|
||||
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||
set(VC_LIB_PATH_SUFFIX lib/x64)
|
||||
else()
|
||||
set(VC_LIB_PATH_SUFFIX lib/x86)
|
||||
endif()
|
||||
# Lookup the 64 bit libs on x64
|
||||
IF(CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||
FIND_LIBRARY(SDL2_TTF_LIBRARY_TEMP
|
||||
NAMES SDL2_ttf
|
||||
HINTS
|
||||
${SDL2}
|
||||
$ENV{SDL2}
|
||||
$ENV{SDL2_TTF}
|
||||
PATH_SUFFIXES lib64 lib
|
||||
lib/x64
|
||||
x86_64-w64-mingw32/lib
|
||||
PATHS
|
||||
/sw
|
||||
/opt/local
|
||||
/opt/csw
|
||||
/opt
|
||||
)
|
||||
# On 32bit build find the 32bit libs
|
||||
ELSE(CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||
FIND_LIBRARY(SDL2_TTF_LIBRARY_TEMP
|
||||
NAMES SDL2_ttf
|
||||
HINTS
|
||||
${SDL2}
|
||||
$ENV{SDL2}
|
||||
$ENV{SDL2_TTF}
|
||||
PATH_SUFFIXES lib
|
||||
lib/x86
|
||||
i686-w64-mingw32/lib
|
||||
PATHS
|
||||
/sw
|
||||
/opt/local
|
||||
/opt/csw
|
||||
/opt
|
||||
)
|
||||
ENDIF(CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||
|
||||
# Search for the SDL2_ttf library
|
||||
find_library(SDL2_TTF_LIBRARY
|
||||
NAMES SDL2_ttf
|
||||
HINTS
|
||||
ENV SDL2TTFDIR
|
||||
ENV SDL2DIR
|
||||
${SDL2_TTF_NO_DEFAULT_PATH_CMD}
|
||||
PATH_SUFFIXES lib ${VC_LIB_PATH_SUFFIX}
|
||||
PATHS ${SDL2_TTF_PATH}
|
||||
DOC "Where the SDL2_ttf Library can be found"
|
||||
)
|
||||
SET(SDL2_TTF_FOUND "NO")
|
||||
IF(SDL2_TTF_LIBRARY_TEMP)
|
||||
# Set the final string here so the GUI reflects the final state.
|
||||
SET(SDL2_TTF_LIBRARY ${SDL2_TTF_LIBRARY_TEMP} CACHE STRING "Where the SDL2_ttf Library can be found")
|
||||
# Set the temp variable to INTERNAL so it is not seen in the CMake GUI
|
||||
SET(SDL2_TTF_LIBRARY_TEMP "${SDL2_TTF_LIBRARY_TEMP}" CACHE INTERNAL "")
|
||||
SET(SDL2_TTF_FOUND "YES")
|
||||
ENDIF(SDL2_TTF_LIBRARY_TEMP)
|
||||
|
||||
# Read SDL2_ttf version
|
||||
if(SDL2_TTF_INCLUDE_DIR AND EXISTS "${SDL2_TTF_INCLUDE_DIR}/SDL_ttf.h")
|
||||
file(STRINGS "${SDL2_TTF_INCLUDE_DIR}/SDL_ttf.h" SDL2_TTF_VERSION_MAJOR_LINE REGEX "^#define[ \t]+SDL_TTF_MAJOR_VERSION[ \t]+[0-9]+$")
|
||||
file(STRINGS "${SDL2_TTF_INCLUDE_DIR}/SDL_ttf.h" SDL2_TTF_VERSION_MINOR_LINE REGEX "^#define[ \t]+SDL_TTF_MINOR_VERSION[ \t]+[0-9]+$")
|
||||
file(STRINGS "${SDL2_TTF_INCLUDE_DIR}/SDL_ttf.h" SDL2_TTF_VERSION_PATCH_LINE REGEX "^#define[ \t]+SDL_TTF_PATCHLEVEL[ \t]+[0-9]+$")
|
||||
string(REGEX REPLACE "^#define[ \t]+SDL_TTF_MAJOR_VERSION[ \t]+([0-9]+)$" "\\1" SDL2_TTF_VERSION_MAJOR "${SDL2_TTF_VERSION_MAJOR_LINE}")
|
||||
string(REGEX REPLACE "^#define[ \t]+SDL_TTF_MINOR_VERSION[ \t]+([0-9]+)$" "\\1" SDL2_TTF_VERSION_MINOR "${SDL2_TTF_VERSION_MINOR_LINE}")
|
||||
string(REGEX REPLACE "^#define[ \t]+SDL_TTF_PATCHLEVEL[ \t]+([0-9]+)$" "\\1" SDL2_TTF_VERSION_PATCH "${SDL2_TTF_VERSION_PATCH_LINE}")
|
||||
set(SDL2_TTF_VERSION_STRING ${SDL2_TTF_VERSION_MAJOR}.${SDL2_TTF_VERSION_MINOR}.${SDL2_TTF_VERSION_PATCH})
|
||||
unset(SDL2_TTF_VERSION_MAJOR_LINE)
|
||||
unset(SDL2_TTF_VERSION_MINOR_LINE)
|
||||
unset(SDL2_TTF_VERSION_PATCH_LINE)
|
||||
unset(SDL2_TTF_VERSION_MAJOR)
|
||||
unset(SDL2_TTF_VERSION_MINOR)
|
||||
unset(SDL2_TTF_VERSION_PATCH)
|
||||
endif()
|
||||
INCLUDE(FindPackageHandleStandardArgs)
|
||||
|
||||
set(SDL2_TTF_LIBRARIES ${SDL2_TTF_LIBRARY})
|
||||
set(SDL2_TTF_INCLUDE_DIRS ${SDL2_TTF_INCLUDE_DIR})
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(SDL2_TTF REQUIRED_VARS SDL2_TTF_LIBRARY SDL2_TTF_INCLUDE_DIR)
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(SDL2_ttf
|
||||
REQUIRED_VARS SDL2_TTF_LIBRARIES SDL2_TTF_INCLUDE_DIRS
|
||||
VERSION_VAR SDL2_TTF_VERSION_STRING)
|
||||
|
||||
|
||||
mark_as_advanced(SDL2_TTF_PATH
|
||||
SDL2_TTF_NO_DEFAULT_PATH
|
||||
SDL2_TTF_LIBRARY
|
||||
SDL2_TTF_INCLUDE_DIR)
|
||||
|
||||
|
||||
if(SDL2_TTF_FOUND)
|
||||
|
||||
# SDL2::TTF target
|
||||
if(SDL2_TTF_LIBRARY AND NOT TARGET SDL2::TTF)
|
||||
add_library(SDL2::TTF UNKNOWN IMPORTED)
|
||||
set_target_properties(SDL2::TTF PROPERTIES
|
||||
IMPORTED_LOCATION "${SDL2_TTF_LIBRARY}"
|
||||
INTERFACE_INCLUDE_DIRECTORIES "${SDL2_TTF_INCLUDE_DIR}"
|
||||
INTERFACE_LINK_LIBRARIES SDL2::Core)
|
||||
endif()
|
||||
endif()
|
||||
|
|
|
@ -1,31 +0,0 @@
|
|||
# Note: LibSndFile exports targets itself with SndFileConfig.cmake,
|
||||
# However, the file is not for some reason provided in packages in some Linux distros, e.g. Ubuntu 18.04
|
||||
# Hence this Find*.cmake file.
|
||||
|
||||
FIND_PATH(SndFile_INCLUDE_DIR sndfile.h)
|
||||
FIND_LIBRARY(SndFile_LIBRARY NAMES sndfile libsndfile sndfile-1)
|
||||
|
||||
find_package_handle_standard_args(
|
||||
SndFile
|
||||
DEFAULT_MSG
|
||||
SndFile_LIBRARY
|
||||
SndFile_INCLUDE_DIR
|
||||
)
|
||||
|
||||
# Export targets
|
||||
if(SndFile_FOUND AND NOT TARGET SndFile::sndfile)
|
||||
add_library(SndFile::sndfile UNKNOWN IMPORTED)
|
||||
set_target_properties(SndFile::sndfile PROPERTIES
|
||||
IMPORTED_LOCATION "${SndFile_LIBRARY}"
|
||||
INTERFACE_INCLUDE_DIRECTORIES "${SndFile_INCLUDE_DIR}")
|
||||
# If we want to statically link it, we also need its dependencies
|
||||
if(SNDFILE_STATIC)
|
||||
find_package(Ogg REQUIRED)
|
||||
find_package(Opus REQUIRED)
|
||||
find_package(FLAC REQUIRED)
|
||||
find_package(Vorbis REQUIRED)
|
||||
find_package(VorbisEnc REQUIRED)
|
||||
set_property(TARGET SndFile::sndfile APPEND PROPERTY
|
||||
INTERFACE_LINK_LIBRARIES Ogg::ogg Opus::opus FLAC::FLAC Vorbis::vorbis Vorbis::VorbisEnc)
|
||||
endif()
|
||||
endif()
|
|
@ -1,161 +0,0 @@
|
|||
# - Find vorbisenc
|
||||
# Find the native vorbisenc includes and libraries
|
||||
#
|
||||
# VORBIS_INCLUDE_DIRS - where to find vorbis.h, etc.
|
||||
# VORBIS_LIBRARIES - List of libraries when using vorbis.
|
||||
# VORBIS_FOUND - True if vorbis found.
|
||||
|
||||
# From https://github.com/erikd/libsndfile/
|
||||
|
||||
if (Vorbis_Vorbis_INCLUDE_DIR)
|
||||
# Already in cache, be silent
|
||||
set (Vorbis_FIND_QUIETLY TRUE)
|
||||
endif ()
|
||||
|
||||
set (Vorbis_Vorbis_FIND_QUIETLY TRUE)
|
||||
set (Vorbis_Enc_FIND_QUIETLY TRUE)
|
||||
set (Vorbis_File_FIND_QUIETLY TRUE)
|
||||
|
||||
find_package (Ogg QUIET)
|
||||
|
||||
find_package (PkgConfig QUIET)
|
||||
pkg_check_modules (PC_Vorbis_Vorbis QUIET vorbis)
|
||||
pkg_check_modules (PC_Vorbis_Enc QUIET vorbisenc)
|
||||
pkg_check_modules (PC_Vorbis_File QUIET vorbisfile)
|
||||
|
||||
set (Vorbis_VERSION ${PC_VORBIS_VERSION})
|
||||
|
||||
find_path (Vorbis_Vorbis_INCLUDE_DIR vorbis/codec.h
|
||||
HINTS
|
||||
${PC_Vorbis_Vorbis_INCLUDEDIR}
|
||||
${PC_Vorbis_Vorbis_INCLUDE_DIRS}
|
||||
${Vorbis_ROOT}
|
||||
)
|
||||
|
||||
find_path (Vorbis_Enc_INCLUDE_DIR vorbis/vorbisenc.h
|
||||
HINTS
|
||||
${PC_Vorbis_Enc_INCLUDEDIR}
|
||||
${PC_Vorbis_Enc_INCLUDE_DIRS}
|
||||
${Vorbis_ROOT}
|
||||
)
|
||||
|
||||
find_path (Vorbis_File_INCLUDE_DIR vorbis/vorbisfile.h
|
||||
HINTS
|
||||
${PC_Vorbis_File_INCLUDEDIR}
|
||||
${PC_Vorbis_File_INCLUDE_DIRS}
|
||||
${Vorbis_ROOT}
|
||||
)
|
||||
|
||||
find_library (Vorbis_Vorbis_LIBRARY
|
||||
NAMES
|
||||
vorbis
|
||||
vorbis_static
|
||||
libvorbis
|
||||
libvorbis_static
|
||||
HINTS
|
||||
${PC_Vorbis_Vorbis_LIBDIR}
|
||||
${PC_Vorbis_Vorbis_LIBRARY_DIRS}
|
||||
${Vorbis_ROOT}
|
||||
)
|
||||
|
||||
find_library (Vorbis_Enc_LIBRARY
|
||||
NAMES
|
||||
vorbisenc
|
||||
vorbisenc_static
|
||||
libvorbisenc
|
||||
libvorbisenc_static
|
||||
HINTS
|
||||
${PC_Vorbis_Enc_LIBDIR}
|
||||
${PC_Vorbis_Enc_LIBRARY_DIRS}
|
||||
${Vorbis_ROOT}
|
||||
)
|
||||
|
||||
find_library (Vorbis_File_LIBRARY
|
||||
NAMES
|
||||
vorbisfile
|
||||
vorbisfile_static
|
||||
libvorbisfile
|
||||
libvorbisfile_static
|
||||
HINTS
|
||||
${PC_Vorbis_File_LIBDIR}
|
||||
${PC_Vorbis_File_LIBRARY_DIRS}
|
||||
${Vorbis_ROOT}
|
||||
)
|
||||
|
||||
include (FindPackageHandleStandardArgs)
|
||||
|
||||
find_package_handle_standard_args (Vorbis_Vorbis
|
||||
REQUIRED_VARS
|
||||
Vorbis_Vorbis_LIBRARY
|
||||
Vorbis_Vorbis_INCLUDE_DIR
|
||||
Ogg_FOUND
|
||||
NAME_MISMATCHED
|
||||
)
|
||||
|
||||
find_package_handle_standard_args (Vorbis_Enc
|
||||
REQUIRED_VARS
|
||||
Vorbis_Enc_LIBRARY
|
||||
Vorbis_Enc_INCLUDE_DIR
|
||||
Vorbis_Vorbis_FOUND
|
||||
NAME_MISMATCHED
|
||||
)
|
||||
|
||||
find_package_handle_standard_args (Vorbis_File
|
||||
REQUIRED_VARS
|
||||
Vorbis_File_LIBRARY
|
||||
Vorbis_File_INCLUDE_DIR
|
||||
Vorbis_Vorbis_FOUND
|
||||
NAME_MISMATCHED
|
||||
)
|
||||
|
||||
if (Vorbis_Vorbis_FOUND)
|
||||
set (Vorbis_Vorbis_INCLUDE_DIRS ${VORBIS_INCLUDE_DIR})
|
||||
set (Vorbis_Vorbis_LIBRARIES ${VORBIS_LIBRARY} ${OGG_LIBRARIES})
|
||||
if (NOT TARGET Vorbis::vorbis)
|
||||
add_library (Vorbis::vorbis UNKNOWN IMPORTED)
|
||||
set_target_properties (Vorbis::vorbis PROPERTIES
|
||||
INTERFACE_INCLUDE_DIRECTORIES "${Vorbis_Vorbis_INCLUDE_DIR}"
|
||||
IMPORTED_LOCATION "${Vorbis_Vorbis_LIBRARY}"
|
||||
INTERFACE_LINK_LIBRARIES Ogg::ogg
|
||||
)
|
||||
endif ()
|
||||
|
||||
if (Vorbis_Enc_FOUND)
|
||||
set (Vorbis_Enc_INCLUDE_DIRS ${Vorbis_Enc_INCLUDE_DIR})
|
||||
set (Vorbis_Enc_LIBRARIES ${Vorbis_Enc_LIBRARY} ${Vorbis_Enc_LIBRARIES})
|
||||
if (NOT TARGET Vorbis::vorbisenc)
|
||||
add_library (Vorbis::vorbisenc UNKNOWN IMPORTED)
|
||||
set_target_properties (Vorbis::vorbisenc PROPERTIES
|
||||
INTERFACE_INCLUDE_DIRECTORIES "${Vorbis_Enc_INCLUDE_DIR}"
|
||||
IMPORTED_LOCATION "${Vorbis_Enc_LIBRARY}"
|
||||
INTERFACE_LINK_LIBRARIES Vorbis::vorbis
|
||||
)
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
if (Vorbis_File_FOUND)
|
||||
set (Vorbis_File_INCLUDE_DIRS ${Vorbis_File_INCLUDE_DIR})
|
||||
set (Vorbis_File_LIBRARIES ${Vorbis_File_LIBRARY} ${Vorbis_File_LIBRARIES})
|
||||
if (NOT TARGET Vorbis::vorbisfile)
|
||||
add_library (Vorbis::vorbisfile UNKNOWN IMPORTED)
|
||||
set_target_properties (Vorbis::vorbisfile PROPERTIES
|
||||
INTERFACE_INCLUDE_DIRECTORIES "${Vorbis_File_INCLUDE_DIR}"
|
||||
IMPORTED_LOCATION "${Vorbis_File_LIBRARY}"
|
||||
INTERFACE_LINK_LIBRARIES Vorbis::vorbis
|
||||
)
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
endif ()
|
||||
|
||||
find_package_handle_standard_args (Vorbis
|
||||
REQUIRED_VARS
|
||||
Vorbis_Vorbis_LIBRARY
|
||||
Vorbis_Vorbis_INCLUDE_DIR
|
||||
Ogg_FOUND
|
||||
HANDLE_COMPONENTS
|
||||
VERSION_VAR Vorbis_VERSION)
|
||||
|
||||
mark_as_advanced (Vorbis_Vorbis_INCLUDE_DIR Vorbis_Vorbis_LIBRARY)
|
||||
mark_as_advanced (Vorbis_Enc_INCLUDE_DIR Vorbis_Enc_LIBRARY)
|
||||
mark_as_advanced (Vorbis_File_INCLUDE_DIR Vorbis_File_LIBRARY)
|
|
@ -1,66 +0,0 @@
|
|||
# - Find vorbisenc
|
||||
# Find the native vorbisenc includes and libraries
|
||||
#
|
||||
# VORBISENC_INCLUDE_DIRS - where to find vorbisenc.h, etc.
|
||||
# VORBISENC_LIBRARIES - List of libraries when using vorbisenc.
|
||||
# VORBISENC_FOUND - True if vorbisenc found.
|
||||
|
||||
# From https://github.com/erikd/libsndfile/
|
||||
|
||||
if (VORBISENC_INCLUDE_DIR)
|
||||
# Already in cache, be silent
|
||||
set (VORBISENC_FIND_QUIETLY TRUE)
|
||||
endif ()
|
||||
|
||||
find_package (Vorbis QUIET)
|
||||
|
||||
find_package (PkgConfig QUIET)
|
||||
pkg_check_modules (PC_VORBISENC QUIET vorbisenc)
|
||||
|
||||
set (VORBISENC_VERSION ${PC_VORBISENC_VERSION})
|
||||
|
||||
find_path (VORBISENC_INCLUDE_DIR vorbis/vorbisenc.h
|
||||
HINTS
|
||||
${PC_VORBISENC_INCLUDEDIR}
|
||||
${PC_VORBISENC_INCLUDE_DIRS}
|
||||
${VORBISENC_ROOT}
|
||||
)
|
||||
|
||||
find_library (VORBISENC_LIBRARY
|
||||
NAMES
|
||||
vorbisenc
|
||||
vorbisenc_static
|
||||
libvorbisenc
|
||||
libvorbisenc_static
|
||||
HINTS
|
||||
${PC_VORBISENC_LIBDIR}
|
||||
${PC_VORBISENC_LIBRARY_DIRS}
|
||||
${VORBISENC_ROOT}
|
||||
)
|
||||
|
||||
# Handle the QUIETLY and REQUIRED arguments and set VORBISENC_FOUND
|
||||
# to TRUE if all listed variables are TRUE.
|
||||
include (FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args (VorbisEnc
|
||||
REQUIRED_VARS
|
||||
VORBISENC_LIBRARY
|
||||
VORBISENC_INCLUDE_DIR
|
||||
VORBIS_FOUND
|
||||
VERSION_VAR
|
||||
VORBISENC_VERSION
|
||||
)
|
||||
|
||||
if (VORBISENC_FOUND)
|
||||
set (VORBISENC_INCLUDE_DIRS ${VORBISENC_INCLUDE_DIR})
|
||||
set (VORBISENC_LIBRARIES ${VORBISENC_LIBRARY} ${VORBIS_LIBRARIES})
|
||||
if (NOT TARGET Vorbis::VorbisEnc)
|
||||
add_library (Vorbis::VorbisEnc UNKNOWN IMPORTED)
|
||||
set_target_properties (Vorbis::VorbisEnc PROPERTIES
|
||||
INTERFACE_INCLUDE_DIRECTORIES "${VORBISENC_INCLUDE_DIR}"
|
||||
IMPORTED_LOCATION "${VORBISENC_LIBRARY}"
|
||||
INTERFACE_LINK_LIBRARIES Vorbis::vorbis
|
||||
)
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
mark_as_advanced (VORBISENC_INCLUDE_DIR VORBISENC_LIBRARY)
|
|
@ -4,20 +4,17 @@
|
|||
# This adds a new target with generated fake source files that include single header files
|
||||
# It is a workaround for how CMake and Clang handle header files in compilation database
|
||||
# And we need that to check each header file in the project exactly once, the same as .cpp modules
|
||||
# Note: This is modifying an existing target by adding fake source files.
|
||||
##
|
||||
macro(add_fake_header_sources subdir the_target)
|
||||
macro(add_fake_header_sources subdir)
|
||||
set(all_fake_header_src_files "")
|
||||
|
||||
set(fake_headers_src_dir ${colobot_BINARY_DIR}/fake_header_sources)
|
||||
file(MAKE_DIRECTORY ${fake_headers_src_dir})
|
||||
|
||||
get_target_property(the_target_sources ${the_target} SOURCES)
|
||||
file(GLOB_RECURSE all_header_files RELATIVE ${colobot_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/*.h)
|
||||
|
||||
foreach(source_file IN LISTS the_target_sources)
|
||||
string(REGEX MATCH [[^.*\.h$]] is_header_file ${source_file})
|
||||
if(is_header_file)
|
||||
file(RELATIVE_PATH header_file ${colobot_SOURCE_DIR} ${colobot_SOURCE_DIR}/${subdir}/${source_file})
|
||||
if(all_header_files)
|
||||
foreach(header_file ${all_header_files})
|
||||
string(REGEX REPLACE "\\.h$" ".cpp" fake_header_src_file "${fake_headers_src_dir}/${header_file}")
|
||||
|
||||
get_filename_component(fake_header_src_dir ${fake_header_src_file} PATH)
|
||||
|
@ -25,8 +22,10 @@ macro(add_fake_header_sources subdir the_target)
|
|||
|
||||
file(WRITE ${fake_header_src_file} "#include \"${header_file}\"\n\n")
|
||||
|
||||
target_sources(${the_target} PRIVATE ${fake_header_src_file})
|
||||
target_include_directories(${the_target} PUBLIC ${colobot_SOURCE_DIR})
|
||||
endif()
|
||||
endforeach()
|
||||
list(APPEND all_fake_header_src_files ${fake_header_src_file})
|
||||
endforeach()
|
||||
|
||||
include_directories(${colobot_SOURCE_DIR})
|
||||
add_library(colobot_${subdir}_fake_header_srcs STATIC ${all_fake_header_src_files})
|
||||
endif()
|
||||
endmacro()
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# Hacks for MSYS
|
||||
if (MSYS)
|
||||
if (MSYS AND (NOT MXE))
|
||||
message(STATUS "Detected MSYS build")
|
||||
|
||||
set(PLATFORM_WINDOWS 1)
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
# When cross-compiling with MXE, we need to straighten some things
|
||||
|
||||
# Checking is a bit primitive, but this should detect MXE toolchain file
|
||||
if((${CMAKE_CROSSCOMPILING}) AND (DEFINED MSYS))
|
||||
message(STATUS "Detected MXE build")
|
||||
set(MXE 1)
|
||||
set(PLATFORM_WINDOWS 1)
|
||||
set(PLATFORM_LINUX 0)
|
||||
set(PLATFORM_OTHER 0)
|
||||
# All must be static, CBOT and GLEW too
|
||||
set(CBOT_STATIC ON)
|
||||
set(GLEW_STATIC ON)
|
||||
|
||||
if (${OPENAL_SOUND})
|
||||
set(OPENAL_MXE_LIBS
|
||||
${CMAKE_FIND_ROOT_PATH}/lib/libFLAC.a
|
||||
${CMAKE_FIND_ROOT_PATH}/lib/libvorbis.a
|
||||
${CMAKE_FIND_ROOT_PATH}/lib/libvorbisenc.a
|
||||
${CMAKE_FIND_ROOT_PATH}/lib/libvorbisfile.a
|
||||
${CMAKE_FIND_ROOT_PATH}/lib/libogg.a
|
||||
)
|
||||
endif()
|
||||
|
||||
set(MXE_CFLAGS "-DAL_LIBTYPE_STATIC")
|
||||
set(MXE_LIBS
|
||||
# For some reason, these have to be absolute paths
|
||||
${CMAKE_FIND_ROOT_PATH}/lib/libintl.a
|
||||
${CMAKE_FIND_ROOT_PATH}/lib/libiconv.a
|
||||
${CMAKE_FIND_ROOT_PATH}/lib/libglew32s.a
|
||||
${CMAKE_FIND_ROOT_PATH}/lib/libfreetype.a
|
||||
${CMAKE_FIND_ROOT_PATH}/lib/libopengl32.a
|
||||
${CMAKE_FIND_ROOT_PATH}/lib/libjpeg.a
|
||||
${CMAKE_FIND_ROOT_PATH}/lib/libwinmm.a
|
||||
${CMAKE_FIND_ROOT_PATH}/lib/libdxguid.a
|
||||
${CMAKE_FIND_ROOT_PATH}/lib/libbz2.a
|
||||
${CMAKE_FIND_ROOT_PATH}/lib/libimm32.a
|
||||
${CMAKE_FIND_ROOT_PATH}/lib/libole32.a
|
||||
${CMAKE_FIND_ROOT_PATH}/lib/liboleaut32.a
|
||||
${CMAKE_FIND_ROOT_PATH}/lib/libharfbuzz.a
|
||||
${CMAKE_FIND_ROOT_PATH}/lib/libwebp.a
|
||||
${CMAKE_FIND_ROOT_PATH}/lib/libversion.a
|
||||
${CMAKE_FIND_ROOT_PATH}/lib/libglib-2.0.a
|
||||
${CMAKE_FIND_ROOT_PATH}/lib/libwsock32.a
|
||||
${CMAKE_FIND_ROOT_PATH}/lib/libws2_32.a
|
||||
${CMAKE_FIND_ROOT_PATH}/lib/libintl.a
|
||||
${OPENAL_MXE_LIBS}
|
||||
)
|
||||
else()
|
||||
set(MXE 0)
|
||||
endif()
|
|
@ -1,41 +0,0 @@
|
|||
# Hide console on Windows (useful for release builds)
|
||||
option(COLOBOT_HIDE_CONSOLE "Hide console" OFF)
|
||||
|
||||
add_executable(colobot)
|
||||
|
||||
target_sources(colobot PRIVATE
|
||||
src/main.cpp
|
||||
)
|
||||
|
||||
if(MSVC)
|
||||
target_compile_options(colobot PRIVATE /utf-8)
|
||||
endif()
|
||||
|
||||
if(PLATFORM_WINDOWS)
|
||||
target_sources(colobot PRIVATE ${PROJECT_BINARY_DIR}/desktop/colobot.rc)
|
||||
endif()
|
||||
|
||||
target_link_libraries(colobot Colobot-Base SDL2::Main)
|
||||
|
||||
if(COLOBOT_HIDE_CONSOLE)
|
||||
set_target_properties(colobot PROPERTIES WIN32_EXECUTABLE TRUE)
|
||||
endif()
|
||||
|
||||
# Install
|
||||
install(TARGETS colobot RUNTIME DESTINATION ${COLOBOT_INSTALL_BIN_DIR})
|
||||
|
||||
if(MSVC)
|
||||
install(FILES $<TARGET_PDB_FILE:colobot>
|
||||
CONFIGURATIONS Debug RelWithDebInfo
|
||||
DESTINATION ${COLOBOT_INSTALL_BIN_DIR} OPTIONAL)
|
||||
endif()
|
||||
|
||||
if(NOT CBOT_STATIC)
|
||||
set_target_properties(colobot PROPERTIES
|
||||
INSTALL_RPATH ${COLOBOT_INSTALL_LIB_DIR})
|
||||
endif()
|
||||
|
||||
# Linter-specific
|
||||
if(COLOBOT_LINT_BUILD)
|
||||
add_fake_header_sources("src" colobot)
|
||||
endif()
|
|
@ -1,359 +0,0 @@
|
|||
/*
|
||||
* This file is part of the Colobot: Gold Edition source code
|
||||
* Copyright (C) 2001-2023, Daniel Roux, EPSITEC SA & TerranovaTeam
|
||||
* http://epsitec.ch; http://colobot.info; http://github.com/colobot
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see http://gnu.org/licenses
|
||||
*/
|
||||
|
||||
#include "app/modman.h"
|
||||
|
||||
#include "common/config.h"
|
||||
|
||||
#include "app/app.h"
|
||||
#include "app/pathman.h"
|
||||
|
||||
#include "common/config_file.h"
|
||||
#include "common/logger.h"
|
||||
#include "common/stringutils.h"
|
||||
|
||||
#include "common/resources/resourcemanager.h"
|
||||
|
||||
#include "level/parser/parser.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <filesystem>
|
||||
#include <map>
|
||||
|
||||
CModManager::CModManager(CApplication* app, CPathManager* pathManager)
|
||||
: m_app{app},
|
||||
m_pathManager{pathManager}
|
||||
{
|
||||
}
|
||||
|
||||
void CModManager::FindMods()
|
||||
{
|
||||
m_mods.clear();
|
||||
m_userChanges = false;
|
||||
|
||||
// Load names from the config file
|
||||
std::vector<std::string> savedModNames;
|
||||
GetConfigFile().GetArrayProperty("Mods", "Names", savedModNames);
|
||||
std::vector<bool> savedEnabled;
|
||||
GetConfigFile().GetArrayProperty("Mods", "Enabled", savedEnabled);
|
||||
|
||||
// Transform the data into Mod structures
|
||||
m_mods.reserve(savedModNames.size());
|
||||
for (size_t i = 0; i < savedModNames.size(); ++i)
|
||||
{
|
||||
Mod mod{};
|
||||
mod.name = savedModNames[i];
|
||||
if (i < savedEnabled.size())
|
||||
{
|
||||
mod.enabled = savedEnabled[i];
|
||||
}
|
||||
mod.path = ""; // Find the path later
|
||||
m_mods.push_back(mod);
|
||||
}
|
||||
|
||||
// Search the folders for mods
|
||||
auto rawPaths = m_pathManager->FindMods();
|
||||
std::map<std::string, std::string> modPaths;
|
||||
for (const auto& path : rawPaths)
|
||||
{
|
||||
auto modName = std::filesystem::path(path).stem().string();
|
||||
modPaths.insert(std::make_pair(modName, path));
|
||||
}
|
||||
|
||||
// Find paths for already saved mods
|
||||
auto it = m_mods.begin();
|
||||
while (it != m_mods.end())
|
||||
{
|
||||
auto& mod = *it;
|
||||
const auto pathsIt = modPaths.find(mod.name);
|
||||
if (pathsIt != modPaths.end())
|
||||
{
|
||||
mod.path = (*pathsIt).second;
|
||||
modPaths.erase(pathsIt);
|
||||
++it;
|
||||
}
|
||||
else
|
||||
{
|
||||
GetLogger()->Warn("Could not find mod %s, removing it from the list\n", mod.name.c_str());
|
||||
it = m_mods.erase(it);
|
||||
}
|
||||
}
|
||||
|
||||
// Add the remaining found mods to the end of the list
|
||||
for (const auto& newMod : modPaths)
|
||||
{
|
||||
Mod mod{};
|
||||
mod.name = newMod.first;
|
||||
mod.path = newMod.second;
|
||||
m_mods.push_back(mod);
|
||||
}
|
||||
|
||||
// Load the metadata for each mod
|
||||
|
||||
// Unfortunately, the paths are distinguished by their real paths, not mount points
|
||||
// So we must unmount mods temporarily
|
||||
for (const auto& path : m_mountedModPaths)
|
||||
{
|
||||
UnmountMod(path);
|
||||
}
|
||||
|
||||
for (auto& mod : m_mods)
|
||||
{
|
||||
MountMod(mod, "/temp/mod");
|
||||
LoadModData(mod);
|
||||
UnmountMod(mod);
|
||||
}
|
||||
|
||||
// Mount back
|
||||
for (const auto& path : m_mountedModPaths)
|
||||
{
|
||||
MountMod(path);
|
||||
}
|
||||
}
|
||||
|
||||
void CModManager::ReloadMods()
|
||||
{
|
||||
UnmountAllMountedMods();
|
||||
MountAllMods();
|
||||
ReloadResources();
|
||||
}
|
||||
|
||||
void CModManager::EnableMod(size_t i)
|
||||
{
|
||||
m_mods[i].enabled = true;
|
||||
m_userChanges = true;
|
||||
}
|
||||
|
||||
void CModManager::DisableMod(size_t i)
|
||||
{
|
||||
m_mods[i].enabled = false;
|
||||
m_userChanges = true;
|
||||
}
|
||||
|
||||
size_t CModManager::MoveUp(size_t i)
|
||||
{
|
||||
if (i != 0)
|
||||
{
|
||||
std::swap(m_mods[i - 1], m_mods[i]);
|
||||
m_userChanges = true;
|
||||
return i - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
size_t CModManager::MoveDown(size_t i)
|
||||
{
|
||||
if (i != m_mods.size() - 1)
|
||||
{
|
||||
std::swap(m_mods[i], m_mods[i + 1]);
|
||||
m_userChanges = true;
|
||||
return i + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
bool CModManager::Changes()
|
||||
{
|
||||
std::vector<std::string> paths;
|
||||
for (const auto& mod : m_mods)
|
||||
{
|
||||
if (mod.enabled)
|
||||
{
|
||||
paths.push_back(mod.path);
|
||||
}
|
||||
}
|
||||
return paths != m_mountedModPaths || m_userChanges;
|
||||
}
|
||||
|
||||
void CModManager::MountAllMods()
|
||||
{
|
||||
for (const auto& mod : m_mods)
|
||||
{
|
||||
if (mod.enabled)
|
||||
{
|
||||
MountMod(mod);
|
||||
m_mountedModPaths.push_back(mod.path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CModManager::ReloadResources()
|
||||
{
|
||||
m_app->ReloadResources();
|
||||
}
|
||||
|
||||
void CModManager::SaveMods()
|
||||
{
|
||||
std::vector<std::string> savedNames;
|
||||
savedNames.reserve(m_mods.size());
|
||||
std::transform(m_mods.begin(), m_mods.end(), std::back_inserter(savedNames), [](const Mod& mod) { return mod.name; });
|
||||
GetConfigFile().SetArrayProperty("Mods", "Names", savedNames);
|
||||
|
||||
std::vector<bool> savedEnabled;
|
||||
savedEnabled.reserve(m_mods.size());
|
||||
std::transform(m_mods.begin(), m_mods.end(), std::back_inserter(savedEnabled), [](const Mod& mod) { return mod.enabled; });
|
||||
GetConfigFile().SetArrayProperty("Mods", "Enabled", savedEnabled);
|
||||
|
||||
GetConfigFile().Save();
|
||||
|
||||
m_userChanges = false;
|
||||
}
|
||||
|
||||
size_t CModManager::CountMods() const
|
||||
{
|
||||
return m_mods.size();
|
||||
}
|
||||
|
||||
const Mod& CModManager::GetMod(size_t i) const
|
||||
{
|
||||
return m_mods[i];
|
||||
}
|
||||
|
||||
const std::vector<Mod>& CModManager::GetMods() const
|
||||
{
|
||||
return m_mods;
|
||||
}
|
||||
|
||||
void CModManager::LoadModData(Mod& mod)
|
||||
{
|
||||
auto& data = mod.data;
|
||||
|
||||
data.displayName = mod.name;
|
||||
|
||||
try
|
||||
{
|
||||
CLevelParser levelParser("temp/mod/manifest.txt");
|
||||
if (levelParser.Exists())
|
||||
{
|
||||
levelParser.Load();
|
||||
|
||||
CLevelParserLine* line = nullptr;
|
||||
|
||||
// DisplayName
|
||||
line = levelParser.GetIfDefined("DisplayName");
|
||||
if (line != nullptr && line->GetParam("text")->IsDefined())
|
||||
{
|
||||
data.displayName = line->GetParam("text")->AsString();
|
||||
}
|
||||
|
||||
// Author
|
||||
line = levelParser.GetIfDefined("Author");
|
||||
if (line != nullptr && line->GetParam("text")->IsDefined())
|
||||
{
|
||||
data.author = line->GetParam("text")->AsString();
|
||||
}
|
||||
|
||||
// Version
|
||||
line = levelParser.GetIfDefined("Version");
|
||||
if (line != nullptr)
|
||||
{
|
||||
if (line->GetParam("text")->IsDefined())
|
||||
{
|
||||
data.version = line->GetParam("text")->AsString();
|
||||
}
|
||||
else if (line->GetParam("major")->IsDefined() && line->GetParam("minor")->IsDefined() && line->GetParam("patch")->IsDefined())
|
||||
{
|
||||
auto major = StrUtils::ToString(line->GetParam("major")->AsInt());
|
||||
auto minor = StrUtils::ToString(line->GetParam("minor")->AsInt());
|
||||
auto patch = StrUtils::ToString(line->GetParam("patch")->AsInt());
|
||||
|
||||
std::ostringstream stream;
|
||||
stream << major << "." << minor << "." << patch;
|
||||
data.version = stream.str();
|
||||
}
|
||||
}
|
||||
|
||||
// Website
|
||||
line = levelParser.GetIfDefined("Website");
|
||||
if (line != nullptr && line->GetParam("text")->IsDefined())
|
||||
{
|
||||
data.website = line->GetParam("text")->AsString();
|
||||
}
|
||||
|
||||
// Summary
|
||||
line = levelParser.GetIfDefined("Summary");
|
||||
if (line != nullptr && line->GetParam("text")->IsDefined())
|
||||
{
|
||||
data.summary = line->GetParam("text")->AsString();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
GetLogger()->Warn("No manifest file for mod %s\n", mod.name.c_str());
|
||||
}
|
||||
}
|
||||
catch (CLevelParserException& e)
|
||||
{
|
||||
GetLogger()->Warn("Failed parsing manifest for mod %s: %s\n", mod.name.c_str(), e.what());
|
||||
}
|
||||
|
||||
// Changes
|
||||
data.changes = CResourceManager::ListDirectories("temp/mod");
|
||||
auto levelsIt = std::find(data.changes.begin(), data.changes.end(), "levels");
|
||||
if (levelsIt != data.changes.end())
|
||||
{
|
||||
auto levelsDirs = CResourceManager::ListDirectories("temp/mod/levels");
|
||||
if (!levelsDirs.empty())
|
||||
{
|
||||
std::transform(levelsDirs.begin(), levelsDirs.end(), levelsDirs.begin(), [](const std::string& dir) { return "levels/" + dir; });
|
||||
levelsIt = data.changes.erase(levelsIt);
|
||||
data.changes.insert(levelsIt, levelsDirs.begin(), levelsDirs.end());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CModManager::MountMod(const Mod& mod, const std::string& mountPoint)
|
||||
{
|
||||
MountMod(mod.path, mountPoint);
|
||||
}
|
||||
|
||||
void CModManager::MountMod(const std::string& path, const std::string& mountPoint)
|
||||
{
|
||||
GetLogger()->Debug("Mounting mod: '%s' at path %s\n", path.c_str(), mountPoint.c_str());
|
||||
CResourceManager::AddLocation(path, true, mountPoint);
|
||||
}
|
||||
|
||||
void CModManager::UnmountMod(const Mod& mod)
|
||||
{
|
||||
UnmountMod(mod.path);
|
||||
}
|
||||
|
||||
void CModManager::UnmountMod(const std::string& path)
|
||||
{
|
||||
if (CResourceManager::LocationExists(path))
|
||||
{
|
||||
GetLogger()->Debug("Unmounting mod: '%s'\n", path.c_str());
|
||||
CResourceManager::RemoveLocation(path);
|
||||
}
|
||||
}
|
||||
|
||||
void CModManager::UnmountAllMountedMods()
|
||||
{
|
||||
for (const auto& path : m_mountedModPaths)
|
||||
{
|
||||
UnmountMod(path);
|
||||
}
|
||||
m_mountedModPaths.clear();
|
||||
}
|
|
@ -1,124 +0,0 @@
|
|||
/*
|
||||
* This file is part of the Colobot: Gold Edition source code
|
||||
* Copyright (C) 2001-2023, Daniel Roux, EPSITEC SA & TerranovaTeam
|
||||
* http://epsitec.ch; http://colobot.info; http://github.com/colobot
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see http://gnu.org/licenses
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
class CApplication;
|
||||
class CPathManager;
|
||||
|
||||
struct ModData
|
||||
{
|
||||
std::string displayName{};
|
||||
std::string author{};
|
||||
std::string version{};
|
||||
std::string website{};
|
||||
std::string summary{};
|
||||
std::vector<std::string> changes{};
|
||||
};
|
||||
|
||||
struct Mod
|
||||
{
|
||||
std::string name{};
|
||||
std::string path{};
|
||||
bool enabled = false;
|
||||
ModData data{};
|
||||
};
|
||||
|
||||
/**
|
||||
* \class CModManager
|
||||
* \brief This class handles the list of mods.
|
||||
*
|
||||
* The order matters since the order in which files are loaded matters,
|
||||
* because some files can be overwritten.
|
||||
*
|
||||
* The changes in the list do not immediately apply.
|
||||
*/
|
||||
class CModManager
|
||||
{
|
||||
public:
|
||||
CModManager(CApplication* app, CPathManager* pathManager);
|
||||
|
||||
//! Finds all the mods along with their metadata
|
||||
void FindMods();
|
||||
|
||||
//! Applies the current configuration and reloads the application
|
||||
void ReloadMods();
|
||||
|
||||
//! Removes a mod from the list of loaded mods
|
||||
void EnableMod(size_t i);
|
||||
|
||||
//! Adds a mod to the list of loaded mods
|
||||
void DisableMod(size_t i);
|
||||
|
||||
//! Moves the selected mod up in the list so that it's loaded sooner than others, returns the new index
|
||||
size_t MoveUp(size_t i);
|
||||
|
||||
//! Moves the selected mod down in the list so that it's loaded later than others, returns the new index
|
||||
size_t MoveDown(size_t i);
|
||||
|
||||
//! Checks if the list of currently used mods differs from the current configuration or there were changes made by the user
|
||||
bool Changes();
|
||||
|
||||
//! Saves the current configuration of mods to the config file
|
||||
void SaveMods();
|
||||
|
||||
//! Number of mods loaded
|
||||
size_t CountMods() const;
|
||||
|
||||
//! Returns the reference to the mod in given position
|
||||
const Mod& GetMod(size_t i) const;
|
||||
|
||||
//! Returns the list of mods
|
||||
const std::vector<Mod>& GetMods() const;
|
||||
|
||||
private:
|
||||
// Allow access to MountAllMods() as CApplication doesn't want to reload itself during initialization
|
||||
friend CApplication;
|
||||
|
||||
//! Reloads application resources so the enabled mods are applied
|
||||
void ReloadResources();
|
||||
|
||||
//! Load mod data into mod
|
||||
void LoadModData(Mod& mod);
|
||||
|
||||
//! Updates the paths in Path Manager according to the current mod configuration
|
||||
void MountAllMods();
|
||||
|
||||
void MountMod(const Mod& mod, const std::string& mountPoint = "");
|
||||
void MountMod(const std::string& path, const std::string& mountPoint = "");
|
||||
void UnmountMod(const Mod& mod);
|
||||
void UnmountMod(const std::string& path);
|
||||
void UnmountAllMountedMods();
|
||||
|
||||
private:
|
||||
CApplication* m_app;
|
||||
CPathManager* m_pathManager;
|
||||
|
||||
//! Paths to mods already in the virtual filesystem
|
||||
std::vector<std::string> m_mountedModPaths;
|
||||
|
||||
//! List of mods
|
||||
std::vector<Mod> m_mods;
|
||||
|
||||
bool m_userChanges = false;
|
||||
};
|
|
@ -1,89 +0,0 @@
|
|||
/*
|
||||
* This file is part of the Colobot: Gold Edition source code
|
||||
* Copyright (C) 2001-2023, Daniel Roux, EPSITEC SA & TerranovaTeam
|
||||
* http://epsitec.ch; http://colobot.info; http://github.com/colobot
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see http://gnu.org/licenses
|
||||
*/
|
||||
|
||||
#include "common/font_loader.h"
|
||||
|
||||
#include "common/logger.h"
|
||||
#include "common/stringutils.h"
|
||||
|
||||
#include "common/resources/inputstream.h"
|
||||
#include "common/resources/outputstream.h"
|
||||
|
||||
#include "common/system/system.h"
|
||||
|
||||
#include "graphics/engine/text.h"
|
||||
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
#include <cstring>
|
||||
|
||||
|
||||
CFontLoader::CFontLoader()
|
||||
{
|
||||
}
|
||||
|
||||
CFontLoader::~CFontLoader()
|
||||
{
|
||||
}
|
||||
|
||||
bool CFontLoader::Init()
|
||||
{
|
||||
try
|
||||
{
|
||||
std::unique_ptr<std::istream> stream;
|
||||
auto inputStream = std::make_unique<CInputStream>("/fonts/fonts.ini");
|
||||
bool good = inputStream->is_open();
|
||||
stream = std::move(inputStream);
|
||||
|
||||
if (good)
|
||||
{
|
||||
std::string line;
|
||||
|
||||
while (std::getline(*stream, line))
|
||||
{
|
||||
auto parts = StrUtils::Split(line, " =");
|
||||
|
||||
m_fonts[parts[0]] = parts[1];
|
||||
}
|
||||
|
||||
GetLogger()->Debug("Fonts config file loaded correctly. \n");
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
catch (std::exception & e)
|
||||
{
|
||||
GetLogger()->Error("Error on parsing config file: %s\n", e.what());
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
std::optional<std::string> CFontLoader::GetFont(Gfx::FontType type) const
|
||||
{
|
||||
auto iterator = m_fonts.find(ToString(type));
|
||||
|
||||
if (iterator == m_fonts.end())
|
||||
return std::nullopt;
|
||||
else
|
||||
return std::string("/fonts/") + iterator->second;
|
||||
}
|
|
@ -1,54 +0,0 @@
|
|||
/*
|
||||
* This file is part of the Colobot: Gold Edition source code
|
||||
* Copyright (C) 2001-2023, Daniel Roux, EPSITEC SA & TerranovaTeam
|
||||
* http://epsitec.ch; http://colobot.info; http://github.com/colobot
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see http://gnu.org/licenses
|
||||
*/
|
||||
|
||||
#include "common/timeutils.h"
|
||||
|
||||
#include <cassert>
|
||||
|
||||
namespace TimeUtils
|
||||
{
|
||||
|
||||
TimeStamp Lerp(TimeStamp a, TimeStamp b, float t)
|
||||
{
|
||||
return a + std::chrono::duration_cast<TimeStamp::duration>((b - a) * t);
|
||||
}
|
||||
|
||||
float Diff(TimeStamp before, TimeStamp after, TimeUnit unit)
|
||||
{
|
||||
long long exact = ExactDiff(before, after);
|
||||
|
||||
float result = 0.0f;
|
||||
if (unit == TimeUnit::SECONDS)
|
||||
result = exact * 1e-9;
|
||||
else if (unit == TimeUnit::MILLISECONDS)
|
||||
result = exact * 1e-6;
|
||||
else if (unit == TimeUnit::MICROSECONDS)
|
||||
result = exact * 1e-3;
|
||||
else
|
||||
assert(false);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
long long ExactDiff(TimeStamp before, TimeStamp after)
|
||||
{
|
||||
return std::chrono::duration_cast<std::chrono::nanoseconds>(after - before).count();
|
||||
}
|
||||
|
||||
} // namespace TimeUtils
|
|
@ -1,50 +0,0 @@
|
|||
/*
|
||||
* This file is part of the Colobot: Gold Edition source code
|
||||
* Copyright (C) 2001-2023, Daniel Roux, EPSITEC SA & TerranovaTeam
|
||||
* http://epsitec.ch; http://colobot.info; http://github.com/colobot
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see http://gnu.org/licenses
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file common/timeutils.h
|
||||
* \brief Some useful cross-platform operations on timestamps
|
||||
*/
|
||||
|
||||
#include <chrono>
|
||||
|
||||
namespace TimeUtils
|
||||
{
|
||||
|
||||
enum class TimeUnit
|
||||
{
|
||||
SECONDS,
|
||||
MILLISECONDS,
|
||||
MICROSECONDS
|
||||
};
|
||||
|
||||
using TimeStamp = std::chrono::time_point<std::chrono::high_resolution_clock>;
|
||||
|
||||
//! Linearly interpolates between two timestamps.
|
||||
TimeStamp Lerp(TimeStamp a, TimeStamp b, float t);
|
||||
|
||||
//! Returns a difference between two timestamps in given time unit
|
||||
/** The difference is \a after - \a before. */
|
||||
float Diff(TimeStamp before, TimeStamp after, TimeUnit unit = TimeUnit::SECONDS);
|
||||
|
||||
//! Returns the exact (in nanosecond units) difference between two timestamps
|
||||
/** The difference is \a after - \a before. */
|
||||
long long ExactDiff(TimeStamp before, TimeStamp after);
|
||||
|
||||
} // namespace TimeUtils
|
|
@ -1,14 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include <string_view>
|
||||
|
||||
namespace Version
|
||||
{
|
||||
static inline constexpr bool OFFICIAL_BUILD = @OFFICIAL_COLOBOT_BUILD@;
|
||||
static inline constexpr bool DEVELOPMENT_BUILD = @DEVELOPMENT_COLOBOT_BUILD@;
|
||||
static inline constexpr int BUILD_NUMBER = @BUILD_NUMBER@;
|
||||
|
||||
static inline constexpr char FULL_NAME[] = "Colobot: Gold Edition @COLOBOT_VERSION_FULL@";
|
||||
static inline constexpr char VERSION[] = "@CMAKE_PROJECT_VERSION@";
|
||||
static inline constexpr char VERSION_DISPLAY[] = "@COLOBOT_VERSION_DISPLAY@";
|
||||
}
|
|
@ -1,395 +0,0 @@
|
|||
/*
|
||||
* This file is part of the Colobot: Gold Edition source code
|
||||
* Copyright (C) 2001-2023, Daniel Roux, EPSITEC SA & TerranovaTeam
|
||||
* http://epsitec.ch; http://colobot.info; http://github.com/colobot
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see http://gnu.org/licenses
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file graphics/core/device.h
|
||||
* \brief Abstract graphics device - CDevice class and related structs/enums
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "graphics/core/color.h"
|
||||
#include "graphics/core/texture.h"
|
||||
#include "graphics/core/vertex.h"
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
|
||||
class CImage;
|
||||
struct ImageData;
|
||||
|
||||
|
||||
// Graphics module namespace
|
||||
namespace Gfx
|
||||
{
|
||||
|
||||
class CFramebuffer;
|
||||
class CUIRenderer;
|
||||
class CTerrainRenderer;
|
||||
class CShadowRenderer;
|
||||
class CObjectRenderer;
|
||||
class CParticleRenderer;
|
||||
|
||||
struct FramebufferParams;
|
||||
struct Light;
|
||||
struct Material;
|
||||
struct Vertex;
|
||||
struct VertexCol;
|
||||
struct Vertex3D;
|
||||
|
||||
enum class CullFace : unsigned char;
|
||||
enum class PrimitiveType : unsigned char;
|
||||
enum class TransparencyMode : unsigned char;
|
||||
|
||||
/**
|
||||
* \struct DeviceConfig
|
||||
* \brief General config for graphics device
|
||||
*
|
||||
* These settings are common window options set by SDL.
|
||||
*/
|
||||
struct DeviceConfig
|
||||
{
|
||||
//! Screen size
|
||||
glm::ivec2 size = { 800, 600 };
|
||||
//! Bits per pixel
|
||||
int bpp = 32;
|
||||
//! Full screen
|
||||
bool fullScreen = false;
|
||||
//! Resizeable window
|
||||
bool resizeable = true;
|
||||
//! Double buffering
|
||||
bool doubleBuf = true;
|
||||
//! No window frame (also set with full screen)
|
||||
bool noFrame = false;
|
||||
|
||||
//! Size of red channel in bits
|
||||
int redSize = 8;
|
||||
//! Size of green channel in bits
|
||||
int greenSize = 8;
|
||||
//! Size of blue channel in bits
|
||||
int blueSize = 8;
|
||||
//! Size of alpha channel in bits
|
||||
int alphaSize = 8;
|
||||
//! Color depth in bits
|
||||
int depthSize = 24;
|
||||
//! Stencil depth in bits
|
||||
int stencilSize = 8;
|
||||
|
||||
//! Force hardware acceleration (video mode set will fail on lack of hw accel)
|
||||
bool hardwareAccel = true;
|
||||
|
||||
//! Loads the default values
|
||||
void LoadDefault()
|
||||
{
|
||||
*this = DeviceConfig();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* \struct DeviceCapabilities
|
||||
* \brief This structs contains various capabilities of graphics device
|
||||
*/
|
||||
struct DeviceCapabilities
|
||||
{
|
||||
bool multitexturingSupported = false;
|
||||
int maxTextures = 1;
|
||||
int maxTextureSize = 1024;
|
||||
|
||||
int maxLights = 8;
|
||||
|
||||
bool shadowMappingSupported = false;
|
||||
|
||||
bool framebufferSupported = false;
|
||||
int maxRenderbufferSize = 0;
|
||||
|
||||
bool anisotropySupported = false;
|
||||
int maxAnisotropy = 1;
|
||||
|
||||
bool multisamplingSupported = false;
|
||||
int maxSamples = 1;
|
||||
};
|
||||
|
||||
/**
|
||||
* \enum FillMode
|
||||
* \brief Polygon fill mode
|
||||
*/
|
||||
enum class FillMode : unsigned char
|
||||
{
|
||||
//! Draw only points
|
||||
POINT,
|
||||
//! Draw only lines
|
||||
LINES,
|
||||
//! Draw full polygons
|
||||
POLY
|
||||
};
|
||||
|
||||
/**
|
||||
* \enum FrustumPlane
|
||||
* \brief Planes of frustum space
|
||||
*
|
||||
* Bitset of flags - can be OR'd together.
|
||||
*/
|
||||
enum FrustumPlane
|
||||
{
|
||||
FRUSTUM_PLANE_LEFT = 0x01,
|
||||
FRUSTUM_PLANE_RIGHT = 0x02,
|
||||
FRUSTUM_PLANE_TOP = 0x04,
|
||||
FRUSTUM_PLANE_BOTTOM = 0x08,
|
||||
FRUSTUM_PLANE_FRONT = 0x10,
|
||||
FRUSTUM_PLANE_BACK = 0x20,
|
||||
FRUSTUM_PLANE_ALL = FRUSTUM_PLANE_LEFT | FRUSTUM_PLANE_RIGHT |
|
||||
FRUSTUM_PLANE_TOP | FRUSTUM_PLANE_BOTTOM |
|
||||
FRUSTUM_PLANE_FRONT | FRUSTUM_PLANE_BACK
|
||||
};
|
||||
|
||||
class CFrameBufferPixels
|
||||
{
|
||||
public:
|
||||
virtual ~CFrameBufferPixels() {}
|
||||
|
||||
virtual void* GetPixelsData() = 0;
|
||||
};
|
||||
|
||||
class CVertexBuffer
|
||||
{
|
||||
protected:
|
||||
PrimitiveType m_type;
|
||||
std::vector<Vertex3D> m_data;
|
||||
|
||||
public:
|
||||
CVertexBuffer(PrimitiveType type, size_t size)
|
||||
: m_type(type), m_data(size, Vertex3D{})
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
virtual ~CVertexBuffer()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
virtual void Update() = 0;
|
||||
|
||||
PrimitiveType GetType() const
|
||||
{
|
||||
return m_type;
|
||||
}
|
||||
|
||||
void SetType(PrimitiveType type)
|
||||
{
|
||||
m_type = type;
|
||||
}
|
||||
|
||||
size_t Size() const
|
||||
{
|
||||
return m_data.size();
|
||||
}
|
||||
|
||||
void Resize(size_t size)
|
||||
{
|
||||
m_data.resize(size);
|
||||
}
|
||||
|
||||
Vertex3D& operator[](size_t index)
|
||||
{
|
||||
return m_data[index];
|
||||
}
|
||||
|
||||
const Vertex3D& operator[](size_t index) const
|
||||
{
|
||||
return m_data[index];
|
||||
}
|
||||
|
||||
void SetData(const Vertex3D* data, size_t offset, size_t count)
|
||||
{
|
||||
std::copy(data, data + count, m_data.data() + offset);
|
||||
}
|
||||
|
||||
auto Data()
|
||||
{
|
||||
return m_data.data();
|
||||
}
|
||||
|
||||
auto Data() const
|
||||
{
|
||||
return m_data.data();
|
||||
}
|
||||
|
||||
auto begin()
|
||||
{
|
||||
return m_data.begin();
|
||||
}
|
||||
|
||||
auto end()
|
||||
{
|
||||
return m_data.end();
|
||||
}
|
||||
|
||||
auto begin() const
|
||||
{
|
||||
return m_data.begin();
|
||||
}
|
||||
|
||||
auto end() const
|
||||
{
|
||||
return m_data.end();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* \class CDevice
|
||||
* \brief Abstract interface of graphics device
|
||||
*
|
||||
* It is based on DIRECT3DDEVICE class from DirectX to make it easier to port existing code.
|
||||
* It encapsulates the general graphics device state and provides a common interface
|
||||
* to graphics-specific functions which will be used throughout the program,
|
||||
* both in CEngine class and in UI classes. Note that it doesn't contain all functions from DirectX,
|
||||
* only those that were used in old code.
|
||||
*
|
||||
*/
|
||||
class CDevice
|
||||
{
|
||||
protected:
|
||||
std::string m_errorMessage;
|
||||
|
||||
//! Capabilities of this device
|
||||
//! Should only be changed by code in concrete device implementation
|
||||
DeviceCapabilities m_capabilities;
|
||||
|
||||
public:
|
||||
virtual ~CDevice() {}
|
||||
|
||||
//! Returns last error message or empty string
|
||||
inline std::string GetError()
|
||||
{
|
||||
return m_errorMessage;
|
||||
}
|
||||
|
||||
//! Returns device capabilities
|
||||
const DeviceCapabilities& GetCapabilities()
|
||||
{
|
||||
return m_capabilities;
|
||||
}
|
||||
|
||||
//! Returns a name of this device
|
||||
virtual std::string GetName() = 0;
|
||||
|
||||
//! Initializes the device, setting the initial state
|
||||
virtual bool Create() = 0;
|
||||
//! Destroys the device, releasing every acquired resource
|
||||
virtual void Destroy() = 0;
|
||||
|
||||
//! Changes configuration
|
||||
virtual void ConfigChanged(const DeviceConfig &newConfig) = 0;
|
||||
|
||||
//! Begins drawing the 3D scene
|
||||
virtual void BeginScene() = 0;
|
||||
//! Ends drawing the 3D scene
|
||||
virtual void EndScene() = 0;
|
||||
|
||||
//! Clears the screen to blank
|
||||
virtual void Clear() = 0;
|
||||
|
||||
//! Returns UI renderer
|
||||
virtual CUIRenderer* GetUIRenderer() = 0;
|
||||
//! Returns terrain renderer
|
||||
virtual CTerrainRenderer* GetTerrainRenderer() = 0;
|
||||
//! Returns object renderer
|
||||
virtual CObjectRenderer* GetObjectRenderer() = 0;
|
||||
//! Returns particle renderer
|
||||
virtual CParticleRenderer* GetParticleRenderer() = 0;
|
||||
//! Returns shadow renderer
|
||||
virtual CShadowRenderer* GetShadowRenderer() = 0;
|
||||
|
||||
//! Creates a texture from image; the image can be safely removed after that
|
||||
virtual Texture CreateTexture(CImage *image, const TextureCreateParams ¶ms) = 0;
|
||||
//! Creates a texture from raw image data; image data can be freed after that
|
||||
virtual Texture CreateTexture(ImageData *data, const TextureCreateParams ¶ms) = 0;
|
||||
//! Creates a depth texture with specific dimensions and depth
|
||||
virtual Texture CreateDepthTexture(int width, int height, int depth) = 0;
|
||||
//! Updates a part of texture from raw image data
|
||||
virtual void UpdateTexture(const Texture& texture, const glm::ivec2& offset, ImageData* data, TextureFormat format) = 0;
|
||||
//! Deletes a given texture, freeing it from video memory
|
||||
virtual void DestroyTexture(const Texture &texture) = 0;
|
||||
//! Deletes all textures created so far
|
||||
virtual void DestroyAllTextures() = 0;
|
||||
|
||||
virtual CVertexBuffer* CreateVertexBuffer(PrimitiveType primitiveType, const Vertex3D* vertices, int vertexCount) = 0;
|
||||
virtual void DestroyVertexBuffer(CVertexBuffer*) = 0;
|
||||
|
||||
//! Changes rendering viewport
|
||||
virtual void SetViewport(int x, int y, int width, int height) = 0;
|
||||
|
||||
//! Sets depth test
|
||||
virtual void SetDepthTest(bool enabled) = 0;
|
||||
//! Sets depth mask
|
||||
virtual void SetDepthMask(bool enabled) = 0;
|
||||
|
||||
//! Sets which faces to cull
|
||||
virtual void SetCullFace(CullFace mode) = 0;
|
||||
|
||||
//! Sets transparency mode
|
||||
virtual void SetTransparency(TransparencyMode mode) = 0;
|
||||
|
||||
//! Sets the color mask
|
||||
virtual void SetColorMask(bool red, bool green, bool blue, bool alpha) = 0;
|
||||
|
||||
//! Sets the clear color
|
||||
virtual void SetClearColor(const Color &color) = 0;
|
||||
|
||||
//! Copies content of framebuffer to texture
|
||||
virtual void CopyFramebufferToTexture(Texture& texture, int xOffset, int yOffset, int x, int y, int width, int height) = 0;
|
||||
|
||||
//! Returns the pixels of the entire screen
|
||||
virtual std::unique_ptr<CFrameBufferPixels> GetFrameBufferPixels() const = 0;
|
||||
|
||||
//! Returns framebuffer with given name or nullptr if it doesn't exist
|
||||
virtual CFramebuffer* GetFramebuffer(std::string name) = 0;
|
||||
|
||||
//! Creates new framebuffer with given name or nullptr if it's not possible
|
||||
virtual CFramebuffer* CreateFramebuffer(std::string name, const FramebufferParams& params) = 0;
|
||||
|
||||
//! Deletes framebuffer
|
||||
virtual void DeleteFramebuffer(std::string name) = 0;
|
||||
|
||||
//! Checks if anisotropy is supported
|
||||
virtual bool IsAnisotropySupported() = 0;
|
||||
|
||||
//! Returns max anisotropy level supported
|
||||
virtual int GetMaxAnisotropyLevel() = 0;
|
||||
|
||||
//! Returns max samples supported
|
||||
virtual int GetMaxSamples() = 0;
|
||||
|
||||
//! Checks if shadow mapping is supported
|
||||
virtual bool IsShadowMappingSupported() = 0;
|
||||
|
||||
//! Returns max texture size supported
|
||||
virtual int GetMaxTextureSize() = 0;
|
||||
|
||||
//! Checks if framebuffers are supported
|
||||
virtual bool IsFramebufferSupported() = 0;
|
||||
};
|
||||
|
||||
|
||||
} // namespace Gfx
|
|
@ -1,114 +0,0 @@
|
|||
/*
|
||||
* This file is part of the Colobot: Gold Edition source code
|
||||
* Copyright (C) 2001-2023, Daniel Roux, EPSITEC SA & TerranovaTeam
|
||||
* http://epsitec.ch; http://colobot.info; http://github.com/colobot
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see http://gnu.org/licenses
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file graphics/core/material.h
|
||||
* \brief Material struct
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
#include "graphics/core/color.h"
|
||||
#include "graphics/core/transparency.h"
|
||||
|
||||
|
||||
// Graphics module namespace
|
||||
namespace Gfx
|
||||
{
|
||||
|
||||
/**
|
||||
* \enum CullFace
|
||||
* \brief Specifies which faces to cull while rendering polygons
|
||||
*/
|
||||
enum class CullFace : unsigned char
|
||||
{
|
||||
NONE,
|
||||
BACK,
|
||||
FRONT,
|
||||
BOTH,
|
||||
};
|
||||
|
||||
//! PBR material
|
||||
struct Material
|
||||
{
|
||||
//! Albedo color
|
||||
Color albedoColor = Color{ 1.0f, 1.0f, 1.0f, 1.0f };
|
||||
//! Albedo texture
|
||||
std::string albedoTexture = "";
|
||||
//! Roughness
|
||||
float roughness = 1.0;
|
||||
//! Metalness
|
||||
float metalness = 0.0;
|
||||
//! AO strength
|
||||
float aoStrength = 0.0;
|
||||
//! AO-roughness-metalness texture
|
||||
std::string materialTexture = "";
|
||||
//! Emissive color
|
||||
Color emissiveColor = Color{ 0.0f, 0.0f, 0.0f, 0.0f };
|
||||
//! Emissive texture
|
||||
std::string emissiveTexture = "";
|
||||
//! Normal map
|
||||
std::string normalTexture = "";
|
||||
//! Alpha mode
|
||||
AlphaMode alphaMode = AlphaMode::NONE;
|
||||
//! Alpha threshold
|
||||
float alphaThreshold = 0.5;
|
||||
// Cull face
|
||||
CullFace cullFace = CullFace::BACK;
|
||||
// Special tag
|
||||
std::string tag = "";
|
||||
// Recolor name
|
||||
std::string recolor = "";
|
||||
// Recolor reference color
|
||||
Color recolorReference = { 0.0f, 0.0f, 0.0f, 0.0f };
|
||||
|
||||
// Legacy functionality
|
||||
//! Variable detail texture
|
||||
bool variableDetail = false;
|
||||
//! Detail texture
|
||||
std::string detailTexture = "";
|
||||
|
||||
bool operator==(const Material& other) const
|
||||
{
|
||||
return albedoColor == other.albedoColor
|
||||
&& albedoTexture == other.albedoTexture
|
||||
&& roughness == other.roughness
|
||||
&& metalness == other.metalness
|
||||
&& materialTexture == other.materialTexture
|
||||
&& emissiveColor == other.emissiveColor
|
||||
&& emissiveTexture == other.emissiveTexture
|
||||
&& normalTexture == other.normalTexture
|
||||
&& alphaMode == other.alphaMode
|
||||
&& alphaThreshold == other.alphaThreshold
|
||||
&& cullFace == other.cullFace
|
||||
&& tag == other.tag
|
||||
&& recolor == other.recolor
|
||||
&& recolorReference == other.recolorReference
|
||||
&& variableDetail == other.variableDetail
|
||||
&& detailTexture == other.detailTexture;
|
||||
}
|
||||
|
||||
bool operator!=(const Material& other) const
|
||||
{
|
||||
return !operator==(other);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace Gfx
|
|
@ -1,293 +0,0 @@
|
|||
/*
|
||||
* This file is part of the Colobot: Gold Edition source code
|
||||
* Copyright (C) 2001-2021, Daniel Roux, EPSITEC SA & TerranovaTeam
|
||||
* http://epsitec.ch; http://colobot.info; http://github.com/colobot
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see http://gnu.org/licenses
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file graphics/core/renderers.h
|
||||
* \brief Abstract classes representing renderers
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
|
||||
// Graphics module namespace
|
||||
namespace Gfx
|
||||
{
|
||||
|
||||
class CVertexBuffer;
|
||||
enum class CullFace : unsigned char;
|
||||
enum class TransparencyMode : unsigned char;
|
||||
struct Color;
|
||||
struct Texture;
|
||||
struct Vertex2D;
|
||||
struct Vertex3D;
|
||||
struct VertexParticle;
|
||||
|
||||
/**
|
||||
* \enum PrimitiveType
|
||||
* \brief Type of primitive to render
|
||||
*/
|
||||
enum class PrimitiveType : unsigned char
|
||||
{
|
||||
POINTS,
|
||||
LINES,
|
||||
LINE_STRIP,
|
||||
LINE_LOOP,
|
||||
TRIANGLES,
|
||||
TRIANGLE_STRIP,
|
||||
TRIANGLE_FAN,
|
||||
};
|
||||
|
||||
struct ShadowParam
|
||||
{
|
||||
glm::mat4 matrix;
|
||||
glm::vec2 uv_offset;
|
||||
glm::vec2 uv_scale;
|
||||
};
|
||||
|
||||
/**
|
||||
* \class CRenderer
|
||||
* \brief Common abstract interface for renderers
|
||||
*/
|
||||
class CRenderer
|
||||
{
|
||||
public:
|
||||
virtual ~CRenderer() { }
|
||||
};
|
||||
|
||||
/**
|
||||
* \class CUIRenderer
|
||||
* \brief Abstract interface for UI renderers
|
||||
*/
|
||||
class CUIRenderer : public CRenderer
|
||||
{
|
||||
public:
|
||||
virtual ~CUIRenderer() { }
|
||||
|
||||
//! Sets ortographic projection with given parameters
|
||||
virtual void SetProjection(float left, float right, float bottom, float top) = 0;
|
||||
//! Sets texture, setting texture 0 means using white texture
|
||||
virtual void SetTexture(const Texture& texture) = 0;
|
||||
//! Sets color
|
||||
virtual void SetColor(const glm::vec4& color) = 0;
|
||||
//! Sets transparency mode
|
||||
virtual void SetTransparency(TransparencyMode mode) = 0;
|
||||
|
||||
virtual Vertex2D* BeginPrimitive(PrimitiveType type, int count) = 0;
|
||||
virtual Vertex2D* BeginPrimitives(PrimitiveType type, int drawCount, const int* counts) = 0;
|
||||
virtual bool EndPrimitive() = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* \class CTerrainRenderer
|
||||
* \brief Abstract interface for terrain renderers
|
||||
*/
|
||||
class CTerrainRenderer : public CRenderer
|
||||
{
|
||||
public:
|
||||
virtual ~CTerrainRenderer() { }
|
||||
|
||||
virtual void Begin() = 0;
|
||||
|
||||
virtual void End() = 0;
|
||||
|
||||
//! Sets projection matrix
|
||||
virtual void SetProjectionMatrix(const glm::mat4& matrix) = 0;
|
||||
//! Sets view matrix
|
||||
virtual void SetViewMatrix(const glm::mat4& matrix) = 0;
|
||||
//! Sets model matrix
|
||||
virtual void SetModelMatrix(const glm::mat4& matrix) = 0;
|
||||
|
||||
//! Sets albedo color
|
||||
virtual void SetAlbedoColor(const Color& color) = 0;
|
||||
//! Sets albedo texture
|
||||
virtual void SetAlbedoTexture(const Texture& texture) = 0;
|
||||
//! Sets emissive color
|
||||
virtual void SetEmissiveColor(const Color& color) = 0;
|
||||
//! Sets emissive texture
|
||||
virtual void SetEmissiveTexture(const Texture& texture) = 0;
|
||||
//! Sets material parameters
|
||||
virtual void SetMaterialParams(float roughness, float metalness, float aoStrength) = 0;
|
||||
//! Sets material texture
|
||||
virtual void SetMaterialTexture(const Texture& texture) = 0;
|
||||
|
||||
//! Sets detail texture
|
||||
virtual void SetDetailTexture(const Texture& texture) = 0;
|
||||
//! Sets shadow map
|
||||
virtual void SetShadowMap(const Texture& texture) = 0;
|
||||
|
||||
//! Sets light parameters
|
||||
virtual void SetLight(const glm::vec4& position, const float& intensity, const glm::vec3& color) = 0;
|
||||
//! Sets sky parameters
|
||||
virtual void SetSky(const Color& color, float intensity) = 0;
|
||||
//! Sets shadow parameters
|
||||
virtual void SetShadowParams(int count, const ShadowParam* params) = 0;
|
||||
|
||||
//! Sets fog parameters
|
||||
virtual void SetFog(float min, float max, const glm::vec3& color) = 0;
|
||||
|
||||
//! Draws terrain object
|
||||
virtual void DrawObject(const glm::mat4& matrix, const CVertexBuffer* buffer) = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* \class CObjectRenderer
|
||||
* \brief Abstract interface for object renderers
|
||||
*/
|
||||
class CObjectRenderer : public CRenderer
|
||||
{
|
||||
public:
|
||||
virtual ~CObjectRenderer() { }
|
||||
|
||||
virtual void Begin() = 0;
|
||||
|
||||
virtual void End() = 0;
|
||||
|
||||
//! Sets projection matrix
|
||||
virtual void SetProjectionMatrix(const glm::mat4& matrix) = 0;
|
||||
//! Sets view matrix
|
||||
virtual void SetViewMatrix(const glm::mat4& matrix) = 0;
|
||||
//! Sets model matrix
|
||||
virtual void SetModelMatrix(const glm::mat4& matrix) = 0;
|
||||
|
||||
//! Sets albedo color
|
||||
virtual void SetAlbedoColor(const Color& color) = 0;
|
||||
//! Sets albedo texture
|
||||
virtual void SetAlbedoTexture(const Texture& texture) = 0;
|
||||
//! Sets emissive color
|
||||
virtual void SetEmissiveColor(const Color& color) = 0;
|
||||
//! Sets emissive texture
|
||||
virtual void SetEmissiveTexture(const Texture& texture) = 0;
|
||||
//! Sets material parameters
|
||||
virtual void SetMaterialParams(float roughness, float metalness, float aoStrength) = 0;
|
||||
//! Sets material texture
|
||||
virtual void SetMaterialTexture(const Texture& texture) = 0;
|
||||
|
||||
//! Sets detail texture
|
||||
virtual void SetDetailTexture(const Texture& texture) = 0;
|
||||
//! Sets shadow map
|
||||
virtual void SetShadowMap(const Texture& texture) = 0;
|
||||
|
||||
//! Enables lighting
|
||||
virtual void SetLighting(bool enabled) = 0;
|
||||
//! Sets light parameters
|
||||
virtual void SetLight(const glm::vec4& position, const float& intensity, const glm::vec3& color) = 0;
|
||||
//! Sets sky parameters
|
||||
virtual void SetSky(const Color& color, float intensity) = 0;
|
||||
//! Sets shadow parameters
|
||||
virtual void SetShadowParams(int count, const ShadowParam* params) = 0;
|
||||
|
||||
//! Sets fog parameters
|
||||
virtual void SetFog(float min, float max, const glm::vec3& color) = 0;
|
||||
//! Sets alpha scissor
|
||||
virtual void SetAlphaScissor(float alpha) = 0;
|
||||
|
||||
//! Sets recolor parameters
|
||||
virtual void SetRecolor(bool enabled, const glm::vec3& from = {}, const glm::vec3& to = {}, float threshold = {}) = 0;
|
||||
|
||||
//! Sets depth test
|
||||
virtual void SetDepthTest(bool enabled) = 0;
|
||||
//! Sets depth mask
|
||||
virtual void SetDepthMask(bool enabled) = 0;
|
||||
//! Sets cull face mode
|
||||
virtual void SetCullFace(CullFace mode) = 0;
|
||||
//! Sets transparency mode
|
||||
virtual void SetTransparency(TransparencyMode mode) = 0;
|
||||
|
||||
//! Sets UV transform
|
||||
virtual void SetUVTransform(const glm::vec2& offset, const glm::vec2& scale) = 0;
|
||||
|
||||
//! Sets triplanar mode
|
||||
virtual void SetTriplanarMode(bool enabled) = 0;
|
||||
//! Sets triplanar scale
|
||||
virtual void SetTriplanarScale(float scale) = 0;
|
||||
|
||||
//! Draws an object
|
||||
virtual void DrawObject(const CVertexBuffer* buffer) = 0;
|
||||
//! Draws a primitive
|
||||
virtual void DrawPrimitive(PrimitiveType type, int count, const Vertex3D* vertices) = 0;
|
||||
//! Draws a set of primitives
|
||||
virtual void DrawPrimitives(PrimitiveType type, int drawCount, int count[], const Vertex3D* vertices) = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* \class CParticleRenderer
|
||||
* \brief Abstract interface for particle renderers
|
||||
*/
|
||||
class CParticleRenderer : public CRenderer
|
||||
{
|
||||
public:
|
||||
virtual ~CParticleRenderer() { }
|
||||
|
||||
virtual void Begin() = 0;
|
||||
|
||||
virtual void End() = 0;
|
||||
|
||||
//! Sets projection matrix
|
||||
virtual void SetProjectionMatrix(const glm::mat4& matrix) = 0;
|
||||
//! Sets view matrix
|
||||
virtual void SetViewMatrix(const glm::mat4& matrix) = 0;
|
||||
//! Sets model matrix
|
||||
virtual void SetModelMatrix(const glm::mat4& matrix) = 0;
|
||||
|
||||
//! Sets color
|
||||
virtual void SetColor(const glm::vec4& color) = 0;
|
||||
//! Sets texture
|
||||
virtual void SetTexture(const Texture& texture) = 0;
|
||||
|
||||
//! Sets transparency mode
|
||||
virtual void SetTransparency(TransparencyMode mode) = 0;
|
||||
|
||||
//! Draws particles
|
||||
virtual void DrawParticle(PrimitiveType type, int count, const VertexParticle* vertices) = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* \class CShadowRenderer
|
||||
* \brief Abstract interface for shadow renderers
|
||||
*/
|
||||
class CShadowRenderer : public CRenderer
|
||||
{
|
||||
public:
|
||||
virtual ~CShadowRenderer() { }
|
||||
|
||||
virtual void Begin() = 0;
|
||||
|
||||
virtual void End() = 0;
|
||||
|
||||
//! Sets projection matrix
|
||||
virtual void SetProjectionMatrix(const glm::mat4& matrix) = 0;
|
||||
//! Sets view matrix
|
||||
virtual void SetViewMatrix(const glm::mat4& matrix) = 0;
|
||||
//! Sets model matrix
|
||||
virtual void SetModelMatrix(const glm::mat4& matrix) = 0;
|
||||
|
||||
//! Sets texture
|
||||
virtual void SetTexture(const Texture& texture) = 0;
|
||||
|
||||
//! Sets shadow map
|
||||
virtual void SetShadowMap(const Texture& texture) = 0;
|
||||
//! Sets shadow region
|
||||
virtual void SetShadowRegion(const glm::vec2& offset, const glm::vec2& scale) = 0;
|
||||
|
||||
//! Draws terrain object
|
||||
virtual void DrawObject(const CVertexBuffer* buffer, bool transparent) = 0;
|
||||
};
|
||||
|
||||
} // namespace Gfx
|
|
@ -1,163 +0,0 @@
|
|||
/*
|
||||
* This file is part of the Colobot: Gold Edition source code
|
||||
* Copyright (C) 2001-2023, Daniel Roux, EPSITEC SA & TerranovaTeam
|
||||
* http://epsitec.ch; http://colobot.info; http://github.com/colobot
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see http://gnu.org/licenses
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file graphics/core/texture.h
|
||||
* \brief Texture struct and related enums
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
|
||||
|
||||
// Graphics module namespace
|
||||
namespace Gfx
|
||||
{
|
||||
|
||||
|
||||
/**
|
||||
* \enum TextureFormat
|
||||
* \brief Format of image data
|
||||
*/
|
||||
enum class TextureFormat : unsigned char
|
||||
{
|
||||
//! Try to determine automatically (may not work)
|
||||
AUTO,
|
||||
//! RGB triplet, 3 bytes
|
||||
RGB,
|
||||
//! BGR triplet, 3 bytes
|
||||
BGR,
|
||||
//! RGBA triplet, 4 bytes
|
||||
RGBA,
|
||||
//! BGRA triplet, 4 bytes
|
||||
BGRA,
|
||||
};
|
||||
|
||||
/**
|
||||
* \enum TextureFilter
|
||||
* \brief General texture filtering mode
|
||||
*
|
||||
* Corresponds to typical options in game graphics settings.
|
||||
*/
|
||||
enum class TextureFilter : unsigned char
|
||||
{
|
||||
//! Nearest-neighbor filtering
|
||||
NEAREST,
|
||||
//! Linear filtering
|
||||
BILINEAR,
|
||||
//! Linear filtering with mipmapping
|
||||
TRILINEAR,
|
||||
};
|
||||
|
||||
/**
|
||||
* \enum TexWrapMode
|
||||
* \brief Wrapping mode for texture coords
|
||||
*/
|
||||
enum class TextureWrapMode : unsigned char
|
||||
{
|
||||
//! UVs are clamped to edges
|
||||
CLAMP,
|
||||
//! UVs are repeated
|
||||
REPEAT,
|
||||
};
|
||||
|
||||
/**
|
||||
* \struct TextureCreateParams
|
||||
* \brief Parameters for texture creation
|
||||
*
|
||||
* These params define how particular texture is created and later displayed.
|
||||
* They must be specified at texture creation time and cannot be changed later.
|
||||
*/
|
||||
struct TextureCreateParams
|
||||
{
|
||||
//! Whether to generate mipmaps
|
||||
bool mipmap = false;
|
||||
//! Format of source image data
|
||||
TextureFormat format = TextureFormat::RGB;
|
||||
//! General texture filtering mode
|
||||
TextureFilter filter = TextureFilter::NEAREST;
|
||||
//! Wrap mode for texture coordinates
|
||||
TextureWrapMode wrap = TextureWrapMode::REPEAT;
|
||||
//! Pad the image to nearest power of 2 dimensions
|
||||
bool padToNearestPowerOfTwo = false;
|
||||
};
|
||||
|
||||
/**
|
||||
* \struct Texture
|
||||
* \brief Info about a texture
|
||||
*
|
||||
* Identifies (through id) a texture created in graphics engine.
|
||||
* Also contains some additional data.
|
||||
*/
|
||||
struct Texture
|
||||
{
|
||||
//! ID of the texture in graphics engine; 0 = invalid texture
|
||||
unsigned int id = 0;
|
||||
//! Size of texture
|
||||
glm::ivec2 size = { 0, 0 };
|
||||
//! Original size of texture (as loaded from image)
|
||||
glm::ivec2 originalSize = { 0, 0 };
|
||||
//! Whether the texture has alpha channel
|
||||
bool alpha = false;
|
||||
|
||||
//! Returns whether the texture is valid (ID != 0)
|
||||
bool Valid() const
|
||||
{
|
||||
return id != 0;
|
||||
}
|
||||
|
||||
//! Sets the ID to invalid value (0)
|
||||
void SetInvalid()
|
||||
{
|
||||
id = 0;
|
||||
}
|
||||
|
||||
//! Comparator for use in texture maps and sets
|
||||
bool operator<(const Texture &other) const
|
||||
{
|
||||
// Invalid textures are always "less than" every other texture
|
||||
|
||||
if ( (! Valid()) && (! other.Valid()) )
|
||||
return false;
|
||||
|
||||
if (! Valid())
|
||||
return true;
|
||||
|
||||
if (! other.Valid())
|
||||
return false;
|
||||
|
||||
return id < other.id;
|
||||
}
|
||||
|
||||
//! Comparator
|
||||
bool operator==(const Texture &other) const
|
||||
{
|
||||
if (Valid() != other.Valid())
|
||||
return false;
|
||||
if ( (! Valid()) && (! other.Valid()) )
|
||||
return true;
|
||||
|
||||
return id == other.id;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
} // namespace Gfx
|
||||
|
|
@ -1,48 +0,0 @@
|
|||
/*
|
||||
* This file is part of the Colobot: Gold Edition source code
|
||||
* Copyright (C) 2001-2022, Daniel Roux, EPSITEC SA & TerranovaTeam
|
||||
* http://epsitec.ch; http://colobot.info; http://github.com/colobot
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see http://gnu.org/licenses
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file graphics/core/transparency.h
|
||||
* \brief Structures and functions related to transparency
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
// Graphics module namespace
|
||||
namespace Gfx
|
||||
{
|
||||
|
||||
//! Transparency mode
|
||||
enum class TransparencyMode : unsigned char
|
||||
{
|
||||
NONE,
|
||||
ALPHA,
|
||||
BLACK,
|
||||
WHITE,
|
||||
};
|
||||
|
||||
//! Alpha transparency mode
|
||||
enum class AlphaMode : unsigned char
|
||||
{
|
||||
NONE, // opaque material
|
||||
MASK, // alpha scissor with threshold
|
||||
BLEND, // alpha blending
|
||||
};
|
||||
|
||||
}
|
|
@ -1,75 +0,0 @@
|
|||
/*
|
||||
* This file is part of the Colobot: Gold Edition source code
|
||||
* Copyright (C) 2001-2023, Daniel Roux, EPSITEC SA & TerranovaTeam
|
||||
* http://epsitec.ch; http://colobot.info; http://github.com/colobot
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see http://gnu.org/licenses
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file graphics/core/vertex.h
|
||||
* \brief Vertex structs
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
#include "graphics/core/color.h"
|
||||
#include "graphics/core/type.h"
|
||||
|
||||
#include <sstream>
|
||||
#include <cstdint>
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
|
||||
// Graphics module namespace
|
||||
namespace Gfx
|
||||
{
|
||||
|
||||
/**
|
||||
* \struct Vertex2D
|
||||
* \brief 2D vertex for interface rendering, contains UV and color
|
||||
*/
|
||||
struct Vertex2D
|
||||
{
|
||||
glm::vec2 position = { 0.0f, 0.0f };
|
||||
glm::vec2 uv = { 0.0f, 0.0f };
|
||||
glm::u8vec4 color = { 255, 255, 255, 255 };
|
||||
};
|
||||
|
||||
/**
|
||||
* \struct Vertex3D
|
||||
* \brief 3D vertex for 3D rendering, contains UV, color and normal
|
||||
*/
|
||||
struct Vertex3D
|
||||
{
|
||||
glm::vec3 position = { 0.0f, 0.0f, 0.0f };
|
||||
glm::u8vec4 color = { 255, 255, 255, 255 };
|
||||
glm::vec2 uv = { 0.0f, 0.0f };
|
||||
glm::vec2 uv2 = { 0.0f, 0.0f };
|
||||
glm::vec3 normal = { 0.0f, 0.0f, 1.0f };
|
||||
};
|
||||
|
||||
/**
|
||||
* \struct VertexParticle
|
||||
* \brief 3D vertex for particle rendering, contains color and UV coordinates
|
||||
*/
|
||||
struct VertexParticle
|
||||
{
|
||||
glm::vec3 position = { 0.0f, 0.0f, 0.0f };
|
||||
glm::u8vec4 color = { 255, 255, 255, 255 };
|
||||
glm::vec2 uv = { 0.0f, 0.0f };
|
||||
};
|
||||
|
||||
} // namespace Gfx
|
|
@ -1,713 +0,0 @@
|
|||
/*
|
||||
* This file is part of the Colobot: Gold Edition source code
|
||||
* Copyright (C) 2001-2022, Daniel Roux, EPSITEC SA & TerranovaTeam
|
||||
* http://epsitec.ch; http://colobot.info; http://github.com/colobot
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see http://gnu.org/licenses
|
||||
*/
|
||||
|
||||
#include "graphics/model/model_mod.h"
|
||||
|
||||
#include "common/ioutils.h"
|
||||
#include "common/logger.h"
|
||||
#include "common/resources/inputstream.h"
|
||||
|
||||
#include "graphics/model/model_io_exception.h"
|
||||
#include "graphics/model/model_io_structs.h"
|
||||
|
||||
#include <vector>
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
using namespace IOUtils;
|
||||
|
||||
using json = nlohmann::json;
|
||||
|
||||
namespace Gfx::ModelIO
|
||||
{
|
||||
|
||||
struct BufferView
|
||||
{
|
||||
int buffer = 0;
|
||||
size_t offset = 0;
|
||||
size_t length = 0;
|
||||
};
|
||||
|
||||
struct Accessor
|
||||
{
|
||||
int bufferView = 0;
|
||||
size_t byteOffset = 0;
|
||||
int componentType = 0;
|
||||
int count = 0;
|
||||
std::string type = "";
|
||||
};
|
||||
|
||||
struct Texture
|
||||
{
|
||||
int sampler = -1;
|
||||
int source = 0;
|
||||
};
|
||||
|
||||
struct Image
|
||||
{
|
||||
std::string uri;
|
||||
};
|
||||
|
||||
struct Sampler
|
||||
{
|
||||
|
||||
};
|
||||
|
||||
class GLTFLoader
|
||||
{
|
||||
public:
|
||||
std::unique_ptr<CModel> Load(const std::filesystem::path& path);
|
||||
|
||||
private:
|
||||
void ReadBuffers();
|
||||
void ReadBufferViews();
|
||||
void ReadMaterials();
|
||||
void ReadAccessors();
|
||||
void ReadSamplers();
|
||||
void ReadImages();
|
||||
void ReadTextures();
|
||||
void ReadMeshes();
|
||||
|
||||
std::vector<glm::vec3> ReadPositions(int index);
|
||||
std::vector<glm::vec3> ReadNormals(int index);
|
||||
std::vector<glm::vec2> ReadUVs(int index);
|
||||
std::vector<glm::u8vec4> ReadColors(int index);
|
||||
std::vector<unsigned> ReadIndices(int index);
|
||||
|
||||
std::unique_ptr<CModel> m_model;
|
||||
|
||||
std::filesystem::path m_directory;
|
||||
json m_root;
|
||||
|
||||
std::vector<std::vector<char>> m_buffers;
|
||||
std::vector<BufferView> m_bufferViews;
|
||||
std::vector<Material> m_materials;
|
||||
std::vector<Accessor> m_accessors;
|
||||
std::vector<Texture> m_textures;
|
||||
std::vector<Image> m_images;
|
||||
std::vector<Sampler> m_samplers;
|
||||
};
|
||||
|
||||
std::unique_ptr<CModel> ReadGLTFModel(const std::filesystem::path& path)
|
||||
{
|
||||
GLTFLoader loader;
|
||||
|
||||
return loader.Load(path);
|
||||
}
|
||||
|
||||
std::unique_ptr<CModel> GLTFLoader::Load(const std::filesystem::path& path)
|
||||
{
|
||||
m_directory = path.parent_path();
|
||||
|
||||
CInputStream stream(path);
|
||||
|
||||
stream >> m_root;
|
||||
|
||||
m_model = std::make_unique<CModel>();
|
||||
|
||||
ReadBuffers();
|
||||
ReadBufferViews();
|
||||
ReadAccessors();
|
||||
ReadSamplers();
|
||||
ReadImages();
|
||||
ReadTextures();
|
||||
ReadMaterials();
|
||||
ReadMeshes();
|
||||
|
||||
return std::move(m_model);
|
||||
}
|
||||
|
||||
void GLTFLoader::ReadBuffers()
|
||||
{
|
||||
m_buffers.clear();
|
||||
|
||||
for (const auto& node : m_root["buffers"])
|
||||
{
|
||||
size_t length = node["byteLength"].get<int>();
|
||||
|
||||
std::vector<char> buffer(length);
|
||||
|
||||
if (node.contains("uri"))
|
||||
{
|
||||
auto uri = m_directory / node["uri"].get<std::string>();
|
||||
|
||||
CInputStream stream(uri);
|
||||
|
||||
stream.read(buffer.data(), buffer.size());
|
||||
}
|
||||
else
|
||||
{
|
||||
GetLogger()->Error("Base64 not yet supported\n");
|
||||
}
|
||||
|
||||
m_buffers.emplace_back(std::move(buffer));
|
||||
}
|
||||
}
|
||||
|
||||
void GLTFLoader::ReadBufferViews()
|
||||
{
|
||||
m_bufferViews.clear();
|
||||
|
||||
for (const auto& node : m_root["bufferViews"])
|
||||
{
|
||||
BufferView bufferView{};
|
||||
|
||||
bufferView.buffer = node["buffer"].get<int>();
|
||||
bufferView.offset = node["byteOffset"].get<int>();
|
||||
bufferView.length = node["byteLength"].get<int>();
|
||||
|
||||
m_bufferViews.push_back(bufferView);
|
||||
}
|
||||
}
|
||||
|
||||
void GLTFLoader::ReadMaterials()
|
||||
{
|
||||
m_materials.clear();
|
||||
|
||||
for (const auto& material : m_root["materials"])
|
||||
{
|
||||
Material mat;
|
||||
|
||||
if (material.contains("doubleSided"))
|
||||
{
|
||||
mat.cullFace = material["doubleSided"].get<bool>() ? CullFace::NONE : CullFace::BACK;
|
||||
}
|
||||
|
||||
if (material.contains("extras"))
|
||||
{
|
||||
const auto& extras = material["extras"];
|
||||
|
||||
if (extras.contains("dirt"))
|
||||
{
|
||||
int dirt = extras["dirt"].get<int>();
|
||||
|
||||
std::string texName = std::string("dirty0") + char('0' + dirt) + ".png";
|
||||
|
||||
mat.detailTexture = texName;
|
||||
}
|
||||
|
||||
if (extras.contains("tag"))
|
||||
{
|
||||
mat.tag = extras["tag"].get<std::string>();
|
||||
}
|
||||
|
||||
if (extras.contains("recolor"))
|
||||
{
|
||||
mat.recolor = extras["recolor"].get<std::string>();
|
||||
}
|
||||
|
||||
if (extras.contains("recolor_ref"))
|
||||
{
|
||||
const auto& color = extras["recolor_ref"];
|
||||
|
||||
float r = color[0];
|
||||
float g = color[1];
|
||||
float b = color[2];
|
||||
|
||||
mat.recolorReference = Color(r, g, b);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if (material.contains("emissiveFactor"))
|
||||
{
|
||||
const auto& color = material["emissiveFactor"];
|
||||
|
||||
mat.emissiveColor = {
|
||||
color[0].get<float>(),
|
||||
color[1].get<float>(),
|
||||
color[2].get<float>(),
|
||||
0.0
|
||||
};
|
||||
|
||||
mat.emissiveColor = Gfx::ToLinear(mat.emissiveColor);
|
||||
}
|
||||
else
|
||||
{
|
||||
mat.emissiveColor = { 0.0, 0.0, 0.0, 0.0 };
|
||||
}
|
||||
|
||||
if (material.contains("emissiveTexture"))
|
||||
{
|
||||
const auto& tex = material["emissiveTexture"];
|
||||
|
||||
if (tex.contains("index"))
|
||||
{
|
||||
int index = tex["index"].get<int>();
|
||||
|
||||
const auto& texture = m_textures[index];
|
||||
|
||||
const auto& image = m_images[texture.source];
|
||||
|
||||
mat.emissiveTexture = image.uri;
|
||||
}
|
||||
}
|
||||
|
||||
if (material.contains("pbrMetallicRoughness"))
|
||||
{
|
||||
const auto& pbr = material["pbrMetallicRoughness"];
|
||||
|
||||
if (pbr.contains("baseColorFactor"))
|
||||
{
|
||||
const auto& color = pbr["baseColorFactor"];
|
||||
|
||||
mat.albedoColor = {
|
||||
color[0].get<float>(),
|
||||
color[1].get<float>(),
|
||||
color[2].get<float>(),
|
||||
color[3].get<float>()
|
||||
};
|
||||
|
||||
mat.albedoColor = Gfx::ToLinear(mat.albedoColor);
|
||||
}
|
||||
else
|
||||
{
|
||||
mat.albedoColor = { 1.0, 1.0, 1.0, 1.0 };
|
||||
}
|
||||
|
||||
if (pbr.contains("baseColorTexture"))
|
||||
{
|
||||
const auto& tex = pbr["baseColorTexture"];
|
||||
|
||||
if (tex.contains("index"))
|
||||
{
|
||||
int index = tex["index"].get<int>();
|
||||
|
||||
const auto& texture = m_textures[index];
|
||||
|
||||
const auto& image = m_images[texture.source];
|
||||
|
||||
mat.albedoTexture = image.uri;
|
||||
}
|
||||
}
|
||||
|
||||
if (pbr.contains("metallicFactor"))
|
||||
{
|
||||
mat.metalness = pbr["metallicFactor"].get<float>();
|
||||
}
|
||||
else
|
||||
{
|
||||
mat.metalness = 1.0;
|
||||
}
|
||||
|
||||
if (pbr.contains("roughnessFactor"))
|
||||
{
|
||||
mat.roughness = pbr["roughnessFactor"].get<float>();
|
||||
}
|
||||
else
|
||||
{
|
||||
mat.roughness = 1.0;
|
||||
}
|
||||
|
||||
if (pbr.contains("metallicRoughnessTexture"))
|
||||
{
|
||||
const auto& tex = pbr["metallicRoughnessTexture"];
|
||||
|
||||
if (tex.contains("index"))
|
||||
{
|
||||
int index = tex["index"].get<int>();
|
||||
|
||||
const auto& texture = m_textures[index];
|
||||
|
||||
const auto& image = m_images[texture.source];
|
||||
|
||||
mat.materialTexture = image.uri;
|
||||
}
|
||||
}
|
||||
|
||||
if (pbr.contains("occlusionTexture"))
|
||||
{
|
||||
const auto& tex = pbr["occlusionTexture"];
|
||||
|
||||
if (tex.contains("index"))
|
||||
{
|
||||
int index = tex["index"].get<int>();
|
||||
|
||||
const auto& texture = m_textures[index];
|
||||
|
||||
[[maybe_unused]] const auto& image = m_images[texture.source];
|
||||
|
||||
if (tex.contains("strength"))
|
||||
{
|
||||
mat.aoStrength = tex["strength"].get<float>();
|
||||
}
|
||||
else
|
||||
{
|
||||
mat.aoStrength = 1.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (material.contains("normalTexture"))
|
||||
{
|
||||
const auto& tex = material["normalTexture"];
|
||||
|
||||
if (tex.contains("index"))
|
||||
{
|
||||
int index = tex["index"].get<int>();
|
||||
|
||||
const auto& texture = m_textures[index];
|
||||
|
||||
const auto& image = m_images[texture.source];
|
||||
|
||||
mat.normalTexture = image.uri;
|
||||
}
|
||||
}
|
||||
|
||||
if (material.contains("alphaMode"))
|
||||
{
|
||||
auto mode = material["alphaMode"].get<std::string>();
|
||||
|
||||
if (mode == "OPAQUE")
|
||||
mat.alphaMode = AlphaMode::NONE;
|
||||
else if (mode == "MASK")
|
||||
mat.alphaMode = AlphaMode::MASK;
|
||||
else if (mode == "BLEND")
|
||||
mat.alphaMode = AlphaMode::BLEND;
|
||||
}
|
||||
|
||||
if (material.contains("alphaCutoff"))
|
||||
{
|
||||
mat.alphaThreshold = material["alphaCutoff"].get<float>();
|
||||
}
|
||||
|
||||
m_materials.push_back(mat);
|
||||
}
|
||||
}
|
||||
|
||||
void GLTFLoader::ReadAccessors()
|
||||
{
|
||||
m_accessors.clear();
|
||||
|
||||
for (const auto& node : m_root["accessors"])
|
||||
{
|
||||
Accessor accessor{};
|
||||
|
||||
accessor.bufferView = node["bufferView"].get<int>();
|
||||
|
||||
if (node.contains("byteOffset"))
|
||||
accessor.byteOffset = node["byteOffset"].get<int>();
|
||||
else
|
||||
accessor.byteOffset = 0;
|
||||
accessor.count = node["count"].get<int>();
|
||||
accessor.componentType = node["componentType"].get<int>();
|
||||
accessor.type = node["type"].get<std::string>();
|
||||
|
||||
m_accessors.push_back(accessor);
|
||||
}
|
||||
}
|
||||
|
||||
void GLTFLoader::ReadSamplers()
|
||||
{
|
||||
m_samplers.clear();
|
||||
|
||||
for ([[maybe_unused]] const auto& node : m_root["samplers"])
|
||||
{
|
||||
Sampler sampler{};
|
||||
|
||||
m_samplers.push_back(sampler);
|
||||
}
|
||||
}
|
||||
|
||||
void GLTFLoader::ReadImages()
|
||||
{
|
||||
m_images.clear();
|
||||
|
||||
for (const auto& node : m_root["images"])
|
||||
{
|
||||
Image image{};
|
||||
|
||||
if (node.contains("uri"))
|
||||
{
|
||||
image.uri = node["uri"].get<std::string>();
|
||||
}
|
||||
|
||||
m_images.push_back(image);
|
||||
}
|
||||
}
|
||||
|
||||
void GLTFLoader::ReadTextures()
|
||||
{
|
||||
m_textures.clear();
|
||||
|
||||
for (const auto& node : m_root["textures"])
|
||||
{
|
||||
Texture texture{};
|
||||
|
||||
if (node.contains("sampler"))
|
||||
texture.sampler = node["sampler"].get<int>();
|
||||
|
||||
texture.source = node["source"].get<int>();
|
||||
|
||||
m_textures.push_back(texture);
|
||||
}
|
||||
}
|
||||
|
||||
void GLTFLoader::ReadMeshes()
|
||||
{
|
||||
m_model = std::make_unique<CModel>();
|
||||
|
||||
for (const auto& node : m_root["meshes"])
|
||||
{
|
||||
auto name = node["name"].get<std::string>();
|
||||
|
||||
auto mesh = std::make_unique<CModelMesh>();
|
||||
|
||||
for (const auto& primitive : node["primitives"])
|
||||
{
|
||||
const auto& material = m_materials[primitive["material"].get<int>()];
|
||||
|
||||
auto part = mesh->AddPart(material);
|
||||
|
||||
if (primitive.contains("attributes"))
|
||||
{
|
||||
const auto& attributes = primitive["attributes"];
|
||||
|
||||
auto positions = ReadPositions(attributes["POSITION"].get<int>());
|
||||
|
||||
if (positions.empty()) continue;
|
||||
|
||||
part->SetVertices(positions.size());
|
||||
|
||||
for (size_t i = 0; i < positions.size(); i++)
|
||||
part->GetVertex(i).SetPosition(positions[i] * glm::vec3(1.0f, 1.0f, -1.0f));
|
||||
|
||||
if (attributes.contains("NORMAL"))
|
||||
{
|
||||
part->Add(VertexAttribute::NORMAL);
|
||||
|
||||
auto normals = ReadNormals(attributes["NORMAL"].get<int>());
|
||||
|
||||
for (size_t i = 0; i < normals.size(); i++)
|
||||
part->GetVertex(i).SetNormal(normals[i] * glm::vec3(1.0f, 1.0f, -1.0f));
|
||||
}
|
||||
|
||||
if (attributes.contains("TEXCOORD_0"))
|
||||
{
|
||||
part->Add(VertexAttribute::UV1);
|
||||
|
||||
auto uvs = ReadUVs(attributes["TEXCOORD_0"].get<int>());
|
||||
|
||||
for (size_t i = 0; i < uvs.size(); i++)
|
||||
part->GetVertex(i).SetUV1(uvs[i]);
|
||||
}
|
||||
|
||||
if (attributes.contains("TEXCOORD_1"))
|
||||
{
|
||||
part->Add(VertexAttribute::UV2);
|
||||
|
||||
auto uvs = ReadUVs(attributes["TEXCOORD_1"].get<int>());
|
||||
|
||||
for (size_t i = 0; i < uvs.size(); i++)
|
||||
part->GetVertex(i).SetUV2(uvs[i]);
|
||||
}
|
||||
|
||||
if (attributes.contains("COLOR_0"))
|
||||
{
|
||||
part->Add(VertexAttribute::COLOR);
|
||||
|
||||
auto colors = ReadColors(attributes["COLOR_0"].get<int>());
|
||||
|
||||
for (size_t i = 0; i < colors.size(); i++)
|
||||
part->GetVertex(i).SetColor(colors[i]);
|
||||
}
|
||||
}
|
||||
|
||||
if (primitive.contains("indices"))
|
||||
{
|
||||
auto indices = ReadIndices(primitive["indices"].get<int>());
|
||||
|
||||
part->SetIndices(indices.size());
|
||||
|
||||
for (unsigned i = 0; i < indices.size(); i += 3)
|
||||
{
|
||||
part->SetIndex(i + 0, indices[i + 0]);
|
||||
part->SetIndex(i + 1, indices[i + 2]);
|
||||
part->SetIndex(i + 2, indices[i + 1]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
size_t vertices = part->GetVertexCount();
|
||||
|
||||
part->SetIndices(vertices);
|
||||
|
||||
for (unsigned i = 0; i < vertices; i += 3)
|
||||
{
|
||||
part->SetIndex(i + 0, i + 0);
|
||||
part->SetIndex(i + 1, i + 2);
|
||||
part->SetIndex(i + 2, i + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (mesh->GetPartCount() > 0)
|
||||
m_model->AddMesh(name, std::move(mesh));
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<glm::vec3> GLTFLoader::ReadPositions(int index)
|
||||
{
|
||||
const auto& accessor = m_accessors[index];
|
||||
|
||||
std::vector<glm::vec3> positions(accessor.count);
|
||||
|
||||
const auto& bufferView = m_bufferViews[accessor.bufferView];
|
||||
|
||||
const auto& buffer = m_buffers[bufferView.buffer];
|
||||
|
||||
auto data = reinterpret_cast<const glm::vec3*>(buffer.data() + bufferView.offset);
|
||||
|
||||
for (size_t i = 0; i < accessor.count; i++)
|
||||
positions[i] = data[i];
|
||||
|
||||
return positions;
|
||||
}
|
||||
|
||||
std::vector<glm::vec3> GLTFLoader::ReadNormals(int index)
|
||||
{
|
||||
const auto& accessor = m_accessors[index];
|
||||
|
||||
std::vector<glm::vec3> normals(accessor.count);
|
||||
|
||||
const auto& bufferView = m_bufferViews[accessor.bufferView];
|
||||
|
||||
const auto& buffer = m_buffers[bufferView.buffer];
|
||||
|
||||
auto data = reinterpret_cast<const glm::vec3*>(buffer.data() + bufferView.offset);
|
||||
|
||||
for (size_t i = 0; i < accessor.count; i++)
|
||||
normals[i] = data[i];
|
||||
|
||||
return normals;
|
||||
}
|
||||
|
||||
std::vector<glm::vec2> GLTFLoader::ReadUVs(int index)
|
||||
{
|
||||
const auto& accessor = m_accessors[index];
|
||||
|
||||
std::vector<glm::vec2> uvs(accessor.count);
|
||||
|
||||
const auto& bufferView = m_bufferViews[accessor.bufferView];
|
||||
|
||||
const auto& buffer = m_buffers[bufferView.buffer];
|
||||
|
||||
if (accessor.componentType == 5126)
|
||||
{
|
||||
auto data = reinterpret_cast<const glm::vec2*>(buffer.data() + bufferView.offset);
|
||||
|
||||
for (size_t i = 0; i < accessor.count; i++)
|
||||
uvs[i] = data[i];
|
||||
}
|
||||
else
|
||||
{
|
||||
GetLogger()->Error("Invalid UV type: %d\n", accessor.componentType);
|
||||
}
|
||||
|
||||
return uvs;
|
||||
}
|
||||
|
||||
std::vector<glm::u8vec4> GLTFLoader::ReadColors(int index)
|
||||
{
|
||||
const auto& accessor = m_accessors[index];
|
||||
|
||||
std::vector<glm::u8vec4> colors(accessor.count);
|
||||
|
||||
const auto& bufferView = m_bufferViews[accessor.bufferView];
|
||||
|
||||
const auto& buffer = m_buffers[bufferView.buffer];
|
||||
|
||||
if (accessor.componentType == 5121)
|
||||
{
|
||||
auto data = reinterpret_cast<const glm::u8vec4*>(buffer.data() + bufferView.offset);
|
||||
|
||||
for (size_t i = 0; i < accessor.count; i++)
|
||||
colors[i] = data[i];
|
||||
}
|
||||
else if (accessor.componentType == 5123)
|
||||
{
|
||||
auto data = reinterpret_cast<const glm::u16vec4*>(buffer.data() + bufferView.offset);
|
||||
|
||||
for (size_t i = 0; i < accessor.count; i++)
|
||||
colors[i] = glm::u8vec4(data[i] / glm::u16vec4(256));
|
||||
}
|
||||
else if (accessor.componentType == 5126)
|
||||
{
|
||||
auto data = reinterpret_cast<const glm::vec4*>(buffer.data() + bufferView.offset);
|
||||
|
||||
for (size_t i = 0; i < accessor.count; i++)
|
||||
colors[i] = glm::u8vec4(data[i] * 255.0f);
|
||||
}
|
||||
else
|
||||
{
|
||||
GetLogger()->Error("Invalid color type: %d\n", accessor.componentType);
|
||||
}
|
||||
|
||||
// Fix for bug in Blender where it exports vertex colors in sRGB instead of linear space
|
||||
for (size_t i = 0; i < colors.size(); i++)
|
||||
{
|
||||
auto color = Gfx::IntColorToColor(Gfx::IntColor(colors[i]));
|
||||
|
||||
color = Gfx::ToLinear(color);
|
||||
|
||||
colors[i] = Gfx::ColorToIntColor(color);
|
||||
}
|
||||
|
||||
return colors;
|
||||
}
|
||||
|
||||
std::vector<unsigned> GLTFLoader::ReadIndices(int index)
|
||||
{
|
||||
const auto& accessor = m_accessors[index];
|
||||
|
||||
std::vector<unsigned> indices(accessor.count);
|
||||
|
||||
const auto& bufferView = m_bufferViews[accessor.bufferView];
|
||||
|
||||
const auto& buffer = m_buffers[bufferView.buffer];
|
||||
|
||||
// Unsigned byte components
|
||||
if (accessor.componentType == 5121)
|
||||
{
|
||||
auto data = reinterpret_cast<const uint8_t*>(buffer.data() + bufferView.offset);
|
||||
|
||||
for (size_t i = 0; i < accessor.count; i++)
|
||||
indices[i] = data[i];
|
||||
}
|
||||
// Unsigned short components
|
||||
else if (accessor.componentType == 5123)
|
||||
{
|
||||
auto data = reinterpret_cast<const uint16_t*>(buffer.data() + bufferView.offset);
|
||||
|
||||
for (size_t i = 0; i < accessor.count; i++)
|
||||
indices[i] = data[i];
|
||||
}
|
||||
// Unsigned int components
|
||||
else if (accessor.componentType == 5125)
|
||||
{
|
||||
auto data = reinterpret_cast<const uint32_t*>(buffer.data() + bufferView.offset);
|
||||
|
||||
for (size_t i = 0; i < accessor.count; i++)
|
||||
indices[i] = data[i];
|
||||
}
|
||||
|
||||
return indices;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,36 +0,0 @@
|
|||
/*
|
||||
* This file is part of the Colobot: Gold Edition source code
|
||||
* Copyright (C) 2001-2022, Daniel Roux, EPSITEC SA & TerranovaTeam
|
||||
* http://epsitec.ch; http://colobot.info; http://github.com/colobot
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see http://gnu.org/licenses
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "graphics/model/model.h"
|
||||
|
||||
#include <filesystem>
|
||||
#include <istream>
|
||||
|
||||
/**
|
||||
* \namespace ModelInput
|
||||
* \brief Namespace with functions to read model files
|
||||
*/
|
||||
namespace Gfx::ModelIO
|
||||
{
|
||||
|
||||
std::unique_ptr<CModel> ReadGLTFModel(const std::filesystem::path& path);
|
||||
|
||||
}
|
|
@ -1,461 +0,0 @@
|
|||
/*
|
||||
* This file is part of the Colobot: Gold Edition source code
|
||||
* Copyright (C) 2001-2023, Daniel Roux, EPSITEC SA & TerranovaTeam
|
||||
* http://epsitec.ch; http://colobot.info; http://github.com/colobot
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see http://gnu.org/licenses
|
||||
*/
|
||||
|
||||
#include "graphics/model/model_mesh.h"
|
||||
|
||||
#include <array>
|
||||
|
||||
namespace Gfx
|
||||
{
|
||||
|
||||
CVertexProxy::CVertexProxy(CModelPart* part, size_t index)
|
||||
: m_part(part), m_index(index)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
const glm::vec3& CVertexProxy::GetPosition() const
|
||||
{
|
||||
return m_part->m_positions.array[m_index];
|
||||
}
|
||||
|
||||
void CVertexProxy::SetPosition(const glm::vec3& position) const
|
||||
{
|
||||
m_part->m_positions.array[m_index] = position;
|
||||
}
|
||||
|
||||
const glm::u8vec4& CVertexProxy::GetColor() const
|
||||
{
|
||||
return m_part->m_colors.array[m_index];
|
||||
}
|
||||
|
||||
void CVertexProxy::SetColor(const glm::u8vec4& color) const
|
||||
{
|
||||
m_part->m_colors.array[m_index] = color;
|
||||
}
|
||||
|
||||
const glm::vec2& CVertexProxy::GetUV1() const
|
||||
{
|
||||
return m_part->m_uvs1.array[m_index];
|
||||
}
|
||||
|
||||
void CVertexProxy::SetUV1(const glm::vec2& uv) const
|
||||
{
|
||||
m_part->m_uvs1.array[m_index] = uv;
|
||||
}
|
||||
|
||||
const glm::vec2& CVertexProxy::GetUV2() const
|
||||
{
|
||||
return m_part->m_uvs2.array[m_index];
|
||||
}
|
||||
|
||||
void CVertexProxy::SetUV2(const glm::vec2& uv) const
|
||||
{
|
||||
m_part->m_uvs2.array[m_index] = uv;
|
||||
}
|
||||
|
||||
const glm::vec3& CVertexProxy::GetNormal() const
|
||||
{
|
||||
return m_part->m_normals.array[m_index];
|
||||
}
|
||||
|
||||
void CVertexProxy::SetNormal(const glm::vec3& normal) const
|
||||
{
|
||||
m_part->m_normals.array[m_index] = normal;
|
||||
}
|
||||
|
||||
const glm::vec4& CVertexProxy::GetTangent() const
|
||||
{
|
||||
return m_part->m_tangents.array[m_index];
|
||||
}
|
||||
|
||||
void CVertexProxy::SetTangent(const glm::vec4& tangent) const
|
||||
{
|
||||
m_part->m_tangents.array[m_index] = tangent;
|
||||
}
|
||||
|
||||
const glm::u8vec4& CVertexProxy::GetBoneIndices() const
|
||||
{
|
||||
return m_part->m_boneIndices.array[m_index];
|
||||
}
|
||||
|
||||
void CVertexProxy::SetBoneIndices(const glm::u8vec4& indices) const
|
||||
{
|
||||
m_part->m_boneIndices.array[m_index] = indices;
|
||||
}
|
||||
|
||||
const glm::vec4& CVertexProxy::GetBoneWeights() const
|
||||
{
|
||||
return m_part->m_boneWeights.array[m_index];
|
||||
}
|
||||
|
||||
void CVertexProxy::SetBoneWeights(const glm::vec4& weights) const
|
||||
{
|
||||
m_part->m_boneWeights.array[m_index] = weights;
|
||||
}
|
||||
|
||||
|
||||
CModelPart::CModelPart(const Material& material, size_t vertices, size_t indices)
|
||||
: m_material(material) {
|
||||
m_positions.array.resize(vertices);
|
||||
m_indices.array.resize(indices);
|
||||
}
|
||||
|
||||
const Material& CModelPart::GetMaterial() const
|
||||
{
|
||||
return m_material;
|
||||
}
|
||||
|
||||
void CModelPart::SetVertices(size_t count)
|
||||
{
|
||||
m_positions.array.resize(count);
|
||||
|
||||
if (m_colors.enabled) m_colors.array.resize(count);
|
||||
if (m_uvs1.enabled) m_uvs1.array.resize(count);
|
||||
if (m_uvs2.enabled) m_uvs2.array.resize(count);
|
||||
if (m_normals.enabled) m_normals.array.resize(count);
|
||||
if (m_tangents.enabled) m_tangents.array.resize(count);
|
||||
if (m_boneIndices.enabled) m_boneIndices.array.resize(count);
|
||||
if (m_boneWeights.enabled) m_boneWeights.array.resize(count);
|
||||
}
|
||||
|
||||
void CModelPart::SetIndices(size_t count)
|
||||
{
|
||||
m_indices.enabled = count > 0;
|
||||
m_indices.array.resize(count);
|
||||
}
|
||||
|
||||
bool CModelPart::Has(VertexAttribute array) const
|
||||
{
|
||||
switch (array)
|
||||
{
|
||||
case VertexAttribute::POSITION:
|
||||
return true;
|
||||
case VertexAttribute::COLOR:
|
||||
return m_colors.enabled;
|
||||
case VertexAttribute::UV1:
|
||||
return m_uvs1.enabled;
|
||||
case VertexAttribute::UV2:
|
||||
return m_uvs2.enabled;
|
||||
case VertexAttribute::NORMAL:
|
||||
return m_normals.enabled;
|
||||
case VertexAttribute::TANGENT:
|
||||
return m_tangents.enabled;
|
||||
case VertexAttribute::BONE_INDICES:
|
||||
return m_boneIndices.enabled;
|
||||
case VertexAttribute::BONE_WEIGHTS:
|
||||
return m_boneWeights.enabled;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void CModelPart::Add(VertexAttribute attribute)
|
||||
{
|
||||
switch (attribute)
|
||||
{
|
||||
case VertexAttribute::COLOR:
|
||||
m_colors.enabled = true;
|
||||
m_colors.array.resize(m_positions.array.size());
|
||||
break;
|
||||
case VertexAttribute::UV1:
|
||||
m_uvs1.enabled = true;
|
||||
m_uvs1.array.resize(m_positions.array.size());
|
||||
break;
|
||||
case VertexAttribute::UV2:
|
||||
m_uvs2.enabled = true;
|
||||
m_uvs2.array.resize(m_positions.array.size());
|
||||
break;
|
||||
case VertexAttribute::NORMAL:
|
||||
m_normals.enabled = true;
|
||||
m_normals.array.resize(m_positions.array.size());
|
||||
break;
|
||||
case VertexAttribute::TANGENT:
|
||||
m_tangents.enabled = true;
|
||||
m_tangents.array.resize(m_positions.array.size());
|
||||
break;
|
||||
case VertexAttribute::BONE_INDICES:
|
||||
m_boneIndices.enabled = true;
|
||||
m_boneIndices.array.resize(m_positions.array.size());
|
||||
break;
|
||||
case VertexAttribute::BONE_WEIGHTS:
|
||||
m_boneWeights.enabled = true;
|
||||
m_boneWeights.array.resize(m_positions.array.size());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void CModelPart::Remove(VertexAttribute attribute)
|
||||
{
|
||||
switch (attribute)
|
||||
{
|
||||
case VertexAttribute::COLOR:
|
||||
m_colors.enabled = false;
|
||||
m_colors.array.resize(0);
|
||||
return;
|
||||
case VertexAttribute::UV1:
|
||||
m_uvs1.enabled = false;
|
||||
m_uvs1.array.resize(0);
|
||||
return;
|
||||
case VertexAttribute::UV2:
|
||||
m_uvs2.enabled = false;
|
||||
m_uvs2.array.resize(0);
|
||||
return;
|
||||
case VertexAttribute::NORMAL:
|
||||
m_normals.enabled = false;
|
||||
m_normals.array.resize(0);
|
||||
return;
|
||||
case VertexAttribute::TANGENT:
|
||||
m_tangents.enabled = false;
|
||||
m_tangents.array.resize(0);
|
||||
return;
|
||||
case VertexAttribute::BONE_INDICES:
|
||||
m_boneIndices.enabled = false;
|
||||
m_boneIndices.array.resize(0);
|
||||
return;
|
||||
case VertexAttribute::BONE_WEIGHTS:
|
||||
m_boneWeights.enabled = false;
|
||||
m_boneWeights.array.resize(0);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
bool CModelPart::IsIndexed() const
|
||||
{
|
||||
return m_indices.enabled;
|
||||
}
|
||||
|
||||
size_t CModelPart::GetVertexCount() const
|
||||
{
|
||||
return m_positions.array.size();
|
||||
}
|
||||
|
||||
size_t CModelPart::GetIndexCount() const
|
||||
{
|
||||
return m_indices.array.size();
|
||||
}
|
||||
|
||||
const std::vector<unsigned int>& CModelPart::GetIndices() const
|
||||
{
|
||||
return m_indices.array;
|
||||
}
|
||||
|
||||
CVertexProxy CModelPart::GetVertex(size_t index)
|
||||
{
|
||||
return CVertexProxy(this, index);
|
||||
}
|
||||
|
||||
std::uint32_t CModelPart::GetIndex(size_t index)
|
||||
{
|
||||
return m_indices.array[index];
|
||||
}
|
||||
|
||||
void CModelPart::AddVertex(const Vertex3D& vertex)
|
||||
{
|
||||
m_positions.array.push_back(vertex.position);
|
||||
|
||||
if (m_colors.enabled) m_colors.array.push_back(vertex.color);
|
||||
if (m_uvs1.enabled) m_uvs1.array.push_back(vertex.uv);
|
||||
if (m_uvs2.enabled) m_uvs2.array.push_back(vertex.uv2);
|
||||
if (m_normals.enabled) m_normals.array.push_back(vertex.normal);
|
||||
if (m_tangents.enabled) m_tangents.array.push_back({ 1.0f, 0.0f, 0.0f, 1.0f });
|
||||
if (m_boneIndices.enabled) m_boneIndices.array.push_back({ 0, 0, 0, 0 });
|
||||
if (m_boneWeights.enabled) m_boneWeights.array.push_back({ 1.0f, 0.0f, 0.0f, 0.0f });
|
||||
}
|
||||
|
||||
void CModelPart::AddIndex(unsigned int index)
|
||||
{
|
||||
if (m_indices.enabled) m_indices.array.push_back(index);
|
||||
}
|
||||
|
||||
void CModelPart::SetIndex(size_t index, unsigned int value)
|
||||
{
|
||||
m_indices.array[index] = value;
|
||||
}
|
||||
|
||||
void CModelPart::GetTriangles(std::vector<Gfx::ModelTriangle>& triangles)
|
||||
{
|
||||
size_t n = IsIndexed()
|
||||
? GetIndexCount()
|
||||
: GetVertexCount();
|
||||
|
||||
for (size_t i = 0; i < n - 2; i += 3)
|
||||
{
|
||||
std::array<Gfx::Vertex3D, 3> verts;
|
||||
|
||||
for (size_t j = 0; j < 3; j++)
|
||||
{
|
||||
size_t index = IsIndexed()
|
||||
? GetIndex(i + j)
|
||||
: i + j;
|
||||
auto vertex = GetVertex(index);
|
||||
|
||||
verts[j].position = vertex.GetPosition();
|
||||
|
||||
if (Has(VertexAttribute::COLOR)) verts[j].color = vertex.GetColor();
|
||||
else verts[j].color = { 255, 255, 255, 255 };
|
||||
|
||||
if (Has(VertexAttribute::UV1)) verts[j].uv = vertex.GetUV1();
|
||||
else verts[j].uv = { 0, 0 };
|
||||
|
||||
if (Has(VertexAttribute::UV2)) verts[j].uv2 = vertex.GetUV2();
|
||||
else verts[j].uv2 = { 0, 0 };
|
||||
|
||||
if (Has(VertexAttribute::NORMAL)) verts[j].normal = vertex.GetNormal();
|
||||
else verts[j].normal = { 0, 0, 1 };
|
||||
}
|
||||
|
||||
triangles.push_back({ verts[0], verts[1], verts[2], GetMaterial() });
|
||||
}
|
||||
}
|
||||
|
||||
void CModelMesh::AddTriangle(const ModelTriangle& triangle)
|
||||
{
|
||||
for (auto& part : m_parts)
|
||||
{
|
||||
if (part->GetMaterial() == triangle.material)
|
||||
{
|
||||
part->AddVertex(triangle.p1);
|
||||
part->AddVertex(triangle.p2);
|
||||
part->AddVertex(triangle.p3);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
auto part = std::make_unique<CModelPart>(triangle.material, 0, 0);
|
||||
|
||||
part->Add(VertexAttribute::COLOR);
|
||||
part->Add(VertexAttribute::UV1);
|
||||
part->Add(VertexAttribute::UV2);
|
||||
part->Add(VertexAttribute::NORMAL);
|
||||
|
||||
part->AddVertex(triangle.p1);
|
||||
part->AddVertex(triangle.p2);
|
||||
part->AddVertex(triangle.p3);
|
||||
|
||||
m_parts.push_back(std::move(part));
|
||||
}
|
||||
|
||||
void CModelMesh::AddTriangle(const Triangle& triangle, const Material& material)
|
||||
{
|
||||
for (auto& part : m_parts)
|
||||
{
|
||||
if (part->GetMaterial() == material)
|
||||
{
|
||||
part->AddVertex(triangle.p1);
|
||||
part->AddVertex(triangle.p2);
|
||||
part->AddVertex(triangle.p3);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
auto part = std::make_unique<CModelPart>(material, 0, 0);
|
||||
|
||||
part->Add(VertexAttribute::COLOR);
|
||||
part->Add(VertexAttribute::UV1);
|
||||
part->Add(VertexAttribute::UV2);
|
||||
part->Add(VertexAttribute::NORMAL);
|
||||
|
||||
part->AddVertex(triangle.p1);
|
||||
part->AddVertex(triangle.p2);
|
||||
part->AddVertex(triangle.p3);
|
||||
|
||||
m_parts.push_back(std::move(part));
|
||||
}
|
||||
|
||||
size_t CModelMesh::GetPartCount() const
|
||||
{
|
||||
return m_parts.size();
|
||||
}
|
||||
|
||||
CModelPart* CModelMesh::GetPart(size_t index) const
|
||||
{
|
||||
return m_parts[index].get();
|
||||
}
|
||||
|
||||
CModelPart* CModelMesh::AddPart(const Material& material)
|
||||
{
|
||||
for (auto& part : m_parts)
|
||||
{
|
||||
if (part->GetMaterial() == material)
|
||||
{
|
||||
return part.get();
|
||||
}
|
||||
}
|
||||
|
||||
auto part = std::make_unique<CModelPart>(material, 0, 0);
|
||||
|
||||
m_parts.push_back(std::move(part));
|
||||
|
||||
return m_parts.back().get();
|
||||
}
|
||||
|
||||
const glm::vec3& CModelMesh::GetPosition() const
|
||||
{
|
||||
return m_position;
|
||||
}
|
||||
|
||||
void CModelMesh::SetPosition(const glm::vec3& position)
|
||||
{
|
||||
m_position = position;
|
||||
}
|
||||
|
||||
const glm::vec3& CModelMesh::GetRotation() const
|
||||
{
|
||||
return m_rotation;
|
||||
}
|
||||
|
||||
void CModelMesh::SetRotation(const glm::vec3& rotation)
|
||||
{
|
||||
m_rotation = rotation;
|
||||
}
|
||||
|
||||
const glm::vec3& CModelMesh::GetScale() const
|
||||
{
|
||||
return m_scale;
|
||||
}
|
||||
|
||||
void CModelMesh::SetScale(const glm::vec3& scale)
|
||||
{
|
||||
m_scale = scale;
|
||||
}
|
||||
|
||||
const std::string& CModelMesh::GetParent() const
|
||||
{
|
||||
return m_parent;
|
||||
}
|
||||
|
||||
void CModelMesh::SetParent(const std::string& parent)
|
||||
{
|
||||
m_parent = parent;
|
||||
}
|
||||
|
||||
std::vector<ModelTriangle> CModelMesh::GetTriangles() const
|
||||
{
|
||||
std::vector<ModelTriangle> triangles;
|
||||
|
||||
for (const auto& part : m_parts)
|
||||
{
|
||||
part->GetTriangles(triangles);
|
||||
}
|
||||
|
||||
return triangles;
|
||||
}
|
||||
|
||||
} // namespace Gfx
|
|
@ -1,236 +0,0 @@
|
|||
/*
|
||||
* This file is part of the Colobot: Gold Edition source code
|
||||
* Copyright (C) 2001-2023, Daniel Roux, EPSITEC SA & TerranovaTeam
|
||||
* http://epsitec.ch; http://colobot.info; http://github.com/colobot
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see http://gnu.org/licenses
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "graphics/model/model_triangle.h"
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
namespace Gfx
|
||||
{
|
||||
|
||||
/**
|
||||
* \enum VertexAttribute
|
||||
* \brief An enum for vertex attributes
|
||||
*/
|
||||
enum class VertexAttribute
|
||||
{
|
||||
POSITION,
|
||||
COLOR,
|
||||
UV1,
|
||||
UV2,
|
||||
NORMAL,
|
||||
TANGENT,
|
||||
BONE_INDICES,
|
||||
BONE_WEIGHTS,
|
||||
};
|
||||
|
||||
class CModelPart;
|
||||
|
||||
|
||||
/**
|
||||
* \class CVertexProxy
|
||||
* \brief Proxy object for manipulating vertex data
|
||||
*/
|
||||
class CVertexProxy
|
||||
{
|
||||
CModelPart* m_part;
|
||||
size_t m_index;
|
||||
|
||||
public:
|
||||
CVertexProxy(CModelPart* part, size_t index);
|
||||
|
||||
//! Returns vertex position
|
||||
const glm::vec3& GetPosition() const;
|
||||
//! Sets vertex position
|
||||
void SetPosition(const glm::vec3& position) const;
|
||||
|
||||
//! Returns vertex color
|
||||
const glm::u8vec4& GetColor() const;
|
||||
//! Sets vertex color
|
||||
void SetColor(const glm::u8vec4& color) const;
|
||||
|
||||
//! Returns 1st UV
|
||||
const glm::vec2& GetUV1() const;
|
||||
//! Sets 1st UV
|
||||
void SetUV1(const glm::vec2& uv) const;
|
||||
|
||||
//! Returns 2nd UV
|
||||
const glm::vec2& GetUV2() const;
|
||||
//! Sets 2nd UV
|
||||
void SetUV2(const glm::vec2& uv) const;
|
||||
|
||||
//! Returns normal
|
||||
const glm::vec3& GetNormal() const;
|
||||
//! Sets normal
|
||||
void SetNormal(const glm::vec3& normal) const;
|
||||
|
||||
//! Returns tangent
|
||||
const glm::vec4& GetTangent() const;
|
||||
//! Sets tangent
|
||||
void SetTangent(const glm::vec4& tangent) const;
|
||||
|
||||
//! Returns bone indices
|
||||
const glm::u8vec4& GetBoneIndices() const;
|
||||
//! Sets bone indices
|
||||
void SetBoneIndices(const glm::u8vec4& indices) const;
|
||||
|
||||
//! Returns bone weights
|
||||
const glm::vec4& GetBoneWeights() const;
|
||||
//! Sets bone weights
|
||||
void SetBoneWeights(const glm::vec4& weights) const;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct VertexAttributeArray
|
||||
{
|
||||
bool enabled = false;
|
||||
std::vector<T> array = {};
|
||||
};
|
||||
|
||||
/**
|
||||
* \class CModelPart
|
||||
* \brief Part of mesh with a common material
|
||||
*/
|
||||
class CModelPart
|
||||
{
|
||||
public:
|
||||
//! Creates new part for given material
|
||||
CModelPart(const Material& material, size_t vertices = 0, size_t indices = 0);
|
||||
|
||||
//! Returns this part's material
|
||||
const Material& GetMaterial() const;
|
||||
|
||||
//! Sets the number of vertices
|
||||
void SetVertices(size_t count);
|
||||
//! Sets the number of indices
|
||||
void SetIndices(size_t count);
|
||||
|
||||
//! Returns whether this mesh part contains specific vertex attribute
|
||||
bool Has(VertexAttribute attribute) const;
|
||||
//! Adds vertex attribute to this mesh part
|
||||
void Add(VertexAttribute attribute);
|
||||
//! Removes vertex attribute from this mesh part
|
||||
void Remove(VertexAttribute attribute);
|
||||
|
||||
//! Returns true if this part is indexed
|
||||
bool IsIndexed() const;
|
||||
//! Returns the number of vertices in this part
|
||||
size_t GetVertexCount() const;
|
||||
//! Returns the number of indices in this part
|
||||
size_t GetIndexCount() const;
|
||||
//! Returns the indices in this part
|
||||
const std::vector<unsigned int>& GetIndices() const;
|
||||
|
||||
//! Returns vertex proxy object for manipulating vertex data
|
||||
CVertexProxy GetVertex(size_t index);
|
||||
//! Returns vertex index
|
||||
std::uint32_t GetIndex(size_t index);
|
||||
|
||||
//! Adds a vertex
|
||||
void AddVertex(const Vertex3D& vertex);
|
||||
//! Adds an index
|
||||
void AddIndex(unsigned int index);
|
||||
|
||||
//! Set index
|
||||
void SetIndex(size_t index, unsigned int value);
|
||||
|
||||
//! Fills the array with converted model triangles
|
||||
void GetTriangles(std::vector<Gfx::ModelTriangle>& triangles);
|
||||
|
||||
friend class CVertexProxy;
|
||||
|
||||
private:
|
||||
//! Material
|
||||
Material m_material;
|
||||
|
||||
//! Positions
|
||||
VertexAttributeArray<glm::vec3> m_positions;
|
||||
//! Colors
|
||||
VertexAttributeArray<glm::u8vec4> m_colors;
|
||||
//! UVs 1
|
||||
VertexAttributeArray<glm::vec2> m_uvs1;
|
||||
//! UVs 2
|
||||
VertexAttributeArray<glm::vec2> m_uvs2;
|
||||
//! Normals
|
||||
VertexAttributeArray<glm::vec3> m_normals;
|
||||
//! Tangents
|
||||
VertexAttributeArray<glm::vec4> m_tangents;
|
||||
//! Bone indices
|
||||
VertexAttributeArray<glm::u8vec4> m_boneIndices;
|
||||
//! Bone weights
|
||||
VertexAttributeArray<glm::vec4> m_boneWeights;
|
||||
|
||||
//! Indices
|
||||
VertexAttributeArray<std::uint32_t> m_indices;
|
||||
};
|
||||
|
||||
/**
|
||||
* \class CModelMesh
|
||||
* \brief Mesh data saved in model file
|
||||
*/
|
||||
class CModelMesh
|
||||
{
|
||||
public:
|
||||
//! Adds a new triangle
|
||||
void AddTriangle(const ModelTriangle& triangle);
|
||||
//! Adds a new triangle
|
||||
void AddTriangle(const Triangle& triangle, const Material& material);
|
||||
|
||||
//! Returns the number of parts
|
||||
size_t GetPartCount() const;
|
||||
//! Returns a part with given index
|
||||
CModelPart* GetPart(size_t index) const;
|
||||
//! Adds a new part with given material or returns an existing one
|
||||
CModelPart* AddPart(const Material& material);
|
||||
|
||||
//! Returns the mesh position
|
||||
const glm::vec3& GetPosition() const;
|
||||
//! Sets the mesh rotation
|
||||
void SetPosition(const glm::vec3& position);
|
||||
|
||||
//! Returns the mesh rotation
|
||||
const glm::vec3& GetRotation() const;
|
||||
//! Sets the mesh rotation
|
||||
void SetRotation(const glm::vec3& rotation);
|
||||
|
||||
//! Returns the mesh scale
|
||||
const glm::vec3& GetScale() const;
|
||||
//! Sets the mesh scale
|
||||
void SetScale(const glm::vec3& scale);
|
||||
|
||||
//! Returns the name of parent mesh
|
||||
const std::string& GetParent() const;
|
||||
//! Sets the name of parent mesh
|
||||
void SetParent(const std::string& parent);
|
||||
|
||||
//! Returns all model triangles of this mesh
|
||||
std::vector<ModelTriangle> GetTriangles() const;
|
||||
|
||||
private:
|
||||
std::vector<std::unique_ptr<CModelPart>> m_parts;
|
||||
glm::vec3 m_position = { 0, 0, 0 };
|
||||
glm::vec3 m_rotation = { 0, 0, 0 };
|
||||
glm::vec3 m_scale = { 1, 1, 1 };
|
||||
std::string m_parent;
|
||||
};
|
||||
|
||||
} // namespace Gfx
|
|
@ -1,378 +0,0 @@
|
|||
/*
|
||||
* This file is part of the Colobot: Gold Edition source code
|
||||
* Copyright (C) 2001-2022, Daniel Roux, EPSITEC SA & TerranovaTeam
|
||||
* http://epsitec.ch; http://colobot.info; http://github.com/colobot
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see http://gnu.org/licenses
|
||||
*/
|
||||
|
||||
#include "graphics/model/model_mod.h"
|
||||
|
||||
#include "common/ioutils.h"
|
||||
#include "common/stringutils.h"
|
||||
#include "common/resources/inputstream.h"
|
||||
|
||||
#include "graphics/model/model_io_exception.h"
|
||||
#include "graphics/model/model_io_structs.h"
|
||||
|
||||
#include <array>
|
||||
#include <iostream>
|
||||
|
||||
using namespace IOUtils;
|
||||
|
||||
namespace Gfx::ModelIO
|
||||
{
|
||||
|
||||
std::vector<ModelTriangle> ReadOldModelV1(std::istream& stream, int totalTriangles);
|
||||
std::vector<ModelTriangle> ReadOldModelV2(std::istream& stream, int totalTriangles);
|
||||
std::vector<ModelTriangle> ReadOldModelV3(std::istream& stream, int totalTriangles);
|
||||
|
||||
Vertex3D ReadBinaryVertex(std::istream& stream);
|
||||
Vertex3D ReadBinaryVertexTex2(std::istream& stream);
|
||||
LegacyMaterial ReadBinaryMaterial(std::istream& stream);
|
||||
|
||||
void ConvertOldTex1Name(ModelTriangle& triangle, const char* tex1Name);
|
||||
void ConvertFromOldRenderState(ModelTriangle& triangle, int state);
|
||||
ModelLODLevel MinMaxToLodLevel(float min, float max);
|
||||
|
||||
std::unique_ptr<CModel> ReadOldModel(const std::filesystem::path& path)
|
||||
{
|
||||
CInputStream stream(path);
|
||||
|
||||
OldModelHeader header;
|
||||
|
||||
try
|
||||
{
|
||||
header.revision = ReadBinary<4, int>(stream);
|
||||
header.version = ReadBinary<4, int>(stream);
|
||||
header.totalTriangles = ReadBinary<4, int>(stream);
|
||||
for (int i = 0; i < 10; ++i)
|
||||
header.reserved[i] = ReadBinary<4, int>(stream);
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
throw CModelIOException(std::string("Error reading model file header: ") + e.what());
|
||||
}
|
||||
|
||||
std::vector<ModelTriangle> triangles;
|
||||
|
||||
try
|
||||
{
|
||||
if (header.revision == 1 && header.version == 0)
|
||||
{
|
||||
triangles = ReadOldModelV1(stream, header.totalTriangles);
|
||||
}
|
||||
else if (header.revision == 1 && header.version == 1)
|
||||
{
|
||||
triangles = ReadOldModelV2(stream, header.totalTriangles);
|
||||
}
|
||||
else
|
||||
{
|
||||
triangles = ReadOldModelV3(stream, header.totalTriangles);
|
||||
}
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
throw CModelIOException(std::string("Error reading model triangles: ") + e.what());
|
||||
}
|
||||
|
||||
auto mesh = std::make_unique<CModelMesh>();
|
||||
|
||||
for (const auto& triangle : triangles)
|
||||
mesh->AddTriangle(triangle);
|
||||
|
||||
auto model = std::make_unique<CModel>();
|
||||
|
||||
model->AddMesh("main", std::move(mesh));
|
||||
|
||||
return model;
|
||||
}
|
||||
|
||||
std::vector<ModelTriangle> ReadOldModelV1(std::istream& stream, int totalTriangles)
|
||||
{
|
||||
std::vector<ModelTriangle> triangles;
|
||||
|
||||
for (int i = 0; i < totalTriangles; ++i)
|
||||
{
|
||||
OldModelTriangleV1 t;
|
||||
t.used = ReadBinary<1, char>(stream);
|
||||
t.selected = ReadBinary<1, char>(stream);
|
||||
|
||||
/* padding */ ReadBinary<2, unsigned int>(stream);
|
||||
|
||||
t.p1 = ReadBinaryVertex(stream);
|
||||
t.p2 = ReadBinaryVertex(stream);
|
||||
t.p3 = ReadBinaryVertex(stream);
|
||||
|
||||
auto material = ReadBinaryMaterial(stream);
|
||||
stream.read(t.texName, 20);
|
||||
t.min = ReadBinaryFloat(stream);
|
||||
t.max = ReadBinaryFloat(stream);
|
||||
|
||||
ModelLODLevel lodLevel = MinMaxToLodLevel(t.min, t.max);
|
||||
if (lodLevel == ModelLODLevel::Low ||
|
||||
lodLevel == ModelLODLevel::Medium)
|
||||
continue;
|
||||
|
||||
ModelTriangle triangle;
|
||||
triangle.p1 = t.p1;
|
||||
triangle.p2 = t.p2;
|
||||
triangle.p3 = t.p3;
|
||||
|
||||
auto diffuse = Gfx::ColorToIntColor(material.diffuse);
|
||||
glm::u8vec4 color = { diffuse.r, diffuse.g, diffuse.b, 255 };
|
||||
|
||||
triangle.p1.color = color;
|
||||
triangle.p2.color = color;
|
||||
triangle.p3.color = color;
|
||||
|
||||
ConvertOldTex1Name(triangle, t.texName);
|
||||
|
||||
triangles.push_back(triangle);
|
||||
}
|
||||
|
||||
return triangles;
|
||||
}
|
||||
|
||||
std::vector<ModelTriangle> ReadOldModelV2(std::istream& stream, int totalTriangles)
|
||||
{
|
||||
std::vector<ModelTriangle> triangles;
|
||||
|
||||
for (int i = 0; i < totalTriangles; ++i)
|
||||
{
|
||||
OldModelTriangleV2 t;
|
||||
t.used = ReadBinary<1, char>(stream);
|
||||
t.selected = ReadBinary<1, char>(stream);
|
||||
|
||||
/* padding */ ReadBinary<2, unsigned int>(stream);
|
||||
|
||||
t.p1 = ReadBinaryVertex(stream);
|
||||
t.p2 = ReadBinaryVertex(stream);
|
||||
t.p3 = ReadBinaryVertex(stream);
|
||||
|
||||
auto material = ReadBinaryMaterial(stream);
|
||||
stream.read(t.texName, 20);
|
||||
t.min = ReadBinaryFloat(stream);
|
||||
t.max = ReadBinaryFloat(stream);
|
||||
t.state = ReadBinary<4, long>(stream);
|
||||
|
||||
t.reserved1 = ReadBinary<2, short>(stream);
|
||||
t.reserved2 = ReadBinary<2, short>(stream);
|
||||
t.reserved3 = ReadBinary<2, short>(stream);
|
||||
t.reserved4 = ReadBinary<2, short>(stream);
|
||||
|
||||
ModelLODLevel lodLevel = MinMaxToLodLevel(t.min, t.max);
|
||||
if (lodLevel == ModelLODLevel::Low ||
|
||||
lodLevel == ModelLODLevel::Medium)
|
||||
continue;
|
||||
|
||||
ModelTriangle triangle;
|
||||
triangle.p1 = t.p1;
|
||||
triangle.p2 = t.p2;
|
||||
triangle.p3 = t.p3;
|
||||
|
||||
auto diffuse = Gfx::ColorToIntColor(material.diffuse);
|
||||
glm::u8vec4 color = { diffuse.r, diffuse.g, diffuse.b, 255 };
|
||||
|
||||
triangle.p1.color = color;
|
||||
triangle.p2.color = color;
|
||||
triangle.p3.color = color;
|
||||
|
||||
ConvertOldTex1Name(triangle, t.texName);
|
||||
|
||||
ConvertFromOldRenderState(triangle, t.state);
|
||||
|
||||
triangles.push_back(triangle);
|
||||
}
|
||||
|
||||
return triangles;
|
||||
}
|
||||
|
||||
std::vector<ModelTriangle> ReadOldModelV3(std::istream& stream, int totalTriangles)
|
||||
{
|
||||
std::vector<ModelTriangle> triangles;
|
||||
|
||||
for (int i = 0; i < totalTriangles; ++i)
|
||||
{
|
||||
OldModelTriangleV3 t;
|
||||
t.used = ReadBinary<1, char>(stream);
|
||||
t.selected = ReadBinary<1, char>(stream);
|
||||
|
||||
/* padding */ ReadBinary<2, unsigned int>(stream);
|
||||
|
||||
t.p1 = ReadBinaryVertexTex2(stream);
|
||||
t.p2 = ReadBinaryVertexTex2(stream);
|
||||
t.p3 = ReadBinaryVertexTex2(stream);
|
||||
|
||||
auto material = ReadBinaryMaterial(stream);
|
||||
stream.read(t.texName, 20);
|
||||
t.min = ReadBinaryFloat(stream);
|
||||
t.max = ReadBinaryFloat(stream);
|
||||
t.state = ReadBinary<4, long>(stream);
|
||||
t.texNum2 = ReadBinary<2, short>(stream);
|
||||
|
||||
t.reserved2 = ReadBinary<2, short>(stream);
|
||||
t.reserved3 = ReadBinary<2, short>(stream);
|
||||
t.reserved4 = ReadBinary<2, short>(stream);
|
||||
|
||||
ModelLODLevel lodLevel = MinMaxToLodLevel(t.min, t.max);
|
||||
if (lodLevel == ModelLODLevel::Low ||
|
||||
lodLevel == ModelLODLevel::Medium)
|
||||
continue;
|
||||
|
||||
ModelTriangle triangle;
|
||||
triangle.p1 = t.p1;
|
||||
triangle.p2 = t.p2;
|
||||
triangle.p3 = t.p3;
|
||||
|
||||
auto diffuse = Gfx::ColorToIntColor(material.diffuse);
|
||||
glm::u8vec4 color = { diffuse.r, diffuse.g, diffuse.b, 255 };
|
||||
|
||||
triangle.p1.color = color;
|
||||
triangle.p2.color = color;
|
||||
triangle.p3.color = color;
|
||||
|
||||
ConvertOldTex1Name(triangle, t.texName);
|
||||
|
||||
ConvertFromOldRenderState(triangle, t.state);
|
||||
triangle.material.variableDetail = t.texNum2 == 1;
|
||||
|
||||
if (!triangle.material.variableDetail && t.texNum2 != 0)
|
||||
{
|
||||
std::array<char, 20> tex2Name = {0};
|
||||
std::snprintf(tex2Name.data(), tex2Name.size(), "dirty%.2d.png", t.texNum2);
|
||||
triangle.material.detailTexture = tex2Name.data();
|
||||
}
|
||||
|
||||
triangles.push_back(triangle);
|
||||
}
|
||||
|
||||
return triangles;
|
||||
}
|
||||
|
||||
ModelLODLevel MinMaxToLodLevel(float min, float max)
|
||||
{
|
||||
if (min == 0.0f && max == 100.0f)
|
||||
return ModelLODLevel::High;
|
||||
else if (min == 100.0f && max == 200.0f)
|
||||
return ModelLODLevel::Medium;
|
||||
else if (min == 200.0f && max == 1000000.0f)
|
||||
return ModelLODLevel::Low;
|
||||
else if (min == 0.0f && max == 1000000.0f)
|
||||
return ModelLODLevel::Constant;
|
||||
|
||||
return ModelLODLevel::Constant;
|
||||
}
|
||||
|
||||
void ConvertOldTex1Name(ModelTriangle& triangle, const char* tex1Name)
|
||||
{
|
||||
triangle.material.albedoTexture = tex1Name;
|
||||
triangle.material.albedoTexture = StrUtils::Replace(
|
||||
triangle.material.albedoTexture, "bmp", "png");
|
||||
triangle.material.albedoTexture = StrUtils::Replace(
|
||||
triangle.material.albedoTexture, "tga", "png");
|
||||
}
|
||||
|
||||
void ConvertFromOldRenderState(ModelTriangle& triangle, int state)
|
||||
{
|
||||
if (triangle.material.albedoTexture == "plant.png" || (state & static_cast<int>(ModelRenderState::Alpha)) != 0)
|
||||
{
|
||||
triangle.material.alphaMode = AlphaMode::MASK;
|
||||
triangle.material.alphaThreshold = 0.5f;
|
||||
}
|
||||
else
|
||||
triangle.material.alphaMode = AlphaMode::NONE;
|
||||
|
||||
if ((state & static_cast<int>(ModelRenderState::Part1)) != 0)
|
||||
triangle.material.tag = "tracker_right";
|
||||
else if ((state & static_cast<int>(ModelRenderState::Part2)) != 0)
|
||||
triangle.material.tag = "tracker_left";
|
||||
else if ((state & static_cast<int>(ModelRenderState::Part3)) != 0)
|
||||
triangle.material.tag = "energy";
|
||||
else
|
||||
triangle.material.tag = "";
|
||||
|
||||
bool doubleSided = (state & static_cast<int>(ModelRenderState::TwoFace)) != 0;
|
||||
triangle.material.cullFace = doubleSided ? CullFace::NONE : CullFace::BACK;
|
||||
}
|
||||
|
||||
Vertex3D ReadBinaryVertex(std::istream& stream)
|
||||
{
|
||||
Vertex3D vertex;
|
||||
|
||||
vertex.position.x = ReadBinaryFloat(stream);
|
||||
vertex.position.y = ReadBinaryFloat(stream);
|
||||
vertex.position.z = ReadBinaryFloat(stream);
|
||||
|
||||
vertex.normal.x = ReadBinaryFloat(stream);
|
||||
vertex.normal.y = ReadBinaryFloat(stream);
|
||||
vertex.normal.z = ReadBinaryFloat(stream);
|
||||
|
||||
vertex.uv.x = ReadBinaryFloat(stream);
|
||||
vertex.uv.y = ReadBinaryFloat(stream);
|
||||
|
||||
return vertex;
|
||||
}
|
||||
|
||||
Vertex3D ReadBinaryVertexTex2(std::istream& stream)
|
||||
{
|
||||
Vertex3D vertex;
|
||||
|
||||
vertex.position.x = ReadBinaryFloat(stream);
|
||||
vertex.position.y = ReadBinaryFloat(stream);
|
||||
vertex.position.z = ReadBinaryFloat(stream);
|
||||
|
||||
vertex.normal.x = ReadBinaryFloat(stream);
|
||||
vertex.normal.y = ReadBinaryFloat(stream);
|
||||
vertex.normal.z = ReadBinaryFloat(stream);
|
||||
|
||||
vertex.uv.x = ReadBinaryFloat(stream);
|
||||
vertex.uv.y = ReadBinaryFloat(stream);
|
||||
|
||||
vertex.uv2.x = ReadBinaryFloat(stream);
|
||||
vertex.uv2.y = ReadBinaryFloat(stream);
|
||||
|
||||
return vertex;
|
||||
}
|
||||
|
||||
LegacyMaterial ReadBinaryMaterial(std::istream& stream)
|
||||
{
|
||||
LegacyMaterial material;
|
||||
|
||||
material.diffuse.r = ReadBinaryFloat(stream);
|
||||
material.diffuse.g = ReadBinaryFloat(stream);
|
||||
material.diffuse.b = ReadBinaryFloat(stream);
|
||||
material.diffuse.a = ReadBinaryFloat(stream);
|
||||
|
||||
material.ambient.r = ReadBinaryFloat(stream);
|
||||
material.ambient.g = ReadBinaryFloat(stream);
|
||||
material.ambient.b = ReadBinaryFloat(stream);
|
||||
material.ambient.a = ReadBinaryFloat(stream);
|
||||
|
||||
material.specular.r = ReadBinaryFloat(stream);
|
||||
material.specular.g = ReadBinaryFloat(stream);
|
||||
material.specular.b = ReadBinaryFloat(stream);
|
||||
material.specular.a = ReadBinaryFloat(stream);
|
||||
|
||||
/* emissive.r = */ ReadBinaryFloat(stream);
|
||||
/* emissive.g = */ ReadBinaryFloat(stream);
|
||||
/* emissive.b = */ ReadBinaryFloat(stream);
|
||||
/* emissive.a = */ ReadBinaryFloat(stream);
|
||||
|
||||
/* power = */ ReadBinaryFloat(stream);
|
||||
|
||||
return material;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,36 +0,0 @@
|
|||
/*
|
||||
* This file is part of the Colobot: Gold Edition source code
|
||||
* Copyright (C) 2001-2022, Daniel Roux, EPSITEC SA & TerranovaTeam
|
||||
* http://epsitec.ch; http://colobot.info; http://github.com/colobot
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see http://gnu.org/licenses
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "graphics/model/model.h"
|
||||
|
||||
#include <filesystem>
|
||||
#include <istream>
|
||||
|
||||
/**
|
||||
* \namespace ModelInput
|
||||
* \brief Namespace with functions to read model files
|
||||
*/
|
||||
namespace Gfx::ModelIO
|
||||
{
|
||||
|
||||
std::unique_ptr<CModel> ReadOldModel(const std::filesystem::path& path);
|
||||
|
||||
}
|
|
@ -1,429 +0,0 @@
|
|||
/*
|
||||
* This file is part of the Colobot: Gold Edition source code
|
||||
* Copyright (C) 2001-2022, Daniel Roux, EPSITEC SA & TerranovaTeam
|
||||
* http://epsitec.ch; http://colobot.info; http://github.com/colobot
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see http://gnu.org/licenses
|
||||
*/
|
||||
|
||||
#include "graphics/model/model_mod.h"
|
||||
|
||||
#include "common/ioutils.h"
|
||||
#include "common/stringutils.h"
|
||||
#include "common/resources/inputstream.h"
|
||||
|
||||
#include "graphics/model/model_io_exception.h"
|
||||
#include "graphics/model/model_io_structs.h"
|
||||
|
||||
using namespace IOUtils;
|
||||
|
||||
namespace Gfx::ModelIO
|
||||
{
|
||||
|
||||
void ReadTextModelV1AndV2(CModel& model, std::istream& stream);
|
||||
void ReadTextModelV3(CModel& model, std::istream& stream);
|
||||
ModelHeaderV3 ReadTextHeader(std::istream& stream);
|
||||
std::unique_ptr<CModelMesh> ReadTextMesh(std::istream& stream);
|
||||
|
||||
std::string ReadLineString(std::istream& stream, const std::string& expectedPrefix);
|
||||
void ReadValuePrefix(std::istream& stream, const std::string& expectedPrefix);
|
||||
Vertex3D ParseVertexTex2(const std::string& text);
|
||||
LegacyMaterial ParseMaterial(const std::string& text);
|
||||
glm::vec3 ParseVector(const std::string& text);
|
||||
ModelCrashSphere ParseCrashSphere(const std::string& text);
|
||||
ModelShadowSpot ParseShadowSpot(const std::string& text);
|
||||
Math::Sphere ParseCameraCollisionSphere(const std::string& text);
|
||||
AlphaMode ParseTransparentMode(const std::string& text);
|
||||
std::string ParseSpecialMark(const std::string& text);
|
||||
|
||||
void ConvertFromOldRenderState(ModelTriangle& triangle, int state);
|
||||
|
||||
std::unique_ptr<CModel> ReadTextModel(const std::filesystem::path& path)
|
||||
{
|
||||
CInputStream stream(path);
|
||||
|
||||
int version = 0;
|
||||
try
|
||||
{
|
||||
version = std::stoi(ReadLineString(stream, "version"));
|
||||
stream.seekg(std::ios_base::beg);
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
throw CModelIOException(std::string("Error reading version number: ") + e.what());
|
||||
}
|
||||
|
||||
auto model = std::make_unique<CModel>();
|
||||
|
||||
if (version == 1 || version == 2)
|
||||
ReadTextModelV1AndV2(*model, stream);
|
||||
else if (version == 3)
|
||||
ReadTextModelV3(*model, stream);
|
||||
else
|
||||
throw CModelIOException(std::string("Unexpected version number: ") + std::to_string(version));
|
||||
|
||||
return model;
|
||||
}
|
||||
|
||||
void ReadTextModelV1AndV2(CModel& model, std::istream& stream)
|
||||
{
|
||||
ModelHeaderV1AndV2 header;
|
||||
|
||||
try
|
||||
{
|
||||
header.version = std::stoi(ReadLineString(stream, "version"));
|
||||
header.totalTriangles = std::stoi(ReadLineString(stream, "total_triangles"));
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
throw CModelIOException(std::string("Error reading model header: ") + e.what());
|
||||
}
|
||||
|
||||
auto mesh = std::make_unique<CModelMesh>();
|
||||
|
||||
for (int i = 0; i < header.totalTriangles; ++i)
|
||||
{
|
||||
ModelTriangleV1AndV2 t;
|
||||
|
||||
std::string p1Text = ReadLineString(stream, "p1");
|
||||
t.p1 = ParseVertexTex2(p1Text);
|
||||
std::string p2Text = ReadLineString(stream, "p2");
|
||||
t.p2 = ParseVertexTex2(p2Text);
|
||||
std::string p3Text = ReadLineString(stream, "p3");
|
||||
t.p3 = ParseVertexTex2(p3Text);
|
||||
|
||||
std::string matText = ReadLineString(stream, "mat");
|
||||
auto material = ParseMaterial(matText);
|
||||
|
||||
auto diffuse = Gfx::ColorToIntColor(material.diffuse);
|
||||
glm::u8vec4 color = { diffuse.r, diffuse.g, diffuse.b, 255 };
|
||||
|
||||
t.p1.color = color;
|
||||
t.p2.color = color;
|
||||
t.p3.color = color;
|
||||
|
||||
t.tex1Name = ReadLineString(stream, "tex1");
|
||||
t.tex2Name = ReadLineString(stream, "tex2");
|
||||
std::string varTex2Ch = ReadLineString(stream, "var_tex2");
|
||||
t.variableTex2 = varTex2Ch == "Y";
|
||||
|
||||
if (header.version == 1)
|
||||
t.lodLevel = static_cast<ModelLODLevel>(std::stoi(ReadLineString(stream, "lod_level")));
|
||||
|
||||
t.state = std::stoi(ReadLineString(stream, "state"));
|
||||
|
||||
if (t.lodLevel == ModelLODLevel::Low ||
|
||||
t.lodLevel == ModelLODLevel::Medium)
|
||||
continue;
|
||||
|
||||
ModelTriangle triangle;
|
||||
triangle.p1 = t.p1;
|
||||
triangle.p2 = t.p2;
|
||||
triangle.p3 = t.p3;
|
||||
triangle.material.albedoTexture = t.tex1Name;
|
||||
triangle.material.detailTexture = t.tex2Name;
|
||||
triangle.material.variableDetail = t.variableTex2;
|
||||
ConvertFromOldRenderState(triangle, t.state);
|
||||
|
||||
mesh->AddTriangle(triangle);
|
||||
}
|
||||
|
||||
model.AddMesh("main", std::move(mesh));
|
||||
}
|
||||
|
||||
void ReadTextModelV3(CModel& model, std::istream& stream)
|
||||
{
|
||||
ModelHeaderV3 header;
|
||||
|
||||
try
|
||||
{
|
||||
header = ReadTextHeader(stream);
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
throw CModelIOException(std::string("Error reading model header: ") + e.what());
|
||||
}
|
||||
|
||||
for (int i = 0; i < header.totalCrashSpheres; ++i)
|
||||
{
|
||||
auto crashSphere = ParseCrashSphere(ReadLineString(stream, "crash_sphere"));
|
||||
model.AddCrashSphere(crashSphere);
|
||||
}
|
||||
|
||||
if (header.hasShadowSpot)
|
||||
{
|
||||
auto shadowSpot = ParseShadowSpot(ReadLineString(stream, "shadow_spot"));
|
||||
model.SetShadowSpot(shadowSpot);
|
||||
}
|
||||
|
||||
if (header.hasCameraCollisionSphere)
|
||||
{
|
||||
auto sphere = ParseCameraCollisionSphere(ReadLineString(stream, "camera_collision_sphere"));
|
||||
model.SetCameraCollisionSphere(sphere);
|
||||
}
|
||||
|
||||
for (int i = 0; i < header.totalMeshes; ++i)
|
||||
{
|
||||
std::string meshName = ReadLineString(stream, "mesh");
|
||||
auto mesh = ReadTextMesh(stream);
|
||||
model.AddMesh(meshName, std::move(mesh));
|
||||
}
|
||||
}
|
||||
|
||||
ModelHeaderV3 ReadTextHeader(std::istream& stream)
|
||||
{
|
||||
ModelHeaderV3 header;
|
||||
header.version = std::stoi(ReadLineString(stream, "version"));
|
||||
header.totalCrashSpheres = std::stoi(ReadLineString(stream, "total_crash_spheres"));
|
||||
header.hasShadowSpot = ReadLineString(stream, "has_shadow_spot") == std::string("Y");
|
||||
header.hasCameraCollisionSphere = ReadLineString(stream, "has_camera_collision_sphere") == std::string("Y");
|
||||
header.totalMeshes = std::stoi(ReadLineString(stream, "total_meshes"));
|
||||
return header;
|
||||
}
|
||||
|
||||
std::unique_ptr<CModelMesh> ReadTextMesh(std::istream& stream)
|
||||
{
|
||||
auto mesh = std::make_unique<CModelMesh>();
|
||||
|
||||
mesh->SetPosition(ParseVector(ReadLineString(stream, "position")));
|
||||
mesh->SetRotation(ParseVector(ReadLineString(stream, "rotation")));
|
||||
mesh->SetScale(ParseVector(ReadLineString(stream, "scale")));
|
||||
mesh->SetParent(ReadLineString(stream, "parent"));
|
||||
|
||||
int totalTriangles = std::stoi(ReadLineString(stream, "total_triangles"));
|
||||
|
||||
for (int i = 0; i < totalTriangles; ++i)
|
||||
{
|
||||
ModelTriangleV3 t;
|
||||
|
||||
std::string p1Text = ReadLineString(stream, "p1");
|
||||
t.p1 = ParseVertexTex2(p1Text);
|
||||
std::string p2Text = ReadLineString(stream, "p2");
|
||||
t.p2 = ParseVertexTex2(p2Text);
|
||||
std::string p3Text = ReadLineString(stream, "p3");
|
||||
t.p3 = ParseVertexTex2(p3Text);
|
||||
|
||||
std::string matText = ReadLineString(stream, "mat");
|
||||
LegacyMaterial mat = ParseMaterial(matText);
|
||||
|
||||
auto diffuse = Gfx::ColorToIntColor(mat.diffuse);
|
||||
glm::u8vec4 color = { diffuse.r, diffuse.g, diffuse.b, 255 };
|
||||
|
||||
t.p1.color = color;
|
||||
t.p2.color = color;
|
||||
t.p3.color = color;
|
||||
|
||||
t.material.albedoTexture = ReadLineString(stream, "tex1");
|
||||
t.material.detailTexture = ReadLineString(stream, "tex2");
|
||||
t.material.variableDetail = ReadLineString(stream, "var_tex2") == std::string("Y");
|
||||
|
||||
t.material.alphaMode = ParseTransparentMode(ReadLineString(stream, "trans_mode"));
|
||||
t.material.tag = ParseSpecialMark(ReadLineString(stream, "mark"));
|
||||
bool doubleSided = ReadLineString(stream, "dbl_side") == std::string("Y");
|
||||
t.material.cullFace = doubleSided ? CullFace::NONE : CullFace::BACK;
|
||||
|
||||
if (t.material.alphaMode != AlphaMode::NONE)
|
||||
t.material.alphaThreshold = 0.5f;
|
||||
|
||||
mesh->AddTriangle(t);
|
||||
}
|
||||
|
||||
return mesh;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
std::string ReadLineString(std::istream& stream, const std::string& expectedPrefix)
|
||||
{
|
||||
std::string line;
|
||||
while (true)
|
||||
{
|
||||
if (stream.eof())
|
||||
throw CModelIOException("Unexpected EOF");
|
||||
|
||||
std::getline(stream, line);
|
||||
StrUtils::TrimRight(line);
|
||||
if (!line.empty() && line[0] != '#')
|
||||
break;
|
||||
}
|
||||
|
||||
std::stringstream s;
|
||||
s.str(line);
|
||||
|
||||
std::string prefix;
|
||||
s >> prefix;
|
||||
if (prefix != expectedPrefix)
|
||||
throw CModelIOException(std::string("Unexpected prefix: '") + prefix + "'");
|
||||
|
||||
std::string value;
|
||||
std::getline(s, value);
|
||||
StrUtils::TrimLeft(value);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
void ReadValuePrefix(std::istream& stream, const std::string& expectedPrefix)
|
||||
{
|
||||
std::string prefix;
|
||||
stream >> prefix;
|
||||
if (prefix != expectedPrefix)
|
||||
throw CModelIOException(std::string("Unexpected prefix: '") + prefix + "', expected was: '" + expectedPrefix + "'");
|
||||
}
|
||||
|
||||
Vertex3D ParseVertexTex2(const std::string& text)
|
||||
{
|
||||
Vertex3D vertex;
|
||||
|
||||
std::stringstream stream;
|
||||
stream.str(text);
|
||||
|
||||
ReadValuePrefix(stream, "c");
|
||||
stream >> vertex.position.x >> vertex.position.y >> vertex.position.z;
|
||||
|
||||
ReadValuePrefix(stream, "n");
|
||||
stream >> vertex.normal.x >> vertex.normal.y >> vertex.normal.z;
|
||||
|
||||
ReadValuePrefix(stream, "t1");
|
||||
stream >> vertex.uv.x >> vertex.uv.y;
|
||||
|
||||
ReadValuePrefix(stream, "t2");
|
||||
stream >> vertex.uv2.x >> vertex.uv2.y;
|
||||
|
||||
return vertex;
|
||||
}
|
||||
|
||||
LegacyMaterial ParseMaterial(const std::string& text)
|
||||
{
|
||||
LegacyMaterial material;
|
||||
|
||||
std::stringstream stream;
|
||||
stream.str(text);
|
||||
|
||||
ReadValuePrefix(stream, "dif");
|
||||
stream >> material.diffuse.r
|
||||
>> material.diffuse.g
|
||||
>> material.diffuse.b
|
||||
>> material.diffuse.a;
|
||||
|
||||
ReadValuePrefix(stream, "amb");
|
||||
stream >> material.ambient.r
|
||||
>> material.ambient.g
|
||||
>> material.ambient.b
|
||||
>> material.ambient.a;
|
||||
|
||||
ReadValuePrefix(stream, "spc");
|
||||
stream >> material.specular.r
|
||||
>> material.specular.g
|
||||
>> material.specular.b
|
||||
>> material.specular.a;
|
||||
|
||||
return material;
|
||||
}
|
||||
|
||||
glm::vec3 ParseVector(const std::string& text)
|
||||
{
|
||||
glm::vec3 vector = { 0, 0, 0 };
|
||||
|
||||
std::stringstream stream;
|
||||
stream.str(text);
|
||||
|
||||
stream >> vector.x >> vector.y >> vector.z;
|
||||
|
||||
return vector;
|
||||
}
|
||||
|
||||
ModelCrashSphere ParseCrashSphere(const std::string& text)
|
||||
{
|
||||
ModelCrashSphere crashSphere;
|
||||
|
||||
std::stringstream stream;
|
||||
stream.str(text);
|
||||
|
||||
ReadValuePrefix(stream, "pos");
|
||||
stream >> crashSphere.position.x
|
||||
>> crashSphere.position.y
|
||||
>> crashSphere.position.z;
|
||||
|
||||
ReadValuePrefix(stream, "rad");
|
||||
stream >> crashSphere.radius;
|
||||
|
||||
ReadValuePrefix(stream, "sound");
|
||||
stream >> crashSphere.sound;
|
||||
|
||||
ReadValuePrefix(stream, "hard");
|
||||
stream >> crashSphere.hardness;
|
||||
|
||||
return crashSphere;
|
||||
}
|
||||
|
||||
ModelShadowSpot ParseShadowSpot(const std::string& text)
|
||||
{
|
||||
ModelShadowSpot shadowSpot;
|
||||
|
||||
std::stringstream stream;
|
||||
stream.str(text);
|
||||
|
||||
ReadValuePrefix(stream, "rad");
|
||||
stream >> shadowSpot.radius;
|
||||
|
||||
ReadValuePrefix(stream, "int");
|
||||
stream >> shadowSpot.intensity;
|
||||
|
||||
return shadowSpot;
|
||||
}
|
||||
|
||||
Math::Sphere ParseCameraCollisionSphere(const std::string& text)
|
||||
{
|
||||
Math::Sphere sphere;
|
||||
|
||||
std::stringstream stream;
|
||||
stream.str(text);
|
||||
|
||||
ReadValuePrefix(stream, "pos");
|
||||
stream >> sphere.pos.x
|
||||
>> sphere.pos.y
|
||||
>> sphere.pos.z;
|
||||
|
||||
ReadValuePrefix(stream, "rad");
|
||||
stream >> sphere.radius;
|
||||
|
||||
return sphere;
|
||||
}
|
||||
|
||||
AlphaMode ParseTransparentMode(const std::string& text)
|
||||
{
|
||||
if (text == "none")
|
||||
return AlphaMode::NONE;
|
||||
else if (text == "alpha")
|
||||
return AlphaMode::MASK;
|
||||
else
|
||||
return AlphaMode::NONE;
|
||||
}
|
||||
|
||||
std::string ParseSpecialMark(const std::string& text)
|
||||
{
|
||||
if (text == "none")
|
||||
return "";
|
||||
else if (text == "part1")
|
||||
return "tracker_right";
|
||||
else if (text == "part2")
|
||||
return "tracker_left";
|
||||
else if (text == "part3")
|
||||
return "energy";
|
||||
else
|
||||
throw CModelIOException(std::string("Unexpected special mark: '") + text + "'");
|
||||
}
|
||||
|
||||
}
|
|
@ -1,36 +0,0 @@
|
|||
/*
|
||||
* This file is part of the Colobot: Gold Edition source code
|
||||
* Copyright (C) 2001-2022, Daniel Roux, EPSITEC SA & TerranovaTeam
|
||||
* http://epsitec.ch; http://colobot.info; http://github.com/colobot
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see http://gnu.org/licenses
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "graphics/model/model.h"
|
||||
|
||||
#include <filesystem>
|
||||
#include <istream>
|
||||
|
||||
/**
|
||||
* \namespace ModelInput
|
||||
* \brief Namespace with functions to read model files
|
||||
*/
|
||||
namespace Gfx::ModelIO
|
||||
{
|
||||
|
||||
std::unique_ptr<CModel> ReadTextModel(const std::filesystem::path& path);
|
||||
|
||||
}
|
|
@ -1,8 +0,0 @@
|
|||
/**
|
||||
* \dir src/graphics/opengl33
|
||||
* \brief OpenGL 3.3 engine implementation
|
||||
*
|
||||
* Contains the concrete implementation using OpenGL 3.3 of abstract CDevice class
|
||||
* from src/graphics/core
|
||||
*/
|
||||
|
|
@ -1,715 +0,0 @@
|
|||
/*
|
||||
* This file is part of the Colobot: Gold Edition source code
|
||||
* Copyright (C) 2001-2022, Daniel Roux, EPSITEC SA & TerranovaTeam
|
||||
* http://epsitec.ch; http://colobot.info; http://github.com/colobot
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see http://gnu.org/licenses
|
||||
*/
|
||||
|
||||
#include "graphics/opengl33/gl33_device.h"
|
||||
|
||||
#include "graphics/opengl33/gl33_object_renderer.h"
|
||||
#include "graphics/opengl33/gl33_particle_renderer.h"
|
||||
#include "graphics/opengl33/gl33_shadow_renderer.h"
|
||||
#include "graphics/opengl33/gl33_terrain_renderer.h"
|
||||
#include "graphics/opengl33/gl33_ui_renderer.h"
|
||||
#include "graphics/opengl33/glframebuffer.h"
|
||||
|
||||
#include "common/config.h"
|
||||
|
||||
#include "common/config_file.h"
|
||||
#include "common/image.h"
|
||||
#include "common/logger.h"
|
||||
#include "common/version.h"
|
||||
|
||||
#include "graphics/core/light.h"
|
||||
#include "graphics/core/material.h"
|
||||
#include "graphics/core/transparency.h"
|
||||
|
||||
#include "graphics/engine/engine.h"
|
||||
|
||||
#include "math/geometry.h"
|
||||
|
||||
#include <SDL.h>
|
||||
#include <physfs.h>
|
||||
|
||||
#include <cassert>
|
||||
|
||||
#include <glm/gtc/type_ptr.hpp>
|
||||
|
||||
|
||||
// Graphics module namespace
|
||||
namespace Gfx
|
||||
{
|
||||
|
||||
CGL33VertexBuffer::CGL33VertexBuffer(PrimitiveType type, size_t size)
|
||||
: CVertexBuffer(type, size)
|
||||
{
|
||||
glGenVertexArrays(1, &m_vao);
|
||||
glBindVertexArray(m_vao);
|
||||
|
||||
glGenBuffers(1, &m_vbo);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
|
||||
glBufferData(GL_ARRAY_BUFFER, m_data.size() * sizeof(Vertex3D), nullptr, GL_STATIC_DRAW);
|
||||
|
||||
// Vertex coordinate
|
||||
glEnableVertexAttribArray(0);
|
||||
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex3D), reinterpret_cast<void*>(offsetof(Vertex3D, position)));
|
||||
|
||||
// Normal
|
||||
glEnableVertexAttribArray(1);
|
||||
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex3D), reinterpret_cast<void*>(offsetof(Vertex3D, normal)));
|
||||
|
||||
// Color
|
||||
glEnableVertexAttribArray(2);
|
||||
glVertexAttribPointer(2, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(Vertex3D), reinterpret_cast<void*>(offsetof(Vertex3D, color)));
|
||||
|
||||
// Texture coordinate 0
|
||||
glEnableVertexAttribArray(3);
|
||||
glVertexAttribPointer(3, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex3D), reinterpret_cast<void*>(offsetof(Vertex3D, uv)));
|
||||
|
||||
// Texture coordinate 1
|
||||
glEnableVertexAttribArray(4);
|
||||
glVertexAttribPointer(4, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex3D), reinterpret_cast<void*>(offsetof(Vertex3D, uv2)));
|
||||
}
|
||||
|
||||
CGL33VertexBuffer::~CGL33VertexBuffer()
|
||||
{
|
||||
glDeleteVertexArrays(1, &m_vao);
|
||||
glDeleteBuffers(1, &m_vbo);
|
||||
}
|
||||
|
||||
void CGL33VertexBuffer::Update()
|
||||
{
|
||||
glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
|
||||
glBufferSubData(GL_ARRAY_BUFFER, 0, m_data.size() * sizeof(Vertex3D), m_data.data());
|
||||
}
|
||||
|
||||
CGL33Device::CGL33Device(const DeviceConfig &config)
|
||||
: m_config(config)
|
||||
{}
|
||||
|
||||
|
||||
CGL33Device::~CGL33Device()
|
||||
{
|
||||
}
|
||||
|
||||
std::string CGL33Device::GetName()
|
||||
{
|
||||
return std::string("OpenGL 3.3");
|
||||
}
|
||||
|
||||
bool CGL33Device::Create()
|
||||
{
|
||||
GetLogger()->Info("Creating CDevice - OpenGL 3.3\n");
|
||||
|
||||
if (!InitializeGLEW())
|
||||
{
|
||||
m_errorMessage = "An error occurred while initializing GLEW.";
|
||||
return false;
|
||||
}
|
||||
|
||||
// Extract OpenGL version
|
||||
int glMajor, glMinor;
|
||||
int glVersion = GetOpenGLVersion(glMajor, glMinor);
|
||||
|
||||
if (glVersion < 32)
|
||||
{
|
||||
GetLogger()->Error("Unsupported OpenGL version: %d.%d\n", glMajor, glMinor);
|
||||
GetLogger()->Error("OpenGL 3.2 or newer is required to use this engine.\n");
|
||||
m_errorMessage = "It seems your graphics card does not support OpenGL 3.2.\n";
|
||||
m_errorMessage += "Please make sure you have appropriate hardware and newest drivers installed.\n";
|
||||
m_errorMessage += "(OpenGL 3.2 is roughly equivalent to Direct3D 10)\n\n";
|
||||
m_errorMessage += GetHardwareInfo();
|
||||
return false;
|
||||
}
|
||||
else if (glVersion < 33)
|
||||
{
|
||||
GetLogger()->Warn("Partially supported OpenGL version: %d.%d\n", glMajor, glMinor);
|
||||
GetLogger()->Warn("You may experience problems while running the game on this engine.\n");
|
||||
GetLogger()->Warn("OpenGL 3.3 or newer is recommended.\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
const char* version = reinterpret_cast<const char*>(glGetString(GL_VERSION));
|
||||
const char* renderer = reinterpret_cast<const char*>(glGetString(GL_RENDERER));
|
||||
|
||||
GetLogger()->Info("OpenGL %s\n", version);
|
||||
GetLogger()->Info("%s\n", renderer);
|
||||
}
|
||||
|
||||
// Detect support of anisotropic filtering
|
||||
m_capabilities.anisotropySupported = AreExtensionsSupported("GL_EXT_texture_filter_anisotropic");
|
||||
if (m_capabilities.anisotropySupported)
|
||||
{
|
||||
// Obtain maximum anisotropy level available
|
||||
float level;
|
||||
glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &level);
|
||||
m_capabilities.maxAnisotropy = static_cast<int>(level);
|
||||
|
||||
GetLogger()->Info("Anisotropic filtering available\n");
|
||||
GetLogger()->Info("Maximum anisotropy: %d\n", m_capabilities.maxAnisotropy);
|
||||
}
|
||||
else
|
||||
{
|
||||
GetLogger()->Info("Anisotropic filtering not available\n");
|
||||
}
|
||||
|
||||
m_capabilities.multisamplingSupported = true;
|
||||
glGetIntegerv(GL_MAX_SAMPLES, &m_capabilities.maxSamples);
|
||||
GetLogger()->Info("Multisampling supported, max samples: %d\n", m_capabilities.maxSamples);
|
||||
|
||||
// Set just to be sure
|
||||
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
|
||||
glViewport(0, 0, m_config.size.x, m_config.size.y);
|
||||
|
||||
// this is set in shader
|
||||
m_capabilities.maxLights = 4;
|
||||
|
||||
int maxTextures = 0;
|
||||
glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &maxTextures);
|
||||
GetLogger()->Info("Maximum texture image units: %d\n", maxTextures);
|
||||
|
||||
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &m_capabilities.maxTextureSize);
|
||||
GetLogger()->Info("Maximum texture size: %d\n", m_capabilities.maxTextureSize);
|
||||
|
||||
m_capabilities.multitexturingSupported = true;
|
||||
m_capabilities.maxTextures = maxTextures;
|
||||
|
||||
m_capabilities.shadowMappingSupported = true;
|
||||
|
||||
m_capabilities.framebufferSupported = true;
|
||||
glGetIntegerv(GL_MAX_RENDERBUFFER_SIZE, &m_capabilities.maxRenderbufferSize);
|
||||
GetLogger()->Info("Maximum renderbuffer size: %d\n", m_capabilities.maxRenderbufferSize);
|
||||
|
||||
m_uiRenderer = std::make_unique<CGL33UIRenderer>(this);
|
||||
m_terrainRenderer = std::make_unique<CGL33TerrainRenderer>(this);
|
||||
m_objectRenderer = std::make_unique<CGL33ObjectRenderer>(this);
|
||||
m_particleRenderer = std::make_unique<CGL33ParticleRenderer>(this);
|
||||
m_shadowRenderer = std::make_unique<CGL33ShadowRenderer>(this);
|
||||
|
||||
// create default framebuffer object
|
||||
FramebufferParams framebufferParams;
|
||||
|
||||
framebufferParams.width = m_config.size.x;
|
||||
framebufferParams.height = m_config.size.y;
|
||||
framebufferParams.depth = m_config.depthSize;
|
||||
|
||||
m_framebuffers["default"] = std::make_unique<CDefaultFramebuffer>(framebufferParams);
|
||||
|
||||
GetLogger()->Info("CDevice created successfully\n");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CGL33Device::Destroy()
|
||||
{
|
||||
// delete shader program
|
||||
glUseProgram(0);
|
||||
|
||||
// delete framebuffers
|
||||
for (auto& framebuffer : m_framebuffers)
|
||||
framebuffer.second->Destroy();
|
||||
|
||||
m_framebuffers.clear();
|
||||
|
||||
// Delete the remaining textures
|
||||
// Should not be strictly necessary, but just in case
|
||||
DestroyAllTextures();
|
||||
|
||||
for (auto buffer : m_buffers)
|
||||
delete buffer;
|
||||
|
||||
m_buffers.clear();
|
||||
|
||||
m_uiRenderer = nullptr;
|
||||
m_terrainRenderer = nullptr;
|
||||
m_objectRenderer = nullptr;
|
||||
m_particleRenderer = nullptr;
|
||||
m_shadowRenderer = nullptr;
|
||||
}
|
||||
|
||||
void CGL33Device::ConfigChanged(const DeviceConfig& newConfig)
|
||||
{
|
||||
m_config = newConfig;
|
||||
|
||||
// Reset state
|
||||
glViewport(0, 0, m_config.size.x, m_config.size.y);
|
||||
|
||||
// create default framebuffer object
|
||||
FramebufferParams framebufferParams;
|
||||
|
||||
framebufferParams.width = m_config.size.x;
|
||||
framebufferParams.height = m_config.size.y;
|
||||
framebufferParams.depth = m_config.depthSize;
|
||||
|
||||
m_framebuffers["default"] = std::make_unique<CDefaultFramebuffer>(framebufferParams);
|
||||
}
|
||||
|
||||
void CGL33Device::BeginScene()
|
||||
{
|
||||
Clear();
|
||||
|
||||
glDisable(GL_BLEND);
|
||||
m_transparency = TransparencyMode::NONE;
|
||||
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
m_depthTest = false;
|
||||
|
||||
glDepthMask(GL_TRUE);
|
||||
m_depthMask = true;
|
||||
|
||||
glFrontFace(GL_CW); // Colobot issue: faces are reversed
|
||||
m_cullFace = CullFace::NONE;
|
||||
glDisable(GL_CULL_FACE);
|
||||
}
|
||||
|
||||
void CGL33Device::EndScene()
|
||||
{
|
||||
if constexpr (Version::DEVELOPMENT_BUILD)
|
||||
CheckGLErrors();
|
||||
}
|
||||
|
||||
void CGL33Device::Clear()
|
||||
{
|
||||
glDepthMask(GL_TRUE);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
}
|
||||
|
||||
CUIRenderer* CGL33Device::GetUIRenderer()
|
||||
{
|
||||
return m_uiRenderer.get();
|
||||
}
|
||||
|
||||
CTerrainRenderer* CGL33Device::GetTerrainRenderer()
|
||||
{
|
||||
return m_terrainRenderer.get();
|
||||
}
|
||||
|
||||
CObjectRenderer* CGL33Device::GetObjectRenderer()
|
||||
{
|
||||
return m_objectRenderer.get();
|
||||
}
|
||||
|
||||
CParticleRenderer* CGL33Device::GetParticleRenderer()
|
||||
{
|
||||
return m_particleRenderer.get();
|
||||
}
|
||||
|
||||
CShadowRenderer* CGL33Device::GetShadowRenderer()
|
||||
{
|
||||
return m_shadowRenderer.get();
|
||||
}
|
||||
|
||||
/** If image is invalid, returns invalid texture.
|
||||
Otherwise, returns pointer to new Texture struct.
|
||||
This struct must not be deleted in other way than through DeleteTexture() */
|
||||
Texture CGL33Device::CreateTexture(CImage *image, const TextureCreateParams ¶ms)
|
||||
{
|
||||
ImageData *data = image->GetData();
|
||||
if (data == nullptr)
|
||||
{
|
||||
GetLogger()->Error("Invalid texture data\n");
|
||||
return Texture(); // invalid texture
|
||||
}
|
||||
|
||||
glm::ivec2 originalSize = image->GetSize();
|
||||
|
||||
if (params.padToNearestPowerOfTwo)
|
||||
image->PadToNearestPowerOfTwo();
|
||||
|
||||
Texture tex = CreateTexture(data, params);
|
||||
tex.originalSize = originalSize;
|
||||
|
||||
return tex;
|
||||
}
|
||||
|
||||
Texture CGL33Device::CreateTexture(ImageData *data, const TextureCreateParams ¶ms)
|
||||
{
|
||||
Texture result;
|
||||
|
||||
result.size.x = data->surface->w;
|
||||
result.size.y = data->surface->h;
|
||||
|
||||
result.originalSize = result.size;
|
||||
|
||||
glGenTextures(1, &result.id);
|
||||
|
||||
glActiveTexture(GL_TEXTURE3);
|
||||
glBindTexture(GL_TEXTURE_2D, result.id);
|
||||
|
||||
// Set texture parameters
|
||||
GLint minF = GL_NEAREST, magF = GL_NEAREST;
|
||||
int mipmapLevel = 1;
|
||||
|
||||
switch (params.filter)
|
||||
{
|
||||
case TextureFilter::NEAREST:
|
||||
minF = GL_NEAREST;
|
||||
magF = GL_NEAREST;
|
||||
break;
|
||||
case TextureFilter::BILINEAR:
|
||||
minF = GL_LINEAR;
|
||||
magF = GL_LINEAR;
|
||||
break;
|
||||
case TextureFilter::TRILINEAR:
|
||||
minF = GL_LINEAR_MIPMAP_LINEAR;
|
||||
magF = GL_LINEAR;
|
||||
mipmapLevel = CEngine::GetInstance().GetTextureMipmapLevel();
|
||||
break;
|
||||
}
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, minF);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, magF);
|
||||
|
||||
GLint wrap = GL_REPEAT;
|
||||
|
||||
switch (params.wrap)
|
||||
{
|
||||
case TextureWrapMode::REPEAT:
|
||||
wrap = GL_REPEAT;
|
||||
break;
|
||||
case TextureWrapMode::CLAMP:
|
||||
wrap = GL_CLAMP;
|
||||
break;
|
||||
}
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrap);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrap);
|
||||
|
||||
// Set mipmap level and automatic mipmap generation if neccesary
|
||||
if (params.mipmap)
|
||||
{
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, mipmapLevel - 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Has to be set to 0 because no mipmaps are generated
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
|
||||
}
|
||||
|
||||
// Set anisotropy level if available
|
||||
if (m_capabilities.anisotropySupported)
|
||||
{
|
||||
float level = Math::Min(m_capabilities.maxAnisotropy, CEngine::GetInstance().GetTextureAnisotropyLevel());
|
||||
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, level);
|
||||
}
|
||||
|
||||
PreparedTextureData texData = PrepareTextureData(data, params.format);
|
||||
result.alpha = texData.alpha;
|
||||
|
||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, texData.actualSurface->pitch / texData.actualSurface->format->BytesPerPixel);
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, texData.actualSurface->w, texData.actualSurface->h,
|
||||
0, texData.sourceFormat, GL_UNSIGNED_BYTE, texData.actualSurface->pixels);
|
||||
|
||||
if (params.mipmap)
|
||||
glGenerateMipmap(GL_TEXTURE_2D);
|
||||
|
||||
SDL_FreeSurface(texData.convertedSurface);
|
||||
|
||||
m_allTextures.insert(result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
Texture CGL33Device::CreateDepthTexture(int width, int height, int depth)
|
||||
{
|
||||
Texture result;
|
||||
|
||||
result.alpha = false;
|
||||
result.size.x = width;
|
||||
result.size.y = height;
|
||||
|
||||
glGenTextures(1, &result.id);
|
||||
|
||||
glActiveTexture(GL_TEXTURE3);
|
||||
glBindTexture(GL_TEXTURE_2D, result.id);
|
||||
|
||||
GLuint format = GL_DEPTH_COMPONENT;
|
||||
|
||||
switch (depth)
|
||||
{
|
||||
case 16:
|
||||
format = GL_DEPTH_COMPONENT16;
|
||||
break;
|
||||
case 24:
|
||||
format = GL_DEPTH_COMPONENT24;
|
||||
break;
|
||||
case 32:
|
||||
format = GL_DEPTH_COMPONENT32;
|
||||
break;
|
||||
}
|
||||
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, format, width, height, 0, GL_DEPTH_COMPONENT, GL_INT, nullptr);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
|
||||
|
||||
float color[] = { 1.0f, 1.0f, 1.0f, 1.0f };
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
|
||||
glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, color);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void CGL33Device::UpdateTexture(const Texture& texture, const glm::ivec2& offset, ImageData* data, TextureFormat format)
|
||||
{
|
||||
if (texture.id == 0) return;
|
||||
|
||||
glActiveTexture(GL_TEXTURE3);
|
||||
glBindTexture(GL_TEXTURE_2D, texture.id);
|
||||
|
||||
PreparedTextureData texData = PrepareTextureData(data, format);
|
||||
|
||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, texData.actualSurface->pitch / texData.actualSurface->format->BytesPerPixel);
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, offset.x, offset.y, texData.actualSurface->w, texData.actualSurface->h,
|
||||
texData.sourceFormat, GL_UNSIGNED_BYTE, texData.actualSurface->pixels);
|
||||
|
||||
glGenerateMipmap(GL_TEXTURE_2D);
|
||||
|
||||
SDL_FreeSurface(texData.convertedSurface);
|
||||
}
|
||||
|
||||
void CGL33Device::DestroyTexture(const Texture &texture)
|
||||
{
|
||||
auto it = m_allTextures.find(texture);
|
||||
if (it != m_allTextures.end())
|
||||
{
|
||||
glDeleteTextures(1, &texture.id);
|
||||
m_allTextures.erase(it);
|
||||
}
|
||||
}
|
||||
|
||||
void CGL33Device::DestroyAllTextures()
|
||||
{
|
||||
// Unbind all texture stages
|
||||
for (int index = 0; index < 32; ++index)
|
||||
{
|
||||
glActiveTexture(GL_TEXTURE0 + index);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
}
|
||||
|
||||
for (auto it = m_allTextures.begin(); it != m_allTextures.end(); ++it)
|
||||
glDeleteTextures(1, &(*it).id);
|
||||
|
||||
m_allTextures.clear();
|
||||
}
|
||||
|
||||
CVertexBuffer* CGL33Device::CreateVertexBuffer(PrimitiveType primitiveType, const Vertex3D* vertices, int vertexCount)
|
||||
{
|
||||
auto buffer = new CGL33VertexBuffer(primitiveType, vertexCount);
|
||||
|
||||
buffer->SetData(vertices, 0, vertexCount);
|
||||
buffer->Update();
|
||||
|
||||
m_buffers.insert(buffer);
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
void CGL33Device::DestroyVertexBuffer(CVertexBuffer* buffer)
|
||||
{
|
||||
if (m_buffers.count(buffer) == 0) return;
|
||||
|
||||
m_buffers.erase(buffer);
|
||||
|
||||
delete buffer;
|
||||
}
|
||||
|
||||
void CGL33Device::SetViewport(int x, int y, int width, int height)
|
||||
{
|
||||
glViewport(x, y, width, height);
|
||||
}
|
||||
|
||||
void CGL33Device::SetDepthTest(bool enabled)
|
||||
{
|
||||
if (m_depthTest == enabled) return;
|
||||
|
||||
m_depthTest = enabled;
|
||||
|
||||
if (enabled)
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
else
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
}
|
||||
|
||||
void CGL33Device::SetDepthMask(bool enabled)
|
||||
{
|
||||
if (m_depthMask == enabled) return;
|
||||
|
||||
m_depthMask = enabled;
|
||||
|
||||
glDepthMask(enabled ? GL_TRUE : GL_FALSE);
|
||||
}
|
||||
|
||||
void CGL33Device::SetCullFace(CullFace mode)
|
||||
{
|
||||
if (m_cullFace == mode) return;
|
||||
|
||||
m_cullFace = mode;
|
||||
|
||||
switch (mode)
|
||||
{
|
||||
case CullFace::NONE:
|
||||
glDisable(GL_CULL_FACE);
|
||||
break;
|
||||
case CullFace::BACK:
|
||||
glEnable(GL_CULL_FACE);
|
||||
glCullFace(GL_BACK);
|
||||
break;
|
||||
case CullFace::FRONT:
|
||||
glEnable(GL_CULL_FACE);
|
||||
glCullFace(GL_FRONT);
|
||||
break;
|
||||
case CullFace::BOTH:
|
||||
glEnable(GL_CULL_FACE);
|
||||
glCullFace(GL_FRONT_AND_BACK);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void CGL33Device::SetTransparency(TransparencyMode mode)
|
||||
{
|
||||
if (m_transparency == mode) return;
|
||||
|
||||
m_transparency = mode;
|
||||
|
||||
switch (mode)
|
||||
{
|
||||
case TransparencyMode::NONE:
|
||||
glDisable(GL_BLEND);
|
||||
break;
|
||||
case TransparencyMode::ALPHA:
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glBlendEquation(GL_FUNC_ADD);
|
||||
break;
|
||||
case TransparencyMode::BLACK:
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_COLOR);
|
||||
glBlendEquation(GL_FUNC_ADD);
|
||||
break;
|
||||
case TransparencyMode::WHITE:
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_DST_COLOR, GL_ZERO);
|
||||
glBlendEquation(GL_FUNC_ADD);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void CGL33Device::SetColorMask(bool red, bool green, bool blue, bool alpha)
|
||||
{
|
||||
glColorMask(red, green, blue, alpha);
|
||||
}
|
||||
|
||||
void CGL33Device::SetClearColor(const Color &color)
|
||||
{
|
||||
glClearColor(color.r, color.g, color.b, color.a);
|
||||
}
|
||||
|
||||
void CGL33Device::CopyFramebufferToTexture(Texture& texture, int xOffset, int yOffset, int x, int y, int width, int height)
|
||||
{
|
||||
if (texture.id == 0) return;
|
||||
|
||||
glActiveTexture(GL_TEXTURE3);
|
||||
glBindTexture(GL_TEXTURE_2D, texture.id);
|
||||
|
||||
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, xOffset, yOffset, x, y, width, height);
|
||||
}
|
||||
|
||||
std::unique_ptr<CFrameBufferPixels> CGL33Device::GetFrameBufferPixels() const
|
||||
{
|
||||
return GetGLFrameBufferPixels(m_config.size);
|
||||
}
|
||||
|
||||
CFramebuffer* CGL33Device::GetFramebuffer(std::string name)
|
||||
{
|
||||
auto it = m_framebuffers.find(name);
|
||||
if (it == m_framebuffers.end())
|
||||
return nullptr;
|
||||
|
||||
return it->second.get();
|
||||
}
|
||||
|
||||
CFramebuffer* CGL33Device::CreateFramebuffer(std::string name, const FramebufferParams& params)
|
||||
{
|
||||
// existing framebuffer was found
|
||||
if (m_framebuffers.find(name) != m_framebuffers.end())
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto framebuffer = std::make_unique<CGLFramebuffer>(params);
|
||||
if (!framebuffer->Create()) return nullptr;
|
||||
|
||||
CFramebuffer* framebufferPtr = framebuffer.get();
|
||||
m_framebuffers[name] = std::move(framebuffer);
|
||||
return framebufferPtr;
|
||||
}
|
||||
|
||||
void CGL33Device::DeleteFramebuffer(std::string name)
|
||||
{
|
||||
// can't delete default framebuffer
|
||||
if (name == "default") return;
|
||||
|
||||
auto it = m_framebuffers.find(name);
|
||||
if (it != m_framebuffers.end())
|
||||
{
|
||||
it->second->Destroy();
|
||||
m_framebuffers.erase(it);
|
||||
}
|
||||
}
|
||||
|
||||
bool CGL33Device::IsAnisotropySupported()
|
||||
{
|
||||
return m_capabilities.anisotropySupported;
|
||||
}
|
||||
|
||||
int CGL33Device::GetMaxAnisotropyLevel()
|
||||
{
|
||||
return m_capabilities.maxAnisotropy;
|
||||
}
|
||||
|
||||
int CGL33Device::GetMaxSamples()
|
||||
{
|
||||
return m_capabilities.maxSamples;
|
||||
}
|
||||
|
||||
bool CGL33Device::IsShadowMappingSupported()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
int CGL33Device::GetMaxTextureSize()
|
||||
{
|
||||
return m_capabilities.maxTextureSize;
|
||||
}
|
||||
|
||||
bool CGL33Device::IsFramebufferSupported()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace Gfx
|
|
@ -1,192 +0,0 @@
|
|||
/*
|
||||
* This file is part of the Colobot: Gold Edition source code
|
||||
* Copyright (C) 2001-2022, Daniel Roux, EPSITEC SA & TerranovaTeam
|
||||
* http://epsitec.ch; http://colobot.info; http://github.com/colobot
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see http://gnu.org/licenses
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file graphics/opengl33/gl33_device.h
|
||||
* \brief OpenGL 3.3 implementation - CGL33Device class
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "graphics/core/device.h"
|
||||
|
||||
#include "graphics/opengl33/glframebuffer.h"
|
||||
#include "graphics/opengl33/glutil.h"
|
||||
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <unordered_set>
|
||||
|
||||
|
||||
// Graphics module namespace
|
||||
namespace Gfx
|
||||
{
|
||||
|
||||
enum class CullFace : unsigned char;
|
||||
enum class TransparencyMode : unsigned char;
|
||||
|
||||
class CGL33VertexBuffer : public CVertexBuffer
|
||||
{
|
||||
GLuint m_vao = 0;
|
||||
GLuint m_vbo = 0;
|
||||
|
||||
public:
|
||||
CGL33VertexBuffer(PrimitiveType type, size_t size);
|
||||
virtual ~CGL33VertexBuffer();
|
||||
|
||||
virtual void Update() override;
|
||||
|
||||
GLuint GetVAO() const
|
||||
{
|
||||
return m_vao;
|
||||
}
|
||||
|
||||
GLuint GetVBO() const
|
||||
{
|
||||
return m_vbo;
|
||||
}
|
||||
};
|
||||
|
||||
class CGL33UIRenderer;
|
||||
class CGL33TerrainRenderer;
|
||||
class CGL33ObjectRenderer;
|
||||
class CGL33ParticleRenderer;
|
||||
class CGL33ShadowRenderer;
|
||||
|
||||
/**
|
||||
\class CGL33Device
|
||||
\brief Implementation of CDevice interface in OpenGL 3.3
|
||||
|
||||
Provides the concrete implementation of 3D device in OpenGL.
|
||||
|
||||
This class should be initialized (by calling Initialize() ) only after
|
||||
setting the video mode by CApplication, once the OpenGL context is defined.
|
||||
Because of that, CGLDeviceConfig is outside the CDevice class and must be set
|
||||
in CApplication.
|
||||
*/
|
||||
class CGL33Device : public CDevice
|
||||
{
|
||||
public:
|
||||
CGL33Device(const DeviceConfig &config);
|
||||
virtual ~CGL33Device();
|
||||
|
||||
std::string GetName() override;
|
||||
|
||||
bool Create() override;
|
||||
void Destroy() override;
|
||||
|
||||
void ConfigChanged(const DeviceConfig &newConfig) override;
|
||||
|
||||
void BeginScene() override;
|
||||
void EndScene() override;
|
||||
|
||||
void Clear() override;
|
||||
|
||||
CUIRenderer* GetUIRenderer() override;
|
||||
CTerrainRenderer* GetTerrainRenderer() override;
|
||||
CObjectRenderer* GetObjectRenderer() override;
|
||||
CParticleRenderer* GetParticleRenderer() override;
|
||||
CShadowRenderer* GetShadowRenderer() override;
|
||||
|
||||
Texture CreateTexture(CImage *image, const TextureCreateParams ¶ms) override;
|
||||
Texture CreateTexture(ImageData *data, const TextureCreateParams ¶ms) override;
|
||||
Texture CreateDepthTexture(int width, int height, int depth) override;
|
||||
void UpdateTexture(const Texture& texture, const glm::ivec2& offset, ImageData* data, TextureFormat format) override;
|
||||
void DestroyTexture(const Texture &texture) override;
|
||||
void DestroyAllTextures() override;
|
||||
|
||||
CVertexBuffer* CreateVertexBuffer(PrimitiveType primitiveType, const Vertex3D* vertices, int vertexCount) override;
|
||||
void DestroyVertexBuffer(CVertexBuffer*) override;
|
||||
|
||||
void SetViewport(int x, int y, int width, int height) override;
|
||||
|
||||
void SetDepthTest(bool enabled) override;
|
||||
void SetDepthMask(bool enabled) override;
|
||||
|
||||
void SetCullFace(CullFace mode) override;
|
||||
|
||||
void SetTransparency(TransparencyMode mode) override;
|
||||
|
||||
void SetColorMask(bool red, bool green, bool blue, bool alpha) override;
|
||||
|
||||
void SetClearColor(const Color &color) override;
|
||||
|
||||
void CopyFramebufferToTexture(Texture& texture, int xOffset, int yOffset, int x, int y, int width, int height) override;
|
||||
|
||||
std::unique_ptr<CFrameBufferPixels> GetFrameBufferPixels() const override;
|
||||
|
||||
CFramebuffer* GetFramebuffer(std::string name) override;
|
||||
|
||||
CFramebuffer* CreateFramebuffer(std::string name, const FramebufferParams& params) override;
|
||||
|
||||
void DeleteFramebuffer(std::string name) override;
|
||||
|
||||
bool IsAnisotropySupported() override;
|
||||
int GetMaxAnisotropyLevel() override;
|
||||
|
||||
int GetMaxSamples() override;
|
||||
|
||||
bool IsShadowMappingSupported() override;
|
||||
|
||||
int GetMaxTextureSize() override;
|
||||
|
||||
bool IsFramebufferSupported() override;
|
||||
|
||||
private:
|
||||
//! Current config
|
||||
DeviceConfig m_config;
|
||||
|
||||
//! Set of all created textures
|
||||
std::set<Texture> m_allTextures;
|
||||
|
||||
//! Detected capabilities
|
||||
//! Set of vertex buffers
|
||||
std::unordered_set<CVertexBuffer*> m_buffers;
|
||||
|
||||
//! Total memory allocated in VBOs
|
||||
unsigned long m_vboMemory = 0;
|
||||
|
||||
//! Map of framebuffers
|
||||
std::map<std::string, std::unique_ptr<CFramebuffer>> m_framebuffers;
|
||||
|
||||
//! Interface renderer
|
||||
std::unique_ptr<CGL33UIRenderer> m_uiRenderer;
|
||||
//! Terrain renderer
|
||||
std::unique_ptr<CGL33TerrainRenderer> m_terrainRenderer;
|
||||
//! Object renderer
|
||||
std::unique_ptr<CGL33ObjectRenderer> m_objectRenderer;
|
||||
//! Particle renderer
|
||||
std::unique_ptr<CGL33ParticleRenderer> m_particleRenderer;
|
||||
//! Shadow renderer
|
||||
std::unique_ptr<CGL33ShadowRenderer> m_shadowRenderer;
|
||||
|
||||
//! Depth test
|
||||
bool m_depthTest = false;
|
||||
//! Depth mask
|
||||
bool m_depthMask = true;
|
||||
//! Cull face mode
|
||||
CullFace m_cullFace = {};
|
||||
//! Transparency mode
|
||||
TransparencyMode m_transparency = {};
|
||||
};
|
||||
|
||||
} // namespace Gfx
|
|
@ -1,506 +0,0 @@
|
|||
/*
|
||||
* This file is part of the Colobot: Gold Edition source code
|
||||
* Copyright (C) 2001-2022, Daniel Roux, EPSITEC SA & TerranovaTeam
|
||||
* http://epsitec.ch; http://colobot.info; http://github.com/colobot
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see http://gnu.org/licenses
|
||||
*/
|
||||
|
||||
#include "graphics/opengl33/gl33_object_renderer.h"
|
||||
|
||||
#include "graphics/opengl33/gl33_device.h"
|
||||
#include "graphics/opengl33/glutil.h"
|
||||
|
||||
#include "graphics/core/material.h"
|
||||
#include "graphics/core/transparency.h"
|
||||
#include "graphics/core/vertex.h"
|
||||
|
||||
#include "common/logger.h"
|
||||
|
||||
#include <GL/glew.h>
|
||||
|
||||
#include <glm/ext.hpp>
|
||||
#include <glm/gtc/type_ptr.hpp>
|
||||
|
||||
using namespace Gfx;
|
||||
|
||||
CGL33ObjectRenderer::CGL33ObjectRenderer(CGL33Device* device)
|
||||
:m_device(device)
|
||||
{
|
||||
GetLogger()->Info("Creating CGL33ObjectRenderer\n");
|
||||
|
||||
std::string preamble = LoadSource("shaders/gl33/preamble.glsl");
|
||||
std::string shadowSource = LoadSource("shaders/gl33/shadow.glsl");
|
||||
std::string lightingSource = LoadSource("shaders/gl33/lighting.glsl");
|
||||
std::string vsSource = LoadSource("shaders/gl33/object_vs.glsl");
|
||||
std::string fsSource = LoadSource("shaders/gl33/object_fs.glsl");
|
||||
|
||||
GLint vsShader = CreateShader(GL_VERTEX_SHADER, { preamble, lightingSource, shadowSource, vsSource });
|
||||
if (vsShader == 0)
|
||||
{
|
||||
GetLogger()->Error("Cound not create vertex shader from file 'object_vs.glsl'\n");
|
||||
return;
|
||||
}
|
||||
|
||||
GLint fsShader = CreateShader(GL_FRAGMENT_SHADER, { preamble, lightingSource, shadowSource, fsSource });
|
||||
if (fsShader == 0)
|
||||
{
|
||||
GetLogger()->Error("Cound not create fragment shader from file 'object_fs.glsl'\n");
|
||||
return;
|
||||
}
|
||||
|
||||
m_program = LinkProgram({ vsShader, fsShader });
|
||||
|
||||
glDeleteShader(vsShader);
|
||||
glDeleteShader(fsShader);
|
||||
|
||||
glUseProgram(m_program);
|
||||
|
||||
// Setup uniforms
|
||||
glm::mat4 identity(1.0f);
|
||||
|
||||
m_projectionMatrix = glGetUniformLocation(m_program, "uni_ProjectionMatrix");
|
||||
m_viewMatrix = glGetUniformLocation(m_program, "uni_ViewMatrix");
|
||||
m_shadowMatrix = glGetUniformLocation(m_program, "uni_ShadowMatrix");
|
||||
m_modelMatrix = glGetUniformLocation(m_program, "uni_ModelMatrix");
|
||||
m_normalMatrix = glGetUniformLocation(m_program, "uni_NormalMatrix");
|
||||
|
||||
m_lighting = glGetUniformLocation(m_program, "uni_Lighting");
|
||||
m_cameraPosition = glGetUniformLocation(m_program, "uni_CameraPosition");
|
||||
m_lightPosition = glGetUniformLocation(m_program, "uni_LightPosition");
|
||||
m_lightIntensity = glGetUniformLocation(m_program, "uni_LightIntensity");
|
||||
m_lightColor = glGetUniformLocation(m_program, "uni_LightColor");
|
||||
|
||||
m_skyColor = glGetUniformLocation(m_program, "uni_SkyColor");
|
||||
m_skyIntensity = glGetUniformLocation(m_program, "uni_SkyIntensity");
|
||||
|
||||
m_fogRange = glGetUniformLocation(m_program, "uni_FogRange");
|
||||
m_fogColor = glGetUniformLocation(m_program, "uni_FogColor");
|
||||
|
||||
m_albedoColor = glGetUniformLocation(m_program, "uni_AlbedoColor");
|
||||
m_emissiveColor = glGetUniformLocation(m_program, "uni_EmissiveColor");
|
||||
m_roughness = glGetUniformLocation(m_program, "uni_Roughness");
|
||||
m_metalness = glGetUniformLocation(m_program, "uni_Metalness");
|
||||
m_aoStrength = glGetUniformLocation(m_program, "uni_AOStrength");
|
||||
|
||||
m_triplanarMode = glGetUniformLocation(m_program, "uni_TriplanarMode");
|
||||
m_triplanarScale = glGetUniformLocation(m_program, "uni_TriplanarScale");
|
||||
m_alphaScissor = glGetUniformLocation(m_program, "uni_AlphaScissor");
|
||||
|
||||
m_recolor = glGetUniformLocation(m_program, "uni_Recolor");
|
||||
m_recolorFrom = glGetUniformLocation(m_program, "uni_RecolorFrom");
|
||||
m_recolorTo = glGetUniformLocation(m_program, "uni_RecolorTo");
|
||||
m_recolorThreshold = glGetUniformLocation(m_program, "uni_RecolorThreshold");
|
||||
|
||||
m_uvOffset = glGetUniformLocation(m_program, "uni_UVOffset");
|
||||
m_uvScale = glGetUniformLocation(m_program, "uni_UVScale");
|
||||
|
||||
m_shadowRegions = glGetUniformLocation(m_program, "uni_ShadowRegions");
|
||||
|
||||
std::array<GLchar, 256> name;
|
||||
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
snprintf(name.data(), name.size(), "uni_ShadowParam[%d].transform", i);
|
||||
m_shadows[i].transform = glGetUniformLocation(m_program, name.data());
|
||||
|
||||
snprintf(name.data(), name.size(), "uni_ShadowParam[%d].uv_offset", i);
|
||||
m_shadows[i].offset = glGetUniformLocation(m_program, name.data());
|
||||
|
||||
snprintf(name.data(), name.size(), "uni_ShadowParam[%d].uv_scale", i);
|
||||
m_shadows[i].scale = glGetUniformLocation(m_program, name.data());
|
||||
}
|
||||
|
||||
// Set texture units
|
||||
auto texture = glGetUniformLocation(m_program, "uni_AlbedoTexture");
|
||||
glUniform1i(texture, m_albedoIndex);
|
||||
|
||||
texture = glGetUniformLocation(m_program, "uni_DetailTexture");
|
||||
glUniform1i(texture, m_detailIndex);
|
||||
|
||||
texture = glGetUniformLocation(m_program, "uni_EmissiveTexture");
|
||||
glUniform1i(texture, m_emissiveIndex);
|
||||
|
||||
texture = glGetUniformLocation(m_program, "uni_MaterialTexture");
|
||||
glUniform1i(texture, m_materialIndex);
|
||||
|
||||
texture = glGetUniformLocation(m_program, "uni_ShadowMap");
|
||||
glUniform1i(texture, m_shadowIndex);
|
||||
|
||||
// White texture
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glGenTextures(1, &m_whiteTexture);
|
||||
glBindTexture(GL_TEXTURE_2D, m_whiteTexture);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, GL_ONE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_G, GL_ONE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, GL_ONE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_A, GL_ONE);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
|
||||
glUseProgram(0);
|
||||
|
||||
// Generic buffer
|
||||
glGenBuffers(1, &m_bufferVBO);
|
||||
glBindBuffer(GL_COPY_WRITE_BUFFER, m_bufferVBO);
|
||||
glBufferData(GL_COPY_WRITE_BUFFER, 8 * sizeof(Vertex3D), nullptr, GL_STREAM_DRAW);
|
||||
|
||||
glGenVertexArrays(1, &m_bufferVAO);
|
||||
glBindVertexArray(m_bufferVAO);
|
||||
|
||||
glEnableVertexAttribArray(0);
|
||||
glEnableVertexAttribArray(1);
|
||||
glEnableVertexAttribArray(2);
|
||||
glEnableVertexAttribArray(3);
|
||||
glEnableVertexAttribArray(4);
|
||||
|
||||
GetLogger()->Info("CGL33ObjectRenderer created successfully\n");
|
||||
}
|
||||
|
||||
CGL33ObjectRenderer::~CGL33ObjectRenderer()
|
||||
{
|
||||
glDeleteProgram(m_program);
|
||||
glDeleteTextures(1, &m_whiteTexture);
|
||||
glDeleteBuffers(1, &m_bufferVBO);
|
||||
glDeleteVertexArrays(1, &m_bufferVAO);
|
||||
}
|
||||
|
||||
void CGL33ObjectRenderer::CGL33ObjectRenderer::Begin()
|
||||
{
|
||||
glUseProgram(m_program);
|
||||
//glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
|
||||
|
||||
glActiveTexture(GL_TEXTURE0 + m_albedoIndex);
|
||||
glBindTexture(GL_TEXTURE_2D, m_whiteTexture);
|
||||
|
||||
glActiveTexture(GL_TEXTURE0 + m_detailIndex);
|
||||
glBindTexture(GL_TEXTURE_2D, m_whiteTexture);
|
||||
|
||||
glActiveTexture(GL_TEXTURE0 + m_emissiveIndex);
|
||||
glBindTexture(GL_TEXTURE_2D, m_whiteTexture);
|
||||
|
||||
glActiveTexture(GL_TEXTURE0 + m_materialIndex);
|
||||
glBindTexture(GL_TEXTURE_2D, m_whiteTexture);
|
||||
|
||||
glActiveTexture(GL_TEXTURE0 + m_shadowIndex);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
|
||||
m_albedoTexture = 0;
|
||||
m_detailTexture = 0;
|
||||
m_emissiveTexture = 0;
|
||||
m_materialTexture = 0;
|
||||
m_shadowMap = 0;
|
||||
|
||||
m_device->SetDepthTest(true);
|
||||
m_device->SetDepthMask(true);
|
||||
m_device->SetTransparency(TransparencyMode::NONE);
|
||||
m_device->SetCullFace(CullFace::BACK);
|
||||
|
||||
SetUVTransform({ 0.0f, 0.0f }, { 1.0f, 1.0f });
|
||||
SetAlphaScissor(0.0f);
|
||||
SetFog(1e+6f, 1e+6, {});
|
||||
SetEmissiveColor({ 0, 0, 0, 0 });
|
||||
SetAlbedoColor({ 1, 1, 1, 1 });
|
||||
SetMaterialParams(1.0, 0.0, 0.0);
|
||||
SetRecolor(false);
|
||||
}
|
||||
|
||||
void CGL33ObjectRenderer::CGL33ObjectRenderer::End()
|
||||
{
|
||||
glActiveTexture(GL_TEXTURE0 + m_albedoIndex);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
|
||||
glActiveTexture(GL_TEXTURE0 + m_detailIndex);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
|
||||
glActiveTexture(GL_TEXTURE0 + m_emissiveIndex);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
|
||||
glActiveTexture(GL_TEXTURE0 + m_materialIndex);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
|
||||
glActiveTexture(GL_TEXTURE0 + m_shadowIndex);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
|
||||
m_albedoTexture = 0;
|
||||
m_detailTexture = 0;
|
||||
m_emissiveTexture = 0;
|
||||
m_materialTexture = 0;
|
||||
m_shadowMap = 0;
|
||||
}
|
||||
|
||||
void CGL33ObjectRenderer::SetProjectionMatrix(const glm::mat4& matrix)
|
||||
{
|
||||
glUniformMatrix4fv(m_projectionMatrix, 1, GL_FALSE, value_ptr(matrix));
|
||||
}
|
||||
|
||||
void CGL33ObjectRenderer::SetViewMatrix(const glm::mat4& matrix)
|
||||
{
|
||||
glm::mat4 scale(1.0f);
|
||||
scale[2][2] = -1.0f;
|
||||
|
||||
auto viewMatrix = scale * matrix;
|
||||
auto cameraMatrix = glm::inverse(viewMatrix);
|
||||
auto cameraPos = cameraMatrix[3];
|
||||
|
||||
glUniformMatrix4fv(m_viewMatrix, 1, GL_FALSE, value_ptr(viewMatrix));
|
||||
glUniform3f(m_cameraPosition, cameraPos.x, cameraPos.y, cameraPos.z);
|
||||
}
|
||||
|
||||
void CGL33ObjectRenderer::SetModelMatrix(const glm::mat4& matrix)
|
||||
{
|
||||
auto normalMatrix = glm::transpose(glm::inverse(glm::mat3(matrix)));
|
||||
|
||||
glUniformMatrix4fv(m_modelMatrix, 1, GL_FALSE, value_ptr(matrix));
|
||||
glUniformMatrix3fv(m_normalMatrix, 1, GL_FALSE, value_ptr(normalMatrix));
|
||||
}
|
||||
|
||||
void CGL33ObjectRenderer::SetAlbedoColor(const Color& color)
|
||||
{
|
||||
glUniform4f(m_albedoColor, color.r, color.g, color.b, color.a);
|
||||
}
|
||||
|
||||
void CGL33ObjectRenderer::SetAlbedoTexture(const Texture& texture)
|
||||
{
|
||||
if (m_albedoTexture == texture.id) return;
|
||||
|
||||
m_albedoTexture = texture.id;
|
||||
|
||||
glActiveTexture(GL_TEXTURE0 + m_albedoIndex);
|
||||
|
||||
if (texture.id == 0)
|
||||
glBindTexture(GL_TEXTURE_2D, m_whiteTexture);
|
||||
else
|
||||
glBindTexture(GL_TEXTURE_2D, texture.id);
|
||||
}
|
||||
|
||||
void CGL33ObjectRenderer::SetEmissiveColor(const Color& color)
|
||||
{
|
||||
glUniform3f(m_emissiveColor, color.r, color.g, color.b);
|
||||
}
|
||||
|
||||
void CGL33ObjectRenderer::SetEmissiveTexture(const Texture& texture)
|
||||
{
|
||||
if (m_emissiveTexture == texture.id) return;
|
||||
|
||||
m_emissiveTexture = texture.id;
|
||||
|
||||
glActiveTexture(GL_TEXTURE0 + m_emissiveIndex);
|
||||
|
||||
if (texture.id == 0)
|
||||
glBindTexture(GL_TEXTURE_2D, m_whiteTexture);
|
||||
else
|
||||
glBindTexture(GL_TEXTURE_2D, texture.id);
|
||||
}
|
||||
|
||||
void CGL33ObjectRenderer::SetMaterialParams(float roughness, float metalness, float aoStrength)
|
||||
{
|
||||
glUniform1f(m_roughness, roughness);
|
||||
glUniform1f(m_metalness, metalness);
|
||||
glUniform1f(m_aoStrength, aoStrength);
|
||||
}
|
||||
|
||||
void CGL33ObjectRenderer::SetMaterialTexture(const Texture& texture)
|
||||
{
|
||||
if (m_materialTexture == texture.id) return;
|
||||
|
||||
m_materialTexture = texture.id;
|
||||
|
||||
glActiveTexture(GL_TEXTURE0 + m_materialIndex);
|
||||
|
||||
if (texture.id == 0)
|
||||
glBindTexture(GL_TEXTURE_2D, m_whiteTexture);
|
||||
else
|
||||
glBindTexture(GL_TEXTURE_2D, texture.id);
|
||||
}
|
||||
|
||||
void CGL33ObjectRenderer::SetDetailTexture(const Texture& texture)
|
||||
{
|
||||
if (m_detailTexture == texture.id) return;
|
||||
|
||||
m_detailTexture = texture.id;
|
||||
|
||||
glActiveTexture(GL_TEXTURE0 + m_detailIndex);
|
||||
|
||||
if (texture.id == 0)
|
||||
glBindTexture(GL_TEXTURE_2D, m_whiteTexture);
|
||||
else
|
||||
glBindTexture(GL_TEXTURE_2D, texture.id);
|
||||
}
|
||||
|
||||
void CGL33ObjectRenderer::SetShadowMap(const Texture& texture)
|
||||
{
|
||||
if (m_shadowMap == texture.id) return;
|
||||
|
||||
m_shadowMap = texture.id;
|
||||
|
||||
glActiveTexture(GL_TEXTURE0 + m_shadowIndex);
|
||||
|
||||
if (texture.id == 0)
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
else
|
||||
glBindTexture(GL_TEXTURE_2D, texture.id);
|
||||
}
|
||||
|
||||
void CGL33ObjectRenderer::SetLighting(bool enabled)
|
||||
{
|
||||
glUniform1i(m_lighting, enabled ? 1 : 0);
|
||||
}
|
||||
|
||||
void CGL33ObjectRenderer::SetLight(const glm::vec4& position, const float& intensity, const glm::vec3& color)
|
||||
{
|
||||
glUniform4fv(m_lightPosition, 1, glm::value_ptr(position));
|
||||
glUniform1f(m_lightIntensity, intensity);
|
||||
glUniform3f(m_lightColor, color.r, color.g, color.b);
|
||||
}
|
||||
|
||||
void CGL33ObjectRenderer::SetSky(const Color& color, float intensity)
|
||||
{
|
||||
glUniform3f(m_skyColor, color.r, color.g, color.b);
|
||||
glUniform1f(m_skyIntensity, intensity);
|
||||
}
|
||||
|
||||
void CGL33ObjectRenderer::SetShadowParams(int count, const ShadowParam* params)
|
||||
{
|
||||
glUniform1i(m_shadowRegions, count);
|
||||
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
glUniformMatrix4fv(m_shadows[i].transform, 1, GL_FALSE, glm::value_ptr(params[i].matrix));
|
||||
glUniform2fv(m_shadows[i].offset, 1, glm::value_ptr(params[i].uv_offset));
|
||||
glUniform2fv(m_shadows[i].scale, 1, glm::value_ptr(params[i].uv_scale));
|
||||
}
|
||||
}
|
||||
|
||||
void CGL33ObjectRenderer::SetFog(float min, float max, const glm::vec3& color)
|
||||
{
|
||||
glUniform2f(m_fogRange, min, max);
|
||||
glUniform3f(m_fogColor, color.r, color.g, color.b);
|
||||
}
|
||||
|
||||
void CGL33ObjectRenderer::SetDepthTest(bool enabled)
|
||||
{
|
||||
m_device->SetDepthTest(enabled);
|
||||
}
|
||||
|
||||
void CGL33ObjectRenderer::SetDepthMask(bool enabled)
|
||||
{
|
||||
m_device->SetDepthMask(enabled);
|
||||
}
|
||||
|
||||
void CGL33ObjectRenderer::SetCullFace(CullFace mode)
|
||||
{
|
||||
m_device->SetCullFace(mode);
|
||||
}
|
||||
|
||||
void CGL33ObjectRenderer::SetTransparency(TransparencyMode mode)
|
||||
{
|
||||
m_device->SetTransparency(mode);
|
||||
}
|
||||
|
||||
void CGL33ObjectRenderer::SetUVTransform(const glm::vec2& offset, const glm::vec2& scale)
|
||||
{
|
||||
glUniform2fv(m_uvOffset, 1, glm::value_ptr(offset));
|
||||
glUniform2fv(m_uvScale, 1, glm::value_ptr(scale));
|
||||
}
|
||||
|
||||
void CGL33ObjectRenderer::SetTriplanarMode(bool enabled)
|
||||
{
|
||||
glUniform1i(m_triplanarMode, enabled ? 1 : 0);
|
||||
}
|
||||
|
||||
void CGL33ObjectRenderer::SetTriplanarScale(float scale)
|
||||
{
|
||||
glUniform1f(m_triplanarScale, scale);
|
||||
}
|
||||
|
||||
void CGL33ObjectRenderer::SetAlphaScissor(float alpha)
|
||||
{
|
||||
glUniform1f(m_alphaScissor, alpha);
|
||||
}
|
||||
|
||||
void CGL33ObjectRenderer::SetRecolor(bool enabled, const glm::vec3& from, const glm::vec3& to, float threshold)
|
||||
{
|
||||
glUniform1i(m_recolor, enabled ? 1 : 0);
|
||||
|
||||
if (enabled)
|
||||
{
|
||||
auto fromHSV = RGB2HSV(Color(from.r, from.g, from.b, 1.0));
|
||||
auto toHSV = RGB2HSV(Color(to.r, to.g, to.b, 1.0));
|
||||
|
||||
glUniform3f(m_recolorFrom, fromHSV.h, fromHSV.s, fromHSV.v);
|
||||
glUniform3f(m_recolorTo, toHSV.h, toHSV.s, toHSV.v);
|
||||
glUniform1f(m_recolorThreshold, threshold);
|
||||
}
|
||||
}
|
||||
|
||||
void CGL33ObjectRenderer::DrawObject(const CVertexBuffer* buffer)
|
||||
{
|
||||
auto b = dynamic_cast<const CGL33VertexBuffer*>(buffer);
|
||||
|
||||
if (b == nullptr) return;
|
||||
|
||||
glBindVertexArray(b->GetVAO());
|
||||
|
||||
glDrawArrays(TranslateGfxPrimitive(b->GetType()), 0, static_cast<GLsizei>(b->Size()));
|
||||
}
|
||||
|
||||
void CGL33ObjectRenderer::DrawPrimitive(PrimitiveType type, int count, const Vertex3D* vertices)
|
||||
{
|
||||
DrawPrimitives(type, 1, &count, vertices);
|
||||
}
|
||||
|
||||
void CGL33ObjectRenderer::DrawPrimitives(PrimitiveType type, int drawCount, int count[], const Vertex3D* vertices)
|
||||
{
|
||||
m_first.resize(drawCount);
|
||||
|
||||
GLint offset = 0;
|
||||
|
||||
for (size_t i = 0; i < drawCount; i++)
|
||||
{
|
||||
m_first[i] = offset;
|
||||
offset += count[i];
|
||||
}
|
||||
|
||||
glBindVertexArray(m_bufferVAO);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, m_bufferVBO);
|
||||
|
||||
size_t size = offset * sizeof(Vertex3D);
|
||||
|
||||
// Send new vertices to GPU
|
||||
glBindBuffer(GL_ARRAY_BUFFER, m_bufferVBO);
|
||||
glBufferData(GL_ARRAY_BUFFER, size, nullptr, GL_STREAM_DRAW);
|
||||
glBufferSubData(GL_ARRAY_BUFFER, 0, size, vertices);
|
||||
|
||||
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex3D),
|
||||
reinterpret_cast<void*>(offsetof(Vertex3D, position)));
|
||||
|
||||
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex3D),
|
||||
reinterpret_cast<void*>(offsetof(Vertex3D, normal)));
|
||||
|
||||
glVertexAttribPointer(2, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(Vertex3D),
|
||||
reinterpret_cast<void*>(offsetof(Vertex3D, color)));
|
||||
|
||||
glVertexAttribPointer(3, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex3D),
|
||||
reinterpret_cast<void*>(offsetof(Vertex3D, uv)));
|
||||
|
||||
glVertexAttribPointer(4, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex3D),
|
||||
reinterpret_cast<void*>(offsetof(Vertex3D, uv2)));
|
||||
|
||||
glMultiDrawArrays(TranslateGfxPrimitive(type), m_first.data(), count, drawCount);
|
||||
}
|
|
@ -1,196 +0,0 @@
|
|||
/*
|
||||
* This file is part of the Colobot: Gold Edition source code
|
||||
* Copyright (C) 2001-2022, Daniel Roux, EPSITEC SA & TerranovaTeam
|
||||
* http://epsitec.ch; http://colobot.info; http://github.com/colobot
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see http://gnu.org/licenses
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file graphics/opengl33/gl33_object_renderer.h
|
||||
* \brief OpenGL 3.3 object renderer
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "graphics/core/renderers.h"
|
||||
|
||||
#include <GL/glew.h>
|
||||
|
||||
#include <array>
|
||||
#include <vector>
|
||||
|
||||
// Graphics module namespace
|
||||
namespace Gfx
|
||||
{
|
||||
|
||||
class CGL33Device;
|
||||
|
||||
class CGL33ObjectRenderer : public CObjectRenderer
|
||||
{
|
||||
public:
|
||||
CGL33ObjectRenderer(CGL33Device* device);
|
||||
virtual ~CGL33ObjectRenderer();
|
||||
|
||||
virtual void Begin() override;
|
||||
|
||||
virtual void End() override;
|
||||
|
||||
//! Sets projection matrix
|
||||
virtual void SetProjectionMatrix(const glm::mat4& matrix) override;
|
||||
//! Sets view matrix
|
||||
virtual void SetViewMatrix(const glm::mat4& matrix) override;
|
||||
//! Sets model matrix
|
||||
virtual void SetModelMatrix(const glm::mat4& matrix) override;
|
||||
|
||||
//! Sets albedo color
|
||||
virtual void SetAlbedoColor(const Color& color) override;
|
||||
//! Sets albedo texture
|
||||
virtual void SetAlbedoTexture(const Texture& texture) override;
|
||||
//! Sets emissive color
|
||||
virtual void SetEmissiveColor(const Color& color) override;
|
||||
//! Sets emissive texture
|
||||
virtual void SetEmissiveTexture(const Texture& texture) override;
|
||||
//! Sets material parameters
|
||||
virtual void SetMaterialParams(float roughness, float metalness, float aoStrength) override;
|
||||
//! Sets material texture
|
||||
virtual void SetMaterialTexture(const Texture& texture) override;
|
||||
|
||||
//! Sets detail texture
|
||||
virtual void SetDetailTexture(const Texture& texture) override;
|
||||
//! Sets shadow map
|
||||
virtual void SetShadowMap(const Texture& texture) override;
|
||||
|
||||
//! Enables lighting
|
||||
virtual void SetLighting(bool enabled) override;
|
||||
//! Sets light parameters
|
||||
virtual void SetLight(const glm::vec4& position, const float& intensity, const glm::vec3& color) override;
|
||||
//! Sets sky parameters
|
||||
virtual void SetSky(const Color& color, float intensity) override;
|
||||
//! Sets shadow parameters
|
||||
virtual void SetShadowParams(int count, const ShadowParam* params) override;
|
||||
|
||||
//! Sets fog parameters
|
||||
virtual void SetFog(float min, float max, const glm::vec3& color) override;
|
||||
//! Sets alpha scissor
|
||||
virtual void SetAlphaScissor(float alpha) override;
|
||||
|
||||
//! Sets recolor parameters
|
||||
virtual void SetRecolor(bool enabled, const glm::vec3& from = {}, const glm::vec3& to = {}, float threshold = {}) override;
|
||||
|
||||
virtual void SetDepthTest(bool enabled) override;
|
||||
virtual void SetDepthMask(bool enabled) override;
|
||||
|
||||
//! Sets cull mode parameters
|
||||
virtual void SetCullFace(CullFace mode) override;
|
||||
//! Sets transparency mode
|
||||
virtual void SetTransparency(TransparencyMode mode) override;
|
||||
|
||||
//! Sets UV transform
|
||||
virtual void SetUVTransform(const glm::vec2& offset, const glm::vec2& scale) override;
|
||||
|
||||
//! Sets triplanar mode
|
||||
virtual void SetTriplanarMode(bool enabled) override;
|
||||
//! Sets triplanar scale
|
||||
virtual void SetTriplanarScale(float scale) override;
|
||||
|
||||
//! Draws an object
|
||||
virtual void DrawObject(const CVertexBuffer* buffer) override;
|
||||
//! Draws a primitive
|
||||
virtual void DrawPrimitive(PrimitiveType type, int count, const Vertex3D* vertices) override;
|
||||
//! Draws a set of primitives
|
||||
virtual void DrawPrimitives(PrimitiveType type, int drawCount, int count[], const Vertex3D* vertices) override;
|
||||
|
||||
private:
|
||||
CGL33Device* const m_device;
|
||||
|
||||
// Uniform data
|
||||
GLint m_projectionMatrix = -1;
|
||||
GLint m_viewMatrix = -1;
|
||||
GLint m_shadowMatrix = -1;
|
||||
GLint m_modelMatrix = -1;
|
||||
GLint m_normalMatrix = -1;
|
||||
|
||||
GLint m_lighting = -1;
|
||||
GLint m_cameraPosition = -1;
|
||||
GLint m_lightPosition = -1;
|
||||
GLint m_lightIntensity = -1;
|
||||
GLint m_lightColor = -1;
|
||||
|
||||
GLint m_skyColor = -1;
|
||||
GLint m_skyIntensity = -1;
|
||||
|
||||
GLint m_fogRange = -1;
|
||||
GLint m_fogColor = -1;
|
||||
|
||||
GLint m_albedoColor = -1;
|
||||
GLint m_emissiveColor = -1;
|
||||
GLint m_roughness = -1;
|
||||
GLint m_metalness = -1;
|
||||
GLint m_aoStrength = -1;
|
||||
|
||||
GLint m_triplanarMode = -1;
|
||||
GLint m_triplanarScale = -1;
|
||||
GLint m_alphaScissor = -1;
|
||||
|
||||
GLint m_recolor = -1;
|
||||
GLint m_recolorFrom = -1;
|
||||
GLint m_recolorTo = -1;
|
||||
GLint m_recolorThreshold = -1;
|
||||
|
||||
GLint m_uvOffset = -1;
|
||||
GLint m_uvScale = -1;
|
||||
|
||||
struct ShadowUniforms
|
||||
{
|
||||
GLint transform;
|
||||
GLint offset;
|
||||
GLint scale;
|
||||
};
|
||||
|
||||
GLint m_shadowRegions = 0;
|
||||
ShadowUniforms m_shadows[4] = {};
|
||||
|
||||
// Shader program
|
||||
GLuint m_program = 0;
|
||||
|
||||
// Texture unit bindings
|
||||
const int m_albedoIndex = 4;
|
||||
const int m_detailIndex = 5;
|
||||
const int m_emissiveIndex = 6;
|
||||
const int m_materialIndex = 7;
|
||||
const int m_shadowIndex = 8;
|
||||
|
||||
// 1x1 white texture
|
||||
GLuint m_whiteTexture = 0;
|
||||
// Currently bound albedo texture
|
||||
GLuint m_albedoTexture = 0;
|
||||
// Currently bound detail texture
|
||||
GLuint m_detailTexture = 0;
|
||||
// Currently bound emissive texture
|
||||
GLuint m_emissiveTexture = 0;
|
||||
// Currently bound material texture
|
||||
GLuint m_materialTexture = 0;
|
||||
// Currently bound shadow map
|
||||
GLuint m_shadowMap = 0;
|
||||
|
||||
// Vertex buffer object
|
||||
GLuint m_bufferVBO = 0;
|
||||
// Vertex array object
|
||||
GLuint m_bufferVAO = 0;
|
||||
// Offsets
|
||||
std::vector<GLint> m_first;
|
||||
};
|
||||
|
||||
}
|
|
@ -1,246 +0,0 @@
|
|||
/*
|
||||
* This file is part of the Colobot: Gold Edition source code
|
||||
* Copyright (C) 2001-2022, Daniel Roux, EPSITEC SA & TerranovaTeam
|
||||
* http://epsitec.ch; http://colobot.info; http://github.com/colobot
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see http://gnu.org/licenses
|
||||
*/
|
||||
|
||||
#include "graphics/opengl33/gl33_particle_renderer.h"
|
||||
|
||||
#include "graphics/opengl33/gl33_device.h"
|
||||
#include "graphics/opengl33/glutil.h"
|
||||
|
||||
#include "graphics/core/material.h"
|
||||
#include "graphics/core/transparency.h"
|
||||
#include "graphics/core/vertex.h"
|
||||
|
||||
#include "common/logger.h"
|
||||
|
||||
#include <GL/glew.h>
|
||||
|
||||
#include <glm/ext.hpp>
|
||||
#include <glm/gtc/type_ptr.hpp>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
using namespace Gfx;
|
||||
|
||||
CGL33ParticleRenderer::CGL33ParticleRenderer(CGL33Device* device)
|
||||
: m_device(device)
|
||||
{
|
||||
GetLogger()->Info("Creating CGL33ParticleRenderer\n");
|
||||
|
||||
std::string preamble = LoadSource("shaders/gl33/preamble.glsl");
|
||||
std::string shadowSource = LoadSource("shaders/gl33/shadow.glsl");
|
||||
std::string vsSource = LoadSource("shaders/gl33/particle_vs.glsl");
|
||||
std::string fsSource = LoadSource("shaders/gl33/particle_fs.glsl");
|
||||
|
||||
GLint vsShader = CreateShader(GL_VERTEX_SHADER, { preamble, shadowSource, vsSource });
|
||||
if (vsShader == 0)
|
||||
{
|
||||
GetLogger()->Error("Cound not create vertex shader from file 'particle_vs.glsl'\n");
|
||||
return;
|
||||
}
|
||||
|
||||
GLint fsShader = CreateShader(GL_FRAGMENT_SHADER, { preamble, shadowSource, fsSource });
|
||||
if (fsShader == 0)
|
||||
{
|
||||
GetLogger()->Error("Cound not create fragment shader from file 'particle_fs.glsl'\n");
|
||||
return;
|
||||
}
|
||||
|
||||
m_program = LinkProgram({ vsShader, fsShader });
|
||||
|
||||
glDeleteShader(vsShader);
|
||||
glDeleteShader(fsShader);
|
||||
|
||||
glUseProgram(m_program);
|
||||
|
||||
// Setup uniforms
|
||||
m_projectionMatrix = glGetUniformLocation(m_program, "uni_ProjectionMatrix");
|
||||
m_viewMatrix = glGetUniformLocation(m_program, "uni_ViewMatrix");
|
||||
m_modelMatrix = glGetUniformLocation(m_program, "uni_ModelMatrix");
|
||||
m_fogRange = glGetUniformLocation(m_program, "uni_FogRange");
|
||||
m_fogColor = glGetUniformLocation(m_program, "uni_FogColor");
|
||||
m_color = glGetUniformLocation(m_program, "uni_Color");
|
||||
m_alphaScissor = glGetUniformLocation(m_program, "uni_AlphaScissor");
|
||||
|
||||
// Set texture units
|
||||
auto texture = glGetUniformLocation(m_program, "uni_Texture");
|
||||
glUniform1i(texture, 10);
|
||||
|
||||
glUniform1f(m_alphaScissor, 0.5f);
|
||||
|
||||
// White texture
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glGenTextures(1, &m_whiteTexture);
|
||||
glBindTexture(GL_TEXTURE_2D, m_whiteTexture);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, GL_ONE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_G, GL_ONE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, GL_ONE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_A, GL_ONE);
|
||||
|
||||
glUseProgram(0);
|
||||
|
||||
// Generic buffer
|
||||
glGenBuffers(1, &m_bufferVBO);
|
||||
glBindBuffer(GL_COPY_WRITE_BUFFER, m_bufferVBO);
|
||||
glBufferData(GL_COPY_WRITE_BUFFER, m_bufferCapacity * sizeof(VertexParticle), nullptr, GL_STREAM_DRAW);
|
||||
m_bufferOffset = m_bufferCapacity;
|
||||
|
||||
glGenVertexArrays(1, &m_bufferVAO);
|
||||
glBindVertexArray(m_bufferVAO);
|
||||
|
||||
glEnableVertexAttribArray(0);
|
||||
glEnableVertexAttribArray(1);
|
||||
glEnableVertexAttribArray(2);
|
||||
|
||||
GetLogger()->Info("CGL33ParticleRenderer created successfully\n");
|
||||
}
|
||||
|
||||
CGL33ParticleRenderer::~CGL33ParticleRenderer()
|
||||
{
|
||||
glDeleteProgram(m_program);
|
||||
glDeleteTextures(1, &m_whiteTexture);
|
||||
}
|
||||
|
||||
void CGL33ParticleRenderer::Begin()
|
||||
{
|
||||
glUseProgram(m_program);
|
||||
|
||||
glActiveTexture(GL_TEXTURE10);
|
||||
glBindTexture(GL_TEXTURE_2D, m_whiteTexture);
|
||||
|
||||
m_texture = 0;
|
||||
|
||||
m_device->SetDepthTest(true);
|
||||
m_device->SetDepthMask(false);
|
||||
m_device->SetCullFace(CullFace::NONE);
|
||||
|
||||
glUniform4f(m_color, 1.0f, 1.0f, 1.0f, 1.0f);
|
||||
|
||||
glBindVertexArray(m_bufferVAO);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, m_bufferVBO);
|
||||
}
|
||||
|
||||
void CGL33ParticleRenderer::End()
|
||||
{
|
||||
glActiveTexture(GL_TEXTURE10);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
|
||||
m_texture = 0;
|
||||
|
||||
glBindVertexArray(0);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
}
|
||||
|
||||
void CGL33ParticleRenderer::SetProjectionMatrix(const glm::mat4& matrix)
|
||||
{
|
||||
glUniformMatrix4fv(m_projectionMatrix, 1, GL_FALSE, value_ptr(matrix));
|
||||
}
|
||||
|
||||
void CGL33ParticleRenderer::SetViewMatrix(const glm::mat4& matrix)
|
||||
{
|
||||
glm::mat4 scale(1.0f);
|
||||
scale[2][2] = -1.0f;
|
||||
|
||||
auto viewMatrix = scale * matrix;
|
||||
|
||||
glUniformMatrix4fv(m_viewMatrix, 1, GL_FALSE, value_ptr(viewMatrix));
|
||||
}
|
||||
|
||||
void CGL33ParticleRenderer::SetModelMatrix(const glm::mat4& matrix)
|
||||
{
|
||||
glUniformMatrix4fv(m_modelMatrix, 1, GL_FALSE, value_ptr(matrix));
|
||||
}
|
||||
|
||||
void CGL33ParticleRenderer::SetColor(const glm::vec4& color)
|
||||
{
|
||||
glUniform4f(m_color, color.r, color.g, color.b, color.a);
|
||||
}
|
||||
|
||||
void CGL33ParticleRenderer::SetTexture(const Texture& texture)
|
||||
{
|
||||
if (m_texture == texture.id) return;
|
||||
|
||||
m_texture = texture.id;
|
||||
|
||||
glActiveTexture(GL_TEXTURE10);
|
||||
|
||||
if (texture.id == 0)
|
||||
glBindTexture(GL_TEXTURE_2D, m_whiteTexture);
|
||||
else
|
||||
glBindTexture(GL_TEXTURE_2D, texture.id);
|
||||
}
|
||||
|
||||
void CGL33ParticleRenderer::SetTransparency(TransparencyMode mode)
|
||||
{
|
||||
m_device->SetTransparency(mode);
|
||||
}
|
||||
|
||||
void CGL33ParticleRenderer::DrawParticle(PrimitiveType type, int count, const VertexParticle* vertices)
|
||||
{
|
||||
GLuint total = m_bufferOffset + count;
|
||||
|
||||
// Buffer full, orphan
|
||||
if (total >= m_bufferCapacity)
|
||||
{
|
||||
glBufferData(GL_ARRAY_BUFFER, m_bufferCapacity * sizeof(VertexParticle), nullptr, GL_STREAM_DRAW);
|
||||
|
||||
m_bufferOffset = 0;
|
||||
|
||||
// Respecify vertex attributes
|
||||
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(VertexParticle),
|
||||
reinterpret_cast<void*>(offsetof(VertexParticle, position)));
|
||||
|
||||
glVertexAttribPointer(1, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(VertexParticle),
|
||||
reinterpret_cast<void*>(offsetof(VertexParticle, color)));
|
||||
|
||||
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(VertexParticle),
|
||||
reinterpret_cast<void*>(offsetof(VertexParticle, uv)));
|
||||
}
|
||||
|
||||
void* ptr = glMapBufferRange(GL_ARRAY_BUFFER,
|
||||
m_bufferOffset * sizeof(VertexParticle),
|
||||
count * sizeof(VertexParticle),
|
||||
GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT);
|
||||
|
||||
if (ptr)
|
||||
{
|
||||
auto buffer = reinterpret_cast<VertexParticle*>(ptr);
|
||||
|
||||
std::copy_n(vertices, count, buffer);
|
||||
|
||||
glUnmapBuffer(GL_ARRAY_BUFFER);
|
||||
}
|
||||
else
|
||||
{
|
||||
glBufferSubData(GL_ARRAY_BUFFER,
|
||||
m_bufferOffset * sizeof(VertexParticle),
|
||||
count * sizeof(VertexParticle),
|
||||
vertices);
|
||||
}
|
||||
|
||||
glDrawArrays(TranslateGfxPrimitive(type),
|
||||
m_bufferOffset,
|
||||
count);
|
||||
|
||||
m_bufferOffset += count;
|
||||
}
|
|
@ -1,98 +0,0 @@
|
|||
/*
|
||||
* This file is part of the Colobot: Gold Edition source code
|
||||
* Copyright (C) 2001-2022, Daniel Roux, EPSITEC SA & TerranovaTeam
|
||||
* http://epsitec.ch; http://colobot.info; http://github.com/colobot
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see http://gnu.org/licenses
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file graphics/opengl33/gl33_particle_renderer.h
|
||||
* \brief OpenGL 3.3 particle renderer
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "graphics/core/renderers.h"
|
||||
|
||||
#include <GL/glew.h>
|
||||
|
||||
#include <array>
|
||||
#include <vector>
|
||||
|
||||
// Graphics module namespace
|
||||
namespace Gfx
|
||||
{
|
||||
|
||||
class CGL33Device;
|
||||
|
||||
class CGL33ParticleRenderer : public CParticleRenderer
|
||||
{
|
||||
public:
|
||||
CGL33ParticleRenderer(CGL33Device* device);
|
||||
virtual ~CGL33ParticleRenderer();
|
||||
|
||||
virtual void Begin() override;
|
||||
|
||||
virtual void End() override;
|
||||
|
||||
//! Sets projection matrix
|
||||
virtual void SetProjectionMatrix(const glm::mat4& matrix) override;
|
||||
//! Sets view matrix
|
||||
virtual void SetViewMatrix(const glm::mat4& matrix) override;
|
||||
//! Sets model matrix
|
||||
virtual void SetModelMatrix(const glm::mat4& matrix) override;
|
||||
|
||||
//! Sets color
|
||||
virtual void SetColor(const glm::vec4& color) override;
|
||||
//! Sets texture
|
||||
virtual void SetTexture(const Texture& texture) override;
|
||||
|
||||
//! Sets transparency mode
|
||||
virtual void SetTransparency(TransparencyMode mode) override;
|
||||
|
||||
//! Draws particles
|
||||
virtual void DrawParticle(PrimitiveType type, int count, const VertexParticle* vertices) override;
|
||||
|
||||
private:
|
||||
CGL33Device* const m_device;
|
||||
|
||||
// Uniform data
|
||||
GLint m_projectionMatrix = -1;
|
||||
GLint m_viewMatrix = -1;
|
||||
GLint m_modelMatrix = -1;
|
||||
GLint m_fogRange = -1;
|
||||
GLint m_fogColor = -1;
|
||||
GLint m_color = -1;
|
||||
GLint m_alphaScissor = -1;
|
||||
|
||||
// Shader program
|
||||
GLuint m_program = 0;
|
||||
|
||||
// 1x1 white texture
|
||||
GLuint m_whiteTexture = 0;
|
||||
// Currently bound primary texture
|
||||
GLuint m_texture = 0;
|
||||
|
||||
// Vertex buffer object
|
||||
GLuint m_bufferVBO = 0;
|
||||
// Vertex array object
|
||||
GLuint m_bufferVAO = 0;
|
||||
// VBO capacity
|
||||
GLsizei m_bufferCapacity = 64 * 1024;
|
||||
// Buffer offset
|
||||
GLsizei m_bufferOffset = 0;
|
||||
};
|
||||
|
||||
}
|
|
@ -1,192 +0,0 @@
|
|||
/*
|
||||
* This file is part of the Colobot: Gold Edition source code
|
||||
* Copyright (C) 2001-2022, Daniel Roux, EPSITEC SA & TerranovaTeam
|
||||
* http://epsitec.ch; http://colobot.info; http://github.com/colobot
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see http://gnu.org/licenses
|
||||
*/
|
||||
|
||||
#include "graphics/opengl33/gl33_shadow_renderer.h"
|
||||
|
||||
#include "graphics/opengl33/gl33_device.h"
|
||||
#include "graphics/opengl33/glutil.h"
|
||||
|
||||
#include "graphics/core/material.h"
|
||||
#include "graphics/core/transparency.h"
|
||||
#include "graphics/core/vertex.h"
|
||||
|
||||
#include "common/logger.h"
|
||||
|
||||
#include <GL/glew.h>
|
||||
|
||||
#include <glm/ext.hpp>
|
||||
#include <glm/gtc/type_ptr.hpp>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
using namespace Gfx;
|
||||
|
||||
CGL33ShadowRenderer::CGL33ShadowRenderer(CGL33Device* device)
|
||||
: m_device(device)
|
||||
{
|
||||
GetLogger()->Info("Creating CGL33ShadowRenderer\n");
|
||||
|
||||
GLint shaders[2] = {};
|
||||
|
||||
shaders[0] = LoadShader(GL_VERTEX_SHADER, "shaders/gl33/shadow_vs.glsl");
|
||||
if (shaders[0] == 0)
|
||||
{
|
||||
GetLogger()->Error("Cound not create vertex shader from file 'shadow_vs.glsl'\n");
|
||||
return;
|
||||
}
|
||||
|
||||
shaders[1] = LoadShader(GL_FRAGMENT_SHADER, "shaders/gl33/shadow_fs.glsl");
|
||||
if (shaders[1] == 0)
|
||||
{
|
||||
GetLogger()->Error("Cound not create fragment shader from file 'shadow_fs.glsl'\n");
|
||||
return;
|
||||
}
|
||||
|
||||
m_program = LinkProgram(2, shaders);
|
||||
if (m_program == 0)
|
||||
{
|
||||
GetLogger()->Error("Cound not link shader program for terrain renderer\n");
|
||||
return;
|
||||
}
|
||||
|
||||
glDeleteShader(shaders[0]);
|
||||
glDeleteShader(shaders[1]);
|
||||
|
||||
glUseProgram(m_program);
|
||||
|
||||
// Setup uniforms
|
||||
auto texture = glGetUniformLocation(m_program, "uni_Texture");
|
||||
glUniform1i(texture, 0);
|
||||
|
||||
glm::mat4 identity(1.0f);
|
||||
|
||||
m_projectionMatrix = glGetUniformLocation(m_program, "uni_ProjectionMatrix");
|
||||
m_viewMatrix = glGetUniformLocation(m_program, "uni_ViewMatrix");
|
||||
m_modelMatrix = glGetUniformLocation(m_program, "uni_ModelMatrix");
|
||||
m_alphaScissor = glGetUniformLocation(m_program, "uni_AlphaScissor");
|
||||
|
||||
glUseProgram(0);
|
||||
|
||||
glGenFramebuffers(1, &m_framebuffer);
|
||||
|
||||
GetLogger()->Info("CGL33ShadowRenderer created successfully\n");
|
||||
}
|
||||
|
||||
CGL33ShadowRenderer::~CGL33ShadowRenderer()
|
||||
{
|
||||
glDeleteProgram(m_program);
|
||||
|
||||
glDeleteFramebuffers(1, &m_framebuffer);
|
||||
}
|
||||
|
||||
void CGL33ShadowRenderer::Begin()
|
||||
{
|
||||
glViewport(0, 0, m_width, m_height);
|
||||
m_device->SetDepthMask(true);
|
||||
glClear(GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
glUseProgram(m_program);
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, m_framebuffer);
|
||||
|
||||
glEnable(GL_POLYGON_OFFSET_FILL);
|
||||
glPolygonOffset(2.0f, 8.0f);
|
||||
|
||||
m_device->SetColorMask(false, false, false, false);
|
||||
m_device->SetDepthTest(true);
|
||||
m_device->SetDepthMask(true);
|
||||
|
||||
m_device->SetTransparency(TransparencyMode::NONE);
|
||||
m_device->SetCullFace(CullFace::NONE);
|
||||
}
|
||||
|
||||
void CGL33ShadowRenderer::End()
|
||||
{
|
||||
glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, 0, 0);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
|
||||
glDisable(GL_POLYGON_OFFSET_FILL);
|
||||
glPolygonOffset(0.0f, 0.0f);
|
||||
|
||||
m_device->SetColorMask(true, true, true, true);
|
||||
}
|
||||
|
||||
void CGL33ShadowRenderer::SetProjectionMatrix(const glm::mat4& matrix)
|
||||
{
|
||||
glUniformMatrix4fv(m_projectionMatrix, 1, GL_FALSE, value_ptr(matrix));
|
||||
}
|
||||
|
||||
void CGL33ShadowRenderer::SetViewMatrix(const glm::mat4& matrix)
|
||||
{
|
||||
glm::mat4 scale(1.0f);
|
||||
scale[2][2] = -1.0f;
|
||||
|
||||
auto viewMatrix = scale * matrix;
|
||||
|
||||
glUniformMatrix4fv(m_viewMatrix, 1, GL_FALSE, value_ptr(viewMatrix));
|
||||
}
|
||||
|
||||
void CGL33ShadowRenderer::SetModelMatrix(const glm::mat4& matrix)
|
||||
{
|
||||
glUniformMatrix4fv(m_modelMatrix, 1, GL_FALSE, value_ptr(matrix));
|
||||
}
|
||||
|
||||
void CGL33ShadowRenderer::SetTexture(const Texture& texture)
|
||||
{
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, texture.id);
|
||||
}
|
||||
|
||||
void CGL33ShadowRenderer::SetShadowMap(const Texture& texture)
|
||||
{
|
||||
glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, texture.id, 0);
|
||||
|
||||
m_width = texture.size.x;
|
||||
m_height = texture.size.y;
|
||||
|
||||
auto status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
|
||||
|
||||
if (status != GL_FRAMEBUFFER_COMPLETE)
|
||||
{
|
||||
GetLogger()->Error("Framebuffer incomplete: %d\n", status);
|
||||
}
|
||||
}
|
||||
|
||||
void CGL33ShadowRenderer::SetShadowRegion(const glm::vec2& offset, const glm::vec2& scale)
|
||||
{
|
||||
int x = static_cast<int>(m_width * offset.x);
|
||||
int y = static_cast<int>(m_height * offset.y);
|
||||
int width = static_cast<int>(m_width * scale.x);
|
||||
int height = static_cast<int>(m_height * scale.y);
|
||||
|
||||
glViewport(x, y, width, height);
|
||||
}
|
||||
|
||||
void CGL33ShadowRenderer::DrawObject(const CVertexBuffer* buffer, bool transparent)
|
||||
{
|
||||
auto b = dynamic_cast<const CGL33VertexBuffer*>(buffer);
|
||||
|
||||
if (b == nullptr) return;
|
||||
|
||||
glUniform1i(m_alphaScissor, transparent ? 1 : 0);
|
||||
|
||||
glBindVertexArray(b->GetVAO());
|
||||
|
||||
glDrawArrays(TranslateGfxPrimitive(b->GetType()), 0, b->Size());
|
||||
}
|
|
@ -1,86 +0,0 @@
|
|||
/*
|
||||
* This file is part of the Colobot: Gold Edition source code
|
||||
* Copyright (C) 2001-2022, Daniel Roux, EPSITEC SA & TerranovaTeam
|
||||
* http://epsitec.ch; http://colobot.info; http://github.com/colobot
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see http://gnu.org/licenses
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file graphics/opengl33/gl33_shadow_renderer.h
|
||||
* \brief OpenGL 3.3 shadow renderer
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "graphics/core/renderers.h"
|
||||
|
||||
#include <GL/glew.h>
|
||||
|
||||
#include <array>
|
||||
#include <vector>
|
||||
|
||||
// Graphics module namespace
|
||||
namespace Gfx
|
||||
{
|
||||
|
||||
class CGL33Device;
|
||||
|
||||
class CGL33ShadowRenderer : public CShadowRenderer
|
||||
{
|
||||
public:
|
||||
CGL33ShadowRenderer(CGL33Device* device);
|
||||
virtual ~CGL33ShadowRenderer();
|
||||
|
||||
virtual void Begin() override;
|
||||
|
||||
virtual void End() override;
|
||||
|
||||
//! Sets projection matrix
|
||||
virtual void SetProjectionMatrix(const glm::mat4& matrix) override;
|
||||
//! Sets view matrix
|
||||
virtual void SetViewMatrix(const glm::mat4& matrix) override;
|
||||
//! Sets model matrix
|
||||
virtual void SetModelMatrix(const glm::mat4& matrix) override;
|
||||
|
||||
//! Sets texture
|
||||
virtual void SetTexture(const Texture& texture) override;
|
||||
|
||||
//! Sets shadow map
|
||||
virtual void SetShadowMap(const Texture& texture) override;
|
||||
//! Sets shadow region
|
||||
virtual void SetShadowRegion(const glm::vec2& offset, const glm::vec2& scale) override;
|
||||
|
||||
//! Draws terrain object
|
||||
virtual void DrawObject(const CVertexBuffer* buffer, bool transparent) override;
|
||||
|
||||
private:
|
||||
CGL33Device* const m_device;
|
||||
|
||||
// Uniform data
|
||||
GLint m_projectionMatrix = -1;
|
||||
GLint m_viewMatrix = -1;
|
||||
GLint m_modelMatrix = -1;
|
||||
GLint m_alphaScissor = -1;
|
||||
|
||||
// Shader program
|
||||
GLuint m_program = 0;
|
||||
|
||||
// Framebuffer
|
||||
GLuint m_framebuffer = 0;
|
||||
int m_width = 0;
|
||||
int m_height = 0;
|
||||
};
|
||||
|
||||
} // namespace Gfx
|
|
@ -1,377 +0,0 @@
|
|||
/*
|
||||
* This file is part of the Colobot: Gold Edition source code
|
||||
* Copyright (C) 2001-2022, Daniel Roux, EPSITEC SA & TerranovaTeam
|
||||
* http://epsitec.ch; http://colobot.info; http://github.com/colobot
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see http://gnu.org/licenses
|
||||
*/
|
||||
|
||||
#include "graphics/opengl33/gl33_terrain_renderer.h"
|
||||
|
||||
#include "graphics/opengl33/gl33_device.h"
|
||||
#include "graphics/opengl33/glutil.h"
|
||||
|
||||
#include "graphics/core/material.h"
|
||||
#include "graphics/core/transparency.h"
|
||||
#include "graphics/core/vertex.h"
|
||||
|
||||
#include "common/logger.h"
|
||||
|
||||
#include <GL/glew.h>
|
||||
|
||||
#include <glm/ext.hpp>
|
||||
#include <glm/gtc/type_ptr.hpp>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
using namespace Gfx;
|
||||
|
||||
CGL33TerrainRenderer::CGL33TerrainRenderer(CGL33Device* device)
|
||||
: m_device(device)
|
||||
{
|
||||
GetLogger()->Info("Creating CGL33TerrainRenderer\n");
|
||||
|
||||
std::string preamble = LoadSource("shaders/gl33/preamble.glsl");
|
||||
std::string shadowSource = LoadSource("shaders/gl33/shadow.glsl");
|
||||
std::string lightingSource = LoadSource("shaders/gl33/lighting.glsl");
|
||||
std::string vsSource = LoadSource("shaders/gl33/terrain_vs.glsl");
|
||||
std::string fsSource = LoadSource("shaders/gl33/terrain_fs.glsl");
|
||||
|
||||
GLint vsShader = CreateShader(GL_VERTEX_SHADER, { preamble, lightingSource, shadowSource, vsSource });
|
||||
if (vsShader == 0)
|
||||
{
|
||||
GetLogger()->Error("Cound not create vertex shader from file 'terrain_vs.glsl'\n");
|
||||
return;
|
||||
}
|
||||
|
||||
GLint fsShader = CreateShader(GL_FRAGMENT_SHADER, { preamble, lightingSource, shadowSource, fsSource });
|
||||
if (fsShader == 0)
|
||||
{
|
||||
GetLogger()->Error("Cound not create fragment shader from file 'terrain_vs.glsl'\n");
|
||||
return;
|
||||
}
|
||||
|
||||
m_program = LinkProgram({ vsShader, fsShader });
|
||||
if (m_program == 0)
|
||||
{
|
||||
GetLogger()->Error("Cound not link shader program for terrain renderer\n");
|
||||
return;
|
||||
}
|
||||
|
||||
glDeleteShader(vsShader);
|
||||
glDeleteShader(fsShader);
|
||||
|
||||
glUseProgram(m_program);
|
||||
|
||||
// Setup uniforms
|
||||
glm::mat4 identity(1.0f);
|
||||
|
||||
m_projectionMatrix = glGetUniformLocation(m_program, "uni_ProjectionMatrix");
|
||||
m_viewMatrix = glGetUniformLocation(m_program, "uni_ViewMatrix");
|
||||
m_shadowMatrix = glGetUniformLocation(m_program, "uni_ShadowMatrix");
|
||||
m_modelMatrix = glGetUniformLocation(m_program, "uni_ModelMatrix");
|
||||
m_normalMatrix = glGetUniformLocation(m_program, "uni_NormalMatrix");
|
||||
|
||||
m_cameraPosition = glGetUniformLocation(m_program, "uni_CameraPosition");
|
||||
m_lightPosition = glGetUniformLocation(m_program, "uni_LightPosition");
|
||||
m_lightIntensity = glGetUniformLocation(m_program, "uni_LightIntensity");
|
||||
m_lightColor = glGetUniformLocation(m_program, "uni_LightColor");
|
||||
|
||||
m_skyColor = glGetUniformLocation(m_program, "uni_SkyColor");
|
||||
m_skyIntensity = glGetUniformLocation(m_program, "uni_SkyIntensity");
|
||||
|
||||
m_fogRange = glGetUniformLocation(m_program, "uni_FogRange");
|
||||
m_fogColor = glGetUniformLocation(m_program, "uni_FogColor");
|
||||
|
||||
m_albedoColor = glGetUniformLocation(m_program, "uni_AlbedoColor");
|
||||
m_emissiveColor = glGetUniformLocation(m_program, "uni_EmissiveColor");
|
||||
m_roughness = glGetUniformLocation(m_program, "uni_Roughness");
|
||||
m_metalness = glGetUniformLocation(m_program, "uni_Metalness");
|
||||
m_aoStrength = glGetUniformLocation(m_program, "uni_AOStrength");
|
||||
|
||||
m_shadowRegions = glGetUniformLocation(m_program, "uni_ShadowRegions");
|
||||
|
||||
std::array<GLchar, 256> name;
|
||||
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
snprintf(name.data(), name.size(), "uni_ShadowParam[%d].transform", i);
|
||||
m_shadows[i].transform = glGetUniformLocation(m_program, name.data());
|
||||
|
||||
snprintf(name.data(), name.size(), "uni_ShadowParam[%d].uv_offset", i);
|
||||
m_shadows[i].offset = glGetUniformLocation(m_program, name.data());
|
||||
|
||||
snprintf(name.data(), name.size(), "uni_ShadowParam[%d].uv_scale", i);
|
||||
m_shadows[i].scale = glGetUniformLocation(m_program, name.data());
|
||||
}
|
||||
|
||||
// Set texture units
|
||||
auto texture = glGetUniformLocation(m_program, "uni_AlbedoTexture");
|
||||
glUniform1i(texture, m_albedoIndex);
|
||||
|
||||
texture = glGetUniformLocation(m_program, "uni_DetailTexture");
|
||||
glUniform1i(texture, m_detailIndex);
|
||||
|
||||
texture = glGetUniformLocation(m_program, "uni_EmissiveTexture");
|
||||
glUniform1i(texture, m_emissiveIndex);
|
||||
|
||||
texture = glGetUniformLocation(m_program, "uni_MaterialTexture");
|
||||
glUniform1i(texture, m_materialIndex);
|
||||
|
||||
texture = glGetUniformLocation(m_program, "uni_ShadowMap");
|
||||
glUniform1i(texture, m_shadowIndex);
|
||||
|
||||
// White texture
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glGenTextures(1, &m_whiteTexture);
|
||||
glBindTexture(GL_TEXTURE_2D, m_whiteTexture);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, GL_ONE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_G, GL_ONE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, GL_ONE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_A, GL_ONE);
|
||||
|
||||
glUseProgram(0);
|
||||
|
||||
GetLogger()->Info("CGL33TerrainRenderer created successfully\n");
|
||||
}
|
||||
|
||||
CGL33TerrainRenderer::~CGL33TerrainRenderer()
|
||||
{
|
||||
glDeleteProgram(m_program);
|
||||
glDeleteTextures(1, &m_whiteTexture);
|
||||
}
|
||||
|
||||
void CGL33TerrainRenderer::Begin()
|
||||
{
|
||||
glUseProgram(m_program);
|
||||
|
||||
m_device->SetDepthTest(true);
|
||||
m_device->SetDepthMask(true);
|
||||
m_device->SetCullFace(CullFace::BACK);
|
||||
|
||||
m_device->SetTransparency(TransparencyMode::NONE);
|
||||
|
||||
glActiveTexture(GL_TEXTURE0 + m_albedoIndex);
|
||||
glBindTexture(GL_TEXTURE_2D, m_whiteTexture);
|
||||
|
||||
glActiveTexture(GL_TEXTURE0 + m_detailIndex);
|
||||
glBindTexture(GL_TEXTURE_2D, m_whiteTexture);
|
||||
|
||||
glActiveTexture(GL_TEXTURE0 + m_emissiveIndex);
|
||||
glBindTexture(GL_TEXTURE_2D, m_whiteTexture);
|
||||
|
||||
glActiveTexture(GL_TEXTURE0 + m_materialIndex);
|
||||
glBindTexture(GL_TEXTURE_2D, m_whiteTexture);
|
||||
|
||||
glActiveTexture(GL_TEXTURE0 + m_shadowIndex);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
|
||||
m_albedoTexture = 0;
|
||||
m_detailTexture = 0;
|
||||
m_emissiveTexture = 0;
|
||||
m_materialTexture = 0;
|
||||
m_shadowMap = 0;
|
||||
|
||||
m_device->SetDepthTest(true);
|
||||
m_device->SetDepthMask(true);
|
||||
m_device->SetTransparency(TransparencyMode::NONE);
|
||||
m_device->SetCullFace(CullFace::BACK);
|
||||
|
||||
SetFog(1e+6f, 1e+6, {});
|
||||
}
|
||||
|
||||
void CGL33TerrainRenderer::End()
|
||||
{
|
||||
glActiveTexture(GL_TEXTURE0 + m_albedoIndex);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
|
||||
glActiveTexture(GL_TEXTURE0 + m_detailIndex);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
|
||||
glActiveTexture(GL_TEXTURE0 + m_emissiveIndex);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
|
||||
glActiveTexture(GL_TEXTURE0 + m_materialIndex);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
|
||||
glActiveTexture(GL_TEXTURE0 + m_shadowIndex);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
|
||||
m_albedoTexture = 0;
|
||||
m_detailTexture = 0;
|
||||
m_emissiveTexture = 0;
|
||||
m_materialTexture = 0;
|
||||
m_shadowMap = 0;
|
||||
}
|
||||
|
||||
void CGL33TerrainRenderer::SetProjectionMatrix(const glm::mat4& matrix)
|
||||
{
|
||||
glUniformMatrix4fv(m_projectionMatrix, 1, GL_FALSE, value_ptr(matrix));
|
||||
}
|
||||
|
||||
void CGL33TerrainRenderer::SetViewMatrix(const glm::mat4& matrix)
|
||||
{
|
||||
glm::mat4 scale(1.0f);
|
||||
scale[2][2] = -1.0f;
|
||||
|
||||
auto viewMatrix = scale * matrix;
|
||||
auto cameraMatrix = glm::inverse(viewMatrix);
|
||||
auto cameraPos = cameraMatrix[3];
|
||||
|
||||
glUniformMatrix4fv(m_viewMatrix, 1, GL_FALSE, value_ptr(viewMatrix));
|
||||
glUniform3f(m_cameraPosition, cameraPos.x, cameraPos.y, cameraPos.z);
|
||||
}
|
||||
|
||||
void CGL33TerrainRenderer::SetModelMatrix(const glm::mat4& matrix)
|
||||
{
|
||||
auto normalMatrix = glm::transpose(glm::inverse(glm::mat3(matrix)));
|
||||
|
||||
glUniformMatrix4fv(m_modelMatrix, 1, GL_FALSE, value_ptr(matrix));
|
||||
glUniformMatrix3fv(m_normalMatrix, 1, GL_FALSE, value_ptr(normalMatrix));
|
||||
}
|
||||
|
||||
void CGL33TerrainRenderer::SetAlbedoColor(const Color& color)
|
||||
{
|
||||
glUniform4f(m_albedoColor, color.r, color.g, color.b, color.a);
|
||||
}
|
||||
|
||||
void CGL33TerrainRenderer::SetAlbedoTexture(const Texture& texture)
|
||||
{
|
||||
if (m_albedoTexture == texture.id) return;
|
||||
|
||||
m_albedoTexture = texture.id;
|
||||
|
||||
glActiveTexture(GL_TEXTURE0 + m_albedoIndex);
|
||||
|
||||
if (texture.id == 0)
|
||||
glBindTexture(GL_TEXTURE_2D, m_whiteTexture);
|
||||
else
|
||||
glBindTexture(GL_TEXTURE_2D, texture.id);
|
||||
}
|
||||
|
||||
void CGL33TerrainRenderer::SetEmissiveColor(const Color& color)
|
||||
{
|
||||
glUniform3f(m_emissiveColor, color.r, color.g, color.b);
|
||||
}
|
||||
|
||||
void CGL33TerrainRenderer::SetEmissiveTexture(const Texture& texture)
|
||||
{
|
||||
if (m_emissiveTexture == texture.id) return;
|
||||
|
||||
m_emissiveTexture = texture.id;
|
||||
|
||||
glActiveTexture(GL_TEXTURE0 + m_emissiveIndex);
|
||||
|
||||
if (texture.id == 0)
|
||||
glBindTexture(GL_TEXTURE_2D, m_whiteTexture);
|
||||
else
|
||||
glBindTexture(GL_TEXTURE_2D, texture.id);
|
||||
}
|
||||
|
||||
void CGL33TerrainRenderer::SetMaterialParams(float roughness, float metalness, float aoStrength)
|
||||
{
|
||||
glUniform1f(m_roughness, roughness);
|
||||
glUniform1f(m_metalness, metalness);
|
||||
glUniform1f(m_aoStrength, aoStrength);
|
||||
}
|
||||
|
||||
void CGL33TerrainRenderer::SetMaterialTexture(const Texture& texture)
|
||||
{
|
||||
if (m_materialTexture == texture.id) return;
|
||||
|
||||
m_materialTexture = texture.id;
|
||||
|
||||
glActiveTexture(GL_TEXTURE0 + m_materialIndex);
|
||||
|
||||
if (texture.id == 0)
|
||||
glBindTexture(GL_TEXTURE_2D, m_whiteTexture);
|
||||
else
|
||||
glBindTexture(GL_TEXTURE_2D, texture.id);
|
||||
}
|
||||
|
||||
void CGL33TerrainRenderer::SetDetailTexture(const Texture& texture)
|
||||
{
|
||||
if (m_detailTexture == texture.id) return;
|
||||
|
||||
m_detailTexture = texture.id;
|
||||
|
||||
glActiveTexture(GL_TEXTURE0 + m_detailIndex);
|
||||
|
||||
if (texture.id == 0)
|
||||
glBindTexture(GL_TEXTURE_2D, m_whiteTexture);
|
||||
else
|
||||
glBindTexture(GL_TEXTURE_2D, texture.id);
|
||||
}
|
||||
|
||||
void CGL33TerrainRenderer::SetShadowMap(const Texture& texture)
|
||||
{
|
||||
if (m_shadowMap == texture.id) return;
|
||||
|
||||
m_shadowMap = texture.id;
|
||||
|
||||
glActiveTexture(GL_TEXTURE0 + m_shadowIndex);
|
||||
|
||||
if (texture.id == 0)
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
else
|
||||
glBindTexture(GL_TEXTURE_2D, texture.id);
|
||||
}
|
||||
|
||||
void CGL33TerrainRenderer::SetLight(const glm::vec4& position, const float& intensity, const glm::vec3& color)
|
||||
{
|
||||
glUniform4fv(m_lightPosition, 1, glm::value_ptr(position));
|
||||
glUniform1f(m_lightIntensity, intensity);
|
||||
glUniform3fv(m_lightColor, 1, glm::value_ptr(color));
|
||||
}
|
||||
|
||||
void CGL33TerrainRenderer::SetSky(const Color& color, float intensity)
|
||||
{
|
||||
glUniform3f(m_skyColor, color.r, color.g, color.b);
|
||||
glUniform1f(m_skyIntensity, intensity);
|
||||
}
|
||||
|
||||
void CGL33TerrainRenderer::SetShadowParams(int count, const ShadowParam* params)
|
||||
{
|
||||
glUniform1i(m_shadowRegions, count);
|
||||
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
glUniformMatrix4fv(m_shadows[i].transform, 1, GL_FALSE, glm::value_ptr(params[i].matrix));
|
||||
glUniform2fv(m_shadows[i].offset, 1, glm::value_ptr(params[i].uv_offset));
|
||||
glUniform2fv(m_shadows[i].scale, 1, glm::value_ptr(params[i].uv_scale));
|
||||
}
|
||||
}
|
||||
|
||||
void CGL33TerrainRenderer::SetFog(float min, float max, const glm::vec3& color)
|
||||
{
|
||||
glUniform2f(m_fogRange, min, max);
|
||||
glUniform3f(m_fogColor, color.r, color.g, color.b);
|
||||
}
|
||||
|
||||
void CGL33TerrainRenderer::DrawObject(const glm::mat4& matrix, const CVertexBuffer* buffer)
|
||||
{
|
||||
auto b = dynamic_cast<const CGL33VertexBuffer*>(buffer);
|
||||
|
||||
if (b == nullptr) return;
|
||||
|
||||
SetModelMatrix(matrix);
|
||||
glBindVertexArray(b->GetVAO());
|
||||
|
||||
glDrawArrays(TranslateGfxPrimitive(b->GetType()), 0, static_cast<GLsizei>(b->Size()));
|
||||
}
|
|
@ -1,151 +0,0 @@
|
|||
/*
|
||||
* This file is part of the Colobot: Gold Edition source code
|
||||
* Copyright (C) 2001-2022, Daniel Roux, EPSITEC SA & TerranovaTeam
|
||||
* http://epsitec.ch; http://colobot.info; http://github.com/colobot
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see http://gnu.org/licenses
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file graphics/opengl33/gl33_terrain_renderer.h
|
||||
* \brief OpenGL 3.3 terrain renderer
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "graphics/core/renderers.h"
|
||||
|
||||
#include <GL/glew.h>
|
||||
|
||||
#include <array>
|
||||
#include <vector>
|
||||
|
||||
// Graphics module namespace
|
||||
namespace Gfx
|
||||
{
|
||||
|
||||
struct Texture;
|
||||
|
||||
class CGL33Device;
|
||||
|
||||
class CGL33TerrainRenderer : public CTerrainRenderer
|
||||
{
|
||||
public:
|
||||
CGL33TerrainRenderer(CGL33Device* device);
|
||||
virtual ~CGL33TerrainRenderer();
|
||||
|
||||
virtual void Begin() override;
|
||||
|
||||
virtual void End() override;
|
||||
|
||||
//! Sets projection matrix
|
||||
virtual void SetProjectionMatrix(const glm::mat4& matrix) override;
|
||||
//! Sets view matrix
|
||||
virtual void SetViewMatrix(const glm::mat4& matrix) override;
|
||||
//! Sets model matrix
|
||||
virtual void SetModelMatrix(const glm::mat4& matrix) override;
|
||||
|
||||
//! Sets albedo color
|
||||
virtual void SetAlbedoColor(const Color& color) override;
|
||||
//! Sets albedo texture
|
||||
virtual void SetAlbedoTexture(const Texture& texture) override;
|
||||
//! Sets emissive color
|
||||
virtual void SetEmissiveColor(const Color& color) override;
|
||||
//! Sets emissive texture
|
||||
virtual void SetEmissiveTexture(const Texture& texture) override;
|
||||
//! Sets material parameters
|
||||
virtual void SetMaterialParams(float roughness, float metalness, float aoStrength) override;
|
||||
//! Sets material texture
|
||||
virtual void SetMaterialTexture(const Texture& texture) override;
|
||||
|
||||
//! Sets detail texture
|
||||
virtual void SetDetailTexture(const Texture& texture) override;
|
||||
//! Sets shadow map
|
||||
virtual void SetShadowMap(const Texture& texture) override;
|
||||
|
||||
//! Sets light parameters
|
||||
virtual void SetLight(const glm::vec4& position, const float& intensity, const glm::vec3& color) override;
|
||||
//! Sets sky parameters
|
||||
virtual void SetSky(const Color& color, float intensity) override;
|
||||
//! Sets shadow parameters
|
||||
virtual void SetShadowParams(int count, const ShadowParam* params) override;
|
||||
|
||||
//! Sets fog parameters
|
||||
virtual void SetFog(float min, float max, const glm::vec3& color) override;
|
||||
|
||||
//! Draws terrain object
|
||||
virtual void DrawObject(const glm::mat4& matrix, const CVertexBuffer* buffer) override;
|
||||
|
||||
private:
|
||||
CGL33Device* const m_device;
|
||||
|
||||
// Uniform data
|
||||
GLint m_projectionMatrix = -1;
|
||||
GLint m_viewMatrix = -1;
|
||||
GLint m_shadowMatrix = -1;
|
||||
GLint m_modelMatrix = -1;
|
||||
GLint m_normalMatrix = -1;
|
||||
|
||||
GLint m_cameraPosition = -1;
|
||||
GLint m_lightPosition = -1;
|
||||
GLint m_lightIntensity = -1;
|
||||
GLint m_lightColor = -1;
|
||||
|
||||
GLint m_skyColor = -1;
|
||||
GLint m_skyIntensity = -1;
|
||||
|
||||
GLint m_fogRange = -1;
|
||||
GLint m_fogColor = -1;
|
||||
|
||||
GLint m_albedoColor = -1;
|
||||
GLint m_emissiveColor = -1;
|
||||
GLint m_roughness = -1;
|
||||
GLint m_metalness = -1;
|
||||
GLint m_aoStrength = -1;
|
||||
|
||||
struct ShadowUniforms
|
||||
{
|
||||
GLint transform;
|
||||
GLint offset;
|
||||
GLint scale;
|
||||
};
|
||||
|
||||
GLint m_shadowRegions = 0;
|
||||
ShadowUniforms m_shadows[4] = {};
|
||||
|
||||
// Shader program
|
||||
GLuint m_program = 0;
|
||||
|
||||
// Texture unit bindings
|
||||
const int m_albedoIndex = 4;
|
||||
const int m_detailIndex = 5;
|
||||
const int m_emissiveIndex = 6;
|
||||
const int m_materialIndex = 7;
|
||||
const int m_shadowIndex = 8;
|
||||
|
||||
// 1x1 white texture
|
||||
GLuint m_whiteTexture = 0;
|
||||
// Currently bound albedo texture
|
||||
GLuint m_albedoTexture = 0;
|
||||
// Currently bound detail texture
|
||||
GLuint m_detailTexture = 0;
|
||||
// Currently bound emissive texture
|
||||
GLuint m_emissiveTexture = 0;
|
||||
// Currently bound material texture
|
||||
GLuint m_materialTexture = 0;
|
||||
// Currently bound shadow map
|
||||
GLuint m_shadowMap = 0;
|
||||
};
|
||||
|
||||
}
|
|
@ -1,286 +0,0 @@
|
|||
/*
|
||||
* This file is part of the Colobot: Gold Edition source code
|
||||
* Copyright (C) 2001-2022, Daniel Roux, EPSITEC SA & TerranovaTeam
|
||||
* http://epsitec.ch; http://colobot.info; http://github.com/colobot
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see http://gnu.org/licenses
|
||||
*/
|
||||
|
||||
#include "graphics/opengl33/gl33_ui_renderer.h"
|
||||
|
||||
#include "graphics/opengl33/gl33_device.h"
|
||||
#include "graphics/opengl33/glutil.h"
|
||||
|
||||
#include "graphics/core/material.h"
|
||||
#include "graphics/core/transparency.h"
|
||||
#include "graphics/core/vertex.h"
|
||||
|
||||
#include "common/logger.h"
|
||||
|
||||
#include <GL/glew.h>
|
||||
|
||||
#include <glm/ext.hpp>
|
||||
#include <glm/gtc/type_ptr.hpp>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include <array>
|
||||
#include <vector>
|
||||
|
||||
using namespace Gfx;
|
||||
|
||||
CGL33UIRenderer::CGL33UIRenderer(CGL33Device* device)
|
||||
: m_device(device)
|
||||
{
|
||||
GetLogger()->Info("Creating CGL33UIRenderer\n");
|
||||
|
||||
GLint shaders[2] = {};
|
||||
|
||||
shaders[0] = LoadShader(GL_VERTEX_SHADER, "shaders/gl33/ui_vs.glsl");
|
||||
if (shaders[0] == 0)
|
||||
{
|
||||
GetLogger()->Error("Cound not create vertex shader from file 'ui_vs.glsl'\n");
|
||||
return;
|
||||
}
|
||||
|
||||
shaders[1] = LoadShader(GL_FRAGMENT_SHADER, "shaders/gl33/ui_fs.glsl");
|
||||
if (shaders[1] == 0)
|
||||
{
|
||||
GetLogger()->Error("Cound not create fragment shader from file 'ui_fs.glsl'\n");
|
||||
return;
|
||||
}
|
||||
|
||||
m_program = LinkProgram(2, shaders);
|
||||
if (m_program == 0)
|
||||
{
|
||||
GetLogger()->Error("Cound not link shader program for interface renderer\n");
|
||||
return;
|
||||
}
|
||||
|
||||
glDeleteShader(shaders[0]);
|
||||
glDeleteShader(shaders[1]);
|
||||
|
||||
glUseProgram(m_program);
|
||||
|
||||
// Create uniform buffer
|
||||
glGenBuffers(1, &m_uniformBuffer);
|
||||
|
||||
m_uniforms.projectionMatrix = glm::ortho(0.0f, +1.0f, 0.0f, +1.0f);
|
||||
m_uniforms.color = { 1.0f, 1.0f, 1.0f, 1.0f };
|
||||
|
||||
m_uniformsDirty = true;
|
||||
|
||||
UpdateUniforms();
|
||||
|
||||
// Bind uniform block to uniform buffer binding
|
||||
GLuint blockIndex = glGetUniformBlockIndex(m_program, "Uniforms");
|
||||
|
||||
glBindBufferBase(GL_UNIFORM_BUFFER, 0, m_uniformBuffer);
|
||||
glUniformBlockBinding(m_program, blockIndex, 0);
|
||||
|
||||
// Set texture unit to 8th
|
||||
auto texture = glGetUniformLocation(m_program, "uni_Texture");
|
||||
glUniform1i(texture, 8);
|
||||
|
||||
// Generic buffer
|
||||
glGenBuffers(1, &m_bufferVBO);
|
||||
glBindBuffer(GL_COPY_WRITE_BUFFER, m_bufferVBO);
|
||||
glBufferData(GL_COPY_WRITE_BUFFER, m_bufferCapacity * sizeof(Vertex2D), nullptr, GL_STREAM_DRAW);
|
||||
m_bufferOffset = m_bufferCapacity;
|
||||
|
||||
glGenVertexArrays(1, &m_bufferVAO);
|
||||
glBindVertexArray(m_bufferVAO);
|
||||
|
||||
// White texture
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glGenTextures(1, &m_whiteTexture);
|
||||
glBindTexture(GL_TEXTURE_2D, m_whiteTexture);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, GL_ONE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_G, GL_ONE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, GL_ONE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_A, GL_ONE);
|
||||
|
||||
glUseProgram(0);
|
||||
|
||||
GetLogger()->Info("CGL33UIRenderer created successfully\n");
|
||||
}
|
||||
|
||||
CGL33UIRenderer::~CGL33UIRenderer()
|
||||
{
|
||||
glDeleteProgram(m_program);
|
||||
glDeleteTextures(1, &m_whiteTexture);
|
||||
|
||||
glDeleteBuffers(1, &m_bufferVBO);
|
||||
glDeleteVertexArrays(1, &m_bufferVAO);
|
||||
}
|
||||
|
||||
void CGL33UIRenderer::SetProjection(float left, float right, float bottom, float top)
|
||||
{
|
||||
m_uniforms.projectionMatrix = glm::ortho(left, right, bottom, top);
|
||||
m_uniformsDirty = true;
|
||||
}
|
||||
|
||||
void CGL33UIRenderer::SetTexture(const Texture& texture)
|
||||
{
|
||||
if (m_currentTexture == texture.id) return;
|
||||
|
||||
glActiveTexture(GL_TEXTURE8);
|
||||
|
||||
m_currentTexture = texture.id;
|
||||
|
||||
if (m_currentTexture == 0)
|
||||
glBindTexture(GL_TEXTURE_2D, m_whiteTexture);
|
||||
else
|
||||
glBindTexture(GL_TEXTURE_2D, m_currentTexture);
|
||||
}
|
||||
|
||||
void CGL33UIRenderer::SetColor(const glm::vec4& color)
|
||||
{
|
||||
m_uniforms.color = color;
|
||||
m_uniformsDirty = true;
|
||||
}
|
||||
|
||||
void CGL33UIRenderer::SetTransparency(TransparencyMode mode)
|
||||
{
|
||||
m_device->SetTransparency(mode);
|
||||
}
|
||||
|
||||
Vertex2D* CGL33UIRenderer::BeginPrimitive(PrimitiveType type, int count)
|
||||
{
|
||||
return BeginPrimitives(type, 1, &count);
|
||||
}
|
||||
|
||||
Vertex2D* CGL33UIRenderer::BeginPrimitives(PrimitiveType type, int drawCount, const int* counts)
|
||||
{
|
||||
glBindVertexArray(m_bufferVAO);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, m_bufferVBO);
|
||||
|
||||
m_currentCount = 0;
|
||||
|
||||
for (size_t i = 0; i < drawCount; i++)
|
||||
{
|
||||
m_currentCount += counts[i];
|
||||
}
|
||||
|
||||
GLuint total = m_bufferOffset + m_currentCount;
|
||||
|
||||
// Buffer full, orphan
|
||||
if (total >= m_bufferCapacity)
|
||||
{
|
||||
glBufferData(GL_ARRAY_BUFFER, m_bufferCapacity * sizeof(Vertex2D), nullptr, GL_STREAM_DRAW);
|
||||
|
||||
m_bufferOffset = 0;
|
||||
|
||||
// Respecify vertex attributes
|
||||
glEnableVertexAttribArray(0);
|
||||
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex2D),
|
||||
reinterpret_cast<void*>(offsetof(Vertex2D, position)));
|
||||
|
||||
glEnableVertexAttribArray(1);
|
||||
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex2D),
|
||||
reinterpret_cast<void*>(offsetof(Vertex2D, uv)));
|
||||
|
||||
glEnableVertexAttribArray(2);
|
||||
glVertexAttribPointer(2, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(Vertex2D),
|
||||
reinterpret_cast<void*>(offsetof(Vertex2D, color)));
|
||||
}
|
||||
|
||||
m_first.resize(drawCount);
|
||||
m_count.resize(drawCount);
|
||||
|
||||
GLsizei currentOffset = m_bufferOffset;
|
||||
|
||||
for (size_t i = 0; i < drawCount; i++)
|
||||
{
|
||||
m_first[i] = currentOffset;
|
||||
m_count[i] = counts[i];
|
||||
|
||||
currentOffset += counts[i];
|
||||
}
|
||||
|
||||
auto ptr = glMapBufferRange(GL_ARRAY_BUFFER,
|
||||
m_bufferOffset * sizeof(Vertex2D),
|
||||
m_currentCount * sizeof(Vertex2D),
|
||||
GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT);
|
||||
|
||||
m_mapped = true;
|
||||
m_type = type;
|
||||
m_drawCount = drawCount;
|
||||
|
||||
// Mapping failed, use backup buffer
|
||||
if (ptr == nullptr)
|
||||
{
|
||||
m_backup = true;
|
||||
m_buffer.resize(m_currentCount);
|
||||
|
||||
return m_buffer.data();
|
||||
}
|
||||
else
|
||||
{
|
||||
return reinterpret_cast<Vertex2D*>(ptr);
|
||||
}
|
||||
}
|
||||
|
||||
bool CGL33UIRenderer::EndPrimitive()
|
||||
{
|
||||
if (!m_mapped) return false;
|
||||
|
||||
if (m_backup)
|
||||
{
|
||||
glBufferSubData(GL_ARRAY_BUFFER,
|
||||
m_bufferOffset * sizeof(Vertex2D),
|
||||
m_currentCount * sizeof(Vertex2D),
|
||||
m_buffer.data());
|
||||
}
|
||||
else
|
||||
{
|
||||
glUnmapBuffer(GL_ARRAY_BUFFER);
|
||||
}
|
||||
|
||||
glUseProgram(m_program);
|
||||
|
||||
glBindBufferBase(GL_UNIFORM_BUFFER, 0, m_uniformBuffer);
|
||||
|
||||
UpdateUniforms();
|
||||
|
||||
m_device->SetDepthTest(false);
|
||||
m_device->SetCullFace(CullFace::NONE);
|
||||
|
||||
if (m_drawCount == 1)
|
||||
glDrawArrays(TranslateGfxPrimitive(m_type), m_first.front(), m_count.front());
|
||||
else
|
||||
glMultiDrawArrays(TranslateGfxPrimitive(m_type), m_first.data(), m_count.data(), m_drawCount);
|
||||
|
||||
m_bufferOffset += m_currentCount;
|
||||
|
||||
m_mapped = false;
|
||||
m_backup = false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CGL33UIRenderer::UpdateUniforms()
|
||||
{
|
||||
if (!m_uniformsDirty) return;
|
||||
|
||||
glBindBuffer(GL_COPY_WRITE_BUFFER, m_uniformBuffer);
|
||||
glBufferData(GL_COPY_WRITE_BUFFER, sizeof(Uniforms), nullptr, GL_STREAM_DRAW);
|
||||
glBufferSubData(GL_COPY_WRITE_BUFFER, 0, sizeof(Uniforms), &m_uniforms);
|
||||
glBindBuffer(GL_COPY_WRITE_BUFFER, 0);
|
||||
}
|
|
@ -1,110 +0,0 @@
|
|||
/*
|
||||
* This file is part of the Colobot: Gold Edition source code
|
||||
* Copyright (C) 2001-2022, Daniel Roux, EPSITEC SA & TerranovaTeam
|
||||
* http://epsitec.ch; http://colobot.info; http://github.com/colobot
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see http://gnu.org/licenses
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file graphics/opengl33/gl33_ui_renderer.h
|
||||
* \brief OpenGL 3.3 UI renderer
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "graphics/core/renderers.h"
|
||||
|
||||
#include <GL/glew.h>
|
||||
|
||||
#include <array>
|
||||
#include <vector>
|
||||
|
||||
// Graphics module namespace
|
||||
namespace Gfx
|
||||
{
|
||||
|
||||
class CGL33Device;
|
||||
|
||||
class CGL33UIRenderer : public CUIRenderer
|
||||
{
|
||||
public:
|
||||
CGL33UIRenderer(CGL33Device* device);
|
||||
virtual ~CGL33UIRenderer();
|
||||
|
||||
virtual void SetProjection(float left, float right, float bottom, float top) override;
|
||||
virtual void SetTexture(const Texture& texture) override;
|
||||
virtual void SetColor(const glm::vec4& color) override;
|
||||
virtual void SetTransparency(TransparencyMode mode) override;
|
||||
|
||||
virtual Vertex2D* BeginPrimitive(PrimitiveType type, int count) override;
|
||||
virtual Vertex2D* BeginPrimitives(PrimitiveType type, int drawCount, const int* counts) override;
|
||||
virtual bool EndPrimitive() override;
|
||||
|
||||
private:
|
||||
void UpdateUniforms();
|
||||
|
||||
CGL33Device* const m_device;
|
||||
|
||||
// Uniform data
|
||||
struct Uniforms
|
||||
{
|
||||
glm::mat4 projectionMatrix;
|
||||
glm::vec4 color;
|
||||
};
|
||||
Uniforms m_uniforms = {};
|
||||
|
||||
// true means uniforms need to be updated
|
||||
bool m_uniformsDirty = false;
|
||||
|
||||
// Uniform buffer object
|
||||
GLuint m_uniformBuffer = 0;
|
||||
|
||||
// Vertex buffer object
|
||||
GLuint m_bufferVBO = 0;
|
||||
// Vertex array object
|
||||
GLuint m_bufferVAO = 0;
|
||||
// VBO capacity
|
||||
GLsizei m_bufferCapacity = 128 * 1024;
|
||||
// Buffer offset
|
||||
GLsizei m_bufferOffset = 0;
|
||||
|
||||
// Buffer mapping state
|
||||
PrimitiveType m_type = {};
|
||||
// Number of drawn primitives
|
||||
GLuint m_drawCount = 0;
|
||||
// Total count of drawn vertices
|
||||
GLuint m_currentCount = 0;
|
||||
// Starting offset for each drawn primitive
|
||||
std::vector<GLint> m_first;
|
||||
// Numbers of vertices for each drawn primitive
|
||||
std::vector<GLsizei> m_count;
|
||||
// True means currently drawing
|
||||
bool m_mapped = false;
|
||||
// True means mapping failed, using auxiliary buffer
|
||||
bool m_backup = false;
|
||||
|
||||
// Buffered vertex data
|
||||
std::vector<Vertex2D> m_buffer;
|
||||
|
||||
// Shader program
|
||||
GLuint m_program = 0;
|
||||
|
||||
// 1x1 white texture
|
||||
GLuint m_whiteTexture = 0;
|
||||
// Currently bound texture
|
||||
GLuint m_currentTexture = 0;
|
||||
};
|
||||
|
||||
}
|
|
@ -1,106 +0,0 @@
|
|||
/*
|
||||
* This file is part of the Colobot: Gold Edition source code
|
||||
* Copyright (C) 2001-2021, Daniel Roux, EPSITEC SA & TerranovaTeam
|
||||
* http://epsitec.ch; http://colobot.info; http://github.com/colobot
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see http://gnu.org/licenses
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
// config.h must be included first
|
||||
#include "common/config.h"
|
||||
|
||||
#include <GL/glew.h>
|
||||
#include <glm/glm.hpp>
|
||||
|
||||
#include <string>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
struct SDL_Surface;
|
||||
|
||||
class CImage;
|
||||
struct ImageData;
|
||||
|
||||
// Graphics module namespace
|
||||
namespace Gfx
|
||||
{
|
||||
|
||||
class CDevice;
|
||||
class CFrameBufferPixels;
|
||||
struct DeviceConfig;
|
||||
enum class PrimitiveType : unsigned char;
|
||||
enum class Type : unsigned char;
|
||||
enum class TextureFormat : unsigned char;
|
||||
|
||||
bool InitializeGLEW();
|
||||
|
||||
//! Creates OpenGL device
|
||||
std::unique_ptr<CDevice> CreateDevice(const DeviceConfig &config, const std::string& name);
|
||||
|
||||
//! Returns OpenGL version
|
||||
// \return First digit is major part, second digit is minor part.
|
||||
int GetOpenGLVersion();
|
||||
|
||||
//! Returns OpenGL version
|
||||
// \return First digit is major part, second digit is minor part.
|
||||
int GetOpenGLVersion(int &major, int &minor);
|
||||
|
||||
//! Checks if extensions in space-delimited list are supported
|
||||
// \return true if all extensions are supported
|
||||
bool AreExtensionsSupported(std::string list);
|
||||
|
||||
//! Returns information about graphics card
|
||||
std::string GetHardwareInfo(bool full = false);
|
||||
|
||||
//! Clears OpenGL errors
|
||||
int ClearGLErrors();
|
||||
|
||||
//! Checks for OpenGL errors
|
||||
bool CheckGLErrors();
|
||||
|
||||
//! Translate Gfx primitive type to OpenGL primitive type
|
||||
GLenum TranslateGfxPrimitive(PrimitiveType type);
|
||||
|
||||
bool InPlane(glm::vec3 normal, float originPlane, glm::vec3 center, float radius);
|
||||
|
||||
GLenum TranslateType(Type type);
|
||||
|
||||
std::string GetLastShaderError();
|
||||
|
||||
std::string LoadSource(const std::string& path);
|
||||
|
||||
GLint CreateShader(GLint type, const std::vector<std::string>& sources);
|
||||
|
||||
GLint LoadShader(GLint type, const char* filename);
|
||||
|
||||
GLint LinkProgram(int count, const GLint* shaders);
|
||||
|
||||
GLint LinkProgram(const std::vector<GLint>& shaders);
|
||||
|
||||
// TODO: Moved this here temporarily only to remove code duplication in CGLDeviceXX
|
||||
struct PreparedTextureData
|
||||
{
|
||||
SDL_Surface* actualSurface = nullptr;
|
||||
SDL_Surface* convertedSurface = nullptr;
|
||||
GLenum sourceFormat = 0;
|
||||
bool alpha = false;
|
||||
};
|
||||
|
||||
PreparedTextureData PrepareTextureData(ImageData* imageData, TextureFormat format);
|
||||
|
||||
std::unique_ptr<CFrameBufferPixels> GetGLFrameBufferPixels(const glm::ivec2& size);
|
||||
|
||||
} // namespace Gfx
|
|
@ -1,89 +0,0 @@
|
|||
/*
|
||||
* This file is part of the Colobot: Gold Edition source code
|
||||
* Copyright (C) 2001-2022, Daniel Roux, EPSITEC SA & TerranovaTeam
|
||||
* http://epsitec.ch; http://colobot.info; http://github.com/colobot
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see http://gnu.org/licenses
|
||||
*/
|
||||
|
||||
// PBR lighting calculations
|
||||
|
||||
uniform bool uni_Lighting;
|
||||
|
||||
uniform vec3 uni_CameraPosition;
|
||||
|
||||
uniform float uni_LightIntensity;
|
||||
uniform vec4 uni_LightPosition;
|
||||
uniform vec3 uni_LightColor;
|
||||
|
||||
uniform float uni_SkyIntensity;
|
||||
uniform vec3 uni_SkyColor;
|
||||
|
||||
const float PI = 3.1415926;
|
||||
|
||||
vec3 SchlickFresnel(float LdH, float metalness, vec3 color)
|
||||
{
|
||||
vec3 f = mix(vec3(0.04), color, metalness);
|
||||
|
||||
return f + (1.0 - f) * pow(1.0 - LdH, 5.0);
|
||||
}
|
||||
|
||||
float GeometrySmith(float dotProd, float roughness)
|
||||
{
|
||||
float k = (roughness + 1.0) * (roughness + 1.0) / 8.0;
|
||||
float denom = dotProd * (1 - k) + k;
|
||||
return 1.0 / denom;
|
||||
}
|
||||
|
||||
float GGXDistribution(float NdH, float roughness)
|
||||
{
|
||||
float alpha2 = roughness * roughness * roughness * roughness;
|
||||
float d = (NdH * NdH) * (alpha2 - 1) + 1.0;
|
||||
return alpha2 / (PI * d * d);
|
||||
}
|
||||
|
||||
vec3 CalculateLighting(
|
||||
vec3 position,
|
||||
vec3 normal,
|
||||
vec3 albedo,
|
||||
vec3 emissive,
|
||||
float shadow,
|
||||
float ambientOcclusion,
|
||||
float roughness,
|
||||
float metalness)
|
||||
{
|
||||
vec3 diffuseBrdf = mix(albedo, vec3(0.0), metalness);
|
||||
|
||||
vec3 light = normalize(uni_LightPosition.xyz);
|
||||
float lightIntensity = uni_LightIntensity;
|
||||
|
||||
vec3 view = normalize(uni_CameraPosition - position);
|
||||
vec3 halfway = normalize(view + light);
|
||||
|
||||
float NdH = dot(normal, halfway);
|
||||
float LdH = dot(light, halfway);
|
||||
float NdL = max(dot(normal, light), 0.0);
|
||||
float NdV = dot(normal, view);
|
||||
|
||||
vec3 specBrdf = 0.25
|
||||
* GGXDistribution(NdH, roughness)
|
||||
* SchlickFresnel(LdH, metalness, albedo)
|
||||
* GeometrySmith(NdL, roughness)
|
||||
* GeometrySmith(NdV, roughness);
|
||||
|
||||
vec3 diffuseSpecular = (diffuseBrdf + PI * specBrdf) * uni_LightIntensity * uni_LightColor * NdL * shadow;
|
||||
vec3 ambient = albedo * uni_SkyColor * uni_SkyIntensity * ambientOcclusion;
|
||||
|
||||
return ambient + emissive + diffuseSpecular;
|
||||
}
|
|
@ -1,166 +0,0 @@
|
|||
/*
|
||||
* This file is part of the Colobot: Gold Edition source code
|
||||
* Copyright (C) 2001-2021, Daniel Roux, EPSITEC SA & TerranovaTeam
|
||||
* http://epsitec.ch; http://colobot.info; http://github.com/colobot
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see http://gnu.org/licenses
|
||||
*/
|
||||
|
||||
// FRAGMENT SHADER - OBJECT RENDERER
|
||||
|
||||
uniform vec2 uni_FogRange;
|
||||
uniform vec3 uni_FogColor;
|
||||
|
||||
uniform vec4 uni_AlbedoColor;
|
||||
uniform sampler2D uni_AlbedoTexture;
|
||||
uniform sampler2D uni_DetailTexture;
|
||||
|
||||
uniform float uni_Roughness;
|
||||
uniform float uni_Metalness;
|
||||
uniform float uni_AOStrength;
|
||||
uniform sampler2D uni_MaterialTexture;
|
||||
|
||||
uniform vec3 uni_EmissiveColor;
|
||||
uniform sampler2D uni_EmissiveTexture;
|
||||
|
||||
uniform bool uni_TriplanarMode;
|
||||
uniform float uni_TriplanarScale;
|
||||
|
||||
uniform float uni_AlphaScissor;
|
||||
|
||||
uniform bool uni_Recolor;
|
||||
uniform vec3 uni_RecolorFrom;
|
||||
uniform vec3 uni_RecolorTo;
|
||||
uniform float uni_RecolorThreshold;
|
||||
|
||||
in VertexData
|
||||
{
|
||||
vec4 Color;
|
||||
vec2 TexCoord0;
|
||||
vec2 TexCoord1;
|
||||
vec3 Normal;
|
||||
vec3 VertexCoord;
|
||||
vec3 VertexNormal;
|
||||
vec3 Position;
|
||||
vec3 ShadowCoords[4];
|
||||
} data;
|
||||
|
||||
out vec4 out_FragColor;
|
||||
|
||||
vec3 Triplanar(vec3 position, vec3 normal)
|
||||
{
|
||||
vec3 weights = normal * normal;
|
||||
|
||||
vec3 sum = texture(uni_DetailTexture, position.yz).rgb * weights.x;
|
||||
sum += texture(uni_DetailTexture, position.zx).rgb * weights.y;
|
||||
sum += texture(uni_DetailTexture, position.xy).rgb * weights.z;
|
||||
|
||||
return sum;
|
||||
}
|
||||
|
||||
// All components are in the range [0...1], including hue.
|
||||
vec3 rgb2hsv(vec3 c)
|
||||
{
|
||||
vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);
|
||||
vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g));
|
||||
vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r));
|
||||
|
||||
float d = q.x - min(q.w, q.y);
|
||||
float e = 1.0e-10;
|
||||
return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);
|
||||
}
|
||||
|
||||
// All components are in the range [0...1], including hue.
|
||||
vec3 hsv2rgb(vec3 c)
|
||||
{
|
||||
vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
|
||||
vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);
|
||||
return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 albedo = data.Color * uni_AlbedoColor;
|
||||
|
||||
vec4 texColor = texture(uni_AlbedoTexture, data.TexCoord0);
|
||||
|
||||
if (uni_Recolor)
|
||||
{
|
||||
vec3 hsv = rgb2hsv(texColor.rgb);
|
||||
|
||||
if (abs(hsv.x - uni_RecolorFrom.x) < uni_RecolorThreshold)
|
||||
{
|
||||
hsv += (uni_RecolorTo - uni_RecolorFrom);
|
||||
|
||||
if (hsv.x < 0.0) hsv.x += 1.0;
|
||||
if (hsv.x > 1.0) hsv.x -= 1.0;
|
||||
}
|
||||
|
||||
texColor.rgb = hsv2rgb(hsv);
|
||||
}
|
||||
|
||||
albedo *= texColor;
|
||||
|
||||
vec3 dirty = vec3(0.0);
|
||||
|
||||
if (uni_TriplanarMode)
|
||||
{
|
||||
dirty = Triplanar(data.VertexCoord * uni_TriplanarScale, data.VertexNormal);
|
||||
}
|
||||
else
|
||||
{
|
||||
dirty = texture(uni_DetailTexture, data.TexCoord1).rgb;
|
||||
}
|
||||
|
||||
albedo.rgb *= dirty;
|
||||
|
||||
vec3 color = albedo.rgb;
|
||||
float alpha = albedo.a;
|
||||
|
||||
if (uni_Lighting)
|
||||
{
|
||||
float shadow = CalculateShadow(data.ShadowCoords);
|
||||
|
||||
shadow = mix(0.5, 1.0, shadow);
|
||||
|
||||
vec3 normal = mix(-data.Normal, data.Normal, float(gl_FrontFacing));
|
||||
|
||||
vec3 emissive = uni_EmissiveColor * texture(uni_EmissiveTexture, data.TexCoord0).rgb;
|
||||
|
||||
vec3 params = texture(uni_MaterialTexture, data.TexCoord0).xyz;
|
||||
|
||||
float ambientOcclusion = 1.0 + uni_AOStrength * (params.r - 1.0);
|
||||
float roughness = uni_Roughness * params.g;
|
||||
float metalness = uni_Metalness * params.b;
|
||||
|
||||
color = CalculateLighting(
|
||||
data.Position,
|
||||
normal,
|
||||
color,
|
||||
emissive,
|
||||
shadow,
|
||||
ambientOcclusion,
|
||||
roughness,
|
||||
metalness);
|
||||
}
|
||||
|
||||
float dist = length(uni_CameraPosition - data.Position);
|
||||
float fogAmount = clamp((dist - uni_FogRange.x) / (uni_FogRange.y - uni_FogRange.x), 0.0, 1.0);
|
||||
|
||||
color = mix(color, uni_FogColor, fogAmount);
|
||||
|
||||
if (alpha < uni_AlphaScissor) discard;
|
||||
|
||||
out_FragColor = vec4(color, alpha);
|
||||
}
|
|
@ -1,21 +0,0 @@
|
|||
/*
|
||||
* This file is part of the Colobot: Gold Edition source code
|
||||
* Copyright (C) 2001-2021, Daniel Roux, EPSITEC SA & TerranovaTeam
|
||||
* http://epsitec.ch; http://colobot.info; http://github.com/colobot
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see http://gnu.org/licenses
|
||||
*/
|
||||
|
||||
// Common shader preamble
|
||||
#version 330 core
|
|
@ -1,74 +0,0 @@
|
|||
/*
|
||||
* This file is part of the Colobot: Gold Edition source code
|
||||
* Copyright (C) 2001-2021, Daniel Roux, EPSITEC SA & TerranovaTeam
|
||||
* http://epsitec.ch; http://colobot.info; http://github.com/colobot
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see http://gnu.org/licenses
|
||||
*/
|
||||
|
||||
// Shadow mapping implementation
|
||||
|
||||
struct ShadowParam
|
||||
{
|
||||
mat4 transform;
|
||||
vec2 uv_offset;
|
||||
vec2 uv_scale;
|
||||
};
|
||||
|
||||
uniform sampler2DShadow uni_ShadowMap;
|
||||
uniform int uni_ShadowRegions;
|
||||
uniform ShadowParam uni_ShadowParam[4];
|
||||
|
||||
// Projects world-space position into an array of shadow coordinates
|
||||
vec3[4] ProjectShadows(vec3 position)
|
||||
{
|
||||
vec3 result[4];
|
||||
|
||||
for (int i = 0; i < uni_ShadowRegions; i++)
|
||||
{
|
||||
vec4 projected = uni_ShadowParam[i].transform * vec4(position, 1.0);
|
||||
|
||||
result[i] = projected.xyz / projected.w;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// Calculates shadow based on array of shadow coordinates
|
||||
float CalculateShadow(vec3 projected[4])
|
||||
{
|
||||
for (int i = 0; i < uni_ShadowRegions; i++)
|
||||
{
|
||||
if (projected[i].x < 0.0 || projected[i].x > 1.0) continue;
|
||||
if (projected[i].y < 0.0 || projected[i].y > 1.0) continue;
|
||||
|
||||
vec2 uv = projected[i].xy * uni_ShadowParam[i].uv_scale + uni_ShadowParam[i].uv_offset;
|
||||
float depth = projected[i].z;
|
||||
|
||||
vec3 coord = vec3(uv, depth);
|
||||
|
||||
/*
|
||||
float value = texture(uni_ShadowMap, coord);
|
||||
value += textureOffset(uni_ShadowMap, coord, ivec2( 1, 0));
|
||||
value += textureOffset(uni_ShadowMap, coord, ivec2(-1, 0));
|
||||
value += textureOffset(uni_ShadowMap, coord, ivec2( 0, 1));
|
||||
value += textureOffset(uni_ShadowMap, coord, ivec2( 0,-1));
|
||||
return value * (1.0f / 5.0f);
|
||||
// */
|
||||
|
||||
return texture(uni_ShadowMap, coord);
|
||||
}
|
||||
|
||||
return 1.0;
|
||||
}
|
|
@ -1,91 +0,0 @@
|
|||
/*
|
||||
* This file is part of the Colobot: Gold Edition source code
|
||||
* Copyright (C) 2001-2014, Daniel Roux, EPSITEC SA & TerranovaTeam
|
||||
* http://epsitec.ch; http://colobot.info; http://github.com/colobot
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see http://gnu.org/licenses
|
||||
*/
|
||||
|
||||
// FRAGMENT SHADER - TERRAIN RENDERER
|
||||
|
||||
uniform vec2 uni_FogRange;
|
||||
uniform vec3 uni_FogColor;
|
||||
|
||||
uniform vec4 uni_AlbedoColor;
|
||||
uniform sampler2D uni_AlbedoTexture;
|
||||
uniform sampler2D uni_DetailTexture;
|
||||
|
||||
uniform float uni_Roughness;
|
||||
uniform float uni_Metalness;
|
||||
uniform float uni_AOStrength;
|
||||
uniform sampler2D uni_MaterialTexture;
|
||||
|
||||
uniform vec3 uni_EmissiveColor;
|
||||
uniform sampler2D uni_EmissiveTexture;
|
||||
|
||||
in VertexData
|
||||
{
|
||||
vec4 Color;
|
||||
vec2 TexCoord0;
|
||||
vec2 TexCoord1;
|
||||
vec3 Normal;
|
||||
vec3 Position;
|
||||
vec3 ShadowCoords[4];
|
||||
} data;
|
||||
|
||||
out vec4 out_FragColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 albedo = data.Color * uni_AlbedoColor;
|
||||
|
||||
albedo *= texture(uni_AlbedoTexture, data.TexCoord0);
|
||||
|
||||
vec3 detail = texture(uni_DetailTexture, data.TexCoord1).rgb;
|
||||
|
||||
albedo.rgb *= detail;
|
||||
|
||||
float shadow = CalculateShadow(data.ShadowCoords);
|
||||
|
||||
shadow = mix(0.5, 1.0, shadow);
|
||||
|
||||
vec3 normal = mix(-data.Normal, data.Normal, float(gl_FrontFacing));
|
||||
|
||||
vec3 emissive = uni_EmissiveColor * texture(uni_EmissiveTexture, data.TexCoord0).rgb;
|
||||
|
||||
vec3 params = texture(uni_MaterialTexture, data.TexCoord0).xyz;
|
||||
|
||||
float ambientOcclusion = 1.0 + uni_AOStrength * (params.r - 1.0);
|
||||
float roughness = uni_Roughness * params.g;
|
||||
float metalness = uni_Metalness * params.b;
|
||||
|
||||
vec3 color = albedo.rgb;
|
||||
|
||||
color = CalculateLighting(
|
||||
data.Position,
|
||||
normal,
|
||||
color,
|
||||
emissive,
|
||||
shadow,
|
||||
ambientOcclusion,
|
||||
roughness,
|
||||
metalness);
|
||||
|
||||
float dist = length(uni_CameraPosition - data.Position);
|
||||
float fogAmount = clamp((dist - uni_FogRange.x) / (uni_FogRange.y - uni_FogRange.x), 0.0, 1.0);
|
||||
|
||||
color = mix(color, uni_FogColor, fogAmount);
|
||||
|
||||
out_FragColor = vec4(color, 1.0);
|
||||
}
|
|
@ -1,45 +0,0 @@
|
|||
/*
|
||||
* This file is part of the Colobot: Gold Edition source code
|
||||
* Copyright (C) 2001-2021, Daniel Roux, EPSITEC SA & TerranovaTeam
|
||||
* http://epsitec.ch; http://colobot.info; http://github.com/colobot
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see http://gnu.org/licenses
|
||||
*/
|
||||
|
||||
// VERTEX SHADER - UI RENDERER
|
||||
#version 330 core
|
||||
|
||||
layout(location = 0) in vec4 in_VertexCoord;
|
||||
layout(location = 1) in vec2 in_TexCoord;
|
||||
layout(location = 2) in vec4 in_Color;
|
||||
|
||||
uniform Uniforms
|
||||
{
|
||||
mat4 uni_Matrix;
|
||||
vec4 uni_Color;
|
||||
};
|
||||
|
||||
out VertexData
|
||||
{
|
||||
vec4 Color;
|
||||
vec2 TexCoord;
|
||||
} data;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = uni_Matrix * in_VertexCoord;
|
||||
|
||||
data.Color = in_Color;
|
||||
data.TexCoord = in_TexCoord;
|
||||
}
|
|
@ -1,148 +0,0 @@
|
|||
/*
|
||||
* This file is part of the Colobot: Gold Edition source code
|
||||
* Copyright (C) 2001-2023, Daniel Roux, EPSITEC SA & TerranovaTeam
|
||||
* http://epsitec.ch; http://colobot.info; http://github.com/colobot
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see http://gnu.org/licenses
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "object/object.h"
|
||||
#include "object/object_interface_type.h"
|
||||
|
||||
#include "object/interface/power_container_object.h"
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
|
||||
class CObject;
|
||||
|
||||
/**
|
||||
* \class CSlottedObject
|
||||
* \brief Interface for objects that hold other objects
|
||||
*/
|
||||
class CSlottedObject
|
||||
{
|
||||
public:
|
||||
///! Object-independent identifiers for certain special slots
|
||||
enum class Pseudoslot
|
||||
{
|
||||
POWER,
|
||||
CARRYING
|
||||
};
|
||||
|
||||
explicit CSlottedObject(ObjectInterfaceTypes& types)
|
||||
{
|
||||
types[static_cast<int>(ObjectInterfaceType::Slotted)] = true;
|
||||
}
|
||||
virtual ~CSlottedObject()
|
||||
{}
|
||||
|
||||
//! Given one of the PSEUDOSLOT enums, returns real slot number, or -1 if specified pseudoslot is not present in this object.
|
||||
virtual int MapPseudoSlot(Pseudoslot pseudoslot) = 0;
|
||||
|
||||
//! Get number of slots. Valid slot numbers are 0 up to GetNumSlots()-1. Using invalid slot numbers in the other functions will crash the game.
|
||||
virtual int GetNumSlots() = 0;
|
||||
//! Get relative position of a slot.
|
||||
virtual glm::vec3 GetSlotPosition(int slotNum) = 0;
|
||||
//! Get relative angle (in radians) where robot should be positioned when inserting into a slot.
|
||||
virtual float GetSlotAngle(int slotNum) = 0;
|
||||
//! Get the maximum angular distance from the ideal angle (in radians) where robot should be positioned when inserting into a slot.
|
||||
virtual float GetSlotAcceptanceAngle(int slotNum) = 0;
|
||||
//! Get object contained in a slot.
|
||||
virtual CObject *GetSlotContainedObject(int slotNum) = 0;
|
||||
//! Set object contained in a slot.
|
||||
virtual void SetSlotContainedObject(int slotNum, CObject *object) = 0;
|
||||
|
||||
void SetSlotContainedObjectReq(Pseudoslot pseudoslot, CObject *object)
|
||||
{
|
||||
int slotNum = MapPseudoSlot(pseudoslot);
|
||||
assert(slotNum >= 0);
|
||||
SetSlotContainedObject(slotNum, object);
|
||||
}
|
||||
|
||||
CObject *GetSlotContainedObjectOpt(Pseudoslot pseudoslot)
|
||||
{
|
||||
int slotNum = MapPseudoSlot(pseudoslot);
|
||||
return slotNum < 0 ? nullptr : GetSlotContainedObject(slotNum);
|
||||
}
|
||||
|
||||
CObject *GetSlotContainedObjectReq(Pseudoslot pseudoslot)
|
||||
{
|
||||
int slotNum = MapPseudoSlot(pseudoslot);
|
||||
assert(slotNum >= 0);
|
||||
return GetSlotContainedObject(slotNum);
|
||||
}
|
||||
};
|
||||
|
||||
inline bool HasPowerCellSlot(CObject *object)
|
||||
{
|
||||
if (object->Implements(ObjectInterfaceType::Slotted))
|
||||
{
|
||||
return dynamic_cast<CSlottedObject&>(*object).MapPseudoSlot(CSlottedObject::Pseudoslot::POWER) >= 0;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
inline CObject *GetObjectInPowerCellSlot(CObject *object)
|
||||
{
|
||||
if (object->Implements(ObjectInterfaceType::Slotted))
|
||||
{
|
||||
return dynamic_cast<CSlottedObject&>(*object).GetSlotContainedObjectOpt(CSlottedObject::Pseudoslot::POWER);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
inline CPowerContainerObject *GetObjectPowerCell(CObject *object)
|
||||
{
|
||||
if (CObject *powerSlotObj = GetObjectInPowerCellSlot(object))
|
||||
{
|
||||
if (powerSlotObj->Implements(ObjectInterfaceType::PowerContainer))
|
||||
{
|
||||
return dynamic_cast<CPowerContainerObject*>(powerSlotObj);
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
inline float GetObjectEnergy(CObject* object)
|
||||
{
|
||||
if (CPowerContainerObject* power = GetObjectPowerCell(object))
|
||||
return power->GetEnergy();
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
inline float GetObjectEnergyLevel(CObject* object)
|
||||
{
|
||||
if (CPowerContainerObject* power = GetObjectPowerCell(object))
|
||||
return power->GetEnergyLevel();
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
inline bool ObjectHasPowerCell(CObject* object)
|
||||
{
|
||||
// XXX: not GetObjectPowerCell? We count e.g. titanium cubes as power cells in this function?
|
||||
return GetObjectInPowerCellSlot(object) != nullptr;
|
||||
}
|
||||
|
||||
inline bool IsObjectCarryingCargo(CObject* object)
|
||||
{
|
||||
if (object->Implements(ObjectInterfaceType::Slotted))
|
||||
{
|
||||
return dynamic_cast<CSlottedObject&>(*object).GetSlotContainedObjectOpt(CSlottedObject::Pseudoslot::CARRYING) != nullptr;
|
||||
}
|
||||
return false;
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -1,236 +0,0 @@
|
|||
/*
|
||||
* This file is part of the Colobot: Gold Edition source code
|
||||
* Copyright (C) 2001-2023, Daniel Roux, EPSITEC SA & TerranovaTeam
|
||||
* http://epsitec.ch; http://colobot.info; http://github.com/colobot
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see http://gnu.org/licenses
|
||||
*/
|
||||
|
||||
#include "object/object_type.h"
|
||||
|
||||
#include <unordered_set>
|
||||
|
||||
bool IsValidObjectTypeId(int id)
|
||||
{
|
||||
static const std::unordered_set<int> validIds{
|
||||
OBJECT_NULL,
|
||||
OBJECT_PORTICO,
|
||||
OBJECT_BASE,
|
||||
OBJECT_DERRICK,
|
||||
OBJECT_FACTORY,
|
||||
OBJECT_STATION,
|
||||
OBJECT_CONVERT,
|
||||
OBJECT_REPAIR,
|
||||
OBJECT_TOWER,
|
||||
OBJECT_NEST,
|
||||
OBJECT_RESEARCH,
|
||||
OBJECT_RADAR,
|
||||
OBJECT_ENERGY,
|
||||
OBJECT_LABO,
|
||||
OBJECT_NUCLEAR,
|
||||
OBJECT_START,
|
||||
OBJECT_END,
|
||||
OBJECT_INFO,
|
||||
OBJECT_PARA,
|
||||
OBJECT_TARGET1,
|
||||
OBJECT_TARGET2,
|
||||
OBJECT_SAFE,
|
||||
OBJECT_HUSTON,
|
||||
OBJECT_DESTROYER,
|
||||
OBJECT_STONE,
|
||||
OBJECT_URANIUM,
|
||||
OBJECT_METAL,
|
||||
OBJECT_POWER,
|
||||
OBJECT_ATOMIC,
|
||||
OBJECT_BULLET,
|
||||
OBJECT_BBOX,
|
||||
OBJECT_TNT,
|
||||
OBJECT_MARKPOWER,
|
||||
OBJECT_MARKSTONE,
|
||||
OBJECT_MARKURANIUM,
|
||||
OBJECT_MARKKEYa,
|
||||
OBJECT_MARKKEYb,
|
||||
OBJECT_MARKKEYc,
|
||||
OBJECT_MARKKEYd,
|
||||
OBJECT_BOMB,
|
||||
OBJECT_WINFIRE,
|
||||
OBJECT_SHOW,
|
||||
OBJECT_BAG,
|
||||
OBJECT_PLANT0,
|
||||
OBJECT_PLANT1,
|
||||
OBJECT_PLANT2,
|
||||
OBJECT_PLANT3,
|
||||
OBJECT_PLANT4,
|
||||
OBJECT_PLANT5,
|
||||
OBJECT_PLANT6,
|
||||
OBJECT_PLANT7,
|
||||
OBJECT_PLANT8,
|
||||
OBJECT_PLANT9,
|
||||
OBJECT_PLANT10,
|
||||
OBJECT_PLANT11,
|
||||
OBJECT_PLANT12,
|
||||
OBJECT_PLANT13,
|
||||
OBJECT_PLANT14,
|
||||
OBJECT_PLANT15,
|
||||
OBJECT_PLANT16,
|
||||
OBJECT_PLANT17,
|
||||
OBJECT_PLANT18,
|
||||
OBJECT_PLANT19,
|
||||
OBJECT_TREE0,
|
||||
OBJECT_TREE1,
|
||||
OBJECT_TREE2,
|
||||
OBJECT_TREE3,
|
||||
OBJECT_TREE4,
|
||||
OBJECT_TREE5,
|
||||
OBJECT_MOBILEwt,
|
||||
OBJECT_MOBILEtt,
|
||||
OBJECT_MOBILEft,
|
||||
OBJECT_MOBILEit,
|
||||
OBJECT_MOBILErp,
|
||||
OBJECT_MOBILEst,
|
||||
OBJECT_MOBILEwa,
|
||||
OBJECT_MOBILEta,
|
||||
OBJECT_MOBILEfa,
|
||||
OBJECT_MOBILEia,
|
||||
OBJECT_MOBILEwc,
|
||||
OBJECT_MOBILEtc,
|
||||
OBJECT_MOBILEfc,
|
||||
OBJECT_MOBILEic,
|
||||
OBJECT_MOBILEwi,
|
||||
OBJECT_MOBILEti,
|
||||
OBJECT_MOBILEfi,
|
||||
OBJECT_MOBILEii,
|
||||
OBJECT_MOBILEws,
|
||||
OBJECT_MOBILEts,
|
||||
OBJECT_MOBILEfs,
|
||||
OBJECT_MOBILEis,
|
||||
OBJECT_MOBILErt,
|
||||
OBJECT_MOBILErc,
|
||||
OBJECT_MOBILErr,
|
||||
OBJECT_MOBILErs,
|
||||
OBJECT_MOBILEsa,
|
||||
OBJECT_MOBILEtg,
|
||||
OBJECT_MOBILEdr,
|
||||
OBJECT_CONTROLLER,
|
||||
OBJECT_MOBILEwb,
|
||||
OBJECT_MOBILEtb,
|
||||
OBJECT_MOBILEfb,
|
||||
OBJECT_MOBILEib,
|
||||
OBJECT_MOBILEpr,
|
||||
OBJECT_WAYPOINT,
|
||||
OBJECT_FLAGb,
|
||||
OBJECT_FLAGr,
|
||||
OBJECT_FLAGg,
|
||||
OBJECT_FLAGy,
|
||||
OBJECT_FLAGv,
|
||||
OBJECT_KEYa,
|
||||
OBJECT_KEYb,
|
||||
OBJECT_KEYc,
|
||||
OBJECT_KEYd,
|
||||
OBJECT_HUMAN,
|
||||
OBJECT_TOTO,
|
||||
OBJECT_TECH,
|
||||
OBJECT_BARRIER0,
|
||||
OBJECT_BARRIER1,
|
||||
OBJECT_BARRIER2,
|
||||
OBJECT_BARRIER3,
|
||||
OBJECT_BARRICADE0,
|
||||
OBJECT_BARRICADE1,
|
||||
OBJECT_MOTHER,
|
||||
OBJECT_EGG,
|
||||
OBJECT_ANT,
|
||||
OBJECT_SPIDER,
|
||||
OBJECT_BEE,
|
||||
OBJECT_WORM,
|
||||
OBJECT_RUINmobilew1,
|
||||
OBJECT_RUINmobilew2,
|
||||
OBJECT_RUINmobilet1,
|
||||
OBJECT_RUINmobilet2,
|
||||
OBJECT_RUINmobiler1,
|
||||
OBJECT_RUINmobiler2,
|
||||
OBJECT_RUINfactory,
|
||||
OBJECT_RUINdoor,
|
||||
OBJECT_RUINsupport,
|
||||
OBJECT_RUINradar,
|
||||
OBJECT_RUINconvert,
|
||||
OBJECT_RUINbase,
|
||||
OBJECT_RUINhead,
|
||||
OBJECT_TEEN0,
|
||||
OBJECT_TEEN1,
|
||||
OBJECT_TEEN2,
|
||||
OBJECT_TEEN3,
|
||||
OBJECT_TEEN4,
|
||||
OBJECT_TEEN5,
|
||||
OBJECT_TEEN6,
|
||||
OBJECT_TEEN7,
|
||||
OBJECT_TEEN8,
|
||||
OBJECT_TEEN9,
|
||||
OBJECT_TEEN10,
|
||||
OBJECT_TEEN11,
|
||||
OBJECT_TEEN12,
|
||||
OBJECT_TEEN13,
|
||||
OBJECT_TEEN14,
|
||||
OBJECT_TEEN15,
|
||||
OBJECT_TEEN16,
|
||||
OBJECT_TEEN17,
|
||||
OBJECT_TEEN18,
|
||||
OBJECT_TEEN19,
|
||||
OBJECT_TEEN20,
|
||||
OBJECT_TEEN21,
|
||||
OBJECT_TEEN22,
|
||||
OBJECT_TEEN23,
|
||||
OBJECT_TEEN24,
|
||||
OBJECT_TEEN25,
|
||||
OBJECT_TEEN26,
|
||||
OBJECT_TEEN27,
|
||||
OBJECT_TEEN28,
|
||||
OBJECT_TEEN29,
|
||||
OBJECT_TEEN30,
|
||||
OBJECT_TEEN31,
|
||||
OBJECT_TEEN32,
|
||||
OBJECT_TEEN33,
|
||||
OBJECT_TEEN34,
|
||||
OBJECT_TEEN35,
|
||||
OBJECT_TEEN36,
|
||||
OBJECT_TEEN37,
|
||||
OBJECT_TEEN38,
|
||||
OBJECT_TEEN39,
|
||||
OBJECT_TEEN40,
|
||||
OBJECT_TEEN41,
|
||||
OBJECT_TEEN42,
|
||||
OBJECT_TEEN43,
|
||||
OBJECT_TEEN44,
|
||||
OBJECT_QUARTZ0,
|
||||
OBJECT_QUARTZ1,
|
||||
OBJECT_QUARTZ2,
|
||||
OBJECT_QUARTZ3,
|
||||
OBJECT_ROOT0,
|
||||
OBJECT_ROOT1,
|
||||
OBJECT_ROOT2,
|
||||
OBJECT_ROOT3,
|
||||
OBJECT_ROOT4,
|
||||
OBJECT_ROOT5,
|
||||
OBJECT_MUSHROOM1,
|
||||
OBJECT_MUSHROOM2,
|
||||
OBJECT_APOLLO1,
|
||||
OBJECT_APOLLO2,
|
||||
OBJECT_APOLLO3,
|
||||
OBJECT_APOLLO4,
|
||||
OBJECT_APOLLO5,
|
||||
OBJECT_HOME1,
|
||||
|
||||
OBJECT_MAX
|
||||
};
|
||||
return validIds.count(id);
|
||||
}
|
|
@ -1,893 +0,0 @@
|
|||
/*
|
||||
* This file is part of the Colobot: Gold Edition source code
|
||||
* Copyright (C) 2001-2023, Daniel Roux, EPSITEC SA & TerranovaTeam
|
||||
* http://epsitec.ch; http://colobot.info; http://github.com/colobot
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see http://gnu.org/licenses
|
||||
*/
|
||||
|
||||
#include "object/subclass/base_building.h"
|
||||
|
||||
#include "graphics/engine/engine.h"
|
||||
#include "graphics/engine/oldmodelmanager.h"
|
||||
#include "graphics/engine/terrain.h"
|
||||
|
||||
#include "math/geometry.h"
|
||||
|
||||
#include "object/object_create_params.h"
|
||||
|
||||
#include "object/auto/autobase.h"
|
||||
#include "object/auto/autoconvert.h"
|
||||
#include "object/auto/autoderrick.h"
|
||||
#include "object/auto/autodestroyer.h"
|
||||
#include "object/auto/autofactory.h"
|
||||
#include "object/auto/autohouston.h"
|
||||
#include "object/auto/autolabo.h"
|
||||
#include "object/auto/autonest.h"
|
||||
#include "object/auto/autonuclearplant.h"
|
||||
#include "object/auto/autoportico.h"
|
||||
#include "object/auto/autopowercaptor.h"
|
||||
#include "object/auto/autopowerplant.h"
|
||||
#include "object/auto/autopowerstation.h"
|
||||
#include "object/auto/autoradar.h"
|
||||
#include "object/auto/autorepair.h"
|
||||
#include "object/auto/autoresearch.h"
|
||||
#include "object/auto/autotower.h"
|
||||
#include "object/auto/autovault.h"
|
||||
|
||||
|
||||
CBaseBuilding::CBaseBuilding(int id, ObjectType type)
|
||||
: COldObject(id)
|
||||
{
|
||||
SetType(type);
|
||||
}
|
||||
|
||||
CBaseBuilding::~CBaseBuilding()
|
||||
{}
|
||||
|
||||
std::unique_ptr<CBaseBuilding> CBaseBuilding::Create(
|
||||
const ObjectCreateParams& params,
|
||||
Gfx::COldModelManager* modelManager,
|
||||
Gfx::CEngine* engine)
|
||||
{
|
||||
auto obj = std::make_unique<CBaseBuilding>(params.id, params.type);
|
||||
|
||||
obj->SetTrainer(params.trainer || obj->GetPlusTrainer());
|
||||
obj->SetTeam(params.team);
|
||||
|
||||
float height = params.height;
|
||||
|
||||
int rank = engine->CreateObject(obj.get());
|
||||
engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_FIX); // it is a stationary object
|
||||
obj->SetObjectRank(0, rank);
|
||||
|
||||
if ( params.type == OBJECT_PORTICO )
|
||||
{
|
||||
modelManager->AddModelReference("portico1", false, rank, params.team);
|
||||
obj->SetPosition(params.pos);
|
||||
obj->SetRotationY(params.angle);
|
||||
obj->SetFloorHeight(0.0f);
|
||||
|
||||
rank = engine->CreateObject(obj.get());
|
||||
engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_DESCENDANT);
|
||||
obj->SetObjectRank(1, rank);
|
||||
obj->SetObjectParent(1, 0);
|
||||
modelManager->AddModelReference("portico2", false, rank, params.team);
|
||||
obj->SetPartPosition(1, glm::vec3(0.0f, 67.0f, 0.0f));
|
||||
|
||||
rank = engine->CreateObject(obj.get());
|
||||
engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_DESCENDANT);
|
||||
obj->SetObjectRank(2, rank);
|
||||
obj->SetObjectParent(2, 1);
|
||||
modelManager->AddModelReference("portico3", false, rank, params.team);
|
||||
obj->SetPartPosition(2, glm::vec3(0.0f, 0.0f, -33.0f));
|
||||
obj->SetPartRotationY(2, 45.0f*Math::PI/180.0f);
|
||||
|
||||
rank = engine->CreateObject(obj.get());
|
||||
engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_DESCENDANT);
|
||||
obj->SetObjectRank(3, rank);
|
||||
obj->SetObjectParent(3, 2);
|
||||
modelManager->AddModelReference("portico4", false, rank, params.team);
|
||||
obj->SetPartPosition(3, glm::vec3(50.0f, 0.0f, 0.0f));
|
||||
obj->SetPartRotationY(3, -60.0f*Math::PI/180.0f);
|
||||
|
||||
rank = engine->CreateObject(obj.get());
|
||||
engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_DESCENDANT);
|
||||
obj->SetObjectRank(4, rank);
|
||||
obj->SetObjectParent(4, 3);
|
||||
modelManager->AddModelReference("portico5", false, rank, params.team);
|
||||
obj->SetPartPosition(4, glm::vec3(35.0f, 0.0f, 0.0f));
|
||||
obj->SetPartRotationY(4, -55.0f*Math::PI/180.0f);
|
||||
|
||||
rank = engine->CreateObject(obj.get());
|
||||
engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_DESCENDANT);
|
||||
obj->SetObjectRank(5, rank);
|
||||
obj->SetObjectParent(5, 1);
|
||||
modelManager->AddModelReference("portico3", false, rank, params.team);
|
||||
obj->SetPartPosition(5, glm::vec3(0.0f, 0.0f, 33.0f));
|
||||
obj->SetPartRotationY(5, -45.0f*Math::PI/180.0f);
|
||||
|
||||
rank = engine->CreateObject(obj.get());
|
||||
engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_DESCENDANT);
|
||||
obj->SetObjectRank(6, rank);
|
||||
obj->SetObjectParent(6, 5);
|
||||
modelManager->AddModelReference("portico4", false, rank, params.team);
|
||||
obj->SetPartPosition(6, glm::vec3(50.0f, 0.0f, 0.0f));
|
||||
obj->SetPartRotationY(6, 60.0f*Math::PI/180.0f);
|
||||
|
||||
rank = engine->CreateObject(obj.get());
|
||||
engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_DESCENDANT);
|
||||
obj->SetObjectRank(7, rank);
|
||||
obj->SetObjectParent(7, 6);
|
||||
modelManager->AddModelReference("portico5", false, rank, params.team);
|
||||
obj->SetPartPosition(7, glm::vec3(35.0f, 0.0f, 0.0f));
|
||||
obj->SetPartRotationY(7, 55.0f*Math::PI/180.0f);
|
||||
|
||||
rank = engine->CreateObject(obj.get());
|
||||
engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_DESCENDANT);
|
||||
obj->SetObjectRank(8, rank);
|
||||
obj->SetObjectParent(8, 0);
|
||||
modelManager->AddModelReference("portico6", false, rank, params.team);
|
||||
obj->SetPartPosition(8, glm::vec3(-35.0f, 50.0f, -35.0f));
|
||||
obj->SetPartRotationY(8, -Math::PI/2.0f);
|
||||
obj->SetPartScale(8, 2.0f);
|
||||
|
||||
rank = engine->CreateObject(obj.get());
|
||||
engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_DESCENDANT);
|
||||
obj->SetObjectRank(9, rank);
|
||||
obj->SetObjectParent(9, 8);
|
||||
modelManager->AddModelReference("portico7", false, rank, params.team);
|
||||
obj->SetPartPosition(9, glm::vec3(0.0f, 4.5f, 1.9f));
|
||||
|
||||
rank = engine->CreateObject(obj.get());
|
||||
engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_DESCENDANT);
|
||||
obj->SetObjectRank(10, rank);
|
||||
obj->SetObjectParent(10, 0);
|
||||
modelManager->AddModelReference("portico6", false, rank, params.team);
|
||||
obj->SetPartPosition(10, glm::vec3(-35.0f, 50.0f, 35.0f));
|
||||
obj->SetPartRotationY(10, -Math::PI/2.0f);
|
||||
obj->SetPartScale(10, 2.0f);
|
||||
|
||||
rank = engine->CreateObject(obj.get());
|
||||
engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_DESCENDANT);
|
||||
obj->SetObjectRank(11, rank);
|
||||
obj->SetObjectParent(11, 10);
|
||||
modelManager->AddModelReference("portico7", false, rank, params.team);
|
||||
obj->SetPartPosition(11, glm::vec3(0.0f, 4.5f, 1.9f));
|
||||
|
||||
obj->AddCrashSphere(CrashSphere(glm::vec3( 0.0f, 28.0f, 0.0f), 45.5f, SOUND_BOUMm, 0.45f));
|
||||
obj->AddCrashSphere(CrashSphere(glm::vec3( 27.0f, 10.0f, -42.0f), 15.0f, SOUND_BOUMm, 0.45f));
|
||||
obj->AddCrashSphere(CrashSphere(glm::vec3( 0.0f, 10.0f, -42.0f), 15.0f, SOUND_BOUMm, 0.45f));
|
||||
obj->AddCrashSphere(CrashSphere(glm::vec3(-27.0f, 10.0f, -42.0f), 15.0f, SOUND_BOUMm, 0.45f));
|
||||
obj->AddCrashSphere(CrashSphere(glm::vec3( 27.0f, 10.0f, 42.0f), 15.0f, SOUND_BOUMm, 0.45f));
|
||||
obj->AddCrashSphere(CrashSphere(glm::vec3( 0.0f, 10.0f, 42.0f), 15.0f, SOUND_BOUMm, 0.45f));
|
||||
obj->AddCrashSphere(CrashSphere(glm::vec3(-27.0f, 10.0f, 42.0f), 15.0f, SOUND_BOUMm, 0.45f));
|
||||
obj->AddCrashSphere(CrashSphere(glm::vec3(-32.0f, 45.0f, -32.0f), 10.0f, SOUND_BOUMm, 0.45f));
|
||||
obj->AddCrashSphere(CrashSphere(glm::vec3(-32.0f, 45.0f, 32.0f), 10.0f, SOUND_BOUMm, 0.45f));
|
||||
obj->AddCrashSphere(CrashSphere(glm::vec3( 32.0f, 45.0f, -32.0f), 10.0f, SOUND_BOUMm, 0.45f));
|
||||
obj->AddCrashSphere(CrashSphere(glm::vec3( 32.0f, 45.0f, 32.0f), 10.0f, SOUND_BOUMm, 0.45f));
|
||||
obj->SetCameraCollisionSphere(Math::Sphere(glm::vec3(0.0f, 35.0f, 0.0f), 50.0f));
|
||||
|
||||
obj->CreateShadowCircle(50.0f, 1.0f);
|
||||
}
|
||||
|
||||
if ( params.type == OBJECT_BASE )
|
||||
{
|
||||
modelManager->AddModelReference("base1", false, rank, params.team);
|
||||
obj->SetPosition(params.pos);
|
||||
obj->SetRotationY(params.angle);
|
||||
obj->SetFloorHeight(0.0f);
|
||||
|
||||
for (int i=0 ; i<8 ; i++ )
|
||||
{
|
||||
rank = engine->CreateObject(obj.get());
|
||||
engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_DESCENDANT);
|
||||
obj->SetObjectRank(1+i, rank);
|
||||
obj->SetObjectParent(1+i, 0);
|
||||
modelManager->AddModelReference("base2", false, rank, params.team);
|
||||
glm::vec2 p = Math::RotatePoint(-Math::PI/4.0f*i, 27.8f);
|
||||
obj->SetPartPosition(1+i, glm::vec3(p.x, 30.0f, p.y));
|
||||
obj->SetPartRotationY(1+i, Math::PI/4.0f*i);
|
||||
obj->SetPartRotationZ(1+i, Math::PI/2.0f);
|
||||
|
||||
rank = engine->CreateObject(obj.get());
|
||||
engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_DESCENDANT);
|
||||
obj->SetObjectRank(10+i, rank);
|
||||
obj->SetObjectParent(10+i, 1+i);
|
||||
modelManager->AddModelReference("base4", false, rank, params.team);
|
||||
obj->SetPartPosition(10+i, glm::vec3(23.5f, 0.0f, 7.0f));
|
||||
|
||||
rank = engine->CreateObject(obj.get());
|
||||
engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_DESCENDANT);
|
||||
obj->SetObjectRank(18+i, rank);
|
||||
obj->SetObjectParent(18+i, 1+i);
|
||||
modelManager->AddModelReference("base4", true, rank, params.team);
|
||||
obj->SetPartPosition(18+i, glm::vec3(23.5f, 0.0f, -7.0f));
|
||||
}
|
||||
|
||||
rank = engine->CreateObject(obj.get());
|
||||
engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_DESCENDANT);
|
||||
obj->SetObjectRank(9, rank);
|
||||
obj->SetObjectParent(9, 0);
|
||||
modelManager->AddModelReference("base3", false, rank, params.team); // central pillar
|
||||
|
||||
obj->AddCrashSphere(CrashSphere(glm::vec3( 0.0f, 33.0f, 0.0f), 2.5f, SOUND_BOUMm, 0.45f));
|
||||
obj->AddCrashSphere(CrashSphere(glm::vec3( 0.0f, 39.0f, 0.0f), 2.5f, SOUND_BOUMm, 0.45f));
|
||||
obj->AddCrashSphere(CrashSphere(glm::vec3( 0.0f, 45.0f, 0.0f), 2.5f, SOUND_BOUMm, 0.45f));
|
||||
obj->AddCrashSphere(CrashSphere(glm::vec3( 0.0f, 51.0f, 0.0f), 2.5f, SOUND_BOUMm, 0.45f));
|
||||
obj->AddCrashSphere(CrashSphere(glm::vec3( 0.0f, 57.0f, 0.0f), 2.5f, SOUND_BOUMm, 0.45f));
|
||||
obj->AddCrashSphere(CrashSphere(glm::vec3( 0.0f, 63.0f, 0.0f), 2.5f, SOUND_BOUMm, 0.45f));
|
||||
obj->AddCrashSphere(CrashSphere(glm::vec3( 0.0f, 69.0f, 0.0f), 2.5f, SOUND_BOUMm, 0.45f));
|
||||
obj->AddCrashSphere(CrashSphere(glm::vec3( 0.0f, 82.0f, 0.0f), 8.0f, SOUND_BOUMm, 0.45f));
|
||||
obj->AddCrashSphere(CrashSphere(glm::vec3( 18.0f, 94.0f, 0.0f), 10.0f, SOUND_BOUMm, 0.45f));
|
||||
obj->AddCrashSphere(CrashSphere(glm::vec3(-18.0f, 94.0f, 0.0f), 10.0f, SOUND_BOUMm, 0.45f));
|
||||
obj->AddCrashSphere(CrashSphere(glm::vec3( 0.0f, 94.0f, 18.0f), 10.0f, SOUND_BOUMm, 0.45f));
|
||||
obj->AddCrashSphere(CrashSphere(glm::vec3( 0.0f, 94.0f, -18.0f), 10.0f, SOUND_BOUMm, 0.45f));
|
||||
obj->AddCrashSphere(CrashSphere(glm::vec3( 13.0f, 94.0f, 13.0f), 10.0f, SOUND_BOUMm, 0.45f));
|
||||
obj->AddCrashSphere(CrashSphere(glm::vec3(-13.0f, 94.0f, 13.0f), 10.0f, SOUND_BOUMm, 0.45f));
|
||||
obj->AddCrashSphere(CrashSphere(glm::vec3( 13.0f, 94.0f, -13.0f), 10.0f, SOUND_BOUMm, 0.45f));
|
||||
obj->AddCrashSphere(CrashSphere(glm::vec3(-13.0f, 94.0f, -13.0f), 10.0f, SOUND_BOUMm, 0.45f));
|
||||
obj->AddCrashSphere(CrashSphere(glm::vec3( 0.0f,104.0f, 0.0f), 14.0f, SOUND_BOUMm, 0.45f));
|
||||
|
||||
obj->SetCameraCollisionSphere(Math::Sphere(glm::vec3(0.0f, 45.0f, 0.0f), 10.0f));
|
||||
|
||||
obj->CreateShadowCircle(60.0f, 1.0f);
|
||||
|
||||
engine->GetTerrain()->AddBuildingLevel(params.pos, 28.6f, 73.4f, 30.0f, 0.4f);
|
||||
}
|
||||
|
||||
if ( params.type == OBJECT_DERRICK )
|
||||
{
|
||||
modelManager->AddModelReference("derrick1", false, rank, params.team);
|
||||
obj->SetPosition(params.pos);
|
||||
obj->SetRotationY(params.angle);
|
||||
obj->SetFloorHeight(0.0f);
|
||||
|
||||
rank = engine->CreateObject(obj.get());
|
||||
engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_DESCENDANT);
|
||||
obj->SetObjectRank(1, rank);
|
||||
obj->SetObjectParent(1, 0);
|
||||
modelManager->AddModelReference("derrick2", false, rank, params.team);
|
||||
|
||||
obj->AddCrashSphere(CrashSphere(glm::vec3(0.0f, 0.0f, 0.0f), 6.0f, SOUND_BOUMm, 0.45f));
|
||||
obj->AddCrashSphere(CrashSphere(glm::vec3(0.0f, 10.0f, 0.0f), 5.0f, SOUND_BOUMm, 0.45f));
|
||||
obj->AddCrashSphere(CrashSphere(glm::vec3(0.0f, 17.0f, 0.0f), 6.0f, SOUND_BOUMm, 0.45f));
|
||||
obj->AddCrashSphere(CrashSphere(glm::vec3(0.0f, 26.0f, 0.0f), 3.0f, SOUND_BOUMm, 0.45f));
|
||||
obj->AddCrashSphere(CrashSphere(glm::vec3(7.0f, 17.0f, 0.0f), 3.0f, SOUND_BOUMm, 0.45f));
|
||||
obj->SetCameraCollisionSphere(Math::Sphere(glm::vec3(0.0f, 10.0f, 0.0f), 10.0f));
|
||||
|
||||
obj->CreateShadowCircle(10.0f, 0.4f);
|
||||
}
|
||||
|
||||
if ( params.type == OBJECT_RESEARCH )
|
||||
{
|
||||
modelManager->AddModelReference("search1", false, rank, params.team);
|
||||
obj->SetPosition(params.pos);
|
||||
obj->SetRotationY(params.angle);
|
||||
obj->SetFloorHeight(0.0f);
|
||||
|
||||
rank = engine->CreateObject(obj.get());
|
||||
engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_DESCENDANT);
|
||||
obj->SetObjectRank(1, rank);
|
||||
obj->SetObjectParent(1, 0);
|
||||
modelManager->AddModelReference("search2", false, rank, params.team);
|
||||
obj->SetPartPosition(1, glm::vec3(0.0f, 13.0f, 0.0f));
|
||||
|
||||
rank = engine->CreateObject(obj.get());
|
||||
engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_DESCENDANT);
|
||||
obj->SetObjectRank(2, rank);
|
||||
obj->SetObjectParent(2, 1);
|
||||
modelManager->AddModelReference("search3", false, rank, params.team);
|
||||
obj->SetPartPosition(2, glm::vec3(0.0f, 4.0f, 0.0f));
|
||||
obj->SetPartRotationZ(2, 35.0f*Math::PI/180.0f);
|
||||
|
||||
obj->AddCrashSphere(CrashSphere(glm::vec3(0.0f, 0.0f, 0.0f), 9.0f, SOUND_BOUMm, 0.45f));
|
||||
obj->AddCrashSphere(CrashSphere(glm::vec3(0.0f, 6.0f, 0.0f), 9.0f, SOUND_BOUMm, 0.45f));
|
||||
obj->AddCrashSphere(CrashSphere(glm::vec3(0.0f, 14.0f, 0.0f), 7.0f, SOUND_BOUMm, 0.45f));
|
||||
obj->SetCameraCollisionSphere(Math::Sphere(glm::vec3(0.0f, 8.0f, 0.0f), 12.0f));
|
||||
|
||||
obj->SetPowerPosition(glm::vec3(7.5f, 3.0f, 0.0f));
|
||||
|
||||
obj->CreateShadowCircle(12.0f, 1.0f);
|
||||
}
|
||||
|
||||
if ( params.type == OBJECT_RADAR )
|
||||
{
|
||||
modelManager->AddModelReference("radar1", false, rank, params.team);
|
||||
obj->SetPosition(params.pos);
|
||||
obj->SetRotationY(params.angle);
|
||||
obj->SetFloorHeight(0.0f);
|
||||
|
||||
rank = engine->CreateObject(obj.get());
|
||||
engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_DESCENDANT);
|
||||
obj->SetObjectRank(1, rank);
|
||||
obj->SetObjectParent(1, 0);
|
||||
modelManager->AddModelReference("radar2", false, rank, params.team);
|
||||
obj->SetPartPosition(1, glm::vec3(0.0f, 5.0f, 0.0f));
|
||||
|
||||
rank = engine->CreateObject(obj.get());
|
||||
engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_DESCENDANT);
|
||||
obj->SetObjectRank(2, rank);
|
||||
obj->SetObjectParent(2, 0);
|
||||
modelManager->AddModelReference("radar3", false, rank, params.team);
|
||||
obj->SetPartPosition(2, glm::vec3(0.0f, 11.0f, 0.0f));
|
||||
obj->SetPartRotationY(2, -Math::PI/2.0f);
|
||||
|
||||
rank = engine->CreateObject(obj.get());
|
||||
engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_DESCENDANT);
|
||||
obj->SetObjectRank(3, rank);
|
||||
obj->SetObjectParent(3, 2);
|
||||
modelManager->AddModelReference("radar4", false, rank, params.team);
|
||||
obj->SetPartPosition(3, glm::vec3(0.0f, 4.5f, 1.9f));
|
||||
|
||||
obj->AddCrashSphere(CrashSphere(glm::vec3(0.0f, 3.0f, 0.0f), 6.0f, SOUND_BOUMm, 0.45f));
|
||||
obj->AddCrashSphere(CrashSphere(glm::vec3(0.0f, 11.0f, 0.0f), 6.0f, SOUND_BOUMm, 0.45f));
|
||||
obj->SetCameraCollisionSphere(Math::Sphere(glm::vec3(0.0f, 7.0f, 0.0f), 7.0f));
|
||||
|
||||
obj->CreateShadowCircle(8.0f, 1.0f);
|
||||
}
|
||||
|
||||
if ( params.type == OBJECT_ENERGY )
|
||||
{
|
||||
modelManager->AddModelCopy("energy", false, rank, params.team);
|
||||
obj->SetPosition(params.pos);
|
||||
obj->SetRotationY(params.angle);
|
||||
obj->SetFloorHeight(0.0f);
|
||||
|
||||
obj->AddCrashSphere(CrashSphere(glm::vec3(-2.0f, 13.0f, 0.0f), 6.0f, SOUND_BOUMm, 0.45f));
|
||||
obj->AddCrashSphere(CrashSphere(glm::vec3(-7.0f, 3.0f, 0.0f), 5.0f, SOUND_BOUMm, 0.45f));
|
||||
obj->AddCrashSphere(CrashSphere(glm::vec3( 0.0f, 1.0f, 0.0f), 1.5f, SOUND_BOUMm, 0.45f));
|
||||
obj->SetCameraCollisionSphere(Math::Sphere(glm::vec3(-7.0f, 5.0f, 0.0f), 5.0f));
|
||||
|
||||
obj->SetPowerPosition(glm::vec3(0.0f, 3.0f, 0.0f));
|
||||
obj->SetEnergyLevel(params.power); // initializes the energy level
|
||||
|
||||
obj->CreateShadowCircle(6.0f, 0.5f);
|
||||
}
|
||||
|
||||
if ( params.type == OBJECT_LABO )
|
||||
{
|
||||
modelManager->AddModelReference("labo1", false, rank, params.team);
|
||||
obj->SetPosition(params.pos);
|
||||
obj->SetRotationY(params.angle);
|
||||
obj->SetFloorHeight(0.0f);
|
||||
|
||||
rank = engine->CreateObject(obj.get());
|
||||
engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_DESCENDANT);
|
||||
obj->SetObjectRank(1, rank);
|
||||
obj->SetObjectParent(1, 0);
|
||||
modelManager->AddModelReference("labo2", false, rank, params.team);
|
||||
obj->SetPartPosition(1, glm::vec3(-9.0f, 3.0f, 0.0f));
|
||||
obj->SetPartRotationZ(1, Math::PI/2.0f);
|
||||
|
||||
rank = engine->CreateObject(obj.get());
|
||||
engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_DESCENDANT);
|
||||
obj->SetObjectRank(2, rank);
|
||||
obj->SetObjectParent(2, 1);
|
||||
modelManager->AddModelReference("labo3", false, rank, params.team);
|
||||
obj->SetPartPosition(2, glm::vec3(9.0f, -1.0f, 0.0f));
|
||||
|
||||
rank = engine->CreateObject(obj.get());
|
||||
engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_DESCENDANT);
|
||||
obj->SetObjectRank(3, rank);
|
||||
obj->SetObjectParent(3, 2);
|
||||
modelManager->AddModelReference("labo4", false, rank, params.team);
|
||||
obj->SetPartPosition(3, glm::vec3(0.0f, 0.0f, 0.0f));
|
||||
obj->SetPartRotationZ(3, 80.0f*Math::PI/180.0f);
|
||||
|
||||
rank = engine->CreateObject(obj.get());
|
||||
engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_DESCENDANT);
|
||||
obj->SetObjectRank(4, rank);
|
||||
obj->SetObjectParent(4, 2);
|
||||
modelManager->AddModelReference("labo4", false, rank, params.team);
|
||||
obj->SetPartPosition(4, glm::vec3(0.0f, 0.0f, 0.0f));
|
||||
obj->SetPartRotationZ(4, 80.0f*Math::PI/180.0f);
|
||||
obj->SetPartRotationY(4, Math::PI*2.0f/3.0f);
|
||||
|
||||
rank = engine->CreateObject(obj.get());
|
||||
engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_DESCENDANT);
|
||||
obj->SetObjectRank(5, rank);
|
||||
obj->SetObjectParent(5, 2);
|
||||
modelManager->AddModelReference("labo4", false, rank, params.team);
|
||||
obj->SetPartPosition(5, glm::vec3(0.0f, 0.0f, 0.0f));
|
||||
obj->SetPartRotationZ(5, 80.0f*Math::PI/180.0f);
|
||||
obj->SetPartRotationY(5, -Math::PI*2.0f/3.0f);
|
||||
|
||||
obj->AddCrashSphere(CrashSphere(glm::vec3( 0.0f, 1.0f, 0.0f), 1.5f, SOUND_BOUMm, 0.45f));
|
||||
obj->AddCrashSphere(CrashSphere(glm::vec3( 0.0f, 11.0f, 0.0f), 4.0f, SOUND_BOUMm, 0.45f));
|
||||
obj->AddCrashSphere(CrashSphere(glm::vec3(-10.0f, 10.0f, 0.0f), 4.0f, SOUND_BOUMm, 0.45f));
|
||||
obj->AddCrashSphere(CrashSphere(glm::vec3(-12.0f, 3.0f, 3.0f), 4.0f, SOUND_BOUMm, 0.45f));
|
||||
obj->AddCrashSphere(CrashSphere(glm::vec3(-12.0f, 3.0f, -3.0f), 4.0f, SOUND_BOUMm, 0.45f));
|
||||
obj->SetCameraCollisionSphere(Math::Sphere(glm::vec3(-10.0f, 5.0f, 0.0f), 7.0f));
|
||||
|
||||
obj->SetPowerPosition(glm::vec3(0.0f, 3.0f, 0.0f));
|
||||
|
||||
obj->CreateShadowCircle(7.0f, 0.5f);
|
||||
}
|
||||
|
||||
if ( params.type == OBJECT_FACTORY )
|
||||
{
|
||||
modelManager->AddModelReference("factory1", false, rank, params.team);
|
||||
obj->SetPosition(params.pos);
|
||||
obj->SetRotationY(params.angle);
|
||||
obj->SetFloorHeight(0.0f);
|
||||
|
||||
for (int i=0 ; i<9 ; i++ )
|
||||
{
|
||||
rank = engine->CreateObject(obj.get());
|
||||
engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_DESCENDANT);
|
||||
obj->SetObjectRank(1+i, rank);
|
||||
obj->SetObjectParent(1+i, 0);
|
||||
modelManager->AddModelReference("factory2", false, rank, params.team);
|
||||
obj->SetPartPosition(1+i, glm::vec3(10.0f, 2.0f*i, 10.0f));
|
||||
obj->SetPartRotationZ(1+i, Math::PI/2.0f);
|
||||
obj->SetPartScaleZ(1+i, 0.30f);
|
||||
|
||||
rank = engine->CreateObject(obj.get());
|
||||
engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_DESCENDANT);
|
||||
obj->SetObjectRank(10+i, rank);
|
||||
obj->SetObjectParent(10+i, 0);
|
||||
modelManager->AddModelReference("factory2", false, rank, params.team);
|
||||
obj->SetPartPosition(10+i, glm::vec3(10.0f, 2.0f*i, -10.0f));
|
||||
obj->SetPartRotationZ(10+i, -Math::PI/2.0f);
|
||||
obj->SetPartRotationY(10+i, Math::PI);
|
||||
obj->SetPartScaleZ(10+i, 0.30f);
|
||||
}
|
||||
|
||||
for (int i=0 ; i<2 ; i++ )
|
||||
{
|
||||
float s = static_cast<float>(i*2-1);
|
||||
obj->AddCrashSphere(CrashSphere(glm::vec3(-10.0f, 2.0f, 11.0f*s), 4.0f, SOUND_BOUMm, 0.45f));
|
||||
obj->AddCrashSphere(CrashSphere(glm::vec3( -3.0f, 2.0f, 11.0f*s), 4.0f, SOUND_BOUMm, 0.45f));
|
||||
obj->AddCrashSphere(CrashSphere(glm::vec3( 3.0f, 2.0f, 11.0f*s), 4.0f, SOUND_BOUMm, 0.45f));
|
||||
obj->AddCrashSphere(CrashSphere(glm::vec3( 10.0f, 2.0f, 11.0f*s), 4.0f, SOUND_BOUMm, 0.45f));
|
||||
obj->AddCrashSphere(CrashSphere(glm::vec3(-10.0f, 9.0f, 11.0f*s), 4.0f, SOUND_BOUMm, 0.45f));
|
||||
obj->AddCrashSphere(CrashSphere(glm::vec3( -3.0f, 9.0f, 11.0f*s), 4.0f, SOUND_BOUMm, 0.45f));
|
||||
obj->AddCrashSphere(CrashSphere(glm::vec3( 3.0f, 9.0f, 11.0f*s), 4.0f, SOUND_BOUMm, 0.45f));
|
||||
obj->AddCrashSphere(CrashSphere(glm::vec3( 10.0f, 9.0f, 11.0f*s), 4.0f, SOUND_BOUMm, 0.45f));
|
||||
obj->AddCrashSphere(CrashSphere(glm::vec3(-10.0f, 16.0f, 11.0f*s), 4.0f, SOUND_BOUMm, 0.45f));
|
||||
obj->AddCrashSphere(CrashSphere(glm::vec3( -3.0f, 16.0f, 11.0f*s), 4.0f, SOUND_BOUMm, 0.45f));
|
||||
obj->AddCrashSphere(CrashSphere(glm::vec3( 3.0f, 16.0f, 11.0f*s), 4.0f, SOUND_BOUMm, 0.45f));
|
||||
obj->AddCrashSphere(CrashSphere(glm::vec3( 10.0f, 16.0f, 11.0f*s), 4.0f, SOUND_BOUMm, 0.45f));
|
||||
obj->AddCrashSphere(CrashSphere(glm::vec3(-10.0f, 16.0f, 4.0f*s), 4.0f, SOUND_BOUMm, 0.45f));
|
||||
obj->AddCrashSphere(CrashSphere(glm::vec3( -3.0f, 16.0f, 4.0f*s), 4.0f, SOUND_BOUMm, 0.45f));
|
||||
obj->AddCrashSphere(CrashSphere(glm::vec3( 3.0f, 16.0f, 4.0f*s), 4.0f, SOUND_BOUMm, 0.45f));
|
||||
obj->AddCrashSphere(CrashSphere(glm::vec3( 10.0f, 16.0f, 4.0f*s), 4.0f, SOUND_BOUMm, 0.45f));
|
||||
obj->AddCrashSphere(CrashSphere(glm::vec3(-10.0f, 2.0f, 4.0f*s), 4.0f, SOUND_BOUMm, 0.45f));
|
||||
obj->AddCrashSphere(CrashSphere(glm::vec3(-10.0f, 9.0f, 4.0f*s), 4.0f, SOUND_BOUMm, 0.45f));
|
||||
}
|
||||
obj->AddCrashSphere(CrashSphere(glm::vec3(-10.0f, 21.0f, -4.0f), 3.0f, SOUND_BOUMm, 0.45f));
|
||||
obj->SetCameraCollisionSphere(Math::Sphere(glm::vec3(0.0f, 10.0f, 0.0f), 18.0f));
|
||||
|
||||
obj->CreateShadowCircle(24.0f, 0.3f);
|
||||
}
|
||||
|
||||
if ( params.type == OBJECT_REPAIR )
|
||||
{
|
||||
modelManager->AddModelReference("repair1", false, rank, params.team);
|
||||
obj->SetPosition(params.pos);
|
||||
obj->SetRotationY(params.angle);
|
||||
obj->SetFloorHeight(0.0f);
|
||||
|
||||
rank = engine->CreateObject(obj.get());
|
||||
engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_DESCENDANT);
|
||||
obj->SetObjectRank(1, rank);
|
||||
obj->SetObjectParent(1, 0);
|
||||
modelManager->AddModelReference("repair2", false, rank, params.team);
|
||||
obj->SetPartPosition(1, glm::vec3(-11.0f, 13.5f, 0.0f));
|
||||
obj->SetPartRotationZ(1, Math::PI/2.0f);
|
||||
|
||||
engine->GetTerrain()->AddBuildingLevel(params.pos, 7.0f, 9.0f, 1.0f, 0.5f);
|
||||
|
||||
obj->AddCrashSphere(CrashSphere(glm::vec3(-11.0f, 0.0f, 4.0f), 5.0f, SOUND_BOUMm, 0.45f));
|
||||
obj->AddCrashSphere(CrashSphere(glm::vec3(-11.0f, 0.0f, 0.0f), 5.0f, SOUND_BOUMm, 0.45f));
|
||||
obj->AddCrashSphere(CrashSphere(glm::vec3(-11.0f, 0.0f, -4.0f), 5.0f, SOUND_BOUMm, 0.45f));
|
||||
obj->AddCrashSphere(CrashSphere(glm::vec3(-11.0f, 10.0f, 0.0f), 5.0f, SOUND_BOUMm, 0.45f));
|
||||
obj->SetCameraCollisionSphere(Math::Sphere(glm::vec3(-11.0f, 13.0f, 0.0f), 15.0f));
|
||||
}
|
||||
|
||||
if ( params.type == OBJECT_DESTROYER )
|
||||
{
|
||||
modelManager->AddModelReference("destroy1", false, rank, params.team);
|
||||
obj->SetPosition(params.pos);
|
||||
obj->SetRotationY(params.angle);
|
||||
obj->SetFloorHeight(0.0f);
|
||||
|
||||
rank = engine->CreateObject(obj.get());
|
||||
engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_DESCENDANT);
|
||||
obj->SetObjectRank(1, rank);
|
||||
obj->SetObjectParent(1, 0);
|
||||
modelManager->AddModelReference("destroy2", false, rank, params.team);
|
||||
obj->SetPartPosition(1, glm::vec3(0.0f, 0.0f, 0.0f));
|
||||
|
||||
engine->GetTerrain()->AddBuildingLevel(params.pos, 7.0f, 9.0f, 1.0f, 0.5f);
|
||||
|
||||
obj->AddCrashSphere(CrashSphere(glm::vec3(-3.5f, 0.0f, -13.5f), 4.0f, SOUND_BOUMm, 0.45f));
|
||||
obj->AddCrashSphere(CrashSphere(glm::vec3( 3.5f, 0.0f, -13.5f), 4.0f, SOUND_BOUMm, 0.45f));
|
||||
obj->AddCrashSphere(CrashSphere(glm::vec3(-3.5f, 0.0f, 13.5f), 4.0f, SOUND_BOUMm, 0.45f));
|
||||
obj->AddCrashSphere(CrashSphere(glm::vec3( 3.5f, 0.0f, 13.5f), 4.0f, SOUND_BOUMm, 0.45f));
|
||||
|
||||
obj->CreateShadowCircle(19.0f, 1.0f);
|
||||
}
|
||||
|
||||
if ( params.type == OBJECT_STATION )
|
||||
{
|
||||
modelManager->AddModelCopy("station", false, rank, params.team);
|
||||
obj->SetPosition(params.pos);
|
||||
obj->SetRotationY(params.angle);
|
||||
obj->SetFloorHeight(0.0f);
|
||||
|
||||
engine->GetTerrain()->AddBuildingLevel(params.pos, 7.0f, 9.0f, 1.0f, 0.5f);
|
||||
|
||||
obj->AddCrashSphere(CrashSphere(glm::vec3(-15.0f, 2.0f, 0.0f), 5.0f, SOUND_BOUMm, 0.45f));
|
||||
obj->AddCrashSphere(CrashSphere(glm::vec3(-15.0f, 6.0f, 0.0f), 4.0f, SOUND_BOUMm, 0.45f));
|
||||
obj->SetCameraCollisionSphere(Math::Sphere(glm::vec3(-15.0f, 5.0f, 0.0f), 6.0f));
|
||||
|
||||
obj->SetEnergyLevel(params.power);
|
||||
}
|
||||
|
||||
if ( params.type == OBJECT_CONVERT )
|
||||
{
|
||||
modelManager->AddModelReference("convert1", false, rank, params.team);
|
||||
obj->SetPosition(params.pos);
|
||||
obj->SetRotationY(params.angle);
|
||||
obj->SetFloorHeight(0.0f);
|
||||
|
||||
rank = engine->CreateObject(obj.get());
|
||||
engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_DESCENDANT);
|
||||
obj->SetObjectRank(1, rank);
|
||||
obj->SetObjectParent(1, 0);
|
||||
modelManager->AddModelReference("convert2", false, rank, params.team);
|
||||
obj->SetPartPosition(1, glm::vec3(0.0f, 14.0f, 0.0f));
|
||||
|
||||
rank = engine->CreateObject(obj.get());
|
||||
engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_DESCENDANT);
|
||||
obj->SetObjectRank(2, rank);
|
||||
obj->SetObjectParent(2, 0);
|
||||
modelManager->AddModelReference("convert3", false, rank, params.team);
|
||||
obj->SetPartPosition(2, glm::vec3(0.0f, 11.5f, 0.0f));
|
||||
obj->SetPartRotationX(2, -Math::PI*0.35f);
|
||||
|
||||
rank = engine->CreateObject(obj.get());
|
||||
engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_DESCENDANT);
|
||||
obj->SetObjectRank(3, rank);
|
||||
obj->SetObjectParent(3, 0);
|
||||
modelManager->AddModelReference("convert3", false, rank, params.team);
|
||||
obj->SetPartPosition(3, glm::vec3(0.0f, 11.5f, 0.0f));
|
||||
obj->SetPartRotationY(3, Math::PI);
|
||||
obj->SetPartRotationX(3, -Math::PI*0.35f);
|
||||
|
||||
engine->GetTerrain()->AddBuildingLevel(params.pos, 7.0f, 9.0f, 1.0f, 0.5f);
|
||||
|
||||
obj->AddCrashSphere(CrashSphere(glm::vec3(-10.0f, 2.0f, 4.0f), 5.0f, SOUND_BOUMm, 0.45f));
|
||||
obj->AddCrashSphere(CrashSphere(glm::vec3(-10.0f, 2.0f, -4.0f), 5.0f, SOUND_BOUMm, 0.45f));
|
||||
obj->AddCrashSphere(CrashSphere(glm::vec3(-10.0f, 9.0f, 0.0f), 6.0f, SOUND_BOUMm, 0.45f));
|
||||
obj->AddCrashSphere(CrashSphere(glm::vec3( 0.0f, 14.0f, 0.0f), 1.5f, SOUND_BOUMm, 0.45f));
|
||||
obj->SetCameraCollisionSphere(Math::Sphere(glm::vec3(-3.0f, 8.0f, 0.0f), 14.0f));
|
||||
}
|
||||
|
||||
if ( params.type == OBJECT_TOWER )
|
||||
{
|
||||
modelManager->AddModelReference("tower", false, rank, params.team);
|
||||
obj->SetPosition(params.pos);
|
||||
obj->SetRotationY(params.angle);
|
||||
obj->SetFloorHeight(0.0f);
|
||||
|
||||
rank = engine->CreateObject(obj.get());
|
||||
engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_DESCENDANT);
|
||||
obj->SetObjectRank(1, rank);
|
||||
obj->SetObjectParent(1, 0);
|
||||
modelManager->AddModelReference("roller2c", false, rank, params.team);
|
||||
obj->SetPartPosition(1, glm::vec3(0.0f, 20.0f, 0.0f));
|
||||
obj->SetPartRotationZ(1, Math::PI/2.0f);
|
||||
|
||||
rank = engine->CreateObject(obj.get());
|
||||
engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_DESCENDANT);
|
||||
obj->SetObjectRank(2, rank);
|
||||
obj->SetObjectParent(2, 1);
|
||||
modelManager->AddModelReference("roller3c", false, rank, params.team);
|
||||
obj->SetPartPosition(2, glm::vec3(4.5f, 0.0f, 0.0f));
|
||||
obj->SetPartRotationZ(2, 0.0f);
|
||||
|
||||
obj->AddCrashSphere(CrashSphere(glm::vec3(0.0f, 0.0f, 0.0f), 6.5f, SOUND_BOUMm, 0.45f));
|
||||
obj->AddCrashSphere(CrashSphere(glm::vec3(0.0f, 8.0f, 0.0f), 4.0f, SOUND_BOUMm, 0.45f));
|
||||
obj->AddCrashSphere(CrashSphere(glm::vec3(0.0f, 15.0f, 0.0f), 5.0f, SOUND_BOUMm, 0.45f));
|
||||
obj->AddCrashSphere(CrashSphere(glm::vec3(0.0f, 24.0f, 0.0f), 5.0f, SOUND_BOUMm, 0.45f));
|
||||
obj->SetCameraCollisionSphere(Math::Sphere(glm::vec3(0.0f, 5.0f, 0.0f), 7.0f));
|
||||
|
||||
obj->SetPowerPosition(glm::vec3(5.0f, 3.0f, 0.0f));
|
||||
|
||||
obj->CreateShadowCircle(6.0f, 1.0f);
|
||||
}
|
||||
|
||||
if ( params.type == OBJECT_NUCLEAR )
|
||||
{
|
||||
modelManager->AddModelReference("nuclear1", false, rank, params.team);
|
||||
obj->SetPosition(params.pos);
|
||||
obj->SetRotationY(params.angle);
|
||||
obj->SetFloorHeight(0.0f);
|
||||
|
||||
rank = engine->CreateObject(obj.get());
|
||||
engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_DESCENDANT);
|
||||
obj->SetObjectRank(1, rank);
|
||||
obj->SetObjectParent(1, 0);
|
||||
modelManager->AddModelReference("nuclear2", false, rank, params.team);
|
||||
obj->SetPartPosition(1, glm::vec3(20.0f, 10.0f, 0.0f));
|
||||
obj->SetPartRotationZ(1, 135.0f*Math::PI/180.0f);
|
||||
|
||||
obj->AddCrashSphere(CrashSphere(glm::vec3( 0.0f, 0.0f, 0.0f), 19.0f, SOUND_BOUMm, 0.45f));
|
||||
obj->AddCrashSphere(CrashSphere(glm::vec3( 0.0f, 24.0f, 0.0f), 15.0f, SOUND_BOUMm, 0.45f));
|
||||
obj->AddCrashSphere(CrashSphere(glm::vec3(22.0f, 1.0f, 0.0f), 1.5f, SOUND_BOUMm, 0.45f));
|
||||
obj->SetCameraCollisionSphere(Math::Sphere(glm::vec3(0.0f, 17.0f, 0.0f), 26.0f));
|
||||
|
||||
obj->SetPowerPosition(glm::vec3(22.0f, 3.0f, 0.0f));
|
||||
|
||||
obj->CreateShadowCircle(21.0f, 1.0f);
|
||||
}
|
||||
|
||||
if ( params.type == OBJECT_PARA )
|
||||
{
|
||||
modelManager->AddModelReference("para", false, rank, params.team);
|
||||
obj->SetPosition(params.pos);
|
||||
obj->SetRotationY(params.angle);
|
||||
obj->SetFloorHeight(0.0f);
|
||||
|
||||
engine->GetTerrain()->AddBuildingLevel(params.pos, 16.0f, 18.0f, 1.0f, 0.5f);
|
||||
|
||||
obj->AddCrashSphere(CrashSphere(glm::vec3( 13.0f, 3.0f, 13.0f), 3.0f, SOUND_BOUMm, 0.45f));
|
||||
obj->AddCrashSphere(CrashSphere(glm::vec3( 11.0f, 15.0f, 11.0f), 2.0f, SOUND_BOUMm, 0.45f));
|
||||
obj->AddCrashSphere(CrashSphere(glm::vec3(-13.0f, 3.0f, 13.0f), 3.0f, SOUND_BOUMm, 0.45f));
|
||||
obj->AddCrashSphere(CrashSphere(glm::vec3(-11.0f, 15.0f, -11.0f), 2.0f, SOUND_BOUMm, 0.45f));
|
||||
obj->AddCrashSphere(CrashSphere(glm::vec3( 13.0f, 3.0f, -13.0f), 3.0f, SOUND_BOUMm, 0.45f));
|
||||
obj->AddCrashSphere(CrashSphere(glm::vec3( 11.0f, 15.0f, -11.0f), 2.0f, SOUND_BOUMm, 0.45f));
|
||||
obj->AddCrashSphere(CrashSphere(glm::vec3(-13.0f, 3.0f, -13.0f), 3.0f, SOUND_BOUMm, 0.45f));
|
||||
obj->AddCrashSphere(CrashSphere(glm::vec3(-11.0f, 15.0f, -11.0f), 2.0f, SOUND_BOUMm, 0.45f));
|
||||
obj->AddCrashSphere(CrashSphere(glm::vec3( 0.0f, 26.0f, 0.0f), 9.0f, SOUND_BOUMm, 0.45f));
|
||||
obj->AddCrashSphere(CrashSphere(glm::vec3( 0.0f, 54.0f, 0.0f), 14.0f, SOUND_BOUMm, 0.45f));
|
||||
obj->SetCameraCollisionSphere(Math::Sphere(glm::vec3(0.0f, 10.0f, 0.0f), 20.0f));
|
||||
|
||||
obj->CreateShadowCircle(21.0f, 1.0f);
|
||||
}
|
||||
|
||||
if ( params.type == OBJECT_SAFE )
|
||||
{
|
||||
modelManager->AddModelReference("safe1", false, rank, params.team);
|
||||
obj->SetPosition(params.pos);
|
||||
obj->SetRotationY(params.angle);
|
||||
obj->SetFloorHeight(0.0f);
|
||||
|
||||
rank = engine->CreateObject(obj.get());
|
||||
engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_DESCENDANT);
|
||||
obj->SetObjectRank(1, rank);
|
||||
obj->SetObjectParent(1, 0);
|
||||
modelManager->AddModelReference("safe2", false, rank, params.team);
|
||||
obj->SetPartScale(1, 1.05f);
|
||||
|
||||
rank = engine->CreateObject(obj.get());
|
||||
engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_DESCENDANT);
|
||||
obj->SetObjectRank(2, rank);
|
||||
obj->SetObjectParent(2, 0);
|
||||
modelManager->AddModelReference("safe3", false, rank, params.team);
|
||||
obj->SetPartScale(2, 1.05f);
|
||||
|
||||
engine->GetTerrain()->AddBuildingLevel(params.pos, 18.0f, 20.0f, 1.0f, 0.5f);
|
||||
|
||||
obj->AddCrashSphere(CrashSphere(glm::vec3(0.0f, 1.0f, 0.0f), 13.0f, SOUND_BOUMm, 0.45f));
|
||||
obj->SetCameraCollisionSphere(Math::Sphere(glm::vec3(0.0f, 1.0f, 0.0f), 13.0f));
|
||||
|
||||
obj->CreateShadowCircle(23.0f, 1.0f);
|
||||
}
|
||||
|
||||
if ( params.type == OBJECT_HUSTON )
|
||||
{
|
||||
modelManager->AddModelReference("huston1", false, rank, params.team);
|
||||
obj->SetPosition(params.pos);
|
||||
obj->SetRotationY(params.angle);
|
||||
obj->SetFloorHeight(0.0f);
|
||||
|
||||
rank = engine->CreateObject(obj.get());
|
||||
engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_DESCENDANT);
|
||||
obj->SetObjectRank(1, rank);
|
||||
obj->SetObjectParent(1, 0);
|
||||
modelManager->AddModelReference("huston2", false, rank, params.team);
|
||||
obj->SetPartPosition(1, glm::vec3(0.0f, 39.0f, 30.0f));
|
||||
obj->SetPartRotationY(1, -Math::PI/2.0f);
|
||||
obj->SetPartScale(1, 3.0f);
|
||||
|
||||
rank = engine->CreateObject(obj.get());
|
||||
engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_DESCENDANT);
|
||||
obj->SetObjectRank(2, rank);
|
||||
obj->SetObjectParent(2, 1);
|
||||
modelManager->AddModelReference("huston3", false, rank, params.team);
|
||||
obj->SetPartPosition(2, glm::vec3(0.0f, 4.5f, 1.9f));
|
||||
|
||||
obj->AddCrashSphere(CrashSphere(glm::vec3( 15.0f, 6.0f, -53.0f), 16.0f, SOUND_BOUMm, 0.45f));
|
||||
obj->AddCrashSphere(CrashSphere(glm::vec3(-15.0f, 6.0f, -53.0f), 16.0f, SOUND_BOUMm, 0.45f));
|
||||
obj->AddCrashSphere(CrashSphere(glm::vec3( 15.0f, 6.0f, -26.0f), 16.0f, SOUND_BOUMm, 0.45f));
|
||||
obj->AddCrashSphere(CrashSphere(glm::vec3(-15.0f, 6.0f, -26.0f), 16.0f, SOUND_BOUMm, 0.45f));
|
||||
obj->AddCrashSphere(CrashSphere(glm::vec3( 15.0f, 6.0f, 0.0f), 16.0f, SOUND_BOUMm, 0.45f));
|
||||
obj->AddCrashSphere(CrashSphere(glm::vec3(-15.0f, 6.0f, 0.0f), 16.0f, SOUND_BOUMm, 0.45f));
|
||||
obj->AddCrashSphere(CrashSphere(glm::vec3( 15.0f, 6.0f, 26.0f), 16.0f, SOUND_BOUMm, 0.45f));
|
||||
obj->AddCrashSphere(CrashSphere(glm::vec3(-15.0f, 6.0f, 26.0f), 16.0f, SOUND_BOUMm, 0.45f));
|
||||
obj->AddCrashSphere(CrashSphere(glm::vec3( 15.0f, 6.0f, 53.0f), 16.0f, SOUND_BOUMm, 0.45f));
|
||||
obj->AddCrashSphere(CrashSphere(glm::vec3(-15.0f, 6.0f, 53.0f), 16.0f, SOUND_BOUMm, 0.45f));
|
||||
obj->AddCrashSphere(CrashSphere(glm::vec3( 0.0f, 27.0f, 30.0f), 12.0f, SOUND_BOUMm, 0.45f));
|
||||
obj->AddCrashSphere(CrashSphere(glm::vec3( 0.0f, 45.0f, 30.0f), 14.0f, SOUND_BOUMm, 0.45f));
|
||||
obj->AddCrashSphere(CrashSphere(glm::vec3( 26.0f, 4.0f, -61.0f), 5.0f, SOUND_BOUMm, 0.45f));
|
||||
obj->AddCrashSphere(CrashSphere(glm::vec3(-26.0f, 4.0f, -61.0f), 5.0f, SOUND_BOUMm, 0.45f));
|
||||
obj->AddCrashSphere(CrashSphere(glm::vec3( 26.0f, 4.0f, 61.0f), 5.0f, SOUND_BOUMm, 0.45f));
|
||||
obj->AddCrashSphere(CrashSphere(glm::vec3(-26.0f, 4.0f, 61.0f), 5.0f, SOUND_BOUMm, 0.45f));
|
||||
}
|
||||
|
||||
if ( params.type == OBJECT_TARGET1 )
|
||||
{
|
||||
modelManager->AddModelReference("target1", false, rank, params.team);
|
||||
obj->SetPosition(params.pos);
|
||||
obj->SetRotationY(params.angle);
|
||||
obj->SetScale(1.5f);
|
||||
obj->SetFloorHeight(0.0f);
|
||||
|
||||
obj->AddCrashSphere(CrashSphere(glm::vec3( 0.0f, 50.0f+14.0f, 0.0f), 3.0f, SOUND_BOUMm, 0.45f));
|
||||
obj->AddCrashSphere(CrashSphere(glm::vec3( -7.0f, 50.0f+12.0f, 0.0f), 3.0f, SOUND_BOUMm, 0.45f));
|
||||
obj->AddCrashSphere(CrashSphere(glm::vec3( 7.0f, 50.0f+12.0f, 0.0f), 3.0f, SOUND_BOUMm, 0.45f));
|
||||
obj->AddCrashSphere(CrashSphere(glm::vec3(-12.0f, 50.0f+ 7.0f, 0.0f), 3.0f, SOUND_BOUMm, 0.45f));
|
||||
obj->AddCrashSphere(CrashSphere(glm::vec3( 12.0f, 50.0f+ 7.0f, 0.0f), 3.0f, SOUND_BOUMm, 0.45f));
|
||||
obj->AddCrashSphere(CrashSphere(glm::vec3(-14.0f, 50.0f+ 0.0f, 0.0f), 3.0f, SOUND_BOUMm, 0.45f));
|
||||
obj->AddCrashSphere(CrashSphere(glm::vec3( 14.0f, 50.0f+ 0.0f, 0.0f), 3.0f, SOUND_BOUMm, 0.45f));
|
||||
obj->AddCrashSphere(CrashSphere(glm::vec3(-12.0f, 50.0f- 7.0f, 0.0f), 3.0f, SOUND_BOUMm, 0.45f));
|
||||
obj->AddCrashSphere(CrashSphere(glm::vec3( 12.0f, 50.0f- 7.0f, 0.0f), 3.0f, SOUND_BOUMm, 0.45f));
|
||||
obj->AddCrashSphere(CrashSphere(glm::vec3( -7.0f, 50.0f-12.0f, 0.0f), 3.0f, SOUND_BOUMm, 0.45f));
|
||||
obj->AddCrashSphere(CrashSphere(glm::vec3( 7.0f, 50.0f-12.0f, 0.0f), 3.0f, SOUND_BOUMm, 0.45f));
|
||||
obj->AddCrashSphere(CrashSphere(glm::vec3( 0.0f, 50.0f-14.0f, 0.0f), 3.0f, SOUND_BOUMm, 0.45f));
|
||||
|
||||
obj->AddCrashSphere(CrashSphere(glm::vec3(0.0f, 30.0f, 0.0f), 2.0f, SOUND_BOUMm, 0.45f));
|
||||
obj->AddCrashSphere(CrashSphere(glm::vec3(0.0f, 24.0f, 0.0f), 3.0f, SOUND_BOUMm, 0.45f));
|
||||
obj->AddCrashSphere(CrashSphere(glm::vec3(0.0f, 16.0f, 0.0f), 4.0f, SOUND_BOUMm, 0.45f));
|
||||
obj->AddCrashSphere(CrashSphere(glm::vec3(0.0f, 4.0f, 0.0f), 8.0f, SOUND_BOUMm, 0.45f));
|
||||
|
||||
obj->CreateShadowCircle(15.0f, 1.0f);
|
||||
}
|
||||
|
||||
if ( params.type == OBJECT_TARGET2 )
|
||||
{
|
||||
modelManager->AddModelReference("target2", false, rank, params.team);
|
||||
obj->SetPosition(params.pos);
|
||||
obj->SetRotationY(params.angle);
|
||||
obj->SetFloorHeight(0.0f);
|
||||
|
||||
height += 50.0f*1.5f;
|
||||
}
|
||||
|
||||
if ( params.type == OBJECT_NEST )
|
||||
{
|
||||
modelManager->AddModelReference("nest", false, rank, params.team);
|
||||
obj->SetPosition(params.pos);
|
||||
obj->SetRotationY(params.angle);
|
||||
obj->SetFloorHeight(0.0f);
|
||||
|
||||
engine->GetTerrain()->AddBuildingLevel(params.pos, 3.0f, 5.0f, 1.0f, 0.5f);
|
||||
|
||||
obj->CreateShadowCircle(4.0f, 1.0f);
|
||||
}
|
||||
|
||||
if ( params.type == OBJECT_START )
|
||||
{
|
||||
modelManager->AddModelReference("start", false, rank, params.team);
|
||||
obj->SetPosition(params.pos);
|
||||
obj->SetRotationY(params.angle);
|
||||
obj->SetFloorHeight(0.0f);
|
||||
|
||||
engine->GetTerrain()->AddBuildingLevel(params.pos, 7.0f, 9.0f, 1.0f, 0.5f);
|
||||
}
|
||||
|
||||
if ( params.type == OBJECT_END )
|
||||
{
|
||||
modelManager->AddModelReference("end", false, rank, params.team);
|
||||
obj->SetPosition(params.pos);
|
||||
obj->SetRotationY(params.angle);
|
||||
obj->SetFloorHeight(0.0f);
|
||||
|
||||
engine->GetTerrain()->AddBuildingLevel(params.pos, 7.0f, 9.0f, 1.0f, 0.5f);
|
||||
}
|
||||
|
||||
glm::vec3 pos = obj->GetPosition();
|
||||
pos.y += height;
|
||||
obj->SetPosition(pos); // to display the shadows immediately
|
||||
|
||||
std::unique_ptr<CAuto> objAuto;
|
||||
if ( params.type == OBJECT_BASE )
|
||||
{
|
||||
objAuto = std::make_unique<CAutoBase>(obj.get());
|
||||
}
|
||||
if ( params.type == OBJECT_PORTICO )
|
||||
{
|
||||
objAuto = std::make_unique<CAutoPortico>(obj.get());
|
||||
}
|
||||
if ( params.type == OBJECT_DERRICK )
|
||||
{
|
||||
objAuto = std::make_unique<CAutoDerrick>(obj.get());
|
||||
}
|
||||
if ( params.type == OBJECT_FACTORY )
|
||||
{
|
||||
objAuto = std::make_unique<CAutoFactory>(obj.get());
|
||||
}
|
||||
if ( params.type == OBJECT_REPAIR )
|
||||
{
|
||||
objAuto = std::make_unique<CAutoRepair>(obj.get());
|
||||
}
|
||||
if ( params.type == OBJECT_DESTROYER )
|
||||
{
|
||||
objAuto = std::make_unique<CAutoDestroyer>(obj.get());
|
||||
}
|
||||
if ( params.type == OBJECT_STATION )
|
||||
{
|
||||
objAuto = std::make_unique<CAutoPowerStation>(obj.get());
|
||||
}
|
||||
if ( params.type == OBJECT_CONVERT )
|
||||
{
|
||||
objAuto = std::make_unique<CAutoConvert>(obj.get());
|
||||
}
|
||||
if ( params.type == OBJECT_TOWER )
|
||||
{
|
||||
objAuto = std::make_unique<CAutoTower>(obj.get());
|
||||
}
|
||||
if ( params.type == OBJECT_RESEARCH )
|
||||
{
|
||||
objAuto = std::make_unique<CAutoResearch>(obj.get());
|
||||
}
|
||||
if ( params.type == OBJECT_RADAR )
|
||||
{
|
||||
objAuto = std::make_unique<CAutoRadar>(obj.get());
|
||||
}
|
||||
if ( params.type == OBJECT_ENERGY )
|
||||
{
|
||||
objAuto = std::make_unique<CAutoPowerPlant>(obj.get());
|
||||
}
|
||||
if ( params.type == OBJECT_LABO )
|
||||
{
|
||||
objAuto = std::make_unique<CAutoLabo>(obj.get());
|
||||
}
|
||||
if ( params.type == OBJECT_NUCLEAR )
|
||||
{
|
||||
objAuto = std::make_unique<CAutoNuclearPlant>(obj.get());
|
||||
}
|
||||
if ( params.type == OBJECT_PARA )
|
||||
{
|
||||
objAuto = std::make_unique<CAutoPowerCaptor>(obj.get());
|
||||
}
|
||||
if ( params.type == OBJECT_SAFE )
|
||||
{
|
||||
objAuto = std::make_unique<CAutoVault>(obj.get());
|
||||
}
|
||||
if ( params.type == OBJECT_HUSTON )
|
||||
{
|
||||
objAuto = std::make_unique<CAutoHouston>(obj.get());
|
||||
}
|
||||
if ( params.type == OBJECT_NEST )
|
||||
{
|
||||
objAuto = std::make_unique<CAutoNest>(obj.get());
|
||||
}
|
||||
|
||||
if (objAuto != nullptr)
|
||||
{
|
||||
objAuto->Init();
|
||||
obj->SetAuto(std::move(objAuto));
|
||||
}
|
||||
|
||||
engine->LoadAllTextures();
|
||||
|
||||
obj->UpdateMapping();
|
||||
|
||||
return obj;
|
||||
}
|
|
@ -1,107 +0,0 @@
|
|||
/*
|
||||
* This file is part of the Colobot: Gold Edition source code
|
||||
* Copyright (C) 2001-2023, Daniel Roux, EPSITEC SA & TerranovaTeam
|
||||
* http://epsitec.ch; http://colobot.info; http://github.com/colobot
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see http://gnu.org/licenses
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "common/event.h"
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
|
||||
#include <array>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
namespace Gfx
|
||||
{
|
||||
class CEngine;
|
||||
} // namespace Gfx
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
|
||||
class CButton;
|
||||
class CCheck;
|
||||
class CColor;
|
||||
class CControl;
|
||||
class CEdit;
|
||||
class CEditValue;
|
||||
class CEnumSlider;
|
||||
class CGroup;
|
||||
class CImage;
|
||||
class CKey;
|
||||
class CLabel;
|
||||
class CList;
|
||||
class CMap;
|
||||
class CScroll;
|
||||
class CShortcut;
|
||||
class CSlider;
|
||||
class CTarget;
|
||||
class CWindow;
|
||||
|
||||
const int MAXCONTROL = 100;
|
||||
|
||||
class CInterface
|
||||
{
|
||||
public:
|
||||
CInterface();
|
||||
~CInterface();
|
||||
|
||||
bool EventProcess(const Event &event);
|
||||
bool GetTooltip(const glm::vec2& pos, std::string &name);
|
||||
|
||||
void Flush();
|
||||
CButton* CreateButton(const glm::vec2& pos, const glm::vec2& dim, int icon, EventType eventMsg);
|
||||
CColor* CreateColor(const glm::vec2& pos, const glm::vec2& dim, int icon, EventType eventMsg);
|
||||
CCheck* CreateCheck(const glm::vec2& pos, const glm::vec2& dim, int icon, EventType eventMsg);
|
||||
CKey* CreateKey(const glm::vec2& pos, const glm::vec2& dim, int icon, EventType eventMsg);
|
||||
CGroup* CreateGroup(const glm::vec2& pos, const glm::vec2& dim, int icon, EventType eventMsg);
|
||||
CImage* CreateImage(const glm::vec2& pos, const glm::vec2& dim, int icon, EventType eventMsg);
|
||||
CEdit* CreateEdit(const glm::vec2& pos, const glm::vec2& dim, int icon, EventType eventMsg);
|
||||
CEditValue* CreateEditValue(const glm::vec2& pos, const glm::vec2& dim, int icon, EventType eventMsg);
|
||||
CScroll* CreateScroll(const glm::vec2& pos, const glm::vec2& dim, int icon, EventType eventMsg);
|
||||
CSlider* CreateSlider(const glm::vec2& pos, const glm::vec2& dim, int icon, EventType eventMsg);
|
||||
CEnumSlider* CreateEnumSlider(const glm::vec2& pos, const glm::vec2& dim, int icon, EventType eventMsg);
|
||||
CShortcut* CreateShortcut(const glm::vec2& pos, const glm::vec2& dim, int icon, EventType eventMsg);
|
||||
CTarget* CreateTarget(const glm::vec2& pos, const glm::vec2& dim, int icon, EventType eventMsg);
|
||||
CMap* CreateMap(const glm::vec2& pos, const glm::vec2& dim, int icon, EventType eventMsg);
|
||||
|
||||
CWindow* CreateWindows(const glm::vec2& pos, const glm::vec2& dim, int icon, EventType eventMsg);
|
||||
CList* CreateList(const glm::vec2& pos, const glm::vec2& dim, int icon, EventType eventMsg, float expand=1.2f);
|
||||
CLabel* CreateLabel(const glm::vec2& pos, const glm::vec2& dim, int icon, EventType eventMsg, std::string name);
|
||||
|
||||
bool DeleteControl(EventType eventMsg);
|
||||
CControl* SearchControl(EventType eventMsg);
|
||||
|
||||
void Draw();
|
||||
|
||||
void SetFocus(CControl* focusControl);
|
||||
|
||||
protected:
|
||||
int GetNextFreeControl();
|
||||
|
||||
template <typename ControlClass>
|
||||
ControlClass* CreateControl(const glm::vec2& pos, const glm::vec2& dim, int icon, EventType eventMsg);
|
||||
|
||||
CEventQueue* m_event;
|
||||
Gfx::CEngine* m_engine;
|
||||
std::array<std::unique_ptr<CControl>, MAXCONTROL> m_controls;
|
||||
};
|
||||
|
||||
|
||||
} // namespace Ui
|
|
@ -1,157 +0,0 @@
|
|||
/*
|
||||
* This file is part of the Colobot: Gold Edition source code
|
||||
* Copyright (C) 2001-2023, Daniel Roux, EPSITEC SA & TerranovaTeam
|
||||
* http://epsitec.ch; http://colobot.info; http://github.com/colobot
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see http://gnu.org/licenses
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "ui/controls/control.h"
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace Gfx
|
||||
{
|
||||
enum EngineMouseType : unsigned char;
|
||||
}
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
|
||||
class CButton;
|
||||
class CColor;
|
||||
class CCheck;
|
||||
class CKey;
|
||||
class CGroup;
|
||||
class CImage;
|
||||
class CLabel;
|
||||
class CEdit;
|
||||
class CEditValue;
|
||||
class CScroll;
|
||||
class CSlider;
|
||||
class CEnumSlider;
|
||||
class CList;
|
||||
class CShortcut;
|
||||
class CMap;
|
||||
class CGauge;
|
||||
class CTarget;
|
||||
|
||||
class CWindow : public CControl
|
||||
{
|
||||
public:
|
||||
CWindow();
|
||||
~CWindow();
|
||||
|
||||
void Flush();
|
||||
bool Create(const glm::vec2& pos, const glm::vec2& dim, int icon, EventType eventMsg) override;
|
||||
CButton* CreateButton(const glm::vec2& pos, const glm::vec2& dim, int icon, EventType eventMsg);
|
||||
CColor* CreateColor(const glm::vec2& pos, const glm::vec2& dim, int icon, EventType eventMsg);
|
||||
CCheck* CreateCheck(const glm::vec2& pos, const glm::vec2& dim, int icon, EventType eventMsg);
|
||||
CKey* CreateKey(const glm::vec2& pos, const glm::vec2& dim, int icon, EventType eventMsg);
|
||||
CGroup* CreateGroup(const glm::vec2& pos, const glm::vec2& dim, int icon, EventType eventMsg);
|
||||
CImage* CreateImage(const glm::vec2& pos, const glm::vec2& dim, int icon, EventType eventMsg);
|
||||
CLabel* CreateLabel(const glm::vec2& pos, const glm::vec2& dim, int icon, EventType eventMsg, std::string name);
|
||||
CEdit* CreateEdit(const glm::vec2& pos, const glm::vec2& dim, int icon, EventType eventMsg);
|
||||
CEditValue* CreateEditValue(const glm::vec2& pos, const glm::vec2& dim, int icon, EventType eventMsg);
|
||||
CScroll* CreateScroll(const glm::vec2& pos, const glm::vec2& dim, int icon, EventType eventMsg);
|
||||
CSlider* CreateSlider(const glm::vec2& pos, const glm::vec2& dim, int icon, EventType eventMsg);
|
||||
CEnumSlider* CreateEnumSlider(const glm::vec2& pos, const glm::vec2& dim, int icon, EventType eventMsg);
|
||||
CList* CreateList(const glm::vec2& pos, const glm::vec2& dim, int icon, EventType eventMsg, float expand=1.2f);
|
||||
CShortcut* CreateShortcut(const glm::vec2& pos, const glm::vec2& dim, int icon, EventType eventMsg);
|
||||
CMap* CreateMap(const glm::vec2& pos, const glm::vec2& dim, int icon, EventType eventMsg);
|
||||
CGauge* CreateGauge(const glm::vec2& pos, const glm::vec2& dim, int icon, EventType eventMsg);
|
||||
CTarget* CreateTarget(const glm::vec2& pos, const glm::vec2& dim, int icon, EventType eventMsg);
|
||||
bool DeleteControl(EventType eventMsg);
|
||||
CControl* SearchControl(EventType eventMsg);
|
||||
|
||||
EventType GetEventTypeReduce();
|
||||
EventType GetEventTypeFull();
|
||||
EventType GetEventTypeClose();
|
||||
|
||||
void SetName(std::string name, bool tooltip = true) override;
|
||||
|
||||
void SetTrashEvent(bool bTrash);
|
||||
bool GetTrashEvent();
|
||||
|
||||
void SetPos(const glm::vec2& pos) override;
|
||||
void SetDim(const glm::vec2& dim) override;
|
||||
|
||||
void SetMinDim(const glm::vec2& dim);
|
||||
void SetMaxDim(const glm::vec2& dim);
|
||||
glm::vec2 GetMinDim();
|
||||
glm::vec2 GetMaxDim();
|
||||
|
||||
void SetMovable(bool bMode);
|
||||
bool GetMovable();
|
||||
|
||||
void SetRedim(bool bMode);
|
||||
bool GetRedim();
|
||||
|
||||
void SetClosable(bool bMode);
|
||||
bool GetClosable();
|
||||
|
||||
void SetMaximized(bool bMaxi);
|
||||
bool GetMaximized();
|
||||
void SetMinimized(bool bMini);
|
||||
bool GetMinimized();
|
||||
void SetFixed(bool bFix);
|
||||
bool GetFixed();
|
||||
|
||||
bool GetTooltip(const glm::vec2& pos, std::string &name) override;
|
||||
|
||||
bool EventProcess(const Event &event) override;
|
||||
|
||||
void Draw() override;
|
||||
|
||||
void SetFocus(CControl* focusControl) override;
|
||||
|
||||
protected:
|
||||
int BorderDetect(const glm::vec2& pos);
|
||||
void AdjustButtons();
|
||||
void MoveAdjust();
|
||||
void DrawVertex(const glm::vec2& pos, const glm::vec2& dim, int icon);
|
||||
void DrawHach(const glm::vec2& pos, const glm::vec2& dim);
|
||||
template<typename ControlClass>
|
||||
ControlClass* CreateControl(const glm::vec2& pos, const glm::vec2& dim, int icon, EventType eventMsg);
|
||||
|
||||
protected:
|
||||
std::vector<std::unique_ptr<CControl>> m_controls;
|
||||
|
||||
bool m_bTrashEvent;
|
||||
bool m_bMaximized;
|
||||
bool m_bMinimized;
|
||||
bool m_bFixed;
|
||||
|
||||
glm::vec2 m_minDim;
|
||||
glm::vec2 m_maxDim;
|
||||
|
||||
std::unique_ptr<CButton> m_buttonReduce;
|
||||
std::unique_ptr<CButton> m_buttonFull;
|
||||
std::unique_ptr<CButton> m_buttonClose;
|
||||
|
||||
bool m_bMovable;
|
||||
bool m_bRedim;
|
||||
bool m_bClosable;
|
||||
bool m_bCapture;
|
||||
glm::vec2 m_pressPos;
|
||||
int m_pressFlags;
|
||||
Gfx::EngineMouseType m_pressMouse;
|
||||
};
|
||||
|
||||
|
||||
} // namespace Ui
|
File diff suppressed because it is too large
Load Diff
|
@ -1,364 +0,0 @@
|
|||
/*
|
||||
* This file is part of the Colobot: Gold Edition source code
|
||||
* Copyright (C) 2001-2023, Daniel Roux, EPSITEC SA & TerranovaTeam
|
||||
* http://epsitec.ch; http://colobot.info; http://github.com/colobot
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see http://gnu.org/licenses
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "common/event.h"
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
|
||||
struct Event;
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
|
||||
class CEdit;
|
||||
class CInterface;
|
||||
|
||||
|
||||
/**
|
||||
* \brief File selector dialog
|
||||
*
|
||||
* \section Example Example usage
|
||||
* Create the dialog and set the type of dialog.
|
||||
* \code
|
||||
* CFileDialog* fileDialog = new CFileDialog();
|
||||
* fileDialog->SetDialogType(CFileDialog::Type::Folder);
|
||||
* \endcode
|
||||
*
|
||||
* Initial settings and start the dialog.
|
||||
* \code
|
||||
* fileDialog->SetWindowTitle("Select Player Folder");
|
||||
* fileDialog->SetBasePath("savegame");
|
||||
* fileDialog->StartDialog();
|
||||
* \endcode
|
||||
*
|
||||
* Handle events for the dialog.
|
||||
* \code
|
||||
* // first check for events sent from the dialog
|
||||
*
|
||||
* if (event.type == EVENT_DIALOG_STOP) // cancel or close
|
||||
* {
|
||||
* fileDialog->StopDialog();
|
||||
* delete fileDialog;
|
||||
* return true;
|
||||
* }
|
||||
*
|
||||
* if (event.type == EVENT_DIALOG_ACTION) // ok button was pressed
|
||||
* {
|
||||
* std::string folder = fileDialog->GetSubFolderPath();
|
||||
* fileDialog->StopDialog();
|
||||
* delete fileDialog;
|
||||
* return true;
|
||||
* }
|
||||
*
|
||||
* // send the event to the dialog
|
||||
* return m_fileDialog->EventProcess(event);
|
||||
* \endcode
|
||||
*
|
||||
* \nosubgrouping
|
||||
*/
|
||||
class CFileDialog
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* \brief Constructor
|
||||
*/
|
||||
CFileDialog();
|
||||
|
||||
/**
|
||||
* \brief Destructor
|
||||
*/
|
||||
~CFileDialog();
|
||||
|
||||
//! \name Set dialog type, starting, event processing, and stopping
|
||||
//@{
|
||||
/**
|
||||
* \brief Disables other windows and creates the dialog window.
|
||||
*/
|
||||
void StartDialog();
|
||||
|
||||
/**
|
||||
* \brief Enables other windows and deletes the dialog window.
|
||||
*/
|
||||
void StopDialog();
|
||||
|
||||
/**
|
||||
* \brief Event processing.
|
||||
*/
|
||||
bool EventProcess(const Event &event);
|
||||
|
||||
/**
|
||||
* \brief Identifies the type of dialog to display.
|
||||
*/
|
||||
enum class Type
|
||||
{
|
||||
None, //!< Type was not set
|
||||
Open, //!< Open dialog
|
||||
Save, //!< Save dialog
|
||||
Folder, //!< Select Folder dialog
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Set the type of dialog to use.
|
||||
*/
|
||||
void SetDialogType(CFileDialog::Type type) { m_dialogtype = type; }
|
||||
|
||||
/**
|
||||
* \brief Get the type of dialog.
|
||||
*/
|
||||
CFileDialog::Type GetDialogType() { return m_dialogtype; }
|
||||
|
||||
//@}
|
||||
|
||||
//! \name Dialog window properties
|
||||
//@{
|
||||
/**
|
||||
* \brief Set EventType for the dialog window.
|
||||
* If not set, a unique EventType will be used.
|
||||
*/
|
||||
void SetWindowEvent(EventType type) { m_windowEvent = type; }
|
||||
|
||||
/**
|
||||
* \brief Get EventType for the dialog window.
|
||||
*/
|
||||
EventType GetWindowEvent() { return m_windowEvent; }
|
||||
|
||||
/**
|
||||
* \brief Set the initial position of the window.
|
||||
*/
|
||||
void SetWindowPos(const glm::vec2& pos) { m_windowPos = pos; }
|
||||
|
||||
/**
|
||||
* \brief Get the position of the window.
|
||||
*/
|
||||
glm::vec2 GetWindowPos() { return m_windowPos; }
|
||||
|
||||
/**
|
||||
* \brief Set the initial size of the window.
|
||||
*/
|
||||
void SetWindowDim(const glm::vec2& dim) { m_windowDim = dim; }
|
||||
|
||||
/**
|
||||
* \brief Get the size of the window.
|
||||
*/
|
||||
glm::vec2 GetWindowDim() { return m_windowDim; }
|
||||
|
||||
/**
|
||||
* \brief Set the text for the title bar of the dialog.
|
||||
* This setting will override the default title text for the dialog.
|
||||
*/
|
||||
void SetWindowTitle(const std::string& name) { m_title = name; }
|
||||
|
||||
//@}
|
||||
|
||||
//! \name Settings for Public and Private check boxes
|
||||
//@{
|
||||
/**
|
||||
* \brief Set whether to create Public and Private check boxes.
|
||||
* \param usePublic If true, Public and Private check boxes will be added to the dialog.
|
||||
*/
|
||||
void SetUsePublicPrivate(bool usePublic);
|
||||
|
||||
/**
|
||||
* \brief Set initial state for Public and Private check boxes.
|
||||
* \param bPublic If true, the Public check box will be marked.
|
||||
*/
|
||||
void SetPublic(bool bPublic);
|
||||
|
||||
/**
|
||||
* \brief Get the state of Public and Private check boxes.
|
||||
* \return true if Public check box is marked and false for Private.
|
||||
*/
|
||||
bool GetPublic();
|
||||
|
||||
/**
|
||||
* \brief Set the path for the folder associated with the Public check box.
|
||||
* \param dir Path to 'Public' folder.
|
||||
*/
|
||||
void SetPublicFolder(const std::string& dir);
|
||||
|
||||
/**
|
||||
* \brief Set the path for the folder associated with the Private check box.
|
||||
* \param dir Path to 'Private' folder.
|
||||
*/
|
||||
void SetPrivateFolder(const std::string& dir);
|
||||
|
||||
//@}
|
||||
|
||||
//! \name Folder settings
|
||||
//@{
|
||||
/**
|
||||
* \brief Set the initial path for the folder whose contents are displayed.
|
||||
* This setting is overridden by Public/Private settings.
|
||||
*/
|
||||
void SetBasePath(const std::string& dir);
|
||||
|
||||
/**
|
||||
* \brief Get the initial path or Public/Private folder path
|
||||
*/
|
||||
std::string GetBasePath();
|
||||
|
||||
/**
|
||||
* \brief Set the initial subfolder whose contents are displayed.
|
||||
* \param dir Name of a subfolder. Ex. "subfolder/anotherFolder/oneMoreFolder"
|
||||
*/
|
||||
void SetSubFolderPath(const std::string& dir);
|
||||
|
||||
/**
|
||||
* \brief Get the current subfolder shown by the dialog.
|
||||
* \return A string with a folder name and subsequent folders separated by forward slash.
|
||||
* <p>Returns empty string if the dialog is showing GetBasePath().
|
||||
*/
|
||||
std::string GetSubFolderPath();
|
||||
|
||||
//@}
|
||||
|
||||
//! \name File name settings
|
||||
//@{
|
||||
/**
|
||||
* \brief Set the extension that may be appended to a file name.
|
||||
* <p> If any extensions are defined, the dialog will only show files
|
||||
* with those extensions.
|
||||
* \param ext A string with an extension. Ex. ".txt"
|
||||
*/
|
||||
void SetAutoExtension(const std::string& ext) { m_extension = ext; }
|
||||
|
||||
/**
|
||||
* \brief Define extensions that will be accepted as part of a valid file name.
|
||||
* \param ext A string with an extension. Ex. ".txt"
|
||||
*/
|
||||
void AddOptionalExtension(const std::string& ext) { m_extlist.push_back(ext); }
|
||||
|
||||
/**
|
||||
* \brief Set the filename that appears in the edit box when the dialog opens.
|
||||
*/
|
||||
void SetFilename(const std::string& filename);
|
||||
|
||||
/**
|
||||
* \brief Get the filename that was selected or typed.
|
||||
* \return The filename that was typed in the edit box.
|
||||
*/
|
||||
std::string GetFilename();
|
||||
|
||||
/**
|
||||
* \brief Set whether to check if a file exists when the 'Save' button is pressed,
|
||||
* and if the file exists, an "Overwrite existing file?" message is shown.
|
||||
* \param doCheck true to check if a file exists when the 'Save' button is pressed.
|
||||
*/
|
||||
void SetConfirmOverwrite(bool doCheck) { m_confirmOverwrite = doCheck; }
|
||||
|
||||
//@}
|
||||
|
||||
private:
|
||||
|
||||
void StartFileDialog();
|
||||
void AdjustDialog();
|
||||
|
||||
void PopulateList();
|
||||
void GetListChoice();
|
||||
void SearchList(const std::string &text, bool dirOnly = false);
|
||||
|
||||
void UpdateAction();
|
||||
void UpdatePathLabel();
|
||||
void UpdatePublic(bool bPublic);
|
||||
|
||||
void OpenFolder();
|
||||
|
||||
bool StartNewFolderMode();
|
||||
bool StopNewFolderMode(bool bCancel = false);
|
||||
bool EventNewFolder(const Event &event);
|
||||
void UpdateNewFolder();
|
||||
void CreateNewFolder();
|
||||
|
||||
bool EventSelectFolder(const Event &event);
|
||||
void UpdateSelectFolder();
|
||||
|
||||
bool ListItemIsFolder();
|
||||
bool DirectoryExists(const std::string &name);
|
||||
|
||||
bool CheckFilename(const std::string& name);
|
||||
bool ActionOpen();
|
||||
bool ActionSave(bool checkFileExist = false);
|
||||
|
||||
bool StartAskOverwrite(const std::string& name);
|
||||
bool StopAskOverwrite();
|
||||
bool EventAskOverwrite(const Event &event);
|
||||
|
||||
/*!
|
||||
* \brief Set the text in the file name edit box.
|
||||
* \param edit Pointer to the edit box.
|
||||
* \param filename Text to put in the edit box.
|
||||
*/
|
||||
void SetFilenameField(CEdit* edit, const std::string& filename);
|
||||
|
||||
/*!
|
||||
* \brief Get the current directory with the current sub-directory appended.
|
||||
* \param bCreate If true, the directories in question will be created.
|
||||
* \return A string with the path of current directory, plus the
|
||||
* current sub-directory if any.
|
||||
*/
|
||||
std::string SearchDirectory(bool bCreate);
|
||||
|
||||
private:
|
||||
|
||||
CEventQueue* m_eventQueue;
|
||||
CInterface* m_interface;
|
||||
|
||||
CFileDialog::Type m_dialogtype = Type::None;
|
||||
|
||||
// EventType for this dialog.
|
||||
// With EVENT_NULL, a unique EventType will be used.
|
||||
EventType m_windowEvent = EVENT_NULL;
|
||||
|
||||
glm::vec2 m_windowPos;
|
||||
glm::vec2 m_windowDim;
|
||||
std::string m_title = "";
|
||||
|
||||
float m_time;
|
||||
float m_lastTimeClickDir;
|
||||
bool m_captureClick = false;
|
||||
|
||||
bool m_newFolderMode = false;
|
||||
bool m_selectFolderMode = false;
|
||||
bool m_askOverwriteMode = false;
|
||||
bool m_confirmOverwrite = false;
|
||||
|
||||
bool m_public = false;
|
||||
std::string m_pathPublic = "";
|
||||
std::string m_pathPrivate = "";
|
||||
bool m_usePublicPrivate = false;
|
||||
|
||||
std::string m_basePath = "";
|
||||
std::string m_subDirPath = "";
|
||||
|
||||
std::string m_filename = "";
|
||||
|
||||
//! The extension to add to a filename if needed
|
||||
std::string m_extension = "";
|
||||
//! List of extensions accepted as part of a valid file name
|
||||
std::vector<std::string> m_extlist = {};
|
||||
};
|
||||
|
||||
} // namespace Ui
|
|
@ -1,58 +0,0 @@
|
|||
/*
|
||||
* This file is part of the Colobot: Gold Edition source code
|
||||
* Copyright (C) 2001-2023, Daniel Roux, EPSITEC SA & TerranovaTeam
|
||||
* http://epsitec.ch; http://colobot.info; http://github.com/colobot
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see http://gnu.org/licenses
|
||||
*/
|
||||
|
||||
#include "ui/particles_generator.h"
|
||||
|
||||
#include "graphics/engine/engine.h"
|
||||
#include "graphics/engine/particle.h"
|
||||
|
||||
#include "math/func.h"
|
||||
|
||||
namespace UI
|
||||
{
|
||||
CParticlesGenerator::CParticlesGenerator()
|
||||
{
|
||||
m_particleManager = Gfx::CEngine::GetInstancePointer()->GetParticle();
|
||||
}
|
||||
|
||||
void CParticlesGenerator::GenerateMouseParticles(const glm::vec2& mousePosition, bool buttonPressed)
|
||||
{
|
||||
Gfx::ParticleType particleType = buttonPressed ? Gfx::ParticleType::PARTISCRAPS : Gfx::ParticleType::PARTILENS1;
|
||||
m_particleManager->CreateParticle(glm::vec3(mousePosition.x, mousePosition.y, 0), CreateRandomSpeedForMouseParticles(),
|
||||
CreateRandomDimensionsForMouseParticles(buttonPressed), particleType,
|
||||
CreateRandomDurationForMouseParticles(), 2.0f, 0.0f, Gfx::SH_INTERFACE);
|
||||
}
|
||||
|
||||
glm::vec2 CParticlesGenerator::CreateRandomDimensionsForMouseParticles(bool buttonPressed)
|
||||
{
|
||||
float dimensionX = buttonPressed ? (0.005f + Math::Rand() * 0.005f) : (0.01f + Math::Rand() * 0.01f);
|
||||
return { dimensionX, dimensionX / 0.75f };
|
||||
}
|
||||
|
||||
glm::vec3 CParticlesGenerator::CreateRandomSpeedForMouseParticles()
|
||||
{
|
||||
return glm::vec3((Math::Rand() - 0.5f) * 0.5f, 0.3f + Math::Rand() * 0.3f, 0.0f);
|
||||
}
|
||||
|
||||
float CParticlesGenerator::CreateRandomDurationForMouseParticles()
|
||||
{
|
||||
return Math::Rand() * 0.5f + 0.5f;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,46 +0,0 @@
|
|||
/*
|
||||
* This file is part of the Colobot: Gold Edition source code
|
||||
* Copyright (C) 2001-2023, Daniel Roux, EPSITEC SA & TerranovaTeam
|
||||
* http://epsitec.ch; http://colobot.info; http://github.com/colobot
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see http://gnu.org/licenses
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "graphics/engine/particle.h"
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
|
||||
namespace UI
|
||||
{
|
||||
/**
|
||||
* \brief class for generating particles in the menu
|
||||
*/
|
||||
class CParticlesGenerator
|
||||
{
|
||||
public:
|
||||
CParticlesGenerator();
|
||||
/**
|
||||
* \brief generates particles after mouse cursor movement
|
||||
*/
|
||||
void GenerateMouseParticles(const glm::vec2& mousePosition, bool buttonPressed);
|
||||
private:
|
||||
Gfx::CParticle* m_particleManager;
|
||||
glm::vec2 CreateRandomDimensionsForMouseParticles(bool buttonPressed);
|
||||
glm::vec3 CreateRandomSpeedForMouseParticles();
|
||||
float CreateRandomDurationForMouseParticles();
|
||||
};
|
||||
|
||||
}
|
|
@ -1,582 +0,0 @@
|
|||
/*
|
||||
* This file is part of the Colobot: Gold Edition source code
|
||||
* Copyright (C) 2001-2023, Daniel Roux, EPSITEC SA & TerranovaTeam
|
||||
* http://epsitec.ch; http://colobot.info; http://github.com/colobot
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see http://gnu.org/licenses
|
||||
*/
|
||||
|
||||
#include "ui/screen/screen_mod_list.h"
|
||||
|
||||
#include "common/config.h"
|
||||
|
||||
#include "app/app.h"
|
||||
#include "app/modman.h"
|
||||
|
||||
#include "common/logger.h"
|
||||
#include "common/restext.h"
|
||||
#include "common/stringutils.h"
|
||||
|
||||
#include "common/resources/resourcemanager.h"
|
||||
|
||||
#include "common/system/system.h"
|
||||
|
||||
#include "level/robotmain.h"
|
||||
|
||||
#include "math/func.h"
|
||||
|
||||
#include "sound/sound.h"
|
||||
|
||||
#include "ui/controls/button.h"
|
||||
#include "ui/controls/edit.h"
|
||||
#include "ui/controls/interface.h"
|
||||
#include "ui/controls/label.h"
|
||||
#include "ui/controls/list.h"
|
||||
#include "ui/controls/window.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
|
||||
CScreenModList::CScreenModList(CMainDialog* dialog, CModManager* modManager)
|
||||
: m_dialog(dialog),
|
||||
m_modManager(modManager)
|
||||
{
|
||||
}
|
||||
|
||||
void CScreenModList::CreateInterface()
|
||||
{
|
||||
CWindow* pw;
|
||||
CEdit* pe;
|
||||
CLabel* pl;
|
||||
CButton* pb;
|
||||
CList* pli;
|
||||
glm::vec2 pos, ddim;
|
||||
std::string name;
|
||||
|
||||
// Display the window
|
||||
pos.x = 0.10f;
|
||||
pos.y = 0.10f;
|
||||
ddim.x = 0.80f;
|
||||
ddim.y = 0.80f;
|
||||
pw = m_interface->CreateWindows(pos, ddim, 12, EVENT_WINDOW5);
|
||||
pw->SetClosable(true);
|
||||
GetResource(RES_TEXT, RT_TITLE_MODS, name);
|
||||
pw->SetName(name);
|
||||
|
||||
pos.x = 0.10f;
|
||||
pos.y = 0.40f;
|
||||
ddim.x = 0.50f;
|
||||
ddim.y = 0.50f;
|
||||
pw->CreateGroup(pos, ddim, 5, EVENT_INTERFACE_GLINTl); // orange corner
|
||||
pos.x = 0.40f;
|
||||
pos.y = 0.10f;
|
||||
ddim.x = 0.50f;
|
||||
ddim.y = 0.50f;
|
||||
pw->CreateGroup(pos, ddim, 4, EVENT_INTERFACE_GLINTr); // blue corner
|
||||
|
||||
// Display the list of mods
|
||||
pos.x = ox+sx*3;
|
||||
pos.y = oy+sy*10.5f;
|
||||
ddim.x = dim.x*7.5f;
|
||||
ddim.y = dim.y*0.6f;
|
||||
GetResource(RES_TEXT, RT_MOD_LIST, name);
|
||||
pl = pw->CreateLabel(pos, ddim, 0, EVENT_LABEL11, name);
|
||||
pl->SetTextAlign(Gfx::TEXT_ALIGN_LEFT);
|
||||
|
||||
pos.y = oy+sy*6.7f;
|
||||
ddim.y = dim.y*4.6f;
|
||||
ddim.x = dim.x*6.5f;
|
||||
pli = pw->CreateList(pos, ddim, 0, EVENT_INTERFACE_MOD_LIST);
|
||||
pli->SetState(STATE_SHADOW);
|
||||
pli->SetState(STATE_EXTEND);
|
||||
|
||||
// Displays the mod details
|
||||
pos.x = ox+sx*9.5f;
|
||||
pos.y = oy+sy*10.5f;
|
||||
ddim.x = dim.x*7.5f;
|
||||
ddim.y = dim.y*0.6f;
|
||||
GetResource(RES_TEXT, RT_MOD_DETAILS, name);
|
||||
pl = pw->CreateLabel(pos, ddim, 0, EVENT_LABEL12, name);
|
||||
pl->SetTextAlign(Gfx::TEXT_ALIGN_LEFT);
|
||||
|
||||
pos.y = oy+sy*6.7f;
|
||||
ddim.y = dim.y*4.3f;
|
||||
ddim.x = dim.x*6.5f;
|
||||
pe = pw->CreateEdit(pos, ddim, 0, EVENT_INTERFACE_MOD_DETAILS);
|
||||
pe->SetState(STATE_SHADOW);
|
||||
pe->SetMaxChar(500);
|
||||
pe->SetEditCap(false); // just to see
|
||||
pe->SetHighlightCap(true);
|
||||
|
||||
pos = pli->GetPos();
|
||||
ddim = pli->GetDim();
|
||||
|
||||
// Displays the mod summary
|
||||
pos.x = ox+sx*3;
|
||||
pos.y = oy+sy*5.4f;
|
||||
ddim.x = dim.x*6.5f;
|
||||
ddim.y = dim.y*0.6f;
|
||||
GetResource(RES_TEXT, RT_MOD_SUMMARY, name);
|
||||
pl = pw->CreateLabel(pos, ddim, 0, EVENT_LABEL13, name);
|
||||
pl->SetTextAlign(Gfx::TEXT_ALIGN_LEFT);
|
||||
|
||||
pos.x = ox+sx*3;
|
||||
pos.y = oy+sy*3.6f;
|
||||
ddim.x = dim.x*13.4f;
|
||||
ddim.y = dim.y*1.9f;
|
||||
pe = pw->CreateEdit(pos, ddim, 0, EVENT_INTERFACE_MOD_SUMMARY);
|
||||
pe->SetState(STATE_SHADOW);
|
||||
pe->SetMaxChar(500);
|
||||
pe->SetEditCap(false); // just to see
|
||||
pe->SetHighlightCap(true);
|
||||
|
||||
// Apply button
|
||||
pos.x = ox+sx*13.75f;
|
||||
pos.y = oy+sy*2;
|
||||
ddim.x = dim.x*2.0f;
|
||||
ddim.y = dim.y*1;
|
||||
pb = pw->CreateButton(pos, ddim, -1, EVENT_INTERFACE_MODS_APPLY);
|
||||
pb->SetState(STATE_SHADOW);
|
||||
|
||||
// Display the enable/disable button
|
||||
pos.x -= dim.x*2.3f;
|
||||
ddim.x = dim.x*2.0f;
|
||||
pb = pw->CreateButton(pos, ddim, -1, EVENT_INTERFACE_MOD_ENABLE_OR_DISABLE);
|
||||
pb->SetState(STATE_SHADOW);
|
||||
|
||||
// Display the move up button
|
||||
pos.x -= dim.x*0.8f;
|
||||
pos.y = oy+sy*2.48;
|
||||
ddim.x = dim.x*0.5;
|
||||
ddim.y = dim.y*0.5;
|
||||
pb = pw->CreateButton(pos, ddim, 49, EVENT_INTERFACE_MOD_MOVE_UP);
|
||||
pb->SetState(STATE_SHADOW);
|
||||
|
||||
// Display the move down button
|
||||
pos.y = oy+sy*2;
|
||||
pb = pw->CreateButton(pos, ddim, 50, EVENT_INTERFACE_MOD_MOVE_DOWN);
|
||||
pb->SetState(STATE_SHADOW);
|
||||
|
||||
// Display the refresh button
|
||||
pos.x -= dim.x*1.3f;
|
||||
pos.y = oy+sy*2;
|
||||
ddim.x = dim.x*1;
|
||||
ddim.y = dim.y*1;
|
||||
pb = pw->CreateButton(pos, ddim, 87, EVENT_INTERFACE_MODS_REFRESH);
|
||||
pb->SetState(STATE_SHADOW);
|
||||
|
||||
// Display the open website button
|
||||
pos.x -= dim.x*1.3f;
|
||||
pb = pw->CreateButton(pos, ddim, 40, EVENT_INTERFACE_WORKSHOP);
|
||||
pb->SetState(STATE_SHADOW);
|
||||
|
||||
// Display the open directory button
|
||||
pos.x -= dim.x*1.3f;
|
||||
pb = pw->CreateButton(pos, ddim, 57, EVENT_INTERFACE_MODS_DIR);
|
||||
pb->SetState(STATE_SHADOW);
|
||||
|
||||
// Back button
|
||||
pos.x = ox+sx*3;
|
||||
ddim.x = dim.x*4;
|
||||
pb = pw->CreateButton(pos, ddim, -1, EVENT_INTERFACE_BACK);
|
||||
pb->SetState(STATE_SHADOW);
|
||||
|
||||
FindMods();
|
||||
UpdateAll();
|
||||
|
||||
// Background
|
||||
SetBackground("textures/interface/interface.png");
|
||||
CreateVersionDisplay();
|
||||
}
|
||||
|
||||
bool CScreenModList::EventProcess(const Event &event)
|
||||
{
|
||||
CWindow* pw;
|
||||
CList* pl;
|
||||
|
||||
const std::string workshopUrl = "https://www.moddb.com/games/colobot-gold-edition";
|
||||
const std::string modDir = CResourceManager::GetSaveLocation() + "/mods";
|
||||
|
||||
auto systemUtils = CSystemUtils::Create(); // platform-specific utils
|
||||
|
||||
Mod const * mod;
|
||||
|
||||
pw = static_cast<CWindow*>(m_interface->SearchControl(EVENT_WINDOW5));
|
||||
if (pw == nullptr) return false;
|
||||
|
||||
if (event.type == pw->GetEventTypeClose() ||
|
||||
event.type == EVENT_INTERFACE_BACK ||
|
||||
(event.type == EVENT_KEY_DOWN && event.GetData<KeyEventData>()->key == KEY(ESCAPE)))
|
||||
{
|
||||
if (m_modManager->Changes())
|
||||
{
|
||||
m_dialog->StartQuestion(RT_DIALOG_CHANGES_QUESTION, true, true, false,
|
||||
[this]()
|
||||
{
|
||||
ApplyChanges();
|
||||
CloseWindow();
|
||||
},
|
||||
[this]()
|
||||
{
|
||||
CloseWindow();
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
CloseWindow();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
switch( event.type )
|
||||
{
|
||||
case EVENT_INTERFACE_MOD_LIST:
|
||||
pl = static_cast<CList*>(pw->SearchControl(EVENT_INTERFACE_MOD_LIST));
|
||||
if (pl == nullptr) break;
|
||||
m_modSelectedIndex = pl->GetSelect();
|
||||
UpdateModSummary();
|
||||
UpdateModDetails();
|
||||
UpdateEnableDisableButton();
|
||||
UpdateUpDownButtons();
|
||||
break;
|
||||
|
||||
case EVENT_INTERFACE_MOD_ENABLE_OR_DISABLE:
|
||||
mod = &m_modManager->GetMod(m_modSelectedIndex);
|
||||
if (mod->enabled)
|
||||
{
|
||||
m_modManager->DisableMod(m_modSelectedIndex);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_modManager->EnableMod(m_modSelectedIndex);
|
||||
}
|
||||
UpdateModList();
|
||||
UpdateEnableDisableButton();
|
||||
UpdateApplyButton();
|
||||
break;
|
||||
|
||||
case EVENT_INTERFACE_MOD_MOVE_UP:
|
||||
m_modSelectedIndex = m_modManager->MoveUp(m_modSelectedIndex);
|
||||
UpdateModList();
|
||||
UpdateUpDownButtons();
|
||||
UpdateApplyButton();
|
||||
break;
|
||||
|
||||
case EVENT_INTERFACE_MOD_MOVE_DOWN:
|
||||
m_modSelectedIndex = m_modManager->MoveDown(m_modSelectedIndex);
|
||||
UpdateModList();
|
||||
UpdateUpDownButtons();
|
||||
UpdateApplyButton();
|
||||
break;
|
||||
|
||||
case EVENT_INTERFACE_MODS_REFRESH:
|
||||
// Apply any changes before refresh so that the config file
|
||||
// is better synchronized with the state of the game
|
||||
case EVENT_INTERFACE_MODS_APPLY:
|
||||
ApplyChanges();
|
||||
UpdateAll();
|
||||
// Start playing the main menu music again
|
||||
if (!m_app->GetSound()->IsPlayingMusic())
|
||||
{
|
||||
m_app->GetSound()->PlayMusic("music/Intro1.ogg", false);
|
||||
m_app->GetSound()->CacheMusic("music/Intro2.ogg");
|
||||
}
|
||||
break;
|
||||
|
||||
case EVENT_INTERFACE_MODS_DIR:
|
||||
if (!systemUtils->OpenPath(modDir))
|
||||
{
|
||||
std::string title, text;
|
||||
GetResource(RES_TEXT, RT_DIALOG_OPEN_PATH_FAILED_TITLE, title);
|
||||
GetResource(RES_TEXT, RT_DIALOG_OPEN_PATH_FAILED_TEXT, text);
|
||||
|
||||
// Workaround for Windows: the label skips everything after the first \\ character
|
||||
std::string modDirWithoutBackSlashes = modDir;
|
||||
std::replace(modDirWithoutBackSlashes.begin(), modDirWithoutBackSlashes.end(), '\\', '/');
|
||||
|
||||
m_dialog->StartInformation(title, title, StrUtils::Format(text.c_str(), modDirWithoutBackSlashes.c_str()));
|
||||
}
|
||||
break;
|
||||
|
||||
case EVENT_INTERFACE_WORKSHOP:
|
||||
if (!systemUtils->OpenWebsite(workshopUrl))
|
||||
{
|
||||
std::string title, text;
|
||||
GetResource(RES_TEXT, RT_DIALOG_OPEN_WEBSITE_FAILED_TITLE, title);
|
||||
GetResource(RES_TEXT, RT_DIALOG_OPEN_WEBSITE_FAILED_TEXT, text);
|
||||
m_dialog->StartInformation(title, title, StrUtils::Format(text.c_str(), workshopUrl.c_str()));
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void CScreenModList::FindMods()
|
||||
{
|
||||
m_modManager->FindMods();
|
||||
if (m_modManager->CountMods() != 0)
|
||||
{
|
||||
m_modSelectedIndex = glm::clamp(m_modSelectedIndex, static_cast<size_t>(0), m_modManager->CountMods() - 1);
|
||||
}
|
||||
}
|
||||
|
||||
void CScreenModList::ApplyChanges()
|
||||
{
|
||||
m_modManager->SaveMods();
|
||||
m_modManager->ReloadMods();
|
||||
}
|
||||
|
||||
void CScreenModList::CloseWindow()
|
||||
{
|
||||
m_main->ChangePhase(PHASE_MAIN_MENU);
|
||||
}
|
||||
|
||||
void CScreenModList::UpdateAll()
|
||||
{
|
||||
UpdateModList();
|
||||
UpdateModDetails();
|
||||
UpdateModSummary();
|
||||
UpdateEnableDisableButton();
|
||||
UpdateApplyButton();
|
||||
UpdateUpDownButtons();
|
||||
}
|
||||
|
||||
void CScreenModList::UpdateModList()
|
||||
{
|
||||
CWindow* pw = static_cast<CWindow*>(m_interface->SearchControl(EVENT_WINDOW5));
|
||||
if (pw == nullptr) return;
|
||||
|
||||
CList* pl = static_cast<CList*>(pw->SearchControl(EVENT_INTERFACE_MOD_LIST));
|
||||
if (pl == nullptr) return;
|
||||
|
||||
pl->Flush();
|
||||
|
||||
if (m_modManager->CountMods() == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const auto& mods = m_modManager->GetMods();
|
||||
for (size_t i = 0; i < mods.size(); ++i)
|
||||
{
|
||||
const auto& mod = mods[i];
|
||||
const auto& name = mod.data.displayName;
|
||||
pl->SetItemName(i, name);
|
||||
pl->SetCheck(i, mod.enabled);
|
||||
pl->SetEnable(i, true);
|
||||
}
|
||||
|
||||
pl->SetSelect(m_modSelectedIndex);
|
||||
pl->ShowSelect(false);
|
||||
}
|
||||
|
||||
void CScreenModList::UpdateModDetails()
|
||||
{
|
||||
CWindow* pw = static_cast<CWindow*>(m_interface->SearchControl(EVENT_WINDOW5));
|
||||
if (pw == nullptr) return;
|
||||
|
||||
CEdit* pe = static_cast<CEdit*>(pw->SearchControl(EVENT_INTERFACE_MOD_DETAILS));
|
||||
if (pe == nullptr) return;
|
||||
|
||||
if (m_modManager->CountMods() == 0)
|
||||
{
|
||||
pe->SetText("No information");
|
||||
return;
|
||||
}
|
||||
|
||||
std::string details{};
|
||||
|
||||
const auto& mod = m_modManager->GetMod(m_modSelectedIndex);
|
||||
const auto data = mod.data;
|
||||
|
||||
details += "\\b;" + data.displayName + '\n';
|
||||
|
||||
std::string authorFieldName;
|
||||
GetResource(RES_TEXT, RT_MOD_AUTHOR_FIELD_NAME, authorFieldName);
|
||||
details += "\\s;" + authorFieldName + " ";
|
||||
if (!data.author.empty())
|
||||
{
|
||||
details += data.author;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string unknownAuthor;
|
||||
GetResource(RES_TEXT, RT_MOD_UNKNOWN_AUTHOR, unknownAuthor);
|
||||
details += unknownAuthor;
|
||||
}
|
||||
details += '\n';
|
||||
|
||||
details += '\n';
|
||||
|
||||
if (!data.version.empty())
|
||||
{
|
||||
std::string versionFieldName;
|
||||
GetResource(RES_TEXT, RT_MOD_VERSION_FIELD_NAME, versionFieldName);
|
||||
details += "\\t;" + versionFieldName + '\n' + data.version + '\n';
|
||||
}
|
||||
|
||||
if (!data.website.empty())
|
||||
{
|
||||
std::string websiteFieldName;
|
||||
GetResource(RES_TEXT, RT_MOD_WEBSITE_FIELD_NAME, websiteFieldName);
|
||||
details += "\\t;" + websiteFieldName + '\n' + data.website + '\n';
|
||||
}
|
||||
|
||||
std::string changesFieldName;
|
||||
GetResource(RES_TEXT, RT_MOD_CHANGES_FIELD_NAME, changesFieldName);
|
||||
details += "\\t;" + changesFieldName + '\n';
|
||||
if (!data.changes.empty())
|
||||
{
|
||||
for (const auto& change : data.changes)
|
||||
{
|
||||
details += change + '\n';
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string noChanges;
|
||||
GetResource(RES_TEXT, RT_MOD_NO_CHANGES, noChanges);
|
||||
details += noChanges;
|
||||
}
|
||||
|
||||
pe->SetText(details);
|
||||
|
||||
pe->SetFirstLine(0);
|
||||
}
|
||||
|
||||
void CScreenModList::UpdateModSummary()
|
||||
{
|
||||
CWindow* pw = static_cast<CWindow*>(m_interface->SearchControl(EVENT_WINDOW5));
|
||||
if (pw == nullptr) return;
|
||||
|
||||
CEdit* pe = static_cast<CEdit*>(pw->SearchControl(EVENT_INTERFACE_MOD_SUMMARY));
|
||||
if (pe == nullptr) return;
|
||||
|
||||
std::string noSummary;
|
||||
GetResource(RES_TEXT, RT_MOD_NO_SUMMARY, noSummary);
|
||||
|
||||
if (m_modManager->CountMods() == 0)
|
||||
{
|
||||
pe->SetText(noSummary);
|
||||
return;
|
||||
}
|
||||
|
||||
const auto& mod = m_modManager->GetMod(m_modSelectedIndex);
|
||||
|
||||
if (!mod.data.summary.empty())
|
||||
{
|
||||
pe->SetText(mod.data.summary);
|
||||
}
|
||||
else
|
||||
{
|
||||
pe->SetText(noSummary);
|
||||
}
|
||||
}
|
||||
|
||||
void CScreenModList::UpdateEnableDisableButton()
|
||||
{
|
||||
CWindow* pw = static_cast<CWindow*>(m_interface->SearchControl(EVENT_WINDOW5));
|
||||
if (pw == nullptr) return;
|
||||
|
||||
CButton* pb = static_cast<CButton*>(pw->SearchControl(EVENT_INTERFACE_MOD_ENABLE_OR_DISABLE));
|
||||
if (pb == nullptr) return;
|
||||
|
||||
std::string buttonName{};
|
||||
|
||||
if (m_modManager->CountMods() == 0)
|
||||
{
|
||||
pb->ClearState(STATE_ENABLE);
|
||||
|
||||
// Set some default name
|
||||
GetResource(RES_TEXT, RT_MOD_ENABLE, buttonName);
|
||||
pb->SetName(buttonName);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
const auto& mod = m_modManager->GetMod(m_modSelectedIndex);
|
||||
|
||||
if (mod.enabled)
|
||||
{
|
||||
GetResource(RES_TEXT, RT_MOD_DISABLE, buttonName);
|
||||
pb->SetName(buttonName);
|
||||
}
|
||||
else
|
||||
{
|
||||
GetResource(RES_TEXT, RT_MOD_ENABLE, buttonName);
|
||||
pb->SetName(buttonName);
|
||||
}
|
||||
}
|
||||
|
||||
void CScreenModList::UpdateApplyButton()
|
||||
{
|
||||
CWindow* pw = static_cast<CWindow*>(m_interface->SearchControl(EVENT_WINDOW5));
|
||||
if (pw == nullptr) return;
|
||||
|
||||
CButton* pb = static_cast<CButton*>(pw->SearchControl(EVENT_INTERFACE_MODS_APPLY));
|
||||
if (pb == nullptr) return;
|
||||
|
||||
if (m_modManager->Changes())
|
||||
{
|
||||
pb->SetState(STATE_ENABLE);
|
||||
}
|
||||
else
|
||||
{
|
||||
pb->ClearState(STATE_ENABLE);
|
||||
}
|
||||
}
|
||||
|
||||
void CScreenModList::UpdateUpDownButtons()
|
||||
{
|
||||
CWindow* pw = static_cast<CWindow*>(m_interface->SearchControl(EVENT_WINDOW5));
|
||||
if (pw == nullptr) return;
|
||||
|
||||
CButton* pb_up = static_cast<CButton*>(pw->SearchControl(EVENT_INTERFACE_MOD_MOVE_UP));
|
||||
if (pb_up == nullptr) return;
|
||||
|
||||
CButton* pb_down = static_cast<CButton*>(pw->SearchControl(EVENT_INTERFACE_MOD_MOVE_DOWN));
|
||||
if (pb_down == nullptr) return;
|
||||
|
||||
if (m_modManager->CountMods() == 0)
|
||||
{
|
||||
pb_up->ClearState(STATE_ENABLE);
|
||||
pb_down->ClearState(STATE_ENABLE);
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_modSelectedIndex == 0)
|
||||
{
|
||||
pb_up->ClearState(STATE_ENABLE);
|
||||
}
|
||||
else
|
||||
{
|
||||
pb_up->SetState(STATE_ENABLE);
|
||||
}
|
||||
|
||||
if (m_modSelectedIndex >= m_modManager->CountMods() - 1)
|
||||
{
|
||||
pb_down->ClearState(STATE_ENABLE);
|
||||
}
|
||||
else
|
||||
{
|
||||
pb_down->SetState(STATE_ENABLE);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Ui
|
|
@ -1,66 +0,0 @@
|
|||
/*
|
||||
* This file is part of the Colobot: Gold Edition source code
|
||||
* Copyright (C) 2001-2023, Daniel Roux, EPSITEC SA & TerranovaTeam
|
||||
* http://epsitec.ch; http://colobot.info; http://github.com/colobot
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see http://gnu.org/licenses
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "app/modman.h"
|
||||
|
||||
#include "ui/maindialog.h"
|
||||
|
||||
#include "ui/screen/screen.h"
|
||||
|
||||
#include <map>
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
|
||||
/**
|
||||
* \class CScreenModList
|
||||
* \brief This class is the front-end for the \ref CModManager.
|
||||
*/
|
||||
class CScreenModList : public CScreen
|
||||
{
|
||||
public:
|
||||
CScreenModList(CMainDialog* dialog, CModManager* modManager);
|
||||
|
||||
void CreateInterface() override;
|
||||
bool EventProcess(const Event &event) override;
|
||||
|
||||
protected:
|
||||
void FindMods();
|
||||
void ApplyChanges();
|
||||
void CloseWindow();
|
||||
|
||||
void UpdateAll();
|
||||
void UpdateModList();
|
||||
void UpdateModDetails();
|
||||
void UpdateModSummary();
|
||||
void UpdateEnableDisableButton();
|
||||
void UpdateApplyButton();
|
||||
void UpdateUpDownButtons();
|
||||
|
||||
protected:
|
||||
Ui::CMainDialog* m_dialog;
|
||||
|
||||
CModManager* m_modManager;
|
||||
|
||||
size_t m_modSelectedIndex = 0;
|
||||
};
|
||||
|
||||
} // namespace Ui
|
|
@ -1,25 +0,0 @@
|
|||
add_library(Colobot-Common STATIC)
|
||||
|
||||
if(NOT CBOT_STATIC)
|
||||
# required to use static library inside CBot shared library
|
||||
set_property(TARGET Colobot-Common PROPERTY POSITION_INDEPENDENT_CODE ON)
|
||||
endif()
|
||||
|
||||
target_sources(Colobot-Common PRIVATE
|
||||
src/common/stringutils.cpp
|
||||
src/common/stringutils.h
|
||||
)
|
||||
|
||||
if(WIN32)
|
||||
target_sources(Colobot-Common PRIVATE
|
||||
src/common/stringutils_windows.cpp
|
||||
)
|
||||
else()
|
||||
target_sources(Colobot-Common PRIVATE
|
||||
src/common/stringutils_generic.cpp
|
||||
)
|
||||
endif()
|
||||
|
||||
target_include_directories(Colobot-Common PUBLIC
|
||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/src>
|
||||
)
|
|
@ -1,167 +0,0 @@
|
|||
/*
|
||||
* This file is part of the Colobot: Gold Edition source code
|
||||
* Copyright (C) 2001-2023, Daniel Roux, EPSITEC SA & TerranovaTeam
|
||||
* http://epsitec.ch; http://colobot.info; http://github.com/colobot
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see http://gnu.org/licenses
|
||||
*/
|
||||
|
||||
|
||||
#include "common/stringutils.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <cstdarg>
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <cwchar>
|
||||
#include <cwctype>
|
||||
#include <stdexcept>
|
||||
#include <vector>
|
||||
|
||||
unsigned int StrUtils::HexStringToInt(const std::string& str)
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << std::hex << str;
|
||||
unsigned int x;
|
||||
ss >> x;
|
||||
return x;
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
std::string VFormat(const char *fmt, va_list ap)
|
||||
{
|
||||
std::array<char, 1024> stackbuf;
|
||||
std::vector<char> dynamicbuf;
|
||||
char *buf = stackbuf.data();
|
||||
size_t size = stackbuf.size();
|
||||
|
||||
while (true)
|
||||
{
|
||||
int needed = vsnprintf (buf, size, fmt, ap);
|
||||
|
||||
if (needed <= static_cast<int>(size) && needed >= 0)
|
||||
{
|
||||
return std::string(buf, static_cast<std::size_t>(needed));
|
||||
}
|
||||
|
||||
size = (needed > 0) ? (needed+1) : (size*2);
|
||||
dynamicbuf.resize(size);
|
||||
buf = dynamicbuf.data();
|
||||
}
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
std::string StrUtils::Format(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
std::string buf = VFormat(fmt, ap);
|
||||
va_end(ap);
|
||||
return buf;
|
||||
}
|
||||
|
||||
std::string StrUtils::Replace(const std::string &str, const std::string &oldStr, const std::string &newStr)
|
||||
{
|
||||
std::string result = str;
|
||||
std::size_t pos = 0;
|
||||
while ((pos = result.find(oldStr, pos)) != std::string::npos)
|
||||
{
|
||||
result.replace(pos, oldStr.length(), newStr);
|
||||
pos += newStr.length();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
std::vector<std::string> StrUtils::Split(const std::string& text, std::string_view separators)
|
||||
{
|
||||
std::string_view stream = text;
|
||||
|
||||
std::vector<std::string> result;
|
||||
std::string part;
|
||||
|
||||
while (!stream.empty())
|
||||
{
|
||||
char c = stream.front();
|
||||
stream.remove_prefix(1);
|
||||
|
||||
if (separators.find(c) != std::string::npos)
|
||||
{
|
||||
if (!part.empty())
|
||||
{
|
||||
result.push_back(part);
|
||||
part.clear();
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
part += c;
|
||||
}
|
||||
|
||||
if (!part.empty()) result.push_back(part);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void StrUtils::TrimLeft(std::string& s)
|
||||
{
|
||||
s.erase(s.begin(), std::find_if(s.begin(), s.end(), [](unsigned char ch) {
|
||||
return !std::isspace(ch);
|
||||
}));
|
||||
}
|
||||
|
||||
void StrUtils::TrimRight(std::string& s)
|
||||
{
|
||||
s.erase(std::find_if(s.rbegin(), s.rend(), [](unsigned char ch) {
|
||||
return !std::isspace(ch);
|
||||
}).base(), s.end());
|
||||
}
|
||||
|
||||
void StrUtils::Trim(std::string& str)
|
||||
{
|
||||
TrimLeft(str);
|
||||
TrimRight(str);
|
||||
}
|
||||
|
||||
void StrUtils::RemoveComments(std::string& text)
|
||||
{
|
||||
for (size_t i = 0; i < text.size(); i++)
|
||||
{
|
||||
char c = text[i];
|
||||
|
||||
// If a string literal of form "text" or 'text', skip
|
||||
if (c == '"' || c == '\'')
|
||||
{
|
||||
size_t j = i + 1;
|
||||
|
||||
while (j < text.size())
|
||||
{
|
||||
if (text[j] == c) break;
|
||||
|
||||
j++;
|
||||
}
|
||||
|
||||
i = j;
|
||||
}
|
||||
// If a comment of form // comment, remove and end processing
|
||||
else if (text[i] == '/' && text[i + 1] == '/')
|
||||
{
|
||||
text.erase(std::next(text.begin(), i), text.end());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,221 +0,0 @@
|
|||
/*
|
||||
* This file is part of the Colobot: Gold Edition source code
|
||||
* Copyright (C) 2001-2023, Daniel Roux, EPSITEC SA & TerranovaTeam
|
||||
* http://epsitec.ch; http://colobot.info; http://github.com/colobot
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see http://gnu.org/licenses
|
||||
*/
|
||||
|
||||
#include "common/stringutils.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <cstdarg>
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <cwchar>
|
||||
#include <cwctype>
|
||||
#include <stdexcept>
|
||||
#include <vector>
|
||||
|
||||
using UTF8Buffer = std::array<char, 8>;
|
||||
|
||||
std::string StrUtils::UnicodeCharToUtf8(unsigned int ch)
|
||||
{
|
||||
UTF8Buffer buffer;
|
||||
|
||||
std::mbstate_t state = {};
|
||||
|
||||
int count = wcrtomb(buffer.data(), static_cast<wchar_t>(ch), &state);
|
||||
|
||||
if (count == 0) count = 1;
|
||||
else if (count == -1) throw std::invalid_argument("Invalid character");
|
||||
|
||||
return std::string(buffer.data(), count);
|
||||
}
|
||||
|
||||
std::string StrUtils::UnicodeStringToUtf8(const std::wstring &str)
|
||||
{
|
||||
std::string result;
|
||||
result.reserve(str.size());
|
||||
|
||||
UTF8Buffer buffer;
|
||||
|
||||
for (const auto& ch : str)
|
||||
{
|
||||
std::mbstate_t state = {};
|
||||
|
||||
size_t len = std::wcrtomb(buffer.data(), ch, &state);
|
||||
|
||||
if (len == 0) len = 1;
|
||||
else if (len == -1) throw std::invalid_argument("Invalid character");
|
||||
|
||||
result.append(buffer.data(), len);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
unsigned int StrUtils::Utf8CharToUnicode(const std::string &ch)
|
||||
{
|
||||
if (ch.empty())
|
||||
return 0;
|
||||
|
||||
std::mbstate_t state = {};
|
||||
|
||||
wchar_t c = 0;
|
||||
|
||||
int len = mbrtowc(&c, ch.data(), ch.size(), &state);
|
||||
|
||||
if (len == 0) return L'\0';
|
||||
else if (len == -1) throw std::invalid_argument("Invalid character");
|
||||
else if (len == -2) throw std::invalid_argument("Invalid character");
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
std::wstring StrUtils::Utf8StringToUnicode(const std::string &str)
|
||||
{
|
||||
std::wstring result;
|
||||
result.reserve(str.size());
|
||||
|
||||
for (size_t i = 0; i < str.size();)
|
||||
{
|
||||
std::mbstate_t state = {};
|
||||
wchar_t ch;
|
||||
|
||||
int len = std::mbrtowc(&ch, str.data() + i, str.size() - i, &state);
|
||||
|
||||
if (len == 0) len = 1;
|
||||
else if (len == -1) throw std::invalid_argument("Invalid character");
|
||||
else if (len == -2) throw std::invalid_argument("Invalid character");
|
||||
|
||||
i += len;
|
||||
|
||||
result += ch;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int StrUtils::Utf8CharSizeAt(const std::string &str, unsigned int pos)
|
||||
{
|
||||
if (pos >= str.size())
|
||||
throw std::out_of_range("Index is greater than size");
|
||||
|
||||
std::mbstate_t state = {};
|
||||
|
||||
int len = std::mbrlen(str.data() + pos, str.size() - pos, &state);
|
||||
|
||||
if (len == 0) len = 1;
|
||||
else if (len == -1) throw std::invalid_argument("Invalid character");
|
||||
else if (len == -2) throw std::invalid_argument("Invalid character");
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
std::size_t StrUtils::Utf8StringLength(const std::string &str)
|
||||
{
|
||||
std::size_t result = 0;
|
||||
|
||||
for (size_t i = 0; i < str.size();)
|
||||
{
|
||||
std::mbstate_t state = {};
|
||||
|
||||
size_t count = std::mbrlen(str.data() + i, str.size() - i, &state);
|
||||
|
||||
if (count == 0) count = 1;
|
||||
else if (count == -1) throw std::invalid_argument("Invalid character");
|
||||
else if (count == -2) throw std::invalid_argument("Invalid character");
|
||||
|
||||
i += count;
|
||||
|
||||
++result;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool StrUtils::isUtf8ContinuationByte(char c)
|
||||
{
|
||||
return (c & 0b1100'0000) == 0b1000'0000;
|
||||
}
|
||||
|
||||
std::string StrUtils::ToLower(const std::string& text)
|
||||
{
|
||||
std::string result;
|
||||
result.reserve(text.size());
|
||||
|
||||
UTF8Buffer buffer;
|
||||
|
||||
for (size_t i = 0; i < text.size();)
|
||||
{
|
||||
std::mbstate_t state = {};
|
||||
wchar_t ch;
|
||||
|
||||
int len = std::mbrtowc(&ch, text.data() + i, text.size() - i, &state);
|
||||
|
||||
if (len == 0) len = 1;
|
||||
else if (len == -1) throw std::invalid_argument("Invalid character");
|
||||
else if (len == -2) throw std::invalid_argument("Invalid character");
|
||||
|
||||
i += len;
|
||||
|
||||
ch = std::towlower(ch);
|
||||
|
||||
state = {};
|
||||
size_t count = std::wcrtomb(buffer.data(), ch, &state);
|
||||
|
||||
if (count == 0) count = 1;
|
||||
else if (count == -1) throw std::invalid_argument("Invalid character");
|
||||
|
||||
result.append(buffer.data(), count);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
std::string StrUtils::ToUpper(const std::string& text)
|
||||
{
|
||||
std::string result;
|
||||
result.reserve(text.size());
|
||||
|
||||
UTF8Buffer buffer;
|
||||
|
||||
for (size_t i = 0; i < text.size();)
|
||||
{
|
||||
std::mbstate_t state = {};
|
||||
wchar_t ch;
|
||||
|
||||
size_t len = std::mbrtowc(&ch, text.data() + i, text.size() - i, &state);
|
||||
|
||||
if (len == 0) len = 1;
|
||||
else if (len == -1) throw std::invalid_argument("Invalid character");
|
||||
else if (len == -2) throw std::invalid_argument("Invalid character");
|
||||
|
||||
i += len;
|
||||
|
||||
ch = std::towupper(ch);
|
||||
|
||||
state = {};
|
||||
size_t count = std::wcrtomb(buffer.data(), ch, &state);
|
||||
|
||||
if (count == 0) count = 1;
|
||||
else if (count == -1) throw std::invalid_argument("Invalid character");
|
||||
|
||||
result.append(buffer.data(), count);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
|
@ -1,148 +0,0 @@
|
|||
/*
|
||||
* This file is part of the Colobot: Gold Edition source code
|
||||
* Copyright (C) 2001-2023, Daniel Roux, EPSITEC SA & TerranovaTeam
|
||||
* http://epsitec.ch; http://colobot.info; http://github.com/colobot
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see http://gnu.org/licenses
|
||||
*/
|
||||
|
||||
|
||||
#include "common/stringutils.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <stdexcept>
|
||||
#include <vector>
|
||||
|
||||
#include <Windows.h>
|
||||
#include <stringapiset.h>
|
||||
|
||||
std::string StrUtils::UnicodeCharToUtf8(unsigned int ch)
|
||||
{
|
||||
wchar_t character = ch;
|
||||
std::array<char, 8> buffer;
|
||||
|
||||
int length = WideCharToMultiByte(CP_UTF8, 0,
|
||||
&character, 1, buffer.data(), buffer.size(), nullptr, nullptr);
|
||||
|
||||
if (length == 0) throw std::invalid_argument("Invalid character");
|
||||
|
||||
return std::string(buffer.data(), length);
|
||||
}
|
||||
|
||||
std::string StrUtils::UnicodeStringToUtf8(const std::wstring &str)
|
||||
{
|
||||
int length = WideCharToMultiByte(CP_UTF8, 0,
|
||||
str.c_str(), str.size(), nullptr, 0, nullptr, nullptr);
|
||||
|
||||
if (length == 0) throw std::invalid_argument("Invalid character");
|
||||
|
||||
std::string result(length, '\0');
|
||||
|
||||
length = WideCharToMultiByte(CP_UTF8, 0, str.c_str(), str.size(),
|
||||
result.data(), result.size() + 1, nullptr, nullptr);
|
||||
|
||||
if (length == 0) throw std::invalid_argument("Invalid character");
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
unsigned int StrUtils::Utf8CharToUnicode(const std::string &ch)
|
||||
{
|
||||
if (ch.empty())
|
||||
return 0;
|
||||
|
||||
wchar_t c = 0;
|
||||
|
||||
int length = MultiByteToWideChar(CP_UTF8, 0,
|
||||
ch.c_str(), ch.size(), &c, 1);
|
||||
|
||||
if (length == 0) throw std::invalid_argument("Invalid character");
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
std::wstring StrUtils::Utf8StringToUnicode(const std::string &str)
|
||||
{
|
||||
int length = MultiByteToWideChar(CP_UTF8, 0,
|
||||
str.c_str(), str.size(), nullptr, 0);
|
||||
|
||||
if (length == 0) throw std::invalid_argument("Invalid character");
|
||||
|
||||
std::wstring result(length, L'\0');
|
||||
|
||||
length = MultiByteToWideChar(CP_UTF8, 0,
|
||||
str.c_str(), str.size(), result.data(), length);
|
||||
|
||||
if (length == 0) throw std::invalid_argument("Invalid character");
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int StrUtils::Utf8CharSizeAt(const std::string &str, unsigned int pos)
|
||||
{
|
||||
if (pos >= str.size())
|
||||
throw std::out_of_range("Index is greater than size");
|
||||
|
||||
std::array<wchar_t, 4> buffer;
|
||||
|
||||
int remaining = str.size() - pos;
|
||||
if (remaining > 4) remaining = 4;
|
||||
|
||||
int length = MultiByteToWideChar(CP_UTF8, 0,
|
||||
str.data() + pos, remaining,
|
||||
buffer.data(), buffer.size());
|
||||
|
||||
if (length == 0) throw std::invalid_argument("Invalid character");
|
||||
|
||||
length = WideCharToMultiByte(CP_UTF8, 0,
|
||||
buffer.data(), 1, nullptr, 0, 0, 0);
|
||||
|
||||
if (length == 0) throw std::invalid_argument("Invalid character");
|
||||
|
||||
return length;
|
||||
}
|
||||
|
||||
std::size_t StrUtils::Utf8StringLength(const std::string &str)
|
||||
{
|
||||
int length = MultiByteToWideChar(CP_UTF8, 0,
|
||||
str.c_str(), str.size(), nullptr, 0);
|
||||
|
||||
if (length == 0) throw std::invalid_argument("Invalid character");
|
||||
|
||||
return length;
|
||||
}
|
||||
|
||||
bool StrUtils::isUtf8ContinuationByte(char c)
|
||||
{
|
||||
return (c & 0b1100'0000) == 0b1000'0000;
|
||||
}
|
||||
|
||||
std::string StrUtils::ToLower(const std::string& text)
|
||||
{
|
||||
std::wstring unicode = Utf8StringToUnicode(text);
|
||||
|
||||
CharLowerBuffW(unicode.data(), unicode.size());
|
||||
|
||||
return UnicodeStringToUtf8(unicode);
|
||||
}
|
||||
|
||||
std::string StrUtils::ToUpper(const std::string& text)
|
||||
{
|
||||
std::wstring unicode = Utf8StringToUnicode(text);
|
||||
|
||||
CharUpperBuffW(unicode.data(), unicode.size());
|
||||
|
||||
return UnicodeStringToUtf8(unicode);
|
||||
}
|
2
data
2
data
|
@ -1 +1 @@
|
|||
Subproject commit 1759e5bd31bf0cadaf44723f7852423fe6912df1
|
||||
Subproject commit c467bd994e60fb54cf977fbe8583f92957330695
|
|
@ -1,4 +1,4 @@
|
|||
cmake_minimum_required(VERSION 3.16)
|
||||
cmake_minimum_required(VERSION 2.8)
|
||||
|
||||
set(COLOBOT_ICON_FILE ${CMAKE_CURRENT_SOURCE_DIR}/colobot.svg)
|
||||
|
||||
|
@ -156,7 +156,12 @@ if(PLATFORM_MACOSX)
|
|||
endif(PLATFORM_MACOSX)
|
||||
|
||||
if(PLATFORM_WINDOWS)
|
||||
set(COLOBOT_VERSION_4COMMAS "${CMAKE_PROJECT_VERSION_MAJOR},${CMAKE_PROJECT_VERSION_MINOR},${CMAKE_PROJECT_VERSION_PATCH},${CMAKE_PROJECT_VERSION_TWEAK}")
|
||||
if(COLOBOT_VERSION_REVISION MATCHES "([0-9]+)\\.([0-9]+)")
|
||||
string(REGEX REPLACE "([0-9]+)\\.([0-9]+)" "\\1,\\2" COLOBOT_VERSION_REVISION_COMMA "${COLOBOT_VERSION_REVISION}")
|
||||
set(COLOBOT_VERSION_4COMMAS "${COLOBOT_VERSION_MAJOR},${COLOBOT_VERSION_MINOR},${COLOBOT_VERSION_REVISION_COMMA}")
|
||||
else()
|
||||
set(COLOBOT_VERSION_4COMMAS "${COLOBOT_VERSION_MAJOR},${COLOBOT_VERSION_MINOR},${COLOBOT_VERSION_REVISION},0")
|
||||
endif()
|
||||
configure_file(colobot.rc.cmake ${CMAKE_CURRENT_BINARY_DIR}/colobot.rc)
|
||||
endif(PLATFORM_WINDOWS)
|
||||
|
||||
|
@ -170,9 +175,9 @@ set(CPACK_PACKAGE_DESCRIPTION_FILE "${CMAKE_CURRENT_SOURCE_DIR}/../README.md")
|
|||
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Colobot: Gold Edition")
|
||||
set(CPACK_PACKAGE_VENDOR "TerranovaTeam")
|
||||
|
||||
set(CPACK_PACKAGE_VERSION_MAJOR ${CMAKE_PROJECT_VERSION_MAJOR})
|
||||
set(CPACK_PACKAGE_VERSION_MINOR ${CMAKE_PROJECT_VERSION_MINOR})
|
||||
set(CPACK_PACKAGE_VERSION_PATCH ${CMAKE_PROJECT_VERSION_PATCH})
|
||||
set(CPACK_PACKAGE_VERSION_MAJOR ${COLOBOT_VERSION_MAJOR})
|
||||
set(CPACK_PACKAGE_VERSION_MINOR ${COLOBOT_VERSION_MINOR})
|
||||
set(CPACK_PACKAGE_VERSION_PATCH ${COLOBOT_VERSION_REVISION})
|
||||
|
||||
if(PLATFORM_WINDOWS)
|
||||
set(CPACK_STRIP_FILES TRUE)
|
||||
|
|
Before Width: | Height: | Size: 4.9 KiB After Width: | Height: | Size: 4.9 KiB |
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
Binary file not shown.
Before Width: | Height: | Size: 10 KiB |
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue