CSEngine
Loading...
Searching...
No Matches
CSE::ShaderUtil Class Reference

This class provides utility functions for shaders. More...

#include <ShaderUtil.h>

Public Member Functions

 ShaderUtil ()
 Constructor for the ShaderUtil class.
 
 ~ShaderUtil ()
 Destructor for the ShaderUtil class.
 

Static Public Member Functions

static GLProgramHandleCreateProgramHandle (const GLchar *vertexSource, const GLchar *fragmentSource, GLProgramHandle *handle=nullptr)
 Creates a program handle.
 
static GLuint createProgram (const GLchar *vertexSource, const GLchar *fragmentSource, const GLProgramHandle &handle)
 Creates a program.
 
static GLuint createProgram (GLuint vertexShader, GLuint fragmentShader, const GLProgramHandle &handle)
 
static GLuint loadShader (GLenum shaderType, const char *pSource, const GLProgramHandle &handle)
 Loads a shader.
 
static std::map< std::string, std::string > GetImportantVariables (const GLchar *source)
 Gets the important variables from the shader source code.
 
static void BindVariables (GLProgramHandle *handle)
 Binds variables to the shader.
 
static void BindCameraToShader (const GLProgramHandle &handle, const mat4 &camera, const vec3 &cameraPosition, const mat4 &projection, const mat4 &transform)
 Binds the camera data to the shader.
 
static void BindAttributeToShader (const GLProgramHandle &handle, const GLMeshID &meshId)
 Binds the attributes to the shader.
 
static void BindSkinningDataToShader (const GLProgramHandle &handle, const GLMeshID &meshId, const std::vector< mat4 > &jointMatrix)
 Binds the skinning data to the shader.
 
static void BindAttributeToPlane ()
 
static void BindAttributeToCubeMap ()
 

Detailed Description

This class provides utility functions for shaders.

This class provides utility functions for shaders. It can be used to create a program handle, create a program, bind variables and attributes to the shader, and bind skinning data.

Definition at line 21 of file ShaderUtil.h.

Constructor & Destructor Documentation

◆ ShaderUtil()

ShaderUtil::ShaderUtil ( )
default

Constructor for the ShaderUtil class.

Constructor for the ShaderUtil class.

◆ ~ShaderUtil()

ShaderUtil::~ShaderUtil ( )
default

Destructor for the ShaderUtil class.

Destructor for the ShaderUtil class.

Member Function Documentation

◆ BindAttributeToCubeMap()

void ShaderUtil::BindAttributeToCubeMap ( )
static

Definition at line 313 of file ShaderUtil.cpp.

313 {
314 SEnvironmentMgr::RenderCubeVAO();
315}

◆ BindAttributeToPlane()

void ShaderUtil::BindAttributeToPlane ( )
static

Definition at line 309 of file ShaderUtil.cpp.

309 {
310 SEnvironmentMgr::RenderPlaneVAO();
311}

◆ BindAttributeToShader()

void ShaderUtil::BindAttributeToShader ( const GLProgramHandle handle,
const GLMeshID meshId 
)
static

Binds the attributes to the shader.

Binds the attributes to the shader.

Parameters
handleThe program handle to use.
meshIdThe ID of the mesh.

Definition at line 267 of file ShaderUtil.cpp.

267 {
268 int stride = 4 * sizeof(vec3) + sizeof(vec2); //normal + position + uv = (4 * sizeof(vec3) + sizeof(vec2))
269 // 필요한 속성 정의
270 struct Attribute {
271 int id; // 속성 ID
272 size_t offset; // 오프셋
273 int size; // 속성의 개수
274 };
275
276 // 필요한 속성들을 정의
277 const std::vector<Attribute> attributes = {
278 { handle.Attributes.Position, 0, 3 },
279 { handle.Attributes.Normal, sizeof(vec3), 3 },
280 { handle.Attributes.TextureCoord, 2 * sizeof(vec3), 2 },
281 { handle.Attributes.Weight, 2 * sizeof(vec3) + sizeof(vec2), 3 },
282 { handle.Attributes.JointId, 3 * sizeof(vec3) + sizeof(vec2), 3 },
283 };
284
285 // 속성들을 바인딩
286 glBindVertexArray(meshId.m_vertexArray);
287 glBindBuffer(GL_ARRAY_BUFFER, meshId.m_vertexBuffer);
288 for (const auto& attribute: attributes) {
289 if (attribute.id < 0) continue; // 속성이 없을 경우 다음 속성으로
290 glEnableVertexAttribArray(attribute.id);
291 glVertexAttribPointer(attribute.id, attribute.size, GL_FLOAT, GL_FALSE, stride, (GLvoid*) attribute.offset);
292 }
293
294 // 인덱스가 있을 경우 인덱스 버퍼를 바인딩
295 if (meshId.m_indexSize < 0) {
296 glDrawArrays(GL_TRIANGLES, 0, meshId.m_vertexSize);
297 } else {
298 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, meshId.m_indexBuffer);
299 glDrawElements(GL_TRIANGLES, meshId.m_indexSize * 3, GL_UNSIGNED_SHORT, nullptr);
300 }
301 // 속성들의 바인딩을 해제
302 for (const auto& attribute: attributes) {
303 if (attribute.id < 0) continue; // 속성이 없을 경우 다음 속성으로
304 glDisableVertexAttribArray(attribute.id);
305 }
306 glBindVertexArray(0);
307}

