13 void gl_error(std::string msg) {
14 const GLubyte *errBegin = gluErrorString(glGetError());
15 if (errBegin && *errBegin != '\0') {
16 const GLubyte *errEnd = errBegin;
17 while (*errEnd != '\0') {
21 msg.append(errBegin, errEnd);
23 throw std::runtime_error(msg);
30 Shader::Shader(GLenum type)
31 : handle(glCreateShader(type)) {
33 gl_error("glCreateShader");
39 glDeleteShader(handle);
43 Shader::Shader(Shader &&other)
44 : handle(other.handle) {
48 Shader &Shader::operator =(Shader &&other) {
49 std::swap(handle, other.handle);
54 void Shader::Source(const GLchar *src) {
55 const GLchar* src_arr[] = { src };
56 glShaderSource(handle, 1, src_arr, nullptr);
59 void Shader::Compile() {
60 glCompileShader(handle);
63 bool Shader::Compiled() const {
64 GLint compiled = GL_FALSE;
65 glGetShaderiv(handle, GL_COMPILE_STATUS, &compiled);
66 return compiled == GL_TRUE;
69 void Shader::Log(std::ostream &out) const {
70 int log_len = 0, max_len = 0;
71 glGetShaderiv(handle, GL_INFO_LOG_LENGTH, &max_len);
72 std::unique_ptr<char[]> log(new char[max_len]);
73 glGetShaderInfoLog(handle, max_len, &log_len, log.get());
74 out.write(log.get(), log_len);
78 void Shader::AttachToProgram(GLuint id) const {
79 glAttachShader(id, handle);
84 : handle(glCreateProgram()) {
86 gl_error("glCreateProgram");
92 glDeleteProgram(handle);
97 const Shader &Program::LoadShader(GLenum type, const GLchar *src) {
98 shaders.emplace_back(type);
99 Shader &shader = shaders.back();
102 if (!shader.Compiled()) {
103 shader.Log(std::cerr);
104 throw std::runtime_error("compile shader");
110 void Program::Attach(Shader &shader) {
111 shader.AttachToProgram(handle);
114 void Program::Link() {
115 glLinkProgram(handle);
118 bool Program::Linked() const {
119 GLint linked = GL_FALSE;
120 glGetProgramiv(handle, GL_LINK_STATUS, &linked);
121 return linked == GL_TRUE;
124 void Program::Log(std::ostream &out) const {
125 int log_len = 0, max_len = 0;
126 glGetProgramiv(handle, GL_INFO_LOG_LENGTH, &max_len);
127 std::unique_ptr<char[]> log(new char[max_len]);
128 glGetProgramInfoLog(handle, max_len, &log_len, log.get());
129 out.write(log.get(), log_len);
133 GLint Program::UniformLocation(const GLchar *name) const {
134 return glGetUniformLocation(handle, name);