Repository navigation
Expand file tree
/
Copy pathglsupport.cpp
More file actions
130 lines (100 loc) · 3.81 KB
/
Copy pathglsupport.cpp
File metadata and controls
130 lines (100 loc) · 3.81 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
#include <fstream>
#include <vector>
#include <string>
#include <iostream>
#include <stdexcept>
#include "glsupport.h"
using namespace std;
void checkGlErrors() {
const GLenum errCode = glGetError();
if (errCode != GL_NO_ERROR) {
string error("GL Error: ");
error += reinterpret_cast<const char*>(gluErrorString(errCode));
cerr << error << endl;
throw runtime_error(error);
}
}
// Dump text file into a character vector, throws exception on error
static void readTextFile(const char *fn, vector<char>& data) {
// Sets ios::binary bit to prevent end of line translation, so that the
// number of bytes we read equals file size
ifstream ifs(fn, ios::binary);
if (!ifs)
throw runtime_error(string("Cannot open file ") + fn);
// Sets bits to report IO error using exception
ifs.exceptions(ios::eofbit | ios::failbit | ios::badbit);
ifs.seekg(0, ios::end);
size_t len = ifs.tellg();
data.resize(len);
ifs.seekg(0, ios::beg);
ifs.read(&data[0], len);
}
// GL 3 core needs separate functions for shader and program info logs
// Print info regarding a GL program
static void printProgramInfoLog(GLuint obj, const string& filename) {
GLsizei infoLogLength, charsWritten;
glGetProgramiv(obj, GL_INFO_LOG_LENGTH, &infoLogLength);
if (infoLogLength > 0) {
string infoLog(infoLogLength, ' ');
glGetProgramInfoLog(obj, infoLogLength, &charsWritten, &infoLog[0]);
std::cerr << "##### Log [" << filename << "]:\n" << infoLog << endl;
}
}
// Print info regarding a GL shader
static void printShaderInfoLog(GLuint obj, const string& filename) {
GLsizei infoLogLength, charsWritten;
glGetShaderiv(obj, GL_INFO_LOG_LENGTH, &infoLogLength);
if (infoLogLength > 0) {
string infoLog(infoLogLength, ' ');
glGetShaderInfoLog(obj, infoLogLength, &charsWritten, &infoLog[0]);
std::cerr << "##### Log [" << filename << "]:\n" << infoLog << endl;
}
}
static void compileShader(GLuint shaderHandle, int sourceLength, const char *source, const char *filenameHint) {
const char *ptrs[] = { source };
const GLint lens[] = { sourceLength };
glShaderSource(shaderHandle, 1, ptrs, lens); // load the shader sources
glCompileShader(shaderHandle);
printShaderInfoLog(shaderHandle, filenameHint);
GLint compiled = 0;
glGetShaderiv(shaderHandle, GL_COMPILE_STATUS, &compiled);
if (!compiled)
throw runtime_error("fails to compile GL shader");
}
void readAndCompileSingleShaderFromMemory(GLuint shaderHandle,
int sourceLength, const char *source) {
compileShader(shaderHandle, sourceLength, source, "<in-memory source>");
}
void readAndCompileSingleShader(GLuint shaderHandle, const char *fn) {
vector<char> source;
readTextFile(fn, source);
compileShader(shaderHandle, source.size(), &source[0], fn);
}
void linkShader(GLuint programHandle, GLuint vs, GLuint fs) {
glAttachShader(programHandle, vs);
glAttachShader(programHandle, fs);
glLinkProgram(programHandle);
glDetachShader(programHandle, vs);
glDetachShader(programHandle, fs);
GLint linked = 0;
glGetProgramiv(programHandle, GL_LINK_STATUS, &linked);
printProgramInfoLog(programHandle, "linking");
if (!linked)
throw runtime_error("fails to link shaders");
}
void readAndCompileShader(GLuint programHandle, const char * vertexShaderFileName, const char * fragmentShaderFileName) {
GlShader vs(GL_VERTEX_SHADER);
GlShader fs(GL_FRAGMENT_SHADER);
readAndCompileSingleShader(vs, vertexShaderFileName);
readAndCompileSingleShader(fs, fragmentShaderFileName);
linkShader(programHandle, vs, fs);
}
void readAndCompileShaderFromMemory(GLuint programHandle,
int vsSourceLength, const char *vsSource,
int fsSourceLength, const char *fsSource) {
GlShader vs(GL_VERTEX_SHADER);
GlShader fs(GL_FRAGMENT_SHADER);
readAndCompileSingleShaderFromMemory(vs, vsSourceLength, vsSource);
readAndCompileSingleShaderFromMemory(fs, fsSourceLength, fsSource);
linkShader(programHandle, vs, fs);
}