gl.h 6.43 KB
Newer Older
TheNumbat's avatar
TheNumbat committed
1
2
3
4
5

#pragma once

#include <string>
#include <unordered_map>
TheNumbat's avatar
TheNumbat committed
6
#include <vector>
TheNumbat's avatar
TheNumbat committed
7
8

#include "../lib/mathlib.h"
TheNumbat's avatar
TheNumbat committed
9
#include <glad/glad.h>
TheNumbat's avatar
TheNumbat committed
10
11
12
13
14
15
16
17
18
19
20
21
22

namespace GL {

void setup();
void shutdown();
std::string version();
std::string renderer();

void global_params();
void clear_screen(Vec4 col);
void viewport(Vec2 dim);
int max_msaa();

TheNumbat's avatar
TheNumbat committed
23
enum class Opt { wireframe, offset, culling, depth_write };
TheNumbat's avatar
TheNumbat committed
24
25
26
27
28
29
30
31
32
33

void enable(Opt opt);
void disable(Opt opt);

void color_mask(bool enable);

using TexID = GLuint;

class Tex2D {
public:
TheNumbat's avatar
TheNumbat committed
34
35
36
37
    Tex2D();
    Tex2D(const Tex2D &src) = delete;
    Tex2D(Tex2D &&src);
    ~Tex2D();
TheNumbat's avatar
TheNumbat committed
38

TheNumbat's avatar
TheNumbat committed
39
40
    void operator=(const Tex2D &src) = delete;
    void operator=(Tex2D &&src);
TheNumbat's avatar
TheNumbat committed
41

TheNumbat's avatar
TheNumbat committed
42
43
44
    void image(int w, int h, unsigned char *img);
    TexID get_id() const;
    void bind(int idx = 0) const;
TheNumbat's avatar
TheNumbat committed
45
46

private:
TheNumbat's avatar
TheNumbat committed
47
    GLuint id;
TheNumbat's avatar
TheNumbat committed
48
49
50
51
};

class Mesh {
public:
TheNumbat's avatar
TheNumbat committed
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
    typedef GLuint Index;
    struct Vert {
        Vec3 pos;
        Vec3 norm;
        GLuint id;
    };

    Mesh();
    Mesh(std::vector<Vert> &&vertices, std::vector<Index> &&indices);
    Mesh(const Mesh &src) = delete;
    Mesh(Mesh &&src);
    ~Mesh();

    void operator=(const Mesh &src) = delete;
    void operator=(Mesh &&src);

    /// Assumes proper shader is already bound
    void render();
    void recreate(std::vector<Vert> &&vertices, std::vector<Index> &&indices);
    std::vector<Vert> &edit_verts();
    std::vector<Index> &edit_indices();

