how to copy bitmap to texture?

Problems building or running the engine, queries about how to use features etc.
Post Reply
yaxinhoo
Gremlin
Posts: 173
Joined: Sun Jun 06, 2010 4:34 pm

how to copy bitmap to texture?

Post by yaxinhoo »

i don't understand the code, why copy bitmap to texture do like this ? it only work on window opengl. but i can't work on iphone gles/gles2. when it work on gles , the font is rendered as color rectangle block.

what is difference of copy bitmap to texture between opengl and gles1/gles2 ?

Code: Select all

bool FontFaceLayer::GenerateTexture(const byte*& texture_data, Vector2i& texture_dimensions, int texture_id)
.....
// Copy the glyph's bitmap data into its allocated texture.
         if (glyph.bitmap_data != NULL)
         {
            byte* destination = rectangle.GetTextureData();
            byte* source = glyph.bitmap_data;
                for (int j = 0; j < glyph.bitmap_dimensions.y; ++j)
            {
               for (int k = 0; k < glyph.bitmap_dimensions.x; ++k)
                  destination[k * 4 + 3] = source[k];

               destination += rectangle.GetTextureStride();
                    len += rectangle.GetTextureStride();
                    source += glyph.bitmap_dimensions.x;
            }
                
                //memcpy(destination, glyph.bitmap_data, glyph.bitmap_dimensions.x*glyph.bitmap_dimensions.y);
         }
the code is from
http://www.ogre3d.org/forums/viewtopic.php?f=21&t=76125
User avatar
Kojack
OGRE Moderator
OGRE Moderator
Posts: 7157
Joined: Sun Jan 25, 2004 7:35 am
Location: Brisbane, Australia
x 534

Re: how to copy bitmap to texture?

Post by Kojack »

What pixel formats are the source and destination?
Those loops are counting up to the x and y dimensions and inside it's copying one byte from the source to the 4th byte+3 in the destination. That makes it look like it's copying a single channel (or indexed) source bitmap into one channel of a 32bit texture while leaving the others unset (could be red, blue or alpha depending on pixel format).

Mobiles tend to like 16 bit textures due to speed and less memory, so your texture might not be a 32 bit format. Or even if it's pixel format is 32 bit it might be different (ARGB, ABGR, RGBA, BGRA) so the data is going into the alpha channel instead of a colour.

Other than that I don't use opengl or gles so no idea.
Transporter
Minaton
Posts: 933
Joined: Mon Mar 05, 2012 11:37 am
Location: Germany
x 110

Re: how to copy bitmap to texture?

Post by Transporter »

I've created this function for ogre-procedural to draw a text on a texture.

Code: Select all

TextureBufferPtr TextTexture::process()
{
	FT_Library ftlib;
	FT_Face face;
	FT_GlyphSlot slot;

	FT_Error error = FT_Init_FreeType(&ftlib);
	if(error == 0)
	{
		error = FT_New_Face(ftlib, getFontFileByName().c_str(), 0, &face);
		if(error == FT_Err_Unknown_File_Format)
			logMsg("FreeType ERROR: FT_Err_Unknown_File_Format");
		else if(error)
			logMsg("FreeType ERROR: FT_New_Face - " + Ogre::StringConverter::toString(error));
		else
		{
			FT_Set_Pixel_Sizes(face, 0, mFontSize);
			
			size_t px = (size_t)mX;
			size_t py = (size_t)mY;
			slot = face->glyph;

			for(size_t n = 0; n < mText.length(); n++)
			{
				error = FT_Load_Char(face, mText[n], FT_LOAD_RENDER);
				if(error) continue;
				
				for(size_t i = 0; i < slot->bitmap.width; i++)
				{
					for(size_t j = 0; j < slot->bitmap.rows; j++)
					{
						if(slot->bitmap.buffer[j * slot->bitmap.width + i] > 127)
							mBuffer->setPixel(px + i, py + j, mColour);
					}
				}

				px += slot->advance.x >> 6;
				py += slot->advance.y >> 6;
			}
			FT_Done_Face(face);
			logMsg("Modify texture with text processing : " + mText);
		}
		FT_Done_FreeType(ftlib);
	}
	else
		logMsg("FreeType ERROR: FT_Init_FreeType");
	return mBuffer;
}
yaxinhoo
Gremlin
Posts: 173
Joined: Sun Jun 06, 2010 4:34 pm

