CSEngine
Loading...
Searching...
No Matches
GLProgramHandle.cpp
1//
2// Created by ounols on 19. 5. 8.
3//
4#include "GLProgramHandle.h"
5#include "AssetsDef.h"
6#include "MoreString.h"
7#include "Render/ShaderUtil.h"
8#include "../Manager/EngineCore.h"
9
10using namespace CSE;
11
12GLProgramHandle::GLProgramHandle() : Program(HANDLE_NULL) {
13 SetUndestroyable(true);
14}
15
16GLProgramHandle::~GLProgramHandle() = default;
17
18void GLProgramHandle::Exterminate() {
19 glDeleteProgram(Program);
20
21 for (const auto& element_pair : AttributesList) {
22 Element* element = element_pair.second;
23 SAFE_DELETE(element);
24 }
25
26 for (const auto& element_pair : UniformsList) {
27 Element* element = element_pair.second;
28 SAFE_DELETE(element);
29 }
30}
31
32void GLProgramHandle::SetAttribVec3(const std::string& location, vec3& value) {
33 glUseProgram(Program);
34 auto iter = AttributesList.find(location);
35 if (iter != AttributesList.end()) {
36 glVertexAttrib3fv(iter->second->id, value.Pointer());
37 return;
38 }
39 glVertexAttrib3fv(glGetAttribLocation(Program, location.c_str()), value.Pointer());
40}
41
42void GLProgramHandle::SetAttribVec4(const std::string& location, vec4& value) {
43 glUseProgram(Program);
44 auto iter = AttributesList.find(location);
45 if (iter != AttributesList.end()) {
46 glVertexAttrib4fv(iter->second->id, value.Pointer());
47 return;
48 }
49 glVertexAttrib4fv(glGetAttribLocation(Program, location.c_str()), value.Pointer());
50}
51
52void GLProgramHandle::SetUniformInt(const std::string& location, int value) {
53 glUseProgram(Program);
54 auto iter = UniformsList.find(location);
55 if (iter != UniformsList.end()) {
56 glUniform1i(iter->second->id, value);
57 return;
58 }
59 glUniform1i(glGetUniformLocation(Program, location.c_str()), value);
60}
61
62void GLProgramHandle::SetUniformFloat(const std::string& location, float value) {
63 glUseProgram(Program);
64 auto iter = UniformsList.find(location);
65 if (iter != UniformsList.end()) {
66 glUniform1f(iter->second->id, value);
67 return;
68 }
69 glUniform1f(glGetUniformLocation(Program, location.c_str()), value);
70}
71
72void GLProgramHandle::SetUniformMat4(const std::string& location, mat4& value) {
73 glUseProgram(Program);
74 auto iter = UniformsList.find(location);
75 if (iter != UniformsList.end()) {
76 glUniformMatrix4fv(iter->second->id, 1, 0, value.Pointer());
77 return;
78 }
79 glUniformMatrix4fv(glGetUniformLocation(Program, location.c_str()), 1, 0, value.Pointer());
80}
81
82void GLProgramHandle::SetUniformMat3(const std::string& location, mat3& value) {
83 glUseProgram(Program);
84 auto iter = UniformsList.find(location);
85 if (iter != UniformsList.end()) {
86 glUniformMatrix3fv(iter->second->id, 1, 0, value.Pointer());
87 return;
88 }
89 glUniformMatrix3fv(glGetUniformLocation(Program, location.c_str()), 1, 0, value.Pointer());
90}
91
92void GLProgramHandle::SetAttributesList(std::map<std::string, std::string>& vert,
93 std::map<std::string, std::string>& frag) {
94 GLint count = 0;
95 GLsizei length = 0;
96 GLint size = 0;
97 GLenum type;
98
99 glGetProgramiv(Program, GL_ACTIVE_ATTRIBUTES, &count);
100 AttributesList.clear();
101
102 for (int i = 0; i < count; i++) {
103 GLchar name[32];
104 glGetActiveAttrib(Program, (GLuint) i, 32, &length, &size, &type, name);
105
106 std::string name_str = name;
107 std::string imp_name = getImplementName(vert, name_str);
108 bool isTargetChanged = false;
109
110 if (imp_name.empty()) {
111 imp_name = getImplementName(frag, name_str);
112 if (imp_name.empty()) continue;
113
114 isTargetChanged = true;
115 }
116
117 int id = glGetAttribLocation(Program, (isTargetChanged ? frag : vert).find(imp_name)->second.c_str());
118
119 auto element = new Element;
120 element->type = type;
121 element->id = id;
122
123 AttributesList[imp_name] = element;
124 }
125}
126
127void
128GLProgramHandle::SetUniformsList(std::map<std::string, std::string>& vert, std::map<std::string, std::string>& frag) {
129 GLint count = 0;
130 GLsizei length = 0;
131 GLint size = 0;
132 GLenum type;
133
134 glGetProgramiv(Program, GL_ACTIVE_UNIFORMS, &count);
135 UniformsList.clear();
136
137 for (int i = 0; i < count; i++) {
138 GLchar name[64];
139 glGetActiveUniform(Program, (GLuint) i, 64, &length, &size, &type, name);
140
141 std::string name_str = name;
142
143 std::string imp_name = getImplementName(vert, name_str);
144 bool isTargetChanged = false;
145
146 if (imp_name.empty()) {
147 imp_name = getImplementName(frag, name_str);
148 if (imp_name.empty()) continue;
149
150 isTargetChanged = true;
151 }
152
153 int id = glGetUniformLocation(Program, (isTargetChanged ? frag : vert).find(imp_name)->second.c_str());
154
155 auto element = new Element;
156 element->type = type;
157 element->id = id;
158
159 UniformsList[imp_name] = element;
160 }
161}
162
163GLProgramHandle::GLElementList GLProgramHandle::GetAttributesList() const {
164 return AttributesList;
165}
166
167GLProgramHandle::GLElementList GLProgramHandle::GetUniformsList() const {
168 return UniformsList;
169}
170
171
172void GLProgramHandle::SaveShader(const std::string& path) {
173 return;
174}
175
176std::string GLProgramHandle::getImplementName(std::map<std::string, std::string>& list, const std::string& name) {
177
178 for (auto it = list.begin(); it != list.end(); it++) {
179 if (name.find(it->second) != std::string::npos) {
180 return it->first;
181 }
182 }
183
184 return "";
185}
186
187void GLProgramHandle::Init(const AssetMgr::AssetReference* asset) {
188 //
189 std::string shader_combine = CSE::AssetMgr::LoadAssetFile(asset->name_path);
190
191 auto shader_combine_vector = split(shader_combine, ',');
192
193 if (shader_combine_vector.size() < 2) return;
194 m_vertShaderName = trim(shader_combine_vector.at(0));
195 m_fragShaderName = trim(shader_combine_vector.at(1));
196
197 //
198 auto resMgr = CORE->GetCore(ResMgr);
199 auto vert_asset = resMgr->GetAssetReference(m_vertShaderName);
200 auto frag_asset = resMgr->GetAssetReference(m_fragShaderName);
201
202 std::string vert_str = CSE::AssetMgr::LoadAssetFile(vert_asset->name_path);
203 std::string frag_str = CSE::AssetMgr::LoadAssetFile(frag_asset->name_path);
204
205 if (vert_str.empty() || frag_str.empty()) return;
206
207 if (ShaderUtil::CreateProgramHandle(vert_str.c_str(), frag_str.c_str(), this) == nullptr) {
208 return;
209 }
210}
static GLProgramHandle * CreateProgramHandle(const GLchar *vertexSource, const GLchar *fragmentSource, GLProgramHandle *handle=nullptr)
Creates a program handle.