DevIL Image and textures

Started by
6 comments, last by soggie 19 years, 11 months ago
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.
"Darkness cannot drive out darkness, only Light can do that. Hate cannot drive out hate, only Love can do that."
Advertisement
Would be not simpler to use a TGA / BMP class loader instead of adding a requirement such as devIL library ? I may post TGA/BMP loader if you need it.



Colossus

Mizio, a proxy scanner hunter tool with GUI for Linux
http://mizio.sourceforge.net
ColossusCpsed,a Linux OpenGL 3D scene editorhttp://cpsed.sourceforge.net
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.
"Darkness cannot drive out darkness, only Light can do that. Hate cannot drive out hate, only Love can do that."
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
ColossusCpsed,a Linux OpenGL 3D scene editorhttp://cpsed.sourceforge.net
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...
"Darkness cannot drive out darkness, only Light can do that. Hate cannot drive out hate, only Love can do that."
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]
:0 opps i did some typo there. I typed it up from memory actually :D

hmm init. I''ll look into it. thanks man!
"Darkness cannot drive out darkness, only Light can do that. Hate cannot drive out hate, only Love can do that."
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#endifvector<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 OpenGLNote 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]
[size="1"]

This topic is closed to new replies.

Advertisement