]> git.tdb.fi Git - libs/gl.git/blob - source/program.cpp
Add mult_matrix functions
[libs/gl.git] / source / program.cpp
1 /* $Id$
2
3 This file is part of libmspgl
4 Copyright © 2007 Mikko Rasa, Mikkosoft Productions
5 Distributed under the LGPL
6 */
7
8 #define GL_GLEXT_PROTOTYPES
9 #include "error.h"
10 #include "program.h"
11 #include "shader.h"
12
13 using namespace std;
14
15 namespace Msp {
16 namespace GL {
17
18 Program::Program():
19         id(glCreateProgram()),
20         del_shaders(false),
21         linked(false)
22 { }
23
24 Program::Program(const string &vert, const string &frag):
25         id(glCreateProgram()),
26         del_shaders(true),
27         linked(false)
28 {
29         attach_shader(*new Shader(VERTEX_SHADER, vert));
30         attach_shader(*new Shader(FRAGMENT_SHADER, frag));
31         link();
32 }
33
34 Program::~Program()
35 {
36         if(del_shaders)
37         {
38                 for(list<Shader *>::iterator i=shaders.begin(); i!=shaders.end(); ++i)
39                         delete *i;
40         }
41         glDeleteProgram(id);
42 }
43
44 void Program::attach_shader(Shader &shader)
45 {
46         if(find(shaders.begin(), shaders.end(), &shader)==shaders.end())
47         {
48                 glAttachShader(id, shader.get_id());
49                 shaders.push_back(&shader);
50         }
51 }
52
53 void Program::detach_shader(Shader &shader)
54 {
55         list<Shader *>::iterator i=remove(shaders.begin(), shaders.end(), &shader);
56         if(i!=shaders.end())
57         {
58                 shaders.erase(i, shaders.end());
59                 glDetachShader(id, shader.get_id());
60         }
61 }
62
63 void Program::set_del_shaders(bool ds)
64 {
65         del_shaders=ds;
66 }
67
68 void Program::bind_attribute(int index, const string &name)
69 {
70         glBindAttribLocation(id, index, name.c_str());
71 }
72
73 bool Program::link()
74 {
75         for(list<Shader *>::iterator i=shaders.begin(); i!=shaders.end(); ++i)
76                 if(!(*i)->get_compiled() && !(*i)->compile())
77                         return false;
78
79         glLinkProgram(id);
80         linked=get_param(GL_LINK_STATUS);
81         return linked;
82 }
83
84 int Program::get_param(GLenum param) const
85 {
86         int value;
87         glGetProgramiv(id, param, &value);
88         return value;
89 }
90
91 string Program::get_info_log() const
92 {
93         sizei len=get_param(GL_INFO_LOG_LENGTH);
94         char log[len+1];
95         glGetProgramInfoLog(id, len+1, reinterpret_cast<GLsizei *>(&len), log);
96         return string(log, len);
97 }
98
99 void Program::bind()
100 {
101         if(!linked)
102                 throw InvalidState("Program is not linked");
103
104         glUseProgram(id);
105         cur_prog=this;
106 }
107
108 int Program::get_uniform_location(const string &n) const
109 {
110         return glGetUniformLocation(id, n.c_str());
111 }
112
113 void Program::uniform(int i, int v)
114 {
115         glUniform1i(i, v);
116 }
117
118 void Program::uniform(int i, float x)
119 {
120         glUniform1f(i, x);
121 }
122
123 void Program::uniform(int i, float x, float y)
124 {
125         glUniform2f(i, x, y);
126 }
127
128 void Program::uniform(int i, float x, float y, float z)
129 {
130         glUniform3f(i, x, y, z);
131 }
132
133 void Program::uniform(int i, float x, float y, float z, float w)
134 {
135         glUniform4f(i, x, y, z, w);
136 }
137
138 void Program::uniform_matrix4(int i, const float *v)
139 {
140         glUniformMatrix4fv(i, 1, false, v);
141 }
142
143 void Program::unbind()
144 {
145         glUseProgram(0);
146         cur_prog=0;
147 }
148
149 void Program::maybe_bind()
150 {
151         if(cur_prog!=this)
152                 bind();
153 }
154
155 Program *Program::cur_prog=0;
156
157
158 Program::Loader::Loader(Program &p):
159         prog(p)
160 {
161         prog.set_del_shaders(true);
162
163         add("vertex_shader",   &Loader::vertex_shader);
164         add("fragment_shader", &Loader::fragment_shader);
165 }
166
167 Program::Loader::~Loader()
168 {
169         prog.link();
170 }
171
172 void Program::Loader::vertex_shader(const string &src)
173 {
174         prog.attach_shader(*new Shader(VERTEX_SHADER, src));
175 }
176
177 void Program::Loader::fragment_shader(const string &src)
178 {
179         prog.attach_shader(*new Shader(FRAGMENT_SHADER, src));
180 }
181
182 } // namespace GL
183 } // namespace Msp