Archived

This topic is now archived and is closed to further replies.

DevIL Image and textures

This topic is 4956 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi, I am doin this:
bool Image::Load(char* filename)
{
    int id = 0;
    ilInit();
    ilGenImages(, &id);
    if(!ilLoadImage(filename))
    {
        //log error

        return false;
    }

    //set image properties

    mID = id;
    mWidth = ilGetInteger(IL_IMAGE_WIDTH);
    mHeight = ilGetInteger(IL_IMAGE_HEIGHT);
    mBpp = ilGetInteger(IL_IMAGE_BITS_PER_PIXEL);
    mFormat = ilGetInteger(IL_IMAGE_FORMAT);
    mData = ilGetData();

    //output success

    return true;
}
steppin'' thru my code, all the other member values (mID, mWidth, mHeight...) loaded with the correct values, but mData was a bunch of identical symbols (something like a y with two dots above it). My pic was a bitmap drawn in paint, saved as a 24-bit bmp and size is 256 X 256. Anybody knows of the correct way to get the image data from DevIL? I am using DevIL to load images for my GL texture objects. Thanks for your help in adv.

Share this post


Link to post
Share on other sites
thanks man I would greatly appreciate it. The reason i used DevIL was that I wanted my engine to support as many kinds of images as possible. But hey, if you got a good BMP/TGA loader that will load all kinds of BMP and TGA, I would use that instead. Thanks a lot.

Share this post


Link to post
Share on other sites
For BMP loader look at http://nehe.gamedev.net/data/lessons/lesson.asp?lesson=28
and download the linux glx port. Inside the file lesson28.c there is a BMP loader function.
Regarding the TGA look here and download the tutorial SkyBox, there are two files TGA.c and TGA.h who load and write a TGA file.



Colossus

Mizio, a proxy scanner hunter tool with GUI for Linux
http://mizio.sourceforge.net

Share this post


Link to post
Share on other sites
nope not good... these loaders only load one format. It doesn''t load 8-bit bitmaps, 24-bit compressed TGA and so on! That''s the main reason I used DevIL in the first place. I''ve checked out these two thingy long time ago... but thanks anyway.

Come to think of it, why didn''t anybody just write a class that loads images and let people sorta like plug into their app? I mean, I don''t want my engine to come with high coupling with tons of libraries and dlls...

Share this post


Link to post
Share on other sites
FreeImage sounds close to what you want, although it does have to use DLLs.
Corona is another image loading lib which can handle a couple of formats.

As for your DevIl problem;
- It looks like you are Initing DevIL everytime you load an image, this cant be good.
- I'm pretty sure the init function needs a flag to tell it to produce OpenGL compaible data
- did you copy and paste this code? if so how is the missin first parameter on ilGenImages() not being caught?

[edited by - _the_phantom_ on May 20, 2004 12:41:22 PM]

Share this post


Link to post
Share on other sites
heres the code to my Texture class, using DevIL. feel free to use it to work out what's wrong with yours, or just use it if you are lazy. DevIL is great, I'd stick with it if I were you.

make sure you call


ilInit();
iluInit();
ilutInit();
ilutRenderer(ILUT_OPENGL);


once before using it.

texture.h:


// Texture.h: interface for the Texture class.


//


//////////////////////////////////////////////////////////////////////




#ifndef TEXTURE_H

#define TEXTURE_H

#include <boost/shared_ptr.hpp>
using namespace boost;

#include <string>
#include <vector>
#include <algorithm>
using namespace std;

#include <IL/ilut.h>

#include "glheader.h"
#include "PathManager.h"

#include "ILHash.h"

class Texture

{

public:

struct TextureRef
{
shared_ptr<Texture>sp;
unsigned int format;
unsigned int type;
string filename;
//note that neither operator== compares the shared_ptr.

bool operator==(string s){return (filename==s);}
bool operator==(TextureRef s){return (filename==s.filename && format==s.format && type==s.type);}
};

void SetUpOGLTexture(bool force = false);

void SetFormat(unsigned int format, unsigned int type = TEXTYPE_UBYTE);

GLuint GetGLName();

ILuint GetILName();

string filename;

bool LoadImage(string infilename);

Texture();

virtual ~Texture();

//!Binds the texture in opengl

void Bind();

//! get a reference to an existing texture, or load one if not

static bool GetInstance(string filename, shared_ptr<Texture>&tobe,
unsigned int format = TEXFORMAT_RGB,
unsigned int type = TEXTYPE_UBYTE);
//! for adding code generated images to the loaded_resource pool

static bool NewTexture(string name, shared_ptr<Texture>&track_me,
unsigned int format = TEXFORMAT_RGB,
unsigned int type = TEXTYPE_UBYTE);
private:

ILuint ILname;

GLuint GLname;

bool inIL, inGL;

//!vector of currently loaded resources

static vector<TextureRef> loaded_resources;

//!returns false if resource indicated by filename+format is not loaded, otherwise returns true and sets the passed shared_ptr

static bool Loaded(string filename, shared_ptr<Texture>& tobe, unsigned int format, unsigned int type);

//!returns false if file indicated by filename is not loaded, otherwise returns true and sets the passedshared_ptr

static bool Loaded(string filename, shared_ptr<Texture>&tobe);

};



#endif





texture.cpp:


// Texture.cpp: implementation of the Texture class.


//


//////////////////////////////////////////////////////////////////////




#include "Texture.h"
#include "buildconfig.h"

#ifdef DEBUG
#include <imdebug.h>
#ifdef DEBUG_TEXTURE_BIND
#include <iostream>
#endif
#endif


