Sign in to follow this  

texture arrays

This topic is 3143 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

hey! here's the problem: i want to load 6 images using devil end put them in a texture array. i guess i could do it one by one, basically repeating the same code 6 times (one for each image), but im trying to do it in a way that uses less lines of code. so here's what i have:
 void load_img_devil () {
	int width, height, format, il_img;
	
	ilInit ();
	iluInit();
	ilutRenderer(ILUT_OPENGL);
	
	for(int i=0;i<6;i++){
		ilGenImages (1, (ILuint*)&il_img); // get an unique ID
		ilBindImage(il_img); // Bind this image name.
		if (i==0) if(!ilLoadImage((const wchar_t *)"F:\\Side1.png")) exit(0); // Load the image
		if (i==1) if(!ilLoadImage((const wchar_t *)"F:\\Side2.png")) exit(0); // Load the image
		if (i==2) if(!ilLoadImage((const wchar_t *)"F:\\Side3.png")) exit(0); // Load the image
		if (i==3) if(!ilLoadImage((const wchar_t *)"F:\\Side4.png")) exit(0); // Load the image
		if (i==4) if(!ilLoadImage((const wchar_t *)"F:\\Side5.png")) exit(0); // Load the image
		if (i==5) if(!ilLoadImage((const wchar_t *)"F:\\Side6.png")) exit(0); // Load the image
		width = ilGetInteger (IL_IMAGE_WIDTH);
		height = ilGetInteger (IL_IMAGE_HEIGHT);
		il_imgData[i] = ilGetData();
		format = ilGetInteger(IL_IMAGE_FORMAT);

		// create GL texture
		glGenTextures (1, (GLuint *)&texID[i]); // get texture unique ID
		glBindTexture (GL_TEXTURE_2D, texID[i]); // bind it
		
		// associate with data read with DevIL
		glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, format,
		GL_UNSIGNED_BYTE, il_imgData[i]);
		
		// Release data space created with DevIL
		ilDeleteImages(1, (const ILuint *)&il_img);
        }
	
	// Parameterise Texture
		glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
		glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
		glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
		glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
}

the thing is.. it doesnt work. to test it i made a square and textured it with texID[0], it appears white; as with any other index. Note 1: texID and il_imgData are global variables; arrays with lenght 6. Note 2: if i open brackets after 'if(i==0)' and close it after the ilDeleteImages call, it works.(for the first image)

Share this post


Link to post
Share on other sites
@DevFred: i can. i dont get any compiler errors or warnings. in fact, that's why i did the cast in the first place, otherwise i'd get a compiler error. plus, if i try to load only one texture, it works. my guess is the problem is somewhere in the loop.

@Zahlman: i'm not sure what you mean but i think it's more or less what DevFred said, so...

Thanks for the replies.

Share this post


Link to post
Share on other sites
Quote:
Original post by Rui
@DevFred: i can. i dont get any compiler errors or warnings. in fact, that's why i did the cast in the first place, otherwise i'd get a compiler error. plus, if i try to load only one texture, it works. my guess is the problem is somewhere in the loop.

@Zahlman: i'm not sure what you mean but i think it's more or less what DevFred said, so...

Thanks for the replies.


No, DevFred is right. you're casting one type of pointer (char*) to (wchar_t* )..
One is an 8-bit ascii string, the other is a 16-bit unicode string, something which is valid C++ (so no compiler error) but in this case it's still a bug.
Use L"F:\\Side1.png" to create a 16-bit unicode string.

Share this post


Link to post
Share on other sites
Quote:
Original post by Rui
@DevFred: i can. i dont get any compiler errors or warnings. in fact, that's why i did the cast in the first place, otherwise i'd get a compiler error. plus, if i try to load only one texture, it works. my guess is the problem is somewhere in the loop.

@Zahlman: i'm not sure what you mean but i think it's more or less what DevFred said, so...

Thanks for the replies.


While casting like that isn't a compiler error, it's a logical error and most likely explains why you're getting untextured triangles.

To use wide character strings use a capital L before the quotation mark.

