forked from CIS565-Fall-2013/Project4-Rasterizer
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathglslUtility.cpp
More file actions
153 lines (121 loc) · 3.86 KB
/
glslUtility.cpp
File metadata and controls
153 lines (121 loc) · 3.86 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
// GLSL Utility: A utility class for loading GLSL shaders, for Patrick Cozzi's CIS565: GPU Computing at the University of Pennsylvania
// Written by Varun Sampath and Patrick Cozzi, Copyright (c) 2012 University of Pennsylvania
#include "glslUtility.h"
#include <iostream>
#include <fstream>
#include <string>
using std::ios;
namespace glslUtility {
typedef struct {
GLuint vertex;
GLuint fragment;
} 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 * frag_path) {
GLuint f, v;
char *vs,*fs;
v = glCreateShader(GL_VERTEX_SHADER);
f = glCreateShader(GL_FRAGMENT_SHADER);
// load shaders & get length of each
GLint vlen;
GLint flen;
vs = loadFile(vert_path,vlen);
fs = loadFile(frag_path,flen);
const char * vv = vs;
const char * ff = fs;
glShaderSource(v, 1, &vv,&vlen);
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);
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.fragment = f;
delete [] vs; // dont forget to free allocated memory, or else really bad things start happening
delete [] fs; // we allocated this in the loadFile function...
return out;
}
void attachAndLinkProgram( GLuint program, shaders_t shaders) {
glAttachShader(program, shaders.vertex);
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, fragmentShaderPath);
GLuint program = glCreateProgram();
for (GLuint i = 0; i < numberOfLocations; ++i)
{
glBindAttribLocation(program, i, attributeLocations[i]);
}
glslUtility::attachAndLinkProgram(program, shaders);
return program;
}
}