forked from dolphin-emu/dolphin
		
	
		
			
				
	
	
		
			282 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			282 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
// Copyright 2008 Dolphin Emulator Project
 | 
						|
// Licensed under GPLv2+
 | 
						|
// Refer to the license.txt file included.
 | 
						|
 | 
						|
#include <vector>
 | 
						|
 | 
						|
#include "Common/Common.h"
 | 
						|
#include "Common/GL/GLUtil.h"
 | 
						|
 | 
						|
#include "VideoBackends/OGL/ProgramShaderCache.h"
 | 
						|
#include "VideoBackends/OGL/RasterFont.h"
 | 
						|
 | 
						|
// globals
 | 
						|
 | 
						|
namespace OGL
 | 
						|
{
 | 
						|
static const int CHAR_WIDTH = 8;
 | 
						|
static const int CHAR_HEIGHT = 13;
 | 
						|
static const int CHAR_OFFSET = 32;
 | 
						|
static const int CHAR_COUNT = 95;
 | 
						|
 | 
						|
static 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_vertexShaderSrc = "uniform vec2 charSize;\n"
 | 
						|
                                       "uniform vec2 offset;"
 | 
						|
                                       "in vec2 rawpos;\n"
 | 
						|
                                       "in vec2 tex0;\n"
 | 
						|
                                       "out vec2 uv0;\n"
 | 
						|
                                       "void main(void) {\n"
 | 
						|
                                       "	gl_Position = vec4(rawpos + offset,0,1);\n"
 | 
						|
                                       "	uv0 = tex0 * charSize;\n"
 | 
						|
                                       "}\n";
 | 
						|
 | 
						|
static const char* s_fragmentShaderSrc = "SAMPLER_BINDING(8) uniform sampler2D samp8;\n"
 | 
						|
                                         "uniform vec4 color;\n"
 | 
						|
                                         "in vec2 uv0;\n"
 | 
						|
                                         "out vec4 ocol0;\n"
 | 
						|
                                         "void main(void) {\n"
 | 
						|
                                         "	ocol0 = texture(samp8,uv0) * color;\n"
 | 
						|
                                         "}\n";
 | 
						|
 | 
						|
static SHADER s_shader;
 | 
						|
 | 
						|
RasterFont::RasterFont()
 | 
						|
{
 | 
						|
  // generate the texture
 | 
						|
  glGenTextures(1, &texture);
 | 
						|
  glActiveTexture(GL_TEXTURE8);
 | 
						|
  glBindTexture(GL_TEXTURE_2D, texture);
 | 
						|
  std::vector<u32> texture_data(CHAR_WIDTH * CHAR_COUNT * CHAR_HEIGHT);
 | 
						|
  for (int y = 0; y < CHAR_HEIGHT; y++)
 | 
						|
  {
 | 
						|
    for (int c = 0; c < CHAR_COUNT; c++)
 | 
						|
    {
 | 
						|
      for (int x = 0; x < CHAR_WIDTH; x++)
 | 
						|
      {
 | 
						|
        bool pixel = (0 != (rasters[c][y] & (1 << (CHAR_WIDTH - x - 1))));
 | 
						|
        texture_data[CHAR_WIDTH * CHAR_COUNT * y + CHAR_WIDTH * c + x] = pixel ? -1 : 0;
 | 
						|
      }
 | 
						|
    }
 | 
						|
  }
 | 
						|
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
 | 
						|
  glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, CHAR_WIDTH * CHAR_COUNT, CHAR_HEIGHT, 0, GL_RGBA,
 | 
						|
               GL_UNSIGNED_BYTE, texture_data.data());
 | 
						|
 | 
						|
  // generate shader
 | 
						|
  ProgramShaderCache::CompileShader(s_shader, s_vertexShaderSrc, s_fragmentShaderSrc);
 | 
						|
  s_shader.Bind();
 | 
						|
 | 
						|
  // bound uniforms
 | 
						|
  glUniform2f(glGetUniformLocation(s_shader.glprogid, "charSize"), 1.0f / GLfloat(CHAR_COUNT),
 | 
						|
              1.0f);
 | 
						|
  uniform_color_id = glGetUniformLocation(s_shader.glprogid, "color");
 | 
						|
  glUniform4f(uniform_color_id, 1.0f, 1.0f, 1.0f, 1.0f);
 | 
						|
  uniform_offset_id = glGetUniformLocation(s_shader.glprogid, "offset");
 | 
						|
  glUniform2f(uniform_offset_id, 0.0f, 0.0f);
 | 
						|
 | 
						|
  // generate VBO & VAO
 | 
						|
  glGenBuffers(1, &VBO);
 | 
						|
  glGenVertexArrays(1, &VAO);
 | 
						|
  glBindBuffer(GL_ARRAY_BUFFER, VBO);
 | 
						|
  glBindVertexArray(VAO);
 | 
						|
  glEnableVertexAttribArray(SHADER_POSITION_ATTRIB);
 | 
						|
  glVertexAttribPointer(SHADER_POSITION_ATTRIB, 2, GL_FLOAT, 0, sizeof(GLfloat) * 4, nullptr);
 | 
						|
  glEnableVertexAttribArray(SHADER_TEXTURE0_ATTRIB);
 | 
						|
  glVertexAttribPointer(SHADER_TEXTURE0_ATTRIB, 2, GL_FLOAT, 0, sizeof(GLfloat) * 4,
 | 
						|
                        (GLfloat*)nullptr + 2);
 | 
						|
}
 | 
						|
 | 
						|
