Page 2 of 2

Re: OpenGL Texture Problem

Posted: Fri Mar 25, 2011 10:06 am
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

Re: OpenGL Texture Problem

Posted: Fri Mar 25, 2011 11:39 am
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.