compressed textures, texture objects
This commit is contained in:
parent
4f9c62a0d6
commit
e6369ba5a4
|
|
@ -744,6 +744,63 @@ flip_frame() {
|
|||
do_flip_frame();
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsEngine::extract_texture_data
|
||||
// Access: Published
|
||||
// Description: Asks the indicated GraphicsStateGuardian to retrieve
|
||||
// the texture memory image of the indicated texture and
|
||||
// store it in the texture's ram_image field. The image
|
||||
// can then be written to disk via Texture::write(), or
|
||||
// otherwise manipulated on the CPU.
|
||||
//
|
||||
// This is useful for retrieving the contents of a
|
||||
// texture that has been somehow generated on the
|
||||
// graphics card, instead of having been loaded the
|
||||
// normal way via Texture::read() or Texture::load().
|
||||
// It is particularly useful for getting the data
|
||||
// associated with a compressed texture image.
|
||||
//
|
||||
// Since this requires a round-trip to the draw thread,
|
||||
// it may require waiting for the current thread to
|
||||
// finish rendering if it is called in a multithreaded
|
||||
// environment. However, you can call this several
|
||||
// consecutive times on different textures for little
|
||||
// additional cost.
|
||||
//
|
||||
// If the texture has not yet been loaded to the GSG in
|
||||
// question, it will be loaded immediately.
|
||||
//
|
||||
// The return value is true if the operation is
|
||||
// successful, false otherwise.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool GraphicsEngine::
|
||||
extract_texture_data(Texture *tex, GraphicsStateGuardian *gsg) {
|
||||
MutexHolder holder(_lock);
|
||||
|
||||
string draw_name = gsg->get_threading_model().get_draw_name();
|
||||
if (draw_name.empty()) {
|
||||
// A single-threaded environment. No problem.
|
||||
return gsg->extract_texture_data(tex);
|
||||
|
||||
} else {
|
||||
// A multi-threaded environment. We have to wait until the draw
|
||||
// thread has finished its current task.
|
||||
WindowRenderer *wr = get_window_renderer(draw_name, 0);
|
||||
RenderThread *thread = (RenderThread *)wr;
|
||||
MutexHolder holder2(thread->_cv_mutex);
|
||||
|
||||
while (thread->_thread_state != TS_wait) {
|
||||
thread->_cv_done.wait();
|
||||
}
|
||||
|
||||
// OK, now the draw thread is idle. That's really good enough for
|
||||
// our purposes; we don't *actually* need to make the draw thread
|
||||
// do the work--it's sufficient that it's not doing anything else
|
||||
// while we access the GSG.
|
||||
return gsg->extract_texture_data(tex);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsEngine::add_callback
|
||||
|
|
|
|||
|
|
@ -97,6 +97,8 @@ PUBLISHED:
|
|||
void sync_frame();
|
||||
void flip_frame();
|
||||
|
||||
bool extract_texture_data(Texture *tex, GraphicsStateGuardian *gsg);
|
||||
|
||||
public:
|
||||
enum ThreadState {
|
||||
TS_wait,
|
||||
|
|
|
|||
|
|
@ -356,6 +356,29 @@ get_supports_tex_non_pow2() const {
|
|||
return _supports_tex_non_pow2;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsStateGuardian::get_supports_compressed_texture
|
||||
// Access: Published
|
||||
// Description: Returns true if this GSG can compress textures as it
|
||||
// loads them into texture memory, and/or accept
|
||||
// pre-compressed textures for storing.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool GraphicsStateGuardian::
|
||||
get_supports_compressed_texture() const {
|
||||
return _supports_compressed_texture;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsStateGuardian::get_supports_compressed_texture_format
|
||||
// Access: Published
|
||||
// Description: Returns true if this GSG can accept textures
|
||||
// pre-compressed in the indicated format.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool GraphicsStateGuardian::
|
||||
get_supports_compressed_texture_format(Texture::CompressionMode compression) const {
|
||||
return _compressed_texture_formats.get_bit(compression);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsStateGuardian::get_max_lights
|
||||
// Access: Published
|
||||
|
|
|
|||
|
|
@ -136,6 +136,9 @@ GraphicsStateGuardian(const FrameBufferProperties &properties,
|
|||
_supports_3d_texture = false;
|
||||
_supports_cube_map = false;
|
||||
_supports_tex_non_pow2 = false;
|
||||
_supports_compressed_texture = false;
|
||||
_compressed_texture_formats.clear();
|
||||
_compressed_texture_formats.set_bit(Texture::CM_off);
|
||||
|
||||
// Assume no limits on number of lights or clip planes.
|
||||
_max_lights = -1;
|
||||
|
|
@ -415,6 +418,23 @@ void GraphicsStateGuardian::
|
|||
release_texture(TextureContext *) {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsStateGuardian::extract_texture_data
|
||||
// Access: Public, Virtual
|
||||
// Description: This method should only be called by the
|
||||
// GraphicsEngine. Do not call it directly; call
|
||||
// GraphicsEngine::extract_texture_data() instead.
|
||||
//
|
||||
// This method will be called in the draw thread to
|
||||
// download the texture memory's image into its
|
||||
// ram_image value. It returns true on success, false
|
||||
// otherwise.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool GraphicsStateGuardian::
|
||||
extract_texture_data(Texture *) {
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsStateGuardian::prepare_geom
|
||||
// Access: Public, Virtual
|
||||
|
|
|
|||
|
|
@ -43,6 +43,8 @@
|
|||
#include "pvector.h"
|
||||
#include "attribSlots.h"
|
||||
#include "shaderContext.h"
|
||||
#include "bitMask.h"
|
||||
#include "texture.h"
|
||||
|
||||
class DrawableRegion;
|
||||
class GraphicsEngine;
|
||||
|
|
@ -99,6 +101,9 @@ PUBLISHED:
|
|||
INLINE bool get_supports_cube_map() const;
|
||||
INLINE bool get_supports_tex_non_pow2() const;
|
||||
|
||||
INLINE bool get_supports_compressed_texture() const;
|
||||
INLINE bool get_supports_compressed_texture_format(Texture::CompressionMode compression) const;
|
||||
|
||||
INLINE int get_max_lights() const;
|
||||
INLINE int get_max_clip_planes() const;
|
||||
|
||||
|
|
@ -132,6 +137,7 @@ public:
|
|||
|
||||
virtual TextureContext *prepare_texture(Texture *tex);
|
||||
virtual void release_texture(TextureContext *tc);
|
||||
virtual bool extract_texture_data(Texture *tex);
|
||||
|
||||
virtual GeomContext *prepare_geom(Geom *geom);
|
||||
virtual void release_geom(GeomContext *gc);
|
||||
|
|
@ -347,6 +353,9 @@ protected:
|
|||
bool _supports_cube_map;
|
||||
bool _supports_tex_non_pow2;
|
||||
|
||||
bool _supports_compressed_texture;
|
||||
BitMask32 _compressed_texture_formats;
|
||||
|
||||
int _max_lights;
|
||||
int _max_clip_planes;
|
||||
|
||||
|
|
|
|||
|
|
@ -148,6 +148,13 @@ DXGraphicsStateGuardian8::
|
|||
TextureContext *DXGraphicsStateGuardian8::
|
||||
prepare_texture(Texture *tex) {
|
||||
DXTextureContext8 *dtc = new DXTextureContext8(tex);
|
||||
|
||||
if (!get_supports_compressed_texture_format(tex->get_ram_image_compression())) {
|
||||
dxgsg8_cat.error()
|
||||
<< *dtc->_texture << " is stored in an unsupported compressed format.\n";
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!dtc->create_texture(*_screen)) {
|
||||
delete dtc;
|
||||
return NULL;
|
||||
|
|
@ -189,7 +196,14 @@ apply_texture(int i, TextureContext *tc) {
|
|||
// error or oversight.
|
||||
if ((dirty & Texture::DF_image) == 0) {
|
||||
dxgsg8_cat.warning()
|
||||
<< "Texture " << *dtc->_texture << " has changed mipmap state.\n";
|
||||
<< *dtc->_texture << " has changed mipmap state.\n";
|
||||
}
|
||||
|
||||
if (!get_supports_compressed_texture_format(tc->_texture->get_ram_image_compression())) {
|
||||
dxgsg8_cat.error()
|
||||
<< *dtc->_texture << " is stored in an unsupported compressed format.\n";
|
||||
_d3d_device->SetTextureStageState(i, D3DTSS_COLOROP, D3DTOP_DISABLE);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!dtc->create_texture(*_screen)) {
|
||||
|
|
|
|||
|
|
@ -191,6 +191,13 @@ DXGraphicsStateGuardian9::
|
|||
TextureContext *DXGraphicsStateGuardian9::
|
||||
prepare_texture(Texture *tex) {
|
||||
DXTextureContext9 *dtc = new DXTextureContext9(tex);
|
||||
|
||||
if (!get_supports_compressed_texture_format(tex->get_ram_image_compression())) {
|
||||
dxgsg9_cat.error()
|
||||
<< *dtc->_texture << " is stored in an unsupported compressed format.\n";
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!dtc->create_texture(*_screen)) {
|
||||
delete dtc;
|
||||
return NULL;
|
||||
|
|
@ -237,7 +244,14 @@ apply_texture(int i, TextureContext *tc) {
|
|||
// error or oversight.
|
||||
if ((dirty & Texture::DF_image) == 0) {
|
||||
dxgsg9_cat.warning()
|
||||
<< "Texture " << *dtc->_texture << " has changed mipmap state.\n";
|
||||
<< *dtc->_texture << " has changed mipmap state.\n";
|
||||
}
|
||||
|
||||
if (!get_supports_compressed_texture_format(tc->_texture->get_ram_image_compression())) {
|
||||
dxgsg9_cat.error()
|
||||
<< *dtc->_texture << " is stored in an unsupported compressed format.\n";
|
||||
_d3d_device->SetTextureStageState(i, D3DTSS_COLOROP, D3DTOP_DISABLE);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!dtc->create_texture(*_screen)) {
|
||||
|
|
|
|||
|
|
@ -63,6 +63,26 @@ get_format() const {
|
|||
return _format;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggTexture::set_compression_mode
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void EggTexture::
|
||||
set_compression_mode(CompressionMode mode) {
|
||||
_compression_mode = mode;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggTexture::get_compression_mode
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE EggTexture::CompressionMode EggTexture::
|
||||
get_compression_mode() const {
|
||||
return _compression_mode;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggTexture::set_wrap_mode
|
||||
// Access: Published
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@ EggTexture(const string &tref_name, const string &filename)
|
|||
{
|
||||
_texture_type = TT_unspecified;
|
||||
_format = F_unspecified;
|
||||
_compression_mode = CM_default;
|
||||
_wrap_mode = WM_unspecified;
|
||||
_wrap_u = WM_unspecified;
|
||||
_wrap_v = WM_unspecified;
|
||||
|
|
@ -80,6 +81,7 @@ operator = (const EggTexture ©) {
|
|||
|
||||
_texture_type = copy._texture_type;
|
||||
_format = copy._format;
|
||||
_compression_mode = copy._compression_mode;
|
||||
_wrap_mode = copy._wrap_mode;
|
||||
_wrap_u = copy._wrap_u;
|
||||
_wrap_v = copy._wrap_v;
|
||||
|
|
@ -152,6 +154,11 @@ write(ostream &out, int indent_level) const {
|
|||
<< "<Scalar> format { " << get_format() << " }\n";
|
||||
}
|
||||
|
||||
if (get_compression_mode() != CM_default) {
|
||||
indent(out, indent_level + 2)
|
||||
<< "<Scalar> compression { " << get_compression_mode() << " }\n";
|
||||
}
|
||||
|
||||
if (get_wrap_mode() != WM_unspecified) {
|
||||
indent(out, indent_level + 2)
|
||||
<< "<Scalar> wrap { " << get_wrap_mode() << " }\n";
|
||||
|
|
@ -360,6 +367,7 @@ is_equivalent_to(const EggTexture &other, int eq) const {
|
|||
//cout << "compared by attributes" << endl;
|
||||
if (_texture_type != other._texture_type ||
|
||||
_format != other._format ||
|
||||
_compression_mode != other._compression_mode ||
|
||||
_wrap_mode != other._wrap_mode ||
|
||||
_wrap_u != other._wrap_u ||
|
||||
_wrap_v != other._wrap_v ||
|
||||
|
|
@ -442,6 +450,9 @@ sorts_less_than(const EggTexture &other, int eq) const {
|
|||
if (_format != other._format) {
|
||||
return (int)_format < (int)other._format;
|
||||
}
|
||||
if (_compression_mode != other._compression_mode) {
|
||||
return (int)_compression_mode < (int)other._compression_mode;
|
||||
}
|
||||
if (_wrap_mode != other._wrap_mode) {
|
||||
return (int)_wrap_mode < (int)other._wrap_mode;
|
||||
}
|
||||
|
|
@ -617,7 +628,7 @@ string_texture_type(const string &string) {
|
|||
} else if (cmp_nocase_uh(string, "3d") == 0 ||
|
||||
cmp_nocase_uh(string, "3dtexture") == 0 ||
|
||||
cmp_nocase_uh(string, "3d_texture") == 0) {
|
||||
return TT_2d_texture;
|
||||
return TT_3d_texture;
|
||||
|
||||
} else if (cmp_nocase_uh(string, "cube") == 0 ||
|
||||
cmp_nocase_uh(string, "cubemap") == 0 ||
|
||||
|
|
@ -680,6 +691,36 @@ string_format(const string &string) {
|
|||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggTexture::string_compression_mode
|
||||
// Access: Published, Static
|
||||
// Description: Returns the CompressionMode value associated with the given
|
||||
// string representation, or CM_default if the string
|
||||
// does not match any known CompressionMode value.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
EggTexture::CompressionMode EggTexture::
|
||||
string_compression_mode(const string &string) {
|
||||
if (cmp_nocase_uh(string, "off") == 0) {
|
||||
return CM_off;
|
||||
} else if (cmp_nocase_uh(string, "on") == 0) {
|
||||
return CM_on;
|
||||
} else if (cmp_nocase_uh(string, "fxt1") == 0) {
|
||||
return CM_fxt1;
|
||||
} else if (cmp_nocase_uh(string, "dxt1") == 0) {
|
||||
return CM_dxt1;
|
||||
} else if (cmp_nocase_uh(string, "dxt2") == 0) {
|
||||
return CM_dxt2;
|
||||
} else if (cmp_nocase_uh(string, "dxt3") == 0) {
|
||||
return CM_dxt3;
|
||||
} else if (cmp_nocase_uh(string, "dxt4") == 0) {
|
||||
return CM_dxt4;
|
||||
} else if (cmp_nocase_uh(string, "dxt5") == 0) {
|
||||
return CM_dxt5;
|
||||
} else {
|
||||
return CM_default;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggTexture::string_wrap_mode
|
||||
// Access: Published, Static
|
||||
|
|
@ -1067,6 +1108,36 @@ ostream &operator << (ostream &out, EggTexture::Format format) {
|
|||
return out << "(**invalid**)";
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CompressionMode output operator
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
ostream &operator << (ostream &out, EggTexture::CompressionMode mode) {
|
||||
switch (mode) {
|
||||
case EggTexture::CM_default:
|
||||
return out << "default";
|
||||
case EggTexture::CM_off:
|
||||
return out << "off";
|
||||
case EggTexture::CM_on:
|
||||
return out << "on";
|
||||
case EggTexture::CM_fxt1:
|
||||
return out << "fxt1";
|
||||
case EggTexture::CM_dxt1:
|
||||
return out << "dxt1";
|
||||
case EggTexture::CM_dxt2:
|
||||
return out << "dxt2";
|
||||
case EggTexture::CM_dxt3:
|
||||
return out << "dxt3";
|
||||
case EggTexture::CM_dxt4:
|
||||
return out << "dxt4";
|
||||
case EggTexture::CM_dxt5:
|
||||
return out << "dxt5";
|
||||
}
|
||||
|
||||
nassertr(false, out);
|
||||
return out << "(**invalid**)";
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: WrapMode output operator
|
||||
// Description:
|
||||
|
|
|
|||
|
|
@ -69,6 +69,10 @@ PUBLISHED:
|
|||
F_red, F_green, F_blue, F_alpha, F_luminance,
|
||||
F_luminance_alpha, F_luminance_alphamask
|
||||
};
|
||||
enum CompressionMode {
|
||||
CM_default, CM_off, CM_on,
|
||||
CM_fxt1, CM_dxt1, CM_dxt2, CM_dxt3, CM_dxt4, CM_dxt5,
|
||||
};
|
||||
enum WrapMode {
|
||||
WM_unspecified, WM_clamp, WM_repeat,
|
||||
WM_mirror, WM_mirror_once, WM_border_color
|
||||
|
|
@ -157,6 +161,9 @@ PUBLISHED:
|
|||
INLINE void set_format(Format format);
|
||||
INLINE Format get_format() const;
|
||||
|
||||
INLINE void set_compression_mode(CompressionMode mode);
|
||||
INLINE CompressionMode get_compression_mode() const;
|
||||
|
||||
INLINE void set_wrap_mode(WrapMode mode);
|
||||
INLINE WrapMode get_wrap_mode() const;
|
||||
|
||||
|
|
@ -253,6 +260,7 @@ PUBLISHED:
|
|||
|
||||
static TextureType string_texture_type(const string &string);
|
||||
static Format string_format(const string &string);
|
||||
static CompressionMode string_compression_mode(const string &string);
|
||||
static WrapMode string_wrap_mode(const string &string);
|
||||
static FilterType string_filter_type(const string &string);
|
||||
static EnvType string_env_type(const string &string);
|
||||
|
|
@ -286,6 +294,7 @@ private:
|
|||
|
||||
TextureType _texture_type;
|
||||
Format _format;
|
||||
CompressionMode _compression_mode;
|
||||
WrapMode _wrap_mode, _wrap_u, _wrap_v, _wrap_w;
|
||||
FilterType _minfilter, _magfilter;
|
||||
int _anisotropic_degree;
|
||||
|
|
@ -367,6 +376,7 @@ INLINE ostream &operator << (ostream &out, const EggTexture &n) {
|
|||
|
||||
EXPCL_PANDAEGG ostream &operator << (ostream &out, EggTexture::TextureType texture_type);
|
||||
EXPCL_PANDAEGG ostream &operator << (ostream &out, EggTexture::Format format);
|
||||
EXPCL_PANDAEGG ostream &operator << (ostream &out, EggTexture::CompressionMode mode);
|
||||
EXPCL_PANDAEGG ostream &operator << (ostream &out, EggTexture::WrapMode mode);
|
||||
EXPCL_PANDAEGG ostream &operator << (ostream &out, EggTexture::FilterType type);
|
||||
EXPCL_PANDAEGG ostream &operator << (ostream &out, EggTexture::EnvType type);
|
||||
|
|
|
|||
|
|
@ -360,6 +360,14 @@ texture_body:
|
|||
texture->set_format(f);
|
||||
}
|
||||
|
||||
} else if (cmp_nocase_uh(name, "compression") == 0) {
|
||||
EggTexture::CompressionMode w = EggTexture::string_compression_mode(strval);
|
||||
if (w == EggTexture::CM_default) {
|
||||
eggyywarning("Unknown texture compression mode " + strval);
|
||||
} else {
|
||||
texture->set_compression_mode(w);
|
||||
}
|
||||
|
||||
} else if (cmp_nocase_uh(name, "wrap") == 0) {
|
||||
EggTexture::WrapMode w = EggTexture::string_wrap_mode(strval);
|
||||
if (w == EggTexture::WM_unspecified) {
|
||||
|
|
|
|||
|
|
@ -933,9 +933,23 @@ load_texture(TextureDef &def, const EggTexture *egg_tex) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void EggLoader::
|
||||
apply_texture_attributes(Texture *tex, const EggTexture *egg_tex) {
|
||||
tex->set_wrap_u(convert_wrap_mode(egg_tex->determine_wrap_u()));
|
||||
tex->set_wrap_v(convert_wrap_mode(egg_tex->determine_wrap_v()));
|
||||
tex->set_wrap_w(convert_wrap_mode(egg_tex->determine_wrap_w()));
|
||||
if (egg_tex->get_compression_mode() != EggTexture::CM_default) {
|
||||
tex->set_compression(convert_compression_mode(egg_tex->get_compression_mode()));
|
||||
}
|
||||
|
||||
EggTexture::WrapMode wrap_u = egg_tex->determine_wrap_u();
|
||||
EggTexture::WrapMode wrap_v = egg_tex->determine_wrap_v();
|
||||
EggTexture::WrapMode wrap_w = egg_tex->determine_wrap_w();
|
||||
|
||||
if (wrap_u != EggTexture::WM_unspecified) {
|
||||
tex->set_wrap_u(convert_wrap_mode(wrap_u));
|
||||
}
|
||||
if (wrap_v != EggTexture::WM_unspecified) {
|
||||
tex->set_wrap_v(convert_wrap_mode(wrap_v));
|
||||
}
|
||||
if (wrap_w != EggTexture::WM_unspecified) {
|
||||
tex->set_wrap_w(convert_wrap_mode(wrap_w));
|
||||
}
|
||||
|
||||
if (egg_tex->has_border_color()) {
|
||||
tex->set_border_color(egg_tex->get_border_color());
|
||||
|
|
@ -1013,12 +1027,7 @@ apply_texture_attributes(Texture *tex, const EggTexture *egg_tex) {
|
|||
break;
|
||||
|
||||
case EggTexture::FT_unspecified:
|
||||
// Default is bilinear, unless egg_ignore_filters is specified.
|
||||
if (egg_ignore_filters) {
|
||||
tex->set_minfilter(Texture::FT_nearest);
|
||||
} else {
|
||||
tex->set_minfilter(Texture::FT_linear);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
switch (egg_tex->get_magfilter()) {
|
||||
|
|
@ -1041,12 +1050,7 @@ apply_texture_attributes(Texture *tex, const EggTexture *egg_tex) {
|
|||
break;
|
||||
|
||||
case EggTexture::FT_unspecified:
|
||||
// Default is bilinear, unless egg_ignore_filters is specified.
|
||||
if (egg_ignore_filters) {
|
||||
tex->set_magfilter(Texture::FT_nearest);
|
||||
} else {
|
||||
tex->set_magfilter(Texture::FT_linear);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (egg_tex->has_anisotropic_degree()) {
|
||||
|
|
@ -1176,6 +1180,50 @@ apply_texture_attributes(Texture *tex, const EggTexture *egg_tex) {
|
|||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggLoader::convert_compression_mode
|
||||
// Access: Private
|
||||
// Description: Returns the Texture::CompressionMode enum
|
||||
// corresponding to the EggTexture::CompressionMode.
|
||||
// Returns CM_default if the compression mode is
|
||||
// unspecified.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
Texture::CompressionMode EggLoader::
|
||||
convert_compression_mode(EggTexture::CompressionMode compression_mode) const {
|
||||
switch (compression_mode) {
|
||||
case EggTexture::CM_off:
|
||||
return Texture::CM_off;
|
||||
|
||||
case EggTexture::CM_on:
|
||||
return Texture::CM_on;
|
||||
|
||||
case EggTexture::CM_fxt1:
|
||||
return Texture::CM_fxt1;
|
||||
|
||||
case EggTexture::CM_dxt1:
|
||||
return Texture::CM_dxt1;
|
||||
|
||||
case EggTexture::CM_dxt2:
|
||||
return Texture::CM_dxt2;
|
||||
|
||||
case EggTexture::CM_dxt3:
|
||||
return Texture::CM_dxt3;
|
||||
|
||||
case EggTexture::CM_dxt4:
|
||||
return Texture::CM_dxt4;
|
||||
|
||||
case EggTexture::CM_dxt5:
|
||||
return Texture::CM_dxt5;
|
||||
|
||||
case EggTexture::CM_default:
|
||||
return Texture::CM_default;
|
||||
}
|
||||
|
||||
egg2pg_cat.warning()
|
||||
<< "Unexpected texture compression flag: " << (int)compression_mode << "\n";
|
||||
return Texture::CM_default;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggLoader::convert_wrap_mode
|
||||
// Access: Private
|
||||
|
|
|
|||
|
|
@ -122,6 +122,7 @@ private:
|
|||
void load_textures();
|
||||
bool load_texture(TextureDef &def, const EggTexture *egg_tex);
|
||||
void apply_texture_attributes(Texture *tex, const EggTexture *egg_tex);
|
||||
Texture::CompressionMode convert_compression_mode(EggTexture::CompressionMode compression_mode) const;
|
||||
Texture::WrapMode convert_wrap_mode(EggTexture::WrapMode wrap_mode) const;
|
||||
PT(TextureStage) make_texture_stage(const EggTexture *egg_tex);
|
||||
|
||||
|
|
|
|||
|
|
@ -593,12 +593,19 @@ load_model(const NodePath &parent, Filename filename) {
|
|||
LoaderFileType *model_type =
|
||||
reg->get_type_from_extension(extension);
|
||||
if (model_type == (LoaderFileType *)NULL) {
|
||||
// The extension isn't a known model file type, is it a known
|
||||
// texture extension?
|
||||
TexturePool *texture_pool = TexturePool::get_global_ptr();
|
||||
if (texture_pool->get_texture_type(extension) != NULL) {
|
||||
// It is a known texture extension.
|
||||
is_image = true;
|
||||
// The extension isn't a known model file type; is it a known
|
||||
// image file extension?
|
||||
if (extension == "txo") {
|
||||
// A texture object. Not exactly an image, but certainly a
|
||||
// texture.
|
||||
is_image = true;
|
||||
|
||||
} else {
|
||||
TexturePool *texture_pool = TexturePool::get_global_ptr();
|
||||
if (texture_pool->get_texture_type(extension) != NULL) {
|
||||
// It is a known image file extension.
|
||||
is_image = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1093,7 +1100,7 @@ load_image_as_model(const Filename &filename) {
|
|||
|
||||
int x_size = tex->get_x_size();
|
||||
int y_size = tex->get_y_size();
|
||||
bool has_alpha = false;
|
||||
bool has_alpha = true;
|
||||
LVecBase2f tex_scale(1.0f, 1.0f);
|
||||
|
||||
if (tex->is_of_type(VideoTexture::get_class_type())) {
|
||||
|
|
@ -1103,7 +1110,7 @@ load_image_as_model(const Filename &filename) {
|
|||
y_size = vtex->get_video_height();
|
||||
tex_scale = vtex->get_tex_scale();
|
||||
|
||||
} else {
|
||||
} else if (!tex->get_loaded_from_txo()) {
|
||||
// Get the size from the original image (the texture may have
|
||||
// scaled it to make a power of 2).
|
||||
PNMImageHeader header;
|
||||
|
|
@ -1127,7 +1134,6 @@ load_image_as_model(const Filename &filename) {
|
|||
float top = y_size / 2.0;
|
||||
|
||||
PT(GeomNode) card_node = new GeomNode("card");
|
||||
card_node->set_attrib(ColorAttrib::make_flat(Colorf(1.0f, 1.0f, 1.0f, 1.0f)));
|
||||
card_node->set_attrib(TextureAttrib::make(tex));
|
||||
if (has_alpha) {
|
||||
card_node->set_attrib(TransparencyAttrib::make(TransparencyAttrib::M_alpha));
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -65,6 +65,9 @@ typedef void (APIENTRYP PFNGLBUFFERSUBDATAPROC) (GLenum target, GLintptr offset,
|
|||
typedef void (APIENTRYP PFNGLDRAWBUFFERSARBPROC) (GLsizei n, const GLenum *bufs);
|
||||
typedef void (APIENTRYP PFNGLBUFFERDATAPROC) (GLenum target, GLsizeiptr size, const GLvoid *data, GLenum usage);
|
||||
typedef void (APIENTRYP PFNGLDELETEBUFFERSPROC) (GLsizei n, const GLuint *buffers);
|
||||
typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE2DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data);
|
||||
typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *data);
|
||||
typedef void (APIENTRYP PFNGLGETCOMPRESSEDTEXIMAGEPROC) (GLenum target, GLint level, GLvoid *img);
|
||||
|
||||
class CLP(GeomContext);
|
||||
|
||||
|
|
@ -106,6 +109,7 @@ public:
|
|||
|
||||
virtual TextureContext *prepare_texture(Texture *tex);
|
||||
virtual void release_texture(TextureContext *tc);
|
||||
virtual bool extract_texture_data(Texture *tex);
|
||||
|
||||
virtual GeomContext *prepare_geom(Geom *geom);
|
||||
virtual void release_geom(GeomContext *gc);
|
||||
|
|
@ -236,14 +240,14 @@ protected:
|
|||
|
||||
static GLenum get_numeric_type(Geom::NumericType numeric_type);
|
||||
GLenum get_texture_target(Texture::TextureType texture_type) const;
|
||||
GLenum get_texture_wrap_mode(Texture::WrapMode wm);
|
||||
GLenum get_texture_wrap_mode(Texture::WrapMode wm) const;
|
||||
static Texture::WrapMode get_panda_wrap_mode(GLenum wm);
|
||||
static GLenum get_texture_filter_type(Texture::FilterType ft, bool ignore_mipmaps);
|
||||
static Texture::FilterType get_panda_filter_type(GLenum ft);
|
||||
static GLenum get_component_type(Texture::ComponentType component_type);
|
||||
GLint get_external_image_format(Texture::Format format) const;
|
||||
static GLint get_internal_image_format(Texture::Format format);
|
||||
static int get_external_texture_bytes(int width, int height, int depth,
|
||||
GLint external_format,
|
||||
GLenum component_type);
|
||||
GLint get_external_image_format(Texture *tex) const;
|
||||
GLint get_internal_image_format(Texture *tex) const;
|
||||
static bool is_compressed_format(GLenum format);
|
||||
static GLint get_texture_apply_mode_type(TextureStage::Mode am);
|
||||
static GLint get_texture_combine_type(TextureStage::CombineMode cm);
|
||||
GLint get_texture_src_type(TextureStage::CombineSource cs,
|
||||
|
|
@ -268,7 +272,9 @@ protected:
|
|||
GLenum target, GLint internal_format,
|
||||
int width, int height, int depth,
|
||||
GLint external_format, GLenum component_type,
|
||||
const unsigned char *image);
|
||||
const unsigned char *image,
|
||||
size_t image_size,
|
||||
Texture::CompressionMode image_compression);
|
||||
|
||||
void do_point_size();
|
||||
|
||||
|
|
@ -361,6 +367,10 @@ public:
|
|||
PFNGLTEXIMAGE3DPROC _glTexImage3D;
|
||||
PFNGLTEXSUBIMAGE3DPROC _glTexSubImage3D;
|
||||
|
||||
PFNGLCOMPRESSEDTEXIMAGE2DPROC _glCompressedTexImage2D;
|
||||
PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC _glCompressedTexSubImage2D;
|
||||
PFNGLGETCOMPRESSEDTEXIMAGEPROC _glGetCompressedTexImage;
|
||||
|
||||
bool _supports_bgr;
|
||||
bool _supports_rescale_normal;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
#define OTHER_LIBS interrogatedb:c dconfig:c dtoolconfig:m \
|
||||
dtoolutil:c dtoolbase:c dtool:m prc:c
|
||||
#define OSX_SYS_LIBS mx
|
||||
#define USE_PACKAGES zlib
|
||||
|
||||
#begin lib_target
|
||||
#define TARGET gobj
|
||||
|
|
|
|||
|
|
@ -79,6 +79,13 @@ ConfigVariableBool keep_texture_ram
|
|||
"texture image from disk; but it will consume memory somewhat "
|
||||
"wastefully."));
|
||||
|
||||
ConfigVariableBool compressed_textures
|
||||
("compressed-textures", false,
|
||||
PRC_DESC("Set this to true to compress textures as they are loaded into "
|
||||
"texture memory, if the driver supports this. Specifically, this "
|
||||
"changes the meaning of set_compression(Texture::CM_default) to "
|
||||
"Texture::CM_on."));
|
||||
|
||||
ConfigVariableBool vertex_buffers
|
||||
("vertex-buffers", true,
|
||||
PRC_DESC("Set this true to allow the use of vertex buffers (or buffer "
|
||||
|
|
@ -167,11 +174,6 @@ ConfigVariableBool connect_triangle_strips
|
|||
"triangle strip may help performance by reducing the number "
|
||||
"of separate graphics calls that have to be made."));
|
||||
|
||||
ConfigVariableEnum<BamTextureMode> 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."));
|
||||
|
||||
ConfigVariableEnum<AutoTextureScale> textures_power_2
|
||||
("textures-power-2", ATS_down,
|
||||
PRC_DESC("Specify whether textures should automatically be constrained to "
|
||||
|
|
@ -300,52 +302,6 @@ ConfigureFn(config_gobj) {
|
|||
InternalName::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) {
|
||||
|
|
|
|||
|
|
@ -28,16 +28,6 @@
|
|||
|
||||
NotifyCategoryDecl(gobj, EXPCL_PANDA, EXPTP_PANDA);
|
||||
|
||||
enum BamTextureMode {
|
||||
BTM_unchanged,
|
||||
BTM_fullpath,
|
||||
BTM_relative,
|
||||
BTM_basename,
|
||||
BTM_rawdata
|
||||
};
|
||||
EXPCL_PANDA ostream &operator << (ostream &out, BamTextureMode btm);
|
||||
EXPCL_PANDA istream &operator >> (istream &in, BamTextureMode &btm);
|
||||
|
||||
enum AutoTextureScale {
|
||||
ATS_none,
|
||||
ATS_down,
|
||||
|
|
@ -49,6 +39,7 @@ EXPCL_PANDA 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 compressed_textures;
|
||||
extern EXPCL_PANDA ConfigVariableBool vertex_buffers;
|
||||
extern EXPCL_PANDA ConfigVariableBool vertex_arrays;
|
||||
extern EXPCL_PANDA ConfigVariableBool display_lists;
|
||||
|
|
@ -58,7 +49,6 @@ extern EXPCL_PANDA ConfigVariableBool matrix_palette;
|
|||
extern EXPCL_PANDA ConfigVariableBool display_list_animation;
|
||||
extern EXPCL_PANDA ConfigVariableBool connect_triangle_strips;
|
||||
|
||||
extern EXPCL_PANDA ConfigVariableEnum<BamTextureMode> bam_texture_mode;
|
||||
extern EXPCL_PANDA ConfigVariableEnum<AutoTextureScale> textures_power_2;
|
||||
extern EXPCL_PANDA ConfigVariableEnum<AutoTextureScale> textures_square;
|
||||
extern EXPCL_PANDA ConfigVariableBool textures_header_only;
|
||||
|
|
|
|||
|
|
@ -398,13 +398,29 @@ get_border_color() const {
|
|||
return _border_color;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Texture::get_compression
|
||||
// Access: Published
|
||||
// Description: Returns the compression mode requested for this
|
||||
// particular texture, or CM_off if the texture is not
|
||||
// to be compressed.
|
||||
//
|
||||
// If a value other than CM_off is returned, this is
|
||||
// not a guarantee that the texture is actually
|
||||
// successfully compressed on the GSG. It may be that
|
||||
// the GSG does not support the requested compression
|
||||
// mode, in which case the texture may actually be
|
||||
// stored uncompressed in texture memory.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE Texture::CompressionMode Texture::
|
||||
get_compression() const {
|
||||
return _compression;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Texture::get_render_to_texture
|
||||
// Access: Published
|
||||
// Description: Returns the solid color of the texture's border.
|
||||
// Some OpenGL implementations use a border for tiling
|
||||
// textures; in Panda, it is only used for specifying
|
||||
// the clamp color.
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool Texture::
|
||||
get_render_to_texture() const {
|
||||
|
|
@ -446,7 +462,24 @@ might_have_ram_image() const {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
INLINE size_t Texture::
|
||||
get_ram_image_size() const {
|
||||
return _image.size();
|
||||
return _ram_image.size();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Texture::get_ram_page_size
|
||||
// Access: Published
|
||||
// Description: Returns the number of bytes used by the in-memory
|
||||
// image per page, or 0 if there is no in-memory image.
|
||||
//
|
||||
// For a non-compressed texture, this is the same as
|
||||
// get_expected_ram_page_size(). For a compressed
|
||||
// texture, this may be a smaller value. (We do assume
|
||||
// that all pages will be the same size on a compressed
|
||||
// texture).
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE size_t Texture::
|
||||
get_ram_page_size() const {
|
||||
return _ram_image_compression != CM_off ? _ram_page_size : get_expected_ram_page_size();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -474,6 +507,21 @@ get_expected_ram_page_size() const {
|
|||
return (size_t)(_x_size * _y_size * _num_components * _component_width);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Texture::get_ram_image_compression
|
||||
// Access: Published
|
||||
// Description: Returns the compression mode in which the ram image
|
||||
// is already stored pre-compressed. If this is other
|
||||
// than CM_off, you cannot rely on the contents of the
|
||||
// ram image to be anything predicatable (it will not be
|
||||
// an array of x by y pixels, and it probably won't have
|
||||
// the same length as get_expected_ram_image_size()).
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE Texture::CompressionMode Texture::
|
||||
get_ram_image_compression() const {
|
||||
return _ram_image_compression;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Texture::set_keep_ram_image
|
||||
// Access: Published
|
||||
|
|
@ -678,6 +726,30 @@ get_loaded_from_disk() const {
|
|||
return _loaded_from_disk;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Texture::set_loaded_from_txo
|
||||
// Access: Published
|
||||
// Description: Sets the flag that indicates the texture has been
|
||||
// loaded from a txo file. You probably shouldn't be
|
||||
// setting this directly; it is set automatically when a
|
||||
// Texture is loaded.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void Texture::
|
||||
set_loaded_from_txo() {
|
||||
_loaded_from_txo = true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Texture::get_loaded_from_txo
|
||||
// Access: Published
|
||||
// Description: Returns the flag that indicates the texture has been
|
||||
// loaded from a txo file.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool Texture::
|
||||
get_loaded_from_txo() const {
|
||||
return _loaded_from_txo;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Texture::get_match_framebuffer_format
|
||||
// Access: Public
|
||||
|
|
@ -725,7 +797,7 @@ set_match_framebuffer_format(bool flag) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void Texture::
|
||||
store_unscaled_byte(int &index, int value) {
|
||||
_image[index++] = (uchar)value;
|
||||
_ram_image[index++] = (uchar)value;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -744,8 +816,8 @@ store_unscaled_short(int &index, int value) {
|
|||
uchar uc[2];
|
||||
} v;
|
||||
v.us = (ushort)value;
|
||||
_image[index++] = v.uc[0];
|
||||
_image[index++] = v.uc[1];
|
||||
_ram_image[index++] = v.uc[0];
|
||||
_ram_image[index++] = v.uc[1];
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -786,8 +858,8 @@ store_scaled_short(int &index, int value, double scale) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
INLINE double Texture::
|
||||
get_unsigned_byte(int &index) const {
|
||||
nassertr(index >= 0 && index < (int)_image.size(), 0.0);
|
||||
return (double)_image[index++] / 255.0;
|
||||
nassertr(index >= 0 && index < (int)_ram_image.size(), 0.0);
|
||||
return (double)_ram_image[index++] / 255.0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -800,12 +872,29 @@ get_unsigned_byte(int &index) const {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
INLINE double Texture::
|
||||
get_unsigned_short(int &index) const {
|
||||
nassertr(index >= 0 && index+1 < (int)_image.size(), 0.0);
|
||||
nassertr(index >= 0 && index+1 < (int)_ram_image.size(), 0.0);
|
||||
union {
|
||||
ushort us;
|
||||
uchar uc[2];
|
||||
} v;
|
||||
v.uc[0] = _image[index++];
|
||||
v.uc[1] = _image[index++];
|
||||
v.uc[0] = _ram_image[index++];
|
||||
v.uc[1] = _ram_image[index++];
|
||||
return (double)v.us / 65535.0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Texture::is_txo_filename
|
||||
// Access: Private, Static
|
||||
// Description: Returns true if the indicated filename ends in .txo
|
||||
// or .txo.pz, false otherwise.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool Texture::
|
||||
is_txo_filename(const Filename &fullpath) {
|
||||
string extension = fullpath.get_extension();
|
||||
#ifdef HAVE_ZLIB
|
||||
if (extension == "pz") {
|
||||
extension = Filename(fullpath.get_basename_wo_extension()).get_extension();
|
||||
}
|
||||
#endif // HAVE_ZLIB
|
||||
return (extension == "txo");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,6 +29,11 @@
|
|||
#include "preparedGraphicsObjects.h"
|
||||
#include "pnmImage.h"
|
||||
#include "virtualFileSystem.h"
|
||||
#include "datagramInputFile.h"
|
||||
#include "datagramOutputFile.h"
|
||||
#include "bam.h"
|
||||
#include "zStream.h"
|
||||
#include "indent.h"
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
|
|
@ -58,6 +63,9 @@ Texture(const string &name) :
|
|||
_keep_ram_image = true;
|
||||
_all_dirty_flags = 0;
|
||||
_border_color.set(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
_compression = CM_default;
|
||||
_ram_image_compression = CM_off;
|
||||
_ram_page_size = 0;
|
||||
_render_to_texture = false;
|
||||
_match_framebuffer_format = false;
|
||||
|
||||
|
|
@ -69,6 +77,7 @@ Texture(const string &name) :
|
|||
set_component_type(T_unsigned_byte);
|
||||
|
||||
_loaded_from_disk = false;
|
||||
_loaded_from_txo = false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -95,6 +104,7 @@ Texture(const Texture ©) :
|
|||
_format(copy._format),
|
||||
_component_type(copy._component_type),
|
||||
_loaded_from_disk(copy._loaded_from_disk),
|
||||
_loaded_from_txo(copy._loaded_from_txo),
|
||||
_wrap_u(copy._wrap_u),
|
||||
_wrap_v(copy._wrap_v),
|
||||
_wrap_w(copy._wrap_w),
|
||||
|
|
@ -103,12 +113,56 @@ Texture(const Texture ©) :
|
|||
_anisotropic_degree(copy._anisotropic_degree),
|
||||
_keep_ram_image(copy._keep_ram_image),
|
||||
_border_color(copy._border_color),
|
||||
_compression(copy._compression),
|
||||
_match_framebuffer_format(copy._match_framebuffer_format),
|
||||
_all_dirty_flags(0),
|
||||
_image(copy._image)
|
||||
_ram_image(copy._ram_image),
|
||||
_ram_image_compression(copy._ram_image_compression),
|
||||
_ram_page_size(copy._ram_page_size)
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Texture::Copy Assignment Operator
|
||||
// Access: Protected
|
||||
// Description: Use Texture::make_copy() to make a duplicate copy of
|
||||
// an existing Texture.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void Texture::
|
||||
operator = (const Texture ©) {
|
||||
Namable::operator = (copy);
|
||||
_filename = copy._filename;
|
||||
_alpha_filename = copy._alpha_filename;
|
||||
_fullpath = copy._fullpath;
|
||||
_alpha_fullpath = copy._alpha_fullpath;
|
||||
_primary_file_num_channels = copy._primary_file_num_channels;
|
||||
_alpha_file_channel = copy._alpha_file_channel;
|
||||
_x_size = copy._x_size;
|
||||
_y_size = copy._y_size;
|
||||
_z_size = copy._z_size;
|
||||
_num_components = copy._num_components;
|
||||
_component_width = copy._component_width;
|
||||
_texture_type = copy._texture_type;
|
||||
_format = copy._format;
|
||||
_component_type = copy._component_type;
|
||||
_loaded_from_disk = copy._loaded_from_disk;
|
||||
_loaded_from_txo = copy._loaded_from_txo;
|
||||
_wrap_u = copy._wrap_u;
|
||||
_wrap_v = copy._wrap_v;
|
||||
_wrap_w = copy._wrap_w;
|
||||
_minfilter = copy._minfilter;
|
||||
_magfilter = copy._magfilter;
|
||||
_anisotropic_degree = copy._anisotropic_degree;
|
||||
_keep_ram_image = copy._keep_ram_image;
|
||||
_border_color = copy._border_color;
|
||||
_compression = copy._compression;
|
||||
_match_framebuffer_format = copy._match_framebuffer_format;
|
||||
_all_dirty_flags = 0;
|
||||
_ram_image = copy._ram_image;
|
||||
_ram_image_compression = copy._ram_image_compression;
|
||||
_ram_page_size = copy._ram_page_size;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Texture::Destructor
|
||||
// Access: Published, Virtual
|
||||
|
|
@ -170,6 +224,7 @@ setup_texture(Texture::TextureType texture_type, int x_size, int y_size,
|
|||
|
||||
clear_ram_image();
|
||||
_loaded_from_disk = false;
|
||||
_loaded_from_txo = false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -187,7 +242,7 @@ setup_texture(Texture::TextureType texture_type, int x_size, int y_size,
|
|||
void Texture::
|
||||
generate_normalization_cube_map(int size) {
|
||||
setup_cube_map(size, T_unsigned_byte, F_rgb);
|
||||
PTA_uchar image = modify_ram_image();
|
||||
PTA_uchar image = make_ram_image();
|
||||
|
||||
float half_size = (float)size * 0.5f;
|
||||
float center = half_size - 0.5f;
|
||||
|
|
@ -284,9 +339,18 @@ generate_normalization_cube_map(int size) {
|
|||
// than this number.
|
||||
//
|
||||
// This also implicitly sets keep_ram_image to false.
|
||||
//
|
||||
// If the filename has the extension .txo, this
|
||||
// implicitly reads a texture object instead of a
|
||||
// filename (which replaces all of the texture
|
||||
// properties).
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool Texture::
|
||||
read(const Filename &fullpath, int z, int primary_file_num_channels) {
|
||||
if (is_txo_filename(fullpath)) {
|
||||
return read_txo_file(fullpath);
|
||||
}
|
||||
|
||||
PNMImage image;
|
||||
|
||||
if (textures_header_only) {
|
||||
|
|
@ -461,11 +525,24 @@ read(const Filename &fullpath, const Filename &alpha_fullpath,
|
|||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Texture::write
|
||||
// Access: Published
|
||||
// Description: Writes the texture to the indicated filename.
|
||||
// Description: Writes the texture to the indicated filename. If the
|
||||
// filename ends in the extension .txo, this implicitly
|
||||
// writes a Panda texture object (.txo) instead of an
|
||||
// image file.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool Texture::
|
||||
write(const Filename &name, int z) const {
|
||||
if (!has_ram_image()) {
|
||||
((Texture *)this)->get_ram_image();
|
||||
}
|
||||
nassertr(has_ram_image(), false);
|
||||
|
||||
if (is_txo_filename(name)) {
|
||||
return write_txo_file(name);
|
||||
}
|
||||
|
||||
nassertr(get_ram_image_compression() == CM_off, false);
|
||||
|
||||
PNMImage pnmimage;
|
||||
if (!store(pnmimage, z)) {
|
||||
return false;
|
||||
|
|
@ -479,6 +556,114 @@ write(const Filename &name, int z) const {
|
|||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Texture::read_txo
|
||||
// Access: Published
|
||||
// Description: Reads the texture from a Panda texture object. This
|
||||
// defines the complete Texture specification, including
|
||||
// the image data as well as all texture properties.
|
||||
//
|
||||
// The filename is just for reference.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool Texture::
|
||||
read_txo(istream &in, const string &filename) {
|
||||
DatagramInputFile din;
|
||||
|
||||
if (!din.open(in)) {
|
||||
gobj_cat.error()
|
||||
<< "Could not read texture object: " << filename << "\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
string head;
|
||||
if (!din.read_header(head, _bam_header.size())) {
|
||||
gobj_cat.error()
|
||||
<< filename << " is not a texture object file.\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (head != _bam_header) {
|
||||
gobj_cat.error()
|
||||
<< filename << " is not a texture object file.\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
BamReader reader(&din, filename);
|
||||
if (!reader.init()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
TypedWritable *object = reader.read_object();
|
||||
if (object == (TypedWritable *)NULL) {
|
||||
gobj_cat.error()
|
||||
<< "Texture object " << filename << " is empty.\n";
|
||||
return false;
|
||||
|
||||
} else if (!object->is_of_type(Texture::get_class_type())) {
|
||||
gobj_cat.error()
|
||||
<< "Texture object " << filename << "contains a "
|
||||
<< object->get_type() << ", not a Texture.\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
PT(Texture) other = DCAST(Texture, object);
|
||||
if (!reader.resolve()) {
|
||||
gobj_cat.error()
|
||||
<< "Unable to fully resolve texture object file.\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
(*this) = (*other);
|
||||
_loaded_from_disk = true;
|
||||
_loaded_from_txo = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Texture::write_txo
|
||||
// Access: Published
|
||||
// Description: Writes the texture to a Panda texture object. This
|
||||
// defines the complete Texture specification, including
|
||||
// the image data as well as all texture properties.
|
||||
//
|
||||
// The filename is just for reference.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool Texture::
|
||||
write_txo(ostream &out, const string &filename) const {
|
||||
DatagramOutputFile dout;
|
||||
|
||||
if (!dout.open(out)) {
|
||||
gobj_cat.error()
|
||||
<< "Could not write texture object: " << filename << "\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!dout.write_header(_bam_header)) {
|
||||
gobj_cat.error()
|
||||
<< "Unable to write to " << filename << "\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
BamWriter writer(&dout, filename);
|
||||
if (!writer.init()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
writer.set_file_texture_mode(BTM_rawdata);
|
||||
|
||||
if (!writer.write_object(this)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!has_ram_image()) {
|
||||
gobj_cat.error()
|
||||
<< get_name() << " does not have ram image\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Texture::read_pages
|
||||
// Access: Published
|
||||
|
|
@ -497,6 +682,10 @@ write(const Filename &name, int z) const {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
bool Texture::
|
||||
read_pages(Filename fullpath_pattern, int z_size) {
|
||||
if (is_txo_filename(fullpath_pattern)) {
|
||||
return read_txo_file(fullpath_pattern);
|
||||
}
|
||||
|
||||
fullpath_pattern.set_pattern(true);
|
||||
if (!fullpath_pattern.has_hash()) {
|
||||
gobj_cat.error()
|
||||
|
|
@ -566,6 +755,10 @@ read_pages(Filename fullpath_pattern, int z_size) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
bool Texture::
|
||||
write_pages(Filename fullpath_pattern) {
|
||||
if (is_txo_filename(fullpath_pattern)) {
|
||||
return write_txo_file(fullpath_pattern);
|
||||
}
|
||||
|
||||
fullpath_pattern.set_pattern(true);
|
||||
if (!fullpath_pattern.has_hash()) {
|
||||
gobj_cat.error()
|
||||
|
|
@ -938,13 +1131,37 @@ set_border_color(const Colorf &color) {
|
|||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Texture::set_compression
|
||||
// Access: Published
|
||||
// Description: Requests that this particular Texture be compressed
|
||||
// when it is loaded into texture memory.
|
||||
//
|
||||
// This refers to the internal compression of the
|
||||
// texture image within texture memory; it is not
|
||||
// related to jpeg or png compression, which are disk
|
||||
// file compression formats. The actual disk file that
|
||||
// generated this texture may be stored in a compressed
|
||||
// or uncompressed format supported by Panda; it will be
|
||||
// decompressed on load, and then recompressed by the
|
||||
// graphics API if this parameter is not CM_off.
|
||||
//
|
||||
// If the GSG does not support this texture compression
|
||||
// mode, the texture will silently be loaded
|
||||
// uncompressed.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void Texture::
|
||||
set_compression(Texture::CompressionMode compression) {
|
||||
if (_compression != compression) {
|
||||
mark_dirty(DF_image);
|
||||
_compression = compression;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Texture::set_render_to_texture
|
||||
// Access: Published
|
||||
// Description: Specifies the solid color of the texture's border.
|
||||
// Some OpenGL implementations use a border for tiling
|
||||
// textures; in Panda, it is only used for specifying
|
||||
// the clamp color.
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void Texture::
|
||||
set_render_to_texture(bool render_to_texture) {
|
||||
|
|
@ -981,7 +1198,7 @@ set_render_to_texture(bool render_to_texture) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
bool Texture::
|
||||
has_ram_image() const {
|
||||
return !_image.empty();
|
||||
return !_ram_image.empty();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -1018,26 +1235,28 @@ get_ram_image() {
|
|||
reload_ram_image();
|
||||
}
|
||||
|
||||
return _image;
|
||||
return _ram_image;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Texture::modify_ram_image
|
||||
// Access: Published
|
||||
// Description: Returns a modifiable pointer to the system-RAM image.
|
||||
// If the RAM image has been dumped, creates a new one.
|
||||
// This assumes the RAM image should be uncompressed.
|
||||
// If the RAM image has been dumped, or is stored
|
||||
// compressed, creates a new one.
|
||||
//
|
||||
// This also implicitly sets keep_ram_image to true.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
PTA_uchar Texture::
|
||||
modify_ram_image() {
|
||||
if (_image.empty()) {
|
||||
if (_ram_image.empty() || _ram_image_compression != CM_off) {
|
||||
make_ram_image();
|
||||
}
|
||||
|
||||
mark_dirty(DF_image);
|
||||
_keep_ram_image = true;
|
||||
return _image;
|
||||
return _ram_image;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -1051,25 +1270,35 @@ modify_ram_image() {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
PTA_uchar Texture::
|
||||
make_ram_image() {
|
||||
_image = PTA_uchar::empty_array(get_expected_ram_image_size());
|
||||
_ram_image = PTA_uchar::empty_array(get_expected_ram_image_size());
|
||||
_ram_image_compression = CM_off;
|
||||
mark_dirty(DF_image);
|
||||
_keep_ram_image = true;
|
||||
return _image;
|
||||
return _ram_image;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Texture::set_ram_image
|
||||
// Access: Published
|
||||
// Description: Replaces the current system-RAM image with the new
|
||||
// data.
|
||||
// data. If compression is not CM_off, it indicates
|
||||
// that the new data is already pre-compressed in the
|
||||
// indicated format.
|
||||
//
|
||||
// This also implicitly sets keep_ram_image to true.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void Texture::
|
||||
set_ram_image(PTA_uchar image) {
|
||||
nassertv(image.size() == get_expected_ram_image_size());
|
||||
if (_image != image) {
|
||||
_image = image;
|
||||
set_ram_image(PTA_uchar image, Texture::CompressionMode compression,
|
||||
size_t page_size) {
|
||||
nassertv(compression != CM_default);
|
||||
nassertv(compression != CM_off || image.size() == get_expected_ram_image_size());
|
||||
if (_ram_image != image || _ram_image_compression != compression) {
|
||||
_ram_image = image;
|
||||
_ram_image_compression = compression;
|
||||
_ram_page_size = page_size;
|
||||
if (page_size == 0) {
|
||||
_ram_page_size = image.size();
|
||||
}
|
||||
mark_dirty(DF_image);
|
||||
}
|
||||
_keep_ram_image = true;
|
||||
|
|
@ -1082,7 +1311,8 @@ set_ram_image(PTA_uchar image) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void Texture::
|
||||
clear_ram_image() {
|
||||
_image.clear();
|
||||
_ram_image.clear();
|
||||
_ram_image_compression = CM_off;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -1172,6 +1402,169 @@ release_all() {
|
|||
return num_freed;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Texture::write
|
||||
// Access: Published
|
||||
// Description: Not to be confused with write(Filename), this method
|
||||
// simply describes the texture properties.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void Texture::
|
||||
write(ostream &out, int indent_level) const {
|
||||
indent(out, indent_level)
|
||||
<< get_type() << " " << get_name();
|
||||
if (!get_filename().empty()) {
|
||||
out << " (from " << get_filename() << ")";
|
||||
}
|
||||
out << "\n";
|
||||
|
||||
indent(out, indent_level + 2);
|
||||
|
||||
switch (get_texture_type()) {
|
||||
case TT_1d_texture:
|
||||
out << "1-d, " << get_x_size();
|
||||
break;
|
||||
|
||||
case TT_2d_texture:
|
||||
out << "2-d, " << get_x_size() << " x " << get_y_size();
|
||||
break;
|
||||
|
||||
case TT_3d_texture:
|
||||
out << "3-d, " << get_x_size() << " x " << get_y_size()
|
||||
<< " x " << get_z_size();
|
||||
break;
|
||||
|
||||
case TT_cube_map:
|
||||
out << "cube map, " << get_x_size() << " x " << get_y_size();
|
||||
break;
|
||||
}
|
||||
|
||||
out << " pixels, each " << get_num_components();
|
||||
|
||||
switch (get_component_type()) {
|
||||
case T_unsigned_byte:
|
||||
out << " bytes";
|
||||
break;
|
||||
|
||||
case T_unsigned_short:
|
||||
out << " shorts";
|
||||
break;
|
||||
|
||||
case T_float:
|
||||
out << " floats";
|
||||
break;
|
||||
}
|
||||
|
||||
out << ", ";
|
||||
switch (get_format()) {
|
||||
case F_color_index:
|
||||
out << "color_index";
|
||||
break;
|
||||
case F_stencil_index:
|
||||
out << "stencil_index";
|
||||
break;
|
||||
case F_depth_component:
|
||||
out << "depth_component";
|
||||
break;
|
||||
|
||||
case F_rgba:
|
||||
out << "rgba";
|
||||
break;
|
||||
case F_rgbm:
|
||||
out << "rgbm";
|
||||
break;
|
||||
case F_rgba12:
|
||||
out << "rgba12";
|
||||
break;
|
||||
case F_rgba8:
|
||||
out << "rgba8";
|
||||
break;
|
||||
case F_rgba4:
|
||||
out << "rgba4";
|
||||
break;
|
||||
|
||||
case F_rgb:
|
||||
out << "rgb";
|
||||
break;
|
||||
case F_rgb12:
|
||||
out << "rgb12";
|
||||
break;
|
||||
case F_rgb8:
|
||||
out << "rgb8";
|
||||
break;
|
||||
case F_rgb5:
|
||||
out << "rgb5";
|
||||
break;
|
||||
case F_rgba5:
|
||||
out << "rgba5";
|
||||
break;
|
||||
case F_rgb332:
|
||||
out << "rgb332";
|
||||
break;
|
||||
|
||||
case F_red:
|
||||
out << "red";
|
||||
break;
|
||||
case F_green:
|
||||
out << "green";
|
||||
break;
|
||||
case F_blue:
|
||||
out << "blue";
|
||||
break;
|
||||
case F_alpha:
|
||||
out << "alpha";
|
||||
break;
|
||||
case F_luminance:
|
||||
out << "luminance";
|
||||
break;
|
||||
case F_luminance_alpha:
|
||||
out << "luminance_alpha";
|
||||
break;
|
||||
case F_luminance_alphamask:
|
||||
out << "luminance_alphamask";
|
||||
break;
|
||||
}
|
||||
|
||||
if (get_compression() != CM_default) {
|
||||
out << ", compression " << get_compression();
|
||||
}
|
||||
out << "\n";
|
||||
|
||||
indent(out, indent_level + 2);
|
||||
|
||||
switch (get_texture_type()) {
|
||||
case TT_1d_texture:
|
||||
out << get_wrap_u() << ", ";
|
||||
break;
|
||||
|
||||
case TT_2d_texture:
|
||||
out << get_wrap_u() << " x " << get_wrap_v() << ", ";
|
||||
break;
|
||||
|
||||
case TT_3d_texture:
|
||||
out << get_wrap_u() << " x " << get_wrap_v()
|
||||
<< " x " << get_wrap_w() << ", ";
|
||||
break;
|
||||
|
||||
case TT_cube_map:
|
||||
break;
|
||||
}
|
||||
|
||||
out << "min " << get_minfilter()
|
||||
<< ", mag " << get_magfilter()
|
||||
<< ", aniso " << get_anisotropic_degree()
|
||||
<< ", border " << get_border_color()
|
||||
<< "\n";
|
||||
|
||||
indent(out, indent_level + 2);
|
||||
if (has_ram_image()) {
|
||||
out << get_ram_image_size() << " bytes in ram, compression "
|
||||
<< get_ram_image_compression() << "\n";
|
||||
|
||||
} else {
|
||||
out << "no ram image\n";
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Texture::set_format
|
||||
// Access: Published
|
||||
|
|
@ -1307,7 +1700,7 @@ prepare_now(PreparedGraphicsObjects *prepared_objects,
|
|||
gobj_cat.debug()
|
||||
<< "Dumping RAM for texture " << get_name() << "\n";
|
||||
}
|
||||
_image.clear();
|
||||
_ram_image.clear();
|
||||
}
|
||||
}
|
||||
return tc;
|
||||
|
|
@ -1465,17 +1858,23 @@ reconsider_dirty() {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void Texture::
|
||||
reload_ram_image() {
|
||||
if (_texture_type == TT_1d_texture || _texture_type == TT_2d_texture) {
|
||||
gobj_cat.info()
|
||||
<< "Reloading texture " << get_name() << "\n";
|
||||
gobj_cat.info()
|
||||
<< "Reloading texture " << get_name() << "\n";
|
||||
|
||||
make_ram_image();
|
||||
make_ram_image();
|
||||
|
||||
if (_texture_type == TT_1d_texture || _texture_type == TT_2d_texture) {
|
||||
// 1-d or 2-d texture. Just one page.
|
||||
if (has_alpha_fullpath()) {
|
||||
read(get_fullpath(), get_alpha_fullpath(),
|
||||
0, _primary_file_num_channels, _alpha_file_channel);
|
||||
} else {
|
||||
read(get_fullpath(), 0, _primary_file_num_channels);
|
||||
}
|
||||
|
||||
} else {
|
||||
// 3-d texture or cube map. Multiple pages.
|
||||
read_pages(get_fullpath(), _z_size);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1510,6 +1909,50 @@ down_to_power_2(int value) {
|
|||
return x;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Texture::is_specific
|
||||
// Access: Public, Static
|
||||
// Description: Returns true if the indicated compression mode is one
|
||||
// of the specific compression types, false otherwise.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool Texture::
|
||||
is_specific(Texture::CompressionMode compression) {
|
||||
switch (compression) {
|
||||
case CM_default:
|
||||
case CM_off:
|
||||
case CM_on:
|
||||
return false;
|
||||
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Texture::has_alpha
|
||||
// Access: Public, Static
|
||||
// Description: Returns true if the indicated format includes alpha,
|
||||
// false otherwise.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool Texture::
|
||||
has_alpha(Format format) {
|
||||
switch (format) {
|
||||
case F_alpha:
|
||||
case F_rgba:
|
||||
case F_rgbm:
|
||||
case F_rgba4:
|
||||
case F_rgba5:
|
||||
case F_rgba8:
|
||||
case F_rgba12:
|
||||
case F_luminance_alpha:
|
||||
case F_luminance_alphamask:
|
||||
return true;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Texture::reconsider_z_size
|
||||
// Access: Protected
|
||||
|
|
@ -1530,9 +1973,9 @@ reconsider_z_size(int z) {
|
|||
// Increase the size of the data buffer to make room for the new
|
||||
// texture level.
|
||||
size_t new_size = get_expected_ram_image_size();
|
||||
if (!_image.is_null() && new_size > _image.size()) {
|
||||
_image.insert(_image.end(), new_size - _image.size(), 0);
|
||||
nassertr(_image.size() == new_size, false);
|
||||
if (!_ram_image.is_null() && new_size > _ram_image.size()) {
|
||||
_ram_image.insert(_ram_image.end(), new_size - _ram_image.size(), 0);
|
||||
nassertr(_ram_image.size() == new_size, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1710,6 +2153,66 @@ consider_downgrade(PNMImage &pnmimage, int num_channels) {
|
|||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Texture::read_txo_file
|
||||
// Access: Private
|
||||
// Description: Called internally when read() or read_pages() detects
|
||||
// a txo file.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool Texture::
|
||||
read_txo_file(const Filename &fullpath) {
|
||||
VirtualFileSystem *vfs = VirtualFileSystem::get_global_ptr();
|
||||
|
||||
Filename filename = Filename::binary_filename(fullpath);
|
||||
PT(VirtualFile) file = vfs->get_file(filename);
|
||||
if (file == (VirtualFile *)NULL) {
|
||||
// No such file.
|
||||
gobj_cat.error()
|
||||
<< "Could not find " << fullpath << "\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (gobj_cat.is_debug()) {
|
||||
gobj_cat.debug()
|
||||
<< "Reading texture object " << filename << "\n";
|
||||
}
|
||||
|
||||
istream *in = file->open_read_file(true);
|
||||
bool success = read_txo(*in, fullpath);
|
||||
vfs->close_read_file(in);
|
||||
|
||||
set_fullpath(fullpath);
|
||||
clear_alpha_fullpath();
|
||||
_keep_ram_image = false;
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Texture::write_txo_file
|
||||
// Access: Private
|
||||
// Description: Called internally when write() or write_pages() detects
|
||||
// a txo file.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool Texture::
|
||||
write_txo_file(const Filename &fullpath) const {
|
||||
Filename filename = Filename::binary_filename(fullpath);
|
||||
ofstream out;
|
||||
if (!filename.open_write(out)) {
|
||||
gobj_cat.error()
|
||||
<< "Unable to open " << filename << "\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef HAVE_ZLIB
|
||||
if (fullpath.get_extension() == "pz") {
|
||||
OCompressStream compressor(&out, false);
|
||||
return write_txo(compressor);
|
||||
}
|
||||
#endif // HAVE_ZLIB
|
||||
return write_txo(out, fullpath);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Texture::register_with_read_factory
|
||||
// Access: Public, Static
|
||||
|
|
@ -1752,7 +2255,12 @@ make_from_bam(const FactoryParams ¶ms) {
|
|||
if (has_rawdata) {
|
||||
// If the raw image data is included, then just create a Texture
|
||||
// and don't load from the file.
|
||||
me = new Texture("");
|
||||
me = new Texture(name);
|
||||
me->_filename = filename;
|
||||
me->_alpha_filename = alpha_filename;
|
||||
me->_primary_file_num_channels = primary_file_num_channels;
|
||||
me->_alpha_file_channel = alpha_file_channel;
|
||||
me->_texture_type = texture_type;
|
||||
|
||||
} else {
|
||||
if (filename.empty()) {
|
||||
|
|
@ -1828,6 +2336,10 @@ fillin(DatagramIterator &scan, BamReader *manager, bool has_rawdata) {
|
|||
_magfilter = (FilterType)scan.get_uint8();
|
||||
_anisotropic_degree = scan.get_int16();
|
||||
_border_color.read_datagram(scan);
|
||||
_compression = CM_default;
|
||||
if (manager->get_file_minor_ver() >= 1) {
|
||||
_compression = (CompressionMode)scan.get_uint8();
|
||||
}
|
||||
|
||||
Format format = (Format)scan.get_uint8();
|
||||
int num_components = scan.get_uint8();
|
||||
|
|
@ -1849,15 +2361,21 @@ fillin(DatagramIterator &scan, BamReader *manager, bool has_rawdata) {
|
|||
_z_size = scan.get_uint32();
|
||||
_component_type = (ComponentType)scan.get_uint8();
|
||||
_component_width = scan.get_uint8();
|
||||
_ram_image_compression = CM_off;
|
||||
_ram_page_size = 0;
|
||||
if (manager->get_file_minor_ver() >= 1) {
|
||||
_ram_image_compression = (CompressionMode)scan.get_uint8();
|
||||
_ram_page_size = scan.get_uint32();
|
||||
}
|
||||
_loaded_from_disk = false;
|
||||
|
||||
PN_uint32 u_size = scan.get_uint32();
|
||||
|
||||
// fill the _image buffer with image data
|
||||
string temp_buff = scan.extract_bytes(u_size);
|
||||
_image = PTA_uchar::empty_array((int) u_size);
|
||||
_ram_image = PTA_uchar::empty_array((int) u_size);
|
||||
for (PN_uint32 u_idx=0; u_idx < u_size; ++u_idx) {
|
||||
_image[(int)u_idx] = (uchar) temp_buff[u_idx];
|
||||
_ram_image[(int)u_idx] = (uchar) temp_buff[u_idx];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1870,11 +2388,6 @@ fillin(DatagramIterator &scan, BamReader *manager, bool has_rawdata) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void Texture::
|
||||
write_datagram(BamWriter *manager, Datagram &me) {
|
||||
bool has_bam_dir = !manager->get_filename().empty();
|
||||
Filename bam_dir = manager->get_filename().get_dirname();
|
||||
Filename filename = get_filename();
|
||||
Filename alpha_filename = get_alpha_filename();
|
||||
|
||||
// Write out the texture's raw pixel data if (a) the current Bam
|
||||
// Texture Mode requires that, or (b) there's no filename, so the
|
||||
// file can't be loaded up from disk, but the raw pixel data is
|
||||
|
|
@ -1883,10 +2396,24 @@ write_datagram(BamWriter *manager, Datagram &me) {
|
|||
// Otherwise, we just write out the filename, and assume whoever
|
||||
// loads the bam file later will have access to the image file on
|
||||
// disk.
|
||||
BamTextureMode file_texture_mode = manager->get_file_texture_mode();
|
||||
bool has_rawdata =
|
||||
(bam_texture_mode == BTM_rawdata || (has_ram_image() && filename.empty()));
|
||||
(file_texture_mode == BTM_rawdata || (has_ram_image() && get_filename().empty()));
|
||||
if (has_rawdata && !has_ram_image()) {
|
||||
get_ram_image();
|
||||
if (!has_ram_image()) {
|
||||
// No image data after all.
|
||||
has_rawdata = false;
|
||||
}
|
||||
}
|
||||
|
||||
switch (bam_texture_mode) {
|
||||
bool has_bam_dir = !manager->get_filename().empty();
|
||||
Filename bam_dir = manager->get_filename().get_dirname();
|
||||
Filename filename = get_filename();
|
||||
Filename alpha_filename = get_alpha_filename();
|
||||
|
||||
|
||||
switch (file_texture_mode) {
|
||||
case BTM_unchanged:
|
||||
case BTM_rawdata:
|
||||
break;
|
||||
|
|
@ -1928,7 +2455,7 @@ write_datagram(BamWriter *manager, Datagram &me) {
|
|||
|
||||
default:
|
||||
gobj_cat.error()
|
||||
<< "Unsupported bam-texture-mode: " << (int)bam_texture_mode << "\n";
|
||||
<< "Unsupported bam-texture-mode: " << (int)file_texture_mode << "\n";
|
||||
}
|
||||
|
||||
me.add_string(get_name());
|
||||
|
|
@ -1947,6 +2474,7 @@ write_datagram(BamWriter *manager, Datagram &me) {
|
|||
me.add_uint8(_magfilter);
|
||||
me.add_int16(_anisotropic_degree);
|
||||
_border_color.write_datagram(me);
|
||||
me.add_uint8(_compression);
|
||||
|
||||
me.add_uint8(_format);
|
||||
me.add_uint8(_num_components);
|
||||
|
|
@ -1959,9 +2487,11 @@ write_datagram(BamWriter *manager, Datagram &me) {
|
|||
me.add_uint32(_z_size);
|
||||
me.add_uint8(_component_type);
|
||||
me.add_uint8(_component_width);
|
||||
me.add_uint8(_ram_image_compression);
|
||||
me.add_uint32(_ram_page_size);
|
||||
|
||||
me.add_uint32(_image.size());
|
||||
me.append_data(_image, _image.size());
|
||||
me.add_uint32(_ram_image.size());
|
||||
me.append_data(_ram_image, _ram_image.size());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2046,3 +2576,33 @@ operator >> (istream &in, Texture::WrapMode &wm) {
|
|||
wm = Texture::string_wrap_mode(word);
|
||||
return in;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Texture::CompressionMode output operator
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
ostream &
|
||||
operator << (ostream &out, Texture::CompressionMode cm) {
|
||||
switch (cm) {
|
||||
case Texture::CM_default:
|
||||
return out << "default";
|
||||
case Texture::CM_off:
|
||||
return out << "off";
|
||||
case Texture::CM_on:
|
||||
return out << "on";
|
||||
case Texture::CM_fxt1:
|
||||
return out << "fxt1";
|
||||
case Texture::CM_dxt1:
|
||||
return out << "dxt1";
|
||||
case Texture::CM_dxt2:
|
||||
return out << "dxt2";
|
||||
case Texture::CM_dxt3:
|
||||
return out << "dxt3";
|
||||
case Texture::CM_dxt4:
|
||||
return out << "dxt4";
|
||||
case Texture::CM_dxt5:
|
||||
return out << "dxt5";
|
||||
}
|
||||
|
||||
return out << "(**invalid Texture::CompressionMode(" << (int)cm << ")**)";
|
||||
}
|
||||
|
|
|
|||
|
|
@ -144,10 +144,31 @@ PUBLISHED:
|
|||
WM_invalid
|
||||
};
|
||||
|
||||
enum CompressionMode {
|
||||
// Generic compresssion modes. Usually, you should choose one of
|
||||
// these.
|
||||
CM_default, // on or off, according to compressed-textures
|
||||
CM_off, // uncompressed image
|
||||
CM_on, // whatever compression the driver supports
|
||||
|
||||
// Specific compression modes. Use only when you really want to
|
||||
// use a particular compression algorithm. Use with caution; not
|
||||
// all drivers support all compression modes. You can use
|
||||
// GSG::get_supports_compressed_texture_format() to query the
|
||||
// available compression modes for a particular GSG.
|
||||
CM_fxt1,
|
||||
CM_dxt1,
|
||||
CM_dxt2,
|
||||
CM_dxt3,
|
||||
CM_dxt4,
|
||||
CM_dxt5,
|
||||
};
|
||||
|
||||
PUBLISHED:
|
||||
Texture(const string &name = string());
|
||||
protected:
|
||||
Texture(const Texture ©);
|
||||
void operator = (const Texture ©);
|
||||
PUBLISHED:
|
||||
virtual ~Texture();
|
||||
|
||||
|
|
@ -179,6 +200,9 @@ PUBLISHED:
|
|||
int primary_file_num_channels = 0, int alpha_file_channel = 0);
|
||||
bool write(const Filename &fullpath, int z = 0) const;
|
||||
|
||||
bool read_txo(istream &in, const string &filename = "stream");
|
||||
bool write_txo(ostream &out, const string &filename = "stream") const;
|
||||
|
||||
bool read_pages(Filename fullpath_pattern, int z_size = 0);
|
||||
bool write_pages(Filename fullpath_pattern);
|
||||
|
||||
|
|
@ -213,6 +237,7 @@ PUBLISHED:
|
|||
void set_magfilter(FilterType filter);
|
||||
void set_anisotropic_degree(int anisotropic_degree);
|
||||
void set_border_color(const Colorf &color);
|
||||
void set_compression(CompressionMode compression);
|
||||
void set_render_to_texture(bool render_to_texture);
|
||||
|
||||
INLINE WrapMode get_wrap_u() const;
|
||||
|
|
@ -222,18 +247,22 @@ PUBLISHED:
|
|||
INLINE FilterType get_magfilter() const;
|
||||
INLINE int get_anisotropic_degree() const;
|
||||
INLINE Colorf get_border_color() const;
|
||||
INLINE CompressionMode get_compression() const;
|
||||
INLINE bool get_render_to_texture() const;
|
||||
INLINE bool uses_mipmaps() const;
|
||||
|
||||
virtual bool has_ram_image() const;
|
||||
INLINE bool might_have_ram_image() const;
|
||||
INLINE size_t get_ram_image_size() const;
|
||||
INLINE size_t get_ram_page_size() const;
|
||||
INLINE size_t get_expected_ram_image_size() const;
|
||||
INLINE size_t get_expected_ram_page_size() const;
|
||||
CPTA_uchar get_ram_image();
|
||||
INLINE CompressionMode get_ram_image_compression() const;
|
||||
PTA_uchar modify_ram_image();
|
||||
PTA_uchar make_ram_image();
|
||||
void set_ram_image(PTA_uchar image);
|
||||
void set_ram_image(PTA_uchar image, CompressionMode compression = CM_off,
|
||||
size_t page_size = 0);
|
||||
void clear_ram_image();
|
||||
INLINE void set_keep_ram_image(bool keep_ram_image);
|
||||
virtual bool get_keep_ram_image() const;
|
||||
|
|
@ -242,6 +271,8 @@ PUBLISHED:
|
|||
bool release(PreparedGraphicsObjects *prepared_objects);
|
||||
int release_all();
|
||||
|
||||
void write(ostream &out, int indent_level) const;
|
||||
|
||||
PUBLISHED:
|
||||
// These are published, but in general, you shouldn't be mucking
|
||||
// with these values; they are set automatically when a texture is
|
||||
|
|
@ -264,6 +295,9 @@ PUBLISHED:
|
|||
INLINE void set_loaded_from_disk();
|
||||
INLINE bool get_loaded_from_disk() const;
|
||||
|
||||
INLINE void set_loaded_from_txo();
|
||||
INLINE bool get_loaded_from_txo() const;
|
||||
|
||||
public:
|
||||
INLINE bool get_match_framebuffer_format() const;
|
||||
INLINE void set_match_framebuffer_format(bool flag);
|
||||
|
|
@ -298,6 +332,9 @@ public:
|
|||
static int up_to_power_2(int value);
|
||||
static int down_to_power_2(int value);
|
||||
|
||||
static bool is_specific(CompressionMode compression);
|
||||
static bool has_alpha(Format format);
|
||||
|
||||
protected:
|
||||
virtual void reconsider_dirty();
|
||||
virtual void reload_ram_image();
|
||||
|
|
@ -319,6 +356,10 @@ private:
|
|||
INLINE double get_unsigned_byte(int &index) const;
|
||||
INLINE double get_unsigned_short(int &index) const;
|
||||
|
||||
INLINE static bool is_txo_filename(const Filename &fullpath);
|
||||
bool read_txo_file(const Filename &fullpath);
|
||||
bool write_txo_file(const Filename &fullpath) const;
|
||||
|
||||
protected:
|
||||
Filename _filename;
|
||||
Filename _alpha_filename;
|
||||
|
|
@ -344,6 +385,7 @@ protected:
|
|||
ComponentType _component_type;
|
||||
|
||||
bool _loaded_from_disk;
|
||||
bool _loaded_from_txo;
|
||||
|
||||
WrapMode _wrap_u;
|
||||
WrapMode _wrap_v;
|
||||
|
|
@ -353,6 +395,7 @@ protected:
|
|||
int _anisotropic_degree;
|
||||
bool _keep_ram_image;
|
||||
Colorf _border_color;
|
||||
CompressionMode _compression;
|
||||
bool _render_to_texture;
|
||||
bool _match_framebuffer_format;
|
||||
|
||||
|
|
@ -377,7 +420,9 @@ protected:
|
|||
// texture.
|
||||
int _all_dirty_flags;
|
||||
|
||||
PTA_uchar _image;
|
||||
PTA_uchar _ram_image;
|
||||
CompressionMode _ram_image_compression;
|
||||
size_t _ram_page_size;
|
||||
|
||||
|
||||
// Datagram stuff
|
||||
|
|
@ -417,6 +462,8 @@ EXPCL_PANDA istream &operator >> (istream &in, Texture::FilterType &ft);
|
|||
EXPCL_PANDA ostream &operator << (ostream &out, Texture::WrapMode wm);
|
||||
EXPCL_PANDA istream &operator >> (istream &in, Texture::WrapMode &wm);
|
||||
|
||||
EXPCL_PANDA ostream &operator << (ostream &out, Texture::CompressionMode cm);
|
||||
|
||||
#include "texture.I"
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -33,6 +33,9 @@ VideoTexture::
|
|||
VideoTexture(const string &name) :
|
||||
Texture(name)
|
||||
{
|
||||
// We don't want to try to compress each frame as it's loaded.
|
||||
_compression = CM_off;
|
||||
|
||||
_video_width = 0;
|
||||
_video_height = 0;
|
||||
|
||||
|
|
@ -69,7 +72,7 @@ has_ram_image() const {
|
|||
if (this_frame != _last_frame_update) {
|
||||
return false;
|
||||
}
|
||||
return !_image.empty();
|
||||
return !_ram_image.empty();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -346,7 +346,7 @@ update_frame(int frame) {
|
|||
const unsigned char *source = page._color.get_frame_data(frame);
|
||||
if (source != NULL) {
|
||||
nassertv(get_video_width() <= _x_size && get_video_height() <= _y_size);
|
||||
unsigned char *dest = _image.p() + get_expected_ram_page_size() * z;
|
||||
unsigned char *dest = _ram_image.p() + get_expected_ram_page_size() * z;
|
||||
|
||||
int dest_row_width = (_x_size * _num_components * _component_width);
|
||||
int source_row_width = get_video_width() * 3;
|
||||
|
|
@ -385,7 +385,7 @@ update_frame(int frame) {
|
|||
const unsigned char *source = page._alpha.get_frame_data(frame);
|
||||
if (source != NULL) {
|
||||
nassertv(get_video_width() <= _x_size && get_video_height() <= _y_size);
|
||||
unsigned char *dest = _image.p() + get_expected_ram_page_size() * z;
|
||||
unsigned char *dest = _ram_image.p() + get_expected_ram_page_size() * z;
|
||||
|
||||
int dest_row_width = (_x_size * _num_components * _component_width);
|
||||
int source_row_width = get_video_width() * 3;
|
||||
|
|
|
|||
|
|
@ -369,6 +369,30 @@ get_current_minor_ver() {
|
|||
return _bam_minor_ver;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BamFile::get_reader
|
||||
// Access: Public
|
||||
// Description: Returns the BamReader in charge of performing the
|
||||
// read operations. This will return NULL unless
|
||||
// open_read() was called.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
BamReader *BamFile::
|
||||
get_reader() {
|
||||
return _reader;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BamFile::get_writer
|
||||
// Access: Public
|
||||
// Description: Returns the BamWriter in charge of performing the
|
||||
// write operations. This will return NULL unless
|
||||
// open_write() was called.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
BamWriter *BamFile::
|
||||
get_writer() {
|
||||
return _writer;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BamFile::continue_open_read
|
||||
// Access: Private
|
||||
|
|
|
|||
|
|
@ -78,6 +78,9 @@ PUBLISHED:
|
|||
int get_current_major_ver();
|
||||
int get_current_minor_ver();
|
||||
|
||||
BamReader *get_reader();
|
||||
BamWriter *get_writer();
|
||||
|
||||
private:
|
||||
bool continue_open_read(const string &bam_filename, bool report_errors);
|
||||
bool continue_open_write(const string &bam_filename, bool report_errors);
|
||||
|
|
|
|||
|
|
@ -12,7 +12,9 @@
|
|||
animInterface.h animInterface.I \
|
||||
bam.h bamEndian.h \
|
||||
bamReader.I bamReader.N bamReader.h bamReaderParam.I \
|
||||
bamReaderParam.h bamWriter.I bamWriter.h \
|
||||
bamReaderParam.h \
|
||||
bamTextureMode.h \
|
||||
bamWriter.I bamWriter.h \
|
||||
bitArray.I bitArray.h \
|
||||
bitMask.I bitMask.h \
|
||||
buttonHandle.I \
|
||||
|
|
@ -58,7 +60,9 @@
|
|||
#define INCLUDED_SOURCES \
|
||||
animInterface.cxx \
|
||||
bamEndian.cxx \
|
||||
bamReader.cxx bamReaderParam.cxx bamWriter.cxx \
|
||||
bamReader.cxx bamReaderParam.cxx \
|
||||
bamTextureMode.cxx \
|
||||
bamWriter.cxx \
|
||||
bitArray.cxx \
|
||||
bitMask.cxx \
|
||||
buttonHandle.cxx buttonRegistry.cxx \
|
||||
|
|
@ -91,6 +95,7 @@
|
|||
animInterface.h animInterface.I \
|
||||
bam.h bamEndian.h \
|
||||
bamReader.I bamReader.h bamReaderParam.I bamReaderParam.h \
|
||||
bamTextureMode.h \
|
||||
bamWriter.I bamWriter.h \
|
||||
bitArray.I bitArray.h \
|
||||
bitMask.I bitMask.h \
|
||||
|
|
|
|||
|
|
@ -36,7 +36,8 @@ static const unsigned short _bam_major_ver = 6;
|
|||
// Bumped to major version 5 on 5/6/05 for new Geom implementation.
|
||||
// Bumped to major version 6 on 2/11/06 to factor out PandaNode::CData.
|
||||
|
||||
static const unsigned short _bam_minor_ver = 0;
|
||||
static const unsigned short _bam_minor_ver = 1;
|
||||
// Bumped to minor version 1 on 3/12/06 to add Texture::_compression.
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -0,0 +1,66 @@
|
|||
// Filename: bamTextureMode.cxx
|
||||
// Created by: drose (14Mar06)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
|
||||
//
|
||||
// All use of this software is subject to the terms of the Panda 3d
|
||||
// Software license. You should have received a copy of this license
|
||||
// along with this source code; you will also find a current copy of
|
||||
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d-general@lists.sourceforge.net .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "bamTextureMode.h"
|
||||
#include "config_util.h"
|
||||
|
||||
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 {
|
||||
util_cat->error() << "Invalid BamTextureMode value: " << word << "\n";
|
||||
btm = BTM_relative;
|
||||
}
|
||||
|
||||
return in;
|
||||
}
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
// Filename: bamTextureMode.h
|
||||
// Created by: drose (14Mar06)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
|
||||
//
|
||||
// All use of this software is subject to the terms of the Panda 3d
|
||||
// Software license. You should have received a copy of this license
|
||||
// along with this source code; you will also find a current copy of
|
||||
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d-general@lists.sourceforge.net .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef BAMTEXTUREMODE_H
|
||||
#define BAMTEXTUREMODE_H
|
||||
|
||||
#include "pandabase.h"
|
||||
|
||||
// This enum is used to control how textures are written to a bam
|
||||
// stream.
|
||||
enum BamTextureMode {
|
||||
BTM_unchanged,
|
||||
BTM_fullpath,
|
||||
BTM_relative,
|
||||
BTM_basename,
|
||||
BTM_rawdata
|
||||
};
|
||||
EXPCL_PANDA ostream &operator << (ostream &out, BamTextureMode btm);
|
||||
EXPCL_PANDA istream &operator >> (istream &in, BamTextureMode &btm);
|
||||
|
||||
#endif
|
||||
|
|
@ -43,3 +43,29 @@ INLINE BamEndian BamWriter::
|
|||
get_file_endian() const {
|
||||
return _file_endian;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BamWriter::get_file_texture_mode
|
||||
// Access: Public
|
||||
// Description: Returns the BamTextureMode preference indicated by
|
||||
// the Bam file currently being written. Texture
|
||||
// objects written to this Bam file will be encoded
|
||||
// according to the specified mode.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE BamTextureMode BamWriter::
|
||||
get_file_texture_mode() const {
|
||||
return _file_texture_mode;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BamWriter::set_file_texture_mode
|
||||
// Access: Public
|
||||
// Description: Changes the BamTextureMode preference for
|
||||
// the Bam file currently being written. Texture
|
||||
// objects written to this Bam file will be encoded
|
||||
// according to the specified mode.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void BamWriter::
|
||||
set_file_texture_mode(BamTextureMode file_texture_mode) {
|
||||
_file_texture_mode = file_texture_mode;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -78,6 +78,7 @@ init() {
|
|||
_long_pta_id = false;
|
||||
|
||||
_file_endian = bam_endian;
|
||||
_file_texture_mode = bam_texture_mode;
|
||||
|
||||
// Write out the current major and minor BAM file version numbers.
|
||||
Datagram header;
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@
|
|||
#include "pandabase.h"
|
||||
#include "notify.h"
|
||||
#include "bamEndian.h"
|
||||
#include "bamTextureMode.h"
|
||||
#include "typedWritable.h"
|
||||
#include "datagramSink.h"
|
||||
#include "pdeque.h"
|
||||
|
|
@ -88,6 +89,9 @@ public:
|
|||
|
||||
INLINE BamEndian get_file_endian() const;
|
||||
|
||||
INLINE BamTextureMode get_file_texture_mode() const;
|
||||
INLINE void set_file_texture_mode(BamTextureMode file_texture_mode);
|
||||
|
||||
public:
|
||||
// Functions to support classes that write themselves to the Bam.
|
||||
|
||||
|
|
@ -109,6 +113,7 @@ private:
|
|||
Filename _filename;
|
||||
|
||||
BamEndian _file_endian;
|
||||
BamTextureMode _file_texture_mode;
|
||||
|
||||
// This is the set of all TypeHandles already written.
|
||||
pset<int, int_hash> _types_written;
|
||||
|
|
|
|||
|
|
@ -53,6 +53,11 @@ ConfigVariableEnum<BamEndian> bam_endian
|
|||
"may set it to \"littleendian\" or \"bigendian\" to target a "
|
||||
"particular platform."));
|
||||
|
||||
ConfigVariableEnum<BamTextureMode> 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."));
|
||||
|
||||
ConfigVariableSearchPath model_path
|
||||
("model-path",
|
||||
PRC_DESC("The default directories to search for all models and general "
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@
|
|||
#include "configVariableSearchPath.h"
|
||||
#include "configVariableEnum.h"
|
||||
#include "bamEndian.h"
|
||||
#include "bamTextureMode.h"
|
||||
#include "dconfig.h"
|
||||
|
||||
class DSearchPath;
|
||||
|
|
@ -36,9 +37,10 @@ NotifyCategoryDecl(bam, EXPCL_PANDA, EXPTP_PANDA);
|
|||
// because we must be able to access it at static init time. Instead
|
||||
// of declaring it a global constant, we'll make it a member of
|
||||
// MemoryUsage.
|
||||
|
||||
//extern EXPCL_PANDA const bool track_memory_usage;
|
||||
|
||||
extern EXPCL_PANDA ConfigVariableEnum<BamEndian> bam_endian;
|
||||
extern EXPCL_PANDA ConfigVariableEnum<BamTextureMode> bam_texture_mode;
|
||||
|
||||
extern EXPCL_PANDA ConfigVariableSearchPath model_path;
|
||||
extern EXPCL_PANDA ConfigVariableSearchPath texture_path;
|
||||
|
|
|
|||
|
|
@ -16,8 +16,8 @@
|
|||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef LOAD_EGG_FILE_H
|
||||
#define LOAD_EGG_FILE_H
|
||||
#ifndef LOAD_PRC_FILE_H
|
||||
#define LOAD_PRC_FILE_H
|
||||
|
||||
#include "pandabase.h"
|
||||
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
#include "bamEndian.cxx"
|
||||
#include "bamReader.cxx"
|
||||
#include "bamReaderParam.cxx"
|
||||
#include "bamTextureMode.cxx"
|
||||
#include "bamWriter.cxx"
|
||||
#include "bitArray.cxx"
|
||||
#include "bitMask.cxx"
|
||||
|
|
|
|||
|
|
@ -33,6 +33,10 @@ DynamicTextPage::
|
|||
DynamicTextPage(DynamicTextFont *font, int page_number) :
|
||||
_font(font)
|
||||
{
|
||||
// Since the texture might change frequently, don't try to compress
|
||||
// it by default.
|
||||
_compression = CM_off;
|
||||
|
||||
_x_size = _font->get_page_x_size();
|
||||
_y_size = _font->get_page_y_size();
|
||||
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@
|
|||
#include "bamFile.h"
|
||||
#include "pandaNode.h"
|
||||
#include "geomNode.h"
|
||||
#include "texture.h"
|
||||
#include "recorderHeader.h"
|
||||
#include "recorderFrame.h"
|
||||
#include "recorderTable.h"
|
||||
|
|
@ -145,6 +146,10 @@ get_info(const Filename &filename) {
|
|||
objects[0]->is_of_type(PandaNode::get_class_type())) {
|
||||
describe_scene_graph(DCAST(PandaNode, objects[0]));
|
||||
|
||||
} else if (objects.size() == 1 &&
|
||||
objects[0]->is_of_type(Texture::get_class_type())) {
|
||||
describe_texture(DCAST(Texture, objects[0]));
|
||||
|
||||
} else if (!objects.empty() && objects[0]->is_of_type(RecorderHeader::get_class_type())) {
|
||||
describe_session(DCAST(RecorderHeader, objects[0]), objects);
|
||||
|
||||
|
|
@ -189,6 +194,16 @@ describe_scene_graph(PandaNode *node) {
|
|||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BamInfo::describe_texture
|
||||
// Access: Private
|
||||
// Description: Called for Bam files that contain a Texture object.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void BamInfo::
|
||||
describe_texture(Texture *tex) {
|
||||
tex->write(nout, 2);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BamInfo::describe_session
|
||||
// Access: Private
|
||||
|
|
|
|||
|
|
@ -48,6 +48,7 @@ private:
|
|||
|
||||
bool get_info(const Filename &filename);
|
||||
void describe_scene_graph(PandaNode *node);
|
||||
void describe_texture(Texture *tex);
|
||||
void describe_session(RecorderHeader *header, const Objects &objects);
|
||||
void describe_general_object(TypedWritable *object);
|
||||
void list_hierarchy(PandaNode *node, int indent_level);
|
||||
|
|
|
|||
|
|
@ -24,6 +24,18 @@
|
|||
#include "config_egg2pg.h"
|
||||
#include "config_gobj.h"
|
||||
#include "config_chan.h"
|
||||
#include "pandaNode.h"
|
||||
#include "geomNode.h"
|
||||
#include "renderState.h"
|
||||
#include "textureAttrib.h"
|
||||
#include "dcast.h"
|
||||
#include "graphicsPipeSelection.h"
|
||||
#include "graphicsEngine.h"
|
||||
#include "graphicsBuffer.h"
|
||||
#include "graphicsStateGuardian.h"
|
||||
#include "load_prc_file.h"
|
||||
#include "windowProperties.h"
|
||||
#include "frameBufferProperties.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggToBam::Constructor
|
||||
|
|
@ -36,7 +48,10 @@ EggToBam() :
|
|||
{
|
||||
set_program_description
|
||||
("This program reads Egg files and outputs Bam files, the binary format "
|
||||
"suitable for direct loading of animation and models into Panda.");
|
||||
"suitable for direct loading of animation and models into Panda. Bam "
|
||||
"files are tied to a particular version of Panda, so should not be "
|
||||
"considered replacements for egg files, but they tend to be smaller and "
|
||||
"load much faster than the equivalent egg files.");
|
||||
|
||||
// -f is always in effect for egg2bam. It doesn't make sense to
|
||||
// provide it as an option to the user.
|
||||
|
|
@ -107,6 +122,53 @@ EggToBam() :
|
|||
"way to ensure the bam file is completely self-contained.",
|
||||
&EggToBam::dispatch_none, &_tex_rawdata);
|
||||
|
||||
add_option
|
||||
("txo", "", 0,
|
||||
"Rather than writing texture data directly into the bam file, as in "
|
||||
"-rawtex, create a texture object for each referenced texture. A "
|
||||
"texture object is a kind of mini-bam file, with a .txo extension, "
|
||||
"that contains all of the data needed to recreate a texture, including "
|
||||
"its image contents, filter and wrap settings, and so on. 3-D textures "
|
||||
"and cube maps can also be represented in a single .txo file. Texture "
|
||||
"object files, like bam files, are tied to a particular version of "
|
||||
"Panda.",
|
||||
&EggToBam::dispatch_none, &_tex_txo);
|
||||
|
||||
#ifdef HAVE_ZLIB
|
||||
add_option
|
||||
("txopz", "", 0,
|
||||
"In addition to writing texture object files as above, compress each "
|
||||
"one using pzip to a .txo.pz file. In many cases, this will yield a "
|
||||
"disk file size comparable to that achieved by png compression. This "
|
||||
"is an on-disk compression only, and does not affect the amount of "
|
||||
"RAM or texture memory consumed by the texture when it is loaded.",
|
||||
&EggToBam::dispatch_none, &_tex_txopz);
|
||||
#endif // HAVE_ZLIB
|
||||
|
||||
add_option
|
||||
("ctex", "", 0,
|
||||
"Asks the graphics card to pre-compress the texture images when using "
|
||||
"-rawtex or -txo. "
|
||||
#ifdef HAVE_ZLIB
|
||||
"This is unrelated to the on-disk compression achieved "
|
||||
"via -txopz (and it may be used in conjunction with that parameter). "
|
||||
#endif // HAVE_ZLIB
|
||||
"This will result in a smaller RAM and texture memory footprint for "
|
||||
"the texture images. The same "
|
||||
"effect can be achieved at load time by setting compressed-textures in "
|
||||
"your Config.prc file; but -ctex pre-compresses the "
|
||||
"textures so that they do not need to be compressed at load time. "
|
||||
"Note that using -ctex makes .txo files that are only guaranteed to load "
|
||||
"on the particular graphics card that was used to generate them.",
|
||||
&EggToBam::dispatch_none, &_tex_ctex);
|
||||
|
||||
add_option
|
||||
("load-display", "display name", 0,
|
||||
"Specifies the particular display module to load to perform the texture "
|
||||
"compression requested by -ctex. If this is omitted, the default is "
|
||||
"taken from the Config.prc file.",
|
||||
&EggToBam::dispatch_string, NULL, &_load_display);
|
||||
|
||||
redescribe_option
|
||||
("cs",
|
||||
"Specify the coordinate system of the resulting " + _format_name +
|
||||
|
|
@ -118,6 +180,7 @@ EggToBam() :
|
|||
_egg_flatten = 0;
|
||||
_egg_combine_geoms = 0;
|
||||
_egg_suppress_hidden = 1;
|
||||
_tex_txopz = false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -162,6 +225,31 @@ run() {
|
|||
nout << "Unable to build scene graph from egg file.\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (_tex_ctex) {
|
||||
if (!make_buffer()) {
|
||||
nout << "Unable to initialize graphics context; cannot compress textures.\n";
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
if (_tex_txo || _tex_txopz || (_tex_ctex && _tex_rawdata)) {
|
||||
collect_textures(root);
|
||||
Textures::iterator ti;
|
||||
for (ti = _textures.begin(); ti != _textures.end(); ++ti) {
|
||||
Texture *tex = (*ti);
|
||||
if (_tex_ctex) {
|
||||
tex->set_keep_ram_image(true);
|
||||
tex->set_compression(Texture::CM_on);
|
||||
if (!_engine->extract_texture_data(tex, _gsg)) {
|
||||
nout << " couldn't compress " << tex->get_name() << "\n";
|
||||
}
|
||||
}
|
||||
if (_tex_txo || _tex_txopz) {
|
||||
convert_txo(tex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (_ls) {
|
||||
root->ls(nout, 0);
|
||||
|
|
@ -170,7 +258,7 @@ run() {
|
|||
// This should be guaranteed because we pass false to the
|
||||
// constructor, above.
|
||||
nassertv(has_output_filename());
|
||||
|
||||
|
||||
Filename filename = get_output_filename();
|
||||
filename.make_dir();
|
||||
nout << "Writing " << filename << "\n";
|
||||
|
|
@ -214,6 +302,158 @@ handle_args(ProgramBase::Args &args) {
|
|||
return EggToSomething::handle_args(args);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggToBam::collect_textures
|
||||
// Access: Private
|
||||
// Description: Recursively walks the scene graph, looking for
|
||||
// Texture references.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void EggToBam::
|
||||
collect_textures(PandaNode *node) {
|
||||
collect_textures(node->get_state());
|
||||
if (node->is_geom_node()) {
|
||||
GeomNode *geom_node = DCAST(GeomNode, node);
|
||||
int num_geoms = geom_node->get_num_geoms();
|
||||
for (int i = 0; i < num_geoms; ++i) {
|
||||
collect_textures(geom_node->get_geom_state(i));
|
||||
}
|
||||
}
|
||||
|
||||
PandaNode::Children children = node->get_children();
|
||||
int num_children = children.get_num_children();
|
||||
for (int i = 0; i < num_children; ++i) {
|
||||
collect_textures(children.get_child(i));
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggToBam::collect_textures
|
||||
// Access: Private
|
||||
// Description: Recursively walks the scene graph, looking for
|
||||
// Texture references.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void EggToBam::
|
||||
collect_textures(const RenderState *state) {
|
||||
const TextureAttrib *tex_attrib = state->get_texture();
|
||||
if (tex_attrib != (TextureAttrib *)NULL) {
|
||||
int num_on_stages = tex_attrib->get_num_on_stages();
|
||||
for (int i = 0; i < num_on_stages; ++i) {
|
||||
_textures.insert(tex_attrib->get_on_texture(tex_attrib->get_on_stage(i)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggToBam::convert_txo
|
||||
// Access: Private
|
||||
// Description: If the indicated Texture was not already loaded from
|
||||
// a txo file, writes it to a txo file and updates the
|
||||
// Texture object to reference the new file.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void EggToBam::
|
||||
convert_txo(Texture *tex) {
|
||||
if (!tex->get_loaded_from_txo()) {
|
||||
Filename fullpath = tex->get_fullpath().get_filename_index(0);
|
||||
if (_tex_txopz) {
|
||||
fullpath.set_extension("txo.pz");
|
||||
// We use this clumsy syntax so that the new extension appears to be
|
||||
// two separate extensions, .txo followed by .pz, which is what
|
||||
// Texture::write() expects to find.
|
||||
fullpath = Filename(fullpath.get_fullpath());
|
||||
} else {
|
||||
fullpath.set_extension("txo");
|
||||
}
|
||||
|
||||
if (tex->write(fullpath)) {
|
||||
nout << " Writing " << fullpath;
|
||||
if (tex->get_ram_image_compression() != Texture::CM_off) {
|
||||
nout << " (compressed " << tex->get_ram_image_compression() << ")";
|
||||
}
|
||||
nout << "\n";
|
||||
tex->set_loaded_from_txo();
|
||||
tex->set_fullpath(fullpath);
|
||||
tex->clear_alpha_fullpath();
|
||||
|
||||
Filename filename = tex->get_filename().get_filename_index(0);
|
||||
if (_tex_txopz) {
|
||||
filename.set_extension("txo.pz");
|
||||
filename = Filename(filename.get_fullpath());
|
||||
} else {
|
||||
filename.set_extension("txo");
|
||||
}
|
||||
|
||||
tex->set_filename(filename);
|
||||
tex->clear_alpha_filename();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggToBam::make_buffer
|
||||
// Access: Private
|
||||
// Description: Creates a GraphicsBuffer for communicating with the
|
||||
// graphics card.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool EggToBam::
|
||||
make_buffer() {
|
||||
if (!_load_display.empty()) {
|
||||
// Override the user's config file with the command-line parameter.
|
||||
string prc = "load-display " + _load_display;
|
||||
load_prc_file_data("prc", prc);
|
||||
}
|
||||
|
||||
GraphicsPipeSelection *selection = GraphicsPipeSelection::get_global_ptr();
|
||||
_pipe = selection->make_default_pipe();
|
||||
if (_pipe == (GraphicsPipe *)NULL) {
|
||||
nout << "Unable to create graphics pipe.\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
_engine = new GraphicsEngine;
|
||||
|
||||
FrameBufferProperties fbprops = FrameBufferProperties::get_default();
|
||||
|
||||
// Some graphics drivers can only create single-buffered offscreen
|
||||
// buffers. So request that.
|
||||
fbprops.set_frame_buffer_mode((fbprops.get_frame_buffer_mode() & ~FrameBufferProperties::FM_buffer) | FrameBufferProperties::FM_single_buffer);
|
||||
|
||||
PT(GraphicsStateGuardian) gsg =
|
||||
_engine->make_gsg(_pipe, fbprops);
|
||||
if (gsg == (GraphicsStateGuardian *)NULL) {
|
||||
nout << "Unable to create GraphicsStateGuardian.\n";
|
||||
return false;
|
||||
}
|
||||
_gsg = gsg;
|
||||
|
||||
// We don't care how big the buffer is; we just need it to manifest
|
||||
// the GSG.
|
||||
_buffer = _engine->make_buffer(_gsg, "buffer", 0, 1, 1);
|
||||
_engine->open_windows();
|
||||
if (_buffer == (GraphicsOutput *)NULL || !_buffer->is_valid()) {
|
||||
if (_buffer != (GraphicsOutput *)NULL) {
|
||||
_engine->remove_window(_buffer);
|
||||
}
|
||||
|
||||
// Couldn't create a buffer; try for a window instead.
|
||||
GraphicsWindow *window = _engine->make_window(_gsg, "window", 0);
|
||||
if (window == (GraphicsWindow *)NULL) {
|
||||
nout << "Unable to create graphics window.\n";
|
||||
return false;
|
||||
}
|
||||
WindowProperties props;
|
||||
props.set_size(1, 1);
|
||||
props.set_origin(0, 0);
|
||||
props.set_undecorated(true);
|
||||
props.set_open(true);
|
||||
props.set_z_order(WindowProperties::Z_bottom);
|
||||
window->request_properties(props);
|
||||
_buffer = window;
|
||||
_engine->open_windows();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
EggToBam prog;
|
||||
|
|
|
|||
|
|
@ -22,6 +22,15 @@
|
|||
#include "pandatoolbase.h"
|
||||
|
||||
#include "eggToSomething.h"
|
||||
#include "pset.h"
|
||||
#include "graphicsPipe.h"
|
||||
|
||||
class PandaNode;
|
||||
class RenderState;
|
||||
class Texture;
|
||||
class GraphicsEngine;
|
||||
class GraphicsStateGuardian;
|
||||
class GraphicsOutput;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : EggToBam
|
||||
|
|
@ -37,6 +46,16 @@ protected:
|
|||
virtual bool handle_args(Args &args);
|
||||
|
||||
private:
|
||||
void collect_textures(PandaNode *node);
|
||||
void collect_textures(const RenderState *state);
|
||||
void convert_txo(Texture *tex);
|
||||
|
||||
bool make_buffer();
|
||||
|
||||
private:
|
||||
typedef pset<Texture *> Textures;
|
||||
Textures _textures;
|
||||
|
||||
bool _has_egg_flatten;
|
||||
int _egg_flatten;
|
||||
bool _has_egg_combine_geoms;
|
||||
|
|
@ -47,6 +66,16 @@ private:
|
|||
int _compression_quality;
|
||||
bool _compression_off;
|
||||
bool _tex_rawdata;
|
||||
bool _tex_txo;
|
||||
bool _tex_txopz;
|
||||
bool _tex_ctex;
|
||||
string _load_display;
|
||||
|
||||
// The rest of this is required to support -ctex.
|
||||
PT(GraphicsPipe) _pipe;
|
||||
GraphicsStateGuardian *_gsg;
|
||||
GraphicsEngine *_engine;
|
||||
GraphicsOutput *_buffer;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
Loading…
Reference in New Issue