forked from richteer/CS452-LAB2
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathlab2InitShaders.cpp
More file actions
185 lines (147 loc) · 5.77 KB
/
Copy pathlab2InitShaders.cpp
File metadata and controls
185 lines (147 loc) · 5.77 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
// -----------------------
// --- I N C L U D E S ---
// -----------------------
#include "lab2InitShaders.h"
// ---------------------------
// --- P R O T O T Y P E S ---
// ---------------------------
const GLchar* inputShader(const char* filename);
GLuint createShader(GLenum type, const GLchar* shadeSource);
GLuint createProgram(const vector<GLuint> shadeList);
// -----------------------------------------------
// --- F U N C T I O N D E F I N I T I O N S ---
// -----------------------------------------------
// ----------------------------------------------------------------------------
// - initShaders takes in a pointer to a ShaderInfo struct. It uses this
// - pointer to create a vector of these shaders. With this vector, the
// - function creates and uses a program created from these shaders.
// ----------------------------------------------------------------------------
void initShaders(ShaderInfo* shaders)
{
// Declare data members
ShaderInfo* shade = shaders;
vector<GLuint> Shadelist;
GLuint program;
// Iterate through shaders and add all shaders to ShadeList
while(shade->type != GL_NONE)
{
Shadelist.push_back(createShader(shade->type,inputShader(shade->filename)));
++shade;
}
// Creates a program which links all shaders with your OpenGL program
program = createProgram(Shadelist);
// Installs program incorporating shaders into OpenGL program
glUseProgram(program);
}
// ----------------------------------------------------------------------------
// - inputShader reads in and returns the shader file denoted by the inputted
// filename.
// ----------------------------------------------------------------------------
const GLchar* inputShader(const char* filename)
{
// Open the file
FILE* fshade = fopen(filename, "rb");
// If file is open, print error and return
if(!fshade)
{
fprintf(stderr,"unable to open file '%s'\n",filename);
return NULL;
}
// Get the length of the file in ASCII characters
fseek(fshade, 0, SEEK_END);
long filesize=ftell(fshade);
// Reset position to beginning of file
fseek(fshade, 0, SEEK_SET);
// Read in the file
GLchar* shadingSource= new GLchar[filesize+1];//
fread(shadingSource, 1, filesize, fshade);
// If file is empty, print error and return
if(ftell(fshade) == 0)
{
fprintf(stderr, "File '%s' is empty.\n",filename);
return NULL;
}
// Close the file
fclose(fshade);
// Add null terminating character to end of file
shadingSource[filesize] = 0;
// Return the file's text
return const_cast<const GLchar*>(shadingSource);
}
// ----------------------------------------------------------------------------
// - createShader takes the shader (presumably read in from inputShader) and
// - compiles the shader. If the shader fails to compile, a log is printed
// - to stderr. Regardless of whether the compile was successful, the shader
// - GLuint is returned.
// ----------------------------------------------------------------------------
GLuint createShader(GLenum type, const GLchar* shadeSource)
{
// Create a shader based on type GL_VERTEX_SHADER or GL_FRAGMENT_SHADER
GLuint shader = glCreateShader(type);
glShaderSource(shader, 1, &shadeSource, NULL);
// Compile the shader object
glCompileShader(shader);
// Get the status of the compilation
GLint compileStatus;
glGetShaderiv(shader, GL_COMPILE_STATUS, &compileStatus);
// If the shader did not compile, generate and print an error log
if(!compileStatus)
{
// Get the length of the shadeSource file
GLint logSize;
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &logSize);
// Put debug info into infoLog
GLchar* infoLog = new GLchar[logSize+1];
glGetShaderInfoLog(shader,logSize,&logSize,infoLog);
// Puts which type of shader having the error in shadeInfo
const char *shadeInfo = NULL;
switch(type)
{
case GL_VERTEX_SHADER: shadeInfo = "vertex"; break;
case GL_GEOMETRY_SHADER_EXT: shadeInfo = "geometric"; break;
case GL_FRAGMENT_SHADER: shadeInfo = "fragment"; break;
}
// Prints error containing info on the erroneous shader
fprintf(stderr,"\nCompile failure in %u shader: %s\n Error message:\n%s\n",type,shadeInfo,infoLog);
// Deallocate dynamically allocated data members
delete[] infoLog;
}
return shader;
}
// ----------------------------------------------------------------------------
// - createProgram takes in a vector of shaders. A program is created, shaders
// - are attached, and attributes are bound to locations. The program is
// - linked to your actual code (lab2.cpp) and is returned. If the link fails,
// - a log is written to stderr.
// ----------------------------------------------------------------------------
GLuint createProgram(const vector<GLuint> shadeList)
{
// Create a program object
GLuint program = glCreateProgram();
// Attach all shaders to newly created program object
for(GLuint i=0;i<shadeList.size();i++){glAttachShader(program,shadeList[i]);}
// Bind position attribute to 0; color attribute to 1
glBindAttribLocation(program, 0, "in_position");
glBindAttribLocation(program, 1, "in_color");
// Link program oject to OpenGL program
glLinkProgram(program);
// Get the status of the program linking
GLint linkStatus;
glGetProgramiv(program, GL_LINK_STATUS, &linkStatus);
// If link fails, generate and print an error log
if(!linkStatus)
{
// Get the linker status log
GLint logSize;
glGetProgramiv(program, GL_INFO_LOG_LENGTH, &logSize);
// Put debug info into infoLog
GLchar *infoLog = new GLchar[logSize+1];
glGetProgramInfoLog(program,logSize,&logSize,infoLog);
// Prints error containing info on the erroneous linking
fprintf(stderr,"\nShader linking failed: %s\n",infoLog);
// Deallocate dynamically allocated data members
delete[] infoLog;
for(GLuint i=0;i<shadeList.size();i++){glDeleteShader(shadeList[i]);}
}
return program;
}