Skip to content

Commit 1c6df4a

Browse files
authored
Refactor shader program creation into a factory (#19)
* Refactor shader program creation into a factory Centralizes complex construction logic and makes debugging easier. Will also enable further abstraction down the road for HLSL, or Vulkan shaders. * Update c-cpp.yml * Update codeql-analysis.yml
1 parent e8e94fc commit 1c6df4a

File tree

12 files changed

+312
-226
lines changed

12 files changed

+312
-226
lines changed

.github/workflows/c-cpp.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ jobs:
1313

1414
steps:
1515
- uses: actions/checkout@v2
16+
- name: apt update
17+
run: sudo apt update
1618
- name: install deps
1719
run: bash ./install-deps-ubuntu.sh
1820
- name: make

.github/workflows/codeql-analysis.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ jobs:
6161
# uses a compiled language
6262

6363
- run: |
64+
sudo apt update
6465
bash ./install-deps-ubuntu.sh
6566
make all
6667

MP-APS/Core/RenderSystem.cpp

Lines changed: 42 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#include "RenderSystem.h"
22

3-
#include "../Graphics/GLShader.h"
3+
#include "../Graphics/GLShaderProgramFactory.h"
44
#include "../Camera.h"
55

66
#include "../Input.h"
@@ -17,8 +17,25 @@
1717
#define GPU_MEMORY_INFO_TOTAL_AVAILABLE_MEMORY_NVX 0x9048
1818
#define GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX 0x9049
1919

20+
/***********************************************************************************/
21+
void GLAPIENTRY
22+
MessageCallback( GLenum source,
23+
GLenum type,
24+
GLuint id,
25+
GLenum severity,
26+
GLsizei length,
27+
const GLchar* message,
28+
const void* userParam )
29+
{
30+
std::fprintf( stderr, "GL CALLBACK: %s type = 0x%x, severity = 0x%x, message = %s\n",
31+
( type == GL_DEBUG_TYPE_ERROR ? "** GL ERROR **" : "" ),
32+
type, severity, message );
33+
}
34+
2035
/***********************************************************************************/
2136
void RenderSystem::Init(const pugi::xml_node& rendererNode) {
37+
38+
m_rendererNode = rendererNode;
2239

2340
if (!gladLoadGLLoader(reinterpret_cast<GLADloadproc>(glfwGetProcAddress))) {
2441
std::cerr << "Failed to start GLAD.";
@@ -29,7 +46,7 @@ void RenderSystem::Init(const pugi::xml_node& rendererNode) {
2946

3047
std::cout << m_caps << '\n';
3148

32-
#ifdef _DEBUG
49+
#ifndef NDEBUG
3350
std::cout << "OpenGL Version: " << glGetString(GL_VERSION) << '\n';
3451
std::cout << "GLSL Version: " << glGetString(GL_SHADING_LANGUAGE_VERSION) << '\n';
3552
std::cout << "OpenGL Driver Vendor: " << glGetString(GL_VENDOR) << '\n';
@@ -46,32 +63,16 @@ void RenderSystem::Init(const pugi::xml_node& rendererNode) {
4663
m_hdrFBO.Init("HDR FBO");
4764
m_skybox.Init("Data/hdri/barcelona.hdr", 2048);
4865

49-
// Compile all shader programs in config.xml
50-
for (auto program = rendererNode.child("Program"); program; program = program.next_sibling("Program")) {
51-
52-
// Get all shader files that make up the program
53-
std::vector<GLShader> shaders;
54-
for (auto shader = program.child("Shader"); shader; shader = shader.next_sibling("Shader")) {
55-
shaders.emplace_back(shader.attribute("path").as_string(), shader.attribute("type").as_string());
56-
}
57-
58-
//GLShaderProgram prgrm;
59-
//prgrm.Init(program.attribute("name").as_string(), shaders);
60-
61-
// Compile and cache shader program
62-
//m_shaderCache.try_emplace(program.attribute("name").as_string(), prgrm);
63-
m_shaderCache.try_emplace(program.attribute("name").as_string(), program.attribute("name").as_string(), shaders);
64-
}
66+
compileShaders();
6567

6668
setupScreenquad();
6769
setupTextureSamplers();
6870
setupShadowMap();
6971
setupPostProcessing();
7072

71-
#ifdef _DEBUG
7273
glEnable(GL_DEBUG_OUTPUT);
7374
glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
74-
#endif
75+
//glDebugMessageCallback(MessageCallback, nullptr);
7576
setDefaultState();
7677
glEnable(GL_MULTISAMPLE);
7778

@@ -213,6 +214,27 @@ void RenderSystem::UpdateView(const Camera& camera) {
213214
glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(glm::mat4), glm::value_ptr(m_projMatrix));
214215
}
215216

217+
/***********************************************************************************/
218+
void RenderSystem::compileShaders() {
219+
m_shaderCache.clear();
220+
for (auto program = m_rendererNode.child("Program"); program; program = program.next_sibling("Program")) {
221+
222+
// Get all shader files that make up the program
223+
std::vector<Graphics::ShaderStage> stages;
224+
for (auto shader = program.child("Shader"); shader; shader = shader.next_sibling("Shader")) {
225+
stages.emplace_back(shader.attribute("path").as_string(), shader.attribute("type").as_string());
226+
}
227+
228+
std::string name{ program.attribute("name").as_string() };
229+
230+
auto shaderProgram{ Graphics::GLShaderProgramFactory::createShaderProgram(name, stages) };
231+
232+
if (shaderProgram) {
233+
m_shaderCache.try_emplace(name, std::move(shaderProgram.value())); // value_or for default and remove if-check?
234+
}
235+
}
236+
}
237+
216238
/***********************************************************************************/
217239
void RenderSystem::queryHardwareCaps() {
218240
// Anisotropic filtering

MP-APS/Core/RenderSystem.h

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
#include "../Graphics/GLShaderProgram.h"
88
#include "../Graphics/HardwareCaps.h"
99

10+
#include <pugixml.hpp>
11+
1012
#include <unordered_map>
1113
#include <vector>
1214

@@ -18,9 +20,6 @@
1820
class Camera;
1921
class SceneBase;
2022
class GLShaderProgram;
21-
namespace pugi {
22-
class xml_node;
23-
}
2423

2524
/***********************************************************************************/
2625
class RenderSystem {
@@ -48,6 +47,8 @@ class RenderSystem {
4847
private:
4948
// Helper functions
5049

50+
//
51+
void compileShaders();
5152
//
5253
void queryHardwareCaps();
5354
// Sets the default state required for rendering
@@ -71,6 +72,8 @@ class RenderSystem {
7172
// Sets projection matrix variable and updates UBO
7273
void setProjectionMatrix(const Camera& camera);
7374

75+
pugi::xml_node m_rendererNode;
76+
7477
Graphics::HardwareCaps m_caps;
7578

7679
// Screen dimensions

MP-APS/Graphics/GLShader.cpp

Lines changed: 0 additions & 110 deletions
This file was deleted.

MP-APS/Graphics/GLShader.h

Lines changed: 0 additions & 29 deletions
This file was deleted.

MP-APS/Graphics/GLShaderProgram.cpp

Lines changed: 9 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,13 @@
11
#include "GLShaderProgram.h"
22

3-
#include "GLShader.h"
4-
3+
#include <cassert>
54
#include <iostream>
6-
#include <string_view>
7-
#include <string>
85

96
/***********************************************************************************/
10-
GLShaderProgram::GLShaderProgram(const std::string_view programName, const std::vector<GLShader>& shaders) : m_programName(programName) {
11-
m_programID = glCreateProgram();
12-
13-
for (const auto& shader : shaders) {
14-
shader.AttachShader(m_programID);
15-
}
16-
17-
if (linkAndValidate()) {
18-
getUniforms();
19-
}
20-
21-
// Cleanup
22-
for (const auto& shader : shaders) {
23-
shader.DetachShader(m_programID);
24-
shader.DeleteShader();
25-
}
7+
GLShaderProgram::GLShaderProgram(const std::string& programName, const GLuint programID) :
8+
m_programName(programName), m_programID(programID)
9+
{
10+
getUniforms();
2611
}
2712

2813
/***********************************************************************************/
@@ -32,12 +17,15 @@ GLShaderProgram::~GLShaderProgram() {
3217

3318
/***********************************************************************************/
3419
void GLShaderProgram::Bind() const {
20+
assert(m_programID != 0);
21+
3522
glUseProgram(m_programID);
3623
}
3724

3825
/***********************************************************************************/
3926
void GLShaderProgram::DeleteProgram() const {
4027
if (m_programID != 0) {
28+
std::cout << "Deleting program: " << m_programName << '\n';
4129
glDeleteProgram(m_programID);
4230
}
4331
}
@@ -98,28 +86,6 @@ GLShaderProgram& GLShaderProgram::SetUniform(const std::string& uniformName, con
9886
return *this;
9987
}
10088

101-
/***********************************************************************************/
102-
bool GLShaderProgram::linkAndValidate() {
103-
104-
glLinkProgram(m_programID);
105-
glGetProgramiv(m_programID, GL_LINK_STATUS, &m_success);
106-
if (!m_success) {
107-
glGetProgramInfoLog(m_programID, m_infoLog.size(), nullptr, m_infoLog.data());
108-
std::cerr << "Shader Program Linking Error: " << m_infoLog.data() << std::endl;
109-
return false;
110-
}
111-
112-
glValidateProgram(m_programID);
113-
glGetProgramiv(m_programID, GL_VALIDATE_STATUS, &m_success);
114-
if (!m_success) {
115-
glGetProgramInfoLog(m_programID, m_infoLog.size(), nullptr, m_infoLog.data());
116-
std::cerr << "Shader Program Validation Error: " << m_infoLog.data() << std::endl;
117-
return false;
118-
}
119-
120-
return true;
121-
}
122-
12389
/***********************************************************************************/
12490
void GLShaderProgram::getUniforms() {
12591

@@ -137,4 +103,4 @@ void GLShaderProgram::getUniforms() {
137103
// TODO: Filter out uniform block members using glGetActiveUniformsiv
138104
m_uniforms.try_emplace(nameStr, glGetUniformLocation(m_programID, name));
139105
}
140-
}
106+
}

0 commit comments

Comments
 (0)