|
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
//********************************************** //Singleton Texture Manager class //Written by Ben English //benjamin.english@oit.edu // //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 //benjamin.english@oit.edu // //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效果图: tga效果图: jpg效果图: png效果图: 有的图的效果不是想要的,可能和RGB的顺序有关。
|