2012-08-02 01:43:55 +00:00
|
|
|
#include "GuiImage.h"
|
|
|
|
#include <iostream>
|
2012-08-09 21:19:07 +00:00
|
|
|
#include <boost/filesystem.hpp>
|
2012-08-02 01:43:55 +00:00
|
|
|
|
2012-08-29 18:53:53 +00:00
|
|
|
int GuiImage::getWidth() { return mWidth; }
|
2012-08-29 19:22:05 +00:00
|
|
|
int GuiImage::getHeight() { return mHeight; }
|
2012-08-09 21:19:07 +00:00
|
|
|
|
2012-08-29 21:52:25 +00:00
|
|
|
GuiImage::GuiImage(int offsetX, int offsetY, std::string path, unsigned int resizeWidth, unsigned int resizeHeight, bool resizeExact)
|
2012-08-02 01:43:55 +00:00
|
|
|
{
|
2012-08-29 18:53:53 +00:00
|
|
|
mTextureID = 0;
|
2012-08-09 21:19:07 +00:00
|
|
|
|
|
|
|
mOffsetX = offsetX;
|
|
|
|
mOffsetY = offsetY;
|
|
|
|
|
2012-08-13 18:32:53 +00:00
|
|
|
//default origin (center of image)
|
2012-08-15 06:18:06 +00:00
|
|
|
mOriginX = 0.5;
|
|
|
|
mOriginY = 0.5;
|
2012-08-13 18:32:53 +00:00
|
|
|
|
2012-08-29 18:53:53 +00:00
|
|
|
mWidth = 0;
|
|
|
|
mHeight = 0;
|
|
|
|
|
2012-08-13 18:32:53 +00:00
|
|
|
mTiled = false;
|
|
|
|
|
2012-08-29 21:52:25 +00:00
|
|
|
mResizeWidth = resizeWidth;
|
|
|
|
mResizeHeight = resizeHeight;
|
2012-08-13 18:32:53 +00:00
|
|
|
|
2012-08-10 19:28:34 +00:00
|
|
|
mResizeExact = resizeExact;
|
2012-08-13 18:32:53 +00:00
|
|
|
mUseAlpha = false;
|
2012-08-09 21:19:07 +00:00
|
|
|
|
2012-08-02 01:43:55 +00:00
|
|
|
if(!path.empty())
|
|
|
|
setImage(path);
|
|
|
|
}
|
|
|
|
|
|
|
|
GuiImage::~GuiImage()
|
|
|
|
{
|
2012-08-29 18:53:53 +00:00
|
|
|
unloadImage();
|
2012-08-02 01:43:55 +00:00
|
|
|
}
|
|
|
|
|
2012-08-10 02:17:48 +00:00
|
|
|
void GuiImage::loadImage(std::string path)
|
2012-08-09 21:19:07 +00:00
|
|
|
{
|
2012-08-29 18:53:53 +00:00
|
|
|
//make sure the file *exists*
|
|
|
|
if(!boost::filesystem::exists(path))
|
2012-08-02 01:43:55 +00:00
|
|
|
{
|
2012-08-29 18:53:53 +00:00
|
|
|
std::cerr << "File \"" << path << "\" not found!\n";
|
|
|
|
return;
|
|
|
|
}
|
2012-08-09 21:19:07 +00:00
|
|
|
|
2012-08-29 18:53:53 +00:00
|
|
|
FREE_IMAGE_FORMAT format = FIF_UNKNOWN;
|
|
|
|
FIBITMAP* image = NULL;
|
|
|
|
BYTE* imageData = NULL;
|
|
|
|
unsigned int width, height;
|
2012-08-09 21:19:07 +00:00
|
|
|
|
2012-08-29 18:53:53 +00:00
|
|
|
//detect the filetype
|
|
|
|
//format = FreeImage_GetFileType(path.c_str(), 0);
|
|
|
|
if(format == FIF_UNKNOWN)
|
|
|
|
format = FreeImage_GetFIFFromFilename(path.c_str());
|
|
|
|
if(format == FIF_UNKNOWN)
|
|
|
|
{
|
|
|
|
std::cerr << "Error - could not detect filetype for image \"" << path << "\"!\n";
|
|
|
|
return;
|
|
|
|
}
|
2012-08-09 21:19:07 +00:00
|
|
|
|
|
|
|
|
2012-08-29 18:53:53 +00:00
|
|
|
//make sure we can read this filetype first, then load it
|
|
|
|
if(FreeImage_FIFSupportsReading(format))
|
|
|
|
{
|
|
|
|
std::cout << "Loading image...";
|
|
|
|
image = FreeImage_Load(format, path.c_str());
|
|
|
|
std::cout << "success\n";
|
|
|
|
}else{
|
|
|
|
std::cerr << "Error - file format reading not supported for image \"" << path << "\"!\n";
|
|
|
|
return;
|
|
|
|
}
|
2012-08-13 18:32:53 +00:00
|
|
|
|
2012-08-29 18:53:53 +00:00
|
|
|
//make sure it loaded properly
|
|
|
|
if(!image)
|
|
|
|
{
|
|
|
|
std::cerr << "Error loading image \"" << path << "\"!\n";
|
|
|
|
return;
|
|
|
|
}
|
2012-08-10 19:28:34 +00:00
|
|
|
|
2012-08-29 19:22:05 +00:00
|
|
|
//convert to 32bit
|
|
|
|
FIBITMAP* imgConv = FreeImage_ConvertTo32Bits(image);
|
|
|
|
FreeImage_Unload(image);
|
|
|
|
image = imgConv;
|
|
|
|
|
2012-08-29 18:53:53 +00:00
|
|
|
imageData = FreeImage_GetBits(image);
|
|
|
|
if(!imageData)
|
|
|
|
{
|
|
|
|
std::cerr << "Error retriving bits from image \"" << path << "\"!\n";
|
|
|
|
return;
|
|
|
|
}
|
2012-08-02 01:43:55 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
2012-08-29 18:53:53 +00:00
|
|
|
width = FreeImage_GetWidth(image);
|
|
|
|
height = FreeImage_GetHeight(image);
|
2012-08-13 18:32:53 +00:00
|
|
|
|
2012-08-29 18:53:53 +00:00
|
|
|
if(!width || !height)
|
|
|
|
{
|
|
|
|
std::cerr << "Width or height are zero for image \"" << path << "\"!\n";
|
|
|
|
return;
|
2012-08-10 02:17:48 +00:00
|
|
|
}
|
2012-08-29 18:53:53 +00:00
|
|
|
|
2012-08-29 19:22:05 +00:00
|
|
|
|
|
|
|
//convert from BGRA to RGBA
|
|
|
|
GLubyte* imageRGBA = new GLubyte[4*width*height];
|
|
|
|
for(unsigned int i = 0; i < width*height; i++)
|
|
|
|
{
|
|
|
|
imageRGBA[i*4+0] = imageData[i*4+2];
|
|
|
|
imageRGBA[i*4+1] = imageData[i*4+1];
|
|
|
|
imageRGBA[i*4+2] = imageData[i*4+0];
|
|
|
|
imageRGBA[i*4+3] = imageData[i*4+3];
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2012-08-29 18:53:53 +00:00
|
|
|
//now for the openGL texture stuff
|
|
|
|
glGenTextures(1, &mTextureID);
|
|
|
|
glBindTexture(GL_TEXTURE_2D, mTextureID);
|
2012-08-29 19:22:05 +00:00
|
|
|
|
|
|
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, imageRGBA);
|
|
|
|
|
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
2012-08-29 18:53:53 +00:00
|
|
|
|
|
|
|
mWidth = width;
|
|
|
|
mHeight = height;
|
|
|
|
|
|
|
|
//free the image data
|
|
|
|
FreeImage_Unload(image);
|
|
|
|
|
2012-08-29 19:22:05 +00:00
|
|
|
//free the memory from that pointer
|
|
|
|
delete[] imageRGBA;
|
|
|
|
|
2012-08-29 21:52:25 +00:00
|
|
|
//a simple way to resize: lie about our real texture size!
|
|
|
|
//(we don't resize tiled images)
|
|
|
|
if(!mTiled)
|
|
|
|
{
|
|
|
|
float resizeScaleX = 0, resizeScaleY = 0;
|
|
|
|
if(mResizeExact)
|
|
|
|
{
|
|
|
|
if(mResizeWidth)
|
|
|
|
resizeScaleX = (float)mResizeWidth / mWidth;
|
|
|
|
if(mResizeHeight)
|
|
|
|
resizeScaleY = (float)mResizeHeight / mHeight;
|
|
|
|
}else{
|
|
|
|
if(mResizeWidth && mWidth > mResizeWidth)
|
|
|
|
resizeScaleX = (float)mResizeWidth / mWidth;
|
|
|
|
|
|
|
|
if(mResizeHeight && mHeight > mResizeHeight)
|
|
|
|
resizeScaleY = (float)mResizeHeight / mHeight;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(resizeScaleX && !resizeScaleY)
|
|
|
|
resizeScaleY = resizeScaleX;
|
|
|
|
if(resizeScaleY && !resizeScaleX)
|
|
|
|
resizeScaleX = resizeScaleY;
|
|
|
|
|
|
|
|
if(resizeScaleX)
|
|
|
|
mWidth *= resizeScaleX;
|
|
|
|
if(resizeScaleY)
|
|
|
|
mHeight *= resizeScaleY;
|
|
|
|
}
|
|
|
|
|
2012-08-29 18:53:53 +00:00
|
|
|
std::cout << "Image load successful, w: " << mWidth << " h: " << mHeight << " texID: " << mTextureID << "\n";
|
2012-08-09 21:19:07 +00:00
|
|
|
}
|
|
|
|
|
2012-08-29 18:53:53 +00:00
|
|
|
void GuiImage::unloadImage()
|
2012-08-13 18:32:53 +00:00
|
|
|
{
|
2012-08-29 18:53:53 +00:00
|
|
|
if(mTextureID)
|
2012-08-13 18:32:53 +00:00
|
|
|
{
|
2012-08-29 18:53:53 +00:00
|
|
|
std::cout << "deleting texture\n";
|
|
|
|
glDeleteTextures(1, &mTextureID);
|
2012-08-13 18:32:53 +00:00
|
|
|
|
2012-08-29 18:53:53 +00:00
|
|
|
mTextureID = 0;
|
2012-08-13 18:32:53 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-08-09 21:19:07 +00:00
|
|
|
void GuiImage::setImage(std::string path)
|
|
|
|
{
|
2012-08-10 02:17:48 +00:00
|
|
|
if(mPath == path)
|
|
|
|
return;
|
2012-08-09 21:19:07 +00:00
|
|
|
|
2012-08-10 02:17:48 +00:00
|
|
|
mPath = path;
|
|
|
|
|
2012-08-29 18:53:53 +00:00
|
|
|
unloadImage();
|
2012-08-10 02:17:48 +00:00
|
|
|
if(!path.empty())
|
|
|
|
loadImage(path);
|
|
|
|
|
2012-08-02 01:43:55 +00:00
|
|
|
}
|
|
|
|
|
2012-08-13 18:32:53 +00:00
|
|
|
void GuiImage::setOrigin(float originX, float originY)
|
|
|
|
{
|
|
|
|
mOriginX = originX;
|
|
|
|
mOriginY = originY;
|
|
|
|
}
|
|
|
|
|
|
|
|
void GuiImage::setTiling(bool tile)
|
|
|
|
{
|
|
|
|
mTiled = tile;
|
|
|
|
|
|
|
|
if(mTiled)
|
|
|
|
mResizeExact = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
void GuiImage::setAlpha(bool useAlpha)
|
|
|
|
{
|
|
|
|
mUseAlpha = useAlpha;
|
|
|
|
}
|
|
|
|
|
2012-08-02 01:43:55 +00:00
|
|
|
void GuiImage::onRender()
|
|
|
|
{
|
2012-08-29 18:53:53 +00:00
|
|
|
if(mTextureID)
|
2012-08-13 18:32:53 +00:00
|
|
|
{
|
2012-08-29 21:52:25 +00:00
|
|
|
if(mTiled)
|
|
|
|
{
|
|
|
|
for(unsigned int x = 0; x < (unsigned int)((float)mResizeWidth/mWidth + 1.5); x++)
|
|
|
|
{
|
|
|
|
for(unsigned int y = 0; y < (unsigned int)((float)mResizeHeight/mHeight + 1.5); y++)
|
|
|
|
{
|
|
|
|
drawImage(mOffsetX + x*mWidth, mOffsetY + y*mHeight);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}else{
|
|
|
|
drawImage(mOffsetX, mOffsetY);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2012-08-29 18:53:53 +00:00
|
|
|
|
2012-08-29 21:52:25 +00:00
|
|
|
void GuiImage::drawImage(int posX, int posY)
|
|
|
|
{
|
|
|
|
glBindTexture(GL_TEXTURE_2D, mTextureID);
|
|
|
|
glEnable(GL_TEXTURE_2D);
|
|
|
|
glEnable(GL_BLEND);
|
2012-08-29 18:53:53 +00:00
|
|
|
|
2012-08-29 21:52:25 +00:00
|
|
|
GLfloat points[12];
|
|
|
|
points[0] = posX - (mWidth * mOriginX); points[1] = posY - (mHeight * mOriginY);
|
|
|
|
points[2] = posX - (mWidth * mOriginX); points[3] = posY + (mHeight * (1 - mOriginY));
|
|
|
|
points[4] = posX + (mWidth * (1 - mOriginX)); points[5] = posY - (mHeight * mOriginY);
|
2012-08-29 18:53:53 +00:00
|
|
|
|
2012-08-29 21:52:25 +00:00
|
|
|
points[6] = posX + (mWidth * (1 - mOriginX)); points[7] = posY - (mHeight * mOriginY);
|
|
|
|
points[8] = posX - (mWidth * mOriginX); points[9] = posY + (mHeight * (1 - mOriginY));
|
|
|
|
points[10] = posX + (mWidth * (1 -mOriginX)); points[11] = posY + (mHeight * (1 - mOriginY));
|
2012-08-29 18:53:53 +00:00
|
|
|
|
2012-08-29 21:52:25 +00:00
|
|
|
//std::cout << "x: " << points[0] << " y: " << points[1] << " to x: " << points[10] << " y: " << points[11] << std::endl;
|
|
|
|
//std::cout << "(w: " << mWidth << " h: " << mHeight << ")" << std::endl;
|
2012-08-29 18:53:53 +00:00
|
|
|
|
2012-08-29 21:52:25 +00:00
|
|
|
GLfloat texs[12];
|
|
|
|
texs[0] = 0; texs[1] = 1;
|
|
|
|
texs[2] = 0; texs[3] = 0;
|
|
|
|
texs[4] = 1; texs[5] = 1;
|
2012-08-29 18:53:53 +00:00
|
|
|
|
2012-08-29 21:52:25 +00:00
|
|
|
texs[6] = 1; texs[7] = 1;
|
|
|
|
texs[8] = 0; texs[9] = 0;
|
|
|
|
texs[10] = 1; texs[11] = 0;
|
2012-08-29 18:53:53 +00:00
|
|
|
|
|
|
|
|
2012-08-29 21:52:25 +00:00
|
|
|
glEnableClientState(GL_VERTEX_ARRAY);
|
|
|
|
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
2012-08-29 18:53:53 +00:00
|
|
|
|
2012-08-29 21:52:25 +00:00
|
|
|
glVertexPointer(2, GL_FLOAT, 0, points);
|
|
|
|
glTexCoordPointer(2, GL_FLOAT, 0, texs);
|
2012-08-29 18:53:53 +00:00
|
|
|
|
2012-08-29 21:52:25 +00:00
|
|
|
glDrawArrays(GL_TRIANGLES, 0, 6);
|
2012-08-29 18:53:53 +00:00
|
|
|
|
2012-08-29 21:52:25 +00:00
|
|
|
glDisableClientState(GL_VERTEX_ARRAY);
|
|
|
|
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
2012-08-29 18:53:53 +00:00
|
|
|
|
2012-08-29 21:52:25 +00:00
|
|
|
glDisable(GL_TEXTURE_2D);
|
|
|
|
glDisable(GL_BLEND);
|
2012-08-02 01:43:55 +00:00
|
|
|
}
|