X-Git-Url: http://git.tdb.fi/?p=libs%2Fgl.git;a=blobdiff_plain;f=source%2Ftexture.h;h=94614c45c7319748c102456dcd6c1b3bb6119649;hp=848517eb45c99da20a67c8261ed81488b7902ea3;hb=a9c375e17065bcc429b430bd8211a9ee845159a5;hpb=ceae2a27dfc58310c5bab7e3aa3fedf0fa9a1f49 diff --git a/source/texture.h b/source/texture.h index 848517eb..94614c45 100644 --- a/source/texture.h +++ b/source/texture.h @@ -1,74 +1,222 @@ -/* $Id$ - -This file is part of libmspgl -Copyright © 2007 Mikko Rasa, Mikkosoft Productions -Distributed under the LGPL -*/ - #ifndef MSP_GL_TEXTURE_H_ #define MSP_GL_TEXTURE_H_ -#include #include +#include +#include "datatype.h" #include "gl.h" +#include "pixelformat.h" +#include "predicate.h" +#include "resource.h" namespace Msp { namespace GL { enum TextureFilter { - NEAREST = GL_NEAREST, - LINEAR = GL_LINEAR, + /// No filtering + NEAREST = GL_NEAREST, + + /// Bilinear filtering + LINEAR = GL_LINEAR, + + /// Mipmapping without filtering NEAREST_MIPMAP_NEAREST = GL_NEAREST_MIPMAP_NEAREST, - NEAREST_MIPMAP_LINEAR = GL_NEAREST_MIPMAP_LINEAR, - LINEAR_MIPMAP_NEAREST = GL_LINEAR_MIPMAP_NEAREST, - LINEAR_MIPMAP_LINEAR = GL_LINEAR_MIPMAP_LINEAR + + /// Linear filtering between two mipmap levels + NEAREST_MIPMAP_LINEAR = GL_NEAREST_MIPMAP_LINEAR, + + /// Bilinear filtering on the closest mipmap level + LINEAR_MIPMAP_NEAREST = GL_LINEAR_MIPMAP_NEAREST, + + /// Trilinear filtering between two mipmap levels + LINEAR_MIPMAP_LINEAR = GL_LINEAR_MIPMAP_LINEAR }; -std::istream &operator>>(std::istream &, TextureFilter &); + +enum TextureWrap +{ + /// Tile the texture infinitely + REPEAT = GL_REPEAT, + + /// Extend the texels at the edge of the texture to infinity + CLAMP_TO_EDGE = GL_CLAMP_TO_EDGE, + + /// Tile the texture, with every other repetition mirrored + MIRRORED_REPEAT = GL_MIRRORED_REPEAT +}; /** 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. + +A texture is generally rendered at a size that's either smaller or larger than +its native size, so that the texture coordinates do not exactly correspond to +the texels of the texture. The kind of filtering used, if any, is determined +by the minification and magnification filter parameters. The default is LINEAR +for magnification and NEAREST_MIPMAP_LINEAR for minification. + +When a mipmapped filter is in use, the texture consists of a stack of mipmap +images. Level 0 is the base image. Each level above 0 has half the size of +the previous level, rounded down and clamped to 1. The level with size 1 in +all dimensions is the last mipmap level. All levels must be allocated for the +texture to be usable. + +If texture coordinates fall outside of the principal range of the texture, +wrapping is applied. The default for all directions is REPEAT. */ -class Texture +class Texture: public Resource { protected: - class Loader: public DataFile::ObjectLoader + class Loader: public DataFile::CollectionObjectLoader { + protected: + bool srgb; + public: Loader(Texture &); - void min_filter(TextureFilter); - void mag_filter(TextureFilter); + Loader(Texture &, Collection &); + private: + void init(); + + void external_image(const std::string &); + void filter(TextureFilter); void generate_mipmap(bool); + void image_data(const std::string &); + void mag_filter(TextureFilter); + void max_anisotropy(float); + void min_filter(TextureFilter); + void mipmap_levels(unsigned); + void wrap(TextureWrap); + void wrap_r(TextureWrap); + void wrap_s(TextureWrap); + void wrap_t(TextureWrap); }; -public: - ~Texture(); + enum ParameterMask + { + MIN_FILTER = 1, + MAG_FILTER = 2, + WRAP_S = 4, + WRAP_T = 8, + WRAP_R = 16, + GENERATE_MIPMAP = 32, + COMPARE = 64, + COMPARE_FUNC = 128, + MAX_ANISOTROPY = 256, + FORMAT_SWIZZLE = 512, + MIPMAP_LEVELS = 1024 + }; - void bind() const; - void bind_to(unsigned) const; - void parameter(GLenum, int); - void parameter(GLenum, float); - void set_min_filter(TextureFilter f) { parameter(GL_TEXTURE_MIN_FILTER, f); } - void set_mag_filter(TextureFilter f) { parameter(GL_TEXTURE_MAG_FILTER, f); } - GLenum get_target() const { return target; } - unsigned get_id() const { return id; } + enum FormatSwizzle + { + NO_SWIZZLE, + R_TO_LUMINANCE, + RG_TO_LUMINANCE_ALPHA + }; - static void unbind(); - static void unbind_from(unsigned); -protected: - unsigned id; + unsigned id; GLenum target; + PixelFormat ifmt; + FormatSwizzle swizzle; + TextureFilter min_filter; + TextureFilter mag_filter; + unsigned mipmap_levels; + float max_anisotropy; + TextureWrap wrap_s; + TextureWrap wrap_t; + TextureWrap wrap_r; + bool gen_mipmap; + bool compare; + Predicate cmp_func; + mutable int dirty_params; - Texture(); + static int swizzle_orders[]; + + Texture(GLenum, ResourceManager * = 0); Texture(const Texture &); Texture &operator=(const Texture &); - void maybe_bind() const; +public: + ~Texture(); + +protected: + static DataType get_alloc_type(PixelFormat); + void set_internal_format(PixelFormat); + PixelFormat get_upload_format(PixelFormat) const; + + void update_parameter(int) const; + void set_parameter_i(GLenum, int) const; + void set_parameter_f(GLenum, float) const; +public: + void set_min_filter(TextureFilter); + void set_mag_filter(TextureFilter); + + /** Sets filter for both minification and magnification. Since mipmapping + is not applicable to magnification, LINEAR is used instead. */ + void set_filter(TextureFilter); + + void set_mipmap_levels(unsigned); + + void set_max_anisotropy(float); + + /** Sets the wrapping mode for all coordinates. */ + void set_wrap(TextureWrap); + + void set_wrap_s(TextureWrap); + void set_wrap_t(TextureWrap); + void set_wrap_r(TextureWrap); + + static bool can_generate_mipmap(); + + /** Sets automatic mipmap generation. If enabled, mipmaps are generated + when a texture image is uploaded. */ + void set_generate_mipmap(bool); + +protected: + void auto_generate_mipmap(); + +public: + /** Sets depth texture comparison. Has no effect on other formats. When + comparison is enabled, the third component of the texture coordinate is + compared against the texel value, and the result is returned as the texture + sample. */ + void set_compare_enabled(bool); + + /** Sets the function to use for depth comparison. */ + void set_compare_func(Predicate); + + /// Loads a Graphics::Image from a file and uploads it to the texture. + virtual void load_image(const std::string &, bool srgb = false); + + /** 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. + + If srgb is true and storage is determined by this call, then an sRGB pixel + format will be used. */ + virtual void image(const Graphics::Image &, bool srgb = false) = 0; + + GLenum get_target() const { return target; } + unsigned get_id() const { return id; } + + void bind(bool legacy = true) const { bind_to(0, legacy); } + void bind_to(unsigned, bool = true) const; + + static const Texture *current(unsigned = 0); + static void unbind() { unbind_from(0); } + static void unbind_from(unsigned); +private: + static bool is_legacy_target(GLenum); + +public: + virtual UInt64 get_data_size() const { return 0; } }; + +bool is_mipmapped(TextureFilter); + } // namespace GL } // namespace Msp