-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathGLProgram.hpp
More file actions
113 lines (91 loc) · 3.31 KB
/
Copy pathGLProgram.hpp
File metadata and controls
113 lines (91 loc) · 3.31 KB
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
#pragma once
/*
* GLShader is a wrapper for an OpenGL Shader Object. (Useful when sharing between programs.)
*
* GLProgram is a wrapper for an OpenGL Shader Program.
* It provides some convenience methods to perform *checked*
* lookups of attributes and uniforms.
*/
#include "gl.hpp"
#include <string>
#include <stdexcept>
#include <iostream>
#include <initializer_list>
struct GLShader {
GLuint shader = 0;
//Compile a shader from source:
GLShader( GLenum type, std::string const &source );
~GLShader() { if (shader != 0) glDeleteShader(shader); }
GLShader(GLShader const &) = delete;
GLShader(GLShader &&from) { std::swap(shader, from.shader); }
GLShader &operator=(GLShader &&from) { std::swap(shader, from.shader); return *this; }
};
struct GLProgram {
GLuint program = 0;
//Compiles + links program from source; throws on compile error:
GLProgram(
std::string const &vertex_source,
std::string const &fragment_source
) : GLProgram{
GLShader( GL_VERTEX_SHADER, vertex_source ),
GLShader( GL_FRAGMENT_SHADER, fragment_source ) } { }
GLProgram(
GLShader const &vertex_shader,
std::string const &fragment_source
) : GLProgram{
vertex_shader,
GLShader( GL_FRAGMENT_SHADER, fragment_source ) } { }
GLProgram(
std::string const &vertex_source,
GLShader const &fragment_shader
) : GLProgram{
GLShader( GL_VERTEX_SHADER, vertex_source ),
fragment_shader } { }
//Links program from shader objects:
GLProgram( GLShader const &shader0, GLShader const &shader1 ) : GLProgram({ &shader0, &shader1 }) { }
GLProgram( std::initializer_list< GLShader const * > shaders );
~GLProgram() { if (program != 0) glDeleteProgram(program); }
GLProgram(GLProgram const &) = delete;
GLProgram(GLProgram &&from) { std::swap(program, from.program); }
GLProgram &operator=(GLProgram &&from) { std::swap(program, from.program); return *this; }
//---------
void DEBUG_dump_info(std::string const &name);
//---------
enum MissingIs {
MissingIsWarning = 0,
MissingIsError = 1,
};
//getAttribLocation looks up an attribute:
GLint getAttribLocation(std::string const &name, MissingIs missing_is = MissingIsError) const {
GLint ret = glGetAttribLocation(program, name.c_str());
if (ret == -1) {
if (missing_is == MissingIsWarning) {
std::cerr << "WARNING: Attribute '" + name + "' does not exist in program." << std::endl;
} else {
throw std::runtime_error("Attribute '" + name + "' does not exist in program.");
}
}
return ret;
}
//getUniformLocation looks up a uniform address:
GLint getUniformLocation(std::string const &name, MissingIs missing_is = MissingIsError) const {
GLint ret = glGetUniformLocation(program, name.c_str());
if (ret == -1) {
if (missing_is == MissingIsWarning) {
std::cerr << "WARNING: Uniform '" + name + "' does not exist in program." << std::endl;
} else {
throw std::runtime_error("Uniform '" + name + "' does not exist in program.");
}
}
return ret;
}
//shorthand for getUniformLocation / getAttribLocation:
//operator() looks up an attribute (and checks that it exists):
GLint operator()(std::string const &name) const {
return getAttribLocation(name, MissingIsError);
}
//operator[] looks up a uniform address (and checks that it exists):
GLint operator[](std::string const &name) const {
return getUniformLocation(name, MissingIsError);
}
};