forked from dolphin-emu/dolphin
		
	
		
			
				
	
	
		
			284 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			284 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
// Copyright (C) 2003 Dolphin Project.
 | 
						|
 | 
						|
// This program is free software: you can redistribute it and/or modify
 | 
						|
// it under the terms of the GNU General Public License as published by
 | 
						|
// the Free Software Foundation, version 2.0.
 | 
						|
 | 
						|
// This program is distributed in the hope that it will be useful,
 | 
						|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
						|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
						|
// GNU General Public License 2.0 for more details.
 | 
						|
 | 
						|
// A copy of the GPL 2.0 should have been included with the program.
 | 
						|
// If not, see http://www.gnu.org/licenses/
 | 
						|
 | 
						|
// Official SVN repository and contact information can be found at
 | 
						|
// http://code.google.com/p/dolphin-emu/
 | 
						|
 | 
						|
#include "GLUtil.h"
 | 
						|
 | 
						|
#include "RasterFont.h"
 | 
						|
// globals
 | 
						|
 | 
						|
 | 
						|
static const u32 char_width = 8;
 | 
						|
static const u32 char_height = 13;
 | 
						|
static const u32 char_offset = 32;
 | 
						|
static const u32 char_count = 95;
 | 
						|
 | 
						|
const u8 rasters[char_count][char_height] = {
 | 
						|
    {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, 
 | 
						|
    {0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18}, 
 | 
						|
    {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x36, 0x36, 0x36}, 
 | 
						|
    {0x00, 0x00, 0x00, 0x66, 0x66, 0xff, 0x66, 0x66, 0xff, 0x66, 0x66, 0x00, 0x00}, 
 | 
						|
    {0x00, 0x00, 0x18, 0x7e, 0xff, 0x1b, 0x1f, 0x7e, 0xf8, 0xd8, 0xff, 0x7e, 0x18}, 
 | 
						|
    {0x00, 0x00, 0x0e, 0x1b, 0xdb, 0x6e, 0x30, 0x18, 0x0c, 0x76, 0xdb, 0xd8, 0x70}, 
 | 
						|
    {0x00, 0x00, 0x7f, 0xc6, 0xcf, 0xd8, 0x70, 0x70, 0xd8, 0xcc, 0xcc, 0x6c, 0x38}, 
 | 
						|
    {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x1c, 0x0c, 0x0e}, 
 | 
						|
    {0x00, 0x00, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x18, 0x0c}, 
 | 
						|
    {0x00, 0x00, 0x30, 0x18, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x18, 0x30}, 
 | 
						|
    {0x00, 0x00, 0x00, 0x00, 0x99, 0x5a, 0x3c, 0xff, 0x3c, 0x5a, 0x99, 0x00, 0x00}, 
 | 
						|
    {0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0xff, 0xff, 0x18, 0x18, 0x18, 0x00, 0x00}, 
 | 
						|
    {0x00, 0x00, 0x30, 0x18, 0x1c, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, 
 | 
						|
    {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00}, 
 | 
						|
    {0x00, 0x00, 0x00, 0x38, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, 
 | 
						|
    {0x00, 0x60, 0x60, 0x30, 0x30, 0x18, 0x18, 0x0c, 0x0c, 0x06, 0x06, 0x03, 0x03}, 
 | 
						|
    {0x00, 0x00, 0x3c, 0x66, 0xc3, 0xe3, 0xf3, 0xdb, 0xcf, 0xc7, 0xc3, 0x66, 0x3c}, 
 | 
						|
    {0x00, 0x00, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x78, 0x38, 0x18}, 
 | 
						|
    {0x00, 0x00, 0xff, 0xc0, 0xc0, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x03, 0xe7, 0x7e}, 
 | 
						|
    {0x00, 0x00, 0x7e, 0xe7, 0x03, 0x03, 0x07, 0x7e, 0x07, 0x03, 0x03, 0xe7, 0x7e}, 
 | 
						|
    {0x00, 0x00, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0xff, 0xcc, 0x6c, 0x3c, 0x1c, 0x0c}, 
 | 
						|
    {0x00, 0x00, 0x7e, 0xe7, 0x03, 0x03, 0x07, 0xfe, 0xc0, 0xc0, 0xc0, 0xc0, 0xff}, 
 | 
						|
    {0x00, 0x00, 0x7e, 0xe7, 0xc3, 0xc3, 0xc7, 0xfe, 0xc0, 0xc0, 0xc0, 0xe7, 0x7e}, 
 | 
						|
    {0x00, 0x00, 0x30, 0x30, 0x30, 0x30, 0x18, 0x0c, 0x06, 0x03, 0x03, 0x03, 0xff}, 
 | 
						|
    {0x00, 0x00, 0x7e, 0xe7, 0xc3, 0xc3, 0xe7, 0x7e, 0xe7, 0xc3, 0xc3, 0xe7, 0x7e}, 
 | 
						|
    {0x00, 0x00, 0x7e, 0xe7, 0x03, 0x03, 0x03, 0x7f, 0xe7, 0xc3, 0xc3, 0xe7, 0x7e}, 
 | 
						|
    {0x00, 0x00, 0x00, 0x38, 0x38, 0x00, 0x00, 0x38, 0x38, 0x00, 0x00, 0x00, 0x00}, 
 | 
						|
    {0x00, 0x00, 0x30, 0x18, 0x1c, 0x1c, 0x00, 0x00, 0x1c, 0x1c, 0x00, 0x00, 0x00}, 
 | 
						|
    {0x00, 0x00, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x60, 0x30, 0x18, 0x0c, 0x06}, 
 | 
						|
    {0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00}, 
 | 
						|
    {0x00, 0x00, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x03, 0x06, 0x0c, 0x18, 0x30, 0x60}, 
 | 
						|
    {0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x18, 0x0c, 0x06, 0x03, 0xc3, 0xc3, 0x7e}, 
 | 
						|
    {0x00, 0x00, 0x3f, 0x60, 0xcf, 0xdb, 0xd3, 0xdd, 0xc3, 0x7e, 0x00, 0x00, 0x00}, 
 | 
						|
    {0x00, 0x00, 0xc3, 0xc3, 0xc3, 0xc3, 0xff, 0xc3, 0xc3, 0xc3, 0x66, 0x3c, 0x18}, 
 | 
						|
    {0x00, 0x00, 0xfe, 0xc7, 0xc3, 0xc3, 0xc7, 0xfe, 0xc7, 0xc3, 0xc3, 0xc7, 0xfe}, 
 | 
						|
    {0x00, 0x00, 0x7e, 0xe7, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xe7, 0x7e}, 
 | 
						|
    {0x00, 0x00, 0xfc, 0xce, 0xc7, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc7, 0xce, 0xfc}, 
 | 
						|
    {0x00, 0x00, 0xff, 0xc0, 0xc0, 0xc0, 0xc0, 0xfc, 0xc0, 0xc0, 0xc0, 0xc0, 0xff}, 
 | 
						|
    {0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xfc, 0xc0, 0xc0, 0xc0, 0xff}, 
 | 
						|
    {0x00, 0x00, 0x7e, 0xe7, 0xc3, 0xc3, 0xcf, 0xc0, 0xc0, 0xc0, 0xc0, 0xe7, 0x7e}, 
 | 
						|
    {0x00, 0x00, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xff, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3}, 
 | 
						|
    {0x00, 0x00, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7e}, 
 | 
						|
    {0x00, 0x00, 0x7c, 0xee, 0xc6, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06}, 
 | 
						|
    {0x00, 0x00, 0xc3, 0xc6, 0xcc, 0xd8, 0xf0, 0xe0, 0xf0, 0xd8, 0xcc, 0xc6, 0xc3}, 
 | 
						|
    {0x00, 0x00, 0xff, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0}, 
 | 
						|
    {0x00, 0x00, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xdb, 0xff, 0xff, 0xe7, 0xc3}, 
 | 
						|
    {0x00, 0x00, 0xc7, 0xc7, 0xcf, 0xcf, 0xdf, 0xdb, 0xfb, 0xf3, 0xf3, 0xe3, 0xe3}, 
 | 
						|
    {0x00, 0x00, 0x7e, 0xe7, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xe7, 0x7e}, 
 | 
						|
    {0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xfe, 0xc7, 0xc3, 0xc3, 0xc7, 0xfe}, 
 | 
						|
    {0x00, 0x00, 0x3f, 0x6e, 0xdf, 0xdb, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0x66, 0x3c}, 
 | 
						|
    {0x00, 0x00, 0xc3, 0xc6, 0xcc, 0xd8, 0xf0, 0xfe, 0xc7, 0xc3, 0xc3, 0xc7, 0xfe}, 
 | 
						|
    {0x00, 0x00, 0x7e, 0xe7, 0x03, 0x03, 0x07, 0x7e, 0xe0, 0xc0, 0xc0, 0xe7, 0x7e}, 
 | 
						|
    {0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff}, 
 | 
						|
    {0x00, 0x00, 0x7e, 0xe7, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3}, 
 | 
						|
    {0x00, 0x00, 0x18, 0x3c, 0x3c, 0x66, 0x66, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3}, 
 | 
						|
    {0x00, 0x00, 0xc3, 0xe7, 0xff, 0xff, 0xdb, 0xdb, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3}, 
 | 
						|
    {0x00, 0x00, 0xc3, 0x66, 0x66, 0x3c, 0x3c, 0x18, 0x3c, 0x3c, 0x66, 0x66, 0xc3}, 
 | 
						|
    {0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x3c, 0x66, 0x66, 0xc3}, 
 | 
						|
    {0x00, 0x00, 0xff, 0xc0, 0xc0, 0x60, 0x30, 0x7e, 0x0c, 0x06, 0x03, 0x03, 0xff}, 
 | 
						|
    {0x00, 0x00, 0x3c, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x3c}, 
 | 
						|
    {0x00, 0x03, 0x03, 0x06, 0x06, 0x0c, 0x0c, 0x18, 0x18, 0x30, 0x30, 0x60, 0x60}, 
 | 
						|
    {0x00, 0x00, 0x3c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x3c}, 
 | 
						|
    {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0x66, 0x3c, 0x18}, 
 | 
						|
    {0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, 
 | 
						|
    {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x38, 0x30, 0x70}, 
 | 
						|
    {0x00, 0x00, 0x7f, 0xc3, 0xc3, 0x7f, 0x03, 0xc3, 0x7e, 0x00, 0x00, 0x00, 0x00}, 
 | 
						|
    {0x00, 0x00, 0xfe, 0xc3, 0xc3, 0xc3, 0xc3, 0xfe, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0}, 
 | 
						|
    {0x00, 0x00, 0x7e, 0xc3, 0xc0, 0xc0, 0xc0, 0xc3, 0x7e, 0x00, 0x00, 0x00, 0x00}, 
 | 
						|
    {0x00, 0x00, 0x7f, 0xc3, 0xc3, 0xc3, 0xc3, 0x7f, 0x03, 0x03, 0x03, 0x03, 0x03}, 
 | 
						|
    {0x00, 0x00, 0x7f, 0xc0, 0xc0, 0xfe, 0xc3, 0xc3, 0x7e, 0x00, 0x00, 0x00, 0x00}, 
 | 
						|
    {0x00, 0x00, 0x30, 0x30, 0x30, 0x30, 0x30, 0xfc, 0x30, 0x30, 0x30, 0x33, 0x1e}, 
 | 
						|
    {0x7e, 0xc3, 0x03, 0x03, 0x7f, 0xc3, 0xc3, 0xc3, 0x7e, 0x00, 0x00, 0x00, 0x00}, 
 | 
						|
    {0x00, 0x00, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xfe, 0xc0, 0xc0, 0xc0, 0xc0}, 
 | 
						|
    {0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x18, 0x00}, 
 | 
						|
    {0x38, 0x6c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x00, 0x00, 0x0c, 0x00}, 
 | 
						|
    {0x00, 0x00, 0xc6, 0xcc, 0xf8, 0xf0, 0xd8, 0xcc, 0xc6, 0xc0, 0xc0, 0xc0, 0xc0}, 
 | 
						|
    {0x00, 0x00, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x78}, 
 | 
						|
    {0x00, 0x00, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xfe, 0x00, 0x00, 0x00, 0x00}, 
 | 
						|
    {0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xfc, 0x00, 0x00, 0x00, 0x00}, 
 | 
						|
    {0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00}, 
 | 
						|
    {0xc0, 0xc0, 0xc0, 0xfe, 0xc3, 0xc3, 0xc3, 0xc3, 0xfe, 0x00, 0x00, 0x00, 0x00}, 
 | 
						|
    {0x03, 0x03, 0x03, 0x7f, 0xc3, 0xc3, 0xc3, 0xc3, 0x7f, 0x00, 0x00, 0x00, 0x00}, 
 | 
						|
    {0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xe0, 0xfe, 0x00, 0x00, 0x00, 0x00}, 
 | 
						|
    {0x00, 0x00, 0xfe, 0x03, 0x03, 0x7e, 0xc0, 0xc0, 0x7f, 0x00, 0x00, 0x00, 0x00}, 
 | 
						|
    {0x00, 0x00, 0x1c, 0x36, 0x30, 0x30, 0x30, 0x30, 0xfc, 0x30, 0x30, 0x30, 0x00}, 
 | 
						|
    {0x00, 0x00, 0x7e, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00}, 
 | 
						|
    {0x00, 0x00, 0x18, 0x3c, 0x3c, 0x66, 0x66, 0xc3, 0xc3, 0x00, 0x00, 0x00, 0x00}, 
 | 
						|
    {0x00, 0x00, 0xc3, 0xe7, 0xff, 0xdb, 0xc3, 0xc3, 0xc3, 0x00, 0x00, 0x00, 0x00}, 
 | 
						|
    {0x00, 0x00, 0xc3, 0x66, 0x3c, 0x18, 0x3c, 0x66, 0xc3, 0x00, 0x00, 0x00, 0x00}, 
 | 
						|
    {0xc0, 0x60, 0x60, 0x30, 0x18, 0x3c, 0x66, 0x66, 0xc3, 0x00, 0x00, 0x00, 0x00}, 
 | 
						|
    {0x00, 0x00, 0xff, 0x60, 0x30, 0x18, 0x0c, 0x06, 0xff, 0x00, 0x00, 0x00, 0x00}, 
 | 
						|
    {0x00, 0x00, 0x0f, 0x18, 0x18, 0x18, 0x38, 0xf0, 0x38, 0x18, 0x18, 0x18, 0x0f}, 
 | 
						|
    {0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18}, 
 | 
						|
    {0x00, 0x00, 0xf0, 0x18, 0x18, 0x18, 0x1c, 0x0f, 0x1c, 0x18, 0x18, 0x18, 0xf0}, 
 | 
						|
    {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x8f, 0xf1, 0x60, 0x00, 0x00, 0x00} 
 | 
						|
};
 | 
						|
 | 
						|
static const char *s_vertex_shader = 
 | 
						|
	"attribute vec2 vertexPosition;\n"
 | 
						|
	"attribute vec2 texturePosition;\n"
 | 
						|
	"varying vec2 tpos;\n"
 | 
						|
	"void main(void) {\n"
 | 
						|
	"	gl_Position = vec4(vertexPosition,0,1);\n"
 | 
						|
	"	tpos = texturePosition;\n"
 | 
						|
	"}\n"; 
 | 
						|
 | 
						|
static const char *s_fragment_shader =
 | 
						|
	"#extension GL_ARB_texture_rectangle : enable\n"
 | 
						|
	"uniform sampler2DRect textureSampler;\n"
 | 
						|
	"uniform vec4 color;\n"
 | 
						|
	"varying vec2 tpos;\n"
 | 
						|
	"void main(void) {\n"
 | 
						|
	"	gl_FragColor = texture2DRect(textureSampler,tpos) * color;\n"
 | 
						|
	"}\n";
 | 
						|
	
 | 
						|
RasterFont::RasterFont()
 | 
						|
{
 | 
						|
	// generate the texture
 | 
						|
	glGenTextures(1, &texture);
 | 
						|
	glBindTexture(GL_TEXTURE_RECTANGLE, texture);
 | 
						|
	u32* texture_data = new u32[char_width*char_count*char_height];
 | 
						|
	for(u32 y=0; y<char_height; y++) {
 | 
						|
		for(u32 c=0; c<char_count; c++) {
 | 
						|
			for(u32 x=0; x<char_width; x++) {
 | 
						|
				bool pixel = rasters[c][y] & (1<<(char_width-x-1));
 | 
						|
				texture_data[char_width*char_count*y+char_width*c+x] = pixel ? -1 : 0;
 | 
						|
			}
 | 
						|
		}
 | 
						|
	}
 | 
						|
	glTexImage2D(GL_TEXTURE_RECTANGLE, 0, GL_RGBA, char_width*char_count, char_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, texture_data);
 | 
						|
	delete [] texture_data;
 | 
						|
	
 | 
						|
	// generate shader
 | 
						|
	shader_program = OpenGL_CompileProgram(s_vertex_shader, s_fragment_shader);
 | 
						|
	
 | 
						|
	// bound uniforms
 | 
						|
	glUseProgram(shader_program);
 | 
						|
	glUniform1i(glGetUniformLocation(shader_program,"textureSampler"), 0); // GL_TEXTURE0
 | 
						|
	uniform_color_id = glGetUniformLocation(shader_program,"color");
 | 
						|
	glUniform4f(uniform_color_id, 1, 1, 1, 1);
 | 
						|
	cached_color = -1;
 | 
						|
	glUseProgram(0);
 | 
						|
	
 | 
						|
	// generate VBO & VAO
 | 
						|
	glGenBuffers(1, &VBO);
 | 
						|
	glGenVertexArrays(1, &VAO);
 | 
						|
	glBindBuffer(GL_ARRAY_BUFFER, VBO);
 | 
						|
	glBindVertexArray(VAO);
 | 
						|
	glEnableVertexAttribArray(glGetAttribLocation(shader_program, "vertexPosition"));
 | 
						|
	glVertexAttribPointer(glGetAttribLocation(shader_program, "vertexPosition"), 2, GL_FLOAT, 0, sizeof(GLfloat)*4, NULL);
 | 
						|
	glEnableVertexAttribArray(glGetAttribLocation(shader_program, "texturePosition"));
 | 
						|
	glVertexAttribPointer(glGetAttribLocation(shader_program, "texturePosition"), 2, GL_FLOAT, 0, sizeof(GLfloat)*4, (GLfloat*)NULL+2);
 | 
						|
	
 | 
						|
	// TODO: this after merging with graphic_update
 | 
						|
	glBindVertexArray(0);
 | 
						|
	glBindBuffer(GL_ARRAY_BUFFER, 0);
 | 
						|
}
 | 
						|
 | 
						|
RasterFont::~RasterFont()
 | 
						|
{
 | 
						|
	glDeleteTextures(1, &texture);
 | 
						|
	glDeleteBuffers(1, &VBO);
 | 
						|
	glDeleteVertexArrays(1, &VAO);
 | 
						|
	glDeleteProgram(shader_program);
 | 
						|
}
 | 
						|
 | 
						|
void RasterFont::printMultilineText(const char *text, double start_x, double start_y, double z, int bbWidth, int bbHeight, u32 color)
 | 
						|
{
 | 
						|
	int length = (int)strlen(text);
 | 
						|
	if (!length)
 | 
						|
		return; // nothing to do
 | 
						|
	
 | 
						|
	glBindVertexArray(VAO);
 | 
						|
	glBindBuffer(GL_ARRAY_BUFFER, VBO);
 | 
						|
	glBufferData(GL_ARRAY_BUFFER, length*4*6*sizeof(GLfloat), NULL, GL_STREAM_DRAW);
 | 
						|
	GLfloat *vertices = (GLfloat*)glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);
 | 
						|
	
 | 
						|
	int usage = 0;
 | 
						|
	GLfloat delta_x = 2*char_width/GLfloat(bbWidth);
 | 
						|
	GLfloat delta_y = 2*char_height/GLfloat(bbHeight);
 | 
						|
	GLfloat border_x = 1*2/GLfloat(bbWidth);
 | 
						|
	GLfloat border_y = 2*2/GLfloat(bbHeight);
 | 
						|
	
 | 
						|
	GLfloat x = start_x;
 | 
						|
	GLfloat y = start_y;
 | 
						|
	
 | 
						|
	for(int i=0; i<length; i++) {
 | 
						|
		u8 c = text[i];
 | 
						|
		
 | 
						|
		if(c == '\n') {
 | 
						|
			x = start_x;
 | 
						|
			y -= delta_y + border_y;
 | 
						|
			continue;
 | 
						|
		}
 | 
						|
		
 | 
						|
		// do not print spaces, they can be skipped easyly
 | 
						|
		if(c == ' ') {
 | 
						|
			x += delta_x + border_x;
 | 
						|
			continue;
 | 
						|
		}
 | 
						|
		
 | 
						|
		if(c < char_offset || c >= char_count+char_offset) continue;
 | 
						|
		
 | 
						|
		vertices[usage++] = x;
 | 
						|
		vertices[usage++] = y;
 | 
						|
		vertices[usage++] = (c-char_offset)*char_width;
 | 
						|
		vertices[usage++] = 0;
 | 
						|
		
 | 
						|
		vertices[usage++] = x+delta_x;
 | 
						|
		vertices[usage++] = y;
 | 
						|
		vertices[usage++] = (c-char_offset+1)*char_width;
 | 
						|
		vertices[usage++] = 0;
 | 
						|
		
 | 
						|
		vertices[usage++] = x+delta_x;
 | 
						|
		vertices[usage++] = y+delta_y;
 | 
						|
		vertices[usage++] = (c-char_offset+1)*char_width;
 | 
						|
		vertices[usage++] = char_height;
 | 
						|
		
 | 
						|
		vertices[usage++] = x;
 | 
						|
		vertices[usage++] = y;
 | 
						|
		vertices[usage++] = (c-char_offset)*char_width;
 | 
						|
		vertices[usage++] = 0;
 | 
						|
		
 | 
						|
		vertices[usage++] = x+delta_x;
 | 
						|
		vertices[usage++] = y+delta_y;
 | 
						|
		vertices[usage++] = (c-char_offset+1)*char_width;
 | 
						|
		vertices[usage++] = char_height;
 | 
						|
		
 | 
						|
		vertices[usage++] = x;
 | 
						|
		vertices[usage++] = y+delta_y;
 | 
						|
		vertices[usage++] = (c-char_offset)*char_width;
 | 
						|
		vertices[usage++] = char_height;
 | 
						|
		
 | 
						|
		x += delta_x + border_x;
 | 
						|
	}
 | 
						|
	glUnmapBuffer(GL_ARRAY_BUFFER);
 | 
						|
 | 
						|
	glUseProgram(shader_program);
 | 
						|
	
 | 
						|
	if(color != cached_color) {
 | 
						|
		glUniform4f(uniform_color_id, ((color>>16)&0xff)/255.f,((color>>8)&0xff)/255.f,((color>>0)&0xff)/255.f,((color>>24)&0xff)/255.f);
 | 
						|
		cached_color = color;
 | 
						|
	}
 | 
						|
	
 | 
						|
	glActiveTexture(GL_TEXTURE0);
 | 
						|
	glBindTexture(GL_TEXTURE_RECTANGLE, texture);
 | 
						|
	glDrawArrays(GL_TRIANGLES, 0, usage/4);
 | 
						|
	
 | 
						|
	// TODO: this after merging with graphic_update
 | 
						|
	glBindVertexArray(0);
 | 
						|
	glBindBuffer(GL_ARRAY_BUFFER, 0);
 | 
						|
	
 | 
						|
	glUseProgram(0);
 | 
						|
}
 |