-
Notifications
You must be signed in to change notification settings - Fork 5
/
material.cpp
124 lines (110 loc) · 2.71 KB
/
material.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
#include "material.h"
#include "../common/shader.h"
#include <glm/gtc/type_ptr.hpp>
Material::Material()
: program(0), diffuse(0)
{
}
Material::~Material()
{
if(program)
{
glDeleteProgram(program);
}
}
bool Material::load(const char* vertexSrc, const char* fragmentSrc)
{
// We start by creating a vertex and fragment shader
GLuint vertex = createShader(vertexSrc, GL_VERTEX_SHADER);
if(!vertex)
{
return false;
}
GLuint fragment = createShader(fragmentSrc, GL_FRAGMENT_SHADER);
if(!fragment)
{
return false;
}
// Now we must make a shader program: this program
// contains both the vertex and the fragment shader
program = createShaderProgram(vertex, fragment);
if(!program)
{
glDeleteShader(vertex);
glDeleteShader(fragment);
return false;
}
// We link the program, just like your C compiler links
// .o files
bool result = linkShader(program);
if(!result)
{
glDeleteShader(vertex);
glDeleteShader(fragment);
glDeleteProgram(program);
program = 0;
return false;
}
// We make sure the shader is validated
result = validateShader(program);
if(!result)
{
glDeleteShader(vertex);
glDeleteShader(fragment);
glDeleteProgram(program);
program = 0;
return false;
}
// Detach and delete the shaders, because we no longer need them
glDetachShader(program, vertex);
glDeleteShader(vertex);
glDetachShader(program, fragment);
glDeleteShader(fragment);
return true;
}
bool Material::setUniform(const char* name, const glm::mat4& m)
{
if(!program)
{
std::cerr << "Program not set while trying to set uniform" << std::endl;
return false;
}
GLint loc = glGetUniformLocation(program, name);
if(loc == -1)
{
std::cerr << "Uniform '" << name << "' not found in shader" << std::endl;
return false;
}
glUniformMatrix4fv(loc, 1, GL_FALSE, glm::value_ptr(m));
return true;
}
void Material::setDiffuseTexture(GLuint texture)
{
diffuse = texture;
}
bool Material::use()
{
if(!program)
{
std::cerr << "Tried to use material without program" << std::endl;
}
glUseProgram(program);
return true;
}
bool Material::bind()
{
if(!program || !diffuse)
{
std::cerr << "Set program and textures before binding a material!" << std::endl;
return false;
}
glUseProgram(program);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, diffuse);
glUniform1i(glGetUniformLocation(program, "diffuse"), 0);
return true;
}
void Material::stopUsing()
{
glUseProgram(0);
}