Skip to main content
gamedev.net
🔒 Locked

SDL_Surface (array) - OpenGL Texture (array) Corruption

Started by RyanA 1 reply 2.3k views
Original Post
RyanA
RyanA
I currently have a function which turns color-keyed transparency bmp's into OpenGL textures working perfectly. So today, I tried to adapt that function into a simple monospace bitmap font loader/renderer. For some reason, the GL textures are corrupt or something..and I haven't really figured out the problem. font.h:

// Font.h
#include <windows.h>
#include <gl/gl.h>

struct MonoFont
{
	int glyph_width;
	int glyph_height;
	int glyph_tex_width;
	int glyph_tex_height;
	GLuint glyphs[128];
};

MonoFont LoadBmpFont(char *filename);
void DrawText(MonoFont font, int x, int y, char *text, ...);

font.cpp

MonoFont LoadBmpFont(char *filename)
{
	MonoFont Temp;
	
	SDL_Surface *FullFont;
	FullFont = SDL_LoadBMP(filename);

	Temp.glyph_width = FullFont->w / 16;
	Temp.glyph_height = FullFont->h / 6;
	Temp.glyph_tex_width = NextPowerOfTwo(Temp.glyph_width);
	Temp.glyph_tex_height = NextPowerOfTwo(Temp.glyph_height);

	SDL_Surface *GlyphSurfaces[128];

	#if SDL_BYTEORDER == SDL_LIL_ENDIAN
		for(int i=0; i<128; i++)
		{
			GlyphSurfaces = SDL_CreateRGBSurface(SDL_SWSURFACE, Temp.glyph_tex_width,
				Temp.glyph_tex_height, 32, 0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000);
		}
	#else
		for(int i=0; i<128; i++)
		{
			GlyphSurfaces = SDL_CreateRGBSurface(SDL_SWSURFACE, Temp.glyph_tex_width,
				Temp.glyph_tex_height, 32, 0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF);
		}
	#endif

	Uint32 ColorKey;
	
	for(int i=0; i<128; i++)
	{
		ColorKey = SDL_MapRGBA(GlyphSurfaces->format, 255, 0, 255, 0);
		SDL_FillRect(GlyphSurfaces, 0, ColorKey);
	}

	ColorKey = SDL_MapRGBA(FullFont->format, 255, 0, 255, 0);
	SDL_SetColorKey(FullFont, SDL_SRCCOLORKEY, ColorKey);

	SDL_Rect source;
	source.x = 0;
	source.y = 0;
	source.w = Temp.glyph_width;
	source.h = Temp.glyph_height;

	SDL_Rect dest;
	dest.x = 0;
	dest.y = 0;
	dest.w = Temp.glyph_width;
	dest.h = Temp.glyph_height;

	for(int i=32; i<128; i++)
	{
		SDL_BlitSurface(FullFont, &source, GlyphSurfaces, &dest);
	
		source.x += 8;
		if(source.x == 128)
		{
			source.x = 0;
			source.y += 12;
		}
	}

	for(int i=32; i<128; i++)
	{
		glGenTextures(1, &Temp.glyphs);
		glBindTexture(GL_TEXTURE_2D, Temp.glyphs);

		// Todo: Figure out what parameters I need here:
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);

		glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, Temp.glyph_tex_width, Temp.glyph_tex_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, GlyphSurfaces->pixels);
	}

	SDL_SaveBMP(GlyphSurfaces[82], "char.bmp");
	return Temp;
}

void DrawText(MonoFont font, int x, int y, char *text, ...)
{
	char FullText[1024];
	va_list ParseVars;
	va_start(ParseVars, text);
	vsprintf(FullText, text, ParseVars);
	va_end(ParseVars);

	int ascii;
	int glyph_x = x;

	for(int i=0; i<(int)strlen(text); i++)
	{
		ascii = (int)FullText;

		glEnable(GL_TEXTURE_2D);
		glBindTexture(GL_TEXTURE_2D, font.glyphs[ascii]);
		glBegin(GL_QUADS);
			glTexCoord2f(0.0, 0.0);		glVertex2i(glyph_x, y);
			glTexCoord2f(1.0, 0.0);		glVertex2i(glyph_x + font.glyph_tex_width, y);
			glTexCoord2f(1.0, 1.0);		glVertex2i(glyph_x + font.glyph_tex_width, y+font.glyph_tex_height);
			glTexCoord2f(0.0, 0.0);		glVertex2i(glyph_x, y+font.glyph_tex_height);
		glEnd();
		glDisable(GL_TEXTURE_2D);

		glyph_x += font.glyph_width;
	}
}

At first I thought the SDL_Surface of each glyph was corrupted, so I saved a bitmap of a few of them to see if it worked, which they do. It just seems somewhere in the handoff between SDL_Surface -> GL Texture, something gets lost / corrupted in translation. If it would help to post the regular texture loading code, that works perfectly, I can do that as well. I did not post it now because the functions are not called anywhere in these source files, just using the same concepts. As always thank you for your help! Once these bugs are worked out I can post up both this and the bmp texture loader if it will help anyone. :) Oh, here is a screenshot of the corruption. As you can sort of make out, it's supposed to read "Hello World!". (Click the thumbnail) -Ryan
Shadx
Shadx
Did you try setting the unpack_row_length?

glPushClientAttrib(GL_CLIENT_PIXEL_STORE_BIT);		glPixelStorei(GL_UNPACK_ROW_LENGTH, GlyphSurfaces->pitch / GlyphSurfaces->format->BytesPerPixel);...glPopClientAttrib();


Cheers
RyanA
RyanA
Thanks for the suggestion, I added the code here:

for(int i=32; i<128; i++){	glPushClientAttrib(GL_CLIENT_PIXEL_STORE_BIT);	glPixelStorei(GL_UNPACK_ROW_LENGTH, GlyphSurfaces->pitch / GlyphSurfaces->format->BytesPerPixel);	glGenTextures(1, &Temp.glyphs);	glBindTexture(GL_TEXTURE_2D, Temp.glyphs);			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, Temp.glyph_tex_width, Temp.glyph_tex_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, GlyphSurfaces->pixels);			glPopClientAttrib();}


But it's still showing the textures as I showed above. Any other suggestions you can think of? I am really stumped.

Topic Locked

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

Sign in to reply to this topic.