    BBox bbox() const;
    const std::vector<Vert> &verts() const;
    const std::vector<Index> &indices() const;
    GLuint tris() const;
TheNumbat's avatar
TheNumbat committed
78
79

private:
TheNumbat's avatar
TheNumbat committed
80
81
82
    void update();
    void create();
    void destroy();
TheNumbat's avatar
TheNumbat committed
83

TheNumbat's avatar
TheNumbat committed
84
85
86
87
    BBox _bbox;
    GLuint vao = 0, vbo = 0, ebo = 0;
    GLuint n_elem = 0;
    bool dirty = true;
TheNumbat's avatar
TheNumbat committed
88

TheNumbat's avatar
TheNumbat committed
89
90
    std::vector<Vert> _verts;
    std::vector<Index> _idxs;
TheNumbat's avatar
TheNumbat committed
91

TheNumbat's avatar
TheNumbat committed
92
    friend class Instances;
TheNumbat's avatar
TheNumbat committed
93
94
95
96
};

class Instances {
public:
TheNumbat's avatar
TheNumbat committed
97
98
99
100
    Instances(GL::Mesh &&mesh);
    Instances(const Instances &src) = delete;
    Instances(Instances &&src);
    ~Instances();
TheNumbat's avatar
TheNumbat committed
101

TheNumbat's avatar
TheNumbat committed
102
103
    void operator=(const Instances &src) = delete;
    void operator=(Instances &&src);
TheNumbat's avatar
TheNumbat committed
104

TheNumbat's avatar
TheNumbat committed
105
106
107
108
    struct Info {
        GLuint id;
        Mat4 transform;
    };
TheNumbat's avatar
TheNumbat committed
109

TheNumbat's avatar
TheNumbat committed
110
111
112
113
    void render();
    size_t add(const Mat4 &transform, GLuint id = 0);
    Info &get(size_t idx);
    void clear();
TheNumbat's avatar
TheNumbat committed
114
115

private:
TheNumbat's avatar
TheNumbat committed
116
117
118
    void create();
    void destroy();
    void update();
TheNumbat's avatar
TheNumbat committed
119

TheNumbat's avatar
TheNumbat committed
120
121
    GLuint vbo = 0;
    bool dirty = false;
TheNumbat's avatar
TheNumbat committed
122

TheNumbat's avatar
TheNumbat committed
123
124
    Mesh mesh;
    std::vector<Info> data;
TheNumbat's avatar
TheNumbat committed
125
126
127
128
};

class Lines {
public:
TheNumbat's avatar
TheNumbat committed
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
    struct Vert {
        Vec3 pos;
        Vec3 color;
    };

    Lines(float thickness = 1.0f);
    Lines(std::vector<Vert> &&verts, float thickness = 1.0f);
    Lines(const Lines &src) = delete;
    Lines(Lines &&src);
    ~Lines();

    void operator=(const Lines &src) = delete;
    void operator=(Lines &&src);

    /// Assumes proper shader is already bound
    void render(bool smooth) const;
    void add(Vec3 start, Vec3 end, Vec3 color);
    void pop();
    void clear();
TheNumbat's avatar
TheNumbat committed
148
149

private:
TheNumbat's avatar
TheNumbat committed
150
151
152
    void create();
    void destroy();
    void update() const;
TheNumbat's avatar
TheNumbat committed
153

TheNumbat's avatar
TheNumbat committed
154
155
156
    mutable bool dirty = false;
    float thickness = 0.0f;
    GLuint vao = 0, vbo = 0;
TheNumbat's avatar
TheNumbat committed
157

TheNumbat's avatar
TheNumbat committed
158
    std::vector<Vert> vertices;
TheNumbat's avatar
TheNumbat committed
159
160
};

TheNumbat's avatar
TheNumbat committed
161
class Shader {
TheNumbat's avatar
TheNumbat committed
162
public:
TheNumbat's avatar
TheNumbat committed
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
    Shader();
    Shader(std::string vertex_file, std::string fragment_file);
    Shader(const Shader &src) = delete;
    Shader(Shader &&src);
    ~Shader();

    void operator=(const Shader &src) = delete;
    void operator=(Shader &&src);

    void bind() const;
    void load(std::string vertex, std::string fragment);

    void uniform(std::string name, const Mat4 &mat) const;
    void uniform(std::string name, Vec3 vec3) const;
    void uniform(std::string name, Vec2 vec2) const;
    void uniform(std::string name, GLint i) const;
    void uniform(std::string name, GLuint i) const;
    void uniform(std::string name, GLfloat f) const;
    void uniform(std::string name, bool b) const;
    void uniform(std::string name, int count, const Vec2 items[]) const;
    void uniform_block(std::string name, GLuint i) const;
TheNumbat's avatar
TheNumbat committed
184
185

private:
TheNumbat's avatar
TheNumbat committed
186
187
    GLuint loc(std::string name) const;
    static bool validate(GLuint program);
TheNumbat's avatar
TheNumbat committed
188

TheNumbat's avatar
TheNumbat committed
189
190
    GLuint program = 0;
    GLuint v = 0, f = 0;
TheNumbat's avatar
TheNumbat committed
191

TheNumbat's avatar
TheNumbat committed
192
    void destroy();
TheNumbat's avatar
TheNumbat committed
193
194
195
196
197
198
};

/// this is very restrictive; it assumes a set number of gl_rgb8 output
/// textures and a floating point depth render buffer.
class Framebuffer {
public:
TheNumbat's avatar
TheNumbat committed
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
    Framebuffer();
    Framebuffer(int outputs, Vec2 dim, int samples = 1, bool depth = true);
    Framebuffer(const Framebuffer &src) = delete;
    Framebuffer(Framebuffer &&src);
    ~Framebuffer();

