-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathglslUtility.cpp
More file actions
187 lines (149 loc) · 4.74 KB
/
Copy pathglslUtility.cpp
File metadata and controls
187 lines (149 loc) · 4.74 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
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
181
182
183
184
185
186
187
#include "glslUtility.h"
#include <iostream>
#include <fstream>
#include <string>
#include <stdlib.h>
using std::ios;
namespace glslUtility {
typedef struct {
GLuint vertex;
GLuint fragment;
GLuint geometry;
} shaders_t;
char* loadFile(const char *fname, GLint &fSize)
{
// file read based on example in cplusplus.com tutorial
std::ifstream file(fname, ios::in | ios::binary | ios::ate);
if (file.is_open())
{
unsigned int size = (unsigned int)file.tellg();
fSize = size;
char *memblock = new char[size];
file.seekg(0, ios::beg);
file.read(memblock, size);
file.close();
//std::cout << " file " << fname << " loaded" << std::endl;
return memblock;
}
std::cout << "Unable to open file " << fname << std::endl;
exit(1);
}
// printShaderInfoLog
// From OpenGL Shading Language 3rd Edition, p215-216
// Display (hopefully) useful error messages if shader fails to compile
void printShaderInfoLog(GLint shader)
{
int infoLogLen = 0;
int charsWritten = 0;
GLchar *infoLog;
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLogLen);
if (infoLogLen > 1)
{
infoLog = new GLchar[infoLogLen];
// error check for fail to allocate memory omitted
glGetShaderInfoLog(shader, infoLogLen, &charsWritten, infoLog);
std::cout << "InfoLog:" << std::endl << infoLog << std::endl;
delete[] infoLog;
}
}
void printLinkInfoLog(GLint prog)
{
int infoLogLen = 0;
int charsWritten = 0;
GLchar *infoLog;
glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &infoLogLen);
if (infoLogLen > 1)
{
infoLog = new GLchar[infoLogLen];
// error check for fail to allocate memory omitted
glGetProgramInfoLog(prog, infoLogLen, &charsWritten, infoLog);
std::cout << "InfoLog:" << std::endl << infoLog << std::endl;
delete[] infoLog;
}
}
shaders_t loadShaders(const char * vert_path, const char * geom_path, const char * frag_path) {
GLuint f, g = -1, v;
char *vs, *gs, *fs;
v = glCreateShader(GL_VERTEX_SHADER);
if (geom_path) g = glCreateShader(GL_GEOMETRY_SHADER);
f = glCreateShader(GL_FRAGMENT_SHADER);
// load shaders & get length of each
GLint vlen;
GLint glen;
GLint flen;
vs = loadFile(vert_path, vlen);
if (geom_path) gs = loadFile(geom_path, glen);
fs = loadFile(frag_path, flen);
const char * vv = vs;
const char * gg = geom_path ? gs : NULL;
const char * ff = fs;
glShaderSource(v, 1, &vv, &vlen);
if (geom_path) glShaderSource(g, 1, &gg, &glen);
glShaderSource(f, 1, &ff, &flen);
GLint compiled;
glCompileShader(v);
glGetShaderiv(v, GL_COMPILE_STATUS, &compiled);
if (!compiled)
{
std::cout << "Vertex shader not compiled." << std::endl;
}
printShaderInfoLog(v);
if (geom_path)
{
glCompileShader(g);
glGetShaderiv(g, GL_COMPILE_STATUS, &compiled);
if (!compiled)
{
std::cout << "Geometry shader not compiled." << std::endl;
}
printShaderInfoLog(g);
}
glCompileShader(f);
glGetShaderiv(f, GL_COMPILE_STATUS, &compiled);
if (!compiled)
{
std::cout << "Fragment shader not compiled." << std::endl;
}
printShaderInfoLog(f);
shaders_t out; out.vertex = v; out.geometry = g; out.fragment = f;
delete[] vs; // dont forget to free allocated memory, or else really bad things start happening
if (geom_path) delete[] gs;
delete[] fs; // we allocated this in the loadFile function...
return out;
}
void attachAndLinkProgram(GLuint program, shaders_t shaders) {
glAttachShader(program, shaders.vertex);
if (shaders.geometry >= 0) glAttachShader(program, shaders.geometry);
glAttachShader(program, shaders.fragment);
glLinkProgram(program);
GLint linked;
glGetProgramiv(program, GL_LINK_STATUS, &linked);
if (!linked)
{
std::cout << "Program did not link." << std::endl;
}
printLinkInfoLog(program);
}
GLuint createProgram(const char *vertexShaderPath, const char *fragmentShaderPath, const char *attributeLocations[], GLuint numberOfLocations)
{
glslUtility::shaders_t shaders = glslUtility::loadShaders(vertexShaderPath, NULL, fragmentShaderPath);
GLuint program = glCreateProgram();
for (GLuint i = 0; i < numberOfLocations; i++)
{
glBindAttribLocation(program, i, attributeLocations[i]);
}
glslUtility::attachAndLinkProgram(program, shaders);
return program;
}
GLuint createProgram(const char *vertexShaderPath, const char *geometryShaderPath, const char *fragmentShaderPath, const char *attributeLocations[], GLuint numberOfLocations)
{
glslUtility::shaders_t shaders = glslUtility::loadShaders(vertexShaderPath, geometryShaderPath, fragmentShaderPath);
GLuint program = glCreateProgram();
for (GLuint i = 0; i < numberOfLocations; i++)
{
glBindAttribLocation(program, i, attributeLocations[i]);
}
glslUtility::attachAndLinkProgram(program, shaders);
return program;
}
}