mirror of
				https://github.com/ciphervance/supercell-wx.git
				synced 2025-10-31 01:40: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); | ||||||
|  | 
 | ||||||
|  |       QFile file(shader.second.c_str()); | ||||||
|  |       file.open(QIODevice::ReadOnly | QIODevice::Text); | ||||||
|  | 
 | ||||||
|  |       if (!file.isOpen()) | ||||||
|  |       { | ||||||
|  |          logger_->error("Could not load shader"); | ||||||
|  |          success = false; | ||||||
|  |          break; | ||||||
|       } |       } | ||||||
| 
 | 
 | ||||||
|    if (!fragmentFile.isOpen()) |       QTextStream shaderStream(&file); | ||||||
|    { |       shaderStream.setEncoding(QStringConverter::Utf8); | ||||||
|       logger_->error("Could not load fragment shader: {}", fragmentPath); |  | ||||||
|       return false; |  | ||||||
|    } |  | ||||||
| 
 | 
 | ||||||
|    QTextStream vertexShaderStream(&vertexFile); |       std::string shaderSource  = shaderStream.readAll().toStdString(); | ||||||
|    QTextStream fragmentShaderStream(&fragmentFile); |       const char* shaderSourceC = shaderSource.c_str(); | ||||||
| 
 |  | ||||||
|    vertexShaderStream.setEncoding(QStringConverter::Utf8); |  | ||||||
|    fragmentShaderStream.setEncoding(QStringConverter::Utf8); |  | ||||||
| 
 |  | ||||||
|    std::string vertexShaderSource = vertexShaderStream.readAll().toStdString(); |  | ||||||
|    std::string fragmentShaderSource = |  | ||||||
|       fragmentShaderStream.readAll().toStdString(); |  | ||||||
| 
 |  | ||||||
|    const char* vertexShaderSourceC   = vertexShaderSource.c_str(); |  | ||||||
|    const char* fragmentShaderSourceC = fragmentShaderSource.c_str(); |  | ||||||
| 
 | 
 | ||||||
|       // Create a vertex shader
 |       // Create a vertex shader
 | ||||||
|    GLuint vertexShader = gl.glCreateShader(GL_VERTEX_SHADER); |       GLuint shaderId = gl.glCreateShader(shader.first); | ||||||
|  |       shaderIds.push_back(shaderId); | ||||||
| 
 | 
 | ||||||
|       // Attach the shader source code and compile the shader
 |       // Attach the shader source code and compile the shader
 | ||||||
|    gl.glShaderSource(vertexShader, 1, &vertexShaderSourceC, NULL); |       gl.glShaderSource(shaderId, 1, &shaderSourceC, NULL); | ||||||
|    gl.glCompileShader(vertexShader); |       gl.glCompileShader(shaderId); | ||||||
| 
 | 
 | ||||||
|       // Check for errors
 |       // Check for errors
 | ||||||
|    gl.glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &glSuccess); |       gl.glGetShaderiv(shaderId, GL_COMPILE_STATUS, &glSuccess); | ||||||
|    gl.glGetShaderInfoLog(vertexShader, kInfoLogBufSize, &logLength, infoLog); |       gl.glGetShaderInfoLog(shaderId, kInfoLogBufSize, &logLength, infoLog); | ||||||
|       if (!glSuccess) |       if (!glSuccess) | ||||||
|       { |       { | ||||||
|       logger_->error("Vertex shader compilation failed: {}", infoLog); |          logger_->error("Shader compilation failed: {}", infoLog); | ||||||
|          success = false; |          success = false; | ||||||
|  |          break; | ||||||
|       } |       } | ||||||
|       else if (logLength > 0) |       else if (logLength > 0) | ||||||
|       { |       { | ||||||
|       logger_->error("Vertex shader compiled with warnings: {}", infoLog); |          logger_->error("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
	
	 Dan Paulat
						Dan Paulat