◆ BindCameraToShader()

void ShaderUtil::BindCameraToShader ( const GLProgramHandle handle,
const mat4 camera,
const vec3 cameraPosition,
const mat4 projection,
const mat4 transform 
)
static

Binds the camera data to the shader.

Binds the camera data to the shader.

Parameters
handleThe program handle to use.
cameraThe camera transformation matrix.
cameraPositionThe position of the camera.
projectionThe projection matrix.
transformThe transformation matrix.

Definition at line 249 of file ShaderUtil.cpp.

250 {
251 if(handle.Uniforms.ViewMatrix >= 0)
252 glUniformMatrix4fv(handle.Uniforms.ViewMatrix, 1, 0, view.Pointer());
253 if(handle.Uniforms.ModelMatrix >= 0)
254 glUniformMatrix4fv(handle.Uniforms.ModelMatrix, 1, 0, transform.Pointer());
255 if(handle.Uniforms.ProjectionMatrix >= 0)
256 glUniformMatrix4fv(handle.Uniforms.ProjectionMatrix, 1, 0, projection.Pointer());
257 if(handle.Uniforms.CameraPosition >= 0)
258 glUniform3fv(handle.Uniforms.CameraPosition, 1, cameraPosition.Pointer());
259
260 if(handle.Uniforms.ProjectionInvMatrix >= 0)
261 glUniformMatrix4fv(handle.Uniforms.ProjectionInvMatrix, 1, 0, mat4::Invert(projection).Pointer());
262 if(handle.Uniforms.ViewInvMatrix >= 0)
263 glUniformMatrix4fv(handle.Uniforms.ViewInvMatrix, 1, 0, mat4::Invert(view).Pointer());
264}

Referenced by CSE::DeferredRenderGroup::RenderGbuffer().

◆ BindSkinningDataToShader()

void ShaderUtil::BindSkinningDataToShader ( const GLProgramHandle handle,
const GLMeshID meshId,
const std::vector< mat4 > &  jointMatrix 
)
static

Binds the skinning data to the shader.

Binds the skinning data to the shader.

Parameters
handleThe program handle to use.
meshIdThe ID of the mesh.
jointMatrixThe joint transformation matrices.

Definition at line 317 of file ShaderUtil.cpp.

318 {
319 if (!meshId.m_hasJoint || jointMatrix.empty()) {
320 glUniform1i(handle.Uniforms.SkinningMode, 0);
321 return;
322 }
323
324 std::vector<float> result;
325 result.reserve(jointMatrix.size() * 16);
326 for (const mat4& matrix: jointMatrix) {
327 std::copy(matrix.Pointer(), matrix.Pointer() + 16, std::back_inserter(result));
328 }
329
330 glUniformMatrix4fv(handle.Uniforms.JointMatrix, Settings::GetMaxJoints(), GL_FALSE, &result[0]);
331 glUniform1i(handle.Uniforms.SkinningMode, 1);
332}

◆ BindVariables()

void ShaderUtil::BindVariables ( GLProgramHandle handle)
static

Binds variables to the shader.

Binds variables to the shader.

Parameters
handleThe program handle to use.

Definition at line 186 of file ShaderUtil.cpp.

