void GameLogic::renderLeadBoard() { //Render leader board screen m_platform.beginRender(); glClear(GL_COLOR_BUFFER_BIT); glEnable(GL_TEXTURE_2D); glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_TEXTURE_COORD_ARRAY); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); m_background.draw(); m_leaderBoard.draw(); glDisableClientState(GL_VERTEX_ARRAY); glDisableClientState(GL_TEXTURE_COORD_ARRAY); glDisable(GL_TEXTURE_2D); glDisable(GL_BLEND); bbutil_render_text(m_font, m_message, m_messagePosX, m_messagePosY, 1.0f, 1.0f, 1.0f, 1.0f); if (m_leaderBoardReady) { m_playButton.draw(); float posY, sizeX, sizeY; char buf[100]; bbutil_measure_text(m_leaderboardFont, "123", &sizeX, &sizeY); posY = m_leaderBoard.PosY() + m_leaderBoard.Height() / 2 - sizeY - LEADERBOARD_LINE_OFFSET_Y; for (int i = 0; i < static_cast<int>(m_leaderboard.size()); i++) { sprintf(buf, "%i. %s", m_leaderboard[i].rank(), m_leaderboard[i].name().c_str()); bbutil_render_text(m_leaderboardFont, buf, m_leaderBoard.PosX() - m_leaderBoard.Width() / 2 + LEADERBOARD_LINE_OFFSET_X, posY, 1.0f, 1.0f, 1.0f, 1.0f); sprintf(buf, "%li", m_leaderboard[i].score()); bbutil_measure_text(m_leaderboardFont, buf, &sizeX, &sizeY); bbutil_render_text(m_leaderboardFont, buf, m_leaderBoard.PosX() + m_leaderBoard.Width() / 2 - sizeX - LEADERBOARD_LINE_OFFSET_X, posY, 1.0f, 1.0f, 1.0f, 1.0f); posY -= sizeY + 10.0f; } } m_platform.finishRender(); }
void GameLogic::onPause() { if (m_gamePaused == false && m_state == GamePlay) { m_gamePaused = true; m_message = "Game paused, tap screen to start"; float textSizeX, textSizeY; bbutil_measure_text(m_font, m_message, &textSizeX, &textSizeY); m_messagePosX = (m_sceneWidth - textSizeX) / 2; m_messagePosY = (m_sceneHeight - textSizeY) / 2; } m_backgroundMusic.pause(); }
void GameLogic::onUserReady(const std::string& userName, bool isAnonymous, const std::string& errorString) { if (isAnonymous) { if (!errorString.empty()) { m_platform.displayPrompt(errorString + ", please enter your name"); } else { m_platform.displayPrompt("Please enter your name"); } } else { // We've got the user name, proceed with game play (which starts paused). m_state = GamePlay; m_message = "Game paused, tap screen to start"; float textSizeX, textSizeY; bbutil_measure_text(m_font, m_message, &textSizeX, &textSizeY); m_messagePosX = (m_sceneWidth - textSizeX) / 2; m_messagePosY = (m_sceneHeight - textSizeY) / 2; } }
void GameLogic::endGamePlay(bool win) { m_gameFinished = true; m_state = LeaderBoard; if (win) { m_message = "Congratulations, you won!"; } else { m_message = "Sorry, you lost. Another try maybe?"; } float sizeX, sizeY; bbutil_measure_text(m_font, m_message, &sizeX, &sizeY); m_messagePosX = (m_sceneWidth - sizeX) / 2; m_messagePosY = m_sceneHeight - sizeY - MESSAGE_OFFSET_Y; if (win) { m_platform.submitScore(m_score); } else { m_platform.fetchLeaderboard(); } }
static void frame(void *data) { App *app = (App*)data; /* Calculate delta time */ app->timeStart = GetTicks(); Globals::DeltaTime = (float)(app->timeStart - app->oldTime) / app->dfps; app->oldTime = app->timeStart; /* Update & draw game */ Game::Update(); Game::Draw(); /* Calculate FPS */ if(GetTicks() >= app->fpsTimeStart + 1000) { Globals::FPS = app->frames; app->frames = 1; app->fpsTimeStart = GetTicks(); } /*else*/ ++app->frames; /* Print FPS */ static std::stringstream ss; ss.str(""); ss << "FPS: " << Globals::FPS; //ss << Globals::ScreenWidth << ", " << Globals::ScreenHeight; float textWidth, textHeight; bbutil_measure_text(app->mainFont, ss.str().c_str(), &textWidth, &textHeight); float x = -Globals::ScreenWidth * 0.5f; float y = Globals::ScreenHeight * 0.5f - textHeight; bbutil_render_text(app->mainFont, ss.str().c_str(), x, y, 1.0f, 1.0f, 1.0f, 1.0f); }
int init() { EGLint surface_width, surface_height; //On initialize bbutil loads arial as a default font. We are going to load MyriadPro-Bold as it looks a little better and scale it //to fit out bubble nicely. int dpi = bbutil_calculate_dpi(screen_cxt); font = bbutil_load_font( "/usr/fonts/font_repository/adobe/MyriadPro-Bold.otf", 15, dpi); if (!font) { return EXIT_FAILURE; } //Load background texture float tex_x, tex_y; if (EXIT_SUCCESS != bbutil_load_texture("app/native/HelloWorld_smaller_bubble.png", NULL, NULL, &tex_x, &tex_y, &background)) { fprintf(stderr, "Unable to load background texture\n"); } //Query width and height of the window surface created by utility code eglQuerySurface(egl_disp, egl_surf, EGL_WIDTH, &surface_width); eglQuerySurface(egl_disp, egl_surf, EGL_HEIGHT, &surface_height); EGLint err = eglGetError(); if (err != 0x3000) { fprintf(stderr, "Unable to query EGL surface dimensions\n"); return EXIT_FAILURE; } width = (float) surface_width; height = (float) surface_height; //Initialize GL for 2D rendering glViewport(0, 0, (int) width, (int) height); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrthof(0.0f, width / height, 0.0f, 1.0f, -1.0f, 1.0f); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); //Set world coordinates to coincide with screen pixels glScalef(1.0f / height, 1.0f / height, 1.0f); float text_width, text_height; bbutil_measure_text(font, "Hello world", &text_width, &text_height); pos_x = (width - text_width) / 2; pos_y = height / 2; //Setup background polygon vertices[0] = 0.0f; vertices[1] = 0.0f; vertices[2] = width; vertices[3] = 0.0f; vertices[4] = 0.0f; vertices[5] = height; vertices[6] = width; vertices[7] = height; tex_coord[0] = 0.0f; tex_coord[1] = 0.0f; tex_coord[2] = tex_x; tex_coord[3] = 0.0f; tex_coord[4] = 0.0f; tex_coord[5] = tex_y; tex_coord[6] = tex_x; tex_coord[7] = tex_y; return EXIT_SUCCESS; }
int initialize() { //Load shadow and button textures float tex_x = 1.0f, tex_y = 1.0f; //Load textures for radio buttons int size_x = 64, size_y = 64; if (EXIT_SUCCESS != bbutil_load_texture("app/native/radio_btn_unselected.png", NULL, NULL, &tex_x, &tex_y, &radio_btn_unselected)) { fprintf(stderr, "Unable to load non-selected radio button texture\n"); } radio_btn_unselected_vertices[0] = 0.0f; radio_btn_unselected_vertices[1] = 0.0f; radio_btn_unselected_vertices[2] = size_x; radio_btn_unselected_vertices[3] = 0.0f; radio_btn_unselected_vertices[4] = 0.0f; radio_btn_unselected_vertices[5] = size_y; radio_btn_unselected_vertices[6] = size_x; radio_btn_unselected_vertices[7] = size_y; radio_btn_unselected_tex_coord[0] = 0.0f; radio_btn_unselected_tex_coord[1] = 0.0f; radio_btn_unselected_tex_coord[2] = tex_x; radio_btn_unselected_tex_coord[3] = 0.0f; radio_btn_unselected_tex_coord[4] = 0.0f; radio_btn_unselected_tex_coord[5] = tex_y; radio_btn_unselected_tex_coord[6] = tex_x; radio_btn_unselected_tex_coord[7] = tex_y; if (EXIT_SUCCESS != bbutil_load_texture("app/native/radio_btn_selected.png", NULL, NULL, &tex_x, &tex_y, &radio_btn_selected)) { fprintf(stderr, "Unable to load selected radio button texture\n"); } radio_btn_selected_vertices[0] = 0.0f; radio_btn_selected_vertices[1] = 0.0f; radio_btn_selected_vertices[2] = size_x; radio_btn_selected_vertices[3] = 0.0f; radio_btn_selected_vertices[4] = 0.0f; radio_btn_selected_vertices[5] = size_y; radio_btn_selected_vertices[6] = size_x; radio_btn_selected_vertices[7] = size_y; radio_btn_selected_tex_coord[0] = 0.0f; radio_btn_selected_tex_coord[1] = 0.0f; radio_btn_selected_tex_coord[2] = tex_x; radio_btn_selected_tex_coord[3] = 0.0f; radio_btn_selected_tex_coord[4] = 0.0f; radio_btn_selected_tex_coord[5] = tex_y; radio_btn_selected_tex_coord[6] = tex_x; radio_btn_selected_tex_coord[7] = tex_y; button_size_x = (float) size_x; button_size_y = (float) size_y; if (EXIT_SUCCESS != bbutil_load_texture("app/native/shadow.png", NULL, NULL, &tex_x, &tex_y, &shadow)) { fprintf(stderr, "Unable to load shadow texture\n"); } shadow_size_x = (float) 512; shadow_size_y = (float) 256; shadow_tex_coord[0] = 0.0f; shadow_tex_coord[1] = 0.0f; shadow_tex_coord[2] = tex_x; shadow_tex_coord[3] = 0.0f; shadow_tex_coord[4] = 0.0f; shadow_tex_coord[5] = tex_y; shadow_tex_coord[6] = tex_x; shadow_tex_coord[7] = tex_y; angle = 0.0f; pos_x = 0.0f; pos_y = 0.0f; //Load MyriadPro bold to use for our color menu int dpi = bbutil_calculate_dpi(screen_cxt); if (dpi == EXIT_FAILURE) { fprintf(stderr, "Unable to calculate dpi\n"); return EXIT_FAILURE; } font = bbutil_load_font( "/usr/fonts/font_repository/adobe/MyriadPro-Bold.otf", 15, dpi); if (!font) { return EXIT_FAILURE; } float text_width, text_height; bbutil_measure_text(font, "Color Menu", &text_width, &text_height); menu_height = text_height + 10.0f + button_size_y * 4; //See if a savefile exists. If not, initialize to a hidden menu and a red cube. if (!read_from_file()) { selected = 3; cube_color[0] = 1.0f; cube_color[1] = 0.0f; cube_color[2] = 0.0f; cube_color[3] = 1.0f; menu_animation = 0.0f; menu_active = false; menu_show_animation = false; menu_hide_animation = false; } //Initialize positions of graphics assets on the screen, but don't resize the surface if (EXIT_FAILURE == resize(NULL)) { fprintf(stderr, "Initialize surface\n"); return EXIT_FAILURE; } //Common gl setup glShadeModel(GL_SMOOTH); glClearColor(0.775f, 0.775f, 0.775f, 1.0f); glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient); glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse); glLightfv(GL_LIGHT0, GL_POSITION, light_pos); glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, light_direction); glEnable(GL_CULL_FACE); return EXIT_SUCCESS; }
GameLogic::GameLogic(Platform &platform) : HawkInputHandler() , m_platform(platform) , m_shutdown(false) , m_gamePaused(true) , m_gameFinished(false) , m_state(FetchUser) , m_scoreTime(0) , m_resumeTime(0) , m_score(0) , m_leaderBoardReady(false) , m_timeStep(1.0f / 60.0f) , m_velocityIterations(6) , m_positionIterations(2) , m_world(b2Vec2(0.0f, -10.0f)) , m_player(0) , m_contactListener(m_clickReverb) { m_backgroundMusic.load("app/native/background.wav"); m_click1.load("app/native/click1.wav"); m_click2.load("app/native/click2.wav"); m_clickReverb.load("app/native/clickreverb.wav"); m_blockFall.load("app/native/blockfall.wav"); m_platform.setEventHandler(this); m_platform.getSize(m_sceneWidth, m_sceneHeight); int dpi = m_platform.getDPI(); int point_size = (int) (15.0f / ((float) dpi / 170.0f)); /* As bbutil renders text using device-specifc dpi, we need to compute * a point size for the font, so that the text string fits into the bubble. * Note that Playbook is used as a reference point in this equation as we * know that at dpi of 170, font with point size ofi 15 fits into the * bubble texture. */ m_font = bbutil_load_font("/usr/fonts/font_repository/monotype/arial.ttf", point_size, dpi); if (!m_font) { fprintf(stderr, "Unable to load font\n"); } m_scoreFont = bbutil_load_font("/usr/fonts/font_repository/monotype/arial.ttf", point_size, dpi); if (!m_scoreFont) { fprintf(stderr, "Unable to load font\n"); } m_leaderboardFont = bbutil_load_font("/usr/fonts/font_repository/monotype/arial.ttf", point_size, dpi); if (!m_scoreFont) { fprintf(stderr, "Unable to load font\n"); } //Initialize game sprites m_smallBlockBelligerent.load("app/native/belligerent_small.png"); m_smallBlockResting.load("app/native/resting_small.png"); m_largeBlockBelligerent.load("app/native/belligerent.png"); m_largeBlockResting.load("app/native/resting.png"); m_background.load("app/native/Background.png"); m_background.setPosition(m_sceneWidth / 2, m_sceneHeight / 2); m_background.setSize(m_sceneWidth, m_sceneHeight); m_leaderBoard.load("app/native/leaderboard.png"); m_leaderBoard.setPosition(m_sceneWidth / 2, m_sceneHeight / 2); m_buttonRegular.load("app/native/button_regular.png"); m_buttonPressed.load("app/native/button_pressed.png"); //Initialize message float textSizeX, textSizeY; m_message = "Loading..."; bbutil_measure_text(m_font, m_message, &textSizeX, &textSizeY); m_messagePosX = (m_sceneWidth - textSizeX) / 2; m_messagePosY = (m_sceneHeight - textSizeY) / 2; //Initialize score and timer positions bbutil_measure_text(m_scoreFont, "123", &textSizeX, &textSizeY); m_scorePosX = SCORE_OFFSET_X; m_scorePosY = m_sceneHeight - textSizeY - SCORE_OFFSET_Y; bbutil_measure_text(m_font, "123", &textSizeX, &textSizeY); m_timerPosX = TIMER_OFFSET_X; m_timerPosY = m_scorePosY - textSizeY - TIMER_OFFSET_Y; //Initialize start button m_playButton.sizeX = m_buttonRegular.Width(); m_playButton.sizeY = m_buttonRegular.Height(); m_playButton.isPressed = false; m_playButton.regular = &m_buttonRegular; m_playButton.pressed = &m_buttonPressed; m_playButton.font = m_font; m_playButton.text = "Play Again"; bbutil_measure_text(m_font, m_playButton.text, &textSizeX, &textSizeY); m_playButton.textX = -textSizeX / 2; m_playButton.textY = -textSizeY / 2; m_playButton.setPosition(m_sceneWidth / 2, m_leaderBoard.PosY() - m_leaderBoard.Height() / 2); //Box2D initialization and scene setup m_world.SetContactListener(&m_contactListener); DynamicHawkBodyDef def; def.world = &m_world; def.speed = HawkVector(4, 4); def.burst = HawkVector(8, 8); def.fixedRotation = true; for (int i = 0; i < 4; ++i) { HawkBody* platform = new HawkBody(def); platform->createSprite("app/native/ground.png"); HawkPoint center((i * (m_sceneWidth / 4)) + (platform->width() / 2), ((i % 2) * 200) + platform->height()); platform->createBody(center); platform->createFixtureFromSprite(); m_terrain.push_back(platform); } m_player = new DynamicHawkBody(def); m_player->createSprite("app/native/resting.png"); HawkPoint center(m_sceneWidth / 2, m_sceneHeight / 2); m_player->createBody(center); m_player->createFixtureFromSprite(); }
int initialize() { EGLint surface_width, surface_height; //Load background and button textures float tex_x = 1.0f, tex_y = 1.0f; //Load textures for radio buttons int size_x = 64, size_y = 64; if (EXIT_SUCCESS != bbutil_load_texture("app/native/radio_btn_unselected.png", NULL, NULL, &tex_x, &tex_y, &radio_btn_unselected)) { fprintf(stderr, "Unable to load non-selected radio button texture\n"); } radio_btn_unselected_vertices[0] = 0.0f; radio_btn_unselected_vertices[1] = 0.0f; radio_btn_unselected_vertices[2] = size_x; radio_btn_unselected_vertices[3] = 0.0f; radio_btn_unselected_vertices[4] = 0.0f; radio_btn_unselected_vertices[5] = size_y; radio_btn_unselected_vertices[6] = size_x; radio_btn_unselected_vertices[7] = size_y; radio_btn_unselected_tex_coord[0] = 0.0f; radio_btn_unselected_tex_coord[1] = 0.0f; radio_btn_unselected_tex_coord[2] = tex_x; radio_btn_unselected_tex_coord[3] = 0.0f; radio_btn_unselected_tex_coord[4] = 0.0f; radio_btn_unselected_tex_coord[5] = tex_y; radio_btn_unselected_tex_coord[6] = tex_x; radio_btn_unselected_tex_coord[7] = tex_y; if (EXIT_SUCCESS != bbutil_load_texture("app/native/radio_btn_selected.png", NULL, NULL, &tex_x, &tex_y, &radio_btn_selected)) { fprintf(stderr, "Unable to load selected radio button texture\n"); } radio_btn_selected_vertices[0] = 0.0f; radio_btn_selected_vertices[1] = 0.0f; radio_btn_selected_vertices[2] = size_x; radio_btn_selected_vertices[3] = 0.0f; radio_btn_selected_vertices[4] = 0.0f; radio_btn_selected_vertices[5] = size_y; radio_btn_selected_vertices[6] = size_x; radio_btn_selected_vertices[7] = size_y; radio_btn_selected_tex_coord[0] = 0.0f; radio_btn_selected_tex_coord[1] = 0.0f; radio_btn_selected_tex_coord[2] = tex_x; radio_btn_selected_tex_coord[3] = 0.0f; radio_btn_selected_tex_coord[4] = 0.0f; radio_btn_selected_tex_coord[5] = tex_y; radio_btn_selected_tex_coord[6] = tex_x; radio_btn_selected_tex_coord[7] = tex_y; button_size_x = (float) size_x; button_size_y = (float) size_y; eglQuerySurface(egl_disp, egl_surf, EGL_WIDTH, &surface_width); eglQuerySurface(egl_disp, egl_surf, EGL_HEIGHT, &surface_height); EGLint err = eglGetError(); if (err != 0x3000) { fprintf(stderr, "Unable to query EGL surface dimensions\n"); return EXIT_FAILURE; } width = (float) surface_width; height = (float) surface_height; if (EXIT_SUCCESS != bbutil_load_texture("app/native/background-landscape.png", NULL, NULL, &tex_x, &tex_y, &background_landscape)) { fprintf(stderr, "Unable to load landscape background texture\n"); } size_x = (width > height) ? width : height; size_y = (width > height) ? height : width; background_landscape_vertices[0] = 0.0f; background_landscape_vertices[1] = 0.0f; background_landscape_vertices[2] = size_x; background_landscape_vertices[3] = 0.0f; background_landscape_vertices[4] = 0.0f; background_landscape_vertices[5] = size_y; background_landscape_vertices[6] = size_x; background_landscape_vertices[7] = size_y; background_landscape_tex_coord[0] = 0.0f; background_landscape_tex_coord[1] = 0.0f; background_landscape_tex_coord[2] = tex_x; background_landscape_tex_coord[3] = 0.0f; background_landscape_tex_coord[4] = 0.0f; background_landscape_tex_coord[5] = tex_y; background_landscape_tex_coord[6] = tex_x; background_landscape_tex_coord[7] = tex_y; if (EXIT_SUCCESS != bbutil_load_texture("app/native/background-portrait.png", NULL, NULL, &tex_x, &tex_y, &background_portrait)) { fprintf(stderr, "Unable to load portrait background texture\n"); } size_x = (height > width) ? width : height; size_y = (height > width) ? height : width; background_portrait_vertices[0] = 0.0f; background_portrait_vertices[1] = 0.0f; background_portrait_vertices[2] = size_x; background_portrait_vertices[3] = 0.0f; background_portrait_vertices[4] = 0.0f; background_portrait_vertices[5] = size_y; background_portrait_vertices[6] = size_x; background_portrait_vertices[7] = size_y; background_portrait_tex_coord[0] = 0.0f; background_portrait_tex_coord[1] = 0.0f; background_portrait_tex_coord[2] = tex_x; background_portrait_tex_coord[3] = 0.0f; background_portrait_tex_coord[4] = 0.0f; background_portrait_tex_coord[5] = tex_y; background_portrait_tex_coord[6] = tex_x; background_portrait_tex_coord[7] = tex_y; angle = 0.0f; pos_x = 0.0f; pos_y = 0.0f; //Load a typical arial font to use for our color menu int dpi = bbutil_calculate_dpi(screen_cxt); if (dpi == EXIT_FAILURE) { fprintf(stderr, "Unable to calculate dpi\n"); return EXIT_FAILURE; } //As bbutil renders text using device-specifc dpi, we need to compute a point size //for the font, so that the text string fits into the bubble. Note that Playbook is used //as a reference point in this equation as we know that at dpi of 170, font with point size of //15 fits into the bubble texture. int point_size = (int)(15.0f / ((float)dpi / 170.0f )); font = bbutil_load_font("/usr/fonts/font_repository/monotype/arial.ttf", point_size, dpi); if (!font) { return EXIT_FAILURE; } float text_width, text_height; bbutil_measure_text(font, "Color Menu", &text_width, &text_height); menu_height = text_height + 10.0f + button_size_y * 4; //See if a savefile exists. If not, initialize to a hidden menu and a red cube. if (!read_from_file()) { selected = 3; cube_color[0] = 1.0f; cube_color[1] = 0.0f; cube_color[2] = 0.0f; cube_color[3] = 1.0f; menu_animation = 0.0f; menu_active = false; menu_show_animation = false; menu_hide_animation = false; } //Initialize positions of graphics assets on the screen, but don't resize the surface if (EXIT_FAILURE == resize(NULL)) { fprintf(stderr, "Initialize surface\n"); return EXIT_FAILURE; } //Common gl setup glShadeModel(GL_SMOOTH); glClearColor(1.0f, 1.0f, 1.0f, 1.0f); glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient); glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse); glLightfv(GL_LIGHT0, GL_POSITION, light_pos); glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, light_direction); glEnable(GL_CULL_FACE); menu_show_animation = true; return EXIT_SUCCESS; }
int init() { EGLint surface_width, surface_height; //Load background texture float tex_x, tex_y; int size_x, size_y; if (EXIT_SUCCESS != bbutil_load_texture("app/native/HelloWorld_bubble_portrait.png", &size_x, &size_y, &tex_x, &tex_y, &background)) { fprintf(stderr, "Unable to load background texture\n"); return EXIT_FAILURE; } //Query width and height of the window surface created by utility code eglQuerySurface(egl_disp, egl_surf, EGL_WIDTH, &surface_width); eglQuerySurface(egl_disp, egl_surf, EGL_HEIGHT, &surface_height); EGLint err = eglGetError(); if (err != 0x3000) { fprintf(stderr, "Unable to query EGL surface dimensions\n"); return EXIT_FAILURE; } width = (float) surface_width; height = (float) surface_height; int dpi = bbutil_calculate_dpi(screen_ctx); //As bbutil renders text using device-specifc dpi, we need to compute a point size //for the font, so that the text string fits into the bubble. We use 15 pt as our //font size. // // This app assumes the use of a Z10 in portrait mode. For other devices and // orientations, you need to modify the code and settings accordingly. // font with point size of //15 fits into the bubble texture. const float Z10_DPI = 358.0f; const float FONT_PT_SIZE = 15.0f; float stretch_factor = (float)surface_width / (float)size_x; int point_size = (int)(FONT_PT_SIZE * stretch_factor / ((float)dpi / Z10_DPI )); font = bbutil_load_font("/usr/fonts/font_repository/monotype/arial.ttf", point_size, dpi); if (!font) { return EXIT_FAILURE; } //Initialize GL for 2D rendering glViewport(0, 0, (int) width, (int) height); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrthof(0.0f, width / height, 0.0f, 1.0f, -1.0f, 1.0f); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); //Set world coordinates to coincide with screen pixels glScalef(1.0f / height, 1.0f / height, 1.0f); float text_width, text_height; bbutil_measure_text(font, message, &text_width, &text_height); pos_x = (width - text_width) / 2; pos_y = height / 2; //Setup background polygon vertices[0] = 0.0f; vertices[1] = 0.0f; vertices[2] = width; vertices[3] = 0.0f; vertices[4] = 0.0f; vertices[5] = height; vertices[6] = width; vertices[7] = height; tex_coord[0] = 0.0f; tex_coord[1] = 0.0f; tex_coord[2] = tex_x; tex_coord[3] = 0.0f; tex_coord[4] = 0.0f; tex_coord[5] = tex_y; tex_coord[6] = tex_x; tex_coord[7] = tex_y; return EXIT_SUCCESS; }