256x256pixel textures

Started by
48 comments, last by Harrism 18 years, 3 months ago
You are all making this much more complicated than necessary. Like I said before you just need to load the image into a larger 2^ texture, but, the image data must match that size or it won't work:

This won't work out of the box, and utilizes SDL_image to load the actual image for cross-platform compatibility. However, if you look over this code it should help you get the idea.

typedef struct {	GLuint texture;	int ow;			// Old width	int oh;			// Old height	int w;	int h;	char filename[32];	char type;	char *bitmask;} GLtexture;GLtexture* OGL_S2T(char *filename){	Uint8 *rowhi, *rowlo;	Uint8 *tmpbuf, tmpch;	SDL_Surface *s;	SDL_Surface *tmp;	int i, j;	int x2, y2;	SDL_Color clr;	Uint32 col = 0;	Uint32 col2 = 0;	char *gpos = NULL;	char *hpos = NULL;	int iw=0, ih=0;	int exp = 1;	GLtexture *tex = (GLtexture *)malloc(sizeof(GLtexture));	s = IMG_Load(filename);	if ( s == NULL ) {		fprintf(stderr, "Unable to load %s: %s\n", filename, SDL_GetError());		return(NULL);	}	SDL_DisplayFormatAlpha(s);	tex->ow = s->w;	tex->oh = s->h;	while(pow(2, exp) < s->w)		exp++;	iw = pow(2, exp);	exp = 1;	while(pow(2, exp) < s->h)		exp++;	ih = pow(2, exp);	tmp = SDL_CreateRGBSurface(SDL_HWSURFACE|SDL_SRCALPHA, iw, ih, 32, 0, 0, 0, 255);	SDL_LockSurface(tmp);	SDL_LockSurface(s);	y2 = 0;	while(y2 < s->h)	{		x2 = 0;		while(x2 < s->w)		{			gpos = (char *)s->pixels;			gpos += (s->pitch * y2);			gpos += (s->format->BytesPerPixel * x2);			hpos = (char*)tmp->pixels;			hpos += (tmp->pitch *y2);			hpos += (tmp->format->BytesPerPixel * x2);			memcpy(&col, gpos, s->format->BytesPerPixel);			SDL_GetRGBA(col, s->format, &clr.r, &clr.g, &clr.b, &clr.unused);			col2 = SDL_MapRGBA(s->format, clr.r, clr.g, clr.b, clr.unused);			memcpy(hpos, &col2, tmp->format->BytesPerPixel);			x2++;		}		y2++;	}	SDL_UnlockSurface(tmp);	SDL_UnlockSurface(s);	tex->bitmask = GenBitMask(s);		SDL_FreeSurface(s);	/* GL surfaces are upsidedown and RGB, not BGR :-) */	tmpbuf = (Uint8 *)malloc(tmp->pitch);	if ( tmpbuf == NULL ) {		fprintf(stderr, "Out of memory\n");		return(NULL);	}	rowhi = (Uint8 *)tmp->pixels;	rowlo = rowhi + (tmp->h * tmp->pitch) - tmp->pitch;	for ( i=0; i<tmp->h/2; ++i ) {		for ( j=0; j<tmp->w; ++j ) {			tmpch = rowhi[j*4];			rowhi[j*4] = rowhi[j*4+2];			rowhi[j*4+2] = tmpch;			tmpch = rowlo[j*4];			rowlo[j*4] = rowlo[j*4+2];			rowlo[j*4+2] = tmpch;		}		memcpy(tmpbuf, rowhi, tmp->pitch);		memcpy(rowhi, rowlo, tmp->pitch);		memcpy(rowlo, tmpbuf, tmp->pitch);		rowhi += tmp->pitch;		rowlo -= tmp->pitch;	}	free(tmpbuf);	glGenTextures(1, &tex->texture);	glBindTexture(GL_TEXTURE_2D, tex->texture);	tex->w = iw;	tex->h = ih;	glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);	glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);	glTexImage2D(GL_TEXTURE_2D, 0, 4, iw, ih, 0, GL_BGRA, GL_UNSIGNED_BYTE, tmp->pixels);	SDL_FreeSurface(tmp);	strcpy(tex->filename, filename);	tex->type = GFX_TYPE_BMP;	return tex;	}
---John Josef, Technical DirectorGlass Hat Software Inc
Advertisement
Even better:

No need to scale the image, which will distort the picture.

Create the texture at 1024x512 (why does he need 1024x1024 when the height is 480?) but do not supply data - pass in NULL for the data ptr and the texture will be created without initial texel data. YES this is legal and supported for non-compressed textures.

Then use glTexSubImage to download the 640x480 image. Now these texels are defined but the texels outside this range are undefined.

Set the MIN and MAG filters to NEAREST since you want to blit the image without blurring it, and you dont want to sample outside the defined 640x480 region.

Now render with appropriate texcoord. Instead of corners at (0,0) and (1,1) use (0,0) and (640.0/1024.0, 480.0/512.0).

This will work portably without any extensions. texture_rectangle is ideal for this but its not supported on your hardware, so this is the next best answer.
What? You're still helping me after what I said?

I'm reading. Having a few problems working out how to generate maps from bitmaps but I'll get there, I'm reading up on ratio's at the moment.

Hmm, Gold, I'm not sure why but it does seem to work as it is, texture is 640x480, it's just stretched out over the shape. I'm not sure why this is happening if you say its impossible, have I touch another part of GL without relieasing it?

Although I'm understanding how transpancy works, it feels like it's cheating but I suppose I could work out another way of getting it working. Every pixel that is pink is masked say. It does seem a shame for a need of two images. Anyway I'm off to read what you wrote and try and get this bitmap2map generator ratio working. I might need to write a generator and then load the map from a text file else it'll take a good 10 minutes to load each map (I've just been experimenting)
Quote:
Intel never liked the texture_rectangle extension so I'm not surprised they don't support it. The most efficient solution for you is going to be splitting the image into power-of-two tiles. Or get a new card.


I'm going to have to say it, I'm coding on a laptop cos it's nicer, I have a geforce sitting in the corner, a radeon in my second box and a radeon x800 which blew on me a few months back. Laptop is nicest to type on. The bitmap loading seems to work, I might give it a trial run on my otherbox if your saying its impossible or it shouldn't.

It's basicly just a bitmap loader for opengl right now, few transparency images, nothing much. Collision detection is after the bitmap2map generator.
Quote:Original post by Harrism
Hmm, Gold, I'm not sure why but it does seem to work as it is, texture is 640x480, it's just stretched out over the shape. I'm not sure why this is happening if you say its impossible, have I touch another part of GL without relieasing it?

Not sure I understand - you created a 640x480 texture? Either your driver support texture_non_power_of_two or OpenGL 2.0. Dandy! But you say its stretched over an object? I thought you were trying to render a background image. Is it working as desired?
Quote:Although I'm understanding how transpancy works, it feels like it's cheating but I suppose I could work out another way of getting it working. Every pixel that is pink is masked say.

Sounds like you want a color key? Unfortunately this is not supported. You don't need a separate texture, but you can put this in the alpha channel. Some implementations support RGB5_A1 as an internal format, 5 bits each for RGB and 1 for alpha - good for masking if you can deal with lower color resolution. Otherwise just use RGBA8. By the way, you can use alpha test instead of blending if you just want to render with a mask - its more efficient since it doesnt involve a read-modify-write for each pixel.

Well I'll ask that a little later on, if I can get this running I can start modifying it all but the platform works well. For some reason (bitmap2map works btw) by using a polygon of about 200 it doesn't want to display all the points and decides to skip out on about half of them only producing the basic image. (say you had a square with a point sticking in one side, it would smooth it out so it was an exact square - same princible)

Got to find a way to get that sorted since I plan on cheating on the platform front. Long story but it'll end up opensource most likely (due to the nature of the game theres no way I can sell it, but i'm going to have a lot of fun with it :-))
You are right tho, I plan to look into that a little later. It'll make level editing so much easilier but for now :-)
If you use mipmapping then there is no need for the texture to be either a square or a power of 2, you can use any shape or size you desire.
Quote:Original post by AndyEsser
If you use mipmapping then there is no need for the texture to be either a square or a power of 2, you can use any shape or size you desire.


I believe you are thinking of gluBuild2DMipmaps which resizes the source image to a power of two. This happens behind your back (in the GLU library) but by the time the GL sees it, its a power of two.

Mipmapping does not remove the OpenGL 1.x requirement that textures be a power of two.
You are right I've properly examined the code.

Thanks that's a good thing to know about mipmap.

This topic is closed to new replies.

Advertisement