├── .github └── workflows │ └── ci-build.yml ├── .gitignore ├── .travis.yml ├── CMakeLists.txt ├── Contributors.txt ├── GettingStarted.txt ├── LICENSE.txt ├── PagedGeometry.pc.in ├── PagedGeometryConfig.cmake.in ├── README.md ├── Todo.txt ├── bin ├── media │ ├── grass │ │ ├── __ReadMe__.txt │ │ ├── grass.png │ │ └── grass2.png │ ├── newterrain │ │ ├── TextureUsageAgreement.txt │ │ ├── cloudy_noon_bk.jpg │ │ ├── cloudy_noon_dn.jpg │ │ ├── cloudy_noon_fr.jpg │ │ ├── cloudy_noon_lf.jpg │ │ ├── cloudy_noon_rt.jpg │ │ ├── cloudy_noon_up.jpg │ │ ├── depthshadowobject.cg │ │ ├── dirt_grayrocky_diffusespecular.dds │ │ ├── dirt_grayrocky_normalheight.dds │ │ ├── early_morning_bk.jpg │ │ ├── early_morning_dn.jpg │ │ ├── early_morning_fr.jpg │ │ ├── early_morning_lf.jpg │ │ ├── early_morning_rt.jpg │ │ ├── early_morning_up.jpg │ │ ├── fw12b.jpg │ │ ├── grass.material │ │ ├── grass_green-01_diffusespecular.dds │ │ ├── grass_green-01_normalheight.dds │ │ ├── growth_weirdfungus-03_diffusespecular.dds │ │ ├── growth_weirdfungus-03_normalheight.dds │ │ ├── new_terrain.png │ │ ├── new_terrain_detail.jpg │ │ ├── new_terrain_texture.jpg │ │ ├── pssm.material │ │ ├── sky.material │ │ ├── tudorhouse.material │ │ └── tudorhouse.mesh │ ├── shaders │ │ ├── BatchPage_vp.glsl │ │ ├── Default_fp.glsl │ │ ├── Grass_vp.glsl │ │ ├── PagedGeometry.program │ │ └── Sprite_vp.glsl │ ├── terrain2 │ │ ├── densitymap.png │ │ ├── terrain.cfg │ │ ├── terrain.png │ │ ├── terrain2.cfg │ │ ├── terrain3.cfg │ │ ├── terrain_detail.jpg │ │ ├── terrain_detail0.jpg │ │ ├── terrain_lightmap.jpg │ │ ├── terrain_texture.jpg │ │ └── terrain_texture2.jpg │ ├── trees │ │ ├── Bush.blend │ │ ├── Bush.mesh │ │ ├── Leaves.png │ │ ├── Pine1.mesh │ │ ├── PineLeaves.png │ │ ├── Tree0.blend │ │ ├── tree.material │ │ ├── tree.mesh │ │ ├── tree2.mesh │ │ └── wood7.jpg │ └── trees2 │ │ ├── 3d-diggers_fir.material │ │ ├── 3ddsky_0001.jpg │ │ ├── 3ddsky_0002.jpg │ │ ├── 3ddsky_0003.jpg │ │ ├── 3ddsky_0004.jpg │ │ ├── 3ddsky_0005.jpg │ │ ├── 3ddsky_0006.jpg │ │ ├── 3ddsky_0007.jpg │ │ ├── __ReadMe__.txt │ │ ├── farn01.png │ │ ├── farn02.png │ │ ├── farn1.mesh │ │ ├── farn1.mesh.material │ │ ├── farn2.mesh │ │ ├── farn2.mesh.material │ │ ├── fir01.png │ │ ├── fir02.jpg │ │ ├── fir05_30.mesh │ │ ├── fir06_30.mesh │ │ ├── fir14_25.mesh │ │ ├── plant1.mesh │ │ ├── plant1.mesh.material │ │ ├── plant1.png │ │ ├── plant2.mesh │ │ ├── plant2.mesh.material │ │ ├── plant2.png │ │ ├── shroom1.png │ │ ├── shroom1_1.mesh │ │ ├── shroom1_2.mesh │ │ ├── shroom1_3.mesh │ │ ├── shroom2.png │ │ ├── shroom2_1.mesh │ │ ├── shroom2_2.mesh │ │ ├── shroom2_3.mesh │ │ ├── shrooms.material │ │ └── skybox.material └── resources.cfg ├── docs ├── Doxyfile.in ├── PagedGeometryScreen1.jpg ├── Tutorial-1.md ├── Tutorial-2.md ├── Tutorial-3.md └── Tutorial-4.md ├── examples ├── CMakeLists.txt ├── Example1.cpp ├── Example10.cpp ├── Example11.cpp ├── Example2.cpp ├── Example3.cpp ├── Example4.cpp ├── Example5.cpp ├── Example6.cpp ├── Example7.cpp ├── Example8.cpp ├── Example9.cpp ├── HeightFunction.h ├── LegacyTerrainLoader.h └── PGExampleApplication.h ├── include ├── BatchPage.h ├── BatchedGeometry.h ├── GrassLoader.h ├── ImpostorPage.h ├── PagedGeometry.h ├── PagedGeometryConfig.h.in ├── PropertyMaps.h ├── RandomTable.h ├── StaticBillboardSet.h ├── TreeLoader2D.h ├── TreeLoader3D.h ├── WindBatchPage.h └── WindBatchedGeometry.h └── source ├── BatchPage.cpp ├── BatchedGeometry.cpp ├── CMakeLists.txt ├── GrassLoader.cpp ├── ImpostorPage.cpp ├── PagedGeometry.cpp ├── PropertyMaps.cpp ├── StaticBillboardSet.cpp ├── TreeLoader2D.cpp ├── TreeLoader3D.cpp ├── WindBatchPage.cpp └── WindBatchedGeometry.cpp /.github/workflows/ci-build.yml: -------------------------------------------------------------------------------- 1 | name: CI Build 2 | on: 3 | push: 4 | branches: [master] 5 | pull_request: 6 | branches: [master] 7 | jobs: 8 | linux: 9 | runs-on: ubuntu-22.04 10 | steps: 11 | - name: Install Dependencies 12 | run: | 13 | sudo apt update 14 | sudo apt install -y cmake g++ libogre-1.12-dev 15 | - uses: actions/checkout@v2 16 | - name: Test 17 | run: | 18 | cmake -Bbuild . 19 | cmake --build build -- -j 2 20 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | syntax: glob 2 | _build/ 3 | build/ 4 | lib/ 5 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: c 2 | sudo: required 3 | 4 | before_install: 5 | - sudo apt-get install -y cmake pkg-config libogre-1.9-dev libois-dev 6 | 7 | script: 8 | - cmake . 9 | - make -j2 10 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | ###################################################################### 2 | # PagedGeometry BUILD SYSTEM 3 | # Welcome to the CMake build system for PagedGeometry. 4 | # This is the main file where we prepare the general build environment 5 | # and provide build configuration options. 6 | ###################################################################### 7 | # cmake system for PagedGeometry updated on 2-9-2021 by Edgar{at}AnotherFoxGuy{DOT}com 8 | 9 | cmake_minimum_required(VERSION 3.1) 10 | 11 | # define the project 12 | project( 13 | PagedGeometry 14 | HOMEPAGE_URL https://ogrecave.github.io/ogre-pagedgeometry/ 15 | DESCRIPTION "PagedGeometry is a library that helps you to add grass and trees to your Ogre3D scene" 16 | VERSION 1.3.0 17 | ) 18 | 19 | # add some functions we use that are shipped with cmake 20 | include(CheckLibraryExists) 21 | include(CheckIncludeFile) 22 | include(CheckIncludeFileCXX) 23 | include(CheckCCompilerFlag) 24 | include(CheckCSourceCompiles) 25 | include(CMakePackageConfigHelpers) 26 | include(GNUInstallDirs) 27 | 28 | 29 | # build static libs by default 30 | SET(BUILD_SHARED_LIBS OFF) 31 | 32 | SET(CMAKE_USE_RELATIVE_PATHS OFF) 33 | 34 | 35 | # setup paths 36 | SET(RUNTIME_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/bin/") 37 | SET(LIBRARY_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/lib/") 38 | SET(ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/lib/") 39 | SET(EXECUTABLE_OUTPUT_PATH ${RUNTIME_OUTPUT_DIRECTORY}) 40 | SET(LIBRARY_OUTPUT_PATH ${LIBRARY_OUTPUT_DIRECTORY}) 41 | SET(CMAKEFILES_INSTALL_DIR "${CMAKE_INSTALL_LIBDIR}/cmake/PagedGeometry") 42 | 43 | # fix executable paths for windows 44 | SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${RUNTIME_OUTPUT_DIRECTORY}) 45 | SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${RUNTIME_OUTPUT_DIRECTORY}) 46 | SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELWITHDEBINFO ${RUNTIME_OUTPUT_DIRECTORY}) 47 | SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG ${RUNTIME_OUTPUT_DIRECTORY}) 48 | 49 | 50 | # some optimization flags 51 | if (MSVC) 52 | # add multi processor compilation flags 53 | set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MP /GL /Ox /Ob2 /Oi /Ot /Oy /fp:fast /GS- /MP /Zi") 54 | set(CMAKE_CXX_FLAGS_MINSIZEREL "${CMAKE_CXX_FLAGS_MINSIZEREL} /MP /Zi") 55 | set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} /MP /Od /Zi") 56 | set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MP /Od /Zi") 57 | # some general flags 58 | add_definitions("-D_CRT_SECURE_NO_WARNINGS") 59 | include_directories(${DirectX_INCLUDE_DIR}) 60 | 61 | set(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG} /DEBUG /SUBSYSTEM:WINDOWS") 62 | set(CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE} /DEBUG /SUBSYSTEM:WINDOWS /LTCG /OPT:REF") 63 | set(CMAKE_EXE_LINKER_FLAGS_MINSIZEREL "${CMAKE_EXE_LINKER_FLAGS_MINSIZEREL} /DEBUG /SUBSYSTEM:WINDOWS /LTCG /OPT:REF") 64 | set(CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO "${CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO} /DEBUG /SUBSYSTEM:WINDOWS /LTCG /OPT:REF") 65 | elseif () 66 | set(CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE} -mfpmath=sse -msse2 -mmmx -msse -msse3 -m3dnow -O2 -fomit-frame-pointer -fstrict-aliasing -ffast-math -ftracer") 67 | set(CMAKE_EXE_LINKER_FLAGS_RelWithDebug "${CMAKE_EXE_LINKER_FLAGS_RelWithDebug} -O0") 68 | endif () 69 | 70 | # some PG build options 71 | set(PAGEDGEOMETRY_BUILD_SAMPLES "FALSE" CACHE BOOL "build the examples") 72 | set(PAGEDGEOMETRY_ALTERNATE_COORDSYSTEM "FALSE" CACHE BOOL "alternate coordinate system, do not use unless you are very sure about it") 73 | set(PAGEDGEOMETRY_USER_DATA "FALSE" CACHE BOOL "ability to attach user data to entities") 74 | 75 | # configuration of the config.h 76 | CONFIGURE_FILE("${PROJECT_SOURCE_DIR}/include/PagedGeometryConfig.h.in" "${PROJECT_BINARY_DIR}/include/PagedGeometryConfig.h") 77 | 78 | # some additional compiler flags 79 | if (NOT WIN32) 80 | ADD_DEFINITIONS(-Wall -Wno-unused-parameter) 81 | CHECK_C_COMPILER_FLAG(-Wextra HAVE_W_EXTRA) 82 | if (HAVE_W_EXTRA) 83 | ADD_DEFINITIONS(-Wextra) 84 | endif () 85 | endif () 86 | 87 | # Set visibility options if available 88 | IF (NOT WIN32) 89 | CHECK_C_SOURCE_COMPILES("int foo() __attribute__((destructor)); 90 | int main() {return 0;}" HAVE_GCC_DESTRUCTOR) 91 | 92 | CHECK_C_COMPILER_FLAG(-fvisibility=hidden HAVE_VISIBILITY_SWITCH) 93 | IF (HAVE_VISIBILITY_SWITCH) 94 | CHECK_C_SOURCE_COMPILES("int foo() __attribute__((visibility(\"default\"))); 95 | int main() {return 0;}" HAVE_GCC_VISIBILITY) 96 | IF (HAVE_GCC_VISIBILITY) 97 | ADD_DEFINITIONS(-fvisibility=hidden -DHAVE_GCC_VISIBILITY) 98 | ENDIF () 99 | ENDIF () 100 | ENDIF () 101 | 102 | # --- Ogre 3D graphics engine --- 103 | find_package(OGRE REQUIRED CONFIG) 104 | 105 | # now add the directories 106 | add_subdirectory(source) 107 | 108 | if (PAGEDGEOMETRY_BUILD_SAMPLES) 109 | add_subdirectory(examples) 110 | endif (PAGEDGEOMETRY_BUILD_SAMPLES) 111 | 112 | 113 | # doxygen stuff 114 | find_package(Doxygen) 115 | if (DOXYGEN_FOUND) 116 | message("found doxygen, generating documentation") 117 | # prepare doxygen configuration file 118 | configure_file(${PROJECT_SOURCE_DIR}/docs/Doxyfile.in ${PROJECT_BINARY_DIR}/Doxyfile) 119 | 120 | add_custom_target( 121 | doc_doxygen 122 | COMMAND ${DOXYGEN_EXECUTABLE} ${CMAKE_BINARY_DIR}/Doxyfile 123 | WORKING_DIRECTORY ${CMAKE_BINARY_DIR} 124 | COMMENT "Generating documentation with Doxygen." 125 | VERBATIM 126 | ) 127 | 128 | # cleanup $build/docs on "make clean" 129 | set_property(DIRECTORY APPEND PROPERTY ADDITIONAL_MAKE_CLEAN_FILES docs) 130 | 131 | #install(DIRECTORY ${CMAKE_BINARY_DIR}/docs/html/ DESTINATION ${CMAKE_INSTALL_DOCDIR}/api) 132 | # install man pages into packages, scope is now project root.. 133 | #install(DIRECTORY ${CMAKE_BINARY_DIR}/docs/man/man3 DESTINATION share/man/man3/ ) 134 | endif (DOXYGEN_FOUND) 135 | 136 | # other doc files 137 | set(DOC_FILES Contributors.txt LICENSE.txt README.md Todo.txt) 138 | install(FILES ${DOC_FILES} DESTINATION TYPE DOC) 139 | 140 | # install the PkgConfig file 141 | configure_file("${PROJECT_SOURCE_DIR}/PagedGeometry.pc.in" "${PROJECT_BINARY_DIR}/PagedGeometry.pc" @ONLY) 142 | install(FILES "${PROJECT_BINARY_DIR}/PagedGeometry.pc" DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig") 143 | 144 | configure_package_config_file( 145 | PagedGeometryConfig.cmake.in 146 | ${PROJECT_BINARY_DIR}/PagedGeometryConfig.cmake 147 | INSTALL_DESTINATION ${CMAKEFILES_INSTALL_DIR} 148 | ) 149 | 150 | write_basic_package_version_file( 151 | ${PROJECT_BINARY_DIR}/PagedGeometryConfigVersion.cmake 152 | VERSION "${CMAKE_PROJECT_VERSION}" 153 | COMPATIBILITY SameMajorVersion 154 | ) 155 | 156 | install( 157 | FILES ${PROJECT_BINARY_DIR}/PagedGeometryConfig.cmake 158 | ${PROJECT_BINARY_DIR}/PagedGeometryConfigVersion.cmake 159 | DESTINATION ${CMAKEFILES_INSTALL_DIR} 160 | ) 161 | -------------------------------------------------------------------------------- /Contributors.txt: -------------------------------------------------------------------------------- 1 | John Judnich - main author 2 | Erik Hjortsberg (erik.hjortsberg@iteam.se) 3 | Thomas Fischer (thomas@rigsofrods.com) - maintainer since 2010 4 | m2codegen@rambler.ru - optimizations and performance improvements, releases 1.1.1 RC1 5 | -------------------------------------------------------------------------------- /GettingStarted.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OGRECave/ogre-pagedgeometry/5776681bb56b63e9d2012c9eb0885608968b2d44/GettingStarted.txt -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | This software is provided 'as-is', without any express or implied 2 | warranty. In no event will the authors be held liable for any damages 3 | arising from the use of this software. 4 | 5 | Permission is granted to anyone to use this software for any purpose, 6 | including commercial applications, and to alter it and redistribute it 7 | freely, subject to the following restrictions: 8 | 9 | 1. The origin of this software must not be misrepresented; you must not 10 | claim that you wrote the original software. If you use this software 11 | in a product, an acknowledgment in the product documentation would be 12 | appreciated but is not required. 13 | 14 | 2. Altered source versions must be plainly marked as such, and must not be 15 | misrepresented as being the original software. 16 | 17 | 3. This notice may not be removed or altered from any source 18 | distribution. -------------------------------------------------------------------------------- /PagedGeometry.pc.in: -------------------------------------------------------------------------------- 1 | prefix="@CMAKE_INSTALL_PREFIX@" 2 | exec_prefix="${prefix}" 3 | libdir="${prefix}/@CMAKE_INSTALL_LIBDIR@" 4 | includedir="${prefix}/include" 5 | 6 | Name: @CMAKE_PROJECT_NAME@ 7 | Version: @CMAKE_PROJECT_VERSION@ 8 | Description: @CMAKE_PROJECT_DESCRIPTION@ 9 | Requires: @PKG_CONFIG_REQUIRES@ 10 | Libs: -L${libdir} -l@CMAKE_PROJECT_NAME@ 11 | Cflags: -I${includedir} 12 | -------------------------------------------------------------------------------- /PagedGeometryConfig.cmake.in: -------------------------------------------------------------------------------- 1 | @PACKAGE_INIT@ 2 | 3 | include("${CMAKE_CURRENT_LIST_DIR}/PagedGeometryTargets.cmake") 4 | 5 | check_required_components(PagedGeometry) -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Introduction {#mainpage} 2 | 3 | Although the PagedGeometry engine is fairly simple and easy to use, there are some 4 | advanced features that may be difficult to learn on you own. This API reference is here 5 | for your convenience, to aid you in learning how to get the most out of the PagedGeometry 6 | engine. 7 | 8 | Every feature of the engine is covered here in detail, so you won't be left in the dark 9 | about any aspect of PagedGeometry's use (however, some of the internal workings of the 10 | engine are not documented in here - you'll have to refer to the source code comments 11 | for that). 12 | 13 | # What is PagedGeometry? 14 | The PagedGeometry engine is an add-on to the OGRE 15 | Graphics Engine, which provides highly optimized methods for rendering massive amounts 16 | of small meshes covering a possibly infinite area. This is especially well suited for dense 17 | forests and outdoor scenes, with millions of trees, bushes, grass, rocks, etc., etc. 18 | 19 | ![](docs/PagedGeometryScreen1.jpg) 20 | 21 | Expansive jungle scene with 240,000 trees and animated vegetation 22 | 23 | Paged geometry gives you many advantages over plain entities, the main one being speed: 24 | With proper usage of detail levels, outdoor scenes managed by PagedGeometry can 25 | be >100x faster than plain entities. Another advantage is that the geometry is paged; in 26 | other words, only entities which are immediately needed (to be displayed) are loaded. 27 | This allows you to expand the boundaries of your virtual world almost infinitely 28 | (only limited by floating point precision), providing the player with a more realistically 29 | scaled game area. 30 | 31 | # Features 32 | * Dynamic geometry paging system, which enables infinite worlds 33 | * Batched rendering for optimized rendering of near-by trees 34 | * Impostor rendering -LOD for extremely fast rendering of distant trees 35 | * Flexible -LOD display system, which can be expanded to display geometry with any technique you can implement 36 | * Flexible -LOD configuration system, which allows you to configure any combination of supported LODs in any way you want 37 | * Optional cross-LOD fade transitions, and far -LOD fade-out, fully configurable 38 | * Flexible PageLoader system, allowing you to dynamically load geometry from any source you can imagine 39 | * Easy addition / removal of trees with bit packing, allowing millions of trees to be stored in RAM using only a few MBs 40 | * Color-map support for trees, which enables you to apply terrain lightmaps to your trees with one simple function call 41 | * Animated, optimized grass rendering system. Supports density maps, color maps, wind animations, height range restriction, and much more. 42 | 43 | # Getting Started 44 | 45 | When you're ready to start learning how to use PagedGeometry, the best place to start is 46 | with @ref tut1. The tutorials will teach you how to use many 47 | important PagedGeometry features, step by step. This API reference isn't recommended 48 | for learning, but is a valuable resource when you need specific in-depth information 49 | about a certain function or class. 50 | 51 | 52 | # Credits 53 | 54 | 62 | 63 | 64 | # License 65 | Copyright (c) 2007 John Judnich 66 | 67 | 68 | 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. 69 | 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: 70 | 71 | 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. 72 | 73 | 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 74 | 75 | 3. This notice may not be removed or altered from any source distribution. 76 | -------------------------------------------------------------------------------- /Todo.txt: -------------------------------------------------------------------------------- 1 | __PagedGeometry________________________ 2 | 3 | + Add minimum tree scale for treeloaders 4 | + Enforce tree scales with debug-only exceptions in treeloaders 5 | + Add support for alternate coordinate systems (for example, where Z is up) 6 | + Update docs (recompile API, no more updateAnimation(), new frameUpdate() function in PageLoader) 7 | + Add #defines for alternate coordinate system support 8 | + Fix impostor rotation point 9 | + Add grass layer delete 10 | + Fix impostor rotation point problem 11 | + Add userData parameter support to height functions 12 | 13 | Fixed: 14 | + Fix tree scale issue 15 | + Fix StaticBillboardSet reference bug 16 | + Fix possible grass animation bug 17 | + Fix grass reload bug 18 | + Supplying an invalid material to GrassLayer will crash without a descriptive error 19 | + Fix impostor filename issue 20 | + Batches and impostors do not correctly handle per-subentity materials 21 | 22 | Add shared vertex data support 23 | 24 | Confirmed: 25 | 26 | 27 | --- Release Version 1.0 --- 28 | 29 | + Sprite grass 30 | Angled grass 31 | Add density map tree loader 32 | Fix batching of shared vertices 33 | Density map editing functions 34 | Add BillboardPage 35 | Add Impostor autoregeneration 36 | 37 | --- Release Version 1.1 --- 38 | 39 | Improve impostor customization 40 | setDefaultImpostorResolution(), setDefaultImpostorColor(), setDefaultImpostorRenders() 41 | setImpostorResolution(), setImpostorColor(), setImpostorRenders() 42 | Implement InstancePage 43 | Add hard disk tree loader 44 | 45 | Dynamic lighting 46 | Swaying trees 47 | Add functions to reload rectangular and circular regions of geometry 48 | Add progressive reloading option 49 | 50 | 51 | Add a maximum view height as well as a maximum view distance for detail levels 52 | Optimize impostor generator for tall, skinny trees 53 | Fix Ogre's billboard system for camera roll 54 | Experement with single-triangle billboards and point-sprites 55 | Add collision interface 56 | Possibly add a pseudo-volumetric-texture GeometryPage implementation 57 | Add automated terrain lightmapper to PagedGeometry 58 | -------------------------------------------------------------------------------- /bin/media/grass/__ReadMe__.txt: -------------------------------------------------------------------------------- 1 | This grass texture included with PagedGeometry was kindly provided by 2 | Agnisola Philippe (http://www.blitz3dfr.com/portal_joomla/) for 3 | commercial or non-commercial use. -------------------------------------------------------------------------------- /bin/media/grass/grass.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OGRECave/ogre-pagedgeometry/5776681bb56b63e9d2012c9eb0885608968b2d44/bin/media/grass/grass.png -------------------------------------------------------------------------------- /bin/media/grass/grass2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OGRECave/ogre-pagedgeometry/5776681bb56b63e9d2012c9eb0885608968b2d44/bin/media/grass/grass2.png -------------------------------------------------------------------------------- /bin/media/newterrain/TextureUsageAgreement.txt: -------------------------------------------------------------------------------- 1 | The original diffuse textures are from the NVIDIA texture library, with other maps generated from them by Steve Streeting. The following license applies to all textures. 2 | 3 | Single Product or Project Use of NVSDK-Art Imagery 4 | THIS IS A LEGAL AGREEMENT (the "License Agreement") between you and NVIDIA, Inc. ("Company"). If you do not agree to all the terms and conditions of this License Agreement, immediately delete the NVSDK-Art Imagery from your hard disk. If you proceed to use any of the images (the "Images") contained therein, you thereby signify that you have agreed to all of the terms and conditions set forth below. 5 | 6 | You may not use, copy, display, modify or distribute the Images except in strict accordance with this License Agreement. Company hereby grants to you the following worldwide, non-exclusive, non-transferable, non-sublicensable license for the Term below, with respect to its rights in the Images: 7 | 8 | You may install the Images on an unlimited number of computers; provided that all such computers are physically located at your place of business located at a single specific street address (or its equivalent). You may use and access the Images only at that one location and only as follows: You may use, copy and modify the Images in the creation and presentation of videogames, animations and renderings; provided that you may neither: (a) separately publish, market, distribute, transfer, sell or sublicense all or any part of the Images except in derivative form from which the original, or a substantially similar version of the original Image can be extracted; (b) output the Images to a print format other than for collateral materials (such as sales literature and illustrations) which support your primary electronic use of the Images. Subject to the foregoing limitations, and the rights, you may copy and distribute your animations and renderings incorporating the Images. 9 | 10 | All other rights with respect to the Images and their use are reserved to Company. 11 | 12 | The Images are protected by United States copyright laws, international treaty provisions, and other laws. 13 | 14 | TERM. You may use the Images for incorporation in a single product or production, or for visualization purposes within a single project of duration not more than three years. 15 | 16 | INFRINGEMENT WARRANTY. NVIDIA warrants to you that, to the best of its knowledge, the digital data for the Images do not infringe the rights, including patent, copyright and trade secret rights, of any third party; provided, however, that NVIDIA makes no representation or warranties with respect to infringement of any third party's rights by any image or object depicted by such digital data. 17 | 18 | LIMITATION OF LIABILITY AND WARRANTIES. YOU ASSUME THE ENTIRE COST OF ANY DAMAGE, LOSSES OR EXPENSE RESULTING FROM YOUR USE OR EXPLOITATION OF THE IMAGES. YOU ASSUME ALL RESPONSIBILITIES FOR SELECTION OF THE IMAGES TO ACHIEVE YOUR INTENDED RESULTS, AND FOR THE INSTALLATION OF, USE OF, AND RESULTS OBTAINED FROM THE IMAGES. 19 | 20 | TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, COMPANY HEREBY DISCLAIMS ALL WARRANTIES, EXPRESS AND IMPLIED, INCLUDING BUT NOT LIMITED TO IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT (except as provided in the section titled "Infringement Warranty" above), AND FITNESS FOR A PARTICULAR PURPOSE WITH RESPECT TO THE IMAGES AND ANY ACCOMPANYING SOFTWARE OR MATERIALS. 21 | 22 | This License Agreement is the entire agreement between you and Company with respect to the Images and supersedes any other communications or advertising, whether written or oral, with respect thereto. If any provision of this License Agreement is held invalid or unenforceable, the remainder shall continue in full force and effect, provided that, if any limitation on the grant to you of any right herein is held invalid or unenforceable, such right shall immediately terminate. 23 | 24 | No Warranty. THE SOFTWARE AND ANY OTHER MATERIALS PROVIDED BY NVIDIA TO DEVELOPER HEREUNDER ARE PROVIDED "AS IS." NVIDIA DISCLAIMS ALL WARRANTIES, EXPRESS, IMPLIED OR STATUTORY, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 25 | Limitation of Liability. NVIDIA SHALL NOT BE LIABLE TO DEVELOPER, DEVELOPER'S CUSTOMERS, OR ANY OTHER PERSON OR ENTITY CLAIMING THROUGH OR UNDER DEVELOPER FOR ANY LOSS OF PROFITS, INCOME, SAVINGS, OR ANY OTHER CONSEQUENTIAL, INCIDENTAL, SPECIAL, PUNITIVE, DIRECT OR INDIRECT DAMAGES (WHETHER IN AN ACTION IN CONTRACT, TORT OR BASED ON A WARRANTY), EVEN IF NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS SHALL APPLY NOTWITHSTANDING ANY FAILURE OF THE ESSENTIAL PURPOSE OF ANY LIMITED REMEDY. IN NO EVENT SHALL NVIDIA'S AGGREGATE LIABILITY TO DEVELOPER OR ANY OTHER PERSON OR ENTITY CLAIMING THROUGH OR UNDER DEVELOPER EXCEED THE AMOUNT OF MONEY ACTUALLY PAID BY DEVELOPER TO NVIDIA FOR THE SOFTWARE OR ANY OTHER MATERIALS. 26 | 27 | -------------------------------------------------------------------------------- /bin/media/newterrain/cloudy_noon_bk.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OGRECave/ogre-pagedgeometry/5776681bb56b63e9d2012c9eb0885608968b2d44/bin/media/newterrain/cloudy_noon_bk.jpg -------------------------------------------------------------------------------- /bin/media/newterrain/cloudy_noon_dn.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OGRECave/ogre-pagedgeometry/5776681bb56b63e9d2012c9eb0885608968b2d44/bin/media/newterrain/cloudy_noon_dn.jpg -------------------------------------------------------------------------------- /bin/media/newterrain/cloudy_noon_fr.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OGRECave/ogre-pagedgeometry/5776681bb56b63e9d2012c9eb0885608968b2d44/bin/media/newterrain/cloudy_noon_fr.jpg -------------------------------------------------------------------------------- /bin/media/newterrain/cloudy_noon_lf.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OGRECave/ogre-pagedgeometry/5776681bb56b63e9d2012c9eb0885608968b2d44/bin/media/newterrain/cloudy_noon_lf.jpg -------------------------------------------------------------------------------- /bin/media/newterrain/cloudy_noon_rt.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OGRECave/ogre-pagedgeometry/5776681bb56b63e9d2012c9eb0885608968b2d44/bin/media/newterrain/cloudy_noon_rt.jpg -------------------------------------------------------------------------------- /bin/media/newterrain/cloudy_noon_up.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OGRECave/ogre-pagedgeometry/5776681bb56b63e9d2012c9eb0885608968b2d44/bin/media/newterrain/cloudy_noon_up.jpg -------------------------------------------------------------------------------- /bin/media/newterrain/depthshadowobject.cg: -------------------------------------------------------------------------------- 1 | /* Copyright Torus Knot Software Ltd 2009 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | */ 21 | #include "shadows.cg" 22 | 23 | #define BIAS 0 24 | 25 | struct VS_OUT 26 | { 27 | float4 pos : POSITION; 28 | float3 diffuseUV : TEXCOORD0; // xy = UV, z = fog/depth 29 | #if !SHADOWCASTER 30 | float3 col : COLOR; 31 | #endif 32 | #if DEPTH_SHADOWCASTER 33 | float depth : TEXCOORD1; 34 | #endif 35 | #if DEPTH_SHADOWRECEIVER 36 | float4 lightSpacePos0 : TEXCOORD2; 37 | float4 lightSpacePos1 : TEXCOORD3; 38 | float4 lightSpacePos2 : TEXCOORD4; 39 | #endif 40 | }; 41 | 42 | VS_OUT main_vp( 43 | float4 pos : POSITION, 44 | float3 normal : NORMAL, 45 | float4 uv0 : TEXCOORD0, 46 | 47 | uniform float4x4 worldViewProj, 48 | uniform float4 lightPosition, 49 | uniform float3 lightDiffuse 50 | #if FOG 51 | , uniform float2 fogParams // x = fog start, y = fog distance 52 | #endif 53 | #if DEPTH_SHADOWCASTER 54 | , uniform float4 depthRange // x = min, y = max, z = range, w = 1/range 55 | #elif DEPTH_SHADOWRECEIVER 56 | , uniform float4 depthRange0 // x = min, y = max, z = range, w = 1/range 57 | , uniform float4 depthRange1 // x = min, y = max, z = range, w = 1/range 58 | , uniform float4 depthRange2 // x = min, y = max, z = range, w = 1/range 59 | #endif 60 | #if DEPTH_SHADOWRECEIVER 61 | , uniform float4x4 texWorldViewProjMatrix0 62 | , uniform float4x4 texWorldViewProjMatrix1 63 | , uniform float4x4 texWorldViewProjMatrix2 64 | #endif 65 | 66 | ) 67 | { 68 | VS_OUT outp; 69 | 70 | // project position to the screen 71 | outp.pos = mul(worldViewProj, pos); 72 | 73 | #if !SHADOWCASTER 74 | // Get object space light direction 75 | float3 lightDir = normalize(lightPosition.xyz - (pos.xyz * lightPosition.w).xyz); 76 | outp.col = lightDiffuse.xyz * max(dot(lightDir, normal.xyz), 0.0); 77 | # if FOG 78 | outp.diffuseUV.z = linearFog(outp.pos.z, fogParams.x, fogParams.y); 79 | # endif 80 | 81 | #endif 82 | 83 | // pass through other texcoords exactly as they were received 84 | outp.diffuseUV.xy = uv0.xy; 85 | 86 | 87 | #if DEPTH_SHADOWCASTER 88 | outp.depth = (BIAS + outp.pos.z - depthRange.x) * depthRange.w; 89 | #endif 90 | 91 | #if DEPTH_SHADOWRECEIVER 92 | // Calculate the position of vertex in light space 93 | outp.lightSpacePos0 = mul(texWorldViewProjMatrix0, pos); 94 | outp.lightSpacePos1 = mul(texWorldViewProjMatrix1, pos); 95 | outp.lightSpacePos2 = mul(texWorldViewProjMatrix2, pos); 96 | 97 | // make linear 98 | outp.lightSpacePos0.z = (outp.lightSpacePos0.z - depthRange0.x) * depthRange0.w; 99 | outp.lightSpacePos1.z = (outp.lightSpacePos1.z - depthRange1.x) * depthRange1.w; 100 | outp.lightSpacePos2.z = (outp.lightSpacePos2.z - depthRange2.x) * depthRange2.w; 101 | 102 | // pass cam depth 103 | outp.diffuseUV.z = outp.pos.z; 104 | 105 | #endif 106 | 107 | return outp; 108 | } 109 | 110 | 111 | float4 main_fp( 112 | VS_OUT In, 113 | 114 | uniform sampler2D diffuseMap : register(s0), 115 | #if DEPTH_SHADOWRECEIVER 116 | uniform sampler2D shadowMap0 : register(s1), 117 | uniform sampler2D shadowMap1 : register(s2), 118 | uniform sampler2D shadowMap2 : register(s3), 119 | #endif 120 | 121 | uniform float3 materialAmbient 122 | 123 | #if SHADOWCASTER 124 | , uniform float3 shadowColour 125 | #endif 126 | #if FOG 127 | , uniform float3 fogColour 128 | #endif 129 | #if DEPTH_SHADOWRECEIVER 130 | , uniform float inverseShadowmapSize0 131 | , uniform float inverseShadowmapSize1 132 | , uniform float inverseShadowmapSize2 133 | , uniform float4 pssmSplitPoints 134 | #endif 135 | 136 | ) : COLOR 137 | { 138 | 139 | // look up the diffuse map layer 140 | float4 texDiffuse = tex2D(diffuseMap, In.diffuseUV.xy); 141 | 142 | #if SHADOWCASTER 143 | # if DEPTH_SHADOWCASTER 144 | // early-out with depth (we still include alpha for those cards that support it) 145 | return float4(In.depth.xxx, 1); 146 | # else 147 | return float4(shadowColour.xyz, texDiffuse.a); 148 | # endif 149 | 150 | #else 151 | // compute the ambient contribution (pulled from the diffuse map) 152 | float3 vAmbient = texDiffuse.xyz * materialAmbient.xyz; 153 | float3 vColor3 = texDiffuse.rgb * In.col.rgb; 154 | 155 | # if DEPTH_SHADOWRECEIVER 156 | float camDepth = In.diffuseUV.z; 157 | float shadow = calcPSSMDepthShadow(shadowMap0, shadowMap1, shadowMap2, 158 | In.lightSpacePos0, In.lightSpacePos1, In.lightSpacePos2, 159 | inverseShadowmapSize0, inverseShadowmapSize1, inverseShadowmapSize2, 160 | pssmSplitPoints, camDepth); 161 | vColor3 *= shadow; 162 | /* 163 | vAmbient = float3(0,0,0); 164 | vColor3 = calcPSSMDebugShadow(shadowMap0, shadowMap1, shadowMap2, 165 | In.lightSpacePos0, In.lightSpacePos1, In.lightSpacePos2, 166 | inverseShadowmapSize0, inverseShadowmapSize1, inverseShadowmapSize2, 167 | pssmSplitPoints, camDepth); 168 | */ 169 | # endif 170 | 171 | float4 vColor; 172 | vColor = float4(vColor3 + vAmbient, texDiffuse.a); 173 | 174 | # if FOG 175 | // if fog is active, interpolate between the unfogged color and the fog color 176 | // based on vertex shader fog value 177 | vColor.rgb = lerp(vColor.rgb, fogColour, In.diffuseUV.z).rgb; 178 | # endif 179 | 180 | return vColor; 181 | #endif 182 | 183 | } 184 | 185 | 186 | -------------------------------------------------------------------------------- /bin/media/newterrain/dirt_grayrocky_diffusespecular.dds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OGRECave/ogre-pagedgeometry/5776681bb56b63e9d2012c9eb0885608968b2d44/bin/media/newterrain/dirt_grayrocky_diffusespecular.dds -------------------------------------------------------------------------------- /bin/media/newterrain/dirt_grayrocky_normalheight.dds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OGRECave/ogre-pagedgeometry/5776681bb56b63e9d2012c9eb0885608968b2d44/bin/media/newterrain/dirt_grayrocky_normalheight.dds -------------------------------------------------------------------------------- /bin/media/newterrain/early_morning_bk.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OGRECave/ogre-pagedgeometry/5776681bb56b63e9d2012c9eb0885608968b2d44/bin/media/newterrain/early_morning_bk.jpg -------------------------------------------------------------------------------- /bin/media/newterrain/early_morning_dn.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OGRECave/ogre-pagedgeometry/5776681bb56b63e9d2012c9eb0885608968b2d44/bin/media/newterrain/early_morning_dn.jpg -------------------------------------------------------------------------------- /bin/media/newterrain/early_morning_fr.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OGRECave/ogre-pagedgeometry/5776681bb56b63e9d2012c9eb0885608968b2d44/bin/media/newterrain/early_morning_fr.jpg -------------------------------------------------------------------------------- /bin/media/newterrain/early_morning_lf.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OGRECave/ogre-pagedgeometry/5776681bb56b63e9d2012c9eb0885608968b2d44/bin/media/newterrain/early_morning_lf.jpg -------------------------------------------------------------------------------- /bin/media/newterrain/early_morning_rt.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OGRECave/ogre-pagedgeometry/5776681bb56b63e9d2012c9eb0885608968b2d44/bin/media/newterrain/early_morning_rt.jpg -------------------------------------------------------------------------------- /bin/media/newterrain/early_morning_up.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OGRECave/ogre-pagedgeometry/5776681bb56b63e9d2012c9eb0885608968b2d44/bin/media/newterrain/early_morning_up.jpg -------------------------------------------------------------------------------- /bin/media/newterrain/fw12b.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OGRECave/ogre-pagedgeometry/5776681bb56b63e9d2012c9eb0885608968b2d44/bin/media/newterrain/fw12b.jpg -------------------------------------------------------------------------------- /bin/media/newterrain/grass.material: -------------------------------------------------------------------------------- 1 | // old 2 | material grass 3 | { 4 | //transparency_casts_shadows off 5 | receive_shadows on 6 | technique 7 | { 8 | pass 9 | { 10 | //ambient 0.9 0.9 0.9 1 11 | //diffuse 0.7 0.7 0.7 1 12 | //specular 0.5 0.5 0.5 1 32 13 | lighting off 14 | 15 | cull_hardware none 16 | //cull_software none 17 | 18 | scene_blend alpha_blend 19 | alpha_rejection greater_equal 128 20 | //transparency_casts_shadows off 21 | //depth_write off 22 | 23 | texture_unit 24 | { 25 | texture grass2.png 26 | } 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /bin/media/newterrain/grass_green-01_diffusespecular.dds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OGRECave/ogre-pagedgeometry/5776681bb56b63e9d2012c9eb0885608968b2d44/bin/media/newterrain/grass_green-01_diffusespecular.dds -------------------------------------------------------------------------------- /bin/media/newterrain/grass_green-01_normalheight.dds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OGRECave/ogre-pagedgeometry/5776681bb56b63e9d2012c9eb0885608968b2d44/bin/media/newterrain/grass_green-01_normalheight.dds -------------------------------------------------------------------------------- /bin/media/newterrain/growth_weirdfungus-03_diffusespecular.dds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OGRECave/ogre-pagedgeometry/5776681bb56b63e9d2012c9eb0885608968b2d44/bin/media/newterrain/growth_weirdfungus-03_diffusespecular.dds -------------------------------------------------------------------------------- /bin/media/newterrain/growth_weirdfungus-03_normalheight.dds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OGRECave/ogre-pagedgeometry/5776681bb56b63e9d2012c9eb0885608968b2d44/bin/media/newterrain/growth_weirdfungus-03_normalheight.dds -------------------------------------------------------------------------------- /bin/media/newterrain/new_terrain.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OGRECave/ogre-pagedgeometry/5776681bb56b63e9d2012c9eb0885608968b2d44/bin/media/newterrain/new_terrain.png -------------------------------------------------------------------------------- /bin/media/newterrain/new_terrain_detail.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OGRECave/ogre-pagedgeometry/5776681bb56b63e9d2012c9eb0885608968b2d44/bin/media/newterrain/new_terrain_detail.jpg -------------------------------------------------------------------------------- /bin/media/newterrain/new_terrain_texture.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OGRECave/ogre-pagedgeometry/5776681bb56b63e9d2012c9eb0885608968b2d44/bin/media/newterrain/new_terrain_texture.jpg -------------------------------------------------------------------------------- /bin/media/newterrain/pssm.material: -------------------------------------------------------------------------------- 1 | material PSSM/shadow_caster 2 | { 3 | technique 4 | { 5 | pass 6 | { 7 | } 8 | } 9 | } -------------------------------------------------------------------------------- /bin/media/newterrain/sky.material: -------------------------------------------------------------------------------- 1 | material Examples/CloudyNoonSkyBox 2 | { 3 | technique 4 | { 5 | pass 6 | { 7 | lighting off 8 | depth_write off 9 | 10 | texture_unit 11 | { 12 | cubic_texture cloudy_noon.jpg separateUV 13 | tex_address_mode clamp 14 | } 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /bin/media/newterrain/tudorhouse.material: -------------------------------------------------------------------------------- 1 | material Examples/TudorHouse 2 | { 3 | technique 4 | { 5 | pass 6 | { 7 | texture_unit 8 | { 9 | texture fw12b.jpg 10 | tex_address_mode clamp 11 | } 12 | } 13 | } 14 | } -------------------------------------------------------------------------------- /bin/media/newterrain/tudorhouse.mesh: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OGRECave/ogre-pagedgeometry/5776681bb56b63e9d2012c9eb0885608968b2d44/bin/media/newterrain/tudorhouse.mesh -------------------------------------------------------------------------------- /bin/media/shaders/BatchPage_vp.glsl: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | uniform mat4 worldViewProj; 4 | 5 | #ifdef LIGHTING 6 | uniform vec4 objSpaceLight; 7 | uniform vec4 lightDiffuse; 8 | uniform vec4 lightAmbient; 9 | #endif 10 | 11 | #ifdef FADE 12 | uniform vec3 camPos; 13 | uniform float fadeGap; 14 | uniform float invisibleDist; 15 | #endif 16 | 17 | #ifdef ANIMATE 18 | uniform float time; 19 | #endif 20 | 21 | 22 | MAIN_PARAMETERS 23 | 24 | IN(vec4 vertex, POSITION) 25 | IN(vec3 normal, NORMAL) 26 | #ifdef VERTEXCOLOUR 27 | IN(vec4 colour, COLOR) 28 | #endif 29 | 30 | IN(vec4 uv0, TEXCOORD0) 31 | #ifdef ANIMATE 32 | IN(vec4 uv1, TEXCOORD1) 33 | IN(vec4 uv2, TEXCOORD2) 34 | #endif 35 | 36 | 37 | OUT(vec4 oUV, TEXCOORD0) 38 | OUT(vec4 oColour, COLOR) 39 | OUT(float oFogCoord, FOG) 40 | MAIN_DECLARATION 41 | { 42 | #ifdef LIGHTING 43 | //Perform lighting calculations (no specular) 44 | vec3 light = normalize(objSpaceLight.xyz - (vertex.xyz * objSpaceLight.w)); 45 | float diffuseFactor = max(dot(normal, light), 0.0); 46 | # ifdef VERTEXCOLOUR 47 | oColour = (lightAmbient + diffuseFactor * lightDiffuse) * colour; 48 | # else 49 | oColour = (lightAmbient + diffuseFactor * lightDiffuse); 50 | # endif 51 | #else 52 | # ifdef VERTEXCOLOUR 53 | oColour = colour; 54 | # else 55 | oColour = vec4(1.0, 1.0, 1.0, 1.0); 56 | # endif 57 | #endif 58 | 59 | #ifdef FADE 60 | //Fade out in the distance 61 | float dist = distance(camPos.xz, vertex.xz); 62 | oColour.a *= (invisibleDist - dist) / fadeGap; 63 | #endif 64 | 65 | oUV = uv0; 66 | vec4 tmpPos = vertex; 67 | #ifdef ANIMATE 68 | vec4 params = uv1; 69 | vec4 originPos = uv2; 70 | 71 | float radiusCoeff = params.x; 72 | float heightCoeff = params.y; 73 | float factorX = params.z; 74 | float factorY = params.w; 75 | 76 | /* 77 | 2 different methods are used to for the sin calculation : 78 | - the first one gives a better effect but at the cost of a few fps because of the 2 sines 79 | - the second one uses less ressources but is a bit less realistic 80 | 81 | a sin approximation could be use to optimize performances 82 | */ 83 | # if 1 84 | tmpPos.y += sin(time + originPos.z + tmpPos.y + tmpPos.x) * radiusCoeff * radiusCoeff * factorY; 85 | tmpPos.x += sin(time + originPos.z ) * heightCoeff * heightCoeff * factorX; 86 | # else 87 | float sinval = sin(time + originPos.z ); 88 | tmpPos.y += sinval * radiusCoeff * radiusCoeff * factorY; 89 | tmpPos.x += sinval * heightCoeff * heightCoeff * factorX; 90 | # endif 91 | #endif 92 | 93 | gl_Position = mul(worldViewProj, tmpPos); 94 | oFogCoord = gl_Position.z; 95 | } -------------------------------------------------------------------------------- /bin/media/shaders/Default_fp.glsl: -------------------------------------------------------------------------------- 1 | #define USE_OGRE_FROM_FUTURE 2 | #include 3 | 4 | SAMPLER2D(texMap, 0); 5 | 6 | uniform vec4 fogColour; 7 | uniform vec4 fogParams; 8 | 9 | MAIN_PARAMETERS 10 | IN(vec4 oUV, TEXCOORD0) 11 | IN(vec4 oColour, COLOR) 12 | IN(float oFogCoord, FOG) 13 | MAIN_DECLARATION 14 | { 15 | gl_FragColor = texture2D(texMap, oUV.xy); 16 | #ifdef ALPHA_TEST 17 | if(gl_FragColor.a < 0.5 || oColour.a < 0.5) 18 | discard; 19 | #endif 20 | gl_FragColor *= saturate(oColour); 21 | #ifdef USE_FOG 22 | float fogf = saturate((fogParams.z - abs(oFogCoord)) * fogParams.w); 23 | gl_FragColor.rgb = mix(fogColour.rgb, gl_FragColor.rgb, fogf); 24 | #endif 25 | } 26 | -------------------------------------------------------------------------------- /bin/media/shaders/Grass_vp.glsl: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #ifdef LIGHTING 4 | uniform vec4 objSpaceLight; 5 | uniform vec4 lightDiffuse; 6 | uniform vec4 lightAmbient; 7 | #endif 8 | 9 | #ifdef ANIMATE 10 | uniform float time; 11 | uniform float frequency; 12 | uniform vec4 direction; 13 | #endif 14 | 15 | #ifdef FADETECH_GROW 16 | uniform float grassHeight; 17 | #endif 18 | 19 | uniform mat4 worldViewProj; 20 | uniform vec3 camPos; 21 | uniform float fadeRange; 22 | 23 | MAIN_PARAMETERS 24 | 25 | IN(vec4 vertex, POSITION) 26 | #ifdef GRASSTECH_SPRITE 27 | IN(vec4 normal, NORMAL) 28 | #endif 29 | IN(vec4 colour, COLOR) 30 | IN(vec4 uv0, TEXCOORD0) 31 | 32 | OUT(vec4 oUV, TEXCOORD0) 33 | OUT(vec4 oColour, COLOR) 34 | OUT(float oFogCoord, FOG) 35 | 36 | MAIN_DECLARATION 37 | { 38 | vec4 color = colour; 39 | vec4 position = vertex; 40 | float dist = distance(camPos.xz, position.xz); 41 | 42 | #ifdef LIGHTING 43 | vec3 light = normalize(objSpaceLight.xyz - (vertex.xyz * objSpaceLight.w)); 44 | float diffuseFactor = max( dot( vec3(0.0,1.0,0.0), light), 0.0); 45 | color = (lightAmbient + diffuseFactor * lightDiffuse) * colour; 46 | #endif 47 | 48 | #ifdef FADETECH_ALPHA 49 | //Fade out in the distance 50 | color.w = 2.0 - (2.0 * dist / fadeRange); 51 | #else 52 | color.w = 1.0; 53 | #endif 54 | 55 | #ifdef GRASSTECH_SPRITE 56 | //Face the camera 57 | vec3 dirVec = position.xyz - camPos.xyz; 58 | vec3 p = normalize(cross(vec3(0.0,1.0,0.0), dirVec)); 59 | position += vec4(p.x * normal.x, normal.y, p.z * normal.x, 0.0); 60 | #endif 61 | 62 | #ifdef ANIMATE 63 | if (uv0.y == 0.0) 64 | { 65 | //Wave grass in breeze 66 | position += direction * sin(time + vertex.x * frequency); 67 | } 68 | #endif 69 | 70 | #if defined(BLEND) && defined(ANIMATE) 71 | else 72 | { 73 | #elif defined(BLEND) 74 | if (uv0.y != 0.0) 75 | { 76 | #endif 77 | #ifdef BLEND 78 | //Blend the base of nearby grass into the terrain 79 | color.w = clamp(color.w, 0.0, 1.0) * 4.0 * ((dist / fadeRange) - 0.1); 80 | } 81 | #endif 82 | 83 | #ifdef FADETECH_GROW 84 | position.y -= grassHeight * clamp((2.0 * dist / fadeRange) - 1.0, 0.0, 1.0); 85 | #endif 86 | 87 | gl_Position = mul(worldViewProj, position); 88 | oColour = color; 89 | oUV = uv0; 90 | oFogCoord = gl_Position.z; 91 | } -------------------------------------------------------------------------------- /bin/media/shaders/PagedGeometry.program: -------------------------------------------------------------------------------- 1 | // First shader, simple camera-alignment 2 | vertex_program Sprite_vp glsl glsles hlsl 3 | { 4 | source Sprite_vp.glsl 5 | default_params 6 | { 7 | param_named_auto worldViewProj worldviewproj_matrix 8 | } 9 | } 10 | 11 | // Second shader, camera alignment and distance based fading 12 | vertex_program SpriteFade_vp glsl glsles hlsl 13 | { 14 | source Sprite_vp.glsl 15 | preprocessor_defines FADE 16 | default_params 17 | { 18 | param_named_auto worldViewProj worldviewproj_matrix 19 | param_named_auto camPos camera_position_object_space 20 | } 21 | } 22 | 23 | // Default pixel shader 24 | fragment_program Default_AlphaTest glsl glsles hlsl 25 | { 26 | source Default_fp.glsl 27 | preprocessor_defines USE_FOG,ALPHA_TEST 28 | default_params 29 | { 30 | param_named_auto fogColour fog_colour 31 | param_named_auto fogParams fog_params 32 | } 33 | } 34 | 35 | fragment_program Default_AlphaTest_NoFog glsl glsles hlsl 36 | { 37 | source Default_fp.glsl 38 | preprocessor_defines ALPHA_TEST 39 | } 40 | -------------------------------------------------------------------------------- /bin/media/shaders/Sprite_vp.glsl: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | uniform mat4 worldViewProj; 4 | #ifdef FADE 5 | uniform vec3 camPos; 6 | uniform float fadeGap; 7 | uniform float invisibleDist; 8 | #endif 9 | uniform float uScroll; 10 | uniform float vScroll; 11 | uniform vec4 preRotatedQuad[4]; 12 | 13 | MAIN_PARAMETERS 14 | 15 | IN(vec4 vertex, POSITION) 16 | IN(vec4 normal, NORMAL) 17 | IN(vec4 colour, COLOR) 18 | IN(vec4 uv0, TEXCOORD0) 19 | 20 | OUT(vec4 oUV, TEXCOORD0) 21 | OUT(vec4 oColour, COLOR) 22 | OUT(float oFogCoord, FOG) 23 | 24 | MAIN_DECLARATION 25 | { 26 | //Face the camera 27 | vec4 vCenter = vec4( vertex.x, vertex.y, vertex.z, 1.0 ); 28 | vec4 vScale = vec4( normal.x, normal.y, normal.x , 1.0 ); 29 | gl_Position = mul(worldViewProj, vCenter + (preRotatedQuad[int(normal.z)] * vScale) ); 30 | 31 | //Color 32 | oColour = colour; 33 | 34 | //Fade out in the distance 35 | #ifdef FADE 36 | vec4 position = vertex; 37 | float dist = distance(camPos.xz, position.xz); 38 | oColour.w = (invisibleDist - dist) / fadeGap; 39 | #endif 40 | 41 | //UV scroll 42 | oUV = uv0; 43 | oUV.x += uScroll; 44 | oUV.y += vScroll; 45 | 46 | //Fog 47 | oFogCoord = gl_Position.z; 48 | } -------------------------------------------------------------------------------- /bin/media/terrain2/densitymap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OGRECave/ogre-pagedgeometry/5776681bb56b63e9d2012c9eb0885608968b2d44/bin/media/terrain2/densitymap.png -------------------------------------------------------------------------------- /bin/media/terrain2/terrain.cfg: -------------------------------------------------------------------------------- 1 | # The main world texture (if you wish the terrain manager to create a material for you) 2 | WorldTexture=terrain_texture.jpg 3 | 4 | # The detail texture (if you wish the terrain manager to create a material for you) 5 | DetailTexture=terrain_detail0.jpg 6 | 7 | #number of times the detail texture will tile in a terrain tile 8 | DetailTile=5 9 | 10 | # Heightmap source 11 | PageSource=Heightmap 12 | 13 | # Heightmap-source specific settings 14 | Heightmap.image=terrain.png 15 | 16 | # If you use RAW, fill in the below too 17 | # RAW-specific setting - size (horizontal/vertical) 18 | #Heightmap.raw.size=513 19 | # RAW-specific setting - bytes per pixel (1 = 8bit, 2=16bit) 20 | #Heightmap.raw.bpp=2 21 | 22 | # How large is a page of tiles (in vertices)? Must be (2^n)+1 23 | PageSize=513 24 | 25 | # How large is each tile? Must be (2^n)+1 and be smaller than PageSize 26 | TileSize=65 27 | 28 | # The maximum error allowed when determining which LOD to use 29 | MaxPixelError=3 30 | 31 | # The size of a terrain page, in world units 32 | PageWorldX=1500 33 | PageWorldZ=1500 34 | # Maximum height of the terrain 35 | MaxHeight=100 36 | 37 | # Upper LOD limit 38 | MaxMipMapLevel=5 39 | 40 | #VertexNormals=yes 41 | #VertexColors=yes 42 | #UseTriStrips=yes 43 | 44 | # Use vertex program to morph LODs, if available 45 | VertexProgramMorph=yes 46 | 47 | # The proportional distance range at which the LOD morph starts to take effect 48 | # This is as a proportion of the distance between the current LODs effective range, 49 | # and the effective range of the next lower LOD 50 | LODMorphStart=0.2 51 | 52 | # This following section is for if you want to provide your own terrain shading routine 53 | # Note that since you define your textures within the material this makes the 54 | # WorldTexture and DetailTexture settings redundant 55 | 56 | # The name of the vertex program parameter you wish to bind the morph LOD factor to 57 | # this is 0 when there is no adjustment (highest) to 1 when the morph takes it completely 58 | # to the same position as the next lower LOD 59 | # USE THIS IF YOU USE HIGH-LEVEL VERTEX PROGRAMS WITH LOD MORPHING 60 | #MorphLODFactorParamName=morphFactor 61 | 62 | # The index of the vertex program parameter you wish to bind the morph LOD factor to 63 | # this is 0 when there is no adjustment (highest) to 1 when the morph takes it completely 64 | # to the same position as the next lower LOD 65 | # USE THIS IF YOU USE ASSEMBLER VERTEX PROGRAMS WITH LOD MORPHING 66 | #MorphLODFactorParamIndex=4 67 | 68 | # The name of the material you will define to shade the terrain 69 | #CustomMaterialName=TestTerrainMaterial 70 | 71 | 72 | -------------------------------------------------------------------------------- /bin/media/terrain2/terrain.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OGRECave/ogre-pagedgeometry/5776681bb56b63e9d2012c9eb0885608968b2d44/bin/media/terrain2/terrain.png -------------------------------------------------------------------------------- /bin/media/terrain2/terrain2.cfg: -------------------------------------------------------------------------------- 1 | # The main world texture (if you wish the terrain manager to create a material for you) 2 | WorldTexture=terrain_texture2.jpg 3 | 4 | # The detail texture (if you wish the terrain manager to create a material for you) 5 | DetailTexture=terrain_detail.jpg 6 | 7 | #number of times the detail texture will tile in a terrain tile 8 | DetailTile=5 9 | 10 | # Heightmap source 11 | PageSource=Heightmap 12 | 13 | # Heightmap-source specific settings 14 | Heightmap.image=terrain.png 15 | 16 | # If you use RAW, fill in the below too 17 | # RAW-specific setting - size (horizontal/vertical) 18 | #Heightmap.raw.size=513 19 | # RAW-specific setting - bytes per pixel (1 = 8bit, 2=16bit) 20 | #Heightmap.raw.bpp=2 21 | 22 | # How large is a page of tiles (in vertices)? Must be (2^n)+1 23 | PageSize=513 24 | 25 | # How large is each tile? Must be (2^n)+1 and be smaller than PageSize 26 | TileSize=65 27 | 28 | # The maximum error allowed when determining which LOD to use 29 | MaxPixelError=3 30 | 31 | # The size of a terrain page, in world units 32 | PageWorldX=1500 33 | PageWorldZ=1500 34 | # Maximum height of the terrain 35 | MaxHeight=100 36 | 37 | # Upper LOD limit 38 | MaxMipMapLevel=5 39 | 40 | #VertexNormals=yes 41 | #VertexColors=yes 42 | #UseTriStrips=yes 43 | 44 | # Use vertex program to morph LODs, if available 45 | VertexProgramMorph=yes 46 | 47 | # The proportional distance range at which the LOD morph starts to take effect 48 | # This is as a proportion of the distance between the current LODs effective range, 49 | # and the effective range of the next lower LOD 50 | LODMorphStart=0.2 51 | 52 | # This following section is for if you want to provide your own terrain shading routine 53 | # Note that since you define your textures within the material this makes the 54 | # WorldTexture and DetailTexture settings redundant 55 | 56 | # The name of the vertex program parameter you wish to bind the morph LOD factor to 57 | # this is 0 when there is no adjustment (highest) to 1 when the morph takes it completely 58 | # to the same position as the next lower LOD 59 | # USE THIS IF YOU USE HIGH-LEVEL VERTEX PROGRAMS WITH LOD MORPHING 60 | #MorphLODFactorParamName=morphFactor 61 | 62 | # The index of the vertex program parameter you wish to bind the morph LOD factor to 63 | # this is 0 when there is no adjustment (highest) to 1 when the morph takes it completely 64 | # to the same position as the next lower LOD 65 | # USE THIS IF YOU USE ASSEMBLER VERTEX PROGRAMS WITH LOD MORPHING 66 | #MorphLODFactorParamIndex=4 67 | 68 | # The name of the material you will define to shade the terrain 69 | #CustomMaterialName=TestTerrainMaterial 70 | 71 | 72 | -------------------------------------------------------------------------------- /bin/media/terrain2/terrain3.cfg: -------------------------------------------------------------------------------- 1 | # The main world texture (if you wish the terrain manager to create a material for you) 2 | WorldTexture=terrain_texture2.jpg 3 | 4 | # The detail texture (if you wish the terrain manager to create a material for you) 5 | DetailTexture=terrain_detail.jpg 6 | 7 | #number of times the detail texture will tile in a terrain tile 8 | DetailTile=5 9 | 10 | # Heightmap source 11 | PageSource=Heightmap 12 | 13 | # Heightmap-source specific settings 14 | Heightmap.image=terrain.png 15 | 16 | # If you use RAW, fill in the below too 17 | # RAW-specific setting - size (horizontal/vertical) 18 | #Heightmap.raw.size=513 19 | # RAW-specific setting - bytes per pixel (1 = 8bit, 2=16bit) 20 | #Heightmap.raw.bpp=2 21 | 22 | # How large is a page of tiles (in vertices)? Must be (2^n)+1 23 | PageSize=513 24 | 25 | # How large is each tile? Must be (2^n)+1 and be smaller than PageSize 26 | TileSize=65 27 | 28 | # The maximum error allowed when determining which LOD to use 29 | MaxPixelError=7 30 | 31 | # The size of a terrain page, in world units 32 | PageWorldX=1500 33 | PageWorldZ=1500 34 | # Maximum height of the terrain 35 | MaxHeight=50 36 | 37 | # Upper LOD limit 38 | MaxMipMapLevel=5 39 | 40 | #VertexNormals=yes 41 | #VertexColors=yes 42 | #UseTriStrips=yes 43 | 44 | # Use vertex program to morph LODs, if available 45 | VertexProgramMorph=yes 46 | 47 | # The proportional distance range at which the LOD morph starts to take effect 48 | # This is as a proportion of the distance between the current LODs effective range, 49 | # and the effective range of the next lower LOD 50 | LODMorphStart=0.2 51 | 52 | # This following section is for if you want to provide your own terrain shading routine 53 | # Note that since you define your textures within the material this makes the 54 | # WorldTexture and DetailTexture settings redundant 55 | 56 | # The name of the vertex program parameter you wish to bind the morph LOD factor to 57 | # this is 0 when there is no adjustment (highest) to 1 when the morph takes it completely 58 | # to the same position as the next lower LOD 59 | # USE THIS IF YOU USE HIGH-LEVEL VERTEX PROGRAMS WITH LOD MORPHING 60 | #MorphLODFactorParamName=morphFactor 61 | 62 | # The index of the vertex program parameter you wish to bind the morph LOD factor to 63 | # this is 0 when there is no adjustment (highest) to 1 when the morph takes it completely 64 | # to the same position as the next lower LOD 65 | # USE THIS IF YOU USE ASSEMBLER VERTEX PROGRAMS WITH LOD MORPHING 66 | #MorphLODFactorParamIndex=4 67 | 68 | # The name of the material you will define to shade the terrain 69 | #CustomMaterialName=TestTerrainMaterial 70 | 71 | 72 | -------------------------------------------------------------------------------- /bin/media/terrain2/terrain_detail.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OGRECave/ogre-pagedgeometry/5776681bb56b63e9d2012c9eb0885608968b2d44/bin/media/terrain2/terrain_detail.jpg -------------------------------------------------------------------------------- /bin/media/terrain2/terrain_detail0.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OGRECave/ogre-pagedgeometry/5776681bb56b63e9d2012c9eb0885608968b2d44/bin/media/terrain2/terrain_detail0.jpg -------------------------------------------------------------------------------- /bin/media/terrain2/terrain_lightmap.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OGRECave/ogre-pagedgeometry/5776681bb56b63e9d2012c9eb0885608968b2d44/bin/media/terrain2/terrain_lightmap.jpg -------------------------------------------------------------------------------- /bin/media/terrain2/terrain_texture.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OGRECave/ogre-pagedgeometry/5776681bb56b63e9d2012c9eb0885608968b2d44/bin/media/terrain2/terrain_texture.jpg -------------------------------------------------------------------------------- /bin/media/terrain2/terrain_texture2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OGRECave/ogre-pagedgeometry/5776681bb56b63e9d2012c9eb0885608968b2d44/bin/media/terrain2/terrain_texture2.jpg -------------------------------------------------------------------------------- /bin/media/trees/Bush.blend: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OGRECave/ogre-pagedgeometry/5776681bb56b63e9d2012c9eb0885608968b2d44/bin/media/trees/Bush.blend -------------------------------------------------------------------------------- /bin/media/trees/Bush.mesh: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OGRECave/ogre-pagedgeometry/5776681bb56b63e9d2012c9eb0885608968b2d44/bin/media/trees/Bush.mesh -------------------------------------------------------------------------------- /bin/media/trees/Leaves.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OGRECave/ogre-pagedgeometry/5776681bb56b63e9d2012c9eb0885608968b2d44/bin/media/trees/Leaves.png -------------------------------------------------------------------------------- /bin/media/trees/Pine1.mesh: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OGRECave/ogre-pagedgeometry/5776681bb56b63e9d2012c9eb0885608968b2d44/bin/media/trees/Pine1.mesh -------------------------------------------------------------------------------- /bin/media/trees/PineLeaves.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OGRECave/ogre-pagedgeometry/5776681bb56b63e9d2012c9eb0885608968b2d44/bin/media/trees/PineLeaves.png -------------------------------------------------------------------------------- /bin/media/trees/Tree0.blend: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OGRECave/ogre-pagedgeometry/5776681bb56b63e9d2012c9eb0885608968b2d44/bin/media/trees/Tree0.blend -------------------------------------------------------------------------------- /bin/media/trees/tree.material: -------------------------------------------------------------------------------- 1 | material SOLID/TEX/wood7.jpg 2 | { 3 | technique 4 | { 5 | pass 6 | { 7 | ambient 0.4 0.4 0.4 1 8 | diffuse 1 1 1 1 9 | 10 | scene_blend alpha_blend 11 | 12 | texture_unit 13 | { 14 | texture wood7.jpg 15 | } 16 | } 17 | } 18 | } 19 | 20 | material SOLID/TEX/Leaves.png 21 | { 22 | technique 23 | { 24 | pass 25 | { 26 | ambient 0.5 0.5 0.5 1 27 | diffuse 0.6 0.6 0.6 1 28 | 29 | cull_hardware none 30 | alpha_rejection greater_equal 128 31 | //scene_blend alpha_blend 32 | 33 | texture_unit 34 | { 35 | texture Leaves.png alpha 36 | } 37 | } 38 | } 39 | } 40 | 41 | material SOLID/TEX/PineLeaves.png 42 | { 43 | technique 44 | { 45 | pass 46 | { 47 | ambient 0.5 0.5 0.5 1 48 | diffuse 0.6 0.6 0.6 1 49 | 50 | cull_hardware none 51 | alpha_rejection greater_equal 128 52 | 53 | texture_unit 54 | { 55 | texture PineLeaves.png alpha 56 | } 57 | } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /bin/media/trees/tree.mesh: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OGRECave/ogre-pagedgeometry/5776681bb56b63e9d2012c9eb0885608968b2d44/bin/media/trees/tree.mesh -------------------------------------------------------------------------------- /bin/media/trees/tree2.mesh: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OGRECave/ogre-pagedgeometry/5776681bb56b63e9d2012c9eb0885608968b2d44/bin/media/trees/tree2.mesh -------------------------------------------------------------------------------- /bin/media/trees/wood7.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OGRECave/ogre-pagedgeometry/5776681bb56b63e9d2012c9eb0885608968b2d44/bin/media/trees/wood7.jpg -------------------------------------------------------------------------------- /bin/media/trees2/3d-diggers_fir.material: -------------------------------------------------------------------------------- 1 | 2 | material 3D-Diggers/fir01 3 | { 4 | technique Default 5 | { 6 | pass Main 7 | { 8 | ambient 0.5 0.5 0.5 1 9 | diffuse 0.6 0.6 0.6 1 10 | 11 | alpha_rejection greater_equal 128 12 | 13 | texture_unit 14 | { 15 | texture fir01.png alpha 16 | } 17 | } 18 | } 19 | } 20 | 21 | material 3D-Diggers/fir02 22 | { 23 | technique Default 24 | { 25 | pass Main 26 | { 27 | ambient 0.5 0.5 0.5 1 28 | diffuse 0.6 0.6 0.6 1 29 | 30 | texture_unit 31 | { 32 | texture_alias diffuse 33 | texture fir02.jpg -1 34 | } 35 | } 36 | } 37 | } -------------------------------------------------------------------------------- /bin/media/trees2/3ddsky_0001.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OGRECave/ogre-pagedgeometry/5776681bb56b63e9d2012c9eb0885608968b2d44/bin/media/trees2/3ddsky_0001.jpg -------------------------------------------------------------------------------- /bin/media/trees2/3ddsky_0002.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OGRECave/ogre-pagedgeometry/5776681bb56b63e9d2012c9eb0885608968b2d44/bin/media/trees2/3ddsky_0002.jpg -------------------------------------------------------------------------------- /bin/media/trees2/3ddsky_0003.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OGRECave/ogre-pagedgeometry/5776681bb56b63e9d2012c9eb0885608968b2d44/bin/media/trees2/3ddsky_0003.jpg -------------------------------------------------------------------------------- /bin/media/trees2/3ddsky_0004.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OGRECave/ogre-pagedgeometry/5776681bb56b63e9d2012c9eb0885608968b2d44/bin/media/trees2/3ddsky_0004.jpg -------------------------------------------------------------------------------- /bin/media/trees2/3ddsky_0005.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OGRECave/ogre-pagedgeometry/5776681bb56b63e9d2012c9eb0885608968b2d44/bin/media/trees2/3ddsky_0005.jpg -------------------------------------------------------------------------------- /bin/media/trees2/3ddsky_0006.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OGRECave/ogre-pagedgeometry/5776681bb56b63e9d2012c9eb0885608968b2d44/bin/media/trees2/3ddsky_0006.jpg -------------------------------------------------------------------------------- /bin/media/trees2/3ddsky_0007.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OGRECave/ogre-pagedgeometry/5776681bb56b63e9d2012c9eb0885608968b2d44/bin/media/trees2/3ddsky_0007.jpg -------------------------------------------------------------------------------- /bin/media/trees2/__ReadMe__.txt: -------------------------------------------------------------------------------- 1 | ////////////////////////////////////////////////////////// 2 | // "Veggies for the people" // 3 | // (c) 3D-Diggers 2008 // 4 | // Author: Christian Herzog // 5 | // Web: www.3d-diggers.de // 6 | ////////////////////////////////////////////////////////// 7 | 8 | +--------------------------------------------------------+ 9 | | License: | 10 | +--------------------------------------------------------+ 11 | "Do what you want" 12 | 13 | This is a free give away from the 3D-Diggers. 14 | You can use it in any project you want (commercial, non-commercial, etc.). 15 | 16 | 17 | I'd be happy though, if anybody using it, could send me a link to the project or so! (just to know IF this is actually being used... ;) ) 18 | But again, you don't have to. 19 | My email is Giggsy@gmx.at. 20 | 21 | If you want to see more, drop by on our homepage: www.3d-diggers.de. 22 | (you get the full fir pack there, which can easily be exported for OGRE as you can see) -------------------------------------------------------------------------------- /bin/media/trees2/farn01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OGRECave/ogre-pagedgeometry/5776681bb56b63e9d2012c9eb0885608968b2d44/bin/media/trees2/farn01.png -------------------------------------------------------------------------------- /bin/media/trees2/farn02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OGRECave/ogre-pagedgeometry/5776681bb56b63e9d2012c9eb0885608968b2d44/bin/media/trees2/farn02.png -------------------------------------------------------------------------------- /bin/media/trees2/farn1.mesh: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OGRECave/ogre-pagedgeometry/5776681bb56b63e9d2012c9eb0885608968b2d44/bin/media/trees2/farn1.mesh -------------------------------------------------------------------------------- /bin/media/trees2/farn1.mesh.material: -------------------------------------------------------------------------------- 1 | material 3D-Diggers/farn01 2 | { 3 | technique Default 4 | { 5 | pass Main 6 | { 7 | ambient 0.5 0.5 0.5 1 8 | diffuse 0.6 0.6 0.6 1 9 | 10 | alpha_rejection greater_equal 128 11 | 12 | texture_unit 13 | { 14 | texture farn01.png alpha 15 | } 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /bin/media/trees2/farn2.mesh: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OGRECave/ogre-pagedgeometry/5776681bb56b63e9d2012c9eb0885608968b2d44/bin/media/trees2/farn2.mesh -------------------------------------------------------------------------------- /bin/media/trees2/farn2.mesh.material: -------------------------------------------------------------------------------- 1 | material 3D-Diggers/farn02 2 | { 3 | technique Default 4 | { 5 | pass Main 6 | { 7 | ambient 0.5 0.5 0.5 1 8 | diffuse 0.6 0.6 0.6 1 9 | 10 | alpha_rejection greater_equal 128 11 | 12 | texture_unit 13 | { 14 | texture farn02.png alpha 15 | } 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /bin/media/trees2/fir01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OGRECave/ogre-pagedgeometry/5776681bb56b63e9d2012c9eb0885608968b2d44/bin/media/trees2/fir01.png -------------------------------------------------------------------------------- /bin/media/trees2/fir02.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OGRECave/ogre-pagedgeometry/5776681bb56b63e9d2012c9eb0885608968b2d44/bin/media/trees2/fir02.jpg -------------------------------------------------------------------------------- /bin/media/trees2/fir05_30.mesh: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OGRECave/ogre-pagedgeometry/5776681bb56b63e9d2012c9eb0885608968b2d44/bin/media/trees2/fir05_30.mesh -------------------------------------------------------------------------------- /bin/media/trees2/fir06_30.mesh: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OGRECave/ogre-pagedgeometry/5776681bb56b63e9d2012c9eb0885608968b2d44/bin/media/trees2/fir06_30.mesh -------------------------------------------------------------------------------- /bin/media/trees2/fir14_25.mesh: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OGRECave/ogre-pagedgeometry/5776681bb56b63e9d2012c9eb0885608968b2d44/bin/media/trees2/fir14_25.mesh -------------------------------------------------------------------------------- /bin/media/trees2/plant1.mesh: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OGRECave/ogre-pagedgeometry/5776681bb56b63e9d2012c9eb0885608968b2d44/bin/media/trees2/plant1.mesh -------------------------------------------------------------------------------- /bin/media/trees2/plant1.mesh.material: -------------------------------------------------------------------------------- 1 | material 3D-Diggers/plant1 2 | { 3 | technique Default 4 | { 5 | pass Main 6 | { 7 | ambient 0.5 0.5 0.5 1 8 | diffuse 0.6 0.6 0.6 1 9 | 10 | alpha_rejection greater_equal 128 11 | 12 | texture_unit 13 | { 14 | texture plant1.png alpha 15 | } 16 | } 17 | } 18 | } 19 | 20 | material 3D-Diggers/plant1sprite 21 | { 22 | technique Default 23 | { 24 | pass Main 25 | { 26 | cull_hardware none 27 | cull_software none 28 | 29 | ambient 0.5 0.5 0.5 1 30 | diffuse 0.6 0.6 0.6 1 31 | 32 | alpha_rejection greater_equal 128 33 | 34 | texture_unit 35 | { 36 | texture plant1.png alpha 37 | } 38 | } 39 | } 40 | } -------------------------------------------------------------------------------- /bin/media/trees2/plant1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OGRECave/ogre-pagedgeometry/5776681bb56b63e9d2012c9eb0885608968b2d44/bin/media/trees2/plant1.png -------------------------------------------------------------------------------- /bin/media/trees2/plant2.mesh: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OGRECave/ogre-pagedgeometry/5776681bb56b63e9d2012c9eb0885608968b2d44/bin/media/trees2/plant2.mesh -------------------------------------------------------------------------------- /bin/media/trees2/plant2.mesh.material: -------------------------------------------------------------------------------- 1 | material 3D-Diggers/plant2 2 | { 3 | technique Default 4 | { 5 | pass Main 6 | { 7 | ambient 0.5 0.5 0.5 1 8 | diffuse 0.6 0.6 0.6 1 9 | 10 | alpha_rejection greater_equal 128 11 | 12 | texture_unit 13 | { 14 | texture plant2.png alpha 15 | } 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /bin/media/trees2/plant2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OGRECave/ogre-pagedgeometry/5776681bb56b63e9d2012c9eb0885608968b2d44/bin/media/trees2/plant2.png -------------------------------------------------------------------------------- /bin/media/trees2/shroom1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OGRECave/ogre-pagedgeometry/5776681bb56b63e9d2012c9eb0885608968b2d44/bin/media/trees2/shroom1.png -------------------------------------------------------------------------------- /bin/media/trees2/shroom1_1.mesh: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OGRECave/ogre-pagedgeometry/5776681bb56b63e9d2012c9eb0885608968b2d44/bin/media/trees2/shroom1_1.mesh -------------------------------------------------------------------------------- /bin/media/trees2/shroom1_2.mesh: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OGRECave/ogre-pagedgeometry/5776681bb56b63e9d2012c9eb0885608968b2d44/bin/media/trees2/shroom1_2.mesh -------------------------------------------------------------------------------- /bin/media/trees2/shroom1_3.mesh: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OGRECave/ogre-pagedgeometry/5776681bb56b63e9d2012c9eb0885608968b2d44/bin/media/trees2/shroom1_3.mesh -------------------------------------------------------------------------------- /bin/media/trees2/shroom2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OGRECave/ogre-pagedgeometry/5776681bb56b63e9d2012c9eb0885608968b2d44/bin/media/trees2/shroom2.png -------------------------------------------------------------------------------- /bin/media/trees2/shroom2_1.mesh: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OGRECave/ogre-pagedgeometry/5776681bb56b63e9d2012c9eb0885608968b2d44/bin/media/trees2/shroom2_1.mesh -------------------------------------------------------------------------------- /bin/media/trees2/shroom2_2.mesh: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OGRECave/ogre-pagedgeometry/5776681bb56b63e9d2012c9eb0885608968b2d44/bin/media/trees2/shroom2_2.mesh -------------------------------------------------------------------------------- /bin/media/trees2/shroom2_3.mesh: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OGRECave/ogre-pagedgeometry/5776681bb56b63e9d2012c9eb0885608968b2d44/bin/media/trees2/shroom2_3.mesh -------------------------------------------------------------------------------- /bin/media/trees2/shrooms.material: -------------------------------------------------------------------------------- 1 | material 3D-Diggers/shroom1 2 | { 3 | technique Default 4 | { 5 | pass Main 6 | { 7 | ambient 0.5 0.5 0.5 1 8 | diffuse 0.6 0.6 0.6 1 9 | 10 | alpha_rejection greater_equal 128 11 | 12 | texture_unit 13 | { 14 | texture shroom1.png alpha 15 | } 16 | } 17 | } 18 | } 19 | 20 | material 3D-Diggers/shroom2 21 | { 22 | technique Default 23 | { 24 | pass Main 25 | { 26 | ambient 0.5 0.5 0.5 1 27 | diffuse 0.6 0.6 0.6 1 28 | 29 | alpha_rejection greater_equal 128 30 | 31 | texture_unit 32 | { 33 | texture shroom2.png alpha 34 | } 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /bin/media/trees2/skybox.material: -------------------------------------------------------------------------------- 1 | material 3D-Diggers/SkyBox 2 | { 3 | technique 4 | { 5 | pass 6 | { 7 | fog_override true none 8 | lighting off 9 | depth_write off 10 | 11 | texture_unit 12 | { 13 | cubic_texture 3ddsky_0001.jpg 3ddsky_0003.jpg 3ddsky_0004.jpg 3ddsky_0002.jpg 3ddsky_0005.jpg 3ddsky_0006.jpg separateUV 14 | tex_address_mode clamp 15 | } 16 | } 17 | } 18 | } -------------------------------------------------------------------------------- /bin/resources.cfg: -------------------------------------------------------------------------------- 1 | [General] 2 | FileSystem=media/shaders 3 | FileSystem=media/grass 4 | FileSystem=media/terrain2 5 | FileSystem=media/trees 6 | FileSystem=media/trees2 7 | FileSystem=media/newterrain 8 | -------------------------------------------------------------------------------- /docs/PagedGeometryScreen1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OGRECave/ogre-pagedgeometry/5776681bb56b63e9d2012c9eb0885608968b2d44/docs/PagedGeometryScreen1.jpg -------------------------------------------------------------------------------- /docs/Tutorial-2.md: -------------------------------------------------------------------------------- 1 | # Tutorial 2: Trees and Bushes {#tut2} 2 | 3 | 4 | # Introduction 5 | 6 | As you've seen in Lesson 1, once you know how to set up PagedGeometry, 7 | adding trees to your world is as easy as calling 8 | TreeLoader3D::addTree(). This tutorial expands on what you already know, 9 | and explains the fastest way to add trees and bushes to your scene. 10 | 11 | ## Tutorial Requirements 12 | 13 | - @ref tut1 14 | - A basic understanding of Ogre 15 | - Some experience using C++ 16 | 17 | See also 18 | 19 | - Example 3 - “Trees and Bushes” 20 | - Example 2 - “TreeLoader2D” 21 | 22 | 23 | # Level of Detail 24 | 25 | If you want, you can add trees, bushes, rocks, any pretty much anything 26 | you like to your scene using the PagedGeometry object from Lesson 1. But 27 | at a certain point you may find that even with all of PagedGeometry's 28 | batching and impostoring optimizations, the frame rate might not be as 29 | high as you like. 30 | 31 | Bushes, rocks, and other small ground details aren't nearly as important 32 | as trees in the distance. If you reduce the viewing range of this 33 | “ground clutter”, you'll get a considerable performance boost without 34 | much noticeable loss of visual quality. For example, if your trees are 35 | visible up to a half of a mile, your bushes / rocks / etc. may only need 36 | to be rendered up to one or two hundred yards. This way, you can include 37 | a high level of detail (bushes, rocks, etc.) in your scene without 38 | wasting too much time rendering them in the far distance. 39 | 40 | 41 | # Multiple View Ranges 42 | 43 | At this point you may be wondering how you're going to assign multiple 44 | view ranges to different types of entities, etc. Fortunately, there is a 45 | very easy way to achieve this: Create two instances of PagedGeometry - 46 | one is set up to render trees how you want, and the other is set up to 47 | render bushes how you want (with the closer view range). 48 | 49 | This is the tree setup code: 50 | 51 | ```cpp 52 | PagedGeometry *trees = new PagedGeometry(camera, 50); 53 | 54 | trees->addDetailLevel(150, 30); 55 | 56 | trees->addDetailLevel(400, 50); 57 | ``` 58 | 59 | This is basically the same as the code seen in Lesson 1, with a few 60 | changes: The camera and pageSize data is specified in the constructor, 61 | rather than being set through functions. Also, trees->setInfinite() 62 | was removed since infinite mode is already enabled by default. 63 | 64 | As you can see, the code sets up batches up to 150 units and impostors 65 | up to 400 units. While this should work fine for trees, the bushes won't 66 | need to be rendered this far, so another PagedGeometry object will be 67 | created for the sole purpose of rendering bushes/rocks/etc.: 68 | 69 | ```cpp 70 | PagedGeometry *bushes = new PagedGeometry(camera, 40); 71 | 72 | bushes->addDetailLevel(80, 20); 73 | 74 | bushes->addDetailLevel(160, 40); 75 | ``` 76 | 77 | Note that since this new PagedGeometry object (“bushes”) is independent 78 | from “trees”, you can set up the LODs completely differently if you 79 | like. In this case, BatchPage and ImpostorPage are still used, but the 80 | ranges are changed to roughly half of what the trees will be using. 81 | 82 | Now it's time to assign PageLoader's to the PagedGeometry objects. 83 | Obviously, each PagedGeometry object will need it's own PageLoader 84 | object so you can add your trees and bushes: 85 | 86 | ```cpp 87 | TreeLoader3D *treeLoader = new TreeLoader3D(trees, TBounds(0, 0, 1500, 88 | 1500)); 89 | 90 | trees->setPageLoader(treeLoader); 91 | 92 | TreeLoader3D *bushLoader = new TreeLoader3D(bushes, TBounds(0, 0, 1500, 93 | 1500)); 94 | 95 | bushes->setPageLoader(bushLoader); 96 | ``` 97 | 98 | # Adding the Trees and Bushes 99 | 100 | At this point you should add all your trees to treeLoader, all your 101 | bushes to bushLoader, and your scene should be ready to go. The 102 | following code randomely places trees and bushes, but is of course for 103 | demonstration purposes (normally you'd use a level editor of some sort 104 | to place them): 105 | 106 | ```cpp 107 | Entity *myTree = sceneMgr->createEntity("MyTree", "tree.mesh"); 108 | 109 | Entity *myBush = sceneMgr->createEntity("MyBush", "bush.mesh"); 110 | 111 | //Add trees 112 | 113 | float x = 0, y = 0, z = 0, yaw, scale; 114 | 115 | for (int i = 0; i < 10000; i++){ 116 | 117 | yaw = Math::RangeRandom(0, 360); 118 | 119 | if (Math::RangeRandom(0, 1) <= 0.8f){ 120 | 121 | //Clump trees together occasionally 122 | 123 | x += Math::RangeRandom(-10.0f, 10.0f); 124 | 125 | z += Math::RangeRandom(-10.0f, 10.0f); 126 | 127 | if (x < 0) x = 0; else if (x > 1500) x = 1500; 128 | 129 | if (z < 0) z = 0; else if (z > 1500) z = 1500; 130 | 131 | } else { 132 | 133 | x = Math::RangeRandom(0, 1500); 134 | 135 | z = Math::RangeRandom(0, 1500); 136 | 137 | } 138 | 139 | y = getTerrainHeight(x, z); 140 | 141 | scale = Math::RangeRandom(0.9f, 1.1f); 142 | 143 | treeLoader->addTree(myTree, Vector3(x, y, z), Degree(yaw), scale); 144 | 145 | } 146 | 147 | //Add bushes 148 | 149 | float x = 0, y = 0, z = 0, yaw, scale; 150 | 151 | for (int i = 0; i < 20000; i++){ 152 | 153 | yaw = Math::RangeRandom(0, 360); 154 | 155 | if (Math::RangeRandom(0, 1) <= 0.3f){ 156 | 157 | //Clump bushes together occasionally 158 | 159 | x += Math::RangeRandom(-10.0f, 10.0f); 160 | 161 | z += Math::RangeRandom(-10.0f, 10.0f); 162 | 163 | if (x < 0) x = 0; else if (x > 1500) x = 1500; 164 | 165 | if (z < 0) z = 0; else if (z > 1500) z = 1500; 166 | 167 | } else { 168 | 169 | x = Math::RangeRandom(0, 1500); 170 | 171 | z = Math::RangeRandom(0, 1500); 172 | 173 | } 174 | 175 | y = getTerrainHeight(x, z); 176 | 177 | scale = Math::RangeRandom(0.9f, 1.1f); 178 | 179 | bushLoader->addTree(myBush, Vector3(x, y, z), Degree(yaw), scale); 180 | 181 | } 182 | ``` 183 | 184 | # Updating PagedGeometry 185 | 186 | And to finish, remember to call both trees->update() *and* 187 | bushes->update() every frame: 188 | 189 | ``` 190 | [each frame] 191 | 192 | { 193 | 194 | trees->update(); 195 | 196 | bushes->update(); 197 | 198 | } 199 | ``` 200 | 201 | # Optimizing 202 | 203 | Now you should have trees and bushes rendering in a fairly optimized 204 | setup. At this point it usually helps to play around with the page sizes 205 | and batching/impostoring view ranges. Try to find values that give the 206 | best possible performance without losing rendering quality. 207 | 208 | Optimizing Tips 209 | 210 | - Larger page sizes render more efficiently what is on the screen, but 211 | also causes more off-screen entities to be rendered. Depending on 212 | the volume and view range of your trees/bushes, decreasing or 213 | increasing the page size may give better performance. 214 | 215 | - Generally, you should adjust the batching range as low as possible 216 | without making the flatness of impostors obvious. However, 217 | excessively low batching ranges can actually run slower, since when 218 | impostors are rendered near the camera there can be more overdraw. 219 | 220 | - Once you have near-optimal FPS, try moving the camera around in 221 | your game. If high speed camera movement results in stuttering frame 222 | rates, then your page size may be too large. In this case, reduce 223 | the page size until the stuttering is no longer a problem. It may 224 | also help to enable bounded mode (PagedGeometry::setBounds()) 225 | 226 | # TreeLoader2D (Optional) 227 | 228 | You may notice in the example above in the "procedural" tree / bush 229 | placement code that GetTerrainHeight() is called to get the height of 230 | the terrain at any given x/z coordinate. Obviously, the height needs to 231 | be calculated this way so trees are placed on the terrain, not under it. 232 | 233 | If all your trees use "Y = getTerrainHeight(X, Z)" to calculate the 234 | height, you can save a good amount of memory by switching to 235 | TreeLoader2D (rather than TreeLoader3D). This version of TreeLoader3D 236 | ignores the vertical (Y) component of the position when you call 237 | addTree(), and instead calculates the Y value later from the X/Z values, 238 | using the function you provide. For example: 239 | 240 | ```cpp 241 | TreeLoader2D *treeLoader = new TreeLoader2D(trees, TBounds(0, 0, 1500, 242 | 1500)); 243 | 244 | trees->setPageLoader(treeLoader); 245 | 246 | treeLoader->setHeightFunction(&getTerrainHeight); 247 | 248 | treeLoader->addTree(myEntity, Vector2(x, 0, z), yaw, scale); 249 | ``` 250 | 251 | TreeLoader2D is basically identical to TreeLoader3D, except 252 | setHeightFunction() is used to supply TreeLoader2D with your function 253 | that will be used to calculate the Y coordinates of each tree (from the 254 | X and Z coordinates), and addTree() ignores the Y component of the 255 | position you supply. 256 | 257 | # Conclusion 258 | 259 | Adding trees, bushes, rockes, and many other details to your game world 260 | is very easy, but acheiving good frame rates often takes a little 261 | tweaking. Fortunately, PagedGeometry makes it easy to configure LODs and 262 | view ranges in almost any way, allowing you to effeciently render vast 263 | forests and jungles with dense brush and vegetation. 264 | 265 | In the examples folder, you can get a full working example of what you 266 | learned in this tutorial by opening the "Example 3 – Trees and Bushes" 267 | project. 268 | -------------------------------------------------------------------------------- /docs/Tutorial-3.md: -------------------------------------------------------------------------------- 1 | # Tutorial 3: Grass and Shadows {#tut3} 2 | 3 | # Introduction 4 | 5 | At this point you should be fairly familiar with the basic use of 6 | PagedGeometry to add trees and bushes to your world. Now it's time to 7 | add some grass. This tutorial explains the use of PagedGeometry's 8 | GrassLoader module to add animated grass to your scene, and how to apply 9 | shadows (lightmaps) to your grass and trees to greatly improve the 10 | graphical realism. 11 | 12 | ## Tutorial Requirements 13 | 14 | - @ref tut1 (\#2 also recommended) 15 | - A basic understanding of Ogre 16 | - Some experience using C++ 17 | 18 | See also 19 | 20 | - Example 4 - “GrassLoader” 21 | - Example 7 - “Lightmaps” 22 | 23 | 24 | # GrassLoader 25 | 26 | GrassLoader, like TreeLoader2D and TreeLoader3D, is a module that 27 | provides the core engine with the geometry you want rendered. Using one 28 | of the TreeLoader classes to add grass would be extremely tedious and 29 | inefficient, since each blade or clump of grass would need to be added 30 | individually. For this reason, GrassLoader exists to provide you an easy 31 | to use, efficient grass renderer. 32 | 33 | It is important to note that GrassLoader differs in two significant ways 34 | from the other PageLoader's: 35 | 36 | 1. You can't use ImpostorPage to display grass. Since grass is 37 | displayed using many small non camera-aligned billboards, it's 38 | already as optimized as possible, geometrically. Attempting to use 39 | impostors for grass will result in a lot of impostor rendering, a 40 | lot of wasted memory, and a lot of lag when loading new pages. You 41 | should use either BatchPage, or preferably “GrassPage” to display 42 | grass, the latter being the most optimized. 43 | 44 | 2. Fade transitions are always used on grass, and do not cost 45 | any performance. When configuring the PagedGeometry object used to 46 | render your grass, do *not *enable transitions yourself. Doing this 47 | will only reduce performance unnecessarily. 48 | 49 | 50 | # Creating Grass 51 | 52 | To add grass to your world, you start by creating a PagedGeometry 53 | object, as always: 54 | 55 | ```cpp 56 | PagedGeometry *grass = new PagedGeometry(camera, 50); 57 | ``` 58 | 59 | But this time, instead of adding the usual BatchPage and ImpostorPage 60 | combination that works well for trees, GrassPage will be used: 61 | 62 | ```cpp 63 | grass->addDetailLevel(100);//Draw grass up to 100 64 | units away 65 | ``` 66 | 67 | GrassPage is the most effecient LOD to use when displaying grass, and 68 | should be used exclusively for this purpose (in other words, it's *not* 69 | effecient for displaying trees). 70 | 71 | Next, setup a new GrassLoader instance to be used with this 72 | PagedGeometry object: 73 | 74 | ```cpp 75 | GrassLoader *grassLoader = new GrassLoader(grass); 76 | 77 | grass->setPageLoader(grassLoader); 78 | 79 | grassLoader->setHeightFunction(&getTerrainHeight); 80 | ``` 81 | 82 | In addition to creating and assigning a GrassLoader instance to the 83 | PagedGeometry object, you can see this code calls setHeightFunction(). 84 | Like TreeLoader2D, GrassLoader calculates the Y positions of grasses 85 | during runtime with this function. This is usually set to a function 86 | that returns the height of your terrain at the given point, so the 87 | grass/trees/etc appear directly on the surface of the terrain. 88 | 89 | At this point PagedGeometry is fully configured to display grass! All 90 | you need to do is add some: 91 | 92 | ```cpp 93 | GrassLayer *layer = grassLoader->addLayer("GrassMaterial"); 94 | ``` 95 | 96 | If you ran the application at this point, you would see your entire 97 | terrain covered in grass (provided that grass->update() is called 98 | every frame, of course). addLayer() basically adds a "layer" of grass to 99 | your scene which will appear everywhere, by default. In this case, grass 100 | is added and textured with "GrassMaterial". 101 | 102 | The GrassLayer object returned allows you to configure the grass any way 103 | you want. You can adjust the size, animation, density, etc through this 104 | object. For example: 105 | 106 | ```cpp 107 | layer->setMinimumSize(2.0f, 2.0f); 108 | 109 | layer->setMaximumSize(2.5f, 2.5f); 110 | 111 | layer->setAnimationEnabled(true); 112 | 113 | layer->setSwayDistribution(10.0f); 114 | 115 | layer->setSwayLength(0.5f); 116 | 117 | layer->setSwaySpeed(0.5f); 118 | 119 | layer->setDensity(1.5f); 120 | 121 | layer->setFadeTechnique(FADETECH_GROW); 122 | ``` 123 | 124 | As you can see, this sets the grass size, enables animations, configures 125 | the sway animation style, sets the density, and customizes the fade 126 | technique. All these options are fully documented in the PagedGeometry 127 | API documentation, so please refer to it for more detailed information 128 | about configuring your GrassLayer. 129 | 130 | If you want, you can add more and more layers until you have all the 131 | grass variety you want. This tutorial will just use the single grass 132 | layer created above, for simplicity. 133 | 134 | In most cases, you won't want the grass to grow *everywhere*. You might 135 | only want grass to appear in fields, or on lawn areas, for example. 136 | GrassLoader gives you complete control over the density levels of grass 137 | anywhere on your terrain through *density maps*. A density map is simply 138 | a greyscale 2D image you provide, where a white pixel indicates full 139 | grass density, and a black pixel indicates no grass at all (of course, 140 | any shade in between can be used too). You can literally "draw" grass 141 | into your world with any paint program by simply drawing a pattern image 142 | and using that image as a density map. For example, if your density map 143 | has a big round white circle in the middle, there will be a big round 144 | white circle of grass in the middle of your terrain. 145 | 146 | But first, you need to specify the boundaries of your terrain, so the 147 | grass engine will know where your density map is to be applied: 148 | 149 | ```cpp 150 | layer->setMapBounds(TBounds(0, 0, 1500, 1500)); 151 | ``` 152 | 153 | The line above configures the grass layer so the density map will take 154 | effect in the square region from (0x, 0z) to (1500x, 1500z). Usually you 155 | should supply the boundaries of your terrain here, since that's often 156 | the desired behavior. 157 | 158 | Now, use setDensityMap() to supply your density map image: 159 | 160 | ```cpp 161 | layer->setDensityMap("GrassMap.png"); 162 | ``` 163 | 164 | Note that the density map parameter is the filename of an image, not an 165 | Ogre Material. A material wouldn't make sense here, since it's not 166 | actually going to be applied as a texture to anything. 167 | 168 | Try running your application. The patterns of your grassmap should show 169 | up in your game world as different densities of grass. Now you have full 170 | control over where and how your grass grows. 171 | 172 | You can get a full working example of what you learned about grass by 173 | opening the "Example 3 – Trees and Bushes" project found in the examples 174 | folder. 175 | 176 | # Adding Shadows 177 | 178 | At this point you should be able to add trees and grass wherever you 179 | want in your world, but there's one very important aspect that's 180 | missing: shadows. Without any shadows being applied to the trees and 181 | grass, they will often look out of place against the dark, shadowed 182 | sides of your mountains. This can be fixed by applying a lightmap to 183 | your trees and grass that shades them according to the terrain. 184 | 185 | To apply a lightmap to grass, use the setColorMap() function, like this: 186 | 187 | ```cpp 188 | layer->setColorMap(“LightMap.png”); 189 | ``` 190 | 191 | And that's all there is to it, basically. Just make sure setMapBounds() 192 | is called at some point, since both color maps and density maps can't be 193 | applied without boundary information. 194 | 195 | You may notice that "set**Color**Map" allows you to not only configure 196 | the shade of grass, but the coloration as well. You can use this feature 197 | to not only shade grass, but also color it to the terrain's features. 198 | For example, if you make your grass texture white (instead of green or 199 | whatever), you can apply your terrain's texture as a color map, and the 200 | grass will match up to the terrain perfectly. This often produces a very 201 | nice, smooth look to the grass, and blends in very well to the terrain. 202 | See Example 4 for an example of this. 203 | 204 | Applying a lightmap to your trees is just as easy as with GrassLoader, 205 | since TreeLoader2D and TreeLoader3D both include a setColorMap() 206 | function. For example, you can do this: 207 | 208 | ```cpp 209 | treeLoader->setColorMap(“LightMap.png”); 210 | ``` 211 | 212 | Where "treeLoader" is a pointer to your TreeLoader2D or TreeLoader3D 213 | object. Unlike GrassLayer, there's no setMapBounds() function; the color 214 | map always takes effect in the boundary you specify in the 215 | TreeLoader2D/TreeLoader3D constructor. 216 | 217 | For a full working example of tree and grass shadows, take a look at the 218 | "Lightmaps" example (Example 7) in the examples folder. 219 | 220 | # Updating PagedGeometry 221 | 222 | As always, you need to call PagedGeometry::update() in order for the 223 | grass, etc to be displayed 224 | 225 | ```cpp 226 | [each frame] 227 | 228 | { 229 | 230 | grass->update(); 231 | 232 | } 233 | ``` 234 | 235 | # Conclusion 236 | 237 | As you can see, adding grass and applying shadows to your scene isn't 238 | very difficult – it's simply a matter of specifying the desired 239 | properties (grass texture, size, density, lightmap, etc). For a full 240 | working example of what you learned in this tutorial, see "Example 7 – 241 | Lightmaps", found in the examples folder. 242 | -------------------------------------------------------------------------------- /docs/Tutorial-4.md: -------------------------------------------------------------------------------- 1 | # Tutorial 4: Custom PageLoader {#tut4} 2 | 3 | 4 | # Introduction 5 | 6 | This tutorial explains how you can make your own custom 7 | PageLoader-derived class (like GrassLoader, TreeLoader2D, and 8 | TreeLoader3D) to have complete control over the dynamic loading process. 9 | By implementing your own PageLoader, you can load your trees, etc. from 10 | literally any source you can imagine, including hard disks, CDs, the 11 | Internet, and even procedurally. 12 | 13 | ## Tutorial Requirements 14 | 15 | - A fair understanding of PagedGeometry basics (see tutorials 1 – 3) 16 | - A basic understanding of Ogre 17 | - An fair understanding of C++ inheritance and polymorphism 18 | 19 | 20 | # How a PageLoader Works 21 | 22 | By now you should know basically what a PageLoader is – it's a abstract 23 | class which is used to load all kinds of geometry (trees, grass, etc.) 24 | into PagedGeometry, since the PagedGeometry class itself has no built-in 25 | functions for the addition of trees, grass, etc. to the scene. This way, 26 | you can implement PageLoader – derived classes which allow your geometry 27 | to be added to the scene in literally any way you want. As you've seen, 28 | PagedGeometry includes several PageLoader classes by default, which can 29 | be used to easily display what you want. 30 | 31 | As you probably know, PagedGeometry doesn't load everything in the scene 32 | all at one – it loads only what it needed to display visible trees, etc. 33 | This means entities are loaded dynamically, as your camera moves around 34 | in the world. When PagedGeometry needs a certain region of entities to 35 | be loaded, it will call on the PageLoader to do so. In other words, 36 | implementing a PageLoader is as simple as implementing a loadPage() 37 | function that loads entities within a requested boundary. 38 | 39 | 40 | # Defining a PageLoader 41 | 42 | To create a custom PageLoader, simply declare a class deriving from 43 | PageLoader. For example: 44 | 45 | ```cpp 46 | class CustomLoader: public PageLoader 47 | 48 | { 49 | 50 | public: 51 | 52 | void loadPage(PageInfo &page); 53 | 54 | }; 55 | ``` 56 | 57 | As you can see, the PageLoader structure is very simple; it's basically 58 | just a callback. Once you implement the loadPage() function, your new 59 | PageLoader will be ready for use! 60 | 61 | Here's an example implementation of loadPage(), which will populate the 62 | trees randomely: 63 | 64 | ```cpp 65 | void CustomLoader::loadPage(PageInfo &page) 66 | 67 | { 68 | 69 | Vector3 position; 70 | 71 | Quaternion rotation; 72 | 73 | Vector3 scale; 74 | 75 | ColourValue color; 76 | 77 | for (int i = 0; i < 100; i++){ 78 | 79 | //Calculate a random rotation around the Y axis 80 | 81 | rotation = Quaternion(Degree(Math::RangeRandom(0, 360)), 82 | Vector3::UNIT\_Y); 83 | 84 | //Calculate a position within the specified boundaries 85 | 86 | position.x = Math::RangeRandom(page.bounds.left, page.bounds.right); 87 | 88 | position.z = Math::RangeRandom(page.bounds.top, page.bounds.bottom); 89 | 90 | position.y = HeightFunction::getTerrainHeight(position.x, position.z); 91 | 92 | //Calculate a scale value (uniformly scaled in all dimensions) 93 | 94 | float uniformScale = Math::RangeRandom(0.5f, 0.6f); 95 | 96 | scale.x = uniformScale; 97 | 98 | scale.y = uniformScale; 99 | 100 | scale.z = uniformScale; 101 | 102 | //All trees will be fully lit in this demo 103 | 104 | color = ColourValue::White; 105 | 106 | //Add a tree to the scene at the desired location 107 | 108 | addEntity(myTree, position, rotation, scale, color); 109 | 110 | } 111 | 112 | } 113 | ``` 114 | 115 | This example basically adds 100 trees to PagedGeometry with addEntity(). 116 | addEntity() is a function in the base PageLoader class through which all 117 | geometry is eventually added to PagedGeometry. To use addEntity(), 118 | simply specify the desired entity, postion, rotation, scale, and color. 119 | 120 | The most important concept of this function is that the entities which 121 | are being added are *all* within the given boundaries. The boundaries, 122 | as well as other useful information, is passed to loadPage() through a 123 | PageInfo struct. For example, the X/Z position in the above loadPage() 124 | implementation is calculated like this: 125 | 126 | ```cpp 127 | position.x = Math::RangeRandom(page.bounds.left, page.bounds.right); 128 | 129 | position.z = Math::RangeRandom(page.bounds.top, page.bounds.bottom); 130 | ``` 131 | 132 | So the trees will be between page.bounds.left – page.bounds.right in the 133 | X coordinate, and between page.bounds.top – page.bounds.bottom in the Z 134 | coordinate. It's important that you don't add any entities outside of 135 | these boundaries; when PagedGeometry asks you for a certain region of 136 | entities to be loaded, it expects exactly that to be done – attempting 137 | to add entities anywhere else may crash the application. 138 | 139 | # A “Page” of Geometry 140 | 141 | As mentioned above, your loadPage() function is simply given a desired 142 | rectangular boundary along the X/Z plane, and the task of filling those 143 | boundaries with the desired entities. Implementing an effecient 144 | PageLoader with this information alone would be extremely difficult in 145 | many cases, since retreiving some random rectangular region of entities 146 | usually isn't very effecient. 147 | 148 | There's one fact that can be extremely helpful when implemeting your 149 | PageLoader: The boundaries you are requested to fill out will *always* 150 | have the same width and height (both being equivelant to the value given 151 | to PagedGeometry::setPageSize()), and will *always* be a single "tile" 152 | of an infinitely sized "virtual grid". 153 | 154 | It may be helpful to picture the actual layout of your trees as being 155 | divided into a huge grid, where each "tile" of that grid (called a 156 | "page") can be individually loaded and unloaded. The PageInfo parameter 157 | specified to your loadPage() function will always be providing the 158 | boundaries, etc. of *one* of those tiles, which you need to load. In 159 | fact, you could implement your entire loadPage() function if only given 160 | the x and z indexes of the desired tile. 161 | 162 | # Conclusion 163 | 164 | A PageLoader is nothing more than an advanced callback function; when 165 | the PagedGeometry engine decides a certain page of geometry needs to be 166 | loaded, it calls on the PageLoader to do this. While creating your own 167 | custom PageLoader class is an advanced, and sometimes difficult task, 168 | it's really very simple in concept. Through custom PageLoader's, your 169 | trees, grass, etc can now be loaded from literally any source you can 170 | imagine. 171 | -------------------------------------------------------------------------------- /examples/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | # PagedGeometry includes 3 | include_directories(${CMAKE_SOURCE_DIR}/include) 4 | include_directories(${CMAKE_BINARY_DIR}/include) 5 | 6 | # external includes 7 | include_directories(${OGRE_INCLUDE_DIRS}) 8 | link_directories(${OGRE_LIBRARY_DIRS}) 9 | 10 | macro(example_app NAME) 11 | add_executable(${NAME} WIN32 ${NAME}.cpp) 12 | target_link_libraries(${NAME} PagedGeometry ${OGRE_LIBRARIES}) 13 | endmacro(example_app) 14 | 15 | example_app(Example1) 16 | example_app(Example2) 17 | example_app(Example3) 18 | example_app(Example4) 19 | example_app(Example5) 20 | example_app(Example6) 21 | example_app(Example7) 22 | example_app(Example8) 23 | example_app(Example9) 24 | example_app(Example10) 25 | example_app(Example11) 26 | 27 | -------------------------------------------------------------------------------- /examples/Example1.cpp: -------------------------------------------------------------------------------- 1 | //=============================================================================================================== 2 | //Example 1 - TreeLoader3D 3 | //--------------------------------------------------------------------------------------------------------------- 4 | // This example demonstrates the basic use of PagedGeometry to display trees with TreeLoader3D. 5 | // Instructions: Move around with the arrow/WASD keys, hold SHIFT to move faster, and hold SPACE to fly. 6 | // HINT: Search this source for "[NOTE]" to find important code and comments related to PagedGeometry. 7 | //=============================================================================================================== 8 | #define AppTitle "PagedGeometry Example 1 - TreeLoader3D" 9 | 10 | #include "PagedGeometryConfig.h" 11 | #include 12 | #if OGRE_PLATFORM == OGRE_PLATFORM_WIN32 13 | #include 14 | #endif 15 | 16 | #include 17 | #include 18 | 19 | using namespace Ogre; 20 | 21 | 22 | //Include PagedGeometry headers that will be needed 23 | #include "PagedGeometry.h" 24 | #include "BatchPage.h" 25 | #include "ImpostorPage.h" 26 | #include "TreeLoader3D.h" 27 | 28 | //Include "LegacyTerrainLoader.h", a header that allows loading Ogre 1.7 style terrain 29 | #include "LegacyTerrainLoader.h" 30 | 31 | //Include "HeightFunction.h", a header that provides some useful functions for quickly and easily 32 | //getting the height of the terrain at a given point. 33 | #include "HeightFunction.h" 34 | //[NOTE] Remember that this "HeightFunction.h" file is not related to the PagedGeometry library itself 35 | //in any way. It's simply a utility that's included with all these examples to make getting the terrain 36 | //height easy. You can use it in your games/applications if you want, although if you're using a 37 | //collision/physics library with a faster alternate, you may use that instead. 38 | 39 | //PagedGeometry's classes and functions are under the "Forests" namespace 40 | using namespace Forests; 41 | 42 | //Demo world class 43 | //[NOTE] The main PagedGeometry-related sections of this class are load() and 44 | //render. These functions setup and use PagedGeometry in the scene. 45 | class World : public TerrainWorld 46 | { 47 | public: 48 | World(RenderWindow* win); 49 | 50 | void load(); //Loads the 3D scene 51 | void unload(); //Unloads the 3D scene cleanly 52 | void run(); //Runs the simulation 53 | 54 | void render(); //Renders a single frame, updating PagedGeometry and Ogre 55 | 56 | //Various pointers to Ogre objects are stored here: 57 | RenderWindow *window; 58 | Viewport *viewport; 59 | Camera *camera; 60 | SceneNode* cameraNode; 61 | 62 | //Pointers to PagedGeometry class instances: 63 | PagedGeometry *trees; 64 | }; 65 | 66 | #if OGRE_PLATFORM == OGRE_PLATFORM_WIN32 67 | INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE hPrevInstance, LPSTR strCmdLine, INT nCmdShow) 68 | #else 69 | int main(int argc, char *argv[]) 70 | #endif 71 | { 72 | //Initialize Ogre 73 | OgreBites::ApplicationContext ctx; 74 | ctx.initApp(); 75 | ctx.setWindowGrab(true); 76 | 77 | World myWorld(ctx.getRenderWindow()); 78 | myWorld.load(); //Load world 79 | 80 | OgreBites::CameraMan camman(myWorld.cameraNode); 81 | ctx.addInputListener(&camman); 82 | 83 | myWorld.run(); //Display world 84 | 85 | myWorld.unload(); 86 | 87 | //Shut down Ogre 88 | ctx.closeApp(); 89 | 90 | return 0; 91 | } 92 | 93 | World::World(RenderWindow* win) 94 | { 95 | window = win; 96 | 97 | //Initialize the camera and viewport 98 | camera = sceneMgr->createCamera("MainCamera"); 99 | viewport = window->addViewport(camera); 100 | viewport->setBackgroundColour(ColourValue(0.47f, 0.67f, 0.96f)); //Blue sky background color 101 | camera->setAspectRatio(Real(viewport->getActualWidth()) / Real(viewport->getActualHeight())); 102 | camera->setNearClipDistance(1.0f); 103 | camera->setFarClipDistance(2000.0f); 104 | 105 | cameraNode = sceneMgr->getRootSceneNode()->createChildSceneNode(); 106 | cameraNode->attachObject(camera); 107 | 108 | //Set up lighting 109 | Light *light = sceneMgr->createLight("Sun"); 110 | light->setType(Light::LT_DIRECTIONAL); 111 | sceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(light); 112 | light->getParentSceneNode()->setDirection(Vector3(0.0f, -0.5f, 1.0f)); 113 | sceneMgr->setAmbientLight(ColourValue(1, 1, 1)); 114 | } 115 | 116 | //[NOTE] In addition to some Ogre setup, this function configures PagedGeometry in the scene. 117 | void World::load() 118 | { 119 | //-------------------------------------- LOAD TERRAIN -------------------------------------- 120 | //Setup the fog up to 500 units away 121 | sceneMgr->setFog(FOG_LINEAR, viewport->getBackgroundColour(), 0, 100, 700); 122 | 123 | //Load the terrain 124 | terrain = loadLegacyTerrain("terrain.cfg", sceneMgr); 125 | 126 | //Start off with the camera at the center of the terrain 127 | cameraNode->setPosition(700, 100, 700); 128 | 129 | //-------------------------------------- LOAD TREES -------------------------------------- 130 | //Create and configure a new PagedGeometry instance 131 | trees = new PagedGeometry(); 132 | trees->setCamera(camera); //Set the camera so PagedGeometry knows how to calculate LODs 133 | trees->setPageSize(80); //Set the size of each page of geometry 134 | trees->setInfinite(); //Use infinite paging mode 135 | trees->addDetailLevel(150, 50); //Use batches up to 150 units away, and fade for 30 more units 136 | trees->addDetailLevel(500, 50); //Use impostors up to 400 units, and for for 50 more units 137 | 138 | //Create a new TreeLoader3D object 139 | TreeLoader3D *treeLoader = new TreeLoader3D(trees, TBounds(0, 0, 1500, 1500)); 140 | trees->setPageLoader(treeLoader); //Assign the "treeLoader" to be used to load geometry for the PagedGeometry instance 141 | 142 | //Load a tree entity 143 | Entity *myEntity = sceneMgr->createEntity("Tree", "tree2.mesh"); 144 | 145 | //Setup the height function (so the Y values of trees can be calculated when they are placed on the terrain) 146 | HeightFunction::initialize(terrain); 147 | 148 | //Randomly place 20,000 copies of the tree on the terrain 149 | Vector3 position; 150 | Radian yaw; 151 | Real scale; 152 | for (int i = 0; i < 20000; i++){ 153 | yaw = Degree(Math::RangeRandom(0, 360)); 154 | 155 | position.x = Math::RangeRandom(0, 1500); 156 | position.z = Math::RangeRandom(0, 1500); 157 | position.y = HeightFunction::getTerrainHeight(position.x, position.z); 158 | 159 | scale = Math::RangeRandom(0.5f, 0.6f); 160 | 161 | treeLoader->addTree(myEntity, position, yaw, scale); 162 | } 163 | } 164 | 165 | void World::unload() 166 | { 167 | //[NOTE] Always remember to delete any PageLoader(s) and PagedGeometry instances in order to avoid memory leaks. 168 | 169 | //Delete the TreeLoader3D instance 170 | delete trees->getPageLoader(); 171 | 172 | //Delete the PagedGeometry instance 173 | delete trees; 174 | 175 | //Also delete the tree entity 176 | sceneMgr->destroyEntity("Tree"); 177 | 178 | unloadTerrain(); 179 | } 180 | 181 | void World::run() 182 | { 183 | //Render loop 184 | while(!Root::getSingleton().endRenderingQueued()) 185 | { 186 | //Update frame 187 | render(); 188 | } 189 | } 190 | 191 | void World::render() 192 | { 193 | //[NOTE] PagedGeometry::update() is called every frame to keep LODs, etc. up-to-date 194 | trees->update(); 195 | 196 | //Render the scene with Ogre 197 | root->renderOneFrame(); 198 | } 199 | -------------------------------------------------------------------------------- /examples/Example10.cpp: -------------------------------------------------------------------------------- 1 | #include "PGExampleApplication.h" 2 | 3 | #include "PagedGeometry.h" 4 | #include "BatchPage.h" 5 | #include "WindBatchPage.h" 6 | #include "TreeLoader3D.h" 7 | #include "TreeLoader2D.h" 8 | #include "ImpostorPage.h" 9 | #include "GrassLoader.h" 10 | 11 | #include "HeightFunction.h" 12 | 13 | using namespace Forests; 14 | 15 | // we use wind pages 16 | //#define WIND 17 | 18 | // SAMPLE CLASS 19 | class PGSampleApp : public ExampleApplication 20 | { 21 | public: 22 | PGSampleApp(); 23 | void createPGDemo(void); 24 | void createScene(void); 25 | protected: 26 | }; 27 | 28 | // SAMPLE IMPLEMENTATION 29 | PGSampleApp::PGSampleApp() : ExampleApplication() 30 | { 31 | } 32 | 33 | void PGSampleApp::createScene(void) 34 | { 35 | 36 | //Setup the fog up to 1500 units away 37 | mSceneMgr->setFog(FOG_NONE); 38 | 39 | //Load the terrain 40 | mTerrainGroup = loadLegacyTerrain("terrain3.cfg", mSceneMgr); 41 | 42 | //Start off with the camera at the center of the terrain 43 | mCameraNode->setPosition(700, 100, 700); 44 | 45 | //Setup a skybox 46 | mSceneMgr->setSkyBox(true, "3D-Diggers/SkyBox", 2000); 47 | 48 | // setup some useful defaults 49 | //MaterialManager::getSingleton().setDefaultTextureFiltering(TFO_ANISOTROPIC); 50 | //MaterialManager::getSingleton().setDefaultAnisotropy(7); 51 | 52 | LogManager::getSingleton().setLogDetail(LL_BOREME); 53 | 54 | Light *light = mSceneMgr->createLight("Sun"); 55 | mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(light); 56 | light->setType(Light::LT_DIRECTIONAL); 57 | light->getParentSceneNode()->setDirection(Ogre::Vector3(0.0f, -0.5f, 1.0f)); 58 | mSceneMgr->setAmbientLight(Ogre::ColourValue(1, 1, 1)); 59 | 60 | mCameraNode->setPosition(Vector3(100, 50, 1000)); 61 | mCameraNode->lookAt(Vector3(150, 50, 1000), Node::TS_WORLD); 62 | mCamera->setNearClipDistance(0.1); 63 | mCamera->setFarClipDistance(50000); 64 | 65 | if (mRoot->getRenderSystem()->getCapabilities()->hasCapability(RSC_INFINITE_FAR_PLANE)) 66 | { 67 | mCamera->setFarClipDistance(0); // enable infinite far clip distance if we can 68 | } 69 | } 70 | void PGSampleApp::createPGDemo(void) 71 | { 72 | //-------------------------------------- LOAD TREES -------------------------------------- 73 | //Create and configure a new PagedGeometry instance 74 | PagedGeometry *trees = new PagedGeometry(); 75 | trees->setCamera(mCamera); //Set the camera so PagedGeometry knows how to calculate LODs 76 | trees->setPageSize(50); //Set the size of each page of geometry 77 | trees->setInfinite(); //Use infinite paging mode 78 | 79 | #ifdef WIND 80 | //WindBatchPage is a variation of BatchPage which includes a wind animation shader 81 | trees->addDetailLevel(70, 30); //Use batches up to 70 units away, and fade for 30 more units 82 | #else 83 | trees->addDetailLevel(70, 30); //Use batches up to 70 units away, and fade for 30 more units 84 | #endif 85 | trees->addDetailLevel(5000, 50); //Use impostors up to 400 units, and for for 50 more units 86 | 87 | //Create a new TreeLoader2D object 88 | TreeLoader2D *treeLoader = new TreeLoader2D(trees, TBounds(0, 0, 1500, 1500)); 89 | trees->setPageLoader(treeLoader); //Assign the "treeLoader" to be used to load geometry for the PagedGeometry instance 90 | 91 | //Supply a height function to TreeLoader2D so it can calculate tree Y values 92 | HeightFunction::initialize(mTerrainGroup); 93 | treeLoader->setHeightFunction(&HeightFunction::getTerrainHeight); 94 | 95 | //[NOTE] This sets the color map, or lightmap to be used for trees. All trees will be colored according 96 | //to this texture. In this case, the shading of the terrain is used so trees will be shadowed 97 | //just as the terrain is (this should appear like the terrain is casting shadows on the trees). 98 | //You may notice that TreeLoader2D / TreeLoader3D doesn't have a setMapBounds() function as GrassLoader 99 | //does. This is because the bounds you specify in the TreeLoader2D constructor are used to apply 100 | //the color map. 101 | treeLoader->setColorMap("terrain_lightmap.jpg"); 102 | 103 | //Load a tree entity 104 | Entity *tree1 = mSceneMgr->createEntity("Tree1", "fir06_30.mesh"); 105 | 106 | Entity *tree2 = mSceneMgr->createEntity("Tree2", "fir14_25.mesh"); 107 | 108 | #ifdef WIND 109 | trees->setCustomParam(tree1->getName(), "windFactorX", 15); 110 | trees->setCustomParam(tree1->getName(), "windFactorY", 0.01); 111 | trees->setCustomParam(tree2->getName(), "windFactorX", 22); 112 | trees->setCustomParam(tree2->getName(), "windFactorY", 0.013); 113 | #endif 114 | 115 | //Randomly place 10000 copies of the tree on the terrain 116 | Ogre::Vector3 position = Ogre::Vector3::ZERO; 117 | Radian yaw; 118 | Real scale; 119 | for (int i = 0; i < 60000; i++){ 120 | yaw = Degree(Math::RangeRandom(0, 360)); 121 | 122 | position.x = Math::RangeRandom(0, 1500); 123 | position.z = Math::RangeRandom(0, 1500); 124 | 125 | scale = Math::RangeRandom(0.07f, 0.12f); 126 | 127 | //[NOTE] Unlike TreeLoader3D, TreeLoader2D's addTree() function accepts a Vector2D position (x/z) 128 | //The Y value is calculated during runtime (to save memory) from the height function supplied (above) 129 | if (Math::UnitRandom() < 0.5f) 130 | treeLoader->addTree(tree1, position, yaw, scale); 131 | else 132 | treeLoader->addTree(tree2, position, yaw, scale); 133 | } 134 | addPG(trees); 135 | 136 | } 137 | 138 | // MAIN BELOW 139 | #if OGRE_PLATFORM == OGRE_PLATFORM_WIN32 140 | INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE hPrevInstance, LPSTR strCmdLine, INT nCmdShow) 141 | #else 142 | int main(int argc, char *argv[]) 143 | #endif 144 | { 145 | 146 | PGSampleApp *app = new PGSampleApp(); 147 | app->go(); 148 | 149 | return 0; 150 | } 151 | -------------------------------------------------------------------------------- /examples/Example2.cpp: -------------------------------------------------------------------------------- 1 | //=============================================================================================================== 2 | //Example 2 - TreeLoader2D 3 | //--------------------------------------------------------------------------------------------------------------- 4 | // This example demonstrates the basic use of PagedGeometry to display trees with TreeLoader2D. 5 | // Instructions: Move around with the arrow/WASD keys, hold SHIFT to move faster, and hold SPACE to fly. 6 | // HINT: Search this source for "[NOTE]" to find important code and comments related to PagedGeometry. 7 | //=============================================================================================================== 8 | #define AppTitle "PagedGeometry Example 2 - TreeLoader2D" 9 | 10 | #include "PagedGeometryConfig.h" 11 | #include 12 | 13 | #if OGRE_PLATFORM == OGRE_PLATFORM_WIN32 14 | #include 15 | #endif 16 | 17 | #include 18 | #include 19 | 20 | using namespace Ogre; 21 | 22 | 23 | //Include PagedGeometry headers that will be needed 24 | #include "PagedGeometry.h" 25 | #include "BatchPage.h" 26 | #include "ImpostorPage.h" 27 | #include "TreeLoader2D.h" 28 | 29 | //Include "LegacyTerrainLoader.h", a header that allows loading Ogre 1.7 style terrain 30 | #include "LegacyTerrainLoader.h" 31 | 32 | //Include "HeightFunction.h", a header that provides some useful functions for quickly and easily 33 | //getting the height of the terrain at a given point. 34 | #include "HeightFunction.h" 35 | //[NOTE] Remember that this "HeightFunction.h" file is not related to the PagedGeometry library itself 36 | //in any way. It's simply a utility that's included with all these examples to make getting the terrain 37 | //height easy. You can use it in your games/applications if you want, although if you're using a 38 | //collision/physics library with a faster alternate, you may use that instead. 39 | 40 | //PagedGeometry's classes and functions are under the "Forests" namespace 41 | using namespace Forests; 42 | 43 | 44 | //Demo world class 45 | //[NOTE] The main PagedGeometry-related sections of this class are load() and 46 | //render. These functions setup and use PagedGeometry in the scene. 47 | class World : public TerrainWorld 48 | { 49 | public: 50 | World(RenderWindow* win); 51 | 52 | void load(); //Loads the 3D scene 53 | void unload(); //Unloads the 3D scene cleanly 54 | void run(); //Runs the simulation 55 | 56 | void render(); //Renders a single frame, updating PagedGeometry and Ogre 57 | 58 | //Various pointers to Ogre objects are stored here: 59 | RenderWindow *window; 60 | Viewport *viewport; 61 | Camera *camera; 62 | SceneNode* cameraNode; 63 | 64 | //Pointers to PagedGeometry class instances: 65 | PagedGeometry *trees; 66 | }; 67 | 68 | #if OGRE_PLATFORM == OGRE_PLATFORM_WIN32 69 | INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE hPrevInstance, LPSTR strCmdLine, INT nCmdShow) 70 | #else 71 | int main(int argc, char *argv[]) 72 | #endif 73 | { 74 | //Initialize Ogre 75 | OgreBites::ApplicationContext ctx; 76 | ctx.initApp(); 77 | ctx.setWindowGrab(true); 78 | 79 | World myWorld(ctx.getRenderWindow()); 80 | myWorld.load(); //Load world 81 | 82 | OgreBites::CameraMan camman(myWorld.cameraNode); 83 | ctx.addInputListener(&camman); 84 | 85 | myWorld.run(); //Display world 86 | 87 | myWorld.unload(); 88 | 89 | //Shut down Ogre 90 | ctx.closeApp(); 91 | 92 | return 0; 93 | } 94 | 95 | World::World(RenderWindow* win) 96 | { 97 | window = win; 98 | 99 | //Initialize the camera and viewport 100 | camera = sceneMgr->createCamera("MainCamera"); 101 | viewport = window->addViewport(camera); 102 | viewport->setBackgroundColour(ColourValue(0.47f, 0.67f, 0.96f)); //Blue sky background color 103 | camera->setAspectRatio(Real(viewport->getActualWidth()) / Real(viewport->getActualHeight())); 104 | camera->setNearClipDistance(1.0f); 105 | camera->setFarClipDistance(2000.0f); 106 | 107 | cameraNode = sceneMgr->getRootSceneNode()->createChildSceneNode(); 108 | cameraNode->attachObject(camera); 109 | 110 | //Set up lighting 111 | Light *light = sceneMgr->createLight("Sun"); 112 | light->setType(Light::LT_DIRECTIONAL); 113 | sceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(light); 114 | light->getParentSceneNode()->setDirection(Vector3(0.0f, -0.5f, 1.0f)); 115 | sceneMgr->setAmbientLight(ColourValue(1, 1, 1)); 116 | } 117 | 118 | //[NOTE] In addition to some Ogre setup, this function configures PagedGeometry in the scene. 119 | void World::load() 120 | { 121 | //-------------------------------------- LOAD TERRAIN -------------------------------------- 122 | //Setup the fog up to 500 units away 123 | sceneMgr->setFog(FOG_LINEAR, viewport->getBackgroundColour(), 0, 100, 700); 124 | 125 | //Load the terrain 126 | terrain = loadLegacyTerrain("terrain.cfg", sceneMgr); 127 | 128 | //Start off with the camera at the center of the terrain 129 | cameraNode->setPosition(700, 100, 700); 130 | 131 | //-------------------------------------- LOAD TREES -------------------------------------- 132 | //Create and configure a new PagedGeometry instance 133 | trees = new PagedGeometry(); 134 | trees->setCamera(camera); //Set the camera so PagedGeometry knows how to calculate LODs 135 | trees->setPageSize(80); //Set the size of each page of geometry 136 | trees->setInfinite(); //Use infinite paging mode 137 | trees->addDetailLevel(150, 50); //Use batches up to 150 units away, and fade for 30 more units 138 | trees->addDetailLevel(500, 50); //Use impostors up to 400 units, and for for 50 more units 139 | 140 | //Create a new TreeLoader2D object 141 | TreeLoader2D *treeLoader = new TreeLoader2D(trees, TBounds(0, 0, 1500, 1500)); 142 | trees->setPageLoader(treeLoader); //Assign the "treeLoader" to be used to load geometry for the PagedGeometry instance 143 | 144 | //Supply a height function to TreeLoader2D so it can calculate tree Y values 145 | HeightFunction::initialize(terrain); 146 | treeLoader->setHeightFunction(&HeightFunction::getTerrainHeight); 147 | 148 | //Load a tree entity 149 | Entity *myEntity = sceneMgr->createEntity("Tree", "tree2.mesh"); 150 | 151 | //Randomly place 20,000 copies of the tree on the terrain 152 | Vector3 position = Vector3::ZERO; 153 | Radian yaw; 154 | Real scale; 155 | for (int i = 0; i < 20000; i++){ 156 | yaw = Degree(Math::RangeRandom(0, 360)); 157 | 158 | position.x = Math::RangeRandom(0, 1500); 159 | position.z = Math::RangeRandom(0, 1500); 160 | 161 | scale = Math::RangeRandom(0.5f, 0.6f); 162 | 163 | //[NOTE] Unlike TreeLoader3D, TreeLoader2D's addTree() function accepts a Vector2D position (x/z) 164 | //The Y value is calculated during runtime (to save memory) from the height function supplied (above) 165 | treeLoader->addTree(myEntity, position, yaw, scale); 166 | } 167 | } 168 | 169 | void World::unload() 170 | { 171 | //[NOTE] Always remember to delete any PageLoader(s) and PagedGeometry instances in order to avoid memory leaks. 172 | 173 | //Delete the TreeLoader2D instance 174 | delete trees->getPageLoader(); 175 | 176 | //Delete the PagedGeometry instance 177 | delete trees; 178 | 179 | //Also delete the tree entity 180 | sceneMgr->destroyEntity("Tree"); 181 | 182 | unloadTerrain(); 183 | } 184 | 185 | void World::run() 186 | { 187 | //Render loop 188 | while(!Root::getSingleton().endRenderingQueued()) 189 | { 190 | //Update frame 191 | render(); 192 | } 193 | } 194 | 195 | void World::render() 196 | { 197 | //[NOTE] PagedGeometry::update() is called every frame to keep LODs, etc. up-to-date 198 | trees->update(); 199 | 200 | //Render the scene with Ogre 201 | root->renderOneFrame(); 202 | } 203 | -------------------------------------------------------------------------------- /examples/Example3.cpp: -------------------------------------------------------------------------------- 1 | //=============================================================================================================== 2 | //Example 3 - Trees and Bushes 3 | //--------------------------------------------------------------------------------------------------------------- 4 | // This example demonstrates the use of PagedGeometry to display trees and bushes with different view ranges. 5 | // Instructions: Move around with the arrow/WASD keys, hold SHIFT to move faster, and hold SPACE to fly. 6 | // HINT: Search this source for "[NOTE]" to find important code and comments related to PagedGeometry. 7 | //=============================================================================================================== 8 | #define AppTitle "PagedGeometry Example 3 - Trees and Bushes" 9 | 10 | #include "PagedGeometryConfig.h" 11 | #include 12 | 13 | #if OGRE_PLATFORM == OGRE_PLATFORM_WIN32 14 | #include 15 | #endif 16 | 17 | #include 18 | #include 19 | 20 | using namespace Ogre; 21 | 22 | 23 | //Include PagedGeometry headers that will be needed 24 | #include "PagedGeometry.h" 25 | #include "BatchPage.h" 26 | #include "ImpostorPage.h" 27 | #include "TreeLoader2D.h" 28 | 29 | //Include "LegacyTerrainLoader.h", a header that allows loading Ogre 1.7 style terrain 30 | #include "LegacyTerrainLoader.h" 31 | 32 | //Include "HeightFunction.h", a header that provides some useful functions for quickly and easily 33 | //getting the height of the terrain at a given point. 34 | #include "HeightFunction.h" 35 | //[NOTE] Remember that this "HeightFunction.h" file is not related to the PagedGeometry library itself 36 | //in any way. It's simply a utility that's included with all these examples to make getting the terrain 37 | //height easy. You can use it in your games/applications if you want, although if you're using a 38 | //collision/physics library with a faster alternate, you may use that instead. 39 | 40 | //PagedGeometry's classes and functions are under the "Forests" namespace 41 | using namespace Forests; 42 | 43 | //Demo world class 44 | //[NOTE] The main PagedGeometry-related sections of this class are load() and 45 | //render. These functions setup and use PagedGeometry in the scene. 46 | class World : public TerrainWorld 47 | { 48 | public: 49 | World(RenderWindow* win); 50 | 51 | void load(); //Loads the 3D scene 52 | void unload(); //Unloads the 3D scene cleanly 53 | void run(); //Runs the simulation 54 | 55 | void render(); //Renders a single frame, updating PagedGeometry and Ogre 56 | 57 | //Various pointers to Ogre objects are stored here: 58 | RenderWindow *window; 59 | Viewport *viewport; 60 | Camera *camera; 61 | SceneNode* cameraNode; 62 | 63 | //Pointers to PagedGeometry class instances: 64 | PagedGeometry *trees, *bushes; 65 | }; 66 | 67 | #if OGRE_PLATFORM == OGRE_PLATFORM_WIN32 68 | INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE hPrevInstance, LPSTR strCmdLine, INT nCmdShow) 69 | #else 70 | int main(int argc, char *argv[]) 71 | #endif 72 | { 73 | //Initialize Ogre 74 | OgreBites::ApplicationContext ctx; 75 | ctx.initApp(); 76 | ctx.setWindowGrab(true); 77 | 78 | World myWorld(ctx.getRenderWindow()); 79 | myWorld.load(); //Load world 80 | 81 | OgreBites::CameraMan camman(myWorld.cameraNode); 82 | ctx.addInputListener(&camman); 83 | 84 | myWorld.run(); //Display world 85 | 86 | myWorld.unload(); 87 | 88 | //Shut down Ogre 89 | ctx.closeApp(); 90 | 91 | return 0; 92 | } 93 | 94 | World::World(RenderWindow* win) 95 | { 96 | window = win; 97 | 98 | //Initialize the camera and viewport 99 | camera = sceneMgr->createCamera("MainCamera"); 100 | viewport = window->addViewport(camera); 101 | viewport->setBackgroundColour(ColourValue(0.47f, 0.67f, 0.96f)); //Blue sky background color 102 | camera->setAspectRatio(Real(viewport->getActualWidth()) / Real(viewport->getActualHeight())); 103 | camera->setNearClipDistance(1.0f); 104 | camera->setFarClipDistance(2000.0f); 105 | 106 | cameraNode = sceneMgr->getRootSceneNode()->createChildSceneNode(); 107 | cameraNode->attachObject(camera); 108 | 109 | //Set up lighting 110 | Light *light = sceneMgr->createLight("Sun"); 111 | light->setType(Light::LT_DIRECTIONAL); 112 | sceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(light); 113 | light->getParentSceneNode()->setDirection(Vector3(0.0f, -0.5f, 1.0f)); 114 | sceneMgr->setAmbientLight(ColourValue(1, 1, 1)); 115 | } 116 | 117 | //[NOTE] In addition to some Ogre setup, this function configures PagedGeometry in the scene. 118 | void World::load() 119 | { 120 | //-------------------------------------- LOAD TERRAIN -------------------------------------- 121 | //Setup the fog up to 500 units away 122 | sceneMgr->setFog(FOG_LINEAR, viewport->getBackgroundColour(), 0, 100, 700); 123 | 124 | //Load the terrain 125 | terrain = loadLegacyTerrain("terrain.cfg", sceneMgr); 126 | 127 | //Start off with the camera at the center of the terrain 128 | cameraNode->setPosition(700, 100, 700); 129 | 130 | //-------------------------------------- LOAD TREES -------------------------------------- 131 | //Create and configure a new PagedGeometry instance for trees 132 | trees = new PagedGeometry(camera, 80); 133 | trees->addDetailLevel(150, 50); 134 | trees->addDetailLevel(500, 50); 135 | 136 | //Create a new TreeLoader2D object 137 | TreeLoader2D *treeLoader = new TreeLoader2D(trees, TBounds(0, 0, 1500, 1500)); 138 | trees->setPageLoader(treeLoader); 139 | 140 | //Supply the height function to TreeLoader2D so it can calculate tree Y values 141 | HeightFunction::initialize(terrain); 142 | treeLoader->setHeightFunction(&HeightFunction::getTerrainHeight); 143 | 144 | //Load a tree entity 145 | Entity *myTree = sceneMgr->createEntity("Tree", "tree2.mesh"); 146 | 147 | //Randomly place 10,000 copies of the tree on the terrain 148 | Vector3 position = Vector3::ZERO; 149 | Radian yaw; 150 | Real scale; 151 | for (int i = 0; i < 10000; i++){ 152 | yaw = Degree(Math::RangeRandom(0, 360)); 153 | position.x = Math::RangeRandom(0, 1500); 154 | position.z = Math::RangeRandom(0, 1500); 155 | scale = Math::RangeRandom(0.5f, 0.6f); 156 | 157 | treeLoader->addTree(myTree, position, yaw, scale); 158 | } 159 | 160 | //-------------------------------------- LOAD BUSHES -------------------------------------- 161 | //Create and configure a new PagedGeometry instance for bushes 162 | bushes = new PagedGeometry(camera, 50); 163 | bushes->addDetailLevel(80, 50); 164 | 165 | //Create a new TreeLoader2D object for the bushes 166 | TreeLoader2D *bushLoader = new TreeLoader2D(bushes, TBounds(0, 0, 1500, 1500)); 167 | bushes->setPageLoader(bushLoader); 168 | 169 | //Supply the height function to TreeLoader2D so it can calculate tree Y values 170 | bushLoader->setHeightFunction(&HeightFunction::getTerrainHeight); 171 | 172 | //Load a bush entity 173 | Entity *myBush = sceneMgr->createEntity("Bush", "Bush.mesh"); 174 | 175 | //Randomly place 30,000 copies of the bush on the terrain 176 | for (int i = 0; i < 30000; i++){ 177 | yaw = Degree(Math::RangeRandom(0, 360)); 178 | position.x = Math::RangeRandom(0, 1500); 179 | position.z = Math::RangeRandom(0, 1500); 180 | scale = Math::RangeRandom(0.7f, 0.8f); 181 | 182 | bushLoader->addTree(myBush, position, yaw, scale); 183 | } 184 | } 185 | 186 | void World::unload() 187 | { 188 | //[NOTE] Always remember to delete any PageLoader(s) and PagedGeometry instances in order to avoid memory leaks. 189 | 190 | //Delete the TreeLoader2D instances 191 | delete trees->getPageLoader(); 192 | delete bushes->getPageLoader(); 193 | 194 | //Delete the PagedGeometry instances 195 | delete trees; 196 | delete bushes; 197 | 198 | //Also delete the tree/bush entities 199 | sceneMgr->destroyEntity("Tree"); 200 | sceneMgr->destroyEntity("Bush"); 201 | 202 | unloadTerrain(); 203 | } 204 | 205 | void World::run() 206 | { 207 | //Render loop 208 | while(!Root::getSingleton().endRenderingQueued()) 209 | { 210 | //Update frame 211 | render(); 212 | } 213 | } 214 | 215 | void World::render() 216 | { 217 | //[NOTE] PagedGeometry::update() is called every frame to keep LODs, etc. up-to-date 218 | trees->update(); 219 | bushes->update(); 220 | 221 | //Render the scene with Ogre 222 | root->renderOneFrame(); 223 | } 224 | -------------------------------------------------------------------------------- /examples/Example4.cpp: -------------------------------------------------------------------------------- 1 | //=============================================================================================================== 2 | //Example 4 - GrassLoader 3 | //--------------------------------------------------------------------------------------------------------------- 4 | // This example demonstrates the basic use of PagedGeometry to display grass with GrassLoader. 5 | // Instructions: Move around with the arrow/WASD keys, hold SHIFT to move faster, and hold SPACE to fly. 6 | // HINT: Search this source for "[NOTE]" to find important code and comments related to PagedGeometry. 7 | //=============================================================================================================== 8 | #define AppTitle "PagedGeometry Example 4 - GrassLoader" 9 | 10 | #include "PagedGeometryConfig.h" 11 | #include 12 | 13 | #if OGRE_PLATFORM == OGRE_PLATFORM_WIN32 14 | #include 15 | #endif 16 | 17 | #include 18 | #include 19 | 20 | using namespace Ogre; 21 | 22 | 23 | //Include PagedGeometry headers that will be needed 24 | #include "PagedGeometry.h" 25 | #include "GrassLoader.h" 26 | 27 | //Include "LegacyTerrainLoader.h", a header that allows loading Ogre 1.7 style terrain 28 | #include "LegacyTerrainLoader.h" 29 | 30 | //Include "HeightFunction.h", a header that provides some useful functions for quickly and easily 31 | //getting the height of the terrain at a given point. 32 | #include "HeightFunction.h" 33 | //[NOTE] Remember that this "HeightFunction.h" file is not related to the PagedGeometry library itself 34 | //in any way. It's simply a utility that's included with all these examples to make getting the terrain 35 | //height easy. You can use it in your games/applications if you want, although if you're using a 36 | //collision/physics library with a faster alternate, you may use that instead. 37 | 38 | //PagedGeometry's classes and functions are under the "Forests" namespace 39 | using namespace Forests; 40 | 41 | //Demo world class 42 | //[NOTE] The main PagedGeometry-related sections of this class are load() and 43 | //render. These functions setup and use PagedGeometry in the scene. 44 | class World : public TerrainWorld 45 | { 46 | public: 47 | World(RenderWindow* win); 48 | 49 | void load(); //Loads the 3D scene 50 | void unload(); //Unloads the 3D scene cleanly 51 | void run(); //Runs the simulation 52 | 53 | void render(); //Renders a single frame, updating PagedGeometry and Ogre 54 | 55 | //Various pointers to Ogre objects are stored here: 56 | RenderWindow *window; 57 | Viewport *viewport; 58 | Camera *camera; 59 | SceneNode* cameraNode; 60 | 61 | //Pointers to PagedGeometry class instances: 62 | PagedGeometry *grass; 63 | GrassLoader *grassLoader; 64 | }; 65 | 66 | #if OGRE_PLATFORM == OGRE_PLATFORM_WIN32 67 | INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE hPrevInstance, LPSTR strCmdLine, INT nCmdShow) 68 | #else 69 | int main(int argc, char *argv[]) 70 | #endif 71 | { 72 | //Initialize Ogre 73 | OgreBites::ApplicationContext ctx; 74 | ctx.initApp(); 75 | ctx.setWindowGrab(true); 76 | 77 | World myWorld(ctx.getRenderWindow()); 78 | myWorld.load(); //Load world 79 | 80 | OgreBites::CameraMan camman(myWorld.cameraNode); 81 | ctx.addInputListener(&camman); 82 | 83 | myWorld.run(); //Display world 84 | 85 | myWorld.unload(); 86 | 87 | //Shut down Ogre 88 | ctx.closeApp(); 89 | 90 | return 0; 91 | } 92 | 93 | World::World(RenderWindow* win) 94 | { 95 | window = win; 96 | 97 | //Initialize the camera and viewport 98 | camera = sceneMgr->createCamera("MainCamera"); 99 | viewport = window->addViewport(camera); 100 | viewport->setBackgroundColour(ColourValue(0.47f, 0.67f, 0.96f)); //Blue sky background color 101 | camera->setAspectRatio(Real(viewport->getActualWidth()) / Real(viewport->getActualHeight())); 102 | camera->setNearClipDistance(1.0f); 103 | camera->setFarClipDistance(2000.0f); 104 | 105 | cameraNode = sceneMgr->getRootSceneNode()->createChildSceneNode(); 106 | cameraNode->attachObject(camera); 107 | 108 | //Set up lighting 109 | Light *light = sceneMgr->createLight("Sun"); 110 | light->setType(Light::LT_DIRECTIONAL); 111 | sceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(light); 112 | light->getParentSceneNode()->setDirection(Vector3(0.0f, -0.5f, 1.0f)); 113 | sceneMgr->setAmbientLight(ColourValue(1, 1, 1)); 114 | 115 | } 116 | 117 | //[NOTE] In addition to some Ogre setup, this function configures PagedGeometry in the scene. 118 | void World::load() 119 | { 120 | //-------------------------------------- LOAD TERRAIN -------------------------------------- 121 | //Setup the fog up to 500 units away 122 | sceneMgr->setFog(FOG_LINEAR, viewport->getBackgroundColour(), 0, 100, 700); 123 | 124 | //Load the terrain 125 | terrain = loadLegacyTerrain("terrain.cfg", sceneMgr); 126 | 127 | //Start off with the camera at the center of the terrain 128 | cameraNode->setPosition(700, 100, 700); 129 | 130 | //-------------------------------------- LOAD GRASS -------------------------------------- 131 | //Create and configure a new PagedGeometry instance for grass 132 | grass = new PagedGeometry(camera, 50); 133 | grass->addDetailLevel(150); 134 | 135 | //Create a GrassLoader object 136 | grassLoader = new GrassLoader(grass); 137 | grass->setPageLoader(grassLoader); //Assign the "treeLoader" to be used to load geometry for the PagedGeometry instance 138 | 139 | //Supply a height function to GrassLoader so it can calculate grass Y values 140 | HeightFunction::initialize(terrain); 141 | grassLoader->setHeightFunction(&HeightFunction::getTerrainHeight); 142 | 143 | //Add some grass to the scene with GrassLoader::addLayer() 144 | GrassLayer *l = grassLoader->addLayer("grass"); 145 | 146 | //Configure the grass layer properties (size, density, animation properties, fade settings, etc.) 147 | l->setMinimumSize(2.0f, 2.0f); 148 | l->setMaximumSize(2.5f, 2.5f); 149 | l->setAnimationEnabled(true); //Enable animations 150 | l->setSwayDistribution(10.0f); //Sway fairly unsynchronized 151 | l->setSwayLength(0.5f); //Sway back and forth 0.5 units in length 152 | l->setSwaySpeed(0.5f); //Sway 1/2 a cycle every second 153 | l->setDensity(1.5f); //Relatively dense grass 154 | l->setFadeTechnique(FADETECH_GROW); //Distant grass should slowly raise out of the ground when coming in range 155 | l->setRenderTechnique(GRASSTECH_QUAD); //Draw grass as scattered quads 156 | 157 | //This sets a color map to be used when determining the color of each grass quad. setMapBounds() 158 | //is used to set the area which is affected by the color map. Here, "terrain_texture.jpg" is used 159 | //to color the grass to match the terrain under it. 160 | l->setColorMap("terrain_texture.jpg"); 161 | l->setMapBounds(TBounds(0, 0, 1500, 1500)); //(0,0)-(1500,1500) is the full boundaries of the terrain 162 | 163 | } 164 | 165 | void World::unload() 166 | { 167 | //[NOTE] Always remember to delete any PageLoader(s) and PagedGeometry instances in order to avoid memory leaks. 168 | 169 | //Delete the GrassLoader instance 170 | delete grass->getPageLoader(); 171 | 172 | //Delete the PagedGeometry instance 173 | delete grass; 174 | 175 | unloadTerrain(); 176 | } 177 | 178 | void World::run() 179 | { 180 | //Render loop 181 | while(!Root::getSingleton().endRenderingQueued()) 182 | { 183 | //Update frame 184 | render(); 185 | } 186 | } 187 | 188 | void World::render() 189 | { 190 | //[NOTE] PagedGeometry::update() is called every frame to keep LODs, etc. up-to-date 191 | grass->update(); 192 | 193 | //Render the scene with Ogre 194 | root->renderOneFrame(); 195 | } 196 | -------------------------------------------------------------------------------- /examples/Example5.cpp: -------------------------------------------------------------------------------- 1 | //=============================================================================================================== 2 | //Example 5 - Dynamic Trees 3 | //--------------------------------------------------------------------------------------------------------------- 4 | // This example demonstrates the use of TreeLoader2D to dynamically add/remove trees. 5 | // Instructions: Move around with arrow/WASD keys. Left mouse button adds trees, right mouse button deletes trees. 6 | // HINT: Search this source for "[NOTE]" to find important code and comments related to PagedGeometry. 7 | //=============================================================================================================== 8 | #define AppTitle "PagedGeometry Example 5 - Dynamic Trees" 9 | 10 | #include "PagedGeometryConfig.h" 11 | #include 12 | 13 | #if OGRE_PLATFORM == OGRE_PLATFORM_WIN32 14 | #include 15 | #endif 16 | 17 | #include 18 | #include 19 | 20 | using namespace Ogre; 21 | 22 | 23 | //Include PagedGeometry headers that will be needed 24 | #include "PagedGeometry.h" 25 | #include "BatchPage.h" 26 | #include "ImpostorPage.h" 27 | #include "TreeLoader2D.h" 28 | 29 | //Include "LegacyTerrainLoader.h", a header that allows loading Ogre 1.7 style terrain 30 | #include "LegacyTerrainLoader.h" 31 | 32 | //Include "HeightFunction.h", a header that provides some useful functions for quickly and easily 33 | //getting the height of the terrain at a given point. 34 | #include "HeightFunction.h" 35 | //[NOTE] Remember that this "HeightFunction.h" file is not related to the PagedGeometry library itself 36 | //in any way. It's simply a utility that's included with all these examples to make getting the terrain 37 | //height easy. You can use it in your games/applications if you want, although if you're using a 38 | //collision/physics library with a faster alternate, you may use that instead. 39 | 40 | //PagedGeometry's classes and functions are under the "Forests" namespace 41 | using namespace Forests; 42 | 43 | //Demo world class 44 | //[NOTE] The main PagedGeometry-related sections of this class are load() and 45 | //render. These functions setup and use PagedGeometry in the scene. 46 | class World : public TerrainWorld 47 | { 48 | public: 49 | World(RenderWindow* win); 50 | 51 | void load(); //Loads the 3D scene 52 | void unload(); //Unloads the 3D scene cleanly 53 | void run(); //Runs the simulation 54 | 55 | void render(); //Renders a single frame, updating PagedGeometry and Ogre 56 | 57 | //Various pointers to Ogre objects are stored here: 58 | RenderWindow *window; 59 | Viewport *viewport; 60 | Camera *camera; 61 | SceneNode* cameraNode; 62 | 63 | //Pointers to PagedGeometry class instances: 64 | PagedGeometry *trees; 65 | TreeLoader2D *treeLoader; 66 | 67 | //The tree entity being used in this demo (stored for later use when dynamically adding trees) 68 | Entity *myTree; 69 | }; 70 | 71 | #if OGRE_PLATFORM == OGRE_PLATFORM_WIN32 72 | INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE hPrevInstance, LPSTR strCmdLine, INT nCmdShow) 73 | #else 74 | int main(int argc, char *argv[]) 75 | #endif 76 | { 77 | //Initialize Ogre 78 | OgreBites::ApplicationContext ctx; 79 | ctx.initApp(); 80 | ctx.setWindowGrab(true); 81 | 82 | World myWorld(ctx.getRenderWindow()); 83 | myWorld.load(); //Load world 84 | 85 | OgreBites::CameraMan camman(myWorld.cameraNode); 86 | ctx.addInputListener(&camman); 87 | 88 | myWorld.run(); //Display world 89 | 90 | myWorld.unload(); 91 | 92 | //Shut down Ogre 93 | ctx.closeApp(); 94 | 95 | return 0; 96 | } 97 | 98 | World::World(RenderWindow* win) 99 | { 100 | window = win; 101 | 102 | //Initialize the camera and viewport 103 | camera = sceneMgr->createCamera("MainCamera"); 104 | viewport = window->addViewport(camera); 105 | viewport->setBackgroundColour(ColourValue(0.47f, 0.67f, 0.96f)); //Blue sky background color 106 | camera->setAspectRatio(Real(viewport->getActualWidth()) / Real(viewport->getActualHeight())); 107 | camera->setNearClipDistance(1.0f); 108 | camera->setFarClipDistance(2000.0f); 109 | 110 | cameraNode = sceneMgr->getRootSceneNode()->createChildSceneNode(); 111 | cameraNode->attachObject(camera); 112 | 113 | //Set up lighting 114 | Light *light = sceneMgr->createLight("Sun"); 115 | light->setType(Light::LT_DIRECTIONAL); 116 | sceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(light); 117 | light->getParentSceneNode()->setDirection(Vector3(0.0f, -0.5f, 1.0f)); 118 | sceneMgr->setAmbientLight(Ogre::ColourValue(1, 1, 1)); 119 | } 120 | 121 | //[NOTE] In addition to some Ogre setup, this function configures PagedGeometry in the scene. 122 | void World::load() 123 | { 124 | //-------------------------------------- LOAD TERRAIN -------------------------------------- 125 | //Setup the fog up to 500 units away 126 | sceneMgr->setFog(FOG_LINEAR, viewport->getBackgroundColour(), 0, 100, 700); 127 | 128 | //Load the terrain 129 | terrain = loadLegacyTerrain("terrain.cfg", sceneMgr); 130 | 131 | //Start off with the camera at the center of the terrain 132 | cameraNode->setPosition(700, 100, 700); 133 | 134 | //-------------------------------------- LOAD TREES -------------------------------------- 135 | //Create and configure a new PagedGeometry instance 136 | trees = new PagedGeometry(); 137 | trees->setCamera(camera); //Set the camera so PagedGeometry knows how to calculate LODs 138 | trees->setPageSize(80); //Set the size of each page of geometry 139 | trees->setInfinite(); //Use infinite paging mode 140 | trees->addDetailLevel(150, 50); //Use batches up to 150 units away, and fade for 30 more units 141 | trees->addDetailLevel(500, 50); //Use impostors up to 400 units, and for for 50 more units 142 | 143 | //Create a new TreeLoader2D object 144 | treeLoader = new TreeLoader2D(trees, TBounds(0, 0, 1500, 1500)); 145 | trees->setPageLoader(treeLoader); //Assign the "treeLoader" to be used to load geometry for the PagedGeometry instance 146 | 147 | //Supply a height function to TreeLoader2D so it can calculate tree Y values 148 | HeightFunction::initialize(terrain); 149 | treeLoader->setHeightFunction(&HeightFunction::getTerrainHeight); 150 | 151 | //Load a tree entity 152 | myTree = sceneMgr->createEntity("Tree", "tree2.mesh"); 153 | 154 | //Randomly place 2000 copies of the tree on the terrain. 155 | //More will be added later by the user (see World::processInput()) 156 | Vector3 position = Vector3::ZERO; 157 | Radian yaw; 158 | Real scale; 159 | for (int i = 0; i < 2000; i++){ 160 | yaw = Degree(Math::RangeRandom(0, 360)); 161 | position.x = Math::RangeRandom(0, 1500); 162 | position.z = Math::RangeRandom(0, 1500); 163 | scale = Math::RangeRandom(0.5f, 0.6f); 164 | 165 | treeLoader->addTree(myTree, position, yaw, scale); 166 | } 167 | } 168 | 169 | void World::unload() 170 | { 171 | //[NOTE] Always remember to delete any PageLoader(s) and PagedGeometry instances in order to avoid memory leaks. 172 | 173 | //Delete the TreeLoader2D instance 174 | delete trees->getPageLoader(); 175 | 176 | //Delete the PagedGeometry instance 177 | delete trees; 178 | 179 | //Also delete the tree entity 180 | sceneMgr->destroyEntity("Tree"); 181 | 182 | unloadTerrain(); 183 | } 184 | 185 | void World::run() 186 | { 187 | //Render loop 188 | while(!Root::getSingleton().endRenderingQueued()) 189 | { 190 | //Update frame 191 | render(); 192 | } 193 | } 194 | 195 | void World::render() 196 | { 197 | //[NOTE] PagedGeometry::update() is called every frame to keep LODs, etc. up-to-date 198 | trees->update(); 199 | 200 | //Render the scene with Ogre 201 | root->renderOneFrame(); 202 | } 203 | -------------------------------------------------------------------------------- /examples/Example6.cpp: -------------------------------------------------------------------------------- 1 | //=============================================================================================================== 2 | //Example 6 - Custom PageLoader 3 | //--------------------------------------------------------------------------------------------------------------- 4 | // This example demonstrates the use of a custom PageLoader by creating a procedural tree loader (advanced). 5 | // Instructions: Move around with the arrow/WASD keys, hold SHIFT to move faster, and hold SPACE to fly. 6 | // HINT: Search this source for "[NOTE]" to find important code and comments related to PagedGeometry. 7 | //=============================================================================================================== 8 | #define AppTitle "PagedGeometry Example 6 - Custom PageLoader" 9 | 10 | 11 | #include "PagedGeometryConfig.h" 12 | #include 13 | 14 | #if OGRE_PLATFORM == OGRE_PLATFORM_WIN32 15 | #include 16 | #endif 17 | 18 | #include 19 | #include 20 | 21 | using namespace Ogre; 22 | 23 | 24 | //Include PagedGeometry headers that will be needed 25 | #include "PagedGeometry.h" 26 | #include "BatchPage.h" 27 | #include "ImpostorPage.h" 28 | #include "TreeLoader3D.h" 29 | 30 | //Include "LegacyTerrainLoader.h", a header that allows loading Ogre 1.7 style terrain 31 | #include "LegacyTerrainLoader.h" 32 | 33 | //Include "HeightFunction.h", a header that provides some useful functions for quickly and easily 34 | //getting the height of the terrain at a given point. 35 | #include "HeightFunction.h" 36 | //[NOTE] Remember that this "HeightFunction.h" file is not related to the PagedGeometry library itself 37 | //in any way. It's simply a utility that's included with all these examples to make getting the terrain 38 | //height easy. You can use it in your games/applications if you want, although if you're using a 39 | //collision/physics library with a faster alternate, you may use that instead. 40 | 41 | //PagedGeometry's classes and functions are under the "Forests" namespace 42 | using namespace Forests; 43 | 44 | //Demo world class 45 | //[NOTE] The main PagedGeometry-related sections of this class are load() and 46 | //render. These functions setup and use PagedGeometry in the scene. 47 | class World : public TerrainWorld 48 | { 49 | public: 50 | World(RenderWindow* win); 51 | 52 | void load(); //Loads the 3D scene 53 | void unload(); //Unloads the 3D scene cleanly 54 | void run(); //Runs the simulation 55 | 56 | void render(); //Renders a single frame, updating PagedGeometry and Ogre 57 | 58 | //Various pointers to Ogre objects are stored here: 59 | RenderWindow *window; 60 | Viewport *viewport; 61 | Camera *camera; 62 | SceneNode* cameraNode; 63 | 64 | //Pointers to PagedGeometry class instances: 65 | PagedGeometry *trees; 66 | }; 67 | 68 | 69 | //--------------------------------------- Custom PageLoader class ----------------------------------------------- 70 | //[NOTE] This is where the custom PageLoader class, "ProceduralLoader", is defined. Making a custom 71 | //PageLoader class is as simple as implementing a PageLoader-derived class. The API reference contains 72 | //detailed instructions on doing this (see the PageLoader documentation), but basically you just 73 | //implement a loadPage() function which adds trees to the scene when the PagedGeometry engine requests 74 | //a certain region to be loaded. 75 | class ProceduralLoader: public PageLoader 76 | { 77 | public: 78 | ProceduralLoader(SceneManager *sceneMgr); 79 | ~ProceduralLoader(); 80 | void loadPage(PageInfo &page); 81 | 82 | private: 83 | Entity *myTree; 84 | SceneManager *sceneMgr; 85 | }; 86 | 87 | ProceduralLoader::ProceduralLoader(SceneManager *sceneMgr) 88 | { 89 | //Load a tree entity 90 | this->sceneMgr = sceneMgr; 91 | myTree = sceneMgr->createEntity("Tree", "tree2.mesh"); 92 | } 93 | 94 | ProceduralLoader::~ProceduralLoader() 95 | { 96 | //Delete the tree entity 97 | sceneMgr->destroyEntity("Tree"); 98 | } 99 | 100 | void ProceduralLoader::loadPage(PageInfo &page) 101 | { 102 | //[NOTE] When this function (loadPage) is called, the PagedGeometry engine needs a certain region of 103 | //geometry to be loaded immediately. You can implement this function any way you like, loading your 104 | //trees from RAM, a hard drive, the internet, or even procedurally. In this example, a very simple 105 | //procedural implementation is used which basically places trees randomly on the terrain. 106 | 107 | //This may appear similar to the code seen in other examples where trees are randomly added to 108 | //TreeLoader3D or TreeLoader2D, but this method is much more direct. While the TreeLoader classes 109 | //store the tree positions in memory and retrieve them later when loadPage() is called, this directly 110 | //generates the random tree positions of requested areas. The primary difference from the user's point 111 | //of view is that this demo ProceduralLoader class uses no memory, and can produce an infinite amount of 112 | //trees in infinite mode (you can test this by commenting out the trees->setBounds() line below in 113 | //World::load() - the trees should extend infinitely, although the terrain won't). 114 | 115 | Ogre::Vector3 position; 116 | Ogre::Quaternion rotation; 117 | Ogre::Vector3 scale; 118 | Ogre::ColourValue color; 119 | for (int i = 0; i < 100; i++){ 120 | //Calculate a random rotation around the Y axis 121 | rotation = Ogre::Quaternion(Degree(Math::RangeRandom(0, 360)), Ogre::Vector3::UNIT_Y); 122 | 123 | //Note that the position is within the page.bounds boundaries. "page.bounds" specifies 124 | //the area of the world that needs to be loaded. 125 | position.x = Math::RangeRandom(page.bounds.left, page.bounds.right); 126 | position.z = Math::RangeRandom(page.bounds.top, page.bounds.bottom); 127 | position.y = HeightFunction::getTerrainHeight(position.x, position.z); 128 | 129 | //Calculate a scale value (uniformly scaled in all dimensions) 130 | float uniformScale = Math::RangeRandom(0.5f, 0.6f); 131 | scale.x = uniformScale; 132 | scale.y = uniformScale; 133 | scale.z = uniformScale; 134 | 135 | //All trees will be fully lit in this demo 136 | color = ColourValue::White; 137 | 138 | //[NOTE] addEntity() is used to add trees to the scene from PageLoader::loadPage(). 139 | addEntity(myTree, position, rotation, scale, color); 140 | } 141 | } 142 | //--------------------------------------------------------------------------------------------------------------- 143 | 144 | 145 | #if OGRE_PLATFORM == OGRE_PLATFORM_WIN32 146 | INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE hPrevInstance, LPSTR strCmdLine, INT nCmdShow) 147 | #else 148 | int main(int argc, char *argv[]) 149 | #endif 150 | { 151 | //Initialize Ogre 152 | OgreBites::ApplicationContext ctx; 153 | ctx.initApp(); 154 | ctx.setWindowGrab(true); 155 | 156 | World myWorld(ctx.getRenderWindow()); 157 | myWorld.load(); //Load world 158 | 159 | OgreBites::CameraMan camman(myWorld.cameraNode); 160 | ctx.addInputListener(&camman); 161 | 162 | myWorld.run(); //Display world 163 | 164 | myWorld.unload(); 165 | 166 | //Shut down Ogre 167 | ctx.closeApp(); 168 | 169 | return 0; 170 | } 171 | 172 | World::World(RenderWindow* win) 173 | { 174 | window = win; 175 | 176 | //Initialize the camera and viewport 177 | camera = sceneMgr->createCamera("MainCamera"); 178 | viewport = window->addViewport(camera); 179 | viewport->setBackgroundColour(ColourValue(0.47f, 0.67f, 0.96f)); //Blue sky background color 180 | camera->setAspectRatio(Real(viewport->getActualWidth()) / Real(viewport->getActualHeight())); 181 | camera->setNearClipDistance(1.0f); 182 | camera->setFarClipDistance(2000.0f); 183 | 184 | cameraNode = sceneMgr->getRootSceneNode()->createChildSceneNode(); 185 | cameraNode->attachObject(camera); 186 | 187 | //Set up lighting 188 | Light *light = sceneMgr->createLight("Sun"); 189 | light->setType(Light::LT_DIRECTIONAL); 190 | sceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(light); 191 | light->getParentSceneNode()->setDirection(Vector3(0.0f, -0.5f, 1.0f)); 192 | sceneMgr->setAmbientLight(Ogre::ColourValue(1, 1, 1)); 193 | } 194 | 195 | //[NOTE] In addition to some Ogre setup, this function configures PagedGeometry in the scene. 196 | void World::load() 197 | { 198 | //-------------------------------------- LOAD TERRAIN -------------------------------------- 199 | //Setup the fog up to 500 units away 200 | sceneMgr->setFog(FOG_LINEAR, viewport->getBackgroundColour(), 0, 100, 700); 201 | 202 | //Load the terrain 203 | terrain = loadLegacyTerrain("terrain.cfg", sceneMgr); 204 | 205 | //Setup the height function (so the Y values of trees can be calculated when they are placed on the terrain) 206 | HeightFunction::initialize(terrain); 207 | 208 | //Start off with the camera at the center of the terrain 209 | cameraNode->setPosition(700, 100, 700); 210 | 211 | //-------------------------------------- LOAD TREES -------------------------------------- 212 | //Create and configure a new PagedGeometry instance 213 | trees = new PagedGeometry(); 214 | trees->setCamera(camera); //Set the camera so PagedGeometry knows how to calculate LODs 215 | trees->setPageSize(100); //Set the size of each page of geometry 216 | trees->setBounds(TBounds(0, 0, 1500, 1500)); //Force a boundary on the trees, since ProceduralLoader is infinite 217 | trees->addDetailLevel(150, 50); //Use batches up to 150 units away, and fade for 30 more units 218 | trees->addDetailLevel(500, 50); //Use impostors up to 400 units, and for for 50 more units 219 | 220 | //Create an instance of the custom PageLoader class, called "ProceduralLoader" 221 | ProceduralLoader *treeLoader = new ProceduralLoader(sceneMgr); 222 | trees->setPageLoader(treeLoader); 223 | 224 | //[NOTE] The ProceduralLoader will now randomly place trees on the terrain when PagedGeometry needs them. 225 | //The actual implementation of the ProceduralLoader class can be found above. 226 | } 227 | 228 | void World::unload() 229 | { 230 | //[NOTE] Always remember to delete any PageLoader(s) and PagedGeometry instances in order to avoid memory leaks. 231 | 232 | //Delete the TreeLoader3D instance 233 | delete trees->getPageLoader(); 234 | 235 | //Delete the PagedGeometry instance 236 | delete trees; 237 | 238 | unloadTerrain(); 239 | } 240 | 241 | void World::run() 242 | { 243 | //Render loop 244 | while(!Root::getSingleton().endRenderingQueued()) 245 | { 246 | //Update frame 247 | render(); 248 | } 249 | } 250 | 251 | void World::render() 252 | { 253 | //[NOTE] PagedGeometry::update() is called every frame to keep LODs, etc. up-to-date 254 | trees->update(); 255 | 256 | //Render the scene with Ogre 257 | root->renderOneFrame(); 258 | } 259 | -------------------------------------------------------------------------------- /examples/Example9.cpp: -------------------------------------------------------------------------------- 1 | #include "PGExampleApplication.h" 2 | 3 | #include "PagedGeometry.h" 4 | #include "BatchPage.h" 5 | #include "WindBatchPage.h" 6 | #include "TreeLoader3D.h" 7 | #include "TreeLoader2D.h" 8 | #include "ImpostorPage.h" 9 | #include "GrassLoader.h" 10 | 11 | #include "HeightFunction.h" 12 | 13 | using namespace Forests; 14 | 15 | // we use wind pages 16 | #define WIND 17 | 18 | // SAMPLE CLASS 19 | class PGSampleApp : public ExampleApplication 20 | { 21 | public: 22 | PGSampleApp(); 23 | void createPGDemo(void); 24 | protected: 25 | }; 26 | 27 | // SAMPLE IMPLEMENTATION 28 | PGSampleApp::PGSampleApp() : ExampleApplication() 29 | { 30 | } 31 | 32 | void PGSampleApp::createPGDemo(void) 33 | { 34 | //-------------------------------------- LOAD GRASS -------------------------------------- 35 | //Create and configure a new PagedGeometry instance for grass 36 | PagedGeometry *grass = new PagedGeometry(mCamera, 30); 37 | grass->addDetailLevel(60); 38 | 39 | //Create a GrassLoader object 40 | GrassLoader *grassLoader = new GrassLoader(grass); 41 | grass->setPageLoader(grassLoader); //Assign the "treeLoader" to be used to load geometry for the PagedGeometry instance 42 | 43 | //Supply a height function to GrassLoader so it can calculate grass Y values 44 | HeightFunction::initialize(mTerrainGroup); 45 | grassLoader->setHeightFunction(&HeightFunction::getTerrainHeight); 46 | 47 | //Add some grass to the scene with GrassLoader::addLayer() 48 | GrassLayer *l = grassLoader->addLayer("3D-Diggers/plant1sprite"); 49 | 50 | //Configure the grass layer properties (size, density, animation properties, fade settings, etc.) 51 | l->setMinimumSize(0.7f, 0.7f); 52 | l->setMaximumSize(0.9f, 0.9f); 53 | l->setAnimationEnabled(true); //Enable animations 54 | l->setSwayDistribution(7.0f); //Sway fairly unsynchronized 55 | l->setSwayLength(0.1f); //Sway back and forth 0.5 units in length 56 | l->setSwaySpeed(0.4f); //Sway 1/2 a cycle every second 57 | l->setDensity(3.0f); //Relatively dense grass 58 | l->setRenderTechnique(GRASSTECH_SPRITE); 59 | l->setFadeTechnique(FADETECH_GROW); //Distant grass should slowly raise out of the ground when coming in range 60 | 61 | //[NOTE] This sets the color map, or lightmap to be used for grass. All grass will be colored according 62 | //to this texture. In this case, the colors of the terrain is used so grass will be shadowed/colored 63 | //just as the terrain is (this usually makes the grass fit in very well). 64 | l->setColorMap("terrain_texture2.jpg"); 65 | 66 | //This sets the density map that will be used to determine the density levels of grass all over the 67 | //terrain. This can be used to make grass grow anywhere you want to; in this case it's used to make 68 | //grass grow only on fairly level ground (see densitymap.png to see how this works). 69 | l->setDensityMap("densitymap.png"); 70 | 71 | //setMapBounds() must be called for the density and color maps to work (otherwise GrassLoader wouldn't 72 | //have any knowledge of where you want the maps to be applied). In this case, the maps are applied 73 | //to the same boundaries as the terrain. 74 | l->setMapBounds(TBounds(0, 0, 1500, 1500)); //(0,0)-(1500,1500) is the full boundaries of the terrain 75 | addPG(grass); 76 | 77 | //-------------------------------------- LOAD TREES -------------------------------------- 78 | //Create and configure a new PagedGeometry instance 79 | PagedGeometry *trees = new PagedGeometry(); 80 | trees->setCamera(mCamera); //Set the camera so PagedGeometry knows how to calculate LODs 81 | trees->setPageSize(50); //Set the size of each page of geometry 82 | trees->setInfinite(); //Use infinite paging mode 83 | 84 | #ifdef WIND 85 | //WindBatchPage is a variation of BatchPage which includes a wind animation shader 86 | trees->addDetailLevel(90, 30); //Use batches up to 150 units away, and fade for 30 more units 87 | #else 88 | trees->addDetailLevel(90, 30); //Use batches up to 150 units away, and fade for 30 more units 89 | #endif 90 | trees->addDetailLevel(700, 50); //Use impostors up to 400 units, and for for 50 more units 91 | 92 | //Create a new TreeLoader2D object 93 | TreeLoader2D *treeLoader = new TreeLoader2D(trees, TBounds(0, 0, 1500, 1500)); 94 | trees->setPageLoader(treeLoader); //Assign the "treeLoader" to be used to load geometry for the PagedGeometry instance 95 | 96 | //Supply a height function to TreeLoader2D so it can calculate tree Y values 97 | treeLoader->setHeightFunction(&HeightFunction::getTerrainHeight); 98 | 99 | //[NOTE] This sets the color map, or lightmap to be used for trees. All trees will be colored according 100 | //to this texture. In this case, the shading of the terrain is used so trees will be shadowed 101 | //just as the terrain is (this should appear like the terrain is casting shadows on the trees). 102 | //You may notice that TreeLoader2D / TreeLoader3D doesn't have a setMapBounds() function as GrassLoader 103 | //does. This is because the bounds you specify in the TreeLoader2D constructor are used to apply 104 | //the color map. 105 | treeLoader->setColorMap("terrain_lightmap.jpg"); 106 | 107 | //Load a tree entity 108 | Entity *tree1 = mSceneMgr->createEntity("Tree1", "fir05_30.mesh"); 109 | 110 | Entity *tree2 = mSceneMgr->createEntity("Tree2", "fir14_25.mesh"); 111 | 112 | #ifdef WIND 113 | trees->setCustomParam(tree1->getName(), "windFactorX", 15); 114 | trees->setCustomParam(tree1->getName(), "windFactorY", 0.01); 115 | trees->setCustomParam(tree2->getName(), "windFactorX", 22); 116 | trees->setCustomParam(tree2->getName(), "windFactorY", 0.013); 117 | #endif 118 | 119 | //Randomly place 10000 copies of the tree on the terrain 120 | Ogre::Vector3 position = Ogre::Vector3::ZERO; 121 | Radian yaw; 122 | Real scale; 123 | for (int i = 0; i < 10000; i++){ 124 | yaw = Degree(Math::RangeRandom(0, 360)); 125 | 126 | position.x = Math::RangeRandom(0, 1500); 127 | position.z = Math::RangeRandom(0, 1500); 128 | 129 | scale = Math::RangeRandom(0.07f, 0.12f); 130 | 131 | //[NOTE] Unlike TreeLoader3D, TreeLoader2D's addTree() function accepts a Vector2D position (x/z) 132 | //The Y value is calculated during runtime (to save memory) from the height function supplied (above) 133 | if (Math::UnitRandom() < 0.5f) 134 | treeLoader->addTree(tree1, position, yaw, scale); 135 | else 136 | treeLoader->addTree(tree2, position, yaw, scale); 137 | } 138 | addPG(trees); 139 | 140 | //-------------------------------------- LOAD BUSHES -------------------------------------- 141 | //Create and configure a new PagedGeometry instance for bushes 142 | PagedGeometry *bushes = new PagedGeometry(mCamera, 50); 143 | 144 | #ifdef WIND 145 | bushes->addDetailLevel(80, 50); 146 | #else 147 | bushes->addDetailLevel(80, 50); 148 | #endif 149 | 150 | //Create a new TreeLoader2D object for the bushes 151 | TreeLoader2D *bushLoader = new TreeLoader2D(bushes, TBounds(0, 0, 1500, 1500)); 152 | bushes->setPageLoader(bushLoader); 153 | 154 | //Supply the height function to TreeLoader2D so it can calculate tree Y values 155 | bushLoader->setHeightFunction(&HeightFunction::getTerrainHeight); 156 | 157 | bushLoader->setColorMap("terrain_lightmap.jpg"); 158 | 159 | //Load a bush entity 160 | Entity *fern = mSceneMgr->createEntity("Fern", "farn1.mesh"); 161 | 162 | Entity *plant = mSceneMgr->createEntity("Plant", "plant2.mesh"); 163 | 164 | Entity *mushroom = mSceneMgr->createEntity("Mushroom", "shroom1_1.mesh"); 165 | 166 | #ifdef WIND 167 | bushes->setCustomParam(fern->getName(), "factorX", 1); 168 | bushes->setCustomParam(fern->getName(), "factorY", 0.01); 169 | 170 | bushes->setCustomParam(plant->getName(), "factorX", 0.6); 171 | bushes->setCustomParam(plant->getName(), "factorY", 0.02); 172 | #endif 173 | 174 | //Randomly place 20,000 bushes on the terrain 175 | for (int i = 0; i < 20000; i++){ 176 | yaw = Degree(Math::RangeRandom(0, 360)); 177 | position.x = Math::RangeRandom(0, 1500); 178 | position.z = Math::RangeRandom(0, 1500); 179 | 180 | float rnd = Math::UnitRandom(); 181 | if (rnd < 0.8f) { 182 | scale = Math::RangeRandom(0.3f, 0.4f); 183 | bushLoader->addTree(fern, position, yaw, scale); 184 | } else if (rnd < 0.9) { 185 | scale = Math::RangeRandom(0.2f, 0.6f); 186 | bushLoader->addTree(mushroom, position, yaw, scale); 187 | } else { 188 | scale = Math::RangeRandom(0.3f, 0.5f); 189 | bushLoader->addTree(plant, position, yaw, scale); 190 | } 191 | } 192 | 193 | addPG(bushes); 194 | 195 | } 196 | 197 | // MAIN BELOW 198 | #if OGRE_PLATFORM == OGRE_PLATFORM_WIN32 199 | INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE hPrevInstance, LPSTR strCmdLine, INT nCmdShow) 200 | #else 201 | int main(int argc, char *argv[]) 202 | #endif 203 | { 204 | 205 | PGSampleApp *app = new PGSampleApp(); 206 | app->go(); 207 | 208 | return 0; 209 | } 210 | -------------------------------------------------------------------------------- /examples/HeightFunction.h: -------------------------------------------------------------------------------- 1 | //This provides functions that can be used to easily get the height of Ogre's terrain at any x/z point. 2 | //Simply call HeightFunction::initialize(), then use HeightFunction::getTerrainHeight() as needed. 3 | 4 | //This file is used by the PagedGeometry examples to place trees on the terrain. 5 | 6 | #include "OgreTerrainGroup.h" 7 | 8 | namespace HeightFunction 9 | { 10 | Ogre::TerrainGroup* terrain = NULL; 11 | 12 | //Initializes the height function. Call this before calling getTerrainHeight() 13 | void initialize(Ogre::TerrainGroup* terrainGroup) { 14 | if (!terrain){ 15 | terrain = terrainGroup; 16 | } 17 | } 18 | 19 | //Gets the height of the terrain at the specified x/z coordinate 20 | //The userData parameter isn't used in this implementation of a height function, since 21 | //there's no need for extra data other than the x/z coordinates. 22 | inline float getTerrainHeight(const float x, const float z, void *userData = NULL) { 23 | return terrain->getHeightAtWorldPosition(x, 0, z); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /examples/LegacyTerrainLoader.h: -------------------------------------------------------------------------------- 1 | /* 2 | ----------------------------------------------------------------------------- 3 | This source file is part of OGRE 4 | (Object-oriented Graphics Rendering Engine) 5 | For the latest info, see http://www.ogre3d.org/ 6 | 7 | Copyright (c) 2000-2009 Torus Knot Software Ltd 8 | Also see acknowledgements in Readme.html 9 | 10 | You may use this sample code for anything you like, it is not covered by the 11 | same license as the rest of the engine. 12 | ----------------------------------------------------------------------------- 13 | */ 14 | 15 | #include 16 | 17 | struct TerrainWorld 18 | { 19 | Ogre::Root *root; 20 | Ogre::SceneManager *sceneMgr; 21 | Ogre::TerrainGroup* terrain = nullptr; 22 | 23 | TerrainWorld() 24 | { 25 | //Setup Ogre::Root and the scene manager 26 | root = Ogre::Root::getSingletonPtr(); 27 | sceneMgr = root->createSceneManager(); 28 | Ogre::RTShader::ShaderGenerator::getSingleton().addSceneManager(sceneMgr); 29 | } 30 | 31 | void unloadTerrain() 32 | { 33 | delete terrain; 34 | delete Ogre::TerrainGlobalOptions::getSingletonPtr(); 35 | } 36 | }; 37 | 38 | inline Ogre::TerrainGroup* loadLegacyTerrain(const Ogre::String& cfgFileName, Ogre::SceneManager* sceneMgr) 39 | { 40 | using namespace Ogre; 41 | 42 | if(!TerrainGlobalOptions::getSingletonPtr()) 43 | new TerrainGlobalOptions(); 44 | 45 | auto terrainGroup = new TerrainGroup(sceneMgr); 46 | #if OGRE_VERSION >= ((1 << 16) | (11 << 8) | 6) 47 | terrainGroup->loadLegacyTerrain(cfgFileName); 48 | #endif 49 | 50 | return terrainGroup; 51 | } 52 | -------------------------------------------------------------------------------- /examples/PGExampleApplication.h: -------------------------------------------------------------------------------- 1 | /* 2 | ----------------------------------------------------------------------------- 3 | This source file is part of OGRE 4 | (Object-oriented Graphics Rendering Engine) 5 | For the latest info, see http://www.ogre3d.org/ 6 | 7 | Copyright (c) 2000-2009 Torus Knot Software Ltd 8 | Also see acknowledgements in Readme.html 9 | 10 | You may use this sample code for anything you like, it is not covered by the 11 | same license as the rest of the engine. 12 | ----------------------------------------------------------------------------- 13 | */ 14 | /* 15 | ----------------------------------------------------------------------------- 16 | Filename: ExampleApplication.h 17 | Description: Base class for all the OGRE examples 18 | ----------------------------------------------------------------------------- 19 | */ 20 | 21 | #ifndef __PGExampleApplication_H__ 22 | #define __PGExampleApplication_H__ 23 | 24 | #include "Ogre.h" 25 | #include "OgreConfigFile.h" 26 | #include 27 | #include "PagedGeometry.h" 28 | 29 | #include 30 | #include 31 | #include 32 | 33 | #include "LegacyTerrainLoader.h" 34 | 35 | using namespace Ogre; 36 | 37 | /** Base class which manages the standard startup of an Ogre application. 38 | Designed to be subclassed for specific examples if required. 39 | */ 40 | class ExampleApplication : public OgreBites::ApplicationContext 41 | { 42 | public: 43 | /// Standard constructor 44 | ExampleApplication() : OgreBites::ApplicationContext() 45 | { 46 | mCameraMan = 0; 47 | mRenderControls = 0; 48 | 49 | } 50 | /// Standard destructor 51 | virtual ~ExampleApplication() 52 | { 53 | if (mCameraMan) 54 | delete mCameraMan; 55 | if (mRenderControls) 56 | delete mRenderControls; 57 | } 58 | 59 | virtual void addPG(Forests::PagedGeometry *pg) 60 | { 61 | pgs.push_back(pg); 62 | } 63 | 64 | /// Start the example 65 | virtual void go(void) 66 | { 67 | initApp(); 68 | setWindowGrab(); 69 | mRoot->startRendering(); 70 | 71 | // clean up 72 | destroyScene(); 73 | closeApp(); 74 | } 75 | 76 | protected: 77 | Camera* mCamera; 78 | SceneNode* mCameraNode; 79 | SceneManager* mSceneMgr; 80 | OgreBites::CameraMan* mCameraMan; 81 | OgreBites::AdvancedRenderControls* mRenderControls; 82 | 83 | TerrainGroup* mTerrainGroup; 84 | 85 | std::vector pgs; 86 | 87 | 88 | // These internal methods package up the stages in the startup process 89 | /** Sets up the application - returns false if the user chooses to abandon configuration. */ 90 | virtual void setup(void) 91 | { 92 | OgreBites::ApplicationContext::setup(); 93 | 94 | chooseSceneManager(); 95 | createCamera(); 96 | createViewports(); 97 | 98 | 99 | // Set default mipmap level (NB some APIs ignore this) 100 | TextureManager::getSingleton().setDefaultNumMipmaps(5); 101 | 102 | // Create the scene 103 | createScene(); 104 | 105 | createPGDemo(); 106 | } 107 | 108 | virtual void chooseSceneManager(void) 109 | { 110 | mSceneMgr = mRoot->createSceneManager(); 111 | RTShader::ShaderGenerator::getSingleton().addSceneManager(mSceneMgr); 112 | } 113 | 114 | virtual void createCamera(void) 115 | { 116 | // Create the camera 117 | mCamera = mSceneMgr->createCamera("PlayerCam"); 118 | 119 | mCameraNode = mSceneMgr->getRootSceneNode()->createChildSceneNode(); 120 | mCameraNode->attachObject(mCamera); 121 | 122 | mCameraMan = new OgreBites::CameraMan(mCameraNode); 123 | addInputListener(mCameraMan); 124 | mCameraMan->setStyle(OgreBites::CS_FREELOOK); 125 | 126 | // Position it at 500 in Z direction 127 | mCameraNode->setPosition(Vector3(0,50,500)); 128 | // Look back along -Z 129 | mCameraNode->lookAt(Vector3(0,0,-300), Node::TS_WORLD); 130 | mCamera->setNearClipDistance(5); 131 | 132 | } 133 | 134 | bool frameRenderingQueued(const Ogre::FrameEvent& evt) { 135 | OgreBites::ApplicationContext::frameRenderingQueued(evt); 136 | 137 | for(std::vector::iterator it=pgs.begin(); it!=pgs.end(); it++) 138 | { 139 | (*it)->update(); 140 | } 141 | 142 | return true; 143 | } 144 | 145 | virtual void createPGDemo(void) = 0; 146 | 147 | virtual void createScene(void) 148 | { 149 | 150 | //Setup the fog up to 1500 units away 151 | mSceneMgr->setFog(FOG_LINEAR, getRenderWindow()->getViewport(0)->getBackgroundColour(), 0, 100, 900); 152 | 153 | //Load the terrain 154 | mTerrainGroup = loadLegacyTerrain("terrain2.cfg", mSceneMgr); 155 | 156 | //Start off with the camera at the center of the terrain 157 | mCameraNode->setPosition(700, 100, 700); 158 | 159 | //Setup a skybox 160 | mSceneMgr->setSkyBox(true, "3D-Diggers/SkyBox", 2000); 161 | 162 | // setup some useful defaults 163 | MaterialManager::getSingleton().setDefaultTextureFiltering(TFO_ANISOTROPIC); 164 | MaterialManager::getSingleton().setDefaultAnisotropy(7); 165 | 166 | LogManager::getSingleton().setLogDetail(LL_BOREME); 167 | 168 | Light *light = mSceneMgr->createLight("Sun"); 169 | light->setType(Light::LT_DIRECTIONAL); 170 | mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(light); 171 | light->getParentSceneNode()->setDirection(Vector3(0.0f, -0.5f, 1.0f)); 172 | mSceneMgr->setAmbientLight(Ogre::ColourValue(1, 1, 1)); 173 | 174 | mCameraNode->setPosition(Vector3(100, 50, 1000)); 175 | mCameraNode->lookAt(Vector3(150, 50, 1000), Node::TS_WORLD); 176 | mCamera->setNearClipDistance(0.1); 177 | mCamera->setFarClipDistance(50000); 178 | 179 | if (mRoot->getRenderSystem()->getCapabilities()->hasCapability(RSC_INFINITE_FAR_PLANE)) 180 | { 181 | mCamera->setFarClipDistance(0); // enable infinite far clip distance if we can 182 | } 183 | } 184 | 185 | virtual void destroyScene(void){ 186 | for(std::vector::iterator it=pgs.begin(); it!=pgs.end(); it++) 187 | { 188 | (*it)->removeDetailLevels(); 189 | } 190 | 191 | delete mTerrainGroup; 192 | delete TerrainGlobalOptions::getSingletonPtr(); 193 | } 194 | 195 | virtual void createViewports(void) 196 | { 197 | // Create one viewport, entire window 198 | Viewport* vp = getRenderWindow()->addViewport(mCamera); 199 | vp->setBackgroundColour(ColourValue(0.47f, 0.67f, 0.96f)); //Blue sky background color 200 | 201 | // Alter the camera aspect ratio to match the viewport 202 | mCamera->setAspectRatio( 203 | Real(vp->getActualWidth()) / Real(vp->getActualHeight())); 204 | } 205 | 206 | }; 207 | 208 | #endif 209 | -------------------------------------------------------------------------------- /include/BatchPage.h: -------------------------------------------------------------------------------- 1 | /*------------------------------------------------------------------------------------- 2 | Copyright (c) 2006 John Judnich 3 | 4 | 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. 5 | 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: 6 | 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. 7 | 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 8 | 3. This notice may not be removed or altered from any source distribution. 9 | -------------------------------------------------------------------------------------*/ 10 | 11 | /// \file BatchPage.h 12 | /// \brief BatchPage is an extension to PagedGeometry which displays entities as static geometry. 13 | //------------------------------------------------------------------------------------- 14 | #ifndef __BatchPage_H__ 15 | #define __BatchPage_H__ 16 | 17 | #include "PagedGeometry.h" 18 | #include "BatchedGeometry.h" 19 | 20 | #include 21 | #include 22 | 23 | namespace Forests 24 | { 25 | 26 | /** 27 | \brief The BatchPage class renders entities as StaticGeometry. 28 | 29 | This is one of the geometry page types included in the StaticGeometry engine. These 30 | page types should be added to a PagedGeometry object with PagedGeometry::addDetailLevel() 31 | so the PagedGeometry will know how you want your geometry displayed. 32 | 33 | To use this page type, use (the last parameter is optional): 34 | \code 35 | PagedGeometry::addDetailLevel(farRange, transitionLength, Ogre::Any(LODLevel)); 36 | \endcode 37 | 38 | This page type uses batched geometry (Ogre::StaticGeometry) to represent the entities. 39 | Batched geometry is generally much faster than plain entities, since video card state 40 | changes and transform calculations can be minimized. Batched geometry can be anywhere 41 | from 2 to 20 times faster than plain entities. 42 | 43 | "LODLevel" can be used to specify a certain LOD level to use from the added entities. 44 | This would be useful, for example, if you wanted to add high-res batched trees near the camera, 45 | and low-res batched trees farther away. 46 | */ 47 | class BatchPage: public GeometryPage 48 | { 49 | typedef std::vector TMaterials; 50 | public: 51 | /// Default constructor 52 | BatchPage(); 53 | ~BatchPage(); 54 | 55 | /// Replace pure virtual GeometryPage::init 56 | void init(PagedGeometry *geom, const Ogre::Any &data); 57 | 58 | void addEntity(Ogre::Entity *ent, const Ogre::Vector3 &position, const Ogre::Quaternion &rotation, 59 | const Ogre::Vector3 &scale, const Ogre::ColourValue &color); 60 | void removeEntities(); 61 | 62 | void build(); 63 | 64 | void setVisible(bool visible); 65 | void setFade(bool enabled, Ogre::Real visibleDist, Ogre::Real invisibleDist); 66 | 67 | void addEntityToBoundingBox() 68 | { 69 | int a = 0; 70 | a++; 71 | } 72 | 73 | void clearBoundingBox() 74 | { 75 | int a = 0; 76 | a++; 77 | } 78 | 79 | const Ogre::AxisAlignedBox &getBoundingBox() { return m_pBatchGeom->getBoundingBox(); } 80 | 81 | protected : 82 | virtual void _updateShaders(); 83 | 84 | private: 85 | static Ogre::String getUniqueID(const Ogre::String &prefix) 86 | { 87 | return prefix + Ogre::StringConverter::toString(++s_nGUID); 88 | } 89 | 90 | // Data section of class BatchPage 91 | protected: 92 | PagedGeometry* m_pPagedGeom; 93 | Ogre::SceneManager* m_pSceneMgr; 94 | BatchedGeometry* m_pBatchGeom; 95 | size_t m_nLODLevel; 96 | bool m_bFadeEnabled; 97 | bool m_bShadersSupported; 98 | Ogre::Real m_fVisibleDist; 99 | Ogre::Real m_fInvisibleDist; 100 | TMaterials m_vecUnfadedMaterials; 101 | 102 | protected: 103 | static unsigned long s_nRefCount; 104 | static unsigned long s_nGUID; 105 | }; 106 | 107 | } 108 | 109 | #endif 110 | -------------------------------------------------------------------------------- /include/BatchedGeometry.h: -------------------------------------------------------------------------------- 1 | /*------------------------------------------------------------------------------------- 2 | Copyright (c) 2006 John Judnich 3 | 4 | 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. 5 | 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: 6 | 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. 7 | 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 8 | 3. This notice may not be removed or altered from any source distribution. 9 | -------------------------------------------------------------------------------------*/ 10 | #ifndef __BatchedGeometry_H__ 11 | #define __BatchedGeometry_H__ 12 | 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | namespace Forests 19 | { 20 | //-------------------------------------------------------------------------- 21 | /// A "lightweight" version of Ogre::StaticGeometry, which gives you a little 22 | /// more control over the batch materials, etc. 23 | class BatchedGeometry : public Ogre::MovableObject 24 | { 25 | public: 26 | //-------------------------------------------------------------------------- 27 | /// Visible chunk of geometry. 28 | class SubBatch : public Ogre::Renderable 29 | { 30 | protected: 31 | // A structure defining the desired position/orientation/scale of a batched mesh. The 32 | // SubMesh is not specified since that can be determined by which MeshQueue this belongs to. 33 | struct QueuedMesh 34 | { 35 | QueuedMesh(Ogre::SubMesh* sm, const Ogre::Vector3 &pos, const Ogre::Quaternion &ori, 36 | const Ogre::Vector3 &scl, const Ogre::ColourValue &clr, void *userData_ = 0) : 37 | subMesh (sm), 38 | position (pos), 39 | orientation (ori), 40 | scale (scl), 41 | color (clr), 42 | userData (userData_) 43 | { 44 | // empty 45 | } 46 | 47 | Ogre::SubMesh* subMesh; 48 | Ogre::Vector3 position; 49 | Ogre::Quaternion orientation; 50 | Ogre::Vector3 scale; 51 | Ogre::ColourValue color; 52 | void* userData; 53 | }; 54 | 55 | /// Queue of meshes for build batch of geometry 56 | typedef std::vector TMeshQueue; 57 | 58 | 59 | // Function section 60 | 61 | public: 62 | /// Constructor 63 | SubBatch(BatchedGeometry *parent, Ogre::SubEntity *ent); 64 | /// Destructor 65 | ~SubBatch(); 66 | 67 | /// 68 | void addSubEntity(Ogre::SubEntity *ent, const Ogre::Vector3 &position, 69 | const Ogre::Quaternion &orientation, const Ogre::Vector3 &scale, 70 | const Ogre::ColourValue &color = Ogre::ColourValue::White, void* userData = NULL); 71 | 72 | /// Build (assemble a vertex/index buffers) geometry for rendering 73 | virtual void build(); 74 | /// 75 | void clear(); 76 | 77 | /// 78 | void addSelfToRenderQueue(Ogre::RenderQueueGroup *rqg); 79 | /// 80 | void getRenderOperation(Ogre::RenderOperation& op); 81 | /// 82 | Ogre::Real getSquaredViewDepth(const Ogre::Camera* cam) const; 83 | /// 84 | const Ogre::LightList& getLights(void) const; 85 | 86 | /// 87 | void setMaterial(Ogre::MaterialPtr &mat) { m_ptrMaterial = mat; } 88 | void setMaterialName(const Ogre::String &mat, const Ogre::String &rg = 89 | Ogre::ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME) 90 | { 91 | m_ptrMaterial = Ogre::MaterialManager::getSingleton().getByName(mat, rg); 92 | } 93 | 94 | /// Get material name. Be careful, resource group name missing 95 | const Ogre::String& getMaterialName() const { return m_ptrMaterial->getName(); } 96 | Ogre::Technique *getTechnique() const { return m_pBestTechnique; } 97 | const Ogre::MaterialPtr& getMaterial(void) const { return m_ptrMaterial; } 98 | void getWorldTransforms(Ogre::Matrix4* xform) const { *xform = m_pParentGeom->_getParentNodeFullTransform(); } 99 | const Ogre::Quaternion& getWorldOrientation(void) const { return m_pParentGeom->m_pSceneNode->_getDerivedOrientation(); } 100 | const Ogre::Vector3& getWorldPosition(void) const { return m_pParentGeom->m_pSceneNode->_getDerivedPosition(); } 101 | bool castsShadows(void) const { return m_pParentGeom->getCastShadows(); } 102 | 103 | // internal fuctions 104 | private: 105 | /// Build vertex of QueuedMesh if it have identity orientation 106 | static void _buildIdentiryOrientation(const QueuedMesh &queuedMesh, const Ogre::Vector3 &parentGeomCenter, 107 | const std::vector &vertexBufferElements, std::vector &vertexBuffers, 108 | Ogre::VertexData *dst); 109 | /// Build vertex of QueuedMesh if it have some orientation 110 | static void _buildFullTransform(const QueuedMesh &queuedMesh, const Ogre::Vector3 &parentGeomCenter, 111 | const std::vector &vertexBufferElements, std::vector &vertexBuffers, 112 | Ogre::VertexData *dst); 113 | 114 | 115 | // Data section class SubBatch 116 | 117 | public: 118 | Ogre::VertexData* m_pVertexData; ///< 119 | Ogre::IndexData* m_pIndexData; ///< 120 | 121 | protected: 122 | bool m_Built; ///< 123 | bool m_RequireVertexColors; ///< 124 | Ogre::SubMesh* m_pSubMesh; ///< Ogre::SubMesh for Index/Vertex buffers manipulation 125 | BatchedGeometry* m_pParentGeom; ///< 126 | Ogre::MaterialPtr m_ptrMaterial; ///< 127 | TMeshQueue m_queueMesh; ///< The list of meshes to be added to this batch 128 | 129 | private: 130 | Ogre::Technique* m_pBestTechnique; ///< Technique recalculated every frame 131 | 132 | }; // end class SubBatch 133 | //----------------------------------------------------------------------- 134 | 135 | /// Stores a list of GeomBatch'es, using a format string (generated with getGeometryFormatString()) as the key value 136 | typedef std::map TSubBatchMap; 137 | typedef Ogre::MapIterator TSubBatchIterator; 138 | typedef Ogre::ConstMapIterator TConstSubBatchIterator; 139 | 140 | public: 141 | 142 | /// Constructor 143 | BatchedGeometry(Ogre::SceneManager *mgr, Ogre::SceneNode *rootSceneNode); 144 | ~BatchedGeometry(); 145 | 146 | TConstSubBatchIterator getSubBatchIterator() const { return TConstSubBatchIterator(m_mapSubBatch); } 147 | TSubBatchIterator getSubBatchIterator() { return TSubBatchIterator(m_mapSubBatch); } 148 | 149 | virtual void addEntity(Ogre::Entity *ent, const Ogre::Vector3 &position, 150 | const Ogre::Quaternion &orientation = Ogre::Quaternion::IDENTITY, 151 | const Ogre::Vector3 &scale = Ogre::Vector3::UNIT_SCALE, 152 | const Ogre::ColourValue &color = Ogre::ColourValue::White); 153 | 154 | void build(); 155 | void clear(); 156 | 157 | Ogre::Vector3 _convertToLocal(const Ogre::Vector3 &globalVec) const; 158 | 159 | const Ogre::AxisAlignedBox &getBoundingBox(void) const { return m_boundsAAB; } 160 | Ogre::Real getBoundingRadius(void) const { return m_fRadius; } 161 | 162 | private: 163 | bool isVisible() const; 164 | const Ogre::String& getMovableType(void) const; 165 | void visitRenderables(Ogre::Renderable::Visitor* visitor, bool debugRenderables) { /* empty */ } 166 | void _notifyCurrentCamera(Ogre::Camera *cam); 167 | void _updateRenderQueue(Ogre::RenderQueue *queue); 168 | 169 | protected: 170 | static Ogre::String getFormatString(Ogre::SubEntity *ent); 171 | static void extractVertexDataFromShared(const Ogre::MeshPtr &mesh); 172 | 173 | 174 | // Data section of BatchedGeometry class 175 | protected: 176 | bool m_Built; 177 | bool m_BoundsUndefined; 178 | Ogre::Vector3 m_vecCenter; 179 | Ogre::AxisAlignedBox m_boundsAAB; 180 | TSubBatchMap m_mapSubBatch; 181 | /// Internal matrix for remap vertex type to vertex size instead call VertexElement::getTypeSize 182 | static size_t s_vertexType2Size[Ogre::VET_UBYTE4_NORM + 1]; 183 | 184 | private: 185 | bool m_bWithinFarDistance; 186 | Ogre::Real m_fRadius; 187 | Ogre::Real m_fMinDistanceSquared; 188 | Ogre::SceneManager* m_pSceneMgr; 189 | Ogre::SceneNode* m_pSceneNode; 190 | Ogre::SceneNode* m_pParentSceneNode; 191 | }; 192 | 193 | } 194 | 195 | #endif 196 | -------------------------------------------------------------------------------- /include/PagedGeometryConfig.h.in: -------------------------------------------------------------------------------- 1 | #ifndef PagedGeometryConfig_h__ 2 | #define PagedGeometryConfig_h__ 3 | 4 | /* Define the library version */ 5 | #define PAGEDGEOMETRY_VERSION_MAJOR ${CMAKE_PROJECT_VERSION_MAJOR} 6 | #define PAGEDGEOMETRY_VERSION_MINOR ${CMAKE_PROJECT_VERSION_MINOR} 7 | #define PAGEDGEOMETRY_VERSION_PATCH ${CMAKE_PROJECT_VERSION_PATCH} 8 | #define PAGEDGEOMETRY_VERSION "${CMAKE_PROJECT_VERSION}" 9 | 10 | /* Define if we use the alternate coordsystem */ 11 | #cmakedefine PAGEDGEOMETRY_ALTERNATE_COORDSYSTEM 12 | 13 | /* Define if we use ogre random */ 14 | #cmakedefine PAGEDGEOMETRY_USE_OGRE_RANDOM 15 | 16 | /* Define if we support user data */ 17 | #cmakedefine PAGEDGEOMETRY_USER_DATA 18 | 19 | 20 | /* some helpful OIS macro */ 21 | #cmakedefine OIS_USING_DIR 22 | 23 | #endif //PagedGeometryConfig_h__ 24 | -------------------------------------------------------------------------------- /include/PropertyMaps.h: -------------------------------------------------------------------------------- 1 | /*------------------------------------------------------------------------------------- 2 | Copyright (c) 2006 John Judnich 3 | 4 | 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. 5 | 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: 6 | 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. 7 | 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 8 | 3. This notice may not be removed or altered from any source distribution. 9 | -------------------------------------------------------------------------------------*/ 10 | #ifndef __PropertyMaps_H__ 11 | #define __PropertyMaps_H__ 12 | 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | 19 | namespace Forests 20 | { 21 | 22 | /** \brief Specifies which color channel(s) to extract from an image */ 23 | enum MapChannel 24 | { 25 | /// Use only the image's red color channel 26 | CHANNEL_RED, 27 | /// Use only the image's green color channel 28 | CHANNEL_GREEN, 29 | /// Use only the image's blue color channel 30 | CHANNEL_BLUE, 31 | /// Use only the image's alpha channel 32 | CHANNEL_ALPHA, 33 | /// Use the image's full RGB color information 34 | CHANNEL_COLOR 35 | }; 36 | 37 | /** \brief Specifies the filtering method used to interpret property maps */ 38 | enum MapFilter 39 | { 40 | /// Use no filtering - fast, but may appear blocky 41 | MAPFILTER_NONE, 42 | /// Use bilinear filtering - slower, but will appear less blocky 43 | MAPFILTER_BILINEAR 44 | }; 45 | 46 | /** \brief A 2D greyscale image that is assigned to a certain region of your world to represent density levels. 47 | 48 | This class is used by various PagedLoader's internally, so it's not necessary to learn anything about this class. 49 | However, you can achieve more advanced effects through the DensityMap class interface than you can with the standard 50 | GrassLayer density map functions, for example. 51 | 52 | Probably the most useful function in this class is getPixelBox(), which you can use to directly manipulate the 53 | density map pixels in real-time. */ 54 | class DensityMap 55 | { 56 | public: 57 | static DensityMap *load(const Ogre::String &fileName, MapChannel channel = CHANNEL_COLOR); 58 | static DensityMap *load(Ogre::TexturePtr texture, MapChannel channel = CHANNEL_COLOR); 59 | void unload(); 60 | 61 | /** \brief Sets the filtering mode used for this density map 62 | 63 | This function can be used to set the filtering mode used for your density map. By default, 64 | bilinear filtering is used (MAPFILTER_BILINEAR). If you disable filtering by using MAPFILTER_NONE, 65 | the resulting effect of the density map may look square and blocky, depending on the resolution of 66 | the map. 67 | 68 | MAPFILTER_NONE is slightly faster than MAPFILTER_BILINEAR, so use it if you don't notice any 69 | considerable blockyness. */ 70 | void setFilter(MapFilter filter) { this->filter = filter; } 71 | 72 | /** \brief Returns the filtering mode being used for this density map */ 73 | MapFilter getFilter() { return filter; } 74 | 75 | /** \brief Gets a pointer to the pixel data of the density map 76 | 77 | You can use this function to access the pixel data of the density map. The PixelBox 78 | returned is an image in PF_BYTE_L (aka. PF_L8) byte format. You can modify this image 79 | any way you like in real-time, so long as you do not change the byte format. 80 | 81 | This function is useful in editors where the density map needs to be changed dynamically. 82 | Note that although you can change this map in real-time, the changes won't be uploaded to your 83 | video card until you call PagedGeometry::reloadGeometry(). If you don't, the grass you see 84 | will remain unchanged. */ 85 | Ogre::PixelBox getPixelBox() 86 | { 87 | return pixels.getPixelBox(); 88 | } 89 | 90 | /** \brief Gets the density level at the specified position 91 | 92 | The boundary given defines the area where this density map takes effect. 93 | Normally this is set to your terrain's bounds so the density map is aligned 94 | to your heightmap, but you could apply it anywhere you want. */ 95 | Ogre::Real getDensityAt(Ogre::Real x, Ogre::Real z, const Ogre::RealRect &mapBounds) 96 | { 97 | if (filter == MAPFILTER_NONE) 98 | return _getDensityAt_Unfiltered(x, z, mapBounds); 99 | else 100 | return _getDensityAt_Bilinear(x, z, mapBounds); 101 | } 102 | 103 | Ogre::Real _getDensityAt_Unfiltered(Ogre::Real x, Ogre::Real z, const Ogre::RealRect &mapBounds); 104 | Ogre::Real _getDensityAt_Bilinear(Ogre::Real x, Ogre::Real z, const Ogre::RealRect &mapBounds); 105 | 106 | private: 107 | DensityMap(Ogre::TexturePtr texture, MapChannel channel); 108 | ~DensityMap(); 109 | 110 | static std::map selfList; 111 | Ogre::String selfKey; 112 | Ogre::uint32 refCount; 113 | 114 | MapFilter filter; 115 | Ogre::Image pixels; 116 | }; 117 | 118 | /** \brief A 2D greyscale image that is assigned to a certain region of your world to represent color levels. 119 | 120 | This class is used by various PagedLoader's internally, so it's not necessary to learn anything about this class. 121 | However, you can achieve more advanced effects through the ColorMap class interface than you can with the standard 122 | GrassLayer color map functions, for example. 123 | 124 | Probably the most useful function in this class is getPixelBox(), which you can use to directly manipulate the 125 | color map pixels in real-time. */ 126 | class ColorMap 127 | { 128 | public: 129 | static ColorMap *load(const Ogre::String &fileName, MapChannel channel = CHANNEL_COLOR); 130 | static ColorMap *load(Ogre::TexturePtr texture, MapChannel channel = CHANNEL_COLOR); 131 | void unload(); 132 | 133 | /** \brief Sets the filtering mode used for this color map 134 | 135 | This function can be used to set the filtering mode used for your color map. By default, 136 | bilinear filtering is used (MAPFILTER_BILINEAR). If you disable filtering by using 137 | MAPFILTER_NONE, the resulting coloration may appear slightly pixelated, depending on the 138 | resolution of the map. 139 | 140 | MAPFILTER_NONE is slightly faster than MAPFILTER_BILINEAR, so use it if you don't notice any 141 | considerable pixelation. */ 142 | void setFilter(MapFilter filter) { this->filter = filter; } 143 | 144 | /** \brief Returns the filtering mode being used for this color map */ 145 | MapFilter getFilter() { return filter; } 146 | 147 | /** \brief Gets a pointer to the pixel data of the color map 148 | 149 | You can use this function to access the pixel data of the color map. The PixelBox 150 | returned is an image in PF_A8R8G8B8 format when running with DirectX, and PF_A8B8G8R8 151 | when running with OpenGL. You can modify this image any way you like in 152 | real-time, so long as you do not change the byte format. 153 | 154 | This function is useful in editors where the color map needs to be changed dynamically. 155 | Note that although you can change this map in real-time, the changes won't be uploaded to your 156 | video card until you call PagedGeometry::reloadGeometry(). If you don't, the grass you see 157 | will remain unchanged. */ 158 | Ogre::PixelBox getPixelBox() 159 | { 160 | return pixels.getPixelBox(); 161 | } 162 | 163 | /** \brief Gets the color value at the specified position 164 | 165 | A RenderSystem-specific 32-bit packed color value is used, so it can be fed directly to 166 | the video card. 167 | 168 | The boundary given defines the area where this color map takes effect. 169 | Normally this is set to your terrain's bounds so the color map is aligned 170 | to your heightmap, but you could apply it anywhere you want. */ 171 | Ogre::uint32 getColorAt(Ogre::Real x, Ogre::Real z, const Ogre::RealRect &mapBounds) 172 | { 173 | return filter == MAPFILTER_NONE ? _getColorAt(x, z, mapBounds) : _getColorAt_Bilinear(x, z, mapBounds); 174 | } 175 | 176 | /** \brief Gets the color value at the specified position 177 | 178 | The unpacks the 32-bit color value into an Ogre::ColourValue and returns it. */ 179 | Ogre::ColourValue getColorAt_Unpacked(Ogre::Real x, Ogre::Real z, const Ogre::RealRect &mapBounds) 180 | { 181 | Ogre::uint32 c = filter == MAPFILTER_NONE ? _getColorAt(x, z, mapBounds) : _getColorAt_Bilinear(x, z, mapBounds); 182 | return Ogre::ColourValue((Ogre::uchar*)&c); 183 | } 184 | 185 | private: 186 | ColorMap(Ogre::TexturePtr map, MapChannel channel); 187 | ~ColorMap(); 188 | 189 | static std::map selfList; 190 | Ogre::String selfKey; 191 | Ogre::uint32 refCount; 192 | 193 | //Directly interpolates two Ogre::uint32 colors 194 | Ogre::uint32 _interpolateColor(Ogre::uint32 color1, Ogre::uint32 color2, Ogre::Real ratio, Ogre::Real ratioInv); 195 | 196 | //Returns the color map value at the given location 197 | Ogre::uint32 _getColorAt(Ogre::Real x, Ogre::Real z, const Ogre::RealRect &mapBounds); 198 | 199 | //Returns the color map value at the given location with bilinear filtering 200 | Ogre::uint32 _getColorAt_Bilinear(Ogre::Real x, Ogre::Real z, const Ogre::RealRect &mapBounds); 201 | 202 | MapFilter filter; 203 | Ogre::Image pixels; 204 | Ogre::RealRect mapBounds; 205 | }; 206 | 207 | } 208 | 209 | #endif 210 | -------------------------------------------------------------------------------- /include/RandomTable.h: -------------------------------------------------------------------------------- 1 | /*------------------------------------------------------------------------------------- 2 | Copyright (c) 2006 John Judnich 3 | 4 | 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. 5 | 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: 6 | 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. 7 | 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 8 | 3. This notice may not be removed or altered from any source distribution. 9 | -------------------------------------------------------------------------------------*/ 10 | 11 | #ifndef __RandomTable_H__ 12 | #define __RandomTable_H__ 13 | 14 | #include 15 | #include 16 | 17 | #include 18 | #ifdef _WIN32 19 | #define _WIN32_WINNT 0x0600 20 | #include 21 | #endif 22 | 23 | // random table class that speeds up PG a bit 24 | class RandomTable 25 | { 26 | public: 27 | RandomTable(unsigned long size=0x8000); 28 | ~RandomTable(); 29 | 30 | void resetRandomIndex(); 31 | float getUnitRandom(); 32 | float getRangeRandom(float start, float end); 33 | 34 | protected: 35 | unsigned long tableSize; 36 | float *table; 37 | unsigned long customRandomIndex; 38 | 39 | void generateRandomNumbers(); 40 | }; 41 | 42 | 43 | // implementation below 44 | inline RandomTable::RandomTable(unsigned long size) : tableSize(size), table(0), customRandomIndex(0) 45 | { 46 | table = (float *)malloc(sizeof(float) * tableSize); 47 | generateRandomNumbers(); 48 | } 49 | 50 | inline RandomTable::~RandomTable() 51 | { 52 | if(table) 53 | { 54 | free(table); 55 | table=0; 56 | } 57 | } 58 | 59 | inline void RandomTable::resetRandomIndex() 60 | { 61 | customRandomIndex = 0; 62 | } 63 | 64 | inline float RandomTable::getUnitRandom() 65 | { 66 | // prevent against overflow 67 | if(customRandomIndex > tableSize - 1) 68 | customRandomIndex = 0; 69 | return table[customRandomIndex++]; 70 | } 71 | 72 | inline float RandomTable::getRangeRandom(float start, float end) 73 | { 74 | return (start + ((end - start) * getUnitRandom())); 75 | } 76 | 77 | inline void RandomTable::generateRandomNumbers() 78 | { 79 | // using our Mersenne Twister (preferred way) 80 | std::mt19937 rng; 81 | for(unsigned long i = 0; i < tableSize; i++) 82 | table[i] = float(rng())/rng.max(); 83 | } 84 | 85 | #endif // __RandomTable_H__ 86 | 87 | -------------------------------------------------------------------------------- /include/WindBatchPage.h: -------------------------------------------------------------------------------- 1 | /*------------------------------------------------------------------------------------- 2 | Copyright (c) 2006 John Judnich 3 | 4 | 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. 5 | 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: 6 | 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. 7 | 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 8 | 3. This notice may not be removed or altered from any source distribution. 9 | -------------------------------------------------------------------------------------*/ 10 | 11 | /// \file WindBatchPage.h 12 | /// \brief WindBatchPage is child of BatchPage to include a wind effect. 13 | #ifndef __WindBatchPage_H__ 14 | #define __WindBatchPage_H__ 15 | 16 | #include 17 | #include 18 | 19 | #include "BatchPage.h" 20 | #include "WindBatchedGeometry.h" 21 | 22 | namespace Forests 23 | { 24 | 25 | class PagedGeometry; 26 | 27 | /** 28 | \brief The WindBatchPage class renders entities as StaticGeometry with hardware accelerated wind animation capability. 29 | 30 | This is one of the geometry page types included in the StaticGeometry engine. These 31 | page types should be added to a PagedGeometry object with PagedGeometry::addDetailLevel() 32 | so the PagedGeometry will know how you want your geometry displayed. 33 | 34 | To use this page type, use: 35 | \code 36 | PagedGeometry::addDetailLevel(farRange, transitionLength, Ogre::Any(LODLevel)); 37 | \endcode 38 | 39 | This page type (WindBatchPage) is almost identical to BatchPage, except it includes additional 40 | code to support a hardware accelerated wind animation technique (through a vertex shader). To 41 | enable animation on your tree(s), use PagedGeometry::setCustomParam() to set the following 42 | parameters: 43 | 44 | windFactorX - Horizontal tree sway magnitude 45 | windFactorY - Vertical tree sway magnitude 46 | 47 | See Example 8 for a practical example of using WindBatchPage. 48 | 49 | Special thanks to Wendigo Studios (www.wendigostudios.com) for donating this extension of 50 | BatchPage to the PagedGeometry project. 51 | */ 52 | class WindBatchPage: public BatchPage 53 | { 54 | public: 55 | WindBatchPage() : m_pPagedGeom(NULL) { /* empty */ } 56 | 57 | /// 58 | void init(PagedGeometry *geom, const Ogre::Any &data); 59 | 60 | protected: 61 | void _updateShaders(); 62 | 63 | private: 64 | Ogre::String m_strEntityName; ///< 65 | const PagedGeometry* m_pPagedGeom; ///< 66 | }; 67 | 68 | } 69 | 70 | #endif 71 | -------------------------------------------------------------------------------- /include/WindBatchedGeometry.h: -------------------------------------------------------------------------------- 1 | /*------------------------------------------------------------------------------------- 2 | Copyright (c) 2006 John Judnich 3 | 4 | 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. 5 | 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: 6 | 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. 7 | 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 8 | 3. This notice may not be removed or altered from any source distribution. 9 | -------------------------------------------------------------------------------------*/ 10 | #ifndef __WindBatchedGeometry_H__ 11 | #define __WindBatchedGeometry_H__ 12 | 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | #include "BatchedGeometry.h" 19 | 20 | namespace Forests 21 | { 22 | // Forward declaration 23 | class PagedGeometry; 24 | 25 | 26 | //----------------------------------------------------------------------------- 27 | /// A variation of BatchedGeometry designed for WindBatchPage. 28 | class WindBatchedGeometry: public BatchedGeometry 29 | { 30 | public: 31 | //-------------------------------------------------------------------------- 32 | /// Wind chunck of Renderable geometry 33 | class WindSubBatch: public BatchedGeometry::SubBatch 34 | { 35 | public: 36 | WindSubBatch(WindBatchedGeometry *parent, Ogre::SubEntity *ent); 37 | void build(); 38 | }; 39 | 40 | public: 41 | WindBatchedGeometry(Ogre::SceneManager *mgr, Ogre::SceneNode *rootSceneNode, const PagedGeometry *pagedGeom); 42 | 43 | void addEntity(Ogre::Entity *ent, const Ogre::Vector3 &position, const Ogre::Quaternion &orientation = Ogre::Quaternion::IDENTITY, const Ogre::Vector3 &scale = Ogre::Vector3::UNIT_SCALE, const Ogre::ColourValue &color = Ogre::ColourValue::White); 44 | void setGeom(const PagedGeometry * geom) { mGeom = geom; } 45 | 46 | private: 47 | const PagedGeometry * mGeom; 48 | }; 49 | 50 | } 51 | 52 | #endif 53 | -------------------------------------------------------------------------------- /source/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | file(GLOB sources *.cpp ${PROJECT_SOURCE_DIR}/include/*.h) 2 | 3 | add_library(${PROJECT_NAME} STATIC ${sources}) 4 | 5 | target_include_directories( 6 | ${PROJECT_NAME} PUBLIC 7 | $ 8 | $ 9 | $ 10 | ) 11 | 12 | # install the library 13 | install( 14 | TARGETS ${PROJECT_NAME} 15 | EXPORT PagedGeometryTargets 16 | RUNTIME LIBRARY ARCHIVE 17 | ) 18 | 19 | install( 20 | EXPORT PagedGeometryTargets 21 | FILE PagedGeometryTargets.cmake 22 | NAMESPACE PagedGeometry:: 23 | DESTINATION ${CMAKEFILES_INSTALL_DIR} 24 | ) 25 | 26 | # install the headers: both source and build headers 27 | install(DIRECTORY ${PROJECT_SOURCE_DIR}/include/ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/PagedGeometry FILES_MATCHING PATTERN "*.h" PATTERN ".svn" EXCLUDE) 28 | install(DIRECTORY ${PROJECT_BINARY_DIR}/include/ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/PagedGeometry FILES_MATCHING PATTERN "*.h" PATTERN ".svn" EXCLUDE) 29 | 30 | # --- Threading support (still needed for GCC even with C++11) 31 | set(CMAKE_THREAD_PREFER_PTHREAD YES) 32 | find_package(Threads REQUIRED) 33 | target_link_libraries( 34 | ${PROJECT_NAME} PRIVATE 35 | Threads::Threads 36 | ) 37 | 38 | target_link_libraries( 39 | ${PROJECT_NAME} PRIVATE 40 | ${OGRE_LIBRARIES} 41 | ) 42 | target_include_directories( 43 | ${PROJECT_NAME} PRIVATE 44 | ${OGRE_INCLUDE_DIRS} 45 | ) 46 | -------------------------------------------------------------------------------- /source/WindBatchPage.cpp: -------------------------------------------------------------------------------- 1 | /*------------------------------------------------------------------------------------- 2 | Copyright (c) 2006 John Judnich 3 | 4 | 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. 5 | 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: 6 | 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. 7 | 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 8 | 3. This notice may not be removed or altered from any source distribution. 9 | -------------------------------------------------------------------------------------*/ 10 | 11 | //WindBatchPage.cpp 12 | //WindBatchPage is an extension to PagedGeometry which displays entities as static geometry but that is affected by wind. 13 | //------------------------------------------------------------------------------------- 14 | 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | 26 | #include "WindBatchPage.h" 27 | #include "WindBatchedGeometry.h" 28 | 29 | // to dump the shader source in a file 30 | #include 31 | 32 | using namespace Ogre; 33 | using namespace Forests; 34 | 35 | //------------------------------------------------------------------------------------- 36 | 37 | //----------------------------------------------------------------------------- 38 | /// 39 | void WindBatchPage::init(PagedGeometry *geom, const Any &data) 40 | { 41 | int datacast = data.has_value() ? Ogre::any_cast(data) : 0; 42 | #ifdef _DEBUG 43 | if (datacast < 0) 44 | { 45 | OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, 46 | "Data of WindBatchPage must be a positive integer. It representing the LOD level this detail level stores.", 47 | "WindBatchPage::WindBatchPage"); 48 | } 49 | #endif 50 | 51 | m_pBatchGeom = new WindBatchedGeometry(geom->getSceneManager(), geom->getSceneNode(), geom); 52 | m_nLODLevel = datacast; 53 | m_pPagedGeom = geom; 54 | m_bFadeEnabled = false; 55 | 56 | const RenderSystemCapabilities *caps = Root::getSingleton().getRenderSystem()->getCapabilities(); 57 | m_bShadersSupported = caps->hasCapability(RSC_VERTEX_PROGRAM) ? true : false; // <-- DELETE THIS 58 | 59 | ++s_nRefCount; 60 | } 61 | 62 | 63 | //----------------------------------------------------------------------------- 64 | /// 65 | void WindBatchPage::_updateShaders() 66 | { 67 | if (!m_bShadersSupported) 68 | return; 69 | 70 | unsigned int i = 0; 71 | BatchedGeometry::TSubBatchIterator it = m_pBatchGeom->getSubBatchIterator(); 72 | while (it.hasMoreElements()) 73 | { 74 | BatchedGeometry::SubBatch *subBatch = it.getNext(); 75 | const MaterialPtr &ptrMat = m_vecUnfadedMaterials[i++]; 76 | 77 | //Check if lighting should be enabled 78 | bool lightingEnabled = false; 79 | for (unsigned short t = 0, techCnt = ptrMat->getNumTechniques(); t < techCnt; ++t) 80 | { 81 | Technique *tech = ptrMat->getTechnique(t); 82 | for (unsigned short p = 0, passCnt = tech->getNumPasses(); p < passCnt; ++p) 83 | { 84 | if (tech->getPass(p)->getLightingEnabled()) 85 | { 86 | lightingEnabled = true; 87 | break; 88 | } 89 | } 90 | 91 | if (lightingEnabled) 92 | break; 93 | } 94 | 95 | //Compile the shader script based on various material / fade options 96 | Ogre::StringStream tmpName; 97 | tmpName << "BatchPage_"; 98 | if (m_bFadeEnabled) 99 | tmpName << "fade_"; 100 | if (lightingEnabled) 101 | tmpName << "lit_"; 102 | if (subBatch->m_pVertexData->vertexDeclaration->findElementBySemantic(VES_DIFFUSE) != NULL) 103 | tmpName << "clr_"; 104 | 105 | for (unsigned short i = 0; i < subBatch->m_pVertexData->vertexDeclaration->getElementCount(); ++i) 106 | { 107 | const VertexElement *el = subBatch->m_pVertexData->vertexDeclaration->getElement(i); 108 | if (el->getSemantic() == VES_TEXTURE_COORDINATES) 109 | { 110 | String uvType; 111 | switch (el->getType()) 112 | { 113 | case VET_FLOAT1: uvType = "1"; break; 114 | case VET_FLOAT2: uvType = "2"; break; 115 | case VET_FLOAT3: uvType = "3"; break; 116 | case VET_FLOAT4: uvType = "4"; break; 117 | default: 118 | OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, "Unsupported texture coordinate type"); 119 | } 120 | tmpName << uvType << '_'; 121 | } 122 | } 123 | 124 | tmpName << "vp"; 125 | 126 | const String vertexProgName = tmpName.str(); 127 | String shaderLanguage = m_pPagedGeom->getShaderLanguage(); 128 | 129 | //If the shader hasn't been created yet, create it 130 | if (!HighLevelGpuProgramManager::getSingleton().getByName(vertexProgName)) 131 | { 132 | String vertexProgSource = Root::getSingleton().openFileStream("BatchPage_vp.glsl")->getAsString(); 133 | 134 | String defines = "ANIMATE,"; 135 | if (lightingEnabled) defines += "LIGHTING,"; 136 | if (subBatch->m_pVertexData->vertexDeclaration->findElementBySemantic(VES_DIFFUSE)) defines += "VERTEXCOLOUR,"; 137 | if (m_bFadeEnabled) defines += "FADE,"; 138 | 139 | HighLevelGpuProgramPtr vertexShader = HighLevelGpuProgramManager::getSingleton().createProgram( 140 | vertexProgName, 141 | ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, 142 | shaderLanguage, GPT_VERTEX_PROGRAM); 143 | 144 | vertexShader->setSource(vertexProgSource); 145 | vertexShader->setParameter("preprocessor_defines", defines); 146 | 147 | if (shaderLanguage == "hlsl") 148 | { 149 | vertexShader->setParameter("target", "vs_1_1"); 150 | } 151 | 152 | vertexShader->load(); 153 | } 154 | 155 | //Now that the shader is ready to be applied, apply it 156 | Ogre::StringStream materialSignature; 157 | materialSignature << "BatchMat|"; 158 | materialSignature << ptrMat->getName() << "|"; 159 | if (m_bFadeEnabled) 160 | { 161 | materialSignature << m_fVisibleDist << "|"; 162 | materialSignature << m_fInvisibleDist << "|"; 163 | } 164 | 165 | //Search for the desired material 166 | MaterialPtr generatedMaterial = MaterialManager::getSingleton().getByName(materialSignature.str()); 167 | if (!generatedMaterial) 168 | { 169 | //Clone the material 170 | generatedMaterial = ptrMat->clone(materialSignature.str()); 171 | 172 | //And apply the fade shader 173 | for (unsigned short t = 0; t < generatedMaterial->getNumTechniques(); ++t){ 174 | Technique *tech = generatedMaterial->getTechnique(t); 175 | for (unsigned short p = 0; p < tech->getNumPasses(); ++p){ 176 | Pass *pass = tech->getPass(p); 177 | 178 | //Setup vertex program 179 | if (pass->getVertexProgramName() == "") 180 | pass->setVertexProgram(vertexProgName); 181 | pass->setFragmentProgram(m_pPagedGeom->getFragmentProgramName()); 182 | 183 | try{ 184 | GpuProgramParametersSharedPtr params = pass->getVertexProgramParameters(); 185 | 186 | if (lightingEnabled) { 187 | params->setNamedAutoConstant("objSpaceLight", GpuProgramParameters::ACT_LIGHT_POSITION_OBJECT_SPACE); 188 | params->setNamedAutoConstant("lightDiffuse", GpuProgramParameters::ACT_DERIVED_LIGHT_DIFFUSE_COLOUR); 189 | params->setNamedAutoConstant("lightAmbient", GpuProgramParameters::ACT_DERIVED_AMBIENT_LIGHT_COLOUR); 190 | //params->setNamedAutoConstant("matAmbient", GpuProgramParameters::ACT_SURFACE_AMBIENT_COLOUR); 191 | } 192 | 193 | params->setNamedConstantFromTime("time", 1); 194 | params->setNamedAutoConstant("worldViewProj", GpuProgramParameters::ACT_WORLDVIEWPROJ_MATRIX); 195 | 196 | if (m_bFadeEnabled) 197 | { 198 | params->setNamedAutoConstant("camPos", GpuProgramParameters::ACT_CAMERA_POSITION_OBJECT_SPACE); 199 | 200 | //Set fade ranges 201 | params->setNamedAutoConstant("invisibleDist", GpuProgramParameters::ACT_CUSTOM); 202 | params->setNamedConstant("invisibleDist", m_fInvisibleDist); 203 | 204 | params->setNamedAutoConstant("fadeGap", GpuProgramParameters::ACT_CUSTOM); 205 | params->setNamedConstant("fadeGap", m_fInvisibleDist - m_fVisibleDist); 206 | 207 | if (pass->getAlphaRejectFunction() == CMPF_ALWAYS_PASS) 208 | pass->setSceneBlending(SBT_TRANSPARENT_ALPHA); 209 | } 210 | } 211 | catch (const Ogre::Exception &e) 212 | { 213 | // test for shader source 214 | std::ofstream shaderOutput; 215 | shaderOutput.open("exception.log"); 216 | shaderOutput << e.getDescription(); 217 | shaderOutput.close(); 218 | } 219 | catch (...) 220 | { 221 | OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, 222 | "Error configuring batched geometry transitions. If you're using materials with custom\ 223 | vertex shaders, they will need to implement fade transitions to be compatible with BatchPage.", 224 | "BatchPage::_updateShaders()"); 225 | } 226 | } 227 | } 228 | 229 | } 230 | 231 | //Apply the material 232 | subBatch->setMaterial(generatedMaterial); 233 | } 234 | 235 | } 236 | --------------------------------------------------------------------------------