diff --git a/.gitignore b/.gitignore index 6f094c23a183dc06d291a5f2ec4baa6e9bdaeb99..1bca81dc46774127805661e5efe50517b113d6c6 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ BUILD* .dir-locals.el *.pyc x64/ +TAGS diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 0944eae2f5b68a49b59a80d6d80e1516d7113925..bd70efcfca3aea4ab861f211810a9a55079822ee 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -168,7 +168,7 @@ build:linux:gcc5.3.1: - cd build - make Cpplint-Test-Suite - make Cppcheck-Test-Suite - - make -j + - make -j8 artifacts: paths: - build @@ -186,7 +186,7 @@ build:linux:gcc6.3.1: - cd build - make Cpplint-Test-Suite - make Cppcheck-Test-Suite - - make -j + - make -j8 artifacts: paths: - build diff --git a/CMakeLists.txt b/CMakeLists.txt index 2e91b48732b0221406d8057aa61229c86dd2ee02..09a00f1f0b518516658fcd8cd92418d8dea66257 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -46,12 +46,13 @@ include(GenerateExportHeader) include(WarningLevels) conan_or_find_package(gl REQUIRED) -conan_or_find_package(boost REQUIRED) +conan_or_find_package(boost_optional REQUIRED) +conan_or_find_package(boost_signals2 REQUIRED) conan_or_find_package(glew REQUIRED) conan_or_find_package(glm REQUIRED) conan_or_find_package(assimp REQUIRED) find_package(OpenGL REQUIRED) -conan_or_find_package(SDL2 REQUIRED) +conan_or_find_package(sdl2 REQUIRED) conan_or_find_package(spdlog REQUIRED) conan_or_find_package(freeimage REQUIRED) conan_or_find_package(openvr REQUIRED) diff --git a/EXTERNALS.md b/EXTERNALS.md new file mode 100644 index 0000000000000000000000000000000000000000..4c616a1cd6827929fc25ad7fadcb1e53f0d63794 --- /dev/null +++ b/EXTERNALS.md @@ -0,0 +1,464 @@ +# External libraries + +Project Phoenix uses the following external libraries, each using their own license: +* [Assimp](#assimp) +* [Boost](#boost) +* [Catch2](#catch2) +* [cpplint](#cpplint) +* [Freeimage](#freeimage) +* [gl](#gl) +* [glew](#glew) +* [glm](#glm) +* [JSON for Modern C++](#json-for-modern-c) +* [OpenVR SDK](#openvr-sdk) +* [SDL 2](#sdl-2) +* [spdlog](#spdlog) +* [trompeloeil](#trompeloeil) + +## Assimp +available at (http://assimp.sourceforge.net/) +### 3-clause BSD license + +Copyright (c) 2006-2015 assimp team +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 the assimp team nor the names of its 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 OWNER 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. + + +## Boost +available at (http://www.boost.org) +### Boost Software License + +Boost Software License - Version 1.0 - August 17th, 2003 + +Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the software and accompanying documentation covered by +this license (the "Software") to use, reproduce, display, distribute, +execute, and transmit the Software, and to prepare derivative works of the +Software, and to permit third-parties to whom the Software is furnished to +do so, all subject to the following: + +The copyright notices in the Software and this entire statement, including +the above license grant, this restriction and the following disclaimer, +must be included in all copies of the Software, in whole or in part, and +all derivative works of the Software, unless such copies or derivative +works are solely in the form of machine-executable object code generated by +a source language processor. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. + + +## Catch2 +available at (https://github.com/catchorg/Catch2) +###Boost Software License + +Boost Software License - Version 1.0 - August 17th, 2003 + +Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the software and accompanying documentation covered by +this license (the "Software") to use, reproduce, display, distribute, +execute, and transmit the Software, and to prepare derivative works of the +Software, and to permit third-parties to whom the Software is furnished to +do so, all subject to the following: + +The copyright notices in the Software and this entire statement, including +the above license grant, this restriction and the following disclaimer, +must be included in all copies of the Software, in whole or in part, and +all derivative works of the Software, unless such copies or derivative +works are solely in the form of machine-executable object code generated by +a source language processor. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. + + +## cpplint +available at (https://github.com/cpplint/cpplint) +### 3-clause BSD license + +cpplint.py and its corresponding unit tests are Copyright (C) 2009 Google Inc. + +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 Google Inc. nor the names of its +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 +OWNER 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. + + +## Freeimage +available at (http://freeimage.sourceforge.net/) +### Freeimage Public License - Version 1.0 + +1. Definitions. +1.1. "Contributor" means each entity that creates or contributes to the creation of Modifications. +1.2. "Contributor Version" means the combination of the Original Code, prior Modifications used by a Contributor, and the Modifications made by that particular Contributor. +1.3. "Covered Code" means the Original Code or Modifications or the combination of the Original Code and Modifications, in each case including portions thereof. +1.4. "Electronic Distribution Mechanism" means a mechanism generally accepted in the software development community for the electronic transfer of data. +1.5. "Executable" means Covered Code in any form other than Source Code. +1.6. "Initial Developer" means the individual or entity identified as the Initial Developer in the Source Code notice required by Exhibit A. +1.7. "Larger Work" means a work which combines Covered Code or portions thereof with code not governed by the terms of this License. +1.8. "License" means this document. +1.9. "Modifications" means any addition to or deletion from the substance or structure of either the Original Code or any previous Modifications. When Covered Code is released as a series of files, a +Modification is: +A. Any addition to or deletion from the contents of a file containing Original Code or previous Modifications. +B. Any new file that contains any part of the Original Code or previous Modifications. +1.10. "Original Code" means Source Code of computer software code which is described in the Source Code notice required by Exhibit A as Original Code, and which, at the time of its release under this License is not already Covered Code governed by this License. +1.11. "Source Code" means the preferred form of the Covered Code for making modifications to it, including all modules it contains, plus any associated interface definition files, scripts used to control +compilation and installation of an Executable, or a list of source code differential comparisons against either the Original Code or another well known, available Covered Code of the Contributor's choice. The Source Code can be in a compressed or archival form, provided the appropriate decompression or de-archiving software is widely available for no charge. +1.12. "You" means an individual or a legal entity exercising rights under, and complying with all of the terms of, this License or a future version of this License issued under Section 6.1. For legal entities, "You" includes any entity which controls, is controlled by, or is under common control with You. For purposes of this definition, "control" means (a) the power, direct or indirect, to cause the +direction or management of such entity, whether by contract or otherwise, or (b) ownership of fifty percent (50%) or more of the outstanding shares or beneficial ownership of such entity. +2. Source Code License. +2.1. The Initial Developer Grant. +The Initial Developer hereby grants You a world-wide, royalty-free, non-exclusive license, subject to third party intellectual property claims: +(a) to use, reproduce, modify, display, perform, sublicense and distribute the Original Code (or portions thereof) with or without Modifications, or as part of a Larger Work; and +(b) under patents now or hereafter owned or controlled by Initial Developer, to make, have made, use and sell ("Utilize") the Original Code (or portions thereof), but solely to the extent that +any such patent is reasonably necessary to enable You to Utilize the Original Code (or portions thereof) and not to any greater extent that may be necessary to Utilize further Modifications or +combinations. +2.2. Contributor Grant. +Each Contributor hereby grants You a world-wide, royalty-free, non-exclusive license, subject to third party intellectual property claims: +(a) to use, reproduce, modify, display, perform, sublicense and distribute the Modifications created by such Contributor (or portions thereof) either on an unmodified basis, with other Modifications, as Covered Code or as part of a Larger Work; and +(b) under patents now or hereafter owned or controlled by Contributor, to Utilize the Contributor Version (or portions thereof), but solely to the extent that any such patent is reasonably necessary to enable You to Utilize the Contributor Version (or portions thereof), and not to any greater extent that +may be necessary to Utilize further Modifications or combinations. +3. Distribution Obligations. +3.1. Application of License. +The Modifications which You create or to which You contribute are governed by the terms of this License, including without limitation Section 2.2. The Source Code version of Covered Code may be distributed only under the terms of this License or a future version of this License released under Section 6.1, and You must include a copy of this License with every copy of the Source Code You distribute. You may not offer or impose any terms on any Source Code version that alters or +restricts the applicable version of this License or the recipients' rights hereunder. However, You may include an additional document offering the additional rights described in Section 3.5. +3.2. Availability of Source Code. +Any Modification which You create or to which You contribute must be made available in Source Code form under the terms of this License either on the same media as an Executable version or via an accepted Electronic Distribution Mechanism to anyone to whom you made an Executable version available; and if made available via Electronic Distribution Mechanism, must remain available for at least twelve (12) months after the date it initially became available, or at least six (6) months after a subsequent version of that particular Modification has been made available to such recipients. You are responsible for ensuring that the Source Code version remains available even if the Electronic Distribution Mechanism is maintained by a third party. +3.3. Description of Modifications. +You must cause all Covered Code to which you contribute to contain a file documenting the changes You made to create that Covered Code and the date of any change. You must include a prominent statement that the Modification is derived, directly or indirectly, from Original Code provided by the Initial Developer and including the name of the Initial Developer in (a) the Source Code, and (b) in any notice in an Executable version or related documentation in which You describe the origin or ownership of the Covered Code. +3.4. Intellectual Property Matters +(a) Third Party Claims. +If You have knowledge that a party claims an intellectual property right in particular functionality or code (or its utilization under this License), you must include a text file with the source code distribution titled "LEGAL" which describes the claim and the party making the claim in sufficient detail that a recipient will know whom to contact. If you obtain such knowledge after You make Your Modification available as described in Section 3.2, You shall promptly modify the LEGAL file in all copies You make +available thereafter and shall take other steps (such as notifying appropriate mailing lists or newsgroups) reasonably calculated to inform those who received the Covered Code that new knowledge has been obtained. +(b) Contributor APIs. +If Your Modification is an application programming interface and You own or control patents which are reasonably necessary to implement that API, you must also include this information in the LEGAL file. +3.5. Required Notices. +You must duplicate the notice in Exhibit A in each file of the Source Code, and this License in any documentation for the Source Code, where You describe recipients' rights relating to Covered Code. If You created one or more Modification(s), You may add your name as a Contributor to the notice described in Exhibit A. If it is not possible to put such notice in a particular Source Code file due to its +structure, then you must include such notice in a location (such as a relevant directory file) where a user would be likely to look for such a notice. You may choose to offer, and to charge a fee for, warranty, support, indemnity or liability obligations to one or more recipients of Covered Code. However, You may do so only on Your own behalf, and not on behalf of the Initial Developer or any Contributor. You must make it absolutely clear than any such warranty, support, indemnity or +liability obligation is offered by You alone, and You hereby agree to indemnify the Initial Developer and every Contributor for any liability incurred by the Initial Developer or such Contributor as a result of +warranty, support, indemnity or liability terms You offer. +3.6. Distribution of Executable Versions. +You may distribute Covered Code in Executable form only if the requirements of Section 3.1-3.5 have been met for that Covered Code, and if You include a notice stating that the Source Code version of the Covered Code is available under the terms of this License, including a description of how and where You have fulfilled the obligations of Section 3.2. The notice must be conspicuously included in any notice in an Executable version, related documentation or collateral in which You +describe recipients' rights relating to the Covered Code. You may distribute the Executable version of Covered Code under a license of Your choice, which may contain terms different from this License, +provided that You are in compliance with the terms of this License and that the license for the Executable version does not attempt to limit or alter the recipient's rights in the Source Code version from the rights set forth in this License. If You distribute the Executable version under a different license You must make it absolutely clear that any terms which differ from this License are offered by You alone, not by the Initial Developer or any Contributor. You hereby agree to indemnify the Initial Developer and every Contributor for any liability incurred by the Initial Developer or such Contributor as a result of any such terms You offer. +3.7. Larger Works. +You may create a Larger Work by combining Covered Code with other code not governed by the terms of this License and distribute the Larger Work as a single product. In such a case, You must make sure the requirements of this License are fulfilled for the Covered Code. +4. Inability to Comply Due to Statute or Regulation. +If it is impossible for You to comply with any of the terms of this License with respect to some or all of the Covered Code due to statute or regulation then You must: (a) comply with the terms of this License to the maximum extent possible; and (b) describe the limitations and the code they affect. Such description must be included in the LEGAL file described in Section 3.4 and must be included with all distributions of the Source Code. Except to the extent prohibited by statute or regulation, such description must be sufficiently detailed for a recipient of ordinary skill to be able to understand it. +5. Application of this License. +This License applies to code to which the Initial Developer has attached the notice in Exhibit A, and to related Covered Code. +6. Versions of the License. +6.1. New Versions. +Floris van den Berg may publish revised and/or new versions of the License from time to time. Each version will be given a distinguishing version number. +6.2. Effect of New Versions. +Once Covered Code has been published under a particular version of the License, You may always continue to use it under the terms of that version. You may also choose to use such Covered Code under the terms of any subsequent version of the License published by Floris van den Berg +No one other than Floris van den Berg has the right to modify the terms applicable to Covered Code created under this License. +6.3. Derivative Works. +If you create or use a modified version of this License (which you may only do in order to apply it to code which is not already Covered Code governed by this License), you must (a) rename Your license so that the phrases "FreeImage", `FreeImage Public License", "FIPL", or any confusingly similar phrase do not appear anywhere in your license and (b) otherwise make it clear that your version of the license contains terms which differ from the FreeImage Public License. (Filling in the name of the Initial Developer, Original Code or Contributor in the notice described in Exhibit A shall not of themselves be deemed to be modifications of this License.) +7. DISCLAIMER OF WARRANTY. +COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES THAT THE COVERED CODE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER THIS DISCLAIMER. +8. TERMINATION. +This License and the rights granted hereunder will terminate automatically if You fail to comply with terms herein and fail to cure such breach within 30 days of becoming aware of the breach. All sublicenses to the Covered Code which are properly granted shall survive any termination of this License. Provisions which, by their nature, must remain in effect beyond the termination of this License shall survive. +9. LIMITATION OF LIABILITY. +UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, WHETHER TORT (INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE, SHALL THE INITIAL DEVELOPER, ANY OTHER CONTRIBUTOR, OR ANY DISTRIBUTOR OF COVERED CODE, OR ANY SUPPLIER OF ANY OF SUCH PARTIES, BE LIABLE TO YOU OR ANY OTHER PERSON FOR ANY INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY CHARACTER INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF GOODWILL, WORK STOPPAGE, COMPUTER FAILURE OR MALFUNCTION, OR ANY AND ALL OTHER COMMERCIAL DAMAGES OR LOSSES, EVEN IF SUCH PARTY SHALL HAVE BEEN INFORMED OF THE POSSIBILITY OF SUCH DAMAGES. THIS LIMITATION OF LIABILITY SHALL NOT APPLY TO LIABILITY FOR DEATH OR PERSONAL INJURY RESULTING FROM SUCH PARTY'S NEGLIGENCE TO THE EXTENT APPLICABLE LAW PROHIBITS SUCH LIMITATION. SOME JURISDICTIONS DO NOT ALLOW THE +EXCLUSION OR LIMITATION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO THAT EXCLUSION AND LIMITATION MAY NOT APPLY TO YOU. +10. U.S. GOVERNMENT END USERS. +The Covered Code is a "commercial item," as that term is defined in 48 C.F.R. 2.101 (Oct. 1995), consisting of "commercial computer software" and "commercial computer software documentation," as such terms are used in 48 C.F.R. 12.212 (Sept. 1995). Consistent with 48 C.F.R. 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 (June 1995), all U.S. Government End Users acquire Covered Code with only those rights set forth herein. +11. MISCELLANEOUS. +This License represents the complete agreement concerning subject matter hereof. If any provision of this License is held to be unenforceable, such provision shall be reformed only to the extent necessary to make it enforceable. This License shall be governed by Dutch law provisions (except to the extent applicable law, if any, provides otherwise), excluding its conflict-of-law provisions. With respect to disputes in which at least one party is a citizen of, or an entity chartered or registered to do business in, the The Netherlands: (a) unless otherwise agreed in writing, all disputes relating to this License (excepting any dispute relating to intellectual property rights) shall be subject to final and binding arbitration, with the losing party paying all costs of arbitration; (b) any arbitration relating to this Agreement shall be held in Almelo, The Netherlands; and (c) any litigation relating to this Agreement shall be subject to the jurisdiction of the court of Almelo, The Netherlands with the losing party responsible for costs, including without limitation, court costs and reasonable attorneys fees and expenses. Any law or regulation which provides that the language of a contract shall be construed against the drafter shall not apply to this License. +12. RESPONSIBILITY FOR CLAIMS. +Except in cases where another Contributor has failed to comply with Section 3.4, You are responsible for damages arising, directly or indirectly, out of Your utilization of rights under this License, based +on the number of copies of Covered Code you made available, the revenues you received from utilizing such rights, and other relevant factors. You agree to work with affected parties to distribute +responsibility on an equitable basis. + +EXHIBIT A. +"The contents of this file are subject to the FreeImage Public License Version 1.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://home.wxs.nl/~flvdberg/freeimage-license.txt +Software distributed under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for the specific language governing rights and limitations under the License. + + +## gl +available at (https://github.com/acdemiralp/gl) +### Boost Software License - Version 1.0 + +Boost Software License - Version 1.0 - August 17th, 2003 + +Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the software and accompanying documentation covered by +this license (the "Software") to use, reproduce, display, distribute, +execute, and transmit the Software, and to prepare derivative works of the +Software, and to permit third-parties to whom the Software is furnished to +do so, all subject to the following: + +The copyright notices in the Software and this entire statement, including +the above license grant, this restriction and the following disclaimer, +must be included in all copies of the Software, in whole or in part, and +all derivative works of the Software, unless such copies or derivative +works are solely in the form of machine-executable object code generated by +a source language processor. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. + + + +## glew +available at (http://glew.sourceforge.net/) +### Khronos License + +Copyright (c) 2007 The Khronos Group Inc. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and/or associated documentation files (the +"Materials"), to deal in the Materials without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Materials, and to +permit persons to whom the Materials are furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Materials. + +THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. + + +## glm +available at (https://glm.g-truc.net) +### The Happy Bunny License +================================================================================ +OpenGL Mathematics (GLM) +-------------------------------------------------------------------------------- +GLM is licensed under The Happy Bunny License and MIT License + +================================================================================ +The Happy Bunny License (Modified MIT License) +-------------------------------------------------------------------------------- +Copyright (c) 2005 - 2014 G-Truc Creation + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +Restrictions: + By making use of the Software for military purposes, you choose to make a + Bunny unhappy. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +================================================================================ +The MIT License +-------------------------------------------------------------------------------- +Copyright (c) 2005 - 2014 G-Truc Creation + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + + +## JSON for Modern C++ +available at (https://github.com/nlohmann/json) +### MIT License + +MIT License + +Copyright (c) 2013-2018 Niels Lohmann + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + + +## OpenVR SDK +available at (https://github.com/ValveSoftware/openvr) +### License +Copyright (c) 2015, Valve Corporation +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this +list of conditions and the following disclaimer. + +2. 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. + +3. Neither the name of the copyright holder nor the names of its 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. + + +## SDL 2 +available at (https://www.libsdl.org) +### zlib license + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any damages +arising from the use of this software. + +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it +freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. + + +## spdlog +available at (https://github.com/gabime/spdlog) +### MIT license + +The MIT License (MIT) + +Copyright (c) 2016 Gabi Melman. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + + +## trompeloeil +available at (https://github.com/rollbear/trompeloeil) +### Boost Software License - Version 1.0 + +Boost Software License - Version 1.0 - August 17th, 2003 + +Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the software and accompanying documentation covered by +this license (the "Software") to use, reproduce, display, distribute, +execute, and transmit the Software, and to prepare derivative works of the +Software, and to permit third-parties to whom the Software is furnished to +do so, all subject to the following: + +The copyright notices in the Software and this entire statement, including +the above license grant, this restriction and the following disclaimer, +must be included in all copies of the Software, in whole or in part, and +all derivative works of the Software, unless such copies or derivative +works are solely in the form of machine-executable object code generated by +a source language processor. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/LICENSE b/LICENSE index 44a184c18c328385d7aba4d554b25cb9035d8db1..898ac02fd787f43a70dfb95a03ea00d1f6876221 100644 --- a/LICENSE +++ b/LICENSE @@ -16,204 +16,30 @@ 52074 Aachen -------------------------------------------------------------------------------- - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. +The 3-Clause BSD License + +Copyright 2017-2018 Virtual Reality & Immersive Visualization Group, +RWTH Aachen University, Germany. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. +2. 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. +3. Neither the name of the copyright holder nor the names of its 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. \ No newline at end of file diff --git a/README.md b/README.md index 6e740b179a115ceca887a1edf8de4c64ab8561fd..f11bf1102f35d13fe0d395b182dd5e61a7efa8c9 100644 --- a/README.md +++ b/README.md @@ -22,3 +22,9 @@ distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + + +## External libraries + +Project Phoenix uses external libraries that are listed in the file +[EXTERNALS.md](EXTERNALS.md) along with their corresponding license information. \ No newline at end of file diff --git a/cmake/ConanHelpers.cmake b/cmake/ConanHelpers.cmake index e5166a7fc4b22bb0ae4345f54795ca3d229c949c..5aa92e447add76dbf54878d886948664e96e4ea9 100644 --- a/cmake/ConanHelpers.cmake +++ b/cmake/ConanHelpers.cmake @@ -22,6 +22,8 @@ #download/build the missing dependencies include(conan) +execute_process(COMMAND conan remote add bincrafters https://api.bintray.com/conan/bincrafters/public-conan False OUTPUT_QUIET) +execute_process(COMMAND conan remote add rwth-vr https://api.bintray.com/conan/rwth-vr/conan False OUTPUT_QUIET) conan_cmake_run(CONANFILE conanfile.py BUILD missing) @@ -95,11 +97,15 @@ macro(CONAN_OR_FIND_PACKAGE package) # set target variable to be used in target_link_libraries accordingly option(USE_CONAN_${package} "Use conan for dependency ${package}" ${USE_CONAN}) + string(REPLACE "." "_" + package_underscored + ${package} + ) if(USE_CONAN AND USE_CONAN_${package}) - set(CONAN_OR_CMAKE_${package} ${CONAN_PACKAGE_NAME}) + set(CONAN_OR_CMAKE_${package_underscored} ${CONAN_PACKAGE_NAME}) else() find_package(${package} ${ADDITIONAL_PARAMS}) - set(CONAN_OR_CMAKE_${package} ${package}) + set(CONAN_OR_CMAKE_${package_underscored} ${package}) endif() endmacro() diff --git a/cmake/WarningLevels.cmake b/cmake/WarningLevels.cmake index 2fbf048bdc3ae797c38ea9bccc836279d9e3dd13..8b20c58477352b4a7a88ff43a9d073d39bfd4c2d 100644 --- a/cmake/WarningLevels.cmake +++ b/cmake/WarningLevels.cmake @@ -32,6 +32,8 @@ set(WARNING_LEVELS_RWTH_CLANG -Wno-c++98-compat -Wno-c++98-compat-pedantic -Wno-weak-vtables + -Wno-exit-time-destructors + -Wno-global-constructors ) set(WARNING_LEVELS_RWTH_GCC @@ -54,23 +56,6 @@ set(WARNING_LEVELS_RWTH_MSVC "$<$<CXX_COMPILER_ID:MSVC>:/w14312>" ) - -# flags for overriding warning levels for files generated by Qt's MOC -set(WARNING_LEVELS_RWTH_CLANG_QT_MOC_OVERRIDE - -Wno-padded - -Wno-undefined-reinterpret-cast -) - -set(WARNING_LEVELS_RWTH_GCC_QT_MOC_OVERRIDE - -Wno-padded - -Wno-undefined-reinterpret-cast -) - -set(WARNING_LEVELS_RWTH_MSVC_QT_MOC_OVERRIDE - -W0 -) - - # compiler identification if(CMAKE_C_COMPILER_ID MATCHES "Clang" AND CMAKE_CXX_COMPILER_ID MATCHES "Clang") @@ -105,28 +90,10 @@ macro(SET_WARNING_LEVELS_RWTH TARGET) if(IS_CLANG) target_compile_options(${TARGET} PRIVATE ${WARNING_LEVELS_RWTH_CLANG}) - if (CMAKE_AUTOMOC) - set_source_files_properties( - ${CMAKE_CURRENT_BINARY_DIR}/${TARGET}_autogen/moc_compilation.cpp - PROPERTIES COMPILE_FLAGS ${WARNING_LEVELS_RWTH_CLANG_QT_MOC_OVERRIDE}) - endif () - target_compile_options(${TARGET} PRIVATE "-include${SUPPRESS_WARNING_HEADER_FILE}") elseif(IS_GCC) target_compile_options(${TARGET} PRIVATE ${WARNING_LEVELS_RWTH_GCC}) - if (CMAKE_AUTOMOC) - set_source_files_properties( - ${CMAKE_CURRENT_BINARY_DIR}/${TARGET}_autogen/moc_compilation.cpp - PROPERTIES COMPILE_FLAGS ${WARNING_LEVELS_RWTH_GCC_QT_MOC_OVERRIDE}) - endif () - target_compile_options(${TARGET} PRIVATE "-include${SUPPRESS_WARNING_HEADER_FILE}") elseif(IS_MSVC) target_compile_options(${TARGET} PRIVATE ${WARNING_LEVELS_RWTH_MSVC}) - if (CMAKE_AUTOMOC) - set_source_files_properties( - ${CMAKE_CURRENT_BINARY_DIR}/${target}_autogen/moc_compilation.cpp - PROPERTIES COMPILE_FLAGS ${WARNING_LEVELS_RWTH_MSVC_QT_MOC_OVERRIDE}) - endif () - target_compile_options(${TARGET} PRIVATE "/FI ${SUPPRESS_WARNING_HEADER_FILE}") else() message(WARNING "SET_WARNING_LEVELS_RWTH not implemented for your compiler. " "Implement it to support our no-warning policy.") diff --git a/cmake/conan.cmake b/cmake/conan.cmake index 65f73023a5a49fa74db9b59793eb351da3ed27b4..80e14f33415e8d269a6df3cff5e4a5594937ec90 100644 --- a/cmake/conan.cmake +++ b/cmake/conan.cmake @@ -1,36 +1,23 @@ -# Makes conan install callable from within cmake -# Copied from https://raw.githubusercontent.com/conan-io/cmake-conan/master/conan.cmake -# See https://github.com/conan-io/cmake-conan - - include(CMakeParseArguments) function(_get_msvc_ide_version result) set(${result} "" PARENT_SCOPE) - if(${CMAKE_GENERATOR} STREQUAL "Ninja") - string(REGEX MATCHALL "[0-9]+" output "$ENV{VisualStudioVersion}") - list(GET output 0 _msvc_version) - set(${result} ${_msvc_version} PARENT_SCOPE) + if(NOT MSVC_VERSION VERSION_LESS 1400 AND MSVC_VERSION VERSION_LESS 1500) + set(${result} 8 PARENT_SCOPE) + elseif(NOT MSVC_VERSION VERSION_LESS 1500 AND MSVC_VERSION VERSION_LESS 1600) + set(${result} 9 PARENT_SCOPE) + elseif(NOT MSVC_VERSION VERSION_LESS 1600 AND MSVC_VERSION VERSION_LESS 1700) + set(${result} 10 PARENT_SCOPE) + elseif(NOT MSVC_VERSION VERSION_LESS 1700 AND MSVC_VERSION VERSION_LESS 1800) + set(${result} 11 PARENT_SCOPE) + elseif(NOT MSVC_VERSION VERSION_LESS 1800 AND MSVC_VERSION VERSION_LESS 1900) + set(${result} 12 PARENT_SCOPE) + elseif(NOT MSVC_VERSION VERSION_LESS 1900 AND MSVC_VERSION VERSION_LESS 1910) + set(${result} 14 PARENT_SCOPE) + elseif(NOT MSVC_VERSION VERSION_LESS 1910 AND MSVC_VERSION VERSION_LESS 1920) + set(${result} 15 PARENT_SCOPE) else() - if(CMAKE_VS_PLATFORM_TOOLSET) - string(REGEX MATCHALL "[0-9]+" output "${CMAKE_VS_PLATFORM_TOOLSET}") - list(GET output 0 _toolset_version) - if(_toolset_version LESS 142) - if ("${_toolset_version}" EQUAL "141") - set(_msvc_version "15") - else() - string(SUBSTRING ${_toolset_version} 0 2 _msvc_version) - endif() - set(${result} ${_msvc_version} PARENT_SCOPE) - return() - else() - message(STATUS "Conan **WARNING** : Unknown MSVC toolset ${_toolset_version}") - endif() - endif() - - string(REGEX MATCHALL "[0-9]+" output "${CMAKE_GENERATOR}") - list(GET output 0 _msvc_version) - set(${result} ${_msvc_version} PARENT_SCOPE) + message(FATAL_ERROR "Conan: Unknown MSVC compiler version [${MSVC_VERSION}]") endif() endfunction() @@ -53,9 +40,6 @@ function(conan_cmake_settings result) set(_SETTINGS -g cmake) endif() if(CMAKE_BUILD_TYPE) - if(CMAKE_BUILD_TYPE STREQUAL "MinSizeRel" OR CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo") - set(CMAKE_BUILD_TYPE "Release") - endif() set(_SETTINGS ${_SETTINGS} -s build_type=${CMAKE_BUILD_TYPE}) else() message(FATAL_ERROR "Please specify in command line CMAKE_BUILD_TYPE (-DCMAKE_BUILD_TYPE=Release)") @@ -63,7 +47,7 @@ function(conan_cmake_settings result) #handle -s os setting if(CMAKE_SYSTEM_NAME) - #use default conan os setting if CMAKE_SYSTEM_NAME is not defined + #use default conan os setting if CMAKE_SYSTEM_NAME is not defined set(CONAN_SYSTEM_NAME ${CMAKE_SYSTEM_NAME}) if(${CMAKE_SYSTEM_NAME} STREQUAL "Darwin") set(CONAN_SYSTEM_NAME Macos) @@ -78,62 +62,78 @@ function(conan_cmake_settings result) endif() endif() - if (${CMAKE_CXX_COMPILER_ID} STREQUAL GNU) + get_property(_languages GLOBAL PROPERTY ENABLED_LANGUAGES) + if (";${_languages};" MATCHES ";CXX;") + set(LANGUAGE CXX) + set(USING_CXX 1) + elseif (";${_languages};" MATCHES ";C;") + set(LANGUAGE C) + set(USING_CXX 0) + else () + message(FATAL_ERROR "Conan: Neither C or C++ was detected as a language for the project. Unabled to detect compiler version.") + endif() + + if (${CMAKE_${LANGUAGE}_COMPILER_ID} STREQUAL GNU) # using GCC # TODO: Handle other params - string(REPLACE "." ";" VERSION_LIST ${CMAKE_CXX_COMPILER_VERSION}) + string(REPLACE "." ";" VERSION_LIST ${CMAKE_${LANGUAGE}_COMPILER_VERSION}) list(GET VERSION_LIST 0 MAJOR) list(GET VERSION_LIST 1 MINOR) - conan_cmake_detect_gnu_libcxx(_LIBCXX) - set(_SETTINGS ${_SETTINGS} -s compiler=gcc -s compiler.version=${MAJOR}.${MINOR} -s compiler.libcxx=${_LIBCXX}) - elseif (${CMAKE_CXX_COMPILER_ID} STREQUAL AppleClang) + set(COMPILER_VERSION ${MAJOR}.${MINOR}) + set(_SETTINGS ${_SETTINGS} -s compiler=gcc -s compiler.version=${COMPILER_VERSION}) + if (USING_CXX) + conan_cmake_detect_gnu_libcxx(_LIBCXX) + set(_SETTINGS ${_SETTINGS} -s compiler.libcxx=${_LIBCXX}) + endif () + elseif (${CMAKE_${LANGUAGE}_COMPILER_ID} STREQUAL AppleClang) # using AppleClang - string(REPLACE "." ";" VERSION_LIST ${CMAKE_CXX_COMPILER_VERSION}) + string(REPLACE "." ";" VERSION_LIST ${CMAKE_${LANGUAGE}_COMPILER_VERSION}) list(GET VERSION_LIST 0 MAJOR) list(GET VERSION_LIST 1 MINOR) - set(_SETTINGS ${_SETTINGS} -s compiler=apple-clang -s compiler.version=${MAJOR}.${MINOR} -s compiler.libcxx=libc++) - elseif (${CMAKE_CXX_COMPILER_ID} STREQUAL Clang) - string(REPLACE "." ";" VERSION_LIST ${CMAKE_CXX_COMPILER_VERSION}) + set(_SETTINGS ${_SETTINGS} -s compiler=apple-clang -s compiler.version=${MAJOR}.${MINOR}) + if (USING_CXX) + set(_SETTINGS ${_SETTINGS} -s compiler.libcxx=libc++) + endif () + elseif (${CMAKE_${LANGUAGE}_COMPILER_ID} STREQUAL Clang) + string(REPLACE "." ";" VERSION_LIST ${CMAKE_${LANGUAGE}_COMPILER_VERSION}) list(GET VERSION_LIST 0 MAJOR) - list(GET VERSION_LIST 1 MINOR) + list(GET VERSION_LIST 1 MINOR) if(APPLE) cmake_policy(GET CMP0025 APPLE_CLANG_POLICY_ENABLED) if(NOT APPLE_CLANG_POLICY_ENABLED) message(STATUS "Conan: APPLE and Clang detected. Assuming apple-clang compiler. Set CMP0025 to avoid it") - set(_SETTINGS ${_SETTINGS} -s compiler=apple-clang -s compiler.version=${MAJOR}.${MINOR} -s compiler.libcxx=libc++) + set(_SETTINGS ${_SETTINGS} -s compiler=apple-clang -s compiler.version=${MAJOR}.${MINOR}) else() - set(_SETTINGS ${_SETTINGS} -s compiler=clang -s compiler.version=${MAJOR}.${MINOR} -s compiler.libcxx=libstdc++) + set(_SETTINGS ${_SETTINGS} -s compiler=clang -s compiler.version=${MAJOR}.${MINOR}) endif() + if (USING_CXX) + set(_SETTINGS ${_SETTINGS} -s compiler.libcxx=libc++) + endif () else() - set(_SETTINGS ${_SETTINGS} -s compiler=clang -s compiler.version=${MAJOR}.${MINOR} -s compiler.libcxx=libstdc++) + set(_SETTINGS ${_SETTINGS} -s compiler=clang -s compiler.version=${MAJOR}.${MINOR}) + if (USING_CXX) + conan_cmake_detect_gnu_libcxx(_LIBCXX) + set(_SETTINGS ${_SETTINGS} -s compiler.libcxx=${_LIBCXX}) + endif () endif() - elseif(${CMAKE_CXX_COMPILER_ID} STREQUAL MSVC) + elseif(${CMAKE_${LANGUAGE}_COMPILER_ID} STREQUAL MSVC) set(_VISUAL "Visual Studio") _get_msvc_ide_version(_VISUAL_VERSION) if("${_VISUAL_VERSION}" STREQUAL "") - message(FATAL_ERROR "Visual Studio not recognized") + message(FATAL_ERROR "Conan: Visual Studio not recognized") else() set(_SETTINGS ${_SETTINGS} -s compiler=${_VISUAL} -s compiler.version=${_VISUAL_VERSION}) endif() - if(${CMAKE_GENERATOR} STREQUAL "Ninja") - if($ENV{Platform} STREQUAL "X64") - set(_SETTINGS ${_SETTINGS} -s arch=x86_64) - elseif($ENV{Platform} STREQUAL "ARM") - message(STATUS "Conan: Using default ARM architecture from MSVC") - set(_SETTINGS ${_SETTINGS} -s arch=armv6) - else() - set(_SETTINGS ${_SETTINGS} -s arch=x86) - endif() - else() - if(${CMAKE_GENERATOR} MATCHES "Win64") - set(_SETTINGS ${_SETTINGS} -s arch=x86_64) - elseif (${CMAKE_GENERATOR} MATCHES "ARM") - message(STATUS "Conan: Using default ARM architecture from MSVC") - set(_SETTINGS ${_SETTINGS} -s arch=armv6) - else() - set(_SETTINGS ${_SETTINGS} -s arch=x86) - endif() + if (MSVC_${LANGUAGE}_ARCHITECTURE_ID MATCHES "64") + set(_SETTINGS ${_SETTINGS} -s arch=x86_64) + elseif (MSVC_${LANGUAGE}_ARCHITECTURE_ID MATCHES "^ARM") + message(STATUS "Conan: Using default ARM architecture from MSVC") + set(_SETTINGS ${_SETTINGS} -s arch=armv6) + elseif (MSVC_${LANGUAGE}_ARCHITECTURE_ID MATCHES "86") + set(_SETTINGS ${_SETTINGS} -s arch=x86) + else () + message(FATAL_ERROR "Conan: Unknown MSVC architecture [${MSVC_${LANGUAGE}_ARCHITECTURE_ID}]") endif() conan_cmake_detect_vs_runtime(_vs_runtime) @@ -199,8 +199,8 @@ endfunction() macro(parse_arguments) - set(options BASIC_SETUP CMAKE_TARGETS UPDATE) - set(oneValueArgs CONANFILE) + set(options BASIC_SETUP CMAKE_TARGETS UPDATE KEEP_RPATHS) + set(oneValueArgs CONANFILE DEBUG_PROFILE RELEASE_PROFILE PROFILE) set(multiValueArgs REQUIRES OPTIONS IMPORTS BUILD CONAN_COMMAND) cmake_parse_arguments(ARGUMENTS "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN} ) endmacro() @@ -227,13 +227,29 @@ function(conan_cmake_install) else() set(conan_command conan) endif() + set(CONAN_OPTIONS "") if(ARGUMENTS_CONANFILE) - set(CONANFILE -f=${CMAKE_CURRENT_SOURCE_DIR}/${ARGUMENTS_CONANFILE}) + set(CONANFILE ${CMAKE_CURRENT_SOURCE_DIR}/${ARGUMENTS_CONANFILE}) + # A conan file has been specified - apply specified options as well if provided + foreach(ARG ${ARGUMENTS_OPTIONS}) + set(CONAN_OPTIONS ${CONAN_OPTIONS} -o ${ARG}) + endforeach() + else() + set(CONANFILE ".") + endif() + if(CMAKE_BUILD_TYPE STREQUAL "Debug" AND ARGUMENTS_DEBUG_PROFILE) + set(settings -pr ${ARGUMENTS_DEBUG_PROFILE}) + endif() + if(CMAKE_BUILD_TYPE STREQUAL "Release" AND ARGUMENTS_RELEASE_PROFILE) + set(settings -pr ${ARGUMENTS_RELEASE_PROFILE}) + endif() + if(ARGUMENTS_PROFILE) + set(settings -pr ${ARGUMENTS_PROFILE}) endif() if(ARGUMENTS_UPDATE) set(CONAN_INSTALL_UPDATE --update) endif() - set(conan_args install ${CONANFILE} ${settings} ${CONAN_BUILD_POLICY} ${CONAN_INSTALL_UPDATE}) + set(conan_args install ${CONANFILE} ${settings} ${CONAN_BUILD_POLICY} ${CONAN_INSTALL_UPDATE} ${CONAN_OPTIONS}) string (REPLACE ";" " " _conan_args "${conan_args}") message(STATUS "Conan executing: ${conan_command} ${_conan_args}") @@ -263,7 +279,7 @@ endfunction() function(conan_cmake_generate_conanfile) # Generate, writing in disk a conanfile.txt with the requires, options, and imports # specified as arguments - # This will be considered as temporary file, generated in CMAKE_CURRENT_BINARY_DIR + # This will be considered as temporary file, generated in CMAKE_CURRENT_BINARY_DIR) parse_arguments(${ARGV}) set(_FN "${CMAKE_CURRENT_BINARY_DIR}/conanfile.txt") @@ -328,9 +344,17 @@ macro(conan_cmake_run) if(ARGUMENTS_BASIC_SETUP) if(ARGUMENTS_CMAKE_TARGETS) - conan_basic_setup(TARGETS) + if(ARGUMENTS_KEEP_RPATHS) + conan_basic_setup(TARGETS KEEP_RPATHS) + else() + conan_basic_setup(TARGETS) + endif() else() - conan_basic_setup() + if(ARGUMENTS_KEEP_RPATHS) + conan_basic_setup(KEEP_RPATHS) + else() + conan_basic_setup() + endif() endif() endif() endmacro() diff --git a/cmake/cppcheck.cmake b/cmake/cppcheck.cmake index 523502ddf8860098ff3f361b0db90503390144ce..0f0416429527034f4cb413afef17df299c27f293 100644 --- a/cmake/cppcheck.cmake +++ b/cmake/cppcheck.cmake @@ -30,12 +30,13 @@ if(NOT CPPCHECK_COMMAND) " ERROR: Could not find cppcheck. Having cppcheck is a mandatory requirement. CMake will not generate the project without it. - Add its location to the environments variables PATH or CPPCHECK_DIR.") + Add its location to the environments variables PATH or CPPCHECK_DIR. + However, this should normally be supplied by conan!") else() message(STATUS "Use cppcheck from: ${CPPCHECK_COMMAND}") endif() -set(CPPCHECK_ARGUMENTS --enable=warning,performance,portability,missingInclude --error-exitcode=1 --quiet --verbose) +set(CPPCHECK_ARGUMENTS --enable=warning,performance,portability,missingInclude,unusedFunction,style --error-exitcode=1 --quiet --verbose) if(MSVC) list(APPEND CPPCHECK_ARGUMENTS --template=vs) elseif(CLANG) diff --git a/cmake/cpplint.cmake b/cmake/cpplint.cmake index 18d881e45ba1ac2152c31b7a2b8579fe323ab712..9342399d3f15c119b3fd1fddeb4fe741fa8dc999 100644 --- a/cmake/cpplint.cmake +++ b/cmake/cpplint.cmake @@ -65,7 +65,8 @@ function(ADD_TEST_CPPLINT) set(multiValueArgs ) cmake_parse_arguments(ADD_TEST_CPPLINT "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN} ) - + + set(CPPLINT_ARGS "--quiet") if(MSVC) set(CPPLINT_OUTPUT "--output=vs7") else() @@ -73,7 +74,7 @@ function(ADD_TEST_CPPLINT) endif() add_test(NAME "${ADD_TEST_CPPLINT_NAME}" - COMMAND ${PYTHON_EXECUTABLE} ${CPPLINT_COMMAND} ${CPPLINT_OUTPUT} + COMMAND ${PYTHON_EXECUTABLE} ${CPPLINT_COMMAND} ${CPPLINT_OUTPUT} ${CPPLINT_ARGS} ${ADD_TEST_CPPLINT_UNPARSED_ARGUMENTS} ) set_tests_properties(${ADD_TEST_CPPLINT_NAME} PROPERTIES TIMEOUT 20.0) diff --git a/cmake/suppress_warnings.hpp.in b/cmake/suppress_warnings.hpp.in index 70613698f3c81d308f25335ff2752cb2b42433af..89e84c7db1004f1bdebdd3f3099b0182e6dd8a58 100644 --- a/cmake/suppress_warnings.hpp.in +++ b/cmake/suppress_warnings.hpp.in @@ -44,9 +44,6 @@ #define SUPPRESS_WARNINGS_BEGIN_PADDED \ _Pragma("clang diagnostic push") \ _Pragma("clang diagnostic ignored \"-Wpadded\"") -#define SUPPRESS_WARNINGS_BEGIN_PADDED \ - _Pragma("clang diagnostic push") \ - _Pragma("clang diagnostic ignored \"-Wpadded\"") #define SUPPRESS_WARNINGS_END _Pragma("clang diagnostic pop") #elif defined _MSC_VER @@ -61,14 +58,14 @@ #else #define SUPPRESS_WARNINGS_GCC7_AND_ABOVE #endif -#define SUPPRESS_WARNINGS_BEGIN \ - _Pragma("GCC diagnostic push") \ - SUPPRESS_WARNINGS_GCC7_AND_ABOVE \ - _Pragma("GCC diagnostic ignored \"-Wall\"") \ - _Pragma("GCC diagnostic ignored \"-Wextra\"") \ +#define SUPPRESS_WARNINGS_BEGIN \ + _Pragma("GCC diagnostic push") \ + SUPPRESS_WARNINGS_GCC7_AND_ABOVE \ + _Pragma("GCC diagnostic ignored \"-Wall\"") \ + _Pragma("GCC diagnostic ignored \"-Wextra\"") \ _Pragma("GCC diagnostic ignored \"-Wpadded\"") -#define SUPPRESS_WARNINGS_BEGIN_PADDED \ - _Pragma("GCC diagnostic push") \ +#define SUPPRESS_WARNINGS_BEGIN_PADDED \ + _Pragma("GCC diagnostic push") \ _Pragma("GCC diagnostic ignored \"-Wpadded\"") #define SUPPRESS_WARNINGS_END _Pragma("GCC diagnostic pop") diff --git a/conanfile.py b/conanfile.py index 8b074ea48bfe90284c9dd7a660005b0bd7e82d28..41cacdd49a281bd7bdcfdcb1c544221f16fb7ea6 100644 --- a/conanfile.py +++ b/conanfile.py @@ -24,32 +24,39 @@ from conans import ConanFile, CMake class ProjectPhoenix(ConanFile): name = "phx" - version = "18.02.0" + version = "18.03.0" license = "3-Clause BSD License" description = """Project Phoenix""" settings = "os", "compiler", "build_type", "arch" - requires = (("assimp/9756b48@RWTH-VR/thirdparty"), - ("boost/1.64.0@RWTH-VR/thirdparty"), - ("catch/1.9.7@RWTH-VR/thirdparty"), + requires = (("assimp/4.1.0@RWTH-VR/thirdparty"), + ("boost_optional/1.66.0@bincrafters/testing"), + ("boost_signals2/1.66.0@bincrafters/testing"), #still not working in stable, change whenever available (also boost_optional) + ("catch/1.12.0@RWTH-VR/thirdparty"), ("cppcheck/1.82@RWTH-VR/thirdparty"), - ("cpplint/9883c51@RWTH-VR/thirdparty"), - ("freeimage/3.17.0@RWTH-VR/thirdparty"), - ("gl/1.0.0@RWTH-VR/thirdparty"), - ("glew/2.1.0_1@RWTH-VR/thirdparty"), - ("glm/0.9.8@RWTH-VR/thirdparty"), - ("jsonformoderncpp/3.0.1@vthiery/stable"), - ("openvr/1.0.10@RWTH-VR/thirdparty"), - ("SDL2/2.0.5@RWTH-VR/thirdparty"), - ("spdlog/0.14.0@RWTH-VR/thirdparty"), - ("trompeloeil/v25@RWTH-VR/thirdparty")) + ("cpplint/e8ffd7c@RWTH-VR/thirdparty"), + ("freeimage/3.17.0_2@RWTH-VR/thirdparty"), + ("gl/1.1.1@RWTH-VR/thirdparty"), + ("glm/0.9.8.5@g-truc/stable"), + ("jsonformoderncpp/3.0.1@vthiery/stable"), + ("openvr/1.0.12@RWTH-VR/thirdparty"), + ("sdl2/2.0.7@bincrafters/stable"), + ("spdlog/0.16.3@bincrafters/stable"), + ("trompeloeil/v29@rollbear/stable")) generators = "cmake" def configure(self): self.options["boost"].header_only = True + self.options["boost_python"].python_version = 2.7 self.options["freeimage"].shared = True - self.options["glew"].shared = True self.options["gl"].shared = False + if self.settings.os == "Linux": + self.options["sdl2"].alsa = False + self.options["sdl2"].jack = False + self.options["sdl2"].pulse = False + self.options["sdl2"].esd = False + self.options["sdl2"].nas = False + self.options["sdl2"].arts = False def imports(self): self.copy("*.dll", dst="lib", src="bin") diff --git a/demos/viewer/CMakeLists.txt b/demos/viewer/CMakeLists.txt index cea35965784e4da544e2913c81a668c383b133bb..4543989d62e0e52f086c2d5f68ca812b0bb5a4ce 100644 --- a/demos/viewer/CMakeLists.txt +++ b/demos/viewer/CMakeLists.txt @@ -26,7 +26,9 @@ file(GLOB VIEWER_HEADERS src/*.hpp) add_executable(viewer ${VIEWER_SOURCES} ${VIEWER_HEADERS} + resource_file.rc ) + target_include_directories(viewer PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/src phoenix @@ -42,5 +44,4 @@ add_test_cpplint(NAME "viewer--cpplint" add_test_cppcheck(NAME "viewer--cppcheck" ${VIEWER_SOURCES} - ${VIEWER_HEADERS} ) diff --git a/demos/viewer/debug.ico b/demos/viewer/debug.ico new file mode 100644 index 0000000000000000000000000000000000000000..d50bba3f00e11284dacdb4fc5204d44719d06f17 Binary files /dev/null and b/demos/viewer/debug.ico differ diff --git a/demos/viewer/phoenix.ico b/demos/viewer/phoenix.ico new file mode 100644 index 0000000000000000000000000000000000000000..eb61a4bbc71865920433a7e6a017048146f26ba9 Binary files /dev/null and b/demos/viewer/phoenix.ico differ diff --git a/demos/viewer/resource_file.rc b/demos/viewer/resource_file.rc new file mode 100644 index 0000000000000000000000000000000000000000..9d43170e1f42673464a80b382527e7e1de273191 --- /dev/null +++ b/demos/viewer/resource_file.rc @@ -0,0 +1,7 @@ +// Icon Resource Definition +#define MAIN_ICON 102 +#if defined(_DEBUG) +MAIN_ICON ICON "debug.ico" +#else +MAIN_ICON ICON "phoenix.ico" +#endif \ No newline at end of file diff --git a/demos/viewer/src/navigation_behavior.cpp b/demos/viewer/src/navigation_behavior.cpp index 1dd78c59f213a0a2c67cc4830b821d8d0dee89f7..b93fedc62fcf6ed9e92709af458817ac90a7ce43 100644 --- a/demos/viewer/src/navigation_behavior.cpp +++ b/demos/viewer/src/navigation_behavior.cpp @@ -24,9 +24,13 @@ #include <vector> +#include "phx/suppress_warnings.hpp" + +SUPPRESS_WARNINGS_BEGIN #include "glm/detail/type_vec3.hpp" #include "glm/glm.hpp" #include "glm/gtc/matrix_access.hpp" +SUPPRESS_WARNINGS_END #include "phx/display_system_openvr.hpp" #include "phx/engine.hpp" @@ -35,15 +39,15 @@ #include "phx/scene.hpp" #include "phx/transform.hpp" +NavigationBehavior::NavigationBehavior( + phx::DisplaySystemOpenVR* display_system_openvr) + : display_system_openvr_(display_system_openvr) {} + void NavigationBehavior::OnUpdate() { // If there exists an HMD and a transform. - const auto display_system_hmd = GetEntity() - ->GetScene() - ->GetEngine() - ->GetSystem<phx::DisplaySystemOpenVR>(); phx::HMD* hmd = nullptr; - if (display_system_hmd != nullptr) { - hmd = display_system_hmd->GetHMD(); + if (display_system_openvr_ != nullptr) { + hmd = display_system_openvr_->GetHMD(); } const auto transform = GetEntity()->GetFirstComponent<phx::Transform>(); if (hmd == nullptr || transform == nullptr) return; diff --git a/demos/viewer/src/navigation_behavior.hpp b/demos/viewer/src/navigation_behavior.hpp index 0209b0264c9786635732b0df1939ba9b33891a71..0dcd7085ae57ac203d3485d85e71bd52a2f63e51 100644 --- a/demos/viewer/src/navigation_behavior.hpp +++ b/demos/viewer/src/navigation_behavior.hpp @@ -24,10 +24,21 @@ #define DEMOS_VIEWER_SRC_NAVIGATION_BEHAVIOR_HPP_ #include "phx/behavior.hpp" +#include "phx/display_system_openvr.hpp" class NavigationBehavior : public phx::Behavior { public: + explicit NavigationBehavior(phx::DisplaySystemOpenVR* display_system_openvr); + NavigationBehavior(const NavigationBehavior& that) = default; + NavigationBehavior(NavigationBehavior&& temp) = default; + virtual ~NavigationBehavior() = default; + NavigationBehavior& operator=(const NavigationBehavior& that) = default; + NavigationBehavior& operator=(NavigationBehavior&& temp) = default; + void OnUpdate() override; + + protected: + phx::DisplaySystemOpenVR* display_system_openvr_; }; #endif // DEMOS_VIEWER_SRC_NAVIGATION_BEHAVIOR_HPP_ diff --git a/demos/viewer/src/rotation_behavior.cpp b/demos/viewer/src/rotation_behavior.cpp index f9d889e567450afe5d271bee24eccf8d4eb807ff..94d0799921c4dcd236ebb1d1526179e89072b850 100644 --- a/demos/viewer/src/rotation_behavior.cpp +++ b/demos/viewer/src/rotation_behavior.cpp @@ -22,8 +22,12 @@ #include "rotation_behavior.hpp" +#include "phx/suppress_warnings.hpp" + +SUPPRESS_WARNINGS_BEGIN #include "glm/detail/type_vec3.hpp" #include "glm/glm.hpp" +SUPPRESS_WARNINGS_END #include "phx/engine.hpp" #include "phx/entity.hpp" diff --git a/demos/viewer/src/viewer.cpp b/demos/viewer/src/viewer.cpp index bb293a384a638272b18eca2dd3b178a20fd135c8..358ba7fa1a55321e6520258f4e8db36726fa35ee 100644 --- a/demos/viewer/src/viewer.cpp +++ b/demos/viewer/src/viewer.cpp @@ -43,7 +43,6 @@ #include "phx/resource_declaration.hpp" #include "phx/resource_manager.hpp" #include "phx/resource_pointer.hpp" -#include "phx/resource_proxy.hpp" #include "phx/runtime_component.hpp" #include "phx/scene.hpp" #include "phx/scene_loader.hpp" @@ -57,6 +56,10 @@ #include "rotation_behavior.hpp" #include "viewer_system.hpp" +#if defined __clang__ +#pragma clang diagnostic ignored "-Wmissing-prototypes" +#endif + int main(int, char**) { std::unique_ptr<phx::Engine> engine = phx::Setup::CreateDefaultEngine(); auto scene = engine->GetScene(); @@ -112,17 +115,21 @@ int main(int, char**) { virtual_platform_transform->SetLocalTranslation(glm::vec3(0.f, -1.f, -2.f)); - phx::Entity* camera = scene->CreateEntity(); - auto camera_transform = camera->AddComponent<phx::Transform>(); - auto camera_projection = camera->AddComponent<phx::Projection>(); - camera->AddComponent<NavigationBehavior>(); - camera_projection->SetPerspective(glm::radians(68.0f), 4.0f / 3.0f, 0.01f, - 1000.0f); - camera_transform->SetLocalTranslation(glm::vec3(0, 0, 0)); - camera_transform->SetParent(virtual_platform_transform, false); + phx::Entity* camera = + scene->GetEntitiesWithComponents<phx::RenderTarget>()[0]; + if (camera->GetFirstComponent<phx::RuntimeComponent<phx::LEFT_EYE>>() == + nullptr && + camera->GetFirstComponent<phx::RuntimeComponent<phx::RIGHT_EYE>>() == + nullptr) { + auto camera_projection = camera->GetFirstComponent<phx::Projection>(); + camera_projection->SetPerspective(glm::radians(68.0f), 4.0f / 3.0f, 0.01f, + 1000.0f); + } + auto virtual_platform = scene->GetEntitiesWithComponents< phx::RuntimeComponent<phx::USER_PLATFORM>>()[0]; - virtual_platform->AddComponent<NavigationBehavior>(); + virtual_platform->AddComponent<NavigationBehavior>( + engine->GetSystem<phx::DisplaySystemOpenVR>()); engine->Run(); diff --git a/demos/viewer/src/viewer_system.hpp b/demos/viewer/src/viewer_system.hpp index f449c431543a0528a31c3217c491451e42965810..f4298c3ce7ececcced9772eb3eaee9eb6e3251f8 100644 --- a/demos/viewer/src/viewer_system.hpp +++ b/demos/viewer/src/viewer_system.hpp @@ -25,6 +25,8 @@ #include <chrono> +#include "phx/suppress_warnings.hpp" + #include "phx/engine.hpp" #include "phx/frame_timer.hpp" #include "phx/system.hpp" diff --git a/library/CMakeLists.txt b/library/CMakeLists.txt index 9dc9bc1052dd1720d8f247b10c786894e5490faf..74d8d59a664bd41be9bd4e7d40e26a27edcd6c79 100644 --- a/library/CMakeLists.txt +++ b/library/CMakeLists.txt @@ -41,13 +41,14 @@ target_include_directories(phoenix ) target_link_libraries(phoenix + ${OPENGL_LIBRARIES} ${CONAN_OR_CMAKE_assimp} ${CONAN_OR_CMAKE_gl} - ${CONAN_OR_CMAKE_boost} + ${CONAN_OR_CMAKE_boost_optional} + ${CONAN_OR_CMAKE_boost_signals2} ${CONAN_OR_CMAKE_glm} - ${CONAN_OR_CMAKE_SDL2} + ${CONAN_OR_CMAKE_sdl2} ${CONAN_OR_CMAKE_spdlog} - ${OPENGL_LIBRARIES} ${CONAN_OR_CMAKE_freeimage} ${CONAN_OR_CMAKE_openvr} ${CONAN_OR_CMAKE_jsonformoderncpp} @@ -68,7 +69,6 @@ add_test_cpplint(NAME "phoenix--cpplint" add_test_cppcheck(NAME "phoenix--cppcheck" ${PHOENIX_SOURCES} - ${PHOENIX_HEADERS} ) generate_configure_files(phoenix) diff --git a/library/phx/assimp_model_loader.cpp b/library/phx/assimp_model_loader.cpp index 0882122dfde8d46b32060ef1211600f9feed06e1..0c079c9a011db2ca4fc2195961945f5b0c4ba7dd 100644 --- a/library/phx/assimp_model_loader.cpp +++ b/library/phx/assimp_model_loader.cpp @@ -64,76 +64,78 @@ std::unique_ptr<phx::Resource> AssimpModelLoader::Load( const aiScene *scene = importer_.GetScene(); - if (declaration.find("material_index") != declaration.end()) { - std::size_t single_material_index = declaration["material_index"]; - auto path = file_name.substr(0, file_name.find_last_of("/\\")); - return LoadSingleMaterial(scene->mMaterials[single_material_index], path); - } - if (declaration.find("mesh_index") != declaration.end()) { - std::size_t single_mesh_index = declaration["mesh_index"]; - return LoadSingleMesh(scene->mMeshes[single_mesh_index]); + if (declaration.find("mesh_index") == declaration.end() && + declaration.find("material_name") == declaration.end()) { + return LoadModel(scene, file_name); + } else if (declaration.find("material_name") != declaration.end()) { + return LoadSingleMaterial(scene, declaration, file_name); + } else if (declaration.find("mesh_index") != declaration.end()) { + return LoadSingleMesh(scene, declaration); } + return nullptr; +} +std::unique_ptr<phx::Model> AssimpModelLoader::LoadModel( + const aiScene *scene, const std::string &file_name) { auto resource = std::make_unique<phx::Model>(); + LoadModelMaterials(scene, file_name, resource.get()); + + LoadModelMeshes(scene, file_name, resource.get()); + + return resource; +} + +void AssimpModelLoader::LoadModelMaterials(const aiScene *scene, + const std::string &file_name, + phx::Model *resource) { for (unsigned int i = 0; i < scene->mNumMaterials; ++i) { - auto material_proxy = phx::ResourceUtils::LoadResourceFromFile<Material>( - file_name, {{"material_index", i}}, true); - resource->AddMaterial(material_proxy); + auto material = phx::ResourceUtils::LoadResourceFromFile<Material>( + file_name, {{"material_name", GetSceneMaterialNameFromIndex(scene, i)}}, + true); + resource->AddMaterial(material); } +} +void AssimpModelLoader::LoadModelMeshes(const aiScene *scene, + const std::string &file_name, + phx::Model *resource) { for (unsigned int i = 0; i < scene->mNumMeshes; i++) { - auto mesh_proxy = phx::ResourceUtils::LoadResourceFromFile<Mesh>( + auto mesh = phx::ResourceUtils::LoadResourceFromFile<Mesh>( file_name, {{"mesh_index", i}}, true); - resource->AddMesh(mesh_proxy); - if (last_material_index_ != -1) { - resource->SetMaterialForMesh( - mesh_proxy, resource->GetMaterials()[last_material_index_]); + resource->AddMesh(mesh); + + for (auto mesh_material : resource->GetMaterials()) { + if (mesh_material->GetName() == + GetSceneMaterialNameFromIndex(scene, + scene->mMeshes[i]->mMaterialIndex)) { + resource->SetMaterialForMesh(mesh, mesh_material); + break; + } } } - - return resource; -} - -std::unique_ptr<phx::Mesh> AssimpModelLoader::LoadSingleMesh( - const aiMesh *mesh) { - auto resource = std::make_unique<phx::Mesh>(); - - resource->SetVertices(LoadVertices(mesh)); - resource->SetIndices(LoadIndices(mesh)); - resource->SetNormals(LoadNormals(mesh)); - resource->SetTangents(LoadTangents(mesh)); - resource->SetBitangents(LoadBitangents(mesh)); - resource->SetTextureCoords(LoadTextureCoords(mesh)); - - // cache material index to later be able to store the connection in the case - // that we actually load a complete model via Load() - // @TODO(anyone) - // This needs to be refactored when we implement proper loading of a - // complete model file (incl. transform hierarchies and everything) as opposed - // to right now, where each sub-mesh and sub-material is effectively loaded - // separately and just pushed into a Model file for storage - last_material_index_ = mesh->mMaterialIndex; - - return resource; -} +} // namespace phx std::unique_ptr<phx::Material> AssimpModelLoader::LoadSingleMaterial( - const aiMaterial *material, const std::string &filepath) { + const aiScene *scene, const ResourceDeclaration &declaration, + const std::string &file_name) { + auto filepath = file_name.substr(0, file_name.find_last_of("/\\")); auto resource = std::make_unique<phx::Material>(); + aiMaterial *material = scene->mMaterials[GetSceneMaterialIndex( + scene, declaration["material_name"])]; aiColor4D color_diffuse(0.f, 0.f, 0.f, 1.f); - aiGetMaterialColor(material, AI_MATKEY_COLOR_DIFFUSE, &color_diffuse); + material->Get(AI_MATKEY_COLOR_DIFFUSE, color_diffuse); aiColor4D color_specular(0.f, 0.f, 0.f, 1.f); - aiGetMaterialColor(material, AI_MATKEY_COLOR_SPECULAR, &color_specular); + material->Get(AI_MATKEY_COLOR_SPECULAR, color_specular); aiColor4D color_ambient(0.f, 0.f, 0.f, 1.f); - aiGetMaterialColor(material, AI_MATKEY_COLOR_AMBIENT, &color_ambient); + material->Get(AI_MATKEY_COLOR_AMBIENT, color_ambient); aiString name; material->Get(AI_MATKEY_NAME, name); float shininess; - aiGetMaterialFloat(material, AI_MATKEY_SHININESS, &shininess); + material->Get(AI_MATKEY_SHININESS, shininess); resource->SetDiffuseColor( glm::vec3(color_diffuse.r, color_diffuse.g, color_diffuse.b)); @@ -147,21 +149,43 @@ std::unique_ptr<phx::Material> AssimpModelLoader::LoadSingleMaterial( aiString relative_path; if (AI_SUCCESS == material->GetTexture(aiTextureType_AMBIENT, 0, &relative_path)) { - auto image_proxy = ResourceUtils::LoadResourceFromFile<Image>( + auto image = ResourceUtils::LoadResourceFromFile<Image>( filepath + "/" + std::string(relative_path.C_Str()), {}, true); - resource->SetAmbientImage(image_proxy); + resource->SetAmbientImage(image); } if (AI_SUCCESS == material->GetTexture(aiTextureType_DIFFUSE, 0, &relative_path)) { - auto image_proxy = ResourceUtils::LoadResourceFromFile<Image>( + auto image = ResourceUtils::LoadResourceFromFile<Image>( filepath + "/" + std::string(relative_path.C_Str()), {}, true); - resource->SetDiffuseImage(image_proxy); + resource->SetDiffuseImage(image); } if (AI_SUCCESS == material->GetTexture(aiTextureType_SPECULAR, 0, &relative_path)) { - auto image_proxy = ResourceUtils::LoadResourceFromFile<Image>( + auto image = ResourceUtils::LoadResourceFromFile<Image>( filepath + "/" + std::string(relative_path.C_Str()), {}, true); - resource->SetSpecularImage(image_proxy); + resource->SetSpecularImage(image); + } + + return resource; +} + +std::unique_ptr<phx::Mesh> AssimpModelLoader::LoadSingleMesh( + const aiScene *scene, const ResourceDeclaration &declaration) { + auto resource = std::make_unique<phx::Mesh>(); + std::size_t mesh_index = declaration["mesh_index"]; + + aiMesh *mesh = scene->mMeshes[mesh_index]; + resource->SetVertices(LoadVertices(mesh)); + resource->SetIndices(LoadIndices(mesh)); + resource->SetNormals(LoadNormals(mesh)); + resource->SetTangents(LoadTangents(mesh)); + resource->SetBitangents(LoadBitangents(mesh)); + resource->SetTextureCoords(LoadTextureCoords(mesh)); + + auto mesh_name = std::string(mesh->mName.C_Str()); + // If an object is unnamed, assimp names it "defaultobject" + if (mesh_name != "defaultobject") { + resource->SetName(mesh_name); } return resource; @@ -209,8 +233,8 @@ std::vector<glm::vec2> AssimpModelLoader::LoadTextureCoords( const aiMesh *mesh) { std::vector<glm::vec2> result; if (!mesh->HasTextureCoords(0)) { - // since our shaders currently require texture coordinates to exist, we load - // dummy ones + // since our shaders currently require texture coordinates to exist, we + // load dummy ones return std::vector<glm::vec2>(mesh->mNumVertices, glm::vec2()); } for (unsigned int i = 0; i < mesh->mNumVertices; i++) { @@ -227,6 +251,30 @@ std::vector<glm::vec3> AssimpModelLoader::LoadNormals(const aiMesh *mesh) { return LoadVectorData(mesh->mNormals, mesh->mNumVertices); } +unsigned int AssimpModelLoader::GetSceneMaterialIndex( + const aiScene *scene, const std::string &material_name) { + if (material_name.empty() == true) { + info("No material name defined, returning first material in file."); + return 0; + } + for (unsigned int i = 0; i < scene->mNumMaterials; ++i) { + if (GetSceneMaterialNameFromIndex(scene, i) == material_name) { + return i; + } + } + + warn("No Material named {} found, returning material with index 0 instead.", + material_name); + return 0; +} + +std::string AssimpModelLoader::GetSceneMaterialNameFromIndex( + const aiScene *scene, const unsigned int mesh_index) { + aiString mat_name; + scene->mMaterials[mesh_index]->Get(AI_MATKEY_NAME, mat_name); + return std::string(mat_name.C_Str()); +} + bool AssimpModelLoader::LoadFile(const std::string &filename) { info("Load Model: {}", filename); const aiScene *scene = importer_.ReadFile( @@ -239,7 +287,7 @@ bool AssimpModelLoader::LoadFile(const std::string &filename) { } info("Finished Loading Model"); last_loaded_scene_ = filename; - last_material_index_ = -1; + last_material_index_ = kInvalidMaterialIndex; return true; } @@ -257,9 +305,9 @@ bool AssimpModelLoader::AssimpProgressHandler::Update(float percentage) { if (percentage > 1.0f) percentage = 1.0f; const int precision = 50; const int progress = static_cast<int>(percentage * precision); - std::cout << "\r[" << std::string(progress, '=') - << std::string(precision - progress, ' ') << "] (" - << (progress * 100 / precision) << "%) "; + std::cout << "\r[" << std::string(static_cast<std::size_t>(progress), '=') + << std::string(static_cast<std::size_t>(precision - progress), ' ') + << "] (" << (progress * 100 / precision) << "%) "; if (parent_ != nullptr && parent_->on_progress_update_callback_ != nullptr) parent_->on_progress_update_callback_(percentage); diff --git a/library/phx/assimp_model_loader.hpp b/library/phx/assimp_model_loader.hpp index e128fe7477e4ed59cc6420d3b514a9c6b02ff5e9..88426077760a81fcd6087b2ddf7a12be62f44deb 100644 --- a/library/phx/assimp_model_loader.hpp +++ b/library/phx/assimp_model_loader.hpp @@ -32,6 +32,8 @@ #include "assimp/ProgressHandler.hpp" #include "assimp/scene.h" +#include "phx/suppress_warnings.hpp" + SUPPRESS_WARNINGS_BEGIN #include "glm/glm.hpp" SUPPRESS_WARNINGS_END @@ -39,11 +41,14 @@ SUPPRESS_WARNINGS_END #include "phx/export.hpp" #include "phx/material.hpp" #include "phx/mesh.hpp" +#include "phx/model.hpp" #include "phx/resource_declaration.hpp" #include "phx/resource_load_strategy.hpp" +#include "phx/resource_pointer.hpp" namespace phx { +SUPPRESS_WARNINGS_BEGIN_PADDED class PHOENIX_EXPORT AssimpModelLoader final : public ResourceLoadStrategy { public: AssimpModelLoader(); @@ -59,9 +64,19 @@ class PHOENIX_EXPORT AssimpModelLoader final : public ResourceLoadStrategy { void SetProgressUpdateCallback(const std::function<void(float)>& callback); protected: - std::unique_ptr<phx::Mesh> LoadSingleMesh(const aiMesh* mesh); + std::unique_ptr<phx::Model> LoadModel(const aiScene* scene, + const std::string& file_name); + void LoadModelMaterials(const aiScene* scene, const std::string& file_name, + phx::Model* resource); + void LoadModelMeshes(const aiScene* scene, const std::string& file_name, + phx::Model* resource); + std::unique_ptr<phx::Material> LoadSingleMaterial( - const aiMaterial* material, const std::string& filepath); + const aiScene* scene, const ResourceDeclaration& declaration, + const std::string& file_name); + + std::unique_ptr<phx::Mesh> LoadSingleMesh( + const aiScene* scene, const ResourceDeclaration& declaration); std::vector<glm::vec3> LoadVertices(const aiMesh* mesh); std::vector<unsigned int> LoadIndices(const aiMesh* mesh); @@ -74,6 +89,11 @@ class PHOENIX_EXPORT AssimpModelLoader final : public ResourceLoadStrategy { std::vector<glm::vec3> LoadVectorData(FileSourceType* source, const std::size_t num_entries); + unsigned int GetSceneMaterialIndex(const aiScene* scene, + const std::string& material_name); + std::string GetSceneMaterialNameFromIndex(const aiScene*, + const unsigned int mesh_index); + private: class AssimpProgressHandler : public Assimp::ProgressHandler { public: @@ -83,12 +103,15 @@ class PHOENIX_EXPORT AssimpModelLoader final : public ResourceLoadStrategy { bool LoadFile(const std::string& filename); + static const int kInvalidMaterialIndex = -1; + Assimp::Importer importer_; AssimpProgressHandler progress_handler_; std::string last_loaded_scene_; - int last_material_index_ = -1; + int last_material_index_ = kInvalidMaterialIndex; std::function<void(float)> on_progress_update_callback_; }; +SUPPRESS_WARNINGS_END template <typename FileSourceType> std::vector<glm::vec3> phx::AssimpModelLoader::LoadVectorData( diff --git a/library/phx/behavior_system.hpp b/library/phx/behavior_system.hpp index f8dfd0986bfe7d590cce5a06848484985d22bdbb..54819db82d4d95d4dced1ca240d87812936424db 100644 --- a/library/phx/behavior_system.hpp +++ b/library/phx/behavior_system.hpp @@ -23,6 +23,8 @@ #ifndef LIBRARY_PHX_BEHAVIOR_SYSTEM_HPP_ #define LIBRARY_PHX_BEHAVIOR_SYSTEM_HPP_ +#include "phx/suppress_warnings.hpp" + #include "phx/engine.hpp" #include "phx/export.hpp" #include "phx/system.hpp" diff --git a/library/phx/blit_pass.cpp b/library/phx/blit_pass.cpp index edc96534e6e531d9ca7ee2e28380339d5ee45177..92f9deb7fe361960d913f95c23b4c056044e8d8a 100644 --- a/library/phx/blit_pass.cpp +++ b/library/phx/blit_pass.cpp @@ -34,11 +34,27 @@ void BlitPass::Initialize() { } void BlitPass::Execute() { - const glm::uvec2& dims = render_target_->GetDimensions(); - const GLint width = static_cast<int>(dims.x); - const GLint height = static_cast<int>(dims.y); - default_framebuffer_->blit(*render_target_, 0, 0, width, height, 0, 0, width, - height, GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT, + const glm::uvec2& source_dims = render_target_->GetDimensions(); + const GLint source_width = static_cast<int>(source_dims.x); + const GLint source_height = static_cast<int>(source_dims.y); + + GLint target_dims[4] = {0}; + glGetIntegerv(GL_VIEWPORT, target_dims); + const GLint target_width = target_dims[2]; + const GLint target_height = target_dims[3]; + + GLint source_x = 0; + GLint source_y = 0; + if (target_width < source_width) { + source_x = (source_width - target_width) / 2; + } + if (target_height < source_height) { + source_y = (source_height - target_height) / 2; + } + + default_framebuffer_->blit(*render_target_, source_x, source_y, target_width, + target_height, 0, 0, target_width, target_height, + GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT, GL_NEAREST); } } // namespace phx diff --git a/library/phx/clear_pass.cpp b/library/phx/clear_pass.cpp index 6f5c166c60f40a676e390b5f4a3a497d302e87da..6d42887213e4d5bb272feefbb0ff3a17a3455894 100644 --- a/library/phx/clear_pass.cpp +++ b/library/phx/clear_pass.cpp @@ -22,7 +22,11 @@ #include "gl/framebuffer.hpp" +#include "phx/suppress_warnings.hpp" + +SUPPRESS_WARNINGS_BEGIN #include "glm/gtc/type_ptr.hpp" +SUPPRESS_WARNINGS_END #include "clear_pass.hpp" diff --git a/library/phx/clear_pass.hpp b/library/phx/clear_pass.hpp index af2bd0d3af6ea666cb3f173d425d1334fad3e47e..4df4c70bb388be168607f25bda00fe65376c43d3 100644 --- a/library/phx/clear_pass.hpp +++ b/library/phx/clear_pass.hpp @@ -23,6 +23,8 @@ #ifndef LIBRARY_PHX_CLEAR_PASS_HPP_ #define LIBRARY_PHX_CLEAR_PASS_HPP_ +#include "phx/suppress_warnings.hpp" + SUPPRESS_WARNINGS_BEGIN #include "glm/glm.hpp" #include "glm/vec4.hpp" diff --git a/library/phx/display_system.hpp b/library/phx/display_system.hpp index 98b84f3ceb0a433000582e059730885a7e00bb47..08e2d36364fc6747c9cb8d2605b45e990ebeaa9d 100644 --- a/library/phx/display_system.hpp +++ b/library/phx/display_system.hpp @@ -44,8 +44,6 @@ class PHOENIX_EXPORT DisplaySystem : public System { void Update(const FrameTimer::TimeInfo&) override = 0; - virtual std::vector<std::unique_ptr<RenderTarget>> CreateRenderTargets() = 0; - protected: explicit DisplaySystem(Engine* engine); friend DisplaySystem* Engine::CreateSystem<DisplaySystem>(); diff --git a/library/phx/display_system_openvr.cpp b/library/phx/display_system_openvr.cpp index 909eeb69c0334a2bfac89ab77c0e68c70baaf526..7938a3fce7112a3c5791d209b315c3d5fc4b616e 100644 --- a/library/phx/display_system_openvr.cpp +++ b/library/phx/display_system_openvr.cpp @@ -29,14 +29,25 @@ #include <utility> #include <vector> +#include "engine.hpp" #include "logger.hpp" #include "rendering_system.hpp" +#include "runtime_component.hpp" +#include "scene.hpp" #undef CreateWindow namespace phx { DisplaySystemOpenVR::DisplaySystemOpenVR(Engine* engine) - : DisplaySystem(engine) {} + : DisplaySystem(engine), + left_render_target_(nullptr), + right_render_target_(nullptr) { + scene_changed_connection_ = engine->AddSceneChangedCallback( + [this](std::shared_ptr<Scene>, std::shared_ptr<Scene> new_scene) { + RemoveRenderTargets(); + CreateRenderTargets(new_scene.get()); + }); +} DisplaySystemOpenVR::~DisplaySystemOpenVR() {} phx::HMD* DisplaySystemOpenVR::CreateHMD() { @@ -56,32 +67,59 @@ phx::HMD* DisplaySystemOpenVR::GetHMD() { return hmd_.get(); } void DisplaySystemOpenVR::Update(const FrameTimer::TimeInfo&) { if (hmd_ != nullptr) { - auto rendering_system = engine_->GetSystem<RenderingSystem>(); - if (rendering_system != nullptr) { - auto render_targets = rendering_system->GetRenderTargets(); - if (render_targets.size() >= 2) { - auto right_texture = render_targets[0]->GetColorTexture(); - hmd_->Submit(HMD::RIGHT_EYE, right_texture); - auto left_texture = render_targets[1]->GetColorTexture(); - hmd_->Submit(HMD::LEFT_EYE, left_texture); - } + if (left_render_target_ != nullptr && right_render_target_ != nullptr) { + auto right_texture = right_render_target_->GetColorTexture(); + hmd_->Submit(HMD::RIGHT_EYE, right_texture); + auto left_texture = left_render_target_->GetColorTexture(); + hmd_->Submit(HMD::LEFT_EYE, left_texture); } } } -std::vector<std::unique_ptr<RenderTarget>> -DisplaySystemOpenVR::CreateRenderTargets() { - std::vector<std::unique_ptr<RenderTarget>> render_targets; +void DisplaySystemOpenVR::CreateRenderTargets(Scene* scene) { if (GetHMD() == nullptr) { error("Cannot create render targets: no HMD."); - return std::move(render_targets); + return; + } + auto left_eye_components = + scene->GetEntitiesWithComponents<RuntimeComponent<LEFT_EYE>>(); + if (!left_eye_components.empty()) { + left_render_target_ = left_eye_components[0]->AddComponent<RenderTarget>( + GetHMD()->GetViewportSize()); + } + auto right_eye_components = + scene->GetEntitiesWithComponents<RuntimeComponent<RIGHT_EYE>>(); + if (!right_eye_components.empty()) { + right_render_target_ = right_eye_components[0]->AddComponent<RenderTarget>( + GetHMD()->GetViewportSize()); } + SetEyeProjections(scene); +} + +void DisplaySystemOpenVR::RemoveRenderTargets() { + if (left_render_target_) + left_render_target_->GetEntity()->RemoveComponent(left_render_target_); + if (right_render_target_) + right_render_target_->GetEntity()->RemoveComponent(right_render_target_); +} - render_targets.push_back( - std::make_unique<RenderTarget>(GetHMD()->GetViewportSize())); - render_targets.push_back( - std::make_unique<RenderTarget>(GetHMD()->GetViewportSize())); - return std::move(render_targets); +void DisplaySystemOpenVR::SetEyeProjections(Scene* scene) { + if (GetHMD() == nullptr) { + error("Cannot set eye projections: no HMD."); + return; + } + auto left_eye_components = + scene->GetEntitiesWithComponents<RuntimeComponent<LEFT_EYE>>(); + if (!left_eye_components.empty()) { + left_eye_components[0]->GetFirstComponent<Projection>()->SetMatrix( + GetHMD()->GetProjectionMatrix(HMD::LEFT_EYE)); + } + auto right_eye_components = + scene->GetEntitiesWithComponents<RuntimeComponent<RIGHT_EYE>>(); + if (!right_eye_components.empty()) { + right_eye_components[0]->GetFirstComponent<Projection>()->SetMatrix( + GetHMD()->GetProjectionMatrix(HMD::RIGHT_EYE)); + } } } // namespace phx diff --git a/library/phx/display_system_openvr.hpp b/library/phx/display_system_openvr.hpp index 8e0962cc327aa78984354bc48b5630f078723cbb..389c6e41dff4208bacd729bc1d63941f0180faaa 100644 --- a/library/phx/display_system_openvr.hpp +++ b/library/phx/display_system_openvr.hpp @@ -29,6 +29,8 @@ #include "phx/display_system.hpp" #include "phx/export.hpp" #include "phx/hmd.hpp" +#include "phx/render_target.hpp" +#include "phx/scene.hpp" #include "phx/window.hpp" namespace phx { @@ -49,10 +51,19 @@ class PHOENIX_EXPORT DisplaySystemOpenVR : public DisplaySystem { void Update(const FrameTimer::TimeInfo&) override; - std::vector<std::unique_ptr<RenderTarget>> CreateRenderTargets() override; + void CreateRenderTargets(Scene* scene); protected: std::unique_ptr<HMD> hmd_; + + private: + void RemoveRenderTargets(); + void SetEyeProjections(Scene* scene); + + boost::signals2::connection scene_changed_connection_; + + RenderTarget* left_render_target_; + RenderTarget* right_render_target_; }; } // namespace phx diff --git a/library/phx/display_system_window.cpp b/library/phx/display_system_window.cpp index 7f87978aa75274c4396227f799d406b573a68773..095f56d72197328a03dbd26bfd21ba74abf3350a 100644 --- a/library/phx/display_system_window.cpp +++ b/library/phx/display_system_window.cpp @@ -48,18 +48,9 @@ DisplaySystemWindow::~DisplaySystemWindow() { SDL_VideoQuit(); } void DisplaySystemWindow::DestroyWindow() { window_.reset(); - /*windows_.erase( - std::remove_if(windows_.begin(), windows_.end(), - [window](const std::unique_ptr<Window>& iteratee) { - return window == iteratee.get(); - }));*/ } Window* DisplaySystemWindow::GetWindow() { - /*std::vector<Window*> windows(windows_.size()); - std::transform( - windows_.begin(), windows_.end(), windows.begin(), - [](const std::unique_ptr<Window>& iteratee) { return iteratee.get(); });*/ return window_.get(); } @@ -69,17 +60,4 @@ void DisplaySystemWindow::Update(const FrameTimer::TimeInfo&) { } } -std::vector<std::unique_ptr<RenderTarget>> -DisplaySystemWindow::CreateRenderTargets() { - std::vector<std::unique_ptr<RenderTarget>> render_targets; - if (GetWindow() == nullptr) { - error("Cannot create render target: no window."); - return std::move(render_targets); - } - - render_targets.push_back( - std::make_unique<RenderTarget>(GetWindow()->GetSize())); - return std::move(render_targets); -} - } // namespace phx diff --git a/library/phx/display_system_window.hpp b/library/phx/display_system_window.hpp index 8abfcee03022c9af1d00355b788690bfbf9ffd55..024c34de643bb5ef6fccc1e82688b435541585f9 100644 --- a/library/phx/display_system_window.hpp +++ b/library/phx/display_system_window.hpp @@ -52,8 +52,6 @@ class PHOENIX_EXPORT DisplaySystemWindow : public DisplaySystem { void Update(const FrameTimer::TimeInfo&) override; - std::vector<std::unique_ptr<RenderTarget>> CreateRenderTargets() override; - protected: std::unique_ptr<Window> window_; }; diff --git a/library/phx/engine.cpp b/library/phx/engine.cpp index cf624f5649bf511076bd400694a41354051da84e..2ca67313b4ae9dc73c008738edb8357478c0fe89 100644 --- a/library/phx/engine.cpp +++ b/library/phx/engine.cpp @@ -86,7 +86,7 @@ std::vector<Entity*> Engine::GetEntities() const { std::shared_ptr<Scene> Engine::GetScene() const { return scene_; } -void Engine::SetScene(const std::shared_ptr<Scene>& new_scene) { +void Engine::SetScene(std::shared_ptr<Scene> new_scene) { // detach from current scene if (scene_ != nullptr) { scene_->engine_ = nullptr; @@ -103,63 +103,16 @@ boost::signals2::connection Engine::AddSceneChangedCallback( return scene_changed_signal_.connect(callback); } -void Engine::UpdateOrder::MoveToFront(System* system) const { - auto it = FindSystem(system); - if (it == engine_->systems_.end()) { - error("Cannot move system to front of update order: system not found"); - return; - } - auto system_temp = std::move(*it); - engine_->systems_.erase(it); - engine_->systems_.insert(engine_->systems_.begin(), std::move(system_temp)); -} - -void Engine::UpdateOrder::MoveToBack(System* system) const { - auto it = FindSystem(system); - if (it == engine_->systems_.end()) { - error("Cannot move system to back of update order: system not found"); - return; - } - auto system_temp = std::move(*it); - engine_->systems_.erase(it); - engine_->systems_.insert(engine_->systems_.end(), std::move(system_temp)); -} +void Engine::MoveSystemToFront(System* system) { systems_.MoveToFront(system); } -void Engine::UpdateOrder::MoveAfter(System* system, System* after) const { - MoveBeforeRelative(system, after, 1); -} - -void Engine::UpdateOrder::MoveBefore(System* system, System* before) const { - MoveBeforeRelative(system, before, 0); -} +void Engine::MoveSystemToBack(System* system) { systems_.MoveToBack(system); } -std::vector<std::unique_ptr<phx::System>>::iterator -Engine::UpdateOrder::FindSystem(System* system) const { - auto find_func = [system](const std::unique_ptr<System>& sys) { - return sys.get() == system; - }; - return std::find_if(engine_->systems_.begin(), engine_->systems_.end(), - find_func); +void Engine::MoveSystemAfter(System* system, System* after) { + systems_.MoveAfter(system, after); } -void Engine::UpdateOrder::MoveBeforeRelative(System* system, - System* relative_to, - int distance) const { - if (system == relative_to) return; - auto it_sys = FindSystem(system); - if (it_sys == engine_->systems_.end()) { - error("Cannot change update order: system not found"); - return; - } - if (FindSystem(relative_to) == engine_->systems_.end()) { - error("Cannot change update order: target system not found"); - return; - } - auto system_temp = std::move(*it_sys); - engine_->systems_.erase(it_sys); - auto it_target = FindSystem(relative_to); - it_target += distance; - engine_->systems_.insert(it_target, std::move(system_temp)); +void Engine::MoveSystemBefore(System* system, System* before) { + systems_.MoveBefore(system, before); } } // namespace phx diff --git a/library/phx/engine.hpp b/library/phx/engine.hpp index 99898cfeb8760fa6665d5a385b1001e6cd658bea..b7c51154b09a19a35febbd8edbe7bbb1a74bc868 100644 --- a/library/phx/engine.hpp +++ b/library/phx/engine.hpp @@ -32,6 +32,8 @@ #include <utility> #include <vector> +#include "phx/suppress_warnings.hpp" + SUPPRESS_WARNINGS_BEGIN #define BOOST_BIND_NO_PLACEHOLDERS #include "boost/signals2/connection.hpp" @@ -42,6 +44,7 @@ SUPPRESS_WARNINGS_END #include "phx/export.hpp" #include "phx/frame_timer.hpp" #include "phx/loggable.hpp" +#include "phx/orderable_list.hpp" #include "phx/scene.hpp" #include "phx/system.hpp" @@ -65,8 +68,7 @@ class PHOENIX_EXPORT Engine final : public Loggable { "The type does not inherit from System."); auto system = std::unique_ptr<SystemType>(new SystemType(this, arguments...)); - systems_.push_back(std::move(system)); - return static_cast<SystemType*>(systems_.back().get()); + return static_cast<SystemType*>(systems_.PushBack(std::move(system))); } template <typename SystemType> SystemType* GetSystem() { @@ -100,13 +102,18 @@ class PHOENIX_EXPORT Engine final : public Loggable { systems_.end()); } + void MoveSystemToFront(System* system); + void MoveSystemToBack(System* system); + void MoveSystemAfter(System* system, System* after); + void MoveSystemBefore(System* system, System* before); + void Run(); void Stop(); std::string ToString() const override; bool IsRunning() const; - void SetScene(const std::shared_ptr<Scene>& new_scene); + void SetScene(std::shared_ptr<Scene> new_scene); std::shared_ptr<Scene> GetScene() const; // Parameters to the callback are: (old scene, new scene) boost::signals2::connection AddSceneChangedCallback( @@ -124,25 +131,6 @@ class PHOENIX_EXPORT Engine final : public Loggable { template <typename... Components> std::vector<std::tuple<Components*...>> GetFirstComponentsMany() const; - // Update order - class UpdateOrder { - public: - explicit UpdateOrder(Engine* engine) : engine_(engine) {} - void MoveToFront(System* system) const; - void MoveToBack(System* system) const; - void MoveAfter(System* system, System* after) const; - void MoveBefore(System* system, System* before) const; - - private: - std::vector<std::unique_ptr<System>>::iterator FindSystem( - System* system) const; - void MoveBeforeRelative(System* system, System* relative_to, - int distance) const; - Engine* engine_; - }; - - const UpdateOrder& GetUpdateOrder() const { return update_order_; } - private: template <typename SystemType> static bool SystemMatchPredicate(const std::unique_ptr<System>& iteratee) { @@ -151,7 +139,7 @@ class PHOENIX_EXPORT Engine final : public Loggable { void UpdateSystems(); - std::vector<std::unique_ptr<System>> systems_; + OrderableList<System> systems_; bool is_running_ = false; std::shared_ptr<Scene> scene_; @@ -159,7 +147,6 @@ class PHOENIX_EXPORT Engine final : public Loggable { scene_changed_signal_; FrameTimer frame_timer_; - UpdateOrder update_order_ = UpdateOrder(this); }; template <typename... Components> diff --git a/library/phx/entity.hpp b/library/phx/entity.hpp index d902b8da6cb494ecfaa9f8ec218508f0bce5d6ca..7d9b7939bac276a32122c4fa11ca2ac6fb2141fb 100644 --- a/library/phx/entity.hpp +++ b/library/phx/entity.hpp @@ -52,11 +52,11 @@ class PHOENIX_EXPORT Entity : public Nameable, public Loggable { Entity& operator=(const Entity&) = delete; Entity& operator=(Entity&&) = default; - template <class ComponentType> - ComponentType* AddComponent() { + template <class ComponentType, typename... ComponentArguments> + ComponentType* AddComponent(ComponentArguments&&... arguments) { static_assert(std::is_base_of<phx::Component, ComponentType>::value, "ComponentType is not derived from phx::Component."); - auto component_ptr = new ComponentType(); + auto component_ptr = new ComponentType(arguments...); components_.push_back(std::unique_ptr<ComponentType>(component_ptr)); component_ptr->entity_ = this; return component_ptr; diff --git a/library/phx/geometry_pass.cpp b/library/phx/geometry_pass.cpp index 3f464d4bb203e979cdc723b8ea6c2c8ed4ff78b7..81987ac6acb99103684547bb8443762ecab65aa6 100644 --- a/library/phx/geometry_pass.cpp +++ b/library/phx/geometry_pass.cpp @@ -35,10 +35,9 @@ #include "phx/logger.hpp" #include "phx/mesh.hpp" -#include "phx/resource_proxy.hpp" #include "phx/resource_utils.hpp" -#include "phx/transform.hpp" #include "phx/shader_source.hpp" +#include "phx/transform.hpp" namespace phx { @@ -92,16 +91,17 @@ void GeometryPass::UploadMeshData( } rendering_resource_->vertex_buffer.set_sub_data( - offset.vertex_offset * sizeof(glm::vec3), - mesh->GetVertices().size() * sizeof(glm::vec3), + static_cast<GLsizeiptr>(offset.vertex_offset * sizeof(glm::vec3)), + static_cast<GLsizeiptr>(mesh->GetVertices().size() * sizeof(glm::vec3)), mesh->GetVertices().data()); rendering_resource_->normal_buffer.set_sub_data( - offset.vertex_offset * sizeof(glm::vec3), - mesh->GetNormals().size() * sizeof(glm::vec3), + static_cast<GLintptr>(offset.vertex_offset * sizeof(glm::vec3)), + static_cast<GLsizeiptr>(mesh->GetNormals().size() * sizeof(glm::vec3)), mesh->GetNormals().data()); rendering_resource_->tex_coords_buffer.set_sub_data( - offset.vertex_offset * sizeof(glm::vec2), - mesh->GetTextureCoords().size() * sizeof(glm::vec2), + static_cast<GLintptr>(offset.vertex_offset * sizeof(glm::vec2)), + static_cast<GLsizeiptr>(mesh->GetTextureCoords().size() * + sizeof(glm::vec2)), mesh->GetTextureCoords().data()); std::vector<unsigned int> shifted_indices; @@ -114,8 +114,9 @@ void GeometryPass::UploadMeshData( }); rendering_resource_->index_buffer.set_sub_data( - offset.index_offset * sizeof(unsigned int), - shifted_indices.size() * sizeof(unsigned int), shifted_indices.data()); + static_cast<GLintptr>(offset.index_offset * sizeof(unsigned int)), + static_cast<GLsizeiptr>(shifted_indices.size() * sizeof(unsigned int)), + shifted_indices.data()); mesh_cache_[mesh] = offset; @@ -147,8 +148,7 @@ void GeometryPass::SetUpShaders() { shader_program_ = std::make_unique<ShaderProgram>(); shader_program_->SetShader(ShaderProgram::VERTEX, vertex_shader); - shader_program_->SetShader(ShaderProgram::FRAGMENT, - fragment_shader); + shader_program_->SetShader(ShaderProgram::FRAGMENT, fragment_shader); shader_program_->Link(); } @@ -204,7 +204,8 @@ void GeometryPass::BindResources() { rendering_resource_->vertex_array.bind(); shader_program_->use(); render_target_->bind(); - light_buffer_.bind_base<GL_UNIFORM_BUFFER>(0); + render_target_->SetViewport(); + light_buffer_.bind_base(GL_UNIFORM_BUFFER, 0); } void GeometryPass::Draw(const RenderingInstance& rendering_instance) { @@ -235,7 +236,7 @@ void GeometryPass::Draw(const RenderingInstance& rendering_instance) { void GeometryPass::UnbindResources() { render_target_->unbind(); shader_program_->unuse(); - light_buffer_.unbind_base<GL_UNIFORM_BUFFER>(0); + light_buffer_.unbind_base(GL_UNIFORM_BUFFER, 0); glBindVertexArray(0); } diff --git a/library/phx/geometry_pass.hpp b/library/phx/geometry_pass.hpp index 9d969edca251c110d96b2bf52e76dae54954614e..847648d73b38a52192df694081953719a5643e1b 100644 --- a/library/phx/geometry_pass.hpp +++ b/library/phx/geometry_pass.hpp @@ -29,6 +29,8 @@ #include <utility> #include <vector> +#include "phx/suppress_warnings.hpp" + SUPPRESS_WARNINGS_BEGIN #include "gl/buffer.hpp" #include "gl/vertex_array.hpp" diff --git a/library/phx/hmd.cpp b/library/phx/hmd.cpp index 4f8c5d3e7edd18133fe39a504e9924a9548f1e20..16194898bce619c8f79972531de415e69b5d0a53 100644 --- a/library/phx/hmd.cpp +++ b/library/phx/hmd.cpp @@ -30,6 +30,8 @@ #include <utility> #include <vector> +#include "phx/suppress_warnings.hpp" + SUPPRESS_WARNINGS_BEGIN #include "glm/glm.hpp" SUPPRESS_WARNINGS_END @@ -77,7 +79,7 @@ std::vector<vr::TrackedDeviceIndex_t> HMD::GetControllerIndices() { vr::VRSystem()->GetSortedTrackedDeviceIndicesOfClass( vr::TrackedDeviceClass_Controller, indices.data(), static_cast<std::uint32_t>(indices.size())); - return std::move(indices); + return indices; } vr::ETrackedControllerRole HMD::GetControllerRoleForTrackedDeviceIndex( @@ -204,14 +206,14 @@ std::unique_ptr<Material> HMD::GetControllerMaterial(Controller controller) { material->SetAmbientColor(glm::vec3(0.1, 0.1, 0.1)); material->SetSpecularColor(glm::vec3(0.3, 0.3, 0.3)); - auto texture_proxy = ResourceManager::instance().DeclareResource( + auto texture = ResourceManager::instance().DeclareResource<Image>( {{"TYPE", "openVR"}, {"OpenVR_type", "texture"}, {"texture_id", model->diffuseTextureId}, {"side", controller == HMD::Controller::LEFT_CONTROLLER ? "left" : "right"}}); - texture_proxy->Load(); - material->SetDiffuseImage(ResourcePointer<Image>(texture_proxy)); + texture.Load(); + material->SetDiffuseImage(texture); return material; } diff --git a/library/phx/hmd.hpp b/library/phx/hmd.hpp index 82bedf2cfaf9e305a32b7126ec7415fd6635d45b..5ccffcfa0c9bfb0bfd86c28d8054905f1a4a700e 100644 --- a/library/phx/hmd.hpp +++ b/library/phx/hmd.hpp @@ -26,6 +26,8 @@ #include <memory> #include <vector> +#include "phx/suppress_warnings.hpp" + SUPPRESS_WARNINGS_BEGIN #include "glm/mat4x4.hpp" #include "glm/vec2.hpp" diff --git a/library/phx/image.cpp b/library/phx/image.cpp index 29619e6ad34ba2e1a2f0da6c8610bfaea19e85d5..c2af360d9c091595cc00fa883d69f94edffe8096 100644 --- a/library/phx/image.cpp +++ b/library/phx/image.cpp @@ -41,27 +41,23 @@ Image::Image(const std::array<std::size_t, 2>& dimensions, } Image::Image(const std::string& filepath, const std::int32_t native_flags) { Initialize(); - format_ = FreeImage_GetFileType(filepath.c_str(), 0); - if (format_ == FIF_UNKNOWN) - format_ = FreeImage_GetFIFFromFilename(filepath.c_str()); + FREE_IMAGE_FORMAT format = FreeImage_GetFileType(filepath.c_str(), 0); + if (format == FIF_UNKNOWN) + format = FreeImage_GetFIFFromFilename(filepath.c_str()); - native_ = FreeImage_Load(format_, filepath.c_str(), native_flags); + native_ = FreeImage_Load(format, filepath.c_str(), native_flags); if (!native_) throw std::runtime_error("FreeImage_Load failed."); SwapRedBlue(native_); } Image::Image(const Image& that) - : Resource(that), - Loggable(that), - native_(FreeImage_Clone(that.native_)), - format_(that.format_) { + : Resource(that), Loggable(that), native_(FreeImage_Clone(that.native_)) { if (!native_) throw std::runtime_error("FreeImage_Clone failed."); FreeImage_CloneMetadata(native_, that.native_); -} +} // namespace phx Image::Image(Image&& temp) noexcept - : Resource(temp), - Loggable(temp), - native_(std::move(temp.native_)), - format_(std::move(temp.format_)) { + : Resource(std::move(static_cast<Resource&&>(temp))), + Loggable(std::move(static_cast<Loggable&&>(temp))), + native_(temp.native_) { temp.native_ = nullptr; } Image::~Image() { @@ -69,15 +65,13 @@ Image::~Image() { } Image& Image::operator=(const Image& that) { native_ = FreeImage_Clone(that.native_); - format_ = that.format_; if (!native_) throw std::runtime_error("FreeImage_Clone failed."); FreeImage_CloneMetadata(native_, that.native_); return *this; } Image& Image::operator=(Image&& temp) noexcept { if (this != &temp) { - native_ = std::move(temp.native_); - format_ = std::move(temp.format_); + native_ = temp.native_; temp.native_ = nullptr; } return *this; diff --git a/library/phx/image.hpp b/library/phx/image.hpp index b9ccc8bcf7a0cb9f6cec1b2c406a9a6f15f1f941..fa4593e4aea52dcd1a253a33dc133fe8027eb5c5 100644 --- a/library/phx/image.hpp +++ b/library/phx/image.hpp @@ -71,7 +71,7 @@ class PHOENIX_EXPORT Image : public Resource, public Loggable { static_cast<std::int32_t>(dimensions[1]), static_cast<std::int32_t>((bits_per_pixel * dimensions[0] + 31) / 32 * 4), - static_cast<std::int32_t>(bits_per_pixel), FI_RGBA_RED_MASK, + static_cast<std::uint32_t>(bits_per_pixel), FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK, false); if (!native_) { throw std::runtime_error("FreeImage_ConvertFromRawBitsEx failed."); @@ -118,8 +118,8 @@ class PHOENIX_EXPORT Image : public Resource, public Loggable { void Replace(FIBITMAP* native); bool SwapRedBlue(FIBITMAP* dib); + private: FIBITMAP* native_; - FREE_IMAGE_FORMAT format_ = FIF_UNKNOWN; static std::once_flag once_flag_; }; // namespace phx } // namespace phx diff --git a/library/phx/image_loader.cpp b/library/phx/image_loader.cpp index 7f5fe30dcd006665e5f32cf1598ce1095b01a86d..a28713dd9312f2e826bc760b64083ad2990b62f9 100644 --- a/library/phx/image_loader.cpp +++ b/library/phx/image_loader.cpp @@ -65,10 +65,12 @@ std::unique_ptr<Resource> ImageLoader::Load( case 24: image->To24Bits(); break; + case 32: + image->To32Bits(); + break; default: warn("[ImageLoader] bit_format {} not supported, use 32 bits instead", bit_format); - case 32: image->To32Bits(); break; } diff --git a/library/phx/input_system.cpp b/library/phx/input_system.cpp index a8b8ece9fdbc1af2b9a6d6a0927c60dd17d8142b..df27af3ce77b7b1595dc6be0044d375a9635845f 100644 --- a/library/phx/input_system.cpp +++ b/library/phx/input_system.cpp @@ -26,6 +26,8 @@ #include "logger.hpp" #include "rendering_system.hpp" +#include "phx/suppress_warnings.hpp" + SUPPRESS_WARNINGS_BEGIN #include "SDL.h" SUPPRESS_WARNINGS_END diff --git a/library/phx/input_system.hpp b/library/phx/input_system.hpp index 6c2d1875f47623552b9bc21bdcbb386d77096b36..a85319a40eb754266c947f03f332d9b0c3cee693 100644 --- a/library/phx/input_system.hpp +++ b/library/phx/input_system.hpp @@ -26,6 +26,8 @@ #include <functional> #include <string> +#include "phx/suppress_warnings.hpp" + SUPPRESS_WARNINGS_BEGIN #define BOOST_BIND_NO_PLACEHOLDERS #include "boost/signals2/connection.hpp" diff --git a/library/phx/light.hpp b/library/phx/light.hpp index 53e590f1ef6303c9cb3bf79d7c1d3ccbd0adffd6..de0a6522916b8b8326916751fc49d38d8e2a86e4 100644 --- a/library/phx/light.hpp +++ b/library/phx/light.hpp @@ -25,6 +25,8 @@ #include <string> +#include "phx/suppress_warnings.hpp" + SUPPRESS_WARNINGS_BEGIN #include "glm/glm.hpp" SUPPRESS_WARNINGS_END diff --git a/library/phx/material.cpp b/library/phx/material.cpp index 59f16c5abedb7d7e765abf358b97a6c1a8b71545..7809e25d95ec336118961986c3837941178c4c89 100644 --- a/library/phx/material.cpp +++ b/library/phx/material.cpp @@ -22,6 +22,8 @@ #include "material.hpp" +#include <math.h> +#include <algorithm> #include <memory> #include <string> @@ -29,6 +31,8 @@ namespace phx { +const char Material::UNNAMED[] = "UnnamedMaterial"; + glm::vec3 Material::GetDiffuseColor() const { return diffuse_color_; } void Material::SetDiffuseColor(glm::vec3 color) { diffuse_color_ = color; } @@ -89,23 +93,26 @@ void Material::SetShininess(float shininess) { } } -const std::string& Material::GetName() const { return name_; } -void Material::SetName(const std::string& name) { name_ = name; } - void Material::SetTexture(ResourcePointer<Image> image, std::shared_ptr<gl::texture_2d>* texture) { - if (!image.GetProxy()->IsOnline()) return; + if (image == nullptr) return; if (*texture && (*texture)->is_valid()) { gl::texture_handle handle(*texture->get()); handle.set_resident(false); } + auto dimensions = image->GetDimensions(); (*texture) = std::make_shared<gl::texture_2d>(); (*texture)->set_min_filter(GL_LINEAR_MIPMAP_LINEAR); (*texture)->set_mag_filter(GL_LINEAR); (*texture)->set_wrap_s(GL_REPEAT); (*texture)->set_wrap_t(GL_REPEAT); - (*texture)->set_storage(8, GL_RGBA8, static_cast<GLsizei>(dimensions[0]), + int mipmap_levels = 8; + int max_level = static_cast<int>( + std::floor(log2(std::min(dimensions[0], dimensions[1])))); + mipmap_levels = std::min(mipmap_levels, max_level + 1); + (*texture)->set_storage(mipmap_levels, GL_RGBA8, + static_cast<GLsizei>(dimensions[0]), static_cast<GLsizei>(dimensions[1])); (*texture)->set_sub_image(0, 0, 0, static_cast<GLsizei>(dimensions[0]), static_cast<GLsizei>(dimensions[1]), GL_RGBA, @@ -113,6 +120,7 @@ void Material::SetTexture(ResourcePointer<Image> image, (*texture)->generate_mipmap(); gl::texture_handle handle(*texture->get()); handle.set_resident(true); + gl::print_error("[Material::SetTexture] OpenGl Error code"); } } // namespace phx diff --git a/library/phx/material.hpp b/library/phx/material.hpp index 3de50a4d1f860ba3292faef1aa29e6d9178c7ae8..520bbd5adc423fb721d0ca48d6804a1a3661eaa6 100644 --- a/library/phx/material.hpp +++ b/library/phx/material.hpp @@ -27,28 +27,41 @@ #include <string> #include <vector> +#include "phx/suppress_warnings.hpp" + SUPPRESS_WARNINGS_BEGIN #include "gl/texture.hpp" #include "gl/texture_handle.hpp" #include "glm/vec3.hpp" SUPPRESS_WARNINGS_END +#include "nameable.hpp" #include "phx/export.hpp" #include "phx/image.hpp" #include "phx/resource.hpp" #include "phx/resource_pointer.hpp" -#include "phx/resource_proxy.hpp" namespace phx { // TODO(acd): Move render backend specific functionality out. -class PHOENIX_EXPORT Material : public Resource { +class PHOENIX_EXPORT Material : public Resource, public Nameable { public: + static const char UNNAMED[]; + + Material() : Nameable(UNNAMED) {} + Material(const Material&) = default; + Material(Material&&) = default; + + ~Material() override = default; + + Material& operator=(const Material&) = default; + Material& operator=(Material&&) = default; + glm::vec3 GetDiffuseColor() const; void SetDiffuseColor(glm::vec3 color); ResourcePointer<Image> GetDiffuseImage() const; - void SetDiffuseImage(ResourcePointer<Image> proxy); + void SetDiffuseImage(ResourcePointer<Image> image); gl::texture_2d* GetDiffuseTexture(); @@ -56,7 +69,7 @@ class PHOENIX_EXPORT Material : public Resource { void SetAmbientColor(glm::vec3 color); ResourcePointer<Image> GetAmbientImage() const; - void SetAmbientImage(ResourcePointer<Image> proxy); + void SetAmbientImage(ResourcePointer<Image> image); gl::texture_2d* GetAmbientTexture(); @@ -71,24 +84,20 @@ class PHOENIX_EXPORT Material : public Resource { float GetShininess() const; void SetShininess(float shininess); - const std::string& GetName() const; - void SetName(const std::string& name); - private: void SetTexture(ResourcePointer<Image> image, std::shared_ptr<gl::texture_2d>* texture); - glm::vec3 ambient_color_ = glm::vec3(0, 0, 0); - glm::vec3 diffuse_color_ = glm::vec3(1, 0, 0); - glm::vec3 specular_color_ = glm::vec3(1, 1, 1); ResourcePointer<Image> ambient_image_{nullptr}; ResourcePointer<Image> diffuse_image_{nullptr}; ResourcePointer<Image> specular_image_{nullptr}; std::shared_ptr<gl::texture_2d> ambient_texture_ = nullptr; std::shared_ptr<gl::texture_2d> diffuse_texture_ = nullptr; std::shared_ptr<gl::texture_2d> specular_texture_ = nullptr; + glm::vec3 ambient_color_ = glm::vec3(0, 0, 0); + glm::vec3 diffuse_color_ = glm::vec3(1, 0, 0); + glm::vec3 specular_color_ = glm::vec3(1, 1, 1); float shininess_ = 1.0f; - std::string name_ = "UnnamedMaterial"; }; } // namespace phx diff --git a/library/phx/material_handle.hpp b/library/phx/material_handle.hpp index 0a5e866be3725faa7f3ea74678070f5fc0a449cb..e51fb04fc2790a0b2fcb2603a93fbb60ab31f6fe 100644 --- a/library/phx/material_handle.hpp +++ b/library/phx/material_handle.hpp @@ -26,6 +26,8 @@ #include <string> #include <vector> +#include "phx/suppress_warnings.hpp" + SUPPRESS_WARNINGS_BEGIN #include "glm/vec3.hpp" SUPPRESS_WARNINGS_END @@ -35,7 +37,6 @@ SUPPRESS_WARNINGS_END #include "phx/material.hpp" #include "phx/nameable.hpp" #include "phx/resource_pointer.hpp" -#include "phx/resource_proxy.hpp" namespace phx { diff --git a/library/phx/mesh.cpp b/library/phx/mesh.cpp index f5eacf34226273c7fd427d8b45dbacafd5ded3b4..fe06eb2fd87fdea52aad92c644abe4f1e1bf79e6 100644 --- a/library/phx/mesh.cpp +++ b/library/phx/mesh.cpp @@ -31,6 +31,8 @@ namespace phx { +const char Mesh::UNNAMED[] = "UnnamedMesh"; + void Mesh::SetVertices(std::vector<glm::vec3>&& vertices) { vertices_ = std::move(vertices); } diff --git a/library/phx/mesh.hpp b/library/phx/mesh.hpp index 3471314ace53f72623cd03db7d50cd8b38697873..6e1e5685e7a28a16bfb4e0be22d5c1b2f432ca11 100644 --- a/library/phx/mesh.hpp +++ b/library/phx/mesh.hpp @@ -26,18 +26,23 @@ #include <string> #include <vector> +#include "phx/suppress_warnings.hpp" + SUPPRESS_WARNINGS_BEGIN #include "glm/glm.hpp" SUPPRESS_WARNINGS_END #include "phx/export.hpp" +#include "phx/nameable.hpp" #include "phx/resource.hpp" namespace phx { -class PHOENIX_EXPORT Mesh : public Resource { +class PHOENIX_EXPORT Mesh : public Resource, public Nameable { public: - Mesh() = default; + static const char UNNAMED[]; + + Mesh() : Nameable(UNNAMED) {} Mesh(const Mesh &) = default; Mesh(Mesh &&) = default; diff --git a/library/phx/mesh_handle.cpp b/library/phx/mesh_handle.cpp index abaaac234aaaf3497634dc9d8c234737c96ee6b9..e8b2f5f2a875f6aff6f0f669c1f4397c1683609b 100644 --- a/library/phx/mesh_handle.cpp +++ b/library/phx/mesh_handle.cpp @@ -24,7 +24,6 @@ #include <string> #include "phx/mesh.hpp" -#include "phx/resource_proxy.hpp" namespace phx { diff --git a/library/phx/mesh_handle.hpp b/library/phx/mesh_handle.hpp index 4b83c9f87d76a5c59a5f2c93217db90f13611985..729d62289c8e6a0e9b47e4f92722242f281dd56d 100644 --- a/library/phx/mesh_handle.hpp +++ b/library/phx/mesh_handle.hpp @@ -29,7 +29,6 @@ #include "phx/mesh.hpp" #include "phx/nameable.hpp" #include "phx/resource_pointer.hpp" -#include "phx/resource_proxy.hpp" namespace phx { /** diff --git a/library/phx/model.cpp b/library/phx/model.cpp index 164b63f8b447d5e7c570d1dab35f4f0a7f3bb3ff..62e78a3a57d3d05252b139432c206bda5f884e26 100644 --- a/library/phx/model.cpp +++ b/library/phx/model.cpp @@ -22,8 +22,10 @@ #include "model.hpp" +#include <string> #include <vector> +#include "phx/logger.hpp" #include "phx/material.hpp" namespace phx { @@ -56,4 +58,29 @@ void Model::SetMaterialForMesh(ResourcePointer<Mesh> mesh, material_by_mesh_[mesh] = material; } +ResourcePointer<Mesh> Model::GetMesh(std::string mesh_name) { + if (mesh_proxies_.size() == 0) { + warn("Model contains no mesh."); + return ResourcePointer<Mesh>(nullptr); + } + + if (mesh_name.empty() == true) { + if (mesh_proxies_.size() > 1) { + info( + "No mesh_name defined and multiple meshes were found, returning " + "first mesh in model."); + } + return mesh_proxies_[0]; + } + + for (auto resource_pointer : mesh_proxies_) { + if (resource_pointer->GetName() == mesh_name) { + return resource_pointer; + } + } + + warn("Couldn't find mesh_name in model."); + return ResourcePointer<Mesh>(nullptr); +} + } // namespace phx diff --git a/library/phx/model.hpp b/library/phx/model.hpp index 16b569d9be23be17abafeca3e35a6c3e1cb3a57c..f6ce4133b1a0e0bb01a8ce057d2bb6d3119e167b 100644 --- a/library/phx/model.hpp +++ b/library/phx/model.hpp @@ -27,6 +27,8 @@ #include <string> #include <vector> +#include "phx/suppress_warnings.hpp" + SUPPRESS_WARNINGS_BEGIN #include "glm/glm.hpp" SUPPRESS_WARNINGS_END @@ -61,6 +63,8 @@ class PHOENIX_EXPORT Model : public Resource { void SetMaterialForMesh(ResourcePointer<Mesh> mesh, ResourcePointer<Material> material); + ResourcePointer<Mesh> GetMesh(std::string mesh_name = ""); + private: std::vector<ResourcePointer<Mesh>> mesh_proxies_; std::vector<ResourcePointer<Material>> material_proxies_; diff --git a/library/phx/opengl_image_buffer_data.hpp b/library/phx/opengl_image_buffer_data.hpp index ec22c55097df8da5951da12b871f77c7edb5bf86..13ec7a85db6dcbf96d8c04c4f1987247ec5bc166 100644 --- a/library/phx/opengl_image_buffer_data.hpp +++ b/library/phx/opengl_image_buffer_data.hpp @@ -26,11 +26,13 @@ #include <algorithm> #include <cmath> #include <fstream> +#include <locale> #include <memory> #include <string> #include <vector> #include "GL/glew.h" +#include "gl/texture.hpp" #include "phx/export.hpp" #include "phx/image.hpp" @@ -151,6 +153,9 @@ class PHOENIX_EXPORT OpenGLImageBufferData { static std::unique_ptr<OpenGLImageBufferData<T>> CreateFromImage( phx::Image* image); + static std::unique_ptr<OpenGLImageBufferData<T>> CreateFromTexture( + gl::texture_2d* texture); + std::unique_ptr<phx::Image> CreateImage() const; inline std::size_t GetSizeInBytes() const { return buffer_data_.size(); } @@ -288,6 +293,32 @@ phx::OpenGLImageBufferData<T>::CreateFromImage(phx::Image* image) { return buffer; } +template <typename T> +std::unique_ptr<OpenGLImageBufferData<T>> +phx::OpenGLImageBufferData<T>::CreateFromTexture(gl::texture_2d* texture) { + if (texture == nullptr) { + warn("OpenGLImageBufferData<T>::CreateFromTexture called with nullptr"); + return nullptr; + } + if (texture->internal_format() != GL_RGB8) { + warn( + "OpenGLImageBufferData<T>::CreateFromTexture not implemented for " + "anything else than RGB8, tried internal format: {}", + texture->internal_format()); + return nullptr; + } + // copy width, height and data outright + std::size_t width = static_cast<std::size_t>(texture->width()); + std::size_t height = static_cast<std::size_t>(texture->height()); + auto buffer = std::make_unique<OpenGLImageBufferData<T>>(width, height); + // std::vector<GLubyte> tex_data = texture->image(0, GL_RGB, + // GL_UNSIGNED_BYTE); + buffer->buffer_data_ = static_cast<std::vector<unsigned char>>( + texture->image(0, GL_RGB, GL_UNSIGNED_BYTE)); + + return buffer; +} + // different behavior for Float32! template <> std::unique_ptr<OpenGLImageBufferData<OpenGLImageBufferDataType_Float32>> @@ -340,7 +371,7 @@ void phx::OpenGLImageBufferData<T>::SaveToFilePNG( } else { std::string extension = filename.substr(filename.length() - 4); std::transform(extension.begin(), extension.end(), extension.begin(), - ::tolower); + [](char c) { return std::tolower(c, std::locale()); }); if (extension != ".png") { filename_corrected = filename_corrected + ".png"; } diff --git a/library/phx/openvr_controller_behavior.hpp b/library/phx/openvr_controller_behavior.hpp index c8fb9898d17f86bb238273837acb31dcc97df088..a1b0340fb01912a614f75e2fa3e283821f76f2ff 100644 --- a/library/phx/openvr_controller_behavior.hpp +++ b/library/phx/openvr_controller_behavior.hpp @@ -23,11 +23,13 @@ #ifndef LIBRARY_PHX_OPENVR_CONTROLLER_BEHAVIOR_HPP_ #define LIBRARY_PHX_OPENVR_CONTROLLER_BEHAVIOR_HPP_ +#include "phx/suppress_warnings.hpp" + #include "phx/behavior.hpp" #include "phx/export.hpp" namespace phx { - +SUPPRESS_WARNINGS_BEGIN_PADDED class PHOENIX_EXPORT OpenVRControllerBehavior : public Behavior { public: enum Side { LEFT, RIGHT }; @@ -40,6 +42,7 @@ class PHOENIX_EXPORT OpenVRControllerBehavior : public Behavior { private: Side side_ = Side::LEFT; }; +SUPPRESS_WARNINGS_END } // namespace phx #endif // LIBRARY_PHX_OPENVR_CONTROLLER_BEHAVIOR_HPP_ diff --git a/library/phx/openvr_controller_system.cpp b/library/phx/openvr_controller_system.cpp index 737f3be65a0201f4929455f29bf46e43456cccc9..01a18ad27879ff4a817143af9081477a807b8040 100644 --- a/library/phx/openvr_controller_system.cpp +++ b/library/phx/openvr_controller_system.cpp @@ -26,15 +26,15 @@ #include <string> #include <utility> -#include "display_system_openvr.hpp" -#include "logger.hpp" -#include "material_handle.hpp" -#include "mesh_handle.hpp" -#include "openvr_controller_behavior.hpp" -#include "openvr_resource_loader.hpp" -#include "resource_manager.hpp" -#include "resource_pointer.hpp" -#include "transform.hpp" +#include "phx/display_system_openvr.hpp" +#include "phx/logger.hpp" +#include "phx/material_handle.hpp" +#include "phx/mesh_handle.hpp" +#include "phx/openvr_controller_behavior.hpp" +#include "phx/openvr_resource_loader.hpp" +#include "phx/resource_manager.hpp" +#include "phx/resource_pointer.hpp" +#include "phx/transform.hpp" namespace phx { @@ -53,43 +53,51 @@ OpenVRControllerSystem::OpenVRControllerSystem(Engine* engine, resource_manager.RegisterResourceType("openVR", std::move(openvr_loader)); } -Entity* AddControllerEntity(const std::shared_ptr<phx::Scene>& scene, - ResourcePointer<Mesh> mesh, - ResourcePointer<Material> material, - OpenVRControllerBehavior::Side side) { - Entity* controller = scene->CreateEntity(); - controller->AddComponent<MeshHandle>()->SetMesh(mesh); - controller->AddComponent<Transform>(); - controller->AddComponent<MaterialHandle>()->SetMaterial(material); - controller->AddComponent<OpenVRControllerBehavior>()->SetSide(side); +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wmissing-prototypes" +#endif - return controller; -} - -Entity* AddController(const std::shared_ptr<phx::Scene>& scene, - OpenVRControllerBehavior::Side side) { +Entity* OpenVRControllerSystem::AddController( + phx::Scene* scene, OpenVRControllerBehavior::Side side) { auto& resource_manager = ResourceManager::instance(); std::string side_string = side == OpenVRControllerBehavior::LEFT ? "left" : "right"; ResourceDeclaration mesh_declaration{ {"TYPE", "openVR"}, {"OpenVR_type", "mesh"}, {"side", side_string}}; - auto mesh_proxy = - ResourceManager::instance().DeclareResource(mesh_declaration); - mesh_proxy->Load(); + auto mesh = + ResourceManager::instance().DeclareResource<Mesh>(mesh_declaration); + mesh.Load(); ResourceDeclaration material_declaration{ {"TYPE", "openVR"}, {"OpenVR_type", "material"}, {"side", side_string}}; - auto material_proxy = resource_manager.DeclareResource(material_declaration); - material_proxy->Load(); + auto material = + resource_manager.DeclareResource<Material>(material_declaration); + material.Load(); - if (mesh_proxy->GetAs<Mesh>() != nullptr) { - return AddControllerEntity(scene, ResourcePointer<Mesh>(mesh_proxy), - ResourcePointer<Material>(material_proxy), side); + if (mesh != nullptr) { + return AddControllerEntity(scene, mesh, material, side); } return nullptr; } +Entity* OpenVRControllerSystem::AddControllerEntity( + phx::Scene* scene, ResourcePointer<Mesh> mesh, + ResourcePointer<Material> material, OpenVRControllerBehavior::Side side) { + Entity* controller = scene->CreateEntity(); + controller->AddComponent<MeshHandle>()->SetMesh(mesh); + controller->AddComponent<Transform>(); + controller->AddComponent<MaterialHandle>()->SetMaterial(material); + controller->AddComponent<OpenVRControllerBehavior>()->SetSide(side); + + return controller; +} + +#ifdef __clang__ +#pragma clang diagnostic pop +#endif + void OpenVRControllerSystem::Update(const FrameTimer::TimeInfo&) { // check which controllers are active and update their scene representation, // if necessary @@ -122,13 +130,13 @@ void OpenVRControllerSystem::Update(const FrameTimer::TimeInfo&) { if (left_controller_entity == nullptr) { // create that controller left_controller_entity = - AddController(scene, OpenVRControllerBehavior::LEFT); + AddController(scene.get(), OpenVRControllerBehavior::LEFT); } left_controller_active = true; } else if (role == vr::TrackedControllerRole_RightHand) { if (right_controller_entity == nullptr) { right_controller_entity = - AddController(scene, OpenVRControllerBehavior::RIGHT); + AddController(scene.get(), OpenVRControllerBehavior::RIGHT); } right_controller_active = true; } diff --git a/library/phx/openvr_controller_system.hpp b/library/phx/openvr_controller_system.hpp index 21a3f8b91e243cd6643f34ed9921a31980561ed2..17f7cfd53707f4876766e7c8871e0ec3186a0553 100644 --- a/library/phx/openvr_controller_system.hpp +++ b/library/phx/openvr_controller_system.hpp @@ -26,6 +26,8 @@ #include <memory> #include <vector> +#include "phx/suppress_warnings.hpp" + SUPPRESS_WARNINGS_BEGIN #include "glm/glm.hpp" SUPPRESS_WARNINGS_END @@ -34,6 +36,7 @@ SUPPRESS_WARNINGS_END #include "phx/engine.hpp" #include "phx/export.hpp" #include "phx/hmd.hpp" +#include "phx/openvr_controller_behavior.hpp" #include "phx/system.hpp" namespace phx { @@ -55,6 +58,13 @@ class PHOENIX_EXPORT OpenVRControllerSystem : public System { OpenVRControllerSystem(Engine* engine, DisplaySystem* display_system); private: + static Entity* AddControllerEntity(phx::Scene* scene, + ResourcePointer<Mesh> mesh, + ResourcePointer<Material> material, + OpenVRControllerBehavior::Side side); + static Entity* AddController(phx::Scene* scene, + OpenVRControllerBehavior::Side side); + HMD* hmd_ = nullptr; }; diff --git a/library/phx/openvr_resource_loader.hpp b/library/phx/openvr_resource_loader.hpp index 5c68b9e89d3a2f73e3d4a0bb9d94cdf80371c830..d51e796557e2160129c94d761834f23af71edd73 100644 --- a/library/phx/openvr_resource_loader.hpp +++ b/library/phx/openvr_resource_loader.hpp @@ -26,6 +26,8 @@ #include <memory> #include <vector> +#include "phx/suppress_warnings.hpp" + SUPPRESS_WARNINGS_BEGIN #include "glm/glm.hpp" SUPPRESS_WARNINGS_END diff --git a/library/phx/orderable_list.hpp b/library/phx/orderable_list.hpp new file mode 100644 index 0000000000000000000000000000000000000000..a9f50f36c48863528d1a72301b7146a730ccc3f4 --- /dev/null +++ b/library/phx/orderable_list.hpp @@ -0,0 +1,135 @@ +//------------------------------------------------------------------------------ +// Project Phoenix +// +// Copyright (c) 2017-2018 RWTH Aachen University, Germany, +// Virtual Reality & Immersive Visualization Group. +//------------------------------------------------------------------------------ +// License +// +// Licensed under the 3-Clause BSD License (the "License"); +// you may not use this file except in compliance with the License. +// See the file LICENSE for the full text. +// You may obtain a copy of the License at +// +// https://opensource.org/licenses/BSD-3-Clause +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +//------------------------------------------------------------------------------ + +#ifndef LIBRARY_PHX_ORDERABLE_LIST_HPP_ +#define LIBRARY_PHX_ORDERABLE_LIST_HPP_ + +#include <memory> +#include <utility> +#include <vector> + +#include "phx/export.hpp" +#include "phx/logger.hpp" + +namespace phx { + +template <typename ElementType> +class PHOENIX_EXPORT OrderableList { + public: + typedef typename std::vector<std::unique_ptr<ElementType>>::iterator + orderable_list_iterator; + typedef typename std::vector<std::unique_ptr<ElementType>>::const_iterator + orderable_list_const_iterator; + + std::size_t size() const { return data_.size(); } + orderable_list_iterator begin() { return data_.begin(); } + orderable_list_iterator end() { return data_.end(); } + orderable_list_const_iterator begin() const { return data_.begin(); } + orderable_list_const_iterator end() const { return data_.end(); } + orderable_list_iterator erase(orderable_list_const_iterator first, + orderable_list_const_iterator last) { + return data_.erase(first, last); + } + + ElementType* PushBack(std::unique_ptr<ElementType>&& element) { + data_.push_back(std::move(element)); + return data_.back().get(); + } + + void MoveToFront(ElementType* element); + void MoveToBack(ElementType* element); + void MoveAfter(ElementType* element, ElementType* after) { + MoveRelativeTo(element, after, 1); + } + void MoveBefore(ElementType* element, ElementType* before) { + MoveRelativeTo(element, before, 0); + } + + private: + orderable_list_iterator FindElement(ElementType* element); + void MoveRelativeTo(ElementType* element, ElementType* relative_to, + int distance); + + std::vector<std::unique_ptr<ElementType>> data_; +}; + +template <typename ElementType> +void phx::OrderableList<ElementType>::MoveToFront(ElementType* element) { + auto it = FindElement(element); + if (it == data_.end()) { + phx::error( + "Cannot move Element to front of orderable list: element not found"); + return; + } + auto tmp = std::move(*it); + data_.erase(it); + data_.insert(data_.begin(), std::move(tmp)); +} + +template <typename ElementType> +void phx::OrderableList<ElementType>::MoveToBack(ElementType* element) { + auto it = FindElement(element); + if (it == data_.end()) { + phx::error( + "Cannot move element to the back of the orderable list: element not " + "found"); + return; + } + auto tmp = std::move(*it); + data_.erase(it); + data_.insert(data_.end(), std::move(tmp)); +} + +template <typename ElementType> +typename std::vector<std::unique_ptr<ElementType>>::iterator +phx::OrderableList<ElementType>::FindElement(ElementType* element) { + auto find_func = [element](const std::unique_ptr<ElementType>& elem) { + return elem.get() == element; + }; + return std::find_if(data_.begin(), data_.end(), find_func); +} + +template <typename ElementType> +void phx::OrderableList<ElementType>::MoveRelativeTo(ElementType* element, + ElementType* relative_to, + int distance) { + if (element == relative_to) return; + auto it_element = FindElement(element); + if (it_element == data_.end()) { + phx::error("Cannot change ordered list: element not found"); + return; + } + auto it_target = FindElement(relative_to); + if (it_target == data_.end()) { + phx::error("Cannot change ordered list: target element not found"); + return; + } + auto tmp = std::move(*it_element); + data_.erase(it_element); + it_target = FindElement(relative_to); + it_target += distance; + data_.insert(it_target, std::move(tmp)); +} + +} // namespace phx + +#endif // LIBRARY_PHX_ORDERABLE_LIST_HPP_ diff --git a/library/phx/projection.cpp b/library/phx/projection.cpp index 81b915481df519d8dd512505209b7c7b961abf5a..81713abd912bc564b7a0615a738cfcc05e7a052c 100644 --- a/library/phx/projection.cpp +++ b/library/phx/projection.cpp @@ -24,6 +24,8 @@ #include <string> +#include "phx/suppress_warnings.hpp" + SUPPRESS_WARNINGS_BEGIN #include "glm/mat4x4.hpp" SUPPRESS_WARNINGS_END @@ -44,6 +46,8 @@ void Projection::SetOrthogonal(float left, float right, float bottom, float top, matrix_ = glm::ortho(left, right, bottom, top, near, far); } +void Projection::SetMatrix(const glm::mat4& matrix) { matrix_ = matrix; } + std::string Projection::ToString() const { return "ProjectionComponent"; } } // namespace phx diff --git a/library/phx/projection.hpp b/library/phx/projection.hpp index 5f882493183b25de522b786c91ed9e1d564a56a4..17671b52416f0bdda621d5f711670fd7f955a2b9 100644 --- a/library/phx/projection.hpp +++ b/library/phx/projection.hpp @@ -25,6 +25,8 @@ #include <string> +#include "phx/suppress_warnings.hpp" + SUPPRESS_WARNINGS_BEGIN #include "glm/mat4x4.hpp" SUPPRESS_WARNINGS_END @@ -42,6 +44,7 @@ class PHOENIX_EXPORT Projection final : public Component { void SetOrthogonal(float left, float right, float bottom, float top, float near, float far); + void SetMatrix(const glm::mat4& matrix); std::string ToString() const override; diff --git a/library/phx/render_target.cpp b/library/phx/render_target.cpp index f1db70c4d69494583f66fd6887149bf33d71f23c..02008a7d97e3072cb6c1a7a42ebb34edc9393210 100644 --- a/library/phx/render_target.cpp +++ b/library/phx/render_target.cpp @@ -25,8 +25,12 @@ #include <memory> #include "gl/command_execution.hpp" +#include "gl/viewport.hpp" +#include "phx/entity.hpp" #include "phx/logger.hpp" +#include "phx/projection.hpp" +#include "phx/transform.hpp" namespace phx { phx::RenderTarget::RenderTarget(const glm::uvec2 dimensions) @@ -64,18 +68,37 @@ phx::RenderTarget::RenderTarget(const glm::uvec2 dimensions) const glm::uvec2& RenderTarget::GetDimensions() const { return dimensions_; } -const glm::mat4& RenderTarget::GetProjection() const { return projection_; } - -void RenderTarget::SetProjection(const glm::mat4& matrix) { - projection_ = matrix; +gl::texture_2d* RenderTarget::GetColorTexture() const { + return color_texture_.get(); } -const glm::mat4& RenderTarget::GetView() const { return view_; } +const glm::mat4 RenderTarget::GetProjection() const { + auto projection = GetEntity()->GetFirstComponent<Projection>(); + if (projection) { + return projection->GetMatrix(); + } else { + error( + "RenderTarget component may not be added to an Entity without a " + "Projection component!"); + return glm::mat4(); + } +} -void RenderTarget::SetView(const glm::mat4& matrix) { view_ = matrix; } +const glm::mat4 RenderTarget::GetView() const { + auto transform = GetEntity()->GetFirstComponent<Transform>(); + if (transform) { + return inverse(transform->GetGlobalMatrix()); + } else { + error( + "RenderTarget component may not be added to an Entity without a " + "Transform component!"); + return glm::mat4(); + } +} -gl::texture_2d* RenderTarget::GetColorTexture() const { - return color_texture_.get(); +void RenderTarget::SetViewport() const { + gl::set_viewport({{0, 0}}, {{static_cast<GLsizei>(dimensions_[0]), + static_cast<GLsizei>(dimensions_[1])}}); } } // namespace phx diff --git a/library/phx/render_target.hpp b/library/phx/render_target.hpp index b87da3212c45b003218067c09ff3d5199976c41b..f441a947c7a32e831d353f1078bfd6b986bf2d28 100644 --- a/library/phx/render_target.hpp +++ b/library/phx/render_target.hpp @@ -25,6 +25,8 @@ #include <memory> +#include "phx/suppress_warnings.hpp" + SUPPRESS_WARNINGS_BEGIN #include "glm/mat4x4.hpp" #include "glm/vec2.hpp" @@ -36,13 +38,15 @@ SUPPRESS_WARNINGS_END #include "gl/renderbuffer.hpp" #include "gl/texture.hpp" +#include "phx/component.hpp" #include "phx/export.hpp" namespace phx { SUPPRESS_WARNINGS_BEGIN_PADDED -class PHOENIX_EXPORT RenderTarget : public gl::framebuffer { +class PHOENIX_EXPORT RenderTarget : public Component, public gl::framebuffer { public: + RenderTarget() = delete; explicit RenderTarget(const glm::uvec2 dimensions); RenderTarget(RenderTarget&) = delete; RenderTarget(RenderTarget&&) = default; @@ -52,22 +56,18 @@ class PHOENIX_EXPORT RenderTarget : public gl::framebuffer { RenderTarget& operator=(RenderTarget&&) = default; const glm::uvec2& GetDimensions() const; + gl::texture_2d* GetColorTexture() const; - const glm::mat4& GetProjection() const; - void SetProjection(const glm::mat4& matrix); - - const glm::mat4& GetView() const; - void SetView(const glm::mat4& matrix); + const glm::mat4 GetProjection() const; + const glm::mat4 GetView() const; - gl::texture_2d* GetColorTexture() const; + void SetViewport() const; private: std::unique_ptr<gl::texture_2d> color_texture_; std::unique_ptr<gl::texture_2d> depth_texture_; glm::uvec2 dimensions_; - glm::mat4 projection_; - glm::mat4 view_; }; SUPPRESS_WARNINGS_END diff --git a/library/phx/rendering_system.cpp b/library/phx/rendering_system.cpp index 45d55f276d7a08076cb91a6274c69c4fb5819544..b403cbecc009abe26a32c6b1efd303ffcf73489c 100644 --- a/library/phx/rendering_system.cpp +++ b/library/phx/rendering_system.cpp @@ -29,10 +29,6 @@ #include <utility> #include <vector> -#include "blit_pass.hpp" -#include "clear_pass.hpp" -#include "display_system_openvr.hpp" -#include "display_system_window.hpp" #include "engine.hpp" #include "light.hpp" #include "logger.hpp" @@ -73,42 +69,14 @@ void RenderingSystem::SetupFramegraph() { void RenderingSystem::Update(const FrameTimer::TimeInfo&) { std::vector<GeometryPass::RenderingInstance> rendering_instances; std::vector<std::pair<Light*, Transform*>> light_transform_pairs; - std::vector<std::pair<Projection*, Transform*>> projection_transform_pairs; if (GetEngine()->GetScene() == nullptr) { return; } - if (render_targets_.empty()) { - return; - } - - const auto display_system_window = engine_->GetSystem<DisplaySystemWindow>(); - const auto display_system_hmd = engine_->GetSystem<DisplaySystemOpenVR>(); - - // @TODO(anyone): these render parameters should be extracted from the scene - // somehow, the RenderingSystem shouldn't have to know about this. - if (display_system_hmd != nullptr && render_targets_.size() >= 2) { - auto right_eye_entities = - GetEngine()->GetEntitiesWithComponents<RuntimeComponent<RIGHT_EYE>>(); - if (!right_eye_entities.empty()) { - render_targets_[0]->SetView(inverse(right_eye_entities[0] - ->GetFirstComponent<Transform>() - ->GetGlobalMatrix())); - } - - auto left_eye_entities = - GetEngine()->GetEntitiesWithComponents<RuntimeComponent<LEFT_EYE>>(); - if (!left_eye_entities.empty()) { - render_targets_[1]->SetView(inverse(left_eye_entities[0] - ->GetFirstComponent<Transform>() - ->GetGlobalMatrix())); - } - } for (auto& entity : GetEngine()->GetEntities()) { auto mesh_handle = entity->GetFirstComponent<MeshHandle>(); auto light = entity->GetFirstComponent<Light>(); - auto projection = entity->GetFirstComponent<Projection>(); auto transform = entity->GetFirstComponent<Transform>(); auto material_handle = entity->GetFirstComponent<MaterialHandle>(); if (transform != nullptr) { @@ -121,34 +89,15 @@ void RenderingSystem::Update(const FrameTimer::TimeInfo&) { } else if (light != nullptr) { light_transform_pairs.push_back( std::pair<Light*, Transform*>(light, transform)); - } else if (projection != nullptr) { - projection_transform_pairs.push_back( - std::pair<Projection*, Transform*>(projection, transform)); } } } + auto geometry_passes = frame_graph_->GetRenderPasses<GeometryPass>(); for (auto geometry_pass : geometry_passes) { geometry_pass->SetData(rendering_instances, light_transform_pairs); } - // @TODO(anyone) see above, should also not be in the RenderingSystem, but - // the scene (Camera?) should store the connection between render target - // and Camera - if (display_system_hmd != nullptr && render_targets_.size() >= 2) { - HMD* hmd = display_system_hmd->GetHMD(); - render_targets_[0]->SetProjection(hmd->GetProjectionMatrix(HMD::RIGHT_EYE)); - render_targets_[1]->SetProjection(hmd->GetProjectionMatrix(HMD::LEFT_EYE)); - } - - if (display_system_hmd == nullptr && display_system_window != nullptr && - !render_targets_.empty() && !projection_transform_pairs.empty()) { - render_targets_[0]->SetProjection( - projection_transform_pairs[0].first->GetMatrix()); - render_targets_[0]->SetView( - glm::inverse(projection_transform_pairs[0].second->GetGlobalMatrix())); - } - frame_graph_->Execute(); } @@ -165,18 +114,4 @@ std::string RenderingSystem::ToString() const { std::to_string(frame_graph_->GetNumberOfPasses()); } -void RenderingSystem::SetRenderTargets( - std::vector<std::unique_ptr<RenderTarget>>* render_targets) { - render_targets_ = std::move(*render_targets); -} - -std::vector<RenderTarget*> RenderingSystem::GetRenderTargets() const { - std::vector<RenderTarget*> render_targets; - std::transform( - render_targets_.begin(), render_targets_.end(), - std::back_inserter(render_targets), - [](const std::unique_ptr<RenderTarget>& ptr) { return ptr.get(); }); - return render_targets; -} - } // namespace phx diff --git a/library/phx/rendering_system.hpp b/library/phx/rendering_system.hpp index 886f321b624c15f9b0859086ff2e96c7898fea23..40da48362089f540ebadc82d309a3f3e9874041c 100644 --- a/library/phx/rendering_system.hpp +++ b/library/phx/rendering_system.hpp @@ -56,10 +56,6 @@ class PHOENIX_EXPORT RenderingSystem : public System { RenderingSystem& operator=(const RenderingSystem&) = delete; RenderingSystem& operator=(RenderingSystem&&) = default; - void SetRenderTargets( - std::vector<std::unique_ptr<RenderTarget>>* render_targets); - std::vector<RenderTarget*> GetRenderTargets() const; - protected: template <typename SystemType, typename... SystemArguments> friend SystemType* Engine::CreateSystem(SystemArguments&&... arguments); @@ -70,8 +66,6 @@ class PHOENIX_EXPORT RenderingSystem : public System { void SetupFramegraph(); std::unique_ptr<FrameGraph> frame_graph_; - - std::vector<std::unique_ptr<RenderTarget>> render_targets_; }; } // namespace phx diff --git a/library/phx/resource_manager.cpp b/library/phx/resource_manager.cpp index 2d566f968c9e5be02d7bd71eb0f1017d849d83aa..309d82f4cf22f5692029e02b5f75c1648a9772fc 100644 --- a/library/phx/resource_manager.cpp +++ b/library/phx/resource_manager.cpp @@ -46,20 +46,6 @@ void ResourceManager::RegisterResourceType( loaders_by_type_[type] = std::move(loader); } -phx::ResourceProxy *ResourceManager::DeclareResource( - const ResourceDeclaration &declaration) { - auto resource_hash = std::hash<std::string>{}(declaration.dump()); - - auto resource_entry = resources_.find(resource_hash); - if (resource_entry != resources_.end()) { - return resource_entry->second.get(); - } - - auto entry = resources_.insert(std::make_pair( - resource_hash, std::make_unique<ResourceProxy>(this, declaration))); - return entry.first->second.get(); -} - std::unique_ptr<phx::Resource> ResourceManager::Load( const ResourceDeclaration &declaration) { ResourceLoadStrategy *loader = nullptr; diff --git a/library/phx/resource_manager.hpp b/library/phx/resource_manager.hpp index 25e9bc943e903033fcf876e8a4b1a55e43c36797..1949b293fa82998e7dd7c09f73a00f1aa95d5ab7 100644 --- a/library/phx/resource_manager.hpp +++ b/library/phx/resource_manager.hpp @@ -31,6 +31,7 @@ #include "phx/logger.hpp" #include "phx/resource_declaration.hpp" #include "phx/resource_load_strategy.hpp" +#include "phx/resource_pointer.hpp" #include "phx/resource_proxy.hpp" #include "phx/singleton.hpp" @@ -50,7 +51,9 @@ class PHOENIX_EXPORT ResourceManager final : public singleton<ResourceManager> { void RegisterResourceType(const std::string& type, std::unique_ptr<ResourceLoadStrategy> loader); - ResourceProxy* DeclareResource(const ResourceDeclaration& declaration); + template <typename ResourceType> + ResourcePointer<ResourceType> DeclareResource( + const ResourceDeclaration& declaration); ResourceLoadStrategy* GetLoaderForType(const std::string& type) const; @@ -74,6 +77,21 @@ class PHOENIX_EXPORT ResourceManager final : public singleton<ResourceManager> { std::map<std::size_t, std::unique_ptr<ResourceProxy>> resources_; }; +template <typename ResourceType> +ResourcePointer<ResourceType> phx::ResourceManager::DeclareResource( + const ResourceDeclaration& declaration) { + auto resource_hash = std::hash<std::string>{}(declaration.dump()); + + auto resource_entry = resources_.find(resource_hash); + if (resource_entry != resources_.end()) { + return ResourcePointer<ResourceType>(resource_entry->second.get()); + } + + auto entry = resources_.insert(std::make_pair( + resource_hash, std::make_unique<ResourceProxy>(this, declaration))); + return ResourcePointer<ResourceType>(entry.first->second.get()); +} + } // namespace phx #endif // LIBRARY_PHX_RESOURCE_MANAGER_HPP_ diff --git a/library/phx/resource_pointer.hpp b/library/phx/resource_pointer.hpp index f2cb9391373e770bcf040f78424061c920453f15..4e2f0f8d9ea889d4f09ec5d60c2e18ecef8bd494 100644 --- a/library/phx/resource_pointer.hpp +++ b/library/phx/resource_pointer.hpp @@ -23,6 +23,8 @@ #ifndef LIBRARY_PHX_RESOURCE_POINTER_HPP_ #define LIBRARY_PHX_RESOURCE_POINTER_HPP_ +#include <cstddef> + #include "phx/export.hpp" #include "resource_proxy.hpp" @@ -32,7 +34,7 @@ template <class ResourceType> class PHOENIX_EXPORT ResourcePointer { public: ResourcePointer() : proxy_(nullptr) {} - explicit ResourcePointer(nullptr_t) : proxy_(nullptr) {} + explicit ResourcePointer(std::nullptr_t) : proxy_(nullptr) {} explicit ResourcePointer(ResourceProxy *proxy) : proxy_(proxy) {} ResourcePointer(const ResourcePointer &) = default; ResourcePointer(ResourcePointer &&) = default; @@ -42,25 +44,27 @@ class PHOENIX_EXPORT ResourcePointer { ResourceType *operator->() { return proxy_->GetAs<ResourceType>(); } bool operator==(const ResourcePointer<ResourceType> &a) const { - return a.GetProxy() == proxy_; + return a.proxy_ == proxy_; } - bool operator==(nullptr_t) const { + bool operator==(std::nullptr_t) const { return proxy_ == nullptr || !proxy_->IsOnline(); } bool operator!=(const ResourcePointer<ResourceType> &a) const { - return a.GetProxy() != proxy_; + return a.proxy_ != proxy_; } - bool operator!=(nullptr_t) const { + bool operator!=(std::nullptr_t) const { return proxy_ != nullptr && proxy_->IsOnline(); } bool operator<(const ResourcePointer<ResourceType> &a) const { - return a.GetProxy() < proxy_; + return a.proxy_ < proxy_; } operator bool() const { return proxy_ != nullptr && proxy_->IsOnline(); } - ResourceProxy *GetProxy() const { return proxy_; } ResourceType *Get() const { return proxy_->GetAs<ResourceType>(); } + void Load() { if (proxy_) proxy_->Load(); } + void Unload() { if (proxy_) proxy_->Unload(); } + private: ResourceProxy *proxy_; }; diff --git a/library/phx/resource_utils.cpp b/library/phx/resource_utils.cpp index e4e7f6990c71a92f781618f91ee2418e89f66f26..1e2c1995d089c4ad671e42f5f65db3fd4eb47ec8 100644 --- a/library/phx/resource_utils.cpp +++ b/library/phx/resource_utils.cpp @@ -22,6 +22,7 @@ #include "resource_utils.hpp" #include <algorithm> +#include <locale> #include <string> #include "phx/resource_manager.hpp" @@ -46,7 +47,7 @@ ResourceDeclaration ResourceUtils::DeclarationFromFile( std::string ResourceUtils::ExtractFileExtension(const std::string& file_name) { std::string extension = file_name.substr(file_name.rfind('.')); std::transform(extension.begin(), extension.end(), extension.begin(), - ::tolower); + [](char c) { return std::tolower(c, std::locale()); }); return extension; } diff --git a/library/phx/resource_utils.hpp b/library/phx/resource_utils.hpp index b599385d96f4231bce773898872d0db9b6fb7341..c27d46ee044641f0e3d45083f2ac8f371c5ce772 100644 --- a/library/phx/resource_utils.hpp +++ b/library/phx/resource_utils.hpp @@ -35,7 +35,6 @@ #include "phx/resource_load_strategy.hpp" #include "phx/resource_manager.hpp" #include "phx/resource_pointer.hpp" -#include "phx/resource_proxy.hpp" #include "phx/singleton.hpp" namespace phx { @@ -54,10 +53,11 @@ class PHOENIX_EXPORT ResourceUtils final { static ResourcePointer<ResourceType> LoadResourceFromFile( const std::string& file_name, nlohmann::json additional_info = {}, bool absolute_path = false) { - auto proxy = phx::ResourceManager::instance().DeclareResource( - DeclarationFromFile(file_name, additional_info, absolute_path)); - proxy->Load(); - return ResourcePointer<ResourceType>(proxy); + auto res_ptr = + phx::ResourceManager::instance().DeclareResource<ResourceType>( + DeclarationFromFile(file_name, additional_info, absolute_path)); + res_ptr.Load(); + return res_ptr; } }; diff --git a/library/phx/scene.cpp b/library/phx/scene.cpp index 3cadf3e1433d32120e4919ea218e06c9534ae393..00933e4940f25304858b3da1a9d57b70149b5ca3 100644 --- a/library/phx/scene.cpp +++ b/library/phx/scene.cpp @@ -73,6 +73,4 @@ std::string Scene::ToString() const { "(Scene #Entities: " + std::to_string(GetNumberOfEntities()) + ")"; } -phx::Engine* Scene::GetEngine() const { return engine_; } - } // namespace phx diff --git a/library/phx/scene_loader.cpp b/library/phx/scene_loader.cpp index a112b8884c0fe1aa8f192d5fcb820c7f72073867..ef6fa6fa88ac6d8a832806836d7a310805662e05 100644 --- a/library/phx/scene_loader.cpp +++ b/library/phx/scene_loader.cpp @@ -36,20 +36,36 @@ namespace phx { bool SceneLoader::InsertModelIntoScene(const std::string& file_name, Scene* scene) { auto model = ResourceUtils::LoadResourceFromFile<Model>(file_name); - if (!model.GetProxy()->IsOnline()) { + if (model == nullptr) { return false; } + auto rootEntity = scene->CreateEntity(); + rootEntity->SetName(ConstructRootName(file_name)); + auto root_transform = rootEntity->AddComponent<Transform>(); + for (auto mesh : model->GetMeshes()) { auto entity = scene->CreateEntity(); - entity->AddComponent<Transform>(); + entity->AddComponent<Transform>()->SetParent(root_transform); entity->AddComponent<MeshHandle>()->SetMesh(mesh); ResourcePointer<Material> material = model->GetMaterialForMesh(mesh); - if (material != nullptr && material.GetProxy()->IsOnline()) { + if (material != nullptr) { entity->AddComponent<MaterialHandle>()->SetMaterial(material); } } return true; } + +std::string SceneLoader::ConstructRootName(const std::string& file_name) { + const auto last_slash = file_name.find_last_of('/'); + const auto last_dot = file_name.find_last_of('.'); + const std::size_t model_name_first_pos = + last_slash == std::string::npos ? 0 : last_slash + 1; + const std::size_t model_name_last_pos = + last_dot == std::string::npos ? file_name.length() - 1 : last_dot; + return file_name.substr(model_name_first_pos, + model_name_last_pos - model_name_first_pos); +} + } // namespace phx diff --git a/library/phx/scene_loader.hpp b/library/phx/scene_loader.hpp index 2ba77eb4e1dcfc6544fbfb18c6beb50c95a15a87..204af32dde777a4e863e912f5977bd290b385b28 100644 --- a/library/phx/scene_loader.hpp +++ b/library/phx/scene_loader.hpp @@ -33,6 +33,9 @@ namespace phx { class PHOENIX_EXPORT SceneLoader { public: static bool InsertModelIntoScene(const std::string& file_name, Scene* scene); + + private: + static std::string ConstructRootName(const std::string& file_name); }; } // namespace phx diff --git a/library/phx/setup.cpp b/library/phx/setup.cpp index 2b97bad44ba18b34ec81f4a458f3869c44af6318..0d5ff27d4693e93541dc5380ecff61f6da41fe47 100644 --- a/library/phx/setup.cpp +++ b/library/phx/setup.cpp @@ -24,11 +24,13 @@ #include <cassert> #include <memory> +#include <string> #include <utility> #include "behavior_system.hpp" #include "blit_pass.hpp" #include "clear_pass.hpp" +#include "component.hpp" #include "display_system_openvr.hpp" #include "display_system_window.hpp" #include "engine.hpp" @@ -38,6 +40,8 @@ #include "openvr_controller_system.hpp" #include "render_target.hpp" #include "rendering_system.hpp" +#include "runtime_component.hpp" +#include "scene.hpp" #include "tracking_system_openvr.hpp" #undef CreateWindow @@ -55,83 +59,103 @@ std::unique_ptr<Engine> Setup::CreateDefaultEngine() { auto displaysys_window = engine->CreateSystem<DisplaySystemWindow>(); DisplaySystemOpenVR* displaysys_hmd = nullptr; bool using_hmd = false; + if (HMD::IsHMDPresent()) { info("An HMD is present so we use it"); using_hmd = true; displaysys_hmd = engine->CreateSystem<DisplaySystemOpenVR>(); displaysys_hmd->CreateHMD(); - displaysys_window->CreateWindow( - "Phoenix HMD Companion", glm::uvec2(10, 10), - displaysys_hmd->GetHMD()->GetViewportSize()); - } else { - displaysys_window->CreateWindow("Phoenix", glm::uvec2(100, 100)); } + const std::string window_title{using_hmd ? "Phoenix -- HMD Companion" + : "Phoenix"}; + const glm::uvec2 window_position{100, 100}; + const glm::uvec2 window_size{1024, 768}; + displaysys_window->CreateWindow(window_title, window_position, window_size); + auto rendering_system = engine->CreateSystem<RenderingSystem>(engine->GetSystem<DisplaySystem>()); // fix update order - engine->GetUpdateOrder().MoveToBack(displaysys_window); - engine->GetUpdateOrder().MoveBefore(rendering_system, displaysys_window); + engine->MoveSystemToBack(displaysys_window); + engine->MoveSystemBefore(rendering_system, displaysys_window); // setup rendering and frame graph if (using_hmd) { - // we need the render targets of the DisplaySystemOpenVR, but the - // DisplaySystemWindow only exists for blitting the result of the left eye - // into the window and does not create a render target themselves - auto render_targets = displaysys_hmd->CreateRenderTargets(); - rendering_system->SetRenderTargets(&render_targets); - SetupDefaultFrameGraphOpenVR(rendering_system); auto tracking_system = engine->CreateSystem<TrackingSystemOpenVR>(displaysys_hmd); auto controller_system = engine->CreateSystem<OpenVRControllerSystem>( engine->GetSystem<DisplaySystem>()); - engine->GetUpdateOrder().MoveBefore(tracking_system, rendering_system); - engine->GetUpdateOrder().MoveAfter(behavior_system, tracking_system); - engine->GetUpdateOrder().MoveAfter(tracking_system, controller_system); + + displaysys_hmd->CreateRenderTargets(engine->GetScene().get()); + SetupDefaultFrameGraphOpenVR(rendering_system, engine.get()); + + engine->MoveSystemBefore(tracking_system, rendering_system); + engine->MoveSystemAfter(behavior_system, tracking_system); + engine->MoveSystemAfter(controller_system, tracking_system); } else { - auto render_targets = displaysys_window->CreateRenderTargets(); - rendering_system->SetRenderTargets(&render_targets); - SetupDefaultFrameGraphWindow(rendering_system); + // TODO(@ALL): This should not be done here. + Entity* platform = + engine->GetScene() + ->GetEntitiesWithComponents<RuntimeComponent<USER_PLATFORM>>()[0]; + Entity* camera = engine->GetScene()->CreateEntity(); + camera->AddComponent<Transform>()->SetParent( + platform->GetFirstComponent<Transform>()); + camera->AddComponent<Projection>(); + camera->AddComponent<RenderTarget>(window_size); + SetupDefaultFrameGraphWindow(rendering_system, engine.get()); } return engine; } -void Setup::SetupDefaultFrameGraphWindow(RenderingSystem* rendering_system) { +void Setup::SetupDefaultFrameGraphWindow(RenderingSystem* rendering_system, + Engine* engine) { auto frame_graph = std::make_unique<FrameGraph>(); - auto render_targets = rendering_system->GetRenderTargets(); - if (render_targets.empty()) { + auto render_target = engine->GetScene() + ->GetEntitiesWithComponents<RenderTarget>()[0] + ->GetFirstComponent<RenderTarget>(); + if (!render_target) { error("Cannot setup default frame graph (window): no render targets."); return; } - frame_graph->AddRenderPass(std::make_unique<ClearPass>(render_targets[0])); - frame_graph->AddRenderPass(std::make_unique<GeometryPass>(render_targets[0])); - frame_graph->AddRenderPass(std::make_unique<BlitPass>(render_targets[0])); + frame_graph->AddRenderPass(std::make_unique<ClearPass>(render_target)); + frame_graph->AddRenderPass(std::make_unique<GeometryPass>(render_target)); + frame_graph->AddRenderPass(std::make_unique<BlitPass>(render_target)); frame_graph->Initialize(); rendering_system->SetFrameGraph(std::move(frame_graph)); } -void Setup::SetupDefaultFrameGraphOpenVR(RenderingSystem* rendering_system) { +void Setup::SetupDefaultFrameGraphOpenVR(RenderingSystem* rendering_system, + Engine* engine) { auto frame_graph = std::make_unique<FrameGraph>(); - auto render_targets = rendering_system->GetRenderTargets(); - if (render_targets.size() < 2) { + auto left_render_target = + engine->GetScene() + ->GetEntitiesWithComponents<RuntimeComponent<LEFT_EYE>>()[0] + ->GetFirstComponent<RenderTarget>(); + auto right_render_target = + engine->GetScene() + ->GetEntitiesWithComponents<RuntimeComponent<RIGHT_EYE>>()[0] + ->GetFirstComponent<RenderTarget>(); + if (!left_render_target || !right_render_target) { error( "Cannot setup default frame graph (OpenVR): not enough render " "targets."); return; } - frame_graph->AddRenderPass(std::make_unique<ClearPass>(render_targets[0])); - frame_graph->AddRenderPass(std::make_unique<ClearPass>(render_targets[1])); - frame_graph->AddRenderPass(std::make_unique<GeometryPass>(render_targets[0])); - frame_graph->AddRenderPass(std::make_unique<GeometryPass>(render_targets[1])); + frame_graph->AddRenderPass(std::make_unique<ClearPass>(right_render_target)); + frame_graph->AddRenderPass(std::make_unique<ClearPass>(left_render_target)); + frame_graph->AddRenderPass( + std::make_unique<GeometryPass>(right_render_target)); + frame_graph->AddRenderPass( + std::make_unique<GeometryPass>(left_render_target)); - frame_graph->AddRenderPass(std::make_unique<BlitPass>(render_targets[0])); + frame_graph->AddRenderPass(std::make_unique<BlitPass>(right_render_target)); frame_graph->Initialize(); diff --git a/library/phx/setup.hpp b/library/phx/setup.hpp index c5fb4a7496c2990dc871484eb020e0c22c0b437b..ee37cf4cf9b4712479652c1d5aa2716bf5b29343 100644 --- a/library/phx/setup.hpp +++ b/library/phx/setup.hpp @@ -43,8 +43,10 @@ class PHOENIX_EXPORT Setup { // also creates an empty scene for the engine static std::unique_ptr<Engine> CreateDefaultEngine(); - static void SetupDefaultFrameGraphWindow(RenderingSystem* rendering_system); - static void SetupDefaultFrameGraphOpenVR(RenderingSystem* rendering_system); + static void SetupDefaultFrameGraphWindow(RenderingSystem* rendering_system, + Engine* engine); + static void SetupDefaultFrameGraphOpenVR(RenderingSystem* rendering_system, + Engine* engine); }; } // namespace phx diff --git a/library/phx/shader_program.cpp b/library/phx/shader_program.cpp index 445f001ef4171700c652313dc480c1e557673caa..85f76897a39a9db2028f7681ebfc46788b795cc8 100644 --- a/library/phx/shader_program.cpp +++ b/library/phx/shader_program.cpp @@ -33,8 +33,8 @@ namespace phx { -bool ShaderProgram::SetShader( - ShaderChannel channel, ResourcePointer<ShaderSource> shader_source) { +bool ShaderProgram::SetShader(ShaderChannel channel, + ResourcePointer<ShaderSource> shader_source) { auto& entry = shaders_[channel]; entry.first = shader_source; entry.second = @@ -79,10 +79,11 @@ GLenum ShaderProgram::ConvertChannelToGL(ShaderChannel channel) const { return GL_FRAGMENT_SHADER; case COMPUTE: return GL_COMPUTE_SHADER; - default: - phx::warn("WARNING: Invalid internal shader channel {}!", channel); - return GL_INVALID_ENUM; + case MAX_SHADER_CHANNEL: + break; } + phx::warn("WARNING: Invalid internal shader channel {}!", channel); + return GL_INVALID_ENUM; } } // namespace phx diff --git a/library/phx/shader_program.hpp b/library/phx/shader_program.hpp index 3244f15ee0a6174b50ccfd3301026bdfca7178e4..63bc305fb810aeb66a55d9c6ecdc016849a0e466 100644 --- a/library/phx/shader_program.hpp +++ b/library/phx/shader_program.hpp @@ -29,6 +29,8 @@ #include <utility> #include <vector> +#include "phx/suppress_warnings.hpp" + SUPPRESS_WARNINGS_BEGIN #include "gl/auxiliary/glm_uniforms.hpp" SUPPRESS_WARNINGS_END diff --git a/library/phx/singleton.hpp b/library/phx/singleton.hpp index cabe1ab8714e216fb9e73031b1aac91315bc7748..73fddef37be3d30202a44b280b29abf25161b545 100644 --- a/library/phx/singleton.hpp +++ b/library/phx/singleton.hpp @@ -35,8 +35,8 @@ class singleton { static type& instance(arguments&&... args) { std::call_once( get_once_flag(), - [](arguments&&... args) { - instance_.reset(new type(std::forward<arguments>(args)...)); + [](arguments&&... lambda_args) { + instance_.reset(new type(std::forward<arguments>(lambda_args)...)); }, std::forward<arguments>(args)...); return *instance_.get(); @@ -58,7 +58,9 @@ class singleton { } static std::unique_ptr<type> instance_; }; + template <class type> std::unique_ptr<type> singleton<type>::instance_ = nullptr; + } // namespace phx #endif // LIBRARY_PHX_SINGLETON_HPP_ diff --git a/library/phx/splash_screen.cpp b/library/phx/splash_screen.cpp index 3a36247ff754345f13c6ad1b564496a68e8f1b9a..3064a85876105d783d1c8282cabd900418d83d71 100644 --- a/library/phx/splash_screen.cpp +++ b/library/phx/splash_screen.cpp @@ -99,8 +99,9 @@ void SplashScreen::Draw() { gl::print_error("OpenGl Error blitting Splash Screen: "); constexpr float progressbar_max_pixel_width = 198.f; - const int progressbar_current_pixel_width = static_cast<int>( - std::round(load_progress_ * progressbar_max_pixel_width)); + const unsigned int progressbar_current_pixel_width = + static_cast<unsigned int>( + std::round(load_progress_ * progressbar_max_pixel_width)); const int progressbar_pixel_height = 9; auto progressbar_x_offset = x_offset + 98; diff --git a/library/phx/splash_screen.hpp b/library/phx/splash_screen.hpp index 71492e57ab2e767359e97016fda3868c9d7e7d10..8755048cd61e850108a5505898ea3b99c70a7ad4 100644 --- a/library/phx/splash_screen.hpp +++ b/library/phx/splash_screen.hpp @@ -25,16 +25,18 @@ #include <memory> +#include "phx/suppress_warnings.hpp" + #include "phx/export.hpp" #include "phx/image.hpp" #include "phx/resource_pointer.hpp" -#include "phx/resource_proxy.hpp" #include "phx/window.hpp" #include "gl/framebuffer.hpp" namespace phx { +SUPPRESS_WARNINGS_BEGIN_PADDED class PHOENIX_EXPORT SplashScreen { public: explicit SplashScreen(Window* window); @@ -56,6 +58,7 @@ class PHOENIX_EXPORT SplashScreen { float load_progress_ = 0.f; }; +SUPPRESS_WARNINGS_END } // namespace phx diff --git a/library/phx/stream_helpers.hpp b/library/phx/stream_helpers.hpp index 671241428cccbe62c224065b2e5db66044ac8f92..0c924d2681858e4e67747a3ef69391200aefd71e 100644 --- a/library/phx/stream_helpers.hpp +++ b/library/phx/stream_helpers.hpp @@ -25,11 +25,15 @@ #include <ostream> +#include "phx/suppress_warnings.hpp" + +SUPPRESS_WARNINGS_BEGIN #include "glm/gtc/quaternion.hpp" #include "glm/mat4x4.hpp" #include "glm/vec2.hpp" #include "glm/vec3.hpp" #include "glm/vec4.hpp" +SUPPRESS_WARNINGS_END #include "phx/export.hpp" diff --git a/library/phx/tracking_system_openvr.hpp b/library/phx/tracking_system_openvr.hpp index 6c11f301c89d77052db966367b82834ac6c6e92b..9c1498555367f468a097c6b42cc437aff2577b74 100644 --- a/library/phx/tracking_system_openvr.hpp +++ b/library/phx/tracking_system_openvr.hpp @@ -26,6 +26,8 @@ #include <memory> #include <string> +#include "phx/suppress_warnings.hpp" + #include "phx/display_system_openvr.hpp" #include "phx/engine.hpp" #include "phx/export.hpp" diff --git a/library/phx/transform.cpp b/library/phx/transform.cpp index 160668d0cc6b8ffbde7987a3087473a7c2e3cd8e..32f699262afff5d85e53f5074623bea8a9ce66cf 100644 --- a/library/phx/transform.cpp +++ b/library/phx/transform.cpp @@ -23,10 +23,14 @@ #include <sstream> #include <string> +#include "phx/suppress_warnings.hpp" + +SUPPRESS_WARNINGS_BEGIN #include "glm/gtc/matrix_transform.hpp" #include "glm/gtx/matrix_decompose.hpp" #include "glm/gtx/quaternion.hpp" #include "glm/gtx/transform.hpp" +SUPPRESS_WARNINGS_END #include "transform.hpp" diff --git a/library/phx/transform.hpp b/library/phx/transform.hpp index 787c9df69a1c1055b3021fd58bc658ce349c0431..99092fe7e690363f8c2651b794d08a24fb6a9325 100644 --- a/library/phx/transform.hpp +++ b/library/phx/transform.hpp @@ -26,6 +26,8 @@ #include <ostream> #include <string> +#include "phx/suppress_warnings.hpp" + SUPPRESS_WARNINGS_BEGIN #include "glm/gtc/quaternion.hpp" #include "glm/mat4x4.hpp" diff --git a/library/phx/window.hpp b/library/phx/window.hpp index ea581f66159bc2051f4a0f5c04a3eefb46ea9dfd..23edcc2ed4affbb1b95fedf52aba016b8d89d948 100644 --- a/library/phx/window.hpp +++ b/library/phx/window.hpp @@ -25,6 +25,8 @@ #include <string> +#include "phx/suppress_warnings.hpp" + SUPPRESS_WARNINGS_BEGIN #include "SDL.h" #include "glm/vec2.hpp" diff --git a/resources/models/2MeshTest/2meshTest.mtl b/resources/models/2MeshTest/2meshTest.mtl index b12a299a5d24e44c41408fa26644fad05a48d88e..53e38c00429447e03f7c524c812927d3776d140f 100644 --- a/resources/models/2MeshTest/2meshTest.mtl +++ b/resources/models/2MeshTest/2meshTest.mtl @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f65ac63255c0ee6b100c60930f56246352d74c29244b41e55e796810f840dc39 +oid sha256:0aa92a1ed628ff21cec3069d2ae6ed1681c0ecd9577aa356826ddb71fc4e4673 size 443 diff --git a/resources/models/2MeshTest/2meshTest.obj b/resources/models/2MeshTest/2meshTest.obj index ada20b1a1a38726f2d685768b64b169acbd0e618..24e354691f9608ce0c5a5e32cb5b7a49327d0ec8 100644 --- a/resources/models/2MeshTest/2meshTest.obj +++ b/resources/models/2MeshTest/2meshTest.obj @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:adf68eae4f58c5a70ad65175988afd205eaa522ceb770d29846e4f6ec4321501 -size 46824 +oid sha256:3ffb6645047c096c5030efdba23b4bcada00a4e97c1396848bdf92469d98eff5 +size 46435 diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 14e3a3d43d80b7ada144e5e8a3f81e07489abb90..7a9d51630e5abc3d55fc600d163802bf5d3266ed 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -40,7 +40,7 @@ get_target_property(glew_include_directories get_target_property(phoenix_include_directories phoenix INCLUDE_DIRECTORIES) get_target_property(sdl2_include_directories - ${CONAN_OR_CMAKE_SDL2} INTERFACE_INCLUDE_DIRECTORIES) + ${CONAN_OR_CMAKE_sdl2} INTERFACE_INCLUDE_DIRECTORIES) get_target_property(openvr_include_directories ${CONAN_OR_CMAKE_openvr} INTERFACE_INCLUDE_DIRECTORIES) get_target_property(gl_include_directories @@ -54,6 +54,9 @@ macro(add_mock_lib mock_name mock_src_path) ) target_link_libraries(${mock_name} ${CONAN_OR_CMAKE_trompeloeil}) + #phx include dirs needed for suppress_warnings.hpp + target_include_directories(${mock_name} + PRIVATE ${phoenix_include_directories}) set_property(TARGET ${mock_name} PROPERTY FOLDER "Tests") set_warning_levels_rwth(${mock_name}) endmacro() @@ -162,7 +165,7 @@ macro(add_mocked_test cpp_file) list(REMOVE_ITEM phoenix_link_libraries ${CONAN_OR_CMAKE_gl}) list(REMOVE_ITEM phoenix_link_libraries ${CONAN_OR_CMAKE_glew}) #SDL has also to be removed since it contains OpenGL - list(REMOVE_ITEM phoenix_link_libraries ${CONAN_OR_CMAKE_SDL2}) + list(REMOVE_ITEM phoenix_link_libraries ${CONAN_OR_CMAKE_sdl2}) list(REMOVE_ITEM phoenix_link_libraries ${OPENGL_LIBRARIES}) list(APPEND phoenix_link_libraries opengl_mock) list(APPEND phoenix_link_libraries ${gl_link_library}) @@ -176,7 +179,7 @@ macro(add_mocked_test cpp_file) target_compile_definitions(${cpp_file} PRIVATE TESTING) target_include_directories(${cpp_file} PRIVATE ${sdl2_include_directories}) - list(REMOVE_ITEM phoenix_link_libraries ${CONAN_OR_CMAKE_SDL2}) + list(REMOVE_ITEM phoenix_link_libraries ${CONAN_OR_CMAKE_sdl2}) endif(${ADD_MOCKED_TEST_MOCK_SDL}) if(${ADD_MOCKED_TEST_MOCK_OPENVR}) @@ -199,9 +202,7 @@ endmacro() # Otherwise, the mocked ones are not in PHOENIX_TEST_SOURCES anymore add_test_cppcheck(NAME "phoenix-tests--cppcheck" ${PHOENIX_TEST_SOURCES} - ${PHOENIX_TEST_HEADERS} ${PHOENIX_TEST_UTILITIES_TEST_SOURCES} - ${PHOENIX_TEST_UTILITIES_HEADERS} ${PHOENIX_TEST_UTILITIES_SOURCES} ) @@ -231,6 +232,7 @@ add_mocked_test(test_openvr_controller_system MOCK_SDL MOCK_OPENVR MOCK_GLEW) add_mocked_test(integration_test_model_rendering MOCK_OPENVR) add_mocked_test(integration_test_opengl_buffer_data_download MOCK_OPENVR) add_mocked_test(integration_test_rendering MOCK_OPENVR) +add_mocked_test(integration_test_hmd MOCK_OPENVR) #------------------------------------------------------------------------------- #------------------------------------------------------------------------------- diff --git a/tests/reference_images/hmd_test_left.png b/tests/reference_images/hmd_test_left.png new file mode 100644 index 0000000000000000000000000000000000000000..9989f7ae4601b0eb1fcd961ccba454ddf6fdd45d --- /dev/null +++ b/tests/reference_images/hmd_test_left.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e4a6d5d6c1eed96056d964381617ec97dd3b6c9d26717cdc55c1e66c8343feed +size 115516 diff --git a/tests/reference_images/hmd_test_right.png b/tests/reference_images/hmd_test_right.png new file mode 100644 index 0000000000000000000000000000000000000000..33f5fa2758442f23f4bcf04d353ea2e6661cc9a6 --- /dev/null +++ b/tests/reference_images/hmd_test_right.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e07eb1a9c5bfea732801cbd4b6d6321c7797d815645b23fa205a14fa50d76b3d +size 115419 diff --git a/tests/src/integration_test_hmd.cpp b/tests/src/integration_test_hmd.cpp new file mode 100644 index 0000000000000000000000000000000000000000..9a71c4ec06ce21fbb2c41cf1bbd034a4eda12b0b --- /dev/null +++ b/tests/src/integration_test_hmd.cpp @@ -0,0 +1,169 @@ +//------------------------------------------------------------------------------ +// Project Phoenix +// +// Copyright (c) 2017-2018 RWTH Aachen University, Germany, +// Virtual Reality & Immersive Visualization Group. +//------------------------------------------------------------------------------ +// License +// +// Licensed under the 3-Clause BSD License (the "License"); +// you may not use this file except in compliance with the License. +// See the file LICENSE for the full text. +// You may obtain a copy of the License at +// +// https://opensource.org/licenses/BSD-3-Clause +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +//------------------------------------------------------------------------------ + +#include <memory> +#include <string> +#include <utility> +#include <vector> + +#include "catch/catch.hpp" + +#include "phx/suppress_warnings.hpp" + +#include "phx/engine.hpp" +#include "phx/light.hpp" +#include "phx/opengl_image_buffer_data.hpp" +#include "phx/resource_utils.hpp" +#include "phx/runtime_component.hpp" +#include "phx/scene_loader.hpp" +#include "phx/setup.hpp" +#include "phx/transform.hpp" + +SUPPRESS_WARNINGS_BEGIN +#include "mocks/openvr_mock.hpp" + +#include "gl/texture.hpp" +SUPPRESS_WARNINGS_END + +#include "test_utilities/opengl_buffer_data_comparison.hpp" + +#include "trompeloeil.hpp" + +extern template struct trompeloeil::reporter<trompeloeil::specialized>; +using trompeloeil::_; + +namespace { + +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wmissing-prototypes" +#endif + +void SetupScene(phx::Engine* engine) { + auto scene = engine->GetScene(); + phx::Entity* main_light = scene->CreateEntity(); + phx::Transform* light_transform = main_light->AddComponent<phx::Transform>(); + light_transform->SetLocalRotation( + glm::angleAxis(0.1f * glm::pi<float>(), glm::vec3(0, 1, 0))); + phx::Light* light = main_light->AddComponent<phx::Light>(); + light->SetType(phx::Light::Type::kDirectional); + light->SetColor(glm::vec3(1.0f, 1.0f, 1.0f)); + light->SetIntensity(1.0f); + + phx::SceneLoader::InsertModelIntoScene("models/2MeshTest/2meshTest.obj", + scene.get()); +} + +GLuint OpenVRTextureID(const vr::Texture_t* vr_texture) { + if (vr_texture->eType != vr::TextureType_OpenGL || + vr_texture->eColorSpace != vr::ColorSpace_Gamma) { + std::cerr << "vr_texture has unexpected type!" << std::endl; + return 0; + } + return static_cast<GLuint>(reinterpret_cast<uintptr_t>(vr_texture->handle)); +} + +class EngineStopTestSystem : public phx::System { + public: + explicit EngineStopTestSystem(phx::Engine* engine) : phx::System(engine) {} + + void Update(const phx::FrameTimer::TimeInfo&) override { + GetEngine()->Stop(); + } +}; + +void CheckSimilarity(GLuint submitted_image_id, std::string ref_image_name) { + gl::texture_2d submitted_tex(submitted_image_id); + auto buffer = phx::OpenGLImageBufferData< + phx::OpenGLImageBufferDataType_RGB>::CreateFromTexture(&submitted_tex); + test_utilities::OpenGLBufferComparison::REQUIRE_REFERENCE_IMAGE_SIMILARITY( + *buffer, ref_image_name, 1.0); +} + +void MoveUserPlatform(phx::Engine* engine) { + auto platform_entities = engine->GetScene() + ->GetEntitiesWithComponents< + phx::RuntimeComponent<phx::USER_PLATFORM>>(); + REQUIRE(platform_entities.size() == 1); + auto transform_cmp = + platform_entities[0]->GetFirstComponent<phx::Transform>(); + transform_cmp->Translate(glm::vec3(3.0f, 0.0f, 5.0f)); + transform_cmp->SetLocalRotationEuler(glm::vec3(0.f, 30.f, 0.f)); +} + +#ifdef __clang__ +#pragma clang diagnostic pop +#endif + +GLuint left_tex_id, right_tex_id; + +} // namespace + +#define ALLOW_SUBMIT_CALLS \ + ALLOW_CALL(openvr_mock.GetCompositor(), \ + Submit(vr::EVREye::Eye_Left, _, _, _)) \ + .SIDE_EFFECT(::left_tex_id = ::OpenVRTextureID(_2)) \ + .RETURN(vr::EVRCompositorError::VRCompositorError_None); \ + ALLOW_CALL(openvr_mock.GetCompositor(), \ + Submit(vr::EVREye::Eye_Right, _, _, _)) \ + .SIDE_EFFECT(::right_tex_id = ::OpenVRTextureID(_2)) \ + .RETURN(vr::EVRCompositorError::VRCompositorError_None); + +SCENARIO("If no HMD is present nothing is rendered into it", + "[phx][phx::HMD]") { + ALLOW_CALL(openvr_mock.Get(), VR_IsHmdPresent()).RETURN(false); + GIVEN("A standard engine that runs one frame") { + std::unique_ptr<phx::Engine> engine = phx::Setup::CreateDefaultEngine(); + engine->CreateSystem<EngineStopTestSystem>(); + + WHEN("We run the engine") { + FORBID_CALL(openvr_mock.GetCompositor(), Submit(_, _, _, _)); + engine->Run(); + THEN("Submit() to HMD is never called") {} + } + } +} + +SCENARIO("If a HMD is present we render for both eyes including controllers", + "[phx][phx::HMD]") { + OPENVR_MOCK_ALLOW_ANY_CALL + ALLOW_CALL(openvr_mock.Get(), VR_IsHmdPresent()).RETURN(true); + ALLOW_SUBMIT_CALLS + + GIVEN( + "A standard engine that runs one frame and a scene plus a moved user " + "platform") { + std::unique_ptr<phx::Engine> engine = phx::Setup::CreateDefaultEngine(); + engine->CreateSystem<EngineStopTestSystem>(); + ::SetupScene(engine.get()); + ::MoveUserPlatform(engine.get()); + + WHEN("We run the engine") { + // TODO(JW): controller models should also be rendered + engine->Run(); + THEN("Submit() is called for both eyes submitting the expected images") { + ::CheckSimilarity(::left_tex_id, "hmd_test_left.png"); + ::CheckSimilarity(::right_tex_id, "hmd_test_right.png"); + } + } + } +} diff --git a/tests/src/integration_test_model_rendering.cpp b/tests/src/integration_test_model_rendering.cpp index dc107451e97160504b6886a2d518bf801e229bd5..4b9416dad1fbd4ac028b01a2c67ece54298a56c7 100644 --- a/tests/src/integration_test_model_rendering.cpp +++ b/tests/src/integration_test_model_rendering.cpp @@ -21,9 +21,12 @@ //------------------------------------------------------------------------------ #include <memory> +#include <string> #include "catch/catch.hpp" +#include "phx/suppress_warnings.hpp" + #include "phx/assimp_model_loader.hpp" #include "phx/display_system_window.hpp" #include "phx/frame_timer.hpp" @@ -33,7 +36,6 @@ #include "phx/rendering_system.hpp" #include "phx/resource_declaration.hpp" #include "phx/resource_manager.hpp" -#include "phx/resource_proxy.hpp" #include "phx/resource_utils.hpp" #include "phx/scene.hpp" #include "phx/setup.hpp" @@ -49,8 +51,12 @@ SUPPRESS_WARNINGS_END extern template struct trompeloeil::reporter<trompeloeil::specialized>; +#if defined __clang__ +#pragma clang diagnostic ignored "-Wmissing-prototypes" +#endif + phx::Entity* LoadBunny(glm::vec3 pos, float angleDeg, - unsigned int material_index, phx::Scene* scene) { + const std::string& material_name, phx::Scene* scene) { auto bunny_mesh = phx::ResourceUtils::LoadResourceFromFile<phx::Mesh>( "models/bunny.obj", {{"mesh_index", 0}}); @@ -63,7 +69,7 @@ phx::Entity* LoadBunny(glm::vec3 pos, float angleDeg, bunny->AddComponent<phx::MaterialHandle>(); auto bunny_material = phx::ResourceUtils::LoadResourceFromFile<phx::Material>( - "models/bunny.obj", {{"material_index", material_index}}); + "models/bunny.obj", {{"material_name", material_name}}); bunny_material_handle->SetMaterial(bunny_material); phx::Transform* bunny_transform = bunny->AddComponent<phx::Transform>(); @@ -74,7 +80,6 @@ phx::Entity* LoadBunny(glm::vec3 pos, float angleDeg, return bunny; } -void SetupLightAndCamera(phx::Scene* scene); void SetupLightAndCamera(phx::Scene* scene) { phx::Entity* main_light = scene->CreateEntity(); phx::Transform* light_transform = main_light->AddComponent<phx::Transform>(); @@ -85,9 +90,10 @@ void SetupLightAndCamera(phx::Scene* scene) { light->SetColor(glm::vec3(1.0f, 1.0f, 1.0f)); light->SetIntensity(1.0f); - phx::Entity* camera = scene->CreateEntity(); - auto camera_transform = camera->AddComponent<phx::Transform>(); - auto camera_projection = camera->AddComponent<phx::Projection>(); + phx::Entity* camera = + scene->GetEntitiesWithComponents<phx::RenderTarget>()[0]; + auto camera_transform = camera->GetFirstComponent<phx::Transform>(); + auto camera_projection = camera->GetFirstComponent<phx::Projection>(); camera_projection->SetPerspective(glm::radians(68.0f), 4.0f / 3.0f, 0.01f, 1000.0f); camera_transform->SetLocalTranslation(glm::vec3(0, 0, -0.3)); @@ -105,10 +111,8 @@ SCENARIO( SetupLightAndCamera(scene.get()); - phx::Entity* bunny1 = - LoadBunny(glm::vec3(0.15f, -0.1f, 0.0f), 0.0f, 1, scene.get()); - phx::Entity* bunny2 = - LoadBunny(glm::vec3(-0.15f, -0.1f, 0.0f), 180.0f, 2, scene.get()); + LoadBunny(glm::vec3(0.15f, -0.1f, 0.0f), 0.0f, "bunny", scene.get()); + LoadBunny(glm::vec3(-0.15f, -0.1f, 0.0f), 180.0f, "bunny2", scene.get()); auto rendering_system = engine->GetSystem<phx::RenderingSystem>(); auto display_system = engine->GetSystem<phx::DisplaySystemWindow>(); @@ -136,8 +140,7 @@ SCENARIO( std::unique_ptr<phx::Engine> engine = phx::Setup::CreateDefaultEngine(); auto scene = engine->GetScene(); - phx::Entity* bunny1 = - LoadBunny(glm::vec3(0.0f, -0.1f, -0.3f), 0.0f, 1, scene.get()); + LoadBunny(glm::vec3(0.0f, -0.1f, -0.3f), 0.0f, "bunny", scene.get()); auto rendering_system = engine->GetSystem<phx::RenderingSystem>(); auto display_system = engine->GetSystem<phx::DisplaySystemWindow>(); diff --git a/tests/src/integration_test_opengl_buffer_data_download.cpp b/tests/src/integration_test_opengl_buffer_data_download.cpp index 16ec61edecc70111a11ca1ce5e3ee78a2bccdb64..7b9e2c2707f673f8ad166cc2280783908edd9466 100644 --- a/tests/src/integration_test_opengl_buffer_data_download.cpp +++ b/tests/src/integration_test_opengl_buffer_data_download.cpp @@ -27,6 +27,8 @@ #include "catch/catch.hpp" +#include "phx/suppress_warnings.hpp" + #include "phx/engine.hpp" #include "phx/entity.hpp" #include "phx/mesh.hpp" @@ -36,7 +38,6 @@ #include "phx/resource_declaration.hpp" #include "phx/resource_manager.hpp" #include "phx/resource_pointer.hpp" -#include "phx/resource_proxy.hpp" #include "phx/scene.hpp" #include "phx/setup.hpp" #include "phx/window.hpp" @@ -94,14 +95,14 @@ class SceneSetupSimple { "custommaterial", std::make_unique<phx::DummyMaterialGenerator>( glm::vec3(), glm::vec3(), glm::vec3(1.f, 0.5f, 0.25f), 500.0f)); - auto material_proxy = phx::ResourceManager::instance().DeclareResource( - {{"TYPE", "custommaterial"}}); - material_proxy->Load(); + auto material = + phx::ResourceManager::instance().DeclareResource<phx::Material>( + {{"TYPE", "custommaterial"}}); + material.Load(); phx::MaterialHandle* material_handle = triangle->AddComponent<phx::MaterialHandle>(); - material_handle->SetMaterial( - phx::ResourcePointer<phx::Material>(material_proxy)); + material_handle->SetMaterial(material); std::vector<glm::vec3> vertices = { {-1.0f, -1.0f, 0.5f}, {1.0f, -1.0f, 0.5f}, {1.0f, 1.0f, 0.5f}}; @@ -113,12 +114,12 @@ class SceneSetupSimple { "staticmesh", std::make_unique<phx::DummyMeshLoader>( std::move(vertices), std::move(normals), std::move(indices))); - auto mesh_proxy = phx::ResourceManager::instance().DeclareResource( + auto mesh = phx::ResourceManager::instance().DeclareResource<phx::Mesh>( {{"TYPE", "staticmesh"}}); - mesh_proxy->Load(); + mesh.Load(); auto mesh_handle = triangle->AddComponent<phx::MeshHandle>(); - mesh_handle->SetMesh(phx::ResourcePointer<phx::Mesh>(mesh_proxy)); + mesh_handle->SetMesh(mesh); phx::Entity* main_light = scene->CreateEntity(); main_light->AddComponent<phx::Transform>(); diff --git a/tests/src/integration_test_rendering.cpp b/tests/src/integration_test_rendering.cpp index 4dc91836cd69184f7098628ee3c63fbc2e8ad285..fae6373d2b335894e644afe32725def618896dbb 100644 --- a/tests/src/integration_test_rendering.cpp +++ b/tests/src/integration_test_rendering.cpp @@ -26,6 +26,8 @@ #include "catch/catch.hpp" +#include "phx/suppress_warnings.hpp" + #include "phx/display_system_window.hpp" #include "phx/frame_timer.hpp" #include "phx/mesh.hpp" @@ -33,7 +35,6 @@ #include "phx/opengl_image_buffer_data.hpp" #include "phx/rendering_system.hpp" #include "phx/resource_manager.hpp" -#include "phx/resource_proxy.hpp" #include "phx/scene.hpp" #include "phx/setup.hpp" #include "phx/window.hpp" @@ -50,7 +51,10 @@ SUPPRESS_WARNINGS_END extern template struct trompeloeil::reporter<trompeloeil::specialized>; -void SetupLightAndCamera(phx::Scene* scene); +#if defined __clang__ +#pragma clang diagnostic ignored "-Wmissing-prototypes" +#endif + void SetupLightAndCamera(phx::Scene* scene) { phx::Entity* main_light = scene->CreateEntity(); phx::Transform* light_transform = main_light->AddComponent<phx::Transform>(); @@ -61,9 +65,10 @@ void SetupLightAndCamera(phx::Scene* scene) { light->SetColor(glm::vec3(1.0f, 1.0f, 1.0f)); light->SetIntensity(1.0f); - phx::Entity* camera = scene->CreateEntity(); - auto camera_transform = camera->AddComponent<phx::Transform>(); - auto camera_projection = camera->AddComponent<phx::Projection>(); + phx::Entity* camera = + scene->GetEntitiesWithComponents<phx::RenderTarget>()[0]; + auto camera_transform = camera->GetFirstComponent<phx::Transform>(); + auto camera_projection = camera->GetFirstComponent<phx::Projection>(); camera_projection->SetPerspective(glm::radians(68.0f), 4.0f / 3.0f, 0.01f, 1000.0f); camera_transform->SetLocalTranslation(glm::vec3(0, 0, 2.0)); @@ -82,12 +87,12 @@ void CreateTestTriangleComponent(phx::Entity* triangle) { "staticmesh", std::make_unique<phx::DummyMeshLoader>( std::move(vertices), std::move(normals), std::move(indices))); - auto mesh_proxy = phx::ResourceManager::instance().DeclareResource( + auto mesh = phx::ResourceManager::instance().DeclareResource<phx::Mesh>( {{"TYPE", "staticmesh"}}); - mesh_proxy->Load(); + mesh.Load(); phx::MeshHandle* mesh_handle = triangle->AddComponent<phx::MeshHandle>(); - mesh_handle->SetMesh(phx::ResourcePointer<phx::Mesh>(mesh_proxy)); + mesh_handle->SetMesh(mesh); } SCENARIO("We can render a simple triangle", "[phx][phx::Rendering]") { @@ -107,15 +112,15 @@ SCENARIO("We can render a simple triangle", "[phx][phx::Rendering]") { "custommaterial", std::make_unique<phx::DummyMaterialGenerator>( glm::vec3(0.2f, 0.2f, 1.0f), glm::vec3(1, 1, 1), glm::vec3(), 500.0f)); - auto material_proxy = phx::ResourceManager::instance().DeclareResource( - {{"TYPE", "custommaterial"}}); - material_proxy->Load(); + auto material = + phx::ResourceManager::instance().DeclareResource<phx::Material>( + {{"TYPE", "custommaterial"}}); + material.Load(); - phx::Transform* transform = triangle->AddComponent<phx::Transform>(); + triangle->AddComponent<phx::Transform>(); phx::MaterialHandle* material_handle = triangle->AddComponent<phx::MaterialHandle>(); - material_handle->SetMaterial( - phx::ResourcePointer<phx::Material>(material_proxy)); + material_handle->SetMaterial(material); WHEN("We render the scene") { rendering_system->Update(phx::FrameTimer::TimeInfo{}); @@ -145,7 +150,7 @@ SCENARIO("If no material given a default red one is taken.", phx::Entity* triangle = scene->CreateEntity(); CreateTestTriangleComponent(triangle); - phx::Transform* transform = triangle->AddComponent<phx::Transform>(); + triangle->AddComponent<phx::Transform>(); WHEN("We render the scene") { rendering_system->Update(phx::FrameTimer::TimeInfo{}); diff --git a/tests/src/mocks/generation/Create_openGL_mock.py b/tests/src/mocks/generation/Create_openGL_mock.py index db07bbaff7b30f0607b5d2631536020020a8c638..e113d9005ca04a02224e258bb5c6c71d5497de26 100644 --- a/tests/src/mocks/generation/Create_openGL_mock.py +++ b/tests/src/mocks/generation/Create_openGL_mock.py @@ -56,13 +56,13 @@ functions_to_mock =['glClear', 'glEnable', 'glClearColor', 'glCreateProgram', 'g '__glewGetShaderInfoLog', '__glewGetShaderSource', '__glewGetShaderiv', '__glewIsShader', '__glewSpecializeShader', '__glewReleaseShaderCompiler', '__glewShaderBinary', '__glewIsImageHandleResidentARB', '__glewMakeImageHandleNonResidentARB', '__glewMakeImageHandleResidentARB', '__glewIsTextureHandleResidentARB', '__glewMakeTextureHandleNonResidentARB', '__glewMakeTextureHandleResidentARB', '__glewDeleteBuffers', '__glewClearNamedBufferData', '__glewClearNamedBufferSubData','__glewCopyNamedBufferSubData', - '__glewFlushMappedNamedBufferRange', '__glewGetNamedBufferParameteri64v', '__glewGetNamedBufferParameteriv', '__glewGetNamedBufferPointerv', + '__glewFlushMappedNamedBufferRange', '__glewGetNamedBufferParameteri64v', '__glewGetNamedBufferParameteriv', '__glewGetNamedBufferPointerv', 'glViewport', '__glewGetNamedBufferSubData', '__glewMapNamedBuffer', '__glewMapNamedBufferRange', '__glewNamedBufferStorage', '__glewNamedBufferSubData', '__glewUnmapNamedBuffer', '__glewInvalidateBufferData', '__glewInvalidateBufferSubData', '__glewDisableVertexArrayAttrib', '__glewGetVertexArrayIndexed64iv', '__glewGetVertexArrayIndexediv', '__glewGetVertexArrayiv', '__glewVertexArrayAttribBinding', '__glewVertexArrayAttribIFormat', '__glewVertexArrayAttribLFormat', - '__glewVertexArrayBindingDivisor', '__glewDeleteVertexArrays', 'glBindTexture', 'glDeleteTextures', '__glewCreateTextures', '__glewNamedFramebufferTexture', - '__glewTextureStorage2D', '__glewBindFramebuffer', 'glIsTexture', '__glewGetTextureHandleARB', '__glewGenerateTextureMipmap', '__glewTextureParameteri', '__glewTextureSubImage2D', - '__glewBindBufferBase'] + '__glewVertexArrayBindingDivisor', '__glewDeleteVertexArrays', 'glBindTexture', 'glDeleteTextures', '__glewCreateTextures', '__glewNamedFramebufferTexture', + '__glewTextureStorage2D', '__glewBindFramebuffer', 'glIsTexture', '__glewGetTextureHandleARB', '__glewGenerateTextureMipmap', '__glewTextureParameteri', '__glewTextureSubImage2D', + '__glewBindBufferBase', '__glewBindBuffer', '__glewBindBufferRange', '__glewCreateShaderProgramv', 'glDepthRange', '__glewDepthRangef', '__glewDepthRangeIndexed', '__glewViewportIndexedf'] #allow calls you want to provide and not be auto generated allow_calls_provided = ['ALLOW_CALL(open_gl_mock, glewInit()).RETURN(GLEW_OK);', diff --git a/tests/src/mocks/generation/opengl_mock_template.hpp b/tests/src/mocks/generation/opengl_mock_template.hpp index 2c54bd1846058b290f79a2c03b4417ae453f0d33..39396b217d23a480dd6987ec022cc571b39a0751 100644 --- a/tests/src/mocks/generation/opengl_mock_template.hpp +++ b/tests/src/mocks/generation/opengl_mock_template.hpp @@ -34,6 +34,8 @@ #endif #endif +#include "phx/suppress_warnings.hpp" + SUPPRESS_WARNINGS_BEGIN #include "GL/glew.h" SUPPRESS_WARNINGS_END @@ -56,10 +58,13 @@ class OPENGL_MOCK_EXPORT OpenGLMockInternal { class OPENGL_MOCK_EXPORT OpenGLMockWrapper { public: OpenGLMockWrapper() : mock_(new OpenGLMockInternal) {} - // We have to leak the mock_ pointer for the time being. See: - // https://github.com/rollbear/trompeloeil/issues/54#issuecomment-324306089 - // TODO(@tvierjahn) regularly check progress on this issue - ~OpenGLMockWrapper() = default; + OpenGLMockWrapper(const OpenGLMockWrapper&) = delete; + OpenGLMockWrapper(OpenGLMockWrapper&&) = default; + + ~OpenGLMockWrapper() { delete mock_; } + + OpenGLMockWrapper& operator=(const OpenGLMockWrapper&) = delete; + OpenGLMockWrapper& operator=(OpenGLMockWrapper&&) = default; OpenGLMockInternal &Get() { return *mock_; } diff --git a/tests/src/mocks/openvr_mock.cpp b/tests/src/mocks/openvr_mock.cpp index 4b5fc468d4dab28ab2ae9cfed5a9a61a9469457c..31b624134a9ddf3553a816ccd90de5c3352c983c 100644 --- a/tests/src/mocks/openvr_mock.cpp +++ b/tests/src/mocks/openvr_mock.cpp @@ -20,6 +20,8 @@ // limitations under the License. //------------------------------------------------------------------------------ +#include "phx/suppress_warnings.hpp" + SUPPRESS_WARNINGS_BEGIN #include "mocks/openvr_mock.hpp" SUPPRESS_WARNINGS_END diff --git a/tests/src/mocks/openvr_mock.hpp b/tests/src/mocks/openvr_mock.hpp index 77881d7054b6d4a82e1777140ec2b34724e70a8c..83ec13827c371fd43eb7406175ab4393cb5867bd 100644 --- a/tests/src/mocks/openvr_mock.hpp +++ b/tests/src/mocks/openvr_mock.hpp @@ -23,6 +23,10 @@ #ifndef TESTS_SRC_MOCKS_OPENVR_MOCK_HPP_ #define TESTS_SRC_MOCKS_OPENVR_MOCK_HPP_ +#include <string> + +#include "phx/suppress_warnings.hpp" + SUPPRESS_WARNINGS_BEGIN #ifdef OPENVR_MOCK_BUILD #define VR_API_EXPORT @@ -39,11 +43,11 @@ using trompeloeil::_; class OPENVR_MOCK_EXPORT OpenVRMockInternal { public: MAKE_MOCK0(VR_IsHmdPresent, bool()); - MAKE_MOCK2(VR_GetGenericInterface, void *(const char *, vr::EVRInitError *)); - MAKE_MOCK3(VR_InitInternal2, uint32_t(vr::EVRInitError *, - vr::EVRApplicationType, const char *)); + MAKE_MOCK2(VR_GetGenericInterface, void*(const char*, vr::EVRInitError*)); + MAKE_MOCK3(VR_InitInternal2, + uint32_t(vr::EVRInitError*, vr::EVRApplicationType, const char*)); MAKE_MOCK0(VR_ShutdownInternal, void()); - MAKE_MOCK1(VR_IsInterfaceVersionValid, bool(const char *)); + MAKE_MOCK1(VR_IsInterfaceVersionValid, bool(const char*)); MAKE_MOCK0(VR_GetInitToken, uint32_t()); }; @@ -52,31 +56,30 @@ namespace vr { class OPENVR_MOCK_EXPORT IVRSystemMock : public IVRSystem { public: virtual ~IVRSystemMock() = default; - MAKE_MOCK2(GetRecommendedRenderTargetSize, void(uint32_t *, uint32_t *)); - MAKE_MOCK5(GetProjectionRaw, - void(EVREye, float *, float *, float *, float *)); + MAKE_MOCK2(GetRecommendedRenderTargetSize, void(uint32_t*, uint32_t*)); + MAKE_MOCK5(GetProjectionRaw, void(EVREye, float*, float*, float*, float*)); MAKE_MOCK4(ComputeDistortion, - bool(EVREye, float, float, DistortionCoordinates_t *)); - MAKE_MOCK2(GetTimeSinceLastVsync, bool(float *, uint64_t *)); + bool(EVREye, float, float, DistortionCoordinates_t*)); + MAKE_MOCK2(GetTimeSinceLastVsync, bool(float*, uint64_t*)); MAKE_MOCK0(GetD3D9AdapterIndex, int32_t()); - MAKE_MOCK1(GetDXGIOutputInfo, void(int32_t *)); - MAKE_MOCK3(GetOutputDevice, void(uint64_t *, ETextureType, VkInstance_T *)); + MAKE_MOCK1(GetDXGIOutputInfo, void(int32_t*)); + MAKE_MOCK3(GetOutputDevice, void(uint64_t*, ETextureType, VkInstance_T*)); MAKE_MOCK0(IsDisplayOnDesktop, bool()); MAKE_MOCK1(SetDisplayVisibility, bool(bool)); MAKE_MOCK4(GetDeviceToAbsoluteTrackingPose, - void(ETrackingUniverseOrigin, float, TrackedDevicePose_t *, + void(ETrackingUniverseOrigin, float, TrackedDevicePose_t*, uint32_t)); MAKE_MOCK0(ResetSeatedZeroPose, void()); MAKE_MOCK0(GetSeatedZeroPoseToStandingAbsoluteTrackingPose, HmdMatrix34_t()); MAKE_MOCK0(GetRawZeroPoseToStandingAbsoluteTrackingPose, HmdMatrix34_t()); MAKE_MOCK4(GetSortedTrackedDeviceIndicesOfClass, - uint32_t(ETrackedDeviceClass, TrackedDeviceIndex_t *, uint32_t, + uint32_t(ETrackedDeviceClass, TrackedDeviceIndex_t*, uint32_t, TrackedDeviceIndex_t)); MAKE_MOCK1(GetTrackedDeviceActivityLevel, EDeviceActivityLevel(TrackedDeviceIndex_t)); MAKE_MOCK3(ApplyTransform, - void(TrackedDevicePose_t *, const TrackedDevicePose_t *, - const HmdMatrix34_t *)); + void(TrackedDevicePose_t*, const TrackedDevicePose_t*, + const HmdMatrix34_t*)); MAKE_MOCK1(GetTrackedDeviceIndexForControllerRole, TrackedDeviceIndex_t(vr::ETrackedControllerRole)); MAKE_MOCK1(GetControllerRoleForTrackedDeviceIndex, @@ -86,43 +89,43 @@ class OPENVR_MOCK_EXPORT IVRSystemMock : public IVRSystem { MAKE_MOCK1(IsTrackedDeviceConnected, bool(vr::TrackedDeviceIndex_t)); MAKE_MOCK3(GetBoolTrackedDeviceProperty, bool(vr::TrackedDeviceIndex_t, ETrackedDeviceProperty, - ETrackedPropertyError *)); + ETrackedPropertyError*)); MAKE_MOCK3(GetFloatTrackedDeviceProperty, float(vr::TrackedDeviceIndex_t, ETrackedDeviceProperty, - ETrackedPropertyError *)); + ETrackedPropertyError*)); MAKE_MOCK3(GetInt32TrackedDeviceProperty, int32_t(vr::TrackedDeviceIndex_t, ETrackedDeviceProperty, - ETrackedPropertyError *)); + ETrackedPropertyError*)); MAKE_MOCK3(GetUint64TrackedDeviceProperty, uint64_t(vr::TrackedDeviceIndex_t, ETrackedDeviceProperty, - ETrackedPropertyError *)); + ETrackedPropertyError*)); MAKE_MOCK3(GetMatrix34TrackedDeviceProperty, HmdMatrix34_t(vr::TrackedDeviceIndex_t, ETrackedDeviceProperty, - ETrackedPropertyError *)); + ETrackedPropertyError*)); MAKE_MOCK5(GetStringTrackedDeviceProperty, - uint32_t(vr::TrackedDeviceIndex_t, ETrackedDeviceProperty, char *, - uint32_t, ETrackedPropertyError *)); - MAKE_MOCK1(GetPropErrorNameFromEnum, const char *(ETrackedPropertyError)); - MAKE_MOCK2(PollNextEvent, bool(VREvent_t *, uint32_t)); - MAKE_MOCK4(PollNextEventWithPose, bool(ETrackingUniverseOrigin, VREvent_t *, - uint32_t, vr::TrackedDevicePose_t *)); - MAKE_MOCK1(GetEventTypeNameFromEnum, const char *(EVREventType)); + uint32_t(vr::TrackedDeviceIndex_t, ETrackedDeviceProperty, char*, + uint32_t, ETrackedPropertyError*)); + MAKE_MOCK1(GetPropErrorNameFromEnum, const char*(ETrackedPropertyError)); + MAKE_MOCK2(PollNextEvent, bool(VREvent_t*, uint32_t)); + MAKE_MOCK4(PollNextEventWithPose, bool(ETrackingUniverseOrigin, VREvent_t*, + uint32_t, vr::TrackedDevicePose_t*)); + MAKE_MOCK1(GetEventTypeNameFromEnum, const char*(EVREventType)); MAKE_MOCK2(GetHiddenAreaMesh, HiddenAreaMesh_t(EVREye, EHiddenAreaMeshType)); MAKE_MOCK3(GetControllerState, bool(vr::TrackedDeviceIndex_t, - vr::VRControllerState_t *, uint32_t)); + vr::VRControllerState_t*, uint32_t)); MAKE_MOCK5(GetControllerStateWithPose, bool(ETrackingUniverseOrigin, vr::TrackedDeviceIndex_t, - vr::VRControllerState_t *, uint32_t, TrackedDevicePose_t *)); + vr::VRControllerState_t*, uint32_t, TrackedDevicePose_t*)); MAKE_MOCK3(TriggerHapticPulse, void(vr::TrackedDeviceIndex_t, uint32_t, unsigned short)); - MAKE_MOCK1(GetButtonIdNameFromEnum, const char *(EVRButtonId)); + MAKE_MOCK1(GetButtonIdNameFromEnum, const char*(EVRButtonId)); MAKE_MOCK1(GetControllerAxisTypeNameFromEnum, - const char *(EVRControllerAxisType)); + const char*(EVRControllerAxisType)); MAKE_MOCK0(CaptureInputFocus, bool()); MAKE_MOCK0(ReleaseInputFocus, void()); MAKE_MOCK0(IsInputFocusCapturedByAnotherProcess, bool()); - MAKE_MOCK4(DriverDebugRequest, uint32_t(vr::TrackedDeviceIndex_t, - const char *, char *, uint32_t)); + MAKE_MOCK4(DriverDebugRequest, + uint32_t(vr::TrackedDeviceIndex_t, const char*, char*, uint32_t)); MAKE_MOCK1(PerformFirmwareUpdate, vr::EVRFirmwareError(vr::TrackedDeviceIndex_t)); MAKE_MOCK0(AcknowledgeQuit_Exiting, void()); @@ -131,38 +134,46 @@ class OPENVR_MOCK_EXPORT IVRSystemMock : public IVRSystem { // somehow returning structs is a problem, so this workaround // TODO(WJ): should be reworked once this is solved in trompeloeil // https://github.com/rollbear/trompeloeil/issues/69 - MAKE_MOCK3(GetProjectionMatrixArray, float *(vr::EVREye, float, float)); + MAKE_MOCK3(GetProjectionMatrixArray, float*(vr::EVREye, float, float)); vr::HmdMatrix44_t GetProjectionMatrix(vr::EVREye, float, float); - MAKE_MOCK1(GetEyeToHeadTransformArray, float *(EVREye)); + MAKE_MOCK1(GetEyeToHeadTransformArray, float*(EVREye)); HmdMatrix34_t GetEyeToHeadTransform(EVREye); + MAKE_MOCK6(GetArrayTrackedDeviceProperty, + uint32_t(vr::TrackedDeviceIndex_t, ETrackedDeviceProperty, + PropertyTypeTag_t, void*, uint32_t, + ETrackedPropertyError*)); + MAKE_MOCK0(IsInputAvailable, bool()); + MAKE_MOCK0(IsSteamVRDrawingControllers, bool()); + MAKE_MOCK0(ShouldApplicationPause, bool()); + MAKE_MOCK0(ShouldApplicationReduceRenderingWork, bool()); }; class OPENVR_MOCK_EXPORT IVRCompositorMock : public IVRCompositor { public: + virtual ~IVRCompositorMock() = default; MAKE_MOCK1(SetTrackingSpace, void(ETrackingUniverseOrigin)); MAKE_MOCK0(GetTrackingSpace, ETrackingUniverseOrigin()); - MAKE_MOCK4(WaitGetPoses, EVRCompositorError(TrackedDevicePose_t *, uint32_t, - TrackedDevicePose_t *, uint32_t)); - MAKE_MOCK4(GetLastPoses, EVRCompositorError(TrackedDevicePose_t *, uint32_t, - TrackedDevicePose_t *, uint32_t)); + MAKE_MOCK4(WaitGetPoses, EVRCompositorError(TrackedDevicePose_t*, uint32_t, + TrackedDevicePose_t*, uint32_t)); + MAKE_MOCK4(GetLastPoses, EVRCompositorError(TrackedDevicePose_t*, uint32_t, + TrackedDevicePose_t*, uint32_t)); MAKE_MOCK3(GetLastPoseForTrackedDeviceIndex, - EVRCompositorError(TrackedDeviceIndex_t, TrackedDevicePose_t *, - TrackedDevicePose_t *)); + EVRCompositorError(TrackedDeviceIndex_t, TrackedDevicePose_t*, + TrackedDevicePose_t*)); MAKE_MOCK4(Submit, - EVRCompositorError(EVREye, const Texture_t *, - const VRTextureBounds_t *, EVRSubmitFlags)); + EVRCompositorError(EVREye, const Texture_t*, + const VRTextureBounds_t*, EVRSubmitFlags)); MAKE_MOCK0(ClearLastSubmittedFrame, void()); MAKE_MOCK0(PostPresentHandoff, void()); - MAKE_MOCK2(GetFrameTiming, bool(Compositor_FrameTiming *, uint32_t)); - MAKE_MOCK2(GetFrameTimings, uint32_t(Compositor_FrameTiming *, uint32_t)); + MAKE_MOCK2(GetFrameTiming, bool(Compositor_FrameTiming*, uint32_t)); + MAKE_MOCK2(GetFrameTimings, uint32_t(Compositor_FrameTiming*, uint32_t)); MAKE_MOCK0(GetFrameTimeRemaining, float()); - MAKE_MOCK2(GetCumulativeStats, void(Compositor_CumulativeStats *, uint32_t)); + MAKE_MOCK2(GetCumulativeStats, void(Compositor_CumulativeStats*, uint32_t)); MAKE_MOCK6(FadeToColor, void(float, float, float, float, float, bool)); MAKE_MOCK1(GetCurrentFadeColor, HmdColor_t(bool)); MAKE_MOCK2(FadeGrid, void(float, bool)); MAKE_MOCK0(GetCurrentGridAlpha, float()); - MAKE_MOCK2(SetSkyboxOverride, - EVRCompositorError(const Texture_t *, uint32_t)); + MAKE_MOCK2(SetSkyboxOverride, EVRCompositorError(const Texture_t*, uint32_t)); MAKE_MOCK0(ClearSkyboxOverride, void()); MAKE_MOCK0(CompositorBringToFront, void()); MAKE_MOCK0(CompositorGoToBack, void()); @@ -180,64 +191,68 @@ class OPENVR_MOCK_EXPORT IVRCompositorMock : public IVRCompositor { MAKE_MOCK0(ForceReconnectProcess, void()); MAKE_MOCK1(SuspendRendering, void(bool)); MAKE_MOCK3(GetMirrorTextureD3D11, - EVRCompositorError(vr::EVREye, void *, void **)); - MAKE_MOCK1(ReleaseMirrorTextureD3D11, void(void *)); + EVRCompositorError(vr::EVREye, void*, void**)); + MAKE_MOCK1(ReleaseMirrorTextureD3D11, void(void*)); MAKE_MOCK3(GetMirrorTextureGL, - vr::EVRCompositorError(vr::EVREye, vr::glUInt_t *, - vr::glSharedTextureHandle_t *)); + vr::EVRCompositorError(vr::EVREye, vr::glUInt_t*, + vr::glSharedTextureHandle_t*)); MAKE_MOCK2(ReleaseSharedGLTexture, bool(vr::glUInt_t, vr::glSharedTextureHandle_t)); MAKE_MOCK1(LockGLSharedTextureForAccess, void(vr::glSharedTextureHandle_t)); MAKE_MOCK1(UnlockGLSharedTextureForAccess, void(vr::glSharedTextureHandle_t)); - MAKE_MOCK2(GetVulkanInstanceExtensionsRequired, uint32_t(char *, uint32_t)); + MAKE_MOCK2(GetVulkanInstanceExtensionsRequired, uint32_t(char*, uint32_t)); MAKE_MOCK3(GetVulkanDeviceExtensionsRequired, - uint32_t(VkPhysicalDevice_T *, char *, uint32_t)); + uint32_t(VkPhysicalDevice_T*, char*, uint32_t)); MAKE_MOCK1(SetExplicitTimingMode, void(bool)); MAKE_MOCK0(SubmitExplicitTimingData, EVRCompositorError()); + MAKE_MOCK1(SetExplicitTimingMode, void(EVRCompositorTimingMode)); }; class OPENVR_MOCK_EXPORT IVRRenderModelsMock : public IVRRenderModels { public: + virtual ~IVRRenderModelsMock() = default; MAKE_MOCK2(LoadRenderModel_Async, - EVRRenderModelError(const char *, RenderModel_t **)); - MAKE_MOCK1(FreeRenderModel, void(RenderModel_t *)); + EVRRenderModelError(const char*, RenderModel_t**)); + MAKE_MOCK1(FreeRenderModel, void(RenderModel_t*)); MAKE_MOCK2(LoadTexture_Async, - EVRRenderModelError(TextureID_t, RenderModel_TextureMap_t **)); - MAKE_MOCK1(FreeTexture, void(RenderModel_TextureMap_t *)); + EVRRenderModelError(TextureID_t, RenderModel_TextureMap_t**)); + MAKE_MOCK1(FreeTexture, void(RenderModel_TextureMap_t*)); MAKE_MOCK3(LoadTextureD3D11_Async, - EVRRenderModelError(TextureID_t, void *, void **)); + EVRRenderModelError(TextureID_t, void*, void**)); MAKE_MOCK2(LoadIntoTextureD3D11_Async, - EVRRenderModelError(TextureID_t, void *)); - MAKE_MOCK1(FreeTextureD3D11, void(void *)); + EVRRenderModelError(TextureID_t, void*)); + MAKE_MOCK1(FreeTextureD3D11, void(void*)); MAKE_MOCK3(GetRenderModelName, - uint32_t(uint32_t, VR_OUT_STRING() char *, uint32_t)); + uint32_t(uint32_t, VR_OUT_STRING() char*, uint32_t)); MAKE_MOCK0(GetRenderModelCount, uint32_t()); - MAKE_MOCK1(GetComponentCount, uint32_t(const char *)); - MAKE_MOCK4(GetComponentName, uint32_t(const char *, uint32_t, - VR_OUT_STRING() char *, uint32_t)); + MAKE_MOCK1(GetComponentCount, uint32_t(const char*)); + MAKE_MOCK4(GetComponentName, + uint32_t(const char*, uint32_t, VR_OUT_STRING() char*, uint32_t)); - MAKE_MOCK2(GetComponentButtonMask, uint64_t(const char *, const char *)); + MAKE_MOCK2(GetComponentButtonMask, uint64_t(const char*, const char*)); MAKE_MOCK4(GetComponentRenderModelName, - uint32_t(const char *, const char *, VR_OUT_STRING() char *, + uint32_t(const char*, const char*, VR_OUT_STRING() char*, uint32_t)); MAKE_MOCK5(GetComponentState, - bool(const char *, const char *, const vr::VRControllerState_t *, - const RenderModel_ControllerMode_State_t *, - RenderModel_ComponentState_t *)); + bool(const char*, const char*, const vr::VRControllerState_t*, + const RenderModel_ControllerMode_State_t*, + RenderModel_ComponentState_t*)); - MAKE_MOCK2(RenderModelHasComponent, bool(const char *, const char *)); + MAKE_MOCK2(RenderModelHasComponent, bool(const char*, const char*)); MAKE_MOCK4(GetRenderModelThumbnailURL, - uint32_t(const char *, VR_OUT_STRING() char *, uint32_t, - vr::EVRRenderModelError *)); + uint32_t(const char*, VR_OUT_STRING() char*, uint32_t, + vr::EVRRenderModelError*)); MAKE_MOCK4(GetRenderModelOriginalPath, - uint32_t(const char *, VR_OUT_STRING() char *, uint32_t, - vr::EVRRenderModelError *)); + uint32_t(const char*, VR_OUT_STRING() char*, uint32_t, + vr::EVRRenderModelError*)); MAKE_MOCK1(GetRenderModelErrorNameFromEnum, - const char *(vr::EVRRenderModelError)); + const char*(vr::EVRRenderModelError)); }; } // namespace vr +SUPPRESS_WARNINGS_BEGIN_PADDED + class OPENVR_MOCK_EXPORT OpenVRMock { public: OpenVRMock() @@ -245,50 +260,71 @@ class OPENVR_MOCK_EXPORT OpenVRMock { ivr_system_mock_(new vr::IVRSystemMock), ivr_compositor_mock_(new vr::IVRCompositorMock), ivr_render_models_mock_(new vr::IVRRenderModelsMock) {} + OpenVRMock(const OpenVRMock&) = delete; + OpenVRMock(OpenVRMock&&) = default; ~OpenVRMock() { - // We have to leak the mock_ pointer for the time being. - // see - // https://github.com/rollbear/trompeloeil/issues/54#issuecomment-324306089 - // TODO(@tvierjahn) regularly check progress on this issue + delete mock_; + delete ivr_system_mock_; + delete ivr_compositor_mock_; + delete ivr_render_models_mock_; } - OpenVRMockInternal &Get() { return *mock_; } - vr::IVRSystemMock &GetSystem() const { return *ivr_system_mock_; } - vr::IVRCompositorMock &GetCompositor() { return *ivr_compositor_mock_; } - vr::IVRRenderModelsMock &GetRenderModels() { + OpenVRMock& operator=(const OpenVRMock&) = delete; + OpenVRMock& operator=(OpenVRMock&&) = default; + + OpenVRMockInternal& Get() { return *mock_; } + vr::IVRSystemMock& GetSystem() const { return *ivr_system_mock_; } + vr::IVRCompositorMock& GetCompositor() { return *ivr_compositor_mock_; } + vr::IVRRenderModelsMock& GetRenderModels() { return *ivr_render_models_mock_; } - static vr::RenderModel_t *CreateDummyTriangleModel() { - vr::RenderModel_t *model = new vr::RenderModel_t(); - model->rIndexData = new uint16_t[3]{0, 1, 2}; + vr::RenderModel_t* CreateDummyTriangleModel(unsigned int id) { + vr::RenderModel_t* model = new vr::RenderModel_t(); + + model->rIndexData = &model_indices_[0]; model->unVertexCount = 3; model->unTriangleCount = 1; - model->diffuseTextureId = -1; + model->diffuseTextureId = static_cast<int>(id); + + model_vertices_[0].vPosition = {{-0.1f, -0.1f, 0.f}}; + model_vertices_[0].vNormal = {{0.f, 0.f, 1.f}}; + model_vertices_[0].rfTextureCoord[0] = 0.f; + model_vertices_[0].rfTextureCoord[1] = 0.f; - vr::RenderModel_Vertex_t vertex1; - vertex1.vPosition = {{-0.1f, -0.1f, 0.f}}; - vertex1.vNormal = {{0.f, 0.f, 1.f}}; - vertex1.rfTextureCoord[0] = 0.f; - vertex1.rfTextureCoord[1] = 0.f; - vr::RenderModel_Vertex_t vertex2 = vertex1; - vertex2.vPosition = {{+0.1f, -0.1f, 0.f}}; - vr::RenderModel_Vertex_t vertex3 = vertex1; - vertex2.vPosition = {{0.f, +0.1f, 0.f}}; + model_vertices_[1].vPosition = {{+0.1f, -0.1f, 0.f}}; + model_vertices_[1].vNormal = {{0.f, 0.f, 1.f}}; + model_vertices_[1].rfTextureCoord[0] = 1.f; + model_vertices_[1].rfTextureCoord[1] = 0.f; - model->rVertexData = - new vr::RenderModel_Vertex_t[3]{vertex1, vertex2, vertex3}; + model_vertices_[2].vPosition = {{0.f, +0.1f, 0.f}}; + model_vertices_[2].vNormal = {{0.f, 0.f, 1.f}}; + model_vertices_[2].rfTextureCoord[0] = 0.5f; + model_vertices_[2].rfTextureCoord[1] = 1.f; + + model->rVertexData = &model_vertices_[0]; return model; } + vr::RenderModel_TextureMap_t* CreateDummyTexture(unsigned int id) { + vr::RenderModel_TextureMap_t* texture = new vr::RenderModel_TextureMap_t(); + texture->unHeight = 1u; + texture->unWidth = 1u; + if (id == 1u) + texture->rubTextureMapData = &green_pixel_[0]; + else + texture->rubTextureMapData = &blue_pixel_[0]; + return texture; + } + static vr::HmdMatrix44_t toHMDMatrix44_t(float mat[16]); static vr::HmdMatrix34_t toHMDMatrix34_t(float mat[12]); // Matrix4x4 - float projection_matrix_[16] = {1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, - 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, - 0.0f, 0.0f, 0.0f, 1.0f}; + float projection_matrix_[16] = {1.483f, 0.0f, 0.0f, 0.0f, 0.0f, 1.483f, + 0.0f, 0.0f, 0.0f, 0.0f, -1.0f, -0.02f, + 0.0f, 0.0f, -1.0f, 0.0f}; // Matrix 3x4 float eye_to_head_left_[12] = {1.0f, 0.0f, 0.0f, 0.03f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f}; @@ -296,72 +332,125 @@ class OPENVR_MOCK_EXPORT OpenVRMock { 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f}; float head_transformation_[12] = {1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.8f, 0.0f, 0.0f, 1.0f, 0.0f}; + float l_cont_transformation_[12] = {1.0f, 0.0f, 0.0f, -0.2f, 0.0f, 1.0f, + 0.0f, 1.6f, 0.0f, 0.0f, 1.0f, -0.6f}; + float r_cont_transformation_[12] = {1.0f, 0.0f, 0.0f, 0.2f, 0.0f, 1.0f, + 0.0f, 1.6f, 0.0f, 0.0f, 1.0f, -0.6f}; + + unsigned int index_right_controller_ = 1u; + unsigned int index_left_controller_ = 2u; + + char name_left_controller_[vr::k_unMaxPropertyStringSize] = "controller_left"; + char name_right_controller_[vr::k_unMaxPropertyStringSize] = + "controller_right"; + + uint8_t green_pixel_[4] = {0, 255, 0, 255}; + uint8_t blue_pixel_[4] = {0, 0, 255, 255}; + + uint16_t model_indices_[3] = {0, 1, 2}; + vr::RenderModel_Vertex_t model_vertices_[3]; private: - OpenVRMockInternal *mock_; - vr::IVRSystemMock *ivr_system_mock_; - vr::IVRCompositorMock *ivr_compositor_mock_; - vr::IVRRenderModelsMock *ivr_render_models_mock_; + OpenVRMockInternal* mock_; + vr::IVRSystemMock* ivr_system_mock_; + vr::IVRCompositorMock* ivr_compositor_mock_; + vr::IVRRenderModelsMock* ivr_render_models_mock_; }; +SUPPRESS_WARNINGS_END + extern OPENVR_MOCK_EXPORT OpenVRMock openvr_mock; -#define OPENVR_MOCK_ALLOW_ANY_CALL \ - ALLOW_CALL(openvr_mock.Get(), VR_IsHmdPresent()).RETURN(true); \ - ALLOW_CALL(openvr_mock.GetSystem(), GetRecommendedRenderTargetSize(_, _)) \ - .SIDE_EFFECT(*_1 = 100) \ - .SIDE_EFFECT(*_2 = 100); \ - ALLOW_CALL(openvr_mock.GetSystem(), GetProjectionMatrixArray(_, _, _)) \ - .RETURN(openvr_mock.projection_matrix_); \ - ALLOW_CALL(openvr_mock.GetSystem(), \ - GetEyeToHeadTransformArray(vr::EVREye::Eye_Left)) \ - .RETURN(openvr_mock.eye_to_head_left_); \ - ALLOW_CALL(openvr_mock.GetSystem(), \ - GetEyeToHeadTransformArray(vr::EVREye::Eye_Right)) \ - .RETURN(openvr_mock.eye_to_head_right_); \ - ALLOW_CALL(openvr_mock.GetSystem(), \ - GetSortedTrackedDeviceIndicesOfClass(_, _, _, _)) \ - .RETURN(2u) \ - .SIDE_EFFECT(*_2 = 0u) \ - .SIDE_EFFECT(*(_2 + sizeof(vr::TrackedDeviceIndex_t)) = 1u); \ - ALLOW_CALL(openvr_mock.GetSystem(), \ - GetControllerRoleForTrackedDeviceIndex(0u)) \ - .RETURN(vr::TrackedControllerRole_LeftHand); \ - ALLOW_CALL(openvr_mock.GetSystem(), \ - GetControllerRoleForTrackedDeviceIndex(1u)) \ - .RETURN(vr::TrackedControllerRole_RightHand); \ - ALLOW_CALL(openvr_mock.GetCompositor(), WaitGetPoses(_, _, _, _)) \ - .RETURN(vr::EVRCompositorError::VRCompositorError_None) \ - .SIDE_EFFECT( \ - _1[vr::k_unTrackedDeviceIndex_Hmd].mDeviceToAbsoluteTracking = \ - OpenVRMock::toHMDMatrix34_t(openvr_mock.head_transformation_)) \ - .SIDE_EFFECT(_1[vr::k_unTrackedDeviceIndex_Hmd].bPoseIsValid = true); \ - ALLOW_CALL(openvr_mock.GetCompositor(), Submit(_, _, _, _)) \ - .RETURN(vr::EVRCompositorError::VRCompositorError_None); \ - ALLOW_CALL(openvr_mock.Get(), VR_GetGenericInterface(_, _)) \ - .WITH(std::string(vr::IVRSystem_Version) == std::string(_1)) \ - .RETURN(static_cast<void *>(&openvr_mock.GetSystem())); \ - ALLOW_CALL(openvr_mock.Get(), VR_GetGenericInterface(_, _)) \ - .WITH(std::string(vr::IVRRenderModels_Version) == std::string(_1)) \ - .RETURN(static_cast<void *>(&openvr_mock.GetRenderModels())); \ - ALLOW_CALL(openvr_mock.Get(), VR_GetGenericInterface(_, _)) \ - .WITH(std::string(vr::IVRCompositor_Version) == std::string(_1)) \ - .RETURN(static_cast<void *>(&openvr_mock.GetCompositor())); \ - ALLOW_CALL(openvr_mock.Get(), \ - VR_InitInternal2(_, vr::VRApplication_Scene, _)) \ - .RETURN(static_cast<uint32_t>(1337)) \ - .SIDE_EFFECT(*_1 = vr::VRInitError_None); \ - ALLOW_CALL(openvr_mock.Get(), VR_ShutdownInternal()); \ - ALLOW_CALL(openvr_mock.Get(), VR_IsInterfaceVersionValid(_)).RETURN(true); \ - ALLOW_CALL(openvr_mock.Get(), VR_GetInitToken()).RETURN(1337); \ - ALLOW_CALL(openvr_mock.GetRenderModels(), LoadRenderModel_Async(_, _)) \ - .RETURN(vr::VRRenderModelError_None) \ - .SIDE_EFFECT(*_2 = openvr_mock.CreateDummyTriangleModel()); \ - ALLOW_CALL(openvr_mock.GetSystem(), \ - GetStringTrackedDeviceProperty(_, _, _, _, _)) \ - .RETURN(0); \ - ALLOW_CALL(openvr_mock.GetRenderModels(), LoadTexture_Async(_, _)) \ - .RETURN(vr::VRRenderModelError_None) \ - .SIDE_EFFECT(*_2 = nullptr); +#define OPENVR_MOCK_ALLOW_ANY_CALL \ + ALLOW_CALL(openvr_mock.Get(), VR_IsHmdPresent()).RETURN(true); \ + ALLOW_CALL(openvr_mock.GetSystem(), GetRecommendedRenderTargetSize(_, _)) \ + .SIDE_EFFECT(*_1 = 1000) \ + .SIDE_EFFECT(*_2 = 1000); \ + ALLOW_CALL(openvr_mock.GetSystem(), GetProjectionMatrixArray(_, _, _)) \ + .RETURN(openvr_mock.projection_matrix_); \ + ALLOW_CALL(openvr_mock.GetSystem(), \ + GetEyeToHeadTransformArray(vr::EVREye::Eye_Left)) \ + .RETURN(openvr_mock.eye_to_head_left_); \ + ALLOW_CALL(openvr_mock.GetSystem(), \ + GetEyeToHeadTransformArray(vr::EVREye::Eye_Right)) \ + .RETURN(openvr_mock.eye_to_head_right_); \ + ALLOW_CALL(openvr_mock.GetSystem(), \ + GetSortedTrackedDeviceIndicesOfClass(_, _, _, _)) \ + .RETURN(2u) \ + .SIDE_EFFECT(*_2 = openvr_mock.index_right_controller_) \ + .SIDE_EFFECT(*(_2 + 1) = openvr_mock.index_left_controller_); \ + ALLOW_CALL(openvr_mock.GetSystem(), GetControllerRoleForTrackedDeviceIndex( \ + openvr_mock.index_left_controller_)) \ + .RETURN(vr::TrackedControllerRole_LeftHand); \ + ALLOW_CALL(openvr_mock.GetSystem(), \ + GetControllerRoleForTrackedDeviceIndex( \ + openvr_mock.index_right_controller_)) \ + .RETURN(vr::TrackedControllerRole_RightHand); \ + ALLOW_CALL(openvr_mock.GetSystem(), GetControllerRoleForTrackedDeviceIndex( \ + vr::k_unTrackedDeviceIndex_Hmd)) \ + .RETURN(vr::TrackedControllerRole_Invalid); \ + ALLOW_CALL(openvr_mock.GetCompositor(), WaitGetPoses(_, _, _, _)) \ + .RETURN(vr::EVRCompositorError::VRCompositorError_None) \ + .SIDE_EFFECT( \ + _1[vr::k_unTrackedDeviceIndex_Hmd].mDeviceToAbsoluteTracking = \ + OpenVRMock::toHMDMatrix34_t(openvr_mock.head_transformation_)) \ + .SIDE_EFFECT(_1[vr::k_unTrackedDeviceIndex_Hmd].bPoseIsValid = true) \ + .SIDE_EFFECT( \ + _1[openvr_mock.index_right_controller_].mDeviceToAbsoluteTracking = \ + OpenVRMock::toHMDMatrix34_t(openvr_mock.r_cont_transformation_)) \ + .SIDE_EFFECT(_1[openvr_mock.index_right_controller_].bPoseIsValid = \ + true) \ + .SIDE_EFFECT( \ + _1[openvr_mock.index_left_controller_].mDeviceToAbsoluteTracking = \ + OpenVRMock::toHMDMatrix34_t(openvr_mock.l_cont_transformation_)) \ + .SIDE_EFFECT(_1[openvr_mock.index_left_controller_].bPoseIsValid = \ + true); \ + ALLOW_CALL(openvr_mock.GetCompositor(), Submit(_, _, _, _)) \ + .RETURN(vr::EVRCompositorError::VRCompositorError_None); \ + ALLOW_CALL(openvr_mock.Get(), VR_GetGenericInterface(_, _)) \ + .WITH(std::string(vr::IVRSystem_Version) == std::string(_1)) \ + .RETURN(static_cast<void*>(&openvr_mock.GetSystem())); \ + ALLOW_CALL(openvr_mock.Get(), VR_GetGenericInterface(_, _)) \ + .WITH(std::string(vr::IVRRenderModels_Version) == std::string(_1)) \ + .RETURN(static_cast<void*>(&openvr_mock.GetRenderModels())); \ + ALLOW_CALL(openvr_mock.Get(), VR_GetGenericInterface(_, _)) \ + .WITH(std::string(vr::IVRCompositor_Version) == std::string(_1)) \ + .RETURN(static_cast<void*>(&openvr_mock.GetCompositor())); \ + ALLOW_CALL(openvr_mock.Get(), \ + VR_InitInternal2(_, vr::VRApplication_Scene, _)) \ + .RETURN(static_cast<uint32_t>(1337)) \ + .SIDE_EFFECT(*_1 = vr::VRInitError_None); \ + ALLOW_CALL(openvr_mock.Get(), VR_ShutdownInternal()); \ + ALLOW_CALL(openvr_mock.Get(), VR_IsInterfaceVersionValid(_)).RETURN(true); \ + ALLOW_CALL(openvr_mock.Get(), VR_GetInitToken()).RETURN(1337); \ + ALLOW_CALL(openvr_mock.GetRenderModels(), LoadRenderModel_Async(_, _)) \ + .WITH(std::string(_1) == std::string(openvr_mock.name_left_controller_)) \ + .SIDE_EFFECT(*_2 = openvr_mock.CreateDummyTriangleModel( \ + openvr_mock.index_left_controller_)) \ + .RETURN(vr::VRRenderModelError_None); \ + ALLOW_CALL(openvr_mock.GetRenderModels(), LoadRenderModel_Async(_, _)) \ + .WITH(std::string(_1) == \ + std::string(openvr_mock.name_right_controller_)) \ + .SIDE_EFFECT(*_2 = openvr_mock.CreateDummyTriangleModel( \ + openvr_mock.index_right_controller_)) \ + .RETURN(vr::VRRenderModelError_None); \ + ALLOW_CALL(openvr_mock.GetSystem(), \ + GetStringTrackedDeviceProperty( \ + openvr_mock.index_left_controller_, \ + vr::Prop_RenderModelName_String, _, _, _)) \ + .SIDE_EFFECT(std::string(openvr_mock.name_left_controller_) \ + .copy(_3, vr::k_unMaxPropertyStringSize)) \ + .RETURN(vr::k_unMaxPropertyStringSize); \ + ALLOW_CALL(openvr_mock.GetSystem(), \ + GetStringTrackedDeviceProperty( \ + openvr_mock.index_right_controller_, \ + vr::Prop_RenderModelName_String, _, _, _)) \ + .SIDE_EFFECT(std::string(openvr_mock.name_right_controller_) \ + .copy(_3, vr::k_unMaxPropertyStringSize)) \ + .RETURN(vr::k_unMaxPropertyStringSize); \ + ALLOW_CALL(openvr_mock.GetRenderModels(), LoadTexture_Async(_, _)) \ + .RETURN(vr::VRRenderModelError_None) \ + .SIDE_EFFECT(*_2 = openvr_mock.CreateDummyTexture( \ + static_cast<unsigned int>(_1))); #endif // TESTS_SRC_MOCKS_OPENVR_MOCK_HPP_ diff --git a/tests/src/mocks/sdl_mock.hpp b/tests/src/mocks/sdl_mock.hpp index 3faddfd628ae9facd6a4096e641a865ff89dd94d..c9146b5dda4c69339f0b10366da6f80b37acba15 100644 --- a/tests/src/mocks/sdl_mock.hpp +++ b/tests/src/mocks/sdl_mock.hpp @@ -23,6 +23,8 @@ #ifndef TESTS_SRC_MOCKS_SDL_MOCK_HPP_ #define TESTS_SRC_MOCKS_SDL_MOCK_HPP_ +#include "phx/suppress_warnings.hpp" + SUPPRESS_WARNINGS_BEGIN #include "SDL.h" SUPPRESS_WARNINGS_END @@ -56,12 +58,13 @@ class SdlMockInternal { class SdlMock { public: SdlMock() : mock_(new SdlMockInternal) {} - ~SdlMock() { - // We have to leak the mock_ pointer for the time being. - // see - // https://github.com/rollbear/trompeloeil/issues/54#issuecomment-324306089 - // TODO(@tvierjahn) regularly check progress on this issue - } + SdlMock(const SdlMock&) = delete; + SdlMock(SdlMock&&) = default; + + ~SdlMock() { delete mock_; } + + SdlMock& operator=(const SdlMock&) = delete; + SdlMock& operator=(SdlMock&&) = default; SdlMockInternal& Get() { return *mock_; } diff --git a/tests/src/test-phoenix.cpp b/tests/src/test-phoenix.cpp index 282bba566a816573880a11d4ce23ca98e8765e60..e94c6c5a983d7060a60ef133f3d497c3fbd295aa 100644 --- a/tests/src/test-phoenix.cpp +++ b/tests/src/test-phoenix.cpp @@ -23,7 +23,3 @@ #include "catch/catch.hpp" #include "phx/phoenix.hpp" - -TEST_CASE("Project Phoenix shall greet.", "[phx]") { - CHECK(phx::Greet() == "Hello world!"); -} diff --git a/tests/src/test-transform.cpp b/tests/src/test-transform.cpp index f9cc4cd768ca728876390516071144d790209032..a02f86e2635ce824d1efe520fe8154d30c34688f 100644 --- a/tests/src/test-transform.cpp +++ b/tests/src/test-transform.cpp @@ -26,6 +26,8 @@ #include "catch/catch.hpp" +#include "phx/suppress_warnings.hpp" + SUPPRESS_WARNINGS_BEGIN #include "glm/glm.hpp" SUPPRESS_WARNINGS_END @@ -300,7 +302,8 @@ SCENARIO( WHEN("We iterate the second transform's children.") { auto iteration_count = 0; - for (auto& current : *parent) iteration_count++; + for (auto it = parent->begin(); it != parent->end(); ++it) + iteration_count++; THEN("It should consist of a single iteration.") { REQUIRE(iteration_count == 1); } diff --git a/tests/src/test_assimp_loader.cpp b/tests/src/test_assimp_loader.cpp index 1855a8b7361992e9c8e559e232e8e263b12960b7..613ee4564563aabd2ea0de4c3045d8f82841d29d 100644 --- a/tests/src/test_assimp_loader.cpp +++ b/tests/src/test_assimp_loader.cpp @@ -29,7 +29,7 @@ #include "phx/assimp_model_loader.hpp" #include "phx/logger.hpp" #include "phx/mesh.hpp" -#include "phx/resource_proxy.hpp" +#include "phx/nameable.hpp" #include "phx/resource_utils.hpp" #include "test_utilities/log_capture.hpp" @@ -54,7 +54,7 @@ SCENARIO("The assimp loader loads models using the Assimp library.", TestLogger test_logger; WHEN("We load an invalid file") { - phx::ResourceUtils::LoadResourceFromFile<phx::Mesh>("invalid.obj"); + phx::ResourceUtils::LoadResourceFromFile<phx::Model>("invalid.obj"); THEN("We get an error message printed to the console.") { std::string captured_message = test_logger.GetCapture()->ToString(); @@ -65,9 +65,9 @@ SCENARIO("The assimp loader loads models using the Assimp library.", } } WHEN("We load the stanford bunny.") { - auto resource = phx::ResourceUtils::LoadResourceFromFile<phx::Mesh>( - "models/bunny.obj", {{"mesh_index", 0}}); - auto mesh = resource.Get(); + auto resource = phx::ResourceUtils::LoadResourceFromFile<phx::Model>( + "models/bunny.obj"); + auto mesh = resource->GetMesh(); THEN("there is a mesh") { REQUIRE(mesh != nullptr); @@ -89,6 +89,52 @@ SCENARIO("The assimp loader loads models using the Assimp library.", THEN("The mesh component has 2503 texture coordinates.") { REQUIRE(mesh->GetTextureCoords().size() == 2503); } + THEN("The mesh component is unnamed.") { + REQUIRE(mesh->GetName() == phx::Mesh::UNNAMED); + } + } + } + WHEN("We load a specific material.") { + const std::string material_name = "Material.001"; + auto resource = phx::ResourceUtils::LoadResourceFromFile<phx::Material>( + "models/2MeshTest/2meshTest.obj", {{"material_name", material_name}}); + auto material = resource.Get(); + THEN("there is a material") { + REQUIRE(material != nullptr); + THEN("The material has the right name") { + REQUIRE(material->GetName() == material_name); + } + } + } + WHEN("We load a named mesh in an OBJ-File with two models.") { + const std::string mesh_name = "Cube_Cube.001"; + auto resource = phx::ResourceUtils::LoadResourceFromFile<phx::Model>( + "models/2MeshTest/2meshTest.obj"); + auto mesh = resource->GetMesh(mesh_name); + + THEN("there is a mesh") { + REQUIRE(mesh != nullptr); + THEN("The mesh component has 24 vertices.") { + REQUIRE(mesh->GetVertices().size() == 24); + } + THEN("The mesh component has 12 * 3 indices.") { + REQUIRE(mesh->GetIndices().size() == 12 * 3); + } + THEN("The mesh component has 24 normals.") { + REQUIRE(mesh->GetNormals().size() == 24); + } + THEN("The mesh component has 0 tangents.") { + REQUIRE(mesh->GetTangents().size() == 0); + } + THEN("The mesh component has 0 bitangents.") { + REQUIRE(mesh->GetBitangents().size() == 0); + } + THEN("The mesh component has 24 texture coordinates.") { + REQUIRE(mesh->GetTextureCoords().size() == 24); + } + THEN("The mesh component is named like the mesh in the OBJ-File.") { + REQUIRE(mesh->GetName() == mesh_name); + } } } } diff --git a/tests/src/test_clear_pass.cpp b/tests/src/test_clear_pass.cpp index 8ae007bdce6b795fb265c8e4685feaa95e5043df..d5db32896437c18990051b25e0c07b91b2fb4e03 100644 --- a/tests/src/test_clear_pass.cpp +++ b/tests/src/test_clear_pass.cpp @@ -22,6 +22,8 @@ #include "catch/catch.hpp" +#include "phx/suppress_warnings.hpp" + SUPPRESS_WARNINGS_BEGIN #include "GL/glew.h" #include "glm/vec2.hpp" diff --git a/tests/src/test_engine.cpp b/tests/src/test_engine.cpp index f8a7baf5c5e313fd405ed9ca22895433af8bfaad..02b9efd634ccea19931a1ccccab5481fd5c0ec02 100644 --- a/tests/src/test_engine.cpp +++ b/tests/src/test_engine.cpp @@ -41,8 +41,8 @@ #include "trompeloeil.hpp" -#include "mocks/openvr_mock.hpp" #include "mocks/opengl_mock.hpp" +#include "mocks/openvr_mock.hpp" #include "mocks/sdl_mock.hpp" using trompeloeil::_; @@ -106,7 +106,7 @@ class TestOrderSystem : public phx::System { }; class AnyBehavior : public phx::Behavior { - void OnUpdate() override{}; + void OnUpdate() override {} }; SCENARIO("Only one engine should be created", "[phx][phx::Engine]") { @@ -197,10 +197,7 @@ SCENARIO("The active scene in an engine can be switched", }); engine.SetScene(first_scene); - THEN("It has a scene") { - REQUIRE(engine.GetScene() != nullptr); - REQUIRE(engine.GetScene()->GetEngine() == &engine); - } + THEN("It has a scene") { REQUIRE(engine.GetScene() != nullptr); } THEN("The old scene is nullptr.") { REQUIRE(s1 == nullptr); } THEN("The new scene is the one we just set.") { REQUIRE(s2 == first_scene.get()); @@ -213,9 +210,6 @@ SCENARIO("The active scene in an engine can be switched", "The new scene is attached to the engine and the old scene is " "detached") { REQUIRE(engine.GetScene() == new_scene); - REQUIRE(new_scene->GetEngine() == &engine); - - REQUIRE(first_scene->GetEngine() == nullptr); } THEN("The signal is triggered with the appropriate values.") { REQUIRE(s1 == first_scene.get()); @@ -357,67 +351,3 @@ SCENARIO("An engine can be setup by the default setup", "[phx][phx::Engine]") { } } } - -SCENARIO("The order in which systems are updated by the engine can be changed", - "[phx][phx::Engine]") { - SDL_MOCK_ALLOW_ANY_CALL - OPENGL_MOCK_ALLOW_ANY_CALL - GIVEN("An engine set up with a number of test systems") { - auto engine = std::make_unique<phx::Engine>(); - auto system1 = engine->CreateSystem<TestOrderSystem<int>>(); - auto system2 = engine->CreateSystem<TestOrderSystem<float>>(); - auto system3 = engine->CreateSystem<TestOrderSystem<unsigned int>>(); - auto system4 = engine->CreateSystem<TestOrderSystem<double>>(); - engine->CreateSystem<EngineStopTestSystem>(); - std::string test_string; - auto callback1 = [&test_string]() { test_string.push_back('A'); }; - auto callback2 = [&test_string]() { test_string.push_back('B'); }; - auto callback3 = [&test_string]() { test_string.push_back('C'); }; - auto callback4 = [&test_string]() { test_string.push_back('D'); }; - system1->SetCallbackOnUpdate(callback1); - system2->SetCallbackOnUpdate(callback2); - system3->SetCallbackOnUpdate(callback3); - system4->SetCallbackOnUpdate(callback4); - - WHEN("We run the engine") { - engine->Run(); - THEN( - "The test systems have been updated in the same order in which they " - "were added") { - REQUIRE(test_string == "ABCD"); - } - } - - WHEN("We change the second system to update first") { - engine->GetUpdateOrder().MoveToFront(system2); - engine->Run(); - THEN("The systems are updated in the order 2-1-3-4") { - REQUIRE(test_string == "BACD"); - } - } - - WHEN("We change the second system to update last") { - engine->GetUpdateOrder().MoveToBack(system2); - engine->Run(); - THEN("The systems are updated in the order 1-3-4-2") { - REQUIRE(test_string == "ACDB"); - } - } - - WHEN("We change the update order to update system 2 after system 3") { - engine->GetUpdateOrder().MoveAfter(system2, system3); - engine->Run(); - THEN("The systems are updated in the order 1-3-2-4") { - REQUIRE(test_string == "ACBD"); - } - } - - WHEN("We change the update order to update system 4 before system 1") { - engine->GetUpdateOrder().MoveBefore(system4, system1); - engine->Run(); - THEN("The systems are updated in the order 4-1-2-3") { - REQUIRE(test_string == "DABC"); - } - } - } -} diff --git a/tests/src/test_geometry_pass.cpp b/tests/src/test_geometry_pass.cpp index a111eeee252dcab4e8f899ebd40ea4f86b35d9bb..d8cdc27c771136f87a763a8cb840352afbd17ceb 100644 --- a/tests/src/test_geometry_pass.cpp +++ b/tests/src/test_geometry_pass.cpp @@ -27,6 +27,8 @@ #include "catch/catch.hpp" +#include "phx/suppress_warnings.hpp" + SUPPRESS_WARNINGS_BEGIN #include "GL/glew.h" @@ -37,7 +39,9 @@ SUPPRESS_WARNINGS_END #include "phx/entity.hpp" #include "phx/geometry_pass.hpp" +#include "phx/projection.hpp" #include "phx/render_target.hpp" +#include "phx/transform.hpp" #include "mocks/opengl_mock.hpp" @@ -55,8 +59,12 @@ SCENARIO( const GLuint index_buffer_id = 4u; GIVEN("A geometry pass") { - phx::RenderTarget renderTarget(glm::uvec2(1024, 768)); - phx::GeometryPass geometry_pass(&renderTarget); + phx::Entity camera; + camera.AddComponent<phx::Transform>(); + camera.AddComponent<phx::Projection>(); + auto render_target = + camera.AddComponent<phx::RenderTarget>(glm::uvec2(1024, 768)); + phx::GeometryPass geometry_pass(render_target); WHEN("We initialize it.") { trompeloeil::sequence seq; @@ -221,8 +229,12 @@ SCENARIO( const GLuint index_buffer_id = 3u; GIVEN("An initialized geometry pass") { - phx::RenderTarget renderTarget(glm::uvec2(1024, 768)); - phx::GeometryPass geometry_pass(&renderTarget); + phx::Entity camera; + camera.AddComponent<phx::Transform>(); + camera.AddComponent<phx::Projection>(); + auto render_target = + camera.AddComponent<phx::RenderTarget>(glm::uvec2(1024, 768)); + phx::GeometryPass geometry_pass(render_target); geometry_pass.Initialize(); WHEN("We add a meshes with two different transformations") { diff --git a/tests/src/test_input_system.cpp b/tests/src/test_input_system.cpp index 63b20191aeab02742ca194a7d22f6b52ea716afa..dc2a11142349b5407fabd1d807c19498bd2bdfc4 100644 --- a/tests/src/test_input_system.cpp +++ b/tests/src/test_input_system.cpp @@ -29,6 +29,8 @@ #include "trompeloeil.hpp" +#include "phx/suppress_warnings.hpp" + SUPPRESS_WARNINGS_BEGIN #include "mocks/openvr_mock.hpp" SUPPRESS_WARNINGS_END diff --git a/tests/src/test_openvr_controller_system.cpp b/tests/src/test_openvr_controller_system.cpp index 225ea9b498109211629d506451deb94b6834fde4..22d3acf01a91f4d15c9ceb424d311930288b2fe2 100644 --- a/tests/src/test_openvr_controller_system.cpp +++ b/tests/src/test_openvr_controller_system.cpp @@ -24,6 +24,8 @@ #include "catch/catch.hpp" +#include "phx/suppress_warnings.hpp" + SUPPRESS_WARNINGS_BEGIN #include "GL/glew.h" SUPPRESS_WARNINGS_END diff --git a/tests/src/test_orderable_list.cpp b/tests/src/test_orderable_list.cpp new file mode 100644 index 0000000000000000000000000000000000000000..093264bad578bcdabf0cc7d1aabfd0cd30395173 --- /dev/null +++ b/tests/src/test_orderable_list.cpp @@ -0,0 +1,149 @@ +//------------------------------------------------------------------------------ +// Project Phoenix +// +// Copyright (c) 2017-2018 RWTH Aachen University, Germany, +// Virtual Reality & Immersive Visualization Group. +//------------------------------------------------------------------------------ +// License +// +// Licensed under the 3-Clause BSD License (the "License"); +// you may not use this file except in compliance with the License. +// See the file LICENSE for the full text. +// You may obtain a copy of the License at +// +// https://opensource.org/licenses/BSD-3-Clause +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +//------------------------------------------------------------------------------ + +#include <memory> +#include <string> + +#include "catch/catch.hpp" +#include "trompeloeil.hpp" + +#include "phx/orderable_list.hpp" + +using trompeloeil::_; +using trompeloeil::ne; + +extern template struct trompeloeil::reporter<trompeloeil::specialized>; + +SCENARIO("An OderableList can be used as a list", "[phx][phx::OrderableList]") { + GIVEN("An empty OrderableList") { + phx::OrderableList<int> orderable_list; + + THEN("It does not contain anything") { + REQUIRE(orderable_list.size() == 0); + + WHEN("we add one element") { + orderable_list.PushBack(std::make_unique<int>(1)); + THEN("the number of elements is correct") { + REQUIRE(orderable_list.size() == 1); + WHEN("we add one more") { + orderable_list.PushBack(std::make_unique<int>(2)); + THEN("the number of elements is correct") { + REQUIRE(orderable_list.size() == 2); + WHEN("We remove it again") { + orderable_list.erase(orderable_list.begin() + 1, + orderable_list.end()); + THEN("it has 1 element again") { + REQUIRE(orderable_list.size() == 1); + } + } + } + } + } + } + } + } +} + +SCENARIO("An OderableList can looped through", "[phx][phx::OrderableList]") { + GIVEN("An OrderableList with 3 elements") { + phx::OrderableList<int> orderable_list; + orderable_list.PushBack(std::make_unique<int>(1)); + orderable_list.PushBack(std::make_unique<int>(2)); + orderable_list.PushBack(std::make_unique<int>(3)); + + THEN("it can be iterated over the elements using a for each loop") { + int elements = 0; + int correct_order = true; + for (auto& it : orderable_list) { + elements++; + if (*it != elements) correct_order = false; + } + REQUIRE(correct_order); + REQUIRE(elements == 3); + } + } +} + +#if defined __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wmissing-prototypes" +#endif + +namespace { + +std::string GetOrderString( + const phx::OrderableList<std::string>& orderable_list) { + std::string order_string; + for (auto& it : orderable_list) { + order_string += *it; + } + return order_string; +} + +} // namespace + +#if defined __clang__ +#pragma clang diagnostic pop +#endif + +SCENARIO("The order in which elements are ordered can be changed", + "[phx][phx::OrderableList]") { + GIVEN("An OrderableList set up with 4 number of elements") { + phx::OrderableList<std::string> orderable_list; + auto elem1 = orderable_list.PushBack(std::make_unique<std::string>("A")); + auto elem2 = orderable_list.PushBack(std::make_unique<std::string>("B")); + auto elem3 = orderable_list.PushBack(std::make_unique<std::string>("C")); + auto elem4 = orderable_list.PushBack(std::make_unique<std::string>("D")); + + THEN("The elements are in the same order in which they were added") { + REQUIRE(::GetOrderString(orderable_list) == "ABCD"); + } + + WHEN("We change the second element to be first") { + orderable_list.MoveToFront(elem2); + THEN("The elements are in order 2-1-3-4") { + REQUIRE(::GetOrderString(orderable_list) == "BACD"); + } + } + + WHEN("We change the second element to update last") { + orderable_list.MoveToBack(elem2); + THEN("The elements are in order 1-3-4-2") { + REQUIRE(::GetOrderString(orderable_list) == "ACDB"); + } + } + + WHEN("We change order to have element 2 after element 3") { + orderable_list.MoveAfter(elem2, elem3); + THEN("The elements are in order 1-3-2-4") { + REQUIRE(::GetOrderString(orderable_list) == "ACBD"); + } + } + + WHEN("We change order to have element 4 before element 1") { + orderable_list.MoveBefore(elem4, elem1); + THEN("The elements are in order 4-1-2-3") { + REQUIRE(::GetOrderString(orderable_list) == "DABC"); + } + } + } +} diff --git a/tests/src/test_projection.cpp b/tests/src/test_projection.cpp index b1b4c963d59c733777bbe52adcb26cfcd378843b..d38f27056061dc6686fc944cb5ad3b236cda0d2b 100644 --- a/tests/src/test_projection.cpp +++ b/tests/src/test_projection.cpp @@ -22,6 +22,8 @@ #include "catch/catch.hpp" +#include "phx/suppress_warnings.hpp" + SUPPRESS_WARNINGS_BEGIN #include "glm/glm.hpp" SUPPRESS_WARNINGS_END diff --git a/tests/src/test_resource_manager.cpp b/tests/src/test_resource_manager.cpp index a8dfb054ac1b747c05ef9b6c3687bb913ff1abfa..a217d071cdc5914ca202e1003c672f2ccf9fad15 100644 --- a/tests/src/test_resource_manager.cpp +++ b/tests/src/test_resource_manager.cpp @@ -24,7 +24,11 @@ #include <memory> #include <string> +#include "phx/suppress_warnings.hpp" + +SUPPRESS_WARNINGS_BEGIN #include "glm/glm.hpp" +SUPPRESS_WARNINGS_END #include "catch/catch.hpp" @@ -32,10 +36,9 @@ #include "phx/image.hpp" #include "phx/image_loader.hpp" -#include "phx/mesh.hpp" +#include "phx/model.hpp" #include "phx/resource_declaration.hpp" #include "phx/resource_manager.hpp" -#include "phx/resource_proxy.hpp" #include "phx/resource_utils.hpp" #include "phx/shader_source.hpp" @@ -46,22 +49,22 @@ SCENARIO( GIVEN("A fresh resource manager...") { auto &manager = phx::ResourceManager::instance(); GIVEN("A file name of an .obj file...") { - std::string mesh_file_name{"models/bunny.obj"}; - phx::ResourceDeclaration mesh_declaration = - phx::ResourceUtils::DeclarationFromFile(mesh_file_name, - {{"mesh_index", 0}}); + std::string model_file_name{"models/bunny.obj"}; + phx::ResourceDeclaration model_declaration = + phx::ResourceUtils::DeclarationFromFile(model_file_name); WHEN("A resource is declared") { - auto mesh_proxy = manager.DeclareResource(mesh_declaration); - THEN("the returned key is a proxy for an unloaded resource") { - REQUIRE(mesh_proxy != nullptr); - REQUIRE_FALSE(mesh_proxy->IsOnline()); + auto model = manager.DeclareResource<phx::Model>(model_declaration); + THEN("the returned resource pointer represents an unloaded resource") { + REQUIRE(model == nullptr); } WHEN("The same resource declaration is issued again") { - auto redundant_proxy = manager.DeclareResource(mesh_declaration); + auto redundant_model_resource_ptr = + manager.DeclareResource<phx::Model>(model_declaration); THEN( - "the same key is returned (i.e. each resource exists only " + "An equal resource pointer is returned (i.e. each resource " + "exists only " "once!).") { - REQUIRE(redundant_proxy == mesh_proxy); + REQUIRE(redundant_model_resource_ptr == model); } } } @@ -73,53 +76,56 @@ SCENARIO( "Check the load/unload phases of a resource life cycle. A resource is " "offline after declaration and can be loaded in order to bring it online.", "[phx][phx::ResourceManager]") { - GIVEN("A fresh resource manager and a declared mesh resource") { + GIVEN("A fresh resource manager and a declared model resource") { auto &manager = phx::ResourceManager::instance(); - std::string mesh_file_name{"models/bunny.obj"}; - phx::ResourceDeclaration mesh_declaration = - phx::ResourceUtils::DeclarationFromFile(mesh_file_name, - {{"mesh_index", 0}}); - auto mesh_proxy = manager.DeclareResource(mesh_declaration); + std::string model_file_name{"models/bunny.obj"}; + phx::ResourceDeclaration model_declaration = + phx::ResourceUtils::DeclarationFromFile(model_file_name); + auto model = manager.DeclareResource<phx::Model>(model_declaration); WHEN("A resource has not yet been loaded") { - THEN("its state is still \"offline\".") { - REQUIRE_FALSE(mesh_proxy->IsOnline()); + THEN( + "its state is still \"offline\", i.e., its resource pointer is equal " + "to nullptr") { + REQUIRE(model == nullptr); } - THEN("accessing it yields a nullptr.") { - REQUIRE(mesh_proxy->GetAs<phx::Mesh>() == nullptr); + THEN("accessing the resource directly yields a nullptr.") { + REQUIRE(model.Get() == nullptr); } } - WHEN("A resource is loaded through its proxy") { - mesh_proxy->Load(); - THEN("its state changes to \"online\"") { - REQUIRE(mesh_proxy->IsOnline()); + WHEN("A resource is loaded through its resource pointer") { + model.Load(); + THEN( + "its state changes to \"online\", i.e., its resource pointer is not " + "nullptr anymore") { + REQUIRE(model != nullptr); } - THEN("it is available through the proxy") { - auto mesh_resource = mesh_proxy->GetAs<phx::Mesh>(); - REQUIRE(mesh_resource != nullptr); - REQUIRE(mesh_resource->GetNumberOfVertices() > 0); + THEN("the resource itself is available through the resource pointer") { + auto model_resource = model.Get(); + REQUIRE(model_resource != nullptr); + REQUIRE(model_resource->GetMeshes().size() > 0); WHEN("the resource is loaded again") { - mesh_proxy->Load(); - THEN("the underlying resource pointer remains the same") { - auto redundant_mesh = mesh_proxy->GetAs<phx::Mesh>(); - REQUIRE(mesh_proxy->IsOnline()); - REQUIRE(redundant_mesh == mesh_resource); + model.Load(); + THEN("the underlying resource remains the same") { + auto redundant_model = model.Get(); + REQUIRE(model != nullptr); + REQUIRE(redundant_model == model_resource); } } } - WHEN("a resource proxy is used to unload a resource again") { - mesh_proxy->Unload(); + WHEN("a resource pointer is used to unload a resource again") { + model.Unload(); THEN("its state changes to \"offline\" (again)") { - REQUIRE_FALSE(mesh_proxy->IsOnline()); + REQUIRE(model == nullptr); } - THEN("its resource pointer reverts to nullptr") { - REQUIRE(mesh_proxy->GetAs<phx::Mesh>() == nullptr); + THEN("its resource reverts to nullptr") { + REQUIRE(model.Get() == nullptr); } WHEN("an unloaded resource is unloaded again") { - mesh_proxy->Unload(); + model.Unload(); THEN("its state remains unchanged") { - REQUIRE_FALSE(mesh_proxy->IsOnline()); - REQUIRE(mesh_proxy->GetAs<phx::Mesh>() == nullptr); + REQUIRE(model == nullptr); + REQUIRE(model.Get() == nullptr); } } } @@ -133,29 +139,25 @@ SCENARIO("Shaders are resources", "[phx][phx::ResourceManager]") { GIVEN("A shader file name") { const std::string shader_file{"shader/test.frag"}; WHEN("A shader is declared") { - auto shader_proxy = manager.DeclareResource( + auto shader = manager.DeclareResource<phx::ShaderSource>( phx::ResourceUtils::DeclarationFromFile(shader_file)); - THEN("a valid resource proxy is returned") { - REQUIRE(shader_proxy != nullptr); - REQUIRE_FALSE(shader_proxy->IsOnline()); - } - WHEN("The shader is loaded through its proxy") { - shader_proxy->Load(); - THEN("the proxy state changes to \"online\"") { - REQUIRE(shader_proxy->IsOnline()); - } - THEN("the shader source is available through the proxy") { - auto shader = shader_proxy->GetAs<phx::ShaderSource>(); - REQUIRE(shader != nullptr); + WHEN("The shader is loaded through its resource pointer") { + shader.Load(); + THEN("It is now online") { REQUIRE(shader != nullptr); } + THEN( + "the resource (shader source) is available through the resource " + "pointer") { + auto shader_resource = shader.Get(); + REQUIRE(shader_resource != nullptr); REQUIRE(shader->GetSourceLength() > 0); } WHEN("The shader is unloaded again") { - shader_proxy->Unload(); - THEN("its proxy state returns to offline") { - REQUIRE_FALSE(shader_proxy->IsOnline()); + shader.Unload(); + THEN("its resource pointer compares to null again") { + REQUIRE(shader == nullptr); } - THEN("the source code is gone") { - REQUIRE(shader_proxy->GetAs<phx::ShaderSource>() == nullptr); + THEN("the resource (shader source) is gone") { + REQUIRE(shader.Get() == nullptr); } } } @@ -170,30 +172,24 @@ SCENARIO("Images are resources", "[phx][phx::ResourceManager]") { GIVEN("An image file name") { const std::string image_file{"textures/test.jpg"}; WHEN("An image is declared") { - auto image_proxy = manager.DeclareResource( + auto image = manager.DeclareResource<phx::Image>( phx::ResourceUtils::DeclarationFromFile(image_file)); - THEN("a valid resource proxy is returned") { - REQUIRE(image_proxy != nullptr); - REQUIRE_FALSE(image_proxy->IsOnline()); - } - WHEN("The image is loaded through its proxy") { - image_proxy->Load(); - THEN("the proxy changes to \"online\"") { - REQUIRE(image_proxy->IsOnline()); - } - THEN("the image data is available through the proxy") { - auto image = image_proxy->GetAs<phx::Image>(); + WHEN("The image is loaded through its resource pointer") { + image.Load(); + THEN("The resource pointer is not null anymore") { REQUIRE(image != nullptr); + } + THEN("the image data is available through the resource pointer") { + auto image_resource = image.Get(); + REQUIRE(image_resource != nullptr); REQUIRE(image->GetDimensions()[0] > 0); } WHEN("The image is unloaded again") { - image_proxy->Unload(); - THEN("its proxy state returns to offline") { - REQUIRE_FALSE(image_proxy->IsOnline()); - } - THEN("the image data is gone") { - REQUIRE(image_proxy->GetAs<phx::Image>() == nullptr); + image.Unload(); + THEN("the resource pointer equals null again") { + REQUIRE(image == nullptr); } + THEN("the image data is gone") { REQUIRE(image.Get() == nullptr); } } } } @@ -203,12 +199,12 @@ SCENARIO("Images are resources", "[phx][phx::ResourceManager]") { "extension") { const std::string image_file{"textures/test_uppercase.JPG"}; WHEN("An image is declared and loaded") { - auto image_proxy = manager.DeclareResource( + auto image = manager.DeclareResource<phx::Image>( phx::ResourceUtils::DeclarationFromFile(image_file)); - image_proxy->Load(); - THEN("the image data is available through the proxy") { - auto image = image_proxy->GetAs<phx::Image>(); - REQUIRE(image != nullptr); + image.Load(); + THEN("the image data is available through the resource pointer") { + auto image_resource = image.Get(); + REQUIRE(image_resource != nullptr); REQUIRE(image->GetDimensions()[0] > 0); } } diff --git a/tests/src/test_resource_pointer.cpp b/tests/src/test_resource_pointer.cpp index a95e89a53565bbedb982e9c6468f2d3a4d1e49bb..2a36059fe6f23f5219374eda299c312701ec5785 100644 --- a/tests/src/test_resource_pointer.cpp +++ b/tests/src/test_resource_pointer.cpp @@ -25,71 +25,64 @@ #include "phx/image.hpp" #include "phx/resource_manager.hpp" #include "phx/resource_pointer.hpp" -#include "phx/resource_proxy.hpp" #include "phx/resource_utils.hpp" SCENARIO( - "The resource pointer holds a raw pointer to a resource proxy and makes " - "the underlying resource available through the -> operator.", + "The resource pointer makes the underlying resource available through the " + "-> operator.", "[phx][phx::ResourcePointer]") { - GIVEN("A proxy to an arbitrarily chosen image resource.") { - phx::ResourceProxy* proxy = - phx::ResourceManager::instance().DeclareResource( + GIVEN("A resource pointer to an arbitrarily chosen image resource.") { + phx::ResourcePointer<phx::Image> resource_pointer = + phx::ResourceManager::instance().DeclareResource<phx::Image>( phx::ResourceUtils::DeclarationFromFile( "textures/splash_progress.png")); - WHEN("We initialize a resource pointer with that proxy.") { - phx::ResourcePointer<phx::Image> resource_pointer = - phx::ResourcePointer<phx::Image>(proxy); - THEN("We can access the image through the -> operator.") { - REQUIRE(resource_pointer.operator->() == proxy->GetAs<phx::Image>()); - } - THEN("We can access the proxy through the GetProxy() method.") { - REQUIRE(resource_pointer.GetProxy() == proxy); - } + THEN( + "We can can compare the pointer to nullptr using the != operator and " + "they are the same, because the resource is not loaded.") { + REQUIRE(resource_pointer == nullptr); + REQUIRE(!resource_pointer); + } + WHEN("We load the resource.") { + resource_pointer.Load(); THEN( - "We can can compare the pointer to nullptr using the != operator and " - "they are the same, because the resource is not loaded.") { - REQUIRE(resource_pointer == nullptr); - REQUIRE(!resource_pointer); + "We can compare the pointer to nullptr and they are not the " + "same.") { + REQUIRE(resource_pointer != nullptr); + REQUIRE(resource_pointer); } - WHEN("We load the resource.") { - proxy->Load(); - THEN( - "We can compare the pointer to nullptr and they are not the " - "same.") { - REQUIRE(resource_pointer != nullptr); - REQUIRE(resource_pointer); - } + THEN("We can access the image through the -> operator.") { + REQUIRE(resource_pointer.operator->() == resource_pointer.Get()); + REQUIRE(resource_pointer.Get() != nullptr); } - WHEN("We initialize a new pointer with the same proxy.") { - phx::ResourcePointer<phx::Image> resource_pointer2 = - phx::ResourcePointer<phx::Image>(proxy); - THEN( - "We can can compare the two pointers using the == operator and " - "they are the same") { - REQUIRE(resource_pointer == resource_pointer2); - } + } + WHEN("We initialize a new pointer to the same resource.") { + phx::ResourcePointer<phx::Image> resource_pointer2 = + phx::ResourceManager::instance().DeclareResource<phx::Image>( + phx::ResourceUtils::DeclarationFromFile( + "textures/splash_progress.png")); + THEN( + "We can can compare the two pointers using the == operator and " + "they are the same") { + REQUIRE(resource_pointer == resource_pointer2); } - WHEN("We initialize a new pointer with a different proxy.") { - phx::ResourceProxy* proxy2 = - phx::ResourceManager::instance().DeclareResource( - phx::ResourceUtils::DeclarationFromFile("textures/splash.png")); - phx::ResourcePointer<phx::Image> resource_pointer2 = - phx::ResourcePointer<phx::Image>(proxy2); - THEN( - "We can can compare the two pointers using the != operator and " - "they are not the same") { - REQUIRE(resource_pointer != resource_pointer2); - } + } + WHEN("We initialize a new pointer with a different resource.") { + phx::ResourcePointer<phx::Image> resource_pointer2 = + phx::ResourceManager::instance().DeclareResource<phx::Image>( + phx::ResourceUtils::DeclarationFromFile("textures/splash.png")); + THEN( + "We can can compare the two pointers using the != operator and " + "they are not the same") { + REQUIRE(resource_pointer != resource_pointer2); } - WHEN("We initialize a new pointer with nullptr.") { - phx::ResourcePointer<phx::Image> resource_pointer2 = - phx::ResourcePointer<phx::Image>(nullptr); - THEN( - "We can can compare the two pointers using the != operator and " - "they are not the same") { - REQUIRE(resource_pointer != resource_pointer2); - } + } + WHEN("We initialize a new pointer with nullptr.") { + phx::ResourcePointer<phx::Image> resource_pointer2 = + phx::ResourcePointer<phx::Image>(nullptr); + THEN( + "We can can compare the two pointers using the != operator and " + "they are not the same") { + REQUIRE(resource_pointer != resource_pointer2); } } } diff --git a/tests/src/test_resource_utils.cpp b/tests/src/test_resource_utils.cpp index 45d092956465a30c8583ac65a7fae6a441df33aa..154d5a12cc885ff931db52c3ab788a464ba5b838 100644 --- a/tests/src/test_resource_utils.cpp +++ b/tests/src/test_resource_utils.cpp @@ -26,7 +26,6 @@ #include "phx/image.hpp" #include "phx/resource_declaration.hpp" -#include "phx/resource_proxy.hpp" #include "phx/resource_utils.hpp" #include "phx/resources_path.hpp" diff --git a/tests/src/test_scene_loader.cpp b/tests/src/test_scene_loader.cpp index 61ded29bd2c21f78b3fd5509555206180aa45feb..c62ab489b7bd3b926b0bbe978972a3bc37c3a0bf 100644 --- a/tests/src/test_scene_loader.cpp +++ b/tests/src/test_scene_loader.cpp @@ -24,8 +24,11 @@ #include "catch/catch.hpp" +#include "phx/entity.hpp" +#include "phx/mesh_handle.hpp" #include "phx/scene.hpp" #include "phx/scene_loader.hpp" +#include "phx/transform.hpp" SCENARIO("The scene loader can load a model", "[phx][phx::SceneLoader]") { GIVEN("An empty scene") { @@ -33,9 +36,37 @@ SCENARIO("The scene loader can load a model", "[phx][phx::SceneLoader]") { WHEN("We load a model into the scene") { std::string mesh_file{"models/2MeshTest/2meshTest.obj"}; bool success = phx::SceneLoader::InsertModelIntoScene(mesh_file, &scene); - THEN("the scene contains 2 entities + the virtual platform") { + + THEN( + "the scene contains 2 entities + the virtual platform + the root " + "entity") { REQUIRE(success); - REQUIRE(scene.GetEntities().size() == 3u); + REQUIRE(scene.GetEntities().size() == 4u); + } + + THEN( + "the scene contains exactly one root entity with the same name like " + "the model + mesh entites are children of that entity") { + unsigned int nameCounter = 0; + bool meshHasWrongParent = false; + + auto entityVec = scene.GetEntities(); + for (auto currentEntity : entityVec) { + if (currentEntity->GetName() == "2meshTest") { + nameCounter++; + } + if (currentEntity->GetFirstComponent<phx::MeshHandle>() != nullptr) { + auto parentEntity = + currentEntity->GetFirstComponent<phx::Transform>() + ->GetParent() + ->GetEntity(); + if (parentEntity->GetName() != "2meshTest") { + meshHasWrongParent = true; + } + } + } + REQUIRE(nameCounter == 1u); + REQUIRE(meshHasWrongParent == false); } } } diff --git a/tests/src/test_shader.cpp b/tests/src/test_shader.cpp index b433156e3078559d9ae89dc3f3bc06059fa6f024..1e7bdfffe16aaa32f55e419ad277d734c0ecd5ae 100644 --- a/tests/src/test_shader.cpp +++ b/tests/src/test_shader.cpp @@ -24,6 +24,8 @@ #include <memory> #include <string> +#include "phx/suppress_warnings.hpp" + SUPPRESS_WARNINGS_BEGIN #include "GL/glew.h" SUPPRESS_WARNINGS_END diff --git a/tests/src/test_tracking_system.cpp b/tests/src/test_tracking_system.cpp index 467bf0b4ae7463e2e96ac722de572710e9f82466..2b1ae42eabbcb6ac2a7d0e187008c9ab14253dcc 100644 --- a/tests/src/test_tracking_system.cpp +++ b/tests/src/test_tracking_system.cpp @@ -21,11 +21,14 @@ //------------------------------------------------------------------------------ #include <memory> +#include <string> #include "catch/catch.hpp" #include "trompeloeil.hpp" +#include "phx/suppress_warnings.hpp" + SUPPRESS_WARNINGS_BEGIN #include "mocks/openvr_mock.hpp" SUPPRESS_WARNINGS_END @@ -46,7 +49,13 @@ using trompeloeil::ne; extern template struct trompeloeil::reporter<trompeloeil::specialized>; -void SetGlmToArrayMatrix_3_4(glm::mat4 m, float *array); +#if defined __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wmissing-prototypes" +#endif + +namespace { + void SetGlmToArrayMatrix_3_4(glm::mat4 m, float *array) { std::size_t index = 0; for (int x = 0; x < 3; x++) { @@ -57,228 +66,118 @@ void SetGlmToArrayMatrix_3_4(glm::mat4 m, float *array) { } template <typename ComponentType> -bool HasComponent(phx::Entity *entity) { +bool Has(phx::Entity *entity) { return entity->GetFirstComponent<ComponentType>() != nullptr; } -bool HasUserPlatform(phx::Entity *entity) { - return HasComponent<phx::RuntimeComponent<phx::USER_PLATFORM>>(entity); -} - -bool HasHMD(phx::Entity *entity) { - return HasComponent<phx::RuntimeComponent<phx::HEAD>>(entity); -} - -bool HasTransform(phx::Entity *entity) { - return HasComponent<phx::Transform>(entity); -} - -bool HasLeftEye(phx::Entity *entity) { - return HasComponent<phx::RuntimeComponent<phx::LEFT_EYE>>(entity); +template <phx::RuntimeComponentType type_id> +bool Has(phx::Entity *entity) { + return Has<phx::RuntimeComponent<type_id>>(entity); } -bool HasRightEye(phx::Entity *entity) { - return HasComponent<phx::RuntimeComponent<phx::RIGHT_EYE>>(entity); +template <phx::RuntimeComponentType type_id> +bool ParentOfTransformIsTransformOf(phx::Entity *entity) { + const auto *parent_of_transform = + entity->GetFirstComponent<phx::Transform>()->GetParent(); + REQUIRE(parent_of_transform != nullptr); + return Has<type_id>(parent_of_transform->GetEntity()); } -bool HasProjection(phx::Entity *entity) { - return HasComponent<phx::Projection>(entity); -} - -bool HasLeftController(phx::Entity *entity) { - return HasComponent<phx::RuntimeComponent<phx::LEFT_CONTROLLER>>(entity); -} - -bool HasRightController(phx::Entity *entity) { - return HasComponent<phx::RuntimeComponent<phx::RIGHT_CONTROLLER>>(entity); -} - -bool ValidateUserPlatform(phx::Entity *entity, bool platform_present) { - if (HasUserPlatform(entity)) { - THEN("There is only one virtual platform.") { - REQUIRE(platform_present == false); - } - return true; +std::string RuntimeComponentName(phx::RuntimeComponentType type_id) { + switch (type_id) { + case phx::USER_PLATFORM: + return "user platform"; + case phx::HEAD: + return "HMD"; + case phx::LEFT_EYE: + return "left eye"; + case phx::RIGHT_EYE: + return "right eye"; + case phx::LEFT_CONTROLLER: + return "left controller"; + case phx::RIGHT_CONTROLLER: + return "right controller"; } - return false; + return "unknown runtime component"; } -bool ValidateHMD(phx::Entity *entity, bool hmd_present) { - if (HasHMD(entity)) { - THEN("There is only one HMD.") { REQUIRE(hmd_present == false); } - THEN("The HMD has a transform component.") { - REQUIRE(HasTransform(entity)); - } - THEN( - "The parent of the HMD's transform is the platform's " - "transform.") { - REQUIRE(entity->GetFirstComponent<phx::Transform>()->GetParent() != - nullptr); - REQUIRE( - entity->GetFirstComponent<phx::Transform>() - ->GetParent() - ->GetEntity() - ->GetFirstComponent<phx::RuntimeComponent<phx::USER_PLATFORM>>()); - } - return true; +template <phx::RuntimeComponentType type_id> +void ThenRequireThereIsOnlyOne(bool is_present) { + THEN("There is only one " + RuntimeComponentName(type_id) + ".") { + REQUIRE_FALSE(is_present); } - return false; } -bool ValidateLeftEye(phx::Entity *entity, bool left_eye_present) { - if (HasLeftEye(entity)) { - THEN("There is only one left eye.") { REQUIRE(left_eye_present == false); } - THEN("The left eye has a transform component.") { - REQUIRE(HasTransform(entity)); - } - THEN("The left eye has a projection component.") { - REQUIRE(HasProjection(entity)); - } - THEN( - "The parent of the left eye's transform is the HMD's " - "transform.") { - REQUIRE(entity->GetFirstComponent<phx::Transform>()->GetParent() != - nullptr); - REQUIRE(entity->GetFirstComponent<phx::Transform>() - ->GetParent() - ->GetEntity() - ->GetFirstComponent<phx::RuntimeComponent<phx::HEAD>>()); - } - return true; +void ThenRequireItHasTransformComponent(phx::Entity *entity) { + THEN("It has a transform component.") { + REQUIRE(Has<phx::Transform>(entity)); } - return false; } -bool ValidateRightEye(phx::Entity *entity, bool right_eye_present) { - if (HasRightEye(entity)) { - THEN("There is only one right eye.") { - REQUIRE(right_eye_present == false); - } - THEN("The right eye has a transform component.") { - REQUIRE(HasTransform(entity)); - } - THEN("The right eye has a projection component.") { - REQUIRE(HasProjection(entity)); - } - THEN( - "The parent of the right eye's transform is the HMD's " - "transform.") { - REQUIRE(entity->GetFirstComponent<phx::Transform>()->GetParent() != - nullptr); - REQUIRE(entity->GetFirstComponent<phx::Transform>() - ->GetParent() - ->GetEntity() - ->GetFirstComponent<phx::RuntimeComponent<phx::HEAD>>()); - } - return true; +void ThenRequireItHasProjectionComponent(phx::Entity *entity) { + THEN("It has a transform component.") { + REQUIRE(Has<phx::Projection>(entity)); } - return false; } -bool ValidateLeftController(phx::Entity *entity, bool left_controller_present) { - if (HasLeftController(entity)) { - THEN("There is only one left controller.") { - REQUIRE(left_controller_present == false); - } - THEN("The left controller has a transform component.") { - REQUIRE(HasTransform(entity)); - } - THEN( - "The parent of the left controller's transform is the " - "platform's transform.") { - REQUIRE(entity->GetFirstComponent<phx::Transform>()->GetParent() != - nullptr); - REQUIRE( - entity->GetFirstComponent<phx::Transform>() - ->GetParent() - ->GetEntity() - ->GetFirstComponent<phx::RuntimeComponent<phx::USER_PLATFORM>>()); - } - return true; +template <phx::RuntimeComponentType type_id> +void ThenRequireParentOfItsTranformIsTransformOf(phx::Entity *entity) { + THEN("Its transform's parent is the " + RuntimeComponentName(type_id) + + "'s transform") { + REQUIRE(ParentOfTransformIsTransformOf<type_id>(entity)); } - return false; } -bool ValidateRightController(phx::Entity *entity, - bool right_controller_present) { - if (HasRightController(entity)) { - THEN("There is only one right controller.") { - REQUIRE(right_controller_present == false); - } - THEN("The right controller has a transform component.") { - REQUIRE(HasTransform(entity)); - } - THEN( - "The parent of the right controller's transform is the " - "platform's transform.") { - REQUIRE(entity->GetFirstComponent<phx::Transform>()->GetParent() != - nullptr); - REQUIRE( - entity->GetFirstComponent<phx::Transform>() - ->GetParent() - ->GetEntity() - ->GetFirstComponent<phx::RuntimeComponent<phx::USER_PLATFORM>>()); - } +template <bool expression> +using BoolIf = typename std::enable_if<expression, bool>::type; + +template <phx::RuntimeComponentType type_id> +BoolIf<type_id == phx::USER_PLATFORM> Validate(phx::Entity *entity, + bool is_present) { + if (Has<type_id>(entity)) { + ThenRequireThereIsOnlyOne<type_id>(is_present); return true; } return false; } -bool ValidatePlatformTransform(phx::Entity *entity, - glm::mat4 platform_trans_mat) { - if (HasUserPlatform(entity)) { - THEN("The platform transformation did not change.") { - REQUIRE( - test_utilities::Approx<glm::mat4>( - entity->GetFirstComponent<phx::Transform>()->GetLocalMatrix()) == - platform_trans_mat); - } +template <phx::RuntimeComponentType type_id> +BoolIf<type_id == phx::HEAD || type_id == phx::LEFT_CONTROLLER || + type_id == phx::RIGHT_CONTROLLER> +Validate(phx::Entity *entity, bool is_present) { + if (Has<type_id>(entity)) { + ThenRequireThereIsOnlyOne<type_id>(is_present); + ThenRequireItHasTransformComponent(entity); + ThenRequireParentOfItsTranformIsTransformOf<phx::USER_PLATFORM>(entity); return true; } return false; } -bool ValidateHMDTransform(phx::Entity *entity, glm::mat4 hmd_trans_mat) { - if (HasHMD(entity)) { - THEN( - "The hmd transformation changes to the one provided by " - "OpenVR.") { - REQUIRE( - test_utilities::Approx<glm::mat4>( - entity->GetFirstComponent<phx::Transform>()->GetLocalMatrix()) == - hmd_trans_mat); - } +template <phx::RuntimeComponentType type_id> +BoolIf<type_id == phx::LEFT_EYE || type_id == phx::RIGHT_EYE> Validate( + phx::Entity *entity, bool is_present) { + if (Has<type_id>(entity)) { + ThenRequireThereIsOnlyOne<type_id>(is_present); + ThenRequireItHasTransformComponent(entity); + ThenRequireItHasProjectionComponent(entity); + ThenRequireParentOfItsTranformIsTransformOf<phx::HEAD>(entity); return true; } return false; } -bool ValidateLeftEyeTransform(phx::Entity *entity, - glm::mat4 left_eye_trans_mat) { - if (HasLeftEye(entity)) { - THEN( - "The left eye transformation changes to the one provided " - "by OpenVR.") { - REQUIRE( - test_utilities::Approx<glm::mat4>( - entity->GetFirstComponent<phx::Transform>()->GetLocalMatrix()) == - left_eye_trans_mat); - } - return true; - } - return false; +test_utilities::Approx<glm::mat4> GetApproxLocalMatrix(phx::Entity *entity) { + return test_utilities::Approx<glm::mat4>( + entity->GetFirstComponent<phx::Transform>()->GetLocalMatrix()); } -bool ValidateRightEyeTransform(phx::Entity *entity, - glm::mat4 right_eye_trans_mat) { - if (HasRightEye(entity)) { - THEN( - "The right eye transformation changes to the one provided " - "by OpenVR.") { - REQUIRE( - test_utilities::Approx<glm::mat4>( - entity->GetFirstComponent<phx::Transform>()->GetLocalMatrix()) == - right_eye_trans_mat); +template <phx::RuntimeComponentType type_id> +bool ValidateTransform(phx::Entity *entity, glm::mat4 trans_mat, + const std::string &then) { + if (Has<type_id>(entity)) { + THEN("For the " + RuntimeComponentName(type_id) + " " + then) { + REQUIRE(GetApproxLocalMatrix(entity) == trans_mat); } return true; } @@ -296,17 +195,18 @@ void TestRuntimeEntityStructure(std::shared_ptr<phx::Scene> scene) { bool right_controller_present = false; for (auto entity : entities) { - platform_present |= ValidateUserPlatform(entity, platform_present); + platform_present |= + Validate<phx::USER_PLATFORM>(entity, platform_present); - hmd_present |= ValidateHMD(entity, hmd_present); + hmd_present |= Validate<phx::HEAD>(entity, hmd_present); - left_eye_present |= ValidateLeftEye(entity, left_eye_present); - right_eye_present |= ValidateRightEye(entity, right_eye_present); + left_eye_present |= Validate<phx::LEFT_EYE>(entity, left_eye_present); + right_eye_present |= Validate<phx::RIGHT_EYE>(entity, right_eye_present); left_controller_present |= - ValidateLeftController(entity, left_controller_present); + Validate<phx::LEFT_CONTROLLER>(entity, left_controller_present); right_controller_present |= - ValidateLeftController(entity, right_controller_present); + Validate<phx::RIGHT_CONTROLLER>(entity, right_controller_present); } THEN( @@ -330,7 +230,7 @@ void InitMatrices(glm::mat4 *platform_trans_mat, glm::mat4 *hmd_trans_mat, glm::mat4(1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, -1.0f, 0.5f, 1.0f); *hmd_trans_mat = glm::mat4(1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, - 0.0f, 0.0f, 1.0f, 0.0f, 0.5f, 1.8f, 0.2f, 1.0f); + 0.0f, 0.0f, 1.0f, 0.0f, 0.5f, 1.8f, 0.2f, 1.0f); *left_eye_trans_mat = glm::mat4(1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, -0.04f, 0.0f, 0.0f, 1.0f); @@ -363,18 +263,22 @@ void TestRuntimeEntityUpdate(std::shared_ptr<phx::Scene> scene, bool right_controller_present = false; for (auto entity : entities) { - platform_present |= - ValidatePlatformTransform(entity, platform_trans_mat); - - hmd_present |= ValidateHMDTransform(entity, hmd_trans_mat); - - left_eye_present |= - ValidateLeftEyeTransform(entity, left_eye_trans_mat); - right_eye_present |= - ValidateRightEyeTransform(entity, right_eye_trans_mat); - - left_controller_present |= HasLeftController(entity); - right_controller_present |= HasRightController(entity); + platform_present |= ValidateTransform<phx::USER_PLATFORM>( + entity, platform_trans_mat, "the transformation did not change."); + + hmd_present |= ValidateTransform<phx::HEAD>( + entity, hmd_trans_mat, + "the transformation changes to the one provided by OpenVR."); + + left_eye_present |= ValidateTransform<phx::LEFT_EYE>( + entity, left_eye_trans_mat, + "the transformation changes to the one provided by OpenVR."); + right_eye_present |= ValidateTransform<phx::RIGHT_EYE>( + entity, right_eye_trans_mat, + "the transformation changes to the one provided by OpenVR."); + + left_controller_present |= Has<phx::LEFT_CONTROLLER>(entity); + right_controller_present |= Has<phx::RIGHT_CONTROLLER>(entity); } THEN( "There are still six entities: The platform, the HMD, the " @@ -391,6 +295,28 @@ void TestRuntimeEntityUpdate(std::shared_ptr<phx::Scene> scene, } } +void SetPlatformMatrix(const phx::Scene *scene, glm::mat4 matrix) { + auto *transform = scene + ->GetEntitiesWithComponents< + phx::RuntimeComponent<phx::USER_PLATFORM>>()[0] + ->GetFirstComponent<phx::Transform>(); + + transform->SetLocalMatrix(matrix); +} + +template <phx::RuntimeComponentType type_id> +std::size_t NumberOfContained(const phx::Scene *scene) { + const auto &entities = + scene->GetEntitiesWithComponents<phx::RuntimeComponent<type_id>>(); + return entities.size(); +} + +} // namespace + +#if defined __clang__ +#pragma clang diagnostic pop +#endif + SCENARIO( "The tracking system tracks hardware and updates their software " "counterparts.", @@ -410,58 +336,35 @@ SCENARIO( auto platform_trans_mat = glm::mat4(1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, -1.0f, 0.5f, 1.0f); - first_scene - ->GetEntitiesWithComponents< - phx::RuntimeComponent<phx::USER_PLATFORM>>()[0] - ->GetFirstComponent<phx::Transform>() - ->SetLocalMatrix(platform_trans_mat); + ::SetPlatformMatrix(first_scene.get(), platform_trans_mat); WHEN("A tracking system is created and initialized.") { auto tracking_system = engine.CreateSystem<phx::TrackingSystemOpenVR>(display_system); - TestRuntimeEntityStructure(first_scene); - TestRuntimeEntityUpdate(first_scene, tracking_system); + ::TestRuntimeEntityStructure(first_scene); + ::TestRuntimeEntityUpdate(first_scene, tracking_system); WHEN("The scene is then changed.") { auto new_scene = std::make_shared<phx::Scene>(); - new_scene - ->GetEntitiesWithComponents< - phx::RuntimeComponent<phx::USER_PLATFORM>>()[0] - ->GetFirstComponent<phx::Transform>() - ->SetLocalMatrix(platform_trans_mat); + ::SetPlatformMatrix(new_scene.get(), platform_trans_mat); engine.SetScene(new_scene); THEN( "The first scene does not contain runtime entities except for " "exactly one user platform.") { - REQUIRE(first_scene - ->GetEntitiesWithComponents< - phx::RuntimeComponent<phx::USER_PLATFORM>>() - .size() == 1); - REQUIRE(first_scene - ->GetEntitiesWithComponents< - phx::RuntimeComponent<phx::HEAD>>() - .size() == 0); - REQUIRE(first_scene - ->GetEntitiesWithComponents< - phx::RuntimeComponent<phx::LEFT_EYE>>() - .size() == 0); - REQUIRE(first_scene - ->GetEntitiesWithComponents< - phx::RuntimeComponent<phx::RIGHT_EYE>>() - .size() == 0); - REQUIRE(first_scene - ->GetEntitiesWithComponents< - phx::RuntimeComponent<phx::LEFT_CONTROLLER>>() - .size() == 0); - REQUIRE(first_scene - ->GetEntitiesWithComponents< - phx::RuntimeComponent<phx::RIGHT_CONTROLLER>>() - .size() == 0); + REQUIRE(::NumberOfContained<phx::USER_PLATFORM>(first_scene.get()) == + 1); + REQUIRE(::NumberOfContained<phx::HEAD>(first_scene.get()) == 0); + REQUIRE(::NumberOfContained<phx::LEFT_EYE>(first_scene.get()) == 0); + REQUIRE(::NumberOfContained<phx::RIGHT_EYE>(first_scene.get()) == 0); + REQUIRE(::NumberOfContained<phx::LEFT_CONTROLLER>( + first_scene.get()) == 0); + REQUIRE(::NumberOfContained<phx::RIGHT_CONTROLLER>( + first_scene.get()) == 0); } - TestRuntimeEntityStructure(new_scene); - TestRuntimeEntityUpdate(new_scene, tracking_system); + ::TestRuntimeEntityStructure(new_scene); + ::TestRuntimeEntityUpdate(new_scene, tracking_system); } } } diff --git a/tests/test_utilities/approx.hpp b/tests/test_utilities/approx.hpp index 16f031df651358ce770b8c74690a4f4ee00a4dcb..f09bbcaaba026bf7bad7ccfeaf8468dfe4ba3e1b 100644 --- a/tests/test_utilities/approx.hpp +++ b/tests/test_utilities/approx.hpp @@ -30,6 +30,8 @@ #include "catch/catch.hpp" +#include "phx/suppress_warnings.hpp" + SUPPRESS_WARNINGS_BEGIN #include "glm/glm.hpp" SUPPRESS_WARNINGS_END diff --git a/tests/test_utilities/dummy_material_generator.hpp b/tests/test_utilities/dummy_material_generator.hpp index d3522def0d021b21f42a48607cf696937819a269..87df638b6954851b52d679a169686e73b26ba468 100644 --- a/tests/test_utilities/dummy_material_generator.hpp +++ b/tests/test_utilities/dummy_material_generator.hpp @@ -27,7 +27,11 @@ #include <utility> #include <vector> +#include "phx/suppress_warnings.hpp" + +SUPPRESS_WARNINGS_BEGIN #include "glm/vec3.hpp" +SUPPRESS_WARNINGS_END #include "phx/resource_load_strategy.hpp" diff --git a/tests/test_utilities/dummy_mesh_generator.hpp b/tests/test_utilities/dummy_mesh_generator.hpp index 4ddf397cacdf3e8e83494f392fde3b332c628cc0..d12a719e4e198051a7758675ac2770fac22f4426 100644 --- a/tests/test_utilities/dummy_mesh_generator.hpp +++ b/tests/test_utilities/dummy_mesh_generator.hpp @@ -27,7 +27,11 @@ #include <utility> #include <vector> +#include "phx/suppress_warnings.hpp" + +SUPPRESS_WARNINGS_BEGIN #include "glm/vec3.hpp" +SUPPRESS_WARNINGS_END #include "phx/resource_load_strategy.hpp" diff --git a/tests/test_utilities/glm_mat4.hpp b/tests/test_utilities/glm_mat4.hpp index 3a0428365a52c6ab0e2e6c881bfb64a763b27e6c..c34f9e9eeb2d7daa75e5f752120f0018932145a0 100644 --- a/tests/test_utilities/glm_mat4.hpp +++ b/tests/test_utilities/glm_mat4.hpp @@ -30,6 +30,8 @@ #include "catch/catch.hpp" +#include "phx/suppress_warnings.hpp" + SUPPRESS_WARNINGS_BEGIN #include "glm/glm.hpp" SUPPRESS_WARNINGS_END diff --git a/tests/test_utilities/glm_quat.hpp b/tests/test_utilities/glm_quat.hpp index 6d3d385ad4271744dc3e7e4034718366bc417b57..a6dd611a663dcbe7283f067ef91430d313b15473 100644 --- a/tests/test_utilities/glm_quat.hpp +++ b/tests/test_utilities/glm_quat.hpp @@ -30,6 +30,8 @@ #include "catch/catch.hpp" +#include "phx/suppress_warnings.hpp" + SUPPRESS_WARNINGS_BEGIN #include "glm/glm.hpp" SUPPRESS_WARNINGS_END diff --git a/tests/test_utilities/glm_vec3.hpp b/tests/test_utilities/glm_vec3.hpp index 70415bcd3a383bb6e1ddd3feee145d42dd448660..d9a1de832d5e38f673b4111d7f2f2dbb3be0b57a 100644 --- a/tests/test_utilities/glm_vec3.hpp +++ b/tests/test_utilities/glm_vec3.hpp @@ -30,6 +30,8 @@ #include "catch/catch.hpp" +#include "phx/suppress_warnings.hpp" + SUPPRESS_WARNINGS_BEGIN #include "glm/glm.hpp" SUPPRESS_WARNINGS_END diff --git a/tests/test_utilities/log_capture.hpp b/tests/test_utilities/log_capture.hpp index 53a258f406e908e9c181fd8c5ee3414faccc2d17..ba70a17190eb1d0c9f1ba7da9b9cc2cea32457cf 100644 --- a/tests/test_utilities/log_capture.hpp +++ b/tests/test_utilities/log_capture.hpp @@ -30,6 +30,8 @@ #include "spdlog/sinks/sink.h" +#include "phx/suppress_warnings.hpp" + namespace test_utilities { SUPPRESS_WARNINGS_BEGIN_PADDED diff --git a/tests/test_utilities/opengl_buffer_data_comparison.hpp b/tests/test_utilities/opengl_buffer_data_comparison.hpp index eed037ce414255f39e7d0c8f2c79a10377453a42..2ffdc3f3140f72ece5936003d80aec7bbc65f087 100644 --- a/tests/test_utilities/opengl_buffer_data_comparison.hpp +++ b/tests/test_utilities/opengl_buffer_data_comparison.hpp @@ -213,47 +213,45 @@ void OpenGLBufferComparison::REQUIRE_REFERENCE_IMAGE_SIMILARITY( std::string filename_with_path = test_utilities::reference_image_root + filename_reference_image; - auto img_proxy = phx::ResourceManager::instance().DeclareResource( + auto image = phx::ResourceManager::instance().DeclareResource<phx::Image>( phx::ResourceUtils::DeclarationFromFile( filename_with_path, {{"bit_format", bit_format}}, true)); - phx::Image* ref_image = nullptr; try { - img_proxy->Load(); - ref_image = img_proxy->GetAs<phx::Image>(); + image.Load(); } catch (const std::exception&) { } - similarity = ComputeSimilarity(buffer_test, ref_image); + similarity = ComputeSimilarity(buffer_test, image.Get()); if (similarity < minimumSimilarity) { std::unique_ptr< phx::OpenGLImageBufferData<phx::OpenGLImageBufferDataType_Float32>> buffer_diff = nullptr; - if (ref_image != nullptr) { + if (image.Get() != nullptr) { auto buffer_ref = - phx::OpenGLImageBufferData<T>::CreateFromImage(ref_image); + phx::OpenGLImageBufferData<T>::CreateFromImage(image.Get()); buffer_diff = phx::OpenGLImageBufferData<T>::CreateDifferenceMagnitudeBuffer( buffer_test, *buffer_ref.get()); } auto filenames = - SaveTemporaryFiles(buffer_test, ref_image, buffer_diff.get()); + SaveTemporaryFiles(buffer_test, image.Get(), buffer_diff.get()); std::string file1 = std::get<0>(filenames); std::string file2 = std::get<1>(filenames); std::string file_diff = std::get<2>(filenames); - OutputFailMessage(buffer_test, filename_with_path, similarity, ref_image); - if (ref_image != nullptr) { - OutputComparisonInfo(minimumSimilarity, similarity, ref_image, + OutputFailMessage(buffer_test, filename_with_path, similarity, image.Get()); + if (image.Get() != nullptr) { + OutputComparisonInfo(minimumSimilarity, similarity, image.Get(), buffer_diff.get(), file1, file2, file_diff); } else { OutputRefImageMissingInfo(file1); } DetermineTestOutcome(similarity, minimumSimilarity, buffer_test, filename_with_path, file1, file2, file_diff, - ref_image != nullptr); + image.Get() != nullptr); } else { // pass test REQUIRE(similarity >= minimumSimilarity);