-
Notifications
You must be signed in to change notification settings - Fork 2
/
shaders.c
120 lines (92 loc) · 2.86 KB
/
shaders.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
#include <stdlib.h>
#include <stdio.h>
#include "shaders.h"
#include "utils.h"
#include "shaders_errors.h"
ShaderProgram * getShaderProgram(const char * vPath,
const char * gPath, const char * fPath)
{
ShaderProgram * sp = (ShaderProgram *) malloc(sizeof(ShaderProgram));
char * vSrc = getTextFileContent(vPath, NULL);
char * gSrc = (gPath != NULL) ?
getTextFileContent(gPath, NULL) : NULL;
char * fSrc = getTextFileContent(fPath, NULL);
if (vSrc == NULL || fSrc == NULL ||
(gPath != NULL && gSrc == NULL))
{
fprintf(stderr,
"getShaderProgram() failed: file can not be read.\n");
exit(EXIT_FAILURE);
}
sp->v = glCreateShader(GL_VERTEX_SHADER);
sp->g = (gPath != NULL) ? glCreateShader(GL_GEOMETRY_SHADER) : 0;
sp->f = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(sp->v, 1, (const char **) &vSrc, NULL);
glShaderSource(sp->f, 1, (const char **) &fSrc, NULL);
glCompileShader(sp->v);
checkCompileStatus(sp->v);
glCompileShader(sp->f);
checkCompileStatus(sp->f);
free(vSrc);
free(fSrc);
sp->p = glCreateProgram();
glAttachShader(sp->p, sp->v);
glAttachShader(sp->p, sp->f);
if (gPath != NULL)
{
glShaderSource(sp->g, 1, (const char **) &gSrc, NULL);
glCompileShader(sp->g);
checkCompileStatus(sp->g);
free(gSrc);
glAttachShader(sp->p, sp->g);
}
CHECK_OPENGL_ERRORS(__FILE__, __LINE__);
glLinkProgram(sp->p);
checkLinkStatus(sp->p);
glUseProgram(sp->p);
glValidateProgram(sp->p);
return sp;
}
void freeShaderProgram(ShaderProgram * sp)
{
glUseProgram(0);
glDetachShader(sp->p, sp->v);
if (sp->g != 0)
{
glDetachShader(sp->p, sp->g);
}
glDetachShader(sp->p, sp->f);
glDeleteShader(sp->v);
if (sp->g != 0)
{
glDeleteShader(sp->g);
}
glDeleteShader(sp->f);
glDeleteProgram(sp->p);
}
void setupVbo(ShaderProgram * sp, const GLfloat * data,
const char * attrName, int groupSize, GLsizei cnt)
{
GLuint vboP, attribP;
glUseProgram(sp->p);
glGenBuffers(1, &vboP);
glBindBuffer(GL_ARRAY_BUFFER, vboP);
glBufferData(GL_ARRAY_BUFFER, cnt * groupSize * sizeof(GLfloat), data,
GL_STATIC_DRAW);
attribP = glGetAttribLocation(sp->p, attrName);
/* TODO: if (attribP == -1) {} */
glVertexAttribPointer(attribP, groupSize, GL_FLOAT, GL_FALSE, 0,
(const GLvoid *) 0);
glEnableVertexAttribArray(attribP);
CHECK_OPENGL_ERRORS(__FILE__, __LINE__);
}
void setupIdxVbo(ShaderProgram * sp, const GLuint * idx, GLsizei cnt)
{
GLuint vboIdxP;
glUseProgram(sp->p);
glGenBuffers(1, &vboIdxP);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vboIdxP);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, cnt * sizeof(GLuint),
idx, GL_STATIC_DRAW);
CHECK_OPENGL_ERRORS(__FILE__, __LINE__);
}