文章目录

  • 统一变量
  • 缺省区块统一变量
  • 排列我们的统一变量
  • 使用统一变量转换几何图形
    • 自己封装的Shader类(改进)
      • Shader.h
      • Shader.cpp
    • shader file
      • vertex shader
      • fragment shader
    • 源码
    • 效果
  • 总结

统一变量

统一变量是一种能够直接将数据从应用程序传递到着色器阶段的变量。
统一变量分为两种形式:
一种是在默认区块中声明的统一变量
另一种是一致区块,该区块的值储存在缓存对象中

缺省区块统一变量

缺省区块统一变量,就是将统一变量放在OpenGL默认的区块当中(我们也可以自己设置区块)。

排列我们的统一变量

通过使用位置配置限定符(layout qualifier),我们可以在着色器编码中指定统一变量的位置。OpenGL会尝试将指定的位置分配给着色器的统一变量。
layout (location = 17) uniform vec4 myUniform;
如果没有在着色器编码过程中为统一变量指定位置,那么OpenGL会自动为这些变量分配位置。我们可以调用
GLuint glGetUniformLocation(GLuint program, const GLchar* name);获取program程序中的名字为name的变量位置
注意:如果统一变量没有使用,那么其名称可能在程序中“消失”

使用统一变量转换几何图形

自己封装的Shader类(改进)

Shader.h

#pragma once
#include "sb7.h"
#include <string>
#include <fstream>
#include <sstream>
#include <iostream>
#include <exception>
#include <vmath.h>
class Shader
{public:GLuint program;public:Shader();Shader(const std::string vertexPath, const std::string fragmentPath);Shader(const std::string vertexPath, const std::string tescPath, const std::string tesePath, const std::string fragmentPath);//program对象使用void use();//设置统一变量void setInt(const char* name, int data) const;void setBool(const char* name, bool data) const;void setFloat(const char* name, float data) const;void setVec2(const char* name, vmath::vec2 data) const;void setVec3(const char* name, vmath::vec3 data) const;void setVec4(const char* name, vmath::vec4 data) const;void setMat2(const char* name, vmath::mat2 data) const;void setMat3(const char* name, vmath::mat3 data) const;void setMat4(const char* name, vmath::mat4 data) const;
private://源代码std::string shaderString;const char* shaderSource;//用于读取shader文件std::ifstream shaderFile;//转换源码std::stringstream shaderSStream;private://查错程序,是否有编译错误void checkCompileErrors(unsigned int ID, std::string type);//读取文件,并且创建着色器对象void readShaderSource(std::string shaderFilePath);//链接着色器void linkShader(GLuint shaderObject, std::string type);//设置顶点着色器void setVertexShder(const std::string vertexPath);//设置曲面细分控制着色器void setTescShader(const std::string tescPath);//设置曲面细分评估着色器void setTeseShader(const std::string tesePath);//设置片段着色器void setFragmentShader(const std::string fragmentPath);//获取一致区块的位置GLuint getUniformLocation(const char* name) const;
};

Shader.cpp

