OpenGL_11:封装一个自己的着色器类
2017-10-19 00:56
232 查看
之前都是通过读取着色器字符串来创建着色器,这样耦合程度很高,并且生成、链接着色器程序也需要写很繁杂的过程。现在我编写一个Shader类来读取着色器文本文件,并且封装那些繁杂的步骤。
Shader头文件:
Shader.cpp:
使用步骤:
Shader头文件:
#ifndef INC_10_SHADER_LOADER_SHADER_H #define INC_10_SHADER_LOADER_SHADER_H #include <glad/glad.h> #include <string> #include <fstream> #include <sstream> #include <iostream> class Shader { private: unsigned int id; public: Shader(const char* vertexPath, const char* fragmentShader); void use(); void setBool(const char* name, bool value) const; void setInt(const char* name, int value) const; void setFloat(const char* name, float value) const; private: void checkCompileErrors(unsigned int shader, std::string type); }; #endif //INC_10_SHADER_LOADER_SHADER_H
Shader.cpp:
#include "Shader.h" Shader::Shader(const char *vertexShaderPath, const char *fragmentShaderPath) { std::string vertexCode; std::string fragmentCode; std::ifstream vShaderFile; std::ifstream fShaderFile; //保证ifstream对象可以抛出异常 vShaderFile.exceptions(std::ifstream::failbit | std::ifstream::badbit); fShaderFile.exceptions(std::ifstream::failbit | std::if 4000 stream::badbit); try { //打开文件 vShaderFile.open(vertexShaderPath); fShaderFile.open(fragmentShaderPath); //读取文件缓冲内容到数据流里 std::stringstream vShaderStream, fShaderStream; vShaderStream << vShaderFile.rdbuf(); fShaderStream << fShaderFile.rdbuf(); //关闭文件处理器 vShaderFile.close(); fShaderFile.close(); //把数据流转换成string vertexCode = vShaderStream.str(); fragmentCode = fShaderStream.str(); } catch (std::ifstream::failure e){ std::cout << "Failed to read shaderFile" << std::endl; } //再转换成字符数组 const char* vShaderSource = vertexCode.c_str(); const char* fShaderSource = fragmentCode.c_str(); //接着就可以开始编译和连接着色器了 unsigned int vertexShader, fragmentShader; //编译顶点着色器 vertexShader = glCreateShader(GL_VERTEX_SHADER); glShaderSource(vertexShader, 1, &vShaderSource, NULL); glCompileShader(vertexShader); checkCompileErrors(vertexShader, "VERTEX"); //编译片段着色器 fragmentShader = glCreateShader(GL_FRAGMENT_SHADER); glShaderSource(fragmentShader, 1, &fShaderSource, NULL); glCompileShader(fragmentShader); checkCompileErrors(vertexShader, "FRAGMENT"); //链接着色器 id = glCreateProgram(); glAttachShader(id, vertexShader); glAttachShader(id, fragmentShader); glLinkProgram(id); checkCompileErrors(id, "PROGRAM"); //当着色器链接到了程序中,就不再需要了 glDeleteShader(vertexShader); glDeleteShader(fragmentShader); } //激活着色器 void Shader::use() { glUseProgram(this->id); } //设置uniform变量 void Shader::setBool(const char *name, bool value) const { glUniform1i(glGetUniformLocation(this->id, name), (int)value); } //设置uniform变量 void Shader::setInt(const char *name, int value) const { glUniform1i(glGetUniformLocation(this->id, name), value); } //设置uniform变量 void Shader::setFloat(const char *name, float value) const { glUniform1f(glGetUniformLocation(this->id, name), value); } //输出shader编译或program链接的错误信息 void Shader::checkCompileErrors(unsigned int shader, std::string type) { int success; char infoLog[512]; if (type != "PROGRAM"){ glGetShaderiv(shader, GL_COMPILE_STATUS, &success); if (!success){ glGetShaderInfoLog(shader, 512, NULL, infoLog); std::cout << "ERROR: Failed to compile shader of type:"<< type <<std::endl; } } else { glGetShaderiv(shader, GL_LINK_STATUS, &success); if (!success){ glGetShaderInfoLog(shader, 512, NULL, infoLog); std::cout << "ERROR: Failed to link program of type:"<< type <<std::endl; } } }
使用步骤:
Shader *shader = new Shader("../../vertex.glsl", "../../fragment.glsl"); 在渲染循环中{ ... shader->use(); ... }
相关文章推荐
- OpenGL学习笔记(十一):封装自己的着色器类
- 自己封装了一个取得电脑信息及关机相关操作的类
- 自己封装一个获取组件的方法
- 封装一个用户控件的pager.ascx文件供自己使用
- D3D初始化环境 自己封装的一个简单的类
- 自己封装一个Vue2的ShowMore组件
- 大学生活应该这样度过之参加一个社团让自己溶入团队——《程序员羊皮卷》连载(11)
- java基础--20 自己封装一个DateUtil类
- 自己封装一个MySignal函数,方便以后直接copy.
- 官网下载qt-opensource-windows-x86-mingw482_opengl-5.3.1.exe。封装好了Qt libraries、Qt Creator。只需要这一个可执行程序就好了。
- 9. 11. 27. 写与读自己封装ArrayList implements the empty Serializable interface
- 自己封装一个简单的自定义检索
- 自己封装一个插件化框架
- 自己封装的一个纯div+css样式弹出泡泡消息框
- 自己封装的三维AABB包围盒类,用于三维模型静态碰撞检测,可以直接调用,使用OpenGL进行绘制
- 整理 qt opengl,自己的基础框架 —— 绘制一个彩色三角形
- 自己封装的一个简单的倒计时功能实例
- 自己封装的一个工具类
- 自己封装的一个泛型集合基类
- 大学生活应该这样度过之参加一个社团让自己溶入团队——《程序员羊皮卷》连载(11)