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 326 of file ShaderUtil.cpp.

326 {
327 SEnvironmentMgr::RenderCubeVAO();
328}

◆ BindAttributeToPlane()

void ShaderUtil::BindAttributeToPlane ( )
static

Definition at line 322 of file ShaderUtil.cpp.

322 {
323 SEnvironmentMgr::RenderPlaneVAO();
324}

◆ 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 280 of file ShaderUtil.cpp.

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

◆ 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 262 of file ShaderUtil.cpp.

263 {
264 if(handle.Uniforms.ViewMatrix >= 0)
265 glUniformMatrix4fv(handle.Uniforms.ViewMatrix, 1, 0, view.Pointer());
266 if(handle.Uniforms.ModelMatrix >= 0)
267 glUniformMatrix4fv(handle.Uniforms.ModelMatrix, 1, 0, transform.Pointer());
268 if(handle.Uniforms.ProjectionMatrix >= 0)
269 glUniformMatrix4fv(handle.Uniforms.ProjectionMatrix, 1, 0, projection.Pointer());
270 if(handle.Uniforms.CameraPosition >= 0)
271 glUniform3fv(handle.Uniforms.CameraPosition, 1, cameraPosition.Pointer());
272
273 if(handle.Uniforms.ProjectionInvMatrix >= 0)
274 glUniformMatrix4fv(handle.Uniforms.ProjectionInvMatrix, 1, 0, mat4::Invert(projection).Pointer());
275 if(handle.Uniforms.ViewInvMatrix >= 0)
276 glUniformMatrix4fv(handle.Uniforms.ViewInvMatrix, 1, 0, mat4::Invert(view).Pointer());
277}

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 330 of file ShaderUtil.cpp.

331 {
332 if (!meshId.m_hasJoint || jointMatrix.empty()) {
333 glUniform1i(handle.Uniforms.SkinningMode, 0);
334 return;
335 }
336
337 std::vector<float> result;
338 result.reserve(jointMatrix.size() * 16);
339 for (const mat4& matrix: jointMatrix) {
340 std::copy(matrix.Pointer(), matrix.Pointer() + 16, std::back_inserter(result));
341 }
342
343 glUniformMatrix4fv(handle.Uniforms.JointMatrix, Settings::GetMaxJoints(), GL_FALSE, &result[0]);
344 glUniform1i(handle.Uniforms.SkinningMode, 1);
345}

◆ 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 187 of file ShaderUtil.cpp.

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

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 glDeleteShader(vertexShader);
93 glDeleteShader(fragmentShader);
94 glDeleteProgram(program);
95 return 0;
96 }
97 glDetachShader(program, vertexShader);
98 glDetachShader(program, fragmentShader);
99
100 }
101 glDeleteShader(vertexShader);
102 glDeleteShader(fragmentShader);
103
104 return program;
105}

◆ 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 143 of file ShaderUtil.cpp.

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

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 107 of file ShaderUtil.cpp.

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

Referenced by createProgram().


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