186 {
187 if (handle == nullptr) return;
188
189 //Attributes
190 auto position = handle->AttributeLocation("att.position");
191 auto normal = handle->AttributeLocation("att.normal");
192 auto jointId = handle->AttributeLocation("att.joint_indices");
193 auto weight = handle->AttributeLocation("att.weight");
194 auto textureCoord = handle->AttributeLocation("att.tex_uv");
195 auto color = handle->AttributeLocation("att.color");
196 //Uniforms
197 auto view = handle->UniformLocation("matrix.view");
198 auto model = handle->UniformLocation("matrix.model");
199 auto cameraPosition = handle->UniformLocation("vec3.camera");
200 auto projection = handle->UniformLocation("matrix.projection");
201 auto projectionInv = handle->UniformLocation("matrix.projection.inv");
202 auto viewInv = handle->UniformLocation("matrix.view.inv");
203 auto skinningMode = handle->UniformLocation("matrix.skinning_mode");
204 auto jointMatrix = handle->UniformLocation("matrix.joint");
205 auto lightPosition = handle->UniformLocation("light.position");
206 auto lightType = handle->UniformLocation("light.type");
207 auto lightRadius = handle->UniformLocation("light.radius");
208 auto lightColor = handle->UniformLocation("light.color");
209 auto lightShadowMap = handle->UniformLocation("light.shadow_map");
210 auto lightMatrix = handle->UniformLocation("light.matrix");
211 auto lightShadowMode = handle->UniformLocation("light.shadow_mode");
212 auto lightSize = handle->UniformLocation("light.size");
213 auto lightIrradiance = handle->UniformLocation("light.irradiance");
214 auto lightPrefilter = handle->UniformLocation("light.prefilter");
215 auto lightBrdf = handle->UniformLocation("light.brdf");
216 auto srcBuffer = handle->UniformLocation("buffer.source");
217 auto srcBufferSize = handle->UniformLocation("buffer.source.size");
218
219 handle->Attributes.Position = position != nullptr ? position->id : HANDLE_NULL;
220 handle->Attributes.Normal = normal != nullptr ? normal->id : HANDLE_NULL;
221 handle->Attributes.JointId = jointId != nullptr ? jointId->id : HANDLE_NULL;
222 handle->Attributes.Weight = weight != nullptr ? weight->id : HANDLE_NULL;
223 handle->Attributes.TextureCoord = textureCoord != nullptr ? textureCoord->id : HANDLE_NULL;
224 handle->Attributes.Color = color != nullptr ? color->id : HANDLE_NULL;
225
226 handle->Uniforms.ViewMatrix = view != nullptr ? view->id : HANDLE_NULL;
227 handle->Uniforms.ModelMatrix = model != nullptr ? model->id : HANDLE_NULL;
228 handle->Uniforms.CameraPosition = cameraPosition != nullptr ? cameraPosition->id : HANDLE_NULL;
229 handle->Uniforms.ProjectionMatrix = projection != nullptr ? projection->id : HANDLE_NULL;
230 handle->Uniforms.ProjectionInvMatrix = projectionInv != nullptr ? projectionInv->id : HANDLE_NULL;
231 handle->Uniforms.ViewInvMatrix = viewInv != nullptr ? viewInv->id : HANDLE_NULL;
232 handle->Uniforms.SkinningMode = skinningMode != nullptr ? skinningMode->id : HANDLE_NULL;
233 handle->Uniforms.JointMatrix = jointMatrix != nullptr ? jointMatrix->id : HANDLE_NULL;
234 handle->Uniforms.LightPosition = lightPosition != nullptr ? lightPosition->id : HANDLE_NULL;
235 handle->Uniforms.LightType = lightType != nullptr ? lightType->id : HANDLE_NULL;
236 handle->Uniforms.LightRadius = lightRadius != nullptr ? lightRadius->id : HANDLE_NULL;
237 handle->Uniforms.LightColor = lightColor != nullptr ? lightColor->id : HANDLE_NULL;
238 handle->Uniforms.LightShadowMap = lightShadowMap != nullptr ? lightShadowMap->id : HANDLE_NULL;
239 handle->Uniforms.LightMatrix = lightMatrix != nullptr ? lightMatrix->id : HANDLE_NULL;
240 handle->Uniforms.LightShadowMode = lightShadowMode != nullptr ? lightShadowMode->id : HANDLE_NULL;
241 handle->Uniforms.LightSize = lightSize != nullptr ? lightSize->id : HANDLE_NULL;
242 handle->Uniforms.LightIrradiance = lightIrradiance != nullptr ? lightIrradiance->id : HANDLE_NULL;
243 handle->Uniforms.LightPrefilter = lightPrefilter != nullptr ? lightPrefilter->id : HANDLE_NULL;
244 handle->Uniforms.LightBrdfLut = lightBrdf != nullptr ? lightBrdf->id : HANDLE_NULL;
245 handle->Uniforms.SourceBuffer = srcBuffer != nullptr ? srcBuffer->id : HANDLE_NULL;
246 handle->Uniforms.SourceBufferSize = srcBufferSize != nullptr ? srcBufferSize->id : HANDLE_NULL;
247}

