Developer documentation
Version 3.0.3-105-gd3941f44
shader.h
Go to the documentation of this file.
1/* Copyright (c) 2008-2022 the MRtrix3 contributors.
2 *
3 * This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
6 *
7 * Covered Software is provided under this License on an "as is"
8 * basis, without warranty of any kind, either expressed, implied, or
9 * statutory, including, without limitation, warranties that the
10 * Covered Software is free of defects, merchantable, fit for a
11 * particular purpose or non-infringing.
12 * See the Mozilla Public License v. 2.0 for more details.
13 *
14 * For more details, see http://www.mrtrix.org/.
15 */
16
17#ifndef __gui_opengl_shader_h__
18#define __gui_opengl_shader_h__
19
20#include "gui/opengl/gl.h"
21#include "app.h"
22
23namespace MR
24{
25 namespace GUI
26 {
27 namespace GL
28 {
29 namespace Shader
30 {
31
32 void print_log (bool is_program, const std::string& type_name, GLuint index);
33
34 class Program;
35
36 template <GLint TYPE> class Object
38 public:
39 Object () : index_ (0) { }
40 Object (const std::string& source) : index_ (0) { if(!source.empty()) compile (source); }
41 Object (const Object&) = delete;
42 Object (Object&& other) : index_ (other.index_) { other.index_ = 0; }
43 Object& operator= (const Object&) = delete;
45 clear();
46 index_ = other.index_;
47 other.index_ = 0;
48 return *this;
49 }
50 ~Object () { clear(); }
51
52 void clear() {
53 if (index_) {
54 GL_DEBUG ("deleting OpenGL shader ID " + str(index_));
55 gl::DeleteShader (index_);
56 }
57 index_ = 0;
58 }
59
60 operator GLuint () const { return (index_); }
61
62 void compile (const std::string& source) {
63 std::string code = "#version 330 core\n" + source;
64 DEBUG ("compiling OpenGL " + this->type() + " shader:\n" + code);
65 if (!index_) {
66 index_ = gl::CreateShader (TYPE);
67 GL_DEBUG ("created OpenGL " + this->type() + " shader ID " + str (index_));
68 }
69 const char* p = code.c_str();
70 gl::ShaderSource (index_, 1, &p, NULL);
71 gl::CompileShader (index_);
72 GLint status;
73 gl::GetShaderiv (index_, gl::COMPILE_STATUS, &status);
74 if (status == gl::FALSE_) {
75 debug();
76 throw Exception ("error compiling OpenGL " + this->type() + " shader ID " + str (index_));
77 }
78 }
79 static const std::string type() { return TYPE == gl::VERTEX_SHADER ? "vertex" : ( TYPE == gl::FRAGMENT_SHADER ? "fragment" : "geometry" ); }
80
81 void debug () {
82 assert (index_);
83 print_log (false, this->type() + " shader", index_);
84 }
85
86 protected:
87 GLuint index_;
88 friend class Program;
89 };
90
94
95
96
97 class Program
99 public:
100 Program () : index_ (0) { }
101 Program (Program&& other) : index_ (other.index_) { other.index_ = 0; }
102 Program (const Program&) = delete;
103 Program& operator= (const Program&) = delete;
105 clear();
106 index_ = other.index_;
107 other.index_ = 0;
108 return *this;
109 }
110 ~Program () { clear(); }
111
112 void clear () {
113 if (index_) {
114 GL_DEBUG ("deleting OpenGL shader program " + str(index_));
115 gl::DeleteProgram (index_);
116 }
117 index_ = 0;
118 }
119 operator GLuint () const {
120 return index_;
121 }
122 template <GLint TYPE> void attach (const Object<TYPE>& object) {
123 if (!index_) {
124 index_ = gl::CreateProgram();
125 GL_DEBUG ("created OpenGL shader program ID " + str(index_));
126 }
127 gl::AttachShader (index_, object.index_);
128 GL_DEBUG ("attached OpenGL " + Object<TYPE>::type() + " shader ID " + str(object.index_) + " to program ID " + str(index_));
129 }
130 template <GLint TYPE> void detach (const Object<TYPE>& object) {
131 assert (index_);
132 assert (object.index_);
133 gl::DetachShader (index_, object.index_);
134 GL_DEBUG ("detached OpenGL " + Object<TYPE>::type() + " shader ID " + str(object.index_) + " from program ID " + str(index_));
135 }
136 void link () {
137 GL_DEBUG ("linking OpenGL shader program ID " + str(index_) + "...");
138 assert (index_);
139 gl::LinkProgram (index_);
140 GLint status;
141 gl::GetProgramiv (index_, gl::LINK_STATUS, &status);
142 if (status == gl::FALSE_) {
143 debug();
144 throw Exception (std::string ("error linking OpenGL shader program ID " + str(index_)));
145 }
146 }
147 void start () const {
148 assert (index_);
149 gl::UseProgram (index_);
150 GL_DEBUG ("using OpenGL shader program ID " + str(index_));
151 }
152 static void stop () {
153 gl::UseProgram (0);
154 GL_DEBUG ("using default OpenGL shader program");
155 }
156
157 void debug () const {
158 assert (index_);
159 print_log (true, "OpenGL shader program", index_);
160 }
161
162 protected:
163 GLuint index_;
164 };
165
166 }
167 }
168 }
169}
170
171#endif
172
void compile(const std::string &source)
Definition: shader.h:62
Object & operator=(const Object &)=delete
Object(const std::string &source)
Definition: shader.h:40
Object(const Object &)=delete
static const std::string type()
Definition: shader.h:79
Object(Object &&other)
Definition: shader.h:42
Program & operator=(const Program &)=delete
void detach(const Object< TYPE > &object)
Definition: shader.h:130
Program(const Program &)=delete
Program(Program &&other)
Definition: shader.h:101
void attach(const Object< TYPE > &object)
Definition: shader.h:122
#define DEBUG(msg)
Definition: exception.h:75
#define GL_DEBUG(msg)
Definition: gl.h:46
#define NOMEMALIGN
Definition: memory.h:22
void print_log(bool is_program, const std::string &type_name, GLuint index)
Definition: base.h:24
std::string str(const T &value, int precision=0)
Definition: mrtrix.h:247
size_t index