浏览代码

Add Image::SaveDDS function. Add Resource::Save|Load(fileName) functions.

Eugene Kozlov 9 年之前
父节点
当前提交
8acd69046a

+ 16 - 4
Source/Urho3D/AngelScript/APITemplates.h

@@ -777,26 +777,36 @@ template <class T> void RegisterNode(asIScriptEngine* engine, const char* classN
     engine->RegisterObjectMethod(className, "VariantMap& get_vars()", asFUNCTION(NodeGetVars), asCALL_CDECL_OBJLAST);
     engine->RegisterObjectMethod(className, "VariantMap& get_vars()", asFUNCTION(NodeGetVars), asCALL_CDECL_OBJLAST);
 }
 }
 
 
-static bool ResourceLoad(File* file, XMLFile* ptr)
+static bool ResourceLoad(File* file, Resource* ptr)
 {
 {
     return file && ptr->Load(*file);
     return file && ptr->Load(*file);
 }
 }
 
 
-static bool ResourceLoadVectorBuffer(VectorBuffer& buffer, XMLFile* ptr)
+static bool ResourceLoadVectorBuffer(VectorBuffer& buffer, Resource* ptr)
 {
 {
     return ptr->Load(buffer);
     return ptr->Load(buffer);
 }
 }
 
 
-static bool ResourceSave(File* file, XMLFile* ptr)
+static bool ResourceLoadByName(const String& fileName, Resource* ptr)
+{
+    return ptr->Load(fileName);
+}
+
+static bool ResourceSave(File* file, Resource* ptr)
 {
 {
     return file && ptr->Save(*file);
     return file && ptr->Save(*file);
 }
 }
 
 
-static bool ResourceSaveVectorBuffer(VectorBuffer& buffer, XMLFile* ptr)
+static bool ResourceSaveVectorBuffer(VectorBuffer& buffer, Resource* ptr)
 {
 {
     return ptr->Save(buffer);
     return ptr->Save(buffer);
 }
 }
 
 
+static bool ResourceSaveByName(const String& fileName, Resource* ptr)
+{
+    return ptr->Save(fileName);
+}
+
 /// Template function for registering a class derived from Resource.
 /// Template function for registering a class derived from Resource.
 template <class T> void RegisterResource(asIScriptEngine* engine, const char* className)
 template <class T> void RegisterResource(asIScriptEngine* engine, const char* className)
 {
 {
@@ -810,8 +820,10 @@ template <class T> void RegisterResource(asIScriptEngine* engine, const char* cl
     }
     }
     engine->RegisterObjectMethod(className, "bool Load(File@+)", asFUNCTION(ResourceLoad), asCALL_CDECL_OBJLAST);
     engine->RegisterObjectMethod(className, "bool Load(File@+)", asFUNCTION(ResourceLoad), asCALL_CDECL_OBJLAST);
     engine->RegisterObjectMethod(className, "bool Load(VectorBuffer&)", asFUNCTION(ResourceLoadVectorBuffer), asCALL_CDECL_OBJLAST);
     engine->RegisterObjectMethod(className, "bool Load(VectorBuffer&)", asFUNCTION(ResourceLoadVectorBuffer), asCALL_CDECL_OBJLAST);
+    engine->RegisterObjectMethod(className, "bool Load(const String&in)", asFUNCTION(ResourceLoadByName), asCALL_CDECL_OBJLAST);
     engine->RegisterObjectMethod(className, "bool Save(File@+) const", asFUNCTION(ResourceSave), asCALL_CDECL_OBJLAST);
     engine->RegisterObjectMethod(className, "bool Save(File@+) const", asFUNCTION(ResourceSave), asCALL_CDECL_OBJLAST);
     engine->RegisterObjectMethod(className, "bool Save(VectorBuffer&) const", asFUNCTION(ResourceSaveVectorBuffer), asCALL_CDECL_OBJLAST);
     engine->RegisterObjectMethod(className, "bool Save(VectorBuffer&) const", asFUNCTION(ResourceSaveVectorBuffer), asCALL_CDECL_OBJLAST);
+    engine->RegisterObjectMethod(className, "bool Save(const String&in) const", asFUNCTION(ResourceSaveByName), asCALL_CDECL_OBJLAST);
     engine->RegisterObjectMethod(className, "void set_name(const String&in) const", asMETHODPR(T, SetName, (const String&), void), asCALL_THISCALL);
     engine->RegisterObjectMethod(className, "void set_name(const String&in) const", asMETHODPR(T, SetName, (const String&), void), asCALL_THISCALL);
     engine->RegisterObjectMethod(className, "const String& get_name() const", asMETHODPR(T, GetName, () const, const String&), asCALL_THISCALL);
     engine->RegisterObjectMethod(className, "const String& get_name() const", asMETHODPR(T, GetName, () const, const String&), asCALL_THISCALL);
     engine->RegisterObjectMethod(className, "uint get_memoryUse() const", asMETHODPR(T, GetMemoryUse, () const, unsigned), asCALL_THISCALL);
     engine->RegisterObjectMethod(className, "uint get_memoryUse() const", asMETHODPR(T, GetMemoryUse, () const, unsigned), asCALL_THISCALL);

+ 1 - 0
Source/Urho3D/LuaScript/pkgs/Resource/Image.pkg

@@ -36,6 +36,7 @@ class Image : public Resource
     bool SavePNG(const String fileName) const;
     bool SavePNG(const String fileName) const;
     bool SaveTGA(const String fileName) const;
     bool SaveTGA(const String fileName) const;
     bool SaveJPG(const String fileName, int quality) const;
     bool SaveJPG(const String fileName, int quality) const;
+    bool SaveDDS(const String fileName) const;
 
 
     Color GetPixel(int x, int y) const;
     Color GetPixel(int x, int y) const;
     Color GetPixel(int x, int y, int z) const;
     Color GetPixel(int x, int y, int z) const;

+ 2 - 23
Source/Urho3D/LuaScript/pkgs/Resource/Resource.pkg

@@ -1,12 +1,11 @@
-$#include "IO/File.h"
 $#include "Resource/Resource.h"
 $#include "Resource/Resource.h"
 
 
 class Resource
 class Resource
 {
 {
     bool Load(Deserializer& source);
     bool Load(Deserializer& source);
     bool Save(Serializer& dest) const;
     bool Save(Serializer& dest) const;
-    tolua_outside bool ResourceLoad @ Load(const String fileName);
-    tolua_outside bool ResourceSave @ Save(const String fileName) const;
+    bool Load(const String& fileName);
+    bool Save(const String& fileName) const;
     
     
     const String GetName() const;
     const String GetName() const;
     StringHash GetNameHash() const;
     StringHash GetNameHash() const;
@@ -16,23 +15,3 @@ class Resource
     tolua_readonly tolua_property__get_set StringHash nameHash;
     tolua_readonly tolua_property__get_set StringHash nameHash;
     tolua_readonly tolua_property__get_set unsigned memoryUse;
     tolua_readonly tolua_property__get_set unsigned memoryUse;
 };
 };
-
-${
-static bool ResourceLoad(Resource* resource, const String& fileName)
-{
-    if (!resource)
-        return false;
-
-    File file(resource->GetContext());
-    return file.Open(fileName, FILE_READ) && resource->Load(file);
-}
-
-static bool ResourceSave(const Resource* resource, const String& fileName)
-{
-    if (!resource)
-        return false;
-
-    File file(resource->GetContext());
-    return file.Open(fileName, FILE_WRITE) && resource->Save(file);
-}
-$}

+ 65 - 0
Source/Urho3D/Resource/Image.cpp

@@ -775,6 +775,19 @@ bool Image::Save(Serializer& dest) const
     return success;
     return success;
 }
 }
 
 
