• 10
• 9
• 13
• 10
• 18

OpenGL and BMfont (released!)

This topic is 4366 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

Recommended Posts

Edit: the post has been replaced with the below link to the solution of the problem (e.g. an OpenGL BMfont implementation) oglBMfont on sourceforge.net Download the source and fit it to your own use! [Edited by - legolas558 on April 6, 2006 1:51:52 PM]

Share on other sites
I'm not sure what you're trying to acomplish, building a display list with all the characters doesn't make much sense to me. But then again, I do not know much about OpenGL. I think what you really need to do, is to create a display list for the text string you intend to print on the screen instead.

Anyway, it seems that you have misunderstood the meaning of x_advance. This should be used to update the cursor position after printing the character, it doesn't affect the position of the current character.

You may also want to use the kerning info, which for some fonts make a big difference. These values define an adjusted position of the characters for certain character pairs, e.g. 'i' and 'l' may need to be closer to each other than x_advance specify.

Regards,
Andreas

Share on other sites
As I said, I don't know OpenGL very well. If glCallList() can use the display list to get the quad that needs to be drawn and then position it correctly on the screen, then that sounds like a good idea. [smile]

The x,y, and offsets are correct. It's only the x_advance that was wrong. The tutorial does it correctly, as far as I can see.

Also that tutorial doesn't show you how to use the kerning information. Take a look at the other tutorial for that information.

About the image: Perhaps the texture is upside down? TGA files allow to specify the orientation of the textures, this could be the cause of the 'modern art'.

Regards,
Andreas

Share on other sites
Are you parsing the font file using boost::regex? No? Why not?

Share on other sites
Quote:
 Original post by DeyjaAre you parsing the font file using boost::regex? No? Why not?

Because I have done it without. And without I don't have to include boost::regex.

Share on other sites
But boost makes the code SO AWESOME.

Probably won't make much sense out of context, but...

#pragma warning(disable:4786)#include "font.h"#include <boost/regex.hpp>#include "vfs.h"#include <boost/lexical_cast.hpp>#include "log.h"#include "sdl/sdl.h"/* Regex's used for parsing font file. */namespace{boost::regex Common("^common\\s+lineHeight=(\\d+)\\s+base=(\\d+)\\s+scaleW=(\\d+)\\s+scaleH=(\\d+)\\s+pages=(\\d+)\\s*$"); boost::regex Entry("^char\\s+id=(\\d+)\\s+x=(\\d+)\\s+y=(\\d+)\\s+width=(\\d+)\\s+height=(\\d+)\\s+xoffset=(-?\\d+)\\s+yoffset=(-?\\d+)\\s+xadvance=(\\d+)\\s+page=(\\d+)\\s*$"); std::string group(boost::match_results<std::string::const_iterator>& what, int index)	{		return std::string(what[index].first,what[index].second);	}};void Graphics::Font::Load(const std::string& filename){	pimple = boost::shared_ptr<FontImple>(new FontImple());	std::vector<std::string> v_lines;	{		System::File f(filename, System::File::READ | System::File::TEXT);		f.readAll(v_lines);	}		if (v_lines.size() < 1) 	{		System::log << "Error loading font " << filename << ": Empty file?\n";		return;	}	boost::match_results<std::string::const_iterator> what; 	if (!boost::regex_match(v_lines[0],what,Common)) 	{		System::log << "Error loading font " << filename << ": Error in header.\n";		return;	}		pimple->lineHeight = boost::lexical_cast<int>(group(what,1));	pimple->base = boost::lexical_cast<int>(group(what,2));	pimple->scale_width = boost::lexical_cast<int>(group(what,3));	pimple->scale_height = boost::lexical_cast<int>(group(what,4));	unsigned int nPages = boost::lexical_cast<int>(group(what,5));		for (unsigned int i = 0; i < nPages; ++i)	{		std::string t_fname = filename+"_";		if (i < 10) t_fname += "0";		t_fname += boost::lexical_cast<std::string>(i);		t_fname += ".tga";		pimple->pages.push_back(load_image(t_fname));	}		std::vector<std::string>::iterator line = v_lines.begin();	++line;	for (; line != v_lines.end(); ++line)	{		FontImple::CharInfo CI;		if (!boost::regex_match(*line,what,Entry)) {			System::log << "Error loading font " << filename << ": Line format mismatch.\n";			return;		}		unsigned int ID = boost::lexical_cast<int>(group(what,1));		pimple->chars[ID].x = boost::lexical_cast<int>(group(what,2));		pimple->chars[ID].y = boost::lexical_cast<int>(group(what,3));		pimple->chars[ID].width = boost::lexical_cast<int>(group(what,4));		pimple->chars[ID].height = boost::lexical_cast<int>(group(what,5));		pimple->chars[ID].x_offset = boost::lexical_cast<int>(group(what,6));		pimple->chars[ID].y_offset = boost::lexical_cast<int>(group(what,7));		pimple->chars[ID].x_advance = boost::lexical_cast<int>(group(what,8));		pimple->chars[ID].page = boost::lexical_cast<int>(group(what,9));	}	System::log << "Loaded font " << filename << ".\n";}void Graphics::Font::Draw(		const std::string& text, 		int x, int y,		Graphics::Surface surface){	if (!pimple) 	{		System::log << "Drawing with invalid font.\n";		return;	}	int LX = 0;	SDL_Rect source, dest;	for (unsigned int I = 0; I < text.size(); ++I)	{		if (text >= 256) continue;				FontImple::CharInfo CI = pimple->chars[text];		if (CI.page >= pimple->pages.size()) continue;		dest.x = x + (LX+CI.x_offset);		dest.y = y + (CI.y_offset);		dest.w = CI.width;		dest.h = CI.height;		source.x = CI.x;		source.y = CI.y;		source.w = CI.width;		source.h = CI.height;		SDL_BlitSurface(pimple->pages[CI.page].get(),&source,surface.get(),&dest);		LX += CI.x_advance;	}}