#pragma once #include #include #include #include "lib_begin.h" namespace cgv { namespace render { /** the texture class encapsulates all functionality independent of the rendering api. */ class CGV_API texture : public texture_base, public cgv::data::data_format { protected: mutable bool state_out_of_date; int tex_unit; bool complete_create(context& ctx, bool created); public: /**@name methods that can be called without context */ //@{ /** construct from description string (which defaults to rgba format) and most commonly used texture parameters. The description can define a component format as described in \c cgv::data::component_format::set_component_format() or a data format as described in \c cgv::data::data_format::set_data_format(). */ texture(const std::string& description = "uint8[R,G,B,A]", TextureFilter _mag_filter = TF_LINEAR, TextureFilter _min_filter = TF_LINEAR, TextureWrap _wrap_s = TW_CLAMP_TO_EDGE, TextureWrap _wrap_t = TW_CLAMP_TO_EDGE, TextureWrap _wrap_r = TW_CLAMP_TO_EDGE); /** destruct texture, the destructor can be called without context if the destruct method has been called or no creation has taken place */ ~texture(); /// change the data format and clear internal format bool set_data_format(const std::string& description); /// change component format and clear internal format void set_component_format(const component_format& cf); /// change component format and clear internal format void set_component_format(const std::string& description); /// set the texture wrap behaviour in s direction void set_wrap_s(TextureWrap _wrap_s); /// set the texture wrap behaviour in t direction void set_wrap_t(TextureWrap _wrap_t); /// set the texture wrap behaviour in r direction void set_wrap_r(TextureWrap _wrap_r); /// return the texture wrap behaviour in s direction TextureWrap get_wrap_s() const; /// return the texture wrap behaviour in t direction TextureWrap get_wrap_t() const; /// return the texture wrap behaviour in r direction TextureWrap get_wrap_r() const; /// set the border color void set_border_color(const float* rgba) { set_border_color(rgba[0],rgba[1],rgba[2],rgba[3]); } /// set the border color void set_border_color(float r, float g, float b, float a = 1.0f); /** set the minification filters, if minification is set to TF_ANISOTROP, the second floating point parameter specifies the degree of anisotropy */ void set_min_filter(TextureFilter _min_filter, float _anisotropy = 2.0f); /// return the minification filter TextureFilter get_min_filter() const; /// return the currently set anisotropy float get_anisotropy() const; /// set the magnification filter void set_mag_filter(TextureFilter _mag_filter); /// return the magnification filter TextureFilter get_mag_filter() const; /// set priority with which texture is kept in GPU memory void set_priority(float _priority); /// return the priority with which texture is kept in GPU memory float get_priority() const; /// check whether mipmaps have been created bool mipmaps_created() const; /// ensure the the texture state is synchronized with the GPU settings void ensure_state(context& ctx) const; /// check whether textue is enabled bool is_enabled() const; /// return the currently used texture unit and -1 for current int get_tex_unit() const; //@} /**@name methods that can be called only with a context */ //@{ /// find the format that matches the one specified in the component format best void find_best_format(context& ctx, const std::vector* palettes = 0); /** create the texture of dimension and resolution specified in the data format base class. If no type is given, determine it from the format. If dimensions are given, they overwrite the dimensions in the texture format. */ bool create(context& ctx, TextureType _tt = TT_UNDEF, unsigned width=-1, unsigned height=-1, unsigned depth=-1); /** create the texture from an image file. If the file_name is not given ask the user interactively for a file name. The image dimensions are written to the optionally passed pointers image_width_ptr and image_height_ptr. In order to support mipmapping, the width and height of the texture must be powers of two. If the clear_color_ptr is given, the texture is automatically extended in size to powers of two. clear_color_ptr points to four bytes that specify a RGBA color used to fill texels that are inserted to ensure dimensions of powers of two. For creation of a side of a cubemap specify the cube_side parameter. */ bool create_from_image(context& ctx, const std::string& file_name = "", int* image_width_ptr = 0, int* image_height_ptr = 0, unsigned char* clear_color_ptr = 0, int level = -1, int cube_side = -1); /** same as previous method but use the passed data format and data view to store the content of the image. No pointers to width and height can be passed as this information is available in the data_format after the call. */ bool create_from_image(cgv::data::data_format& df, cgv::data::data_view& dv, context& ctx, const std::string& file_name = "", unsigned char* clear_color_ptr = 0, int level = -1, int cube_side = -1); //! Helper function that determins the individual file names for a cubemap. /*! Returns whether the file_names specification was correct. See comment to create_from_images for the syntax of the file_names parameter. */ static bool deduce_file_names(const std::string& file_names, std::vector& deduced_names); //! Create a cube map from six files specified in the file_names parameter. /*! The file_names parameter can specify different file names by the use of the wildchar symbol '*' or by curly brackets. When using '*' the files are loaded in alphanumerical order. The image files defining the cubemap sides must be in the order positive x, negative x, positive y, negative y, positive z and negative z. Some examples of specifying file names: - "cm_{xp,xn,yp,yn,zp,zn}.png" defines the file names "cm_xp.png", "cm_xn.png", "cm_yp.png", "cm_yn.png", "cm_zp.png" and "cm_zn.png" - "cm_*.png" issues a glob command resulting in an alphanumerically ordered file name list. Be aware that the naming of the previous example would result in a wrong ordering of the file names. Mixing of '*' and "{,}" syntax is not allowed. The static method deduce_file_names is used to deduce the individual file names from the file_names parameter and can be used also when the correct path to the cubemap files needs to be found. Different levels of the mipmap pyramid can be created in separate calls. If the level parameter is not specified or -1, the images are load to level 0 and a mipmap pyramid is built automatically. This method has no support for rescaling to power of two dimensions. If a mipmap is used, the image files should already have power of two dimensions. */ bool create_from_images(context& ctx, const std::string& file_names, int level = -1); /// write the content of the texture to a file. This method needs support for frame buffer objects. bool write_to_file(context& ctx, const std::string& file_name, unsigned int z_or_cube_side = -1) const; /** generate mipmaps automatically, only supported if framebuffer objects are supported by the GPU */ bool generate_mipmaps(context& ctx); /** create texture from the currently set read buffer, where x, y, width and height define the to be used rectangle of the read buffer. The dimension and resolution of the texture format are updated automatically. If level is not specified or set to -1 mipmaps are generated. */ bool create_from_buffer(context& ctx, int x, int y, int width, int height, int level = -1); /** create texture from data view. Use dimension and resolution of data view but the component format of the texture. If level is not specified or set to -1 mipmaps are generated. If cube_side is specified, and data view is 2D, create one of the six sides of a cubemap. */ bool create(context& ctx, const cgv::data::const_data_view& data, int level = -1, int cube_side = -1, const std::vector* palettes = 0); /** replace a block within a 1d texture with the given data. If level is not specified, level 0 is set and if a mipmap has been created before, coarser levels are updated also. */ bool replace(context& ctx, int x, const cgv::data::const_data_view& data, int level = -1, const std::vector* palettes = 0); /** replace a block within a 2d texture with the given data. If level is not specified, level 0 is set and if a mipmap has been created before, coarser levels are updated also. */ bool replace(context& ctx, int x, int y, const cgv::data::const_data_view& data, int level = -1, const std::vector* palettes = 0); /** replace a block within a 3d texture or a side of a cube map with the given data. If level is not specified, level 0 is set and if a mipmap has been created before, coarser levels are updated also. */ bool replace(context& ctx, int x, int y, int z_or_cube_side, const cgv::data::const_data_view& data, int level = -1, const std::vector* palettes = 0); /// replace a block within a 2d texture from the current read buffer. bool replace_from_buffer(context& ctx, int x, int y, int x_buffer, int y_buffer, int width, int height, int level = -1); /// replace a block within a 3d texture or a side from a cube map from the current read buffer. bool replace_from_buffer(context& ctx, int x, int y, int z_or_cube_side, int x_buffer, int y_buffer, int width, int height, int level); /// replace within a slice of a volume or a side of a cube map from the given image bool replace_from_image(context& ctx, const std::string& file_name, int x, int y, int z_or_cube_side, int level); /** same as previous method but use the passed data format and data view to store the content of the image. */ bool replace_from_image(cgv::data::data_format& df, cgv::data::data_view& dv, context& ctx, const std::string& file_name, int x, int y, int z_or_cube_side, int level); /// destruct the texture and free texture memory and handle bool destruct(context& ctx); //@} /**@name methods that change the current gpu context */ //@{ /** enable this texture in the given texture unit, -1 corresponds to the current unit. */ bool enable(context& ctx, int tex_unit = -1); /// disable texture and restore state before last enable call bool disable(context& ctx); //@} }; } } #include