Referenced by CreateProgramHandle().

◆ createProgram() [1/2]

GLuint ShaderUtil::createProgram ( const GLchar *  vertexSource,
const GLchar *  fragmentSource,
const GLProgramHandle handle 
)
static

Creates a program.

Creates a program with the given vertex and fragment shaders and the given program handle.

Parameters
vertexShaderThe vertex shader.
fragmentShaderThe fragment shader.
handleThe program handle to use.
Returns
The ID of the created program.

Definition at line 52 of file ShaderUtil.cpp.

52 {
53 GLuint vertexShader = loadShader(GL_VERTEX_SHADER, vertexSource, handle);
54 if (!vertexShader) {
55 return 0;
56 }
57
58 GLuint fragmentShader = loadShader(GL_FRAGMENT_SHADER, fragmentSource, handle);
59 if (!fragmentShader) {
60 return 0;
61 }
62
63 return createProgram(vertexShader, fragmentShader, handle);
64}
static GLuint loadShader(GLenum shaderType, const char *pSource, const GLProgramHandle &handle)
Loads a shader.
static GLuint createProgram(const GLchar *vertexSource, const GLchar *fragmentSource, const GLProgramHandle &handle)
Creates a program.

References createProgram(), and loadShader().

Referenced by createProgram(), and CreateProgramHandle().

◆ createProgram() [2/2]

GLuint ShaderUtil::createProgram ( GLuint  vertexShader,
GLuint  fragmentShader,
const GLProgramHandle handle 
)
static

Definition at line 66 of file ShaderUtil.cpp.

66 {
67 GLuint program = glCreateProgram();
68
69 if (program) {
70 //쉐이더를 attach 합니다.
71 glAttachShader(program, vertexShader);
72 glAttachShader(program, fragmentShader);
73 glLinkProgram(program);
74
75 GLint linkStatus = GL_FALSE;
76 glGetProgramiv(program, GL_LINK_STATUS, &linkStatus);
77 if (linkStatus != GL_TRUE) {
78 GLint bufLength = 0;
79 glGetProgramiv(program, GL_INFO_LOG_LENGTH, &bufLength);
80
81 if (bufLength) {
82 auto buf = static_cast<char*>(malloc(bufLength));
83
84 if (buf) {
85 glGetProgramInfoLog(program, bufLength, nullptr, buf);
86 auto errorLog = std::string("[") + handle.GetName() + "] Could not link program:" + buf;
87 SafeLog::Log(errorLog.c_str());
88 free(buf);
89
90 }
91 }
92 glDeleteProgram(program);
93 program = 0;
94
95 }
96 glDetachShader(program, vertexShader);
97 glDetachShader(program, fragmentShader);
98
99 }
100 glDeleteShader(vertexShader);
101 glDeleteShader(fragmentShader);
102
103 return program;
104}

◆ CreateProgramHandle()

GLProgramHandle * ShaderUtil::CreateProgramHandle ( const GLchar *  vertexSource,
const GLchar *  fragmentSource,
GLProgramHandle handle = nullptr 
)
static

Creates a program handle.

Creates a program handle with the given vertex and fragment shaders.

Parameters
vertexSourceThe vertex shader source code.
fragmentSourceThe fragment shader source code.
handleThe program handle to use.
Returns
A pointer to the created program handle.

Definition at line 24 of file ShaderUtil.cpp.

24 {
25 if (vertexSource == nullptr || fragmentSource == nullptr) return nullptr;
26 if (handle != nullptr && handle->Program != HANDLE_NULL) return nullptr;
27
28 GLProgramHandle* newHandle = handle;
29 auto program = createProgram(vertexSource, fragmentSource, *newHandle);
30 if (!program) {
31 return nullptr;
32 }
33
34 //Find important variables from shader.
35 auto variables_vert = GetImportantVariables(vertexSource);
36 auto variables_frag = GetImportantVariables(fragmentSource);
37
38 if (newHandle == nullptr)
39 newHandle = new GLProgramHandle();
40 newHandle->SetProgram(program);
41 //Get all variables from shader.
42 newHandle->SetAttributesList(variables_vert, variables_frag);
43 newHandle->SetUniformsList(variables_vert, variables_frag);
44
45 //Binding important variables to engine.
46 BindVariables(newHandle);
47
48 return newHandle;
49}
static void BindVariables(GLProgramHandle *handle)
Binds variables to the shader.
static std::map< std::string, std::string > GetImportantVariables(const GLchar *source)
Gets the important variables from the shader source code.

