-
Notifications
You must be signed in to change notification settings - Fork 0
/
shaderprogram.cpp
133 lines (106 loc) · 3.95 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
#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);
}