]> git.sesse.net Git - casparcg/blob - core/mixer/gpu/shader.cpp
2.0. image_mixer/amcp: Added LEVELS, SATURATION, BRIGHTNESS, CONTRAST.
[casparcg] / core / mixer / gpu / shader.cpp
1 #include "../../../stdafx.h"\r
2 \r
3 #include "shader.h"\r
4 \r
5 #include <common/gl/gl_check.h>\r
6 \r
7 #include <unordered_map>\r
8 \r
9 namespace caspar { namespace core {\r
10 \r
11 struct shader::implementation : boost::noncopyable\r
12 {\r
13         GLuint program_;\r
14         std::unordered_map<std::string, GLint> locations_;\r
15 public:\r
16 \r
17         implementation(const std::string& vertex_source_str, const std::string& fragment_source_str) : program_(0)\r
18         {\r
19                 GLint success;\r
20         \r
21                 const char* vertex_source = vertex_source_str.c_str();\r
22                                                 \r
23                 auto vertex_shader = glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB);\r
24                                         \r
25                 GL(glShaderSourceARB(vertex_shader, 1, &vertex_source, NULL));\r
26                 GL(glCompileShaderARB(vertex_shader));\r
27 \r
28                 GL(glGetObjectParameterivARB(vertex_shader, GL_OBJECT_COMPILE_STATUS_ARB, &success));\r
29                 if (success == GL_FALSE)\r
30                 {\r
31                         char info[2048];\r
32                         GL(glGetInfoLogARB(vertex_shader, sizeof(info), 0, info));\r
33                         GL(glDeleteObjectARB(vertex_shader));\r
34                         std::stringstream str;\r
35                         str << "Failed to compile vertex shader:" << std::endl << info << std::endl;\r
36                         BOOST_THROW_EXCEPTION(caspar_exception() << msg_info(str.str()));\r
37                 }\r
38                         \r
39                 const char* fragment_source = fragment_source_str.c_str();\r
40                                                 \r
41                 auto fragmemt_shader = glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB);\r
42                                         \r
43                 GL(glShaderSourceARB(fragmemt_shader, 1, &fragment_source, NULL));\r
44                 GL(glCompileShaderARB(fragmemt_shader));\r
45 \r
46                 GL(glGetObjectParameterivARB(fragmemt_shader, GL_OBJECT_COMPILE_STATUS_ARB, &success));\r
47                 if (success == GL_FALSE)\r
48                 {\r
49                         char info[2048];\r
50                         GL(glGetInfoLogARB(fragmemt_shader, sizeof(info), 0, info));\r
51                         GL(glDeleteObjectARB(fragmemt_shader));\r
52                         std::stringstream str;\r
53                         str << "Failed to compile fragment shader:" << std::endl << info << std::endl;\r
54                         BOOST_THROW_EXCEPTION(caspar_exception() << msg_info(str.str()));\r
55                 }\r
56                         \r
57                 program_ = glCreateProgramObjectARB();\r
58                         \r
59                 GL(glAttachObjectARB(program_, vertex_shader));\r
60                 GL(glAttachObjectARB(program_, fragmemt_shader));\r
61 \r
62                 GL(glLinkProgramARB(program_));\r
63                         \r
64                 GL(glDeleteObjectARB(vertex_shader));\r
65                 GL(glDeleteObjectARB(fragmemt_shader));\r
66 \r
67                 GL(glGetObjectParameterivARB(program_, GL_OBJECT_LINK_STATUS_ARB, &success));\r
68                 if (success == GL_FALSE)\r
69                 {\r
70                         char info[2048];\r
71                         GL(glGetInfoLogARB(program_, sizeof(info), 0, info));\r
72                         GL(glDeleteObjectARB(program_));\r
73                         std::stringstream str;\r
74                         str << "Failed to link shader program:" << std::endl << info << std::endl;\r
75                         BOOST_THROW_EXCEPTION(caspar_exception() << msg_info(str.str()));\r
76                 }\r
77                 GL(glUseProgramObjectARB(program_));\r
78         }\r
79         \r
80         ~implementation()\r
81         {\r
82                 glDeleteProgram(program_);\r
83         }\r
84 \r
85         GLint get_location(const char* name)\r
86         {\r
87                 auto it = locations_.find(name);\r
88                 if(it == locations_.end())\r
89                         it = locations_.insert(std::make_pair(name, glGetUniformLocation(program_, name))).first;\r
90                 return it->second;\r
91         }\r
92 \r
93         void use()\r
94         {       \r
95                 GL(glUseProgramObjectARB(program_));            \r
96         }\r
97 \r
98         void set(const std::string& name, int value)\r
99         {\r
100                 GL(glUniform1i(get_location(name.c_str()), value));\r
101         }\r
102         \r
103         void set(const std::string& name, float value)\r
104         {\r
105                 GL(glUniform1f(get_location(name.c_str()), value));\r
106         }\r
107 \r
108         void set(const std::string& name, double value)\r
109         {\r
110                 GL(glUniform1f(get_location(name.c_str()), static_cast<float>(value)));\r
111         }\r
112 };\r
113 \r
114 \r
115 shader::shader(const std::string& vertex_source_str, const std::string& fragment_source_str) : impl_(new implementation(vertex_source_str, fragment_source_str)){}\r
116 void shader::use(){impl_->use();}\r
117 void shader::set(const std::string& name, int value){impl_->set(name, value);}\r
118 void shader::set(const std::string& name, float value){impl_->set(name, value);}\r
119 void shader::set(const std::string& name, double value){impl_->set(name, value);}\r
120 \r
121 }}