vector<Texture::TextureRef> Texture::loaded_resources;


//////////////////////////////////////////////////////////////////////


// Construction/Destruction


//////////////////////////////////////////////////////////////////////




Texture::Texture()

{

GLname = 0;

ILname = 0;

inGL = inIL = false;

}



Texture::~Texture()

{

if (inIL)

{

ilDeleteImages(1, &ILname);

}



if (inGL)

{

glDeleteTextures(1, &GLname);

}

}



bool Texture::LoadImage(string infilename)

{

filename = infilename;



//request a new image from DevIL


ilGenImages(1, &ILname);

//make that image current


ilBindImage(ILname);

//load the image


ilLoadImage((char *const)filename.c_str());

inIL = true;

//imdebug("rgb w=%d h=%d %p",ilGetInteger(IL_IMAGE_WIDTH),ilGetInteger(IL_IMAGE_HEIGHT),ilGetData());


return true;



}



void Texture::SetUpOGLTexture(bool force)

{
//if the texture isn't in opengl or it is and we want to force deletion of the old one and allocation of a new one

if ((!inGL) || (inGL && force))
{
//ensure the image is current in DevIL


ilBindImage(ILname);

//generate an OpenGL mipmapped texture and store the handle in GLname


GLname = ilutGLBindMipmaps();

inGL = true;
}

}



ILuint Texture::GetILName()

{

return ILname;

}



GLuint Texture::GetGLName()

{

return GLname;



}



void Texture::SetFormat(unsigned int format, unsigned int type)
{

//ensure the image is current in DevIL


if (format) //check if it's a format supported by devil

{
ilBindImage(ILname);
//convert the image to the specified format (DevIL will set the opengl format and internal format from this)

ilConvertImage(ILFormatHash(format),ILTypeHash(type));
}

}

/* Binds the texture in OpenGL
Note that this has no knowledge of the current active texture unit */

void Texture::Bind()
{
//checks for the texture disabling macro from buildconfig

#ifndef ENABLE_NO_TEXTURES
glBindTexture(GL_TEXTURE_2D, GLname);
#ifdef DEBUG_TEXTURE_BIND
cout << "binding " << filename << " texnname: " << GLname << endl;
#endif
#endif
}

bool Texture::GetInstance(string filename, shared_ptr<Texture>&tobe, unsigned int format, unsigned int type)
{
//check if the resource has been loaded

if (Loaded(filename, tobe, format, type))
{
return true;
}
//else

//create a new texture

shared_ptr<Texture>t(new Texture);
//work out the proper path using the path manager

string n = filename;

//ask the path manager to find the file. if it does, filename will be changed to the full path

if (PathManager::FindAsset(n))
{
//try loading the file

if (t->LoadImage(n))
{
//if it works, set the format

t->SetFormat(format, type);
//set it up in opengl

t->SetUpOGLTexture();
//add the resource to the list of loaded resources

TextureRef tr;
tr.filename= filename;
tr.format = format;
tr.type = type;
tr.sp = t;
loaded_resources.push_back(tr);
//set the requested sptr to the new resource

tobe = t;
return true;
}
}
return false;

//if t wasn't added to the list of loaded resources (eg the load failed) it falls out of scope here and the new'd Texture is deleted by shared_ptr

}

bool Texture::Loaded(string file_name, shared_ptr<Texture>&tobe, unsigned int format, unsigned int type)
{
//checks format as well as filename, so we create a temp TextureRef to do te check using operator==(TextureRef)

TextureRef a;
a.filename = file_name;
a.format = format;
a.type = type;

//if the resource is loaded, this'll get an iterator pointing to it's place in the vector

vector<TextureRef>::iterator i = find(loaded_resources.begin(),loaded_resources.end(), a);
// ( instead of stl find, could write something similar that checks unique as it goes - garbage collect as new resources are added....

//if it returns end it wasn't found, otherwise

if (i != loaded_resources.end())
{
//set the requested shared pointer to the existing resource

tobe = i->sp;
return true;
}
//if we get to here, the resource hasn't been found

return false;
}

bool Texture::Loaded(string file_name, shared_ptr<Texture>&tobe)
{
//only checks filename - may lead to surprises, so use the version with format too


//if the resource is loaded, this'll get an iterator pointing to it's place in the vector

vector<TextureRef>::iterator i = find(loaded_resources.begin(),loaded_resources.end(), file_name);
// ( instead of stl find, could write something similar that checks unique as it goes - garbage collect as new resources are added....

//if it returns end it wasn't found, otherwise

if (i != loaded_resources.end())
{
//set the requested shared pointer to the existing resource

tobe = i->sp;
return true;
}
//if we get to here, the resource hasn't been found

return false;
}

bool Texture::NewTexture(string name, shared_ptr<Texture>&track_me, unsigned int format, unsigned int type)
{
//if the name exists, track_me is set to point to it and we return false

//the user code can decide whether to accept the existing resource or rethink

if(!Loaded(name, track_me))
{
//create a texture ref for the new texture

TextureRef t;
t.filename = name;
t.format = format;
t.sp = track_me;
t.type = type;
//and add it to the loaded_resouces list

loaded_resources.push_back(t);
return true;
}
return false;
}


you can ignore the TextureRef, GetInstance, Loaded, NewTexture stuff - it's just for the managed objects in my engine.

Edit: source tags use [] not <>!

[edited by - mrbastard on May 21, 2004 10:50:19 AM]

Share this post


Link to post
Share on other sites