├── .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 | 
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 |
55 | - John Judnich - Programming / design / documentation
56 | - Alexander Shyrokov (aka. sj) - Testing / co-design
57 | - Tuan Kuranes - Imposter image render technique
58 | - (Falagard) - Camera-facing billboard vertex shader
59 | - Wendigo Studios - Tree animation code & various patches/improvements
60 | - Thomas Fischer - Maintainer from Jun/2009
61 |
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 |
--------------------------------------------------------------------------------