better texture filename extension error reporting

This commit is contained in:
David Rose 2005-09-22 14:12:27 +00:00
parent 7312bb5a0d
commit 942f595c7f
9 changed files with 156 additions and 46 deletions

View File

@ -49,9 +49,9 @@
#include "pgTop.h"
#include "geomNode.h"
#include "texture.h"
#include "pnmImage.h"
#include "videoTexture.h"
#include "texturePool.h"
#include "loaderFileTypeRegistry.h"
#include "pnmFileTypeRegistry.h"
#include "pnmImage.h"
#include "virtualFileSystem.h"
@ -562,12 +562,10 @@ load_model(const NodePath &parent, Filename filename) {
reg->get_type_from_extension(extension);
if (model_type == (LoaderFileType *)NULL) {
// The extension isn't a known model file type, is it a known
// image extension?
PNMFileTypeRegistry *reg = PNMFileTypeRegistry::get_global_ptr();
PNMFileType *image_type =
reg->get_type_from_extension(extension);
if (image_type != (PNMFileType *)NULL) {
// It is a known image extension.
// 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;
}
}
@ -981,20 +979,35 @@ setup_lights() {
////////////////////////////////////////////////////////////////////
PT(PandaNode) WindowFramework::
load_image_as_model(const Filename &filename) {
PNMImageHeader header;
if (!header.read_header(filename)) {
PT(Texture) tex = TexturePool::load_texture(filename);
if (tex == NULL) {
return NULL;
}
int x_size = header.get_x_size();
int y_size = header.get_y_size();
bool has_alpha = header.has_alpha();
int x_size = tex->get_x_size();
int y_size = tex->get_y_size();
bool has_alpha = false;
LVecBase2f tex_scale(1.0f, 1.0f);
if (tex->is_of_type(VideoTexture::get_class_type())) {
// Get the size from the video stream.
VideoTexture *vtex = DCAST(VideoTexture, tex);
x_size = vtex->get_video_width();
y_size = vtex->get_video_height();
tex_scale = vtex->get_tex_scale();
} else {
// Get the size from the original image (the texture may have
// scaled it to make a power of 2).
PNMImageHeader header;
if (header.read_header(filename)) {
x_size = header.get_x_size();
y_size = header.get_y_size();
has_alpha = header.has_alpha();
}
}
// Yes, it is an image file; make a texture out of it.
PT(Texture) tex = new Texture;
if (!tex->read(filename)) {
return NULL;
}
tex->set_minfilter(Texture::FT_linear_mipmap_linear);
tex->set_magfilter(Texture::FT_linear);
@ -1024,10 +1037,10 @@ load_image_as_model(const Filename &filename) {
vertex.add_data3f(Vertexf::rfu(right, 0.02f, top));
vertex.add_data3f(Vertexf::rfu(right, 0.02f, bottom));
texcoord.add_data2f(0.0f, 1.0f);
texcoord.add_data2f(0.0f, tex_scale[1]);
texcoord.add_data2f(0.0f, 0.0f);
texcoord.add_data2f(1.0f, 1.0f);
texcoord.add_data2f(1.0f, 0.0f);
texcoord.add_data2f(tex_scale[0], tex_scale[1]);
texcoord.add_data2f(tex_scale[0], 0.0f);
PT(GeomTristrips) strip = new GeomTristrips(Geom::UH_static);
strip->add_consecutive_vertices(0, 4);

View File

@ -289,7 +289,7 @@ bool Texture::
read(const Filename &fullpath, int z, int primary_file_num_channels) {
PNMImage image;
if (!image.read(fullpath)) {
if (!image.read(fullpath, NULL, false)) {
gobj_cat.error()
<< "Texture::read() - couldn't read: " << fullpath << endl;
return false;
@ -328,14 +328,14 @@ bool Texture::
read(const Filename &fullpath, const Filename &alpha_fullpath,
int z, int primary_file_num_channels, int alpha_file_channel) {
PNMImage image;
if (!image.read(fullpath)) {
if (!image.read(fullpath, NULL, false)) {
gobj_cat.error()
<< "Texture::read() - couldn't read: " << fullpath << endl;
return false;
}
PNMImage alpha_image;
if (!alpha_image.read(alpha_fullpath)) {
if (!alpha_image.read(alpha_fullpath, NULL, true)) {
gobj_cat.error()
<< "Texture::read() - couldn't read (alpha): " << alpha_fullpath << endl;
return false;
@ -1330,6 +1330,17 @@ string_filter_type(const string &string) {
}
}
////////////////////////////////////////////////////////////////////
// Function: Texture::make_texture
// Access: Public, Static
// Description: A factory function to make a new Texture, used to
// pass to the TexturePool.
////////////////////////////////////////////////////////////////////
PT(Texture) Texture::
make_texture() {
return new Texture;
}
////////////////////////////////////////////////////////////////////
// Function: Texture::reconsider_dirty
// Access: Protected, Virtual

View File

@ -277,6 +277,8 @@ public:
static WrapMode string_wrap_mode(const string &string);
static FilterType string_filter_type(const string &string);
static PT(Texture) make_texture();
protected:
virtual void reconsider_dirty();
virtual void reload_ram_image();

View File

@ -22,6 +22,7 @@
#include "config_express.h"
#include "string_utils.h"
#include "virtualFileSystem.h"
#include "pnmFileTypeRegistry.h"
TexturePool *TexturePool::_global_ptr = (TexturePool *)NULL;
@ -59,6 +60,36 @@ register_texture_type(MakeTextureFunc *func, const string &extensions) {
}
}
////////////////////////////////////////////////////////////////////
// Function: TexturePool::get_texture_type
// Access: Public
// Description: Returns the factory function to construct a new
// texture of the type appropriate for the indicated
// filename extension, if any, or NULL if the extension
// is not one of the extensions for a texture file.
////////////////////////////////////////////////////////////////////
TexturePool::MakeTextureFunc *TexturePool::
get_texture_type(const string &extension) const {
string c = downcase(extension);
TypeRegistry::const_iterator ti;
ti = _type_registry.find(extension);
if (ti != _type_registry.end()) {
return (*ti).second;
}
// Check the PNM type registry.
PNMFileTypeRegistry *pnm_reg = PNMFileTypeRegistry::get_global_ptr();
PNMFileType *type = pnm_reg->get_type_from_extension(extension);
if (type != (PNMFileType *)NULL) {
// This is a known image type; create an ordinary Texture.
((TexturePool *)this)->_type_registry[extension] = Texture::make_texture;
return Texture::make_texture;
}
// This is an unknown texture type.
return NULL;
}
////////////////////////////////////////////////////////////////////
// Function: TexturePool::make_texture
// Access: Public
@ -68,16 +99,47 @@ register_texture_type(MakeTextureFunc *func, const string &extensions) {
// register_texture_type().
////////////////////////////////////////////////////////////////////
PT(Texture) TexturePool::
make_texture(const string &extension) {
string c = downcase(extension);
TypeRegistry::const_iterator ti;
ti = _type_registry.find(extension);
if (ti != _type_registry.end()) {
return (*ti).second();
make_texture(const string &extension) const {
MakeTextureFunc *func = get_texture_type(extension);
if (func != NULL) {
return func();
}
// We don't know what kind of file type this is; return an ordinary
// Texture in case it's an image file with no extension.
return new Texture;
}
////////////////////////////////////////////////////////////////////
// Function: TexturePool::write_texture_types
// Access: Public
// Description: Outputs a list of the available texture types to the
// indicated output stream. This is mostly the list of
// available image types, with maybe a few additional
// ones for video textures.
////////////////////////////////////////////////////////////////////
void TexturePool::
write_texture_types(ostream &out, int indent_level) const {
PNMFileTypeRegistry *pnm_reg = PNMFileTypeRegistry::get_global_ptr();
pnm_reg->write(out, indent_level);
// Also output any of the additional texture types, that aren't
// strictly images (these are typically video textures).
TypeRegistry::const_iterator ti;
for (ti = _type_registry.begin(); ti != _type_registry.end(); ++ti) {
string extension = (*ti).first;
MakeTextureFunc *func = (*ti).second;
if (pnm_reg->get_type_from_extension(extension) == NULL) {
PT(Texture) tex = func();
string name = tex->get_type().get_name();
indent(out, indent_level) << name;
indent(out, max(30 - (int)name.length(), 0))
<< " ." << extension << "\n";
}
}
}
////////////////////////////////////////////////////////////////////
// Function: TexturePool::get_global_ptr
// Access: Public, Static
@ -463,5 +525,14 @@ report_texture_unreadable(const Filename &filename) const {
// The file exists, but it couldn't be read for some reason.
gobj_cat.error()
<< "Texture \"" << filename << "\" exists but cannot be read.\n";
// Maybe the filename extension is unknown.
MakeTextureFunc *func = get_texture_type(filename.get_extension());
if (func == (MakeTextureFunc *)NULL) {
gobj_cat.error()
<< "Texture extension \"" << filename.get_extension()
<< "\" is unknown. Supported texture types:\n";
write_texture_types(gobj_cat.error(false), 2);
}
}
}

View File

@ -71,8 +71,10 @@ PUBLISHED:
public:
typedef PT(Texture) MakeTextureFunc();
void register_texture_type(MakeTextureFunc *func, const string &extensions);
PT(Texture) make_texture(const string &extension);
MakeTextureFunc *get_texture_type(const string &extension) const;
PT(Texture) make_texture(const string &extension) const;
void write_texture_types(ostream &out, int indent_level) const;
static TexturePool *get_global_ptr();

View File

@ -158,10 +158,11 @@ alpha_fill_val(xelval alpha) {
// is. Returns true if successful, false on error.
////////////////////////////////////////////////////////////////////
bool PNMImage::
read(const Filename &filename, PNMFileType *type) {
read(const Filename &filename, PNMFileType *type, bool report_unknown_type) {
clear();
PNMReader *reader = PNMImageHeader::make_reader(filename, type);
PNMReader *reader = PNMImageHeader::make_reader(filename, type,
report_unknown_type);
if (reader == (PNMReader *)NULL) {
return false;
}
@ -174,18 +175,21 @@ read(const Filename &filename, PNMFileType *type) {
// Description: Reads the image data from the indicated stream.
//
// The filename is advisory only, and may be used
// suggest a type if it has a known extension.
// to suggest a type if it has a known extension.
//
// If type is non-NULL, it is a suggestion for the type
// of file it is. Returns true if successful, false on
// error.
// of file it is (and a non-NULL type will override any
// magic number test or filename extension lookup).
//
// Returns true if successful, false on error.
////////////////////////////////////////////////////////////////////
bool PNMImage::
read(istream &data, const string &filename, PNMFileType *type) {
read(istream &data, const string &filename, PNMFileType *type,
bool report_unknown_type) {
clear();
PNMReader *reader = PNMImageHeader::make_reader
(&data, false, filename, string(), type);
(&data, false, filename, string(), type, report_unknown_type);
if (reader == (PNMReader *)NULL) {
return false;
}

View File

@ -87,9 +87,11 @@ PUBLISHED:
INLINE void alpha_fill(double alpha = 0.0);
void alpha_fill_val(xelval alpha = 0);
bool read(const Filename &filename, PNMFileType *type = NULL);
bool read(const Filename &filename, PNMFileType *type = NULL,
bool report_unknown_type = true);
bool read(istream &data, const string &filename = string(),
PNMFileType *type = NULL);
PNMFileType *type = NULL,
bool report_unknown_type = true);
bool read(PNMReader *reader);
bool write(const Filename &filename, PNMFileType *type = NULL) const;

View File

@ -58,7 +58,8 @@ read_header(const Filename &filename, PNMFileType *type) {
// needed.
////////////////////////////////////////////////////////////////////
PNMReader *PNMImageHeader::
make_reader(const Filename &filename, PNMFileType *type) const {
make_reader(const Filename &filename, PNMFileType *type,
bool report_unknown_type) const {
if (pnmimage_cat.is_debug()) {
pnmimage_cat.debug()
<< "Reading image from " << filename << "\n";
@ -88,7 +89,8 @@ make_reader(const Filename &filename, PNMFileType *type) const {
return NULL;
}
return make_reader(file, owns_file, filename, string(), type);
return make_reader(file, owns_file, filename, string(), type,
report_unknown_type);
}
@ -123,7 +125,8 @@ make_reader(const Filename &filename, PNMFileType *type) const {
////////////////////////////////////////////////////////////////////
PNMReader *PNMImageHeader::
make_reader(istream *file, bool owns_file, const Filename &filename,
string magic_number, PNMFileType *type) const {
string magic_number, PNMFileType *type,
bool report_unknown_type) const {
if (type == (PNMFileType *)NULL) {
if (!read_magic_number(file, magic_number, 2)) {
// No magic number. No image.
@ -188,7 +191,7 @@ make_reader(istream *file, bool owns_file, const Filename &filename,
if (type == (PNMFileType *)NULL) {
// We can't figure out what type the file is; give up.
if (pnmimage_cat.is_error()) {
if (report_unknown_type && pnmimage_cat.is_error()) {
pnmimage_cat.error()
<< "Cannot determine type of image file " << filename << ".\n"
<< "Currently supported image types:\n";

View File

@ -79,11 +79,13 @@ PUBLISHED:
bool read_header(const Filename &filename, PNMFileType *type = NULL);
PNMReader *make_reader(const Filename &filename,
PNMFileType *type = NULL) const;
PNMFileType *type = NULL,
bool report_unknown_type = true) const;
PNMReader *make_reader(istream *file, bool owns_file = true,
const Filename &filename = Filename(),
string magic_number = string(),
PNMFileType *type = NULL) const;
PNMFileType *type = NULL,
bool report_unknown_type = true) const;
PNMWriter *make_writer(const Filename &filename,
PNMFileType *type = NULL) const;