-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathShader.cpp
More file actions
154 lines (129 loc) · 5.15 KB
/
Shader.cpp
File metadata and controls
154 lines (129 loc) · 5.15 KB
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
#include "Shader.h"
#include "FCT/DebugTools/Android_Out.h"
#include "Model.h"
#include "Utility.h"
Shader *Shader::loadShader(
const std::string &vertexSource,
const std::string &fragmentSource,
const std::string &positionAttributeName,
const std::string &uvAttributeName,
const std::string &projectionMatrixUniformName) {
Shader *shader = nullptr;
GLuint vertexShader = loadShader(GL_VERTEX_SHADER, vertexSource);
if (!vertexShader) {
return nullptr;
}
GLuint fragmentShader = loadShader(GL_FRAGMENT_SHADER, fragmentSource);
if (!fragmentShader) {
glDeleteShader(vertexShader);
return nullptr;
}
GLuint program = glCreateProgram();
if (program) {
glAttachShader(program, vertexShader);
glAttachShader(program, fragmentShader);
glLinkProgram(program);
GLint linkStatus = GL_FALSE;
glGetProgramiv(program, GL_LINK_STATUS, &linkStatus);
if (linkStatus != GL_TRUE) {
GLint logLength = 0;
glGetProgramiv(program, GL_INFO_LOG_LENGTH, &logLength);
// If we fail to link the shader program, log the result for debugging
if (logLength) {
GLchar *log = new GLchar[logLength];
glGetProgramInfoLog(program, logLength, nullptr, log);
aout << "Failed to link program with:\n" << log << std::endl;
delete[] log;
}
glDeleteProgram(program);
} else {
// Get the attribute and uniform locations by name. You may also choose to hardcode
// indices with layout= in your shader, but it is not done in this sample
GLint positionAttribute = glGetAttribLocation(program, positionAttributeName.c_str());
GLint uvAttribute = glGetAttribLocation(program, uvAttributeName.c_str());
GLint projectionMatrixUniform = glGetUniformLocation(
program,
projectionMatrixUniformName.c_str());
// Only create a new shader if all the attributes are found.
if (positionAttribute != -1
&& uvAttribute != -1
&& projectionMatrixUniform != -1) {
shader = new Shader(
program,
positionAttribute,
uvAttribute,
projectionMatrixUniform);
} else {
glDeleteProgram(program);
}
}
}
// The shaders are no longer needed once the program is linked. Release their memory.
glDeleteShader(vertexShader);
glDeleteShader(fragmentShader);
return shader;
}
GLuint Shader::loadShader(GLenum shaderType, const std::string &shaderSource) {
Utility::assertGlError();
GLuint shader = glCreateShader(shaderType);
if (shader) {
auto *shaderRawString = (GLchar *) shaderSource.c_str();
GLint shaderLength = shaderSource.length();
glShaderSource(shader, 1, &shaderRawString, &shaderLength);
glCompileShader(shader);
GLint shaderCompiled = 0;
glGetShaderiv(shader, GL_COMPILE_STATUS, &shaderCompiled);
// If the shader doesn't compile, log the result to the terminal for debugging
if (!shaderCompiled) {
GLint infoLength = 0;
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLength);
if (infoLength) {
auto *infoLog = new GLchar[infoLength];
glGetShaderInfoLog(shader, infoLength, nullptr, infoLog);
aout << "Failed to compile with:\n" << infoLog << std::endl;
delete[] infoLog;
}
glDeleteShader(shader);
shader = 0;
}
}
return shader;
}
void Shader::activate() const {
glUseProgram(program_);
}
void Shader::deactivate() const {
glUseProgram(0);
}
void Shader::drawModel(const Model &model) const {
// The position attribute is 3 floats
glVertexAttribPointer(
position_, // attrib
3, // elements
GL_FLOAT, // of type float
GL_FALSE, // don't normalize
sizeof(Vertex), // stride is Vertex bytes
model.getVertexData() // pull from the start of the vertex data
);
glEnableVertexAttribArray(position_);
// The uv attribute is 2 floats
glVertexAttribPointer(
uv_, // attrib
2, // elements
GL_FLOAT, // of type float
GL_FALSE, // don't normalize
sizeof(Vertex), // stride is Vertex bytes
((uint8_t *) model.getVertexData()) + sizeof(Vector3) // offset Vector3 from the start
);
glEnableVertexAttribArray(uv_);
// Setup the texture
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, model.getTexture().getTextureID());
// Draw as indexed triangles
glDrawElements(GL_TRIANGLES, model.getIndexCount(), GL_UNSIGNED_SHORT, model.getIndexData());
glDisableVertexAttribArray(uv_);
glDisableVertexAttribArray(position_);
}
void Shader::setProjectionMatrix(float *projectionMatrix) const {
glUniformMatrix4fv(projectionMatrix_, 1, false, projectionMatrix);
}