#include "Shader.h"Shader::Shader() {}Shader::Shader(const std::string vertexPath, const std::string fragmentPath)
{//创建程序对象program = glCreateProgram();setVertexShder(vertexPath);setFragmentShader(fragmentPath);}Shader::Shader(const std::string vertexPath, const std::string tescPath, const std::string tesePath, const std::string fragmentPath)
{//创建程序对象program = glCreateProgram();setVertexShder(vertexPath);setFragmentShader(fragmentPath);setTescShader(tescPath);setTeseShader(tesePath);
}//设置顶点着色器
void Shader::setVertexShder(const std::string vertexPath)
{//读取shader源代码readShaderSource(vertexPath);//创建shader对象GLuint vertexShader;vertexShader = glCreateShader(GL_VERTEX_SHADER);//链接shader对象linkShader(vertexShader, "VERTEX");
}//设置曲面细分控制着色器
void Shader::setTescShader(const std::string tescPath)
{//读取shader源代码readShaderSource(tescPath);//创建shader对象GLuint tescShader;tescShader = glCreateShader(GL_TESS_CONTROL_SHADER);//链接shader对象linkShader(tescShader, "TESC");
}//设置曲面细分评估着色器
void Shader::setTeseShader(const std::string tesePath)
{//读取shader源代码readShaderSource(tesePath);//创建shader对象GLuint teseShader;teseShader = glCreateShader(GL_TESS_EVALUATION_SHADER);//链接shader对象linkShader(teseShader, "TESE");
}//设置片段着色器
void Shader::setFragmentShader(const std::string fragmentPath)
{//读取shader源代码readShaderSource(fragmentPath);//创建shader对象GLuint fragmentShader;fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);//链接shader对象linkShader(fragmentShader, "FRAGMENT");
}GLuint Shader::getUniformLocation(const char* name) const
{return glGetUniformLocation(program, name);
}void Shader::use()
{glUseProgram(program);
}void Shader::setInt(const char* name, int data) const
{glUniform1i(getUniformLocation(name), data);
}void Shader::setBool(const char* name, bool data) const
{glUniform1i(getUniformLocation(name), (int)data);
}void Shader::setFloat(const char* name, float data) const
{glUniform1f(getUniformLocation(name), data);
}void Shader::setVec2(const char* name, vmath::vec2 data) const
{glUniform2fv(getUniformLocation(name), 1, data);
}void Shader::setVec3(const char* name, vmath::vec3 data) const
{glUniform3fv(getUniformLocation(name), 1, data);
}void Shader::setVec4(const char* name, vmath::vec4 data) const
{glUniform4fv(getUniformLocation(name), 1, data);
}void Shader::setMat2(const char* name, vmath::mat2 data) const
{glUniformMatrix2fv(getUniformLocation(name), 1, GL_FALSE, data);
}void Shader::setMat3(const char* name, vmath::mat3 data) const
{glUniformMatrix3fv(getUniformLocation(name), 1, GL_FALSE, data);
}void Shader::setMat4(const char* name, vmath::mat4 data) const
{glUniformMatrix4fv(getUniformLocation(name), 1, GL_FALSE, data);
}//读取文件,并且创建着色器对象
void Shader::readShaderSource(std::string shaderFilePath)
{//将上一个shader的源码清理shaderSStream.str("");memset(&shaderSource, '\0', sizeof(shaderSource));//open shader fileif (!shaderFilePath.empty())    //判断文件路径是否为空{//文件路径不为空,打开文件shaderFile.open(shaderFilePath);shaderFile.exceptions(std::ifstream::badbit || std::ifstream::failbit);try{if (!shaderFile.is_open()) //文件打开失败{throw std::exception("open fragment shader file fail");}//文件成功打开//字符串流读取文件中的数据shaderSStream << shaderFile.rdbuf();//读完了,把文件关了shaderFile.close();//把源代码读入字符串中去shaderString = shaderSStream.str();//把string转成系数需要的const char *类型shaderSource = shaderString.c_str();}catch (const std::exception& e){std::cout << e.what() << std::endl;}}
}//链接着色器
void Shader::linkShader(GLuint shaderObject, std::string type)
{//将源代码读入shader对象glShaderSource(shaderObject, 1, &shaderSource, NULL);//编译shader对象中的源码glCompileShader(shaderObject);//检查着色器对象是否有误checkCompileErrors(shaderObject, type);//将shader对象附加到program对象上去glAttachShader(program, shaderObject);//链接program对象上的shader对象glLinkProgram(program);//查错checkCompileErrors(program, "PROGRAM");//完事,可以把shader对象删了glDeleteShader(shaderObject);
}/*
* 查错
*/
void Shader::checkCompileErrors(unsigned int ID, std::string type)
{int success;char infoLog[512];if (type != "PROGRAM"){glGetShaderiv(ID, GL_COMPILE_STATUS, &success);if (!success){glGetShaderInfoLog(ID, 512, NULL, infoLog);std::cout << "shader compile error: " << infoLog << std::endl;}}else{glGetProgramiv(ID, GL_LINK_STATUS, &success);if (!success){glGetProgramInfoLog(ID, 512, NULL, infoLog);std::cout << "program linking error: " << infoLog << std::endl;}}
}

shader file

vertex shader

#version 450 core
layout(location = 0) in vec3 position;uniform mat4 mv_matrix;
uniform mat4 proj_matrix;out VS_OUT
{vec4 color;
} vs_out;void main()
{gl_Position = proj_matrix * mv_matrix * vec4(position, 1.0);vs_out.color = vec4(position, 1.0) * 2.0 + vec4(0.5, 0.5, 0.5, 0.0);
}

fragment shader

#version 450 core
layout(location = 0) uniform vec4 icolor;out vec4 color;in VS_OUT
{vec4 color;
} vs_out;void main()
{color = vs_out.color;
}

源码

#include "sb7.h"
#include <iostream>
#include "Shader.h"
#include <math.h>
#include <vmath.h>class my_application : public sb7::application
{public:void startup(){static const float vertex_positiona[] ={-0.25f, -0.25f, -0.25f,0.25f, -0.25f, -0.25f,0.25f,  0.25f, -0.25f,0.25f,  0.25f, -0.25f,-0.25f,  0.25f, -0.25f,-0.25f, -0.25f, -0.25f,-0.25f, -0.25f,  0.25f,0.25f, -0.25f,  0.25f,0.25f,  0.25f,  0.25f,0.25f,  0.25f,  0.25f,-0.25f,  0.25f,  0.25f,-0.25f, -0.25f,  0.25f,-0.25f,  0.25f,  0.25f,-0.25f,  0.25f, -0.25f,-0.25f, -0.25f, -0.25f,-0.25f, -0.25f, -0.25f,-0.25f, -0.25f,  0.25f,-0.25f,  0.25f,  0.25f,0.25f,  0.25f,  0.25f,0.25f,  0.25f, -0.25f,0.25f, -0.25f, -0.25f,0.25f, -0.25f, -0.25f,0.25f, -0.25f,  0.25f,0.25f,  0.25f,  0.25f,-0.25f, -0.25f, -0.25f,0.25f, -0.25f, -0.25f,0.25f, -0.25f,  0.25f,0.25f, -0.25f,  0.25f,-0.25f, -0.25f,  0.25f,-0.25f, -0.25f, -0.25f,-0.25f,  0.25f, -0.25f,0.25f,  0.25f, -0.25f,0.25f,  0.25f,  0.25f,0.25f,  0.25f,  0.25f,-0.25f,  0.25f,  0.25f,-0.25f,  0.25f, -0.25f};shader = new Shader("vs.vert", "fs.frag");program = shader->program;//创建vao对象glCreateVertexArrays(1, &vao);//绑定vao到上下文glBindVertexArray(vao);//创建vbo对象glCreateBuffers(1, &vbo);//绑定vboglBindBuffer(GL_ARRAY_BUFFER, vbo);//为缓冲申请内存,并且赋予初始数据glNamedBufferStorage(vbo, sizeof(vertex_positiona), vertex_positiona, GL_DYNAMIC_STORAGE_BIT);//绑定缓冲到vaoglVertexArrayVertexBuffer(vao, 0, vbo, 0, sizeof(float) * 3);//缓冲的布局glVertexArrayAttribFormat(vao, 0, 3, GL_FLOAT, GL_FALSE, 0);//指示vao的顶点属性从哪个绑定点缓冲哪数据glVertexArrayAttribBinding(vao, 0, 0);glEnableVertexArrayAttrib(vao, 0);//深度测试glEnable(GL_DEPTH_TEST);}void render(double currentTime){GLfloat color[] = { 1.0, 1.0, 1.0, 1.0 };glClearBufferfv(GL_COLOR, 0, color);glClearBufferfi(GL_DEPTH_STENCIL, 0, 1.0f, 0);GLfloat icolor[4] = {(float)sin(currentTime) * 0.5 + 0.5,(float)cos(currentTime) * 0.5 + 0.5,0.0, 1.0};glUniform4fv(0, 1, icolor);float aspect = (float)info.windowWidth / (float)info.windowHeight;//投影矩阵vmath::mat4 proj_matrix = vmath::perspective(50.f, aspect, 0.1f, 1000.f);shader->use();/*vmath::mat4 mv_matrix = vmath::translate(0.0f, 0.0f, -4.0f) *vmath::translate(sinf(2.1f * f) * 0.5f,cosf(1.7f * f) * 0.5f,sinf(1.3f * f) * cosf(1.5f * f) * 2.0f) *vmath::rotate((float)currentTime * 45.0f, 0.0f, 1.0f, 0.0f) *vmath::rotate((float)currentTime * 81.0f, 1.0f, 0.0f, 0.0f);*///渲染24个立方体for (size_t i = 0; i < 24; i++){float f = float(currentTime) * 0.3f + (float)i;//model view矩阵vmath::mat4 mv_matrix = vmath::translate(0.0f, 0.0f, -5.f) *vmath::rotate((float)currentTime * 45.0f, 0.0f, 1.0f, 0.0f) *vmath::rotate((float)currentTime * 21.0f, 1.0f, 0.0f, 0.0f) *vmath::translate(sinf(2.1f * f) * 2.0f, cosf(1.7f * f) * 2.0f, sinf(1.3f * f) * cosf(1.5f * f) * 2.0f);shader->setMat4("mv_matrix", mv_matrix);shader->setMat4("proj_matrix", proj_matrix);glDrawArrays(GL_TRIANGLES, 0, 36);}}void shutdown() {}private:Shader* shader;GLuint program;GLuint vao;GLuint vbo;
};DECLARE_MAIN(my_application);

效果

总结

统一变量就是可以一种从程序把数据传到着色器里面的数据类型。

OpenGL超级宝典 统一变量(uniform variable)相关推荐

  1. OpenGL超级宝典(第7版)笔记20 统一变量 一致区块 uniform相关内容 清单5.9-5.28

    OpenGL超级宝典(第7版)笔记20 统一变量 一致区块 uniform相关内容 清单5.9-5.28 文章目录 OpenGL超级宝典(第7版)笔记20 统一变量 一致区块 uniform相关内容 ...

  2. OpenGL 统一变量uniform

    OpenGL统一变量uniform OpenGL统一变量uniform简介 源代码剖析 主要源代码 OpenGL统一变量uniform简介 在本课中,我们将介绍着色器中的一种新型变量 - unifor ...

  3. [转]OpenGL超级宝典 5e 环境配置

    OpenGL超级宝典(第五版)环境配置 1.各种库的配置 (1)glew 下载:https://sourceforge.net/projects/glew/files/glew/1.7.0/glew- ...

  4. OpenGL超级宝典(第7版)笔记13 前三章实例 下个五子棋 (上)

    OpenGL超级宝典(第7版)笔记13 前三章实例 下个五子棋 (上) 文章目录 OpenGL超级宝典(第7版)笔记13 前三章实例 下个五子棋 (上) 前言 1 初构建 2 构建数据结构 3 绘制 ...

  5. OpenGL超级宝典(第7版)笔记4 渲染管线介绍 清单2.3-2.7

    OpenGL超级宝典(第7版)笔记4 渲染管线介绍 清单2.3-2.7 文章目录 OpenGL超级宝典(第7版)笔记4 渲染管线介绍 清单2.3-2.7 1 OpenGL简介 2 OpenGL渲染管线 ...

  6. OpenGL超级宝典(第7版)之第十一章高级数据管理

    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 OpenGL超级宝典(第7版)之第十一章高级数据管理 前言 一.取消绑定 二.稀疏纹理 三.压缩纹理 四.压缩数据格式 五.高质量纹理 ...

  7. OpenGL超级宝典(第五版)环境配置

    本文转自:http://blog.csdn.net/sunny_unix/article/details/8056807,感谢作者分享. OpenGL超级宝典(第五版)环境配置 Vs2008+winX ...

  8. OpenGL超级宝典 5e 环境配置

    OpenGL超级宝典(第五版)环境配置 1.各种库的配置 (1)glew 下载:https://sourceforge.net/projects/glew/files/glew/1.7.0/glew- ...

  9. OpenGL超级宝典(第五版)环境配置【转】

    OpenGL超级宝典(第五版)环境配置 Vs2008+winXP  后续会整理Ubuntu 12.04LTS下的配置作者:sunny_unix 1.各种库的配置 (1)glew 下载:https:// ...

最新文章

  1. GNN 系列:Graph 基础知识介绍
  2. 201671010145 2016-2017《Java程序设计》JAVA语言中,异常处理有哪几种方式?
  3. c#第一个程序-计算平方根
  4. VC从文件中加载图片
  5. leetcode1169. 查询无效交易
  6. github(5):GitHub的注册与使用(详细图解)
  7. 求一个数字中1的个数
  8. Little Elephant and Shifts(CF-220C)
  9. java类成员和实例成员,Java 实例成员和类成员
  10. 给那些因为Firebug而舍不得FireFox的朋友
  11. 虚拟机 linux 设置IP 常用命令
  12. MATLAB 2016a安装
  13. 非极大值抑制(Non-max suppression)
  14. 利用vegas去除视频水印
  15. ubuntu系统学习(1) 测网速命令/实时显示网速speedometer
  16. spring-AOP 增强接口Introductions
  17. 如何用私钥登陆linux服务器和cyberduck登陆配置
  18. 微信小程序开通流量主,流量主收入却是个坑
  19. java程序启动打印_JAVA打印问题:程序正常运行,打印机无反应
  20. php选择栏可输入可选择,填制凭证时,“科目名称”栏可选择用下列()方法输入。...

热门文章

  1. 还在为IntelliJ Lombok 插件烦恼吗?来这里带你一起飞
  2. 再见,米哈游!原神社区防f12控制台调试代码全解(年轻人不讲武德)
  3. composer require topthink/think-migration报错
  4. (74)项目中的亮点是什么?
  5. iOS开发之iAd苹果广告
  6. SpringBoot 查询根据时间数据-数据库时区错误
  7. tiny4412 裸机程序 一、说明【转】
  8. K8S开启默认的StroageClass
  9. 我的英文写作学习之旅:100日入门+后期靠积累
  10. 计算机重装系统桌面文件如何恢复,电脑系统重装,如何恢复之前的文件?