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
|
#include <stdbool.h>
#include <stdio.h>
#include <SDL2/SDL.h>
#include <SDL2/SDL_opengles2.h>
#include "quark.h"
#include "render.h"
/* shader handles */
static GLuint prog = 0;
static GLint u_res;
static GLint u_color;
static GLuint vbo = 0;
/* helpers */
static GLuint compile(GLenum type, const char* src);
static GLuint compile(GLenum type, const char* src)
{
GLuint s = glCreateShader(type);
glShaderSource(s, 1, &src, NULL);
glCompileShader(s);
GLint ok;
glGetShaderiv(s, GL_COMPILE_STATUS, &ok);
if (!ok) {
char log[512];
glGetShaderInfoLog(s, sizeof(log), NULL, log);
LOG_ERROR("renderer: shader error: %s", log);
glDeleteShader(s);
return 0;
}
return s;
}
void render_begin(int w, int h)
{
glViewport(0, 0, w, h);
glClearColor(0.0, 0.0, 0.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT);
glUseProgram(prog);
glUniform2f(u_res, w, h);
}
void render_end(SDL_Window* win)
{
SDL_GL_SwapWindow(win);
}
bool render_init(void)
{
const char* vs =
"attribute vec2 a_pos;"
"uniform vec2 u_res;"
"void main() {"
"vec2 p = a_pos / u_res;"
"p.y = 1.0 - p.y;"
"p = p * 2.0 - 1.0;"
" gl_Position = vec4(p, 0.0, 1.0);"
"}";
const char* fs =
"precision mediump float;"
"uniform vec4 u_color;"
"void main()"
"{"
" gl_FragColor = u_color;"
"}";
GLuint v = compile(GL_VERTEX_SHADER, vs);
GLuint f = compile(GL_FRAGMENT_SHADER, fs);
if (!v || !f)
return false;
prog = glCreateProgram();
glAttachShader(prog, v);
glAttachShader(prog, f);
glBindAttribLocation(prog, 0, "a_pos");
glLinkProgram(prog);
glDeleteShader(v);
glDeleteShader(f);
GLint ok;
glGetProgramiv(prog, GL_LINK_STATUS, &ok);
if (!ok) {
LOG_ERROR("renderer: program link failed");
return false;
}
u_res = glGetUniformLocation(prog, "u_res");
u_color = glGetUniformLocation(prog, "u_color");
glGenBuffers(1, &vbo);
return true;
}
void render_rect(float x, float y, float w, float h, float r, float g, float b, float a)
{
float verts[12] = {
x, y,
x+w, y,
x+w, y+h,
x, y,
x+w, y+h,
x, y+h
};
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(verts), verts, GL_STREAM_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, 0);
glUniform4f(u_color, r, g, b, a);
glDrawArrays(GL_TRIANGLES, 0, 6);
}
void render_shutdown(void)
{
glDeleteProgram(prog);
glDeleteBuffers(1, &vbo);
}
|