-
Notifications
You must be signed in to change notification settings - Fork 0
/
shader.cpp
107 lines (93 loc) · 3 KB
/
shader.cpp
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
#include "shader.h"
enum ShaderType { vertex, fragment };
GLuint LoadSingleShader(const char * shaderFilePath, ShaderType type)
{
// Create a shader id.
GLuint shaderID = 0;
if (type == vertex)
shaderID = glCreateShader(GL_VERTEX_SHADER);
else if (type == fragment)
shaderID = glCreateShader(GL_FRAGMENT_SHADER);
// Try to read shader codes from the shader file.
std::string shaderCode;
std::ifstream shaderStream(shaderFilePath, std::ios::in);
if (shaderStream.is_open())
{
std::string Line = "";
while (getline(shaderStream, Line))
shaderCode += "\n" + Line;
shaderStream.close();
}
else
{
std::cerr << "Impossible to open " << shaderFilePath << ". "
<< "Check to make sure the file exists and you passed in the "
<< "right filepath!"
<< std::endl;
return 0;
}
GLint Result = GL_FALSE;
int InfoLogLength;
// Compile Shader.
std::cerr << "Compiling shader: " << shaderFilePath << std::endl;
char const * sourcePointer = shaderCode.c_str();
glShaderSource(shaderID, 1, &sourcePointer, NULL);
glCompileShader(shaderID);
// Check Shader.
glGetShaderiv(shaderID, GL_COMPILE_STATUS, &Result);
glGetShaderiv(shaderID, GL_INFO_LOG_LENGTH, &InfoLogLength);
if (InfoLogLength > 0)
{
std::vector<char> shaderErrorMessage(InfoLogLength + 1);
glGetShaderInfoLog(shaderID, InfoLogLength, NULL, shaderErrorMessage.data());
std::string msg(shaderErrorMessage.begin(), shaderErrorMessage.end());
std::cerr << msg << std::endl;
return 0;
}
else
{
if (type == vertex)
printf("Successfully compiled vertex shader!\n");
else if (type == fragment)
printf("Successfully compiled fragment shader!\n");
}
return shaderID;
}
GLuint LoadShaders(const char * vertexFilePath, const char * fragmentFilePath)
{
// Create the vertex shader and fragment shader.
GLuint vertexShaderID = LoadSingleShader(vertexFilePath, vertex);
GLuint fragmentShaderID = LoadSingleShader(fragmentFilePath, fragment);
// Check both shaders.
if (vertexShaderID == 0 || fragmentShaderID == 0) return 0;
GLint Result = GL_FALSE;
int InfoLogLength;
// Link the program.
printf("Linking program\n");
GLuint programID = glCreateProgram();
glAttachShader(programID, vertexShaderID);
glAttachShader(programID, fragmentShaderID);
glLinkProgram(programID);
// Check the program.
glGetProgramiv(programID, GL_LINK_STATUS, &Result);
glGetProgramiv(programID, GL_INFO_LOG_LENGTH, &InfoLogLength);
if (InfoLogLength > 0)
{
std::vector<char> ProgramErrorMessage(InfoLogLength + 1);
glGetProgramInfoLog(programID, InfoLogLength, NULL, ProgramErrorMessage.data());
std::string msg(ProgramErrorMessage.begin(), ProgramErrorMessage.end());
std::cerr << msg << std::endl;
glDeleteProgram(programID);
return 0;
}
else
{
printf("Successfully linked program!\n");
}
// Detach and delete the shaders as they are no longer needed.
glDetachShader(programID, vertexShaderID);
glDetachShader(programID, fragmentShaderID);
glDeleteShader(vertexShaderID);
glDeleteShader(fragmentShaderID);
return programID;
}