-
Notifications
You must be signed in to change notification settings - Fork 0
/
shaderprogram.cpp
153 lines (122 loc) · 4.79 KB
/
shaderprogram.cpp
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
/*
Niniejszy program jest wolnym oprogramowaniem; możesz go
rozprowadzać dalej i / lub modyfikować na warunkach Powszechnej
Licencji Publicznej GNU, wydanej przez Fundację Wolnego
Oprogramowania - według wersji 2 tej Licencji lub(według twojego
wyboru) którejś z późniejszych wersji.
Niniejszy program rozpowszechniany jest z nadzieją, iż będzie on
użyteczny - jednak BEZ JAKIEJKOLWIEK GWARANCJI, nawet domyślnej
gwarancji PRZYDATNOŚCI HANDLOWEJ albo PRZYDATNOŚCI DO OKREŚLONYCH
ZASTOSOWAŃ.W celu uzyskania bliższych informacji sięgnij do
Powszechnej Licencji Publicznej GNU.
Z pewnością wraz z niniejszym programem otrzymałeś też egzemplarz
Powszechnej Licencji Publicznej GNU(GNU General Public License);
jeśli nie - napisz do Free Software Foundation, Inc., 59 Temple
Place, Fifth Floor, Boston, MA 02110 - 1301 USA
*/
#include "shaderprogram.h"
//Procedura wczytuje plik do tablicy znaków.
char* ShaderProgram::readFile(const char* fileName) {
int filesize;
FILE *plik;
char* result;
#pragma warning(suppress : 4996) //Wyłączenie błędu w Visual Studio wynikające z nietrzymania się standardów przez Microsoft.
plik=fopen(fileName,"rb");
if (plik != NULL) {
fseek(plik, 0, SEEK_END);
filesize = ftell(plik);
fseek(plik, 0, SEEK_SET);
result = new char[filesize + 1];
#pragma warning(suppress : 6386) //Wyłączenie błędu w Visual Studio wynikającego z błędnej analizy statycznej kodu.
int readsize=fread(result, 1, filesize, plik);
result[filesize] = 0;
fclose(plik);
return result;
}
return NULL;
}
//Metoda wczytuje i kompiluje shader, a następnie zwraca jego uchwyt
GLuint ShaderProgram::loadShader(GLenum shaderType,const char* fileName) {
//Wygeneruj uchwyt na shader
GLuint shader=glCreateShader(shaderType);//shaderType to GL_VERTEX_SHADER, GL_GEOMETRY_SHADER lub GL_FRAGMENT_SHADER
//Wczytaj plik ze źródłem shadera do tablicy znaków
const GLchar* shaderSource=readFile(fileName);
//Powiąż źródło z uchwytem shadera
glShaderSource(shader,1,&shaderSource,NULL);
//Skompiluj źródło
glCompileShader(shader);
//Usuń źródło shadera z pamięci (nie będzie już potrzebne)
delete []shaderSource;
//Pobierz log błędów kompilacji i wyświetl
int infologLength = 0;
int charsWritten = 0;
char *infoLog;
glGetShaderiv(shader, GL_INFO_LOG_LENGTH,&infologLength);
if (infologLength > 1) {
infoLog = new char[infologLength];
glGetShaderInfoLog(shader, infologLength, &charsWritten, infoLog);
printf("%s\n",infoLog);
delete []infoLog;
}
//Zwróć uchwyt wygenerowanego shadera
return shader;
}
ShaderProgram::ShaderProgram(const char* vertexShaderFile,const char* geometryShaderFile,const char* fragmentShaderFile) {
//Wczytaj vertex shader
printf("Loading vertex shader...\n");
vertexShader=loadShader(GL_VERTEX_SHADER,vertexShaderFile);
//Wczytaj geometry shader
if (geometryShaderFile!=NULL) {
printf("Loading geometry shader...\n");
geometryShader=loadShader(GL_GEOMETRY_SHADER,geometryShaderFile);
} else {
geometryShader=0;
}
//Wczytaj fragment shader
printf("Loading fragment shader...\n");
fragmentShader=loadShader(GL_FRAGMENT_SHADER,fragmentShaderFile);
//Wygeneruj uchwyt programu cieniującego
shaderProgram=glCreateProgram();
//Podłącz do niego shadery i zlinkuj program
glAttachShader(shaderProgram,vertexShader);
glAttachShader(shaderProgram,fragmentShader);
if (geometryShaderFile!=NULL) glAttachShader(shaderProgram,geometryShader);
glLinkProgram(shaderProgram);
//Pobierz log błędów linkowania i wyświetl
int infologLength = 0;
int charsWritten = 0;
char *infoLog;
glGetProgramiv(shaderProgram, GL_INFO_LOG_LENGTH,&infologLength);
if (infologLength > 1)
{
infoLog = new char[infologLength];
glGetProgramInfoLog(shaderProgram, infologLength, &charsWritten, infoLog);
printf("%s\n",infoLog);
delete []infoLog;
}
printf("Shader program created \n");
}
ShaderProgram::~ShaderProgram() {
//Odłącz shadery od programu
glDetachShader(shaderProgram, vertexShader);
if (geometryShader!=0) glDetachShader(shaderProgram, geometryShader);
glDetachShader(shaderProgram, fragmentShader);
//Wykasuj shadery
glDeleteShader(vertexShader);
if (geometryShader!=0) glDeleteShader(geometryShader);
glDeleteShader(fragmentShader);
//Wykasuj program
glDeleteProgram(shaderProgram);
}
//Włącz używanie programu cieniującego reprezentowanego przez aktualny obiekt
void ShaderProgram::use() {
glUseProgram(shaderProgram);
}
//Pobierz numer slotu odpowiadającego zmiennej jednorodnej o nazwie variableName
GLuint ShaderProgram::u(const char* variableName) {
return glGetUniformLocation(shaderProgram,variableName);
}
//Pobierz numer slotu odpowiadającego atrybutowi o nazwie variableName
GLuint ShaderProgram::a(const char* variableName) {
return glGetAttribLocation(shaderProgram,variableName);
}