1//************************************ bs::framework - Copyright 2018 Marko Pintera **************************************//
2//*********** Licensed under the MIT license. See LICENSE.md for full terms. This notice is not to be removed. ***********//
3#include "Resources/BsBuiltinResources.h"
4#include "GUI/BsGUILabel.h"
5#include "Image/BsSpriteTexture.h"
6#include "Text/BsFont.h"
7#include "Image/BsTexture.h"
8#include "Importer/BsImporter.h"
9#include "Resources/BsResources.h"
10#include "Resources/BsBuiltinResourcesHelper.h"
11#include "Resources/BsResourceManifest.h"
12#include "Material/BsShader.h"
13#include "Material/BsMaterial.h"
14#include "Reflection/BsRTTIType.h"
15#include "FileSystem/BsFileSystem.h"
16#include "CoreThread/BsCoreThread.h"
17#include "Utility/BsShapeMeshes3D.h"
18#include "Mesh/BsMesh.h"
19
20using json = nlohmann::json;
21
22namespace bs
23{
24 constexpr const char* BuiltinResources::IconTextureName;
25 constexpr const char* BuiltinResources::MultiLineLabelStyle;
26
27 /************************************************************************/
28 /* GUI TEXTURES */
29 /************************************************************************/
30
31 const String BuiltinResources::WhiteTex = u8"White.psd";
32
33 /************************************************************************/
34 /* CURSOR TEXTURES */
35 /************************************************************************/
36
37 const String BuiltinResources::CursorArrowTex = u8"Arrow.psd";
38 const String BuiltinResources::CursorArrowDragTex = u8"ArrowDrag.psd";
39 const String BuiltinResources::CursorArrowLeftRightTex = u8"ArrowLeftRight.psd";
40 const String BuiltinResources::CursorIBeamTex = u8"IBeam.psd";
41 const String BuiltinResources::CursorDenyTex = u8"Deny.psd";
42 const String BuiltinResources::CursorWaitTex = u8"Wait.psd";
43 const String BuiltinResources::CursorSizeNESWTex = u8"SizeNESW.psd";
44 const String BuiltinResources::CursorSizeNSTex = u8"SizeNS.psd";
45 const String BuiltinResources::CursorSizeNWSETex = u8"SizeNWSE.psd";
46 const String BuiltinResources::CursorSizeWETex = u8"SizeWE.psd";
47
48 const Vector2I BuiltinResources::CursorArrowHotspot = Vector2I(10, 8);
49 const Vector2I BuiltinResources::CursorArrowDragHotspot = Vector2I(8, 4);
50 const Vector2I BuiltinResources::CursorArrowLeftRightHotspot = Vector2I(13, 9);
51 const Vector2I BuiltinResources::CursorIBeamHotspot = Vector2I(16, 15);
52 const Vector2I BuiltinResources::CursorDenyHotspot = Vector2I(15, 15);
53 const Vector2I BuiltinResources::CursorWaitHotspot = Vector2I(15, 15);
54 const Vector2I BuiltinResources::CursorSizeNESWHotspot = Vector2I(16, 15);
55 const Vector2I BuiltinResources::CursorSizeNSHotspot = Vector2I(16, 15);
56 const Vector2I BuiltinResources::CursorSizeNWSEHotspot = Vector2I(16, 15);
57 const Vector2I BuiltinResources::CursorSizeWEHotspot = Vector2I(16, 15);
58
59 /************************************************************************/
60 /* SHADERS */
61 /************************************************************************/
62
63 const String BuiltinResources::ShaderSpriteTextFile = u8"SpriteText.bsl";
64 const String BuiltinResources::ShaderSpriteImageFile = u8"SpriteImage.bsl";
65 const String BuiltinResources::ShaderSpriteLineFile = u8"SpriteLine.bsl";
66
67 constexpr const char* ShaderDiffuseFile = u8"Diffuse.bsl";
68 constexpr const char* ShaderTransparentFile = u8"Transparent.bsl";
69 constexpr const char* ShaderParticlesUnlitFile = u8"ParticlesUnlit.bsl";
70 constexpr const char* ShaderParticlesLitFile = u8"ParticlesLit.bsl";
71 constexpr const char* ShaderParticlesLitOpaqueFile = u8"ParticlesLitOpaque.bsl";
72 constexpr const char* ShaderDecalFile = u8"Decal.bsl";
73
74 BuiltinResources::~BuiltinResources()
75 {
76 mCursorArrow = nullptr;
77 mCursorArrowDrag = nullptr;
78 mCursorArrowLeftRight = nullptr;
79 mCursorIBeam = nullptr;
80 mCursorDeny = nullptr;
81 mCursorWait = nullptr;
82 mCursorSizeNESW = nullptr;
83 mCursorSizeNS = nullptr;
84 mCursorSizeNWSE = nullptr;
85 mCursorSizeWE = nullptr;
86 mFrameworkIcon = nullptr;
87 }
88
89 BuiltinResources::BuiltinResources()
90 {
91 // Set up paths
92 mBuiltinRawDataFolder = Paths::getDataPath() + u8"Raw/";
93
94 mBuiltinDataFolder = Paths::getDataPath();
95 mEngineSkinSpritesFolder = mBuiltinDataFolder + SKIN_FOLDER + SPRITE_FOLDER;
96 mEngineShaderFolder = mBuiltinDataFolder + SHADER_FOLDER;
97 mEngineMeshFolder = mBuiltinDataFolder + MESH_FOLDER;
98 mEngineCursorFolder = mBuiltinDataFolder + CURSOR_FOLDER;
99
100 ResourceManifestPath = mBuiltinDataFolder + "ResourceManifest.asset";
101
102 // Load manifest
103 if (FileSystem::exists(ResourceManifestPath))
104 mResourceManifest = ResourceManifest::load(ResourceManifestPath, mBuiltinDataFolder);
105
106 if (mResourceManifest == nullptr)
107 mResourceManifest = ResourceManifest::create("BuiltinResources");
108
109 gResources().registerResourceManifest(mResourceManifest);
110
111 // Load basic resources
112 mShaderSpriteText = getShader(ShaderSpriteTextFile);
113 mShaderSpriteImage = getShader(ShaderSpriteImageFile);
114 mShaderSpriteLine = getShader(ShaderSpriteLineFile);
115 mShaderDiffuse = getShader(ShaderDiffuseFile);
116 mShaderTransparent = getShader(ShaderTransparentFile);
117 mShaderParticlesUnlit = getShader(ShaderParticlesUnlitFile);
118 mShaderParticlesLit = getShader(ShaderParticlesLitFile);
119 mShaderParticlesLitOpaque = getShader(ShaderParticlesLitOpaqueFile);
120 mShaderDecal = getShader(ShaderDecalFile);
121
122 SPtr<PixelData> dummyPixelData = PixelData::create(2, 2, 1, PF_RGBA8);
123
124 dummyPixelData->setColorAt(Color::Red, 0, 0);
125 dummyPixelData->setColorAt(Color::Red, 0, 1);
126 dummyPixelData->setColorAt(Color::Red, 1, 0);
127 dummyPixelData->setColorAt(Color::Red, 1, 1);
128
129 mDummyTexture = Texture::create(dummyPixelData);
130
131 mWhiteSpriteTexture = getSkinTexture(WhiteTex);
132 mDummySpriteTexture = SpriteTexture::create(mDummyTexture);
133
134 mFont = gResources().load<Font>(mBuiltinDataFolder + (String(DEFAULT_FONT_NAME) + u8".asset"));
135 mSkin = gResources().load<GUISkin>(mBuiltinDataFolder + (String(GUI_SKIN_FILE) + u8".json.asset"));
136 mEmptySkin = GUISkin::create();
137
138 /************************************************************************/
139 /* CURSOR */
140 /************************************************************************/
141
142 HTexture cursorArrowTex = getCursorTexture(CursorArrowTex);
143 HTexture cursorArrowDragTex = getCursorTexture(CursorArrowDragTex);
144 HTexture cursorArrowLeftRightTex = getCursorTexture(CursorArrowLeftRightTex);
145 HTexture cursorIBeamTex = getCursorTexture(CursorIBeamTex);
146 HTexture cursorDenyTex = getCursorTexture(CursorDenyTex);
147 HTexture cursorWaitTex = getCursorTexture(CursorWaitTex);
148 HTexture cursorSizeNESWTex = getCursorTexture(CursorSizeNESWTex);
149 HTexture cursorSizeNSTex = getCursorTexture(CursorSizeNSTex);
150 HTexture cursorSizeNWSETex = getCursorTexture(CursorSizeNWSETex);
151 HTexture cursorSizeWETex = getCursorTexture(CursorSizeWETex);
152
153 mCursorArrow = cursorArrowTex->getProperties().allocBuffer(0, 0);
154 cursorArrowTex->readData(mCursorArrow);
155
156 mCursorArrowDrag = cursorArrowDragTex->getProperties().allocBuffer(0, 0);
157 cursorArrowDragTex->readData(mCursorArrowDrag);
158
159 mCursorArrowLeftRight = cursorArrowLeftRightTex->getProperties().allocBuffer(0, 0);
160 cursorArrowLeftRightTex->readData(mCursorArrowLeftRight);
161
162 mCursorIBeam = cursorIBeamTex->getProperties().allocBuffer(0, 0);
163 cursorIBeamTex->readData(mCursorIBeam);
164
165 mCursorDeny = cursorDenyTex->getProperties().allocBuffer(0, 0);
166 cursorDenyTex->readData(mCursorDeny);
167
168 mCursorWait = cursorWaitTex->getProperties().allocBuffer(0, 0);
169 cursorWaitTex->readData(mCursorWait);
170
171 mCursorSizeNESW = cursorSizeNESWTex->getProperties().allocBuffer(0, 0);
172 cursorSizeNESWTex->readData(mCursorSizeNESW);
173
174 mCursorSizeNS = cursorSizeNSTex->getProperties().allocBuffer(0, 0);
175 cursorSizeNSTex->readData(mCursorSizeNS);
176
177 mCursorSizeNWSE = cursorSizeNWSETex->getProperties().allocBuffer(0, 0);
178 cursorSizeNWSETex->readData(mCursorSizeNWSE);
179
180 mCursorSizeWE = cursorSizeWETex->getProperties().allocBuffer(0, 0);
181 cursorSizeWETex->readData(mCursorSizeWE);
182
183 /************************************************************************/
184 /* ICON */
185 /************************************************************************/
186
187 Path iconPath = mBuiltinDataFolder + ICON_FOLDER;
188 iconPath.append(String(IconTextureName) + u8".asset");
189
190 HTexture iconTex = gResources().load<Texture>(iconPath);
191
192 mFrameworkIcon = iconTex->getProperties().allocBuffer(0, 0);
193 iconTex->readData(mFrameworkIcon);
194
195 gCoreThread().submit(true);
196 }
197
198 HSpriteTexture BuiltinResources::getSkinTexture(const String& name) const
199 {
200 Path texturePath = mEngineSkinSpritesFolder;
201 texturePath.append(u8"sprite_" + name + u8".asset");
202
203 return gResources().load<SpriteTexture>(texturePath);
204 }
205
206 HShader BuiltinResources::getShader(const Path& path) const
207 {
208 Path programPath = mEngineShaderFolder;
209 programPath.append(path);
210 programPath.setExtension(programPath.getExtension() + ".asset");
211
212 return gResources().load<Shader>(programPath);
213 }
214
215 HTexture BuiltinResources::getCursorTexture(const String& name) const
216 {
217 Path cursorPath = mEngineCursorFolder;
218 cursorPath.append(name + u8".asset");
219
220 return gResources().load<Texture>(cursorPath);
221 }
222
223 const PixelData& BuiltinResources::getCursorArrow(Vector2I& hotSpot)
224 {
225 hotSpot = CursorArrowHotspot;
226 return *mCursorArrow.get();
227 }
228
229 const PixelData& BuiltinResources::getCursorArrowDrag(Vector2I& hotSpot)
230 {
231 hotSpot = CursorArrowDragHotspot;
232 return *mCursorArrowDrag.get();
233 }
234
235 const PixelData& BuiltinResources::getCursorWait(Vector2I& hotSpot)
236 {
237 hotSpot = CursorWaitHotspot;
238 return *mCursorWait.get();
239 }
240
241 const PixelData& BuiltinResources::getCursorIBeam(Vector2I& hotSpot)
242 {
243 hotSpot = CursorIBeamHotspot;
244 return *mCursorIBeam.get();
245 }
246
247 const PixelData& BuiltinResources::getCursorSizeNESW(Vector2I& hotSpot)
248 {
249 hotSpot = CursorSizeNESWHotspot;
250 return *mCursorSizeNESW.get();
251 }
252
253 const PixelData& BuiltinResources::getCursorSizeNS(Vector2I& hotSpot)
254 {
255 hotSpot = CursorSizeNSHotspot;
256 return *mCursorSizeNS.get();
257 }
258
259 const PixelData& BuiltinResources::getCursorSizeNWSE(Vector2I& hotSpot)
260 {
261 hotSpot = CursorSizeNWSEHotspot;
262 return *mCursorSizeNWSE.get();
263 }
264
265 const PixelData& BuiltinResources::getCursorSizeWE(Vector2I& hotSpot)
266 {
267 hotSpot = CursorSizeWEHotspot;
268 return *mCursorSizeWE.get();
269 }
270
271 const PixelData& BuiltinResources::getCursorDeny(Vector2I& hotSpot)
272 {
273 hotSpot = CursorDenyHotspot;
274 return *mCursorDeny.get();
275 }
276
277 const PixelData& BuiltinResources::getCursorMoveLeftRight(Vector2I& hotSpot)
278 {
279 hotSpot = CursorArrowLeftRightHotspot;
280 return *mCursorArrowLeftRight.get();
281 }
282
283 const PixelData& BuiltinResources::getFrameworkIcon()
284 {
285 return *mFrameworkIcon.get();
286 }
287
288 Path BuiltinResources::getRawShaderFolder()
289 {
290 return Paths::getDataPath() + "Raw/" + SHADER_FOLDER;
291 }
292
293 Path BuiltinResources::getShaderIncludeFolder()
294 {
295 return Paths::getDataPath() + SHADER_INCLUDE_FOLDER;
296 }
297
298 Path BuiltinResources::getIconFolder()
299 {
300 return Paths::getDataPath() + ICON_FOLDER;
301 }
302
303#if BS_IS_BANSHEE3D || defined BS_IS_ASSET_TOOL
304 Path BuiltinResources::getEditorShaderIncludeFolder()
305 {
306 return Paths::getEditorDataPath() + SHADER_INCLUDE_FOLDER;
307 }
308#endif
309
310 HMesh BuiltinResources::getMesh(BuiltinMesh mesh) const
311 {
312 Path meshPath = mEngineMeshFolder;
313
314 switch (mesh)
315 {
316 case BuiltinMesh::Box:
317 meshPath.append(MESH_BOX_FILE);
318 break;
319 case BuiltinMesh::Sphere:
320 meshPath.append(MESH_SPHERE_FILE);
321 break;
322 case BuiltinMesh::Cone:
323 meshPath.append(MESH_CONE_FILE);
324 break;
325 case BuiltinMesh::Cylinder:
326 meshPath.append(MESH_CYLINDER_FILE);
327 break;
328 case BuiltinMesh::Quad:
329 meshPath.append(MESH_QUAD_FILE);
330 break;
331 case BuiltinMesh::Disc:
332 meshPath.append(MESH_DISC_FILE);
333 break;
334 }
335
336 return gResources().load<Mesh>(meshPath);
337 }
338
339 HShader BuiltinResources::getBuiltinShader(BuiltinShader type) const
340 {
341 switch(type)
342 {
343 case BuiltinShader::Standard:
344 return mShaderDiffuse;
345 case BuiltinShader::Transparent:
346 return mShaderTransparent;
347 case BuiltinShader::ParticlesUnlit:
348 return mShaderParticlesUnlit;
349 case BuiltinShader::ParticlesLit:
350 return mShaderParticlesLit;
351 case BuiltinShader::ParticlesLitOpaque:
352 return mShaderParticlesLitOpaque;
353 case BuiltinShader::Decal:
354 return mShaderDecal;
355 default:
356 break;
357 }
358
359 return HShader();
360 }
361
362 HTexture BuiltinResources::getTexture(BuiltinTexture type)
363 {
364 Path texturePath = Paths::getDataPath();
365 texturePath.append(TEXTURE_FOLDER);
366
367 switch (type)
368 {
369 case BuiltinTexture::Black:
370 texturePath.append(TEXTURE_BLACK_FILE);
371 break;
372 case BuiltinTexture::White:
373 texturePath.append(TEXTURE_WHITE_FILE);
374 break;
375 case BuiltinTexture::Normal:
376 texturePath.append(TEXTURE_NORMAL_FILE);
377 break;
378 }
379
380 return gResources().load<Texture>(texturePath);
381 }
382
383 HMaterial BuiltinResources::createSpriteTextMaterial() const
384 {
385 return Material::create(mShaderSpriteText);
386 }
387
388 HMaterial BuiltinResources::createSpriteImageMaterial() const
389 {
390 return Material::create(mShaderSpriteImage);
391 }
392
393 HMaterial BuiltinResources::createSpriteLineMaterial() const
394 {
395 return Material::create(mShaderSpriteLine);
396 }
397
398 BuiltinResources& gBuiltinResources()
399 {
400 return BuiltinResources::instance();
401 }
402}