1 // Copyright 2013-2018 the openage authors. See copying.md for legal info. 2 3 #pragma once 4 5 #include <epoxy/gl.h> 6 #include <vector> 7 #include <memory> 8 9 #include "gamedata/texture.gen.h" 10 #include "coord/pixel.h" 11 #include "coord/tile.h" 12 #include "shader/program.h" 13 #include "shader/shader.h" 14 #include "util/path.h" 15 16 17 namespace openage { 18 class Terrain; 19 20 namespace util { 21 class Path; 22 } 23 24 namespace coord { 25 class CoordManager; 26 } 27 28 namespace texture_shader { 29 extern shader::Program *program; 30 extern GLint texture, tex_coord; 31 } // namespace texture_shader 32 33 namespace teamcolor_shader { 34 extern shader::Program *program; 35 extern GLint texture, tex_coord; 36 extern GLint player_id_var, alpha_marker_var, player_color_var; 37 } // namespace teamcolor_shader 38 39 namespace alphamask_shader { 40 extern shader::Program *program; 41 extern GLint base_texture, mask_texture, base_coord, mask_coord, show_mask; 42 } // namespace alphamask_shader 43 44 // bitmasks for shader modes 45 constexpr int PLAYERCOLORED = 1 << 0; 46 constexpr int ALPHAMASKED = 1 << 1; 47 48 /** 49 * enables transfer of data to opengl 50 */ 51 struct gl_texture_buffer { 52 GLuint id, vertbuf; 53 54 // this requires loading on the main thread 55 bool transferred; 56 int texture_format_in; 57 int texture_format_out; 58 std::unique_ptr<uint32_t[]> data; 59 }; 60 61 62 /** 63 * A texture for rendering graphically. 64 * 65 * You may believe it or not, but this class represents a single texture, 66 * which can be drawn on the screen. 67 * 68 * The class supports subtextures, so that one big texture can contain 69 * several small images. These are the ones actually to be rendered. 70 */ 71 class Texture { 72 public: 73 int w; 74 int h; 75 76 /** 77 * Create a texture from a rgba8 array. 78 * It will have w * h * 32bit storage. 79 */ 80 Texture(int width, int height, std::unique_ptr<uint32_t[]> data); 81 82 /** 83 * Create a texture from a existing image file. 84 * For supported image file types, see the SDL_Image initialization in the engine. 85 */ 86 Texture(const util::Path &filename, bool use_metafile=false); 87 ~Texture(); 88 89 /** 90 * Draws the texture at hud coordinates. 91 */ 92 void draw(const coord::CoordManager &mgr, coord::camhud pos, unsigned int mode=0, bool mirrored=false, int subid=0, unsigned player=0) const; 93 94 /** 95 * Draws the texture at game coordinates. 96 */ 97 void draw(const coord::CoordManager &mgr, coord::camgame pos, unsigned int mode=0, bool mirrored=false, int subid=0, unsigned player=0) const; 98 99 /** 100 * Draws the texture at phys coordinates. 101 */ 102 void draw(const coord::CoordManager &mgr, coord::phys3 pos, unsigned int mode=0, bool mirrored=false, int subid=0, unsigned player=0) const; 103 104 /** 105 * Draws the texture at tile coordinates. 106 */ 107 void draw(const coord::CoordManager &mgr, const Terrain &terrain, coord::tile pos, unsigned int mode, int subid, Texture *alpha_texture, int alpha_subid) const; 108 109 /** 110 * Draws the texture at window coordinates. 111 */ 112 void draw(coord::viewport pos, unsigned int mode, bool mirrored, int subid, unsigned player, Texture *alpha_texture, int alpha_subid) const; 113 114 /** 115 * Reload the image file. Used for inotify refreshing. 116 */ 117 void reload(); 118 119 /** 120 * Get the subtexture coordinates by its id. 121 */ 122 const gamedata::subtexture *get_subtexture(uint64_t subid) const; 123 124 /** 125 * @return the number of available subtextures 126 */ 127 size_t get_subtexture_count() const; 128 129 /** 130 * Fetch the size of the given subtexture. 131 * @param subid: index of the requested subtexture 132 * @param w: the subtexture width 133 * @param h: the subtexture height 134 */ 135 void get_subtexture_size(uint64_t subid, int *w, int *h) const; 136 137 /** 138 * get atlas subtexture coordinates. 139 * 140 * left, right, top and bottom bounds as coordinates 141 * these pick the requested area out of the big texture. 142 * returned as floats in range 0.0 to 1.0 143 */ 144 void get_subtexture_coordinates(uint64_t subid, float *txl, float *txr, float *txt, float *txb) const; 145 void get_subtexture_coordinates(const gamedata::subtexture *subtex, float *txl, float *txr, float *txt, float *txb) const; 146 147 /** 148 * fixes the hotspots of all subtextures to (x,y). 149 * this is a temporary workaround; such fixes should actually be done in the 150 * convert script. 151 */ 152 void fix_hotspots(unsigned x, unsigned y); 153 154 /** 155 * activates the influence of a given alpha mask to this texture. 156 */ 157 void activate_alphamask(Texture *mask, uint64_t subid); 158 159 /** 160 * disable a previously activated alpha mask. 161 */ 162 void disable_alphamask(); 163 164 /** 165 * returns the opengl texture id of this texture. 166 */ 167 GLuint get_texture_id() const; 168 169 private: 170 std::unique_ptr<gl_texture_buffer> buffer; 171 std::vector<gamedata::subtexture> subtextures; 172 bool use_metafile; 173 174 util::Path filename; 175 176 void load(); 177 178 /** 179 * The texture loadin must occur on the thread that manages the gl context. 180 */ 181 void load_in_glthread() const; 182 GLuint make_gl_texture(int iformat, int oformat, int w, int h, void *) const; 183 void unload(); 184 185 }; 186 187 } // namespace openage 188