The Battle for Wesnoth  1.13.4+dev
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
shader.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2014 - 2016 by Boldizsár Lipka <[email protected]>
3  Part of the Battle for Wesnoth Project http://www.wesnoth.org/
4 
5  This program is free software; you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation; either version 2 of the License, or
8  (at your option) any later version.
9  This program is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY.
11 
12  See the COPYING file for more details.
13 */
14 
15 #include "shader.hpp"
16 #include <iostream>
17 #include "image.hpp"
18 #include "../image.hpp" // We want the file in src/
19 
20 #ifdef SDL_GPU
21 namespace sdl
22 {
23 
24 shader_program::shader_program(const std::string &vsrc, const std::string &fsrc)
25  : program_object_(0)
26  , vertex_object_(0)
27  , fragment_object_(0)
28  , block_()
29  , attr_color_mod_(0)
30  , attr_submerge_(0)
31  , attr_effects_(0)
32  , uni_overlay_(0)
33  , overlay_image_()
34  , refcount_(new unsigned(1))
35 {
36  vertex_object_ = GPU_LoadShader(GPU_VERTEX_SHADER, vsrc.c_str());
37  if (!vertex_object_) {
38  throw shader_error("Failed to compile vertex shader");
39  }
40 
41  fragment_object_ = GPU_LoadShader(GPU_FRAGMENT_SHADER, fsrc.c_str());
42  if (!fragment_object_) {
43  throw shader_error("Failed to compile fragment shader");
44  }
45 
46  program_object_ = GPU_LinkShaders(vertex_object_, fragment_object_);
47  if (!program_object_) {
48  throw shader_error("Failed to link shader program");
49  }
50 
51  attr_color_mod_ = GPU_GetAttributeLocation(program_object_,
52  "vert_color_mod");
53  attr_submerge_ = GPU_GetAttributeLocation(program_object_,
54  "vert_submerge");
55  attr_effects_ = GPU_GetAttributeLocation(program_object_,
56  "vert_effects");
57  uni_overlay_ = GPU_GetUniformLocation(program_object_, "overlay");
58 
59  set_color_mod(0, 0, 0, 0);
60  set_submerge(0);
61  set_effects(0);
62 }
63 
64 shader_program::shader_program()
65  : program_object_(0)
66  , vertex_object_(0)
67  , fragment_object_(0)
68  , block_()
69  , attr_color_mod_(0)
70  , attr_submerge_(0)
71  , attr_effects_(0)
72  , uni_overlay_(0)
73  , overlay_image_()
74  , refcount_(new unsigned(1))
75 {}
76 
77 shader_program::~shader_program()
78 {
79  (*refcount_)--;
80  if (!*refcount_) {
81  deactivate();
82  GPU_FreeShader(vertex_object_);
83  GPU_FreeShader(fragment_object_);
84  GPU_FreeShaderProgram(program_object_);
85  }
86 }
87 
88 shader_program::shader_program(const shader_program &prog)
89  : program_object_(prog.program_object_)
90  , vertex_object_(prog.vertex_object_)
91  , fragment_object_(prog.fragment_object_)
92  , block_(prog.block_)
93  , attr_color_mod_(prog.attr_color_mod_)
94  , attr_submerge_(prog.attr_submerge_)
95  , attr_effects_(prog.attr_effects_)
96  , uni_overlay_(prog.uni_overlay_)
97  , overlay_image_(prog.overlay_image_)
98  , refcount_(prog.refcount_)
99 {
100  (*refcount_)++;
101 }
102 
103 const shader_program &shader_program::operator =(const shader_program &prog)
104 {
105  if (&prog != this) {
106  this->~shader_program();
107  return *(new(this) shader_program(prog));
108  }
109 
110  return *this;
111 }
112 
113 void shader_program::activate()
114 {
115  block_ = GPU_LoadShaderBlock(program_object_, "vert_vertex",
116  "vert_texture_pos", "vert_draw_color",
117  "model_view_proj");
118  GPU_ActivateShaderProgram(program_object_, &block_);
119  //NOTE: this line can be removed once we made sure that a sane overlay
120  // will be set before rendering anything.
121  set_overlay(image::get_texture("misc/blank.png"));
122 }
123 
124 void shader_program::deactivate()
125 {
126  if (GPU_GetCurrentShaderProgram() == program_object_) {
128  }
129 }
130 
131 void shader_program::set_color_mod(int r, int g, int b, int a)
132 {
133  static float color_mod[4];
134  color_mod[0] = float(r) / 255;
135  color_mod[1] = float(g) / 255;
136  color_mod[2] = float(b) / 255;
137  color_mod[3] = float(a) / 255;
138 
139  GPU_SetAttributefv(attr_color_mod_, 4, color_mod);
140 }
141 
142 void shader_program::set_submerge(float val)
143 {
144  GPU_SetAttributef(attr_submerge_, val);
145 }
146 
147 void shader_program::set_effects(int effects)
148 {
149  GPU_SetAttributei(attr_effects_, effects);
150 }
151 
152 void shader_program::set_overlay(const timage &img)
153 {
154  overlay_image_ = img;
155  GPU_SetShaderImage(img.raw(), uni_overlay_, 1);
156 }
157 
158 shader_error::shader_error(const std::string &op)
159  : game::error(op + "\n" + GPU_GetShaderMessage())
160 {
161  std::cerr << GPU_GetShaderMessage() << std::endl;
162 }
163 
164 }
165 #endif
GPU_ShaderBlock GPU_LoadShaderBlock(Uint32 program_object, const char *position_name, const char *texcoord_name, const char *color_name, const char *modelViewMatrix_name)
Definition: SDL_gpu.c:2346
static l_noret error(LoadState *S, const char *why)
Definition: lundump.cpp:29
Uint32 GPU_LinkShaders(Uint32 shader_object1, Uint32 shader_object2)
Definition: SDL_gpu.c:2243
const char * GPU_GetShaderMessage(void)
Definition: SDL_gpu.c:2307
GLuint const GLfloat * val
Definition: glew.h:2614
GLboolean GLboolean g
Definition: glew.h:7319
Uint32 GPU_LoadShader(GPU_ShaderEnum shader_type, const char *filename)
Definition: SDL_gpu.c:2206
GLdouble GLdouble GLdouble b
Definition: glew.h:6966
void GPU_SetShaderImage(GPU_Image *image, int location, int image_unit)
Definition: SDL_gpu.c:2369
void GPU_SetAttributefv(int location, int num_elements, float *value)
Definition: SDL_gpu.c:2493
void GPU_ActivateShaderProgram(Uint32 program_object, GPU_ShaderBlock *block)
Definition: SDL_gpu.c:2291
GLboolean GLboolean GLboolean GLboolean a
Definition: glew.h:7319
void GPU_FreeShaderProgram(Uint32 program_object)
Definition: SDL_gpu.c:2259
void GPU_SetAttributef(int location, float value)
Definition: SDL_gpu.c:2469
void GPU_DeactivateShaderProgram(void)
Definition: SDL_gpu.c:2299
int GPU_GetUniformLocation(Uint32 program_object, const char *uniform_name)
Definition: SDL_gpu.c:2338
GLdouble GLdouble GLdouble r
Definition: glew.h:1374
void GPU_FreeShader(Uint32 shader_object)
Definition: SDL_gpu.c:2251
GLint GLvoid * img
Definition: glew.h:1353
int GPU_GetAttributeLocation(Uint32 program_object, const char *attrib_name)
Definition: SDL_gpu.c:2315
Uint32 GPU_GetCurrentShaderProgram(void)
Definition: SDL_gpu.c:69
GLsizei const GLcharARB ** string
Definition: glew.h:4503
void GPU_SetAttributei(int location, int value)
Definition: SDL_gpu.c:2477