post GLFT_Font integration, pre ResourceManagement revisions
This commit is contained in:
parent
fc6ce7335c
commit
5ca1c67cba
@ -5,7 +5,7 @@
|
|||||||
// James Turk (jpt2433@rit.edu)
|
// James Turk (jpt2433@rit.edu)
|
||||||
//
|
//
|
||||||
// Version:
|
// Version:
|
||||||
// $Id: Font.hpp,v 1.1 2005/06/29 04:30:40 cozman Exp $
|
// $Id: Font.hpp,v 1.2 2005/07/03 05:20:49 cozman Exp $
|
||||||
|
|
||||||
#ifndef PHOTON_VIDEO_FONT_HPP
|
#ifndef PHOTON_VIDEO_FONT_HPP
|
||||||
#define PHOTON_VIDEO_FONT_HPP
|
#define PHOTON_VIDEO_FONT_HPP
|
||||||
@ -18,6 +18,9 @@ namespace photon
|
|||||||
namespace video
|
namespace video
|
||||||
{
|
{
|
||||||
|
|
||||||
|
class StreamFlusher { };
|
||||||
|
std::ostream& operator<<(std::ostream& os, const StreamFlusher& rhs);
|
||||||
|
|
||||||
// Class: Font
|
// Class: Font
|
||||||
// Simple OO wrapper around a TrueType font that can be drawn to textures and
|
// Simple OO wrapper around a TrueType font that can be drawn to textures and
|
||||||
// rendered via OpenGL.
|
// rendered via OpenGL.
|
||||||
@ -32,10 +35,30 @@ namespace video
|
|||||||
class Font: public ResourceManaged<FontResourceManager>
|
class Font: public ResourceManaged<FontResourceManager>
|
||||||
{
|
{
|
||||||
|
|
||||||
|
// Resource Creation
|
||||||
|
public:
|
||||||
|
// Function: addResource
|
||||||
|
// Define a new named font resource, works just like
|
||||||
|
// <ResourceManaged::addResource> except that it takes a size for the font.
|
||||||
|
//
|
||||||
|
// Parameters:
|
||||||
|
// name - Name to give to font resource.
|
||||||
|
// path - Path of font file.
|
||||||
|
// size - Point size for the font.
|
||||||
|
static void addResource(const std::string& name, const std::string& path,
|
||||||
|
uint size);
|
||||||
|
|
||||||
|
// Function: addResource
|
||||||
|
// Define a new unaliased font resource (name == path). Works just like
|
||||||
|
// <ResourceManaged::addResource> except that it takes a size for the font.
|
||||||
|
//
|
||||||
|
// Parameters:.
|
||||||
|
// path - Path of font file.
|
||||||
|
// size - Point size for the font.
|
||||||
|
static void addResource(const std::string& path, uint size);
|
||||||
|
|
||||||
// Group: (Con/De)structors
|
// Group: (Con/De)structors
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
|
||||||
// Function: Font
|
// Function: Font
|
||||||
// Default constructor, initalizes internal state of Font.
|
// Default constructor, initalizes internal state of Font.
|
||||||
Font();
|
Font();
|
||||||
@ -63,21 +86,40 @@ public:
|
|||||||
// Function: open
|
// Function: open
|
||||||
// Opens an TrueType font.
|
// Opens an TrueType font.
|
||||||
//
|
//
|
||||||
// Loading is done via FTGL.
|
// Loading is done via FreeType.
|
||||||
//
|
//
|
||||||
// Parameters:
|
// Parameters:
|
||||||
// name - Name of the Font <Resource> to open.
|
// name - Name of the Font <Resource> to open.
|
||||||
void open(const std::string& name);
|
void open(const std::string& name);
|
||||||
|
|
||||||
|
bool isValid() const;
|
||||||
|
|
||||||
Font& operator=(const Font &rhs);
|
Font& operator=(const Font &rhs);
|
||||||
operator bool() const;
|
operator bool() const;
|
||||||
|
|
||||||
// Group: Writing
|
// Group: Drawing
|
||||||
public:
|
public:
|
||||||
void write(const std::string& str);
|
void drawText(float x, float y, const char *str, ...) const;
|
||||||
|
void drawText(float x, float y, const std::string& str) const;
|
||||||
|
|
||||||
|
std::ostream& beginDraw(float x, float y);
|
||||||
|
StreamFlusher endDraw();
|
||||||
|
|
||||||
|
// Group: Font Metrics
|
||||||
|
public:
|
||||||
|
unsigned int calcStringWidth(const std::string& str) const;
|
||||||
|
unsigned int getHeight() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
FTFont* font_;
|
// font data
|
||||||
|
uint texID_;
|
||||||
|
uint listBase_;
|
||||||
|
std::vector<ubyte> widths_;
|
||||||
|
ubyte height_;
|
||||||
|
// stream drawing stuff
|
||||||
|
std::ostringstream ss_;
|
||||||
|
float drawX_;
|
||||||
|
float drawY_;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -5,15 +5,15 @@
|
|||||||
// James Turk (jpt2433@rit.edu)
|
// James Turk (jpt2433@rit.edu)
|
||||||
//
|
//
|
||||||
// Version:
|
// Version:
|
||||||
// $Id: FontResourceManager.hpp,v 1.1 2005/06/29 04:30:40 cozman Exp $
|
// $Id: FontResourceManager.hpp,v 1.2 2005/07/03 05:20:49 cozman Exp $
|
||||||
|
|
||||||
#ifndef PHOTON_VIDEO_FONTRESOURCEMANAGER_HPP
|
#ifndef PHOTON_VIDEO_FONTRESOURCEMANAGER_HPP
|
||||||
#define PHOTON_VIDEO_FONTRESOURCEMANAGER_HPP
|
#define PHOTON_VIDEO_FONTRESOURCEMANAGER_HPP
|
||||||
|
|
||||||
#include "ResourceManager.hpp"
|
#include "ResourceManager.hpp"
|
||||||
|
|
||||||
#include "FTGL/FTGL.h"
|
#include <ft2build.h>
|
||||||
#include "FTGL/FTFont.h"
|
#include FT_FREETYPE_H
|
||||||
|
|
||||||
namespace photon
|
namespace photon
|
||||||
{
|
{
|
||||||
@ -23,17 +23,38 @@ namespace video
|
|||||||
class FontResource : public Resource
|
class FontResource : public Resource
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
FTFont* font;
|
uint texID;
|
||||||
|
uint listBase;
|
||||||
|
std::vector<ubyte> widths;
|
||||||
|
ubyte height;
|
||||||
};
|
};
|
||||||
|
|
||||||
class FontResourceManager : public ResourceManager<FontResource>
|
class FontResourceManager : public ResourceManager<FontResource>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
void getFontData(const std::string& name, FTFont*& font);
|
FontResourceManager();
|
||||||
|
~FontResourceManager();
|
||||||
|
|
||||||
|
void getFontData(const std::string& name, uint& texID, uint& listBase,
|
||||||
|
std::vector<ubyte>& widths, ubyte& height);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
// defined but not implemented
|
||||||
virtual void loadResource(FontResource &res, const std::string& name);
|
virtual void loadResource(FontResource &res, const std::string& name);
|
||||||
|
|
||||||
|
FontResource newResource(const std::string& name, const std::string& path,
|
||||||
|
uint size);
|
||||||
|
|
||||||
|
virtual void loadResource(FontResource &res, const std::string& name,
|
||||||
|
uint size);
|
||||||
virtual void freeResource(FontResource &res);
|
virtual void freeResource(FontResource &res);
|
||||||
|
|
||||||
|
private:
|
||||||
|
FT_Library library_;
|
||||||
|
public:
|
||||||
|
static const unsigned int SPACE = 32;
|
||||||
|
static const unsigned int NUM_CHARS = 96;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
// James Turk (jpt2433@rit.edu)
|
// James Turk (jpt2433@rit.edu)
|
||||||
//
|
//
|
||||||
// Version:
|
// Version:
|
||||||
// $Id: Texture.hpp,v 1.2 2005/06/13 07:05:28 cozman Exp $
|
// $Id: Texture.hpp,v 1.3 2005/07/03 05:20:49 cozman Exp $
|
||||||
|
|
||||||
#ifndef PHOTON_VIDEO_TEXTURE_HPP
|
#ifndef PHOTON_VIDEO_TEXTURE_HPP
|
||||||
#define PHOTON_VIDEO_TEXTURE_HPP
|
#define PHOTON_VIDEO_TEXTURE_HPP
|
||||||
@ -31,7 +31,7 @@ namespace video
|
|||||||
// - Texture = Texture
|
// - Texture = Texture
|
||||||
// - bool : True if texture is loaded, false if not.
|
// - bool : True if texture is loaded, false if not.
|
||||||
// - ostream& << Texture
|
// - ostream& << Texture
|
||||||
class Texture: public ResourceManaged<TextureResourceManager>
|
class Texture : public ResourceManaged<TextureResourceManager>
|
||||||
{
|
{
|
||||||
|
|
||||||
// Group: (Con/De)structors
|
// Group: (Con/De)structors
|
||||||
|
@ -5,26 +5,53 @@
|
|||||||
// James Turk (jpt2433@rit.edu)
|
// James Turk (jpt2433@rit.edu)
|
||||||
//
|
//
|
||||||
// Version:
|
// Version:
|
||||||
// $Id: Font.cpp,v 1.1 2005/06/29 04:30:40 cozman Exp $
|
// $Id: Font.cpp,v 1.2 2005/07/03 05:20:49 cozman Exp $
|
||||||
|
|
||||||
#include "video/Font.hpp"
|
#include "video/Font.hpp"
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
#include <stdexcept>
|
||||||
|
#include <cstdarg>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
namespace photon
|
namespace photon
|
||||||
{
|
{
|
||||||
namespace video
|
namespace video
|
||||||
{
|
{
|
||||||
|
|
||||||
Font::Font()
|
std::ostream& operator<<(std::ostream& os, const StreamFlusher& rhs)
|
||||||
{ }
|
|
||||||
|
|
||||||
Font::Font(const Font &rhs) :
|
|
||||||
ResourceManaged<FontResourceManager>(rhs)
|
|
||||||
{
|
{
|
||||||
resMgr_.getFontData(getName(), font_);
|
return os.flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
Font::Font(const std::string& name)
|
void Font::addResource(const std::string& name, const std::string& path,
|
||||||
|
uint size)
|
||||||
|
{
|
||||||
|
resMgr_.newResource(name,path,size);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Font::addResource(const std::string& path, uint size)
|
||||||
|
{
|
||||||
|
resMgr_.newResource(path,path,size);
|
||||||
|
}
|
||||||
|
|
||||||
|
Font::Font() :
|
||||||
|
texID_(0), listBase_(0), // initalize GL variables to zero
|
||||||
|
widths_(FontResourceManager::NUM_CHARS), // make room for 96 widths
|
||||||
|
height_(0), drawX_(0), drawY_(0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Font::Font(const Font &rhs) :
|
||||||
|
ResourceManaged<FontResourceManager>(rhs),
|
||||||
|
drawX_(0), drawY_(0)
|
||||||
|
{
|
||||||
|
resMgr_.getFontData(getName(), texID_, listBase_, widths_, height_);
|
||||||
|
}
|
||||||
|
|
||||||
|
Font::Font(const std::string& name) :
|
||||||
|
drawX_(0), drawY_(0)
|
||||||
{
|
{
|
||||||
open(name);
|
open(name);
|
||||||
}
|
}
|
||||||
@ -32,7 +59,12 @@ Font::Font(const std::string& name)
|
|||||||
void Font::open(const std::string& name)
|
void Font::open(const std::string& name)
|
||||||
{
|
{
|
||||||
ResourceManaged<FontResourceManager>::open(name);
|
ResourceManaged<FontResourceManager>::open(name);
|
||||||
resMgr_.getFontData(getName(), font_);
|
resMgr_.getFontData(getName(), texID_, listBase_, widths_, height_);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Font::isValid() const
|
||||||
|
{
|
||||||
|
return glIsTexture(texID_) == GL_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
Font& Font::operator=(const Font &rhs)
|
Font& Font::operator=(const Font &rhs)
|
||||||
@ -40,19 +72,124 @@ Font& Font::operator=(const Font &rhs)
|
|||||||
if(&rhs != this)
|
if(&rhs != this)
|
||||||
{
|
{
|
||||||
ResourceManaged<FontResourceManager>::operator=(rhs);
|
ResourceManaged<FontResourceManager>::operator=(rhs);
|
||||||
resMgr_.getFontData(getName(), font_);
|
resMgr_.getFontData(getName(), texID_, listBase_, widths_, height_);
|
||||||
}
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
Font::operator bool() const
|
Font::operator bool() const
|
||||||
{
|
{
|
||||||
return font_ != 0;
|
return isValid();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Font::write(const std::string& str)
|
void Font::drawText(float x, float y, const char *str, ...) const
|
||||||
{
|
{
|
||||||
font_->Render(str.c_str());
|
if(!isValid())
|
||||||
|
{
|
||||||
|
throw PreconditionException("Invalid Font::drawText call.");
|
||||||
|
}
|
||||||
|
|
||||||
|
std::va_list args;
|
||||||
|
char buf[1024];
|
||||||
|
|
||||||
|
va_start(args,str);
|
||||||
|
std::vsnprintf(buf, 1024, str, args); // avoid buffer overflow
|
||||||
|
va_end(args);
|
||||||
|
|
||||||
|
glBindTexture(GL_TEXTURE_2D, texID_);
|
||||||
|
glPushMatrix();
|
||||||
|
glTranslated(x,y,0);
|
||||||
|
for(unsigned int i=0; i < std::strlen(buf); ++i)
|
||||||
|
{
|
||||||
|
// ch-SPACE = DisplayList offset
|
||||||
|
unsigned char ch( buf[i] - FontResourceManager::SPACE );
|
||||||
|
// replace characters outside the valid range with undrawable
|
||||||
|
if(ch > FontResourceManager::NUM_CHARS)
|
||||||
|
{
|
||||||
|
// last character is 'undrawable'
|
||||||
|
ch = FontResourceManager::NUM_CHARS-1;
|
||||||
|
}
|
||||||
|
glCallList(listBase_+ch); // calculate list to call
|
||||||
|
}
|
||||||
|
|
||||||
|
// Alternative, ignores undrawables (no noticable speed difference)
|
||||||
|
//glListBase(listBase_-32);
|
||||||
|
//glCallLists(static_cast<int>(std::strlen(buf)), GL_UNSIGNED_BYTE, buf);
|
||||||
|
|
||||||
|
glPopMatrix();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Font::drawText(float x, float y, const std::string& str) const
|
||||||
|
{
|
||||||
|
if(!isValid())
|
||||||
|
{
|
||||||
|
throw PreconditionException("Invalid Font::drawText call.");
|
||||||
|
}
|
||||||
|
|
||||||
|
glBindTexture(GL_TEXTURE_2D, texID_);
|
||||||
|
glPushMatrix();
|
||||||
|
glTranslated(x,y,0);
|
||||||
|
for(std::string::const_iterator i = str.begin(); i != str.end(); ++i)
|
||||||
|
{
|
||||||
|
// ch-SPACE = DisplayList offset
|
||||||
|
unsigned char ch( *i - FontResourceManager::SPACE );
|
||||||
|
// replace characters outside the valid range with undrawable
|
||||||
|
if(ch > FontResourceManager::NUM_CHARS)
|
||||||
|
{
|
||||||
|
// last character is 'undrawable'
|
||||||
|
ch = FontResourceManager::NUM_CHARS-1;
|
||||||
|
}
|
||||||
|
glCallList(listBase_+ch); // calculate list to call
|
||||||
|
}
|
||||||
|
|
||||||
|
// Alternative, ignores undrawables (no noticable speed difference)
|
||||||
|
//glListBase(listBase_-32);
|
||||||
|
//glCallLists(static_cast<int>(std::strlen(buf)), GL_UNSIGNED_BYTE, buf);
|
||||||
|
|
||||||
|
glPopMatrix();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::ostream& Font::beginDraw(float x, float y)
|
||||||
|
{
|
||||||
|
// clear the string and store the draw-position
|
||||||
|
ss_.str("");
|
||||||
|
drawX_ = x;
|
||||||
|
drawY_ = y;
|
||||||
|
return ss_;
|
||||||
|
}
|
||||||
|
|
||||||
|
StreamFlusher Font::endDraw()
|
||||||
|
{
|
||||||
|
drawText(drawX_, drawY_, ss_.str()); // draw the string
|
||||||
|
ss_.str(""); // clear the buffer
|
||||||
|
return StreamFlusher();
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int Font::calcStringWidth(const std::string& str) const
|
||||||
|
{
|
||||||
|
if(!isValid())
|
||||||
|
{
|
||||||
|
throw PreconditionException("Invalid Font::calcStringWidth call.");
|
||||||
|
}
|
||||||
|
unsigned int width=0;
|
||||||
|
|
||||||
|
// iterate through widths of each char and accumulate width of string
|
||||||
|
for(std::string::const_iterator i = str.begin(); i < str.end(); ++i)
|
||||||
|
{
|
||||||
|
width += widths_[static_cast<unsigned int>(*i) -
|
||||||
|
FontResourceManager::SPACE];
|
||||||
|
}
|
||||||
|
|
||||||
|
return width;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int Font::getHeight() const
|
||||||
|
{
|
||||||
|
if(!isValid())
|
||||||
|
{
|
||||||
|
throw PreconditionException("Invalid Font::getHeight call.");
|
||||||
|
}
|
||||||
|
return height_;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -5,47 +5,227 @@
|
|||||||
// James Turk (jpt2433@rit.edu)
|
// James Turk (jpt2433@rit.edu)
|
||||||
//
|
//
|
||||||
// Version:
|
// Version:
|
||||||
// $Id: FontResourceManager.cpp,v 1.1 2005/06/29 04:30:40 cozman Exp $
|
// $Id: FontResourceManager.cpp,v 1.2 2005/07/03 05:20:49 cozman Exp $
|
||||||
|
|
||||||
#include "video/FontResourceManager.hpp"
|
#include "video/FontResourceManager.hpp"
|
||||||
|
|
||||||
#include "util/FileBuffer.hpp"
|
#include "util/FileBuffer.hpp"
|
||||||
|
|
||||||
#include "FTGL/FTGLTextureFont.h"
|
|
||||||
|
|
||||||
|
|
||||||
namespace photon
|
namespace photon
|
||||||
{
|
{
|
||||||
namespace video
|
namespace video
|
||||||
{
|
{
|
||||||
|
|
||||||
void FontResourceManager::getFontData(const std::string& name, FTFont*& font)
|
FontResourceManager::FontResourceManager()
|
||||||
|
{
|
||||||
|
if(FT_Init_FreeType(&library_) != 0)
|
||||||
|
{
|
||||||
|
throw APIError("Could not initialize FreeType2 library.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FontResourceManager::~FontResourceManager()
|
||||||
|
{
|
||||||
|
FT_Done_FreeType(library_);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FontResourceManager::getFontData(const std::string& name, uint& texID,
|
||||||
|
uint& listBase,
|
||||||
|
std::vector<ubyte>& widths,
|
||||||
|
ubyte& height)
|
||||||
{
|
{
|
||||||
FontResource resource( getResource(name) );
|
FontResource resource( getResource(name) );
|
||||||
font = resource.font;
|
texID = resource.texID;
|
||||||
|
listBase = resource.listBase;
|
||||||
|
widths = resource.widths;
|
||||||
|
height = resource.height;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FontResourceManager::loadResource(FontResource &res,
|
void FontResourceManager::loadResource(FontResource &res,
|
||||||
const std::string& path)
|
const std::string& path)
|
||||||
{
|
{
|
||||||
util::FileBuffer buf(path);
|
throw Error("loadResource(FontResource&, const std::string& is undefined "
|
||||||
|
" for Font. A size must be specified.");
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<ubyte> data = buf.getData();
|
FontResource FontResourceManager::newResource(const std::string& name,
|
||||||
|
const std::string& path,
|
||||||
|
uint size)
|
||||||
|
{
|
||||||
|
FontResource resource;
|
||||||
|
resource.name = name;
|
||||||
|
resource.path = path;
|
||||||
|
|
||||||
//res.font = new FTGLTextureFont((ubyte*)&data[0],data.size());
|
try
|
||||||
res.font = new FTGLTextureFont("/usr/share/fonts/truetype/freefont/FreeMono.ttf");
|
|
||||||
|
|
||||||
if(!res.font || res.font->Error() != 0)
|
|
||||||
{
|
{
|
||||||
throw APIError("Failed to create FTGLTextureFont");
|
// attempt to load
|
||||||
|
loadResource(resource, path, size);
|
||||||
|
}
|
||||||
|
catch(ResourceException& e)
|
||||||
|
{
|
||||||
|
// rethrow any exceptions with specific information
|
||||||
|
throw ResourceException("Could not load " + path + " as " + name +
|
||||||
|
": " + e.getDesc());
|
||||||
}
|
}
|
||||||
|
|
||||||
assert( res.font->FaceSize(6) );
|
resourceMap_[name] = resource; // add the resource to resourceMap
|
||||||
|
}
|
||||||
|
|
||||||
|
void FontResourceManager::loadResource(FontResource &res,
|
||||||
|
const std::string& path, uint size)
|
||||||
|
{
|
||||||
|
const size_t MARGIN = 3;
|
||||||
|
|
||||||
|
res.widths.resize(NUM_CHARS);
|
||||||
|
|
||||||
|
// Step 1: Open the font using FreeType //
|
||||||
|
util::FileBuffer buf(path);
|
||||||
|
std::vector<ubyte> data = buf.getData();
|
||||||
|
|
||||||
|
FT_Face face;
|
||||||
|
|
||||||
|
if(FT_New_Memory_Face(library_, (ubyte*)&data[0], data.size(), 0, &face)
|
||||||
|
!= 0)
|
||||||
|
{
|
||||||
|
throw APIError("Could not load font file.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Abort if this is not a scalable font.
|
||||||
|
if(!(face->face_flags & FT_FACE_FLAG_SCALABLE) ||
|
||||||
|
!(face->face_flags & FT_FACE_FLAG_HORIZONTAL))
|
||||||
|
{
|
||||||
|
throw ResourceException("Invalid font: Error setting font size.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the font size
|
||||||
|
FT_Set_Pixel_Sizes(face, size, 0);
|
||||||
|
|
||||||
|
// Step 2: Find maxAscent/Descent to calculate imageHeight //
|
||||||
|
size_t imageHeight = 0;
|
||||||
|
size_t imageWidth = 256;
|
||||||
|
int maxDescent = 0;
|
||||||
|
int maxAscent = 0;
|
||||||
|
size_t lineSpace = imageWidth - MARGIN;
|
||||||
|
size_t lines = 1;
|
||||||
|
size_t charIndex;
|
||||||
|
|
||||||
|
for(unsigned int ch = 0; ch < NUM_CHARS; ++ch)
|
||||||
|
{
|
||||||
|
// Look up the character in the font file.
|
||||||
|
charIndex = FT_Get_Char_Index(face, ch+SPACE);
|
||||||
|
|
||||||
|
// Render the current glyph.
|
||||||
|
FT_Load_Glyph(face, charIndex, FT_LOAD_RENDER);
|
||||||
|
|
||||||
|
res.widths[ch] = (face->glyph->metrics.horiAdvance >> 6) + MARGIN;
|
||||||
|
// If the line is full go to the next line
|
||||||
|
if(res.widths[ch] > lineSpace)
|
||||||
|
{
|
||||||
|
lineSpace = imageWidth - MARGIN;
|
||||||
|
++lines;
|
||||||
|
}
|
||||||
|
lineSpace -= res.widths[ch];
|
||||||
|
|
||||||
|
maxAscent = std::max(face->glyph->bitmap_top, maxAscent);
|
||||||
|
maxDescent = std::max(face->glyph->bitmap.rows -
|
||||||
|
face->glyph->bitmap_top, maxDescent);
|
||||||
|
}
|
||||||
|
|
||||||
|
res.height = maxAscent + maxDescent; // calculate height_ for text
|
||||||
|
|
||||||
|
// Compute how high the texture has to be.
|
||||||
|
size_t neededHeight = (maxAscent + maxDescent + MARGIN) * lines + MARGIN;
|
||||||
|
// Get the first power of two in which it will fit
|
||||||
|
imageHeight = 16;
|
||||||
|
while(imageHeight < neededHeight)
|
||||||
|
{
|
||||||
|
imageHeight <<= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Step 3: Generation of the actual texture //
|
||||||
|
|
||||||
|
// create and zero the memory
|
||||||
|
unsigned char* image = new unsigned char[imageHeight * imageWidth];
|
||||||
|
std::memset(image, 0, imageHeight * imageWidth);
|
||||||
|
|
||||||
|
// These are the position at which to draw the next glyph
|
||||||
|
size_t x = MARGIN;
|
||||||
|
size_t y = MARGIN + maxAscent;
|
||||||
|
float texX1, texX2, texY1, texY2; // used for display list
|
||||||
|
|
||||||
|
res.listBase = glGenLists(NUM_CHARS); // generate the lists for filling
|
||||||
|
|
||||||
|
// Drawing loop
|
||||||
|
for(unsigned int ch = 0; ch < NUM_CHARS; ++ch)
|
||||||
|
{
|
||||||
|
size_t charIndex = FT_Get_Char_Index(face, ch+SPACE);
|
||||||
|
|
||||||
|
// Render the glyph
|
||||||
|
FT_Load_Glyph(face, charIndex, FT_LOAD_DEFAULT);
|
||||||
|
FT_Render_Glyph(face->glyph, FT_RENDER_MODE_NORMAL);
|
||||||
|
|
||||||
|
// See whether the character fits on the current line
|
||||||
|
if(res.widths[ch] > imageWidth - x)
|
||||||
|
{
|
||||||
|
x = MARGIN;
|
||||||
|
y += (maxAscent + maxDescent + MARGIN);
|
||||||
|
}
|
||||||
|
|
||||||
|
// calculate texture coordinates of the character
|
||||||
|
texX1 = static_cast<float>(x) / imageWidth;
|
||||||
|
texX2 = static_cast<float>(x+res.widths[ch]) / imageWidth;
|
||||||
|
texY1 = static_cast<float>(y - maxAscent) / imageHeight;
|
||||||
|
texY2 = texY1 + static_cast<float>(res.height) / imageHeight;
|
||||||
|
|
||||||
|
// generate the character's display list
|
||||||
|
glNewList(res.listBase + ch, GL_COMPILE);
|
||||||
|
glBegin(GL_QUADS);
|
||||||
|
glTexCoord2f(texX1,texY1); glVertex2i(0, 0);
|
||||||
|
glTexCoord2f(texX2,texY1); glVertex2i(res.widths[ch], 0);
|
||||||
|
glTexCoord2f(texX2,texY2); glVertex2i(res.widths[ch], res.height);
|
||||||
|
glTexCoord2f(texX1,texY2); glVertex2i(0, res.height);
|
||||||
|
glEnd();
|
||||||
|
glTranslatef(res.widths[ch],0,0); // translate forward
|
||||||
|
glEndList();
|
||||||
|
|
||||||
|
// copy image generated by FreeType to the texture
|
||||||
|
for(int row = 0; row < face->glyph->bitmap.rows; ++row)
|
||||||
|
{
|
||||||
|
for(int pixel = 0; pixel < face->glyph->bitmap.width; ++pixel)
|
||||||
|
{
|
||||||
|
// set pixel at position to intensity (0-255) at the position
|
||||||
|
image[(x + face->glyph->bitmap_left + pixel) +
|
||||||
|
(y - face->glyph->bitmap_top + row) * imageWidth] =
|
||||||
|
face->glyph->bitmap.buffer[pixel +
|
||||||
|
row * face->glyph->bitmap.pitch];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
x += res.widths[ch];
|
||||||
|
}
|
||||||
|
|
||||||
|
// generate the OpenGL texture from the byte array
|
||||||
|
glGenTextures(1, &res.texID);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, res.texID);
|
||||||
|
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||||
|
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||||
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA8, imageWidth, imageHeight, 0,
|
||||||
|
GL_ALPHA, GL_UNSIGNED_BYTE, image);
|
||||||
|
|
||||||
|
delete[] image; // now done with the image memory
|
||||||
|
FT_Done_Face(face); // free the face data
|
||||||
}
|
}
|
||||||
|
|
||||||
void FontResourceManager::freeResource(FontResource &res)
|
void FontResourceManager::freeResource(FontResource &res)
|
||||||
{
|
{
|
||||||
delete res.font;
|
if(glIsList(res.listBase))
|
||||||
|
{
|
||||||
|
glDeleteLists(res.listBase, NUM_CHARS);
|
||||||
|
}
|
||||||
|
if(glIsTexture(res.texID))
|
||||||
|
{
|
||||||
|
glDeleteTextures(1, &res.texID);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
// James Turk (jpt2433@rit.edu)
|
// James Turk (jpt2433@rit.edu)
|
||||||
//
|
//
|
||||||
// Version:
|
// Version:
|
||||||
// $Id: VideoCore.cpp,v 1.6 2005/06/29 04:30:40 cozman Exp $
|
// $Id: VideoCore.cpp,v 1.7 2005/07/03 05:20:49 cozman Exp $
|
||||||
|
|
||||||
#include "video/VideoCore.hpp"
|
#include "video/VideoCore.hpp"
|
||||||
|
|
||||||
@ -13,7 +13,6 @@
|
|||||||
|
|
||||||
#include "GL/gl.h"
|
#include "GL/gl.h"
|
||||||
#include "GL/glu.h"
|
#include "GL/glu.h"
|
||||||
#include "FTGL/FTLibrary.h"
|
|
||||||
|
|
||||||
namespace photon
|
namespace photon
|
||||||
{
|
{
|
||||||
@ -25,7 +24,6 @@ VideoCore::VideoCore() :
|
|||||||
viewportWidth_(0), viewportHeight_(0)
|
viewportWidth_(0), viewportHeight_(0)
|
||||||
{
|
{
|
||||||
initOpenGL();
|
initOpenGL();
|
||||||
FTLibrary::Instance().Error(); // ignoring error, fix this
|
|
||||||
}
|
}
|
||||||
|
|
||||||
VideoCore::~VideoCore()
|
VideoCore::~VideoCore()
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
// James Turk (jpt2433@rit.edu)
|
// James Turk (jpt2433@rit.edu)
|
||||||
//
|
//
|
||||||
// Version:
|
// Version:
|
||||||
// $Id: Font_test.cpp,v 1.1 2005/06/29 04:30:40 cozman Exp $
|
// $Id: Font_test.cpp,v 1.2 2005/07/03 05:20:49 cozman Exp $
|
||||||
|
|
||||||
#include "photon.hpp"
|
#include "photon.hpp"
|
||||||
using namespace photon;
|
using namespace photon;
|
||||||
@ -48,17 +48,10 @@ public:
|
|||||||
|
|
||||||
video.clear();
|
video.clear();
|
||||||
|
|
||||||
glColor4ub(255,0,0,255);
|
font.drawText(0, 0, "Photon");
|
||||||
glEnable(GL_TEXTURE_2D);
|
font.drawText(font.calcStringWidth("Photon"), font.getHeight(),
|
||||||
glScaled(1.0/.75,1,1);
|
"FPS: %.0f", app.getFramerate() );
|
||||||
font.write("he");
|
font.beginDraw(200, 200) << "another font" << font.endDraw();
|
||||||
glBegin(GL_QUADS);
|
|
||||||
glTexCoord2f(0,0); glVertex2f(150,200);
|
|
||||||
glTexCoord2f(1,0); glVertex2f(300,350);
|
|
||||||
glTexCoord2f(1,1); glVertex2f(150,300);
|
|
||||||
glTexCoord2f(0,1); glVertex2f(200,350);
|
|
||||||
glEnd();
|
|
||||||
glColor4ub(255,255,255,255);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
Loading…
Reference in New Issue
Block a user