Go to most recent revision | Blame | Last modification | View Log | RSS feed
#include <assert.h>
#include <stdio.h>
#ifdef WIN32
#include <windows.h>
#include <io.h>
#endif
#include <string.h>
#include <stdlib.h>
#include <iostream>
#include <CGLA/Vec2i.h>
#include <CGLA/Vec2f.h>
#include "Texmap.h"
#include <IL/il.h>
#include <IL/ilu.h>
using namespace std;
using namespace CGLA;
namespace Geometry
{
Texmap::Texmap(): image(0), bpp(0), size_x(0),
size_y(0), load_size_x(0), load_size_y(0)
{}
Texmap::~Texmap()
{
}
Vec3f Texmap::get_texel(int u, int v)
{
int bits = bpp/8;
Vec3f value;
value[0] = image[(u*size_x+v)*bits + 0];
value[1] = image[(u*size_x+v)*bits + 1];
value[2] = image[(u*size_x+v)*bits + 2];
return value/256.0f;
}
bool Texmap::load(const std::string& _name)
{
image = 0;
bpp = 0;
size_x = 0;
size_y = 0;
load_size_x = 0;
load_size_y = 0;
name = _name;
ILenum Error;
ILuint ImgId;
static bool washere = false;
if(!washere)
{
ilInit();
iluInit();
washere=true;
}
ilEnable(IL_CONV_PAL);
ilEnable(IL_ORIGIN_SET);
ilOriginFunc(IL_ORIGIN_LOWER_LEFT);
ilGenImages(1, &ImgId);
ilBindImage(ImgId);
char* name_cstr = const_cast<char*>(name.c_str());
if(!ilLoadImage(name_cstr))
{
cout << "could not load <" << name << ">" << endl;
return false;
}
load_size_x = ilGetInteger(IL_IMAGE_WIDTH);
load_size_y = ilGetInteger(IL_IMAGE_HEIGHT);
bpp = ilGetInteger(IL_IMAGE_BITS_PER_PIXEL);
if (bpp==24)
ilConvertImage(IL_RGB, IL_UNSIGNED_BYTE);
else if (bpp==32)
ilConvertImage(IL_RGBA, IL_UNSIGNED_BYTE);
else if (bpp==8)
ilConvertImage(IL_LUMINANCE, IL_UNSIGNED_BYTE);
else
assert(0);
int i;
for (i=2;i<=4096 ;i*=2)
if (i>=load_size_x)
break;
size_x = i;
for (i=2;i<=4096 ;i*=2)
if (i>=load_size_y)
break;
size_y = i;
if(size_x != load_size_x || size_y != load_size_y)
{
iluImageParameter(ILU_FILTER, ILU_BILINEAR);
iluScale(size_x, size_y, 1);
}
const int image_size =size_x*size_y*ilGetInteger(IL_IMAGE_BYTES_PER_PIXEL);
image = new unsigned char[image_size];
memcpy(image, ilGetData(), image_size);
ilDeleteImages(1, &ImgId);
while ((Error = ilGetError())) {
cout << __LINE__ << "Error: " << iluErrorString(Error) << endl;
return false;
}
return true;
}
float log2(float val)
{
return log(val)/log(2.0f);
}
void Texmap::gl_bind()
{
glBindTexture(GL_TEXTURE_2D, id);
}
void Texmap::gl_init()
{
GLint internalFormat=0;
GLenum format=0;
glGenTextures(1, &id);
switch (bpp)
{
case 8:
internalFormat = GL_LUMINANCE;
format = GL_LUMINANCE;
break;
case 24:
internalFormat = GL_RGB;
format = GL_RGB;
break;
case 32:
internalFormat = GL_RGBA;
format = GL_RGBA;
break;
default:
assert(0);
}
glBindTexture(GL_TEXTURE_2D, id);
glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, size_x, size_y, 0,
format, GL_UNSIGNED_BYTE, image);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
}
}