References BindVariables(), createProgram(), and GetImportantVariables().

◆ GetImportantVariables()

std::map< std::string, std::string > ShaderUtil::GetImportantVariables ( const GLchar *  source)
static

Gets the important variables from the shader source code.

Gets the important variables from the shader source code.

Parameters
sourceThe shader source code.
Returns
A map of variable names and types.

Definition at line 142 of file ShaderUtil.cpp.

142 {
143 // source를 각 라인별로 나누기 위해 std::stringstream을 사용
144 std::stringstream ss(source);
145 std::string line;
146 std::map<std::string, std::string> variables;
147 std::string type_str;
148
149 // std::stringstream에서 각 라인을 읽음
150 while (std::getline(ss, line)) {
151 // 변수 타입을 포함하는 주석 블록의 시작과 끝 인덱스를 찾음
152 int start_index = line.find("//[");
153 int end_index = line.find("]//");
154
155 if (start_index != std::string::npos && end_index != std::string::npos) {
156 // 시작 인덱스를 3 증가시킴 (주석 블록을 제외한 타입 이름의 시작 인덱스)
157 start_index += 3;
158 // 타입 이름을 추출
159 type_str = line.substr(start_index, end_index - 3);
160 continue;
161 }
162
163 // 타입 이름이 찾아졌으면, 변수 선언을 이 라인에서 찾음
164 if (!type_str.empty()) {
165 // 문장의 끝을 나타내는 세미콜론의 인덱스를 찾음
166 int eoc_index = line.find(';');
167
168 if (eoc_index != std::string::npos) {
169 // 변수 이름의 시작과 끝 인덱스를 찾음
170 int startIndex = line.substr(0, eoc_index).rfind(' ');
171 int endIndex = line.rfind('[');
172 endIndex = endIndex == std::string::npos ? eoc_index : endIndex;
173 auto detail = line.substr(startIndex, endIndex - startIndex);
174
175 // 변수 이름의 공백을 제거하고 맵에 추가
176 detail = trim(detail);
177 variables[type_str] = detail;
178 type_str.clear();
179 }
180 }
181 }
182
183 return variables;
184}

Referenced by CreateProgramHandle().

◆ loadShader()

GLuint ShaderUtil::loadShader ( GLenum  shaderType,
const char *  pSource,
const GLProgramHandle handle 
)
static

Loads a shader.

Loads a shader with the given shader type and source code and the given program handle.

Parameters
shaderTypeThe type of shader to load.
pSourceThe source code of the shader.
handleThe program handle to use.
Returns
The ID of the loaded shader.

Definition at line 106 of file ShaderUtil.cpp.

106 {
107 GLuint shader = glCreateShader(shaderType);
108 std::string srcString = m_defineVersion
109 + "#define MAX_JOINTS " + std::to_string(Settings::GetMaxJoints()) + '\n'
110 + "#define MAX_LIGHTS " + std::to_string(Settings::GetMaxLights()) + '\n'
111 + pSource;
112 const char* src = srcString.c_str();
113
114 if (shader) {
115 glShaderSource(shader, 1, &src, nullptr);
116 glCompileShader(shader);
117 GLint compiled = 0;
118 glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
119
120 if (!compiled) {
121 GLint infoLen = 0;
122 glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLen);
123
124 if (infoLen) {
125 auto buf = static_cast<char*>(malloc(infoLen));
126
127 if (buf) {
128 glGetShaderInfoLog(shader, infoLen, nullptr, buf);
129 //LOGE("Could not compile shader %d:\n%s\n", shaderType, buf);
130 auto errorLog = std::string("[") + handle.GetName() + "] Could not compile shader:" + buf;
131 SafeLog::Log(errorLog.c_str());
132 free(buf);
133 }
134 glDeleteShader(shader);
135 shader = 0;
136 }
137 }
138 }
139 return shader;
140}

Referenced by createProgram().


The documentation for this class was generated from the following files: