OpenGL Texture Problem

Whether you're a newbie or an experienced programmer, any questions, help, or just talk of any language will be welcomed here.

Moderator: Coders of Rage

User avatar
MrDeathNote
ES Beta Backer
ES Beta Backer
Posts: 594
Joined: Sun Oct 11, 2009 9:57 am
Current Project: cocos2d-x project
Favorite Gaming Platforms: SNES, Sega Megadrive, XBox 360
Programming Language of Choice: C/++
Location: Belfast, Ireland
Contact:

Re: OpenGL Texture Problem

Post by MrDeathNote »

Ok so i'm at work and i'm kinda bored so i've given it a go at recreateing the code I was gonna post later. Note that this is untested but should give you a good idea of what should be going on. Also Texture is a class that holds a GLuint, a height and a width (that should be pretty obvious from the code).

Code: Select all

	Texture temp;
	
	/*
	Draw simple white text to the screen
	*/
	void RenderText(TTF_Font* font, Vector2& position, const char *fmt, ...){
		//Holds the string
		char text[256];
		int h,w;

		//Color for the text
		SDL_Color color;
		color.r = 255;
		color.g = 255;
		color.b = 255;

		// Pointer to list of arguments
		va_list ap;

		// If There's no text, do nothing
		if (fmt == NULL)
				return;

		// Parses the string for variables
		va_start(ap, fmt);
				vsprintf(text, fmt, ap);
		va_end(ap);

		//Create the font texture
		SDL_Surface *initial = TTF_RenderText_Blended(font, text, color);
		h = initial->h;
		w = initial->w;
		Texture texture = createGLTexture(initial);

		//Temporary vars
		Rect dimensions = Rect(position.getX(), position.getY(), texture.getHeight(), texture.getWidth());
		Rect source = Rect(0, 0, texture.getHeight(), texture.getWidth());

		//Draw the text
		drawQuad(texture, dimensions, source);
	}
	
	/*
	Draw simple textured quad
	*/
	void drawQuad(Texture &texture, Rect &dimensions, Rect &source){
			//Bind the texture (will be the texture used for this quad)
			glBindTexture(GL_TEXTURE_2D, texture.getTexture());

			//Calculate texture coords
			float min_x = (float)(source.getX())/texture.getWidth();
			float min_y = (float)(source.getY())/texture.getHeight();
			float max_x = (float)(source.getX() + source.getWidth())/texture.getWidth();
			float max_y = (float)(source.getY() + source.getHeight())/texture.getHeight();

			//Draw the quad to the screen
			glBegin(GL_QUADS);
					glTexCoord2f(min_x, max_y); glVertex2i(dimensions.getX(), dimensions.getY() + dimensions.getHeight());
					glTexCoord2f(min_x, min_y); glVertex2i(dimensions.getX(), dimensions.getY());
					glTexCoord2f(max_x, min_y); glVertex2i(dimensions.getX() + dimensions.getWidth(), dimensions.getY());
					glTexCoord2f(max_x, max_y); glVertex2i(dimensions.getX() + dimensions.getWidth(), dimensions.getY() + dimensions.getHeight());
			glEnd();

			glLoadIdentity();
	}
	
	/*
	Create a texture from sdl_surface
	*/
	Texture& createGLTexture(SDL_Surface* tex){
		//Declare a GL texture
		GLuint texture = 0;

		if(tex){
				//Bind the texture
				glGenTextures(1, &texture);
				glBindTexture(GL_TEXTURE_2D, texture);
		   
				//Get the height and width of the texture and bpp
				int width = tex->w;
				int height = tex->h;
				int bpp = tex->format->BitsPerPixel;

				//Set the mode
				int mode = GL_RGB;

				//Check bpp
				if(bpp == 32)
					 mode = GL_RGBA;

				//Generate the texture
				glTexImage2D( GL_TEXTURE_2D, 0, tex->format->BytesPerPixel,
							 width, height, 0, mode, GL_UNSIGNED_BYTE, tex->pixels );

				//Set texture parameters
				glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
				glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

				//Free the SDL_surface
				SDL_FreeSurface(tex);

				//Create the new texture
				temp = Texture(texture, height, width);
		}

		//Return the texture
		return temp;
}
EDIT: I don't condone using immediate mode but this was the quickest way to demonstrate my point
http://www.youtube.com/user/MrDeathNote1988

Image
Image

"C makes it easy to shoot yourself in the foot. C++ makes it
harder, but when you do, it blows away your whole leg." - Bjarne Stroustrup
qpHalcy0n
Respected Programmer
Respected Programmer
Posts: 387
Joined: Fri Dec 19, 2008 3:33 pm
Location: Dallas
Contact:

Re: OpenGL Texture Problem

Post by qpHalcy0n »

You need to be sure of your source image's format. Make sure it is indeed ARGB as this is what you've specified to SDL. If this is indeed the case then you can not use GL_RGBA as a source image format to glTexImage. This simply will not give you the correct results. There is no GL_ARGB so you have to use a bit of tom foolery. You can say that the image is of type GL_BGRA which is a common form, then for the "type" parameter (next to last in glTexImage2D), use GL_UNSIGNED_INT_8_8_8_8_REV. This tells the API that the source pixels are in reverse order.

The other issue that appears to be suspect is your blend mode. GL_ONE/GL_ONE? This is an additive blend and will simply add the values in the backbuffer to the values coming in piece by piece. Works for many techniques, not this one. If you have a fontmap, then it should be of RGBA format (not RGB), and your blend mode would be glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ). Render text last, always.

Lastly, with your glColor4f( 1, 1, 1, alpha ). The default texture combiner is GL_MODULATE, this means that whatever is sampled from the texture is multiplied with any other source color (be it color, another texture, or what have you). So keep an eye on what "alpha" is. If it's zero then the whole thing disappears regardless.

Start there, see what ya come up with.
Post Reply