1 #include "BlendedSprite.hpp"
2 #include "PlainColor.hpp"
5 #include "SkyBoxShader.hpp"
7 #include "ArrayTexture.hpp"
10 #include "../app/error.hpp"
18 #include <glm/gtc/type_ptr.hpp>
24 Shader::Shader(GLenum type)
25 : handle(glCreateShader(type)) {
27 throw app::GLError("glCreateShader");
33 glDeleteShader(handle);
37 Shader::Shader(Shader &&other) noexcept
38 : handle(other.handle) {
42 Shader &Shader::operator =(Shader &&other) noexcept {
43 std::swap(handle, other.handle);
48 void Shader::Source(const GLchar *src) noexcept {
49 const GLchar* src_arr[] = { src };
50 glShaderSource(handle, 1, src_arr, nullptr);
53 void Shader::Compile() noexcept {
54 glCompileShader(handle);
57 bool Shader::Compiled() const noexcept {
58 GLint compiled = GL_FALSE;
59 glGetShaderiv(handle, GL_COMPILE_STATUS, &compiled);
60 return compiled == GL_TRUE;
63 void Shader::Log(std::ostream &out) const {
64 int log_len = 0, max_len = 0;
65 glGetShaderiv(handle, GL_INFO_LOG_LENGTH, &max_len);
66 std::unique_ptr<char[]> log(new char[max_len]);
67 glGetShaderInfoLog(handle, max_len, &log_len, log.get());
68 out.write(log.get(), log_len);
72 void Shader::AttachToProgram(GLuint id) const noexcept {
73 glAttachShader(id, handle);
78 : handle(glCreateProgram()) {
80 throw app::GLError("glCreateProgram");
86 glDeleteProgram(handle);
91 const Shader &Program::LoadShader(GLenum type, const GLchar *src) {
92 shaders.emplace_back(type);
93 Shader &shader = shaders.back();
96 if (!shader.Compiled()) {
97 shader.Log(std::cerr);
98 throw std::runtime_error("compile shader");
104 void Program::Attach(Shader &shader) noexcept {
105 shader.AttachToProgram(handle);
108 void Program::Link() noexcept {
109 glLinkProgram(handle);
112 bool Program::Linked() const noexcept {
113 GLint linked = GL_FALSE;
114 glGetProgramiv(handle, GL_LINK_STATUS, &linked);
115 return linked == GL_TRUE;
118 void Program::Log(std::ostream &out) const {
119 int log_len = 0, max_len = 0;
120 glGetProgramiv(handle, GL_INFO_LOG_LENGTH, &max_len);
121 std::unique_ptr<char[]> log(new char[max_len]);
122 glGetProgramInfoLog(handle, max_len, &log_len, log.get());
123 out.write(log.get(), log_len);
127 GLint Program::AttributeLocation(const GLchar *name) const noexcept {
128 return glGetAttribLocation(handle, name);
131 GLint Program::UniformLocation(const GLchar *name) const noexcept {
132 return glGetUniformLocation(handle, name);
136 void Program::Uniform(GLint loc, GLint val) noexcept {
137 glUniform1i(loc, val);
140 void Program::Uniform(GLint loc, float val) noexcept {
141 glUniform1f(loc, val);
144 void Program::Uniform(GLint loc, const glm::vec3 &val) noexcept {
145 glUniform3fv(loc, 1, glm::value_ptr(val));
148 void Program::Uniform(GLint loc, const glm::vec4 &val) noexcept {
149 glUniform4fv(loc, 1, glm::value_ptr(val));
152 void Program::Uniform(GLint loc, const glm::mat4 &val) noexcept {
153 glUniformMatrix4fv(loc, 1, GL_FALSE, glm::value_ptr(val));
157 BlendedSprite::BlendedSprite()
161 , sampler_handle(0) {
164 "#version 330 core\n"
165 "layout(location = 0) in vec3 vtx_position;\n"
166 "layout(location = 1) in vec2 vtx_tex_uv;\n"
167 "uniform mat4 MVP;\n"
168 "out vec2 frag_tex_uv;\n"
170 "gl_Position = MVP * vec4(vtx_position, 1);\n"
171 "frag_tex_uv = vtx_tex_uv;\n"
176 "#version 330 core\n"
177 "in vec2 frag_tex_uv;\n"
178 "uniform sampler2D tex_sampler;\n"
179 "uniform vec4 fg_factor;\n"
180 "uniform vec4 bg_factor;\n"
183 "vec4 tex_color = texture(tex_sampler, frag_tex_uv);\n"
184 "vec4 factor = mix(bg_factor, fg_factor, tex_color.a);\n"
185 "color = tex_color * factor;\n"
186 "color.a = factor.a;\n"
190 if (!program.Linked()) {
191 program.Log(std::cerr);
192 throw std::runtime_error("link program");
195 mvp_handle = program.UniformLocation("MVP");
196 sampler_handle = program.UniformLocation("tex_sampler");
197 fg_handle = program.UniformLocation("fg_factor");
198 bg_handle = program.UniformLocation("bg_factor");
201 SetFG(glm::vec4(1.0f, 1.0f, 1.0f, 1.0f));
202 SetBG(glm::vec4(1.0f, 1.0f, 1.0f, 0.0f));
206 void BlendedSprite::Activate() noexcept {
210 void BlendedSprite::SetM(const glm::mat4 &m) noexcept {
211 program.Uniform(mvp_handle, vp * m);
214 void BlendedSprite::SetProjection(const glm::mat4 &p) noexcept {
219 void BlendedSprite::SetView(const glm::mat4 &v) noexcept {
224 void BlendedSprite::SetVP(const glm::mat4 &v, const glm::mat4 &p) noexcept {
230 void BlendedSprite::SetMVP(const glm::mat4 &m, const glm::mat4 &v, const glm::mat4 &p) noexcept {
235 void BlendedSprite::SetTexture(Texture &tex) noexcept {
236 glActiveTexture(GL_TEXTURE0);
238 program.Uniform(sampler_handle, GLint(0));
241 void BlendedSprite::SetFG(const glm::vec4 &v) noexcept {
242 program.Uniform(fg_handle, v);
245 void BlendedSprite::SetBG(const glm::vec4 &v) noexcept {
246 program.Uniform(bg_handle, v);
250 SkyBoxShader::SkyBoxShader()
254 , sampler_handle(0) {
257 "#version 330 core\n"
258 "layout(location = 0) in vec3 vtx_position;\n"
260 "out vec3 vtx_viewspace;\n"
262 "gl_Position = VP * vec4(vtx_position, 1);\n"
263 "gl_Position.z = gl_Position.w;\n"
264 "vtx_viewspace = vtx_position;\n"
269 "#version 330 core\n"
270 "in vec3 vtx_viewspace;\n"
271 "uniform samplerCube tex_sampler;\n"
274 "color = texture(tex_sampler, vtx_viewspace).rgb;\n"
275 //"color = vec3(1,0,0);\n"
279 if (!program.Linked()) {
280 program.Log(std::cerr);
281 throw std::runtime_error("link program");
284 vp_handle = program.UniformLocation("VP");
285 sampler_handle = program.UniformLocation("tex_sampler");
289 void SkyBoxShader::Activate() noexcept {
293 void SkyBoxShader::SetTexture(CubeMap &tex) noexcept {
294 glActiveTexture(GL_TEXTURE0);
296 program.Uniform(sampler_handle, GLint(0));
299 void SkyBoxShader::SetProjection(const glm::mat4 &p) noexcept {
302 program.Uniform(vp_handle, vp);
305 void SkyBoxShader::SetView(const glm::mat4 &v) noexcept {
310 view[3] = glm::vec4(0.0f, 0.0f, 0.0f, 1.0f);
311 vp = projection * view;
312 program.Uniform(vp_handle, vp);
315 void SkyBoxShader::SetVP(const glm::mat4 &v, const glm::mat4 &p) noexcept {
321 PlainColor::PlainColor()
327 "#version 330 core\n"
328 "layout(location = 0) in vec3 vtx_position;\n"
329 "layout(location = 1) in vec4 vtx_color;\n"
330 "uniform mat4 MVP;\n"
331 "out vec4 frag_color;\n"
333 "gl_Position = MVP * vec4(vtx_position, 1);\n"
334 "frag_color = vtx_color;\n"
339 "#version 330 core\n"
340 "in vec4 frag_color;\n"
343 "color = frag_color;\n"
347 if (!program.Linked()) {
348 program.Log(std::cerr);
349 throw std::runtime_error("link program");
352 mvp_handle = program.UniformLocation("MVP");
356 void PlainColor::Activate() noexcept {
360 void PlainColor::SetM(const glm::mat4 &m) noexcept {
361 program.Uniform(mvp_handle, vp * m);
364 void PlainColor::SetProjection(const glm::mat4 &p) noexcept {
369 void PlainColor::SetView(const glm::mat4 &v) noexcept {
374 void PlainColor::SetVP(const glm::mat4 &v, const glm::mat4 &p) noexcept {
380 void PlainColor::SetMVP(const glm::mat4 &m, const glm::mat4 &v, const glm::mat4 &p) noexcept {