fixed fonts
This commit is contained in:
@@ -92,5 +92,8 @@ private:
|
|||||||
GLuint shader_program_;
|
GLuint shader_program_;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Global instance — shared by all panels and radar stubs. */
|
/* Global instances — shared by all panels and radar stubs.
|
||||||
|
* g_text_renderer : FONT_SIZE_NORMAL (body text, controls, status bar)
|
||||||
|
* g_text_renderer_large: FONT_SIZE_TITLE (panel titles, scope headings) */
|
||||||
extern TextRenderer g_text_renderer;
|
extern TextRenderer g_text_renderer;
|
||||||
|
extern TextRenderer g_text_renderer_large;
|
||||||
|
|||||||
@@ -151,10 +151,12 @@
|
|||||||
|
|
||||||
#define FONT_PATH "/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf"
|
#define FONT_PATH "/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf"
|
||||||
#define FONT_SIZE_NORMAL 18u
|
#define FONT_SIZE_NORMAL 18u
|
||||||
#define FONT_SIZE_TITLE 24u
|
#define FONT_SIZE_TITLE 26u
|
||||||
|
|
||||||
// Pixels between text baselines at scale 1.0 with FONT_SIZE_NORMAL
|
// Pixels between text baselines at scale 1.0 with FONT_SIZE_NORMAL
|
||||||
#define LINE_HEIGHT 24.0f
|
#define LINE_HEIGHT 24.0f
|
||||||
|
// Pixels between text baselines at scale 1.0 with FONT_SIZE_TITLE
|
||||||
|
#define LINE_HEIGHT_LARGE 34.0f
|
||||||
|
|
||||||
// Pixel margin from panel edge for text placement
|
// Pixel margin from panel edge for text placement
|
||||||
#define TEXT_MARGIN 10.0f
|
#define TEXT_MARGIN 10.0f
|
||||||
|
|||||||
@@ -66,13 +66,13 @@ static const float COL_GREEN_LO[3] = { 0.00f, 0.55f, 0.18f };
|
|||||||
/* Layout helpers */
|
/* Layout helpers */
|
||||||
/* ------------------------------------------------------------------ */
|
/* ------------------------------------------------------------------ */
|
||||||
|
|
||||||
static const float SCALE_TITLE = 1.25f;
|
|
||||||
static const float SCALE_NORMAL = 1.00f;
|
static const float SCALE_NORMAL = 1.00f;
|
||||||
static const float SCALE_SMALL = 0.85f;
|
static const float SCALE_SMALL = 0.85f;
|
||||||
static const float MARGIN = static_cast<float>(TEXT_MARGIN);
|
static const float MARGIN = static_cast<float>(TEXT_MARGIN);
|
||||||
static const float LH = LINE_HEIGHT; /* line height at scale 1.0 */
|
static const float LH = LINE_HEIGHT;
|
||||||
|
static const float LH_LARGE = LINE_HEIGHT_LARGE;
|
||||||
|
|
||||||
/* Render one line of text and advance y downward by one line. */
|
/* Render one body-text line and advance y downward. */
|
||||||
static void text_line(const std::string& text, float x, float& y,
|
static void text_line(const std::string& text, float x, float& y,
|
||||||
float scale,
|
float scale,
|
||||||
float cr, float cg, float cb) {
|
float cr, float cg, float cb) {
|
||||||
@@ -80,6 +80,13 @@ static void text_line(const std::string& text, float x, float& y,
|
|||||||
y -= LH * scale;
|
y -= LH * scale;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Render one title-size line using the large renderer at scale 1.0. */
|
||||||
|
static void text_line_large(const std::string& text, float x, float& y,
|
||||||
|
float cr, float cg, float cb) {
|
||||||
|
g_text_renderer_large.render_text(text, x, y, 1.0f, cr, cg, cb);
|
||||||
|
y -= LH_LARGE;
|
||||||
|
}
|
||||||
|
|
||||||
/* Render a blank spacer line. */
|
/* Render a blank spacer line. */
|
||||||
static void blank_line(float& y, float scale) {
|
static void blank_line(float& y, float scale) {
|
||||||
y -= LH * scale * 0.6f;
|
y -= LH * scale * 0.6f;
|
||||||
@@ -123,16 +130,16 @@ static void render_scope_name(const std::string& radar_name) {
|
|||||||
const float scope_w = static_cast<float>(SCOPE_WIDTH);
|
const float scope_w = static_cast<float>(SCOPE_WIDTH);
|
||||||
const float scope_h = static_cast<float>(SCOPE_HEIGHT);
|
const float scope_h = static_cast<float>(SCOPE_HEIGHT);
|
||||||
|
|
||||||
float name_w = g_text_renderer.get_text_width(radar_name, 2.0f);
|
float name_w = g_text_renderer_large.get_text_width(radar_name, 1.0f);
|
||||||
float nx = (scope_w - name_w) / 2.0f;
|
float nx = (scope_w - name_w) / 2.0f;
|
||||||
float ny = scope_h / 2.0f + 20.0f;
|
float ny = scope_h / 2.0f + 20.0f;
|
||||||
g_text_renderer.render_text(radar_name, nx, ny, 2.0f,
|
g_text_renderer_large.render_text(radar_name, nx, ny, 1.0f,
|
||||||
COL_GREEN_DIM[0], COL_GREEN_DIM[1], COL_GREEN_DIM[2]);
|
COL_GREEN_DIM[0], COL_GREEN_DIM[1], COL_GREEN_DIM[2]);
|
||||||
|
|
||||||
std::string sub = "[ stub - initialization test only ]";
|
std::string sub = "[ stub - initialization test only ]";
|
||||||
float sub_w = g_text_renderer.get_text_width(sub, SCALE_NORMAL);
|
float sub_w = g_text_renderer.get_text_width(sub, SCALE_NORMAL);
|
||||||
float sx = (scope_w - sub_w) / 2.0f;
|
float sx = (scope_w - sub_w) / 2.0f;
|
||||||
float sy = ny - LH * 2.0f;
|
float sy = ny - LH_LARGE;
|
||||||
g_text_renderer.render_text(sub, sx, sy, SCALE_NORMAL,
|
g_text_renderer.render_text(sub, sx, sy, SCALE_NORMAL,
|
||||||
COL_GREEN_LO[0], COL_GREEN_LO[1], COL_GREEN_LO[2]);
|
COL_GREEN_LO[0], COL_GREEN_LO[1], COL_GREEN_LO[2]);
|
||||||
}
|
}
|
||||||
@@ -157,10 +164,10 @@ static void render_common_status(float x, float& y, float scale) {
|
|||||||
/* ================================================================== */
|
/* ================================================================== */
|
||||||
|
|
||||||
void ChainHomeRadar::render_left_panel() {
|
void ChainHomeRadar::render_left_panel() {
|
||||||
float y = static_cast<float>(WINDOW_HEIGHT) - MARGIN - LH * SCALE_TITLE;
|
float y = static_cast<float>(WINDOW_HEIGHT) - MARGIN - LH_LARGE;
|
||||||
float x = MARGIN;
|
float x = MARGIN;
|
||||||
|
|
||||||
text_line("CHAIN HOME RADAR", x, y, SCALE_TITLE,
|
text_line_large("CHAIN HOME RADAR", x, y,
|
||||||
COL_WHITE[0], COL_WHITE[1], COL_WHITE[2]);
|
COL_WHITE[0], COL_WHITE[1], COL_WHITE[2]);
|
||||||
blank_line(y, SCALE_NORMAL);
|
blank_line(y, SCALE_NORMAL);
|
||||||
|
|
||||||
@@ -231,10 +238,10 @@ void ChainHomeRadar::render_status_bar() {
|
|||||||
/* ================================================================== */
|
/* ================================================================== */
|
||||||
|
|
||||||
void MarineAScopeRadar::render_left_panel() {
|
void MarineAScopeRadar::render_left_panel() {
|
||||||
float y = static_cast<float>(WINDOW_HEIGHT) - MARGIN - LH * SCALE_TITLE;
|
float y = static_cast<float>(WINDOW_HEIGHT) - MARGIN - LH_LARGE;
|
||||||
float x = MARGIN;
|
float x = MARGIN;
|
||||||
|
|
||||||
text_line("MARINE A-SCOPE RADAR", x, y, SCALE_TITLE,
|
text_line_large("MARINE A-SCOPE RADAR", x, y,
|
||||||
COL_WHITE[0], COL_WHITE[1], COL_WHITE[2]);
|
COL_WHITE[0], COL_WHITE[1], COL_WHITE[2]);
|
||||||
blank_line(y, SCALE_NORMAL);
|
blank_line(y, SCALE_NORMAL);
|
||||||
|
|
||||||
@@ -303,10 +310,10 @@ void MarineAScopeRadar::render_status_bar() {
|
|||||||
/* ================================================================== */
|
/* ================================================================== */
|
||||||
|
|
||||||
void MarineTrafficRadar::render_left_panel() {
|
void MarineTrafficRadar::render_left_panel() {
|
||||||
float y = static_cast<float>(WINDOW_HEIGHT) - MARGIN - LH * SCALE_TITLE;
|
float y = static_cast<float>(WINDOW_HEIGHT) - MARGIN - LH_LARGE;
|
||||||
float x = MARGIN;
|
float x = MARGIN;
|
||||||
|
|
||||||
text_line("MARINE TRAFFIC CONTROL RADAR", x, y, SCALE_TITLE,
|
text_line_large("MARINE TRAFFIC CONTROL RADAR", x, y,
|
||||||
COL_WHITE[0], COL_WHITE[1], COL_WHITE[2]);
|
COL_WHITE[0], COL_WHITE[1], COL_WHITE[2]);
|
||||||
blank_line(y, SCALE_NORMAL);
|
blank_line(y, SCALE_NORMAL);
|
||||||
|
|
||||||
@@ -379,10 +386,10 @@ void MarineTrafficRadar::render_status_bar() {
|
|||||||
/* ================================================================== */
|
/* ================================================================== */
|
||||||
|
|
||||||
void PoliceboatRadar::render_left_panel() {
|
void PoliceboatRadar::render_left_panel() {
|
||||||
float y = static_cast<float>(WINDOW_HEIGHT) - MARGIN - LH * SCALE_TITLE;
|
float y = static_cast<float>(WINDOW_HEIGHT) - MARGIN - LH_LARGE;
|
||||||
float x = MARGIN;
|
float x = MARGIN;
|
||||||
|
|
||||||
text_line("POLICE BOAT RADAR", x, y, SCALE_TITLE,
|
text_line_large("POLICE BOAT RADAR", x, y,
|
||||||
COL_WHITE[0], COL_WHITE[1], COL_WHITE[2]);
|
COL_WHITE[0], COL_WHITE[1], COL_WHITE[2]);
|
||||||
blank_line(y, SCALE_NORMAL);
|
blank_line(y, SCALE_NORMAL);
|
||||||
|
|
||||||
|
|||||||
@@ -42,6 +42,7 @@
|
|||||||
|
|
||||||
/* Global singleton used by all components. */
|
/* Global singleton used by all components. */
|
||||||
TextRenderer g_text_renderer;
|
TextRenderer g_text_renderer;
|
||||||
|
TextRenderer g_text_renderer_large;
|
||||||
|
|
||||||
/* ------------------------------------------------------------------ */
|
/* ------------------------------------------------------------------ */
|
||||||
/* Internal helpers */
|
/* Internal helpers */
|
||||||
|
|||||||
38
src/main.cpp
38
src/main.cpp
@@ -93,6 +93,7 @@ static const float COL_PINK[3] = { 1.00f, 0.60f, 0.80f };
|
|||||||
static const float COL_RED[3] = { 1.00f, 0.25f, 0.25f };
|
static const float COL_RED[3] = { 1.00f, 0.25f, 0.25f };
|
||||||
|
|
||||||
static const float LH_MAIN = LINE_HEIGHT;
|
static const float LH_MAIN = LINE_HEIGHT;
|
||||||
|
static const float LH_LARGE = LINE_HEIGHT_LARGE;
|
||||||
static const float MARGIN = static_cast<float>(TEXT_MARGIN);
|
static const float MARGIN = static_cast<float>(TEXT_MARGIN);
|
||||||
|
|
||||||
/* ------------------------------------------------------------------ */
|
/* ------------------------------------------------------------------ */
|
||||||
@@ -372,12 +373,12 @@ static void parse_args(int argc, char* argv[]) {
|
|||||||
/* ------------------------------------------------------------------ */
|
/* ------------------------------------------------------------------ */
|
||||||
|
|
||||||
static void render_intro_left_panel() {
|
static void render_intro_left_panel() {
|
||||||
float y = static_cast<float>(WINDOW_HEIGHT) - MARGIN - LH_MAIN * 1.25f;
|
float y = static_cast<float>(WINDOW_HEIGHT) - MARGIN - LH_LARGE;
|
||||||
float x = MARGIN;
|
float x = MARGIN;
|
||||||
|
|
||||||
g_text_renderer.render_text("RAF / MARINE RADAR EXHIBIT", x, y, 1.25f,
|
g_text_renderer_large.render_text("RAF / MARINE RADAR EXHIBIT", x, y, 1.0f,
|
||||||
COL_WHITE[0], COL_WHITE[1], COL_WHITE[2]);
|
COL_WHITE[0], COL_WHITE[1], COL_WHITE[2]);
|
||||||
y -= LH_MAIN * 1.25f;
|
y -= LH_LARGE;
|
||||||
|
|
||||||
y -= LH_MAIN * 0.5f;
|
y -= LH_MAIN * 0.5f;
|
||||||
|
|
||||||
@@ -414,11 +415,11 @@ static void render_radar_list() {
|
|||||||
|
|
||||||
/* Title */
|
/* Title */
|
||||||
std::string title = "SELECT A RADAR";
|
std::string title = "SELECT A RADAR";
|
||||||
float tw = g_text_renderer.get_text_width(title, 1.5f);
|
float tw = g_text_renderer_large.get_text_width(title, 1.0f);
|
||||||
g_text_renderer.render_text(title,
|
g_text_renderer_large.render_text(title,
|
||||||
(scope_w - tw) / 2.0f,
|
(scope_w - tw) / 2.0f,
|
||||||
scope_h - 60.0f,
|
scope_h - 60.0f,
|
||||||
1.5f,
|
1.0f,
|
||||||
COL_WHITE[0], COL_WHITE[1], COL_WHITE[2]);
|
COL_WHITE[0], COL_WHITE[1], COL_WHITE[2]);
|
||||||
|
|
||||||
if (g_selectable.empty()) {
|
if (g_selectable.empty()) {
|
||||||
@@ -440,18 +441,17 @@ static void render_radar_list() {
|
|||||||
std::string entry = g_selectable[i].display_name;
|
std::string entry = g_selectable[i].display_name;
|
||||||
bool highlighted = (i == g_selection_cursor);
|
bool highlighted = (i == g_selection_cursor);
|
||||||
|
|
||||||
float scale = highlighted ? 1.3f : 1.0f;
|
|
||||||
const float* col = highlighted ? COL_GREEN_HI : COL_GREEN_DIM;
|
const float* col = highlighted ? COL_GREEN_HI : COL_GREEN_DIM;
|
||||||
|
|
||||||
std::string prefix = highlighted ? "> " : " ";
|
std::string prefix = highlighted ? "> " : " ";
|
||||||
std::string line = prefix + entry;
|
std::string line = prefix + entry;
|
||||||
|
|
||||||
float lw = g_text_renderer.get_text_width(line, scale);
|
TextRenderer& tr = highlighted ? g_text_renderer_large : g_text_renderer;
|
||||||
|
float lw = tr.get_text_width(line, 1.0f);
|
||||||
float lx = (scope_w - lw) / 2.0f;
|
float lx = (scope_w - lw) / 2.0f;
|
||||||
float ly = list_y_start - i * LH_MAIN * 1.4f;
|
float ly = list_y_start - i * LH_MAIN * 1.4f;
|
||||||
|
|
||||||
g_text_renderer.render_text(line, lx, ly, scale,
|
tr.render_text(line, lx, ly, 1.0f, col[0], col[1], col[2]);
|
||||||
col[0], col[1], col[2]);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -514,6 +514,7 @@ static void render_selection_screen() {
|
|||||||
glClearColor(0.04f, 0.04f, 0.04f, 1.0f);
|
glClearColor(0.04f, 0.04f, 0.04f, 1.0f);
|
||||||
glClear(GL_COLOR_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
g_text_renderer.set_projection(LEFT_PANEL_WIDTH, WINDOW_HEIGHT);
|
g_text_renderer.set_projection(LEFT_PANEL_WIDTH, WINDOW_HEIGHT);
|
||||||
|
g_text_renderer_large.set_projection(LEFT_PANEL_WIDTH, WINDOW_HEIGHT);
|
||||||
render_intro_left_panel();
|
render_intro_left_panel();
|
||||||
|
|
||||||
/* Scope area — radar list */
|
/* Scope area — radar list */
|
||||||
@@ -522,6 +523,7 @@ static void render_selection_screen() {
|
|||||||
glClearColor(0.0f, 0.05f, 0.01f, 1.0f);
|
glClearColor(0.0f, 0.05f, 0.01f, 1.0f);
|
||||||
glClear(GL_COLOR_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
g_text_renderer.set_projection(scope_w, scope_h);
|
g_text_renderer.set_projection(scope_w, scope_h);
|
||||||
|
g_text_renderer_large.set_projection(scope_w, scope_h);
|
||||||
render_radar_list();
|
render_radar_list();
|
||||||
|
|
||||||
/* Status bar */
|
/* Status bar */
|
||||||
@@ -530,6 +532,7 @@ static void render_selection_screen() {
|
|||||||
glClearColor(0.04f, 0.04f, 0.04f, 1.0f);
|
glClearColor(0.04f, 0.04f, 0.04f, 1.0f);
|
||||||
glClear(GL_COLOR_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
g_text_renderer.set_projection(scope_w, STATUS_BAR_HEIGHT);
|
g_text_renderer.set_projection(scope_w, STATUS_BAR_HEIGHT);
|
||||||
|
g_text_renderer_large.set_projection(scope_w, STATUS_BAR_HEIGHT);
|
||||||
render_selection_status_bar();
|
render_selection_status_bar();
|
||||||
|
|
||||||
glDisable(GL_SCISSOR_TEST);
|
glDisable(GL_SCISSOR_TEST);
|
||||||
@@ -548,6 +551,7 @@ static void render_operating_screen() {
|
|||||||
glClearColor(0.04f, 0.04f, 0.04f, 1.0f);
|
glClearColor(0.04f, 0.04f, 0.04f, 1.0f);
|
||||||
glClear(GL_COLOR_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
g_text_renderer.set_projection(LEFT_PANEL_WIDTH, WINDOW_HEIGHT);
|
g_text_renderer.set_projection(LEFT_PANEL_WIDTH, WINDOW_HEIGHT);
|
||||||
|
g_text_renderer_large.set_projection(LEFT_PANEL_WIDTH, WINDOW_HEIGHT);
|
||||||
g_active_radar->render_left_panel();
|
g_active_radar->render_left_panel();
|
||||||
|
|
||||||
/* Scope — radar name (stub) */
|
/* Scope — radar name (stub) */
|
||||||
@@ -556,6 +560,7 @@ static void render_operating_screen() {
|
|||||||
glClearColor(0.0f, 0.05f, 0.01f, 1.0f);
|
glClearColor(0.0f, 0.05f, 0.01f, 1.0f);
|
||||||
glClear(GL_COLOR_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
g_text_renderer.set_projection(scope_w, scope_h);
|
g_text_renderer.set_projection(scope_w, scope_h);
|
||||||
|
g_text_renderer_large.set_projection(scope_w, scope_h);
|
||||||
g_active_radar->render_scope();
|
g_active_radar->render_scope();
|
||||||
|
|
||||||
/* Status bar — current control values */
|
/* Status bar — current control values */
|
||||||
@@ -564,6 +569,7 @@ static void render_operating_screen() {
|
|||||||
glClearColor(0.04f, 0.04f, 0.04f, 1.0f);
|
glClearColor(0.04f, 0.04f, 0.04f, 1.0f);
|
||||||
glClear(GL_COLOR_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
g_text_renderer.set_projection(scope_w, STATUS_BAR_HEIGHT);
|
g_text_renderer.set_projection(scope_w, STATUS_BAR_HEIGHT);
|
||||||
|
g_text_renderer_large.set_projection(scope_w, STATUS_BAR_HEIGHT);
|
||||||
g_active_radar->render_status_bar();
|
g_active_radar->render_status_bar();
|
||||||
|
|
||||||
glDisable(GL_SCISSOR_TEST);
|
glDisable(GL_SCISSOR_TEST);
|
||||||
@@ -627,7 +633,7 @@ int main(int argc, char* argv[]) {
|
|||||||
glEnable(GL_BLEND);
|
glEnable(GL_BLEND);
|
||||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||||
|
|
||||||
/* 6. Load text renderer shaders and font. */
|
/* 6. Load text renderer shaders and fonts. */
|
||||||
if (!g_text_renderer.initialize_shaders()) {
|
if (!g_text_renderer.initialize_shaders()) {
|
||||||
fprintf(stderr, "[main] text renderer shader init failed\n");
|
fprintf(stderr, "[main] text renderer shader init failed\n");
|
||||||
glfwTerminate();
|
glfwTerminate();
|
||||||
@@ -638,6 +644,16 @@ int main(int argc, char* argv[]) {
|
|||||||
glfwTerminate();
|
glfwTerminate();
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
if (!g_text_renderer_large.initialize_shaders()) {
|
||||||
|
fprintf(stderr, "[main] large text renderer shader init failed\n");
|
||||||
|
glfwTerminate();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (!g_text_renderer_large.initialize_font(FONT_PATH, FONT_SIZE_TITLE)) {
|
||||||
|
fprintf(stderr, "[main] large font load failed: " FONT_PATH "\n");
|
||||||
|
glfwTerminate();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
/* 7. Register keyboard callback. */
|
/* 7. Register keyboard callback. */
|
||||||
glfwSetKeyCallback(window, key_callback);
|
glfwSetKeyCallback(window, key_callback);
|
||||||
|
|||||||
Reference in New Issue
Block a user