[SDL] SDL_Image and OpenGL

wazoo at wazooenterprises.com wazoo at wazooenterprises.com
Thu Nov 9 08:43:07 PST 2006


> On 11/9/06, Zhuang Zhao <zhuazhao at yahoo.com> wrote:
>> Hi
>> I used to use BMP loader to load from images files to use as a OpenGL
>> Texture. However, since i started using IMG_Load*, my textures turn out
>> weird. They have repeating bands of red, green, and blue instead of the
>> real
>> texture. I read previous posts on PNG files and OpenGL, but i can't get
>> it
>> to work right.

Hi Zhuang,

The only way I could get it to work was by using the texture loading code
that was posted to this mailing list ages ago, but naturally I forgot to
bookmark it. *sob*

I'll post the code that I use, which works without any problems for me.

=========================================================
//String is defined as std::string (or std::wstring in UNICODE)
//m_tex is a GLuint


bool SceneTexture::loadImage( const String& strFilename, bool bAlpha,
		bool bMipMaps, bool bRepeat )
	{

		//load the image data to an SDL_Surface structure
		SDL_Surface* pTexSurface = IMG_Load( strFilename.c_str() );
		if( NULL == pTexSurface )
		{
			//error
			return false;
		}

		//calculate the total size of the image data. If you are needing
		//the alpha channel then account for that
		int dim = pTexSurface->w * pTexSurface->h * ((bAlpha) ? 4: 3);
		GLubyte *pData = new GLubyte[ dim ];

		//loop through our SDL_Surface and copy it into the array
		//if the image has an extra alpha channel of information then
		//be sure to append that
		int pos = 0;
		for( int y = (pTexSurface->h) - 1; y > -1; y-- )
		{
			for(int x = 0; x < pTexSurface->w; x++)
			{
				Uint8 r, g, b, a;

				//getPixel is defined in the SDL documentation. It just
				//grabs the pixel data from a given SDL_Surface at
				//coordinates x,y
				Uint32 color = getPixel(pTexSurface, x, y);

				if(!bAlpha)
					SDL_GetRGB( color, pTexSurface->format, &r, &g, &b);

				else
					SDL_GetRGBA( color, pTexSurface->format, &r, &g, &b, &a);

				pData[pos] = r; pos++;
				pData[pos] = g; pos++;
				pData[pos] = b; pos++;
				if( bAlpha )
					pData[pos] = a; pos++;
			}
		}


		int type = (bAlpha) ? GL_RGBA : GL_RGB;
		glGenTextures(1, &m_tex);		// Generate texture ID
		glBindTexture(GL_TEXTURE_2D, m_tex);

		int filter_min, filter_mag;


		filter_min = (bMipMaps) ? GL_NEAREST_MIPMAP_NEAREST : GL_NEAREST;
		filter_mag = GL_NEAREST;

		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
			filter_min);

		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
			filter_mag);

		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,
			(bRepeat) ? GL_REPEAT : GL_CLAMP);

		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,
			(bRepeat) ? GL_REPEAT : GL_CLAMP);

		if(bMipMaps)
		{
			gluBuild2DMipmaps(GL_TEXTURE_2D, type, pTexSurface->w, pTexSurface->h,
				type, GL_UNSIGNED_BYTE, pData);
		}else
		{
			glTexImage2D(GL_TEXTURE_2D, 0, type, pTexSurface->w,
				pTexSurface->h, 0, type, GL_UNSIGNED_BYTE, pData);
		}

		//now that we are finished, do some garbage collection
		//clean up our array and destroy the surface you loaded
		delete [] pData;
		SDL_FreeSurface( pTexSurface );

		//return the texture handle
		return true;
	}

	/*
	* Return the pixel value at (x, y)
	* NOTE: The surface must be locked before calling this!
	* Taken from SDL documentation.
	*/
	Uint32 SceneTexture::getPixel(SDL_Surface *surface, int x, int y)
	{
		int bpp = surface->format->BytesPerPixel;
		/* Here p is the address to the pixel we want to retrieve */
		Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * bpp;

		switch(bpp) {
		case 1:
			return *p;

		case 2:
			return *(Uint16 *)p;

		case 3:
			if(SDL_BYTEORDER == SDL_BIG_ENDIAN)
				return p[0] << 16 | p[1] << 8 | p[2];
			else
				return p[0] | p[1] << 8 | p[2] << 16;

		case 4:
			return *(Uint32 *)p;

		default:
			return 0;       /* shouldn't happen, but avoids warnings */
		}
	}

hth,
Erik Yuzwa
http://www.wazooinc.com

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






More information about the SDL mailing list