#ifndef MSP_GL_TEXTURE_H_
#define MSP_GL_TEXTURE_H_
+#include <msp/datafile/dynamicobjectloader.h>
#include <msp/datafile/objectloader.h>
#include <msp/graphics/image.h>
-#include "gl.h"
#include "pixelformat.h"
#include "resource.h"
+#include "texture_backend.h"
namespace Msp {
namespace GL {
/**
-Base class for textures. This class only defines operations common for all
-texture types and is not instantiable. For specifying images for textures,
-see one of the dimensioned texture classes.
+Base class for textures. Most operations are defined in subclasses.
-A texture can consinst of a stack of images, called a mipmap. The dimensions
-of each mipmap level are half that of the previous level. The mipmap stack
-can be used for texture minification; see the Sampler class for details.
+Memory must be allocated for the texture by calling storage(). Each subclass
+provides this function with parameters appropriate to that type of texture.
+Contents can then be modified using the image() and sub_image() functions
+provided by subclasses.
+
+Most types of textures can consist of a pyramid of images, called a mipmap.
+The dimensions of each mipmap level are half that of the previous level.
+
+Textures can be used as either a data source or target for draw commands. To
+read from a texture in a shader, it must be paired with a Sampler to determine
+how the texels are accessed. To draw into a texture, it must be attached to a
+Framebuffer.
*/
-class Texture: public Resource
+class Texture: public TextureBackend, public Resource
{
+ friend TextureBackend;
+
protected:
class Loader: public DataFile::CollectionObjectLoader<Texture>
{
unsigned levels;
public:
- Loader(Texture &);
- Loader(Texture &, Collection &);
+ Loader(Texture &t): Loader(t, 0) { }
+ Loader(Texture &t, Collection &c): Loader(t, &c) { }
private:
- void init();
+ Loader(Texture &, Collection *);
virtual void finish();
void load_external_image(Graphics::Image &, const std::string &);
private:
- void external_image(const std::string &);
- void external_image_srgb(const std::string &);
- void external_image_common(const std::string &);
+ void external_data(const std::string &);
+ void external_image(bool, const std::string &);
void generate_mipmap(bool);
void image_data(const std::string &);
void mipmap_levels(unsigned);
+ void raw_data(const std::string &);
};
+public:
+ class GenericLoader: public DataFile::DynamicObjectLoader<Texture>
+ {
+ friend class Texture;
+
+ public:
+ GenericLoader(Collection &c): DynamicObjectLoader<Texture>(&c) { }
+
+ protected:
+ virtual const TypeRegistry &get_type_registry() const { return get_texture_registry(); }
+ };
+
+protected:
enum FormatSwizzle
{
NO_SWIZZLE,
RGB_TO_BGR
};
- unsigned id;
- GLenum target;
PixelFormat format;
PixelFormat storage_fmt;
FormatSwizzle swizzle;
bool use_srgb_format;
bool auto_gen_mipmap;
- std::string debug_name;
- static const int swizzle_orders[];
- static Texture *scratch_binding;
+ Texture(unsigned);
- Texture(GLenum, ResourceManager * = 0);
- Texture(const Texture &);
- Texture &operator=(const Texture &);
-public:
- ~Texture();
-
-protected:
- void generate_id();
void set_format(PixelFormat);
- void apply_swizzle();
- void set_parameter_i(GLenum, int) const;
public:
PixelFormat get_format() const { return format; }
- void generate_mipmap();
+ using TextureBackend::generate_mipmap;
- /// Loads a Graphics::Image from a file and uploads it to the texture.
+ /** Replaces contents of an entire mipmap level. Allocated storage must
+ exist. The image data is interpreted according to the storage format and
+ must have size matching the selected mipmap level. */
+ virtual void image(unsigned level, const void *) = 0;
+
+ /** Loads an image into the texture from a file. */
virtual void load_image(const std::string &, unsigned = 0);
- /** Uploads an image to the texture. If storage has not been defined, it
- will be set to match the image. Otherwise the image must be compatible
- with the defined storage. Semantics depend on the type of texture. */
+ /** Sets the texture's contents from an image. If storage has not been
+ allocated yet, it will be set to match the image. Otherwise the image must
+ be compatible with the existing storage. Subclasses may impose restrictions
+ on the image's dimensions. */
virtual void image(const Graphics::Image &, unsigned = 0) = 0;
- GLenum get_target() const { return target; }
- unsigned get_id() const { return id; }
-
- virtual std::uint64_t get_data_size() const { return 0; }
+ virtual std::size_t get_data_size() const { return 0; }
- void set_debug_name(const std::string &);
+ using TextureBackend::set_debug_name;
-protected:
- void bind_scratch();
-public:
- static void unbind_scratch();
+private:
+ static GenericLoader::TypeRegistry &get_texture_registry();
};
} // namespace GL