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