Cleanup line endings (#245)

The exact commands to make this commit were:

git reset --hard origin/master
find -type f |  # list all regular files
  grep -E '\.(h|cpp|fsh|vsh|mm)|LICENSE$' |  # filter for text files
  xargs -n 1 -P $(nproc) sed -i 's:\s*$::'  # for each file, trim trailing whitespace including the CR
git commit -a
This commit is contained in:
Vitaliy
2023-10-03 21:37:00 +03:00
committed by GitHub
parent ea1b58387e
commit 9954667c45
303 changed files with 99367 additions and 99367 deletions

View File

@ -1,109 +1,109 @@
// Copyright (C) 2002-2011 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#ifdef _IRR_COMPILE_ANDROID_ASSET_READER_
#include "CAndroidAssetReader.h"
#include "CReadFile.h"
#include "coreutil.h"
#include "CAndroidAssetFileArchive.h"
#include "CIrrDeviceAndroid.h"
#include "os.h" // for logging (just keep it in even when not needed right now as it's used all the time)
#include <android_native_app_glue.h>
#include <android/native_activity.h>
#include <android/log.h>
namespace irr
{
namespace io
{
CAndroidAssetFileArchive::CAndroidAssetFileArchive(AAssetManager *assetManager, bool ignoreCase, bool ignorePaths)
: CFileList("/asset", ignoreCase, ignorePaths), AssetManager(assetManager)
{
}
CAndroidAssetFileArchive::~CAndroidAssetFileArchive()
{
}
//! get the archive type
E_FILE_ARCHIVE_TYPE CAndroidAssetFileArchive::getType() const
{
return EFAT_ANDROID_ASSET;
}
const IFileList* CAndroidAssetFileArchive::getFileList() const
{
// The assert_manager can not read directory names, so
// getFileList returns only files in folders which have been added.
return this;
}
//! opens a file by file name
IReadFile* CAndroidAssetFileArchive::createAndOpenFile(const io::path& filename)
{
CAndroidAssetReader *reader = new CAndroidAssetReader(AssetManager, filename);
if(reader->isOpen())
return reader;
reader->drop();
return NULL;
}
//! opens a file by index
IReadFile* CAndroidAssetFileArchive::createAndOpenFile(u32 index)
{
const io::path& filename(getFullFileName(index));
if ( filename.empty() )
return 0;
return createAndOpenFile(filename);
}
void CAndroidAssetFileArchive::addDirectoryToFileList(const io::path &dirname_)
{
io::path dirname(dirname_);
fschar_t lastChar = dirname.lastChar();
if ( lastChar == '/' || lastChar == '\\' )
dirname.erase(dirname.size()-1);
// os::Printer::log("addDirectoryToFileList:", dirname.c_str(), ELL_DEBUG);
if (findFile(dirname, true) >= 0 )
return; // was already added
AAssetDir *dir = AAssetManager_openDir(AssetManager, core::stringc(dirname).c_str());
if(!dir)
return;
// add directory itself
addItem(dirname, 0, 0, /*isDir*/true, getFileCount());
// add all files in folder.
// Note: AAssetDir_getNextFileName does not return directory names (neither does any other NDK function)
while(const char *filename = AAssetDir_getNextFileName(dir))
{
core::stringc full_filename= dirname=="" ? filename
: dirname+"/"+filename;
// We can't get the size without opening the file - so for performance
// reasons we set the file size to 0.
// TODO: Does this really cost so much performance that it's worth losing this information? Dirs are usually just added once at startup...
addItem(full_filename, /*offet*/0, /*size*/0, /*isDir*/false, getFileCount());
// os::Printer::log("addItem:", full_filename.c_str(), ELL_DEBUG);
}
AAssetDir_close(dir);
}
} // end namespace io
} // end namespace irr
#endif // _IRR_COMPILE_ANDROID_ASSET_READER_
// Copyright (C) 2002-2011 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#ifdef _IRR_COMPILE_ANDROID_ASSET_READER_
#include "CAndroidAssetReader.h"
#include "CReadFile.h"
#include "coreutil.h"
#include "CAndroidAssetFileArchive.h"
#include "CIrrDeviceAndroid.h"
#include "os.h" // for logging (just keep it in even when not needed right now as it's used all the time)
#include <android_native_app_glue.h>
#include <android/native_activity.h>
#include <android/log.h>
namespace irr
{
namespace io
{
CAndroidAssetFileArchive::CAndroidAssetFileArchive(AAssetManager *assetManager, bool ignoreCase, bool ignorePaths)
: CFileList("/asset", ignoreCase, ignorePaths), AssetManager(assetManager)
{
}
CAndroidAssetFileArchive::~CAndroidAssetFileArchive()
{
}
//! get the archive type
E_FILE_ARCHIVE_TYPE CAndroidAssetFileArchive::getType() const
{
return EFAT_ANDROID_ASSET;
}
const IFileList* CAndroidAssetFileArchive::getFileList() const
{
// The assert_manager can not read directory names, so
// getFileList returns only files in folders which have been added.
return this;
}
//! opens a file by file name
IReadFile* CAndroidAssetFileArchive::createAndOpenFile(const io::path& filename)
{
CAndroidAssetReader *reader = new CAndroidAssetReader(AssetManager, filename);
if(reader->isOpen())
return reader;
reader->drop();
return NULL;
}
//! opens a file by index
IReadFile* CAndroidAssetFileArchive::createAndOpenFile(u32 index)
{
const io::path& filename(getFullFileName(index));
if ( filename.empty() )
return 0;
return createAndOpenFile(filename);
}
void CAndroidAssetFileArchive::addDirectoryToFileList(const io::path &dirname_)
{
io::path dirname(dirname_);
fschar_t lastChar = dirname.lastChar();
if ( lastChar == '/' || lastChar == '\\' )
dirname.erase(dirname.size()-1);
// os::Printer::log("addDirectoryToFileList:", dirname.c_str(), ELL_DEBUG);
if (findFile(dirname, true) >= 0 )
return; // was already added
AAssetDir *dir = AAssetManager_openDir(AssetManager, core::stringc(dirname).c_str());
if(!dir)
return;
// add directory itself
addItem(dirname, 0, 0, /*isDir*/true, getFileCount());
// add all files in folder.
// Note: AAssetDir_getNextFileName does not return directory names (neither does any other NDK function)
while(const char *filename = AAssetDir_getNextFileName(dir))
{
core::stringc full_filename= dirname=="" ? filename
: dirname+"/"+filename;
// We can't get the size without opening the file - so for performance
// reasons we set the file size to 0.
// TODO: Does this really cost so much performance that it's worth losing this information? Dirs are usually just added once at startup...
addItem(full_filename, /*offet*/0, /*size*/0, /*isDir*/false, getFileCount());
// os::Printer::log("addItem:", full_filename.c_str(), ELL_DEBUG);
}
AAssetDir_close(dir);
}
} // end namespace io
} // end namespace irr
#endif // _IRR_COMPILE_ANDROID_ASSET_READER_

View File

@ -1,64 +1,64 @@
// Copyright (C) 2012 Joerg Henrichs
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#pragma once
#ifdef _IRR_COMPILE_ANDROID_ASSET_READER_
#include "IReadFile.h"
#include "IFileArchive.h"
#include "CFileList.h"
#include <android/native_activity.h>
namespace irr
{
namespace io
{
/*!
Android asset file system written August 2012 by J.Henrichs (later reworked by others).
*/
class CAndroidAssetFileArchive : public virtual IFileArchive,
virtual CFileList
{
public:
//! constructor
CAndroidAssetFileArchive(AAssetManager *assetManager, bool ignoreCase, bool ignorePaths);
//! destructor
virtual ~CAndroidAssetFileArchive();
//! opens a file by file name
virtual IReadFile* createAndOpenFile(const io::path& filename);
//! opens a file by index
virtual IReadFile* createAndOpenFile(u32 index);
//! returns the list of files
virtual const IFileList* getFileList() const;
//! get the archive type
virtual E_FILE_ARCHIVE_TYPE getType() const;
//! Add a directory to read files from. Since the Android
//! API does not return names of directories, they need to
//! be added manually.
virtual void addDirectoryToFileList(const io::path &filename);
//! return the name (id) of the file Archive
const io::path& getArchiveName() const override {return Path;}
protected:
//! Android's asset manager
AAssetManager *AssetManager;
}; // CAndroidAssetFileArchive
} // end namespace io
} // end namespace irr
#endif // _IRR_COMPILE_ANDROID_ASSET_READER_
// Copyright (C) 2012 Joerg Henrichs
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#pragma once
#ifdef _IRR_COMPILE_ANDROID_ASSET_READER_
#include "IReadFile.h"
#include "IFileArchive.h"
#include "CFileList.h"
#include <android/native_activity.h>
namespace irr
{
namespace io
{
/*!
Android asset file system written August 2012 by J.Henrichs (later reworked by others).
*/
class CAndroidAssetFileArchive : public virtual IFileArchive,
virtual CFileList
{
public:
//! constructor
CAndroidAssetFileArchive(AAssetManager *assetManager, bool ignoreCase, bool ignorePaths);
//! destructor
virtual ~CAndroidAssetFileArchive();
//! opens a file by file name
virtual IReadFile* createAndOpenFile(const io::path& filename);
//! opens a file by index
virtual IReadFile* createAndOpenFile(u32 index);
//! returns the list of files
virtual const IFileList* getFileList() const;
//! get the archive type
virtual E_FILE_ARCHIVE_TYPE getType() const;
//! Add a directory to read files from. Since the Android
//! API does not return names of directories, they need to
//! be added manually.
virtual void addDirectoryToFileList(const io::path &filename);
//! return the name (id) of the file Archive
const io::path& getArchiveName() const override {return Path;}
protected:
//! Android's asset manager
AAssetManager *AssetManager;
}; // CAndroidAssetFileArchive
} // end namespace io
} // end namespace irr
#endif // _IRR_COMPILE_ANDROID_ASSET_READER_

View File

@ -1,72 +1,72 @@
// Copyright (C) 2002-2011 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#ifdef _IRR_COMPILE_ANDROID_ASSET_READER_
#include "CAndroidAssetReader.h"
#include "CReadFile.h"
#include "coreutil.h"
#include "CAndroidAssetReader.h"
#include "CIrrDeviceAndroid.h"
#include <android_native_app_glue.h>
#include <android/native_activity.h>
namespace irr
{
namespace io
{
CAndroidAssetReader::CAndroidAssetReader(AAssetManager *assetManager, const io::path &filename)
: AssetManager(assetManager), Filename(filename)
{
Asset = AAssetManager_open(AssetManager,
core::stringc(filename).c_str(),
AASSET_MODE_RANDOM);
}
CAndroidAssetReader::~CAndroidAssetReader()
{
if(Asset)
AAsset_close(Asset);
}
size_t CAndroidAssetReader::read(void* buffer, size_t sizeToRead)
{
int readBytes = AAsset_read(Asset, buffer, sizeToRead);
if ( readBytes >= 0 )
return size_t(readBytes);
return 0; // direct fd access is not possible (for example, if the asset is compressed).
}
bool CAndroidAssetReader::seek(long finalPos, bool relativeMovement)
{
off_t status = AAsset_seek(Asset, finalPos, relativeMovement ? SEEK_CUR : SEEK_SET);
return status+1;
}
long CAndroidAssetReader::getSize() const
{
return AAsset_getLength(Asset);
}
long CAndroidAssetReader::getPos() const
{
return AAsset_getLength(Asset) - AAsset_getRemainingLength(Asset);
}
const io::path& CAndroidAssetReader::getFileName() const
{
return Filename;
}
} // end namespace io
} // end namespace irr
#endif // _IRR_COMPILE_ANDROID_ASSET_READER_
// Copyright (C) 2002-2011 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#ifdef _IRR_COMPILE_ANDROID_ASSET_READER_
#include "CAndroidAssetReader.h"
#include "CReadFile.h"
#include "coreutil.h"
#include "CAndroidAssetReader.h"
#include "CIrrDeviceAndroid.h"
#include <android_native_app_glue.h>
#include <android/native_activity.h>
namespace irr
{
namespace io
{
CAndroidAssetReader::CAndroidAssetReader(AAssetManager *assetManager, const io::path &filename)
: AssetManager(assetManager), Filename(filename)
{
Asset = AAssetManager_open(AssetManager,
core::stringc(filename).c_str(),
AASSET_MODE_RANDOM);
}
CAndroidAssetReader::~CAndroidAssetReader()
{
if(Asset)
AAsset_close(Asset);
}
size_t CAndroidAssetReader::read(void* buffer, size_t sizeToRead)
{
int readBytes = AAsset_read(Asset, buffer, sizeToRead);
if ( readBytes >= 0 )
return size_t(readBytes);
return 0; // direct fd access is not possible (for example, if the asset is compressed).
}
bool CAndroidAssetReader::seek(long finalPos, bool relativeMovement)
{
off_t status = AAsset_seek(Asset, finalPos, relativeMovement ? SEEK_CUR : SEEK_SET);
return status+1;
}
long CAndroidAssetReader::getSize() const
{
return AAsset_getLength(Asset);
}
long CAndroidAssetReader::getPos() const
{
return AAsset_getLength(Asset) - AAsset_getRemainingLength(Asset);
}
const io::path& CAndroidAssetReader::getFileName() const
{
return Filename;
}
} // end namespace io
} // end namespace irr
#endif // _IRR_COMPILE_ANDROID_ASSET_READER_

View File

@ -1,69 +1,69 @@
// Copyright (C) 2012 Joerg Henrichs
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#pragma once
#ifdef _IRR_COMPILE_ANDROID_ASSET_READER_
#include "IReadFile.h"
struct AAssetManager;
struct AAsset;
struct ANativeActivity;
namespace irr
{
namespace io
{
class CAndroidAssetReader : public virtual IReadFile
{
public:
CAndroidAssetReader(AAssetManager *assetManager, const io::path &filename);
virtual ~CAndroidAssetReader();
//! Reads an amount of bytes from the file.
/** \param buffer Pointer to buffer where read bytes are written to.
\param sizeToRead Amount of bytes to read from the file.
\return How many bytes were read. */
virtual size_t read(void* buffer, size_t sizeToRead);
//! Changes position in file
/** \param finalPos Destination position in the file.
\param relativeMovement If set to true, the position in the file is
changed relative to current position. Otherwise the position is changed
from beginning of file.
\return True if successful, otherwise false. */
virtual bool seek(long finalPos, bool relativeMovement = false);
//! Get size of file.
/** \return Size of the file in bytes. */
virtual long getSize() const;
//! Get the current position in the file.
/** \return Current position in the file in bytes. */
virtual long getPos() const;
//! Get name of file.
/** \return File name as zero terminated character string. */
virtual const io::path& getFileName() const;
/** Return true if the file could be opened. */
bool isOpen() const { return Asset!=NULL; }
private:
//! Android's asset manager
AAssetManager *AssetManager;
// An asset, i.e. file
AAsset *Asset;
path Filename;
};
} // end namespace io
} // end namespace irr
#endif // _IRR_COMPILE_ANDROID_ASSET_READER_
// Copyright (C) 2012 Joerg Henrichs
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#pragma once
#ifdef _IRR_COMPILE_ANDROID_ASSET_READER_
#include "IReadFile.h"
struct AAssetManager;
struct AAsset;
struct ANativeActivity;
namespace irr
{
namespace io
{
class CAndroidAssetReader : public virtual IReadFile
{
public:
CAndroidAssetReader(AAssetManager *assetManager, const io::path &filename);
virtual ~CAndroidAssetReader();
//! Reads an amount of bytes from the file.
/** \param buffer Pointer to buffer where read bytes are written to.
\param sizeToRead Amount of bytes to read from the file.
\return How many bytes were read. */
virtual size_t read(void* buffer, size_t sizeToRead);
//! Changes position in file
/** \param finalPos Destination position in the file.
\param relativeMovement If set to true, the position in the file is
changed relative to current position. Otherwise the position is changed
from beginning of file.
\return True if successful, otherwise false. */
virtual bool seek(long finalPos, bool relativeMovement = false);
//! Get size of file.
/** \return Size of the file in bytes. */
virtual long getSize() const;
//! Get the current position in the file.
/** \return Current position in the file in bytes. */
virtual long getPos() const;
//! Get name of file.
/** \return File name as zero terminated character string. */
virtual const io::path& getFileName() const;
/** Return true if the file could be opened. */
bool isOpen() const { return Asset!=NULL; }
private:
//! Android's asset manager
AAssetManager *AssetManager;
// An asset, i.e. file
AAsset *Asset;
path Filename;
};
} // end namespace io
} // end namespace irr
#endif // _IRR_COMPILE_ANDROID_ASSET_READER_

File diff suppressed because it is too large Load Diff

View File

@ -1,101 +1,101 @@
// Copyright (C) 2002-2011 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#pragma once
#ifdef _IRR_COMPILE_WITH_ANDROID_DEVICE_
#include "CIrrDeviceStub.h"
#include "IrrlichtDevice.h"
#include "ICursorControl.h"
#include <android/sensor.h>
#include <android_native_app_glue.h>
namespace irr
{
class CIrrDeviceAndroid : public CIrrDeviceStub
{
public:
CIrrDeviceAndroid(const SIrrlichtCreationParameters& param);
virtual ~CIrrDeviceAndroid();
virtual bool run();
virtual void yield();
virtual void sleep(u32 timeMs, bool pauseTimer = false);
virtual void setWindowCaption(const wchar_t* text);
virtual bool isWindowActive() const;
virtual bool isWindowFocused() const;
virtual bool isWindowMinimized() const;
virtual void closeDevice();
virtual void setResizable(bool resize = false);
virtual void minimizeWindow();
virtual void maximizeWindow();
virtual void restoreWindow();
virtual core::position2di getWindowPosition();
virtual E_DEVICE_TYPE getType() const;
virtual bool activateAccelerometer(float updateInterval);
virtual bool deactivateAccelerometer();
virtual bool isAccelerometerActive();
virtual bool isAccelerometerAvailable();
virtual bool activateGyroscope(float updateInterval);
virtual bool deactivateGyroscope();
virtual bool isGyroscopeActive();
virtual bool isGyroscopeAvailable();
private:
static void handleAndroidCommand(android_app* app, int32_t cmd);
static s32 handleInput(android_app* app, AInputEvent* event);
void createDriver();
void createKeyMap();
video::SExposedVideoData& getExposedVideoData();
android_app* Android;
ASensorManager* SensorManager;
ASensorEventQueue* SensorEventQueue;
const ASensor* Accelerometer;
const ASensor* Gyroscope;
bool Focused;
bool Initialized;
bool Paused;
JNIEnv* JNIEnvAttachedToVM;
video::SExposedVideoData ExposedVideoData;
core::array<EKEY_CODE> KeyMap;
};
} // end namespace irr
#endif // _IRR_COMPILE_WITH_ANDROID_DEVICE_
// Copyright (C) 2002-2011 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#pragma once
#ifdef _IRR_COMPILE_WITH_ANDROID_DEVICE_
#include "CIrrDeviceStub.h"
#include "IrrlichtDevice.h"
#include "ICursorControl.h"
#include <android/sensor.h>
#include <android_native_app_glue.h>
namespace irr
{
class CIrrDeviceAndroid : public CIrrDeviceStub
{
public:
CIrrDeviceAndroid(const SIrrlichtCreationParameters& param);
virtual ~CIrrDeviceAndroid();
virtual bool run();
virtual void yield();
virtual void sleep(u32 timeMs, bool pauseTimer = false);
virtual void setWindowCaption(const wchar_t* text);
virtual bool isWindowActive() const;
virtual bool isWindowFocused() const;
virtual bool isWindowMinimized() const;
virtual void closeDevice();
virtual void setResizable(bool resize = false);
virtual void minimizeWindow();
virtual void maximizeWindow();
virtual void restoreWindow();
virtual core::position2di getWindowPosition();
virtual E_DEVICE_TYPE getType() const;
virtual bool activateAccelerometer(float updateInterval);
virtual bool deactivateAccelerometer();
virtual bool isAccelerometerActive();
virtual bool isAccelerometerAvailable();
virtual bool activateGyroscope(float updateInterval);
virtual bool deactivateGyroscope();
virtual bool isGyroscopeActive();
virtual bool isGyroscopeAvailable();
private:
static void handleAndroidCommand(android_app* app, int32_t cmd);
static s32 handleInput(android_app* app, AInputEvent* event);
void createDriver();
void createKeyMap();
video::SExposedVideoData& getExposedVideoData();
android_app* Android;
ASensorManager* SensorManager;
ASensorEventQueue* SensorEventQueue;
const ASensor* Accelerometer;
const ASensor* Gyroscope;
bool Focused;
bool Initialized;
bool Paused;
JNIEnv* JNIEnvAttachedToVM;
video::SExposedVideoData ExposedVideoData;
core::array<EKEY_CODE> KeyMap;
};
} // end namespace irr
#endif // _IRR_COMPILE_WITH_ANDROID_DEVICE_

View File

@ -1,63 +1,63 @@
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#include "CKeyEventWrapper.h"
#ifdef _IRR_COMPILE_WITH_ANDROID_DEVICE_
#include "os.h"
namespace irr
{
namespace jni
{
jclass CKeyEventWrapper::Class_KeyEvent = 0;
jmethodID CKeyEventWrapper::Method_constructor = 0;
jmethodID CKeyEventWrapper::Method_getUnicodeChar = 0;
CKeyEventWrapper::CKeyEventWrapper(JNIEnv* jniEnv, int action, int code)
: JniEnv(jniEnv), JniKeyEvent(0)
{
if ( JniEnv )
{
if (!Class_KeyEvent )
{
// Find java classes & functions on first call
os::Printer::log("CKeyEventWrapper first initialize", ELL_DEBUG);
jclass localClass = JniEnv->FindClass("android/view/KeyEvent");
if (localClass)
{
Class_KeyEvent = reinterpret_cast<jclass>(JniEnv->NewGlobalRef(localClass));
}
Method_constructor = JniEnv->GetMethodID(Class_KeyEvent, "<init>", "(II)V");
Method_getUnicodeChar = JniEnv->GetMethodID(Class_KeyEvent, "getUnicodeChar", "(I)I");
}
if ( Class_KeyEvent && Method_constructor )
{
JniKeyEvent = JniEnv->NewObject(Class_KeyEvent, Method_constructor, action, code);
}
else
{
os::Printer::log("CKeyEventWrapper didn't find JNI classes/methods", ELL_WARNING);
}
}
}
CKeyEventWrapper::~CKeyEventWrapper()
{
JniEnv->DeleteLocalRef(JniKeyEvent);
}
int CKeyEventWrapper::getUnicodeChar(int metaState)
{
return JniEnv->CallIntMethod(JniKeyEvent, Method_getUnicodeChar, metaState);
}
} // namespace jni
} // namespace irr
#endif // _IRR_COMPILE_WITH_ANDROID_DEVICE_
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#include "CKeyEventWrapper.h"
#ifdef _IRR_COMPILE_WITH_ANDROID_DEVICE_
#include "os.h"
namespace irr
{
namespace jni
{
jclass CKeyEventWrapper::Class_KeyEvent = 0;
jmethodID CKeyEventWrapper::Method_constructor = 0;
jmethodID CKeyEventWrapper::Method_getUnicodeChar = 0;
CKeyEventWrapper::CKeyEventWrapper(JNIEnv* jniEnv, int action, int code)
: JniEnv(jniEnv), JniKeyEvent(0)
{
if ( JniEnv )
{
if (!Class_KeyEvent )
{
// Find java classes & functions on first call
os::Printer::log("CKeyEventWrapper first initialize", ELL_DEBUG);
jclass localClass = JniEnv->FindClass("android/view/KeyEvent");
if (localClass)
{
Class_KeyEvent = reinterpret_cast<jclass>(JniEnv->NewGlobalRef(localClass));
}
Method_constructor = JniEnv->GetMethodID(Class_KeyEvent, "<init>", "(II)V");
Method_getUnicodeChar = JniEnv->GetMethodID(Class_KeyEvent, "getUnicodeChar", "(I)I");
}
if ( Class_KeyEvent && Method_constructor )
{
JniKeyEvent = JniEnv->NewObject(Class_KeyEvent, Method_constructor, action, code);
}
else
{
os::Printer::log("CKeyEventWrapper didn't find JNI classes/methods", ELL_WARNING);
}
}
}
CKeyEventWrapper::~CKeyEventWrapper()
{
JniEnv->DeleteLocalRef(JniKeyEvent);
}
int CKeyEventWrapper::getUnicodeChar(int metaState)
{
return JniEnv->CallIntMethod(JniKeyEvent, Method_getUnicodeChar, metaState);
}
} // namespace jni
} // namespace irr
#endif // _IRR_COMPILE_WITH_ANDROID_DEVICE_

View File

@ -1,39 +1,39 @@
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#pragma once
#ifdef _IRR_COMPILE_WITH_ANDROID_DEVICE_
#include <jni.h>
struct android_app;
namespace irr
{
namespace jni
{
//! Minimal JNI wrapper class around android.view.KeyEvent
//! NOTE: Only functions we actually use in the engine are wrapped
//! This is currently not written to support multithreading - meaning threads are not attached/detached to the Java VM (to be discussed)
class CKeyEventWrapper
{
public:
CKeyEventWrapper(JNIEnv* jniEnv, int action, int code);
~CKeyEventWrapper();
int getUnicodeChar(int metaState);
private:
static jclass Class_KeyEvent;
static jmethodID Method_getUnicodeChar;
static jmethodID Method_constructor;
JNIEnv* JniEnv;
jobject JniKeyEvent; // this object in java
};
} // namespace jni
} // namespace irr
#endif // _IRR_COMPILE_WITH_ANDROID_DEVICE_
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#pragma once
#ifdef _IRR_COMPILE_WITH_ANDROID_DEVICE_
#include <jni.h>
struct android_app;
namespace irr
{
namespace jni
{
//! Minimal JNI wrapper class around android.view.KeyEvent
//! NOTE: Only functions we actually use in the engine are wrapped
//! This is currently not written to support multithreading - meaning threads are not attached/detached to the Java VM (to be discussed)
class CKeyEventWrapper
{
public:
CKeyEventWrapper(JNIEnv* jniEnv, int action, int code);
~CKeyEventWrapper();
int getUnicodeChar(int metaState);
private:
static jclass Class_KeyEvent;
static jmethodID Method_getUnicodeChar;
static jmethodID Method_constructor;
JNIEnv* JniEnv;
jobject JniKeyEvent; // this object in java
};
} // namespace jni
} // namespace irr
#endif // _IRR_COMPILE_WITH_ANDROID_DEVICE_

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,181 +1,181 @@
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#pragma once
#include "IAnimatedMeshSceneNode.h"
#include "IAnimatedMesh.h"
#include "matrix4.h"
namespace irr
{
namespace scene
{
class IDummyTransformationSceneNode;
class CAnimatedMeshSceneNode : public IAnimatedMeshSceneNode
{
public:
//! constructor
CAnimatedMeshSceneNode(IAnimatedMesh* mesh, ISceneNode* parent, ISceneManager* mgr, s32 id,
const core::vector3df& position = core::vector3df(0,0,0),
const core::vector3df& rotation = core::vector3df(0,0,0),
const core::vector3df& scale = core::vector3df(1.0f, 1.0f, 1.0f));
//! destructor
virtual ~CAnimatedMeshSceneNode();
//! sets the current frame. from now on the animation is played from this frame.
void setCurrentFrame(f32 frame) override;
//! frame
void OnRegisterSceneNode() override;
//! OnAnimate() is called just before rendering the whole scene.
void OnAnimate(u32 timeMs) override;
//! renders the node.
void render() override;
//! returns the axis aligned bounding box of this node
const core::aabbox3d<f32>& getBoundingBox() const override;
//! sets the frames between the animation is looped.
//! the default is 0 - MaximalFrameCount of the mesh.
//! NOTE: setMesh will also change this value and set it to the full range of animations of the mesh
bool setFrameLoop(s32 begin, s32 end) override;
//! Sets looping mode which is on by default. If set to false,
//! animations will not be looped.
void setLoopMode(bool playAnimationLooped) override;
//! returns the current loop mode
bool getLoopMode() const override;
//! Sets a callback interface which will be called if an animation
//! playback has ended. Set this to 0 to disable the callback again.
void setAnimationEndCallback(IAnimationEndCallBack* callback=0) override;
//! sets the speed with which the animation is played
//! NOTE: setMesh will also change this value and set it to the default speed of the mesh
void setAnimationSpeed(f32 framesPerSecond) override;
//! gets the speed with which the animation is played
f32 getAnimationSpeed() const override;
//! returns the material based on the zero based index i. To get the amount
//! of materials used by this scene node, use getMaterialCount().
//! This function is needed for inserting the node into the scene hierarchy on a
//! optimal position for minimizing renderstate changes, but can also be used
//! to directly modify the material of a scene node.
video::SMaterial& getMaterial(u32 i) override;
//! returns amount of materials used by this scene node.
u32 getMaterialCount() const override;
//! Returns a pointer to a child node, which has the same transformation as
//! the corresponding joint, if the mesh in this scene node is a skinned mesh.
IBoneSceneNode* getJointNode(const c8* jointName) override;
//! same as getJointNode(const c8* jointName), but based on id
IBoneSceneNode* getJointNode(u32 jointID) override;
//! Gets joint count.
u32 getJointCount() const override;
//! Removes a child from this scene node.
//! Implemented here, to be able to remove the shadow properly, if there is one,
//! or to remove attached child.
bool removeChild(ISceneNode* child) override;
//! Returns the current displayed frame number.
f32 getFrameNr() const override;
//! Returns the current start frame number.
s32 getStartFrame() const override;
//! Returns the current end frame number.
s32 getEndFrame() const override;
//! Sets if the scene node should not copy the materials of the mesh but use them in a read only style.
/* In this way it is possible to change the materials a mesh causing all mesh scene nodes
referencing this mesh to change too. */
void setReadOnlyMaterials(bool readonly) override;
//! Returns if the scene node should not copy the materials of the mesh but use them in a read only style
bool isReadOnlyMaterials() const override;
//! Sets a new mesh
void setMesh(IAnimatedMesh* mesh) override;
//! Returns the current mesh
IAnimatedMesh* getMesh(void) override { return Mesh; }
//! Returns type of the scene node
ESCENE_NODE_TYPE getType() const override { return ESNT_ANIMATED_MESH; }
//! updates the absolute position based on the relative and the parents position
void updateAbsolutePosition() override;
//! Set the joint update mode (0-unused, 1-get joints only, 2-set joints only, 3-move and set)
void setJointMode(E_JOINT_UPDATE_ON_RENDER mode) override;
//! Sets the transition time in seconds (note: This needs to enable joints, and setJointmode maybe set to 2)
//! you must call animateJoints(), or the mesh will not animate
void setTransitionTime(f32 Time) override;
//! updates the joint positions of this mesh
void animateJoints(bool CalculateAbsolutePositions=true) override;
//! render mesh ignoring its transformation. Used with ragdolls. (culling is unaffected)
void setRenderFromIdentity( bool On ) override;
//! Creates a clone of this scene node and its children.
/** \param newParent An optional new parent.
\param newManager An optional new scene manager.
\return The newly created clone of this node. */
ISceneNode* clone(ISceneNode* newParent=0, ISceneManager* newManager=0) override;
private:
//! Get a static mesh for the current frame of this animated mesh
IMesh* getMeshForCurrentFrame();
void buildFrameNr(u32 timeMs);
void checkJoints();
void beginTransition();
core::array<video::SMaterial> Materials;
core::aabbox3d<f32> Box;
IAnimatedMesh* Mesh;
s32 StartFrame;
s32 EndFrame;
f32 FramesPerSecond;
f32 CurrentFrameNr;
u32 LastTimeMs;
u32 TransitionTime; //Transition time in millisecs
f32 Transiting; //is mesh transiting (plus cache of TransitionTime)
f32 TransitingBlend; //0-1, calculated on buildFrameNr
//0-unused, 1-get joints only, 2-set joints only, 3-move and set
E_JOINT_UPDATE_ON_RENDER JointMode;
bool JointsUsed;
bool Looping;
bool ReadOnlyMaterials;
bool RenderFromIdentity;
IAnimationEndCallBack* LoopCallBack;
s32 PassCount;
core::array<IBoneSceneNode* > JointChildSceneNodes;
core::array<core::matrix4> PretransitingSave;
};
} // end namespace scene
} // end namespace irr
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#pragma once
#include "IAnimatedMeshSceneNode.h"
#include "IAnimatedMesh.h"
#include "matrix4.h"
namespace irr
{
namespace scene
{
class IDummyTransformationSceneNode;
class CAnimatedMeshSceneNode : public IAnimatedMeshSceneNode
{
public:
//! constructor
CAnimatedMeshSceneNode(IAnimatedMesh* mesh, ISceneNode* parent, ISceneManager* mgr, s32 id,
const core::vector3df& position = core::vector3df(0,0,0),
const core::vector3df& rotation = core::vector3df(0,0,0),
const core::vector3df& scale = core::vector3df(1.0f, 1.0f, 1.0f));
//! destructor
virtual ~CAnimatedMeshSceneNode();
//! sets the current frame. from now on the animation is played from this frame.
void setCurrentFrame(f32 frame) override;
//! frame
void OnRegisterSceneNode() override;
//! OnAnimate() is called just before rendering the whole scene.
void OnAnimate(u32 timeMs) override;
//! renders the node.
void render() override;
//! returns the axis aligned bounding box of this node
const core::aabbox3d<f32>& getBoundingBox() const override;
//! sets the frames between the animation is looped.
//! the default is 0 - MaximalFrameCount of the mesh.
//! NOTE: setMesh will also change this value and set it to the full range of animations of the mesh
bool setFrameLoop(s32 begin, s32 end) override;
//! Sets looping mode which is on by default. If set to false,
//! animations will not be looped.
void setLoopMode(bool playAnimationLooped) override;
//! returns the current loop mode
bool getLoopMode() const override;
//! Sets a callback interface which will be called if an animation
//! playback has ended. Set this to 0 to disable the callback again.
void setAnimationEndCallback(IAnimationEndCallBack* callback=0) override;
//! sets the speed with which the animation is played
//! NOTE: setMesh will also change this value and set it to the default speed of the mesh
void setAnimationSpeed(f32 framesPerSecond) override;
//! gets the speed with which the animation is played
f32 getAnimationSpeed() const override;
//! returns the material based on the zero based index i. To get the amount
//! of materials used by this scene node, use getMaterialCount().
//! This function is needed for inserting the node into the scene hierarchy on a
//! optimal position for minimizing renderstate changes, but can also be used
//! to directly modify the material of a scene node.
video::SMaterial& getMaterial(u32 i) override;
//! returns amount of materials used by this scene node.
u32 getMaterialCount() const override;
//! Returns a pointer to a child node, which has the same transformation as
//! the corresponding joint, if the mesh in this scene node is a skinned mesh.
IBoneSceneNode* getJointNode(const c8* jointName) override;
//! same as getJointNode(const c8* jointName), but based on id
IBoneSceneNode* getJointNode(u32 jointID) override;
//! Gets joint count.
u32 getJointCount() const override;
//! Removes a child from this scene node.
//! Implemented here, to be able to remove the shadow properly, if there is one,
//! or to remove attached child.
bool removeChild(ISceneNode* child) override;
//! Returns the current displayed frame number.
f32 getFrameNr() const override;
//! Returns the current start frame number.
s32 getStartFrame() const override;
//! Returns the current end frame number.
s32 getEndFrame() const override;
//! Sets if the scene node should not copy the materials of the mesh but use them in a read only style.
/* In this way it is possible to change the materials a mesh causing all mesh scene nodes
referencing this mesh to change too. */
void setReadOnlyMaterials(bool readonly) override;
//! Returns if the scene node should not copy the materials of the mesh but use them in a read only style
bool isReadOnlyMaterials() const override;
//! Sets a new mesh
void setMesh(IAnimatedMesh* mesh) override;
//! Returns the current mesh
IAnimatedMesh* getMesh(void) override { return Mesh; }
//! Returns type of the scene node
ESCENE_NODE_TYPE getType() const override { return ESNT_ANIMATED_MESH; }
//! updates the absolute position based on the relative and the parents position
void updateAbsolutePosition() override;
//! Set the joint update mode (0-unused, 1-get joints only, 2-set joints only, 3-move and set)
void setJointMode(E_JOINT_UPDATE_ON_RENDER mode) override;
//! Sets the transition time in seconds (note: This needs to enable joints, and setJointmode maybe set to 2)
//! you must call animateJoints(), or the mesh will not animate
void setTransitionTime(f32 Time) override;
//! updates the joint positions of this mesh
void animateJoints(bool CalculateAbsolutePositions=true) override;
//! render mesh ignoring its transformation. Used with ragdolls. (culling is unaffected)
void setRenderFromIdentity( bool On ) override;
//! Creates a clone of this scene node and its children.
/** \param newParent An optional new parent.
\param newManager An optional new scene manager.
\return The newly created clone of this node. */
ISceneNode* clone(ISceneNode* newParent=0, ISceneManager* newManager=0) override;
private:
//! Get a static mesh for the current frame of this animated mesh
IMesh* getMeshForCurrentFrame();
void buildFrameNr(u32 timeMs);
void checkJoints();
void beginTransition();
core::array<video::SMaterial> Materials;
core::aabbox3d<f32> Box;
IAnimatedMesh* Mesh;
s32 StartFrame;
s32 EndFrame;
f32 FramesPerSecond;
f32 CurrentFrameNr;
u32 LastTimeMs;
u32 TransitionTime; //Transition time in millisecs
f32 Transiting; //is mesh transiting (plus cache of TransitionTime)
f32 TransitingBlend; //0-1, calculated on buildFrameNr
//0-unused, 1-get joints only, 2-set joints only, 3-move and set
E_JOINT_UPDATE_ON_RENDER JointMode;
bool JointsUsed;
bool Looping;
bool ReadOnlyMaterials;
bool RenderFromIdentity;
IAnimationEndCallBack* LoopCallBack;
s32 PassCount;
core::array<IBoneSceneNode* > JointChildSceneNodes;
core::array<core::matrix4> PretransitingSave;
};
} // end namespace scene
} // end namespace irr

View File

@ -1,162 +1,162 @@
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#include "CAttributes.h"
#include "fast_atof.h"
#include "ITexture.h"
#include "IVideoDriver.h"
namespace irr
{
namespace io
{
/*
Basic types, check documentation in IAttribute.h to see how they generally work.
*/
// Attribute implemented for boolean values
class CBoolAttribute : public IAttribute
{
public:
CBoolAttribute(const char* name, bool value)
{
Name = name;
setBool(value);
}
s32 getInt() const override
{
return BoolValue ? 1 : 0;
}
f32 getFloat() const override
{
return BoolValue ? 1.0f : 0.0f;
}
bool getBool() const override
{
return BoolValue;
}
void setInt(s32 intValue) override
{
BoolValue = (intValue != 0);
}
void setFloat(f32 floatValue) override
{
BoolValue = (floatValue != 0);
}
void setBool(bool boolValue) override
{
BoolValue = boolValue;
}
E_ATTRIBUTE_TYPE getType() const override
{
return EAT_BOOL;
}
const wchar_t* getTypeString() const override
{
return L"bool";
}
bool BoolValue;
};
// Attribute implemented for integers
class CIntAttribute : public IAttribute
{
public:
CIntAttribute(const char* name, s32 value)
{
Name = name;
setInt(value);
}
s32 getInt() const override
{
return Value;
}
f32 getFloat() const override
{
return (f32)Value;
}
void setInt(s32 intValue) override
{
Value = intValue;
}
void setFloat(f32 floatValue) override
{
Value = (s32)floatValue;
};
E_ATTRIBUTE_TYPE getType() const override
{
return EAT_INT;
}
const wchar_t* getTypeString() const override
{
return L"int";
}
s32 Value;
};
// Attribute implemented for floats
class CFloatAttribute : public IAttribute
{
public:
CFloatAttribute(const char* name, f32 value)
{
Name = name;
setFloat(value);
}
s32 getInt() const override
{
return (s32)Value;
}
f32 getFloat() const override
{
return Value;
}
void setInt(s32 intValue) override
{
Value = (f32)intValue;
}
void setFloat(f32 floatValue) override
{
Value = floatValue;
}
E_ATTRIBUTE_TYPE getType() const override
{
return EAT_FLOAT;
}
const wchar_t* getTypeString() const override
{
return L"float";
}
f32 Value;
};
} // end namespace io
} // end namespace irr
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#include "CAttributes.h"
#include "fast_atof.h"
#include "ITexture.h"
#include "IVideoDriver.h"
namespace irr
{
namespace io
{
/*
Basic types, check documentation in IAttribute.h to see how they generally work.
*/
// Attribute implemented for boolean values
class CBoolAttribute : public IAttribute
{
public:
CBoolAttribute(const char* name, bool value)
{
Name = name;
setBool(value);
}
s32 getInt() const override
{
return BoolValue ? 1 : 0;
}
f32 getFloat() const override
{
return BoolValue ? 1.0f : 0.0f;
}
bool getBool() const override
{
return BoolValue;
}
void setInt(s32 intValue) override
{
BoolValue = (intValue != 0);
}
void setFloat(f32 floatValue) override
{
BoolValue = (floatValue != 0);
}
void setBool(bool boolValue) override
{
BoolValue = boolValue;
}
E_ATTRIBUTE_TYPE getType() const override
{
return EAT_BOOL;
}
const wchar_t* getTypeString() const override
{
return L"bool";
}
bool BoolValue;
};
// Attribute implemented for integers
class CIntAttribute : public IAttribute
{
public:
CIntAttribute(const char* name, s32 value)
{
Name = name;
setInt(value);
}
s32 getInt() const override
{
return Value;
}
f32 getFloat() const override
{
return (f32)Value;
}
void setInt(s32 intValue) override
{
Value = intValue;
}
void setFloat(f32 floatValue) override
{
Value = (s32)floatValue;
};
E_ATTRIBUTE_TYPE getType() const override
{
return EAT_INT;
}
const wchar_t* getTypeString() const override
{
return L"int";
}
s32 Value;
};
// Attribute implemented for floats
class CFloatAttribute : public IAttribute
{
public:
CFloatAttribute(const char* name, f32 value)
{
Name = name;
setFloat(value);
}
s32 getInt() const override
{
return (s32)Value;
}
f32 getFloat() const override
{
return Value;
}
void setInt(s32 intValue) override
{
Value = (f32)intValue;
}
void setFloat(f32 floatValue) override
{
Value = floatValue;
}
E_ATTRIBUTE_TYPE getType() const override
{
return EAT_FLOAT;
}
const wchar_t* getTypeString() const override
{
return L"float";
}
f32 Value;
};
} // end namespace io
} // end namespace irr

View File

@ -1,274 +1,274 @@
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#include "CAttributes.h"
#include "CAttributeImpl.h"
#include "ITexture.h"
#include "IVideoDriver.h"
namespace irr
{
namespace io
{
CAttributes::CAttributes(video::IVideoDriver* driver)
: Driver(driver)
{
#ifdef _DEBUG
setDebugName("CAttributes");
#endif
if (Driver)
Driver->grab();
}
CAttributes::~CAttributes()
{
clear();
if (Driver)
Driver->drop();
}
//! Removes all attributes
void CAttributes::clear()
{
for (u32 i=0; i<Attributes.size(); ++i)
Attributes[i]->drop();
Attributes.clear();
}
//! Returns attribute index from name, -1 if not found
s32 CAttributes::findAttribute(const c8* attributeName) const
{
for (u32 i=0; i<Attributes.size(); ++i)
if (Attributes[i]->Name == attributeName)
return i;
return -1;
}
IAttribute* CAttributes::getAttributeP(const c8* attributeName) const
{
for (u32 i=0; i<Attributes.size(); ++i)
if (Attributes[i]->Name == attributeName)
return Attributes[i];
return 0;
}
//! Sets a attribute as boolean value
void CAttributes::setAttribute(const c8* attributeName, bool value)
{
IAttribute* att = getAttributeP(attributeName);
if (att)
att->setBool(value);
else
{
Attributes.push_back(new CBoolAttribute(attributeName, value));
}
}
//! Gets a attribute as boolean value
//! \param attributeName: Name of the attribute to get.
//! \return Returns value of the attribute previously set by setAttribute() as bool
//! or 0 if attribute is not set.
bool CAttributes::getAttributeAsBool(const c8* attributeName, bool defaultNotFound) const
{
const IAttribute* att = getAttributeP(attributeName);
if (att)
return att->getBool();
else
return defaultNotFound;
}
//! Sets a attribute as integer value
void CAttributes::setAttribute(const c8* attributeName, s32 value)
{
IAttribute* att = getAttributeP(attributeName);
if (att)
att->setInt(value);
else
{
Attributes.push_back(new CIntAttribute(attributeName, value));
}
}
//! Gets a attribute as integer value
//! \param attributeName: Name of the attribute to get.
//! \return Returns value of the attribute previously set by setAttribute() as integer
//! or 0 if attribute is not set.
s32 CAttributes::getAttributeAsInt(const c8* attributeName, irr::s32 defaultNotFound) const
{
const IAttribute* att = getAttributeP(attributeName);
if (att)
return att->getInt();
else
return defaultNotFound;
}
//! Sets a attribute as float value
void CAttributes::setAttribute(const c8* attributeName, f32 value)
{
IAttribute* att = getAttributeP(attributeName);
if (att)
att->setFloat(value);
else
Attributes.push_back(new CFloatAttribute(attributeName, value));
}
//! Gets a attribute as integer value
//! \param attributeName: Name of the attribute to get.
//! \return Returns value of the attribute previously set by setAttribute() as float value
//! or 0 if attribute is not set.
f32 CAttributes::getAttributeAsFloat(const c8* attributeName, irr::f32 defaultNotFound) const
{
const IAttribute* att = getAttributeP(attributeName);
if (att)
return att->getFloat();
return defaultNotFound;
}
//! Returns amount of string attributes set in this scene manager.
u32 CAttributes::getAttributeCount() const
{
return Attributes.size();
}
//! Returns string attribute name by index.
//! \param index: Index value, must be between 0 and getStringAttributeCount()-1.
const c8* CAttributes::getAttributeName(s32 index) const
{
if ((u32)index >= Attributes.size())
return 0;
return Attributes[index]->Name.c_str();
}
//! Returns the type of an attribute
E_ATTRIBUTE_TYPE CAttributes::getAttributeType(const c8* attributeName) const
{
E_ATTRIBUTE_TYPE ret = EAT_UNKNOWN;
const IAttribute* att = getAttributeP(attributeName);
if (att)
ret = att->getType();
return ret;
}
//! Returns attribute type by index.
//! \param index: Index value, must be between 0 and getAttributeCount()-1.
E_ATTRIBUTE_TYPE CAttributes::getAttributeType(s32 index) const
{
if ((u32)index >= Attributes.size())
return EAT_UNKNOWN;
return Attributes[index]->getType();
}
//! Returns the type of an attribute
const wchar_t* CAttributes::getAttributeTypeString(const c8* attributeName, const wchar_t* defaultNotFound) const
{
const IAttribute* att = getAttributeP(attributeName);
if (att)
return att->getTypeString();
else
return defaultNotFound;
}
//! Returns attribute type string by index.
//! \param index: Index value, must be between 0 and getAttributeCount()-1.
const wchar_t* CAttributes::getAttributeTypeString(s32 index, const wchar_t* defaultNotFound) const
{
if ((u32)index >= Attributes.size())
return defaultNotFound;
return Attributes[index]->getTypeString();
}
//! Gets an attribute as integer value
//! \param index: Index value, must be between 0 and getAttributeCount()-1.
s32 CAttributes::getAttributeAsInt(s32 index) const
{
if ((u32)index < Attributes.size())
return Attributes[index]->getInt();
else
return 0;
}
//! Gets an attribute as float value
//! \param index: Index value, must be between 0 and getAttributeCount()-1.
f32 CAttributes::getAttributeAsFloat(s32 index) const
{
if ((u32)index < Attributes.size())
return Attributes[index]->getFloat();
else
return 0.f;
}
//! Gets an attribute as boolean value
//! \param index: Index value, must be between 0 and getAttributeCount()-1.
bool CAttributes::getAttributeAsBool(s32 index) const
{
bool ret = false;
if ((u32)index < Attributes.size())
ret = Attributes[index]->getBool();
return ret;
}
//! Adds an attribute as integer
void CAttributes::addInt(const c8* attributeName, s32 value)
{
Attributes.push_back(new CIntAttribute(attributeName, value));
}
//! Adds an attribute as float
void CAttributes::addFloat(const c8* attributeName, f32 value)
{
Attributes.push_back(new CFloatAttribute(attributeName, value));
}
//! Adds an attribute as bool
void CAttributes::addBool(const c8* attributeName, bool value)
{
Attributes.push_back(new CBoolAttribute(attributeName, value));
}
//! Returns if an attribute with a name exists
bool CAttributes::existsAttribute(const c8* attributeName) const
{
return getAttributeP(attributeName) != 0;
}
//! Sets an attribute as boolean value
void CAttributes::setAttribute(s32 index, bool value)
{
if ((u32)index < Attributes.size())
Attributes[index]->setBool(value);
}
//! Sets an attribute as integer value
void CAttributes::setAttribute(s32 index, s32 value)
{
if ((u32)index < Attributes.size())
Attributes[index]->setInt(value);
}
//! Sets a attribute as float value
void CAttributes::setAttribute(s32 index, f32 value)
{
if ((u32)index < Attributes.size())
Attributes[index]->setFloat(value);
}
} // end namespace io
} // end namespace irr
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#include "CAttributes.h"
#include "CAttributeImpl.h"
#include "ITexture.h"
#include "IVideoDriver.h"
namespace irr
{
namespace io
{
CAttributes::CAttributes(video::IVideoDriver* driver)
: Driver(driver)
{
#ifdef _DEBUG
setDebugName("CAttributes");
#endif
if (Driver)
Driver->grab();
}
CAttributes::~CAttributes()
{
clear();
if (Driver)
Driver->drop();
}
//! Removes all attributes
void CAttributes::clear()
{
for (u32 i=0; i<Attributes.size(); ++i)
Attributes[i]->drop();
Attributes.clear();
}
//! Returns attribute index from name, -1 if not found
s32 CAttributes::findAttribute(const c8* attributeName) const
{
for (u32 i=0; i<Attributes.size(); ++i)
if (Attributes[i]->Name == attributeName)
return i;
return -1;
}
IAttribute* CAttributes::getAttributeP(const c8* attributeName) const
{
for (u32 i=0; i<Attributes.size(); ++i)
if (Attributes[i]->Name == attributeName)
return Attributes[i];
return 0;
}
//! Sets a attribute as boolean value
void CAttributes::setAttribute(const c8* attributeName, bool value)
{
IAttribute* att = getAttributeP(attributeName);
if (att)
att->setBool(value);
else
{
Attributes.push_back(new CBoolAttribute(attributeName, value));
}
}
//! Gets a attribute as boolean value
//! \param attributeName: Name of the attribute to get.
//! \return Returns value of the attribute previously set by setAttribute() as bool
//! or 0 if attribute is not set.
bool CAttributes::getAttributeAsBool(const c8* attributeName, bool defaultNotFound) const
{
const IAttribute* att = getAttributeP(attributeName);
if (att)
return att->getBool();
else
return defaultNotFound;
}
//! Sets a attribute as integer value
void CAttributes::setAttribute(const c8* attributeName, s32 value)
{
IAttribute* att = getAttributeP(attributeName);
if (att)
att->setInt(value);
else
{
Attributes.push_back(new CIntAttribute(attributeName, value));
}
}
//! Gets a attribute as integer value
//! \param attributeName: Name of the attribute to get.
//! \return Returns value of the attribute previously set by setAttribute() as integer
//! or 0 if attribute is not set.
s32 CAttributes::getAttributeAsInt(const c8* attributeName, irr::s32 defaultNotFound) const
{
const IAttribute* att = getAttributeP(attributeName);
if (att)
return att->getInt();
else
return defaultNotFound;
}
//! Sets a attribute as float value
void CAttributes::setAttribute(const c8* attributeName, f32 value)
{
IAttribute* att = getAttributeP(attributeName);
if (att)
att->setFloat(value);
else
Attributes.push_back(new CFloatAttribute(attributeName, value));
}
//! Gets a attribute as integer value
//! \param attributeName: Name of the attribute to get.
//! \return Returns value of the attribute previously set by setAttribute() as float value
//! or 0 if attribute is not set.
f32 CAttributes::getAttributeAsFloat(const c8* attributeName, irr::f32 defaultNotFound) const
{
const IAttribute* att = getAttributeP(attributeName);
if (att)
return att->getFloat();
return defaultNotFound;
}
//! Returns amount of string attributes set in this scene manager.
u32 CAttributes::getAttributeCount() const
{
return Attributes.size();
}
//! Returns string attribute name by index.
//! \param index: Index value, must be between 0 and getStringAttributeCount()-1.
const c8* CAttributes::getAttributeName(s32 index) const
{
if ((u32)index >= Attributes.size())
return 0;
return Attributes[index]->Name.c_str();
}
//! Returns the type of an attribute
E_ATTRIBUTE_TYPE CAttributes::getAttributeType(const c8* attributeName) const
{
E_ATTRIBUTE_TYPE ret = EAT_UNKNOWN;
const IAttribute* att = getAttributeP(attributeName);
if (att)
ret = att->getType();
return ret;
}
//! Returns attribute type by index.
//! \param index: Index value, must be between 0 and getAttributeCount()-1.
E_ATTRIBUTE_TYPE CAttributes::getAttributeType(s32 index) const
{
if ((u32)index >= Attributes.size())
return EAT_UNKNOWN;
return Attributes[index]->getType();
}
//! Returns the type of an attribute
const wchar_t* CAttributes::getAttributeTypeString(const c8* attributeName, const wchar_t* defaultNotFound) const
{
const IAttribute* att = getAttributeP(attributeName);
if (att)
return att->getTypeString();
else
return defaultNotFound;
}
//! Returns attribute type string by index.
//! \param index: Index value, must be between 0 and getAttributeCount()-1.
const wchar_t* CAttributes::getAttributeTypeString(s32 index, const wchar_t* defaultNotFound) const
{
if ((u32)index >= Attributes.size())
return defaultNotFound;
return Attributes[index]->getTypeString();
}
//! Gets an attribute as integer value
//! \param index: Index value, must be between 0 and getAttributeCount()-1.
s32 CAttributes::getAttributeAsInt(s32 index) const
{
if ((u32)index < Attributes.size())
return Attributes[index]->getInt();
else
return 0;
}
//! Gets an attribute as float value
//! \param index: Index value, must be between 0 and getAttributeCount()-1.
f32 CAttributes::getAttributeAsFloat(s32 index) const
{
if ((u32)index < Attributes.size())
return Attributes[index]->getFloat();
else
return 0.f;
}
//! Gets an attribute as boolean value
//! \param index: Index value, must be between 0 and getAttributeCount()-1.
bool CAttributes::getAttributeAsBool(s32 index) const
{
bool ret = false;
if ((u32)index < Attributes.size())
ret = Attributes[index]->getBool();
return ret;
}
//! Adds an attribute as integer
void CAttributes::addInt(const c8* attributeName, s32 value)
{
Attributes.push_back(new CIntAttribute(attributeName, value));
}
//! Adds an attribute as float
void CAttributes::addFloat(const c8* attributeName, f32 value)
{
Attributes.push_back(new CFloatAttribute(attributeName, value));
}
//! Adds an attribute as bool
void CAttributes::addBool(const c8* attributeName, bool value)
{
Attributes.push_back(new CBoolAttribute(attributeName, value));
}
//! Returns if an attribute with a name exists
bool CAttributes::existsAttribute(const c8* attributeName) const
{
return getAttributeP(attributeName) != 0;
}
//! Sets an attribute as boolean value
void CAttributes::setAttribute(s32 index, bool value)
{
if ((u32)index < Attributes.size())
Attributes[index]->setBool(value);
}
//! Sets an attribute as integer value
void CAttributes::setAttribute(s32 index, s32 value)
{
if ((u32)index < Attributes.size())
Attributes[index]->setInt(value);
}
//! Sets a attribute as float value
void CAttributes::setAttribute(s32 index, f32 value)
{
if ((u32)index < Attributes.size())
Attributes[index]->setFloat(value);
}
} // end namespace io
} // end namespace irr

View File

@ -1,148 +1,148 @@
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#pragma once
#include "IAttributes.h"
#include "IAttribute.h"
namespace irr
{
namespace video
{
class ITexture;
class IVideoDriver;
}
namespace io
{
//! Implementation of the IAttributes interface
class CAttributes : public IAttributes
{
public:
CAttributes(video::IVideoDriver* driver=0);
~CAttributes();
//! Returns amount of attributes in this collection of attributes.
u32 getAttributeCount() const override;
//! Returns attribute name by index.
//! \param index: Index value, must be between 0 and getAttributeCount()-1.
const c8* getAttributeName(s32 index) const override;
//! Returns the type of an attribute
//! \param attributeName: Name for the attribute
E_ATTRIBUTE_TYPE getAttributeType(const c8* attributeName) const override;
//! Returns attribute type by index.
//! \param index: Index value, must be between 0 and getAttributeCount()-1.
E_ATTRIBUTE_TYPE getAttributeType(s32 index) const override;
//! Returns the type string of the attribute
//! \param attributeName: String for the attribute type
//! \param defaultNotFound Value returned when attributeName was not found
const wchar_t* getAttributeTypeString(const c8* attributeName, const wchar_t* defaultNotFound = L"unknown") const override;
//! Returns the type string of the attribute by index.
//! \param index: Index value, must be between 0 and getAttributeCount()-1.
const wchar_t* getAttributeTypeString(s32 index, const wchar_t* defaultNotFound = L"unknown") const override;
//! Returns if an attribute with a name exists
bool existsAttribute(const c8* attributeName) const override;
//! Returns attribute index from name, -1 if not found
s32 findAttribute(const c8* attributeName) const override;
//! Removes all attributes
void clear() override;
/*
Integer Attribute
*/
//! Adds an attribute as integer
void addInt(const c8* attributeName, s32 value) override;
//! Sets an attribute as integer value
void setAttribute(const c8* attributeName, s32 value) override;
//! Gets an attribute as integer value
//! \param attributeName: Name of the attribute to get.
//! \param defaultNotFound Value returned when attributeName was not found
//! \return Returns value of the attribute previously set by setAttribute()
s32 getAttributeAsInt(const c8* attributeName, irr::s32 defaultNotFound=0) const override;
//! Gets an attribute as integer value
//! \param index: Index value, must be between 0 and getAttributeCount()-1.
s32 getAttributeAsInt(s32 index) const override;
//! Sets an attribute as integer value
void setAttribute(s32 index, s32 value) override;
/*
Float Attribute
*/
//! Adds an attribute as float
void addFloat(const c8* attributeName, f32 value) override;
//! Sets a attribute as float value
void setAttribute(const c8* attributeName, f32 value) override;
//! Gets an attribute as float value
//! \param attributeName: Name of the attribute to get.
//! \param defaultNotFound Value returned when attributeName was not found
//! \return Returns value of the attribute previously set by setAttribute()
f32 getAttributeAsFloat(const c8* attributeName, irr::f32 defaultNotFound=0.f) const override;
//! Gets an attribute as float value
//! \param index: Index value, must be between 0 and getAttributeCount()-1.
f32 getAttributeAsFloat(s32 index) const override;
//! Sets an attribute as float value
void setAttribute(s32 index, f32 value) override;
/*
Bool Attribute
*/
//! Adds an attribute as bool
void addBool(const c8* attributeName, bool value) override;
//! Sets an attribute as boolean value
void setAttribute(const c8* attributeName, bool value) override;
//! Gets an attribute as boolean value
//! \param attributeName: Name of the attribute to get.
//! \param defaultNotFound Value returned when attributeName was not found
//! \return Returns value of the attribute previously set by setAttribute()
bool getAttributeAsBool(const c8* attributeName, bool defaultNotFound=false) const override;
//! Gets an attribute as boolean value
//! \param index: Index value, must be between 0 and getAttributeCount()-1.
bool getAttributeAsBool(s32 index) const override;
//! Sets an attribute as boolean value
void setAttribute(s32 index, bool value) override;
protected:
core::array<IAttribute*> Attributes;
IAttribute* getAttributeP(const c8* attributeName) const;
video::IVideoDriver* Driver;
};
} // end namespace io
} // end namespace irr
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#pragma once
#include "IAttributes.h"
#include "IAttribute.h"
namespace irr
{
namespace video
{
class ITexture;
class IVideoDriver;
}
namespace io
{
//! Implementation of the IAttributes interface
class CAttributes : public IAttributes
{
public:
CAttributes(video::IVideoDriver* driver=0);
~CAttributes();
//! Returns amount of attributes in this collection of attributes.
u32 getAttributeCount() const override;
//! Returns attribute name by index.
//! \param index: Index value, must be between 0 and getAttributeCount()-1.
const c8* getAttributeName(s32 index) const override;
//! Returns the type of an attribute
//! \param attributeName: Name for the attribute
E_ATTRIBUTE_TYPE getAttributeType(const c8* attributeName) const override;
//! Returns attribute type by index.
//! \param index: Index value, must be between 0 and getAttributeCount()-1.
E_ATTRIBUTE_TYPE getAttributeType(s32 index) const override;
//! Returns the type string of the attribute
//! \param attributeName: String for the attribute type
//! \param defaultNotFound Value returned when attributeName was not found
const wchar_t* getAttributeTypeString(const c8* attributeName, const wchar_t* defaultNotFound = L"unknown") const override;
//! Returns the type string of the attribute by index.
//! \param index: Index value, must be between 0 and getAttributeCount()-1.
const wchar_t* getAttributeTypeString(s32 index, const wchar_t* defaultNotFound = L"unknown") const override;
//! Returns if an attribute with a name exists
bool existsAttribute(const c8* attributeName) const override;
//! Returns attribute index from name, -1 if not found
s32 findAttribute(const c8* attributeName) const override;
//! Removes all attributes
void clear() override;
/*
Integer Attribute
*/
//! Adds an attribute as integer
void addInt(const c8* attributeName, s32 value) override;
//! Sets an attribute as integer value
void setAttribute(const c8* attributeName, s32 value) override;
//! Gets an attribute as integer value
//! \param attributeName: Name of the attribute to get.
//! \param defaultNotFound Value returned when attributeName was not found
//! \return Returns value of the attribute previously set by setAttribute()
s32 getAttributeAsInt(const c8* attributeName, irr::s32 defaultNotFound=0) const override;
//! Gets an attribute as integer value
//! \param index: Index value, must be between 0 and getAttributeCount()-1.
s32 getAttributeAsInt(s32 index) const override;
//! Sets an attribute as integer value
void setAttribute(s32 index, s32 value) override;
/*
Float Attribute
*/
//! Adds an attribute as float
void addFloat(const c8* attributeName, f32 value) override;
//! Sets a attribute as float value
void setAttribute(const c8* attributeName, f32 value) override;
//! Gets an attribute as float value
//! \param attributeName: Name of the attribute to get.
//! \param defaultNotFound Value returned when attributeName was not found
//! \return Returns value of the attribute previously set by setAttribute()
f32 getAttributeAsFloat(const c8* attributeName, irr::f32 defaultNotFound=0.f) const override;
//! Gets an attribute as float value
//! \param index: Index value, must be between 0 and getAttributeCount()-1.
f32 getAttributeAsFloat(s32 index) const override;
//! Sets an attribute as float value
void setAttribute(s32 index, f32 value) override;
/*
Bool Attribute
*/
//! Adds an attribute as bool
void addBool(const c8* attributeName, bool value) override;
//! Sets an attribute as boolean value
void setAttribute(const c8* attributeName, bool value) override;
//! Gets an attribute as boolean value
//! \param attributeName: Name of the attribute to get.
//! \param defaultNotFound Value returned when attributeName was not found
//! \return Returns value of the attribute previously set by setAttribute()
bool getAttributeAsBool(const c8* attributeName, bool defaultNotFound=false) const override;
//! Gets an attribute as boolean value
//! \param index: Index value, must be between 0 and getAttributeCount()-1.
bool getAttributeAsBool(s32 index) const override;
//! Sets an attribute as boolean value
void setAttribute(s32 index, bool value) override;
protected:
core::array<IAttribute*> Attributes;
IAttribute* getAttributeP(const c8* attributeName) const;
video::IVideoDriver* Driver;
};
} // end namespace io
} // end namespace irr

File diff suppressed because it is too large Load Diff

View File

@ -1,83 +1,83 @@
// Copyright (C) 2006-2012 Luke Hoschke
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
// B3D Mesh loader
// File format designed by Mark Sibly for the Blitz3D engine and has been
// declared public domain
#pragma once
#include "IMeshLoader.h"
#include "ISceneManager.h"
#include "CSkinnedMesh.h"
#include "SB3DStructs.h"
#include "IReadFile.h"
namespace irr
{
namespace scene
{
//! Meshloader for B3D format
class CB3DMeshFileLoader : public IMeshLoader
{
public:
//! Constructor
CB3DMeshFileLoader(scene::ISceneManager* smgr);
//! returns true if the file maybe is able to be loaded by this class
//! based on the file extension (e.g. ".bsp")
bool isALoadableFileExtension(const io::path& filename) const override;
//! creates/loads an animated mesh from the file.
//! \return Pointer to the created mesh. Returns 0 if loading failed.
//! If you no longer need the mesh, you should call IAnimatedMesh::drop().
//! See IReferenceCounted::drop() for more information.
IAnimatedMesh* createMesh(io::IReadFile* file) override;
private:
bool load();
bool readChunkNODE(CSkinnedMesh::SJoint* InJoint);
bool readChunkMESH(CSkinnedMesh::SJoint* InJoint);
bool readChunkVRTS(CSkinnedMesh::SJoint* InJoint);
bool readChunkTRIS(scene::SSkinMeshBuffer *MeshBuffer, u32 MeshBufferID, s32 Vertices_Start);
bool readChunkBONE(CSkinnedMesh::SJoint* InJoint);
bool readChunkKEYS(CSkinnedMesh::SJoint* InJoint);
bool readChunkANIM();
bool readChunkTEXS();
bool readChunkBRUS();
void readString(core::stringc& newstring);
void readFloats(f32* vec, u32 count);
core::array<SB3dChunk> B3dStack;
core::array<SB3dMaterial> Materials;
core::array<SB3dTexture> Textures;
core::array<s32> AnimatedVertices_VertexID;
core::array<s32> AnimatedVertices_BufferID;
core::array<video::S3DVertex2TCoords> BaseVertices;
CSkinnedMesh* AnimatedMesh;
io::IReadFile* B3DFile;
//B3Ds have Vertex ID's local within the mesh I don't want this
// Variable needs to be class member due to recursion in calls
u32 VerticesStart;
bool NormalsInFile;
bool HasVertexColors;
bool ShowWarning;
};
} // end namespace scene
} // end namespace irr
// Copyright (C) 2006-2012 Luke Hoschke
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
// B3D Mesh loader
// File format designed by Mark Sibly for the Blitz3D engine and has been
// declared public domain
#pragma once
#include "IMeshLoader.h"
#include "ISceneManager.h"
#include "CSkinnedMesh.h"
#include "SB3DStructs.h"
#include "IReadFile.h"
namespace irr
{
namespace scene
{
//! Meshloader for B3D format
class CB3DMeshFileLoader : public IMeshLoader
{
public:
//! Constructor
CB3DMeshFileLoader(scene::ISceneManager* smgr);
//! returns true if the file maybe is able to be loaded by this class
//! based on the file extension (e.g. ".bsp")
bool isALoadableFileExtension(const io::path& filename) const override;
//! creates/loads an animated mesh from the file.
//! \return Pointer to the created mesh. Returns 0 if loading failed.
//! If you no longer need the mesh, you should call IAnimatedMesh::drop().
//! See IReferenceCounted::drop() for more information.
IAnimatedMesh* createMesh(io::IReadFile* file) override;
private:
bool load();
bool readChunkNODE(CSkinnedMesh::SJoint* InJoint);
bool readChunkMESH(CSkinnedMesh::SJoint* InJoint);
bool readChunkVRTS(CSkinnedMesh::SJoint* InJoint);
bool readChunkTRIS(scene::SSkinMeshBuffer *MeshBuffer, u32 MeshBufferID, s32 Vertices_Start);
bool readChunkBONE(CSkinnedMesh::SJoint* InJoint);
bool readChunkKEYS(CSkinnedMesh::SJoint* InJoint);
bool readChunkANIM();
bool readChunkTEXS();
bool readChunkBRUS();
void readString(core::stringc& newstring);
void readFloats(f32* vec, u32 count);
core::array<SB3dChunk> B3dStack;
core::array<SB3dMaterial> Materials;
core::array<SB3dTexture> Textures;
core::array<s32> AnimatedVertices_VertexID;
core::array<s32> AnimatedVertices_BufferID;
core::array<video::S3DVertex2TCoords> BaseVertices;
CSkinnedMesh* AnimatedMesh;
io::IReadFile* B3DFile;
//B3Ds have Vertex ID's local within the mesh I don't want this
// Variable needs to be class member due to recursion in calls
u32 VerticesStart;
bool NormalsInFile;
bool HasVertexColors;
bool ShowWarning;
};
} // end namespace scene
} // end namespace irr

File diff suppressed because it is too large Load Diff

View File

@ -1,51 +1,51 @@
// Copyright (C) 2014 Lauri Kasanen
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
// Modified version with rigging/skinning support
#pragma once
#include "IMeshWriter.h"
#include "IWriteFile.h"
#include "SB3DStructs.h"
#include "ISkinnedMesh.h"
namespace irr
{
namespace scene
{
//! class to write B3D mesh files
class CB3DMeshWriter : public IMeshWriter
{
public:
CB3DMeshWriter();
//! Returns the type of the mesh writer
EMESH_WRITER_TYPE getType() const override;
//! writes a mesh
bool writeMesh(io::IWriteFile* file, scene::IMesh* mesh, s32 flags=EMWF_NONE) override;
private:
void writeJointChunk(io::IWriteFile* file, ISkinnedMesh* mesh , ISkinnedMesh::SJoint* joint, f32 animationSpeedMultiplier);
u32 getJointChunkSize(const ISkinnedMesh* mesh, ISkinnedMesh::SJoint* joint);
core::array<ISkinnedMesh::SJoint*> getRootJoints(const ISkinnedMesh* mesh);
u32 getUVlayerCount(const IMesh *mesh);
ISkinnedMesh* getSkinned (IMesh *mesh);
inline void writeVector2(io::IWriteFile* file, const core::vector2df& vec);
inline void writeVector3(io::IWriteFile* file, const core::vector3df& vec);
inline void writeQuaternion(io::IWriteFile* file, const core::quaternion& quat);
inline void writeColor(io::IWriteFile* file, const video::SColorf& color);
void writeSizeFrom(io::IWriteFile* file, const u32 from, const u32 adressToWrite);
};
} // end namespace
} // end namespace
// Copyright (C) 2014 Lauri Kasanen
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
// Modified version with rigging/skinning support
#pragma once
#include "IMeshWriter.h"
#include "IWriteFile.h"
#include "SB3DStructs.h"
#include "ISkinnedMesh.h"
namespace irr
{
namespace scene
{
//! class to write B3D mesh files
class CB3DMeshWriter : public IMeshWriter
{
public:
CB3DMeshWriter();
//! Returns the type of the mesh writer
EMESH_WRITER_TYPE getType() const override;
//! writes a mesh
bool writeMesh(io::IWriteFile* file, scene::IMesh* mesh, s32 flags=EMWF_NONE) override;
private:
void writeJointChunk(io::IWriteFile* file, ISkinnedMesh* mesh , ISkinnedMesh::SJoint* joint, f32 animationSpeedMultiplier);
u32 getJointChunkSize(const ISkinnedMesh* mesh, ISkinnedMesh::SJoint* joint);
core::array<ISkinnedMesh::SJoint*> getRootJoints(const ISkinnedMesh* mesh);
u32 getUVlayerCount(const IMesh *mesh);
ISkinnedMesh* getSkinned (IMesh *mesh);
inline void writeVector2(io::IWriteFile* file, const core::vector2df& vec);
inline void writeVector3(io::IWriteFile* file, const core::vector3df& vec);
inline void writeQuaternion(io::IWriteFile* file, const core::quaternion& quat);
inline void writeColor(io::IWriteFile* file, const video::SColorf& color);
void writeSizeFrom(io::IWriteFile* file, const u32 from, const u32 adressToWrite);
};
} // end namespace
} // end namespace

View File

@ -1,281 +1,281 @@
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#include "CBillboardSceneNode.h"
#include "IVideoDriver.h"
#include "ISceneManager.h"
#include "ICameraSceneNode.h"
#include "os.h"
namespace irr
{
namespace scene
{
//! constructor
CBillboardSceneNode::CBillboardSceneNode(ISceneNode* parent, ISceneManager* mgr, s32 id,
const core::vector3df& position, const core::dimension2d<f32>& size,
video::SColor colorTop, video::SColor colorBottom)
: IBillboardSceneNode(parent, mgr, id, position)
, Buffer(new SMeshBuffer())
{
#ifdef _DEBUG
setDebugName("CBillboardSceneNode");
#endif
setSize(size);
Buffer->Vertices.set_used(4);
Buffer->Indices.set_used(6);
Buffer->Indices[0] = 0;
Buffer->Indices[1] = 2;
Buffer->Indices[2] = 1;
Buffer->Indices[3] = 0;
Buffer->Indices[4] = 3;
Buffer->Indices[5] = 2;
Buffer->Vertices[0].TCoords.set(1.0f, 1.0f);
Buffer->Vertices[0].Color = colorBottom;
Buffer->Vertices[1].TCoords.set(1.0f, 0.0f);
Buffer->Vertices[1].Color = colorTop;
Buffer->Vertices[2].TCoords.set(0.0f, 0.0f);
Buffer->Vertices[2].Color = colorTop;
Buffer->Vertices[3].TCoords.set(0.0f, 1.0f);
Buffer->Vertices[3].Color = colorBottom;
}
CBillboardSceneNode::~CBillboardSceneNode()
{
Buffer->drop();
}
//! pre render event
void CBillboardSceneNode::OnRegisterSceneNode()
{
if (IsVisible)
SceneManager->registerNodeForRendering(this);
ISceneNode::OnRegisterSceneNode();
}
//! render
void CBillboardSceneNode::render()
{
video::IVideoDriver* driver = SceneManager->getVideoDriver();
ICameraSceneNode* camera = SceneManager->getActiveCamera();
if (!camera || !driver)
return;
// make billboard look to camera
updateMesh(camera);
driver->setTransform(video::ETS_WORLD, core::IdentityMatrix);
driver->setMaterial(Buffer->Material);
driver->drawMeshBuffer(Buffer);
if (DebugDataVisible & scene::EDS_BBOX)
{
driver->setTransform(video::ETS_WORLD, AbsoluteTransformation);
video::SMaterial m;
m.Lighting = false;
driver->setMaterial(m);
driver->draw3DBox(BBoxSafe, video::SColor(0,208,195,152));
}
}
void CBillboardSceneNode::updateMesh(const irr::scene::ICameraSceneNode* camera)
{
// billboard looks toward camera
core::vector3df pos = getAbsolutePosition();
core::vector3df campos = camera->getAbsolutePosition();
core::vector3df target = camera->getTarget();
core::vector3df up = camera->getUpVector();
core::vector3df view = target - campos;
view.normalize();
core::vector3df horizontal = up.crossProduct(view);
if ( horizontal.getLength() == 0 )
{
horizontal.set(up.Y,up.X,up.Z);
}
horizontal.normalize();
core::vector3df topHorizontal = horizontal * 0.5f * TopEdgeWidth;
horizontal *= 0.5f * Size.Width;
// pointing down!
core::vector3df vertical = horizontal.crossProduct(view);
vertical.normalize();
vertical *= 0.5f * Size.Height;
view *= -1.0f;
core::array<video::S3DVertex>& vertices = Buffer->Vertices;
for (s32 i=0; i<4; ++i)
vertices[i].Normal = view;
/* Vertices are:
2--1
|\ |
| \|
3--0
*/
vertices[0].Pos = pos + horizontal + vertical;
vertices[1].Pos = pos + topHorizontal - vertical;
vertices[2].Pos = pos - topHorizontal - vertical;
vertices[3].Pos = pos - horizontal + vertical;
Buffer->setDirty(EBT_VERTEX);
Buffer->recalculateBoundingBox();
}
//! returns the axis aligned bounding box of this node
const core::aabbox3d<f32>& CBillboardSceneNode::getBoundingBox() const
{
// Really wrong when scaled (as the node does not scale it's vertices - maybe it should?)
return BBoxSafe;
}
const core::aabbox3d<f32>& CBillboardSceneNode::getTransformedBillboardBoundingBox(const irr::scene::ICameraSceneNode* camera)
{
updateMesh(camera);
return Buffer->BoundingBox;
}
void CBillboardSceneNode::setSize(const core::dimension2d<f32>& size)
{
Size = size;
if (core::equals(Size.Width, 0.0f))
Size.Width = 1.0f;
TopEdgeWidth = Size.Width;
if (core::equals(Size.Height, 0.0f))
Size.Height = 1.0f;
const f32 extent = 0.5f*sqrtf(Size.Width*Size.Width + Size.Height*Size.Height);
BBoxSafe.MinEdge.set(-extent,-extent,-extent);
BBoxSafe.MaxEdge.set(extent,extent,extent);
}
void CBillboardSceneNode::setSize(f32 height, f32 bottomEdgeWidth, f32 topEdgeWidth)
{
Size.set(bottomEdgeWidth, height);
TopEdgeWidth = topEdgeWidth;
if (core::equals(Size.Height, 0.0f))
Size.Height = 1.0f;
if (core::equals(Size.Width, 0.f) && core::equals(TopEdgeWidth, 0.f))
{
Size.Width = 1.0f;
TopEdgeWidth = 1.0f;
}
const f32 extent = 0.5f*sqrtf(Size.Width*Size.Width + Size.Height*Size.Height);
BBoxSafe.MinEdge.set(-extent,-extent,-extent);
BBoxSafe.MaxEdge.set(extent,extent,extent);
}
video::SMaterial& CBillboardSceneNode::getMaterial(u32 i)
{
return Buffer->Material;
}
//! returns amount of materials used by this scene node.
u32 CBillboardSceneNode::getMaterialCount() const
{
return 1;
}
//! gets the size of the billboard
const core::dimension2d<f32>& CBillboardSceneNode::getSize() const
{
return Size;
}
//! Gets the widths of the top and bottom edges of the billboard.
void CBillboardSceneNode::getSize(f32& height, f32& bottomEdgeWidth,
f32& topEdgeWidth) const
{
height = Size.Height;
bottomEdgeWidth = Size.Width;
topEdgeWidth = TopEdgeWidth;
}
//! Set the color of all vertices of the billboard
//! \param overallColor: the color to set
void CBillboardSceneNode::setColor(const video::SColor& overallColor)
{
for(u32 vertex = 0; vertex < 4; ++vertex)
Buffer->Vertices[vertex].Color = overallColor;
}
//! Set the color of the top and bottom vertices of the billboard
//! \param topColor: the color to set the top vertices
//! \param bottomColor: the color to set the bottom vertices
void CBillboardSceneNode::setColor(const video::SColor& topColor,
const video::SColor& bottomColor)
{
Buffer->Vertices[0].Color = bottomColor;
Buffer->Vertices[1].Color = topColor;
Buffer->Vertices[2].Color = topColor;
Buffer->Vertices[3].Color = bottomColor;
}
//! Gets the color of the top and bottom vertices of the billboard
//! \param[out] topColor: stores the color of the top vertices
//! \param[out] bottomColor: stores the color of the bottom vertices
void CBillboardSceneNode::getColor(video::SColor& topColor,
video::SColor& bottomColor) const
{
bottomColor = Buffer->Vertices[0].Color;
topColor = Buffer->Vertices[1].Color;
}
//! Creates a clone of this scene node and its children.
ISceneNode* CBillboardSceneNode::clone(ISceneNode* newParent, ISceneManager* newManager)
{
if (!newParent)
newParent = Parent;
if (!newManager)
newManager = SceneManager;
CBillboardSceneNode* nb = new CBillboardSceneNode(newParent,
newManager, ID, RelativeTranslation, Size);
nb->cloneMembers(this, newManager);
nb->Buffer->Material = Buffer->Material;
nb->Size = Size;
nb->TopEdgeWidth = this->TopEdgeWidth;
video::SColor topColor,bottomColor;
getColor(topColor,bottomColor);
nb->setColor(topColor,bottomColor);
if ( newParent )
nb->drop();
return nb;
}
} // end namespace scene
} // end namespace irr
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#include "CBillboardSceneNode.h"
#include "IVideoDriver.h"
#include "ISceneManager.h"
#include "ICameraSceneNode.h"
#include "os.h"
namespace irr
{
namespace scene
{
//! constructor
CBillboardSceneNode::CBillboardSceneNode(ISceneNode* parent, ISceneManager* mgr, s32 id,
const core::vector3df& position, const core::dimension2d<f32>& size,
video::SColor colorTop, video::SColor colorBottom)
: IBillboardSceneNode(parent, mgr, id, position)
, Buffer(new SMeshBuffer())
{
#ifdef _DEBUG
setDebugName("CBillboardSceneNode");
#endif
setSize(size);
Buffer->Vertices.set_used(4);
Buffer->Indices.set_used(6);
Buffer->Indices[0] = 0;
Buffer->Indices[1] = 2;
Buffer->Indices[2] = 1;
Buffer->Indices[3] = 0;
Buffer->Indices[4] = 3;
Buffer->Indices[5] = 2;
Buffer->Vertices[0].TCoords.set(1.0f, 1.0f);
Buffer->Vertices[0].Color = colorBottom;
Buffer->Vertices[1].TCoords.set(1.0f, 0.0f);
Buffer->Vertices[1].Color = colorTop;
Buffer->Vertices[2].TCoords.set(0.0f, 0.0f);
Buffer->Vertices[2].Color = colorTop;
Buffer->Vertices[3].TCoords.set(0.0f, 1.0f);
Buffer->Vertices[3].Color = colorBottom;
}
CBillboardSceneNode::~CBillboardSceneNode()
{
Buffer->drop();
}
//! pre render event
void CBillboardSceneNode::OnRegisterSceneNode()
{
if (IsVisible)
SceneManager->registerNodeForRendering(this);
ISceneNode::OnRegisterSceneNode();
}
//! render
void CBillboardSceneNode::render()
{
video::IVideoDriver* driver = SceneManager->getVideoDriver();
ICameraSceneNode* camera = SceneManager->getActiveCamera();
if (!camera || !driver)
return;
// make billboard look to camera
updateMesh(camera);
driver->setTransform(video::ETS_WORLD, core::IdentityMatrix);
driver->setMaterial(Buffer->Material);
driver->drawMeshBuffer(Buffer);
if (DebugDataVisible & scene::EDS_BBOX)
{
driver->setTransform(video::ETS_WORLD, AbsoluteTransformation);
video::SMaterial m;
m.Lighting = false;
driver->setMaterial(m);
driver->draw3DBox(BBoxSafe, video::SColor(0,208,195,152));
}
}
void CBillboardSceneNode::updateMesh(const irr::scene::ICameraSceneNode* camera)
{
// billboard looks toward camera
core::vector3df pos = getAbsolutePosition();
core::vector3df campos = camera->getAbsolutePosition();
core::vector3df target = camera->getTarget();
core::vector3df up = camera->getUpVector();
core::vector3df view = target - campos;
view.normalize();
core::vector3df horizontal = up.crossProduct(view);
if ( horizontal.getLength() == 0 )
{
horizontal.set(up.Y,up.X,up.Z);
}
horizontal.normalize();
core::vector3df topHorizontal = horizontal * 0.5f * TopEdgeWidth;
horizontal *= 0.5f * Size.Width;
// pointing down!
core::vector3df vertical = horizontal.crossProduct(view);
vertical.normalize();
vertical *= 0.5f * Size.Height;
view *= -1.0f;
core::array<video::S3DVertex>& vertices = Buffer->Vertices;
for (s32 i=0; i<4; ++i)
vertices[i].Normal = view;
/* Vertices are:
2--1
|\ |
| \|
3--0
*/
vertices[0].Pos = pos + horizontal + vertical;
vertices[1].Pos = pos + topHorizontal - vertical;
vertices[2].Pos = pos - topHorizontal - vertical;
vertices[3].Pos = pos - horizontal + vertical;
Buffer->setDirty(EBT_VERTEX);
Buffer->recalculateBoundingBox();
}
//! returns the axis aligned bounding box of this node
const core::aabbox3d<f32>& CBillboardSceneNode::getBoundingBox() const
{
// Really wrong when scaled (as the node does not scale it's vertices - maybe it should?)
return BBoxSafe;
}
const core::aabbox3d<f32>& CBillboardSceneNode::getTransformedBillboardBoundingBox(const irr::scene::ICameraSceneNode* camera)
{
updateMesh(camera);
return Buffer->BoundingBox;
}
void CBillboardSceneNode::setSize(const core::dimension2d<f32>& size)
{
Size = size;
if (core::equals(Size.Width, 0.0f))
Size.Width = 1.0f;
TopEdgeWidth = Size.Width;
if (core::equals(Size.Height, 0.0f))
Size.Height = 1.0f;
const f32 extent = 0.5f*sqrtf(Size.Width*Size.Width + Size.Height*Size.Height);
BBoxSafe.MinEdge.set(-extent,-extent,-extent);
BBoxSafe.MaxEdge.set(extent,extent,extent);
}
void CBillboardSceneNode::setSize(f32 height, f32 bottomEdgeWidth, f32 topEdgeWidth)
{
Size.set(bottomEdgeWidth, height);
TopEdgeWidth = topEdgeWidth;
if (core::equals(Size.Height, 0.0f))
Size.Height = 1.0f;
if (core::equals(Size.Width, 0.f) && core::equals(TopEdgeWidth, 0.f))
{
Size.Width = 1.0f;
TopEdgeWidth = 1.0f;
}
const f32 extent = 0.5f*sqrtf(Size.Width*Size.Width + Size.Height*Size.Height);
BBoxSafe.MinEdge.set(-extent,-extent,-extent);
BBoxSafe.MaxEdge.set(extent,extent,extent);
}
video::SMaterial& CBillboardSceneNode::getMaterial(u32 i)
{
return Buffer->Material;
}
//! returns amount of materials used by this scene node.
u32 CBillboardSceneNode::getMaterialCount() const
{
return 1;
}
//! gets the size of the billboard
const core::dimension2d<f32>& CBillboardSceneNode::getSize() const
{
return Size;
}
//! Gets the widths of the top and bottom edges of the billboard.
void CBillboardSceneNode::getSize(f32& height, f32& bottomEdgeWidth,
f32& topEdgeWidth) const
{
height = Size.Height;
bottomEdgeWidth = Size.Width;
topEdgeWidth = TopEdgeWidth;
}
//! Set the color of all vertices of the billboard
//! \param overallColor: the color to set
void CBillboardSceneNode::setColor(const video::SColor& overallColor)
{
for(u32 vertex = 0; vertex < 4; ++vertex)
Buffer->Vertices[vertex].Color = overallColor;
}
//! Set the color of the top and bottom vertices of the billboard
//! \param topColor: the color to set the top vertices
//! \param bottomColor: the color to set the bottom vertices
void CBillboardSceneNode::setColor(const video::SColor& topColor,
const video::SColor& bottomColor)
{
Buffer->Vertices[0].Color = bottomColor;
Buffer->Vertices[1].Color = topColor;
Buffer->Vertices[2].Color = topColor;
Buffer->Vertices[3].Color = bottomColor;
}
//! Gets the color of the top and bottom vertices of the billboard
//! \param[out] topColor: stores the color of the top vertices
//! \param[out] bottomColor: stores the color of the bottom vertices
void CBillboardSceneNode::getColor(video::SColor& topColor,
video::SColor& bottomColor) const
{
bottomColor = Buffer->Vertices[0].Color;
topColor = Buffer->Vertices[1].Color;
}
//! Creates a clone of this scene node and its children.
ISceneNode* CBillboardSceneNode::clone(ISceneNode* newParent, ISceneManager* newManager)
{
if (!newParent)
newParent = Parent;
if (!newManager)
newManager = SceneManager;
CBillboardSceneNode* nb = new CBillboardSceneNode(newParent,
newManager, ID, RelativeTranslation, Size);
nb->cloneMembers(this, newManager);
nb->Buffer->Material = Buffer->Material;
nb->Size = Size;
nb->TopEdgeWidth = this->TopEdgeWidth;
video::SColor topColor,bottomColor;
getColor(topColor,bottomColor);
nb->setColor(topColor,bottomColor);
if ( newParent )
nb->drop();
return nb;
}
} // end namespace scene
} // end namespace irr

View File

@ -1,117 +1,117 @@
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#pragma once
#include "IBillboardSceneNode.h"
#include "SMeshBuffer.h"
namespace irr
{
namespace scene
{
//! Scene node which is a billboard. A billboard is like a 3d sprite: A 2d element,
//! which always looks to the camera.
class CBillboardSceneNode : virtual public IBillboardSceneNode
{
public:
//! constructor
CBillboardSceneNode(ISceneNode* parent, ISceneManager* mgr, s32 id,
const core::vector3df& position, const core::dimension2d<f32>& size,
video::SColor colorTop=video::SColor(0xFFFFFFFF),
video::SColor colorBottom=video::SColor(0xFFFFFFFF));
virtual ~CBillboardSceneNode();
//! pre render event
void OnRegisterSceneNode() override;
//! render
void render() override;
//! returns the axis aligned bounding box of this node
const core::aabbox3d<f32>& getBoundingBox() const override;
//! sets the size of the billboard
void setSize(const core::dimension2d<f32>& size) override;
//! Sets the widths of the top and bottom edges of the billboard independently.
void setSize(f32 height, f32 bottomEdgeWidth, f32 topEdgeWidth) override;
//! gets the size of the billboard
const core::dimension2d<f32>& getSize() const override;
//! Gets the widths of the top and bottom edges of the billboard.
void getSize(f32& height, f32& bottomEdgeWidth, f32& topEdgeWidth) const override;
video::SMaterial& getMaterial(u32 i) override;
//! returns amount of materials used by this scene node.
u32 getMaterialCount() const override;
//! Set the color of all vertices of the billboard
//! \param overallColor: the color to set
void setColor(const video::SColor& overallColor) override;
//! Set the color of the top and bottom vertices of the billboard
//! \param topColor: the color to set the top vertices
//! \param bottomColor: the color to set the bottom vertices
virtual void setColor(const video::SColor& topColor,
const video::SColor& bottomColor) override;
//! Gets the color of the top and bottom vertices of the billboard
//! \param[out] topColor: stores the color of the top vertices
//! \param[out] bottomColor: stores the color of the bottom vertices
virtual void getColor(video::SColor& topColor,
video::SColor& bottomColor) const override;
//! Get the real boundingbox used by the billboard (which depends on the active camera)
const core::aabbox3d<f32>& getTransformedBillboardBoundingBox(const irr::scene::ICameraSceneNode* camera) override;
//! Get the amount of mesh buffers.
u32 getMeshBufferCount() const override
{
return Buffer ? 1 : 0;
}
//! Get pointer to the mesh buffer.
IMeshBuffer* getMeshBuffer(u32 nr) const override
{
if ( nr == 0 )
return Buffer;
return 0;
}
//! Returns type of the scene node
ESCENE_NODE_TYPE getType() const override { return ESNT_BILLBOARD; }
//! Creates a clone of this scene node and its children.
ISceneNode* clone(ISceneNode* newParent=0, ISceneManager* newManager=0) override;
protected:
void updateMesh(const irr::scene::ICameraSceneNode* camera);
private:
//! Size.Width is the bottom edge width
core::dimension2d<f32> Size;
f32 TopEdgeWidth;
//! BoundingBox which is large enough to contain the billboard independent of the camera
// TODO: BUG - still can be wrong with scaling < 1. Billboards should calculate relative coordinates for their mesh
// and then use the node-scaling. But needs some work...
/** Note that we can't use the real boundingbox for culling because at that point
the camera which is used to calculate the billboard is not yet updated. So we only
know the real boundingbox after rendering - which is too late for culling. */
core::aabbox3d<f32> BBoxSafe;
scene::SMeshBuffer* Buffer;
};
} // end namespace scene
} // end namespace irr
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#pragma once
#include "IBillboardSceneNode.h"
#include "SMeshBuffer.h"
namespace irr
{
namespace scene
{
//! Scene node which is a billboard. A billboard is like a 3d sprite: A 2d element,
//! which always looks to the camera.
class CBillboardSceneNode : virtual public IBillboardSceneNode
{
public:
//! constructor
CBillboardSceneNode(ISceneNode* parent, ISceneManager* mgr, s32 id,
const core::vector3df& position, const core::dimension2d<f32>& size,
video::SColor colorTop=video::SColor(0xFFFFFFFF),
video::SColor colorBottom=video::SColor(0xFFFFFFFF));
virtual ~CBillboardSceneNode();
//! pre render event
void OnRegisterSceneNode() override;
//! render
void render() override;
//! returns the axis aligned bounding box of this node
const core::aabbox3d<f32>& getBoundingBox() const override;
//! sets the size of the billboard
void setSize(const core::dimension2d<f32>& size) override;
//! Sets the widths of the top and bottom edges of the billboard independently.
void setSize(f32 height, f32 bottomEdgeWidth, f32 topEdgeWidth) override;
//! gets the size of the billboard
const core::dimension2d<f32>& getSize() const override;
//! Gets the widths of the top and bottom edges of the billboard.
void getSize(f32& height, f32& bottomEdgeWidth, f32& topEdgeWidth) const override;
video::SMaterial& getMaterial(u32 i) override;
//! returns amount of materials used by this scene node.
u32 getMaterialCount() const override;
//! Set the color of all vertices of the billboard
//! \param overallColor: the color to set
void setColor(const video::SColor& overallColor) override;
//! Set the color of the top and bottom vertices of the billboard
//! \param topColor: the color to set the top vertices
//! \param bottomColor: the color to set the bottom vertices
virtual void setColor(const video::SColor& topColor,
const video::SColor& bottomColor) override;
//! Gets the color of the top and bottom vertices of the billboard
//! \param[out] topColor: stores the color of the top vertices
//! \param[out] bottomColor: stores the color of the bottom vertices
virtual void getColor(video::SColor& topColor,
video::SColor& bottomColor) const override;
//! Get the real boundingbox used by the billboard (which depends on the active camera)
const core::aabbox3d<f32>& getTransformedBillboardBoundingBox(const irr::scene::ICameraSceneNode* camera) override;
//! Get the amount of mesh buffers.
u32 getMeshBufferCount() const override
{
return Buffer ? 1 : 0;
}
//! Get pointer to the mesh buffer.
IMeshBuffer* getMeshBuffer(u32 nr) const override
{
if ( nr == 0 )
return Buffer;
return 0;
}
//! Returns type of the scene node
ESCENE_NODE_TYPE getType() const override { return ESNT_BILLBOARD; }
//! Creates a clone of this scene node and its children.
ISceneNode* clone(ISceneNode* newParent=0, ISceneManager* newManager=0) override;
protected:
void updateMesh(const irr::scene::ICameraSceneNode* camera);
private:
//! Size.Width is the bottom edge width
core::dimension2d<f32> Size;
f32 TopEdgeWidth;
//! BoundingBox which is large enough to contain the billboard independent of the camera
// TODO: BUG - still can be wrong with scaling < 1. Billboards should calculate relative coordinates for their mesh
// and then use the node-scaling. But needs some work...
/** Note that we can't use the real boundingbox for culling because at that point
the camera which is used to calculate the billboard is not yet updated. So we only
know the real boundingbox after rendering - which is too late for culling. */
core::aabbox3d<f32> BBoxSafe;
scene::SMeshBuffer* Buffer;
};
} // end namespace scene
} // end namespace irr

File diff suppressed because it is too large Load Diff

View File

@ -1,97 +1,97 @@
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#include "CBoneSceneNode.h"
namespace irr
{
namespace scene
{
//! constructor
CBoneSceneNode::CBoneSceneNode(ISceneNode* parent, ISceneManager* mgr, s32 id,
u32 boneIndex, const c8* boneName)
: IBoneSceneNode(parent, mgr, id), BoneIndex(boneIndex),
AnimationMode(EBAM_AUTOMATIC), SkinningSpace(EBSS_LOCAL)
{
#ifdef _DEBUG
setDebugName("CBoneSceneNode");
#endif
setName(boneName);
}
//! Returns the index of the bone
u32 CBoneSceneNode::getBoneIndex() const
{
return BoneIndex;
}
//! Sets the animation mode of the bone. Returns true if successful.
bool CBoneSceneNode::setAnimationMode(E_BONE_ANIMATION_MODE mode)
{
AnimationMode = mode;
return true;
}
//! Gets the current animation mode of the bone
E_BONE_ANIMATION_MODE CBoneSceneNode::getAnimationMode() const
{
return AnimationMode;
}
//! returns the axis aligned bounding box of this node
const core::aabbox3d<f32>& CBoneSceneNode::getBoundingBox() const
{
return Box;
}
/*
//! Returns the relative transformation of the scene node.
core::matrix4 CBoneSceneNode::getRelativeTransformation() const
{
return core::matrix4(); // RelativeTransformation;
}
*/
void CBoneSceneNode::OnAnimate(u32 timeMs)
{
if (IsVisible)
{
// update absolute position
//updateAbsolutePosition();
// perform the post render process on all children
ISceneNodeList::iterator it = Children.begin();
for (; it != Children.end(); ++it)
(*it)->OnAnimate(timeMs);
}
}
void CBoneSceneNode::helper_updateAbsolutePositionOfAllChildren(ISceneNode *Node)
{
Node->updateAbsolutePosition();
ISceneNodeList::const_iterator it = Node->getChildren().begin();
for (; it != Node->getChildren().end(); ++it)
{
helper_updateAbsolutePositionOfAllChildren( (*it) );
}
}
void CBoneSceneNode::updateAbsolutePositionOfAllChildren()
{
helper_updateAbsolutePositionOfAllChildren( this );
}
} // namespace scene
} // namespace irr
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#include "CBoneSceneNode.h"
namespace irr
{
namespace scene
{
//! constructor
CBoneSceneNode::CBoneSceneNode(ISceneNode* parent, ISceneManager* mgr, s32 id,
u32 boneIndex, const c8* boneName)
: IBoneSceneNode(parent, mgr, id), BoneIndex(boneIndex),
AnimationMode(EBAM_AUTOMATIC), SkinningSpace(EBSS_LOCAL)
{
#ifdef _DEBUG
setDebugName("CBoneSceneNode");
#endif
setName(boneName);
}
//! Returns the index of the bone
u32 CBoneSceneNode::getBoneIndex() const
{
return BoneIndex;
}
//! Sets the animation mode of the bone. Returns true if successful.
bool CBoneSceneNode::setAnimationMode(E_BONE_ANIMATION_MODE mode)
{
AnimationMode = mode;
return true;
}
//! Gets the current animation mode of the bone
E_BONE_ANIMATION_MODE CBoneSceneNode::getAnimationMode() const
{
return AnimationMode;
}
//! returns the axis aligned bounding box of this node
const core::aabbox3d<f32>& CBoneSceneNode::getBoundingBox() const
{
return Box;
}
/*
//! Returns the relative transformation of the scene node.
core::matrix4 CBoneSceneNode::getRelativeTransformation() const
{
return core::matrix4(); // RelativeTransformation;
}
*/
void CBoneSceneNode::OnAnimate(u32 timeMs)
{
if (IsVisible)
{
// update absolute position
//updateAbsolutePosition();
// perform the post render process on all children
ISceneNodeList::iterator it = Children.begin();
for (; it != Children.end(); ++it)
(*it)->OnAnimate(timeMs);
}
}
void CBoneSceneNode::helper_updateAbsolutePositionOfAllChildren(ISceneNode *Node)
{
Node->updateAbsolutePosition();
ISceneNodeList::const_iterator it = Node->getChildren().begin();
for (; it != Node->getChildren().end(); ++it)
{
helper_updateAbsolutePositionOfAllChildren( (*it) );
}
}
void CBoneSceneNode::updateAbsolutePositionOfAllChildren()
{
helper_updateAbsolutePositionOfAllChildren( this );
}
} // namespace scene
} // namespace irr

View File

@ -1,70 +1,70 @@
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#pragma once
// Used with SkinnedMesh and IAnimatedMeshSceneNode, for boned meshes
#include "IBoneSceneNode.h"
namespace irr
{
namespace scene
{
class CBoneSceneNode : public IBoneSceneNode
{
public:
//! constructor
CBoneSceneNode(ISceneNode* parent, ISceneManager* mgr,
s32 id=-1, u32 boneIndex=0, const c8* boneName=0);
//! Returns the index of the bone
u32 getBoneIndex() const override;
//! Sets the animation mode of the bone. Returns true if successful.
bool setAnimationMode(E_BONE_ANIMATION_MODE mode) override;
//! Gets the current animation mode of the bone
E_BONE_ANIMATION_MODE getAnimationMode() const override;
//! returns the axis aligned bounding box of this node
const core::aabbox3d<f32>& getBoundingBox() const override;
/*
//! Returns the relative transformation of the scene node.
//core::matrix4 getRelativeTransformation() const override;
*/
void OnAnimate(u32 timeMs) override;
void updateAbsolutePositionOfAllChildren() override;
//! How the relative transformation of the bone is used
void setSkinningSpace(E_BONE_SKINNING_SPACE space) override
{
SkinningSpace=space;
}
E_BONE_SKINNING_SPACE getSkinningSpace() const override
{
return SkinningSpace;
}
private:
void helper_updateAbsolutePositionOfAllChildren(ISceneNode *Node);
u32 BoneIndex;
core::aabbox3d<f32> Box;
E_BONE_ANIMATION_MODE AnimationMode;
E_BONE_SKINNING_SPACE SkinningSpace;
};
} // end namespace scene
} // end namespace irr
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#pragma once
// Used with SkinnedMesh and IAnimatedMeshSceneNode, for boned meshes
#include "IBoneSceneNode.h"
namespace irr
{
namespace scene
{
class CBoneSceneNode : public IBoneSceneNode
{
public:
//! constructor
CBoneSceneNode(ISceneNode* parent, ISceneManager* mgr,
s32 id=-1, u32 boneIndex=0, const c8* boneName=0);
//! Returns the index of the bone
u32 getBoneIndex() const override;
//! Sets the animation mode of the bone. Returns true if successful.
bool setAnimationMode(E_BONE_ANIMATION_MODE mode) override;
//! Gets the current animation mode of the bone
E_BONE_ANIMATION_MODE getAnimationMode() const override;
//! returns the axis aligned bounding box of this node
const core::aabbox3d<f32>& getBoundingBox() const override;
/*
//! Returns the relative transformation of the scene node.
//core::matrix4 getRelativeTransformation() const override;
*/
void OnAnimate(u32 timeMs) override;
void updateAbsolutePositionOfAllChildren() override;
//! How the relative transformation of the bone is used
void setSkinningSpace(E_BONE_SKINNING_SPACE space) override
{
SkinningSpace=space;
}
E_BONE_SKINNING_SPACE getSkinningSpace() const override
{
return SkinningSpace;
}
private:
void helper_updateAbsolutePositionOfAllChildren(ISceneNode *Node);
u32 BoneIndex;
core::aabbox3d<f32> Box;
E_BONE_ANIMATION_MODE AnimationMode;
E_BONE_SKINNING_SPACE SkinningSpace;
};
} // end namespace scene
} // end namespace irr

View File

@ -1,350 +1,350 @@
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#include "CCameraSceneNode.h"
#include "ISceneManager.h"
#include "IVideoDriver.h"
#include "os.h"
namespace irr
{
namespace scene
{
//! constructor
CCameraSceneNode::CCameraSceneNode(ISceneNode* parent, ISceneManager* mgr, s32 id,
const core::vector3df& position, const core::vector3df& lookat)
: ICameraSceneNode(parent, mgr, id, position),
BoundingBox(core::vector3df(0, 0, 0)), // Camera has no size. Still not sure if FLT_MAX might be the better variant
Target(lookat), UpVector(0.0f, 1.0f, 0.0f), ZNear(1.0f), ZFar(3000.0f),
InputReceiverEnabled(true), TargetAndRotationAreBound(false)
{
#ifdef _DEBUG
setDebugName("CCameraSceneNode");
#endif
// set default projection
Fovy = core::PI / 2.5f; // Field of view, in radians.
Aspect = 4.0f / 3.0f; // Aspect ratio.
const video::IVideoDriver* const d = mgr?mgr->getVideoDriver():0;
if (d)
{
if ( d->getCurrentRenderTargetSize().Height )
Aspect = (f32)d->getCurrentRenderTargetSize().Width /
(f32)d->getCurrentRenderTargetSize().Height;
}
ViewArea.setFarNearDistance(ZFar - ZNear);
recalculateProjectionMatrix();
recalculateViewArea();
}
//! Disables or enables the camera to get key or mouse inputs.
void CCameraSceneNode::setInputReceiverEnabled(bool enabled)
{
InputReceiverEnabled = enabled;
}
//! Returns if the input receiver of the camera is currently enabled.
bool CCameraSceneNode::isInputReceiverEnabled() const
{
return InputReceiverEnabled;
}
//! Sets the projection matrix of the camera.
/** The core::matrix4 class has some methods
to build a projection matrix. e.g: core::matrix4::buildProjectionMatrixPerspectiveFovLH
\param projection: The new projection matrix of the camera. */
void CCameraSceneNode::setProjectionMatrix(const core::matrix4& projection, bool isOrthogonal)
{
IsOrthogonal = isOrthogonal;
ViewArea.getTransform ( video::ETS_PROJECTION ) = projection;
}
//! Gets the current projection matrix of the camera
//! \return Returns the current projection matrix of the camera.
const core::matrix4& CCameraSceneNode::getProjectionMatrix() const
{
return ViewArea.getTransform ( video::ETS_PROJECTION );
}
//! Gets the current view matrix of the camera
//! \return Returns the current view matrix of the camera.
const core::matrix4& CCameraSceneNode::getViewMatrix() const
{
return ViewArea.getTransform ( video::ETS_VIEW );
}
//! Sets a custom view matrix affector. The matrix passed here, will be
//! multiplied with the view matrix when it gets updated.
//! This allows for custom camera setups like, for example, a reflection camera.
/** \param affector: The affector matrix. */
void CCameraSceneNode::setViewMatrixAffector(const core::matrix4& affector)
{
Affector = affector;
}
//! Gets the custom view matrix affector.
const core::matrix4& CCameraSceneNode::getViewMatrixAffector() const
{
return Affector;
}
//! It is possible to send mouse and key events to the camera. Most cameras
//! may ignore this input, but camera scene nodes which are created for
//! example with scene::ISceneManager::addMayaCameraSceneNode or
//! scene::ISceneManager::addFPSCameraSceneNode, may want to get this input
//! for changing their position, look at target or whatever.
bool CCameraSceneNode::OnEvent(const SEvent& event)
{
// animators have been deleted; nothing happens here now!
return false;
}
//! sets the look at target of the camera
//! \param pos: Look at target of the camera.
void CCameraSceneNode::setTarget(const core::vector3df& pos)
{
Target = pos;
if(TargetAndRotationAreBound)
{
const core::vector3df toTarget = Target - getAbsolutePosition();
ISceneNode::setRotation(toTarget.getHorizontalAngle());
}
}
//! Sets the rotation of the node.
/** This only modifies the relative rotation of the node.
If the camera's target and rotation are bound ( @see bindTargetAndRotation() )
then calling this will also change the camera's target to match the rotation.
\param rotation New rotation of the node in degrees. */
void CCameraSceneNode::setRotation(const core::vector3df& rotation)
{
if(TargetAndRotationAreBound)
Target = getAbsolutePosition() + rotation.rotationToDirection();
ISceneNode::setRotation(rotation);
}
//! Gets the current look at target of the camera
//! \return Returns the current look at target of the camera
const core::vector3df& CCameraSceneNode::getTarget() const
{
return Target;
}
//! sets the up vector of the camera
//! \param pos: New upvector of the camera.
void CCameraSceneNode::setUpVector(const core::vector3df& pos)
{
UpVector = pos;
}
//! Gets the up vector of the camera.
//! \return Returns the up vector of the camera.
const core::vector3df& CCameraSceneNode::getUpVector() const
{
return UpVector;
}
f32 CCameraSceneNode::getNearValue() const
{
return ZNear;
}
f32 CCameraSceneNode::getFarValue() const
{
return ZFar;
}
f32 CCameraSceneNode::getAspectRatio() const
{
return Aspect;
}
f32 CCameraSceneNode::getFOV() const
{
return Fovy;
}
void CCameraSceneNode::setNearValue(f32 f)
{
ZNear = f;
recalculateProjectionMatrix();
ViewArea.setFarNearDistance(ZFar - ZNear);
}
void CCameraSceneNode::setFarValue(f32 f)
{
ZFar = f;
recalculateProjectionMatrix();
ViewArea.setFarNearDistance(ZFar - ZNear);
}
void CCameraSceneNode::setAspectRatio(f32 f)
{
Aspect = f;
recalculateProjectionMatrix();
}
void CCameraSceneNode::setFOV(f32 f)
{
Fovy = f;
recalculateProjectionMatrix();
}
void CCameraSceneNode::recalculateProjectionMatrix()
{
ViewArea.getTransform ( video::ETS_PROJECTION ).buildProjectionMatrixPerspectiveFovLH(Fovy, Aspect, ZNear, ZFar, false);
IsOrthogonal = false;
}
//! prerender
void CCameraSceneNode::OnRegisterSceneNode()
{
if ( SceneManager->getActiveCamera () == this )
SceneManager->registerNodeForRendering(this, ESNRP_CAMERA);
ISceneNode::OnRegisterSceneNode();
}
//! render
void CCameraSceneNode::render()
{
updateMatrices();
video::IVideoDriver* driver = SceneManager->getVideoDriver();
if ( driver)
{
driver->setTransform(video::ETS_PROJECTION, ViewArea.getTransform ( video::ETS_PROJECTION) );
driver->setTransform(video::ETS_VIEW, ViewArea.getTransform ( video::ETS_VIEW) );
}
}
//! update
void CCameraSceneNode::updateMatrices()
{
core::vector3df pos = getAbsolutePosition();
core::vector3df tgtv = Target - pos;
tgtv.normalize();
// if upvector and vector to the target are the same, we have a
// problem. so solve this problem:
core::vector3df up = UpVector;
up.normalize();
f32 dp = tgtv.dotProduct(up);
if ( core::equals(core::abs_<f32>(dp), 1.f) )
{
up.X += 0.5f;
}
ViewArea.getTransform(video::ETS_VIEW).buildCameraLookAtMatrixLH(pos, Target, up);
ViewArea.getTransform(video::ETS_VIEW) *= Affector;
recalculateViewArea();
}
//! returns the axis aligned bounding box of this node
const core::aabbox3d<f32>& CCameraSceneNode::getBoundingBox() const
{
return BoundingBox;
}
//! returns the view frustum.
const SViewFrustum* CCameraSceneNode::getViewFrustum() const
{
return &ViewArea;
}
void CCameraSceneNode::recalculateViewArea()
{
ViewArea.cameraPosition = getAbsolutePosition();
core::matrix4 m(core::matrix4::EM4CONST_NOTHING);
m.setbyproduct_nocheck(ViewArea.getTransform(video::ETS_PROJECTION),
ViewArea.getTransform(video::ETS_VIEW));
ViewArea.setFrom(m, false);
}
//! Set the binding between the camera's rotation adn target.
void CCameraSceneNode::bindTargetAndRotation(bool bound)
{
TargetAndRotationAreBound = bound;
}
//! Gets the binding between the camera's rotation and target.
bool CCameraSceneNode::getTargetAndRotationBinding(void) const
{
return TargetAndRotationAreBound;
}
//! Creates a clone of this scene node and its children.
ISceneNode* CCameraSceneNode::clone(ISceneNode* newParent, ISceneManager* newManager)
{
ICameraSceneNode::clone(newParent, newManager);
if (!newParent)
newParent = Parent;
if (!newManager)
newManager = SceneManager;
CCameraSceneNode* nb = new CCameraSceneNode(newParent,
newManager, ID, RelativeTranslation, Target);
nb->ISceneNode::cloneMembers(this, newManager);
nb->ICameraSceneNode::cloneMembers(this);
nb->Target = Target;
nb->UpVector = UpVector;
nb->Fovy = Fovy;
nb->Aspect = Aspect;
nb->ZNear = ZNear;
nb->ZFar = ZFar;
nb->ViewArea = ViewArea;
nb->Affector = Affector;
nb->InputReceiverEnabled = InputReceiverEnabled;
nb->TargetAndRotationAreBound = TargetAndRotationAreBound;
if ( newParent )
nb->drop();
return nb;
}
} // end namespace
} // end namespace
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#include "CCameraSceneNode.h"
#include "ISceneManager.h"
#include "IVideoDriver.h"
#include "os.h"
namespace irr
{
namespace scene
{
//! constructor
CCameraSceneNode::CCameraSceneNode(ISceneNode* parent, ISceneManager* mgr, s32 id,
const core::vector3df& position, const core::vector3df& lookat)
: ICameraSceneNode(parent, mgr, id, position),
BoundingBox(core::vector3df(0, 0, 0)), // Camera has no size. Still not sure if FLT_MAX might be the better variant
Target(lookat), UpVector(0.0f, 1.0f, 0.0f), ZNear(1.0f), ZFar(3000.0f),
InputReceiverEnabled(true), TargetAndRotationAreBound(false)
{
#ifdef _DEBUG
setDebugName("CCameraSceneNode");
#endif
// set default projection
Fovy = core::PI / 2.5f; // Field of view, in radians.
Aspect = 4.0f / 3.0f; // Aspect ratio.
const video::IVideoDriver* const d = mgr?mgr->getVideoDriver():0;
if (d)
{
if ( d->getCurrentRenderTargetSize().Height )
Aspect = (f32)d->getCurrentRenderTargetSize().Width /
(f32)d->getCurrentRenderTargetSize().Height;
}
ViewArea.setFarNearDistance(ZFar - ZNear);
recalculateProjectionMatrix();
recalculateViewArea();
}
//! Disables or enables the camera to get key or mouse inputs.
void CCameraSceneNode::setInputReceiverEnabled(bool enabled)
{
InputReceiverEnabled = enabled;
}
//! Returns if the input receiver of the camera is currently enabled.
bool CCameraSceneNode::isInputReceiverEnabled() const
{
return InputReceiverEnabled;
}
//! Sets the projection matrix of the camera.
/** The core::matrix4 class has some methods
to build a projection matrix. e.g: core::matrix4::buildProjectionMatrixPerspectiveFovLH
\param projection: The new projection matrix of the camera. */
void CCameraSceneNode::setProjectionMatrix(const core::matrix4& projection, bool isOrthogonal)
{
IsOrthogonal = isOrthogonal;
ViewArea.getTransform ( video::ETS_PROJECTION ) = projection;
}
//! Gets the current projection matrix of the camera
//! \return Returns the current projection matrix of the camera.
const core::matrix4& CCameraSceneNode::getProjectionMatrix() const
{
return ViewArea.getTransform ( video::ETS_PROJECTION );
}
//! Gets the current view matrix of the camera
//! \return Returns the current view matrix of the camera.
const core::matrix4& CCameraSceneNode::getViewMatrix() const
{
return ViewArea.getTransform ( video::ETS_VIEW );
}
//! Sets a custom view matrix affector. The matrix passed here, will be
//! multiplied with the view matrix when it gets updated.
//! This allows for custom camera setups like, for example, a reflection camera.
/** \param affector: The affector matrix. */
void CCameraSceneNode::setViewMatrixAffector(const core::matrix4& affector)
{
Affector = affector;
}
//! Gets the custom view matrix affector.
const core::matrix4& CCameraSceneNode::getViewMatrixAffector() const
{
return Affector;
}
//! It is possible to send mouse and key events to the camera. Most cameras
//! may ignore this input, but camera scene nodes which are created for
//! example with scene::ISceneManager::addMayaCameraSceneNode or
//! scene::ISceneManager::addFPSCameraSceneNode, may want to get this input
//! for changing their position, look at target or whatever.
bool CCameraSceneNode::OnEvent(const SEvent& event)
{
// animators have been deleted; nothing happens here now!
return false;
}
//! sets the look at target of the camera
//! \param pos: Look at target of the camera.
void CCameraSceneNode::setTarget(const core::vector3df& pos)
{
Target = pos;
if(TargetAndRotationAreBound)
{
const core::vector3df toTarget = Target - getAbsolutePosition();
ISceneNode::setRotation(toTarget.getHorizontalAngle());
}
}
//! Sets the rotation of the node.
/** This only modifies the relative rotation of the node.
If the camera's target and rotation are bound ( @see bindTargetAndRotation() )
then calling this will also change the camera's target to match the rotation.
\param rotation New rotation of the node in degrees. */
void CCameraSceneNode::setRotation(const core::vector3df& rotation)
{
if(TargetAndRotationAreBound)
Target = getAbsolutePosition() + rotation.rotationToDirection();
ISceneNode::setRotation(rotation);
}
//! Gets the current look at target of the camera
//! \return Returns the current look at target of the camera
const core::vector3df& CCameraSceneNode::getTarget() const
{
return Target;
}
//! sets the up vector of the camera
//! \param pos: New upvector of the camera.
void CCameraSceneNode::setUpVector(const core::vector3df& pos)
{
UpVector = pos;
}
//! Gets the up vector of the camera.
//! \return Returns the up vector of the camera.
const core::vector3df& CCameraSceneNode::getUpVector() const
{
return UpVector;
}
f32 CCameraSceneNode::getNearValue() const
{
return ZNear;
}
f32 CCameraSceneNode::getFarValue() const
{
return ZFar;
}
f32 CCameraSceneNode::getAspectRatio() const
{
return Aspect;
}
f32 CCameraSceneNode::getFOV() const
{
return Fovy;
}
void CCameraSceneNode::setNearValue(f32 f)
{
ZNear = f;
recalculateProjectionMatrix();
ViewArea.setFarNearDistance(ZFar - ZNear);
}
void CCameraSceneNode::setFarValue(f32 f)
{
ZFar = f;
recalculateProjectionMatrix();
ViewArea.setFarNearDistance(ZFar - ZNear);
}
void CCameraSceneNode::setAspectRatio(f32 f)
{
Aspect = f;
recalculateProjectionMatrix();
}
void CCameraSceneNode::setFOV(f32 f)
{
Fovy = f;
recalculateProjectionMatrix();
}
void CCameraSceneNode::recalculateProjectionMatrix()
{
ViewArea.getTransform ( video::ETS_PROJECTION ).buildProjectionMatrixPerspectiveFovLH(Fovy, Aspect, ZNear, ZFar, false);
IsOrthogonal = false;
}
//! prerender
void CCameraSceneNode::OnRegisterSceneNode()
{
if ( SceneManager->getActiveCamera () == this )
SceneManager->registerNodeForRendering(this, ESNRP_CAMERA);
ISceneNode::OnRegisterSceneNode();
}
//! render
void CCameraSceneNode::render()
{
updateMatrices();
video::IVideoDriver* driver = SceneManager->getVideoDriver();
if ( driver)
{
driver->setTransform(video::ETS_PROJECTION, ViewArea.getTransform ( video::ETS_PROJECTION) );
driver->setTransform(video::ETS_VIEW, ViewArea.getTransform ( video::ETS_VIEW) );
}
}
//! update
void CCameraSceneNode::updateMatrices()
{
core::vector3df pos = getAbsolutePosition();
core::vector3df tgtv = Target - pos;
tgtv.normalize();
// if upvector and vector to the target are the same, we have a
// problem. so solve this problem:
core::vector3df up = UpVector;
up.normalize();
f32 dp = tgtv.dotProduct(up);
if ( core::equals(core::abs_<f32>(dp), 1.f) )
{
up.X += 0.5f;
}
ViewArea.getTransform(video::ETS_VIEW).buildCameraLookAtMatrixLH(pos, Target, up);
ViewArea.getTransform(video::ETS_VIEW) *= Affector;
recalculateViewArea();
}
//! returns the axis aligned bounding box of this node
const core::aabbox3d<f32>& CCameraSceneNode::getBoundingBox() const
{
return BoundingBox;
}
//! returns the view frustum.
const SViewFrustum* CCameraSceneNode::getViewFrustum() const
{
return &ViewArea;
}
void CCameraSceneNode::recalculateViewArea()
{
ViewArea.cameraPosition = getAbsolutePosition();
core::matrix4 m(core::matrix4::EM4CONST_NOTHING);
m.setbyproduct_nocheck(ViewArea.getTransform(video::ETS_PROJECTION),
ViewArea.getTransform(video::ETS_VIEW));
ViewArea.setFrom(m, false);
}
//! Set the binding between the camera's rotation adn target.
void CCameraSceneNode::bindTargetAndRotation(bool bound)
{
TargetAndRotationAreBound = bound;
}
//! Gets the binding between the camera's rotation and target.
bool CCameraSceneNode::getTargetAndRotationBinding(void) const
{
return TargetAndRotationAreBound;
}
//! Creates a clone of this scene node and its children.
ISceneNode* CCameraSceneNode::clone(ISceneNode* newParent, ISceneManager* newManager)
{
ICameraSceneNode::clone(newParent, newManager);
if (!newParent)
newParent = Parent;
if (!newManager)
newManager = SceneManager;
CCameraSceneNode* nb = new CCameraSceneNode(newParent,
newManager, ID, RelativeTranslation, Target);
nb->ISceneNode::cloneMembers(this, newManager);
nb->ICameraSceneNode::cloneMembers(this);
nb->Target = Target;
nb->UpVector = UpVector;
nb->Fovy = Fovy;
nb->Aspect = Aspect;
nb->ZNear = ZNear;
nb->ZFar = ZFar;
nb->ViewArea = ViewArea;
nb->Affector = Affector;
nb->InputReceiverEnabled = InputReceiverEnabled;
nb->TargetAndRotationAreBound = TargetAndRotationAreBound;
if ( newParent )
nb->drop();
return nb;
}
} // end namespace
} // end namespace

View File

@ -1,167 +1,167 @@
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#pragma once
#include "ICameraSceneNode.h"
#include "SViewFrustum.h"
namespace irr
{
namespace scene
{
class CCameraSceneNode : public ICameraSceneNode
{
public:
//! constructor
CCameraSceneNode(ISceneNode* parent, ISceneManager* mgr, s32 id,
const core::vector3df& position = core::vector3df(0,0,0),
const core::vector3df& lookat = core::vector3df(0,0,100));
//! Sets the projection matrix of the camera.
/** The core::matrix4 class has some methods
to build a projection matrix. e.g: core::matrix4::buildProjectionMatrixPerspectiveFovLH.
Note that the matrix will only stay as set by this method until one of
the following Methods are called: setNearValue, setFarValue, setAspectRatio, setFOV.
\param projection The new projection matrix of the camera.
\param isOrthogonal Set this to true if the matrix is an orthogonal one (e.g.
from matrix4::buildProjectionMatrixOrthoLH(). */
void setProjectionMatrix(const core::matrix4& projection, bool isOrthogonal = false) override;
//! Gets the current projection matrix of the camera
//! \return Returns the current projection matrix of the camera.
const core::matrix4& getProjectionMatrix() const override;
//! Gets the current view matrix of the camera
//! \return Returns the current view matrix of the camera.
const core::matrix4& getViewMatrix() const override;
//! Sets a custom view matrix affector.
/** \param affector: The affector matrix. */
void setViewMatrixAffector(const core::matrix4& affector) override;
//! Gets the custom view matrix affector.
const core::matrix4& getViewMatrixAffector() const override;
//! It is possible to send mouse and key events to the camera. Most cameras
//! may ignore this input, but camera scene nodes which are created for
//! example with scene::ISceneManager::addMayaCameraSceneNode or
//! scene::ISceneManager::addMeshViewerCameraSceneNode, may want to get this input
//! for changing their position, look at target or whatever.
bool OnEvent(const SEvent& event) override;
//! Sets the look at target of the camera
/** If the camera's target and rotation are bound ( @see bindTargetAndRotation() )
then calling this will also change the camera's scene node rotation to match the target.
\param pos: Look at target of the camera. */
void setTarget(const core::vector3df& pos) override;
//! Sets the rotation of the node.
/** This only modifies the relative rotation of the node.
If the camera's target and rotation are bound ( @see bindTargetAndRotation() )
then calling this will also change the camera's target to match the rotation.
\param rotation New rotation of the node in degrees. */
void setRotation(const core::vector3df& rotation) override;
//! Gets the current look at target of the camera
/** \return The current look at target of the camera */
const core::vector3df& getTarget() const override;
//! Sets the up vector of the camera.
//! \param pos: New upvector of the camera.
void setUpVector(const core::vector3df& pos) override;
//! Gets the up vector of the camera.
//! \return Returns the up vector of the camera.
const core::vector3df& getUpVector() const override;
//! Gets distance from the camera to the near plane.
//! \return Value of the near plane of the camera.
f32 getNearValue() const override;
//! Gets the distance from the camera to the far plane.
//! \return Value of the far plane of the camera.
f32 getFarValue() const override;
//! Get the aspect ratio of the camera.
//! \return The aspect ratio of the camera.
f32 getAspectRatio() const override;
//! Gets the field of view of the camera.
//! \return Field of view of the camera
f32 getFOV() const override;
//! Sets the value of the near clipping plane. (default: 1.0f)
void setNearValue(f32 zn) override;
//! Sets the value of the far clipping plane (default: 2000.0f)
void setFarValue(f32 zf) override;
//! Sets the aspect ratio (default: 4.0f / 3.0f)
void setAspectRatio(f32 aspect) override;
//! Sets the field of view (Default: PI / 3.5f)
void setFOV(f32 fovy) override;
//! PreRender event
void OnRegisterSceneNode() override;
//! Render
void render() override;
//! Update
void updateMatrices() override;
//! Returns the axis aligned bounding box of this node
const core::aabbox3d<f32>& getBoundingBox() const override;
//! Returns the view area.
const SViewFrustum* getViewFrustum() const override;
//! Disables or enables the camera to get key or mouse inputs.
//! If this is set to true, the camera will respond to key inputs
//! otherwise not.
void setInputReceiverEnabled(bool enabled) override;
//! Returns if the input receiver of the camera is currently enabled.
bool isInputReceiverEnabled() const override;
//! Returns type of the scene node
ESCENE_NODE_TYPE getType() const override { return ESNT_CAMERA; }
//! Binds the camera scene node's rotation to its target position and vice versa, or unbinds them.
void bindTargetAndRotation(bool bound) override;
//! Queries if the camera scene node's rotation and its target position are bound together.
bool getTargetAndRotationBinding(void) const override;
//! Creates a clone of this scene node and its children.
ISceneNode* clone(ISceneNode* newParent=0, ISceneManager* newManager=0) override;
protected:
void recalculateProjectionMatrix();
void recalculateViewArea();
core::aabbox3d<f32> BoundingBox;
core::vector3df Target;
core::vector3df UpVector;
f32 Fovy; // Field of view, in radians.
f32 Aspect; // Aspect ratio.
f32 ZNear; // value of the near view-plane.
f32 ZFar; // Z-value of the far view-plane.
SViewFrustum ViewArea;
core::matrix4 Affector;
bool InputReceiverEnabled;
bool TargetAndRotationAreBound;
};
} // end namespace
} // end namespace
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#pragma once
#include "ICameraSceneNode.h"
#include "SViewFrustum.h"
namespace irr
{
namespace scene
{
class CCameraSceneNode : public ICameraSceneNode
{
public:
//! constructor
CCameraSceneNode(ISceneNode* parent, ISceneManager* mgr, s32 id,
const core::vector3df& position = core::vector3df(0,0,0),
const core::vector3df& lookat = core::vector3df(0,0,100));
//! Sets the projection matrix of the camera.
/** The core::matrix4 class has some methods
to build a projection matrix. e.g: core::matrix4::buildProjectionMatrixPerspectiveFovLH.
Note that the matrix will only stay as set by this method until one of
the following Methods are called: setNearValue, setFarValue, setAspectRatio, setFOV.
\param projection The new projection matrix of the camera.
\param isOrthogonal Set this to true if the matrix is an orthogonal one (e.g.
from matrix4::buildProjectionMatrixOrthoLH(). */
void setProjectionMatrix(const core::matrix4& projection, bool isOrthogonal = false) override;
//! Gets the current projection matrix of the camera
//! \return Returns the current projection matrix of the camera.
const core::matrix4& getProjectionMatrix() const override;
//! Gets the current view matrix of the camera
//! \return Returns the current view matrix of the camera.
const core::matrix4& getViewMatrix() const override;
//! Sets a custom view matrix affector.
/** \param affector: The affector matrix. */
void setViewMatrixAffector(const core::matrix4& affector) override;
//! Gets the custom view matrix affector.
const core::matrix4& getViewMatrixAffector() const override;
//! It is possible to send mouse and key events to the camera. Most cameras
//! may ignore this input, but camera scene nodes which are created for
//! example with scene::ISceneManager::addMayaCameraSceneNode or
//! scene::ISceneManager::addMeshViewerCameraSceneNode, may want to get this input
//! for changing their position, look at target or whatever.
bool OnEvent(const SEvent& event) override;
//! Sets the look at target of the camera
/** If the camera's target and rotation are bound ( @see bindTargetAndRotation() )
then calling this will also change the camera's scene node rotation to match the target.
\param pos: Look at target of the camera. */
void setTarget(const core::vector3df& pos) override;
//! Sets the rotation of the node.
/** This only modifies the relative rotation of the node.
If the camera's target and rotation are bound ( @see bindTargetAndRotation() )
then calling this will also change the camera's target to match the rotation.
\param rotation New rotation of the node in degrees. */
void setRotation(const core::vector3df& rotation) override;
//! Gets the current look at target of the camera
/** \return The current look at target of the camera */
const core::vector3df& getTarget() const override;
//! Sets the up vector of the camera.
//! \param pos: New upvector of the camera.
void setUpVector(const core::vector3df& pos) override;
//! Gets the up vector of the camera.
//! \return Returns the up vector of the camera.
const core::vector3df& getUpVector() const override;
//! Gets distance from the camera to the near plane.
//! \return Value of the near plane of the camera.
f32 getNearValue() const override;
//! Gets the distance from the camera to the far plane.
//! \return Value of the far plane of the camera.
f32 getFarValue() const override;
//! Get the aspect ratio of the camera.
//! \return The aspect ratio of the camera.
f32 getAspectRatio() const override;
//! Gets the field of view of the camera.
//! \return Field of view of the camera
f32 getFOV() const override;
//! Sets the value of the near clipping plane. (default: 1.0f)
void setNearValue(f32 zn) override;
//! Sets the value of the far clipping plane (default: 2000.0f)
void setFarValue(f32 zf) override;
//! Sets the aspect ratio (default: 4.0f / 3.0f)
void setAspectRatio(f32 aspect) override;
//! Sets the field of view (Default: PI / 3.5f)
void setFOV(f32 fovy) override;
//! PreRender event
void OnRegisterSceneNode() override;
//! Render
void render() override;
//! Update
void updateMatrices() override;
//! Returns the axis aligned bounding box of this node
const core::aabbox3d<f32>& getBoundingBox() const override;
//! Returns the view area.
const SViewFrustum* getViewFrustum() const override;
//! Disables or enables the camera to get key or mouse inputs.
//! If this is set to true, the camera will respond to key inputs
//! otherwise not.
void setInputReceiverEnabled(bool enabled) override;
//! Returns if the input receiver of the camera is currently enabled.
bool isInputReceiverEnabled() const override;
//! Returns type of the scene node
ESCENE_NODE_TYPE getType() const override { return ESNT_CAMERA; }
//! Binds the camera scene node's rotation to its target position and vice versa, or unbinds them.
void bindTargetAndRotation(bool bound) override;
//! Queries if the camera scene node's rotation and its target position are bound together.
bool getTargetAndRotationBinding(void) const override;
//! Creates a clone of this scene node and its children.
ISceneNode* clone(ISceneNode* newParent=0, ISceneManager* newManager=0) override;
protected:
void recalculateProjectionMatrix();
void recalculateViewArea();
core::aabbox3d<f32> BoundingBox;
core::vector3df Target;
core::vector3df UpVector;
f32 Fovy; // Field of view, in radians.
f32 Aspect; // Aspect ratio.
f32 ZNear; // value of the near view-plane.
f32 ZFar; // Z-value of the far view-plane.
SViewFrustum ViewArea;
core::matrix4 Affector;
bool InputReceiverEnabled;
bool TargetAndRotationAreBound;
};
} // end namespace
} // end namespace

File diff suppressed because it is too large Load Diff

View File

@ -1,98 +1,98 @@
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#pragma once
#include "irrTypes.h"
#include "IImage.h"
namespace irr
{
namespace video
{
class CColorConverter
{
public:
//! converts a monochrome bitmap to A1R5G5B5
static void convert1BitTo16Bit(const u8* in, s16* out, s32 width, s32 height, s32 linepad=0, bool flip=false);
//! converts a 4 bit palettized image to A1R5G5B5
static void convert4BitTo16Bit(const u8* in, s16* out, s32 width, s32 height, const s32* palette, s32 linepad=0, bool flip=false);
//! converts a 8 bit palettized image to A1R5G5B5
static void convert8BitTo16Bit(const u8* in, s16* out, s32 width, s32 height, const s32* palette, s32 linepad=0, bool flip=false);
//! converts a 8 bit palettized or non palettized image (A8) into R8G8B8
static void convert8BitTo24Bit(const u8* in, u8* out, s32 width, s32 height, const u8* palette, s32 linepad = 0, bool flip=false);
//! converts a 8 bit palettized or non palettized image (A8) into A8R8G8B8
static void convert8BitTo32Bit(const u8* in, u8* out, s32 width, s32 height, const u8* palette, s32 linepad = 0, bool flip=false);
//! converts R8G8B8 16 bit data to A1R5G5B5 data
static void convert16BitTo16Bit(const s16* in, s16* out, s32 width, s32 height, s32 linepad=0, bool flip=false);
//! copies R8G8B8 24 bit data to 24 data, and flips and
//! mirrors the image during the process.
static void convert24BitTo24Bit(const u8* in, u8* out, s32 width, s32 height, s32 linepad=0, bool flip=false, bool bgr=false);
//! Resizes the surface to a new size and converts it at the same time
//! to an A8R8G8B8 format, returning the pointer to the new buffer.
static void convert16bitToA8R8G8B8andResize(const s16* in, s32* out, s32 newWidth, s32 newHeight, s32 currentWidth, s32 currentHeight);
//! copies X8R8G8B8 32 bit data, and flips and
//! mirrors the image during the process.
static void convert32BitTo32Bit(const s32* in, s32* out, s32 width, s32 height, s32 linepad, bool flip=false);
//! Functions for converting one image format to another efficiently
//! and hopefully correctly.
//! Note that the format descriptions refer to the ECOLOR_FORMAT's and not to memory layout.
//! Reasons for that go back to DX9 naming which tended to flip 32-bit and 16-bit byte orders so ARGB usually means BGRA.
//!
//! \param sP pointer to source pixel data
//! \param sN number of source pixels to copy
//! \param dP pointer to destination data buffer. must be big enough
//! to hold sN pixels in the output format.
static void convert_A1R5G5B5toR8G8B8(const void* sP, s32 sN, void* dP);
static void convert_A1R5G5B5toB8G8R8(const void* sP, s32 sN, void* dP);
static void convert_A1R5G5B5toA8R8G8B8(const void* sP, s32 sN, void* dP);
static void convert_A1R5G5B5toA1R5G5B5(const void* sP, s32 sN, void* dP);
static void convert_A1R5G5B5toR5G5B5A1(const void* sP, s32 sN, void* dP);
static void convert_A1R5G5B5toR5G6B5(const void* sP, s32 sN, void* dP);
static void convert_A8R8G8B8toR8G8B8(const void* sP, s32 sN, void* dP);
static void convert_A8R8G8B8toB8G8R8(const void* sP, s32 sN, void* dP);
static void convert_A8R8G8B8toA8R8G8B8(const void* sP, s32 sN, void* dP);
static void convert_A8R8G8B8toA1R5G5B5(const void* sP, s32 sN, void* dP);
static void convert_A8R8G8B8toA1B5G5R5(const void* sP, s32 sN, void* dP);
static void convert_A8R8G8B8toR5G6B5(const void* sP, s32 sN, void* dP);
static void convert_A8R8G8B8toR3G3B2(const void* sP, s32 sN, void* dP);
static void convert_R8G8B8toR8G8B8(const void* sP, s32 sN, void* dP);
static void convert_R8G8B8toA8R8G8B8(const void* sP, s32 sN, void* dP);
static void convert_R8G8B8toA1R5G5B5(const void* sP, s32 sN, void* dP);
static void convert_R8G8B8toB8G8R8(const void* sP, s32 sN, void* dP);
static void convert_R8G8B8toR5G6B5(const void* sP, s32 sN, void* dP);
static void convert_B8G8R8toA8R8G8B8(const void* sP, s32 sN, void* dP);
static void convert_B8G8R8A8toA8R8G8B8(const void* sP, s32 sN, void* dP);
static void convert_A8R8G8B8toR8G8B8A8(const void* sP, s32 sN, void* dP);
static void convert_A8R8G8B8toA8B8G8R8(const void* sP, s32 sN, void* dP);
static void convert_R5G6B5toR5G6B5(const void* sP, s32 sN, void* dP);
static void convert_R5G6B5toR8G8B8(const void* sP, s32 sN, void* dP);
static void convert_R5G6B5toB8G8R8(const void* sP, s32 sN, void* dP);
static void convert_R5G6B5toA8R8G8B8(const void* sP, s32 sN, void* dP);
static void convert_R5G6B5toA1R5G5B5(const void* sP, s32 sN, void* dP);
static void convert_viaFormat(const void* sP, ECOLOR_FORMAT sF, s32 sN,
void* dP, ECOLOR_FORMAT dF);
// Check if convert_viaFormat is usable
static bool canConvertFormat(ECOLOR_FORMAT sourceFormat, ECOLOR_FORMAT destFormat);
};
} // end namespace video
} // end namespace irr
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#pragma once
#include "irrTypes.h"
#include "IImage.h"
namespace irr
{
namespace video
{
class CColorConverter
{
public:
//! converts a monochrome bitmap to A1R5G5B5
static void convert1BitTo16Bit(const u8* in, s16* out, s32 width, s32 height, s32 linepad=0, bool flip=false);
//! converts a 4 bit palettized image to A1R5G5B5
static void convert4BitTo16Bit(const u8* in, s16* out, s32 width, s32 height, const s32* palette, s32 linepad=0, bool flip=false);
//! converts a 8 bit palettized image to A1R5G5B5
static void convert8BitTo16Bit(const u8* in, s16* out, s32 width, s32 height, const s32* palette, s32 linepad=0, bool flip=false);
//! converts a 8 bit palettized or non palettized image (A8) into R8G8B8
static void convert8BitTo24Bit(const u8* in, u8* out, s32 width, s32 height, const u8* palette, s32 linepad = 0, bool flip=false);
//! converts a 8 bit palettized or non palettized image (A8) into A8R8G8B8
static void convert8BitTo32Bit(const u8* in, u8* out, s32 width, s32 height, const u8* palette, s32 linepad = 0, bool flip=false);
//! converts R8G8B8 16 bit data to A1R5G5B5 data
static void convert16BitTo16Bit(const s16* in, s16* out, s32 width, s32 height, s32 linepad=0, bool flip=false);
//! copies R8G8B8 24 bit data to 24 data, and flips and
//! mirrors the image during the process.
static void convert24BitTo24Bit(const u8* in, u8* out, s32 width, s32 height, s32 linepad=0, bool flip=false, bool bgr=false);
//! Resizes the surface to a new size and converts it at the same time
//! to an A8R8G8B8 format, returning the pointer to the new buffer.
static void convert16bitToA8R8G8B8andResize(const s16* in, s32* out, s32 newWidth, s32 newHeight, s32 currentWidth, s32 currentHeight);
//! copies X8R8G8B8 32 bit data, and flips and
//! mirrors the image during the process.
static void convert32BitTo32Bit(const s32* in, s32* out, s32 width, s32 height, s32 linepad, bool flip=false);
//! Functions for converting one image format to another efficiently
//! and hopefully correctly.
//! Note that the format descriptions refer to the ECOLOR_FORMAT's and not to memory layout.
//! Reasons for that go back to DX9 naming which tended to flip 32-bit and 16-bit byte orders so ARGB usually means BGRA.
//!
//! \param sP pointer to source pixel data
//! \param sN number of source pixels to copy
//! \param dP pointer to destination data buffer. must be big enough
//! to hold sN pixels in the output format.
static void convert_A1R5G5B5toR8G8B8(const void* sP, s32 sN, void* dP);
static void convert_A1R5G5B5toB8G8R8(const void* sP, s32 sN, void* dP);
static void convert_A1R5G5B5toA8R8G8B8(const void* sP, s32 sN, void* dP);
static void convert_A1R5G5B5toA1R5G5B5(const void* sP, s32 sN, void* dP);
static void convert_A1R5G5B5toR5G5B5A1(const void* sP, s32 sN, void* dP);
static void convert_A1R5G5B5toR5G6B5(const void* sP, s32 sN, void* dP);
static void convert_A8R8G8B8toR8G8B8(const void* sP, s32 sN, void* dP);
static void convert_A8R8G8B8toB8G8R8(const void* sP, s32 sN, void* dP);
static void convert_A8R8G8B8toA8R8G8B8(const void* sP, s32 sN, void* dP);
static void convert_A8R8G8B8toA1R5G5B5(const void* sP, s32 sN, void* dP);
static void convert_A8R8G8B8toA1B5G5R5(const void* sP, s32 sN, void* dP);
static void convert_A8R8G8B8toR5G6B5(const void* sP, s32 sN, void* dP);
static void convert_A8R8G8B8toR3G3B2(const void* sP, s32 sN, void* dP);
static void convert_R8G8B8toR8G8B8(const void* sP, s32 sN, void* dP);
static void convert_R8G8B8toA8R8G8B8(const void* sP, s32 sN, void* dP);
static void convert_R8G8B8toA1R5G5B5(const void* sP, s32 sN, void* dP);
static void convert_R8G8B8toB8G8R8(const void* sP, s32 sN, void* dP);
static void convert_R8G8B8toR5G6B5(const void* sP, s32 sN, void* dP);
static void convert_B8G8R8toA8R8G8B8(const void* sP, s32 sN, void* dP);
static void convert_B8G8R8A8toA8R8G8B8(const void* sP, s32 sN, void* dP);
static void convert_A8R8G8B8toR8G8B8A8(const void* sP, s32 sN, void* dP);
static void convert_A8R8G8B8toA8B8G8R8(const void* sP, s32 sN, void* dP);
static void convert_R5G6B5toR5G6B5(const void* sP, s32 sN, void* dP);
static void convert_R5G6B5toR8G8B8(const void* sP, s32 sN, void* dP);
static void convert_R5G6B5toB8G8R8(const void* sP, s32 sN, void* dP);
static void convert_R5G6B5toA8R8G8B8(const void* sP, s32 sN, void* dP);
static void convert_R5G6B5toA1R5G5B5(const void* sP, s32 sN, void* dP);
static void convert_viaFormat(const void* sP, ECOLOR_FORMAT sF, s32 sN,
void* dP, ECOLOR_FORMAT dF);
// Check if convert_viaFormat is usable
static bool canConvertFormat(ECOLOR_FORMAT sourceFormat, ECOLOR_FORMAT destFormat);
};
} // end namespace video
} // end namespace irr

View File

@ -1,105 +1,105 @@
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#include "CDummyTransformationSceneNode.h"
#include "os.h"
namespace irr
{
namespace scene
{
//! constructor
CDummyTransformationSceneNode::CDummyTransformationSceneNode(
ISceneNode* parent, ISceneManager* mgr, s32 id)
: IDummyTransformationSceneNode(parent, mgr, id)
{
#ifdef _DEBUG
setDebugName("CDummyTransformationSceneNode");
#endif
setAutomaticCulling(scene::EAC_OFF);
}
//! returns the axis aligned bounding box of this node
const core::aabbox3d<f32>& CDummyTransformationSceneNode::getBoundingBox() const
{
return Box;
}
//! Returns a reference to the current relative transformation matrix.
//! This is the matrix, this scene node uses instead of scale, translation
//! and rotation.
core::matrix4& CDummyTransformationSceneNode::getRelativeTransformationMatrix()
{
return RelativeTransformationMatrix;
}
//! Returns the relative transformation of the scene node.
core::matrix4 CDummyTransformationSceneNode::getRelativeTransformation() const
{
return RelativeTransformationMatrix;
}
//! Creates a clone of this scene node and its children.
ISceneNode* CDummyTransformationSceneNode::clone(ISceneNode* newParent, ISceneManager* newManager)
{
if (!newParent)
newParent = Parent;
if (!newManager)
newManager = SceneManager;
CDummyTransformationSceneNode* nb = new CDummyTransformationSceneNode(newParent,
newManager, ID);
nb->cloneMembers(this, newManager);
nb->RelativeTransformationMatrix = RelativeTransformationMatrix;
nb->Box = Box;
if ( newParent )
nb->drop();
return nb;
}
const core::vector3df& CDummyTransformationSceneNode::getScale() const
{
os::Printer::log("CDummyTransformationSceneNode::getScale() does not contain the relative transformation.", ELL_DEBUG);
return RelativeScale;
}
void CDummyTransformationSceneNode::setScale(const core::vector3df& scale)
{
os::Printer::log("CDummyTransformationSceneNode::setScale() does not affect the relative transformation.", ELL_DEBUG);
RelativeScale = scale;
}
const core::vector3df& CDummyTransformationSceneNode::getRotation() const
{
os::Printer::log("CDummyTransformationSceneNode::getRotation() does not contain the relative transformation.", ELL_DEBUG);
return RelativeRotation;
}
void CDummyTransformationSceneNode::setRotation(const core::vector3df& rotation)
{
os::Printer::log("CDummyTransformationSceneNode::setRotation() does not affect the relative transformation.", ELL_DEBUG);
RelativeRotation = rotation;
}
const core::vector3df& CDummyTransformationSceneNode::getPosition() const
{
os::Printer::log("CDummyTransformationSceneNode::getPosition() does not contain the relative transformation.", ELL_DEBUG);
return RelativeTranslation;
}
void CDummyTransformationSceneNode::setPosition(const core::vector3df& newpos)
{
os::Printer::log("CDummyTransformationSceneNode::setPosition() does not affect the relative transformation.", ELL_DEBUG);
RelativeTranslation = newpos;
}
} // end namespace scene
} // end namespace irr
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#include "CDummyTransformationSceneNode.h"
#include "os.h"
namespace irr
{
namespace scene
{
//! constructor
CDummyTransformationSceneNode::CDummyTransformationSceneNode(
ISceneNode* parent, ISceneManager* mgr, s32 id)
: IDummyTransformationSceneNode(parent, mgr, id)
{
#ifdef _DEBUG
setDebugName("CDummyTransformationSceneNode");
#endif
setAutomaticCulling(scene::EAC_OFF);
}
//! returns the axis aligned bounding box of this node
const core::aabbox3d<f32>& CDummyTransformationSceneNode::getBoundingBox() const
{
return Box;
}
//! Returns a reference to the current relative transformation matrix.
//! This is the matrix, this scene node uses instead of scale, translation
//! and rotation.
core::matrix4& CDummyTransformationSceneNode::getRelativeTransformationMatrix()
{
return RelativeTransformationMatrix;
}
//! Returns the relative transformation of the scene node.
core::matrix4 CDummyTransformationSceneNode::getRelativeTransformation() const
{
return RelativeTransformationMatrix;
}
//! Creates a clone of this scene node and its children.
ISceneNode* CDummyTransformationSceneNode::clone(ISceneNode* newParent, ISceneManager* newManager)
{
if (!newParent)
newParent = Parent;
if (!newManager)
newManager = SceneManager;
CDummyTransformationSceneNode* nb = new CDummyTransformationSceneNode(newParent,
newManager, ID);
nb->cloneMembers(this, newManager);
nb->RelativeTransformationMatrix = RelativeTransformationMatrix;
nb->Box = Box;
if ( newParent )
nb->drop();
return nb;
}
const core::vector3df& CDummyTransformationSceneNode::getScale() const
{
os::Printer::log("CDummyTransformationSceneNode::getScale() does not contain the relative transformation.", ELL_DEBUG);
return RelativeScale;
}
void CDummyTransformationSceneNode::setScale(const core::vector3df& scale)
{
os::Printer::log("CDummyTransformationSceneNode::setScale() does not affect the relative transformation.", ELL_DEBUG);
RelativeScale = scale;
}
const core::vector3df& CDummyTransformationSceneNode::getRotation() const
{
os::Printer::log("CDummyTransformationSceneNode::getRotation() does not contain the relative transformation.", ELL_DEBUG);
return RelativeRotation;
}
void CDummyTransformationSceneNode::setRotation(const core::vector3df& rotation)
{
os::Printer::log("CDummyTransformationSceneNode::setRotation() does not affect the relative transformation.", ELL_DEBUG);
RelativeRotation = rotation;
}
const core::vector3df& CDummyTransformationSceneNode::getPosition() const
{
os::Printer::log("CDummyTransformationSceneNode::getPosition() does not contain the relative transformation.", ELL_DEBUG);
return RelativeTranslation;
}
void CDummyTransformationSceneNode::setPosition(const core::vector3df& newpos)
{
os::Printer::log("CDummyTransformationSceneNode::setPosition() does not affect the relative transformation.", ELL_DEBUG);
RelativeTranslation = newpos;
}
} // end namespace scene
} // end namespace irr

View File

@ -1,59 +1,59 @@
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#pragma once
#include "IDummyTransformationSceneNode.h"
namespace irr
{
namespace scene
{
class CDummyTransformationSceneNode : public IDummyTransformationSceneNode
{
public:
//! constructor
CDummyTransformationSceneNode(ISceneNode* parent, ISceneManager* mgr, s32 id);
//! returns the axis aligned bounding box of this node
const core::aabbox3d<f32>& getBoundingBox() const override;
//! Returns a reference to the current relative transformation matrix.
//! This is the matrix, this scene node uses instead of scale, translation
//! and rotation.
core::matrix4& getRelativeTransformationMatrix() override;
//! Returns the relative transformation of the scene node.
core::matrix4 getRelativeTransformation() const override;
//! does nothing.
void render() override {}
//! Returns type of the scene node
ESCENE_NODE_TYPE getType() const override { return ESNT_DUMMY_TRANSFORMATION; }
//! Creates a clone of this scene node and its children.
ISceneNode* clone(ISceneNode* newParent=0, ISceneManager* newManager=0) override;
private:
// TODO: We can add least add some warnings to find troubles faster until we have
// fixed bug id 2318691.
const core::vector3df& getScale() const override;
void setScale(const core::vector3df& scale) override;
const core::vector3df& getRotation() const override;
void setRotation(const core::vector3df& rotation) override;
const core::vector3df& getPosition() const override;
void setPosition(const core::vector3df& newpos) override;
core::matrix4 RelativeTransformationMatrix;
core::aabbox3d<f32> Box;
};
} // end namespace scene
} // end namespace irr
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#pragma once
#include "IDummyTransformationSceneNode.h"
namespace irr
{
namespace scene
{
class CDummyTransformationSceneNode : public IDummyTransformationSceneNode
{
public:
//! constructor
CDummyTransformationSceneNode(ISceneNode* parent, ISceneManager* mgr, s32 id);
//! returns the axis aligned bounding box of this node
const core::aabbox3d<f32>& getBoundingBox() const override;
//! Returns a reference to the current relative transformation matrix.
//! This is the matrix, this scene node uses instead of scale, translation
//! and rotation.
core::matrix4& getRelativeTransformationMatrix() override;
//! Returns the relative transformation of the scene node.
core::matrix4 getRelativeTransformation() const override;
//! does nothing.
void render() override {}
//! Returns type of the scene node
ESCENE_NODE_TYPE getType() const override { return ESNT_DUMMY_TRANSFORMATION; }
//! Creates a clone of this scene node and its children.
ISceneNode* clone(ISceneNode* newParent=0, ISceneManager* newManager=0) override;
private:
// TODO: We can add least add some warnings to find troubles faster until we have
// fixed bug id 2318691.
const core::vector3df& getScale() const override;
void setScale(const core::vector3df& scale) override;
const core::vector3df& getRotation() const override;
void setRotation(const core::vector3df& rotation) override;
const core::vector3df& getPosition() const override;
void setPosition(const core::vector3df& newpos) override;
core::matrix4 RelativeTransformationMatrix;
core::aabbox3d<f32> Box;
};
} // end namespace scene
} // end namespace irr

File diff suppressed because it is too large Load Diff

View File

@ -1,111 +1,111 @@
// Copyright (C) 2013 Patryk Nadrowski
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in Irrlicht.h
#pragma once
#include <EGL/egl.h>
#include "SIrrCreationParameters.h"
#include "SExposedVideoData.h"
#include "IContextManager.h"
namespace irr
{
namespace video
{
// EGL manager.
class CEGLManager : public IContextManager
{
public:
//! Constructor.
CEGLManager();
//! Destructor.
virtual ~CEGLManager();
// Initialize EGL.
/* This method initialize EGLand create EGL display, anyway surface and context
aren't create. */
bool initialize(const SIrrlichtCreationParameters& params, const SExposedVideoData& data) override;
// Terminate EGL.
/* Terminate EGL context. This method break both existed surface and context. */
void terminate() override;
// Create EGL surface.
/* This method create EGL surface. On some platforms eg. Android, we must
recreate surface on each resume, because WindowID may change, so existed
surface may not be valid. If EGL context already exist, this method
automatically activates it. */
bool generateSurface() override;
// Destroy EGL surface.
/* This method destroy EGL. On some platforms eg. Android, we should call
this method on each pause, because after resume this surface may not be valid.
Hovewer this method doesn'r break EGL context. */
void destroySurface() override;
// Create EGL context.
/* This method create and activate EGL context. */
bool generateContext() override;
// Destroy EGL context.
/* This method destroy EGL context. */
void destroyContext() override;
const SExposedVideoData& getContext() const override;
bool activateContext(const SExposedVideoData& videoData, bool restorePrimaryOnZero) override;
// Get procedure address.
void* getProcAddress(const std::string &procName) override;
// Swap buffers.
bool swapBuffers() override;
protected:
enum EConfigStyle
{
//! Get first result of eglChooseConfigs and if that fails try again by requesting simpler attributes
ECS_EGL_CHOOSE_FIRST_LOWER_EXPECTATIONS,
//! We select our own best fit and avoid using eglChooseConfigs
ECS_IRR_CHOOSE,
};
EGLConfig chooseConfig(EConfigStyle confStyle);
//! Check how close this config is to the parameters we requested
//! returns 0 is perfect, larger values are worse and < 0 is unusable.
irr::s32 rateConfig(EGLConfig config, EGLint eglOpenGLBIT, bool log=false);
// Helper to sort EGLConfig's. (because we got no std::pair....)
struct SConfigRating
{
EGLConfig config;
irr::s32 rating;
bool operator<(const SConfigRating& other) const
{
return rating < other.rating;
}
};
private:
bool testEGLError();
NativeWindowType EglWindow;
EGLDisplay EglDisplay;
EGLSurface EglSurface;
EGLContext EglContext;
EGLConfig EglConfig;
SIrrlichtCreationParameters Params;
SExposedVideoData Data;
EGLint MajorVersion;
EGLint MinorVersion;
};
}
}
// Copyright (C) 2013 Patryk Nadrowski
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in Irrlicht.h
#pragma once
#include <EGL/egl.h>
#include "SIrrCreationParameters.h"
#include "SExposedVideoData.h"
#include "IContextManager.h"
namespace irr
{
namespace video
{
// EGL manager.
class CEGLManager : public IContextManager
{
public:
//! Constructor.
CEGLManager();
//! Destructor.
virtual ~CEGLManager();
// Initialize EGL.
/* This method initialize EGLand create EGL display, anyway surface and context
aren't create. */
bool initialize(const SIrrlichtCreationParameters& params, const SExposedVideoData& data) override;
// Terminate EGL.
/* Terminate EGL context. This method break both existed surface and context. */
void terminate() override;
// Create EGL surface.
/* This method create EGL surface. On some platforms eg. Android, we must
recreate surface on each resume, because WindowID may change, so existed
surface may not be valid. If EGL context already exist, this method
automatically activates it. */
bool generateSurface() override;
// Destroy EGL surface.
/* This method destroy EGL. On some platforms eg. Android, we should call
this method on each pause, because after resume this surface may not be valid.
Hovewer this method doesn'r break EGL context. */
void destroySurface() override;
// Create EGL context.
/* This method create and activate EGL context. */
bool generateContext() override;
// Destroy EGL context.
/* This method destroy EGL context. */
void destroyContext() override;
const SExposedVideoData& getContext() const override;
bool activateContext(const SExposedVideoData& videoData, bool restorePrimaryOnZero) override;
// Get procedure address.
void* getProcAddress(const std::string &procName) override;
// Swap buffers.
bool swapBuffers() override;
protected:
enum EConfigStyle
{
//! Get first result of eglChooseConfigs and if that fails try again by requesting simpler attributes
ECS_EGL_CHOOSE_FIRST_LOWER_EXPECTATIONS,
//! We select our own best fit and avoid using eglChooseConfigs
ECS_IRR_CHOOSE,
};
EGLConfig chooseConfig(EConfigStyle confStyle);
//! Check how close this config is to the parameters we requested
//! returns 0 is perfect, larger values are worse and < 0 is unusable.
irr::s32 rateConfig(EGLConfig config, EGLint eglOpenGLBIT, bool log=false);
// Helper to sort EGLConfig's. (because we got no std::pair....)
struct SConfigRating
{
EGLConfig config;
irr::s32 rating;
bool operator<(const SConfigRating& other) const
{
return rating < other.rating;
}
};
private:
bool testEGLError();
NativeWindowType EglWindow;
EGLDisplay EglDisplay;
EGLSurface EglSurface;
EGLContext EglContext;
EGLConfig EglConfig;
SIrrlichtCreationParameters Params;
SExposedVideoData Data;
EGLint MajorVersion;
EGLint MinorVersion;
};
}
}

View File

@ -1,70 +1,70 @@
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#include "CEmptySceneNode.h"
#include "ISceneManager.h"
namespace irr
{
namespace scene
{
//! constructor
CEmptySceneNode::CEmptySceneNode(ISceneNode* parent, ISceneManager* mgr, s32 id)
: ISceneNode(parent, mgr, id)
{
#ifdef _DEBUG
setDebugName("CEmptySceneNode");
#endif
setAutomaticCulling(scene::EAC_OFF);
}
//! pre render event
void CEmptySceneNode::OnRegisterSceneNode()
{
if (IsVisible)
SceneManager->registerNodeForRendering(this);
ISceneNode::OnRegisterSceneNode();
}
//! render
void CEmptySceneNode::render()
{
// do nothing
}
//! returns the axis aligned bounding box of this node
const core::aabbox3d<f32>& CEmptySceneNode::getBoundingBox() const
{
return Box;
}
//! Creates a clone of this scene node and its children.
ISceneNode* CEmptySceneNode::clone(ISceneNode* newParent, ISceneManager* newManager)
{
if (!newParent)
newParent = Parent;
if (!newManager)
newManager = SceneManager;
CEmptySceneNode* nb = new CEmptySceneNode(newParent,
newManager, ID);
nb->cloneMembers(this, newManager);
nb->Box = Box;
if ( newParent )
nb->drop();
return nb;
}
} // end namespace scene
} // end namespace irr
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#include "CEmptySceneNode.h"
#include "ISceneManager.h"
namespace irr
{
namespace scene
{
//! constructor
CEmptySceneNode::CEmptySceneNode(ISceneNode* parent, ISceneManager* mgr, s32 id)
: ISceneNode(parent, mgr, id)
{
#ifdef _DEBUG
setDebugName("CEmptySceneNode");
#endif
setAutomaticCulling(scene::EAC_OFF);
}
//! pre render event
void CEmptySceneNode::OnRegisterSceneNode()
{
if (IsVisible)
SceneManager->registerNodeForRendering(this);
ISceneNode::OnRegisterSceneNode();
}
//! render
void CEmptySceneNode::render()
{
// do nothing
}
//! returns the axis aligned bounding box of this node
const core::aabbox3d<f32>& CEmptySceneNode::getBoundingBox() const
{
return Box;
}
//! Creates a clone of this scene node and its children.
ISceneNode* CEmptySceneNode::clone(ISceneNode* newParent, ISceneManager* newManager)
{
if (!newParent)
newParent = Parent;
if (!newManager)
newManager = SceneManager;
CEmptySceneNode* nb = new CEmptySceneNode(newParent,
newManager, ID);
nb->cloneMembers(this, newManager);
nb->Box = Box;
if ( newParent )
nb->drop();
return nb;
}
} // end namespace scene
} // end namespace irr

View File

@ -1,42 +1,42 @@
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#pragma once
#include "ISceneNode.h"
namespace irr
{
namespace scene
{
class CEmptySceneNode : public ISceneNode
{
public:
//! constructor
CEmptySceneNode(ISceneNode* parent, ISceneManager* mgr, s32 id);
//! returns the axis aligned bounding box of this node
const core::aabbox3d<f32>& getBoundingBox() const override;
//! This method is called just before the rendering process of the whole scene.
void OnRegisterSceneNode() override;
//! does nothing.
void render() override;
//! Returns type of the scene node
ESCENE_NODE_TYPE getType() const override { return ESNT_EMPTY; }
//! Creates a clone of this scene node and its children.
ISceneNode* clone(ISceneNode* newParent=0, ISceneManager* newManager=0) override;
private:
core::aabbox3d<f32> Box;
};
} // end namespace scene
} // end namespace irr
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#pragma once
#include "ISceneNode.h"
namespace irr
{
namespace scene
{
class CEmptySceneNode : public ISceneNode
{
public:
//! constructor
CEmptySceneNode(ISceneNode* parent, ISceneManager* mgr, s32 id);
//! returns the axis aligned bounding box of this node
const core::aabbox3d<f32>& getBoundingBox() const override;
//! This method is called just before the rendering process of the whole scene.
void OnRegisterSceneNode() override;
//! does nothing.
void render() override;
//! Returns type of the scene node
ESCENE_NODE_TYPE getType() const override { return ESNT_EMPTY; }
//! Creates a clone of this scene node and its children.
ISceneNode* clone(ISceneNode* newParent=0, ISceneManager* newManager=0) override;
private:
core::aabbox3d<f32> Box;
};
} // end namespace scene
} // end namespace irr

View File

@ -1,76 +1,76 @@
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#include "CFPSCounter.h"
#include "irrMath.h"
namespace irr
{
namespace video
{
CFPSCounter::CFPSCounter()
: FPS(60), Primitive(0), StartTime(0), FramesCounted(0),
PrimitivesCounted(0), PrimitiveAverage(0), PrimitiveTotal(0)
{
}
//! returns current fps
s32 CFPSCounter::getFPS() const
{
return FPS;
}
//! returns current primitive count
u32 CFPSCounter::getPrimitive() const
{
return Primitive;
}
//! returns average primitive count of last period
u32 CFPSCounter::getPrimitiveAverage() const
{
return PrimitiveAverage;
}
//! returns accumulated primitive count since start
u32 CFPSCounter::getPrimitiveTotal() const
{
return PrimitiveTotal;
}
//! to be called every frame
void CFPSCounter::registerFrame(u32 now, u32 primitivesDrawn)
{
++FramesCounted;
PrimitiveTotal += primitivesDrawn;
PrimitivesCounted += primitivesDrawn;
Primitive = primitivesDrawn;
const u32 milliseconds = now - StartTime;
if (milliseconds >= 1500 )
{
const f32 invMilli = core::reciprocal ( (f32) milliseconds );
FPS = core::ceil32 ( ( 1000 * FramesCounted ) * invMilli );
PrimitiveAverage = core::ceil32 ( ( 1000 * PrimitivesCounted ) * invMilli );
FramesCounted = 0;
PrimitivesCounted = 0;
StartTime = now;
}
}
} // end namespace video
} // end namespace irr
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#include "CFPSCounter.h"
#include "irrMath.h"
namespace irr
{
namespace video
{
CFPSCounter::CFPSCounter()
: FPS(60), Primitive(0), StartTime(0), FramesCounted(0),
PrimitivesCounted(0), PrimitiveAverage(0), PrimitiveTotal(0)
{
}
//! returns current fps
s32 CFPSCounter::getFPS() const
{
return FPS;
}
//! returns current primitive count
u32 CFPSCounter::getPrimitive() const
{
return Primitive;
}
//! returns average primitive count of last period
u32 CFPSCounter::getPrimitiveAverage() const
{
return PrimitiveAverage;
}
//! returns accumulated primitive count since start
u32 CFPSCounter::getPrimitiveTotal() const
{
return PrimitiveTotal;
}
//! to be called every frame
void CFPSCounter::registerFrame(u32 now, u32 primitivesDrawn)
{
++FramesCounted;
PrimitiveTotal += primitivesDrawn;
PrimitivesCounted += primitivesDrawn;
Primitive = primitivesDrawn;
const u32 milliseconds = now - StartTime;
if (milliseconds >= 1500 )
{
const f32 invMilli = core::reciprocal ( (f32) milliseconds );
FPS = core::ceil32 ( ( 1000 * FramesCounted ) * invMilli );
PrimitiveAverage = core::ceil32 ( ( 1000 * PrimitivesCounted ) * invMilli );
FramesCounted = 0;
PrimitivesCounted = 0;
StartTime = now;
}
}
} // end namespace video
} // end namespace irr

View File

@ -1,49 +1,49 @@
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#pragma once
#include "irrTypes.h"
namespace irr
{
namespace video
{
class CFPSCounter
{
public:
CFPSCounter();
//! returns current fps
s32 getFPS() const;
//! returns primitive count
u32 getPrimitive() const;
//! returns average primitive count of last period
u32 getPrimitiveAverage() const;
//! returns accumulated primitive count since start
u32 getPrimitiveTotal() const;
//! to be called every frame
void registerFrame(u32 now, u32 primitive);
private:
s32 FPS;
u32 Primitive;
u32 StartTime;
u32 FramesCounted;
u32 PrimitivesCounted;
u32 PrimitiveAverage;
u32 PrimitiveTotal;
};
} // end namespace video
} // end namespace irr
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#pragma once
#include "irrTypes.h"
namespace irr
{
namespace video
{
class CFPSCounter
{
public:
CFPSCounter();
//! returns current fps
s32 getFPS() const;
//! returns primitive count
u32 getPrimitive() const;
//! returns average primitive count of last period
u32 getPrimitiveAverage() const;
//! returns accumulated primitive count since start
u32 getPrimitiveTotal() const;
//! to be called every frame
void registerFrame(u32 now, u32 primitive);
private:
s32 FPS;
u32 Primitive;
u32 StartTime;
u32 FramesCounted;
u32 PrimitivesCounted;
u32 PrimitiveAverage;
u32 PrimitiveTotal;
};
} // end namespace video
} // end namespace irr

View File

@ -1,162 +1,162 @@
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#include "CFileList.h"
#include "irrArray.h"
#include "coreutil.h"
#include "os.h"
namespace irr
{
namespace io
{
static const io::path emptyFileListEntry;
CFileList::CFileList(const io::path& path, bool ignoreCase, bool ignorePaths)
: IgnorePaths(ignorePaths), IgnoreCase(ignoreCase), Path(path)
{
#ifdef _DEBUG
setDebugName("CFileList");
#endif
Path.replace('\\', '/');
}
CFileList::~CFileList()
{
Files.clear();
}
u32 CFileList::getFileCount() const
{
return Files.size();
}
void CFileList::sort()
{
Files.sort();
}
const io::path& CFileList::getFileName(u32 index) const
{
if (index >= Files.size())
return emptyFileListEntry;
return Files[index].Name;
}
//! Gets the full name of a file in the list, path included, based on an index.
const io::path& CFileList::getFullFileName(u32 index) const
{
if (index >= Files.size())
return emptyFileListEntry;
return Files[index].FullName;
}
//! adds a file or folder
u32 CFileList::addItem(const io::path& fullPath, u32 offset, u32 size, bool isDirectory, u32 id)
{
SFileListEntry entry;
entry.ID = id ? id : Files.size();
entry.Offset = offset;
entry.Size = size;
entry.Name = fullPath;
entry.Name.replace('\\', '/');
entry.IsDirectory = isDirectory;
// remove trailing slash
if (entry.Name.lastChar() == '/')
{
entry.IsDirectory = true;
entry.Name[entry.Name.size()-1] = 0;
entry.Name.validate();
}
if (IgnoreCase)
entry.Name.make_lower();
entry.FullName = entry.Name;
core::deletePathFromFilename(entry.Name);
if (IgnorePaths)
entry.FullName = entry.Name;
//os::Printer::log(Path.c_str(), entry.FullName);
Files.push_back(entry);
return Files.size() - 1;
}
//! Returns the ID of a file in the file list, based on an index.
u32 CFileList::getID(u32 index) const
{
return index < Files.size() ? Files[index].ID : 0;
}
bool CFileList::isDirectory(u32 index) const
{
bool ret = false;
if (index < Files.size())
ret = Files[index].IsDirectory;
return ret;
}
//! Returns the size of a file
u32 CFileList::getFileSize(u32 index) const
{
return index < Files.size() ? Files[index].Size : 0;
}
u32 CFileList::getFileOffset(u32 index) const
{
return index < Files.size() ? Files[index].Offset : 0;
}
//! Searches for a file or folder within the list, returns the index
s32 CFileList::findFile(const io::path& filename, bool isDirectory = false) const
{
SFileListEntry entry;
// we only need FullName to be set for the search
entry.FullName = filename;
entry.IsDirectory = isDirectory;
// exchange
entry.FullName.replace('\\', '/');
// remove trailing slash
if (entry.FullName.lastChar() == '/')
{
entry.IsDirectory = true;
entry.FullName[entry.FullName.size()-1] = 0;
entry.FullName.validate();
}
if (IgnoreCase)
entry.FullName.make_lower();
if (IgnorePaths)
core::deletePathFromFilename(entry.FullName);
return Files.binary_search(entry);
}
//! Returns the base path of the file list
const io::path& CFileList::getPath() const
{
return Path;
}
} // end namespace irr
} // end namespace io
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#include "CFileList.h"
#include "irrArray.h"
#include "coreutil.h"
#include "os.h"
namespace irr
{
namespace io
{
static const io::path emptyFileListEntry;
CFileList::CFileList(const io::path& path, bool ignoreCase, bool ignorePaths)
: IgnorePaths(ignorePaths), IgnoreCase(ignoreCase), Path(path)
{
#ifdef _DEBUG
setDebugName("CFileList");
#endif
Path.replace('\\', '/');
}
CFileList::~CFileList()
{
Files.clear();
}
u32 CFileList::getFileCount() const
{
return Files.size();
}
void CFileList::sort()
{
Files.sort();
}
const io::path& CFileList::getFileName(u32 index) const
{
if (index >= Files.size())
return emptyFileListEntry;
return Files[index].Name;
}
//! Gets the full name of a file in the list, path included, based on an index.
const io::path& CFileList::getFullFileName(u32 index) const
{
if (index >= Files.size())
return emptyFileListEntry;
return Files[index].FullName;
}
//! adds a file or folder
u32 CFileList::addItem(const io::path& fullPath, u32 offset, u32 size, bool isDirectory, u32 id)
{
SFileListEntry entry;
entry.ID = id ? id : Files.size();
entry.Offset = offset;
entry.Size = size;
entry.Name = fullPath;
entry.Name.replace('\\', '/');
entry.IsDirectory = isDirectory;
// remove trailing slash
if (entry.Name.lastChar() == '/')
{
entry.IsDirectory = true;
entry.Name[entry.Name.size()-1] = 0;
entry.Name.validate();
}
if (IgnoreCase)
entry.Name.make_lower();
entry.FullName = entry.Name;
core::deletePathFromFilename(entry.Name);
if (IgnorePaths)
entry.FullName = entry.Name;
//os::Printer::log(Path.c_str(), entry.FullName);
Files.push_back(entry);
return Files.size() - 1;
}
//! Returns the ID of a file in the file list, based on an index.
u32 CFileList::getID(u32 index) const
{
return index < Files.size() ? Files[index].ID : 0;
}
bool CFileList::isDirectory(u32 index) const
{
bool ret = false;
if (index < Files.size())
ret = Files[index].IsDirectory;
return ret;
}
//! Returns the size of a file
u32 CFileList::getFileSize(u32 index) const
{
return index < Files.size() ? Files[index].Size : 0;
}
u32 CFileList::getFileOffset(u32 index) const
{
return index < Files.size() ? Files[index].Offset : 0;
}
//! Searches for a file or folder within the list, returns the index
s32 CFileList::findFile(const io::path& filename, bool isDirectory = false) const
{
SFileListEntry entry;
// we only need FullName to be set for the search
entry.FullName = filename;
entry.IsDirectory = isDirectory;
// exchange
entry.FullName.replace('\\', '/');
// remove trailing slash
if (entry.FullName.lastChar() == '/')
{
entry.IsDirectory = true;
entry.FullName[entry.FullName.size()-1] = 0;
entry.FullName.validate();
}
if (IgnoreCase)
entry.FullName.make_lower();
if (IgnorePaths)
core::deletePathFromFilename(entry.FullName);
return Files.binary_search(entry);
}
//! Returns the base path of the file list
const io::path& CFileList::getPath() const
{
return Path;
}
} // end namespace irr
} // end namespace io

View File

@ -1,133 +1,133 @@
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#pragma once
#include "IFileList.h"
#include "irrString.h"
#include "irrArray.h"
namespace irr
{
namespace io
{
//! An entry in a list of files, can be a folder or a file.
struct SFileListEntry
{
//! The name of the file
/** If this is a file or folder in the virtual filesystem and the archive
was created with the ignoreCase flag then the file name will be lower case. */
io::path Name;
//! The name of the file including the path
/** If this is a file or folder in the virtual filesystem and the archive was
created with the ignoreDirs flag then it will be the same as Name. */
io::path FullName;
//! The size of the file in bytes
u32 Size;
//! The ID of the file in an archive
/** This is used to link the FileList entry to extra info held about this
file in an archive, which can hold things like data offset and CRC. */
u32 ID;
//! FileOffset inside an archive
u32 Offset;
//! True if this is a folder, false if not.
bool IsDirectory;
//! The == operator is provided so that CFileList can slowly search the list!
bool operator ==(const struct SFileListEntry& other) const
{
if (IsDirectory != other.IsDirectory)
return false;
return FullName.equals_ignore_case(other.FullName);
}
//! The < operator is provided so that CFileList can sort and quickly search the list.
bool operator <(const struct SFileListEntry& other) const
{
if (IsDirectory != other.IsDirectory)
return IsDirectory;
return FullName.lower_ignore_case(other.FullName);
}
};
//! Implementation of a file list
class CFileList : public IFileList
{
public:
// CFileList methods
//! Constructor
/** \param path The path of this file archive */
CFileList(const io::path& path, bool ignoreCase, bool ignorePaths);
//! Destructor
virtual ~CFileList();
//! Add as a file or folder to the list
/** \param fullPath The file name including path, up to the root of the file list.
\param isDirectory True if this is a directory rather than a file.
\param offset The offset where the file is stored in an archive
\param size The size of the file in bytes.
\param id The ID of the file in the archive which owns it */
u32 addItem(const io::path& fullPath, u32 offset, u32 size, bool isDirectory, u32 id=0) override;
//! Sorts the file list. You should call this after adding any items to the file list
void sort() override;
//! Returns the amount of files in the filelist.
u32 getFileCount() const override;
//! Gets the name of a file in the list, based on an index.
const io::path& getFileName(u32 index) const override;
//! Gets the full name of a file in the list, path included, based on an index.
const io::path& getFullFileName(u32 index) const override;
//! Returns the ID of a file in the file list, based on an index.
u32 getID(u32 index) const override;
//! Returns true if the file is a directory
bool isDirectory(u32 index) const override;
//! Returns the size of a file
u32 getFileSize(u32 index) const override;
//! Returns the offset of a file
u32 getFileOffset(u32 index) const override;
//! Searches for a file or folder within the list, returns the index
s32 findFile(const io::path& filename, bool isFolder) const override;
//! Returns the base path of the file list
const io::path& getPath() const override;
protected:
//! Ignore paths when adding or searching for files
bool IgnorePaths;
//! Ignore case when adding or searching for files
bool IgnoreCase;
//! Path to the file list
io::path Path;
//! List of files
core::array<SFileListEntry> Files;
};
} // end namespace irr
} // end namespace io
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#pragma once
#include "IFileList.h"
#include "irrString.h"
#include "irrArray.h"
namespace irr
{
namespace io
{
//! An entry in a list of files, can be a folder or a file.
struct SFileListEntry
{
//! The name of the file
/** If this is a file or folder in the virtual filesystem and the archive
was created with the ignoreCase flag then the file name will be lower case. */
io::path Name;
//! The name of the file including the path
/** If this is a file or folder in the virtual filesystem and the archive was
created with the ignoreDirs flag then it will be the same as Name. */
io::path FullName;
//! The size of the file in bytes
u32 Size;
//! The ID of the file in an archive
/** This is used to link the FileList entry to extra info held about this
file in an archive, which can hold things like data offset and CRC. */
u32 ID;
//! FileOffset inside an archive
u32 Offset;
//! True if this is a folder, false if not.
bool IsDirectory;
//! The == operator is provided so that CFileList can slowly search the list!
bool operator ==(const struct SFileListEntry& other) const
{
if (IsDirectory != other.IsDirectory)
return false;
return FullName.equals_ignore_case(other.FullName);
}
//! The < operator is provided so that CFileList can sort and quickly search the list.
bool operator <(const struct SFileListEntry& other) const
{
if (IsDirectory != other.IsDirectory)
return IsDirectory;
return FullName.lower_ignore_case(other.FullName);
}
};
//! Implementation of a file list
class CFileList : public IFileList
{
public:
// CFileList methods
//! Constructor
/** \param path The path of this file archive */
CFileList(const io::path& path, bool ignoreCase, bool ignorePaths);
//! Destructor
virtual ~CFileList();
//! Add as a file or folder to the list
/** \param fullPath The file name including path, up to the root of the file list.
\param isDirectory True if this is a directory rather than a file.
\param offset The offset where the file is stored in an archive
\param size The size of the file in bytes.
\param id The ID of the file in the archive which owns it */
u32 addItem(const io::path& fullPath, u32 offset, u32 size, bool isDirectory, u32 id=0) override;
//! Sorts the file list. You should call this after adding any items to the file list
void sort() override;
//! Returns the amount of files in the filelist.
u32 getFileCount() const override;
//! Gets the name of a file in the list, based on an index.
const io::path& getFileName(u32 index) const override;
//! Gets the full name of a file in the list, path included, based on an index.
const io::path& getFullFileName(u32 index) const override;
//! Returns the ID of a file in the file list, based on an index.
u32 getID(u32 index) const override;
//! Returns true if the file is a directory
bool isDirectory(u32 index) const override;
//! Returns the size of a file
u32 getFileSize(u32 index) const override;
//! Returns the offset of a file
u32 getFileOffset(u32 index) const override;
//! Searches for a file or folder within the list, returns the index
s32 findFile(const io::path& filename, bool isFolder) const override;
//! Returns the base path of the file list
const io::path& getPath() const override;
protected:
//! Ignore paths when adding or searching for files
bool IgnorePaths;
//! Ignore case when adding or searching for files
bool IgnoreCase;
//! Path to the file list
io::path Path;
//! List of files
core::array<SFileListEntry> Files;
};
} // end namespace irr
} // end namespace io

File diff suppressed because it is too large Load Diff

View File

@ -1,141 +1,141 @@
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#pragma once
#include "IFileSystem.h"
#include "irrArray.h"
namespace irr
{
namespace io
{
class CZipReader;
/*!
FileSystem which uses normal files and one zipfile
*/
class CFileSystem : public IFileSystem
{
public:
//! constructor
CFileSystem();
//! destructor
virtual ~CFileSystem();
//! opens a file for read access
IReadFile* createAndOpenFile(const io::path& filename) override;
//! Creates an IReadFile interface for accessing memory like a file.
IReadFile* createMemoryReadFile(const void* memory, s32 len, const io::path& fileName, bool deleteMemoryWhenDropped = false) override;
//! Creates an IReadFile interface for accessing files inside files
IReadFile* createLimitReadFile(const io::path& fileName, IReadFile* alreadyOpenedFile, long pos, long areaSize) override;
//! Creates an IWriteFile interface for accessing memory like a file.
IWriteFile* createMemoryWriteFile(void* memory, s32 len, const io::path& fileName, bool deleteMemoryWhenDropped=false) override;
//! Opens a file for write access.
IWriteFile* createAndWriteFile(const io::path& filename, bool append=false) override;
//! Adds an archive to the file system.
virtual bool addFileArchive(const io::path& filename,
bool ignoreCase = true, bool ignorePaths = true,
E_FILE_ARCHIVE_TYPE archiveType = EFAT_UNKNOWN,
const core::stringc& password="",
IFileArchive** retArchive = 0) override;
//! Adds an archive to the file system.
virtual bool addFileArchive(IReadFile* file, bool ignoreCase=true,
bool ignorePaths=true,
E_FILE_ARCHIVE_TYPE archiveType=EFAT_UNKNOWN,
const core::stringc& password="",
IFileArchive** retArchive = 0) override;
//! Adds an archive to the file system.
bool addFileArchive(IFileArchive* archive) override;
//! move the hirarchy of the filesystem. moves sourceIndex relative up or down
bool moveFileArchive(u32 sourceIndex, s32 relative) override;
//! Adds an external archive loader to the engine.
void addArchiveLoader(IArchiveLoader* loader) override;
//! Returns the total number of archive loaders added.
u32 getArchiveLoaderCount() const override;
//! Gets the archive loader by index.
IArchiveLoader* getArchiveLoader(u32 index) const override;
//! gets the file archive count
u32 getFileArchiveCount() const override;
//! gets an archive
IFileArchive* getFileArchive(u32 index) override;
//! removes an archive from the file system.
bool removeFileArchive(u32 index) override;
//! removes an archive from the file system.
bool removeFileArchive(const io::path& filename) override;
//! Removes an archive from the file system.
bool removeFileArchive(const IFileArchive* archive) override;
//! Returns the string of the current working directory
const io::path& getWorkingDirectory() override;
//! Changes the current Working Directory to the string given.
//! The string is operating system dependent. Under Windows it will look
//! like this: "drive:\directory\sudirectory\"
bool changeWorkingDirectoryTo(const io::path& newDirectory) override;
//! Converts a relative path to an absolute (unique) path, resolving symbolic links
io::path getAbsolutePath(const io::path& filename) const override;
//! Returns the directory a file is located in.
/** \param filename: The file to get the directory from */
io::path getFileDir(const io::path& filename) const override;
//! Returns the base part of a filename, i.e. the name without the directory
//! part. If no directory is prefixed, the full name is returned.
/** \param filename: The file to get the basename from */
io::path getFileBasename(const io::path& filename, bool keepExtension=true) const override;
//! flatten a path and file name for example: "/you/me/../." becomes "/you"
io::path& flattenFilename( io::path& directory, const io::path& root = "/" ) const override;
//! Get the relative filename, relative to the given directory
path getRelativeFilename(const path& filename, const path& directory) const override;
EFileSystemType setFileListSystem(EFileSystemType listType) override;
//! Creates a list of files and directories in the current working directory
//! and returns it.
IFileList* createFileList() override;
//! Creates an empty filelist
IFileList* createEmptyFileList(const io::path& path, bool ignoreCase, bool ignorePaths) override;
//! determines if a file exists and would be able to be opened.
bool existFile(const io::path& filename) const override;
private:
//! Currently used FileSystemType
EFileSystemType FileSystemType;
//! WorkingDirectory for Native and Virtual filesystems
io::path WorkingDirectory [2];
//! currently attached ArchiveLoaders
core::array<IArchiveLoader*> ArchiveLoader;
//! currently attached Archives
core::array<IFileArchive*> FileArchives;
};
} // end namespace irr
} // end namespace io
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#pragma once
#include "IFileSystem.h"
#include "irrArray.h"
namespace irr
{
namespace io
{
class CZipReader;
/*!
FileSystem which uses normal files and one zipfile
*/
class CFileSystem : public IFileSystem
{
public:
//! constructor
CFileSystem();
//! destructor
virtual ~CFileSystem();
//! opens a file for read access
IReadFile* createAndOpenFile(const io::path& filename) override;
//! Creates an IReadFile interface for accessing memory like a file.
IReadFile* createMemoryReadFile(const void* memory, s32 len, const io::path& fileName, bool deleteMemoryWhenDropped = false) override;
//! Creates an IReadFile interface for accessing files inside files
IReadFile* createLimitReadFile(const io::path& fileName, IReadFile* alreadyOpenedFile, long pos, long areaSize) override;
//! Creates an IWriteFile interface for accessing memory like a file.
IWriteFile* createMemoryWriteFile(void* memory, s32 len, const io::path& fileName, bool deleteMemoryWhenDropped=false) override;
//! Opens a file for write access.
IWriteFile* createAndWriteFile(const io::path& filename, bool append=false) override;
//! Adds an archive to the file system.
virtual bool addFileArchive(const io::path& filename,
bool ignoreCase = true, bool ignorePaths = true,
E_FILE_ARCHIVE_TYPE archiveType = EFAT_UNKNOWN,
const core::stringc& password="",
IFileArchive** retArchive = 0) override;
//! Adds an archive to the file system.
virtual bool addFileArchive(IReadFile* file, bool ignoreCase=true,
bool ignorePaths=true,
E_FILE_ARCHIVE_TYPE archiveType=EFAT_UNKNOWN,
const core::stringc& password="",
IFileArchive** retArchive = 0) override;
//! Adds an archive to the file system.
bool addFileArchive(IFileArchive* archive) override;
//! move the hirarchy of the filesystem. moves sourceIndex relative up or down
bool moveFileArchive(u32 sourceIndex, s32 relative) override;
//! Adds an external archive loader to the engine.
void addArchiveLoader(IArchiveLoader* loader) override;
//! Returns the total number of archive loaders added.
u32 getArchiveLoaderCount() const override;
//! Gets the archive loader by index.
IArchiveLoader* getArchiveLoader(u32 index) const override;
//! gets the file archive count
u32 getFileArchiveCount() const override;
//! gets an archive
IFileArchive* getFileArchive(u32 index) override;
//! removes an archive from the file system.
bool removeFileArchive(u32 index) override;
//! removes an archive from the file system.
bool removeFileArchive(const io::path& filename) override;
//! Removes an archive from the file system.
bool removeFileArchive(const IFileArchive* archive) override;
//! Returns the string of the current working directory
const io::path& getWorkingDirectory() override;
//! Changes the current Working Directory to the string given.
//! The string is operating system dependent. Under Windows it will look
//! like this: "drive:\directory\sudirectory\"
bool changeWorkingDirectoryTo(const io::path& newDirectory) override;
//! Converts a relative path to an absolute (unique) path, resolving symbolic links
io::path getAbsolutePath(const io::path& filename) const override;
//! Returns the directory a file is located in.
/** \param filename: The file to get the directory from */
io::path getFileDir(const io::path& filename) const override;
//! Returns the base part of a filename, i.e. the name without the directory
//! part. If no directory is prefixed, the full name is returned.
/** \param filename: The file to get the basename from */
io::path getFileBasename(const io::path& filename, bool keepExtension=true) const override;
//! flatten a path and file name for example: "/you/me/../." becomes "/you"
io::path& flattenFilename( io::path& directory, const io::path& root = "/" ) const override;
//! Get the relative filename, relative to the given directory
path getRelativeFilename(const path& filename, const path& directory) const override;
EFileSystemType setFileListSystem(EFileSystemType listType) override;
//! Creates a list of files and directories in the current working directory
//! and returns it.
IFileList* createFileList() override;
//! Creates an empty filelist
IFileList* createEmptyFileList(const io::path& path, bool ignoreCase, bool ignorePaths) override;
//! determines if a file exists and would be able to be opened.
bool existFile(const io::path& filename) const override;
private:
//! Currently used FileSystemType
EFileSystemType FileSystemType;
//! WorkingDirectory for Native and Virtual filesystems
io::path WorkingDirectory [2];
//! currently attached ArchiveLoaders
core::array<IArchiveLoader*> ArchiveLoader;
//! currently attached Archives
core::array<IFileArchive*> FileArchives;
};
} // end namespace irr
} // end namespace io

View File

@ -1,482 +1,482 @@
// Copyright (C) 2013 Christian Stehno
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in Irrlicht.h
#include "CGLXManager.h"
#ifdef _IRR_COMPILE_WITH_GLX_MANAGER_
#include "os.h"
#if defined(_IRR_OPENGL_USE_EXTPOINTER_)
#define GL_GLEXT_LEGACY 1
#define GLX_GLXEXT_LEGACY 1
#else
#define GL_GLEXT_PROTOTYPES 1
#define GLX_GLXEXT_PROTOTYPES 1
#endif
#include <GL/gl.h>
#include <GL/glx.h>
#if defined(_IRR_OPENGL_USE_EXTPOINTER_)
#include <GL/glext.h>
#include <GL/glxext.h>
#endif
namespace irr
{
namespace video
{
CGLXManager::CGLXManager(const SIrrlichtCreationParameters& params, const SExposedVideoData& videodata, int screennr)
: Params(params), PrimaryContext(videodata), VisualInfo(0), glxFBConfig(0), GlxWin(0)
{
#ifdef _DEBUG
setDebugName("CGLXManager");
#endif
CurrentContext.OpenGLLinux.X11Display=PrimaryContext.OpenGLLinux.X11Display;
int major, minor;
Display* display = (Display*)PrimaryContext.OpenGLLinux.X11Display;
const bool isAvailableGLX=glXQueryExtension(display,&major,&minor);
if (isAvailableGLX && glXQueryVersion(display, &major, &minor))
{
#if defined(GLX_VERSION_1_3)
typedef GLXFBConfig * ( * PFNGLXCHOOSEFBCONFIGPROC) (Display *dpy, int screen, const int *attrib_list, int *nelements);
#ifdef _IRR_OPENGL_USE_EXTPOINTER_
PFNGLXCHOOSEFBCONFIGPROC glxChooseFBConfig = (PFNGLXCHOOSEFBCONFIGPROC)glXGetProcAddress(reinterpret_cast<const GLubyte*>("glXChooseFBConfig"));
#else
PFNGLXCHOOSEFBCONFIGPROC glxChooseFBConfig=glXChooseFBConfig;
#endif
if (major==1 && minor>2 && glxChooseFBConfig)
{
os::Printer::log("GLX >= 1.3", ELL_DEBUG);
// attribute array for the draw buffer
int visualAttrBuffer[] =
{
GLX_RENDER_TYPE, GLX_RGBA_BIT,
GLX_RED_SIZE, 4,
GLX_GREEN_SIZE, 4,
GLX_BLUE_SIZE, 4,
GLX_ALPHA_SIZE, Params.WithAlphaChannel?1:0,
GLX_DEPTH_SIZE, Params.ZBufferBits, //10,11
GLX_DOUBLEBUFFER, Params.Doublebuffer?True:False,
GLX_STENCIL_SIZE, Params.Stencilbuffer?1:0,
#if defined(GLX_VERSION_1_4) && defined(GLX_SAMPLE_BUFFERS) // we need to check the extension string!
GLX_SAMPLE_BUFFERS, 1,
GLX_SAMPLES, Params.AntiAlias, // 18,19
#elif defined(GLX_ARB_multisample)
GLX_SAMPLE_BUFFERS_ARB, 1,
GLX_SAMPLES_ARB, Params.AntiAlias, // 18,19
#elif defined(GLX_SGIS_multisample)
GLX_SAMPLE_BUFFERS_SGIS, 1,
GLX_SAMPLES_SGIS, Params.AntiAlias, // 18,19
#endif
//#ifdef GL_ARB_framebuffer_sRGB
// GLX_FRAMEBUFFER_SRGB_CAPABLE_ARB, Params.HandleSRGB,
//#elif defined(GL_EXT_framebuffer_sRGB)
// GLX_FRAMEBUFFER_SRGB_CAPABLE_EXT, Params.HandleSRGB,
//#endif
GLX_STEREO, Params.Stereobuffer?True:False,
None
};
GLXFBConfig *configList=0;
int nitems=0;
if (Params.AntiAlias<2)
{
visualAttrBuffer[17] = 0;
visualAttrBuffer[19] = 0;
}
// first round with unchanged values
{
configList=glxChooseFBConfig(display, screennr, visualAttrBuffer,&nitems);
if (!configList && Params.AntiAlias)
{
while (!configList && (visualAttrBuffer[19]>1))
{
visualAttrBuffer[19] -= 1;
configList=glxChooseFBConfig(display, screennr, visualAttrBuffer,&nitems);
}
if (!configList)
{
visualAttrBuffer[17] = 0;
visualAttrBuffer[19] = 0;
configList=glxChooseFBConfig(display, screennr, visualAttrBuffer,&nitems);
if (configList)
{
os::Printer::log("No FSAA available.", ELL_WARNING);
Params.AntiAlias=0;
}
else
{
//reenable multisampling
visualAttrBuffer[17] = 1;
visualAttrBuffer[19] = Params.AntiAlias;
}
}
}
}
// Next try with flipped stencil buffer value
// If the first round was with stencil flag it's now without
// Other way round also makes sense because some configs
// only have depth buffer combined with stencil buffer
if (!configList)
{
if (Params.Stencilbuffer)
os::Printer::log("No stencilbuffer available, disabling stencil shadows.", ELL_WARNING);
Params.Stencilbuffer = !Params.Stencilbuffer;
visualAttrBuffer[15]=Params.Stencilbuffer?1:0;
configList=glxChooseFBConfig(display, screennr, visualAttrBuffer,&nitems);
if (!configList && Params.AntiAlias)
{
while (!configList && (visualAttrBuffer[19]>1))
{
visualAttrBuffer[19] -= 1;
configList=glxChooseFBConfig(display, screennr, visualAttrBuffer,&nitems);
}
if (!configList)
{
visualAttrBuffer[17] = 0;
visualAttrBuffer[19] = 0;
configList=glxChooseFBConfig(display, screennr, visualAttrBuffer,&nitems);
if (configList)
{
os::Printer::log("No FSAA available.", ELL_WARNING);
Params.AntiAlias=0;
}
else
{
//reenable multisampling
visualAttrBuffer[17] = 1;
visualAttrBuffer[19] = Params.AntiAlias;
}
}
}
}
// Next try without double buffer
if (!configList && Params.Doublebuffer)
{
os::Printer::log("No doublebuffering available.", ELL_WARNING);
Params.Doublebuffer=false;
visualAttrBuffer[13] = GLX_DONT_CARE;
Params.Stencilbuffer = false;
visualAttrBuffer[15]=0;
configList=glxChooseFBConfig(display, screennr, visualAttrBuffer,&nitems);
if (!configList && Params.AntiAlias)
{
while (!configList && (visualAttrBuffer[19]>1))
{
visualAttrBuffer[19] -= 1;
configList=glxChooseFBConfig(display, screennr, visualAttrBuffer,&nitems);
}
if (!configList)
{
visualAttrBuffer[17] = 0;
visualAttrBuffer[19] = 0;
configList=glxChooseFBConfig(display, screennr, visualAttrBuffer,&nitems);
if (configList)
{
os::Printer::log("No FSAA available.", ELL_WARNING);
Params.AntiAlias=0;
}
else
{
//reenable multisampling
visualAttrBuffer[17] = 1;
visualAttrBuffer[19] = Params.AntiAlias;
}
}
}
}
if (configList)
{
glxFBConfig=configList[0];
XFree(configList);
#ifdef _IRR_OPENGL_USE_EXTPOINTER_
typedef XVisualInfo * ( * PFNGLXGETVISUALFROMFBCONFIGPROC) (Display *dpy, GLXFBConfig config);
PFNGLXGETVISUALFROMFBCONFIGPROC glxGetVisualFromFBConfig= (PFNGLXGETVISUALFROMFBCONFIGPROC)glXGetProcAddress(reinterpret_cast<const GLubyte*>("glXGetVisualFromFBConfig"));
if (glxGetVisualFromFBConfig)
VisualInfo = glxGetVisualFromFBConfig(display,(GLXFBConfig)glxFBConfig);
#else
VisualInfo = glXGetVisualFromFBConfig(display,(GLXFBConfig)glxFBConfig);
#endif
}
}
else
#endif
{
// attribute array for the draw buffer
int visualAttrBuffer[] =
{
GLX_RGBA, GLX_USE_GL,
GLX_RED_SIZE, 4,
GLX_GREEN_SIZE, 4,
GLX_BLUE_SIZE, 4,
GLX_ALPHA_SIZE, Params.WithAlphaChannel?1:0,
GLX_DEPTH_SIZE, Params.ZBufferBits,
GLX_STENCIL_SIZE, Params.Stencilbuffer?1:0, // 12,13
// The following attributes have no flags, but are
// either present or not. As a no-op we use
// GLX_USE_GL, which is silently ignored by glXChooseVisual
Params.Doublebuffer?GLX_DOUBLEBUFFER:GLX_USE_GL, // 14
Params.Stereobuffer?GLX_STEREO:GLX_USE_GL, // 15
//#ifdef GL_ARB_framebuffer_sRGB
// Params.HandleSRGB?GLX_FRAMEBUFFER_SRGB_CAPABLE_ARB:GLX_USE_GL,
//#elif defined(GL_EXT_framebuffer_sRGB)
// Params.HandleSRGB?GLX_FRAMEBUFFER_SRGB_CAPABLE_EXT:GLX_USE_GL,
//#endif
None
};
VisualInfo=glXChooseVisual(display, screennr, visualAttrBuffer);
if (!VisualInfo)
{
if (Params.Stencilbuffer)
os::Printer::log("No stencilbuffer available, disabling.", ELL_WARNING);
Params.Stencilbuffer = !Params.Stencilbuffer;
visualAttrBuffer[13]=Params.Stencilbuffer?1:0;
VisualInfo=glXChooseVisual(display, screennr, visualAttrBuffer);
if (!VisualInfo && Params.Doublebuffer)
{
os::Printer::log("No doublebuffering available.", ELL_WARNING);
Params.Doublebuffer=false;
visualAttrBuffer[14] = GLX_USE_GL;
VisualInfo=glXChooseVisual(display, screennr, visualAttrBuffer);
}
}
}
}
else
os::Printer::log("No GLX support available. OpenGL driver will not work.", ELL_WARNING);
}
CGLXManager::~CGLXManager()
{
}
bool CGLXManager::initialize(const SIrrlichtCreationParameters& params, const SExposedVideoData& videodata)
{
// store params
Params=params;
// set display
CurrentContext.OpenGLLinux.X11Display=videodata.OpenGLLinux.X11Display;
// now get new window
CurrentContext.OpenGLLinux.X11Window=videodata.OpenGLLinux.X11Window;
if (!PrimaryContext.OpenGLLinux.X11Window)
{
PrimaryContext.OpenGLLinux.X11Window=CurrentContext.OpenGLLinux.X11Window;
}
return true;
}
void CGLXManager::terminate()
{
memset((void*)&CurrentContext, 0, sizeof(CurrentContext));
}
bool CGLXManager::generateSurface()
{
if (glxFBConfig)
{
GlxWin=glXCreateWindow((Display*)CurrentContext.OpenGLLinux.X11Display,(GLXFBConfig)glxFBConfig,CurrentContext.OpenGLLinux.X11Window,NULL);
if (!GlxWin)
{
os::Printer::log("Could not create GLX window.", ELL_WARNING);
return false;
}
CurrentContext.OpenGLLinux.GLXWindow=GlxWin;
}
else
{
CurrentContext.OpenGLLinux.GLXWindow=CurrentContext.OpenGLLinux.X11Window;
}
return true;
}
void CGLXManager::destroySurface()
{
if (GlxWin)
glXDestroyWindow((Display*)CurrentContext.OpenGLLinux.X11Display, GlxWin);
}
#if defined(GLX_ARB_create_context)
static int IrrIgnoreError(Display *display, XErrorEvent *event)
{
char msg[256];
XGetErrorText(display, event->error_code, msg, 256);
os::Printer::log("Ignoring an X error", msg, ELL_DEBUG);
return 0;
}
#endif
bool CGLXManager::generateContext()
{
GLXContext context = 0;
if (glxFBConfig)
{
if (GlxWin)
{
#if defined(GLX_ARB_create_context)
#ifdef _IRR_OPENGL_USE_EXTPOINTER_
PFNGLXCREATECONTEXTATTRIBSARBPROC glxCreateContextAttribsARB=(PFNGLXCREATECONTEXTATTRIBSARBPROC)glXGetProcAddress(reinterpret_cast<const GLubyte*>("glXCreateContextAttribsARB"));
#else
PFNGLXCREATECONTEXTATTRIBSARBPROC glxCreateContextAttribsARB=glXCreateContextAttribsARB;
#endif
if (glxCreateContextAttribsARB)
{
os::Printer::log("GLX with GLX_ARB_create_context", ELL_DEBUG);
int contextAttrBuffer[] = {
GLX_CONTEXT_MAJOR_VERSION_ARB, 3,
GLX_CONTEXT_MINOR_VERSION_ARB, 0,
// GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_CORE_PROFILE_BIT_ARB,
None
};
XErrorHandler old = XSetErrorHandler(IrrIgnoreError);
context = glxCreateContextAttribsARB((Display*)CurrentContext.OpenGLLinux.X11Display, (GLXFBConfig)glxFBConfig, NULL, True, contextAttrBuffer);
XSetErrorHandler(old);
// transparently fall back to legacy call
}
if (!context)
#endif
{
// create glx context
context = glXCreateNewContext((Display*)CurrentContext.OpenGLLinux.X11Display, (GLXFBConfig)glxFBConfig, GLX_RGBA_TYPE, NULL, True);
if (!context)
{
os::Printer::log("Could not create GLX rendering context.", ELL_WARNING);
return false;
}
}
}
else
{
os::Printer::log("GLX window was not properly created.", ELL_WARNING);
return false;
}
}
else
{
context = glXCreateContext((Display*)CurrentContext.OpenGLLinux.X11Display, VisualInfo, NULL, True);
if (!context)
{
os::Printer::log("Could not create GLX rendering context.", ELL_WARNING);
return false;
}
}
CurrentContext.OpenGLLinux.X11Context=context;
return true;
}
const SExposedVideoData& CGLXManager::getContext() const
{
return CurrentContext;
}
bool CGLXManager::activateContext(const SExposedVideoData& videoData, bool restorePrimaryOnZero)
{
//TODO: handle restorePrimaryOnZero
if (videoData.OpenGLLinux.X11Window)
{
if (videoData.OpenGLLinux.X11Display && videoData.OpenGLLinux.X11Context)
{
if (!glXMakeCurrent((Display*)videoData.OpenGLLinux.X11Display, videoData.OpenGLLinux.GLXWindow, (GLXContext)videoData.OpenGLLinux.X11Context))
{
os::Printer::log("Context activation failed.");
return false;
}
else
{
CurrentContext.OpenGLLinux.GLXWindow = videoData.OpenGLLinux.GLXWindow;
CurrentContext.OpenGLLinux.X11Window = videoData.OpenGLLinux.X11Window;
CurrentContext.OpenGLLinux.X11Display = videoData.OpenGLLinux.X11Display;
}
}
else
{
// in case we only got a window ID, try with the existing values for display and context
if (!glXMakeCurrent((Display*)PrimaryContext.OpenGLLinux.X11Display, videoData.OpenGLLinux.GLXWindow, (GLXContext)PrimaryContext.OpenGLLinux.X11Context))
{
os::Printer::log("Context activation failed.");
return false;
}
else
{
CurrentContext.OpenGLLinux.GLXWindow = videoData.OpenGLLinux.GLXWindow;
CurrentContext.OpenGLLinux.X11Window = videoData.OpenGLLinux.X11Window;
CurrentContext.OpenGLLinux.X11Display = PrimaryContext.OpenGLLinux.X11Display;
}
}
}
else if (!restorePrimaryOnZero && !videoData.OpenGLLinux.X11Window && !videoData.OpenGLLinux.X11Display)
{
if (!glXMakeCurrent((Display*)PrimaryContext.OpenGLLinux.X11Display, None, NULL))
{
os::Printer::log("Render Context reset failed.");
return false;
}
CurrentContext.OpenGLLinux.X11Window = 0;
CurrentContext.OpenGLLinux.X11Display = 0;
}
// set back to main context
else if (CurrentContext.OpenGLLinux.X11Display != PrimaryContext.OpenGLLinux.X11Display)
{
if (!glXMakeCurrent((Display*)PrimaryContext.OpenGLLinux.X11Display, PrimaryContext.OpenGLLinux.X11Window, (GLXContext)PrimaryContext.OpenGLLinux.X11Context))
{
os::Printer::log("Context activation failed.");
return false;
}
else
{
CurrentContext = PrimaryContext;
}
}
return true;
}
void CGLXManager::destroyContext()
{
if (CurrentContext.OpenGLLinux.X11Context)
{
if (GlxWin)
{
if (!glXMakeContextCurrent((Display*)CurrentContext.OpenGLLinux.X11Display, None, None, NULL))
os::Printer::log("Could not release glx context.", ELL_WARNING);
}
else
{
if (!glXMakeCurrent((Display*)CurrentContext.OpenGLLinux.X11Display, None, NULL))
os::Printer::log("Could not release glx context.", ELL_WARNING);
}
glXDestroyContext((Display*)CurrentContext.OpenGLLinux.X11Display, (GLXContext)CurrentContext.OpenGLLinux.X11Context);
}
}
void* CGLXManager::getProcAddress(const std::string &procName)
{
return (void*)glXGetProcAddressARB(reinterpret_cast<const GLubyte*>(procName.c_str()));
}
bool CGLXManager::swapBuffers()
{
glXSwapBuffers((Display*)CurrentContext.OpenGLLinux.X11Display, CurrentContext.OpenGLLinux.GLXWindow);
return true;
}
}
}
#endif
// Copyright (C) 2013 Christian Stehno
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in Irrlicht.h
#include "CGLXManager.h"
#ifdef _IRR_COMPILE_WITH_GLX_MANAGER_
#include "os.h"
#if defined(_IRR_OPENGL_USE_EXTPOINTER_)
#define GL_GLEXT_LEGACY 1
#define GLX_GLXEXT_LEGACY 1
#else
#define GL_GLEXT_PROTOTYPES 1
#define GLX_GLXEXT_PROTOTYPES 1
#endif
#include <GL/gl.h>
#include <GL/glx.h>
#if defined(_IRR_OPENGL_USE_EXTPOINTER_)
#include <GL/glext.h>
#include <GL/glxext.h>
#endif
namespace irr
{
namespace video
{
CGLXManager::CGLXManager(const SIrrlichtCreationParameters& params, const SExposedVideoData& videodata, int screennr)
: Params(params), PrimaryContext(videodata), VisualInfo(0), glxFBConfig(0), GlxWin(0)
{
#ifdef _DEBUG
setDebugName("CGLXManager");
#endif
CurrentContext.OpenGLLinux.X11Display=PrimaryContext.OpenGLLinux.X11Display;
int major, minor;
Display* display = (Display*)PrimaryContext.OpenGLLinux.X11Display;
const bool isAvailableGLX=glXQueryExtension(display,&major,&minor);
if (isAvailableGLX && glXQueryVersion(display, &major, &minor))
{
#if defined(GLX_VERSION_1_3)
typedef GLXFBConfig * ( * PFNGLXCHOOSEFBCONFIGPROC) (Display *dpy, int screen, const int *attrib_list, int *nelements);
#ifdef _IRR_OPENGL_USE_EXTPOINTER_
PFNGLXCHOOSEFBCONFIGPROC glxChooseFBConfig = (PFNGLXCHOOSEFBCONFIGPROC)glXGetProcAddress(reinterpret_cast<const GLubyte*>("glXChooseFBConfig"));
#else
PFNGLXCHOOSEFBCONFIGPROC glxChooseFBConfig=glXChooseFBConfig;
#endif
if (major==1 && minor>2 && glxChooseFBConfig)
{
os::Printer::log("GLX >= 1.3", ELL_DEBUG);
// attribute array for the draw buffer
int visualAttrBuffer[] =
{
GLX_RENDER_TYPE, GLX_RGBA_BIT,
GLX_RED_SIZE, 4,
GLX_GREEN_SIZE, 4,
GLX_BLUE_SIZE, 4,
GLX_ALPHA_SIZE, Params.WithAlphaChannel?1:0,
GLX_DEPTH_SIZE, Params.ZBufferBits, //10,11
GLX_DOUBLEBUFFER, Params.Doublebuffer?True:False,
GLX_STENCIL_SIZE, Params.Stencilbuffer?1:0,
#if defined(GLX_VERSION_1_4) && defined(GLX_SAMPLE_BUFFERS) // we need to check the extension string!
GLX_SAMPLE_BUFFERS, 1,
GLX_SAMPLES, Params.AntiAlias, // 18,19
#elif defined(GLX_ARB_multisample)
GLX_SAMPLE_BUFFERS_ARB, 1,
GLX_SAMPLES_ARB, Params.AntiAlias, // 18,19
#elif defined(GLX_SGIS_multisample)
GLX_SAMPLE_BUFFERS_SGIS, 1,
GLX_SAMPLES_SGIS, Params.AntiAlias, // 18,19
#endif
//#ifdef GL_ARB_framebuffer_sRGB
// GLX_FRAMEBUFFER_SRGB_CAPABLE_ARB, Params.HandleSRGB,
//#elif defined(GL_EXT_framebuffer_sRGB)
// GLX_FRAMEBUFFER_SRGB_CAPABLE_EXT, Params.HandleSRGB,
//#endif
GLX_STEREO, Params.Stereobuffer?True:False,
None
};
GLXFBConfig *configList=0;
int nitems=0;
if (Params.AntiAlias<2)
{
visualAttrBuffer[17] = 0;
visualAttrBuffer[19] = 0;
}
// first round with unchanged values
{
configList=glxChooseFBConfig(display, screennr, visualAttrBuffer,&nitems);
if (!configList && Params.AntiAlias)
{
while (!configList && (visualAttrBuffer[19]>1))
{
visualAttrBuffer[19] -= 1;
configList=glxChooseFBConfig(display, screennr, visualAttrBuffer,&nitems);
}
if (!configList)
{
visualAttrBuffer[17] = 0;
visualAttrBuffer[19] = 0;
configList=glxChooseFBConfig(display, screennr, visualAttrBuffer,&nitems);
if (configList)
{
os::Printer::log("No FSAA available.", ELL_WARNING);
Params.AntiAlias=0;
}
else
{
//reenable multisampling
visualAttrBuffer[17] = 1;
visualAttrBuffer[19] = Params.AntiAlias;
}
}
}
}
// Next try with flipped stencil buffer value
// If the first round was with stencil flag it's now without
// Other way round also makes sense because some configs
// only have depth buffer combined with stencil buffer
if (!configList)
{
if (Params.Stencilbuffer)
os::Printer::log("No stencilbuffer available, disabling stencil shadows.", ELL_WARNING);
Params.Stencilbuffer = !Params.Stencilbuffer;
visualAttrBuffer[15]=Params.Stencilbuffer?1:0;
configList=glxChooseFBConfig(display, screennr, visualAttrBuffer,&nitems);
if (!configList && Params.AntiAlias)
{
while (!configList && (visualAttrBuffer[19]>1))
{
visualAttrBuffer[19] -= 1;
configList=glxChooseFBConfig(display, screennr, visualAttrBuffer,&nitems);
}
if (!configList)
{
visualAttrBuffer[17] = 0;
visualAttrBuffer[19] = 0;
configList=glxChooseFBConfig(display, screennr, visualAttrBuffer,&nitems);
if (configList)
{
os::Printer::log("No FSAA available.", ELL_WARNING);
Params.AntiAlias=0;
}
else
{
//reenable multisampling
visualAttrBuffer[17] = 1;
visualAttrBuffer[19] = Params.AntiAlias;
}
}
}
}
// Next try without double buffer
if (!configList && Params.Doublebuffer)
{
os::Printer::log("No doublebuffering available.", ELL_WARNING);
Params.Doublebuffer=false;
visualAttrBuffer[13] = GLX_DONT_CARE;
Params.Stencilbuffer = false;
visualAttrBuffer[15]=0;
configList=glxChooseFBConfig(display, screennr, visualAttrBuffer,&nitems);
if (!configList && Params.AntiAlias)
{
while (!configList && (visualAttrBuffer[19]>1))
{
visualAttrBuffer[19] -= 1;
configList=glxChooseFBConfig(display, screennr, visualAttrBuffer,&nitems);
}
if (!configList)
{
visualAttrBuffer[17] = 0;
visualAttrBuffer[19] = 0;
configList=glxChooseFBConfig(display, screennr, visualAttrBuffer,&nitems);
if (configList)
{
os::Printer::log("No FSAA available.", ELL_WARNING);
Params.AntiAlias=0;
}
else
{
//reenable multisampling
visualAttrBuffer[17] = 1;
visualAttrBuffer[19] = Params.AntiAlias;
}
}
}
}
if (configList)
{
glxFBConfig=configList[0];
XFree(configList);
#ifdef _IRR_OPENGL_USE_EXTPOINTER_
typedef XVisualInfo * ( * PFNGLXGETVISUALFROMFBCONFIGPROC) (Display *dpy, GLXFBConfig config);
PFNGLXGETVISUALFROMFBCONFIGPROC glxGetVisualFromFBConfig= (PFNGLXGETVISUALFROMFBCONFIGPROC)glXGetProcAddress(reinterpret_cast<const GLubyte*>("glXGetVisualFromFBConfig"));
if (glxGetVisualFromFBConfig)
VisualInfo = glxGetVisualFromFBConfig(display,(GLXFBConfig)glxFBConfig);
#else
VisualInfo = glXGetVisualFromFBConfig(display,(GLXFBConfig)glxFBConfig);
#endif
}
}
else
#endif
{
// attribute array for the draw buffer
int visualAttrBuffer[] =
{
GLX_RGBA, GLX_USE_GL,
GLX_RED_SIZE, 4,
GLX_GREEN_SIZE, 4,
GLX_BLUE_SIZE, 4,
GLX_ALPHA_SIZE, Params.WithAlphaChannel?1:0,
GLX_DEPTH_SIZE, Params.ZBufferBits,
GLX_STENCIL_SIZE, Params.Stencilbuffer?1:0, // 12,13
// The following attributes have no flags, but are
// either present or not. As a no-op we use
// GLX_USE_GL, which is silently ignored by glXChooseVisual
Params.Doublebuffer?GLX_DOUBLEBUFFER:GLX_USE_GL, // 14
Params.Stereobuffer?GLX_STEREO:GLX_USE_GL, // 15
//#ifdef GL_ARB_framebuffer_sRGB
// Params.HandleSRGB?GLX_FRAMEBUFFER_SRGB_CAPABLE_ARB:GLX_USE_GL,
//#elif defined(GL_EXT_framebuffer_sRGB)
// Params.HandleSRGB?GLX_FRAMEBUFFER_SRGB_CAPABLE_EXT:GLX_USE_GL,
//#endif
None
};
VisualInfo=glXChooseVisual(display, screennr, visualAttrBuffer);
if (!VisualInfo)
{
if (Params.Stencilbuffer)
os::Printer::log("No stencilbuffer available, disabling.", ELL_WARNING);
Params.Stencilbuffer = !Params.Stencilbuffer;
visualAttrBuffer[13]=Params.Stencilbuffer?1:0;
VisualInfo=glXChooseVisual(display, screennr, visualAttrBuffer);
if (!VisualInfo && Params.Doublebuffer)
{
os::Printer::log("No doublebuffering available.", ELL_WARNING);
Params.Doublebuffer=false;
visualAttrBuffer[14] = GLX_USE_GL;
VisualInfo=glXChooseVisual(display, screennr, visualAttrBuffer);
}
}
}
}
else
os::Printer::log("No GLX support available. OpenGL driver will not work.", ELL_WARNING);
}
CGLXManager::~CGLXManager()
{
}
bool CGLXManager::initialize(const SIrrlichtCreationParameters& params, const SExposedVideoData& videodata)
{
// store params
Params=params;
// set display
CurrentContext.OpenGLLinux.X11Display=videodata.OpenGLLinux.X11Display;
// now get new window
CurrentContext.OpenGLLinux.X11Window=videodata.OpenGLLinux.X11Window;
if (!PrimaryContext.OpenGLLinux.X11Window)
{
PrimaryContext.OpenGLLinux.X11Window=CurrentContext.OpenGLLinux.X11Window;
}
return true;
}
void CGLXManager::terminate()
{
memset((void*)&CurrentContext, 0, sizeof(CurrentContext));
}
bool CGLXManager::generateSurface()
{
if (glxFBConfig)
{
GlxWin=glXCreateWindow((Display*)CurrentContext.OpenGLLinux.X11Display,(GLXFBConfig)glxFBConfig,CurrentContext.OpenGLLinux.X11Window,NULL);
if (!GlxWin)
{
os::Printer::log("Could not create GLX window.", ELL_WARNING);
return false;
}
CurrentContext.OpenGLLinux.GLXWindow=GlxWin;
}
else
{
CurrentContext.OpenGLLinux.GLXWindow=CurrentContext.OpenGLLinux.X11Window;
}
return true;
}
void CGLXManager::destroySurface()
{
if (GlxWin)
glXDestroyWindow((Display*)CurrentContext.OpenGLLinux.X11Display, GlxWin);
}
#if defined(GLX_ARB_create_context)
static int IrrIgnoreError(Display *display, XErrorEvent *event)
{
char msg[256];
XGetErrorText(display, event->error_code, msg, 256);
os::Printer::log("Ignoring an X error", msg, ELL_DEBUG);
return 0;
}
#endif
bool CGLXManager::generateContext()
{
GLXContext context = 0;
if (glxFBConfig)
{
if (GlxWin)
{
#if defined(GLX_ARB_create_context)
#ifdef _IRR_OPENGL_USE_EXTPOINTER_
PFNGLXCREATECONTEXTATTRIBSARBPROC glxCreateContextAttribsARB=(PFNGLXCREATECONTEXTATTRIBSARBPROC)glXGetProcAddress(reinterpret_cast<const GLubyte*>("glXCreateContextAttribsARB"));
#else
PFNGLXCREATECONTEXTATTRIBSARBPROC glxCreateContextAttribsARB=glXCreateContextAttribsARB;
#endif
if (glxCreateContextAttribsARB)
{
os::Printer::log("GLX with GLX_ARB_create_context", ELL_DEBUG);
int contextAttrBuffer[] = {
GLX_CONTEXT_MAJOR_VERSION_ARB, 3,
GLX_CONTEXT_MINOR_VERSION_ARB, 0,
// GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_CORE_PROFILE_BIT_ARB,
None
};
XErrorHandler old = XSetErrorHandler(IrrIgnoreError);
context = glxCreateContextAttribsARB((Display*)CurrentContext.OpenGLLinux.X11Display, (GLXFBConfig)glxFBConfig, NULL, True, contextAttrBuffer);
XSetErrorHandler(old);
// transparently fall back to legacy call
}
if (!context)
#endif
{
// create glx context
context = glXCreateNewContext((Display*)CurrentContext.OpenGLLinux.X11Display, (GLXFBConfig)glxFBConfig, GLX_RGBA_TYPE, NULL, True);
if (!context)
{
os::Printer::log("Could not create GLX rendering context.", ELL_WARNING);
return false;
}
}
}
else
{
os::Printer::log("GLX window was not properly created.", ELL_WARNING);
return false;
}
}
else
{
context = glXCreateContext((Display*)CurrentContext.OpenGLLinux.X11Display, VisualInfo, NULL, True);
if (!context)
{
os::Printer::log("Could not create GLX rendering context.", ELL_WARNING);
return false;
}
}
CurrentContext.OpenGLLinux.X11Context=context;
return true;
}
const SExposedVideoData& CGLXManager::getContext() const
{
return CurrentContext;
}
bool CGLXManager::activateContext(const SExposedVideoData& videoData, bool restorePrimaryOnZero)
{
//TODO: handle restorePrimaryOnZero
if (videoData.OpenGLLinux.X11Window)
{
if (videoData.OpenGLLinux.X11Display && videoData.OpenGLLinux.X11Context)
{
if (!glXMakeCurrent((Display*)videoData.OpenGLLinux.X11Display, videoData.OpenGLLinux.GLXWindow, (GLXContext)videoData.OpenGLLinux.X11Context))
{
os::Printer::log("Context activation failed.");
return false;
}
else
{
CurrentContext.OpenGLLinux.GLXWindow = videoData.OpenGLLinux.GLXWindow;
CurrentContext.OpenGLLinux.X11Window = videoData.OpenGLLinux.X11Window;
CurrentContext.OpenGLLinux.X11Display = videoData.OpenGLLinux.X11Display;
}
}
else
{
// in case we only got a window ID, try with the existing values for display and context
if (!glXMakeCurrent((Display*)PrimaryContext.OpenGLLinux.X11Display, videoData.OpenGLLinux.GLXWindow, (GLXContext)PrimaryContext.OpenGLLinux.X11Context))
{
os::Printer::log("Context activation failed.");
return false;
}
else
{
CurrentContext.OpenGLLinux.GLXWindow = videoData.OpenGLLinux.GLXWindow;
CurrentContext.OpenGLLinux.X11Window = videoData.OpenGLLinux.X11Window;
CurrentContext.OpenGLLinux.X11Display = PrimaryContext.OpenGLLinux.X11Display;
}
}
}
else if (!restorePrimaryOnZero && !videoData.OpenGLLinux.X11Window && !videoData.OpenGLLinux.X11Display)
{
if (!glXMakeCurrent((Display*)PrimaryContext.OpenGLLinux.X11Display, None, NULL))
{
os::Printer::log("Render Context reset failed.");
return false;
}
CurrentContext.OpenGLLinux.X11Window = 0;
CurrentContext.OpenGLLinux.X11Display = 0;
}
// set back to main context
else if (CurrentContext.OpenGLLinux.X11Display != PrimaryContext.OpenGLLinux.X11Display)
{
if (!glXMakeCurrent((Display*)PrimaryContext.OpenGLLinux.X11Display, PrimaryContext.OpenGLLinux.X11Window, (GLXContext)PrimaryContext.OpenGLLinux.X11Context))
{
os::Printer::log("Context activation failed.");
return false;
}
else
{
CurrentContext = PrimaryContext;
}
}
return true;
}
void CGLXManager::destroyContext()
{
if (CurrentContext.OpenGLLinux.X11Context)
{
if (GlxWin)
{
if (!glXMakeContextCurrent((Display*)CurrentContext.OpenGLLinux.X11Display, None, None, NULL))
os::Printer::log("Could not release glx context.", ELL_WARNING);
}
else
{
if (!glXMakeCurrent((Display*)CurrentContext.OpenGLLinux.X11Display, None, NULL))
os::Printer::log("Could not release glx context.", ELL_WARNING);
}
glXDestroyContext((Display*)CurrentContext.OpenGLLinux.X11Display, (GLXContext)CurrentContext.OpenGLLinux.X11Context);
}
}
void* CGLXManager::getProcAddress(const std::string &procName)
{
return (void*)glXGetProcAddressARB(reinterpret_cast<const GLubyte*>(procName.c_str()));
}
bool CGLXManager::swapBuffers()
{
glXSwapBuffers((Display*)CurrentContext.OpenGLLinux.X11Display, CurrentContext.OpenGLLinux.GLXWindow);
return true;
}
}
}
#endif

View File

@ -1,76 +1,76 @@
// Copyright (C) 2013 Christian Stehno
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in Irrlicht.h
#pragma once
#ifdef _IRR_COMPILE_WITH_GLX_MANAGER_
#include "SIrrCreationParameters.h"
#include "SExposedVideoData.h"
#include "IContextManager.h"
#include "SColor.h"
#include <X11/Xlib.h>
#include <X11/Xutil.h>
// we can't include glx.h here, because gl.h has incompatible types with ogl es headers and it
// cause redefinition errors, thats why we use ugly trick with void* types and casts.
namespace irr
{
namespace video
{
// GLX manager.
class CGLXManager : public IContextManager
{
public:
//! Constructor.
CGLXManager(const SIrrlichtCreationParameters& params, const SExposedVideoData& videodata, int screennr);
//! Destructor
~CGLXManager();
// Initialize
bool initialize(const SIrrlichtCreationParameters& params, const SExposedVideoData& data) override;
// Terminate
void terminate() override;
// Create surface.
bool generateSurface() override;
// Destroy surface.
void destroySurface() override;
// Create context.
bool generateContext() override;
// Destroy context.
void destroyContext() override;
//! Get current context
const SExposedVideoData& getContext() const override;
//! Change render context, disable old and activate new defined by videoData
bool activateContext(const SExposedVideoData& videoData, bool restorePrimaryOnZero) override;
// Get procedure address.
void* getProcAddress(const std::string &procName) override;
// Swap buffers.
bool swapBuffers() override;
XVisualInfo* getVisual() const {return VisualInfo;} // return XVisualInfo
private:
SIrrlichtCreationParameters Params;
SExposedVideoData PrimaryContext;
SExposedVideoData CurrentContext;
XVisualInfo* VisualInfo;
void* glxFBConfig; // GLXFBConfig
XID GlxWin; // GLXWindow
};
}
}
#endif
// Copyright (C) 2013 Christian Stehno
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in Irrlicht.h
#pragma once
#ifdef _IRR_COMPILE_WITH_GLX_MANAGER_
#include "SIrrCreationParameters.h"
#include "SExposedVideoData.h"
#include "IContextManager.h"
#include "SColor.h"
#include <X11/Xlib.h>
#include <X11/Xutil.h>
// we can't include glx.h here, because gl.h has incompatible types with ogl es headers and it
// cause redefinition errors, thats why we use ugly trick with void* types and casts.
namespace irr
{
namespace video
{
// GLX manager.
class CGLXManager : public IContextManager
{
public:
//! Constructor.
CGLXManager(const SIrrlichtCreationParameters& params, const SExposedVideoData& videodata, int screennr);
//! Destructor
~CGLXManager();
// Initialize
bool initialize(const SIrrlichtCreationParameters& params, const SExposedVideoData& data) override;
// Terminate
void terminate() override;
// Create surface.
bool generateSurface() override;
// Destroy surface.
void destroySurface() override;
// Create context.
bool generateContext() override;
// Destroy context.
void destroyContext() override;
//! Get current context
const SExposedVideoData& getContext() const override;
//! Change render context, disable old and activate new defined by videoData
bool activateContext(const SExposedVideoData& videoData, bool restorePrimaryOnZero) override;
// Get procedure address.
void* getProcAddress(const std::string &procName) override;
// Swap buffers.
bool swapBuffers() override;
XVisualInfo* getVisual() const {return VisualInfo;} // return XVisualInfo
private:
SIrrlichtCreationParameters Params;
SExposedVideoData PrimaryContext;
SExposedVideoData CurrentContext;
XVisualInfo* VisualInfo;
void* glxFBConfig; // GLXFBConfig
XID GlxWin; // GLXWindow
};
}
}
#endif

File diff suppressed because it is too large Load Diff

View File

@ -1,241 +1,241 @@
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#pragma once
#include "IGUIButton.h"
#include "IGUISpriteBank.h"
#include "ITexture.h"
#include "SColor.h"
namespace irr
{
namespace gui
{
class CGUIButton : public IGUIButton
{
public:
//! constructor
CGUIButton(IGUIEnvironment* environment, IGUIElement* parent,
s32 id, core::rect<s32> rectangle, bool noclip=false);
//! destructor
virtual ~CGUIButton();
//! called if an event happened.
bool OnEvent(const SEvent& event) override;
//! draws the element and its children
void draw() override;
//! sets another skin independent font. if this is set to zero, the button uses the font of the skin.
void setOverrideFont(IGUIFont* font=0) override;
//! Gets the override font (if any)
IGUIFont* getOverrideFont() const override;
//! Get the font which is used right now for drawing
IGUIFont* getActiveFont() const override;
//! Sets another color for the button text.
void setOverrideColor(video::SColor color) override;
//! Gets the override color
video::SColor getOverrideColor(void) const override;
//! Gets the currently used text color
video::SColor getActiveColor() const override;
//! Sets if the button text should use the override color or the color in the gui skin.
void enableOverrideColor(bool enable) override;
//! Checks if an override color is enabled
bool isOverrideColorEnabled(void) const override;
//! Sets an image which should be displayed on the button when it is in the given state.
void setImage(EGUI_BUTTON_IMAGE_STATE state, video::ITexture* image=0, const core::rect<s32>& sourceRect=core::rect<s32>(0,0,0,0)) override;
//! Sets an image which should be displayed on the button when it is in normal state.
void setImage(video::ITexture* image=0) override
{
setImage(EGBIS_IMAGE_UP, image);
}
//! Sets an image which should be displayed on the button when it is in normal state.
void setImage(video::ITexture* image, const core::rect<s32>& pos) override
{
setImage(EGBIS_IMAGE_UP, image, pos);
}
//! Sets an image which should be displayed on the button when it is in pressed state.
void setPressedImage(video::ITexture* image=0) override
{
setImage(EGBIS_IMAGE_DOWN, image);
}
//! Sets an image which should be displayed on the button when it is in pressed state.
void setPressedImage(video::ITexture* image, const core::rect<s32>& pos) override
{
setImage(EGBIS_IMAGE_DOWN, image, pos);
}
//! Sets the sprite bank used by the button
void setSpriteBank(IGUISpriteBank* bank=0) override;
//! Sets the animated sprite for a specific button state
/** \param index: Number of the sprite within the sprite bank, use -1 for no sprite
\param state: State of the button to set the sprite for
\param index: The sprite number from the current sprite bank
\param color: The color of the sprite
*/
virtual void setSprite(EGUI_BUTTON_STATE state, s32 index,
video::SColor color=video::SColor(255,255,255,255),
bool loop=false, bool scale=false) override;
//! Get the sprite-index for the given state or -1 when no sprite is set
s32 getSpriteIndex(EGUI_BUTTON_STATE state) const override;
//! Get the sprite color for the given state. Color is only used when a sprite is set.
video::SColor getSpriteColor(EGUI_BUTTON_STATE state) const override;
//! Returns if the sprite in the given state does loop
bool getSpriteLoop(EGUI_BUTTON_STATE state) const override;
//! Returns if the sprite in the given state is scaled
bool getSpriteScale(EGUI_BUTTON_STATE state) const override;
//! Sets if the button should behave like a push button. Which means it
//! can be in two states: Normal or Pressed. With a click on the button,
//! the user can change the state of the button.
void setIsPushButton(bool isPushButton=true) override;
//! Checks whether the button is a push button
bool isPushButton() const override;
//! Sets the pressed state of the button if this is a pushbutton
void setPressed(bool pressed=true) override;
//! Returns if the button is currently pressed
bool isPressed() const override;
//! Sets if the button should use the skin to draw its border
void setDrawBorder(bool border=true) override;
//! Checks if the button face and border are being drawn
bool isDrawingBorder() const override;
//! Sets if the alpha channel should be used for drawing images on the button (default is false)
void setUseAlphaChannel(bool useAlphaChannel=true) override;
//! Checks if the alpha channel should be used for drawing images on the button
bool isAlphaChannelUsed() const override;
//! Sets if the button should scale the button images to fit
void setScaleImage(bool scaleImage=true) override;
//! Checks whether the button scales the used images
bool isScalingImage() const override;
//! Get if the shift key was pressed in last EGET_BUTTON_CLICKED event
bool getClickShiftState() const override
{
return ClickShiftState;
}
//! Get if the control key was pressed in last EGET_BUTTON_CLICKED event
bool getClickControlState() const override
{
return ClickControlState;
}
protected:
void drawSprite(EGUI_BUTTON_STATE state, u32 startTime, const core::position2di& center);
EGUI_BUTTON_IMAGE_STATE getImageState(bool pressed) const;
private:
struct ButtonSprite
{
ButtonSprite() : Index(-1), Loop(false), Scale(false)
{
}
bool operator==(const ButtonSprite& other) const
{
return Index == other.Index && Color == other.Color && Loop == other.Loop && Scale == other.Scale;
}
s32 Index;
video::SColor Color;
bool Loop;
bool Scale;
};
ButtonSprite ButtonSprites[EGBS_COUNT];
IGUISpriteBank* SpriteBank;
struct ButtonImage
{
ButtonImage() : Texture(0), SourceRect(core::rect<s32>(0,0,0,0))
{
}
ButtonImage(const ButtonImage& other) : Texture(0), SourceRect(core::rect<s32>(0,0,0,0))
{
*this = other;
}
~ButtonImage()
{
if ( Texture )
Texture->drop();
}
ButtonImage& operator=(const ButtonImage& other)
{
if ( this == &other )
return *this;
if (other.Texture)
other.Texture->grab();
if ( Texture )
Texture->drop();
Texture = other.Texture;
SourceRect = other.SourceRect;
return *this;
}
bool operator==(const ButtonImage& other) const
{
return Texture == other.Texture && SourceRect == other.SourceRect;
}
video::ITexture* Texture;
core::rect<s32> SourceRect;
};
ButtonImage ButtonImages[EGBIS_COUNT];
IGUIFont* OverrideFont;
bool OverrideColorEnabled;
video::SColor OverrideColor;
u32 ClickTime, HoverTime, FocusTime;
bool ClickShiftState;
bool ClickControlState;
bool IsPushButton;
bool Pressed;
bool UseAlphaChannel;
bool DrawBorder;
bool ScaleImage;
};
} // end namespace gui
} // end namespace irr
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#pragma once
#include "IGUIButton.h"
#include "IGUISpriteBank.h"
#include "ITexture.h"
#include "SColor.h"
namespace irr
{
namespace gui
{
class CGUIButton : public IGUIButton
{
public:
//! constructor
CGUIButton(IGUIEnvironment* environment, IGUIElement* parent,
s32 id, core::rect<s32> rectangle, bool noclip=false);
//! destructor
virtual ~CGUIButton();
//! called if an event happened.
bool OnEvent(const SEvent& event) override;
//! draws the element and its children
void draw() override;
//! sets another skin independent font. if this is set to zero, the button uses the font of the skin.
void setOverrideFont(IGUIFont* font=0) override;
//! Gets the override font (if any)
IGUIFont* getOverrideFont() const override;
//! Get the font which is used right now for drawing
IGUIFont* getActiveFont() const override;
//! Sets another color for the button text.
void setOverrideColor(video::SColor color) override;
//! Gets the override color
video::SColor getOverrideColor(void) const override;
//! Gets the currently used text color
video::SColor getActiveColor() const override;
//! Sets if the button text should use the override color or the color in the gui skin.
void enableOverrideColor(bool enable) override;
//! Checks if an override color is enabled
bool isOverrideColorEnabled(void) const override;
//! Sets an image which should be displayed on the button when it is in the given state.
void setImage(EGUI_BUTTON_IMAGE_STATE state, video::ITexture* image=0, const core::rect<s32>& sourceRect=core::rect<s32>(0,0,0,0)) override;
//! Sets an image which should be displayed on the button when it is in normal state.
void setImage(video::ITexture* image=0) override
{
setImage(EGBIS_IMAGE_UP, image);
}
//! Sets an image which should be displayed on the button when it is in normal state.
void setImage(video::ITexture* image, const core::rect<s32>& pos) override
{
setImage(EGBIS_IMAGE_UP, image, pos);
}
//! Sets an image which should be displayed on the button when it is in pressed state.
void setPressedImage(video::ITexture* image=0) override
{
setImage(EGBIS_IMAGE_DOWN, image);
}
//! Sets an image which should be displayed on the button when it is in pressed state.
void setPressedImage(video::ITexture* image, const core::rect<s32>& pos) override
{
setImage(EGBIS_IMAGE_DOWN, image, pos);
}
//! Sets the sprite bank used by the button
void setSpriteBank(IGUISpriteBank* bank=0) override;
//! Sets the animated sprite for a specific button state
/** \param index: Number of the sprite within the sprite bank, use -1 for no sprite
\param state: State of the button to set the sprite for
\param index: The sprite number from the current sprite bank
\param color: The color of the sprite
*/
virtual void setSprite(EGUI_BUTTON_STATE state, s32 index,
video::SColor color=video::SColor(255,255,255,255),
bool loop=false, bool scale=false) override;
//! Get the sprite-index for the given state or -1 when no sprite is set
s32 getSpriteIndex(EGUI_BUTTON_STATE state) const override;
//! Get the sprite color for the given state. Color is only used when a sprite is set.
video::SColor getSpriteColor(EGUI_BUTTON_STATE state) const override;
//! Returns if the sprite in the given state does loop
bool getSpriteLoop(EGUI_BUTTON_STATE state) const override;
//! Returns if the sprite in the given state is scaled
bool getSpriteScale(EGUI_BUTTON_STATE state) const override;
//! Sets if the button should behave like a push button. Which means it
//! can be in two states: Normal or Pressed. With a click on the button,
//! the user can change the state of the button.
void setIsPushButton(bool isPushButton=true) override;
//! Checks whether the button is a push button
bool isPushButton() const override;
//! Sets the pressed state of the button if this is a pushbutton
void setPressed(bool pressed=true) override;
//! Returns if the button is currently pressed
bool isPressed() const override;
//! Sets if the button should use the skin to draw its border
void setDrawBorder(bool border=true) override;
//! Checks if the button face and border are being drawn
bool isDrawingBorder() const override;
//! Sets if the alpha channel should be used for drawing images on the button (default is false)
void setUseAlphaChannel(bool useAlphaChannel=true) override;
//! Checks if the alpha channel should be used for drawing images on the button
bool isAlphaChannelUsed() const override;
//! Sets if the button should scale the button images to fit
void setScaleImage(bool scaleImage=true) override;
//! Checks whether the button scales the used images
bool isScalingImage() const override;
//! Get if the shift key was pressed in last EGET_BUTTON_CLICKED event
bool getClickShiftState() const override
{
return ClickShiftState;
}
//! Get if the control key was pressed in last EGET_BUTTON_CLICKED event
bool getClickControlState() const override
{
return ClickControlState;
}
protected:
void drawSprite(EGUI_BUTTON_STATE state, u32 startTime, const core::position2di& center);
EGUI_BUTTON_IMAGE_STATE getImageState(bool pressed) const;
private:
struct ButtonSprite
{
ButtonSprite() : Index(-1), Loop(false), Scale(false)
{
}
bool operator==(const ButtonSprite& other) const
{
return Index == other.Index && Color == other.Color && Loop == other.Loop && Scale == other.Scale;
}
s32 Index;
video::SColor Color;
bool Loop;
bool Scale;
};
ButtonSprite ButtonSprites[EGBS_COUNT];
IGUISpriteBank* SpriteBank;
struct ButtonImage
{
ButtonImage() : Texture(0), SourceRect(core::rect<s32>(0,0,0,0))
{
}
ButtonImage(const ButtonImage& other) : Texture(0), SourceRect(core::rect<s32>(0,0,0,0))
{
*this = other;
}
~ButtonImage()
{
if ( Texture )
Texture->drop();
}
ButtonImage& operator=(const ButtonImage& other)
{
if ( this == &other )
return *this;
if (other.Texture)
other.Texture->grab();
if ( Texture )
Texture->drop();
Texture = other.Texture;
SourceRect = other.SourceRect;
return *this;
}
bool operator==(const ButtonImage& other) const
{
return Texture == other.Texture && SourceRect == other.SourceRect;
}
video::ITexture* Texture;
core::rect<s32> SourceRect;
};
ButtonImage ButtonImages[EGBIS_COUNT];
IGUIFont* OverrideFont;
bool OverrideColorEnabled;
video::SColor OverrideColor;
u32 ClickTime, HoverTime, FocusTime;
bool ClickShiftState;
bool ClickControlState;
bool IsPushButton;
bool Pressed;
bool UseAlphaChannel;
bool DrawBorder;
bool ScaleImage;
};
} // end namespace gui
} // end namespace irr

View File

@ -1,227 +1,227 @@
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#include "CGUICheckBox.h"
#include "IGUISkin.h"
#include "IGUIEnvironment.h"
#include "IVideoDriver.h"
#include "IGUIFont.h"
#include "os.h"
namespace irr
{
namespace gui
{
//! constructor
CGUICheckBox::CGUICheckBox(bool checked, IGUIEnvironment* environment, IGUIElement* parent, s32 id, core::rect<s32> rectangle)
: IGUICheckBox(environment, parent, id, rectangle), CheckTime(0), Pressed(false), Checked(checked)
, Border(false), Background(false)
{
#ifdef _DEBUG
setDebugName("CGUICheckBox");
#endif
// this element can be tabbed into
setTabStop(true);
setTabOrder(-1);
}
//! called if an event happened.
bool CGUICheckBox::OnEvent(const SEvent& event)
{
if (isEnabled())
{
switch(event.EventType)
{
case EET_KEY_INPUT_EVENT:
if (event.KeyInput.PressedDown &&
(event.KeyInput.Key == KEY_RETURN || event.KeyInput.Key == KEY_SPACE))
{
Pressed = true;
return true;
}
else
if (Pressed && event.KeyInput.PressedDown && event.KeyInput.Key == KEY_ESCAPE)
{
Pressed = false;
return true;
}
else
if (!event.KeyInput.PressedDown && Pressed &&
(event.KeyInput.Key == KEY_RETURN || event.KeyInput.Key == KEY_SPACE))
{
Pressed = false;
if (Parent)
{
SEvent newEvent;
newEvent.EventType = EET_GUI_EVENT;
newEvent.GUIEvent.Caller = this;
newEvent.GUIEvent.Element = 0;
Checked = !Checked;
newEvent.GUIEvent.EventType = EGET_CHECKBOX_CHANGED;
Parent->OnEvent(newEvent);
}
return true;
}
break;
case EET_GUI_EVENT:
if (event.GUIEvent.EventType == EGET_ELEMENT_FOCUS_LOST)
{
if (event.GUIEvent.Caller == this)
Pressed = false;
}
break;
case EET_MOUSE_INPUT_EVENT:
if (event.MouseInput.Event == EMIE_LMOUSE_PRESSED_DOWN)
{
Pressed = true;
CheckTime = os::Timer::getTime();
return true;
}
else
if (event.MouseInput.Event == EMIE_LMOUSE_LEFT_UP)
{
bool wasPressed = Pressed;
Pressed = false;
if (wasPressed && Parent)
{
if ( !AbsoluteClippingRect.isPointInside( core::position2d<s32>(event.MouseInput.X, event.MouseInput.Y) ) )
{
Pressed = false;
return true;
}
SEvent newEvent;
newEvent.EventType = EET_GUI_EVENT;
newEvent.GUIEvent.Caller = this;
newEvent.GUIEvent.Element = 0;
Checked = !Checked;
newEvent.GUIEvent.EventType = EGET_CHECKBOX_CHANGED;
Parent->OnEvent(newEvent);
}
return true;
}
break;
default:
break;
}
}
return IGUIElement::OnEvent(event);
}
//! draws the element and its children
void CGUICheckBox::draw()
{
if (!IsVisible)
return;
IGUISkin* skin = Environment->getSkin();
if (skin)
{
video::IVideoDriver* driver = Environment->getVideoDriver();
core::rect<s32> frameRect(AbsoluteRect);
// draw background
if (Background)
{
video::SColor bgColor = skin->getColor(gui::EGDC_3D_FACE);
driver->draw2DRectangle(bgColor, frameRect, &AbsoluteClippingRect);
}
// draw the border
if (Border)
{
skin->draw3DSunkenPane(this, 0, true, false, frameRect, &AbsoluteClippingRect);
frameRect.UpperLeftCorner.X += skin->getSize(EGDS_TEXT_DISTANCE_X);
frameRect.LowerRightCorner.X -= skin->getSize(EGDS_TEXT_DISTANCE_X);
}
const s32 height = skin->getSize(EGDS_CHECK_BOX_WIDTH);
// the rectangle around the "checked" area.
core::rect<s32> checkRect(frameRect.UpperLeftCorner.X,
((frameRect.getHeight() - height) / 2) + frameRect.UpperLeftCorner.Y,
0, 0);
checkRect.LowerRightCorner.X = checkRect.UpperLeftCorner.X + height;
checkRect.LowerRightCorner.Y = checkRect.UpperLeftCorner.Y + height;
EGUI_DEFAULT_COLOR col = EGDC_GRAY_EDITABLE;
if ( isEnabled() )
col = Pressed ? EGDC_FOCUSED_EDITABLE : EGDC_EDITABLE;
skin->draw3DSunkenPane(this, skin->getColor(col),
false, true, checkRect, &AbsoluteClippingRect);
// the checked icon
if (Checked)
{
skin->drawIcon(this, EGDI_CHECK_BOX_CHECKED, checkRect.getCenter(),
CheckTime, os::Timer::getTime(), false, &AbsoluteClippingRect);
}
// associated text
if (Text.size())
{
checkRect = frameRect;
checkRect.UpperLeftCorner.X += height + 5;
IGUIFont* font = skin->getFont();
if (font)
{
font->draw(Text.c_str(), checkRect,
skin->getColor(isEnabled() ? EGDC_BUTTON_TEXT : EGDC_GRAY_TEXT), false, true, &AbsoluteClippingRect);
}
}
}
IGUIElement::draw();
}
//! set if box is checked
void CGUICheckBox::setChecked(bool checked)
{
Checked = checked;
}
//! returns if box is checked
bool CGUICheckBox::isChecked() const
{
return Checked;
}
//! Sets whether to draw the background
void CGUICheckBox::setDrawBackground(bool draw)
{
Background = draw;
}
//! Checks if background drawing is enabled
bool CGUICheckBox::isDrawBackgroundEnabled() const
{
return Background;
}
//! Sets whether to draw the border
void CGUICheckBox::setDrawBorder(bool draw)
{
Border = draw;
}
//! Checks if border drawing is enabled
bool CGUICheckBox::isDrawBorderEnabled() const
{
return Border;
}
} // end namespace gui
} // end namespace irr
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#include "CGUICheckBox.h"
#include "IGUISkin.h"
#include "IGUIEnvironment.h"
#include "IVideoDriver.h"
#include "IGUIFont.h"
#include "os.h"
namespace irr
{
namespace gui
{
//! constructor
CGUICheckBox::CGUICheckBox(bool checked, IGUIEnvironment* environment, IGUIElement* parent, s32 id, core::rect<s32> rectangle)
: IGUICheckBox(environment, parent, id, rectangle), CheckTime(0), Pressed(false), Checked(checked)
, Border(false), Background(false)
{
#ifdef _DEBUG
setDebugName("CGUICheckBox");
#endif
// this element can be tabbed into
setTabStop(true);
setTabOrder(-1);
}
//! called if an event happened.
bool CGUICheckBox::OnEvent(const SEvent& event)
{
if (isEnabled())
{
switch(event.EventType)
{
case EET_KEY_INPUT_EVENT:
if (event.KeyInput.PressedDown &&
(event.KeyInput.Key == KEY_RETURN || event.KeyInput.Key == KEY_SPACE))
{
Pressed = true;
return true;
}
else
if (Pressed && event.KeyInput.PressedDown && event.KeyInput.Key == KEY_ESCAPE)
{
Pressed = false;
return true;
}
else
if (!event.KeyInput.PressedDown && Pressed &&
(event.KeyInput.Key == KEY_RETURN || event.KeyInput.Key == KEY_SPACE))
{
Pressed = false;
if (Parent)
{
SEvent newEvent;
newEvent.EventType = EET_GUI_EVENT;
newEvent.GUIEvent.Caller = this;
newEvent.GUIEvent.Element = 0;
Checked = !Checked;
newEvent.GUIEvent.EventType = EGET_CHECKBOX_CHANGED;
Parent->OnEvent(newEvent);
}
return true;
}
break;
case EET_GUI_EVENT:
if (event.GUIEvent.EventType == EGET_ELEMENT_FOCUS_LOST)
{
if (event.GUIEvent.Caller == this)
Pressed = false;
}
break;
case EET_MOUSE_INPUT_EVENT:
if (event.MouseInput.Event == EMIE_LMOUSE_PRESSED_DOWN)
{
Pressed = true;
CheckTime = os::Timer::getTime();
return true;
}
else
if (event.MouseInput.Event == EMIE_LMOUSE_LEFT_UP)
{
bool wasPressed = Pressed;
Pressed = false;
if (wasPressed && Parent)
{
if ( !AbsoluteClippingRect.isPointInside( core::position2d<s32>(event.MouseInput.X, event.MouseInput.Y) ) )
{
Pressed = false;
return true;
}
SEvent newEvent;
newEvent.EventType = EET_GUI_EVENT;
newEvent.GUIEvent.Caller = this;
newEvent.GUIEvent.Element = 0;
Checked = !Checked;
newEvent.GUIEvent.EventType = EGET_CHECKBOX_CHANGED;
Parent->OnEvent(newEvent);
}
return true;
}
break;
default:
break;
}
}
return IGUIElement::OnEvent(event);
}
//! draws the element and its children
void CGUICheckBox::draw()
{
if (!IsVisible)
return;
IGUISkin* skin = Environment->getSkin();
if (skin)
{
video::IVideoDriver* driver = Environment->getVideoDriver();
core::rect<s32> frameRect(AbsoluteRect);
// draw background
if (Background)
{
video::SColor bgColor = skin->getColor(gui::EGDC_3D_FACE);
driver->draw2DRectangle(bgColor, frameRect, &AbsoluteClippingRect);
}
// draw the border
if (Border)
{
skin->draw3DSunkenPane(this, 0, true, false, frameRect, &AbsoluteClippingRect);
frameRect.UpperLeftCorner.X += skin->getSize(EGDS_TEXT_DISTANCE_X);
frameRect.LowerRightCorner.X -= skin->getSize(EGDS_TEXT_DISTANCE_X);
}
const s32 height = skin->getSize(EGDS_CHECK_BOX_WIDTH);
// the rectangle around the "checked" area.
core::rect<s32> checkRect(frameRect.UpperLeftCorner.X,
((frameRect.getHeight() - height) / 2) + frameRect.UpperLeftCorner.Y,
0, 0);
checkRect.LowerRightCorner.X = checkRect.UpperLeftCorner.X + height;
checkRect.LowerRightCorner.Y = checkRect.UpperLeftCorner.Y + height;
EGUI_DEFAULT_COLOR col = EGDC_GRAY_EDITABLE;
if ( isEnabled() )
col = Pressed ? EGDC_FOCUSED_EDITABLE : EGDC_EDITABLE;
skin->draw3DSunkenPane(this, skin->getColor(col),
false, true, checkRect, &AbsoluteClippingRect);
// the checked icon
if (Checked)
{
skin->drawIcon(this, EGDI_CHECK_BOX_CHECKED, checkRect.getCenter(),
CheckTime, os::Timer::getTime(), false, &AbsoluteClippingRect);
}
// associated text
if (Text.size())
{
checkRect = frameRect;
checkRect.UpperLeftCorner.X += height + 5;
IGUIFont* font = skin->getFont();
if (font)
{
font->draw(Text.c_str(), checkRect,
skin->getColor(isEnabled() ? EGDC_BUTTON_TEXT : EGDC_GRAY_TEXT), false, true, &AbsoluteClippingRect);
}
}
}
IGUIElement::draw();
}
//! set if box is checked
void CGUICheckBox::setChecked(bool checked)
{
Checked = checked;
}
//! returns if box is checked
bool CGUICheckBox::isChecked() const
{
return Checked;
}
//! Sets whether to draw the background
void CGUICheckBox::setDrawBackground(bool draw)
{
Background = draw;
}
//! Checks if background drawing is enabled
bool CGUICheckBox::isDrawBackgroundEnabled() const
{
return Background;
}
//! Sets whether to draw the border
void CGUICheckBox::setDrawBorder(bool draw)
{
Border = draw;
}
//! Checks if border drawing is enabled
bool CGUICheckBox::isDrawBorderEnabled() const
{
return Border;
}
} // end namespace gui
} // end namespace irr

View File

@ -1,57 +1,57 @@
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#pragma once
#include "IGUICheckBox.h"
namespace irr
{
namespace gui
{
class CGUICheckBox : public IGUICheckBox
{
public:
//! constructor
CGUICheckBox(bool checked, IGUIEnvironment* environment, IGUIElement* parent, s32 id, core::rect<s32> rectangle);
//! set if box is checked
void setChecked(bool checked) override;
//! returns if box is checked
bool isChecked() const override;
//! Sets whether to draw the background
void setDrawBackground(bool draw) override;
//! Checks if background drawing is enabled
/** \return true if background drawing is enabled, false otherwise */
bool isDrawBackgroundEnabled() const override;
//! Sets whether to draw the border
void setDrawBorder(bool draw) override;
//! Checks if border drawing is enabled
/** \return true if border drawing is enabled, false otherwise */
bool isDrawBorderEnabled() const override;
//! called if an event happened.
bool OnEvent(const SEvent& event) override;
//! draws the element and its children
void draw() override;
private:
u32 CheckTime;
bool Pressed;
bool Checked;
bool Border;
bool Background;
};
} // end namespace gui
} // end namespace irr
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#pragma once
#include "IGUICheckBox.h"
namespace irr
{
namespace gui
{
class CGUICheckBox : public IGUICheckBox
{
public:
//! constructor
CGUICheckBox(bool checked, IGUIEnvironment* environment, IGUIElement* parent, s32 id, core::rect<s32> rectangle);
//! set if box is checked
void setChecked(bool checked) override;
//! returns if box is checked
bool isChecked() const override;
//! Sets whether to draw the background
void setDrawBackground(bool draw) override;
//! Checks if background drawing is enabled
/** \return true if background drawing is enabled, false otherwise */
bool isDrawBackgroundEnabled() const override;
//! Sets whether to draw the border
void setDrawBorder(bool draw) override;
//! Checks if border drawing is enabled
/** \return true if border drawing is enabled, false otherwise */
bool isDrawBorderEnabled() const override;
//! called if an event happened.
bool OnEvent(const SEvent& event) override;
//! draws the element and its children
void draw() override;
private:
u32 CheckTime;
bool Pressed;
bool Checked;
bool Border;
bool Background;
};
} // end namespace gui
} // end namespace irr

File diff suppressed because it is too large Load Diff

View File

@ -1,108 +1,108 @@
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#pragma once
#include "IGUIComboBox.h"
#include "IGUIStaticText.h"
#include "irrString.h"
#include "irrArray.h"
namespace irr
{
namespace gui
{
class IGUIButton;
class IGUIListBox;
//! Single line edit box for editing simple text.
class CGUIComboBox : public IGUIComboBox
{
public:
//! constructor
CGUIComboBox(IGUIEnvironment* environment, IGUIElement* parent,
s32 id, core::rect<s32> rectangle);
//! Returns amount of items in box
u32 getItemCount() const override;
//! returns string of an item. the idx may be a value from 0 to itemCount-1
const wchar_t* getItem(u32 idx) const override;
//! Returns item data of an item. the idx may be a value from 0 to itemCount-1
u32 getItemData(u32 idx) const override;
//! Returns index based on item data
s32 getIndexForItemData( u32 data ) const override;
//! adds an item and returns the index of it
u32 addItem(const wchar_t* text, u32 data) override;
//! Removes an item from the combo box.
void removeItem(u32 id) override;
//! deletes all items in the combo box
void clear() override;
//! returns the text of the currently selected item
const wchar_t* getText() const override;
//! returns id of selected item. returns -1 if no item is selected.
s32 getSelected() const override;
//! sets the selected item. Set this to -1 if no item should be selected
void setSelected(s32 idx) override;
//! Sets the selected item and emits a change event.
/** Set this to -1 if no item should be selected */
void setAndSendSelected(s32 idx) override;
//! sets the text alignment of the text part
void setTextAlignment(EGUI_ALIGNMENT horizontal, EGUI_ALIGNMENT vertical) override;
//! Set the maximal number of rows for the selection listbox
void setMaxSelectionRows(u32 max) override;
//! Get the maximal number of rows for the selection listbox
u32 getMaxSelectionRows() const override;
//! called if an event happened.
bool OnEvent(const SEvent& event) override;
//! draws the element and its children
void draw() override;
private:
void openCloseMenu();
void sendSelectionChangedEvent();
void updateListButtonWidth(s32 width);
IGUIButton* ListButton;
IGUIStaticText* SelectedText;
IGUIListBox* ListBox;
IGUIElement *LastFocus;
struct SComboData
{
SComboData ( const wchar_t * text, u32 data )
: Name (text), Data ( data ) {}
core::stringw Name;
u32 Data;
};
core::array< SComboData > Items;
s32 Selected;
EGUI_ALIGNMENT HAlign, VAlign;
u32 MaxSelectionRows;
bool HasFocus;
IGUIFont* ActiveFont;
};
} // end namespace gui
} // end namespace irr
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#pragma once
#include "IGUIComboBox.h"
#include "IGUIStaticText.h"
#include "irrString.h"
#include "irrArray.h"
namespace irr
{
namespace gui
{
class IGUIButton;
class IGUIListBox;
//! Single line edit box for editing simple text.
class CGUIComboBox : public IGUIComboBox
{
public:
//! constructor
CGUIComboBox(IGUIEnvironment* environment, IGUIElement* parent,
s32 id, core::rect<s32> rectangle);
//! Returns amount of items in box
u32 getItemCount() const override;
//! returns string of an item. the idx may be a value from 0 to itemCount-1
const wchar_t* getItem(u32 idx) const override;
//! Returns item data of an item. the idx may be a value from 0 to itemCount-1
u32 getItemData(u32 idx) const override;
//! Returns index based on item data
s32 getIndexForItemData( u32 data ) const override;
//! adds an item and returns the index of it
u32 addItem(const wchar_t* text, u32 data) override;
//! Removes an item from the combo box.
void removeItem(u32 id) override;
//! deletes all items in the combo box
void clear() override;
//! returns the text of the currently selected item
const wchar_t* getText() const override;
//! returns id of selected item. returns -1 if no item is selected.
s32 getSelected() const override;
//! sets the selected item. Set this to -1 if no item should be selected
void setSelected(s32 idx) override;
//! Sets the selected item and emits a change event.
/** Set this to -1 if no item should be selected */
void setAndSendSelected(s32 idx) override;
//! sets the text alignment of the text part
void setTextAlignment(EGUI_ALIGNMENT horizontal, EGUI_ALIGNMENT vertical) override;
//! Set the maximal number of rows for the selection listbox
void setMaxSelectionRows(u32 max) override;
//! Get the maximal number of rows for the selection listbox
u32 getMaxSelectionRows() const override;
//! called if an event happened.
bool OnEvent(const SEvent& event) override;
//! draws the element and its children
void draw() override;
private:
void openCloseMenu();
void sendSelectionChangedEvent();
void updateListButtonWidth(s32 width);
IGUIButton* ListButton;
IGUIStaticText* SelectedText;
IGUIListBox* ListBox;
IGUIElement *LastFocus;
struct SComboData
{
SComboData ( const wchar_t * text, u32 data )
: Name (text), Data ( data ) {}
core::stringw Name;
u32 Data;
};
core::array< SComboData > Items;
s32 Selected;
EGUI_ALIGNMENT HAlign, VAlign;
u32 MaxSelectionRows;
bool HasFocus;
IGUIFont* ActiveFont;
};
} // end namespace gui
} // end namespace irr

File diff suppressed because it is too large Load Diff

View File

@ -1,198 +1,198 @@
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#pragma once
#include "IGUIEditBox.h"
#include "irrArray.h"
#include "IOSOperator.h"
namespace irr
{
namespace gui
{
class CGUIEditBox : public IGUIEditBox
{
public:
//! constructor
CGUIEditBox(const wchar_t* text, bool border, IGUIEnvironment* environment,
IGUIElement* parent, s32 id, const core::rect<s32>& rectangle);
//! destructor
virtual ~CGUIEditBox();
//! Sets another skin independent font.
void setOverrideFont(IGUIFont* font=0) override;
//! Gets the override font (if any)
/** \return The override font (may be 0) */
IGUIFont* getOverrideFont() const override;
//! Get the font which is used right now for drawing
/** Currently this is the override font when one is set and the
font of the active skin otherwise */
IGUIFont* getActiveFont() const override;
//! Sets another color for the text.
void setOverrideColor(video::SColor color) override;
//! Gets the override color
video::SColor getOverrideColor() const override;
//! Sets if the text should use the override color or the
//! color in the gui skin.
void enableOverrideColor(bool enable) override;
//! Checks if an override color is enabled
/** \return true if the override color is enabled, false otherwise */
bool isOverrideColorEnabled(void) const override;
//! Sets whether to draw the background
void setDrawBackground(bool draw) override;
//! Checks if background drawing is enabled
bool isDrawBackgroundEnabled() const override;
//! Turns the border on or off
void setDrawBorder(bool border) override;
//! Checks if border drawing is enabled
bool isDrawBorderEnabled() const override;
//! Enables or disables word wrap for using the edit box as multiline text editor.
void setWordWrap(bool enable) override;
//! Checks if word wrap is enabled
//! \return true if word wrap is enabled, false otherwise
bool isWordWrapEnabled() const override;
//! Enables or disables newlines.
/** \param enable: If set to true, the EGET_EDITBOX_ENTER event will not be fired,
instead a newline character will be inserted. */
void setMultiLine(bool enable) override;
//! Checks if multi line editing is enabled
//! \return true if mult-line is enabled, false otherwise
bool isMultiLineEnabled() const override;
//! Enables or disables automatic scrolling with cursor position
//! \param enable: If set to true, the text will move around with the cursor position
void setAutoScroll(bool enable) override;
//! Checks to see if automatic scrolling is enabled
//! \return true if automatic scrolling is enabled, false if not
bool isAutoScrollEnabled() const override;
//! Gets the size area of the text in the edit box
//! \return Returns the size in pixels of the text
core::dimension2du getTextDimension() override;
//! Sets text justification
void setTextAlignment(EGUI_ALIGNMENT horizontal, EGUI_ALIGNMENT vertical) override;
//! called if an event happened.
bool OnEvent(const SEvent& event) override;
//! draws the element and its children
void draw() override;
//! Sets the new caption of this element.
void setText(const wchar_t* text) override;
//! Sets the maximum amount of characters which may be entered in the box.
//! \param max: Maximum amount of characters. If 0, the character amount is
//! infinity.
void setMax(u32 max) override;
//! Returns maximum amount of characters, previously set by setMax();
u32 getMax() const override;
//! Set the character used for the cursor.
/** By default it's "_" */
void setCursorChar(const wchar_t cursorChar) override;
//! Get the character used for the cursor.
wchar_t getCursorChar() const override;
//! Set the blinktime for the cursor. 2x blinktime is one full cycle.
//** \param timeMs Blinktime in milliseconds. When set to 0 the cursor is constantly on without blinking */
void setCursorBlinkTime(irr::u32 timeMs) override;
//! Get the cursor blinktime
irr::u32 getCursorBlinkTime() const override;
//! Sets whether the edit box is a password box. Setting this to true will
/** disable MultiLine, WordWrap and the ability to copy with ctrl+c or ctrl+x
\param passwordBox: true to enable password, false to disable
\param passwordChar: the character that is displayed instead of letters */
void setPasswordBox(bool passwordBox, wchar_t passwordChar = L'*') override;
//! Returns true if the edit box is currently a password box.
bool isPasswordBox() const override;
//! Updates the absolute position, splits text if required
void updateAbsolutePosition() override;
//! Returns whether the element takes input from the IME
bool acceptsIME() override;
protected:
//! Breaks the single text line.
void breakText();
//! sets the area of the given line
void setTextRect(s32 line);
//! returns the line number that the cursor is on
s32 getLineFromPos(s32 pos);
//! adds a letter to the edit box
void inputChar(wchar_t c);
//! adds a string to the edit box
void inputString(const core::stringw &str);
//! calculates the current scroll position
void calculateScrollPos();
//! calculated the FrameRect
void calculateFrameRect();
//! send some gui event to parent
void sendGuiEvent(EGUI_EVENT_TYPE type);
//! set text markers
void setTextMarkers(s32 begin, s32 end);
//! delete current selection or next char
bool keyDelete();
bool processKey(const SEvent& event);
bool processMouse(const SEvent& event);
s32 getCursorPos(s32 x, s32 y);
bool OverwriteMode;
bool MouseMarking;
bool Border;
bool Background;
bool OverrideColorEnabled;
s32 MarkBegin;
s32 MarkEnd;
video::SColor OverrideColor;
gui::IGUIFont *OverrideFont, *LastBreakFont;
IOSOperator* Operator;
u32 BlinkStartTime;
irr::u32 CursorBlinkTime;
core::stringw CursorChar; // IGUIFont::draw needs stringw instead of wchar_t
s32 CursorPos;
s32 HScrollPos, VScrollPos; // scroll position in characters
u32 Max;
bool WordWrap, MultiLine, AutoScroll, PasswordBox;
wchar_t PasswordChar;
EGUI_ALIGNMENT HAlign, VAlign;
core::array< core::stringw > BrokenText;
core::array< s32 > BrokenTextPositions;
core::rect<s32> CurrentTextRect, FrameRect; // temporary values
};
} // end namespace gui
} // end namespace irr
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#pragma once
#include "IGUIEditBox.h"
#include "irrArray.h"
#include "IOSOperator.h"
namespace irr
{
namespace gui
{
class CGUIEditBox : public IGUIEditBox
{
public:
//! constructor
CGUIEditBox(const wchar_t* text, bool border, IGUIEnvironment* environment,
IGUIElement* parent, s32 id, const core::rect<s32>& rectangle);
//! destructor
virtual ~CGUIEditBox();
//! Sets another skin independent font.
void setOverrideFont(IGUIFont* font=0) override;
//! Gets the override font (if any)
/** \return The override font (may be 0) */
IGUIFont* getOverrideFont() const override;
//! Get the font which is used right now for drawing
/** Currently this is the override font when one is set and the
font of the active skin otherwise */
IGUIFont* getActiveFont() const override;
//! Sets another color for the text.
void setOverrideColor(video::SColor color) override;
//! Gets the override color
video::SColor getOverrideColor() const override;
//! Sets if the text should use the override color or the
//! color in the gui skin.
void enableOverrideColor(bool enable) override;
//! Checks if an override color is enabled
/** \return true if the override color is enabled, false otherwise */
bool isOverrideColorEnabled(void) const override;
//! Sets whether to draw the background
void setDrawBackground(bool draw) override;
//! Checks if background drawing is enabled
bool isDrawBackgroundEnabled() const override;
//! Turns the border on or off
void setDrawBorder(bool border) override;
//! Checks if border drawing is enabled
bool isDrawBorderEnabled() const override;
//! Enables or disables word wrap for using the edit box as multiline text editor.
void setWordWrap(bool enable) override;
//! Checks if word wrap is enabled
//! \return true if word wrap is enabled, false otherwise
bool isWordWrapEnabled() const override;
//! Enables or disables newlines.
/** \param enable: If set to true, the EGET_EDITBOX_ENTER event will not be fired,
instead a newline character will be inserted. */
void setMultiLine(bool enable) override;
//! Checks if multi line editing is enabled
//! \return true if mult-line is enabled, false otherwise
bool isMultiLineEnabled() const override;
//! Enables or disables automatic scrolling with cursor position
//! \param enable: If set to true, the text will move around with the cursor position
void setAutoScroll(bool enable) override;
//! Checks to see if automatic scrolling is enabled
//! \return true if automatic scrolling is enabled, false if not
bool isAutoScrollEnabled() const override;
//! Gets the size area of the text in the edit box
//! \return Returns the size in pixels of the text
core::dimension2du getTextDimension() override;
//! Sets text justification
void setTextAlignment(EGUI_ALIGNMENT horizontal, EGUI_ALIGNMENT vertical) override;
//! called if an event happened.
bool OnEvent(const SEvent& event) override;
//! draws the element and its children
void draw() override;
//! Sets the new caption of this element.
void setText(const wchar_t* text) override;
//! Sets the maximum amount of characters which may be entered in the box.
//! \param max: Maximum amount of characters. If 0, the character amount is
//! infinity.
void setMax(u32 max) override;
//! Returns maximum amount of characters, previously set by setMax();
u32 getMax() const override;
//! Set the character used for the cursor.
/** By default it's "_" */
void setCursorChar(const wchar_t cursorChar) override;
//! Get the character used for the cursor.
wchar_t getCursorChar() const override;
//! Set the blinktime for the cursor. 2x blinktime is one full cycle.
//** \param timeMs Blinktime in milliseconds. When set to 0 the cursor is constantly on without blinking */
void setCursorBlinkTime(irr::u32 timeMs) override;
//! Get the cursor blinktime
irr::u32 getCursorBlinkTime() const override;
//! Sets whether the edit box is a password box. Setting this to true will
/** disable MultiLine, WordWrap and the ability to copy with ctrl+c or ctrl+x
\param passwordBox: true to enable password, false to disable
\param passwordChar: the character that is displayed instead of letters */
void setPasswordBox(bool passwordBox, wchar_t passwordChar = L'*') override;
//! Returns true if the edit box is currently a password box.
bool isPasswordBox() const override;
//! Updates the absolute position, splits text if required
void updateAbsolutePosition() override;
//! Returns whether the element takes input from the IME
bool acceptsIME() override;
protected:
//! Breaks the single text line.
void breakText();
//! sets the area of the given line
void setTextRect(s32 line);
//! returns the line number that the cursor is on
s32 getLineFromPos(s32 pos);
//! adds a letter to the edit box
void inputChar(wchar_t c);
//! adds a string to the edit box
void inputString(const core::stringw &str);
//! calculates the current scroll position
void calculateScrollPos();
//! calculated the FrameRect
void calculateFrameRect();
//! send some gui event to parent
void sendGuiEvent(EGUI_EVENT_TYPE type);
//! set text markers
void setTextMarkers(s32 begin, s32 end);
//! delete current selection or next char
bool keyDelete();
bool processKey(const SEvent& event);
bool processMouse(const SEvent& event);
s32 getCursorPos(s32 x, s32 y);
bool OverwriteMode;
bool MouseMarking;
bool Border;
bool Background;
bool OverrideColorEnabled;
s32 MarkBegin;
s32 MarkEnd;
video::SColor OverrideColor;
gui::IGUIFont *OverrideFont, *LastBreakFont;
IOSOperator* Operator;
u32 BlinkStartTime;
irr::u32 CursorBlinkTime;
core::stringw CursorChar; // IGUIFont::draw needs stringw instead of wchar_t
s32 CursorPos;
s32 HScrollPos, VScrollPos; // scroll position in characters
u32 Max;
bool WordWrap, MultiLine, AutoScroll, PasswordBox;
wchar_t PasswordChar;
EGUI_ALIGNMENT HAlign, VAlign;
core::array< core::stringw > BrokenText;
core::array< s32 > BrokenTextPositions;
core::rect<s32> CurrentTextRect, FrameRect; // temporary values
};
} // end namespace gui
} // end namespace irr

File diff suppressed because it is too large Load Diff

View File

@ -1,228 +1,228 @@
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#pragma once
#include "IGUIEnvironment.h"
#include "IGUIElement.h"
#include "irrArray.h"
#include "IFileSystem.h"
#include "IOSOperator.h"
namespace irr
{
namespace gui
{
class CGUIEnvironment : public IGUIEnvironment, public IGUIElement
{
public:
//! constructor
CGUIEnvironment(io::IFileSystem* fs, video::IVideoDriver* driver, IOSOperator* op);
//! destructor
virtual ~CGUIEnvironment();
//! draws all gui elements
void drawAll(bool useScreenSize) override;
//! returns the current video driver
video::IVideoDriver* getVideoDriver() const override;
//! returns pointer to the filesystem
io::IFileSystem* getFileSystem() const override;
//! returns a pointer to the OS operator
IOSOperator* getOSOperator() const override;
//! posts an input event to the environment
bool postEventFromUser(const SEvent& event) override;
//! This sets a new event receiver for gui events. Usually you do not have to
//! use this method, it is used by the internal engine.
void setUserEventReceiver(IEventReceiver* evr) override;
//! removes all elements from the environment
void clear() override;
//! called if an event happened.
bool OnEvent(const SEvent& event) override;
//! returns the current gui skin
IGUISkin* getSkin() const override;
//! Sets a new GUI Skin
void setSkin(IGUISkin* skin) override;
//! Creates a new GUI Skin based on a template.
/** \return Returns a pointer to the created skin.
If you no longer need the skin, you should call IGUISkin::drop().
See IReferenceCounted::drop() for more information. */
IGUISkin* createSkin(EGUI_SKIN_TYPE type) override;
//! Creates the image list from the given texture.
virtual IGUIImageList* createImageList(video::ITexture* texture,
core::dimension2d<s32> imageSize, bool useAlphaChannel) override;
//! returns the font
IGUIFont* getFont(const io::path& filename) override;
//! add an externally loaded font
IGUIFont* addFont(const io::path& name, IGUIFont* font) override;
//! remove loaded font
void removeFont(IGUIFont* font) override;
//! returns default font
IGUIFont* getBuiltInFont() const override;
//! returns the sprite bank
IGUISpriteBank* getSpriteBank(const io::path& filename) override;
//! returns the sprite bank
IGUISpriteBank* addEmptySpriteBank(const io::path& name) override;
//! adds an button. The returned pointer must not be dropped.
IGUIButton* addButton(const core::rect<s32>& rectangle, IGUIElement* parent=0, s32 id=-1, const wchar_t* text=0,const wchar_t* tooltiptext = 0) override;
//! adds a scrollbar. The returned pointer must not be dropped.
virtual IGUIScrollBar* addScrollBar(bool horizontal, const core::rect<s32>& rectangle,
IGUIElement* parent=0, s32 id=-1) override;
//! Adds an image element.
virtual IGUIImage* addImage(video::ITexture* image, core::position2d<s32> pos,
bool useAlphaChannel=true, IGUIElement* parent=0, s32 id=-1, const wchar_t* text=0) override;
//! adds an image. The returned pointer must not be dropped.
virtual IGUIImage* addImage(const core::rect<s32>& rectangle,
IGUIElement* parent=0, s32 id=-1, const wchar_t* text=0, bool useAlphaChannel=true) override;
//! adds a checkbox
virtual IGUICheckBox* addCheckBox(bool checked, const core::rect<s32>& rectangle,
IGUIElement* parent=0, s32 id=-1, const wchar_t* text=0) override;
//! adds a list box
virtual IGUIListBox* addListBox(const core::rect<s32>& rectangle,
IGUIElement* parent=0, s32 id=-1, bool drawBackground=false) override;
//! Adds a file open dialog.
virtual IGUIFileOpenDialog* addFileOpenDialog(const wchar_t* title = 0,
bool modal=true, IGUIElement* parent=0, s32 id=-1,
bool restoreCWD=false, io::path::char_type* startDir=0) override;
//! adds a static text. The returned pointer must not be dropped.
virtual IGUIStaticText* addStaticText(const wchar_t* text, const core::rect<s32>& rectangle,
bool border=false, bool wordWrap=true, IGUIElement* parent=0, s32 id=-1, bool drawBackground = false) override;
//! Adds an edit box. The returned pointer must not be dropped.
virtual IGUIEditBox* addEditBox(const wchar_t* text, const core::rect<s32>& rectangle,
bool border=false, IGUIElement* parent=0, s32 id=-1) override;
//! Adds a tab control to the environment.
virtual IGUITabControl* addTabControl(const core::rect<s32>& rectangle,
IGUIElement* parent=0, bool fillbackground=false, bool border=true, s32 id=-1) override;
//! Adds tab to the environment.
virtual IGUITab* addTab(const core::rect<s32>& rectangle,
IGUIElement* parent=0, s32 id=-1) override;
//! Adds a combo box to the environment.
virtual IGUIComboBox* addComboBox(const core::rect<s32>& rectangle,
IGUIElement* parent=0, s32 id=-1) override;
//! sets the focus to an element
bool setFocus(IGUIElement* element) override;
//! removes the focus from an element
bool removeFocus(IGUIElement* element) override;
//! Returns if the element has focus
bool hasFocus(const IGUIElement* element, bool checkSubElements=false) const override;
//! Returns the element with the focus
IGUIElement* getFocus() const override;
//! Returns the element last known to be under the mouse
IGUIElement* getHovered() const override;
//! Returns the root gui element.
IGUIElement* getRootGUIElement() override;
void OnPostRender( u32 time ) override;
//! Find the next element which would be selected when pressing the tab-key
IGUIElement* getNextElement(bool reverse=false, bool group=false) override;
//! Set the way the gui will handle focus changes
void setFocusBehavior(u32 flags) override;
//! Get the way the gui does handle focus changes
u32 getFocusBehavior() const override;
//! Adds a IGUIElement to deletion queue.
void addToDeletionQueue(IGUIElement* element) override;
private:
//! clears the deletion queue
void clearDeletionQueue();
void updateHoveredElement(core::position2d<s32> mousePos);
void loadBuiltInFont();
struct SFont
{
io::SNamedPath NamedPath;
IGUIFont* Font;
bool operator < (const SFont& other) const
{
return (NamedPath < other.NamedPath);
}
};
struct SSpriteBank
{
io::SNamedPath NamedPath;
IGUISpriteBank* Bank;
bool operator < (const SSpriteBank& other) const
{
return (NamedPath < other.NamedPath);
}
};
struct SToolTip
{
IGUIStaticText* Element;
u32 LastTime;
u32 EnterTime;
u32 LaunchTime;
u32 RelaunchTime;
};
SToolTip ToolTip;
core::array<SFont> Fonts;
core::array<SSpriteBank> Banks;
video::IVideoDriver* Driver;
IGUIElement* Hovered;
IGUIElement* HoveredNoSubelement; // subelements replaced by their parent, so you only have 'real' elements here
IGUIElement* Focus;
core::position2d<s32> LastHoveredMousePos;
IGUISkin* CurrentSkin;
io::IFileSystem* FileSystem;
IEventReceiver* UserReceiver;
IOSOperator* Operator;
u32 FocusFlags;
core::array<IGUIElement*> DeletionQueue;
static const io::path DefaultFontName;
};
} // end namespace gui
} // end namespace irr
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#pragma once
#include "IGUIEnvironment.h"
#include "IGUIElement.h"
#include "irrArray.h"
#include "IFileSystem.h"
#include "IOSOperator.h"
namespace irr
{
namespace gui
{
class CGUIEnvironment : public IGUIEnvironment, public IGUIElement
{
public:
//! constructor
CGUIEnvironment(io::IFileSystem* fs, video::IVideoDriver* driver, IOSOperator* op);
//! destructor
virtual ~CGUIEnvironment();
//! draws all gui elements
void drawAll(bool useScreenSize) override;
//! returns the current video driver
video::IVideoDriver* getVideoDriver() const override;
//! returns pointer to the filesystem
io::IFileSystem* getFileSystem() const override;
//! returns a pointer to the OS operator
IOSOperator* getOSOperator() const override;
//! posts an input event to the environment
bool postEventFromUser(const SEvent& event) override;
//! This sets a new event receiver for gui events. Usually you do not have to
//! use this method, it is used by the internal engine.
void setUserEventReceiver(IEventReceiver* evr) override;
//! removes all elements from the environment
void clear() override;
//! called if an event happened.
bool OnEvent(const SEvent& event) override;
//! returns the current gui skin
IGUISkin* getSkin() const override;
//! Sets a new GUI Skin
void setSkin(IGUISkin* skin) override;
//! Creates a new GUI Skin based on a template.
/** \return Returns a pointer to the created skin.
If you no longer need the skin, you should call IGUISkin::drop().
See IReferenceCounted::drop() for more information. */
IGUISkin* createSkin(EGUI_SKIN_TYPE type) override;
//! Creates the image list from the given texture.
virtual IGUIImageList* createImageList(video::ITexture* texture,
core::dimension2d<s32> imageSize, bool useAlphaChannel) override;
//! returns the font
IGUIFont* getFont(const io::path& filename) override;
//! add an externally loaded font
IGUIFont* addFont(const io::path& name, IGUIFont* font) override;
//! remove loaded font
void removeFont(IGUIFont* font) override;
//! returns default font
IGUIFont* getBuiltInFont() const override;
//! returns the sprite bank
IGUISpriteBank* getSpriteBank(const io::path& filename) override;
//! returns the sprite bank
IGUISpriteBank* addEmptySpriteBank(const io::path& name) override;
//! adds an button. The returned pointer must not be dropped.
IGUIButton* addButton(const core::rect<s32>& rectangle, IGUIElement* parent=0, s32 id=-1, const wchar_t* text=0,const wchar_t* tooltiptext = 0) override;
//! adds a scrollbar. The returned pointer must not be dropped.
virtual IGUIScrollBar* addScrollBar(bool horizontal, const core::rect<s32>& rectangle,
IGUIElement* parent=0, s32 id=-1) override;
//! Adds an image element.
virtual IGUIImage* addImage(video::ITexture* image, core::position2d<s32> pos,
bool useAlphaChannel=true, IGUIElement* parent=0, s32 id=-1, const wchar_t* text=0) override;
//! adds an image. The returned pointer must not be dropped.
virtual IGUIImage* addImage(const core::rect<s32>& rectangle,
IGUIElement* parent=0, s32 id=-1, const wchar_t* text=0, bool useAlphaChannel=true) override;
//! adds a checkbox
virtual IGUICheckBox* addCheckBox(bool checked, const core::rect<s32>& rectangle,
IGUIElement* parent=0, s32 id=-1, const wchar_t* text=0) override;
//! adds a list box
virtual IGUIListBox* addListBox(const core::rect<s32>& rectangle,
IGUIElement* parent=0, s32 id=-1, bool drawBackground=false) override;
//! Adds a file open dialog.
virtual IGUIFileOpenDialog* addFileOpenDialog(const wchar_t* title = 0,
bool modal=true, IGUIElement* parent=0, s32 id=-1,
bool restoreCWD=false, io::path::char_type* startDir=0) override;
//! adds a static text. The returned pointer must not be dropped.
virtual IGUIStaticText* addStaticText(const wchar_t* text, const core::rect<s32>& rectangle,
bool border=false, bool wordWrap=true, IGUIElement* parent=0, s32 id=-1, bool drawBackground = false) override;
//! Adds an edit box. The returned pointer must not be dropped.
virtual IGUIEditBox* addEditBox(const wchar_t* text, const core::rect<s32>& rectangle,
bool border=false, IGUIElement* parent=0, s32 id=-1) override;
//! Adds a tab control to the environment.
virtual IGUITabControl* addTabControl(const core::rect<s32>& rectangle,
IGUIElement* parent=0, bool fillbackground=false, bool border=true, s32 id=-1) override;
//! Adds tab to the environment.
virtual IGUITab* addTab(const core::rect<s32>& rectangle,
IGUIElement* parent=0, s32 id=-1) override;
//! Adds a combo box to the environment.
virtual IGUIComboBox* addComboBox(const core::rect<s32>& rectangle,
IGUIElement* parent=0, s32 id=-1) override;
//! sets the focus to an element
bool setFocus(IGUIElement* element) override;
//! removes the focus from an element
bool removeFocus(IGUIElement* element) override;
//! Returns if the element has focus
bool hasFocus(const IGUIElement* element, bool checkSubElements=false) const override;
//! Returns the element with the focus
IGUIElement* getFocus() const override;
//! Returns the element last known to be under the mouse
IGUIElement* getHovered() const override;
//! Returns the root gui element.
IGUIElement* getRootGUIElement() override;
void OnPostRender( u32 time ) override;
//! Find the next element which would be selected when pressing the tab-key
IGUIElement* getNextElement(bool reverse=false, bool group=false) override;
//! Set the way the gui will handle focus changes
void setFocusBehavior(u32 flags) override;
//! Get the way the gui does handle focus changes
u32 getFocusBehavior() const override;
//! Adds a IGUIElement to deletion queue.
void addToDeletionQueue(IGUIElement* element) override;
private:
//! clears the deletion queue
void clearDeletionQueue();
void updateHoveredElement(core::position2d<s32> mousePos);
void loadBuiltInFont();
struct SFont
{
io::SNamedPath NamedPath;
IGUIFont* Font;
bool operator < (const SFont& other) const
{
return (NamedPath < other.NamedPath);
}
};
struct SSpriteBank
{
io::SNamedPath NamedPath;
IGUISpriteBank* Bank;
bool operator < (const SSpriteBank& other) const
{
return (NamedPath < other.NamedPath);
}
};
struct SToolTip
{
IGUIStaticText* Element;
u32 LastTime;
u32 EnterTime;
u32 LaunchTime;
u32 RelaunchTime;
};
SToolTip ToolTip;
core::array<SFont> Fonts;
core::array<SSpriteBank> Banks;
video::IVideoDriver* Driver;
IGUIElement* Hovered;
IGUIElement* HoveredNoSubelement; // subelements replaced by their parent, so you only have 'real' elements here
IGUIElement* Focus;
core::position2d<s32> LastHoveredMousePos;
IGUISkin* CurrentSkin;
io::IFileSystem* FileSystem;
IEventReceiver* UserReceiver;
IOSOperator* Operator;
u32 FocusFlags;
core::array<IGUIElement*> DeletionQueue;
static const io::path DefaultFontName;
};
} // end namespace gui
} // end namespace irr

View File

@ -1,412 +1,412 @@
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#include "CGUIFileOpenDialog.h"
#include "IGUISkin.h"
#include "IGUIEnvironment.h"
#include "IVideoDriver.h"
#include "IGUIButton.h"
#include "IGUIStaticText.h"
#include "IGUIFont.h"
#include "IGUIFontBitmap.h"
#include "IFileList.h"
#include "os.h"
namespace irr
{
namespace gui
{
const s32 FOD_WIDTH = 350;
const s32 FOD_HEIGHT = 250;
//! constructor
CGUIFileOpenDialog::CGUIFileOpenDialog(const wchar_t* title,
IGUIEnvironment* environment, IGUIElement* parent, s32 id,
bool restoreCWD, io::path::char_type* startDir)
: IGUIFileOpenDialog(environment, parent, id,
core::rect<s32>((parent->getAbsolutePosition().getWidth()-FOD_WIDTH)/2,
(parent->getAbsolutePosition().getHeight()-FOD_HEIGHT)/2,
(parent->getAbsolutePosition().getWidth()-FOD_WIDTH)/2+FOD_WIDTH,
(parent->getAbsolutePosition().getHeight()-FOD_HEIGHT)/2+FOD_HEIGHT)),
FileNameText(0), FileList(0), Dragging(false)
{
#ifdef _DEBUG
IGUIElement::setDebugName("CGUIFileOpenDialog");
#endif
Text = title;
FileSystem = Environment?Environment->getFileSystem():0;
if (FileSystem)
{
FileSystem->grab();
if (restoreCWD)
RestoreDirectory = FileSystem->getWorkingDirectory();
if (startDir)
{
StartDirectory = startDir;
FileSystem->changeWorkingDirectoryTo(startDir);
}
}
else
return;
IGUISpriteBank* sprites = 0;
video::SColor color(255,255,255,255);
IGUISkin* skin = Environment->getSkin();
if (skin)
{
sprites = skin->getSpriteBank();
color = skin->getColor(EGDC_WINDOW_SYMBOL);
}
const s32 buttonw = skin ? skin->getSize(EGDS_WINDOW_BUTTON_WIDTH) : 2;
const s32 posx = RelativeRect.getWidth() - buttonw - 4;
CloseButton = Environment->addButton(core::rect<s32>(posx, 3, posx + buttonw, 3 + buttonw), this, -1,
L"", skin ? skin->getDefaultText(EGDT_WINDOW_CLOSE) : L"Close");
CloseButton->setSubElement(true);
CloseButton->setTabStop(false);
if (sprites && skin)
{
CloseButton->setSpriteBank(sprites);
CloseButton->setSprite(EGBS_BUTTON_UP, skin->getIcon(EGDI_WINDOW_CLOSE), color);
CloseButton->setSprite(EGBS_BUTTON_DOWN, skin->getIcon(EGDI_WINDOW_CLOSE), color);
}
CloseButton->setAlignment(EGUIA_LOWERRIGHT, EGUIA_LOWERRIGHT, EGUIA_UPPERLEFT, EGUIA_UPPERLEFT);
CloseButton->grab();
OKButton = Environment->addButton(
core::rect<s32>(RelativeRect.getWidth()-80, 30, RelativeRect.getWidth()-10, 50),
this, -1, skin ? skin->getDefaultText(EGDT_MSG_BOX_OK) : L"OK");
OKButton->setSubElement(true);
OKButton->setAlignment(EGUIA_LOWERRIGHT, EGUIA_LOWERRIGHT, EGUIA_UPPERLEFT, EGUIA_UPPERLEFT);
OKButton->grab();
CancelButton = Environment->addButton(
core::rect<s32>(RelativeRect.getWidth()-80, 55, RelativeRect.getWidth()-10, 75),
this, -1, skin ? skin->getDefaultText(EGDT_MSG_BOX_CANCEL) : L"Cancel");
CancelButton->setSubElement(true);
CancelButton->setAlignment(EGUIA_LOWERRIGHT, EGUIA_LOWERRIGHT, EGUIA_UPPERLEFT, EGUIA_UPPERLEFT);
CancelButton->grab();
FileBox = Environment->addListBox(core::rect<s32>(10, 55, RelativeRect.getWidth()-90, 230), this, -1, true);
FileBox->setSubElement(true);
FileBox->setAlignment(EGUIA_UPPERLEFT, EGUIA_LOWERRIGHT, EGUIA_UPPERLEFT, EGUIA_LOWERRIGHT);
FileBox->grab();
FileNameText = Environment->addEditBox(0, core::rect<s32>(10, 30, RelativeRect.getWidth()-90, 50), true, this);
FileNameText->setSubElement(true);
FileNameText->setAlignment(EGUIA_UPPERLEFT, EGUIA_LOWERRIGHT, EGUIA_UPPERLEFT, EGUIA_UPPERLEFT);
FileNameText->grab();
setTabGroup(true);
fillListBox();
}
//! destructor
CGUIFileOpenDialog::~CGUIFileOpenDialog()
{
if (CloseButton)
CloseButton->drop();
if (OKButton)
OKButton->drop();
if (CancelButton)
CancelButton->drop();
if (FileBox)
FileBox->drop();
if (FileNameText)
FileNameText->drop();
if (FileSystem)
{
// revert to original CWD if path was set in constructor
if (RestoreDirectory.size())
FileSystem->changeWorkingDirectoryTo(RestoreDirectory);
FileSystem->drop();
}
if (FileList)
FileList->drop();
}
//! returns the filename of the selected file. Returns NULL, if no file was selected.
const wchar_t* CGUIFileOpenDialog::getFileName() const
{
return FileNameW.c_str();
}
const io::path& CGUIFileOpenDialog::getFileNameP() const
{
return FileName;
}
//! Returns the directory of the selected file. Returns NULL, if no directory was selected.
const io::path& CGUIFileOpenDialog::getDirectoryName() const
{
return FileDirectoryFlat;
}
const wchar_t* CGUIFileOpenDialog::getDirectoryNameW() const
{
return FileDirectoryFlatW.c_str();
}
void CGUIFileOpenDialog::setFileName(const irr::io::path& name)
{
FileName = name;
pathToStringW(FileNameW, FileName);
}
void CGUIFileOpenDialog::setDirectoryName(const irr::io::path& name)
{
FileDirectory = name;
FileDirectoryFlat = name;
FileSystem->flattenFilename (FileDirectoryFlat );
pathToStringW(FileDirectoryFlatW, FileDirectoryFlat);
}
//! called if an event happened.
bool CGUIFileOpenDialog::OnEvent(const SEvent& event)
{
if (isEnabled())
{
switch(event.EventType)
{
case EET_GUI_EVENT:
switch(event.GUIEvent.EventType)
{
case EGET_ELEMENT_FOCUS_LOST:
Dragging = false;
break;
case EGET_BUTTON_CLICKED:
if (event.GUIEvent.Caller == CloseButton ||
event.GUIEvent.Caller == CancelButton)
{
sendCancelEvent();
remove();
return true;
}
else
if (event.GUIEvent.Caller == OKButton )
{
if ( FileDirectory != L"" )
{
sendSelectedEvent( EGET_DIRECTORY_SELECTED );
}
if ( FileName != L"" )
{
sendSelectedEvent( EGET_FILE_SELECTED );
remove();
return true;
}
}
break;
case EGET_LISTBOX_CHANGED:
{
s32 selected = FileBox->getSelected();
if (FileList && FileSystem)
{
if (FileList->isDirectory(selected))
{
setFileName("");
setDirectoryName(FileList->getFullFileName(selected));
}
else
{
setDirectoryName("");
setFileName(FileList->getFullFileName(selected));
}
return true;
}
}
break;
case EGET_LISTBOX_SELECTED_AGAIN:
{
const s32 selected = FileBox->getSelected();
if (FileList && FileSystem)
{
if (FileList->isDirectory(selected))
{
setDirectoryName(FileList->getFullFileName(selected));
FileSystem->changeWorkingDirectoryTo(FileDirectory );
fillListBox();
setFileName("");
}
else
{
setFileName(FileList->getFullFileName(selected));
}
return true;
}
}
break;
case EGET_EDITBOX_ENTER:
if (event.GUIEvent.Caller == FileNameText)
{
io::path dir( FileNameText->getText () );
if ( FileSystem->changeWorkingDirectoryTo( dir ) )
{
fillListBox();
setFileName("");
}
return true;
}
break;
default:
break;
}
break;
case EET_MOUSE_INPUT_EVENT:
switch(event.MouseInput.Event)
{
case EMIE_MOUSE_WHEEL:
return FileBox->OnEvent(event);
case EMIE_LMOUSE_PRESSED_DOWN:
DragStart.X = event.MouseInput.X;
DragStart.Y = event.MouseInput.Y;
Dragging = true;
return true;
case EMIE_LMOUSE_LEFT_UP:
Dragging = false;
return true;
case EMIE_MOUSE_MOVED:
if ( !event.MouseInput.isLeftPressed () )
Dragging = false;
if (Dragging)
{
// gui window should not be dragged outside its parent
if (Parent)
if (event.MouseInput.X < Parent->getAbsolutePosition().UpperLeftCorner.X +1 ||
event.MouseInput.Y < Parent->getAbsolutePosition().UpperLeftCorner.Y +1 ||
event.MouseInput.X > Parent->getAbsolutePosition().LowerRightCorner.X -1 ||
event.MouseInput.Y > Parent->getAbsolutePosition().LowerRightCorner.Y -1)
return true;
move(core::position2d<s32>(event.MouseInput.X - DragStart.X, event.MouseInput.Y - DragStart.Y));
DragStart.X = event.MouseInput.X;
DragStart.Y = event.MouseInput.Y;
return true;
}
break;
default:
break;
}
default:
break;
}
}
return IGUIElement::OnEvent(event);
}
//! draws the element and its children
void CGUIFileOpenDialog::draw()
{
if (!IsVisible)
return;
IGUISkin* skin = Environment->getSkin();
core::rect<s32> rect = AbsoluteRect;
rect = skin->draw3DWindowBackground(this, true, skin->getColor(EGDC_ACTIVE_BORDER),
rect, &AbsoluteClippingRect);
if (Text.size())
{
rect.UpperLeftCorner.X += 2;
rect.LowerRightCorner.X -= skin->getSize(EGDS_WINDOW_BUTTON_WIDTH) + 5;
IGUIFont* font = skin->getFont(EGDF_WINDOW);
if (font)
font->draw(Text.c_str(), rect,
skin->getColor(EGDC_ACTIVE_CAPTION),
false, true, &AbsoluteClippingRect);
}
IGUIElement::draw();
}
void CGUIFileOpenDialog::pathToStringW(irr::core::stringw& result, const irr::io::path& p)
{
core::multibyteToWString(result, p);
}
//! fills the listbox with files.
void CGUIFileOpenDialog::fillListBox()
{
IGUISkin *skin = Environment->getSkin();
if (!FileSystem || !FileBox || !skin)
return;
if (FileList)
FileList->drop();
FileBox->clear();
FileList = FileSystem->createFileList();
core::stringw s;
if (FileList)
{
for (u32 i=0; i < FileList->getFileCount(); ++i)
{
pathToStringW(s, FileList->getFileName(i));
FileBox->addItem(s.c_str(), skin->getIcon(FileList->isDirectory(i) ? EGDI_DIRECTORY : EGDI_FILE));
}
}
if (FileNameText)
{
setDirectoryName(FileSystem->getWorkingDirectory());
pathToStringW(s, FileDirectory);
FileNameText->setText(s.c_str());
}
}
//! sends the event that the file has been selected.
void CGUIFileOpenDialog::sendSelectedEvent( EGUI_EVENT_TYPE type)
{
SEvent event;
event.EventType = EET_GUI_EVENT;
event.GUIEvent.Caller = this;
event.GUIEvent.Element = 0;
event.GUIEvent.EventType = type;
Parent->OnEvent(event);
}
//! sends the event that the file choose process has been cancelled
void CGUIFileOpenDialog::sendCancelEvent()
{
SEvent event;
event.EventType = EET_GUI_EVENT;
event.GUIEvent.Caller = this;
event.GUIEvent.Element = 0;
event.GUIEvent.EventType = EGET_FILE_CHOOSE_DIALOG_CANCELLED;
Parent->OnEvent(event);
}
} // end namespace gui
} // end namespace irr
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#include "CGUIFileOpenDialog.h"
#include "IGUISkin.h"
#include "IGUIEnvironment.h"
#include "IVideoDriver.h"
#include "IGUIButton.h"
#include "IGUIStaticText.h"
#include "IGUIFont.h"
#include "IGUIFontBitmap.h"
#include "IFileList.h"
#include "os.h"
namespace irr
{
namespace gui
{
const s32 FOD_WIDTH = 350;
const s32 FOD_HEIGHT = 250;
//! constructor
CGUIFileOpenDialog::CGUIFileOpenDialog(const wchar_t* title,
IGUIEnvironment* environment, IGUIElement* parent, s32 id,
bool restoreCWD, io::path::char_type* startDir)
: IGUIFileOpenDialog(environment, parent, id,
core::rect<s32>((parent->getAbsolutePosition().getWidth()-FOD_WIDTH)/2,
(parent->getAbsolutePosition().getHeight()-FOD_HEIGHT)/2,
(parent->getAbsolutePosition().getWidth()-FOD_WIDTH)/2+FOD_WIDTH,
(parent->getAbsolutePosition().getHeight()-FOD_HEIGHT)/2+FOD_HEIGHT)),
FileNameText(0), FileList(0), Dragging(false)
{
#ifdef _DEBUG
IGUIElement::setDebugName("CGUIFileOpenDialog");
#endif
Text = title;
FileSystem = Environment?Environment->getFileSystem():0;
if (FileSystem)
{
FileSystem->grab();
if (restoreCWD)
RestoreDirectory = FileSystem->getWorkingDirectory();
if (startDir)
{
StartDirectory = startDir;
FileSystem->changeWorkingDirectoryTo(startDir);
}
}
else
return;
IGUISpriteBank* sprites = 0;
video::SColor color(255,255,255,255);
IGUISkin* skin = Environment->getSkin();
if (skin)
{
sprites = skin->getSpriteBank();
color = skin->getColor(EGDC_WINDOW_SYMBOL);
}
const s32 buttonw = skin ? skin->getSize(EGDS_WINDOW_BUTTON_WIDTH) : 2;
const s32 posx = RelativeRect.getWidth() - buttonw - 4;
CloseButton = Environment->addButton(core::rect<s32>(posx, 3, posx + buttonw, 3 + buttonw), this, -1,
L"", skin ? skin->getDefaultText(EGDT_WINDOW_CLOSE) : L"Close");
CloseButton->setSubElement(true);
CloseButton->setTabStop(false);
if (sprites && skin)
{
CloseButton->setSpriteBank(sprites);
CloseButton->setSprite(EGBS_BUTTON_UP, skin->getIcon(EGDI_WINDOW_CLOSE), color);
CloseButton->setSprite(EGBS_BUTTON_DOWN, skin->getIcon(EGDI_WINDOW_CLOSE), color);
}
CloseButton->setAlignment(EGUIA_LOWERRIGHT, EGUIA_LOWERRIGHT, EGUIA_UPPERLEFT, EGUIA_UPPERLEFT);
CloseButton->grab();
OKButton = Environment->addButton(
core::rect<s32>(RelativeRect.getWidth()-80, 30, RelativeRect.getWidth()-10, 50),
this, -1, skin ? skin->getDefaultText(EGDT_MSG_BOX_OK) : L"OK");
OKButton->setSubElement(true);
OKButton->setAlignment(EGUIA_LOWERRIGHT, EGUIA_LOWERRIGHT, EGUIA_UPPERLEFT, EGUIA_UPPERLEFT);
OKButton->grab();
CancelButton = Environment->addButton(
core::rect<s32>(RelativeRect.getWidth()-80, 55, RelativeRect.getWidth()-10, 75),
this, -1, skin ? skin->getDefaultText(EGDT_MSG_BOX_CANCEL) : L"Cancel");
CancelButton->setSubElement(true);
CancelButton->setAlignment(EGUIA_LOWERRIGHT, EGUIA_LOWERRIGHT, EGUIA_UPPERLEFT, EGUIA_UPPERLEFT);
CancelButton->grab();
FileBox = Environment->addListBox(core::rect<s32>(10, 55, RelativeRect.getWidth()-90, 230), this, -1, true);
FileBox->setSubElement(true);
FileBox->setAlignment(EGUIA_UPPERLEFT, EGUIA_LOWERRIGHT, EGUIA_UPPERLEFT, EGUIA_LOWERRIGHT);
FileBox->grab();
FileNameText = Environment->addEditBox(0, core::rect<s32>(10, 30, RelativeRect.getWidth()-90, 50), true, this);
FileNameText->setSubElement(true);
FileNameText->setAlignment(EGUIA_UPPERLEFT, EGUIA_LOWERRIGHT, EGUIA_UPPERLEFT, EGUIA_UPPERLEFT);
FileNameText->grab();
setTabGroup(true);
fillListBox();
}
//! destructor
CGUIFileOpenDialog::~CGUIFileOpenDialog()
{
if (CloseButton)
CloseButton->drop();
if (OKButton)
OKButton->drop();
if (CancelButton)
CancelButton->drop();
if (FileBox)
FileBox->drop();
if (FileNameText)
FileNameText->drop();
if (FileSystem)
{
// revert to original CWD if path was set in constructor
if (RestoreDirectory.size())
FileSystem->changeWorkingDirectoryTo(RestoreDirectory);
FileSystem->drop();
}
if (FileList)
FileList->drop();
}
//! returns the filename of the selected file. Returns NULL, if no file was selected.
const wchar_t* CGUIFileOpenDialog::getFileName() const
{
return FileNameW.c_str();
}
const io::path& CGUIFileOpenDialog::getFileNameP() const
{
return FileName;
}
//! Returns the directory of the selected file. Returns NULL, if no directory was selected.
const io::path& CGUIFileOpenDialog::getDirectoryName() const
{
return FileDirectoryFlat;
}
const wchar_t* CGUIFileOpenDialog::getDirectoryNameW() const
{
return FileDirectoryFlatW.c_str();
}
void CGUIFileOpenDialog::setFileName(const irr::io::path& name)
{
FileName = name;
pathToStringW(FileNameW, FileName);
}
void CGUIFileOpenDialog::setDirectoryName(const irr::io::path& name)
{
FileDirectory = name;
FileDirectoryFlat = name;
FileSystem->flattenFilename (FileDirectoryFlat );
pathToStringW(FileDirectoryFlatW, FileDirectoryFlat);
}
//! called if an event happened.
bool CGUIFileOpenDialog::OnEvent(const SEvent& event)
{
if (isEnabled())
{
switch(event.EventType)
{
case EET_GUI_EVENT:
switch(event.GUIEvent.EventType)
{
case EGET_ELEMENT_FOCUS_LOST:
Dragging = false;
break;
case EGET_BUTTON_CLICKED:
if (event.GUIEvent.Caller == CloseButton ||
event.GUIEvent.Caller == CancelButton)
{
sendCancelEvent();
remove();
return true;
}
else
if (event.GUIEvent.Caller == OKButton )
{
if ( FileDirectory != L"" )
{
sendSelectedEvent( EGET_DIRECTORY_SELECTED );
}
if ( FileName != L"" )
{
sendSelectedEvent( EGET_FILE_SELECTED );
remove();
return true;
}
}
break;
case EGET_LISTBOX_CHANGED:
{
s32 selected = FileBox->getSelected();
if (FileList && FileSystem)
{
if (FileList->isDirectory(selected))
{
setFileName("");
setDirectoryName(FileList->getFullFileName(selected));
}
else
{
setDirectoryName("");
setFileName(FileList->getFullFileName(selected));
}
return true;
}
}
break;
case EGET_LISTBOX_SELECTED_AGAIN:
{
const s32 selected = FileBox->getSelected();
if (FileList && FileSystem)
{
if (FileList->isDirectory(selected))
{
setDirectoryName(FileList->getFullFileName(selected));
FileSystem->changeWorkingDirectoryTo(FileDirectory );
fillListBox();
setFileName("");
}
else
{
setFileName(FileList->getFullFileName(selected));
}
return true;
}
}
break;
case EGET_EDITBOX_ENTER:
if (event.GUIEvent.Caller == FileNameText)
{
io::path dir( FileNameText->getText () );
if ( FileSystem->changeWorkingDirectoryTo( dir ) )
{
fillListBox();
setFileName("");
}
return true;
}
break;
default:
break;
}
break;
case EET_MOUSE_INPUT_EVENT:
switch(event.MouseInput.Event)
{
case EMIE_MOUSE_WHEEL:
return FileBox->OnEvent(event);
case EMIE_LMOUSE_PRESSED_DOWN:
DragStart.X = event.MouseInput.X;
DragStart.Y = event.MouseInput.Y;
Dragging = true;
return true;
case EMIE_LMOUSE_LEFT_UP:
Dragging = false;
return true;
case EMIE_MOUSE_MOVED:
if ( !event.MouseInput.isLeftPressed () )
Dragging = false;
if (Dragging)
{
// gui window should not be dragged outside its parent
if (Parent)
if (event.MouseInput.X < Parent->getAbsolutePosition().UpperLeftCorner.X +1 ||
event.MouseInput.Y < Parent->getAbsolutePosition().UpperLeftCorner.Y +1 ||
event.MouseInput.X > Parent->getAbsolutePosition().LowerRightCorner.X -1 ||
event.MouseInput.Y > Parent->getAbsolutePosition().LowerRightCorner.Y -1)
return true;
move(core::position2d<s32>(event.MouseInput.X - DragStart.X, event.MouseInput.Y - DragStart.Y));
DragStart.X = event.MouseInput.X;
DragStart.Y = event.MouseInput.Y;
return true;
}
break;
default:
break;
}
default:
break;
}
}
return IGUIElement::OnEvent(event);
}
//! draws the element and its children
void CGUIFileOpenDialog::draw()
{
if (!IsVisible)
return;
IGUISkin* skin = Environment->getSkin();
core::rect<s32> rect = AbsoluteRect;
rect = skin->draw3DWindowBackground(this, true, skin->getColor(EGDC_ACTIVE_BORDER),
rect, &AbsoluteClippingRect);
if (Text.size())
{
rect.UpperLeftCorner.X += 2;
rect.LowerRightCorner.X -= skin->getSize(EGDS_WINDOW_BUTTON_WIDTH) + 5;
IGUIFont* font = skin->getFont(EGDF_WINDOW);
if (font)
font->draw(Text.c_str(), rect,
skin->getColor(EGDC_ACTIVE_CAPTION),
false, true, &AbsoluteClippingRect);
}
IGUIElement::draw();
}
void CGUIFileOpenDialog::pathToStringW(irr::core::stringw& result, const irr::io::path& p)
{
core::multibyteToWString(result, p);
}
//! fills the listbox with files.
void CGUIFileOpenDialog::fillListBox()
{
IGUISkin *skin = Environment->getSkin();
if (!FileSystem || !FileBox || !skin)
return;
if (FileList)
FileList->drop();
FileBox->clear();
FileList = FileSystem->createFileList();
core::stringw s;
if (FileList)
{
for (u32 i=0; i < FileList->getFileCount(); ++i)
{
pathToStringW(s, FileList->getFileName(i));
FileBox->addItem(s.c_str(), skin->getIcon(FileList->isDirectory(i) ? EGDI_DIRECTORY : EGDI_FILE));
}
}
if (FileNameText)
{
setDirectoryName(FileSystem->getWorkingDirectory());
pathToStringW(s, FileDirectory);
FileNameText->setText(s.c_str());
}
}
//! sends the event that the file has been selected.
void CGUIFileOpenDialog::sendSelectedEvent( EGUI_EVENT_TYPE type)
{
SEvent event;
event.EventType = EET_GUI_EVENT;
event.GUIEvent.Caller = this;
event.GUIEvent.Element = 0;
event.GUIEvent.EventType = type;
Parent->OnEvent(event);
}
//! sends the event that the file choose process has been cancelled
void CGUIFileOpenDialog::sendCancelEvent()
{
SEvent event;
event.EventType = EET_GUI_EVENT;
event.GUIEvent.Caller = this;
event.GUIEvent.Element = 0;
event.GUIEvent.EventType = EGET_FILE_CHOOSE_DIALOG_CANCELLED;
Parent->OnEvent(event);
}
} // end namespace gui
} // end namespace irr

View File

@ -1,87 +1,87 @@
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#pragma once
#include "IGUIFileOpenDialog.h"
#include "IGUIButton.h"
#include "IGUIListBox.h"
#include "IGUIEditBox.h"
#include "IFileSystem.h"
namespace irr
{
namespace gui
{
class CGUIFileOpenDialog : public IGUIFileOpenDialog
{
public:
//! constructor
CGUIFileOpenDialog(const wchar_t* title, IGUIEnvironment* environment,
IGUIElement* parent, s32 id, bool restoreCWD=false,
io::path::char_type* startDir=0);
//! destructor
virtual ~CGUIFileOpenDialog();
//! returns the filename of the selected file. Returns NULL, if no file was selected.
const wchar_t* getFileName() const override;
//! Returns the filename of the selected file. Is empty if no file was selected.
const io::path& getFileNameP() const override;
//! Returns the directory of the selected file. Returns NULL, if no directory was selected.
const io::path& getDirectoryName() const override;
//! Returns the directory of the selected file converted to wide characters. Returns NULL if no directory was selected.
const wchar_t* getDirectoryNameW() const override;
//! called if an event happened.
bool OnEvent(const SEvent& event) override;
//! draws the element and its children
void draw() override;
protected:
void setFileName(const irr::io::path& name);
void setDirectoryName(const irr::io::path& name);
//! Ensure filenames are converted correct depending on wide-char settings
void pathToStringW(irr::core::stringw& result, const irr::io::path& p);
//! fills the listbox with files.
void fillListBox();
//! sends the event that the file has been selected.
void sendSelectedEvent( EGUI_EVENT_TYPE type );
//! sends the event that the file choose process has been canceld
void sendCancelEvent();
core::position2d<s32> DragStart;
io::path FileName;
core::stringw FileNameW;
io::path FileDirectory;
io::path FileDirectoryFlat;
core::stringw FileDirectoryFlatW;
io::path RestoreDirectory;
io::path StartDirectory;
IGUIButton* CloseButton;
IGUIButton* OKButton;
IGUIButton* CancelButton;
IGUIListBox* FileBox;
IGUIEditBox* FileNameText;
IGUIElement* EventParent;
io::IFileSystem* FileSystem;
io::IFileList* FileList;
bool Dragging;
};
} // end namespace gui
} // end namespace irr
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#pragma once
#include "IGUIFileOpenDialog.h"
#include "IGUIButton.h"
#include "IGUIListBox.h"
#include "IGUIEditBox.h"
#include "IFileSystem.h"
namespace irr
{
namespace gui
{
class CGUIFileOpenDialog : public IGUIFileOpenDialog
{
public:
//! constructor
CGUIFileOpenDialog(const wchar_t* title, IGUIEnvironment* environment,
IGUIElement* parent, s32 id, bool restoreCWD=false,
io::path::char_type* startDir=0);
//! destructor
virtual ~CGUIFileOpenDialog();
//! returns the filename of the selected file. Returns NULL, if no file was selected.
const wchar_t* getFileName() const override;
//! Returns the filename of the selected file. Is empty if no file was selected.
const io::path& getFileNameP() const override;
//! Returns the directory of the selected file. Returns NULL, if no directory was selected.
const io::path& getDirectoryName() const override;
//! Returns the directory of the selected file converted to wide characters. Returns NULL if no directory was selected.
const wchar_t* getDirectoryNameW() const override;
//! called if an event happened.
bool OnEvent(const SEvent& event) override;
//! draws the element and its children
void draw() override;
protected:
void setFileName(const irr::io::path& name);
void setDirectoryName(const irr::io::path& name);
//! Ensure filenames are converted correct depending on wide-char settings
void pathToStringW(irr::core::stringw& result, const irr::io::path& p);
//! fills the listbox with files.
void fillListBox();
//! sends the event that the file has been selected.
void sendSelectedEvent( EGUI_EVENT_TYPE type );
//! sends the event that the file choose process has been canceld
void sendCancelEvent();
core::position2d<s32> DragStart;
io::path FileName;
core::stringw FileNameW;
io::path FileDirectory;
io::path FileDirectoryFlat;
core::stringw FileDirectoryFlatW;
io::path RestoreDirectory;
io::path StartDirectory;
IGUIButton* CloseButton;
IGUIButton* OKButton;
IGUIButton* CancelButton;
IGUIListBox* FileBox;
IGUIEditBox* FileNameText;
IGUIElement* EventParent;
io::IFileSystem* FileSystem;
io::IFileList* FileList;
bool Dragging;
};
} // end namespace gui
} // end namespace irr

File diff suppressed because it is too large Load Diff

View File

@ -1,108 +1,108 @@
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#pragma once
#include "IGUIFontBitmap.h"
#include "irrString.h"
#include "IReadFile.h"
#include "irrArray.h"
#include <map>
namespace irr
{
namespace video
{
class IVideoDriver;
class IImage;
}
namespace gui
{
class IGUIEnvironment;
class CGUIFont : public IGUIFontBitmap
{
public:
//! constructor
CGUIFont(IGUIEnvironment* env, const io::path& filename);
//! destructor
virtual ~CGUIFont();
//! loads a font from a texture file
bool load(const io::path& filename);
//! loads a font from a texture file
bool load(io::IReadFile* file);
//! draws an text and clips it to the specified rectangle if wanted
virtual void draw(const core::stringw& text, const core::rect<s32>& position,
video::SColor color, bool hcenter=false,
bool vcenter=false, const core::rect<s32>* clip=0) override;
//! returns the dimension of a text
core::dimension2d<u32> getDimension(const wchar_t* text) const override;
//! Calculates the index of the character in the text which is on a specific position.
s32 getCharacterFromPos(const wchar_t* text, s32 pixel_x) const override;
//! Returns the type of this font
EGUI_FONT_TYPE getType() const override { return EGFT_BITMAP; }
//! set an Pixel Offset on Drawing ( scale position on width )
void setKerningWidth (s32 kerning) override;
void setKerningHeight (s32 kerning) override;
//! set an Pixel Offset on Drawing ( scale position on width )
s32 getKerningWidth(const wchar_t* thisLetter=0, const wchar_t* previousLetter=0) const override;
s32 getKerningHeight() const override;
//! gets the sprite bank
IGUISpriteBank* getSpriteBank() const override;
//! returns the sprite number from a given character
u32 getSpriteNoFromChar(const wchar_t *c) const override;
void setInvisibleCharacters( const wchar_t *s ) override;
private:
struct SFontArea
{
SFontArea() : underhang(0), overhang(0), width(0), spriteno(0) {}
s32 underhang;
s32 overhang;
s32 width;
u32 spriteno;
};
//! load & prepare font from ITexture
bool loadTexture(video::IImage * image, const io::path& name);
void readPositions(video::IImage* texture, s32& lowerRightPositions);
s32 getAreaFromCharacter (const wchar_t c) const;
void setMaxHeight();
void pushTextureCreationFlags(bool(&flags)[3]);
void popTextureCreationFlags(const bool(&flags)[3]);
core::array<SFontArea> Areas;
std::map<wchar_t, s32> CharacterMap;
video::IVideoDriver* Driver;
IGUISpriteBank* SpriteBank;
IGUIEnvironment* Environment;
u32 WrongCharacter;
s32 MaxHeight;
s32 GlobalKerningWidth, GlobalKerningHeight;
core::stringw Invisible;
};
} // end namespace gui
} // end namespace irr
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#pragma once
#include "IGUIFontBitmap.h"
#include "irrString.h"
#include "IReadFile.h"
#include "irrArray.h"
#include <map>
namespace irr
{
namespace video
{
class IVideoDriver;
class IImage;
}
namespace gui
{
class IGUIEnvironment;
class CGUIFont : public IGUIFontBitmap
{
public:
//! constructor
CGUIFont(IGUIEnvironment* env, const io::path& filename);
//! destructor
virtual ~CGUIFont();
//! loads a font from a texture file
bool load(const io::path& filename);
//! loads a font from a texture file
bool load(io::IReadFile* file);
//! draws an text and clips it to the specified rectangle if wanted
virtual void draw(const core::stringw& text, const core::rect<s32>& position,
video::SColor color, bool hcenter=false,
bool vcenter=false, const core::rect<s32>* clip=0) override;
//! returns the dimension of a text
core::dimension2d<u32> getDimension(const wchar_t* text) const override;
//! Calculates the index of the character in the text which is on a specific position.
s32 getCharacterFromPos(const wchar_t* text, s32 pixel_x) const override;
//! Returns the type of this font
EGUI_FONT_TYPE getType() const override { return EGFT_BITMAP; }
//! set an Pixel Offset on Drawing ( scale position on width )
void setKerningWidth (s32 kerning) override;
void setKerningHeight (s32 kerning) override;
//! set an Pixel Offset on Drawing ( scale position on width )
s32 getKerningWidth(const wchar_t* thisLetter=0, const wchar_t* previousLetter=0) const override;
s32 getKerningHeight() const override;
//! gets the sprite bank
IGUISpriteBank* getSpriteBank() const override;
//! returns the sprite number from a given character
u32 getSpriteNoFromChar(const wchar_t *c) const override;
void setInvisibleCharacters( const wchar_t *s ) override;
private:
struct SFontArea
{
SFontArea() : underhang(0), overhang(0), width(0), spriteno(0) {}
s32 underhang;
s32 overhang;
s32 width;
u32 spriteno;
};
//! load & prepare font from ITexture
bool loadTexture(video::IImage * image, const io::path& name);
void readPositions(video::IImage* texture, s32& lowerRightPositions);
s32 getAreaFromCharacter (const wchar_t c) const;
void setMaxHeight();
void pushTextureCreationFlags(bool(&flags)[3]);
void popTextureCreationFlags(const bool(&flags)[3]);
core::array<SFontArea> Areas;
std::map<wchar_t, s32> CharacterMap;
video::IVideoDriver* Driver;
IGUISpriteBank* SpriteBank;
IGUIEnvironment* Environment;
u32 WrongCharacter;
s32 MaxHeight;
s32 GlobalKerningWidth, GlobalKerningHeight;
core::stringw Invisible;
};
} // end namespace gui
} // end namespace irr

View File

@ -1,178 +1,178 @@
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#include "CGUIImage.h"
#include "IGUISkin.h"
#include "IGUIEnvironment.h"
#include "IVideoDriver.h"
namespace irr
{
namespace gui
{
//! constructor
CGUIImage::CGUIImage(IGUIEnvironment* environment, IGUIElement* parent, s32 id, core::rect<s32> rectangle)
: IGUIImage(environment, parent, id, rectangle), Texture(0), Color(255,255,255,255),
UseAlphaChannel(false), ScaleImage(false), DrawBounds(0.f, 0.f, 1.f, 1.f), DrawBackground(true)
{
#ifdef _DEBUG
setDebugName("CGUIImage");
#endif
}
//! destructor
CGUIImage::~CGUIImage()
{
if (Texture)
Texture->drop();
}
//! sets an image
void CGUIImage::setImage(video::ITexture* image)
{
if (image == Texture)
return;
if (Texture)
Texture->drop();
Texture = image;
if (Texture)
Texture->grab();
}
//! Gets the image texture
video::ITexture* CGUIImage::getImage() const
{
return Texture;
}
//! sets the color of the image
void CGUIImage::setColor(video::SColor color)
{
Color = color;
}
//! Gets the color of the image
video::SColor CGUIImage::getColor() const
{
return Color;
}
//! draws the element and its children
void CGUIImage::draw()
{
if (!IsVisible)
return;
IGUISkin* skin = Environment->getSkin();
video::IVideoDriver* driver = Environment->getVideoDriver();
if (Texture)
{
core::rect<s32> sourceRect(SourceRect);
if (sourceRect.getWidth() == 0 || sourceRect.getHeight() == 0)
{
sourceRect = core::rect<s32>(core::dimension2di(Texture->getOriginalSize()));
}
if (ScaleImage)
{
const video::SColor Colors[] = {Color,Color,Color,Color};
core::rect<s32> clippingRect(AbsoluteClippingRect);
checkBounds(clippingRect);
driver->draw2DImage(Texture, AbsoluteRect, sourceRect,
&clippingRect, Colors, UseAlphaChannel);
}
else
{
core::rect<s32> clippingRect(AbsoluteRect.UpperLeftCorner, sourceRect.getSize());
checkBounds(clippingRect);
clippingRect.clipAgainst(AbsoluteClippingRect);
driver->draw2DImage(Texture, AbsoluteRect.UpperLeftCorner, sourceRect,
&clippingRect, Color, UseAlphaChannel);
}
}
else if ( DrawBackground )
{
core::rect<s32> clippingRect(AbsoluteClippingRect);
checkBounds(clippingRect);
skin->draw2DRectangle(this, skin->getColor(EGDC_3D_DARK_SHADOW), AbsoluteRect, &clippingRect);
}
IGUIElement::draw();
}
//! sets if the image should use its alpha channel to draw itself
void CGUIImage::setUseAlphaChannel(bool use)
{
UseAlphaChannel = use;
}
//! sets if the image should use its alpha channel to draw itself
void CGUIImage::setScaleImage(bool scale)
{
ScaleImage = scale;
}
//! Returns true if the image is scaled to fit, false if not
bool CGUIImage::isImageScaled() const
{
return ScaleImage;
}
//! Returns true if the image is using the alpha channel, false if not
bool CGUIImage::isAlphaChannelUsed() const
{
return UseAlphaChannel;
}
//! Sets the source rectangle of the image. By default the full image is used.
void CGUIImage::setSourceRect(const core::rect<s32>& sourceRect)
{
SourceRect = sourceRect;
}
//! Returns the customized source rectangle of the image to be used.
core::rect<s32> CGUIImage::getSourceRect() const
{
return SourceRect;
}
//! Restrict target drawing-area.
void CGUIImage::setDrawBounds(const core::rect<f32>& drawBoundUVs)
{
DrawBounds = drawBoundUVs;
DrawBounds.UpperLeftCorner.X = core::clamp(DrawBounds.UpperLeftCorner.X, 0.f, 1.f);
DrawBounds.UpperLeftCorner.Y = core::clamp(DrawBounds.UpperLeftCorner.Y, 0.f, 1.f);
DrawBounds.LowerRightCorner.X = core::clamp(DrawBounds.LowerRightCorner.X, 0.f, 1.f);
DrawBounds.LowerRightCorner.X = core::clamp(DrawBounds.LowerRightCorner.X, 0.f, 1.f);
if ( DrawBounds.UpperLeftCorner.X > DrawBounds.LowerRightCorner.X )
DrawBounds.UpperLeftCorner.X = DrawBounds.LowerRightCorner.X;
if ( DrawBounds.UpperLeftCorner.Y > DrawBounds.LowerRightCorner.Y )
DrawBounds.UpperLeftCorner.Y = DrawBounds.LowerRightCorner.Y;
}
//! Get target drawing-area restrictions.
core::rect<f32> CGUIImage::getDrawBounds() const
{
return DrawBounds;
}
} // end namespace gui
} // end namespace irr
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#include "CGUIImage.h"
#include "IGUISkin.h"
#include "IGUIEnvironment.h"
#include "IVideoDriver.h"
namespace irr
{
namespace gui
{
//! constructor
CGUIImage::CGUIImage(IGUIEnvironment* environment, IGUIElement* parent, s32 id, core::rect<s32> rectangle)
: IGUIImage(environment, parent, id, rectangle), Texture(0), Color(255,255,255,255),
UseAlphaChannel(false), ScaleImage(false), DrawBounds(0.f, 0.f, 1.f, 1.f), DrawBackground(true)
{
#ifdef _DEBUG
setDebugName("CGUIImage");
#endif
}
//! destructor
CGUIImage::~CGUIImage()
{
if (Texture)
Texture->drop();
}
//! sets an image
void CGUIImage::setImage(video::ITexture* image)
{
if (image == Texture)
return;
if (Texture)
Texture->drop();
Texture = image;
if (Texture)
Texture->grab();
}
//! Gets the image texture
video::ITexture* CGUIImage::getImage() const
{
return Texture;
}
//! sets the color of the image
void CGUIImage::setColor(video::SColor color)
{
Color = color;
}
//! Gets the color of the image
video::SColor CGUIImage::getColor() const
{
return Color;
}
//! draws the element and its children
void CGUIImage::draw()
{
if (!IsVisible)
return;
IGUISkin* skin = Environment->getSkin();
video::IVideoDriver* driver = Environment->getVideoDriver();
if (Texture)
{
core::rect<s32> sourceRect(SourceRect);
if (sourceRect.getWidth() == 0 || sourceRect.getHeight() == 0)
{
sourceRect = core::rect<s32>(core::dimension2di(Texture->getOriginalSize()));
}
if (ScaleImage)
{
const video::SColor Colors[] = {Color,Color,Color,Color};
core::rect<s32> clippingRect(AbsoluteClippingRect);
checkBounds(clippingRect);
driver->draw2DImage(Texture, AbsoluteRect, sourceRect,
&clippingRect, Colors, UseAlphaChannel);
}
else
{
core::rect<s32> clippingRect(AbsoluteRect.UpperLeftCorner, sourceRect.getSize());
checkBounds(clippingRect);
clippingRect.clipAgainst(AbsoluteClippingRect);
driver->draw2DImage(Texture, AbsoluteRect.UpperLeftCorner, sourceRect,
&clippingRect, Color, UseAlphaChannel);
}
}
else if ( DrawBackground )
{
core::rect<s32> clippingRect(AbsoluteClippingRect);
checkBounds(clippingRect);
skin->draw2DRectangle(this, skin->getColor(EGDC_3D_DARK_SHADOW), AbsoluteRect, &clippingRect);
}
IGUIElement::draw();
}
//! sets if the image should use its alpha channel to draw itself
void CGUIImage::setUseAlphaChannel(bool use)
{
UseAlphaChannel = use;
}
//! sets if the image should use its alpha channel to draw itself
void CGUIImage::setScaleImage(bool scale)
{
ScaleImage = scale;
}
//! Returns true if the image is scaled to fit, false if not
bool CGUIImage::isImageScaled() const
{
return ScaleImage;
}
//! Returns true if the image is using the alpha channel, false if not
bool CGUIImage::isAlphaChannelUsed() const
{
return UseAlphaChannel;
}
//! Sets the source rectangle of the image. By default the full image is used.
void CGUIImage::setSourceRect(const core::rect<s32>& sourceRect)
{
SourceRect = sourceRect;
}
//! Returns the customized source rectangle of the image to be used.
core::rect<s32> CGUIImage::getSourceRect() const
{
return SourceRect;
}
//! Restrict target drawing-area.
void CGUIImage::setDrawBounds(const core::rect<f32>& drawBoundUVs)
{
DrawBounds = drawBoundUVs;
DrawBounds.UpperLeftCorner.X = core::clamp(DrawBounds.UpperLeftCorner.X, 0.f, 1.f);
DrawBounds.UpperLeftCorner.Y = core::clamp(DrawBounds.UpperLeftCorner.Y, 0.f, 1.f);
DrawBounds.LowerRightCorner.X = core::clamp(DrawBounds.LowerRightCorner.X, 0.f, 1.f);
DrawBounds.LowerRightCorner.X = core::clamp(DrawBounds.LowerRightCorner.X, 0.f, 1.f);
if ( DrawBounds.UpperLeftCorner.X > DrawBounds.LowerRightCorner.X )
DrawBounds.UpperLeftCorner.X = DrawBounds.LowerRightCorner.X;
if ( DrawBounds.UpperLeftCorner.Y > DrawBounds.LowerRightCorner.Y )
DrawBounds.UpperLeftCorner.Y = DrawBounds.LowerRightCorner.Y;
}
//! Get target drawing-area restrictions.
core::rect<f32> CGUIImage::getDrawBounds() const
{
return DrawBounds;
}
} // end namespace gui
} // end namespace irr

View File

@ -1,99 +1,99 @@
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#pragma once
#include "IGUIImage.h"
namespace irr
{
namespace gui
{
class CGUIImage : public IGUIImage
{
public:
//! constructor
CGUIImage(IGUIEnvironment* environment, IGUIElement* parent, s32 id, core::rect<s32> rectangle);
//! destructor
virtual ~CGUIImage();
//! sets an image
void setImage(video::ITexture* image) override;
//! Gets the image texture
video::ITexture* getImage() const override;
//! sets the color of the image
void setColor(video::SColor color) override;
//! sets if the image should scale to fit the element
void setScaleImage(bool scale) override;
//! draws the element and its children
void draw() override;
//! sets if the image should use its alpha channel to draw itself
void setUseAlphaChannel(bool use) override;
//! Gets the color of the image
video::SColor getColor() const override;
//! Returns true if the image is scaled to fit, false if not
bool isImageScaled() const override;
//! Returns true if the image is using the alpha channel, false if not
bool isAlphaChannelUsed() const override;
//! Sets the source rectangle of the image. By default the full image is used.
void setSourceRect(const core::rect<s32>& sourceRect) override;
//! Returns the customized source rectangle of the image to be used.
core::rect<s32> getSourceRect() const override;
//! Restrict drawing-area.
void setDrawBounds(const core::rect<f32>& drawBoundUVs) override;
//! Get drawing-area restrictions.
core::rect<f32> getDrawBounds() const override;
//! Sets whether to draw a background color (EGDC_3D_DARK_SHADOW) when no texture is set
void setDrawBackground(bool draw) override
{
DrawBackground = draw;
}
//! Checks if a background is drawn when no texture is set
bool isDrawBackgroundEnabled() const override
{
return DrawBackground;
}
protected:
void checkBounds(core::rect<s32>& rect)
{
f32 clipWidth = (f32)rect.getWidth();
f32 clipHeight = (f32)rect.getHeight();
rect.UpperLeftCorner.X += core::round32(DrawBounds.UpperLeftCorner.X*clipWidth);
rect.UpperLeftCorner.Y += core::round32(DrawBounds.UpperLeftCorner.Y*clipHeight);
rect.LowerRightCorner.X -= core::round32((1.f-DrawBounds.LowerRightCorner.X)*clipWidth);
rect.LowerRightCorner.Y -= core::round32((1.f-DrawBounds.LowerRightCorner.Y)*clipHeight);
}
private:
video::ITexture* Texture;
video::SColor Color;
bool UseAlphaChannel;
bool ScaleImage;
core::rect<s32> SourceRect;
core::rect<f32> DrawBounds;
bool DrawBackground;
};
} // end namespace gui
} // end namespace irr
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#pragma once
#include "IGUIImage.h"
namespace irr
{
namespace gui
{
class CGUIImage : public IGUIImage
{
public:
//! constructor
CGUIImage(IGUIEnvironment* environment, IGUIElement* parent, s32 id, core::rect<s32> rectangle);
//! destructor
virtual ~CGUIImage();
//! sets an image
void setImage(video::ITexture* image) override;
//! Gets the image texture
video::ITexture* getImage() const override;
//! sets the color of the image
void setColor(video::SColor color) override;
//! sets if the image should scale to fit the element
void setScaleImage(bool scale) override;
//! draws the element and its children
void draw() override;
//! sets if the image should use its alpha channel to draw itself
void setUseAlphaChannel(bool use) override;
//! Gets the color of the image
video::SColor getColor() const override;
//! Returns true if the image is scaled to fit, false if not
bool isImageScaled() const override;
//! Returns true if the image is using the alpha channel, false if not
bool isAlphaChannelUsed() const override;
//! Sets the source rectangle of the image. By default the full image is used.
void setSourceRect(const core::rect<s32>& sourceRect) override;
//! Returns the customized source rectangle of the image to be used.
core::rect<s32> getSourceRect() const override;
//! Restrict drawing-area.
void setDrawBounds(const core::rect<f32>& drawBoundUVs) override;
//! Get drawing-area restrictions.
core::rect<f32> getDrawBounds() const override;
//! Sets whether to draw a background color (EGDC_3D_DARK_SHADOW) when no texture is set
void setDrawBackground(bool draw) override
{
DrawBackground = draw;
}
//! Checks if a background is drawn when no texture is set
bool isDrawBackgroundEnabled() const override
{
return DrawBackground;
}
protected:
void checkBounds(core::rect<s32>& rect)
{
f32 clipWidth = (f32)rect.getWidth();
f32 clipHeight = (f32)rect.getHeight();
rect.UpperLeftCorner.X += core::round32(DrawBounds.UpperLeftCorner.X*clipWidth);
rect.UpperLeftCorner.Y += core::round32(DrawBounds.UpperLeftCorner.Y*clipHeight);
rect.LowerRightCorner.X -= core::round32((1.f-DrawBounds.LowerRightCorner.X)*clipWidth);
rect.LowerRightCorner.Y -= core::round32((1.f-DrawBounds.LowerRightCorner.Y)*clipHeight);
}
private:
video::ITexture* Texture;
video::SColor Color;
bool UseAlphaChannel;
bool ScaleImage;
core::rect<s32> SourceRect;
core::rect<f32> DrawBounds;
bool DrawBackground;
};
} // end namespace gui
} // end namespace irr

View File

@ -1,93 +1,93 @@
// This file is part of the "Irrlicht Engine".
// written by Reinhard Ostermeier, reinhard@nospam.r-ostermeier.de
// modified by Thomas Alten
#include "CGUIImageList.h"
namespace irr
{
namespace gui
{
//! constructor
CGUIImageList::CGUIImageList( video::IVideoDriver* driver )
: Driver( driver ),
Texture( 0 ),
ImageCount( 0 ),
ImageSize( 0, 0 ),
ImagesPerRow( 0 ),
UseAlphaChannel( false )
{
#ifdef _DEBUG
setDebugName( "CGUIImageList" );
#endif
if( Driver )
{
Driver->grab();
}
}
//! destructor
CGUIImageList::~CGUIImageList()
{
if( Driver )
{
Driver->drop();
}
if( Texture )
{
Texture->drop();
}
}
//! Creates the image list from texture.
bool CGUIImageList::createImageList(video::ITexture* texture,
core::dimension2d<s32> imageSize,
bool useAlphaChannel)
{
if( !texture )
{
return false;
}
Texture = texture;
Texture->grab();
ImageSize = imageSize;
ImagesPerRow = Texture->getSize().Width / ImageSize.Width;
ImageCount = ImagesPerRow * Texture->getSize().Height / ImageSize.Height;
UseAlphaChannel = useAlphaChannel;
return true;
}
//! Draws an image and clips it to the specified rectangle if wanted
void CGUIImageList::draw( s32 index, const core::position2d<s32>& destPos,
const core::rect<s32>* clip /*= 0*/ )
{
core::rect<s32> sourceRect;
if( !Driver || index < 0 || index >= ImageCount )
{
return;
}
sourceRect.UpperLeftCorner.X = ( index % ImagesPerRow ) * ImageSize.Width;
sourceRect.UpperLeftCorner.Y = ( index / ImagesPerRow ) * ImageSize.Height;
sourceRect.LowerRightCorner.X = sourceRect.UpperLeftCorner.X + ImageSize.Width;
sourceRect.LowerRightCorner.Y = sourceRect.UpperLeftCorner.Y + ImageSize.Height;
Driver->draw2DImage( Texture, destPos, sourceRect, clip,
video::SColor( 255, 255, 255, 255 ), UseAlphaChannel );
}
} // end namespace gui
} // end namespace irr
// This file is part of the "Irrlicht Engine".
// written by Reinhard Ostermeier, reinhard@nospam.r-ostermeier.de
// modified by Thomas Alten
#include "CGUIImageList.h"
namespace irr
{
namespace gui
{
//! constructor
CGUIImageList::CGUIImageList( video::IVideoDriver* driver )
: Driver( driver ),
Texture( 0 ),
ImageCount( 0 ),
ImageSize( 0, 0 ),
ImagesPerRow( 0 ),
UseAlphaChannel( false )
{
#ifdef _DEBUG
setDebugName( "CGUIImageList" );
#endif
if( Driver )
{
Driver->grab();
}
}
//! destructor
CGUIImageList::~CGUIImageList()
{
if( Driver )
{
Driver->drop();
}
if( Texture )
{
Texture->drop();
}
}
//! Creates the image list from texture.
bool CGUIImageList::createImageList(video::ITexture* texture,
core::dimension2d<s32> imageSize,
bool useAlphaChannel)
{
if( !texture )
{
return false;
}
Texture = texture;
Texture->grab();
ImageSize = imageSize;
ImagesPerRow = Texture->getSize().Width / ImageSize.Width;
ImageCount = ImagesPerRow * Texture->getSize().Height / ImageSize.Height;
UseAlphaChannel = useAlphaChannel;
return true;
}
//! Draws an image and clips it to the specified rectangle if wanted
void CGUIImageList::draw( s32 index, const core::position2d<s32>& destPos,
const core::rect<s32>* clip /*= 0*/ )
{
core::rect<s32> sourceRect;
if( !Driver || index < 0 || index >= ImageCount )
{
return;
}
sourceRect.UpperLeftCorner.X = ( index % ImagesPerRow ) * ImageSize.Width;
sourceRect.UpperLeftCorner.Y = ( index / ImagesPerRow ) * ImageSize.Height;
sourceRect.LowerRightCorner.X = sourceRect.UpperLeftCorner.X + ImageSize.Width;
sourceRect.LowerRightCorner.Y = sourceRect.UpperLeftCorner.Y + ImageSize.Height;
Driver->draw2DImage( Texture, destPos, sourceRect, clip,
video::SColor( 255, 255, 255, 255 ), UseAlphaChannel );
}
} // end namespace gui
} // end namespace irr

View File

@ -1,63 +1,63 @@
// This file is part of the "Irrlicht Engine".
// written by Reinhard Ostermeier, reinhard@nospam.r-ostermeier.de
#pragma once
#include "IGUIImageList.h"
#include "IVideoDriver.h"
namespace irr
{
namespace gui
{
class CGUIImageList : public IGUIImageList
{
public:
//! constructor
CGUIImageList( video::IVideoDriver* Driver );
//! destructor
virtual ~CGUIImageList();
//! Creates the image list from texture.
//! \param texture: The texture to use
//! \param imageSize: Size of a single image
//! \param useAlphaChannel: true if the alpha channel from the texture should be used
//! \return
//! true if the image list was created
bool createImageList(video::ITexture* texture,
core::dimension2d<s32> imageSize,
bool useAlphaChannel);
//! Draws an image and clips it to the specified rectangle if wanted
//! \param index: Index of the image
//! \param destPos: Position of the image to draw
//! \param clip: Optional pointer to a rectangle against which the text will be clipped.
//! If the pointer is null, no clipping will be done.
virtual void draw( s32 index, const core::position2d<s32>& destPos,
const core::rect<s32>* clip = 0 ) override;
//! Returns the count of Images in the list.
//! \return Returns the count of Images in the list.
s32 getImageCount() const override
{ return ImageCount; }
//! Returns the size of the images in the list.
//! \return Returns the size of the images in the list.
core::dimension2d<s32> getImageSize() const override
{ return ImageSize; }
private:
video::IVideoDriver* Driver;
video::ITexture* Texture;
s32 ImageCount;
core::dimension2d<s32> ImageSize;
s32 ImagesPerRow;
bool UseAlphaChannel;
};
} // end namespace gui
} // end namespace irr
// This file is part of the "Irrlicht Engine".
// written by Reinhard Ostermeier, reinhard@nospam.r-ostermeier.de
#pragma once
#include "IGUIImageList.h"
#include "IVideoDriver.h"
namespace irr
{
namespace gui
{
class CGUIImageList : public IGUIImageList
{
public:
//! constructor
CGUIImageList( video::IVideoDriver* Driver );
//! destructor
virtual ~CGUIImageList();
//! Creates the image list from texture.
//! \param texture: The texture to use
//! \param imageSize: Size of a single image
//! \param useAlphaChannel: true if the alpha channel from the texture should be used
//! \return
//! true if the image list was created
bool createImageList(video::ITexture* texture,
core::dimension2d<s32> imageSize,
bool useAlphaChannel);
//! Draws an image and clips it to the specified rectangle if wanted
//! \param index: Index of the image
//! \param destPos: Position of the image to draw
//! \param clip: Optional pointer to a rectangle against which the text will be clipped.
//! If the pointer is null, no clipping will be done.
virtual void draw( s32 index, const core::position2d<s32>& destPos,
const core::rect<s32>* clip = 0 ) override;
//! Returns the count of Images in the list.
//! \return Returns the count of Images in the list.
s32 getImageCount() const override
{ return ImageCount; }
//! Returns the size of the images in the list.
//! \return Returns the size of the images in the list.
core::dimension2d<s32> getImageSize() const override
{ return ImageSize; }
private:
video::IVideoDriver* Driver;
video::ITexture* Texture;
s32 ImageCount;
core::dimension2d<s32> ImageSize;
s32 ImagesPerRow;
bool UseAlphaChannel;
};
} // end namespace gui
} // end namespace irr

File diff suppressed because it is too large Load Diff

View File

@ -1,175 +1,175 @@
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#pragma once
#include "IGUIListBox.h"
#include "irrArray.h"
namespace irr
{
namespace gui
{
class IGUIFont;
class IGUIScrollBar;
class CGUIListBox : public IGUIListBox
{
public:
//! constructor
CGUIListBox(IGUIEnvironment* environment, IGUIElement* parent,
s32 id, core::rect<s32> rectangle, bool clip=true,
bool drawBack=false, bool moveOverSelect=false);
//! destructor
virtual ~CGUIListBox();
//! returns amount of list items
u32 getItemCount() const override;
//! returns string of a list item. the id may be a value from 0 to itemCount-1
const wchar_t* getListItem(u32 id) const override;
//! adds an list item, returns id of item
u32 addItem(const wchar_t* text) override;
//! clears the list
void clear() override;
//! returns id of selected item. returns -1 if no item is selected.
s32 getSelected() const override;
//! sets the selected item. Set this to -1 if no item should be selected
void setSelected(s32 id) override;
//! sets the selected item. Set this to -1 if no item should be selected
void setSelected(const wchar_t *item) override;
//! called if an event happened.
bool OnEvent(const SEvent& event) override;
//! draws the element and its children
void draw() override;
//! adds an list item with an icon
//! \param text Text of list entry
//! \param icon Sprite index of the Icon within the current sprite bank. Set it to -1 if you want no icon
//! \return
//! returns the id of the new created item
u32 addItem(const wchar_t* text, s32 icon) override;
//! Returns the icon of an item
s32 getIcon(u32 id) const override;
//! removes an item from the list
void removeItem(u32 id) override;
//! get the the id of the item at the given absolute coordinates
s32 getItemAt(s32 xpos, s32 ypos) const override;
//! Sets the sprite bank which should be used to draw list icons. This font is set to the sprite bank of
//! the built-in-font by default. A sprite can be displayed in front of every list item.
//! An icon is an index within the icon sprite bank. Several default icons are available in the
//! skin through getIcon
void setSpriteBank(IGUISpriteBank* bank) override;
//! set whether the listbox should scroll to newly selected items
void setAutoScrollEnabled(bool scroll) override;
//! returns true if automatic scrolling is enabled, false if not.
bool isAutoScrollEnabled() const override;
//! Update the position and size of the listbox, and update the scrollbar
void updateAbsolutePosition() override;
//! set all item colors at given index to color
void setItemOverrideColor(u32 index, video::SColor color) override;
//! set all item colors of specified type at given index to color
void setItemOverrideColor(u32 index, EGUI_LISTBOX_COLOR colorType, video::SColor color) override;
//! clear all item colors at index
void clearItemOverrideColor(u32 index) override;
//! clear item color at index for given colortype
void clearItemOverrideColor(u32 index, EGUI_LISTBOX_COLOR colorType) override;
//! has the item at index its color overwritten?
bool hasItemOverrideColor(u32 index, EGUI_LISTBOX_COLOR colorType) const override;
//! return the overwrite color at given item index.
video::SColor getItemOverrideColor(u32 index, EGUI_LISTBOX_COLOR colorType) const override;
//! return the default color which is used for the given colorType
video::SColor getItemDefaultColor(EGUI_LISTBOX_COLOR colorType) const override;
//! set the item at the given index
void setItem(u32 index, const wchar_t* text, s32 icon) override;
//! Insert the item at the given index
//! Return the index on success or -1 on failure.
s32 insertItem(u32 index, const wchar_t* text, s32 icon) override;
//! Swap the items at the given indices
void swapItems(u32 index1, u32 index2) override;
//! set global itemHeight
void setItemHeight( s32 height ) override;
//! Sets whether to draw the background
void setDrawBackground(bool draw) override;
//! Access the vertical scrollbar
IGUIScrollBar* getVerticalScrollBar() const override;
private:
struct ListItem
{
core::stringw Text;
s32 Icon = -1;
// A multicolor extension
struct ListItemOverrideColor
{
bool Use = false;
video::SColor Color;
};
ListItemOverrideColor OverrideColors[EGUI_LBC_COUNT]{};
};
void recalculateItemHeight();
void selectNew(s32 ypos, bool onlyHover=false);
void recalculateScrollPos();
void updateScrollBarSize(s32 size);
// extracted that function to avoid copy&paste code
void recalculateItemWidth(s32 icon);
// get labels used for serialization
bool getSerializationLabels(EGUI_LISTBOX_COLOR colorType, core::stringc & useColorLabel, core::stringc & colorLabel) const;
core::array< ListItem > Items;
s32 Selected;
s32 ItemHeight;
s32 ItemHeightOverride;
s32 TotalItemHeight;
s32 ItemsIconWidth;
gui::IGUIFont* Font;
gui::IGUISpriteBank* IconBank;
gui::IGUIScrollBar* ScrollBar;
u32 selectTime;
u32 LastKeyTime;
core::stringw KeyBuffer;
bool Selecting;
bool DrawBack;
bool MoveOverSelect;
bool AutoScroll;
bool HighlightWhenNotFocused;
};
} // end namespace gui
} // end namespace irr
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#pragma once
#include "IGUIListBox.h"
#include "irrArray.h"
namespace irr
{
namespace gui
{
class IGUIFont;
class IGUIScrollBar;
class CGUIListBox : public IGUIListBox
{
public:
//! constructor
CGUIListBox(IGUIEnvironment* environment, IGUIElement* parent,
s32 id, core::rect<s32> rectangle, bool clip=true,
bool drawBack=false, bool moveOverSelect=false);
//! destructor
virtual ~CGUIListBox();
//! returns amount of list items
u32 getItemCount() const override;
//! returns string of a list item. the id may be a value from 0 to itemCount-1
const wchar_t* getListItem(u32 id) const override;
//! adds an list item, returns id of item
u32 addItem(const wchar_t* text) override;
//! clears the list
void clear() override;
//! returns id of selected item. returns -1 if no item is selected.
s32 getSelected() const override;
//! sets the selected item. Set this to -1 if no item should be selected
void setSelected(s32 id) override;
//! sets the selected item. Set this to -1 if no item should be selected
void setSelected(const wchar_t *item) override;
//! called if an event happened.
bool OnEvent(const SEvent& event) override;
//! draws the element and its children
void draw() override;
//! adds an list item with an icon
//! \param text Text of list entry
//! \param icon Sprite index of the Icon within the current sprite bank. Set it to -1 if you want no icon
//! \return
//! returns the id of the new created item
u32 addItem(const wchar_t* text, s32 icon) override;
//! Returns the icon of an item
s32 getIcon(u32 id) const override;
//! removes an item from the list
void removeItem(u32 id) override;
//! get the the id of the item at the given absolute coordinates
s32 getItemAt(s32 xpos, s32 ypos) const override;
//! Sets the sprite bank which should be used to draw list icons. This font is set to the sprite bank of
//! the built-in-font by default. A sprite can be displayed in front of every list item.
//! An icon is an index within the icon sprite bank. Several default icons are available in the
//! skin through getIcon
void setSpriteBank(IGUISpriteBank* bank) override;
//! set whether the listbox should scroll to newly selected items
void setAutoScrollEnabled(bool scroll) override;
//! returns true if automatic scrolling is enabled, false if not.
bool isAutoScrollEnabled() const override;
//! Update the position and size of the listbox, and update the scrollbar
void updateAbsolutePosition() override;
//! set all item colors at given index to color
void setItemOverrideColor(u32 index, video::SColor color) override;
//! set all item colors of specified type at given index to color
void setItemOverrideColor(u32 index, EGUI_LISTBOX_COLOR colorType, video::SColor color) override;
//! clear all item colors at index
void clearItemOverrideColor(u32 index) override;
//! clear item color at index for given colortype
void clearItemOverrideColor(u32 index, EGUI_LISTBOX_COLOR colorType) override;
//! has the item at index its color overwritten?
bool hasItemOverrideColor(u32 index, EGUI_LISTBOX_COLOR colorType) const override;
//! return the overwrite color at given item index.
video::SColor getItemOverrideColor(u32 index, EGUI_LISTBOX_COLOR colorType) const override;
//! return the default color which is used for the given colorType
video::SColor getItemDefaultColor(EGUI_LISTBOX_COLOR colorType) const override;
//! set the item at the given index
void setItem(u32 index, const wchar_t* text, s32 icon) override;
//! Insert the item at the given index
//! Return the index on success or -1 on failure.
s32 insertItem(u32 index, const wchar_t* text, s32 icon) override;
//! Swap the items at the given indices
void swapItems(u32 index1, u32 index2) override;
//! set global itemHeight
void setItemHeight( s32 height ) override;
//! Sets whether to draw the background
void setDrawBackground(bool draw) override;
//! Access the vertical scrollbar
IGUIScrollBar* getVerticalScrollBar() const override;
private:
struct ListItem
{
core::stringw Text;
s32 Icon = -1;
// A multicolor extension
struct ListItemOverrideColor
{
bool Use = false;
video::SColor Color;
};
ListItemOverrideColor OverrideColors[EGUI_LBC_COUNT]{};
};
void recalculateItemHeight();
void selectNew(s32 ypos, bool onlyHover=false);
void recalculateScrollPos();
void updateScrollBarSize(s32 size);
// extracted that function to avoid copy&paste code
void recalculateItemWidth(s32 icon);
// get labels used for serialization
bool getSerializationLabels(EGUI_LISTBOX_COLOR colorType, core::stringc & useColorLabel, core::stringc & colorLabel) const;
core::array< ListItem > Items;
s32 Selected;
s32 ItemHeight;
s32 ItemHeightOverride;
s32 TotalItemHeight;
s32 ItemsIconWidth;
gui::IGUIFont* Font;
gui::IGUISpriteBank* IconBank;
gui::IGUIScrollBar* ScrollBar;
u32 selectTime;
u32 LastKeyTime;
core::stringw KeyBuffer;
bool Selecting;
bool DrawBack;
bool MoveOverSelect;
bool AutoScroll;
bool HighlightWhenNotFocused;
};
} // end namespace gui
} // end namespace irr

File diff suppressed because it is too large Load Diff

View File

@ -1,98 +1,98 @@
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#pragma once
#include "IGUIScrollBar.h"
#include "IGUIButton.h"
namespace irr
{
namespace gui
{
class CGUIScrollBar : public IGUIScrollBar
{
public:
//! constructor
CGUIScrollBar(bool horizontal, IGUIEnvironment* environment,
IGUIElement* parent, s32 id, core::rect<s32> rectangle,
bool noclip=false);
//! destructor
virtual ~CGUIScrollBar();
//! called if an event happened.
bool OnEvent(const SEvent& event) override;
//! draws the element and its children
void draw() override;
void OnPostRender(u32 timeMs) override;
//! gets the maximum value of the scrollbar.
s32 getMax() const override;
//! sets the maximum value of the scrollbar.
void setMax(s32 max) override;
//! gets the minimum value of the scrollbar.
s32 getMin() const override;
//! sets the minimum value of the scrollbar.
void setMin(s32 min) override;
//! gets the small step value
s32 getSmallStep() const override;
//! sets the small step value
void setSmallStep(s32 step) override;
//! gets the large step value
s32 getLargeStep() const override;
//! sets the large step value
void setLargeStep(s32 step) override;
//! gets the current position of the scrollbar
s32 getPos() const override;
//! sets the position of the scrollbar
void setPos(s32 pos) override;
//! updates the rectangle
void updateAbsolutePosition() override;
private:
void refreshControls();
s32 getPosFromMousePos(const core::position2di &p) const;
IGUIButton* UpButton;
IGUIButton* DownButton;
core::rect<s32> SliderRect;
bool Dragging;
bool Horizontal;
bool DraggedBySlider;
bool TrayClick;
s32 Pos;
s32 DrawPos;
s32 DrawHeight;
s32 Min;
s32 Max;
s32 SmallStep;
s32 LargeStep;
s32 DesiredPos;
u32 LastChange;
video::SColor CurrentIconColor;
f32 range () const { return (f32) ( Max - Min ); }
};
} // end namespace gui
} // end namespace irr
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#pragma once
#include "IGUIScrollBar.h"
#include "IGUIButton.h"
namespace irr
{
namespace gui
{
class CGUIScrollBar : public IGUIScrollBar
{
public:
//! constructor
CGUIScrollBar(bool horizontal, IGUIEnvironment* environment,
IGUIElement* parent, s32 id, core::rect<s32> rectangle,
bool noclip=false);
//! destructor
virtual ~CGUIScrollBar();
//! called if an event happened.
bool OnEvent(const SEvent& event) override;
//! draws the element and its children
void draw() override;
void OnPostRender(u32 timeMs) override;
//! gets the maximum value of the scrollbar.
s32 getMax() const override;
//! sets the maximum value of the scrollbar.
void setMax(s32 max) override;
//! gets the minimum value of the scrollbar.
s32 getMin() const override;
//! sets the minimum value of the scrollbar.
void setMin(s32 min) override;
//! gets the small step value
s32 getSmallStep() const override;
//! sets the small step value
void setSmallStep(s32 step) override;
//! gets the large step value
s32 getLargeStep() const override;
//! sets the large step value
void setLargeStep(s32 step) override;
//! gets the current position of the scrollbar
s32 getPos() const override;
//! sets the position of the scrollbar
void setPos(s32 pos) override;
//! updates the rectangle
void updateAbsolutePosition() override;
private:
void refreshControls();
s32 getPosFromMousePos(const core::position2di &p) const;
IGUIButton* UpButton;
IGUIButton* DownButton;
core::rect<s32> SliderRect;
bool Dragging;
bool Horizontal;
bool DraggedBySlider;
bool TrayClick;
s32 Pos;
s32 DrawPos;
s32 DrawHeight;
s32 Min;
s32 Max;
s32 SmallStep;
s32 LargeStep;
s32 DesiredPos;
u32 LastChange;
video::SColor CurrentIconColor;
f32 range () const { return (f32) ( Max - Min ); }
};
} // end namespace gui
} // end namespace irr

File diff suppressed because it is too large Load Diff

View File

@ -1,231 +1,231 @@
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#pragma once
#include "IGUISkin.h"
#include "irrString.h"
namespace irr
{
namespace video
{
class IVideoDriver;
}
namespace gui
{
class CGUISkin : public IGUISkin
{
public:
CGUISkin(EGUI_SKIN_TYPE type, video::IVideoDriver* driver);
//! destructor
virtual ~CGUISkin();
//! returns default color
video::SColor getColor(EGUI_DEFAULT_COLOR color) const override;
//! sets a default color
void setColor(EGUI_DEFAULT_COLOR which, video::SColor newColor) override;
//! returns size for the given size type
s32 getSize(EGUI_DEFAULT_SIZE size) const override;
//! sets a default size
void setSize(EGUI_DEFAULT_SIZE which, s32 size) override;
//! returns the default font
IGUIFont* getFont(EGUI_DEFAULT_FONT which=EGDF_DEFAULT) const override;
//! sets a default font
void setFont(IGUIFont* font, EGUI_DEFAULT_FONT which=EGDF_DEFAULT) override;
//! sets the sprite bank used for drawing icons
void setSpriteBank(IGUISpriteBank* bank) override;
//! gets the sprite bank used for drawing icons
IGUISpriteBank* getSpriteBank() const override;
//! Returns a default icon
/** Returns the sprite index within the sprite bank */
u32 getIcon(EGUI_DEFAULT_ICON icon) const override;
//! Sets a default icon
/** Sets the sprite index used for drawing icons like arrows,
close buttons and ticks in checkboxes
\param icon: Enum specifying which icon to change
\param index: The sprite index used to draw this icon */
void setIcon(EGUI_DEFAULT_ICON icon, u32 index) override;
//! Returns a default text.
/** For example for Message box button captions:
"OK", "Cancel", "Yes", "No" and so on. */
const wchar_t* getDefaultText(EGUI_DEFAULT_TEXT text) const override;
//! Sets a default text.
/** For example for Message box button captions:
"OK", "Cancel", "Yes", "No" and so on. */
void setDefaultText(EGUI_DEFAULT_TEXT which, const wchar_t* newText) override;
//! draws a standard 3d button pane
/** Used for drawing for example buttons in normal state.
It uses the colors EGDC_3D_DARK_SHADOW, EGDC_3D_HIGH_LIGHT, EGDC_3D_SHADOW and
EGDC_3D_FACE for this. See EGUI_DEFAULT_COLOR for details.
\param rect: Defining area where to draw.
\param clip: Clip area.
\param element: Pointer to the element which wishes to draw this. This parameter
is usually not used by ISkin, but can be used for example by more complex
implementations to find out how to draw the part exactly. */
virtual void draw3DButtonPaneStandard(IGUIElement* element,
const core::rect<s32>& rect,
const core::rect<s32>* clip=0) override;
//! draws a pressed 3d button pane
/** Used for drawing for example buttons in pressed state.
It uses the colors EGDC_3D_DARK_SHADOW, EGDC_3D_HIGH_LIGHT, EGDC_3D_SHADOW and
EGDC_3D_FACE for this. See EGUI_DEFAULT_COLOR for details.
\param rect: Defining area where to draw.
\param clip: Clip area.
\param element: Pointer to the element which wishes to draw this. This parameter
is usually not used by ISkin, but can be used for example by more complex
implementations to find out how to draw the part exactly. */
virtual void draw3DButtonPanePressed(IGUIElement* element,
const core::rect<s32>& rect,
const core::rect<s32>* clip=0) override;
//! draws a sunken 3d pane
/** Used for drawing the background of edit, combo or check boxes.
\param element: Pointer to the element which wishes to draw this. This parameter
is usually not used by ISkin, but can be used for example by more complex
implementations to find out how to draw the part exactly.
\param bgcolor: Background color.
\param flat: Specifies if the sunken pane should be flat or displayed as sunken
deep into the ground.
\param rect: Defining area where to draw.
\param clip: Clip area. */
virtual void draw3DSunkenPane(IGUIElement* element,
video::SColor bgcolor, bool flat,
bool fillBackGround,
const core::rect<s32>& rect,
const core::rect<s32>* clip=0) override;
//! draws a window background
/** Used for drawing the background of dialogs and windows.
\param element: Pointer to the element which wishes to draw this. This parameter
is usually not used by ISkin, but can be used for example by more complex
implementations to find out how to draw the part exactly.
\param titleBarColor: Title color.
\param drawTitleBar: True to enable title drawing.
\param rect: Defining area where to draw.
\param clip: Clip area.
\param checkClientArea: When set to non-null the function will not draw anything,
but will instead return the clientArea which can be used for drawing by the calling window.
That is the area without borders and without titlebar.
\return Returns rect where it would be good to draw title bar text. This will
work even when checkClientArea is set to a non-null value.*/
virtual core::rect<s32> draw3DWindowBackground(IGUIElement* element,
bool drawTitleBar, video::SColor titleBarColor,
const core::rect<s32>& rect,
const core::rect<s32>* clip,
core::rect<s32>* checkClientArea) override;
//! draws a standard 3d menu pane
/** Used for drawing for menus and context menus.
It uses the colors EGDC_3D_DARK_SHADOW, EGDC_3D_HIGH_LIGHT, EGDC_3D_SHADOW and
EGDC_3D_FACE for this. See EGUI_DEFAULT_COLOR for details.
\param element: Pointer to the element which wishes to draw this. This parameter
is usually not used by ISkin, but can be used for example by more complex
implementations to find out how to draw the part exactly.
\param rect: Defining area where to draw.
\param clip: Clip area. */
virtual void draw3DMenuPane(IGUIElement* element,
const core::rect<s32>& rect,
const core::rect<s32>* clip=0) override;
//! draws a standard 3d tool bar
/** Used for drawing for toolbars and menus.
\param element: Pointer to the element which wishes to draw this. This parameter
is usually not used by ISkin, but can be used for example by more complex
implementations to find out how to draw the part exactly.
\param rect: Defining area where to draw.
\param clip: Clip area. */
virtual void draw3DToolBar(IGUIElement* element,
const core::rect<s32>& rect,
const core::rect<s32>* clip=0) override;
//! draws a tab button
/** Used for drawing for tab buttons on top of tabs.
\param element: Pointer to the element which wishes to draw this. This parameter
is usually not used by ISkin, but can be used for example by more complex
implementations to find out how to draw the part exactly.
\param active: Specifies if the tab is currently active.
\param rect: Defining area where to draw.
\param clip: Clip area. */
virtual void draw3DTabButton(IGUIElement* element, bool active,
const core::rect<s32>& rect, const core::rect<s32>* clip=0,
EGUI_ALIGNMENT alignment=EGUIA_UPPERLEFT) override;
//! draws a tab control body
/** \param element: Pointer to the element which wishes to draw this. This parameter
is usually not used by ISkin, but can be used for example by more complex
implementations to find out how to draw the part exactly.
\param border: Specifies if the border should be drawn.
\param background: Specifies if the background should be drawn.
\param rect: Defining area where to draw.
\param clip: Clip area. */
virtual void draw3DTabBody(IGUIElement* element, bool border, bool background,
const core::rect<s32>& rect, const core::rect<s32>* clip=0, s32 tabHeight=-1,
EGUI_ALIGNMENT alignment=EGUIA_UPPERLEFT) override;
//! draws an icon, usually from the skin's sprite bank
/** \param element: Pointer to the element which wishes to draw this icon.
This parameter is usually not used by IGUISkin, but can be used for example
by more complex implementations to find out how to draw the part exactly.
\param icon: Specifies the icon to be drawn.
\param position: The position to draw the icon
\param starttime: The time at the start of the animation
\param currenttime: The present time, used to calculate the frame number
\param loop: Whether the animation should loop or not
\param clip: Clip area. */
virtual void drawIcon(IGUIElement* element, EGUI_DEFAULT_ICON icon,
const core::position2di position,
u32 starttime=0, u32 currenttime=0,
bool loop=false, const core::rect<s32>* clip=0) override;
//! draws a 2d rectangle.
/** \param element: Pointer to the element which wishes to draw this icon.
This parameter is usually not used by IGUISkin, but can be used for example
by more complex implementations to find out how to draw the part exactly.
\param color: Color of the rectangle to draw. The alpha component specifies how
transparent the rectangle will be.
\param pos: Position of the rectangle.
\param clip: Pointer to rectangle against which the rectangle will be clipped.
If the pointer is null, no clipping will be performed. */
virtual void draw2DRectangle(IGUIElement* element, const video::SColor &color,
const core::rect<s32>& pos, const core::rect<s32>* clip = 0) override;
//! get the type of this skin
EGUI_SKIN_TYPE getType() const override;
private:
video::SColor Colors[EGDC_COUNT];
s32 Sizes[EGDS_COUNT];
u32 Icons[EGDI_COUNT];
IGUIFont* Fonts[EGDF_COUNT];
IGUISpriteBank* SpriteBank;
core::stringw Texts[EGDT_COUNT];
video::IVideoDriver* Driver;
bool UseGradient;
EGUI_SKIN_TYPE Type;
};
} // end namespace gui
} // end namespace irr
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#pragma once
#include "IGUISkin.h"
#include "irrString.h"
namespace irr
{
namespace video
{
class IVideoDriver;
}
namespace gui
{
class CGUISkin : public IGUISkin
{
public:
CGUISkin(EGUI_SKIN_TYPE type, video::IVideoDriver* driver);
//! destructor
virtual ~CGUISkin();
//! returns default color
video::SColor getColor(EGUI_DEFAULT_COLOR color) const override;
//! sets a default color
void setColor(EGUI_DEFAULT_COLOR which, video::SColor newColor) override;
//! returns size for the given size type
s32 getSize(EGUI_DEFAULT_SIZE size) const override;
//! sets a default size
void setSize(EGUI_DEFAULT_SIZE which, s32 size) override;
//! returns the default font
IGUIFont* getFont(EGUI_DEFAULT_FONT which=EGDF_DEFAULT) const override;
//! sets a default font
void setFont(IGUIFont* font, EGUI_DEFAULT_FONT which=EGDF_DEFAULT) override;
//! sets the sprite bank used for drawing icons
void setSpriteBank(IGUISpriteBank* bank) override;
//! gets the sprite bank used for drawing icons
IGUISpriteBank* getSpriteBank() const override;
//! Returns a default icon
/** Returns the sprite index within the sprite bank */
u32 getIcon(EGUI_DEFAULT_ICON icon) const override;
//! Sets a default icon
/** Sets the sprite index used for drawing icons like arrows,
close buttons and ticks in checkboxes
\param icon: Enum specifying which icon to change
\param index: The sprite index used to draw this icon */
void setIcon(EGUI_DEFAULT_ICON icon, u32 index) override;
//! Returns a default text.
/** For example for Message box button captions:
"OK", "Cancel", "Yes", "No" and so on. */
const wchar_t* getDefaultText(EGUI_DEFAULT_TEXT text) const override;
//! Sets a default text.
/** For example for Message box button captions:
"OK", "Cancel", "Yes", "No" and so on. */
void setDefaultText(EGUI_DEFAULT_TEXT which, const wchar_t* newText) override;
//! draws a standard 3d button pane
/** Used for drawing for example buttons in normal state.
It uses the colors EGDC_3D_DARK_SHADOW, EGDC_3D_HIGH_LIGHT, EGDC_3D_SHADOW and
EGDC_3D_FACE for this. See EGUI_DEFAULT_COLOR for details.
\param rect: Defining area where to draw.
\param clip: Clip area.
\param element: Pointer to the element which wishes to draw this. This parameter
is usually not used by ISkin, but can be used for example by more complex
implementations to find out how to draw the part exactly. */
virtual void draw3DButtonPaneStandard(IGUIElement* element,
const core::rect<s32>& rect,
const core::rect<s32>* clip=0) override;
//! draws a pressed 3d button pane
/** Used for drawing for example buttons in pressed state.
It uses the colors EGDC_3D_DARK_SHADOW, EGDC_3D_HIGH_LIGHT, EGDC_3D_SHADOW and
EGDC_3D_FACE for this. See EGUI_DEFAULT_COLOR for details.
\param rect: Defining area where to draw.
\param clip: Clip area.
\param element: Pointer to the element which wishes to draw this. This parameter
is usually not used by ISkin, but can be used for example by more complex
implementations to find out how to draw the part exactly. */
virtual void draw3DButtonPanePressed(IGUIElement* element,
const core::rect<s32>& rect,
const core::rect<s32>* clip=0) override;
//! draws a sunken 3d pane
/** Used for drawing the background of edit, combo or check boxes.
\param element: Pointer to the element which wishes to draw this. This parameter
is usually not used by ISkin, but can be used for example by more complex
implementations to find out how to draw the part exactly.
\param bgcolor: Background color.
\param flat: Specifies if the sunken pane should be flat or displayed as sunken
deep into the ground.
\param rect: Defining area where to draw.
\param clip: Clip area. */
virtual void draw3DSunkenPane(IGUIElement* element,
video::SColor bgcolor, bool flat,
bool fillBackGround,
const core::rect<s32>& rect,
const core::rect<s32>* clip=0) override;
//! draws a window background
/** Used for drawing the background of dialogs and windows.
\param element: Pointer to the element which wishes to draw this. This parameter
is usually not used by ISkin, but can be used for example by more complex
implementations to find out how to draw the part exactly.
\param titleBarColor: Title color.
\param drawTitleBar: True to enable title drawing.
\param rect: Defining area where to draw.
\param clip: Clip area.
\param checkClientArea: When set to non-null the function will not draw anything,
but will instead return the clientArea which can be used for drawing by the calling window.
That is the area without borders and without titlebar.
\return Returns rect where it would be good to draw title bar text. This will
work even when checkClientArea is set to a non-null value.*/
virtual core::rect<s32> draw3DWindowBackground(IGUIElement* element,
bool drawTitleBar, video::SColor titleBarColor,
const core::rect<s32>& rect,
const core::rect<s32>* clip,
core::rect<s32>* checkClientArea) override;
//! draws a standard 3d menu pane
/** Used for drawing for menus and context menus.
It uses the colors EGDC_3D_DARK_SHADOW, EGDC_3D_HIGH_LIGHT, EGDC_3D_SHADOW and
EGDC_3D_FACE for this. See EGUI_DEFAULT_COLOR for details.
\param element: Pointer to the element which wishes to draw this. This parameter
is usually not used by ISkin, but can be used for example by more complex
implementations to find out how to draw the part exactly.
\param rect: Defining area where to draw.
\param clip: Clip area. */
virtual void draw3DMenuPane(IGUIElement* element,
const core::rect<s32>& rect,
const core::rect<s32>* clip=0) override;
//! draws a standard 3d tool bar
/** Used for drawing for toolbars and menus.
\param element: Pointer to the element which wishes to draw this. This parameter
is usually not used by ISkin, but can be used for example by more complex
implementations to find out how to draw the part exactly.
\param rect: Defining area where to draw.
\param clip: Clip area. */
virtual void draw3DToolBar(IGUIElement* element,
const core::rect<s32>& rect,
const core::rect<s32>* clip=0) override;
//! draws a tab button
/** Used for drawing for tab buttons on top of tabs.
\param element: Pointer to the element which wishes to draw this. This parameter
is usually not used by ISkin, but can be used for example by more complex
implementations to find out how to draw the part exactly.
\param active: Specifies if the tab is currently active.
\param rect: Defining area where to draw.
\param clip: Clip area. */
virtual void draw3DTabButton(IGUIElement* element, bool active,
const core::rect<s32>& rect, const core::rect<s32>* clip=0,
EGUI_ALIGNMENT alignment=EGUIA_UPPERLEFT) override;
//! draws a tab control body
/** \param element: Pointer to the element which wishes to draw this. This parameter
is usually not used by ISkin, but can be used for example by more complex
implementations to find out how to draw the part exactly.
\param border: Specifies if the border should be drawn.
\param background: Specifies if the background should be drawn.
\param rect: Defining area where to draw.
\param clip: Clip area. */
virtual void draw3DTabBody(IGUIElement* element, bool border, bool background,
const core::rect<s32>& rect, const core::rect<s32>* clip=0, s32 tabHeight=-1,
EGUI_ALIGNMENT alignment=EGUIA_UPPERLEFT) override;
//! draws an icon, usually from the skin's sprite bank
/** \param element: Pointer to the element which wishes to draw this icon.
This parameter is usually not used by IGUISkin, but can be used for example
by more complex implementations to find out how to draw the part exactly.
\param icon: Specifies the icon to be drawn.
\param position: The position to draw the icon
\param starttime: The time at the start of the animation
\param currenttime: The present time, used to calculate the frame number
\param loop: Whether the animation should loop or not
\param clip: Clip area. */
virtual void drawIcon(IGUIElement* element, EGUI_DEFAULT_ICON icon,
const core::position2di position,
u32 starttime=0, u32 currenttime=0,
bool loop=false, const core::rect<s32>* clip=0) override;
//! draws a 2d rectangle.
/** \param element: Pointer to the element which wishes to draw this icon.
This parameter is usually not used by IGUISkin, but can be used for example
by more complex implementations to find out how to draw the part exactly.
\param color: Color of the rectangle to draw. The alpha component specifies how
transparent the rectangle will be.
\param pos: Position of the rectangle.
\param clip: Pointer to rectangle against which the rectangle will be clipped.
If the pointer is null, no clipping will be performed. */
virtual void draw2DRectangle(IGUIElement* element, const video::SColor &color,
const core::rect<s32>& pos, const core::rect<s32>* clip = 0) override;
//! get the type of this skin
EGUI_SKIN_TYPE getType() const override;
private:
video::SColor Colors[EGDC_COUNT];
s32 Sizes[EGDS_COUNT];
u32 Icons[EGDI_COUNT];
IGUIFont* Fonts[EGDF_COUNT];
IGUISpriteBank* SpriteBank;
core::stringw Texts[EGDT_COUNT];
video::IVideoDriver* Driver;
bool UseGradient;
EGUI_SKIN_TYPE Type;
};
} // end namespace gui
} // end namespace irr

View File

@ -1,265 +1,265 @@
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#include "CGUISpriteBank.h"
#include "IGUIEnvironment.h"
#include "IVideoDriver.h"
#include "ITexture.h"
namespace irr
{
namespace gui
{
CGUISpriteBank::CGUISpriteBank(IGUIEnvironment* env) :
Environment(env), Driver(0)
{
#ifdef _DEBUG
setDebugName("CGUISpriteBank");
#endif
if (Environment)
{
Driver = Environment->getVideoDriver();
if (Driver)
Driver->grab();
}
}
CGUISpriteBank::~CGUISpriteBank()
{
clear();
// drop video driver
if (Driver)
Driver->drop();
}
core::array< core::rect<s32> >& CGUISpriteBank::getPositions()
{
return Rectangles;
}
core::array< SGUISprite >& CGUISpriteBank::getSprites()
{
return Sprites;
}
u32 CGUISpriteBank::getTextureCount() const
{
return Textures.size();
}
video::ITexture* CGUISpriteBank::getTexture(u32 index) const
{
if (index < Textures.size())
return Textures[index];
else
return 0;
}
void CGUISpriteBank::addTexture(video::ITexture* texture)
{
if (texture)
texture->grab();
Textures.push_back(texture);
}
void CGUISpriteBank::setTexture(u32 index, video::ITexture* texture)
{
while (index >= Textures.size())
Textures.push_back(0);
if (texture)
texture->grab();
if (Textures[index])
Textures[index]->drop();
Textures[index] = texture;
}
//! clear everything
void CGUISpriteBank::clear()
{
// drop textures
for (u32 i=0; i<Textures.size(); ++i)
{
if (Textures[i])
Textures[i]->drop();
}
Textures.clear();
Sprites.clear();
Rectangles.clear();
}
//! Add the texture and use it for a single non-animated sprite.
s32 CGUISpriteBank::addTextureAsSprite(video::ITexture* texture)
{
if ( !texture )
return -1;
addTexture(texture);
u32 textureIndex = getTextureCount() - 1;
u32 rectangleIndex = Rectangles.size();
Rectangles.push_back( core::rect<s32>(0,0, texture->getOriginalSize().Width, texture->getOriginalSize().Height) );
SGUISprite sprite;
sprite.frameTime = 0;
SGUISpriteFrame frame;
frame.textureNumber = textureIndex;
frame.rectNumber = rectangleIndex;
sprite.Frames.push_back( frame );
Sprites.push_back( sprite );
return Sprites.size() - 1;
}
// get FrameNr for time. return true on exisiting frame
inline bool CGUISpriteBank::getFrameNr(u32& frame,u32 index, u32 time, bool loop) const
{
frame = 0;
if (index >= Sprites.size())
return false;
const SGUISprite& sprite = Sprites[index];
const u32 frameSize = sprite.Frames.size();
if (frameSize < 1)
return false;
if (sprite.frameTime)
{
u32 f = (time / sprite.frameTime);
if (loop)
frame = f % frameSize;
else
frame = (f >= frameSize) ? frameSize - 1 : f;
}
return true;
}
//! draws a sprite in 2d with scale and color
void CGUISpriteBank::draw2DSprite(u32 index, const core::position2di& pos,
const core::rect<s32>* clip, const video::SColor& color,
u32 starttime, u32 currenttime, bool loop, bool center)
{
u32 frame = 0;
if (!getFrameNr(frame, index, currenttime - starttime, loop))
return;
const video::ITexture* tex = getTexture(Sprites[index].Frames[frame].textureNumber);
if (!tex)
return;
const u32 rn = Sprites[index].Frames[frame].rectNumber;
if (rn >= Rectangles.size())
return;
const core::rect<s32>& r = Rectangles[rn];
core::position2di p(pos);
if (center)
{
p -= r.getSize() / 2;
}
Driver->draw2DImage(tex, p, r, clip, color, true);
}
void CGUISpriteBank::draw2DSprite(u32 index, const core::rect<s32>& destRect,
const core::rect<s32>* clip, const video::SColor * const colors,
u32 timeTicks, bool loop)
{
u32 frame = 0;
if (!getFrameNr(frame,index, timeTicks, loop))
return;
const video::ITexture* tex = getTexture(Sprites[index].Frames[frame].textureNumber);
if (!tex)
return;
const u32 rn = Sprites[index].Frames[frame].rectNumber;
if (rn >= Rectangles.size())
return;
Driver->draw2DImage(tex, destRect, Rectangles[rn], clip, colors, true);
}
void CGUISpriteBank::draw2DSpriteBatch( const core::array<u32>& indices,
const core::array<core::position2di>& pos,
const core::rect<s32>* clip,
const video::SColor& color,
u32 starttime, u32 currenttime,
bool loop, bool center)
{
const irr::u32 drawCount = core::min_<u32>(indices.size(), pos.size());
if (!getTextureCount())
return;
core::array<SDrawBatch> drawBatches(getTextureCount());
for (u32 i=0; i < Textures.size(); ++i)
{
drawBatches.push_back(SDrawBatch());
drawBatches[i].positions.reallocate(drawCount);
drawBatches[i].sourceRects.reallocate(drawCount);
}
for (u32 i = 0; i < drawCount; ++i)
{
const u32 index = indices[i];
// work out frame number
u32 frame = 0;
if (!getFrameNr(frame, index, currenttime - starttime, loop))
return;
const u32 texNum = Sprites[index].Frames[frame].textureNumber;
if (texNum >= drawBatches.size())
{
continue;
}
SDrawBatch& currentBatch = drawBatches[texNum];
const u32 rn = Sprites[index].Frames[frame].rectNumber;
if (rn >= Rectangles.size())
return;
const core::rect<s32>& r = Rectangles[rn];
if (center)
{
core::position2di p = pos[i];
p -= r.getSize() / 2;
currentBatch.positions.push_back(p);
currentBatch.sourceRects.push_back(r);
}
else
{
currentBatch.positions.push_back(pos[i]);
currentBatch.sourceRects.push_back(r);
}
}
for(u32 i = 0;i < drawBatches.size();i++)
{
if(!drawBatches[i].positions.empty() && !drawBatches[i].sourceRects.empty())
Driver->draw2DImageBatch(getTexture(i), drawBatches[i].positions,
drawBatches[i].sourceRects, clip, color, true);
}
}
} // namespace gui
} // namespace irr
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#include "CGUISpriteBank.h"
#include "IGUIEnvironment.h"
#include "IVideoDriver.h"
#include "ITexture.h"
namespace irr
{
namespace gui
{
CGUISpriteBank::CGUISpriteBank(IGUIEnvironment* env) :
Environment(env), Driver(0)
{
#ifdef _DEBUG
setDebugName("CGUISpriteBank");
#endif
if (Environment)
{
Driver = Environment->getVideoDriver();
if (Driver)
Driver->grab();
}
}
CGUISpriteBank::~CGUISpriteBank()
{
clear();
// drop video driver
if (Driver)
Driver->drop();
}
core::array< core::rect<s32> >& CGUISpriteBank::getPositions()
{
return Rectangles;
}
core::array< SGUISprite >& CGUISpriteBank::getSprites()
{
return Sprites;
}
u32 CGUISpriteBank::getTextureCount() const
{
return Textures.size();
}
video::ITexture* CGUISpriteBank::getTexture(u32 index) const
{
if (index < Textures.size())
return Textures[index];
else
return 0;
}
void CGUISpriteBank::addTexture(video::ITexture* texture)
{
if (texture)
texture->grab();
Textures.push_back(texture);
}
void CGUISpriteBank::setTexture(u32 index, video::ITexture* texture)
{
while (index >= Textures.size())
Textures.push_back(0);
if (texture)
texture->grab();
if (Textures[index])
Textures[index]->drop();
Textures[index] = texture;
}
//! clear everything
void CGUISpriteBank::clear()
{
// drop textures
for (u32 i=0; i<Textures.size(); ++i)
{
if (Textures[i])
Textures[i]->drop();
}
Textures.clear();
Sprites.clear();
Rectangles.clear();
}
//! Add the texture and use it for a single non-animated sprite.
s32 CGUISpriteBank::addTextureAsSprite(video::ITexture* texture)
{
if ( !texture )
return -1;
addTexture(texture);
u32 textureIndex = getTextureCount() - 1;
u32 rectangleIndex = Rectangles.size();
Rectangles.push_back( core::rect<s32>(0,0, texture->getOriginalSize().Width, texture->getOriginalSize().Height) );
SGUISprite sprite;
sprite.frameTime = 0;
SGUISpriteFrame frame;
frame.textureNumber = textureIndex;
frame.rectNumber = rectangleIndex;
sprite.Frames.push_back( frame );
Sprites.push_back( sprite );
return Sprites.size() - 1;
}
// get FrameNr for time. return true on exisiting frame
inline bool CGUISpriteBank::getFrameNr(u32& frame,u32 index, u32 time, bool loop) const
{
frame = 0;
if (index >= Sprites.size())
return false;
const SGUISprite& sprite = Sprites[index];
const u32 frameSize = sprite.Frames.size();
if (frameSize < 1)
return false;
if (sprite.frameTime)
{
u32 f = (time / sprite.frameTime);
if (loop)
frame = f % frameSize;
else
frame = (f >= frameSize) ? frameSize - 1 : f;
}
return true;
}
//! draws a sprite in 2d with scale and color
void CGUISpriteBank::draw2DSprite(u32 index, const core::position2di& pos,
const core::rect<s32>* clip, const video::SColor& color,
u32 starttime, u32 currenttime, bool loop, bool center)
{
u32 frame = 0;
if (!getFrameNr(frame, index, currenttime - starttime, loop))
return;
const video::ITexture* tex = getTexture(Sprites[index].Frames[frame].textureNumber);
if (!tex)
return;
const u32 rn = Sprites[index].Frames[frame].rectNumber;
if (rn >= Rectangles.size())
return;
const core::rect<s32>& r = Rectangles[rn];
core::position2di p(pos);
if (center)
{
p -= r.getSize() / 2;
}
Driver->draw2DImage(tex, p, r, clip, color, true);
}
void CGUISpriteBank::draw2DSprite(u32 index, const core::rect<s32>& destRect,
const core::rect<s32>* clip, const video::SColor * const colors,
u32 timeTicks, bool loop)
{
u32 frame = 0;
if (!getFrameNr(frame,index, timeTicks, loop))
return;
const video::ITexture* tex = getTexture(Sprites[index].Frames[frame].textureNumber);
if (!tex)
return;
const u32 rn = Sprites[index].Frames[frame].rectNumber;
if (rn >= Rectangles.size())
return;
Driver->draw2DImage(tex, destRect, Rectangles[rn], clip, colors, true);
}
void CGUISpriteBank::draw2DSpriteBatch( const core::array<u32>& indices,
const core::array<core::position2di>& pos,
const core::rect<s32>* clip,
const video::SColor& color,
u32 starttime, u32 currenttime,
bool loop, bool center)
{
const irr::u32 drawCount = core::min_<u32>(indices.size(), pos.size());
if (!getTextureCount())
return;
core::array<SDrawBatch> drawBatches(getTextureCount());
for (u32 i=0; i < Textures.size(); ++i)
{
drawBatches.push_back(SDrawBatch());
drawBatches[i].positions.reallocate(drawCount);
drawBatches[i].sourceRects.reallocate(drawCount);
}
for (u32 i = 0; i < drawCount; ++i)
{
const u32 index = indices[i];
// work out frame number
u32 frame = 0;
if (!getFrameNr(frame, index, currenttime - starttime, loop))
return;
const u32 texNum = Sprites[index].Frames[frame].textureNumber;
if (texNum >= drawBatches.size())
{
continue;
}
SDrawBatch& currentBatch = drawBatches[texNum];
const u32 rn = Sprites[index].Frames[frame].rectNumber;
if (rn >= Rectangles.size())
return;
const core::rect<s32>& r = Rectangles[rn];
if (center)
{
core::position2di p = pos[i];
p -= r.getSize() / 2;
currentBatch.positions.push_back(p);
currentBatch.sourceRects.push_back(r);
}
else
{
currentBatch.positions.push_back(pos[i]);
currentBatch.sourceRects.push_back(r);
}
}
for(u32 i = 0;i < drawBatches.size();i++)
{
if(!drawBatches[i].positions.empty() && !drawBatches[i].sourceRects.empty())
Driver->draw2DImageBatch(getTexture(i), drawBatches[i].positions,
drawBatches[i].sourceRects, clip, color, true);
}
}
} // namespace gui
} // namespace irr

View File

@ -1,84 +1,84 @@
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#pragma once
#include "IGUISpriteBank.h"
namespace irr
{
namespace video
{
class IVideoDriver;
class ITexture;
}
namespace gui
{
class IGUIEnvironment;
//! Sprite bank interface.
class CGUISpriteBank : public IGUISpriteBank
{
public:
CGUISpriteBank(IGUIEnvironment* env);
virtual ~CGUISpriteBank();
core::array< core::rect<s32> >& getPositions() override;
core::array< SGUISprite >& getSprites() override;
u32 getTextureCount() const override;
video::ITexture* getTexture(u32 index) const override;
void addTexture(video::ITexture* texture) override;
void setTexture(u32 index, video::ITexture* texture) override;
//! Add the texture and use it for a single non-animated sprite.
s32 addTextureAsSprite(video::ITexture* texture) override;
//! clears sprites, rectangles and textures
void clear() override;
//! Draws a sprite in 2d with position and color
virtual void draw2DSprite(u32 index, const core::position2di& pos, const core::rect<s32>* clip=0,
const video::SColor& color= video::SColor(255,255,255,255),
u32 starttime=0, u32 currenttime=0, bool loop=true, bool center=false) override;
//! Draws a sprite in 2d with destination rectangle and colors
virtual void draw2DSprite(u32 index, const core::rect<s32>& destRect,
const core::rect<s32>* clip=0,
const video::SColor * const colors=0,
u32 timeTicks = 0,
bool loop=true) override;
//! Draws a sprite batch in 2d using an array of positions and a color
virtual void draw2DSpriteBatch(const core::array<u32>& indices, const core::array<core::position2di>& pos,
const core::rect<s32>* clip=0,
const video::SColor& color= video::SColor(255,255,255,255),
u32 starttime=0, u32 currenttime=0,
bool loop=true, bool center=false) override;
protected:
bool getFrameNr(u32& frameNr, u32 index, u32 time, bool loop) const;
struct SDrawBatch
{
core::array<core::position2di> positions;
core::array<core::recti> sourceRects;
u32 textureNumber;
};
core::array<SGUISprite> Sprites;
core::array< core::rect<s32> > Rectangles;
core::array<video::ITexture*> Textures;
IGUIEnvironment* Environment;
video::IVideoDriver* Driver;
};
} // end namespace gui
} // end namespace irr
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#pragma once
#include "IGUISpriteBank.h"
namespace irr
{
namespace video
{
class IVideoDriver;
class ITexture;
}
namespace gui
{
class IGUIEnvironment;
//! Sprite bank interface.
class CGUISpriteBank : public IGUISpriteBank
{
public:
CGUISpriteBank(IGUIEnvironment* env);
virtual ~CGUISpriteBank();
core::array< core::rect<s32> >& getPositions() override;
core::array< SGUISprite >& getSprites() override;
u32 getTextureCount() const override;
video::ITexture* getTexture(u32 index) const override;
void addTexture(video::ITexture* texture) override;
void setTexture(u32 index, video::ITexture* texture) override;
//! Add the texture and use it for a single non-animated sprite.
s32 addTextureAsSprite(video::ITexture* texture) override;
//! clears sprites, rectangles and textures
void clear() override;
//! Draws a sprite in 2d with position and color
virtual void draw2DSprite(u32 index, const core::position2di& pos, const core::rect<s32>* clip=0,
const video::SColor& color= video::SColor(255,255,255,255),
u32 starttime=0, u32 currenttime=0, bool loop=true, bool center=false) override;
//! Draws a sprite in 2d with destination rectangle and colors
virtual void draw2DSprite(u32 index, const core::rect<s32>& destRect,
const core::rect<s32>* clip=0,
const video::SColor * const colors=0,
u32 timeTicks = 0,
bool loop=true) override;
//! Draws a sprite batch in 2d using an array of positions and a color
virtual void draw2DSpriteBatch(const core::array<u32>& indices, const core::array<core::position2di>& pos,
const core::rect<s32>* clip=0,
const video::SColor& color= video::SColor(255,255,255,255),
u32 starttime=0, u32 currenttime=0,
bool loop=true, bool center=false) override;
protected:
bool getFrameNr(u32& frameNr, u32 index, u32 time, bool loop) const;
struct SDrawBatch
{
core::array<core::position2di> positions;
core::array<core::recti> sourceRects;
u32 textureNumber;
};
core::array<SGUISprite> Sprites;
core::array< core::rect<s32> > Rectangles;
core::array<video::ITexture*> Textures;
IGUIEnvironment* Environment;
video::IVideoDriver* Driver;
};
} // end namespace gui
} // end namespace irr

File diff suppressed because it is too large Load Diff

View File

@ -1,133 +1,133 @@
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#pragma once
#include "IGUIStaticText.h"
#include "irrArray.h"
namespace irr
{
namespace gui
{
class CGUIStaticText : public IGUIStaticText
{
public:
//! constructor
CGUIStaticText(const wchar_t* text, bool border, IGUIEnvironment* environment,
IGUIElement* parent, s32 id, const core::rect<s32>& rectangle,
bool background = false);
//! destructor
virtual ~CGUIStaticText();
//! draws the element and its children
void draw() override;
//! Sets another skin independent font.
void setOverrideFont(IGUIFont* font=0) override;
//! Gets the override font (if any)
IGUIFont* getOverrideFont() const override;
//! Get the font which is used right now for drawing
IGUIFont* getActiveFont() const override;
//! Sets another color for the text.
void setOverrideColor(video::SColor color) override;
//! Sets another color for the background.
void setBackgroundColor(video::SColor color) override;
//! Sets whether to draw the background
void setDrawBackground(bool draw) override;
//! Gets the background color
video::SColor getBackgroundColor() const override;
//! Checks if background drawing is enabled
bool isDrawBackgroundEnabled() const override;
//! Sets whether to draw the border
void setDrawBorder(bool draw) override;
//! Checks if border drawing is enabled
bool isDrawBorderEnabled() const override;
//! Sets alignment mode for text
void setTextAlignment(EGUI_ALIGNMENT horizontal, EGUI_ALIGNMENT vertical) override;
//! Gets the override color
video::SColor getOverrideColor() const override;
//! Gets the currently used text color
video::SColor getActiveColor() const override;
//! Sets if the static text should use the override color or the
//! color in the gui skin.
void enableOverrideColor(bool enable) override;
//! Checks if an override color is enabled
bool isOverrideColorEnabled() const override;
//! Set whether the text in this label should be clipped if it goes outside bounds
void setTextRestrainedInside(bool restrainedInside) override;
//! Checks if the text in this label should be clipped if it goes outside bounds
bool isTextRestrainedInside() const override;
//! Enables or disables word wrap for using the static text as
//! multiline text control.
void setWordWrap(bool enable) override;
//! Checks if word wrap is enabled
bool isWordWrapEnabled() const override;
//! Sets the new caption of this element.
void setText(const wchar_t* text) override;
//! Returns the height of the text in pixels when it is drawn.
s32 getTextHeight() const override;
//! Returns the width of the current text, in the current font
s32 getTextWidth() const override;
//! Updates the absolute position, splits text if word wrap is enabled
void updateAbsolutePosition() override;
//! Set whether the string should be interpreted as right-to-left (RTL) text
/** \note This component does not implement the Unicode bidi standard, the
text of the component should be already RTL if you call this. The
main difference when RTL is enabled is that the linebreaks for multiline
elements are performed starting from the end.
*/
void setRightToLeft(bool rtl) override;
//! Checks if the text should be interpreted as right-to-left text
bool isRightToLeft() const override;
private:
//! Breaks the single text line.
void breakText();
EGUI_ALIGNMENT HAlign, VAlign;
bool Border;
bool OverrideColorEnabled;
bool OverrideBGColorEnabled;
bool WordWrap;
bool Background;
bool RestrainTextInside;
bool RightToLeft;
video::SColor OverrideColor, BGColor;
gui::IGUIFont* OverrideFont;
gui::IGUIFont* LastBreakFont; // stored because: if skin changes, line break must be recalculated.
core::array< core::stringw > BrokenText;
};
} // end namespace gui
} // end namespace irr
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#pragma once
#include "IGUIStaticText.h"
#include "irrArray.h"
namespace irr
{
namespace gui
{
class CGUIStaticText : public IGUIStaticText
{
public:
//! constructor
CGUIStaticText(const wchar_t* text, bool border, IGUIEnvironment* environment,
IGUIElement* parent, s32 id, const core::rect<s32>& rectangle,
bool background = false);
//! destructor
virtual ~CGUIStaticText();
//! draws the element and its children
void draw() override;
//! Sets another skin independent font.
void setOverrideFont(IGUIFont* font=0) override;
//! Gets the override font (if any)
IGUIFont* getOverrideFont() const override;
//! Get the font which is used right now for drawing
IGUIFont* getActiveFont() const override;
//! Sets another color for the text.
void setOverrideColor(video::SColor color) override;
//! Sets another color for the background.
void setBackgroundColor(video::SColor color) override;
//! Sets whether to draw the background
void setDrawBackground(bool draw) override;
//! Gets the background color
video::SColor getBackgroundColor() const override;
//! Checks if background drawing is enabled
bool isDrawBackgroundEnabled() const override;
//! Sets whether to draw the border
void setDrawBorder(bool draw) override;
//! Checks if border drawing is enabled
bool isDrawBorderEnabled() const override;
//! Sets alignment mode for text
void setTextAlignment(EGUI_ALIGNMENT horizontal, EGUI_ALIGNMENT vertical) override;
//! Gets the override color
video::SColor getOverrideColor() const override;
//! Gets the currently used text color
video::SColor getActiveColor() const override;
//! Sets if the static text should use the override color or the
//! color in the gui skin.
void enableOverrideColor(bool enable) override;
//! Checks if an override color is enabled
bool isOverrideColorEnabled() const override;
//! Set whether the text in this label should be clipped if it goes outside bounds
void setTextRestrainedInside(bool restrainedInside) override;
//! Checks if the text in this label should be clipped if it goes outside bounds
bool isTextRestrainedInside() const override;
//! Enables or disables word wrap for using the static text as
//! multiline text control.
void setWordWrap(bool enable) override;
//! Checks if word wrap is enabled
bool isWordWrapEnabled() const override;
//! Sets the new caption of this element.
void setText(const wchar_t* text) override;
//! Returns the height of the text in pixels when it is drawn.
s32 getTextHeight() const override;
//! Returns the width of the current text, in the current font
s32 getTextWidth() const override;
//! Updates the absolute position, splits text if word wrap is enabled
void updateAbsolutePosition() override;
//! Set whether the string should be interpreted as right-to-left (RTL) text
/** \note This component does not implement the Unicode bidi standard, the
text of the component should be already RTL if you call this. The
main difference when RTL is enabled is that the linebreaks for multiline
elements are performed starting from the end.
*/
void setRightToLeft(bool rtl) override;
//! Checks if the text should be interpreted as right-to-left text
bool isRightToLeft() const override;
private:
//! Breaks the single text line.
void breakText();
EGUI_ALIGNMENT HAlign, VAlign;
bool Border;
bool OverrideColorEnabled;
bool OverrideBGColorEnabled;
bool WordWrap;
bool Background;
bool RestrainTextInside;
bool RightToLeft;
video::SColor OverrideColor, BGColor;
gui::IGUIFont* OverrideFont;
gui::IGUIFont* LastBreakFont; // stored because: if skin changes, line break must be recalculated.
core::array< core::stringw > BrokenText;
};
} // end namespace gui
} // end namespace irr

File diff suppressed because it is too large Load Diff

View File

@ -1,181 +1,181 @@
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#pragma once
#include "IGUITabControl.h"
#include "irrArray.h"
#include "IGUISkin.h"
namespace irr
{
namespace gui
{
class CGUITabControl;
class IGUIButton;
// A tab, onto which other gui elements could be added.
class CGUITab : public IGUITab
{
public:
//! constructor
CGUITab(IGUIEnvironment* environment,
IGUIElement* parent, const core::rect<s32>& rectangle,
s32 id);
//! draws the element and its children
void draw() override;
//! sets if the tab should draw its background
void setDrawBackground(bool draw=true) override;
//! sets the color of the background, if it should be drawn.
void setBackgroundColor(video::SColor c) override;
//! sets the color of the text
void setTextColor(video::SColor c) override;
//! returns true if the tab is drawing its background, false if not
bool isDrawingBackground() const override;
//! returns the color of the background
video::SColor getBackgroundColor() const override;
video::SColor getTextColor() const override;
private:
video::SColor BackColor;
bool OverrideTextColorEnabled;
video::SColor TextColor;
bool DrawBackground;
};
//! A standard tab control
class CGUITabControl : public IGUITabControl
{
public:
//! destructor
CGUITabControl(IGUIEnvironment* environment,
IGUIElement* parent, const core::rect<s32>& rectangle,
bool fillbackground=true, bool border=true, s32 id=-1);
//! destructor
virtual ~CGUITabControl();
//! Adds a tab
IGUITab* addTab(const wchar_t* caption, s32 id=-1) override;
//! Adds an existing tab
s32 addTab(IGUITab* tab) override;
//! Insert the tab at the given index
IGUITab* insertTab(s32 idx, const wchar_t* caption, s32 id=-1) override;
//! Insert an existing tab
/** Note that it will also add the tab as a child of this TabControl.
\return Index of added tab (should be same as the one passed) or -1 for failure*/
s32 insertTab(s32 idx, IGUITab* tab, bool serializationMode) override;
//! Removes a tab from the tabcontrol
void removeTab(s32 idx) override;
//! Clears the tabcontrol removing all tabs
void clear() override;
//! Returns amount of tabs in the tabcontrol
s32 getTabCount() const override;
//! Returns a tab based on zero based index
IGUITab* getTab(s32 idx) const override;
//! Brings a tab to front.
bool setActiveTab(s32 idx) override;
//! Brings a tab to front.
bool setActiveTab(IGUITab *tab) override;
//! For given given tab find it's zero-based index (or -1 for not found)
s32 getTabIndex(const IGUIElement *tab) const override;
//! Returns which tab is currently active
s32 getActiveTab() const override;
//! get the the id of the tab at the given absolute coordinates
s32 getTabAt(s32 xpos, s32 ypos) const override;
//! called if an event happened.
bool OnEvent(const SEvent& event) override;
//! draws the element and its children
void draw() override;
//! Removes a child.
void removeChild(IGUIElement* child) override;
//! Set the height of the tabs
void setTabHeight( s32 height ) override;
//! Get the height of the tabs
s32 getTabHeight() const override;
//! set the maximal width of a tab. Per default width is 0 which means "no width restriction".
void setTabMaxWidth(s32 width ) override;
//! get the maximal width of a tab
s32 getTabMaxWidth() const override;
//! Set the alignment of the tabs
//! note: EGUIA_CENTER is not an option
void setTabVerticalAlignment( gui::EGUI_ALIGNMENT alignment ) override;
//! Get the alignment of the tabs
gui::EGUI_ALIGNMENT getTabVerticalAlignment() const override;
//! Set the extra width added to tabs on each side of the text
void setTabExtraWidth( s32 extraWidth ) override;
//! Get the extra width added to tabs on each side of the text
s32 getTabExtraWidth() const override;
//! Update the position of the element, decides scroll button status
void updateAbsolutePosition() override;
private:
void scrollLeft();
void scrollRight();
//! Indicates whether the tabs overflow in X direction
bool needScrollControl( s32 startIndex=0, bool withScrollControl=false, s32 *pos_rightmost=nullptr );
//! Left index calculation based on the selected tab
s32 calculateScrollIndexFromActive();
s32 calcTabWidth(IGUIFont* font, const wchar_t* text) const;
core::rect<s32> calcTabPos();
void setVisibleTab(s32 idx);
void removeTabButNotChild(s32 idx);
void recalculateScrollButtonPlacement();
void recalculateScrollBar();
void refreshSprites();
core::array<IGUITab*> Tabs;
s32 ActiveTabIndex;
bool Border;
bool FillBackground;
bool ScrollControl;
s32 TabHeight;
gui::EGUI_ALIGNMENT VerticalAlignment;
IGUIButton* UpButton;
IGUIButton* DownButton;
s32 TabMaxWidth;
s32 CurrentScrollTabIndex;
s32 TabExtraWidth;
};
} // end namespace gui
} // end namespace irr
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#pragma once
#include "IGUITabControl.h"
#include "irrArray.h"
#include "IGUISkin.h"
namespace irr
{
namespace gui
{
class CGUITabControl;
class IGUIButton;
// A tab, onto which other gui elements could be added.
class CGUITab : public IGUITab
{
public:
//! constructor
CGUITab(IGUIEnvironment* environment,
IGUIElement* parent, const core::rect<s32>& rectangle,
s32 id);
//! draws the element and its children
void draw() override;
//! sets if the tab should draw its background
void setDrawBackground(bool draw=true) override;
//! sets the color of the background, if it should be drawn.
void setBackgroundColor(video::SColor c) override;
//! sets the color of the text
void setTextColor(video::SColor c) override;
//! returns true if the tab is drawing its background, false if not
bool isDrawingBackground() const override;
//! returns the color of the background
video::SColor getBackgroundColor() const override;
video::SColor getTextColor() const override;
private:
video::SColor BackColor;
bool OverrideTextColorEnabled;
video::SColor TextColor;
bool DrawBackground;
};
//! A standard tab control
class CGUITabControl : public IGUITabControl
{
public:
//! destructor
CGUITabControl(IGUIEnvironment* environment,
IGUIElement* parent, const core::rect<s32>& rectangle,
bool fillbackground=true, bool border=true, s32 id=-1);
//! destructor
virtual ~CGUITabControl();
//! Adds a tab
IGUITab* addTab(const wchar_t* caption, s32 id=-1) override;
//! Adds an existing tab
s32 addTab(IGUITab* tab) override;
//! Insert the tab at the given index
IGUITab* insertTab(s32 idx, const wchar_t* caption, s32 id=-1) override;
//! Insert an existing tab
/** Note that it will also add the tab as a child of this TabControl.
\return Index of added tab (should be same as the one passed) or -1 for failure*/
s32 insertTab(s32 idx, IGUITab* tab, bool serializationMode) override;
//! Removes a tab from the tabcontrol
void removeTab(s32 idx) override;
//! Clears the tabcontrol removing all tabs
void clear() override;
//! Returns amount of tabs in the tabcontrol
s32 getTabCount() const override;
//! Returns a tab based on zero based index
IGUITab* getTab(s32 idx) const override;
//! Brings a tab to front.
bool setActiveTab(s32 idx) override;
//! Brings a tab to front.
bool setActiveTab(IGUITab *tab) override;
//! For given given tab find it's zero-based index (or -1 for not found)
s32 getTabIndex(const IGUIElement *tab) const override;
//! Returns which tab is currently active
s32 getActiveTab() const override;
//! get the the id of the tab at the given absolute coordinates
s32 getTabAt(s32 xpos, s32 ypos) const override;
//! called if an event happened.
bool OnEvent(const SEvent& event) override;
//! draws the element and its children
void draw() override;
//! Removes a child.
void removeChild(IGUIElement* child) override;
//! Set the height of the tabs
void setTabHeight( s32 height ) override;
//! Get the height of the tabs
s32 getTabHeight() const override;
//! set the maximal width of a tab. Per default width is 0 which means "no width restriction".
void setTabMaxWidth(s32 width ) override;
//! get the maximal width of a tab
s32 getTabMaxWidth() const override;
//! Set the alignment of the tabs
//! note: EGUIA_CENTER is not an option
void setTabVerticalAlignment( gui::EGUI_ALIGNMENT alignment ) override;
//! Get the alignment of the tabs
gui::EGUI_ALIGNMENT getTabVerticalAlignment() const override;
//! Set the extra width added to tabs on each side of the text
void setTabExtraWidth( s32 extraWidth ) override;
//! Get the extra width added to tabs on each side of the text
s32 getTabExtraWidth() const override;
//! Update the position of the element, decides scroll button status
void updateAbsolutePosition() override;
private:
void scrollLeft();
void scrollRight();
//! Indicates whether the tabs overflow in X direction
bool needScrollControl( s32 startIndex=0, bool withScrollControl=false, s32 *pos_rightmost=nullptr );
//! Left index calculation based on the selected tab
s32 calculateScrollIndexFromActive();
s32 calcTabWidth(IGUIFont* font, const wchar_t* text) const;
core::rect<s32> calcTabPos();
void setVisibleTab(s32 idx);
void removeTabButNotChild(s32 idx);
void recalculateScrollButtonPlacement();
void recalculateScrollBar();
void refreshSprites();
core::array<IGUITab*> Tabs;
s32 ActiveTabIndex;
bool Border;
bool FillBackground;
bool ScrollControl;
s32 TabHeight;
gui::EGUI_ALIGNMENT VerticalAlignment;
IGUIButton* UpButton;
IGUIButton* DownButton;
s32 TabMaxWidth;
s32 CurrentScrollTabIndex;
s32 TabExtraWidth;
};
} // end namespace gui
} // end namespace irr

View File

@ -1,428 +1,428 @@
// Copyright (C) 2002-2012 Nikolaus Gebhardt / Thomas Alten
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#include "CImage.h"
#include "irrString.h"
#include "CColorConverter.h"
#include "CBlit.h"
#include "os.h"
#include "SoftwareDriver2_helper.h"
namespace irr
{
namespace video
{
//! Constructor from raw data
CImage::CImage(ECOLOR_FORMAT format, const core::dimension2d<u32>& size, void* data,
bool ownForeignMemory, bool deleteMemory) : IImage(format, size, deleteMemory)
{
if (ownForeignMemory)
{
Data = (u8*)data;
}
else
{
const u32 dataSize = getDataSizeFromFormat(Format, Size.Width, Size.Height);
Data = new u8[align_next(dataSize,16)];
memcpy(Data, data, dataSize);
DeleteMemory = true;
}
}
//! Constructor of empty image
CImage::CImage(ECOLOR_FORMAT format, const core::dimension2d<u32>& size) : IImage(format, size, true)
{
Data = new u8[align_next(getDataSizeFromFormat(Format, Size.Width, Size.Height),16)];
DeleteMemory = true;
}
//! sets a pixel
void CImage::setPixel(u32 x, u32 y, const SColor &color, bool blend)
{
if (x >= Size.Width || y >= Size.Height)
return;
switch(Format)
{
case ECF_A1R5G5B5:
{
u16 * dest = (u16*) (Data + ( y * Pitch ) + ( x << 1 ));
*dest = video::A8R8G8B8toA1R5G5B5( color.color );
} break;
case ECF_R5G6B5:
{
u16 * dest = (u16*) (Data + ( y * Pitch ) + ( x << 1 ));
*dest = video::A8R8G8B8toR5G6B5( color.color );
} break;
case ECF_R8G8B8:
{
u8* dest = Data + ( y * Pitch ) + ( x * 3 );
dest[0] = (u8)color.getRed();
dest[1] = (u8)color.getGreen();
dest[2] = (u8)color.getBlue();
} break;
case ECF_A8R8G8B8:
{
u32 * dest = (u32*) (Data + ( y * Pitch ) + ( x << 2 ));
*dest = blend ? PixelBlend32 ( *dest, color.color ) : color.color;
} break;
IRR_CASE_IIMAGE_COMPRESSED_FORMAT
os::Printer::log("IImage::setPixel method doesn't work with compressed images.", ELL_WARNING);
return;
case ECF_UNKNOWN:
os::Printer::log("IImage::setPixel unknown format.", ELL_WARNING);
return;
default:
break;
}
}
//! returns a pixel
SColor CImage::getPixel(u32 x, u32 y) const
{
if (x >= Size.Width || y >= Size.Height)
return SColor(0);
switch(Format)
{
case ECF_A1R5G5B5:
return A1R5G5B5toA8R8G8B8(((u16*)Data)[y*Size.Width + x]);
case ECF_R5G6B5:
return R5G6B5toA8R8G8B8(((u16*)Data)[y*Size.Width + x]);
case ECF_A8R8G8B8:
return ((u32*)Data)[y*Size.Width + x];
case ECF_R8G8B8:
{
u8* p = Data+(y*3)*Size.Width + (x*3);
return SColor(255,p[0],p[1],p[2]);
}
IRR_CASE_IIMAGE_COMPRESSED_FORMAT
os::Printer::log("IImage::getPixel method doesn't work with compressed images.", ELL_WARNING);
break;
case ECF_UNKNOWN:
os::Printer::log("IImage::getPixel unknown format.", ELL_WARNING);
break;
default:
break;
}
return SColor(0);
}
//! copies this surface into another at given position
void CImage::copyTo(IImage* target, const core::position2d<s32>& pos)
{
if (IImage::isCompressedFormat(Format))
{
os::Printer::log("IImage::copyTo method doesn't work with compressed images.", ELL_WARNING);
return;
}
if (!Blit(BLITTER_TEXTURE, target, 0, &pos, this, 0, 0)
&& target && pos.X == 0 && pos.Y == 0 &&
CColorConverter::canConvertFormat(Format, target->getColorFormat()))
{
// No fast blitting, but copyToScaling uses other color conversions and might work
irr::core::dimension2du dim(target->getDimension());
copyToScaling(target->getData(), dim.Width, dim.Height, target->getColorFormat(), target->getPitch());
}
}
//! copies this surface partially into another at given position
void CImage::copyTo(IImage* target, const core::position2d<s32>& pos, const core::rect<s32>& sourceRect, const core::rect<s32>* clipRect)
{
if (IImage::isCompressedFormat(Format))
{
os::Printer::log("IImage::copyTo method doesn't work with compressed images.", ELL_WARNING);
return;
}
Blit(BLITTER_TEXTURE, target, clipRect, &pos, this, &sourceRect, 0);
}
//! copies this surface into another, using the alpha mask, a cliprect and a color to add with
void CImage::copyToWithAlpha(IImage* target, const core::position2d<s32>& pos, const core::rect<s32>& sourceRect, const SColor &color, const core::rect<s32>* clipRect, bool combineAlpha)
{
if (IImage::isCompressedFormat(Format))
{
os::Printer::log("IImage::copyToWithAlpha method doesn't work with compressed images.", ELL_WARNING);
return;
}
eBlitter op = combineAlpha ? BLITTER_TEXTURE_COMBINE_ALPHA :
color.color == 0xFFFFFFFF ? BLITTER_TEXTURE_ALPHA_BLEND : BLITTER_TEXTURE_ALPHA_COLOR_BLEND;
Blit(op,target, clipRect, &pos, this, &sourceRect, color.color);
}
//! copies this surface into another, if it has the exact same size and format.
bool CImage::copyToNoScaling(void *target, u32 width, u32 height, ECOLOR_FORMAT format, u32 pitch) const
{
if (IImage::isCompressedFormat(Format))
{
os::Printer::log("IImage::copyToNoScaling method doesn't work with compressed images.", ELL_WARNING);
return false;
}
if (!target || !width || !height || !Size.Width || !Size.Height)
return false;
const u32 bpp=getBitsPerPixelFromFormat(format)/8;
if (0==pitch)
pitch = width*bpp;
if (!(Format==format && Size.Width==width && Size.Height==height))
return false;
if (pitch==Pitch)
{
memcpy(target, Data, (size_t)height*pitch);
}
else
{
u8* tgtpos = (u8*) target;
u8* srcpos = Data;
const u32 bwidth = width*bpp;
const u32 rest = pitch-bwidth;
for (u32 y=0; y<height; ++y)
{
// copy scanline
memcpy(tgtpos, srcpos, bwidth);
// clear pitch
memset(tgtpos+bwidth, 0, rest);
tgtpos += pitch;
srcpos += Pitch;
}
}
return true;
}
//! copies this surface into another, scaling it to the target image size
// note: this is very very slow.
void CImage::copyToScaling(void* target, u32 width, u32 height, ECOLOR_FORMAT format, u32 pitch)
{
if (IImage::isCompressedFormat(Format))
{
os::Printer::log("IImage::copyToScaling method doesn't work with compressed images.", ELL_WARNING);
return;
}
if (!target || !width || !height || !Size.Width || !Size.Height)
return;
const u32 bpp=getBitsPerPixelFromFormat(format)/8;
if (0==pitch)
pitch = width*bpp;
if (copyToNoScaling(target, width, height, format, pitch))
return;
// NOTE: Scaling is coded to keep the border pixels intact.
// Alternatively we could for example work with first pixel being taken at half step-size.
// Then we have one more step here and it would be:
// sourceXStep = (f32)(Size.Width-1) / (f32)(width);
// And sx would start at 0.5f + sourceXStep / 2.f;
// Similar for y.
// As scaling is done without any antialiasing it doesn't matter too much which outermost pixels we use and keeping
// border pixels intact is probably mostly better (with AA the other solution would be more correct).
// This is however unnecessary (and unexpected) for scaling to integer multiples, so don't do it there.
f32 sourceXStep, sourceYStep;
f32 sourceXStart = 0.f, sourceYStart = 0.f;
if (width % Size.Width == 0)
sourceXStep = (f32)(Size.Width) / (f32)(width);
else
{
sourceXStep = width > 1 ? (f32)(Size.Width-1) / (f32)(width-1) : 0.f;
sourceXStart = 0.5f; // for rounding to nearest pixel
}
if (height % Size.Height == 0)
sourceYStep = (f32)(Size.Height) / (f32)(height);
else
{
sourceYStep = height > 1 ? (f32)(Size.Height-1) / (f32)(height-1) : 0.f;
sourceYStart = 0.5f; // for rounding to nearest pixel
}
s32 yval=0, syval=0;
f32 sy = sourceYStart;
for (u32 y=0; y<height; ++y)
{
f32 sx = sourceXStart;
for (u32 x=0; x<width; ++x)
{
CColorConverter::convert_viaFormat(Data+ syval + ((s32)sx)*BytesPerPixel, Format, 1, ((u8*)target)+ yval + (x*bpp), format);
sx+=sourceXStep;
}
sy+=sourceYStep;
syval=(s32)(sy)*Pitch;
yval+=pitch;
}
}
//! copies this surface into another, scaling it to the target image size
// note: this is very very slow.
void CImage::copyToScaling(IImage* target)
{
if (IImage::isCompressedFormat(Format))
{
os::Printer::log("IImage::copyToScaling method doesn't work with compressed images.", ELL_WARNING);
return;
}
if (!target)
return;
const core::dimension2d<u32>& targetSize = target->getDimension();
if (targetSize==Size)
{
copyTo(target);
return;
}
copyToScaling(target->getData(), targetSize.Width, targetSize.Height, target->getColorFormat());
}
//! copies this surface into another, scaling it to fit it.
void CImage::copyToScalingBoxFilter(IImage* target, s32 bias, bool blend)
{
if (IImage::isCompressedFormat(Format))
{
os::Printer::log("IImage::copyToScalingBoxFilter method doesn't work with compressed images.", ELL_WARNING);
return;
}
const core::dimension2d<u32> destSize = target->getDimension();
const f32 sourceXStep = (f32) Size.Width / (f32) destSize.Width;
const f32 sourceYStep = (f32) Size.Height / (f32) destSize.Height;
s32 fx = core::ceil32( sourceXStep );
s32 fy = core::ceil32( sourceYStep );
f32 sx;
f32 sy;
sy = 0.f;
for ( u32 y = 0; y != destSize.Height; ++y )
{
sx = 0.f;
for ( u32 x = 0; x != destSize.Width; ++x )
{
target->setPixel( x, y,
getPixelBox( core::floor32(sx), core::floor32(sy), fx, fy, bias ), blend );
sx += sourceXStep;
}
sy += sourceYStep;
}
}
//! fills the surface with given color
void CImage::fill(const SColor &color)
{
if (IImage::isCompressedFormat(Format))
{
os::Printer::log("IImage::fill method doesn't work with compressed images.", ELL_WARNING);
return;
}
u32 c;
switch ( Format )
{
case ECF_A1R5G5B5:
c = color.toA1R5G5B5();
c |= c << 16;
break;
case ECF_R5G6B5:
c = video::A8R8G8B8toR5G6B5( color.color );
c |= c << 16;
break;
case ECF_A8R8G8B8:
c = color.color;
break;
case ECF_R8G8B8:
{
u8 rgb[3];
CColorConverter::convert_A8R8G8B8toR8G8B8(&color, 1, rgb);
const u32 size = getImageDataSizeInBytes();
for (u32 i=0; i<size; i+=3)
{
memcpy(Data+i, rgb, 3);
}
return;
}
break;
default:
// TODO: Handle other formats
return;
}
memset32( Data, c, getImageDataSizeInBytes() );
}
//! get a filtered pixel
inline SColor CImage::getPixelBox( s32 x, s32 y, s32 fx, s32 fy, s32 bias ) const
{
if (IImage::isCompressedFormat(Format))
{
os::Printer::log("IImage::getPixelBox method doesn't work with compressed images.", ELL_WARNING);
return SColor(0);
}
SColor c;
s32 a = 0, r = 0, g = 0, b = 0;
for ( s32 dx = 0; dx != fx; ++dx )
{
for ( s32 dy = 0; dy != fy; ++dy )
{
c = getPixel( core::s32_min ( x + dx, Size.Width - 1 ) ,
core::s32_min ( y + dy, Size.Height - 1 )
);
a += c.getAlpha();
r += c.getRed();
g += c.getGreen();
b += c.getBlue();
}
}
s32 sdiv = s32_log2_s32(fx * fy);
a = core::s32_clamp( ( a >> sdiv ) + bias, 0, 255 );
r = core::s32_clamp( ( r >> sdiv ) + bias, 0, 255 );
g = core::s32_clamp( ( g >> sdiv ) + bias, 0, 255 );
b = core::s32_clamp( ( b >> sdiv ) + bias, 0, 255 );
c.set( a, r, g, b );
return c;
}
} // end namespace video
} // end namespace irr
// Copyright (C) 2002-2012 Nikolaus Gebhardt / Thomas Alten
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#include "CImage.h"
#include "irrString.h"
#include "CColorConverter.h"
#include "CBlit.h"
#include "os.h"
#include "SoftwareDriver2_helper.h"
namespace irr
{
namespace video
{
//! Constructor from raw data
CImage::CImage(ECOLOR_FORMAT format, const core::dimension2d<u32>& size, void* data,
bool ownForeignMemory, bool deleteMemory) : IImage(format, size, deleteMemory)
{
if (ownForeignMemory)
{
Data = (u8*)data;
}
else
{
const u32 dataSize = getDataSizeFromFormat(Format, Size.Width, Size.Height);
Data = new u8[align_next(dataSize,16)];
memcpy(Data, data, dataSize);
DeleteMemory = true;
}
}
//! Constructor of empty image
CImage::CImage(ECOLOR_FORMAT format, const core::dimension2d<u32>& size) : IImage(format, size, true)
{
Data = new u8[align_next(getDataSizeFromFormat(Format, Size.Width, Size.Height),16)];
DeleteMemory = true;
}
//! sets a pixel
void CImage::setPixel(u32 x, u32 y, const SColor &color, bool blend)
{
if (x >= Size.Width || y >= Size.Height)
return;
switch(Format)
{
case ECF_A1R5G5B5:
{
u16 * dest = (u16*) (Data + ( y * Pitch ) + ( x << 1 ));
*dest = video::A8R8G8B8toA1R5G5B5( color.color );
} break;
case ECF_R5G6B5:
{
u16 * dest = (u16*) (Data + ( y * Pitch ) + ( x << 1 ));
*dest = video::A8R8G8B8toR5G6B5( color.color );
} break;
case ECF_R8G8B8:
{
u8* dest = Data + ( y * Pitch ) + ( x * 3 );
dest[0] = (u8)color.getRed();
dest[1] = (u8)color.getGreen();
dest[2] = (u8)color.getBlue();
} break;
case ECF_A8R8G8B8:
{
u32 * dest = (u32*) (Data + ( y * Pitch ) + ( x << 2 ));
*dest = blend ? PixelBlend32 ( *dest, color.color ) : color.color;
} break;
IRR_CASE_IIMAGE_COMPRESSED_FORMAT
os::Printer::log("IImage::setPixel method doesn't work with compressed images.", ELL_WARNING);
return;
case ECF_UNKNOWN:
os::Printer::log("IImage::setPixel unknown format.", ELL_WARNING);
return;
default:
break;
}
}
//! returns a pixel
SColor CImage::getPixel(u32 x, u32 y) const
{
if (x >= Size.Width || y >= Size.Height)
return SColor(0);
switch(Format)
{
case ECF_A1R5G5B5:
return A1R5G5B5toA8R8G8B8(((u16*)Data)[y*Size.Width + x]);
case ECF_R5G6B5:
return R5G6B5toA8R8G8B8(((u16*)Data)[y*Size.Width + x]);
case ECF_A8R8G8B8:
return ((u32*)Data)[y*Size.Width + x];
case ECF_R8G8B8:
{
u8* p = Data+(y*3)*Size.Width + (x*3);
return SColor(255,p[0],p[1],p[2]);
}
IRR_CASE_IIMAGE_COMPRESSED_FORMAT
os::Printer::log("IImage::getPixel method doesn't work with compressed images.", ELL_WARNING);
break;
case ECF_UNKNOWN:
os::Printer::log("IImage::getPixel unknown format.", ELL_WARNING);
break;
default:
break;
}
return SColor(0);
}
//! copies this surface into another at given position
void CImage::copyTo(IImage* target, const core::position2d<s32>& pos)
{
if (IImage::isCompressedFormat(Format))
{
os::Printer::log("IImage::copyTo method doesn't work with compressed images.", ELL_WARNING);
return;
}
if (!Blit(BLITTER_TEXTURE, target, 0, &pos, this, 0, 0)
&& target && pos.X == 0 && pos.Y == 0 &&
CColorConverter::canConvertFormat(Format, target->getColorFormat()))
{
// No fast blitting, but copyToScaling uses other color conversions and might work
irr::core::dimension2du dim(target->getDimension());
copyToScaling(target->getData(), dim.Width, dim.Height, target->getColorFormat(), target->getPitch());
}
}
//! copies this surface partially into another at given position
void CImage::copyTo(IImage* target, const core::position2d<s32>& pos, const core::rect<s32>& sourceRect, const core::rect<s32>* clipRect)
{
if (IImage::isCompressedFormat(Format))
{
os::Printer::log("IImage::copyTo method doesn't work with compressed images.", ELL_WARNING);
return;
}
Blit(BLITTER_TEXTURE, target, clipRect, &pos, this, &sourceRect, 0);
}
//! copies this surface into another, using the alpha mask, a cliprect and a color to add with
void CImage::copyToWithAlpha(IImage* target, const core::position2d<s32>& pos, const core::rect<s32>& sourceRect, const SColor &color, const core::rect<s32>* clipRect, bool combineAlpha)
{
if (IImage::isCompressedFormat(Format))
{
os::Printer::log("IImage::copyToWithAlpha method doesn't work with compressed images.", ELL_WARNING);
return;
}
eBlitter op = combineAlpha ? BLITTER_TEXTURE_COMBINE_ALPHA :
color.color == 0xFFFFFFFF ? BLITTER_TEXTURE_ALPHA_BLEND : BLITTER_TEXTURE_ALPHA_COLOR_BLEND;
Blit(op,target, clipRect, &pos, this, &sourceRect, color.color);
}
//! copies this surface into another, if it has the exact same size and format.
bool CImage::copyToNoScaling(void *target, u32 width, u32 height, ECOLOR_FORMAT format, u32 pitch) const
{
if (IImage::isCompressedFormat(Format))
{
os::Printer::log("IImage::copyToNoScaling method doesn't work with compressed images.", ELL_WARNING);
return false;
}
if (!target || !width || !height || !Size.Width || !Size.Height)
return false;
const u32 bpp=getBitsPerPixelFromFormat(format)/8;
if (0==pitch)
pitch = width*bpp;
if (!(Format==format && Size.Width==width && Size.Height==height))
return false;
if (pitch==Pitch)
{
memcpy(target, Data, (size_t)height*pitch);
}
else
{
u8* tgtpos = (u8*) target;
u8* srcpos = Data;
const u32 bwidth = width*bpp;
const u32 rest = pitch-bwidth;
for (u32 y=0; y<height; ++y)
{
// copy scanline
memcpy(tgtpos, srcpos, bwidth);
// clear pitch
memset(tgtpos+bwidth, 0, rest);
tgtpos += pitch;
srcpos += Pitch;
}
}
return true;
}
//! copies this surface into another, scaling it to the target image size
// note: this is very very slow.
void CImage::copyToScaling(void* target, u32 width, u32 height, ECOLOR_FORMAT format, u32 pitch)
{
if (IImage::isCompressedFormat(Format))
{
os::Printer::log("IImage::copyToScaling method doesn't work with compressed images.", ELL_WARNING);
return;
}
if (!target || !width || !height || !Size.Width || !Size.Height)
return;
const u32 bpp=getBitsPerPixelFromFormat(format)/8;
if (0==pitch)
pitch = width*bpp;
if (copyToNoScaling(target, width, height, format, pitch))
return;
// NOTE: Scaling is coded to keep the border pixels intact.
// Alternatively we could for example work with first pixel being taken at half step-size.
// Then we have one more step here and it would be:
// sourceXStep = (f32)(Size.Width-1) / (f32)(width);
// And sx would start at 0.5f + sourceXStep / 2.f;
// Similar for y.
// As scaling is done without any antialiasing it doesn't matter too much which outermost pixels we use and keeping
// border pixels intact is probably mostly better (with AA the other solution would be more correct).
// This is however unnecessary (and unexpected) for scaling to integer multiples, so don't do it there.
f32 sourceXStep, sourceYStep;
f32 sourceXStart = 0.f, sourceYStart = 0.f;
if (width % Size.Width == 0)
sourceXStep = (f32)(Size.Width) / (f32)(width);
else
{
sourceXStep = width > 1 ? (f32)(Size.Width-1) / (f32)(width-1) : 0.f;
sourceXStart = 0.5f; // for rounding to nearest pixel
}
if (height % Size.Height == 0)
sourceYStep = (f32)(Size.Height) / (f32)(height);
else
{
sourceYStep = height > 1 ? (f32)(Size.Height-1) / (f32)(height-1) : 0.f;
sourceYStart = 0.5f; // for rounding to nearest pixel
}
s32 yval=0, syval=0;
f32 sy = sourceYStart;
for (u32 y=0; y<height; ++y)
{
f32 sx = sourceXStart;
for (u32 x=0; x<width; ++x)
{
CColorConverter::convert_viaFormat(Data+ syval + ((s32)sx)*BytesPerPixel, Format, 1, ((u8*)target)+ yval + (x*bpp), format);
sx+=sourceXStep;
}
sy+=sourceYStep;
syval=(s32)(sy)*Pitch;
yval+=pitch;
}
}
//! copies this surface into another, scaling it to the target image size
// note: this is very very slow.
void CImage::copyToScaling(IImage* target)
{
if (IImage::isCompressedFormat(Format))
{
os::Printer::log("IImage::copyToScaling method doesn't work with compressed images.", ELL_WARNING);
return;
}
if (!target)
return;
const core::dimension2d<u32>& targetSize = target->getDimension();
if (targetSize==Size)
{
copyTo(target);
return;
}
copyToScaling(target->getData(), targetSize.Width, targetSize.Height, target->getColorFormat());
}
//! copies this surface into another, scaling it to fit it.
void CImage::copyToScalingBoxFilter(IImage* target, s32 bias, bool blend)
{
if (IImage::isCompressedFormat(Format))
{
os::Printer::log("IImage::copyToScalingBoxFilter method doesn't work with compressed images.", ELL_WARNING);
return;
}
const core::dimension2d<u32> destSize = target->getDimension();
const f32 sourceXStep = (f32) Size.Width / (f32) destSize.Width;
const f32 sourceYStep = (f32) Size.Height / (f32) destSize.Height;
s32 fx = core::ceil32( sourceXStep );
s32 fy = core::ceil32( sourceYStep );
f32 sx;
f32 sy;
sy = 0.f;
for ( u32 y = 0; y != destSize.Height; ++y )
{
sx = 0.f;
for ( u32 x = 0; x != destSize.Width; ++x )
{
target->setPixel( x, y,
getPixelBox( core::floor32(sx), core::floor32(sy), fx, fy, bias ), blend );
sx += sourceXStep;
}
sy += sourceYStep;
}
}
//! fills the surface with given color
void CImage::fill(const SColor &color)
{
if (IImage::isCompressedFormat(Format))
{
os::Printer::log("IImage::fill method doesn't work with compressed images.", ELL_WARNING);
return;
}
u32 c;
switch ( Format )
{
case ECF_A1R5G5B5:
c = color.toA1R5G5B5();
c |= c << 16;
break;
case ECF_R5G6B5:
c = video::A8R8G8B8toR5G6B5( color.color );
c |= c << 16;
break;
case ECF_A8R8G8B8:
c = color.color;
break;
case ECF_R8G8B8:
{
u8 rgb[3];
CColorConverter::convert_A8R8G8B8toR8G8B8(&color, 1, rgb);
const u32 size = getImageDataSizeInBytes();
for (u32 i=0; i<size; i+=3)
{
memcpy(Data+i, rgb, 3);
}
return;
}
break;
default:
// TODO: Handle other formats
return;
}
memset32( Data, c, getImageDataSizeInBytes() );
}
//! get a filtered pixel
inline SColor CImage::getPixelBox( s32 x, s32 y, s32 fx, s32 fy, s32 bias ) const
{
if (IImage::isCompressedFormat(Format))
{
os::Printer::log("IImage::getPixelBox method doesn't work with compressed images.", ELL_WARNING);
return SColor(0);
}
SColor c;
s32 a = 0, r = 0, g = 0, b = 0;
for ( s32 dx = 0; dx != fx; ++dx )
{
for ( s32 dy = 0; dy != fy; ++dy )
{
c = getPixel( core::s32_min ( x + dx, Size.Width - 1 ) ,
core::s32_min ( y + dy, Size.Height - 1 )
);
a += c.getAlpha();
r += c.getRed();
g += c.getGreen();
b += c.getBlue();
}
}
s32 sdiv = s32_log2_s32(fx * fy);
a = core::s32_clamp( ( a >> sdiv ) + bias, 0, 255 );
r = core::s32_clamp( ( r >> sdiv ) + bias, 0, 255 );
g = core::s32_clamp( ( g >> sdiv ) + bias, 0, 255 );
b = core::s32_clamp( ( b >> sdiv ) + bias, 0, 255 );
c.set( a, r, g, b );
return c;
}
} // end namespace video
} // end namespace irr

View File

@ -1,75 +1,75 @@
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#pragma once
#include "IImage.h"
#include "rect.h"
namespace irr
{
namespace video
{
//! check sanity of image dimensions to prevent issues later, for use by CImageLoaders
inline bool checkImageDimensions(u32 width, u32 height)
{
// 4 * 23000 * 23000 is just under S32_MAX
return width <= 23000 && height <= 23000;
}
//! IImage implementation with a lot of special image operations for
//! 16 bit A1R5G5B5/32 Bit A8R8G8B8 images, which are used by the SoftwareDevice.
class CImage : public IImage
{
public:
//! constructor from raw image data
/** \param useForeignMemory: If true, the image will use the data pointer
directly and own it from now on, which means it will also try to delete [] the
data when the image will be destructed. If false, the memory will by copied. */
CImage(ECOLOR_FORMAT format, const core::dimension2d<u32>& size, void* data,
bool ownForeignMemory = true, bool deleteMemory = true);
//! constructor for empty image
CImage(ECOLOR_FORMAT format, const core::dimension2d<u32>& size);
//! returns a pixel
SColor getPixel(u32 x, u32 y) const override;
//! sets a pixel
void setPixel(u32 x, u32 y, const SColor &color, bool blend = false ) override;
//! copies this surface into another, if it has the exact same size and format.
bool copyToNoScaling(void *target, u32 width, u32 height, ECOLOR_FORMAT format, u32 pitch=0) const override;
//! copies this surface into another, scaling it to fit.
void copyToScaling(void* target, u32 width, u32 height, ECOLOR_FORMAT format, u32 pitch=0) override;
//! copies this surface into another, scaling it to fit.
void copyToScaling(IImage* target) override;
//! copies this surface into another
void copyTo(IImage* target, const core::position2d<s32>& pos=core::position2d<s32>(0,0)) override;
//! copies this surface into another
void copyTo(IImage* target, const core::position2d<s32>& pos, const core::rect<s32>& sourceRect, const core::rect<s32>* clipRect=0) override;
//! copies this surface into another, using the alpha mask, an cliprect and a color to add with
virtual void copyToWithAlpha(IImage* target, const core::position2d<s32>& pos,
const core::rect<s32>& sourceRect, const SColor &color,
const core::rect<s32>* clipRect = 0, bool combineAlpha=false) override;
//! copies this surface into another, scaling it to fit, applying a box filter
void copyToScalingBoxFilter(IImage* target, s32 bias = 0, bool blend = false) override;
//! fills the surface with given color
void fill(const SColor &color) override;
private:
inline SColor getPixelBox ( s32 x, s32 y, s32 fx, s32 fy, s32 bias ) const;
};
} // end namespace video
} // end namespace irr
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#pragma once
#include "IImage.h"
#include "rect.h"
namespace irr
{
namespace video
{
//! check sanity of image dimensions to prevent issues later, for use by CImageLoaders
inline bool checkImageDimensions(u32 width, u32 height)
{
// 4 * 23000 * 23000 is just under S32_MAX
return width <= 23000 && height <= 23000;
}
//! IImage implementation with a lot of special image operations for
//! 16 bit A1R5G5B5/32 Bit A8R8G8B8 images, which are used by the SoftwareDevice.
class CImage : public IImage
{
public:
//! constructor from raw image data
/** \param useForeignMemory: If true, the image will use the data pointer
directly and own it from now on, which means it will also try to delete [] the
data when the image will be destructed. If false, the memory will by copied. */
CImage(ECOLOR_FORMAT format, const core::dimension2d<u32>& size, void* data,
bool ownForeignMemory = true, bool deleteMemory = true);
//! constructor for empty image
CImage(ECOLOR_FORMAT format, const core::dimension2d<u32>& size);
//! returns a pixel
SColor getPixel(u32 x, u32 y) const override;
//! sets a pixel
void setPixel(u32 x, u32 y, const SColor &color, bool blend = false ) override;
//! copies this surface into another, if it has the exact same size and format.
bool copyToNoScaling(void *target, u32 width, u32 height, ECOLOR_FORMAT format, u32 pitch=0) const override;
//! copies this surface into another, scaling it to fit.
void copyToScaling(void* target, u32 width, u32 height, ECOLOR_FORMAT format, u32 pitch=0) override;
//! copies this surface into another, scaling it to fit.
void copyToScaling(IImage* target) override;
//! copies this surface into another
void copyTo(IImage* target, const core::position2d<s32>& pos=core::position2d<s32>(0,0)) override;
//! copies this surface into another
void copyTo(IImage* target, const core::position2d<s32>& pos, const core::rect<s32>& sourceRect, const core::rect<s32>* clipRect=0) override;
//! copies this surface into another, using the alpha mask, an cliprect and a color to add with
virtual void copyToWithAlpha(IImage* target, const core::position2d<s32>& pos,
const core::rect<s32>& sourceRect, const SColor &color,
const core::rect<s32>* clipRect = 0, bool combineAlpha=false) override;
//! copies this surface into another, scaling it to fit, applying a box filter
void copyToScalingBoxFilter(IImage* target, s32 bias = 0, bool blend = false) override;
//! fills the surface with given color
void fill(const SColor &color) override;
private:
inline SColor getPixelBox ( s32 x, s32 y, s32 fx, s32 fy, s32 bias ) const;
};
} // end namespace video
} // end namespace irr

View File

@ -1,416 +1,416 @@
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#include "CImageLoaderBMP.h"
#include "IReadFile.h"
#include "SColor.h"
#include "CColorConverter.h"
#include "CImage.h"
#include "os.h"
#include "irrString.h"
namespace irr
{
namespace video
{
//! constructor
CImageLoaderBMP::CImageLoaderBMP()
{
#ifdef _DEBUG
setDebugName("CImageLoaderBMP");
#endif
}
//! returns true if the file maybe is able to be loaded by this class
//! based on the file extension (e.g. ".tga")
bool CImageLoaderBMP::isALoadableFileExtension(const io::path& filename) const
{
return core::hasFileExtension ( filename, "bmp" );
}
//! returns true if the file maybe is able to be loaded by this class
bool CImageLoaderBMP::isALoadableFileFormat(io::IReadFile* file) const
{
u16 headerID;
file->read(&headerID, sizeof(u16));
#ifdef __BIG_ENDIAN__
headerID = os::Byteswap::byteswap(headerID);
#endif
return headerID == 0x4d42;
}
// UB-safe overflow check
static inline bool overflowCheck(const void *base, size_t offset, const void *end)
{
auto baseI = reinterpret_cast<uintptr_t>(base),
endI = reinterpret_cast<uintptr_t>(end);
return baseI > endI || offset >= (endI - baseI);
}
// check whether &p[0] to &p[_off - 1] can be accessed
#define CHECKP(_off) if ((_off) < 0 || overflowCheck(p, _off, pEnd)) goto exit
// same for d
#define CHECKD(_off) if ((_off) < 0 || overflowCheck(d, _off, destEnd)) goto exit
void CImageLoaderBMP::decompress8BitRLE(u8*& bmpData, s32 size, s32 width, s32 height, s32 pitch) const
{
u8* p = bmpData;
const u8* pEnd = bmpData + size;
u8* newBmp = new u8[(width+pitch)*height];
u8* d = newBmp;
const u8* destEnd = newBmp + (width+pitch)*height;
s32 line = 0;
while (p < pEnd && d < destEnd)
{
if (*p == 0)
{
++p; CHECKP(1);
switch(*p)
{
case 0: // end of line
++p;
++line;
d = newBmp + (line*(width+pitch));
break;
case 1: // end of bmp
goto exit;
case 2:
++p; CHECKP(2);
d += (u8)*p; ++p; // delta
d += ((u8)*p)*(width+pitch); ++p;
break;
default:
{
// absolute mode
s32 count = (u8)*p; ++p;
s32 readAdditional = ((2-(count%2))%2);
CHECKP(count); CHECKD(count);
for (s32 i=0; i<count; ++i)
{
*d = *p;
++p;
++d;
}
CHECKP(readAdditional);
for (s32 i=0; i<readAdditional; ++i)
++p;
}
}
}
else
{
s32 count = (u8)*p; ++p;
CHECKP(1);
u8 color = *p; ++p;
CHECKD(count);
for (s32 i=0; i<count; ++i)
{
*d = color;
++d;
}
}
}
exit:
delete [] bmpData;
bmpData = newBmp;
}
// how many bytes will be touched given the current state of decompress4BitRLE
static inline u32 shiftedCount(s32 count, s32 shift)
{
_IRR_DEBUG_BREAK_IF(count < 0)
u32 ret = count / 2;
if (shift == 0 || count % 2 == 1)
++ret;
return ret;
}
void CImageLoaderBMP::decompress4BitRLE(u8*& bmpData, s32 size, s32 width, s32 height, s32 pitch) const
{
const s32 lineWidth = (width+1)/2+pitch;
u8* p = bmpData;
const u8* pEnd = bmpData + size;
u8* newBmp = new u8[lineWidth*height];
u8* d = newBmp;
const u8* destEnd = newBmp + lineWidth*height;
s32 line = 0;
s32 shift = 4;
while (p < pEnd && d < destEnd)
{
if (*p == 0)
{
++p; CHECKP(1);
switch(*p)
{
case 0: // end of line
++p;
++line;
d = newBmp + (line*lineWidth);
shift = 4;
break;
case 1: // end of bmp
goto exit;
case 2:
{
++p; CHECKP(2);
s32 x = (u8)*p; ++p;
s32 y = (u8)*p; ++p;
d += x/2 + y*lineWidth;
shift = x%2==0 ? 4 : 0;
}
break;
default:
{
// absolute mode
s32 count = (u8)*p; ++p;
s32 readAdditional = ((2-((count)%2))%2);
s32 readShift = 4;
CHECKP(shiftedCount(count, readShift));
CHECKD(shiftedCount(count, shift));
for (s32 i=0; i<count; ++i)
{
s32 color = (((u8)*p) >> readShift) & 0x0f;
readShift -= 4;
if (readShift < 0)
{
++*p; // <- bug?
readShift = 4;
}
u8 mask = 0x0f << shift;
*d = (*d & (~mask)) | ((color << shift) & mask);
shift -= 4;
if (shift < 0)
{
shift = 4;
++d;
}
}
CHECKP(readAdditional);
for (s32 i=0; i<readAdditional; ++i)
++p;
}
}
}
else
{
s32 count = (u8)*p; ++p;
CHECKP(1);
s32 color1 = (u8)*p; color1 = color1 & 0x0f;
s32 color2 = (u8)*p; color2 = (color2 >> 4) & 0x0f;
++p;
CHECKD(shiftedCount(count, shift));
for (s32 i=0; i<count; ++i)
{
u8 mask = 0x0f << shift;
u8 toSet = (shift==0 ? color1 : color2) << shift;
*d = (*d & (~mask)) | (toSet & mask);
shift -= 4;
if (shift < 0)
{
shift = 4;
++d;
}
}
}
}
exit:
delete [] bmpData;
bmpData = newBmp;
}
#undef CHECKOFF
#undef CHECKP
#undef CHECKD
//! creates a surface from the file
IImage* CImageLoaderBMP::loadImage(io::IReadFile* file) const
{
SBMPHeader header;
file->read(&header, sizeof(header));
#ifdef __BIG_ENDIAN__
header.Id = os::Byteswap::byteswap(header.Id);
header.FileSize = os::Byteswap::byteswap(header.FileSize);
header.BitmapDataOffset = os::Byteswap::byteswap(header.BitmapDataOffset);
header.BitmapHeaderSize = os::Byteswap::byteswap(header.BitmapHeaderSize);
header.Width = os::Byteswap::byteswap(header.Width);
header.Height = os::Byteswap::byteswap(header.Height);
header.Planes = os::Byteswap::byteswap(header.Planes);
header.BPP = os::Byteswap::byteswap(header.BPP);
header.Compression = os::Byteswap::byteswap(header.Compression);
header.BitmapDataSize = os::Byteswap::byteswap(header.BitmapDataSize);
header.PixelPerMeterX = os::Byteswap::byteswap(header.PixelPerMeterX);
header.PixelPerMeterY = os::Byteswap::byteswap(header.PixelPerMeterY);
header.Colors = os::Byteswap::byteswap(header.Colors);
header.ImportantColors = os::Byteswap::byteswap(header.ImportantColors);
#endif
s32 pitch = 0;
//! return if the header is false
if (header.Id != 0x4d42)
return 0;
if (header.Compression > 2) // we'll only handle RLE-Compression
{
os::Printer::log("Compression mode not supported.", ELL_ERROR);
return 0;
}
if (header.BPP > 32 || !checkImageDimensions(header.Width, header.Height))
{
os::Printer::log("Rejecting BMP with unreasonable size or BPP.", ELL_ERROR);
return 0;
}
// adjust bitmap data size to dword boundary
header.BitmapDataSize += (4-(header.BitmapDataSize%4))%4;
// read palette
long pos = file->getPos();
constexpr s32 paletteAllocSize = 256;
s32 paletteSize = (header.BitmapDataOffset - pos) / 4;
paletteSize = core::clamp(paletteSize, 0, paletteAllocSize);
s32* paletteData = 0;
if (paletteSize)
{
// always allocate an 8-bit palette to ensure enough space
paletteData = new s32[paletteAllocSize];
memset(paletteData, 0, paletteAllocSize * sizeof(s32));
file->read(paletteData, paletteSize * sizeof(s32));
#ifdef __BIG_ENDIAN__
for (s32 i=0; i<paletteSize; ++i)
paletteData[i] = os::Byteswap::byteswap(paletteData[i]);
#endif
}
// read image data
if (!header.BitmapDataSize)
{
// okay, lets guess the size
// some tools simply don't set it
header.BitmapDataSize = static_cast<u32>(file->getSize()) - header.BitmapDataOffset;
}
file->seek(header.BitmapDataOffset);
s32 widthInBytes;
{
f32 t = (header.Width) * (header.BPP / 8.0f);
widthInBytes = (s32)t;
t -= widthInBytes;
if (t!=0.0f)
++widthInBytes;
}
const s32 lineSize = widthInBytes + ((4-(widthInBytes%4)))%4;
pitch = lineSize - widthInBytes;
u8* bmpData = new u8[header.BitmapDataSize];
file->read(bmpData, header.BitmapDataSize);
// decompress data if needed
switch(header.Compression)
{
case 1: // 8 bit rle
decompress8BitRLE(bmpData, header.BitmapDataSize, header.Width, header.Height, pitch);
header.BitmapDataSize = (header.Width + pitch) * header.Height;
break;
case 2: // 4 bit rle
decompress4BitRLE(bmpData, header.BitmapDataSize, header.Width, header.Height, pitch);
header.BitmapDataSize = ((header.Width+1)/2 + pitch) * header.Height;
break;
}
if (header.BitmapDataSize < lineSize * header.Height)
{
os::Printer::log("Bitmap data is cut off.", ELL_ERROR);
delete [] paletteData;
delete [] bmpData;
return 0;
}
// create surface
core::dimension2d<u32> dim;
dim.Width = header.Width;
dim.Height = header.Height;
IImage* image = 0;
switch(header.BPP)
{
case 1:
image = new CImage(ECF_A1R5G5B5, dim);
if (image)
CColorConverter::convert1BitTo16Bit(bmpData, (s16*)image->getData(), header.Width, header.Height, pitch, true);
break;
case 4:
image = new CImage(ECF_A1R5G5B5, dim);
if (image)
CColorConverter::convert4BitTo16Bit(bmpData, (s16*)image->getData(), header.Width, header.Height, paletteData, pitch, true);
break;
case 8:
image = new CImage(ECF_A1R5G5B5, dim);
if (image)
CColorConverter::convert8BitTo16Bit(bmpData, (s16*)image->getData(), header.Width, header.Height, paletteData, pitch, true);
break;
case 16:
image = new CImage(ECF_A1R5G5B5, dim);
if (image)
CColorConverter::convert16BitTo16Bit((s16*)bmpData, (s16*)image->getData(), header.Width, header.Height, pitch, true);
break;
case 24:
image = new CImage(ECF_R8G8B8, dim);
if (image)
CColorConverter::convert24BitTo24Bit(bmpData, (u8*)image->getData(), header.Width, header.Height, pitch, true, true);
break;
case 32: // thx to Reinhard Ostermeier
image = new CImage(ECF_A8R8G8B8, dim);
if (image)
CColorConverter::convert32BitTo32Bit((s32*)bmpData, (s32*)image->getData(), header.Width, header.Height, pitch, true);
break;
};
// clean up
delete [] paletteData;
delete [] bmpData;
return image;
}
//! creates a loader which is able to load windows bitmaps
IImageLoader* createImageLoaderBMP()
{
return new CImageLoaderBMP;
}
} // end namespace video
} // end namespace irr
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#include "CImageLoaderBMP.h"
#include "IReadFile.h"
#include "SColor.h"
#include "CColorConverter.h"
#include "CImage.h"
#include "os.h"
#include "irrString.h"
namespace irr
{
namespace video
{
//! constructor
CImageLoaderBMP::CImageLoaderBMP()
{
#ifdef _DEBUG
setDebugName("CImageLoaderBMP");
#endif
}
//! returns true if the file maybe is able to be loaded by this class
//! based on the file extension (e.g. ".tga")
bool CImageLoaderBMP::isALoadableFileExtension(const io::path& filename) const
{
return core::hasFileExtension ( filename, "bmp" );
}
//! returns true if the file maybe is able to be loaded by this class
bool CImageLoaderBMP::isALoadableFileFormat(io::IReadFile* file) const
{
u16 headerID;
file->read(&headerID, sizeof(u16));
#ifdef __BIG_ENDIAN__
headerID = os::Byteswap::byteswap(headerID);
#endif
return headerID == 0x4d42;
}
// UB-safe overflow check
static inline bool overflowCheck(const void *base, size_t offset, const void *end)
{
auto baseI = reinterpret_cast<uintptr_t>(base),
endI = reinterpret_cast<uintptr_t>(end);
return baseI > endI || offset >= (endI - baseI);
}
// check whether &p[0] to &p[_off - 1] can be accessed
#define CHECKP(_off) if ((_off) < 0 || overflowCheck(p, _off, pEnd)) goto exit
// same for d
#define CHECKD(_off) if ((_off) < 0 || overflowCheck(d, _off, destEnd)) goto exit
void CImageLoaderBMP::decompress8BitRLE(u8*& bmpData, s32 size, s32 width, s32 height, s32 pitch) const
{
u8* p = bmpData;
const u8* pEnd = bmpData + size;
u8* newBmp = new u8[(width+pitch)*height];
u8* d = newBmp;
const u8* destEnd = newBmp + (width+pitch)*height;
s32 line = 0;
while (p < pEnd && d < destEnd)
{
if (*p == 0)
{
++p; CHECKP(1);
switch(*p)
{
case 0: // end of line
++p;
++line;
d = newBmp + (line*(width+pitch));
break;
case 1: // end of bmp
goto exit;
case 2:
++p; CHECKP(2);
d += (u8)*p; ++p; // delta
d += ((u8)*p)*(width+pitch); ++p;
break;
default:
{
// absolute mode
s32 count = (u8)*p; ++p;
s32 readAdditional = ((2-(count%2))%2);
CHECKP(count); CHECKD(count);
for (s32 i=0; i<count; ++i)
{
*d = *p;
++p;
++d;
}
CHECKP(readAdditional);
for (s32 i=0; i<readAdditional; ++i)
++p;
}
}
}
else
{
s32 count = (u8)*p; ++p;
CHECKP(1);
u8 color = *p; ++p;
CHECKD(count);
for (s32 i=0; i<count; ++i)
{
*d = color;
++d;
}
}
}
exit:
delete [] bmpData;
bmpData = newBmp;
}
// how many bytes will be touched given the current state of decompress4BitRLE
static inline u32 shiftedCount(s32 count, s32 shift)
{
_IRR_DEBUG_BREAK_IF(count < 0)
u32 ret = count / 2;
if (shift == 0 || count % 2 == 1)
++ret;
return ret;
}
void CImageLoaderBMP::decompress4BitRLE(u8*& bmpData, s32 size, s32 width, s32 height, s32 pitch) const
{
const s32 lineWidth = (width+1)/2+pitch;
u8* p = bmpData;
const u8* pEnd = bmpData + size;
u8* newBmp = new u8[lineWidth*height];
u8* d = newBmp;
const u8* destEnd = newBmp + lineWidth*height;
s32 line = 0;
s32 shift = 4;
while (p < pEnd && d < destEnd)
{
if (*p == 0)
{
++p; CHECKP(1);
switch(*p)
{
case 0: // end of line
++p;
++line;
d = newBmp + (line*lineWidth);
shift = 4;
break;
case 1: // end of bmp
goto exit;
case 2:
{
++p; CHECKP(2);
s32 x = (u8)*p; ++p;
s32 y = (u8)*p; ++p;
d += x/2 + y*lineWidth;
shift = x%2==0 ? 4 : 0;
}
break;
default:
{
// absolute mode
s32 count = (u8)*p; ++p;
s32 readAdditional = ((2-((count)%2))%2);
s32 readShift = 4;
CHECKP(shiftedCount(count, readShift));
CHECKD(shiftedCount(count, shift));
for (s32 i=0; i<count; ++i)
{
s32 color = (((u8)*p) >> readShift) & 0x0f;
readShift -= 4;
if (readShift < 0)
{
++*p; // <- bug?
readShift = 4;
}
u8 mask = 0x0f << shift;
*d = (*d & (~mask)) | ((color << shift) & mask);
shift -= 4;
if (shift < 0)
{
shift = 4;
++d;
}
}
CHECKP(readAdditional);
for (s32 i=0; i<readAdditional; ++i)
++p;
}
}
}
else
{
s32 count = (u8)*p; ++p;
CHECKP(1);
s32 color1 = (u8)*p; color1 = color1 & 0x0f;
s32 color2 = (u8)*p; color2 = (color2 >> 4) & 0x0f;
++p;
CHECKD(shiftedCount(count, shift));
for (s32 i=0; i<count; ++i)
{
u8 mask = 0x0f << shift;
u8 toSet = (shift==0 ? color1 : color2) << shift;
*d = (*d & (~mask)) | (toSet & mask);
shift -= 4;
if (shift < 0)
{
shift = 4;
++d;
}
}
}
}
exit:
delete [] bmpData;
bmpData = newBmp;
}
#undef CHECKOFF
#undef CHECKP
#undef CHECKD
//! creates a surface from the file
IImage* CImageLoaderBMP::loadImage(io::IReadFile* file) const
{
SBMPHeader header;
file->read(&header, sizeof(header));
#ifdef __BIG_ENDIAN__
header.Id = os::Byteswap::byteswap(header.Id);
header.FileSize = os::Byteswap::byteswap(header.FileSize);
header.BitmapDataOffset = os::Byteswap::byteswap(header.BitmapDataOffset);
header.BitmapHeaderSize = os::Byteswap::byteswap(header.BitmapHeaderSize);
header.Width = os::Byteswap::byteswap(header.Width);
header.Height = os::Byteswap::byteswap(header.Height);
header.Planes = os::Byteswap::byteswap(header.Planes);
header.BPP = os::Byteswap::byteswap(header.BPP);
header.Compression = os::Byteswap::byteswap(header.Compression);
header.BitmapDataSize = os::Byteswap::byteswap(header.BitmapDataSize);
header.PixelPerMeterX = os::Byteswap::byteswap(header.PixelPerMeterX);
header.PixelPerMeterY = os::Byteswap::byteswap(header.PixelPerMeterY);
header.Colors = os::Byteswap::byteswap(header.Colors);
header.ImportantColors = os::Byteswap::byteswap(header.ImportantColors);
#endif
s32 pitch = 0;
//! return if the header is false
if (header.Id != 0x4d42)
return 0;
if (header.Compression > 2) // we'll only handle RLE-Compression
{
os::Printer::log("Compression mode not supported.", ELL_ERROR);
return 0;
}
if (header.BPP > 32 || !checkImageDimensions(header.Width, header.Height))
{
os::Printer::log("Rejecting BMP with unreasonable size or BPP.", ELL_ERROR);
return 0;
}
// adjust bitmap data size to dword boundary
header.BitmapDataSize += (4-(header.BitmapDataSize%4))%4;
// read palette
long pos = file->getPos();
constexpr s32 paletteAllocSize = 256;
s32 paletteSize = (header.BitmapDataOffset - pos) / 4;
paletteSize = core::clamp(paletteSize, 0, paletteAllocSize);
s32* paletteData = 0;
if (paletteSize)
{
// always allocate an 8-bit palette to ensure enough space
paletteData = new s32[paletteAllocSize];
memset(paletteData, 0, paletteAllocSize * sizeof(s32));
file->read(paletteData, paletteSize * sizeof(s32));
#ifdef __BIG_ENDIAN__
for (s32 i=0; i<paletteSize; ++i)
paletteData[i] = os::Byteswap::byteswap(paletteData[i]);
#endif
}
// read image data
if (!header.BitmapDataSize)
{
// okay, lets guess the size
// some tools simply don't set it
header.BitmapDataSize = static_cast<u32>(file->getSize()) - header.BitmapDataOffset;
}
file->seek(header.BitmapDataOffset);
s32 widthInBytes;
{
f32 t = (header.Width) * (header.BPP / 8.0f);
widthInBytes = (s32)t;
t -= widthInBytes;
if (t!=0.0f)
++widthInBytes;
}
const s32 lineSize = widthInBytes + ((4-(widthInBytes%4)))%4;
pitch = lineSize - widthInBytes;
u8* bmpData = new u8[header.BitmapDataSize];
file->read(bmpData, header.BitmapDataSize);
// decompress data if needed
switch(header.Compression)
{
case 1: // 8 bit rle
decompress8BitRLE(bmpData, header.BitmapDataSize, header.Width, header.Height, pitch);
header.BitmapDataSize = (header.Width + pitch) * header.Height;
break;
case 2: // 4 bit rle
decompress4BitRLE(bmpData, header.BitmapDataSize, header.Width, header.Height, pitch);
header.BitmapDataSize = ((header.Width+1)/2 + pitch) * header.Height;
break;
}
if (header.BitmapDataSize < lineSize * header.Height)
{
os::Printer::log("Bitmap data is cut off.", ELL_ERROR);
delete [] paletteData;
delete [] bmpData;
return 0;
}
// create surface
core::dimension2d<u32> dim;
dim.Width = header.Width;
dim.Height = header.Height;
IImage* image = 0;
switch(header.BPP)
{
case 1:
image = new CImage(ECF_A1R5G5B5, dim);
if (image)
CColorConverter::convert1BitTo16Bit(bmpData, (s16*)image->getData(), header.Width, header.Height, pitch, true);
break;
case 4:
image = new CImage(ECF_A1R5G5B5, dim);
if (image)
CColorConverter::convert4BitTo16Bit(bmpData, (s16*)image->getData(), header.Width, header.Height, paletteData, pitch, true);
break;
case 8:
image = new CImage(ECF_A1R5G5B5, dim);
if (image)
CColorConverter::convert8BitTo16Bit(bmpData, (s16*)image->getData(), header.Width, header.Height, paletteData, pitch, true);
break;
case 16:
image = new CImage(ECF_A1R5G5B5, dim);
if (image)
CColorConverter::convert16BitTo16Bit((s16*)bmpData, (s16*)image->getData(), header.Width, header.Height, pitch, true);
break;
case 24:
image = new CImage(ECF_R8G8B8, dim);
if (image)
CColorConverter::convert24BitTo24Bit(bmpData, (u8*)image->getData(), header.Width, header.Height, pitch, true, true);
break;
case 32: // thx to Reinhard Ostermeier
image = new CImage(ECF_A8R8G8B8, dim);
if (image)
CColorConverter::convert32BitTo32Bit((s32*)bmpData, (s32*)image->getData(), header.Width, header.Height, pitch, true);
break;
};
// clean up
delete [] paletteData;
delete [] bmpData;
return image;
}
//! creates a loader which is able to load windows bitmaps
IImageLoader* createImageLoaderBMP()
{
return new CImageLoaderBMP;
}
} // end namespace video
} // end namespace irr

View File

@ -1,85 +1,85 @@
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#pragma once
#include "IImageLoader.h"
namespace irr
{
namespace video
{
// byte-align structures
#include "irrpack.h"
struct SBMPHeader
{
u16 Id; // BM - Windows 3.1x, 95, NT, 98, 2000, ME, XP
// BA - OS/2 Bitmap Array
// CI - OS/2 Color Icon
// CP - OS/2 Color Pointer
// IC - OS/2 Icon
// PT - OS/2 Pointer
u32 FileSize;
u32 Reserved;
u32 BitmapDataOffset;
u32 BitmapHeaderSize; // should be 28h for windows bitmaps or
// 0Ch for OS/2 1.x or F0h for OS/2 2.x
u32 Width;
u32 Height;
u16 Planes;
u16 BPP; // 1: Monochrome bitmap
// 4: 16 color bitmap
// 8: 256 color bitmap
// 16: 16bit (high color) bitmap
// 24: 24bit (true color) bitmap
// 32: 32bit (true color) bitmap
u32 Compression; // 0: none (Also identified by BI_RGB)
// 1: RLE 8-bit / pixel (Also identified by BI_RLE4)
// 2: RLE 4-bit / pixel (Also identified by BI_RLE8)
// 3: Bitfields (Also identified by BI_BITFIELDS)
u32 BitmapDataSize; // Size of the bitmap data in bytes. This number must be rounded to the next 4 byte boundary.
u32 PixelPerMeterX;
u32 PixelPerMeterY;
u32 Colors;
u32 ImportantColors;
} PACK_STRUCT;
// Default alignment
#include "irrunpack.h"
/*!
Surface Loader for Windows bitmaps
*/
class CImageLoaderBMP : public IImageLoader
{
public:
//! constructor
CImageLoaderBMP();
//! returns true if the file maybe is able to be loaded by this class
//! based on the file extension (e.g. ".tga")
bool isALoadableFileExtension(const io::path& filename) const override;
//! returns true if the file maybe is able to be loaded by this class
bool isALoadableFileFormat(io::IReadFile* file) const override;
//! creates a surface from the file
IImage* loadImage(io::IReadFile* file) const override;
private:
void decompress8BitRLE(u8*& BmpData, s32 size, s32 width, s32 height, s32 pitch) const;
void decompress4BitRLE(u8*& BmpData, s32 size, s32 width, s32 height, s32 pitch) const;
};
} // end namespace video
} // end namespace irr
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#pragma once
#include "IImageLoader.h"
namespace irr
{
namespace video
{
// byte-align structures
#include "irrpack.h"
struct SBMPHeader
{
u16 Id; // BM - Windows 3.1x, 95, NT, 98, 2000, ME, XP
// BA - OS/2 Bitmap Array
// CI - OS/2 Color Icon
// CP - OS/2 Color Pointer
// IC - OS/2 Icon
// PT - OS/2 Pointer
u32 FileSize;
u32 Reserved;
u32 BitmapDataOffset;
u32 BitmapHeaderSize; // should be 28h for windows bitmaps or
// 0Ch for OS/2 1.x or F0h for OS/2 2.x
u32 Width;
u32 Height;
u16 Planes;
u16 BPP; // 1: Monochrome bitmap
// 4: 16 color bitmap
// 8: 256 color bitmap
// 16: 16bit (high color) bitmap
// 24: 24bit (true color) bitmap
// 32: 32bit (true color) bitmap
u32 Compression; // 0: none (Also identified by BI_RGB)
// 1: RLE 8-bit / pixel (Also identified by BI_RLE4)
// 2: RLE 4-bit / pixel (Also identified by BI_RLE8)
// 3: Bitfields (Also identified by BI_BITFIELDS)
u32 BitmapDataSize; // Size of the bitmap data in bytes. This number must be rounded to the next 4 byte boundary.
u32 PixelPerMeterX;
u32 PixelPerMeterY;
u32 Colors;
u32 ImportantColors;
} PACK_STRUCT;
// Default alignment
#include "irrunpack.h"
/*!
Surface Loader for Windows bitmaps
*/
class CImageLoaderBMP : public IImageLoader
{
public:
//! constructor
CImageLoaderBMP();
//! returns true if the file maybe is able to be loaded by this class
//! based on the file extension (e.g. ".tga")
bool isALoadableFileExtension(const io::path& filename) const override;
//! returns true if the file maybe is able to be loaded by this class
bool isALoadableFileFormat(io::IReadFile* file) const override;
//! creates a surface from the file
IImage* loadImage(io::IReadFile* file) const override;
private:
void decompress8BitRLE(u8*& BmpData, s32 size, s32 width, s32 height, s32 pitch) const;
void decompress4BitRLE(u8*& BmpData, s32 size, s32 width, s32 height, s32 pitch) const;
};
} // end namespace video
} // end namespace irr

View File

@ -1,286 +1,286 @@
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#include "CImageLoaderJPG.h"
#include "IReadFile.h"
#include "CImage.h"
#include "os.h"
#include "irrString.h"
namespace irr
{
namespace video
{
//! constructor
CImageLoaderJPG::CImageLoaderJPG()
{
#ifdef _DEBUG
setDebugName("CImageLoaderJPG");
#endif
}
//! destructor
CImageLoaderJPG::~CImageLoaderJPG()
{
}
//! returns true if the file maybe is able to be loaded by this class
//! based on the file extension (e.g. ".tga")
bool CImageLoaderJPG::isALoadableFileExtension(const io::path& filename) const
{
return core::hasFileExtension ( filename, "jpg", "jpeg" );
}
// struct for handling jpeg errors
struct irr_jpeg_error_mgr
{
// public jpeg error fields
struct jpeg_error_mgr pub;
// for longjmp, to return to caller on a fatal error
jmp_buf setjmp_buffer;
// for having access to the filename when printing the error messages
core::stringc* filename;
};
void CImageLoaderJPG::init_source (j_decompress_ptr cinfo)
{
// DO NOTHING
}
boolean CImageLoaderJPG::fill_input_buffer (j_decompress_ptr cinfo)
{
// DO NOTHING
return TRUE;
}
void CImageLoaderJPG::skip_input_data (j_decompress_ptr cinfo, long count)
{
jpeg_source_mgr * src = cinfo->src;
if(count > 0)
{
src->bytes_in_buffer -= count;
src->next_input_byte += count;
}
}
void CImageLoaderJPG::term_source (j_decompress_ptr cinfo)
{
// DO NOTHING
}
void CImageLoaderJPG::error_exit (j_common_ptr cinfo)
{
// unfortunately we need to use a goto rather than throwing an exception
// as gcc crashes under linux crashes when using throw from within
// extern c code
// Always display the message
(*cinfo->err->output_message) (cinfo);
// cinfo->err really points to a irr_error_mgr struct
irr_jpeg_error_mgr *myerr = (irr_jpeg_error_mgr*) cinfo->err;
longjmp(myerr->setjmp_buffer, 1);
}
void CImageLoaderJPG::output_message(j_common_ptr cinfo)
{
// display the error message.
c8 temp1[JMSG_LENGTH_MAX];
(*cinfo->err->format_message)(cinfo, temp1);
core::stringc errMsg("JPEG FATAL ERROR in ");
irr_jpeg_error_mgr* myerr = (irr_jpeg_error_mgr*)cinfo->err;
errMsg += *myerr->filename;
os::Printer::log(errMsg.c_str(),temp1, ELL_ERROR);
}
//! returns true if the file maybe is able to be loaded by this class
bool CImageLoaderJPG::isALoadableFileFormat(io::IReadFile* file) const
{
if (!(file && file->seek(0)))
return false;
unsigned char header[3];
size_t headerLen = file->read(header, sizeof(header));
return headerLen >= 3 && !memcmp(header, "\xFF\xD8\xFF", 3);
}
//! creates a surface from the file
IImage* CImageLoaderJPG::loadImage(io::IReadFile* file) const
{
if (!file)
return 0;
core::stringc filename = file->getFileName();
u8 **rowPtr=0;
u8* input = new u8[file->getSize()];
file->read(input, file->getSize());
// allocate and initialize JPEG decompression object
struct jpeg_decompress_struct cinfo;
struct irr_jpeg_error_mgr jerr;
//We have to set up the error handler first, in case the initialization
//step fails. (Unlikely, but it could happen if you are out of memory.)
//This routine fills in the contents of struct jerr, and returns jerr's
//address which we place into the link field in cinfo.
cinfo.err = jpeg_std_error(&jerr.pub);
cinfo.err->error_exit = error_exit;
cinfo.err->output_message = output_message;
jerr.filename = &filename;
// compatibility fudge:
// we need to use setjmp/longjmp for error handling as gcc-linux
// crashes when throwing within external c code
if (setjmp(jerr.setjmp_buffer))
{
// If we get here, the JPEG code has signaled an error.
// We need to clean up the JPEG object and return.
jpeg_destroy_decompress(&cinfo);
delete [] input;
delete [] rowPtr;
// return null pointer
return 0;
}
// Now we can initialize the JPEG decompression object.
jpeg_create_decompress(&cinfo);
// specify data source
jpeg_source_mgr jsrc;
// Set up data pointer
jsrc.bytes_in_buffer = file->getSize();
jsrc.next_input_byte = (JOCTET*)input;
cinfo.src = &jsrc;
jsrc.init_source = init_source;
jsrc.fill_input_buffer = fill_input_buffer;
jsrc.skip_input_data = skip_input_data;
jsrc.resync_to_restart = jpeg_resync_to_restart;
jsrc.term_source = term_source;
// Decodes JPG input from whatever source
// Does everything AFTER jpeg_create_decompress
// and BEFORE jpeg_destroy_decompress
// Caller is responsible for arranging these + setting up cinfo
// read file parameters with jpeg_read_header()
jpeg_read_header(&cinfo, TRUE);
bool useCMYK=false;
if (cinfo.jpeg_color_space==JCS_CMYK)
{
cinfo.out_color_space=JCS_CMYK;
cinfo.out_color_components=4;
useCMYK=true;
}
else
{
cinfo.out_color_space=JCS_RGB;
cinfo.out_color_components=3;
}
cinfo.output_gamma=2.2;
cinfo.do_fancy_upsampling=FALSE;
// reject unreasonable sizes
if (!checkImageDimensions(cinfo.image_width, cinfo.image_height))
longjmp(jerr.setjmp_buffer, 1);
// Start decompressor
jpeg_start_decompress(&cinfo);
// Get image data
u32 rowspan = cinfo.image_width * cinfo.out_color_components;
u32 width = cinfo.image_width;
u32 height = cinfo.image_height;
// Allocate memory for buffer
u8* output = new u8[rowspan * height];
// Here we use the library's state variable cinfo.output_scanline as the
// loop counter, so that we don't have to keep track ourselves.
// Create array of row pointers for lib
rowPtr = new u8* [height];
for( u32 i = 0; i < height; i++ )
rowPtr[i] = &output[ i * rowspan ];
u32 rowsRead = 0;
while( cinfo.output_scanline < cinfo.output_height )
rowsRead += jpeg_read_scanlines( &cinfo, &rowPtr[rowsRead], cinfo.output_height - rowsRead );
delete [] rowPtr;
// Finish decompression
jpeg_finish_decompress(&cinfo);
// Release JPEG decompression object
// This is an important step since it will release a good deal of memory.
jpeg_destroy_decompress(&cinfo);
// convert image
IImage* image = 0;
if (useCMYK)
{
image = new CImage(ECF_R8G8B8,
core::dimension2d<u32>(width, height));
const u32 size = 3*width*height;
u8* data = (u8*)image->getData();
if (data)
{
for (u32 i=0,j=0; i<size; i+=3, j+=4)
{
// Also works without K, but has more contrast with K multiplied in
// data[i+0] = output[j+2];
// data[i+1] = output[j+1];
// data[i+2] = output[j+0];
data[i+0] = (char)(output[j+2]*(output[j+3]/255.f));
data[i+1] = (char)(output[j+1]*(output[j+3]/255.f));
data[i+2] = (char)(output[j+0]*(output[j+3]/255.f));
}
}
delete [] output;
}
else
image = new CImage(ECF_R8G8B8,
core::dimension2d<u32>(width, height), output);
delete [] input;
return image;
}
//! creates a loader which is able to load jpeg images
IImageLoader* createImageLoaderJPG()
{
return new CImageLoaderJPG();
}
} // end namespace video
} // end namespace irr
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#include "CImageLoaderJPG.h"
#include "IReadFile.h"
#include "CImage.h"
#include "os.h"
#include "irrString.h"
namespace irr
{
namespace video
{
//! constructor
CImageLoaderJPG::CImageLoaderJPG()
{
#ifdef _DEBUG
setDebugName("CImageLoaderJPG");
#endif
}
//! destructor
CImageLoaderJPG::~CImageLoaderJPG()
{
}
//! returns true if the file maybe is able to be loaded by this class
//! based on the file extension (e.g. ".tga")
bool CImageLoaderJPG::isALoadableFileExtension(const io::path& filename) const
{
return core::hasFileExtension ( filename, "jpg", "jpeg" );
}
// struct for handling jpeg errors
struct irr_jpeg_error_mgr
{
// public jpeg error fields
struct jpeg_error_mgr pub;
// for longjmp, to return to caller on a fatal error
jmp_buf setjmp_buffer;
// for having access to the filename when printing the error messages
core::stringc* filename;
};
void CImageLoaderJPG::init_source (j_decompress_ptr cinfo)
{
// DO NOTHING
}
boolean CImageLoaderJPG::fill_input_buffer (j_decompress_ptr cinfo)
{
// DO NOTHING
return TRUE;
}
void CImageLoaderJPG::skip_input_data (j_decompress_ptr cinfo, long count)
{
jpeg_source_mgr * src = cinfo->src;
if(count > 0)
{
src->bytes_in_buffer -= count;
src->next_input_byte += count;
}
}
void CImageLoaderJPG::term_source (j_decompress_ptr cinfo)
{
// DO NOTHING
}
void CImageLoaderJPG::error_exit (j_common_ptr cinfo)
{
// unfortunately we need to use a goto rather than throwing an exception
// as gcc crashes under linux crashes when using throw from within
// extern c code
// Always display the message
(*cinfo->err->output_message) (cinfo);
// cinfo->err really points to a irr_error_mgr struct
irr_jpeg_error_mgr *myerr = (irr_jpeg_error_mgr*) cinfo->err;
longjmp(myerr->setjmp_buffer, 1);
}
void CImageLoaderJPG::output_message(j_common_ptr cinfo)
{
// display the error message.
c8 temp1[JMSG_LENGTH_MAX];
(*cinfo->err->format_message)(cinfo, temp1);
core::stringc errMsg("JPEG FATAL ERROR in ");
irr_jpeg_error_mgr* myerr = (irr_jpeg_error_mgr*)cinfo->err;
errMsg += *myerr->filename;
os::Printer::log(errMsg.c_str(),temp1, ELL_ERROR);
}
//! returns true if the file maybe is able to be loaded by this class
bool CImageLoaderJPG::isALoadableFileFormat(io::IReadFile* file) const
{
if (!(file && file->seek(0)))
return false;
unsigned char header[3];
size_t headerLen = file->read(header, sizeof(header));
return headerLen >= 3 && !memcmp(header, "\xFF\xD8\xFF", 3);
}
//! creates a surface from the file
IImage* CImageLoaderJPG::loadImage(io::IReadFile* file) const
{
if (!file)
return 0;
core::stringc filename = file->getFileName();
u8 **rowPtr=0;
u8* input = new u8[file->getSize()];
file->read(input, file->getSize());
// allocate and initialize JPEG decompression object
struct jpeg_decompress_struct cinfo;
struct irr_jpeg_error_mgr jerr;
//We have to set up the error handler first, in case the initialization
//step fails. (Unlikely, but it could happen if you are out of memory.)
//This routine fills in the contents of struct jerr, and returns jerr's
//address which we place into the link field in cinfo.
cinfo.err = jpeg_std_error(&jerr.pub);
cinfo.err->error_exit = error_exit;
cinfo.err->output_message = output_message;
jerr.filename = &filename;
// compatibility fudge:
// we need to use setjmp/longjmp for error handling as gcc-linux
// crashes when throwing within external c code
if (setjmp(jerr.setjmp_buffer))
{
// If we get here, the JPEG code has signaled an error.
// We need to clean up the JPEG object and return.
jpeg_destroy_decompress(&cinfo);
delete [] input;
delete [] rowPtr;
// return null pointer
return 0;
}
// Now we can initialize the JPEG decompression object.
jpeg_create_decompress(&cinfo);
// specify data source
jpeg_source_mgr jsrc;
// Set up data pointer
jsrc.bytes_in_buffer = file->getSize();
jsrc.next_input_byte = (JOCTET*)input;
cinfo.src = &jsrc;
jsrc.init_source = init_source;
jsrc.fill_input_buffer = fill_input_buffer;
jsrc.skip_input_data = skip_input_data;
jsrc.resync_to_restart = jpeg_resync_to_restart;
jsrc.term_source = term_source;
// Decodes JPG input from whatever source
// Does everything AFTER jpeg_create_decompress
// and BEFORE jpeg_destroy_decompress
// Caller is responsible for arranging these + setting up cinfo
// read file parameters with jpeg_read_header()
jpeg_read_header(&cinfo, TRUE);
bool useCMYK=false;
if (cinfo.jpeg_color_space==JCS_CMYK)
{
cinfo.out_color_space=JCS_CMYK;
cinfo.out_color_components=4;
useCMYK=true;
}
else
{
cinfo.out_color_space=JCS_RGB;
cinfo.out_color_components=3;
}
cinfo.output_gamma=2.2;
cinfo.do_fancy_upsampling=FALSE;
// reject unreasonable sizes
if (!checkImageDimensions(cinfo.image_width, cinfo.image_height))
longjmp(jerr.setjmp_buffer, 1);
// Start decompressor
jpeg_start_decompress(&cinfo);
// Get image data
u32 rowspan = cinfo.image_width * cinfo.out_color_components;
u32 width = cinfo.image_width;
u32 height = cinfo.image_height;
// Allocate memory for buffer
u8* output = new u8[rowspan * height];
// Here we use the library's state variable cinfo.output_scanline as the
// loop counter, so that we don't have to keep track ourselves.
// Create array of row pointers for lib
rowPtr = new u8* [height];
for( u32 i = 0; i < height; i++ )
rowPtr[i] = &output[ i * rowspan ];
u32 rowsRead = 0;
while( cinfo.output_scanline < cinfo.output_height )
rowsRead += jpeg_read_scanlines( &cinfo, &rowPtr[rowsRead], cinfo.output_height - rowsRead );
delete [] rowPtr;
// Finish decompression
jpeg_finish_decompress(&cinfo);
// Release JPEG decompression object
// This is an important step since it will release a good deal of memory.
jpeg_destroy_decompress(&cinfo);
// convert image
IImage* image = 0;
if (useCMYK)
{
image = new CImage(ECF_R8G8B8,
core::dimension2d<u32>(width, height));
const u32 size = 3*width*height;
u8* data = (u8*)image->getData();
if (data)
{
for (u32 i=0,j=0; i<size; i+=3, j+=4)
{
// Also works without K, but has more contrast with K multiplied in
// data[i+0] = output[j+2];
// data[i+1] = output[j+1];
// data[i+2] = output[j+0];
data[i+0] = (char)(output[j+2]*(output[j+3]/255.f));
data[i+1] = (char)(output[j+1]*(output[j+3]/255.f));
data[i+2] = (char)(output[j+0]*(output[j+3]/255.f));
}
}
delete [] output;
}
else
image = new CImage(ECF_R8G8B8,
core::dimension2d<u32>(width, height), output);
delete [] input;
return image;
}
//! creates a loader which is able to load jpeg images
IImageLoader* createImageLoaderJPG()
{
return new CImageLoaderJPG();
}
} // end namespace video
} // end namespace irr

View File

@ -1,91 +1,91 @@
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#pragma once
#include "IImageLoader.h"
#include <stdio.h> // required for jpeglib.h
#include <jpeglib.h> // use system lib
#include <setjmp.h>
namespace irr
{
namespace video
{
//! Surface Loader for JPG images
class CImageLoaderJPG : public IImageLoader
{
public:
//! constructor
CImageLoaderJPG();
//! destructor
virtual ~CImageLoaderJPG();
//! returns true if the file maybe is able to be loaded by this class
//! based on the file extension (e.g. ".tga")
bool isALoadableFileExtension(const io::path& filename) const override;
//! returns true if the file maybe is able to be loaded by this class
bool isALoadableFileFormat(io::IReadFile* file) const override;
//! creates a surface from the file
IImage* loadImage(io::IReadFile* file) const override;
private:
// several methods used via function pointers by jpeglib
/* Receives control for a fatal error. Information sufficient to
generate the error message has been stored in cinfo->err; call
output_message to display it. Control must NOT return to the caller;
generally this routine will exit() or longjmp() somewhere.
Typically you would override this routine to get rid of the exit()
default behavior. Note that if you continue processing, you should
clean up the JPEG object with jpeg_abort() or jpeg_destroy().
*/
static void error_exit (j_common_ptr cinfo);
/* output error messages via Irrlicht logger. */
static void output_message(j_common_ptr cinfo);
/* Initialize source. This is called by jpeg_read_header() before any
data is actually read. Unlike init_destination(), it may leave
bytes_in_buffer set to 0 (in which case a fill_input_buffer() call
will occur immediately). */
static void init_source (j_decompress_ptr cinfo);
/* This is called whenever bytes_in_buffer has reached zero and more
data is wanted. In typical applications, it should read fresh data
into the buffer (ignoring the current state of next_input_byte and
bytes_in_buffer), reset the pointer & count to the start of the
buffer, and return TRUE indicating that the buffer has been reloaded.
It is not necessary to fill the buffer entirely, only to obtain at
least one more byte. bytes_in_buffer MUST be set to a positive value
if TRUE is returned. A FALSE return should only be used when I/O
suspension is desired (this mode is discussed in the next section). */
static boolean fill_input_buffer (j_decompress_ptr cinfo);
/* Skip num_bytes worth of data. The buffer pointer and count should
be advanced over num_bytes input bytes, refilling the buffer as
needed. This is used to skip over a potentially large amount of
uninteresting data (such as an APPn marker). In some applications
it may be possible to optimize away the reading of the skipped data,
but it's not clear that being smart is worth much trouble; large
skips are uncommon. bytes_in_buffer may be zero on return.
A zero or negative skip count should be treated as a no-op. */
static void skip_input_data (j_decompress_ptr cinfo, long num_bytes);
/* Terminate source --- called by jpeg_finish_decompress() after all
data has been read. Often a no-op. */
static void term_source (j_decompress_ptr cinfo);
};
} // end namespace video
} // end namespace irr
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#pragma once
#include "IImageLoader.h"
#include <stdio.h> // required for jpeglib.h
#include <jpeglib.h> // use system lib
#include <setjmp.h>
namespace irr
{
namespace video
{
//! Surface Loader for JPG images
class CImageLoaderJPG : public IImageLoader
{
public:
//! constructor
CImageLoaderJPG();
//! destructor
virtual ~CImageLoaderJPG();
//! returns true if the file maybe is able to be loaded by this class
//! based on the file extension (e.g. ".tga")
bool isALoadableFileExtension(const io::path& filename) const override;
//! returns true if the file maybe is able to be loaded by this class
bool isALoadableFileFormat(io::IReadFile* file) const override;
//! creates a surface from the file
IImage* loadImage(io::IReadFile* file) const override;
private:
// several methods used via function pointers by jpeglib
/* Receives control for a fatal error. Information sufficient to
generate the error message has been stored in cinfo->err; call
output_message to display it. Control must NOT return to the caller;
generally this routine will exit() or longjmp() somewhere.
Typically you would override this routine to get rid of the exit()
default behavior. Note that if you continue processing, you should
clean up the JPEG object with jpeg_abort() or jpeg_destroy().
*/
static void error_exit (j_common_ptr cinfo);
/* output error messages via Irrlicht logger. */
static void output_message(j_common_ptr cinfo);
/* Initialize source. This is called by jpeg_read_header() before any
data is actually read. Unlike init_destination(), it may leave
bytes_in_buffer set to 0 (in which case a fill_input_buffer() call
will occur immediately). */
static void init_source (j_decompress_ptr cinfo);
/* This is called whenever bytes_in_buffer has reached zero and more
data is wanted. In typical applications, it should read fresh data
into the buffer (ignoring the current state of next_input_byte and
bytes_in_buffer), reset the pointer & count to the start of the
buffer, and return TRUE indicating that the buffer has been reloaded.
It is not necessary to fill the buffer entirely, only to obtain at
least one more byte. bytes_in_buffer MUST be set to a positive value
if TRUE is returned. A FALSE return should only be used when I/O
suspension is desired (this mode is discussed in the next section). */
static boolean fill_input_buffer (j_decompress_ptr cinfo);
/* Skip num_bytes worth of data. The buffer pointer and count should
be advanced over num_bytes input bytes, refilling the buffer as
needed. This is used to skip over a potentially large amount of
uninteresting data (such as an APPn marker). In some applications
it may be possible to optimize away the reading of the skipped data,
but it's not clear that being smart is worth much trouble; large
skips are uncommon. bytes_in_buffer may be zero on return.
A zero or negative skip count should be treated as a no-op. */
static void skip_input_data (j_decompress_ptr cinfo, long num_bytes);
/* Terminate source --- called by jpeg_finish_decompress() after all
data has been read. Often a no-op. */
static void term_source (j_decompress_ptr cinfo);
};
} // end namespace video
} // end namespace irr

View File

@ -1,265 +1,265 @@
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#include "CImageLoaderPNG.h"
#include <png.h> // use system lib png
#include "CImage.h"
#include "CReadFile.h"
#include "os.h"
namespace irr
{
namespace video
{
// PNG function for error handling
static void png_cpexcept_error(png_structp png_ptr, png_const_charp msg)
{
os::Printer::log("PNG fatal error", msg, ELL_ERROR);
longjmp(png_jmpbuf(png_ptr), 1);
}
// PNG function for warning handling
static void png_cpexcept_warn(png_structp png_ptr, png_const_charp msg)
{
os::Printer::log("PNG warning", msg, ELL_WARNING);
}
// PNG function for file reading
void PNGAPI user_read_data_fcn(png_structp png_ptr, png_bytep data, png_size_t length)
{
png_size_t check;
// changed by zola {
io::IReadFile* file=(io::IReadFile*)png_get_io_ptr(png_ptr);
check=(png_size_t) file->read((void*)data, length);
// }
if (check != length)
png_error(png_ptr, "Read Error");
}
//! returns true if the file maybe is able to be loaded by this class
//! based on the file extension (e.g. ".tga")
bool CImageLoaderPng::isALoadableFileExtension(const io::path& filename) const
{
return core::hasFileExtension ( filename, "png" );
}
//! returns true if the file maybe is able to be loaded by this class
bool CImageLoaderPng::isALoadableFileFormat(io::IReadFile* file) const
{
if (!file)
return false;
png_byte buffer[8];
// Read the first few bytes of the PNG file
if (file->read(buffer, 8) != 8)
return false;
// Check if it really is a PNG file
return !png_sig_cmp(buffer, 0, 8);
}
// load in the image data
IImage* CImageLoaderPng::loadImage(io::IReadFile* file) const
{
if (!file)
return 0;
//Used to point to image rows
u8** RowPointers = 0;
png_byte buffer[8];
// Read the first few bytes of the PNG file
if( file->read(buffer, 8) != 8 )
{
os::Printer::log("LOAD PNG: can't read file (filesize < 8)", file->getFileName(), ELL_ERROR);
return 0;
}
// Check if it really is a PNG file
if( png_sig_cmp(buffer, 0, 8) )
{
os::Printer::log("LOAD PNG: not really a png (wrong signature)", file->getFileName(), ELL_ERROR);
return 0;
}
// Allocate the png read struct
png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,
NULL, (png_error_ptr)png_cpexcept_error, (png_error_ptr)png_cpexcept_warn);
if (!png_ptr)
{
os::Printer::log("LOAD PNG: Internal PNG create read struct failure", file->getFileName(), ELL_ERROR);
return 0;
}
// Allocate the png info struct
png_infop info_ptr = png_create_info_struct(png_ptr);
if (!info_ptr)
{
os::Printer::log("LOAD PNG: Internal PNG create info struct failure", file->getFileName(), ELL_ERROR);
png_destroy_read_struct(&png_ptr, NULL, NULL);
return 0;
}
// for proper error handling
if (setjmp(png_jmpbuf(png_ptr)))
{
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
delete [] RowPointers;
return 0;
}
// changed by zola so we don't need to have public FILE pointers
png_set_read_fn(png_ptr, file, user_read_data_fcn);
png_set_sig_bytes(png_ptr, 8); // Tell png that we read the signature
png_read_info(png_ptr, info_ptr); // Read the info section of the png file
u32 Width;
u32 Height;
s32 BitDepth;
s32 ColorType;
{
// Use temporary variables to avoid passing cast pointers
png_uint_32 w,h;
// Extract info
png_get_IHDR(png_ptr, info_ptr,
&w, &h,
&BitDepth, &ColorType, NULL, NULL, NULL);
Width=w;
Height=h;
}
if (!checkImageDimensions(Width, Height))
png_cpexcept_error(png_ptr, "Unreasonable size");
// Convert palette color to true color
if (ColorType==PNG_COLOR_TYPE_PALETTE)
png_set_palette_to_rgb(png_ptr);
// Convert low bit colors to 8 bit colors
if (BitDepth < 8)
{
if (ColorType==PNG_COLOR_TYPE_GRAY || ColorType==PNG_COLOR_TYPE_GRAY_ALPHA)
png_set_expand_gray_1_2_4_to_8(png_ptr);
else
png_set_packing(png_ptr);
}
if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))
png_set_tRNS_to_alpha(png_ptr);
// Convert high bit colors to 8 bit colors
if (BitDepth == 16)
png_set_strip_16(png_ptr);
// Convert gray color to true color
if (ColorType==PNG_COLOR_TYPE_GRAY || ColorType==PNG_COLOR_TYPE_GRAY_ALPHA)
png_set_gray_to_rgb(png_ptr);
int intent;
const double screen_gamma = 2.2;
if (png_get_sRGB(png_ptr, info_ptr, &intent))
png_set_gamma(png_ptr, screen_gamma, 0.45455);
else
{
double image_gamma;
if (png_get_gAMA(png_ptr, info_ptr, &image_gamma))
png_set_gamma(png_ptr, screen_gamma, image_gamma);
else
png_set_gamma(png_ptr, screen_gamma, 0.45455);
}
// Update the changes in between, as we need to get the new color type
// for proper processing of the RGBA type
png_read_update_info(png_ptr, info_ptr);
{
// Use temporary variables to avoid passing cast pointers
png_uint_32 w,h;
// Extract info
png_get_IHDR(png_ptr, info_ptr,
&w, &h,
&BitDepth, &ColorType, NULL, NULL, NULL);
Width=w;
Height=h;
}
// Convert RGBA to BGRA
if (ColorType==PNG_COLOR_TYPE_RGB_ALPHA)
{
#ifdef __BIG_ENDIAN__
png_set_swap_alpha(png_ptr);
#else
png_set_bgr(png_ptr);
#endif
}
// Create the image structure to be filled by png data
video::IImage* image = 0;
if (ColorType==PNG_COLOR_TYPE_RGB_ALPHA)
image = new CImage(ECF_A8R8G8B8, core::dimension2d<u32>(Width, Height));
else
image = new CImage(ECF_R8G8B8, core::dimension2d<u32>(Width, Height));
if (!image)
{
os::Printer::log("LOAD PNG: Internal PNG create image struct failure", file->getFileName(), ELL_ERROR);
png_destroy_read_struct(&png_ptr, NULL, NULL);
return 0;
}
// Create array of pointers to rows in image data
RowPointers = new png_bytep[Height];
if (!RowPointers)
{
os::Printer::log("LOAD PNG: Internal PNG create row pointers failure", file->getFileName(), ELL_ERROR);
png_destroy_read_struct(&png_ptr, NULL, NULL);
delete image;
return 0;
}
// Fill array of pointers to rows in image data
unsigned char* data = (unsigned char*)image->getData();
for (u32 i=0; i<Height; ++i)
{
RowPointers[i]=data;
data += image->getPitch();
}
// for proper error handling
if (setjmp(png_jmpbuf(png_ptr)))
{
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
delete [] RowPointers;
delete image;
return 0;
}
// Read data using the library function that handles all transformations including interlacing
png_read_image(png_ptr, RowPointers);
png_read_end(png_ptr, NULL);
delete [] RowPointers;
png_destroy_read_struct(&png_ptr,&info_ptr, 0); // Clean up memory
return image;
}
IImageLoader* createImageLoaderPNG()
{
return new CImageLoaderPng();
}
}// end namespace irr
}//end namespace video
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#include "CImageLoaderPNG.h"
#include <png.h> // use system lib png
#include "CImage.h"
#include "CReadFile.h"
#include "os.h"
namespace irr
{
namespace video
{
// PNG function for error handling
static void png_cpexcept_error(png_structp png_ptr, png_const_charp msg)
{
os::Printer::log("PNG fatal error", msg, ELL_ERROR);
longjmp(png_jmpbuf(png_ptr), 1);
}
// PNG function for warning handling
static void png_cpexcept_warn(png_structp png_ptr, png_const_charp msg)
{
os::Printer::log("PNG warning", msg, ELL_WARNING);
}
// PNG function for file reading
void PNGAPI user_read_data_fcn(png_structp png_ptr, png_bytep data, png_size_t length)
{
png_size_t check;
// changed by zola {
io::IReadFile* file=(io::IReadFile*)png_get_io_ptr(png_ptr);
check=(png_size_t) file->read((void*)data, length);
// }
if (check != length)
png_error(png_ptr, "Read Error");
}
//! returns true if the file maybe is able to be loaded by this class
//! based on the file extension (e.g. ".tga")
bool CImageLoaderPng::isALoadableFileExtension(const io::path& filename) const
{
return core::hasFileExtension ( filename, "png" );
}
//! returns true if the file maybe is able to be loaded by this class
bool CImageLoaderPng::isALoadableFileFormat(io::IReadFile* file) const
{
if (!file)
return false;
png_byte buffer[8];
// Read the first few bytes of the PNG file
if (file->read(buffer, 8) != 8)
return false;
// Check if it really is a PNG file
return !png_sig_cmp(buffer, 0, 8);
}
// load in the image data
IImage* CImageLoaderPng::loadImage(io::IReadFile* file) const
{
if (!file)
return 0;
//Used to point to image rows
u8** RowPointers = 0;
png_byte buffer[8];
// Read the first few bytes of the PNG file
if( file->read(buffer, 8) != 8 )
{
os::Printer::log("LOAD PNG: can't read file (filesize < 8)", file->getFileName(), ELL_ERROR);
return 0;
}
// Check if it really is a PNG file
if( png_sig_cmp(buffer, 0, 8) )
{
os::Printer::log("LOAD PNG: not really a png (wrong signature)", file->getFileName(), ELL_ERROR);
return 0;
}
// Allocate the png read struct
png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,
NULL, (png_error_ptr)png_cpexcept_error, (png_error_ptr)png_cpexcept_warn);
if (!png_ptr)
{
os::Printer::log("LOAD PNG: Internal PNG create read struct failure", file->getFileName(), ELL_ERROR);
return 0;
}
// Allocate the png info struct
png_infop info_ptr = png_create_info_struct(png_ptr);
if (!info_ptr)
{
os::Printer::log("LOAD PNG: Internal PNG create info struct failure", file->getFileName(), ELL_ERROR);
png_destroy_read_struct(&png_ptr, NULL, NULL);
return 0;
}
// for proper error handling
if (setjmp(png_jmpbuf(png_ptr)))
{
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
delete [] RowPointers;
return 0;
}
// changed by zola so we don't need to have public FILE pointers
png_set_read_fn(png_ptr, file, user_read_data_fcn);
png_set_sig_bytes(png_ptr, 8); // Tell png that we read the signature
png_read_info(png_ptr, info_ptr); // Read the info section of the png file
u32 Width;
u32 Height;
s32 BitDepth;
s32 ColorType;
{
// Use temporary variables to avoid passing cast pointers
png_uint_32 w,h;
// Extract info
png_get_IHDR(png_ptr, info_ptr,
&w, &h,
&BitDepth, &ColorType, NULL, NULL, NULL);
Width=w;
Height=h;
}
if (!checkImageDimensions(Width, Height))
png_cpexcept_error(png_ptr, "Unreasonable size");
// Convert palette color to true color
if (ColorType==PNG_COLOR_TYPE_PALETTE)
png_set_palette_to_rgb(png_ptr);
// Convert low bit colors to 8 bit colors
if (BitDepth < 8)
{
if (ColorType==PNG_COLOR_TYPE_GRAY || ColorType==PNG_COLOR_TYPE_GRAY_ALPHA)
png_set_expand_gray_1_2_4_to_8(png_ptr);
else
png_set_packing(png_ptr);
}
if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))
png_set_tRNS_to_alpha(png_ptr);
// Convert high bit colors to 8 bit colors
if (BitDepth == 16)
png_set_strip_16(png_ptr);
// Convert gray color to true color
if (ColorType==PNG_COLOR_TYPE_GRAY || ColorType==PNG_COLOR_TYPE_GRAY_ALPHA)
png_set_gray_to_rgb(png_ptr);
int intent;
const double screen_gamma = 2.2;
if (png_get_sRGB(png_ptr, info_ptr, &intent))
png_set_gamma(png_ptr, screen_gamma, 0.45455);
else
{
double image_gamma;
if (png_get_gAMA(png_ptr, info_ptr, &image_gamma))
png_set_gamma(png_ptr, screen_gamma, image_gamma);
else
png_set_gamma(png_ptr, screen_gamma, 0.45455);
}
// Update the changes in between, as we need to get the new color type
// for proper processing of the RGBA type
png_read_update_info(png_ptr, info_ptr);
{
// Use temporary variables to avoid passing cast pointers
png_uint_32 w,h;
// Extract info
png_get_IHDR(png_ptr, info_ptr,
&w, &h,
&BitDepth, &ColorType, NULL, NULL, NULL);
Width=w;
Height=h;
}
// Convert RGBA to BGRA
if (ColorType==PNG_COLOR_TYPE_RGB_ALPHA)
{
#ifdef __BIG_ENDIAN__
png_set_swap_alpha(png_ptr);
#else
png_set_bgr(png_ptr);
#endif
}
// Create the image structure to be filled by png data
video::IImage* image = 0;
if (ColorType==PNG_COLOR_TYPE_RGB_ALPHA)
image = new CImage(ECF_A8R8G8B8, core::dimension2d<u32>(Width, Height));
else
image = new CImage(ECF_R8G8B8, core::dimension2d<u32>(Width, Height));
if (!image)
{
os::Printer::log("LOAD PNG: Internal PNG create image struct failure", file->getFileName(), ELL_ERROR);
png_destroy_read_struct(&png_ptr, NULL, NULL);
return 0;
}
// Create array of pointers to rows in image data
RowPointers = new png_bytep[Height];
if (!RowPointers)
{
os::Printer::log("LOAD PNG: Internal PNG create row pointers failure", file->getFileName(), ELL_ERROR);
png_destroy_read_struct(&png_ptr, NULL, NULL);
delete image;
return 0;
}
// Fill array of pointers to rows in image data
unsigned char* data = (unsigned char*)image->getData();
for (u32 i=0; i<Height; ++i)
{
RowPointers[i]=data;
data += image->getPitch();
}
// for proper error handling
if (setjmp(png_jmpbuf(png_ptr)))
{
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
delete [] RowPointers;
delete image;
return 0;
}
// Read data using the library function that handles all transformations including interlacing
png_read_image(png_ptr, RowPointers);
png_read_end(png_ptr, NULL);
delete [] RowPointers;
png_destroy_read_struct(&png_ptr,&info_ptr, 0); // Clean up memory
return image;
}
IImageLoader* createImageLoaderPNG()
{
return new CImageLoaderPng();
}
}// end namespace irr
}//end namespace video

View File

@ -1,36 +1,36 @@
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
// this file was created by rt (www.tomkorp.com), based on ttk's png-reader
// i wanted to be able to read in PNG images with irrlicht :)
// why? lossless compression with 8-bit alpha channel!
#pragma once
#include "IImageLoader.h"
namespace irr
{
namespace video
{
//! Surface Loader for PNG files
class CImageLoaderPng : public IImageLoader
{
public:
//! returns true if the file maybe is able to be loaded by this class
//! based on the file extension (e.g. ".png")
bool isALoadableFileExtension(const io::path& filename) const override;
//! returns true if the file maybe is able to be loaded by this class
bool isALoadableFileFormat(io::IReadFile* file) const override;
//! creates a surface from the file
IImage* loadImage(io::IReadFile* file) const override;
};
} // end namespace video
} // end namespace irr
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
// this file was created by rt (www.tomkorp.com), based on ttk's png-reader
// i wanted to be able to read in PNG images with irrlicht :)
// why? lossless compression with 8-bit alpha channel!
#pragma once
#include "IImageLoader.h"
namespace irr
{
namespace video
{
//! Surface Loader for PNG files
class CImageLoaderPng : public IImageLoader
{
public:
//! returns true if the file maybe is able to be loaded by this class
//! based on the file extension (e.g. ".png")
bool isALoadableFileExtension(const io::path& filename) const override;
//! returns true if the file maybe is able to be loaded by this class
bool isALoadableFileFormat(io::IReadFile* file) const override;
//! creates a surface from the file
IImage* loadImage(io::IReadFile* file) const override;
};
} // end namespace video
} // end namespace irr

View File

@ -1,238 +1,238 @@
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#include "CImageLoaderTGA.h"
#include "IReadFile.h"
#include "os.h"
#include "CColorConverter.h"
#include "CImage.h"
#include "irrString.h"
namespace irr
{
namespace video
{
//! returns true if the file maybe is able to be loaded by this class
//! based on the file extension (e.g. ".tga")
bool CImageLoaderTGA::isALoadableFileExtension(const io::path& filename) const
{
return core::hasFileExtension ( filename, "tga" );
}
//! loads a compressed tga.
u8 *CImageLoaderTGA::loadCompressedImage(io::IReadFile *file, const STGAHeader& header) const
{
// This was written and sent in by Jon Pry, thank you very much!
// I only changed the formatting a little bit.
s32 bytesPerPixel = header.PixelDepth/8;
s32 imageSize = header.ImageHeight * header.ImageWidth * bytesPerPixel;
u8* data = new u8[imageSize];
s32 currentByte = 0;
while(currentByte < imageSize)
{
u8 chunkheader = 0;
file->read(&chunkheader, sizeof(u8)); // Read The Chunk's Header
if(chunkheader < 128) // If The Chunk Is A 'RAW' Chunk
{
chunkheader++; // Add 1 To The Value To Get Total Number Of Raw Pixels
file->read(&data[currentByte], bytesPerPixel * chunkheader);
currentByte += bytesPerPixel * chunkheader;
}
else
{
// thnx to neojzs for some fixes with this code
// If It's An RLE Header
chunkheader -= 127; // Subtract 127 To Get Rid Of The ID Bit
s32 dataOffset = currentByte;
file->read(&data[dataOffset], bytesPerPixel);
currentByte += bytesPerPixel;
for(s32 counter = 1; counter < chunkheader; counter++)
{
for(s32 elementCounter=0; elementCounter < bytesPerPixel; elementCounter++)
data[currentByte + elementCounter] = data[dataOffset + elementCounter];
currentByte += bytesPerPixel;
}
}
}
return data;
}
//! returns true if the file maybe is able to be loaded by this class
bool CImageLoaderTGA::isALoadableFileFormat(io::IReadFile* file) const
{
if (!file)
return false;
STGAFooter footer;
memset(&footer, 0, sizeof(STGAFooter));
file->seek(file->getSize()-sizeof(STGAFooter));
file->read(&footer, sizeof(STGAFooter));
return (!strcmp(footer.Signature,"TRUEVISION-XFILE.")); // very old tgas are refused.
}
//! creates a surface from the file
IImage* CImageLoaderTGA::loadImage(io::IReadFile* file) const
{
STGAHeader header;
u32 *palette = 0;
file->read(&header, sizeof(STGAHeader));
#ifdef __BIG_ENDIAN__
header.ColorMapLength = os::Byteswap::byteswap(header.ColorMapLength);
header.ImageWidth = os::Byteswap::byteswap(header.ImageWidth);
header.ImageHeight = os::Byteswap::byteswap(header.ImageHeight);
#endif
if (!checkImageDimensions(header.ImageWidth, header.ImageHeight))
{
os::Printer::log("Image dimensions too large in file", file->getFileName(), ELL_ERROR);
return 0;
}
// skip image identification field
if (header.IdLength)
file->seek(header.IdLength, true);
if (header.ColorMapType)
{
// create 32 bit palette
palette = new u32[ header.ColorMapLength];
// read color map
u8 * colorMap = new u8[header.ColorMapEntrySize/8 * header.ColorMapLength];
file->read(colorMap,header.ColorMapEntrySize/8 * header.ColorMapLength);
// convert to 32-bit palette
switch ( header.ColorMapEntrySize )
{
case 16:
CColorConverter::convert_A1R5G5B5toA8R8G8B8(colorMap, header.ColorMapLength, palette);
break;
case 24:
CColorConverter::convert_B8G8R8toA8R8G8B8(colorMap, header.ColorMapLength, palette);
break;
case 32:
CColorConverter::convert_B8G8R8A8toA8R8G8B8(colorMap, header.ColorMapLength, palette);
break;
}
delete [] colorMap;
}
// read image
u8* data = 0;
if ( header.ImageType == 1 || // Uncompressed, color-mapped images.
header.ImageType == 2 || // Uncompressed, RGB images
header.ImageType == 3 // Uncompressed, black and white images
)
{
const s32 imageSize = header.ImageHeight * header.ImageWidth * header.PixelDepth/8;
data = new u8[imageSize];
file->read(data, imageSize);
}
else
if(header.ImageType == 10)
{
// Runlength encoded RGB images
data = loadCompressedImage(file, header);
}
else
{
os::Printer::log("Unsupported TGA file type", file->getFileName(), ELL_ERROR);
delete [] palette;
return 0;
}
IImage* image = 0;
switch(header.PixelDepth)
{
case 8:
{
if (header.ImageType==3) // grey image
{
image = new CImage(ECF_R8G8B8,
core::dimension2d<u32>(header.ImageWidth, header.ImageHeight));
if (image)
CColorConverter::convert8BitTo24Bit((u8*)data,
(u8*)image->getData(),
header.ImageWidth,header.ImageHeight,
0, 0, (header.ImageDescriptor&0x20)==0);
}
else
{
image = new CImage(ECF_A1R5G5B5,
core::dimension2d<u32>(header.ImageWidth, header.ImageHeight));
if (image)
CColorConverter::convert8BitTo16Bit((u8*)data,
(s16*)image->getData(),
header.ImageWidth,header.ImageHeight,
(s32*) palette, 0,
(header.ImageDescriptor&0x20)==0);
}
}
break;
case 16:
image = new CImage(ECF_A1R5G5B5,
core::dimension2d<u32>(header.ImageWidth, header.ImageHeight));
if (image)
CColorConverter::convert16BitTo16Bit((s16*)data,
(s16*)image->getData(), header.ImageWidth, header.ImageHeight, 0, (header.ImageDescriptor&0x20)==0);
break;
case 24:
image = new CImage(ECF_R8G8B8,
core::dimension2d<u32>(header.ImageWidth, header.ImageHeight));
if (image)
CColorConverter::convert24BitTo24Bit(
(u8*)data, (u8*)image->getData(), header.ImageWidth, header.ImageHeight, 0, (header.ImageDescriptor&0x20)==0, true);
break;
case 32:
image = new CImage(ECF_A8R8G8B8,
core::dimension2d<u32>(header.ImageWidth, header.ImageHeight));
if (image)
CColorConverter::convert32BitTo32Bit((s32*)data,
(s32*)image->getData(), header.ImageWidth, header.ImageHeight, 0, (header.ImageDescriptor&0x20)==0);
break;
default:
os::Printer::log("Unsupported TGA format", file->getFileName(), ELL_ERROR);
break;
}
delete [] data;
delete [] palette;
return image;
}
//! creates a loader which is able to load tgas
IImageLoader* createImageLoaderTGA()
{
return new CImageLoaderTGA();
}
} // end namespace video
} // end namespace irr
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#include "CImageLoaderTGA.h"
#include "IReadFile.h"
#include "os.h"
#include "CColorConverter.h"
#include "CImage.h"
#include "irrString.h"
namespace irr
{
namespace video
{
//! returns true if the file maybe is able to be loaded by this class
//! based on the file extension (e.g. ".tga")
bool CImageLoaderTGA::isALoadableFileExtension(const io::path& filename) const
{
return core::hasFileExtension ( filename, "tga" );
}
//! loads a compressed tga.
u8 *CImageLoaderTGA::loadCompressedImage(io::IReadFile *file, const STGAHeader& header) const
{
// This was written and sent in by Jon Pry, thank you very much!
// I only changed the formatting a little bit.
s32 bytesPerPixel = header.PixelDepth/8;
s32 imageSize = header.ImageHeight * header.ImageWidth * bytesPerPixel;
u8* data = new u8[imageSize];
s32 currentByte = 0;
while(currentByte < imageSize)
{
u8 chunkheader = 0;
file->read(&chunkheader, sizeof(u8)); // Read The Chunk's Header
if(chunkheader < 128) // If The Chunk Is A 'RAW' Chunk
{
chunkheader++; // Add 1 To The Value To Get Total Number Of Raw Pixels
file->read(&data[currentByte], bytesPerPixel * chunkheader);
currentByte += bytesPerPixel * chunkheader;
}
else
{
// thnx to neojzs for some fixes with this code
// If It's An RLE Header
chunkheader -= 127; // Subtract 127 To Get Rid Of The ID Bit
s32 dataOffset = currentByte;
file->read(&data[dataOffset], bytesPerPixel);
currentByte += bytesPerPixel;
for(s32 counter = 1; counter < chunkheader; counter++)
{
for(s32 elementCounter=0; elementCounter < bytesPerPixel; elementCounter++)
data[currentByte + elementCounter] = data[dataOffset + elementCounter];
currentByte += bytesPerPixel;
}
}
}
return data;
}
//! returns true if the file maybe is able to be loaded by this class
bool CImageLoaderTGA::isALoadableFileFormat(io::IReadFile* file) const
{
if (!file)
return false;
STGAFooter footer;
memset(&footer, 0, sizeof(STGAFooter));
file->seek(file->getSize()-sizeof(STGAFooter));
file->read(&footer, sizeof(STGAFooter));
return (!strcmp(footer.Signature,"TRUEVISION-XFILE.")); // very old tgas are refused.
}
//! creates a surface from the file
IImage* CImageLoaderTGA::loadImage(io::IReadFile* file) const
{
STGAHeader header;
u32 *palette = 0;
file->read(&header, sizeof(STGAHeader));
#ifdef __BIG_ENDIAN__
header.ColorMapLength = os::Byteswap::byteswap(header.ColorMapLength);
header.ImageWidth = os::Byteswap::byteswap(header.ImageWidth);
header.ImageHeight = os::Byteswap::byteswap(header.ImageHeight);
#endif
if (!checkImageDimensions(header.ImageWidth, header.ImageHeight))
{
os::Printer::log("Image dimensions too large in file", file->getFileName(), ELL_ERROR);
return 0;
}
// skip image identification field
if (header.IdLength)
file->seek(header.IdLength, true);
if (header.ColorMapType)
{
// create 32 bit palette
palette = new u32[ header.ColorMapLength];
// read color map
u8 * colorMap = new u8[header.ColorMapEntrySize/8 * header.ColorMapLength];
file->read(colorMap,header.ColorMapEntrySize/8 * header.ColorMapLength);
// convert to 32-bit palette
switch ( header.ColorMapEntrySize )
{
case 16:
CColorConverter::convert_A1R5G5B5toA8R8G8B8(colorMap, header.ColorMapLength, palette);
break;
case 24:
CColorConverter::convert_B8G8R8toA8R8G8B8(colorMap, header.ColorMapLength, palette);
break;
case 32:
CColorConverter::convert_B8G8R8A8toA8R8G8B8(colorMap, header.ColorMapLength, palette);
break;
}
delete [] colorMap;
}
// read image
u8* data = 0;
if ( header.ImageType == 1 || // Uncompressed, color-mapped images.
header.ImageType == 2 || // Uncompressed, RGB images
header.ImageType == 3 // Uncompressed, black and white images
)
{
const s32 imageSize = header.ImageHeight * header.ImageWidth * header.PixelDepth/8;
data = new u8[imageSize];
file->read(data, imageSize);
}
else
if(header.ImageType == 10)
{
// Runlength encoded RGB images
data = loadCompressedImage(file, header);
}
else
{
os::Printer::log("Unsupported TGA file type", file->getFileName(), ELL_ERROR);
delete [] palette;
return 0;
}
IImage* image = 0;
switch(header.PixelDepth)
{
case 8:
{
if (header.ImageType==3) // grey image
{
image = new CImage(ECF_R8G8B8,
core::dimension2d<u32>(header.ImageWidth, header.ImageHeight));
if (image)
CColorConverter::convert8BitTo24Bit((u8*)data,
(u8*)image->getData(),
header.ImageWidth,header.ImageHeight,
0, 0, (header.ImageDescriptor&0x20)==0);
}
else
{
image = new CImage(ECF_A1R5G5B5,
core::dimension2d<u32>(header.ImageWidth, header.ImageHeight));
if (image)
CColorConverter::convert8BitTo16Bit((u8*)data,
(s16*)image->getData(),
header.ImageWidth,header.ImageHeight,
(s32*) palette, 0,
(header.ImageDescriptor&0x20)==0);
}
}
break;
case 16:
image = new CImage(ECF_A1R5G5B5,
core::dimension2d<u32>(header.ImageWidth, header.ImageHeight));
if (image)
CColorConverter::convert16BitTo16Bit((s16*)data,
(s16*)image->getData(), header.ImageWidth, header.ImageHeight, 0, (header.ImageDescriptor&0x20)==0);
break;
case 24:
image = new CImage(ECF_R8G8B8,
core::dimension2d<u32>(header.ImageWidth, header.ImageHeight));
if (image)
CColorConverter::convert24BitTo24Bit(
(u8*)data, (u8*)image->getData(), header.ImageWidth, header.ImageHeight, 0, (header.ImageDescriptor&0x20)==0, true);
break;
case 32:
image = new CImage(ECF_A8R8G8B8,
core::dimension2d<u32>(header.ImageWidth, header.ImageHeight));
if (image)
CColorConverter::convert32BitTo32Bit((s32*)data,
(s32*)image->getData(), header.ImageWidth, header.ImageHeight, 0, (header.ImageDescriptor&0x20)==0);
break;
default:
os::Printer::log("Unsupported TGA format", file->getFileName(), ELL_ERROR);
break;
}
delete [] data;
delete [] palette;
return image;
}
//! creates a loader which is able to load tgas
IImageLoader* createImageLoaderTGA()
{
return new CImageLoaderTGA();
}
} // end namespace video
} // end namespace irr

View File

@ -1,68 +1,68 @@
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#pragma once
#include "IImageLoader.h"
namespace irr
{
namespace video
{
// byte-align structures
#include "irrpack.h"
// these structs are also used in the TGA writer
struct STGAHeader{
u8 IdLength;
u8 ColorMapType;
u8 ImageType;
u8 FirstEntryIndex[2];
u16 ColorMapLength;
u8 ColorMapEntrySize;
u8 XOrigin[2];
u8 YOrigin[2];
u16 ImageWidth;
u16 ImageHeight;
u8 PixelDepth;
u8 ImageDescriptor;
} PACK_STRUCT;
struct STGAFooter
{
u32 ExtensionOffset;
u32 DeveloperOffset;
c8 Signature[18];
} PACK_STRUCT;
// Default alignment
#include "irrunpack.h"
/*!
Surface Loader for targa images
*/
class CImageLoaderTGA : public IImageLoader
{
public:
//! returns true if the file maybe is able to be loaded by this class
//! based on the file extension (e.g. ".tga")
bool isALoadableFileExtension(const io::path& filename) const override;
//! returns true if the file maybe is able to be loaded by this class
bool isALoadableFileFormat(io::IReadFile* file) const override;
//! creates a surface from the file
IImage* loadImage(io::IReadFile* file) const override;
private:
//! loads a compressed tga. Was written and sent in by Jon Pry, thank you very much!
u8* loadCompressedImage(io::IReadFile *file, const STGAHeader& header) const;
};
} // end namespace video
} // end namespace irr
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#pragma once
#include "IImageLoader.h"
namespace irr
{
namespace video
{
// byte-align structures
#include "irrpack.h"
// these structs are also used in the TGA writer
struct STGAHeader{
u8 IdLength;
u8 ColorMapType;
u8 ImageType;
u8 FirstEntryIndex[2];
u16 ColorMapLength;
u8 ColorMapEntrySize;
u8 XOrigin[2];
u8 YOrigin[2];
u16 ImageWidth;
u16 ImageHeight;
u8 PixelDepth;
u8 ImageDescriptor;
} PACK_STRUCT;
struct STGAFooter
{
u32 ExtensionOffset;
u32 DeveloperOffset;
c8 Signature[18];
} PACK_STRUCT;
// Default alignment
#include "irrunpack.h"
/*!
Surface Loader for targa images
*/
class CImageLoaderTGA : public IImageLoader
{
public:
//! returns true if the file maybe is able to be loaded by this class
//! based on the file extension (e.g. ".tga")
bool isALoadableFileExtension(const io::path& filename) const override;
//! returns true if the file maybe is able to be loaded by this class
bool isALoadableFileFormat(io::IReadFile* file) const override;
//! creates a surface from the file
IImage* loadImage(io::IReadFile* file) const override;
private:
//! loads a compressed tga. Was written and sent in by Jon Pry, thank you very much!
u8* loadCompressedImage(io::IReadFile *file, const STGAHeader& header) const;
};
} // end namespace video
} // end namespace irr

View File

@ -1,213 +1,213 @@
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#include "CImageWriterJPG.h"
#include "CColorConverter.h"
#include "IWriteFile.h"
#include "CImage.h"
#include "irrString.h"
#include "os.h"
#include <stdio.h> // required for jpeglib.h
extern "C"
{
#include <jpeglib.h>
#include <jerror.h>
}
namespace irr
{
namespace video
{
// The writer uses a 4k buffer and flushes to disk each time it's filled
#define OUTPUT_BUF_SIZE 4096
typedef struct
{
struct jpeg_destination_mgr pub;/* public fields */
io::IWriteFile* file; /* target file */
JOCTET buffer[OUTPUT_BUF_SIZE]; /* image buffer */
} mem_destination_mgr;
typedef mem_destination_mgr * mem_dest_ptr;
// init
static void jpeg_init_destination(j_compress_ptr cinfo)
{
mem_dest_ptr dest = (mem_dest_ptr) cinfo->dest;
dest->pub.next_output_byte = dest->buffer;
dest->pub.free_in_buffer = OUTPUT_BUF_SIZE;
}
// flush to disk and reset buffer
static boolean jpeg_empty_output_buffer(j_compress_ptr cinfo)
{
mem_dest_ptr dest = (mem_dest_ptr) cinfo->dest;
// for now just exit upon file error
if (dest->file->write(dest->buffer, OUTPUT_BUF_SIZE) != OUTPUT_BUF_SIZE)
ERREXIT (cinfo, JERR_FILE_WRITE);
dest->pub.next_output_byte = dest->buffer;
dest->pub.free_in_buffer = OUTPUT_BUF_SIZE;
return TRUE;
}
static void jpeg_term_destination(j_compress_ptr cinfo)
{
mem_dest_ptr dest = (mem_dest_ptr) cinfo->dest;
const size_t datacount = OUTPUT_BUF_SIZE - dest->pub.free_in_buffer;
// for now just exit upon file error
if (dest->file->write(dest->buffer, datacount) != datacount)
ERREXIT (cinfo, JERR_FILE_WRITE);
}
// set up buffer data
static void jpeg_file_dest(j_compress_ptr cinfo, io::IWriteFile* file)
{
if (cinfo->dest == NULL)
{ /* first time for this JPEG object? */
cinfo->dest = (struct jpeg_destination_mgr *)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo,
JPOOL_PERMANENT,
sizeof(mem_destination_mgr));
}
mem_dest_ptr dest = (mem_dest_ptr) cinfo->dest; /* for casting */
/* Initialize method pointers */
dest->pub.init_destination = jpeg_init_destination;
dest->pub.empty_output_buffer = jpeg_empty_output_buffer;
dest->pub.term_destination = jpeg_term_destination;
/* Initialize private member */
dest->file = file;
}
/* write_JPEG_memory: store JPEG compressed image into memory.
*/
static bool writeJPEGFile(io::IWriteFile* file, IImage* image, u32 quality)
{
void (*format)(const void*, s32, void*) = 0;
switch( image->getColorFormat () )
{
case ECF_R8G8B8:
format = CColorConverter::convert_R8G8B8toR8G8B8;
break;
case ECF_A8R8G8B8:
format = CColorConverter::convert_A8R8G8B8toR8G8B8;
break;
case ECF_A1R5G5B5:
format = CColorConverter::convert_A1R5G5B5toB8G8R8;
break;
case ECF_R5G6B5:
format = CColorConverter::convert_R5G6B5toR8G8B8;
break;
default:
os::Printer::log("writeJPEGFile does not support image format", ColorFormatNames[image->getColorFormat()], ELL_WARNING);
break;
}
// couldn't find a color converter
if ( 0 == format )
return false;
const core::dimension2du dim = image->getDimension();
struct jpeg_compress_struct cinfo;
struct jpeg_error_mgr jerr;
cinfo.err = jpeg_std_error(&jerr);
jpeg_create_compress(&cinfo);
jpeg_file_dest(&cinfo, file);
cinfo.image_width = dim.Width;
cinfo.image_height = dim.Height;
cinfo.input_components = 3;
cinfo.in_color_space = JCS_RGB;
jpeg_set_defaults(&cinfo);
if ( 0 == quality )
quality = 75;
jpeg_set_quality(&cinfo, quality, TRUE);
jpeg_start_compress(&cinfo, TRUE);
u8 * dest = new u8[dim.Width*3];
if (dest)
{
const u32 pitch = image->getPitch();
JSAMPROW row_pointer[1]; /* pointer to JSAMPLE row[s] */
row_pointer[0] = dest;
u8* src = (u8*)image->getData();
while (cinfo.next_scanline < cinfo.image_height)
{
// convert next line
format( src, dim.Width, dest );
src += pitch;
jpeg_write_scanlines(&cinfo, row_pointer, 1);
}
delete [] dest;
/* Step 6: Finish compression */
jpeg_finish_compress(&cinfo);
}
/* Step 7: Destroy */
jpeg_destroy_compress(&cinfo);
return (dest != 0);
}
} // namespace video
} // namespace irr
namespace irr
{
namespace video
{
IImageWriter* createImageWriterJPG()
{
return new CImageWriterJPG;
}
CImageWriterJPG::CImageWriterJPG()
{
#ifdef _DEBUG
setDebugName("CImageWriterJPG");
#endif
}
bool CImageWriterJPG::isAWriteableFileExtension(const io::path& filename) const
{
return core::hasFileExtension ( filename, "jpg", "jpeg" );
}
bool CImageWriterJPG::writeImage(io::IWriteFile *file, IImage *image, u32 quality) const
{
return writeJPEGFile(file, image, quality);
}
} // namespace video
} // namespace irr
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#include "CImageWriterJPG.h"
#include "CColorConverter.h"
#include "IWriteFile.h"
#include "CImage.h"
#include "irrString.h"
#include "os.h"
#include <stdio.h> // required for jpeglib.h
extern "C"
{
#include <jpeglib.h>
#include <jerror.h>
}
namespace irr
{
namespace video
{
// The writer uses a 4k buffer and flushes to disk each time it's filled
#define OUTPUT_BUF_SIZE 4096
typedef struct
{
struct jpeg_destination_mgr pub;/* public fields */
io::IWriteFile* file; /* target file */
JOCTET buffer[OUTPUT_BUF_SIZE]; /* image buffer */
} mem_destination_mgr;
typedef mem_destination_mgr * mem_dest_ptr;
// init
static void jpeg_init_destination(j_compress_ptr cinfo)
{
mem_dest_ptr dest = (mem_dest_ptr) cinfo->dest;
dest->pub.next_output_byte = dest->buffer;
dest->pub.free_in_buffer = OUTPUT_BUF_SIZE;
}
// flush to disk and reset buffer
static boolean jpeg_empty_output_buffer(j_compress_ptr cinfo)
{
mem_dest_ptr dest = (mem_dest_ptr) cinfo->dest;
// for now just exit upon file error
if (dest->file->write(dest->buffer, OUTPUT_BUF_SIZE) != OUTPUT_BUF_SIZE)
ERREXIT (cinfo, JERR_FILE_WRITE);
dest->pub.next_output_byte = dest->buffer;
dest->pub.free_in_buffer = OUTPUT_BUF_SIZE;
return TRUE;
}
static void jpeg_term_destination(j_compress_ptr cinfo)
{
mem_dest_ptr dest = (mem_dest_ptr) cinfo->dest;
const size_t datacount = OUTPUT_BUF_SIZE - dest->pub.free_in_buffer;
// for now just exit upon file error
if (dest->file->write(dest->buffer, datacount) != datacount)
ERREXIT (cinfo, JERR_FILE_WRITE);
}
// set up buffer data
static void jpeg_file_dest(j_compress_ptr cinfo, io::IWriteFile* file)
{
if (cinfo->dest == NULL)
{ /* first time for this JPEG object? */
cinfo->dest = (struct jpeg_destination_mgr *)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo,
JPOOL_PERMANENT,
sizeof(mem_destination_mgr));
}
mem_dest_ptr dest = (mem_dest_ptr) cinfo->dest; /* for casting */
/* Initialize method pointers */
dest->pub.init_destination = jpeg_init_destination;
dest->pub.empty_output_buffer = jpeg_empty_output_buffer;
dest->pub.term_destination = jpeg_term_destination;
/* Initialize private member */
dest->file = file;
}
/* write_JPEG_memory: store JPEG compressed image into memory.
*/
static bool writeJPEGFile(io::IWriteFile* file, IImage* image, u32 quality)
{
void (*format)(const void*, s32, void*) = 0;
switch( image->getColorFormat () )
{
case ECF_R8G8B8:
format = CColorConverter::convert_R8G8B8toR8G8B8;
break;
case ECF_A8R8G8B8:
format = CColorConverter::convert_A8R8G8B8toR8G8B8;
break;
case ECF_A1R5G5B5:
format = CColorConverter::convert_A1R5G5B5toB8G8R8;
break;
case ECF_R5G6B5:
format = CColorConverter::convert_R5G6B5toR8G8B8;
break;
default:
os::Printer::log("writeJPEGFile does not support image format", ColorFormatNames[image->getColorFormat()], ELL_WARNING);
break;
}
// couldn't find a color converter
if ( 0 == format )
return false;
const core::dimension2du dim = image->getDimension();
struct jpeg_compress_struct cinfo;
struct jpeg_error_mgr jerr;
cinfo.err = jpeg_std_error(&jerr);
jpeg_create_compress(&cinfo);
jpeg_file_dest(&cinfo, file);
cinfo.image_width = dim.Width;
cinfo.image_height = dim.Height;
cinfo.input_components = 3;
cinfo.in_color_space = JCS_RGB;
jpeg_set_defaults(&cinfo);
if ( 0 == quality )
quality = 75;
jpeg_set_quality(&cinfo, quality, TRUE);
jpeg_start_compress(&cinfo, TRUE);
u8 * dest = new u8[dim.Width*3];
if (dest)
{
const u32 pitch = image->getPitch();
JSAMPROW row_pointer[1]; /* pointer to JSAMPLE row[s] */
row_pointer[0] = dest;
u8* src = (u8*)image->getData();
while (cinfo.next_scanline < cinfo.image_height)
{
// convert next line
format( src, dim.Width, dest );
src += pitch;
jpeg_write_scanlines(&cinfo, row_pointer, 1);
}
delete [] dest;
/* Step 6: Finish compression */
jpeg_finish_compress(&cinfo);
}
/* Step 7: Destroy */
jpeg_destroy_compress(&cinfo);
return (dest != 0);
}
} // namespace video
} // namespace irr
namespace irr
{
namespace video
{
IImageWriter* createImageWriterJPG()
{
return new CImageWriterJPG;
}
CImageWriterJPG::CImageWriterJPG()
{
#ifdef _DEBUG
setDebugName("CImageWriterJPG");
#endif
}
bool CImageWriterJPG::isAWriteableFileExtension(const io::path& filename) const
{
return core::hasFileExtension ( filename, "jpg", "jpeg" );
}
bool CImageWriterJPG::writeImage(io::IWriteFile *file, IImage *image, u32 quality) const
{
return writeJPEGFile(file, image, quality);
}
} // namespace video
} // namespace irr

View File

@ -1,28 +1,28 @@
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#pragma once
#include "IImageWriter.h"
namespace irr
{
namespace video
{
class CImageWriterJPG : public IImageWriter
{
public:
//! constructor
CImageWriterJPG();
//! return true if this writer can write a file with the given extension
bool isAWriteableFileExtension(const io::path& filename) const override;
//! write image to file
bool writeImage(io::IWriteFile *file, IImage *image, u32 param) const override;
};
}
}
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#pragma once
#include "IImageWriter.h"
namespace irr
{
namespace video
{
class CImageWriterJPG : public IImageWriter
{
public:
//! constructor
CImageWriterJPG();
//! return true if this writer can write a file with the given extension
bool isAWriteableFileExtension(const io::path& filename) const override;
//! write image to file
bool writeImage(io::IWriteFile *file, IImage *image, u32 param) const override;
};
}
}

View File

@ -1,201 +1,201 @@
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#include "CImageWriterPNG.h"
#include "CImageLoaderPNG.h"
#include "CColorConverter.h"
#include "IWriteFile.h"
#include "irrString.h"
#include "os.h" // for logging
#include <png.h> // use system lib png
namespace irr
{
namespace video
{
IImageWriter* createImageWriterPNG()
{
return new CImageWriterPNG;
}
// PNG function for error handling
static void png_cpexcept_error(png_structp png_ptr, png_const_charp msg)
{
os::Printer::log("PNG fatal error", msg, ELL_ERROR);
longjmp(png_jmpbuf(png_ptr), 1);
}
// PNG function for warning handling
static void png_cpexcept_warning(png_structp png_ptr, png_const_charp msg)
{
os::Printer::log("PNG warning", msg, ELL_WARNING);
}
// PNG function for file writing
void PNGAPI user_write_data_fcn(png_structp png_ptr, png_bytep data, png_size_t length)
{
png_size_t check;
io::IWriteFile* file=(io::IWriteFile*)png_get_io_ptr(png_ptr);
check=(png_size_t) file->write((const void*)data, length);
if (check != length)
png_error(png_ptr, "Write Error");
}
CImageWriterPNG::CImageWriterPNG()
{
#ifdef _DEBUG
setDebugName("CImageWriterPNG");
#endif
}
bool CImageWriterPNG::isAWriteableFileExtension(const io::path& filename) const
{
return core::hasFileExtension ( filename, "png" );
}
bool CImageWriterPNG::writeImage(io::IWriteFile* file, IImage* image,u32 param) const
{
if (!file || !image)
return false;
// Allocate the png write struct
png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING,
NULL, (png_error_ptr)png_cpexcept_error, (png_error_ptr)png_cpexcept_warning);
if (!png_ptr)
{
os::Printer::log("PNGWriter: Internal PNG create write struct failure", file->getFileName(), ELL_ERROR);
return false;
}
// Allocate the png info struct
png_infop info_ptr = png_create_info_struct(png_ptr);
if (!info_ptr)
{
os::Printer::log("PNGWriter: Internal PNG create info struct failure", file->getFileName(), ELL_ERROR);
png_destroy_write_struct(&png_ptr, NULL);
return false;
}
// for proper error handling
if (setjmp(png_jmpbuf(png_ptr)))
{
png_destroy_write_struct(&png_ptr, &info_ptr);
return false;
}
png_set_write_fn(png_ptr, file, user_write_data_fcn, NULL);
// Set info
switch(image->getColorFormat())
{
case ECF_A8R8G8B8:
case ECF_A1R5G5B5:
png_set_IHDR(png_ptr, info_ptr,
image->getDimension().Width, image->getDimension().Height,
8, PNG_COLOR_TYPE_RGB_ALPHA, PNG_INTERLACE_NONE,
PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
break;
default:
png_set_IHDR(png_ptr, info_ptr,
image->getDimension().Width, image->getDimension().Height,
8, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE,
PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
}
s32 lineWidth = image->getDimension().Width;
switch(image->getColorFormat())
{
case ECF_R8G8B8:
case ECF_R5G6B5:
lineWidth*=3;
break;
case ECF_A8R8G8B8:
case ECF_A1R5G5B5:
lineWidth*=4;
break;
// TODO: Error handling in case of unsupported color format
default:
break;
}
u8* tmpImage = new u8[image->getDimension().Height*lineWidth];
if (!tmpImage)
{
os::Printer::log("PNGWriter: Internal PNG create image failure", file->getFileName(), ELL_ERROR);
png_destroy_write_struct(&png_ptr, &info_ptr);
return false;
}
u8* data = (u8*)image->getData();
switch(image->getColorFormat())
{
case ECF_R8G8B8:
CColorConverter::convert_R8G8B8toR8G8B8(data,image->getDimension().Height*image->getDimension().Width,tmpImage);
break;
case ECF_A8R8G8B8:
CColorConverter::convert_A8R8G8B8toA8R8G8B8(data,image->getDimension().Height*image->getDimension().Width,tmpImage);
break;
case ECF_R5G6B5:
CColorConverter::convert_R5G6B5toR8G8B8(data,image->getDimension().Height*image->getDimension().Width,tmpImage);
break;
case ECF_A1R5G5B5:
CColorConverter::convert_A1R5G5B5toA8R8G8B8(data,image->getDimension().Height*image->getDimension().Width,tmpImage);
break;
// TODO: Error handling in case of unsupported color format
default:
os::Printer::log("CImageWriterPNG does not support image format", ColorFormatNames[image->getColorFormat()], ELL_WARNING);
png_destroy_write_struct(&png_ptr, &info_ptr);
delete [] tmpImage;
return false;
}
// Create array of pointers to rows in image data
//Used to point to image rows
u8** RowPointers = new png_bytep[image->getDimension().Height];
if (!RowPointers)
{
os::Printer::log("PNGWriter: Internal PNG create row pointers failure", file->getFileName(), ELL_ERROR);
png_destroy_write_struct(&png_ptr, &info_ptr);
delete [] tmpImage;
return false;
}
data=tmpImage;
// Fill array of pointers to rows in image data
for (u32 i=0; i<image->getDimension().Height; ++i)
{
RowPointers[i]=data;
data += lineWidth;
}
// for proper error handling
if (setjmp(png_jmpbuf(png_ptr)))
{
png_destroy_write_struct(&png_ptr, &info_ptr);
delete [] RowPointers;
delete [] tmpImage;
return false;
}
png_set_rows(png_ptr, info_ptr, RowPointers);
if (image->getColorFormat()==ECF_A8R8G8B8 || image->getColorFormat()==ECF_A1R5G5B5)
png_write_png(png_ptr, info_ptr, PNG_TRANSFORM_BGR, NULL);
else
{
png_write_png(png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, NULL);
}
delete [] RowPointers;
delete [] tmpImage;
png_destroy_write_struct(&png_ptr, &info_ptr);
return true;
}
} // namespace video
} // namespace irr
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#include "CImageWriterPNG.h"
#include "CImageLoaderPNG.h"
#include "CColorConverter.h"
#include "IWriteFile.h"
#include "irrString.h"
#include "os.h" // for logging
#include <png.h> // use system lib png
namespace irr
{
namespace video
{
IImageWriter* createImageWriterPNG()
{
return new CImageWriterPNG;
}
// PNG function for error handling
static void png_cpexcept_error(png_structp png_ptr, png_const_charp msg)
{
os::Printer::log("PNG fatal error", msg, ELL_ERROR);
longjmp(png_jmpbuf(png_ptr), 1);
}
// PNG function for warning handling
static void png_cpexcept_warning(png_structp png_ptr, png_const_charp msg)
{
os::Printer::log("PNG warning", msg, ELL_WARNING);
}
// PNG function for file writing
void PNGAPI user_write_data_fcn(png_structp png_ptr, png_bytep data, png_size_t length)
{
png_size_t check;
io::IWriteFile* file=(io::IWriteFile*)png_get_io_ptr(png_ptr);
check=(png_size_t) file->write((const void*)data, length);
if (check != length)
png_error(png_ptr, "Write Error");
}
CImageWriterPNG::CImageWriterPNG()
{
#ifdef _DEBUG
setDebugName("CImageWriterPNG");
#endif
}
bool CImageWriterPNG::isAWriteableFileExtension(const io::path& filename) const
{
return core::hasFileExtension ( filename, "png" );
}
bool CImageWriterPNG::writeImage(io::IWriteFile* file, IImage* image,u32 param) const
{
if (!file || !image)
return false;
// Allocate the png write struct
png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING,
NULL, (png_error_ptr)png_cpexcept_error, (png_error_ptr)png_cpexcept_warning);
if (!png_ptr)
{
os::Printer::log("PNGWriter: Internal PNG create write struct failure", file->getFileName(), ELL_ERROR);
return false;
}
// Allocate the png info struct
png_infop info_ptr = png_create_info_struct(png_ptr);
if (!info_ptr)
{
os::Printer::log("PNGWriter: Internal PNG create info struct failure", file->getFileName(), ELL_ERROR);
png_destroy_write_struct(&png_ptr, NULL);
return false;
}
// for proper error handling
if (setjmp(png_jmpbuf(png_ptr)))
{
png_destroy_write_struct(&png_ptr, &info_ptr);
return false;
}
png_set_write_fn(png_ptr, file, user_write_data_fcn, NULL);
// Set info
switch(image->getColorFormat())
{
case ECF_A8R8G8B8:
case ECF_A1R5G5B5:
png_set_IHDR(png_ptr, info_ptr,
image->getDimension().Width, image->getDimension().Height,
8, PNG_COLOR_TYPE_RGB_ALPHA, PNG_INTERLACE_NONE,
PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
break;
default:
png_set_IHDR(png_ptr, info_ptr,
image->getDimension().Width, image->getDimension().Height,
8, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE,
PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
}
s32 lineWidth = image->getDimension().Width;
switch(image->getColorFormat())
{
case ECF_R8G8B8:
case ECF_R5G6B5:
lineWidth*=3;
break;
case ECF_A8R8G8B8:
case ECF_A1R5G5B5:
lineWidth*=4;
break;
// TODO: Error handling in case of unsupported color format
default:
break;
}
u8* tmpImage = new u8[image->getDimension().Height*lineWidth];
if (!tmpImage)
{
os::Printer::log("PNGWriter: Internal PNG create image failure", file->getFileName(), ELL_ERROR);
png_destroy_write_struct(&png_ptr, &info_ptr);
return false;
}
u8* data = (u8*)image->getData();
switch(image->getColorFormat())
{
case ECF_R8G8B8:
CColorConverter::convert_R8G8B8toR8G8B8(data,image->getDimension().Height*image->getDimension().Width,tmpImage);
break;
case ECF_A8R8G8B8:
CColorConverter::convert_A8R8G8B8toA8R8G8B8(data,image->getDimension().Height*image->getDimension().Width,tmpImage);
break;
case ECF_R5G6B5:
CColorConverter::convert_R5G6B5toR8G8B8(data,image->getDimension().Height*image->getDimension().Width,tmpImage);
break;
case ECF_A1R5G5B5:
CColorConverter::convert_A1R5G5B5toA8R8G8B8(data,image->getDimension().Height*image->getDimension().Width,tmpImage);
break;
// TODO: Error handling in case of unsupported color format
default:
os::Printer::log("CImageWriterPNG does not support image format", ColorFormatNames[image->getColorFormat()], ELL_WARNING);
png_destroy_write_struct(&png_ptr, &info_ptr);
delete [] tmpImage;
return false;
}
// Create array of pointers to rows in image data
//Used to point to image rows
u8** RowPointers = new png_bytep[image->getDimension().Height];
if (!RowPointers)
{
os::Printer::log("PNGWriter: Internal PNG create row pointers failure", file->getFileName(), ELL_ERROR);
png_destroy_write_struct(&png_ptr, &info_ptr);
delete [] tmpImage;
return false;
}
data=tmpImage;
// Fill array of pointers to rows in image data
for (u32 i=0; i<image->getDimension().Height; ++i)
{
RowPointers[i]=data;
data += lineWidth;
}
// for proper error handling
if (setjmp(png_jmpbuf(png_ptr)))
{
png_destroy_write_struct(&png_ptr, &info_ptr);
delete [] RowPointers;
delete [] tmpImage;
return false;
}
png_set_rows(png_ptr, info_ptr, RowPointers);
if (image->getColorFormat()==ECF_A8R8G8B8 || image->getColorFormat()==ECF_A1R5G5B5)
png_write_png(png_ptr, info_ptr, PNG_TRANSFORM_BGR, NULL);
else
{
png_write_png(png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, NULL);
}
delete [] RowPointers;
delete [] tmpImage;
png_destroy_write_struct(&png_ptr, &info_ptr);
return true;
}
} // namespace video
} // namespace irr

View File

@ -1,28 +1,28 @@
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#pragma once
#include "IImageWriter.h"
namespace irr
{
namespace video
{
class CImageWriterPNG : public IImageWriter
{
public:
//! constructor
CImageWriterPNG();
//! return true if this writer can write a file with the given extension
bool isAWriteableFileExtension(const io::path& filename) const override;
//! write image to file
bool writeImage(io::IWriteFile *file, IImage *image, u32 param) const override;
};
} // namespace video
} // namespace irr
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#pragma once
#include "IImageWriter.h"
namespace irr
{
namespace video
{
class CImageWriterPNG : public IImageWriter
{
public:
//! constructor
CImageWriterPNG();
//! return true if this writer can write a file with the given extension
bool isAWriteableFileExtension(const io::path& filename) const override;
//! write image to file
bool writeImage(io::IWriteFile *file, IImage *image, u32 param) const override;
};
} // namespace video
} // namespace irr

File diff suppressed because it is too large Load Diff

View File

@ -1,483 +1,483 @@
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#pragma once
#ifdef _IRR_COMPILE_WITH_X11_DEVICE_
#include "CIrrDeviceStub.h"
#include "IrrlichtDevice.h"
#include "ICursorControl.h"
#include "os.h"
#ifdef _IRR_COMPILE_WITH_X11_
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/cursorfont.h>
#include <X11/keysym.h>
#ifdef _IRR_LINUX_X11_XINPUT2_
#include <X11/extensions/XInput2.h>
#endif
#else
#define KeySym s32
#endif
namespace irr
{
class CIrrDeviceLinux : public CIrrDeviceStub
{
public:
//! constructor
CIrrDeviceLinux(const SIrrlichtCreationParameters& param);
//! destructor
virtual ~CIrrDeviceLinux();
//! runs the device. Returns false if device wants to be deleted
bool run() override;
//! Cause the device to temporarily pause execution and let other processes to run
// This should bring down processor usage without major performance loss for Irrlicht
void yield() override;
//! Pause execution and let other processes to run for a specified amount of time.
void sleep(u32 timeMs, bool pauseTimer) override;
//! sets the caption of the window
void setWindowCaption(const wchar_t* text) override;
//! Sets the window icon.
bool setWindowIcon(const video::IImage *img) override;
//! returns if window is active. if not, nothing need to be drawn
bool isWindowActive() const override;
//! returns if window has focus.
bool isWindowFocused() const override;
//! returns if window is minimized.
bool isWindowMinimized() const override;
//! returns last state from maximizeWindow() and restoreWindow()
bool isWindowMaximized() const override;
//! returns color format of the window.
video::ECOLOR_FORMAT getColorFormat() const override;
//! notifies the device that it should close itself
void closeDevice() override;
//! Sets if the window should be resizable in windowed mode.
void setResizable(bool resize=false) override;
//! Resize the render window.
void setWindowSize(const irr::core::dimension2d<u32>& size) override;
//! Minimizes the window.
void minimizeWindow() override;
//! Maximizes the window.
void maximizeWindow() override;
//! Restores the window size.
void restoreWindow() override;
//! Get the position of this window on screen
core::position2di getWindowPosition() override;
//! Activate any joysticks, and generate events for them.
bool activateJoysticks(core::array<SJoystickInfo> & joystickInfo) override;
//! gets text from the clipboard
//! \return Returns 0 if no string is in there, otherwise utf-8 text.
virtual const c8 *getTextFromClipboard() const;
//! gets text from the primary selection
//! \return Returns 0 if no string is in there, otherwise utf-8 text.
virtual const c8 *getTextFromPrimarySelection() const;
//! copies text to the clipboard
//! This sets the clipboard selection and _not_ the primary selection.
//! @param text The text in utf-8
virtual void copyToClipboard(const c8 *text) const;
//! copies text to the primary selection
//! This sets the primary selection which you have on X on the middle mouse button.
//! @param text The text in utf-8
virtual void copyToPrimarySelection(const c8 *text) const;
//! Remove all messages pending in the system message loop
void clearSystemMessages() override;
//! Get the device type
E_DEVICE_TYPE getType() const override
{
return EIDT_X11;
}
//! Get the display density in dots per inch.
float getDisplayDensity() const override;
#ifdef _IRR_COMPILE_WITH_X11_
// convert an Irrlicht texture to a X11 cursor
Cursor TextureToCursor(irr::video::ITexture * tex, const core::rect<s32>& sourceRect, const core::position2d<s32> &hotspot);
Cursor TextureToMonochromeCursor(irr::video::ITexture * tex, const core::rect<s32>& sourceRect, const core::position2d<s32> &hotspot);
#ifdef _IRR_LINUX_XCURSOR_
Cursor TextureToARGBCursor(irr::video::ITexture * tex, const core::rect<s32>& sourceRect, const core::position2d<s32> &hotspot);
#endif
#endif
private:
//! create the driver
void createDriver();
bool createWindow();
void createKeyMap();
void pollJoysticks();
void initXAtoms();
void initXInput2();
bool switchToFullscreen();
void setupTopLevelXorgWindow();
#ifdef _IRR_COMPILE_WITH_X11_
bool createInputContext();
void destroyInputContext();
EKEY_CODE getKeyCode(XEvent &event);
const c8 *getTextFromSelection(Atom selection, core::stringc &text_buffer) const;
bool becomeSelectionOwner(Atom selection) const;
#endif
//! Implementation of the linux cursor control
class CCursorControl : public gui::ICursorControl
{
public:
CCursorControl(CIrrDeviceLinux* dev, bool null);
~CCursorControl();
//! Changes the visible state of the mouse cursor.
void setVisible(bool visible) override
{
if (visible==IsVisible)
return;
IsVisible = visible;
#ifdef _IRR_COMPILE_WITH_X11_
if (!Null)
{
if ( !IsVisible )
XDefineCursor( Device->XDisplay, Device->XWindow, InvisCursor );
else
XUndefineCursor( Device->XDisplay, Device->XWindow );
}
#endif
}
//! Returns if the cursor is currently visible.
bool isVisible() const override
{
return IsVisible;
}
//! Sets the new position of the cursor.
void setPosition(const core::position2d<f32> &pos) override
{
setPosition(pos.X, pos.Y);
}
//! Sets the new position of the cursor.
void setPosition(f32 x, f32 y) override
{
setPosition((s32)(x*Device->Width), (s32)(y*Device->Height));
}
//! Sets the new position of the cursor.
void setPosition(const core::position2d<s32> &pos) override
{
setPosition(pos.X, pos.Y);
}
//! Sets the new position of the cursor.
void setPosition(s32 x, s32 y) override
{
#ifdef _IRR_COMPILE_WITH_X11_
if (!Null)
{
if (UseReferenceRect)
{
// NOTE: XIWarpPointer works when X11 has set a coordinate transformation matrix for the mouse unlike XWarpPointer
// which runs into a bug mentioned here: https://gitlab.freedesktop.org/xorg/xserver/-/issues/600
// So also workaround for Irrlicht bug #450
#ifdef _IRR_LINUX_X11_XINPUT2_
if ( DeviceId != 0)
{
XIWarpPointer(Device->XDisplay,
DeviceId,
None,
Device->XWindow, 0, 0,
Device->Width,
Device->Height,
ReferenceRect.UpperLeftCorner.X + x,
ReferenceRect.UpperLeftCorner.Y + y);
}
else
#endif
{
XWarpPointer(Device->XDisplay,
None,
Device->XWindow, 0, 0,
Device->Width,
Device->Height,
ReferenceRect.UpperLeftCorner.X + x,
ReferenceRect.UpperLeftCorner.Y + y);
}
}
else
{
#ifdef _IRR_LINUX_X11_XINPUT2_
if ( DeviceId != 0)
{
XIWarpPointer(Device->XDisplay,
DeviceId,
None,
Device->XWindow, 0, 0,
Device->Width,
Device->Height, x, y);
}
else
#endif
{
XWarpPointer(Device->XDisplay,
None,
Device->XWindow, 0, 0,
Device->Width,
Device->Height, x, y);
}
}
XFlush(Device->XDisplay);
}
#endif
CursorPos.X = x;
CursorPos.Y = y;
}
//! Returns the current position of the mouse cursor.
const core::position2d<s32>& getPosition(bool updateCursor) override
{
if ( updateCursor )
updateCursorPos();
return CursorPos;
}
//! Returns the current position of the mouse cursor.
core::position2d<f32> getRelativePosition(bool updateCursor) override
{
if ( updateCursor )
updateCursorPos();
if (!UseReferenceRect)
{
return core::position2d<f32>(CursorPos.X / (f32)Device->Width,
CursorPos.Y / (f32)Device->Height);
}
return core::position2d<f32>(CursorPos.X / (f32)ReferenceRect.getWidth(),
CursorPos.Y / (f32)ReferenceRect.getHeight());
}
void setReferenceRect(core::rect<s32>* rect=0) override
{
if (rect)
{
ReferenceRect = *rect;
UseReferenceRect = true;
// prevent division through zero and uneven sizes
if (!ReferenceRect.getHeight() || ReferenceRect.getHeight()%2)
ReferenceRect.LowerRightCorner.Y += 1;
if (!ReferenceRect.getWidth() || ReferenceRect.getWidth()%2)
ReferenceRect.LowerRightCorner.X += 1;
}
else
UseReferenceRect = false;
}
//! Sets the active cursor icon
void setActiveIcon(gui::ECURSOR_ICON iconId) override;
//! Gets the currently active icon
gui::ECURSOR_ICON getActiveIcon() const override
{
return ActiveIcon;
}
//! Add a custom sprite as cursor icon.
gui::ECURSOR_ICON addIcon(const gui::SCursorSprite& icon) override;
//! replace the given cursor icon.
void changeIcon(gui::ECURSOR_ICON iconId, const gui::SCursorSprite& icon) override;
//! Return a system-specific size which is supported for cursors. Larger icons will fail, smaller icons might work.
core::dimension2di getSupportedIconSize() const override;
#ifdef _IRR_COMPILE_WITH_X11_
//! Set platform specific behavior flags.
void setPlatformBehavior(gui::ECURSOR_PLATFORM_BEHAVIOR behavior) override {PlatformBehavior = behavior; }
//! Return platform specific behavior.
gui::ECURSOR_PLATFORM_BEHAVIOR getPlatformBehavior() const override { return PlatformBehavior; }
void update();
void clearCursors();
#endif
private:
void updateCursorPos()
{
#ifdef _IRR_COMPILE_WITH_X11_
if (Null)
return;
if ( PlatformBehavior&gui::ECPB_X11_CACHE_UPDATES && !os::Timer::isStopped() )
{
u32 now = os::Timer::getTime();
if (now <= LastQuery)
return;
LastQuery = now;
}
Window tmp;
int itmp1, itmp2;
unsigned int maskreturn;
XQueryPointer(Device->XDisplay, Device->XWindow,
&tmp, &tmp,
&itmp1, &itmp2,
&CursorPos.X, &CursorPos.Y, &maskreturn);
#endif
}
CIrrDeviceLinux* Device;
core::position2d<s32> CursorPos;
core::rect<s32> ReferenceRect;
#ifdef _IRR_COMPILE_WITH_X11_
gui::ECURSOR_PLATFORM_BEHAVIOR PlatformBehavior;
u32 LastQuery;
Cursor InvisCursor;
#ifdef _IRR_LINUX_X11_XINPUT2_
int DeviceId;
#endif
struct CursorFrameX11
{
CursorFrameX11() : IconHW(0) {}
CursorFrameX11(Cursor icon) : IconHW(icon) {}
Cursor IconHW; // hardware cursor
};
struct CursorX11
{
CursorX11() {}
explicit CursorX11(Cursor iconHw, u32 frameTime=0) : FrameTime(frameTime)
{
Frames.push_back( CursorFrameX11(iconHw) );
}
core::array<CursorFrameX11> Frames;
u32 FrameTime;
};
core::array<CursorX11> Cursors;
void initCursors();
#endif
bool IsVisible;
bool Null;
bool UseReferenceRect;
gui::ECURSOR_ICON ActiveIcon;
u32 ActiveIconStartTime;
};
friend class CCursorControl;
#ifdef _IRR_COMPILE_WITH_X11_
friend class COpenGLDriver;
Display *XDisplay;
XVisualInfo* VisualInfo;
int Screennr;
Window XWindow;
XSetWindowAttributes WndAttributes;
XSizeHints* StdHints;
XIM XInputMethod;
XIC XInputContext;
bool HasNetWM;
// text is utf-8
mutable core::stringc Clipboard;
mutable core::stringc PrimarySelection;
#endif
#if defined(_IRR_LINUX_X11_XINPUT2_)
int currentTouchedCount;
#endif
u32 Width, Height;
bool WindowHasFocus;
bool WindowMinimized;
bool WindowMaximized;
bool ExternalWindow;
int AutorepeatSupport;
struct SKeyMap
{
SKeyMap() {}
SKeyMap(s32 x11, s32 win32)
: X11Key(x11), Win32Key(win32)
{
}
KeySym X11Key;
s32 Win32Key;
bool operator<(const SKeyMap& o) const
{
return X11Key<o.X11Key;
}
};
core::array<SKeyMap> KeyMap;
#if defined(_IRR_COMPILE_WITH_JOYSTICK_EVENTS_)
struct JoystickInfo
{
int fd;
int axes;
int buttons;
SEvent persistentData;
JoystickInfo() : fd(-1), axes(0), buttons(0) { }
};
core::array<JoystickInfo> ActiveJoysticks;
#endif
};
} // end namespace irr
#endif // _IRR_COMPILE_WITH_X11_DEVICE_
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#pragma once
#ifdef _IRR_COMPILE_WITH_X11_DEVICE_
#include "CIrrDeviceStub.h"
#include "IrrlichtDevice.h"
#include "ICursorControl.h"
#include "os.h"
#ifdef _IRR_COMPILE_WITH_X11_
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/cursorfont.h>
#include <X11/keysym.h>
#ifdef _IRR_LINUX_X11_XINPUT2_
#include <X11/extensions/XInput2.h>
#endif
#else
#define KeySym s32
#endif
namespace irr
{
class CIrrDeviceLinux : public CIrrDeviceStub
{
public:
//! constructor
CIrrDeviceLinux(const SIrrlichtCreationParameters& param);
//! destructor
virtual ~CIrrDeviceLinux();
//! runs the device. Returns false if device wants to be deleted
bool run() override;
//! Cause the device to temporarily pause execution and let other processes to run
// This should bring down processor usage without major performance loss for Irrlicht
void yield() override;
//! Pause execution and let other processes to run for a specified amount of time.
void sleep(u32 timeMs, bool pauseTimer) override;
//! sets the caption of the window
void setWindowCaption(const wchar_t* text) override;
//! Sets the window icon.
bool setWindowIcon(const video::IImage *img) override;
//! returns if window is active. if not, nothing need to be drawn
bool isWindowActive() const override;
//! returns if window has focus.
bool isWindowFocused() const override;
//! returns if window is minimized.
bool isWindowMinimized() const override;
//! returns last state from maximizeWindow() and restoreWindow()
bool isWindowMaximized() const override;
//! returns color format of the window.
video::ECOLOR_FORMAT getColorFormat() const override;
//! notifies the device that it should close itself
void closeDevice() override;
//! Sets if the window should be resizable in windowed mode.
void setResizable(bool resize=false) override;
//! Resize the render window.
void setWindowSize(const irr::core::dimension2d<u32>& size) override;
//! Minimizes the window.
void minimizeWindow() override;
//! Maximizes the window.
void maximizeWindow() override;
//! Restores the window size.
void restoreWindow() override;
//! Get the position of this window on screen
core::position2di getWindowPosition() override;
//! Activate any joysticks, and generate events for them.
bool activateJoysticks(core::array<SJoystickInfo> & joystickInfo) override;
//! gets text from the clipboard
//! \return Returns 0 if no string is in there, otherwise utf-8 text.
virtual const c8 *getTextFromClipboard() const;
//! gets text from the primary selection
//! \return Returns 0 if no string is in there, otherwise utf-8 text.
virtual const c8 *getTextFromPrimarySelection() const;
//! copies text to the clipboard
//! This sets the clipboard selection and _not_ the primary selection.
//! @param text The text in utf-8
virtual void copyToClipboard(const c8 *text) const;
//! copies text to the primary selection
//! This sets the primary selection which you have on X on the middle mouse button.
//! @param text The text in utf-8
virtual void copyToPrimarySelection(const c8 *text) const;
//! Remove all messages pending in the system message loop
void clearSystemMessages() override;
//! Get the device type
E_DEVICE_TYPE getType() const override
{
return EIDT_X11;
}
//! Get the display density in dots per inch.
float getDisplayDensity() const override;
#ifdef _IRR_COMPILE_WITH_X11_
// convert an Irrlicht texture to a X11 cursor
Cursor TextureToCursor(irr::video::ITexture * tex, const core::rect<s32>& sourceRect, const core::position2d<s32> &hotspot);
Cursor TextureToMonochromeCursor(irr::video::ITexture * tex, const core::rect<s32>& sourceRect, const core::position2d<s32> &hotspot);
#ifdef _IRR_LINUX_XCURSOR_
Cursor TextureToARGBCursor(irr::video::ITexture * tex, const core::rect<s32>& sourceRect, const core::position2d<s32> &hotspot);
#endif
#endif
private:
//! create the driver
void createDriver();
bool createWindow();
void createKeyMap();
void pollJoysticks();
void initXAtoms();
void initXInput2();
bool switchToFullscreen();
void setupTopLevelXorgWindow();
#ifdef _IRR_COMPILE_WITH_X11_
bool createInputContext();
void destroyInputContext();
EKEY_CODE getKeyCode(XEvent &event);
const c8 *getTextFromSelection(Atom selection, core::stringc &text_buffer) const;
bool becomeSelectionOwner(Atom selection) const;
#endif
//! Implementation of the linux cursor control
class CCursorControl : public gui::ICursorControl
{
public:
CCursorControl(CIrrDeviceLinux* dev, bool null);
~CCursorControl();
//! Changes the visible state of the mouse cursor.
void setVisible(bool visible) override
{
if (visible==IsVisible)
return;
IsVisible = visible;
#ifdef _IRR_COMPILE_WITH_X11_
if (!Null)
{
if ( !IsVisible )
XDefineCursor( Device->XDisplay, Device->XWindow, InvisCursor );
else
XUndefineCursor( Device->XDisplay, Device->XWindow );
}
#endif
}
//! Returns if the cursor is currently visible.
bool isVisible() const override
{
return IsVisible;
}
//! Sets the new position of the cursor.
void setPosition(const core::position2d<f32> &pos) override
{
setPosition(pos.X, pos.Y);
}
//! Sets the new position of the cursor.
void setPosition(f32 x, f32 y) override
{
setPosition((s32)(x*Device->Width), (s32)(y*Device->Height));
}
//! Sets the new position of the cursor.
void setPosition(const core::position2d<s32> &pos) override
{
setPosition(pos.X, pos.Y);
}
//! Sets the new position of the cursor.
void setPosition(s32 x, s32 y) override
{
#ifdef _IRR_COMPILE_WITH_X11_
if (!Null)
{
if (UseReferenceRect)
{
// NOTE: XIWarpPointer works when X11 has set a coordinate transformation matrix for the mouse unlike XWarpPointer
// which runs into a bug mentioned here: https://gitlab.freedesktop.org/xorg/xserver/-/issues/600
// So also workaround for Irrlicht bug #450
#ifdef _IRR_LINUX_X11_XINPUT2_
if ( DeviceId != 0)
{
XIWarpPointer(Device->XDisplay,
DeviceId,
None,
Device->XWindow, 0, 0,
Device->Width,
Device->Height,
ReferenceRect.UpperLeftCorner.X + x,
ReferenceRect.UpperLeftCorner.Y + y);
}
else
#endif
{
XWarpPointer(Device->XDisplay,
None,
Device->XWindow, 0, 0,
Device->Width,
Device->Height,
ReferenceRect.UpperLeftCorner.X + x,
ReferenceRect.UpperLeftCorner.Y + y);
}
}
else
{
#ifdef _IRR_LINUX_X11_XINPUT2_
if ( DeviceId != 0)
{
XIWarpPointer(Device->XDisplay,
DeviceId,
None,
Device->XWindow, 0, 0,
Device->Width,
Device->Height, x, y);
}
else
#endif
{
XWarpPointer(Device->XDisplay,
None,
Device->XWindow, 0, 0,
Device->Width,
Device->Height, x, y);
}
}
XFlush(Device->XDisplay);
}
#endif
CursorPos.X = x;
CursorPos.Y = y;
}
//! Returns the current position of the mouse cursor.
const core::position2d<s32>& getPosition(bool updateCursor) override
{
if ( updateCursor )
updateCursorPos();
return CursorPos;
}
//! Returns the current position of the mouse cursor.
core::position2d<f32> getRelativePosition(bool updateCursor) override
{
if ( updateCursor )
updateCursorPos();
if (!UseReferenceRect)
{
return core::position2d<f32>(CursorPos.X / (f32)Device->Width,
CursorPos.Y / (f32)Device->Height);
}
return core::position2d<f32>(CursorPos.X / (f32)ReferenceRect.getWidth(),
CursorPos.Y / (f32)ReferenceRect.getHeight());
}
void setReferenceRect(core::rect<s32>* rect=0) override
{
if (rect)
{
ReferenceRect = *rect;
UseReferenceRect = true;
// prevent division through zero and uneven sizes
if (!ReferenceRect.getHeight() || ReferenceRect.getHeight()%2)
ReferenceRect.LowerRightCorner.Y += 1;
if (!ReferenceRect.getWidth() || ReferenceRect.getWidth()%2)
ReferenceRect.LowerRightCorner.X += 1;
}
else
UseReferenceRect = false;
}
//! Sets the active cursor icon
void setActiveIcon(gui::ECURSOR_ICON iconId) override;
//! Gets the currently active icon
gui::ECURSOR_ICON getActiveIcon() const override
{
return ActiveIcon;
}
//! Add a custom sprite as cursor icon.
gui::ECURSOR_ICON addIcon(const gui::SCursorSprite& icon) override;
//! replace the given cursor icon.
void changeIcon(gui::ECURSOR_ICON iconId, const gui::SCursorSprite& icon) override;
//! Return a system-specific size which is supported for cursors. Larger icons will fail, smaller icons might work.
core::dimension2di getSupportedIconSize() const override;
#ifdef _IRR_COMPILE_WITH_X11_
//! Set platform specific behavior flags.
void setPlatformBehavior(gui::ECURSOR_PLATFORM_BEHAVIOR behavior) override {PlatformBehavior = behavior; }
//! Return platform specific behavior.
gui::ECURSOR_PLATFORM_BEHAVIOR getPlatformBehavior() const override { return PlatformBehavior; }
void update();
void clearCursors();
#endif
private:
void updateCursorPos()
{
#ifdef _IRR_COMPILE_WITH_X11_
if (Null)
return;
if ( PlatformBehavior&gui::ECPB_X11_CACHE_UPDATES && !os::Timer::isStopped() )
{
u32 now = os::Timer::getTime();
if (now <= LastQuery)
return;
LastQuery = now;
}
Window tmp;
int itmp1, itmp2;
unsigned int maskreturn;
XQueryPointer(Device->XDisplay, Device->XWindow,
&tmp, &tmp,
&itmp1, &itmp2,
&CursorPos.X, &CursorPos.Y, &maskreturn);
#endif
}
CIrrDeviceLinux* Device;
core::position2d<s32> CursorPos;
core::rect<s32> ReferenceRect;
#ifdef _IRR_COMPILE_WITH_X11_
gui::ECURSOR_PLATFORM_BEHAVIOR PlatformBehavior;
u32 LastQuery;
Cursor InvisCursor;
#ifdef _IRR_LINUX_X11_XINPUT2_
int DeviceId;
#endif
struct CursorFrameX11
{
CursorFrameX11() : IconHW(0) {}
CursorFrameX11(Cursor icon) : IconHW(icon) {}
Cursor IconHW; // hardware cursor
};
struct CursorX11
{
CursorX11() {}
explicit CursorX11(Cursor iconHw, u32 frameTime=0) : FrameTime(frameTime)
{
Frames.push_back( CursorFrameX11(iconHw) );
}
core::array<CursorFrameX11> Frames;
u32 FrameTime;
};
core::array<CursorX11> Cursors;
void initCursors();
#endif
bool IsVisible;
bool Null;
bool UseReferenceRect;
gui::ECURSOR_ICON ActiveIcon;
u32 ActiveIconStartTime;
};
friend class CCursorControl;
#ifdef _IRR_COMPILE_WITH_X11_
friend class COpenGLDriver;
Display *XDisplay;
XVisualInfo* VisualInfo;
int Screennr;
Window XWindow;
XSetWindowAttributes WndAttributes;
XSizeHints* StdHints;
XIM XInputMethod;
XIC XInputContext;
bool HasNetWM;
// text is utf-8
mutable core::stringc Clipboard;
mutable core::stringc PrimarySelection;
#endif
#if defined(_IRR_LINUX_X11_XINPUT2_)
int currentTouchedCount;
#endif
u32 Width, Height;
bool WindowHasFocus;
bool WindowMinimized;
bool WindowMaximized;
bool ExternalWindow;
int AutorepeatSupport;
struct SKeyMap
{
SKeyMap() {}
SKeyMap(s32 x11, s32 win32)
: X11Key(x11), Win32Key(win32)
{
}
KeySym X11Key;
s32 Win32Key;
bool operator<(const SKeyMap& o) const
{
return X11Key<o.X11Key;
}
};
core::array<SKeyMap> KeyMap;
#if defined(_IRR_COMPILE_WITH_JOYSTICK_EVENTS_)
struct JoystickInfo
{
int fd;
int axes;
int buttons;
SEvent persistentData;
JoystickInfo() : fd(-1), axes(0), buttons(0) { }
};
core::array<JoystickInfo> ActiveJoysticks;
#endif
};
} // end namespace irr
#endif // _IRR_COMPILE_WITH_X11_DEVICE_

View File

@ -1,249 +1,249 @@
// Copyright (C) 2005-2006 Etienne Petitjean
// Copyright (C) 2007-2012 Christian Stehno
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in Irrlicht.h
#pragma once
#ifdef _IRR_COMPILE_WITH_OSX_DEVICE_
#include "CIrrDeviceStub.h"
#include "IrrlichtDevice.h"
#include "IGUIEnvironment.h"
#include "ICursorControl.h"
#import <AppKit/NSWindow.h>
#import <AppKit/NSBitmapImageRep.h>
#include <map>
namespace irr
{
class CIrrDeviceMacOSX;
}
@interface CIrrDelegateOSX : NSObject
- (id)initWithDevice:(irr::CIrrDeviceMacOSX*)device;
- (void)terminate:(id)sender;
- (BOOL)isQuit;
@end
namespace irr
{
class CIrrDeviceMacOSX : public CIrrDeviceStub
{
public:
//! constructor
CIrrDeviceMacOSX(const SIrrlichtCreationParameters& params);
//! destructor
virtual ~CIrrDeviceMacOSX();
//! runs the device. Returns false if device wants to be deleted
bool run() override;
//! Cause the device to temporarily pause execution and let other processes to run
// This should bring down processor usage without major performance loss for Irrlicht
void yield() override;
//! Pause execution and let other processes to run for a specified amount of time.
void sleep(u32 timeMs, bool pauseTimer) override;
//! sets the caption of the window
void setWindowCaption(const wchar_t* text) override;
//! returns if window is active. if not, nothing need to be drawn
bool isWindowActive() const override;
//! Checks if the Irrlicht window has focus
bool isWindowFocused() const override;
//! Checks if the Irrlicht window is minimized
bool isWindowMinimized() const override;
//! notifies the device that it should close itself
void closeDevice() override;
//! Sets if the window should be resizable in windowed mode.
void setResizable(bool resize) override;
//! Returns true if the window is resizable, false if not
virtual bool isResizable() const;
//! Minimizes the window if possible
void minimizeWindow() override;
//! Maximizes the window if possible.
void maximizeWindow() override;
//! Restore the window to normal size if possible.
void restoreWindow() override;
//! Get the position of this window on screen
core::position2di getWindowPosition() override;
//! Activate any joysticks, and generate events for them.
bool activateJoysticks(core::array<SJoystickInfo> & joystickInfo) override;
//! Get the device type
E_DEVICE_TYPE getType() const override
{
return EIDT_OSX;
}
void setMouseLocation(int x, int y);
void setResize(int width, int height);
void setCursorVisible(bool visible);
void setWindow(NSWindow* window);
private:
//! create the driver
void createDriver();
//! Implementation of the macos x cursor control
class CCursorControl : public gui::ICursorControl
{
public:
CCursorControl(const core::dimension2d<u32>& wsize, CIrrDeviceMacOSX *device)
: WindowSize(wsize), InvWindowSize(0.0f, 0.0f), Device(device), IsVisible(true), UseReferenceRect(false)
{
CursorPos.X = CursorPos.Y = 0;
if (WindowSize.Width!=0)
InvWindowSize.Width = 1.0f / WindowSize.Width;
if (WindowSize.Height!=0)
InvWindowSize.Height = 1.0f / WindowSize.Height;
}
//! Changes the visible state of the mouse cursor.
void setVisible(bool visible) override
{
IsVisible = visible;
Device->setCursorVisible(visible);
}
//! Returns if the cursor is currently visible.
bool isVisible() const override
{
return IsVisible;
}
//! Sets the new position of the cursor.
void setPosition(const core::position2d<f32> &pos) override
{
setPosition(pos.X, pos.Y);
}
//! Sets the new position of the cursor.
void setPosition(f32 x, f32 y) override
{
setPosition((s32)(x*WindowSize.Width), (s32)(y*WindowSize.Height));
}
//! Sets the new position of the cursor.
void setPosition(const core::position2d<s32> &pos) override
{
if (CursorPos.X != pos.X || CursorPos.Y != pos.Y)
setPosition(pos.X, pos.Y);
}
//! Sets the new position of the cursor.
void setPosition(s32 x, s32 y) override
{
if (UseReferenceRect)
{
Device->setMouseLocation(ReferenceRect.UpperLeftCorner.X + x, ReferenceRect.UpperLeftCorner.Y + y);
}
else
{
Device->setMouseLocation(x,y);
}
}
//! Returns the current position of the mouse cursor.
const core::position2d<s32>& getPosition(bool updateCursor) override
{
return CursorPos;
}
//! Returns the current position of the mouse cursor.
core::position2d<f32> getRelativePosition(bool updateCursor) override
{
if (!UseReferenceRect)
{
return core::position2d<f32>(CursorPos.X * InvWindowSize.Width,
CursorPos.Y * InvWindowSize.Height);
}
return core::position2d<f32>(CursorPos.X / (f32)ReferenceRect.getWidth(),
CursorPos.Y / (f32)ReferenceRect.getHeight());
}
//! Sets an absolute reference rect for calculating the cursor position.
void setReferenceRect(core::rect<s32>* rect=0) override
{
if (rect)
{
ReferenceRect = *rect;
UseReferenceRect = true;
// prevent division through zero and uneven sizes
if (!ReferenceRect.getHeight() || ReferenceRect.getHeight()%2)
ReferenceRect.LowerRightCorner.Y += 1;
if (!ReferenceRect.getWidth() || ReferenceRect.getWidth()%2)
ReferenceRect.LowerRightCorner.X += 1;
}
else
UseReferenceRect = false;
}
//! Updates the internal cursor position
void updateInternalCursorPosition(int x,int y)
{
CursorPos.X = x;
CursorPos.Y = y;
}
private:
core::position2d<s32> CursorPos;
core::dimension2d<s32> WindowSize;
core::dimension2d<float> InvWindowSize;
core::rect<s32> ReferenceRect;
CIrrDeviceMacOSX *Device;
bool IsVisible;
bool UseReferenceRect;
};
bool createWindow();
void initKeycodes();
void storeMouseLocation();
void postMouseEvent(void *event, irr::SEvent &ievent);
void postKeyEvent(void *event, irr::SEvent &ievent, bool pressed);
void pollJoysticks();
NSWindow* Window;
CGDirectDisplayID Display;
std::map<int,int> KeyCodes;
int DeviceWidth;
int DeviceHeight;
int ScreenWidth;
int ScreenHeight;
u32 MouseButtonStates;
bool IsFullscreen;
bool IsActive;
bool IsShiftDown;
bool IsControlDown;
bool IsResizable;
};
} // end namespace irr
#endif // _IRR_COMPILE_WITH_OSX_DEVICE_
// Copyright (C) 2005-2006 Etienne Petitjean
// Copyright (C) 2007-2012 Christian Stehno
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in Irrlicht.h
#pragma once
#ifdef _IRR_COMPILE_WITH_OSX_DEVICE_
#include "CIrrDeviceStub.h"
#include "IrrlichtDevice.h"
#include "IGUIEnvironment.h"
#include "ICursorControl.h"
#import <AppKit/NSWindow.h>
#import <AppKit/NSBitmapImageRep.h>
#include <map>
namespace irr
{
class CIrrDeviceMacOSX;
}
@interface CIrrDelegateOSX : NSObject
- (id)initWithDevice:(irr::CIrrDeviceMacOSX*)device;
- (void)terminate:(id)sender;
- (BOOL)isQuit;
@end
namespace irr
{
class CIrrDeviceMacOSX : public CIrrDeviceStub
{
public:
//! constructor
CIrrDeviceMacOSX(const SIrrlichtCreationParameters& params);
//! destructor
virtual ~CIrrDeviceMacOSX();
//! runs the device. Returns false if device wants to be deleted
bool run() override;
//! Cause the device to temporarily pause execution and let other processes to run
// This should bring down processor usage without major performance loss for Irrlicht
void yield() override;
//! Pause execution and let other processes to run for a specified amount of time.
void sleep(u32 timeMs, bool pauseTimer) override;
//! sets the caption of the window
void setWindowCaption(const wchar_t* text) override;
//! returns if window is active. if not, nothing need to be drawn
bool isWindowActive() const override;
//! Checks if the Irrlicht window has focus
bool isWindowFocused() const override;
//! Checks if the Irrlicht window is minimized
bool isWindowMinimized() const override;
//! notifies the device that it should close itself
void closeDevice() override;
//! Sets if the window should be resizable in windowed mode.
void setResizable(bool resize) override;
//! Returns true if the window is resizable, false if not
virtual bool isResizable() const;
//! Minimizes the window if possible
void minimizeWindow() override;
//! Maximizes the window if possible.
void maximizeWindow() override;
//! Restore the window to normal size if possible.
void restoreWindow() override;
//! Get the position of this window on screen
core::position2di getWindowPosition() override;
//! Activate any joysticks, and generate events for them.
bool activateJoysticks(core::array<SJoystickInfo> & joystickInfo) override;
//! Get the device type
E_DEVICE_TYPE getType() const override
{
return EIDT_OSX;
}
void setMouseLocation(int x, int y);
void setResize(int width, int height);
void setCursorVisible(bool visible);
void setWindow(NSWindow* window);
private:
//! create the driver
void createDriver();
//! Implementation of the macos x cursor control
class CCursorControl : public gui::ICursorControl
{
public:
CCursorControl(const core::dimension2d<u32>& wsize, CIrrDeviceMacOSX *device)
: WindowSize(wsize), InvWindowSize(0.0f, 0.0f), Device(device), IsVisible(true), UseReferenceRect(false)
{
CursorPos.X = CursorPos.Y = 0;
if (WindowSize.Width!=0)
InvWindowSize.Width = 1.0f / WindowSize.Width;
if (WindowSize.Height!=0)
InvWindowSize.Height = 1.0f / WindowSize.Height;
}
//! Changes the visible state of the mouse cursor.
void setVisible(bool visible) override
{
IsVisible = visible;
Device->setCursorVisible(visible);
}
//! Returns if the cursor is currently visible.
bool isVisible() const override
{
return IsVisible;
}
//! Sets the new position of the cursor.
void setPosition(const core::position2d<f32> &pos) override
{
setPosition(pos.X, pos.Y);
}
//! Sets the new position of the cursor.
void setPosition(f32 x, f32 y) override
{
setPosition((s32)(x*WindowSize.Width), (s32)(y*WindowSize.Height));
}
//! Sets the new position of the cursor.
void setPosition(const core::position2d<s32> &pos) override
{
if (CursorPos.X != pos.X || CursorPos.Y != pos.Y)
setPosition(pos.X, pos.Y);
}
//! Sets the new position of the cursor.
void setPosition(s32 x, s32 y) override
{
if (UseReferenceRect)
{
Device->setMouseLocation(ReferenceRect.UpperLeftCorner.X + x, ReferenceRect.UpperLeftCorner.Y + y);
}
else
{
Device->setMouseLocation(x,y);
}
}
//! Returns the current position of the mouse cursor.
const core::position2d<s32>& getPosition(bool updateCursor) override
{
return CursorPos;
}
//! Returns the current position of the mouse cursor.
core::position2d<f32> getRelativePosition(bool updateCursor) override
{
if (!UseReferenceRect)
{
return core::position2d<f32>(CursorPos.X * InvWindowSize.Width,
CursorPos.Y * InvWindowSize.Height);
}
return core::position2d<f32>(CursorPos.X / (f32)ReferenceRect.getWidth(),
CursorPos.Y / (f32)ReferenceRect.getHeight());
}
//! Sets an absolute reference rect for calculating the cursor position.
void setReferenceRect(core::rect<s32>* rect=0) override
{
if (rect)
{
ReferenceRect = *rect;
UseReferenceRect = true;
// prevent division through zero and uneven sizes
if (!ReferenceRect.getHeight() || ReferenceRect.getHeight()%2)
ReferenceRect.LowerRightCorner.Y += 1;
if (!ReferenceRect.getWidth() || ReferenceRect.getWidth()%2)
ReferenceRect.LowerRightCorner.X += 1;
}
else
UseReferenceRect = false;
}
//! Updates the internal cursor position
void updateInternalCursorPosition(int x,int y)
{
CursorPos.X = x;
CursorPos.Y = y;
}
private:
core::position2d<s32> CursorPos;
core::dimension2d<s32> WindowSize;
core::dimension2d<float> InvWindowSize;
core::rect<s32> ReferenceRect;
CIrrDeviceMacOSX *Device;
bool IsVisible;
bool UseReferenceRect;
};
bool createWindow();
void initKeycodes();
void storeMouseLocation();
void postMouseEvent(void *event, irr::SEvent &ievent);
void postKeyEvent(void *event, irr::SEvent &ievent, bool pressed);
void pollJoysticks();
NSWindow* Window;
CGDirectDisplayID Display;
std::map<int,int> KeyCodes;
int DeviceWidth;
int DeviceHeight;
int ScreenWidth;
int ScreenHeight;
u32 MouseButtonStates;
bool IsFullscreen;
bool IsActive;
bool IsShiftDown;
bool IsControlDown;
bool IsResizable;
};
} // end namespace irr
#endif // _IRR_COMPILE_WITH_OSX_DEVICE_

View File

@ -471,12 +471,12 @@ static bool firstLaunch = true;
- (id)initWithDevice:(irr::CIrrDeviceMacOSX*)device
{
self = [super init];
if (self)
Device = device;
Quit = false;
return (self);
}
@ -528,7 +528,7 @@ static bool firstLaunch = true;
{
NSWindow *window;
NSRect frame;
window = [aNotification object];
frame = [window frame];
Device->setResize((int)frame.size.width,(int)frame.size.height);
@ -646,15 +646,15 @@ bool CIrrDeviceMacOSX::createWindow()
CGDisplayErr error;
bool result = false;
Display = CGMainDisplayID();
CGRect displayRect;
CGDisplayModeRef displaymode, olddisplaymode;
ScreenWidth = (int)CGDisplayPixelsWide(Display);
ScreenHeight = (int)CGDisplayPixelsHigh(Display);
const NSBackingStoreType type = (CreationParams.DriverType == video::EDT_OPENGL) ? NSBackingStoreBuffered : NSBackingStoreNonretained;
// TODO: fullscreen
//if (!CreationParams.Fullscreen)
{
@ -662,25 +662,25 @@ bool CIrrDeviceMacOSX::createWindow()
{
int x = (CreationParams.WindowPosition.X > 0) ? CreationParams.WindowPosition.X : 0;
int y = (CreationParams.WindowPosition.Y > 0) ? CreationParams.WindowPosition.Y : 0;
if (CreationParams.WindowPosition.Y > -1)
{
int screenHeight = [[[NSScreen screens] objectAtIndex:0] frame].size.height;
y = screenHeight - y - CreationParams.WindowSize.Height;
}
Window = [[NSWindow alloc] initWithContentRect:NSMakeRect(x, y, CreationParams.WindowSize.Width,CreationParams.WindowSize.Height) styleMask:NSTitledWindowMask+NSClosableWindowMask+NSResizableWindowMask backing:type defer:FALSE];
if (CreationParams.WindowPosition.X == -1 && CreationParams.WindowPosition.Y == -1)
[Window center];
}
DeviceWidth = CreationParams.WindowSize.Width;
DeviceHeight = CreationParams.WindowSize.Height;
result = true;
}
if (result)
{
if (Window)
@ -691,7 +691,7 @@ bool CIrrDeviceMacOSX::createWindow()
[Window makeKeyAndOrderFront:nil];
}
}
return result;
}
@ -706,7 +706,7 @@ void CIrrDeviceMacOSX::setResize(int width, int height)
if (CreationParams.DriverType == video::EDT_OPENGL)
{
NSOpenGLContext* Context = (NSOpenGLContext*)ContextManager->getContext().OpenGLOSX.Context;
if (Context)
[Context update];
}
@ -741,13 +741,13 @@ void CIrrDeviceMacOSX::createDriver()
{
os::Printer::log("Could not create OpenGL driver.", ELL_ERROR);
}
if (Window)
if (Window)
{
[[Window contentView] setWantsBestResolutionOpenGLSurface:NO];
[(NSOpenGLContext*)ContextManager->getContext().OpenGLOSX.Context setView:[Window contentView]];
}
else
else
{
[(NSView*)CreationParams.WindowId setWantsBestResolutionOpenGLSurface:NO];
[(NSOpenGLContext*)ContextManager->getContext().OpenGLOSX.Context setView:(NSView*)CreationParams.WindowId];
@ -1082,7 +1082,7 @@ void CIrrDeviceMacOSX::postMouseEvent(void *event,irr::SEvent &ievent)
{
ievent.MouseInput.Shift = ([(NSEvent *)event modifierFlags] & NSShiftKeyMask) != 0;
ievent.MouseInput.Control = ([(NSEvent *)event modifierFlags] & NSControlKeyMask) != 0;
postEventFromUser(ievent);
}
@ -1162,8 +1162,8 @@ void CIrrDeviceMacOSX::setCursorVisible(bool visible)
else
CGDisplayHideCursor(CGMainDisplayID());
}
void CIrrDeviceMacOSX::setWindow(NSWindow* window)
{
Window = window;
@ -1326,7 +1326,7 @@ void CIrrDeviceMacOSX::restoreWindow()
{
[Window deminiaturize:[NSApp self]];
}
//! Get the position of this window on screen
core::position2di CIrrDeviceMacOSX::getWindowPosition()
{

File diff suppressed because it is too large Load Diff

View File

@ -1,325 +1,325 @@
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
// This device code is based on the original SDL device implementation
// contributed by Shane Parker (sirshane).
#pragma once
#ifdef _IRR_COMPILE_WITH_SDL_DEVICE_
#include "IrrlichtDevice.h"
#include "CIrrDeviceStub.h"
#include "ICursorControl.h"
#ifdef _IRR_EMSCRIPTEN_PLATFORM_
#include <emscripten/html5.h>
#endif
#include <SDL.h>
#include <SDL_syswm.h>
#include <memory>
namespace irr
{
class CIrrDeviceSDL : public CIrrDeviceStub
{
public:
//! constructor
CIrrDeviceSDL(const SIrrlichtCreationParameters& param);
//! destructor
virtual ~CIrrDeviceSDL();
//! runs the device. Returns false if device wants to be deleted
bool run() override;
//! pause execution temporarily
void yield() override;
//! pause execution for a specified time
void sleep(u32 timeMs, bool pauseTimer) override;
//! sets the caption of the window
void setWindowCaption(const wchar_t* text) override;
//! Sets the window icon.
bool setWindowIcon(const video::IImage *img) override;
//! returns if window is active. if not, nothing need to be drawn
bool isWindowActive() const override;
//! returns if window has focus.
bool isWindowFocused() const override;
//! returns if window is minimized.
bool isWindowMinimized() const override;
//! returns color format of the window.
video::ECOLOR_FORMAT getColorFormat() const override;
//! notifies the device that it should close itself
void closeDevice() override;
//! Sets if the window should be resizable in windowed mode.
void setResizable(bool resize=false) override;
//! Minimizes the window.
void minimizeWindow() override;
//! Maximizes the window.
void maximizeWindow() override;
//! Restores the window size.
void restoreWindow() override;
//! Checks if the window is maximized.
bool isWindowMaximized() const override;
//! Checks if the Irrlicht window is running in fullscreen mode
/** \return True if window is fullscreen. */
bool isFullscreen() const override;
//! Get the position of this window on screen
core::position2di getWindowPosition() override;
//! Activate any joysticks, and generate events for them.
bool activateJoysticks(core::array<SJoystickInfo> & joystickInfo) override;
//! Get the device type
E_DEVICE_TYPE getType() const override
{
return EIDT_SDL;
}
//! Get the display density in dots per inch.
float getDisplayDensity() const override;
void SwapWindow();
//! Implementation of the linux cursor control
class CCursorControl : public gui::ICursorControl
{
public:
CCursorControl(CIrrDeviceSDL* dev)
: Device(dev), IsVisible(true)
{
initCursors();
}
//! Changes the visible state of the mouse cursor.
void setVisible(bool visible) override
{
IsVisible = visible;
if ( visible )
SDL_ShowCursor( SDL_ENABLE );
else
{
SDL_ShowCursor( SDL_DISABLE );
}
}
//! Returns if the cursor is currently visible.
bool isVisible() const override
{
return IsVisible;
}
//! Sets the new position of the cursor.
void setPosition(const core::position2d<f32> &pos) override
{
setPosition(pos.X, pos.Y);
}
//! Sets the new position of the cursor.
void setPosition(f32 x, f32 y) override
{
setPosition((s32)(x*Device->Width), (s32)(y*Device->Height));
}
//! Sets the new position of the cursor.
void setPosition(const core::position2d<s32> &pos) override
{
setPosition(pos.X, pos.Y);
}
//! Sets the new position of the cursor.
void setPosition(s32 x, s32 y) override
{
SDL_WarpMouseInWindow(Device->Window, x, y);
if (SDL_GetRelativeMouseMode()) {
// There won't be an event for this warp (details on libsdl-org/SDL/issues/6034)
Device->MouseX = x;
Device->MouseY = y;
}
}
//! Returns the current position of the mouse cursor.
const core::position2d<s32>& getPosition(bool updateCursor) override
{
if ( updateCursor )
updateCursorPos();
return CursorPos;
}
//! Returns the current position of the mouse cursor.
core::position2d<f32> getRelativePosition(bool updateCursor) override
{
if ( updateCursor )
updateCursorPos();
return core::position2d<f32>(CursorPos.X / (f32)Device->Width,
CursorPos.Y / (f32)Device->Height);
}
void setReferenceRect(core::rect<s32>* rect=0) override
{
}
virtual void setRelativeMode(bool relative) _IRR_OVERRIDE_
{
// Only change it when necessary, as it flushes mouse motion when enabled
if ( relative != SDL_GetRelativeMouseMode()) {
if ( relative )
SDL_SetRelativeMouseMode( SDL_TRUE );
else
SDL_SetRelativeMouseMode( SDL_FALSE );
}
}
void setActiveIcon(gui::ECURSOR_ICON iconId) override
{
ActiveIcon = iconId;
if (iconId > Cursors.size() || !Cursors[iconId]) {
iconId = gui::ECI_NORMAL;
if (iconId > Cursors.size() || !Cursors[iconId])
return;
}
SDL_SetCursor(Cursors[iconId].get());
}
gui::ECURSOR_ICON getActiveIcon() const override
{
return ActiveIcon;
}
private:
void updateCursorPos()
{
#ifdef _IRR_EMSCRIPTEN_PLATFORM_
EmscriptenPointerlockChangeEvent pointerlockStatus; // let's hope that test is not expensive ...
if ( emscripten_get_pointerlock_status(&pointerlockStatus) == EMSCRIPTEN_RESULT_SUCCESS )
{
if ( pointerlockStatus.isActive )
{
CursorPos.X += Device->MouseXRel;
CursorPos.Y += Device->MouseYRel;
Device->MouseXRel = 0;
Device->MouseYRel = 0;
}
else
{
CursorPos.X = Device->MouseX;
CursorPos.Y = Device->MouseY;
}
}
#else
CursorPos.X = Device->MouseX;
CursorPos.Y = Device->MouseY;
if (CursorPos.X < 0)
CursorPos.X = 0;
if (CursorPos.X > (s32)Device->Width)
CursorPos.X = Device->Width;
if (CursorPos.Y < 0)
CursorPos.Y = 0;
if (CursorPos.Y > (s32)Device->Height)
CursorPos.Y = Device->Height;
#endif
}
void initCursors();
CIrrDeviceSDL* Device;
core::position2d<s32> CursorPos;
bool IsVisible;
struct CursorDeleter {
void operator()(SDL_Cursor *ptr) {
if (ptr)
SDL_FreeCursor(ptr);
}
};
std::vector<std::unique_ptr<SDL_Cursor, CursorDeleter>> Cursors;
gui::ECURSOR_ICON ActiveIcon;
};
private:
#ifdef _IRR_EMSCRIPTEN_PLATFORM_
static EM_BOOL MouseUpDownCallback(int eventType, const EmscriptenMouseEvent * event, void* userData);
static EM_BOOL MouseEnterCallback(int eventType, const EmscriptenMouseEvent *mouseEvent, void *userData);
static EM_BOOL MouseLeaveCallback(int eventType, const EmscriptenMouseEvent *mouseEvent, void *userData);
#endif
// Check if a key is a known special character with no side effects on text boxes.
static bool keyIsKnownSpecial(EKEY_CODE key);
// Return the Char that should be sent to Irrlicht for the given key (either the one passed in or 0).
static int findCharToPassToIrrlicht(int assumedChar, EKEY_CODE key);
// Check if a text box is in focus. Enable or disable SDL_TEXTINPUT events only if in focus.
void resetReceiveTextInputEvents();
//! create the driver
void createDriver();
bool createWindow();
void createKeyMap();
void logAttributes();
SDL_GLContext Context;
SDL_Window *Window;
int SDL_Flags;
#if defined(_IRR_COMPILE_WITH_JOYSTICK_EVENTS_)
core::array<SDL_Joystick*> Joysticks;
#endif
s32 MouseX, MouseY;
s32 MouseXRel, MouseYRel;
u32 MouseButtonStates;
u32 Width, Height;
bool Resizable;
struct SKeyMap
{
SKeyMap() {}
SKeyMap(s32 x11, s32 win32)
: SDLKey(x11), Win32Key(win32)
{
}
s32 SDLKey;
s32 Win32Key;
bool operator<(const SKeyMap& o) const
{
return SDLKey<o.SDLKey;
}
};
core::array<SKeyMap> KeyMap;
SDL_SysWMinfo Info;
};
} // end namespace irr
#endif // _IRR_COMPILE_WITH_SDL_DEVICE_
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
// This device code is based on the original SDL device implementation
// contributed by Shane Parker (sirshane).
#pragma once
#ifdef _IRR_COMPILE_WITH_SDL_DEVICE_
#include "IrrlichtDevice.h"
#include "CIrrDeviceStub.h"
#include "ICursorControl.h"
#ifdef _IRR_EMSCRIPTEN_PLATFORM_
#include <emscripten/html5.h>
#endif
#include <SDL.h>
#include <SDL_syswm.h>
#include <memory>
namespace irr
{
class CIrrDeviceSDL : public CIrrDeviceStub
{
public:
//! constructor
CIrrDeviceSDL(const SIrrlichtCreationParameters& param);
//! destructor
virtual ~CIrrDeviceSDL();
//! runs the device. Returns false if device wants to be deleted
bool run() override;
//! pause execution temporarily
void yield() override;
//! pause execution for a specified time
void sleep(u32 timeMs, bool pauseTimer) override;
//! sets the caption of the window
void setWindowCaption(const wchar_t* text) override;
//! Sets the window icon.
bool setWindowIcon(const video::IImage *img) override;
//! returns if window is active. if not, nothing need to be drawn
bool isWindowActive() const override;
//! returns if window has focus.
bool isWindowFocused() const override;
//! returns if window is minimized.
bool isWindowMinimized() const override;
//! returns color format of the window.
video::ECOLOR_FORMAT getColorFormat() const override;
//! notifies the device that it should close itself
void closeDevice() override;
//! Sets if the window should be resizable in windowed mode.
void setResizable(bool resize=false) override;
//! Minimizes the window.
void minimizeWindow() override;
//! Maximizes the window.
void maximizeWindow() override;
//! Restores the window size.
void restoreWindow() override;
//! Checks if the window is maximized.
bool isWindowMaximized() const override;
//! Checks if the Irrlicht window is running in fullscreen mode
/** \return True if window is fullscreen. */
bool isFullscreen() const override;
//! Get the position of this window on screen
core::position2di getWindowPosition() override;
//! Activate any joysticks, and generate events for them.
bool activateJoysticks(core::array<SJoystickInfo> & joystickInfo) override;
//! Get the device type
E_DEVICE_TYPE getType() const override
{
return EIDT_SDL;
}
//! Get the display density in dots per inch.
float getDisplayDensity() const override;
void SwapWindow();
//! Implementation of the linux cursor control
class CCursorControl : public gui::ICursorControl
{
public:
CCursorControl(CIrrDeviceSDL* dev)
: Device(dev), IsVisible(true)
{
initCursors();
}
//! Changes the visible state of the mouse cursor.
void setVisible(bool visible) override
{
IsVisible = visible;
if ( visible )
SDL_ShowCursor( SDL_ENABLE );
else
{
SDL_ShowCursor( SDL_DISABLE );
}
}
//! Returns if the cursor is currently visible.
bool isVisible() const override
{
return IsVisible;
}
//! Sets the new position of the cursor.
void setPosition(const core::position2d<f32> &pos) override
{
setPosition(pos.X, pos.Y);
}
//! Sets the new position of the cursor.
void setPosition(f32 x, f32 y) override
{
setPosition((s32)(x*Device->Width), (s32)(y*Device->Height));
}
//! Sets the new position of the cursor.
void setPosition(const core::position2d<s32> &pos) override
{
setPosition(pos.X, pos.Y);
}
//! Sets the new position of the cursor.
void setPosition(s32 x, s32 y) override
{
SDL_WarpMouseInWindow(Device->Window, x, y);
if (SDL_GetRelativeMouseMode()) {
// There won't be an event for this warp (details on libsdl-org/SDL/issues/6034)
Device->MouseX = x;
Device->MouseY = y;
}
}
//! Returns the current position of the mouse cursor.
const core::position2d<s32>& getPosition(bool updateCursor) override
{
if ( updateCursor )
updateCursorPos();
return CursorPos;
}
//! Returns the current position of the mouse cursor.
core::position2d<f32> getRelativePosition(bool updateCursor) override
{
if ( updateCursor )
updateCursorPos();
return core::position2d<f32>(CursorPos.X / (f32)Device->Width,
CursorPos.Y / (f32)Device->Height);
}
void setReferenceRect(core::rect<s32>* rect=0) override
{
}
virtual void setRelativeMode(bool relative) _IRR_OVERRIDE_
{
// Only change it when necessary, as it flushes mouse motion when enabled
if ( relative != SDL_GetRelativeMouseMode()) {
if ( relative )
SDL_SetRelativeMouseMode( SDL_TRUE );
else
SDL_SetRelativeMouseMode( SDL_FALSE );
}
}
void setActiveIcon(gui::ECURSOR_ICON iconId) override
{
ActiveIcon = iconId;
if (iconId > Cursors.size() || !Cursors[iconId]) {
iconId = gui::ECI_NORMAL;
if (iconId > Cursors.size() || !Cursors[iconId])
return;
}
SDL_SetCursor(Cursors[iconId].get());
}
gui::ECURSOR_ICON getActiveIcon() const override
{
return ActiveIcon;
}
private:
void updateCursorPos()
{
#ifdef _IRR_EMSCRIPTEN_PLATFORM_
EmscriptenPointerlockChangeEvent pointerlockStatus; // let's hope that test is not expensive ...
if ( emscripten_get_pointerlock_status(&pointerlockStatus) == EMSCRIPTEN_RESULT_SUCCESS )
{
if ( pointerlockStatus.isActive )
{
CursorPos.X += Device->MouseXRel;
CursorPos.Y += Device->MouseYRel;
Device->MouseXRel = 0;
Device->MouseYRel = 0;
}
else
{
CursorPos.X = Device->MouseX;
CursorPos.Y = Device->MouseY;
}
}
#else
CursorPos.X = Device->MouseX;
CursorPos.Y = Device->MouseY;
if (CursorPos.X < 0)
CursorPos.X = 0;
if (CursorPos.X > (s32)Device->Width)
CursorPos.X = Device->Width;
if (CursorPos.Y < 0)
CursorPos.Y = 0;
if (CursorPos.Y > (s32)Device->Height)
CursorPos.Y = Device->Height;
#endif
}
void initCursors();
CIrrDeviceSDL* Device;
core::position2d<s32> CursorPos;
bool IsVisible;
struct CursorDeleter {
void operator()(SDL_Cursor *ptr) {
if (ptr)
SDL_FreeCursor(ptr);
}
};
std::vector<std::unique_ptr<SDL_Cursor, CursorDeleter>> Cursors;
gui::ECURSOR_ICON ActiveIcon;
};
private:
#ifdef _IRR_EMSCRIPTEN_PLATFORM_
static EM_BOOL MouseUpDownCallback(int eventType, const EmscriptenMouseEvent * event, void* userData);
static EM_BOOL MouseEnterCallback(int eventType, const EmscriptenMouseEvent *mouseEvent, void *userData);
static EM_BOOL MouseLeaveCallback(int eventType, const EmscriptenMouseEvent *mouseEvent, void *userData);
#endif
// Check if a key is a known special character with no side effects on text boxes.
static bool keyIsKnownSpecial(EKEY_CODE key);
// Return the Char that should be sent to Irrlicht for the given key (either the one passed in or 0).
static int findCharToPassToIrrlicht(int assumedChar, EKEY_CODE key);
// Check if a text box is in focus. Enable or disable SDL_TEXTINPUT events only if in focus.
void resetReceiveTextInputEvents();
//! create the driver
void createDriver();
bool createWindow();
void createKeyMap();
void logAttributes();
SDL_GLContext Context;
SDL_Window *Window;
int SDL_Flags;
#if defined(_IRR_COMPILE_WITH_JOYSTICK_EVENTS_)
core::array<SDL_Joystick*> Joysticks;
#endif
s32 MouseX, MouseY;
s32 MouseXRel, MouseYRel;
u32 MouseButtonStates;
u32 Width, Height;
bool Resizable;
struct SKeyMap
{
SKeyMap() {}
SKeyMap(s32 x11, s32 win32)
: SDLKey(x11), Win32Key(win32)
{
}
s32 SDLKey;
s32 Win32Key;
bool operator<(const SKeyMap& o) const
{
return SDLKey<o.SDLKey;
}
};
core::array<SKeyMap> KeyMap;
SDL_SysWMinfo Info;
};
} // end namespace irr
#endif // _IRR_COMPILE_WITH_SDL_DEVICE_

View File

@ -1,412 +1,412 @@
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#include "CIrrDeviceStub.h"
#include "ISceneManager.h"
#include "IEventReceiver.h"
#include "IFileSystem.h"
#include "IGUIElement.h"
#include "IGUIEnvironment.h"
#include "os.h"
#include "CTimer.h"
#include "CLogger.h"
#include "irrString.h"
#include "IrrCompileConfig.h" // for IRRLICHT_SDK_VERSION
namespace irr
{
//! constructor
CIrrDeviceStub::CIrrDeviceStub(const SIrrlichtCreationParameters& params)
: IrrlichtDevice(), VideoDriver(0), GUIEnvironment(0), SceneManager(0),
Timer(0), CursorControl(0), UserReceiver(params.EventReceiver),
Logger(0), Operator(0), FileSystem(0),
InputReceivingSceneManager(0), ContextManager(0),
CreationParams(params), Close(false)
{
Timer = new CTimer();
if (os::Printer::Logger)
{
os::Printer::Logger->grab();
Logger = (CLogger*)os::Printer::Logger;
Logger->setReceiver(UserReceiver);
}
else
{
Logger = new CLogger(UserReceiver);
os::Printer::Logger = Logger;
}
Logger->setLogLevel(CreationParams.LoggingLevel);
os::Printer::Logger = Logger;
FileSystem = io::createFileSystem();
core::stringc s = "Irrlicht Engine version ";
s.append(getVersion());
os::Printer::log(s.c_str(), ELL_INFORMATION);
checkVersion(params.SDK_version_do_not_use);
}
CIrrDeviceStub::~CIrrDeviceStub()
{
if (GUIEnvironment)
GUIEnvironment->drop();
if (SceneManager)
SceneManager->drop();
if (VideoDriver)
VideoDriver->drop();
if (ContextManager)
ContextManager->drop();
if ( FileSystem )
FileSystem->drop();
if (InputReceivingSceneManager)
InputReceivingSceneManager->drop();
if (CursorControl)
CursorControl->drop();
if (Operator)
Operator->drop();
CursorControl = 0;
if (Timer)
Timer->drop();
if (Logger->drop())
os::Printer::Logger = 0;
}
void CIrrDeviceStub::createGUIAndScene()
{
// create gui environment
GUIEnvironment = gui::createGUIEnvironment(FileSystem, VideoDriver, Operator);
// create Scene manager
SceneManager = scene::createSceneManager(VideoDriver, CursorControl);
setEventReceiver(UserReceiver);
}
//! returns the video driver
video::IVideoDriver* CIrrDeviceStub::getVideoDriver()
{
return VideoDriver;
}
//! return file system
io::IFileSystem* CIrrDeviceStub::getFileSystem()
{
return FileSystem;
}
//! returns the gui environment
gui::IGUIEnvironment* CIrrDeviceStub::getGUIEnvironment()
{
return GUIEnvironment;
}
//! returns the scene manager
scene::ISceneManager* CIrrDeviceStub::getSceneManager()
{
return SceneManager;
}
//! \return Returns a pointer to the ITimer object. With it the
//! current Time can be received.
ITimer* CIrrDeviceStub::getTimer()
{
return Timer;
}
//! Sets the window icon.
bool CIrrDeviceStub::setWindowIcon(const video::IImage *img)
{
return false;
}
//! Returns the version of the engine.
const char* CIrrDeviceStub::getVersion() const
{
return IRRLICHT_SDK_VERSION;
}
//! \return Returns a pointer to the mouse cursor control interface.
gui::ICursorControl* CIrrDeviceStub::getCursorControl()
{
return CursorControl;
}
//! return the context manager
video::IContextManager* CIrrDeviceStub::getContextManager()
{
return ContextManager;
}
//! checks version of sdk and prints warning if there might be a problem
bool CIrrDeviceStub::checkVersion(const char* version)
{
if (strcmp(getVersion(), version))
{
core::stringc w;
w = "Warning: The library version of the Irrlicht Engine (";
w += getVersion();
w += ") does not match the version the application was compiled with (";
w += version;
w += "). This may cause problems.";
os::Printer::log(w.c_str(), ELL_WARNING);
return false;
}
return true;
}
//! Compares to the last call of this function to return double and triple clicks.
u32 CIrrDeviceStub::checkSuccessiveClicks(s32 mouseX, s32 mouseY, EMOUSE_INPUT_EVENT inputEvent )
{
const s32 MAX_MOUSEMOVE = 3;
irr::u32 clickTime = getTimer()->getRealTime();
if ( (clickTime-MouseMultiClicks.LastClickTime) < MouseMultiClicks.DoubleClickTime
&& core::abs_(MouseMultiClicks.LastClick.X - mouseX ) <= MAX_MOUSEMOVE
&& core::abs_(MouseMultiClicks.LastClick.Y - mouseY ) <= MAX_MOUSEMOVE
&& MouseMultiClicks.CountSuccessiveClicks < 3
&& MouseMultiClicks.LastMouseInputEvent == inputEvent
)
{
++MouseMultiClicks.CountSuccessiveClicks;
}
else
{
MouseMultiClicks.CountSuccessiveClicks = 1;
}
MouseMultiClicks.LastMouseInputEvent = inputEvent;
MouseMultiClicks.LastClickTime = clickTime;
MouseMultiClicks.LastClick.X = mouseX;
MouseMultiClicks.LastClick.Y = mouseY;
return MouseMultiClicks.CountSuccessiveClicks;
}
//! send the event to the right receiver
bool CIrrDeviceStub::postEventFromUser(const SEvent& event)
{
bool absorbed = false;
if (UserReceiver)
absorbed = UserReceiver->OnEvent(event);
if (!absorbed && GUIEnvironment)
absorbed = GUIEnvironment->postEventFromUser(event);
scene::ISceneManager* inputReceiver = InputReceivingSceneManager;
if (!inputReceiver)
inputReceiver = SceneManager;
if (!absorbed && inputReceiver)
absorbed = inputReceiver->postEventFromUser(event);
return absorbed;
}
//! Sets a new event receiver to receive events
void CIrrDeviceStub::setEventReceiver(IEventReceiver* receiver)
{
UserReceiver = receiver;
Logger->setReceiver(receiver);
if (GUIEnvironment)
GUIEnvironment->setUserEventReceiver(receiver);
}
//! Returns poinhter to the current event receiver. Returns 0 if there is none.
IEventReceiver* CIrrDeviceStub::getEventReceiver()
{
return UserReceiver;
}
//! \return Returns a pointer to the logger.
ILogger* CIrrDeviceStub::getLogger()
{
return Logger;
}
//! Returns the operation system opertator object.
IOSOperator* CIrrDeviceStub::getOSOperator()
{
return Operator;
}
//! Sets the input receiving scene manager.
void CIrrDeviceStub::setInputReceivingSceneManager(scene::ISceneManager* sceneManager)
{
if (sceneManager)
sceneManager->grab();
if (InputReceivingSceneManager)
InputReceivingSceneManager->drop();
InputReceivingSceneManager = sceneManager;
}
//! Checks if the window is maximized.
bool CIrrDeviceStub::isWindowMaximized() const
{
return false;
}
//! Checks if the window is running in fullscreen mode
bool CIrrDeviceStub::isFullscreen() const
{
return CreationParams.Fullscreen;
}
//! returns color format
video::ECOLOR_FORMAT CIrrDeviceStub::getColorFormat() const
{
return video::ECF_R5G6B5;
}
//! No-op in this implementation
bool CIrrDeviceStub::activateJoysticks(core::array<SJoystickInfo> & joystickInfo)
{
return false;
}
//! No-op in this implementation
bool CIrrDeviceStub::activateAccelerometer(float updateInterval)
{
return false;
}
//! No-op in this implementation
bool CIrrDeviceStub::deactivateAccelerometer()
{
return false;
}
//! No-op in this implementation
bool CIrrDeviceStub::isAccelerometerActive()
{
return false;
}
//! No-op in this implementation
bool CIrrDeviceStub::isAccelerometerAvailable()
{
return false;
}
//! No-op in this implementation
bool CIrrDeviceStub::activateGyroscope(float updateInterval)
{
return false;
}
//! No-op in this implementation
bool CIrrDeviceStub::deactivateGyroscope()
{
return false;
}
//! No-op in this implementation
bool CIrrDeviceStub::isGyroscopeActive()
{
return false;
}
//! No-op in this implementation
bool CIrrDeviceStub::isGyroscopeAvailable()
{
return false;
}
//! No-op in this implementation
bool CIrrDeviceStub::activateDeviceMotion(float updateInterval)
{
return false;
}
//! No-op in this implementation
bool CIrrDeviceStub::deactivateDeviceMotion()
{
return false;
}
//! No-op in this implementation
bool CIrrDeviceStub::isDeviceMotionActive()
{
return false;
}
//! No-op in this implementation
bool CIrrDeviceStub::isDeviceMotionAvailable()
{
return false;
}
//! Set the maximal elapsed time between 2 clicks to generate doubleclicks for the mouse. It also affects tripleclick behavior.
void CIrrDeviceStub::setDoubleClickTime( u32 timeMs )
{
MouseMultiClicks.DoubleClickTime = timeMs;
}
//! Get the maximal elapsed time between 2 clicks to generate double- and tripleclicks for the mouse.
u32 CIrrDeviceStub::getDoubleClickTime() const
{
return MouseMultiClicks.DoubleClickTime;
}
//! Remove all messages pending in the system message loop
void CIrrDeviceStub::clearSystemMessages()
{
}
//! Get the display density in dots per inch.
float CIrrDeviceStub::getDisplayDensity() const
{
return 0.0f;
}
//! Checks whether the input device should take input from the IME
bool CIrrDeviceStub::acceptsIME()
{
if (!GUIEnvironment)
return false;
gui::IGUIElement *elem = GUIEnvironment->getFocus();
return elem && elem->acceptsIME();
}
} // end namespace irr
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#include "CIrrDeviceStub.h"
#include "ISceneManager.h"
#include "IEventReceiver.h"
#include "IFileSystem.h"
#include "IGUIElement.h"
#include "IGUIEnvironment.h"
#include "os.h"
#include "CTimer.h"
#include "CLogger.h"
#include "irrString.h"
#include "IrrCompileConfig.h" // for IRRLICHT_SDK_VERSION
namespace irr
{
//! constructor
CIrrDeviceStub::CIrrDeviceStub(const SIrrlichtCreationParameters& params)
: IrrlichtDevice(), VideoDriver(0), GUIEnvironment(0), SceneManager(0),
Timer(0), CursorControl(0), UserReceiver(params.EventReceiver),
Logger(0), Operator(0), FileSystem(0),
InputReceivingSceneManager(0), ContextManager(0),
CreationParams(params), Close(false)
{
Timer = new CTimer();
if (os::Printer::Logger)
{
os::Printer::Logger->grab();
Logger = (CLogger*)os::Printer::Logger;
Logger->setReceiver(UserReceiver);
}
else
{
Logger = new CLogger(UserReceiver);
os::Printer::Logger = Logger;
}
Logger->setLogLevel(CreationParams.LoggingLevel);
os::Printer::Logger = Logger;
FileSystem = io::createFileSystem();
core::stringc s = "Irrlicht Engine version ";
s.append(getVersion());
os::Printer::log(s.c_str(), ELL_INFORMATION);
checkVersion(params.SDK_version_do_not_use);
}
CIrrDeviceStub::~CIrrDeviceStub()
{
if (GUIEnvironment)
GUIEnvironment->drop();
if (SceneManager)
SceneManager->drop();
if (VideoDriver)
VideoDriver->drop();
if (ContextManager)
ContextManager->drop();
if ( FileSystem )
FileSystem->drop();
if (InputReceivingSceneManager)
InputReceivingSceneManager->drop();
if (CursorControl)
CursorControl->drop();
if (Operator)
Operator->drop();
CursorControl = 0;
if (Timer)
Timer->drop();
if (Logger->drop())
os::Printer::Logger = 0;
}
void CIrrDeviceStub::createGUIAndScene()
{
// create gui environment
GUIEnvironment = gui::createGUIEnvironment(FileSystem, VideoDriver, Operator);
// create Scene manager
SceneManager = scene::createSceneManager(VideoDriver, CursorControl);
setEventReceiver(UserReceiver);
}
//! returns the video driver
video::IVideoDriver* CIrrDeviceStub::getVideoDriver()
{
return VideoDriver;
}
//! return file system
io::IFileSystem* CIrrDeviceStub::getFileSystem()
{
return FileSystem;
}
//! returns the gui environment
gui::IGUIEnvironment* CIrrDeviceStub::getGUIEnvironment()
{
return GUIEnvironment;
}
//! returns the scene manager
scene::ISceneManager* CIrrDeviceStub::getSceneManager()
{
return SceneManager;
}
//! \return Returns a pointer to the ITimer object. With it the
//! current Time can be received.
ITimer* CIrrDeviceStub::getTimer()
{
return Timer;
}
//! Sets the window icon.
bool CIrrDeviceStub::setWindowIcon(const video::IImage *img)
{
return false;
}
//! Returns the version of the engine.
const char* CIrrDeviceStub::getVersion() const
{
return IRRLICHT_SDK_VERSION;
}
//! \return Returns a pointer to the mouse cursor control interface.
gui::ICursorControl* CIrrDeviceStub::getCursorControl()
{
return CursorControl;
}
//! return the context manager
video::IContextManager* CIrrDeviceStub::getContextManager()
{
return ContextManager;
}
//! checks version of sdk and prints warning if there might be a problem
bool CIrrDeviceStub::checkVersion(const char* version)
{
if (strcmp(getVersion(), version))
{
core::stringc w;
w = "Warning: The library version of the Irrlicht Engine (";
w += getVersion();
w += ") does not match the version the application was compiled with (";
w += version;
w += "). This may cause problems.";
os::Printer::log(w.c_str(), ELL_WARNING);
return false;
}
return true;
}
//! Compares to the last call of this function to return double and triple clicks.
u32 CIrrDeviceStub::checkSuccessiveClicks(s32 mouseX, s32 mouseY, EMOUSE_INPUT_EVENT inputEvent )
{
const s32 MAX_MOUSEMOVE = 3;
irr::u32 clickTime = getTimer()->getRealTime();
if ( (clickTime-MouseMultiClicks.LastClickTime) < MouseMultiClicks.DoubleClickTime
&& core::abs_(MouseMultiClicks.LastClick.X - mouseX ) <= MAX_MOUSEMOVE
&& core::abs_(MouseMultiClicks.LastClick.Y - mouseY ) <= MAX_MOUSEMOVE
&& MouseMultiClicks.CountSuccessiveClicks < 3
&& MouseMultiClicks.LastMouseInputEvent == inputEvent
)
{
++MouseMultiClicks.CountSuccessiveClicks;
}
else
{
MouseMultiClicks.CountSuccessiveClicks = 1;
}
MouseMultiClicks.LastMouseInputEvent = inputEvent;
MouseMultiClicks.LastClickTime = clickTime;
MouseMultiClicks.LastClick.X = mouseX;
MouseMultiClicks.LastClick.Y = mouseY;
return MouseMultiClicks.CountSuccessiveClicks;
}
//! send the event to the right receiver
bool CIrrDeviceStub::postEventFromUser(const SEvent& event)
{
bool absorbed = false;
if (UserReceiver)
absorbed = UserReceiver->OnEvent(event);
if (!absorbed && GUIEnvironment)
absorbed = GUIEnvironment->postEventFromUser(event);
scene::ISceneManager* inputReceiver = InputReceivingSceneManager;
if (!inputReceiver)
inputReceiver = SceneManager;
if (!absorbed && inputReceiver)
absorbed = inputReceiver->postEventFromUser(event);
return absorbed;
}
//! Sets a new event receiver to receive events
void CIrrDeviceStub::setEventReceiver(IEventReceiver* receiver)
{
UserReceiver = receiver;
Logger->setReceiver(receiver);
if (GUIEnvironment)
GUIEnvironment->setUserEventReceiver(receiver);
}
//! Returns poinhter to the current event receiver. Returns 0 if there is none.
IEventReceiver* CIrrDeviceStub::getEventReceiver()
{
return UserReceiver;
}
//! \return Returns a pointer to the logger.
ILogger* CIrrDeviceStub::getLogger()
{
return Logger;
}
//! Returns the operation system opertator object.
IOSOperator* CIrrDeviceStub::getOSOperator()
{
return Operator;
}
//! Sets the input receiving scene manager.
void CIrrDeviceStub::setInputReceivingSceneManager(scene::ISceneManager* sceneManager)
{
if (sceneManager)
sceneManager->grab();
if (InputReceivingSceneManager)
InputReceivingSceneManager->drop();
InputReceivingSceneManager = sceneManager;
}
//! Checks if the window is maximized.
bool CIrrDeviceStub::isWindowMaximized() const
{
return false;
}
//! Checks if the window is running in fullscreen mode
bool CIrrDeviceStub::isFullscreen() const
{
return CreationParams.Fullscreen;
}
//! returns color format
video::ECOLOR_FORMAT CIrrDeviceStub::getColorFormat() const
{
return video::ECF_R5G6B5;
}
//! No-op in this implementation
bool CIrrDeviceStub::activateJoysticks(core::array<SJoystickInfo> & joystickInfo)
{
return false;
}
//! No-op in this implementation
bool CIrrDeviceStub::activateAccelerometer(float updateInterval)
{
return false;
}
//! No-op in this implementation
bool CIrrDeviceStub::deactivateAccelerometer()
{
return false;
}
//! No-op in this implementation
bool CIrrDeviceStub::isAccelerometerActive()
{
return false;
}
//! No-op in this implementation
bool CIrrDeviceStub::isAccelerometerAvailable()
{
return false;
}
//! No-op in this implementation
bool CIrrDeviceStub::activateGyroscope(float updateInterval)
{
return false;
}
//! No-op in this implementation
bool CIrrDeviceStub::deactivateGyroscope()
{
return false;
}
//! No-op in this implementation
bool CIrrDeviceStub::isGyroscopeActive()
{
return false;
}
//! No-op in this implementation
bool CIrrDeviceStub::isGyroscopeAvailable()
{
return false;
}
//! No-op in this implementation
bool CIrrDeviceStub::activateDeviceMotion(float updateInterval)
{
return false;
}
//! No-op in this implementation
bool CIrrDeviceStub::deactivateDeviceMotion()
{
return false;
}
//! No-op in this implementation
bool CIrrDeviceStub::isDeviceMotionActive()
{
return false;
}
//! No-op in this implementation
bool CIrrDeviceStub::isDeviceMotionAvailable()
{
return false;
}
//! Set the maximal elapsed time between 2 clicks to generate doubleclicks for the mouse. It also affects tripleclick behavior.
void CIrrDeviceStub::setDoubleClickTime( u32 timeMs )
{
MouseMultiClicks.DoubleClickTime = timeMs;
}
//! Get the maximal elapsed time between 2 clicks to generate double- and tripleclicks for the mouse.
u32 CIrrDeviceStub::getDoubleClickTime() const
{
return MouseMultiClicks.DoubleClickTime;
}
//! Remove all messages pending in the system message loop
void CIrrDeviceStub::clearSystemMessages()
{
}
//! Get the display density in dots per inch.
float CIrrDeviceStub::getDisplayDensity() const
{
return 0.0f;
}
//! Checks whether the input device should take input from the IME
bool CIrrDeviceStub::acceptsIME()
{
if (!GUIEnvironment)
return false;
gui::IGUIElement *elem = GUIEnvironment->getFocus();
return elem && elem->acceptsIME();
}
} // end namespace irr

View File

@ -1,207 +1,207 @@
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#pragma once
#include "IrrlichtDevice.h"
#include "SIrrCreationParameters.h"
#include "IContextManager.h"
namespace irr
{
// lots of prototypes:
class ILogger;
class CLogger;
namespace gui
{
class IGUIEnvironment;
IGUIEnvironment* createGUIEnvironment(io::IFileSystem* fs,
video::IVideoDriver* Driver, IOSOperator* op);
}
namespace scene
{
ISceneManager* createSceneManager(video::IVideoDriver* driver, gui::ICursorControl* cc);
}
namespace io
{
IFileSystem* createFileSystem();
}
namespace video
{
IVideoDriver* createNullDriver(io::IFileSystem* io, const core::dimension2d<u32>& screenSize);
}
//! Stub for an Irrlicht Device implementation
class CIrrDeviceStub : public IrrlichtDevice
{
public:
//! constructor
CIrrDeviceStub(const SIrrlichtCreationParameters& param);
//! destructor
virtual ~CIrrDeviceStub();
//! returns the video driver
video::IVideoDriver* getVideoDriver() override;
//! return file system
io::IFileSystem* getFileSystem() override;
//! returns the gui environment
gui::IGUIEnvironment* getGUIEnvironment() override;
//! returns the scene manager
scene::ISceneManager* getSceneManager() override;
//! \return Returns a pointer to the mouse cursor control interface.
gui::ICursorControl* getCursorControl() override;
//! return the context manager
video::IContextManager* getContextManager() override;
//! Returns a pointer to the ITimer object. With it the current Time can be received.
ITimer* getTimer() override;
//! Sets the window icon.
bool setWindowIcon(const video::IImage *img) override;
//! Returns the version of the engine.
const char* getVersion() const override;
//! send the event to the right receiver
bool postEventFromUser(const SEvent& event) override;
//! Sets a new event receiver to receive events
void setEventReceiver(IEventReceiver* receiver) override;
//! Returns pointer to the current event receiver. Returns 0 if there is none.
IEventReceiver* getEventReceiver() override;
//! Sets the input receiving scene manager.
/** If set to null, the main scene manager (returned by GetSceneManager()) will receive the input */
void setInputReceivingSceneManager(scene::ISceneManager* sceneManager) override;
//! Returns a pointer to the logger.
ILogger* getLogger() override;
//! Returns the operation system opertator object.
IOSOperator* getOSOperator() override;
//! Checks if the window is maximized.
bool isWindowMaximized() const override;
//! Checks if the window is running in fullscreen mode.
bool isFullscreen() const override;
//! get color format of the current window
video::ECOLOR_FORMAT getColorFormat() const override;
//! Activate any joysticks, and generate events for them.
bool activateJoysticks(core::array<SJoystickInfo> & joystickInfo) override;
//! Activate accelerometer.
bool activateAccelerometer(float updateInterval = 0.016666f) override;
//! Deactivate accelerometer.
bool deactivateAccelerometer() override;
//! Is accelerometer active.
bool isAccelerometerActive() override;
//! Is accelerometer available.
bool isAccelerometerAvailable() override;
//! Activate gyroscope.
bool activateGyroscope(float updateInterval = 0.016666f) override;
//! Deactivate gyroscope.
bool deactivateGyroscope() override;
//! Is gyroscope active.
bool isGyroscopeActive() override;
//! Is gyroscope available.
bool isGyroscopeAvailable() override;
//! Activate device motion.
bool activateDeviceMotion(float updateInterval = 0.016666f) override;
//! Deactivate device motion.
bool deactivateDeviceMotion() override;
//! Is device motion active.
bool isDeviceMotionActive() override;
//! Is device motion available.
bool isDeviceMotionAvailable() override;
//! Set the maximal elapsed time between 2 clicks to generate doubleclicks for the mouse. It also affects tripleclick behavior.
//! When set to 0 no double- and tripleclicks will be generated.
void setDoubleClickTime( u32 timeMs ) override;
//! Get the maximal elapsed time between 2 clicks to generate double- and tripleclicks for the mouse.
u32 getDoubleClickTime() const override;
//! Remove all messages pending in the system message loop
void clearSystemMessages() override;
//! Get the display density in dots per inch.
float getDisplayDensity() const override;
//! Resize the render window.
void setWindowSize(const irr::core::dimension2d<u32>& size) override {}
protected:
void createGUIAndScene();
//! checks version of SDK and prints warning if there might be a problem
bool checkVersion(const char* version);
//! Compares to the last call of this function to return double and triple clicks.
/** Needed for win32 device event handling
\return Returns only 1,2 or 3. A 4th click will start with 1 again.
*/
virtual u32 checkSuccessiveClicks(s32 mouseX, s32 mouseY, EMOUSE_INPUT_EVENT inputEvent);
//! Checks whether the input device should take input from the IME
bool acceptsIME();
video::IVideoDriver* VideoDriver;
gui::IGUIEnvironment* GUIEnvironment;
scene::ISceneManager* SceneManager;
ITimer* Timer;
gui::ICursorControl* CursorControl;
IEventReceiver* UserReceiver;
CLogger* Logger;
IOSOperator* Operator;
io::IFileSystem* FileSystem;
scene::ISceneManager* InputReceivingSceneManager;
struct SMouseMultiClicks
{
SMouseMultiClicks()
: DoubleClickTime(500), CountSuccessiveClicks(0), LastClickTime(0), LastMouseInputEvent(EMIE_COUNT)
{}
u32 DoubleClickTime;
u32 CountSuccessiveClicks;
u32 LastClickTime;
core::position2di LastClick;
EMOUSE_INPUT_EVENT LastMouseInputEvent;
};
SMouseMultiClicks MouseMultiClicks;
video::IContextManager* ContextManager;
SIrrlichtCreationParameters CreationParams;
bool Close;
};
} // end namespace irr
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#pragma once
#include "IrrlichtDevice.h"
#include "SIrrCreationParameters.h"
#include "IContextManager.h"
namespace irr
{
// lots of prototypes:
class ILogger;
class CLogger;
namespace gui
{
class IGUIEnvironment;
IGUIEnvironment* createGUIEnvironment(io::IFileSystem* fs,
video::IVideoDriver* Driver, IOSOperator* op);
}
namespace scene
{
ISceneManager* createSceneManager(video::IVideoDriver* driver, gui::ICursorControl* cc);
}
namespace io
{
IFileSystem* createFileSystem();
}
namespace video
{
IVideoDriver* createNullDriver(io::IFileSystem* io, const core::dimension2d<u32>& screenSize);
}
//! Stub for an Irrlicht Device implementation
class CIrrDeviceStub : public IrrlichtDevice
{
public:
//! constructor
CIrrDeviceStub(const SIrrlichtCreationParameters& param);
//! destructor
virtual ~CIrrDeviceStub();
//! returns the video driver
video::IVideoDriver* getVideoDriver() override;
//! return file system
io::IFileSystem* getFileSystem() override;
//! returns the gui environment
gui::IGUIEnvironment* getGUIEnvironment() override;
//! returns the scene manager
scene::ISceneManager* getSceneManager() override;
//! \return Returns a pointer to the mouse cursor control interface.
gui::ICursorControl* getCursorControl() override;
//! return the context manager
video::IContextManager* getContextManager() override;
//! Returns a pointer to the ITimer object. With it the current Time can be received.
ITimer* getTimer() override;
//! Sets the window icon.
bool setWindowIcon(const video::IImage *img) override;
//! Returns the version of the engine.
const char* getVersion() const override;
//! send the event to the right receiver
bool postEventFromUser(const SEvent& event) override;
//! Sets a new event receiver to receive events
void setEventReceiver(IEventReceiver* receiver) override;
//! Returns pointer to the current event receiver. Returns 0 if there is none.
IEventReceiver* getEventReceiver() override;
//! Sets the input receiving scene manager.
/** If set to null, the main scene manager (returned by GetSceneManager()) will receive the input */
void setInputReceivingSceneManager(scene::ISceneManager* sceneManager) override;
//! Returns a pointer to the logger.
ILogger* getLogger() override;
//! Returns the operation system opertator object.
IOSOperator* getOSOperator() override;
//! Checks if the window is maximized.
bool isWindowMaximized() const override;
//! Checks if the window is running in fullscreen mode.
bool isFullscreen() const override;
//! get color format of the current window
video::ECOLOR_FORMAT getColorFormat() const override;
//! Activate any joysticks, and generate events for them.
bool activateJoysticks(core::array<SJoystickInfo> & joystickInfo) override;
//! Activate accelerometer.
bool activateAccelerometer(float updateInterval = 0.016666f) override;
//! Deactivate accelerometer.
bool deactivateAccelerometer() override;
//! Is accelerometer active.
bool isAccelerometerActive() override;
//! Is accelerometer available.
bool isAccelerometerAvailable() override;
//! Activate gyroscope.
bool activateGyroscope(float updateInterval = 0.016666f) override;
//! Deactivate gyroscope.
bool deactivateGyroscope() override;
//! Is gyroscope active.
bool isGyroscopeActive() override;
//! Is gyroscope available.
bool isGyroscopeAvailable() override;
//! Activate device motion.
bool activateDeviceMotion(float updateInterval = 0.016666f) override;
//! Deactivate device motion.
bool deactivateDeviceMotion() override;
//! Is device motion active.
bool isDeviceMotionActive() override;
//! Is device motion available.
bool isDeviceMotionAvailable() override;
//! Set the maximal elapsed time between 2 clicks to generate doubleclicks for the mouse. It also affects tripleclick behavior.
//! When set to 0 no double- and tripleclicks will be generated.
void setDoubleClickTime( u32 timeMs ) override;
//! Get the maximal elapsed time between 2 clicks to generate double- and tripleclicks for the mouse.
u32 getDoubleClickTime() const override;
//! Remove all messages pending in the system message loop
void clearSystemMessages() override;
//! Get the display density in dots per inch.
float getDisplayDensity() const override;
//! Resize the render window.
void setWindowSize(const irr::core::dimension2d<u32>& size) override {}
protected:
void createGUIAndScene();
//! checks version of SDK and prints warning if there might be a problem
bool checkVersion(const char* version);
//! Compares to the last call of this function to return double and triple clicks.
/** Needed for win32 device event handling
\return Returns only 1,2 or 3. A 4th click will start with 1 again.
*/
virtual u32 checkSuccessiveClicks(s32 mouseX, s32 mouseY, EMOUSE_INPUT_EVENT inputEvent);
//! Checks whether the input device should take input from the IME
bool acceptsIME();
video::IVideoDriver* VideoDriver;
gui::IGUIEnvironment* GUIEnvironment;
scene::ISceneManager* SceneManager;
ITimer* Timer;
gui::ICursorControl* CursorControl;
IEventReceiver* UserReceiver;
CLogger* Logger;
IOSOperator* Operator;
io::IFileSystem* FileSystem;
scene::ISceneManager* InputReceivingSceneManager;
struct SMouseMultiClicks
{
SMouseMultiClicks()
: DoubleClickTime(500), CountSuccessiveClicks(0), LastClickTime(0), LastMouseInputEvent(EMIE_COUNT)
{}
u32 DoubleClickTime;
u32 CountSuccessiveClicks;
u32 LastClickTime;
core::position2di LastClick;
EMOUSE_INPUT_EVENT LastMouseInputEvent;
};
SMouseMultiClicks MouseMultiClicks;
video::IContextManager* ContextManager;
SIrrlichtCreationParameters CreationParams;
bool Close;
};
} // end namespace irr

File diff suppressed because it is too large Load Diff

View File

@ -1,425 +1,425 @@
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#pragma once
#include "CIrrDeviceStub.h"
#include "IrrlichtDevice.h"
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <mmsystem.h> // For JOYCAPS
#include <windowsx.h>
#if !defined(GET_X_LPARAM)
#define GET_X_LPARAM(lp) ((int)(short)LOWORD(lp))
#define GET_Y_LPARAM(lp) ((int)(short)HIWORD(lp))
#endif
namespace irr
{
struct SJoystickWin32Control;
class CIrrDeviceWin32 : public CIrrDeviceStub
{
friend struct SJoystickWin32Control;
public:
//! constructor
CIrrDeviceWin32(const SIrrlichtCreationParameters& params);
//! destructor
virtual ~CIrrDeviceWin32();
//! runs the device. Returns false if device wants to be deleted
bool run() override;
//! Cause the device to temporarily pause execution and let other processes to run
// This should bring down processor usage without major performance loss for Irrlicht
void yield() override;
//! Pause execution and let other processes to run for a specified amount of time.
void sleep(u32 timeMs, bool pauseTimer) override;
//! sets the caption of the window
void setWindowCaption(const wchar_t* text) override;
//! Sets the window icon.
bool setWindowIcon(const video::IImage *img) override;
//! returns if window is active. if not, nothing need to be drawn
bool isWindowActive() const override;
//! returns if window has focus
bool isWindowFocused() const override;
//! returns if window is minimized
bool isWindowMinimized() const override;
//! returns last state from maximizeWindow() and restoreWindow()
bool isWindowMaximized() const override;
//! notifies the device that it should close itself
void closeDevice() override;
//! Notifies the device, that it has been resized
/** Must be publis as it is called from free function (event handler) */
void OnResized();
//! Sets if the window should be resizable in windowed mode.
void setResizable(bool resize=false) override;
//! Resize the render window.
void setWindowSize(const irr::core::dimension2d<u32>& size) override;
//! Minimizes the window.
void minimizeWindow() override;
//! Maximizes the window.
void maximizeWindow() override;
//! Restores the window size.
void restoreWindow() override;
//! Get the position of the window on screen
core::position2di getWindowPosition() override;
//! Activate any joysticks, and generate events for them.
bool activateJoysticks(core::array<SJoystickInfo> & joystickInfo) override;
//! Remove all messages pending in the system message loop
void clearSystemMessages() override;
//! Get the device type
E_DEVICE_TYPE getType() const override
{
return EIDT_WIN32;
}
//! Get the display density in dots per inch.
float getDisplayDensity() const override;
//! Compares to the last call of this function to return double and triple clicks.
//! \return Returns only 1,2 or 3. A 4th click will start with 1 again.
u32 checkSuccessiveClicks(s32 mouseX, s32 mouseY, EMOUSE_INPUT_EVENT inputEvent ) override
{
// we just have to make it public
return CIrrDeviceStub::checkSuccessiveClicks(mouseX, mouseY, inputEvent );
}
//! Switch to fullscreen
bool switchToFullScreen();
// convert an Irrlicht texture to a windows cursor
HCURSOR TextureToCursor(HWND hwnd, irr::video::ITexture * tex, const core::rect<s32>& sourceRect, const core::position2d<s32> &hotspot);
//! Implementation of the win32 cursor control
class CCursorControl : public gui::ICursorControl
{
public:
CCursorControl(CIrrDeviceWin32* device, const core::dimension2d<u32>& wsize, HWND hwnd, bool fullscreen);
~CCursorControl();
//! Changes the visible state of the mouse cursor.
void setVisible(bool visible) override
{
CURSORINFO info;
info.cbSize = sizeof(CURSORINFO);
BOOL gotCursorInfo = GetCursorInfo(&info);
while ( gotCursorInfo )
{
#ifdef CURSOR_SUPPRESSED
// Since Windows 8 the cursor can be suppressed by a touch interface
if (visible && info.flags == CURSOR_SUPPRESSED)
{
break;
}
#endif
if ( (visible && info.flags == CURSOR_SHOWING) || // visible
(!visible && info.flags == 0 ) ) // hidden
{
break;
}
// this only increases an internal
// display counter in windows, so it
// might have to be called some more
const int showResult = ShowCursor(visible);
// if result has correct sign we can
// stop here as well
if (( !visible && showResult < 0 ) ||
(visible && showResult >= 0))
break;
// yes, it really must be set each time
info.cbSize = sizeof(CURSORINFO);
gotCursorInfo = GetCursorInfo(&info);
#ifdef CURSOR_SUPPRESSED
// Not sure if a cursor which we tried to hide still can be suppressed.
// I have no touch-display for testing this and MSDN doesn't describe it.
// But adding this check shouldn't hurt and might prevent an endless loop.
if (!visible && info.flags == CURSOR_SUPPRESSED)
{
break;
}
#endif
}
IsVisible = visible;
}
//! Returns if the cursor is currently visible.
bool isVisible() const override
{
return IsVisible;
}
//! Sets the new position of the cursor.
void setPosition(const core::position2d<f32> &pos) override
{
setPosition(pos.X, pos.Y);
}
//! Sets the new position of the cursor.
void setPosition(f32 x, f32 y) override
{
if (!UseReferenceRect)
setPosition(core::round32(x*WindowSize.Width), core::round32(y*WindowSize.Height));
else
setPosition(core::round32(x*ReferenceRect.getWidth()), core::round32(y*ReferenceRect.getHeight()));
}
//! Sets the new position of the cursor.
void setPosition(const core::position2d<s32> &pos) override
{
setPosition(pos.X, pos.Y);
}
//! Sets the new position of the cursor.
void setPosition(s32 x, s32 y) override
{
if (UseReferenceRect)
{
SetCursorPos(ReferenceRect.UpperLeftCorner.X + x,
ReferenceRect.UpperLeftCorner.Y + y);
}
else
{
RECT rect;
if (GetWindowRect(HWnd, &rect))
SetCursorPos(x + rect.left + BorderX, y + rect.top + BorderY);
}
CursorPos.X = x;
CursorPos.Y = y;
}
//! Returns the current position of the mouse cursor.
const core::position2d<s32>& getPosition(bool updateCursor) override
{
if ( updateCursor )
updateInternalCursorPosition();
return CursorPos;
}
//! Returns the current position of the mouse cursor.
core::position2d<f32> getRelativePosition(bool updateCursor) override
{
if ( updateCursor )
updateInternalCursorPosition();
if (!UseReferenceRect)
{
return core::position2d<f32>(CursorPos.X * InvWindowSize.Width,
CursorPos.Y * InvWindowSize.Height);
}
return core::position2d<f32>(CursorPos.X / (f32)ReferenceRect.getWidth(),
CursorPos.Y / (f32)ReferenceRect.getHeight());
}
//! Sets an absolute reference rect for calculating the cursor position.
void setReferenceRect(core::rect<s32>* rect=0) override
{
if (rect)
{
ReferenceRect = *rect;
UseReferenceRect = true;
// prevent division through zero and uneven sizes
if (!ReferenceRect.getHeight() || ReferenceRect.getHeight()%2)
ReferenceRect.LowerRightCorner.Y += 1;
if (!ReferenceRect.getWidth() || ReferenceRect.getWidth()%2)
ReferenceRect.LowerRightCorner.X += 1;
}
else
UseReferenceRect = false;
}
/** Used to notify the cursor that the window was resized. */
void OnResize(const core::dimension2d<u32>& size)
{
WindowSize = size;
if (size.Width!=0)
InvWindowSize.Width = 1.0f / size.Width;
else
InvWindowSize.Width = 0.f;
if (size.Height!=0)
InvWindowSize.Height = 1.0f / size.Height;
else
InvWindowSize.Height = 0.f;
}
/** Used to notify the cursor that the window resizable settings changed. */
void updateBorderSize(bool fullscreen, bool resizable)
{
if (!fullscreen)
{
s32 paddingBorder = 0;
#ifdef SM_CXPADDEDBORDER
paddingBorder = GetSystemMetrics(SM_CXPADDEDBORDER);
#endif
if (resizable)
{
BorderX = GetSystemMetrics(SM_CXSIZEFRAME) + paddingBorder;
BorderY = GetSystemMetrics(SM_CYCAPTION) + GetSystemMetrics(SM_CYSIZEFRAME) + paddingBorder;
}
else
{
BorderX = GetSystemMetrics(SM_CXDLGFRAME) + paddingBorder;
BorderY = GetSystemMetrics(SM_CYCAPTION) + GetSystemMetrics(SM_CYDLGFRAME) + paddingBorder;
}
}
else
{
BorderX = BorderY = 0;
}
}
//! Sets the active cursor icon
void setActiveIcon(gui::ECURSOR_ICON iconId) override;
//! Gets the currently active icon
gui::ECURSOR_ICON getActiveIcon() const override
{
return ActiveIcon;
}
//! Add a custom sprite as cursor icon.
gui::ECURSOR_ICON addIcon(const gui::SCursorSprite& icon) override;
//! replace the given cursor icon.
void changeIcon(gui::ECURSOR_ICON iconId, const gui::SCursorSprite& icon) override;
//! Return a system-specific size which is supported for cursors. Larger icons will fail, smaller icons might work.
core::dimension2di getSupportedIconSize() const override;
void update();
private:
//! Updates the internal cursor position
void updateInternalCursorPosition()
{
POINT p;
if (!GetCursorPos(&p))
{
DWORD xy = GetMessagePos();
p.x = GET_X_LPARAM(xy);
p.y = GET_Y_LPARAM(xy);
}
if (UseReferenceRect)
{
CursorPos.X = p.x - ReferenceRect.UpperLeftCorner.X;
CursorPos.Y = p.y - ReferenceRect.UpperLeftCorner.Y;
}
else
{
RECT rect;
if (GetWindowRect(HWnd, &rect))
{
CursorPos.X = p.x-rect.left-BorderX;
CursorPos.Y = p.y-rect.top-BorderY;
}
else
{
// window seems not to be existent, so set cursor to
// a negative value
CursorPos.X = -1;
CursorPos.Y = -1;
}
}
}
CIrrDeviceWin32* Device;
core::position2d<s32> CursorPos;
core::dimension2d<u32> WindowSize;
core::dimension2d<f32> InvWindowSize;
HWND HWnd;
s32 BorderX, BorderY;
core::rect<s32> ReferenceRect;
bool UseReferenceRect;
bool IsVisible;
struct CursorFrameW32
{
CursorFrameW32() : IconHW(0) {}
CursorFrameW32(HCURSOR icon) : IconHW(icon) {}
HCURSOR IconHW; // hardware cursor
};
struct CursorW32
{
CursorW32() {}
explicit CursorW32(HCURSOR iconHw, u32 frameTime=0) : FrameTime(frameTime)
{
Frames.push_back( CursorFrameW32(iconHw) );
}
core::array<CursorFrameW32> Frames;
u32 FrameTime;
};
core::array<CursorW32> Cursors;
gui::ECURSOR_ICON ActiveIcon;
u32 ActiveIconStartTime;
void initCursors();
};
//! returns the win32 cursor control
CCursorControl* getWin32CursorControl();
private:
//! create the driver
void createDriver();
//! Process system events
void handleSystemMessages();
void getWindowsVersion(core::stringc& version);
void resizeIfNecessary();
DWORD getWindowStyle(bool fullscreen, bool resizable) const;
HWND HWnd;
bool Resized;
bool ExternalWindow;
CCursorControl* Win32CursorControl;
SJoystickWin32Control* JoyControl;
bool WindowMaximized;
};
} // end namespace irr
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#pragma once
#include "CIrrDeviceStub.h"
#include "IrrlichtDevice.h"
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <mmsystem.h> // For JOYCAPS
#include <windowsx.h>
#if !defined(GET_X_LPARAM)
#define GET_X_LPARAM(lp) ((int)(short)LOWORD(lp))
#define GET_Y_LPARAM(lp) ((int)(short)HIWORD(lp))
#endif
namespace irr
{
struct SJoystickWin32Control;
class CIrrDeviceWin32 : public CIrrDeviceStub
{
friend struct SJoystickWin32Control;
public:
//! constructor
CIrrDeviceWin32(const SIrrlichtCreationParameters& params);
//! destructor
virtual ~CIrrDeviceWin32();
//! runs the device. Returns false if device wants to be deleted
bool run() override;
//! Cause the device to temporarily pause execution and let other processes to run
// This should bring down processor usage without major performance loss for Irrlicht
void yield() override;
//! Pause execution and let other processes to run for a specified amount of time.
void sleep(u32 timeMs, bool pauseTimer) override;
//! sets the caption of the window
void setWindowCaption(const wchar_t* text) override;
//! Sets the window icon.
bool setWindowIcon(const video::IImage *img) override;
//! returns if window is active. if not, nothing need to be drawn
bool isWindowActive() const override;
//! returns if window has focus
bool isWindowFocused() const override;
//! returns if window is minimized
bool isWindowMinimized() const override;
//! returns last state from maximizeWindow() and restoreWindow()
bool isWindowMaximized() const override;
//! notifies the device that it should close itself
void closeDevice() override;
//! Notifies the device, that it has been resized
/** Must be publis as it is called from free function (event handler) */
void OnResized();
//! Sets if the window should be resizable in windowed mode.
void setResizable(bool resize=false) override;
//! Resize the render window.
void setWindowSize(const irr::core::dimension2d<u32>& size) override;
//! Minimizes the window.
void minimizeWindow() override;
//! Maximizes the window.
void maximizeWindow() override;
//! Restores the window size.
void restoreWindow() override;
//! Get the position of the window on screen
core::position2di getWindowPosition() override;
//! Activate any joysticks, and generate events for them.
bool activateJoysticks(core::array<SJoystickInfo> & joystickInfo) override;
//! Remove all messages pending in the system message loop
void clearSystemMessages() override;
//! Get the device type
E_DEVICE_TYPE getType() const override
{
return EIDT_WIN32;
}
//! Get the display density in dots per inch.
float getDisplayDensity() const override;
//! Compares to the last call of this function to return double and triple clicks.
//! \return Returns only 1,2 or 3. A 4th click will start with 1 again.
u32 checkSuccessiveClicks(s32 mouseX, s32 mouseY, EMOUSE_INPUT_EVENT inputEvent ) override
{
// we just have to make it public
return CIrrDeviceStub::checkSuccessiveClicks(mouseX, mouseY, inputEvent );
}
//! Switch to fullscreen
bool switchToFullScreen();
// convert an Irrlicht texture to a windows cursor
HCURSOR TextureToCursor(HWND hwnd, irr::video::ITexture * tex, const core::rect<s32>& sourceRect, const core::position2d<s32> &hotspot);
//! Implementation of the win32 cursor control
class CCursorControl : public gui::ICursorControl
{
public:
CCursorControl(CIrrDeviceWin32* device, const core::dimension2d<u32>& wsize, HWND hwnd, bool fullscreen);
~CCursorControl();
//! Changes the visible state of the mouse cursor.
void setVisible(bool visible) override
{
CURSORINFO info;
info.cbSize = sizeof(CURSORINFO);
BOOL gotCursorInfo = GetCursorInfo(&info);
while ( gotCursorInfo )
{
#ifdef CURSOR_SUPPRESSED
// Since Windows 8 the cursor can be suppressed by a touch interface
if (visible && info.flags == CURSOR_SUPPRESSED)
{
break;
}
#endif
if ( (visible && info.flags == CURSOR_SHOWING) || // visible
(!visible && info.flags == 0 ) ) // hidden
{
break;
}
// this only increases an internal
// display counter in windows, so it
// might have to be called some more
const int showResult = ShowCursor(visible);
// if result has correct sign we can
// stop here as well
if (( !visible && showResult < 0 ) ||
(visible && showResult >= 0))
break;
// yes, it really must be set each time
info.cbSize = sizeof(CURSORINFO);
gotCursorInfo = GetCursorInfo(&info);
#ifdef CURSOR_SUPPRESSED
// Not sure if a cursor which we tried to hide still can be suppressed.
// I have no touch-display for testing this and MSDN doesn't describe it.
// But adding this check shouldn't hurt and might prevent an endless loop.
if (!visible && info.flags == CURSOR_SUPPRESSED)
{
break;
}
#endif
}
IsVisible = visible;
}
//! Returns if the cursor is currently visible.
bool isVisible() const override
{
return IsVisible;
}
//! Sets the new position of the cursor.
void setPosition(const core::position2d<f32> &pos) override
{
setPosition(pos.X, pos.Y);
}
//! Sets the new position of the cursor.
void setPosition(f32 x, f32 y) override
{
if (!UseReferenceRect)
setPosition(core::round32(x*WindowSize.Width), core::round32(y*WindowSize.Height));
else
setPosition(core::round32(x*ReferenceRect.getWidth()), core::round32(y*ReferenceRect.getHeight()));
}
//! Sets the new position of the cursor.
void setPosition(const core::position2d<s32> &pos) override
{
setPosition(pos.X, pos.Y);
}
//! Sets the new position of the cursor.
void setPosition(s32 x, s32 y) override
{
if (UseReferenceRect)
{
SetCursorPos(ReferenceRect.UpperLeftCorner.X + x,
ReferenceRect.UpperLeftCorner.Y + y);
}
else
{
RECT rect;
if (GetWindowRect(HWnd, &rect))
SetCursorPos(x + rect.left + BorderX, y + rect.top + BorderY);
}
CursorPos.X = x;
CursorPos.Y = y;
}
//! Returns the current position of the mouse cursor.
const core::position2d<s32>& getPosition(bool updateCursor) override
{
if ( updateCursor )
updateInternalCursorPosition();
return CursorPos;
}
//! Returns the current position of the mouse cursor.
core::position2d<f32> getRelativePosition(bool updateCursor) override
{
if ( updateCursor )
updateInternalCursorPosition();
if (!UseReferenceRect)
{
return core::position2d<f32>(CursorPos.X * InvWindowSize.Width,
CursorPos.Y * InvWindowSize.Height);
}
return core::position2d<f32>(CursorPos.X / (f32)ReferenceRect.getWidth(),
CursorPos.Y / (f32)ReferenceRect.getHeight());
}
//! Sets an absolute reference rect for calculating the cursor position.
void setReferenceRect(core::rect<s32>* rect=0) override
{
if (rect)
{
ReferenceRect = *rect;
UseReferenceRect = true;
// prevent division through zero and uneven sizes
if (!ReferenceRect.getHeight() || ReferenceRect.getHeight()%2)
ReferenceRect.LowerRightCorner.Y += 1;
if (!ReferenceRect.getWidth() || ReferenceRect.getWidth()%2)
ReferenceRect.LowerRightCorner.X += 1;
}
else
UseReferenceRect = false;
}
/** Used to notify the cursor that the window was resized. */
void OnResize(const core::dimension2d<u32>& size)
{
WindowSize = size;
if (size.Width!=0)
InvWindowSize.Width = 1.0f / size.Width;
else
InvWindowSize.Width = 0.f;
if (size.Height!=0)
InvWindowSize.Height = 1.0f / size.Height;
else
InvWindowSize.Height = 0.f;
}
/** Used to notify the cursor that the window resizable settings changed. */
void updateBorderSize(bool fullscreen, bool resizable)
{
if (!fullscreen)
{
s32 paddingBorder = 0;
#ifdef SM_CXPADDEDBORDER
paddingBorder = GetSystemMetrics(SM_CXPADDEDBORDER);
#endif
if (resizable)
{
BorderX = GetSystemMetrics(SM_CXSIZEFRAME) + paddingBorder;
BorderY = GetSystemMetrics(SM_CYCAPTION) + GetSystemMetrics(SM_CYSIZEFRAME) + paddingBorder;
}
else
{
BorderX = GetSystemMetrics(SM_CXDLGFRAME) + paddingBorder;
BorderY = GetSystemMetrics(SM_CYCAPTION) + GetSystemMetrics(SM_CYDLGFRAME) + paddingBorder;
}
}
else
{
BorderX = BorderY = 0;
}
}
//! Sets the active cursor icon
void setActiveIcon(gui::ECURSOR_ICON iconId) override;
//! Gets the currently active icon
gui::ECURSOR_ICON getActiveIcon() const override
{
return ActiveIcon;
}
//! Add a custom sprite as cursor icon.
gui::ECURSOR_ICON addIcon(const gui::SCursorSprite& icon) override;
//! replace the given cursor icon.
void changeIcon(gui::ECURSOR_ICON iconId, const gui::SCursorSprite& icon) override;
//! Return a system-specific size which is supported for cursors. Larger icons will fail, smaller icons might work.
core::dimension2di getSupportedIconSize() const override;
void update();
private:
//! Updates the internal cursor position
void updateInternalCursorPosition()
{
POINT p;
if (!GetCursorPos(&p))
{
DWORD xy = GetMessagePos();
p.x = GET_X_LPARAM(xy);
p.y = GET_Y_LPARAM(xy);
}
if (UseReferenceRect)
{
CursorPos.X = p.x - ReferenceRect.UpperLeftCorner.X;
CursorPos.Y = p.y - ReferenceRect.UpperLeftCorner.Y;
}
else
{
RECT rect;
if (GetWindowRect(HWnd, &rect))
{
CursorPos.X = p.x-rect.left-BorderX;
CursorPos.Y = p.y-rect.top-BorderY;
}
else
{
// window seems not to be existent, so set cursor to
// a negative value
CursorPos.X = -1;
CursorPos.Y = -1;
}
}
}
CIrrDeviceWin32* Device;
core::position2d<s32> CursorPos;
core::dimension2d<u32> WindowSize;
core::dimension2d<f32> InvWindowSize;
HWND HWnd;
s32 BorderX, BorderY;
core::rect<s32> ReferenceRect;
bool UseReferenceRect;
bool IsVisible;
struct CursorFrameW32
{
CursorFrameW32() : IconHW(0) {}
CursorFrameW32(HCURSOR icon) : IconHW(icon) {}
HCURSOR IconHW; // hardware cursor
};
struct CursorW32
{
CursorW32() {}
explicit CursorW32(HCURSOR iconHw, u32 frameTime=0) : FrameTime(frameTime)
{
Frames.push_back( CursorFrameW32(iconHw) );
}
core::array<CursorFrameW32> Frames;
u32 FrameTime;
};
core::array<CursorW32> Cursors;
gui::ECURSOR_ICON ActiveIcon;
u32 ActiveIconStartTime;
void initCursors();
};
//! returns the win32 cursor control
CCursorControl* getWin32CursorControl();
private:
//! create the driver
void createDriver();
//! Process system events
void handleSystemMessages();
void getWindowsVersion(core::stringc& version);
void resizeIfNecessary();
DWORD getWindowStyle(bool fullscreen, bool resizable) const;
HWND HWnd;
bool Resized;
bool ExternalWindow;
CCursorControl* Win32CursorControl;
SJoystickWin32Control* JoyControl;
bool WindowMaximized;
};
} // end namespace irr

View File

@ -1,128 +1,128 @@
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#include "CLimitReadFile.h"
#include "irrMath.h"
#include "irrString.h"
namespace irr
{
namespace io
{
CLimitReadFile::CLimitReadFile(IReadFile* alreadyOpenedFile, long pos,
long areaSize, const io::path& name)
: Filename(name), AreaStart(0), AreaEnd(0), Pos(0),
File(alreadyOpenedFile)
{
#ifdef _DEBUG
setDebugName("CLimitReadFile");
#endif
if (File)
{
File->grab();
AreaStart = pos;
AreaEnd = AreaStart + areaSize;
}
}
CLimitReadFile::~CLimitReadFile()
{
if (File)
File->drop();
}
//! returns how much was read
size_t CLimitReadFile::read(void* buffer, size_t sizeToRead)
{
if (0 == File)
return 0;
#if 1
long r = AreaStart + Pos;
long toRead = core::min_(AreaEnd, r + (long)sizeToRead) - core::max_(AreaStart, r);
if (toRead < 0)
return 0;
File->seek(r);
r = (long)File->read(buffer, toRead);
Pos += r;
return r;
#else
const long pos = File->getPos();
if (pos >= AreaEnd)
return 0;
if (pos + (long)sizeToRead >= AreaEnd)
sizeToRead = AreaEnd - pos;
return File->read(buffer, sizeToRead);
#endif
}
//! changes position in file, returns true if successful
bool CLimitReadFile::seek(long finalPos, bool relativeMovement)
{
#if 1
Pos = core::s32_clamp(finalPos + (relativeMovement ? Pos : 0 ), 0, AreaEnd - AreaStart);
return true;
#else
const long pos = File->getPos();
if (relativeMovement)
{
if (pos + finalPos > AreaEnd)
finalPos = AreaEnd - pos;
}
else
{
finalPos += AreaStart;
if (finalPos > AreaEnd)
return false;
}
return File->seek(finalPos, relativeMovement);
#endif
}
//! returns size of file
long CLimitReadFile::getSize() const
{
return AreaEnd - AreaStart;
}
//! returns where in the file we are.
long CLimitReadFile::getPos() const
{
#if 1
return Pos;
#else
return File->getPos() - AreaStart;
#endif
}
//! returns name of file
const io::path& CLimitReadFile::getFileName() const
{
return Filename;
}
IReadFile* createLimitReadFile(const io::path& fileName, IReadFile* alreadyOpenedFile, long pos, long areaSize)
{
return new CLimitReadFile(alreadyOpenedFile, pos, areaSize, fileName);
}
} // end namespace io
} // end namespace irr
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#include "CLimitReadFile.h"
#include "irrMath.h"
#include "irrString.h"
namespace irr
{
namespace io
{
CLimitReadFile::CLimitReadFile(IReadFile* alreadyOpenedFile, long pos,
long areaSize, const io::path& name)
: Filename(name), AreaStart(0), AreaEnd(0), Pos(0),
File(alreadyOpenedFile)
{
#ifdef _DEBUG
setDebugName("CLimitReadFile");
#endif
if (File)
{
File->grab();
AreaStart = pos;
AreaEnd = AreaStart + areaSize;
}
}
CLimitReadFile::~CLimitReadFile()
{
if (File)
File->drop();
}
//! returns how much was read
size_t CLimitReadFile::read(void* buffer, size_t sizeToRead)
{
if (0 == File)
return 0;
#if 1
long r = AreaStart + Pos;
long toRead = core::min_(AreaEnd, r + (long)sizeToRead) - core::max_(AreaStart, r);
if (toRead < 0)
return 0;
File->seek(r);
r = (long)File->read(buffer, toRead);
Pos += r;
return r;
#else
const long pos = File->getPos();
if (pos >= AreaEnd)
return 0;
if (pos + (long)sizeToRead >= AreaEnd)
sizeToRead = AreaEnd - pos;
return File->read(buffer, sizeToRead);
#endif
}
//! changes position in file, returns true if successful
bool CLimitReadFile::seek(long finalPos, bool relativeMovement)
{
#if 1
Pos = core::s32_clamp(finalPos + (relativeMovement ? Pos : 0 ), 0, AreaEnd - AreaStart);
return true;
#else
const long pos = File->getPos();
if (relativeMovement)
{
if (pos + finalPos > AreaEnd)
finalPos = AreaEnd - pos;
}
else
{
finalPos += AreaStart;
if (finalPos > AreaEnd)
return false;
}
return File->seek(finalPos, relativeMovement);
#endif
}
//! returns size of file
long CLimitReadFile::getSize() const
{
return AreaEnd - AreaStart;
}
//! returns where in the file we are.
long CLimitReadFile::getPos() const
{
#if 1
return Pos;
#else
return File->getPos() - AreaStart;
#endif
}
//! returns name of file
const io::path& CLimitReadFile::getFileName() const
{
return Filename;
}
IReadFile* createLimitReadFile(const io::path& fileName, IReadFile* alreadyOpenedFile, long pos, long areaSize)
{
return new CLimitReadFile(alreadyOpenedFile, pos, areaSize, fileName);
}
} // end namespace io
} // end namespace irr

View File

@ -1,64 +1,64 @@
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#pragma once
#include "IReadFile.h"
#include "irrString.h"
namespace irr
{
class CUnicodeConverter;
namespace io
{
/*! this is a read file, which is limited to some boundaries,
so that it may only start from a certain file position
and may only read until a certain file position.
This can be useful, for example for reading uncompressed files
in an archive (zip, tar).
!*/
class CLimitReadFile : public IReadFile
{
public:
CLimitReadFile(IReadFile* alreadyOpenedFile, long pos, long areaSize, const io::path& name);
virtual ~CLimitReadFile();
//! returns how much was read
size_t read(void* buffer, size_t sizeToRead) override;
//! changes position in file, returns true if successful
//! if relativeMovement==true, the pos is changed relative to current pos,
//! otherwise from begin of file
bool seek(long finalPos, bool relativeMovement = false) override;
//! returns size of file
long getSize() const override;
//! returns where in the file we are.
long getPos() const override;
//! returns name of file
const io::path& getFileName() const override;
//! Get the type of the class implementing this interface
EREAD_FILE_TYPE getType() const override
{
return ERFT_LIMIT_READ_FILE;
}
private:
io::path Filename;
long AreaStart;
long AreaEnd;
long Pos;
IReadFile* File;
};
} // end namespace io
} // end namespace irr
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#pragma once
#include "IReadFile.h"
#include "irrString.h"
namespace irr
{
class CUnicodeConverter;
namespace io
{
/*! this is a read file, which is limited to some boundaries,
so that it may only start from a certain file position
and may only read until a certain file position.
This can be useful, for example for reading uncompressed files
in an archive (zip, tar).
!*/
class CLimitReadFile : public IReadFile
{
public:
CLimitReadFile(IReadFile* alreadyOpenedFile, long pos, long areaSize, const io::path& name);
virtual ~CLimitReadFile();
//! returns how much was read
size_t read(void* buffer, size_t sizeToRead) override;
//! changes position in file, returns true if successful
//! if relativeMovement==true, the pos is changed relative to current pos,
//! otherwise from begin of file
bool seek(long finalPos, bool relativeMovement = false) override;
//! returns size of file
long getSize() const override;
//! returns where in the file we are.
long getPos() const override;
//! returns name of file
const io::path& getFileName() const override;
//! Get the type of the class implementing this interface
EREAD_FILE_TYPE getType() const override
{
return ERFT_LIMIT_READ_FILE;
}
private:
io::path Filename;
long AreaStart;
long AreaEnd;
long Pos;
IReadFile* File;
};
} // end namespace io
} // end namespace irr

View File

@ -1,102 +1,102 @@
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#include "CLogger.h"
namespace irr
{
CLogger::CLogger(IEventReceiver* r)
: LogLevel(ELL_INFORMATION), Receiver(r)
{
#ifdef _DEBUG
setDebugName("CLogger");
#endif
}
//! Returns the current set log level.
ELOG_LEVEL CLogger::getLogLevel() const
{
return LogLevel;
}
//! Sets a new log level.
void CLogger::setLogLevel(ELOG_LEVEL ll)
{
LogLevel = ll;
}
//! Prints out a text into the log
void CLogger::log(const c8* text, ELOG_LEVEL ll)
{
if (ll < LogLevel)
return;
if (Receiver)
{
SEvent event;
event.EventType = EET_LOG_TEXT_EVENT;
event.LogEvent.Text = text;
event.LogEvent.Level = ll;
if (Receiver->OnEvent(event))
return;
}
os::Printer::print(text);
}
//! Prints out a text into the log
void CLogger::log(const c8* text, const c8* hint, ELOG_LEVEL ll)
{
if (ll < LogLevel)
return;
core::stringc s = text;
s += ": ";
s += hint;
log (s.c_str(), ll);
}
//! Prints out a text into the log
void CLogger::log(const wchar_t* text, ELOG_LEVEL ll)
{
if (ll < LogLevel)
return;
core::stringc s = text;
log(s.c_str(), ll);
}
//! Prints out a text into the log
void CLogger::log(const wchar_t* text, const wchar_t* hint, ELOG_LEVEL ll)
{
if (ll < LogLevel)
return;
core::stringc s1 = text;
core::stringc s2 = hint;
log(s1.c_str(), s2.c_str(), ll);
}
//! Prints out a text into the log
void CLogger::log(const c8* text, const wchar_t* hint, ELOG_LEVEL ll)
{
if (ll < LogLevel)
return;
core::stringc s2 = hint;
log( text, s2.c_str(), ll);
}
//! Sets a new event receiver
void CLogger::setReceiver(IEventReceiver* r)
{
Receiver = r;
}
} // end namespace irr
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#include "CLogger.h"
namespace irr
{
CLogger::CLogger(IEventReceiver* r)
: LogLevel(ELL_INFORMATION), Receiver(r)
{
#ifdef _DEBUG
setDebugName("CLogger");
#endif
}
//! Returns the current set log level.
ELOG_LEVEL CLogger::getLogLevel() const
{
return LogLevel;
}
//! Sets a new log level.
void CLogger::setLogLevel(ELOG_LEVEL ll)
{
LogLevel = ll;
}
//! Prints out a text into the log
void CLogger::log(const c8* text, ELOG_LEVEL ll)
{
if (ll < LogLevel)
return;
if (Receiver)
{
SEvent event;
event.EventType = EET_LOG_TEXT_EVENT;
event.LogEvent.Text = text;
event.LogEvent.Level = ll;
if (Receiver->OnEvent(event))
return;
}
os::Printer::print(text);
}
//! Prints out a text into the log
void CLogger::log(const c8* text, const c8* hint, ELOG_LEVEL ll)
{
if (ll < LogLevel)
return;
core::stringc s = text;
s += ": ";
s += hint;
log (s.c_str(), ll);
}
//! Prints out a text into the log
void CLogger::log(const wchar_t* text, ELOG_LEVEL ll)
{
if (ll < LogLevel)
return;
core::stringc s = text;
log(s.c_str(), ll);
}
//! Prints out a text into the log
void CLogger::log(const wchar_t* text, const wchar_t* hint, ELOG_LEVEL ll)
{
if (ll < LogLevel)
return;
core::stringc s1 = text;
core::stringc s2 = hint;
log(s1.c_str(), s2.c_str(), ll);
}
//! Prints out a text into the log
void CLogger::log(const c8* text, const wchar_t* hint, ELOG_LEVEL ll)
{
if (ll < LogLevel)
return;
core::stringc s2 = hint;
log( text, s2.c_str(), ll);
}
//! Sets a new event receiver
void CLogger::setReceiver(IEventReceiver* r)
{
Receiver = r;
}
} // end namespace irr

View File

@ -1,52 +1,52 @@
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#pragma once
#include "ILogger.h"
#include "os.h"
#include "irrString.h"
#include "IEventReceiver.h"
namespace irr
{
//! Class for logging messages, warnings and errors to stdout
class CLogger : public ILogger
{
public:
CLogger(IEventReceiver* r);
//! Returns the current set log level.
ELOG_LEVEL getLogLevel() const override;
//! Sets a new log level. void setLogLevel(ELOG_LEVEL ll) override;
void setLogLevel(ELOG_LEVEL ll) override;
//! Prints out a text into the log
void log(const c8* text, ELOG_LEVEL ll=ELL_INFORMATION) override;
//! Prints out a text into the log
void log(const wchar_t* text, ELOG_LEVEL ll=ELL_INFORMATION) override;
//! Prints out a text into the log
void log(const c8* text, const c8* hint, ELOG_LEVEL ll=ELL_INFORMATION) override;
//! Prints out a text into the log
void log(const c8* text, const wchar_t* hint, ELOG_LEVEL ll=ELL_INFORMATION) override;
//! Prints out a text into the log
void log(const wchar_t* text, const wchar_t* hint, ELOG_LEVEL ll=ELL_INFORMATION) override;
//! Sets a new event receiver
void setReceiver(IEventReceiver* r);
private:
ELOG_LEVEL LogLevel;
IEventReceiver* Receiver;
};
} // end namespace
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#pragma once
#include "ILogger.h"
#include "os.h"
#include "irrString.h"
#include "IEventReceiver.h"
namespace irr
{
//! Class for logging messages, warnings and errors to stdout
class CLogger : public ILogger
{
public:
CLogger(IEventReceiver* r);
//! Returns the current set log level.
ELOG_LEVEL getLogLevel() const override;
//! Sets a new log level. void setLogLevel(ELOG_LEVEL ll) override;
void setLogLevel(ELOG_LEVEL ll) override;
//! Prints out a text into the log
void log(const c8* text, ELOG_LEVEL ll=ELL_INFORMATION) override;
//! Prints out a text into the log
void log(const wchar_t* text, ELOG_LEVEL ll=ELL_INFORMATION) override;
//! Prints out a text into the log
void log(const c8* text, const c8* hint, ELOG_LEVEL ll=ELL_INFORMATION) override;
//! Prints out a text into the log
void log(const c8* text, const wchar_t* hint, ELOG_LEVEL ll=ELL_INFORMATION) override;
//! Prints out a text into the log
void log(const wchar_t* text, const wchar_t* hint, ELOG_LEVEL ll=ELL_INFORMATION) override;
//! Sets a new event receiver
void setReceiver(IEventReceiver* r);
private:
ELOG_LEVEL LogLevel;
IEventReceiver* Receiver;
};
} // end namespace

View File

@ -1,187 +1,187 @@
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#include "CMemoryFile.h"
#include "irrString.h"
namespace irr
{
namespace io
{
CMemoryReadFile::CMemoryReadFile(const void* memory, long len, const io::path& fileName, bool d)
: Buffer(memory), Len(len), Pos(0), Filename(fileName), deleteMemoryWhenDropped(d)
{
#ifdef _DEBUG
setDebugName("CMemoryReadFile");
#endif
}
CMemoryReadFile::~CMemoryReadFile()
{
if (deleteMemoryWhenDropped)
delete [] (c8*)Buffer;
}
//! returns how much was read
size_t CMemoryReadFile::read(void* buffer, size_t sizeToRead)
{
long amount = static_cast<long>(sizeToRead);
if (Pos + amount > Len)
amount -= Pos + amount - Len;
if (amount <= 0)
return 0;
c8* p = (c8*)Buffer;
memcpy(buffer, p + Pos, amount);
Pos += amount;
return static_cast<size_t>(amount);
}
//! changes position in file, returns true if successful
//! if relativeMovement==true, the pos is changed relative to current pos,
//! otherwise from begin of file
bool CMemoryReadFile::seek(long finalPos, bool relativeMovement)
{
if (relativeMovement)
{
if (Pos + finalPos < 0 || Pos + finalPos > Len)
return false;
Pos += finalPos;
}
else
{
if (finalPos < 0 || finalPos > Len)
return false;
Pos = finalPos;
}
return true;
}
//! returns size of file
long CMemoryReadFile::getSize() const
{
return Len;
}
//! returns where in the file we are.
long CMemoryReadFile::getPos() const
{
return Pos;
}
//! returns name of file
const io::path& CMemoryReadFile::getFileName() const
{
return Filename;
}
CMemoryWriteFile::CMemoryWriteFile(void* memory, long len, const io::path& fileName, bool d)
: Buffer(memory), Len(len), Pos(0), Filename(fileName), deleteMemoryWhenDropped(d)
{
#ifdef _DEBUG
setDebugName("CMemoryWriteFile");
#endif
}
CMemoryWriteFile::~CMemoryWriteFile()
{
if (deleteMemoryWhenDropped)
delete [] (c8*)Buffer;
}
//! returns how much was written
size_t CMemoryWriteFile::write(const void* buffer, size_t sizeToWrite)
{
long amount = (long)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 (size_t)amount;
}
//! changes position in file, returns true if successful
//! if relativeMovement==true, the pos is changed relative to current pos,
//! otherwise from begin of file
bool CMemoryWriteFile::seek(long finalPos, bool relativeMovement)
{
if (relativeMovement)
{
if (Pos + finalPos < 0 || Pos + finalPos > Len)
return false;
Pos += finalPos;
}
else
{
if (finalPos < 0 || finalPos > Len)
return false;
Pos = finalPos;
}
return true;
}
//! returns where in the file we are.
long CMemoryWriteFile::getPos() const
{
return Pos;
}
//! returns name of file
const io::path& CMemoryWriteFile::getFileName() const
{
return Filename;
}
bool CMemoryWriteFile::flush()
{
return true; // no buffering, so nothing to do
}
IReadFile* createMemoryReadFile(const void* memory, long size, const io::path& fileName, bool deleteMemoryWhenDropped)
{
CMemoryReadFile* file = new CMemoryReadFile(memory, size, fileName, deleteMemoryWhenDropped);
return file;
}
IWriteFile* createMemoryWriteFile(void* memory, long size, const io::path& fileName, bool deleteMemoryWhenDropped)
{
CMemoryWriteFile* file = new CMemoryWriteFile(memory, size, fileName, deleteMemoryWhenDropped);
return file;
}
} // end namespace io
} // end namespace irr
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#include "CMemoryFile.h"
#include "irrString.h"
namespace irr
{
namespace io
{
CMemoryReadFile::CMemoryReadFile(const void* memory, long len, const io::path& fileName, bool d)
: Buffer(memory), Len(len), Pos(0), Filename(fileName), deleteMemoryWhenDropped(d)
{
#ifdef _DEBUG
setDebugName("CMemoryReadFile");
#endif
}
CMemoryReadFile::~CMemoryReadFile()
{
if (deleteMemoryWhenDropped)
delete [] (c8*)Buffer;
}
//! returns how much was read
size_t CMemoryReadFile::read(void* buffer, size_t sizeToRead)
{
long amount = static_cast<long>(sizeToRead);
if (Pos + amount > Len)
amount -= Pos + amount - Len;
if (amount <= 0)
return 0;
c8* p = (c8*)Buffer;
memcpy(buffer, p + Pos, amount);
Pos += amount;
return static_cast<size_t>(amount);
}
//! changes position in file, returns true if successful
//! if relativeMovement==true, the pos is changed relative to current pos,
//! otherwise from begin of file
bool CMemoryReadFile::seek(long finalPos, bool relativeMovement)
{
if (relativeMovement)
{
if (Pos + finalPos < 0 || Pos + finalPos > Len)
return false;
Pos += finalPos;
}
else
{
if (finalPos < 0 || finalPos > Len)
return false;
Pos = finalPos;
}
return true;
}
//! returns size of file
long CMemoryReadFile::getSize() const
{
return Len;
}
//! returns where in the file we are.
long CMemoryReadFile::getPos() const
{
return Pos;
}
//! returns name of file
const io::path& CMemoryReadFile::getFileName() const
{
return Filename;
}
CMemoryWriteFile::CMemoryWriteFile(void* memory, long len, const io::path& fileName, bool d)
: Buffer(memory), Len(len), Pos(0), Filename(fileName), deleteMemoryWhenDropped(d)
{
#ifdef _DEBUG
setDebugName("CMemoryWriteFile");
#endif
}
CMemoryWriteFile::~CMemoryWriteFile()
{
if (deleteMemoryWhenDropped)
delete [] (c8*)Buffer;
}
//! returns how much was written
size_t CMemoryWriteFile::write(const void* buffer, size_t sizeToWrite)
{
long amount = (long)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 (size_t)amount;
}
//! changes position in file, returns true if successful
//! if relativeMovement==true, the pos is changed relative to current pos,
//! otherwise from begin of file
bool CMemoryWriteFile::seek(long finalPos, bool relativeMovement)
{
if (relativeMovement)
{
if (Pos + finalPos < 0 || Pos + finalPos > Len)
return false;
Pos += finalPos;
}
else
{
if (finalPos < 0 || finalPos > Len)
return false;
Pos = finalPos;
}
return true;
}
//! returns where in the file we are.
long CMemoryWriteFile::getPos() const
{
return Pos;
}
//! returns name of file
const io::path& CMemoryWriteFile::getFileName() const
{
return Filename;
}
bool CMemoryWriteFile::flush()
{
return true; // no buffering, so nothing to do
}
IReadFile* createMemoryReadFile(const void* memory, long size, const io::path& fileName, bool deleteMemoryWhenDropped)
{
CMemoryReadFile* file = new CMemoryReadFile(memory, size, fileName, deleteMemoryWhenDropped);
return file;
}
IWriteFile* createMemoryWriteFile(void* memory, long size, const io::path& fileName, bool deleteMemoryWhenDropped)
{
CMemoryWriteFile* file = new CMemoryWriteFile(memory, size, fileName, deleteMemoryWhenDropped);
return file;
}
} // end namespace io
} // end namespace irr

Some files were not shown because too many files have changed in this diff Show More