OpenGL and BMfont (released!)

Started by
5 comments, last by legolas558 18 years ago
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]
Advertisement
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

AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game

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

AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game

Are you parsing the font file using boost::regex? No? Why not?
Quote:Original post by Deyja
Are 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.
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;	}}
Maybe nicer to look, but it is AGES slower.
I have released the whole C source, and it doesn't need other stuff more than what is provided.

This topic is closed to new replies.

Advertisement