Skip to main content
GameDev.net gamedev.net
🔒 Locked

glTexImage2D, the culprit?

Started by Modena_au Nov 19, 2004 at 7:16 PM 8 replies 2.6k views
Original Post
Modena_au
Modena_au
Alright, I'm having a bear of a time with this texture mapping. I've included code, I'm really hoping some one can give me a hand. If anyone can figure out why the texture isn't displaying, I'd really appreciate it. I'm suspicious of glTexImage2D. Sorry about the length.

#include <gl\glut.h>
#include <fstream>
#include <vector>

using namespace std;

struct sImage
{
	GLuint uiFormat;
	GLuint uiWidth;
	GLuint uiHeight;
	GLuint uiLength;
	GLuint uiChannels;
	GLubyte *pubData;
};

#pragma pack(1) // Makes sure that our struct isn't packed
struct sBMPHeader
{
	char cIdentifier[2];
	unsigned int uiFileSize;
	unsigned int uiReserved;
	unsigned int uiOffset;
	unsigned int uiHeaderSize;
	unsigned int uiWidth;
	unsigned int uiHeight;
	unsigned short usPlanes;
	unsigned short usBPP;
	unsigned int uiCompression;
	unsigned int uiDataSize;
	unsigned int uiHResolution;
	unsigned int uiVResolution;
	unsigned int uiColors;
	unsigned int uiImportantColors;
	unsigned int uiPalette[4];
};
#pragma pack() // Sets packing back to default (faster for non-file structs)

sImage *loadImage(string fileName);
void display();

GLuint gTextureID = 0;
sImage *IMAGE;

void main()
{
	IMAGE = loadImage("c:\\Grass00.bmp");

	glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
	glutInitWindowSize(800, 600);
	glutCreateWindow("BMP");
	glutDisplayFunc(display);

	// Generate a texture id
	glGenTextures(1, &gTextureID);

	// bind it to the texture we're about to load
	glBindTexture(GL_TEXTURE_2D, gTextureID);

	glPixelStorei(GL_UNPACK_ALIGNMENT, 1);

	// set up the image we loaded as a openGL texture
	glTexImage2D(GL_TEXTURE_2D, 0, GL_BGR_EXT, IMAGE->uiWidth, 
		IMAGE->uiHeight, 0, GL_BGR_EXT, GL_UNSIGNED_BYTE, IMAGE->pubData);    
	
	glEnable(GL_TEXTURE_2D);

	glutMainLoop();	

	glDisable(GL_TEXTURE_2D);
};

sImage *loadImage(string fileName)
{
	fstream imageFile;
	imageFile.open(fileName.c_str(), ios::in | ios::binary);

	sBMPHeader *imageHeader = new sBMPHeader;
	sImage *imageData = new sImage;

	imageFile.read((char *)imageHeader, sizeof(*imageHeader));
	
	imageData->uiLength = imageHeader->uiDataSize;
	imageData->uiWidth = imageHeader->uiWidth;
	imageData->uiHeight = imageHeader->uiHeight;
	imageData->uiChannels = imageHeader->usPlanes;

	if (strcmp(imageHeader->cIdentifier, "BM"))
	{
		if (imageHeader->usBPP == 32)
			imageData->uiFormat = GL_BGRA_EXT;
		else if (imageHeader->usBPP == 24)
			imageData->uiFormat = GL_BGR_EXT;
	}
	else 
		imageData->uiFormat = GL_RGB;

	imageData->pubData = new GLubyte[imageData->uiLength];
	imageFile.seekg(imageHeader->uiOffset);

	// Read it in one at a time, or else it will load in a string and not get
	// the entire file.
	for (int i = 0; i < imageData->uiLength; i++)
		imageFile.read(reinterpret_cast<char *>(&imageData->pubData), 1);

	return imageData;
};

void display()
{
	glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	

	glBindTexture(GL_TEXTURE_2D, gTextureID);
	glBegin(GL_QUADS);
		glTexCoord2f(1.0f, 0.0f); glVertex2f(0.5f, -0.5f);
		glTexCoord2f(1.0f, 1.0f); glVertex2f(0.5f, 0.5f);
		glTexCoord2f(0.0f, 1.0f); glVertex2f(-0.5f, 0.5f);
		glTexCoord2f(0.0f, 0.0f); glVertex2f(-0.5f, -0.5f);
	glEnd();

	//Just to make sure that the texture information was loaded properly
	glRasterPos2f(0.5f, -0.5f);
	glDrawPixels(64, 64, GL_BGR_EXT, GL_UNSIGNED_BYTE, IMAGE->pubData);
	glDisable(GL_TEXTURE_2D);

	glutSwapBuffers();
	//glFlush();

};


