diff --git a/panda/src/gobj/config_gobj.cxx b/panda/src/gobj/config_gobj.cxx index f850482f3d..4ba5c23c4c 100644 --- a/panda/src/gobj/config_gobj.cxx +++ b/panda/src/gobj/config_gobj.cxx @@ -39,131 +39,90 @@ Configure(config_gobj); NotifyCategoryDef(gobj, ""); -// Set this to the maximum size a texture is allowed to be in either -// dimension. This is generally intended as a simple way to restrict -// texture sizes for limited graphics cards. When this is greater -// than zero, each texture image loaded from a file (but only those -// loaded from a file) will be automatically scaled down, if -// necessary, so that neither dimension is larger than this value. -const int max_texture_dimension = config_gobj.GetInt("max-texture-dimension", -1); +ConfigVariableInt max_texture_dimension +("max-texture-dimension", -1, + PRC_DESC("Set this to the maximum size a texture is allowed to be in either " + "dimension. This is generally intended as a simple way to restrict " + "texture sizes for limited graphics cards. When this is greater " + "than zero, each texture image loaded from a file (but only those " + "loaded from a file) will be automatically scaled down, if " + "necessary, so that neither dimension is larger than this value.")); -// Set textures-power-2 to force texture dimensions to a power of two. -// If this is "up" or "down", the textures will be scaled up or down -// to the next power of two, as indicated; otherwise, if this is #t, -// the textures will be scaled down. If this is #f or unspecified, -// the textures will be left at whatever size they are. +ConfigVariableBool keep_texture_ram +("keep-texture-ram", false, + PRC_DESC("Set this to true to retain the ram image for each texture after it " + "has been prepared with the GSG. This will allow the texture to be " + "prepared with multiple GSG, or to be re-prepared later after it is " + "explicitly released from the GSG, without having to reread the " + "texture image from disk; but it will consume memory somewhat " + "wastefully.")); -// These are filled in by the ConfigureFn block, below. -bool textures_up_power_2 = false; -bool textures_down_power_2 = false; +ConfigVariableBool keep_geom_ram +("keep-geom-ram", true, + PRC_DESC("Set this to true to retain the vertices in ram for each geom " + "after it has been prepared with the GSG. This is similar to " + "keep-texture-ram, but it is a little more dangerous, because if " + "anyone calls release_all_geoms() on the GSG (or if there are " + "multiple GSG's rendering a given geom), Panda won't be able to " + "restore the vertices.")); -// Set textures-square to force texture dimensions to a square aspect -// ratio. This works similarly to textures-power-2, above. If this -// is "up" or "down", the textures will be scaled up or down to the -// containing square or the inscribed square, respectively; otherwise, -// if this is #t, the textures will be scaled down. If this is #f or -// unspecified, the textures will be left at whatever size they are. - -// These are filled in by the ConfigureFn block, below. -bool textures_up_square = false; -bool textures_down_square = false; +ConfigVariableBool retained_mode +("retained-mode", false, + PRC_DESC("Set this true to allow the use of retained mode rendering, which " + "creates specific cache information (like display lists or vertex " + "buffers) with the GSG for static geometry, when supported by the " + "GSG. Set it false to use only immediate mode, which sends the " + "vertices to the GSG every frame.")); -// Set this to true to retain the ram image for each texture after it -// has been prepared with the GSG. This will allow the texture to be -// prepared with multiple GSG, or to be re-prepared later after it is -// explicitly released from the GSG, without having to reread the -// texture image from disk; but it will consume memory somewhat -// wastefully. -bool keep_texture_ram = config_gobj.GetBool("keep-texture-ram", false); +ConfigVariableEnum bam_texture_mode +("bam-texture-mode", BTM_relative, + PRC_DESC("Set this to specify how textures should be written into Bam files." + "See the panda source or documentation for available options.")); -// Ditto for Geom's. This is a little more dangerous, because if -// anyone calls release_all_geoms() on the GSG, we won't be able to -// restore them automatically. -bool keep_geom_ram = config_gobj.GetBool("keep-geom-ram", true); +ConfigVariableEnum textures_power_2 +("textures-power-2", ATS_down, + PRC_DESC("Specify whether textures should automatically be constrained to " + "dimensions which are a power of 2 when they are loaded from " + "disk. Set this to 'none' to disable this feature, or to " + "'down' or 'up' to scale down or up to the nearest power of 2, " + "respectively. This only has effect on textures which are not " + "already a power of 2.")); -// Set this true to allow the use of retained mode rendering, which -// creates specific cache information (like display lists or vertex -// buffers) with the GSG for static geometry, when supported by the -// GSG. Set it false to use only immediate mode, which sends the -// vertices to the GSG every frame. -bool retained_mode = config_gobj.GetBool("retained-mode", false); +ConfigVariableEnum textures_square +("textures-square", ATS_none, + PRC_DESC("Specify whether textures should automatically be constrained to " + "a square aspect ratio when they are loaded from disk. Set this " + "to 'none', 'down', or 'up'. See textures-power-2.")); + +ConfigVariableString fake_texture_image +("fake-texture-image", "", + PRC_DESC("Set this to enable a speedy-load mode in which you don't care " + "what the world looks like, you just want it to load in minimal " + "time. This causes all texture loads via the TexturePool to use " + "the same texture file, which will presumably only be loaded " + "once.")); + +ConfigVariableDouble default_near +("default-near", 1.0, + PRC_DESC("The default near clipping distance for all cameras.")); + +ConfigVariableDouble default_far +("default-far", 1000.0, + PRC_DESC("The default far clipping distance for all cameras.")); + +ConfigVariableDouble default_fov +("default-fov", 40.0, + PRC_DESC("The default field of view in degrees for all cameras.")); -// Set this to specify how textures should be written into Bam files. -// Currently, the options are: +ConfigVariableDouble default_keystone +("default-keystone", 0.0f, + PRC_DESC("The default keystone correction, as an x y pair, for all cameras.")); -// fullpath - write the full pathname loaded. -// relative - search for the texture as a filename relative to the -// model-path or texture-path and write the relative pathname. -// basename - write only the basename of the file, no directory portion -// at all. -BamTextureMode bam_texture_mode; - -// Set this to enable a speedy-load mode where you don't care what the -// world looks like, you just want it to load in minimal time. This -// causes all texture loads via the TexturePool to load the same -// texture file, which will presumably only be loaded once. -const string fake_texture_image = config_gobj.GetString("fake-texture-image", ""); - -// The default near and far plane distances. -const float default_near = config_gobj.GetFloat("default-near", 1.0f); -const float default_far = config_gobj.GetFloat("default-far", 1000.0f); - -// The default camera FOV. -const float default_fov = config_gobj.GetFloat("default-fov", 40.0f); - -static BamTextureMode -parse_texture_mode(const string &mode) { - if (cmp_nocase(mode, "unchanged") == 0) { - return BTM_unchanged; - } else if (cmp_nocase(mode, "fullpath") == 0) { - return BTM_fullpath; - } else if (cmp_nocase(mode, "relative") == 0) { - return BTM_relative; - } else if (cmp_nocase(mode, "basename") == 0) { - return BTM_basename; - } else if (cmp_nocase(mode, "rawdata") == 0) { - return BTM_rawdata; - } - - gobj_cat->error() << "Invalid bam-texture-mode: " << mode << "\n"; - return BTM_relative; -} ConfigureFn(config_gobj) { - string texture_mode = config_util.GetString("bam-texture-mode", "relative"); - bam_texture_mode = parse_texture_mode(texture_mode); - - string textures_power_2 = config_gobj.GetString("textures-power-2", ""); - if (cmp_nocase(textures_power_2, "up") == 0) { - textures_up_power_2 = true; - textures_down_power_2 = false; - - } else if (cmp_nocase(textures_power_2, "down") == 0) { - textures_up_power_2 = false; - textures_down_power_2 = true; - - } else { - textures_up_power_2 = false; - textures_down_power_2 = config_gobj.GetBool("textures-power-2", false); - } - - string textures_square = config_gobj.GetString("textures-square", ""); - if (cmp_nocase(textures_square, "up") == 0) { - textures_up_square = true; - textures_down_square = false; - - } else if (cmp_nocase(textures_square, "down") == 0) { - textures_up_square = false; - textures_down_square = true; - - } else { - textures_up_square = false; - textures_down_square = config_gobj.GetBool("textures-square", false); - } - BoundedObject::init_type(); Geom::init_type(); GeomLine::init_type(); @@ -208,3 +167,93 @@ ConfigureFn(config_gobj) { TextureStage::register_with_read_factory(); TexCoordName::register_with_read_factory(); } + +ostream & +operator << (ostream &out, BamTextureMode btm) { + switch (btm) { + case BTM_unchanged: + return out << "unchanged"; + + case BTM_fullpath: + return out << "fullpath"; + + case BTM_relative: + return out << "relative"; + + case BTM_basename: + return out << "basename"; + + case BTM_rawdata: + return out << "rawdata"; + } + + return out << "**invalid BamTextureMode (" << (int)btm << ")**"; +} + +istream & +operator >> (istream &in, BamTextureMode &btm) { + string word; + in >> word; + + if (cmp_nocase(word, "unchanged") == 0) { + btm = BTM_unchanged; + } else if (cmp_nocase(word, "fullpath") == 0) { + btm = BTM_fullpath; + } else if (cmp_nocase(word, "relative") == 0) { + btm = BTM_relative; + } else if (cmp_nocase(word, "basename") == 0) { + btm = BTM_basename; + } else if (cmp_nocase(word, "rawdata") == 0) { + btm = BTM_rawdata; + + } else { + gobj_cat->error() << "Invalid BamTextureMode value: " << word << "\n"; + btm = BTM_relative; + } + + return in; +} + +ostream & +operator << (ostream &out, AutoTextureScale ats) { + switch (ats) { + case ATS_none: + return out << "none"; + + case ATS_down: + return out << "down"; + + case ATS_up: + return out << "up"; + } + + return out << "**invalid AutoTextureScale (" << (int)ats << ")**"; +} + +istream & +operator >> (istream &in, AutoTextureScale &ats) { + string word; + in >> word; + + if (cmp_nocase(word, "none") == 0 || + cmp_nocase(word, "0") == 0 || + cmp_nocase(word, "#f") == 0 || + tolower(word[0] == 'f')) { + ats = ATS_none; + + } else if (cmp_nocase(word, "down") == 0 || + cmp_nocase(word, "1") == 0 || + cmp_nocase(word, "#t") == 0 || + tolower(word[0] == 't')) { + ats = ATS_down; + + } else if (cmp_nocase(word, "up") == 0) { + ats = ATS_up; + + } else { + gobj_cat->error() << "Invalid AutoTextureScale value: " << word << "\n"; + ats = ATS_none; + } + + return in; +} diff --git a/panda/src/gobj/config_gobj.h b/panda/src/gobj/config_gobj.h index dd05d9da98..5ae330f583 100644 --- a/panda/src/gobj/config_gobj.h +++ b/panda/src/gobj/config_gobj.h @@ -21,19 +21,13 @@ #include "pandabase.h" #include "notifyCategoryProxy.h" +#include "configVariableBool.h" +#include "configVariableInt.h" +#include "configVariableEnum.h" +#include "configVariableDouble.h" NotifyCategoryDecl(gobj, EXPCL_PANDA, EXPTP_PANDA); -// Configure variables for gobj package. -extern EXPCL_PANDA const int max_texture_dimension; -extern EXPCL_PANDA bool textures_up_power_2; -extern EXPCL_PANDA bool textures_down_power_2; -extern EXPCL_PANDA bool textures_up_square; -extern EXPCL_PANDA bool textures_down_square; -extern EXPCL_PANDA bool keep_texture_ram; -extern EXPCL_PANDA bool keep_geom_ram; -extern EXPCL_PANDA bool retained_mode; - enum BamTextureMode { BTM_unchanged, BTM_fullpath, @@ -41,12 +35,32 @@ enum BamTextureMode { BTM_basename, BTM_rawdata }; -extern EXPCL_PANDA BamTextureMode bam_texture_mode; -extern EXPCL_PANDA const string fake_texture_image; +ostream &operator << (ostream &out, BamTextureMode btm); +istream &operator >> (istream &in, BamTextureMode &btm); -extern const float default_near; -extern const float default_far; -extern const float default_fov; +enum AutoTextureScale { + ATS_none, + ATS_down, + ATS_up +}; +ostream &operator << (ostream &out, AutoTextureScale ats); +istream &operator >> (istream &in, AutoTextureScale &ats); + +// Configure variables for gobj package. +extern EXPCL_PANDA ConfigVariableInt max_texture_dimension; +extern EXPCL_PANDA ConfigVariableBool keep_texture_ram; +extern EXPCL_PANDA ConfigVariableBool keep_geom_ram; +extern EXPCL_PANDA ConfigVariableBool retained_mode; + +extern EXPCL_PANDA ConfigVariableEnum bam_texture_mode; +extern EXPCL_PANDA ConfigVariableEnum textures_power_2; +extern EXPCL_PANDA ConfigVariableEnum textures_square; +extern EXPCL_PANDA ConfigVariableString fake_texture_image; + +extern ConfigVariableDouble default_near; +extern ConfigVariableDouble default_far; +extern ConfigVariableDouble default_fov; +extern ConfigVariableDouble default_keystone; #endif diff --git a/panda/src/gobj/lens.I b/panda/src/gobj/lens.I index f1b01685b7..0ea64cc8ad 100644 --- a/panda/src/gobj/lens.I +++ b/panda/src/gobj/lens.I @@ -391,6 +391,17 @@ set_view_vector(float x, float y, float z, float i, float j, float k) { set_view_vector(LVector3f(x, y, z), LVector3f(i, j, k)); } +//////////////////////////////////////////////////////////////////// +// Function: Lens::get_keystone +// Access: Published +// Description: Returns the keystone correction specified for the +// lens. +//////////////////////////////////////////////////////////////////// +INLINE const LVecBase2f &Lens:: +get_keystone() const { + return _keystone; +} + //////////////////////////////////////////////////////////////////// // Function: Lens::get_last_change // Access: Public diff --git a/panda/src/gobj/lens.cxx b/panda/src/gobj/lens.cxx index ae45611c93..6c8175f23b 100644 --- a/panda/src/gobj/lens.cxx +++ b/panda/src/gobj/lens.cxx @@ -105,10 +105,16 @@ clear() { _view_vector.set(0.0f, 1.0f, 0.0f); _up_vector.set(0.0f, 0.0f, 1.0f); _iod_offset = 0.0f; - _keystone.set(0.0f, 0.0f, 0.0f); + _keystone.set(0.0f, 0.0f); + _user_flags = 0; _comp_flags = CF_fov; + if (default_keystone.has_value()) { + _keystone.set(default_keystone[0], default_keystone[1]); + _user_flags |= UF_keystone; + } + // Assign an initial arbitrary sequence to these three. _film_size_seq = 0; _focal_length_seq = 1; @@ -598,38 +604,30 @@ clear_view_mat() { // matrix that will compensate for keystoning of a // projected image; this can be used to compensate for a // projector that for physical reasons cannot be aimed -// directly at it screen. The default value of 0, 0, 0 -// indicates no keystone correction; specify a small -// value (usually in the range -1 .. 1) in one of the -// three axes to generate a keystone correction in that -// axis. +// directly at it screen. +// +// The default value is taken from the default-keystone +// Config variable. 0, 0 indicates no keystone +// correction; specify a small value (usually in the +// range -1 .. 1) in either the x or y position to +// generate a keystone correction in that axis. //////////////////////////////////////////////////////////////////// void Lens:: -set_keystone(const LVecBase3f &keystone) { +set_keystone(const LVecBase2f &keystone) { _keystone = keystone; adjust_user_flags(0, UF_keystone); adjust_comp_flags(CF_projection_mat | CF_projection_mat_inv | CF_film_mat | CF_film_mat_inv, 0); throw_change_event(); } -//////////////////////////////////////////////////////////////////// -// Function: Lens::get_keystone -// Access: Published -// Description: Returns the direction in which the lens is facing. -//////////////////////////////////////////////////////////////////// -const LVecBase3f &Lens:: -get_keystone() const { - return _keystone; -} - //////////////////////////////////////////////////////////////////// // Function: Lens::clear_keystone // Access: Published -// Description: Resets the lens transform to identity. +// Description: Disables the lens keystone correction. //////////////////////////////////////////////////////////////////// void Lens:: clear_keystone() { - _keystone = LVecBase3f(0.0f, 0.0f, 0.0f); + _keystone.set(0.0f, 0.0f); adjust_user_flags(UF_keystone, 0); adjust_comp_flags(CF_projection_mat | CF_projection_mat_inv | CF_film_mat | CF_film_mat_inv, 0); throw_change_event(); @@ -1449,9 +1447,9 @@ compute_film_mat() { -film_offset[0] * scale_x, -film_offset[1] * scale_y, 0.0f, 1.0f); if ((_user_flags & UF_keystone) != 0) { - _film_mat = LMatrix4f(csqrt(1.0f - _keystone[0] * _keystone[0]), 0.0f, 0.0f, _keystone[0], - 0.0f, csqrt(1.0f - _keystone[1] * _keystone[1]), 0.0f, _keystone[1], - 0.0f, 0.0f, csqrt(1.0f - _keystone[2] * _keystone[2]), _keystone[2], + _film_mat = LMatrix4f(1.0f, 0.0f, _keystone[0], _keystone[0], + 0.0f, 1.0f, _keystone[1], _keystone[1], + 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f) * _film_mat; } diff --git a/panda/src/gobj/lens.h b/panda/src/gobj/lens.h index 543400199a..29816c7f2f 100644 --- a/panda/src/gobj/lens.h +++ b/panda/src/gobj/lens.h @@ -112,8 +112,8 @@ PUBLISHED: const LMatrix4f &get_view_mat() const; void clear_view_mat(); - void set_keystone(const LVecBase3f &keystone); - const LVecBase3f &get_keystone() const; + void set_keystone(const LVecBase2f &keystone); + INLINE const LVecBase2f &get_keystone() const; void clear_keystone(); // These flags are passed in as the last parameter to control the @@ -125,6 +125,7 @@ PUBLISHED: FC_off_axis = 0x0004, FC_aspect_ratio = 0x0008, FC_shear = 0x0010, + FC_keystone = 0x0020, }; void set_frustum_from_corners(const LVecBase3f &ul, const LVecBase3f &ur, const LVecBase3f &ll, const LVecBase3f &lr, @@ -202,7 +203,7 @@ protected: LVecBase3f _view_hpr; LVector3f _view_vector, _up_vector; float _iod_offset; - LVecBase3f _keystone; + LVecBase2f _keystone; LMatrix4f _film_mat, _film_mat_inv; LMatrix4f _lens_mat, _lens_mat_inv; diff --git a/panda/src/gobj/texture.cxx b/panda/src/gobj/texture.cxx index 67c5b90e2d..a60688eb32 100644 --- a/panda/src/gobj/texture.cxx +++ b/panda/src/gobj/texture.cxx @@ -71,23 +71,37 @@ consider_rescale(PNMImage &pnmimage, const string &name) { int new_x_size = pnmimage.get_x_size(); int new_y_size = pnmimage.get_y_size(); - if (textures_down_power_2) { + switch (textures_power_2) { + case ATS_down: new_x_size = down_to_power_2(new_x_size); new_y_size = down_to_power_2(new_y_size); - } else if (textures_up_power_2) { + break; + + case ATS_up: new_x_size = up_to_power_2(new_x_size); new_y_size = up_to_power_2(new_y_size); + break; + + case ATS_none: + break; } - if (textures_down_square) { + switch (textures_square) { + case ATS_down: new_x_size = new_y_size = min(new_x_size, new_y_size); - } else if (textures_up_square) { + break; + + case ATS_up: new_x_size = new_y_size = max(new_x_size, new_y_size); + break; + + case ATS_none: + break; } if (max_texture_dimension > 0) { - new_x_size = min(new_x_size, max_texture_dimension); - new_y_size = min(new_y_size, max_texture_dimension); + new_x_size = min(new_x_size, (int)max_texture_dimension); + new_y_size = min(new_y_size, (int)max_texture_dimension); } if (pnmimage.get_x_size() != new_x_size || diff --git a/panda/src/grutil/multitexReducer.cxx b/panda/src/grutil/multitexReducer.cxx index d0ca3c3e71..9baaeb7737 100644 --- a/panda/src/grutil/multitexReducer.cxx +++ b/panda/src/grutil/multitexReducer.cxx @@ -620,8 +620,8 @@ choose_texture_size(int &x_size, int &y_size, // Constrain the x_size and y_size to the max_texture_dimension. if (max_texture_dimension > 0) { - x_size = min(x_size, max_texture_dimension); - y_size = min(y_size, max_texture_dimension); + x_size = min(x_size, (int)max_texture_dimension); + y_size = min(y_size, (int)max_texture_dimension); } // Finally, make sure the new sizes fit within the window, so we can diff --git a/panda/src/pgraph/transparencyAttrib.cxx b/panda/src/pgraph/transparencyAttrib.cxx index c97c73db3e..8aeb7362bc 100644 --- a/panda/src/pgraph/transparencyAttrib.cxx +++ b/panda/src/pgraph/transparencyAttrib.cxx @@ -83,6 +83,9 @@ output(ostream &out) const { case M_dual: out << "dual"; break; + + case M_notused: + break; } }