0%

LoadShaders_加载着色器

1. 接口

1.1 成员

成员名 类 型 简 述
shaderProgram GLuint 着色器程序
ShaderInfo static struct 内置的静态结构体,保存着色器数据的基本信息

1.2 函数

函 数 简 述
Shader(ShaderInfo* const shaders); 构造函数,传入一个着色器数组,生成链接成功的着色器程序
void use(); 激活着色器程序
void set[inputType] (const std::string &name, [inputType] value) const 改变对应的 name 的 uniform 变量

2. 示例使用方式

1
2
3
4
5
6
7
8
9
10
11
Shader::ShaderInfo shaders[] =
{
// { 类型,文件路径 }
{ GL_VERTEX_SHADER, "Media/Shader/01_Triangle/triangles.vert" },
{ GL_FRAGMENT_SHADER, "Media/Shader/01_Triangle/triangles.frag" },
{ GL_NONE, NULL }
};

// 创建着色器文件
Shader ourShader(shaders);
ourShader.use();

3. 源代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
#ifndef SHADER_H
#define SHADER_H

#include <glad/glad.h>
#include <glm/glm.hpp>

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

class Shader
{
public:
static struct ShaderInfo {
GLenum type;
const char* shaderPath;
GLuint shader;
} ;

GLuint shaderProgram;
// constructor generates the shader on the fly
// ------------------------------------------------------------------------
Shader(ShaderInfo* const shaders)
{
ShaderInfo* entry;
entry = shaders;

// 创建着色器程序
shaderProgram = glCreateProgram();

// 编译着色器,添加到着色器程序
while (entry->type != GL_NONE)
{
GLuint iShader;
iShader = readShader(entry->shaderPath, entry->type);
glAttachShader(shaderProgram, iShader);
glDeleteShader(iShader);

++entry;
}

// 链接
glLinkProgram(shaderProgram);
checkLinkErrors(shaderProgram);

}
// activate the shader
// ------------------------------------------------------------------------
void use()
{
glUseProgram(shaderProgram);
}
// utility uniform functions
// ------------------------------------------------------------------------
void setBool(const std::string &name, bool value) const
{
glUniform1i(glGetUniformLocation(shaderProgram, name.c_str()), (int)value);
}
// ------------------------------------------------------------------------
void setInt(const std::string &name, int value) const
{
glUniform1i(glGetUniformLocation(shaderProgram, name.c_str()), value);
}
// ------------------------------------------------------------------------
void setFloat(const std::string &name, float value) const
{
glUniform1f(glGetUniformLocation(shaderProgram, name.c_str()), value);
}
// ------------------------------------------------------------------------
void setVec2(const std::string &name, const glm::vec2 &value) const
{
glUniform2fv(glGetUniformLocation(shaderProgram, name.c_str()), 1, &value[0]);
}
void setVec2(const std::string &name, float x, float y) const
{
glUniform2f(glGetUniformLocation(shaderProgram, name.c_str()), x, y);
}
// ------------------------------------------------------------------------
void setVec3(const std::string &name, const glm::vec3 &value) const
{
glUniform3fv(glGetUniformLocation(shaderProgram, name.c_str()), 1, &value[0]);
}
void setVec3(const std::string &name, float x, float y, float z) const
{
glUniform3f(glGetUniformLocation(shaderProgram, name.c_str()), x, y, z);
}
// ------------------------------------------------------------------------
void setVec4(const std::string &name, const glm::vec4 &value) const
{
glUniform4fv(glGetUniformLocation(shaderProgram, name.c_str()), 1, &value[0]);
}
void setVec4(const std::string &name, float x, float y, float z, float w)
{
glUniform4f(glGetUniformLocation(shaderProgram, name.c_str()), x, y, z, w);
}
// ------------------------------------------------------------------------
void setMat2(const std::string &name, const glm::mat2 &mat) const
{
glUniformMatrix2fv(glGetUniformLocation(shaderProgram, name.c_str()), 1, GL_FALSE, &mat[0][0]);
}
// ------------------------------------------------------------------------
void setMat3(const std::string &name, const glm::mat3 &mat) const
{
glUniformMatrix3fv(glGetUniformLocation(shaderProgram, name.c_str()), 1, GL_FALSE, &mat[0][0]);
}
// ------------------------------------------------------------------------
void setMat4(const std::string &name, const glm::mat4 &mat) const
{
glUniformMatrix4fv(glGetUniformLocation(shaderProgram, name.c_str()), 1, GL_FALSE, &mat[0][0]);
}

private:
GLuint readShader(const char* shaderPath, GLenum shaderType)
{
// 1. retrieve the vertex/fragment source code from filePath
std::string shaderData;
std::ifstream shaderFile;

// ensure ifstream objects can throw exceptions:
shaderFile.exceptions(std::ifstream::failbit | std::ifstream::badbit);
try
{
// open files
shaderFile.open(shaderPath);
std::stringstream shaderStream;
// read file's buffer contents into streams
shaderStream << shaderFile.rdbuf();
// close file handlers
shaderFile.close();
// convert stream into string
shaderData = shaderStream.str(); }
catch (std::ifstream::failure& e)
{
std::cout << "ERROR::SHADER::FILE_NOT_SUCCESFULLY_READ" << std::endl;
}

const char* shaderSource = shaderData.c_str();
// 2. compile shaders
GLuint shader;
// vertex shader
shader = glCreateShader(shaderType);
glShaderSource(shader, 1, &shaderSource, NULL);
glCompileShader(shader);
checkCompileErrors(shader, shaderPath);

return shader;
}


// utility function for checking shader compilation/linking errors.
// ------------------------------------------------------------------------
void checkCompileErrors(GLuint shader, const char* shaderPath)
{
GLint success;
GLchar infoLog[1024];
glGetShaderiv(shader, GL_COMPILE_STATUS, &success);
if (!success)
{
glGetShaderInfoLog(shader, 1024, NULL, infoLog);
std::cout << "ERROR::SHADER_COMPILATION_ERROR of type: " << shaderPath << "\n" << infoLog << "\n -- --------------------------------------------------- -- " << std::endl;
}

}

void checkLinkErrors(GLuint shaderProgram)
{
GLint success;
GLchar infoLog[1024];
glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success);
if (!success)
{
glGetProgramInfoLog(shaderProgram, 1024, NULL, infoLog);
std::cout << "ERROR::PROGRAM_LINKING_ERROR of type: " << "\n" << infoLog << "\n -- --------------------------------------------------- -- " << std::endl;
}

}

};
#endif