-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathLoadShaders.cpp
130 lines (94 loc) · 2.65 KB
/
LoadShaders.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
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
//////////////////////////////////////////////////////////////////////////////
//
// --- LoadShaders.cxx ---
//
//////////////////////////////////////////////////////////////////////////////
#include <cstdlib>
#include <iostream>
#include "GL/glew.h"
#include "LoadShaders.h"
#ifdef __cplusplus
extern "C" {
#endif // __cplusplus
//----------------------------------------------------------------------------
static const GLchar*
ReadShader(const char* filename)
{
FILE* infile;
fopen_s(&infile, filename, "rb");
if (!infile) {
#ifdef _DEBUG
std::cerr << "Unable to open file '" << filename << "'" << std::endl;
#endif /* DEBUG */
return NULL;
}
fseek(infile, 0, SEEK_END);
int len = ftell(infile);
fseek(infile, 0, SEEK_SET);
GLchar* source = new GLchar[len + 1];
fread(source, 1, len, infile);
fclose(infile);
source[len] = 0;
return const_cast<const GLchar*>(source);
}
//----------------------------------------------------------------------------
GLuint
LoadShaders(ShaderInfo* shaders)
{
if (shaders == NULL) { return 0; }
GLuint program = glCreateProgram();
ShaderInfo* entry = shaders;
while (entry->type != GL_NONE) {
GLuint shader = glCreateShader(entry->type);
entry->shader = shader;
const GLchar* source = ReadShader(entry->filename);
if (source == NULL) {
for (entry = shaders; entry->type != GL_NONE; ++entry) {
glDeleteShader(entry->shader);
entry->shader = 0;
}
return 0;
}
glShaderSource(shader, 1, &source, NULL);
delete[] source;
glCompileShader(shader);
GLint compiled;
glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
if (!compiled) {
#ifdef _DEBUG
GLsizei len;
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &len);
GLchar* log = new GLchar[len + 1];
glGetShaderInfoLog(shader, len, &len, log);
std::cerr << "Shader compilation failed: " << log << std::endl;
delete[] log;
#endif /* DEBUG */
return 0;
}
glAttachShader(program, shader);
++entry;
}
glLinkProgram(program);
GLint linked;
glGetProgramiv(program, GL_LINK_STATUS, &linked);
if (!linked) {
#ifdef _DEBUG
GLsizei len;
glGetProgramiv(program, GL_INFO_LOG_LENGTH, &len);
GLchar* log = new GLchar[len + 1];
glGetProgramInfoLog(program, len, &len, log);
std::cerr << "Shader linking failed: " << log << std::endl;
delete[] log;
#endif /* DEBUG */
for (entry = shaders; entry->type != GL_NONE; ++entry) {
glDeleteShader(entry->shader);
entry->shader = 0;
}
return 0;
}
return program;
}
//----------------------------------------------------------------------------
#ifdef __cplusplus
}
#endif // __cplusplus