restructure main, add basic font support
This commit is contained in:
@ -13,6 +13,7 @@ add_executable( gremlin
|
||||
main
|
||||
game
|
||||
Explosion
|
||||
oglfont
|
||||
)
|
||||
|
||||
# set dependencies
|
||||
@ -25,7 +26,7 @@ if (WIN32)
|
||||
endif(WIN32)
|
||||
|
||||
if(UNIX)
|
||||
set(PLATFORM_LIBRARIES GL X11 Xrandr -pthread)
|
||||
set(PLATFORM_LIBRARIES GL X11 Xrandr pthread asound)
|
||||
endif(UNIX)
|
||||
|
||||
target_link_libraries(gremlin
|
||||
|
56
src/Schedule.h
Normal file
56
src/Schedule.h
Normal file
@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Schedule.h
|
||||
*
|
||||
* Created on: 12.06.2010
|
||||
* Author: gmueller
|
||||
*/
|
||||
|
||||
#ifndef SCHEDULE_H_
|
||||
#define SCHEDULE_H_
|
||||
|
||||
class Schedule {
|
||||
double last;
|
||||
double interval;
|
||||
bool exact;
|
||||
bool paused;
|
||||
public:
|
||||
Schedule() :
|
||||
last(0.0), interval(1.0), exact(true), paused(false) {
|
||||
}
|
||||
|
||||
void init(double now) {
|
||||
last = now;
|
||||
}
|
||||
|
||||
void setInterval(double interval) {
|
||||
this->interval = interval;
|
||||
}
|
||||
|
||||
double getInterval() {
|
||||
return interval;
|
||||
}
|
||||
|
||||
void setExact(bool exact) {
|
||||
this->exact = exact;
|
||||
}
|
||||
|
||||
void setPaused(bool paused) {
|
||||
this->paused = paused;
|
||||
}
|
||||
|
||||
bool next(double now) {
|
||||
if (now > (last + interval)) {
|
||||
if (exact)
|
||||
last += interval;
|
||||
else
|
||||
last = now;
|
||||
if (paused)
|
||||
return false;
|
||||
else
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
};
|
||||
#endif /* SCHEDULE_H_ */
|
311
src/main.cpp
311
src/main.cpp
@ -9,6 +9,8 @@
|
||||
#include "common.h"
|
||||
#include "game.h"
|
||||
#include "Explosion.h"
|
||||
#include "Schedule.h"
|
||||
#include "oglfont.h"
|
||||
|
||||
GLUquadricObj *quadratic;
|
||||
ENetHost *host;
|
||||
@ -61,7 +63,7 @@ void setup_opengl() {
|
||||
glEnable( GL_LIGHTING);
|
||||
|
||||
// Enable vertical sync (on cards that support it)
|
||||
glfwSwapInterval(1);
|
||||
glfwSwapInterval(0);
|
||||
}
|
||||
|
||||
void draw_team(team_t *team) {
|
||||
@ -456,19 +458,80 @@ void explosion_callback(double x, double y, double z) {
|
||||
explosion.add(x, y, z);
|
||||
}
|
||||
|
||||
int main(int argc, char ** argv) {
|
||||
int width, height, x, y, last_x, last_y;
|
||||
double time, last_time, phi = 0.0, theta = 0.0, last_player_update,
|
||||
last_bomb;
|
||||
GLboolean running;
|
||||
int server = 0;
|
||||
class Application {
|
||||
public:
|
||||
void initialize(int argc, char ** argv);
|
||||
void update();
|
||||
void shutdown();
|
||||
bool isRunning();
|
||||
private:
|
||||
bool running;
|
||||
double last_time, last_bomb; //TODO: use bomb schedule;
|
||||
int last_x, last_y;
|
||||
double phi, theta;
|
||||
double camX, camY, camZ;
|
||||
Schedule accelerate_schudule;
|
||||
Schedule player_update_schudule;
|
||||
game_t game;
|
||||
int server;
|
||||
int width, height;
|
||||
//TrueTyeFont font;
|
||||
oglf_font_t font;
|
||||
|
||||
void prepareFrame(double rx, double ry, double rz);
|
||||
|
||||
void loadConsoleFont();
|
||||
};
|
||||
|
||||
void Application::loadConsoleFont() {
|
||||
GLuint font_id = 0;
|
||||
|
||||
glGenTextures(1, &font_id);
|
||||
glBindTexture(GL_TEXTURE_2D, font_id);
|
||||
|
||||
// Set texture parameters
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
|
||||
// Upload texture from file to texture memory
|
||||
glfwLoadTexture2D("data/fonts/console.tga", 0);
|
||||
oglf_load(&font, "data/fonts/console.fnt", font_id);
|
||||
}
|
||||
void Application::prepareFrame(double rx, double ry, double rz) {
|
||||
// Get window size (may be different than the requested size)
|
||||
glfwGetWindowSize(&width, &height);
|
||||
height = height > 0 ? height : 1;
|
||||
|
||||
// Set viewport
|
||||
glViewport(0, 0, width, height);
|
||||
|
||||
// Clear color buffer
|
||||
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
// Select and setup the projection matrix
|
||||
glMatrixMode( GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
gluPerspective(60.0f, (GLfloat) width / (GLfloat) height, 1.0f, 10000.0f);
|
||||
|
||||
// Select and setup the modelview matrix
|
||||
glMatrixMode( GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
gluLookAt(camX, camY, camZ, camX + rx * 10.0f, camY + ry * 10.0f, camZ + rz
|
||||
* 10.0f, 0.0f, 1.0f, 0.0f);
|
||||
|
||||
}
|
||||
|
||||
void Application::initialize(int argc, char ** argv) {
|
||||
server = 0;
|
||||
double time, last_player_update;
|
||||
|
||||
quadratic = gluNewQuadric();
|
||||
gluQuadricNormals(quadratic, GLU_SMOOTH);
|
||||
gluQuadricTexture(quadratic, GL_TRUE);
|
||||
|
||||
game_t game;
|
||||
|
||||
game_setup(&game);
|
||||
|
||||
setup_opengl();
|
||||
@ -484,44 +547,56 @@ int main(int argc, char ** argv) {
|
||||
team_t *team = game_team(&game, 0);
|
||||
local_player = game_spawn_player(&game, team);
|
||||
}
|
||||
float plane_color[] = { 0.2f, 0.3f, 0.4f, 1.0f };
|
||||
size_t i;
|
||||
running = GL_TRUE;
|
||||
last_time = glfwGetTime();
|
||||
last_player_update = last_time;
|
||||
last_bomb = last_time;
|
||||
double camX, camY, camZ;
|
||||
glfwGetMousePos(&last_x, &last_y);
|
||||
while (running) {
|
||||
// Get time and mouse position
|
||||
time = glfwGetTime();
|
||||
double dt = time - last_time;
|
||||
glfwGetMousePos(&x, &y);
|
||||
if (glfwGetMouseButton(GLFW_MOUSE_BUTTON_2) == GLFW_PRESS) {
|
||||
phi += (x - last_x) * 0.01;
|
||||
theta += (y - last_y) * -0.01;
|
||||
if (theta > 1.5)
|
||||
theta = 1.5;
|
||||
if (theta < -1.5)
|
||||
theta = -1.5;
|
||||
}
|
||||
last_x = x;
|
||||
last_y = y;
|
||||
|
||||
if (local_player) {
|
||||
camX = local_player->x;
|
||||
camY = local_player->y;
|
||||
camZ = local_player->z;
|
||||
} else {
|
||||
camX = 1000.0;
|
||||
camY = 1000.0;
|
||||
camZ = 1000.0;
|
||||
}
|
||||
accelerate_schudule.setExact(true);
|
||||
accelerate_schudule.setInterval(0.05);
|
||||
|
||||
double rx = cos(phi) * cos(theta);
|
||||
double ry = sin(theta);
|
||||
double rz = sin(phi) * cos(theta);
|
||||
double v = 50.0f * dt;
|
||||
player_update_schudule.setExact(true);
|
||||
player_update_schudule.setInterval(0.1);
|
||||
|
||||
loadConsoleFont();
|
||||
}
|
||||
|
||||
void Application::update() {
|
||||
|
||||
// Get time and mouse position
|
||||
double time = glfwGetTime();
|
||||
double dt = time - last_time;
|
||||
int x, y;
|
||||
glfwGetMousePos(&x, &y);
|
||||
if (glfwGetMouseButton(GLFW_MOUSE_BUTTON_2) == GLFW_PRESS) {
|
||||
phi += (x - last_x) * 0.01;
|
||||
theta += (y - last_y) * -0.01;
|
||||
if (theta > 1.5)
|
||||
theta = 1.5;
|
||||
if (theta < -1.5)
|
||||
theta = -1.5;
|
||||
}
|
||||
last_x = x;
|
||||
last_y = y;
|
||||
|
||||
if (local_player) {
|
||||
camX = local_player->x;
|
||||
camY = local_player->y;
|
||||
camZ = local_player->z;
|
||||
} else {
|
||||
camX = 1000.0;
|
||||
camY = 1000.0;
|
||||
camZ = 1000.0;
|
||||
}
|
||||
|
||||
double rx = cos(phi) * cos(theta);
|
||||
double ry = sin(theta);
|
||||
double rz = sin(phi) * cos(theta);
|
||||
if (accelerate_schudule.next(time)) {
|
||||
double t = accelerate_schudule.getInterval();
|
||||
double v = 50.0 * t;
|
||||
if (glfwGetKey('W')) {
|
||||
accelerate(&game, rx * v, ry * v, rz * v);
|
||||
} else if (glfwGetKey('S')) {
|
||||
@ -535,101 +610,89 @@ int main(int argc, char ** argv) {
|
||||
}
|
||||
|
||||
if (glfwGetKey(GLFW_KEY_SPACE)) {
|
||||
accelerate(&game, local_player->vx * -dt, local_player->vy * -dt,
|
||||
local_player->vz * -dt);
|
||||
accelerate(&game, local_player->vx * -0.1, local_player->vy * -0.1,
|
||||
local_player->vz * -0.1);
|
||||
}
|
||||
|
||||
if (glfwGetKey(GLFW_KEY_LCTRL)) {
|
||||
if (time - last_bomb > 5.0) {
|
||||
last_bomb = time;
|
||||
drop_bomb(&game, local_player->x + rx - 20.0, local_player->y
|
||||
+ ry * -20.0, local_player->z + rz * -20.0, 5.0);
|
||||
}
|
||||
}
|
||||
|
||||
if (glfwGetKey(GLFW_KEY_ENTER)) {
|
||||
explosion.add(200.0, 200.0, 200.0);
|
||||
}
|
||||
|
||||
// Get window size (may be different than the requested size)
|
||||
glfwGetWindowSize(&width, &height);
|
||||
height = height > 0 ? height : 1;
|
||||
|
||||
// Set viewport
|
||||
glViewport(0, 0, width, height);
|
||||
|
||||
// Clear color buffer
|
||||
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
// Select and setup the projection matrix
|
||||
glMatrixMode( GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
gluPerspective(60.0f, (GLfloat) width / (GLfloat) height, 1.0f,
|
||||
10000.0f);
|
||||
|
||||
// Select and setup the modelview matrix
|
||||
glMatrixMode( GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
gluLookAt(camX, camY, camZ, camX + cos(phi) * cos(theta) * 10.0f, camY
|
||||
+ sin(theta) * 10.0f, camZ + sin(phi) * cos(theta) * 10.0f, // View-point
|
||||
0.0f, 1.0f, 0.0f); // Up-vector
|
||||
|
||||
service_network(&game);
|
||||
if (server) {
|
||||
if (time > last_player_update + 0.1) {
|
||||
send_player_updates(&game);
|
||||
last_player_update = time;
|
||||
}
|
||||
}
|
||||
|
||||
game_update_players(&game, dt);
|
||||
game_update_bombs(&game, dt, explosion_callback);
|
||||
|
||||
glEnable( GL_LIGHT0);
|
||||
glEnable( GL_LIGHTING);
|
||||
glEnable( GL_CULL_FACE);
|
||||
|
||||
glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, plane_color);
|
||||
// Draw a textured quad
|
||||
glBegin( GL_QUADS);
|
||||
glVertex3f(-5000.0f, 5000.0f, -5000.0f);
|
||||
glVertex3f(5000.0f, 5000.0f, -5000.0f);
|
||||
glVertex3f(5000.0f, 5000.0f, 5000.0f);
|
||||
glVertex3f(-5000.0f, 5000.0f, 5000.0f);
|
||||
glEnd();
|
||||
for (i = 0; i < GAME_TEAM_COUNT; i++)
|
||||
draw_team(&game.team[i]);
|
||||
|
||||
for (i = 0; i < GAME_PLAYER_COUNT; i++)
|
||||
draw_player(&game.player[i]);
|
||||
|
||||
for (i = 0; i < GAME_BOMB_COUNT; i++)
|
||||
draw_bomb(&game.bomb[i]);
|
||||
|
||||
glDisable(GL_LIGHT0);
|
||||
glDisable(GL_LIGHTING);
|
||||
glDisable(GL_CULL_FACE);
|
||||
explosion.update(dt * 1000.0, camX, camY, camZ);
|
||||
explosion.render();
|
||||
|
||||
// Swap buffers
|
||||
glfwSwapBuffers();
|
||||
|
||||
// Check if the ESC key was pressed or the window was closed
|
||||
running = !glfwGetKey(GLFW_KEY_ESC) && glfwGetWindowParam(GLFW_OPENED);
|
||||
|
||||
last_time = time;
|
||||
}
|
||||
if (glfwGetKey(GLFW_KEY_LCTRL)) {
|
||||
if (time - last_bomb > 5.0) {
|
||||
last_bomb = time;
|
||||
drop_bomb(&game, local_player->x + rx * 20.0, local_player->y + ry
|
||||
* 20.0, local_player->z + rz * 20.0, 5.0);
|
||||
}
|
||||
}
|
||||
|
||||
prepareFrame(rx, ry, rz);
|
||||
|
||||
glEnable( GL_LIGHT0);
|
||||
glEnable( GL_LIGHTING);
|
||||
glEnable( GL_CULL_FACE);
|
||||
const float plane_color[] = { 0.2f, 0.3f, 0.4f, 1.0f };
|
||||
glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, plane_color);
|
||||
// Draw a textured quad
|
||||
glBegin( GL_QUADS);
|
||||
glVertex3f(-5000.0f, 5000.0f, -5000.0f);
|
||||
glVertex3f(5000.0f, 5000.0f, -5000.0f);
|
||||
glVertex3f(5000.0f, 5000.0f, 5000.0f);
|
||||
glVertex3f(-5000.0f, 5000.0f, 5000.0f);
|
||||
glEnd();
|
||||
for (size_t i = 0; i < GAME_TEAM_COUNT; i++)
|
||||
draw_team(&game.team[i]);
|
||||
|
||||
for (size_t i = 0; i < GAME_PLAYER_COUNT; i++)
|
||||
draw_player(&game.player[i]);
|
||||
|
||||
for (size_t i = 0; i < GAME_BOMB_COUNT; i++)
|
||||
draw_bomb(&game.bomb[i]);
|
||||
|
||||
glDisable(GL_LIGHT0);
|
||||
glDisable(GL_LIGHTING);
|
||||
glDisable(GL_CULL_FACE);
|
||||
explosion.update(dt * 1000.0, camX, camY, camZ);
|
||||
explosion.render();
|
||||
|
||||
oglf_begin(&font, width, height);
|
||||
oglf_print(&font, 40, 40, "Hello");
|
||||
oglf_end();
|
||||
|
||||
// Swap buffers
|
||||
glfwSwapBuffers();
|
||||
|
||||
// Check if the ESC key was pressed or the window was closed
|
||||
running = !glfwGetKey(GLFW_KEY_ESC) && glfwGetWindowParam(GLFW_OPENED);
|
||||
service_network(&game);
|
||||
if (server && player_update_schudule.next(time)) {
|
||||
send_player_updates(&game);
|
||||
}
|
||||
|
||||
game_update_players(&game, dt);
|
||||
game_update_bombs(&game, dt, explosion_callback);
|
||||
|
||||
last_time = time;
|
||||
|
||||
}
|
||||
|
||||
void Application::shutdown() {
|
||||
|
||||
gluDeleteQuadric(quadratic);
|
||||
|
||||
enet_host_destroy(host);
|
||||
enet_deinitialize();
|
||||
|
||||
oglf_destroy(&font);
|
||||
// Close OpenGL window and terminate GLFW
|
||||
glfwTerminate();
|
||||
}
|
||||
|
||||
bool Application::isRunning() {
|
||||
return running;
|
||||
}
|
||||
|
||||
int main(int argc, char ** argv) {
|
||||
Application app;
|
||||
app.initialize(argc, argv);
|
||||
while (app.isRunning())
|
||||
app.update();
|
||||
app.shutdown();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
270
src/oglfont.cpp
Normal file
270
src/oglfont.cpp
Normal file
@ -0,0 +1,270 @@
|
||||
#include "oglfont.h"
|
||||
#include <GL/gl.h>
|
||||
#include <GL/glu.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#define GL_Y_FIX(f) (1 - (f))
|
||||
static void _compile(oglf_font_t *font) {
|
||||
int chr;
|
||||
|
||||
font->base_list = glGenLists(OGLF_MAX_ASCII);
|
||||
glBindTexture(GL_TEXTURE_2D, font->fontTex);
|
||||
|
||||
for (chr = 0; chr < OGLF_MAX_ASCII; chr++) {
|
||||
glNewList(font->base_list + chr - 1, GL_COMPILE);
|
||||
|
||||
if (font->chars[chr].w) {
|
||||
glBegin(GL_QUADS);
|
||||
glTexCoord2f(
|
||||
(float) font->chars[chr].x / (float) font->w,
|
||||
(float) GL_Y_FIX((font->chars[chr].y+font->chars[chr].h) / (float) font->h));
|
||||
glVertex2d((float) font->chars[chr].x_ofs,
|
||||
(float) font->chars[chr].h + font->chars[chr].y_ofs);
|
||||
|
||||
glTexCoord2f(
|
||||
(float) (font->chars[chr].x + font->chars[chr].w)
|
||||
/ (float) font->w,
|
||||
(float) GL_Y_FIX((font->chars[chr].y + font->chars[chr].h) / (float) font->h));
|
||||
glVertex2d((float) font->chars[chr].w + font->chars[chr].x_ofs,
|
||||
(float) font->chars[chr].h + font->chars[chr].y_ofs);
|
||||
|
||||
glTexCoord2f((float) (font->chars[chr].x + font->chars[chr].w)
|
||||
/ (float) font->w,
|
||||
(float) GL_Y_FIX( font->chars[chr].y / (float) font->h));
|
||||
glVertex2d((float) font->chars[chr].w + font->chars[chr].x_ofs,
|
||||
(float) font->chars[chr].y_ofs);
|
||||
|
||||
glTexCoord2f((float) font->chars[chr].x / (float) font->w,
|
||||
(float) GL_Y_FIX( font->chars[chr].y / (float) font->h));
|
||||
glVertex2d((float) font->chars[chr].x_ofs,
|
||||
(float) font->chars[chr].y_ofs);
|
||||
glEnd();
|
||||
glTranslatef((float) (font->chars[chr].x_advance
|
||||
), 0, 0);
|
||||
} else {
|
||||
// if char has no width, treat it like a space
|
||||
glTranslatef((float) font->base, 0, 0);
|
||||
}
|
||||
|
||||
glEndList();
|
||||
}
|
||||
}
|
||||
|
||||
static int _starts_with(const char *buffer, const char *text) {
|
||||
const char *text_ptr = text;
|
||||
const char *buffer_ptr = buffer;
|
||||
while (*text_ptr != 0) {
|
||||
|
||||
if (*text_ptr != *buffer_ptr)
|
||||
return 0;
|
||||
|
||||
text_ptr++;
|
||||
buffer_ptr++;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int _parse_line(oglf_font_t *font, char *buffer) {
|
||||
|
||||
if (_starts_with(buffer, "common")) {
|
||||
int count = sscanf(buffer,
|
||||
"common lineHeight=%d base=%d scaleW=%d scaleH=%d pages=%d\n",
|
||||
&font->line_h, &font->base, &font->w, &font->h, &font->pages);
|
||||
|
||||
if (count != 5)
|
||||
return 0;
|
||||
} else if (_starts_with(buffer, "char ")) {
|
||||
oglf_char_t temp_char;
|
||||
int id;
|
||||
int
|
||||
count =
|
||||
sscanf(
|
||||
buffer,
|
||||
"char id=%d x=%d y=%d width=%d height=%d xoffset=%d yoffset=%d xadvance=%d page=%d chnl=%*d\n",
|
||||
&id, &temp_char.x, &temp_char.y, &temp_char.w,
|
||||
&temp_char.h, &temp_char.x_ofs,
|
||||
&temp_char.y_ofs, &temp_char.x_advance,
|
||||
&temp_char.page);
|
||||
font->chars[id] = temp_char;
|
||||
|
||||
if (count != 9)
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int oglf_load(oglf_font_t *font, const char *bmf_path, unsigned int texture) {
|
||||
FILE *file;
|
||||
char buffer[256];
|
||||
|
||||
file = fopen(bmf_path, "r"); // could not open file for read
|
||||
if (file == 0)
|
||||
return 0;
|
||||
|
||||
font->chars = (oglf_char_t *) malloc(OGLF_MAX_ASCII * sizeof(oglf_char_t));
|
||||
|
||||
while (fgets(buffer, sizeof(buffer), file) != 0) {
|
||||
int result = _parse_line(font, buffer);
|
||||
if (result == 0)
|
||||
return 0;
|
||||
}
|
||||
|
||||
fclose(file); // close the source file
|
||||
|
||||
font->fontTex = texture;
|
||||
font->scale = 1.f;
|
||||
|
||||
_compile(font);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
// calculate the approx. width of a string of text
|
||||
// note: no kerning info is currently evaluated
|
||||
int oglf_width(oglf_font_t *font, const char *text) {
|
||||
int w, l, i;
|
||||
w = 0;
|
||||
l = strlen(text);
|
||||
for (i = 0; i < l; i++) {
|
||||
//w += font->chars[text[i]].w;
|
||||
w += font->chars[text[i]].x_advance;
|
||||
}
|
||||
return w;
|
||||
}
|
||||
|
||||
// destroy the charset
|
||||
void oglf_destroy(oglf_font_t *font) {
|
||||
glDeleteLists(font->base_list, OGLF_MAX_ASCII);
|
||||
glDeleteTextures(1, &font->fontTex);
|
||||
free(font->chars);
|
||||
}
|
||||
/*
|
||||
void ogl___font_in(ogl_font *font);
|
||||
|
||||
void bmf___font_in(ogl_font *font) {
|
||||
ogl___font_in(font);
|
||||
}
|
||||
|
||||
|
||||
|
||||
*/
|
||||
|
||||
void oglf_begin(oglf_font_t *font, int width, int height) {
|
||||
glPushAttrib(GL_LIST_BIT | GL_CURRENT_BIT | GL_ENABLE_BIT
|
||||
| GL_TRANSFORM_BIT);
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glDisable(GL_LIGHTING);
|
||||
glDisable(GL_CULL_FACE);
|
||||
//glNormal3f( 0.0, 0.0, 1.0);
|
||||
|
||||
// set projection matrix
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glPushMatrix();
|
||||
glLoadIdentity();
|
||||
//int newheight = (_width / 16.0) * 9.0;
|
||||
glOrtho(0.0,
|
||||
(double)width,
|
||||
(double)height,
|
||||
0.0,
|
||||
-1.0,
|
||||
1.0);
|
||||
// prepare model matrix
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPushMatrix();
|
||||
glLoadIdentity();
|
||||
//glScalef(font->scale, font->scale, 1.f);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, font->fontTex);
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
|
||||
glAlphaFunc(GL_GEQUAL,0.1);
|
||||
glEnable(GL_ALPHA_TEST);
|
||||
}
|
||||
|
||||
void oglf_print_l(oglf_font_t *font, float x, float y, const char *text, int l) {
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPushMatrix();
|
||||
glTranslatef(x, y, 0);
|
||||
glCallLists(l, GL_UNSIGNED_BYTE, text);
|
||||
glPopMatrix();
|
||||
}
|
||||
|
||||
void oglf_end() {
|
||||
glPopAttrib();
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glPopMatrix();
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPopMatrix();
|
||||
}
|
||||
|
||||
void oglf_print(oglf_font_t *font, float x, float y, const char *text) {
|
||||
oglf_print_l(font, x, y, text, strlen(text));
|
||||
}
|
||||
|
||||
void oglf_printf(oglf_font_t *font, int x, int y, const char *fmt, ...) {
|
||||
char text[OGLF_MAX_LINE], *line_start, *c;
|
||||
float h;
|
||||
va_list ap;
|
||||
int row;
|
||||
|
||||
if (strlen(fmt) == 0)
|
||||
return;
|
||||
|
||||
va_start(ap, fmt);
|
||||
vsprintf(text, fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
line_start = text;
|
||||
row = 0;
|
||||
h = font->h / .63f;
|
||||
|
||||
NextL: c = strchr(line_start, '\n');
|
||||
if (c) {
|
||||
row++;
|
||||
oglf_print_l(font, (float) x, (float) (y - h * row), line_start, c
|
||||
- line_start);
|
||||
line_start = c + 1;
|
||||
goto NextL;
|
||||
}
|
||||
|
||||
oglf_print_l(font, (float) x, (float) (y - h * row), line_start, strlen(
|
||||
line_start));
|
||||
}
|
||||
|
||||
/*
|
||||
#define OGLF_CENTER_TEXT(rect, txtw, ofs) ((float)((rect[ofs+_W] - txtw - rect[ofs])/2 + rect[ofs]))
|
||||
|
||||
// printf function which takes in account the alignment
|
||||
void ogl_printf_al(oglf_font_t *font, alignment align, GLuint *rect,
|
||||
const char *fmt, ...) {
|
||||
char text[BMF_MAX_LINE];
|
||||
va_list ap;
|
||||
|
||||
if (!strlen(fmt))
|
||||
return;
|
||||
|
||||
va_start(ap, fmt);
|
||||
vsprintf(text, fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
switch (align) {
|
||||
case al_left:
|
||||
ogl_print(font, (float) rect[_X],
|
||||
OGLF_CENTER_TEXT(rect, font->line_h, _Y), text);
|
||||
break;
|
||||
case al_right:
|
||||
ogl_print(font, ((float) rect[_W] - ogl__width(font, text)),
|
||||
OGLF_CENTER_TEXT(rect, font->line_h, _Y), text);
|
||||
break;
|
||||
case al_center:
|
||||
ogl_print(font, OGLF_CENTER_TEXT(rect, ogl__width(font, text), _X),
|
||||
OGLF_CENTER_TEXT(rect, font->line_h, _Y), text);
|
||||
break;
|
||||
}
|
||||
}
|
||||
*/
|
49
src/oglfont.h
Normal file
49
src/oglfont.h
Normal file
@ -0,0 +1,49 @@
|
||||
#ifndef OGLF_H_
|
||||
#define OGLF_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define OGLF_MAX_ASCII 256
|
||||
#define OGLF_MAX_LINE 1024
|
||||
#define OGLF_MAX_PATH 256
|
||||
|
||||
typedef struct oglf_char_t {
|
||||
unsigned int x, y, w, h;
|
||||
unsigned int x_ofs, y_ofs;
|
||||
unsigned int x_advance, page;
|
||||
} oglf_char_t;
|
||||
|
||||
typedef struct oglf_kerninfo_t {
|
||||
unsigned short first, second;
|
||||
short kerning;
|
||||
} oglf_kerninfo_t;
|
||||
|
||||
typedef struct oglf_font_t {
|
||||
float scale;
|
||||
int base, line_h, w, h, pages, kerninfo_count;
|
||||
unsigned int fontTex;
|
||||
int base_list;
|
||||
oglf_kerninfo_t *kerninfo;
|
||||
oglf_char_t *chars;
|
||||
float mmat[16];
|
||||
} oglf_font_t;
|
||||
|
||||
int oglf_load(oglf_font_t *font, const char *bmf_path, unsigned int texture);
|
||||
int oglf_width(oglf_font_t *font, const char *text);
|
||||
void oglf_destroy(oglf_font_t *font);
|
||||
|
||||
void oglf_begin(oglf_font_t *font, int width, int height);
|
||||
void oglf_end();
|
||||
|
||||
void oglf_print(oglf_font_t *font, float x, float y, const char *text);
|
||||
void oglf_printf_al(oglf_font_t *font, int align, unsigned int *rect,
|
||||
const char *fmt, ...);
|
||||
void oglf_printf(oglf_font_t *font, int x, int y, const char *fmt, ...);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // _FONT_H_
|
Reference in New Issue
Block a user