PDA

View Full Version : Text Glyphs Clipped



Psychofrantic
09-08-2011, 09:25 AM
Hi,

Now I'm a complete novice when it comes to OpenGL, and I fully intend to read up properly and run with some tutorials, but I just need to do something that's (hopefully) very simple in the meantime to make our flagship product ready for an up and coming demo at an exhibition next month. I'm on a really tight schedule, but I'll be exploring OpenGL properly once the exhibition is over.

I'm developing some C# software for a TFT elevator indicator which has an SBC running Windows CE. We have two Single Board Computers with different specs to run different sized displays, and the more powerful SBC has a better CPU and a GPU with OpenGL ES support. Up to now I've just been developing for the lower end SBC, and drawing to the screen using GDI. The GDI drawing does work fine on the large displays due to the additional CPU power behind it, but I'm wanting to have streaming video on the display, so I need to free up CPU usage. The video is running OK on the display, and it all works, but only if I disable the most CPU intensive GDI drawn element on the screen, which is a scrolling ticker of text.

Since I'm just trying to cobble something together quite quickly for this exhibition, I thought I'd just try and create a window with scrolling text using OpenGL ES. I'm using this C# wrapper:
http://www.koushikdutta.com/2008/08/net-compact-framework-wrapper-for.html


Now I've got a window with text on it, but for some reason when I start making the font large, the text is slightly cut off in places, with the cut off bits being rendered elsewhere, like this:

http://www.drucegrove.com/ticker_glyph_problem_01.png*

http://www.drucegrove.com/ticker_glyph_problem_02.png

My C# code for the setup routine is:



void InitOpenGLES()
{

try
{

myDisplay = egl.GetDisplay(new EGLNativeDisplayType(this));

int major, minor;
egl.Initialize(myDisplay, out major, out minor);

EGLConfig[] configs = new EGLConfig[10];
int[] attribList = new int[]
{
egl.EGL_RED_SIZE, 5,
egl.EGL_GREEN_SIZE, 6,
egl.EGL_BLUE_SIZE, 5,
egl.EGL_DEPTH_SIZE, 16 ,
egl.EGL_SURFACE_TYPE, egl.EGL_WINDOW_BIT,
egl.EGL_STENCIL_SIZE, egl.EGL_DONT_CARE,
egl.EGL_NONE, egl.EGL_NONE
};

int numConfig;
if (!egl.ChooseConfig(myDisplay, attribList, configs, configs.Length, out numConfig) || numConfig < 1)
throw new InvalidOperationException("Unable to choose config.");

EGLConfig config = configs[0];
mySurface = egl.CreateWindowSurface(myDisplay, config, Handle, null);
myContext = egl.CreateContext(myDisplay, config, EGLContext.None, null);

egl.MakeCurrent(myDisplay, mySurface, mySurface, myContext);
gl.ClearColor(0, 0, 0, 0);

gl.ShadeModel(gl.GL_SMOOTH);
gl.ClearColor(0.0f, 0.0f, 0.0f, 0.5f);
gl.ClearDepthf(1.0f);
gl.Enable(gl.GL_DEPTH_TEST);
gl.BlendFunc(gl.GL_SRC_ALPHA, gl.GL_ONE_MINUS_SRC_ALPHA);
gl.DepthFunc(gl.GL_LEQUAL);
gl.Enable(gl.GL_BLEND);
gl.Enable(gl.GL_LINE_SMOOTH);
gl.Hint(gl.GL_PERSPECTIVE_CORRECTION_HINT, gl.GL_NICEST);

OpenGLInitialised = true;

}
catch(Exception ex)
{
throw new Exception("InitOpenGLES Error: " + ex.Message);
}

}



My C# code for the drawing routine is like this:



void DrawOpenGLESText(ref string Text, ref OpenGLFont Font, float Scale, OpenGLTextAlignment TextAlignment, int TextX, int TextY, Size Size)
{
if (Text != null)
{

gl.MatrixMode(gl.GL_MODELVIEW);
gl.LoadIdentity(); //Reset the view to (0,0,0)

gl.DepthMask(gl.GL_FALSE); //Disable the depth mask to prevent characters from clipping

gl.Color4f(1.0f, 1.0f, 1.0f, 1.0f); //Set the RGBA colour to (1,1,1,1)

GlyphRun mTextGlyphs = new GlyphRun(Font, Text, Size, TextAlignment, false);
gl.Scalef(Scale, Scale, 0);
gl.Translatef(TextX, TextY, 0); // Move the view
mTextGlyphs.Draw();

gl.DepthMask(gl.GL_TRUE); //Re-enable the depth mask

gl.MatrixMode(gl.GL_MODELVIEW);
gl.LoadIdentity(); //Reset the view to (0,0,0)

}
}



