[Change] Font work was becoming a little too large to sit in opengl specific code. Moved to font.*
This commit is contained in:
parent
74211a0825
commit
d66e1a52f9
318
src/font.c
Normal file
318
src/font.c
Normal file
@ -0,0 +1,318 @@
|
||||
#include "font.h"
|
||||
|
||||
#include "ft2build.h"
|
||||
#include "freetype/freetype.h"
|
||||
#include "freetype/ftglyph.h"
|
||||
|
||||
#include "main.h"
|
||||
#include "log.h"
|
||||
#include "pack.h"
|
||||
|
||||
#define FONT_DEF "../gfx/fonts/font.ttf"
|
||||
// Default font.
|
||||
glFont gl_defFont;
|
||||
|
||||
static void glFontMakeDList(FT_Face face, char ch,
|
||||
GLuint list_base, GLuint* tex_base, int* width_base);
|
||||
|
||||
static int pot(int n);
|
||||
|
||||
// Get the closest power of two.
|
||||
static int pot(int n) {
|
||||
int i = 1;
|
||||
while(i < n)
|
||||
i<<=1;
|
||||
return i;
|
||||
}
|
||||
|
||||
// Print text on screen! YES!!!! Just like printf! But different!
|
||||
// Defaults ft_font to gl_defFont if NULL.
|
||||
void gl_print(const glFont* ft_font, const double x, const double y,
|
||||
const glColour* c, const char* fmt, ...) {
|
||||
//float h = ft_font->h / .63; // Slightly increases font size.
|
||||
char text[256];
|
||||
va_list ap;
|
||||
|
||||
if(ft_font == NULL) ft_font = &gl_defFont;
|
||||
|
||||
if(fmt == NULL) return;
|
||||
else {
|
||||
// convert the symbols to text.
|
||||
va_start(ap, fmt);
|
||||
vsprintf(text, fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
|
||||
glListBase(ft_font->list_base);
|
||||
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPushMatrix(); // Translation matrix.
|
||||
glTranslated(x - (double)gl_screen.w/2., y - (double)gl_screen.h/2., 0);
|
||||
|
||||
if(c == NULL) glColor4d(1., 1., 1., 1.);
|
||||
else COLOUR(*c);
|
||||
glCallLists(strlen(text), GL_UNSIGNED_BYTE, &text);
|
||||
|
||||
glPopMatrix(); // Translation matrix.
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
}
|
||||
|
||||
// Acts just like gl_print, but prints to a max length of max.
|
||||
// Return the amount of characters we had to suppress.
|
||||
int gl_printMax(const glFont* ft_font, const int max, const double x, const double y,
|
||||
const glColour* c, const char* fmt, ...) {
|
||||
//float h = ft_font->h / .63; // Slightly increases font size.
|
||||
char text[256];
|
||||
va_list ap;
|
||||
int i, n, len, ret;
|
||||
|
||||
if(ft_font == NULL) ft_font = &gl_defFont;
|
||||
|
||||
if(fmt == NULL) return -1;
|
||||
else {
|
||||
// convert the symbols to text.
|
||||
va_start(ap, fmt);
|
||||
vsprintf(text, fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
// Limit the size.
|
||||
len = (int)strlen(text);
|
||||
for(n = 0, i = 0; i < len; i++) {
|
||||
n += ft_font->w[(int)text[i]];
|
||||
if(n > max) {
|
||||
ret = len - i; // Difference.
|
||||
text[i] = '\0';
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Display the text.
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
|
||||
glListBase(ft_font->list_base);
|
||||
|
||||
glMatrixMode(GL_MODELVIEW); // Projection gets full fast using modelview.
|
||||
glPushMatrix(); // Translation matrix.
|
||||
glTranslated(x - (double)gl_screen.w/2., y - (double)gl_screen.h/2., 0);
|
||||
|
||||
if(c == NULL) glColor4d(1., 1., 1., 1.);
|
||||
else COLOUR(*c);
|
||||
glCallLists(i, GL_UNSIGNED_BYTE, &text);
|
||||
|
||||
glPopMatrix(); // Translation matrix.
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Acts just like gl_printMax, but centers the text in the width.
|
||||
int gl_printMid(const glFont* ft_font, const int width, double x, const double y,
|
||||
const glColour* c, const char* fmt, ...) {
|
||||
//float h = ft_font->h / .63; // Slightly increases font size.
|
||||
char text[256];
|
||||
va_list ap;
|
||||
int i, n, len, ret;
|
||||
|
||||
ret = 0; // Default return value.
|
||||
|
||||
if(ft_font == NULL) ft_font = &gl_defFont;
|
||||
|
||||
if(fmt == NULL) return -1;
|
||||
else {
|
||||
// convert the symbols to text.
|
||||
va_start(ap, fmt);
|
||||
vsprintf(text, fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
// Limit the size.
|
||||
len = (int)strlen(text);
|
||||
for(n = 0, i = 0; i < len; i++) {
|
||||
n += ft_font->w[(int)text[i]];
|
||||
if(n > width) {
|
||||
ret = len - i; // Difference.
|
||||
n -= ft_font->w[(int)text[i]]; // Actual size.
|
||||
text[i] = '\0';
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
x += (double)(width-n)/2.;
|
||||
|
||||
// Display the text.
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
|
||||
glListBase(ft_font->list_base);
|
||||
|
||||
glMatrixMode(GL_MODELVIEW); // Projection gets full fast using modelview.
|
||||
glPushMatrix(); // Translation matrix.
|
||||
glTranslated(x - (double)gl_screen.w/2., y - (double)gl_screen.h/2., 0);
|
||||
|
||||
if(c == NULL) glColor4d(1., 1., 1., 1.);
|
||||
else COLOUR(*c);
|
||||
glCallLists(i, GL_UNSIGNED_BYTE, &text);
|
||||
|
||||
glPopMatrix(); // Translation matrix.
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
// Get the width of the text about to be printed.
|
||||
int gl_printWidth(const glFont* ft_font, const char* fmt, ...) {
|
||||
int i, n;
|
||||
char txt[256]; // Holds the string.
|
||||
va_list ap;
|
||||
|
||||
if(ft_font == NULL) ft_font = &gl_defFont;
|
||||
|
||||
if(fmt == NULL) return 0;
|
||||
else {
|
||||
// Convert the symbols to text.
|
||||
va_start(ap, fmt);
|
||||
vsprintf(txt, fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
for(n = 0, i = 0; i < (int)strlen(txt); i++)
|
||||
n += ft_font->w[(int)txt[i]];
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
// ================
|
||||
// FONT!
|
||||
// ================
|
||||
static void glFontMakeDList(FT_Face face, char ch, GLuint list_base, GLuint* tex_base, int* width_base) {
|
||||
FT_Glyph glyph;
|
||||
FT_Bitmap bitmap;
|
||||
GLubyte* expanded_data;
|
||||
int w, h;
|
||||
int i, j;
|
||||
|
||||
if(FT_Load_Glyph(face, FT_Get_Char_Index(face, ch), FT_LOAD_DEFAULT))
|
||||
WARN("FT_Load_Glyph failed");
|
||||
|
||||
if(FT_Get_Glyph(face->glyph, &glyph))
|
||||
WARN("FT_Ge_Glyph failed");
|
||||
|
||||
// Convert your glyph to a bitmap.
|
||||
FT_Glyph_To_Bitmap(&glyph, ft_render_mode_normal, 0, 1);
|
||||
FT_BitmapGlyph bitmap_glyph = (FT_BitmapGlyph)glyph;
|
||||
|
||||
bitmap = bitmap_glyph->bitmap; // To simplify.
|
||||
|
||||
// Need the POT wrapping for GL.
|
||||
w = pot(bitmap.width);
|
||||
h = pot(bitmap.rows);
|
||||
|
||||
// Memory for textured data.
|
||||
// Bitmap is useing two channels, one for luminosity and one for alpha.
|
||||
expanded_data = (GLubyte*)malloc(sizeof(GLubyte)*2*w*h);
|
||||
for(j = 0; j < h; j++) {
|
||||
for(i = 0; i < w; i++) {
|
||||
expanded_data[2*(i+j*w)] = expanded_data[2*(i+j*w)+1] =
|
||||
(i >= bitmap.width || j >= bitmap.rows) ? 0 : bitmap.buffer[i + bitmap.width*j];
|
||||
}
|
||||
}
|
||||
// Create the GL texture.
|
||||
glBindTexture(GL_TEXTURE_2D, tex_base[(int)ch]);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, expanded_data);
|
||||
|
||||
free(expanded_data); // No need for this now.
|
||||
|
||||
// Create the display lists.
|
||||
glNewList(list_base+ch, GL_COMPILE);
|
||||
|
||||
// Corrects a spacing flaw between letters and
|
||||
// downwards correction for letters like g or y.
|
||||
glPushMatrix();
|
||||
glTranslated(bitmap_glyph->left, bitmap_glyph->top-bitmap.rows, 0);
|
||||
|
||||
// Take the opengl POT wrapping into account.
|
||||
double x = (double)bitmap.width/(double)w;
|
||||
double y = (double)bitmap.rows/(double)h;
|
||||
|
||||
// Give the width a value.
|
||||
width_base[(int)ch] = bitmap.width;
|
||||
|
||||
// Draw the texture mapped quad.
|
||||
glBindTexture(GL_TEXTURE_2D, tex_base[(int)ch]);
|
||||
glBegin(GL_QUADS);
|
||||
glTexCoord2d(0, 0);
|
||||
glVertex2d(0, bitmap.rows);
|
||||
glTexCoord2d(x, 0);
|
||||
glVertex2d(bitmap.width, bitmap.rows);
|
||||
glTexCoord2d(x, y);
|
||||
glVertex2d(bitmap.width, 0);
|
||||
glTexCoord2d(0, y);
|
||||
glVertex2d(0, 0);
|
||||
glEnd();
|
||||
|
||||
glPopMatrix();
|
||||
glTranslated(face->glyph->advance.x >> 6, 0,0);
|
||||
|
||||
// End of the display list.
|
||||
glEndList();
|
||||
|
||||
FT_Done_Glyph(glyph);
|
||||
}
|
||||
|
||||
void glFontInit(glFont* font, const char* fname, const unsigned int h) {
|
||||
if(font == NULL) font = &gl_defFont;
|
||||
|
||||
uint32_t bufsize;
|
||||
FT_Byte* buf = pack_readfile(DATA, (fname) ? fname : FONT_DEF, &bufsize);
|
||||
|
||||
// Allocatagery.
|
||||
font->textures = malloc(sizeof(GLuint)*128);
|
||||
font->w = malloc(sizeof(int)*128);
|
||||
font->h = (int)h;
|
||||
if(font->textures == NULL || font->w == NULL) {
|
||||
WARN("Out of memory!");
|
||||
return;
|
||||
}
|
||||
|
||||
// Create a FreeType font library.
|
||||
FT_Library library;
|
||||
if(FT_Init_FreeType(&library)) {
|
||||
WARN("FT_Init_FreeType failed");
|
||||
}
|
||||
|
||||
// Objects that freetype uses to store font info.
|
||||
FT_Face face;
|
||||
if(FT_New_Memory_Face(library, buf, bufsize, 0, &face))
|
||||
WARN("FT_New_Memory_Face failed loading library from %s", fname);
|
||||
|
||||
// FreeType is pretty nice and measures using 1/64 of a pixel, therfore expand.
|
||||
FT_Set_Char_Size(face, h << 6, h << 6, 96, 96);
|
||||
|
||||
// Have OpenGL allocate space for the textures / display lists.
|
||||
font->list_base = glGenLists(128);
|
||||
glGenTextures(128, font->textures);
|
||||
|
||||
// Create each of the font display lists.
|
||||
unsigned char i;
|
||||
for(i = 0; i < 128; i++)
|
||||
glFontMakeDList(face, i, font->list_base, font->textures, font->w);
|
||||
|
||||
// We can now free the face and library.
|
||||
FT_Done_Face(face);
|
||||
FT_Done_FreeType(library);
|
||||
free(buf);
|
||||
}
|
||||
|
||||
void gl_freeFont(glFont* font) {
|
||||
if(font == NULL) font = &gl_defFont;
|
||||
glDeleteLists(font->list_base, 128);
|
||||
glDeleteTextures(128, font->textures);
|
||||
free(font->textures);
|
||||
free(font->w);
|
||||
}
|
||||
|
32
src/font.h
Normal file
32
src/font.h
Normal file
@ -0,0 +1,32 @@
|
||||
#pragma once
|
||||
#include "opengl.h"
|
||||
|
||||
// Font info.
|
||||
typedef struct {
|
||||
int h; // Height.
|
||||
int* w;
|
||||
GLuint* textures;
|
||||
GLuint list_base;
|
||||
} glFont;
|
||||
extern glFont gl_defFont; // Default font.
|
||||
|
||||
// glFont loading/freeing.
|
||||
// If font is NULL it uses the internal default font, same with gl_print
|
||||
void glFontInit(glFont* font, const char* fname, const unsigned int h);
|
||||
void gl_freeFont(glFont* font);
|
||||
|
||||
// Print text.
|
||||
void gl_print(const glFont* ft_font, const double x, const double y,
|
||||
const glColour* c, const char* fmt, ...);
|
||||
|
||||
// Print text to a max length.
|
||||
int gl_printMax(const glFont* ft_font, const int max, const double x, const double y,
|
||||
const glColour* c, const char* fmt, ...);
|
||||
|
||||
// Print text centered in width at x.
|
||||
int gl_printMid(const glFont* ft_font, const int width, double x, const double y,
|
||||
const glColour* c, const char* fmt, ...);
|
||||
|
||||
// Get the width of the text that you wish to print.
|
||||
int gl_printWidth(const glFont* ft_font, const char* fmt, ...);
|
||||
|
@ -6,6 +6,7 @@
|
||||
#include "log.h"
|
||||
#include "physics.h"
|
||||
#include "opengl.h"
|
||||
#include "font.h"
|
||||
#include "ship.h"
|
||||
#include "pilot.h"
|
||||
#include "player.h"
|
||||
|
302
src/opengl.c
302
src/opengl.c
@ -16,8 +16,6 @@
|
||||
#define SCREEN_W gl_screen.w
|
||||
#define SCREEN_H gl_screen.h
|
||||
|
||||
#define FONT_DEF "../gfx/fonts/font.ttf"
|
||||
|
||||
// offsets to Adjust the pilot's place onscreen to be in the middle, even with the GUI.
|
||||
extern double gui_xoff;
|
||||
extern double gui_yoff;
|
||||
@ -28,9 +26,6 @@ glInfo gl_screen;
|
||||
// Our precious camera.
|
||||
Vec2* gl_camera;
|
||||
|
||||
// Default font.
|
||||
glFont gl_defFont;
|
||||
|
||||
// Misc.
|
||||
static int SDL_VFlipSurface(SDL_Surface* surface);
|
||||
static int SDL_IsTrans(SDL_Surface* s, int x, int y);
|
||||
@ -38,8 +33,7 @@ static uint8_t* SDL_MapTrans(SDL_Surface* s);
|
||||
static int pot(int n);
|
||||
// glTexture.
|
||||
static GLuint gl_loadSurface(SDL_Surface* surface, int* rw, int* rh);
|
||||
// Gl font.
|
||||
static void glFontMakeDList(FT_Face face, char ch, GLuint list_base, GLuint* tex_base, int* width_base);
|
||||
|
||||
// PNG.
|
||||
int write_png(const char* file_name, png_bytep* rows, int w, int h, int colourtype, int bitdepth);
|
||||
|
||||
@ -47,7 +41,7 @@ int write_png(const char* file_name, png_bytep* rows, int w, int h, int colourty
|
||||
// MISC!
|
||||
// ================
|
||||
|
||||
// Get me the closest power of two plox.
|
||||
// Get the closest power of two.
|
||||
static int pot(int n) {
|
||||
int i = 1;
|
||||
while(i < n)
|
||||
@ -55,6 +49,7 @@ static int pot(int n) {
|
||||
return i;
|
||||
}
|
||||
|
||||
|
||||
// Flips the surface vertically. Return 0 on success.
|
||||
static int SDL_VFlipSurface(SDL_Surface* surface) {
|
||||
// Flip the image.
|
||||
@ -422,297 +417,6 @@ void gl_bindCamera(const Vec2* pos) {
|
||||
gl_camera = (Vec2*)pos;
|
||||
}
|
||||
|
||||
// Print text on screen! YES!!!! Just like printf! But different!
|
||||
// Defaults ft_font to gl_defFont if NULL.
|
||||
void gl_print(const glFont* ft_font, const double x, const double y,
|
||||
const glColour* c, const char* fmt, ...) {
|
||||
//float h = ft_font->h / .63; // Slightly increases font size.
|
||||
char text[256];
|
||||
va_list ap;
|
||||
|
||||
if(ft_font == NULL) ft_font = &gl_defFont;
|
||||
|
||||
if(fmt == NULL) return;
|
||||
else {
|
||||
// convert the symbols to text.
|
||||
va_start(ap, fmt);
|
||||
vsprintf(text, fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
|
||||
glListBase(ft_font->list_base);
|
||||
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPushMatrix(); // Translation matrix.
|
||||
glTranslated(x - (double)gl_screen.w/2., y - (double)gl_screen.h/2., 0);
|
||||
|
||||
if(c == NULL) glColor4d(1., 1., 1., 1.);
|
||||
else COLOUR(*c);
|
||||
glCallLists(strlen(text), GL_UNSIGNED_BYTE, &text);
|
||||
|
||||
glPopMatrix(); // Translation matrix.
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
}
|
||||
|
||||
// Acts just like gl_print, but prints to a max length of max.
|
||||
// Return the amount of characters we had to suppress.
|
||||
int gl_printMax(const glFont* ft_font, const int max, const double x, const double y,
|
||||
const glColour* c, const char* fmt, ...) {
|
||||
//float h = ft_font->h / .63; // Slightly increases font size.
|
||||
char text[256];
|
||||
va_list ap;
|
||||
int i, n, len, ret;
|
||||
|
||||
if(ft_font == NULL) ft_font = &gl_defFont;
|
||||
|
||||
if(fmt == NULL) return -1;
|
||||
else {
|
||||
// convert the symbols to text.
|
||||
va_start(ap, fmt);
|
||||
vsprintf(text, fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
// Limit the size.
|
||||
len = (int)strlen(text);
|
||||
for(n = 0, i = 0; i < len; i++) {
|
||||
n += ft_font->w[(int)text[i]];
|
||||
if(n > max) {
|
||||
ret = len - i; // Difference.
|
||||
text[i] = '\0';
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Display the text.
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
|
||||
glListBase(ft_font->list_base);
|
||||
|
||||
glMatrixMode(GL_MODELVIEW); // Projection gets full fast using modelview.
|
||||
glPushMatrix(); // Translation matrix.
|
||||
glTranslated(x - (double)gl_screen.w/2., y - (double)gl_screen.h/2., 0);
|
||||
|
||||
if(c == NULL) glColor4d(1., 1., 1., 1.);
|
||||
else COLOUR(*c);
|
||||
glCallLists(i, GL_UNSIGNED_BYTE, &text);
|
||||
|
||||
glPopMatrix(); // Translation matrix.
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Acts just like gl_printMax, but centers the text in the width.
|
||||
int gl_printMid(const glFont* ft_font, const int width, double x, const double y,
|
||||
const glColour* c, const char* fmt, ...) {
|
||||
//float h = ft_font->h / .63; // Slightly increases font size.
|
||||
char text[256];
|
||||
va_list ap;
|
||||
int i, n, len, ret;
|
||||
|
||||
ret = 0; // Default return value.
|
||||
|
||||
if(ft_font == NULL) ft_font = &gl_defFont;
|
||||
|
||||
if(fmt == NULL) return -1;
|
||||
else {
|
||||
// convert the symbols to text.
|
||||
va_start(ap, fmt);
|
||||
vsprintf(text, fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
// Limit the size.
|
||||
len = (int)strlen(text);
|
||||
for(n = 0, i = 0; i < len; i++) {
|
||||
n += ft_font->w[(int)text[i]];
|
||||
if(n > width) {
|
||||
ret = len - i; // Difference.
|
||||
n -= ft_font->w[(int)text[i]]; // Actual size.
|
||||
text[i] = '\0';
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
x += (double)(width-n)/2.;
|
||||
|
||||
// Display the text.
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
|
||||
glListBase(ft_font->list_base);
|
||||
|
||||
glMatrixMode(GL_MODELVIEW); // Projection gets full fast using modelview.
|
||||
glPushMatrix(); // Translation matrix.
|
||||
glTranslated(x - (double)gl_screen.w/2., y - (double)gl_screen.h/2., 0);
|
||||
|
||||
if(c == NULL) glColor4d(1., 1., 1., 1.);
|
||||
else COLOUR(*c);
|
||||
glCallLists(i, GL_UNSIGNED_BYTE, &text);
|
||||
|
||||
glPopMatrix(); // Translation matrix.
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
// Get the width of the text about to be printed.
|
||||
int gl_printWidth(const glFont* ft_font, const char* fmt, ...) {
|
||||
int i, n;
|
||||
char txt[256]; // Holds the string.
|
||||
va_list ap;
|
||||
|
||||
if(ft_font == NULL) ft_font = &gl_defFont;
|
||||
|
||||
if(fmt == NULL) return 0;
|
||||
else {
|
||||
// Convert the symbols to text.
|
||||
va_start(ap, fmt);
|
||||
vsprintf(txt, fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
for(n = 0, i = 0; i < (int)strlen(txt); i++)
|
||||
n += ft_font->w[(int)txt[i]];
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
// ================
|
||||
// FONT!
|
||||
// ================
|
||||
static void glFontMakeDList(FT_Face face, char ch, GLuint list_base, GLuint* tex_base, int* width_base) {
|
||||
FT_Glyph glyph;
|
||||
FT_Bitmap bitmap;
|
||||
GLubyte* expanded_data;
|
||||
int w, h;
|
||||
int i, j;
|
||||
|
||||
if(FT_Load_Glyph(face, FT_Get_Char_Index(face, ch), FT_LOAD_DEFAULT))
|
||||
WARN("FT_Load_Glyph failed");
|
||||
|
||||
if(FT_Get_Glyph(face->glyph, &glyph))
|
||||
WARN("FT_Ge_Glyph failed");
|
||||
|
||||
// Convert your glyph to a bitmap.
|
||||
FT_Glyph_To_Bitmap(&glyph, ft_render_mode_normal, 0, 1);
|
||||
FT_BitmapGlyph bitmap_glyph = (FT_BitmapGlyph)glyph;
|
||||
|
||||
bitmap = bitmap_glyph->bitmap; // To simplify.
|
||||
|
||||
// Need the POT wrapping for GL.
|
||||
w = pot(bitmap.width);
|
||||
h = pot(bitmap.rows);
|
||||
|
||||
// Memory for textured data.
|
||||
// Bitmap is useing two channels, one for luminosity and one for alpha.
|
||||
expanded_data = (GLubyte*)malloc(sizeof(GLubyte)*2*w*h);
|
||||
for(j = 0; j < h; j++) {
|
||||
for(i = 0; i < w; i++) {
|
||||
expanded_data[2*(i+j*w)] = expanded_data[2*(i+j*w)+1] =
|
||||
(i >= bitmap.width || j >= bitmap.rows) ? 0 : bitmap.buffer[i + bitmap.width*j];
|
||||
}
|
||||
}
|
||||
// Create the GL texture.
|
||||
glBindTexture(GL_TEXTURE_2D, tex_base[(int)ch]);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, expanded_data);
|
||||
|
||||
free(expanded_data); // No need for this now.
|
||||
|
||||
// Create the display lists.
|
||||
glNewList(list_base+ch, GL_COMPILE);
|
||||
|
||||
// Corrects a spacing flaw between letters and
|
||||
// downwards correction for letters like g or y.
|
||||
glPushMatrix();
|
||||
glTranslated(bitmap_glyph->left, bitmap_glyph->top-bitmap.rows, 0);
|
||||
|
||||
// Take the opengl POT wrapping into account.
|
||||
double x = (double)bitmap.width/(double)w;
|
||||
double y = (double)bitmap.rows/(double)h;
|
||||
|
||||
// Give the width a value.
|
||||
width_base[(int)ch] = bitmap.width;
|
||||
|
||||
// Draw the texture mapped quad.
|
||||
glBindTexture(GL_TEXTURE_2D, tex_base[(int)ch]);
|
||||
glBegin(GL_QUADS);
|
||||
glTexCoord2d(0, 0);
|
||||
glVertex2d(0, bitmap.rows);
|
||||
glTexCoord2d(x, 0);
|
||||
glVertex2d(bitmap.width, bitmap.rows);
|
||||
glTexCoord2d(x, y);
|
||||
glVertex2d(bitmap.width, 0);
|
||||
glTexCoord2d(0, y);
|
||||
glVertex2d(0, 0);
|
||||
glEnd();
|
||||
|
||||
glPopMatrix();
|
||||
glTranslated(face->glyph->advance.x >> 6, 0,0);
|
||||
|
||||
// End of the display list.
|
||||
glEndList();
|
||||
|
||||
FT_Done_Glyph(glyph);
|
||||
}
|
||||
|
||||
void glFontInit(glFont* font, const char* fname, const unsigned int h) {
|
||||
if(font == NULL) font = &gl_defFont;
|
||||
|
||||
uint32_t bufsize;
|
||||
FT_Byte* buf = pack_readfile(DATA, (fname) ? fname : FONT_DEF, &bufsize);
|
||||
|
||||
// Allocatagery.
|
||||
font->textures = malloc(sizeof(GLuint)*128);
|
||||
font->w = malloc(sizeof(int)*128);
|
||||
font->h = (int)h;
|
||||
if(font->textures == NULL || font->w == NULL) {
|
||||
WARN("Out of memory!");
|
||||
return;
|
||||
}
|
||||
|
||||
// Create a FreeType font library.
|
||||
FT_Library library;
|
||||
if(FT_Init_FreeType(&library)) {
|
||||
WARN("FT_Init_FreeType failed");
|
||||
}
|
||||
|
||||
// Objects that freetype uses to store font info.
|
||||
FT_Face face;
|
||||
if(FT_New_Memory_Face(library, buf, bufsize, 0, &face))
|
||||
WARN("FT_New_Memory_Face failed loading library from %s", fname);
|
||||
|
||||
// FreeType is pretty nice and measures using 1/64 of a pixel, therfore expand.
|
||||
FT_Set_Char_Size(face, h << 6, h << 6, 96, 96);
|
||||
|
||||
// Have OpenGL allocate space for the textures / display lists.
|
||||
font->list_base = glGenLists(128);
|
||||
glGenTextures(128, font->textures);
|
||||
|
||||
// Create each of the font display lists.
|
||||
unsigned char i;
|
||||
for(i = 0; i < 128; i++)
|
||||
glFontMakeDList(face, i, font->list_base, font->textures, font->w);
|
||||
|
||||
// We can now free the face and library.
|
||||
FT_Done_Face(face);
|
||||
FT_Done_FreeType(library);
|
||||
free(buf);
|
||||
}
|
||||
|
||||
void gl_freeFont(glFont* font) {
|
||||
if(font == NULL) font = &gl_defFont;
|
||||
glDeleteLists(font->list_base, 128);
|
||||
glDeleteTextures(128, font->textures);
|
||||
free(font->textures);
|
||||
free(font->w);
|
||||
}
|
||||
|
||||
// ================
|
||||
// GLOBAL.
|
||||
// ================
|
||||
|
29
src/opengl.h
29
src/opengl.h
@ -45,20 +45,6 @@ typedef struct {
|
||||
uint8_t* trans; // Maps the transparency.
|
||||
} glTexture;
|
||||
|
||||
// Font info.
|
||||
typedef struct {
|
||||
int h; // Height.
|
||||
int* w;
|
||||
GLuint* textures;
|
||||
GLuint list_base;
|
||||
} glFont;
|
||||
extern glFont gl_defFont; // Default font.
|
||||
|
||||
// glFont loading/freeing.
|
||||
// If font is NULL it uses the internal default font, same with gl_print
|
||||
void glFontInit(glFont* font, const char* fname, const unsigned int h);
|
||||
void gl_freeFont(glFont* font);
|
||||
|
||||
// gl_texute loading/freeing.
|
||||
glTexture* gl_loadImage(SDL_Surface* surface); // Frees the surface.
|
||||
glTexture* gl_newImage(const char* path);
|
||||
@ -77,21 +63,6 @@ void gl_blitStatic(const glTexture* texture, const double bx, const double by,
|
||||
// Bind the camera to a vector.
|
||||
void gl_bindCamera(const Vec2* pos);
|
||||
|
||||
// Print text.
|
||||
void gl_print(const glFont* ft_font, const double x, const double y,
|
||||
const glColour* c, const char* fmt, ...);
|
||||
|
||||
// Print text to a max length.
|
||||
int gl_printMax(const glFont* ft_font, const int max, const double x, const double y,
|
||||
const glColour* c, const char* fmt, ...);
|
||||
|
||||
// Print text centered in width at x.
|
||||
int gl_printMid(const glFont* ft_font, const int width, double x, const double y,
|
||||
const glColour* c, const char* fmt, ...);
|
||||
|
||||
// Get the width of the text that you wish to print.
|
||||
int gl_printWidth(const glFont* ft_font, const char* fmt, ...);
|
||||
|
||||
// Initialize/cleanup.
|
||||
int gl_init(void);
|
||||
void gl_exit(void);
|
||||
|
@ -4,6 +4,7 @@
|
||||
#include "pilot.h"
|
||||
#include "log.h"
|
||||
#include "opengl.h"
|
||||
#include "font.h"
|
||||
#include "pack.h"
|
||||
#include "xml.h"
|
||||
#include "space.h"
|
||||
|
@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
#include "opengl.h"
|
||||
#include "SDL.h"
|
||||
#include "opengl.h"
|
||||
#include "font.h"
|
||||
|
||||
extern int toolkit;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user