OpenGL Four (Shader__Package)

Posted littlebanana

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了OpenGL Four (Shader__Package)相关的知识,希望对你有一定的参考价值。

相信你现在已经写了不少OpenGL的Demo了。一次次的compile和attach着色器是不是很烦。

要想让我们生活愉悦,就不得不封装一个类。( 方便学习,方便移植,方便你我他 )

添加必要的include

#ifndef SHADER_H
#define SHADER_H

#define GLEW_STATIC
#include <GL/glew.h>; // 包含glew来获取所有的必须OpenGL头文件

#include <string>
#include <fstream>
#include <sstream>
#include <iostream>

class Shader{
public:
    // 程序ID
    unsigned int ID;

    // 构造器读取并构建着色器
    Shader(const GLchar* vertexPath, const GLchar* fragmentPath);
    // 使用/激活程序
    void use();
    // uniform工具函数:能够查询一个uniform的位置值并设置它的值。
    void setBool(const std::string &name, bool value) const;  
    void setInt(const std::string &name, int value) const;   
    void setFloat(const std::string &name, float value) const;
};
#endif

从文件读取

  • 我们使用C++文件流读取着色器内容,储存到几个string对象中
//1. 从文件路路径中获取顶点/片段着色器
string vertexCode, fragmentCode;
ifstream vShaderFile, fShaderFile;

//保证ifstream对象可以抛出异常
vShaderFile.exceptions(ifstream::failbit | ifstream::badbit);
fShaderFile.exceptions(ifstream::failbit | ifstream::badbit);

try {
    //打开文件
    vShaderFile.open(vertexPath);
    fShaderFile.open(fragmentPath);

    stringstream vShaderStream, fShaderStream;

    //读取文件的缓冲内容到数据流中
    vShaderStream << vShaderFile.rdbuf();
    fShaderStream << fShaderFile.rdbuf();
    //关闭文件处理器
    vShaderFile.close();
    fShaderFile.close();
    //转换数据流到string
    vertexCode = vShaderStream.str();
    fragmentCode = fShaderStream.str();
}
catch (ifstream::failure e) {
    cout << "ERROR::SHADER::FILE_NOT_SUCCESFULLY_READ" << endl;
}

const char* vShaderCode = vertexCode.c_str();
const char* fShaderCode = fragmentCode.c_str();
  • 下一步就是编译和链接着色器了。
//2. 编译着色器
unsigned int vertex, fragment;
int success;
char infoLog[512];

vertex = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertex, 1, &vShaderCode, NULL);
glCompileShader(vertex);

glGetShaderiv(vertex, GL_COMPILE_STATUS, &success);
if (!success) {
    glGetShaderInfoLog(vertex, 512, NULL, infoLog);
    cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED
" << infoLog << endl;
}

fragment = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragment, 1, &fShaderCode, NULL);
glCompileShader(fragment);

glGetShaderiv(fragment, GL_COMPILE_STATUS, &success);
if (!success) {
    glGetShaderInfoLog(fragment, 512, NULL, infoLog);
    cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED
" << infoLog << endl;
}

this->ID = glCreateProgram();
glAttachShader(this->ID, vertex);
glAttachShader(this->ID, fragment);
glLinkProgram(this->ID);

glGetProgramiv(this->ID, GL_LINK_STATUS, &success);
if (!success) {
    glGetProgramInfoLog(this->ID, 512, NULL, infoLog);
    cout << "ERROR::SHADER::PROGRAM::LINKING_FAILED
" << infoLog << endl;
}

//删除着色器
glDeleteShader(vertex);
glDeleteShader(fragment);
  • 类的完善
void ShaderProgram::use() {
    glUseProgram(this->ID);
}

void ShaderProgram::setBool(const std::string& name, bool value) const{
    glUniform1i(glGetUniformLocation(ID, name.c_str()), (int)value);
}

void ShaderProgram::setInt(const std::string& name, int value) const{
    glUniform1i(glGetUniformLocation(ID, name.c_str()), value);
}

void ShaderProgram::setFloat(const std::string& name, float value) const{
    glUniform1f(glGetUniformLocation(ID, name.c_str()), value);
}

封装好了如何使用呢

  • 首先看一下目录结构撒

技术图片

/* 在需要的时候定义对象就好辣~ */
ShaderProgram shader("vertexShader.glsl", "fragmentShader.glsl");

按照国际惯例,点击获取代码??

以上是关于OpenGL Four (Shader__Package)的主要内容,如果未能解决你的问题,请参考以下文章

OpenGL学习—— Shader

opengl 报错

(Python OpenGL)Uniform变量 PyOpenGL

基于Qt的OpenGL可编程管线学习- 多重纹理

基于Qt的OpenGL可编程管线学习- 使用Subroutine绘制不同光照的模型

shader特效整理