#include "gl3w.h" #include #include #include #include FT_FREETYPE_H #include "GLProgram.h" using namespace std; #define WIDTH 500 #define HEIGHT 500 static FT_Library ft; static FT_Face face; static GLProgram program; static GLint uniform_tex; static GLint uniform_color; const char vertex_shader[] = "#version 120\n" "\n" "attribute vec4 coord;\n" "\n" "varying vec2 tex_coord_i;\n" "\n" "void main(void)\n" "{\n" " gl_Position = vec4(coord.xy * 2.0 / 500.0, 0, 1);\n" " tex_coord_i = coord.zw;\n" "}\n"; const char fragment_shader[] = "varying vec2 tex_coord_i;\n" "\n" "uniform sampler2D tex;\n" "uniform vec4 color;\n" "\n" "void main(void)\n" "{\n" " gl_FragColor = vec4(1, 1, 1, texture2D(tex, tex_coord_i).a) * color;\n" "}\n"; void init(void) { glClearColor (0.0, 0.0, 0.0, 0.0); program.create(vertex_shader, fragment_shader, "coord", 0, NULL, "tex", "color", NULL); uniform_tex = program.uniform("tex"); uniform_color = program.uniform("color"); program.use(); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); } void display(SDL_Window * window) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); if (FT_Load_Char(face, 'h', FT_LOAD_RENDER) != 0) { cerr << "Failed to load character" << endl; } GLuint texture_id; glActiveTexture(GL_TEXTURE0); glGenTextures(1, &texture_id); glBindTexture(GL_TEXTURE_2D, texture_id); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, face->glyph->bitmap.width, face->glyph->bitmap.rows, 0, GL_ALPHA, GL_UNSIGNED_BYTE, face->glyph->bitmap.buffer); GLuint vbo; glGenBuffers(1, &vbo); glEnableVertexAttribArray(0); glBindBuffer(GL_ARRAY_BUFFER, vbo); glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0); GLfloat color[4] = {1, 0.6, 0, 1.0}; glUniform1i(uniform_tex, 0); glUniform4fv(uniform_color, 1, color); GLfloat box[4][4] = { {0, 0, 0, 0}, {face->glyph->bitmap.width, 0, 1, 0}, {0, -face->glyph->bitmap.rows, 0, 1}, {face->glyph->bitmap.width, -face->glyph->bitmap.rows, 1, 1} }; glBufferData(GL_ARRAY_BUFFER, sizeof(box), box, GL_STATIC_DRAW); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); SDL_GL_SwapWindow(window); } int main(int argc, char *argv[]) { if (argc < 2) { cerr << "Usage: " << argv[0] << " " << endl; return 1; } if (SDL_Init(SDL_INIT_VIDEO)) { cerr << "Failed to initialize SDL!" << endl; return 1; } atexit(SDL_Quit); SDL_Window * window = SDL_CreateWindow(argv[0], SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, WIDTH, HEIGHT, SDL_WINDOW_OPENGL); if (!window) { cerr << "Failed to create window!" << endl; SDL_Quit(); return 2; } SDL_GLContext gl_context = SDL_GL_CreateContext(window); if (gl3wInit() != 0) { cerr << "Failed to gl3wInit()" << endl; SDL_Quit(); return 2; } if (!gl3wIsSupported(3, 0)) { cerr << "OpenGL 3.0 is not supported!" << endl; SDL_Quit(); return 2; } if (FT_Init_FreeType(&ft) != 0) { cerr << "Could not FT_Init_FreeType()" << endl; return 2; } if (FT_New_Face(ft, argv[1], 0, &face) != 0) { cerr << "Could not load font " << argv[1] << endl; return 2; } FT_Set_Pixel_Sizes(face, 0, 20); init(); display(window); SDL_Event event; while (SDL_WaitEvent(&event)) { if (event.type == SDL_QUIT) break; else if (event.type == SDL_KEYDOWN) { if (event.key.keysym.sym == SDLK_ESCAPE) break; if (event.key.keysym.sym == SDLK_RETURN) display(window); } } }