+bool Image::Save(const String& fileName) const
+{
+    if (fileName.EndsWith(".dds", false))
+        return SaveDDS(fileName);
+    else if (fileName.EndsWith(".bmp", false))
+        return SaveBMP(fileName);
+    else if (fileName.EndsWith(".jpg", false) || fileName.EndsWith(".jpeg", false))
+        return SaveJPG(fileName, 100);
+    else if (fileName.EndsWith(".tga", false))
+        return SaveTGA(fileName);
+    else
+        return SavePNG(fileName);
+}
 
 
 bool Image::SetSize(int width, int height, unsigned components)
 bool Image::SetSize(int width, int height, unsigned components)
 {
 {
@@ -1212,6 +1225,58 @@ bool Image::SaveJPG(const String& fileName, int quality) const
         return false;
         return false;
 }
 }
 
 
+bool Image::SaveDDS(const String& fileName) const
+{
+    URHO3D_PROFILE(SaveImageDDS);
+
+    File outFile(context_, fileName, FILE_WRITE);
+    if (!outFile.IsOpen())
+    {
+        URHO3D_LOGERROR("Access denied to " + fileName);
+        return false;
+    }
+
+    if (IsCompressed())
+    {
+        URHO3D_LOGERROR("Can not save compressed image to DDS");
+        return false;
+    }
+
+    if (components_)
+    {
+        URHO3D_LOGERRORF("Can not save image with %u components to DDS", components_);
+        return false;
+    }
+
+    // Write image
+    PODVector<const Image*> levels;
+    GetLevels(levels);
+
+    outFile.WriteFileID("DDS ");
+
+    DDSurfaceDesc2 ddsd;
+    memset(&ddsd, 0, sizeof(ddsd));
+    ddsd.dwSize_ = sizeof(ddsd);
+    ddsd.dwFlags_ = 0x00000001l /*DDSD_CAPS*/
+        | 0x00000002l /*DDSD_HEIGHT*/ | 0x00000004l /*DDSD_WIDTH*/ | 0x00020000l /*DDSD_MIPMAPCOUNT*/ | 0x00001000l /*DDSD_PIXELFORMAT*/;
+    ddsd.dwWidth_ = width_;
+    ddsd.dwHeight_ = height_;
+    ddsd.dwMipMapCount_ = levels.Size();
+    ddsd.ddpfPixelFormat_.dwFlags_ = 0x00000040l /*DDPF_RGB*/ | 0x00000001l /*DDPF_ALPHAPIXELS*/;
+    ddsd.ddpfPixelFormat_.dwSize_ = sizeof(ddsd.ddpfPixelFormat_);
+    ddsd.ddpfPixelFormat_.dwRGBBitCount_ = 32;
+    ddsd.ddpfPixelFormat_.dwRBitMask_ = 0x000000ff;
+    ddsd.ddpfPixelFormat_.dwGBitMask_ = 0x0000ff00;
+    ddsd.ddpfPixelFormat_.dwBBitMask_ = 0x00ff0000;
+    ddsd.ddpfPixelFormat_.dwRGBAlphaBitMask_ = 0xff000000;
+
+    outFile.Write(&ddsd, sizeof(ddsd));
+    for (const Image* level : levels)
+        outFile.Write(level->GetData(), level->GetWidth() * level->GetHeight() * 4);
+
+    return true;
+}
+
 Color Image::GetPixel(int x, int y) const
 Color Image::GetPixel(int x, int y) const
 {
 {
     return GetPixel(x, y, 0);
     return GetPixel(x, y, 0);

+ 4 - 0
Source/Urho3D/Resource/Image.h

@@ -104,6 +104,8 @@ public:
     virtual bool BeginLoad(Deserializer& source);
     virtual bool BeginLoad(Deserializer& source);
     /// Save the image to a stream. Regardless of original format, the image is saved as png. Compressed image data is not supported. Return true if successful.
     /// Save the image to a stream. Regardless of original format, the image is saved as png. Compressed image data is not supported. Return true if successful.
     virtual bool Save(Serializer& dest) const;
     virtual bool Save(Serializer& dest) const;
+    /// Save the image to a file. Format of the image is determined by file extension. JPG is saved with maximum quality.
+    virtual bool Save(const String& fileName) const;
 
 
     /// Set 2D size and number of color components. Old image data will be destroyed and new data is undefined. Return true if successful.
     /// Set 2D size and number of color components. Old image data will be destroyed and new data is undefined. Return true if successful.
     bool SetSize(int width, int height, unsigned components);
     bool SetSize(int width, int height, unsigned components);
@@ -139,6 +141,8 @@ public:
     bool SaveTGA(const String& fileName) const;
     bool SaveTGA(const String& fileName) const;
     /// Save in JPG format with compression quality. Return true if successful.
     /// Save in JPG format with compression quality. Return true if successful.
     bool SaveJPG(const String& fileName, int quality) const;
     bool SaveJPG(const String& fileName, int quality) const;
+    /// Save in DDS format. Only uncompressed RGBA images are supported. Return true if successful.
+    bool SaveDDS(const String& fileName) const;
     /// Whether this texture is detected as a cubemap, only relevant for DDS.
     /// Whether this texture is detected as a cubemap, only relevant for DDS.
     bool IsCubemap() const { return cubemap_; }
     bool IsCubemap() const { return cubemap_; }
     /// Whether this texture has been detected as a volume, only relevant for DDS.
     /// Whether this texture has been detected as a volume, only relevant for DDS.

+ 13 - 0
Source/Urho3D/Resource/Resource.cpp

@@ -23,6 +23,7 @@
 #include "../Precompiled.h"
 #include "../Precompiled.h"
 
 
 #include "../Core/Profiler.h"
 #include "../Core/Profiler.h"
+#include "../IO/File.h"
 #include "../IO/Log.h"
 #include "../IO/Log.h"
 #include "../Resource/Resource.h"
 #include "../Resource/Resource.h"
 
 
@@ -82,6 +83,18 @@ bool Resource::Save(Serializer& dest) const
     return false;
     return false;
 }
 }
 
 
+bool Resource::Load(const String& fileName)
+{
+    File file(context_);
+    return file.Open(fileName, FILE_READ) && Load(file);
+}
+
+bool Resource::Save(const String& fileName) const
+{
+    File file(context_);
+    return file.Open(fileName, FILE_WRITE) && Save(file);
+}
+
 void Resource::SetName(const String& name)
 void Resource::SetName(const String& name)
 {
 {
     name_ = name;
     name_ = name;

+ 5 - 0
Source/Urho3D/Resource/Resource.h

@@ -64,6 +64,11 @@ public:
     /// Save resource. Return true if successful.
     /// Save resource. Return true if successful.
     virtual bool Save(Serializer& dest) const;
     virtual bool Save(Serializer& dest) const;
 
 
+    /// Load resource from file.
+    bool Load(const String& fileName);
+    /// Save resource to file.
+    virtual bool Save(const String& fileName) const;
+
     /// Set name.
     /// Set name.
     void SetName(const String& name);
     void SetName(const String& name);
     /// Set memory use in bytes, possibly approximate.
     /// Set memory use in bytes, possibly approximate.