/src/ogre/OgreMain/src/OgreShadowTextureManager.cpp
Line | Count | Source |
1 | | /*------------------------------------------------------------------------- |
2 | | This source file is a part of OGRE |
3 | | (Object-oriented Graphics Rendering Engine) |
4 | | |
5 | | For the latest info, see http://www.ogre3d.org/ |
6 | | |
7 | | Copyright (c) 2000-2014 Torus Knot Software Ltd |
8 | | Permission is hereby granted, free of charge, to any person obtaining a copy |
9 | | of this software and associated documentation files (the "Software"), to deal |
10 | | in the Software without restriction, including without limitation the rights |
11 | | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
12 | | copies of the Software, and to permit persons to whom the Software is |
13 | | furnished to do so, subject to the following conditions: |
14 | | |
15 | | The above copyright notice and this permission notice shall be included in |
16 | | all copies or substantial portions of the Software. |
17 | | |
18 | | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
19 | | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
20 | | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
21 | | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
22 | | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
23 | | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
24 | | THE SOFTWARE |
25 | | |
26 | | You may alternatively use this source under the terms of a specific version of |
27 | | the OGRE Unrestricted License provided you have obtained such a license from |
28 | | Torus Knot Software Ltd. |
29 | | -------------------------------------------------------------------------*/ |
30 | | #include "OgreStableHeaders.h" |
31 | | #include "OgreHardwarePixelBuffer.h" |
32 | | |
33 | | namespace Ogre |
34 | | { |
35 | | //----------------------------------------------------------------------- |
36 | | bool operator== ( const ShadowTextureConfig& lhs, const ShadowTextureConfig& rhs ) |
37 | 0 | { |
38 | 0 | if ( lhs.width != rhs.width || |
39 | 0 | lhs.height != rhs.height || |
40 | 0 | lhs.format != rhs.format ) |
41 | 0 | { |
42 | 0 | return false; |
43 | 0 | } |
44 | | |
45 | 0 | return true; |
46 | 0 | } |
47 | | //----------------------------------------------------------------------- |
48 | | bool operator!= ( const ShadowTextureConfig& lhs, const ShadowTextureConfig& rhs ) |
49 | 0 | { |
50 | 0 | return !( lhs == rhs ); |
51 | 0 | } |
52 | | //----------------------------------------------------------------------- |
53 | | template<> ShadowTextureManager* Singleton<ShadowTextureManager>::msSingleton = 0; |
54 | | ShadowTextureManager* ShadowTextureManager::getSingletonPtr(void) |
55 | 0 | { |
56 | 0 | return msSingleton; |
57 | 0 | } |
58 | | ShadowTextureManager& ShadowTextureManager::getSingleton(void) |
59 | 0 | { |
60 | 0 | assert( msSingleton ); return ( *msSingleton ); |
61 | 0 | } |
62 | | //--------------------------------------------------------------------- |
63 | | ShadowTextureManager::ShadowTextureManager() |
64 | 1 | : mCount(0) |
65 | 1 | { |
66 | | |
67 | 1 | } |
68 | | //--------------------------------------------------------------------- |
69 | | ShadowTextureManager::~ShadowTextureManager() |
70 | 1 | { |
71 | 1 | clear(); |
72 | 1 | } |
73 | | //--------------------------------------------------------------------- |
74 | | void ShadowTextureManager::getShadowTextures(ShadowTextureConfigList& configList, |
75 | | ShadowTextureList& listToPopulate) |
76 | 0 | { |
77 | 0 | listToPopulate.clear(); |
78 | |
|
79 | 0 | std::set<Texture*> usedTextures; |
80 | |
|
81 | 0 | for (ShadowTextureConfig& config : configList) |
82 | 0 | { |
83 | 0 | bool found = false; |
84 | 0 | for (auto & tex : mTextureList) |
85 | 0 | { |
86 | | // Skip if already used this one |
87 | 0 | if (usedTextures.find(tex.get()) != usedTextures.end()) |
88 | 0 | continue; |
89 | | |
90 | 0 | if (config.width == tex->getWidth() && config.height == tex->getHeight() && |
91 | 0 | config.depth == tex->getDepth() && config.type == tex->getTextureType() && |
92 | 0 | config.format == tex->getFormat() && config.fsaa == tex->getFSAA()) |
93 | 0 | { |
94 | | // Ok, a match |
95 | 0 | listToPopulate.push_back(tex); |
96 | 0 | usedTextures.insert(tex.get()); |
97 | 0 | found = true; |
98 | 0 | break; |
99 | 0 | } |
100 | 0 | } |
101 | 0 | if (!found) |
102 | 0 | { |
103 | | // Create a new texture |
104 | 0 | String targName = StringUtil::format("Ogre/ShadowTexture%zu", mCount++); |
105 | 0 | TexturePtr shadowTex = TextureManager::getSingleton().createManual( |
106 | 0 | targName, RGN_INTERNAL, config.type, config.width, config.height, config.depth, 0, config.format, |
107 | 0 | TU_RENDERTARGET | config.extraFlags, NULL, false, config.fsaa); |
108 | 0 | OgreAssert(shadowTex, "Unsupported shadow texture configuration"); |
109 | | // Ensure texture loaded |
110 | 0 | shadowTex->load(); |
111 | | |
112 | | // update with actual format, if the requested format is not supported |
113 | 0 | config.format = shadowTex->getFormat(); |
114 | 0 | listToPopulate.push_back(shadowTex); |
115 | 0 | usedTextures.insert(shadowTex.get()); |
116 | 0 | mTextureList.push_back(shadowTex); |
117 | 0 | } |
118 | 0 | } |
119 | |
|
120 | 0 | } |
121 | | //--------------------------------------------------------------------- |
122 | | TexturePtr ShadowTextureManager::getNoShadowTexture(PixelFormat format) |
123 | 0 | { |
124 | 0 | for (auto & tex : mNullTextureList) |
125 | 0 | { |
126 | 0 | if (format == tex->getFormat()) |
127 | 0 | { |
128 | | // Ok, a match |
129 | 0 | return tex; |
130 | 0 | } |
131 | 0 | } |
132 | | |
133 | | // not found, create a new one |
134 | | // A 1x1 texture of the correct format, not a render target |
135 | 0 | static const String baseName = "Ogre/ShadowTextureNull"; |
136 | 0 | String targName = baseName + StringConverter::toString(mCount++); |
137 | 0 | TexturePtr shadowTex = TextureManager::getSingleton().createManual( |
138 | 0 | targName, |
139 | 0 | ResourceGroupManager::INTERNAL_RESOURCE_GROUP_NAME, |
140 | 0 | TEX_TYPE_2D, 1, 1, 0, format, TU_STATIC_WRITE_ONLY); |
141 | 0 | mNullTextureList.push_back(shadowTex); |
142 | | |
143 | | // lock & populate the texture based on format |
144 | 0 | if(PixelUtil::isDepth(format)) |
145 | 0 | return shadowTex; |
146 | | |
147 | 0 | HardwareBufferLockGuard shadowTexLock(shadowTex->getBuffer(), HardwareBuffer::HBL_DISCARD); |
148 | 0 | const PixelBox& box = shadowTex->getBuffer()->getCurrentLock(); |
149 | | |
150 | | // set high-values across all bytes of the format |
151 | 0 | PixelUtil::packColour( 1.0f, 1.0f, 1.0f, 1.0f, shadowTex->getFormat(), box.data ); |
152 | |
|
153 | 0 | return shadowTex; |
154 | | |
155 | 0 | } |
156 | | //--------------------------------------------------------------------- |
157 | | void ShadowTextureManager::clearUnused() |
158 | 0 | { |
159 | 0 | for (ShadowTextureList::iterator i = mTextureList.begin(); i != mTextureList.end(); ) |
160 | 0 | { |
161 | | // Unreferenced if only this reference and the resource system |
162 | | // Any cached shadow textures should be re-bound each frame dropping |
163 | | // any old references |
164 | 0 | if ((*i).use_count() == ResourceGroupManager::RESOURCE_SYSTEM_NUM_REFERENCE_COUNTS + 1) |
165 | 0 | { |
166 | 0 | TextureManager::getSingleton().remove((*i)->getHandle()); |
167 | 0 | i = mTextureList.erase(i); |
168 | 0 | } |
169 | 0 | else |
170 | 0 | { |
171 | 0 | ++i; |
172 | 0 | } |
173 | 0 | } |
174 | 0 | for (ShadowTextureList::iterator i = mNullTextureList.begin(); i != mNullTextureList.end(); ) |
175 | 0 | { |
176 | | // Unreferenced if only this reference and the resource system |
177 | | // Any cached shadow textures should be re-bound each frame dropping |
178 | | // any old references |
179 | 0 | if ((*i).use_count() == ResourceGroupManager::RESOURCE_SYSTEM_NUM_REFERENCE_COUNTS + 1) |
180 | 0 | { |
181 | 0 | TextureManager::getSingleton().remove((*i)->getHandle()); |
182 | 0 | i = mNullTextureList.erase(i); |
183 | 0 | } |
184 | 0 | else |
185 | 0 | { |
186 | 0 | ++i; |
187 | 0 | } |
188 | 0 | } |
189 | |
|
190 | 0 | } |
191 | | //--------------------------------------------------------------------- |
192 | | void ShadowTextureManager::clear() |
193 | 1 | { |
194 | 1 | for (auto & i : mTextureList) |
195 | 0 | { |
196 | 0 | TextureManager::getSingleton().remove(i->getHandle()); |
197 | 0 | } |
198 | 1 | mTextureList.clear(); |
199 | | |
200 | 1 | } |
201 | | //--------------------------------------------------------------------- |
202 | | |
203 | | } |
204 | | |