-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathGL_utilities.c
172 lines (146 loc) · 4.56 KB
/
GL_utilities.c
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
// GL utilities, bare essentials
// By Ingemar Ragnemalm
// August 2012:
// FBO creation/usage routines.
// Geometry shader support synched with preliminary version.
// September 2012: Improved infolog printouts with file names.
// 120910: Clarified error messages from shader loader.
// 120913: Re-activated automatic framebuffer checks for UseFBO().
// Fixed FUBAR in InitFBO().
//#define GL3_PROTOTYPES
#include <stdlib.h>
#include <stdio.h>
#include <stddef.h>
#include <string.h>
#include "GL_utilities.h"
// Shader loader
char* readFile(char *file)
{
FILE *fptr;
long length;
char *buf;
fptr = fopen(file, "rb"); /* Open file for reading */
if (!fptr) /* Return NULL on failure */
return NULL;
fseek(fptr, 0, SEEK_END); /* Seek to the end of the file */
length = ftell(fptr); /* Find out how many bytes into the file we are */
buf = (char*)malloc(length+1); /* Allocate a buffer for the entire length of the file and a null terminator */
fseek(fptr, 0, SEEK_SET); /* Go back to the beginning of the file */
fread(buf, length, 1, fptr); /* Read the contents of the file in to the buffer */
fclose(fptr); /* Close the file */
buf[length] = 0; /* Null terminator */
return buf; /* Return the buffer */
}
// Infolog: Show result of shader compilation
void printShaderInfoLog(GLuint obj, const char *fn)
{
GLint infologLength = 0;
GLint charsWritten = 0;
char *infoLog;
glGetShaderiv(obj, GL_INFO_LOG_LENGTH, &infologLength);
if (infologLength > 2)
{
printf("[From %s:]\n", fn);
infoLog = (char *)malloc(infologLength);
glGetShaderInfoLog(obj, infologLength, &charsWritten, infoLog);
printf("%s\n",infoLog);
free(infoLog);
}
}
void printProgramInfoLog(GLuint obj, const char *vfn, const char *ffn, const char *gfn)
{
GLint infologLength = 0;
GLint charsWritten = 0;
char *infoLog;
glGetProgramiv(obj, GL_INFO_LOG_LENGTH,&infologLength);
if (infologLength > 2)
{
if (gfn == NULL)
printf("[From %s+%s:]\n", vfn, ffn);
else
printf("[From %s+%s+%s:]\n", vfn, ffn, gfn);
infoLog = (char *)malloc(infologLength);
glGetProgramInfoLog(obj, infologLength, &charsWritten, infoLog);
printf("%s\n",infoLog);
free(infoLog);
}
}
// Compile a shader, return reference to it
GLuint compileShaders(const char *vs, const char *fs, const char *gs, const char *vfn, const char *ffn, const char *gfn)
{
GLuint v,f,g,p;
v = glCreateShader(GL_VERTEX_SHADER);
f = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(v, 1, &vs, NULL);
glShaderSource(f, 1, &fs, NULL);
glCompileShader(v);
glCompileShader(f);
if (gs != NULL)
{
g = glCreateShader(GL_GEOMETRY_SHADER);
glShaderSource(g, 1, &gs, NULL);
glCompileShader(g);
}
p = glCreateProgram();
glAttachShader(p,v);
glAttachShader(p,f);
if (gs != NULL)
glAttachShader(p,g);
glLinkProgram(p);
glUseProgram(p);
printShaderInfoLog(v, vfn);
printShaderInfoLog(f, ffn);
if (gs != NULL) printShaderInfoLog(g, gfn);
printProgramInfoLog(p, vfn, ffn, gfn);
return p;
}
GLuint loadShaders(const char *vertFileName, const char *fragFileName)
{
return loadShadersG(vertFileName, fragFileName, NULL);
}
GLuint loadShadersG(const char *vertFileName, const char *fragFileName, const char *geomFileName)
// With geometry shader support
{
char *vs, *fs, *gs;
GLuint p = 0;
vs = readFile((char *)vertFileName);
fs = readFile((char *)fragFileName);
//gs = readFile((char *)geomFileName);
if (vs==NULL)
printf("Failed to read %s from disk.\n", vertFileName);
if (fs==NULL)
printf("Failed to read %s from disk.\n", fragFileName);
//if ((gs==NULL) && (geomFileName != NULL))
// printf("Failed to read %s from disk.\n", geomFileName);
if ((vs!=NULL)&&(fs!=NULL))
p = compileShaders(vs, fs, NULL, vertFileName, fragFileName, geomFileName);
if (vs != NULL) free(vs);
if (fs != NULL) free(fs);
//if (gs != NULL) free(gs);
return p;
}
// End of Shader loader
void dumpInfo(void)
{
printf ("Vendor: %s\n", glGetString (GL_VENDOR));
printf ("Renderer: %s\n", glGetString (GL_RENDERER));
printf ("Version: %s\n", glGetString (GL_VERSION));
printf ("GLSL: %s\n", glGetString (GL_SHADING_LANGUAGE_VERSION));
printError ("dumpInfo");
}
static GLenum lastError = 0;
static char lastErrorFunction[1024] = "";
/* report GL errors, if any, to stderr */
void printError(const char *functionName)
{
GLenum error;
while (( error = glGetError() ) != GL_NO_ERROR)
{
if ((lastError != error) || (strcmp(functionName, lastErrorFunction)))
{
fprintf (stderr, "GL error 0x%X detected in %s\n", error, functionName);
strcpy(lastErrorFunction, functionName);
lastError = error;
}
}
}