OpenGL Texture Mapping

I'm trying to apply a texture to a square (just for practice). I made an image loader, and I don't think that it's right at all... I just need to know what I'm doing wrong and how to fix it please!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
GLuint LoadTexture(const char * pic, int width, int height)
{
	GLuint Texture;
	BYTE * data;
	FILE * picfile;

	picfile = fopen(pic, "rb");
	if (picfile == NULL)
		return 0;

	data = (BYTE *)malloc(width * height * 3);

	fread(data, width * height, 3, picfile);
	fclose(picfile);
	
        glGenTextures(1, &Texture);
	glBindTexture(GL_TEXTURE_2D,  Texture);

	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);

	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_MIN_FILTER, GL_LINEAR);
	glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

	free(data);
	return Texture;
}

void Games()
{
	glEnable(GL_TEXTURE_2D);
	glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
	GLuint myTex;
	myTex = LoadTexture("boom.bmp", 75, 75);

	glBindTexture(GL_TEXTURE_2D, myTex);

	glBegin(GL_POLYGON);
		glTexCoord2f(37.5, 37.5);   glVertex3f(37.5, 37.5, 0.0);        
		glTexCoord2f(-37.5, 37.5);  glVertex3f(-37.5, 37.5, 0.0);       
		glTexCoord2f(-37.5, -37.5); glVertex3f(-37.5, -37.5, 0.0);      
		glTexCoord2f(37.5, -37.5);  glVertex3f(37.5, -37.5, 0.0);       
	glEnd();

	glDisable(GL_TEXTURE_2D);
}


- Kyle
Last edited on
It'd be easier if you'd tell us what you see (or, even better, post a picture) and what you expected to see, rather than dump a bunch of code and make us figure it out.
I expect to see a picture on the screen, in a window. Nothing more, nothing less. I currently see a blank window.

- Kyle
Last edited on
Alright.

Well, one obvious problem is that you're not doing anything with the loaded bitmap. You just load it to memory and that's it. You don't even free the memory before returning. You'll need glTexImage2D().
glTexImage2D(GL_TEXTURE_2D, 0, 3, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data) at line 18?

- Kyle

EDIT: It is segfaulting on that line...

EDIT: After adding a line to free(data);, it doesn't. I'll put the edited code up in the original post.
Last edited on
There are several problems:

1) You need to bind the texture before you can do anything with it. This means that immediately after the call to glGenTextures, you use glBindTexture with the newly generated texture:

1
2
glGenTextures (1, &Texture);
glBindTexture (GL_TEXTURE_2D, Texture);


2) There are multiple texture parameters that haven't been set. These can be assigned AFTER binding your texture, and using the function glTexParameteri:
1
2
3
4
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_MIN_FILTER, GL_LINEAR);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);


3) The third parameter of glTexImage2D shouldn't be '3', it should instead be GL_RGB. The ability to use 1, 2, 3, and 4 as values for that parameter is a Microsoft-only thing. It may work for now, but I highly recommend that you use GL_RGB (or whatever format the image may be in.)

4) Judging by how you're using a BMP file instead of something more efficient like PNG, I'm assuming you're aware that OpenGL can't load up compressed or formatted files like TIFF, JPEG, and PNG. You're right in using a BMP file since all the image data is stored uncompressed and aligned, but the file still has a header, which you can read about here:

http://en.wikipedia.org/wiki/BMP_file_format#Bitmap_file_header

In order to get the real raw data for the image you'll need to read past the header (the size of which varies by the format version being used) and then load in your data. Note that, if you'd like, you can read the width and height of the image that is stored in the header, which is more convenient than hard-coding it.

I personally recommend using a library like SDL_image for loading in images, and then passing the raw pixel data to OpenGL. It's much simpler, and provides access to formats like JPEG and PNG.

5) This is more of a suggestion than a requirement, but your glTexEnvf call should assign GL_TEXTURE_ENV_MODE to GL_MODULATE instead of GL_DECAL. It won't make a difference now since your image is opaque, but the overhead of using GL_MODULATE instead of GL_DECAL is practically nonexistant, and it'll allow you to move to using transparent images later on without any problems.



EDIT:

6) Your texture coordinates are inappropriate. Texture coordinates must be in the range [0, 1]. You can find more information on how to use texture coordinates here:

http://www.gamedev.net/page/resources/_/technical/opengl/opengl-texture-mapping-an-introduction-r947



EDIT 2:

7) While it might not be an issue on your hardware, on older or less capable graphics cards the texture size must be a power of 2. That means that textures of size 64x128, or 4x512 might work, but your 75x75 texture is non-standard and might not always work properly. If the graphics card doesn't support non-power-of-2 textures, the call to glTexImage2D will fail.
Last edited on
Topic archived. No new replies allowed.