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)的主要内容,如果未能解决你的问题,请参考以下文章
(Python OpenGL)Uniform变量 PyOpenGL