#include "EngineExperiments.h"
#include <cstdio>
#include <cstdlib>
#include <string>
#include <cmath>
#include <algorithm>
#include <Utilities\Include_Helpers\GL_Version.h>
#include <glload\gl_load.hpp> // loads the functions declared in glload/gl_*version*.h"
#include <GL/freeglut.h>
#include <ft2build.h>
#include FT_FREETYPE_H
//#include "../common/shader_utils.h"
// BEGIN copy and past of FreeType's shader_utils.cpp
/**
* From the OpenGL Programming wikibook: http://en.wikibooks.org/wiki/OpenGL_Programming
* This file is in the public domain.
* Contributors: Sylvain Beucler
*/
//#include <stdio.h>
//#include <stdlib.h>
//#include <GL/glew.h> // replaced with freeglut and gl_load
/**
* Store all the file's contents in memory, useful to pass shaders
* source code to OpenGL
*/
char* file_read(const char* filename)
{
FILE* in = fopen(filename, "rb");
if (in == NULL) return NULL;
int res_size = BUFSIZ;
char* res = (char*)malloc(res_size);
int nb_read_total = 0;
while (!feof(in) && !ferror(in)) {
if (nb_read_total + BUFSIZ > res_size) {
if (res_size > 10 * 1024 * 1024) break;
res_size = res_size * 2;
res = (char*)realloc(res, res_size);
}
char* p_res = res + nb_read_total;
nb_read_total += fread(p_res, 1, BUFSIZ, in);
}
fclose(in);
res = (char*)realloc(res, nb_read_total + 1);
res[nb_read_total] = '\0';
return res;
}
/**
* Display compilation errors from the OpenGL shader compiler
*/
void print_log(GLuint object)
{
GLint log_length = 0;
if (glIsShader(object))
glGetShaderiv(object, GL_INFO_LOG_LENGTH, &log_length);
else if (glIsProgram(object))
glGetProgramiv(object, GL_INFO_LOG_LENGTH, &log_length);
else {
fprintf(stderr, "printlog: Not a shader or a program\n");
return;
}
char* log = (char*)malloc(log_length);
if (glIsShader(object))
glGetShaderInfoLog(object, log_length, NULL, log);
else if (glIsProgram(object))
glGetProgramInfoLog(object, log_length, NULL, log);
fprintf(stderr, "%s", log);
free(log);
}
/**
* Compile the shader from file 'filename', with error handling
*/
GLuint create_shader(const char* filename, GLenum type)
{
const GLchar* source = file_read(filename);
if (source == NULL) {
fprintf(stderr, "Error opening %s: ", filename); perror("");
return 0;
}
GLuint res = glCreateShader(type);
const GLchar* sources[] = {
// Define GLSL version
#ifdef GL_ES_VERSION_2_0
"#version 100\n" // OpenGL ES 2.0
#else
"#version 120\n" // OpenGL 2.1
#endif
,
// GLES2 precision specifiers
#ifdef GL_ES_VERSION_2_0
// Define default float precision for fragment shaders:
(type == GL_FRAGMENT_SHADER) ?
"#ifdef GL_FRAGMENT_PRECISION_HIGH\n"
"precision highp float; \n"
"#else \n"
"precision mediump float; \n"
"#endif \n"
: ""
// Note: OpenGL ES automatically defines this:
// #define GL_ES
#else
// Ignore GLES 2 precision specifiers:
"#define lowp \n"
"#define mediump\n"
"#define highp \n"
#endif
,
source };
glShaderSource(res, 3, sources, NULL);
free((void*)source);
glCompileShader(res);
GLint compile_ok = GL_FALSE;
glGetShaderiv(res, GL_COMPILE_STATUS, &compile_ok);
if (compile_ok == GL_FALSE) {
fprintf(stderr, "%s:", filename);
print_log(res);
glDeleteShader(res);
return 0;
}
return res;
}
GLuint create_program(const char *vertexfile, const char *fragmentfile) {
GLuint program = glCreateProgram();
GLuint shader;
if (vertexfile) {
shader = create_shader(vertexfile, GL_VERTEX_SHADER);
if (!shader)
return 0;
glAttachShader(program, shader);
}
if (fragmentfile) {
shader = create_shader(fragmentfile, GL_FRAGMENT_SHADER);
if (!shader)
return 0;
glAttachShader(program, shader);
}
glLinkProgram(program);
GLint link_ok = GL_FALSE;
glGetProgramiv(program, GL_LINK_STATUS, &link_ok);
if (!link_ok) {
fprintf(stderr, "glLinkProgram:");
print_log(program);
glDeleteProgram(program);
return 0;
}
return program;
}
#ifdef GL_GEOMETRY_SHADER
GLuint create_gs_program(const char *vertexfile, const char *geometryfile, const char *fragmentfile, GLint input, GLint output, GLint vertices) {
GLuint program = glCreateProgram();
GLuint shader;
if (vertexfile) {
shader = create_shader(vertexfile, GL_VERTEX_SHADER);
if (!shader)
return 0;
glAttachShader(program, shader);
}
if (geometryfile) {
shader = create_shader(geometryfile, GL_GEOMETRY_SHADER);
if (!shader)
return 0;
glAttachShader(program, shader);
glProgramParameteriEXT(program, GL_GEOMETRY_INPUT_TYPE_EXT, input);
glProgramParameteriEXT(program, GL_GEOMETRY_OUTPUT_TYPE_EXT, output);
glProgramParameteriEXT(program, GL_GEOMETRY_VERTICES_OUT_EXT, vertices);
}
if (fragmentfile) {
shader = create_shader(fragmentfile, GL_FRAGMENT_SHADER);
if (!shader)
return 0;
glAttachShader(program, shader);
}
glLinkProgram(program);
GLint link_ok = GL_FALSE;
glGetProgramiv(program, GL_LINK_STATUS, &link_ok);
if (!link_ok) {
fprintf(stderr, "glLinkProgram:");
print_log(program);
glDeleteProgram(program);
return 0;
}
return program;
}
#else
GLuint create_gs_program(const char *vertexfile, const char *geometryfile, const char *fragmentfile, GLint input, GLint output, GLint vertices) {
fprintf(stderr, "Missing support for geometry shaders.\n");
return 0;
}
#endif
GLint get_attrib(GLuint program, const char *name) {
GLint attribute = glGetAttribLocation(program, name);
if (attribute == -1)
fprintf(stderr, "Could not bind attribute %s\n", name);
return attribute;
}
GLint get_uniform(GLuint program, const char *name) {
GLint uniform = glGetUniformLocation(program, name);
if (uniform == -1)
fprintf(stderr, "Could not bind uniform %s\n", name);
return uniform;
}
// END shader_utils.cpp
GLuint program;
GLint attribute_coord;
GLint uniform_tex;
GLint uniform_color;
struct point {
GLfloat x;
GLfloat y;
GLfloat s;
GLfloat t;
};
GLuint vbo;
FT_Library ft;
FT_Face face;
// Maximum texture width
#define MAXWIDTH 1024
const char *fontfilename;
/**
* The atlas struct holds a texture that contains the visible US-ASCII characters
* of a certain font rendered with a certain character height.
* It also contains an array that contains all the information necessary to
* generate the appropriate vertex and texture coordinates for each character.
*
* After the constructor is run, you don't need to use any FreeType functions anymore.
*/
struct atlas {
GLuint tex; // texture object
unsigned int w; // width of texture in pixels
unsigned int h; // height of texture in pixels
struct {
float ax; // advance.x
float ay; // advance.y
float bw; // bitmap.width;
float bh; // bitmap.height;
float bl; // bitmap_left;
float bt; // bitmap_top;
float tx; // x offset of glyph in texture coordinates
float ty; // y offset of glyph in texture coordinates
} c[128]; // character information
atlas(FT_Face face, int height) {
FT_Set_Pixel_Sizes(face, 0, height);
FT_GlyphSlot g = face->glyph;
unsigned int roww = 0;
unsigned int rowh = 0;
w = 0;
h = 0;
memset(c, 0, sizeof c);