CShader: Make use of unique_ptr where applicable

Prevents unsafe allocations by default.
This commit is contained in:
Lioncash 2020-06-16 18:22:33 -04:00
parent 4d34589816
commit a67df9865e
4 changed files with 62 additions and 67 deletions

View File

@ -5,14 +5,10 @@
#include <Common/TString.h> #include <Common/TString.h>
#include <fstream> #include <fstream>
#include <sstream>
bool gDebugDumpShaders = false; static bool gDebugDumpShaders = false;
uint64 gFailedCompileCount = 0; static uint64 gFailedCompileCount = 0;
uint64 gSuccessfulCompileCount = 0; static uint64 gSuccessfulCompileCount = 0;
CShader* CShader::spCurrentShader = nullptr;
int CShader::smNumShaders = 0;
CShader::CShader() CShader::CShader()
{ {
@ -30,18 +26,25 @@ CShader::CShader(const char *pkVertexSource, const char *pkPixelSource)
CShader::~CShader() CShader::~CShader()
{ {
if (mVertexShaderExists) glDeleteShader(mVertexShader); if (mVertexShaderExists)
if (mPixelShaderExists) glDeleteShader(mPixelShader); glDeleteShader(mVertexShader);
if (mProgramExists) glDeleteProgram(mProgram);
if (mPixelShaderExists)
glDeleteShader(mPixelShader);
if (mProgramExists)
glDeleteProgram(mProgram);
if (spCurrentShader == this)
spCurrentShader = nullptr;
if (spCurrentShader == this) spCurrentShader = 0;
smNumShaders--; smNumShaders--;
} }
bool CShader::CompileVertexSource(const char* pkSource) bool CShader::CompileVertexSource(const char* pkSource)
{ {
mVertexShader = glCreateShader(GL_VERTEX_SHADER); mVertexShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(mVertexShader, 1, (const GLchar**) &pkSource, NULL); glShaderSource(mVertexShader, 1, (const GLchar**) &pkSource, nullptr);
glCompileShader(mVertexShader); glCompileShader(mVertexShader);
// Shader should be compiled - check for errors // Shader should be compiled - check for errors
@ -76,7 +79,7 @@ bool CShader::CompileVertexSource(const char* pkSource)
bool CShader::CompilePixelSource(const char* pkSource) bool CShader::CompilePixelSource(const char* pkSource)
{ {
mPixelShader = glCreateShader(GL_FRAGMENT_SHADER); mPixelShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(mPixelShader, 1, (const GLchar**) &pkSource, NULL); glShaderSource(mPixelShader, 1, (const GLchar**) &pkSource, nullptr);
glCompileShader(mPixelShader); glCompileShader(mPixelShader);
// Shader should be compiled - check for errors // Shader should be compiled - check for errors
@ -110,7 +113,8 @@ bool CShader::CompilePixelSource(const char* pkSource)
bool CShader::LinkShaders() bool CShader::LinkShaders()
{ {
if ((!mVertexShaderExists) || (!mPixelShaderExists)) return false; if (!mVertexShaderExists || !mPixelShaderExists)
return false;
mProgram = glCreateProgram(); mProgram = glCreateProgram();
glAttachShader(mProgram, mVertexShader); glAttachShader(mProgram, mVertexShader);
@ -133,17 +137,12 @@ bool CShader::LinkShaders()
GLint LogLen; GLint LogLen;
glGetProgramiv(mProgram, GL_INFO_LOG_LENGTH, &LogLen); glGetProgramiv(mProgram, GL_INFO_LOG_LENGTH, &LogLen);
GLchar *pInfoLog = new GLchar[LogLen]; auto pInfoLog = std::unique_ptr<GLchar[]>(new GLchar[LogLen]);
glGetProgramInfoLog(mProgram, LogLen, NULL, pInfoLog); glGetProgramInfoLog(mProgram, LogLen, nullptr, pInfoLog.get());
std::ofstream LinkOut;
LinkOut.open(*Out);
std::ofstream LinkOut(*Out);
if (LogLen > 0) if (LogLen > 0)
LinkOut << pInfoLog; LinkOut << pInfoLog.get();
LinkOut.close();
delete[] pInfoLog;
gFailedCompileCount++; gFailedCompileCount++;
glDeleteProgram(mProgram); glDeleteProgram(mProgram);
@ -214,7 +213,7 @@ void CShader::SetCurrent()
} }
// ************ STATIC ************ // ************ STATIC ************
CShader* CShader::FromResourceFile(const TString& rkShaderName) std::unique_ptr<CShader> CShader::FromResourceFile(const TString& rkShaderName)
{ {
TString VertexShaderFilename = gDataDir + "resources/shaders/" + rkShaderName + ".vs"; TString VertexShaderFilename = gDataDir + "resources/shaders/" + rkShaderName + ".vs";
TString PixelShaderFilename = gDataDir + "resources/shaders/" + rkShaderName + ".ps"; TString PixelShaderFilename = gDataDir + "resources/shaders/" + rkShaderName + ".ps";
@ -227,7 +226,7 @@ CShader* CShader::FromResourceFile(const TString& rkShaderName)
if (VertexShaderText.IsEmpty() || PixelShaderText.IsEmpty()) if (VertexShaderText.IsEmpty() || PixelShaderText.IsEmpty())
return nullptr; return nullptr;
CShader *pShader = new CShader(); auto pShader = std::make_unique<CShader>();
pShader->CompileVertexSource(*VertexShaderText); pShader->CompileVertexSource(*VertexShaderText);
pShader->CompilePixelSource(*PixelShaderText); pShader->CompilePixelSource(*PixelShaderText);
pShader->LinkShaders(); pShader->LinkShaders();
@ -241,7 +240,7 @@ CShader* CShader::CurrentShader()
void CShader::KillCachedShader() void CShader::KillCachedShader()
{ {
spCurrentShader = 0; spCurrentShader = nullptr;
} }
// ************ PRIVATE ************ // ************ PRIVATE ************
@ -258,26 +257,20 @@ void CShader::CacheCommonUniforms()
void CShader::DumpShaderSource(GLuint Shader, const TString& rkOut) void CShader::DumpShaderSource(GLuint Shader, const TString& rkOut)
{ {
GLint SourceLen; GLint SourceLen = 0;
glGetShaderiv(Shader, GL_SHADER_SOURCE_LENGTH, &SourceLen); glGetShaderiv(Shader, GL_SHADER_SOURCE_LENGTH, &SourceLen);
GLchar *Source = new GLchar[SourceLen]; auto Source = std::unique_ptr<GLchar[]>(new GLchar[SourceLen]);
glGetShaderSource(Shader, SourceLen, NULL, Source); glGetShaderSource(Shader, SourceLen, nullptr, Source.get());
GLint LogLen; GLint LogLen = 0;
glGetShaderiv(Shader, GL_INFO_LOG_LENGTH, &LogLen); glGetShaderiv(Shader, GL_INFO_LOG_LENGTH, &LogLen);
GLchar *pInfoLog = new GLchar[LogLen]; auto pInfoLog = std::unique_ptr<GLchar[]>(new GLchar[LogLen]);
glGetShaderInfoLog(Shader, LogLen, NULL, pInfoLog); glGetShaderInfoLog(Shader, LogLen, nullptr, pInfoLog.get());
std::ofstream ShaderOut; std::ofstream ShaderOut(*rkOut);
ShaderOut.open(*rkOut);
if (SourceLen > 0) if (SourceLen > 0)
ShaderOut << Source; ShaderOut << Source.get();
if (LogLen > 0) if (LogLen > 0)
ShaderOut << pInfoLog; ShaderOut << pInfoLog.get();
ShaderOut.close();
delete[] Source;
delete[] pInfoLog;
} }

View File

@ -3,6 +3,8 @@
#include <Common/TString.h> #include <Common/TString.h>
#include <GL/glew.h> #include <GL/glew.h>
#include <array>
#include <memory>
class CShader class CShader
{ {
@ -20,11 +22,11 @@ class CShader
GLuint mBoneTransformBlockIndex = 0; GLuint mBoneTransformBlockIndex = 0;
// Cached uniform locations // Cached uniform locations
GLint mTextureUniforms[8] = {}; std::array<GLint, 8> mTextureUniforms{};
GLint mNumLightsUniform = 0; GLint mNumLightsUniform = 0;
static int smNumShaders; static inline int smNumShaders = 0;
static CShader* spCurrentShader; static inline CShader* spCurrentShader = nullptr;
public: public:
CShader(); CShader();
@ -43,7 +45,7 @@ public:
void SetCurrent(); void SetCurrent();
// Static // Static
static CShader* FromResourceFile(const TString& rkShaderName); static std::unique_ptr<CShader> FromResourceFile(const TString& rkShaderName);
static CShader* CurrentShader(); static CShader* CurrentShader();
static void KillCachedShader(); static void KillCachedShader();

View File

@ -318,7 +318,7 @@ void CDrawUtil::UseCollisionShader(bool IsFloor, bool IsUnstandable, const CColo
CShader* CDrawUtil::GetTextShader() CShader* CDrawUtil::GetTextShader()
{ {
Init(); Init();
return mpTextShader; return mpTextShader.get();
} }
void CDrawUtil::LoadCheckerboardTexture(uint32 GLTextureUnit) void CDrawUtil::LoadCheckerboardTexture(uint32 GLTextureUnit)
@ -553,18 +553,18 @@ void CDrawUtil::InitTextures()
void CDrawUtil::Shutdown() void CDrawUtil::Shutdown()
{ {
if (mDrawUtilInitialized) if (!mDrawUtilInitialized)
{ return;
debugf("Shutting down");
mGridVertices = std::nullopt; debugf("Shutting down");
mSquareVertices = std::nullopt; mGridVertices.reset();
mLineVertices = std::nullopt; mSquareVertices.reset();
mWireCubeVertices = std::nullopt; mLineVertices.reset();
delete mpColorShader; mWireCubeVertices.reset();
delete mpColorShaderLighting; mpColorShader.reset();
delete mpTextureShader; mpColorShaderLighting.reset();
delete mpCollisionShader; mpTextureShader.reset();
delete mpTextShader; mpCollisionShader.reset();
mDrawUtilInitialized = false; mpTextShader.reset();
} mDrawUtilInitialized = false;
} }

View File

@ -46,13 +46,13 @@ class CDrawUtil
static inline TResPtr<CModel> mpWireSphereModel; static inline TResPtr<CModel> mpWireSphereModel;
// Shaders // Shaders
static inline CShader *mpColorShader = nullptr; static inline std::unique_ptr<CShader> mpColorShader;
static inline CShader *mpColorShaderLighting = nullptr; static inline std::unique_ptr<CShader> mpColorShaderLighting;
static inline CShader *mpBillboardShader = nullptr; static inline std::unique_ptr<CShader> mpBillboardShader;
static inline CShader *mpLightBillboardShader = nullptr; static inline std::unique_ptr<CShader> mpLightBillboardShader;
static inline CShader *mpTextureShader = nullptr; static inline std::unique_ptr<CShader> mpTextureShader;
static inline CShader *mpCollisionShader = nullptr; static inline std::unique_ptr<CShader> mpCollisionShader;
static inline CShader *mpTextShader = nullptr; static inline std::unique_ptr<CShader> mpTextShader;
// Textures // Textures
static inline TResPtr<CTexture> mpCheckerTexture; static inline TResPtr<CTexture> mpCheckerTexture;