Exemple #1
0
        // Create a display list coresponding to the give character.
        // return character width
        private int make_dlist(Face face, uint ch, uint list_base, uint[] tex_base)
        {
            int charWidth = 0;

            //The first thing we do is get FreeType to render our character
            //into a bitmap.  This actually requires a couple of FreeType commands:

            //Load the Glyph for our character.
            face.LoadGlyph(face.GetCharIndex(ch), LoadFlags.Default, LoadTarget.Normal);

            //Move the face's glyph into a Glyph object.
            Glyph glyph = face.Glyph.GetGlyph();

            //Convert the glyph to a bitmap.
            glyph.ToBitmap(RenderMode.Normal, new FTVector26Dot6(0, 0), true);
            BitmapGlyph bitmap_glyph = glyph.ToBitmapGlyph();

            //This reference will make accessing the bitmap easier
            FTBitmap bitmap = bitmap_glyph.Bitmap;

            //Use our helper function to get the widths of
            //the bitmap data that we will need in order to create
            //our texture.
            int width  = next_p2(bitmap.Width);
            int height = next_p2(bitmap.Rows);

            //Allocate memory for the texture data.
            byte[] expanded_data = new byte[2 * width * height];

            //Here we fill in the data for the expanded bitmap.
            //Notice that we are using two channel bitmap (one for
            //luminocity and one for alpha), but we assign
            //both luminocity and alpha to the value that we
            //find in the FreeType bitmap.
            //We use the ?: operator so that value which we use
            //will be 0 if we are in the padding zone, and whatever
            //is the the Freetype bitmap otherwise.
            for (int j = 0; j < height; j++)
            {
                for (int i = 0; i < width; i++)
                {
                    expanded_data[2 * (i + j * width)] = 255;

                    if (i >= bitmap.Width || j >= bitmap.Rows)
                    {
                        expanded_data[2 * (i + j * width) + 1] = 0;
                    }
                    else
                    {
                        expanded_data[2 * (i + j * width) + 1] = bitmap.BufferData[i + bitmap.Width * j];
                    }
                }
            }

            //Now we just setup some texture paramaters.
            glView.glBindTexture2D(tex_base[ch]);
            glView.glTex2DParameterMinFilterLinear();
            glView.glTex2DParameterMagFilterLinear();

            //Here we actually create the texture itself, notice
            //that we are using GL_LUMINANCE_ALPHA to indicate that
            //we are using 2 channel data.
            glView.glTexImage2D_IntFormatRGBA_formatLumAlpha_bytes(width, height, expanded_data);

            //So now we can create the display list
            glView.glNewListCompile(list_base + ch);
            glView.glBindTexture2D(tex_base[ch]);

            glView.glPushMatrix();                                // better results with popping the matrix here..

            //first we need to move over a little so that
            //the character has the right amount of space
            //between it and the one before it.
            glView.glTranslate((float)bitmap_glyph.Left, 0f, 0f);

            //Now we move down a little in the case that the
            //bitmap extends past the bottom of the line
            //(this is only true for characters like 'g' or 'y'.
            //GL.PushMatrix();                              // better results without popping the matrix before top translation
            int topOffset = bitmap_glyph.Top - bitmap.Rows;

            glView.glTranslate(0f, (float)topOffset, 0f);
            //glTranslatef(0, (GLfloat)bitmap_glyph->top-bitmap.rows, 0);

            //Now we need to account for the fact that many of
            //our textures are filled with empty padding space.
            //We figure what portion of the texture is used by
            //the actual character and store that information in
            //the x and y variables, then when we draw the
            //quad, we will only reference the parts of the texture
            //that we contain the character itself.
            float x = (float)bitmap.Width / (float)width,
                  y = (float)bitmap.Rows / (float)height;

            //Here we draw the texturemaped quads.
            //The bitmap that we got from FreeType was not
            //oriented quite like we would like it to be,
            //so we need to link the texture to the quad
            //so that the result will be properly aligned.
            glView.glBeginQuads();
            glView.glTexCoord2(0, 0); glView.glVertex2(0f, (float)bitmap.Rows);
            glView.glTexCoord2(0, y); glView.glVertex2(0f, 0f);
            glView.glTexCoord2(x, y); glView.glVertex2((float)bitmap.Width, 0);
            glView.glTexCoord2(x, 0); glView.glVertex2((float)bitmap.Width, (float)bitmap.Rows);
            glView.glEnd();
            glView.glPopMatrix();
            glView.glTranslate((float)(face.Glyph.Advance.X), 0f, 0f);

            // set the char width
            charWidth = (int)face.Glyph.Advance.X;

            //Finish the display list
            glView.glEndList();

            // free the glyph memory (bugfix)
            bitmap.Dispose();
            bitmap_glyph.Dispose();
            glyph.Dispose();

            // return the character width
            return(charWidth);
        }