RasterFont::~RasterFont()
 | 
						|
{
 | 
						|
  glDeleteTextures(1, &texture);
 | 
						|
  glDeleteBuffers(1, &VBO);
 | 
						|
  glDeleteVertexArrays(1, &VAO);
 | 
						|
  s_shader.Destroy();
 | 
						|
}
 | 
						|
 | 
						|
void RasterFont::printMultilineText(const std::string& text, double start_x, double start_y,
 | 
						|
                                    double z, int bbWidth, int bbHeight, u32 color)
 | 
						|
{
 | 
						|
  std::vector<GLfloat> vertices(text.length() * 6 * 4);
 | 
						|
 | 
						|
  int usage = 0;
 | 
						|
  GLfloat delta_x = GLfloat(2 * CHAR_WIDTH) / GLfloat(bbWidth);
 | 
						|
  GLfloat delta_y = GLfloat(2 * CHAR_HEIGHT) / GLfloat(bbHeight);
 | 
						|
  GLfloat border_x = 2.0f / GLfloat(bbWidth);
 | 
						|
  GLfloat border_y = 4.0f / GLfloat(bbHeight);
 | 
						|
 | 
						|
  GLfloat x = GLfloat(start_x);
 | 
						|
  GLfloat y = GLfloat(start_y);
 | 
						|
 | 
						|
  for (const char& c : text)
 | 
						|
  {
 | 
						|
    if (c == '\n')
 | 
						|
    {
 | 
						|
      x = GLfloat(start_x);
 | 
						|
      y -= delta_y + border_y;
 | 
						|
      continue;
 | 
						|
    }
 | 
						|
 | 
						|
    // do not print spaces, they can be skipped easily
 | 
						|
    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++] = GLfloat(c - CHAR_OFFSET);
 | 
						|
    vertices[usage++] = 0.0f;
 | 
						|
 | 
						|
    vertices[usage++] = x + delta_x;
 | 
						|
    vertices[usage++] = y;
 | 
						|
    vertices[usage++] = GLfloat(c - CHAR_OFFSET + 1);
 | 
						|
    vertices[usage++] = 0.0f;
 | 
						|
 | 
						|
    vertices[usage++] = x + delta_x;
 | 
						|
    vertices[usage++] = y + delta_y;
 | 
						|
    vertices[usage++] = GLfloat(c - CHAR_OFFSET + 1);
 | 
						|
    vertices[usage++] = 1.0f;
 | 
						|
 | 
						|
    vertices[usage++] = x;
 | 
						|
    vertices[usage++] = y;
 | 
						|
    vertices[usage++] = GLfloat(c - CHAR_OFFSET);
 | 
						|
    vertices[usage++] = 0.0f;
 | 
						|
 | 
						|
    vertices[usage++] = x + delta_x;
 | 
						|
    vertices[usage++] = y + delta_y;
 | 
						|
    vertices[usage++] = GLfloat(c - CHAR_OFFSET + 1);
 | 
						|
    vertices[usage++] = 1.0f;
 | 
						|
 | 
						|
    vertices[usage++] = x;
 | 
						|
    vertices[usage++] = y + delta_y;
 | 
						|
    vertices[usage++] = GLfloat(c - CHAR_OFFSET);
 | 
						|
    vertices[usage++] = 1.0f;
 | 
						|
 | 
						|
    x += delta_x + border_x;
 | 
						|
  }
 | 
						|
 | 
						|
  if (!usage)
 | 
						|
  {
 | 
						|
    return;
 | 
						|
  }
 | 
						|
 | 
						|
  glBindVertexArray(VAO);
 | 
						|
  glBindBuffer(GL_ARRAY_BUFFER, VBO);
 | 
						|
  glBufferData(GL_ARRAY_BUFFER, usage * sizeof(GLfloat), vertices.data(), GL_STREAM_DRAW);
 | 
						|
 | 
						|
  s_shader.Bind();
 | 
						|
 | 
						|
  // shadows
 | 
						|
  glUniform2f(uniform_offset_id, 2.0f / GLfloat(bbWidth), -2.0f / GLfloat(bbHeight));
 | 
						|
  glUniform4f(uniform_color_id, 0.0f, 0.0f, 0.0f, GLfloat((color >> 24) & 0xff) / 255.f);
 | 
						|
  glDrawArrays(GL_TRIANGLES, 0, usage / 4);
 | 
						|
 | 
						|
  glUniform2f(uniform_offset_id, 0.0f, 0.0f);
 | 
						|
  glUniform4f(uniform_color_id, GLfloat((color >> 16) & 0xff) / 255.f,
 | 
						|
              GLfloat((color >> 8) & 0xff) / 255.f, GLfloat((color >> 0) & 0xff) / 255.f,
 | 
						|
              GLfloat((color >> 24) & 0xff) / 255.f);
 | 
						|
  glDrawArrays(GL_TRIANGLES, 0, usage / 4);
 | 
						|
}
 | 
						|
}
 |