-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathshader.c
More file actions
107 lines (101 loc) · 2.68 KB
/
shader.c
File metadata and controls
107 lines (101 loc) · 2.68 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
// If your version of OpenGL requires extentions to
// access the various functions, add them here
#define GL_GLEXT_PROTOTYPES
#include "CSCIx239.h"
//
// Read text file
//
static char* ReadText(const char *file)
{
int n;
char* buffer;
// Open file
FILE* f = fopen(file,"rt");
if (!f) Fatal("Cannot open text file %s\n",file);
// Seek to end to determine size, then rewind
fseek(f,0,SEEK_END);
n = ftell(f);
rewind(f);
// Allocate memory for the whole file
buffer = (char*)malloc(n+1);
if (!buffer) Fatal("Cannot allocate %d bytes for text file %s\n",n+1,file);
// Snarf the file
if (fread(buffer,n,1,f)!=1) Fatal("Cannot read %d bytes for text file %s\n",n,file);
buffer[n] = 0;
// Close and return
fclose(f);
return buffer;
}
//
// Print Shader Log
//
static void PrintShaderLog(int obj,const char* file)
{
int len=0;
glGetShaderiv(obj,GL_INFO_LOG_LENGTH,&len);
if (len>1)
{
int n=0;
char* buffer = (char *)malloc(len);
if (!buffer) Fatal("Cannot allocate %d bytes of text for shader log\n",len);
glGetShaderInfoLog(obj,len,&n,buffer);
fprintf(stderr,"%s:\n%s\n",file,buffer);
free(buffer);
}
glGetShaderiv(obj,GL_COMPILE_STATUS,&len);
if (!len) Fatal("Error compiling %s\n",file);
}
//
// Print Program Log
//
void PrintProgramLog(int obj)
{
int len=0;
glGetProgramiv(obj,GL_INFO_LOG_LENGTH,&len);
if (len>1)
{
int n=0;
char* buffer = (char *)malloc(len);
if (!buffer) Fatal("Cannot allocate %d bytes of text for program log\n",len);
glGetProgramInfoLog(obj,len,&n,buffer);
fprintf(stderr,"%s\n",buffer);
}
glGetProgramiv(obj,GL_LINK_STATUS,&len);
if (!len) Fatal("Error linking program\n");
}
//
// Create Shader
//
void CreateShader(int prog,const GLenum type,const char* file)
{
// Create the shader
int shader = glCreateShader(type);
// Load source code from file
char* source = ReadText(file);
glShaderSource(shader,1,(const char**)&source,NULL);
free(source);
// Compile the shader
glCompileShader(shader);
// Check for errors
PrintShaderLog(shader,file);
// Attach to shader program
glAttachShader(prog,shader);
}
//
// Create Shader Program
//
int CreateShaderProg(const char* VertFile,const char* FragFile)
{
// Create program
int prog = glCreateProgram();
// Create and compile vertex shader
if (VertFile) CreateShader(prog,GL_VERTEX_SHADER,VertFile);
// Create and compile fragment shader
if (FragFile) CreateShader(prog,GL_FRAGMENT_SHADER,FragFile);
// Link program
glLinkProgram(prog);
// Check for errors
PrintProgramLog(prog);
// Return name
return prog;
}