2021SC@SDUSC
目录
本章我们继续来讲OvRendering中与shader(着色器)有关的函数。
1.Uniform
首先我们来介绍一下什么是uniform。
uniform是一种从CPU中的应用向GPU中的着色器发送数据的方式,但uniform和顶点属性有些不同。
首先,uniform是全局的(Global)。
全局意味着uniform变量必须在每个着色器程序对象中都是独一无二的,而且它可以被着色器程序的任意着色器在任意阶段访问。
第二,无论你把uniform值设置成什么,uniform会一直保存它们的数据,直到它们被重置或更新。
总之,uniform对于设置一个在渲染迭代中会改变的属性是一个非常有用的工具,它也是一个在程序和着色器间数据交互的很好工具。
了解了uniform之后,我就来看与它相关的一些数据定义,其中包含了shader类中将会使用的结构体和枚举值。
1.1UniformType
这个枚举类中列出来一个uniform可以使用的数据类型:
#include <stdint.h>
namespace OvRendering::Resources
{
/**
* Defines the types that a uniform can take
*/
enum class UniformType : uint32_t
{
UNIFORM_BOOL = 0x8B56,
UNIFORM_INT = 0x1404,
UNIFORM_FLOAT = 0x1406,
UNIFORM_FLOAT_VEC2 = 0x8B50,
UNIFORM_FLOAT_VEC3 = 0x8B51,
UNIFORM_FLOAT_VEC4 = 0x8B52,
UNIFORM_FLOAT_MAT4 = 0x8B5C,
UNIFORM_DOUBLE_MAT4 = 0x8F48,
UNIFORM_SAMPLER_2D = 0x8B5E,
UNIFORM_SAMPLER_CUBE = 0x8B60
};
}
1.2UniformInfo
在这个结构体中,使用UniformType定义数据类型,之后定义了uniform的变量名称与着色器位置,其中std::any能够接收任意类型的单值数据。
#include <string>
#include <any>
#include "OvRendering/Resources/UniformType.h"
namespace OvRendering::Resources
{
/**
* Data structure containing information about a uniform
*/
struct UniformInfo
{
UniformType type;
std::string name;
uint32_t location;
std::any defaultValue;
};
}
2.Shader
了解了以上内容后,我们进入本文的正题。
我们可以看到,原本的作用域中嵌套定义了一个命名空间Loader,其中包含以一个ShaderLoader类,这个类将会在以后的文章中提及,它将作为Shader类的友元类。
namespace OvRendering::Resources
{
namespace Loaders { class ShaderLoader; }
/**
* OpenGL shader program wrapper
*/
class Shader
{
friend class Loaders::ShaderLoader;
接下来我们来看它的成员变量,其中共有变量包括一个uint32_t型的着色器ID,一个string型的路径名称,依旧一个UniformInfo类型的向量。前两个变量用于指定着色的唯一标识与位置,所以不可以更改。
然后私有变量定义了一个无向图类型的uniform位置缓冲,具体的作用将在下文提到。
public:
const uint32_t id;
const std::string path;
std::vector<UniformInfo> uniforms;
private:
std::unordered_map<std::string, int> m_uniformLocationCache;