Re: how to copy bitmap to texture?

Post by yaxinhoo »

thanks for you reply , transporter. i have one problem , why must greater than 127 ? what is the buffer default value?

Code: Select all

if(slot->bitmap.buffer[j * slot->bitmap.width + i] > 127)
                     mBuffer->setPixel(px + i, py + j, mColour);
Last edited by yaxinhoo on Sun Jan 27, 2013 9:25 pm, edited 1 time in total.
Transporter
Minaton
Posts: 933
Joined: Mon Mar 05, 2012 11:37 am
Location: Germany
x 110

Re: how to copy bitmap to texture?

Post by Transporter »

yaxinhoo wrote:thanks for you reply . transporter. i have one problem , why must greater than 127 ?

Code: Select all

if(slot->bitmap.buffer[j * slot->bitmap.width + i] > 127)
                     mBuffer->setPixel(px + i, py + j, mColour);
Freetype renders the glyphs to a 8 bit grayscale bitmap. I use this to create a monochrom typing. Source pixels with values below 127 are ignored. For source pixels above 127 I paint them with the given color in target texture buffer.
yaxinhoo
Gremlin
Posts: 173
Joined: Sun Jun 06, 2010 4:34 pm

Re: how to copy bitmap to texture?

Post by yaxinhoo »

thanks for you reply . i think i got it . i found i procces with columns , but u use rows . can i see you buffer class code ? cause i want to rebuild it . but i have some unclear point.
yaxinhoo
Gremlin
Posts: 173
Joined: Sun Jun 06, 2010 4:34 pm

Re: how to copy bitmap to texture?

Post by yaxinhoo »

to Kojack
Or even if it's pixel format is 32 bit it might be different (ARGB, ABGR, RGBA, BGRA)
the rocket guys say it is RGBA. but accroding to you say , why it copy the source to the destination's alpha channel only and it can work on windows?
User avatar
Kojack
OGRE Moderator
OGRE Moderator
Posts: 7157
Joined: Sun Jan 25, 2004 7:35 am
Location: Brisbane, Australia
x 534

Re: how to copy bitmap to texture?

Post by Kojack »

RGBA on a pc will be in little endian order, so the bytes in memory will go A,B,G,R (reversed order). Using k * 4 + 3 to copy rows of pixels means it's putting the font data into the red channel.
But iphone is big endian. RGBA will be stored in memory as R,G,B,A. Using the same k * 4 + 3 will put the data into the alpha channel instead.
Try changing the line:

Code: Select all

destination[k * 4 + 3] = source[k];
to:

Code: Select all

destination[k * 4] = source[k];
If my guess is right, then that will work on iphone but not pc.

But I don't use opengl or gles so I have no idea if there's an easy way to get both to work (besides using a #if to change the code when building).
It looks like in ogre on a little endian platform (pc) ARGB and ABGR use GL_UNSIGNED_BYTE which makes them work regardless of endianness, but RGBA and BGRA use GL_UNSIGNED_INT_8_8_8_8 which makes them sensitive to endianness. But on a big endian platform (arm based like iphone) it uses GL_UNSIGNED_INT_8_8_8_8_REV (reversed version) for ARGB and ABGR and GL_UNSIGNED_BYTE for RGBA and BGRA. Seems wrong, but I'm just guessing based on a stack exchange thread.
yaxinhoo
Gremlin
Posts: 173
Joined: Sun Jun 06, 2010 4:34 pm

Re: how to copy bitmap to texture?

Post by yaxinhoo »

thanks for you reply . i try k*4 , but the problem didn't miss.

the issue of librocket forum:
http://forums.librocket.com/viewtopic.php?f=6&t=965
Post Reply