-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathTexture.cpp
137 lines (123 loc) · 3.06 KB
/
Texture.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
#include"Texture.h"
Texture::Texture(const char* image, const char* texType, GLuint slot)
{
// Assigns the type of the texture ot the texture object
type = texType;
// Stores the width, height, and the number of color channels of the image
int widthImg, heightImg, numColCh;
// Flips the image so it appears right side up
stbi_set_flip_vertically_on_load(true);
// Reads the image from a file and stores it in bytes
unsigned char* bytes = stbi_load(image, &widthImg, &heightImg, &numColCh, 0);
// Generates an OpenGL texture object
glGenTextures(1, &ID);
// Assigns the texture to a Texture Unit
glActiveTexture(GL_TEXTURE0 + slot);
unit = slot;
glBindTexture(GL_TEXTURE_2D, ID);
// Configures the type of algorithm that is used to make the image smaller or bigger
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
// Configures the way the texture repeats (if it does at all)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
// Extra lines in case you choose to use GL_CLAMP_TO_BORDER
// float flatColor[] = {1.0f, 1.0f, 1.0f, 1.0f};
// glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, flatColor);
// Check what type of color channels the texture has and load it accordingly
if (type == "normal") // prevents SRGB from deforming normals
glTexImage2D
(
GL_TEXTURE_2D,
0,
GL_RGB,
widthImg,
heightImg,
0,
GL_RGBA,
GL_UNSIGNED_BYTE,
bytes
);
else if (type == "displacement")
glTexImage2D
(
GL_TEXTURE_2D,
0,
GL_RED,
widthImg,
heightImg,
0,
GL_RGBA,
GL_UNSIGNED_BYTE,
bytes
);
else if (numColCh == 4)
glTexImage2D
(
GL_TEXTURE_2D,
0,
GL_SRGB_ALPHA,
widthImg,
heightImg,
0,
GL_RGBA,
GL_UNSIGNED_BYTE,
bytes
);
else if (numColCh == 3)
glTexImage2D
(
GL_TEXTURE_2D,
0,
GL_SRGB,
widthImg,
heightImg,
0,
GL_RGB,
GL_UNSIGNED_BYTE,
bytes
);
else if (numColCh == 1)
glTexImage2D
(
GL_TEXTURE_2D,
0,
GL_SRGB,
widthImg,
heightImg,
0,
GL_RED,
GL_UNSIGNED_BYTE,
bytes
);
else
throw std::invalid_argument("Automatic Texture type recognition failed");
// Generates MipMaps
glGenerateMipmap(GL_TEXTURE_2D);
// Deletes the image data as it is already in the OpenGL Texture object
stbi_image_free(bytes);
// Unbinds the OpenGL Texture object so that it can't accidentally be modified
glBindTexture(GL_TEXTURE_2D, 0);
}
void Texture::texUnit(Shader& shader, const char* uniform, GLuint unit)
{
// Gets the location of the uniform
GLuint texUni = glGetUniformLocation(shader.ID, uniform);
// Shader needs to be activated before changing the value of a uniform
shader.Activate();
// Sets the value of the uniform
glUniform1i(texUni, unit);
}
void Texture::Bind()
{
glActiveTexture(GL_TEXTURE0 + unit);
glBindTexture(GL_TEXTURE_2D, ID);
}
void Texture::Unbind()
{
glBindTexture(GL_TEXTURE_2D, 0);
}
void Texture::Delete()
{
glDeleteTextures(1, &ID);
}