    void operator=(const Framebuffer &src) = delete;
    void operator=(Framebuffer &&src);

    static void bind_screen();

    void setup(int outputs, Vec2 dim, int samples, bool d);
    void resize(Vec2 dim, int samples = 1);
    void bind() const;
    bool is_multisampled() const;

    GLuint get_output(int buf) const;
    GLuint get_depth() const;
    void flush() const;
    int samples() const;
    int bytes() const;

    bool can_read_at() const;
    void read_at(int buf, int x, int y, GLubyte *data) const;
    void read(int buf, GLubyte *data) const;

    void blit_to_screen(int buf, Vec2 dim) const;
    void blit_to(int buf, const Framebuffer &fb, bool avg = true) const;

    void clear(int buf, Vec4 col) const;
    void clear_d() const;
TheNumbat's avatar
TheNumbat committed
230
231

private:
TheNumbat's avatar
TheNumbat committed
232
233
    void create();
    void destroy();
TheNumbat's avatar
TheNumbat committed
234

TheNumbat's avatar
TheNumbat committed
235
236
237
    std::vector<GLuint> output_textures;
    GLuint depth_tex = 0;
    GLuint framebuffer = 0;
TheNumbat's avatar
TheNumbat committed
238

TheNumbat's avatar
TheNumbat committed
239
240
    int w = 0, h = 0, s = 0;
    bool depth = true;
TheNumbat's avatar
TheNumbat committed
241

TheNumbat's avatar
TheNumbat committed
242
    friend class Effects;
TheNumbat's avatar
TheNumbat committed
243
244
245
246
};

class Effects {
public:
TheNumbat's avatar
TheNumbat committed
247
248
249
    static void resolve_to_screen(int buf, const Framebuffer &framebuffer);
    static void resolve_to(int buf, const Framebuffer &from, const Framebuffer &to,
                           bool avg = true);
TheNumbat's avatar
TheNumbat committed
250

TheNumbat's avatar
TheNumbat committed
251
252
    static void outline(const Framebuffer &from, const Framebuffer &to, Vec3 color, Vec2 min,
                        Vec2 max);
TheNumbat's avatar
TheNumbat committed
253
254

private:
TheNumbat's avatar
TheNumbat committed
255
256
257
258
259
260
261
262
263
264
265
266
267
268
    static void init();
    static void destroy();

    static inline Shader resolve_shader, outline_shader, outline_shader_ms;
    static inline GLuint vao;
    static inline const Vec2 screen_quad[] = {Vec2{-1.0f, 1.0f}, Vec2{-1.0f, -1.0f},
                                              Vec2{1.0f, 1.0f}, Vec2{1.0f, -1.0f}};

    friend void setup();
    friend void shutdown();

    static const std::string effects_v;
    static const std::string outline_f, outline_ms_f_33, outline_ms_f_4;
    static const std::string resolve_f;
TheNumbat's avatar
TheNumbat committed
269
270
271
};

namespace Shaders {
TheNumbat's avatar
TheNumbat committed
272
273
274
275
276
277
278
extern const std::string line_v, line_f;
extern const std::string mesh_v, mesh_f;
extern const std::string inst_v;
extern const std::string dome_v, dome_f;

} // namespace Shaders
} // namespace GL