diff options
Diffstat (limited to 'libraries/irrlicht-1.8/source/Irrlicht/CNullDriver.cpp')
-rw-r--r-- | libraries/irrlicht-1.8/source/Irrlicht/CNullDriver.cpp | 4896 |
1 files changed, 2448 insertions, 2448 deletions
diff --git a/libraries/irrlicht-1.8/source/Irrlicht/CNullDriver.cpp b/libraries/irrlicht-1.8/source/Irrlicht/CNullDriver.cpp index 3d02abe..15f32f9 100644 --- a/libraries/irrlicht-1.8/source/Irrlicht/CNullDriver.cpp +++ b/libraries/irrlicht-1.8/source/Irrlicht/CNullDriver.cpp | |||
@@ -1,2448 +1,2448 @@ | |||
1 | // Copyright (C) 2002-2012 Nikolaus Gebhardt | 1 | // Copyright (C) 2002-2012 Nikolaus Gebhardt |
2 | // This file is part of the "Irrlicht Engine". | 2 | // This file is part of the "Irrlicht Engine". |
3 | // For conditions of distribution and use, see copyright notice in irrlicht.h | 3 | // For conditions of distribution and use, see copyright notice in irrlicht.h |
4 | 4 | ||
5 | #include "CNullDriver.h" | 5 | #include "CNullDriver.h" |
6 | #include "os.h" | 6 | #include "os.h" |
7 | #include "CImage.h" | 7 | #include "CImage.h" |
8 | #include "CAttributes.h" | 8 | #include "CAttributes.h" |
9 | #include "IReadFile.h" | 9 | #include "IReadFile.h" |
10 | #include "IWriteFile.h" | 10 | #include "IWriteFile.h" |
11 | #include "IImageLoader.h" | 11 | #include "IImageLoader.h" |
12 | #include "IImageWriter.h" | 12 | #include "IImageWriter.h" |
13 | #include "IMaterialRenderer.h" | 13 | #include "IMaterialRenderer.h" |
14 | #include "IAnimatedMeshSceneNode.h" | 14 | #include "IAnimatedMeshSceneNode.h" |
15 | #include "CMeshManipulator.h" | 15 | #include "CMeshManipulator.h" |
16 | #include "CColorConverter.h" | 16 | #include "CColorConverter.h" |
17 | #include "IAttributeExchangingObject.h" | 17 | #include "IAttributeExchangingObject.h" |
18 | 18 | ||
19 | 19 | ||
20 | namespace irr | 20 | namespace irr |
21 | { | 21 | { |
22 | namespace video | 22 | namespace video |
23 | { | 23 | { |
24 | 24 | ||
25 | //! creates a loader which is able to load windows bitmaps | 25 | //! creates a loader which is able to load windows bitmaps |
26 | IImageLoader* createImageLoaderBMP(); | 26 | IImageLoader* createImageLoaderBMP(); |
27 | 27 | ||
28 | //! creates a loader which is able to load jpeg images | 28 | //! creates a loader which is able to load jpeg images |
29 | IImageLoader* createImageLoaderJPG(); | 29 | IImageLoader* createImageLoaderJPG(); |
30 | 30 | ||
31 | //! creates a loader which is able to load targa images | 31 | //! creates a loader which is able to load targa images |
32 | IImageLoader* createImageLoaderTGA(); | 32 | IImageLoader* createImageLoaderTGA(); |
33 | 33 | ||
34 | //! creates a loader which is able to load psd images | 34 | //! creates a loader which is able to load psd images |
35 | IImageLoader* createImageLoaderPSD(); | 35 | IImageLoader* createImageLoaderPSD(); |
36 | 36 | ||
37 | //! creates a loader which is able to load dds images | 37 | //! creates a loader which is able to load dds images |
38 | IImageLoader* createImageLoaderDDS(); | 38 | IImageLoader* createImageLoaderDDS(); |
39 | 39 | ||
40 | //! creates a loader which is able to load pcx images | 40 | //! creates a loader which is able to load pcx images |
41 | IImageLoader* createImageLoaderPCX(); | 41 | IImageLoader* createImageLoaderPCX(); |
42 | 42 | ||
43 | //! creates a loader which is able to load png images | 43 | //! creates a loader which is able to load png images |
44 | IImageLoader* createImageLoaderPNG(); | 44 | IImageLoader* createImageLoaderPNG(); |
45 | 45 | ||
46 | //! creates a loader which is able to load WAL images | 46 | //! creates a loader which is able to load WAL images |
47 | IImageLoader* createImageLoaderWAL(); | 47 | IImageLoader* createImageLoaderWAL(); |
48 | 48 | ||
49 | //! creates a loader which is able to load halflife images | 49 | //! creates a loader which is able to load halflife images |
50 | IImageLoader* createImageLoaderHalfLife(); | 50 | IImageLoader* createImageLoaderHalfLife(); |
51 | 51 | ||
52 | //! creates a loader which is able to load lmp images | 52 | //! creates a loader which is able to load lmp images |
53 | IImageLoader* createImageLoaderLMP(); | 53 | IImageLoader* createImageLoaderLMP(); |
54 | 54 | ||
55 | //! creates a loader which is able to load ppm/pgm/pbm images | 55 | //! creates a loader which is able to load ppm/pgm/pbm images |
56 | IImageLoader* createImageLoaderPPM(); | 56 | IImageLoader* createImageLoaderPPM(); |
57 | 57 | ||
58 | //! creates a loader which is able to load rgb images | 58 | //! creates a loader which is able to load rgb images |
59 | IImageLoader* createImageLoaderRGB(); | 59 | IImageLoader* createImageLoaderRGB(); |
60 | 60 | ||
61 | 61 | ||
62 | //! creates a writer which is able to save bmp images | 62 | //! creates a writer which is able to save bmp images |
63 | IImageWriter* createImageWriterBMP(); | 63 | IImageWriter* createImageWriterBMP(); |
64 | 64 | ||
65 | //! creates a writer which is able to save jpg images | 65 | //! creates a writer which is able to save jpg images |
66 | IImageWriter* createImageWriterJPG(); | 66 | IImageWriter* createImageWriterJPG(); |
67 | 67 | ||
68 | //! creates a writer which is able to save tga images | 68 | //! creates a writer which is able to save tga images |
69 | IImageWriter* createImageWriterTGA(); | 69 | IImageWriter* createImageWriterTGA(); |
70 | 70 | ||
71 | //! creates a writer which is able to save psd images | 71 | //! creates a writer which is able to save psd images |
72 | IImageWriter* createImageWriterPSD(); | 72 | IImageWriter* createImageWriterPSD(); |
73 | 73 | ||
74 | //! creates a writer which is able to save pcx images | 74 | //! creates a writer which is able to save pcx images |
75 | IImageWriter* createImageWriterPCX(); | 75 | IImageWriter* createImageWriterPCX(); |
76 | 76 | ||
77 | //! creates a writer which is able to save png images | 77 | //! creates a writer which is able to save png images |
78 | IImageWriter* createImageWriterPNG(); | 78 | IImageWriter* createImageWriterPNG(); |
79 | 79 | ||
80 | //! creates a writer which is able to save ppm images | 80 | //! creates a writer which is able to save ppm images |
81 | IImageWriter* createImageWriterPPM(); | 81 | IImageWriter* createImageWriterPPM(); |
82 | 82 | ||
83 | //! constructor | 83 | //! constructor |
84 | CNullDriver::CNullDriver(io::IFileSystem* io, const core::dimension2d<u32>& screenSize) | 84 | CNullDriver::CNullDriver(io::IFileSystem* io, const core::dimension2d<u32>& screenSize) |
85 | : FileSystem(io), MeshManipulator(0), ViewPort(0,0,0,0), ScreenSize(screenSize), | 85 | : FileSystem(io), MeshManipulator(0), ViewPort(0,0,0,0), ScreenSize(screenSize), |
86 | PrimitivesDrawn(0), MinVertexCountForVBO(500), TextureCreationFlags(0), | 86 | PrimitivesDrawn(0), MinVertexCountForVBO(500), TextureCreationFlags(0), |
87 | OverrideMaterial2DEnabled(false), AllowZWriteOnTransparent(false) | 87 | OverrideMaterial2DEnabled(false), AllowZWriteOnTransparent(false) |
88 | { | 88 | { |
89 | #ifdef _DEBUG | 89 | #ifdef _DEBUG |
90 | setDebugName("CNullDriver"); | 90 | setDebugName("CNullDriver"); |
91 | #endif | 91 | #endif |
92 | 92 | ||
93 | DriverAttributes = new io::CAttributes(); | 93 | DriverAttributes = new io::CAttributes(); |
94 | DriverAttributes->addInt("MaxTextures", _IRR_MATERIAL_MAX_TEXTURES_); | 94 | DriverAttributes->addInt("MaxTextures", _IRR_MATERIAL_MAX_TEXTURES_); |
95 | DriverAttributes->addInt("MaxSupportedTextures", _IRR_MATERIAL_MAX_TEXTURES_); | 95 | DriverAttributes->addInt("MaxSupportedTextures", _IRR_MATERIAL_MAX_TEXTURES_); |
96 | DriverAttributes->addInt("MaxLights", getMaximalDynamicLightAmount()); | 96 | DriverAttributes->addInt("MaxLights", getMaximalDynamicLightAmount()); |
97 | DriverAttributes->addInt("MaxAnisotropy", 1); | 97 | DriverAttributes->addInt("MaxAnisotropy", 1); |
98 | // DriverAttributes->addInt("MaxUserClipPlanes", 0); | 98 | // DriverAttributes->addInt("MaxUserClipPlanes", 0); |
99 | // DriverAttributes->addInt("MaxAuxBuffers", 0); | 99 | // DriverAttributes->addInt("MaxAuxBuffers", 0); |
100 | DriverAttributes->addInt("MaxMultipleRenderTargets", 1); | 100 | DriverAttributes->addInt("MaxMultipleRenderTargets", 1); |
101 | DriverAttributes->addInt("MaxIndices", -1); | 101 | DriverAttributes->addInt("MaxIndices", -1); |
102 | DriverAttributes->addInt("MaxTextureSize", -1); | 102 | DriverAttributes->addInt("MaxTextureSize", -1); |
103 | // DriverAttributes->addInt("MaxGeometryVerticesOut", 0); | 103 | // DriverAttributes->addInt("MaxGeometryVerticesOut", 0); |
104 | // DriverAttributes->addFloat("MaxTextureLODBias", 0.f); | 104 | // DriverAttributes->addFloat("MaxTextureLODBias", 0.f); |
105 | DriverAttributes->addInt("Version", 1); | 105 | DriverAttributes->addInt("Version", 1); |
106 | // DriverAttributes->addInt("ShaderLanguageVersion", 0); | 106 | // DriverAttributes->addInt("ShaderLanguageVersion", 0); |
107 | // DriverAttributes->addInt("AntiAlias", 0); | 107 | // DriverAttributes->addInt("AntiAlias", 0); |
108 | 108 | ||
109 | setFog(); | 109 | setFog(); |
110 | 110 | ||
111 | setTextureCreationFlag(ETCF_ALWAYS_32_BIT, true); | 111 | setTextureCreationFlag(ETCF_ALWAYS_32_BIT, true); |
112 | setTextureCreationFlag(ETCF_CREATE_MIP_MAPS, true); | 112 | setTextureCreationFlag(ETCF_CREATE_MIP_MAPS, true); |
113 | 113 | ||
114 | ViewPort = core::rect<s32>(core::position2d<s32>(0,0), core::dimension2di(screenSize)); | 114 | ViewPort = core::rect<s32>(core::position2d<s32>(0,0), core::dimension2di(screenSize)); |
115 | 115 | ||
116 | // create manipulator | 116 | // create manipulator |
117 | MeshManipulator = new scene::CMeshManipulator(); | 117 | MeshManipulator = new scene::CMeshManipulator(); |
118 | 118 | ||
119 | if (FileSystem) | 119 | if (FileSystem) |
120 | FileSystem->grab(); | 120 | FileSystem->grab(); |
121 | 121 | ||
122 | // create surface loader | 122 | // create surface loader |
123 | 123 | ||
124 | #ifdef _IRR_COMPILE_WITH_HALFLIFE_LOADER_ | 124 | #ifdef _IRR_COMPILE_WITH_HALFLIFE_LOADER_ |
125 | SurfaceLoader.push_back(video::createImageLoaderHalfLife()); | 125 | SurfaceLoader.push_back(video::createImageLoaderHalfLife()); |
126 | #endif | 126 | #endif |
127 | #ifdef _IRR_COMPILE_WITH_WAL_LOADER_ | 127 | #ifdef _IRR_COMPILE_WITH_WAL_LOADER_ |
128 | SurfaceLoader.push_back(video::createImageLoaderWAL()); | 128 | SurfaceLoader.push_back(video::createImageLoaderWAL()); |
129 | #endif | 129 | #endif |
130 | #ifdef _IRR_COMPILE_WITH_LMP_LOADER_ | 130 | #ifdef _IRR_COMPILE_WITH_LMP_LOADER_ |
131 | SurfaceLoader.push_back(video::createImageLoaderLMP()); | 131 | SurfaceLoader.push_back(video::createImageLoaderLMP()); |
132 | #endif | 132 | #endif |
133 | #ifdef _IRR_COMPILE_WITH_PPM_LOADER_ | 133 | #ifdef _IRR_COMPILE_WITH_PPM_LOADER_ |
134 | SurfaceLoader.push_back(video::createImageLoaderPPM()); | 134 | SurfaceLoader.push_back(video::createImageLoaderPPM()); |
135 | #endif | 135 | #endif |
136 | #ifdef _IRR_COMPILE_WITH_RGB_LOADER_ | 136 | #ifdef _IRR_COMPILE_WITH_RGB_LOADER_ |
137 | SurfaceLoader.push_back(video::createImageLoaderRGB()); | 137 | SurfaceLoader.push_back(video::createImageLoaderRGB()); |
138 | #endif | 138 | #endif |
139 | #ifdef _IRR_COMPILE_WITH_PSD_LOADER_ | 139 | #ifdef _IRR_COMPILE_WITH_PSD_LOADER_ |
140 | SurfaceLoader.push_back(video::createImageLoaderPSD()); | 140 | SurfaceLoader.push_back(video::createImageLoaderPSD()); |
141 | #endif | 141 | #endif |
142 | #ifdef _IRR_COMPILE_WITH_DDS_LOADER_ | 142 | #ifdef _IRR_COMPILE_WITH_DDS_LOADER_ |
143 | SurfaceLoader.push_back(video::createImageLoaderDDS()); | 143 | SurfaceLoader.push_back(video::createImageLoaderDDS()); |
144 | #endif | 144 | #endif |
145 | #ifdef _IRR_COMPILE_WITH_PCX_LOADER_ | 145 | #ifdef _IRR_COMPILE_WITH_PCX_LOADER_ |
146 | SurfaceLoader.push_back(video::createImageLoaderPCX()); | 146 | SurfaceLoader.push_back(video::createImageLoaderPCX()); |
147 | #endif | 147 | #endif |
148 | #ifdef _IRR_COMPILE_WITH_TGA_LOADER_ | 148 | #ifdef _IRR_COMPILE_WITH_TGA_LOADER_ |
149 | SurfaceLoader.push_back(video::createImageLoaderTGA()); | 149 | SurfaceLoader.push_back(video::createImageLoaderTGA()); |
150 | #endif | 150 | #endif |
151 | #ifdef _IRR_COMPILE_WITH_PNG_LOADER_ | 151 | #ifdef _IRR_COMPILE_WITH_PNG_LOADER_ |
152 | SurfaceLoader.push_back(video::createImageLoaderPNG()); | 152 | SurfaceLoader.push_back(video::createImageLoaderPNG()); |
153 | #endif | 153 | #endif |
154 | #ifdef _IRR_COMPILE_WITH_JPG_LOADER_ | 154 | #ifdef _IRR_COMPILE_WITH_JPG_LOADER_ |
155 | SurfaceLoader.push_back(video::createImageLoaderJPG()); | 155 | SurfaceLoader.push_back(video::createImageLoaderJPG()); |
156 | #endif | 156 | #endif |
157 | #ifdef _IRR_COMPILE_WITH_BMP_LOADER_ | 157 | #ifdef _IRR_COMPILE_WITH_BMP_LOADER_ |
158 | SurfaceLoader.push_back(video::createImageLoaderBMP()); | 158 | SurfaceLoader.push_back(video::createImageLoaderBMP()); |
159 | #endif | 159 | #endif |
160 | 160 | ||
161 | 161 | ||
162 | #ifdef _IRR_COMPILE_WITH_PPM_WRITER_ | 162 | #ifdef _IRR_COMPILE_WITH_PPM_WRITER_ |
163 | SurfaceWriter.push_back(video::createImageWriterPPM()); | 163 | SurfaceWriter.push_back(video::createImageWriterPPM()); |
164 | #endif | 164 | #endif |
165 | #ifdef _IRR_COMPILE_WITH_PCX_WRITER_ | 165 | #ifdef _IRR_COMPILE_WITH_PCX_WRITER_ |
166 | SurfaceWriter.push_back(video::createImageWriterPCX()); | 166 | SurfaceWriter.push_back(video::createImageWriterPCX()); |
167 | #endif | 167 | #endif |
168 | #ifdef _IRR_COMPILE_WITH_PSD_WRITER_ | 168 | #ifdef _IRR_COMPILE_WITH_PSD_WRITER_ |
169 | SurfaceWriter.push_back(video::createImageWriterPSD()); | 169 | SurfaceWriter.push_back(video::createImageWriterPSD()); |
170 | #endif | 170 | #endif |
171 | #ifdef _IRR_COMPILE_WITH_TGA_WRITER_ | 171 | #ifdef _IRR_COMPILE_WITH_TGA_WRITER_ |
172 | SurfaceWriter.push_back(video::createImageWriterTGA()); | 172 | SurfaceWriter.push_back(video::createImageWriterTGA()); |
173 | #endif | 173 | #endif |
174 | #ifdef _IRR_COMPILE_WITH_JPG_WRITER_ | 174 | #ifdef _IRR_COMPILE_WITH_JPG_WRITER_ |
175 | SurfaceWriter.push_back(video::createImageWriterJPG()); | 175 | SurfaceWriter.push_back(video::createImageWriterJPG()); |
176 | #endif | 176 | #endif |
177 | #ifdef _IRR_COMPILE_WITH_PNG_WRITER_ | 177 | #ifdef _IRR_COMPILE_WITH_PNG_WRITER_ |
178 | SurfaceWriter.push_back(video::createImageWriterPNG()); | 178 | SurfaceWriter.push_back(video::createImageWriterPNG()); |
179 | #endif | 179 | #endif |
180 | #ifdef _IRR_COMPILE_WITH_BMP_WRITER_ | 180 | #ifdef _IRR_COMPILE_WITH_BMP_WRITER_ |
181 | SurfaceWriter.push_back(video::createImageWriterBMP()); | 181 | SurfaceWriter.push_back(video::createImageWriterBMP()); |
182 | #endif | 182 | #endif |
183 | 183 | ||
184 | 184 | ||
185 | // set ExposedData to 0 | 185 | // set ExposedData to 0 |
186 | memset(&ExposedData, 0, sizeof(ExposedData)); | 186 | memset(&ExposedData, 0, sizeof(ExposedData)); |
187 | for (u32 i=0; i<video::EVDF_COUNT; ++i) | 187 | for (u32 i=0; i<video::EVDF_COUNT; ++i) |
188 | FeatureEnabled[i]=true; | 188 | FeatureEnabled[i]=true; |
189 | 189 | ||
190 | InitMaterial2D.AntiAliasing=video::EAAM_OFF; | 190 | InitMaterial2D.AntiAliasing=video::EAAM_OFF; |
191 | InitMaterial2D.Lighting=false; | 191 | InitMaterial2D.Lighting=false; |
192 | InitMaterial2D.ZWriteEnable=false; | 192 | InitMaterial2D.ZWriteEnable=false; |
193 | InitMaterial2D.ZBuffer=video::ECFN_NEVER; | 193 | InitMaterial2D.ZBuffer=video::ECFN_NEVER; |
194 | InitMaterial2D.UseMipMaps=false; | 194 | InitMaterial2D.UseMipMaps=false; |
195 | for (u32 i=0; i<video::MATERIAL_MAX_TEXTURES; ++i) | 195 | for (u32 i=0; i<video::MATERIAL_MAX_TEXTURES; ++i) |
196 | { | 196 | { |
197 | InitMaterial2D.TextureLayer[i].BilinearFilter=false; | 197 | InitMaterial2D.TextureLayer[i].BilinearFilter=false; |
198 | InitMaterial2D.TextureLayer[i].TextureWrapU=video::ETC_REPEAT; | 198 | InitMaterial2D.TextureLayer[i].TextureWrapU=video::ETC_REPEAT; |
199 | InitMaterial2D.TextureLayer[i].TextureWrapV=video::ETC_REPEAT; | 199 | InitMaterial2D.TextureLayer[i].TextureWrapV=video::ETC_REPEAT; |
200 | } | 200 | } |
201 | OverrideMaterial2D=InitMaterial2D; | 201 | OverrideMaterial2D=InitMaterial2D; |
202 | } | 202 | } |
203 | 203 | ||
204 | 204 | ||
205 | //! destructor | 205 | //! destructor |
206 | CNullDriver::~CNullDriver() | 206 | CNullDriver::~CNullDriver() |
207 | { | 207 | { |
208 | if (DriverAttributes) | 208 | if (DriverAttributes) |
209 | DriverAttributes->drop(); | 209 | DriverAttributes->drop(); |
210 | 210 | ||
211 | if (FileSystem) | 211 | if (FileSystem) |
212 | FileSystem->drop(); | 212 | FileSystem->drop(); |
213 | 213 | ||
214 | if (MeshManipulator) | 214 | if (MeshManipulator) |
215 | MeshManipulator->drop(); | 215 | MeshManipulator->drop(); |
216 | deleteAllTextures(); | 216 | deleteAllTextures(); |
217 | 217 | ||
218 | u32 i; | 218 | u32 i; |
219 | for (i=0; i<SurfaceLoader.size(); ++i) | 219 | for (i=0; i<SurfaceLoader.size(); ++i) |
220 | SurfaceLoader[i]->drop(); | 220 | SurfaceLoader[i]->drop(); |
221 | 221 | ||
222 | for (i=0; i<SurfaceWriter.size(); ++i) | 222 | for (i=0; i<SurfaceWriter.size(); ++i) |
223 | SurfaceWriter[i]->drop(); | 223 | SurfaceWriter[i]->drop(); |
224 | 224 | ||
225 | // delete material renderers | 225 | // delete material renderers |
226 | deleteMaterialRenders(); | 226 | deleteMaterialRenders(); |
227 | 227 | ||
228 | // delete hardware mesh buffers | 228 | // delete hardware mesh buffers |
229 | removeAllHardwareBuffers(); | 229 | removeAllHardwareBuffers(); |
230 | } | 230 | } |
231 | 231 | ||
232 | 232 | ||
233 | //! Adds an external surface loader to the engine. | 233 | //! Adds an external surface loader to the engine. |
234 | void CNullDriver::addExternalImageLoader(IImageLoader* loader) | 234 | void CNullDriver::addExternalImageLoader(IImageLoader* loader) |
235 | { | 235 | { |
236 | if (!loader) | 236 | if (!loader) |
237 | return; | 237 | return; |
238 | 238 | ||
239 | loader->grab(); | 239 | loader->grab(); |
240 | SurfaceLoader.push_back(loader); | 240 | SurfaceLoader.push_back(loader); |
241 | } | 241 | } |
242 | 242 | ||
243 | 243 | ||
244 | //! Adds an external surface writer to the engine. | 244 | //! Adds an external surface writer to the engine. |
245 | void CNullDriver::addExternalImageWriter(IImageWriter* writer) | 245 | void CNullDriver::addExternalImageWriter(IImageWriter* writer) |
246 | { | 246 | { |
247 | if (!writer) | 247 | if (!writer) |
248 | return; | 248 | return; |
249 | 249 | ||
250 | writer->grab(); | 250 | writer->grab(); |
251 | SurfaceWriter.push_back(writer); | 251 | SurfaceWriter.push_back(writer); |
252 | } | 252 | } |
253 | 253 | ||
254 | 254 | ||
255 | //! Retrieve the number of image loaders | 255 | //! Retrieve the number of image loaders |
256 | u32 CNullDriver::getImageLoaderCount() const | 256 | u32 CNullDriver::getImageLoaderCount() const |
257 | { | 257 | { |
258 | return SurfaceLoader.size(); | 258 | return SurfaceLoader.size(); |
259 | } | 259 | } |
260 | 260 | ||
261 | 261 | ||
262 | //! Retrieve the given image loader | 262 | //! Retrieve the given image loader |
263 | IImageLoader* CNullDriver::getImageLoader(u32 n) | 263 | IImageLoader* CNullDriver::getImageLoader(u32 n) |
264 | { | 264 | { |
265 | if (n < SurfaceLoader.size()) | 265 | if (n < SurfaceLoader.size()) |
266 | return SurfaceLoader[n]; | 266 | return SurfaceLoader[n]; |
267 | return 0; | 267 | return 0; |
268 | } | 268 | } |
269 | 269 | ||
270 | 270 | ||
271 | //! Retrieve the number of image writers | 271 | //! Retrieve the number of image writers |
272 | u32 CNullDriver::getImageWriterCount() const | 272 | u32 CNullDriver::getImageWriterCount() const |
273 | { | 273 | { |
274 | return SurfaceWriter.size(); | 274 | return SurfaceWriter.size(); |
275 | } | 275 | } |
276 | 276 | ||
277 | 277 | ||
278 | //! Retrieve the given image writer | 278 | //! Retrieve the given image writer |
279 | IImageWriter* CNullDriver::getImageWriter(u32 n) | 279 | IImageWriter* CNullDriver::getImageWriter(u32 n) |
280 | { | 280 | { |
281 | if (n < SurfaceWriter.size()) | 281 | if (n < SurfaceWriter.size()) |
282 | return SurfaceWriter[n]; | 282 | return SurfaceWriter[n]; |
283 | return 0; | 283 | return 0; |
284 | } | 284 | } |
285 | 285 | ||
286 | 286 | ||
287 | //! deletes all textures | 287 | //! deletes all textures |
288 | void CNullDriver::deleteAllTextures() | 288 | void CNullDriver::deleteAllTextures() |
289 | { | 289 | { |
290 | // we need to remove previously set textures which might otherwise be kept in the | 290 | // we need to remove previously set textures which might otherwise be kept in the |
291 | // last set material member. Could be optimized to reduce state changes. | 291 | // last set material member. Could be optimized to reduce state changes. |
292 | setMaterial(SMaterial()); | 292 | setMaterial(SMaterial()); |
293 | 293 | ||
294 | for (u32 i=0; i<Textures.size(); ++i) | 294 | for (u32 i=0; i<Textures.size(); ++i) |
295 | Textures[i].Surface->drop(); | 295 | Textures[i].Surface->drop(); |
296 | 296 | ||
297 | Textures.clear(); | 297 | Textures.clear(); |
298 | } | 298 | } |
299 | 299 | ||
300 | 300 | ||
301 | 301 | ||
302 | //! applications must call this method before performing any rendering. returns false if failed. | 302 | //! applications must call this method before performing any rendering. returns false if failed. |
303 | bool CNullDriver::beginScene(bool backBuffer, bool zBuffer, SColor color, | 303 | bool CNullDriver::beginScene(bool backBuffer, bool zBuffer, SColor color, |
304 | const SExposedVideoData& videoData, core::rect<s32>* sourceRect) | 304 | const SExposedVideoData& videoData, core::rect<s32>* sourceRect) |
305 | { | 305 | { |
306 | core::clearFPUException(); | 306 | core::clearFPUException(); |
307 | PrimitivesDrawn = 0; | 307 | PrimitivesDrawn = 0; |
308 | return true; | 308 | return true; |
309 | } | 309 | } |
310 | 310 | ||
311 | 311 | ||
312 | //! applications must call this method after performing any rendering. returns false if failed. | 312 | //! applications must call this method after performing any rendering. returns false if failed. |
313 | bool CNullDriver::endScene() | 313 | bool CNullDriver::endScene() |
314 | { | 314 | { |
315 | FPSCounter.registerFrame(os::Timer::getRealTime(), PrimitivesDrawn); | 315 | FPSCounter.registerFrame(os::Timer::getRealTime(), PrimitivesDrawn); |
316 | updateAllHardwareBuffers(); | 316 | updateAllHardwareBuffers(); |
317 | updateAllOcclusionQueries(); | 317 | updateAllOcclusionQueries(); |
318 | return true; | 318 | return true; |
319 | } | 319 | } |
320 | 320 | ||
321 | 321 | ||
322 | //! Disable a feature of the driver. | 322 | //! Disable a feature of the driver. |
323 | void CNullDriver::disableFeature(E_VIDEO_DRIVER_FEATURE feature, bool flag) | 323 | void CNullDriver::disableFeature(E_VIDEO_DRIVER_FEATURE feature, bool flag) |
324 | { | 324 | { |
325 | FeatureEnabled[feature]=!flag; | 325 | FeatureEnabled[feature]=!flag; |
326 | } | 326 | } |
327 | 327 | ||
328 | 328 | ||
329 | //! queries the features of the driver, returns true if feature is available | 329 | //! queries the features of the driver, returns true if feature is available |
330 | bool CNullDriver::queryFeature(E_VIDEO_DRIVER_FEATURE feature) const | 330 | bool CNullDriver::queryFeature(E_VIDEO_DRIVER_FEATURE feature) const |
331 | { | 331 | { |
332 | return false; | 332 | return false; |
333 | } | 333 | } |
334 | 334 | ||
335 | 335 | ||
336 | //! Get attributes of the actual video driver | 336 | //! Get attributes of the actual video driver |
337 | const io::IAttributes& CNullDriver::getDriverAttributes() const | 337 | const io::IAttributes& CNullDriver::getDriverAttributes() const |
338 | { | 338 | { |
339 | return *DriverAttributes; | 339 | return *DriverAttributes; |
340 | } | 340 | } |
341 | 341 | ||
342 | 342 | ||
343 | //! sets transformation | 343 | //! sets transformation |
344 | void CNullDriver::setTransform(E_TRANSFORMATION_STATE state, const core::matrix4& mat) | 344 | void CNullDriver::setTransform(E_TRANSFORMATION_STATE state, const core::matrix4& mat) |
345 | { | 345 | { |
346 | } | 346 | } |
347 | 347 | ||
348 | 348 | ||
349 | //! Returns the transformation set by setTransform | 349 | //! Returns the transformation set by setTransform |
350 | const core::matrix4& CNullDriver::getTransform(E_TRANSFORMATION_STATE state) const | 350 | const core::matrix4& CNullDriver::getTransform(E_TRANSFORMATION_STATE state) const |
351 | { | 351 | { |
352 | return TransformationMatrix; | 352 | return TransformationMatrix; |
353 | } | 353 | } |
354 | 354 | ||
355 | 355 | ||
356 | //! sets a material | 356 | //! sets a material |
357 | void CNullDriver::setMaterial(const SMaterial& material) | 357 | void CNullDriver::setMaterial(const SMaterial& material) |
358 | { | 358 | { |
359 | } | 359 | } |
360 | 360 | ||
361 | 361 | ||
362 | //! Removes a texture from the texture cache and deletes it, freeing lot of | 362 | //! Removes a texture from the texture cache and deletes it, freeing lot of |
363 | //! memory. | 363 | //! memory. |
364 | void CNullDriver::removeTexture(ITexture* texture) | 364 | void CNullDriver::removeTexture(ITexture* texture) |
365 | { | 365 | { |
366 | if (!texture) | 366 | if (!texture) |
367 | return; | 367 | return; |
368 | 368 | ||
369 | for (u32 i=0; i<Textures.size(); ++i) | 369 | for (u32 i=0; i<Textures.size(); ++i) |
370 | { | 370 | { |
371 | if (Textures[i].Surface == texture) | 371 | if (Textures[i].Surface == texture) |
372 | { | 372 | { |
373 | texture->drop(); | 373 | texture->drop(); |
374 | Textures.erase(i); | 374 | Textures.erase(i); |
375 | } | 375 | } |
376 | } | 376 | } |
377 | } | 377 | } |
378 | 378 | ||
379 | 379 | ||
380 | //! Removes all texture from the texture cache and deletes them, freeing lot of | 380 | //! Removes all texture from the texture cache and deletes them, freeing lot of |
381 | //! memory. | 381 | //! memory. |
382 | void CNullDriver::removeAllTextures() | 382 | void CNullDriver::removeAllTextures() |
383 | { | 383 | { |
384 | setMaterial ( SMaterial() ); | 384 | setMaterial ( SMaterial() ); |
385 | deleteAllTextures(); | 385 | deleteAllTextures(); |
386 | } | 386 | } |
387 | 387 | ||
388 | 388 | ||
389 | //! Returns a texture by index | 389 | //! Returns a texture by index |
390 | ITexture* CNullDriver::getTextureByIndex(u32 i) | 390 | ITexture* CNullDriver::getTextureByIndex(u32 i) |
391 | { | 391 | { |
392 | if ( i < Textures.size() ) | 392 | if ( i < Textures.size() ) |
393 | return Textures[i].Surface; | 393 | return Textures[i].Surface; |
394 | 394 | ||
395 | return 0; | 395 | return 0; |
396 | } | 396 | } |
397 | 397 | ||
398 | 398 | ||
399 | //! Returns amount of textures currently loaded | 399 | //! Returns amount of textures currently loaded |
400 | u32 CNullDriver::getTextureCount() const | 400 | u32 CNullDriver::getTextureCount() const |
401 | { | 401 | { |
402 | return Textures.size(); | 402 | return Textures.size(); |
403 | } | 403 | } |
404 | 404 | ||
405 | 405 | ||
406 | //! Renames a texture | 406 | //! Renames a texture |
407 | void CNullDriver::renameTexture(ITexture* texture, const io::path& newName) | 407 | void CNullDriver::renameTexture(ITexture* texture, const io::path& newName) |
408 | { | 408 | { |
409 | // we can do a const_cast here safely, the name of the ITexture interface | 409 | // we can do a const_cast here safely, the name of the ITexture interface |
410 | // is just readonly to prevent the user changing the texture name without invoking | 410 | // is just readonly to prevent the user changing the texture name without invoking |
411 | // this method, because the textures will need resorting afterwards | 411 | // this method, because the textures will need resorting afterwards |
412 | 412 | ||
413 | io::SNamedPath& name = const_cast<io::SNamedPath&>(texture->getName()); | 413 | io::SNamedPath& name = const_cast<io::SNamedPath&>(texture->getName()); |
414 | name.setPath(newName); | 414 | name.setPath(newName); |
415 | 415 | ||
416 | Textures.sort(); | 416 | Textures.sort(); |
417 | } | 417 | } |
418 | 418 | ||
419 | 419 | ||
420 | //! loads a Texture | 420 | //! loads a Texture |
421 | ITexture* CNullDriver::getTexture(const io::path& filename) | 421 | ITexture* CNullDriver::getTexture(const io::path& filename) |
422 | { | 422 | { |
423 | // Identify textures by their absolute filenames if possible. | 423 | // Identify textures by their absolute filenames if possible. |
424 | const io::path absolutePath = FileSystem->getAbsolutePath(filename); | 424 | const io::path absolutePath = FileSystem->getAbsolutePath(filename); |
425 | 425 | ||
426 | ITexture* texture = findTexture(absolutePath); | 426 | ITexture* texture = findTexture(absolutePath); |
427 | if (texture) | 427 | if (texture) |
428 | return texture; | 428 | return texture; |
429 | 429 | ||
430 | // Then try the raw filename, which might be in an Archive | 430 | // Then try the raw filename, which might be in an Archive |
431 | texture = findTexture(filename); | 431 | texture = findTexture(filename); |
432 | if (texture) | 432 | if (texture) |
433 | return texture; | 433 | return texture; |
434 | 434 | ||
435 | // Now try to open the file using the complete path. | 435 | // Now try to open the file using the complete path. |
436 | io::IReadFile* file = FileSystem->createAndOpenFile(absolutePath); | 436 | io::IReadFile* file = FileSystem->createAndOpenFile(absolutePath); |
437 | 437 | ||
438 | if (!file) | 438 | if (!file) |
439 | { | 439 | { |
440 | // Try to open it using the raw filename. | 440 | // Try to open it using the raw filename. |
441 | file = FileSystem->createAndOpenFile(filename); | 441 | file = FileSystem->createAndOpenFile(filename); |
442 | } | 442 | } |
443 | 443 | ||
444 | if (file) | 444 | if (file) |
445 | { | 445 | { |
446 | // Re-check name for actual archive names | 446 | // Re-check name for actual archive names |
447 | texture = findTexture(file->getFileName()); | 447 | texture = findTexture(file->getFileName()); |
448 | if (texture) | 448 | if (texture) |
449 | { | 449 | { |
450 | file->drop(); | 450 | file->drop(); |
451 | return texture; | 451 | return texture; |
452 | } | 452 | } |
453 | 453 | ||
454 | texture = loadTextureFromFile(file); | 454 | texture = loadTextureFromFile(file); |
455 | file->drop(); | 455 | file->drop(); |
456 | 456 | ||
457 | if (texture) | 457 | if (texture) |
458 | { | 458 | { |
459 | addTexture(texture); | 459 | addTexture(texture); |
460 | texture->drop(); // drop it because we created it, one grab too much | 460 | texture->drop(); // drop it because we created it, one grab too much |
461 | } | 461 | } |
462 | else | 462 | else |
463 | os::Printer::log("Could not load texture", filename, ELL_ERROR); | 463 | os::Printer::log("Could not load texture", filename, ELL_ERROR); |
464 | return texture; | 464 | return texture; |
465 | } | 465 | } |
466 | else | 466 | else |
467 | { | 467 | { |
468 | os::Printer::log("Could not open file of texture", filename, ELL_WARNING); | 468 | os::Printer::log("Could not open file of texture", filename, ELL_WARNING); |
469 | return 0; | 469 | return 0; |
470 | } | 470 | } |
471 | } | 471 | } |
472 | 472 | ||
473 | 473 | ||
474 | //! loads a Texture | 474 | //! loads a Texture |
475 | ITexture* CNullDriver::getTexture(io::IReadFile* file) | 475 | ITexture* CNullDriver::getTexture(io::IReadFile* file) |
476 | { | 476 | { |
477 | ITexture* texture = 0; | 477 | ITexture* texture = 0; |
478 | 478 | ||
479 | if (file) | 479 | if (file) |
480 | { | 480 | { |
481 | texture = findTexture(file->getFileName()); | 481 | texture = findTexture(file->getFileName()); |
482 | 482 | ||
483 | if (texture) | 483 | if (texture) |
484 | return texture; | 484 | return texture; |
485 | 485 | ||
486 | texture = loadTextureFromFile(file); | 486 | texture = loadTextureFromFile(file); |
487 | 487 | ||
488 | if (texture) | 488 | if (texture) |
489 | { | 489 | { |
490 | addTexture(texture); | 490 | addTexture(texture); |
491 | texture->drop(); // drop it because we created it, one grab too much | 491 | texture->drop(); // drop it because we created it, one grab too much |
492 | } | 492 | } |
493 | 493 | ||
494 | if (!texture) | 494 | if (!texture) |
495 | os::Printer::log("Could not load texture", file->getFileName(), ELL_WARNING); | 495 | os::Printer::log("Could not load texture", file->getFileName(), ELL_WARNING); |
496 | } | 496 | } |
497 | 497 | ||
498 | return texture; | 498 | return texture; |
499 | } | 499 | } |
500 | 500 | ||
501 | 501 | ||
502 | //! opens the file and loads it into the surface | 502 | //! opens the file and loads it into the surface |
503 | video::ITexture* CNullDriver::loadTextureFromFile(io::IReadFile* file, const io::path& hashName ) | 503 | video::ITexture* CNullDriver::loadTextureFromFile(io::IReadFile* file, const io::path& hashName ) |
504 | { | 504 | { |
505 | ITexture* texture = 0; | 505 | ITexture* texture = 0; |
506 | IImage* image = createImageFromFile(file); | 506 | IImage* image = createImageFromFile(file); |
507 | 507 | ||
508 | if (image) | 508 | if (image) |
509 | { | 509 | { |
510 | // create texture from surface | 510 | // create texture from surface |
511 | texture = createDeviceDependentTexture(image, hashName.size() ? hashName : file->getFileName() ); | 511 | texture = createDeviceDependentTexture(image, hashName.size() ? hashName : file->getFileName() ); |
512 | os::Printer::log("Loaded texture", file->getFileName()); | 512 | os::Printer::log("Loaded texture", file->getFileName()); |
513 | image->drop(); | 513 | image->drop(); |
514 | } | 514 | } |
515 | 515 | ||
516 | return texture; | 516 | return texture; |
517 | } | 517 | } |
518 | 518 | ||
519 | 519 | ||
520 | //! adds a surface, not loaded or created by the Irrlicht Engine | 520 | //! adds a surface, not loaded or created by the Irrlicht Engine |
521 | void CNullDriver::addTexture(video::ITexture* texture) | 521 | void CNullDriver::addTexture(video::ITexture* texture) |
522 | { | 522 | { |
523 | if (texture) | 523 | if (texture) |
524 | { | 524 | { |
525 | SSurface s; | 525 | SSurface s; |
526 | s.Surface = texture; | 526 | s.Surface = texture; |
527 | texture->grab(); | 527 | texture->grab(); |
528 | 528 | ||
529 | Textures.push_back(s); | 529 | Textures.push_back(s); |
530 | 530 | ||
531 | // the new texture is now at the end of the texture list. when searching for | 531 | // the new texture is now at the end of the texture list. when searching for |
532 | // the next new texture, the texture array will be sorted and the index of this texture | 532 | // the next new texture, the texture array will be sorted and the index of this texture |
533 | // will be changed. to let the order be more consistent to the user, sort | 533 | // will be changed. to let the order be more consistent to the user, sort |
534 | // the textures now already although this isn't necessary: | 534 | // the textures now already although this isn't necessary: |
535 | 535 | ||
536 | Textures.sort(); | 536 | Textures.sort(); |
537 | } | 537 | } |
538 | } | 538 | } |
539 | 539 | ||
540 | 540 | ||
541 | //! looks if the image is already loaded | 541 | //! looks if the image is already loaded |
542 | video::ITexture* CNullDriver::findTexture(const io::path& filename) | 542 | video::ITexture* CNullDriver::findTexture(const io::path& filename) |
543 | { | 543 | { |
544 | SSurface s; | 544 | SSurface s; |
545 | SDummyTexture dummy(filename); | 545 | SDummyTexture dummy(filename); |
546 | s.Surface = &dummy; | 546 | s.Surface = &dummy; |
547 | 547 | ||
548 | s32 index = Textures.binary_search(s); | 548 | s32 index = Textures.binary_search(s); |
549 | if (index != -1) | 549 | if (index != -1) |
550 | return Textures[index].Surface; | 550 | return Textures[index].Surface; |
551 | 551 | ||
552 | return 0; | 552 | return 0; |
553 | } | 553 | } |
554 | 554 | ||
555 | 555 | ||
556 | //! Creates a texture from a loaded IImage. | 556 | //! Creates a texture from a loaded IImage. |
557 | ITexture* CNullDriver::addTexture(const io::path& name, IImage* image, void* mipmapData) | 557 | ITexture* CNullDriver::addTexture(const io::path& name, IImage* image, void* mipmapData) |
558 | { | 558 | { |
559 | if ( 0 == name.size() || !image) | 559 | if ( 0 == name.size() || !image) |
560 | return 0; | 560 | return 0; |
561 | 561 | ||
562 | ITexture* t = createDeviceDependentTexture(image, name, mipmapData); | 562 | ITexture* t = createDeviceDependentTexture(image, name, mipmapData); |
563 | if (t) | 563 | if (t) |
564 | { | 564 | { |
565 | addTexture(t); | 565 | addTexture(t); |
566 | t->drop(); | 566 | t->drop(); |
567 | } | 567 | } |
568 | return t; | 568 | return t; |
569 | } | 569 | } |
570 | 570 | ||
571 | 571 | ||
572 | //! creates a Texture | 572 | //! creates a Texture |
573 | ITexture* CNullDriver::addTexture(const core::dimension2d<u32>& size, | 573 | ITexture* CNullDriver::addTexture(const core::dimension2d<u32>& size, |
574 | const io::path& name, ECOLOR_FORMAT format) | 574 | const io::path& name, ECOLOR_FORMAT format) |
575 | { | 575 | { |
576 | if(IImage::isRenderTargetOnlyFormat(format)) | 576 | if(IImage::isRenderTargetOnlyFormat(format)) |
577 | { | 577 | { |
578 | os::Printer::log("Could not create ITexture, format only supported for render target textures.", ELL_WARNING); | 578 | os::Printer::log("Could not create ITexture, format only supported for render target textures.", ELL_WARNING); |
579 | return 0; | 579 | return 0; |
580 | } | 580 | } |
581 | 581 | ||
582 | if ( 0 == name.size () ) | 582 | if ( 0 == name.size () ) |
583 | return 0; | 583 | return 0; |
584 | 584 | ||
585 | IImage* image = new CImage(format, size); | 585 | IImage* image = new CImage(format, size); |
586 | ITexture* t = createDeviceDependentTexture(image, name); | 586 | ITexture* t = createDeviceDependentTexture(image, name); |
587 | image->drop(); | 587 | image->drop(); |
588 | addTexture(t); | 588 | addTexture(t); |
589 | 589 | ||
590 | if (t) | 590 | if (t) |
591 | t->drop(); | 591 | t->drop(); |
592 | 592 | ||
593 | return t; | 593 | return t; |
594 | } | 594 | } |
595 | 595 | ||
596 | 596 | ||
597 | 597 | ||
598 | //! returns a device dependent texture from a software surface (IImage) | 598 | //! returns a device dependent texture from a software surface (IImage) |
599 | //! THIS METHOD HAS TO BE OVERRIDDEN BY DERIVED DRIVERS WITH OWN TEXTURES | 599 | //! THIS METHOD HAS TO BE OVERRIDDEN BY DERIVED DRIVERS WITH OWN TEXTURES |
600 | ITexture* CNullDriver::createDeviceDependentTexture(IImage* surface, const io::path& name, void* mipmapData) | 600 | ITexture* CNullDriver::createDeviceDependentTexture(IImage* surface, const io::path& name, void* mipmapData) |
601 | { | 601 | { |
602 | return new SDummyTexture(name); | 602 | return new SDummyTexture(name); |
603 | } | 603 | } |
604 | 604 | ||
605 | 605 | ||
606 | //! set or reset special render targets | 606 | //! set or reset special render targets |
607 | bool CNullDriver::setRenderTarget(video::E_RENDER_TARGET target, bool clearTarget, | 607 | bool CNullDriver::setRenderTarget(video::E_RENDER_TARGET target, bool clearTarget, |
608 | bool clearZBuffer, SColor color) | 608 | bool clearZBuffer, SColor color) |
609 | { | 609 | { |
610 | if (ERT_FRAME_BUFFER==target) | 610 | if (ERT_FRAME_BUFFER==target) |
611 | return setRenderTarget(0,clearTarget, clearZBuffer, color); | 611 | return setRenderTarget(0,clearTarget, clearZBuffer, color); |
612 | else | 612 | else |
613 | return false; | 613 | return false; |
614 | } | 614 | } |
615 | 615 | ||
616 | 616 | ||
617 | //! sets a render target | 617 | //! sets a render target |
618 | bool CNullDriver::setRenderTarget(video::ITexture* texture, bool clearBackBuffer, | 618 | bool CNullDriver::setRenderTarget(video::ITexture* texture, bool clearBackBuffer, |
619 | bool clearZBuffer, SColor color) | 619 | bool clearZBuffer, SColor color) |
620 | { | 620 | { |
621 | return false; | 621 | return false; |
622 | } | 622 | } |
623 | 623 | ||
624 | 624 | ||
625 | //! Sets multiple render targets | 625 | //! Sets multiple render targets |
626 | bool CNullDriver::setRenderTarget(const core::array<video::IRenderTarget>& texture, | 626 | bool CNullDriver::setRenderTarget(const core::array<video::IRenderTarget>& texture, |
627 | bool clearBackBuffer, bool clearZBuffer, SColor color) | 627 | bool clearBackBuffer, bool clearZBuffer, SColor color) |
628 | { | 628 | { |
629 | return false; | 629 | return false; |
630 | } | 630 | } |
631 | 631 | ||
632 | 632 | ||
633 | //! sets a viewport | 633 | //! sets a viewport |
634 | void CNullDriver::setViewPort(const core::rect<s32>& area) | 634 | void CNullDriver::setViewPort(const core::rect<s32>& area) |
635 | { | 635 | { |
636 | } | 636 | } |
637 | 637 | ||
638 | 638 | ||
639 | //! gets the area of the current viewport | 639 | //! gets the area of the current viewport |
640 | const core::rect<s32>& CNullDriver::getViewPort() const | 640 | const core::rect<s32>& CNullDriver::getViewPort() const |
641 | { | 641 | { |
642 | return ViewPort; | 642 | return ViewPort; |
643 | } | 643 | } |
644 | 644 | ||
645 | 645 | ||
646 | //! draws a vertex primitive list | 646 | //! draws a vertex primitive list |
647 | void CNullDriver::drawVertexPrimitiveList(const void* vertices, u32 vertexCount, const void* indexList, u32 primitiveCount, E_VERTEX_TYPE vType, scene::E_PRIMITIVE_TYPE pType, E_INDEX_TYPE iType) | 647 | void CNullDriver::drawVertexPrimitiveList(const void* vertices, u32 vertexCount, const void* indexList, u32 primitiveCount, E_VERTEX_TYPE vType, scene::E_PRIMITIVE_TYPE pType, E_INDEX_TYPE iType) |
648 | { | 648 | { |
649 | if ((iType==EIT_16BIT) && (vertexCount>65536)) | 649 | if ((iType==EIT_16BIT) && (vertexCount>65536)) |
650 | os::Printer::log("Too many vertices for 16bit index type, render artifacts may occur."); | 650 | os::Printer::log("Too many vertices for 16bit index type, render artifacts may occur."); |
651 | PrimitivesDrawn += primitiveCount; | 651 | PrimitivesDrawn += primitiveCount; |
652 | } | 652 | } |
653 | 653 | ||
654 | 654 | ||
655 | //! draws a vertex primitive list in 2d | 655 | //! draws a vertex primitive list in 2d |
656 | void CNullDriver::draw2DVertexPrimitiveList(const void* vertices, u32 vertexCount, const void* indexList, u32 primitiveCount, E_VERTEX_TYPE vType, scene::E_PRIMITIVE_TYPE pType, E_INDEX_TYPE iType) | 656 | void CNullDriver::draw2DVertexPrimitiveList(const void* vertices, u32 vertexCount, const void* indexList, u32 primitiveCount, E_VERTEX_TYPE vType, scene::E_PRIMITIVE_TYPE pType, E_INDEX_TYPE iType) |
657 | { | 657 | { |
658 | if ((iType==EIT_16BIT) && (vertexCount>65536)) | 658 | if ((iType==EIT_16BIT) && (vertexCount>65536)) |
659 | os::Printer::log("Too many vertices for 16bit index type, render artifacts may occur."); | 659 | os::Printer::log("Too many vertices for 16bit index type, render artifacts may occur."); |
660 | PrimitivesDrawn += primitiveCount; | 660 | PrimitivesDrawn += primitiveCount; |
661 | } | 661 | } |
662 | 662 | ||
663 | 663 | ||
664 | //! Draws a 3d line. | 664 | //! Draws a 3d line. |
665 | void CNullDriver::draw3DLine(const core::vector3df& start, | 665 | void CNullDriver::draw3DLine(const core::vector3df& start, |
666 | const core::vector3df& end, SColor color) | 666 | const core::vector3df& end, SColor color) |
667 | { | 667 | { |
668 | } | 668 | } |
669 | 669 | ||
670 | 670 | ||
671 | //! Draws a 3d triangle. | 671 | //! Draws a 3d triangle. |
672 | void CNullDriver::draw3DTriangle(const core::triangle3df& triangle, SColor color) | 672 | void CNullDriver::draw3DTriangle(const core::triangle3df& triangle, SColor color) |
673 | { | 673 | { |
674 | S3DVertex vertices[3]; | 674 | S3DVertex vertices[3]; |
675 | vertices[0].Pos=triangle.pointA; | 675 | vertices[0].Pos=triangle.pointA; |
676 | vertices[0].Color=color; | 676 | vertices[0].Color=color; |
677 | vertices[0].Normal=triangle.getNormal().normalize(); | 677 | vertices[0].Normal=triangle.getNormal().normalize(); |
678 | vertices[0].TCoords.set(0.f,0.f); | 678 | vertices[0].TCoords.set(0.f,0.f); |
679 | vertices[1].Pos=triangle.pointB; | 679 | vertices[1].Pos=triangle.pointB; |
680 | vertices[1].Color=color; | 680 | vertices[1].Color=color; |
681 | vertices[1].Normal=vertices[0].Normal; | 681 | vertices[1].Normal=vertices[0].Normal; |
682 | vertices[1].TCoords.set(0.5f,1.f); | 682 | vertices[1].TCoords.set(0.5f,1.f); |
683 | vertices[2].Pos=triangle.pointC; | 683 | vertices[2].Pos=triangle.pointC; |
684 | vertices[2].Color=color; | 684 | vertices[2].Color=color; |
685 | vertices[2].Normal=vertices[0].Normal; | 685 | vertices[2].Normal=vertices[0].Normal; |
686 | vertices[2].TCoords.set(1.f,0.f); | 686 | vertices[2].TCoords.set(1.f,0.f); |
687 | const u16 indexList[] = {0,1,2}; | 687 | const u16 indexList[] = {0,1,2}; |
688 | drawVertexPrimitiveList(vertices, 3, indexList, 1, EVT_STANDARD, scene::EPT_TRIANGLES, EIT_16BIT); | 688 | drawVertexPrimitiveList(vertices, 3, indexList, 1, EVT_STANDARD, scene::EPT_TRIANGLES, EIT_16BIT); |
689 | } | 689 | } |
690 | 690 | ||
691 | 691 | ||
692 | //! Draws a 3d axis aligned box. | 692 | //! Draws a 3d axis aligned box. |
693 | void CNullDriver::draw3DBox(const core::aabbox3d<f32>& box, SColor color) | 693 | void CNullDriver::draw3DBox(const core::aabbox3d<f32>& box, SColor color) |
694 | { | 694 | { |
695 | core::vector3df edges[8]; | 695 | core::vector3df edges[8]; |
696 | box.getEdges(edges); | 696 | box.getEdges(edges); |
697 | 697 | ||
698 | // TODO: optimize into one big drawIndexPrimitive call. | 698 | // TODO: optimize into one big drawIndexPrimitive call. |
699 | 699 | ||
700 | draw3DLine(edges[5], edges[1], color); | 700 | draw3DLine(edges[5], edges[1], color); |
701 | draw3DLine(edges[1], edges[3], color); | 701 | draw3DLine(edges[1], edges[3], color); |
702 | draw3DLine(edges[3], edges[7], color); | 702 | draw3DLine(edges[3], edges[7], color); |
703 | draw3DLine(edges[7], edges[5], color); | 703 | draw3DLine(edges[7], edges[5], color); |
704 | draw3DLine(edges[0], edges[2], color); | 704 | draw3DLine(edges[0], edges[2], color); |
705 | draw3DLine(edges[2], edges[6], color); | 705 | draw3DLine(edges[2], edges[6], color); |
706 | draw3DLine(edges[6], edges[4], color); | 706 | draw3DLine(edges[6], edges[4], color); |
707 | draw3DLine(edges[4], edges[0], color); | 707 | draw3DLine(edges[4], edges[0], color); |
708 | draw3DLine(edges[1], edges[0], color); | 708 | draw3DLine(edges[1], edges[0], color); |
709 | draw3DLine(edges[3], edges[2], color); | 709 | draw3DLine(edges[3], edges[2], color); |
710 | draw3DLine(edges[7], edges[6], color); | 710 | draw3DLine(edges[7], edges[6], color); |
711 | draw3DLine(edges[5], edges[4], color); | 711 | draw3DLine(edges[5], edges[4], color); |
712 | } | 712 | } |
713 | 713 | ||
714 | 714 | ||
715 | 715 | ||
716 | //! draws an 2d image | 716 | //! draws an 2d image |
717 | void CNullDriver::draw2DImage(const video::ITexture* texture, const core::position2d<s32>& destPos) | 717 | void CNullDriver::draw2DImage(const video::ITexture* texture, const core::position2d<s32>& destPos) |
718 | { | 718 | { |
719 | if (!texture) | 719 | if (!texture) |
720 | return; | 720 | return; |
721 | 721 | ||
722 | draw2DImage(texture,destPos, core::rect<s32>(core::position2d<s32>(0,0), | 722 | draw2DImage(texture,destPos, core::rect<s32>(core::position2d<s32>(0,0), |
723 | core::dimension2di(texture->getOriginalSize()))); | 723 | core::dimension2di(texture->getOriginalSize()))); |
724 | } | 724 | } |
725 | 725 | ||
726 | 726 | ||
727 | 727 | ||
728 | //! draws a set of 2d images, using a color and the alpha channel of the | 728 | //! draws a set of 2d images, using a color and the alpha channel of the |
729 | //! texture if desired. The images are drawn beginning at pos and concatenated | 729 | //! texture if desired. The images are drawn beginning at pos and concatenated |
730 | //! in one line. All drawings are clipped against clipRect (if != 0). | 730 | //! in one line. All drawings are clipped against clipRect (if != 0). |
731 | //! The subtextures are defined by the array of sourceRects and are chosen | 731 | //! The subtextures are defined by the array of sourceRects and are chosen |
732 | //! by the indices given. | 732 | //! by the indices given. |
733 | void CNullDriver::draw2DImageBatch(const video::ITexture* texture, | 733 | void CNullDriver::draw2DImageBatch(const video::ITexture* texture, |
734 | const core::position2d<s32>& pos, | 734 | const core::position2d<s32>& pos, |
735 | const core::array<core::rect<s32> >& sourceRects, | 735 | const core::array<core::rect<s32> >& sourceRects, |
736 | const core::array<s32>& indices, | 736 | const core::array<s32>& indices, |
737 | s32 kerningWidth, | 737 | s32 kerningWidth, |
738 | const core::rect<s32>* clipRect, SColor color, | 738 | const core::rect<s32>* clipRect, SColor color, |
739 | bool useAlphaChannelOfTexture) | 739 | bool useAlphaChannelOfTexture) |
740 | { | 740 | { |
741 | core::position2d<s32> target(pos); | 741 | core::position2d<s32> target(pos); |
742 | 742 | ||
743 | for (u32 i=0; i<indices.size(); ++i) | 743 | for (u32 i=0; i<indices.size(); ++i) |
744 | { | 744 | { |
745 | draw2DImage(texture, target, sourceRects[indices[i]], | 745 | draw2DImage(texture, target, sourceRects[indices[i]], |
746 | clipRect, color, useAlphaChannelOfTexture); | 746 | clipRect, color, useAlphaChannelOfTexture); |
747 | target.X += sourceRects[indices[i]].getWidth(); | 747 | target.X += sourceRects[indices[i]].getWidth(); |
748 | target.X += kerningWidth; | 748 | target.X += kerningWidth; |
749 | } | 749 | } |
750 | } | 750 | } |
751 | 751 | ||
752 | //! draws a set of 2d images, using a color and the alpha channel of the | 752 | //! draws a set of 2d images, using a color and the alpha channel of the |
753 | //! texture if desired. | 753 | //! texture if desired. |
754 | void CNullDriver::draw2DImageBatch(const video::ITexture* texture, | 754 | void CNullDriver::draw2DImageBatch(const video::ITexture* texture, |
755 | const core::array<core::position2d<s32> >& positions, | 755 | const core::array<core::position2d<s32> >& positions, |
756 | const core::array<core::rect<s32> >& sourceRects, | 756 | const core::array<core::rect<s32> >& sourceRects, |
757 | const core::rect<s32>* clipRect, | 757 | const core::rect<s32>* clipRect, |
758 | SColor color, | 758 | SColor color, |
759 | bool useAlphaChannelOfTexture) | 759 | bool useAlphaChannelOfTexture) |
760 | { | 760 | { |
761 | const irr::u32 drawCount = core::min_<u32>(positions.size(), sourceRects.size()); | 761 | const irr::u32 drawCount = core::min_<u32>(positions.size(), sourceRects.size()); |
762 | 762 | ||
763 | for (u32 i=0; i<drawCount; ++i) | 763 | for (u32 i=0; i<drawCount; ++i) |
764 | { | 764 | { |
765 | draw2DImage(texture, positions[i], sourceRects[i], | 765 | draw2DImage(texture, positions[i], sourceRects[i], |
766 | clipRect, color, useAlphaChannelOfTexture); | 766 | clipRect, color, useAlphaChannelOfTexture); |
767 | } | 767 | } |
768 | } | 768 | } |
769 | 769 | ||
770 | 770 | ||
771 | //! Draws a part of the texture into the rectangle. | 771 | //! Draws a part of the texture into the rectangle. |
772 | void CNullDriver::draw2DImage(const video::ITexture* texture, const core::rect<s32>& destRect, | 772 | void CNullDriver::draw2DImage(const video::ITexture* texture, const core::rect<s32>& destRect, |
773 | const core::rect<s32>& sourceRect, const core::rect<s32>* clipRect, | 773 | const core::rect<s32>& sourceRect, const core::rect<s32>* clipRect, |
774 | const video::SColor* const colors, bool useAlphaChannelOfTexture) | 774 | const video::SColor* const colors, bool useAlphaChannelOfTexture) |
775 | { | 775 | { |
776 | if (destRect.isValid()) | 776 | if (destRect.isValid()) |
777 | draw2DImage(texture, core::position2d<s32>(destRect.UpperLeftCorner), | 777 | draw2DImage(texture, core::position2d<s32>(destRect.UpperLeftCorner), |
778 | sourceRect, clipRect, colors?colors[0]:video::SColor(0xffffffff), | 778 | sourceRect, clipRect, colors?colors[0]:video::SColor(0xffffffff), |
779 | useAlphaChannelOfTexture); | 779 | useAlphaChannelOfTexture); |
780 | } | 780 | } |
781 | 781 | ||
782 | 782 | ||
783 | //! Draws a 2d image, using a color (if color is other then Color(255,255,255,255)) and the alpha channel of the texture if wanted. | 783 | //! Draws a 2d image, using a color (if color is other then Color(255,255,255,255)) and the alpha channel of the texture if wanted. |
784 | void CNullDriver::draw2DImage(const video::ITexture* texture, const core::position2d<s32>& destPos, | 784 | void CNullDriver::draw2DImage(const video::ITexture* texture, const core::position2d<s32>& destPos, |
785 | const core::rect<s32>& sourceRect, | 785 | const core::rect<s32>& sourceRect, |
786 | const core::rect<s32>* clipRect, SColor color, | 786 | const core::rect<s32>* clipRect, SColor color, |
787 | bool useAlphaChannelOfTexture) | 787 | bool useAlphaChannelOfTexture) |
788 | { | 788 | { |
789 | } | 789 | } |
790 | 790 | ||
791 | 791 | ||
792 | //! Draws the outline of a 2d rectangle | 792 | //! Draws the outline of a 2d rectangle |
793 | void CNullDriver::draw2DRectangleOutline(const core::recti& pos, SColor color) | 793 | void CNullDriver::draw2DRectangleOutline(const core::recti& pos, SColor color) |
794 | { | 794 | { |
795 | draw2DLine(pos.UpperLeftCorner, core::position2di(pos.LowerRightCorner.X, pos.UpperLeftCorner.Y), color); | 795 | draw2DLine(pos.UpperLeftCorner, core::position2di(pos.LowerRightCorner.X, pos.UpperLeftCorner.Y), color); |
796 | draw2DLine(core::position2di(pos.LowerRightCorner.X, pos.UpperLeftCorner.Y), pos.LowerRightCorner, color); | 796 | draw2DLine(core::position2di(pos.LowerRightCorner.X, pos.UpperLeftCorner.Y), pos.LowerRightCorner, color); |
797 | draw2DLine(pos.LowerRightCorner, core::position2di(pos.UpperLeftCorner.X, pos.LowerRightCorner.Y), color); | 797 | draw2DLine(pos.LowerRightCorner, core::position2di(pos.UpperLeftCorner.X, pos.LowerRightCorner.Y), color); |
798 | draw2DLine(core::position2di(pos.UpperLeftCorner.X, pos.LowerRightCorner.Y), pos.UpperLeftCorner, color); | 798 | draw2DLine(core::position2di(pos.UpperLeftCorner.X, pos.LowerRightCorner.Y), pos.UpperLeftCorner, color); |
799 | } | 799 | } |
800 | 800 | ||
801 | 801 | ||
802 | //! Draw a 2d rectangle | 802 | //! Draw a 2d rectangle |
803 | void CNullDriver::draw2DRectangle(SColor color, const core::rect<s32>& pos, const core::rect<s32>* clip) | 803 | void CNullDriver::draw2DRectangle(SColor color, const core::rect<s32>& pos, const core::rect<s32>* clip) |
804 | { | 804 | { |
805 | draw2DRectangle(pos, color, color, color, color, clip); | 805 | draw2DRectangle(pos, color, color, color, color, clip); |
806 | } | 806 | } |
807 | 807 | ||
808 | 808 | ||
809 | 809 | ||
810 | //! Draws a 2d rectangle with a gradient. | 810 | //! Draws a 2d rectangle with a gradient. |
811 | void CNullDriver::draw2DRectangle(const core::rect<s32>& pos, | 811 | void CNullDriver::draw2DRectangle(const core::rect<s32>& pos, |
812 | SColor colorLeftUp, SColor colorRightUp, SColor colorLeftDown, SColor colorRightDown, | 812 | SColor colorLeftUp, SColor colorRightUp, SColor colorLeftDown, SColor colorRightDown, |
813 | const core::rect<s32>* clip) | 813 | const core::rect<s32>* clip) |
814 | { | 814 | { |
815 | } | 815 | } |
816 | 816 | ||
817 | 817 | ||
818 | 818 | ||
819 | //! Draws a 2d line. | 819 | //! Draws a 2d line. |
820 | void CNullDriver::draw2DLine(const core::position2d<s32>& start, | 820 | void CNullDriver::draw2DLine(const core::position2d<s32>& start, |
821 | const core::position2d<s32>& end, SColor color) | 821 | const core::position2d<s32>& end, SColor color) |
822 | { | 822 | { |
823 | } | 823 | } |
824 | 824 | ||
825 | //! Draws a pixel | 825 | //! Draws a pixel |
826 | void CNullDriver::drawPixel(u32 x, u32 y, const SColor & color) | 826 | void CNullDriver::drawPixel(u32 x, u32 y, const SColor & color) |
827 | { | 827 | { |
828 | } | 828 | } |
829 | 829 | ||
830 | 830 | ||
831 | //! Draws a non filled concyclic regular 2d polyon. | 831 | //! Draws a non filled concyclic regular 2d polyon. |
832 | void CNullDriver::draw2DPolygon(core::position2d<s32> center, | 832 | void CNullDriver::draw2DPolygon(core::position2d<s32> center, |
833 | f32 radius, video::SColor color, s32 count) | 833 | f32 radius, video::SColor color, s32 count) |
834 | { | 834 | { |
835 | if (count < 2) | 835 | if (count < 2) |
836 | return; | 836 | return; |
837 | 837 | ||
838 | core::position2d<s32> first; | 838 | core::position2d<s32> first; |
839 | core::position2d<s32> a,b; | 839 | core::position2d<s32> a,b; |
840 | 840 | ||
841 | for (s32 j=0; j<count; ++j) | 841 | for (s32 j=0; j<count; ++j) |
842 | { | 842 | { |
843 | b = a; | 843 | b = a; |
844 | 844 | ||
845 | f32 p = j / (f32)count * (core::PI*2); | 845 | f32 p = j / (f32)count * (core::PI*2); |
846 | a = center + core::position2d<s32>((s32)(sin(p)*radius), (s32)(cos(p)*radius)); | 846 | a = center + core::position2d<s32>((s32)(sin(p)*radius), (s32)(cos(p)*radius)); |
847 | 847 | ||
848 | if (j==0) | 848 | if (j==0) |
849 | first = a; | 849 | first = a; |
850 | else | 850 | else |
851 | draw2DLine(a, b, color); | 851 | draw2DLine(a, b, color); |
852 | } | 852 | } |
853 | 853 | ||
854 | draw2DLine(a, first, color); | 854 | draw2DLine(a, first, color); |
855 | } | 855 | } |
856 | 856 | ||
857 | 857 | ||
858 | //! returns color format | 858 | //! returns color format |
859 | ECOLOR_FORMAT CNullDriver::getColorFormat() const | 859 | ECOLOR_FORMAT CNullDriver::getColorFormat() const |
860 | { | 860 | { |
861 | return ECF_R5G6B5; | 861 | return ECF_R5G6B5; |
862 | } | 862 | } |
863 | 863 | ||
864 | 864 | ||
865 | //! returns screen size | 865 | //! returns screen size |
866 | const core::dimension2d<u32>& CNullDriver::getScreenSize() const | 866 | const core::dimension2d<u32>& CNullDriver::getScreenSize() const |
867 | { | 867 | { |
868 | return ScreenSize; | 868 | return ScreenSize; |
869 | } | 869 | } |
870 | 870 | ||
871 | 871 | ||
872 | //! returns the current render target size, | 872 | //! returns the current render target size, |
873 | //! or the screen size if render targets are not implemented | 873 | //! or the screen size if render targets are not implemented |
874 | const core::dimension2d<u32>& CNullDriver::getCurrentRenderTargetSize() const | 874 | const core::dimension2d<u32>& CNullDriver::getCurrentRenderTargetSize() const |
875 | { | 875 | { |
876 | return ScreenSize; | 876 | return ScreenSize; |
877 | } | 877 | } |
878 | 878 | ||
879 | 879 | ||
880 | // returns current frames per second value | 880 | // returns current frames per second value |
881 | s32 CNullDriver::getFPS() const | 881 | s32 CNullDriver::getFPS() const |
882 | { | 882 | { |
883 | return FPSCounter.getFPS(); | 883 | return FPSCounter.getFPS(); |
884 | } | 884 | } |
885 | 885 | ||
886 | 886 | ||
887 | 887 | ||
888 | //! returns amount of primitives (mostly triangles) were drawn in the last frame. | 888 | //! returns amount of primitives (mostly triangles) were drawn in the last frame. |
889 | //! very useful method for statistics. | 889 | //! very useful method for statistics. |
890 | u32 CNullDriver::getPrimitiveCountDrawn( u32 param ) const | 890 | u32 CNullDriver::getPrimitiveCountDrawn( u32 param ) const |
891 | { | 891 | { |
892 | return (0 == param) ? FPSCounter.getPrimitive() : (1 == param) ? FPSCounter.getPrimitiveAverage() : FPSCounter.getPrimitiveTotal(); | 892 | return (0 == param) ? FPSCounter.getPrimitive() : (1 == param) ? FPSCounter.getPrimitiveAverage() : FPSCounter.getPrimitiveTotal(); |
893 | } | 893 | } |
894 | 894 | ||
895 | 895 | ||
896 | 896 | ||
897 | //! Sets the dynamic ambient light color. The default color is | 897 | //! Sets the dynamic ambient light color. The default color is |
898 | //! (0,0,0,0) which means it is dark. | 898 | //! (0,0,0,0) which means it is dark. |
899 | //! \param color: New color of the ambient light. | 899 | //! \param color: New color of the ambient light. |
900 | void CNullDriver::setAmbientLight(const SColorf& color) | 900 | void CNullDriver::setAmbientLight(const SColorf& color) |
901 | { | 901 | { |
902 | } | 902 | } |
903 | 903 | ||
904 | 904 | ||
905 | 905 | ||
906 | //! \return Returns the name of the video driver. Example: In case of the DIRECT3D8 | 906 | //! \return Returns the name of the video driver. Example: In case of the DIRECT3D8 |
907 | //! driver, it would return "Direct3D8". | 907 | //! driver, it would return "Direct3D8". |
908 | 908 | ||
909 | const wchar_t* CNullDriver::getName() const | 909 | const wchar_t* CNullDriver::getName() const |
910 | { | 910 | { |
911 | return L"Irrlicht NullDevice"; | 911 | return L"Irrlicht NullDevice"; |
912 | } | 912 | } |
913 | 913 | ||
914 | 914 | ||
915 | 915 | ||
916 | //! Draws a shadow volume into the stencil buffer. To draw a stencil shadow, do | 916 | //! Draws a shadow volume into the stencil buffer. To draw a stencil shadow, do |
917 | //! this: Frist, draw all geometry. Then use this method, to draw the shadow | 917 | //! this: Frist, draw all geometry. Then use this method, to draw the shadow |
918 | //! volume. Then, use IVideoDriver::drawStencilShadow() to visualize the shadow. | 918 | //! volume. Then, use IVideoDriver::drawStencilShadow() to visualize the shadow. |
919 | void CNullDriver::drawStencilShadowVolume(const core::array<core::vector3df>& triangles, bool zfail, u32 debugDataVisible) | 919 | void CNullDriver::drawStencilShadowVolume(const core::array<core::vector3df>& triangles, bool zfail, u32 debugDataVisible) |
920 | { | 920 | { |
921 | } | 921 | } |
922 | 922 | ||
923 | 923 | ||
924 | //! Fills the stencil shadow with color. After the shadow volume has been drawn | 924 | //! Fills the stencil shadow with color. After the shadow volume has been drawn |
925 | //! into the stencil buffer using IVideoDriver::drawStencilShadowVolume(), use this | 925 | //! into the stencil buffer using IVideoDriver::drawStencilShadowVolume(), use this |
926 | //! to draw the color of the shadow. | 926 | //! to draw the color of the shadow. |
927 | void CNullDriver::drawStencilShadow(bool clearStencilBuffer, | 927 | void CNullDriver::drawStencilShadow(bool clearStencilBuffer, |
928 | video::SColor leftUpEdge, video::SColor rightUpEdge, | 928 | video::SColor leftUpEdge, video::SColor rightUpEdge, |
929 | video::SColor leftDownEdge, video::SColor rightDownEdge) | 929 | video::SColor leftDownEdge, video::SColor rightDownEdge) |
930 | { | 930 | { |
931 | } | 931 | } |
932 | 932 | ||
933 | 933 | ||
934 | //! deletes all dynamic lights there are | 934 | //! deletes all dynamic lights there are |
935 | void CNullDriver::deleteAllDynamicLights() | 935 | void CNullDriver::deleteAllDynamicLights() |
936 | { | 936 | { |
937 | Lights.set_used(0); | 937 | Lights.set_used(0); |
938 | } | 938 | } |
939 | 939 | ||
940 | 940 | ||
941 | //! adds a dynamic light | 941 | //! adds a dynamic light |
942 | s32 CNullDriver::addDynamicLight(const SLight& light) | 942 | s32 CNullDriver::addDynamicLight(const SLight& light) |
943 | { | 943 | { |
944 | Lights.push_back(light); | 944 | Lights.push_back(light); |
945 | return Lights.size() - 1; | 945 | return Lights.size() - 1; |
946 | } | 946 | } |
947 | 947 | ||
948 | //! Turns a dynamic light on or off | 948 | //! Turns a dynamic light on or off |
949 | //! \param lightIndex: the index returned by addDynamicLight | 949 | //! \param lightIndex: the index returned by addDynamicLight |
950 | //! \param turnOn: true to turn the light on, false to turn it off | 950 | //! \param turnOn: true to turn the light on, false to turn it off |
951 | void CNullDriver::turnLightOn(s32 lightIndex, bool turnOn) | 951 | void CNullDriver::turnLightOn(s32 lightIndex, bool turnOn) |
952 | { | 952 | { |
953 | // Do nothing | 953 | // Do nothing |
954 | } | 954 | } |
955 | 955 | ||
956 | 956 | ||
957 | //! returns the maximal amount of dynamic lights the device can handle | 957 | //! returns the maximal amount of dynamic lights the device can handle |
958 | u32 CNullDriver::getMaximalDynamicLightAmount() const | 958 | u32 CNullDriver::getMaximalDynamicLightAmount() const |
959 | { | 959 | { |
960 | return 0; | 960 | return 0; |
961 | } | 961 | } |
962 | 962 | ||
963 | 963 | ||
964 | //! Returns current amount of dynamic lights set | 964 | //! Returns current amount of dynamic lights set |
965 | //! \return Current amount of dynamic lights set | 965 | //! \return Current amount of dynamic lights set |
966 | u32 CNullDriver::getDynamicLightCount() const | 966 | u32 CNullDriver::getDynamicLightCount() const |
967 | { | 967 | { |
968 | return Lights.size(); | 968 | return Lights.size(); |
969 | } | 969 | } |
970 | 970 | ||
971 | 971 | ||
972 | //! Returns light data which was previously set by IVideoDriver::addDynamicLight(). | 972 | //! Returns light data which was previously set by IVideoDriver::addDynamicLight(). |
973 | //! \param idx: Zero based index of the light. Must be greater than 0 and smaller | 973 | //! \param idx: Zero based index of the light. Must be greater than 0 and smaller |
974 | //! than IVideoDriver()::getDynamicLightCount. | 974 | //! than IVideoDriver()::getDynamicLightCount. |
975 | //! \return Light data. | 975 | //! \return Light data. |
976 | const SLight& CNullDriver::getDynamicLight(u32 idx) const | 976 | const SLight& CNullDriver::getDynamicLight(u32 idx) const |
977 | { | 977 | { |
978 | if ( idx < Lights.size() ) | 978 | if ( idx < Lights.size() ) |
979 | return Lights[idx]; | 979 | return Lights[idx]; |
980 | else | 980 | else |
981 | return *((SLight*)0); | 981 | return *((SLight*)0); |
982 | } | 982 | } |
983 | 983 | ||
984 | 984 | ||
985 | //! Creates a boolean alpha channel of the texture based of an color key. | 985 | //! Creates a boolean alpha channel of the texture based of an color key. |
986 | void CNullDriver::makeColorKeyTexture(video::ITexture* texture, | 986 | void CNullDriver::makeColorKeyTexture(video::ITexture* texture, |
987 | video::SColor color, | 987 | video::SColor color, |
988 | bool zeroTexels) const | 988 | bool zeroTexels) const |
989 | { | 989 | { |
990 | if (!texture) | 990 | if (!texture) |
991 | return; | 991 | return; |
992 | 992 | ||
993 | if (texture->getColorFormat() != ECF_A1R5G5B5 && | 993 | if (texture->getColorFormat() != ECF_A1R5G5B5 && |
994 | texture->getColorFormat() != ECF_A8R8G8B8 ) | 994 | texture->getColorFormat() != ECF_A8R8G8B8 ) |
995 | { | 995 | { |
996 | os::Printer::log("Error: Unsupported texture color format for making color key channel.", ELL_ERROR); | 996 | os::Printer::log("Error: Unsupported texture color format for making color key channel.", ELL_ERROR); |
997 | return; | 997 | return; |
998 | } | 998 | } |
999 | 999 | ||
1000 | if (texture->getColorFormat() == ECF_A1R5G5B5) | 1000 | if (texture->getColorFormat() == ECF_A1R5G5B5) |
1001 | { | 1001 | { |
1002 | u16 *p = (u16*)texture->lock(); | 1002 | u16 *p = (u16*)texture->lock(); |
1003 | 1003 | ||
1004 | if (!p) | 1004 | if (!p) |
1005 | { | 1005 | { |
1006 | os::Printer::log("Could not lock texture for making color key channel.", ELL_ERROR); | 1006 | os::Printer::log("Could not lock texture for making color key channel.", ELL_ERROR); |
1007 | return; | 1007 | return; |
1008 | } | 1008 | } |
1009 | 1009 | ||
1010 | const core::dimension2d<u32> dim = texture->getSize(); | 1010 | const core::dimension2d<u32> dim = texture->getSize(); |
1011 | const u32 pitch = texture->getPitch() / 2; | 1011 | const u32 pitch = texture->getPitch() / 2; |
1012 | 1012 | ||
1013 | // color with alpha disabled (i.e. fully transparent) | 1013 | // color with alpha disabled (i.e. fully transparent) |
1014 | const u16 refZeroAlpha = (0x7fff & color.toA1R5G5B5()); | 1014 | const u16 refZeroAlpha = (0x7fff & color.toA1R5G5B5()); |
1015 | 1015 | ||
1016 | const u32 pixels = pitch * dim.Height; | 1016 | const u32 pixels = pitch * dim.Height; |
1017 | 1017 | ||
1018 | for (u32 pixel = 0; pixel < pixels; ++ pixel) | 1018 | for (u32 pixel = 0; pixel < pixels; ++ pixel) |
1019 | { | 1019 | { |
1020 | // If the color matches the reference color, ignoring alphas, | 1020 | // If the color matches the reference color, ignoring alphas, |
1021 | // set the alpha to zero. | 1021 | // set the alpha to zero. |
1022 | if(((*p) & 0x7fff) == refZeroAlpha) | 1022 | if(((*p) & 0x7fff) == refZeroAlpha) |
1023 | { | 1023 | { |
1024 | if(zeroTexels) | 1024 | if(zeroTexels) |
1025 | (*p) = 0; | 1025 | (*p) = 0; |
1026 | else | 1026 | else |
1027 | (*p) = refZeroAlpha; | 1027 | (*p) = refZeroAlpha; |
1028 | } | 1028 | } |
1029 | 1029 | ||
1030 | ++p; | 1030 | ++p; |
1031 | } | 1031 | } |
1032 | 1032 | ||
1033 | texture->unlock(); | 1033 | texture->unlock(); |
1034 | } | 1034 | } |
1035 | else | 1035 | else |
1036 | { | 1036 | { |
1037 | u32 *p = (u32*)texture->lock(); | 1037 | u32 *p = (u32*)texture->lock(); |
1038 | 1038 | ||
1039 | if (!p) | 1039 | if (!p) |
1040 | { | 1040 | { |
1041 | os::Printer::log("Could not lock texture for making color key channel.", ELL_ERROR); | 1041 | os::Printer::log("Could not lock texture for making color key channel.", ELL_ERROR); |
1042 | return; | 1042 | return; |
1043 | } | 1043 | } |
1044 | 1044 | ||
1045 | core::dimension2d<u32> dim = texture->getSize(); | 1045 | core::dimension2d<u32> dim = texture->getSize(); |
1046 | u32 pitch = texture->getPitch() / 4; | 1046 | u32 pitch = texture->getPitch() / 4; |
1047 | 1047 | ||
1048 | // color with alpha disabled (fully transparent) | 1048 | // color with alpha disabled (fully transparent) |
1049 | const u32 refZeroAlpha = 0x00ffffff & color.color; | 1049 | const u32 refZeroAlpha = 0x00ffffff & color.color; |
1050 | 1050 | ||
1051 | const u32 pixels = pitch * dim.Height; | 1051 | const u32 pixels = pitch * dim.Height; |
1052 | for (u32 pixel = 0; pixel < pixels; ++ pixel) | 1052 | for (u32 pixel = 0; pixel < pixels; ++ pixel) |
1053 | { | 1053 | { |
1054 | // If the color matches the reference color, ignoring alphas, | 1054 | // If the color matches the reference color, ignoring alphas, |
1055 | // set the alpha to zero. | 1055 | // set the alpha to zero. |
1056 | if(((*p) & 0x00ffffff) == refZeroAlpha) | 1056 | if(((*p) & 0x00ffffff) == refZeroAlpha) |
1057 | { | 1057 | { |
1058 | if(zeroTexels) | 1058 | if(zeroTexels) |
1059 | (*p) = 0; | 1059 | (*p) = 0; |
1060 | else | 1060 | else |
1061 | (*p) = refZeroAlpha; | 1061 | (*p) = refZeroAlpha; |
1062 | } | 1062 | } |
1063 | 1063 | ||
1064 | ++p; | 1064 | ++p; |
1065 | } | 1065 | } |
1066 | 1066 | ||
1067 | texture->unlock(); | 1067 | texture->unlock(); |
1068 | } | 1068 | } |
1069 | texture->regenerateMipMapLevels(); | 1069 | texture->regenerateMipMapLevels(); |
1070 | } | 1070 | } |
1071 | 1071 | ||
1072 | 1072 | ||
1073 | 1073 | ||
1074 | //! Creates an boolean alpha channel of the texture based of an color key position. | 1074 | //! Creates an boolean alpha channel of the texture based of an color key position. |
1075 | void CNullDriver::makeColorKeyTexture(video::ITexture* texture, | 1075 | void CNullDriver::makeColorKeyTexture(video::ITexture* texture, |
1076 | core::position2d<s32> colorKeyPixelPos, | 1076 | core::position2d<s32> colorKeyPixelPos, |
1077 | bool zeroTexels) const | 1077 | bool zeroTexels) const |
1078 | { | 1078 | { |
1079 | if (!texture) | 1079 | if (!texture) |
1080 | return; | 1080 | return; |
1081 | 1081 | ||
1082 | if (texture->getColorFormat() != ECF_A1R5G5B5 && | 1082 | if (texture->getColorFormat() != ECF_A1R5G5B5 && |
1083 | texture->getColorFormat() != ECF_A8R8G8B8 ) | 1083 | texture->getColorFormat() != ECF_A8R8G8B8 ) |
1084 | { | 1084 | { |
1085 | os::Printer::log("Error: Unsupported texture color format for making color key channel.", ELL_ERROR); | 1085 | os::Printer::log("Error: Unsupported texture color format for making color key channel.", ELL_ERROR); |
1086 | return; | 1086 | return; |
1087 | } | 1087 | } |
1088 | 1088 | ||
1089 | SColor colorKey; | 1089 | SColor colorKey; |
1090 | 1090 | ||
1091 | if (texture->getColorFormat() == ECF_A1R5G5B5) | 1091 | if (texture->getColorFormat() == ECF_A1R5G5B5) |
1092 | { | 1092 | { |
1093 | u16 *p = (u16*)texture->lock(ETLM_READ_ONLY); | 1093 | u16 *p = (u16*)texture->lock(ETLM_READ_ONLY); |
1094 | 1094 | ||
1095 | if (!p) | 1095 | if (!p) |
1096 | { | 1096 | { |
1097 | os::Printer::log("Could not lock texture for making color key channel.", ELL_ERROR); | 1097 | os::Printer::log("Could not lock texture for making color key channel.", ELL_ERROR); |
1098 | return; | 1098 | return; |
1099 | } | 1099 | } |
1100 | 1100 | ||
1101 | u32 pitch = texture->getPitch() / 2; | 1101 | u32 pitch = texture->getPitch() / 2; |
1102 | 1102 | ||
1103 | const u16 key16Bit = 0x7fff & p[colorKeyPixelPos.Y*pitch + colorKeyPixelPos.X]; | 1103 | const u16 key16Bit = 0x7fff & p[colorKeyPixelPos.Y*pitch + colorKeyPixelPos.X]; |
1104 | 1104 | ||
1105 | colorKey = video::A1R5G5B5toA8R8G8B8(key16Bit); | 1105 | colorKey = video::A1R5G5B5toA8R8G8B8(key16Bit); |
1106 | } | 1106 | } |
1107 | else | 1107 | else |
1108 | { | 1108 | { |
1109 | u32 *p = (u32*)texture->lock(ETLM_READ_ONLY); | 1109 | u32 *p = (u32*)texture->lock(ETLM_READ_ONLY); |
1110 | 1110 | ||
1111 | if (!p) | 1111 | if (!p) |
1112 | { | 1112 | { |
1113 | os::Printer::log("Could not lock texture for making color key channel.", ELL_ERROR); | 1113 | os::Printer::log("Could not lock texture for making color key channel.", ELL_ERROR); |
1114 | return; | 1114 | return; |
1115 | } | 1115 | } |
1116 | 1116 | ||
1117 | u32 pitch = texture->getPitch() / 4; | 1117 | u32 pitch = texture->getPitch() / 4; |
1118 | colorKey = 0x00ffffff & p[colorKeyPixelPos.Y*pitch + colorKeyPixelPos.X]; | 1118 | colorKey = 0x00ffffff & p[colorKeyPixelPos.Y*pitch + colorKeyPixelPos.X]; |
1119 | } | 1119 | } |
1120 | 1120 | ||
1121 | texture->unlock(); | 1121 | texture->unlock(); |
1122 | makeColorKeyTexture(texture, colorKey, zeroTexels); | 1122 | makeColorKeyTexture(texture, colorKey, zeroTexels); |
1123 | } | 1123 | } |
1124 | 1124 | ||
1125 | 1125 | ||
1126 | 1126 | ||
1127 | //! Creates a normal map from a height map texture. | 1127 | //! Creates a normal map from a height map texture. |
1128 | //! \param amplitude: Constant value by which the height information is multiplied. | 1128 | //! \param amplitude: Constant value by which the height information is multiplied. |
1129 | void CNullDriver::makeNormalMapTexture(video::ITexture* texture, f32 amplitude) const | 1129 | void CNullDriver::makeNormalMapTexture(video::ITexture* texture, f32 amplitude) const |
1130 | { | 1130 | { |
1131 | if (!texture) | 1131 | if (!texture) |
1132 | return; | 1132 | return; |
1133 | 1133 | ||
1134 | if (texture->getColorFormat() != ECF_A1R5G5B5 && | 1134 | if (texture->getColorFormat() != ECF_A1R5G5B5 && |
1135 | texture->getColorFormat() != ECF_A8R8G8B8 ) | 1135 | texture->getColorFormat() != ECF_A8R8G8B8 ) |
1136 | { | 1136 | { |
1137 | os::Printer::log("Error: Unsupported texture color format for making normal map.", ELL_ERROR); | 1137 | os::Printer::log("Error: Unsupported texture color format for making normal map.", ELL_ERROR); |
1138 | return; | 1138 | return; |
1139 | } | 1139 | } |
1140 | 1140 | ||
1141 | core::dimension2d<u32> dim = texture->getSize(); | 1141 | core::dimension2d<u32> dim = texture->getSize(); |
1142 | amplitude = amplitude / 255.0f; | 1142 | amplitude = amplitude / 255.0f; |
1143 | f32 vh = dim.Height / (f32)dim.Width; | 1143 | f32 vh = dim.Height / (f32)dim.Width; |
1144 | f32 hh = dim.Width / (f32)dim.Height; | 1144 | f32 hh = dim.Width / (f32)dim.Height; |
1145 | 1145 | ||
1146 | if (texture->getColorFormat() == ECF_A8R8G8B8) | 1146 | if (texture->getColorFormat() == ECF_A8R8G8B8) |
1147 | { | 1147 | { |
1148 | // ECF_A8R8G8B8 version | 1148 | // ECF_A8R8G8B8 version |
1149 | 1149 | ||
1150 | s32 *p = (s32*)texture->lock(); | 1150 | s32 *p = (s32*)texture->lock(); |
1151 | 1151 | ||
1152 | if (!p) | 1152 | if (!p) |
1153 | { | 1153 | { |
1154 | os::Printer::log("Could not lock texture for making normal map.", ELL_ERROR); | 1154 | os::Printer::log("Could not lock texture for making normal map.", ELL_ERROR); |
1155 | return; | 1155 | return; |
1156 | } | 1156 | } |
1157 | 1157 | ||
1158 | // copy texture | 1158 | // copy texture |
1159 | 1159 | ||
1160 | u32 pitch = texture->getPitch() / 4; | 1160 | u32 pitch = texture->getPitch() / 4; |
1161 | 1161 | ||
1162 | s32* in = new s32[dim.Height * pitch]; | 1162 | s32* in = new s32[dim.Height * pitch]; |
1163 | memcpy(in, p, dim.Height * pitch * 4); | 1163 | memcpy(in, p, dim.Height * pitch * 4); |
1164 | 1164 | ||
1165 | for (s32 x=0; x < s32(pitch); ++x) | 1165 | for (s32 x=0; x < s32(pitch); ++x) |
1166 | for (s32 y=0; y < s32(dim.Height); ++y) | 1166 | for (s32 y=0; y < s32(dim.Height); ++y) |
1167 | { | 1167 | { |
1168 | // TODO: this could be optimized really a lot | 1168 | // TODO: this could be optimized really a lot |
1169 | 1169 | ||
1170 | core::vector3df h1((x-1)*hh, nml32(x-1, y, pitch, dim.Height, in)*amplitude, y*vh); | 1170 | core::vector3df h1((x-1)*hh, nml32(x-1, y, pitch, dim.Height, in)*amplitude, y*vh); |
1171 | core::vector3df h2((x+1)*hh, nml32(x+1, y, pitch, dim.Height, in)*amplitude, y*vh); | 1171 | core::vector3df h2((x+1)*hh, nml32(x+1, y, pitch, dim.Height, in)*amplitude, y*vh); |
1172 | //core::vector3df v1(x*hh, nml32(x, y-1, pitch, dim.Height, in)*amplitude, (y-1)*vh); | 1172 | //core::vector3df v1(x*hh, nml32(x, y-1, pitch, dim.Height, in)*amplitude, (y-1)*vh); |
1173 | //core::vector3df v2(x*hh, nml32(x, y+1, pitch, dim.Height, in)*amplitude, (y+1)*vh); | 1173 | //core::vector3df v2(x*hh, nml32(x, y+1, pitch, dim.Height, in)*amplitude, (y+1)*vh); |
1174 | core::vector3df v1(x*hh, nml32(x, y+1, pitch, dim.Height, in)*amplitude, (y-1)*vh); | 1174 | core::vector3df v1(x*hh, nml32(x, y+1, pitch, dim.Height, in)*amplitude, (y-1)*vh); |
1175 | core::vector3df v2(x*hh, nml32(x, y-1, pitch, dim.Height, in)*amplitude, (y+1)*vh); | 1175 | core::vector3df v2(x*hh, nml32(x, y-1, pitch, dim.Height, in)*amplitude, (y+1)*vh); |
1176 | 1176 | ||
1177 | core::vector3df v = v1-v2; | 1177 | core::vector3df v = v1-v2; |
1178 | core::vector3df h = h1-h2; | 1178 | core::vector3df h = h1-h2; |
1179 | 1179 | ||
1180 | core::vector3df n = v.crossProduct(h); | 1180 | core::vector3df n = v.crossProduct(h); |
1181 | n.normalize(); | 1181 | n.normalize(); |
1182 | n *= 0.5f; | 1182 | n *= 0.5f; |
1183 | n += core::vector3df(0.5f,0.5f,0.5f); // now between 0 and 1 | 1183 | n += core::vector3df(0.5f,0.5f,0.5f); // now between 0 and 1 |
1184 | n *= 255.0f; | 1184 | n *= 255.0f; |
1185 | 1185 | ||
1186 | s32 height = (s32)nml32(x, y, pitch, dim.Height, in); | 1186 | s32 height = (s32)nml32(x, y, pitch, dim.Height, in); |
1187 | p[y*pitch + x] = video::SColor( | 1187 | p[y*pitch + x] = video::SColor( |
1188 | height, // store height in alpha | 1188 | height, // store height in alpha |
1189 | (s32)n.X, (s32)n.Z, (s32)n.Y).color; | 1189 | (s32)n.X, (s32)n.Z, (s32)n.Y).color; |
1190 | } | 1190 | } |
1191 | 1191 | ||
1192 | delete [] in; | 1192 | delete [] in; |
1193 | texture->unlock(); | 1193 | texture->unlock(); |
1194 | } | 1194 | } |
1195 | else | 1195 | else |
1196 | { | 1196 | { |
1197 | // ECF_A1R5G5B5 version | 1197 | // ECF_A1R5G5B5 version |
1198 | 1198 | ||
1199 | s16 *p = (s16*)texture->lock(); | 1199 | s16 *p = (s16*)texture->lock(); |
1200 | 1200 | ||
1201 | if (!p) | 1201 | if (!p) |
1202 | { | 1202 | { |
1203 | os::Printer::log("Could not lock texture for making normal map.", ELL_ERROR); | 1203 | os::Printer::log("Could not lock texture for making normal map.", ELL_ERROR); |
1204 | return; | 1204 | return; |
1205 | } | 1205 | } |
1206 | 1206 | ||
1207 | u32 pitch = texture->getPitch() / 2; | 1207 | u32 pitch = texture->getPitch() / 2; |
1208 | 1208 | ||
1209 | // copy texture | 1209 | // copy texture |
1210 | 1210 | ||
1211 | s16* in = new s16[dim.Height * pitch]; | 1211 | s16* in = new s16[dim.Height * pitch]; |
1212 | memcpy(in, p, dim.Height * pitch * 2); | 1212 | memcpy(in, p, dim.Height * pitch * 2); |
1213 | 1213 | ||
1214 | for (s32 x=0; x < s32(pitch); ++x) | 1214 | for (s32 x=0; x < s32(pitch); ++x) |
1215 | for (s32 y=0; y < s32(dim.Height); ++y) | 1215 | for (s32 y=0; y < s32(dim.Height); ++y) |
1216 | { | 1216 | { |
1217 | // TODO: this could be optimized really a lot | 1217 | // TODO: this could be optimized really a lot |
1218 | 1218 | ||
1219 | core::vector3df h1((x-1)*hh, nml16(x-1, y, pitch, dim.Height, in)*amplitude, y*vh); | 1219 | core::vector3df h1((x-1)*hh, nml16(x-1, y, pitch, dim.Height, in)*amplitude, y*vh); |
1220 | core::vector3df h2((x+1)*hh, nml16(x+1, y, pitch, dim.Height, in)*amplitude, y*vh); | 1220 | core::vector3df h2((x+1)*hh, nml16(x+1, y, pitch, dim.Height, in)*amplitude, y*vh); |
1221 | core::vector3df v1(x*hh, nml16(x, y-1, pitch, dim.Height, in)*amplitude, (y-1)*vh); | 1221 | core::vector3df v1(x*hh, nml16(x, y-1, pitch, dim.Height, in)*amplitude, (y-1)*vh); |
1222 | core::vector3df v2(x*hh, nml16(x, y+1, pitch, dim.Height, in)*amplitude, (y+1)*vh); | 1222 | core::vector3df v2(x*hh, nml16(x, y+1, pitch, dim.Height, in)*amplitude, (y+1)*vh); |
1223 | 1223 | ||
1224 | core::vector3df v = v1-v2; | 1224 | core::vector3df v = v1-v2; |
1225 | core::vector3df h = h1-h2; | 1225 | core::vector3df h = h1-h2; |
1226 | 1226 | ||
1227 | core::vector3df n = v.crossProduct(h); | 1227 | core::vector3df n = v.crossProduct(h); |
1228 | n.normalize(); | 1228 | n.normalize(); |
1229 | n *= 0.5f; | 1229 | n *= 0.5f; |
1230 | n += core::vector3df(0.5f,0.5f,0.5f); // now between 0 and 1 | 1230 | n += core::vector3df(0.5f,0.5f,0.5f); // now between 0 and 1 |
1231 | n *= 255.0f; | 1231 | n *= 255.0f; |
1232 | 1232 | ||
1233 | p[y*pitch + x] = video::RGBA16((u32)n.X, (u32)n.Z, (u32)n.Y); | 1233 | p[y*pitch + x] = video::RGBA16((u32)n.X, (u32)n.Z, (u32)n.Y); |
1234 | } | 1234 | } |
1235 | 1235 | ||
1236 | delete [] in; | 1236 | delete [] in; |
1237 | texture->unlock(); | 1237 | texture->unlock(); |
1238 | } | 1238 | } |
1239 | 1239 | ||
1240 | texture->regenerateMipMapLevels(); | 1240 | texture->regenerateMipMapLevels(); |
1241 | } | 1241 | } |
1242 | 1242 | ||
1243 | 1243 | ||
1244 | //! Returns the maximum amount of primitives (mostly vertices) which | 1244 | //! Returns the maximum amount of primitives (mostly vertices) which |
1245 | //! the device is able to render with one drawIndexedTriangleList | 1245 | //! the device is able to render with one drawIndexedTriangleList |
1246 | //! call. | 1246 | //! call. |
1247 | u32 CNullDriver::getMaximalPrimitiveCount() const | 1247 | u32 CNullDriver::getMaximalPrimitiveCount() const |
1248 | { | 1248 | { |
1249 | return 0xFFFFFFFF; | 1249 | return 0xFFFFFFFF; |
1250 | } | 1250 | } |
1251 | 1251 | ||
1252 | 1252 | ||
1253 | //! checks triangle count and print warning if wrong | 1253 | //! checks triangle count and print warning if wrong |
1254 | bool CNullDriver::checkPrimitiveCount(u32 prmCount) const | 1254 | bool CNullDriver::checkPrimitiveCount(u32 prmCount) const |
1255 | { | 1255 | { |
1256 | const u32 m = getMaximalPrimitiveCount(); | 1256 | const u32 m = getMaximalPrimitiveCount(); |
1257 | 1257 | ||
1258 | if (prmCount > m) | 1258 | if (prmCount > m) |
1259 | { | 1259 | { |
1260 | char tmp[1024]; | 1260 | char tmp[1024]; |
1261 | sprintf(tmp,"Could not draw triangles, too many primitives(%u), maxium is %u.", prmCount, m); | 1261 | sprintf(tmp,"Could not draw triangles, too many primitives(%u), maxium is %u.", prmCount, m); |
1262 | os::Printer::log(tmp, ELL_ERROR); | 1262 | os::Printer::log(tmp, ELL_ERROR); |
1263 | return false; | 1263 | return false; |
1264 | } | 1264 | } |
1265 | 1265 | ||
1266 | return true; | 1266 | return true; |
1267 | } | 1267 | } |
1268 | 1268 | ||
1269 | //! Enables or disables a texture creation flag. | 1269 | //! Enables or disables a texture creation flag. |
1270 | void CNullDriver::setTextureCreationFlag(E_TEXTURE_CREATION_FLAG flag, bool enabled) | 1270 | void CNullDriver::setTextureCreationFlag(E_TEXTURE_CREATION_FLAG flag, bool enabled) |
1271 | { | 1271 | { |
1272 | if (enabled && ((flag == ETCF_ALWAYS_16_BIT) || (flag == ETCF_ALWAYS_32_BIT) | 1272 | if (enabled && ((flag == ETCF_ALWAYS_16_BIT) || (flag == ETCF_ALWAYS_32_BIT) |
1273 | || (flag == ETCF_OPTIMIZED_FOR_QUALITY) || (flag == ETCF_OPTIMIZED_FOR_SPEED))) | 1273 | || (flag == ETCF_OPTIMIZED_FOR_QUALITY) || (flag == ETCF_OPTIMIZED_FOR_SPEED))) |
1274 | { | 1274 | { |
1275 | // disable other formats | 1275 | // disable other formats |
1276 | setTextureCreationFlag(ETCF_ALWAYS_16_BIT, false); | 1276 | setTextureCreationFlag(ETCF_ALWAYS_16_BIT, false); |
1277 | setTextureCreationFlag(ETCF_ALWAYS_32_BIT, false); | 1277 | setTextureCreationFlag(ETCF_ALWAYS_32_BIT, false); |
1278 | setTextureCreationFlag(ETCF_OPTIMIZED_FOR_QUALITY, false); | 1278 | setTextureCreationFlag(ETCF_OPTIMIZED_FOR_QUALITY, false); |
1279 | setTextureCreationFlag(ETCF_OPTIMIZED_FOR_SPEED, false); | 1279 | setTextureCreationFlag(ETCF_OPTIMIZED_FOR_SPEED, false); |
1280 | } | 1280 | } |
1281 | 1281 | ||
1282 | // set flag | 1282 | // set flag |
1283 | TextureCreationFlags = (TextureCreationFlags & (~flag)) | | 1283 | TextureCreationFlags = (TextureCreationFlags & (~flag)) | |
1284 | ((((u32)!enabled)-1) & flag); | 1284 | ((((u32)!enabled)-1) & flag); |
1285 | } | 1285 | } |
1286 | 1286 | ||
1287 | 1287 | ||
1288 | //! Returns if a texture creation flag is enabled or disabled. | 1288 | //! Returns if a texture creation flag is enabled or disabled. |
1289 | bool CNullDriver::getTextureCreationFlag(E_TEXTURE_CREATION_FLAG flag) const | 1289 | bool CNullDriver::getTextureCreationFlag(E_TEXTURE_CREATION_FLAG flag) const |
1290 | { | 1290 | { |
1291 | return (TextureCreationFlags & flag)!=0; | 1291 | return (TextureCreationFlags & flag)!=0; |
1292 | } | 1292 | } |
1293 | 1293 | ||
1294 | 1294 | ||
1295 | //! Creates a software image from a file. | 1295 | //! Creates a software image from a file. |
1296 | IImage* CNullDriver::createImageFromFile(const io::path& filename) | 1296 | IImage* CNullDriver::createImageFromFile(const io::path& filename) |
1297 | { | 1297 | { |
1298 | if (!filename.size()) | 1298 | if (!filename.size()) |
1299 | return 0; | 1299 | return 0; |
1300 | 1300 | ||
1301 | IImage* image = 0; | 1301 | IImage* image = 0; |
1302 | io::IReadFile* file = FileSystem->createAndOpenFile(filename); | 1302 | io::IReadFile* file = FileSystem->createAndOpenFile(filename); |
1303 | 1303 | ||
1304 | if (file) | 1304 | if (file) |
1305 | { | 1305 | { |
1306 | image = createImageFromFile(file); | 1306 | image = createImageFromFile(file); |
1307 | file->drop(); | 1307 | file->drop(); |
1308 | } | 1308 | } |
1309 | else | 1309 | else |
1310 | os::Printer::log("Could not open file of image", filename, ELL_WARNING); | 1310 | os::Printer::log("Could not open file of image", filename, ELL_WARNING); |
1311 | 1311 | ||
1312 | return image; | 1312 | return image; |
1313 | } | 1313 | } |
1314 | 1314 | ||
1315 | 1315 | ||
1316 | //! Creates a software image from a file. | 1316 | //! Creates a software image from a file. |
1317 | IImage* CNullDriver::createImageFromFile(io::IReadFile* file) | 1317 | IImage* CNullDriver::createImageFromFile(io::IReadFile* file) |
1318 | { | 1318 | { |
1319 | if (!file) | 1319 | if (!file) |
1320 | return 0; | 1320 | return 0; |
1321 | 1321 | ||
1322 | IImage* image = 0; | 1322 | IImage* image = 0; |
1323 | 1323 | ||
1324 | s32 i; | 1324 | s32 i; |
1325 | 1325 | ||
1326 | // try to load file based on file extension | 1326 | // try to load file based on file extension |
1327 | for (i=SurfaceLoader.size()-1; i>=0; --i) | 1327 | for (i=SurfaceLoader.size()-1; i>=0; --i) |
1328 | { | 1328 | { |
1329 | if (SurfaceLoader[i]->isALoadableFileExtension(file->getFileName())) | 1329 | if (SurfaceLoader[i]->isALoadableFileExtension(file->getFileName())) |
1330 | { | 1330 | { |
1331 | // reset file position which might have changed due to previous loadImage calls | 1331 | // reset file position which might have changed due to previous loadImage calls |
1332 | file->seek(0); | 1332 | file->seek(0); |
1333 | image = SurfaceLoader[i]->loadImage(file); | 1333 | image = SurfaceLoader[i]->loadImage(file); |
1334 | if (image) | 1334 | if (image) |
1335 | return image; | 1335 | return image; |
1336 | } | 1336 | } |
1337 | } | 1337 | } |
1338 | 1338 | ||
1339 | // try to load file based on what is in it | 1339 | // try to load file based on what is in it |
1340 | for (i=SurfaceLoader.size()-1; i>=0; --i) | 1340 | for (i=SurfaceLoader.size()-1; i>=0; --i) |
1341 | { | 1341 | { |
1342 | // dito | 1342 | // dito |
1343 | file->seek(0); | 1343 | file->seek(0); |
1344 | if (SurfaceLoader[i]->isALoadableFileFormat(file)) | 1344 | if (SurfaceLoader[i]->isALoadableFileFormat(file)) |
1345 | { | 1345 | { |
1346 | file->seek(0); | 1346 | file->seek(0); |
1347 | image = SurfaceLoader[i]->loadImage(file); | 1347 | image = SurfaceLoader[i]->loadImage(file); |
1348 | if (image) | 1348 | if (image) |
1349 | return image; | 1349 | return image; |
1350 | } | 1350 | } |
1351 | } | 1351 | } |
1352 | 1352 | ||
1353 | return 0; // failed to load | 1353 | return 0; // failed to load |
1354 | } | 1354 | } |
1355 | 1355 | ||
1356 | 1356 | ||
1357 | //! Writes the provided image to disk file | 1357 | //! Writes the provided image to disk file |
1358 | bool CNullDriver::writeImageToFile(IImage* image, const io::path& filename,u32 param) | 1358 | bool CNullDriver::writeImageToFile(IImage* image, const io::path& filename,u32 param) |
1359 | { | 1359 | { |
1360 | io::IWriteFile* file = FileSystem->createAndWriteFile(filename); | 1360 | io::IWriteFile* file = FileSystem->createAndWriteFile(filename); |
1361 | if(!file) | 1361 | if(!file) |
1362 | return false; | 1362 | return false; |
1363 | 1363 | ||
1364 | bool result = writeImageToFile(image, file, param); | 1364 | bool result = writeImageToFile(image, file, param); |
1365 | file->drop(); | 1365 | file->drop(); |
1366 | 1366 | ||
1367 | return result; | 1367 | return result; |
1368 | } | 1368 | } |
1369 | 1369 | ||
1370 | //! Writes the provided image to a file. | 1370 | //! Writes the provided image to a file. |
1371 | bool CNullDriver::writeImageToFile(IImage* image, io::IWriteFile * file, u32 param) | 1371 | bool CNullDriver::writeImageToFile(IImage* image, io::IWriteFile * file, u32 param) |
1372 | { | 1372 | { |
1373 | if(!file) | 1373 | if(!file) |
1374 | return false; | 1374 | return false; |
1375 | 1375 | ||
1376 | for (s32 i=SurfaceWriter.size()-1; i>=0; --i) | 1376 | for (s32 i=SurfaceWriter.size()-1; i>=0; --i) |
1377 | { | 1377 | { |
1378 | if (SurfaceWriter[i]->isAWriteableFileExtension(file->getFileName())) | 1378 | if (SurfaceWriter[i]->isAWriteableFileExtension(file->getFileName())) |
1379 | { | 1379 | { |
1380 | bool written = SurfaceWriter[i]->writeImage(file, image, param); | 1380 | bool written = SurfaceWriter[i]->writeImage(file, image, param); |
1381 | if (written) | 1381 | if (written) |
1382 | return true; | 1382 | return true; |
1383 | } | 1383 | } |
1384 | } | 1384 | } |
1385 | return false; // failed to write | 1385 | return false; // failed to write |
1386 | } | 1386 | } |
1387 | 1387 | ||
1388 | 1388 | ||
1389 | //! Creates a software image from a byte array. | 1389 | //! Creates a software image from a byte array. |
1390 | IImage* CNullDriver::createImageFromData(ECOLOR_FORMAT format, | 1390 | IImage* CNullDriver::createImageFromData(ECOLOR_FORMAT format, |
1391 | const core::dimension2d<u32>& size, | 1391 | const core::dimension2d<u32>& size, |
1392 | void *data, bool ownForeignMemory, | 1392 | void *data, bool ownForeignMemory, |
1393 | bool deleteMemory) | 1393 | bool deleteMemory) |
1394 | { | 1394 | { |
1395 | if(IImage::isRenderTargetOnlyFormat(format)) | 1395 | if(IImage::isRenderTargetOnlyFormat(format)) |
1396 | { | 1396 | { |
1397 | os::Printer::log("Could not create IImage, format only supported for render target textures.", ELL_WARNING); | 1397 | os::Printer::log("Could not create IImage, format only supported for render target textures.", ELL_WARNING); |
1398 | return 0; | 1398 | return 0; |
1399 | } | 1399 | } |
1400 | 1400 | ||
1401 | return new CImage(format, size, data, ownForeignMemory, deleteMemory); | 1401 | return new CImage(format, size, data, ownForeignMemory, deleteMemory); |
1402 | } | 1402 | } |
1403 | 1403 | ||
1404 | 1404 | ||
1405 | //! Creates an empty software image. | 1405 | //! Creates an empty software image. |
1406 | IImage* CNullDriver::createImage(ECOLOR_FORMAT format, const core::dimension2d<u32>& size) | 1406 | IImage* CNullDriver::createImage(ECOLOR_FORMAT format, const core::dimension2d<u32>& size) |
1407 | { | 1407 | { |
1408 | if(IImage::isRenderTargetOnlyFormat(format)) | 1408 | if(IImage::isRenderTargetOnlyFormat(format)) |
1409 | { | 1409 | { |
1410 | os::Printer::log("Could not create IImage, format only supported for render target textures.", ELL_WARNING); | 1410 | os::Printer::log("Could not create IImage, format only supported for render target textures.", ELL_WARNING); |
1411 | return 0; | 1411 | return 0; |
1412 | } | 1412 | } |
1413 | 1413 | ||
1414 | return new CImage(format, size); | 1414 | return new CImage(format, size); |
1415 | } | 1415 | } |
1416 | 1416 | ||
1417 | 1417 | ||
1418 | //! Creates a software image from another image. | 1418 | //! Creates a software image from another image. |
1419 | IImage* CNullDriver::createImage(ECOLOR_FORMAT format, IImage *imageToCopy) | 1419 | IImage* CNullDriver::createImage(ECOLOR_FORMAT format, IImage *imageToCopy) |
1420 | { | 1420 | { |
1421 | os::Printer::log("Deprecated method, please create an empty image instead and use copyTo().", ELL_WARNING); | 1421 | os::Printer::log("Deprecated method, please create an empty image instead and use copyTo().", ELL_WARNING); |
1422 | if(IImage::isRenderTargetOnlyFormat(format)) | 1422 | if(IImage::isRenderTargetOnlyFormat(format)) |
1423 | { | 1423 | { |
1424 | os::Printer::log("Could not create IImage, format only supported for render target textures.", ELL_WARNING); | 1424 | os::Printer::log("Could not create IImage, format only supported for render target textures.", ELL_WARNING); |
1425 | return 0; | 1425 | return 0; |
1426 | } | 1426 | } |
1427 | 1427 | ||
1428 | CImage* tmp = new CImage(format, imageToCopy->getDimension()); | 1428 | CImage* tmp = new CImage(format, imageToCopy->getDimension()); |
1429 | imageToCopy->copyTo(tmp); | 1429 | imageToCopy->copyTo(tmp); |
1430 | return tmp; | 1430 | return tmp; |
1431 | } | 1431 | } |
1432 | 1432 | ||
1433 | 1433 | ||
1434 | //! Creates a software image from part of another image. | 1434 | //! Creates a software image from part of another image. |
1435 | IImage* CNullDriver::createImage(IImage* imageToCopy, const core::position2d<s32>& pos, const core::dimension2d<u32>& size) | 1435 | IImage* CNullDriver::createImage(IImage* imageToCopy, const core::position2d<s32>& pos, const core::dimension2d<u32>& size) |
1436 | { | 1436 | { |
1437 | os::Printer::log("Deprecated method, please create an empty image instead and use copyTo().", ELL_WARNING); | 1437 | os::Printer::log("Deprecated method, please create an empty image instead and use copyTo().", ELL_WARNING); |
1438 | CImage* tmp = new CImage(imageToCopy->getColorFormat(), imageToCopy->getDimension()); | 1438 | CImage* tmp = new CImage(imageToCopy->getColorFormat(), imageToCopy->getDimension()); |
1439 | imageToCopy->copyTo(tmp, core::position2di(0,0), core::recti(pos,size)); | 1439 | imageToCopy->copyTo(tmp, core::position2di(0,0), core::recti(pos,size)); |
1440 | return tmp; | 1440 | return tmp; |
1441 | } | 1441 | } |
1442 | 1442 | ||
1443 | 1443 | ||
1444 | //! Creates a software image from part of a texture. | 1444 | //! Creates a software image from part of a texture. |
1445 | IImage* CNullDriver::createImage(ITexture* texture, const core::position2d<s32>& pos, const core::dimension2d<u32>& size) | 1445 | IImage* CNullDriver::createImage(ITexture* texture, const core::position2d<s32>& pos, const core::dimension2d<u32>& size) |
1446 | { | 1446 | { |
1447 | if ((pos==core::position2di(0,0)) && (size == texture->getSize())) | 1447 | if ((pos==core::position2di(0,0)) && (size == texture->getSize())) |
1448 | { | 1448 | { |
1449 | IImage* image = new CImage(texture->getColorFormat(), size, texture->lock(ETLM_READ_ONLY), false); | 1449 | IImage* image = new CImage(texture->getColorFormat(), size, texture->lock(ETLM_READ_ONLY), false); |
1450 | texture->unlock(); | 1450 | texture->unlock(); |
1451 | return image; | 1451 | return image; |
1452 | } | 1452 | } |
1453 | else | 1453 | else |
1454 | { | 1454 | { |
1455 | // make sure to avoid buffer overruns | 1455 | // make sure to avoid buffer overruns |
1456 | // make the vector a separate variable for g++ 3.x | 1456 | // make the vector a separate variable for g++ 3.x |
1457 | const core::vector2d<u32> leftUpper(core::clamp(static_cast<u32>(pos.X), 0u, texture->getSize().Width), | 1457 | const core::vector2d<u32> leftUpper(core::clamp(static_cast<u32>(pos.X), 0u, texture->getSize().Width), |
1458 | core::clamp(static_cast<u32>(pos.Y), 0u, texture->getSize().Height)); | 1458 | core::clamp(static_cast<u32>(pos.Y), 0u, texture->getSize().Height)); |
1459 | const core::rect<u32> clamped(leftUpper, | 1459 | const core::rect<u32> clamped(leftUpper, |
1460 | core::dimension2du(core::clamp(static_cast<u32>(size.Width), 0u, texture->getSize().Width), | 1460 | core::dimension2du(core::clamp(static_cast<u32>(size.Width), 0u, texture->getSize().Width), |
1461 | core::clamp(static_cast<u32>(size.Height), 0u, texture->getSize().Height))); | 1461 | core::clamp(static_cast<u32>(size.Height), 0u, texture->getSize().Height))); |
1462 | if (!clamped.isValid()) | 1462 | if (!clamped.isValid()) |
1463 | return 0; | 1463 | return 0; |
1464 | u8* src = static_cast<u8*>(texture->lock(ETLM_READ_ONLY)); | 1464 | u8* src = static_cast<u8*>(texture->lock(ETLM_READ_ONLY)); |
1465 | if (!src) | 1465 | if (!src) |
1466 | return 0; | 1466 | return 0; |
1467 | IImage* image = new CImage(texture->getColorFormat(), clamped.getSize()); | 1467 | IImage* image = new CImage(texture->getColorFormat(), clamped.getSize()); |
1468 | u8* dst = static_cast<u8*>(image->lock()); | 1468 | u8* dst = static_cast<u8*>(image->lock()); |
1469 | src += clamped.UpperLeftCorner.Y * texture->getPitch() + image->getBytesPerPixel() * clamped.UpperLeftCorner.X; | 1469 | src += clamped.UpperLeftCorner.Y * texture->getPitch() + image->getBytesPerPixel() * clamped.UpperLeftCorner.X; |
1470 | for (u32 i=0; i<clamped.getHeight(); ++i) | 1470 | for (u32 i=0; i<clamped.getHeight(); ++i) |
1471 | { | 1471 | { |
1472 | video::CColorConverter::convert_viaFormat(src, texture->getColorFormat(), clamped.getWidth(), dst, image->getColorFormat()); | 1472 | video::CColorConverter::convert_viaFormat(src, texture->getColorFormat(), clamped.getWidth(), dst, image->getColorFormat()); |
1473 | src += texture->getPitch(); | 1473 | src += texture->getPitch(); |
1474 | dst += image->getPitch(); | 1474 | dst += image->getPitch(); |
1475 | } | 1475 | } |
1476 | image->unlock(); | 1476 | image->unlock(); |
1477 | texture->unlock(); | 1477 | texture->unlock(); |
1478 | return image; | 1478 | return image; |
1479 | } | 1479 | } |
1480 | } | 1480 | } |
1481 | 1481 | ||
1482 | 1482 | ||
1483 | //! Sets the fog mode. | 1483 | //! Sets the fog mode. |
1484 | void CNullDriver::setFog(SColor color, E_FOG_TYPE fogType, f32 start, f32 end, | 1484 | void CNullDriver::setFog(SColor color, E_FOG_TYPE fogType, f32 start, f32 end, |
1485 | f32 density, bool pixelFog, bool rangeFog) | 1485 | f32 density, bool pixelFog, bool rangeFog) |
1486 | { | 1486 | { |
1487 | FogColor = color; | 1487 | FogColor = color; |
1488 | FogType = fogType; | 1488 | FogType = fogType; |
1489 | FogStart = start; | 1489 | FogStart = start; |
1490 | FogEnd = end; | 1490 | FogEnd = end; |
1491 | FogDensity = density; | 1491 | FogDensity = density; |
1492 | PixelFog = pixelFog; | 1492 | PixelFog = pixelFog; |
1493 | RangeFog = rangeFog; | 1493 | RangeFog = rangeFog; |
1494 | } | 1494 | } |
1495 | 1495 | ||
1496 | //! Gets the fog mode. | 1496 | //! Gets the fog mode. |
1497 | void CNullDriver::getFog(SColor& color, E_FOG_TYPE& fogType, f32& start, f32& end, | 1497 | void CNullDriver::getFog(SColor& color, E_FOG_TYPE& fogType, f32& start, f32& end, |
1498 | f32& density, bool& pixelFog, bool& rangeFog) | 1498 | f32& density, bool& pixelFog, bool& rangeFog) |
1499 | { | 1499 | { |
1500 | color = FogColor; | 1500 | color = FogColor; |
1501 | fogType = FogType; | 1501 | fogType = FogType; |
1502 | start = FogStart; | 1502 | start = FogStart; |
1503 | end = FogEnd; | 1503 | end = FogEnd; |
1504 | density = FogDensity; | 1504 | density = FogDensity; |
1505 | pixelFog = PixelFog; | 1505 | pixelFog = PixelFog; |
1506 | rangeFog = RangeFog; | 1506 | rangeFog = RangeFog; |
1507 | } | 1507 | } |
1508 | 1508 | ||
1509 | //! Draws a mesh buffer | 1509 | //! Draws a mesh buffer |
1510 | void CNullDriver::drawMeshBuffer(const scene::IMeshBuffer* mb) | 1510 | void CNullDriver::drawMeshBuffer(const scene::IMeshBuffer* mb) |
1511 | { | 1511 | { |
1512 | if (!mb) | 1512 | if (!mb) |
1513 | return; | 1513 | return; |
1514 | 1514 | ||
1515 | //IVertexBuffer and IIndexBuffer later | 1515 | //IVertexBuffer and IIndexBuffer later |
1516 | SHWBufferLink *HWBuffer=getBufferLink(mb); | 1516 | SHWBufferLink *HWBuffer=getBufferLink(mb); |
1517 | 1517 | ||
1518 | if (HWBuffer) | 1518 | if (HWBuffer) |
1519 | drawHardwareBuffer(HWBuffer); | 1519 | drawHardwareBuffer(HWBuffer); |
1520 | else | 1520 | else |
1521 | drawVertexPrimitiveList(mb->getVertices(), mb->getVertexCount(), mb->getIndices(), mb->getIndexCount()/3, mb->getVertexType(), scene::EPT_TRIANGLES, mb->getIndexType()); | 1521 | drawVertexPrimitiveList(mb->getVertices(), mb->getVertexCount(), mb->getIndices(), mb->getIndexCount()/3, mb->getVertexType(), scene::EPT_TRIANGLES, mb->getIndexType()); |
1522 | } | 1522 | } |
1523 | 1523 | ||
1524 | 1524 | ||
1525 | //! Draws the normals of a mesh buffer | 1525 | //! Draws the normals of a mesh buffer |
1526 | void CNullDriver::drawMeshBufferNormals(const scene::IMeshBuffer* mb, f32 length, SColor color) | 1526 | void CNullDriver::drawMeshBufferNormals(const scene::IMeshBuffer* mb, f32 length, SColor color) |
1527 | { | 1527 | { |
1528 | const u32 count = mb->getVertexCount(); | 1528 | const u32 count = mb->getVertexCount(); |
1529 | const bool normalize = mb->getMaterial().NormalizeNormals; | 1529 | const bool normalize = mb->getMaterial().NormalizeNormals; |
1530 | 1530 | ||
1531 | for (u32 i=0; i < count; ++i) | 1531 | for (u32 i=0; i < count; ++i) |
1532 | { | 1532 | { |
1533 | core::vector3df normalizedNormal = mb->getNormal(i); | 1533 | core::vector3df normalizedNormal = mb->getNormal(i); |
1534 | if (normalize) | 1534 | if (normalize) |
1535 | normalizedNormal.normalize(); | 1535 | normalizedNormal.normalize(); |
1536 | 1536 | ||
1537 | const core::vector3df& pos = mb->getPosition(i); | 1537 | const core::vector3df& pos = mb->getPosition(i); |
1538 | draw3DLine(pos, pos + (normalizedNormal * length), color); | 1538 | draw3DLine(pos, pos + (normalizedNormal * length), color); |
1539 | } | 1539 | } |
1540 | } | 1540 | } |
1541 | 1541 | ||
1542 | 1542 | ||
1543 | CNullDriver::SHWBufferLink *CNullDriver::getBufferLink(const scene::IMeshBuffer* mb) | 1543 | CNullDriver::SHWBufferLink *CNullDriver::getBufferLink(const scene::IMeshBuffer* mb) |
1544 | { | 1544 | { |
1545 | if (!mb || !isHardwareBufferRecommend(mb)) | 1545 | if (!mb || !isHardwareBufferRecommend(mb)) |
1546 | return 0; | 1546 | return 0; |
1547 | 1547 | ||
1548 | //search for hardware links | 1548 | //search for hardware links |
1549 | core::map< const scene::IMeshBuffer*,SHWBufferLink* >::Node* node = HWBufferMap.find(mb); | 1549 | core::map< const scene::IMeshBuffer*,SHWBufferLink* >::Node* node = HWBufferMap.find(mb); |
1550 | if (node) | 1550 | if (node) |
1551 | return node->getValue(); | 1551 | return node->getValue(); |
1552 | 1552 | ||
1553 | return createHardwareBuffer(mb); //no hardware links, and mesh wants one, create it | 1553 | return createHardwareBuffer(mb); //no hardware links, and mesh wants one, create it |
1554 | } | 1554 | } |
1555 | 1555 | ||
1556 | 1556 | ||
1557 | //! Update all hardware buffers, remove unused ones | 1557 | //! Update all hardware buffers, remove unused ones |
1558 | void CNullDriver::updateAllHardwareBuffers() | 1558 | void CNullDriver::updateAllHardwareBuffers() |
1559 | { | 1559 | { |
1560 | core::map<const scene::IMeshBuffer*,SHWBufferLink*>::ParentFirstIterator Iterator=HWBufferMap.getParentFirstIterator(); | 1560 | core::map<const scene::IMeshBuffer*,SHWBufferLink*>::ParentFirstIterator Iterator=HWBufferMap.getParentFirstIterator(); |
1561 | 1561 | ||
1562 | for (;!Iterator.atEnd();Iterator++) | 1562 | for (;!Iterator.atEnd();Iterator++) |
1563 | { | 1563 | { |
1564 | SHWBufferLink *Link=Iterator.getNode()->getValue(); | 1564 | SHWBufferLink *Link=Iterator.getNode()->getValue(); |
1565 | 1565 | ||
1566 | Link->LastUsed++; | 1566 | Link->LastUsed++; |
1567 | if (Link->LastUsed>20000) | 1567 | if (Link->LastUsed>20000) |
1568 | { | 1568 | { |
1569 | deleteHardwareBuffer(Link); | 1569 | deleteHardwareBuffer(Link); |
1570 | 1570 | ||
1571 | // todo: needs better fix | 1571 | // todo: needs better fix |
1572 | Iterator = HWBufferMap.getParentFirstIterator(); | 1572 | Iterator = HWBufferMap.getParentFirstIterator(); |
1573 | } | 1573 | } |
1574 | } | 1574 | } |
1575 | } | 1575 | } |
1576 | 1576 | ||
1577 | 1577 | ||
1578 | void CNullDriver::deleteHardwareBuffer(SHWBufferLink *HWBuffer) | 1578 | void CNullDriver::deleteHardwareBuffer(SHWBufferLink *HWBuffer) |
1579 | { | 1579 | { |
1580 | if (!HWBuffer) | 1580 | if (!HWBuffer) |
1581 | return; | 1581 | return; |
1582 | HWBufferMap.remove(HWBuffer->MeshBuffer); | 1582 | HWBufferMap.remove(HWBuffer->MeshBuffer); |
1583 | delete HWBuffer; | 1583 | delete HWBuffer; |
1584 | } | 1584 | } |
1585 | 1585 | ||
1586 | 1586 | ||
1587 | //! Remove hardware buffer | 1587 | //! Remove hardware buffer |
1588 | void CNullDriver::removeHardwareBuffer(const scene::IMeshBuffer* mb) | 1588 | void CNullDriver::removeHardwareBuffer(const scene::IMeshBuffer* mb) |
1589 | { | 1589 | { |
1590 | core::map<const scene::IMeshBuffer*,SHWBufferLink*>::Node* node = HWBufferMap.find(mb); | 1590 | core::map<const scene::IMeshBuffer*,SHWBufferLink*>::Node* node = HWBufferMap.find(mb); |
1591 | if (node) | 1591 | if (node) |
1592 | deleteHardwareBuffer(node->getValue()); | 1592 | deleteHardwareBuffer(node->getValue()); |
1593 | } | 1593 | } |
1594 | 1594 | ||
1595 | 1595 | ||
1596 | //! Remove all hardware buffers | 1596 | //! Remove all hardware buffers |
1597 | void CNullDriver::removeAllHardwareBuffers() | 1597 | void CNullDriver::removeAllHardwareBuffers() |
1598 | { | 1598 | { |
1599 | while (HWBufferMap.size()) | 1599 | while (HWBufferMap.size()) |
1600 | deleteHardwareBuffer(HWBufferMap.getRoot()->getValue()); | 1600 | deleteHardwareBuffer(HWBufferMap.getRoot()->getValue()); |
1601 | } | 1601 | } |
1602 | 1602 | ||
1603 | 1603 | ||
1604 | bool CNullDriver::isHardwareBufferRecommend(const scene::IMeshBuffer* mb) | 1604 | bool CNullDriver::isHardwareBufferRecommend(const scene::IMeshBuffer* mb) |
1605 | { | 1605 | { |
1606 | if (!mb || (mb->getHardwareMappingHint_Index()==scene::EHM_NEVER && mb->getHardwareMappingHint_Vertex()==scene::EHM_NEVER)) | 1606 | if (!mb || (mb->getHardwareMappingHint_Index()==scene::EHM_NEVER && mb->getHardwareMappingHint_Vertex()==scene::EHM_NEVER)) |
1607 | return false; | 1607 | return false; |
1608 | 1608 | ||
1609 | if (mb->getVertexCount()<MinVertexCountForVBO) | 1609 | if (mb->getVertexCount()<MinVertexCountForVBO) |
1610 | return false; | 1610 | return false; |
1611 | 1611 | ||
1612 | return true; | 1612 | return true; |
1613 | } | 1613 | } |
1614 | 1614 | ||
1615 | 1615 | ||
1616 | //! Create occlusion query. | 1616 | //! Create occlusion query. |
1617 | /** Use node for identification and mesh for occlusion test. */ | 1617 | /** Use node for identification and mesh for occlusion test. */ |
1618 | void CNullDriver::addOcclusionQuery(scene::ISceneNode* node, const scene::IMesh* mesh) | 1618 | void CNullDriver::addOcclusionQuery(scene::ISceneNode* node, const scene::IMesh* mesh) |
1619 | { | 1619 | { |
1620 | if (!node) | 1620 | if (!node) |
1621 | return; | 1621 | return; |
1622 | if (!mesh) | 1622 | if (!mesh) |
1623 | { | 1623 | { |
1624 | if ((node->getType() != scene::ESNT_MESH) && (node->getType() != scene::ESNT_ANIMATED_MESH)) | 1624 | if ((node->getType() != scene::ESNT_MESH) && (node->getType() != scene::ESNT_ANIMATED_MESH)) |
1625 | return; | 1625 | return; |
1626 | else if (node->getType() == scene::ESNT_MESH) | 1626 | else if (node->getType() == scene::ESNT_MESH) |
1627 | mesh = static_cast<scene::IMeshSceneNode*>(node)->getMesh(); | 1627 | mesh = static_cast<scene::IMeshSceneNode*>(node)->getMesh(); |
1628 | else | 1628 | else |
1629 | mesh = static_cast<scene::IAnimatedMeshSceneNode*>(node)->getMesh()->getMesh(0); | 1629 | mesh = static_cast<scene::IAnimatedMeshSceneNode*>(node)->getMesh()->getMesh(0); |
1630 | if (!mesh) | 1630 | if (!mesh) |
1631 | return; | 1631 | return; |
1632 | } | 1632 | } |
1633 | 1633 | ||
1634 | //search for query | 1634 | //search for query |
1635 | s32 index = OcclusionQueries.linear_search(SOccQuery(node)); | 1635 | s32 index = OcclusionQueries.linear_search(SOccQuery(node)); |
1636 | if (index != -1) | 1636 | if (index != -1) |
1637 | { | 1637 | { |
1638 | if (OcclusionQueries[index].Mesh != mesh) | 1638 | if (OcclusionQueries[index].Mesh != mesh) |
1639 | { | 1639 | { |
1640 | OcclusionQueries[index].Mesh->drop(); | 1640 | OcclusionQueries[index].Mesh->drop(); |
1641 | OcclusionQueries[index].Mesh = mesh; | 1641 | OcclusionQueries[index].Mesh = mesh; |
1642 | mesh->grab(); | 1642 | mesh->grab(); |
1643 | } | 1643 | } |
1644 | } | 1644 | } |
1645 | else | 1645 | else |
1646 | { | 1646 | { |
1647 | OcclusionQueries.push_back(SOccQuery(node, mesh)); | 1647 | OcclusionQueries.push_back(SOccQuery(node, mesh)); |
1648 | node->setAutomaticCulling(node->getAutomaticCulling() | scene::EAC_OCC_QUERY); | 1648 | node->setAutomaticCulling(node->getAutomaticCulling() | scene::EAC_OCC_QUERY); |
1649 | } | 1649 | } |
1650 | } | 1650 | } |
1651 | 1651 | ||
1652 | 1652 | ||
1653 | //! Remove occlusion query. | 1653 | //! Remove occlusion query. |
1654 | void CNullDriver::removeOcclusionQuery(scene::ISceneNode* node) | 1654 | void CNullDriver::removeOcclusionQuery(scene::ISceneNode* node) |
1655 | { | 1655 | { |
1656 | //search for query | 1656 | //search for query |
1657 | s32 index = OcclusionQueries.linear_search(SOccQuery(node)); | 1657 | s32 index = OcclusionQueries.linear_search(SOccQuery(node)); |
1658 | if (index != -1) | 1658 | if (index != -1) |
1659 | { | 1659 | { |
1660 | node->setAutomaticCulling(node->getAutomaticCulling() & ~scene::EAC_OCC_QUERY); | 1660 | node->setAutomaticCulling(node->getAutomaticCulling() & ~scene::EAC_OCC_QUERY); |
1661 | OcclusionQueries.erase(index); | 1661 | OcclusionQueries.erase(index); |
1662 | } | 1662 | } |
1663 | } | 1663 | } |
1664 | 1664 | ||
1665 | 1665 | ||
1666 | //! Remove all occlusion queries. | 1666 | //! Remove all occlusion queries. |
1667 | void CNullDriver::removeAllOcclusionQueries() | 1667 | void CNullDriver::removeAllOcclusionQueries() |
1668 | { | 1668 | { |
1669 | for (s32 i=OcclusionQueries.size()-1; i>=0; --i) | 1669 | for (s32 i=OcclusionQueries.size()-1; i>=0; --i) |
1670 | { | 1670 | { |
1671 | removeOcclusionQuery(OcclusionQueries[i].Node); | 1671 | removeOcclusionQuery(OcclusionQueries[i].Node); |
1672 | } | 1672 | } |
1673 | } | 1673 | } |
1674 | 1674 | ||
1675 | 1675 | ||
1676 | //! Run occlusion query. Draws mesh stored in query. | 1676 | //! Run occlusion query. Draws mesh stored in query. |
1677 | /** If the mesh shall be rendered visible, use | 1677 | /** If the mesh shall be rendered visible, use |
1678 | flag to enable the proper material setting. */ | 1678 | flag to enable the proper material setting. */ |
1679 | void CNullDriver::runOcclusionQuery(scene::ISceneNode* node, bool visible) | 1679 | void CNullDriver::runOcclusionQuery(scene::ISceneNode* node, bool visible) |
1680 | { | 1680 | { |
1681 | if(!node) | 1681 | if(!node) |
1682 | return; | 1682 | return; |
1683 | s32 index = OcclusionQueries.linear_search(SOccQuery(node)); | 1683 | s32 index = OcclusionQueries.linear_search(SOccQuery(node)); |
1684 | if (index==-1) | 1684 | if (index==-1) |
1685 | return; | 1685 | return; |
1686 | OcclusionQueries[index].Run=0; | 1686 | OcclusionQueries[index].Run=0; |
1687 | if (!visible) | 1687 | if (!visible) |
1688 | { | 1688 | { |
1689 | SMaterial mat; | 1689 | SMaterial mat; |
1690 | mat.Lighting=false; | 1690 | mat.Lighting=false; |
1691 | mat.AntiAliasing=0; | 1691 | mat.AntiAliasing=0; |
1692 | mat.ColorMask=ECP_NONE; | 1692 | mat.ColorMask=ECP_NONE; |
1693 | mat.GouraudShading=false; | 1693 | mat.GouraudShading=false; |
1694 | mat.ZWriteEnable=false; | 1694 | mat.ZWriteEnable=false; |
1695 | setMaterial(mat); | 1695 | setMaterial(mat); |
1696 | } | 1696 | } |
1697 | setTransform(video::ETS_WORLD, node->getAbsoluteTransformation()); | 1697 | setTransform(video::ETS_WORLD, node->getAbsoluteTransformation()); |
1698 | const scene::IMesh* mesh = OcclusionQueries[index].Mesh; | 1698 | const scene::IMesh* mesh = OcclusionQueries[index].Mesh; |
1699 | for (u32 i=0; i<mesh->getMeshBufferCount(); ++i) | 1699 | for (u32 i=0; i<mesh->getMeshBufferCount(); ++i) |
1700 | { | 1700 | { |
1701 | if (visible) | 1701 | if (visible) |
1702 | setMaterial(mesh->getMeshBuffer(i)->getMaterial()); | 1702 | setMaterial(mesh->getMeshBuffer(i)->getMaterial()); |
1703 | drawMeshBuffer(mesh->getMeshBuffer(i)); | 1703 | drawMeshBuffer(mesh->getMeshBuffer(i)); |
1704 | } | 1704 | } |
1705 | } | 1705 | } |
1706 | 1706 | ||
1707 | 1707 | ||
1708 | //! Run all occlusion queries. Draws all meshes stored in queries. | 1708 | //! Run all occlusion queries. Draws all meshes stored in queries. |
1709 | /** If the meshes shall not be rendered visible, use | 1709 | /** If the meshes shall not be rendered visible, use |
1710 | overrideMaterial to disable the color and depth buffer. */ | 1710 | overrideMaterial to disable the color and depth buffer. */ |
1711 | void CNullDriver::runAllOcclusionQueries(bool visible) | 1711 | void CNullDriver::runAllOcclusionQueries(bool visible) |
1712 | { | 1712 | { |
1713 | for (u32 i=0; i<OcclusionQueries.size(); ++i) | 1713 | for (u32 i=0; i<OcclusionQueries.size(); ++i) |
1714 | runOcclusionQuery(OcclusionQueries[i].Node, visible); | 1714 | runOcclusionQuery(OcclusionQueries[i].Node, visible); |
1715 | } | 1715 | } |
1716 | 1716 | ||
1717 | 1717 | ||
1718 | //! Update occlusion query. Retrieves results from GPU. | 1718 | //! Update occlusion query. Retrieves results from GPU. |
1719 | /** If the query shall not block, set the flag to false. | 1719 | /** If the query shall not block, set the flag to false. |
1720 | Update might not occur in this case, though */ | 1720 | Update might not occur in this case, though */ |
1721 | void CNullDriver::updateOcclusionQuery(scene::ISceneNode* node, bool block) | 1721 | void CNullDriver::updateOcclusionQuery(scene::ISceneNode* node, bool block) |
1722 | { | 1722 | { |
1723 | } | 1723 | } |
1724 | 1724 | ||
1725 | 1725 | ||
1726 | //! Update all occlusion queries. Retrieves results from GPU. | 1726 | //! Update all occlusion queries. Retrieves results from GPU. |
1727 | /** If the query shall not block, set the flag to false. | 1727 | /** If the query shall not block, set the flag to false. |
1728 | Update might not occur in this case, though */ | 1728 | Update might not occur in this case, though */ |
1729 | void CNullDriver::updateAllOcclusionQueries(bool block) | 1729 | void CNullDriver::updateAllOcclusionQueries(bool block) |
1730 | { | 1730 | { |
1731 | for (u32 i=0; i<OcclusionQueries.size(); ++i) | 1731 | for (u32 i=0; i<OcclusionQueries.size(); ++i) |
1732 | { | 1732 | { |
1733 | if (OcclusionQueries[i].Run==u32(~0)) | 1733 | if (OcclusionQueries[i].Run==u32(~0)) |
1734 | continue; | 1734 | continue; |
1735 | updateOcclusionQuery(OcclusionQueries[i].Node, block); | 1735 | updateOcclusionQuery(OcclusionQueries[i].Node, block); |
1736 | ++OcclusionQueries[i].Run; | 1736 | ++OcclusionQueries[i].Run; |
1737 | if (OcclusionQueries[i].Run>1000) | 1737 | if (OcclusionQueries[i].Run>1000) |
1738 | removeOcclusionQuery(OcclusionQueries[i].Node); | 1738 | removeOcclusionQuery(OcclusionQueries[i].Node); |
1739 | } | 1739 | } |
1740 | } | 1740 | } |
1741 | 1741 | ||
1742 | 1742 | ||
1743 | //! Return query result. | 1743 | //! Return query result. |
1744 | /** Return value is the number of visible pixels/fragments. | 1744 | /** Return value is the number of visible pixels/fragments. |
1745 | The value is a safe approximation, i.e. can be larger then the | 1745 | The value is a safe approximation, i.e. can be larger then the |
1746 | actual value of pixels. */ | 1746 | actual value of pixels. */ |
1747 | u32 CNullDriver::getOcclusionQueryResult(scene::ISceneNode* node) const | 1747 | u32 CNullDriver::getOcclusionQueryResult(scene::ISceneNode* node) const |
1748 | { | 1748 | { |
1749 | return ~0; | 1749 | return ~0; |
1750 | } | 1750 | } |
1751 | 1751 | ||
1752 | 1752 | ||
1753 | //! Only used by the internal engine. Used to notify the driver that | 1753 | //! Only used by the internal engine. Used to notify the driver that |
1754 | //! the window was resized. | 1754 | //! the window was resized. |
1755 | void CNullDriver::OnResize(const core::dimension2d<u32>& size) | 1755 | void CNullDriver::OnResize(const core::dimension2d<u32>& size) |
1756 | { | 1756 | { |
1757 | if (ViewPort.getWidth() == (s32)ScreenSize.Width && | 1757 | if (ViewPort.getWidth() == (s32)ScreenSize.Width && |
1758 | ViewPort.getHeight() == (s32)ScreenSize.Height) | 1758 | ViewPort.getHeight() == (s32)ScreenSize.Height) |
1759 | ViewPort = core::rect<s32>(core::position2d<s32>(0,0), | 1759 | ViewPort = core::rect<s32>(core::position2d<s32>(0,0), |
1760 | core::dimension2di(size)); | 1760 | core::dimension2di(size)); |
1761 | 1761 | ||
1762 | ScreenSize = size; | 1762 | ScreenSize = size; |
1763 | } | 1763 | } |
1764 | 1764 | ||
1765 | 1765 | ||
1766 | // adds a material renderer and drops it afterwards. To be used for internal creation | 1766 | // adds a material renderer and drops it afterwards. To be used for internal creation |
1767 | s32 CNullDriver::addAndDropMaterialRenderer(IMaterialRenderer* m) | 1767 | s32 CNullDriver::addAndDropMaterialRenderer(IMaterialRenderer* m) |
1768 | { | 1768 | { |
1769 | s32 i = addMaterialRenderer(m); | 1769 | s32 i = addMaterialRenderer(m); |
1770 | 1770 | ||
1771 | if (m) | 1771 | if (m) |
1772 | m->drop(); | 1772 | m->drop(); |
1773 | 1773 | ||
1774 | return i; | 1774 | return i; |
1775 | } | 1775 | } |
1776 | 1776 | ||
1777 | 1777 | ||
1778 | //! Adds a new material renderer to the video device. | 1778 | //! Adds a new material renderer to the video device. |
1779 | s32 CNullDriver::addMaterialRenderer(IMaterialRenderer* renderer, const char* name) | 1779 | s32 CNullDriver::addMaterialRenderer(IMaterialRenderer* renderer, const char* name) |
1780 | { | 1780 | { |
1781 | if (!renderer) | 1781 | if (!renderer) |
1782 | return -1; | 1782 | return -1; |
1783 | 1783 | ||
1784 | SMaterialRenderer r; | 1784 | SMaterialRenderer r; |
1785 | r.Renderer = renderer; | 1785 | r.Renderer = renderer; |
1786 | r.Name = name; | 1786 | r.Name = name; |
1787 | 1787 | ||
1788 | if (name == 0 && (MaterialRenderers.size() < (sizeof(sBuiltInMaterialTypeNames) / sizeof(char*))-1 )) | 1788 | if (name == 0 && (MaterialRenderers.size() < (sizeof(sBuiltInMaterialTypeNames) / sizeof(char*))-1 )) |
1789 | { | 1789 | { |
1790 | // set name of built in renderer so that we don't have to implement name | 1790 | // set name of built in renderer so that we don't have to implement name |
1791 | // setting in all available renderers. | 1791 | // setting in all available renderers. |
1792 | r.Name = sBuiltInMaterialTypeNames[MaterialRenderers.size()]; | 1792 | r.Name = sBuiltInMaterialTypeNames[MaterialRenderers.size()]; |
1793 | } | 1793 | } |
1794 | 1794 | ||
1795 | MaterialRenderers.push_back(r); | 1795 | MaterialRenderers.push_back(r); |
1796 | renderer->grab(); | 1796 | renderer->grab(); |
1797 | 1797 | ||
1798 | return MaterialRenderers.size()-1; | 1798 | return MaterialRenderers.size()-1; |
1799 | } | 1799 | } |
1800 | 1800 | ||
1801 | 1801 | ||
1802 | //! Sets the name of a material renderer. | 1802 | //! Sets the name of a material renderer. |
1803 | void CNullDriver::setMaterialRendererName(s32 idx, const char* name) | 1803 | void CNullDriver::setMaterialRendererName(s32 idx, const char* name) |
1804 | { | 1804 | { |
1805 | if (idx < s32(sizeof(sBuiltInMaterialTypeNames) / sizeof(char*))-1 || | 1805 | if (idx < s32(sizeof(sBuiltInMaterialTypeNames) / sizeof(char*))-1 || |
1806 | idx >= (s32)MaterialRenderers.size()) | 1806 | idx >= (s32)MaterialRenderers.size()) |
1807 | return; | 1807 | return; |
1808 | 1808 | ||
1809 | MaterialRenderers[idx].Name = name; | 1809 | MaterialRenderers[idx].Name = name; |
1810 | } | 1810 | } |
1811 | 1811 | ||
1812 | 1812 | ||
1813 | //! Creates material attributes list from a material, usable for serialization and more. | 1813 | //! Creates material attributes list from a material, usable for serialization and more. |
1814 | io::IAttributes* CNullDriver::createAttributesFromMaterial(const video::SMaterial& material, | 1814 | io::IAttributes* CNullDriver::createAttributesFromMaterial(const video::SMaterial& material, |
1815 | io::SAttributeReadWriteOptions* options) | 1815 | io::SAttributeReadWriteOptions* options) |
1816 | { | 1816 | { |
1817 | io::CAttributes* attr = new io::CAttributes(this); | 1817 | io::CAttributes* attr = new io::CAttributes(this); |
1818 | 1818 | ||
1819 | attr->addEnum("Type", material.MaterialType, sBuiltInMaterialTypeNames); | 1819 | attr->addEnum("Type", material.MaterialType, sBuiltInMaterialTypeNames); |
1820 | 1820 | ||
1821 | attr->addColor("Ambient", material.AmbientColor); | 1821 | attr->addColor("Ambient", material.AmbientColor); |
1822 | attr->addColor("Diffuse", material.DiffuseColor); | 1822 | attr->addColor("Diffuse", material.DiffuseColor); |
1823 | attr->addColor("Emissive", material.EmissiveColor); | 1823 | attr->addColor("Emissive", material.EmissiveColor); |
1824 | attr->addColor("Specular", material.SpecularColor); | 1824 | attr->addColor("Specular", material.SpecularColor); |
1825 | 1825 | ||
1826 | attr->addFloat("Shininess", material.Shininess); | 1826 | attr->addFloat("Shininess", material.Shininess); |
1827 | attr->addFloat("Param1", material.MaterialTypeParam); | 1827 | attr->addFloat("Param1", material.MaterialTypeParam); |
1828 | attr->addFloat("Param2", material.MaterialTypeParam2); | 1828 | attr->addFloat("Param2", material.MaterialTypeParam2); |
1829 | 1829 | ||
1830 | core::stringc prefix="Texture"; | 1830 | core::stringc prefix="Texture"; |
1831 | u32 i; | 1831 | u32 i; |
1832 | for (i=0; i<MATERIAL_MAX_TEXTURES; ++i) | 1832 | for (i=0; i<MATERIAL_MAX_TEXTURES; ++i) |
1833 | { | 1833 | { |
1834 | if (options && (options->Flags&io::EARWF_USE_RELATIVE_PATHS) && options->Filename && material.getTexture(i)) | 1834 | if (options && (options->Flags&io::EARWF_USE_RELATIVE_PATHS) && options->Filename && material.getTexture(i)) |
1835 | { | 1835 | { |
1836 | io::path path = FileSystem->getRelativeFilename( | 1836 | io::path path = FileSystem->getRelativeFilename( |
1837 | FileSystem->getAbsolutePath(material.getTexture(i)->getName()), options->Filename); | 1837 | FileSystem->getAbsolutePath(material.getTexture(i)->getName()), options->Filename); |
1838 | attr->addTexture((prefix+core::stringc(i+1)).c_str(), material.getTexture(i), path); | 1838 | attr->addTexture((prefix+core::stringc(i+1)).c_str(), material.getTexture(i), path); |
1839 | } | 1839 | } |
1840 | else | 1840 | else |
1841 | attr->addTexture((prefix+core::stringc(i+1)).c_str(), material.getTexture(i)); | 1841 | attr->addTexture((prefix+core::stringc(i+1)).c_str(), material.getTexture(i)); |
1842 | } | 1842 | } |
1843 | 1843 | ||
1844 | attr->addBool("Wireframe", material.Wireframe); | 1844 | attr->addBool("Wireframe", material.Wireframe); |
1845 | attr->addBool("GouraudShading", material.GouraudShading); | 1845 | attr->addBool("GouraudShading", material.GouraudShading); |
1846 | attr->addBool("Lighting", material.Lighting); | 1846 | attr->addBool("Lighting", material.Lighting); |
1847 | attr->addBool("ZWriteEnable", material.ZWriteEnable); | 1847 | attr->addBool("ZWriteEnable", material.ZWriteEnable); |
1848 | attr->addInt("ZBuffer", material.ZBuffer); | 1848 | attr->addInt("ZBuffer", material.ZBuffer); |
1849 | attr->addBool("BackfaceCulling", material.BackfaceCulling); | 1849 | attr->addBool("BackfaceCulling", material.BackfaceCulling); |
1850 | attr->addBool("FrontfaceCulling", material.FrontfaceCulling); | 1850 | attr->addBool("FrontfaceCulling", material.FrontfaceCulling); |
1851 | attr->addBool("FogEnable", material.FogEnable); | 1851 | attr->addBool("FogEnable", material.FogEnable); |
1852 | attr->addBool("NormalizeNormals", material.NormalizeNormals); | 1852 | attr->addBool("NormalizeNormals", material.NormalizeNormals); |
1853 | attr->addBool("UseMipMaps", material.UseMipMaps); | 1853 | attr->addBool("UseMipMaps", material.UseMipMaps); |
1854 | attr->addInt("AntiAliasing", material.AntiAliasing); | 1854 | attr->addInt("AntiAliasing", material.AntiAliasing); |
1855 | attr->addInt("ColorMask", material.ColorMask); | 1855 | attr->addInt("ColorMask", material.ColorMask); |
1856 | attr->addInt("ColorMaterial", material.ColorMaterial); | 1856 | attr->addInt("ColorMaterial", material.ColorMaterial); |
1857 | attr->addInt("PolygonOffsetFactor", material.PolygonOffsetFactor); | 1857 | attr->addInt("PolygonOffsetFactor", material.PolygonOffsetFactor); |
1858 | attr->addEnum("PolygonOffsetDirection", material.PolygonOffsetDirection, video::PolygonOffsetDirectionNames); | 1858 | attr->addEnum("PolygonOffsetDirection", material.PolygonOffsetDirection, video::PolygonOffsetDirectionNames); |
1859 | 1859 | ||
1860 | prefix = "BilinearFilter"; | 1860 | prefix = "BilinearFilter"; |
1861 | for (i=0; i<MATERIAL_MAX_TEXTURES; ++i) | 1861 | for (i=0; i<MATERIAL_MAX_TEXTURES; ++i) |
1862 | attr->addBool((prefix+core::stringc(i+1)).c_str(), material.TextureLayer[i].BilinearFilter); | 1862 | attr->addBool((prefix+core::stringc(i+1)).c_str(), material.TextureLayer[i].BilinearFilter); |
1863 | prefix = "TrilinearFilter"; | 1863 | prefix = "TrilinearFilter"; |
1864 | for (i=0; i<MATERIAL_MAX_TEXTURES; ++i) | 1864 | for (i=0; i<MATERIAL_MAX_TEXTURES; ++i) |
1865 | attr->addBool((prefix+core::stringc(i+1)).c_str(), material.TextureLayer[i].TrilinearFilter); | 1865 | attr->addBool((prefix+core::stringc(i+1)).c_str(), material.TextureLayer[i].TrilinearFilter); |
1866 | prefix = "AnisotropicFilter"; | 1866 | prefix = "AnisotropicFilter"; |
1867 | for (i=0; i<MATERIAL_MAX_TEXTURES; ++i) | 1867 | for (i=0; i<MATERIAL_MAX_TEXTURES; ++i) |
1868 | attr->addInt((prefix+core::stringc(i+1)).c_str(), material.TextureLayer[i].AnisotropicFilter); | 1868 | attr->addInt((prefix+core::stringc(i+1)).c_str(), material.TextureLayer[i].AnisotropicFilter); |
1869 | prefix="TextureWrapU"; | 1869 | prefix="TextureWrapU"; |
1870 | for (i=0; i<MATERIAL_MAX_TEXTURES; ++i) | 1870 | for (i=0; i<MATERIAL_MAX_TEXTURES; ++i) |
1871 | attr->addEnum((prefix+core::stringc(i+1)).c_str(), material.TextureLayer[i].TextureWrapU, aTextureClampNames); | 1871 | attr->addEnum((prefix+core::stringc(i+1)).c_str(), material.TextureLayer[i].TextureWrapU, aTextureClampNames); |
1872 | prefix="TextureWrapV"; | 1872 | prefix="TextureWrapV"; |
1873 | for (i=0; i<MATERIAL_MAX_TEXTURES; ++i) | 1873 | for (i=0; i<MATERIAL_MAX_TEXTURES; ++i) |
1874 | attr->addEnum((prefix+core::stringc(i+1)).c_str(), material.TextureLayer[i].TextureWrapV, aTextureClampNames); | 1874 | attr->addEnum((prefix+core::stringc(i+1)).c_str(), material.TextureLayer[i].TextureWrapV, aTextureClampNames); |
1875 | prefix="LODBias"; | 1875 | prefix="LODBias"; |
1876 | for (i=0; i<MATERIAL_MAX_TEXTURES; ++i) | 1876 | for (i=0; i<MATERIAL_MAX_TEXTURES; ++i) |
1877 | attr->addInt((prefix+core::stringc(i+1)).c_str(), material.TextureLayer[i].LODBias); | 1877 | attr->addInt((prefix+core::stringc(i+1)).c_str(), material.TextureLayer[i].LODBias); |
1878 | 1878 | ||
1879 | return attr; | 1879 | return attr; |
1880 | } | 1880 | } |
1881 | 1881 | ||
1882 | 1882 | ||
1883 | //! Fills an SMaterial structure from attributes. | 1883 | //! Fills an SMaterial structure from attributes. |
1884 | void CNullDriver::fillMaterialStructureFromAttributes(video::SMaterial& outMaterial, io::IAttributes* attr) | 1884 | void CNullDriver::fillMaterialStructureFromAttributes(video::SMaterial& outMaterial, io::IAttributes* attr) |
1885 | { | 1885 | { |
1886 | outMaterial.MaterialType = video::EMT_SOLID; | 1886 | outMaterial.MaterialType = video::EMT_SOLID; |
1887 | 1887 | ||
1888 | core::stringc name = attr->getAttributeAsString("Type"); | 1888 | core::stringc name = attr->getAttributeAsString("Type"); |
1889 | 1889 | ||
1890 | u32 i; | 1890 | u32 i; |
1891 | 1891 | ||
1892 | for ( i=0; i < MaterialRenderers.size(); ++i) | 1892 | for ( i=0; i < MaterialRenderers.size(); ++i) |
1893 | if ( name == MaterialRenderers[i].Name ) | 1893 | if ( name == MaterialRenderers[i].Name ) |
1894 | { | 1894 | { |
1895 | outMaterial.MaterialType = (video::E_MATERIAL_TYPE)i; | 1895 | outMaterial.MaterialType = (video::E_MATERIAL_TYPE)i; |
1896 | break; | 1896 | break; |
1897 | } | 1897 | } |
1898 | 1898 | ||
1899 | outMaterial.AmbientColor = attr->getAttributeAsColor("Ambient"); | 1899 | outMaterial.AmbientColor = attr->getAttributeAsColor("Ambient"); |
1900 | outMaterial.DiffuseColor = attr->getAttributeAsColor("Diffuse"); | 1900 | outMaterial.DiffuseColor = attr->getAttributeAsColor("Diffuse"); |
1901 | outMaterial.EmissiveColor = attr->getAttributeAsColor("Emissive"); | 1901 | outMaterial.EmissiveColor = attr->getAttributeAsColor("Emissive"); |
1902 | outMaterial.SpecularColor = attr->getAttributeAsColor("Specular"); | 1902 | outMaterial.SpecularColor = attr->getAttributeAsColor("Specular"); |
1903 | 1903 | ||
1904 | outMaterial.Shininess = attr->getAttributeAsFloat("Shininess"); | 1904 | outMaterial.Shininess = attr->getAttributeAsFloat("Shininess"); |
1905 | outMaterial.MaterialTypeParam = attr->getAttributeAsFloat("Param1"); | 1905 | outMaterial.MaterialTypeParam = attr->getAttributeAsFloat("Param1"); |
1906 | outMaterial.MaterialTypeParam2 = attr->getAttributeAsFloat("Param2"); | 1906 | outMaterial.MaterialTypeParam2 = attr->getAttributeAsFloat("Param2"); |
1907 | 1907 | ||
1908 | core::stringc prefix="Texture"; | 1908 | core::stringc prefix="Texture"; |
1909 | for (i=0; i<MATERIAL_MAX_TEXTURES; ++i) | 1909 | for (i=0; i<MATERIAL_MAX_TEXTURES; ++i) |
1910 | outMaterial.setTexture(i, attr->getAttributeAsTexture((prefix+core::stringc(i+1)).c_str())); | 1910 | outMaterial.setTexture(i, attr->getAttributeAsTexture((prefix+core::stringc(i+1)).c_str())); |
1911 | 1911 | ||
1912 | outMaterial.Wireframe = attr->getAttributeAsBool("Wireframe"); | 1912 | outMaterial.Wireframe = attr->getAttributeAsBool("Wireframe"); |
1913 | outMaterial.GouraudShading = attr->getAttributeAsBool("GouraudShading"); | 1913 | outMaterial.GouraudShading = attr->getAttributeAsBool("GouraudShading"); |
1914 | outMaterial.Lighting = attr->getAttributeAsBool("Lighting"); | 1914 | outMaterial.Lighting = attr->getAttributeAsBool("Lighting"); |
1915 | outMaterial.ZWriteEnable = attr->getAttributeAsBool("ZWriteEnable"); | 1915 | outMaterial.ZWriteEnable = attr->getAttributeAsBool("ZWriteEnable"); |
1916 | outMaterial.ZBuffer = (u8)attr->getAttributeAsInt("ZBuffer"); | 1916 | outMaterial.ZBuffer = (u8)attr->getAttributeAsInt("ZBuffer"); |
1917 | outMaterial.BackfaceCulling = attr->getAttributeAsBool("BackfaceCulling"); | 1917 | outMaterial.BackfaceCulling = attr->getAttributeAsBool("BackfaceCulling"); |
1918 | outMaterial.FrontfaceCulling = attr->getAttributeAsBool("FrontfaceCulling"); | 1918 | outMaterial.FrontfaceCulling = attr->getAttributeAsBool("FrontfaceCulling"); |
1919 | outMaterial.FogEnable = attr->getAttributeAsBool("FogEnable"); | 1919 | outMaterial.FogEnable = attr->getAttributeAsBool("FogEnable"); |
1920 | outMaterial.NormalizeNormals = attr->getAttributeAsBool("NormalizeNormals"); | 1920 | outMaterial.NormalizeNormals = attr->getAttributeAsBool("NormalizeNormals"); |
1921 | if (attr->existsAttribute("UseMipMaps")) // legacy | 1921 | if (attr->existsAttribute("UseMipMaps")) // legacy |
1922 | outMaterial.UseMipMaps = attr->getAttributeAsBool("UseMipMaps"); | 1922 | outMaterial.UseMipMaps = attr->getAttributeAsBool("UseMipMaps"); |
1923 | else | 1923 | else |
1924 | outMaterial.UseMipMaps = true; | 1924 | outMaterial.UseMipMaps = true; |
1925 | 1925 | ||
1926 | // default 0 is ok | 1926 | // default 0 is ok |
1927 | outMaterial.AntiAliasing = attr->getAttributeAsInt("AntiAliasing"); | 1927 | outMaterial.AntiAliasing = attr->getAttributeAsInt("AntiAliasing"); |
1928 | if (attr->existsAttribute("ColorMask")) | 1928 | if (attr->existsAttribute("ColorMask")) |
1929 | outMaterial.ColorMask = attr->getAttributeAsInt("ColorMask"); | 1929 | outMaterial.ColorMask = attr->getAttributeAsInt("ColorMask"); |
1930 | if (attr->existsAttribute("ColorMaterial")) | 1930 | if (attr->existsAttribute("ColorMaterial")) |
1931 | outMaterial.ColorMaterial = attr->getAttributeAsInt("ColorMaterial"); | 1931 | outMaterial.ColorMaterial = attr->getAttributeAsInt("ColorMaterial"); |
1932 | if (attr->existsAttribute("PolygonOffsetFactor")) | 1932 | if (attr->existsAttribute("PolygonOffsetFactor")) |
1933 | outMaterial.PolygonOffsetFactor = attr->getAttributeAsInt("PolygonOffsetFactor"); | 1933 | outMaterial.PolygonOffsetFactor = attr->getAttributeAsInt("PolygonOffsetFactor"); |
1934 | if (attr->existsAttribute("PolygonOffsetDirection")) | 1934 | if (attr->existsAttribute("PolygonOffsetDirection")) |
1935 | outMaterial.PolygonOffsetDirection = (video::E_POLYGON_OFFSET)attr->getAttributeAsEnumeration("PolygonOffsetDirection", video::PolygonOffsetDirectionNames); | 1935 | outMaterial.PolygonOffsetDirection = (video::E_POLYGON_OFFSET)attr->getAttributeAsEnumeration("PolygonOffsetDirection", video::PolygonOffsetDirectionNames); |
1936 | prefix = "BilinearFilter"; | 1936 | prefix = "BilinearFilter"; |
1937 | if (attr->existsAttribute(prefix.c_str())) // legacy | 1937 | if (attr->existsAttribute(prefix.c_str())) // legacy |
1938 | outMaterial.setFlag(EMF_BILINEAR_FILTER, attr->getAttributeAsBool(prefix.c_str())); | 1938 | outMaterial.setFlag(EMF_BILINEAR_FILTER, attr->getAttributeAsBool(prefix.c_str())); |
1939 | else | 1939 | else |
1940 | for (i=0; i<MATERIAL_MAX_TEXTURES; ++i) | 1940 | for (i=0; i<MATERIAL_MAX_TEXTURES; ++i) |
1941 | outMaterial.TextureLayer[i].BilinearFilter = attr->getAttributeAsBool((prefix+core::stringc(i+1)).c_str()); | 1941 | outMaterial.TextureLayer[i].BilinearFilter = attr->getAttributeAsBool((prefix+core::stringc(i+1)).c_str()); |
1942 | 1942 | ||
1943 | prefix = "TrilinearFilter"; | 1943 | prefix = "TrilinearFilter"; |
1944 | if (attr->existsAttribute(prefix.c_str())) // legacy | 1944 | if (attr->existsAttribute(prefix.c_str())) // legacy |
1945 | outMaterial.setFlag(EMF_TRILINEAR_FILTER, attr->getAttributeAsBool(prefix.c_str())); | 1945 | outMaterial.setFlag(EMF_TRILINEAR_FILTER, attr->getAttributeAsBool(prefix.c_str())); |
1946 | else | 1946 | else |
1947 | for (i=0; i<MATERIAL_MAX_TEXTURES; ++i) | 1947 | for (i=0; i<MATERIAL_MAX_TEXTURES; ++i) |
1948 | outMaterial.TextureLayer[i].TrilinearFilter = attr->getAttributeAsBool((prefix+core::stringc(i+1)).c_str()); | 1948 | outMaterial.TextureLayer[i].TrilinearFilter = attr->getAttributeAsBool((prefix+core::stringc(i+1)).c_str()); |
1949 | 1949 | ||
1950 | prefix = "AnisotropicFilter"; | 1950 | prefix = "AnisotropicFilter"; |
1951 | if (attr->existsAttribute(prefix.c_str())) // legacy | 1951 | if (attr->existsAttribute(prefix.c_str())) // legacy |
1952 | outMaterial.setFlag(EMF_ANISOTROPIC_FILTER, attr->getAttributeAsBool(prefix.c_str())); | 1952 | outMaterial.setFlag(EMF_ANISOTROPIC_FILTER, attr->getAttributeAsBool(prefix.c_str())); |
1953 | else | 1953 | else |
1954 | for (i=0; i<MATERIAL_MAX_TEXTURES; ++i) | 1954 | for (i=0; i<MATERIAL_MAX_TEXTURES; ++i) |
1955 | outMaterial.TextureLayer[i].AnisotropicFilter = attr->getAttributeAsInt((prefix+core::stringc(i+1)).c_str()); | 1955 | outMaterial.TextureLayer[i].AnisotropicFilter = attr->getAttributeAsInt((prefix+core::stringc(i+1)).c_str()); |
1956 | 1956 | ||
1957 | prefix = "TextureWrap"; | 1957 | prefix = "TextureWrap"; |
1958 | if (attr->existsAttribute(prefix.c_str())) // legacy | 1958 | if (attr->existsAttribute(prefix.c_str())) // legacy |
1959 | { | 1959 | { |
1960 | for (i=0; i<MATERIAL_MAX_TEXTURES; ++i) | 1960 | for (i=0; i<MATERIAL_MAX_TEXTURES; ++i) |
1961 | { | 1961 | { |
1962 | outMaterial.TextureLayer[i].TextureWrapU = (E_TEXTURE_CLAMP)attr->getAttributeAsEnumeration((prefix+core::stringc(i+1)).c_str(), aTextureClampNames); | 1962 | outMaterial.TextureLayer[i].TextureWrapU = (E_TEXTURE_CLAMP)attr->getAttributeAsEnumeration((prefix+core::stringc(i+1)).c_str(), aTextureClampNames); |
1963 | outMaterial.TextureLayer[i].TextureWrapV = outMaterial.TextureLayer[i].TextureWrapU; | 1963 | outMaterial.TextureLayer[i].TextureWrapV = outMaterial.TextureLayer[i].TextureWrapU; |
1964 | } | 1964 | } |
1965 | } | 1965 | } |
1966 | else | 1966 | else |
1967 | { | 1967 | { |
1968 | for (i=0; i<MATERIAL_MAX_TEXTURES; ++i) | 1968 | for (i=0; i<MATERIAL_MAX_TEXTURES; ++i) |
1969 | { | 1969 | { |
1970 | outMaterial.TextureLayer[i].TextureWrapU = (E_TEXTURE_CLAMP)attr->getAttributeAsEnumeration((prefix+"U"+core::stringc(i+1)).c_str(), aTextureClampNames); | 1970 | outMaterial.TextureLayer[i].TextureWrapU = (E_TEXTURE_CLAMP)attr->getAttributeAsEnumeration((prefix+"U"+core::stringc(i+1)).c_str(), aTextureClampNames); |
1971 | outMaterial.TextureLayer[i].TextureWrapV = (E_TEXTURE_CLAMP)attr->getAttributeAsEnumeration((prefix+"V"+core::stringc(i+1)).c_str(), aTextureClampNames); | 1971 | outMaterial.TextureLayer[i].TextureWrapV = (E_TEXTURE_CLAMP)attr->getAttributeAsEnumeration((prefix+"V"+core::stringc(i+1)).c_str(), aTextureClampNames); |
1972 | } | 1972 | } |
1973 | } | 1973 | } |
1974 | 1974 | ||
1975 | // default 0 is ok | 1975 | // default 0 is ok |
1976 | prefix="LODBias"; | 1976 | prefix="LODBias"; |
1977 | for (i=0; i<MATERIAL_MAX_TEXTURES; ++i) | 1977 | for (i=0; i<MATERIAL_MAX_TEXTURES; ++i) |
1978 | outMaterial.TextureLayer[i].LODBias = attr->getAttributeAsInt((prefix+core::stringc(i+1)).c_str()); | 1978 | outMaterial.TextureLayer[i].LODBias = attr->getAttributeAsInt((prefix+core::stringc(i+1)).c_str()); |
1979 | } | 1979 | } |
1980 | 1980 | ||
1981 | 1981 | ||
1982 | //! Returns driver and operating system specific data about the IVideoDriver. | 1982 | //! Returns driver and operating system specific data about the IVideoDriver. |
1983 | const SExposedVideoData& CNullDriver::getExposedVideoData() | 1983 | const SExposedVideoData& CNullDriver::getExposedVideoData() |
1984 | { | 1984 | { |
1985 | return ExposedData; | 1985 | return ExposedData; |
1986 | } | 1986 | } |
1987 | 1987 | ||
1988 | 1988 | ||
1989 | //! Returns type of video driver | 1989 | //! Returns type of video driver |
1990 | E_DRIVER_TYPE CNullDriver::getDriverType() const | 1990 | E_DRIVER_TYPE CNullDriver::getDriverType() const |
1991 | { | 1991 | { |
1992 | return EDT_NULL; | 1992 | return EDT_NULL; |
1993 | } | 1993 | } |
1994 | 1994 | ||
1995 | 1995 | ||
1996 | //! deletes all material renderers | 1996 | //! deletes all material renderers |
1997 | void CNullDriver::deleteMaterialRenders() | 1997 | void CNullDriver::deleteMaterialRenders() |
1998 | { | 1998 | { |
1999 | // delete material renderers | 1999 | // delete material renderers |
2000 | for (u32 i=0; i<MaterialRenderers.size(); ++i) | 2000 | for (u32 i=0; i<MaterialRenderers.size(); ++i) |
2001 | if (MaterialRenderers[i].Renderer) | 2001 | if (MaterialRenderers[i].Renderer) |
2002 | MaterialRenderers[i].Renderer->drop(); | 2002 | MaterialRenderers[i].Renderer->drop(); |
2003 | 2003 | ||
2004 | MaterialRenderers.clear(); | 2004 | MaterialRenderers.clear(); |
2005 | } | 2005 | } |
2006 | 2006 | ||
2007 | 2007 | ||
2008 | //! Returns pointer to material renderer or null | 2008 | //! Returns pointer to material renderer or null |
2009 | IMaterialRenderer* CNullDriver::getMaterialRenderer(u32 idx) | 2009 | IMaterialRenderer* CNullDriver::getMaterialRenderer(u32 idx) |
2010 | { | 2010 | { |
2011 | if ( idx < MaterialRenderers.size() ) | 2011 | if ( idx < MaterialRenderers.size() ) |
2012 | return MaterialRenderers[idx].Renderer; | 2012 | return MaterialRenderers[idx].Renderer; |
2013 | else | 2013 | else |
2014 | return 0; | 2014 | return 0; |
2015 | } | 2015 | } |
2016 | 2016 | ||
2017 | 2017 | ||
2018 | //! Returns amount of currently available material renderers. | 2018 | //! Returns amount of currently available material renderers. |
2019 | u32 CNullDriver::getMaterialRendererCount() const | 2019 | u32 CNullDriver::getMaterialRendererCount() const |
2020 | { | 2020 | { |
2021 | return MaterialRenderers.size(); | 2021 | return MaterialRenderers.size(); |
2022 | } | 2022 | } |
2023 | 2023 | ||
2024 | 2024 | ||
2025 | //! Returns name of the material renderer | 2025 | //! Returns name of the material renderer |
2026 | const char* CNullDriver::getMaterialRendererName(u32 idx) const | 2026 | const char* CNullDriver::getMaterialRendererName(u32 idx) const |
2027 | { | 2027 | { |
2028 | if ( idx < MaterialRenderers.size() ) | 2028 | if ( idx < MaterialRenderers.size() ) |
2029 | return MaterialRenderers[idx].Name.c_str(); | 2029 | return MaterialRenderers[idx].Name.c_str(); |
2030 | 2030 | ||
2031 | return 0; | 2031 | return 0; |
2032 | } | 2032 | } |
2033 | 2033 | ||
2034 | 2034 | ||
2035 | //! Returns pointer to the IGPUProgrammingServices interface. | 2035 | //! Returns pointer to the IGPUProgrammingServices interface. |
2036 | IGPUProgrammingServices* CNullDriver::getGPUProgrammingServices() | 2036 | IGPUProgrammingServices* CNullDriver::getGPUProgrammingServices() |
2037 | { | 2037 | { |
2038 | return this; | 2038 | return this; |
2039 | } | 2039 | } |
2040 | 2040 | ||
2041 | 2041 | ||
2042 | //! Adds a new material renderer to the VideoDriver, based on a high level shading language. | 2042 | //! Adds a new material renderer to the VideoDriver, based on a high level shading language. |
2043 | s32 CNullDriver::addHighLevelShaderMaterial( | 2043 | s32 CNullDriver::addHighLevelShaderMaterial( |
2044 | const c8* vertexShaderProgram, | 2044 | const c8* vertexShaderProgram, |
2045 | const c8* vertexShaderEntryPointName, | 2045 | const c8* vertexShaderEntryPointName, |
2046 | E_VERTEX_SHADER_TYPE vsCompileTarget, | 2046 | E_VERTEX_SHADER_TYPE vsCompileTarget, |
2047 | const c8* pixelShaderProgram, | 2047 | const c8* pixelShaderProgram, |
2048 | const c8* pixelShaderEntryPointName, | 2048 | const c8* pixelShaderEntryPointName, |
2049 | E_PIXEL_SHADER_TYPE psCompileTarget, | 2049 | E_PIXEL_SHADER_TYPE psCompileTarget, |
2050 | const c8* geometryShaderProgram, | 2050 | const c8* geometryShaderProgram, |
2051 | const c8* geometryShaderEntryPointName, | 2051 | const c8* geometryShaderEntryPointName, |
2052 | E_GEOMETRY_SHADER_TYPE gsCompileTarget, | 2052 | E_GEOMETRY_SHADER_TYPE gsCompileTarget, |
2053 | scene::E_PRIMITIVE_TYPE inType, scene::E_PRIMITIVE_TYPE outType, | 2053 | scene::E_PRIMITIVE_TYPE inType, scene::E_PRIMITIVE_TYPE outType, |
2054 | u32 verticesOut, | 2054 | u32 verticesOut, |
2055 | IShaderConstantSetCallBack* callback, | 2055 | IShaderConstantSetCallBack* callback, |
2056 | E_MATERIAL_TYPE baseMaterial, | 2056 | E_MATERIAL_TYPE baseMaterial, |
2057 | s32 userData, E_GPU_SHADING_LANGUAGE shadingLang) | 2057 | s32 userData, E_GPU_SHADING_LANGUAGE shadingLang) |
2058 | { | 2058 | { |
2059 | os::Printer::log("High level shader materials not available (yet) in this driver, sorry"); | 2059 | os::Printer::log("High level shader materials not available (yet) in this driver, sorry"); |
2060 | return -1; | 2060 | return -1; |
2061 | } | 2061 | } |
2062 | 2062 | ||
2063 | 2063 | ||
2064 | //! Like IGPUProgrammingServices::addShaderMaterial() (look there for a detailed description), | 2064 | //! Like IGPUProgrammingServices::addShaderMaterial() (look there for a detailed description), |
2065 | //! but tries to load the programs from files. | 2065 | //! but tries to load the programs from files. |
2066 | s32 CNullDriver::addHighLevelShaderMaterialFromFiles( | 2066 | s32 CNullDriver::addHighLevelShaderMaterialFromFiles( |
2067 | const io::path& vertexShaderProgramFileName, | 2067 | const io::path& vertexShaderProgramFileName, |
2068 | const c8* vertexShaderEntryPointName, | 2068 | const c8* vertexShaderEntryPointName, |
2069 | E_VERTEX_SHADER_TYPE vsCompileTarget, | 2069 | E_VERTEX_SHADER_TYPE vsCompileTarget, |
2070 | const io::path& pixelShaderProgramFileName, | 2070 | const io::path& pixelShaderProgramFileName, |
2071 | const c8* pixelShaderEntryPointName, | 2071 | const c8* pixelShaderEntryPointName, |
2072 | E_PIXEL_SHADER_TYPE psCompileTarget, | 2072 | E_PIXEL_SHADER_TYPE psCompileTarget, |
2073 | const io::path& geometryShaderProgramFileName, | 2073 | const io::path& geometryShaderProgramFileName, |
2074 | const c8* geometryShaderEntryPointName, | 2074 | const c8* geometryShaderEntryPointName, |
2075 | E_GEOMETRY_SHADER_TYPE gsCompileTarget, | 2075 | E_GEOMETRY_SHADER_TYPE gsCompileTarget, |
2076 | scene::E_PRIMITIVE_TYPE inType, scene::E_PRIMITIVE_TYPE outType, | 2076 | scene::E_PRIMITIVE_TYPE inType, scene::E_PRIMITIVE_TYPE outType, |
2077 | u32 verticesOut, | 2077 | u32 verticesOut, |
2078 | IShaderConstantSetCallBack* callback, | 2078 | IShaderConstantSetCallBack* callback, |
2079 | E_MATERIAL_TYPE baseMaterial, | 2079 | E_MATERIAL_TYPE baseMaterial, |
2080 | s32 userData, E_GPU_SHADING_LANGUAGE shadingLang) | 2080 | s32 userData, E_GPU_SHADING_LANGUAGE shadingLang) |
2081 | { | 2081 | { |
2082 | io::IReadFile* vsfile = 0; | 2082 | io::IReadFile* vsfile = 0; |
2083 | io::IReadFile* psfile = 0; | 2083 | io::IReadFile* psfile = 0; |
2084 | io::IReadFile* gsfile = 0; | 2084 | io::IReadFile* gsfile = 0; |
2085 | 2085 | ||
2086 | if (vertexShaderProgramFileName.size() ) | 2086 | if (vertexShaderProgramFileName.size() ) |
2087 | { | 2087 | { |
2088 | vsfile = FileSystem->createAndOpenFile(vertexShaderProgramFileName); | 2088 | vsfile = FileSystem->createAndOpenFile(vertexShaderProgramFileName); |
2089 | if (!vsfile) | 2089 | if (!vsfile) |
2090 | { | 2090 | { |
2091 | os::Printer::log("Could not open vertex shader program file", | 2091 | os::Printer::log("Could not open vertex shader program file", |
2092 | vertexShaderProgramFileName, ELL_WARNING); | 2092 | vertexShaderProgramFileName, ELL_WARNING); |
2093 | } | 2093 | } |
2094 | } | 2094 | } |
2095 | 2095 | ||
2096 | if (pixelShaderProgramFileName.size() ) | 2096 | if (pixelShaderProgramFileName.size() ) |
2097 | { | 2097 | { |
2098 | psfile = FileSystem->createAndOpenFile(pixelShaderProgramFileName); | 2098 | psfile = FileSystem->createAndOpenFile(pixelShaderProgramFileName); |
2099 | if (!psfile) | 2099 | if (!psfile) |
2100 | { | 2100 | { |
2101 | os::Printer::log("Could not open pixel shader program file", | 2101 | os::Printer::log("Could not open pixel shader program file", |
2102 | pixelShaderProgramFileName, ELL_WARNING); | 2102 | pixelShaderProgramFileName, ELL_WARNING); |
2103 | } | 2103 | } |
2104 | } | 2104 | } |
2105 | 2105 | ||
2106 | if (geometryShaderProgramFileName.size() ) | 2106 | if (geometryShaderProgramFileName.size() ) |
2107 | { | 2107 | { |
2108 | gsfile = FileSystem->createAndOpenFile(geometryShaderProgramFileName); | 2108 | gsfile = FileSystem->createAndOpenFile(geometryShaderProgramFileName); |
2109 | if (!gsfile) | 2109 | if (!gsfile) |
2110 | { | 2110 | { |
2111 | os::Printer::log("Could not open geometry shader program file", | 2111 | os::Printer::log("Could not open geometry shader program file", |
2112 | geometryShaderProgramFileName, ELL_WARNING); | 2112 | geometryShaderProgramFileName, ELL_WARNING); |
2113 | } | 2113 | } |
2114 | } | 2114 | } |
2115 | 2115 | ||
2116 | s32 result = addHighLevelShaderMaterialFromFiles( | 2116 | s32 result = addHighLevelShaderMaterialFromFiles( |
2117 | vsfile, vertexShaderEntryPointName, vsCompileTarget, | 2117 | vsfile, vertexShaderEntryPointName, vsCompileTarget, |
2118 | psfile, pixelShaderEntryPointName, psCompileTarget, | 2118 | psfile, pixelShaderEntryPointName, psCompileTarget, |
2119 | gsfile, geometryShaderEntryPointName, gsCompileTarget, | 2119 | gsfile, geometryShaderEntryPointName, gsCompileTarget, |
2120 | inType, outType, verticesOut, | 2120 | inType, outType, verticesOut, |
2121 | callback, baseMaterial, userData, shadingLang); | 2121 | callback, baseMaterial, userData, shadingLang); |
2122 | 2122 | ||
2123 | if (psfile) | 2123 | if (psfile) |
2124 | psfile->drop(); | 2124 | psfile->drop(); |
2125 | 2125 | ||
2126 | if (vsfile) | 2126 | if (vsfile) |
2127 | vsfile->drop(); | 2127 | vsfile->drop(); |
2128 | 2128 | ||
2129 | if (gsfile) | 2129 | if (gsfile) |
2130 | gsfile->drop(); | 2130 | gsfile->drop(); |
2131 | 2131 | ||
2132 | return result; | 2132 | return result; |
2133 | } | 2133 | } |
2134 | 2134 | ||
2135 | 2135 | ||
2136 | //! Like IGPUProgrammingServices::addShaderMaterial() (look there for a detailed description), | 2136 | //! Like IGPUProgrammingServices::addShaderMaterial() (look there for a detailed description), |
2137 | //! but tries to load the programs from files. | 2137 | //! but tries to load the programs from files. |
2138 | s32 CNullDriver::addHighLevelShaderMaterialFromFiles( | 2138 | s32 CNullDriver::addHighLevelShaderMaterialFromFiles( |
2139 | io::IReadFile* vertexShaderProgram, | 2139 | io::IReadFile* vertexShaderProgram, |
2140 | const c8* vertexShaderEntryPointName, | 2140 | const c8* vertexShaderEntryPointName, |
2141 | E_VERTEX_SHADER_TYPE vsCompileTarget, | 2141 | E_VERTEX_SHADER_TYPE vsCompileTarget, |
2142 | io::IReadFile* pixelShaderProgram, | 2142 | io::IReadFile* pixelShaderProgram, |
2143 | const c8* pixelShaderEntryPointName, | 2143 | const c8* pixelShaderEntryPointName, |
2144 | E_PIXEL_SHADER_TYPE psCompileTarget, | 2144 | E_PIXEL_SHADER_TYPE psCompileTarget, |
2145 | io::IReadFile* geometryShaderProgram, | 2145 | io::IReadFile* geometryShaderProgram, |
2146 | const c8* geometryShaderEntryPointName, | 2146 | const c8* geometryShaderEntryPointName, |
2147 | E_GEOMETRY_SHADER_TYPE gsCompileTarget, | 2147 | E_GEOMETRY_SHADER_TYPE gsCompileTarget, |
2148 | scene::E_PRIMITIVE_TYPE inType, scene::E_PRIMITIVE_TYPE outType, | 2148 | scene::E_PRIMITIVE_TYPE inType, scene::E_PRIMITIVE_TYPE outType, |
2149 | u32 verticesOut, | 2149 | u32 verticesOut, |
2150 | IShaderConstantSetCallBack* callback, | 2150 | IShaderConstantSetCallBack* callback, |
2151 | E_MATERIAL_TYPE baseMaterial, | 2151 | E_MATERIAL_TYPE baseMaterial, |
2152 | s32 userData, E_GPU_SHADING_LANGUAGE shadingLang) | 2152 | s32 userData, E_GPU_SHADING_LANGUAGE shadingLang) |
2153 | { | 2153 | { |
2154 | c8* vs = 0; | 2154 | c8* vs = 0; |
2155 | c8* ps = 0; | 2155 | c8* ps = 0; |
2156 | c8* gs = 0; | 2156 | c8* gs = 0; |
2157 | 2157 | ||
2158 | if (vertexShaderProgram) | 2158 | if (vertexShaderProgram) |
2159 | { | 2159 | { |
2160 | const long size = vertexShaderProgram->getSize(); | 2160 | const long size = vertexShaderProgram->getSize(); |
2161 | if (size) | 2161 | if (size) |
2162 | { | 2162 | { |
2163 | vs = new c8[size+1]; | 2163 | vs = new c8[size+1]; |
2164 | vertexShaderProgram->read(vs, size); | 2164 | vertexShaderProgram->read(vs, size); |
2165 | vs[size] = 0; | 2165 | vs[size] = 0; |
2166 | } | 2166 | } |
2167 | } | 2167 | } |
2168 | 2168 | ||
2169 | if (pixelShaderProgram) | 2169 | if (pixelShaderProgram) |
2170 | { | 2170 | { |
2171 | const long size = pixelShaderProgram->getSize(); | 2171 | const long size = pixelShaderProgram->getSize(); |
2172 | if (size) | 2172 | if (size) |
2173 | { | 2173 | { |
2174 | // if both handles are the same we must reset the file | 2174 | // if both handles are the same we must reset the file |
2175 | if (pixelShaderProgram==vertexShaderProgram) | 2175 | if (pixelShaderProgram==vertexShaderProgram) |
2176 | pixelShaderProgram->seek(0); | 2176 | pixelShaderProgram->seek(0); |
2177 | ps = new c8[size+1]; | 2177 | ps = new c8[size+1]; |
2178 | pixelShaderProgram->read(ps, size); | 2178 | pixelShaderProgram->read(ps, size); |
2179 | ps[size] = 0; | 2179 | ps[size] = 0; |
2180 | } | 2180 | } |
2181 | } | 2181 | } |
2182 | 2182 | ||
2183 | if (geometryShaderProgram) | 2183 | if (geometryShaderProgram) |
2184 | { | 2184 | { |
2185 | const long size = geometryShaderProgram->getSize(); | 2185 | const long size = geometryShaderProgram->getSize(); |
2186 | if (size) | 2186 | if (size) |
2187 | { | 2187 | { |
2188 | // if both handles are the same we must reset the file | 2188 | // if both handles are the same we must reset the file |
2189 | if ((geometryShaderProgram==vertexShaderProgram) || | 2189 | if ((geometryShaderProgram==vertexShaderProgram) || |
2190 | (geometryShaderProgram==pixelShaderProgram)) | 2190 | (geometryShaderProgram==pixelShaderProgram)) |
2191 | geometryShaderProgram->seek(0); | 2191 | geometryShaderProgram->seek(0); |
2192 | gs = new c8[size+1]; | 2192 | gs = new c8[size+1]; |
2193 | geometryShaderProgram->read(gs, size); | 2193 | geometryShaderProgram->read(gs, size); |
2194 | gs[size] = 0; | 2194 | gs[size] = 0; |
2195 | } | 2195 | } |
2196 | } | 2196 | } |
2197 | 2197 | ||
2198 | s32 result = this->addHighLevelShaderMaterial( | 2198 | s32 result = this->addHighLevelShaderMaterial( |
2199 | vs, vertexShaderEntryPointName, vsCompileTarget, | 2199 | vs, vertexShaderEntryPointName, vsCompileTarget, |
2200 | ps, pixelShaderEntryPointName, psCompileTarget, | 2200 | ps, pixelShaderEntryPointName, psCompileTarget, |
2201 | gs, geometryShaderEntryPointName, gsCompileTarget, | 2201 | gs, geometryShaderEntryPointName, gsCompileTarget, |
2202 | inType, outType, verticesOut, | 2202 | inType, outType, verticesOut, |
2203 | callback, baseMaterial, userData, shadingLang); | 2203 | callback, baseMaterial, userData, shadingLang); |
2204 | 2204 | ||
2205 | delete [] vs; | 2205 | delete [] vs; |
2206 | delete [] ps; | 2206 | delete [] ps; |
2207 | delete [] gs; | 2207 | delete [] gs; |
2208 | 2208 | ||
2209 | return result; | 2209 | return result; |
2210 | } | 2210 | } |
2211 | 2211 | ||
2212 | 2212 | ||
2213 | //! Adds a new material renderer to the VideoDriver, using pixel and/or | 2213 | //! Adds a new material renderer to the VideoDriver, using pixel and/or |
2214 | //! vertex shaders to render geometry. | 2214 | //! vertex shaders to render geometry. |
2215 | s32 CNullDriver::addShaderMaterial(const c8* vertexShaderProgram, | 2215 | s32 CNullDriver::addShaderMaterial(const c8* vertexShaderProgram, |
2216 | const c8* pixelShaderProgram, | 2216 | const c8* pixelShaderProgram, |
2217 | IShaderConstantSetCallBack* callback, | 2217 | IShaderConstantSetCallBack* callback, |
2218 | E_MATERIAL_TYPE baseMaterial, | 2218 | E_MATERIAL_TYPE baseMaterial, |
2219 | s32 userData) | 2219 | s32 userData) |
2220 | { | 2220 | { |
2221 | os::Printer::log("Shader materials not implemented yet in this driver, sorry."); | 2221 | os::Printer::log("Shader materials not implemented yet in this driver, sorry."); |
2222 | return -1; | 2222 | return -1; |
2223 | } | 2223 | } |
2224 | 2224 | ||
2225 | 2225 | ||
2226 | //! Like IGPUProgrammingServices::addShaderMaterial(), but tries to load the | 2226 | //! Like IGPUProgrammingServices::addShaderMaterial(), but tries to load the |
2227 | //! programs from files. | 2227 | //! programs from files. |
2228 | s32 CNullDriver::addShaderMaterialFromFiles(io::IReadFile* vertexShaderProgram, | 2228 | s32 CNullDriver::addShaderMaterialFromFiles(io::IReadFile* vertexShaderProgram, |
2229 | io::IReadFile* pixelShaderProgram, | 2229 | io::IReadFile* pixelShaderProgram, |
2230 | IShaderConstantSetCallBack* callback, | 2230 | IShaderConstantSetCallBack* callback, |
2231 | E_MATERIAL_TYPE baseMaterial, | 2231 | E_MATERIAL_TYPE baseMaterial, |
2232 | s32 userData) | 2232 | s32 userData) |
2233 | { | 2233 | { |
2234 | c8* vs = 0; | 2234 | c8* vs = 0; |
2235 | c8* ps = 0; | 2235 | c8* ps = 0; |
2236 | 2236 | ||
2237 | if (vertexShaderProgram) | 2237 | if (vertexShaderProgram) |
2238 | { | 2238 | { |
2239 | const long size = vertexShaderProgram->getSize(); | 2239 | const long size = vertexShaderProgram->getSize(); |
2240 | if (size) | 2240 | if (size) |
2241 | { | 2241 | { |
2242 | vs = new c8[size+1]; | 2242 | vs = new c8[size+1]; |
2243 | vertexShaderProgram->read(vs, size); | 2243 | vertexShaderProgram->read(vs, size); |
2244 | vs[size] = 0; | 2244 | vs[size] = 0; |
2245 | } | 2245 | } |
2246 | } | 2246 | } |
2247 | 2247 | ||
2248 | if (pixelShaderProgram) | 2248 | if (pixelShaderProgram) |
2249 | { | 2249 | { |
2250 | const long size = pixelShaderProgram->getSize(); | 2250 | const long size = pixelShaderProgram->getSize(); |
2251 | if (size) | 2251 | if (size) |
2252 | { | 2252 | { |
2253 | ps = new c8[size+1]; | 2253 | ps = new c8[size+1]; |
2254 | pixelShaderProgram->read(ps, size); | 2254 | pixelShaderProgram->read(ps, size); |
2255 | ps[size] = 0; | 2255 | ps[size] = 0; |
2256 | } | 2256 | } |
2257 | } | 2257 | } |
2258 | 2258 | ||
2259 | s32 result = addShaderMaterial(vs, ps, callback, baseMaterial, userData); | 2259 | s32 result = addShaderMaterial(vs, ps, callback, baseMaterial, userData); |
2260 | 2260 | ||
2261 | delete [] vs; | 2261 | delete [] vs; |
2262 | delete [] ps; | 2262 | delete [] ps; |
2263 | 2263 | ||
2264 | return result; | 2264 | return result; |
2265 | } | 2265 | } |
2266 | 2266 | ||
2267 | 2267 | ||
2268 | //! Like IGPUProgrammingServices::addShaderMaterial(), but tries to load the | 2268 | //! Like IGPUProgrammingServices::addShaderMaterial(), but tries to load the |
2269 | //! programs from files. | 2269 | //! programs from files. |
2270 | s32 CNullDriver::addShaderMaterialFromFiles(const io::path& vertexShaderProgramFileName, | 2270 | s32 CNullDriver::addShaderMaterialFromFiles(const io::path& vertexShaderProgramFileName, |
2271 | const io::path& pixelShaderProgramFileName, | 2271 | const io::path& pixelShaderProgramFileName, |
2272 | IShaderConstantSetCallBack* callback, | 2272 | IShaderConstantSetCallBack* callback, |
2273 | E_MATERIAL_TYPE baseMaterial, | 2273 | E_MATERIAL_TYPE baseMaterial, |
2274 | s32 userData) | 2274 | s32 userData) |
2275 | { | 2275 | { |
2276 | io::IReadFile* vsfile = 0; | 2276 | io::IReadFile* vsfile = 0; |
2277 | io::IReadFile* psfile = 0; | 2277 | io::IReadFile* psfile = 0; |
2278 | 2278 | ||
2279 | if (vertexShaderProgramFileName.size()) | 2279 | if (vertexShaderProgramFileName.size()) |
2280 | { | 2280 | { |
2281 | vsfile = FileSystem->createAndOpenFile(vertexShaderProgramFileName); | 2281 | vsfile = FileSystem->createAndOpenFile(vertexShaderProgramFileName); |
2282 | if (!vsfile) | 2282 | if (!vsfile) |
2283 | { | 2283 | { |
2284 | os::Printer::log("Could not open vertex shader program file", | 2284 | os::Printer::log("Could not open vertex shader program file", |
2285 | vertexShaderProgramFileName, ELL_WARNING); | 2285 | vertexShaderProgramFileName, ELL_WARNING); |
2286 | return -1; | 2286 | return -1; |
2287 | } | 2287 | } |
2288 | } | 2288 | } |
2289 | 2289 | ||
2290 | if (pixelShaderProgramFileName.size()) | 2290 | if (pixelShaderProgramFileName.size()) |
2291 | { | 2291 | { |
2292 | psfile = FileSystem->createAndOpenFile(pixelShaderProgramFileName); | 2292 | psfile = FileSystem->createAndOpenFile(pixelShaderProgramFileName); |
2293 | if (!psfile) | 2293 | if (!psfile) |
2294 | { | 2294 | { |
2295 | os::Printer::log("Could not open pixel shader program file", | 2295 | os::Printer::log("Could not open pixel shader program file", |
2296 | pixelShaderProgramFileName, ELL_WARNING); | 2296 | pixelShaderProgramFileName, ELL_WARNING); |
2297 | if (vsfile) | 2297 | if (vsfile) |
2298 | vsfile->drop(); | 2298 | vsfile->drop(); |
2299 | return -1; | 2299 | return -1; |
2300 | } | 2300 | } |
2301 | } | 2301 | } |
2302 | 2302 | ||
2303 | s32 result = addShaderMaterialFromFiles(vsfile, psfile, callback, | 2303 | s32 result = addShaderMaterialFromFiles(vsfile, psfile, callback, |
2304 | baseMaterial, userData); | 2304 | baseMaterial, userData); |
2305 | 2305 | ||
2306 | if (psfile) | 2306 | if (psfile) |
2307 | psfile->drop(); | 2307 | psfile->drop(); |
2308 | 2308 | ||
2309 | if (vsfile) | 2309 | if (vsfile) |
2310 | vsfile->drop(); | 2310 | vsfile->drop(); |
2311 | 2311 | ||
2312 | return result; | 2312 | return result; |
2313 | } | 2313 | } |
2314 | 2314 | ||
2315 | 2315 | ||
2316 | //! Creates a render target texture. | 2316 | //! Creates a render target texture. |
2317 | ITexture* CNullDriver::addRenderTargetTexture(const core::dimension2d<u32>& size, | 2317 | ITexture* CNullDriver::addRenderTargetTexture(const core::dimension2d<u32>& size, |
2318 | const io::path&name, const ECOLOR_FORMAT format) | 2318 | const io::path&name, const ECOLOR_FORMAT format) |
2319 | { | 2319 | { |
2320 | return 0; | 2320 | return 0; |
2321 | } | 2321 | } |
2322 | 2322 | ||
2323 | 2323 | ||
2324 | //! Clears the ZBuffer. | 2324 | //! Clears the ZBuffer. |
2325 | void CNullDriver::clearZBuffer() | 2325 | void CNullDriver::clearZBuffer() |
2326 | { | 2326 | { |
2327 | } | 2327 | } |
2328 | 2328 | ||
2329 | 2329 | ||
2330 | //! Returns a pointer to the mesh manipulator. | 2330 | //! Returns a pointer to the mesh manipulator. |
2331 | scene::IMeshManipulator* CNullDriver::getMeshManipulator() | 2331 | scene::IMeshManipulator* CNullDriver::getMeshManipulator() |
2332 | { | 2332 | { |
2333 | return MeshManipulator; | 2333 | return MeshManipulator; |
2334 | } | 2334 | } |
2335 | 2335 | ||
2336 | 2336 | ||
2337 | //! Returns an image created from the last rendered frame. | 2337 | //! Returns an image created from the last rendered frame. |
2338 | IImage* CNullDriver::createScreenShot(video::ECOLOR_FORMAT format, video::E_RENDER_TARGET target) | 2338 | IImage* CNullDriver::createScreenShot(video::ECOLOR_FORMAT format, video::E_RENDER_TARGET target) |
2339 | { | 2339 | { |
2340 | return 0; | 2340 | return 0; |
2341 | } | 2341 | } |
2342 | 2342 | ||
2343 | 2343 | ||
2344 | // prints renderer version | 2344 | // prints renderer version |
2345 | void CNullDriver::printVersion() | 2345 | void CNullDriver::printVersion() |
2346 | { | 2346 | { |
2347 | core::stringw namePrint = L"Using renderer: "; | 2347 | core::stringw namePrint = L"Using renderer: "; |
2348 | namePrint += getName(); | 2348 | namePrint += getName(); |
2349 | os::Printer::log(namePrint.c_str(), ELL_INFORMATION); | 2349 | os::Printer::log(namePrint.c_str(), ELL_INFORMATION); |
2350 | } | 2350 | } |
2351 | 2351 | ||
2352 | 2352 | ||
2353 | //! creates a video driver | 2353 | //! creates a video driver |
2354 | IVideoDriver* createNullDriver(io::IFileSystem* io, const core::dimension2d<u32>& screenSize) | 2354 | IVideoDriver* createNullDriver(io::IFileSystem* io, const core::dimension2d<u32>& screenSize) |
2355 | { | 2355 | { |
2356 | CNullDriver* nullDriver = new CNullDriver(io, screenSize); | 2356 | CNullDriver* nullDriver = new CNullDriver(io, screenSize); |
2357 | 2357 | ||
2358 | // create empty material renderers | 2358 | // create empty material renderers |
2359 | for(u32 i=0; sBuiltInMaterialTypeNames[i]; ++i) | 2359 | for(u32 i=0; sBuiltInMaterialTypeNames[i]; ++i) |
2360 | { | 2360 | { |
2361 | IMaterialRenderer* imr = new IMaterialRenderer(); | 2361 | IMaterialRenderer* imr = new IMaterialRenderer(); |
2362 | nullDriver->addMaterialRenderer(imr); | 2362 | nullDriver->addMaterialRenderer(imr); |
2363 | imr->drop(); | 2363 | imr->drop(); |
2364 | } | 2364 | } |
2365 | 2365 | ||
2366 | return nullDriver; | 2366 | return nullDriver; |
2367 | } | 2367 | } |
2368 | 2368 | ||
2369 | 2369 | ||
2370 | //! Set/unset a clipping plane. | 2370 | //! Set/unset a clipping plane. |
2371 | //! There are at least 6 clipping planes available for the user to set at will. | 2371 | //! There are at least 6 clipping planes available for the user to set at will. |
2372 | //! \param index: The plane index. Must be between 0 and MaxUserClipPlanes. | 2372 | //! \param index: The plane index. Must be between 0 and MaxUserClipPlanes. |
2373 | //! \param plane: The plane itself. | 2373 | //! \param plane: The plane itself. |
2374 | //! \param enable: If true, enable the clipping plane else disable it. | 2374 | //! \param enable: If true, enable the clipping plane else disable it. |
2375 | bool CNullDriver::setClipPlane(u32 index, const core::plane3df& plane, bool enable) | 2375 | bool CNullDriver::setClipPlane(u32 index, const core::plane3df& plane, bool enable) |
2376 | { | 2376 | { |
2377 | return false; | 2377 | return false; |
2378 | } | 2378 | } |
2379 | 2379 | ||
2380 | 2380 | ||
2381 | //! Enable/disable a clipping plane. | 2381 | //! Enable/disable a clipping plane. |
2382 | void CNullDriver::enableClipPlane(u32 index, bool enable) | 2382 | void CNullDriver::enableClipPlane(u32 index, bool enable) |
2383 | { | 2383 | { |
2384 | // not necessary | 2384 | // not necessary |
2385 | } | 2385 | } |
2386 | 2386 | ||
2387 | 2387 | ||
2388 | ITexture* CNullDriver::createRenderTargetTexture(const core::dimension2d<u32>& size, | 2388 | ITexture* CNullDriver::createRenderTargetTexture(const core::dimension2d<u32>& size, |
2389 | const c8* name) | 2389 | const c8* name) |
2390 | { | 2390 | { |
2391 | os::Printer::log("createRenderTargetTexture is deprecated, use addRenderTargetTexture instead"); | 2391 | os::Printer::log("createRenderTargetTexture is deprecated, use addRenderTargetTexture instead"); |
2392 | ITexture* tex = addRenderTargetTexture(size, name); | 2392 | ITexture* tex = addRenderTargetTexture(size, name); |
2393 | tex->grab(); | 2393 | tex->grab(); |
2394 | return tex; | 2394 | return tex; |
2395 | } | 2395 | } |
2396 | 2396 | ||
2397 | 2397 | ||
2398 | void CNullDriver::setMinHardwareBufferVertexCount(u32 count) | 2398 | void CNullDriver::setMinHardwareBufferVertexCount(u32 count) |
2399 | { | 2399 | { |
2400 | MinVertexCountForVBO = count; | 2400 | MinVertexCountForVBO = count; |
2401 | } | 2401 | } |
2402 | 2402 | ||
2403 | 2403 | ||
2404 | SOverrideMaterial& CNullDriver::getOverrideMaterial() | 2404 | SOverrideMaterial& CNullDriver::getOverrideMaterial() |
2405 | { | 2405 | { |
2406 | return OverrideMaterial; | 2406 | return OverrideMaterial; |
2407 | } | 2407 | } |
2408 | 2408 | ||
2409 | 2409 | ||
2410 | //! Get the 2d override material for altering its values | 2410 | //! Get the 2d override material for altering its values |
2411 | SMaterial& CNullDriver::getMaterial2D() | 2411 | SMaterial& CNullDriver::getMaterial2D() |
2412 | { | 2412 | { |
2413 | return OverrideMaterial2D; | 2413 | return OverrideMaterial2D; |
2414 | } | 2414 | } |
2415 | 2415 | ||
2416 | 2416 | ||
2417 | //! Enable the 2d override material | 2417 | //! Enable the 2d override material |
2418 | void CNullDriver::enableMaterial2D(bool enable) | 2418 | void CNullDriver::enableMaterial2D(bool enable) |
2419 | { | 2419 | { |
2420 | OverrideMaterial2DEnabled=enable; | 2420 | OverrideMaterial2DEnabled=enable; |
2421 | } | 2421 | } |
2422 | 2422 | ||
2423 | 2423 | ||
2424 | core::dimension2du CNullDriver::getMaxTextureSize() const | 2424 | core::dimension2du CNullDriver::getMaxTextureSize() const |
2425 | { | 2425 | { |
2426 | return core::dimension2du(0x10000,0x10000); // maybe large enough | 2426 | return core::dimension2du(0x10000,0x10000); // maybe large enough |
2427 | } | 2427 | } |
2428 | 2428 | ||
2429 | 2429 | ||
2430 | //! Color conversion convenience function | 2430 | //! Color conversion convenience function |
2431 | /** Convert an image (as array of pixels) from source to destination | 2431 | /** Convert an image (as array of pixels) from source to destination |
2432 | array, thereby converting the color format. The pixel size is | 2432 | array, thereby converting the color format. The pixel size is |
2433 | determined by the color formats. | 2433 | determined by the color formats. |
2434 | \param sP Pointer to source | 2434 | \param sP Pointer to source |
2435 | \param sF Color format of source | 2435 | \param sF Color format of source |
2436 | \param sN Number of pixels to convert, both array must be large enough | 2436 | \param sN Number of pixels to convert, both array must be large enough |
2437 | \param dP Pointer to destination | 2437 | \param dP Pointer to destination |
2438 | \param dF Color format of destination | 2438 | \param dF Color format of destination |
2439 | */ | 2439 | */ |
2440 | void CNullDriver::convertColor(const void* sP, ECOLOR_FORMAT sF, s32 sN, | 2440 | void CNullDriver::convertColor(const void* sP, ECOLOR_FORMAT sF, s32 sN, |
2441 | void* dP, ECOLOR_FORMAT dF) const | 2441 | void* dP, ECOLOR_FORMAT dF) const |
2442 | { | 2442 | { |
2443 | video::CColorConverter::convert_viaFormat(sP, sF, sN, dP, dF); | 2443 | video::CColorConverter::convert_viaFormat(sP, sF, sN, dP, dF); |
2444 | } | 2444 | } |
2445 | 2445 | ||
2446 | 2446 | ||
2447 | } // end namespace | 2447 | } // end namespace |
2448 | } // end namespace | 2448 | } // end namespace |