-
Notifications
You must be signed in to change notification settings - Fork 0
/
Skybox.cpp
96 lines (88 loc) · 1.8 KB
/
Skybox.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
#include "Skybox.h"
#include <filesystem>
#include <iostream>
namespace {
constexpr int NFACE = 6;
const char* face_name[] = { "top", "bottom", "left", "right", "front", "back" };
constexpr int NFORMAT = 4;
const char* format[] = { "jpg", "png", "bmp", "tga"}; // depends on stb_image
}
Skybox::Skybox(const char* dir)
: mesh(Mesh::GenCube(2.0f))
{
using namespace std::filesystem;
faces.resize(6);
path str(dir);
if (!exists(str) && !is_directory(str)) {
std::cout << "skybox path error!\n";
exit(EXIT_FAILURE);
}
for (int i = 0; i < NFACE; ++i) {
str.replace_filename(face_name[i]);
bool ok = false;
for (int j = 0; j < NFORMAT; ++j) {
str.replace_extension(format[j]);
if (exists(str) && is_regular_file(str)) {
ok = true;
break;
}
}
if (ok) {
faces[i] = Texture2D(str.string().c_str());
faces[i].wmode = Texture2D::WrapMode::ClampToEdge;
std::cout << str.stem().string() << " load!\n";
}
else {
std::cout << str.stem().string() << " MISS!\n";
exit(EXIT_FAILURE);
}
}
std::cout << "skybox load!\n";
}
glm::vec4 Skybox::Sample(float x, float y, float z)
{
float absX = fabs(x);
float absY = fabs(y);
float absZ = fabs(z);
float ma, sc, tc;
int faceIndex;
ma = std::max(std::max(absX, absY), absZ);
if (ma == absX) {
if (x > 0) {
faceIndex = 3; // right
sc = z;
tc = y;
}
else {
faceIndex = 2; // left
sc = -z;
tc = y;
}
}
else if (ma == absY) {
if (y > 0) {
faceIndex = 0; // top
sc = x;
tc = z;
}
else {
faceIndex = 1; // bottom
sc = x;
tc = -z;
}
}
else {
if (z > 0) {
faceIndex = 5; // back
sc = -x;
tc = y;
}
else {
faceIndex = 4; // front
sc = x;
tc = y;
}
}
glm::vec2 uv((sc / ma + 1) / 2, (tc / ma + 1) / 2);
return faces[faceIndex].Sample(uv.x, uv.y);
}