mirror of
https://github.com/ciphervance/supercell-wx.git
synced 2025-10-30 21:10:04 +00:00
Add support for loading geometry shaders (and other shaders)
This commit is contained in:
parent
0c5a504ad5
commit
913151e063
2 changed files with 70 additions and 65 deletions
|
|
@ -15,6 +15,11 @@ static const auto logger_ = scwx::util::Logger::Create(logPrefix_);
|
||||||
|
|
||||||
static constexpr GLsizei kInfoLogBufSize = 512;
|
static constexpr GLsizei kInfoLogBufSize = 512;
|
||||||
|
|
||||||
|
static const std::unordered_map<GLenum, std::string> kShaderNames_ {
|
||||||
|
{GL_VERTEX_SHADER, "vertex"},
|
||||||
|
{GL_GEOMETRY_SHADER, "geometry"},
|
||||||
|
{GL_FRAGMENT_SHADER, "fragment"}};
|
||||||
|
|
||||||
class ShaderProgram::Impl
|
class ShaderProgram::Impl
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
@ -30,6 +35,8 @@ public:
|
||||||
gl_.glDeleteProgram(id_);
|
gl_.glDeleteProgram(id_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static std::string ShaderName(GLenum type);
|
||||||
|
|
||||||
OpenGLFunctions& gl_;
|
OpenGLFunctions& gl_;
|
||||||
|
|
||||||
GLuint id_;
|
GLuint id_;
|
||||||
|
|
@ -49,10 +56,27 @@ GLuint ShaderProgram::id() const
|
||||||
return p->id_;
|
return p->id_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string ShaderProgram::Impl::ShaderName(GLenum type)
|
||||||
|
{
|
||||||
|
auto it = kShaderNames_.find(type);
|
||||||
|
if (it != kShaderNames_.cend())
|
||||||
|
{
|
||||||
|
return it->second;
|
||||||
|
}
|
||||||
|
return fmt::format("{:#06x}", type);
|
||||||
|
}
|
||||||
|
|
||||||
bool ShaderProgram::Load(const std::string& vertexPath,
|
bool ShaderProgram::Load(const std::string& vertexPath,
|
||||||
const std::string& fragmentPath)
|
const std::string& fragmentPath)
|
||||||
{
|
{
|
||||||
logger_->debug("Load: {}, {}", vertexPath, fragmentPath);
|
return Load({{GL_VERTEX_SHADER, vertexPath}, //
|
||||||
|
{GL_FRAGMENT_SHADER, fragmentPath}});
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ShaderProgram::Load(
|
||||||
|
std::initializer_list<std::pair<GLenum, std::string>> shaders)
|
||||||
|
{
|
||||||
|
logger_->debug("Load()");
|
||||||
|
|
||||||
OpenGLFunctions& gl = p->gl_;
|
OpenGLFunctions& gl = p->gl_;
|
||||||
|
|
||||||
|
|
@ -61,81 +85,59 @@ bool ShaderProgram::Load(const std::string& vertexPath,
|
||||||
char infoLog[kInfoLogBufSize];
|
char infoLog[kInfoLogBufSize];
|
||||||
GLsizei logLength;
|
GLsizei logLength;
|
||||||
|
|
||||||
QFile vertexFile(vertexPath.c_str());
|
std::vector<GLuint> shaderIds {};
|
||||||
QFile fragmentFile(fragmentPath.c_str());
|
|
||||||
|
|
||||||
vertexFile.open(QIODevice::ReadOnly | QIODevice::Text);
|
for (auto& shader : shaders)
|
||||||
fragmentFile.open(QIODevice::ReadOnly | QIODevice::Text);
|
|
||||||
|
|
||||||
if (!vertexFile.isOpen())
|
|
||||||
{
|
{
|
||||||
logger_->error("Could not load vertex shader: {}", vertexPath);
|
logger_->debug("Loading {} shader: {}",
|
||||||
return false;
|
Impl::ShaderName(shader.first),
|
||||||
}
|
shader.second);
|
||||||
|
|
||||||
if (!fragmentFile.isOpen())
|
QFile file(shader.second.c_str());
|
||||||
{
|
file.open(QIODevice::ReadOnly | QIODevice::Text);
|
||||||
logger_->error("Could not load fragment shader: {}", fragmentPath);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
QTextStream vertexShaderStream(&vertexFile);
|
if (!file.isOpen())
|
||||||
QTextStream fragmentShaderStream(&fragmentFile);
|
{
|
||||||
|
logger_->error("Could not load shader");
|
||||||
|
success = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
vertexShaderStream.setEncoding(QStringConverter::Utf8);
|
QTextStream shaderStream(&file);
|
||||||
fragmentShaderStream.setEncoding(QStringConverter::Utf8);
|
shaderStream.setEncoding(QStringConverter::Utf8);
|
||||||
|
|
||||||
std::string vertexShaderSource = vertexShaderStream.readAll().toStdString();
|
std::string shaderSource = shaderStream.readAll().toStdString();
|
||||||
std::string fragmentShaderSource =
|
const char* shaderSourceC = shaderSource.c_str();
|
||||||
fragmentShaderStream.readAll().toStdString();
|
|
||||||
|
|
||||||
const char* vertexShaderSourceC = vertexShaderSource.c_str();
|
// Create a vertex shader
|
||||||
const char* fragmentShaderSourceC = fragmentShaderSource.c_str();
|
GLuint shaderId = gl.glCreateShader(shader.first);
|
||||||
|
shaderIds.push_back(shaderId);
|
||||||
|
|
||||||
// Create a vertex shader
|
// Attach the shader source code and compile the shader
|
||||||
GLuint vertexShader = gl.glCreateShader(GL_VERTEX_SHADER);
|
gl.glShaderSource(shaderId, 1, &shaderSourceC, NULL);
|
||||||
|
gl.glCompileShader(shaderId);
|
||||||
|
|
||||||
// Attach the shader source code and compile the shader
|
// Check for errors
|
||||||
gl.glShaderSource(vertexShader, 1, &vertexShaderSourceC, NULL);
|
gl.glGetShaderiv(shaderId, GL_COMPILE_STATUS, &glSuccess);
|
||||||
gl.glCompileShader(vertexShader);
|
gl.glGetShaderInfoLog(shaderId, kInfoLogBufSize, &logLength, infoLog);
|
||||||
|
if (!glSuccess)
|
||||||
// Check for errors
|
{
|
||||||
gl.glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &glSuccess);
|
logger_->error("Shader compilation failed: {}", infoLog);
|
||||||
gl.glGetShaderInfoLog(vertexShader, kInfoLogBufSize, &logLength, infoLog);
|
success = false;
|
||||||
if (!glSuccess)
|
break;
|
||||||
{
|
}
|
||||||
logger_->error("Vertex shader compilation failed: {}", infoLog);
|
else if (logLength > 0)
|
||||||
success = false;
|
{
|
||||||
}
|
logger_->error("Shader compiled with warnings: {}", infoLog);
|
||||||
else if (logLength > 0)
|
}
|
||||||
{
|
|
||||||
logger_->error("Vertex shader compiled with warnings: {}", infoLog);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create a fragment shader
|
|
||||||
GLuint fragmentShader = gl.glCreateShader(GL_FRAGMENT_SHADER);
|
|
||||||
|
|
||||||
// Attach the shader source and compile the shader
|
|
||||||
gl.glShaderSource(fragmentShader, 1, &fragmentShaderSourceC, NULL);
|
|
||||||
gl.glCompileShader(fragmentShader);
|
|
||||||
|
|
||||||
// Check for errors
|
|
||||||
gl.glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &glSuccess);
|
|
||||||
gl.glGetShaderInfoLog(fragmentShader, kInfoLogBufSize, &logLength, infoLog);
|
|
||||||
if (!glSuccess)
|
|
||||||
{
|
|
||||||
logger_->error("Fragment shader compilation failed: {}", infoLog);
|
|
||||||
success = false;
|
|
||||||
}
|
|
||||||
else if (logLength > 0)
|
|
||||||
{
|
|
||||||
logger_->error("Fragment shader compiled with warnings: {}", infoLog);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (success)
|
if (success)
|
||||||
{
|
{
|
||||||
gl.glAttachShader(p->id_, vertexShader);
|
for (auto& shaderId : shaderIds)
|
||||||
gl.glAttachShader(p->id_, fragmentShader);
|
{
|
||||||
|
gl.glAttachShader(p->id_, shaderId);
|
||||||
|
}
|
||||||
gl.glLinkProgram(p->id_);
|
gl.glLinkProgram(p->id_);
|
||||||
|
|
||||||
// Check for errors
|
// Check for errors
|
||||||
|
|
@ -153,8 +155,10 @@ bool ShaderProgram::Load(const std::string& vertexPath,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delete shaders
|
// Delete shaders
|
||||||
gl.glDeleteShader(vertexShader);
|
for (auto& shaderId : shaderIds)
|
||||||
gl.glDeleteShader(fragmentShader);
|
{
|
||||||
|
gl.glDeleteShader(shaderId);
|
||||||
|
}
|
||||||
|
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,7 @@ public:
|
||||||
GLuint id() const;
|
GLuint id() const;
|
||||||
|
|
||||||
bool Load(const std::string& vertexPath, const std::string& fragmentPath);
|
bool Load(const std::string& vertexPath, const std::string& fragmentPath);
|
||||||
|
bool Load(std::initializer_list<std::pair<GLenum, std::string>> shaderPaths);
|
||||||
|
|
||||||
void Use() const;
|
void Use() const;
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue