2#include "frame_buffer.h"
4#include <cgv/media/image/image_reader.h>
5#include <cgv/media/image/image_writer.h>
6#include <cgv/utils/tokenizer.h>
7#include <cgv/utils/file.h>
8#include <cgv/utils/statistics.h>
13using namespace cgv::utils::file;
29 mag_filter = _mag_filter;
30 min_filter = _min_filter;
34 state_out_of_date =
true;
48 std::cerr <<
"could not destruct texture properly" << std::endl;
56 state_out_of_date =
true;
65 state_out_of_date =
true;
73 state_out_of_date =
true;
80 state_out_of_date =
true;
86 state_out_of_date =
true;
92 state_out_of_date =
true;
116 state_out_of_date =
true;
122 min_filter = _min_filter;
123 anisotropy = _anisotropy;
124 state_out_of_date =
true;
140 mag_filter = _mag_filter;
141 state_out_of_date =
true;
151 priority = _priority;
152 state_out_of_date =
true;
162 use_compare_function = _use_compare_function;
163 state_out_of_date =
true;
168 return use_compare_function;
174 compare_function = _compare_function;
175 state_out_of_date =
true;
181 return compare_function;
193 void* tmp = internal_format;
195 internal_format = tmp;
200 if (state_out_of_date) {
201 ctx.texture_set_state(*
this);
202 state_out_of_date =
false;
220 if (!internal_format)
222 return complete_create(ctx, ctx.texture_create(*
this, *
this));
227 nr_multi_samples = _nr_samples;
232 fixed_sample_locations = use;
235template <
class int_type>
236bool is_power_of_two(int_type i)
249template <
class int_type>
250int_type power_of_two_ub(int_type i)
259 const std::string& file_name,
unsigned char* clear_color_ptr,
int level,
int cube_side)
261 bool ensure_power_of_two = clear_color_ptr != 0;
262 std::string fn = file_name;
269 std::vector<data_format> palette_formats;
270 std::vector<data_view> palettes;
280 for (
unsigned i=0; i<palette_formats.size(); ++i) {
293 if (ensure_power_of_two && (!is_power_of_two(w) || !is_power_of_two(h))) {
302 const unsigned char* src_ptr = dv.
get_ptr<
unsigned char>();
303 unsigned char* dest_ptr = dv1.
get_ptr<
unsigned char>();
304 unsigned char* dest_ptr_end = dest_ptr + entry_size * W*H;
305 for (
unsigned y = 0; y < h; ++y) {
306 dest_ptr_end -= W * entry_size;
307 memcpy(dest_ptr_end, src_ptr, w*entry_size);
308 if (clear_color_ptr) {
309 for (
size_t x = w; x < W; ++x)
310 memcpy(dest_ptr_end + x * entry_size, clear_color_ptr, entry_size);
313 std::fill(dest_ptr_end + w * entry_size, dest_ptr_end + W*entry_size, 0);
314 src_ptr += w * entry_size;
317 size_t N = (H - h)*W;
318 if (clear_color_ptr) {
319 for (
size_t i = 0; i < N; ++i)
320 memcpy(dest_ptr + i * entry_size, clear_color_ptr, entry_size);
323 std::fill(dest_ptr, dest_ptr + N*entry_size, 0);
325 return create(ctx, dv1, level, cube_side,
false, &palettes);
331 const std::string& file_name,
int* image_width_ptr,
int* image_height_ptr,
332 unsigned char* clear_color_ptr,
int level,
int cube_side)
340 if (image_height_ptr)
347 if (std::find(file_names.begin(), file_names.end(),
'{') != file_names.end()) {
348 std::vector<token> toks;
349 deduced_names.resize(6);
352 for (
unsigned i=0; i<toks.size(); ++i) {
353 if (toks[i] ==
"{") {
354 if (selection != -1) {
355 std::cerr <<
"warning: nested {} not allowed in cubemap file names specification " << file_names << std::endl;
360 else if (toks[i] ==
"}") {
361 if (selection == -1) {
362 std::cerr <<
"warning: } without opening { in cubemap file names specification " << file_names << std::endl;
365 if (selection != 5) {
366 std::cerr <<
"warning: no 6 file names specified for creating cubemap from images " << file_names << std::endl;
371 else if (toks[i] ==
",") {
372 if (selection == -1) {
373 std::cerr <<
"warning: , arising outside {} in cubemap file names specification " << file_names << std::endl;
379 if (selection == -1) {
380 for (
unsigned j=0; j<6; ++j)
384 if (selection == 6) {
385 std::cerr <<
"warning: more than 6 files names specified for cubemap creation " << file_names << std::endl;
388 deduced_names[selection] +=
to_string(toks[i]);
394 std::string path_prefix = get_path(file_names);
395 if (!path_prefix.empty())
397 void* handle = find_first(file_names);
398 while (handle != 0) {
399 deduced_names.push_back(path_prefix+find_name(handle));
400 handle = find_next(handle);
402 if (deduced_names.size() != 6) {
403 std::cerr <<
"warning: not exactly 6 files names specified for cubemap creation " << file_names << std::endl;
412 std::vector<std::string> deduced_names;
416 for (
unsigned i=0; success && i<6; ++i)
419 std::cerr <<
"could not create cubemap side " << i <<
" from image " << deduced_names[i] << std::endl;
427bool texture::write_to_file(
context& ctx,
const std::string& file_name,
unsigned int z_or_cube_size,
float depth_map_gamma,
const std::string& options)
const
431 last_error =
"texture must be created for write_to_file";
436 last_error =
"could not create frame buffer object for write_to_file";
439 if (z_or_cube_size != -1) {
440 if (!fb.
attach(ctx,*
this,z_or_cube_size,0,0)) {
441 last_error =
"could not attach texture for write_to_file";
446 if (!fb.
attach(ctx,*
this)) {
447 last_error =
"could not attach texture for write_to_file";
457 if (!fb.
attach(ctx, rb)) {
458 last_error =
"could not attach color buffer for write_to_file";
463 last_error =
"frame buffer object not complete for write_to_file due to\n";
477 for (i = 0; i < n; ++i)
483 for (i = 0; i < n; ++i) {
513 return ctx.texture_create_mipmaps(*
this, *
this);
523bool texture::complete_create(
const context& ctx,
bool created)
525 state_out_of_date =
true;
549 if (level == -1 && !internal_format)
551 return complete_create(ctx, ctx.texture_create_from_buffer(*
this, *
this, x, y, level));
574 }
else if(num_array_layers != 0) {
575 if(num_array_layers < 0) {
584 case TT_1D: tt = TT_1D_ARRAY;
break;
585 case TT_2D: tt = TT_2D_ARRAY;
break;
586 case TT_3D: tt = TT_2D_ARRAY;
break;
591 if ((tt == TT_1D || tt == TT_2D || tt == TT_3D) &&
is_created()) {
592 bool replace_allowed = tt == this->tt;
595 replace_allowed =
false;
596 if (replace_allowed && level < 1) {
598 case TT_1D :
return replace(ctx, 0, data, level, palettes);
599 case TT_2D :
return replace(ctx, 0, 0, data, level, palettes);
600 case TT_3D :
return replace(ctx, 0, 0, 0, data, level, palettes);
612 if (level == -1 || !internal_format)
615 return complete_create(ctx, ctx.texture_create(*
this, *
this, data, level, cube_side, num_array_layers, palettes));
631 return ctx.texture_replace(*
this,x,-1,-1,data,level, palettes);
647 return ctx.texture_replace(*
this,x,y,-1,data,level, palettes);
660 bool res = ctx.texture_replace(*
this,x,y,z_or_cube_side,data,level, palettes);
661 if (res && level == -1 && !have_mipmaps)
668 int y_buffer,
int width,
int height,
int level)
678 return ctx.texture_replace_from_buffer(*
this,x,y,-1,x_buffer,y_buffer,width,height,level);
683 int y_buffer,
int width,
int height,
int level)
689 if (tt != TT_3D && tt != TT_CUBEMAP) {
693 return ctx.texture_replace_from_buffer(*
this,x,y,z_or_cube_side,x_buffer,y_buffer,width,height,level);
707 const std::string& file_name,
int x,
int y,
int z_or_cube_side,
710 std::string fn = file_name;
714 std::vector<data_format> palette_formats;
718 std::vector<data_view> palettes;
719 for (
unsigned i=0; i<palette_formats.size(); ++i) {
724 replace(ctx, x, y, z_or_cube_side, dv, level, &palettes);
732 state_out_of_date =
true;
735 return ctx.texture_destruct(*
this);
752 tex_unit = _tex_unit;
767 tex_unit = _tex_unit;
770 return ctx.texture_bind_as_image(*
this, tex_unit, level, bind_array, layer, access);
781 return user_data != 0;
void multi_set(const std::string &property_assignments, bool report_error=true)
set several properties
complete implementation of method actions that only call one method when entering a node
The const_data_view has the functionality of the data_view but uses a const pointer and therefore doe...
const data_format * get_format() const
return the component format
cgv::type::func::transfer_const< P, S * >::type get_ptr() const
return a data pointer to type S
the data view gives access to a data array of one, two, three or four dimensions.
A vector with zero based index.
base class for all drawables, which is independent of the used rendering API.
virtual bool read_frame_buffer(data::data_view &dv, unsigned int x=0, unsigned int y=0, FrameBufferType buffer_type=FB_BACK, cgv::type::info::TypeId type=cgv::type::info::TI_UINT8, data::ComponentFormat cf=data::CF_RGB, int w=-1, int h=-1)=0
read the current frame buffer or a rectangular region of it into the given data view.
virtual bool make_current() const =0
make the current context current if possible
this class encapsulate frame buffers that live on the GPU and can be used as destination for the rend...
bool create(const context &ctx, int _width=-1, int _height=-1)
create framebuffer if extension is supported, otherwise return false.
bool is_complete(const context &ctx) const
check for completeness, if not complete, get the reason in last_error
bool attach(const context &ctx, const render_buffer &rb, int i=0)
attach render buffer to depth buffer if it is a depth buffer, to stencil if it is a stencil buffer or...
bool enable(context &ctx, int i0=-1, int i1=-1, int i2=-1, int i3=-1, int i4=-1, int i5=-1, int i6=-1, int i7=-1, int i8=-1, int i9=-1, int i10=-1, int i11=-1, int i12=-1, int i13=-1, int i14=-1, int i15=-1)
enable the framebuffer either with all color attachments if no arguments are given or if arguments ar...
bool disable(context &ctx)
disable the framebuffer object
std::string last_error
a string that contains the last error, which is only set by the init method
this class encapsulate render buffers that live on the GPU which must support frame buffer objects fo...
bool create(const context &ctx, int width=-1, int height=-1)
create a render buffer.
virtual bool is_created() const
return whether component has been created
const context * ctx_ptr
keep pointer to my context
std::string last_error
a string that contains the last error
base interface for a texture
bool generate_mipmaps(const context &ctx)
generate mipmaps automatically, only supported if framebuffer objects are supported by the GPU
void set_mag_filter(TextureFilter _mag_filter)
set the magnification filter
TextureWrap get_wrap_s() const
return the texture wrap behaviour in s direction
TextureFilter get_mag_filter() const
return the magnification filter
bool set_data_format(const std::string &description)
change the data format and clear internal format
TextureFilter get_min_filter() const
return the minification filter
bool create(const context &ctx, TextureType _tt=TT_UNDEF, unsigned width=-1, unsigned height=-1, unsigned depth=-1)
create the texture of dimension and resolution specified in the data format base class.
~texture()
destruct texture, the destructor can be called without context if the destruct method has been called...
void set_compare_function(CompareFunction compare_function)
set the texture compare function
int get_tex_unit() const
return the currently used texture unit and -1 for current
bool create_from_image(const 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)
create the texture from an image file.
TextureWrap get_wrap_r() const
return the texture wrap behaviour in r direction
bool create_from_buffer(const context &ctx, int x, int y, int width, int height, int level=-1)
create texture from the currently set read buffer, where x, y, width and height define the to be used...
static bool deduce_file_names(const std::string &file_names, std::vector< std::string > &deduced_names)
Helper function that determins the individual file names for a cubemap.
bool replace_from_buffer(const context &ctx, int x, int y, int x_buffer, int y_buffer, int width, int height, int level=-1)
replace a block within a 2d texture from the current read buffer.
void set_priority(float _priority)
set priority with which texture is kept in GPU memory
float get_priority() const
return the priority with which texture is kept in GPU memory
void set_fixed_sample_locations(bool use)
set whether multi sampling uses fixed sample locations
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)
construct from description string (which defaults to rgba format) and most commonly used texture para...
bool replace_from_image(const context &ctx, const std::string &file_name, int x, int y, int z_or_cube_side, int level)
replace within a slice of a volume or a side of a cube map from the given image
void set_nr_multi_samples(unsigned _nr_samples)
set the number of multi samples for textures of type TT_MULTISAMPLE_2D and TT_MULTISAMPLE_2D_ARRAY
bool disable(const context &ctx)
disable texture and restore state from before last enable call
void ensure_state(const context &ctx) const
ensure the the texture state is synchronized with the GPU settings
bool enable(const context &ctx, int tex_unit=-1)
enable this texture in the given texture unit, -1 corresponds to the current unit.
void set_wrap_t(TextureWrap _wrap_t)
set the texture wrap behaviour in t direction
bool destruct(const context &ctx)
destruct the texture and free texture memory and handle
std::string last_error
a string that contains the last error
CompareFunction get_compare_function() const
get the texture compare function
bool get_compare_mode() const
get the texture compare mode and function
bool write_to_file(context &ctx, const std::string &file_name, unsigned int z_or_cube_side=-1, float depth_map_gamma=1.0f, const std::string &options="") const
write the content of the texture to a file. This method needs support for frame buffer objects.
bool mipmaps_created() const
check whether mipmaps have been created
void set_wrap_s(TextureWrap _wrap_s)
set the texture wrap behaviour in s direction
bool replace(const context &ctx, int x, const cgv::data::const_data_view &data, int level=-1, const std::vector< cgv::data::data_view > *palettes=0)
replace a block within a 1d texture with the given data.
void find_best_format(const context &ctx, const std::vector< cgv::data::data_view > *palettes=0)
find the format that matches the one specified in the component format best
void set_component_format(const component_format &cf)
change component format and clear internal format
void set_border_color(const float *rgba)
set the border color
bool is_enabled() const
check whether textue is enabled
TextureWrap get_wrap_t() const
return the texture wrap behaviour in t direction
bool create_mipmaps(const context &ctx)
create storage for mipmaps without computing the mipmap contents
void set_wrap_r(TextureWrap _wrap_r)
set the texture wrap behaviour in r direction
void set_min_filter(TextureFilter _min_filter, float _anisotropy=2.0f)
set the minification filters, if minification is set to TF_ANISOTROP, the second floating point param...
void set_compare_mode(bool use_compare_function)
set the texture compare mode and function
bool create_from_images(const context &ctx, const std::string &file_names, int level=-1)
Create a cube map from six files specified in the file_names parameter.
bool bind_as_image(const context &ctx, int tex_unit, int level=0, bool bind_array=false, int layer=0, AccessType access=AT_WRITE_ONLY)
Binds this texture as an image texture to the given texture unit.
float get_anisotropy() const
return the currently set anisotropy
incrementally accumulate statistical information
void update(const double &v)
consider another value
double get_max() const
get the maximum of the considered variables
double get_min() const
get the minimum of the considered variables
the tokenizer allows to split text into tokens in a convenient way.
tokenizer & set_sep(const std::string &sep, bool merge)
set the list of separators and specify whether succeeding separators are merged into single tokens
tokenizer & set_ws(const std::string &ws)
set the list of white spaces, that separate tokens and are skipped
namespace for data management components
@ CF_RGB
color format with two components R and G
@ CF_D
color format with components B, G, R and A
AccessType
different access types
TextureFilter
different texture filter
TextureWrap
different texture wrap modes
TextureType
different texture types
CompareFunction
different comparison functions used for depth testing or texture comparisons
@ TI_UINT8
signed integer stored in 64 bits
unsigned int uint32_type
this type provides an 32 bit unsigned integer type
unsigned char uint8_type
this type provides an 8 bit unsigned integer type
namespace that holds tools that dont fit any other namespace
std::string to_string(const std::string &v, unsigned int w, unsigned int p, bool)
specialization of conversion from string to strings