OpenGL中用FreeImage
FreeImage is an Open Source library project for developers who would like to support popular graphics image formats like PNG, BMP, JPEG, TIFF and others as needed by today's multimedia applications. FreeImage is easy to use, fast, multithreading safe, compatible with all 32-bit versions of Windows, and cross-platform (works both with Linux and Mac OS X).
测试过png,bmp,jpg,tga。
TextureManager.h
TextureManager.cpp
Main.cpp
tga效果图:
jpg效果图:
png效果图:
有的图的效果不是想要的,可能和RGB的顺序有关。
测试过png,bmp,jpg,tga。
TextureManager.h
//
**********************************************
// Singleton Texture Manager class
// Written by Ben English
// [email protected]
//
// For use with OpenGL and the FreeImage library
// **********************************************
#ifndef TextureManager_H
#define TextureManager_H
#include < gl / glew.h >
#include " FreeImage.h "
#include < map >
class TextureManager
{
public:
static TextureManager* Inst();
virtual ~TextureManager();
//load a texture an make it the current texture
//if texID is already in use, it will be unloaded and replaced with this texture
bool LoadTexture(const char* filename, //where to load the file from
const unsigned int texID, //arbitrary id you will reference the texture by
//does not have to be generated with glGenTextures
GLenum image_format = GL_RGB, //format the image is in
GLint internal_format = GL_RGB, //format to store the image in
GLint level = 0, //mipmapping level
GLint border = 0); //border size
//free the memory for a texture
bool UnloadTexture(const unsigned int texID);
//set the current texture
bool BindTexture(const unsigned int texID);
//free all texture memory
void UnloadAllTextures();
protected:
TextureManager();
TextureManager(const TextureManager& tm);
TextureManager& operator=(const TextureManager& tm);
static TextureManager* m_inst;
std::map<unsigned int, GLuint> m_texID;
} ;
#endif
// Singleton Texture Manager class
// Written by Ben English
// [email protected]
//
// For use with OpenGL and the FreeImage library
// **********************************************
#ifndef TextureManager_H
#define TextureManager_H
#include < gl / glew.h >
#include " FreeImage.h "
#include < map >
class TextureManager
{
public:
static TextureManager* Inst();
virtual ~TextureManager();
//load a texture an make it the current texture
//if texID is already in use, it will be unloaded and replaced with this texture
bool LoadTexture(const char* filename, //where to load the file from
const unsigned int texID, //arbitrary id you will reference the texture by
//does not have to be generated with glGenTextures
GLenum image_format = GL_RGB, //format the image is in
GLint internal_format = GL_RGB, //format to store the image in
GLint level = 0, //mipmapping level
GLint border = 0); //border size
//free the memory for a texture
bool UnloadTexture(const unsigned int texID);
//set the current texture
bool BindTexture(const unsigned int texID);
//free all texture memory
void UnloadAllTextures();
protected:
TextureManager();
TextureManager(const TextureManager& tm);
TextureManager& operator=(const TextureManager& tm);
static TextureManager* m_inst;
std::map<unsigned int, GLuint> m_texID;
} ;
#endif
TextureManager.cpp
//
**********************************************
// Singleton Texture Manager class
// Written by Ben English
// [email protected]
//
// For use with OpenGL and the FreeImage library
// **********************************************
#include " TextureManager.h "
TextureManager * TextureManager::m_inst( 0 );
TextureManager * TextureManager::Inst()
{
if(!m_inst)
m_inst = new TextureManager();
return m_inst;
}
TextureManager::TextureManager()
{
// call this ONLY when linking with FreeImage as a static library
#ifdef FREEIMAGE_LIB
FreeImage_Initialise();
#endif
}
// these should never be called
// TextureManager::TextureManager(const TextureManager& tm){}
// TextureManager& TextureManager::operator=(const TextureManager& tm){}
TextureManager:: ~ TextureManager()
{
// call this ONLY when linking with FreeImage as a static library
#ifdef FREEIMAGE_LIB
FreeImage_DeInitialise();
#endif
UnloadAllTextures();
m_inst = 0;
}
bool TextureManager::LoadTexture( const char * filename, const unsigned int texID, GLenum image_format, GLint internal_format, GLint level, GLint border)
{
//image format
FREE_IMAGE_FORMAT fif = FIF_UNKNOWN;
//pointer to the image, once loaded
FIBITMAP *dib(0);
//pointer to the image data
BYTE* bits(0);
//image width and height
unsigned int width(0), height(0);
//OpenGL's image ID to map to
GLuint gl_texID;
//check the file signature and deduce its format
fif = FreeImage_GetFileType(filename, 0);
//if still unknown, try to guess the file format from the file extension
if(fif == FIF_UNKNOWN)
fif = FreeImage_GetFIFFromFilename(filename);
//if still unkown, return failure
if(fif == FIF_UNKNOWN)
return false;
//check that the plugin has reading capabilities and load the file
if(FreeImage_FIFSupportsReading(fif))
dib = FreeImage_Load(fif, filename);
//if the image failed to load, return failure
if(!dib)
return false;
//retrieve the image data
bits = FreeImage_GetBits(dib);
//get the image width and height
width = FreeImage_GetWidth(dib);
height = FreeImage_GetHeight(dib);
//if this somehow one of these failed (they shouldn't), return failure
if((bits == 0) || (width == 0) || (height == 0))
return false;
//if this texture ID is in use, unload the current texture
if(m_texID.find(texID) != m_texID.end())
glDeleteTextures(1, &(m_texID[texID]));
//generate an OpenGL texture ID for this texture
glGenTextures(1, &gl_texID);
//store the texture ID mapping
m_texID[texID] = gl_texID;
//bind to the new texture ID
glBindTexture(GL_TEXTURE_2D, gl_texID);
//store the texture data for OpenGL use
glTexImage2D(GL_TEXTURE_2D, level, internal_format, width, height,
border, image_format, GL_UNSIGNED_BYTE, bits);
//Free FreeImage's copy of the data
FreeImage_Unload(dib);
//return success
return true;
}
bool TextureManager::UnloadTexture( const unsigned int texID)
{
bool result(true);
//if this texture ID mapped, unload it's texture, and remove it from the map
if(m_texID.find(texID) != m_texID.end())
{
glDeleteTextures(1, &(m_texID[texID]));
m_texID.erase(texID);
}
//otherwise, unload failed
else
{
result = false;
}
return result;
}
bool TextureManager::BindTexture( const unsigned int texID)
{
bool result(true);
//if this texture ID mapped, bind it's texture as current
if(m_texID.find(texID) != m_texID.end())
glBindTexture(GL_TEXTURE_2D, m_texID[texID]);
//otherwise, binding failed
else
result = false;
return result;
}
void TextureManager::UnloadAllTextures()
{
//start at the begginning of the texture map
std::map<unsigned int, GLuint>::iterator i = m_texID.begin();
//Unload the textures untill the end of the texture map is found
while(i != m_texID.end())
UnloadTexture(i->first);
//clear the texture map
m_texID.clear();
}
// Singleton Texture Manager class
// Written by Ben English
// [email protected]
//
// For use with OpenGL and the FreeImage library
// **********************************************
#include " TextureManager.h "
TextureManager * TextureManager::m_inst( 0 );
TextureManager * TextureManager::Inst()
{
if(!m_inst)
m_inst = new TextureManager();
return m_inst;
}
TextureManager::TextureManager()
{
// call this ONLY when linking with FreeImage as a static library
#ifdef FREEIMAGE_LIB
FreeImage_Initialise();
#endif
}
// these should never be called
// TextureManager::TextureManager(const TextureManager& tm){}
// TextureManager& TextureManager::operator=(const TextureManager& tm){}
TextureManager:: ~ TextureManager()
{
// call this ONLY when linking with FreeImage as a static library
#ifdef FREEIMAGE_LIB
FreeImage_DeInitialise();
#endif
UnloadAllTextures();
m_inst = 0;
}
bool TextureManager::LoadTexture( const char * filename, const unsigned int texID, GLenum image_format, GLint internal_format, GLint level, GLint border)
{
//image format
FREE_IMAGE_FORMAT fif = FIF_UNKNOWN;
//pointer to the image, once loaded
FIBITMAP *dib(0);
//pointer to the image data
BYTE* bits(0);
//image width and height
unsigned int width(0), height(0);
//OpenGL's image ID to map to
GLuint gl_texID;
//check the file signature and deduce its format
fif = FreeImage_GetFileType(filename, 0);
//if still unknown, try to guess the file format from the file extension
if(fif == FIF_UNKNOWN)
fif = FreeImage_GetFIFFromFilename(filename);
//if still unkown, return failure
if(fif == FIF_UNKNOWN)
return false;
//check that the plugin has reading capabilities and load the file
if(FreeImage_FIFSupportsReading(fif))
dib = FreeImage_Load(fif, filename);
//if the image failed to load, return failure
if(!dib)
return false;
//retrieve the image data
bits = FreeImage_GetBits(dib);
//get the image width and height
width = FreeImage_GetWidth(dib);
height = FreeImage_GetHeight(dib);
//if this somehow one of these failed (they shouldn't), return failure
if((bits == 0) || (width == 0) || (height == 0))
return false;
//if this texture ID is in use, unload the current texture
if(m_texID.find(texID) != m_texID.end())
glDeleteTextures(1, &(m_texID[texID]));
//generate an OpenGL texture ID for this texture
glGenTextures(1, &gl_texID);
//store the texture ID mapping
m_texID[texID] = gl_texID;
//bind to the new texture ID
glBindTexture(GL_TEXTURE_2D, gl_texID);
//store the texture data for OpenGL use
glTexImage2D(GL_TEXTURE_2D, level, internal_format, width, height,
border, image_format, GL_UNSIGNED_BYTE, bits);
//Free FreeImage's copy of the data
FreeImage_Unload(dib);
//return success
return true;
}
bool TextureManager::UnloadTexture( const unsigned int texID)
{
bool result(true);
//if this texture ID mapped, unload it's texture, and remove it from the map
if(m_texID.find(texID) != m_texID.end())
{
glDeleteTextures(1, &(m_texID[texID]));
m_texID.erase(texID);
}
//otherwise, unload failed
else
{
result = false;
}
return result;
}
bool TextureManager::BindTexture( const unsigned int texID)
{
bool result(true);
//if this texture ID mapped, bind it's texture as current
if(m_texID.find(texID) != m_texID.end())
glBindTexture(GL_TEXTURE_2D, m_texID[texID]);
//otherwise, binding failed
else
result = false;
return result;
}
void TextureManager::UnloadAllTextures()
{
//start at the begginning of the texture map
std::map<unsigned int, GLuint>::iterator i = m_texID.begin();
//Unload the textures untill the end of the texture map is found
while(i != m_texID.end())
UnloadTexture(i->first);
//clear the texture map
m_texID.clear();
}
Main.cpp
/**/
/************************************************************************/
/**/ /*Brief: Test all kinds of Textures in OpenGL */
/**/ /*Author: tiny */
/**/ /*Date: 09/29/2008 */
/**/ /************************************************************************/
#include " TextureManager.h "
#include < gl / glew.h >
#include < gl / glut.h >
// 全局贴图ID
GLuint texture[ 1 ];
void init()
{
//将2D贴图状态打开
glEnable( GL_TEXTURE_2D );
//单件贴图管理
//如果加载带路径的文件最好选用.\\这样的格式
TextureManager::Inst()->LoadTexture( "OpenGL_his.jpg", texture[0] );
//线性过滤一定要放到加载纹理的后面
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); // 线性滤波
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); // 线性滤波
glClearColor( 0.5, 0.5, 0.5, 0.5 );
}
void display()
{
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
//绑定纹理
TextureManager::Inst()->BindTexture( texture[0] );
//渲染
glBegin( GL_QUADS );
glTexCoord2d( 0, 0 ); glVertex3f( -5.0f, -5.0f, 0.0f );
glTexCoord2d( 0, 1 ); glVertex3f( -5.0f, 5.0f, 0.0f );
glTexCoord2d( 1, 1 ); glVertex3f( 5.0f, 5.0f, 0.0f );
glTexCoord2d( 1, 0 ); glVertex3f( 5.0f, -5.0f, 0.0f );
glEnd();
glFlush();
glutSwapBuffers();
}
void reshape( int w, int h )
{
glViewport( 0, 0, GLsizei( w ), GLsizei( h ) );
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
gluPerspective( 45, ( GLdouble ) w / ( GLdouble ) h, 1.0f, 1000.0f );
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
gluLookAt( 0, 0, 20, 0, 0, 0, 0, 1, 0 );
}
void keyboard( unsigned char key, int x, int y )
{
if ( key == 27 )
{
//释放掉贴图,防止内存泄露
TextureManager::Inst()->UnloadTexture( texture[0] );
exit( 0 );
}
}
int main( int argc, char * argv[] )
{
glutInit( &argc, argv );
glutInitDisplayMode( GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH );
glutInitWindowPosition( 300, 300 );
glutInitWindowSize( 400, 300 );
glutCreateWindow( "OpenGL Texture Test" );
init();
glutReshapeFunc( reshape );
glutKeyboardFunc( keyboard );
glutDisplayFunc( display );
glutMainLoop();
return 0;
}
bmp效果图:
/**/ /*Brief: Test all kinds of Textures in OpenGL */
/**/ /*Author: tiny */
/**/ /*Date: 09/29/2008 */
/**/ /************************************************************************/
#include " TextureManager.h "
#include < gl / glew.h >
#include < gl / glut.h >
// 全局贴图ID
GLuint texture[ 1 ];
void init()
{
//将2D贴图状态打开
glEnable( GL_TEXTURE_2D );
//单件贴图管理
//如果加载带路径的文件最好选用.\\这样的格式
TextureManager::Inst()->LoadTexture( "OpenGL_his.jpg", texture[0] );
//线性过滤一定要放到加载纹理的后面
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); // 线性滤波
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); // 线性滤波
glClearColor( 0.5, 0.5, 0.5, 0.5 );
}
void display()
{
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
//绑定纹理
TextureManager::Inst()->BindTexture( texture[0] );
//渲染
glBegin( GL_QUADS );
glTexCoord2d( 0, 0 ); glVertex3f( -5.0f, -5.0f, 0.0f );
glTexCoord2d( 0, 1 ); glVertex3f( -5.0f, 5.0f, 0.0f );
glTexCoord2d( 1, 1 ); glVertex3f( 5.0f, 5.0f, 0.0f );
glTexCoord2d( 1, 0 ); glVertex3f( 5.0f, -5.0f, 0.0f );
glEnd();
glFlush();
glutSwapBuffers();
}
void reshape( int w, int h )
{
glViewport( 0, 0, GLsizei( w ), GLsizei( h ) );
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
gluPerspective( 45, ( GLdouble ) w / ( GLdouble ) h, 1.0f, 1000.0f );
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
gluLookAt( 0, 0, 20, 0, 0, 0, 0, 1, 0 );
}
void keyboard( unsigned char key, int x, int y )
{
if ( key == 27 )
{
//释放掉贴图,防止内存泄露
TextureManager::Inst()->UnloadTexture( texture[0] );
exit( 0 );
}
}
int main( int argc, char * argv[] )
{
glutInit( &argc, argv );
glutInitDisplayMode( GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH );
glutInitWindowPosition( 300, 300 );
glutInitWindowSize( 400, 300 );
glutCreateWindow( "OpenGL Texture Test" );
init();
glutReshapeFunc( reshape );
glutKeyboardFunc( keyboard );
glutDisplayFunc( display );
glutMainLoop();
return 0;
}
tga效果图:
jpg效果图:
png效果图:
有的图的效果不是想要的,可能和RGB的顺序有关。