-
Notifications
You must be signed in to change notification settings - Fork 2
/
gpu.c
156 lines (128 loc) · 4.8 KB
/
gpu.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
154
155
156
#include "./common.h"
GLuint compile_shader_file(const char *file_path, GLenum shader_type)
{
char *buffer = cstr_slurp_file(file_path);
const GLchar * const source_cstr = buffer;
GLuint shader = glCreateShader(shader_type);
glShaderSource(shader, 1, &source_cstr, NULL);
glCompileShader(shader);
GLint compiled;
glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
if (compiled != GL_TRUE) {
GLchar log[1024];
GLsizei log_size = 0;
glGetShaderInfoLog(shader, sizeof(log), &log_size, log);
fprintf(stderr, "Failed to compile %s:%.*s\n", file_path,
log_size, log);
exit(1);
}
free(buffer);
return shader;
}
GLuint link_program(GLuint vert_shader, GLuint frag_shader)
{
GLuint program = glCreateProgram();
glAttachShader(program, vert_shader);
glAttachShader(program, frag_shader);
glLinkProgram(program);
GLint linked = 0;
glGetProgramiv(program, GL_LINK_STATUS, &linked);
if (linked != GL_TRUE) {
GLsizei log_size = 0;
GLchar log[1024];
glGetProgramInfoLog(program, sizeof(log), &log_size, log);
fprintf(stderr, "Failed to link the shader program: %.*s\n", log_size, log);
exit(1);
}
return program;
}
int main(void)
{
check_sdl_code(
SDL_Init(SDL_INIT_VIDEO));
SDL_Window * const window =
check_sdl_ptr(
SDL_CreateWindow(
"Bezier Curves",
0, 0,
SCREEN_WIDTH,
SCREEN_HEIGHT,
SDL_WINDOW_RESIZABLE | SDL_WINDOW_OPENGL));
/*SDL_GLContext context = */SDL_GL_CreateContext(window);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
GLuint vert_shader = compile_shader_file("./gpu.vert", GL_VERTEX_SHADER);
GLuint frag_shader = compile_shader_file("./gpu.frag", GL_FRAGMENT_SHADER);
GLuint program = link_program(vert_shader, frag_shader);
glUseProgram(program);
GLint u_p1 = glGetUniformLocation(program, "p1");
GLint u_p2 = glGetUniformLocation(program, "p2");
GLint u_p3 = glGetUniformLocation(program, "p3");
GLint u_marker_radius = glGetUniformLocation(program, "marker_radius");
GLint u_bezier_curve_threshold = glGetUniformLocation(program, "bezier_curve_threshold");
Vec2 p1 = vec2(100.0f, 100.0f);
Vec2 p2 = vec2(200.0f, 200.0f);
Vec2 p3 = vec2(300.0f, 300.0f);
Vec2 *p_selected = NULL;
float bezier_curve_threshold = 10.0f;
int quit = 0;
while (!quit) {
SDL_Event event;
while (SDL_PollEvent(&event)) {
switch (event.type) {
case SDL_QUIT: {
quit = 1;
} break;
case SDL_MOUSEBUTTONDOWN: {
const Vec2 mouse_pos = vec2(
event.button.x,
SCREEN_HEIGHT - event.button.y);
if (event.button.button == SDL_BUTTON_LEFT) {
// TODO: dragging does not work if the window size is not correct
if (vec2_length(vec2_sub(p1, mouse_pos)) < MARKER_SIZE) {
p_selected = &p1;
}
if (vec2_length(vec2_sub(p2, mouse_pos)) < MARKER_SIZE) {
p_selected = &p2;
}
if (vec2_length(vec2_sub(p3, mouse_pos)) < MARKER_SIZE) {
p_selected = &p3;
}
}
} break;
case SDL_MOUSEBUTTONUP: {
if (event.button.button == SDL_BUTTON_LEFT) {
p_selected = NULL;
}
} break;
case SDL_MOUSEMOTION: {
const Vec2 mouse_pos = vec2(
event.button.x,
SCREEN_HEIGHT - event.button.y);
if (p_selected) {
*p_selected = mouse_pos;
}
} break;
case SDL_MOUSEWHEEL: {
#define BEZIER_CURVE_THRESHOLD_STEP 5.0f
if (event.wheel.y > 0) {
bezier_curve_threshold = bezier_curve_threshold + BEZIER_CURVE_THRESHOLD_STEP;
} else if (event.wheel.y < 0) {
bezier_curve_threshold = fmaxf(bezier_curve_threshold - BEZIER_CURVE_THRESHOLD_STEP, 0.0f);
}
} break;
}
}
glViewport(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
glUniform2f(u_p1, p1.x, p1.y);
glUniform2f(u_p2, p2.x, p2.y);
glUniform2f(u_p3, p3.x, p3.y);
glUniform1f(u_marker_radius, MARKER_SIZE);
glUniform1f(u_bezier_curve_threshold, bezier_curve_threshold);
glDrawArrays(GL_QUADS, 0, 4);
SDL_GL_SwapWindow(window);
}
return 0;
}