And at the moment, I'm calling this routine to add some text to a collection that needs to be drawn:


void AddTextElement(string ElementName, ElementType Type, string FontFamily, int FontSize, bool FontBold, bool FontItalic, int Left, int Top, int Width, int Height, StringAlignment HorizontalAlignment, StringAlignment VerticalAlignment)
{

Program.ErrorLocation = "Add Text Element";

if (GetElementByName(ElementName) == null)
{
//Create the element
WindowElement mNewElement = new WindowElement();

//Update the basic element properties
mNewElement.Name = ElementName;
mNewElement.Type = Type;
mNewElement.Left = Left;
mNewElement.Top = Top;
mNewElement.Width = Width;
mNewElement.Height = Height;
mNewElement.FontFamily = FontFamily;
mNewElement.FontSize = FontSize;
mNewElement.FontBold = FontBold;
mNewElement.FontItalic = FontItalic;
mNewElement.FontSize = FontSize;
mNewElement.FontHorizontalAlign = HorizontalAlignment;
mNewElement.FontVerticalAlign = VerticalAlignment;

//Create the font
if (FontFamily.Length > 0)
{
LogFont mLogFont = new LogFont();
mLogFont.FaceName = FontFamily;
if (USE_OPENGLES &amp;&amp; FontSize > 250)
{
mLogFont.Height = (int)(-250);
mNewElement.FontScale = (float)(FontSize / 250.0F);
}else{
mLogFont.Height = (int)(-FontSize);
mNewElement.FontScale = 1.0F;
}
if (FontBold == true)
mLogFont.Weight = LogFontWeight.Bold;
else
mLogFont.Weight = LogFontWeight.Regular;
if (FontItalic == true)
mLogFont.Italic = 1;
else
mLogFont.Italic = 0;
mLogFont.Quality = LogFontQuality.AntiAliased;
mNewElement.Font = Font.FromLogFont(mLogFont);
}


//Create the string format
mNewElement.StringFormat = new StringFormat();
mNewElement.StringFormat.Alignment = HorizontalAlignment;
mNewElement.StringFormat.LineAlignment = VerticalAlignment;

//Create the OpenGLES objects
if (USE_OPENGLES)
{
mNewElement.OpenGLFont = new OpenGLFont(mNewElement.Font);
switch(HorizontalAlignment){
case StringAlignment.Near:
mNewElement.TextAlignment = OpenGLTextAlignment.Left;
break;
case StringAlignment.Center:
mNewElement.TextAlignment = OpenGLTextAlignment.Center;
break;
case StringAlignment.Far:
mNewElement.TextAlignment = OpenGLTextAlignment.Right;
break;
}
mNewElement.DrawX = (int)(mNewElement.Left / mNewElement.FontScale);
mNewElement.DrawY = (int)(mNewElement.Top / mNewElement.FontScale);
mNewElement.DrawSize = new Size((int)(Width / mNewElement.FontScale), (int)(Height / mNewElement.FontScale));

}

//Add the element to the element collection
mWindowElements.Add(mNewElement);
}

}



Which I'd call like this:


AddTextElement("My_Ticker_Text", ElementType.PlainText, "This is a ticker window...", "ARIAL NARROW", 80, true, true, 0, 0, 800, 80, mHorizontalStringAlignment, mVerticalStringAlignment);



Does anyone know why I'm getting these glitches on the text? I've been searching but cant find anything (although admittedly I dont know what to search for!). If I can correct this, I'm fairly sure that getting it to scroll will be simple enough, then I'm pretty much there!

Many thanks,
Rik

ZbuffeR
09-08-2011, 11:49 AM
Do you get the same glitches with non-italic text ?
It seems italics is not taken in account correctly.

Psychofrantic
09-09-2011, 02:12 AM
Ah, this is what happens when you rush I suppose... you miss the obvious clues! Yes, switching off italic seems to correct the issue for this font size. Thanks for the pointer!

I've also been playing about with some very large text (font height > 200), which isn't italic, but I noticed similar effects with that for certain characters.

I've looked more closely at the wrapper code for the OpenGLFont, and I see it's drawing characters onto a bitmap using .NET drawing routines before somehow converting them to textures. I'll see if I can modify the wrapper to sort this out...