[Edited by - Modena_au on November 19, 2004 9:37:18 PM]
Brother Bob
Brother Bob
GL_BGR_EXT is not a valid internal format, you should use GL_RGB instead if you want a three color components.
Modena_au
Modena_au
As far as internal format goes, I've tried GL_RGB, GL_RGBA, GL_BGR_EXT, and GL_BGRA_EXT. And there was a glEnable(GL_TEXTURE_2D) right before the main loop. Any other suggestions?
Enigma
Enigma
A few issues:
  1. You need to set the minification and magnification mode for your texture with calls to glTexParameter{if}(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, minificationFilter); and glTexParameter{if}(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, magnificationFilter);.

  2. You texture loading code does not allow for bitmaps which (validly) set the uiDataSize member to zero.

  3. You are leaking memory. delete what you new and delete[] what you new[]

  4. Whenever I see somebody using Hungarian notation in C++ I point them towards this article. Not that there's anything necessarily wrong with Hungarian notation, but it's pretty pointless [smile].


Enigma

MaulingMonkey
MaulingMonkey
Quote:
Original post by Modena_au
As far as internal format goes, I've tried GL_RGB, GL_RGBA, GL_BGR_EXT, and GL_BGRA_EXT. And there was a glEnable(GL_TEXTURE_2D) right before the main loop. Any other suggestions?


You disable it after every frame, you need to either take out the glDisable call inside of display() (right underneath the glDrawPixels call) or add a glEnable call to the top of it. Otherwise, textures are enabled - for the first frame only.

Also, FYI, GL_BGR_EXT and GL_BGRA_EXT are not supported by all graphics cards - these are extensions. It's preferable to use GL_RGB whenever possible (except for areas where speed is a major issue - displaying a movie stored in BGR for example - in which case you should at least check for the card's support for BGR).

Also, if the data of IMAGE isn't completely changing every frame, creating a texture for it instead of using glDrawPixels will be faster (since glDrawPixels has to send all the pixels every frame, whereas textures get stored in the video card's memory)
zedzeek
zedzeek
>># You need to set the minification and magnification mode for your texture with calls to glTexParameter{if}(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, minificationFilter); and glTexParameter{if}(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, magnificationFilter);.<<

good point, check out the spec, the section about texture completeness it will tell u the things required for a valid, texture

>>Whenever I see somebody using Hungarian notation in C++ I point them towards this article. Not that there's anything necessarily wrong with Hungarian notation, but it's pretty pointless .<<

to right, i believe the guy that invented it works for ms
Myopic Rhino
Myopic Rhino
Quote:
Original post by zedzeek
>># You need to set the minification and magnification mode for your texture with calls to glTexParameter{if}(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, minificationFilter); and glTexParameter{if}(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, magnificationFilter);.<<

good point, check out the spec, the section about texture completeness it will tell u the things required for a valid, texture
The issue isn't so much that you have to set the minification and magnification filters explicitly; there *are* default states that will be used if you don't. The problem is that the default minification filter is one of the mipmapping modes, so if you don't change it or define all the mipmap levels, the texture will be incomplete, which will effectively disable texture mapping.
Modena_au
Modena_au
Guys, fantastic!!! I appreciate all of your information so much. I had actually noticed that I was disabiling the textures every time after I had posted, but I forgot to update the code in my post. Also, just to note, I realize I wasn't clearning the memory, but I just wanted the throw together a very simple application to demonstrate what I was doign to create my textures. Also, I understand what your saying about the hungarian notation, but I've just been using this coding style for so long that I dont' see any reason in changing now. Old habbits die hard, as they say.
zedzeek
zedzeek
Quote:
Original post by Myopic Rhino
The issue isn't so much that you have to set the minification and magnification filters explicitly; there *are* default states that will be used if you don't. The problem is that the default minification filter is one of the mipmapping modes, so if you don't change it or define all the mipmap levels, the texture will be incomplete, which will effectively disable texture mapping.


cheers for the clarification (just read the spec again, heres me thinking also until now u needed to set clamping settings as well)

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.