Commit a603abe0 authored by Rogerborg's avatar Rogerborg

http://irrlicht.sourceforge.net/phpBB2/viewtopic.php?p=183427

Add IFileSystem::createMemoryWriteFile() to allow writing to memory.
Replace CMemoryReadFile with CMemoryFile that also implement IWriteFile.
Add an IVideoDriver::writeImageToFile() overload that takes an IWriteFile.
This allows writing (e.g.) screenshots to memory, rather than directly to file.

New unit test added to test the new functionality.  Tested on Windows with VS2005 and C::B. I'll do Linux ASAP.

git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/trunk@2081 dfc29bdd-3216-0410-991c-e03cc46cb475
parent 90eec5ad
Changes in version 1.6 Changes in version 1.6
- Added IFileSystem::createMemoryWriteFile() to allow creation of an IWriteFile interface that uses an application supplied memory buffer.
- Added an IVideoDriver::writeImageToFile() overload that can take an IWriteFile interface.
- (Internal) Replaced CMemoryReadFile with CMemoryFile, that also implements an IWriteFile interface.
- Added an optional light manager to the scene manager to allow the user application to turn lights on and off during scene rendering. This can be used to produce "zoned" lighting. See example 20.ManagedLights. - Added an optional light manager to the scene manager to allow the user application to turn lights on and off during scene rendering. This can be used to produce "zoned" lighting. See example 20.ManagedLights.
- Added a method to flip the Y movement of the FPS camera. - Added a method to flip the Y movement of the FPS camera.
......
...@@ -52,6 +52,21 @@ public: ...@@ -52,6 +52,21 @@ public:
*/ */
virtual IReadFile* createMemoryReadFile(void* memory, s32 len, const c8* fileName, bool deleteMemoryWhenDropped=false) = 0; virtual IReadFile* createMemoryReadFile(void* memory, s32 len, const c8* fileName, bool deleteMemoryWhenDropped=false) = 0;
//! Creates an IWriteFile interface for accessing memory like a file.
/** This allows you to use a pointer to memory where an IWriteFile is requested.
You are responsible for allocating enough memory.
\param memory: A pointer to the start of the file in memory (allocated by you)
\param len: The length of the memory in bytes
\param fileName: The name given to this file
\param deleteMemoryWhenDropped: True if the memory should be deleted
along with the IWriteFile when it is dropped.
\return Returns a pointer to the created file interface.
The returned pointer should be dropped when no longer needed.
See IReferenceCounted::drop() for more information.
*/
virtual IWriteFile* createMemoryWriteFile(void* memory, s32 len, const c8* fileName, bool deleteMemoryWhenDropped=false) = 0;
//! Opens a file for write access. //! Opens a file for write access.
/** \param filename: Name of file to open. /** \param filename: Name of file to open.
\param append: If the file already exist, all write operations are \param append: If the file already exist, all write operations are
......
...@@ -25,6 +25,7 @@ namespace io ...@@ -25,6 +25,7 @@ namespace io
{ {
class IAttributes; class IAttributes;
class IReadFile; class IReadFile;
class IWriteFile;
} // end namespace io } // end namespace io
namespace scene namespace scene
{ {
...@@ -834,6 +835,19 @@ namespace video ...@@ -834,6 +835,19 @@ namespace video
\return True on successful write. */ \return True on successful write. */
virtual bool writeImageToFile(IImage* image, const c8* filename, u32 param = 0) = 0; virtual bool writeImageToFile(IImage* image, const c8* filename, u32 param = 0) = 0;
//! Writes the provided image to a file.
/** Requires that there is a suitable image writer registered
for writing the image.
\param image Image to write.
\param file An already open io::IWriteFile object
\param extension A file extension that will identify the desired image
writer, e.g. ".jpg"
\param param Control parameter for the backend (e.g. compression
level).
\return True on successful write. */
virtual bool writeImageToFile(IImage* image, io::IWriteFile* file,
const c8* extension, u32 param = 0) = 0;
//! Creates a software image from a byte array. //! Creates a software image from a byte array.
/** No hardware texture will be created for this image. This /** No hardware texture will be created for this image. This
method is useful for example if you want to read a heightmap method is useful for example if you want to read a heightmap
......
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
#include "os.h" #include "os.h"
#include "IrrCompileConfig.h" #include "IrrCompileConfig.h"
#include "CAttributes.h" #include "CAttributes.h"
#include "CMemoryReadFile.h" #include "CMemoryFile.h"
#if defined (_IRR_WINDOWS_API_) #if defined (_IRR_WINDOWS_API_)
#if !defined ( _WIN32_WCE ) #if !defined ( _WIN32_WCE )
...@@ -97,7 +97,17 @@ IReadFile* CFileSystem::createMemoryReadFile(void* memory, s32 len, ...@@ -97,7 +97,17 @@ IReadFile* CFileSystem::createMemoryReadFile(void* memory, s32 len,
if (!memory) if (!memory)
return 0; return 0;
else else
return new CMemoryReadFile(memory, len, fileName, deleteMemoryWhenDropped); return new CMemoryFile(memory, len, fileName, deleteMemoryWhenDropped);
}
//! Creates an IReadFile interface for treating memory like a file.
IWriteFile* CFileSystem::createMemoryWriteFile(void* memory, s32 len,
const c8* fileName, bool deleteMemoryWhenDropped)
{
if (!memory)
return 0;
else
return new CMemoryFile(memory, len, fileName, deleteMemoryWhenDropped);
} }
......
...@@ -37,6 +37,9 @@ public: ...@@ -37,6 +37,9 @@ public:
//! Creates an IReadFile interface for accessing memory like a file. //! Creates an IReadFile interface for accessing memory like a file.
virtual IReadFile* createMemoryReadFile(void* memory, s32 len, const c8* fileName, bool deleteMemoryWhenDropped = false); virtual IReadFile* createMemoryReadFile(void* memory, s32 len, const c8* fileName, bool deleteMemoryWhenDropped = false);
//! Creates an IWriteFile interface for accessing memory like a file.
virtual IWriteFile* createMemoryWriteFile(void* memory, s32 len, const c8* fileName, bool deleteMemoryWhenDropped=false);
//! Opens a file for write access. //! Opens a file for write access.
virtual IWriteFile* createAndWriteFile(const c8* filename, bool append=false); virtual IWriteFile* createAndWriteFile(const c8* filename, bool append=false);
......
// Copyright (C) 2002-2009 Nikolaus Gebhardt // Copyright (C) 2002-2008 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine". // This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h // For conditions of distribution and use, see copyright notice in irrlicht.h
#include "CMemoryReadFile.h" #include "CMemoryFile.h"
#include "irrString.h" #include "irrString.h"
namespace irr namespace irr
...@@ -11,16 +11,16 @@ namespace io ...@@ -11,16 +11,16 @@ namespace io
{ {
CMemoryReadFile::CMemoryReadFile(void* memory, long len, const c8* fileName, bool d) CMemoryFile::CMemoryFile(void* memory, long len, const c8* fileName, bool d)
: Buffer(memory), Len(len), Pos(0), Filename(fileName), deleteMemoryWhenDropped(d) : Buffer(memory), Len(len), Pos(0), Filename(fileName), deleteMemoryWhenDropped(d)
{ {
#ifdef _DEBUG #ifdef _DEBUG
setDebugName("CMemoryReadFile"); setDebugName("CMemoryFile");
#endif #endif
} }
CMemoryReadFile::~CMemoryReadFile() CMemoryFile::~CMemoryFile()
{ {
if (deleteMemoryWhenDropped) if (deleteMemoryWhenDropped)
delete [] (c8*)Buffer; delete [] (c8*)Buffer;
...@@ -28,7 +28,7 @@ CMemoryReadFile::~CMemoryReadFile() ...@@ -28,7 +28,7 @@ CMemoryReadFile::~CMemoryReadFile()
//! returns how much was read //! returns how much was read
s32 CMemoryReadFile::read(void* buffer, u32 sizeToRead) s32 CMemoryFile::read(void* buffer, u32 sizeToRead)
{ {
s32 amount = static_cast<s32>(sizeToRead); s32 amount = static_cast<s32>(sizeToRead);
if (Pos + amount > Len) if (Pos + amount > Len)
...@@ -45,11 +45,30 @@ s32 CMemoryReadFile::read(void* buffer, u32 sizeToRead) ...@@ -45,11 +45,30 @@ s32 CMemoryReadFile::read(void* buffer, u32 sizeToRead)
return amount; return amount;
} }
//! returns how much was written
s32 CMemoryFile::write(const void* buffer, u32 sizeToWrite)
{
s32 amount = static_cast<s32>(sizeToWrite);
if (Pos + amount > Len)
amount -= Pos + amount - Len;
if (amount <= 0)
return 0;
c8* p = (c8*)Buffer;
memcpy(p + Pos, buffer, amount);
Pos += amount;
return amount;
}
//! changes position in file, returns true if successful //! changes position in file, returns true if successful
//! if relativeMovement==true, the pos is changed relative to current pos, //! if relativeMovement==true, the pos is changed relative to current pos,
//! otherwise from begin of file //! otherwise from begin of file
bool CMemoryReadFile::seek(long finalPos, bool relativeMovement) bool CMemoryFile::seek(long finalPos, bool relativeMovement)
{ {
if (relativeMovement) if (relativeMovement)
{ {
...@@ -71,21 +90,21 @@ bool CMemoryReadFile::seek(long finalPos, bool relativeMovement) ...@@ -71,21 +90,21 @@ bool CMemoryReadFile::seek(long finalPos, bool relativeMovement)
//! returns size of file //! returns size of file
long CMemoryReadFile::getSize() const long CMemoryFile::getSize() const
{ {
return Len; return Len;
} }
//! returns where in the file we are. //! returns where in the file we are.
long CMemoryReadFile::getPos() const long CMemoryFile::getPos() const
{ {
return Pos; return Pos;
} }
//! returns name of file //! returns name of file
const c8* CMemoryReadFile::getFileName() const const c8* CMemoryFile::getFileName() const
{ {
return Filename.c_str(); return Filename.c_str();
} }
...@@ -93,7 +112,7 @@ const c8* CMemoryReadFile::getFileName() const ...@@ -93,7 +112,7 @@ const c8* CMemoryReadFile::getFileName() const
IReadFile* createMemoryReadFile(void* memory, long size, const c8* fileName, bool deleteMemoryWhenDropped) IReadFile* createMemoryReadFile(void* memory, long size, const c8* fileName, bool deleteMemoryWhenDropped)
{ {
CMemoryReadFile* file = new CMemoryReadFile(memory, size, fileName, deleteMemoryWhenDropped); CMemoryFile* file = new CMemoryFile(memory, size, fileName, deleteMemoryWhenDropped);
return file; return file;
} }
......
// Copyright (C) 2002-2009 Nikolaus Gebhardt // Copyright (C) 2002-2008 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine". // This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h // For conditions of distribution and use, see copyright notice in irrlicht.h
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#define __C_MEMORY_READ_FILE_H_INCLUDED__ #define __C_MEMORY_READ_FILE_H_INCLUDED__
#include "IReadFile.h" #include "IReadFile.h"
#include "IWriteFile.h"
#include "irrString.h" #include "irrString.h"
namespace irr namespace irr
...@@ -15,21 +16,24 @@ namespace io ...@@ -15,21 +16,24 @@ namespace io
{ {
/*! /*!
Class for reading from memory. Class for reading and writing from memory.
*/ */
class CMemoryReadFile : public IReadFile class CMemoryFile : public IReadFile, public IWriteFile
{ {
public: public:
//! Constructor //! Constructor
CMemoryReadFile(void* memory, long len, const c8* fileName, bool deleteMemoryWhenDropped); CMemoryFile(void* memory, long len, const c8* fileName, bool deleteMemoryWhenDropped);
//! Destructor //! Destructor
virtual ~CMemoryReadFile(); virtual ~CMemoryFile();
//! returns how much was read //! returns how much was read
virtual s32 read(void* buffer, u32 sizeToRead); virtual s32 read(void* buffer, u32 sizeToRead);
//! returns how much was written
virtual s32 write(const void* buffer, u32 sizeToWrite);
//! changes position in file, returns true if successful //! changes position in file, returns true if successful
virtual bool seek(long finalPos, bool relativeMovement = false); virtual bool seek(long finalPos, bool relativeMovement = false);
......
...@@ -1244,18 +1244,29 @@ IImage* CNullDriver::createImageFromFile(io::IReadFile* file) ...@@ -1244,18 +1244,29 @@ IImage* CNullDriver::createImageFromFile(io::IReadFile* file)
//! Writes the provided image to disk file //! Writes the provided image to disk file
bool CNullDriver::writeImageToFile(IImage* image, const char* filename,u32 param) bool CNullDriver::writeImageToFile(IImage* image, const char* filename,u32 param)
{ {
io::IWriteFile* file = FileSystem->createAndWriteFile(filename);
if(!file)
return false;
bool result = writeImageToFile(image, file, filename, param);
file->drop();
return result;
}
//! Writes the provided image to a file.
bool CNullDriver::writeImageToFile(IImage* image, io::IWriteFile * file, const c8* extension, u32 param)
{
if(!file)
return false;
for (u32 i=0; i<SurfaceWriter.size(); ++i) for (u32 i=0; i<SurfaceWriter.size(); ++i)
{ {
if (SurfaceWriter[i]->isAWriteableFileExtension(filename)) if (SurfaceWriter[i]->isAWriteableFileExtension(extension))
{ {
io::IWriteFile* file = FileSystem->createAndWriteFile(filename); bool written = SurfaceWriter[i]->writeImage(file, image, param);
if (file) if (written)
{ return true;
bool written = SurfaceWriter[i]->writeImage(file, image, param);
file->drop();
if (written)
return true;
}
} }
} }
return false; // failed to write return false; // failed to write
......
...@@ -488,6 +488,9 @@ namespace video ...@@ -488,6 +488,9 @@ namespace video
//! Writes the provided image to disk file //! Writes the provided image to disk file
virtual bool writeImageToFile(IImage* image, const char* filename, u32 param = 0); virtual bool writeImageToFile(IImage* image, const char* filename, u32 param = 0);
//! Writes the provided image to a file.
virtual bool writeImageToFile(IImage* image, io::IWriteFile * file, const c8* extension, u32 param = 0);
//! Sets the name of a material renderer. //! Sets the name of a material renderer.
virtual void setMaterialRendererName(s32 idx, const char* name); virtual void setMaterialRendererName(s32 idx, const char* name);
......
...@@ -537,8 +537,8 @@ ...@@ -537,8 +537,8 @@
<Unit filename="CMY3DHelper.h" /> <Unit filename="CMY3DHelper.h" />
<Unit filename="CMY3DMeshFileLoader.cpp" /> <Unit filename="CMY3DMeshFileLoader.cpp" />
<Unit filename="CMY3DMeshFileLoader.h" /> <Unit filename="CMY3DMeshFileLoader.h" />
<Unit filename="CMemoryReadFile.cpp" /> <Unit filename="CMemoryFile.cpp" />
<Unit filename="CMemoryReadFile.h" /> <Unit filename="CMemoryFile.h" />
<Unit filename="CMeshCache.cpp" /> <Unit filename="CMeshCache.cpp" />
<Unit filename="CMeshCache.h" /> <Unit filename="CMeshCache.h" />
<Unit filename="CMeshManipulator.cpp" /> <Unit filename="CMeshManipulator.cpp" />
......
...@@ -2840,7 +2840,7 @@ OverrideBuildCmd=0 ...@@ -2840,7 +2840,7 @@ OverrideBuildCmd=0
BuildCmd= BuildCmd=
[Unit282] [Unit282]
FileName=CMemoryReadFile.cpp FileName=CMemoryFile.cpp
Folder=io_impl Folder=io_impl
Compile=1 Compile=1
CompileCpp=1 CompileCpp=1
...@@ -2850,7 +2850,7 @@ OverrideBuildCmd=0 ...@@ -2850,7 +2850,7 @@ OverrideBuildCmd=0
BuildCmd= BuildCmd=
[Unit283] [Unit283]
FileName=CMemoryReadFile.h FileName=CMemoryFile.h
Folder=io_impl Folder=io_impl
Compile=1 Compile=1
CompileCpp=1 CompileCpp=1
......
...@@ -1995,10 +1995,10 @@ ...@@ -1995,10 +1995,10 @@
RelativePath=".\CLimitReadFile.h"> RelativePath=".\CLimitReadFile.h">
</File> </File>
<File <File
RelativePath=".\CMemoryReadFile.cpp"> RelativePath=".\CMemoryFile.cpp">
</File> </File>
<File <File
RelativePath=".\CMemoryReadFile.h"> RelativePath=".\CMemoryFile.h">
</File> </File>
<File <File
RelativePath=".\CPakReader.cpp"> RelativePath=".\CPakReader.cpp">
......
...@@ -2191,11 +2191,11 @@ ...@@ -2191,11 +2191,11 @@
> >
</File> </File>
<File <File
RelativePath="CDummyTransformationSceneNode.cpp" RelativePath=".\CDummyTransformationSceneNode.cpp"
> >
</File> </File>
<File <File
RelativePath="CDummyTransformationSceneNode.h" RelativePath=".\CDummyTransformationSceneNode.h"
> >
</File> </File>
<File <File
...@@ -2596,11 +2596,11 @@ ...@@ -2596,11 +2596,11 @@
> >
</File> </File>
<File <File
RelativePath="CMemoryReadFile.cpp" RelativePath=".\CMemoryFile.cpp"
> >
</File> </File>
<File <File
RelativePath="CMemoryReadFile.h" RelativePath=".\CMemoryFile.h"
> >
</File> </File>
<File <File
......
...@@ -2675,11 +2675,11 @@ ...@@ -2675,11 +2675,11 @@
> >
</File> </File>
<File <File
RelativePath="CMemoryReadFile.cpp" RelativePath="CMemoryFile.cpp"
> >
</File> </File>
<File <File
RelativePath="CMemoryReadFile.h" RelativePath="CMemoryFile.h"
> >
</File> </File>
<File <File
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
// Other builds must link against it in the project files. // Other builds must link against it in the project files.
#if defined(_MSC_VER) #if defined(_MSC_VER)
#pragma comment(lib, "Irrlicht.lib") #pragma comment(lib, "Irrlicht.lib")
#define _CRT_SECURE_NO_WARNINGS #define _CRT_SECURE_NO_WARNINGS 1
#endif // _MSC_VER #endif // _MSC_VER
#include "testUtils.h" #include "testUtils.h"
...@@ -86,6 +86,7 @@ int main(int argumentCount, char * arguments[]) ...@@ -86,6 +86,7 @@ int main(int argumentCount, char * arguments[])
TEST(matrixOps); TEST(matrixOps);
TEST(sceneNodeAnimator); TEST(sceneNodeAnimator);
TEST(vectorPositionDimension2d); TEST(vectorPositionDimension2d);
TEST(writeImageToFile);
const unsigned int numberOfTests = tests.size(); const unsigned int numberOfTests = tests.size();
......
// Copyright (C) 2008-2009 Colin MacDonald // Copyright (C) 2008-2009 Colin MacDonald
// No rights reserved: this software is in the public domain. // No rights reserved: this software is in the public domain.
#define _CRT_SECURE_NO_WARNINGS #if defined(_MSC_VER)
#define _CRT_SECURE_NO_WARNINGS 1
#endif // _MSC_VER
#include "testUtils.h" #include "testUtils.h"
#include <memory.h> #include <memory.h>
#include <stdio.h> #include <stdio.h>
...@@ -41,9 +44,12 @@ bool binaryCompareFiles(const char * fileName1, const char * fileName2) ...@@ -41,9 +44,12 @@ bool binaryCompareFiles(const char * fileName1, const char * fileName2)
(void)fseek(file1, 0, SEEK_END); (void)fseek(file1, 0, SEEK_END);
(void)fseek(file2, 0, SEEK_END); (void)fseek(file2, 0, SEEK_END);
if(ftell(file1) != ftell(file2)) const size_t file1Size = ftell(file1);
const size_t file2Size = ftell(file2);
if(file1Size != file2Size)
{ {
logTestString("binaryCompareFiles: Files are different sizes\n"); logTestString("binaryCompareFiles: Files are different sizes: %d vs %d\n",
file1Size, file2Size);
(void)fclose(file1); (void)fclose(file1);
(void)fclose(file2); (void)fclose(file2);
return false; return false;
......
...@@ -2,12 +2,16 @@ ...@@ -2,12 +2,16 @@
#ifndef _TEST_UTILS_H_ #ifndef _TEST_UTILS_H_
#define _TEST_UTILS_H_ 1 #define _TEST_UTILS_H_ 1
#include "irrlicht.h"
#if defined(_WIN32) || defined(_WIN64) || defined(WIN32) || defined(WIN64) || defined(_WIN32_WCE) #if defined(_WIN32) || defined(_WIN64) || defined(WIN32) || defined(WIN64) || defined(_WIN32_WCE)
#define TESTING_ON_WINDOWS #define TESTING_ON_WINDOWS
#define DIR_SEP_STRING "\\"
#else
#define DIR_SEP_STRING "/"
#endif #endif
#include "irrlicht.h"
//! Compare two files //! Compare two files
/** \param fileName1 The first file for comparison. /** \param fileName1 The first file for comparison.
\param fileName1 The second file for comparison. \param fileName1 The second file for comparison.
......
Test suite pass at GMT Mon Jan 12 10:46:46 2009 Test suite pass at GMT Fri Jan 16 14:15:51 2009
...@@ -46,8 +46,8 @@ ...@@ -46,8 +46,8 @@
<Unit filename="drawRectOutline.cpp" /> <Unit filename="drawRectOutline.cpp" />
<Unit filename="exports.cpp" /> <Unit filename="exports.cpp" />
<Unit filename="fast_atof.cpp" /> <Unit filename="fast_atof.cpp" />
<Unit filename="irrCoreEquals.cpp" />
<Unit filename="guiDisabledMenu.cpp" /> <Unit filename="guiDisabledMenu.cpp" />
<Unit filename="irrCoreEquals.cpp" />
<Unit filename="line2dIntersectWith.cpp" /> <Unit filename="line2dIntersectWith.cpp" />
<Unit filename="main.cpp" /> <Unit filename="main.cpp" />
<Unit filename="makeColorKeyTexture.cpp" /> <Unit filename="makeColorKeyTexture.cpp" />
...@@ -65,6 +65,7 @@ ...@@ -65,6 +65,7 @@
<Unit filename="textureRenderStates.cpp" /> <Unit filename="textureRenderStates.cpp" />
<Unit filename="transparentAlphaChannelRef.cpp" /> <Unit filename="transparentAlphaChannelRef.cpp" />
<Unit filename="vectorPositionDimension2d.cpp" /> <Unit filename="vectorPositionDimension2d.cpp" />
<Unit filename="writeImageToFile.cpp" />
<Extensions> <Extensions>
<code_completion /> <code_completion />
<debugger /> <debugger />
......
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?> <?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<CodeBlocks_workspace_file> <CodeBlocks_workspace_file>
<Workspace title="tests"> <Workspace title="tests">
<Project filename="..\source\Irrlicht\Irrlicht-gcc.cbp" />
<Project filename="tests.cbp" active="1" /> <Project filename="tests.cbp" active="1" />
<Project filename="..\source\Irrlicht\Irrlicht-gcc.cbp" />
</Workspace> </Workspace>
</CodeBlocks_workspace_file> </CodeBlocks_workspace_file>
...@@ -281,6 +281,10 @@ ...@@ -281,6 +281,10 @@
RelativePath=".\vectorPositionDimension2d.cpp" RelativePath=".\vectorPositionDimension2d.cpp"
> >
</File> </File>
<File
RelativePath=".\writeImageToFile.cpp"
>
</File>
</Filter> </Filter>
<Filter <Filter
Name="Header Files" Name="Header Files"
......
...@@ -279,6 +279,10 @@ ...@@ -279,6 +279,10 @@
RelativePath=".\vectorPositionDimension2d.cpp" RelativePath=".\vectorPositionDimension2d.cpp"
> >
</File> </File>
<File
RelativePath=".\writeImageToFile.cpp"
>
</File>
</Filter> </Filter>
<Filter <Filter
Name="Header Files" Name="Header Files"
......
// Copyright (C) 2009 Colin MacDonald
// No rights reserved: this software is in the public domain.
#if defined(_MSC_VER)
#define _CRT_SECURE_NO_WARNINGS 1
#endif // _MSC_VER
#include "irrlicht.h"
#include "testUtils.h"
#include <assert.h>
using namespace irr;
using namespace core;
using namespace scene;
using namespace video;
using namespace io;
using namespace gui;
//! Tests IVideoDriver::writeImageToFile() using IWriteFile
bool writeImageToFile(void)
{
IrrlichtDevice *device = createDevice( EDT_BURNINGSVIDEO, dimension2d<s32>(160, 120), 32);
if (!device)
return true; // Treat a failure to create a driver as benign; this saves a lot of #ifdefs
IVideoDriver* driver = device->getVideoDriver();
ISceneManager * smgr = device->getSceneManager();
// Draw a cube background so that we can check that the pixels' alpha is working.
ISceneNode * cube = smgr->addCubeSceneNode(50.f, 0, -1, vector3df(0, 0, 60));
cube->setMaterialTexture(0, driver->getTexture("../media/wall.bmp"));
cube->setMaterialFlag(video::EMF_LIGHTING, false);
(void)smgr->addCameraSceneNode();
driver->beginScene(true, true, SColor(255,100,101,140));
smgr->drawAll();
// Test for benign handling of offscreen pixel values as well as onscreen ones.
for(s32 x = -10; x < 170; ++x)
{
s32 y = 120 * x / 160;
driver->drawPixel((u32)x, (u32)y, SColor(255, 255 * x / 640, 255 * (640 - x) / 640, 0));
y = 120 - y;
driver->drawPixel((u32)x, (u32)y, SColor(255 * x / 640, 0, 255, 255));
}
driver->endScene();
bool result = false;
IWriteFile * writtenFile = 0;
IWriteFile * memoryFile = 0;
const char * writtenFilename = 0;
const u32 BUFFER_SIZE = 160 * 120 * 4;
c8 * buffer = 0;
const char * referenceFilename = 0;
irr::video::IImage * screenshot = driver->createScreenShot();
if(!screenshot)
{
logTestString("Failed to take screenshot\n");
assert(false);
goto cleanup;
}
const video::ECOLOR_FORMAT format = screenshot->getColorFormat();
if(format != video::ECF_R8G8B8)
{
irr::video::IImage * fixedScreenshot = driver->createImage(video::ECF_R8G8B8, screenshot);
screenshot->drop();
if(!fixedScreenshot)
{
logTestString("Failed to convert screenshot to ECF_A8R8G8B8\n");
assert(false);
goto cleanup;
}
screenshot = fixedScreenshot;
}
buffer = new c8[BUFFER_SIZE];
memoryFile = device->getFileSystem()->createMemoryWriteFile(buffer, BUFFER_SIZE, "foo", false);
if(!driver->writeImageToFile(screenshot, memoryFile, ".png"))
{
logTestString("Failed to write png to memory file\n");
assert(false);
goto cleanup;
}
writtenFilename = "results" DIR_SEP_STRING "burnings video 0.39b-drawPixel.png";
writtenFile = device->getFileSystem()->createAndWriteFile(writtenFilename);
if(!writtenFile)
{
logTestString("Can't open %s for writing.\n", writtenFilename);
assert(false);
goto cleanup;
}
if(memoryFile->getPos() != writtenFile->write(buffer, memoryFile->getPos()))
{
logTestString("Error while writing to %s.\n", writtenFilename);
assert(false);
goto cleanup;
}
writtenFile->drop();
writtenFile = 0;
referenceFilename = "media" DIR_SEP_STRING "burnings video 0.39b-drawPixel.png";
if(!binaryCompareFiles(writtenFilename, referenceFilename))
{
logTestString("File written from memory is not the same as the reference file.\n");
assert(false);
goto cleanup;
}
result = true;
cleanup:
if(writtenFile)
writtenFile->drop();
if(memoryFile)
memoryFile->drop();
delete [] buffer;
device->drop();
return result;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment