Converting surfaces to OpenGL textures

I’ve got it SO close. It’s ALMOST working. But I can’t seem to get it match
just right.

I’m trying to tease it into the proper byte order by creating a software
surface, then blitting to it. Here’s the relevant code.

GLuint tex;

glGenTextures(1,&tex);

conv=SDL_CreateRGBSurface(SDL_SWSURFACE, s->w, s->h, 32,
0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000);
SDL_BlitSurface(s,NULL,conv,NULL);

glBindTexture(GL_TEXTURE_2D, tex);
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, GL_RGB, s->w, s->h, 0, GL_RGBA,
GL_UNSIGNED_BYTE, conv->pixels);

No matter what I do, no red channel is ever evident. Resaving the 'conv’
surface shows a normal bitmap. What do I do to line these up right?

I’ve got it SO close. It’s ALMOST working. But I can’t seem to get it match
just right.

I’m trying to tease it into the proper byte order by creating a software
surface, then blitting to it. Here’s the relevant code.

conv=SDL_CreateRGBSurface(SDL_SWSURFACE, s->w, s->h, 32,
0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000);

That looks right, but for little-endian (intel) only. For big endian,
this will look all wrong. I assume you’re on a little-endian machine
and don’t intend this to work elsewhere?

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, s->w, s->h, 0, GL_RGBA,
GL_UNSIGNED_BYTE, conv->pixels);

No matter what I do, no red channel is ever evident. Resaving the 'conv’
surface shows a normal bitmap. What do I do to line these up right?

I think your problem is that the first type parameter should be GL_RGBA
as well (like the second), since you are passing it an alpha channel.
That should account for your missing color component.

Though, I could be wrong, I only took a quick glance. Hope this helps.On Wed, Apr 19, 2006 at 12:38:16AM -0600, monttyle wrote:


Steaphan Greene
GPG public key: http://www.cs.binghamton.edu/~sgreene/gpg.key.txt
-------------- next part --------------
A non-text attachment was scrubbed…
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: Digital signature
URL: http://lists.libsdl.org/pipermail/sdl-libsdl.org/attachments/20060419/40f40f77/attachment.pgp

I’ve got it SO close. It’s ALMOST working. But I can’t seem to
get it match
just right.

I’m trying to tease it into the proper byte order by creating a
software
surface, then blitting to it. Here’s the relevant code.

GLuint tex;

glGenTextures(1,&tex);

conv=SDL_CreateRGBSurface(SDL_SWSURFACE, s->w, s->h, 32,
0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000);
SDL_BlitSurface(s,NULL,conv,NULL);

You’re creating an ABGR surface (where A is the most significant
byte). Try creating an ARGB surface instead:
SDL_CreateRGBSurface(SDL_SWSURFACE, s->w, s->h, 32, 0x00ff00000,
0x0000ff00, 0x000000ff, 0xff000000);

glBindTexture(GL_TEXTURE_2D, tex);
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, GL_RGB, s->w, s->h, 0, GL_RGBA,
GL_UNSIGNED_BYTE, conv->pixels);

Then calling:
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, s->w, s->h, 0, GL_BGRA,
GL_UNSIGNED_INT_8_8_8_8_REV, conv->pixels);

This should work on both little-endian and big-endian systems.

Of course, I haven’t tested this, so it’s entirely possible that I’ve
screwed up.

Richard SchreyerOn Apr 18, 2006, at 11:38 PM, monttyle wrote:

In the SDL test directory there is a program called (IIRC) testgl that
contains the code you want. Or, you could just search the mailing
archive, I posted code to do this a few months ago.

Bob PendletonOn Wed, 2006-04-19 at 00:38 -0600, monttyle wrote:

I’ve got it SO close. It’s ALMOST working. But I can’t seem to get it match
just right.

I’m trying to tease it into the proper byte order by creating a software
surface, then blitting to it. Here’s the relevant code.

GLuint tex;

glGenTextures(1,&tex);

conv=SDL_CreateRGBSurface(SDL_SWSURFACE, s->w, s->h, 32,
0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000);
SDL_BlitSurface(s,NULL,conv,NULL);

glBindTexture(GL_TEXTURE_2D, tex);
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, GL_RGB, s->w, s->h, 0, GL_RGBA,
GL_UNSIGNED_BYTE, conv->pixels);

No matter what I do, no red channel is ever evident. Resaving the 'conv’
surface shows a normal bitmap. What do I do to line these up right?


SDL mailing list
SDL at libsdl.org
http://www.libsdl.org/mailman/listinfo/sdl


±-------------------------------------+

Not sure if my code is the most efficient but:

bool loadbmp(char *img, GLuint &image) {
SDL_Surface *temp, *flipped; // temporary SDL image

if((temp = SDL_LoadBMP(img)) == NULL) {
	printf("Cannot load bmp: %s\n", img);
	return false;
}

if(temp->w != temp->h) {
	printf("Image not square\n");
	return false;
}

if(temp->w < 1) {
	printf("Invalid image\n");
	return false;
} else if(!((temp->w & (temp->w-1)) == 0)) {
	printf("Invalid image dimensions\n");
	return false;
}

Uint32 rmask, gmask, bmask, amask;

#if SDL_BYTEORDER == SDL_BIG_ENDIAN
	rmask = 0xff000000;
	gmask = 0x00ff0000;
	bmask = 0x0000ff00;
	amask = 0x000000ff;
#else
	rmask = 0x000000ff;
	gmask = 0x0000ff00;
	bmask = 0x00ff0000;
	amask = 0xff000000;
#endif

// now flip the image
flipped = SDL_CreateRGBSurface(SDL_SWSURFACE, temp->w, temp->h,

temp->format->BitsPerPixel, rmask, gmask, bmask, amask);
if(flipped == NULL) {
printf(“Error flipping image: %s\n”, img);
return false;
}

SLock(temp);
SLock(flipped);

for(int i = 0; i < temp->h; i++) {
	for(int j = 0; j < temp->w; j++) {
		putpixel(flipped, i, temp->h - j - 1, getpixel(temp, i, j));
	}
}

SUnlock(temp);
SUnlock(flipped);



if(temp != NULL) {
	SDL_FreeSurface(temp);
}

// Create textures
glGenTextures(1, &image);

// load the texture
glBindTexture(GL_TEXTURE_2D, image);

// Generate the texture
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, flipped->w, flipped->h, 0,

GL_BGR, GL_UNSIGNED_BYTE, flipped->pixels);

if(flipped != NULL) {
	SDL_FreeSurface(flipped);
}

// Use nearest filtering
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

return true;

}

is what I use when I need to load a bmp as a texture.
Note that I invert the Y axis manualy, and use GL_BGR for the second argument \On 4/20/06, Bob Pendleton wrote:

In the SDL test directory there is a program called (IIRC) testgl that
contains the code you want. Or, you could just search the mailing
archive, I posted code to do this a few months ago.

    Bob Pendleton

On Wed, 2006-04-19 at 00:38 -0600, monttyle wrote:

I’ve got it SO close. It’s ALMOST working. But I can’t seem to get it match
just right.

I’m trying to tease it into the proper byte order by creating a software
surface, then blitting to it. Here’s the relevant code.

GLuint tex;

glGenTextures(1,&tex);

conv=SDL_CreateRGBSurface(SDL_SWSURFACE, s->w, s->h, 32,
0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000);
SDL_BlitSurface(s,NULL,conv,NULL);

glBindTexture(GL_TEXTURE_2D, tex);
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, GL_RGB, s->w, s->h, 0, GL_RGBA,
GL_UNSIGNED_BYTE, conv->pixels);

No matter what I do, no red channel is ever evident. Resaving the 'conv’
surface shows a normal bitmap. What do I do to line these up right?


SDL mailing list
SDL at libsdl.org
http://www.libsdl.org/mailman/listinfo/sdl


±-------------------------------------+


SDL mailing list
SDL at libsdl.org
http://www.libsdl.org/mailman/listinfo/sdl