-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathlabel.c
153 lines (113 loc) · 3.32 KB
/
label.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
#include <string.h>
#include <stdlib.h>
#include "panic.h"
#include "label.h"
#include "linmath.h"
#include "shader.h"
#include "objects.h"
#include "constants.h"
static GLuint glyphVAO(void)
{
static int loaded = 0;
static GLuint vao;
static GLfloat vertices[] = {
0.5f, 0.5f, 0.0f, 1.0f, 0.0f, /* top-right */
0.5f, -0.5f, 0.0f, 1.0f, 1.0f, /* bottom-right */
-0.5f, -0.5f, 0.0f, 0.0f, 1.0f, /* bottom-left */
-0.5f, 0.5f, 0.0f, 0.0f, 0.0f /* top-left */
};
static GLuint indices[] = {
0, 1, 3,
1, 2, 3
};
if (loaded)
return vao;
GLuint vbo;
glGenBuffers(1, &vbo);
GLuint ebo;
glGenBuffers(1, &ebo);
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof (vertices), vertices, GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof (indices), indices, GL_STATIC_DRAW);
glVertexAttribPointer(VERTEX_VAO, 3, GL_FLOAT, GL_FALSE,
5 * sizeof (GLfloat), (GLvoid *) 0);
glEnableVertexAttribArray(VERTEX_VAO);
glVertexAttribPointer(TEXTURE_VAO, 2, GL_FLOAT, GL_FALSE,
5 * sizeof (GLfloat), (GLvoid *) (3 * sizeof (GLfloat)));
glEnableVertexAttribArray(TEXTURE_VAO);
glBindVertexArray(0);
loaded = 1;
return vao;
}
static struct glyph * find_glyph(const struct list *glyphs, char ch)
{
for (struct node *n = glyphs->first; n; n = n->next) {
struct glyph *g = (struct glyph *) n->data;
if (g->character == ch)
return g;
}
return NULL;
}
static void glyph_draw(const struct glyph *g, GLfloat x, GLfloat y, GLuint shader_program)
{
mat4x4 model_matrix;
mat4x4 normal_matrix;
mat4x4_identity(model_matrix);
mat4x4_translate_in_place(model_matrix, x, y, -1.0);
//mat4x4_scale_aniso(model_matrix, model_matrix, 3 , 3 , 3 );
mat4x4_invert(normal_matrix, model_matrix);
mat4x4_transpose(normal_matrix, normal_matrix);
shader_set_uniform_m4(shader_program, "model", model_matrix);
shader_set_uniform_m4(shader_program, "normalModel", normal_matrix);
shader_set_uniform_i(shader_program, "objectType", OBJECT_GLYPH);
glBindTexture(GL_TEXTURE_2D, g->texture);
glBindVertexArray(glyphVAO());
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
glBindVertexArray(0);
}
struct label *
label_new(const char *text, GLfloat x, GLfloat y,
struct font *f)
{
struct label *l;
l = malloc(sizeof *l);
l->x = x;
l->y = y;
l->font = f;
l->text = strdup(text);
l->visible = 1;
return l;
}
void label_draw(void *object, GLuint shader_program)
{
struct label *l = (struct label *) object;
if (!l->visible)
return;
char *ch = l->text;
float x = l->x;
while (*ch) {
struct glyph *g;
g = find_glyph(l->font->glyphs, *ch);
if (g != NULL)
glyph_draw(g, x, l->y, shader_program);
++ch;
x += 1.2f;
}
}
void label_destroy(struct label *l)
{
free(l->text);
free(l);
}
void label_set_text(struct label *l, const char *text)
{
free(l->text);
l->text = strdup(text);
}
void label_set_visible(struct label *l, int visible)
{
l->visible = visible;
}