Share this post


Link to post
Share on other sites
Quote:
Original post by Rui
@DevFred: i can. i dont get any compiler errors or warnings. in fact, that's why i did the cast in the first place, otherwise i'd get a compiler error.

So if you give meat to a vegetarian and he complains "I don't like meat", what do you do? Simply tell him "Don't worry, just pretend it's a vegetable"?

Share this post


Link to post
Share on other sites
k, thanks everyone. i see now why that's an error. devfred really put it in perspective for me lol..

but replacing '(const wchar_t*) "F:\\Side1.pgn"' for 'L"Side1.pgn"' made ilLoadImage exit though..

(following erissian's advice it works perfect, with 'const wchar_t*')

any ideas why that might be?

Share this post


Link to post
Share on other sites
Quote:
Original post by Rui
k, thanks everyone. i see now why that's an error. devfred really put it in perspective for me lol..

but replacing '(const wchar_t*) "F:\\Side1.pgn"' for 'L"Side1.pgn"' made ilLoadImage exit though..

(following erissian's advice it works perfect, with 'const wchar_t*')

any ideas why that might be?


You can use ilGetError() to find out what's going wrong.

Anyways, to understand the problem you had before, you need to realize how the character arrays are kept in memory. A regular ascii character array looks like:

'H','e','l','l','o',' ','w','o','r','l','d',0

Because the individual characters are a single byte. Wide character arrays, on the other hand, are two bytes in length, so the equivalent array looks like:

0,'H',0,'e',0,'l',0,'l',0,'o',0,' ',0,'w',0,'o',0,'r',0,'l',0,'d',0

So while you can use a wide character pointer to reference an ascii character array, what it ends up seeing is:

'He','ll','o ','wo','rl','d\0',...

plus whatever is in memory after that until it comes across 0x00.

For fun, "F:\\Side1.png" translates to: "䘺屓楤攱⹰湧" which is probably not what you were looking for :)

Share this post


Link to post
Share on other sites
Quote:
Original post by Rui
@DevFred: i can. i dont get any compiler errors or warnings.


Just because the compiler doesn't complain about something doesn't mean you "can do" it. You can write programs that are basically guaranteed to crash immediately, without the compiler saying a thing. Such is C++. That's one of the main reasons we try to steer new programmers away from it.

Quote:
plus, if i try to load only one texture, it works. my guess is the problem is somewhere in the loop.


Things "seeming to work once" is a common symptom of code that does something wrong that the compiler can't catch. Again, such is C++, etc.

Quote:
@Zahlman: i'm not sure what you mean


I don't know how much clearer I could make it, but let me try saying exactly what it should look like:


if (i==0) if(!ilLoadImage(L"F:\\Side1.png")) exit(0); // Load the image


The L"something here" construct is built into the language. It tells the compiler that you are creating a wide-character literal. This means that a chunk of memory is set up with a size of (number of characters in the string) * (number of bytes needed for a wide character), and each character of the string is a wide character.

An ordinary string literal uses a chunk of memory with a size of (number of characters in the string) * (number of bytes needed for an ordinary character, i.e. 1). By casting the pointer, you do not affect this chunk of memory. Instead, you instruct the compiler to regard the chunk of memory as if it were a sequence of (size of a wide character)-sized elements, which (a) obviously contains fewer elements than intended, and (b) groups the bytes of the string literal together in nonsensical ways.

Share this post


Link to post
Share on other sites
Quote:
That's one of the main reasons we try to steer new programmers away from it.

Quote:
Again, such is C++, etc.

Granted I dont have much experience, but it's not that i'm a new programmer, i'm just new to C++. I never had a class to learn C++ like I did C or Java for example, and yet I need it for the Computer Graphics class project.

Quote:
I don't know how much clearer I could make it, but let me try saying exactly what it should look like:


if (i==0) if(!ilLoadImage(L"F:\\Side1.png")) exit(0); // Load the image


i had never seen that construct before, hence the confusion.

Share this post


Link to post
Share on other sites

This topic is 3143 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.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this