-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathshader_linux.cpp
More file actions
102 lines (91 loc) · 2.73 KB
/
Copy pathshader_linux.cpp
File metadata and controls
102 lines (91 loc) · 2.73 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
#include "detect_os.hpp"
#ifdef PAZ_LINUX
#include "PAZ_Graphics"
#include "util_linux.hpp"
#include "internal_data.hpp"
#include "common.hpp"
#include "gl_core_4_1.h"
paz::ShaderData::~ShaderData()
{
if(_id)
{
glDeleteProgram(_id);
}
}
void paz::ShaderData::init(unsigned int vertId, unsigned int fragId, const std::
unordered_map<unsigned int, unsigned int>& outputTypes)
{
initialize();
if(_id)
{
throw std::logic_error("Shader has already been initialized.");
}
_outputTypes = outputTypes;
// Link shaders.
_id = glCreateProgram();
glAttachShader(_id, vertId);
glAttachShader(_id, fragId);
glLinkProgram(_id);
// Check linking.
GLint success;
glGetProgramiv(_id, GL_LINK_STATUS, &success);
if(!success)
{
std::string errorLog = get_log(_id, true);
throw std::runtime_error("Failed to link shader program:\n" + errorLog);
}
// Get vertex attributes.
{
GLint n;
GLsizei bufSize;
glGetProgramiv(_id, GL_ACTIVE_ATTRIBUTES, &n);
glGetProgramiv(_id, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &bufSize);
for(GLint i = 0; i < n; ++i)
{
GLint size;
GLenum type;
std::vector<GLchar> buf(bufSize);
glGetActiveAttrib(_id, i, bufSize, nullptr, &size, &type, buf.
data());
std::string name(buf.data());
name = name.substr(0, name.find("[", 0));
// `gl_VertexID` has no location because it is a built-in attribute.
if(name == "gl_VertexID")
{
continue;
}
const GLint location = glGetAttribLocation(_id, name.c_str());
if(location < 0)
{
throw std::logic_error("Vertex attribute \"" + name + "\" is no"
"t active.");
}
if(size >= 0)
{
_attribTypes[location] = type;
}
}
}
// Get uniforms.
{
GLint n;
GLsizei bufSize;
glGetProgramiv(_id, GL_ACTIVE_UNIFORMS, &n);
glGetProgramiv(_id, GL_ACTIVE_UNIFORM_MAX_LENGTH, &bufSize);
for(GLint i = 0; i < n; ++i)
{
GLint size;
GLenum type;
std::vector<GLchar> buf(bufSize);
glGetActiveUniform(_id, i, bufSize, nullptr, &size, &type, buf.
data());
const std::string name(buf.data());
std::size_t end = name.find("[", 0);
const GLuint location = glGetUniformLocation(_id, name.substr(0,
end).c_str());
_uniformIds[name.substr(0, end)] = std::make_tuple(location, type,
size);
}
}
}
#endif