📄 devilimaging.cpp
字号:
// ___ ___ ___ ___ ___ // /\__\ ___ /\__\ /\ \ /\__\ /\ \. // /::| | /\ \ /::| | /::\ \ /:/ / /::\ \. // /:|:| | \:\ \ /:|:| | /:/\:\ \ /:/ / /:/\:\ \. // /:/|:|__|__ /::\__\ /:/|:| |__ /:/ \:\ \ /:/ / /::\~\:\ \. // /:/ |::::\__\ __/:/\/__/ /:/ |:| /\__\ /:/__/_\:\__\ /:/__/ /:/\:\ \:\__\.// \/__/~~/:/ / /\/:/ / \/__|:|/:/ / \:\ /\ \/__/ \:\ \ \:\~\:\ \/__/// /:/ / \::/__/ |:/:/ / \:\ \:\__\ \:\ \ \:\ \:\__\. // /:/ / \:\__\ |::/ / \:\/:/ / \:\ \ \:\ \/__/ // /:/ / \/__/ /:/ / \::/ / \:\__\ \:\__\. // \/__/ \/__/ \/__/ \/__/ \/__/ // // =============================================================================// Minimalist OpenGL Environment// =============================================================================//// This file is part of Minimalist OpenGL Environment (MinGLE)//// Version: 0.2.0// Author: Balazs Domonkos// Filename: src/imaging/src/DevilImage.cpp// Creation Date: January 11th 2008// Revision Date: January 11th 2008////// The Minimalist OpenGL Environment is free software: you can// redistribute it and/or modify it under the terms of the GNU// General Public License as published by the Free Software// Foundation, either version 3 of the License, or (at your// option) any later version.//// The Minimalist OpenGL Environment is distributed in the hope// that it will be useful, but WITHOUT ANY WARRANTY; without// even the implied warranty of MERCHANTABILITY or FITNESS FOR// A PARTICULAR PURPOSE. See the GNU General Public License// for more details.//// You should have received a copy of the GNU General Public License// along with Minimalist OpenGL Environment. If not, see // <http://www.gnu.org/licenses/>. See the COPYING file included // with this distribution file for license details.///// @file DevilImage.cpp/// DevIL imaging implementation// Header that contains the declaration#include <DevilImaging.h>// MinGLE headers#include <Exception.h>#include <GLUtils.h>#include <System.h>namespace MinGLE {// Dynamic library loader functionextern "C"void loadDynLib(void) { // Create and register DevIL imaging system implementation Imaging::registerImplementation("devil", new DevilImaging());}// Dynamic library unloader functionextern "C" void unloadDynLib(void) { // Nothing to do}// =============================================================================GuardedPointer<VirtualFileSystem> DevilImage::msCurrentVfs;VirtualFileSystem *DevilImage::msLockedVfs;DevilImage::DevilImage() { _genImage();}DevilImage::DevilImage(unsigned width, unsigned height, GLenum format, GLenum type, void *data) { mWidth = width; mHeight = height; mBytesPerPixel = GLUtils::calculateBytesPerPixel(format, type); mTotalSize = mWidth*mHeight*mBytesPerPixel; mFormat = format; mType = type; _genImage(); _createFromMemory(width, height, format, type, data);}DevilImage::DevilImage(const std::string& filename, VirtualFileSystem *vfs) { _genImage(); _loadFromFile(filename, vfs);}DevilImage::DevilImage(const Image * image) { _genImage(); _createFromMemory(image->mWidth, image->mHeight, image->mFormat, image->mType, image->mData);}DevilImage::~DevilImage() { _deleteImage();}void DevilImage::loadFromFile(const std::string& filename, VirtualFileSystem *vfs) { _loadFromFile(filename, vfs);}void DevilImage::createFromMemory(unsigned width, unsigned height, GLenum format, GLenum type, void *data) { _createFromMemory(width, height, format, type, data);}void DevilImage::grabFromScreen() {#ifdef ILUT_USE_OPENGL _bindImage(); ilutGLScreen(); _getAttributes();#else Except("DevilImage::grabFromScreen", "ilutGLScreen() function is not supported in your ILUT implementation.");#endif}void DevilImage::saveToFile(const std::string& filename, VirtualFileSystem *vfs) { // Setup virtual file system for DevIL _setVFSFunctionPointers(vfs); // TODO might freeze on HP HPC Linux with pthread msLockedVfs = msCurrentVfs.lock(); // Convert to unsigned byte (for fixed point data formats) std::string ext = VirtualFileSystem::getExtension(filename); if(ext == "jpg" || ext == "png" || ext == "tga" || ext == "bmp") convert(mFormat, GL_UNSIGNED_BYTE); // Save image ilSaveImage((char *) filename.c_str()); // TODO freeze on HP HPC Linux with pthread msCurrentVfs.unlock();}void DevilImage::saveToFile(const std::string& pattern, unsigned index, VirtualFileSystem *vfs) { // TODO: possible memory corruption char filename[pattern.size()+32]; sprintf(filename, pattern.c_str(), index); saveToFile(filename);}void DevilImage::saveToFile(const std::string& pattern, unsigned index1, unsigned index2, VirtualFileSystem *vfs) { // TODO: possible memory corruption char filename[pattern.size()+32]; sprintf(filename, pattern.c_str(), index1, index2); saveToFile(filename);}void DevilImage::texImage2D(GLint level) { _bindImage(); // Image with power of two sizes or OpenGL version >= 2.0 if(MathUtils::isPowerOf2(mWidth) && MathUtils::isPowerOf2(mHeight) || System::getGLVersion().major >= 2) glTexImage2D(GL_TEXTURE_2D, level, mFormat, mWidth, mHeight, 0, mFormat, mType, mData); // Need to resize else { // Calculate new sizes GLsizei width = MathUtils::convertToPowerOf2(mWidth), height = MathUtils::convertToPowerOf2(mHeight); // Scale image Image *scaledImage = new DevilImage(width, height, mFormat, mType, 0); gluScaleImage(mFormat, (GLsizei) mWidth, (GLsizei) mHeight, mType, mData, width, height, mType, scaledImage->mData ); // Set texture glTexImage2D(GL_TEXTURE_2D, level, mFormat, width, height, 0, mFormat, mType, scaledImage->mData); delete scaledImage; }}void DevilImage::convert(GLenum format, GLenum type) { ilConvertImage(DevilImaging::_convertFormatGL2IL(format), DevilImaging::_convertTypeGL2IL(type));}void DevilImage::mirror() { _bindImage(); iluMirror();}void DevilImage::flip() { _bindImage(); iluFlipImage();}void DevilImage::clear(float r, float g, float b, float a) { _bindImage(); ilClearColour((ILclampf) r, (ILclampf) g, (ILclampf) b, (ILclampf) a); ilClearImage();}void DevilImage::_setVFSFunctionPointers(VirtualFileSystem *vfs) { msCurrentVfs.assign(vfs); ilSetRead(_fOpenRProc, _fCloseRProc, _fEofProc, _fGetcProc, _fReadProc, _fSeekRProc, _fTellRProc); ilSetWrite(_fOpenWProc, _fCloseWProc, _fPutcProc, _fSeekWProc, _fTellWProc, _fWriteProc);}void DevilImage::_loadFromFile(const std::string& filename, VirtualFileSystem *vfs) { // Setup virtual file system for DevIL _setVFSFunctionPointers(vfs); // TODO might freeze on HP HPC Linux with pthread msLockedVfs = msCurrentVfs.lock(); _bindImage(); Assert(ilLoadImage((char *) filename.c_str()) == IL_TRUE, "DevilImage::_loadFromFile"); _getAttributes(); // TODO freeze on HP HPC Linux with pthread msCurrentVfs.unlock();}void DevilImage::_createFromMemory(unsigned width, unsigned height, GLenum format, GLenum type, void *data) { _bindImage(); // If not data supplied, allocate blank data bool nullData = false; if(!data) { data = _allocateMemory(width, height, format, type); nullData = true; } // Create image object ilTexImage( width, height, 1, GLUtils::calculateNumberOfChannels(format), DevilImaging::_convertFormatGL2IL(format), DevilImaging::_convertTypeGL2IL(type), data ); if(nullData) free(data); _getAttributes();}void DevilImage::_genImage() { ilGenImages(1, &mImageId);}void DevilImage::_deleteImage() { ilDeleteImages(1, &mImageId); // Set the data pointer to null explicitly // Image::~Image() will check for its nullness mData = 0;}void DevilImage::_bindImage() { ilBindImage(mImageId);}void DevilImage::_getAttributes() { ILinfo ilInfo; iluGetImageInfo(&ilInfo); mWidth = ilInfo.Width; mHeight = ilInfo.Height; mBytesPerPixel = ilInfo.Bpp; mTotalSize = ilInfo.SizeOfData; mFormat = DevilImaging::_convertFormatIL2GL(ilInfo.Format); mType = DevilImaging::_convertTypeIL2GL(ilInfo.Type); mData = ilGetData();}// Callback functions for file readingILvoid DevilImage::_fCloseRProc(ILHANDLE handle) { msLockedVfs->close((VirtualFileSystem::FileHandle) handle);}ILboolean DevilImage::_fEofProc(ILHANDLE handle) { return (ILboolean) msLockedVfs->eof((VirtualFileSystem::FileHandle) handle);}ILint DevilImage::_fGetcProc(ILHANDLE handle) { return (ILint) msLockedVfs->getchar((VirtualFileSystem::FileHandle) handle);}ILHANDLE DevilImage::_fOpenRProc(const ILstring filename) { return (ILHANDLE) msLockedVfs->open(filename, "rb");}ILint DevilImage::_fReadProc(void* ptr, ILuint size, ILuint count, ILHANDLE handle) { return (ILint) msLockedVfs->read(ptr, (int) size, (int) count, (VirtualFileSystem::FileHandle) handle);}ILint DevilImage::_fSeekRProc(ILHANDLE handle, ILint offset, ILint whence) { return (ILint) msLockedVfs->seek((VirtualFileSystem::FileHandle) handle, (int) offset, (int) whence);}ILint DevilImage::_fTellRProc(ILHANDLE handle) { return (ILint) msLockedVfs->tell((VirtualFileSystem::FileHandle) handle);}// Callback functions for file writingILvoid DevilImage::_fCloseWProc(ILHANDLE handle) { msLockedVfs->close((VirtualFileSystem::FileHandle) handle);}ILHANDLE DevilImage::_fOpenWProc(const ILstring filename) { return (ILHANDLE) msLockedVfs->open(filename, "wb");}ILint DevilImage::_fPutcProc(ILubyte ch, ILHANDLE handle) { return (ILint) msLockedVfs->putchar((int) ch, (VirtualFileSystem::FileHandle) handle);}ILint DevilImage::_fSeekWProc(ILHANDLE handle, ILint offset, ILint whence) { return (ILint) msLockedVfs->seek((VirtualFileSystem::FileHandle) handle, (int) offset, (int) whence);}ILint DevilImage::_fTellWProc(ILHANDLE handle) { return (ILint) msLockedVfs->tell((VirtualFileSystem::FileHandle) handle);}ILint DevilImage::_fWriteProc(const void* ptr, ILuint size, ILuint count, ILHANDLE handle) { return (ILint) msLockedVfs->write(ptr, (int) size, (int) count, (VirtualFileSystem::FileHandle) handle);}// =============================================================================DevilImaging::DevilImaging() { ilInit(); iluInit(); ilutInit(); ilEnable(IL_FILE_OVERWRITE); /* // Add support for misc file formats #if MINGLE_PFS_SUPPORT == 1 ilRegisterLoad("pfs", loadPFS); ilRegisterSave("pfs", savePFS); #endif // MINGLE_PFS_SUPPORT == 1 */}DevilImaging::~DevilImaging() { // Nothing to do}Image *DevilImaging::_createImage() { return new DevilImage();}Image *DevilImaging::_createImage(unsigned width, unsigned height, GLenum format, GLenum type, void *data) { return new DevilImage(width, height, format, type, data);}Image *DevilImaging::_createImage(const std::string& filename, VirtualFileSystem *vfs) { return new DevilImage(filename, vfs);}Image *DevilImaging::_createImage(const Image * image) { return new DevilImage(image);}GLenum DevilImaging::_convertFormatIL2GL(unsigned format) { switch(format) { case IL_COLOR_INDEX: return GL_COLOR_INDEX; case IL_RGB: return GL_RGB; case IL_RGBA: return GL_RGBA;#if defined(GL_BGR) && defined(GL_BGRA) case IL_BGR: return GL_BGR; case IL_BGRA: return GL_BGRA;#else case IL_BGR: Except("DevilImaging::_convertFormatIL2GL", "Pixel format \'GL_BGR\' is not supported."); case IL_BGRA: Except("DevilImaging::_convertFormatIL2GL", "Pixel format \'GL_BGRA\' is not supported.");#endif case IL_LUMINANCE: return GL_LUMINANCE; case IL_LUMINANCE_ALPHA: return GL_LUMINANCE_ALPHA; default: Except("DevilImaging::_convertFormatIL2GL", "Invalid format"); } return 0;}unsigned DevilImaging::_convertFormatGL2IL(GLenum format) { switch(format) { case GL_COLOR_INDEX: return IL_COLOR_INDEX; case GL_RGB: return IL_RGB; case GL_RGBA: return IL_RGBA;#if defined(GL_BGR) && defined(GL_BGRA) case GL_BGR: return IL_BGR; case GL_BGRA: return IL_BGRA;#endif case GL_LUMINANCE: return IL_LUMINANCE; case GL_LUMINANCE_ALPHA: return IL_LUMINANCE_ALPHA; default: Except("DevilImaging::_convertFormatGL2IL", "Invalid format"); } return 0;}GLenum DevilImaging::_convertTypeIL2GL(unsigned type) { switch(type) { case IL_BYTE: return GL_BYTE; case IL_UNSIGNED_BYTE: return GL_UNSIGNED_BYTE; case IL_SHORT: return GL_SHORT; case IL_UNSIGNED_SHORT: return GL_UNSIGNED_SHORT; case IL_INT: return GL_INT; case IL_UNSIGNED_INT: return GL_UNSIGNED_INT; case IL_FLOAT: return GL_FLOAT; case IL_DOUBLE: return GL_DOUBLE; default: Except("DevilImaging::_convertTypeIL2GL", "Invalid pixel type"); } return 0;}unsigned DevilImaging::_convertTypeGL2IL(GLenum type) { switch(type) { case GL_BYTE: return IL_BYTE; case GL_UNSIGNED_BYTE: return IL_UNSIGNED_BYTE; case GL_SHORT: return IL_SHORT; case GL_UNSIGNED_SHORT: return IL_UNSIGNED_SHORT; case GL_INT: return IL_INT; case GL_UNSIGNED_INT: return IL_UNSIGNED_INT; case GL_FLOAT: return IL_FLOAT; case GL_DOUBLE: return IL_DOUBLE; default: Except("DevilImaging::_convertTypeGL2IL", "Invalid pixel type"); } return 0;}} // namespace MinGLE
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -