Page 1 of 1

[SOLVED]GL doesn't properly display the image.

Posted: Mon Mar 04, 2013 5:12 pm
by rocko384
I've been working on an engine for a 2D RPG (like the originality?), and recently transitioned from using SDL for drawing to the framebuffer, to the almighty OpenGL. I've migrated pretty much everything over to GL, except images either wont load correctly, or aren't being displayed correctly. Here's a picture (yes, the test sprite is a dick. I'm not the artist in the project)
Image

I wouldn't think the issue would be byte alignment, seeing as the sheet is 512x1024 pixels, but what the hell do I know. Does anyone know what the hell I did to anger the gods? I can post whatever snippets of code anyone needs to see.

Re: GL doesn't properly display the image.

Posted: Mon Mar 04, 2013 5:15 pm
by rocko384

Code: Select all

void IDTexture::Load(IDStr fn) {
		IDSurface* tmp = IMG_Load(fn.c_str());
		IDSurface* op;
		IDSurface* ret;
		int nOfColors;
		GLenum format;
		if (!tmp) {
			std::cout << "IMG_Load Failed: " << SDL_GetError() << std::endl;
			IdenCode = ID_IMG_FAILURE;
			return;
		}
		if (tmp->format->BytesPerPixel == 3) {
			op = SDL_DisplayFormat(tmp);
			SDL_FreeSurface(tmp);
			if (op != NULL) {
				Uint32 ck = SDL_MapRGB(op->format, 0x00, 0x64, 0x00);
				SDL_SetColorKey(op, SDL_SRCCOLORKEY, ck);
			}
			ret = op;
		}
		else {
			ret = tmp;
		}

		
		filename = fn;
		IdenCode = (SDL_GetTicks());
		std::cout << filename << "'s Code: " << IdenCode << std::endl;
		MakeTex(ret);
	}


void IDTexture::MakeTex(IDSurface* s) {
		glPixelStorei(GL_UNPACK_ALIGNMENT,4);

		glGenTextures(1,&t);
		glBindTexture(GL_TEXTURE_2D,t);

		glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
		glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);

		glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER, GL_NEAREST);
		glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER, GL_NEAREST);

		SDL_PixelFormat *fmt = s->format;

		tWidth = (float)s->w;
		tHeight = (float)s->h;

		if (fmt->Amask) {
			gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGBA, tWidth, tHeight, GL_RGBA, GL_UNSIGNED_BYTE, s->pixels);
		}
		else {
			gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGB, tWidth, tHeight, GL_RGB, GL_UNSIGNED_BYTE, s->pixels);
		}

		SDL_FreeSurface(s);
		IDSingleton<IDTextureManager>::GetSingletonPtr()->RegisterTexture(this);
	}
The methods used to load the image in the engine. IDSurface is just a typedef of SDL_Surface. IDSingleton is just a template class to acquire the pointer to each core's instance.

Re: GL doesn't properly display the image.

Posted: Mon Mar 04, 2013 5:21 pm
by rocko384
Image
The original sheet for anyone that needed to see it.

Re: GL doesn't properly display the image.

Posted: Mon Mar 04, 2013 8:05 pm
by YourNerdyJoe
When I made a function like this a while back I used this and here is a simplified version.
They both use GL_LINEAR instead of GL_NEAREST in these lines:

Code: Select all

      glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER, GL_NEAREST);
      glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER, GL_NEAREST);
I think I remember this fixing a problem I had a long time ago so try this. If that does help try changing other differnces.
You can probably tell I'm not really a guru with ogl texture loading. I just use SOIL to load textures now while I stick to the rendering. So... if all else fails switch to SOIL ;) .

Re: GL doesn't properly display the image.

Posted: Mon Mar 04, 2013 8:30 pm
by rocko384
Thanks for the reply YourNerdyJoe. Switching the GL parameter to GL_LINEAR didn't fix it though :( I had someone tell me that it was probably an issue with Alpha, but I'm not entirely sure, though I can see, based on the results, how GL would be having a problem handling it. I swear by Bjarne and Dennis that I will solve this.

Re: GL doesn't properly display the image.

Posted: Tue Mar 05, 2013 3:25 am
by bbguimaraes
No time to check the code carefully, but take a look at the format parameters, see if they are right. Or try loading the example texture on the texture chapter of the red book (scroll down until you see a checkered image).

Re: GL doesn't properly display the image.

Posted: Tue Mar 05, 2013 10:33 am
by dandymcgee
I think bbguimaraes is right, your format params are wrong:
if (fmt->Amask) {
    gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGBA, tWidth, tHeight, GL_RGBA, GL_UNSIGNED_BYTE, s->pixels);
} else {
    gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGB, tWidth, tHeight, GL_RGB, GL_UNSIGNED_BYTE, s->pixels);
}
Try changing the second "GL_RGBA" to "GL_BGRA", and same for the "GL_RGB" -> "GL_BGR". I'm not sure if these are the right values, but I'm pretty sure that is what you need to change.
if (fmt->Amask) {
    gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGBA, tWidth, tHeight, GL_BGRA, GL_UNSIGNED_BYTE, s->pixels);
} else {
    gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGB, tWidth, tHeight, GL_BGR, GL_UNSIGNED_BYTE, s->pixels);
}

Re: GL doesn't properly display the image.

Posted: Tue Mar 05, 2013 1:36 pm
by rocko384
Thanks for the help you guys! I ended up making the function to turn the Surface into a Texture decipher the color format for itself, and that fixed the issue! Here's the source of the Surface loading function and Texture producing function for future generations:

Code: Select all

void IDTexture::Load(IDStr fn) {
		IDSurface* tmp = IMG_Load(fn.c_str());
		IDSurface* op;
		IDSurface* ret;
		
		if (!tmp) {
			std::cout << "IMG_Load Failed: " << SDL_GetError() << std::endl;
			IdenCode = ID_IMG_FAILURE;
			return;
		}
		if (tmp->format->BytesPerPixel == 3) {
			op = SDL_DisplayFormat(tmp);
			SDL_FreeSurface(tmp);
			if (op != NULL) {
				Uint32 ck = SDL_MapRGB(op->format, 0x00, 0x64, 0x00);
				SDL_SetColorKey(op, SDL_SRCCOLORKEY, ck);
			}
			ret = op;
			
		}
		else if (tmp->format->BytesPerPixel == 4) {
			ret = tmp;
		}
		else {
			std::cout << "Image load failed. Image's color depth is less than 3 bytes" << std::endl;
			std::exit(EXIT_FAILURE);
		}

		

		filename = fn;
		IdenCode = (SDL_GetTicks());
		tWidth = ret->w;
		tHeight = ret->h;
		std::cout << filename << "'s Code: " << IdenCode << std::endl;
		MakeTex(ret);
	}


void IDTexture::MakeTex(IDSurface* s) {
		int nOfColors;
		GLenum format;

		if ((s->w) & (s->w-1) != 0) {
			std::cout << "WARNING: " << filename << " WIDTH is not a power of two" << std::endl;
		}

		if ((s->h) & (s->h-1) != 0) {
			std::cout << "WARNING: " << filename << " HEIGHT is not a power of two" << std::endl;
		}

		nOfColors = s->format->BytesPerPixel;

		if (nOfColors == 4) {
			if (s->format->Rmask == 0x000000FF) {
				format = GL_RGBA;
			}
			else {
				format = GL_BGRA;
			}
		}
		else if (nOfColors == 3) {
			if (s->format->Rmask == 0x000000FF) {
				format = GL_RGB;
			}
			else {
				format == GL_BGR;
			}
		}
		else {
			std::cout << "ERROR: " << filename << " COLOR FORMAT not supported" << std::endl;
			std::exit(EXIT_FAILURE);
		}

		glPixelStorei(GL_UNPACK_ALIGNMENT, 4);

		glGenTextures(1, &t);
		glBindTexture(GL_TEXTURE_2D, t);

		glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
		glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);

		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
		
		SDL_PixelFormat *fmt = s->format;

		tWidth = (float)s->w;
		tHeight = (float)s->h;

		if (fmt->Amask) {
			gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGBA, tWidth, tHeight, format, GL_UNSIGNED_BYTE, s->pixels);
		}
		else {
			gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGB, tWidth, tHeight, format, GL_UNSIGNED_BYTE, s->pixels);
		}
		
		SDL_FreeSurface(s);
		IDSingleton<IDTextureManager>::GetSingletonPtr()->RegisterTexture(this);
	}

Re: [SOLVED]GL doesn't properly display the image.

Posted: Tue Mar 05, 2013 2:03 pm
by bbguimaraes
Bottom-left: (0, 0), upper-right: (1, 1). See this.

Re: [SOLVED]GL doesn't properly display the image.

Posted: Tue Mar 05, 2013 2:14 pm
by rocko384
Thanks bbguimaraes.