Simulant  21.12-194
A portable game engine for Windows, OSX, Linux, Dreamcast, and PSP
loader.h
1 /* * Copyright (c) 2011-2017 Luke Benstead https://simulant-engine.appspot.com
2  *
3  * This file is part of Simulant.
4  *
5  * Simulant is free software: you can redistribute it and/or modify
6  * it under the terms of the GNU Lesser General Public License as published by
7  * the Free Software Foundation, either version 3 of the License, or
8  * (at your option) any later version.
9  *
10  * Simulant is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public License
16  * along with Simulant. If not, see <http://www.gnu.org/licenses/>.
17  */
18 
19 #ifndef SIMULANT_LOADER_H
20 #define SIMULANT_LOADER_H
21 
22 #include <set>
23 #include <unordered_map>
24 #include <stdexcept>
25 #include <string>
26 #include <memory>
27 
28 #include "logging.h"
29 
30 #include "utils/kfs.h"
31 #include "loadable.h"
32 #include "streams/file_ifstream.h"
33 #include "generic/property.h"
34 #include "generic/any/any.h"
35 #include "types.h"
36 
37 #include "assets/material.h"
38 #include "texture.h"
39 #include "path.h"
40 
41 namespace smlt {
42 
43 /* Like std::getline, but, it handles \n and \r\n line endings automatically */
44 std::istream& portable_getline(std::istream& stream, std::string& str);
45 
46 class VirtualFileSystem;
47 
48 /*
49  * You may have a situation where a single filetype can be used for different purposes.
50  * For example, a TGA image file might be used as a texture, or could be used as a heightmap,
51  * this causes a problem when calling loader_for(some_filename).. which loader do we return?
52  * The texture or the heightmap?
53  *
54  * For this reason loaders can register hints, and the window's loader_for() can take a hint
55  * argument for distinguishing between the two.
56  */
57 
58 enum LoaderHint {
59  LOADER_HINT_NONE = 0,
60  LOADER_HINT_TEXTURE,
61  LOADER_HINT_MESH
62 };
63 
64 typedef std::unordered_map<unicode, smlt::any> LoaderOptions;
65 
66 class Loader {
67 public:
68  typedef std::shared_ptr<Loader> ptr;
69 
70  Loader(const Path& filename, std::shared_ptr<std::istream> data):
71  filename_(filename),
72  data_(data) {}
73 
74  virtual ~Loader();
75  void into(Loadable* resource, const LoaderOptions& options = LoaderOptions()) {
76  into(*resource, options);
77  }
78 
79  void into(std::shared_ptr<Loadable> resource, const LoaderOptions& options=LoaderOptions()) {
80  into(*resource, options);
81  }
82 
83  void into(Window& window, const LoaderOptions& options=LoaderOptions()) {
84  into((Loadable&) window, options);
85  }
86 
87  void set_vfs(VirtualFileSystem* locator) { locator_ = locator; }
88 
89  Property<VirtualFileSystem* Loader::*> vfs = { this, &Loader::locator_ };
90 
91 protected:
92  Path filename_;
93  std::shared_ptr<std::istream> data_;
94 
95  template<typename T>
96  T* loadable_to(Loadable& loadable) {
97  T* thing = dynamic_cast<T*>(&loadable);
98  if(!thing) {
99  S_WARN("Attempted to cast resource to invalid type");
100  return nullptr;
101  }
102 
103  return thing;
104  }
105 
106 private:
107  VirtualFileSystem* locator_ = nullptr;
108  virtual void into(Loadable& resource, const LoaderOptions& options = LoaderOptions()) = 0;
109 };
110 
111 class LoaderType {
112 public:
113  typedef std::shared_ptr<LoaderType> ptr;
114 
115  virtual ~LoaderType() { }
116 
117  virtual const char* name() = 0;
118  virtual bool supports(const Path& filename) const = 0;
119  virtual Loader::ptr loader_for(const Path& filename, std::shared_ptr<std::istream> data) const = 0;
120 
121  bool has_hint(LoaderHint hint) {
122  return (bool) hints_.count(hint);
123  }
124 
125 protected:
126  void add_hint(LoaderHint hint) {
127  hints_.insert(hint);
128  }
129 
130  std::set<LoaderHint> hints_;
131 };
132 
134  uint16_t width;
135  uint16_t height;
136  uint8_t channels;
137  TextureFormat format;
138  std::vector<uint8_t> data;
139 };
140 
141 namespace loaders {
142 
143 class BaseTextureLoader : public Loader {
144 public:
145  BaseTextureLoader(const Path& filename, std::shared_ptr<std::istream> data):
146  Loader(filename, data) {
147  }
148 
149  void into(Loadable& resource, const LoaderOptions& options = LoaderOptions()) override;
150 
151 private:
152  virtual bool format_stored_upside_down() const { return true; }
153  virtual TextureLoadResult do_load(std::shared_ptr<FileIfstream> stream) = 0;
154 };
155 
156 }
157 
158 
160  /* By default, no backface culling is applied to meshes, set this so that the materials
161  * generated inherit the cull mode you want */
162  CullMode cull_mode = CULL_MODE_NONE;
163 
164  /* Some obj files have faces which have a diffuse texture, but no texture coordinates.
165  * The spec says that these should just have no texture applied, but in some files
166  * they need to be skipped entirely */
167  bool obj_include_faces_with_missing_texture_vertices = false;
168 
169  /* If set to false, the materials created by the model loader will have blending
170  * force disabled. This is useful on the Dreamcast where having blending enabled
171  * is costly */
172  bool blending_enabled = true;
173 
174  /* If non-empty, attempt to load textures with this file extension instead
175  * of the one provided by the mesh. Should be the extension excluding the leading
176  * dot. (e.g. "dtex") */
177  std::string override_texture_extension = "";
178 };
179 
180 #define MESH_LOAD_OPTIONS_KEY "mesh_options"
181 
182 }
183 
184 #endif
smlt::Property
Definition: property.h:202
smlt::MeshLoadOptions
Definition: loader.h:159
smlt::VirtualFileSystem
Definition: vfs.h:45
smlt::TextureLoadResult
Definition: loader.h:133
smlt
Definition: animation.cpp:25
smlt::LoaderType
Definition: loader.h:111
smlt::Window
Definition: window.h:65
smlt::Loader
Definition: loader.h:66
smlt::loaders::BaseTextureLoader
Definition: loader.h:143
smlt::Path
Definition: path.h:7
smlt::Loadable
Definition: loadable.h:26